@brianluby/agent-brain 1.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.
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, mkdirSync, renameSync, unlinkSync } from 'fs';
3
+ import { relative, basename, dirname, resolve, isAbsolute, sep } from 'path';
4
+ import { execSync } from 'child_process';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ function defaultPlatformRelativePath(platform) {
8
+ const normalizedPlatform = platform.trim().toLowerCase();
9
+ const safePlatform = normalizedPlatform.replace(/[^a-z0-9_-]/g, "-").replace(/^-+|-+$/g, "") || "unknown";
10
+ return `.agent-brain/mind-${safePlatform}.mv2`;
11
+ }
12
+ function resolveInsideProject(projectDir, candidatePath) {
13
+ if (isAbsolute(candidatePath)) {
14
+ return resolve(candidatePath);
15
+ }
16
+ const root = resolve(projectDir);
17
+ const resolved = resolve(root, candidatePath);
18
+ const rel = relative(root, resolved);
19
+ if (rel === ".." || rel.startsWith(`..${sep}`)) {
20
+ throw new Error("Resolved memory path must stay inside projectDir");
21
+ }
22
+ return resolved;
23
+ }
24
+ function resolveMemoryPathPolicy(input) {
25
+ const mode = input.platformOptIn ? "platform_opt_in" : "legacy_first";
26
+ const canonicalRelativePath = input.platformOptIn ? input.platformRelativePath || defaultPlatformRelativePath(input.platform) : input.defaultRelativePath;
27
+ const canonicalPath = resolveInsideProject(input.projectDir, canonicalRelativePath);
28
+ if (existsSync(canonicalPath)) {
29
+ return {
30
+ mode,
31
+ memoryPath: canonicalPath,
32
+ canonicalPath
33
+ };
34
+ }
35
+ const fallbackPaths = (input.legacyRelativePaths || []).map((relativePath) => resolveInsideProject(input.projectDir, relativePath));
36
+ for (const fallbackPath of fallbackPaths) {
37
+ if (existsSync(fallbackPath)) {
38
+ return {
39
+ mode,
40
+ memoryPath: fallbackPath,
41
+ canonicalPath,
42
+ migrationSuggestion: {
43
+ fromPath: fallbackPath,
44
+ toPath: canonicalPath
45
+ }
46
+ };
47
+ }
48
+ }
49
+ if (input.platformOptIn) {
50
+ return {
51
+ mode: "platform_opt_in",
52
+ memoryPath: canonicalPath,
53
+ canonicalPath
54
+ };
55
+ }
56
+ return {
57
+ mode: "legacy_first",
58
+ memoryPath: canonicalPath,
59
+ canonicalPath
60
+ };
61
+ }
62
+
63
+ // src/platforms/platform-detector.ts
64
+ function normalizePlatform(value) {
65
+ if (!value) return void 0;
66
+ const normalized = value.trim().toLowerCase();
67
+ return normalized.length > 0 ? normalized : void 0;
68
+ }
69
+ function detectPlatformFromEnv() {
70
+ const explicitFromEnv = normalizePlatform(process.env.MEMVID_PLATFORM);
71
+ if (explicitFromEnv) {
72
+ return explicitFromEnv;
73
+ }
74
+ if (process.env.OPENCODE === "1") {
75
+ return "opencode";
76
+ }
77
+ return "claude";
78
+ }
79
+
80
+ // src/scripts/utils.ts
81
+ async function createFreshMemory(memoryPath, create) {
82
+ const memoryDir = dirname(memoryPath);
83
+ mkdirSync(memoryDir, { recursive: true });
84
+ await create(memoryPath, "basic");
85
+ }
86
+ function isCorruptedMemoryError(error) {
87
+ const errorMessage = error instanceof Error ? error.message : String(error);
88
+ return errorMessage.includes("Deserialization") || errorMessage.includes("UnexpectedVariant") || errorMessage.includes("Invalid") || errorMessage.includes("corrupt") || errorMessage.includes("version mismatch") || errorMessage.includes("validation failed") || errorMessage.includes("unable to recover") || errorMessage.includes("table of contents");
89
+ }
90
+ async function handleCorruptedMemory(memoryPath, create) {
91
+ console.log(
92
+ "\u26A0\uFE0F Memory file is corrupted or incompatible. Creating fresh memory..."
93
+ );
94
+ const backupPath = `${memoryPath}.backup-${Date.now()}`;
95
+ try {
96
+ renameSync(memoryPath, backupPath);
97
+ console.log(` Old file backed up to: ${backupPath}`);
98
+ } catch {
99
+ try {
100
+ unlinkSync(memoryPath);
101
+ } catch {
102
+ }
103
+ }
104
+ await createFreshMemory(memoryPath, create);
105
+ }
106
+ async function openMemorySafely(memoryPath, use, create) {
107
+ if (!existsSync(memoryPath)) {
108
+ console.log("No memory file found. Creating new memory at:", memoryPath);
109
+ await createFreshMemory(memoryPath, create);
110
+ return { memvid: null, isNew: true };
111
+ }
112
+ try {
113
+ const memvid = await use("basic", memoryPath);
114
+ return { memvid, isNew: false };
115
+ } catch (openError) {
116
+ if (isCorruptedMemoryError(openError)) {
117
+ await handleCorruptedMemory(memoryPath, create);
118
+ return { memvid: null, isNew: true };
119
+ }
120
+ throw openError;
121
+ }
122
+ }
123
+ function resolveScriptMemoryPath(projectDir) {
124
+ const pathPolicy = resolveMemoryPathPolicy({
125
+ projectDir,
126
+ platform: detectPlatformFromEnv(),
127
+ defaultRelativePath: ".agent-brain/mind.mv2",
128
+ legacyRelativePaths: [".claude/mind.mv2"],
129
+ platformRelativePath: process.env.MEMVID_PLATFORM_MEMORY_PATH,
130
+ platformOptIn: process.env.MEMVID_PLATFORM_PATH_OPT_IN === "1"
131
+ });
132
+ if (!pathPolicy.migrationSuggestion) {
133
+ return { memoryPath: pathPolicy.memoryPath };
134
+ }
135
+ const fromDisplay = relative(projectDir, pathPolicy.migrationSuggestion.fromPath) || basename(pathPolicy.migrationSuggestion.fromPath);
136
+ const toDisplay = relative(projectDir, pathPolicy.migrationSuggestion.toPath) || basename(pathPolicy.migrationSuggestion.toPath);
137
+ return {
138
+ memoryPath: pathPolicy.memoryPath,
139
+ migrationPrompt: `mkdir -p "${dirname(toDisplay)}" && mv "${fromDisplay}" "${toDisplay}"`
140
+ };
141
+ }
142
+
143
+ // src/scripts/find.ts
144
+ async function ensureDeps() {
145
+ const __dirname = dirname(fileURLToPath(import.meta.url));
146
+ const pluginRoot = resolve(__dirname, "../..");
147
+ const sdkPath = resolve(pluginRoot, "node_modules/@memvid/sdk");
148
+ if (!existsSync(sdkPath)) {
149
+ console.log("Installing dependencies...");
150
+ try {
151
+ execSync("npm install --production --no-fund --no-audit", {
152
+ cwd: pluginRoot,
153
+ stdio: "inherit",
154
+ timeout: 12e4
155
+ });
156
+ } catch {
157
+ console.error("Failed to install dependencies. Please run: npm install");
158
+ process.exit(1);
159
+ }
160
+ }
161
+ }
162
+ async function loadSDK() {
163
+ await ensureDeps();
164
+ return await import('@memvid/sdk');
165
+ }
166
+ async function main() {
167
+ const args = process.argv.slice(2);
168
+ const query = args[0];
169
+ const limit = parseInt(args[1] || "5", 10);
170
+ if (!query) {
171
+ console.error("Usage: find.js <query> [limit]");
172
+ process.exit(1);
173
+ }
174
+ const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.OPENCODE_PROJECT_DIR || process.cwd();
175
+ const { memoryPath, migrationPrompt } = resolveScriptMemoryPath(projectDir);
176
+ if (migrationPrompt) {
177
+ console.log("Legacy memory detected at .claude/mind.mv2.");
178
+ console.log(`Move it to .agent-brain/mind.mv2? Run: ${migrationPrompt}
179
+ `);
180
+ }
181
+ const { use, create } = await loadSDK();
182
+ const { memvid, isNew } = await openMemorySafely(memoryPath, use, create);
183
+ if (isNew || !memvid) {
184
+ console.log("\u2705 Memory initialized! No memories to search yet.\n");
185
+ process.exit(0);
186
+ }
187
+ try {
188
+ const results = await memvid.find(query, { k: limit, mode: "lex" });
189
+ const hits = results.hits || [];
190
+ if (hits.length === 0) {
191
+ console.log(`No memories found for: "${query}"`);
192
+ process.exit(0);
193
+ }
194
+ console.log(`Found ${results.total_hits || hits.length} memories for: "${query}"
195
+ `);
196
+ for (const hit of hits) {
197
+ const title = hit.title || "Untitled";
198
+ const score = hit.score?.toFixed(2) || "N/A";
199
+ const snippet = (hit.snippet || "").slice(0, 200).replace(/\n/g, " ");
200
+ const labels = hit.labels?.slice(0, 3).join(", ") || "";
201
+ console.log(`[${labels || "memory"}] ${title}`);
202
+ console.log(` Score: ${score} | URI: ${hit.uri || ""}`);
203
+ console.log(` ${snippet}${snippet.length >= 200 ? "..." : ""}`);
204
+ console.log();
205
+ }
206
+ } catch (error) {
207
+ console.error("Error searching memories:", error);
208
+ process.exit(1);
209
+ }
210
+ }
211
+ main();
212
+ //# sourceMappingURL=find.js.map
213
+ //# sourceMappingURL=find.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/platforms/path-policy.ts","../../src/platforms/platform-detector.ts","../../src/scripts/utils.ts","../../src/scripts/find.ts"],"names":["pathRelative","existsSync","dirname","resolve"],"mappings":";;;;;;AA0BA,SAAS,4BAA4B,QAAA,EAA0B;AAC7D,EAAA,MAAM,kBAAA,GAAqB,QAAA,CAAS,IAAA,EAAK,CAAE,WAAA,EAAY;AACvD,EAAA,MAAM,YAAA,GAAe,mBAClB,OAAA,CAAQ,cAAA,EAAgB,GAAG,CAAA,CAC3B,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA,IAAK,SAAA;AAC9B,EAAA,OAAO,qBAAqB,YAAY,CAAA,IAAA,CAAA;AAC1C;AAEA,SAAS,oBAAA,CAAqB,YAAoB,aAAA,EAA+B;AAC/E,EAAA,IAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC7B,IAAA,OAAO,QAAQ,aAAa,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,IAAA,GAAO,QAAQ,UAAU,CAAA;AAC/B,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,IAAA,EAAM,aAAa,CAAA;AAC5C,EAAA,MAAM,GAAA,GAAMA,QAAA,CAAa,IAAA,EAAM,QAAQ,CAAA;AACvC,EAAA,IAAI,QAAQ,IAAA,IAAQ,GAAA,CAAI,WAAW,CAAA,EAAA,EAAK,GAAG,EAAE,CAAA,EAAG;AAC9C,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AACA,EAAA,OAAO,QAAA;AACT;AAEO,SAAS,wBAAwB,KAAA,EAAsD;AAC5F,EAAA,MAAM,IAAA,GAAuB,KAAA,CAAM,aAAA,GAAgB,iBAAA,GAAoB,cAAA;AACvE,EAAA,MAAM,qBAAA,GAAwB,MAAM,aAAA,GAChC,KAAA,CAAM,wBAAwB,2BAAA,CAA4B,KAAA,CAAM,QAAQ,CAAA,GACxE,KAAA,CAAM,mBAAA;AACV,EAAA,MAAM,aAAA,GAAgB,oBAAA,CAAqB,KAAA,CAAM,UAAA,EAAY,qBAAqB,CAAA;AAElF,EAAA,IAAI,UAAA,CAAW,aAAa,CAAA,EAAG;AAC7B,IAAA,OAAO;AAAA,MACL,IAAA;AAAA,MACA,UAAA,EAAY,aAAA;AAAA,MACZ;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAAA,CAAiB,KAAA,CAAM,mBAAA,IAAuB,EAAC,EAClD,GAAA,CAAI,CAAC,YAAA,KAAiB,oBAAA,CAAqB,KAAA,CAAM,UAAA,EAAY,YAAY,CAAC,CAAA;AAE7E,EAAA,KAAA,MAAW,gBAAgB,aAAA,EAAe;AACxC,IAAA,IAAI,UAAA,CAAW,YAAY,CAAA,EAAG;AAC5B,MAAA,OAAO;AAAA,QACL,IAAA;AAAA,QACA,UAAA,EAAY,YAAA;AAAA,QACZ,aAAA;AAAA,QACA,mBAAA,EAAqB;AAAA,UACnB,QAAA,EAAU,YAAA;AAAA,UACV,MAAA,EAAQ;AAAA;AACV,OACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,MAAM,aAAA,EAAe;AACvB,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,iBAAA;AAAA,MACN,UAAA,EAAY,aAAA;AAAA,MACZ;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IACN,UAAA,EAAY,aAAA;AAAA,IACZ;AAAA,GACF;AACF;;;AC1FA,SAAS,kBAAkB,KAAA,EAA+C;AACxE,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,IAAA,EAAK,CAAE,WAAA,EAAY;AAC5C,EAAA,OAAO,UAAA,CAAW,MAAA,GAAS,CAAA,GAAI,UAAA,GAAa,MAAA;AAC9C;AAEO,SAAS,qBAAA,GAAgC;AAC9C,EAAA,MAAM,eAAA,GAAkB,iBAAA,CAAkB,OAAA,CAAQ,GAAA,CAAI,eAAe,CAAA;AACrE,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,OAAO,eAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,GAAA,EAAK;AAChC,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,OAAO,QAAA;AACT;;;ACFA,eAAsB,iBAAA,CACpB,YACA,MAAA,EACe;AACf,EAAA,MAAM,SAAA,GAAY,QAAQ,UAAU,CAAA;AACpC,EAAA,SAAA,CAAU,SAAA,EAAW,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AACxC,EAAA,MAAM,MAAA,CAAO,YAAY,OAAO,CAAA;AAClC;AAKO,SAAS,uBAAuB,KAAA,EAAyB;AAC9D,EAAA,MAAM,eACJ,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACvD,EAAA,OACE,YAAA,CAAa,QAAA,CAAS,iBAAiB,CAAA,IACvC,YAAA,CAAa,QAAA,CAAS,mBAAmB,CAAA,IACzC,YAAA,CAAa,QAAA,CAAS,SAAS,CAAA,IAC/B,aAAa,QAAA,CAAS,SAAS,CAAA,IAC/B,YAAA,CAAa,QAAA,CAAS,kBAAkB,CAAA,IACxC,YAAA,CAAa,QAAA,CAAS,mBAAmB,CAAA,IACzC,YAAA,CAAa,QAAA,CAAS,mBAAmB,CAAA,IACzC,YAAA,CAAa,SAAS,mBAAmB,CAAA;AAE7C;AAKA,eAAsB,qBAAA,CACpB,YACA,MAAA,EACe;AACf,EAAA,OAAA,CAAQ,GAAA;AAAA,IACN;AAAA,GACF;AAEA,EAAA,MAAM,aAAa,CAAA,EAAG,UAAU,CAAA,QAAA,EAAW,IAAA,CAAK,KAAK,CAAA,CAAA;AACrD,EAAA,IAAI;AACF,IAAA,UAAA,CAAW,YAAY,UAAU,CAAA;AACjC,IAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,0BAAA,EAA6B,UAAU,CAAA,CAAE,CAAA;AAAA,EACvD,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI;AACF,MAAA,UAAA,CAAW,UAAU,CAAA;AAAA,IACvB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACA,EAAA,MAAM,iBAAA,CAAkB,YAAY,MAAM,CAAA;AAC5C;AAMA,eAAsB,gBAAA,CACpB,UAAA,EACA,GAAA,EACA,MAAA,EAC8C;AAE9C,EAAA,IAAI,CAACC,UAAAA,CAAW,UAAU,CAAA,EAAG;AAC3B,IAAA,OAAA,CAAQ,GAAA,CAAI,iDAAiD,UAAU,CAAA;AACvE,IAAA,MAAM,iBAAA,CAAkB,YAAY,MAAM,CAAA;AAC1C,IAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,EACrC;AAGA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,MAAM,GAAA,CAAI,OAAA,EAAS,UAAU,CAAA;AAC5C,IAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAM;AAAA,EAChC,SAAS,SAAA,EAAoB;AAC3B,IAAA,IAAI,sBAAA,CAAuB,SAAS,CAAA,EAAG;AACrC,MAAA,MAAM,qBAAA,CAAsB,YAAY,MAAM,CAAA;AAC9C,MAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,IACrC;AAEA,IAAA,MAAM,SAAA;AAAA,EACR;AACF;AAOO,SAAS,wBAAwB,UAAA,EAA4C;AAClF,EAAA,MAAM,aAAa,uBAAA,CAAwB;AAAA,IACzC,UAAA;AAAA,IACA,UAAU,qBAAA,EAAsB;AAAA,IAChC,mBAAA,EAAqB,uBAAA;AAAA,IACrB,mBAAA,EAAqB,CAAC,kBAAkB,CAAA;AAAA,IACxC,oBAAA,EAAsB,QAAQ,GAAA,CAAI,2BAAA;AAAA,IAClC,aAAA,EAAe,OAAA,CAAQ,GAAA,CAAI,2BAAA,KAAgC;AAAA,GAC5D,CAAA;AAED,EAAA,IAAI,CAAC,WAAW,mBAAA,EAAqB;AACnC,IAAA,OAAO,EAAE,UAAA,EAAY,UAAA,CAAW,UAAA,EAAW;AAAA,EAC7C;AAEA,EAAA,MAAM,WAAA,GAAc,QAAA,CAAS,UAAA,EAAY,UAAA,CAAW,mBAAA,CAAoB,QAAQ,CAAA,IAAK,QAAA,CAAS,UAAA,CAAW,mBAAA,CAAoB,QAAQ,CAAA;AACrI,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,UAAA,EAAY,UAAA,CAAW,mBAAA,CAAoB,MAAM,CAAA,IAAK,QAAA,CAAS,UAAA,CAAW,mBAAA,CAAoB,MAAM,CAAA;AAC/H,EAAA,OAAO;AAAA,IACL,YAAY,UAAA,CAAW,UAAA;AAAA,IACvB,eAAA,EAAiB,aAAa,OAAA,CAAQ,SAAS,CAAC,CAAA,SAAA,EAAY,WAAW,MAAM,SAAS,CAAA,CAAA;AAAA,GACxF;AACF;;;AC9GA,eAAe,UAAA,GAAa;AAC1B,EAAA,MAAM,SAAA,GAAYC,OAAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AACxD,EAAA,MAAM,UAAA,GAAaC,OAAAA,CAAQ,SAAA,EAAW,OAAO,CAAA;AAC7C,EAAA,MAAM,OAAA,GAAUA,OAAAA,CAAQ,UAAA,EAAY,0BAA0B,CAAA;AAE9D,EAAA,IAAI,CAACF,UAAAA,CAAW,OAAO,CAAA,EAAG;AACxB,IAAA,OAAA,CAAQ,IAAI,4BAA4B,CAAA;AACxC,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,+CAAA,EAAiD;AAAA,QACxD,GAAA,EAAK,UAAA;AAAA,QACL,KAAA,EAAO,SAAA;AAAA,QACP,OAAA,EAAS;AAAA,OACV,CAAA;AAAA,IACH,CAAA,CAAA,MAAQ;AACN,MAAA,OAAA,CAAQ,MAAM,yDAAyD,CAAA;AACvE,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAAA,EACF;AACF;AAGA,eAAe,OAAA,GAAU;AACvB,EAAA,MAAM,UAAA,EAAW;AACjB,EAAA,OAAO,MAAM,OAAO,aAAa,CAAA;AACnC;AAEA,eAAe,IAAA,GAAO;AACpB,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,KAAK,CAAC,CAAA;AACpB,EAAA,MAAM,QAAQ,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,IAAK,KAAK,EAAE,CAAA;AAEzC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAA,CAAQ,MAAM,gCAAgC,CAAA;AAC9C,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAGA,EAAA,MAAM,UAAA,GAAa,QAAQ,GAAA,CAAI,kBAAA,IAAsB,QAAQ,GAAA,CAAI,oBAAA,IAAwB,QAAQ,GAAA,EAAI;AACrG,EAAA,MAAM,EAAE,UAAA,EAAY,eAAA,EAAgB,GAAI,wBAAwB,UAAU,CAAA;AAE1E,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,OAAA,CAAQ,IAAI,6CAA6C,CAAA;AACzD,IAAA,OAAA,CAAQ,GAAA,CAAI,0CAA0C,eAAe;AAAA,CAAI,CAAA;AAAA,EAC3E;AAGA,EAAA,MAAM,EAAE,GAAA,EAAK,MAAA,EAAO,GAAI,MAAM,OAAA,EAAQ;AAGtC,EAAA,MAAM,EAAE,QAAQ,KAAA,EAAM,GAAI,MAAM,gBAAA,CAAiB,UAAA,EAAY,KAAK,MAAM,CAAA;AAExE,EAAA,IAAI,KAAA,IAAS,CAAC,MAAA,EAAQ;AACpB,IAAA,OAAA,CAAQ,IAAI,yDAAoD,CAAA;AAChE,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AAEA,EAAA,IAAI;AAEF,IAAA,MAAM,OAAA,GAAU,MAAO,MAAA,CAAe,IAAA,CAAK,KAAA,EAAO,EAAE,CAAA,EAAG,KAAA,EAAO,IAAA,EAAM,KAAA,EAAO,CAAA;AAG3E,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,IAAQ,EAAC;AAE9B,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,wBAAA,EAA2B,KAAK,CAAA,CAAA,CAAG,CAAA;AAC/C,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,IAChB;AAEA,IAAA,OAAA,CAAQ,IAAI,CAAA,MAAA,EAAS,OAAA,CAAQ,cAAc,IAAA,CAAK,MAAM,mBAAmB,KAAK,CAAA;AAAA,CAAK,CAAA;AAEnF,IAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,IAAS,UAAA;AAC3B,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,EAAO,OAAA,CAAQ,CAAC,CAAA,IAAK,KAAA;AACvC,MAAA,MAAM,OAAA,GAAA,CAAW,GAAA,CAAI,OAAA,IAAW,EAAA,EAAI,KAAA,CAAM,GAAG,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACpE,MAAA,MAAM,MAAA,GAAS,IAAI,MAAA,EAAQ,KAAA,CAAM,GAAG,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,IAAK,EAAA;AAErD,MAAA,OAAA,CAAQ,IAAI,CAAA,CAAA,EAAI,MAAA,IAAU,QAAQ,CAAA,EAAA,EAAK,KAAK,CAAA,CAAE,CAAA;AAC9C,MAAA,OAAA,CAAQ,IAAI,CAAA,SAAA,EAAY,KAAK,WAAW,GAAA,CAAI,GAAA,IAAO,EAAE,CAAA,CAAE,CAAA;AACvD,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,OAAO,CAAA,EAAG,QAAQ,MAAA,IAAU,GAAA,GAAM,KAAA,GAAQ,EAAE,CAAA,CAAE,CAAA;AAC/D,MAAA,OAAA,CAAQ,GAAA,EAAI;AAAA,IACd;AAAA,EACF,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,6BAA6B,KAAK,CAAA;AAChD,IAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EAChB;AACF;AAEA,IAAA,EAAK","file":"find.js","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { isAbsolute, relative as pathRelative, resolve, sep } from \"node:path\";\n\nexport type MemoryPathMode = \"legacy_first\" | \"platform_opt_in\";\n\nexport interface MemoryPathPolicyInput {\n projectDir: string;\n platform: string;\n defaultRelativePath: string;\n platformRelativePath?: string;\n platformOptIn?: boolean;\n legacyRelativePaths?: string[];\n}\n\nexport interface MemoryMigrationSuggestion {\n fromPath: string;\n toPath: string;\n}\n\nexport interface MemoryPathPolicyResult {\n mode: MemoryPathMode;\n memoryPath: string;\n canonicalPath: string;\n migrationSuggestion?: MemoryMigrationSuggestion;\n}\n\nfunction defaultPlatformRelativePath(platform: string): string {\n const normalizedPlatform = platform.trim().toLowerCase();\n const safePlatform = normalizedPlatform\n .replace(/[^a-z0-9_-]/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"unknown\";\n return `.agent-brain/mind-${safePlatform}.mv2`;\n}\n\nfunction resolveInsideProject(projectDir: string, candidatePath: string): string {\n if (isAbsolute(candidatePath)) {\n return resolve(candidatePath);\n }\n const root = resolve(projectDir);\n const resolved = resolve(root, candidatePath);\n const rel = pathRelative(root, resolved);\n if (rel === \"..\" || rel.startsWith(`..${sep}`)) {\n throw new Error(\"Resolved memory path must stay inside projectDir\");\n }\n return resolved;\n}\n\nexport function resolveMemoryPathPolicy(input: MemoryPathPolicyInput): MemoryPathPolicyResult {\n const mode: MemoryPathMode = input.platformOptIn ? \"platform_opt_in\" : \"legacy_first\";\n const canonicalRelativePath = input.platformOptIn\n ? input.platformRelativePath || defaultPlatformRelativePath(input.platform)\n : input.defaultRelativePath;\n const canonicalPath = resolveInsideProject(input.projectDir, canonicalRelativePath);\n\n if (existsSync(canonicalPath)) {\n return {\n mode,\n memoryPath: canonicalPath,\n canonicalPath,\n };\n }\n\n const fallbackPaths = (input.legacyRelativePaths || [])\n .map((relativePath) => resolveInsideProject(input.projectDir, relativePath));\n\n for (const fallbackPath of fallbackPaths) {\n if (existsSync(fallbackPath)) {\n return {\n mode,\n memoryPath: fallbackPath,\n canonicalPath,\n migrationSuggestion: {\n fromPath: fallbackPath,\n toPath: canonicalPath,\n },\n };\n }\n }\n\n if (input.platformOptIn) {\n return {\n mode: \"platform_opt_in\",\n memoryPath: canonicalPath,\n canonicalPath,\n };\n }\n\n return {\n mode: \"legacy_first\",\n memoryPath: canonicalPath,\n canonicalPath,\n };\n}\n","import type { HookInput } from \"../types.js\";\n\nfunction normalizePlatform(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const normalized = value.trim().toLowerCase();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function detectPlatformFromEnv(): string {\n const explicitFromEnv = normalizePlatform(process.env.MEMVID_PLATFORM);\n if (explicitFromEnv) {\n return explicitFromEnv;\n }\n\n if (process.env.OPENCODE === \"1\") {\n return \"opencode\";\n }\n\n return \"claude\";\n}\n\nexport function detectPlatform(input: HookInput): string {\n const explicitFromHook = normalizePlatform(input.platform);\n if (explicitFromHook) {\n return explicitFromHook;\n }\n\n return detectPlatformFromEnv();\n}\n","/**\n * Shared utilities for Memvid Mind scripts\n */\n\nimport { existsSync, mkdirSync, unlinkSync, renameSync } from \"node:fs\";\nimport { basename, dirname, relative } from \"node:path\";\nimport { resolveMemoryPathPolicy } from \"../platforms/path-policy.js\";\nimport { detectPlatformFromEnv } from \"../platforms/platform-detector.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype CreateFn = (path: string, kind: any) => Promise<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype UseFn = (kind: any, path: string) => Promise<any>;\n\n/**\n * Create a fresh memory file at the given path\n */\nexport async function createFreshMemory(\n memoryPath: string,\n create: CreateFn\n): Promise<void> {\n const memoryDir = dirname(memoryPath);\n mkdirSync(memoryDir, { recursive: true });\n await create(memoryPath, \"basic\");\n}\n\n/**\n * Check if an error indicates a corrupted or incompatible memory file\n */\nexport function isCorruptedMemoryError(error: unknown): boolean {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return (\n errorMessage.includes(\"Deserialization\") ||\n errorMessage.includes(\"UnexpectedVariant\") ||\n errorMessage.includes(\"Invalid\") ||\n errorMessage.includes(\"corrupt\") ||\n errorMessage.includes(\"version mismatch\") ||\n errorMessage.includes(\"validation failed\") ||\n errorMessage.includes(\"unable to recover\") ||\n errorMessage.includes(\"table of contents\")\n );\n}\n\n/**\n * Handle corrupted memory file by backing it up and creating a fresh one\n */\nexport async function handleCorruptedMemory(\n memoryPath: string,\n create: CreateFn\n): Promise<void> {\n console.log(\n \"⚠️ Memory file is corrupted or incompatible. Creating fresh memory...\"\n );\n // Backup corrupted file\n const backupPath = `${memoryPath}.backup-${Date.now()}`;\n try {\n renameSync(memoryPath, backupPath);\n console.log(` Old file backed up to: ${backupPath}`);\n } catch {\n try {\n unlinkSync(memoryPath);\n } catch {\n // Ignore unlink errors\n }\n }\n await createFreshMemory(memoryPath, create);\n}\n\n/**\n * Open a memory file, handling corruption by creating fresh memory if needed\n * Returns the opened memvid instance, or null if memory was recreated (caller should exit)\n */\nexport async function openMemorySafely(\n memoryPath: string,\n use: UseFn,\n create: CreateFn\n): Promise<{ memvid: unknown; isNew: boolean }> {\n // Auto-create if doesn't exist\n if (!existsSync(memoryPath)) {\n console.log(\"No memory file found. Creating new memory at:\", memoryPath);\n await createFreshMemory(memoryPath, create);\n return { memvid: null, isNew: true };\n }\n\n // Try to open, handle corrupted files\n try {\n const memvid = await use(\"basic\", memoryPath);\n return { memvid, isNew: false };\n } catch (openError: unknown) {\n if (isCorruptedMemoryError(openError)) {\n await handleCorruptedMemory(memoryPath, create);\n return { memvid: null, isNew: true };\n }\n // Re-throw other errors\n throw openError;\n }\n}\n\nexport interface ScriptMemoryPathResult {\n memoryPath: string;\n migrationPrompt?: string;\n}\n\nexport function resolveScriptMemoryPath(projectDir: string): ScriptMemoryPathResult {\n const pathPolicy = resolveMemoryPathPolicy({\n projectDir,\n platform: detectPlatformFromEnv(),\n defaultRelativePath: \".agent-brain/mind.mv2\",\n legacyRelativePaths: [\".claude/mind.mv2\"],\n platformRelativePath: process.env.MEMVID_PLATFORM_MEMORY_PATH,\n platformOptIn: process.env.MEMVID_PLATFORM_PATH_OPT_IN === \"1\",\n });\n\n if (!pathPolicy.migrationSuggestion) {\n return { memoryPath: pathPolicy.memoryPath };\n }\n\n const fromDisplay = relative(projectDir, pathPolicy.migrationSuggestion.fromPath) || basename(pathPolicy.migrationSuggestion.fromPath);\n const toDisplay = relative(projectDir, pathPolicy.migrationSuggestion.toPath) || basename(pathPolicy.migrationSuggestion.toPath);\n return {\n memoryPath: pathPolicy.memoryPath,\n migrationPrompt: `mkdir -p \"${dirname(toDisplay)}\" && mv \"${fromDisplay}\" \"${toDisplay}\"`,\n };\n}\n","#!/usr/bin/env node\n/**\n * Memvid Mind - Find Script\n *\n * Search memories using the SDK (no CLI dependency)\n */\n\nimport { existsSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport { openMemorySafely, resolveScriptMemoryPath } from \"./utils.js\";\n\n// Ensure dependencies are installed before importing SDK\nasync function ensureDeps() {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pluginRoot = resolve(__dirname, \"../..\");\n const sdkPath = resolve(pluginRoot, \"node_modules/@memvid/sdk\");\n\n if (!existsSync(sdkPath)) {\n console.log(\"Installing dependencies...\");\n try {\n execSync(\"npm install --production --no-fund --no-audit\", {\n cwd: pluginRoot,\n stdio: \"inherit\",\n timeout: 120000,\n });\n } catch {\n console.error(\"Failed to install dependencies. Please run: npm install\");\n process.exit(1);\n }\n }\n}\n\n// Dynamic import for SDK\nasync function loadSDK() {\n await ensureDeps();\n return await import(\"@memvid/sdk\");\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n const query = args[0];\n const limit = parseInt(args[1] || \"5\", 10);\n\n if (!query) {\n console.error(\"Usage: find.js <query> [limit]\");\n process.exit(1);\n }\n\n // Get memory file path\n const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.OPENCODE_PROJECT_DIR || process.cwd();\n const { memoryPath, migrationPrompt } = resolveScriptMemoryPath(projectDir);\n\n if (migrationPrompt) {\n console.log(\"Legacy memory detected at .claude/mind.mv2.\");\n console.log(`Move it to .agent-brain/mind.mv2? Run: ${migrationPrompt}\\n`);\n }\n\n // Load SDK dynamically\n const { use, create } = await loadSDK();\n\n // Open memory safely (handles corrupted files)\n const { memvid, isNew } = await openMemorySafely(memoryPath, use, create);\n\n if (isNew || !memvid) {\n console.log(\"✅ Memory initialized! No memories to search yet.\\n\");\n process.exit(0);\n }\n\n try {\n // Use lexical-only search with mode: \"lex\" for fast retrieval\n const results = await (memvid as any).find(query, { k: limit, mode: \"lex\" });\n\n // SDK returns { hits: [...], context: ..., total_hits: ... }\n const hits = results.hits || [];\n\n if (hits.length === 0) {\n console.log(`No memories found for: \"${query}\"`);\n process.exit(0);\n }\n\n console.log(`Found ${results.total_hits || hits.length} memories for: \"${query}\"\\n`);\n\n for (const hit of hits) {\n const title = hit.title || \"Untitled\";\n const score = hit.score?.toFixed(2) || \"N/A\";\n const snippet = (hit.snippet || \"\").slice(0, 200).replace(/\\n/g, \" \");\n const labels = hit.labels?.slice(0, 3).join(\", \") || \"\";\n\n console.log(`[${labels || \"memory\"}] ${title}`);\n console.log(` Score: ${score} | URI: ${hit.uri || \"\"}`);\n console.log(` ${snippet}${snippet.length >= 200 ? \"...\" : \"\"}`);\n console.log();\n }\n } catch (error) {\n console.error(\"Error searching memories:\", error);\n process.exit(1);\n }\n}\n\nmain();\n"]}
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, statSync, mkdirSync, renameSync, unlinkSync } from 'fs';
3
+ import { relative, basename, dirname, resolve, isAbsolute, sep } from 'path';
4
+ import { execSync } from 'child_process';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ function defaultPlatformRelativePath(platform) {
8
+ const normalizedPlatform = platform.trim().toLowerCase();
9
+ const safePlatform = normalizedPlatform.replace(/[^a-z0-9_-]/g, "-").replace(/^-+|-+$/g, "") || "unknown";
10
+ return `.agent-brain/mind-${safePlatform}.mv2`;
11
+ }
12
+ function resolveInsideProject(projectDir, candidatePath) {
13
+ if (isAbsolute(candidatePath)) {
14
+ return resolve(candidatePath);
15
+ }
16
+ const root = resolve(projectDir);
17
+ const resolved = resolve(root, candidatePath);
18
+ const rel = relative(root, resolved);
19
+ if (rel === ".." || rel.startsWith(`..${sep}`)) {
20
+ throw new Error("Resolved memory path must stay inside projectDir");
21
+ }
22
+ return resolved;
23
+ }
24
+ function resolveMemoryPathPolicy(input) {
25
+ const mode = input.platformOptIn ? "platform_opt_in" : "legacy_first";
26
+ const canonicalRelativePath = input.platformOptIn ? input.platformRelativePath || defaultPlatformRelativePath(input.platform) : input.defaultRelativePath;
27
+ const canonicalPath = resolveInsideProject(input.projectDir, canonicalRelativePath);
28
+ if (existsSync(canonicalPath)) {
29
+ return {
30
+ mode,
31
+ memoryPath: canonicalPath,
32
+ canonicalPath
33
+ };
34
+ }
35
+ const fallbackPaths = (input.legacyRelativePaths || []).map((relativePath) => resolveInsideProject(input.projectDir, relativePath));
36
+ for (const fallbackPath of fallbackPaths) {
37
+ if (existsSync(fallbackPath)) {
38
+ return {
39
+ mode,
40
+ memoryPath: fallbackPath,
41
+ canonicalPath,
42
+ migrationSuggestion: {
43
+ fromPath: fallbackPath,
44
+ toPath: canonicalPath
45
+ }
46
+ };
47
+ }
48
+ }
49
+ if (input.platformOptIn) {
50
+ return {
51
+ mode: "platform_opt_in",
52
+ memoryPath: canonicalPath,
53
+ canonicalPath
54
+ };
55
+ }
56
+ return {
57
+ mode: "legacy_first",
58
+ memoryPath: canonicalPath,
59
+ canonicalPath
60
+ };
61
+ }
62
+
63
+ // src/platforms/platform-detector.ts
64
+ function normalizePlatform(value) {
65
+ if (!value) return void 0;
66
+ const normalized = value.trim().toLowerCase();
67
+ return normalized.length > 0 ? normalized : void 0;
68
+ }
69
+ function detectPlatformFromEnv() {
70
+ const explicitFromEnv = normalizePlatform(process.env.MEMVID_PLATFORM);
71
+ if (explicitFromEnv) {
72
+ return explicitFromEnv;
73
+ }
74
+ if (process.env.OPENCODE === "1") {
75
+ return "opencode";
76
+ }
77
+ return "claude";
78
+ }
79
+
80
+ // src/scripts/utils.ts
81
+ async function createFreshMemory(memoryPath, create) {
82
+ const memoryDir = dirname(memoryPath);
83
+ mkdirSync(memoryDir, { recursive: true });
84
+ await create(memoryPath, "basic");
85
+ }
86
+ function isCorruptedMemoryError(error) {
87
+ const errorMessage = error instanceof Error ? error.message : String(error);
88
+ return errorMessage.includes("Deserialization") || errorMessage.includes("UnexpectedVariant") || errorMessage.includes("Invalid") || errorMessage.includes("corrupt") || errorMessage.includes("version mismatch") || errorMessage.includes("validation failed") || errorMessage.includes("unable to recover") || errorMessage.includes("table of contents");
89
+ }
90
+ async function handleCorruptedMemory(memoryPath, create) {
91
+ console.log(
92
+ "\u26A0\uFE0F Memory file is corrupted or incompatible. Creating fresh memory..."
93
+ );
94
+ const backupPath = `${memoryPath}.backup-${Date.now()}`;
95
+ try {
96
+ renameSync(memoryPath, backupPath);
97
+ console.log(` Old file backed up to: ${backupPath}`);
98
+ } catch {
99
+ try {
100
+ unlinkSync(memoryPath);
101
+ } catch {
102
+ }
103
+ }
104
+ await createFreshMemory(memoryPath, create);
105
+ }
106
+ async function openMemorySafely(memoryPath, use, create) {
107
+ if (!existsSync(memoryPath)) {
108
+ console.log("No memory file found. Creating new memory at:", memoryPath);
109
+ await createFreshMemory(memoryPath, create);
110
+ return { memvid: null, isNew: true };
111
+ }
112
+ try {
113
+ const memvid = await use("basic", memoryPath);
114
+ return { memvid, isNew: false };
115
+ } catch (openError) {
116
+ if (isCorruptedMemoryError(openError)) {
117
+ await handleCorruptedMemory(memoryPath, create);
118
+ return { memvid: null, isNew: true };
119
+ }
120
+ throw openError;
121
+ }
122
+ }
123
+ function resolveScriptMemoryPath(projectDir) {
124
+ const pathPolicy = resolveMemoryPathPolicy({
125
+ projectDir,
126
+ platform: detectPlatformFromEnv(),
127
+ defaultRelativePath: ".agent-brain/mind.mv2",
128
+ legacyRelativePaths: [".claude/mind.mv2"],
129
+ platformRelativePath: process.env.MEMVID_PLATFORM_MEMORY_PATH,
130
+ platformOptIn: process.env.MEMVID_PLATFORM_PATH_OPT_IN === "1"
131
+ });
132
+ if (!pathPolicy.migrationSuggestion) {
133
+ return { memoryPath: pathPolicy.memoryPath };
134
+ }
135
+ const fromDisplay = relative(projectDir, pathPolicy.migrationSuggestion.fromPath) || basename(pathPolicy.migrationSuggestion.fromPath);
136
+ const toDisplay = relative(projectDir, pathPolicy.migrationSuggestion.toPath) || basename(pathPolicy.migrationSuggestion.toPath);
137
+ return {
138
+ memoryPath: pathPolicy.memoryPath,
139
+ migrationPrompt: `mkdir -p "${dirname(toDisplay)}" && mv "${fromDisplay}" "${toDisplay}"`
140
+ };
141
+ }
142
+
143
+ // src/scripts/stats.ts
144
+ async function ensureDeps() {
145
+ const __dirname = dirname(fileURLToPath(import.meta.url));
146
+ const pluginRoot = resolve(__dirname, "../..");
147
+ const sdkPath = resolve(pluginRoot, "node_modules/@memvid/sdk");
148
+ if (!existsSync(sdkPath)) {
149
+ console.log("Installing dependencies...");
150
+ try {
151
+ execSync("npm install --production --no-fund --no-audit", {
152
+ cwd: pluginRoot,
153
+ stdio: "inherit",
154
+ timeout: 12e4
155
+ });
156
+ } catch {
157
+ console.error("Failed to install dependencies. Please run: npm install");
158
+ process.exit(1);
159
+ }
160
+ }
161
+ }
162
+ async function loadSDK() {
163
+ await ensureDeps();
164
+ return await import('@memvid/sdk');
165
+ }
166
+ function formatBytes(bytes) {
167
+ if (bytes === 0) return "0 B";
168
+ const k = 1024;
169
+ const sizes = ["B", "KB", "MB", "GB"];
170
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
171
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + " " + sizes[i];
172
+ }
173
+ async function main() {
174
+ const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.OPENCODE_PROJECT_DIR || process.cwd();
175
+ const { memoryPath, migrationPrompt } = resolveScriptMemoryPath(projectDir);
176
+ if (migrationPrompt) {
177
+ console.log("Legacy memory detected at .claude/mind.mv2.");
178
+ console.log(`Move it to .agent-brain/mind.mv2? Run: ${migrationPrompt}
179
+ `);
180
+ }
181
+ const { use, create } = await loadSDK();
182
+ const { memvid, isNew } = await openMemorySafely(memoryPath, use, create);
183
+ if (isNew) {
184
+ console.log("\u2705 Memory initialized! Stats will appear as you work.\n");
185
+ }
186
+ if (!memvid) {
187
+ const newMemvid = await use("basic", memoryPath);
188
+ await showStats(newMemvid, memoryPath);
189
+ return;
190
+ }
191
+ await showStats(memvid, memoryPath);
192
+ }
193
+ async function showStats(memvid, memoryPath) {
194
+ try {
195
+ const stats = await memvid.stats();
196
+ const fileStats = statSync(memoryPath);
197
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
198
+ console.log(" MEMVID MIND STATISTICS ");
199
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
200
+ console.log(`\u{1F4C1} Memory File: ${memoryPath}`);
201
+ console.log(`\u{1F4CA} Total Frames: ${stats.frame_count || 0}`);
202
+ console.log(`\u{1F4BE} File Size: ${formatBytes(fileStats.size)}`);
203
+ if (stats.capacity_bytes && typeof stats.capacity_bytes === "number") {
204
+ const usagePercent = (fileStats.size / stats.capacity_bytes * 100).toFixed(1);
205
+ console.log(`\u{1F4C8} Capacity Used: ${usagePercent}%`);
206
+ }
207
+ try {
208
+ const timeline = await memvid.timeline({ limit: 1, reverse: true });
209
+ const frames = Array.isArray(timeline) ? timeline : timeline.frames || [];
210
+ if (frames.length > 0) {
211
+ const latest = frames[0];
212
+ const latestDate = latest.timestamp ? new Date(latest.timestamp * 1e3).toLocaleString() : "Unknown";
213
+ console.log(`\u{1F550} Latest Memory: ${latestDate}`);
214
+ }
215
+ } catch {
216
+ }
217
+ console.log("\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
218
+ } catch (error) {
219
+ console.error("Error getting stats:", error);
220
+ process.exit(1);
221
+ }
222
+ }
223
+ main();
224
+ //# sourceMappingURL=stats.js.map
225
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/platforms/path-policy.ts","../../src/platforms/platform-detector.ts","../../src/scripts/utils.ts","../../src/scripts/stats.ts"],"names":["pathRelative","existsSync","dirname","resolve"],"mappings":"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","file":"stats.js","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { isAbsolute, relative as pathRelative, resolve, sep } from \"node:path\";\n\nexport type MemoryPathMode = \"legacy_first\" | \"platform_opt_in\";\n\nexport interface MemoryPathPolicyInput {\n projectDir: string;\n platform: string;\n defaultRelativePath: string;\n platformRelativePath?: string;\n platformOptIn?: boolean;\n legacyRelativePaths?: string[];\n}\n\nexport interface MemoryMigrationSuggestion {\n fromPath: string;\n toPath: string;\n}\n\nexport interface MemoryPathPolicyResult {\n mode: MemoryPathMode;\n memoryPath: string;\n canonicalPath: string;\n migrationSuggestion?: MemoryMigrationSuggestion;\n}\n\nfunction defaultPlatformRelativePath(platform: string): string {\n const normalizedPlatform = platform.trim().toLowerCase();\n const safePlatform = normalizedPlatform\n .replace(/[^a-z0-9_-]/g, \"-\")\n .replace(/^-+|-+$/g, \"\") || \"unknown\";\n return `.agent-brain/mind-${safePlatform}.mv2`;\n}\n\nfunction resolveInsideProject(projectDir: string, candidatePath: string): string {\n if (isAbsolute(candidatePath)) {\n return resolve(candidatePath);\n }\n const root = resolve(projectDir);\n const resolved = resolve(root, candidatePath);\n const rel = pathRelative(root, resolved);\n if (rel === \"..\" || rel.startsWith(`..${sep}`)) {\n throw new Error(\"Resolved memory path must stay inside projectDir\");\n }\n return resolved;\n}\n\nexport function resolveMemoryPathPolicy(input: MemoryPathPolicyInput): MemoryPathPolicyResult {\n const mode: MemoryPathMode = input.platformOptIn ? \"platform_opt_in\" : \"legacy_first\";\n const canonicalRelativePath = input.platformOptIn\n ? input.platformRelativePath || defaultPlatformRelativePath(input.platform)\n : input.defaultRelativePath;\n const canonicalPath = resolveInsideProject(input.projectDir, canonicalRelativePath);\n\n if (existsSync(canonicalPath)) {\n return {\n mode,\n memoryPath: canonicalPath,\n canonicalPath,\n };\n }\n\n const fallbackPaths = (input.legacyRelativePaths || [])\n .map((relativePath) => resolveInsideProject(input.projectDir, relativePath));\n\n for (const fallbackPath of fallbackPaths) {\n if (existsSync(fallbackPath)) {\n return {\n mode,\n memoryPath: fallbackPath,\n canonicalPath,\n migrationSuggestion: {\n fromPath: fallbackPath,\n toPath: canonicalPath,\n },\n };\n }\n }\n\n if (input.platformOptIn) {\n return {\n mode: \"platform_opt_in\",\n memoryPath: canonicalPath,\n canonicalPath,\n };\n }\n\n return {\n mode: \"legacy_first\",\n memoryPath: canonicalPath,\n canonicalPath,\n };\n}\n","import type { HookInput } from \"../types.js\";\n\nfunction normalizePlatform(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const normalized = value.trim().toLowerCase();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nexport function detectPlatformFromEnv(): string {\n const explicitFromEnv = normalizePlatform(process.env.MEMVID_PLATFORM);\n if (explicitFromEnv) {\n return explicitFromEnv;\n }\n\n if (process.env.OPENCODE === \"1\") {\n return \"opencode\";\n }\n\n return \"claude\";\n}\n\nexport function detectPlatform(input: HookInput): string {\n const explicitFromHook = normalizePlatform(input.platform);\n if (explicitFromHook) {\n return explicitFromHook;\n }\n\n return detectPlatformFromEnv();\n}\n","/**\n * Shared utilities for Memvid Mind scripts\n */\n\nimport { existsSync, mkdirSync, unlinkSync, renameSync } from \"node:fs\";\nimport { basename, dirname, relative } from \"node:path\";\nimport { resolveMemoryPathPolicy } from \"../platforms/path-policy.js\";\nimport { detectPlatformFromEnv } from \"../platforms/platform-detector.js\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype CreateFn = (path: string, kind: any) => Promise<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype UseFn = (kind: any, path: string) => Promise<any>;\n\n/**\n * Create a fresh memory file at the given path\n */\nexport async function createFreshMemory(\n memoryPath: string,\n create: CreateFn\n): Promise<void> {\n const memoryDir = dirname(memoryPath);\n mkdirSync(memoryDir, { recursive: true });\n await create(memoryPath, \"basic\");\n}\n\n/**\n * Check if an error indicates a corrupted or incompatible memory file\n */\nexport function isCorruptedMemoryError(error: unknown): boolean {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return (\n errorMessage.includes(\"Deserialization\") ||\n errorMessage.includes(\"UnexpectedVariant\") ||\n errorMessage.includes(\"Invalid\") ||\n errorMessage.includes(\"corrupt\") ||\n errorMessage.includes(\"version mismatch\") ||\n errorMessage.includes(\"validation failed\") ||\n errorMessage.includes(\"unable to recover\") ||\n errorMessage.includes(\"table of contents\")\n );\n}\n\n/**\n * Handle corrupted memory file by backing it up and creating a fresh one\n */\nexport async function handleCorruptedMemory(\n memoryPath: string,\n create: CreateFn\n): Promise<void> {\n console.log(\n \"⚠️ Memory file is corrupted or incompatible. Creating fresh memory...\"\n );\n // Backup corrupted file\n const backupPath = `${memoryPath}.backup-${Date.now()}`;\n try {\n renameSync(memoryPath, backupPath);\n console.log(` Old file backed up to: ${backupPath}`);\n } catch {\n try {\n unlinkSync(memoryPath);\n } catch {\n // Ignore unlink errors\n }\n }\n await createFreshMemory(memoryPath, create);\n}\n\n/**\n * Open a memory file, handling corruption by creating fresh memory if needed\n * Returns the opened memvid instance, or null if memory was recreated (caller should exit)\n */\nexport async function openMemorySafely(\n memoryPath: string,\n use: UseFn,\n create: CreateFn\n): Promise<{ memvid: unknown; isNew: boolean }> {\n // Auto-create if doesn't exist\n if (!existsSync(memoryPath)) {\n console.log(\"No memory file found. Creating new memory at:\", memoryPath);\n await createFreshMemory(memoryPath, create);\n return { memvid: null, isNew: true };\n }\n\n // Try to open, handle corrupted files\n try {\n const memvid = await use(\"basic\", memoryPath);\n return { memvid, isNew: false };\n } catch (openError: unknown) {\n if (isCorruptedMemoryError(openError)) {\n await handleCorruptedMemory(memoryPath, create);\n return { memvid: null, isNew: true };\n }\n // Re-throw other errors\n throw openError;\n }\n}\n\nexport interface ScriptMemoryPathResult {\n memoryPath: string;\n migrationPrompt?: string;\n}\n\nexport function resolveScriptMemoryPath(projectDir: string): ScriptMemoryPathResult {\n const pathPolicy = resolveMemoryPathPolicy({\n projectDir,\n platform: detectPlatformFromEnv(),\n defaultRelativePath: \".agent-brain/mind.mv2\",\n legacyRelativePaths: [\".claude/mind.mv2\"],\n platformRelativePath: process.env.MEMVID_PLATFORM_MEMORY_PATH,\n platformOptIn: process.env.MEMVID_PLATFORM_PATH_OPT_IN === \"1\",\n });\n\n if (!pathPolicy.migrationSuggestion) {\n return { memoryPath: pathPolicy.memoryPath };\n }\n\n const fromDisplay = relative(projectDir, pathPolicy.migrationSuggestion.fromPath) || basename(pathPolicy.migrationSuggestion.fromPath);\n const toDisplay = relative(projectDir, pathPolicy.migrationSuggestion.toPath) || basename(pathPolicy.migrationSuggestion.toPath);\n return {\n memoryPath: pathPolicy.memoryPath,\n migrationPrompt: `mkdir -p \"${dirname(toDisplay)}\" && mv \"${fromDisplay}\" \"${toDisplay}\"`,\n };\n}\n","#!/usr/bin/env node\n/**\n * Memvid Mind - Stats Script\n *\n * Get memory statistics using the SDK (no CLI dependency)\n */\n\nimport { statSync, existsSync } from \"node:fs\";\nimport { resolve, dirname } from \"node:path\";\nimport { execSync } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport { openMemorySafely, resolveScriptMemoryPath } from \"./utils.js\";\n\n// Ensure dependencies are installed before importing SDK\nasync function ensureDeps() {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pluginRoot = resolve(__dirname, \"../..\");\n const sdkPath = resolve(pluginRoot, \"node_modules/@memvid/sdk\");\n\n if (!existsSync(sdkPath)) {\n console.log(\"Installing dependencies...\");\n try {\n execSync(\"npm install --production --no-fund --no-audit\", {\n cwd: pluginRoot,\n stdio: \"inherit\",\n timeout: 120000,\n });\n } catch {\n console.error(\"Failed to install dependencies. Please run: npm install\");\n process.exit(1);\n }\n }\n}\n\n// Dynamic import for SDK\nasync function loadSDK() {\n await ensureDeps();\n return await import(\"@memvid/sdk\");\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + \" \" + sizes[i];\n}\n\nasync function main() {\n // Get memory file path\n const projectDir = process.env.CLAUDE_PROJECT_DIR || process.env.OPENCODE_PROJECT_DIR || process.cwd();\n const { memoryPath, migrationPrompt } = resolveScriptMemoryPath(projectDir);\n\n if (migrationPrompt) {\n console.log(\"Legacy memory detected at .claude/mind.mv2.\");\n console.log(`Move it to .agent-brain/mind.mv2? Run: ${migrationPrompt}\\n`);\n }\n\n // Load SDK dynamically\n const { use, create } = await loadSDK();\n\n // Open memory safely (handles corrupted files)\n const { memvid, isNew } = await openMemorySafely(memoryPath, use, create);\n\n if (isNew) {\n console.log(\"✅ Memory initialized! Stats will appear as you work.\\n\");\n }\n\n if (!memvid) {\n // Memory was just created, open it to get stats\n const newMemvid = await use(\"basic\", memoryPath);\n await showStats(newMemvid as any, memoryPath);\n return;\n }\n\n await showStats(memvid as any, memoryPath);\n}\n\nasync function showStats(memvid: any, memoryPath: string) {\n try {\n const stats = await memvid.stats();\n const fileStats = statSync(memoryPath);\n\n console.log(\"═══════════════════════════════════════\");\n console.log(\" MEMVID MIND STATISTICS \");\n console.log(\"═══════════════════════════════════════\\n\");\n\n console.log(`📁 Memory File: ${memoryPath}`);\n console.log(`📊 Total Frames: ${stats.frame_count || 0}`);\n console.log(`💾 File Size: ${formatBytes(fileStats.size)}`);\n\n if (stats.capacity_bytes && typeof stats.capacity_bytes === \"number\") {\n const usagePercent = ((fileStats.size / stats.capacity_bytes) * 100).toFixed(1);\n console.log(`📈 Capacity Used: ${usagePercent}%`);\n }\n\n // Get timeline for recent activity\n try {\n const timeline = await memvid.timeline({ limit: 1, reverse: true });\n const frames = Array.isArray(timeline) ? timeline : timeline.frames || [];\n if (frames.length > 0) {\n const latest = frames[0];\n const latestDate = latest.timestamp\n ? new Date(latest.timestamp * 1000).toLocaleString()\n : \"Unknown\";\n console.log(`🕐 Latest Memory: ${latestDate}`);\n }\n } catch {\n // Timeline might not be available\n }\n\n console.log(\"\\n═══════════════════════════════════════\");\n } catch (error) {\n console.error(\"Error getting stats:\", error);\n process.exit(1);\n }\n}\n\nmain();\n"]}