coding-friend-cli 1.26.1 → 1.27.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 (36) hide show
  1. package/dist/{chunk-K2PSF7SF.js → chunk-BX3DRKTU.js} +7 -7
  2. package/dist/{chunk-HEBLANJO.js → chunk-JVYZ72EP.js} +81 -13
  3. package/dist/{chunk-LGQBVN2C.js → chunk-TOM2FI3W.js} +6 -6
  4. package/dist/{chunk-OARRVZL4.js → chunk-YCWRBOB3.js} +5 -5
  5. package/dist/{config-MSVSD3HA.js → config-N55LTJ76.js} +33 -20
  6. package/dist/{dev-KTEINOFU.js → dev-BSXR55PZ.js} +7 -7
  7. package/dist/{disable-7BVJGSIP.js → disable-CDOM7SSI.js} +3 -3
  8. package/dist/{enable-RO2FBKS6.js → enable-SF7742UR.js} +3 -3
  9. package/dist/{host-USZC44PR.js → host-JVLWYY5A.js} +2 -2
  10. package/dist/index.js +30 -30
  11. package/dist/{init-EJXHIZCQ.js → init-QP57Q2C6.js} +43 -30
  12. package/dist/{install-65JCZGCB.js → install-G4XYNVL3.js} +6 -6
  13. package/dist/{mcp-4FRVCJBX.js → mcp-24NCFFAF.js} +5 -5
  14. package/dist/{memory-ER5F37WW.js → memory-HLMKDGWY.js} +5 -5
  15. package/dist/{permission-36BMHDYX.js → permission-K54DWLHN.js} +77 -10
  16. package/dist/permissions-O24R7WUU.js +37 -0
  17. package/dist/{session-CZ4ZJP7Q.js → session-DMQZXZ7F.js} +5 -5
  18. package/dist/{status-IJH4EZBG.js → status-K7TBUAXT.js} +16 -16
  19. package/dist/{statusline-PUPTHPBR.js → statusline-CDGADB3C.js} +2 -2
  20. package/dist/{uninstall-5MINSH35.js → uninstall-BOVKPNYN.js} +6 -6
  21. package/dist/{update-IO27DSZW.js → update-6M3YFHS6.js} +5 -5
  22. package/lib/cf-memory/README.md +2 -0
  23. package/lib/cf-memory/src/__tests__/claude-md.test.ts +238 -0
  24. package/lib/cf-memory/src/__tests__/status-frame.test.ts +136 -0
  25. package/lib/cf-memory/src/index.ts +9 -1
  26. package/lib/cf-memory/src/lib/claude-md.ts +217 -0
  27. package/lib/cf-memory/src/lib/status-frame.ts +63 -0
  28. package/lib/cf-memory/src/server.ts +9 -3
  29. package/lib/cf-memory/src/tools/delete.ts +12 -0
  30. package/lib/cf-memory/src/tools/store.ts +46 -10
  31. package/lib/cf-memory/src/tools/update.ts +54 -11
  32. package/package.json +1 -1
  33. package/dist/{chunk-KFNKH5Z7.js → chunk-2HQVNQB7.js} +3 -3
  34. package/dist/{chunk-3HTLOI34.js → chunk-GDZTU2Z4.js} +5 -5
  35. package/dist/{chunk-N2Q224HO.js → chunk-HPNRQYLM.js} +3 -3
  36. package/dist/{chunk-2TFHVNBI.js → chunk-R6HDMRYL.js} +4 -4
@@ -1,10 +1,13 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { z } from "zod";
3
3
  import type { MemoryBackend } from "../lib/backend.js";
4
+ import { removeFromClaudeMd } from "../lib/claude-md.js";
5
+ import type { ToolRegistrationContext } from "../server.js";
4
6
 
