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 +21 -0
- package/README.md +176 -0
- package/docs/devcontainer-setup.md +85 -0
- package/index.json +51 -0
- package/package.json +38 -0
- package/scripts/install-profile.mjs +87 -0
- package/src/cli.js +165 -0
- package/src/commands/local.js +307 -0
- package/src/commands/marketplace.js +403 -0
- package/src/commands/publish.js +252 -0
- package/src/utils/auth.js +403 -0
- package/src/utils/config.js +102 -0
- package/src/utils/snapshot.js +421 -0
- package/test/cli.test.js +22 -0
- package/test/config.test.js +15 -0
- package/test/references.test.js +39 -0
- package/test/snapshot.test.js +61 -0
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
|
+
[](https://www.npmjs.com/package/cli-profile-manager)
|
|
6
|
+
[](./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();
|