cli-profile-manager 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Claude Profile Marketplace Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,176 @@
1
+ # Claude Profile Manager
2
+
3
+ A marketplace for saving, sharing, and loading Claude CLI configuration profiles.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/cli-profile-manager)](https://www.npmjs.com/package/cli-profile-manager)
6
+ [![License](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
7
+
8
+ ## What is this?
9
+
10
+ Claude Profile Manager (`cpm`) lets you:
11
+
12
+ - **Save** your `.claude` folder as a shareable profile
13
+ - **Load** profiles to switch between configurations
14
+ - **Browse** a marketplace of community-created profiles
15
+ - **Share** your profiles with others
16
+
17
+ Dotfiles for Claude CLI, with a built-in plugin marketplace.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install -g cli-profile-manager
23
+ ```
24
+
25
+ Requires Node.js 18+.
26
+
27
+ ## Quick Start
28
+
29
+ ```bash
30
+ # Save your current Claude config as a profile
31
+ cpm save my-setup
32
+
33
+ # List profiles in the marketplace
34
+ cpm list
35
+
36
+ # Install a profile from the marketplace
37
+ cpm install marketplace/senior-developer
38
+
39
+ # Load your saved profile
40
+ cpm load my-setup
41
+ ```
42
+
43
+ ## Commands
44
+
45
+ ### Local Profile Management
46
+
47
+ ```bash
48
+ cpm save <name> [--description "desc"] [--tags "tag1,tag2"]
49
+ cpm load <name> [--backup] [--force]
50
+ cpm local
51
+ cpm info <name>
52
+ cpm delete <name> [--force]
53
+ ```
54
+
55
+ ### Marketplace
56
+
57
+ ```bash
58
+ cpm list [--category <cat>] [--refresh]
59
+ cpm search <query>
60
+ cpm install author/profile-name [--backup] [--force]
61
+ cpm info author/profile-name
62
+ ```
63
+
64
+ ### Publishing
65
+
66
+ ```bash
67
+ cpm publish <name>
68
+ cpm repo owner/repo-name
69
+ ```
70
+
71
+ ### Configuration
72
+
73
+ ```bash
74
+ cpm config
75
+ ```
76
+
77
+ ## What's in a Profile?
78
+
79
+ A profile snapshots your `.claude` folder:
80
+
81
+ - `CLAUDE.md` - Custom instructions
82
+ - `commands/` - Custom slash commands
83
+ - `hooks/` - Event hooks
84
+ - `skills/` - Custom skills
85
+ - `mcp.json` & `mcp_servers/` - MCP server configurations
86
+ - `plugins/` - User-authored plugins
87
+ - `agents/` - Custom agents
88
+
89
+ Sensitive files (credentials, API keys) are excluded by default.
90
+
91
+ ## Example Workflows
92
+
93
+ ### Switch Between Work Personas
94
+
95
+ ```bash
96
+ cpm save work-reviewer --tags "work,code-review"
97
+ cpm save docs-writer --tags "work,documentation"
98
+
99
+ cpm load work-reviewer
100
+ # ... do code reviews ...
101
+ cpm load docs-writer
102
+ # ... write documentation ...
103
+ ```
104
+
105
+ ### Share Team Configuration
106
+
107
+ ```bash
108
+ cpm save team-standards --description "Our team's Claude configuration"
109
+ cpm publish team-standards
110
+
111
+ # Team members install it
112
+ cpm install yourname/team-standards
113
+ ```
114
+
115
+ ### Try Community Profiles
116
+
117
+ ```bash
118
+ cpm list
119
+ cpm search python
120
+ cpm install marketplace/python-expert --backup
121
+
122
+ # Restore if needed
123
+ cpm load .claude-backup-*
124
+ ```
125
+
126
+ ## Profile Storage
127
+
128
+ ```
129
+ ~/.claude-profiles/
130
+ ├── config.json
131
+ ├── my-setup/
132
+ │ ├── profile.json
133
+ │ ├── CLAUDE.md
134
+ │ ├── commands/
135
+ │ └── hooks/
136
+ └── .cache/
137
+ └── marketplace-index.json
138
+ ```
139
+
140
+ ## Contributing Profiles
141
+
142
+ 1. Save your profile: `cpm save my-awesome-profile`
143
+ 2. Publish it: `cpm publish my-awesome-profile`
144
+
145
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed guidelines.
146
+
147
+ ## Custom Marketplace
148
+
149
+ Host your own marketplace (e.g., for your company):
150
+
151
+ 1. Fork this repository
152
+ 2. Add profiles to `profiles/`
153
+ 3. Update `index.json`
154
+ 4. Point users to your repo: `cpm repo your-org/your-marketplace`
155
+
156
+ ## Repository Structure
157
+
158
+ ```
159
+ cli-profile-manager/
160
+ ├── src/ # NPM package source
161
+ │ ├── cli.js # CLI entry point
162
+ │ ├── commands/ # Command implementations
163
+ │ └── utils/ # Utilities
164
+ ├── profiles/ # Marketplace profiles
165
+ │ └── author/
166
+ │ └── profile-name/
167
+ │ ├── profile.json
168
+ │ └── ...
169
+ ├── index.json # Marketplace index
170
+ ├── package.json
171
+ └── README.md
172
+ ```
173
+
174
+ ## License
175
+
176
+ MIT License - see [LICENSE](./LICENSE) for details.
@@ -0,0 +1,85 @@
1
+ # Auto-Install Claude Code + Marketplace Profiles
2
+
3
+ Install Claude Code and a marketplace profile automatically. One command, all platforms.
4
+
5
+ ## Codespaces / Devcontainers
6
+
7
+ Add a `postCreateCommand` to `.devcontainer/devcontainer.json`:
8
+
9
+ ```json
10
+ {
11
+ "name": "Dev with Claude Code",
12
+ "image": "mcr.microsoft.com/devcontainers/universal:2",
13
+ "features": {
14
+ "ghcr.io/devcontainers/features/node:1": {
15
+ "version": "lts"
16
+ }
17
+ },
18
+ "postCreateCommand": "node <(curl -fsSL https://raw.githubusercontent.com/brrichards/cli-profile-manager/main/scripts/install-profile.mjs) marketplace devtools",
19
+ "customizations": {
20
+ "vscode": {
21
+ "extensions": ["anthropic.claude-code"]
22
+ }
23
+ }
24
+ }
25
+ ```
26
+
27
+ ## Local Install
28
+
29
+ Requires Node.js 18+.
30
+
31
+ ```bash
32
+ curl -fsSL https://raw.githubusercontent.com/brrichards/cli-profile-manager/main/scripts/install-profile.mjs -o install-profile.mjs && node install-profile.mjs marketplace devtools
33
+ ```
34
+
35
+ Or from a cloned repo:
36
+
37
+ ```bash
38
+ node scripts/install-profile.mjs marketplace devtools
39
+ ```
40
+
41
+ ## Available Profiles
42
+
43
+ ```bash
44
+ node install-profile.mjs marketplace devtools
45
+ node install-profile.mjs marketplace code-quality
46
+ node install-profile.mjs marketplace git-workflow
47
+ ```
48
+
49
+ Full list in [`index.json`](../index.json).
50
+
51
+ ## How It Works
52
+
53
+ The script fetches the profile's `profile.json` manifest from GitHub and maps files into Claude Code's native structure:
54
+
55
+ | Marketplace Path | Installed To |
56
+ |---|---|
57
+ | `CLAUDE.md` | `~/.claude/CLAUDE.md` (appended) |
58
+ | `commands/<name>.md` | `~/.claude/skills/<name>/SKILL.md` |
59
+ | `hooks/<name>.md` | `~/.claude/hooks/<name>.md` |
60
+
61
+ ### Prerequisites
62
+
63
+ - **Node.js 18+** (uses built-in `fetch`, `fs`, and `path`)
64
+
65
+ ## Chaining With Existing Setup
66
+
67
+ ```json
68
+ {
69
+ "postCreateCommand": "npm install && node <(curl -fsSL https://raw.githubusercontent.com/brrichards/cli-profile-manager/main/scripts/install-profile.mjs) marketplace devtools"
70
+ }
71
+ ```
72
+
73
+ ## Multiple Profiles
74
+
75
+ ```bash
76
+ node install-profile.mjs marketplace devtools && node install-profile.mjs marketplace code-quality
77
+ ```
78
+
79
+ ## Environment Variables
80
+
81
+ | Variable | Default | Description |
82
+ |---|---|---|
83
+ | `SKIP_CLAUDE_INSTALL` | `0` | Skip Claude Code CLI install |
84
+ | `PROFILE_BRANCH` | `main` | Branch to fetch profiles from |
85
+ | `CLAUDE_HOME` | `~/.claude` | Override the Claude config directory |
package/index.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "lastUpdated": "2026-02-16T00:00:00Z",
4
+ "profiles": [
5
+ {
6
+ "name": "devtools",
7
+ "author": "marketplace",
8
+ "version": "1.0.0",
9
+ "description": "Developer productivity commands for dependency auditing, performance profiling, and scaffolding",
10
+ "tags": ["productivity", "scaffolding", "dependencies"],
11
+ "downloads": 0,
12
+ "stars": 0,
13
+ "createdAt": "2026-02-16T00:00:00Z",
14
+ "contents": {
15
+ "instructions": ["CLAUDE.md"],
16
+ "commands": ["deps", "perf", "scaffold"],
17
+ "hooks": ["pre-commit"]
18
+ }
19
+ },
20
+ {
21
+ "name": "code-quality",
22
+ "author": "marketplace",
23
+ "version": "1.0.0",
24
+ "description": "Code review, test generation, and type safety commands with quality-focused hooks",
25
+ "tags": ["code-review", "testing", "type-safety"],
26
+ "downloads": 0,
27
+ "stars": 0,
28
+ "createdAt": "2026-02-16T00:00:00Z",
29
+ "contents": {
30
+ "instructions": ["CLAUDE.md"],
31
+ "commands": ["review", "test-gen", "types"],
32
+ "hooks": ["post-save"]
33
+ }
34
+ },
35
+ {
36
+ "name": "git-workflow",
37
+ "author": "marketplace",
38
+ "version": "1.0.0",
39
+ "description": "Git workflow commands for PR creation, changelog generation, and commit management",
40
+ "tags": ["git", "workflow", "pull-requests"],
41
+ "downloads": 0,
42
+ "stars": 0,
43
+ "createdAt": "2026-02-16T00:00:00Z",
44
+ "contents": {
45
+ "instructions": ["CLAUDE.md"],
46
+ "commands": ["pr", "changelog", "squash"],
47
+ "hooks": ["pre-push"]
48
+ }
49
+ }
50
+ ]
51
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "cli-profile-manager",
3
+ "version": "0.0.1",
4
+ "description": "Save, share, and load Claude CLI profiles - a marketplace for Claude configurations",
5
+ "type": "module",
6
+ "main": "src/cli.js",
7
+ "bin": {
8
+ "cpm": "src/cli.js",
9
+ "claude-profiles": "src/cli.js"
10
+ },
11
+ "scripts": {
12
+ "test": "node --test 'test/**/*.test.js'"
13
+ },
14
+ "keywords": [
15
+ "claude",
16
+ "anthropic",
17
+ "cli",
18
+ "profiles",
19
+ "configuration",
20
+ "dotfiles"
21
+ ],
22
+ "author": "brrichards",
23
+ "license": "MIT",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/brrichards/cli-profile-manager.git"
27
+ },
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
31
+ "dependencies": {
32
+ "chalk": "^5.3.0",
33
+ "commander": "^12.0.0",
34
+ "inquirer": "^9.2.12",
35
+ "node-fetch": "^3.3.2",
36
+ "ora": "^8.0.1"
37
+ }
38
+ }
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Usage:
4
+ // npx -y https://raw.githubusercontent.com/brrichards/cli-profile-manager/main/scripts/install-profile.mjs marketplace devtools
5
+ // node install-profile.mjs <author> <profile>
6
+ //
7
+ // Environment variables (optional):
8
+ // SKIP_CLAUDE_INSTALL=1 Skip installing Claude Code CLI
9
+ // PROFILE_BRANCH=main Branch to fetch profiles from
10
+ // CLAUDE_HOME=<path> Override the Claude config directory
11
+
12
+ import { execSync } from "child_process";
13
+ import { mkdirSync, writeFileSync, appendFileSync, existsSync } from "fs";
14
+ import { join } from "path";
15
+ import { homedir } from "os";
16
+
17
+ const [author, profile] = process.argv.slice(2);
18
+ if (!author || !profile) {
19
+ console.error("Usage: install-profile.mjs <author> <profile>");
20
+ process.exit(1);
21
+ }
22
+
23
+ const REPO = "brrichards/cli-profile-manager";
24
+ const BRANCH = process.env.PROFILE_BRANCH || "main";
25
+ const RAW_BASE = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/profiles/${author}/${profile}`;
26
+ const CLAUDE_DIR = process.env.CLAUDE_HOME || join(homedir(), ".claude");
27
+
28
+ async function fetchText(url) {
29
+ const res = await fetch(url);
30
+ if (!res.ok) throw new Error(`Failed to fetch ${url}: ${res.status}`);
31
+ return res.text();
32
+ }
33
+
34
+ async function main() {
35
+ // Install Claude Code CLI
36
+ if (process.env.SKIP_CLAUDE_INSTALL !== "1") {
37
+ try {
38
+ execSync("claude --version", { stdio: "ignore" });
39
+ console.log("==> Claude Code CLI already installed, skipping.");
40
+ } catch {
41
+ console.log("==> Installing Claude Code CLI...");
42
+ execSync("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
43
+ }
44
+ }
45
+
46
+ // Fetch profile manifest
47
+ console.log(`==> Fetching profile: ${author}/${profile}...`);
48
+ const manifest = JSON.parse(await fetchText(`${RAW_BASE}/profile.json`));
49
+ const contents = manifest.contents || {};
50
+
51
+ // Install instructions (CLAUDE.md)
52
+ for (const file of contents.instructions || []) {
53
+ console.log(` Installing instruction: ${file}`);
54
+ const body = await fetchText(`${RAW_BASE}/${file}`);
55
+ mkdirSync(CLAUDE_DIR, { recursive: true });
56
+ appendFileSync(join(CLAUDE_DIR, "CLAUDE.md"), body + "\n");
57
+ }
58
+
59
+ // Install commands as skills
60
+ for (const cmd of contents.commands || []) {
61
+ console.log(` Installing skill: ${cmd}`);
62
+ const skillDir = join(CLAUDE_DIR, "skills", cmd);
63
+ mkdirSync(skillDir, { recursive: true });
64
+ const body = await fetchText(`${RAW_BASE}/commands/${cmd}.md`);
65
+ const desc = body.split("\n")[0];
66
+ writeFileSync(
67
+ join(skillDir, "SKILL.md"),
68
+ `---\nname: ${cmd}\ndescription: ${desc}\n---\n\n${body}\n`
69
+ );
70
+ }
71
+
72
+ // Install hooks
73
+ for (const hook of contents.hooks || []) {
74
+ console.log(` Installing hook: ${hook}`);
75
+ const hooksDir = join(CLAUDE_DIR, "hooks");
76
+ mkdirSync(hooksDir, { recursive: true });
77
+ const body = await fetchText(`${RAW_BASE}/hooks/${hook}.md`);
78
+ writeFileSync(join(hooksDir, `${hook}.md`), body);
79
+ }
80
+
81
+ console.log(`\n==> Done! Profile '${author}/${profile}' installed to ${CLAUDE_DIR}`);
82
+ }
83
+
84
+ main().catch((err) => {
85
+ console.error(err.message);
86
+ process.exit(1);
87
+ });
package/src/cli.js ADDED
@@ -0,0 +1,165 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import {
6
+ saveProfile,
7
+ loadProfile,
8
+ listLocalProfiles,
9
+ deleteLocalProfile,
10
+ showProfileInfo
11
+ } from './commands/local.js';
12
+ import {
13
+ listMarketplace,
14
+ searchMarketplace,
15
+ installFromMarketplace,
16
+ showMarketplaceInfo
17
+ } from './commands/marketplace.js';
18
+ import {
19
+ publishProfile,
20
+ setRepository
21
+ } from './commands/publish.js';
22
+ import { getConfig } from './utils/config.js';
23
+
24
+ const VERSION = '1.0.0';
25
+
26
+ const program = new Command();
27
+
28
+ // Banner
29
+ const banner = `
30
+ ${chalk.cyan(' ____ ____ __ __')}
31
+ ${chalk.cyan(' / ___| _ \\| \\/ |')}
32
+ ${chalk.cyan(' | | | |_) | |\\/| |')}
33
+ ${chalk.cyan(' | |___| __/| | | |')}
34
+ ${chalk.cyan(' \\____|_| |_| |_|')}
35
+
36
+ ${chalk.magenta('Claude Profile Manager v' + VERSION)}
37
+ `;
38
+
39
+ program
40
+ .name('cpm')
41
+ .description('Save, share, and load Claude CLI profiles')
42
+ .version(VERSION)
43
+ .addHelpText('before', banner);
44
+
45
+ // ============================================================================
46
+ // Local Profile Commands
47
+ // ============================================================================
48
+
49
+ program
50
+ .command('save <name>')
51
+ .description('Save current .claude folder as a profile snapshot')
52
+ .option('-d, --description <desc>', 'Profile description')
53
+ .option('-t, --tags <tags>', 'Comma-separated tags')
54
+ .option('--include-secrets', 'Include sensitive files (use with caution)')
55
+ .action(async (name, options) => {
56
+ await saveProfile(name, options);
57
+ });
58
+
59
+ program
60
+ .command('load <name>')
61
+ .description('Load a profile (local or from marketplace)')
62
+ .option('-f, --force', 'Overwrite existing .claude folder without prompting')
63
+ .option('--backup', 'Backup current .claude folder before loading')
64
+ .option('--marketplace', 'Load from marketplace instead of local')
65
+ .action(async (name, options) => {
66
+ if (options.marketplace || name.includes('/')) {
67
+ await installFromMarketplace(name, options);
68
+ } else {
69
+ await loadProfile(name, options);
70
+ }
71
+ });
72
+
73
+ program
74
+ .command('local')
75
+ .description('List locally saved profiles')
76
+ .action(async () => {
77
+ await listLocalProfiles();
78
+ });
79
+
80
+ program
81
+ .command('delete <name>')
82
+ .description('Delete a locally saved profile')
83
+ .option('-f, --force', 'Delete without confirmation')
84
+ .action(async (name, options) => {
85
+ await deleteLocalProfile(name, options);
86
+ });
87
+
88
+ program
89
+ .command('info <name>')
90
+ .description('Show detailed info about a profile')
91
+ .option('--marketplace', 'Show marketplace profile info')
92
+ .action(async (name, options) => {
93
+ if (options.marketplace || name.includes('/')) {
94
+ await showMarketplaceInfo(name);
95
+ } else {
96
+ await showProfileInfo(name);
97
+ }
98
+ });
99
+
100
+ // ============================================================================
101
+ // Marketplace Commands
102
+ // ============================================================================
103
+
104
+ program
105
+ .command('list')
106
+ .alias('browse')
107
+ .description('Browse profiles in the marketplace')
108
+ .option('-c, --category <category>', 'Filter by category')
109
+ .option('--refresh', 'Force refresh the marketplace index')
110
+ .action(async (options) => {
111
+ await listMarketplace(options);
112
+ });
113
+
114
+ program
115
+ .command('search <query>')
116
+ .description('Search the marketplace')
117
+ .action(async (query) => {
118
+ await searchMarketplace(query);
119
+ });
120
+
121
+ program
122
+ .command('install <profile>')
123
+ .description('Install a profile from the marketplace (format: author/name)')
124
+ .option('-f, --force', 'Overwrite existing .claude folder')
125
+ .option('--backup', 'Backup current config before installing')
126
+ .action(async (profile, options) => {
127
+ await installFromMarketplace(profile, options);
128
+ });
129
+
130
+ // ============================================================================
131
+ // Publishing Commands
132
+ // ============================================================================
133
+
134
+ program
135
+ .command('publish <name>')
136
+ .description('Publish a local profile to the marketplace')
137
+ .action(async (name, options) => {
138
+ await publishProfile(name, options);
139
+ });
140
+
141
+ program
142
+ .command('repo <repository>')
143
+ .description('Set custom marketplace repository (format: owner/repo)')
144
+ .action(async (repository) => {
145
+ await setRepository(repository);
146
+ });
147
+
148
+ // ============================================================================
149
+ // Utility Commands
150
+ // ============================================================================
151
+
152
+ program
153
+ .command('config')
154
+ .description('Show current configuration')
155
+ .action(async () => {
156
+ const config = await getConfig();
157
+ console.log(banner);
158
+ console.log(chalk.bold('Configuration:\n'));
159
+ console.log(` ${chalk.cyan('Profiles Directory:')} ${config.profilesDir}`);
160
+ console.log(` ${chalk.cyan('Claude Directory:')} ${config.claudeDir}`);
161
+ console.log(` ${chalk.cyan('Marketplace Repo:')} ${config.marketplaceRepo}`);
162
+ console.log(` ${chalk.cyan('Cache Directory:')} ${config.cacheDir}`);
163
+ });
164
+
165
+ program.parse();