coding-friend-cli 1.32.1 → 1.32.2

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.
@@ -9,7 +9,7 @@ import {
9
9
  askScope,
10
10
  formatScopeLabel,
11
11
  injectBackChoice
12
- } from "./chunk-HPNRQYLM.js";
12
+ } from "./chunk-Z5Q533UG.js";
13
13
  import {
14
14
  globalConfigPath,
15
15
  localConfigPath
@@ -6,7 +6,7 @@ import {
6
6
  getMemoryMcpStatus,
7
7
  memoryConfigMenu,
8
8
  writeMemoryMcpEntry
9
- } from "./chunk-5W7ZOVDU.js";
9
+ } from "./chunk-3QK6S74O.js";
10
10
  import {
11
11
  loadConfig,
12
12
  resolveMemoryDir
@@ -16,15 +16,15 @@ import {
16
16
  } from "./chunk-RZRT7NGT.js";
17
17
  import {
18
18
  showConfigHint
19
- } from "./chunk-HPNRQYLM.js";
20
- import {
21
- run,
22
- runWithStderr
23
- } from "./chunk-EVGXUDX4.js";
19
+ } from "./chunk-Z5Q533UG.js";
24
20
  import {
25
21
  globalConfigPath,
26
22
  localConfigPath
27
23
  } from "./chunk-TWKNGPBO.js";
24
+ import {
25
+ run,
26
+ runWithStderr
27
+ } from "./chunk-EVGXUDX4.js";
28
28
  import {
29
29
  log,
30
30
  printBanner
@@ -142,70 +142,25 @@ function ensureMemoryBuilt(mcpDir) {
142
142
  log.success("Done.");
143
143
  }
144
144
  }
