coding-friend-cli 1.10.0 → 1.11.0
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/README.md +17 -7
- package/dist/{chunk-BCYBFGVD.js → chunk-4JL3SR5V.js} +60 -0
- package/dist/{chunk-TLLWOWYU.js → chunk-E2XX5MIM.js} +1 -1
- package/dist/{chunk-4C4EKYM3.js → chunk-EL6BAAKL.js} +1 -1
- package/dist/{chunk-AHGBESGW.js → chunk-GJLNN6X5.js} +47 -1
- package/dist/{chunk-YAOUAJZP.js → chunk-HYLS67T7.js} +1 -1
- package/dist/{chunk-UR5XUEH5.js → chunk-RN5UYDIT.js} +22 -6
- package/dist/{chunk-EDVZPZ3B.js → chunk-XIZJ64JK.js} +1 -1
- package/dist/{chunk-HQ5BPWEV.js → chunk-ZS7BLEYT.js} +27 -27
- package/dist/{config-6P3SE3NS.js → config-GYJGDXGV.js} +10 -10
- package/dist/{dev-4NLCK6YG.js → dev-GFFXRZJC.js} +4 -4
- package/dist/{host-BPO2STZA.js → host-SWIWQRRL.js} +2 -2
- package/dist/index.js +22 -22
- package/dist/{init-BG2ESQQC.js → init-QRUDHFME.js} +11 -11
- package/dist/{install-YEAWW7ZX.js → install-FQTMSBGK.js} +32 -11
- package/dist/{mcp-54UB5MF2.js → mcp-H3K67N2P.js} +2 -2
- package/dist/{permission-GPOUJUZS.js → permission-DIJMCOZX.js} +2 -2
- package/dist/postinstall.js +1 -1
- package/dist/{session-STYOO4A4.js → session-2APBPDZF.js} +4 -2
- package/dist/{statusline-L2CYEV4H.js → statusline-H2WUKOJ6.js} +2 -2
- package/dist/{uninstall-3ISPGQHE.js → uninstall-A2LJR2OD.js} +50 -6
- package/dist/{update-EN6S3FKT.js → update-RJSWHCCR.js} +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,10 +16,18 @@ npm i -g coding-friend-cli
|
|
|
16
16
|
## Commands
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
cf install
|
|
20
|
-
|
|
21
|
-
cf
|
|
22
|
-
|
|
19
|
+
cf install # Install plugin (interactive scope chooser)
|
|
20
|
+
cf install --user # Install at user scope (all projects)
|
|
21
|
+
cf install --global # Same as --user
|
|
22
|
+
cf install --project # Install at project scope (shared via git)
|
|
23
|
+
cf install --local # Install at local scope (this machine only)
|
|
24
|
+
# 💡 Safe to run multiple times (idempotent).
|
|
25
|
+
cf uninstall # Uninstall plugin (interactive scope chooser)
|
|
26
|
+
cf uninstall --user # Uninstall from user scope (full cleanup)
|
|
27
|
+
cf uninstall --global # Same as --user
|
|
28
|
+
cf uninstall --project # Uninstall from project scope only
|
|
29
|
+
cf uninstall --local # Uninstall from local scope only
|
|
30
|
+
# 💡 Interactive — asks for confirmation before acting.
|
|
23
31
|
cf init # Initialize workspace (interactive)
|
|
24
32
|
# 💡 You can run this anywhere, anytime.
|
|
25
33
|
cf config # Manage Coding Friend configuration (interactive menu)
|
|
@@ -32,10 +40,12 @@ cf mcp [path] # Setup MCP server for LLM integration
|
|
|
32
40
|
cf permission # Manage Claude Code permission rules for Coding Friend
|
|
33
41
|
cf permission --all # Apply all recommended permissions without prompts
|
|
34
42
|
cf statusline # Setup coding-friend statusline
|
|
35
|
-
cf update
|
|
36
|
-
cf update --cli
|
|
37
|
-
cf update --plugin
|
|
43
|
+
cf update # Update plugin + CLI + statusline
|
|
44
|
+
cf update --cli # Update only the CLI (npm package)
|
|
45
|
+
cf update --plugin # Update only the Claude Code plugin
|
|
38
46
|
cf update --statusline # Update only the statusline
|
|
47
|
+
cf update --project # Update plugin at project scope
|
|
48
|
+
cf update --local # Update plugin at local scope
|
|
39
49
|
cf dev on [path] # Switch to local plugin source for development
|
|
40
50
|
cf dev off # Switch back to remote marketplace
|
|
41
51
|
cf dev status # Show current dev mode (local or remote)
|
|
@@ -22,6 +22,8 @@ _cf_completions() {
|
|
|
22
22
|
local cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
23
23
|
local prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
24
24
|
local commands="install uninstall init config host mcp permission statusline update dev session"
|
|
25
|
+
local scope_flags="--user --global --project --local"
|
|
26
|
+
local update_flags="--cli --plugin --statusline --user --global --project --local"
|
|
25
27
|
|
|
26
28
|
# Subcommands for 'dev'
|
|
27
29
|
if [[ "\${COMP_WORDS[1]}" == "dev" && \${COMP_CWORD} -eq 2 ]]; then
|
|
@@ -41,6 +43,18 @@ _cf_completions() {
|
|
|
41
43
|
return
|
|
42
44
|
fi
|
|
43
45
|
|
|
46
|
+
# Flag completion for install/uninstall
|
|
47
|
+
if [[ "\${COMP_WORDS[1]}" == "install" || "\${COMP_WORDS[1]}" == "uninstall" ]] && [[ "$cur" == -* ]]; then
|
|
48
|
+
COMPREPLY=($(compgen -W "$scope_flags" -- "$cur"))
|
|
49
|
+
return
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Flag completion for update
|
|
53
|
+
if [[ "\${COMP_WORDS[1]}" == "update" && "$cur" == -* ]]; then
|
|
54
|
+
COMPREPLY=($(compgen -W "$update_flags" -- "$cur"))
|
|
55
|
+
return
|
|
56
|
+
fi
|
|
57
|
+
|
|
44
58
|
COMPREPLY=($(compgen -W "$commands" -- "$cur"))
|
|
45
59
|
}
|
|
46
60
|
complete -o default -F _cf_completions cf
|
|
@@ -62,8 +76,31 @@ var ZSH_FUNCTION_BODY = `_cf() {
|
|
|
62
76
|
'session:Save and load Claude Code sessions across machines'
|
|
63
77
|
)
|
|
64
78
|
|
|
79
|
+
local -a scope_flags
|
|
80
|
+
scope_flags=(
|
|
81
|
+
'--user[Install at user scope (all projects)]'
|
|
82
|
+
'--global[Install at user scope (all projects)]'
|
|
83
|
+
'--project[Install at project scope (shared via git)]'
|
|
84
|
+
'--local[Install at local scope (this machine only)]'
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
local -a update_flags
|
|
88
|
+
update_flags=(
|
|
89
|
+
'--cli[Update only the CLI (npm package)]'
|
|
90
|
+
'--plugin[Update only the Claude Code plugin]'
|
|
91
|
+
'--statusline[Update only the statusline]'
|
|
92
|
+
'--user[Update plugin at user scope (all projects)]'
|
|
93
|
+
'--global[Update plugin at user scope (all projects)]'
|
|
94
|
+
'--project[Update plugin at project scope]'
|
|
95
|
+
'--local[Update plugin at local scope]'
|
|
96
|
+
)
|
|
97
|
+
|
|
65
98
|
if (( CURRENT == 2 )); then
|
|
66
99
|
_describe 'command' commands
|
|
100
|
+
elif (( CURRENT >= 3 )) && [[ "\${words[2]}" == "install" || "\${words[2]}" == "uninstall" ]]; then
|
|
101
|
+
_values 'flags' $scope_flags
|
|
102
|
+
elif (( CURRENT >= 3 )) && [[ "\${words[2]}" == "update" ]]; then
|
|
103
|
+
_values 'flags' $update_flags
|
|
67
104
|
elif (( CURRENT == 3 )) && [[ "\${words[2]}" == "dev" ]]; then
|
|
68
105
|
local -a subcommands
|
|
69
106
|
subcommands=(
|
|
@@ -109,12 +146,27 @@ complete -c cf -n "__fish_use_subcommand" -a statusline -d "Setup coding-friend
|
|
|
109
146
|
complete -c cf -n "__fish_use_subcommand" -a update -d "Update coding-friend plugin and refresh statusline"
|
|
110
147
|
complete -c cf -n "__fish_use_subcommand" -a dev -d "Switch between local and remote plugin for development"
|
|
111
148
|
complete -c cf -n "__fish_use_subcommand" -a session -d "Save and load Claude Code sessions across machines"
|
|
149
|
+
# Scope flags for install/uninstall
|
|
150
|
+
complete -c cf -n "__fish_seen_subcommand_from install uninstall" -l user -d "User scope (all projects)"
|
|
151
|
+
complete -c cf -n "__fish_seen_subcommand_from install uninstall" -l global -d "User scope (all projects)"
|
|
152
|
+
complete -c cf -n "__fish_seen_subcommand_from install uninstall" -l project -d "Project scope (shared via git)"
|
|
153
|
+
complete -c cf -n "__fish_seen_subcommand_from install uninstall" -l local -d "Local scope (this machine only)"
|
|
154
|
+
# Flags for update
|
|
155
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l cli -d "Update only the CLI"
|
|
156
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l plugin -d "Update only the plugin"
|
|
157
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l statusline -d "Update only the statusline"
|
|
158
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l user -d "User scope (all projects)"
|
|
159
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l global -d "User scope (all projects)"
|
|
160
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l project -d "Project scope"
|
|
161
|
+
complete -c cf -n "__fish_seen_subcommand_from update" -l local -d "Local scope"
|
|
162
|
+
# Dev subcommands
|
|
112
163
|
complete -c cf -n "__fish_seen_subcommand_from dev" -a on -d "Switch to local plugin source"
|
|
113
164
|
complete -c cf -n "__fish_seen_subcommand_from dev" -a off -d "Switch back to remote marketplace"
|
|
114
165
|
complete -c cf -n "__fish_seen_subcommand_from dev" -a status -d "Show current dev mode"
|
|
115
166
|
complete -c cf -n "__fish_seen_subcommand_from dev" -a restart -d "Restart dev mode"
|
|
116
167
|
complete -c cf -n "__fish_seen_subcommand_from dev" -a sync -d "Sync local plugin files"
|
|
117
168
|
complete -c cf -n "__fish_seen_subcommand_from dev" -a update -d "Update local dev plugin"
|
|
169
|
+
# Session subcommands
|
|
118
170
|
complete -c cf -n "__fish_seen_subcommand_from session" -a save -d "Save current session to docs/sessions/"
|
|
119
171
|
complete -c cf -n "__fish_seen_subcommand_from session" -a load -d "Load a saved session from docs/sessions/"
|
|
120
172
|
`;
|
|
@@ -126,6 +178,8 @@ Register-ArgumentCompleter -Native -CommandName cf -ScriptBlock {
|
|
|
126
178
|
$commands = @('install','uninstall','init','config','host','mcp','permission','statusline','update','dev','session')
|
|
127
179
|
$devSubcommands = @('on','off','status','restart','sync','update')
|
|
128
180
|
$sessionSubcommands = @('save','load')
|
|
181
|
+
$scopeFlags = @('--user','--global','--project','--local')
|
|
182
|
+
$updateFlags = @('--cli','--plugin','--statusline','--user','--global','--project','--local')
|
|
129
183
|
$words = $commandAst.CommandElements
|
|
130
184
|
if ($words.Count -ge 2 -and $words[1].ToString() -eq 'dev') {
|
|
131
185
|
$devSubcommands | Where-Object { $_ -like "$wordToComplete*" } |
|
|
@@ -133,6 +187,12 @@ Register-ArgumentCompleter -Native -CommandName cf -ScriptBlock {
|
|
|
133
187
|
} elseif ($words.Count -ge 2 -and $words[1].ToString() -eq 'session') {
|
|
134
188
|
$sessionSubcommands | Where-Object { $_ -like "$wordToComplete*" } |
|
|
135
189
|
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
190
|
+
} elseif ($words.Count -ge 2 -and ($words[1].ToString() -eq 'install' -or $words[1].ToString() -eq 'uninstall')) {
|
|
191
|
+
$scopeFlags | Where-Object { $_ -like "$wordToComplete*" } |
|
|
192
|
+
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
193
|
+
} elseif ($words.Count -ge 2 -and $words[1].ToString() -eq 'update') {
|
|
194
|
+
$updateFlags | Where-Object { $_ -like "$wordToComplete*" } |
|
|
195
|
+
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
136
196
|
} else {
|
|
137
197
|
$commands | Where-Object { $_ -like "$wordToComplete*" } |
|
|
138
198
|
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
globalConfigPath,
|
|
6
6
|
localConfigPath,
|
|
7
7
|
readJson
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
9
9
|
import {
|
|
10
10
|
log
|
|
11
11
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -33,6 +33,51 @@ async function askScope(label = "Save to:") {
|
|
|
33
33
|
]
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
+
async function askPluginScope() {
|
|
37
|
+
return select({
|
|
38
|
+
message: "Where should the plugin be installed?",
|
|
39
|
+
choices: [
|
|
40
|
+
{
|
|
41
|
+
name: "User / Global \u2014 available in all projects",
|
|
42
|
+
value: "user"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "Project \u2014 shared with team via .claude/settings.json",
|
|
46
|
+
value: "project"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "Local \u2014 this machine only, not shared (gitignored)",
|
|
50
|
+
value: "local"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async function resolveScope(opts) {
|
|
56
|
+
const flags = [
|
|
57
|
+
{ key: "user", scope: "user" },
|
|
58
|
+
{ key: "global", scope: "user" },
|
|
59
|
+
{ key: "project", scope: "project" },
|
|
60
|
+
{ key: "local", scope: "local" }
|
|
61
|
+
];
|
|
62
|
+
const active = flags.filter((f) => opts[f.key] === true);
|
|
63
|
+
const uniqueScopes = new Set(active.map((f) => f.scope));
|
|
64
|
+
if (uniqueScopes.size > 1) {
|
|
65
|
+
log.error(
|
|
66
|
+
"Only one scope flag can be used at a time: --user, --global, --project, or --local"
|
|
67
|
+
);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
if (uniqueScopes.size === 1) {
|
|
71
|
+
return active[0].scope;
|
|
72
|
+
}
|
|
73
|
+
if (!process.stdin.isTTY) {
|
|
74
|
+
log.error(
|
|
75
|
+
"No scope flag provided and stdin is not interactive. Use --user (or --global), --project, or --local."
|
|
76
|
+
);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
return askPluginScope();
|
|
80
|
+
}
|
|
36
81
|
function showConfigHint() {
|
|
37
82
|
console.log(chalk.dim("Config files:"));
|
|
38
83
|
console.log(chalk.dim(" Global: ~/.coding-friend/config.json"));
|
|
@@ -127,6 +172,7 @@ export {
|
|
|
127
172
|
BACK,
|
|
128
173
|
injectBackChoice,
|
|
129
174
|
askScope,
|
|
175
|
+
resolveScope,
|
|
130
176
|
showConfigHint,
|
|
131
177
|
getScopeLabel,
|
|
132
178
|
formatScopeLabel,
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureStatusline,
|
|
3
3
|
getInstalledVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-HYLS67T7.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveScope
|
|
7
|
+
} from "./chunk-GJLNN6X5.js";
|
|
5
8
|
import {
|
|
6
9
|
ensureShellCompletion
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4JL3SR5V.js";
|
|
8
11
|
import {
|
|
9
12
|
commandExists,
|
|
10
13
|
run,
|
|
@@ -13,7 +16,7 @@ import {
|
|
|
13
16
|
import {
|
|
14
17
|
claudeSettingsPath,
|
|
15
18
|
readJson
|
|
16
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
17
20
|
import {
|
|
18
21
|
log
|
|
19
22
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -86,6 +89,13 @@ async function updateCommand(opts) {
|
|
|
86
89
|
const doCli = updateAll || !!opts.cli;
|
|
87
90
|
const doPlugin = updateAll || !!opts.plugin;
|
|
88
91
|
const doStatusline = updateAll || !!opts.statusline;
|
|
92
|
+
const hasScopeFlag = !!(opts.user || opts.global || opts.project || opts.local);
|
|
93
|
+
let scope;
|
|
94
|
+
if (doPlugin && hasScopeFlag) {
|
|
95
|
+
scope = await resolveScope(opts);
|
|
96
|
+
} else if (doPlugin && !hasScopeFlag) {
|
|
97
|
+
scope = "user";
|
|
98
|
+
}
|
|
89
99
|
console.log("=== \u{1F33F} Coding Friend Update \u{1F33F} ===");
|
|
90
100
|
console.log();
|
|
91
101
|
const currentVersion = getInstalledVersion();
|
|
@@ -135,12 +145,18 @@ async function updateCommand(opts) {
|
|
|
135
145
|
"Claude CLI not found. Install it first, or run: claude plugin update coding-friend@coding-friend-marketplace"
|
|
136
146
|
);
|
|
137
147
|
} else {
|
|
138
|
-
log.step(
|
|
139
|
-
|
|
148
|
+
log.step(
|
|
149
|
+
`Updating plugin${scope && scope !== "user" ? ` (${scope} scope)` : ""}...`
|
|
150
|
+
);
|
|
151
|
+
const updateArgs = [
|
|
140
152
|
"plugin",
|
|
141
153
|
"update",
|
|
142
154
|
"coding-friend@coding-friend-marketplace"
|
|
143
|
-
]
|
|
155
|
+
];
|
|
156
|
+
if (scope) {
|
|
157
|
+
updateArgs.push("--scope", scope);
|
|
158
|
+
}
|
|
159
|
+
const result = run("claude", updateArgs);
|
|
144
160
|
if (result === null) {
|
|
145
161
|
log.error(
|
|
146
162
|
"Plugin update failed. Try manually: claude plugin update coding-friend@coding-friend-marketplace"
|
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
// src/lib/json.ts
|
|
2
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
3
|
-
import { dirname } from "path";
|
|
4
|
-
function readJson(filePath) {
|
|
5
|
-
try {
|
|
6
|
-
const content = readFileSync(filePath, "utf-8");
|
|
7
|
-
return JSON.parse(content);
|
|
8
|
-
} catch {
|
|
9
|
-
return null;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
function writeJson(filePath, data) {
|
|
13
|
-
const dir = dirname(filePath);
|
|
14
|
-
if (!existsSync(dir)) {
|
|
15
|
-
mkdirSync(dir, { recursive: true });
|
|
16
|
-
}
|
|
17
|
-
writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
18
|
-
}
|
|
19
|
-
function mergeJson(filePath, data) {
|
|
20
|
-
const existing = readJson(filePath) ?? {};
|
|
21
|
-
writeJson(filePath, { ...existing, ...data });
|
|
22
|
-
}
|
|
23
|
-
|
|
24
1
|
// src/lib/paths.ts
|
|
25
2
|
import { homedir } from "os";
|
|
26
3
|
import { resolve, join } from "path";
|
|
@@ -91,10 +68,30 @@ function claudeSessionDir(encodedPath) {
|
|
|
91
68
|
return join(claudeProjectsDir(), encodedPath);
|
|
92
69
|
}
|
|
93
70
|
|
|
71
|
+
// src/lib/json.ts
|
|
72
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
73
|
+
import { dirname } from "path";
|
|
74
|
+
function readJson(filePath) {
|
|
75
|
+
try {
|
|
76
|
+
const content = readFileSync(filePath, "utf-8");
|
|
77
|
+
return JSON.parse(content);
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function writeJson(filePath, data) {
|
|
83
|
+
const dir = dirname(filePath);
|
|
84
|
+
if (!existsSync(dir)) {
|
|
85
|
+
mkdirSync(dir, { recursive: true });
|
|
86
|
+
}
|
|
87
|
+
writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
88
|
+
}
|
|
89
|
+
function mergeJson(filePath, data) {
|
|
90
|
+
const existing = readJson(filePath) ?? {};
|
|
91
|
+
writeJson(filePath, { ...existing, ...data });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
94
|
export {
|
|
95
|
-
readJson,
|
|
96
|
-
writeJson,
|
|
97
|
-
mergeJson,
|
|
98
95
|
resolvePath,
|
|
99
96
|
localConfigPath,
|
|
100
97
|
globalConfigPath,
|
|
@@ -108,5 +105,8 @@ export {
|
|
|
108
105
|
marketplaceClonePath,
|
|
109
106
|
globalConfigDir,
|
|
110
107
|
encodeProjectPath,
|
|
111
|
-
claudeSessionDir
|
|
108
|
+
claudeSessionDir,
|
|
109
|
+
readJson,
|
|
110
|
+
writeJson,
|
|
111
|
+
mergeJson
|
|
112
112
|
};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
findStatuslineHookPath,
|
|
3
|
+
isStatuslineConfigured,
|
|
4
|
+
saveStatuslineConfig,
|
|
5
|
+
selectStatuslineComponents,
|
|
6
|
+
writeStatuslineSettings
|
|
7
|
+
} from "./chunk-HYLS67T7.js";
|
|
1
8
|
import {
|
|
2
9
|
BACK,
|
|
3
10
|
applyDocsDirChange,
|
|
@@ -7,19 +14,12 @@ import {
|
|
|
7
14
|
getScopeLabel,
|
|
8
15
|
injectBackChoice,
|
|
9
16
|
showConfigHint
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
findStatuslineHookPath,
|
|
13
|
-
isStatuslineConfigured,
|
|
14
|
-
saveStatuslineConfig,
|
|
15
|
-
selectStatuslineComponents,
|
|
16
|
-
writeStatuslineSettings
|
|
17
|
-
} from "./chunk-YAOUAJZP.js";
|
|
17
|
+
} from "./chunk-GJLNN6X5.js";
|
|
18
18
|
import {
|
|
19
19
|
ensureShellCompletion,
|
|
20
20
|
hasShellCompletion,
|
|
21
21
|
removeShellCompletion
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-4JL3SR5V.js";
|
|
23
23
|
import {
|
|
24
24
|
ALL_COMPONENT_IDS,
|
|
25
25
|
DEFAULT_CONFIG
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
mergeJson,
|
|
34
34
|
readJson,
|
|
35
35
|
resolvePath
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
37
37
|
import {
|
|
38
38
|
log
|
|
39
39
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isMarketplaceRegistered,
|
|
3
3
|
isPluginInstalled
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E2XX5MIM.js";
|
|
5
5
|
import {
|
|
6
6
|
ensureStatusline
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HYLS67T7.js";
|
|
8
8
|
import {
|
|
9
9
|
ensureShellCompletion
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4JL3SR5V.js";
|
|
11
11
|
import "./chunk-PGLUEN7D.js";
|
|
12
12
|
import {
|
|
13
13
|
commandExists,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
pluginCachePath,
|
|
20
20
|
readJson,
|
|
21
21
|
writeJson
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
23
23
|
import {
|
|
24
24
|
log
|
|
25
25
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
} from "./chunk-RZRT7NGT.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveDocsDir
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XIZJ64JK.js";
|
|
7
7
|
import "./chunk-PGLUEN7D.js";
|
|
8
8
|
import {
|
|
9
9
|
run,
|
|
10
10
|
streamExec
|
|
11
11
|
} from "./chunk-UFGNO6CW.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-ZS7BLEYT.js";
|
|
13
13
|
import {
|
|
14
14
|
log
|
|
15
15
|
} from "./chunk-W5CD7WTX.js";
|
package/dist/index.js
CHANGED
|
@@ -13,40 +13,40 @@ var program = new Command();
|
|
|
13
13
|
program.name("cf").description(
|
|
14
14
|
"coding-friend CLI \u2014 host learning docs, setup MCP, init projects"
|
|
15
15
|
).version(pkg.version, "-v, --version");
|
|
16
|
-
program.command("install").description("Install the Coding Friend plugin into Claude Code").action(async () => {
|
|
17
|
-
const { installCommand } = await import("./install-
|
|
18
|
-
await installCommand();
|
|
16
|
+
program.command("install").description("Install the Coding Friend plugin into Claude Code").option("--user", "Install at user scope (all projects)").option("--global", "Install at user scope (all projects)").option("--project", "Install at project scope (shared via git)").option("--local", "Install at local scope (this machine only)").action(async (opts) => {
|
|
17
|
+
const { installCommand } = await import("./install-FQTMSBGK.js");
|
|
18
|
+
await installCommand(opts);
|
|
19
19
|
});
|
|
20
|
-
program.command("uninstall").description("Uninstall the Coding Friend plugin from Claude Code").action(async () => {
|
|
21
|
-
const { uninstallCommand } = await import("./uninstall-
|
|
22
|
-
await uninstallCommand();
|
|
20
|
+
program.command("uninstall").description("Uninstall the Coding Friend plugin from Claude Code").option("--user", "Uninstall from user scope (all projects)").option("--global", "Uninstall from user scope (all projects)").option("--project", "Uninstall from project scope").option("--local", "Uninstall from local scope").action(async (opts) => {
|
|
21
|
+
const { uninstallCommand } = await import("./uninstall-A2LJR2OD.js");
|
|
22
|
+
await uninstallCommand(opts);
|
|
23
23
|
});
|
|
24
24
|
program.command("init").description("Initialize coding-friend in current project").action(async () => {
|
|
25
|
-
const { initCommand } = await import("./init-
|
|
25
|
+
const { initCommand } = await import("./init-QRUDHFME.js");
|
|
26
26
|
await initCommand();
|
|
27
27
|
});
|
|
28
28
|
program.command("config").description("Manage Coding Friend configuration").action(async () => {
|
|
29
|
-
const { configCommand } = await import("./config-
|
|
29
|
+
const { configCommand } = await import("./config-GYJGDXGV.js");
|
|
30
30
|
await configCommand();
|
|
31
31
|
});
|
|
32
32
|
program.command("host").description("Build and serve learning docs as a static website").argument("[path]", "path to docs folder").option("-p, --port <port>", "port number", "3333").action(async (path, opts) => {
|
|
33
|
-
const { hostCommand } = await import("./host-
|
|
33
|
+
const { hostCommand } = await import("./host-SWIWQRRL.js");
|
|
34
34
|
await hostCommand(path, opts);
|
|
35
35
|
});
|
|
36
36
|
program.command("mcp").description("Setup MCP server for learning docs").argument("[path]", "path to docs folder").action(async (path) => {
|
|
37
|
-
const { mcpCommand } = await import("./mcp-
|
|
37
|
+
const { mcpCommand } = await import("./mcp-H3K67N2P.js");
|
|
38
38
|
await mcpCommand(path);
|
|
39
39
|
});
|
|
40
40
|
program.command("permission").description("Manage Claude Code permission rules for Coding Friend").option("--all", "Apply all recommended permissions without prompts").action(async (opts) => {
|
|
41
|
-
const { permissionCommand } = await import("./permission-
|
|
41
|
+
const { permissionCommand } = await import("./permission-DIJMCOZX.js");
|
|
42
42
|
await permissionCommand(opts);
|
|
43
43
|
});
|
|
44
44
|
program.command("statusline").description("Setup coding-friend statusline in Claude Code").action(async () => {
|
|
45
|
-
const { statuslineCommand } = await import("./statusline-
|
|
45
|
+
const { statuslineCommand } = await import("./statusline-H2WUKOJ6.js");
|
|
46
46
|
await statuslineCommand();
|
|
47
47
|
});
|
|
48
|
-
program.command("update").description("Update coding-friend plugin, CLI, and statusline").option("--cli", "Update only the CLI (npm package)").option("--plugin", "Update only the Claude Code plugin").option("--statusline", "Update only the statusline").action(async (opts) => {
|
|
49
|
-
const { updateCommand } = await import("./update-
|
|
48
|
+
program.command("update").description("Update coding-friend plugin, CLI, and statusline").option("--cli", "Update only the CLI (npm package)").option("--plugin", "Update only the Claude Code plugin").option("--statusline", "Update only the statusline").option("--user", "Update plugin at user scope (all projects)").option("--global", "Update plugin at user scope (all projects)").option("--project", "Update plugin at project scope").option("--local", "Update plugin at local scope").action(async (opts) => {
|
|
49
|
+
const { updateCommand } = await import("./update-RJSWHCCR.js");
|
|
50
50
|
await updateCommand(opts);
|
|
51
51
|
});
|
|
52
52
|
var session = program.command("session").description("Save and load Claude Code sessions across machines");
|
|
@@ -61,11 +61,11 @@ session.command("save").description("Save current Claude Code session to sync fo
|
|
|
61
61
|
"-s, --session-id <id>",
|
|
62
62
|
"session UUID to save (default: auto-detect newest)"
|
|
63
63
|
).option("-l, --label <label>", "label for this session").action(async (opts) => {
|
|
64
|
-
const { sessionSaveCommand } = await import("./session-
|
|
64
|
+
const { sessionSaveCommand } = await import("./session-2APBPDZF.js");
|
|
65
65
|
await sessionSaveCommand(opts);
|
|
66
66
|
});
|
|
67
67
|
session.command("load").description("Load a saved session from sync folder").action(async () => {
|
|
68
|
-
const { sessionLoadCommand } = await import("./session-
|
|
68
|
+
const { sessionLoadCommand } = await import("./session-2APBPDZF.js");
|
|
69
69
|
await sessionLoadCommand();
|
|
70
70
|
});
|
|
71
71
|
var dev = program.command("dev").description("Development mode commands");
|
|
@@ -81,35 +81,35 @@ Dev subcommands:
|
|
|
81
81
|
dev update [path] Update local dev plugin to latest version`
|
|
82
82
|
);
|
|
83
83
|
dev.command("on").description("Switch to local plugin source").argument("[path]", "path to local coding-friend repo (default: cwd)").action(async (path) => {
|
|
84
|
-
const { devOnCommand } = await import("./dev-
|
|
84
|
+
const { devOnCommand } = await import("./dev-GFFXRZJC.js");
|
|
85
85
|
await devOnCommand(path);
|
|
86
86
|
});
|
|
87
87
|
dev.command("off").description("Switch back to remote marketplace").action(async () => {
|
|
88
|
-
const { devOffCommand } = await import("./dev-
|
|
88
|
+
const { devOffCommand } = await import("./dev-GFFXRZJC.js");
|
|
89
89
|
await devOffCommand();
|
|
90
90
|
});
|
|
91
91
|
dev.command("status").description("Show current dev mode").action(async () => {
|
|
92
|
-
const { devStatusCommand } = await import("./dev-
|
|
92
|
+
const { devStatusCommand } = await import("./dev-GFFXRZJC.js");
|
|
93
93
|
await devStatusCommand();
|
|
94
94
|
});
|
|
95
95
|
dev.command("sync").description(
|
|
96
96
|
"Copy local source files to plugin cache (no version bump needed)"
|
|
97
97
|
).action(async () => {
|
|
98
|
-
const { devSyncCommand } = await import("./dev-
|
|
98
|
+
const { devSyncCommand } = await import("./dev-GFFXRZJC.js");
|
|
99
99
|
await devSyncCommand();
|
|
100
100
|
});
|
|
101
101
|
dev.command("restart").description("Reinstall local dev plugin (off + on)").argument(
|
|
102
102
|
"[path]",
|
|
103
103
|
"path to local coding-friend repo (default: saved path or cwd)"
|
|
104
104
|
).action(async (path) => {
|
|
105
|
-
const { devRestartCommand } = await import("./dev-
|
|
105
|
+
const { devRestartCommand } = await import("./dev-GFFXRZJC.js");
|
|
106
106
|
await devRestartCommand(path);
|
|
107
107
|
});
|
|
108
108
|
dev.command("update").description("Update local dev plugin to latest version (off + on)").argument(
|
|
109
109
|
"[path]",
|
|
110
110
|
"path to local coding-friend repo (default: saved path or cwd)"
|
|
111
111
|
).action(async (path) => {
|
|
112
|
-
const { devUpdateCommand } = await import("./dev-
|
|
112
|
+
const { devUpdateCommand } = await import("./dev-GFFXRZJC.js");
|
|
113
113
|
await devUpdateCommand(path);
|
|
114
114
|
});
|
|
115
115
|
program.parse();
|
|
@@ -3,7 +3,14 @@ import {
|
|
|
3
3
|
buildLearnDirRules,
|
|
4
4
|
getExistingRules,
|
|
5
5
|
getMissingRules
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-EL6BAAKL.js";
|
|
7
|
+
import {
|
|
8
|
+
findStatuslineHookPath,
|
|
9
|
+
isStatuslineConfigured,
|
|
10
|
+
saveStatuslineConfig,
|
|
11
|
+
selectStatuslineComponents,
|
|
12
|
+
writeStatuslineSettings
|
|
13
|
+
} from "./chunk-HYLS67T7.js";
|
|
7
14
|
import {
|
|
8
15
|
BACK,
|
|
9
16
|
applyDocsDirChange,
|
|
@@ -13,18 +20,11 @@ import {
|
|
|
13
20
|
getScopeLabel,
|
|
14
21
|
injectBackChoice,
|
|
15
22
|
showConfigHint
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
findStatuslineHookPath,
|
|
19
|
-
isStatuslineConfigured,
|
|
20
|
-
saveStatuslineConfig,
|
|
21
|
-
selectStatuslineComponents,
|
|
22
|
-
writeStatuslineSettings
|
|
23
|
-
} from "./chunk-YAOUAJZP.js";
|
|
23
|
+
} from "./chunk-GJLNN6X5.js";
|
|
24
24
|
import {
|
|
25
25
|
ensureShellCompletion,
|
|
26
26
|
hasShellCompletion
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-4JL3SR5V.js";
|
|
28
28
|
import {
|
|
29
29
|
DEFAULT_CONFIG
|
|
30
30
|
} from "./chunk-PGLUEN7D.js";
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
mergeJson,
|
|
39
39
|
readJson,
|
|
40
40
|
resolvePath
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
42
42
|
import {
|
|
43
43
|
log
|
|
44
44
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getLatestVersion,
|
|
3
3
|
semverCompare
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RN5UYDIT.js";
|
|
5
5
|
import {
|
|
6
6
|
isMarketplaceRegistered
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-E2XX5MIM.js";
|
|
8
8
|
import {
|
|
9
9
|
getInstalledVersion
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import
|
|
10
|
+
} from "./chunk-HYLS67T7.js";
|
|
11
|
+
import {
|
|
12
|
+
resolveScope
|
|
13
|
+
} from "./chunk-GJLNN6X5.js";
|
|
14
|
+
import {
|
|
15
|
+
ensureShellCompletion
|
|
16
|
+
} from "./chunk-4JL3SR5V.js";
|
|
12
17
|
import "./chunk-PGLUEN7D.js";
|
|
13
18
|
import {
|
|
14
19
|
commandExists,
|
|
15
20
|
run
|
|
16
21
|
} from "./chunk-UFGNO6CW.js";
|
|
17
|
-
import
|
|
22
|
+
import {
|
|
23
|
+
devStatePath
|
|
24
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
18
25
|
import {
|
|
19
26
|
log
|
|
20
27
|
} from "./chunk-W5CD7WTX.js";
|
|
21
28
|
|
|
22
29
|
// src/commands/install.ts
|
|
30
|
+
import { existsSync } from "fs";
|
|
23
31
|
import chalk from "chalk";
|
|
24
|
-
async function installCommand() {
|
|
32
|
+
async function installCommand(opts = {}) {
|
|
25
33
|
console.log("=== \u{1F33F} Coding Friend Install \u{1F33F} ===");
|
|
26
34
|
console.log();
|
|
27
35
|
if (!commandExists("claude")) {
|
|
@@ -30,6 +38,14 @@ async function installCommand() {
|
|
|
30
38
|
);
|
|
31
39
|
process.exit(1);
|
|
32
40
|
}
|
|
41
|
+
if (existsSync(devStatePath())) {
|
|
42
|
+
log.warn("Dev mode is currently active.");
|
|
43
|
+
log.dim(
|
|
44
|
+
`Run ${chalk.bold("cf dev off")} first, then install. Or use ${chalk.bold("cf dev sync")} to update the dev plugin.`
|
|
45
|
+
);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const scope = await resolveScope(opts);
|
|
33
49
|
if (isMarketplaceRegistered()) {
|
|
34
50
|
log.success("Marketplace already registered.");
|
|
35
51
|
} else {
|
|
@@ -49,12 +65,14 @@ async function installCommand() {
|
|
|
49
65
|
log.success("Marketplace added.");
|
|
50
66
|
}
|
|
51
67
|
const installedVersion = getInstalledVersion();
|
|
52
|
-
if (!installedVersion) {
|
|
53
|
-
log.step(
|
|
68
|
+
if (!installedVersion || scope !== "user") {
|
|
69
|
+
log.step(`Installing plugin (${chalk.cyan(scope)} scope)...`);
|
|
54
70
|
const result = run("claude", [
|
|
55
71
|
"plugin",
|
|
56
72
|
"install",
|
|
57
|
-
"coding-friend@coding-friend-marketplace"
|
|
73
|
+
"coding-friend@coding-friend-marketplace",
|
|
74
|
+
"--scope",
|
|
75
|
+
scope
|
|
58
76
|
]);
|
|
59
77
|
if (result === null) {
|
|
60
78
|
log.error(
|
|
@@ -81,12 +99,15 @@ async function installCommand() {
|
|
|
81
99
|
log.dim("Could not check for updates (no network or GitHub rate limit).");
|
|
82
100
|
}
|
|
83
101
|
}
|
|
102
|
+
ensureShellCompletion({ silent: false });
|
|
84
103
|
console.log();
|
|
85
104
|
log.info("Next steps:");
|
|
86
|
-
log
|
|
105
|
+
console.log(
|
|
87
106
|
` ${chalk.cyan("cf init")} Initialize workspace (docs folders, config)`
|
|
88
107
|
);
|
|
89
|
-
log
|
|
108
|
+
console.log(
|
|
109
|
+
` ${chalk.cyan("cf statusline")} Setup statusline in Claude Code to show more real-time info`
|
|
110
|
+
);
|
|
90
111
|
console.log();
|
|
91
112
|
log.dim("Restart Claude Code (or start a new session) to use the plugin.");
|
|
92
113
|
}
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
} from "./chunk-RZRT7NGT.js";
|
|
4
4
|
import {
|
|
5
5
|
resolveDocsDir
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-XIZJ64JK.js";
|
|
7
7
|
import "./chunk-PGLUEN7D.js";
|
|
8
8
|
import {
|
|
9
9
|
run
|
|
10
10
|
} from "./chunk-UFGNO6CW.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-ZS7BLEYT.js";
|
|
12
12
|
import {
|
|
13
13
|
log
|
|
14
14
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
applyPermissions,
|
|
4
4
|
getExistingRules,
|
|
5
5
|
groupByCategory
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-EL6BAAKL.js";
|
|
7
7
|
import {
|
|
8
8
|
claudeLocalSettingsPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
10
10
|
import {
|
|
11
11
|
log
|
|
12
12
|
} from "./chunk-W5CD7WTX.js";
|
package/dist/postinstall.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XIZJ64JK.js";
|
|
4
4
|
import "./chunk-PGLUEN7D.js";
|
|
5
5
|
import {
|
|
6
6
|
claudeSessionDir,
|
|
7
7
|
encodeProjectPath,
|
|
8
8
|
readJson,
|
|
9
|
+
resolvePath,
|
|
9
10
|
writeJson
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
11
12
|
import {
|
|
12
13
|
log
|
|
13
14
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -212,6 +213,7 @@ Remapped to: ${remapped}`
|
|
|
212
213
|
});
|
|
213
214
|
localProjectPath = confirmed.trim() || remapped;
|
|
214
215
|
}
|
|
216
|
+
localProjectPath = resolvePath(localProjectPath);
|
|
215
217
|
loadSession(chosen, localProjectPath, docsDir);
|
|
216
218
|
log.success(`Session "${chosen.label}" loaded.`);
|
|
217
219
|
log.info(`To resume, run:`);
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
saveStatuslineConfig,
|
|
5
5
|
selectStatuslineComponents,
|
|
6
6
|
writeStatuslineSettings
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HYLS67T7.js";
|
|
8
8
|
import {
|
|
9
9
|
ALL_COMPONENT_IDS
|
|
10
10
|
} from "./chunk-PGLUEN7D.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-ZS7BLEYT.js";
|
|
12
12
|
import {
|
|
13
13
|
log
|
|
14
14
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isMarketplaceRegistered,
|
|
3
3
|
isPluginInstalled
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-E2XX5MIM.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveScope
|
|
7
|
+
} from "./chunk-GJLNN6X5.js";
|
|
5
8
|
import {
|
|
6
9
|
hasShellCompletion,
|
|
7
10
|
removeShellCompletion
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-4JL3SR5V.js";
|
|
9
12
|
import {
|
|
10
13
|
commandExists,
|
|
11
14
|
run
|
|
@@ -18,7 +21,7 @@ import {
|
|
|
18
21
|
marketplaceClonePath,
|
|
19
22
|
readJson,
|
|
20
23
|
writeJson
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-ZS7BLEYT.js";
|
|
22
25
|
import {
|
|
23
26
|
log
|
|
24
27
|
} from "./chunk-W5CD7WTX.js";
|
|
@@ -76,7 +79,43 @@ function displayDetection(d) {
|
|
|
76
79
|
function nothingToRemove(d) {
|
|
77
80
|
return !d.pluginInstalled && !d.marketplaceRegistered && !d.cacheExists && !d.cloneExists && !d.statuslineConfigured && !d.shellCompletionExists && !d.globalConfigExists;
|
|
78
81
|
}
|
|
79
|
-
async function
|
|
82
|
+
async function uninstallScoped(scope) {
|
|
83
|
+
const proceed = await confirm({
|
|
84
|
+
message: `Uninstall Coding Friend from ${chalk.cyan(scope)} scope?`,
|
|
85
|
+
default: false
|
|
86
|
+
});
|
|
87
|
+
if (!proceed) {
|
|
88
|
+
log.info("Uninstall cancelled.");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
log.step(`Uninstalling plugin from ${scope} scope...`);
|
|
92
|
+
const result = run("claude", [
|
|
93
|
+
"plugin",
|
|
94
|
+
"uninstall",
|
|
95
|
+
PLUGIN_ID,
|
|
96
|
+
"--scope",
|
|
97
|
+
scope
|
|
98
|
+
]);
|
|
99
|
+
if (result === null) {
|
|
100
|
+
const fallback = run("claude", [
|
|
101
|
+
"plugin",
|
|
102
|
+
"uninstall",
|
|
103
|
+
PLUGIN_NAME,
|
|
104
|
+
"--scope",
|
|
105
|
+
scope
|
|
106
|
+
]);
|
|
107
|
+
if (fallback === null) {
|
|
108
|
+
log.warn(
|
|
109
|
+
"Could not uninstall plugin (may not be installed at this scope)."
|
|
110
|
+
);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
log.success(`Plugin uninstalled from ${scope} scope.`);
|
|
115
|
+
console.log();
|
|
116
|
+
log.dim("Restart Claude Code to complete the uninstall.");
|
|
117
|
+
}
|
|
118
|
+
async function uninstallCommand(opts = {}) {
|
|
80
119
|
console.log(`
|
|
81
120
|
=== \u{1F44B} ${chalk.red("Coding Friend Uninstall")} \u{1F44B} ===`);
|
|
82
121
|
if (!commandExists("claude")) {
|
|
@@ -86,12 +125,17 @@ async function uninstallCommand() {
|
|
|
86
125
|
);
|
|
87
126
|
return;
|
|
88
127
|
}
|
|
89
|
-
|
|
90
|
-
if (detection.devModeActive) {
|
|
128
|
+
if (existsSync(devStatePath())) {
|
|
91
129
|
log.warn("Dev mode is currently active.");
|
|
92
130
|
log.dim(`Run ${chalk.bold("cf dev off")} first, then try again.`);
|
|
93
131
|
return;
|
|
94
132
|
}
|
|
133
|
+
const scope = await resolveScope(opts);
|
|
134
|
+
if (scope === "project" || scope === "local") {
|
|
135
|
+
await uninstallScoped(scope);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const detection = detect();
|
|
95
139
|
if (nothingToRemove(detection)) {
|
|
96
140
|
log.info("Nothing to uninstall \u2014 Coding Friend is not installed.");
|
|
97
141
|
return;
|
|
@@ -2,12 +2,13 @@ import {
|
|
|
2
2
|
getLatestVersion,
|
|
3
3
|
semverCompare,
|
|
4
4
|
updateCommand
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-RN5UYDIT.js";
|
|
6
|
+
import "./chunk-HYLS67T7.js";
|
|
7
|
+
import "./chunk-GJLNN6X5.js";
|
|
8
|
+
import "./chunk-4JL3SR5V.js";
|
|
8
9
|
import "./chunk-PGLUEN7D.js";
|
|
9
10
|
import "./chunk-UFGNO6CW.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-ZS7BLEYT.js";
|
|
11
12
|
import "./chunk-W5CD7WTX.js";
|
|
12
13
|
export {
|
|
13
14
|
getLatestVersion,
|