memonaut 0.1.0 → 0.2.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/dist/search.js CHANGED
@@ -17,6 +17,39 @@ export function quoteQuery(text) {
17
17
  const quoted = tokens.map((t) => '"' + t.replace(/"/g, '""') + '"');
18
18
  return quoted.join(' ');
19
19
  }
20
+ /**
21
+ * Which transcripts a query is allowed to see.
22
+ *
23
+ * Visibility is decided per THREAD, because a lineage can in principle span
24
+ * working directories; the lineage set is only a prefilter. Both the FTS and
25
+ * the regex path go through here, so `private` and the cwd/project filters
26
+ * cannot drift apart between them.
27
+ */
28
+ export function visibleSets(files, query) {
29
+ const cwdMatch = query.cwd && query.cwd.length ? matcher(query.cwd) : null;
30
+ const projectMatch = query.project && query.project.length ? new Set(query.project) : null;
31
+ const visibleFiles = new Set();
32
+ const visibleLineages = new Set();
33
+ const totalLineages = new Set();
34
+ for (const file of files.values()) {
35
+ if (file.lineage_id !== null)
36
+ totalLineages.add(Number(file.lineage_id));
37
+ if (!query.includePrivate && file.private)
38
+ continue;
39
+ if (cwdMatch && !cwdMatch(file.cwd))
40
+ continue;
41
+ if (projectMatch && !(file.project && projectMatch.has(file.project)))
42
+ continue;
43
+ visibleFiles.add(Number(file.id));
44
+ if (file.lineage_id !== null)
45
+ visibleLineages.add(Number(file.lineage_id));
46
+ }
47
+ return {
48
+ files: visibleFiles,
49
+ lineages: visibleLineages,
50
+ totalLineages,
51
+ };
52
+ }
20
53
  function inList(column, values) {
21
54
  if (!values || values.length === 0)
22
55
  return { sql: '', args: [] };
@@ -37,27 +70,7 @@ export function search(db, query, now = Date.now()) {
37
70
  const limit = query.limit ?? 20;
38
71
  const threadLimit = query.threadLimit ?? 3;
39
72
  const files = loadFiles(db);
40
- // Visibility is decided per THREAD, because a lineage can in principle span
41
- // working directories. The lineage set below is only a prefilter.
42
- const cwdMatch = query.cwd && query.cwd.length ? matcher(query.cwd) : null;
43
- const projectMatch = query.project && query.project.length ? new Set(query.project) : null;
44
- const visibleFiles = new Set();
45
- const visibleLineages = new Set();
46
- for (const file of files.values()) {
47
- if (!query.includePrivate && file.private)
48
- continue;
49
- if (cwdMatch && !cwdMatch(file.cwd))
50
- continue;
51
- if (projectMatch && !(file.project && projectMatch.has(file.project)))
52
- continue;
53
- visibleFiles.add(Number(file.id));
54
- if (file.lineage_id !== null)
55
- visibleLineages.add(Number(file.lineage_id));
56
- }
57
- const totalLineages = new Set();
58
- for (const file of files.values())
59
- if (file.lineage_id !== null)
60
- totalLineages.add(Number(file.lineage_id));
73
+ const { files: visibleFiles, lineages: visibleLineages, totalLineages, } = visibleSets(files, query);
61
74
  const clauses = [];
62
75
  const args = [];
63
76
  for (const part of [
@@ -161,8 +174,15 @@ export function search(db, query, now = Date.now()) {
161
174
  quotedFallback,
162
175
  };
163
176
  }
164
- function buildHit(row, kind, score, memberStmt, files, visibleFiles, threadLimit) {
165
- const members = memberStmt.all(row.entry_id);
177
+ /**
178
+ * Fan one entry back out to every visible thread that carries it.
179
+ *
180
+ * Shared by the FTS and the regex path, because they must produce identical
181
+ * thread lists: an entry is stored once and `membership` is what turns it back
182
+ * into "the twelve threads that inherited this".
183
+ */
184
+ export function collectThreads(entryId, memberStmt, files, visibleFiles) {
185
+ const members = memberStmt.all(entryId);
166
186
  const threads = [];
167
187
  for (const m of members) {
168
188
  const fileId = Number(m.file_id);
@@ -188,6 +208,10 @@ function buildHit(row, kind, score, memberStmt, files, visibleFiles, threadLimit
188
208
  // active first: when a fork family matches on shared history, the thread you
189
209
  // touched last is the one you almost always mean.
190
210
  threads.sort((a, b) => (b.lastActivity ?? '').localeCompare(a.lastActivity ?? ''));
211
+ return threads;
212
+ }
213
+ function buildHit(row, kind, score, memberStmt, files, visibleFiles, threadLimit) {
214
+ const threads = collectThreads(Number(row.entry_id), memberStmt, files, visibleFiles);
191
215
  if (threads.length === 0)
192
216
  return null;
193
217
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memonaut",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Index and search AI agent conversation transcripts (pi sessions and friends) from the CLI, from agents, and from your own code",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
package/src/cli-main.ts CHANGED
@@ -11,10 +11,16 @@ import {
11
11
  renderTable,
12
12
  relativeTime,
13
13
  tildify,
14
+ type Style,
14
15
  } from './format.js';
15
16
  import {index} from './indexer.js';
16
- import {TIERS, type ChunkKind, type Tier} from './model.js';
17
+ import {TIERS, type ChunkKind, type SearchHit, type Tier} from './model.js';
17
18
  import {readRawEntry} from './pi-source.js';
19
+ import {
20
+ DEFAULT_MAX_MATCHES,
21
+ DEFAULT_MAX_PER_FILE,
22
+ regexSearch,
23
+ } from './regex.js';
18
24
  import {indexStats, readThread, resolveThread, search} from './search.js';
19
25
 
20
26
  const USAGE = `memonaut — search your agent conversation transcripts
@@ -25,6 +31,7 @@ USAGE
25
31
  COMMANDS
26
32
  index Bring the index up to date (incremental by default)
27
33
  search <query...> Search transcripts, grouped by fork lineage
34
+ search --regex <pat> Exact regex search over the original transcripts
28
35
  show <ref> Print a thread (file id, session uuid prefix, name or path)
29
36
  sql <query> Run a read-only SQL query against the index
30
37
  stats Summarise what is indexed
@@ -47,6 +54,22 @@ SEARCH OPTIONS
47
54
  --json Machine-readable output
48
55
  --no-sync Skip the incremental catch-up before querying
49
56
 
57
+ REGEX OPTIONS
58
+ --regex <pattern> Exact regex search, run by ripgrep over the ORIGINAL
59
+ transcripts instead of the index. It can therefore
60
+ match text the index does not hold at all, notably
61
+ tool output (42% of the bytes, excluded by default),
62
+ and it can match inside identifiers, which FTS5
63
+ cannot. There is no relevance ranking: results are
64
+ ordered by recency. Needs ripgrep installed.
65
+ Every filter above applies, and the candidate files
66
+ come from the index, so ignored and (unless --private)
67
+ private transcripts are still never read.
68
+ -i, --ignore-case Case-insensitive matching (put it AFTER the pattern)
69
+ -F, --fixed Treat the pattern as a literal string, not a regex
70
+ --max-per-file <n> Stop after n matches in one transcript (default ${DEFAULT_MAX_PER_FILE}, 0 = all)
71
+ --max-matches <n> Stop the scan after n matching entries (default ${DEFAULT_MAX_MATCHES})
72
+
50
73
  INDEX OPTIONS
51
74
  --full Rebuild from scratch
52
75
  --tier <t> slim | default | full (overrides config for this run)
@@ -61,6 +84,8 @@ EXAMPLES
61
84
  recall search steering queue --project wherever --since 30d
62
85
  recall search '"fork point" OR parentSession' --threads all
63
86
  recall search --tool bash --kind bash 'fuser -k'
87
+ recall search --regex 'ERR_[A-Z_]+' --since 30d
88
+ recall search --regex 'handleToolCall(' --fixed --project wherever
64
89
  recall sql "select project, count(*) n from file group by 1 order by n desc limit 10"
65
90
  `;
66
91
 
@@ -179,10 +204,89 @@ function cmdIndex(argv: string[]): void {
179
204
  );
180
205
  }
181
206
 
182
- function cmdSearch(argv: string[]): void {
207
+ /** Flags that only mean something on the regex path. */
208
+ const REGEX_ONLY_FLAGS = [
209
+ 'ignore-case',
210
+ 'fixed',
211
+ 'max-per-file',
212
+ 'max-matches',
213
+ ];
214
+ /** Flags that only mean something to the full-text ranker. */
215
+ const FTS_ONLY_FLAGS = ['raw', 'no-recency'];
216
+
217
+ /** Numeric flags and the smallest value that means anything for each. */
218
+ const NUMERIC_FLAGS: Array<[string, number]> = [
219
+ ['max-per-file', 0], // 0 is documented as "no per-file cap"
220
+ ['max-matches', 1],
221
+ ];
222
+
223
+ /**
224
+ * Everything about a search that can be judged from the arguments alone.
225
+ *
226
+ * Pure, and exported, so the rules are testable without a process: the whole
227
+ * point of them is to refuse silently-wrong input, and "silently" is exactly
228
+ * what a hand-check misses. `Number('nonsense')` is NaN, and NaN quietly fails
229
+ * every `> 0` guard downstream, so a mistyped cap would REMOVE the bound it was
230
+ * meant to tighten. Those caps are the only thing between a pathological
231
+ * pattern and an unbounded read.
232
+ */
233
+ export function searchFlagError(
234
+ given: Record<string, unknown>,
235
+ text: string,
236
+ pattern: string | undefined,
237
+ ): string | null {
238
+ if (pattern === undefined) {
239
+ if (!text) return 'nothing to search for. Try `recall search <words>`';
240
+ const stray = REGEX_ONLY_FLAGS.find((f) => given[f] !== undefined);
241
+ if (stray) return `--${stray} only applies to --regex`;
242
+ } else {
243
+ if (text)
244
+ return `--regex takes the pattern itself, so "${text}" has nowhere to go. Try \`recall search --regex '${pattern}'\``;
245
+ if (!pattern.trim()) return '--regex needs a pattern';
246
+ const stray = FTS_ONLY_FLAGS.find((f) => given[f] === true);
247
+ if (stray)
248
+ return `--${stray} applies to full-text ranking, and a regex search has no bm25 to rank with`;
249
+ }
250
+ for (const [flag, min] of NUMERIC_FLAGS) {
251
+ const raw = given[flag];
252
+ if (raw === undefined) continue;
253
+ const n = Number(raw);
254
+ if (!Number.isInteger(n) || n < min)
255
+ return `--${flag} needs a whole number ${min} or more, not "${String(raw)}"`;
256
+ }
257
+ return null;
258
+ }
259
+
260
+ /** One rendered block per hit, or a plain reason there are none. */
261
+ function writeHits(
262
+ hits: SearchHit[],
263
+ opts: {style: Style; showPath: boolean},
264
+ nothing: string,
265
+ ): void {
266
+ if (hits.length === 0) {
267
+ process.stdout.write(nothing + '\n');
268
+ return;
269
+ }
270
+ process.stdout.write(
271
+ hits
272
+ .map((hit) =>
273
+ renderHit(hit, {style: opts.style, showPath: opts.showPath}),
274
+ )
275
+ .join('\n\n') + '\n',
276
+ );
277
+ }
278
+
279
+ async function cmdSearch(argv: string[]): Promise<void> {
183
280
  const {values, positionals} = parseArgs({
184
281
  args: argv,
185
282
  options: {
283
+ // No defaults on the mode-specific flags: `undefined` is what makes
284
+ // "you passed this to the wrong search" detectable.
285
+ regex: {type: 'string'},
286
+ 'ignore-case': {type: 'boolean', short: 'i'},
287
+ fixed: {type: 'boolean', short: 'F'},
288
+ 'max-per-file': {type: 'string'},
289
+ 'max-matches': {type: 'string'},
186
290
  cwd: {type: 'string', multiple: true},
187
291
  project: {type: 'string', multiple: true},
188
292
  role: {type: 'string', multiple: true},
@@ -202,15 +306,28 @@ function cmdSearch(argv: string[]): void {
202
306
  allowPositionals: true,
203
307
  });
204
308
  const text = positionals.join(' ').trim();
205
- if (!text) fail('nothing to search for. Try `recall search <words>`');
309
+ const pattern = values.regex as string | undefined;
310
+
311
+ // Everything that can be judged from the arguments alone is judged here,
312
+ // before a config is loaded, an index is synced or a file is opened.
313
+ const given = values as Record<string, unknown>;
314
+ const problem = searchFlagError(given, text, pattern);
315
+ if (problem) fail(problem);
316
+ const maxPerFile =
317
+ given['max-per-file'] === undefined
318
+ ? DEFAULT_MAX_PER_FILE
319
+ : Number(given['max-per-file']);
320
+ const maxMatches =
321
+ given['max-matches'] === undefined
322
+ ? DEFAULT_MAX_MATCHES
323
+ : Number(given['max-matches']);
206
324
 
207
325
  const config = loadConfig();
208
326
  if (!values['no-sync']) sync(config, Boolean(values.json));
209
327
 
210
328
  const db = openDb(config.dbPath, {readOnly: true});
211
329
  const threadsRaw = String(values.threads);
212
- const outcome = search(db, {
213
- text,
330
+ const common = {
214
331
  cwd: values.cwd as string[] | undefined,
215
332
  project: values.project as string[] | undefined,
216
333
  role: values.role as string[] | undefined,
@@ -221,32 +338,58 @@ function cmdSearch(argv: string[]): void {
221
338
  includePrivate: Boolean(values.private),
222
339
  limit: Number(values.limit),
223
340
  threadLimit: threadsRaw === 'all' ? -1 : Number(threadsRaw),
224
- noRecency: Boolean(values['no-recency']),
225
- raw: Boolean(values.raw),
226
- });
341
+ };
342
+ const style = makeStyle(colorsEnabled());
343
+ const render = {style, showPath: Boolean(values.path)};
344
+ const json = (payload: unknown): void => {
345
+ process.stdout.write(JSON.stringify(payload, null, 2) + '\n');
346
+ };
347
+ const note = (line: string): void => {
348
+ process.stderr.write(style.dim(line + '\n'));
349
+ };
227
350
 
228
- if (values.json) {
229
- process.stdout.write(JSON.stringify(outcome, null, 2) + '\n');
230
- db.close();
231
- return;
232
- }
351
+ try {
352
+ if (pattern !== undefined) {
353
+ const outcome = await regexSearch(db, {
354
+ ...common,
355
+ pattern,
356
+ ignoreCase: Boolean(values['ignore-case']),
357
+ fixed: Boolean(values.fixed),
358
+ maxPerFile,
359
+ maxMatches,
360
+ });
361
+ if (values.json) return json(outcome);
362
+ writeHits(
363
+ outcome.hits,
364
+ render,
365
+ `no matches in ${outcome.filesSearched} transcript(s)`,
366
+ );
367
+ if (outcome.truncated)
368
+ note(
369
+ `(stopped at ${maxMatches} matching entries; narrow the pattern or raise --max-matches)`,
370
+ );
371
+ // The index is caught up before the query, so this means the transcripts
372
+ // moved underneath it: worth saying, since those lines were skipped.
373
+ if (outcome.unresolved > 0)
374
+ note(
375
+ `(${outcome.unresolved} matching line(s) are not in the index yet; \`recall index\` will pick them up)`,
376
+ );
377
+ return;
378
+ }
233
379
 
234
- const style = makeStyle(colorsEnabled());
235
- if (outcome.hits.length === 0) {
236
- process.stdout.write('no matches\n');
380
+ const outcome = search(db, {
381
+ ...common,
382
+ text,
383
+ noRecency: Boolean(values['no-recency']),
384
+ raw: Boolean(values.raw),
385
+ });
386
+ if (values.json) return json(outcome);
387
+ if (outcome.quotedFallback)
388
+ note(`(query retried as literal tokens: ${outcome.usedQuery})`);
389
+ writeHits(outcome.hits, render, 'no matches');
390
+ } finally {
237
391
  db.close();
238
- return;
239
392
  }
240
- if (outcome.quotedFallback) {
241
- process.stderr.write(
242
- style.dim(`(query retried as literal tokens: ${outcome.usedQuery})\n`),
243
- );
244
- }
245
- const rendered = outcome.hits.map((hit) =>
246
- renderHit(hit, {style, showPath: Boolean(values.path)}),
247
- );
248
- process.stdout.write(rendered.join('\n\n') + '\n');
249
- db.close();
250
393
  }
251
394
 
252
395
  function cmdShow(argv: string[]): void {
@@ -432,7 +575,7 @@ function cmdConfig(argv: string[]): void {
432
575
  );
433
576
  }
434
577
 
435
- function main(): void {
578
+ async function main(): Promise<void> {
436
579
  const argv = process.argv.slice(2);
437
580
  const command = argv[0];
438
581
  const rest = argv.slice(1);
@@ -466,9 +609,9 @@ function main(): void {
466
609
  }
467
610
 
468
611
  /** Entry point. Loaded dynamically by `cli.ts`, see the note there. */
469
- export function run(): void {
612
+ export async function run(): Promise<void> {
470
613
  try {
471
- main();
614
+ await main();
472
615
  } catch (err) {
473
616
  fail((err as Error).message);
474
617
  }
package/src/cli.ts CHANGED
@@ -14,4 +14,4 @@ import {silenceSqliteWarning} from './quiet.js';
14
14
  silenceSqliteWarning();
15
15
 
16
16
  const {run} = await import('./cli-main.js');
17
- run();
17
+ await run();
package/src/format.ts CHANGED
@@ -117,6 +117,18 @@ export function renderHit(hit: SearchHit, opts: RenderOptions): string {
117
117
  meta.push(
118
118
  `${hit.otherHits} more match${hit.otherHits === 1 ? '' : 'es'} in this lineage`,
119
119
  );
120
+ // The regex path reads the original transcripts, so it can match text no
121
+ // full-text query could reach: a kind the tier excludes (tool output is 42%
122
+ // of the bytes), or text past where a chunk was truncated. Saying so is the
123
+ // difference between a surprising result and an informative one. A match on
124
+ // the JSON scaffolding is NOT that, and has to say something else: the
125
+ // content around it is very probably indexed.
126
+ if (hit.matchedIn === 'transcript') {
127
+ const what = hit.kind ? `this ${hit.kind} text` : 'this text';
128
+ meta.push(`read from the transcript · ${what} is not indexed`);
129
+ } else if (hit.matchedIn === 'structure') {
130
+ meta.push('matched the transcript JSON, not the message text');
131
+ }
120
132
  if (meta.length) lines.push(' ' + style.dim(meta.join(' · ')));
121
133
 
122
134
  for (const thread of hit.threads) {
package/src/index.ts CHANGED
@@ -6,5 +6,14 @@ export * from './pi-source.js';
6
6
  export * from './db.js';
7
7
  export * from './indexer.js';
8
8
  export * from './search.js';
9
+ export * from './regex.js';
10
+ // Only what a caller of `regexSearch` needs: the errors it can throw and the
11
+ // pre-flight check. Spawning rg is an implementation detail, not API.
12
+ export {
13
+ RipgrepError,
14
+ RipgrepMissingError,
15
+ ripgrepAvailable,
16
+ ripgrepBinary,
17
+ } from './ripgrep.js';
9
18
  export * from './format.js';
10
19
  export {silenceSqliteWarning} from './quiet.js';
package/src/model.ts CHANGED
@@ -107,7 +107,13 @@ export interface SearchHit {
107
107
  role: string;
108
108
  tool: string | null;
109
109
  ts: string | null;
110
- kind: ChunkKind;
110
+ /**
111
+ * Which extracted text this hit is about. Always set on the full-text path,
112
+ * where a hit IS a chunk. Absent on the regex path when the match landed
113
+ * outside any extracted text (see `matchedIn`), because inventing a kind
114
+ * there would be a guess presented as a fact.
115
+ */
116
+ kind?: ChunkKind;
111
117
  snippet: string;
112
118
  score: number;
113
119
  /** Threads carrying this entry, most recently active first (may be capped). */
@@ -116,6 +122,22 @@ export interface SearchHit {
116
122
  threadTotal: number;
117
123
  /** Further matches in the same lineage that were folded into this group. */
118
124
  otherHits: number;
125
+ /**
126
+ * Regex path only: where the matched bytes actually live.
127
+ *
128
+ * - `index`: in extracted text that is also indexed, so a full-text query
129
+ * could in principle have found it too.
130
+ * - `transcript`: in what someone actually said or ran, but NOT in the index.
131
+ * Either the tier excludes that kind (tool output, by default) or the text
132
+ * sits past where the chunk was truncated. This is the whole reason to
133
+ * reach for a regex search.
134
+ * - `structure`: in the transcript's JSON scaffolding, a key, an id or an
135
+ * escape sequence, rather than in anything anyone wrote. Distinct from
136
+ * `transcript` on purpose: the content around it may well be indexed, and
137
+ * claiming otherwise would be exactly the dishonesty the flag exists to
138
+ * prevent.
139
+ */
140
+ matchedIn?: 'index' | 'transcript' | 'structure';
119
141
  }
120
142
 
121
143
  export interface ThreadRef {