145
- function printMemoryMcpConfig(serverPath, memoryDir) {
145
+ function printMemoryMcpConfig(memoryDir) {
146
146
  console.log(chalk2.dim("Add this to your MCP client config:"));
147
147
  console.log();
148
- console.log(
149
- chalk2.yellow.bold("--- Claude Code (.mcp.json in project root) ---")
150
- );
151
- console.log(`
152
- {
148
+ console.log(`{
153
149
  "mcpServers": {
154
150
  "coding-friend-memory": {
155
151
  "command": "npx",
156
- "args": ["-y", "coding-friend-cli", "mcp-serve", "${memoryDir}"]
152
+ "args": [
153
+ "-y",
154
+ "coding-friend-cli",
155
+ "mcp-serve",
156
+ "${memoryDir}"
157
+ ]
157
158
  }
158
159
  }
159
160
  }`);
160
161
  console.log();
161
- console.log(
162
- chalk2.yellow.bold(
163
- "--- Claude Desktop / Claude Chat (claude_desktop_config.json) ---"
164
- )
165
- );
166
- console.log(`
167
- {
168
- "mcpServers": {
169
- "coding-friend-memory": {
170
- "command": "node",
171
- "args": ["${serverPath}", "${memoryDir}"]
172
- }
173
- }
174
- }`);
175
- console.log();
176
- console.log(chalk2.yellow.bold("--- Generic MCP client ---"));
177
- console.log(`
178
- Server command: node ${serverPath} ${memoryDir}
179
- Transport: stdio`);
180
- console.log();
181
- console.log(chalk2.yellow.bold("--- Available tools ---"));
182
- console.log();
183
- console.log(
184
- ` ${chalk2.white("memory_store")} ${chalk2.dim("Store a new memory")}`
185
- );
186
- console.log(
187
- ` ${chalk2.white("memory_search")} ${chalk2.dim("Search memories (keyword match)")}`
188
- );
189
- console.log(
190
- ` ${chalk2.white("memory_retrieve")} ${chalk2.dim("Get a specific memory by ID")}`
191
- );
192
- console.log(
193
- ` ${chalk2.white("memory_list")} ${chalk2.dim("List memories with filtering")}`
194
- );
195
- console.log(
196
- ` ${chalk2.white("memory_update")} ${chalk2.dim("Update existing memory")}`
197
- );
198
- console.log(
199
- ` ${chalk2.white("memory_delete")} ${chalk2.dim("Delete a memory")}`
200
- );
201
- console.log();
202
- console.log(chalk2.yellow.bold("--- Resources ---"));
203
- console.log();
204
- console.log(
205
- ` ${chalk2.white("memory://index")} ${chalk2.dim("Browse all memories")}`
206
- );
207
- console.log(
208
- ` ${chalk2.white("memory://stats")} ${chalk2.dim("Storage statistics")}`
162
+ log.dim(
163
+ "Available tools & resources: https://cf.dinhanhthi.com/docs/cli/cf-mcp/"
209
164
  );
210
165
  console.log();
211
166
  log.warn(
@@ -906,8 +861,7 @@ async function memoryMcpCommand() {
906
861
  const mcpDir = getLibPath("cf-memory");
907
862
  ensureMemoryBuilt(mcpDir);
908
863
  warnStaleMcpJson(memoryDir);
909
- const serverPath = join2(mcpDir, "dist", "index.js");
910
- printMemoryMcpConfig(serverPath, memoryDir);
864
+ printMemoryMcpConfig(memoryDir);
911
865
  }
912
866
 
913
867
  export {
@@ -7,16 +7,16 @@ import {
7
7
  } from "./chunk-DMJCO6LJ.js";
8
8
  import {
9
9
  resolveScope
10
- } from "./chunk-HPNRQYLM.js";
10
+ } from "./chunk-Z5Q533UG.js";
11
+ import {
12
+ claudeSettingsPath
13
+ } from "./chunk-TWKNGPBO.js";
11
14
  import {
12
15
  commandExists,
13
16
  run,
14
17
  runWithStderr,
15
18
  sleepSync
16
19
  } from "./chunk-EVGXUDX4.js";
17
- import {
18
- claudeSettingsPath
19
- } from "./chunk-TWKNGPBO.js";
20
20
  import {
21
21
  log,
22
22
  printBanner
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  memoryConfigMenu
3
- } from "./chunk-5W7ZOVDU.js";
3
+ } from "./chunk-3QK6S74O.js";
4
4
  import "./chunk-GTX6I57V.js";
5
5
  import "./chunk-RZRT7NGT.js";
6
6
  import {
@@ -32,10 +32,7 @@ import {
32
32
  getScopeLabel,
33
33
  injectBackChoice,
34
34
  showConfigHint
35
- } from "./chunk-HPNRQYLM.js";
36
- import {
37
- run
38
- } from "./chunk-EVGXUDX4.js";
35
+ } from "./chunk-Z5Q533UG.js";
39
36
  import {
40
37
  claudeLocalSettingsPath,
41
38
  claudeProjectSettingsPath,
@@ -44,6 +41,9 @@ import {
44
41
  localConfigPath,
45
42
  resolvePath
46
43
  } from "./chunk-TWKNGPBO.js";
44
+ import {
45
+ run
46
+ } from "./chunk-EVGXUDX4.js";
47
47
  import {
48
48
  log,
49
49
  printBanner
@@ -593,7 +593,7 @@ async function editPermissions() {
593
593
  )
594
594
  });
595
595
  if (choice === BACK) return;
596
- const { permissionCommand } = await import("./permission-C5R3LMZQ.js");
596
+ const { permissionCommand } = await import("./permission-DNW7DE24.js");
597
597
  switch (choice) {
598
598
  case "interactive":
599
599
  await permissionCommand({});
@@ -4,9 +4,9 @@ import {
4
4
  } from "./chunk-R6HDMRYL.js";
5
5
  import {
6
6
  resolveScope
7
- } from "./chunk-HPNRQYLM.js";
8
- import "./chunk-EVGXUDX4.js";
7
+ } from "./chunk-Z5Q533UG.js";
9
8
  import "./chunk-TWKNGPBO.js";
9
+ import "./chunk-EVGXUDX4.js";
10
10
  import {
11
11
  log
12
12
  } from "./chunk-NREZK463.js";
@@ -4,9 +4,9 @@ import {
4
4
  } from "./chunk-R6HDMRYL.js";
5
5
  import {
6
6
  resolveScope
7
- } from "./chunk-HPNRQYLM.js";
8
- import "./chunk-EVGXUDX4.js";
7
+ } from "./chunk-Z5Q533UG.js";
9
8
  import "./chunk-TWKNGPBO.js";
9
+ import "./chunk-EVGXUDX4.js";
10
10
  import {
11
11
  log
12
12
  } from "./chunk-NREZK463.js";
package/dist/index.js CHANGED
@@ -14,58 +14,62 @@ 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
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-JR4ITJVU.js");
17
+ const { installCommand } = await import("./install-22BLHQ6D.js");
18
18
  await installCommand(opts);
19
19
  });
20
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-BOVKPNYN.js");
21
+ const { uninstallCommand } = await import("./uninstall-6ZJRS2H4.js");
22
22
  await uninstallCommand(opts);
23
23
  });
24
24
  program.command("disable").description("Disable the Coding Friend plugin without uninstalling").option("--user", "Disable at user scope (all projects)").option("--global", "Disable at user scope (all projects)").option("--project", "Disable at project scope").option("--local", "Disable at local scope").action(async (opts) => {
25
- const { disableCommand } = await import("./disable-CDOM7SSI.js");
25
+ const { disableCommand } = await import("./disable-ZWQVU3QZ.js");
26
26
  await disableCommand(opts);
27
27
  });
28
28
  program.command("enable").description("Re-enable the Coding Friend plugin").option("--user", "Enable at user scope (all projects)").option("--global", "Enable at user scope (all projects)").option("--project", "Enable at project scope").option("--local", "Enable at local scope").action(async (opts) => {
29
- const { enableCommand } = await import("./enable-SF7742UR.js");
29
+ const { enableCommand } = await import("./enable-NXP6APNI.js");
30
30
  await enableCommand(opts);
31
31
  });
32
32
  program.command("init").description("Initialize coding-friend in current project").action(async () => {
33
- const { initCommand } = await import("./init-3UITY4LD.js");
33
+ const { initCommand } = await import("./init-F2NO6NCJ.js");
34
34
  await initCommand();
35
35
  });
36
36
  program.command("config").description("Manage Coding Friend configuration").action(async () => {
37
- const { configCommand } = await import("./config-FUEEFM5N.js");
37
+ const { configCommand } = await import("./config-RE4SQ6Y7.js");
38
38
  await configCommand();
39
39
  });
40
40
  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) => {
41
- const { hostCommand } = await import("./host-RNYPAE4D.js");
41
+ const { hostCommand } = await import("./host-XZZEMMMI.js");
42
42
  await hostCommand(path, opts);
43
43
  });
44
44
  program.command("mcp").description("Setup MCP server for learning docs").argument("[path]", "path to docs folder").action(async (path) => {
45
- const { mcpCommand } = await import("./mcp-LJ5NX6XE.js");
45
+ const { mcpCommand } = await import("./mcp-VQ5OXXU7.js");
46
46
  await mcpCommand(path);
47
47
  });
48
48
  program.command("mcp-serve").description("Start the cf-memory MCP server (used internally by npx)").argument("<memoryDir>", "path to memory directory").action(async (memoryDir) => {
49
49
  const { mcpServeCommand } = await import("./mcp-serve-3FEPFVVQ.js");
50
50
  await mcpServeCommand(memoryDir);
51
51
  });
52
+ program.command("mcp-serve-learn").description("Start the learn MCP server (used internally by npx)").argument("<docsDir>", "path to docs directory").action(async (docsDir) => {
53
+ const { mcpServeLearnCommand } = await import("./mcp-serve-learn-UNW6VH5M.js");
54
+ await mcpServeLearnCommand(docsDir);
55
+ });
52
56
  program.command("permission").description("Manage Claude Code permission rules for Coding Friend").option("--all", "Apply all recommended permissions without prompts").option("--user", "Save to user-level settings (~/.claude/settings.json)").option(
53
57
  "--project",
54
58
  "Save to project-level settings (.claude/settings.local.json)"
55
59
  ).action(async (opts) => {
56
- const { permissionCommand } = await import("./permission-C5R3LMZQ.js");
60
+ const { permissionCommand } = await import("./permission-DNW7DE24.js");
57
61
  await permissionCommand(opts);
58
62
  });
59
63
  program.command("statusline").description("Setup coding-friend statusline in Claude Code").action(async () => {
60
- const { statuslineCommand } = await import("./statusline-5X7FZGRU.js");
64
+ const { statuslineCommand } = await import("./statusline-GKVAX7GR.js");
61
65
  await statuslineCommand();
62
66
  });
63
67
  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) => {
64
- const { updateCommand } = await import("./update-JBCG4CY2.js");
68
+ const { updateCommand } = await import("./update-P5ZR2JVQ.js");
65
69
  await updateCommand(opts);
66
70
  });
67
71
  program.command("status").description("Show comprehensive Coding Friend status").action(async () => {
68
- const { statusCommand } = await import("./status-FU5GR3MP.js");
72
+ const { statusCommand } = await import("./status-7YW3YV2Y.js");
69
73
  await statusCommand();
70
74
  });
71
75
  var session = program.command("session").description("Save and load Claude Code sessions across machines");
@@ -104,43 +108,43 @@ Memory subcommands:
104
108
  memory mcp Show MCP server setup instructions`
105
109
  );
106
110
  memory.command("status").description("Show memory system status").action(async () => {
107
- const { memoryStatusCommand } = await import("./memory-2ZD4WU3S.js");
111
+ const { memoryStatusCommand } = await import("./memory-GKANJJXU.js");
108
112
  await memoryStatusCommand();
109
113
  });
110
114
  memory.command("search").description("Search memories by query").argument("<query>", "search query").action(async (query) => {
111
- const { memorySearchCommand } = await import("./memory-2ZD4WU3S.js");
115
+ const { memorySearchCommand } = await import("./memory-GKANJJXU.js");
112
116
  await memorySearchCommand(query);
113
117
  });
114
118
  memory.command("list").description(
115
119
  "List memories in current project, or all projects with --projects"
116
120
  ).option("--projects", "List all project databases with size and metadata").action(async (opts) => {
117
- const { memoryListCommand } = await import("./memory-2ZD4WU3S.js");
121
+ const { memoryListCommand } = await import("./memory-GKANJJXU.js");
118
122
  await memoryListCommand(opts);
119
123
  });
120
124
  memory.command("init").description(
121
125
  "Initialize memory system \u2014 interactive wizard (first time) or config menu"
122
126
  ).action(async () => {
123
- const { memoryInitCommand } = await import("./memory-2ZD4WU3S.js");
127
+ const { memoryInitCommand } = await import("./memory-GKANJJXU.js");
124
128
  await memoryInitCommand();
125
129
  });
126
130
  memory.command("config").description("Configure memory system settings").action(async () => {
127
- const { memoryConfigCommand } = await import("./memory-2ZD4WU3S.js");
131
+ const { memoryConfigCommand } = await import("./memory-GKANJJXU.js");
128
132
  await memoryConfigCommand();
129
133
  });
130
134
  memory.command("start-daemon").description("Start the memory daemon (Tier 2 \u2014 MiniSearch)").action(async () => {
131
- const { memoryStartDaemonCommand } = await import("./memory-2ZD4WU3S.js");
135
+ const { memoryStartDaemonCommand } = await import("./memory-GKANJJXU.js");
132
136
  await memoryStartDaemonCommand();
133
137
  });
134
138
  memory.command("stop-daemon").description("Stop the memory daemon").action(async () => {
135
- const { memoryStopDaemonCommand } = await import("./memory-2ZD4WU3S.js");
139
+ const { memoryStopDaemonCommand } = await import("./memory-GKANJJXU.js");
136
140
  await memoryStopDaemonCommand();
137
141
  });
138
142
  memory.command("rebuild").description("Rebuild the daemon search index").action(async () => {
139
- const { memoryRebuildCommand } = await import("./memory-2ZD4WU3S.js");
143
+ const { memoryRebuildCommand } = await import("./memory-GKANJJXU.js");
140
144
  await memoryRebuildCommand();
141
145
  });
142
146
  memory.command("mcp").description("Show MCP server setup instructions").action(async () => {
143
- const { memoryMcpCommand } = await import("./memory-2ZD4WU3S.js");
147
+ const { memoryMcpCommand } = await import("./memory-GKANJJXU.js");
144
148
  await memoryMcpCommand();
145
149
  });
146
150
  memory.command("rm").description("Remove a project database").option("--project-id <id>", "Project ID to remove").option("--all", "Remove all project databases").option(
@@ -148,7 +152,7 @@ memory.command("rm").description("Remove a project database").option("--project-
148
152
  "Remove orphaned projects (source dir missing or 0 memories)"
149
153
  ).action(
150
154
  async (opts) => {
151
- const { memoryRmCommand } = await import("./memory-2ZD4WU3S.js");
155
+ const { memoryRmCommand } = await import("./memory-GKANJJXU.js");
152
156
  await memoryRmCommand(opts);
153
157
  }
154
158
  );
@@ -174,41 +178,41 @@ Dev subcommands:
174
178
  dev update [path] Update local dev plugin to latest version`
175
179
  );
176
180
  dev.command("on").description("Switch to local plugin source").argument("[path]", "path to local coding-friend repo (default: cwd)").action(async (path) => {
177
- const { devOnCommand } = await import("./dev-VNDV6R24.js");
181
+ const { devOnCommand } = await import("./dev-QXVERU42.js");
178
182
  await devOnCommand(path);
179
183
  });
180
184
  dev.command("off").description("Switch back to remote marketplace").action(async () => {
181
- const { devOffCommand } = await import("./dev-VNDV6R24.js");
185
+ const { devOffCommand } = await import("./dev-QXVERU42.js");
182
186
  await devOffCommand();
183
187
  });
184
188
  dev.command("status").description("Show current dev mode").action(async () => {
185
- const { devStatusCommand } = await import("./dev-VNDV6R24.js");
189
+ const { devStatusCommand } = await import("./dev-QXVERU42.js");
186
190
  await devStatusCommand();
187
191
  });
188
192
  dev.command("sync").description(
189
193
  "Copy local source files to plugin cache (no version bump needed)"
190
194
  ).action(async () => {
191
- const { devSyncCommand } = await import("./dev-VNDV6R24.js");
195
+ const { devSyncCommand } = await import("./dev-QXVERU42.js");
192
196
  await devSyncCommand();
193
197
  });
194
198
  dev.command("restart").description("Reinstall local dev plugin (off + on)").argument(
195
199
  "[path]",
196
200
  "path to local coding-friend repo (default: saved path or cwd)"
197
201
  ).action(async (path) => {
198
- const { devRestartCommand } = await import("./dev-VNDV6R24.js");
202
+ const { devRestartCommand } = await import("./dev-QXVERU42.js");
199
203
  await devRestartCommand(path);
200
204
  });
201
205
  dev.command("update").description("Update local dev plugin to latest version (off + on)").argument(
202
206
  "[path]",
203
207
  "path to local coding-friend repo (default: saved path or cwd)"
204
208
  ).action(async (path) => {
205
- const { devUpdateCommand } = await import("./dev-VNDV6R24.js");
209
+ const { devUpdateCommand } = await import("./dev-QXVERU42.js");
206
210
  await devUpdateCommand(path);
207
211
  });
208
212
  program.hook("postAction", async () => {
209
213
  const topCmd = process.argv[2];
210
214
  if (topCmd === "update") return;
211
- const { checkAndNotifyCliUpdate } = await import("./update-check-BPCQ25AR.js");
215
+ const { checkAndNotifyCliUpdate } = await import("./update-check-5SCD2JR2.js");
212
216
  checkAndNotifyCliUpdate(pkg.version);
213
217
  });
214
218
  await program.parseAsync();
@@ -2,10 +2,10 @@ import {
2
2
  ensureMemoryBuilt,
3
3
  isMemoryInitialized,
4
4
  memoryInitWizard
5
- } from "./chunk-355AR2X5.js";
5
+ } from "./chunk-66EDSJ6W.js";
6
6
  import {
7
7
  memoryConfigMenu
8
- } from "./chunk-5W7ZOVDU.js";
8
+ } from "./chunk-3QK6S74O.js";
9
9
  import "./chunk-GTX6I57V.js";
10
10
  import {
11
11
  getLibPath
@@ -38,11 +38,7 @@ import {
38
38
  getScopeLabel,
39
39
  injectBackChoice,
40
40
  showConfigHint
41
- } from "./chunk-HPNRQYLM.js";
42
- import {
43
- commandExists,
44
- run
45
- } from "./chunk-EVGXUDX4.js";
41
+ } from "./chunk-Z5Q533UG.js";
46
42
  import {
47
43
  claudeLocalSettingsPath,
48
44
  claudeProjectSettingsPath,
@@ -51,6 +47,10 @@ import {
51
47
  localConfigPath,
52
48
  resolvePath
53
49
  } from "./chunk-TWKNGPBO.js";
50
+ import {
51
+ commandExists,
52
+ run
53
+ } from "./chunk-EVGXUDX4.js";
54
54
  import {
55
55
  log,
56
56
  printBanner
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getLatestVersion,
3
3
  semverCompare
4
- } from "./chunk-4IUUWBZG.js";
4
+ } from "./chunk-G4QGJEV7.js";
5
5
  import {
6
6
  getInstalledVersion
7
7
  } from "./chunk-LXZ47XCD.js";
@@ -16,14 +16,14 @@ import {
16
16
  } from "./chunk-R6HDMRYL.js";
17
17
  import {
18
18
  resolveScope
19
- } from "./chunk-HPNRQYLM.js";
19
+ } from "./chunk-Z5Q533UG.js";
20
+ import {
21
+ devStatePath
22
+ } from "./chunk-TWKNGPBO.js";
20
23
  import {
21
24
  commandExists,
22
25
  run
23
26
  } from "./chunk-EVGXUDX4.js";
24
- import {
25
- devStatePath
26
- } from "./chunk-TWKNGPBO.js";
27
27
  import {
28
28
  log,
29
29
  printBanner
@@ -3,8 +3,8 @@ import {
3
3
  ensureMemoryBuilt,
4
4
  printMemoryMcpConfig,
5
5
  warnStaleMcpJson
6
- } from "./chunk-355AR2X5.js";
7
- import "./chunk-5W7ZOVDU.js";
6
+ } from "./chunk-66EDSJ6W.js";
7
+ import "./chunk-3QK6S74O.js";
8
8
  import {
9
9
  resolveDocsDir,
10
10
  resolveMemoryDir
@@ -13,11 +13,11 @@ import {
13
13
  getLibPath
14
14
  } from "./chunk-RZRT7NGT.js";
15
15
  import "./chunk-DHH6SRXV.js";
16
- import "./chunk-HPNRQYLM.js";
16
+ import "./chunk-Z5Q533UG.js";
17
+ import "./chunk-TWKNGPBO.js";
17
18
  import {
18
19
  run
19
20
  } from "./chunk-EVGXUDX4.js";
20
- import "./chunk-TWKNGPBO.js";
21
21
  import {
22
22
  log,
23
23
  printBanner
@@ -57,7 +57,6 @@ async function mcpCommand(path) {
57
57
  printBanner("\u{1F4DA} Learn MCP");
58
58
  log.info(`Docs folder: ${chalk.cyan(docsDir)}`);
59
59
  log.info(`Found: ${chalk.green(docCount)} docs`);
60
- console.log();
61
60
  if (!existsSync(join(mcpDir, "node_modules"))) {
62
61
  log.step("Installing MCP server dependencies (one-time setup)...");
63
62
  const result = run("npm", ["install", "--silent"], { cwd: mcpDir });
@@ -77,60 +76,24 @@ async function mcpCommand(path) {
77
76
  log.success("Done.");
78
77
  }
79
78
  console.log();
80
- const serverPath = join(mcpDir, "dist", "index.js");
81
79
  console.log(chalk.dim("Add this to your MCP client config:"));
82
80
  console.log();
83
- console.log(
84
- chalk.yellow.bold(
85
- "--- Claude Desktop / Claude Chat (claude_desktop_config.json) ---"
86
- )
87
- );
88
- console.log(`
89
- {
81
+ console.log(`{
90
82
  "mcpServers": {
91
83
  "coding-friend-learn": {
92
- "command": "node",
93
- "args": ["${serverPath}", "${docsDir}"]
84
+ "command": "npx",
85
+ "args": [
86
+ "-y",
87
+ "coding-friend-cli",
88
+ "mcp-serve-learn",
89
+ "${docsDir}"
90
+ ]
94
91
  }
95
92
  }
96
93
  }`);
97
94
  console.log();
98
- console.log(chalk.yellow.bold("--- Generic MCP client ---"));
99
- console.log(`
100
- Server command: node ${serverPath} ${docsDir}
101
- Transport: stdio`);
102
- console.log();
103
- console.log(chalk.yellow.bold("--- Available tools ---"));
104
- console.log();
105
- console.log(chalk.cyan.bold("Read:"));
106
- console.log(
107
- ` ${chalk.white("list-categories")} ${chalk.dim("List all categories with doc counts")}`
108
- );
109
- console.log(
110
- ` ${chalk.white("list-docs")} ${chalk.dim("List docs, filter by category/tag")}`
111
- );
112
- console.log(
113
- ` ${chalk.white("read-doc")} ${chalk.dim("Read full content of a doc")}`
114
- );
115
- console.log(
116
- ` ${chalk.white("search-docs")} ${chalk.dim("Full-text search across all docs")}`
117
- );
118
- console.log(
119
- ` ${chalk.white("get-review-list")} ${chalk.dim("Docs that need review")}`
120
- );
121
- console.log();
122
- console.log(chalk.cyan.bold("Write:"));
123
- console.log(
124
- ` ${chalk.white("create-doc")} ${chalk.dim("Create new learning doc")}`
125
- );
126
- console.log(
127
- ` ${chalk.white("update-doc")} ${chalk.dim("Append content or update tags")}`
128
- );
129
- console.log(
130
- ` ${chalk.white("improve-doc")} ${chalk.dim("Get improvement suggestions")}`
131
- );
132
- console.log(
133
- ` ${chalk.white("track-knowledge")} ${chalk.dim("Record understanding level (remembered/needs-review/new)")}`
95
+ log.dim(
96
+ "Available tools & resources: https://cf.dinhanhthi.com/docs/cli/cf-mcp/"
134
97
  );
135
98
  console.log();
136
99
  printMemoryMcp();
@@ -147,12 +110,11 @@ function printMemoryMcp() {
147
110
  return;
148
111
  }
149
112
  ensureMemoryBuilt(mcpDir);
150
- const serverPath = join(mcpDir, "dist", "index.js");
151
113
  console.log();
152
114
  printBanner("\u{1F9E0} Memory MCP", { color: chalk.magenta });
153
115
  log.info(`Memory dir: ${chalk.cyan(memoryDir)}`);
154
116
  console.log();
155
- printMemoryMcpConfig(serverPath, memoryDir);
117
+ printMemoryMcpConfig(memoryDir);
156
118
  }
157
119
  export {
158
120
  detectMemoryMcpState,
@@ -0,0 +1,59 @@
1
+ import {
2
+ getLibPath
3
+ } from "./chunk-RZRT7NGT.js";
4
+ import {
5
+ runWithStderr
6
+ } from "./chunk-EVGXUDX4.js";
7
+ import {
8
+ log
9
+ } from "./chunk-NREZK463.js";
10
+
11
+ // src/commands/mcp-serve-learn.ts
12
+ import { spawn } from "child_process";
13
+ import { existsSync, statSync } from "fs";
14
+ import { join } from "path";
15
+ function ensureLearnBuilt(mcpDir) {
16
+ if (!existsSync(join(mcpDir, "node_modules"))) {
17
+ log.step("Installing learn server dependencies (one-time setup)...");
18
+ const result = runWithStderr("npm", ["install"], { cwd: mcpDir });
19
+ if (result.exitCode !== 0) {
20
+ log.error("Failed to install dependencies");
21
+ if (result.stderr) log.error(result.stderr);
22
+ process.exit(1);
23
+ }
24
+ log.success("Done.");
25
+ }
26
+ if (!existsSync(join(mcpDir, "dist"))) {
27
+ log.step("Building learn server...");
28
+ const result = runWithStderr("npm", ["run", "build"], { cwd: mcpDir });
29
+ if (result.exitCode !== 0) {
30
+ log.error("Failed to build learn server");
31
+ if (result.stderr) log.error(result.stderr);
32
+ process.exit(1);
33
+ }
34
+ log.success("Done.");
35
+ }
36
+ }
37
+ async function mcpServeLearnCommand(docsDir) {
38
+ if (!existsSync(docsDir) || !statSync(docsDir).isDirectory()) {
39
+ log.error(`Docs directory not found: ${docsDir}`);
40
+ process.exit(1);
41
+ return;
42
+ }
43
+ const mcpDir = getLibPath("learn-mcp");
44
+ ensureLearnBuilt(mcpDir);
45
+ const serverPath = join(mcpDir, "dist", "index.js");
46
+ const child = spawn("node", [serverPath, docsDir], {
47
+ stdio: "inherit"
48
+ });
49
+ child.on("error", (err) => {
50
+ log.error(`Failed to start learn MCP server: ${err.message}`);
51
+ process.exit(1);
52
+ });
53
+ child.on("exit", (code) => {
54
+ process.exit(code ?? 0);
55
+ });
56
+ }
57
+ export {
58
+ mcpServeLearnCommand
59
+ };
@@ -13,14 +13,14 @@ import {
13
13
  memoryStatusCommand,
14
14
  memoryStopDaemonCommand,
15
15
  printMemoryMcpConfig
16
- } from "./chunk-355AR2X5.js";
17
- import "./chunk-5W7ZOVDU.js";
16
+ } from "./chunk-66EDSJ6W.js";
17
+ import "./chunk-3QK6S74O.js";
18
18
  import "./chunk-GTX6I57V.js";
19
19
  import "./chunk-RZRT7NGT.js";
20
20
  import "./chunk-DHH6SRXV.js";
21
- import "./chunk-HPNRQYLM.js";
22
- import "./chunk-EVGXUDX4.js";
21
+ import "./chunk-Z5Q533UG.js";
23
22
  import "./chunk-TWKNGPBO.js";
23
+ import "./chunk-EVGXUDX4.js";
24
24
  import "./chunk-NREZK463.js";
25
25
  import "./chunk-5UVDWG5L.js";
26
26
  export {
@@ -3,8 +3,7 @@ import {
3
3
  formatScopeLabel,
4
4
  getMergedValue,
5
5
  getScopeLabel
6
- } from "./chunk-HPNRQYLM.js";
7
- import "./chunk-EVGXUDX4.js";
6
+ } from "./chunk-Z5Q533UG.js";
8
7
  import {
9
8
  claudeLocalSettingsPath,
10
9
  claudeProjectSettingsPath,
@@ -12,6 +11,7 @@ import {
12
11
  globalConfigPath,
13
12
  localConfigPath
14
13
  } from "./chunk-TWKNGPBO.js";
14
+ import "./chunk-EVGXUDX4.js";
15
15
  import {
16
16
  log,
17
17
  printBanner
@@ -9,7 +9,7 @@ import {
9
9
  getLatestCliVersion,
10
10
  getLatestVersion,
11
11
  semverCompare
12
- } from "./chunk-4IUUWBZG.js";
12
+ } from "./chunk-G4QGJEV7.js";
13
13
  import {
14
14
  getInstalledVersion
15
15
  } from "./chunk-LXZ47XCD.js";
@@ -19,14 +19,14 @@ import {
19
19
  detectPluginScope,
20
20
  isPluginDisabled
21
21
  } from "./chunk-R6HDMRYL.js";
22
- import "./chunk-HPNRQYLM.js";
23
- import "./chunk-EVGXUDX4.js";
22
+ import "./chunk-Z5Q533UG.js";
24
23
  import {
25
24
  claudeSettingsPath,
26
25
  devStatePath,
27
26
  globalConfigPath,
28
27
  localConfigPath
29
28
  } from "./chunk-TWKNGPBO.js";
29
+ import "./chunk-EVGXUDX4.js";
30
30
  import "./chunk-NREZK463.js";
31
31
  import {
32
32
  getExistingRules
@@ -8,11 +8,7 @@ import {
8
8
  } from "./chunk-R6HDMRYL.js";
9
9
  import {
10
10
  resolveScope
11
- } from "./chunk-HPNRQYLM.js";
12
- import {
13
- commandExists,
14
- run
15
- } from "./chunk-EVGXUDX4.js";
11
+ } from "./chunk-Z5Q533UG.js";
16
12
  import {
17
13
  claudeSettingsPath,
18
14
  devStatePath,
@@ -21,6 +17,10 @@ import {
21
17
  marketplaceClonePath,
22
18
  memoryDepsDir
23
19
  } from "./chunk-TWKNGPBO.js";
20
+ import {
21
+ commandExists,
22
+ run
23
+ } from "./chunk-EVGXUDX4.js";
24
24
  import {
25
25
  log,
26
26
  printBanner
@@ -4,13 +4,13 @@ import {
4
4
  getLatestVersion,
5
5
  semverCompare,
6
6
  updateCommand
7
- } from "./chunk-4IUUWBZG.js";
7
+ } from "./chunk-G4QGJEV7.js";
8
8
  import "./chunk-LXZ47XCD.js";
9
9
  import "./chunk-DHH6SRXV.js";
10
10
  import "./chunk-DMJCO6LJ.js";
11
- import "./chunk-HPNRQYLM.js";
12
- import "./chunk-EVGXUDX4.js";
11
+ import "./chunk-Z5Q533UG.js";
13
12
  import "./chunk-TWKNGPBO.js";
13
+ import "./chunk-EVGXUDX4.js";
14
14
  import "./chunk-NREZK463.js";
15
15
  import "./chunk-5UVDWG5L.js";
16
16
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coding-friend-cli",
3
- "version": "1.32.1",
3
+ "version": "1.32.2",
4
4
  "description": "CLI for coding-friend — host learning docs, setup MCP server, initialize projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,10 +1,10 @@
1
- import {
2
- run
3
- } from "./chunk-EVGXUDX4.js";
4
1
  import {
5
2
  globalConfigPath,
6
3
  localConfigPath
7
4
  } from "./chunk-TWKNGPBO.js";
5
+ import {
6
+ run
7
+ } from "./chunk-EVGXUDX4.js";
8
8
  import {
9
9
  log
10
10
  } from "./chunk-NREZK463.js";
@@ -9,15 +9,15 @@ import {
9
9
  isMarketplaceRegistered,
10
10
  isPluginInstalled
11
11
  } from "./chunk-R6HDMRYL.js";
12
- import {
13
- commandExists,
14
- run
15
- } from "./chunk-EVGXUDX4.js";
16
12
  import {
17
13
  devStatePath,
18
14
  knownMarketplacesPath,
19
15
  pluginCachePath
20
16
  } from "./chunk-TWKNGPBO.js";
17
+ import {
18
+ commandExists,
19
+ run
20
+ } from "./chunk-EVGXUDX4.js";
21
21
  import {
22
22
  log,
23
23
  printBanner
@@ -5,11 +5,11 @@ import {
5
5
  getLibPath
6
6
  } from "./chunk-RZRT7NGT.js";
7
7
  import "./chunk-DHH6SRXV.js";
8
+ import "./chunk-TWKNGPBO.js";
8
9
  import {
9
10
  run,
10
11
  streamExec
11
12
  } from "./chunk-EVGXUDX4.js";
12
- import "./chunk-TWKNGPBO.js";
13
13
  import {
14
14
  log,
15
15
  printBanner
@@ -12,10 +12,10 @@ import {
12
12
  import {
13
13
  ALL_COMPONENT_IDS
14
14
  } from "./chunk-DHH6SRXV.js";
15
+ import "./chunk-TWKNGPBO.js";
15
16
  import {
16
17
  commandExists
17
18
  } from "./chunk-EVGXUDX4.js";
18
- import "./chunk-TWKNGPBO.js";
19
19
  import {
20
20
  log,
21
21
  printBanner
@@ -1,9 +1,9 @@
1
- import {
2
- run
3
- } from "./chunk-EVGXUDX4.js";
4
1
  import {
5
2
  globalConfigDir
6
3
  } from "./chunk-TWKNGPBO.js";
4
+ import {
5
+ run
6
+ } from "./chunk-EVGXUDX4.js";
7
7
  import {
8
8
  log
9
9
  } from "./chunk-NREZK463.js";