@voidwire/lore 0.1.15 → 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/cli.ts +24 -8
- package/index.ts +2 -0
- package/lib/list.ts +58 -0
- package/lib/semantic.ts +87 -0
- package/package.json +1 -1
package/cli.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
listSources,
|
|
27
27
|
list,
|
|
28
28
|
listDomains,
|
|
29
|
+
formatBriefList,
|
|
29
30
|
info,
|
|
30
31
|
formatInfoHuman,
|
|
31
32
|
projects,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
captureNote,
|
|
35
36
|
captureTeaching,
|
|
36
37
|
semanticSearch,
|
|
38
|
+
formatBriefSearch,
|
|
37
39
|
hasEmbeddings,
|
|
38
40
|
DOMAINS,
|
|
39
41
|
type SearchResult,
|
|
@@ -81,7 +83,7 @@ function parseArgs(args: string[]): Map<string, string> {
|
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
// Boolean flags that don't take values
|
|
84
|
-
const BOOLEAN_FLAGS = new Set(["help", "sources", "domains", "exact"]);
|
|
86
|
+
const BOOLEAN_FLAGS = new Set(["help", "sources", "domains", "exact", "brief"]);
|
|
85
87
|
|
|
86
88
|
function getPositionalArgs(args: string[]): string[] {
|
|
87
89
|
const result: string[] = [];
|
|
@@ -255,14 +257,21 @@ async function handleSearch(args: string[]): Promise<void> {
|
|
|
255
257
|
fail("No embeddings found. Run lore-embed-all first.", 2);
|
|
256
258
|
}
|
|
257
259
|
|
|
260
|
+
const brief = hasFlag(args, "brief");
|
|
261
|
+
|
|
258
262
|
try {
|
|
259
263
|
const results = await semanticSearch(query, { source, limit, project });
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
results
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
|
|
265
|
+
if (brief) {
|
|
266
|
+
console.log(formatBriefSearch(results));
|
|
267
|
+
} else {
|
|
268
|
+
output({
|
|
269
|
+
success: true,
|
|
270
|
+
results,
|
|
271
|
+
count: results.length,
|
|
272
|
+
mode: "semantic",
|
|
273
|
+
});
|
|
274
|
+
}
|
|
266
275
|
console.error(
|
|
267
276
|
`✅ ${results.length} result${results.length !== 1 ? "s" : ""} found (semantic)`,
|
|
268
277
|
);
|
|
@@ -320,11 +329,14 @@ function handleList(args: string[]): void {
|
|
|
320
329
|
: undefined;
|
|
321
330
|
const format = parsed.get("format") || "json";
|
|
322
331
|
const project = parsed.get("project");
|
|
332
|
+
const brief = hasFlag(args, "brief");
|
|
323
333
|
|
|
324
334
|
try {
|
|
325
335
|
const result = list(domain, { limit, project });
|
|
326
336
|
|
|
327
|
-
if (
|
|
337
|
+
if (brief) {
|
|
338
|
+
console.log(formatBriefList(result));
|
|
339
|
+
} else if (format === "human") {
|
|
328
340
|
console.log(formatHumanOutput(result));
|
|
329
341
|
} else if (format === "jsonl") {
|
|
330
342
|
for (const entry of result.entries) {
|
|
@@ -583,6 +595,7 @@ Search Options:
|
|
|
583
595
|
--exact Use FTS5 text search (bypasses semantic search)
|
|
584
596
|
--limit <n> Maximum results (default: 20)
|
|
585
597
|
--project <name> Filter results by project
|
|
598
|
+
--brief Compact output (titles only)
|
|
586
599
|
--since <date> Filter by date (today, yesterday, this-week, YYYY-MM-DD)
|
|
587
600
|
--sources List indexed sources with counts
|
|
588
601
|
|
|
@@ -593,6 +606,7 @@ Passthrough Sources:
|
|
|
593
606
|
List Options:
|
|
594
607
|
--limit <n> Maximum entries
|
|
595
608
|
--format <fmt> Output format: json (default), jsonl, human
|
|
609
|
+
--brief Compact output (titles only)
|
|
596
610
|
--domains List available domains
|
|
597
611
|
|
|
598
612
|
Capture Types:
|
|
@@ -641,6 +655,7 @@ Options:
|
|
|
641
655
|
--exact Use FTS5 text search (bypasses semantic search)
|
|
642
656
|
--limit <n> Maximum results (default: 20)
|
|
643
657
|
--project <name> Filter results by project (post-filters KNN results)
|
|
658
|
+
--brief Compact output (titles only)
|
|
644
659
|
--since <date> Filter by date (today, yesterday, this-week, YYYY-MM-DD)
|
|
645
660
|
--sources List indexed sources with counts
|
|
646
661
|
--help Show this help
|
|
@@ -688,6 +703,7 @@ Options:
|
|
|
688
703
|
--limit <n> Maximum entries (default: all)
|
|
689
704
|
--format <fmt> Output format: json (default), jsonl, human
|
|
690
705
|
--project <name> Filter by project name
|
|
706
|
+
--brief Compact output (titles only)
|
|
691
707
|
--domains List available domains
|
|
692
708
|
--help Show this help
|
|
693
709
|
|
package/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export {
|
|
|
20
20
|
export {
|
|
21
21
|
list,
|
|
22
22
|
listDomains,
|
|
23
|
+
formatBriefList,
|
|
23
24
|
DOMAINS,
|
|
24
25
|
type Domain,
|
|
25
26
|
type ListOptions,
|
|
@@ -70,6 +71,7 @@ export {
|
|
|
70
71
|
// Semantic search
|
|
71
72
|
export {
|
|
72
73
|
semanticSearch,
|
|
74
|
+
formatBriefSearch,
|
|
73
75
|
embedQuery,
|
|
74
76
|
hasEmbeddings,
|
|
75
77
|
type SemanticResult,
|
package/lib/list.ts
CHANGED
|
@@ -209,3 +209,61 @@ export function list(domain: Domain, options: ListOptions = {}): ListResult {
|
|
|
209
209
|
export function listDomains(): Domain[] {
|
|
210
210
|
return [...DOMAINS];
|
|
211
211
|
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Extract project name from entry metadata
|
|
215
|
+
*/
|
|
216
|
+
function extractProjectFromEntry(entry: ListEntry, domain: string): string {
|
|
217
|
+
const field = PROJECT_FIELD[domain];
|
|
218
|
+
if (!field) return "unknown";
|
|
219
|
+
return (entry.metadata[field] as string) || "unknown";
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Extract identifier from entry based on domain type
|
|
224
|
+
*/
|
|
225
|
+
function extractIdentifier(entry: ListEntry, domain: string): string {
|
|
226
|
+
const metadata = entry.metadata;
|
|
227
|
+
|
|
228
|
+
switch (domain) {
|
|
229
|
+
case "commits":
|
|
230
|
+
return (metadata.sha as string)?.substring(0, 7) || "";
|
|
231
|
+
case "sessions":
|
|
232
|
+
return (metadata.session_id as string)?.substring(0, 8) || "";
|
|
233
|
+
default:
|
|
234
|
+
return (metadata.id as string) || "";
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get the best display text for an entry
|
|
240
|
+
* Commits use content (commit message), others use title
|
|
241
|
+
*/
|
|
242
|
+
function getDisplayText(entry: ListEntry, domain: string): string {
|
|
243
|
+
if (domain === "commits") {
|
|
244
|
+
return entry.content || entry.title;
|
|
245
|
+
}
|
|
246
|
+
return entry.title;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Format list result as brief, compact output
|
|
251
|
+
* One line per entry: " project: identifier - title"
|
|
252
|
+
*/
|
|
253
|
+
export function formatBriefList(result: ListResult): string {
|
|
254
|
+
const lines = [`${result.domain} (${result.count}):`];
|
|
255
|
+
|
|
256
|
+
result.entries.forEach((entry) => {
|
|
257
|
+
const project = extractProjectFromEntry(entry, result.domain);
|
|
258
|
+
const identifier = extractIdentifier(entry, result.domain);
|
|
259
|
+
const displayText = getDisplayText(entry, result.domain);
|
|
260
|
+
|
|
261
|
+
const line = identifier
|
|
262
|
+
? ` ${project}: ${identifier} - ${displayText}`
|
|
263
|
+
: ` ${project}: ${displayText}`;
|
|
264
|
+
|
|
265
|
+
lines.push(line);
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
return lines.join("\n");
|
|
269
|
+
}
|
package/lib/semantic.ts
CHANGED
|
@@ -259,3 +259,90 @@ export async function semanticSearch(
|
|
|
259
259
|
db.close();
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Extract project from result metadata
|
|
265
|
+
*/
|
|
266
|
+
function extractProjectFromMetadata(metadata: string, source: string): string {
|
|
267
|
+
const field = PROJECT_FIELD[source];
|
|
268
|
+
if (!field) return "unknown";
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
const parsed = JSON.parse(metadata);
|
|
272
|
+
return parsed[field] || "unknown";
|
|
273
|
+
} catch {
|
|
274
|
+
return "unknown";
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Extract identifier from semantic result
|
|
280
|
+
*/
|
|
281
|
+
function extractIdentifierFromResult(result: SemanticResult): string {
|
|
282
|
+
try {
|
|
283
|
+
const metadata = JSON.parse(result.metadata);
|
|
284
|
+
|
|
285
|
+
switch (result.source) {
|
|
286
|
+
case "commits":
|
|
287
|
+
return metadata.sha?.substring(0, 7) || "";
|
|
288
|
+
case "sessions":
|
|
289
|
+
return metadata.session_id?.substring(0, 8) || "";
|
|
290
|
+
default:
|
|
291
|
+
return metadata.id || "";
|
|
292
|
+
}
|
|
293
|
+
} catch {
|
|
294
|
+
return "";
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Get the best display text for a result
|
|
300
|
+
* Commits use content (commit message), others use title
|
|
301
|
+
*/
|
|
302
|
+
function getDisplayText(result: SemanticResult): string {
|
|
303
|
+
if (result.source === "commits") {
|
|
304
|
+
return result.content || result.title;
|
|
305
|
+
}
|
|
306
|
+
return result.title;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Format semantic search results as brief, compact output
|
|
311
|
+
* Groups by source type, one line per result
|
|
312
|
+
*/
|
|
313
|
+
export function formatBriefSearch(results: SemanticResult[]): string {
|
|
314
|
+
if (results.length === 0) {
|
|
315
|
+
return "(no results)";
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Group results by source
|
|
319
|
+
const grouped = new Map<string, SemanticResult[]>();
|
|
320
|
+
results.forEach((result) => {
|
|
321
|
+
const existing = grouped.get(result.source) || [];
|
|
322
|
+
existing.push(result);
|
|
323
|
+
grouped.set(result.source, existing);
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
const sections: string[] = [];
|
|
327
|
+
|
|
328
|
+
// Format each source group
|
|
329
|
+
grouped.forEach((sourceResults, source) => {
|
|
330
|
+
const lines = [`${source} (${sourceResults.length}):`];
|
|
331
|
+
|
|
332
|
+
sourceResults.forEach((r) => {
|
|
333
|
+
const project = extractProjectFromMetadata(r.metadata, r.source);
|
|
334
|
+
const identifier = extractIdentifierFromResult(r);
|
|
335
|
+
const displayText = getDisplayText(r);
|
|
336
|
+
|
|
337
|
+
const line = identifier
|
|
338
|
+
? ` ${project}: ${identifier} - ${displayText}`
|
|
339
|
+
: ` ${project}: ${displayText}`;
|
|
340
|
+
|
|
341
|
+
lines.push(line);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
sections.push(lines.join("\n"));
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
return sections.join("\n\n");
|
|
348
|
+
}
|