@kaitranntt/ccs 2.4.4 → 2.4.6

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 CHANGED
@@ -108,7 +108,7 @@ export CCS_CLAUDE_PATH="/path/to/claude" # Unix
108
108
  $env:CCS_CLAUDE_PATH = "D:\Tools\Claude\claude.exe" # Windows
109
109
  ```
110
110
 
111
- **See [Troubleshooting Guide](./docs/troubleshooting.md#claude-cli-in-non-standard-location) for detailed setup instructions.**
111
+ **See [Troubleshooting Guide](./docs/en/troubleshooting.md#claude-cli-in-non-standard-location) for detailed setup instructions.**
112
112
 
113
113
  ---
114
114
 
@@ -191,35 +191,6 @@ graph LR
191
191
  - **Context Preservation**: Your workflow remains uninterrupted
192
192
  - **Seamless Integration**: Works exactly like native Claude CLI
193
193
 
194
- ### Task Delegation
195
-
196
- > **🚧 Work in Progress**: This feature is experimental and not fully tested. Use with caution.
197
-
198
- CCS includes intelligent task delegation via the `/ccs` meta-command:
199
-
200
- **Install CCS commands:**
201
- ```bash
202
- ccs --install # Install /ccs command to Claude CLI
203
- ```
204
-
205
- **Use task delegation:**
206
- ```bash
207
- # After running ccs --install, you can use:
208
- /ccs glm /plan "add user authentication"
209
- /ccs glm /code "implement auth endpoints"
210
- /ccs glm /ask "explain this error"
211
- ```
212
-
213
- **Remove when not needed:**
214
- ```bash
215
- ccs --uninstall # Remove /ccs command from Claude CLI
216
- ```
217
-
218
- **Benefits**:
219
- - ✅ Save tokens by delegating simple tasks to cheaper models
220
- - ✅ Use right model for each task automatically
221
- - ✅ Seamless integration with existing workflows
222
- - ✅ Clean installation and removal when needed
223
194
 
224
195
  ---
225
196
 
@@ -229,13 +200,13 @@ ccs --uninstall # Remove /ccs command from Claude CLI
229
200
  ccs # Use Claude subscription (default)
230
201
  ccs glm # Use GLM fallback
231
202
  ccs --version # Show CCS version and install location
232
- ccs --install # Install CCS commands and skills to ~/.claude/
233
- ccs --uninstall # Remove CCS commands and skills from ~/.claude/
234
203
  ```
235
204
 
236
205
  ---
237
206
 
238
- ### 🗑️ Uninstall
207
+ ### 🗑️ Official Uninstall
208
+
209
+ **The recommended way to completely remove CCS:**
239
210
 
240
211
  **macOS / Linux**:
241
212
  ```bash
@@ -247,6 +218,16 @@ curl -fsSL ccs.kaitran.ca/uninstall | bash
247
218
  irm ccs.kaitran.ca/uninstall | iex
248
219
  ```
249
220
 
