@leynier/ccst
Advanced tools
+321
| # ccst - Claude Code Switch Tools | ||
| > Fast and predictable way to manage Claude Code contexts (`~/.claude/settings.json`) | ||
| **ccst** (Claude Code Switch Tools) is inspired by [cctx](https://github.com/nwiizo/cctx), which is itself inspired by kubectx, and ports the cctx experience to TypeScript with additional capabilities. Switch between permission sets, environments, and settings with a single command. | ||
| ## Features | ||
| - Instant context switching | ||
| - Predictable UX with user-level defaults | ||
| - Security-first separation of work, personal, and project contexts | ||
| - Shell completions for major shells | ||
| - Previous context quick switch with `ccst -` | ||
| - File-based JSON contexts you can edit manually | ||
| ## Quick Start | ||
| ### Installation | ||
| Install globally with npm (default): | ||
| ```bash | ||
| npm install -g @leynier/ccst | ||
| ``` | ||
| Alternative package managers: | ||
| ```bash | ||
| # bun | ||
| bun add -g @leynier/ccst | ||
| # pnpm | ||
| pnpm add -g @leynier/ccst | ||
| # yarn | ||
| yarn global add @leynier/ccst | ||
| ``` | ||
| ### 30-Second Setup | ||
| ```bash | ||
| # 1. Create your first context from current settings | ||
| ccst -n personal | ||
| # 2. Create a restricted work context | ||
| ccst -n work | ||
| # 3. Switch between contexts | ||
| ccst work # Switch to work | ||
| ccst personal # Switch to personal | ||
| ccst - # Switch back to previous | ||
| ``` | ||
| ## Usage | ||
| ### Basic Commands | ||
| ```bash | ||
| # List all contexts | ||
| ccst | ||
| # Switch to a context | ||
| ccst work | ||
| # Switch to previous context | ||
| ccst - | ||
| # Show current context | ||
| ccst -c | ||
| ``` | ||
| ### Settings Level Management | ||
| ccst respects Claude Code's settings hierarchy with explicit flags: | ||
| ```bash | ||
| # Default: always uses user-level contexts | ||
| ccst # Manages ~/.claude/settings.json | ||
| # Explicit flags for project/local contexts | ||
| ccst --in-project # Manages ./.claude/settings.json | ||
| ccst --local # Manages ./.claude/settings.local.json | ||
| # All commands work with any level | ||
| ccst --in-project work # Switch to 'work' in project contexts | ||
| ccst --local staging # Switch to 'staging' in local contexts | ||
| ``` | ||
| ### Context Management | ||
| ```bash | ||
| # Create new context from current settings | ||
| ccst -n project-alpha | ||
| # Delete a context | ||
| ccst -d old-project | ||
| # Rename a context (prompts for new name) | ||
| ccst -r old-name | ||
| # Edit context with $EDITOR | ||
| ccst -e work | ||
| # Show context content (JSON) | ||
| ccst -s production | ||
| # Unset current context | ||
| ccst -u | ||
| ``` | ||
| ### Import/Export | ||
| ```bash | ||
| # Export context to file | ||
| ccst --export production > prod-settings.json | ||
| # Import context from file | ||
| ccst --import staging < staging-settings.json | ||
| # Share contexts between machines | ||
| ccst --export work | ssh remote-host 'ccst --import work' | ||
| ``` | ||
| ### Merge Permissions | ||
| Merge permissions from other contexts or files to build complex configurations: | ||
| ```bash | ||
| # Merge user settings into current context | ||
| ccst --merge-from user | ||
| # Merge from another context | ||
| ccst --merge-from personal work | ||
| # Merge from a specific file | ||
| ccst --merge-from /path/to/permissions.json staging | ||
| # Remove previously merged permissions | ||
| ccst --unmerge user | ||
| # View merge history | ||
| ccst --merge-history | ||
| # Merge into a specific context (default is current) | ||
| ccst --merge-from user production | ||
| ``` | ||
| Merge features: | ||
| - Smart deduplication | ||
| - History tracking | ||
| - Reversible unmerge | ||
| - Targeted merges | ||
| ### Shell Completions | ||
| Enable tab completion for faster workflow: | ||
| ```bash | ||
| # Bash | ||
| ccst --completions bash > ~/.local/share/bash-completion/completions/ccst | ||
| # Zsh | ||
| ccst --completions zsh > /usr/local/share/zsh/site-functions/_ccst | ||
| # Fish | ||
| ccst --completions fish > ~/.config/fish/completions/ccst.fish | ||
| # PowerShell | ||
| ccst --completions powershell > ccst.ps1 | ||
| ``` | ||
| ### Importing Profiles | ||
| ccst includes importer commands to migrate existing profiles: | ||
| ```bash | ||
| # Import from CCS profiles (~/.ccs/*.settings.json) | ||
| ccst import ccs | ||
| # Import from configs directory (default: ~/.ccst) | ||
| ccst import configs | ||
| # Use a custom configs directory | ||
| ccst import configs -d /path/to/configs | ||
| ``` | ||
| ## File Structure | ||
| Contexts are stored as individual JSON files at different levels: | ||
| User level (`~/.claude/`): | ||
| ```text | ||
| ~/.claude/ | ||
| ├── settings.json # Active user context | ||
| └── settings/ | ||
| ├── work.json # Work context | ||
| ├── personal.json # Personal context | ||
| └── .cctx-state.json # State tracking | ||
| ``` | ||
| Project level (`./.claude/`): | ||
| ```text | ||
| ./.claude/ | ||
| ├── settings.json # Shared project context | ||
| ├── settings.local.json # Local project context (gitignored) | ||
| └── settings/ | ||
| ├── staging.json # Staging context | ||
| ├── production.json # Production context | ||
| ├── .cctx-state.json # Project state | ||
| └── .cctx-state.local.json # Local state | ||
| ``` | ||
| ## Interactive Mode | ||
| When no arguments are provided, ccst can enter interactive mode: | ||
| - fzf integration when available | ||
| - Built-in fallback selector when fzf is not installed | ||
| - Current context highlighted in the list | ||
| ```bash | ||
| # Interactive context selection | ||
| CCTX_INTERACTIVE=1 ccst | ||
| ``` | ||
| ## Common Workflows | ||
| ### Professional Setup | ||
| ```bash | ||
| # Create restricted work context for safer collaboration | ||
| ccst -n work | ||
| ccst -e work # Edit to add restrictions | ||
| ``` | ||
| ### Project-Based Contexts | ||
| ```bash | ||
| # Create project-specific contexts | ||
| ccst -n client-alpha | ||
| ccst -n side-project | ||
| ccst -n experiments | ||
| # Switch based on current work | ||
| ccst client-alpha | ||
| ccst experiments | ||
| ``` | ||
| ### Daily Context Switching | ||
| ```bash | ||
| # Morning: start with work context | ||
| ccst work | ||
| # Need full access for personal project | ||
| ccst personal | ||
| # Quick switch back to work | ||
| ccst - | ||
| # Check current context anytime | ||
| ccst -c | ||
| ``` | ||
| ## Complete Command Reference | ||
| ### Basic Operations | ||
| - `ccst` - List contexts (defaults to user-level) | ||
| - `ccst <name>` - Switch to context | ||
| - `ccst -` - Switch to previous context | ||
| - `ccst -c` - Show current context name | ||
| - `ccst -q` - Quiet mode (only show current context) | ||
| ### Context Management Reference | ||
| - `ccst -n <name>` - Create new context from current settings | ||
| - `ccst -d <name>` - Delete context (interactive if no name) | ||
| - `ccst -r <name>` - Rename context (prompts for new name) | ||
| - `ccst -e [name]` - Edit context with $EDITOR | ||
| - `ccst -s [name]` - Show context content (JSON) | ||
| - `ccst -u` - Unset current context (removes settings file) | ||
| ### Import/Export Reference | ||
| - `ccst --export [name]` - Export context to stdout | ||
| - `ccst --import <name>` - Import context from stdin | ||
| ### Importer Commands | ||
| - `ccst import ccs` - Import from CCS settings (~/.ccs) | ||
| - `ccst import configs` - Import from configs directory (default: ~/.ccst) | ||
| - `ccst import configs -d <dir>` - Import from a custom configs directory | ||
| - `ccst import ccs -d <dir>` - Use custom configs directory for default.json | ||
| ### Merge Operations | ||
| - `ccst --merge-from <source> [target]` - Merge permissions from source into target (default: current) | ||
| - Source can be: `user`, another context name, or file path | ||
| - `ccst --merge-from <source> --merge-full [target]` - Merge ALL settings (not just permissions) | ||
| - `ccst --unmerge <source> [target]` - Remove previously merged permissions | ||
| - `ccst --unmerge <source> --merge-full [target]` - Remove ALL previously merged settings | ||
| - `ccst --merge-history [name]` - Show merge history for context | ||
| ### Settings Levels | ||
| - `ccst` - User-level contexts (default: `~/.claude/settings.json`) | ||
| - `ccst --in-project` - Project-level contexts (`./.claude/settings.json`) | ||
| - `ccst --local` - Local project contexts (`./.claude/settings.local.json`) | ||
| ### Other Options | ||
| - `ccst --completions <shell>` - Generate shell completions | ||
| - `ccst --help` - Show help information | ||
| ## Compatibility Note | ||
| ccst is a TypeScript port of cctx with some differences. Behavior and output are intentionally close to cctx, but there may be small UX or implementation differences. |
+2
-2
| { | ||
| "name": "@leynier/ccst", | ||
| "version": "0.5.2", | ||
| "version": "0.5.3", | ||
| "description": "Claude Code Switch Tools for managing contexts", | ||
@@ -59,2 +59,2 @@ "keywords": [ | ||
| } | ||
| } | ||
| } |
@@ -8,2 +8,3 @@ import { spawn } from "node:child_process"; | ||
| getLogPath, | ||
| getProcessByPort, | ||
| getRunningDaemonPid, | ||
@@ -50,23 +51,25 @@ isProcessRunning, | ||
| if (process.platform === "win32") { | ||
| // On Windows, use PowerShell with Start-Process -WindowStyle Hidden | ||
| // This is the only way to completely hide a console app that creates its own window | ||
| const ps = spawn( | ||
| "powershell", | ||
| [ | ||
| "-WindowStyle", | ||
| "Hidden", | ||
| "-Command", | ||
| `$p = Start-Process -FilePath '${ccsPath}' -ArgumentList 'config' -WindowStyle Hidden -PassThru; $p.Id`, | ||
| ], | ||
| { | ||
| stdio: ["ignore", "pipe", "ignore"], | ||
| windowsHide: true, | ||
| }, | ||
| ); | ||
| const output = await new Response(ps.stdout).text(); | ||
| pid = Number.parseInt(output.trim(), 10); | ||
| if (!Number.isFinite(pid)) { | ||
| // On Windows, use cmd /c start /B to launch without creating a new window | ||
| // This works with npm-installed .cmd wrappers that create their own console | ||
| const proc = spawn("cmd", ["/c", `start /B "" "${ccsPath}" config`], { | ||
| stdio: "ignore", | ||
| windowsHide: true, | ||
| detached: true, | ||
| }); | ||
| proc.unref(); | ||
| // Wait for the process to start, then find it by port | ||
| console.log(pc.dim("Starting CCS config daemon...")); | ||
| await new Promise((resolve) => setTimeout(resolve, 2000)); | ||
| // Find the process by port 3000 (dashboard port) | ||
| const foundPid = await getProcessByPort(3000); | ||
| if (foundPid === null) { | ||
| console.log(pc.red("Failed to start CCS config daemon")); | ||
| console.log( | ||
| pc.dim("Check if ccs is installed: npm install -g @anthropic/ccs"), | ||
| ); | ||
| return; | ||
| } | ||
| pid = foundPid; | ||
| } else { | ||
@@ -73,0 +76,0 @@ // On Unix, use regular spawn with detached mode |
+25
-8
@@ -117,3 +117,4 @@ import { existsSync, mkdirSync, unlinkSync } from "node:fs"; | ||
| if (process.platform === "win32") { | ||
| const proc = Bun.spawn(["cmd", "/c", `netstat -ano | findstr :${port}`], { | ||
| // Run netstat directly and parse ourselves for exact port matching | ||
| const proc = Bun.spawn(["netstat", "-ano", "-p", "tcp"], { | ||
| stdout: "pipe", | ||
@@ -124,10 +125,25 @@ stderr: "ignore", | ||
| await proc.exited; | ||
| const lines = output.trim().split("\n"); | ||
| const lines = output.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.includes("LISTENING") || line.includes("ESTABLISHED")) { | ||
| const parts = line.trim().split(/\s+/); | ||
| const pid = Number.parseInt(parts[parts.length - 1], 10); | ||
| if (Number.isFinite(pid) && pid > 0) { | ||
| return pid; | ||
| } | ||
| // Format: Proto Local Address Foreign Address State PID | ||
| // TCP 0.0.0.0:3000 0.0.0.0:0 LISTENING 12345 | ||
| const parts = line.trim().split(/\s+/); | ||
| if (parts.length < 5) continue; | ||
| const state = parts[3]; | ||
| const localAddr = parts[1]; | ||
| const pidStr = parts[4]; | ||
| if (state !== "LISTENING" || !localAddr || !pidStr) continue; | ||
| // Extract port from local address (last part after colon) | ||
| const portMatch = localAddr.match(/:(\d+)$/); | ||
| if (!portMatch?.[1]) continue; | ||
| const localPort = Number.parseInt(portMatch[1], 10); | ||
| if (localPort !== port) continue; | ||
| const pid = Number.parseInt(pidStr, 10); | ||
| if (Number.isFinite(pid) && pid > 0) { | ||
| return pid; | ||
| } | ||
@@ -137,2 +153,3 @@ } | ||
| } | ||
| // Unix: use lsof | ||
| const proc = Bun.spawn(["lsof", "-ti", `:${port}`], { | ||
@@ -139,0 +156,0 @@ stdout: "pipe", |
-321
| # ccst - Claude Code Switch Tools | ||
| > Fast and predictable way to manage Claude Code contexts (`~/.claude/settings.json`) | ||
| **ccst** (Claude Code Switch Tools) is inspired by [cctx](https://github.com/nwiizo/cctx), which is itself inspired by kubectx, and ports the cctx experience to TypeScript with additional capabilities. Switch between permission sets, environments, and settings with a single command. | ||
| ## Features | ||
| - Instant context switching | ||
| - Predictable UX with user-level defaults | ||
| - Security-first separation of work, personal, and project contexts | ||
| - Shell completions for major shells | ||
| - Previous context quick switch with `ccst -` | ||
| - File-based JSON contexts you can edit manually | ||
| ## Quick Start | ||
| ### Installation | ||
| Install globally with npm (default): | ||
| ```bash | ||
| npm install -g @leynier/ccst | ||
| ``` | ||
| Alternative package managers: | ||
| ```bash | ||
| # bun | ||
| bun add -g @leynier/ccst | ||
| # pnpm | ||
| pnpm add -g @leynier/ccst | ||
| # yarn | ||
| yarn global add @leynier/ccst | ||
| ``` | ||
| ### 30-Second Setup | ||
| ```bash | ||
| # 1. Create your first context from current settings | ||
| ccst -n personal | ||
| # 2. Create a restricted work context | ||
| ccst -n work | ||
| # 3. Switch between contexts | ||
| ccst work # Switch to work | ||
| ccst personal # Switch to personal | ||
| ccst - # Switch back to previous | ||
| ``` | ||
| ## Usage | ||
| ### Basic Commands | ||
| ```bash | ||
| # List all contexts | ||
| ccst | ||
| # Switch to a context | ||
| ccst work | ||
| # Switch to previous context | ||
| ccst - | ||
| # Show current context | ||
| ccst -c | ||
| ``` | ||
| ### Settings Level Management | ||
| ccst respects Claude Code's settings hierarchy with explicit flags: | ||
| ```bash | ||
| # Default: always uses user-level contexts | ||
| ccst # Manages ~/.claude/settings.json | ||
| # Explicit flags for project/local contexts | ||
| ccst --in-project # Manages ./.claude/settings.json | ||
| ccst --local # Manages ./.claude/settings.local.json | ||
| # All commands work with any level | ||
| ccst --in-project work # Switch to 'work' in project contexts | ||
| ccst --local staging # Switch to 'staging' in local contexts | ||
| ``` | ||
| ### Context Management | ||
| ```bash | ||
| # Create new context from current settings | ||
| ccst -n project-alpha | ||
| # Delete a context | ||
| ccst -d old-project | ||
| # Rename a context (prompts for new name) | ||
| ccst -r old-name | ||
| # Edit context with $EDITOR | ||
| ccst -e work | ||
| # Show context content (JSON) | ||
| ccst -s production | ||
| # Unset current context | ||
| ccst -u | ||
| ``` | ||
| ### Import/Export | ||
| ```bash | ||
| # Export context to file | ||
| ccst --export production > prod-settings.json | ||
| # Import context from file | ||
| ccst --import staging < staging-settings.json | ||
| # Share contexts between machines | ||
| ccst --export work | ssh remote-host 'ccst --import work' | ||
| ``` | ||
| ### Merge Permissions | ||
| Merge permissions from other contexts or files to build complex configurations: | ||
| ```bash | ||
| # Merge user settings into current context | ||
| ccst --merge-from user | ||
| # Merge from another context | ||
| ccst --merge-from personal work | ||
| # Merge from a specific file | ||
| ccst --merge-from /path/to/permissions.json staging | ||
| # Remove previously merged permissions | ||
| ccst --unmerge user | ||
| # View merge history | ||
| ccst --merge-history | ||
| # Merge into a specific context (default is current) | ||
| ccst --merge-from user production | ||
| ``` | ||
| Merge features: | ||
| - Smart deduplication | ||
| - History tracking | ||
| - Reversible unmerge | ||
| - Targeted merges | ||
| ### Shell Completions | ||
| Enable tab completion for faster workflow: | ||
| ```bash | ||
| # Bash | ||
| ccst --completions bash > ~/.local/share/bash-completion/completions/ccst | ||
| # Zsh | ||
| ccst --completions zsh > /usr/local/share/zsh/site-functions/_ccst | ||
| # Fish | ||
| ccst --completions fish > ~/.config/fish/completions/ccst.fish | ||
| # PowerShell | ||
| ccst --completions powershell > ccst.ps1 | ||
| ``` | ||
| ### Importing Profiles | ||
| ccst includes importer commands to migrate existing profiles: | ||
| ```bash | ||
| # Import from CCS profiles (~/.ccs/*.settings.json) | ||
| ccst import ccs | ||
| # Import from configs directory (default: ~/.ccst) | ||
| ccst import configs | ||
| # Use a custom configs directory | ||
| ccst import configs -d /path/to/configs | ||
| ``` | ||
| ## File Structure | ||
| Contexts are stored as individual JSON files at different levels: | ||
| User level (`~/.claude/`): | ||
| ```text | ||
| ~/.claude/ | ||
| ├── settings.json # Active user context | ||
| └── settings/ | ||
| ├── work.json # Work context | ||
| ├── personal.json # Personal context | ||
| └── .cctx-state.json # State tracking | ||
| ``` | ||
| Project level (`./.claude/`): | ||
| ```text | ||
| ./.claude/ | ||
| ├── settings.json # Shared project context | ||
| ├── settings.local.json # Local project context (gitignored) | ||
| └── settings/ | ||
| ├── staging.json # Staging context | ||
| ├── production.json # Production context | ||
| ├── .cctx-state.json # Project state | ||
| └── .cctx-state.local.json # Local state | ||
| ``` | ||
| ## Interactive Mode | ||
| When no arguments are provided, ccst can enter interactive mode: | ||
| - fzf integration when available | ||
| - Built-in fallback selector when fzf is not installed | ||
| - Current context highlighted in the list | ||
| ```bash | ||
| # Interactive context selection | ||
| CCTX_INTERACTIVE=1 ccst | ||
| ``` | ||
| ## Common Workflows | ||
| ### Professional Setup | ||
| ```bash | ||
| # Create restricted work context for safer collaboration | ||
| ccst -n work | ||
| ccst -e work # Edit to add restrictions | ||
| ``` | ||
| ### Project-Based Contexts | ||
| ```bash | ||
| # Create project-specific contexts | ||
| ccst -n client-alpha | ||
| ccst -n side-project | ||
| ccst -n experiments | ||
| # Switch based on current work | ||
| ccst client-alpha | ||
| ccst experiments | ||
| ``` | ||
| ### Daily Context Switching | ||
| ```bash | ||
| # Morning: start with work context | ||
| ccst work | ||
| # Need full access for personal project | ||
| ccst personal | ||
| # Quick switch back to work | ||
| ccst - | ||
| # Check current context anytime | ||
| ccst -c | ||
| ``` | ||
| ## Complete Command Reference | ||
| ### Basic Operations | ||
| - `ccst` - List contexts (defaults to user-level) | ||
| - `ccst <name>` - Switch to context | ||
| - `ccst -` - Switch to previous context | ||
| - `ccst -c` - Show current context name | ||
| - `ccst -q` - Quiet mode (only show current context) | ||
| ### Context Management Reference | ||
| - `ccst -n <name>` - Create new context from current settings | ||
| - `ccst -d <name>` - Delete context (interactive if no name) | ||
| - `ccst -r <name>` - Rename context (prompts for new name) | ||
| - `ccst -e [name]` - Edit context with $EDITOR | ||
| - `ccst -s [name]` - Show context content (JSON) | ||
| - `ccst -u` - Unset current context (removes settings file) | ||
| ### Import/Export Reference | ||
| - `ccst --export [name]` - Export context to stdout | ||
| - `ccst --import <name>` - Import context from stdin | ||
| ### Importer Commands | ||
| - `ccst import ccs` - Import from CCS settings (~/.ccs) | ||
| - `ccst import configs` - Import from configs directory (default: ~/.ccst) | ||
| - `ccst import configs -d <dir>` - Import from a custom configs directory | ||
| - `ccst import ccs -d <dir>` - Use custom configs directory for default.json | ||
| ### Merge Operations | ||
| - `ccst --merge-from <source> [target]` - Merge permissions from source into target (default: current) | ||
| - Source can be: `user`, another context name, or file path | ||
| - `ccst --merge-from <source> --merge-full [target]` - Merge ALL settings (not just permissions) | ||
| - `ccst --unmerge <source> [target]` - Remove previously merged permissions | ||
| - `ccst --unmerge <source> --merge-full [target]` - Remove ALL previously merged settings | ||
| - `ccst --merge-history [name]` - Show merge history for context | ||
| ### Settings Levels | ||
| - `ccst` - User-level contexts (default: `~/.claude/settings.json`) | ||
| - `ccst --in-project` - Project-level contexts (`./.claude/settings.json`) | ||
| - `ccst --local` - Local project contexts (`./.claude/settings.local.json`) | ||
| ### Other Options | ||
| - `ccst --completions <shell>` - Generate shell completions | ||
| - `ccst --help` - Show help information | ||
| ## Compatibility Note | ||
| ccst is a TypeScript port of cctx with some differences. Behavior and output are intentionally close to cctx, but there may be small UX or implementation differences. |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
84887
1.42%2344
0.56%