coding-friend-cli 1.36.3 → 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.
Files changed (28) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-57EGAXYI.js → chunk-3WIZA5OZ.js} +4 -0
  3. package/dist/{chunk-EAJJVXAE.js → chunk-676YCW6T.js} +18 -2
  4. package/dist/{chunk-MAGBNYZK.js → chunk-6S7352JG.js} +60 -47
  5. package/dist/{chunk-VV2U7NDN.js → chunk-DP6DFQ4G.js} +83 -35
  6. package/dist/{chunk-CDTQL4FI.js → chunk-PI4P34KF.js} +41 -2
  7. package/dist/{chunk-TPGAW67X.js → chunk-W6D3J5DX.js} +39 -27
  8. package/dist/{chunk-7SMP5CZ4.js → chunk-XEKQW4RN.js} +1 -1
  9. package/dist/{clean-MXIMMXDH.js → clean-WEYQZB34.js} +3 -2
  10. package/dist/{config-B2P7TXL4.js → config-ZMR2AOBB.js} +10 -10
  11. package/dist/{dev-GKD52XE6.js → dev-IGHMMEP4.js} +2 -2
  12. package/dist/{host-PEKK7OOC.js → host-SSRI4JZV.js} +2 -2
  13. package/dist/index.js +34 -32
  14. package/dist/{init-M5JJP5YO.js → init-6MFQWPOP.js} +30 -15
  15. package/dist/{install-VFMO45SP.js → install-37NN4CQH.js} +5 -3
  16. package/dist/{learn-QQ7XEHDY.js → learn-OPH3CI67.js} +2 -2
  17. package/dist/{mcp-372LGOZJ.js → mcp-DWKVMNC7.js} +21 -21
  18. package/dist/{mcp-serve-3FEPFVVQ.js → mcp-serve-5GODJ4DJ.js} +10 -1
  19. package/dist/{memory-XINRMEWB.js → memory-TRDLADUM.js} +5 -5
  20. package/dist/{session-2R7WWNML.js → session-S4WKA4P5.js} +3 -2
  21. package/dist/{status-Z4V7IYOB.js → status-YZEOUX46.js} +13 -10
  22. package/dist/{statusline-WDTN3OI4.js → statusline-KKFJPTI7.js} +2 -2
  23. package/dist/{uninstall-ASLHT3MH.js → uninstall-AVA3J554.js} +14 -0
  24. package/dist/{update-MY2DRJLV.js → update-Q3ACCK4Z.js} +5 -3
  25. package/lib/cf-memory/src/__tests__/sqlite-lazy-db.test.ts +213 -0
  26. package/lib/cf-memory/src/__tests__/tier.test.ts +22 -1
  27. package/lib/cf-memory/src/backends/sqlite/index.ts +142 -85
  28. package/package.json +1 -1
@@ -9,13 +9,9 @@ import {
9
9
  registerLearnMcp,
10
10
  unregisterLearnMcp
11
11
  } from "./chunk-YIXAQ4R2.js";
12
- import {
13
- memoryConfigMenu
14
- } from "./chunk-VV2U7NDN.js";
15
12
  import {
16
13
  resolveLearnDir
17
- } from "./chunk-CDTQL4FI.js";
18
- import "./chunk-RZRT7NGT.js";
14
+ } from "./chunk-PI4P34KF.js";
19
15
  import {
20
16
  findStatuslineHookPath,
21
17
  getCurrentAccountEmail,
@@ -26,16 +22,20 @@ import {
26
22
  saveStatuslineConfig,
27
23
  selectStatuslineComponents,
28
24
  writeStatuslineSettings
29
- } from "./chunk-7SMP5CZ4.js";
25
+ } from "./chunk-XEKQW4RN.js";
30
26
  import {
31
27
  ALL_COMPONENT_IDS,
32
28
  DEFAULT_CONFIG
33
- } from "./chunk-57EGAXYI.js";
29
+ } from "./chunk-3WIZA5OZ.js";
34
30
  import {
35
31
  ensureShellCompletion,
36
32
  hasShellCompletion,
37
33
  removeShellCompletion
38
34
  } from "./chunk-667NMPN4.js";
