@danielmarbach/mnemonic-mcp 0.1.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 +37 -0
- package/LICENSE +201 -0
- package/README.md +395 -0
- package/build/config.d.ts +34 -0
- package/build/config.d.ts.map +1 -0
- package/build/config.js +141 -0
- package/build/config.js.map +1 -0
- package/build/consolidate.d.ts +7 -0
- package/build/consolidate.d.ts.map +1 -0
- package/build/consolidate.js +42 -0
- package/build/consolidate.js.map +1 -0
- package/build/embeddings.d.ts +4 -0
- package/build/embeddings.d.ts.map +1 -0
- package/build/embeddings.js +32 -0
- package/build/embeddings.js.map +1 -0
- package/build/git.d.ts +70 -0
- package/build/git.d.ts.map +1 -0
- package/build/git.js +196 -0
- package/build/git.js.map +1 -0
- package/build/import.d.ts +14 -0
- package/build/import.d.ts.map +1 -0
- package/build/import.js +41 -0
- package/build/import.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +2753 -0
- package/build/index.js.map +1 -0
- package/build/markdown.d.ts +6 -0
- package/build/markdown.d.ts.map +1 -0
- package/build/markdown.js +51 -0
- package/build/markdown.js.map +1 -0
- package/build/migration.d.ts +65 -0
- package/build/migration.d.ts.map +1 -0
- package/build/migration.js +372 -0
- package/build/migration.js.map +1 -0
- package/build/project-introspection.d.ts +5 -0
- package/build/project-introspection.d.ts.map +1 -0
- package/build/project-introspection.js +28 -0
- package/build/project-introspection.js.map +1 -0
- package/build/project-memory-policy.d.ts +17 -0
- package/build/project-memory-policy.d.ts.map +1 -0
- package/build/project-memory-policy.js +16 -0
- package/build/project-memory-policy.js.map +1 -0
- package/build/project.d.ts +32 -0
- package/build/project.d.ts.map +1 -0
- package/build/project.js +125 -0
- package/build/project.js.map +1 -0
- package/build/recall.d.ts +10 -0
- package/build/recall.d.ts.map +1 -0
- package/build/recall.js +18 -0
- package/build/recall.js.map +1 -0
- package/build/storage.d.ts +58 -0
- package/build/storage.d.ts.map +1 -0
- package/build/storage.js +269 -0
- package/build/storage.js.map +1 -0
- package/build/structured-content.d.ts +1818 -0
- package/build/structured-content.d.ts.map +1 -0
- package/build/structured-content.js +267 -0
- package/build/structured-content.js.map +1 -0
- package/build/vault.d.ts +54 -0
- package/build/vault.d.ts.map +1 -0
- package/build/vault.js +144 -0
- package/build/vault.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import matter from "gray-matter";
|
|
4
|
+
import { readVaultSchemaVersion, writeVaultSchemaVersion } from "./config.js";
|
|
5
|
+
export class Migrator {
|
|
6
|
+
vaultManager;
|
|
7
|
+
migrations = new Map();
|
|
8
|
+
vaultLocks = new Map();
|
|
9
|
+
constructor(vaultManager) {
|
|
10
|
+
this.vaultManager = vaultManager;
|
|
11
|
+
this.registerBuiltInMigrations();
|
|
12
|
+
}
|
|
13
|
+
registerMigration(migration) {
|
|
14
|
+
if (this.migrations.has(migration.name)) {
|
|
15
|
+
throw new Error(`Migration already registered: ${migration.name}`);
|
|
16
|
+
}
|
|
17
|
+
if (!migration.minSchemaVersion && !migration.maxSchemaVersion) {
|
|
18
|
+
console.error(`[migration] Warning: ${migration.name} has no version constraints and will run on every invocation.`);
|
|
19
|
+
}
|
|
20
|
+
this.migrations.set(migration.name, migration);
|
|
21
|
+
}
|
|
22
|
+
listAvailableMigrations() {
|
|
23
|
+
return Array.from(this.migrations.values());
|
|
24
|
+
}
|
|
25
|
+
async getPendingMigrations(currentSchemaVersion, targetSchemaVersion) {
|
|
26
|
+
const all = this.listAvailableMigrations();
|
|
27
|
+
const current = this.parseVersion(currentSchemaVersion);
|
|
28
|
+
const target = targetSchemaVersion ? this.parseVersion(targetSchemaVersion) : undefined;
|
|
29
|
+
const pending = all.filter(mig => {
|
|
30
|
+
// Primary filter: maxSchemaVersion means "this migration upgrades TO this version"
|
|
31
|
+
// Run if current < max, don't run if current >= max
|
|
32
|
+
if (mig.maxSchemaVersion) {
|
|
33
|
+
const max = this.parseVersion(mig.maxSchemaVersion);
|
|
34
|
+
if (target && this.compareVersions(max, target) > 0)
|
|
35
|
+
return false;
|
|
36
|
+
if (this.compareVersions(current, max) >= 0)
|
|
37
|
+
return false;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
// If no max, check min: minSchemaVersion means "this migration was introduced at this version"
|
|
41
|
+
// Run if current < min (haven't reached that version yet)
|
|
42
|
+
if (mig.minSchemaVersion) {
|
|
43
|
+
const min = this.parseVersion(mig.minSchemaVersion);
|
|
44
|
+
if (target && this.compareVersions(min, target) > 0)
|
|
45
|
+
return false;
|
|
46
|
+
if (this.compareVersions(current, min) < 0)
|
|
47
|
+
return true;
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
// No version constraints, always run
|
|
51
|
+
return true;
|
|
52
|
+
});
|
|
53
|
+
// Sort by target version so migrations execute in schema-version order
|
|
54
|
+
// regardless of registration sequence. Unbounded migrations run last.
|
|
55
|
+
return pending.sort((a, b) => {
|
|
56
|
+
const aVer = a.maxSchemaVersion ?? a.minSchemaVersion;
|
|
57
|
+
const bVer = b.maxSchemaVersion ?? b.minSchemaVersion;
|
|
58
|
+
if (!aVer && !bVer)
|
|
59
|
+
return 0;
|
|
60
|
+
if (!aVer)
|
|
61
|
+
return 1;
|
|
62
|
+
if (!bVer)
|
|
63
|
+
return -1;
|
|
64
|
+
return this.compareVersions(this.parseVersion(aVer), this.parseVersion(bVer));
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async runMigration(migrationName, options) {
|
|
68
|
+
const migration = this.migrations.get(migrationName);
|
|
69
|
+
if (!migration) {
|
|
70
|
+
throw new Error(`Unknown migration: ${migrationName}`);
|
|
71
|
+
}
|
|
72
|
+
const vaults = [];
|
|
73
|
+
if (options.cwd) {
|
|
74
|
+
const projectVault = await this.vaultManager.getProjectVaultIfExists(options.cwd);
|
|
75
|
+
if (projectVault)
|
|
76
|
+
vaults.push(projectVault);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
vaults.push(...this.vaultManager.allKnownVaults());
|
|
80
|
+
}
|
|
81
|
+
const results = new Map();
|
|
82
|
+
for (const vault of vaults) {
|
|
83
|
+
const result = await this.withVaultLock(vault.storage.vaultPath, async () => {
|
|
84
|
+
const migrationResult = await this.runMigrationAtomically(vault, migration, options.dryRun);
|
|
85
|
+
if (!options.dryRun && migrationResult.errors.length === 0) {
|
|
86
|
+
const currentSchemaVersion = await readVaultSchemaVersion(vault.storage.vaultPath);
|
|
87
|
+
const nextSchemaVersion = this.getLatestSchemaVersion(currentSchemaVersion, [migration]);
|
|
88
|
+
const filesToCommit = new Set(migrationResult.modifiedNoteIds.map((id) => `${vault.notesRelDir}/${id}.md`));
|
|
89
|
+
if (nextSchemaVersion !== currentSchemaVersion) {
|
|
90
|
+
await writeVaultSchemaVersion(vault.storage.vaultPath, nextSchemaVersion);
|
|
91
|
+
filesToCommit.add(getConfigPathForVault(vault));
|
|
92
|
+
}
|
|
93
|
+
if (filesToCommit.size > 0) {
|
|
94
|
+
const commitMessage = [
|
|
95
|
+
`migrate: ${migrationName}`,
|
|
96
|
+
"",
|
|
97
|
+
`- Modified: ${migrationResult.notesModified} note(s)`,
|
|
98
|
+
`- Processed: ${migrationResult.notesProcessed} note(s)`,
|
|
99
|
+
`- Schema: ${currentSchemaVersion} -> ${nextSchemaVersion}`,
|
|
100
|
+
].join("\n");
|
|
101
|
+
try {
|
|
102
|
+
await vault.git.commit(commitMessage, [...filesToCommit]);
|
|
103
|
+
await vault.git.push();
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.error(`[migration] Failed to commit for ${vault.storage.vaultPath}: ${err}`);
|
|
107
|
+
migrationResult.warnings.push(`Auto-commit failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return migrationResult;
|
|
112
|
+
});
|
|
113
|
+
results.set(vault.storage.vaultPath, result);
|
|
114
|
+
}
|
|
115
|
+
return { results, vaultsProcessed: vaults.length };
|
|
116
|
+
}
|
|
117
|
+
async runAllPending(options) {
|
|
118
|
+
const vaults = [];
|
|
119
|
+
if (options.cwd) {
|
|
120
|
+
const projectVault = await this.vaultManager.getProjectVaultIfExists(options.cwd);
|
|
121
|
+
if (projectVault)
|
|
122
|
+
vaults.push(projectVault);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
vaults.push(...this.vaultManager.allKnownVaults());
|
|
126
|
+
}
|
|
127
|
+
const migrationResults = new Map();
|
|
128
|
+
for (const vault of vaults) {
|
|
129
|
+
const vaultResults = await this.withVaultLock(vault.storage.vaultPath, async () => {
|
|
130
|
+
const vaultVersion = await readVaultSchemaVersion(vault.storage.vaultPath);
|
|
131
|
+
const pending = await this.getPendingMigrations(vaultVersion);
|
|
132
|
+
if (pending.length === 0)
|
|
133
|
+
return null;
|
|
134
|
+
const lockedVaultResults = [];
|
|
135
|
+
const filesToCommit = new Set();
|
|
136
|
+
let hasErrors = false;
|
|
137
|
+
if (!options.dryRun) {
|
|
138
|
+
await vault.storage.beginAtomicNotesWrite();
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
for (const migration of pending) {
|
|
142
|
+
const result = await migration.run(vault, options.dryRun);
|
|
143
|
+
lockedVaultResults.push({ migration: migration.name, result });
|
|
144
|
+
if (!options.dryRun && result.notesModified > 0) {
|
|
145
|
+
for (const noteId of result.modifiedNoteIds) {
|
|
146
|
+
filesToCommit.add(`${vault.notesRelDir}/${noteId}.md`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (result.errors.length > 0)
|
|
150
|
+
hasErrors = true;
|
|
151
|
+
}
|
|
152
|
+
if (!options.dryRun) {
|
|
153
|
+
if (hasErrors) {
|
|
154
|
+
await vault.storage.rollbackAtomicNotesWrite();
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
await vault.storage.commitAtomicNotesWrite();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
if (!options.dryRun) {
|
|
163
|
+
await vault.storage.rollbackAtomicNotesWrite();
|
|
164
|
+
}
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
if (!options.dryRun && pending.length > 0) {
|
|
168
|
+
if (!hasErrors) {
|
|
169
|
+
const nextSchemaVersion = this.getLatestSchemaVersion(vaultVersion, pending);
|
|
170
|
+
if (nextSchemaVersion !== vaultVersion) {
|
|
171
|
+
await writeVaultSchemaVersion(vault.storage.vaultPath, nextSchemaVersion);
|
|
172
|
+
filesToCommit.add(getConfigPathForVault(vault));
|
|
173
|
+
}
|
|
174
|
+
if (filesToCommit.size > 0) {
|
|
175
|
+
const commitMessage = [
|
|
176
|
+
"migrate: apply pending migrations",
|
|
177
|
+
"",
|
|
178
|
+
`- Migrations: ${pending.map((migration) => migration.name).join(", ")}`,
|
|
179
|
+
`- Schema: ${vaultVersion} -> ${nextSchemaVersion}`,
|
|
180
|
+
].join("\n");
|
|
181
|
+
try {
|
|
182
|
+
await vault.git.commit(commitMessage, [...filesToCommit]);
|
|
183
|
+
await vault.git.push();
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
const message = `Auto-commit failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
187
|
+
console.error(`[migration] Failed to commit for ${vault.storage.vaultPath}: ${err}`);
|
|
188
|
+
for (const { result } of lockedVaultResults) {
|
|
189
|
+
result.warnings.push(message);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else if (filesToCommit.size > 0) {
|
|
195
|
+
const warning = "Schema version not advanced because one or more migrations reported errors; staged note updates were rolled back.";
|
|
196
|
+
for (const { result } of lockedVaultResults) {
|
|
197
|
+
result.warnings.push(warning);
|
|
198
|
+
}
|
|
199
|
+
console.error(`[migration] ${vault.storage.vaultPath}: ${warning}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return lockedVaultResults;
|
|
203
|
+
});
|
|
204
|
+
if (vaultResults) {
|
|
205
|
+
migrationResults.set(vault.storage.vaultPath, vaultResults);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return { migrationResults, vaultsProcessed: vaults.length };
|
|
209
|
+
}
|
|
210
|
+
registerBuiltInMigrations() {
|
|
211
|
+
this.registerMigration(createV010BackfillMemoryVersionMigration());
|
|
212
|
+
this.registerMigration(createV011BackfillLifecycleMigration());
|
|
213
|
+
}
|
|
214
|
+
parseVersion(version) {
|
|
215
|
+
if (!/^\d+(\.\d+)*$/.test(version)) {
|
|
216
|
+
throw new Error(`Invalid schema version: ${version}`);
|
|
217
|
+
}
|
|
218
|
+
return version.split(".").map(n => parseInt(n, 10));
|
|
219
|
+
}
|
|
220
|
+
compareVersions(a, b) {
|
|
221
|
+
for (let i = 0; i < Math.max(a.length, b.length); i++) {
|
|
222
|
+
const aPart = a[i] || 0;
|
|
223
|
+
const bPart = b[i] || 0;
|
|
224
|
+
if (aPart !== bPart)
|
|
225
|
+
return aPart - bPart;
|
|
226
|
+
}
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
getLatestSchemaVersion(currentSchemaVersion, migrations) {
|
|
230
|
+
let latest = currentSchemaVersion;
|
|
231
|
+
for (const migration of migrations) {
|
|
232
|
+
const candidate = migration.maxSchemaVersion ?? migration.minSchemaVersion;
|
|
233
|
+
if (!candidate) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
if (this.compareVersions(this.parseVersion(candidate), this.parseVersion(latest)) > 0) {
|
|
237
|
+
latest = candidate;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return latest;
|
|
241
|
+
}
|
|
242
|
+
async withVaultLock(vaultPath, operation) {
|
|
243
|
+
const previous = this.vaultLocks.get(vaultPath) ?? Promise.resolve();
|
|
244
|
+
let release;
|
|
245
|
+
const gate = new Promise((resolve) => {
|
|
246
|
+
release = resolve;
|
|
247
|
+
});
|
|
248
|
+
const tail = previous.then(() => gate);
|
|
249
|
+
this.vaultLocks.set(vaultPath, tail);
|
|
250
|
+
await previous;
|
|
251
|
+
try {
|
|
252
|
+
return await operation();
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
release();
|
|
256
|
+
if (this.vaultLocks.get(vaultPath) === tail) {
|
|
257
|
+
this.vaultLocks.delete(vaultPath);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async runMigrationAtomically(vault, migration, dryRun) {
|
|
262
|
+
if (dryRun) {
|
|
263
|
+
return migration.run(vault, true);
|
|
264
|
+
}
|
|
265
|
+
await vault.storage.beginAtomicNotesWrite();
|
|
266
|
+
try {
|
|
267
|
+
const result = await migration.run(vault, false);
|
|
268
|
+
if (result.errors.length > 0) {
|
|
269
|
+
await vault.storage.rollbackAtomicNotesWrite();
|
|
270
|
+
if (result.notesModified > 0) {
|
|
271
|
+
result.warnings.push("Atomic migration rollback applied; note changes were not flushed to disk.");
|
|
272
|
+
}
|
|
273
|
+
return result;
|
|
274
|
+
}
|
|
275
|
+
await vault.storage.commitAtomicNotesWrite();
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
await vault.storage.rollbackAtomicNotesWrite();
|
|
280
|
+
throw err;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function getConfigPathForVault(vault) {
|
|
285
|
+
return vault.notesRelDir.replace(/notes$/, "config.json");
|
|
286
|
+
}
|
|
287
|
+
function createV010BackfillMemoryVersionMigration() {
|
|
288
|
+
return {
|
|
289
|
+
name: "v0.1.0-backfill-memory-versions",
|
|
290
|
+
description: "Adds memoryVersion: 1 to all notes that lack a version marker",
|
|
291
|
+
minSchemaVersion: "0.0",
|
|
292
|
+
maxSchemaVersion: "1.0",
|
|
293
|
+
async run(vault, dryRun) {
|
|
294
|
+
const result = {
|
|
295
|
+
notesProcessed: 0,
|
|
296
|
+
notesModified: 0,
|
|
297
|
+
modifiedNoteIds: [],
|
|
298
|
+
errors: [],
|
|
299
|
+
warnings: [],
|
|
300
|
+
};
|
|
301
|
+
const notes = await vault.storage.listNotes();
|
|
302
|
+
result.notesProcessed = notes.length;
|
|
303
|
+
for (const note of notes) {
|
|
304
|
+
try {
|
|
305
|
+
if (note.memoryVersion === undefined || note.memoryVersion === 0) {
|
|
306
|
+
result.notesModified++;
|
|
307
|
+
result.modifiedNoteIds.push(note.id);
|
|
308
|
+
if (!dryRun) {
|
|
309
|
+
const updatedNote = {
|
|
310
|
+
...note,
|
|
311
|
+
memoryVersion: 1,
|
|
312
|
+
};
|
|
313
|
+
await vault.storage.writeNote(updatedNote);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
result.errors.push({
|
|
319
|
+
noteId: note.id,
|
|
320
|
+
error: err instanceof Error ? err.message : String(err),
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return result;
|
|
325
|
+
},
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
function createV011BackfillLifecycleMigration() {
|
|
329
|
+
return {
|
|
330
|
+
name: "v0.1.1-backfill-note-lifecycle",
|
|
331
|
+
description: "Adds lifecycle: permanent to notes that lack a lifecycle marker",
|
|
332
|
+
minSchemaVersion: "1.0",
|
|
333
|
+
maxSchemaVersion: "1.1",
|
|
334
|
+
async run(vault, dryRun) {
|
|
335
|
+
const result = {
|
|
336
|
+
notesProcessed: 0,
|
|
337
|
+
notesModified: 0,
|
|
338
|
+
modifiedNoteIds: [],
|
|
339
|
+
errors: [],
|
|
340
|
+
warnings: [],
|
|
341
|
+
};
|
|
342
|
+
const notes = await vault.storage.listNotes();
|
|
343
|
+
result.notesProcessed = notes.length;
|
|
344
|
+
for (const note of notes) {
|
|
345
|
+
try {
|
|
346
|
+
const notePath = path.join(vault.storage.notesDir, `${note.id}.md`);
|
|
347
|
+
const raw = await fs.readFile(notePath, "utf-8");
|
|
348
|
+
const parsed = matter(raw);
|
|
349
|
+
if (parsed.data["lifecycle"] === "temporary" || parsed.data["lifecycle"] === "permanent") {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
result.notesModified++;
|
|
353
|
+
result.modifiedNoteIds.push(note.id);
|
|
354
|
+
if (!dryRun) {
|
|
355
|
+
await vault.storage.writeNote({
|
|
356
|
+
...note,
|
|
357
|
+
lifecycle: "permanent",
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
result.errors.push({
|
|
363
|
+
noteId: note.id,
|
|
364
|
+
error: err instanceof Error ? err.message : String(err),
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Note } from "./storage.js";
|
|
2
|
+
export declare function summarizePreview(content: string, maxLength?: number): string;
|
|
3
|
+
export declare function classifyTheme(note: Note): string;
|
|
4
|
+
export declare function titleCaseTheme(theme: string): string;
|
|
5
|
+
//# sourceMappingURL=project-introspection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-introspection.d.ts","sourceRoot":"","sources":["../src/project-introspection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAM,GAAG,MAAM,CAMzE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAWhD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function summarizePreview(content, maxLength = 120) {
|
|
2
|
+
const singleLine = content.replace(/\s+/g, " ").trim();
|
|
3
|
+
if (singleLine.length <= maxLength) {
|
|
4
|
+
return singleLine;
|
|
5
|
+
}
|
|
6
|
+
return `${singleLine.slice(0, maxLength - 3)}...`;
|
|
7
|
+
}
|
|
8
|
+
export function classifyTheme(note) {
|
|
9
|
+
const title = note.title.toLowerCase();
|
|
10
|
+
const tags = new Set(note.tags.map((tag) => tag.toLowerCase()));
|
|
11
|
+
if (tags.has("overview") || title.includes("overview"))
|
|
12
|
+
return "overview";
|
|
13
|
+
if (tags.has("decisions") || tags.has("design") || tags.has("policy") || tags.has("ux"))
|
|
14
|
+
return "decisions";
|
|
15
|
+
if (tags.has("tools") || tags.has("mcp") || tags.has("docker") || tags.has("deployment"))
|
|
16
|
+
return "tooling";
|
|
17
|
+
if (tags.has("bugs") || tags.has("setup"))
|
|
18
|
+
return "bugs";
|
|
19
|
+
if (tags.has("relationships") || tags.has("graph") || tags.has("architecture") || tags.has("structure"))
|
|
20
|
+
return "architecture";
|
|
21
|
+
if (tags.has("linting") || tags.has("tests") || tags.has("quality"))
|
|
22
|
+
return "quality";
|
|
23
|
+
return "other";
|
|
24
|
+
}
|
|
25
|
+
export function titleCaseTheme(theme) {
|
|
26
|
+
return `${theme[0]?.toUpperCase() ?? ""}${theme.slice(1)}`;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=project-introspection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-introspection.js","sourceRoot":"","sources":["../src/project-introspection.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,SAAS,GAAG,GAAG;IAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACvD,IAAI,UAAU,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QACnC,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAEhE,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAC1E,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC;IAC5G,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3G,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IACzD,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;QAAE,OAAO,cAAc,CAAC;IAC/H,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IACtF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type WriteScope = "project" | "global";
|
|
2
|
+
export declare const WRITE_SCOPES: readonly ["project", "global"];
|
|
3
|
+
export type ProjectPolicyScope = WriteScope | "ask";
|
|
4
|
+
export declare const PROJECT_POLICY_SCOPES: readonly ["project", "global", "ask"];
|
|
5
|
+
export type ConsolidationMode = "supersedes" | "delete";
|
|
6
|
+
export declare const CONSOLIDATION_MODES: readonly ["supersedes", "delete"];
|
|
7
|
+
export interface ProjectMemoryPolicy {
|
|
8
|
+
projectId: string;
|
|
9
|
+
projectName?: string;
|
|
10
|
+
defaultScope: ProjectPolicyScope;
|
|
11
|
+
/** Default consolidation mode for this project. "supersedes" preserves history, "delete" removes sources. */
|
|
12
|
+
consolidationMode?: ConsolidationMode;
|
|
13
|
+
updatedAt: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function resolveConsolidationMode(policy: ProjectMemoryPolicy | undefined): ConsolidationMode;
|
|
16
|
+
export declare function resolveWriteScope(explicitScope: WriteScope | undefined, projectPolicyScope: ProjectPolicyScope | undefined, hasProjectContext: boolean): WriteScope | "ask";
|
|
17
|
+
//# sourceMappingURL=project-memory-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-memory-policy.d.ts","sourceRoot":"","sources":["../src/project-memory-policy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAC9C,eAAO,MAAM,YAAY,gCAAiE,CAAC;AAC3F,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,KAAK,CAAC;AACpD,eAAO,MAAM,qBAAqB,uCAAgF,CAAC;AAEnH,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,QAAQ,CAAC;AACxD,eAAO,MAAM,mBAAmB,mCAA2E,CAAC;AAE5G,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,kBAAkB,CAAC;IACjC,6GAA6G;IAC7G,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,mBAAmB,GAAG,SAAS,GAAG,iBAAiB,CAEnG;AAED,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,UAAU,GAAG,SAAS,EACrC,kBAAkB,EAAE,kBAAkB,GAAG,SAAS,EAClD,iBAAiB,EAAE,OAAO,GACzB,UAAU,GAAG,KAAK,CAUpB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const WRITE_SCOPES = ["project", "global"];
|
|
2
|
+
export const PROJECT_POLICY_SCOPES = ["project", "global", "ask"];
|
|
3
|
+
export const CONSOLIDATION_MODES = ["supersedes", "delete"];
|
|
4
|
+
export function resolveConsolidationMode(policy) {
|
|
5
|
+
return policy?.consolidationMode ?? "supersedes";
|
|
6
|
+
}
|
|
7
|
+
export function resolveWriteScope(explicitScope, projectPolicyScope, hasProjectContext) {
|
|
8
|
+
if (explicitScope) {
|
|
9
|
+
return explicitScope;
|
|
10
|
+
}
|
|
11
|
+
if (projectPolicyScope) {
|
|
12
|
+
return projectPolicyScope;
|
|
13
|
+
}
|
|
14
|
+
return hasProjectContext ? "project" : "global";
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=project-memory-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-memory-policy.js","sourceRoot":"","sources":["../src/project-memory-policy.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,QAAQ,CAA0C,CAAC;AAE3F,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAkD,CAAC;AAGnH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAiD,CAAC;AAW5G,MAAM,UAAU,wBAAwB,CAAC,MAAuC;IAC9E,OAAO,MAAM,EAAE,iBAAiB,IAAI,YAAY,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,aAAqC,EACrC,kBAAkD,EAClD,iBAA0B;IAE1B,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IAED,OAAO,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type ProjectSource = "git-remote" | "git-remote-override" | "git-folder" | "folder";
|
|
2
|
+
export interface ProjectInfo {
|
|
3
|
+
/** Stable identifier: normalized git remote URL or folder name */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Human-readable name (last path segment of remote, or folder name) */
|
|
6
|
+
name: string;
|
|
7
|
+
/** How the project was detected */
|
|
8
|
+
source: ProjectSource;
|
|
9
|
+
/** Which remote produced this identity when remote-based detection is used. */
|
|
10
|
+
remoteName?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ProjectIdentityOverride {
|
|
13
|
+
remoteName: string;
|
|
14
|
+
updatedAt: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ProjectDetectionOptions {
|
|
17
|
+
getProjectIdentityOverride?: (projectId: string) => Promise<ProjectIdentityOverride | undefined>;
|
|
18
|
+
}
|
|
19
|
+
export interface ProjectIdentityResolution {
|
|
20
|
+
project: ProjectInfo;
|
|
21
|
+
defaultProject: ProjectInfo;
|
|
22
|
+
identityOverride?: ProjectIdentityOverride;
|
|
23
|
+
identityOverrideApplied: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a working directory path to a stable project identifier.
|
|
27
|
+
* Uses the git remote URL when available so the same project is recognized
|
|
28
|
+
* across machines regardless of local clone path.
|
|
29
|
+
*/
|
|
30
|
+
export declare function detectProject(cwd: string, options?: ProjectDetectionOptions): Promise<ProjectInfo | null>;
|
|
31
|
+
export declare function resolveProjectIdentity(cwd: string, options?: ProjectDetectionOptions): Promise<ProjectIdentityResolution | null>;
|
|
32
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,qBAAqB,GAAG,YAAY,GAAG,QAAQ,CAAC;AAE3F,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,MAAM,EAAE,aAAa,CAAC;IACtB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,0BAA0B,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAAC,CAAC;CAClG;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,WAAW,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;IAC5B,gBAAgB,CAAC,EAAE,uBAAuB,CAAC;IAC3C,uBAAuB,EAAE,OAAO,CAAC;CAClC;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAGnH;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CA4C3C"}
|
package/build/project.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { execFile } from "child_process";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import path from "path";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a working directory path to a stable project identifier.
|
|
7
|
+
* Uses the git remote URL when available so the same project is recognized
|
|
8
|
+
* across machines regardless of local clone path.
|
|
9
|
+
*/
|
|
10
|
+
export async function detectProject(cwd, options = {}) {
|
|
11
|
+
const resolved = await resolveProjectIdentity(cwd, options);
|
|
12
|
+
return resolved?.project ?? null;
|
|
13
|
+
}
|
|
14
|
+
export async function resolveProjectIdentity(cwd, options = {}) {
|
|
15
|
+
if (!cwd)
|
|
16
|
+
return null;
|
|
17
|
+
const defaultProject = await detectDefaultProject(cwd);
|
|
18
|
+
if (!defaultProject)
|
|
19
|
+
return null;
|
|
20
|
+
if (defaultProject.source !== "git-remote") {
|
|
21
|
+
return {
|
|
22
|
+
project: defaultProject,
|
|
23
|
+
defaultProject,
|
|
24
|
+
identityOverrideApplied: false,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const identityOverride = await options.getProjectIdentityOverride?.(defaultProject.id);
|
|
28
|
+
if (!identityOverride) {
|
|
29
|
+
return {
|
|
30
|
+
project: defaultProject,
|
|
31
|
+
defaultProject,
|
|
32
|
+
identityOverrideApplied: false,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const overrideRemote = await getGitRemoteUrl(cwd, identityOverride.remoteName);
|
|
36
|
+
if (!overrideRemote) {
|
|
37
|
+
return {
|
|
38
|
+
project: defaultProject,
|
|
39
|
+
defaultProject,
|
|
40
|
+
identityOverride,
|
|
41
|
+
identityOverrideApplied: false,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
project: {
|
|
46
|
+
id: normalizeRemote(overrideRemote),
|
|
47
|
+
name: extractRepoName(overrideRemote),
|
|
48
|
+
source: "git-remote-override",
|
|
49
|
+
remoteName: identityOverride.remoteName,
|
|
50
|
+
},
|
|
51
|
+
defaultProject,
|
|
52
|
+
identityOverride,
|
|
53
|
+
identityOverrideApplied: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
async function detectDefaultProject(cwd) {
|
|
57
|
+
if (!cwd)
|
|
58
|
+
return null;
|
|
59
|
+
// Try git remote first
|
|
60
|
+
const remote = await getGitRemoteUrl(cwd, "origin");
|
|
61
|
+
if (remote) {
|
|
62
|
+
const id = normalizeRemote(remote);
|
|
63
|
+
const name = extractRepoName(remote);
|
|
64
|
+
return { id, name, source: "git-remote", remoteName: "origin" };
|
|
65
|
+
}
|
|
66
|
+
// Try git root folder name (repo without remote)
|
|
67
|
+
try {
|
|
68
|
+
const { stdout: rootOut } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], { cwd });
|
|
69
|
+
const root = rootOut.trim();
|
|
70
|
+
if (root) {
|
|
71
|
+
const name = path.basename(root);
|
|
72
|
+
return { id: slugify(name), name, source: "git-folder" };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// not a git repo at all — fall through
|
|
77
|
+
}
|
|
78
|
+
// Fallback: just use the directory name
|
|
79
|
+
const name = path.basename(path.resolve(cwd));
|
|
80
|
+
if (name) {
|
|
81
|
+
return { id: slugify(name), name, source: "folder" };
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
async function getGitRemoteUrl(cwd, remoteName) {
|
|
86
|
+
try {
|
|
87
|
+
const { stdout: remoteOut } = await execFileAsync("git", ["remote", "get-url", remoteName], { cwd });
|
|
88
|
+
const remote = remoteOut.trim();
|
|
89
|
+
return remote || null;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Normalize a git remote URL to a stable lowercase identifier.
|
|
97
|
+
* Strips protocol, auth, .git suffix, and converts separators to dashes.
|
|
98
|
+
*
|
|
99
|
+
* Examples:
|
|
100
|
+
* git@github.com:acme/myapp.git → github-com-acme-myapp
|
|
101
|
+
* https://github.com/acme/myapp → github-com-acme-myapp
|
|
102
|
+
*/
|
|
103
|
+
function normalizeRemote(remote) {
|
|
104
|
+
let s = remote.trim().toLowerCase();
|
|
105
|
+
// SSH: git@github.com:user/repo.git
|
|
106
|
+
s = s.replace(/^git@/, "").replace(/:/, "/");
|
|
107
|
+
// Strip protocol
|
|
108
|
+
s = s.replace(/^https?:\/\//, "").replace(/^ssh:\/\//, "");
|
|
109
|
+
// Strip auth (user:pass@)
|
|
110
|
+
s = s.replace(/^[^@]*@/, "");
|
|
111
|
+
// Strip .git
|
|
112
|
+
s = s.replace(/\.git$/, "");
|
|
113
|
+
// Normalise separators
|
|
114
|
+
s = s.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
115
|
+
return s;
|
|
116
|
+
}
|
|
117
|
+
function extractRepoName(remote) {
|
|
118
|
+
// Get the last path segment before .git
|
|
119
|
+
const match = remote.match(/\/([^/]+?)(\.git)?$/);
|
|
120
|
+
return match?.[1] ?? path.basename(remote);
|
|
121
|
+
}
|
|
122
|
+
function slugify(s) {
|
|
123
|
+
return s.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"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"}
|