claude-switch-profile 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/README.md ADDED
@@ -0,0 +1,744 @@
1
+ # Claude Switch Profile (CSP)
2
+
3
+ A CLI tool for managing multiple Claude Code configurations and profiles. Effortlessly switch between different development setups, each with their own rules, agents, skills, and settings.
4
+
5
+ ## Overview
6
+
7
+ Claude Switch Profile enables developers to maintain multiple isolated Claude Code environments on a single machine. Each profile captures and restores:
8
+
9
+ - **Symlinked items** (rules, agents, skills, hooks, CLAUDE.md, etc.) — point to external repositories
10
+ - **Mutable files** (settings.json, .env, .ck.json, etc.) — copied and restored per profile
11
+ - **Custom directories** (commands, plugins) — copied and restored per profile
12
+
13
+ Profiles are stored in `~/.claude-profiles/` and are never managed by Claude Code itself, ensuring clean separation and safe switching.
14
+
15
+ ## Installation
16
+
17
+ ### Global Installation
18
+
19
+ ```bash
20
+ npm install -g claude-switch-profile
21
+ ```
22
+
23
+ Then use the `csp` command globally:
24
+
25
+ ```bash
26
+ csp list
27
+ csp current
28
+ csp create my-profile
29
+ ```
30
+
31
+ ### Local Development
32
+
33
+ ```bash
34
+ # In the project root
35
+ npm install
36
+ npm link
37
+
38
+ # Now available as `csp` command
39
+ csp --help
40
+ ```
41
+
42
+ ### Requirements
43
+
44
+ - Node.js >= 18.0.0
45
+ - Unix/Linux/macOS (uses symlinks and POSIX tools)
46
+
47
+ ## Quick Start
48
+
49
+ ### 1. Initialize
50
+
51
+ Capture your current Claude Code setup as the default profile:
52
+
53
+ ```bash
54
+ csp init
55
+ ```
56
+
57
+ This creates `~/.claude-profiles/default/` containing your current configuration.
58
+
59
+ ### 2. Create Additional Profiles
60
+
61
+ Create a new profile from your current state:
62
+
63
+ ```bash
64
+ csp create work --description "Work setup with company rules"
65
+ ```
66
+
67
+ Or clone from an existing profile:
68
+
69
+ ```bash
70
+ csp create experimental --from default --description "Testing new tools"
71
+ ```
72
+
73
+ ### 3. Switch Between Profiles
74
+
75
+ Switch to a profile (automatically saves current state):
76
+
77
+ ```bash
78
+ csp use work
79
+ # Restart your Claude Code session for changes to take effect
80
+ ```
81
+
82
+ Use `--dry-run` to preview changes:
83
+
84
+ ```bash
85
+ csp use work --dry-run
86
+ ```
87
+
88
+ ### 4. Save Current State
89
+
90
+ Save the active profile with current configuration:
91
+
92
+ ```bash
93
+ csp save
94
+ ```
95
+
96
+ ### 5. List All Profiles
97
+
98
+ View all available profiles with their status:
99
+
100
+ ```bash
101
+ csp list
102
+ ```
103
+
104
+ Output example:
105
+
106
+ ```
107
+ * default — Default profile (initial capture) (2026-03-11)
108
+ work — Work setup (2026-03-11)
109
+ experimental (2026-03-11)
110
+ ```
111
+
112
+ The `*` marks the active profile.
113
+
114
+ ## Commands Reference
115
+
116
+ ### init
117
+
118
+ Initialize the profile system and capture current state as "default" profile.
119
+
120
+ ```bash
121
+ csp init
122
+ ```
123
+
124
+ **Options:** None
125
+
126
+ **Behavior:**
127
+ - Creates `~/.claude-profiles/` directory
128
+ - Captures current `~/.claude` configuration
129
+ - Creates `default` profile and marks it active
130
+ - If already initialized, displays current active profile
131
+
132
+ ---
133
+
134
+ ### current
135
+
136
+ Display the currently active profile.
137
+
138
+ ```bash
139
+ csp current
140
+ ```
141
+
142
+ **Output:**
143
+ ```
144
+ ✓ Active profile: default
145
+ ℹ Location: /home/user/.claude-profiles/default
146
+ ```
147
+
148
+ ---
149
+
150
+ ### list (ls)
151
+
152
+ List all profiles with descriptions and creation dates.
153
+
154
+ ```bash
155
+ csp list
156
+ csp ls
157
+ ```
158
+
159
+ **Output format:**
160
+ ```
161
+ * profile-name — optional description (YYYY-MM-DD)
162
+ other-profile (YYYY-MM-DD)
163
+ ```
164
+
165
+ The `*` marks the currently active profile.
166
+
167
+ ---
168
+
169
+ ### create
170
+
171
+ Create a new profile from current state or clone existing profile.
172
+
173
+ ```bash
174
+ csp create <name> [options]
175
+ ```
176
+
177
+ **Options:**
178
+ - `--from <profile>` — Clone from existing profile instead of current state
179
+ - `-d, --description <text>` — Add description to profile
180
+
181
+ **Examples:**
182
+
183
+ Create from current state:
184
+ ```bash
185
+ csp create production
186
+ ```
187
+
188
+ Create with description:
189
+ ```bash
190
+ csp create staging -d "Staging environment with logging enabled"
191
+ ```
192
+
193
+ Clone from existing:
194
+ ```bash
195
+ csp create backup --from production
196
+ ```
197
+
198
+ **Behavior:**
199
+ - Creates profile directory: `~/.claude-profiles/<name>/`
200
+ - If `--from` is specified, clones all content from source profile
201
+ - Otherwise, captures current `~/.claude` state
202
+ - If this is the first profile, automatically sets it as active
203
+ - Saves metadata (created timestamp, description)
204
+
205
+ ---
206
+
207
+ ### save
208
+
209
+ Save the current `~/.claude` state to the active profile.
210
+
211
+ ```bash
212
+ csp save
213
+ ```
214
+
215
+ **Behavior:**
216
+ - Captures all managed symlinks and files from `~/.claude`
217
+ - Overwrites profile's `source.json` and file copies
218
+ - Useful after modifying rules, settings, or other configuration
219
+ - Requires active profile (run `csp create` if none exists)
220
+
221
+ ---
222
+
223
+ ### use
224
+
225
+ Switch to a different profile.
226
+
227
+ ```bash
228
+ csp use <name> [options]
229
+ ```
230
+
231
+ **Options:**
232
+ - `--dry-run` — Show what would change without executing
233
+ - `--no-save` — Skip saving current profile before switching
234
+ - `--force` — Switch even if some symlink targets are missing
235
+
236
+ **Examples:**
237
+
238
+ Simple switch:
239
+ ```bash
240
+ csp use production
241
+ ```
242
+
243
+ Preview changes first:
244
+ ```bash
245
+ csp use staging --dry-run
246
+ ```
247
+
248
+ Switch without saving current state:
249
+ ```bash
250
+ csp use backup --no-save
251
+ ```
252
+
253
+ Force switch with missing targets:
254
+ ```bash
255
+ csp use legacy --force
256
+ ```
257
+
258
+ **Behavior:**
259
+ 1. Validates target profile exists and is valid
260
+ 2. (Optional) Validates symlink targets exist
261
+ 3. If active profile exists and `--no-save` is not set: saves current state
262
+ 4. Creates automatic backup at `~/.claude-profiles/.backup/`
263
+ 5. Removes all managed items from `~/.claude`
264
+ 6. Restores target profile's symlinks and files
265
+ 7. Updates active marker
266
+ 8. **Important:** Claude Code session must be restarted for changes to apply
267
+
268
+ ---
269
+
270
+ ### delete (rm)
271
+
272
+ Delete a profile.
273
+
274
+ ```bash
275
+ csp delete <name> [options]
276
+ csp rm <name> [options]
277
+ ```
278
+
279
+ **Options:**
280
+ - `-f, --force` — Skip confirmation prompt
281
+
282
+ **Examples:**
283
+
284
+ Delete with confirmation:
285
+ ```bash
286
+ csp delete experimental
287
+ # Delete profile "experimental"? This cannot be undone. (y/N)
288
+ ```
289
+
290
+ Force delete without prompt:
291
+ ```bash
292
+ csp delete old-setup --force
293
+ ```
294
+
295
+ **Behavior:**
296
+ - Cannot delete the active profile (must switch first)
297
+ - Prompts for confirmation unless `--force` is used
298
+ - Permanently removes profile directory and metadata
299
+ - Cannot be undone (but auto-backups from `use` are preserved)
300
+
301
+ ---
302
+
303
+ ### export
304
+
305
+ Export a profile as a compressed tar.gz archive.
306
+
307
+ ```bash
308
+ csp export <name> [options]
309
+ ```
310
+
311
+ **Options:**
312
+ - `-o, --output <path>` — Output file path (defaults to `./{name}.csp.tar.gz`)
313
+
314
+ **Examples:**
315
+
316
+ Export with default filename:
317
+ ```bash
318
+ csp export production
319
+ # Exports to ./production.csp.tar.gz
320
+ ```
321
+
322
+ Export to custom location:
323
+ ```bash
324
+ csp export staging -o ~/backups/claude-staging.tar.gz
325
+ ```
326
+
327
+ **Behavior:**
328
+ - Creates tar.gz archive of entire profile directory
329
+ - Includes source.json (symlink targets) and all copied files
330
+ - Useful for backup, sharing, or version control
331
+
332
+ ---
333
+
334
+ ### import
335
+
336
+ Import a profile from tar.gz archive.
337
+
338
+ ```bash
339
+ csp import <file> [options]
340
+ ```
341
+
342
+ **Options:**
343
+ - `-n, --name <name>` — Profile name (defaults to archive filename without extension)
344
+ - `-d, --description <text>` — Profile description
345
+
346
+ **Examples:**
347
+
348
+ Import with default name:
349
+ ```bash
350
+ csp import production.csp.tar.gz
351
+ # Creates profile named "production"
352
+ ```
353
+
354
+ Import with custom name and description:
355
+ ```bash
356
+ csp import backup.tar.gz -n restored -d "Restored from backup"
357
+ ```
358
+
359
+ **Behavior:**
360
+ - Extracts archive to `~/.claude-profiles/<name>/`
361
+ - Uses filename as profile name if `--name` not specified
362
+ - Creates metadata entry for profile
363
+ - Profile is ready to use immediately
364
+
365
+ ---
366
+
367
+ ### diff
368
+
369
+ Compare two profiles to identify differences.
370
+
371
+ ```bash
372
+ csp diff <profileA> <profileB>
373
+ ```
374
+
375
+ **Special:** Use `current` to compare against active profile.
376
+
377
+ **Examples:**
378
+
379
+ Compare two profiles:
380
+ ```bash
381
+ csp diff staging production
382
+ ```
383
+
384
+ Compare current profile with another:
385
+ ```bash
386
+ csp diff current backup
387
+ ```
388
+
389
+ **Output:**
390
+ ```
391
+ Comparing: staging ↔ production
392
+
393
+ Symlink targets (source.json): identical
394
+
395
+ File differences:
396
+ settings.json — different
397
+ .env — only in production
398
+ rules/CLAUDE.md — different
399
+ ```
400
+
401
+ **Behavior:**
402
+ - Compares `source.json` (symlink targets)
403
+ - Lists file presence and content differences
404
+ - Shows which files differ and in which profile they exist
405
+
406
+ ## How Profiles Work
407
+
408
+ ### Profile Storage
409
+
410
+ Profiles are stored in `~/.claude-profiles/`:
411
+
412
+ ```
413
+ ~/.claude-profiles/
414
+ ├── .active # Current active profile name
415
+ ├── profiles.json # Metadata for all profiles
416
+ ├── default/
417
+ │ ├── source.json # Symlink targets
418
+ │ ├── settings.json # Copied from ~/.claude
419
+ │ ├── .env # Copied from ~/.claude
420
+ │ ├── .ck.json # Copied from ~/.claude
421
+ │ ├── .ckignore # Copied from ~/.claude
422
+ │ ├── commands/ # Copied from ~/.claude
423
+ │ └── plugins/ # Copied from ~/.claude
424
+ └── production/
425
+ ├── source.json
426
+ ├── settings.json
427
+ └── ...
428
+ ```
429
+
430
+ ### What Gets Managed
431
+
432
+ **Symlinked Items** (via `source.json`):
433
+ - `CLAUDE.md` — Project-specific Claude configuration
434
+ - `rules/` — Development rules and guidelines
435
+ - `agents/` — Agent scripts and configurations
436
+ - `skills/` — Custom Luna skills
437
+ - `hooks/` — Pre/post action hooks
438
+ - `statusline.cjs` — Custom statusline
439
+ - `.luna.json` — Luna configuration
440
+
441
+ **Copied Files**:
442
+ - `settings.json` — Editor settings
443
+ - `.env` — Environment variables
444
+ - `.ck.json` — Custom settings
445
+ - `.ckignore` — Ignore patterns
446
+
447
+ **Copied Directories**:
448
+ - `commands/` — Custom commands
449
+ - `plugins/` — Custom plugins
450
+
451
+ **Never Touched** (runtime/session data):
452
+ - `.credentials.json`
453
+ - `projects/`
454
+ - `backups/`
455
+ - `cache/`, `debug/`, `telemetry/`
456
+ - `history.jsonl`
457
+ - `plans/`, `todos/`, `tasks/`
458
+ - `agent-memory/`, `session-env/`
459
+ - All other session-specific data
460
+
461
+ ### Symlink vs. Copy Strategy
462
+
463
+ **Why symlinks for some items?**
464
+ - Rules, agents, skills often live in external git repos
465
+ - Multiple profiles may share the same rules/skills
466
+ - Symlinks avoid duplication and keep everything in sync
467
+
468
+ **Why copies for others?**
469
+ - Settings and env vars are environment-specific
470
+ - Each profile needs its own independent configuration
471
+ - Prevents accidental modifications from affecting other profiles
472
+
473
+ ## Safety Features
474
+
475
+ ### Lock File
476
+
477
+ Prevents concurrent profile switches:
478
+ - Created at `~/.claude-profiles/.lock` during operations
479
+ - Contains process ID (PID) of the running operation
480
+ - Auto-detects stale locks (process no longer running)
481
+ - Throws error if another switch is in progress
482
+
483
+ ```
484
+ Another csp operation is running (PID: 12345).
485
+ Remove ~/.claude-profiles/.lock if stale.
486
+ ```
487
+
488
+ ### Automatic Backups
489
+
490
+ Every profile switch creates a timestamped backup:
491
+
492
+ ```
493
+ ~/.claude-profiles/.backup/
494
+ ├── 2026-03-11T14-30-45-123Z/
495
+ │ ├── source.json
496
+ │ ├── settings.json
497
+ │ ├── .env
498
+ │ └── ...
499
+ └── 2026-03-11T15-45-22-456Z/
500
+ └── ...
501
+ ```
502
+
503
+ Backups are kept indefinitely. You can manually restore by copying from backup directory.
504
+
505
+ ### Claude Process Detection
506
+
507
+ When switching profiles, CSP detects if Claude Code is running:
508
+
509
+ ```
510
+ ⚠ Claude Code appears to be running. Restart your Claude session after switching profiles.
511
+ ```
512
+
513
+ **Important:** Changes only take effect after restarting Claude Code.
514
+
515
+ ### Validation
516
+
517
+ Before switching, CSP validates:
518
+ 1. Target profile exists
519
+ 2. Profile structure is valid
520
+ 3. (Optional with `--force`) Symlink targets are accessible
521
+
522
+ Use `--force` to proceed even if validation fails:
523
+
524
+ ```bash
525
+ csp use legacy --force
526
+ ```
527
+
528
+ ## Configuration via Environment Variables
529
+
530
+ Override default behavior for testing or advanced use:
531
+
532
+ ### CSP_HOME
533
+
534
+ Override the home directory (default: `process.env.HOME`).
535
+
536
+ ```bash
537
+ CSP_HOME=/tmp/test csp list
538
+ ```
539
+
540
+ ### CSP_CLAUDE_DIR
541
+
542
+ Override Claude config directory (default: `~/.claude`).
543
+
544
+ ```bash
545
+ CSP_CLAUDE_DIR=/tmp/test-claude csp init
546
+ ```
547
+
548
+ ### CSP_PROFILES_DIR
549
+
550
+ Override profiles storage directory (default: `~/.claude-profiles`).
551
+
552
+ ```bash
553
+ CSP_PROFILES_DIR=/tmp/test-profiles csp list
554
+ ```
555
+
556
+ **Use case:** Testing in isolated environments without affecting your real configuration.
557
+
558
+ ## Workflow Examples
559
+
560
+ ### Scenario 1: Work vs. Personal
561
+
562
+ ```bash
563
+ # Initial setup
564
+ csp init
565
+
566
+ # Create work profile
567
+ csp create work -d "Work environment with company rules"
568
+ # ... modify rules, settings, etc. ...
569
+ csp save
570
+
571
+ # Create personal profile
572
+ csp use default
573
+ csp create personal -d "Personal projects"
574
+ csp save
575
+
576
+ # Switch between them
577
+ csp use work # Switch to work
578
+ csp use personal # Switch to personal
579
+ ```
580
+
581
+ ### Scenario 2: Testing New Tools
582
+
583
+ ```bash
584
+ # Clone current profile
585
+ csp create experimental --from current -d "Testing new Luna skills"
586
+
587
+ # Switch and experiment
588
+ csp use experimental
589
+ # ... install new skills, modify rules ...
590
+ csp save
591
+
592
+ # If good, merge back to default
593
+ csp diff current default
594
+ # ... review differences ...
595
+ csp use default
596
+ # ... copy changes manually or recreate ...
597
+
598
+ # Clean up
599
+ csp delete experimental
600
+ ```
601
+
602
+ ### Scenario 3: Backup and Restore
603
+
604
+ ```bash
605
+ # Backup production profile
606
+ csp export production -o ~/backups/production-2026-03.tar.gz
607
+
608
+ # ... time passes ...
609
+
610
+ # Restore if needed
611
+ csp import ~/backups/production-2026-03.tar.gz -n production-restored
612
+ csp use production-restored
613
+ ```
614
+
615
+ ### Scenario 4: Share Profile with Team
616
+
617
+ ```bash
618
+ # Export your setup
619
+ csp export my-setup -o ./my-setup.csp.tar.gz
620
+
621
+ # Teammate imports
622
+ csp import my-setup.csp.tar.gz -n shared-team-setup
623
+ csp use shared-team-setup
624
+ ```
625
+
626
+ ## Troubleshooting
627
+
628
+ ### No active profile
629
+
630
+ **Error:** `No active profile. Run "csp create <name>" first.`
631
+
632
+ **Solution:** Initialize with `csp init` to create the default profile.
633
+
634
+ ```bash
635
+ csp init
636
+ ```
637
+
638
+ ### Profile doesn't exist
639
+
640
+ **Error:** `Profile "name" does not exist. Run "csp list" to see available profiles.`
641
+
642
+ **Solution:** Check available profiles and use exact name.
643
+
644
+ ```bash
645
+ csp list
646
+ csp use production # if "production" exists
647
+ ```
648
+
649
+ ### Cannot delete active profile
650
+
651
+ **Error:** `Cannot delete active profile "default". Switch to another profile first.`
652
+
653
+ **Solution:** Switch to a different profile before deleting.
654
+
655
+ ```bash
656
+ csp use production
657
+ csp delete default
658
+ ```
659
+
660
+ ### Stale lock file
661
+
662
+ **Error:** `Another csp operation is running (PID: 12345). Remove ~/.claude-profiles/.lock if stale.`
663
+
664
+ **Solution:** If the process is not running, manually remove the lock:
665
+
666
+ ```bash
667
+ rm ~/.claude-profiles/.lock
668
+ ```
669
+
670
+ ### Symlink targets missing
671
+
672
+ **Warning:** `Some symlink targets are missing: rules/development-rules.md — missing target`
673
+
674
+ **Solution:** Either restore the missing files to their original location or use `--force`:
675
+
676
+ ```bash
677
+ csp use production --force
678
+ ```
679
+
680
+ ### Changes not applying
681
+
682
+ **Issue:** Switched profiles but changes don't appear in Claude Code.
683
+
684
+ **Solution:** Restart Claude Code session after switching.
685
+
686
+ ```bash
687
+ csp use staging
688
+ # Close and restart Claude Code
689
+ ```
690
+
691
+ ## Development
692
+
693
+ ### Run Tests
694
+
695
+ ```bash
696
+ npm test # All tests
697
+ npm run test:core # Core library tests
698
+ npm run test:cli # CLI integration tests
699
+ npm run test:safety # Safety feature tests
700
+ ```
701
+
702
+ ### Project Structure
703
+
704
+ ```
705
+ .
706
+ ├── bin/
707
+ │ └── csp.js # CLI entry point
708
+ ├── src/
709
+ │ ├── commands/ # Command implementations
710
+ │ │ ├── init.js
711
+ │ │ ├── current.js
712
+ │ │ ├── list.js
713
+ │ │ ├── create.js
714
+ │ │ ├── save.js
715
+ │ │ ├── use.js
716
+ │ │ ├── delete.js
717
+ │ │ ├── export.js
718
+ │ │ ├── import.js
719
+ │ │ └── diff.js
720
+ │ ├── constants.js # Configuration constants
721
+ │ ├── profile-store.js # Profile metadata management
722
+ │ ├── symlink-manager.js # Symlink operations
723
+ │ ├── file-operations.js # File copy/restore operations
724
+ │ ├── safety.js # Locking, backups, validation
725
+ │ ├── profile-validator.js # Profile validation
726
+ │ └── output-helpers.js # Console output formatting
727
+ ├── tests/
728
+ │ ├── core-library.test.js
729
+ │ ├── cli-integration.test.js
730
+ │ └── safety.test.js
731
+ └── package.json
732
+ ```
733
+
734
+ ## License
735
+
736
+ MIT
737
+
738
+ ## Contributing
739
+
740
+ Contributions welcome! Please ensure tests pass and follow existing code style.
741
+
742
+ ```bash
743
+ npm test
744
+ ```