@haiyangj/ccs 1.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/CHANGELOG.md ADDED
@@ -0,0 +1,47 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.0.1] - 2026-01-16
6
+
7
+ ### Changed
8
+ - **Settings.json Structure**: Updated to work with actual Claude Code settings format
9
+ - Now updates `env.ANTHROPIC_BASE_URL` and `env.ANTHROPIC_AUTH_TOKEN` fields
10
+ - Previously was updating top-level `apiUrl` and `apiKey` fields (incorrect)
11
+ - Preserves other settings like `enabledPlugins`
12
+
13
+ - **API Key Validation**: Removed the requirement for API keys to start with `sk-ant-`
14
+ - Old rule: Must start with `sk-ant-`, minimum 20 characters
15
+ - New rule: Minimum 10 characters, any format accepted
16
+ - This change allows the tool to work with various API providers and custom endpoints
17
+
18
+ ### Technical Details
19
+ - Updated `src/core/config.js`:
20
+ - `getApiConfig()` - reads from `env.ANTHROPIC_BASE_URL` and `env.ANTHROPIC_AUTH_TOKEN`
21
+ - `updateApiConfig()` - updates nested env fields while preserving other settings
22
+ - `createSettings()` - creates proper settings structure
23
+ - Updated `src/core/validator.js` - `validateApiKey()` function
24
+ - Updated documentation: DESIGN_SPEC.md, README.md, IMPLEMENTATION.md
25
+
26
+ ---
27
+
28
+ ## [1.0.0] - 2026-01-16
29
+
30
+ ### Added
31
+ - Initial release of Claude Config Manager (CCM)
32
+ - 10 core commands: init, list, show, add, use, set, delete, rename, export, import
33
+ - Interactive mode support for add/set commands
34
+ - Colored terminal output with status indicators
35
+ - Secure file handling with 0600 permissions
36
+ - API key masking in all output
37
+ - Profile import/export functionality
38
+ - Automatic backup on file modifications
39
+ - Smart profile name suggestions
40
+ - Confirmation prompts for destructive operations
41
+
42
+ ### Features
43
+ - Profile management with CRUD operations
44
+ - Configuration file management (profiles.json + settings.json)
45
+ - Path resolution with multiple fallback strategies
46
+ - Input validation for names, URLs, and API keys
47
+ - Atomic file writes for data safety
package/DESIGN_SPEC.md ADDED
@@ -0,0 +1,530 @@
1
+ # Claude Config Manager (CCM) - Design Specification
2
+
3
+ ## Overview
4
+ A Node.js CLI tool for managing Claude Code configuration profiles, enabling quick switching between different API endpoints and keys stored in `.claude/settings.json`.
5
+
6
+ ---
7
+
8
+ ## System Architecture
9
+
10
+ ### Component Structure
11
+ ```
12
+ ccm/
13
+ ├── bin/
14
+ │ └── ccm.js # CLI entry point
15
+ ├── src/
16
+ │ ├── commands/
17
+ │ │ ├── list.js # List all profiles
18
+ │ │ ├── use.js # Switch to a profile
19
+ │ │ ├── add.js # Add new profile
20
+ │ │ ├── set.js # Update existing profile
21
+ │ │ ├── delete.js # Delete a profile
22
+ │ │ ├── show.js # Show current active profile
23
+ │ │ └── init.js # Initialize profile storage
24
+ │ ├── core/
25
+ │ │ ├── config.js # Config file operations
26
+ │ │ ├── profiles.js # Profile management
27
+ │ │ └── validator.js # Input validation
28
+ │ └── utils/
29
+ │ ├── logger.js # Colored console output
30
+ │ └── paths.js # Path resolution
31
+ ├── package.json
32
+ └── README.md
33
+ ```
34
+
35
+ ---
36
+
37
+ ## Data Model
38
+
39
+ ### Profile Storage Format
40
+ Location: `.claude/profiles.json`
41
+
42
+ ```json
43
+ {
44
+ "version": "1.0.0",
45
+ "currentProfile": "default",
46
+ "profiles": {
47
+ "default": {
48
+ "name": "default",
49
+ "apiUrl": "https://api.anthropic.com",
50
+ "apiKey": "sk-ant-xxxxx",
51
+ "createdAt": "2026-01-16T10:00:00.000Z",
52
+ "lastUsed": "2026-01-16T10:00:00.000Z"
53
+ },
54
+ "work": {
55
+ "name": "work",
56
+ "apiUrl": "https://work-proxy.company.com",
57
+ "apiKey": "sk-ant-work-xxxxx",
58
+ "createdAt": "2026-01-16T11:00:00.000Z",
59
+ "lastUsed": null
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Settings File Format
66
+ Location: `.claude/settings.json`
67
+
68
+ ```json
69
+ {
70
+ "env": {
71
+ "ANTHROPIC_AUTH_TOKEN": "your-api-key",
72
+ "ANTHROPIC_BASE_URL": "https://api.anthropic.com"
73
+ },
74
+ "enabledPlugins": {
75
+ "document-skills@anthropic-agent-skills": true,
76
+ "code-review@claude-plugins-official": true,
77
+ "superpowers@superpowers-marketplace": true
78
+ },
79
+ "apiUrl": "",
80
+ "apiKey": ""
81
+ }
82
+ ```
83
+
84
+ ---
85
+
86
+ ## CLI Commands Specification
87
+
88
+ ### 1. `ccm list` (alias: `ls`)
89
+ **Purpose**: Display all configured profiles with status indicators
90
+
91
+ **Output**:
92
+ ```
93
+ Available profiles:
94
+
95
+ ✓ default https://api.anthropic.com (active)
96
+ work https://work-proxy.company.com
97
+ staging https://staging-api.example.com
98
+
99
+ Use 'ccm use <name>' to switch profiles
100
+ ```
101
+
102
+ **Features**:
103
+ - ✓ checkmark for currently active profile
104
+ - Masked API keys (show last 4 chars only)
105
+ - Color coding: green for active, white for inactive
106
+ - Sort by last used, then alphabetically
107
+
108
+ ---
109
+
110
+ ### 2. `ccm use <name>`
111
+ **Purpose**: Switch to a different profile
112
+
113
+ **Arguments**:
114
+ - `<name>`: Profile name (required)
115
+
116
+ **Behavior**:
117
+ 1. Validate profile exists
118
+ 2. Read current `.claude/settings.json`
119
+ 3. Update `apiUrl` and `apiKey` from selected profile
120
+ 4. Write back to `.claude/settings.json`
121
+ 5. Update `lastUsed` timestamp in profiles.json
122
+ 6. Update `currentProfile` in profiles.json
123
+
124
+ **Output**:
125
+ ```
126
+ ✓ Switched to profile 'work'
127
+ API URL: https://work-proxy.company.com
128
+ API Key: ****xxxxx
129
+ ```
130
+
131
+ **Error Handling**:
132
+ - Profile not found → suggest similar names
133
+ - Settings file missing → offer to create
134
+ - Permission denied → clear error message
135
+
136
+ ---
137
+
138
+ ### 3. `ccm add <name> <url> <key>`
139
+ **Purpose**: Add a new profile
140
+
141
+ **Arguments**:
142
+ - `<name>`: Profile name (required, alphanumeric + dash/underscore)
143
+ - `<url>`: API endpoint URL (required, must be valid HTTPS URL)
144
+ - `<key>`: API key (required)
145
+
146
+ **Validation**:
147
+ - Name: 1-50 chars, alphanumeric, dash, underscore only
148
+ - URL: Valid HTTPS URL format
149
+ - Key: Minimum 10 chars
150
+
151
+ **Behavior**:
152
+ 1. Validate all inputs
153
+ 2. Check for duplicate profile name
154
+ 3. Add to profiles.json
155
+ 4. Optionally switch to new profile (prompt user)
156
+
157
+ **Output**:
158
+ ```
159
+ ✓ Profile 'staging' added successfully
160
+ API URL: https://staging-api.example.com
161
+ API Key: ****xxxxx
162
+
163
+ Switch to this profile now? (y/N):
164
+ ```
165
+
166
+ **Interactive Mode**:
167
+ ```bash
168
+ ccm add
169
+ # Prompts for:
170
+ # Profile name: _
171
+ # API URL: _
172
+ # API Key: _ (hidden input)
173
+ ```
174
+
175
+ ---
176
+
177
+ ### 4. `ccm set <name> <url> <key>`
178
+ **Purpose**: Update an existing profile
179
+
180
+ **Arguments**: Same as `add`
181
+
182
+ **Behavior**:
183
+ 1. Validate profile exists
184
+ 2. Validate new inputs
185
+ 3. Update profile in profiles.json
186
+ 4. If profile is currently active, update settings.json
187
+ 5. Preserve createdAt timestamp
188
+
189
+ **Output**:
190
+ ```
191
+ ✓ Profile 'work' updated successfully
192
+ API URL: https://work-proxy.company.com (updated)
193
+ API Key: ****xxxxx (updated)
194
+
195
+ ⚠ This profile is currently active. Changes applied to settings.json
196
+ ```
197
+
198
+ ---
199
+
200
+ ### 5. `ccm delete <name>` (alias: `rm`)
201
+ **Purpose**: Remove a profile
202
+
203
+ **Arguments**:
204
+ - `<name>`: Profile name (required)
205
+
206
+ **Safeguards**:
207
+ - Cannot delete currently active profile (must switch first)
208
+ - Confirmation prompt (bypass with `--force` or `-f`)
209
+
210
+ **Output**:
211
+ ```
212
+ ⚠ Delete profile 'staging'? This cannot be undone. (y/N): y
213
+ ✓ Profile 'staging' deleted
214
+ ```
215
+
216
+ ---
217
+
218
+ ### 6. `ccm show` (alias: `current`)
219
+ **Purpose**: Display current active profile details
220
+
221
+ **Output**:
222
+ ```
223
+ Current profile: work
224
+
225
+ API URL: https://work-proxy.company.com
226
+ API Key: ****xxxxx
227
+ Created: 2026-01-16 11:00 AM
228
+ Last used: 2026-01-16 02:30 PM
229
+ ```
230
+
231
+ ---
232
+
233
+ ### 7. `ccm init`
234
+ **Purpose**: Initialize profile management (first-time setup)
235
+
236
+ **Behavior**:
237
+ 1. Check if profiles.json exists
238
+ 2. If settings.json exists, import as "default" profile
239
+ 3. Create profiles.json with initial structure
240
+ 4. Set up default profile
241
+
242
+ **Output**:
243
+ ```
244
+ Initializing Claude Config Manager...
245
+
246
+ ✓ Found existing settings.json
247
+ ✓ Created profiles.json
248
+ ✓ Imported current config as 'default' profile
249
+
250
+ You can now use 'ccm add' to create additional profiles.
251
+ ```
252
+
253
+ ---
254
+
255
+ ### 8. `ccm export [file]`
256
+ **Purpose**: Export profiles to a file (for backup/sharing)
257
+
258
+ **Arguments**:
259
+ - `[file]`: Output file path (default: `./claude-profiles-backup.json`)
260
+
261
+ **Options**:
262
+ - `--no-keys`: Export without API keys (for sharing)
263
+
264
+ **Output**:
265
+ ```
266
+ ✓ Exported 3 profiles to claude-profiles-backup.json
267
+ ```
268
+
269
+ ---
270
+
271
+ ### 9. `ccm import <file>`
272
+ **Purpose**: Import profiles from a file
273
+
274
+ **Arguments**:
275
+ - `<file>`: Input file path (required)
276
+
277
+ **Options**:
278
+ - `--merge`: Merge with existing profiles (default: replace)
279
+
280
+ **Behavior**:
281
+ 1. Validate file format
282
+ 2. Check for name conflicts
283
+ 3. Import profiles
284
+ 4. Preserve current active profile
285
+
286
+ **Output**:
287
+ ```
288
+ Importing profiles from backup.json...
289
+
290
+ ✓ 2 profiles imported
291
+ ⚠ 1 profile skipped (name conflict: 'work')
292
+
293
+ Use 'ccm list' to see all profiles.
294
+ ```
295
+
296
+ ---
297
+
298
+ ### 10. `ccm rename <old-name> <new-name>`
299
+ **Purpose**: Rename an existing profile
300
+
301
+ **Arguments**:
302
+ - `<old-name>`: Current profile name (required)
303
+ - `<new-name>`: New profile name (required)
304
+
305
+ **Output**:
306
+ ```
307
+ ✓ Profile renamed: 'staging' → 'stage'
308
+ ```
309
+
310
+ ---
311
+
312
+ ## Technical Implementation Details
313
+
314
+ ### Dependencies
315
+ ```json
316
+ {
317
+ "dependencies": {
318
+ "commander": "^11.1.0", // CLI framework
319
+ "chalk": "^5.3.0", // Terminal colors
320
+ "inquirer": "^9.2.12", // Interactive prompts
321
+ "ora": "^8.0.1", // Spinners
322
+ "conf": "^12.0.0" // Config storage (alternative to custom JSON)
323
+ }
324
+ }
325
+ ```
326
+
327
+ ### Path Resolution Strategy
328
+ ```javascript
329
+ // Priority order for finding .claude directory:
330
+ 1. Current working directory: process.cwd() + '/.claude'
331
+ 2. Git root directory: git rev-parse --show-toplevel + '/.claude'
332
+ 3. Home directory: os.homedir() + '/.claude'
333
+ 4. Environment variable: process.env.CLAUDE_CONFIG_DIR
334
+ ```
335
+
336
+ ### Error Handling Principles
337
+ - **Graceful degradation**: Don't crash, show helpful messages
338
+ - **Validation first**: Check inputs before file operations
339
+ - **Atomic operations**: Use temp files for updates, rename on success
340
+ - **Backup on modify**: Keep `.bak` file when updating settings.json
341
+
342
+ ### Security Considerations
343
+ 1. **File Permissions**: Set profiles.json to 0600 (owner read/write only)
344
+ 2. **API Key Display**: Always mask except last 4 characters
345
+ 3. **Input Sanitization**: Validate all user inputs
346
+ 4. **No Logging**: Never log API keys, even to debug logs
347
+
348
+ ---
349
+
350
+ ## User Experience Enhancements
351
+
352
+ ### Auto-completion Support
353
+ Provide shell completion scripts:
354
+ ```bash
355
+ ccm completion bash > /etc/bash_completion.d/ccm
356
+ ccm completion zsh > ~/.zsh/completion/_ccm
357
+ ```
358
+
359
+ ### Configuration Validation
360
+ On every operation, validate settings.json structure:
361
+ - Required fields present
362
+ - API URL is reachable (optional check with --validate)
363
+ - API key format correct
364
+
365
+ ### Color Scheme
366
+ - **Green**: Success messages, active profile
367
+ - **Yellow**: Warnings, prompts
368
+ - **Red**: Errors
369
+ - **Blue**: Info, headers
370
+ - **Gray**: Secondary text, masked keys
371
+
372
+ ### Interactive Mode Triggers
373
+ Commands support both argument-based and interactive modes:
374
+ ```bash
375
+ ccm add # Interactive prompts
376
+ ccm add name url key # Direct arguments
377
+ ```
378
+
379
+ ---
380
+
381
+ ## Migration Strategy
382
+
383
+ ### First-time Users
384
+ 1. Run `ccm init` to create profiles.json
385
+ 2. Current settings.json becomes "default" profile
386
+ 3. Ready to add more profiles
387
+
388
+ ### Existing Multi-config Users
389
+ 1. Run `ccm import` with existing config files
390
+ 2. Assign meaningful names during import
391
+ 3. Use `ccm use` to switch between them
392
+
393
+ ---
394
+
395
+ ## Testing Strategy
396
+
397
+ ### Unit Tests
398
+ - Config file read/write operations
399
+ - Profile validation logic
400
+ - Path resolution
401
+ - Input sanitization
402
+
403
+ ### Integration Tests
404
+ - Full command workflows (add → use → delete)
405
+ - File permission handling
406
+ - Concurrent access (file locking)
407
+
408
+ ### Manual Testing Checklist
409
+ - [ ] Create profile with special characters in URL
410
+ - [ ] Switch profiles and verify settings.json updates
411
+ - [ ] Delete active profile (should fail)
412
+ - [ ] Import with name conflicts
413
+ - [ ] Run without .claude directory (should guide setup)
414
+
415
+ ---
416
+
417
+ ## Future Enhancements (v2.0)
418
+
419
+ 1. **Environment Variables**: Support for env var substitution in profiles
420
+ 2. **Profile Groups**: Organize profiles by project/environment
421
+ 3. **Cloud Sync**: Optional encrypted cloud backup of profiles
422
+ 4. **API Key Encryption**: Encrypt keys at rest in profiles.json
423
+ 5. **Health Checks**: Validate API connectivity before switching
424
+ 6. **Profile Templates**: Quick setup for common configurations
425
+ 7. **Diff Command**: Compare two profiles
426
+ 8. **Audit Log**: Track profile switches with timestamps
427
+
428
+ ---
429
+
430
+ ## Installation & Distribution
431
+
432
+ ### NPM Package
433
+ ```bash
434
+ npm install -g @haiyangj/ccs
435
+ ```
436
+
437
+ ### Manual Installation
438
+ ```bash
439
+ git clone https://github.com/haiyangj/ccs.git
440
+ cd ccs
441
+ npm install
442
+ npm link
443
+ ```
444
+
445
+ ### Binary Distribution
446
+ Use `pkg` to create standalone binaries for:
447
+ - macOS (ARM64, x64)
448
+ - Linux (x64)
449
+ - Windows (x64)
450
+
451
+ ---
452
+
453
+ ## Documentation Requirements
454
+
455
+ 1. **README.md**: Quick start guide, command reference
456
+ 2. **ARCHITECTURE.md**: This design document
457
+ 3. **API.md**: Programmatic usage (if used as library)
458
+ 4. **CHANGELOG.md**: Version history
459
+ 5. **CONTRIBUTING.md**: Development setup, testing
460
+
461
+ ---
462
+
463
+ ## Success Metrics
464
+
465
+ - **Time to switch**: < 1 second for profile switching
466
+ - **First-time setup**: < 2 minutes from install to first profile switch
467
+ - **Error recovery**: Clear actionable messages for all error states
468
+ - **Zero data loss**: Atomic operations, backup files maintained
469
+
470
+ ---
471
+
472
+ ## Command Summary Table
473
+
474
+ | Command | Aliases | Arguments | Description |
475
+ |---------|---------|-----------|-------------|
476
+ | `init` | - | - | Initialize profile management |
477
+ | `list` | `ls` | - | Show all profiles |
478
+ | `show` | `current` | - | Show active profile details |
479
+ | `use` | - | `<name>` | Switch to profile |
480
+ | `add` | - | `<name> <url> <key>` | Add new profile |
481
+ | `set` | - | `<name> <url> <key>` | Update profile |
482
+ | `delete` | `rm` | `<name>` | Delete profile |
483
+ | `rename` | `mv` | `<old> <new>` | Rename profile |
484
+ | `export` | - | `[file]` | Export profiles |
485
+ | `import` | - | `<file>` | Import profiles |
486
+
487
+ ---
488
+
489
+ ## Example Workflow
490
+
491
+ ```bash
492
+ # First time setup
493
+ $ ccm init
494
+ ✓ Initialized with 'default' profile
495
+
496
+ # Add work profile
497
+ $ ccm add work https://work.api.com sk-ant-work-key
498
+ ✓ Profile 'work' added
499
+
500
+ # List profiles
501
+ $ ccm list
502
+ ✓ default https://api.anthropic.com (active)
503
+ work https://work.api.com
504
+
505
+ # Switch to work
506
+ $ ccm use work
507
+ ✓ Switched to profile 'work'
508
+
509
+ # Show current
510
+ $ ccm show
511
+ Current profile: work
512
+ API URL: https://work.api.com
513
+ API Key: ****key
514
+
515
+ # Back to default
516
+ $ ccm use default
517
+ ✓ Switched to profile 'default'
518
+
519
+ # Export for backup
520
+ $ ccm export ~/backups/claude-profiles.json
521
+ ✓ Exported 2 profiles
522
+ ```
523
+
524
+ ---
525
+
526
+ ## End of Specification
527
+
528
+ **Document Version**: 1.0.0
529
+ **Last Updated**: 2026-01-16
530
+ **Status**: Ready for Implementation