claude-switch-profile 1.4.19 → 1.4.21
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/.github/workflows/update-brew.yml +8 -0
- package/Formula/claude-switch-profile.rb +2 -16
- package/README.md +27 -1
- package/bin/csp.js +2 -2
- package/package.json +1 -1
- package/src/commands/uninstall.js +53 -64
|
@@ -3,6 +3,9 @@ name: Update Homebrew Formula
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
tags: ['v*']
|
|
6
|
+
workflow_run:
|
|
7
|
+
workflows: ["Release on push to main"]
|
|
8
|
+
types: [completed]
|
|
6
9
|
workflow_dispatch:
|
|
7
10
|
inputs:
|
|
8
11
|
version:
|
|
@@ -11,18 +14,23 @@ on:
|
|
|
11
14
|
|
|
12
15
|
jobs:
|
|
13
16
|
bump-formula:
|
|
17
|
+
if: github.event_name != 'workflow_run' || github.event.workflow_run.conclusion == 'success'
|
|
14
18
|
runs-on: ubuntu-latest
|
|
15
19
|
permissions:
|
|
16
20
|
contents: write # Cho phép GITHUB_TOKEN mặc định được ghi dữ liệu vào repo này
|
|
17
21
|
steps:
|
|
18
22
|
- name: Checkout Repository
|
|
19
23
|
uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
20
26
|
|
|
21
27
|
- name: Resolve Version
|
|
22
28
|
id: version
|
|
23
29
|
run: |
|
|
24
30
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
|
25
31
|
VERSION="${{ github.event.inputs.version }}"
|
|
32
|
+
elif [ "${{ github.event_name }}" = "workflow_run" ]; then
|
|
33
|
+
VERSION=$(node -e "console.log(JSON.parse(require('fs').readFileSync('package.json', 'utf8')).version)")
|
|
26
34
|
else
|
|
27
35
|
VERSION="${{ github.ref_name }}"
|
|
28
36
|
VERSION="${VERSION#v}"
|
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
# Homebrew Formula Template for claude-switch-profile
|
|
2
|
-
#
|
|
3
|
-
# INSTRUCTIONS FOR MAINTAINER:
|
|
4
|
-
# 1. Create a new GitHub repository named `homebrew-tap` (e.g. `ThanhThi2895/homebrew-tap`).
|
|
5
|
-
# 2. Inside that repository, create a `Formula/` directory.
|
|
6
|
-
# 3. Copy this file into `Formula/claude-switch-profile.rb`.
|
|
7
|
-
# 4. Update the `url` and `sha256` fields with the latest npm tarball release.
|
|
8
|
-
# (You can get the tarball url from `npm view claude-switch-profile dist.tarball`)
|
|
9
|
-
# (You must calculate the sha256 of the tarball, e.g. `curl -sL <tarball_url> | shasum -a 256`)
|
|
10
|
-
|
|
11
1
|
require "language/node"
|
|
12
2
|
|
|
13
3
|
class ClaudeSwitchProfile < Formula
|
|
14
4
|
desc "CLI tool for managing multiple Claude Code profiles"
|
|
15
5
|
homepage "https://github.com/ThanhThi2895/claude-switch-profile"
|
|
16
|
-
url "https://registry.npmjs.org/claude-switch-profile/-/claude-switch-profile-1.4.
|
|
17
|
-
sha256 "
|
|
6
|
+
url "https://registry.npmjs.org/claude-switch-profile/-/claude-switch-profile-1.4.20.tgz"
|
|
7
|
+
sha256 "5cb22677386f5220f92ccfe714e968e8121e27943daed2e816f6b1128cf8aba9"
|
|
18
8
|
license "MIT"
|
|
19
9
|
|
|
20
10
|
depends_on "node"
|
|
21
11
|
|
|
22
12
|
def install
|
|
23
|
-
# Language::Node.std_npm_install_args securely installs the node module into
|
|
24
|
-
# the Homebrew Cellar, making it completely independent of any global Node.js
|
|
25
|
-
# managers like NVM or FNM that the user might be running.
|
|
26
13
|
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
|
|
27
14
|
bin.install_symlink Dir["#{libexec}/bin/*"]
|
|
28
15
|
end
|
|
29
16
|
|
|
30
17
|
test do
|
|
31
|
-
# Simple test to verify the CLI initializes correctly
|
|
32
18
|
assert_match "Usage: csp", shell_output("#{bin}/csp --help")
|
|
33
19
|
end
|
|
34
20
|
end
|
package/README.md
CHANGED
|
@@ -51,6 +51,32 @@ brew install claude-switch-profile
|
|
|
51
51
|
npm install -g claude-switch-profile
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
## Uninstall
|
|
55
|
+
|
|
56
|
+
`csp uninstall` only removes the **CLI tool**. It does **not** delete any profile data.
|
|
57
|
+
|
|
58
|
+
- Profiles stay at `~/.claude-profiles/`
|
|
59
|
+
- Your `~/.claude` config is not mutated by this command
|
|
60
|
+
|
|
61
|
+
Choose uninstall method that matches how you installed CSP:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# npm global install
|
|
65
|
+
csp uninstall --method npm
|
|
66
|
+
# then run:
|
|
67
|
+
npm uninstall -g claude-switch-profile
|
|
68
|
+
|
|
69
|
+
# Homebrew install
|
|
70
|
+
csp uninstall --method brew
|
|
71
|
+
# then run:
|
|
72
|
+
brew uninstall claude-switch-profile
|
|
73
|
+
|
|
74
|
+
# Standalone install.sh
|
|
75
|
+
csp uninstall --method standalone
|
|
76
|
+
# this removes ~/.local/bin/csp and ~/.csp-cli directly
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use `--force` to skip confirmation.
|
|
54
80
|
|
|
55
81
|
## Quick Start
|
|
56
82
|
|
|
@@ -90,7 +116,7 @@ csp
|
|
|
90
116
|
| `csp import <file>` | Import profile from archive |
|
|
91
117
|
| `csp delete <name>` | Delete a profile |
|
|
92
118
|
| `csp deactivate` | Switch back to `default` profile |
|
|
93
|
-
| `csp uninstall
|
|
119
|
+
| `csp uninstall --method <npm\|brew\|standalone>` | Uninstall csp CLI and keep all profiles |
|
|
94
120
|
|
|
95
121
|
> 📖 **Full command reference with all options and detailed behavior:** [docs/commands-reference.md](docs/commands-reference.md)
|
|
96
122
|
|
package/bin/csp.js
CHANGED
|
@@ -152,9 +152,9 @@ program
|
|
|
152
152
|
|
|
153
153
|
program
|
|
154
154
|
.command('uninstall')
|
|
155
|
-
.description('
|
|
155
|
+
.description('Uninstall csp CLI while keeping all profile data intact')
|
|
156
156
|
.option('-f, --force', 'Skip confirmation prompt')
|
|
157
|
-
.option('--
|
|
157
|
+
.option('--method <method>', 'Install method: npm | brew | standalone')
|
|
158
158
|
.action(uninstallCommand);
|
|
159
159
|
|
|
160
160
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { existsSync, rmSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
2
4
|
import { createInterface } from 'node:readline';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { withLock, createBackup, warnIfClaudeRunning } from '../safety.js';
|
|
7
|
-
import { PROFILES_DIR, DEFAULT_PROFILE } from '../constants.js';
|
|
8
|
-
import { success, error, info, warn } from '../output-helpers.js';
|
|
5
|
+
import { success, info, warn } from '../output-helpers.js';
|
|
6
|
+
|
|
7
|
+
const METHODS = ['npm', 'brew', 'standalone'];
|
|
9
8
|
|
|
10
9
|
const confirm = (question) => {
|
|
11
10
|
return new Promise((resolve) => {
|
|
@@ -17,80 +16,70 @@ const confirm = (question) => {
|
|
|
17
16
|
});
|
|
18
17
|
};
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
const
|
|
19
|
+
const normalizeMethod = (method) => {
|
|
20
|
+
const normalized = (method || '').toLowerCase();
|
|
21
|
+
if (!normalized) return null;
|
|
22
|
+
return METHODS.includes(normalized) ? normalized : null;
|
|
23
|
+
};
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
info('
|
|
25
|
+
const printMethodHint = (method) => {
|
|
26
|
+
if (method === 'npm') {
|
|
27
|
+
info('Run this command to uninstall csp:');
|
|
28
|
+
info(' npm uninstall -g claude-switch-profile');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (method === 'brew') {
|
|
32
|
+
info('Run this command to uninstall csp:');
|
|
33
|
+
info(' brew uninstall claude-switch-profile');
|
|
26
34
|
return;
|
|
27
35
|
}
|
|
28
36
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
info('Removed standalone install artifacts:');
|
|
38
|
+
info(' ~/.local/bin/csp');
|
|
39
|
+
info(' ~/.csp-cli');
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const uninstallStandalone = () => {
|
|
43
|
+
const home = process.env.CSP_HOME || homedir();
|
|
44
|
+
const binDir = process.env.CSP_STANDALONE_BIN_DIR || join(home, '.local', 'bin');
|
|
45
|
+
|
|
46
|
+
rmSync(join(binDir, 'csp'), { force: true });
|
|
47
|
+
rmSync(join(home, '.csp-cli'), { recursive: true, force: true });
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const uninstallCommand = async (options) => {
|
|
51
|
+
const method = normalizeMethod(options.method);
|
|
52
|
+
|
|
53
|
+
if (!method) {
|
|
54
|
+
warn('Missing or invalid --method. Use one of: npm, brew, standalone');
|
|
55
|
+
return;
|
|
37
56
|
}
|
|
38
57
|
|
|
39
|
-
// Show what will happen
|
|
40
58
|
console.log('');
|
|
41
|
-
info('This will
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
} else if (active && profileExists(active)) {
|
|
45
|
-
info(` 1. Restore active profile "${active}" to ~/.claude (use --profile <name> to choose)`);
|
|
46
|
-
} else {
|
|
47
|
-
warn(' 1. No profile to restore (managed items will be removed)');
|
|
48
|
-
}
|
|
49
|
-
info(` 2. Remove all profiles: ${PROFILES_DIR}`);
|
|
50
|
-
info(' 3. You can then run: npm uninstall -g claude-switch-profile');
|
|
59
|
+
info('This will uninstall csp CLI only.');
|
|
60
|
+
info('Profiles are kept at ~/.claude-profiles (no data is removed).');
|
|
61
|
+
info(`Method: ${method}`);
|
|
51
62
|
console.log('');
|
|
52
63
|
|
|
53
64
|
if (!options.force) {
|
|
54
|
-
const confirmed = await confirm(
|
|
65
|
+
const confirmed = await confirm(`Proceed uninstall for method "${method}"? (y/N) `);
|
|
55
66
|
if (!confirmed) {
|
|
56
67
|
warn('Cancelled.');
|
|
57
68
|
return;
|
|
58
69
|
}
|
|
59
70
|
}
|
|
60
71
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
info(`Final backup created at ${backupPath}`);
|
|
68
|
-
} catch {
|
|
69
|
-
// Non-critical — profiles dir may be empty
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 2. Remove current managed items from ~/.claude
|
|
73
|
-
removeItems();
|
|
74
|
-
removeFiles();
|
|
75
|
-
|
|
76
|
-
// 3. Restore the chosen profile's config
|
|
77
|
-
if (restoreProfile && profileExists(restoreProfile)) {
|
|
78
|
-
const profileDir = getProfileDir(restoreProfile);
|
|
79
|
-
restoreItems(profileDir);
|
|
80
|
-
restoreFiles(profileDir);
|
|
81
|
-
success(`Restored "${restoreProfile}" profile to ~/.claude`);
|
|
82
|
-
} else {
|
|
83
|
-
warn('No profile restored. ~/.claude managed items have been cleared.');
|
|
84
|
-
}
|
|
85
|
-
});
|
|
72
|
+
if (method === 'standalone') {
|
|
73
|
+
uninstallStandalone();
|
|
74
|
+
success('Standalone csp uninstall completed.');
|
|
75
|
+
printMethodHint(method);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
86
78
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
if (!existsSync(join(process.env.CSP_HOME || homedir(), '.claude-profiles'))) {
|
|
80
|
+
info('No profiles directory found.');
|
|
81
|
+
}
|
|
90
82
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
info(' npm uninstall -g claude-switch-profile');
|
|
94
|
-
info('');
|
|
95
|
-
info('Restart your Claude Code session to apply changes.');
|
|
83
|
+
success('csp uninstall instructions are ready.');
|
|
84
|
+
printMethodHint(method);
|
|
96
85
|
};
|