@danielmarbach/mnemonic-mcp 0.1.0 → 0.3.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/CHANGELOG.md +24 -0
- package/README.md +7 -19
- package/build/git.d.ts +2 -1
- package/build/git.d.ts.map +1 -1
- package/build/git.js +3 -2
- package/build/git.js.map +1 -1
- package/build/index.js +46 -7
- package/build/index.js.map +1 -1
- package/build/storage.js +9 -2
- package/build/storage.js.map +1 -1
- package/build/structured-content.d.ts +76 -42
- package/build/structured-content.d.ts.map +1 -1
- package/build/structured-content.js +2 -1
- package/build/structured-content.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,30 @@ All notable changes to `mnemonic` will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is loosely based on Keep a Changelog and uses semver-style version headings.
|
|
6
6
|
|
|
7
|
+
## [0.3.0] - 2026-03-10
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `recall` now backfills missing and stale embeddings on demand before searching. Notes that arrived via `git pull` without a local embedding, or that were edited directly in an editor after their embedding was written, are re-embedded automatically. If Ollama is unavailable the backfill fails silently and recall continues with existing embeddings.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- `parseNote` in `Storage` now converts gray-matter `Date` objects to ISO strings for `createdAt` and `updatedAt`. YAML frontmatter with unquoted ISO timestamps is parsed by gray-matter as JS `Date` instances; notes arriving via `git pull` from another machine were affected, causing output validation errors on recall.
|
|
16
|
+
- `pushWithStatus` in `GitOps` now returns `{ status: "failed", error }` instead of throwing on push failure. Previously, any push error caused mutating MCP tools (`remember`, `update`, `consolidate`, etc.) to return `isError: true` even though the note was committed successfully. The `PersistenceStatus` schema gains a `"failed"` push status and a `pushError` field to surface the failure detail without blocking the operation.
|
|
17
|
+
- `consolidate` `execute-merge` now reuses an existing consolidated target note on retry when the same source notes already point to the same `supersedes` target with the same title. This prevents duplicate consolidated notes after partial-success retry flows and keeps repeated merge attempts idempotent without requiring caller-supplied ids.
|
|
18
|
+
|
|
19
|
+
## [0.2.0] - 2026-03-10
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- `mnemonic import-claude-memory` CLI command imports Claude Code auto-memory notes into the vault. Each `##` heading becomes a separate note tagged `claude-memory` and `imported`. Safe to re-run — notes whose titles already exist are skipped.
|
|
24
|
+
- `mutationPushMode` config option controls when mutating writes auto-push to the remote: `main-only` (default), `all`, or `none`. Prevents push failures on unpublished project branches while keeping the main vault in sync automatically.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Published to the public npm registry with provenance attestation via OIDC trusted publishing. No authentication required to install.
|
|
29
|
+
- Renovate configured for automated dependency updates.
|
|
30
|
+
|
|
7
31
|
## [0.1.0] - 2026-03-08
|
|
8
32
|
|
|
9
33
|
First public release candidate.
|
package/README.md
CHANGED
|
@@ -75,28 +75,16 @@ Override the vault location:
|
|
|
75
75
|
VAULT_PATH=/path/to/your-vault docker compose run --rm mnemonic
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
## Installing from
|
|
78
|
+
## Installing from npm
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Create an `.npmrc` in the consuming project (or your home directory):
|
|
83
|
-
|
|
84
|
-
```ini
|
|
85
|
-
@danielmarbach:registry=https://npm.pkg.github.com
|
|
86
|
-
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Then install:
|
|
80
|
+
Packages are published to the public npm registry. No authentication required.
|
|
90
81
|
|
|
91
82
|
```bash
|
|
92
|
-
# Latest
|
|
93
|
-
npm install @danielmarbach/mnemonic-mcp
|
|
94
|
-
|
|
95
|
-
# Specific prerelease
|
|
96
|
-
npm install @danielmarbach/mnemonic-mcp@0.1.0-staging.12
|
|
83
|
+
# Latest stable release
|
|
84
|
+
npm install @danielmarbach/mnemonic-mcp
|
|
97
85
|
|
|
98
|
-
#
|
|
99
|
-
npm install @danielmarbach/mnemonic-mcp@0.
|
|
86
|
+
# Specific release
|
|
87
|
+
npm install @danielmarbach/mnemonic-mcp@0.2.0
|
|
100
88
|
```
|
|
101
89
|
|
|
102
90
|
## MCP client config
|
|
@@ -108,7 +96,7 @@ npm install @danielmarbach/mnemonic-mcp@0.1.0
|
|
|
108
96
|
"mcpServers": {
|
|
109
97
|
"mnemonic": {
|
|
110
98
|
"command": "npx",
|
|
111
|
-
"args": ["@danielmarbach/mnemonic-mcp
|
|
99
|
+
"args": ["@danielmarbach/mnemonic-mcp"],
|
|
112
100
|
"env": {
|
|
113
101
|
"VAULT_PATH": "/Users/you/mnemonic-vault"
|
|
114
102
|
}
|
package/build/git.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ export interface CommitResult {
|
|
|
15
15
|
reason?: "git-disabled" | "no-changes";
|
|
16
16
|
}
|
|
17
17
|
export interface PushResult {
|
|
18
|
-
status: "pushed" | "skipped";
|
|
18
|
+
status: "pushed" | "skipped" | "failed";
|
|
19
19
|
reason?: "git-disabled" | "no-remote" | "auto-push-disabled";
|
|
20
|
+
error?: string;
|
|
20
21
|
}
|
|
21
22
|
export declare class GitOps {
|
|
22
23
|
private git;
|
package/build/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAEA,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,SAAS,EAAE,QAAQ,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO;CAKzD;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,cAAc,GAAG,YAAY,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAEA,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,SAAS,EAAE,QAAQ,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO;CAKzD;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,cAAc,GAAG,YAAY,CAAC;CACxC;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,MAAM,CAAC,EAAE,cAAc,GAAG,WAAW,GAAG,oBAAoB,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,OAAO,CAAU;gBAEb,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,MAAgB;IAMpD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;;;;;;;;;;;;;;;;;OAkBG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKzE,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAwB9F;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,UAAU,CAAC;IA6BjC,uEAAuE;IACjE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,cAAc,IAAI,OAAO,CAAC,UAAU,CAAC;YAiB7B,WAAW;YASX,oBAAoB;IASlC;;;OAGG;YACW,cAAc;CAuC7B"}
|
package/build/git.js
CHANGED
|
@@ -129,8 +129,9 @@ export class GitOps {
|
|
|
129
129
|
return { status: "pushed" };
|
|
130
130
|
}
|
|
131
131
|
catch (err) {
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
133
|
+
console.error(`[git] Push failed: ${message}`);
|
|
134
|
+
return { status: "failed", error: message };
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
// ── Private helpers ──────────────────────────────────────────────────────────
|
package/build/git.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,YAAY,CAAC;AAElD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,SAA4B,EAAE,KAAc;QACtD,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,KAAK,CAAC,OAAO,SAAS,YAAY,MAAM,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
package/build/index.js
CHANGED
|
@@ -464,7 +464,7 @@ async function embedMissingNotes(storage, noteIds, force = false) {
|
|
|
464
464
|
}
|
|
465
465
|
if (!force) {
|
|
466
466
|
const existing = await storage.readEmbedding(note.id);
|
|
467
|
-
if (existing?.model === embedModel) {
|
|
467
|
+
if (existing?.model === embedModel && existing.updatedAt >= note.updatedAt) {
|
|
468
468
|
continue;
|
|
469
469
|
}
|
|
470
470
|
}
|
|
@@ -542,6 +542,7 @@ function buildPersistenceStatus(args) {
|
|
|
542
542
|
commitBody: args.commitBody,
|
|
543
543
|
commitReason: args.commit.reason,
|
|
544
544
|
pushReason: args.push.reason,
|
|
545
|
+
pushError: args.push.error,
|
|
545
546
|
},
|
|
546
547
|
durability: resolveDurability(args.commit, args.push),
|
|
547
548
|
};
|
|
@@ -1170,7 +1171,8 @@ server.registerTool("recall", {
|
|
|
1170
1171
|
description: "Semantic search over memories. " +
|
|
1171
1172
|
"When `cwd` is provided, searches both the project vault (.mnemonic/) and the " +
|
|
1172
1173
|
"main vault — project memories are boosted by +0.15 and shown first. " +
|
|
1173
|
-
"Without `cwd`, searches only the main vault."
|
|
1174
|
+
"Without `cwd`, searches only the main vault. " +
|
|
1175
|
+
"Missing or stale embeddings (e.g. from a git pull or direct editor edit) are backfilled on demand before searching.",
|
|
1174
1176
|
inputSchema: z.object({
|
|
1175
1177
|
query: z.string().describe("What to search for"),
|
|
1176
1178
|
cwd: projectParam,
|
|
@@ -1190,6 +1192,9 @@ server.registerTool("recall", {
|
|
|
1190
1192
|
const project = await resolveProject(cwd);
|
|
1191
1193
|
const queryVec = await embed(query);
|
|
1192
1194
|
const vaults = await vaultManager.searchOrder(cwd);
|
|
1195
|
+
for (const vault of vaults) {
|
|
1196
|
+
await embedMissingNotes(vault.storage).catch(() => { });
|
|
1197
|
+
}
|
|
1193
1198
|
const scored = [];
|
|
1194
1199
|
for (const vault of vaults) {
|
|
1195
1200
|
const embeddings = await vault.storage.listEmbeddings();
|
|
@@ -2414,8 +2419,9 @@ async function executeMerge(entries, mergePlan, defaultConsolidationMode, projec
|
|
|
2414
2419
|
sourceEntries.push(entry);
|
|
2415
2420
|
}
|
|
2416
2421
|
const consolidationMode = resolveEffectiveConsolidationMode(sourceEntries.map((entry) => entry.note), defaultConsolidationMode, explicitMode);
|
|
2422
|
+
const existingTargetEntry = findExistingExecuteMergeTarget(entries, sourceEntries, targetTitle);
|
|
2417
2423
|
const projectVault = cwd ? await vaultManager.getOrCreateProjectVault(cwd) : null;
|
|
2418
|
-
const targetVault = projectVault ?? vaultManager.main;
|
|
2424
|
+
const targetVault = existingTargetEntry?.vault ?? projectVault ?? vaultManager.main;
|
|
2419
2425
|
const now = new Date().toISOString();
|
|
2420
2426
|
// Build consolidated content
|
|
2421
2427
|
const sections = [];
|
|
@@ -2444,9 +2450,12 @@ async function executeMerge(entries, mergePlan, defaultConsolidationMode, projec
|
|
|
2444
2450
|
const combinedTags = tags ?? Array.from(new Set(sourceEntries.flatMap((e) => e.note.tags)));
|
|
2445
2451
|
// Collect all unique relationships from sources (excluding relationships among sources)
|
|
2446
2452
|
const sourceIdsSet = new Set(sourceIds);
|
|
2447
|
-
const
|
|
2448
|
-
|
|
2449
|
-
|
|
2453
|
+
const relationshipSources = existingTargetEntry
|
|
2454
|
+
? [...sourceEntries.map((entry) => entry.note), existingTargetEntry.note]
|
|
2455
|
+
: sourceEntries.map((entry) => entry.note);
|
|
2456
|
+
const allRelationships = mergeRelationshipsFromNotes(relationshipSources, sourceIdsSet);
|
|
2457
|
+
// Create or update the consolidated note
|
|
2458
|
+
const targetId = existingTargetEntry?.note.id ?? makeId(targetTitle);
|
|
2450
2459
|
const consolidatedNote = {
|
|
2451
2460
|
id: targetId,
|
|
2452
2461
|
title: targetTitle,
|
|
@@ -2456,7 +2465,7 @@ async function executeMerge(entries, mergePlan, defaultConsolidationMode, projec
|
|
|
2456
2465
|
project: project?.id,
|
|
2457
2466
|
projectName: project?.name,
|
|
2458
2467
|
relatedTo: allRelationships,
|
|
2459
|
-
createdAt: now,
|
|
2468
|
+
createdAt: existingTargetEntry?.note.createdAt ?? now,
|
|
2460
2469
|
updatedAt: now,
|
|
2461
2470
|
memoryVersion: 1,
|
|
2462
2471
|
};
|
|
@@ -2580,6 +2589,9 @@ async function executeMerge(entries, mergePlan, defaultConsolidationMode, projec
|
|
|
2580
2589
|
lines.push(`Consolidated ${sourceIds.length} notes into '${targetId}'`);
|
|
2581
2590
|
lines.push(`Mode: ${consolidationMode}`);
|
|
2582
2591
|
lines.push(`Stored in: ${targetVault.isProject ? "project-vault" : "main-vault"}`);
|
|
2592
|
+
if (existingTargetEntry) {
|
|
2593
|
+
lines.push("Idempotency: reused existing target note.");
|
|
2594
|
+
}
|
|
2583
2595
|
lines.push(formatPersistenceSummary(persistence));
|
|
2584
2596
|
switch (consolidationMode) {
|
|
2585
2597
|
case "supersedes":
|
|
@@ -2605,6 +2617,33 @@ async function executeMerge(entries, mergePlan, defaultConsolidationMode, projec
|
|
|
2605
2617
|
};
|
|
2606
2618
|
return { content: [{ type: "text", text: lines.join("\n") }], structuredContent };
|
|
2607
2619
|
}
|
|
2620
|
+
function findExistingExecuteMergeTarget(entries, sourceEntries, targetTitle) {
|
|
2621
|
+
const normalizedTitle = targetTitle.trim();
|
|
2622
|
+
const targetSlug = slugify(normalizedTitle);
|
|
2623
|
+
const sourceIds = new Set(sourceEntries.map((entry) => entry.note.id));
|
|
2624
|
+
let sharedTargetIds;
|
|
2625
|
+
for (const entry of sourceEntries) {
|
|
2626
|
+
const supersededTargetIds = new Set((entry.note.relatedTo ?? [])
|
|
2627
|
+
.filter((rel) => rel.type === "supersedes")
|
|
2628
|
+
.map((rel) => rel.id)
|
|
2629
|
+
.filter((id) => !sourceIds.has(id)));
|
|
2630
|
+
if (supersededTargetIds.size === 0) {
|
|
2631
|
+
return undefined;
|
|
2632
|
+
}
|
|
2633
|
+
sharedTargetIds = sharedTargetIds
|
|
2634
|
+
? new Set([...sharedTargetIds].filter((id) => supersededTargetIds.has(id)))
|
|
2635
|
+
: supersededTargetIds;
|
|
2636
|
+
if (sharedTargetIds.size === 0) {
|
|
2637
|
+
return undefined;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
const candidates = entries
|
|
2641
|
+
.filter((entry) => sharedTargetIds?.has(entry.note.id))
|
|
2642
|
+
.filter((entry) => entry.note.title.trim() === normalizedTitle)
|
|
2643
|
+
.filter((entry) => !targetSlug || entry.note.id === targetSlug || entry.note.id.startsWith(`${targetSlug}-`))
|
|
2644
|
+
.sort((left, right) => right.note.updatedAt.localeCompare(left.note.updatedAt));
|
|
2645
|
+
return candidates[0];
|
|
2646
|
+
}
|
|
2608
2647
|
async function pruneSuperseded(entries, consolidationMode, project) {
|
|
2609
2648
|
if (consolidationMode !== "delete") {
|
|
2610
2649
|
const structuredContent = {
|