coding-friend-cli 1.36.4 → 1.37.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/dist/index.js CHANGED
@@ -43,11 +43,11 @@ program.name("cf").description(
43
43
  "coding-friend CLI \u2014 host learning docs, setup MCP, init projects"
44
44
  ).version(wantsVersion ? buildVersionString() : pkg.version, "-v, --version");
45
45
  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) => {
46
- const { installCommand } = await import("./install-R2HDM3N4.js");
46
+ const { installCommand } = await import("./install-37NN4CQH.js");
47
47
  await installCommand(opts);
48
48
  });
49
49
  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) => {
50
- const { uninstallCommand } = await import("./uninstall-ASLHT3MH.js");
50
+ const { uninstallCommand } = await import("./uninstall-AVA3J554.js");
51
51
  await uninstallCommand(opts);
52
52
  });
53
53
  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) => {
@@ -59,11 +59,11 @@ program.command("enable").description("Re-enable the Coding Friend plugin").opti
59
59
  await enableCommand(opts);
60
60
  });
61
61
  program.command("init").description("Initialize coding-friend in current project").action(async () => {
62
- const { initCommand } = await import("./init-UABKVDVT.js");
62
+ const { initCommand } = await import("./init-6MFQWPOP.js");
63
63
  await initCommand();
64
64
  });
65
65
  program.command("config").description("Manage Coding Friend configuration").action(async () => {
66
- const { configCommand } = await import("./config-CTTHWJH5.js");
66
+ const { configCommand } = await import("./config-ZMR2AOBB.js");
67
67
  await configCommand();
68
68
  });
69
69
  var learn = program.command("learn").description("Manage learning docs \u2014 host as a website or push to git");
