@bubstack/moe-memory 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.
Files changed (157) hide show
  1. package/.mcp.json +18 -0
  2. package/README.md +47 -0
  3. package/agents/search-conversations.md +171 -0
  4. package/dist/LICENSE +25 -0
  5. package/dist/cli.d.ts +25 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +125 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/codex-hook-trust.d.ts +4 -0
  10. package/dist/codex-hook-trust.d.ts.map +1 -0
  11. package/dist/codex-hook-trust.js +114 -0
  12. package/dist/codex-hook-trust.js.map +1 -0
  13. package/dist/codex-support.d.ts +6 -0
  14. package/dist/codex-support.d.ts.map +1 -0
  15. package/dist/codex-support.js +29 -0
  16. package/dist/codex-support.js.map +1 -0
  17. package/dist/constants.d.ts +14 -0
  18. package/dist/constants.d.ts.map +1 -0
  19. package/dist/constants.js +14 -0
  20. package/dist/constants.js.map +1 -0
  21. package/dist/db.d.ts +103 -0
  22. package/dist/db.d.ts.map +1 -0
  23. package/dist/db.js +430 -0
  24. package/dist/db.js.map +1 -0
  25. package/dist/doctor-cli.d.ts +3 -0
  26. package/dist/doctor-cli.d.ts.map +1 -0
  27. package/dist/doctor-cli.js +43 -0
  28. package/dist/doctor-cli.js.map +1 -0
  29. package/dist/doctor.d.ts +17 -0
  30. package/dist/doctor.d.ts.map +1 -0
  31. package/dist/doctor.js +98 -0
  32. package/dist/doctor.js.map +1 -0
  33. package/dist/embedding-migration.d.ts +73 -0
  34. package/dist/embedding-migration.d.ts.map +1 -0
  35. package/dist/embedding-migration.js +120 -0
  36. package/dist/embedding-migration.js.map +1 -0
  37. package/dist/embeddings.d.ts +78 -0
  38. package/dist/embeddings.d.ts.map +1 -0
  39. package/dist/embeddings.js +180 -0
  40. package/dist/embeddings.js.map +1 -0
  41. package/dist/file-lock.d.ts +39 -0
  42. package/dist/file-lock.d.ts.map +1 -0
  43. package/dist/file-lock.js +91 -0
  44. package/dist/file-lock.js.map +1 -0
  45. package/dist/index-cli.d.ts +10 -0
  46. package/dist/index-cli.d.ts.map +1 -0
  47. package/dist/index-cli.js +195 -0
  48. package/dist/index-cli.js.map +1 -0
  49. package/dist/index.d.ts +12 -0
  50. package/dist/index.d.ts.map +1 -0
  51. package/dist/index.js +19 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/indexer.d.ts +4 -0
  54. package/dist/indexer.d.ts.map +1 -0
  55. package/dist/indexer.js +318 -0
  56. package/dist/indexer.js.map +1 -0
  57. package/dist/install-check.d.ts +48 -0
  58. package/dist/install-check.d.ts.map +1 -0
  59. package/dist/install-check.js +82 -0
  60. package/dist/install-check.js.map +1 -0
  61. package/dist/journal/index.d.ts +5 -0
  62. package/dist/journal/index.d.ts.map +1 -0
  63. package/dist/journal/index.js +5 -0
  64. package/dist/journal/index.js.map +1 -0
  65. package/dist/journal/legacy-sidecars.d.ts +74 -0
  66. package/dist/journal/legacy-sidecars.d.ts.map +1 -0
  67. package/dist/journal/legacy-sidecars.js +151 -0
  68. package/dist/journal/legacy-sidecars.js.map +1 -0
  69. package/dist/journal/markdown.d.ts +91 -0
  70. package/dist/journal/markdown.d.ts.map +1 -0
  71. package/dist/journal/markdown.js +234 -0
  72. package/dist/journal/markdown.js.map +1 -0
  73. package/dist/journal/search.d.ts +91 -0
  74. package/dist/journal/search.d.ts.map +1 -0
  75. package/dist/journal/search.js +203 -0
  76. package/dist/journal/search.js.map +1 -0
  77. package/dist/journal/store.d.ts +96 -0
  78. package/dist/journal/store.d.ts.map +1 -0
  79. package/dist/journal/store.js +270 -0
  80. package/dist/journal/store.js.map +1 -0
  81. package/dist/journal-cli.d.ts +19 -0
  82. package/dist/journal-cli.d.ts.map +1 -0
  83. package/dist/journal-cli.js +153 -0
  84. package/dist/journal-cli.js.map +1 -0
  85. package/dist/logging.d.ts +6 -0
  86. package/dist/logging.d.ts.map +1 -0
  87. package/dist/logging.js +20 -0
  88. package/dist/logging.js.map +1 -0
  89. package/dist/mcp-server.d.ts +34 -0
  90. package/dist/mcp-server.d.ts.map +1 -0
  91. package/dist/mcp-server.js +607 -0
  92. package/dist/mcp-server.js.map +1 -0
  93. package/dist/parser.d.ts +11 -0
  94. package/dist/parser.d.ts.map +1 -0
  95. package/dist/parser.js +445 -0
  96. package/dist/parser.js.map +1 -0
  97. package/dist/paths.d.ts +103 -0
  98. package/dist/paths.d.ts.map +1 -0
  99. package/dist/paths.js +258 -0
  100. package/dist/paths.js.map +1 -0
  101. package/dist/search-cli.d.ts +3 -0
  102. package/dist/search-cli.d.ts.map +1 -0
  103. package/dist/search-cli.js +138 -0
  104. package/dist/search-cli.js.map +1 -0
  105. package/dist/search.d.ts +36 -0
  106. package/dist/search.d.ts.map +1 -0
  107. package/dist/search.js +371 -0
  108. package/dist/search.js.map +1 -0
  109. package/dist/show-cli.d.ts +3 -0
  110. package/dist/show-cli.d.ts.map +1 -0
  111. package/dist/show-cli.js +60 -0
  112. package/dist/show-cli.js.map +1 -0
  113. package/dist/show.d.ts +3 -0
  114. package/dist/show.d.ts.map +1 -0
  115. package/dist/show.js +984 -0
  116. package/dist/show.js.map +1 -0
  117. package/dist/stats-cli.d.ts +3 -0
  118. package/dist/stats-cli.d.ts.map +1 -0
  119. package/dist/stats-cli.js +51 -0
  120. package/dist/stats-cli.js.map +1 -0
  121. package/dist/stats.d.ts +19 -0
  122. package/dist/stats.d.ts.map +1 -0
  123. package/dist/stats.js +116 -0
  124. package/dist/stats.js.map +1 -0
  125. package/dist/summarizer.d.ts +83 -0
  126. package/dist/summarizer.d.ts.map +1 -0
  127. package/dist/summarizer.js +526 -0
  128. package/dist/summarizer.js.map +1 -0
  129. package/dist/summary-sentinel.d.ts +31 -0
  130. package/dist/summary-sentinel.d.ts.map +1 -0
  131. package/dist/summary-sentinel.js +80 -0
  132. package/dist/summary-sentinel.js.map +1 -0
  133. package/dist/sync-cli.d.ts +15 -0
  134. package/dist/sync-cli.d.ts.map +1 -0
  135. package/dist/sync-cli.js +202 -0
  136. package/dist/sync-cli.js.map +1 -0
  137. package/dist/sync.d.ts +35 -0
  138. package/dist/sync.d.ts.map +1 -0
  139. package/dist/sync.js +204 -0
  140. package/dist/sync.js.map +1 -0
  141. package/dist/types.d.ts +125 -0
  142. package/dist/types.d.ts.map +1 -0
  143. package/dist/types.js +32 -0
  144. package/dist/types.js.map +1 -0
  145. package/dist/verify.d.ts +30 -0
  146. package/dist/verify.d.ts.map +1 -0
  147. package/dist/verify.js +174 -0
  148. package/dist/verify.js.map +1 -0
  149. package/dist/version.d.ts +13 -0
  150. package/dist/version.d.ts.map +1 -0
  151. package/dist/version.js +13 -0
  152. package/dist/version.js.map +1 -0
  153. package/hooks/hooks.json +15 -0
  154. package/package.json +71 -0
  155. package/prompts/search-agent.md +160 -0
  156. package/skills/remembering-conversations/MCP-TOOLS.md +147 -0
  157. package/skills/remembering-conversations/SKILL.md +97 -0
