@danielmarbach/mnemonic-mcp 0.25.0 → 0.25.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.
- package/CHANGELOG.md +15 -0
- package/build/index.js +33 -6
- package/build/index.js.map +1 -1
- package/build/markdown.d.ts +4 -0
- package/build/markdown.d.ts.map +1 -1
- package/build/markdown.js +12 -4
- package/build/markdown.js.map +1 -1
- package/build/semantic-patch.d.ts +4 -1
- package/build/semantic-patch.d.ts.map +1 -1
- package/build/semantic-patch.js +4 -2
- package/build/semantic-patch.js.map +1 -1
- package/build/structured-content.d.ts +2 -0
- package/build/structured-content.d.ts.map +1 -1
- package/build/structured-content.js +1 -0
- package/build/structured-content.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,21 @@ The format is loosely based on Keep a Changelog and uses semver-style version he
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.25.2] - 2026-04-24
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `semanticPatch` parameter description now includes the full selector/operation type union and a 3-patch working example, so LLMs can construct correct JSON shapes without guessing at the nesting structure.
|
|
14
|
+
- `mnemonic-workflow-hint` prompt now includes a `semanticPatch format` section with explicit nesting examples and a callout for the common `{op, value}` flattening mistake.
|
|
15
|
+
- Selector-not-found errors now include a format reminder showing the correct selector shape using the first available heading.
|
|
16
|
+
|
|
17
|
+
## [0.25.1] - 2026-04-24
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- `semanticPatch` no longer rejects content with markdown lint issues — the patch succeeds and warnings are surfaced in the response instead, so the LLM can continue without retrying from scratch. Previously any lint issue forced a hard failure.
|
|
22
|
+
- Structural errors (bad selector, invalid operation) and content lint errors are now distinguished from patch lint warnings with separate guidance, so the LLM gets the right fix direction for each failure mode.
|
|
23
|
+
|
|
9
24
|
## [0.25.0] - 2026-04-24
|
|
10
25
|
|
|
11
26
|
### Added
|
package/build/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import { suggestAutoRelationships } from "./auto-relate.js";
|
|
|
17
17
|
import { computeRecallMetadataBoost, computeHybridScore, selectRecallResults, selectWorkflowResults, applyLexicalReranking, applyCanonicalExplanationPromotion, } from "./recall.js";
|
|
18
18
|
import { shouldTriggerLexicalRescue, rankDocumentsByTfIdf, LEXICAL_RESCUE_CANDIDATE_LIMIT, LEXICAL_RESCUE_THRESHOLD, LEXICAL_RESCUE_RESULT_LIMIT, } from "./lexical.js";
|
|
19
19
|
import { getRelationshipPreview } from "./relationships.js";
|
|
20
|
-
import { cleanMarkdown } from "./markdown.js";
|
|
20
|
+
import { MarkdownLintError, cleanMarkdown } from "./markdown.js";
|
|
21
21
|
import { applySemanticPatches } from "./semantic-patch.js";
|
|
22
22
|
import { MnemonicConfigStore, readVaultSchemaVersion } from "./config.js";
|
|
23
23
|
import { CONSOLIDATION_MODES, PROTECTED_BRANCH_BEHAVIORS, PROJECT_POLICY_SCOPES, WRITE_SCOPES, isProtectedBranch, resolveProtectedBranchBehavior, resolveProtectedBranchPatterns, resolveConsolidationMode, resolveWriteScope, } from "./project-memory-policy.js";
|
|
@@ -2158,8 +2158,16 @@ server.registerTool("update", {
|
|
|
2158
2158
|
]),
|
|
2159
2159
|
}))
|
|
2160
2160
|
.optional()
|
|
2161
|
-
.describe("
|
|
2162
|
-
"
|
|
2161
|
+
.describe("Targeted edits to note sections. Array of {selector, operation} objects. Mutually exclusive with content. " +
|
|
2162
|
+
"If this fails, fix the issue in your patch values and retry — do NOT fall back to full content rewrite.\n\n" +
|
|
2163
|
+
"selector: exactly one of { heading: \"exact heading text\" } | { headingStartsWith: \"prefix\" } | { lastChild: true } | { nthChild: 0-based-index }\n" +
|
|
2164
|
+
"operation: { op: \"appendChild\", value: \"content\" } | { op: \"prependChild\", value: \"content\" } | { op: \"replace\", value: \"new content\" } | { op: \"replaceChildren\", value: \"new children\" } | { op: \"insertAfter\", value: \"content\" } | { op: \"insertBefore\", value: \"content\" } | { op: \"remove\" }\n\n" +
|
|
2165
|
+
"Example — append a paragraph under ## Findings, replace ## Recommendation body, remove ## Old Section:\n" +
|
|
2166
|
+
"[\n" +
|
|
2167
|
+
" { \"selector\": { \"heading\": \"Findings\" }, \"operation\": { \"op\": \"appendChild\", \"value\": \"A new paragraph.\" } },\n" +
|
|
2168
|
+
" { \"selector\": { \"heading\": \"Recommendation\" }, \"operation\": { \"op\": \"replaceChildren\", \"value\": \"Updated recommendation.\" } },\n" +
|
|
2169
|
+
" { \"selector\": { \"heading\": \"Old Section\" }, \"operation\": { \"op\": \"remove\" } }\n" +
|
|
2170
|
+
"]"),
|
|
2163
2171
|
content: z.string().optional().describe("Full note body replacement. Use only for complete rewrites or when the note is small. Mutually exclusive with semanticPatch."),
|
|
2164
2172
|
title: z.string().optional().describe("Specific, retrieval-friendly title. Prefer the concrete topic or decision, not a vague label."),
|
|
2165
2173
|
tags: z.array(z.string()).optional().describe("Optional tags for later filtering. Use a small number of stable, meaningful tags."),
|
|
@@ -2222,11 +2230,18 @@ server.registerTool("update", {
|
|
|
2222
2230
|
}
|
|
2223
2231
|
const now = new Date().toISOString();
|
|
2224
2232
|
let patchedContent;
|
|
2233
|
+
let lintWarnings;
|
|
2225
2234
|
if (semanticPatch && semanticPatch.length > 0) {
|
|
2226
2235
|
try {
|
|
2227
|
-
|
|
2236
|
+
const result = await applySemanticPatches(note.content, semanticPatch);
|
|
2237
|
+
patchedContent = result.content;
|
|
2238
|
+
lintWarnings = result.lintWarnings;
|
|
2228
2239
|
}
|
|
2229
2240
|
catch (err) {
|
|
2241
|
+
if (err instanceof MarkdownLintError) {
|
|
2242
|
+
const message = `Semantic patch produced content with markdown lint issues. Fix the lint issues in your patch values and retry — do NOT fall back to full content rewrite.\n\n${err.message}`;
|
|
2243
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
2244
|
+
}
|
|
2230
2245
|
const message = err instanceof Error ? err.message : String(err);
|
|
2231
2246
|
return { content: [{ type: "text", text: `Semantic patch failed: ${message}` }], isError: true };
|
|
2232
2247
|
}
|
|
@@ -2333,11 +2348,15 @@ server.registerTool("update", {
|
|
|
2333
2348
|
project: noteProjectRef(updated),
|
|
2334
2349
|
lifecycle: updated.lifecycle,
|
|
2335
2350
|
role: updated.role,
|
|
2351
|
+
lintWarnings: lintWarnings && lintWarnings.length > 0 ? lintWarnings : undefined,
|
|
2336
2352
|
persistence,
|
|
2337
2353
|
};
|
|
2338
2354
|
invalidateActiveProjectCache();
|
|
2339
2355
|
const fieldText = changes.length > 0 ? `\nfields modified: ${changes.join(", ")}` : "";
|
|
2340
|
-
|
|
2356
|
+
const warningsText = lintWarnings && lintWarnings.length > 0
|
|
2357
|
+
? `\nmarkdown lint warnings (not auto-fixable):\n- ${lintWarnings.join("\n- ")}`
|
|
2358
|
+
: "";
|
|
2359
|
+
return { content: [{ type: "text", text: `Updated memory '${id}'${fieldText}${warningsText}\n${formatPersistenceSummary(persistence)}` }], structuredContent };
|
|
2341
2360
|
});
|
|
2342
2361
|
// ── forget ────────────────────────────────────────────────────────────────────
|
|
2343
2362
|
server.registerTool("forget", {
|
|
@@ -5056,7 +5075,15 @@ server.registerPrompt("mnemonic-workflow-hint", {
|
|
|
5056
5075
|
"- Existing bug note found by `recall` -> inspect with `get` -> refine with `update`.\n" +
|
|
5057
5076
|
"- No matching note found by `recall` -> optional `discover_tags` with note context -> create with `remember`.\n" +
|
|
5058
5077
|
"- Two notes overlap heavily -> inspect -> clean up with `consolidate`.\n" +
|
|
5059
|
-
"- Resume work: `project_memory_summary` -> `recall` (lifecycle: temporary) -> continue from temporary notes
|
|
5078
|
+
"- Resume work: `project_memory_summary` -> `recall` (lifecycle: temporary) -> continue from temporary notes.\n\n" +
|
|
5079
|
+
"### semanticPatch format\n\n" +
|
|
5080
|
+
"When using `update` with `semanticPatch`:\n" +
|
|
5081
|
+
"- Each patch is an object with two keys: `selector` and `operation` (not flat `{op, value}` at top level).\n" +
|
|
5082
|
+
"- `selector` has exactly one key: `heading`, `headingStartsWith`, `nthChild`, or `lastChild`.\n" +
|
|
5083
|
+
"- `operation` has an `op` key plus `value` (except `remove` which has no value).\n" +
|
|
5084
|
+
"- The parameter must be a JSON array, NOT a string.\n" +
|
|
5085
|
+
"- Use `get` first to read exact heading text, then use those headings (without `##` prefix) as selector values.\n" +
|
|
5086
|
+
"- Common mistake: writing `{ \"op\": \"appendChild\", \"value\": \"...\" }` at the top level instead of nesting inside `operation`. Correct shape: `{ \"selector\": { \"heading\": \"Findings\" }, \"operation\": { \"op\": \"appendChild\", \"value\": \"text\" } }`",
|
|
5060
5087
|
},
|
|
5061
5088
|
},
|
|
5062
5089
|
],
|