@@ -75,23 +75,25 @@ Learn subcommands:
75
75
  learn push [path] Commit and push learning docs (only if learn dir is the git root)`
76
76
  );
77
77
  learn.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) => {
78
- const { hostCommand } = await import("./host-NCJMUSME.js");
78
+ const { hostCommand } = await import("./host-SSRI4JZV.js");
79
79
  await hostCommand(path, opts);
80
80
  });
81
81
  learn.command("push").description("Commit and push learning docs to origin").argument("[path]", "path to docs folder").action(async (path) => {
82
- const { learnPushCommand } = await import("./learn-K64AUUFB.js");
82
+ const { learnPushCommand } = await import("./learn-OPH3CI67.js");
83
83
  await learnPushCommand(path);
84
84
  });
85
85
  program.command("host", { hidden: true }).argument("[path]", "path to docs folder").option("-p, --port <port>", "port number", "3333").action(async (path, opts) => {
86
- const { hostCommand } = await import("./host-NCJMUSME.js");
86
+ const { hostCommand } = await import("./host-SSRI4JZV.js");
87
87
  await hostCommand(path, opts);
88
88
  });
89
89
  program.command("mcp").description("Setup MCP server for learning docs").action(async () => {
90
- const { mcpCommand } = await import("./mcp-OMQFSJP4.js");
90
+ const { mcpCommand } = await import("./mcp-DWKVMNC7.js");
91
91
  await mcpCommand();
92
92
  });
93
- program.command("mcp-serve").description("Start the cf-memory MCP server (used internally by npx)").argument("<memoryDir>", "path to memory directory").action(async (memoryDir) => {
94
- const { mcpServeCommand } = await import("./mcp-serve-3FEPFVVQ.js");
93
+ program.command("mcp-serve").description(
94
+ "Start the cf-memory MCP server (used internally by npx). When memoryDir is omitted, resolves from CLAUDE_PROJECT_DIR at runtime."
95
+ ).argument("[memoryDir]", "path to memory directory (optional)").action(async (memoryDir) => {
96
+ const { mcpServeCommand } = await import("./mcp-serve-5GODJ4DJ.js");
95
97
  await mcpServeCommand(memoryDir);
96
98
  });
97
99
  program.command("mcp-serve-learn").description("Start the learn MCP server (used internally by npx)").argument("<docsDir>", "path to docs directory").action(async (docsDir) => {
@@ -110,15 +112,15 @@ program.command("statusline").description("Setup coding-friend statusline in Cla
110
112
  await statuslineCommand();
111
113
  });
112
114
  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) => {
113
- const { updateCommand } = await import("./update-DIOH45TE.js");
115
+ const { updateCommand } = await import("./update-Q3ACCK4Z.js");
114
116
  await updateCommand(opts);
115
117
  });
116
118
  program.command("status").description("Show comprehensive Coding Friend status").action(async () => {
117
- const { statusCommand } = await import("./status-ML4XEDYL.js");
119
+ const { statusCommand } = await import("./status-YZEOUX46.js");
118
120
  await statusCommand();
119
121
  });
120
122
  program.command("clean").description("Clean files generated by Coding Friend in docs/").action(async () => {
121
- const { cleanCommand } = await import("./clean-Q4VU662V.js");
123
+ const { cleanCommand } = await import("./clean-WEYQZB34.js");
122
124
  await cleanCommand();
123
125
  });
124
126
  var session = program.command("session").description("[beta] Save and load Claude Code sessions across machines");
@@ -133,11 +135,11 @@ session.command("save").description("Save current Claude Code session to sync fo
133
135
  "-s, --session-id <id>",
134
136
  "session UUID to save (default: auto-detect newest)"
135
137
  ).option("-l, --label <label>", "label for this session").action(async (opts) => {
136
- const { sessionSaveCommand } = await import("./session-Q2DLQPYP.js");
138
+ const { sessionSaveCommand } = await import("./session-S4WKA4P5.js");
137
139
  await sessionSaveCommand(opts);
138
140
  });
139
141
  session.command("load").description("Load a saved session from sync folder").action(async () => {
140
- const { sessionLoadCommand } = await import("./session-Q2DLQPYP.js");
142
+ const { sessionLoadCommand } = await import("./session-S4WKA4P5.js");
141
143
  await sessionLoadCommand();
142
144
  });
143
145
  var memory = program.command("memory").description("AI memory system \u2014 store and search project knowledge");
@@ -157,43 +159,43 @@ Memory subcommands:
157
159
  memory mcp Show MCP server setup instructions`
158
160
  );
159
161
  memory.command("status").description("Show memory system status").action(async () => {
160
- const { memoryStatusCommand } = await import("./memory-Y6GNALG3.js");
162
+ const { memoryStatusCommand } = await import("./memory-TRDLADUM.js");
161
163
  await memoryStatusCommand();
162
164
  });
163
165
  memory.command("search").description("Search memories by query").argument("<query>", "search query").action(async (query) => {
164
- const { memorySearchCommand } = await import("./memory-Y6GNALG3.js");
166
+ const { memorySearchCommand } = await import("./memory-TRDLADUM.js");
165
167
  await memorySearchCommand(query);
166
168
  });
167
169
  memory.command("list").description(
168
170
  "List memories in current project, or all projects with --projects"
169
171
  ).option("--projects", "List all project databases with size and metadata").action(async (opts) => {
170
- const { memoryListCommand } = await import("./memory-Y6GNALG3.js");
172
+ const { memoryListCommand } = await import("./memory-TRDLADUM.js");
171
173
  await memoryListCommand(opts);
172
174
  });
173
175
  memory.command("init").description(
174
176
  "Initialize memory system \u2014 interactive wizard (first time) or config menu"
175
177
  ).action(async () => {
176
- const { memoryInitCommand } = await import("./memory-Y6GNALG3.js");
178
+ const { memoryInitCommand } = await import("./memory-TRDLADUM.js");
177
179
  await memoryInitCommand();
178
180
  });
179
181
  memory.command("config").description("Configure memory system settings").action(async () => {
180
- const { memoryConfigCommand } = await import("./memory-Y6GNALG3.js");
182
+ const { memoryConfigCommand } = await import("./memory-TRDLADUM.js");
181
183
  await memoryConfigCommand();
182
184
  });
