memonaut 0.0.0 → 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 (71) hide show
  1. package/LICENSE +661 -0
  2. package/dist/cli-main.d.ts +3 -0
  3. package/dist/cli-main.d.ts.map +1 -0
  4. package/dist/cli-main.js +428 -0
  5. package/dist/cli-main.js.map +1 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +16 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +38 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +86 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/db.d.ts +37 -0
  15. package/dist/db.d.ts.map +1 -0
  16. package/dist/db.js +184 -0
  17. package/dist/db.js.map +1 -0
  18. package/dist/format.d.ts +22 -0
  19. package/dist/format.d.ts.map +1 -0
  20. package/dist/format.js +130 -0
  21. package/dist/format.js.map +1 -0
  22. package/dist/glob.d.ts +17 -0
  23. package/dist/glob.d.ts.map +1 -0
  24. package/dist/glob.js +77 -0
  25. package/dist/glob.js.map +1 -0
  26. package/dist/index.d.ts +11 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +11 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/indexer.d.ts +50 -0
  31. package/dist/indexer.d.ts.map +1 -0
  32. package/dist/indexer.js +404 -0
  33. package/dist/indexer.js.map +1 -0
  34. package/dist/lineage.d.ts +31 -0
  35. package/dist/lineage.d.ts.map +1 -0
  36. package/dist/lineage.js +94 -0
  37. package/dist/lineage.js.map +1 -0
  38. package/dist/model.d.ts +99 -0
  39. package/dist/model.d.ts.map +1 -0
  40. package/dist/model.js +41 -0
  41. package/dist/model.js.map +1 -0
  42. package/dist/pi-source.d.ts +47 -0
  43. package/dist/pi-source.d.ts.map +1 -0
  44. package/dist/pi-source.js +309 -0
  45. package/dist/pi-source.js.map +1 -0
  46. package/dist/quiet.d.ts +7 -0
  47. package/dist/quiet.d.ts.map +1 -0
  48. package/dist/quiet.js +19 -0
  49. package/dist/quiet.js.map +1 -0
  50. package/dist/search.d.ts +93 -0
  51. package/dist/search.d.ts.map +1 -0
  52. package/dist/search.js +285 -0
  53. package/dist/search.js.map +1 -0
  54. package/dist/silence-sqlite-warning.d.ts +2 -0
  55. package/dist/silence-sqlite-warning.d.ts.map +1 -0
  56. package/dist/silence-sqlite-warning.js +9 -0
  57. package/dist/silence-sqlite-warning.js.map +1 -0
  58. package/package.json +57 -2
  59. package/src/cli-main.ts +475 -0
  60. package/src/cli.ts +17 -0
  61. package/src/config.ts +130 -0
  62. package/src/db.ts +213 -0
  63. package/src/format.ts +173 -0
  64. package/src/glob.ts +79 -0
  65. package/src/index.ts +10 -0
  66. package/src/indexer.ts +534 -0
  67. package/src/lineage.ts +111 -0
  68. package/src/model.ts +135 -0
  69. package/src/pi-source.ts +328 -0
  70. package/src/quiet.ts +22 -0
  71. package/src/search.ts +462 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,mEAAmE;AACnE,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/C,eAAO,MAAM,KAAK,EAAE,IAAI,EAAgC,CAAC;AAEzD,4EAA4E;AAC5E,MAAM,MAAM,SAAS,GAClB,MAAM,GACN,WAAW,GACX,UAAU,GACV,UAAU,GACV,YAAY,GACZ,MAAM,GACN,SAAS,GACT,MAAM,CAAC;AAEV,uDAAuD;AACvD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,CAS7C,CAAC;AAEF,oDAAoD;AACpD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CASjD,CAAC;AAEF,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAChC,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,WAAW;IAC3B,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACb;AAED,6EAA6E;AAC7E,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;CAChB"}