35
+ import {
36
+ memoryConfigMenu
37
+ } from "./chunk-DP6DFQ4G.js";
38
+ import "./chunk-RZRT7NGT.js";
39
39
  import {
40
40
  BACK,
41
41
  applyDocsDirChange,
@@ -440,8 +440,8 @@ async function editDisableGUIPlan(globalCfg, localCfg) {
440
440
  log.dim(`Current: ${currentValue}`);
441
441
  }
442
442
  const value = await confirm({
443
- message: "Disable the human overview doc that /cf-plan generates alongside the agent plan?",
444
- default: currentValue ?? false
443
+ message: "Disable the human overview doc that /cf-plan generates alongside the agent plan? (off by default)",
444
+ default: currentValue ?? true
445
445
  });
446
446
  const scope = await askScope();
447
447
  if (scope === "back") return;
@@ -491,7 +491,7 @@ async function planDocsSubMenu() {
491
491
  choices: injectBackChoice(
492
492
  [
493
493
  {
494
- name: `Disable overview doc (${disableVal ?? false})`,
494
+ name: `Disable overview doc (${disableVal ?? true})`,
495
495
  value: "disableGUIPlan"
496
496
  },
497
497
  {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ensureStatusline
3
- } from "./chunk-7SMP5CZ4.js";
4
- import "./chunk-57EGAXYI.js";
3
+ } from "./chunk-XEKQW4RN.js";
4
+ import "./chunk-3WIZA5OZ.js";
5
5
  import {
6
6
  ensureShellCompletion
7
7
  } from "./chunk-667NMPN4.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  resolveLearnDir
3
- } from "./chunk-CDTQL4FI.js";
3
+ } from "./chunk-PI4P34KF.js";
4
+ import "./chunk-3WIZA5OZ.js";
4
5
  import {
5
6
  getLibPath
6
7
  } from "./chunk-RZRT7NGT.js";
7
- import "./chunk-57EGAXYI.js";
8
8
  import {
9
9
  run,
10
10
  streamExec
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-VFMO45SP.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-M5JJP5YO.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-B2P7TXL4.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-PEKK7OOC.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-QQ7XEHDY.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-PEKK7OOC.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-372LGOZJ.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) => {
@@ -106,19 +108,19 @@ program.command("permission").description("Manage Claude Code permission rules f
106
108
  await permissionCommand(opts);
107
109
  });
108
110
  program.command("statusline").description("Setup coding-friend statusline in Claude Code").action(async () => {
109
- const { statuslineCommand } = await import("./statusline-WDTN3OI4.js");
111
+ const { statuslineCommand } = await import("./statusline-KKFJPTI7.js");
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-MY2DRJLV.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-Z4V7IYOB.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-MXIMMXDH.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-2R7WWNML.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-2R7WWNML.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.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-XINRMEWB.js");
206
+ const { memoryRmCommand } = await import("./memory-TRDLADUM.js");
205
207
  await memoryRmCommand(opts);
206
208
  }
207
209
  );
@@ -227,28 +229,28 @@ Dev subcommands:
227
229
  dev update [path] Update local dev plugin to latest version`
228
230
  );
229
231
  dev.command("on").description("Switch to local plugin source").argument("[path]", "path to local coding-friend repo (default: cwd)").action(async (path) => {
230
- const { devOnCommand } = await import("./dev-GKD52XE6.js");
232
+ const { devOnCommand } = await import("./dev-IGHMMEP4.js");
231
233
  await devOnCommand(path);
232
234
  });
233
235
  dev.command("off").description("Switch back to remote marketplace").action(async () => {
234
- const { devOffCommand } = await import("./dev-GKD52XE6.js");
236
+ const { devOffCommand } = await import("./dev-IGHMMEP4.js");
235
237
  await devOffCommand();
236
238
  });
237
239
  dev.command("status").description("Show current dev mode").action(async () => {
238
- const { devStatusCommand } = await import("./dev-GKD52XE6.js");
240
+ const { devStatusCommand } = await import("./dev-IGHMMEP4.js");
239
241
  await devStatusCommand();
240
242
  });
241
243
  dev.command("sync").description(
242
244
  "Copy local source files to plugin cache (no version bump needed)"
243
245
  ).action(async () => {
244
- const { devSyncCommand } = await import("./dev-GKD52XE6.js");
246
+ const { devSyncCommand } = await import("./dev-IGHMMEP4.js");
245
247
  await devSyncCommand();
246
248
  });
247
249
  dev.command("restart").description("Reinstall local dev plugin (off + on)").argument(
248
250
  "[path]",
249
251
  "path to local coding-friend repo (default: saved path or cwd)"
250
252
  ).action(async (path) => {
251
- const { devRestartCommand } = await import("./dev-GKD52XE6.js");
253
+ const { devRestartCommand } = await import("./dev-IGHMMEP4.js");
252
254
  await devRestartCommand(path);
253
255
  });
254
256
  dev.command("update").description(
@@ -257,7 +259,7 @@ dev.command("update").description(
257
259
  "[path]",
258
260
  "path to local coding-friend repo (default: saved path or cwd)"
259
261
  ).action(async (path) => {
260
- const { devUpdateCommand } = await import("./dev-GKD52XE6.js");
262
+ const { devUpdateCommand } = await import("./dev-IGHMMEP4.js");
261
263
  await devUpdateCommand(path);
262
264
  });
263
265
  program.hook("postAction", async () => {
@@ -15,15 +15,9 @@ import {
15
15
  ensureMemoryBuilt,
16
16
  isMemoryInitialized,
17
17
  memoryInitWizard
18
- } from "./chunk-TPGAW67X.js";
19
- import "./chunk-MAGBNYZK.js";
20
- import {
21
- memoryConfigMenu
22
- } from "./chunk-VV2U7NDN.js";
23
- import "./chunk-CDTQL4FI.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,
@@ -34,14 +28,22 @@ import {
34
28
  saveStatuslineConfig,
35
29
  selectStatuslineComponents,
36
30
  writeStatuslineSettings
37
- } from "./chunk-7SMP5CZ4.js";
31
+ } from "./chunk-XEKQW4RN.js";
38
32
  import {
39
33
  DEFAULT_CONFIG
40
- } from "./chunk-57EGAXYI.js";
34
+ } from "./chunk-3WIZA5OZ.js";
41
35
  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,
@@ -726,8 +728,8 @@ async function stepPlanDocs(globalCfg, localCfg) {
726
728
  "The human overview doc /cf-plan writes next to the agent plan \u2014 enable/disable and choose format."
727
729
  );
728
730
  const disableChoice = await confirm({
729
- message: "Disable the /cf-plan human overview doc?",
730
- default: currentDisable ?? false
731
+ message: "Disable the /cf-plan human overview doc? (off by default)",
732
+ default: currentDisable ?? true
731
733
  });
732
734
  let formatChoice;
733
735
  if (!disableChoice) {
@@ -1002,8 +1004,8 @@ async function initMenu(gitAvailable) {
1002
1004
  }
1003
1005
  case "planDocs": {
1004
1006
  const planDocsDisableChoice = await confirm({
1005
- message: "Disable the /cf-plan human overview doc?",
1006
- default: planDocsDisableVal ?? false
1007
+ message: "Disable the /cf-plan human overview doc? (off by default)",
1008
+ default: planDocsDisableVal ?? true
1007
1009
  });
1008
1010
  let planDocsFormatChoice;
1009
1011
  if (!planDocsDisableChoice) {
@@ -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,14 +1,16 @@
1
1
  import {
2
2
  getLatestVersion,
3
3
  semverCompare
4
- } from "./chunk-EAJJVXAE.js";
4
+ } from "./chunk-676YCW6T.js";
5
5
  import {
6
6
  getInstalledVersion
7
- } from "./chunk-7SMP5CZ4.js";
8
- import "./chunk-57EGAXYI.js";
7
+ } from "./chunk-XEKQW4RN.js";
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,7 +1,7 @@
1
1
  import {
2
2
  resolveLearnDir
3
- } from "./chunk-CDTQL4FI.js";
4
- import "./chunk-57EGAXYI.js";
3
+ } from "./chunk-PI4P34KF.js";
4
+ import "./chunk-3WIZA5OZ.js";
5
5
  import {
6
6
  commandExists,
7
7
  run,
@@ -8,26 +8,26 @@ import {
8
8
  import {
9
9
  ensureMemoryBuilt,
10
10
  printMemoryMcpConfig
11
- } from "./chunk-TPGAW67X.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-MAGBNYZK.js";
19
- import {
20
- getMemoryMcpStatus,
21
- writeMemoryMcpEntry
22
- } from "./chunk-VV2U7NDN.js";
18
+ } from "./chunk-6S7352JG.js";
23
19
  import {
24
20
  resolveLearnDir,
25
21
  resolveMemoryDir
26
- } from "./chunk-CDTQL4FI.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-57EGAXYI.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-TPGAW67X.js";
18
- import "./chunk-MAGBNYZK.js";
19
- import "./chunk-VV2U7NDN.js";
20
- import "./chunk-CDTQL4FI.js";
17
+ } from "./chunk-W6D3J5DX.js";
18
+ import "./chunk-6S7352JG.js";
19
+ import "./chunk-PI4P34KF.js";
20
+ import "./chunk-3WIZA5OZ.js";
21
+ import "./chunk-DP6DFQ4G.js";
21
22
  import "./chunk-RZRT7NGT.js";
22
- import "./chunk-57EGAXYI.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-CDTQL4FI.js";
4
- import "./chunk-57EGAXYI.js";
3
+ } from "./chunk-PI4P34KF.js";
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-MAGBNYZK.js";
14
- import "./chunk-VV2U7NDN.js";
13
+ } from "./chunk-6S7352JG.js";
15
14
  import {
16
15
  resolveLearnDir,
17
16
  resolveMemoryDir,
18
17
  sanitizeRawConfig
19
- } from "./chunk-CDTQL4FI.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-EAJJVXAE.js";
24
+ } from "./chunk-676YCW6T.js";
29
25
  import {
30
26
  getInstalledVersion
31
- } from "./chunk-7SMP5CZ4.js";
32
- import "./chunk-57EGAXYI.js";
27
+ } from "./chunk-XEKQW4RN.js";
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) {
@@ -8,10 +8,10 @@ import {
8
8
  saveStatuslineConfig,
9
9
  selectStatuslineComponents,
10
10
  writeStatuslineSettings
11
- } from "./chunk-7SMP5CZ4.js";
11
+ } from "./chunk-XEKQW4RN.js";
12
12
  import {
13
13
  ALL_COMPONENT_IDS
14
- } from "./chunk-57EGAXYI.js";
14
+ } from "./chunk-3WIZA5OZ.js";
15
15
  import {
16
16
  commandExists
17
17
  } from "./chunk-EVGXUDX4.js";
@@ -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-EAJJVXAE.js";
8
- import "./chunk-7SMP5CZ4.js";
9
- import "./chunk-57EGAXYI.js";
7
+ } from "./chunk-676YCW6T.js";
8
+ import "./chunk-XEKQW4RN.js";
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";