coding-friend-cli 1.35.8 → 1.36.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 +5 -3
- package/dist/{chunk-RLUNNJWJ.js → chunk-667NMPN4.js} +47 -4
- package/dist/{chunk-HA7E7QZ4.js → chunk-7QFJODWB.js} +14 -9
- package/dist/{chunk-UCYGDDFS.js → chunk-7SMP5CZ4.js} +6 -6
- package/dist/{chunk-5Z5TZUHZ.js → chunk-DUKBBMVM.js} +6 -18
- package/dist/{chunk-TAPL6NF3.js → chunk-EFRPDFO7.js} +4 -4
- package/dist/{chunk-ASNR6LFD.js → chunk-GHR3TNL6.js} +8 -8
- package/dist/{chunk-R6HDMRYL.js → chunk-GZT3YPAP.js} +5 -5
- package/dist/{chunk-UIPLDRGI.js → chunk-KIKN5HEH.js} +6 -6
- package/dist/{chunk-O27FVQFU.js → chunk-O5ZKLFSL.js} +6 -4
- package/dist/{chunk-UXIWEBI2.js → chunk-PQUACN4U.js} +1 -1
- package/dist/{chunk-WSUYLIYX.js → chunk-TEC25H6C.js} +3 -3
- package/dist/{chunk-TWKNGPBO.js → chunk-X2H7JJMR.js} +15 -10
- package/dist/{clean-PAYOM4FV.js → clean-2IRHH4SU.js} +24 -25
- package/dist/{config-NPKT6NN3.js → config-36YY3XLM.js} +17 -17
- package/dist/{dev-MD5TNAKI.js → dev-JSYPSXEZ.js} +8 -8
- package/dist/{disable-5UK4QINT.js → disable-35RSJICU.js} +3 -3
- package/dist/{enable-UQZNZRPI.js → enable-RXWDQRIU.js} +3 -3
- package/dist/{guide-LQ2BHU5Y.js → guide-ECSMH2AT.js} +4 -4
- package/dist/{host-DKGDDAGO.js → host-BYJEZN6T.js} +10 -5
- package/dist/index.js +52 -36
- package/dist/{init-ZIUTSR4U.js → init-QXCMAPXT.js} +19 -19
- package/dist/{install-VFD6C3LZ.js → install-NALHBTGG.js} +8 -8
- package/dist/learn-PNG2TI2E.js +111 -0
- package/dist/{mcp-T3UG4PS3.js → mcp-6GRHKIQW.js} +9 -9
- package/dist/{mcp-serve-learn-OKVC5WV3.js → mcp-serve-learn-36ZQQQTF.js} +3 -3
- package/dist/{memory-R57VRQZL.js → memory-A7OUTQ54.js} +6 -6
- package/dist/{permission-KLT2TLZY.js → permission-PB3OMKRB.js} +9 -9
- package/dist/{permissions-LYADLYYK.js → permissions-J46VP6US.js} +2 -1
- package/dist/postinstall.js +1 -1
- package/dist/{session-MVH6IYHM.js → session-YJJRGQPX.js} +6 -6
- package/dist/{status-YWABL222.js → status-SG5LCXER.js} +16 -16
- package/dist/{statusline-EYTWM5X6.js → statusline-3Z4DE24F.js} +2 -2
- package/dist/{uninstall-MLSKOCOZ.js → uninstall-JLSEHXS5.js} +11 -11
- package/dist/{update-G5YXZRMQ.js → update-MO5BT3C5.js} +5 -5
- package/dist/{update-check-BPCQ25AR.js → update-check-I2RSVGFO.js} +3 -3
- package/lib/learn-host/README.md +8 -9
- package/lib/learn-host/src/components/Breadcrumbs.tsx +30 -19
- package/package.json +1 -1
- package/lib/learn-host/tsconfig.tsbuildinfo +0 -1
package/README.md
CHANGED
|
@@ -78,10 +78,12 @@ cf init # Initialize workspace (interactive)
|
|
|
78
78
|
# 💡 You can run this anywhere, anytime.
|
|
79
79
|
cf config # Manage Coding Friend configuration (interactive menu)
|
|
80
80
|
# 💡 Edit docsDir, language, learn settings, and more.
|
|
81
|
-
cf host [path]
|
|
82
|
-
# [path] is optional, default is
|
|
81
|
+
cf learn host [path] # Build and serve learning docs at localhost:3333
|
|
82
|
+
# [path] is optional, default is `~/.coding-friend/learn`
|
|
83
|
+
cf learn push [path] # Commit and push learning docs (only if learn dir is the git root)
|
|
84
|
+
# [path] is optional, default is `~/.coding-friend/learn`
|
|
83
85
|
cf mcp [path] # Setup MCP server for LLM integration
|
|
84
|
-
# [path] is optional, default is
|
|
86
|
+
# [path] is optional, default is `~/.coding-friend/learn`
|
|
85
87
|
# This prints a JSON config snippet to add to your client's MCP
|
|
86
88
|
cf permission # Manage Claude Code permission rules (interactive)
|
|
87
89
|
cf permission --all # Apply all recommended permissions without prompts
|
|
@@ -21,7 +21,7 @@ ${MARKER_START}
|
|
|
21
21
|
_cf_completions() {
|
|
22
22
|
local cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
23
23
|
local prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
24
|
-
local commands="install uninstall disable enable init config
|
|
24
|
+
local commands="install uninstall disable enable init config learn mcp memory permission statusline update status clean dev session guide"
|
|
25
25
|
local scope_flags="--user --global --project --local"
|
|
26
26
|
local update_flags="--cli --plugin --statusline --user --global --project --local"
|
|
27
27
|
|
|
@@ -43,6 +43,18 @@ _cf_completions() {
|
|
|
43
43
|
return
|
|
44
44
|
fi
|
|
45
45
|
|
|
46
|
+
# Subcommands for 'guide'
|
|
47
|
+
if [[ "\${COMP_WORDS[1]}" == "guide" && \${COMP_CWORD} -eq 2 ]]; then
|
|
48
|
+
COMPREPLY=($(compgen -W "create list" -- "$cur"))
|
|
49
|
+
return
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# Subcommands for 'learn'
|
|
53
|
+
if [[ "\${COMP_WORDS[1]}" == "learn" && \${COMP_CWORD} -eq 2 ]]; then
|
|
54
|
+
COMPREPLY=($(compgen -W "host push" -- "$cur"))
|
|
55
|
+
return
|
|
56
|
+
fi
|
|
57
|
+
|
|
46
58
|
# Path completion for 'dev on|restart|update'
|
|
47
59
|
if [[ "\${COMP_WORDS[1]}" == "dev" && ("$prev" == "on" || "$prev" == "restart" || "$prev" == "update") ]]; then
|
|
48
60
|
COMPREPLY=($(compgen -d -- "$cur"))
|
|
@@ -81,7 +93,7 @@ var ZSH_FUNCTION_BODY = `_cf() {
|
|
|
81
93
|
'enable:Re-enable the Coding Friend plugin'
|
|
82
94
|
'init:Initialize coding-friend in current project'
|
|
83
95
|
'config:Manage Coding Friend configuration'
|
|
84
|
-
'
|
|
96
|
+
'learn:Manage learning docs \u2014 host as a website or push to git'
|
|
85
97
|
'mcp:Setup MCP server for learning docs'
|
|
86
98
|
'memory:AI memory system \u2014 store and search project knowledge'
|
|
87
99
|
'permission:Manage Claude Code permission rules for Coding Friend'
|
|
@@ -91,6 +103,7 @@ var ZSH_FUNCTION_BODY = `_cf() {
|
|
|
91
103
|
'status:Show comprehensive Coding Friend status'
|
|
92
104
|
'clean:Clean files generated by Coding Friend in docs/'
|
|
93
105
|
'session:Save and load Claude Code sessions across machines'
|
|
106
|
+
'guide:Manage custom skill guides'
|
|
94
107
|
)
|
|
95
108
|
|
|
96
109
|
local -a scope_flags
|
|
@@ -159,6 +172,20 @@ var ZSH_FUNCTION_BODY = `_cf() {
|
|
|
159
172
|
'load:Load a saved session from docs/sessions/'
|
|
160
173
|
)
|
|
161
174
|
_describe 'subcommand' subcommands
|
|
175
|
+
elif (( CURRENT == 3 )) && [[ "\${words[2]}" == "guide" ]]; then
|
|
176
|
+
local -a subcommands
|
|
177
|
+
subcommands=(
|
|
178
|
+
'create:Create a custom guide for a skill'
|
|
179
|
+
'list:List existing custom guides'
|
|
180
|
+
)
|
|
181
|
+
_describe 'subcommand' subcommands
|
|
182
|
+
elif (( CURRENT == 3 )) && [[ "\${words[2]}" == "learn" ]]; then
|
|
183
|
+
local -a subcommands
|
|
184
|
+
subcommands=(
|
|
185
|
+
'host:Build and serve learning docs as a static website'
|
|
186
|
+
'push:Commit and push learning docs to origin'
|
|
187
|
+
)
|
|
188
|
+
_describe 'subcommand' subcommands
|
|
162
189
|
elif (( CURRENT == 4 )) && [[ "\${words[2]}" == "dev" && ("\${words[3]}" == "on" || "\${words[3]}" == "restart" || "\${words[3]}" == "update") ]]; then
|
|
163
190
|
_path_files -/
|
|
164
191
|
fi
|
|
@@ -181,7 +208,7 @@ complete -c cf -n "__fish_use_subcommand" -a disable -d "Disable the Coding Frie
|
|
|
181
208
|
complete -c cf -n "__fish_use_subcommand" -a enable -d "Re-enable the Coding Friend plugin"
|
|
182
209
|
complete -c cf -n "__fish_use_subcommand" -a init -d "Initialize coding-friend in current project"
|
|
183
210
|
complete -c cf -n "__fish_use_subcommand" -a config -d "Manage Coding Friend configuration"
|
|
184
|
-
complete -c cf -n "__fish_use_subcommand" -a
|
|
211
|
+
complete -c cf -n "__fish_use_subcommand" -a learn -d "Manage learning docs \u2014 host as a website or push to git"
|
|
185
212
|
complete -c cf -n "__fish_use_subcommand" -a mcp -d "Setup MCP server for learning docs"
|
|
186
213
|
complete -c cf -n "__fish_use_subcommand" -a memory -d "AI memory system \u2014 store and search project knowledge"
|
|
187
214
|
complete -c cf -n "__fish_use_subcommand" -a permission -d "Manage Claude Code permission rules"
|
|
@@ -189,7 +216,9 @@ complete -c cf -n "__fish_use_subcommand" -a statusline -d "Setup coding-friend
|
|
|
189
216
|
complete -c cf -n "__fish_use_subcommand" -a update -d "Update coding-friend plugin and refresh statusline"
|
|
190
217
|
complete -c cf -n "__fish_use_subcommand" -a dev -d "Switch between local and remote plugin for development"
|
|
191
218
|
complete -c cf -n "__fish_use_subcommand" -a status -d "Show comprehensive Coding Friend status"
|
|
219
|
+
complete -c cf -n "__fish_use_subcommand" -a clean -d "Clean files generated by Coding Friend in docs/"
|
|
192
220
|
complete -c cf -n "__fish_use_subcommand" -a session -d "Save and load Claude Code sessions across machines"
|
|
221
|
+
complete -c cf -n "__fish_use_subcommand" -a guide -d "Manage custom skill guides"
|
|
193
222
|
# Scope flags for install/uninstall/disable/enable
|
|
194
223
|
complete -c cf -n "__fish_seen_subcommand_from install uninstall disable enable" -l user -d "User scope (all projects)"
|
|
195
224
|
complete -c cf -n "__fish_seen_subcommand_from install uninstall disable enable" -l global -d "User scope (all projects)"
|
|
@@ -228,16 +257,24 @@ complete -c cf -n "__fish_seen_subcommand_from memory" -a mcp -d "Show MCP serve
|
|
|
228
257
|
# Session subcommands
|
|
229
258
|
complete -c cf -n "__fish_seen_subcommand_from session" -a save -d "Save current session to docs/sessions/"
|
|
230
259
|
complete -c cf -n "__fish_seen_subcommand_from session" -a load -d "Load a saved session from docs/sessions/"
|
|
260
|
+
# Guide subcommands
|
|
261
|
+
complete -c cf -n "__fish_seen_subcommand_from guide" -a create -d "Create a custom guide for a skill"
|
|
262
|
+
complete -c cf -n "__fish_seen_subcommand_from guide" -a list -d "List existing custom guides"
|
|
263
|
+
# Learn subcommands
|
|
264
|
+
complete -c cf -n "__fish_seen_subcommand_from learn" -a host -d "Build and serve learning docs as a static website"
|
|
265
|
+
complete -c cf -n "__fish_seen_subcommand_from learn" -a push -d "Commit and push learning docs to origin"
|
|
231
266
|
`;
|
|
232
267
|
var POWERSHELL_BLOCK = `
|
|
233
268
|
|
|
234
269
|
${MARKER_START}
|
|
235
270
|
Register-ArgumentCompleter -Native -CommandName cf -ScriptBlock {
|
|
236
271
|
param($wordToComplete, $commandAst, $cursorPosition)
|
|
237
|
-
$commands = @('install','uninstall','disable','enable','init','config','
|
|
272
|
+
$commands = @('install','uninstall','disable','enable','init','config','learn','mcp','memory','permission','statusline','update','status','clean','dev','session','guide')
|
|
238
273
|
$devSubcommands = @('on','off','status','restart','sync','update')
|
|
239
274
|
$memorySubcommands = @('status','search','list','rm','init','config','start-daemon','stop-daemon','rebuild','mcp')
|
|
240
275
|
$sessionSubcommands = @('save','load')
|
|
276
|
+
$guideSubcommands = @('create','list')
|
|
277
|
+
$learnSubcommands = @('host','push')
|
|
241
278
|
$scopeFlags = @('--user','--global','--project','--local')
|
|
242
279
|
$updateFlags = @('--cli','--plugin','--statusline','--user','--global','--project','--local')
|
|
243
280
|
$words = $commandAst.CommandElements
|
|
@@ -250,6 +287,12 @@ Register-ArgumentCompleter -Native -CommandName cf -ScriptBlock {
|
|
|
250
287
|
} elseif ($words.Count -ge 2 -and $words[1].ToString() -eq 'session') {
|
|
251
288
|
$sessionSubcommands | Where-Object { $_ -like "$wordToComplete*" } |
|
|
252
289
|
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
290
|
+
} elseif ($words.Count -ge 2 -and $words[1].ToString() -eq 'guide') {
|
|
291
|
+
$guideSubcommands | Where-Object { $_ -like "$wordToComplete*" } |
|
|
292
|
+
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
293
|
+
} elseif ($words.Count -ge 2 -and $words[1].ToString() -eq 'learn') {
|
|
294
|
+
$learnSubcommands | Where-Object { $_ -like "$wordToComplete*" } |
|
|
295
|
+
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
253
296
|
} elseif ($words.Count -ge 2 -and ($words[1].ToString() -eq 'install' -or $words[1].ToString() -eq 'uninstall' -or $words[1].ToString() -eq 'disable' -or $words[1].ToString() -eq 'enable')) {
|
|
254
297
|
$scopeFlags | Where-Object { $_ -like "$wordToComplete*" } |
|
|
255
298
|
ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveMemoryDir
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DUKBBMVM.js";
|
|
4
4
|
import {
|
|
5
5
|
getLibPath
|
|
6
6
|
} from "./chunk-RZRT7NGT.js";
|
|
@@ -9,11 +9,7 @@ import {
|
|
|
9
9
|
askScope,
|
|
10
10
|
formatScopeLabel,
|
|
11
11
|
injectBackChoice
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import {
|
|
14
|
-
globalConfigPath,
|
|
15
|
-
localConfigPath
|
|
16
|
-
} from "./chunk-TWKNGPBO.js";
|
|
12
|
+
} from "./chunk-EFRPDFO7.js";
|
|
17
13
|
import {
|
|
18
14
|
log
|
|
19
15
|
} from "./chunk-NREZK463.js";
|
|
@@ -22,11 +18,16 @@ import {
|
|
|
22
18
|
readJson,
|
|
23
19
|
writeJson
|
|
24
20
|
} from "./chunk-5UVDWG5L.js";
|
|
21
|
+
import {
|
|
22
|
+
claudeConfigDir,
|
|
23
|
+
globalConfigPath,
|
|
24
|
+
localConfigPath
|
|
25
|
+
} from "./chunk-X2H7JJMR.js";
|
|
25
26
|
|
|
26
27
|
// src/lib/memory-prompts.ts
|
|
27
|
-
import { homedir } from "os";
|
|
28
28
|
import { confirm, input, select } from "@inquirer/prompts";
|
|
29
29
|
import chalk from "chalk";
|
|
30
|
+
import { homedir } from "os";
|
|
30
31
|
import { join } from "path";
|
|
31
32
|
function getMemoryFieldScope(field, globalCfg, localCfg) {
|
|
32
33
|
const localSection = localCfg?.memory;
|
|
@@ -238,7 +239,7 @@ function getMemoryMcpStatus() {
|
|
|
238
239
|
if (localServers != null && "coding-friend-memory" in localServers) {
|
|
239
240
|
return { configured: true, scope: "local" };
|
|
240
241
|
}
|
|
241
|
-
const globalMcpPath = join(
|
|
242
|
+
const globalMcpPath = join(claudeConfigDir(), ".mcp.json");
|
|
242
243
|
const globalMcp = readJson(globalMcpPath);
|
|
243
244
|
const globalServers = globalMcp?.mcpServers;
|
|
244
245
|
if (globalServers != null && "coding-friend-memory" in globalServers) {
|
|
@@ -249,7 +250,11 @@ function getMemoryMcpStatus() {
|
|
|
249
250
|
async function editMemoryMcp() {
|
|
250
251
|
const status = getMemoryMcpStatus();
|
|
251
252
|
if (status.configured) {
|
|
252
|
-
const
|
|
253
|
+
const globalMcpDisplay = join(claudeConfigDir(), ".mcp.json").replace(
|
|
254
|
+
homedir(),
|
|
255
|
+
"~"
|
|
256
|
+
);
|
|
257
|
+
const label = status.scope === "local" ? chalk.green("configured") + chalk.dim(" (local .mcp.json)") : chalk.green("configured") + chalk.dim(` (global ${globalMcpDisplay})`) + " " + chalk.yellow("\u26A0 only works for one project");
|
|
253
258
|
log.info(`MCP: ${label}`);
|
|
254
259
|
const reconfigure = await confirm({
|
|
255
260
|
message: "Reconfigure Memory MCP in local .mcp.json?",
|
|
@@ -2,17 +2,17 @@ import {
|
|
|
2
2
|
ALL_COMPONENT_IDS,
|
|
3
3
|
STATUSLINE_COMPONENTS
|
|
4
4
|
} from "./chunk-57EGAXYI.js";
|
|
5
|
-
import {
|
|
6
|
-
claudeSettingsPath,
|
|
7
|
-
globalConfigPath,
|
|
8
|
-
installedPluginsPath,
|
|
9
|
-
pluginCachePath
|
|
10
|
-
} from "./chunk-TWKNGPBO.js";
|
|
11
5
|
import {
|
|
12
6
|
mergeJson,
|
|
13
7
|
readJson,
|
|
14
8
|
writeJson
|
|
15
9
|
} from "./chunk-5UVDWG5L.js";
|
|
10
|
+
import {
|
|
11
|
+
claudeSettingsPath,
|
|
12
|
+
globalConfigPath,
|
|
13
|
+
installedPluginsPath,
|
|
14
|
+
pluginCachePath
|
|
15
|
+
} from "./chunk-X2H7JJMR.js";
|
|
16
16
|
|
|
17
17
|
// src/lib/statusline.ts
|
|
18
18
|
import { existsSync, readdirSync } from "fs";
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_CONFIG
|
|
3
3
|
} from "./chunk-57EGAXYI.js";
|
|
4
|
-
import {
|
|
5
|
-
globalConfigPath,
|
|
6
|
-
localConfigPath,
|
|
7
|
-
resolvePath
|
|
8
|
-
} from "./chunk-TWKNGPBO.js";
|
|
9
4
|
import {
|
|
10
5
|
log
|
|
11
6
|
} from "./chunk-NREZK463.js";
|
|
12
7
|
import {
|
|
13
8
|
readJson
|
|
14
9
|
} from "./chunk-5UVDWG5L.js";
|
|
10
|
+
import {
|
|
11
|
+
globalConfigPath,
|
|
12
|
+
localConfigPath,
|
|
13
|
+
resolvePath
|
|
14
|
+
} from "./chunk-X2H7JJMR.js";
|
|
15
15
|
|
|
16
16
|
// src/lib/config.ts
|
|
17
17
|
import { z } from "zod";
|
|
@@ -189,21 +189,10 @@ function loadConfig() {
|
|
|
189
189
|
const merged = deepMerge(base, local ?? {});
|
|
190
190
|
return validateConfig(merged);
|
|
191
191
|
}
|
|
192
|
-
function
|
|
192
|
+
function resolveLearnDir(globalCfg, explicitPath) {
|
|
193
193
|
if (explicitPath) {
|
|
194
194
|
return resolvePath(explicitPath);
|
|
195
195
|
}
|
|
196
|
-
const local = readJson(localConfigPath());
|
|
197
|
-
if (local?.learn?.outputDir) {
|
|
198
|
-
return resolvePath(local.learn.outputDir);
|
|
199
|
-
}
|
|
200
|
-
const global = readJson(globalConfigPath());
|
|
201
|
-
if (global?.learn?.outputDir) {
|
|
202
|
-
return resolvePath(global.learn.outputDir);
|
|
203
|
-
}
|
|
204
|
-
return resolvePath("docs/learn");
|
|
205
|
-
}
|
|
206
|
-
function resolveLearnDir(globalCfg) {
|
|
207
196
|
if (globalCfg?.learn?.outputDir) {
|
|
208
197
|
return resolvePath(globalCfg.learn.outputDir);
|
|
209
198
|
}
|
|
@@ -223,7 +212,6 @@ function resolveMemoryDir(explicitPath) {
|
|
|
223
212
|
export {
|
|
224
213
|
sanitizeRawConfig,
|
|
225
214
|
loadConfig,
|
|
226
|
-
resolveDocsDir,
|
|
227
215
|
resolveLearnDir,
|
|
228
216
|
resolveMemoryDir
|
|
229
217
|
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
run
|
|
3
3
|
} from "./chunk-EVGXUDX4.js";
|
|
4
|
-
import {
|
|
5
|
-
globalConfigPath,
|
|
6
|
-
localConfigPath
|
|
7
|
-
} from "./chunk-TWKNGPBO.js";
|
|
8
4
|
import {
|
|
9
5
|
log
|
|
10
6
|
} from "./chunk-NREZK463.js";
|
|
11
7
|
import {
|
|
12
8
|
readJson
|
|
13
9
|
} from "./chunk-5UVDWG5L.js";
|
|
10
|
+
import {
|
|
11
|
+
globalConfigPath,
|
|
12
|
+
localConfigPath
|
|
13
|
+
} from "./chunk-X2H7JJMR.js";
|
|
14
14
|
|
|
15
15
|
// src/lib/prompt-utils.ts
|
|
16
16
|
import { select, Separator } from "@inquirer/prompts";
|
|
@@ -2,30 +2,26 @@ import {
|
|
|
2
2
|
checkMemoryMcpHealth,
|
|
3
3
|
printHealthSection,
|
|
4
4
|
warnStaleMcpJson
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PQUACN4U.js";
|
|
6
6
|
import {
|
|
7
7
|
getMemoryMcpStatus,
|
|
8
8
|
memoryConfigMenu,
|
|
9
9
|
writeMemoryMcpEntry
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-7QFJODWB.js";
|
|
11
11
|
import {
|
|
12
12
|
loadConfig,
|
|
13
13
|
resolveMemoryDir
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DUKBBMVM.js";
|
|
15
15
|
import {
|
|
16
16
|
getLibPath
|
|
17
17
|
} from "./chunk-RZRT7NGT.js";
|
|
18
18
|
import {
|
|
19
19
|
showConfigHint
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EFRPDFO7.js";
|
|
21
21
|
import {
|
|
22
22
|
run,
|
|
23
23
|
runWithStderr
|
|
24
24
|
} from "./chunk-EVGXUDX4.js";
|
|
25
|
-
import {
|
|
26
|
-
globalConfigPath,
|
|
27
|
-
localConfigPath
|
|
28
|
-
} from "./chunk-TWKNGPBO.js";
|
|
29
25
|
import {
|
|
30
26
|
log,
|
|
31
27
|
printBanner
|
|
@@ -34,6 +30,10 @@ import {
|
|
|
34
30
|
mergeJson,
|
|
35
31
|
readJson
|
|
36
32
|
} from "./chunk-5UVDWG5L.js";
|
|
33
|
+
import {
|
|
34
|
+
globalConfigPath,
|
|
35
|
+
localConfigPath
|
|
36
|
+
} from "./chunk-X2H7JJMR.js";
|
|
37
37
|
|
|
38
38
|
// src/commands/memory.ts
|
|
39
39
|
import { existsSync, readdirSync, statSync, rmSync } from "fs";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readJson,
|
|
3
|
+
writeJson
|
|
4
|
+
} from "./chunk-5UVDWG5L.js";
|
|
1
5
|
import {
|
|
2
6
|
claudeLocalSettingsPath,
|
|
3
7
|
claudeProjectSettingsPath,
|
|
4
8
|
claudeSettingsPath,
|
|
5
9
|
installedPluginsPath,
|
|
6
10
|
knownMarketplacesPath
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
readJson,
|
|
10
|
-
writeJson
|
|
11
|
-
} from "./chunk-5UVDWG5L.js";
|
|
11
|
+
} from "./chunk-X2H7JJMR.js";
|
|
12
12
|
|
|
13
13
|
// src/lib/plugin-state.ts
|
|
14
14
|
var MARKETPLACE_NAME = "coding-friend-marketplace";
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureStatusline,
|
|
3
3
|
getInstalledVersion
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7SMP5CZ4.js";
|
|
5
5
|
import {
|
|
6
6
|
ensureShellCompletion
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-667NMPN4.js";
|
|
8
8
|
import {
|
|
9
9
|
resolveScope
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-EFRPDFO7.js";
|
|
11
11
|
import {
|
|
12
12
|
commandExists,
|
|
13
13
|
run,
|
|
14
14
|
runWithStderr,
|
|
15
15
|
sleepSync
|
|
16
16
|
} from "./chunk-EVGXUDX4.js";
|
|
17
|
-
import {
|
|
18
|
-
claudeSettingsPath
|
|
19
|
-
} from "./chunk-TWKNGPBO.js";
|
|
20
17
|
import {
|
|
21
18
|
log,
|
|
22
19
|
printBanner
|
|
@@ -24,6 +21,9 @@ import {
|
|
|
24
21
|
import {
|
|
25
22
|
readJson
|
|
26
23
|
} from "./chunk-5UVDWG5L.js";
|
|
24
|
+
import {
|
|
25
|
+
claudeSettingsPath
|
|
26
|
+
} from "./chunk-X2H7JJMR.js";
|
|
27
27
|
|
|
28
28
|
// src/commands/update.ts
|
|
29
29
|
import { readFileSync } from "fs";
|
|
@@ -2,9 +2,11 @@ import {
|
|
|
2
2
|
readJson,
|
|
3
3
|
writeJson
|
|
4
4
|
} from "./chunk-5UVDWG5L.js";
|
|
5
|
+
import {
|
|
6
|
+
pluginCachePath
|
|
7
|
+
} from "./chunk-X2H7JJMR.js";
|
|
5
8
|
|
|
6
9
|
// src/lib/permissions.ts
|
|
7
|
-
import { homedir } from "os";
|
|
8
10
|
var STATIC_RULES = [
|
|
9
11
|
// Core Utilities (hooks & infrastructure)
|
|
10
12
|
{
|
|
@@ -255,9 +257,9 @@ var STATIC_RULES = [
|
|
|
255
257
|
recommended: true
|
|
256
258
|
}
|
|
257
259
|
];
|
|
258
|
-
var PLUGIN_CACHE_TILDE = "~/.claude/plugins/cache/coding-friend-marketplace/coding-friend";
|
|
259
260
|
function buildPluginScriptRules() {
|
|
260
|
-
const absBase =
|
|
261
|
+
const absBase = pluginCachePath();
|
|
262
|
+
const readBase = process.env.CLAUDE_CONFIG_DIR?.trim() ? absBase : "~/.claude/plugins/cache/coding-friend-marketplace/coding-friend";
|
|
261
263
|
return [
|
|
262
264
|
{
|
|
263
265
|
rule: `Bash(bash ${absBase}/*)`,
|
|
@@ -272,7 +274,7 @@ function buildPluginScriptRules() {
|
|
|
272
274
|
recommended: true
|
|
273
275
|
},
|
|
274
276
|
{
|
|
275
|
-
rule: `Read(${
|
|
277
|
+
rule: `Read(${readBase}/**)`,
|
|
276
278
|
description: "[read-only] Read plugin files \xB7 Used by: hooks, agents",
|
|
277
279
|
category: "Plugin Scripts",
|
|
278
280
|
recommended: true
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runWithStderr
|
|
3
3
|
} from "./chunk-EVGXUDX4.js";
|
|
4
|
-
import {
|
|
5
|
-
resolvePath
|
|
6
|
-
} from "./chunk-TWKNGPBO.js";
|
|
7
4
|
import {
|
|
8
5
|
log
|
|
9
6
|
} from "./chunk-NREZK463.js";
|
|
7
|
+
import {
|
|
8
|
+
resolvePath
|
|
9
|
+
} from "./chunk-X2H7JJMR.js";
|
|
10
10
|
|
|
11
11
|
// src/lib/learn-prompts.ts
|
|
12
12
|
var MCP_NAME = "coding-friend-learn";
|
|
@@ -12,8 +12,15 @@ function localConfigPath() {
|
|
|
12
12
|
function globalConfigPath() {
|
|
13
13
|
return join(homedir(), ".coding-friend", "config.json");
|
|
14
14
|
}
|
|
15
|
+
function claudeConfigDir() {
|
|
16
|
+
const env = process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
17
|
+
if (!env) return join(homedir(), ".claude");
|
|
18
|
+
if (env === "~") return homedir();
|
|
19
|
+
if (env.startsWith("~/")) return join(homedir(), env.slice(2));
|
|
20
|
+
return env;
|
|
21
|
+
}
|
|
15
22
|
function claudeSettingsPath() {
|
|
16
|
-
return join(
|
|
23
|
+
return join(claudeConfigDir(), "settings.json");
|
|
17
24
|
}
|
|
18
25
|
function claudeProjectSettingsPath() {
|
|
19
26
|
return resolve(process.cwd(), ".claude", "settings.json");
|
|
@@ -22,12 +29,11 @@ function claudeLocalSettingsPath() {
|
|
|
22
29
|
return resolve(process.cwd(), ".claude", "settings.local.json");
|
|
23
30
|
}
|
|
24
31
|
function installedPluginsPath() {
|
|
25
|
-
return join(
|
|
32
|
+
return join(claudeConfigDir(), "plugins", "installed_plugins.json");
|
|
26
33
|
}
|
|
27
34
|
function pluginCachePath() {
|
|
28
35
|
return join(
|
|
29
|
-
|
|
30
|
-
".claude",
|
|
36
|
+
claudeConfigDir(),
|
|
31
37
|
"plugins",
|
|
32
38
|
"cache",
|
|
33
39
|
"coding-friend-marketplace",
|
|
@@ -38,12 +44,11 @@ function devStatePath() {
|
|
|
38
44
|
return join(homedir(), ".coding-friend", "dev-state.json");
|
|
39
45
|
}
|
|
40
46
|
function knownMarketplacesPath() {
|
|
41
|
-
return join(
|
|
47
|
+
return join(claudeConfigDir(), "plugins", "known_marketplaces.json");
|
|
42
48
|
}
|
|
43
49
|
function marketplaceCachePath() {
|
|
44
50
|
return join(
|
|
45
|
-
|
|
46
|
-
".claude",
|
|
51
|
+
claudeConfigDir(),
|
|
47
52
|
"plugins",
|
|
48
53
|
"cache",
|
|
49
54
|
"coding-friend-marketplace"
|
|
@@ -51,8 +56,7 @@ function marketplaceCachePath() {
|
|
|
51
56
|
}
|
|
52
57
|
function marketplaceClonePath() {
|
|
53
58
|
return join(
|
|
54
|
-
|
|
55
|
-
".claude",
|
|
59
|
+
claudeConfigDir(),
|
|
56
60
|
"plugins",
|
|
57
61
|
"marketplaces",
|
|
58
62
|
"coding-friend-marketplace"
|
|
@@ -68,7 +72,7 @@ function encodeProjectPath(absolutePath) {
|
|
|
68
72
|
return absolutePath.replace(/[\\/:]/g, "-");
|
|
69
73
|
}
|
|
70
74
|
function claudeProjectsDir() {
|
|
71
|
-
return join(
|
|
75
|
+
return join(claudeConfigDir(), "projects");
|
|
72
76
|
}
|
|
73
77
|
function claudeSessionDir(encodedPath) {
|
|
74
78
|
return join(claudeProjectsDir(), encodedPath);
|
|
@@ -78,6 +82,7 @@ export {
|
|
|
78
82
|
resolvePath,
|
|
79
83
|
localConfigPath,
|
|
80
84
|
globalConfigPath,
|
|
85
|
+
claudeConfigDir,
|
|
81
86
|
claudeSettingsPath,
|
|
82
87
|
claudeProjectSettingsPath,
|
|
83
88
|
claudeLocalSettingsPath,
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
resolveMemoryDir
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-DUKBBMVM.js";
|
|
5
5
|
import "./chunk-57EGAXYI.js";
|
|
6
|
-
import {
|
|
7
|
-
resolvePath
|
|
8
|
-
} from "./chunk-TWKNGPBO.js";
|
|
9
6
|
import {
|
|
10
7
|
log,
|
|
11
8
|
printBanner
|
|
12
9
|
} from "./chunk-NREZK463.js";
|
|
13
10
|
import "./chunk-5UVDWG5L.js";
|
|
11
|
+
import {
|
|
12
|
+
resolvePath
|
|
13
|
+
} from "./chunk-X2H7JJMR.js";
|
|
14
14
|
|
|
15
15
|
// src/commands/clean.ts
|
|
16
16
|
import { existsSync, readdirSync, rmSync, statSync } from "fs";
|
|
17
17
|
import { join, relative } from "path";
|
|
18
|
-
import {
|
|
18
|
+
import { confirm, input, select } from "@inquirer/prompts";
|
|
19
19
|
import chalk from "chalk";
|
|
20
20
|
var DATE_PREFIX_RE = /^(\d{4}-\d{2}-\d{2})/;
|
|
21
21
|
function parseDateFromName(name) {
|
|
@@ -122,27 +122,25 @@ async function cleanCommand() {
|
|
|
122
122
|
{ key: "sessions", path: join(docsDir, "sessions") },
|
|
123
123
|
{ key: "learn", path: join(docsDir, "learn") }
|
|
124
124
|
];
|
|
125
|
-
const cleanable = candidates.map((c) => ({ ...c, fileCount: countFiles(c.path) })).filter((c) => existsSync(c.path) && c.fileCount > 0);
|
|
126
|
-
if (cleanable.length === 0) {
|
|
127
|
-
log.info("Nothing to clean.");
|
|
128
|
-
console.log();
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
const selected = await checkbox({
|
|
132
|
-
message: "Select directories to clean:",
|
|
133
|
-
choices: cleanable.map((c) => ({
|
|
134
|
-
name: `${c.key} \u2014 ${c.fileCount} ${c.fileCount === 1 ? "file" : "files"}`,
|
|
135
|
-
value: c.key
|
|
136
|
-
}))
|
|
137
|
-
});
|
|
138
|
-
if (selected.length === 0) {
|
|
139
|
-
log.dim(" Nothing selected.");
|
|
140
|
-
console.log();
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const now = /* @__PURE__ */ new Date();
|
|
144
125
|
const summary = [];
|
|
145
|
-
|
|
126
|
+
while (true) {
|
|
127
|
+
const cleanable = candidates.map((c) => ({ ...c, fileCount: countFiles(c.path) })).filter((c) => existsSync(c.path) && c.fileCount > 0);
|
|
128
|
+
if (cleanable.length === 0) {
|
|
129
|
+
log.info("Nothing to clean.");
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
const selected = await select({
|
|
133
|
+
message: "Select a directory to clean:",
|
|
134
|
+
choices: [
|
|
135
|
+
...cleanable.map((c) => ({
|
|
136
|
+
name: `${c.key} \u2014 ${c.fileCount} ${c.fileCount === 1 ? "file" : "files"}`,
|
|
137
|
+
value: c.key
|
|
138
|
+
})),
|
|
139
|
+
{ name: chalk.dim("Done (exit)"), value: "__done__" }
|
|
140
|
+
]
|
|
141
|
+
});
|
|
142
|
+
if (selected === "__done__") break;
|
|
143
|
+
const entry = cleanable.find((c) => c.key === selected);
|
|
146
144
|
const relPath = relative(process.cwd(), entry.path);
|
|
147
145
|
console.log();
|
|
148
146
|
console.log(`${chalk.yellow("\u2192")} ${chalk.bold(entry.key)} (${relPath})`);
|
|
@@ -151,6 +149,7 @@ async function cleanCommand() {
|
|
|
151
149
|
const message = isMemory ? `Delete matching contents of ${relPath}/? (includes SQLite databases \u2014 stop memory daemon first if running)` : `Delete matching contents of ${relPath}/?`;
|
|
152
150
|
const ok = await confirm({ message, default: false });
|
|
153
151
|
if (ok) {
|
|
152
|
+
const now = /* @__PURE__ */ new Date();
|
|
154
153
|
const { deleted, failed } = deleteMatchingEntries(
|
|
155
154
|
entry.path,
|
|
156
155
|
range,
|