@danielmarbach/mnemonic-mcp 0.23.0 → 0.24.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.
@@ -0,0 +1,4 @@
1
+ import type { Root } from "mdast";
2
+ export declare function parseBody(content: string): Root;
3
+ export declare function serializeBody(tree: Root): string;
4
+ //# sourceMappingURL=markdown-ast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-ast.d.ts","sourceRoot":"","sources":["../src/markdown-ast.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAElC,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEhD"}
@@ -0,0 +1,10 @@
1
+ import { unified } from "unified";
2
+ import remarkParse from "remark-parse";
3
+ import remarkStringify from "remark-stringify";
4
+ export function parseBody(content) {
5
+ return unified().use(remarkParse).parse(content);
6
+ }
7
+ export function serializeBody(tree) {
8
+ return unified().use(remarkStringify, { bullet: "-" }).stringify(tree);
9
+ }
10
+ //# sourceMappingURL=markdown-ast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-ast.js","sourceRoot":"","sources":["../src/markdown-ast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,WAAW,MAAM,cAAc,CAAC;AACvC,OAAO,eAAe,MAAM,kBAAkB,CAAC;AAG/C,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,OAAO,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,OAAO,CAAS,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,OAAO,OAAO,EAAE,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAW,CAAC;AACnF,CAAC"}
@@ -0,0 +1,36 @@
1
+ export type SemanticSelector = {
2
+ heading: string;
3
+ } | {
4
+ headingStartsWith: string;
5
+ } | {
6
+ nthChild: number;
7
+ } | {
8
+ lastChild: true;
9
+ };
10
+ export type SemanticOperation = {
11
+ op: "appendChild";
12
+ value: string;
13
+ } | {
14
+ op: "prependChild";
15
+ value: string;
16
+ } | {
17
+ op: "replace";
18
+ value: string;
19
+ } | {
20
+ op: "replaceChildren";
21
+ value: string;
22
+ } | {
23
+ op: "insertAfter";
24
+ value: string;
25
+ } | {
26
+ op: "insertBefore";
27
+ value: string;
28
+ } | {
29
+ op: "remove";
30
+ };
31
+ export interface SemanticPatch {
32
+ selector: SemanticSelector;
33
+ operation: SemanticOperation;
34
+ }
35
+ export declare function applySemanticPatches(body: string, patches: SemanticPatch[]): Promise<string>;
36
+ //# sourceMappingURL=semantic-patch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-patch.d.ts","sourceRoot":"","sources":["../src/semantic-patch.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,gBAAgB,GACxB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,iBAAiB,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpB;IAAE,SAAS,EAAE,IAAI,CAAA;CAAE,CAAC;AAExB,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,EAAE,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,EAAE,EAAE,QAAQ,CAAA;CAAE,CAAC;AAErB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,EAAE,iBAAiB,CAAC;CAC9B;AA6ED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ElG"}
@@ -0,0 +1,141 @@
1
+ import { parseBody, serializeBody } from "./markdown-ast.js";
2
+ import { cleanMarkdown } from "./markdown.js";
3
+ function getHeadingText(node) {
4
+ return node.children
5
+ .filter((c) => c.type === "text")
6
+ .map((c) => c.value)
7
+ .join("");
8
+ }
9
+ function isHeadingNode(node) {
10
+ return node.type === "heading";
11
+ }
12
+ function resolveSelector(tree, selector) {
13
+ if ("heading" in selector) {
14
+ for (let i = 0; i < tree.children.length; i++) {
15
+ const child = tree.children[i];
16
+ if (isHeadingNode(child) && getHeadingText(child) === selector.heading) {
17
+ return { parent: tree, index: i, target: child };
18
+ }
19
+ }
20
+ return undefined;
21
+ }
22
+ if ("headingStartsWith" in selector) {
23
+ for (let i = 0; i < tree.children.length; i++) {
24
+ const child = tree.children[i];
25
+ if (isHeadingNode(child) && getHeadingText(child).startsWith(selector.headingStartsWith)) {
26
+ return { parent: tree, index: i, target: child };
27
+ }
28
+ }
29
+ return undefined;
30
+ }
31
+ if ("nthChild" in selector) {
32
+ const index = selector.nthChild;
33
+ if (index < 0 || index >= tree.children.length) {
34
+ return undefined;
35
+ }
36
+ return { parent: tree, index, target: tree.children[index] };
37
+ }
38
+ if ("lastChild" in selector) {
39
+ if (tree.children.length === 0) {
40
+ return undefined;
41
+ }
42
+ const index = tree.children.length - 1;
43
+ return { parent: tree, index, target: tree.children[index] };
44
+ }
45
+ return undefined;
46
+ }
47
+ const CONTAINER_TYPES = new Set(["heading", "blockquote", "list", "paragraph"]);
48
+ function getTargetChildren(target) {
49
+ if (CONTAINER_TYPES.has(target.type)) {
50
+ return target.children;
51
+ }
52
+ return undefined;
53
+ }
54
+ function parseValueNodes(value) {
55
+ const fragment = parseBody(value);
56
+ return fragment.children;
57
+ }
58
+ function collectAvailableHeadings(tree) {
59
+ const headings = [];
60
+ for (const child of tree.children) {
61
+ if (isHeadingNode(child)) {
62
+ headings.push(getHeadingText(child));
63
+ }
64
+ }
65
+ return headings;
66
+ }
67
+ export async function applySemanticPatches(body, patches) {
68
+ const tree = parseBody(body);
69
+ for (const patch of patches) {
70
+ const resolved = resolveSelector(tree, patch.selector);
71
+ if (!resolved) {
72
+ const headings = collectAvailableHeadings(tree);
73
+ let diagnostic = `Selector not found: ${JSON.stringify(patch.selector)}`;
74
+ if (headings.length > 0) {
75
+ diagnostic += `\nAvailable headings:\n${headings.map((h) => ` - ${h}`).join("\n")}`;
76
+ }
77
+ else {
78
+ diagnostic += "\nNo headings in document.";
79
+ }
80
+ throw new Error(diagnostic);
81
+ }
82
+ const { parent, index, target } = resolved;
83
+ const op = patch.operation;
84
+ switch (op.op) {
85
+ case "appendChild": {
86
+ const targetChildren = getTargetChildren(target);
87
+ if (!targetChildren) {
88
+ throw new Error(`Cannot appendChild to node of type '${target.type}'`);
89
+ }
90
+ const newNodes = parseValueNodes(op.value);
91
+ targetChildren.push(...newNodes);
92
+ break;
93
+ }
94
+ case "prependChild": {
95
+ const targetChildren = getTargetChildren(target);
96
+ if (!targetChildren) {
97
+ throw new Error(`Cannot prependChild to node of type '${target.type}'`);
98
+ }
99
+ const newNodes = parseValueNodes(op.value);
100
+ targetChildren.unshift(...newNodes);
101
+ break;
102
+ }
103
+ case "replace": {
104
+ const newNodes = parseValueNodes(op.value);
105
+ parent.children.splice(index, 1, ...newNodes);
106
+ break;
107
+ }
108
+ case "replaceChildren": {
109
+ const targetChildren = getTargetChildren(target);
110
+ if (!targetChildren) {
111
+ throw new Error(`Cannot replaceChildren of node of type '${target.type}'`);
112
+ }
113
+ const newNodes = parseValueNodes(op.value);
114
+ targetChildren.length = 0;
115
+ targetChildren.push(...newNodes);
116
+ break;
117
+ }
118
+ case "insertAfter": {
119
+ const newNodes = parseValueNodes(op.value);
120
+ parent.children.splice(index + 1, 0, ...newNodes);
121
+ break;
122
+ }
123
+ case "insertBefore": {
124
+ const newNodes = parseValueNodes(op.value);
125
+ parent.children.splice(index, 0, ...newNodes);
126
+ break;
127
+ }
128
+ case "remove": {
129
+ parent.children.splice(index, 1);
130
+ break;
131
+ }
132
+ default: {
133
+ const _exhaustive = op;
134
+ throw new Error(`Unknown operation: ${_exhaustive}`);
135
+ }
136
+ }
137
+ }
138
+ const serialized = serializeBody(tree);
139
+ return cleanMarkdown(serialized);
140
+ }
141
+ //# sourceMappingURL=semantic-patch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-patch.js","sourceRoot":"","sources":["../src/semantic-patch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danielmarbach/mnemonic-mcp",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "A local MCP memory server backed by markdown + JSON files, synced via git",
5
5
  "type": "module",
6
6
  "repository": {
@@ -35,7 +35,10 @@
35
35
  "@modelcontextprotocol/sdk": "^1.10.1",
36
36
  "gray-matter": "^4.0.3",
37
37
  "markdownlint": "^0.40.0",
38
+ "remark-parse": "^11.0.0",
39
+ "remark-stringify": "^11.0.0",
38
40
  "simple-git": "^3.27.0",
41
+ "unified": "^11.0.0",
39
42
  "zod": "^4.3.6"
40
43
  },
41
44
  "devDependencies": {