A powerful CLI tool to manage multiple Claude configuration profiles using GitHub Gists as secure cloud storage. This tool enables you to store, restore, and synchronize Claude configurations across machines, supporting both macOS and Linux platforms with automatic credential format conversion.
Perfect for developers working with:
- Cloud Development Environments: GitPod, GitHub Codespaces, and other cloud IDEs
- Multiple Devices: Seamlessly sync profiles between your macOS laptop, Linux desktop, and cloud workspaces
- Team Environments: Share configurations across team development environments
- Ephemeral Environments: Quickly restore your Claude setup in temporary containers or VMs
- Profile Management: Store, restore, and delete multiple Claude configuration profiles
- Cloud Storage: Uses GitHub Gists (secret) for secure profile storage
- Cross-Platform Support: Works on macOS and Linux with automatic credential format conversion
- macOS Keychain Integration: Fully supports macOS Keychain credentials storage and retrieval
- Watch Mode: Automatically saves configuration changes to a profile with intelligent debouncing
- Profile Verification: Validates profile integrity before restoration
- No Dependencies: Uses dynamic module loading (use-m) - no package.json required
- Comprehensive Logging: Optional file logging and verbose mode for debugging
~/.claude/directory - entire directory with all subdirectories and files:- IDE lock files (
ide/*.lock) - Plugin configurations (
plugins/) - Project history and conversations (
projects/) - Todo items (
todos/) - Shell snapshots (
shell-snapshots/) - Settings and statistics (
settings.json,statsig/) - All other Claude-related data
- IDE lock files (
~/.claude.json(main configuration file)~/.claude.json.backup(configuration backup)- macOS Keychain credentials (exported to archive as
.macos.credentials.json) - Linux credentials file (
~/.claude/.credentials.json)
Important: When restoring a profile:
- Files are overwritten: Existing files with the same name will be replaced
- New files are added: Files from the backup are added to existing directories
- Existing files are preserved: Files not in the backup remain untouched
- Merge behavior: The restore process merges the backup with existing content:
- Project conversations are merged (existing conversations remain)
- Todo items are merged (existing todos remain)
- Settings files (
settings.json,config.json) are overwritten with backup versions - Lock files and temporary files are overwritten
- Node.js (v18 or higher)
- GitHub CLI (
gh) authenticated with gist permissions unzipcommand (pre-installed on macOS, may need installation on Linux)
bun install -g @link-assistant/claude-profilesnpm install -g @link-assistant/claude-profilesAfter installation, the tool will be available globally as claude-profiles:
claude-profiles --help-
Install GitHub CLI (if not already installed):
# macOS brew install gh # Ubuntu/Debian sudo apt install gh # Other Linux distributions # Visit: https://github.com/cli/cli#installation
-
Authenticate with GitHub:
gh auth login -s gist
Follow the prompts and ensure you grant the
gistscope for creating and managing gists. -
Clone or download the tool:
# Option A: Clone the repository git clone https://github.com/link-assistant/claude-profiles.git cd claude-profiles chmod +x claude-profiles.mjs # Option B: Download directly curl -O https://raw.githubusercontent.com/link-assistant/claude-profiles/main/claude-profiles.mjs chmod +x claude-profiles.mjs
-
Verify installation:
# If installed via npm claude-profiles --list # If using from source ./claude-profiles.mjs --list
claude-profiles --list
# or
claude-profiles -lclaude-profiles --store work
# or
claude-profiles --save work
# or
claude-profiles -s workclaude-profiles --restore personal
# or
claude-profiles -r personalclaude-profiles --delete old-profile
# or
claude-profiles -d old-profileclaude-profiles --verify work
# or
claude-profiles -v workNote: If you're using the tool from source instead of npm, prefix commands with ./ like ./claude-profiles.mjs --list
Automatically saves configuration changes to a profile with a 30-second throttle:
claude-profiles --watch work
# With verbose logging
claude-profiles --watch work --verbose
# With file logging
claude-profiles --watch work --log
# With custom log file
claude-profiles --watch work --log=/path/to/log-file.txtWatch Mode Features:
- Monitors all Claude configuration files for changes
- Debounced saves (waits 2 seconds after last change)
- Minimum 30-second interval between saves to prevent excessive updates
- On macOS, also monitors Keychain credentials changes
- Graceful shutdown with Ctrl+C
Enable detailed logging for troubleshooting:
claude-profiles --store work --verboseSave all output to a log file:
# Auto-generated filename with timestamp
claude-profiles --store work --log
# Custom log file
claude-profiles --store work --log=claude-backup.logExclude the projects folder from backups to reduce profile size:
# Store profile without projects folder
claude-profiles --store work --skip-projects
# Restore and watch without projects
claude-profiles --restore work --watch work --skip-projects
# Useful when projects folder is large
claude-profiles --watch work --skip-projectsUse Cases:
- Reduce backup size when projects folder contains large conversation histories
- Avoid hitting GitHub's 10MB gist size limit
- Focus on configuration and settings without project data
Profile names must follow these rules:
- Only lowercase letters (a-z)
- Numbers (0-9)
- Hyphens (-)
- Examples:
work,personal,client-1,dev-2024
The tool automatically handles credential format conversion between platforms:
When restoring a macOS profile on Linux:
- Keychain credentials are converted to Linux format
- Credentials are saved to
~/.claude/.credentials.json - Both old (underscore) and new (claudeAiOauth) formats are supported
When restoring a Linux profile on macOS:
- Linux credentials are converted to Keychain format
- Credentials are stored in macOS Keychain
- Legacy Linux formats are automatically upgraded
The tool supports multiple credential formats:
-
Modern Format (with claudeAiOauth wrapper):
{ "claudeAiOauth": { "accessToken": "...", "refreshToken": "...", "expiresAt": "...", "scopes": ["user:inference"], "subscriptionType": "max" } } -
Legacy Linux Format (underscore format):
{ "access_token": "...", "refresh_token": "...", "expiry_date": "...", "scopes": ["user:inference"], "subscriptionType": "max" }
All formats are automatically detected and converted as needed.
Problem: Token lacks gist permissions
β Permission error creating gist
Solution:
gh auth refresh -s gistProblem: Gist owned by different GitHub account
β HTTP 409 - Gist cannot be updated
Solution:
# Check current account
gh auth status
# Re-login with correct account
gh auth loginProblem: Too many API requests
β οΈ GitHub API rate limit exceeded
Solution: Wait a few minutes and try again
Problem: Claude configuration incomplete
β Cannot create profile - essential files are missing
Solution:
- Ensure Claude is properly configured
- Use Claude at least once to generate config files
- Check that
~/.claude/directory exists
Problem: Profile exceeds GitHub's 10MB gist limit
β Profile is too large for GitHub Gist (>10MB)
Solution:
- Clean up
~/.claude/directory - Remove unnecessary files or cache
- Consider splitting into multiple profiles
Problem: Profile verification fails
β Cannot restore profile - verification failed
Solution:
- Use
--verifyto check profile integrity - Create a new backup with
--store - Check if the profile was created on a different platform
Problem: Cannot access Keychain
β οΈ No credentials found in macOS Keychain
Solution:
- Ensure Claude has been used at least once
- Check Keychain Access app for "Claude Code-credentials"
- Grant terminal access to Keychain if prompted
Problem: unzip command not found
π¦ The unzip command is required but not installed
Solution:
# Ubuntu/Debian
sudo apt-get install unzip
# Alpine
apk add unzip
# RHEL/CentOS
sudo yum install unzipProblem: Cannot connect to GitHub
π Network error while accessing GitHub
Solution:
- Check internet connection
- Verify GitHub is accessible:
ping github.com - Check proxy settings if behind firewall
Problem: Cannot read/write Claude files
π Permission denied
Solution:
# Check permissions
ls -la ~/.claude/
# Fix ownership (if needed)
chown -R $USER:$USER ~/.claudeProblem: No space for extraction
πΎ No space left on device
Solution:
- Free up disk space
- Use a different temp directory:
export TMPDIR=/path/to/space
- Gist Privacy: All profiles are stored as secret gists (not public)
- Credential Security:
- macOS: Stored securely in Keychain
- Linux: Stored in user-only readable file
- Transit: Base64 encoded (not encrypted)
- GitHub Authentication: Uses GitHub CLI's secure token storage
- File Permissions: Restored files maintain appropriate permissions
# Verbose mode for detailed logging
claude-profiles --store work --verbose
# Save debug output to file
claude-profiles --store work --verbose --log=debug.log# Verify GitHub CLI authentication
gh auth status
# Test gist access
echo "test" | gh gist create -
# List your gists
gh gist list --limit 5# View gist contents
gh gist list | grep claude-profiles
gh gist view <GIST_ID>
# Delete gist entirely (removes all profiles)
gh gist delete <GIST_ID>-
First Time Setup:
# 1. Install the tool (bun is faster) bun install -g @link-assistant/claude-profiles # or: npm install -g @link-assistant/claude-profiles # 2. Authenticate GitHub CLI gh auth login -s gist # 3. Create your first profile claude-profiles --store default # 4. List profiles to confirm claude-profiles --list
-
Switching Between Profiles:
# Save current state claude-profiles --store current-work # Switch to different profile claude-profiles --restore personal # Later, switch back claude-profiles --restore current-work
-
Migrating to New Machine:
# On old machine claude-profiles --store migration # On new machine (after installing and gh auth) bun install -g @link-assistant/claude-profiles claude-profiles --restore migration
- Profiles are stored as ZIP archives
- Archives are base64-encoded for gist compatibility
- Each profile is a separate file in the gist
- Gist description: "claude-profiles-backup"
profile.zip.base64
βββ .claude/ # Complete directory structure
β βββ .credentials.json # Linux credentials (if present)
β βββ ide/ # IDE lock files
β βββ plugins/ # Plugin configurations
β β βββ config.json
β β βββ repos/
β βββ projects/ # Project conversations
β β βββ [project-folders]/ # Individual project histories
β βββ settings.json # Claude settings
β βββ shell-snapshots/ # Shell session snapshots
β βββ statsig/ # Usage statistics
β βββ todos/ # Todo items
βββ .claude.json # Main configuration
βββ .claude.json.backup # Configuration backup
βββ .macos.credentials.json # macOS Keychain export (see note below)
Important Note about .macos.credentials.json:
- This is an internal file created by the tool, not a Claude system file
- It only exists within the backup archive stored on GitHub Gist
- Purpose: Exports macOS Keychain credentials for cross-platform compatibility
- On restore:
- To macOS: Credentials are restored directly to Keychain (file is not created on disk)
- To Linux: Credentials are converted and saved as
~/.claude/.credentials.json
- This file never appears in your local filesystem on macOS - credentials always stay in Keychain
The tool uses dynamic loading via use-m for zero-install dependencies:
command-stream@0.7.0- Shell command executionyargs@17.7.2- CLI argument parsingarchiver@7.0.1- ZIP archive creation
This project is released into the public domain under The Unlicense. See LICENSE file for details.
Contributions are welcome! Please feel free to submit issues or pull requests at: https://github.com/link-assistant/claude-profiles
This project uses Changesets for version management and automated releases.
-
Create a branch for your changes:
git checkout -b feature/my-feature
-
Make your changes and commit them
-
Create a changeset to document your changes:
npm run changeset
This will prompt you to:
- Select the version bump type (patch/minor/major)
- Provide a description of your changes
A new file will be created in
.changeset/directory. -
Commit the changeset along with your changes:
git add .changeset/ git commit -m "Add changeset for my feature" -
Create a pull request - the CI will validate that a changeset is present
Releases are fully automated via GitHub Actions with OIDC trusted publishing to npm:
-
Merge PR to main - Once your PR with a changeset is merged:
- The
release.ymlworkflow automatically detects the changeset - It bumps the version in
package.json - Updates
CHANGELOG.mdwith your changes - Commits the version bump back to main
- Publishes to npm using OIDC (no npm tokens needed!)
- Creates a GitHub release with release notes
- The
-
Manual Releases - Maintainers can also trigger releases manually via GitHub Actions:
Actions β Checks and release β Run workflowChoose between:
- Instant Release: Immediately bump version and publish
- Changeset PR: Create a PR with changeset for review
- Patch (0.0.x): Bug fixes, minor improvements, documentation
- Minor (0.x.0): New features, non-breaking changes
- Major (x.0.0): Breaking changes, major rewrites
The project uses GitHub Actions for continuous integration and deployment:
- PR Checks: Validates changesets and runs syntax checks on Node.js 18, 20, 22
- Automated Releases: Triggered on merge to main when changesets are present
- OIDC Publishing: Secure, token-free publishing to npm registry
- No manual npm tokens: Uses OpenID Connect for trusted publishing
For issues, questions, or feature requests, please open an issue on GitHub: https://github.com/link-assistant/claude-profiles/issues