183
185
  memory.command("start-daemon").description("Start the memory daemon (Tier 2 \u2014 MiniSearch)").action(async () => {
184
- const { memoryStartDaemonCommand } = await import("./memory-Y6GNALG3.js");
186
+ const { memoryStartDaemonCommand } = await import("./memory-TRDLADUM.js");
185
187
  await memoryStartDaemonCommand();
186
188
  });
187
189
  memory.command("stop-daemon").description("Stop the memory daemon").action(async () => {
188
- const { memoryStopDaemonCommand } = await import("./memory-Y6GNALG3.js");
190
+ const { memoryStopDaemonCommand } = await import("./memory-TRDLADUM.js");
189
191
  await memoryStopDaemonCommand();
190
192
  });
191
193
  memory.command("rebuild").description("Rebuild the daemon search index").action(async () => {
192
- const { memoryRebuildCommand } = await import("./memory-Y6GNALG3.js");
194
+ const { memoryRebuildCommand } = await import("./memory-TRDLADUM.js");
193
195
  await memoryRebuildCommand();
194
196
  });
195
197
  memory.command("mcp").description("Show MCP server setup instructions").action(async () => {
196
- const { memoryMcpCommand } = await import("./memory-Y6GNALG3.js");
198
+ const { memoryMcpCommand } = await import("./memory-TRDLADUM.js");
197
199
  await memoryMcpCommand();
198
200
  });
199
201
  memory.command("rm").description("Remove a project database").option("--project-id <id>", "Project ID to remove").option("--all", "Remove all project databases").option(
@@ -201,7 +203,7 @@ memory.command("rm").description("Remove a project database").option("--project-
201
203
  "Remove orphaned projects (source dir missing or 0 memories)"
202
204
  ).action(
203
205
  async (opts) => {
204
- const { memoryRmCommand } = await import("./memory-Y6GNALG3.js");
206
+ const { memoryRmCommand } = await import("./memory-TRDLADUM.js");
205
207
  await memoryRmCommand(opts);
206
208
  }
207
209
  );
@@ -15,15 +15,9 @@ import {
15
15
  ensureMemoryBuilt,
16
16
  isMemoryInitialized,
17
17
  memoryInitWizard
18
- } from "./chunk-AK6RMCAC.js";
19
- import "./chunk-56YJWGAN.js";
20
- import {
21
- memoryConfigMenu
22
- } from "./chunk-N4WZWRCI.js";
23
- import "./chunk-K4WSC62G.js";
24
- import {
25
- getLibPath
26
- } from "./chunk-RZRT7NGT.js";
18
+ } from "./chunk-W6D3J5DX.js";
19
+ import "./chunk-6S7352JG.js";
20
+ import "./chunk-PI4P34KF.js";
27
21
  import {
28
22
  findStatuslineHookPath,
29
23
  getCurrentAccountEmail,
@@ -42,6 +36,14 @@ import {
42
36
  ensureShellCompletion,
43
37
  hasShellCompletion
44
38
  } from "./chunk-667NMPN4.js";
39
+ import {
40
+ isMemoryMcpRegistered,
41
+ memoryConfigMenu,
42
+ registerMemoryMcp
43
+ } from "./chunk-DP6DFQ4G.js";
44
+ import {
45
+ getLibPath
46
+ } from "./chunk-RZRT7NGT.js";
45
47
  import {
46
48
  BACK,
47
49
  applyDocsDirChange,
@@ -1166,6 +1168,19 @@ async function initCommand() {
1166
1168
  );
1167
1169
  }
1168
1170
  }