package/dist/paths.js ADDED
@@ -0,0 +1,258 @@
1
+ /** Path resolution for transcript archives, indexes, and journals. */
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ /** Project-local journal directory name. */
6
+ export const JOURNAL_DIR_NAME = ".moe-journal";
7
+ /**
8
+ * Ensure a directory exists, creating it if necessary
9
+ */
10
+ function ensureDir(dir) {
11
+ if (!fs.existsSync(dir)) {
12
+ fs.mkdirSync(dir, { recursive: true });
13
+ }
14
+ return dir;
15
+ }
16
+ /**
17
+ * Get the Claude Code configuration directory.
18
+ * Supports CLAUDE_CONFIG_DIR for multiple profiles.
19
+ * Falls back to ~/.claude when not set.
20
+ */
21
+ export function getClaudeDir() {
22
+ return process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
23
+ }
24
+ /**
25
+ * Get the Codex configuration directory.
26
+ * Supports CODEX_HOME for alternate profiles.
27
+ * Falls back to ~/.codex when not set.
28
+ */
29
+ export function getCodexDir() {
30
+ return process.env.CODEX_HOME || path.join(os.homedir(), ".codex");
31
+ }
32
+ /**
33
+ * Get all directories where supported harnesses store conversation files.
34
+ * Checks Claude Code legacy (projects/) and current (transcripts/) locations,
35
+ * plus Codex sessions.
36
+ * Returns only directories that exist.
37
+ */
38
+ export function getConversationSourceDirs() {
39
+ const testDir = process.env.TEST_PROJECTS_DIR;
40
+ if (testDir)
41
+ return [testDir];
42
+ const claudeDir = getClaudeDir();
43
+ const codexDir = getCodexDir();
44
+ return [
45
+ path.join(claudeDir, "projects"),
46
+ path.join(claudeDir, "transcripts"),
47
+ path.join(codexDir, "sessions"),
48
+ ].filter((d) => fs.existsSync(d));
49
+ }
50
+ /**
51
+ * Recursively find all .jsonl files under a directory.
52
+ * Returns paths relative to the given directory.
53
+ *
54
+ * `excludedDirNames` skips any subdirectory whose name matches an entry in
55
+ * the set, at any depth. Top-level project skipping at the caller is the
56
+ * usual case; this parameter handles nested directories like `subagents/`
57
+ * inside session UUIDs (#80).
58
+ */
59
+ export function findJsonlFiles(dir, excludedDirNames) {
60
+ const results = [];
61
+ try {
62
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
63
+ for (const entry of entries) {
64
+ if (entry.isFile() && entry.name.endsWith(".jsonl")) {
65
+ results.push(entry.name);
66
+ }
67
+ else if (entry.isDirectory()) {
68
+ if (excludedDirNames?.has(entry.name))
69
+ continue;
70
+ const subDir = path.join(dir, entry.name);
71
+ for (const f of findJsonlFiles(subDir, excludedDirNames)) {
72
+ results.push(path.join(entry.name, f));
73
+ }
74
+ }
75
+ }
76
+ }
77
+ catch {
78
+ // Directory might not be readable
79
+ }
80
+ return results;
81
+ }
82
+ /**
83
+ * Get this package's data directory: archive, index, model cache, logs, locks
84
+ * and the user-global journal all live under it.
85
+ *
86
+ * Precedence:
87
+ * 1. MOE_MEMORY_CONFIG_DIR — this package's dir directly (also the test seam)
88
+ * 2. MOE_DATA_DIR/memory — the shared cross-package Moe data root
89
+ * 3. XDG_CONFIG_HOME/moe/memory
90
+ * 4. ~/.config/moe/memory (default)
91
+ */
92
+ export function getMemoryDataDir() {
93
+ let dir;
94
+ if (process.env.MOE_MEMORY_CONFIG_DIR) {
95
+ dir = process.env.MOE_MEMORY_CONFIG_DIR;
96
+ }
97
+ else if (process.env.MOE_DATA_DIR) {
98
+ dir = path.join(process.env.MOE_DATA_DIR, "memory");
99
+ }
100
+ else {
101
+ const xdgConfigHome = process.env.XDG_CONFIG_HOME;
102
+ if (xdgConfigHome) {
103
+ dir = path.join(xdgConfigHome, "moe", "memory");
104
+ }
105
+ else {
106
+ dir = path.join(os.homedir(), ".config", "moe", "memory");
107
+ }
108
+ }
109
+ return ensureDir(dir);
110
+ }
111
+ /**
112
+ * Get conversation archive directory
113
+ */
114
+ export function getArchiveDir() {
115
+ // Allow test override
116
+ if (process.env.TEST_ARCHIVE_DIR) {
117
+ return ensureDir(process.env.TEST_ARCHIVE_DIR);
118
+ }
119
+ return ensureDir(path.join(getMemoryDataDir(), "conversation-archive"));
120
+ }
121
+ /**
122
+ * Get conversation index directory
123
+ */
124
+ export function getIndexDir() {
125
+ return ensureDir(path.join(getMemoryDataDir(), "conversation-index"));
126
+ }
127
+ /**
128
+ * Where transformers.js caches the ONNX model.
129
+ *
130
+ * Upstream never set `env.cacheDir`, so the first `initEmbeddings()` fetched
131
+ * the model into whatever transformers.js defaults to — which under pnpm is a
132
+ * path inside the content-addressed store, shared across the workspace and
133
+ * possibly read-only in a container. Pinning it here keeps the download in one
134
+ * writable place that moves with `MOE_MEMORY_CONFIG_DIR`, which is what makes
135
+ * the encoder-dependent test project reproducible.
136
+ */
137
+ export function getModelCacheDir() {
138
+ if (process.env.MOE_MEMORY_MODEL_CACHE_DIR) {
139
+ return ensureDir(process.env.MOE_MEMORY_MODEL_CACHE_DIR);
140
+ }
141
+ return ensureDir(path.join(getMemoryDataDir(), "models"));
142
+ }
143
+ /**
144
+ * Get database path. Both record types live in this one file.
145
+ */
146
+ export function getDbPath() {
147
+ // Allow test override with direct DB path
148
+ const override = process.env.MOE_MEMORY_DB_PATH || process.env.TEST_DB_PATH;
149
+ if (override)
150
+ return override;
151
+ return path.join(getIndexDir(), "db.sqlite");
152
+ }
153
+ /**
154
+ * Get exclude config path
155
+ */
156
+ export function getExcludeConfigPath() {
157
+ return path.join(getIndexDir(), "exclude.txt");
158
+ }
159
+ /**
160
+ * Get list of projects to exclude from indexing
161
+ * Configurable via env var or config file
162
+ */
163
+ export function getExcludedProjects() {
164
+ // Check env variable first
165
+ if (process.env.CONVERSATION_SEARCH_EXCLUDE_PROJECTS) {
166
+ return process.env.CONVERSATION_SEARCH_EXCLUDE_PROJECTS.split(",").map((p) => p.trim());
167
+ }
168
+ // Check for config file
169
+ const configPath = getExcludeConfigPath();
170
+ if (fs.existsSync(configPath)) {
171
+ const content = fs.readFileSync(configPath, "utf-8");
172
+ return content
173
+ .split("\n")
174
+ .map((line) => line.trim())
175
+ .filter((line) => line && !line.startsWith("#"));
176
+ }
177
+ // Default: no exclusions
178
+ return [];
179
+ }
180
+ // ---------------------------------------------------------------------------
181
+ // Journal paths
182
+ // ---------------------------------------------------------------------------
183
+ /** Read the journal-path override. */
184
+ function journalPathOverride() {
185
+ return process.env.MOE_MEMORY_JOURNAL_PATH;
186
+ }
187
+ /**
188
+ * Resolve a writable directory for journal storage.
189
+ *
190
+ * The override wins outright, then cwd (unless cwd is a system root), then
191
+ * HOME, USERPROFILE, and the temp directories.
192
+ *
193
+ * @param subdirectory subdirectory name (e.g. `.moe-journal`)
194
+ * @param includeCurrentDirectory whether to consider the current working directory
195
+ */
196
+ export function resolveJournalPath(subdirectory = JOURNAL_DIR_NAME, includeCurrentDirectory = true) {
197
+ const override = journalPathOverride();
198
+ if (override)
199
+ return override;
200
+ const possiblePaths = [];
201
+ // Try current working directory only if requested and it's reasonable
202
+ if (includeCurrentDirectory) {
203
+ try {
204
+ const cwd = process.cwd();
205
+ // Don't use root directories or other system directories
206
+ if (cwd !== "/" && cwd !== "C:\\" && cwd !== "/System" && cwd !== "/usr") {
207
+ possiblePaths.push(path.join(cwd, subdirectory));
208
+ }
209
+ }
210
+ catch {
211
+ // Ignore errors getting cwd
212
+ }
213
+ }
214
+ // Try home directories (cross-platform)
215
+ if (process.env.HOME) {
216
+ possiblePaths.push(path.join(process.env.HOME, subdirectory));
217
+ }
218
+ if (process.env.USERPROFILE) {
219
+ possiblePaths.push(path.join(process.env.USERPROFILE, subdirectory));
220
+ }
221
+ // Try temp directories as last resort
222
+ possiblePaths.push(path.join("/tmp", subdirectory));
223
+ if (process.env.TEMP) {
224
+ possiblePaths.push(path.join(process.env.TEMP, subdirectory));
225
+ }
226
+ if (process.env.TMP) {
227
+ possiblePaths.push(path.join(process.env.TMP, subdirectory));
228
+ }
229
+ return possiblePaths[0] ?? path.join("/tmp", subdirectory);
230
+ }
231
+ /**
232
+ * Project-local journal directory: `<project>/.moe-journal`.
233
+ * Per-project journals are a feature, not an accident — they are the half of
234
+ * the journal that belongs to the codebase you are in.
235
+ */
236
+ export function resolveProjectJournalPath() {
237
+ return resolveJournalPath(JOURNAL_DIR_NAME, true);
238
+ }
239
+ /**
240
+ * User-global journal directory.
241
+ *
242
+ * It lives at `<data dir>/journal`, alongside the conversation archive and
243
+ * index. `MOE_MEMORY_JOURNAL_PATH` overrides it.
244
+ */
245
+ export function resolveUserJournalPath() {
246
+ const override = journalPathOverride();
247
+ if (override)
248
+ return override;
249
+ return path.join(getMemoryDataDir(), "journal");
250
+ }
251
+ /**
252
+ * The journal roots to read, resolved and de-duplicated.
253
+ */
254
+ export function journalRoots() {
255
+ const roots = [path.resolve(resolveProjectJournalPath()), path.resolve(resolveUserJournalPath())];
256
+ return [...new Set(roots)];
257
+ }
258
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** `moe-memory search` — conversation search from the terminal. */
2
+ export declare function runSearch(args: string[]): Promise<number>;
3
+ //# sourceMappingURL=search-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-cli.d.ts","sourceRoot":"","sources":["../src/search-cli.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAkDnE,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyF/D"}
@@ -0,0 +1,138 @@
1
+ /** `moe-memory search` — conversation search from the terminal. */
2
+ import { formatMultiConceptResults, formatResults, searchConversations, searchMultipleConcepts, } from "./search.js";
3
+ const HELP = `
4
+ Usage: moe-memory search [OPTIONS] <query>
5
+
6
+ Search indexed conversations using semantic similarity or exact text matching.
7
+ For journal entries, use \`moe-memory journal search\`.
8
+
9
+ MODES:
10
+ (default) Combined vector + text search
11
+ --vector Vector similarity only (semantic)
12
+ --text Exact string matching only (for git SHAs, error codes)
13
+
14
+ OPTIONS:
15
+ --after DATE Only conversations after YYYY-MM-DD
16
+ --before DATE Only conversations before YYYY-MM-DD
17
+ --project NAME Filter by project name (exact match)
18
+ --session-id ID Filter by session ID (exact match)
19
+ --git-branch BRANCH Filter by git branch name (exact match)
20
+ --limit N Max results (default: 10)
21
+ --help, -h Show this help
22
+
23
+ EXAMPLES:
24
+ # Semantic search
25
+ moe-memory search "React Router authentication errors"
26
+
27
+ # Find exact string
28
+ moe-memory search --text "a1b2c3d4e5f6"
29
+
30
+ # Time filtering
31
+ moe-memory search --after 2025-09-01 "refactoring"
32
+
33
+ # Filter to one project
34
+ moe-memory search --project my-app "auth flow"
35
+
36
+ # Filter to one git branch
37
+ moe-memory search --git-branch feature/login "validation"
38
+
39
+ # Multi-concept search (AND - all concepts must match)
40
+ moe-memory search "React Router" "authentication" "JWT"
41
+ `;
42
+ export async function runSearch(args) {
43
+ let mode = "both";
44
+ let after;
45
+ let before;
46
+ let project;
47
+ let sessionId;
48
+ let gitBranch;
49
+ let limit = 10;
50
+ const queries = [];
51
+ for (let i = 0; i < args.length; i++) {
52
+ const arg = args[i];
53
+ if (arg === "--help" || arg === "-h") {
54
+ console.log(HELP);
55
+ return 0;
56
+ }
57
+ if (arg === "--vector") {
58
+ mode = "vector";
59
+ }
60
+ else if (arg === "--text") {
61
+ mode = "text";
62
+ }
63
+ else if (arg === "--both") {
64
+ mode = "both";
65
+ }
66
+ else if (arg === "--after") {
67
+ after = args[++i];
68
+ }
69
+ else if (arg === "--before") {
70
+ before = args[++i];
71
+ }
72
+ else if (arg === "--project") {
73
+ project = args[++i];
74
+ }
75
+ else if (arg === "--session-id") {
76
+ sessionId = args[++i];
77
+ }
78
+ else if (arg === "--git-branch") {
79
+ gitBranch = args[++i];
80
+ }
81
+ else if (arg === "--limit") {
82
+ const raw = args[++i];
83
+ const parsed = raw === undefined ? Number.NaN : Number.parseInt(raw, 10);
84
+ // An empty or non-numeric --limit used to become NaN and silently break
85
+ // the query. Reject it instead.
86
+ if (!Number.isFinite(parsed) || parsed < 1) {
87
+ console.error(`Invalid --limit value: ${raw ?? "(missing)"}`);
88
+ return 1;
89
+ }
90
+ limit = parsed;
91
+ }
92
+ else if (arg !== undefined) {
93
+ // All non-flag args are query terms
94
+ queries.push(arg);
95
+ }
96
+ }
97
+ if (queries.length === 0) {
98
+ console.error("Usage: moe-memory search [OPTIONS] <query> [query2] [query3]...");
99
+ console.error("Try: moe-memory search --help");
100
+ return 1;
101
+ }
102
+ try {
103
+ // Multi-concept search if multiple queries provided
104
+ if (queries.length > 1) {
105
+ const options = {
106
+ limit,
107
+ after,
108
+ before,
109
+ project,
110
+ session_id: sessionId,
111
+ git_branch: gitBranch,
112
+ };
113
+ const results = await searchMultipleConcepts(queries, options);
114
+ console.log(await formatMultiConceptResults(results, queries));
115
+ return 0;
116
+ }
117
+ const options = {
118
+ mode,
119
+ limit,
120
+ after,
121
+ before,
122
+ project,
123
+ session_id: sessionId,
124
+ git_branch: gitBranch,
125
+ };
126
+ const first = queries[0];
127
+ if (first === undefined)
128
+ return 1;
129
+ const results = await searchConversations(first, options);
130
+ console.log(await formatResults(results));
131
+ return 0;
132
+ }
133
+ catch (error) {
134
+ console.error("Error searching:", error);
135
+ return 1;
136
+ }
137
+ }
138
+ //# sourceMappingURL=search-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-cli.js","sourceRoot":"","sources":["../src/search-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Conversation-exchange retrieval: sqlite-vec KNN, SQL LIKE, or both.
3
+ *
4
+ * This is the implementation that WON the reconciliation. private-journal-mcp's
5
+ * `search.ts` scanned every `.embedding` JSON sidecar into memory and scored it
6
+ * in JS; journal entries now get rows in the same store and are queried through
7
+ * journal/search.ts, which reuses `l2DistanceToCosineSimilarity` from here.
8
+ */
9
+ import type { MultiConceptResult, SearchResult } from "./types.js";
10
+ export interface SearchOptions {
11
+ limit?: number | undefined;
12
+ mode?: "vector" | "text" | "both" | undefined;
13
+ after?: string | undefined;
14
+ before?: string | undefined;
15
+ project?: string | undefined;
16
+ session_id?: string | undefined;
17
+ git_branch?: string | undefined;
18
+ }
19
+ /**
20
+ * Convert an L2 (Euclidean) distance between two unit-normalized vectors
21
+ * into a cosine similarity in [-1, 1].
22
+ *
23
+ * For unit vectors u, v: ||u - v||^2 = 2 - 2 * cos(u, v)
24
+ * Therefore: cos(u, v) = 1 - d^2 / 2
25
+ *
26
+ * ⚠️ Valid ONLY because src/embeddings.ts passes `normalize: true`. That coupling
27
+ * is invisible to the compiler: flip normalisation and every score here is
28
+ * silently wrong with no type error and no exception. Both record types share the
29
+ * encoder, so both share this constraint — journal/search.ts calls this function.
30
+ */
31
+ export declare function l2DistanceToCosineSimilarity(distance: number): number;
32
+ export declare function searchConversations(query: string, options?: SearchOptions): Promise<SearchResult[]>;
33
+ export declare function formatResults(results: SearchResult[]): Promise<string>;
34
+ export declare function searchMultipleConcepts(concepts: string[], options?: Omit<SearchOptions, "mode">): Promise<MultiConceptResult[]>;
35
+ export declare function formatMultiConceptResults(results: MultiConceptResult[], concepts: string[]): Promise<string>;
36
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAwB,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEzF,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC9C,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAmHD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrE;AAgBD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC,CAyGzB;AAgDD,wBAAsB,aAAa,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0C5E;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,GAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAM,GACxC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA8D/B;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,kBAAkB,EAAE,EAC7B,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,CAyCjB"}