@neuledge/context 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.
- package/LICENSE +202 -0
- package/README.md +484 -0
- package/dist/build.d.ts +25 -0
- package/dist/build.js +309 -0
- package/dist/build.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +454 -0
- package/dist/cli.js.map +1 -0
- package/dist/db.d.ts +4 -0
- package/dist/db.js +24 -0
- package/dist/db.js.map +1 -0
- package/dist/git.d.ts +74 -0
- package/dist/git.js +397 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/package-builder.d.ts +22 -0
- package/dist/package-builder.js +80 -0
- package/dist/package-builder.js.map +1 -0
- package/dist/search.d.ts +12 -0
- package/dist/search.js +152 -0
- package/dist/search.js.map +1 -0
- package/dist/server.d.ts +20 -0
- package/dist/server.js +108 -0
- package/dist/server.js.map +1 -0
- package/dist/store.d.ts +31 -0
- package/dist/store.js +58 -0
- package/dist/store.js.map +1 -0
- package/dist/test-utils.d.ts +17 -0
- package/dist/test-utils.js +37 -0
- package/dist/test-utils.js.map +1 -0
- package/package.json +69 -0
package/dist/git.js
ADDED
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git operations for cloning repositories.
|
|
3
|
+
*/
|
|
4
|
+
// TODO: Future enhancements:
|
|
5
|
+
// - Auto-detect documentation site from README (parse for docs.* or documentation links)
|
|
6
|
+
// - Suggest specific versions when repo has tags (e.g., "context add react --version 18.2.0")
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, } from "node:fs";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import ignore, {} from "ignore";
|
|
13
|
+
/**
|
|
14
|
+
* Generate a content hash for deduplication.
|
|
15
|
+
* Uses first 16 chars of MD5 (sufficient for detecting identical content).
|
|
16
|
+
*/
|
|
17
|
+
function contentHash(content) {
|
|
18
|
+
return createHash("md5").update(content).digest("hex").slice(0, 16);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* ISO 639-1 language codes (2-letter) commonly used in docs.
|
|
22
|
+
* Used to detect and filter locale directories.
|
|
23
|
+
*/
|
|
24
|
+
const LOCALE_CODES = new Set([
|
|
25
|
+
"ar",
|
|
26
|
+
"bg",
|
|
27
|
+
"bn",
|
|
28
|
+
"ca",
|
|
29
|
+
"cs",
|
|
30
|
+
"da",
|
|
31
|
+
"de",
|
|
32
|
+
"el",
|
|
33
|
+
"en",
|
|
34
|
+
"es",
|
|
35
|
+
"et",
|
|
36
|
+
"fa",
|
|
37
|
+
"fi",
|
|
38
|
+
"fr",
|
|
39
|
+
"he",
|
|
40
|
+
"hi",
|
|
41
|
+
"hr",
|
|
42
|
+
"hu",
|
|
43
|
+
"id",
|
|
44
|
+
"it",
|
|
45
|
+
"ja",
|
|
46
|
+
"ko",
|
|
47
|
+
"lt",
|
|
48
|
+
"lv",
|
|
49
|
+
"ms",
|
|
50
|
+
"nl",
|
|
51
|
+
"no",
|
|
52
|
+
"pl",
|
|
53
|
+
"pt",
|
|
54
|
+
"ro",
|
|
55
|
+
"ru",
|
|
56
|
+
"sk",
|
|
57
|
+
"sl",
|
|
58
|
+
"sr",
|
|
59
|
+
"sv",
|
|
60
|
+
"th",
|
|
61
|
+
"tr",
|
|
62
|
+
"uk",
|
|
63
|
+
"vi",
|
|
64
|
+
"zh",
|
|
65
|
+
"zh-cn",
|
|
66
|
+
"zh-tw",
|
|
67
|
+
"zh-hans",
|
|
68
|
+
"zh-hant",
|
|
69
|
+
"pt-br",
|
|
70
|
+
"es-la",
|
|
71
|
+
]);
|
|
72
|
+
/**
|
|
73
|
+
* Check if a directory name looks like a locale code.
|
|
74
|
+
*/
|
|
75
|
+
function isLocaleDir(name) {
|
|
76
|
+
return LOCALE_CODES.has(name.toLowerCase());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Files to ignore during markdown indexing.
|
|
80
|
+
* These are common repo files that aren't useful documentation.
|
|
81
|
+
*/
|
|
82
|
+
const IGNORED_FILES = new Set([
|
|
83
|
+
"code_of_conduct.md",
|
|
84
|
+
"contributing.md",
|
|
85
|
+
"changelog.md",
|
|
86
|
+
"history.md",
|
|
87
|
+
"license.md",
|
|
88
|
+
"security.md",
|
|
89
|
+
"pull_request_template.md",
|
|
90
|
+
"issue_template.md",
|
|
91
|
+
"claude.md", // AI assistant configuration
|
|
92
|
+
]);
|
|
93
|
+
/**
|
|
94
|
+
* Directories to ignore during markdown indexing.
|
|
95
|
+
* Includes test directories, internal docs, and other non-user-facing content.
|
|
96
|
+
*/
|
|
97
|
+
const IGNORED_DIRS = new Set([
|
|
98
|
+
// Test directories
|
|
99
|
+
"__tests__",
|
|
100
|
+
"__test__",
|
|
101
|
+
"test",
|
|
102
|
+
"tests",
|
|
103
|
+
"spec",
|
|
104
|
+
"specs",
|
|
105
|
+
"fixtures",
|
|
106
|
+
"__fixtures__",
|
|
107
|
+
"__mocks__",
|
|
108
|
+
// Internal/development directories
|
|
109
|
+
"internal",
|
|
110
|
+
"dev",
|
|
111
|
+
"plans",
|
|
112
|
+
".plans",
|
|
113
|
+
// Build/generated directories
|
|
114
|
+
"node_modules",
|
|
115
|
+
"dist",
|
|
116
|
+
"build",
|
|
117
|
+
"out",
|
|
118
|
+
".next",
|
|
119
|
+
".nuxt",
|
|
120
|
+
// Other non-doc directories
|
|
121
|
+
"examples", // Often contains code samples, not docs
|
|
122
|
+
"benchmarks",
|
|
123
|
+
"benchmark",
|
|
124
|
+
]);
|
|
125
|
+
/**
|
|
126
|
+
* Check if a string is a git URL (supports various git protocols).
|
|
127
|
+
* Matches: https://, git://, ssh://, git@host:, or .git suffix
|
|
128
|
+
* Excludes: URLs with paths beyond repo root (releases, blob, actions, etc.)
|
|
129
|
+
*/
|
|
130
|
+
export function isGitUrl(source) {
|
|
131
|
+
// https://... or http://... ending with .git
|
|
132
|
+
if (/^https?:\/\/.*\.git$/i.test(source))
|
|
133
|
+
return true;
|
|
134
|
+
// git://...
|
|
135
|
+
if (source.startsWith("git://"))
|
|
136
|
+
return true;
|
|
137
|
+
// ssh://...
|
|
138
|
+
if (source.startsWith("ssh://"))
|
|
139
|
+
return true;
|
|
140
|
+
// git@host:user/repo format (SSH shorthand)
|
|
141
|
+
if (/^git@[\w.-]+:[\w./-]+$/.test(source))
|
|
142
|
+
return true;
|
|
143
|
+
// Known git hosting providers - only match repo root or /tree/ paths
|
|
144
|
+
// Exclude: /releases/, /blob/, /raw/, /actions/, /issues/, /pull/, etc.
|
|
145
|
+
const gitHostMatch = source.match(/^https?:\/\/(github|gitlab|bitbucket|codeberg)\.[^/]+\/[\w.-]+\/[\w.-]+(\/tree\/.*)?$/);
|
|
146
|
+
if (gitHostMatch)
|
|
147
|
+
return true;
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Clone a git repository to a temporary directory.
|
|
152
|
+
*/
|
|
153
|
+
export function cloneRepository(url, ref) {
|
|
154
|
+
const tempDir = mkdtempSync(join(tmpdir(), "context-git-"));
|
|
155
|
+
try {
|
|
156
|
+
// Clone with depth 1 for efficiency (shallow clone)
|
|
157
|
+
const cloneArgs = ["clone", "--depth", "1"];
|
|
158
|
+
if (ref) {
|
|
159
|
+
cloneArgs.push("--branch", ref);
|
|
160
|
+
}
|
|
161
|
+
cloneArgs.push(url, tempDir);
|
|
162
|
+
execSync(`git ${cloneArgs.join(" ")}`, {
|
|
163
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
164
|
+
encoding: "utf-8",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// Clean up on failure
|
|
169
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
170
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
171
|
+
throw new Error(`Git clone failed: ${message}`);
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
tempDir,
|
|
175
|
+
cleanup: () => rmSync(tempDir, { recursive: true, force: true }),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Extract repository name from a git URL.
|
|
180
|
+
* Handles common docs repo patterns:
|
|
181
|
+
* - org.github.io → org
|
|
182
|
+
* - expressjs.com → express
|
|
183
|
+
* - project-docs → project
|
|
184
|
+
*/
|
|
185
|
+
export function extractRepoName(url) {
|
|
186
|
+
// Remove .git suffix if present
|
|
187
|
+
let cleaned = url.replace(/\.git$/, "");
|
|
188
|
+
// Handle SSH shorthand (git@host:user/repo)
|
|
189
|
+
if (cleaned.includes("@") && cleaned.includes(":")) {
|
|
190
|
+
cleaned = cleaned.split(":").pop() ?? cleaned;
|
|
191
|
+
}
|
|
192
|
+
// Get the last path segment (repo name) and org/user
|
|
193
|
+
const segments = cleaned.split("/").filter(Boolean);
|
|
194
|
+
let name = segments.pop() ?? "unknown";
|
|
195
|
+
const org = segments.pop();
|
|
196
|
+
// Handle *.github.io patterns → use org name instead
|
|
197
|
+
if (name.endsWith(".github.io") && org) {
|
|
198
|
+
name = org;
|
|
199
|
+
}
|
|
200
|
+
// Handle domain-style repos (e.g., expressjs.com) → strip TLD and "js" suffix
|
|
201
|
+
else if (/\.(com|org|io|dev|net|site|app)$/i.test(name)) {
|
|
202
|
+
name = name
|
|
203
|
+
.replace(/\.(com|org|io|dev|net|site|app)$/i, "")
|
|
204
|
+
.replace(/js$/i, ""); // expressjs → express (only for domain repos)
|
|
205
|
+
}
|
|
206
|
+
return (name
|
|
207
|
+
.toLowerCase()
|
|
208
|
+
.replace(/\.js$/, "") // express.js → express
|
|
209
|
+
.replace(/-docs?$/, "")
|
|
210
|
+
.replace(/[^a-z0-9-]/g, "-")
|
|
211
|
+
.replace(/-+/g, "-")
|
|
212
|
+
.replace(/^-|-$/g, "") || "unknown");
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Parse git URL to extract optional ref from URL path.
|
|
216
|
+
* Supports: https://github.com/owner/repo/tree/branch
|
|
217
|
+
*/
|
|
218
|
+
export function parseGitUrl(url) {
|
|
219
|
+
// Handle GitHub/GitLab tree paths
|
|
220
|
+
const treeMatch = url.match(/^(https?:\/\/[^/]+\/[^/]+\/[^/]+)\/tree\/(.+)$/);
|
|
221
|
+
if (treeMatch?.[1] && treeMatch[2]) {
|
|
222
|
+
return { url: treeMatch[1], ref: treeMatch[2] };
|
|
223
|
+
}
|
|
224
|
+
return { url };
|
|
225
|
+
}
|
|
226
|
+
const DOCS_FOLDER_CANDIDATES = ["docs", "documentation", "doc"];
|
|
227
|
+
/**
|
|
228
|
+
* Detect docs folder in a local directory.
|
|
229
|
+
*/
|
|
230
|
+
export function detectLocalDocsFolder(dirPath) {
|
|
231
|
+
try {
|
|
232
|
+
const entries = readdirSync(dirPath, { withFileTypes: true });
|
|
233
|
+
const dirs = entries
|
|
234
|
+
.filter((e) => e.isDirectory())
|
|
235
|
+
.map((e) => e.name.toLowerCase());
|
|
236
|
+
for (const candidate of DOCS_FOLDER_CANDIDATES) {
|
|
237
|
+
if (dirs.includes(candidate)) {
|
|
238
|
+
// Return actual case-sensitive name
|
|
239
|
+
const actual = entries.find((e) => e.isDirectory() && e.name.toLowerCase() === candidate);
|
|
240
|
+
return actual?.name ?? null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Directory read failed
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Load .gitignore from a directory if it exists.
|
|
251
|
+
*/
|
|
252
|
+
function loadGitignore(basePath) {
|
|
253
|
+
const ig = ignore();
|
|
254
|
+
const gitignorePath = join(basePath, ".gitignore");
|
|
255
|
+
if (existsSync(gitignorePath)) {
|
|
256
|
+
try {
|
|
257
|
+
const content = readFileSync(gitignorePath, "utf-8");
|
|
258
|
+
ig.add(content);
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
// Ignore read errors
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return ig;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Recursively find all markdown files in a directory.
|
|
268
|
+
* Respects .gitignore rules and skips non-doc files like CODE_OF_CONDUCT.
|
|
269
|
+
* By default, filters out non-English locale directories.
|
|
270
|
+
*/
|
|
271
|
+
function findMarkdownFiles(dirPath, ig, basePath = "", options = {}) {
|
|
272
|
+
const files = [];
|
|
273
|
+
const lang = options.lang?.toLowerCase();
|
|
274
|
+
try {
|
|
275
|
+
const entries = readdirSync(dirPath, { withFileTypes: true });
|
|
276
|
+
for (const entry of entries) {
|
|
277
|
+
const fullPath = join(dirPath, entry.name);
|
|
278
|
+
const relativePath = basePath ? join(basePath, entry.name) : entry.name;
|
|
279
|
+
// Skip hidden entries
|
|
280
|
+
if (entry.name.startsWith("."))
|
|
281
|
+
continue;
|
|
282
|
+
// Check gitignore (directories need trailing slash for gitignore matching)
|
|
283
|
+
const pathToCheck = entry.isDirectory()
|
|
284
|
+
? `${relativePath}/`
|
|
285
|
+
: relativePath;
|
|
286
|
+
if (ig.ignores(pathToCheck))
|
|
287
|
+
continue;
|
|
288
|
+
if (entry.isDirectory()) {
|
|
289
|
+
// Skip test, internal, and other non-doc directories
|
|
290
|
+
if (IGNORED_DIRS.has(entry.name.toLowerCase())) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
// Filter locale directories unless --lang all or specific lang matches
|
|
294
|
+
if (isLocaleDir(entry.name)) {
|
|
295
|
+
const dirName = entry.name.toLowerCase();
|
|
296
|
+
// Include if: all languages, matching lang, or default to English
|
|
297
|
+
if (lang === "all" ||
|
|
298
|
+
lang === dirName ||
|
|
299
|
+
(!lang && dirName === "en")) {
|
|
300
|
+
files.push(...findMarkdownFiles(fullPath, ig, relativePath, options));
|
|
301
|
+
}
|
|
302
|
+
// Skip other locales by default
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
files.push(...findMarkdownFiles(fullPath, ig, relativePath, options));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
else if (entry.isFile()) {
|
|
309
|
+
if (entry.name.endsWith(".md") || entry.name.endsWith(".mdx")) {
|
|
310
|
+
const lowerName = entry.name.toLowerCase();
|
|
311
|
+
// Skip non-doc markdown files
|
|
312
|
+
if (IGNORED_FILES.has(lowerName))
|
|
313
|
+
continue;
|
|
314
|
+
// Skip test fixture files (e.g., component.expect.md, hook.test.md)
|
|
315
|
+
if (lowerName.endsWith(".expect.md") ||
|
|
316
|
+
lowerName.endsWith(".test.md") ||
|
|
317
|
+
lowerName.endsWith(".spec.md")) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
files.push(relativePath);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
// Directory read failed
|
|
327
|
+
}
|
|
328
|
+
return files;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Read all markdown files from a local directory.
|
|
332
|
+
* Respects .gitignore from the base path (repo root).
|
|
333
|
+
* By default, filters out non-English locale directories.
|
|
334
|
+
* Deduplicates files by content hash (keeps first occurrence).
|
|
335
|
+
*/
|
|
336
|
+
export function readLocalDocsFiles(basePath, options = {}) {
|
|
337
|
+
const { docsPath, lang } = options;
|
|
338
|
+
const searchPath = docsPath ? join(basePath, docsPath) : basePath;
|
|
339
|
+
if (!existsSync(searchPath)) {
|
|
340
|
+
throw new Error(`Directory not found: ${searchPath}`);
|
|
341
|
+
}
|
|
342
|
+
// Load gitignore from repo root
|
|
343
|
+
const ig = loadGitignore(basePath);
|
|
344
|
+
const markdownFiles = findMarkdownFiles(searchPath, ig, "", { lang });
|
|
345
|
+
const files = [];
|
|
346
|
+
const seenHashes = new Set();
|
|
347
|
+
for (const filePath of markdownFiles) {
|
|
348
|
+
try {
|
|
349
|
+
const fullPath = join(searchPath, filePath);
|
|
350
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
351
|
+
// Skip duplicate content (keep first occurrence)
|
|
352
|
+
const hash = contentHash(content);
|
|
353
|
+
if (seenHashes.has(hash)) {
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
seenHashes.add(hash);
|
|
357
|
+
// Use relative path from docs folder for storage
|
|
358
|
+
const storagePath = docsPath ? join(docsPath, filePath) : filePath;
|
|
359
|
+
files.push({ path: storagePath, content });
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// Skip files that can't be read
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
return files;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Extract version from ref or return 'latest'.
|
|
369
|
+
*/
|
|
370
|
+
export function extractVersion(ref) {
|
|
371
|
+
if (!ref)
|
|
372
|
+
return "latest";
|
|
373
|
+
return ref.startsWith("v") ? ref.slice(1) : ref;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Detect version from a directory by checking:
|
|
377
|
+
* 1. Latest git tag (universal across all languages)
|
|
378
|
+
* 2. Falls back to 'latest'
|
|
379
|
+
*/
|
|
380
|
+
export function detectVersion(dirPath) {
|
|
381
|
+
// Try git tag (works for any language/framework)
|
|
382
|
+
try {
|
|
383
|
+
const tag = execSync("git describe --tags --abbrev=0 2>/dev/null", {
|
|
384
|
+
cwd: dirPath,
|
|
385
|
+
encoding: "utf-8",
|
|
386
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
387
|
+
}).trim();
|
|
388
|
+
if (tag) {
|
|
389
|
+
return tag.startsWith("v") ? tag.slice(1) : tag;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
// Not a git repo or no tags
|
|
394
|
+
}
|
|
395
|
+
return "latest";
|
|
396
|
+
}
|
|
397
|
+
//# sourceMappingURL=git.js.map
|
package/dist/git.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../src/git.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { type DocSection, type ParsedDoc, parseMarkdown } from "./build.js";
|
|
2
|
+
export { cloneRepository, detectLocalDocsFolder, extractRepoName, extractVersion, type GitCloneResult, isGitUrl, type LocalDocsResult, parseGitUrl, readLocalDocsFiles, } from "./git.js";
|
|
3
|
+
export { type BuildResult, buildPackage, type MarkdownFile, type PackageBuildOptions, } from "./package-builder.js";
|
|
4
|
+
export type { DocSnippet, SearchResult } from "./search.js";
|
|
5
|
+
export { ContextServer } from "./server.js";
|
|
6
|
+
export { type PackageInfo, type PackageMeta, PackageStore, readPackageInfo, } from "./store.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Public API
|
|
2
|
+
// Build utilities
|
|
3
|
+
export { parseMarkdown } from "./build.js";
|
|
4
|
+
// Git utilities
|
|
5
|
+
export { cloneRepository, detectLocalDocsFolder, extractRepoName, extractVersion, isGitUrl, parseGitUrl, readLocalDocsFiles, } from "./git.js";
|
|
6
|
+
export { buildPackage, } from "./package-builder.js";
|
|
7
|
+
export { ContextServer } from "./server.js";
|
|
8
|
+
export { PackageStore, readPackageInfo, } from "./store.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AAEb,kBAAkB;AAClB,OAAO,EAAmC,aAAa,EAAE,MAAM,YAAY,CAAC;AAC5E,gBAAgB;AAChB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,cAAc,EAEd,QAAQ,EAER,WAAW,EACX,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAEL,YAAY,GAGb,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAGL,YAAY,EACZ,eAAe,GAChB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package builder for creating documentation packages from markdown files.
|
|
3
|
+
*/
|
|
4
|
+
export interface PackageBuildOptions {
|
|
5
|
+
name: string;
|
|
6
|
+
version: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
sourceUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface MarkdownFile {
|
|
11
|
+
path: string;
|
|
12
|
+
content: string;
|
|
13
|
+
}
|
|
14
|
+
export interface BuildResult {
|
|
15
|
+
path: string;
|
|
16
|
+
sectionCount: number;
|
|
17
|
+
totalTokens: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a documentation package from markdown files.
|
|
21
|
+
*/
|
|
22
|
+
export declare function buildPackage(outputPath: string, files: MarkdownFile[], options: PackageBuildOptions): BuildResult;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package builder for creating documentation packages from markdown files.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, unlinkSync } from "node:fs";
|
|
5
|
+
import Database from "better-sqlite3";
|
|
6
|
+
import { parseMarkdown } from "./build.js";
|
|
7
|
+
/**
|
|
8
|
+
* Build a documentation package from markdown files.
|
|
9
|
+
*/
|
|
10
|
+
export function buildPackage(outputPath, files, options) {
|
|
11
|
+
// Remove existing file if present
|
|
12
|
+
if (existsSync(outputPath)) {
|
|
13
|
+
unlinkSync(outputPath);
|
|
14
|
+
}
|
|
15
|
+
const db = new Database(outputPath);
|
|
16
|
+
try {
|
|
17
|
+
// Create schema
|
|
18
|
+
db.exec(`
|
|
19
|
+
CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT);
|
|
20
|
+
CREATE TABLE chunks (
|
|
21
|
+
id INTEGER PRIMARY KEY,
|
|
22
|
+
doc_path TEXT NOT NULL,
|
|
23
|
+
doc_title TEXT NOT NULL,
|
|
24
|
+
section_title TEXT NOT NULL,
|
|
25
|
+
content TEXT NOT NULL,
|
|
26
|
+
tokens INTEGER NOT NULL,
|
|
27
|
+
has_code INTEGER DEFAULT 0
|
|
28
|
+
);
|
|
29
|
+
CREATE VIRTUAL TABLE chunks_fts USING fts5(
|
|
30
|
+
doc_title, section_title, content,
|
|
31
|
+
content='chunks', content_rowid='id',
|
|
32
|
+
tokenize='porter unicode61'
|
|
33
|
+
);
|
|
34
|
+
`);
|
|
35
|
+
// Insert metadata
|
|
36
|
+
const insertMeta = db.prepare("INSERT INTO meta (key, value) VALUES (?, ?)");
|
|
37
|
+
insertMeta.run("name", options.name);
|
|
38
|
+
insertMeta.run("version", options.version);
|
|
39
|
+
if (options.description) {
|
|
40
|
+
insertMeta.run("description", options.description);
|
|
41
|
+
}
|
|
42
|
+
if (options.sourceUrl) {
|
|
43
|
+
insertMeta.run("source_url", options.sourceUrl);
|
|
44
|
+
}
|
|
45
|
+
// Parse and insert chunks
|
|
46
|
+
const insertChunk = db.prepare(`
|
|
47
|
+
INSERT INTO chunks (doc_path, doc_title, section_title, content, tokens, has_code)
|
|
48
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
49
|
+
`);
|
|
50
|
+
const allSections = [];
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = parseMarkdown(file.content, file.path);
|
|
54
|
+
allSections.push(...parsed.sections);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Skip files that fail to parse
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Insert all sections in a transaction
|
|
61
|
+
const insertAll = db.transaction((sections) => {
|
|
62
|
+
for (const section of sections) {
|
|
63
|
+
insertChunk.run(section.docPath, section.docTitle, section.sectionTitle, section.content, section.tokens, section.hasCode ? 1 : 0);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
insertAll(allSections);
|
|
67
|
+
// Rebuild FTS index
|
|
68
|
+
db.exec("INSERT INTO chunks_fts(chunks_fts) VALUES('rebuild')");
|
|
69
|
+
const totalTokens = allSections.reduce((sum, s) => sum + s.tokens, 0);
|
|
70
|
+
return {
|
|
71
|
+
path: outputPath,
|
|
72
|
+
sectionCount: allSections.length,
|
|
73
|
+
totalTokens,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
db.close();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=package-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-builder.js","sourceRoot":"","sources":["../src/package-builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAmB,aAAa,EAAE,MAAM,YAAY,CAAC;AAoB5D;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,UAAkB,EAClB,KAAqB,EACrB,OAA4B;IAE5B,kCAAkC;IAClC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,UAAU,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,gBAAgB;QAChB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;KAgBP,CAAC,CAAC;QAEH,kBAAkB;QAClB,MAAM,UAAU,GAAG,EAAE,CAAC,OAAO,CAC3B,6CAA6C,CAC9C,CAAC;QACF,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,UAAU,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,UAAU,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC;QAED,0BAA0B;QAC1B,MAAM,WAAW,GAAG,EAAE,CAAC,OAAO,CAAC;;;KAG9B,CAAC,CAAC;QAEH,MAAM,WAAW,GAAiB,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtD,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,MAAM,SAAS,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,QAAsB,EAAE,EAAE;YAC1D,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,WAAW,CAAC,GAAG,CACb,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,QAAQ,EAChB,OAAO,CAAC,YAAY,EACpB,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACxB,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,WAAW,CAAC,CAAC;QAEvB,oBAAoB;QACpB,EAAE,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;QAEhE,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEtE,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,YAAY,EAAE,WAAW,CAAC,MAAM;YAChC,WAAW;SACZ,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
export interface DocSnippet {
|
|
3
|
+
title: string;
|
|
4
|
+
content: string;
|
|
5
|
+
source: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SearchResult {
|
|
8
|
+
library: string;
|
|
9
|
+
version: string;
|
|
10
|
+
results: DocSnippet[];
|
|
11
|
+
}
|
|
12
|
+
export declare function search(db: Database.Database, topic: string): SearchResult;
|