package/dist/model.js ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shared vocabulary.
3
+ *
4
+ * The domain has three nouns that are easy to conflate, so they are named
5
+ * apart here and used consistently everywhere else:
6
+ *
7
+ * - **file**: one transcript file on disk (a pi `.jsonl` session).
8
+ * - **entry**: one message/event inside a transcript. An entry is identified by
9
+ * `(lineage, entryKey)`, NEVER by `entryKey` alone (see `lineage`).
10
+ * - **thread**: a file read as a root-to-leaf path. Forking copies a prefix of
11
+ * entries into a new file, so ONE entry can belong to MANY threads.
12
+ *
13
+ * A **lineage** is a fork family: a root file plus every file transitively
14
+ * forked from it. Entry ids are only 8 hex chars and DO collide across
15
+ * unrelated transcripts (38 measured collisions in a 463k-entry corpus), so the
16
+ * lineage is what makes an entry key meaningful.
17
+ */
18
+ export const TIERS = ['slim', 'default', 'full'];
19
+ /** Lowest tier at which each chunk kind is indexed. */
20
+ export const KIND_TIER = {
21
+ user: 'slim',
22
+ assistant: 'slim',
23
+ summary: 'slim',
24
+ name: 'slim',
25
+ thinking: 'default',
26
+ toolCall: 'default',
27
+ bash: 'default',
28
+ toolResult: 'full',
29
+ };
30
+ /** Relevance multipliers applied on top of bm25. */
31
+ export const KIND_WEIGHT = {
32
+ name: 3,
33
+ user: 2.5,
34
+ summary: 2,
35
+ assistant: 1.5,
36
+ bash: 1,
37
+ toolCall: 0.6,
38
+ thinking: 0.5,
39
+ toolResult: 0.4,
40
+ };
41
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,MAAM,CAAC,MAAM,KAAK,GAAW,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAazD,uDAAuD;AACvD,MAAM,CAAC,MAAM,SAAS,GAA4B;IACjD,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,MAAM;IACf,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,SAAS;IACnB,IAAI,EAAE,SAAS;IACf,UAAU,EAAE,MAAM;CAClB,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAA8B;IACrD,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,GAAG;IACT,OAAO,EAAE,CAAC;IACV,SAAS,EAAE,GAAG;IACd,IAAI,EAAE,CAAC;IACP,QAAQ,EAAE,GAAG;IACb,QAAQ,EAAE,GAAG;IACb,UAAU,EAAE,GAAG;CACf,CAAC"}
@@ -0,0 +1,47 @@
1
+ import type { ParsedEntry, Tier, TranscriptHeader } from './model.js';
2
+ /** Recursively collect transcript files under a root. */
3
+ export declare function listTranscripts(root: string): string[];
4
+ /**
5
+ * FNV-1a over the first bytes of a file: guards the append-only assumption.
6
+ *
7
+ * The token embeds how many bytes were actually hashed, because a transcript
8
+ * shorter than the window grows past it on the next append. `matchesStoredHead`
9
+ * re-hashes exactly that many bytes, so "the prefix is unchanged" stays a real
10
+ * check instead of a coincidence.
11
+ */
12
+ export declare function headFingerprint(file: string, bytes?: number): string;
13
+ /** Read only the first line of a transcript, without loading the whole file. */
14
+ export declare const HEAD_BYTES = 4096;
15
+ /** True when the first bytes of `file` still hash to the stored token. */
16
+ export declare function matchesStoredHead(file: string, stored: string | null | undefined): boolean;
17
+ export declare function readHeader(file: string): TranscriptHeader | null;
18
+ export interface ExtractOptions {
19
+ tier: Tier;
20
+ toolResultHeadBytes: number;
21
+ toolArgsHeadBytes: number;
22
+ }
23
+ /**
24
+ * Turn one raw transcript line into an entry plus its indexable chunks.
25
+ *
26
+ * Returns null for lines that carry no identity (the header) or nothing worth
27
+ * remembering. Non-message entries that still shape a session (`session_info`,
28
+ * `compaction`, `branch_summary`) ARE kept: a session's name and its compaction
29
+ * summaries are some of the highest-signal text in the whole corpus.
30
+ */
31
+ export declare function extractEntry(obj: Record<string, unknown>, byteOffset: number, byteLength: number, opts: ExtractOptions): ParsedEntry | null;
32
+ export interface ParseResult {
33
+ entries: ParsedEntry[];
34
+ /** Byte offset just past the last COMPLETE line consumed. */
35
+ endOffset: number;
36
+ malformed: number;
37
+ }
38
+ /**
39
+ * Parse a transcript from `fromOffset` to the end.
40
+ *
41
+ * A trailing partial line (a session being written right now) is left
42
+ * unconsumed, so `endOffset` is always a safe resume point.
43
+ */
44
+ export declare function parseTranscript(file: string, fromOffset: number, opts: ExtractOptions): ParseResult;
45
+ /** Read one raw line back from a transcript, for on-demand expansion of a hit. */
46
+ export declare function readRawEntry(file: string, byteOffset: number, byteLength: number): unknown | null;
47
+ //# sourceMappingURL=pi-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-source.d.ts","sourceRoot":"","sources":["../src/pi-source.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEX,WAAW,EACX,IAAI,EACJ,gBAAgB,EAChB,MAAM,YAAY,CAAC;AAGpB,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBtD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAa,GAAG,MAAM,CAiBxE;AAED,gFAAgF;AAChF,eAAO,MAAM,UAAU,OAAO,CAAC;AAE/B,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAOT;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAoChE;AAwBD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,IAAI,CAAC;IACX,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;CAC1B;AAQD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC3B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,cAAc,GAClB,WAAW,GAAG,IAAI,CAuGpB;AAED,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,cAAc,GAClB,WAAW,CA2Bb;AAED,kFAAkF;AAClF,wBAAgB,YAAY,CAC3B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAChB,OAAO,GAAG,IAAI,CAYhB"}
@@ -0,0 +1,309 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { KIND_TIER } from './model.js';
4
+ /** Recursively collect transcript files under a root. */
5
+ export function listTranscripts(root) {
6
+ const out = [];
7
+ const walk = (dir) => {
8
+ let entries;
9
+ try {
10
+ entries = fs.readdirSync(dir, { withFileTypes: true });
11
+ }
12
+ catch {
13
+ return;
14
+ }
15
+ for (const e of entries) {
16
+ const full = path.join(dir, e.name);
17
+ if (e.isDirectory())
18
+ walk(full);
19
+ else if (e.isFile() && e.name.endsWith('.jsonl'))
20
+ out.push(full);
21
+ }
22
+ };
23
+ walk(root);
24
+ out.sort();
25
+ return out;
26
+ }
27
+ /**
28
+ * FNV-1a over the first bytes of a file: guards the append-only assumption.
29
+ *
30
+ * The token embeds how many bytes were actually hashed, because a transcript
31
+ * shorter than the window grows past it on the next append. `matchesStoredHead`
32
+ * re-hashes exactly that many bytes, so "the prefix is unchanged" stays a real
33
+ * check instead of a coincidence.
34
+ */
35
+ export function headFingerprint(file, bytes = HEAD_BYTES) {
36
+ let fd;
37
+ try {
38
+ fd = fs.openSync(file, 'r');
39
+ const buf = Buffer.allocUnsafe(bytes);
40
+ const read = fs.readSync(fd, buf, 0, bytes, 0);
41
+ let h = 0x811c9dc5;
42
+ for (let i = 0; i < read; i++) {
43
+ h ^= buf[i];
44
+ h = Math.imul(h, 0x01000193) >>> 0;
45
+ }
46
+ return h.toString(16) + ':' + read;
47
+ }
48
+ catch {
49
+ return '';
50
+ }
51
+ finally {
52
+ if (fd !== undefined)
53
+ fs.closeSync(fd);
54
+ }
55
+ }
56
+ /** Read only the first line of a transcript, without loading the whole file. */
57
+ export const HEAD_BYTES = 4096;
58
+ /** True when the first bytes of `file` still hash to the stored token. */
59
+ export function matchesStoredHead(file, stored) {
60
+ if (!stored)
61
+ return false;
62
+ const colon = stored.lastIndexOf(':');
63
+ if (colon < 0)
64
+ return false;
65
+ const length = Number(stored.slice(colon + 1));
66
+ if (!Number.isFinite(length) || length <= 0)
67
+ return false;
68
+ return headFingerprint(file, length) === stored;
69
+ }
70
+ export function readHeader(file) {
71
+ let fd;
72
+ try {
73
+ fd = fs.openSync(file, 'r');
74
+ const chunks = [];
75
+ const buf = Buffer.allocUnsafe(8192);
76
+ let total = 0;
77
+ while (total < 1 << 20) {
78
+ const read = fs.readSync(fd, buf, 0, buf.length, total);
79
+ if (read <= 0)
80
+ break;
81
+ const slice = buf.subarray(0, read);
82
+ const nl = slice.indexOf(0x0a);
83
+ if (nl >= 0) {
84
+ chunks.push(Buffer.from(slice.subarray(0, nl)));
85
+ break;
86
+ }
87
+ chunks.push(Buffer.from(slice));
88
+ total += read;
89
+ }
90
+ const line = Buffer.concat(chunks).toString('utf8');
91
+ if (!line.trim())
92
+ return null;
93
+ const obj = JSON.parse(line);
94
+ if (obj.type !== 'session')
95
+ return null;
96
+ return {
97
+ sessionUuid: typeof obj.id === 'string' ? obj.id : undefined,
98
+ cwd: typeof obj.cwd === 'string' ? obj.cwd : undefined,
99
+ parentPath: typeof obj.parentSession === 'string' ? obj.parentSession : undefined,
100
+ started: typeof obj.timestamp === 'string' ? obj.timestamp : undefined,
101
+ version: typeof obj.version === 'number' ? obj.version : undefined,
102
+ };
103
+ }
104
+ catch {
105
+ return null;
106
+ }
107
+ finally {
108
+ if (fd !== undefined)
109
+ fs.closeSync(fd);
110
+ }
111
+ }
112
+ function truncate(text, max) {
113
+ if (text.length <= max)
114
+ return text;
115
+ return text.slice(0, max) + `\n…[truncated ${text.length - max} chars]`;
116
+ }
117
+ function textOf(content) {
118
+ if (typeof content === 'string')
119
+ return content;
120
+ if (!Array.isArray(content))
121
+ return '';
122
+ const parts = [];
123
+ for (const c of content) {
124
+ if (typeof c === 'string')
125
+ parts.push(c);
126
+ else if (c &&
127
+ typeof c === 'object' &&
128
+ c.type === 'text') {
129
+ parts.push(String(c.text ?? ''));
130
+ }
131
+ }
132
+ return parts.join('\n');
133
+ }
134
+ const TIER_RANK = { slim: 0, default: 1, full: 2 };
135
+ function wants(kind, tier) {
136
+ return TIER_RANK[KIND_TIER[kind]] <= TIER_RANK[tier];
137
+ }
138
+ /**
139
+ * Turn one raw transcript line into an entry plus its indexable chunks.
140
+ *
141
+ * Returns null for lines that carry no identity (the header) or nothing worth
142
+ * remembering. Non-message entries that still shape a session (`session_info`,
143
+ * `compaction`, `branch_summary`) ARE kept: a session's name and its compaction
144
+ * summaries are some of the highest-signal text in the whole corpus.
145
+ */
146
+ export function extractEntry(obj, byteOffset, byteLength, opts) {
147
+ const entryKey = typeof obj.id === 'string' ? obj.id : null;
148
+ if (!entryKey)
149
+ return null;
150
+ const type = String(obj.type ?? '');
151
+ const base = {
152
+ entryKey,
153
+ parentKey: typeof obj.parentId === 'string' ? obj.parentId : null,
154
+ ts: typeof obj.timestamp === 'string' ? obj.timestamp : null,
155
+ byteOffset,
156
+ byteLength,
157
+ };
158
+ const chunks = [];
159
+ if (type === 'session_info') {
160
+ const name = typeof obj.name === 'string' ? obj.name : '';
161
+ if (name && wants('name', opts.tier))
162
+ chunks.push({ kind: 'name', text: name });
163
+ return {
164
+ ...base,
165
+ role: 'session_info',
166
+ tool: null,
167
+ sessionName: name || undefined,
168
+ chunks,
169
+ };
170
+ }
171
+ if (type === 'compaction' || type === 'branch_summary') {
172
+ const summary = typeof obj.summary === 'string' ? obj.summary : '';
173
+ if (summary && wants('summary', opts.tier))
174
+ chunks.push({ kind: 'summary', text: summary });
175
+ return { ...base, role: type, tool: null, chunks };
176
+ }
177
+ if (type === 'custom_message') {
178
+ const text = textOf(obj.content);
179
+ if (text && wants('assistant', opts.tier))
180
+ chunks.push({ kind: 'assistant', text });
181
+ return { ...base, role: 'custom_message', tool: null, chunks };
182
+ }
183
+ if (type !== 'message') {
184
+ // model_change, thinking_level_change, label, custom: structural only.
185
+ return { ...base, role: type || 'unknown', tool: null, chunks };
186
+ }
187
+ const message = (obj.message ?? {});
188
+ const role = String(message.role ?? 'unknown');
189
+ let tool = null;
190
+ if (role === 'user') {
191
+ const text = textOf(message.content);
192
+ if (text && wants('user', opts.tier))
193
+ chunks.push({ kind: 'user', text });
194
+ }
195
+ else if (role === 'assistant') {
196
+ for (const c of (message.content ?? [])) {
197
+ if (!c || typeof c !== 'object')
198
+ continue;
199
+ if (c.type === 'text' && wants('assistant', opts.tier)) {
200
+ chunks.push({ kind: 'assistant', text: String(c.text ?? '') });
201
+ }
202
+ else if (c.type === 'thinking' && wants('thinking', opts.tier)) {
203
+ chunks.push({ kind: 'thinking', text: String(c.thinking ?? '') });
204
+ }
205
+ else if (c.type === 'toolCall') {
206
+ tool = tool ?? (typeof c.name === 'string' ? c.name : null);
207
+ if (wants('toolCall', opts.tier)) {
208
+ const args = c.arguments === undefined ? '' : JSON.stringify(c.arguments);
209
+ const text = `${String(c.name ?? '')} ${args}`.trim();
210
+ if (text)
211
+ chunks.push({
212
+ kind: 'toolCall',
213
+ text: truncate(text, opts.toolArgsHeadBytes),
214
+ });
215
+ }
216
+ }
217
+ }
218
+ }
219
+ else if (role === 'toolResult') {
220
+ tool = typeof message.toolName === 'string' ? message.toolName : null;
221
+ if (wants('toolResult', opts.tier)) {
222
+ const text = textOf(message.content);
223
+ if (text)
224
+ chunks.push({
225
+ kind: 'toolResult',
226
+ text: truncate(text, opts.toolResultHeadBytes),
227
+ });
228
+ }
229
+ }
230
+ else if (role === 'bashExecution') {
231
+ const command = String(message.command ?? '');
232
+ if (wants('bash', opts.tier)) {
233
+ const output = String(message.output ?? '');
234
+ const text = [command, truncate(output, opts.toolResultHeadBytes)]
235
+ .filter(Boolean)
236
+ .join('\n');
237
+ if (text)
238
+ chunks.push({ kind: 'bash', text });
239
+ }
240
+ }
241
+ else if (role === 'compactionSummary' || role === 'branchSummary') {
242
+ const summary = String(message.summary ?? '');
243
+ if (summary && wants('summary', opts.tier))
244
+ chunks.push({ kind: 'summary', text: summary });
245
+ }
246
+ else if (role === 'custom') {
247
+ const text = textOf(message.content);
248
+ if (text && wants('assistant', opts.tier))
249
+ chunks.push({ kind: 'assistant', text });
250
+ }
251
+ return { ...base, role, tool, chunks };
252
+ }
253
+ /**
254
+ * Parse a transcript from `fromOffset` to the end.
255
+ *
256
+ * A trailing partial line (a session being written right now) is left
257
+ * unconsumed, so `endOffset` is always a safe resume point.
258
+ */
259
+ export function parseTranscript(file, fromOffset, opts) {
260
+ const buf = fs.readFileSync(file);
261
+ const entries = [];
262
+ let malformed = 0;
263
+ let offset = fromOffset;
264
+ let consumed = fromOffset;
265
+ while (offset < buf.length) {
266
+ const nl = buf.indexOf(0x0a, offset);
267
+ if (nl < 0)
268
+ break; // partial trailing line: stop, resume from `consumed`
269
+ const line = buf.subarray(offset, nl).toString('utf8');
270
+ const lineStart = offset;
271
+ offset = nl + 1;
272
+ consumed = offset;
273
+ const trimmed = line.trim();
274
+ if (!trimmed)
275
+ continue;
276
+ let obj;
277
+ try {
278
+ obj = JSON.parse(trimmed);
279
+ }
280
+ catch {
281
+ malformed++;
282
+ continue;
283
+ }
284
+ if (obj.type === 'session')
285
+ continue;
286
+ const entry = extractEntry(obj, lineStart, nl - lineStart, opts);
287
+ if (entry)
288
+ entries.push(entry);
289
+ }
290
+ return { entries, endOffset: consumed, malformed };
291
+ }
292
+ /** Read one raw line back from a transcript, for on-demand expansion of a hit. */
293
+ export function readRawEntry(file, byteOffset, byteLength) {
294
+ let fd;
295
+ try {
296
+ fd = fs.openSync(file, 'r');
297
+ const buf = Buffer.allocUnsafe(byteLength);
298
+ const read = fs.readSync(fd, buf, 0, byteLength, byteOffset);
299
+ return JSON.parse(buf.subarray(0, read).toString('utf8'));
300
+ }
301
+ catch {
302
+ return null;
303
+ }
304
+ finally {
305
+ if (fd !== undefined)
306
+ fs.closeSync(fd);
307
+ }
308
+ }
309
+ //# sourceMappingURL=pi-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-source.js","sourceRoot":"","sources":["../src/pi-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * `node:sqlite` is still flagged experimental and prints a warning on first
3
+ * use. That is noise in a CLI the user runs fifty times a day, so it is
4
+ * silenced here and ONLY here, narrowly: any other warning still gets through.
5
+ */
6
+ export declare function silenceSqliteWarning(): void;
7
+ //# sourceMappingURL=quiet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quiet.d.ts","sourceRoot":"","sources":["../src/quiet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAgB3C"}
package/dist/quiet.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `node:sqlite` is still flagged experimental and prints a warning on first
3
+ * use. That is noise in a CLI the user runs fifty times a day, so it is
4
+ * silenced here and ONLY here, narrowly: any other warning still gets through.
5
+ */
6
+ export function silenceSqliteWarning() {
7
+ const proc = process;
8
+ const original = proc.emit.bind(process);
9
+ proc.emit = (name, ...args) => {
10
+ if (name === 'warning') {
11
+ const warning = args[0];
12
+ if (warning?.name === 'ExperimentalWarning' &&
13
+ /SQLite/i.test(warning.message ?? ''))
14
+ return false;
15
+ }
16
+ return original(name, ...args);
17
+ };
18
+ }
19
+ //# sourceMappingURL=quiet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quiet.js","sourceRoot":"","sources":["../src/quiet.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IACnC,MAAM,IAAI,GAAG,OAEZ,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAY,EAAE,GAAG,IAAe,EAAW,EAAE;QACzD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAkD,CAAC;YACzE,IACC,OAAO,EAAE,IAAI,KAAK,qBAAqB;gBACvC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBAErC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,93 @@
1
+ import type { DB } from './db.js';
2
+ import type { ChunkKind, SearchHit } from './model.js';
3
+ export interface FileRecord {
4
+ id: number;
5
+ path: string;
6
+ source: string;
7
+ session_uuid: string | null;
8
+ cwd: string | null;
9
+ project: string | null;
10
+ name: string | null;
11
+ parent_id: number | null;
12
+ lineage_id: number | null;
13
+ lineage_depth: number;
14
+ orphaned: number;
15
+ private: number;
16
+ started: string | null;
17
+ last_activity: string | null;
18
+ entry_count: number;
19
+ }
20
+ export interface SearchQuery {
21
+ /** FTS5 MATCH expression (see `docs/QUERIES.md`). */
22
+ text: string;
23
+ cwd?: string[];
24
+ project?: string[];
25
+ role?: string[];
26
+ tool?: string[];
27
+ kind?: ChunkKind[];
28
+ since?: string;
29
+ until?: string;
30
+ includePrivate?: boolean;
31
+ limit?: number;
32
+ /** Threads listed per group; the total is always reported. */
33
+ threadLimit?: number;
34
+ /** Disable the recency nudge and rank purely on bm25 x kind weight. */
35
+ noRecency?: boolean;
36
+ /** Pass the query to FTS5 verbatim, never fall back to quoting. */
37
+ raw?: boolean;
38
+ }
39
+ export interface SearchOutcome {
40
+ hits: SearchHit[];
41
+ /** The MATCH expression actually used, after any quoting fallback. */
42
+ usedQuery: string;
43
+ /** Total groups found before `limit` was applied. */
44
+ scanned: number;
45
+ quotedFallback: boolean;
46
+ }
47
+ export declare function loadFiles(db: DB): Map<number, FileRecord>;
48
+ /** Quote every token, turning a hostile string into a valid FTS5 AND query. */
49
+ export declare function quoteQuery(text: string): string;
50
+ export declare function search(db: DB, query: SearchQuery, now?: number): SearchOutcome;
51
+ /** Resolve a user-supplied reference to a thread: file id, uuid prefix, or path. */
52
+ export declare function resolveThread(db: DB, ref: string): FileRecord | null;
53
+ export interface ThreadEntry {
54
+ seq: number;
55
+ entryId: number;
56
+ entryKey: string;
57
+ role: string;
58
+ tool: string | null;
59
+ ts: string | null;
60
+ /** True when this entry was inherited from an ancestor rather than written here. */
61
+ shared: boolean;
62
+ /** Transcript that first recorded this entry, and where it lives verbatim. */
63
+ ownerPath: string | null;
64
+ byteOffset: number;
65
+ byteLength: number;
66
+ texts: Array<{
67
+ kind: ChunkKind;
68
+ text: string;
69
+ }>;
70
+ }
71
+ /**
72
+ * Read one thread back in order.
73
+ *
74
+ * `ownerPath` + byte range is the pointer back to the source transcript. The
75
+ * index deliberately stores tool output truncated (or not at all), so anything
76
+ * that needs full fidelity re-reads those bytes instead of trusting the cache.
77
+ */
78
+ export declare function readThread(db: DB, fileId: number, from?: number, limit?: number): ThreadEntry[];
79
+ export interface IndexStatsRow {
80
+ files: number;
81
+ lineages: number;
82
+ forks: number;
83
+ entries: number;
84
+ memberships: number;
85
+ chunks: number;
86
+ privateFiles: number;
87
+ orphans: number;
88
+ projects: number;
89
+ oldest: string | null;
90
+ newest: string | null;
91
+ }
92
+ export declare function indexStats(db: DB): IndexStatsRow;
93
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}