5
7
  export function registerDelete(
6
8
  server: McpServer,
7
9
  backend: MemoryBackend,
10
+ ctx?: ToolRegistrationContext,
8
11
  ): void {
9
12
  server.tool(
10
13
  "memory_delete",
@@ -25,6 +28,15 @@ export function registerDelete(
25
28
  isError: true,
26
29
  };
27
30
  }
31
+ // Remove from CLAUDE.md if it was a conventions entry
32
+ if (id.startsWith("conventions/") && ctx?.docsDir) {
33
+ try {
34
+ removeFromClaudeMd(ctx.docsDir, id);
35
+ } catch {
36
+ // Best-effort
37
+ }
38
+ }
39
+
28
40
  return {
29
41
  content: [
30
42
  {
@@ -1,10 +1,18 @@
1
+ import path from "node:path";
1
2
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
3
  import { z } from "zod";
3
4
  import type { MemoryBackend } from "../lib/backend.js";
4
5
  import { MEMORY_TYPES } from "../lib/types.js";
5
6
  import { checkDuplicate } from "../lib/dedup.js";
7
+ import { buildStoreStatus } from "../lib/status-frame.js";
8
+ import { syncToClaudeMd } from "../lib/claude-md.js";
9
+ import type { ToolRegistrationContext } from "../server.js";
6
10
 
7
- export function registerStore(server: McpServer, backend: MemoryBackend): void {
11
+ export function registerStore(
12
+ server: McpServer,
13
+ backend: MemoryBackend,
14
+ ctx?: ToolRegistrationContext,
15
+ ): void {
8
16
  server.tool(
9
17
  "memory_store",
10
18
  "Store a new memory. Provide title, description, type, tags, and content.",
@@ -65,24 +73,52 @@ export function registerStore(server: McpServer, backend: MemoryBackend): void {
65
73
 
66
74
  const memory = await backend.store(input);
67
75
 
76
+ // Sync convention memories to CLAUDE.md
77
+ let claudeMdUpdated = false;
78
+ if (memory.category === "conventions" && ctx?.docsDir && !index_only) {
79
+ try {
80
+ syncToClaudeMd(ctx.docsDir, memory.id, description);
81
+ claudeMdUpdated = true;
82
+ } catch {
83
+ // Best-effort — don't block store on CLAUDE.md sync errors
84
+ }
85
+ }
86
+
68
87
  const response: Record<string, unknown> = {
69
88
  id: memory.id,
70
89
  title: memory.frontmatter.title,
71
90
  stored: true,
72
91
  };
73
92
 
93
+ let warning: string | undefined;
74
94
  if (dedup?.isDuplicate) {
75
- response.warning = `Near-duplicate found: ${dedup.similarId} (similarity: ${dedup.similarity.toFixed(2)}). Memory stored anyway.`;
95
+ warning = `Near-duplicate found: ${dedup.similarId} (similarity: ${dedup.similarity.toFixed(2)}). Memory stored anyway.`;
96
+ response.warning = warning;
76
97
  }
77
98
 
78
- return {
79
- content: [
80
- {
81
- type: "text" as const,
82
- text: JSON.stringify(response, null, 2),
83
- },
84
- ],
85
- };
99
+ const parts: Array<{ type: "text"; text: string }> = [
100
+ {
101
+ type: "text" as const,
102
+ text: JSON.stringify(response, null, 2),
103
+ },
104
+ ];
105
+
106
+ if (ctx?.docsDir) {
107
+ const markdownPath = path.join(ctx.docsDir, `${memory.id}.md`);
108
+ parts.push({
109
+ type: "text" as const,
110
+ text: buildStoreStatus({
111
+ id: memory.id,
112
+ title: memory.frontmatter.title,
113
+ markdownPath,
114
+ dbPath: ctx.dbPath ?? null,
115
+ claudeMdUpdated,
116
+ warning,
117
+ }),
118
+ });
119
+ }
120
+
121
+ return { content: parts };
86
122
  },
87
123
  );
88
124
  }
@@ -1,10 +1,15 @@
1
+ import path from "node:path";
1
2
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
3
  import { z } from "zod";
3
4
  import type { MemoryBackend } from "../lib/backend.js";
5
+ import { buildUpdateStatus } from "../lib/status-frame.js";
6
+ import { updateInClaudeMd, syncToClaudeMd } from "../lib/claude-md.js";
7
+ import type { ToolRegistrationContext } from "../server.js";
4
8
 
5
9
  export function registerUpdate(
6
10
  server: McpServer,
7
11
  backend: MemoryBackend,
12
+ ctx?: ToolRegistrationContext,
8
13
  ): void {
9
14
  server.tool(
10
15
  "memory_update",
@@ -45,18 +50,56 @@ export function registerUpdate(
45
50
  isError: true,
46
51
  };
47
52
  }
48
- return {
49
- content: [
50
- {
51
- type: "text" as const,
52
- text: JSON.stringify(
53
- { id: memory.id, title: memory.frontmatter.title, updated: true },
54
- null,
55
- 2,
56
- ),
57
- },
58
- ],
53
+
54
+ // Sync convention memories to CLAUDE.md
55
+ let claudeMdUpdated = false;
56
+ if (memory.category === "conventions" && ctx?.docsDir) {
57
+ try {
58
+ if (description) {
59
+ // Description changed — update the CLAUDE.md entry
60
+ updateInClaudeMd(ctx.docsDir, memory.id, description);
61
+ } else {
62
+ // Ensure entry exists (e.g. if memory was created before this feature)
63
+ syncToClaudeMd(
64
+ ctx.docsDir,
65
+ memory.id,
66
+ memory.frontmatter.description,
67
+ );
68
+ }
69
+ claudeMdUpdated = true;
70
+ } catch {
71
+ // Best-effort
72
+ }
73
+ }
74
+
75
+ const response = {
76
+ id: memory.id,
77
+ title: memory.frontmatter.title,
78
+ updated: true,
59
79
  };
80
+
81
+ const parts: Array<{ type: "text"; text: string }> = [
82
+ {
83
+ type: "text" as const,
84
+ text: JSON.stringify(response, null, 2),
85
+ },
86
+ ];
87
+
88
+ if (ctx?.docsDir) {
89
+ const markdownPath = path.join(ctx.docsDir, `${memory.id}.md`);
90
+ parts.push({
91
+ type: "text" as const,
92
+ text: buildUpdateStatus({
93
+ id: memory.id,
94
+ title: memory.frontmatter.title,
95
+ markdownPath,
96
+ dbPath: ctx.dbPath ?? null,
97
+ claudeMdUpdated,
98
+ }),
99
+ });
100
+ }
101
+
102
+ return { content: parts };
60
103
  },
61
104
  );
62
105
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coding-friend-cli",
3
- "version": "1.26.1",
3
+ "version": "1.27.0",
4
4
  "description": "CLI for coding-friend — host learning docs, setup MCP server, initialize projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  DEFAULT_CONFIG
3
3
  } from "./chunk-PRIH34UB.js";
4
- import {
5
- readJson
6
- } from "./chunk-5UVDWG5L.js";
7
4
  import {
8
5
  globalConfigPath,
9
6
  localConfigPath,
10
7
  resolvePath
11
8
  } from "./chunk-TWKNGPBO.js";
9
+ import {
10
+ readJson
11
+ } from "./chunk-5UVDWG5L.js";
12
12
 
13
13
  // src/lib/config.ts
14
14
  function deepMerge(base, override) {
@@ -2,17 +2,17 @@ import {
2
2
  ALL_COMPONENT_IDS,
3
3
  STATUSLINE_COMPONENTS
4
4
  } from "./chunk-PRIH34UB.js";
5
- import {
6
- mergeJson,
7
- readJson,
8
- writeJson
9
- } from "./chunk-5UVDWG5L.js";
10
5
  import {
11
6
  claudeSettingsPath,
12
7
  globalConfigPath,
13
8
  installedPluginsPath,
14
9
  pluginCachePath
15
10
  } from "./chunk-TWKNGPBO.js";
11
+ import {
12
+ mergeJson,
13
+ readJson,
14
+ writeJson
15
+ } from "./chunk-5UVDWG5L.js";
16
16
 
17
17
  // src/lib/statusline.ts
18
18
  import { existsSync, readdirSync } from "fs";
@@ -1,9 +1,6 @@
1
1
  import {
2
2
  run
3
3
  } from "./chunk-EVGXUDX4.js";
4
- import {
5
- readJson
6
- } from "./chunk-5UVDWG5L.js";
7
4
  import {
8
5
  globalConfigPath,
9
6
  localConfigPath
@@ -11,6 +8,9 @@ import {
11
8
  import {
12
9
  log
13
10
  } from "./chunk-NREZK463.js";
11
+ import {
12
+ readJson
13
+ } from "./chunk-5UVDWG5L.js";
14
14
 
15
15
  // src/lib/prompt-utils.ts
16
16
  import { select, Separator } from "@inquirer/prompts";
@@ -1,7 +1,3 @@
1
- import {
2
- readJson,
3
- writeJson
4
- } from "./chunk-5UVDWG5L.js";
5
1
  import {
6
2
  claudeLocalSettingsPath,
7
3
  claudeProjectSettingsPath,
@@ -9,6 +5,10 @@ import {
9
5
  installedPluginsPath,
10
6
  knownMarketplacesPath
11
7
  } from "./chunk-TWKNGPBO.js";
8
+ import {
9
+ readJson,
10
+ writeJson
11
+ } from "./chunk-5UVDWG5L.js";
12
12
 
13
13
  // src/lib/plugin-state.ts
14
14
  var MARKETPLACE_NAME = "coding-friend-marketplace";