@fragno-dev/cli 0.1.13 → 0.1.15
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +44 -0
- package/dist/cli.d.ts +52 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +573 -51
- package/dist/cli.js.map +1 -1
- package/package.json +6 -3
- package/src/cli.ts +95 -76
- package/src/commands/corpus.ts +581 -0
- package/src/commands/search.ts +105 -0
- package/src/utils/format-search-results.ts +121 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
interface SearchResult {
|
|
2
|
+
id: string;
|
|
3
|
+
type: "page" | "heading" | "text";
|
|
4
|
+
content: string;
|
|
5
|
+
breadcrumbs?: string[];
|
|
6
|
+
contentWithHighlights?: Array<{
|
|
7
|
+
type: string;
|
|
8
|
+
content: string;
|
|
9
|
+
styles?: { highlight?: boolean };
|
|
10
|
+
}>;
|
|
11
|
+
url: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface MergedResult {
|
|
15
|
+
url: string;
|
|
16
|
+
urlWithMd: string;
|
|
17
|
+
fullUrl: string;
|
|
18
|
+
fullUrlWithMd: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
breadcrumbs?: string[];
|
|
21
|
+
type: "page" | "heading" | "text";
|
|
22
|
+
sections: Array<{
|
|
23
|
+
content: string;
|
|
24
|
+
type: "page" | "heading" | "text";
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Merge search results by URL, grouping sections and content under each URL (without hash)
|
|
30
|
+
*/
|
|
31
|
+
export function mergeResultsByUrl(results: SearchResult[], baseUrl: string): MergedResult[] {
|
|
32
|
+
const mergedMap = new Map<string, MergedResult>();
|
|
33
|
+
|
|
34
|
+
for (const result of results) {
|
|
35
|
+
// Strip hash to get base URL for merging
|
|
36
|
+
const baseUrlWithoutHash = result.url.split("#")[0];
|
|
37
|
+
const existing = mergedMap.get(baseUrlWithoutHash);
|
|
38
|
+
|
|
39
|
+
if (existing) {
|
|
40
|
+
// Add this result as a section
|
|
41
|
+
existing.sections.push({
|
|
42
|
+
content: result.content,
|
|
43
|
+
type: result.type,
|
|
44
|
+
});
|
|
45
|
+
} else {
|
|
46
|
+
// Create new merged result
|
|
47
|
+
const urlWithMd = `${baseUrlWithoutHash}.md`;
|
|
48
|
+
|
|
49
|
+
const fullUrl = `https://${baseUrl}${baseUrlWithoutHash}`;
|
|
50
|
+
const fullUrlWithMd = `https://${baseUrl}${urlWithMd}`;
|
|
51
|
+
|
|
52
|
+
mergedMap.set(baseUrlWithoutHash, {
|
|
53
|
+
url: baseUrlWithoutHash,
|
|
54
|
+
urlWithMd,
|
|
55
|
+
fullUrl,
|
|
56
|
+
fullUrlWithMd,
|
|
57
|
+
title: result.type === "page" ? result.content : undefined,
|
|
58
|
+
breadcrumbs: result.breadcrumbs,
|
|
59
|
+
type: result.type,
|
|
60
|
+
sections: [
|
|
61
|
+
{
|
|
62
|
+
content: result.content,
|
|
63
|
+
type: result.type,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return Array.from(mergedMap.values());
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Format merged results as markdown
|
|
75
|
+
*/
|
|
76
|
+
export function formatAsMarkdown(mergedResults: MergedResult[]): string {
|
|
77
|
+
const lines: string[] = [];
|
|
78
|
+
|
|
79
|
+
for (const result of mergedResults) {
|
|
80
|
+
// Title (use first section content if it's a page, or just use content)
|
|
81
|
+
const title = result.title || result.sections[0]?.content || "Untitled";
|
|
82
|
+
lines.push(`## Page: '${title}'`);
|
|
83
|
+
// Breadcrumbs
|
|
84
|
+
if (result.breadcrumbs && result.breadcrumbs.length > 0) {
|
|
85
|
+
lines.push(" " + result.breadcrumbs.join(" > "));
|
|
86
|
+
lines.push("");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Both URLs
|
|
90
|
+
lines.push("URLs:");
|
|
91
|
+
lines.push(` - ${result.fullUrl}`);
|
|
92
|
+
lines.push(` - ${result.fullUrlWithMd}`);
|
|
93
|
+
lines.push("");
|
|
94
|
+
|
|
95
|
+
// Show all sections found on this page
|
|
96
|
+
if (result.sections.length > 1) {
|
|
97
|
+
lines.push("Relevant sections:");
|
|
98
|
+
for (let i = 0; i < result.sections.length; i++) {
|
|
99
|
+
const section = result.sections[i];
|
|
100
|
+
// Skip the first section if it's just the page title repeated
|
|
101
|
+
if (i === 0 && result.type === "page" && section.content === result.title) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
lines.push(` - ${section.content}`);
|
|
105
|
+
}
|
|
106
|
+
lines.push("");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
lines.push("---");
|
|
110
|
+
lines.push("");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return lines.join("\n");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Format merged results as JSON
|
|
118
|
+
*/
|
|
119
|
+
export function formatAsJson(mergedResults: MergedResult[]): string {
|
|
120
|
+
return JSON.stringify(mergedResults, null, 2);
|
|
121
|
+
}
|