1171
+ if (isMemoryMcpRegistered()) {
1172
+ log.dim("coding-friend-memory: already registered (user scope)");
1173
+ log.dim(
1174
+ " (If it points to an old path, run: claude mcp remove --scope user coding-friend-memory && cf mcp)"
1175
+ );
1176
+ } else {
1177
+ const registered = registerMemoryMcp();
1178
+ if (registered) {
1179
+ log.success(
1180
+ "Registered coding-friend-memory (user scope). Restart Claude Code to activate."
1181
+ );
1182
+ }
1183
+ }
1169
1184
  await stepShellCompletion();
1170
1185
  await stepStatusline();
1171
1186
  await stepMemory(docsDir);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getLatestVersion,
3
3
  semverCompare
4
- } from "./chunk-XHP3EBR3.js";
4
+ } from "./chunk-676YCW6T.js";
5
5
  import {
6
6
  getInstalledVersion
7
7
  } from "./chunk-XEKQW4RN.js";
@@ -9,6 +9,8 @@ import "./chunk-3WIZA5OZ.js";
9
9
  import {
10
10
  ensureShellCompletion
11
11
  } from "./chunk-667NMPN4.js";
12
+ import "./chunk-DP6DFQ4G.js";
13
+ import "./chunk-RZRT7NGT.js";
12
14
  import {
13
15
  enableMarketplaceAutoUpdate,
14
16
  isMarketplaceRegistered,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveLearnDir
3
- } from "./chunk-K4WSC62G.js";
3
+ } from "./chunk-PI4P34KF.js";
4
4
  import "./chunk-3WIZA5OZ.js";
5
5
  import {
6
6
  commandExists,
@@ -8,26 +8,26 @@ import {
8
8
  import {
9
9
  ensureMemoryBuilt,
10
10
  printMemoryMcpConfig
11
- } from "./chunk-AK6RMCAC.js";
11
+ } from "./chunk-W6D3J5DX.js";
12
12
  import {
13
13
  checkLearnMcpHealth,
14
14
  checkMemoryMcpHealth,
15
15
  detectMemoryMcpState,
16
16
  printHealthSection,
17
17
  warnStaleMcpJson
18
- } from "./chunk-56YJWGAN.js";
19
- import {
20
- getMemoryMcpStatus,
21
- writeMemoryMcpEntry
22
- } from "./chunk-N4WZWRCI.js";
18
+ } from "./chunk-6S7352JG.js";
23
19
  import {
24
20
  resolveLearnDir,
25
21
  resolveMemoryDir
26
- } from "./chunk-K4WSC62G.js";
22
+ } from "./chunk-PI4P34KF.js";
23
+ import "./chunk-3WIZA5OZ.js";
24
+ import {
25
+ isMemoryMcpRegistered,
26
+ registerMemoryMcp
27
+ } from "./chunk-DP6DFQ4G.js";
27
28
  import {
28
29
  getLibPath
29
30
  } from "./chunk-RZRT7NGT.js";
30
- import "./chunk-3WIZA5OZ.js";
31
31
  import "./chunk-IKLMHJH6.js";