221
+ > 💡 **Why use the official uninstaller?**
222
+ > - Removes all CCS files and configurations
223
+ > - Cleans up PATH modifications
224
+ > - Removes Claude CLI commands/skills
225
+ > - Handles edge cases we've tested
226
+
227
+ **Alternative methods** (if official uninstaller fails):
228
+ - **npm**: `npm uninstall -g @kaitranntt/ccs`
229
+ - **Manual**: See [troubleshooting guide](./docs/en/troubleshooting.md#manual-uninstall)
230
+
250
231
  ---
251
232
 
252
233
  ## 🎯 Philosophy
@@ -260,17 +241,17 @@ irm ccs.kaitran.ca/uninstall | iex
260
241
  ## 📖 Documentation
261
242
 
262
243
  **Complete documentation in [docs/](./docs/)**:
263
- - [Installation Guide](./docs/installation.md)
264
- - [Configuration](./docs/configuration.md)
265
- - [Usage Examples](./docs/usage.md)
266
- - [Troubleshooting](./docs/troubleshooting.md)
267
- - [Contributing](./docs/contributing.md)
244
+ - [Installation Guide](./docs/en/installation.md)
245
+ - [Configuration](./docs/en/configuration.md)
246
+ - [Usage Examples](./docs/en/usage.md)
247
+ - [Troubleshooting](./docs/en/troubleshooting.md)
248
+ - [Contributing](./docs/en/contributing.md)
268
249
 
269
250
  ---
270
251
 
271
252
  ## 🤝 Contributing
272
253
 
273
- We welcome contributions! Please see our [Contributing Guide](./docs/contributing.md) for details.
254
+ We welcome contributions! Please see our [Contributing Guide](./docs/en/contributing.md) for details.
274
255
 
275
256
  ---
276
257
 
@@ -284,6 +265,6 @@ CCS is licensed under the [MIT License](LICENSE).
284
265
 
285
266
  **Made with ❤️ for developers who hit rate limits too often**
286
267
 
287
- [⭐ Star this repo](https://github.com/kaitranntt/ccs) | [🐛 Report issues](https://github.com/kaitranntt/ccs/issues) | [📖 Read docs](./docs/)
268
+ [⭐ Star this repo](https://github.com/kaitranntt/ccs) | [🐛 Report issues](https://github.com/kaitranntt/ccs/issues) | [📖 Read docs](./docs/en/)
288
269
 
289
270
  </div>
package/README.vi.md CHANGED
@@ -190,35 +190,6 @@ graph LR
190
190
  - **Bảo Toàn Context**: Workflow của bạn không bị gián đoạn
191
191
  - **Tích Hợp Liền Mạch**: Hoạt động chính xác như Claude CLI native
192
192
 
193
- ### Delegation Tác Vụ
194
-
195
- > **🚧 Đang phát triển**: Tính năng này đang trong giai đoạn thử nghiệm và chưa được kiểm tra đầy đủ. Sử dụng với cẩn thận.
196
-
197
- CCS bao gồm delegation tác vụ thông minh qua meta-command `/ccs`:
198
-
199
- **Cài đặt lệnh CCS:**
200
- ```bash
201
- ccs --install # Cài đặt lệnh /ccs vào Claude CLI
202
- ```
203
-
204
- **Sử dụng delegation tác vụ:**
205
- ```bash
206
- # Sau khi chạy ccs --install, bạn có thể dùng:
207
- /ccs glm /plan "add user authentication"
208
- /ccs glm /code "implement auth endpoints"
209
- /ccs glm /ask "explain this error"
210
- ```
211
-
212
- **Gỡ bỏ khi không cần:**
213
- ```bash
214
- ccs --uninstall # Gỡ bỏ lệnh /ccs khỏi Claude CLI
215
- ```
216
-
217
- **Lợi ích**:
218
- - ✅ Tiết kiệm tokens bằng cách delegation tác vụ đơn giản cho model rẻ hơn
219
- - ✅ Dùng đúng model cho từng tác vụ tự động
220
- - ✅ Tích hợp liền mạch với workflows hiện có
221
- - ✅ Cài đặt và gỡ bỏ sạch sẽ khi cần
222
193
 
223
194
  ---
224
195
 
@@ -228,13 +199,13 @@ ccs --uninstall # Gỡ bỏ lệnh /ccs khỏi Claude CLI
228
199
  ccs # Dùng Claude subscription (mặc định)
229
200
  ccs glm # Dùng GLM fallback
230
201
  ccs --version # Hiển thị phiên bản CCS và vị trí cài đặt
231
- ccs --install # Cài đặt lệnh và kỹ năng CCS vào ~/.claude/
232
- ccs --uninstall # Gỡ bỏ lệnh và kỹ năng CCS khỏi ~/.claude/
233
202
  ```
234
203
 
235
204
  ---
236
205
 
237
- ### 🗑️ Gỡ Cài Đặt
206
+ ### 🗑️ Gỡ Cài Đặt Chính Thức
207
+
208
+ **Cách được khuyến nghị để gỡ bỏ hoàn toàn CCS:**
238
209
 
239
210
  **macOS / Linux**:
240
211
  ```bash
@@ -246,6 +217,16 @@ curl -fsSL ccs.kaitran.ca/uninstall | bash
246
217
  irm ccs.kaitran.ca/uninstall | iex
247
218
  ```
248
219
 
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
+
249
230
  ---
250
231
 
251
232
  ## 🎯 Triết Lý
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.4.4
1
+ 2.4.6
package/bin/ccs.js CHANGED
@@ -4,104 +4,149 @@
4
4
  const { spawn } = require('child_process');
5
5
  const path = require('path');
6
6
  const fs = require('fs');
7
- const { showError, colors } = require('./helpers');
7
+ const { error, colored } = require('./helpers');
8
8
  const { detectClaudeCli, showClaudeNotFoundError } = require('./claude-detector');
9
- const { getSettingsPath } = require('./config-manager');
9
+ const { getSettingsPath, getConfigPath } = require('./config-manager');
10
10
 
11
11
  // Version (sync with package.json)
12
12
  const CCS_VERSION = require('../package.json').version;
13
13
 
14
- // Helper: Get spawn options for claude execution
15
- // On Windows, .cmd/.bat/.ps1 files need shell: true
16
- function getSpawnOptions(claudePath) {
17
- const isWindows = process.platform === 'win32';
18
- const needsShell = isWindows && /\.(cmd|bat|ps1)$/i.test(claudePath);
19
-
20
- return {
21
- stdio: 'inherit',
22
- shell: needsShell,
23
- windowsHide: true // Hide the console window on Windows
24
- };
25
- }
26
-
27
- // Helper: Escape arguments for shell execution to prevent security vulnerabilities
28
- function escapeShellArg(arg) {
29
- if (process.platform !== 'win32') {
30
- // Unix-like systems: escape single quotes and wrap in single quotes
31
- return "'" + arg.replace(/'/g, "'\"'\"'") + "'";
32
- } else {
33
- // Windows: escape double quotes and wrap in double quotes
34
- return '"' + arg.replace(/"/g, '""') + '"';
35
- }
14
+ // Execute Claude CLI with unified spawn logic
15
+ function execClaude(claudeCli, args) {
16
+ const child = spawn(claudeCli, args, { stdio: 'inherit', windowsHide: true });
17
+ child.on('exit', (code, signal) => {
18
+ if (signal) process.kill(process.pid, signal);
19
+ else process.exit(code || 0);
20
+ });
21
+ child.on('error', () => {
22
+ showClaudeNotFoundError();
23
+ process.exit(1);
24
+ });
36
25
  }
37
26
 
38
27
  // Special command handlers
39
28
  function handleVersionCommand() {
40
- console.log(`CCS (Claude Code Switch) version ${CCS_VERSION}`);
29
+ // Title
30
+ console.log(colored(`CCS (Claude Code Switch) v${CCS_VERSION}`, 'bold'));
31
+ console.log('');
41
32
 
42
- // Show install location
43
- const installLocation = process.argv[1];
44
- if (installLocation) {
45
- console.log(`Installed at: ${installLocation}`);
46
- }
33
+ // Installation section
34
+ console.log(colored('Installation:', 'cyan'));
47
35
 
48
- console.log('https://github.com/kaitranntt/ccs');
49
- process.exit(0);
50
- }
36
+ // Location
37
+ const installLocation = process.argv[1] || '(not found)';
38
+ console.log(` ${colored('Location:', 'cyan')} ${installLocation}`);
51
39
 
52
- function handleHelpCommand(remainingArgs) {
53
- const claudeCli = detectClaudeCli();
40
+ // Config path
41
+ const configPath = getConfigPath();
42
+ console.log(` ${colored('Config:', 'cyan')} ${configPath}`);
43
+ console.log('');
54
44
 
55
- // Check if claude was found
56
- if (!claudeCli) {
57
- showClaudeNotFoundError();
58
- process.exit(1);
59
- }
45
+ // Documentation
46
+ console.log(`${colored('Documentation:', 'cyan')} https://github.com/kaitranntt/ccs`);
47
+ console.log(`${colored('License:', 'cyan')} MIT`);
48
+ console.log('');
60
49
 
61
- // Execute claude --help
62
- const spawnOpts = getSpawnOptions(claudeCli);
63
- let claudeArgs, child;
50
+ // Help hint
51
+ console.log(colored('Run \'ccs --help\' for usage information', 'yellow'));
64
52
 
65
- if (spawnOpts.shell) {
66
- // When shell is required, escape arguments properly
67
- claudeArgs = [claudeCli, '--help', ...remainingArgs].map(escapeShellArg).join(' ');
68
- child = spawn(claudeArgs, spawnOpts);
69
- } else {
70
- // When no shell needed, use arguments array directly
71
- claudeArgs = ['--help', ...remainingArgs];
72
- child = spawn(claudeCli, claudeArgs, spawnOpts);
73
- }
53
+ process.exit(0);
54
+ }
74
55
 
75
- child.on('exit', (code, signal) => {
76
- if (signal) {
77
- process.kill(process.pid, signal);
78
- } else {
79
- process.exit(code || 0);
80
- }
81
- });
56
+ function handleHelpCommand() {
57
+ // Title
58
+ console.log(colored('CCS (Claude Code Switch) - Instant profile switching for Claude CLI', 'bold'));
59
+ console.log('');
60
+
61
+ // Usage
62
+ console.log(colored('Usage:', 'cyan'));
63
+ console.log(` ${colored('ccs', 'yellow')} [profile] [claude-args...]`);
64
+ console.log(` ${colored('ccs', 'yellow')} [flags]`);
65
+ console.log('');
66
+
67
+ // Description
68
+ console.log(colored('Description:', 'cyan'));
69
+ console.log(' Switch between Claude models instantly. Stop hitting rate limits.');
70
+ console.log(' Maps profile names to Claude settings files via ~/.ccs/config.json');
71
+ console.log('');
72
+
73
+ // Profile Switching
74
+ console.log(colored('Profile Switching:', 'cyan'));
75
+ console.log(` ${colored('ccs', 'yellow')} Use default profile`);
76
+ console.log(` ${colored('ccs glm', 'yellow')} Switch to GLM profile`);
77
+ console.log(` ${colored('ccs glm', 'yellow')} "debug this code" Switch to GLM and run command`);
78
+ console.log(` ${colored('ccs glm', 'yellow')} --verbose Switch to GLM with Claude flags`);
79
+ console.log('');
80
+
81
+ // Flags
82
+ console.log(colored('Flags:', 'cyan'));
83
+ console.log(` ${colored('-h, --help', 'yellow')} Show this help message`);
84
+ console.log(` ${colored('-v, --version', 'yellow')} Show version and installation info`);
85
+ console.log('');
86
+
87
+ // Configuration
88
+ console.log(colored('Configuration:', 'cyan'));
89
+ console.log(' Config File: ~/.ccs/config.json');
90
+ console.log(' Settings: ~/.ccs/*.settings.json');
91
+ console.log(' Environment: CCS_CONFIG (override config path)');
92
+ console.log('');
93
+
94
+ // Examples
95
+ console.log(colored('Examples:', 'cyan'));
96
+ console.log(' # Try without installing');
97
+ console.log(` ${colored('npx @kaitranntt/ccs glm', 'yellow')} "write tests"`);
98
+ console.log('');
99
+ console.log(' # Use default Claude subscription');
100
+ console.log(` ${colored('ccs', 'yellow')} "Review this architecture"`);
101
+ console.log('');
102
+ console.log(' # Switch to GLM for cost-effective tasks');
103
+ console.log(` ${colored('ccs glm', 'yellow')} "Write unit tests"`);
104
+ console.log('');
105
+ console.log(' # Use GLM with verbose output');
106
+ console.log(` ${colored('ccs glm', 'yellow')} --verbose "Debug error"`);
107
+ console.log('');
108
+
109
+ // Uninstall
110
+ console.log(colored('Uninstall:', 'yellow'));
111
+ console.log(' npm: npm uninstall -g @kaitranntt/ccs');
112
+ console.log(' macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash');
113
+ console.log(' Windows: irm ccs.kaitran.ca/uninstall | iex');
114
+ console.log('');
115
+
116
+ // Documentation
117
+ console.log(colored('Documentation:', 'cyan'));
118
+ console.log(` GitHub: ${colored('https://github.com/kaitranntt/ccs', 'cyan')}`);
119
+ console.log(' Docs: https://github.com/kaitranntt/ccs/blob/main/README.md');
120
+ console.log(' Issues: https://github.com/kaitranntt/ccs/issues');
121
+ console.log('');
122
+
123
+ // License
124
+ console.log(`${colored('License:', 'cyan')} MIT`);
82
125
 
83
- child.on('error', (err) => {
84
- showClaudeNotFoundError();
85
- process.exit(1);
86
- });
126
+ process.exit(0);
87
127
  }
88
128
 
89
129
  function handleInstallCommand() {
90
- // Implementation for --install (copy commands/skills to ~/.claude)
91
- console.log('[Installing CCS Commands and Skills]');
92
- console.log('Feature not yet implemented in Node.js standalone');
93
- console.log('Use traditional installer for now:');
94
- console.log(process.platform === 'win32'
95
- ? ' irm ccs.kaitran.ca/install | iex'
96
- : ' curl -fsSL ccs.kaitran.ca/install | bash');
130
+ console.log('');
131
+ console.log('Feature not available');
132
+ console.log('');
133
+ console.log('The --install flag is currently under development.');
134
+ console.log('.claude/ integration testing is not complete.');
135
+ console.log('');
136
+ console.log('For updates: https://github.com/kaitranntt/ccs/issues');
137
+ console.log('');
97
138
  process.exit(0);
98
139
  }
99
140
 
100
141
  function handleUninstallCommand() {
101
- // Implementation for --uninstall (remove commands/skills from ~/.claude)
102
- console.log('[Uninstalling CCS Commands and Skills]');
103
- console.log('Feature not yet implemented in Node.js standalone');
104
- console.log('Use traditional uninstaller for now');
142
+ console.log('');
143
+ console.log('Feature not available');
144
+ console.log('');
145
+ console.log('The --uninstall flag is currently under development.');
146
+ console.log('.claude/ integration testing is not complete.');
147
+ console.log('');
148
+ console.log('For updates: https://github.com/kaitranntt/ccs/issues');
149
+ console.log('');
105
150
  process.exit(0);
106
151
  }
107
152
 
@@ -128,8 +173,7 @@ function main() {
128
173
 
129
174
  // Special case: help command
130
175
  if (firstArg === '--help' || firstArg === '-h' || firstArg === 'help') {
131
- const remainingArgs = args.slice(1);
132
- handleHelpCommand(remainingArgs);
176
+ handleHelpCommand();
133
177
  return;
134
178
  }
135
179
 
@@ -151,40 +195,12 @@ function main() {
151
195
  // Special case: "default" profile just runs claude directly
152
196
  if (profile === 'default') {
153
197
  const claudeCli = detectClaudeCli();
154
-
155
- // Check if claude was found
156
198
  if (!claudeCli) {
157
199
  showClaudeNotFoundError();
158
200
  process.exit(1);
159
201
  }
160
202
 
161
- // Execute claude with args
162
- const spawnOpts = getSpawnOptions(claudeCli);
163
- let claudeArgs, child;
164
-
165
- if (spawnOpts.shell) {
166
- // When shell is required, escape arguments properly
167
- claudeArgs = [claudeCli, ...remainingArgs].map(escapeShellArg).join(' ');
168
- child = spawn(claudeArgs, spawnOpts);
169
- } else {
170
- // When no shell needed, use arguments array directly
171
- claudeArgs = remainingArgs;
172
- child = spawn(claudeCli, claudeArgs, spawnOpts);
173
- }
174
-
175
- child.on('exit', (code, signal) => {
176
- if (signal) {
177
- process.kill(process.pid, signal);
178
- } else {
179
- process.exit(code || 0);
180
- }
181
- });
182
-
183
- child.on('error', (err) => {
184
- showClaudeNotFoundError();
185
- process.exit(1);
186
- });
187
-
203
+ execClaude(claudeCli, remainingArgs);
188
204
  return;
189
205
  }
190
206
 
@@ -201,32 +217,7 @@ function main() {
201
217
  }
202
218
 
203
219
  // Execute claude with --settings
204
- const claudeArgsList = ['--settings', settingsPath, ...remainingArgs];
205
- const spawnOpts = getSpawnOptions(claudeCli);
206
- let claudeArgs, child;
207
-
208
- if (spawnOpts.shell) {
209
- // When shell is required, escape arguments properly
210
- claudeArgs = [claudeCli, ...claudeArgsList].map(escapeShellArg).join(' ');
211
- child = spawn(claudeArgs, spawnOpts);
212
- } else {
213
- // When no shell needed, use arguments array directly
214
- claudeArgs = claudeArgsList;
215
- child = spawn(claudeCli, claudeArgs, spawnOpts);
216
- }
217
-
218
- child.on('exit', (code, signal) => {
219
- if (signal) {
220
- process.kill(process.pid, signal);
221
- } else {
222
- process.exit(code || 0);
223
- }
224
- });
225
-
226
- child.on('error', (err) => {
227
- showClaudeNotFoundError();
228
- process.exit(1);
229
- });
220
+ execClaude(claudeCli, ['--settings', settingsPath, ...remainingArgs]);
230
221
  }
231
222
 
232
223
  // Run main
@@ -2,7 +2,7 @@
2
2
 
3
3
  const fs = require('fs');
4
4
  const { execSync } = require('child_process');
5
- const { showError, expandPath } = require('./helpers');
5
+ const { expandPath } = require('./helpers');
6
6
 
7
7
  // Detect Claude CLI executable
8
8
  function detectClaudeCli() {
@@ -60,40 +60,11 @@ function detectClaudeCli() {
60
60
  return null;
61
61
  }
62
62
 
63
- // Show Claude not found error with diagnostics
63
+ // Show Claude not found error
64
64
  function showClaudeNotFoundError() {
65
- const isWindows = process.platform === 'win32';
66
- const pathDirs = (process.env.PATH || '').split(isWindows ? ';' : ':');
67
-
68
- const errorMsg = `Claude CLI not found in PATH
69
-
70
- CCS requires Claude CLI to be installed and available in your PATH.
71
-
72
- [i] Diagnostic Info:
73
- Platform: ${process.platform}
74
- PATH directories: ${pathDirs.length}
75
- Looking for: claude${isWindows ? '.exe' : ''}
76
-
77
- Solutions:
78
- 1. Install Claude CLI:
79
- https://docs.claude.com/en/docs/claude-code/installation
80
-
81
- 2. Verify installation:
82
- ${isWindows ? 'Get-Command claude' : 'command -v claude'}
83
-
84
- 3. If installed but not in PATH, add it:
85
- # Find Claude installation
86
- ${isWindows ? 'where.exe claude' : 'which claude'}
87
-
88
- # Or set custom path
89
- ${isWindows
90
- ? '$env:CCS_CLAUDE_PATH = \'C:\\path\\to\\claude.exe\''
91
- : 'export CCS_CLAUDE_PATH=\'/path/to/claude\''
92
- }
93
-
94
- Restart your terminal after installation.`;
95
-
96
- showError(errorMsg);
65
+ console.error('ERROR: Claude CLI not found in PATH');
66
+ console.error('Install from: https://docs.claude.com/en/docs/claude-code/installation');
67
+ process.exit(1);
97
68
  }
98
69
 
99
70
  module.exports = {
@@ -3,7 +3,7 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
  const os = require('os');
6
- const { showError, expandPath, validateProfileName } = require('./helpers');
6
+ const { error, expandPath } = require('./helpers');
7
7
 
8
8
  // Get config file path
9
9
  function getConfigPath() {
@@ -16,30 +16,7 @@ function readConfig() {
16
16
 
17
17
  // Check config exists
18
18
  if (!fs.existsSync(configPath)) {
19
- const isWindows = process.platform === 'win32';
20
- showError(`Config file not found: ${configPath}
21
-
22
- Solutions:
23
- 1. Reinstall CCS (auto-creates config):
24
- npm install -g @kaitranntt/ccs --force
25
-
26
- 2. Or use traditional installer:
27
- ${isWindows ? 'irm ccs.kaitran.ca/install | iex' : 'curl -fsSL ccs.kaitran.ca/install | bash'}
28
-
29
- 3. Or create manually:
30
- mkdir -p ~/.ccs
31
- cat > ~/.ccs/config.json << 'EOF'
32
- {
33
- "profiles": {
34
- "glm": "~/.ccs/glm.settings.json",
35
- "default": "~/.claude/settings.json"
36
- }
37
- }
38
- EOF
39
-
40
- Note: If you installed with npm --ignore-scripts, configs weren't created.
41
- Reinstall without that flag: npm install -g @kaitranntt/ccs --force`);
42
- process.exit(1);
19
+ error(`Config file not found: ${configPath}`);
43
20
  }
44
21
 
45
22
  // Read and parse JSON
@@ -48,23 +25,12 @@ EOF
48
25
  const configContent = fs.readFileSync(configPath, 'utf8');
49
26
  config = JSON.parse(configContent);
50
27
  } catch (e) {
51
- const isWindows = process.platform === 'win32';
52
- showError(`Invalid JSON in ${configPath}
53
-
54
- Fix the JSON syntax or reinstall:
55
- ${isWindows ? 'irm ccs.kaitran.ca/install | iex' : 'curl -fsSL ccs.kaitran.ca/install | bash'}`);
56
- process.exit(1);
28
+ error(`Invalid JSON in ${configPath}: ${e.message}`);
57
29
  }
58
30
 
59
31
  // Validate config has profiles object
60
32
  if (!config.profiles || typeof config.profiles !== 'object') {
61
- const isWindows = process.platform === 'win32';
62
- showError(`Config must have 'profiles' object
63
-
64
- See config.example.json for correct format
65
- Or reinstall:
66
- ${isWindows ? 'irm ccs.kaitran.ca/install | iex' : 'curl -fsSL ccs.kaitran.ca/install | bash'}`);
67
- process.exit(1);
33
+ error(`Config must have 'profiles' object in ${configPath}`);
68
34
  }
69
35
 
70
36
  return config;
@@ -74,24 +40,12 @@ Or reinstall:
74
40
  function getSettingsPath(profile) {
75
41
  const config = readConfig();
76
42
 
77
- // Validate profile name
78
- if (!validateProfileName(profile)) {
79
- showError(`Invalid profile name: ${profile}
80
-
81
- Use only alphanumeric characters, dash, or underscore.`);
82
- process.exit(1);
83
- }
84
-
85
43
  // Get settings path
86
44
  const settingsPath = config.profiles[profile];
87
45
 
88
46
  if (!settingsPath) {
89
- const availableProfiles = Object.keys(config.profiles).map(p => ` - ${p}`).join('\n');
90
- showError(`Profile '${profile}' not found in ${getConfigPath()}
91
-
92
- Available profiles:
93
- ${availableProfiles}`);
94
- process.exit(1);
47
+ const availableProfiles = Object.keys(config.profiles).join(', ');
48
+ error(`Profile '${profile}' not found. Available: ${availableProfiles}`);
95
49
  }
96
50
 
97
51
  // Expand path
@@ -99,14 +53,7 @@ ${availableProfiles}`);
99
53
 
100
54
  // Validate settings file exists
101
55
  if (!fs.existsSync(expandedPath)) {
102
- const isWindows = process.platform === 'win32';
103
- showError(`Settings file not found: ${expandedPath}
104
-
105
- Solutions:
106
- 1. Create the settings file for profile '${profile}'
107
- 2. Update the path in ${getConfigPath()}
108
- 3. Or reinstall: ${isWindows ? 'irm ccs.kaitran.ca/install | iex' : 'curl -fsSL ccs.kaitran.ca/install | bash'}`);
109
- process.exit(1);
56
+ error(`Settings file not found: ${expandedPath}`);
110
57
  }
111
58
 
112
59
  // Validate settings file is valid JSON
@@ -114,15 +61,7 @@ Solutions:
114
61
  const settingsContent = fs.readFileSync(expandedPath, 'utf8');
115
62
  JSON.parse(settingsContent);
116
63
  } catch (e) {
117
- showError(`Invalid JSON in ${expandedPath}
118
-
119
- Details: ${e.message}
120
-
121
- Solutions:
122
- 1. Validate JSON at https://jsonlint.com
123
- 2. Or reset to template: echo '{"env":{}}' > ${expandedPath}
124
- 3. Or reinstall CCS`);
125
- process.exit(1);
64
+ error(`Invalid JSON in ${expandedPath}: ${e.message}`);
126
65
  }
127
66
 
128
67
  return expandedPath;