32
32
  import {
33
33
  run
@@ -44,12 +44,11 @@ import {
44
44
  } from "./chunk-NREZK463.js";
45
45
 
46
46
  // src/commands/mcp.ts
47
- import { confirm } from "@inquirer/prompts";
48
47
  import { existsSync } from "fs";
49
48
  import { join } from "path";
50
49
  import chalk from "chalk";
51
50
  async function mcpCommand() {
52
- warnStaleMcpJson(resolveMemoryDir());
51
+ warnStaleMcpJson();
53
52
  const globalCfg = readJson(globalConfigPath());
54
53
  const learnDir = resolveLearnDir(globalCfg);
55
54
  const learnMcpDir = getLibPath("learn-mcp");
@@ -124,17 +123,17 @@ async function mcpCommand() {
124
123
  learnMcpDistPath
125
124
  });
126
125
  printHealthSection(learnHealth);
127
- const memoryMcpStatus = getMemoryMcpStatus();
128
- if (memoryMcpStatus.configured) {
129
- log.dim("coding-friend-memory: already in .mcp.json");
126
+ if (isMemoryMcpRegistered()) {
127
+ log.dim("coding-friend-memory: already registered (user scope)");
128
+ log.dim(
129
+ " (If it points to an old path, run: claude mcp remove --scope user coding-friend-memory && cf mcp)"
130
+ );
130
131
  } else {
131
- const addMemoryMcp = await confirm({
132
- message: "coding-friend-memory not found in this project's .mcp.json. Add it now? (project-scoped \u2014 writes to .mcp.json)",
133
- default: true
134
- });
135
- if (addMemoryMcp) {
136
- const memoryDir = resolveMemoryDir();
137
- writeMemoryMcpEntry(memoryDir);
132
+ const registered = registerMemoryMcp();
133
+ if (registered) {
134
+ log.success(
135
+ "Registered coding-friend-memory (user scope). Restart Claude Code to activate."
136
+ );
138
137
  }
139
138
  }
140
139
  console.log();
@@ -169,7 +168,8 @@ async function printMemoryMcp() {
169
168
  readMcpJson: () => readJson(localMcpPath),
170
169
  pathExists: existsSync,
171
170
  isDaemonRunning,
172
- memoryDistPath
171
+ memoryDistPath,
172
+ isRegistered: isMemoryMcpRegistered
173
173
  });
174
174
  printHealthSection(memoryHealth);
175
175
  }
@@ -1,6 +1,13 @@
1
+ import {
2
+ resolveProjectMemoryDir
3
+ } from "./chunk-PI4P34KF.js";
4
+ import "./chunk-3WIZA5OZ.js";
1
5
  import {
2
6
  getLibPath
3
7
  } from "./chunk-RZRT7NGT.js";
8
+ import "./chunk-EVGXUDX4.js";
9
+ import "./chunk-5UVDWG5L.js";
10
+ import "./chunk-X2H7JJMR.js";
4
11
  import {
5
12
  log
6
13
  } from "./chunk-NREZK463.js";
@@ -9,9 +16,11 @@ import {
9
16
  import { spawn } from "child_process";
10
17
  import { join } from "path";
11
18
  async function mcpServeCommand(memoryDir) {
19
+ const resolvedDir = memoryDir ?? resolveProjectMemoryDir(process.env.CLAUDE_PROJECT_DIR ?? process.cwd());
20
+ log.dim(`memory dir: ${resolvedDir}`);
12
21
  const mcpDir = getLibPath("cf-memory");
13
22
  const serverPath = join(mcpDir, "dist", "index.js");
14
- const child = spawn("node", [serverPath, memoryDir], {
23
+ const child = spawn("node", [serverPath, resolvedDir], {
15
24
  stdio: "inherit"
16
25
  });
17
26
  child.on("error", (err) => {
@@ -14,12 +14,12 @@ import {
14
14
  memoryStopDaemonCommand,
15
15
  printMemoryMcpConfig,
16
16
  refreshMemoryAfterUpdate
17
- } from "./chunk-AK6RMCAC.js";
18
- import "./chunk-56YJWGAN.js";
19
- import "./chunk-N4WZWRCI.js";
20
- import "./chunk-K4WSC62G.js";
21
- import "./chunk-RZRT7NGT.js";
17
+ } from "./chunk-W6D3J5DX.js";
18
+ import "./chunk-6S7352JG.js";
19
+ import "./chunk-PI4P34KF.js";
22
20
  import "./chunk-3WIZA5OZ.js";
21
+ import "./chunk-DP6DFQ4G.js";
22
+ import "./chunk-RZRT7NGT.js";
23
23
  import "./chunk-IKLMHJH6.js";
24
24
  import "./chunk-EVGXUDX4.js";
25
25
  import "./chunk-5UVDWG5L.js";
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-K4WSC62G.js";
3
+ } from "./chunk-PI4P34KF.js";
4
4
  import "./chunk-3WIZA5OZ.js";
5
+ import "./chunk-EVGXUDX4.js";
5
6
  import {
6
7
  readJson,
7
8
  writeJson
@@ -10,27 +10,29 @@ import {
10
10
  import {
11
11
  checkLearnMcpHealth,
12
12
  checkMemoryMcpHealth
13
- } from "./chunk-56YJWGAN.js";
14
- import "./chunk-N4WZWRCI.js";
13
+ } from "./chunk-6S7352JG.js";
15
14
  import {
16
15
  resolveLearnDir,
17
16
  resolveMemoryDir,
18
17
  sanitizeRawConfig
19
- } from "./chunk-K4WSC62G.js";
20
- import {
21
- getLibPath
22
- } from "./chunk-RZRT7NGT.js";
18
+ } from "./chunk-PI4P34KF.js";
23
19
  import {
24
20
  getCliVersion,
25
21
  getLatestCliVersion,
26
22
  getLatestVersion,
27
23
  semverCompare
28
- } from "./chunk-XHP3EBR3.js";
24
+ } from "./chunk-676YCW6T.js";
29
25
  import {
30
26
  getInstalledVersion
31
27
  } from "./chunk-XEKQW4RN.js";
32
28
  import "./chunk-3WIZA5OZ.js";
33
29
  import "./chunk-667NMPN4.js";
30
+ import {
31
+ isMemoryMcpRegistered
32
+ } from "./chunk-DP6DFQ4G.js";
33
+ import {
34
+ getLibPath
35
+ } from "./chunk-RZRT7NGT.js";
34
36
  import {
35
37
  detectPluginScope,
36
38
  isPluginDisabled
@@ -250,7 +252,8 @@ async function statusCommand() {
250
252
  readMcpJson: () => readJson(localMcpPath),
251
253
  pathExists: existsSync,
252
254
  isDaemonRunning: memIsDaemonRunning,
253
- memoryDistPath
255
+ memoryDistPath,
256
+ isRegistered: isMemoryMcpRegistered
254
257
  });
255
258
  let memHasIssues = false;
256
259
  for (const check of memHealth.checks) {
@@ -2,6 +2,10 @@ import {
2
2
  hasShellCompletion,
3
3
  removeShellCompletion
4
4
  } from "./chunk-667NMPN4.js";
5
+ import {
6
+ removeMemoryMcpEntry
7
+ } from "./chunk-DP6DFQ4G.js";
8
+ import "./chunk-RZRT7NGT.js";
5
9
  import {
6
10
  isMarketplaceRegistered,
7
11
  isPluginInstalled
@@ -144,6 +148,16 @@ async function uninstallCommand(opts = {}) {
144
148
  );
145
149
  if (scope === "project" || scope === "local") {
146
150
  await uninstallScoped(scope);
151
+ if (scope === "project") {
152
+ const migrationResult = removeMemoryMcpEntry();
153
+ if (migrationResult.removed) {
154
+ if (migrationResult.fileDeleted) {
155
+ log.success("Removed legacy project-scope coding-friend-memory from .mcp.json (file deleted \u2014 was empty).");
156
+ } else {
157
+ log.success("Removed legacy project-scope coding-friend-memory from .mcp.json");
158
+ }
159
+ }
160
+ }
147
161
  return;
148
162
  }
149
163
  const detection = detect();
@@ -4,10 +4,12 @@ import {
4
4
  getLatestVersion,
5
5
  semverCompare,
6
6
  updateCommand
7
- } from "./chunk-XHP3EBR3.js";
7
+ } from "./chunk-676YCW6T.js";
8
8
  import "./chunk-XEKQW4RN.js";
9
9
  import "./chunk-3WIZA5OZ.js";
10
10
  import "./chunk-667NMPN4.js";
11
+ import "./chunk-DP6DFQ4G.js";
12
+ import "./chunk-RZRT7NGT.js";
11
13
  import "./chunk-IKLMHJH6.js";
12
14
  import "./chunk-EVGXUDX4.js";
13
15
  import "./chunk-5UVDWG5L.js";