@gresmcp/mcp 1.2.0 → 1.3.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/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/db.ts","../src/cli.ts","../src/ollama.ts","../src/ingest.ts","../src/chunk.ts","../src/html.ts","../src/progress.ts","../src/scrape.ts","../src/check.ts","../src/version.ts"],"sourcesContent":["export const DEFAULT_DATABASE_URL = \"postgresql://gres:gres@localhost/gres\";\r\nexport const DEFAULT_OLLAMA_URL = \"http://localhost:11434\";\r\n\r\nexport function databaseUrl(): string {\r\n return process.env.GRESMCP_DATABASE_URL || DEFAULT_DATABASE_URL;\r\n}\r\n\r\nexport function normalizeUrl(url: string): string {\r\n return url.replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport function ollamaUrl(override?: string): string {\r\n const raw = override || process.env.GRESMCP_OLLAMA_URL || DEFAULT_OLLAMA_URL;\r\n return normalizeUrl(raw);\r\n}\r\n","import { Pool } from \"pg\";\r\nimport { toSql } from \"pgvector\";\r\nimport { createHash } from \"node:crypto\";\r\nimport { databaseUrl, DEFAULT_OLLAMA_URL } from \"./config.js\";\r\n\r\nlet pool: Pool | undefined;\r\n\r\nexport function getPool(): Pool {\r\n if (!pool) {\r\n pool = new Pool({ connectionString: databaseUrl(), max: 5 });\r\n }\r\n return pool;\r\n}\r\n\r\nexport async function closePool(): Promise<void> {\r\n if (pool) {\r\n await pool.end();\r\n pool = undefined;\r\n }\r\n}\r\n\r\nexport interface KnowledgeSource {\r\n id: string;\r\n name: string;\r\n description: string;\r\n embedding_model: string;\r\n embedding_dim: number;\r\n ollama_url: string;\r\n created_at: Date;\r\n updated_at: Date;\r\n}\r\n\r\nexport interface EntryRow {\r\n id: string | number;\r\n source: string;\r\n title: string;\r\n chunk_index: number;\r\n content: string;\r\n content_hash: string;\r\n metadata: Record<string, unknown>;\r\n created_at: Date;\r\n}\r\n\r\nexport function entryTableName(ks: Pick<KnowledgeSource, \"id\">): string {\r\n const name = `entry_${ks.id.replace(/-/g, \"\")}`;\r\n assertTableName(name);\r\n return name;\r\n}\r\n\r\nexport function assertTableName(name: string): void {\r\n if (!/^entry_[0-9a-f]{32}$/.test(name)) {\r\n throw new Error(`Refusing to use unsafe table name: ${name}`);\r\n }\r\n}\r\n\r\nexport function contentHash(content: string): string {\r\n return createHash(\"sha256\").update(content).digest(\"hex\");\r\n}\r\n\r\nexport async function initDb(): Promise<void> {\r\n const p = getPool();\r\n await p.query(`CREATE EXTENSION IF NOT EXISTS vector`);\r\n await p.query(`\r\n CREATE TABLE IF NOT EXISTS ks (\r\n id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\r\n name text NOT NULL UNIQUE,\r\n description text NOT NULL DEFAULT '',\r\n embedding_model text NOT NULL,\r\n embedding_dim integer NOT NULL,\r\n ollama_url text NOT NULL DEFAULT '${DEFAULT_OLLAMA_URL}',\r\n created_at timestamptz NOT NULL DEFAULT now(),\r\n updated_at timestamptz NOT NULL DEFAULT now()\r\n )\r\n `);\r\n}\r\n\r\nexport async function createKs(input: {\r\n name: string;\r\n description?: string;\r\n model: string;\r\n dim: number;\r\n url: string;\r\n}): Promise<KnowledgeSource> {\r\n const res = await getPool().query(\r\n `INSERT INTO ks (name, description, embedding_model, embedding_dim, ollama_url)\r\n VALUES ($1, $2, $3, $4, $5)\r\n RETURNING *`,\r\n [input.name, input.description ?? \"\", input.model, input.dim, input.url],\r\n );\r\n const ks = res.rows[0] as KnowledgeSource;\r\n await ensureEntryTable(ks);\r\n return ks;\r\n}\r\n\r\nexport async function listKs(): Promise<KnowledgeSource[]> {\r\n const res = await getPool().query(`SELECT * FROM ks ORDER BY name`);\r\n return res.rows as KnowledgeSource[];\r\n}\r\n\r\nexport async function getKs(name: string): Promise<KnowledgeSource | undefined> {\r\n const res = await getPool().query(`SELECT * FROM ks WHERE name = $1`, [name]);\r\n return res.rows[0] as KnowledgeSource | undefined;\r\n}\r\n\r\nexport async function updateKs(\r\n id: string,\r\n fields: { name?: string; description?: string; ollama_url?: string },\r\n): Promise<KnowledgeSource> {\r\n const sets: string[] = [];\r\n const params: unknown[] = [];\r\n if (fields.name !== undefined) {\r\n params.push(fields.name);\r\n sets.push(`name = $${params.length}`);\r\n }\r\n if (fields.description !== undefined) {\r\n params.push(fields.description);\r\n sets.push(`description = $${params.length}`);\r\n }\r\n if (fields.ollama_url !== undefined) {\r\n params.push(fields.ollama_url);\r\n sets.push(`ollama_url = $${params.length}`);\r\n }\r\n if (sets.length === 0) {\r\n const res = await getPool().query(`SELECT * FROM ks WHERE id = $1`, [id]);\r\n return res.rows[0] as KnowledgeSource;\r\n }\r\n sets.push(`updated_at = now()`);\r\n params.push(id);\r\n const res = await getPool().query(\r\n `UPDATE ks SET ${sets.join(\", \")} WHERE id = $${params.length} RETURNING *`,\r\n params,\r\n );\r\n return res.rows[0] as KnowledgeSource;\r\n}\r\n\r\nexport async function deleteKs(ks: KnowledgeSource): Promise<void> {\r\n const tbl = entryTableName(ks);\r\n await getPool().query(`DROP TABLE IF EXISTS ${tbl}`);\r\n await getPool().query(`DELETE FROM ks WHERE id = $1`, [ks.id]);\r\n}\r\n\r\nexport async function ensureEntryTable(ks: KnowledgeSource): Promise<void> {\r\n const tbl = entryTableName(ks);\r\n const p = getPool();\r\n await p.query(`\r\n CREATE TABLE IF NOT EXISTS ${tbl} (\r\n id bigserial PRIMARY KEY,\r\n source text NOT NULL,\r\n title text NOT NULL DEFAULT '',\r\n chunk_index integer NOT NULL DEFAULT 0,\r\n content text NOT NULL,\r\n content_hash text NOT NULL,\r\n metadata jsonb NOT NULL DEFAULT '{}',\r\n tsv tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED,\r\n embedding vector(${ks.embedding_dim}) NOT NULL,\r\n created_at timestamptz NOT NULL DEFAULT now()\r\n )\r\n `);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_tsv_idx ON ${tbl} USING gin (tsv)`);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_emb_idx ON ${tbl} USING hnsw (embedding vector_cosine_ops)`);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_source_idx ON ${tbl} (source)`);\r\n}\r\n\r\nexport interface ChunkInsert {\r\n source: string;\r\n title: string;\r\n chunk_index: number;\r\n content: string;\r\n metadata: Record<string, unknown>;\r\n embedding: number[];\r\n}\r\n\r\nexport async function insertChunks(ks: KnowledgeSource, rows: ChunkInsert[]): Promise<number> {\r\n if (rows.length === 0) return 0;\r\n const tbl = entryTableName(ks);\r\n const p = getPool();\r\n const BATCH = 25;\r\n let inserted = 0;\r\n for (let i = 0; i < rows.length; i += BATCH) {\r\n const batch = rows.slice(i, i + BATCH);\r\n const values: string[] = [];\r\n const params: unknown[] = [];\r\n batch.forEach((r, j) => {\r\n const b = j * 7;\r\n values.push(`($${b + 1}, $${b + 2}, $${b + 3}, $${b + 4}, $${b + 5}, $${b + 6}, $${b + 7}::vector)`);\r\n params.push(r.source, r.title, r.chunk_index, r.content, contentHash(r.content), JSON.stringify(r.metadata), toSql(r.embedding));\r\n });\r\n const res = await p.query(\r\n `INSERT INTO ${tbl} (source, title, chunk_index, content, content_hash, metadata, embedding)\r\n VALUES ${values.join(\", \")}`,\r\n params,\r\n );\r\n inserted += res.rowCount ?? 0;\r\n }\r\n return inserted;\r\n}\r\n\r\nexport async function deleteBySource(ks: KnowledgeSource, source: string): Promise<number> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(`DELETE FROM ${tbl} WHERE source = $1`, [source]);\r\n return res.rowCount ?? 0;\r\n}\r\n\r\nexport async function sourceChunkHashes(\r\n ks: KnowledgeSource,\r\n source: string,\r\n): Promise<Map<number, string>> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(\r\n `SELECT chunk_index, content_hash FROM ${tbl} WHERE source = $1`,\r\n [source],\r\n );\r\n const map = new Map<number, string>();\r\n for (const row of res.rows) {\r\n map.set(Number(row.chunk_index), String(row.content_hash));\r\n }\r\n return map;\r\n}\r\n\r\nexport async function countEntries(ks: KnowledgeSource): Promise<number> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(`SELECT count(*)::int AS n FROM ${tbl}`);\r\n return Number(res.rows[0]?.n ?? 0);\r\n}\r\n\r\nexport async function dbClockTimestamp(): Promise<Date> {\r\n const res = await getPool().query(`SELECT clock_timestamp() AS ts`);\r\n return res.rows[0]!.ts as Date;\r\n}\r\n\r\nexport interface KsStats {\r\n ks: KnowledgeSource;\r\n entries: number;\r\n sources: number;\r\n chars: number;\r\n avg_chunk_chars: number | null;\r\n min_chunk_chars: number | null;\r\n max_chunk_chars: number | null;\r\n last_fed_at: Date | null;\r\n}\r\n\r\nexport async function ksStats(ks: KnowledgeSource, since?: Date): Promise<KsStats> {\r\n const tbl = entryTableName(ks);\r\n const params: unknown[] = [];\r\n let where = \"\";\r\n if (since) {\r\n params.push(since);\r\n where = ` WHERE created_at >= $1`;\r\n }\r\n const res = await getPool().query(\r\n `SELECT count(*)::int AS entries,\r\n count(DISTINCT source)::int AS sources,\r\n COALESCE(sum(length(content)), 0)::bigint AS chars,\r\n round(avg(length(content)))::int AS avg_chunk_chars,\r\n min(length(content))::int AS min_chunk_chars,\r\n max(length(content))::int AS max_chunk_chars,\r\n max(created_at) AS last_fed_at\r\n FROM ${tbl}${where}`,\r\n params,\r\n );\r\n const r = res.rows[0] as Record<string, unknown>;\r\n return {\r\n ks,\r\n entries: Number(r.entries ?? 0),\r\n sources: Number(r.sources ?? 0),\r\n chars: Number(r.chars ?? 0),\r\n avg_chunk_chars: r.avg_chunk_chars === null ? null : Number(r.avg_chunk_chars),\r\n min_chunk_chars: r.min_chunk_chars === null ? null : Number(r.min_chunk_chars),\r\n max_chunk_chars: r.max_chunk_chars === null ? null : Number(r.max_chunk_chars),\r\n last_fed_at: r.last_fed_at === null ? null : (r.last_fed_at as Date),\r\n };\r\n}\r\n","import { Command } from \"commander\";\r\nimport { createInterface } from \"node:readline/promises\";\r\nimport { stdin, stdout } from \"node:process\";\r\nimport {\r\n initDb,\r\n closePool,\r\n createKs,\r\n listKs,\r\n getKs,\r\n updateKs,\r\n deleteKs,\r\n countEntries,\r\n ksStats,\r\n dbClockTimestamp,\r\n type KnowledgeSource,\r\n} from \"./db.js\";\r\nimport { probeModel } from \"./ollama.js\";\r\nimport { ollamaUrl } from \"./config.js\";\r\nimport { feedTarget, feedText } from \"./ingest.js\";\r\nimport { feedUrl, CRAWLER_KINDS, parseSitemapOption, type CrawlerKind, type SitemapMode } from \"./scrape.js\";\r\nimport { parseHtmlFilter, validateCssSelector } from \"./html.js\";\r\nimport { runChecks, type CheckStatus } from \"./check.js\";\r\nimport { VERSION } from \"./version.js\";\r\n\r\nasync function run(fn: () => Promise<void>): Promise<void> {\r\n try {\r\n await fn();\r\n } catch (err) {\r\n console.error(`error: ${err instanceof Error ? err.message : err}`);\r\n process.exitCode = 1;\r\n } finally {\r\n await closePool().catch(() => {});\r\n }\r\n}\r\n\r\nasync function confirm(question: string): Promise<boolean> {\r\n const rl = createInterface({ input: stdin, output: stdout });\r\n try {\r\n const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();\r\n return answer === \"y\" || answer === \"yes\";\r\n } finally {\r\n rl.close();\r\n }\r\n}\r\n\r\nfunction requireKs(ks: KnowledgeSource | undefined, name: string): KnowledgeSource {\r\n if (!ks) throw new Error(`knowledge source '${name}' not found`);\r\n return ks;\r\n}\r\n\r\nfunction parseKeyValue(pairs: string[]): Record<string, unknown> {\r\n const out: Record<string, unknown> = {};\r\n for (const pair of pairs) {\r\n const idx = pair.indexOf(\"=\");\r\n if (idx <= 0) throw new Error(`invalid metadata entry '${pair}', expected key=value`);\r\n out[pair.slice(0, idx)] = pair.slice(idx + 1);\r\n }\r\n return out;\r\n}\r\n\r\nfunction parseTags(tags?: string): string[] | undefined {\r\n if (!tags) return undefined;\r\n const list = tags.split(\",\").map((t) => t.trim()).filter(Boolean);\r\n return list.length > 0 ? list : undefined;\r\n}\r\n\r\nfunction parseGlobs(globs?: string[]): string[] | undefined {\r\n if (!globs || globs.length === 0) return undefined;\r\n const list = [...new Set(globs.map((g) => g.trim()).filter(Boolean))];\r\n return list.length > 0 ? list : undefined;\r\n}\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name(\"gresmcp\")\r\n .description(\"Manage Postgres-backed knowledge sources for the gresmcp MCP server\")\r\n .version(VERSION);\r\n\r\nprogram\r\n .command(\"init\")\r\n .description(\"Initialize the database schema (extension, ks table; repairs entry tables)\")\r\n .action(() =>\r\n run(async () => {\r\n await initDb();\r\n for (const ks of await listKs()) {\r\n const { ensureEntryTable } = await import(\"./db.js\");\r\n await ensureEntryTable(ks);\r\n }\r\n console.log(\"database ready\");\r\n }),\r\n );\r\n\r\nprogram\r\n .command(\"check\")\r\n .description(\"Verify environment requirements (Node, Postgres, pgvector, schema, Ollama models)\")\r\n .requiredOption(\"--model <model>\", \"Verify this Ollama model is available (e.g. nomic-embed-text)\")\r\n .option(\"--url <url>\", \"Ollama base URL (default http://localhost:11434)\")\r\n .option(\"--probe\", \"Embed a test string with each model to verify dimensions (slower)\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((opts: { model: string; url?: string; probe?: boolean; json?: boolean }) =>\r\n run(async () => {\r\n const results = await runChecks({ model: opts.model, url: opts.url, probe: opts.probe });\r\n if (opts.json) {\r\n console.log(JSON.stringify(results, null, 2));\r\n } else {\r\n const symbols: Record<CheckStatus, string> = { ok: \"✔\", warn: \"⚠\", fail: \"✘\", skip: \"-\" };\r\n for (const r of results) console.log(`${symbols[r.status]} ${r.detail}`);\r\n const failed = results.filter((r) => r.status === \"fail\").length;\r\n const warned = results.filter((r) => r.status === \"warn\").length;\r\n if (failed > 0) {\r\n console.log(`${failed} check(s) failed${warned > 0 ? `, ${warned} warning(s)` : \"\"}`);\r\n } else if (warned > 0) {\r\n console.log(`all checks passed with ${warned} warning(s)`);\r\n } else {\r\n console.log(\"all checks passed\");\r\n }\r\n }\r\n if (results.some((r) => r.status === \"fail\")) process.exitCode = 1;\r\n }),\r\n );\r\n\r\nconst ksCmd = program.command(\"ks\").description(\"Manage knowledge sources\");\r\n\r\nksCmd\r\n .command(\"create <name>\")\r\n .description(\"Create a knowledge source (probes Ollama to validate the model and detect dimensions)\")\r\n .requiredOption(\"--model <model>\", \"Ollama embedding model, e.g. nomic-embed-text\")\r\n .option(\"--url <url>\", \"Ollama base URL (default http://localhost:11434)\")\r\n .option(\"--description <description>\", \"Human-readable description\")\r\n .option(\"--dim <n>\", \"Skip the Ollama probe and set the embedding dimension explicitly\", parseInt)\r\n .action((name: string, opts: { model: string; url?: string; description?: string; dim?: number }) =>\r\n run(async () => {\r\n await initDb();\r\n if (await getKs(name)) throw new Error(`knowledge source '${name}' already exists`);\r\n const url = ollamaUrl(opts.url);\r\n let dim = opts.dim;\r\n if (dim === undefined || !Number.isFinite(dim) || dim <= 0) {\r\n console.log(`Probing model ${opts.model} at ${url} ...`);\r\n dim = (await probeModel(url, opts.model)).dim;\r\n console.log(`Model OK, embedding dimension: ${dim}`);\r\n }\r\n const ks = await createKs({\r\n name,\r\n description: opts.description,\r\n model: opts.model,\r\n dim,\r\n url,\r\n });\r\n console.log(`Created knowledge source '${ks.name}' (dim=${ks.embedding_dim}, model=${ks.embedding_model}, url=${ks.ollama_url})`);\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"edit <name>\")\r\n .description(\"Edit a knowledge source (the embedding model is immutable)\")\r\n .option(\"--url <url>\", \"New Ollama base URL\")\r\n .option(\"--rename <new-name>\", \"Rename the knowledge source\")\r\n .option(\"--description <description>\", \"New description\")\r\n .action((name: string, opts: { url?: string; rename?: string; description?: string }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n if (opts.rename && opts.rename !== name && (await getKs(opts.rename))) {\r\n throw new Error(`knowledge source '${opts.rename}' already exists`);\r\n }\r\n const updated = await updateKs(ks.id, {\r\n name: opts.rename,\r\n description: opts.description,\r\n ollama_url: opts.url ? ollamaUrl(opts.url) : undefined,\r\n });\r\n console.log(`Updated '${updated.name}' (model=${updated.embedding_model}, url=${updated.ollama_url}, dim=${updated.embedding_dim})`);\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"list\")\r\n .description(\"List knowledge sources\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((opts: { json?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const all = await listKs();\r\n if (opts.json) {\r\n console.log(JSON.stringify(all, null, 2));\r\n return;\r\n }\r\n if (all.length === 0) {\r\n console.log(\"no knowledge sources yet; create one with: gresmcp ks create <name> --model <model>\");\r\n return;\r\n }\r\n for (const ks of all) {\r\n const n = await countEntries(ks);\r\n console.log(\r\n `${ks.name.padEnd(20)} ${`${ks.embedding_model}@${ks.ollama_url}`.padEnd(50)} dim=${String(ks.embedding_dim).padEnd(6)} entries=${String(n).padEnd(8)} ${ks.description}`,\r\n );\r\n }\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"stats <name>\")\r\n .description(\"Show statistics for a knowledge source (entries, sources, content volume)\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((name: string, opts: { json?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n const stats = await ksStats(ks);\r\n if (opts.json) {\r\n console.log(JSON.stringify(stats, null, 2));\r\n return;\r\n }\r\n console.log(\r\n `Knowledge source '${stats.ks.name}' (model=${stats.ks.embedding_model}@${stats.ks.ollama_url}, dim=${stats.ks.embedding_dim})`,\r\n );\r\n if (stats.ks.description) console.log(` description: ${stats.ks.description}`);\r\n console.log(` created: ${stats.ks.created_at.toISOString()}`);\r\n console.log(` last fed: ${stats.last_fed_at ? stats.last_fed_at.toISOString() : \"never\"}`);\r\n console.log(\"\");\r\n if (stats.entries === 0) {\r\n console.log(` no entries yet; feed it with: gresmcp feed ${stats.ks.name}`);\r\n return;\r\n }\r\n const size = (n: number | null) => (n === null ? \"-\" : n.toLocaleString(\"en-US\"));\r\n console.log(` entries (chunks): ${stats.entries.toLocaleString(\"en-US\")}`);\r\n console.log(` distinct sources: ${stats.sources.toLocaleString(\"en-US\")}`);\r\n console.log(\r\n ` content: ${stats.chars.toLocaleString(\"en-US\")} chars` +\r\n ` (avg ${size(stats.avg_chunk_chars)}, min ${size(stats.min_chunk_chars)}, max ${size(stats.max_chunk_chars)} per chunk)`,\r\n );\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"delete <name>\")\r\n .description(\"Delete a knowledge source and all of its entries\")\r\n .option(\"--yes\", \"Do not ask for confirmation\")\r\n .action((name: string, opts: { yes?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n if (!opts.yes) {\r\n const n = await countEntries(ks);\r\n const ok = await confirm(`Delete knowledge source '${name}' and its ${n} entry chunk(s)?`);\r\n if (!ok) {\r\n console.log(\"aborted\");\r\n return;\r\n }\r\n }\r\n await deleteKs(ks);\r\n console.log(`Deleted knowledge source '${name}'`);\r\n }),\r\n );\r\n\r\nprogram\r\n .command(\"feed <ks>\")\r\n .description(\"Feed data into a knowledge source (from a file/folder via --path, a website via --url, or inline via --text/--stdin)\")\r\n .option(\"--path <path>\", \"File or folder to ingest (text, markdown, code, html)\")\r\n .option(\"--url <url>\", \"Website URL to scrape and ingest (crawls same-host pages linked from the seed)\")\r\n .option(\"--crawler <crawler>\", \"Crawler backend for --url: auto, crawlee, playwright, puppeteer (default auto; playwright/puppeteer must be installed globally)\", ((v: string) => v.toLowerCase()) as never)\r\n .option(\"--max-pages <n>\", \"Max pages to fetch when crawling --url (default 999)\", parseInt)\r\n .option(\"--depth <n>\", \"Max link depth from the seed URL (default 5; 0 = seed page only)\", parseInt)\r\n .option(\r\n \"--url-filter <glob>\",\r\n \"Only follow --url links whose URL matches this glob (repeatable; a link is followed if it matches any glob, e.g. '**/docs/**')\",\r\n ((v: string, prev: string[]) => [...prev, v]) as never,\r\n [] as string[],\r\n )\r\n .option(\r\n \"--html-filter <selector>\",\r\n \"CSS selector for HTML content — any DOM selector works (e.g. 'article.post', '#article .content:first-child'); optionally chain steps with ' -> ' (e.g. '#article -> .content'); applies to --path HTML files and --url pages\",\r\n )\r\n .option(\r\n \"--sitemap <mode>\",\r\n \"Link discovery for --url: 'auto' (default; sitemap.xml, then robots.txt sitemaps, else follow links), 'sitemap-only' (only sitemap.xml / robots.txt sitemaps), 'html-only' (follow links), or a CSS selector to only follow links inside it (e.g. 'nav.docs a')\",\r\n )\r\n .option(\"--text <text>\", \"Inline text entry\")\r\n .option(\"--stdin\", \"Read entry text from stdin\")\r\n .option(\"--title <title>\", \"Title for manual entries\")\r\n .option(\"--source-name <name>\", \"Source name for manual entries (default 'manual')\")\r\n .option(\"--tags <tags>\", \"Comma-separated tags\")\r\n .option(\"--metadata <key=value...>\", \"Custom metadata entries\", ((v: string, prev: string[]) => [...prev, v]) as never, [] as string[])\r\n .option(\"--replace\", \"Replace existing chunks of the same source instead of deduplicating\")\r\n .option(\"--dry-run\", \"Parse and chunk only; do not embed or write\")\r\n .option(\"--chunk-size <n>\", \"Max chunk length in characters\", parseInt)\r\n .option(\"--overlap <n>\", \"Chunk overlap in characters\", parseInt)\r\n .action((name: string, opts: {\r\n path?: string;\r\n url?: string;\r\n crawler?: string;\r\n maxPages?: number;\r\n depth?: number;\r\n urlFilter?: string[];\r\n htmlFilter?: string;\r\n sitemap?: string;\r\n text?: string;\r\n stdin?: boolean;\r\n title?: string;\r\n sourceName?: string;\r\n tags?: string;\r\n metadata?: string[];\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n chunkSize?: number;\r\n overlap?: number;\r\n }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n const modes = [opts.path, opts.url, opts.text, opts.stdin].filter(Boolean).length;\r\n if (modes !== 1) throw new Error(\"provide exactly one of --path, --url, --text or --stdin\");\r\n const urlFilter = parseGlobs(opts.urlFilter);\r\n if (urlFilter && !opts.url) {\r\n console.error(\"warning: --url-filter has no effect without --url\");\r\n }\r\n if (opts.htmlFilter) parseHtmlFilter(opts.htmlFilter);\r\n if (opts.htmlFilter && !opts.path && !opts.url) {\r\n console.error(\"warning: --html-filter has no effect without --path or --url\");\r\n }\r\n let sitemap: SitemapMode | undefined;\r\n if (opts.sitemap !== undefined) {\r\n sitemap = parseSitemapOption(opts.sitemap);\r\n if (sitemap.kind === \"selector\") validateCssSelector(sitemap.selector);\r\n if (!opts.url) console.error(\"warning: --sitemap has no effect without --url\");\r\n }\r\n const common = {\r\n replace: opts.replace,\r\n dryRun: opts.dryRun,\r\n batchSize: 32,\r\n maxLen: opts.chunkSize && opts.chunkSize > 0 ? opts.chunkSize : undefined,\r\n overlap: opts.overlap,\r\n tags: parseTags(opts.tags),\r\n metadata: parseKeyValue(opts.metadata ?? []),\r\n htmlFilter: opts.htmlFilter,\r\n };\r\n let summary;\r\n const since = await dbClockTimestamp();\r\n if (opts.path) {\r\n summary = await feedTarget(ks, opts.path, common);\r\n } else if (opts.url) {\r\n const crawler = opts.crawler as CrawlerKind | undefined;\r\n if (crawler && !CRAWLER_KINDS.includes(crawler)) {\r\n throw new Error(`unknown crawler '${crawler}' (use auto, crawlee, playwright or puppeteer)`);\r\n }\r\n summary = await feedUrl(ks, opts.url, { ...common, crawler, sitemap, maxPages: opts.maxPages, depth: opts.depth, urlFilter });\r\n } else {\r\n const text = opts.stdin ? await readStdin() : opts.text!;\r\n if (!text.trim()) throw new Error(\"empty input text\");\r\n summary = await feedText(ks, text, { ...common, title: opts.title, sourceName: opts.sourceName });\r\n }\r\n if (summary.dryRun) {\r\n console.log(`dry run: ${summary.documents} document(s), ${summary.chunks} chunk(s), ${summary.skippedFiles.length} file(s) skipped`);\r\n } else {\r\n console.log(\r\n `fed '${ks.name}': ${summary.inserted} chunk(s) inserted` +\r\n (summary.skippedExisting ? `, ${summary.skippedExisting} unchanged chunk(s) skipped` : \"\") +\r\n (summary.deletedForReplace ? `, ${summary.deletedForReplace} old chunk(s) replaced` : \"\") +\r\n `, ${summary.skippedFiles.length} file(s) skipped`,\r\n );\r\n await printRunStats(ks, since);\r\n }\r\n }),\r\n );\r\n\r\nasync function printRunStats(ks: KnowledgeSource, since: Date): Promise<void> {\r\n const stats = await ksStats(ks, since);\r\n if (stats.entries === 0) return;\r\n const size = (n: number | null) => (n === null ? \"-\" : n.toLocaleString(\"en-US\"));\r\n console.log(\"\");\r\n console.log(\r\n `this run: ${stats.entries.toLocaleString(\"en-US\")} chunk(s) across ${stats.sources.toLocaleString(\"en-US\")} source(s)`,\r\n );\r\n console.log(\r\n ` content: ${stats.chars.toLocaleString(\"en-US\")} chars` +\r\n ` (avg ${size(stats.avg_chunk_chars)}, min ${size(stats.min_chunk_chars)}, max ${size(stats.max_chunk_chars)} per chunk)`,\r\n );\r\n}\r\n\r\nasync function readStdin(): Promise<string> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stdin) chunks.push(chunk as Buffer);\r\n return Buffer.concat(chunks).toString(\"utf8\");\r\n}\r\n\r\nprogram.parseAsync(process.argv);\r\n","import { normalizeUrl } from \"./config.js\";\r\n\r\nexport class OllamaError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n ) {\r\n super(message);\r\n this.name = \"OllamaError\";\r\n }\r\n}\r\n\r\nexport async function embed(\r\n baseUrl: string,\r\n model: string,\r\n inputs: string[],\r\n timeoutMs = 120_000,\r\n): Promise<number[][]> {\r\n const url = `${normalizeUrl(baseUrl)}/api/embed`;\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({ model, input: inputs }),\r\n signal: AbortSignal.timeout(timeoutMs),\r\n });\r\n } catch (err) {\r\n throw new OllamaError(\r\n `Cannot reach Ollama at ${normalizeUrl(baseUrl)} (${err instanceof Error ? err.message : err})`,\r\n );\r\n }\r\n if (!res.ok) {\r\n const body = await res.text().catch(() => \"\");\r\n throw new OllamaError(`Ollama returned ${res.status} for ${url}: ${body.slice(0, 300)}`, res.status);\r\n }\r\n const data = (await res.json()) as { embeddings?: number[][]; error?: string };\r\n if (data.error) {\r\n throw new OllamaError(`Ollama error: ${data.error}`);\r\n }\r\n if (!Array.isArray(data.embeddings) || data.embeddings.length !== inputs.length) {\r\n throw new OllamaError(`Unexpected response shape from ${url}`);\r\n }\r\n return data.embeddings;\r\n}\r\n\r\nexport async function embedBatch(\r\n baseUrl: string,\r\n model: string,\r\n inputs: string[],\r\n batchSize = 32,\r\n onProgress?: (done: number, total: number) => void,\r\n): Promise<number[][]> {\r\n const out: number[][] = [];\r\n let done = 0;\r\n for (let i = 0; i < inputs.length; i += batchSize) {\r\n const batch = inputs.slice(i, i + batchSize);\r\n const embs = await embed(baseUrl, model, batch);\r\n out.push(...embs);\r\n done += batch.length;\r\n onProgress?.(done, inputs.length);\r\n }\r\n return out;\r\n}\r\n\r\nexport async function probeModel(\r\n baseUrl: string,\r\n model: string,\r\n): Promise<{ dim: number }> {\r\n const embs = await embed(baseUrl, model, [\"gresmcp dimension probe\"], 30_000);\r\n const first = embs[0];\r\n if (!first || first.length === 0) {\r\n throw new OllamaError(`Ollama returned an empty embedding for model ${model}`);\r\n }\r\n return { dim: first.length };\r\n}\r\n","import { promises as fs } from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { chunkMarkdown, chunkPlain, mdTitle, type Chunk } from \"./chunk.js\";\r\nimport { htmlToMarkdown } from \"./html.js\";\r\nimport {\r\n deleteBySource,\r\n insertChunks,\r\n sourceChunkHashes,\r\n contentHash,\r\n type ChunkInsert,\r\n type KnowledgeSource,\r\n} from \"./db.js\";\r\nimport { embedBatch } from \"./ollama.js\";\r\nimport { FeedProgress } from \"./progress.js\";\r\n\r\nexport const MD_EXT = new Set([\".md\", \".markdown\", \".mdx\"]);\r\nexport const HTML_EXT = new Set([\".html\", \".htm\", \".xhtml\"]);\r\nexport const TEXT_EXT = new Set([\r\n \".txt\", \".text\", \".log\", \".csv\", \".tsv\", \".json\", \".jsonl\", \".yaml\", \".yml\",\r\n \".toml\", \".ini\", \".cfg\", \".conf\", \".xml\", \".rst\", \".adoc\",\r\n]);\r\nexport const CODE_EXT = new Set([\r\n \".js\", \".mjs\", \".cjs\", \".ts\", \".tsx\", \".jsx\", \".py\", \".go\", \".rs\", \".java\",\r\n \".kt\", \".kts\", \".rb\", \".php\", \".c\", \".h\", \".cpp\", \".hpp\", \".cc\", \".cs\",\r\n \".sh\", \".bash\", \".zsh\", \".ps1\", \".psm1\", \".bat\", \".cmd\", \".sql\", \".css\",\r\n \".scss\", \".less\", \".vue\", \".svelte\", \".astro\", \".swift\", \".scala\", \".pl\",\r\n \".lua\", \".r\", \".dart\", \".gradle\", \".cmake\", \".dockerfile\", \".makefile\", \".proto\", \".graphql\",\r\n]);\r\n\r\nconst SKIP_DIRS = new Set([\r\n \"node_modules\", \".git\", \".hg\", \".svn\", \"dist\", \"build\", \"out\", \".next\",\r\n \".nuxt\", \".venv\", \"venv\", \"__pycache__\", \".idea\", \".vscode\", \"target\",\r\n \"coverage\", \".turbo\", \".cache\",\r\n]);\r\n\r\nexport interface LoadedDoc {\r\n source: string;\r\n title: string;\r\n chunks: Chunk[];\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport interface SkippedFile {\r\n path: string;\r\n reason: string;\r\n}\r\n\r\nexport interface LoadResult {\r\n docs: LoadedDoc[];\r\n fileCount: number;\r\n skipped: SkippedFile[];\r\n}\r\n\r\nfunction isAllowed(ext: string): boolean {\r\n return MD_EXT.has(ext) || HTML_EXT.has(ext) || TEXT_EXT.has(ext) || CODE_EXT.has(ext);\r\n}\r\n\r\nasync function walk(root: string): Promise<string[]> {\r\n const out: string[] = [];\r\n const entries = await fs.readdir(root, { withFileTypes: true });\r\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\r\n const full = path.join(root, entry.name);\r\n if (entry.isDirectory()) {\r\n if (SKIP_DIRS.has(entry.name)) continue;\r\n out.push(...(await walk(full)));\r\n } else if (entry.isFile()) {\r\n out.push(full);\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nexport async function loadTarget(\r\n target: string,\r\n opts: { maxLen: number; overlap: number; htmlFilter?: string },\r\n): Promise<LoadResult> {\r\n const stat = await fs.stat(target);\r\n const files = stat.isDirectory() ? await walk(target) : [target];\r\n const docs: LoadedDoc[] = [];\r\n const skipped: SkippedFile[] = [];\r\n\r\n for (const file of files) {\r\n const ext = path.extname(file).toLowerCase();\r\n if (!isAllowed(ext)) {\r\n skipped.push({ path: file, reason: `unsupported extension '${ext || \"(none)\"}'` });\r\n continue;\r\n }\r\n let raw: string;\r\n try {\r\n raw = await fs.readFile(file, \"utf8\");\r\n } catch {\r\n skipped.push({ path: file, reason: \"unreadable\" });\r\n continue;\r\n }\r\n if (raw.includes(\"\\u0000\")) {\r\n skipped.push({ path: file, reason: \"binary content\" });\r\n continue;\r\n }\r\n let text = raw;\r\n let title = \"\";\r\n if (HTML_EXT.has(ext)) {\r\n const conv = htmlToMarkdown(raw, { filter: opts.htmlFilter });\r\n text = conv.markdown;\r\n title = conv.title ?? \"\";\r\n } else if (MD_EXT.has(ext)) {\r\n title = mdTitle(raw) ?? \"\";\r\n }\r\n if (!text.trim()) {\r\n skipped.push({\r\n path: file,\r\n reason: HTML_EXT.has(ext) && opts.htmlFilter\r\n ? `html filter '${opts.htmlFilter}' matched nothing`\r\n : \"empty\",\r\n });\r\n continue;\r\n }\r\n if (!title) title = path.basename(file);\r\n const chunks = HTML_EXT.has(ext) || MD_EXT.has(ext)\r\n ? chunkMarkdown(text, opts)\r\n : chunkPlain(text, opts);\r\n if (chunks.length === 0) {\r\n skipped.push({ path: file, reason: \"no chunks produced\" });\r\n continue;\r\n }\r\n docs.push({ source: path.resolve(file), title, chunks });\r\n }\r\n return { docs, fileCount: files.length, skipped };\r\n}\r\n\r\nexport interface FeedSummary {\r\n documents: number;\r\n chunks: number;\r\n inserted: number;\r\n skippedExisting: number;\r\n deletedForReplace: number;\r\n skippedFiles: SkippedFile[];\r\n dryRun: boolean;\r\n}\r\n\r\nexport interface FeedDocsOptions {\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n progress?: FeedProgress;\r\n}\r\n\r\nconst DOC_CONCURRENCY = 3;\r\n\r\nexport async function feedDocs(\r\n ks: KnowledgeSource,\r\n docs: LoadedDoc[],\r\n opts: FeedDocsOptions = {},\r\n): Promise<FeedSummary> {\r\n const log = opts.log ?? ((m: string) => console.log(m));\r\n const progress = opts.progress;\r\n const batchSize = opts.batchSize ?? 32;\r\n const baseMeta = { ...(opts.metadata ?? {}) };\r\n const cliTags = opts.tags && opts.tags.length > 0 ? opts.tags : undefined;\r\n const say = (msg: string) => (progress ? progress.log(msg) : log(msg));\r\n\r\n let deletedForReplace = 0;\r\n let skippedExisting = 0;\r\n let inserted = 0;\r\n let announcedEmbed = false;\r\n\r\n const processDoc = async (doc: LoadedDoc): Promise<void> => {\r\n const file = progress?.startFile(\r\n doc.source,\r\n doc.chunks.length,\r\n doc.chunks.reduce((n, c) => n + c.content.length, 0),\r\n );\r\n if (opts.replace) {\r\n const deleted = await deleteBySource(ks, doc.source);\r\n deletedForReplace += deleted;\r\n }\r\n const existing = await sourceChunkHashes(ks, doc.source);\r\n const meta: Record<string, unknown> = { ...baseMeta, ...(doc.metadata ?? {}) };\r\n if (!(\"tags\" in meta) && cliTags) meta.tags = cliTags;\r\n const todo: Chunk[] = [];\r\n for (const chunk of doc.chunks) {\r\n if (!opts.replace && existing.get(chunk.index) === contentHash(chunk.content)) {\r\n skippedExisting++;\r\n file?.handled(1, chunk.content.length);\r\n continue;\r\n }\r\n todo.push(chunk);\r\n }\r\n if (todo.length === 0) return;\r\n if (opts.dryRun) {\r\n for (const chunk of todo) file?.handled(1, chunk.content.length);\r\n return;\r\n }\r\n if (!announcedEmbed) {\r\n announcedEmbed = true;\r\n say(`Embedding with ${ks.embedding_model} at ${ks.ollama_url} ...`);\r\n }\r\n const contents = todo.map((c) => c.content);\r\n const charLens = contents.map((c) => c.length);\r\n let reported = 0;\r\n const embeddings = await embedBatch(ks.ollama_url, ks.embedding_model, contents, batchSize, (done) => {\r\n const delta = done - reported;\r\n if (delta <= 0) return;\r\n let chars = 0;\r\n for (let i = reported; i < done; i++) chars += charLens[i]!;\r\n reported = done;\r\n file?.handled(delta, chars);\r\n });\r\n const rows: ChunkInsert[] = todo.map((chunk, i) => ({\r\n source: doc.source,\r\n title: doc.title,\r\n chunk_index: chunk.index,\r\n content: chunk.content,\r\n metadata: meta,\r\n embedding: embeddings[i]!,\r\n }));\r\n const rowCount = await insertChunks(ks, rows);\r\n inserted += rowCount;\r\n };\r\n\r\n let cursor = 0;\r\n let firstError: unknown;\r\n const runWorker = async (): Promise<void> => {\r\n while (firstError === undefined) {\r\n const index = cursor++;\r\n if (index >= docs.length) return;\r\n try {\r\n await processDoc(docs[index]!);\r\n } catch (err) {\r\n firstError ??= err;\r\n return;\r\n }\r\n }\r\n };\r\n const workerCount = Math.min(DOC_CONCURRENCY, docs.length);\r\n await Promise.all(Array.from({ length: workerCount }, () => runWorker()));\r\n\r\n if (firstError !== undefined) {\r\n progress?.close();\r\n throw firstError;\r\n }\r\n progress?.finish();\r\n return {\r\n documents: docs.length,\r\n chunks: docs.reduce((n, d) => n + d.chunks.length, 0),\r\n inserted,\r\n skippedExisting,\r\n deletedForReplace,\r\n skippedFiles: [],\r\n dryRun: opts.dryRun ?? false,\r\n };\r\n}\r\n\r\nexport async function feedTarget(\r\n ks: KnowledgeSource,\r\n target: string,\r\n opts: {\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n maxLen?: number;\r\n overlap?: number;\r\n htmlFilter?: string;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n progress?: FeedProgress;\r\n } = {},\r\n): Promise<FeedSummary> {\r\n const loadOpts = { maxLen: opts.maxLen ?? 1200, overlap: opts.overlap ?? 180, htmlFilter: opts.htmlFilter };\r\n const { docs, skipped } = await loadTarget(target, loadOpts);\r\n for (const s of skipped) {\r\n (opts.log ?? ((m: string) => console.log(m)))(`skipped ${s.path}: ${s.reason}`);\r\n }\r\n const progress = opts.progress ?? new FeedProgress({ total: docs.length, rejected: skipped.length });\r\n const summary = await feedDocs(ks, docs, { ...opts, progress });\r\n return { ...summary, skippedFiles: skipped };\r\n}\r\n\r\nexport async function feedText(\r\n ks: KnowledgeSource,\r\n text: string,\r\n opts: {\r\n title?: string;\r\n sourceName?: string;\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n maxLen?: number;\r\n overlap?: number;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n progress?: FeedProgress;\r\n } = {},\r\n): Promise<FeedSummary> {\r\n const log = opts.log ?? ((m: string) => console.log(m));\r\n const source = opts.sourceName?.trim() || \"manual\";\r\n const title = opts.title?.trim() || source;\r\n const chunks = chunkMarkdown(text, { maxLen: opts.maxLen ?? 1200, overlap: opts.overlap ?? 180 });\r\n const doc: LoadedDoc = { source, title, chunks };\r\n const progress = opts.progress ?? new FeedProgress({ total: 1, rejected: 0 });\r\n return feedDocs(ks, [doc], { ...opts, progress });\r\n}\r\n","export interface Chunk {\r\n index: number;\r\n content: string;\r\n}\r\n\r\nexport interface ChunkOptions {\r\n maxLen?: number;\r\n overlap?: number;\r\n}\r\n\r\nconst HEADING_RE = /^(#{1,6})\\s+(.+)$/;\r\n\r\nfunction splitBlocks(text: string): string[] {\r\n return text\r\n .split(/\\n{2,}/)\r\n .map((b) => b.trim())\r\n .filter((b) => b.length > 0);\r\n}\r\n\r\nfunction cutPoint(slice: string): number {\r\n const nl = slice.lastIndexOf(\"\\n\");\r\n if (nl > slice.length * 0.5) return nl + 1;\r\n const dot = slice.lastIndexOf(\". \");\r\n if (dot > slice.length * 0.5) return dot + 1;\r\n const sp = slice.lastIndexOf(\" \");\r\n if (sp > slice.length * 0.5) return sp + 1;\r\n return slice.length;\r\n}\r\n\r\nfunction hardSplit(block: string, maxLen: number, overlap: number): string[] {\r\n const parts: string[] = [];\r\n let pos = 0;\r\n while (pos < block.length) {\r\n const end = Math.min(pos + maxLen, block.length);\r\n let slice = block.slice(pos, end);\r\n if (end < block.length) {\r\n const cut = cutPoint(slice);\r\n slice = slice.slice(0, cut);\r\n }\r\n parts.push(slice.trim());\r\n if (end >= block.length) break;\r\n const advanced = Math.max(slice.length - overlap, 1);\r\n pos += advanced;\r\n }\r\n return parts.filter((p) => p.length > 0);\r\n}\r\n\r\nfunction packBlocks(blocks: string[], maxLen: number, overlap: number): string[] {\r\n const pieces: string[] = [];\r\n let current = \"\";\r\n for (const block of blocks) {\r\n const expanded =\r\n block.length > maxLen ? hardSplit(block, maxLen, overlap) : [block];\r\n for (const part of expanded) {\r\n if (!current) {\r\n current = part;\r\n } else if (current.length + 2 + part.length <= maxLen) {\r\n current += \"\\n\\n\" + part;\r\n } else {\r\n pieces.push(current);\r\n const tail =\r\n overlap > 0 && current.length > overlap\r\n ? current.slice(current.length - overlap).replace(/^\\S+\\s+/, \"\")\r\n : \"\";\r\n current = tail ? tail + \"\\n\\n\" + part : part;\r\n }\r\n }\r\n }\r\n if (current) pieces.push(current);\r\n return pieces;\r\n}\r\n\r\nexport function chunkMarkdown(text: string, opts: ChunkOptions = {}): Chunk[] {\r\n const maxLen = opts.maxLen ?? 1200;\r\n const overlap = Math.min(opts.overlap ?? 180, Math.floor(maxLen / 4));\r\n const norm = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n if (!norm) return [];\r\n\r\n const lines = norm.split(\"\\n\");\r\n const sections: { path: string[]; body: string[] }[] = [{ path: [], body: [] }];\r\n for (const line of lines) {\r\n const m = HEADING_RE.exec(line);\r\n if (m) {\r\n const level = m[1]!.length;\r\n const path = sections[sections.length - 1]!.path;\r\n const parent = path.slice(0, level - 1);\r\n sections.push({ path: [...parent, m[2]!.trim()], body: [line] });\r\n } else {\r\n sections[sections.length - 1]!.body.push(line);\r\n }\r\n }\r\n\r\n const pieces: string[] = [];\r\n for (const s of sections) {\r\n const body = s.body.join(\"\\n\").trim();\r\n if (!body) continue;\r\n const context = s.path.length > 0 ? s.path.join(\" > \") + \"\\n\" : \"\";\r\n const packed = packBlocks(splitBlocks(body), maxLen, overlap);\r\n packed.forEach((piece, i) => {\r\n pieces.push(i === 0 || !context ? piece : context + piece);\r\n });\r\n }\r\n return pieces.map((content, index) => ({ index, content }));\r\n}\r\n\r\nexport function chunkPlain(text: string, opts: ChunkOptions = {}): Chunk[] {\r\n const maxLen = opts.maxLen ?? 1200;\r\n const overlap = Math.min(opts.overlap ?? 180, Math.floor(maxLen / 4));\r\n const norm = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n if (!norm) return [];\r\n const pieces = packBlocks(splitBlocks(norm), maxLen, overlap);\r\n return pieces.map((content, index) => ({ index, content }));\r\n}\r\n\r\nexport function mdTitle(text: string): string | undefined {\r\n const m = /^#\\s+(.+)\\s*$/m.exec(text);\r\n return m ? m[1]!.trim() : undefined;\r\n}\r\n","import { JSDOM } from \"jsdom\";\r\nimport TurndownService from \"turndown\";\r\nimport { Readability, isProbablyReaderable } from \"@mozilla/readability\";\r\nimport gfmModule from \"turndown-plugin-gfm\";\r\n\r\nconst gfm: (service: TurndownService) => void =\r\n typeof gfmModule === \"function\"\r\n ? (gfmModule as unknown as (service: TurndownService) => void)\r\n : ((gfmModule as { gfm?: (service: TurndownService) => void }).gfm as (service: TurndownService) => void);\r\n\r\nconst REMOVE_SELECTORS =\r\n \"script, style, noscript, template, iframe, svg, nav, footer, aside, form, button\";\r\n\r\nconst SHELL_MARKER_RE =\r\n /id=[\"'](root|app|__next|__nuxt|q-app)[\"']|data-reactroot|ng-version=/i;\r\nconst SHELL_TEXT_THRESHOLD = 250;\r\n\r\nlet service: TurndownService | undefined;\r\n\r\nfunction turndown(): TurndownService {\r\n if (!service) {\r\n service = new TurndownService({\r\n headingStyle: \"atx\",\r\n codeBlockStyle: \"fenced\",\r\n bulletListMarker: \"-\",\r\n });\r\n if (typeof gfm === \"function\") {\r\n service.use(gfm);\r\n }\r\n service.remove([\"button\"]);\r\n }\r\n return service;\r\n}\r\n\r\nexport function parseHtmlFilter(spec: string): string[] {\r\n const steps = spec.split(/\\s*->\\s*/).map((s) => s.trim()).filter(Boolean);\r\n if (steps.length === 0) {\r\n throw new Error(`invalid --html-filter '${spec.trim()}': expected a CSS selector chain, e.g. '#article -> .content'`);\r\n }\r\n return steps;\r\n}\r\n\r\nexport function validateCssSelector(selector: string): void {\r\n const dom = new JSDOM();\r\n try {\r\n dom.window.document.querySelector(selector);\r\n } catch (err) {\r\n throw new Error(`invalid CSS selector '${selector}': ${err instanceof Error ? err.message : err}`);\r\n }\r\n}\r\n\r\nfunction selectChain(scope: Document | Element, steps: string[]): Element[] | undefined {\r\n for (const step of steps.slice(0, -1)) {\r\n const next = scope.querySelector(step);\r\n if (!next) return undefined;\r\n scope = next;\r\n }\r\n const matches = [...scope.querySelectorAll(steps[steps.length - 1]!)];\r\n return matches.length > 0 ? matches : undefined;\r\n}\r\n\r\nfunction elementsToMarkdown(elements: Element[]): string {\r\n const parts: string[] = [];\r\n for (const el of elements) {\r\n try {\r\n parts.push(turndown().turndown(el.innerHTML));\r\n } catch {\r\n parts.push(el.textContent ?? \"\");\r\n }\r\n }\r\n return parts.join(\"\\n\\n\");\r\n}\r\n\r\nexport function htmlToMarkdown(\r\n html: string,\r\n opts: { filter?: string } = {},\r\n): { markdown: string; title?: string } {\r\n const dom = new JSDOM(html);\r\n const doc = dom.window.document;\r\n doc.querySelectorAll(REMOVE_SELECTORS).forEach((el) => el.remove());\r\n\r\n const title =\r\n doc.title?.trim() || doc.querySelector(\"h1\")?.textContent?.trim() || undefined;\r\n\r\n let markdown = \"\";\r\n if (opts.filter) {\r\n const elements = selectChain(doc, parseHtmlFilter(opts.filter));\r\n if (elements) markdown = elementsToMarkdown(elements);\r\n } else {\r\n const root = doc.body ?? doc.documentElement;\r\n try {\r\n markdown = turndown().turndown(root.innerHTML);\r\n } catch {\r\n markdown = root.textContent ?? \"\";\r\n }\r\n }\r\n markdown = markdown.replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n return { markdown, title: title || undefined };\r\n}\r\n\r\nexport interface ExtractedPage {\r\n markdown: string;\r\n title?: string;\r\n description?: string;\r\n tags?: string[];\r\n likelyShell: boolean;\r\n filterMatched?: boolean;\r\n}\r\n\r\nfunction metaContent(doc: Document, selectors: string[]): string | undefined {\r\n for (const selector of selectors) {\r\n const el = doc.querySelector(selector);\r\n const value = (el?.getAttribute(\"content\") ?? el?.textContent ?? \"\").trim();\r\n if (value) return value;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction collectTags(doc: Document): string[] {\r\n const tags: string[] = [];\r\n const keywords = metaContent(doc, ['meta[name=\"keywords\"]']);\r\n if (keywords) {\r\n for (const part of keywords.split(\",\")) {\r\n const tag = part.trim();\r\n if (tag) tags.push(tag);\r\n }\r\n }\r\n doc.querySelectorAll('meta[property=\"og:article:tag\"]').forEach((el) => {\r\n const value = (el.getAttribute(\"content\") ?? \"\").trim();\r\n if (value) tags.push(value);\r\n });\r\n const seen = new Set<string>();\r\n return tags.filter((t) => {\r\n const key = t.toLowerCase();\r\n if (seen.has(key)) return false;\r\n seen.add(key);\r\n return true;\r\n });\r\n}\r\n\r\nexport function extractPage(html: string, opts: { filter?: string } = {}): ExtractedPage {\r\n const dom = new JSDOM(html);\r\n const doc = dom.window.document;\r\n\r\n const title =\r\n doc.title?.trim() ||\r\n doc.querySelector('meta[property=\"og:title\"]')?.getAttribute(\"content\")?.trim() ||\r\n doc.querySelector(\"h1\")?.textContent?.trim() ||\r\n undefined;\r\n const description = metaContent(doc, [\r\n 'meta[name=\"description\"]',\r\n 'meta[property=\"og:description\"]',\r\n ]);\r\n const tags = collectTags(doc);\r\n\r\n doc.querySelectorAll(REMOVE_SELECTORS).forEach((el) => el.remove());\r\n\r\n let markdown = \"\";\r\n let filterMatched: boolean | undefined;\r\n if (opts.filter) {\r\n const elements = selectChain(doc, parseHtmlFilter(opts.filter));\r\n filterMatched = elements !== undefined;\r\n if (elements) markdown = elementsToMarkdown(elements);\r\n } else {\r\n try {\r\n if (isProbablyReaderable(doc)) {\r\n const article = new Readability(doc).parse();\r\n if (article?.content) markdown = turndown().turndown(article.content);\r\n }\r\n } catch {\r\n markdown = \"\";\r\n }\r\n if (!markdown.trim()) {\r\n const root = doc.body ?? doc.documentElement;\r\n try {\r\n markdown = turndown().turndown(root.innerHTML);\r\n } catch {\r\n markdown = root.textContent ?? \"\";\r\n }\r\n }\r\n }\r\n markdown = markdown.replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n\r\n const likelyShell = markdown.length < SHELL_TEXT_THRESHOLD && SHELL_MARKER_RE.test(html);\r\n return {\r\n markdown,\r\n title,\r\n description,\r\n tags: tags.length > 0 ? tags : undefined,\r\n likelyShell,\r\n filterMatched,\r\n };\r\n}\r\n","const BAR_WIDTH = 20;\nconst PLAIN_STEP = 32;\n\nfunction fmt(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\nfunction bar(pct: number): string {\n const filled = Math.max(0, Math.min(BAR_WIDTH, Math.round(pct * BAR_WIDTH)));\n return \"#\".repeat(filled) + \".\".repeat(BAR_WIDTH - filled);\n}\n\nfunction pct(p: number): string {\n return `${Math.round(Math.max(0, Math.min(1, p)) * 100)}%`;\n}\n\nexport interface FeedProgressOptions {\n total: number;\n rejected: number;\n out?: (s: string) => void;\n interactive?: boolean;\n}\n\ninterface FileSlot {\n source: string;\n totalChunks: number;\n totalChars: number;\n doneChunks: number;\n doneChars: number;\n printedChunks: number;\n}\n\nexport interface FileProgressHandle {\n handled(chunks: number, chars: number): void;\n}\n\nconst NOOP_HANDLE: FileProgressHandle = { handled: () => {} };\n\nexport class FeedProgress {\n private readonly write: (s: string) => void;\n private readonly interactive: boolean;\n private readonly total: number;\n private readonly rejected: number;\n private readonly slots: FileSlot[] = [];\n private filesDone = 0;\n private totalChars = 0;\n private blockLines = 0;\n private finished = false;\n\n constructor(opts: FeedProgressOptions) {\n this.total = Math.max(0, Math.floor(opts.total));\n this.rejected = Math.max(0, Math.floor(opts.rejected));\n this.write = opts.out ?? ((s: string) => process.stderr.write(s));\n this.interactive = opts.interactive ?? (opts.out === undefined && !!process.stderr.isTTY);\n }\n\n get isInteractive(): boolean {\n return this.interactive;\n }\n\n startFile(source: string, totalChunks: number, totalChars: number): FileProgressHandle {\n if (this.finished) return NOOP_HANDLE;\n const slot: FileSlot = { source, totalChunks, totalChars, doneChunks: 0, doneChars: 0, printedChunks: 0 };\n this.slots.push(slot);\n this.render();\n return {\n handled: (chunks, chars) => this.handleSlot(slot, chunks, chars),\n };\n }\n\n log(msg: string): void {\n if (this.finished) return;\n this.clearBlock();\n this.write(`${msg}\\n`);\n }\n\n finish(): void {\n if (this.finished) return;\n this.finished = true;\n if (this.slots.length === 0 && this.total === 0 && this.rejected === 0) return;\n if (this.interactive) {\n this.redraw(this.lines());\n this.write(\"\\n\");\n this.blockLines = 0;\n } else {\n this.write(`${this.totalLine()}\\n`);\n }\n }\n\n close(): void {\n if (this.finished) return;\n this.finished = true;\n this.clearBlock();\n }\n\n private lines(): string[] {\n return [...this.slots.map((slot) => this.fileLine(slot)), this.totalLine()];\n }\n\n private handleSlot(slot: FileSlot, chunks: number, chars: number): void {\n if (this.finished || chunks <= 0 || slot.doneChunks >= slot.totalChunks) return;\n slot.doneChunks += chunks;\n slot.doneChars += chars;\n this.totalChars += chars;\n if (slot.doneChunks >= slot.totalChunks) {\n this.filesDone++;\n if (this.interactive) {\n this.render();\n } else {\n this.printFileLine(slot);\n }\n this.slots.splice(this.slots.indexOf(slot), 1);\n return;\n }\n if (!this.interactive && slot.doneChunks - slot.printedChunks >= PLAIN_STEP) {\n this.printFileLine(slot);\n } else if (this.interactive) {\n this.render();\n }\n }\n\n private render(): void {\n if (!this.interactive) return;\n this.redraw(this.lines());\n }\n\n private printFileLine(slot: FileSlot): void {\n slot.printedChunks = slot.doneChunks;\n this.write(`${this.fileLine(slot)}\\n`);\n }\n\n private fileLine(slot: FileSlot): string {\n const p = slot.totalChunks > 0 ? slot.doneChunks / slot.totalChunks : 1;\n return (\n `[${bar(p)}] ${pct(p).padStart(4)} ${fmt(slot.doneChunks)}/${fmt(slot.totalChunks)} chunks` +\n ` ${fmt(slot.doneChars)}/${fmt(slot.totalChars)} chars ${slot.source}`\n );\n }\n\n private totalLine(): string {\n const p = this.total > 0 ? this.filesDone / this.total : 0;\n const rejected = this.rejected > 0 ? ` | rejected: ${this.rejected} (excluded)` : \"\";\n return `total: ${this.filesDone}/${this.total} files (${pct(p)}) ${fmt(this.totalChars)} chars${rejected}`;\n }\n\n private redraw(lines: string[]): void {\n let out = \"\";\n if (this.blockLines > 1) out += `\\x1b[${this.blockLines - 1}A`;\n out += \"\\r\";\n for (let i = 0; i < lines.length; i++) {\n out += `\\x1b[2K${lines[i]}${i < lines.length - 1 ? \"\\n\" : \"\"}`;\n }\n this.write(out);\n this.blockLines = lines.length;\n }\n\n private clearBlock(): void {\n if (!this.interactive || this.blockLines === 0) {\n this.blockLines = 0;\n return;\n }\n let out = \"\";\n if (this.blockLines > 1) out += `\\x1b[${this.blockLines - 1}A`;\n out += \"\\r\";\n for (let i = 0; i < this.blockLines; i++) {\n out += `\\x1b[2K${i < this.blockLines - 1 ? \"\\n\" : \"\"}`;\n }\n out += \"\\n\";\n this.write(out);\n this.blockLines = 0;\n }\n}\n","import { mkdtempSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n CheerioCrawler,\n PlaywrightCrawler,\n PuppeteerCrawler,\n Request as CrawleeRequest,\n RequestQueue,\n RobotsTxtFile,\n Sitemap,\n constructGlobObjectsFromGlobs,\n filterRequestsByPatterns,\n log,\n} from \"crawlee\";\nimport { chunkMarkdown, chunkPlain, mdTitle } from \"./chunk.js\";\nimport { extractPage, type ExtractedPage } from \"./html.js\";\nimport { feedDocs, type FeedSummary, type LoadedDoc, type SkippedFile } from \"./ingest.js\";\nimport { FeedProgress } from \"./progress.js\";\nimport type { KnowledgeSource } from \"./db.js\";\n\nexport type CrawlerKind = \"auto\" | \"crawlee\" | \"playwright\" | \"puppeteer\";\n\nexport const CRAWLER_KINDS: CrawlerKind[] = [\"auto\", \"crawlee\", \"playwright\", \"puppeteer\"];\n\nexport type SitemapMode =\n | { kind: \"auto\" }\n | { kind: \"sitemap-only\" }\n | { kind: \"html-only\" }\n | { kind: \"selector\"; selector: string };\n\nexport function parseSitemapOption(value: string): SitemapMode {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(\"invalid --sitemap '': use auto, sitemap-only, html-only or a CSS selector\");\n }\n const key = trimmed.toLowerCase();\n if (key === \"auto\") return { kind: \"auto\" };\n if (key === \"sitemap-only\") return { kind: \"sitemap-only\" };\n if (key === \"html-only\") return { kind: \"html-only\" };\n return { kind: \"selector\", selector: trimmed };\n}\n\nconst BINARY_LINK_RE =\n /\\.(css|js|mjs|cjs|map|png|jpe?g|gif|svg|webp|avif|ico|bmp|tiff?|woff2?|ttf|otf|eot|pdf|zip|gz|tgz|tar|rar|7z|bz2|xz|zst|mp3|mp4|m4a|webm|mov|avi|wmv|flv|docx?|xlsx?|pptx?|odt|ods|odp|rtf|dmg|exe|msi|apk|iso|bin|wasm|deb|rpm)(\\?.*)?$/i;\n\ninterface CrawlOptions {\n crawler: CrawlerKind;\n maxPages: number;\n depth: number;\n maxLen: number;\n overlap: number;\n tags?: string[];\n urlFilter?: string[];\n htmlFilter?: string;\n log: (msg: string) => void;\n sitemap?: SitemapMode;\n}\n\ninterface RunOptions extends CrawlOptions {\n followLinks: boolean;\n linkSelector?: string;\n selectorStats: { hits: number; misses: number };\n}\n\nexport interface CrawlResult {\n docs: LoadedDoc[];\n skipped: SkippedFile[];\n}\n\ninterface PageDeps {\n maxLen: number;\n overlap: number;\n cliTags?: string[];\n urlFilter?: string[];\n htmlFilter?: string;\n followLinks?: boolean;\n linkSelector?: string;\n selectorStats: { hits: number; misses: number };\n}\n\nprocess.env.CRAWLEE_STORAGE_DIR ??= mkdtempSync(path.join(tmpdir(), \"gresmcp-crawl-\"));\n\nasync function freshQueue(): Promise<RequestQueue> {\n return RequestQueue.open(`gresmcp-${randomUUID()}`);\n}\n\nfunction normalizeSeedUrl(seed: string): string {\n let url: URL;\n try {\n url = new URL(seed.trim());\n } catch {\n throw new Error(`invalid URL '${seed}'`);\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new Error(`unsupported URL protocol '${url.protocol.replace(\":\", \"\")}' (use http or https)`);\n }\n url.hash = \"\";\n return url.toString();\n}\n\nfunction responseStatus(response: unknown): number | undefined {\n if (!response || typeof response !== \"object\") return undefined;\n const res = response as { status?: unknown; statusCode?: unknown };\n if (typeof res.status === \"number\") return res.status;\n if (typeof res.status === \"function\") {\n const value = (res.status as () => unknown)();\n return typeof value === \"number\" ? value : undefined;\n }\n if (typeof res.statusCode === \"number\") return res.statusCode;\n return undefined;\n}\n\nfunction toText(body: string | Buffer): string {\n return typeof body === \"string\" ? body : body.toString(\"utf-8\");\n}\n\nfunction titleFor(url: string, fallback?: string): string {\n const trimmed = fallback?.trim();\n if (trimmed) return trimmed;\n try {\n const segment = new URL(url).pathname.split(\"/\").filter(Boolean).pop();\n const name = segment ? decodeURIComponent(segment) : \"\";\n return name || url;\n } catch {\n return url;\n }\n}\n\nfunction unionTags(...lists: (string[] | undefined)[]): string[] | undefined {\n const out: string[] = [];\n const seen = new Set<string>();\n for (const list of lists) {\n for (const tag of list ?? []) {\n const value = tag.trim();\n if (!value) continue;\n const key = value.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(value);\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\nfunction buildDoc(\n url: string,\n kind: \"html\" | \"md\" | \"plain\",\n text: string,\n page: ExtractedPage | undefined,\n deps: PageDeps,\n): LoadedDoc | undefined {\n const chunkOpts = { maxLen: deps.maxLen, overlap: deps.overlap };\n const chunks = kind === \"plain\" ? chunkPlain(text, chunkOpts) : chunkMarkdown(text, chunkOpts);\n if (chunks.length === 0) return undefined;\n const title = kind === \"html\"\n ? titleFor(url, page?.title)\n : kind === \"md\"\n ? mdTitle(text) ?? titleFor(url)\n : titleFor(url);\n const metadata: Record<string, unknown> = { source_url: url, crawled_at: new Date().toISOString() };\n if (page?.description) metadata.description = page.description;\n const tags = unionTags(page?.tags, deps.cliTags);\n if (tags) metadata.tags = tags;\n return { source: url, title, chunks, metadata };\n}\n\nfunction dedupeDocs(docs: LoadedDoc[]): LoadedDoc[] {\n const bySource = new Map<string, LoadedDoc>();\n for (const doc of docs) {\n if (!bySource.has(doc.source)) bySource.set(doc.source, doc);\n }\n return [...bySource.values()];\n}\n\nfunction shortReason(err: Error): string {\n const message = (err?.message ?? String(err)).replace(/\\s+/g, \" \").trim();\n const contentType = /served Content-Type ([^,\\s]+),/.exec(message);\n if (contentType) return `unsupported content-type '${contentType[1]}'`;\n return message.slice(0, 200);\n}\n\ninterface CrawlSink {\n docs: LoadedDoc[];\n skipped: SkippedFile[];\n shellUrls?: string[];\n}\n\nasync function crawlWithCheerio(\n queue: RequestQueue,\n seedUrls: string[],\n opts: RunOptions,\n sink: CrawlSink,\n): Promise<void> {\n const crawler = new CheerioCrawler({\n requestQueue: queue,\n maxRequestsPerCrawl: Math.max(1, opts.maxPages),\n maxCrawlDepth: Math.max(0, opts.depth),\n additionalMimeTypes: [\"text/plain\", \"text/markdown\"],\n async requestHandler(ctx) {\n const { request, response, contentType, body, $ } = ctx;\n const url = request.loadedUrl ?? request.url;\n const status = responseStatus(response);\n if (status === undefined || status < 200 || status >= 300) {\n sink.skipped.push({ path: url, reason: status === undefined ? \"no HTTP response\" : `HTTP ${status}` });\n return;\n }\n const type = contentType?.type ?? \"\";\n if (type === \"text/html\" || type === \"application/xhtml+xml\") {\n const html = typeof body === \"string\" ? body : toText(body as Buffer);\n const page = extractPage(html, { filter: opts.htmlFilter });\n if (page.likelyShell) {\n sink.shellUrls?.push(url);\n sink.skipped.push({ path: url, reason: \"likely JS-rendered shell\" });\n return;\n }\n if (opts.htmlFilter && !page.filterMatched) {\n sink.skipped.push({ path: url, reason: `html filter '${opts.htmlFilter}' matched nothing` });\n return;\n }\n if (!page.markdown.trim()) {\n sink.skipped.push({ path: url, reason: \"empty\" });\n return;\n }\n const doc = buildDoc(url, \"html\", page.markdown, page, sinkDeps(opts));\n if (!doc) {\n sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n sink.docs.push(doc);\n if (opts.followLinks !== false) {\n const selector = opts.linkSelector;\n if (selector) {\n if ($(selector).length > 0) {\n opts.selectorStats.hits += 1;\n await ctx.enqueueLinks({\n selector,\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: opts.urlFilter,\n });\n } else {\n opts.selectorStats.misses += 1;\n }\n } else {\n await ctx.enqueueLinks({\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: opts.urlFilter,\n });\n }\n }\n } else if (type === \"text/markdown\") {\n const doc = buildDoc(url, \"md\", toText(body as Buffer), undefined, sinkDeps(opts));\n if (!doc) {\n sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n sink.docs.push(doc);\n } else if (type === \"text/plain\") {\n const doc = buildDoc(url, \"plain\", toText(body as Buffer), undefined, sinkDeps(opts));\n if (!doc) {\n sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n sink.docs.push(doc);\n } else {\n sink.skipped.push({ path: url, reason: `unsupported content-type '${type}'` });\n }\n },\n async failedRequestHandler(ctx, error) {\n const url = ctx.request.loadedUrl ?? ctx.request.url;\n sink.skipped.push({ path: url, reason: shortReason(error) });\n },\n });\n\n try {\n await crawler.run(seedUrls);\n } finally {\n await crawler.teardown().catch(() => {});\n }\n}\n\nfunction sinkDeps(opts: RunOptions): PageDeps {\n return {\n maxLen: opts.maxLen,\n overlap: opts.overlap,\n cliTags: opts.tags,\n urlFilter: opts.urlFilter,\n htmlFilter: opts.htmlFilter,\n followLinks: opts.followLinks,\n linkSelector: opts.linkSelector,\n selectorStats: opts.selectorStats,\n };\n}\n\nasync function importOptional(name: string): Promise<Record<string, unknown> | undefined> {\n try {\n return (await import(name)) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\nasync function requireBrowserEngine(kind: \"playwright\" | \"puppeteer\"): Promise<void> {\n const moduleName = kind === \"playwright\" ? \"playwright\" : \"puppeteer\";\n const mod = await importOptional(moduleName);\n if (!mod) {\n const install = kind === \"playwright\"\n ? \"npm i -g playwright && npx playwright install chromium\"\n : \"npm i -g puppeteer\";\n throw new Error(`--crawler ${kind} requires ${moduleName}, which is not installed (install it with: ${install})`);\n }\n}\n\ninterface BrowserHandlerDeps extends PageDeps {\n sink: CrawlSink;\n}\n\nasync function handleBrowserPage(ctx: any, deps: BrowserHandlerDeps): Promise<void> {\n const request = ctx.request as { url: string; loadedUrl?: string };\n const url = request.loadedUrl ?? request.url;\n const status = responseStatus(ctx.response);\n if (status === undefined || status < 200 || status >= 300) {\n deps.sink.skipped.push({ path: url, reason: status === undefined ? \"no HTTP response\" : `HTTP ${status}` });\n return;\n }\n const html = await (ctx.page as { content(): Promise<string> }).content();\n const page = extractPage(html, { filter: deps.htmlFilter });\n if (deps.htmlFilter && !page.filterMatched) {\n deps.sink.skipped.push({ path: url, reason: `html filter '${deps.htmlFilter}' matched nothing` });\n return;\n }\n if (!page.markdown.trim()) {\n deps.sink.skipped.push({ path: url, reason: \"empty after render\" });\n return;\n }\n const doc = buildDoc(url, \"html\", page.markdown, page, deps);\n if (!doc) {\n deps.sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n deps.sink.docs.push(doc);\n if (deps.followLinks !== false) {\n const selector = deps.linkSelector;\n if (selector) {\n const elements = await (ctx.page as { $$(selector: string): Promise<unknown[]> }).$$(selector);\n if (elements.length > 0) {\n deps.selectorStats.hits += 1;\n await ctx.enqueueLinks({\n selector,\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: deps.urlFilter,\n });\n } else {\n deps.selectorStats.misses += 1;\n }\n } else {\n await ctx.enqueueLinks({\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: deps.urlFilter,\n });\n }\n }\n}\n\nasync function crawlWithBrowser(\n kind: \"playwright\" | \"puppeteer\",\n queue: RequestQueue,\n seedUrls: string[],\n opts: RunOptions,\n sink: CrawlSink,\n): Promise<void> {\n const crawler = kind === \"playwright\"\n ? new PlaywrightCrawler({\n requestQueue: queue,\n maxRequestsPerCrawl: Math.max(1, opts.maxPages),\n maxCrawlDepth: Math.max(0, opts.depth),\n preNavigationHooks: [\n (_ctx: unknown, gotoOptions: { waitUntil?: string; timeout?: number }) => {\n gotoOptions.waitUntil = \"networkidle\";\n gotoOptions.timeout = 30_000;\n },\n ],\n requestHandler: (ctx: any) => handleBrowserPage(ctx, { ...sinkDeps(opts), sink }),\n failedRequestHandler: (ctx: any, error: Error) => {\n const request = ctx.request as { url: string; loadedUrl?: string };\n sink.skipped.push({ path: request.loadedUrl ?? request.url, reason: shortReason(error) });\n },\n } as never)\n : new PuppeteerCrawler({\n requestQueue: queue,\n maxRequestsPerCrawl: Math.max(1, opts.maxPages),\n maxCrawlDepth: Math.max(0, opts.depth),\n preNavigationHooks: [\n (_ctx: unknown, gotoOptions: { waitUntil?: string; timeout?: number }) => {\n gotoOptions.waitUntil = \"networkidle2\";\n gotoOptions.timeout = 30_000;\n },\n ],\n requestHandler: (ctx: any) => handleBrowserPage(ctx, { ...sinkDeps(opts), sink }),\n failedRequestHandler: (ctx: any, error: Error) => {\n const request = ctx.request as { url: string; loadedUrl?: string };\n sink.skipped.push({ path: request.loadedUrl ?? request.url, reason: shortReason(error) });\n },\n } as never);\n\n try {\n await crawler.run(seedUrls);\n } finally {\n await crawler.teardown().catch(() => {});\n }\n}\n\nfunction normalizeSitemapUrls(urls: string[]): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n for (const raw of urls) {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n continue;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") continue;\n url.hash = \"\";\n const key = url.toString();\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(key);\n }\n return out;\n}\n\nfunction applyUrlFilter(urls: string[], globs: string[] | undefined): string[] {\n if (!globs || globs.length === 0) return urls;\n const requests = urls.map((url) => new CrawleeRequest({ url }));\n const patterns = constructGlobObjectsFromGlobs(globs);\n return filterRequestsByPatterns(requests, patterns).map((r) => r.url);\n}\n\nasync function loadSitemap(urls: string[]): Promise<string[]> {\n try {\n const sitemap = await Sitemap.load(urls, undefined, { reportNetworkErrors: false });\n return normalizeSitemapUrls(sitemap.urls);\n } catch {\n return [];\n }\n}\n\nasync function discoverSitemapUrls(seedUrl: string): Promise<string[] | undefined> {\n const origin = new URL(seedUrl).origin;\n const fromSitemapXml = await loadSitemap([`${origin}/sitemap.xml`]);\n if (fromSitemapXml.length > 0) return fromSitemapXml;\n try {\n const robots = await RobotsTxtFile.find(seedUrl);\n const referenced = robots.getSitemaps();\n if (referenced.length > 0) {\n const fromRobots = await loadSitemap(referenced);\n if (fromRobots.length > 0) return fromRobots;\n }\n } catch {\n // robots.txt unreachable or malformed — treated as no sitemap\n }\n return undefined;\n}\n\nasync function runCrawl(kind: CrawlerKind, seedUrls: string[], opts: RunOptions): Promise<CrawlResult> {\n if (kind === \"playwright\" || kind === \"puppeteer\") {\n await requireBrowserEngine(kind);\n const sink: CrawlSink = { docs: [], skipped: [] };\n const queue = await freshQueue();\n await crawlWithBrowser(kind, queue, seedUrls, opts, sink);\n return { docs: dedupeDocs(sink.docs), skipped: sink.skipped };\n }\n\n const shellUrls: string[] = [];\n const sink: CrawlSink = { docs: [], skipped: [], shellUrls };\n const staticQueue = await freshQueue();\n await crawlWithCheerio(staticQueue, seedUrls, opts, sink);\n if (kind !== \"auto\" || shellUrls.length === 0) {\n return { docs: dedupeDocs(sink.docs), skipped: sink.skipped };\n }\n\n opts.log(\n `${shellUrls.length} page(s) look JS-rendered; retrying with playwright (install: npm i -g playwright && npx playwright install chromium) ...`,\n );\n const mod = await importOptional(\"playwright\");\n if (!mod) {\n return { docs: dedupeDocs(sink.docs), skipped: sink.skipped };\n }\n const browserSink: CrawlSink = { docs: [], skipped: [] };\n const browserQueue = await freshQueue();\n await crawlWithBrowser(\"playwright\", browserQueue, shellUrls, opts, browserSink);\n return {\n docs: dedupeDocs([...sink.docs, ...browserSink.docs]),\n skipped: [...sink.skipped, ...browserSink.skipped],\n };\n}\n\nexport async function crawlWebsite(seed: string, opts: CrawlOptions): Promise<CrawlResult> {\n const seedUrl = normalizeSeedUrl(seed);\n const kind = opts.crawler;\n const mode: SitemapMode = opts.sitemap ?? { kind: \"auto\" };\n const selectorStats = { hits: 0, misses: 0 };\n\n if (mode.kind === \"auto\" || mode.kind === \"sitemap-only\") {\n const sitemapUrls = await discoverSitemapUrls(seedUrl);\n if (sitemapUrls) {\n const filtered = applyUrlFilter(sitemapUrls, opts.urlFilter);\n const detail = filtered.length < sitemapUrls.length\n ? `${filtered.length} matching --url-filter`\n : `${filtered.length} URL(s)`;\n opts.log(`sitemap: ${sitemapUrls.length} URL(s) discovered, ${detail} to crawl`);\n return runCrawl(kind, filtered, { ...opts, followLinks: false, selectorStats });\n }\n if (mode.kind === \"sitemap-only\") {\n opts.log(`warning: no sitemap.xml and no sitemaps in robots.txt found for ${seedUrl}; nothing to ingest`);\n return { docs: [], skipped: [] };\n }\n opts.log(\"no sitemap found; falling back to HTML link crawling\");\n }\n\n const result = await runCrawl(kind, [seedUrl], {\n ...opts,\n followLinks: true,\n linkSelector: mode.kind === \"selector\" ? mode.selector : undefined,\n selectorStats,\n });\n if (mode.kind === \"selector\" && selectorStats.hits === 0 && selectorStats.misses > 0) {\n opts.log(`warning: --sitemap selector '${mode.selector}' matched no links`);\n }\n return result;\n}\n\nexport interface FeedUrlOptions {\n crawler?: CrawlerKind;\n sitemap?: SitemapMode;\n maxPages?: number;\n depth?: number;\n urlFilter?: string[];\n htmlFilter?: string;\n replace?: boolean;\n dryRun?: boolean;\n batchSize?: number;\n maxLen?: number;\n overlap?: number;\n tags?: string[];\n metadata?: Record<string, unknown>;\n log?: (msg: string) => void;\n progress?: FeedProgress;\n}\n\nexport async function feedUrl(\n ks: KnowledgeSource,\n url: string,\n opts: FeedUrlOptions = {},\n): Promise<FeedSummary> {\n const log = opts.log ?? ((m: string) => console.log(m));\n const kind: CrawlerKind = opts.crawler ?? \"auto\";\n if (!CRAWLER_KINDS.includes(kind)) {\n throw new Error(`unknown crawler '${kind}' (use auto, crawlee, playwright or puppeteer)`);\n }\n const maxPages = opts.maxPages && opts.maxPages > 0 ? Math.floor(opts.maxPages) : 999;\n const depth = typeof opts.depth === \"number\" && Number.isFinite(opts.depth) && opts.depth >= 0\n ? Math.floor(opts.depth)\n : 5;\n const maxLen = opts.maxLen ?? 1200;\n const overlap = opts.overlap ?? 180;\n\n const { docs, skipped } = await crawlWebsite(url, {\n crawler: kind,\n maxPages,\n depth,\n maxLen,\n overlap,\n tags: opts.tags,\n urlFilter: opts.urlFilter,\n htmlFilter: opts.htmlFilter,\n sitemap: opts.sitemap,\n log,\n });\n for (const s of skipped) {\n log(`skipped ${s.path}: ${s.reason}`);\n }\n const progress = opts.progress ?? new FeedProgress({ total: docs.length, rejected: skipped.length });\n const summary = await feedDocs(ks, docs, {\n replace: opts.replace,\n dryRun: opts.dryRun,\n batchSize: opts.batchSize,\n tags: opts.tags,\n metadata: opts.metadata,\n log,\n progress,\n });\n return { ...summary, skippedFiles: [...summary.skippedFiles, ...skipped] };\n}\n\ntry {\n if (typeof log?.setLevel === \"function\" && log.LEVELS) {\n log.setLevel(log.LEVELS.ERROR);\n }\n} catch {\n}\n","import pg from \"pg\";\r\nimport { databaseUrl, normalizeUrl, ollamaUrl } from \"./config.js\";\r\nimport { entryTableName } from \"./db.js\";\r\nimport { probeModel } from \"./ollama.js\";\r\n\r\nexport const MIN_NODE_MAJOR = 20;\r\nexport const MIN_PGVECTOR_VERSION = \"0.5.0\";\r\nconst DB_CONNECT_TIMEOUT_MS = 5_000;\r\nconst OLLAMA_TIMEOUT_MS = 10_000;\r\n\r\nexport type CheckStatus = \"ok\" | \"warn\" | \"fail\" | \"skip\";\r\n\r\nexport interface CheckResult {\r\n id: string;\r\n status: CheckStatus;\r\n detail: string;\r\n}\r\n\r\nexport interface KsInfo {\r\n id: string;\r\n name: string;\r\n embedding_model: string;\r\n embedding_dim: number;\r\n ollama_url: string;\r\n}\r\n\r\nexport interface CheckOptions {\r\n model: string;\r\n url?: string;\r\n probe?: boolean;\r\n}\r\n\r\nexport function compareVersions(a: string, b: string): number {\r\n const pa = a.split(/[.-]/).map((s) => parseInt(s, 10) || 0);\r\n const pb = b.split(/[.-]/).map((s) => parseInt(s, 10) || 0);\r\n const len = Math.max(pa.length, pb.length);\r\n for (let i = 0; i < len; i++) {\r\n const d = (pa[i] ?? 0) - (pb[i] ?? 0);\r\n if (d !== 0) return d < 0 ? -1 : 1;\r\n }\r\n return 0;\r\n}\r\n\r\nexport function modelMatches(tag: string, wanted: string): boolean {\r\n if (tag === wanted) return true;\r\n if (wanted.includes(\":\")) return false;\r\n return tag === `${wanted}:latest`;\r\n}\r\n\r\nfunction errMsg(err: unknown): string {\r\n return err instanceof Error ? err.message : String(err);\r\n}\r\n\r\nfunction shortVersion(v: string): string {\r\n return v.split(/\\s+/).slice(0, 2).join(\" \") || v;\r\n}\r\n\r\ntype TagResult = { names: string[] } | { error: string };\r\n\r\nasync function fetchTags(baseUrl: string): Promise<TagResult> {\r\n try {\r\n const res = await fetch(`${normalizeUrl(baseUrl)}/api/tags`, {\r\n headers: { accept: \"application/json\" },\r\n signal: AbortSignal.timeout(OLLAMA_TIMEOUT_MS),\r\n });\r\n if (!res.ok) return { error: `HTTP ${res.status}` };\r\n const data = (await res.json()) as { models?: { name?: string; model?: string }[] };\r\n const names = (data.models ?? [])\r\n .map((m) => m.name ?? m.model ?? \"\")\r\n .filter(Boolean);\r\n return { names };\r\n } catch (err) {\r\n return { error: errMsg(err) };\r\n }\r\n}\r\n\r\nasync function checkOneModel(\r\n id: string,\r\n model: string,\r\n baseUrl: string,\r\n names: string[],\r\n ks: KsInfo | undefined,\r\n probe: boolean,\r\n): Promise<CheckResult> {\r\n const scope = ks ? ` (ks '${ks.name}')` : \"\";\r\n if (!names.some((n) => modelMatches(n, model))) {\r\n return {\r\n id,\r\n status: \"fail\",\r\n detail: `model '${model}' not found at ${baseUrl}${scope} — run: ollama pull ${model}`,\r\n };\r\n }\r\n if (probe) {\r\n try {\r\n const { dim } = await probeModel(baseUrl, model);\r\n if (ks && dim !== ks.embedding_dim) {\r\n return {\r\n id,\r\n status: \"fail\",\r\n detail: `model '${model}' serves dim=${dim} but ks '${ks.name}' expects dim=${ks.embedding_dim}`,\r\n };\r\n }\r\n return { id, status: \"ok\", detail: `model '${model}' available at ${baseUrl}${scope} (dim=${dim})` };\r\n } catch (err) {\r\n return { id, status: \"fail\", detail: `probe of model '${model}' failed — ${errMsg(err)}${scope}` };\r\n }\r\n }\r\n return { id, status: \"ok\", detail: `model '${model}' available at ${baseUrl}${scope}` };\r\n}\r\n\r\nexport async function runChecks(opts: CheckOptions): Promise<CheckResult[]> {\r\n const results: CheckResult[] = [];\r\n\r\n const major = Number(process.versions.node.split(\".\")[0]);\r\n results.push({\r\n id: \"node\",\r\n status: Number.isFinite(major) && major >= MIN_NODE_MAJOR ? \"ok\" : \"fail\",\r\n detail: `Node ${process.versions.node} (>= ${MIN_NODE_MAJOR} required)`,\r\n });\r\n\r\n let client: pg.Client | undefined;\r\n let dbUp = false;\r\n let kss: KsInfo[] = [];\r\n try {\r\n try {\r\n client = new pg.Client({\r\n connectionString: databaseUrl(),\r\n connectionTimeoutMillis: DB_CONNECT_TIMEOUT_MS,\r\n });\r\n client.on(\"error\", () => {});\r\n await client.connect();\r\n const v = await client.query(\"SELECT version() AS v\");\r\n dbUp = true;\r\n results.push({\r\n id: \"postgres\",\r\n status: \"ok\",\r\n detail: `PostgreSQL reachable at ${databaseUrl()} (${shortVersion(String(v.rows[0]?.v ?? \"\"))})`,\r\n });\r\n } catch (err) {\r\n results.push({\r\n id: \"postgres\",\r\n status: \"fail\",\r\n detail: `PostgreSQL not reachable at ${databaseUrl()} — ${errMsg(err)}`,\r\n });\r\n }\r\n\r\n if (dbUp && client) {\r\n try {\r\n await client.query(`CREATE EXTENSION IF NOT EXISTS vector`);\r\n const res = await client.query(\"SELECT extversion AS v FROM pg_extension WHERE extname = 'vector'\");\r\n const ver = res.rows[0]?.v as string | undefined;\r\n if (!ver) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"fail\",\r\n detail: \"pgvector extension not installed — install it on the PostgreSQL server (https://github.com/pgvector/pgvector)\",\r\n });\r\n } else if (compareVersions(ver, MIN_PGVECTOR_VERSION) < 0) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"warn\",\r\n detail: `pgvector ${ver} installed (>= ${MIN_PGVECTOR_VERSION} required for HNSW indexes; older versions fall back to sequential scans)`,\r\n });\r\n } else {\r\n results.push({ id: \"pgvector\", status: \"ok\", detail: `pgvector ${ver} installed` });\r\n }\r\n } catch (err) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"fail\",\r\n detail: `pgvector unavailable — ${errMsg(err)}`,\r\n });\r\n }\r\n } else {\r\n results.push({ id: \"pgvector\", status: \"skip\", detail: \"pgvector check skipped — PostgreSQL unreachable\" });\r\n }\r\n\r\n if (dbUp && client) {\r\n try {\r\n const hasKs = await client.query(\"SELECT to_regclass('ks') IS NOT NULL AS present\");\r\n if (!hasKs.rows[0]?.present) {\r\n results.push({ id: \"schema\", status: \"fail\", detail: \"schema missing — run: gresmcp init\" });\r\n } else {\r\n const ksRes = await client.query(\r\n \"SELECT id, name, embedding_model, embedding_dim, ollama_url FROM ks ORDER BY name\",\r\n );\r\n kss = ksRes.rows as KsInfo[];\r\n const missing: string[] = [];\r\n for (const ks of kss) {\r\n const r = await client.query(\"SELECT to_regclass($1) IS NOT NULL AS present\", [entryTableName(ks)]);\r\n if (!r.rows[0]?.present) missing.push(ks.name);\r\n }\r\n if (missing.length > 0) {\r\n results.push({\r\n id: \"schema\",\r\n status: \"fail\",\r\n detail: `entry table missing for: ${missing.join(\", \")} — run: gresmcp init`,\r\n });\r\n } else {\r\n results.push({\r\n id: \"schema\",\r\n status: \"ok\",\r\n detail: `schema ready (${kss.length} knowledge source(s))`,\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n results.push({ id: \"schema\", status: \"fail\", detail: `schema check failed — ${errMsg(err)}` });\r\n }\r\n } else {\r\n results.push({ id: \"schema\", status: \"skip\", detail: \"schema check skipped — PostgreSQL unreachable\" });\r\n }\r\n } finally {\r\n if (client) {\r\n try {\r\n await client.end();\r\n } catch {}\r\n }\r\n }\r\n\r\n const defaultUrl = ollamaUrl(opts.url);\r\n const tagCache = new Map<string, Promise<TagResult>>();\r\n const getTags = (baseUrl: string): Promise<TagResult> => {\r\n const key = normalizeUrl(baseUrl);\r\n let entry = tagCache.get(key);\r\n if (!entry) {\r\n entry = fetchTags(key);\r\n tagCache.set(key, entry);\r\n }\r\n return entry;\r\n };\r\n\r\n const defaultTags = await getTags(defaultUrl);\r\n results.push(\r\n \"error\" in defaultTags\r\n ? { id: \"ollama\", status: \"fail\", detail: `Ollama not reachable at ${defaultUrl} — ${defaultTags.error}` }\r\n : { id: \"ollama\", status: \"ok\", detail: `Ollama reachable at ${defaultUrl} (${defaultTags.names.length} model(s))` },\r\n );\r\n\r\n const tags = await getTags(defaultUrl);\r\n if (\"error\" in tags) {\r\n results.push({\r\n id: \"model\",\r\n status: \"skip\",\r\n detail: `Ollama unreachable at ${defaultUrl} — cannot verify model '${opts.model}'`,\r\n });\r\n } else {\r\n results.push(await checkOneModel(\"model\", opts.model, defaultUrl, tags.names, undefined, opts.probe ?? false));\r\n }\r\n\r\n for (const ks of kss) {\r\n const tags = await getTags(ks.ollama_url);\r\n if (\"error\" in tags) {\r\n results.push({\r\n id: `model:${ks.name}`,\r\n status: \"fail\",\r\n detail: `Ollama not reachable at ${ks.ollama_url} (required by ks '${ks.name}') — ${tags.error}`,\r\n });\r\n continue;\r\n }\r\n results.push(\r\n await checkOneModel(`model:${ks.name}`, ks.embedding_model, ks.ollama_url, tags.names, ks, opts.probe ?? false),\r\n );\r\n }\r\n\r\n return results;\r\n}\r\n","export const VERSION = \"1.2.0\";\r\n"],"mappings":"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","names":["res","path","pct","log","path","path","sink","log","tags","ensureEntryTable"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/db.ts","../src/cli.ts","../src/ollama.ts","../src/ingest.ts","../src/chunk.ts","../src/html.ts","../src/doc.ts","../src/epub.ts","../src/pdf.ts","../src/progress.ts","../src/scrape.ts","../src/check.ts","../src/version.ts"],"sourcesContent":["export const DEFAULT_DATABASE_URL = \"postgresql://gres:gres@localhost/gres\";\r\nexport const DEFAULT_OLLAMA_URL = \"http://localhost:11434\";\r\n\r\nexport function databaseUrl(): string {\r\n return process.env.GRESMCP_DATABASE_URL || DEFAULT_DATABASE_URL;\r\n}\r\n\r\nexport function normalizeUrl(url: string): string {\r\n return url.replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport function ollamaUrl(override?: string): string {\r\n const raw = override || process.env.GRESMCP_OLLAMA_URL || DEFAULT_OLLAMA_URL;\r\n return normalizeUrl(raw);\r\n}\r\n","import { Pool } from \"pg\";\r\nimport { toSql } from \"pgvector\";\r\nimport { createHash } from \"node:crypto\";\r\nimport { databaseUrl, DEFAULT_OLLAMA_URL } from \"./config.js\";\r\n\r\nlet pool: Pool | undefined;\r\n\r\nexport function getPool(): Pool {\r\n if (!pool) {\r\n pool = new Pool({ connectionString: databaseUrl(), max: 5 });\r\n }\r\n return pool;\r\n}\r\n\r\nexport async function closePool(): Promise<void> {\r\n if (pool) {\r\n await pool.end();\r\n pool = undefined;\r\n }\r\n}\r\n\r\nexport interface KnowledgeSource {\r\n id: string;\r\n name: string;\r\n description: string;\r\n embedding_model: string;\r\n embedding_dim: number;\r\n ollama_url: string;\r\n created_at: Date;\r\n updated_at: Date;\r\n}\r\n\r\nexport interface EntryRow {\r\n id: string | number;\r\n source: string;\r\n title: string;\r\n chunk_index: number;\r\n content: string;\r\n content_hash: string;\r\n metadata: Record<string, unknown>;\r\n created_at: Date;\r\n}\r\n\r\nexport function entryTableName(ks: Pick<KnowledgeSource, \"id\">): string {\r\n const name = `entry_${ks.id.replace(/-/g, \"\")}`;\r\n assertTableName(name);\r\n return name;\r\n}\r\n\r\nexport function assertTableName(name: string): void {\r\n if (!/^entry_[0-9a-f]{32}$/.test(name)) {\r\n throw new Error(`Refusing to use unsafe table name: ${name}`);\r\n }\r\n}\r\n\r\nexport function contentHash(content: string): string {\r\n return createHash(\"sha256\").update(content).digest(\"hex\");\r\n}\r\n\r\nexport async function initDb(): Promise<void> {\r\n const p = getPool();\r\n await p.query(`CREATE EXTENSION IF NOT EXISTS vector`);\r\n await p.query(`\r\n CREATE TABLE IF NOT EXISTS ks (\r\n id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\r\n name text NOT NULL UNIQUE,\r\n description text NOT NULL DEFAULT '',\r\n embedding_model text NOT NULL,\r\n embedding_dim integer NOT NULL,\r\n ollama_url text NOT NULL DEFAULT '${DEFAULT_OLLAMA_URL}',\r\n created_at timestamptz NOT NULL DEFAULT now(),\r\n updated_at timestamptz NOT NULL DEFAULT now()\r\n )\r\n `);\r\n}\r\n\r\nexport async function createKs(input: {\r\n name: string;\r\n description?: string;\r\n model: string;\r\n dim: number;\r\n url: string;\r\n}): Promise<KnowledgeSource> {\r\n const res = await getPool().query(\r\n `INSERT INTO ks (name, description, embedding_model, embedding_dim, ollama_url)\r\n VALUES ($1, $2, $3, $4, $5)\r\n RETURNING *`,\r\n [input.name, input.description ?? \"\", input.model, input.dim, input.url],\r\n );\r\n const ks = res.rows[0] as KnowledgeSource;\r\n await ensureEntryTable(ks);\r\n return ks;\r\n}\r\n\r\nexport async function listKs(): Promise<KnowledgeSource[]> {\r\n const res = await getPool().query(`SELECT * FROM ks ORDER BY name`);\r\n return res.rows as KnowledgeSource[];\r\n}\r\n\r\nexport async function getKs(name: string): Promise<KnowledgeSource | undefined> {\r\n const res = await getPool().query(`SELECT * FROM ks WHERE name = $1`, [name]);\r\n return res.rows[0] as KnowledgeSource | undefined;\r\n}\r\n\r\nexport async function updateKs(\r\n id: string,\r\n fields: { name?: string; description?: string; ollama_url?: string },\r\n): Promise<KnowledgeSource> {\r\n const sets: string[] = [];\r\n const params: unknown[] = [];\r\n if (fields.name !== undefined) {\r\n params.push(fields.name);\r\n sets.push(`name = $${params.length}`);\r\n }\r\n if (fields.description !== undefined) {\r\n params.push(fields.description);\r\n sets.push(`description = $${params.length}`);\r\n }\r\n if (fields.ollama_url !== undefined) {\r\n params.push(fields.ollama_url);\r\n sets.push(`ollama_url = $${params.length}`);\r\n }\r\n if (sets.length === 0) {\r\n const res = await getPool().query(`SELECT * FROM ks WHERE id = $1`, [id]);\r\n return res.rows[0] as KnowledgeSource;\r\n }\r\n sets.push(`updated_at = now()`);\r\n params.push(id);\r\n const res = await getPool().query(\r\n `UPDATE ks SET ${sets.join(\", \")} WHERE id = $${params.length} RETURNING *`,\r\n params,\r\n );\r\n return res.rows[0] as KnowledgeSource;\r\n}\r\n\r\nexport async function deleteKs(ks: KnowledgeSource): Promise<void> {\r\n const tbl = entryTableName(ks);\r\n await getPool().query(`DROP TABLE IF EXISTS ${tbl}`);\r\n await getPool().query(`DELETE FROM ks WHERE id = $1`, [ks.id]);\r\n}\r\n\r\nexport async function ensureEntryTable(ks: KnowledgeSource): Promise<void> {\r\n const tbl = entryTableName(ks);\r\n const p = getPool();\r\n await p.query(`\r\n CREATE TABLE IF NOT EXISTS ${tbl} (\r\n id bigserial PRIMARY KEY,\r\n source text NOT NULL,\r\n title text NOT NULL DEFAULT '',\r\n chunk_index integer NOT NULL DEFAULT 0,\r\n content text NOT NULL,\r\n content_hash text NOT NULL,\r\n metadata jsonb NOT NULL DEFAULT '{}',\r\n tsv tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED,\r\n embedding vector(${ks.embedding_dim}) NOT NULL,\r\n created_at timestamptz NOT NULL DEFAULT now()\r\n )\r\n `);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_tsv_idx ON ${tbl} USING gin (tsv)`);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_emb_idx ON ${tbl} USING hnsw (embedding vector_cosine_ops)`);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_source_idx ON ${tbl} (source)`);\r\n}\r\n\r\nexport interface ChunkInsert {\r\n source: string;\r\n title: string;\r\n chunk_index: number;\r\n content: string;\r\n metadata: Record<string, unknown>;\r\n embedding: number[];\r\n}\r\n\r\nexport async function insertChunks(ks: KnowledgeSource, rows: ChunkInsert[]): Promise<number> {\r\n if (rows.length === 0) return 0;\r\n const tbl = entryTableName(ks);\r\n const p = getPool();\r\n const BATCH = 25;\r\n let inserted = 0;\r\n for (let i = 0; i < rows.length; i += BATCH) {\r\n const batch = rows.slice(i, i + BATCH);\r\n const values: string[] = [];\r\n const params: unknown[] = [];\r\n batch.forEach((r, j) => {\r\n const b = j * 7;\r\n values.push(`($${b + 1}, $${b + 2}, $${b + 3}, $${b + 4}, $${b + 5}, $${b + 6}, $${b + 7}::vector)`);\r\n params.push(r.source, r.title, r.chunk_index, r.content, contentHash(r.content), JSON.stringify(r.metadata), toSql(r.embedding));\r\n });\r\n const res = await p.query(\r\n `INSERT INTO ${tbl} (source, title, chunk_index, content, content_hash, metadata, embedding)\r\n VALUES ${values.join(\", \")}`,\r\n params,\r\n );\r\n inserted += res.rowCount ?? 0;\r\n }\r\n return inserted;\r\n}\r\n\r\nexport async function deleteBySource(ks: KnowledgeSource, source: string): Promise<number> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(`DELETE FROM ${tbl} WHERE source = $1`, [source]);\r\n return res.rowCount ?? 0;\r\n}\r\n\r\nexport async function sourceChunkHashes(\r\n ks: KnowledgeSource,\r\n source: string,\r\n): Promise<Map<number, string>> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(\r\n `SELECT chunk_index, content_hash FROM ${tbl} WHERE source = $1`,\r\n [source],\r\n );\r\n const map = new Map<number, string>();\r\n for (const row of res.rows) {\r\n map.set(Number(row.chunk_index), String(row.content_hash));\r\n }\r\n return map;\r\n}\r\n\r\nexport async function countEntries(ks: KnowledgeSource): Promise<number> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(`SELECT count(*)::int AS n FROM ${tbl}`);\r\n return Number(res.rows[0]?.n ?? 0);\r\n}\r\n\r\nexport async function dbClockTimestamp(): Promise<Date> {\r\n const res = await getPool().query(`SELECT clock_timestamp() AS ts`);\r\n return res.rows[0]!.ts as Date;\r\n}\r\n\r\nexport interface KsStats {\r\n ks: KnowledgeSource;\r\n entries: number;\r\n sources: number;\r\n chars: number;\r\n avg_chunk_chars: number | null;\r\n min_chunk_chars: number | null;\r\n max_chunk_chars: number | null;\r\n last_fed_at: Date | null;\r\n}\r\n\r\nexport async function ksStats(ks: KnowledgeSource, since?: Date): Promise<KsStats> {\r\n const tbl = entryTableName(ks);\r\n const params: unknown[] = [];\r\n let where = \"\";\r\n if (since) {\r\n params.push(since);\r\n where = ` WHERE created_at >= $1`;\r\n }\r\n const res = await getPool().query(\r\n `SELECT count(*)::int AS entries,\r\n count(DISTINCT source)::int AS sources,\r\n COALESCE(sum(length(content)), 0)::bigint AS chars,\r\n round(avg(length(content)))::int AS avg_chunk_chars,\r\n min(length(content))::int AS min_chunk_chars,\r\n max(length(content))::int AS max_chunk_chars,\r\n max(created_at) AS last_fed_at\r\n FROM ${tbl}${where}`,\r\n params,\r\n );\r\n const r = res.rows[0] as Record<string, unknown>;\r\n return {\r\n ks,\r\n entries: Number(r.entries ?? 0),\r\n sources: Number(r.sources ?? 0),\r\n chars: Number(r.chars ?? 0),\r\n avg_chunk_chars: r.avg_chunk_chars === null ? null : Number(r.avg_chunk_chars),\r\n min_chunk_chars: r.min_chunk_chars === null ? null : Number(r.min_chunk_chars),\r\n max_chunk_chars: r.max_chunk_chars === null ? null : Number(r.max_chunk_chars),\r\n last_fed_at: r.last_fed_at === null ? null : (r.last_fed_at as Date),\r\n };\r\n}\r\n","import { Command } from \"commander\";\r\nimport { createInterface } from \"node:readline/promises\";\r\nimport { stdin, stdout } from \"node:process\";\r\nimport {\r\n initDb,\r\n closePool,\r\n createKs,\r\n listKs,\r\n getKs,\r\n updateKs,\r\n deleteKs,\r\n countEntries,\r\n ksStats,\r\n dbClockTimestamp,\r\n type KnowledgeSource,\r\n} from \"./db.js\";\r\nimport { probeModel } from \"./ollama.js\";\r\nimport { ollamaUrl } from \"./config.js\";\r\nimport { feedTarget, feedText } from \"./ingest.js\";\r\nimport { feedUrl, CRAWLER_KINDS, parseSitemapOption, type CrawlerKind, type SitemapMode } from \"./scrape.js\";\r\nimport { parseHtmlFilter, validateCssSelector } from \"./html.js\";\r\nimport { runChecks, type CheckStatus } from \"./check.js\";\r\nimport { VERSION } from \"./version.js\";\r\n\r\nasync function run(fn: () => Promise<void>): Promise<void> {\r\n try {\r\n await fn();\r\n } catch (err) {\r\n console.error(`error: ${err instanceof Error ? err.message : err}`);\r\n process.exitCode = 1;\r\n } finally {\r\n await closePool().catch(() => {});\r\n }\r\n}\r\n\r\nasync function confirm(question: string): Promise<boolean> {\r\n const rl = createInterface({ input: stdin, output: stdout });\r\n try {\r\n const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();\r\n return answer === \"y\" || answer === \"yes\";\r\n } finally {\r\n rl.close();\r\n }\r\n}\r\n\r\nfunction requireKs(ks: KnowledgeSource | undefined, name: string): KnowledgeSource {\r\n if (!ks) throw new Error(`knowledge source '${name}' not found`);\r\n return ks;\r\n}\r\n\r\nfunction parseKeyValue(pairs: string[]): Record<string, unknown> {\r\n const out: Record<string, unknown> = {};\r\n for (const pair of pairs) {\r\n const idx = pair.indexOf(\"=\");\r\n if (idx <= 0) throw new Error(`invalid metadata entry '${pair}', expected key=value`);\r\n out[pair.slice(0, idx)] = pair.slice(idx + 1);\r\n }\r\n return out;\r\n}\r\n\r\nfunction parseTags(tags?: string): string[] | undefined {\r\n if (!tags) return undefined;\r\n const list = tags.split(\",\").map((t) => t.trim()).filter(Boolean);\r\n return list.length > 0 ? list : undefined;\r\n}\r\n\r\nfunction parseGlobs(globs?: string[]): string[] | undefined {\r\n if (!globs || globs.length === 0) return undefined;\r\n const list = [...new Set(globs.map((g) => g.trim()).filter(Boolean))];\r\n return list.length > 0 ? list : undefined;\r\n}\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name(\"gresmcp\")\r\n .description(\"Manage Postgres-backed knowledge sources for the gresmcp MCP server\")\r\n .version(VERSION);\r\n\r\nprogram\r\n .command(\"init\")\r\n .description(\"Initialize the database schema (extension, ks table; repairs entry tables)\")\r\n .action(() =>\r\n run(async () => {\r\n await initDb();\r\n for (const ks of await listKs()) {\r\n const { ensureEntryTable } = await import(\"./db.js\");\r\n await ensureEntryTable(ks);\r\n }\r\n console.log(\"database ready\");\r\n }),\r\n );\r\n\r\nprogram\r\n .command(\"check\")\r\n .description(\"Verify environment requirements (Node, Postgres, pgvector, schema, Ollama models)\")\r\n .requiredOption(\"--model <model>\", \"Verify this Ollama model is available (e.g. nomic-embed-text)\")\r\n .option(\"--url <url>\", \"Ollama base URL (default http://localhost:11434)\")\r\n .option(\"--probe\", \"Embed a test string with each model to verify dimensions (slower)\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((opts: { model: string; url?: string; probe?: boolean; json?: boolean }) =>\r\n run(async () => {\r\n const results = await runChecks({ model: opts.model, url: opts.url, probe: opts.probe });\r\n if (opts.json) {\r\n console.log(JSON.stringify(results, null, 2));\r\n } else {\r\n const symbols: Record<CheckStatus, string> = { ok: \"✔\", warn: \"⚠\", fail: \"✘\", skip: \"-\" };\r\n for (const r of results) console.log(`${symbols[r.status]} ${r.detail}`);\r\n const failed = results.filter((r) => r.status === \"fail\").length;\r\n const warned = results.filter((r) => r.status === \"warn\").length;\r\n if (failed > 0) {\r\n console.log(`${failed} check(s) failed${warned > 0 ? `, ${warned} warning(s)` : \"\"}`);\r\n } else if (warned > 0) {\r\n console.log(`all checks passed with ${warned} warning(s)`);\r\n } else {\r\n console.log(\"all checks passed\");\r\n }\r\n }\r\n if (results.some((r) => r.status === \"fail\")) process.exitCode = 1;\r\n }),\r\n );\r\n\r\nconst ksCmd = program.command(\"ks\").description(\"Manage knowledge sources\");\r\n\r\nksCmd\r\n .command(\"create <name>\")\r\n .description(\"Create a knowledge source (probes Ollama to validate the model and detect dimensions)\")\r\n .requiredOption(\"--model <model>\", \"Ollama embedding model, e.g. nomic-embed-text\")\r\n .option(\"--url <url>\", \"Ollama base URL (default http://localhost:11434)\")\r\n .option(\"--description <description>\", \"Human-readable description\")\r\n .option(\"--dim <n>\", \"Skip the Ollama probe and set the embedding dimension explicitly\", parseInt)\r\n .action((name: string, opts: { model: string; url?: string; description?: string; dim?: number }) =>\r\n run(async () => {\r\n await initDb();\r\n if (await getKs(name)) throw new Error(`knowledge source '${name}' already exists`);\r\n const url = ollamaUrl(opts.url);\r\n let dim = opts.dim;\r\n if (dim === undefined || !Number.isFinite(dim) || dim <= 0) {\r\n console.log(`Probing model ${opts.model} at ${url} ...`);\r\n dim = (await probeModel(url, opts.model)).dim;\r\n console.log(`Model OK, embedding dimension: ${dim}`);\r\n }\r\n const ks = await createKs({\r\n name,\r\n description: opts.description,\r\n model: opts.model,\r\n dim,\r\n url,\r\n });\r\n console.log(`Created knowledge source '${ks.name}' (dim=${ks.embedding_dim}, model=${ks.embedding_model}, url=${ks.ollama_url})`);\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"edit <name>\")\r\n .description(\"Edit a knowledge source (the embedding model is immutable)\")\r\n .option(\"--url <url>\", \"New Ollama base URL\")\r\n .option(\"--rename <new-name>\", \"Rename the knowledge source\")\r\n .option(\"--description <description>\", \"New description\")\r\n .action((name: string, opts: { url?: string; rename?: string; description?: string }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n if (opts.rename && opts.rename !== name && (await getKs(opts.rename))) {\r\n throw new Error(`knowledge source '${opts.rename}' already exists`);\r\n }\r\n const updated = await updateKs(ks.id, {\r\n name: opts.rename,\r\n description: opts.description,\r\n ollama_url: opts.url ? ollamaUrl(opts.url) : undefined,\r\n });\r\n console.log(`Updated '${updated.name}' (model=${updated.embedding_model}, url=${updated.ollama_url}, dim=${updated.embedding_dim})`);\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"list\")\r\n .description(\"List knowledge sources\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((opts: { json?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const all = await listKs();\r\n if (opts.json) {\r\n console.log(JSON.stringify(all, null, 2));\r\n return;\r\n }\r\n if (all.length === 0) {\r\n console.log(\"no knowledge sources yet; create one with: gresmcp ks create <name> --model <model>\");\r\n return;\r\n }\r\n for (const ks of all) {\r\n const n = await countEntries(ks);\r\n console.log(\r\n `${ks.name.padEnd(20)} ${`${ks.embedding_model}@${ks.ollama_url}`.padEnd(50)} dim=${String(ks.embedding_dim).padEnd(6)} entries=${String(n).padEnd(8)} ${ks.description}`,\r\n );\r\n }\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"stats <name>\")\r\n .description(\"Show statistics for a knowledge source (entries, sources, content volume)\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((name: string, opts: { json?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n const stats = await ksStats(ks);\r\n if (opts.json) {\r\n console.log(JSON.stringify(stats, null, 2));\r\n return;\r\n }\r\n console.log(\r\n `Knowledge source '${stats.ks.name}' (model=${stats.ks.embedding_model}@${stats.ks.ollama_url}, dim=${stats.ks.embedding_dim})`,\r\n );\r\n if (stats.ks.description) console.log(` description: ${stats.ks.description}`);\r\n console.log(` created: ${stats.ks.created_at.toISOString()}`);\r\n console.log(` last fed: ${stats.last_fed_at ? stats.last_fed_at.toISOString() : \"never\"}`);\r\n console.log(\"\");\r\n if (stats.entries === 0) {\r\n console.log(` no entries yet; feed it with: gresmcp feed ${stats.ks.name}`);\r\n return;\r\n }\r\n const size = (n: number | null) => (n === null ? \"-\" : n.toLocaleString(\"en-US\"));\r\n console.log(` entries (chunks): ${stats.entries.toLocaleString(\"en-US\")}`);\r\n console.log(` distinct sources: ${stats.sources.toLocaleString(\"en-US\")}`);\r\n console.log(\r\n ` content: ${stats.chars.toLocaleString(\"en-US\")} chars` +\r\n ` (avg ${size(stats.avg_chunk_chars)}, min ${size(stats.min_chunk_chars)}, max ${size(stats.max_chunk_chars)} per chunk)`,\r\n );\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"delete <name>\")\r\n .description(\"Delete a knowledge source and all of its entries\")\r\n .option(\"--yes\", \"Do not ask for confirmation\")\r\n .action((name: string, opts: { yes?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n if (!opts.yes) {\r\n const n = await countEntries(ks);\r\n const ok = await confirm(`Delete knowledge source '${name}' and its ${n} entry chunk(s)?`);\r\n if (!ok) {\r\n console.log(\"aborted\");\r\n return;\r\n }\r\n }\r\n await deleteKs(ks);\r\n console.log(`Deleted knowledge source '${name}'`);\r\n }),\r\n );\r\n\r\nprogram\r\n .command(\"feed <ks>\")\r\n .description(\"Feed data into a knowledge source (from a file/folder via --path, a website via --url, or inline via --text/--stdin)\")\r\n .option(\"--path <path>\", \"File or folder to ingest (text, markdown, code, html, pdf, doc, docx, epub)\")\r\n .option(\"--url <url>\", \"Website URL to scrape and ingest (crawls same-host pages linked from the seed)\")\r\n .option(\"--crawler <crawler>\", \"Crawler backend for --url: auto, crawlee, playwright, puppeteer (default auto; playwright/puppeteer must be installed globally)\", ((v: string) => v.toLowerCase()) as never)\r\n .option(\"--max-pages <n>\", \"Max pages to fetch when crawling --url (default 999)\", parseInt)\r\n .option(\"--depth <n>\", \"Max link depth from the seed URL (default 5; 0 = seed page only)\", parseInt)\r\n .option(\r\n \"--url-filter <glob>\",\r\n \"Only follow --url links whose URL matches this glob (repeatable; a link is followed if it matches any glob, e.g. '**/docs/**')\",\r\n ((v: string, prev: string[]) => [...prev, v]) as never,\r\n [] as string[],\r\n )\r\n .option(\r\n \"--html-filter <selector>\",\r\n \"CSS selector for HTML content — any DOM selector works (e.g. 'article.post', '#article .content:first-child'); optionally chain steps with ' -> ' (e.g. '#article -> .content'); applies to --path HTML files and --url pages\",\r\n )\r\n .option(\r\n \"--sitemap <mode>\",\r\n \"Link discovery for --url: 'auto' (default; sitemap.xml, then robots.txt sitemaps, else follow links), 'sitemap-only' (only sitemap.xml / robots.txt sitemaps), 'html-only' (follow links), or a CSS selector to only follow links inside it (e.g. 'nav.docs a')\",\r\n )\r\n .option(\r\n \"--file-password <password>\",\r\n \"Password for encrypted files (PDF, DOC/DOCX); applies to --path and --url ingestion. Owner-restricted PDFs without a user password are read without it\",\r\n )\r\n .option(\"--text <text>\", \"Inline text entry\")\r\n .option(\"--stdin\", \"Read entry text from stdin\")\r\n .option(\"--title <title>\", \"Title for manual entries\")\r\n .option(\"--source-name <name>\", \"Source name for manual entries (default 'manual')\")\r\n .option(\"--tags <tags>\", \"Comma-separated tags\")\r\n .option(\"--metadata <key=value...>\", \"Custom metadata entries\", ((v: string, prev: string[]) => [...prev, v]) as never, [] as string[])\r\n .option(\"--replace\", \"Replace existing chunks of the same source instead of deduplicating\")\r\n .option(\"--dry-run\", \"Parse and chunk only; do not embed or write\")\r\n .option(\"--chunk-size <n>\", \"Max chunk length in characters\", parseInt)\r\n .option(\"--overlap <n>\", \"Chunk overlap in characters\", parseInt)\r\n .action((name: string, opts: {\r\n path?: string;\r\n url?: string;\r\n crawler?: string;\r\n maxPages?: number;\r\n depth?: number;\r\n urlFilter?: string[];\r\n htmlFilter?: string;\r\n sitemap?: string;\r\n filePassword?: string;\r\n text?: string;\r\n stdin?: boolean;\r\n title?: string;\r\n sourceName?: string;\r\n tags?: string;\r\n metadata?: string[];\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n chunkSize?: number;\r\n overlap?: number;\r\n }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n const modes = [opts.path, opts.url, opts.text, opts.stdin].filter(Boolean).length;\r\n if (modes !== 1) throw new Error(\"provide exactly one of --path, --url, --text or --stdin\");\r\n const urlFilter = parseGlobs(opts.urlFilter);\r\n if (urlFilter && !opts.url) {\r\n console.error(\"warning: --url-filter has no effect without --url\");\r\n }\r\n if (opts.htmlFilter) parseHtmlFilter(opts.htmlFilter);\r\n if (opts.htmlFilter && !opts.path && !opts.url) {\r\n console.error(\"warning: --html-filter has no effect without --path or --url\");\r\n }\r\n let sitemap: SitemapMode | undefined;\r\n if (opts.sitemap !== undefined) {\r\n sitemap = parseSitemapOption(opts.sitemap);\r\n if (sitemap.kind === \"selector\") validateCssSelector(sitemap.selector);\r\n if (!opts.url) console.error(\"warning: --sitemap has no effect without --url\");\r\n }\r\n const common = {\r\n replace: opts.replace,\r\n dryRun: opts.dryRun,\r\n batchSize: 32,\r\n maxLen: opts.chunkSize && opts.chunkSize > 0 ? opts.chunkSize : undefined,\r\n overlap: opts.overlap,\r\n tags: parseTags(opts.tags),\r\n metadata: parseKeyValue(opts.metadata ?? []),\r\n htmlFilter: opts.htmlFilter,\r\n filePassword: opts.filePassword,\r\n };\r\n let summary;\r\n const since = await dbClockTimestamp();\r\n if (opts.path) {\r\n summary = await feedTarget(ks, opts.path, common);\r\n } else if (opts.url) {\r\n const crawler = opts.crawler as CrawlerKind | undefined;\r\n if (crawler && !CRAWLER_KINDS.includes(crawler)) {\r\n throw new Error(`unknown crawler '${crawler}' (use auto, crawlee, playwright or puppeteer)`);\r\n }\r\n summary = await feedUrl(ks, opts.url, { ...common, crawler, sitemap, maxPages: opts.maxPages, depth: opts.depth, urlFilter });\r\n } else {\r\n const text = opts.stdin ? await readStdin() : opts.text!;\r\n if (!text.trim()) throw new Error(\"empty input text\");\r\n summary = await feedText(ks, text, { ...common, title: opts.title, sourceName: opts.sourceName });\r\n }\r\n if (summary.dryRun) {\r\n console.log(`dry run: ${summary.documents} document(s), ${summary.chunks} chunk(s), ${summary.skippedFiles.length} file(s) skipped`);\r\n } else {\r\n console.log(\r\n `fed '${ks.name}': ${summary.inserted} chunk(s) inserted` +\r\n (summary.skippedExisting ? `, ${summary.skippedExisting} unchanged chunk(s) skipped` : \"\") +\r\n (summary.deletedForReplace ? `, ${summary.deletedForReplace} old chunk(s) replaced` : \"\") +\r\n `, ${summary.skippedFiles.length} file(s) skipped`,\r\n );\r\n await printRunStats(ks, since);\r\n }\r\n }),\r\n );\r\n\r\nasync function printRunStats(ks: KnowledgeSource, since: Date): Promise<void> {\r\n const stats = await ksStats(ks, since);\r\n if (stats.entries === 0) return;\r\n const size = (n: number | null) => (n === null ? \"-\" : n.toLocaleString(\"en-US\"));\r\n console.log(\"\");\r\n console.log(\r\n `this run: ${stats.entries.toLocaleString(\"en-US\")} chunk(s) across ${stats.sources.toLocaleString(\"en-US\")} source(s)`,\r\n );\r\n console.log(\r\n ` content: ${stats.chars.toLocaleString(\"en-US\")} chars` +\r\n ` (avg ${size(stats.avg_chunk_chars)}, min ${size(stats.min_chunk_chars)}, max ${size(stats.max_chunk_chars)} per chunk)`,\r\n );\r\n}\r\n\r\nasync function readStdin(): Promise<string> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stdin) chunks.push(chunk as Buffer);\r\n return Buffer.concat(chunks).toString(\"utf8\");\r\n}\r\n\r\nprogram.parseAsync(process.argv);\r\n","import { normalizeUrl } from \"./config.js\";\r\n\r\nexport class OllamaError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n ) {\r\n super(message);\r\n this.name = \"OllamaError\";\r\n }\r\n}\r\n\r\nexport async function embed(\r\n baseUrl: string,\r\n model: string,\r\n inputs: string[],\r\n timeoutMs = 120_000,\r\n): Promise<number[][]> {\r\n const url = `${normalizeUrl(baseUrl)}/api/embed`;\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({ model, input: inputs }),\r\n signal: AbortSignal.timeout(timeoutMs),\r\n });\r\n } catch (err) {\r\n throw new OllamaError(\r\n `Cannot reach Ollama at ${normalizeUrl(baseUrl)} (${err instanceof Error ? err.message : err})`,\r\n );\r\n }\r\n if (!res.ok) {\r\n const body = await res.text().catch(() => \"\");\r\n throw new OllamaError(`Ollama returned ${res.status} for ${url}: ${body.slice(0, 300)}`, res.status);\r\n }\r\n const data = (await res.json()) as { embeddings?: number[][]; error?: string };\r\n if (data.error) {\r\n throw new OllamaError(`Ollama error: ${data.error}`);\r\n }\r\n if (!Array.isArray(data.embeddings) || data.embeddings.length !== inputs.length) {\r\n throw new OllamaError(`Unexpected response shape from ${url}`);\r\n }\r\n return data.embeddings;\r\n}\r\n\r\nexport async function embedBatch(\r\n baseUrl: string,\r\n model: string,\r\n inputs: string[],\r\n batchSize = 32,\r\n onProgress?: (done: number, total: number) => void,\r\n): Promise<number[][]> {\r\n const out: number[][] = [];\r\n let done = 0;\r\n for (let i = 0; i < inputs.length; i += batchSize) {\r\n const batch = inputs.slice(i, i + batchSize);\r\n const embs = await embed(baseUrl, model, batch);\r\n out.push(...embs);\r\n done += batch.length;\r\n onProgress?.(done, inputs.length);\r\n }\r\n return out;\r\n}\r\n\r\nexport async function probeModel(\r\n baseUrl: string,\r\n model: string,\r\n): Promise<{ dim: number }> {\r\n const embs = await embed(baseUrl, model, [\"gresmcp dimension probe\"], 30_000);\r\n const first = embs[0];\r\n if (!first || first.length === 0) {\r\n throw new OllamaError(`Ollama returned an empty embedding for model ${model}`);\r\n }\r\n return { dim: first.length };\r\n}\r\n","import { promises as fs } from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { chunkMarkdown, chunkPlain, mdTitle, type Chunk } from \"./chunk.js\";\r\nimport { docToDoc, type OfficeDoc } from \"./doc.js\";\r\nimport { epubToDoc, type EpubDoc } from \"./epub.js\";\r\nimport { htmlToMarkdown } from \"./html.js\";\r\nimport {\r\n deleteBySource,\r\n insertChunks,\r\n sourceChunkHashes,\r\n contentHash,\r\n type ChunkInsert,\r\n type KnowledgeSource,\r\n} from \"./db.js\";\r\nimport { embedBatch } from \"./ollama.js\";\r\nimport { pdfToDoc, type PdfDoc } from \"./pdf.js\";\r\nimport { FeedProgress } from \"./progress.js\";\r\n\r\nexport const MD_EXT = new Set([\".md\", \".markdown\", \".mdx\"]);\r\nexport const HTML_EXT = new Set([\".html\", \".htm\", \".xhtml\"]);\r\nexport const PDF_EXT = new Set([\".pdf\"]);\r\nexport const DOC_EXT = new Set([\".doc\", \".docx\"]);\r\nexport const EPUB_EXT = new Set([\".epub\"]);\r\nexport const TEXT_EXT = new Set([\r\n \".txt\", \".text\", \".log\", \".csv\", \".tsv\", \".json\", \".jsonl\", \".yaml\", \".yml\",\r\n \".toml\", \".ini\", \".cfg\", \".conf\", \".xml\", \".rst\", \".adoc\",\r\n]);\r\nexport const CODE_EXT = new Set([\r\n \".js\", \".mjs\", \".cjs\", \".ts\", \".tsx\", \".jsx\", \".py\", \".go\", \".rs\", \".java\",\r\n \".kt\", \".kts\", \".rb\", \".php\", \".c\", \".h\", \".cpp\", \".hpp\", \".cc\", \".cs\",\r\n \".sh\", \".bash\", \".zsh\", \".ps1\", \".psm1\", \".bat\", \".cmd\", \".sql\", \".css\",\r\n \".scss\", \".less\", \".vue\", \".svelte\", \".astro\", \".swift\", \".scala\", \".pl\",\r\n \".lua\", \".r\", \".dart\", \".gradle\", \".cmake\", \".dockerfile\", \".makefile\", \".proto\", \".graphql\",\r\n]);\r\n\r\nconst SKIP_DIRS = new Set([\r\n \"node_modules\", \".git\", \".hg\", \".svn\", \"dist\", \"build\", \"out\", \".next\",\r\n \".nuxt\", \".venv\", \"venv\", \"__pycache__\", \".idea\", \".vscode\", \"target\",\r\n \"coverage\", \".turbo\", \".cache\",\r\n]);\r\n\r\nexport interface LoadedDoc {\r\n source: string;\r\n title: string;\r\n chunks: Chunk[];\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\nexport interface SkippedFile {\r\n path: string;\r\n reason: string;\r\n}\r\n\r\nexport interface LoadResult {\r\n docs: LoadedDoc[];\r\n fileCount: number;\r\n skipped: SkippedFile[];\r\n}\r\n\r\nfunction isAllowed(ext: string): boolean {\r\n return MD_EXT.has(ext) || HTML_EXT.has(ext) || TEXT_EXT.has(ext) || CODE_EXT.has(ext) || PDF_EXT.has(ext) || DOC_EXT.has(ext) || EPUB_EXT.has(ext);\r\n}\r\n\r\nasync function walk(root: string): Promise<string[]> {\r\n const out: string[] = [];\r\n const entries = await fs.readdir(root, { withFileTypes: true });\r\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\r\n const full = path.join(root, entry.name);\r\n if (entry.isDirectory()) {\r\n if (SKIP_DIRS.has(entry.name)) continue;\r\n out.push(...(await walk(full)));\r\n } else if (entry.isFile()) {\r\n out.push(full);\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nexport async function loadTarget(\r\n target: string,\r\n opts: { maxLen: number; overlap: number; htmlFilter?: string; filePassword?: string },\r\n): Promise<LoadResult> {\r\n const stat = await fs.stat(target);\r\n const files = stat.isDirectory() ? await walk(target) : [target];\r\n const docs: LoadedDoc[] = [];\r\n const skipped: SkippedFile[] = [];\r\n\r\n for (const file of files) {\r\n const ext = path.extname(file).toLowerCase();\r\n if (!isAllowed(ext)) {\r\n skipped.push({ path: file, reason: `unsupported extension '${ext || \"(none)\"}'` });\r\n continue;\r\n }\r\n let buf: Buffer;\r\n try {\r\n buf = await fs.readFile(file);\r\n } catch {\r\n skipped.push({ path: file, reason: \"unreadable\" });\r\n continue;\r\n }\r\n let text = \"\";\r\n let title = \"\";\r\n let docMeta: Record<string, unknown> | undefined;\r\n let chunks: Chunk[] = [];\r\n if (PDF_EXT.has(ext)) {\r\n let pdf: PdfDoc;\r\n try {\r\n pdf = await pdfToDoc(new Uint8Array(buf), { password: opts.filePassword });\r\n } catch (err) {\r\n skipped.push({ path: file, reason: err instanceof Error ? err.message : \"PDF parse failed\" });\r\n continue;\r\n }\r\n text = pdf.markdown;\r\n title = pdf.title ?? \"\";\r\n if (pdf.pageCount > 0) docMeta = { pdf_pages: pdf.pageCount };\r\n if (pdf.imageOnlyPages.length > 0) {\r\n docMeta = { ...docMeta, pdf_image_only_pages: pdf.imageOnlyPages.length };\r\n }\r\n if (!text.trim()) {\r\n skipped.push({\r\n path: file,\r\n reason:\r\n pdf.pageCount > 0 && pdf.imageOnlyPages.length === pdf.pageCount\r\n ? \"image-only PDF (no text layer; likely scanned)\"\r\n : \"no extractable text from PDF\",\r\n });\r\n continue;\r\n }\r\n chunks = chunkMarkdown(text, opts);\r\n } else if (DOC_EXT.has(ext)) {\r\n let word: OfficeDoc;\r\n try {\r\n word = await docToDoc(new Uint8Array(buf), { password: opts.filePassword });\r\n } catch (err) {\r\n skipped.push({ path: file, reason: err instanceof Error ? err.message : \"Word document parse failed\" });\r\n continue;\r\n }\r\n text = word.markdown;\r\n title = word.title ?? \"\";\r\n docMeta = { doc_format: word.format };\r\n if (word.encrypted) docMeta.doc_encrypted = true;\r\n if (!text.trim()) {\r\n skipped.push({ path: file, reason: \"no extractable text from Word document\" });\r\n continue;\r\n }\r\n chunks = word.format === \"docx\" ? chunkMarkdown(text, opts) : chunkPlain(text, opts);\r\n } else if (EPUB_EXT.has(ext)) {\r\n let epub: EpubDoc;\r\n try {\r\n epub = await epubToDoc(file);\r\n } catch (err) {\r\n skipped.push({ path: file, reason: err instanceof Error ? err.message : \"EPUB parse failed\" });\r\n continue;\r\n }\r\n text = epub.markdown;\r\n title = epub.title ?? \"\";\r\n docMeta = { epub_chapters: epub.chapters };\r\n if (epub.author) docMeta.epub_author = epub.author;\r\n if (epub.language) docMeta.epub_language = epub.language;\r\n if (epub.encrypted) docMeta.epub_encrypted = true;\r\n chunks = chunkMarkdown(text, opts);\r\n } else {\r\n const raw = buf.toString(\"utf8\");\r\n if (raw.includes(\"\\u0000\")) {\r\n skipped.push({ path: file, reason: \"binary content\" });\r\n continue;\r\n }\r\n text = raw;\r\n if (HTML_EXT.has(ext)) {\r\n const conv = htmlToMarkdown(raw, { filter: opts.htmlFilter });\r\n text = conv.markdown;\r\n title = conv.title ?? \"\";\r\n } else if (MD_EXT.has(ext)) {\r\n title = mdTitle(raw) ?? \"\";\r\n }\r\n if (!text.trim()) {\r\n skipped.push({\r\n path: file,\r\n reason: HTML_EXT.has(ext) && opts.htmlFilter\r\n ? `html filter '${opts.htmlFilter}' matched nothing`\r\n : \"empty\",\r\n });\r\n continue;\r\n }\r\n chunks = HTML_EXT.has(ext) || MD_EXT.has(ext)\r\n ? chunkMarkdown(text, opts)\r\n : chunkPlain(text, opts);\r\n }\r\n if (chunks.length === 0) {\r\n skipped.push({ path: file, reason: \"no chunks produced\" });\r\n continue;\r\n }\r\n if (!title) title = path.basename(file);\r\n docs.push({ source: path.resolve(file), title, chunks, metadata: docMeta });\r\n }\r\n return { docs, fileCount: files.length, skipped };\r\n}\r\n\r\nexport interface FeedSummary {\r\n documents: number;\r\n chunks: number;\r\n inserted: number;\r\n skippedExisting: number;\r\n deletedForReplace: number;\r\n skippedFiles: SkippedFile[];\r\n dryRun: boolean;\r\n}\r\n\r\nexport interface FeedDocsOptions {\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n progress?: FeedProgress;\r\n}\r\n\r\nconst DOC_CONCURRENCY = 3;\r\n\r\nexport async function feedDocs(\r\n ks: KnowledgeSource,\r\n docs: LoadedDoc[],\r\n opts: FeedDocsOptions = {},\r\n): Promise<FeedSummary> {\r\n const log = opts.log ?? ((m: string) => console.log(m));\r\n const progress = opts.progress;\r\n const batchSize = opts.batchSize ?? 32;\r\n const baseMeta = { ...(opts.metadata ?? {}) };\r\n const cliTags = opts.tags && opts.tags.length > 0 ? opts.tags : undefined;\r\n const say = (msg: string) => (progress ? progress.log(msg) : log(msg));\r\n\r\n let deletedForReplace = 0;\r\n let skippedExisting = 0;\r\n let inserted = 0;\r\n let announcedEmbed = false;\r\n\r\n const processDoc = async (doc: LoadedDoc): Promise<void> => {\r\n const file = progress?.startFile(\r\n doc.source,\r\n doc.chunks.length,\r\n doc.chunks.reduce((n, c) => n + c.content.length, 0),\r\n );\r\n if (opts.replace) {\r\n const deleted = await deleteBySource(ks, doc.source);\r\n deletedForReplace += deleted;\r\n }\r\n const existing = await sourceChunkHashes(ks, doc.source);\r\n const meta: Record<string, unknown> = { ...baseMeta, ...(doc.metadata ?? {}) };\r\n if (!(\"tags\" in meta) && cliTags) meta.tags = cliTags;\r\n const todo: Chunk[] = [];\r\n for (const chunk of doc.chunks) {\r\n if (!opts.replace && existing.get(chunk.index) === contentHash(chunk.content)) {\r\n skippedExisting++;\r\n file?.handled(1, chunk.content.length);\r\n continue;\r\n }\r\n todo.push(chunk);\r\n }\r\n if (todo.length === 0) return;\r\n if (opts.dryRun) {\r\n for (const chunk of todo) file?.handled(1, chunk.content.length);\r\n return;\r\n }\r\n if (!announcedEmbed) {\r\n announcedEmbed = true;\r\n say(`Embedding with ${ks.embedding_model} at ${ks.ollama_url} ...`);\r\n }\r\n const contents = todo.map((c) => c.content);\r\n const charLens = contents.map((c) => c.length);\r\n let reported = 0;\r\n const embeddings = await embedBatch(ks.ollama_url, ks.embedding_model, contents, batchSize, (done) => {\r\n const delta = done - reported;\r\n if (delta <= 0) return;\r\n let chars = 0;\r\n for (let i = reported; i < done; i++) chars += charLens[i]!;\r\n reported = done;\r\n file?.handled(delta, chars);\r\n });\r\n const rows: ChunkInsert[] = todo.map((chunk, i) => ({\r\n source: doc.source,\r\n title: doc.title,\r\n chunk_index: chunk.index,\r\n content: chunk.content,\r\n metadata: meta,\r\n embedding: embeddings[i]!,\r\n }));\r\n const rowCount = await insertChunks(ks, rows);\r\n inserted += rowCount;\r\n };\r\n\r\n let cursor = 0;\r\n let firstError: unknown;\r\n const runWorker = async (): Promise<void> => {\r\n while (firstError === undefined) {\r\n const index = cursor++;\r\n if (index >= docs.length) return;\r\n try {\r\n await processDoc(docs[index]!);\r\n } catch (err) {\r\n firstError ??= err;\r\n return;\r\n }\r\n }\r\n };\r\n const workerCount = Math.min(DOC_CONCURRENCY, docs.length);\r\n await Promise.all(Array.from({ length: workerCount }, () => runWorker()));\r\n\r\n if (firstError !== undefined) {\r\n progress?.close();\r\n throw firstError;\r\n }\r\n progress?.finish();\r\n return {\r\n documents: docs.length,\r\n chunks: docs.reduce((n, d) => n + d.chunks.length, 0),\r\n inserted,\r\n skippedExisting,\r\n deletedForReplace,\r\n skippedFiles: [],\r\n dryRun: opts.dryRun ?? false,\r\n };\r\n}\r\n\r\nexport async function feedTarget(\r\n ks: KnowledgeSource,\r\n target: string,\r\n opts: {\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n maxLen?: number;\r\n overlap?: number;\r\n htmlFilter?: string;\r\n filePassword?: string;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n progress?: FeedProgress;\r\n } = {},\r\n): Promise<FeedSummary> {\r\n const loadOpts = { maxLen: opts.maxLen ?? 1200, overlap: opts.overlap ?? 180, htmlFilter: opts.htmlFilter, filePassword: opts.filePassword };\r\n const { docs, skipped } = await loadTarget(target, loadOpts);\r\n for (const s of skipped) {\r\n (opts.log ?? ((m: string) => console.log(m)))(`skipped ${s.path}: ${s.reason}`);\r\n }\r\n const progress = opts.progress ?? new FeedProgress({ total: docs.length, rejected: skipped.length });\r\n const summary = await feedDocs(ks, docs, { ...opts, progress });\r\n return { ...summary, skippedFiles: skipped };\r\n}\r\n\r\nexport async function feedText(\r\n ks: KnowledgeSource,\r\n text: string,\r\n opts: {\r\n title?: string;\r\n sourceName?: string;\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n maxLen?: number;\r\n overlap?: number;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n progress?: FeedProgress;\r\n } = {},\r\n): Promise<FeedSummary> {\r\n const log = opts.log ?? ((m: string) => console.log(m));\r\n const source = opts.sourceName?.trim() || \"manual\";\r\n const title = opts.title?.trim() || source;\r\n const chunks = chunkMarkdown(text, { maxLen: opts.maxLen ?? 1200, overlap: opts.overlap ?? 180 });\r\n const doc: LoadedDoc = { source, title, chunks };\r\n const progress = opts.progress ?? new FeedProgress({ total: 1, rejected: 0 });\r\n return feedDocs(ks, [doc], { ...opts, progress });\r\n}\r\n","export interface Chunk {\r\n index: number;\r\n content: string;\r\n}\r\n\r\nexport interface ChunkOptions {\r\n maxLen?: number;\r\n overlap?: number;\r\n}\r\n\r\nconst HEADING_RE = /^(#{1,6})\\s+(.+)$/;\r\n\r\nfunction splitBlocks(text: string): string[] {\r\n return text\r\n .split(/\\n{2,}/)\r\n .map((b) => b.trim())\r\n .filter((b) => b.length > 0);\r\n}\r\n\r\nfunction cutPoint(slice: string): number {\r\n const nl = slice.lastIndexOf(\"\\n\");\r\n if (nl > slice.length * 0.5) return nl + 1;\r\n const dot = slice.lastIndexOf(\". \");\r\n if (dot > slice.length * 0.5) return dot + 1;\r\n const sp = slice.lastIndexOf(\" \");\r\n if (sp > slice.length * 0.5) return sp + 1;\r\n return slice.length;\r\n}\r\n\r\nfunction hardSplit(block: string, maxLen: number, overlap: number): string[] {\r\n const parts: string[] = [];\r\n let pos = 0;\r\n while (pos < block.length) {\r\n const end = Math.min(pos + maxLen, block.length);\r\n let slice = block.slice(pos, end);\r\n if (end < block.length) {\r\n const cut = cutPoint(slice);\r\n slice = slice.slice(0, cut);\r\n }\r\n parts.push(slice.trim());\r\n if (end >= block.length) break;\r\n const advanced = Math.max(slice.length - overlap, 1);\r\n pos += advanced;\r\n }\r\n return parts.filter((p) => p.length > 0);\r\n}\r\n\r\nfunction packBlocks(blocks: string[], maxLen: number, overlap: number): string[] {\r\n const pieces: string[] = [];\r\n let current = \"\";\r\n for (const block of blocks) {\r\n const expanded =\r\n block.length > maxLen ? hardSplit(block, maxLen, overlap) : [block];\r\n for (const part of expanded) {\r\n if (!current) {\r\n current = part;\r\n } else if (current.length + 2 + part.length <= maxLen) {\r\n current += \"\\n\\n\" + part;\r\n } else {\r\n pieces.push(current);\r\n const tail =\r\n overlap > 0 && current.length > overlap\r\n ? current.slice(current.length - overlap).replace(/^\\S+\\s+/, \"\")\r\n : \"\";\r\n current = tail ? tail + \"\\n\\n\" + part : part;\r\n }\r\n }\r\n }\r\n if (current) pieces.push(current);\r\n return pieces;\r\n}\r\n\r\nexport function chunkMarkdown(text: string, opts: ChunkOptions = {}): Chunk[] {\r\n const maxLen = opts.maxLen ?? 1200;\r\n const overlap = Math.min(opts.overlap ?? 180, Math.floor(maxLen / 4));\r\n const norm = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n if (!norm) return [];\r\n\r\n const lines = norm.split(\"\\n\");\r\n const sections: { path: string[]; body: string[] }[] = [{ path: [], body: [] }];\r\n for (const line of lines) {\r\n const m = HEADING_RE.exec(line);\r\n if (m) {\r\n const level = m[1]!.length;\r\n const path = sections[sections.length - 1]!.path;\r\n const parent = path.slice(0, level - 1);\r\n sections.push({ path: [...parent, m[2]!.trim()], body: [line] });\r\n } else {\r\n sections[sections.length - 1]!.body.push(line);\r\n }\r\n }\r\n\r\n const pieces: string[] = [];\r\n for (const s of sections) {\r\n const body = s.body.join(\"\\n\").trim();\r\n if (!body) continue;\r\n const context = s.path.length > 0 ? s.path.join(\" > \") + \"\\n\" : \"\";\r\n const packed = packBlocks(splitBlocks(body), maxLen, overlap);\r\n packed.forEach((piece, i) => {\r\n pieces.push(i === 0 || !context ? piece : context + piece);\r\n });\r\n }\r\n return pieces.map((content, index) => ({ index, content }));\r\n}\r\n\r\nexport function chunkPlain(text: string, opts: ChunkOptions = {}): Chunk[] {\r\n const maxLen = opts.maxLen ?? 1200;\r\n const overlap = Math.min(opts.overlap ?? 180, Math.floor(maxLen / 4));\r\n const norm = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n if (!norm) return [];\r\n const pieces = packBlocks(splitBlocks(norm), maxLen, overlap);\r\n return pieces.map((content, index) => ({ index, content }));\r\n}\r\n\r\nexport function mdTitle(text: string): string | undefined {\r\n const m = /^#\\s+(.+)\\s*$/m.exec(text);\r\n return m ? m[1]!.trim() : undefined;\r\n}\r\n","import { JSDOM } from \"jsdom\";\r\nimport TurndownService from \"turndown\";\r\nimport { Readability, isProbablyReaderable } from \"@mozilla/readability\";\r\nimport gfmModule from \"turndown-plugin-gfm\";\r\n\r\nconst gfm: (service: TurndownService) => void =\r\n typeof gfmModule === \"function\"\r\n ? (gfmModule as unknown as (service: TurndownService) => void)\r\n : ((gfmModule as { gfm?: (service: TurndownService) => void }).gfm as (service: TurndownService) => void);\r\n\r\nconst REMOVE_SELECTORS =\r\n \"script, style, noscript, template, iframe, svg, nav, footer, aside, form, button\";\r\n\r\nconst SHELL_MARKER_RE =\r\n /id=[\"'](root|app|__next|__nuxt|q-app)[\"']|data-reactroot|ng-version=/i;\r\nconst SHELL_TEXT_THRESHOLD = 250;\r\n\r\nlet service: TurndownService | undefined;\r\n\r\nfunction turndown(): TurndownService {\r\n if (!service) {\r\n service = new TurndownService({\r\n headingStyle: \"atx\",\r\n codeBlockStyle: \"fenced\",\r\n bulletListMarker: \"-\",\r\n });\r\n if (typeof gfm === \"function\") {\r\n service.use(gfm);\r\n }\r\n service.remove([\"button\"]);\r\n }\r\n return service;\r\n}\r\n\r\nexport function parseHtmlFilter(spec: string): string[] {\r\n const steps = spec.split(/\\s*->\\s*/).map((s) => s.trim()).filter(Boolean);\r\n if (steps.length === 0) {\r\n throw new Error(`invalid --html-filter '${spec.trim()}': expected a CSS selector chain, e.g. '#article -> .content'`);\r\n }\r\n return steps;\r\n}\r\n\r\nexport function validateCssSelector(selector: string): void {\r\n const dom = new JSDOM();\r\n try {\r\n dom.window.document.querySelector(selector);\r\n } catch (err) {\r\n throw new Error(`invalid CSS selector '${selector}': ${err instanceof Error ? err.message : err}`);\r\n }\r\n}\r\n\r\nfunction selectChain(scope: Document | Element, steps: string[]): Element[] | undefined {\r\n for (const step of steps.slice(0, -1)) {\r\n const next = scope.querySelector(step);\r\n if (!next) return undefined;\r\n scope = next;\r\n }\r\n const matches = [...scope.querySelectorAll(steps[steps.length - 1]!)];\r\n return matches.length > 0 ? matches : undefined;\r\n}\r\n\r\nfunction elementsToMarkdown(elements: Element[]): string {\r\n const parts: string[] = [];\r\n for (const el of elements) {\r\n try {\r\n parts.push(turndown().turndown(el.innerHTML));\r\n } catch {\r\n parts.push(el.textContent ?? \"\");\r\n }\r\n }\r\n return parts.join(\"\\n\\n\");\r\n}\r\n\r\nexport function htmlToMarkdown(\r\n html: string,\r\n opts: { filter?: string } = {},\r\n): { markdown: string; title?: string } {\r\n const dom = new JSDOM(html);\r\n const doc = dom.window.document;\r\n doc.querySelectorAll(REMOVE_SELECTORS).forEach((el) => el.remove());\r\n\r\n const title =\r\n doc.title?.trim() || doc.querySelector(\"h1\")?.textContent?.trim() || undefined;\r\n\r\n let markdown = \"\";\r\n if (opts.filter) {\r\n const elements = selectChain(doc, parseHtmlFilter(opts.filter));\r\n if (elements) markdown = elementsToMarkdown(elements);\r\n } else {\r\n const root = doc.body ?? doc.documentElement;\r\n try {\r\n markdown = turndown().turndown(root.innerHTML);\r\n } catch {\r\n markdown = root.textContent ?? \"\";\r\n }\r\n }\r\n markdown = markdown.replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n return { markdown, title: title || undefined };\r\n}\r\n\r\nexport interface ExtractedPage {\r\n markdown: string;\r\n title?: string;\r\n description?: string;\r\n tags?: string[];\r\n likelyShell: boolean;\r\n filterMatched?: boolean;\r\n}\r\n\r\nfunction metaContent(doc: Document, selectors: string[]): string | undefined {\r\n for (const selector of selectors) {\r\n const el = doc.querySelector(selector);\r\n const value = (el?.getAttribute(\"content\") ?? el?.textContent ?? \"\").trim();\r\n if (value) return value;\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction collectTags(doc: Document): string[] {\r\n const tags: string[] = [];\r\n const keywords = metaContent(doc, ['meta[name=\"keywords\"]']);\r\n if (keywords) {\r\n for (const part of keywords.split(\",\")) {\r\n const tag = part.trim();\r\n if (tag) tags.push(tag);\r\n }\r\n }\r\n doc.querySelectorAll('meta[property=\"og:article:tag\"]').forEach((el) => {\r\n const value = (el.getAttribute(\"content\") ?? \"\").trim();\r\n if (value) tags.push(value);\r\n });\r\n const seen = new Set<string>();\r\n return tags.filter((t) => {\r\n const key = t.toLowerCase();\r\n if (seen.has(key)) return false;\r\n seen.add(key);\r\n return true;\r\n });\r\n}\r\n\r\nexport function extractPage(html: string, opts: { filter?: string } = {}): ExtractedPage {\r\n const dom = new JSDOM(html);\r\n const doc = dom.window.document;\r\n\r\n const title =\r\n doc.title?.trim() ||\r\n doc.querySelector('meta[property=\"og:title\"]')?.getAttribute(\"content\")?.trim() ||\r\n doc.querySelector(\"h1\")?.textContent?.trim() ||\r\n undefined;\r\n const description = metaContent(doc, [\r\n 'meta[name=\"description\"]',\r\n 'meta[property=\"og:description\"]',\r\n ]);\r\n const tags = collectTags(doc);\r\n\r\n doc.querySelectorAll(REMOVE_SELECTORS).forEach((el) => el.remove());\r\n\r\n let markdown = \"\";\r\n let filterMatched: boolean | undefined;\r\n if (opts.filter) {\r\n const elements = selectChain(doc, parseHtmlFilter(opts.filter));\r\n filterMatched = elements !== undefined;\r\n if (elements) markdown = elementsToMarkdown(elements);\r\n } else {\r\n try {\r\n if (isProbablyReaderable(doc)) {\r\n const article = new Readability(doc).parse();\r\n if (article?.content) markdown = turndown().turndown(article.content);\r\n }\r\n } catch {\r\n markdown = \"\";\r\n }\r\n if (!markdown.trim()) {\r\n const root = doc.body ?? doc.documentElement;\r\n try {\r\n markdown = turndown().turndown(root.innerHTML);\r\n } catch {\r\n markdown = root.textContent ?? \"\";\r\n }\r\n }\r\n }\r\n markdown = markdown.replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n\r\n const likelyShell = markdown.length < SHELL_TEXT_THRESHOLD && SHELL_MARKER_RE.test(html);\r\n return {\r\n markdown,\r\n title,\r\n description,\r\n tags: tags.length > 0 ? tags : undefined,\r\n likelyShell,\r\n filterMatched,\r\n };\r\n}\r\n","import { htmlToMarkdown } from \"./html.js\";\nimport mammoth from \"mammoth\";\nimport {\n DecryptionError,\n Doc97File,\n FileFormatError,\n InvalidKeyError,\n OfficeFile,\n OleFileIO,\n isEncrypted,\n} from \"office-crypto\";\nimport WordExtractor from \"word-extractor\";\n\nexport class DocError extends Error {\n constructor(\n message: string,\n public readonly kind: \"password\" | \"corrupt\",\n ) {\n super(message);\n this.name = \"DocError\";\n }\n}\n\nexport interface OfficeDoc {\n markdown: string;\n title?: string;\n format: \"docx\" | \"doc\";\n /** true when the file was encrypted and a password was used to decrypt it */\n encrypted?: boolean;\n}\n\nexport interface DocOptions {\n password?: string;\n}\n\nconst OLE_MAGIC = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1] as const;\n\nfunction hasMagic(data: Uint8Array, magic: readonly number[]): boolean {\n if (data.length < magic.length) return false;\n return magic.every((byte, i) => data[i] === byte);\n}\n\nfunction isOle(data: Uint8Array): boolean {\n return hasMagic(data, OLE_MAGIC);\n}\n\nfunction isZip(data: Uint8Array): boolean {\n return data.length >= 4 && data[0] === 0x50 && data[1] === 0x4b && data[2] === 0x03 && data[3] === 0x04;\n}\n\nfunction toDocError(err: unknown, prefix: string): DocError {\n if (err instanceof DocError) return err;\n if (err instanceof InvalidKeyError) {\n return new DocError(\"wrong password for encrypted Word document\", \"password\");\n }\n const message = err instanceof Error ? err.message : String(err);\n return new DocError(`${prefix}: ${message.slice(0, 200)}`, \"corrupt\");\n}\n\nfunction requirePassword(): DocError {\n return new DocError(\"password-protected Word document (use --file-password)\", \"password\");\n}\n\nfunction oleHasStream(data: Uint8Array, name: string): boolean {\n try {\n return new OleFileIO(data).exists(name);\n } catch {\n return false;\n }\n}\n\nfunction decryptOoxml(data: Uint8Array, password?: string): Uint8Array {\n try {\n if (!password) throw requirePassword();\n const file = OfficeFile(data);\n file.loadKey({ password, verifyPassword: true });\n return file.decrypt();\n } catch (err) {\n throw toDocError(err, \"cannot decrypt Word document\");\n }\n}\n\nfunction decryptDoc97(data: Uint8Array, password?: string): Uint8Array {\n try {\n if (!password) throw requirePassword();\n const file = new Doc97File(new OleFileIO(data));\n file.loadKey({ password });\n return file.decrypt();\n } catch (err) {\n throw toDocError(err, \"cannot decrypt Word document\");\n }\n}\n\nasync function docxToMarkdown(data: Uint8Array, encrypted: boolean): Promise<OfficeDoc> {\n let html: string;\n try {\n const result = await mammoth.convertToHtml({ buffer: Buffer.from(data) });\n html = result.value;\n } catch (err) {\n throw toDocError(err, \"cannot parse docx\");\n }\n html = html\n .replace(/<img\\b[^>]*>/gi, \"\")\n // unwrap <p> inside table cells so turndown's GFM table rule can fire\n .replace(/<t([dh])\\b([^>]*)>([\\s\\S]*?)<\\/t\\1>/gi, (_m, letter: string, attrs: string, inner: string) =>\n `<t${letter}${attrs}>${inner.replace(/<\\/?p(?:\\s[^>]*)?>/gi, \"\").replace(/<br(?:\\s[^>]*)?>/gi, \" \")}</t${letter}>`,\n )\n // mammoth emits plain <td> rows; promote the first row to <th> so GFM tables convert to pipes\n .replace(/<table\\b[^>]*>([\\s\\S]*?)<\\/table>/gi, (m, inner: string) =>\n m.replace(/(<tr\\b[^>]*>)([\\s\\S]*?)(<\\/tr>)/i, (row, open: string, cells: string) =>\n open + cells.replace(/<td\\b/gi, \"<th\").replace(/<\\/td>/gi, \"</th>\") + \"</tr>\",\n ),\n );\n const { markdown, title } = htmlToMarkdown(html);\n return {\n markdown: markdown.replace(/\\n{3,}/g, \"\\n\\n\").trim(),\n title: title || undefined,\n format: \"docx\",\n ...(encrypted ? { encrypted: true } : {}),\n };\n}\n\nasync function docToText(data: Uint8Array, encrypted: boolean): Promise<OfficeDoc> {\n try {\n const doc = await new WordExtractor().extract(Buffer.from(data));\n const normalize = (s: string) =>\n s.replace(/\\r\\n?/g, \"\\n\").replace(/\\f/g, \"\\n\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n // body plus content Word can hide outside it (textboxes, footnotes, endnotes)\n const parts = [doc.getBody(), doc.getTextboxes(), doc.getFootnotes(), doc.getEndnotes()]\n .map(normalize)\n .filter(Boolean);\n return { markdown: parts.join(\"\\n\\n\"), format: \"doc\", ...(encrypted ? { encrypted: true } : {}) };\n } catch (err) {\n throw toDocError(err, \"cannot parse doc\");\n }\n}\n\nexport async function docToDoc(data: Uint8Array, opts: DocOptions = {}): Promise<OfficeDoc> {\n if (isZip(data)) return docxToMarkdown(data, false);\n if (isOle(data)) {\n if (oleHasStream(data, \"EncryptionInfo\")) {\n if (oleHasStream(data, \"Workbook\") || oleHasStream(data, \"PowerPoint Document\")) {\n throw new DocError(\"not a Word document (encrypted Excel/PowerPoint package)\", \"corrupt\");\n }\n const plain = decryptOoxml(data, opts.password);\n return isZip(plain) ? docxToMarkdown(plain, true) : docToText(plain, true);\n }\n if (oleHasStream(data, \"WordDocument\") || oleHasStream(data, \"wordDocument\")) {\n if (isEncrypted(data)) {\n const plain = decryptDoc97(data, opts.password);\n return docToText(plain, true);\n }\n return docToText(data, false);\n }\n throw new DocError(\"not a Word document (unsupported OLE compound file)\", \"corrupt\");\n }\n throw new DocError(\"not a Word document (missing docx/doc signature)\", \"corrupt\");\n}\n","import { promises as fs } from \"node:fs\";\nimport { mkdtempSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { EPub } from \"epub2\";\nimport { htmlToMarkdown } from \"./html.js\";\n\nexport class EpubError extends Error {\n constructor(\n message: string,\n public readonly kind: \"drm\" | \"corrupt\",\n ) {\n super(message);\n this.name = \"EpubError\";\n }\n}\n\nexport interface EpubDoc {\n markdown: string;\n title?: string;\n author?: string;\n language?: string;\n /** number of spine chapters that contributed text */\n chapters: number;\n /** META-INF/encryption.xml present (DRM or font obfuscation) */\n encrypted?: boolean;\n}\n\nconst REWRITE_ROOT_RE = /^\\/(?:links|images)\\//i;\nconst ENCRYPTION_ENTRY = \"meta-inf/encryption.xml\";\n\nfunction toEpubError(err: unknown): EpubError {\n if (err instanceof EpubError) return err;\n const message = err instanceof Error ? err.message : String(err);\n return new EpubError(`cannot parse EPUB: ${message.slice(0, 200)}`, \"corrupt\");\n}\n\nfunction hasEncryptionEntry(names: string[] | undefined): boolean {\n return (names ?? []).some((n) => n.toLowerCase() === ENCRYPTION_ENTRY);\n}\n\nfunction normalizeHref(href: string): string {\n const raw = href.split(\"#\")[0]!.trim();\n if (!raw) return \"\";\n let decoded = raw;\n try {\n decoded = decodeURIComponent(raw);\n } catch {\n // malformed percent-encoding — use raw\n }\n return path.posix.normalize(decoded).toLowerCase();\n}\n\n// epub2 rewrites manifest-referenced image/link URLs to useless /images/ and /links/ roots\nfunction cleanChapterHtml(html: string): string {\n return html\n .replace(/<img\\b[^>]*>/gi, \"\")\n .replace(/<a\\b([^>]*)>([\\s\\S]*?)<\\/a>/gi, (m, attrs: string, inner: string) => {\n const href = /\\shref\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)')/i.exec(attrs);\n const url = (href?.[1] ?? href?.[2] ?? \"\").trim();\n return REWRITE_ROOT_RE.test(url) ? inner : m;\n });\n}\n\n// map spine items to chapter titles from the (NCX) table of contents\nfunction tocTitleMap(epub: EPub): Map<string, string> {\n const titles = new Map<string, string>();\n for (const entry of epub.toc ?? []) {\n const title = entry?.title?.trim();\n if (!title) continue;\n if (entry.id && epub.manifest[entry.id]) {\n const idKey = `id:${entry.id}`;\n if (!titles.has(idKey)) titles.set(idKey, title);\n continue;\n }\n if (entry.href) {\n const hrefKey = normalizeHref(entry.href);\n if (hrefKey && !titles.has(hrefKey)) titles.set(hrefKey, title);\n }\n }\n return titles;\n}\n\nexport async function epubToDoc(filePath: string): Promise<EpubDoc> {\n let epub: EPub;\n try {\n epub = await EPub.createAsync(filePath);\n } catch (err) {\n throw toEpubError(err);\n }\n\n const encrypted = hasEncryptionEntry(epub.zip?.names);\n const titles = tocTitleMap(epub);\n\n const parts: string[] = [];\n for (const item of epub.flow ?? []) {\n const id = item?.id;\n if (!id) continue;\n let html: string;\n try {\n html = await epub.getChapterAsync(id);\n } catch {\n continue; // non-XHTML spine item, unreadable or encrypted content\n }\n const { markdown } = htmlToMarkdown(cleanChapterHtml(html));\n if (!markdown.trim()) continue;\n const heading =\n titles.get(`id:${id}`) ?? (item.href ? titles.get(normalizeHref(item.href)) : undefined);\n parts.push(heading ? `## ${heading}\\n\\n${markdown}` : markdown);\n }\n\n const markdown = parts.join(\"\\n\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\n if (!markdown) {\n throw new EpubError(\n encrypted\n ? \"DRM-protected EPUB (encryption.xml; no readable text)\"\n : \"no extractable text from EPUB\",\n encrypted ? \"drm\" : \"corrupt\",\n );\n }\n return {\n markdown,\n title: epub.metadata?.title?.trim() || undefined,\n author: epub.metadata?.creator?.trim() || undefined,\n language: epub.metadata?.language?.trim() || undefined,\n chapters: parts.length,\n ...(encrypted ? { encrypted: true } : {}),\n };\n}\n\nexport async function epubFromBuffer(data: Uint8Array): Promise<EpubDoc> {\n const dir = mkdtempSync(path.join(tmpdir(), \"gresmcp-epub-\"));\n try {\n const file = path.join(dir, \"book.epub\");\n await fs.writeFile(file, data);\n return await epubToDoc(file);\n } finally {\n await fs.rm(dir, { recursive: true, force: true }).catch(() => {});\n }\n}\n","import pdf2md from \"@opendocsg/pdf2md\";\nimport { extractText, getMeta } from \"unpdf\";\n\nconst PAGE_BREAK_MARK = \"<!-- PAGE_BREAK -->\";\n\nexport class PdfError extends Error {\n constructor(\n message: string,\n public readonly kind: \"password\" | \"corrupt\",\n ) {\n super(message);\n this.name = \"PdfError\";\n }\n}\n\nexport interface PdfDoc {\n markdown: string;\n title?: string;\n pageCount: number;\n /** 1-based page numbers with no extractable text (likely scanned images) */\n imageOnlyPages: number[];\n}\n\nexport interface PdfOptions {\n password?: string;\n}\n\ninterface UnpdfExtract {\n totalPages: number;\n text: string[];\n}\n\nfunction isPasswordException(err: unknown): boolean {\n return err instanceof Error && err.name === \"PasswordException\";\n}\n\nfunction toPdfError(err: unknown): PdfError {\n if (err instanceof PdfError) return err;\n if (isPasswordException(err)) {\n return new PdfError(\"wrong password for encrypted PDF\", \"password\");\n }\n const message = err instanceof Error ? err.message : String(err);\n return new PdfError(`cannot parse PDF: ${message.slice(0, 200)}`, \"corrupt\");\n}\n\nfunction titleFromInfo(info: unknown): string | undefined {\n const raw = (info as { Title?: unknown } | undefined)?.Title;\n const value = typeof raw === \"string\" ? raw.trim() : \"\";\n return value || undefined;\n}\n\nfunction imageOnlyFromPages(pages: { index: number; items: { text?: string }[] }[]): number[] {\n const out: number[] = [];\n for (const page of pages) {\n const hasText = page.items.some((it) => String(it.text ?? \"\").trim().length > 0);\n if (!hasText) out.push(page.index + 1);\n }\n return out;\n}\n\nasync function extractEncrypted(data: Uint8Array, password: string): Promise<PdfDoc> {\n try {\n const extractOpts = { mergePages: false, password } as Parameters<typeof extractText>[1];\n const metaOpts = { password } as Parameters<typeof getMeta>[1];\n const [result, meta] = await Promise.all([\n extractText(data, extractOpts) as Promise<UnpdfExtract>,\n getMeta(data, metaOpts).catch(() => undefined),\n ]);\n const pages: string[] = result.text;\n const imageOnlyPages: number[] = [];\n pages.forEach((text, i) => {\n if (!text.trim()) imageOnlyPages.push(i + 1);\n });\n const markdown = pages.map((p) => p.trim()).filter(Boolean).join(\"\\n\\n\").trim();\n return {\n markdown,\n title: titleFromInfo(meta?.info),\n pageCount: result.totalPages,\n imageOnlyPages,\n };\n } catch (err) {\n throw toPdfError(err);\n }\n}\n\nexport async function pdfToDoc(data: Uint8Array, opts: PdfOptions = {}): Promise<PdfDoc> {\n let title: string | undefined;\n let pages: { index: number; items: { text?: string }[] }[] = [];\n let markdown: string;\n try {\n markdown = await pdf2md(data, {\n metadataParsed: (meta) => {\n title = titleFromInfo(meta.info);\n },\n pageParsed: (parsed) => {\n pages = parsed;\n },\n });\n } catch (err) {\n if (isPasswordException(err)) {\n if (opts.password) {\n return extractEncrypted(data, opts.password);\n }\n throw new PdfError(\"password-protected PDF (use --file-password)\", \"password\");\n }\n throw toPdfError(err);\n }\n markdown = markdown\n .split(PAGE_BREAK_MARK)\n .map((part) => part.replace(/\\s+$/, \"\"))\n .join(\"\\n\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n return {\n markdown,\n title,\n pageCount: pages.length,\n imageOnlyPages: imageOnlyFromPages(pages),\n };\n}\n","const BAR_WIDTH = 20;\nconst PLAIN_STEP = 32;\n\nfunction fmt(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\nfunction bar(pct: number): string {\n const filled = Math.max(0, Math.min(BAR_WIDTH, Math.round(pct * BAR_WIDTH)));\n return \"#\".repeat(filled) + \".\".repeat(BAR_WIDTH - filled);\n}\n\nfunction pct(p: number): string {\n return `${Math.round(Math.max(0, Math.min(1, p)) * 100)}%`;\n}\n\nexport interface FeedProgressOptions {\n total: number;\n rejected: number;\n out?: (s: string) => void;\n interactive?: boolean;\n}\n\ninterface FileSlot {\n source: string;\n totalChunks: number;\n totalChars: number;\n doneChunks: number;\n doneChars: number;\n printedChunks: number;\n}\n\nexport interface FileProgressHandle {\n handled(chunks: number, chars: number): void;\n}\n\nconst NOOP_HANDLE: FileProgressHandle = { handled: () => {} };\n\nexport class FeedProgress {\n private readonly write: (s: string) => void;\n private readonly interactive: boolean;\n private readonly total: number;\n private readonly rejected: number;\n private readonly slots: FileSlot[] = [];\n private filesDone = 0;\n private totalChars = 0;\n private blockLines = 0;\n private finished = false;\n\n constructor(opts: FeedProgressOptions) {\n this.total = Math.max(0, Math.floor(opts.total));\n this.rejected = Math.max(0, Math.floor(opts.rejected));\n this.write = opts.out ?? ((s: string) => process.stderr.write(s));\n this.interactive = opts.interactive ?? (opts.out === undefined && !!process.stderr.isTTY);\n }\n\n get isInteractive(): boolean {\n return this.interactive;\n }\n\n startFile(source: string, totalChunks: number, totalChars: number): FileProgressHandle {\n if (this.finished) return NOOP_HANDLE;\n const slot: FileSlot = { source, totalChunks, totalChars, doneChunks: 0, doneChars: 0, printedChunks: 0 };\n this.slots.push(slot);\n this.render();\n return {\n handled: (chunks, chars) => this.handleSlot(slot, chunks, chars),\n };\n }\n\n log(msg: string): void {\n if (this.finished) return;\n this.clearBlock();\n this.write(`${msg}\\n`);\n }\n\n finish(): void {\n if (this.finished) return;\n this.finished = true;\n if (this.slots.length === 0 && this.total === 0 && this.rejected === 0) return;\n if (this.interactive) {\n this.redraw(this.lines());\n this.write(\"\\n\");\n this.blockLines = 0;\n } else {\n this.write(`${this.totalLine()}\\n`);\n }\n }\n\n close(): void {\n if (this.finished) return;\n this.finished = true;\n this.clearBlock();\n }\n\n private lines(): string[] {\n return [...this.slots.map((slot) => this.fileLine(slot)), this.totalLine()];\n }\n\n private handleSlot(slot: FileSlot, chunks: number, chars: number): void {\n if (this.finished || chunks <= 0 || slot.doneChunks >= slot.totalChunks) return;\n slot.doneChunks += chunks;\n slot.doneChars += chars;\n this.totalChars += chars;\n if (slot.doneChunks >= slot.totalChunks) {\n this.filesDone++;\n if (this.interactive) {\n this.render();\n } else {\n this.printFileLine(slot);\n }\n this.slots.splice(this.slots.indexOf(slot), 1);\n return;\n }\n if (!this.interactive && slot.doneChunks - slot.printedChunks >= PLAIN_STEP) {\n this.printFileLine(slot);\n } else if (this.interactive) {\n this.render();\n }\n }\n\n private render(): void {\n if (!this.interactive) return;\n this.redraw(this.lines());\n }\n\n private printFileLine(slot: FileSlot): void {\n slot.printedChunks = slot.doneChunks;\n this.write(`${this.fileLine(slot)}\\n`);\n }\n\n private fileLine(slot: FileSlot): string {\n const p = slot.totalChunks > 0 ? slot.doneChunks / slot.totalChunks : 1;\n return (\n `[${bar(p)}] ${pct(p).padStart(4)} ${fmt(slot.doneChunks)}/${fmt(slot.totalChunks)} chunks` +\n ` ${fmt(slot.doneChars)}/${fmt(slot.totalChars)} chars ${slot.source}`\n );\n }\n\n private totalLine(): string {\n const p = this.total > 0 ? this.filesDone / this.total : 0;\n const rejected = this.rejected > 0 ? ` | rejected: ${this.rejected} (excluded)` : \"\";\n return `total: ${this.filesDone}/${this.total} files (${pct(p)}) ${fmt(this.totalChars)} chars${rejected}`;\n }\n\n private redraw(lines: string[]): void {\n let out = \"\";\n if (this.blockLines > 1) out += `\\x1b[${this.blockLines - 1}A`;\n out += \"\\r\";\n for (let i = 0; i < lines.length; i++) {\n out += `\\x1b[2K${lines[i]}${i < lines.length - 1 ? \"\\n\" : \"\"}`;\n }\n this.write(out);\n this.blockLines = lines.length;\n }\n\n private clearBlock(): void {\n if (!this.interactive || this.blockLines === 0) {\n this.blockLines = 0;\n return;\n }\n let out = \"\";\n if (this.blockLines > 1) out += `\\x1b[${this.blockLines - 1}A`;\n out += \"\\r\";\n for (let i = 0; i < this.blockLines; i++) {\n out += `\\x1b[2K${i < this.blockLines - 1 ? \"\\n\" : \"\"}`;\n }\n out += \"\\n\";\n this.write(out);\n this.blockLines = 0;\n }\n}\n","import { mkdtempSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n CheerioCrawler,\n PlaywrightCrawler,\n PuppeteerCrawler,\n Request as CrawleeRequest,\n RequestQueue,\n RobotsTxtFile,\n Sitemap,\n constructGlobObjectsFromGlobs,\n filterRequestsByPatterns,\n log,\n} from \"crawlee\";\nimport { chunkMarkdown, chunkPlain, mdTitle } from \"./chunk.js\";\nimport { docToDoc } from \"./doc.js\";\nimport { epubFromBuffer } from \"./epub.js\";\nimport { extractPage, type ExtractedPage } from \"./html.js\";\nimport { feedDocs, type FeedSummary, type LoadedDoc, type SkippedFile } from \"./ingest.js\";\nimport { pdfToDoc } from \"./pdf.js\";\nimport { FeedProgress } from \"./progress.js\";\nimport type { KnowledgeSource } from \"./db.js\";\n\nexport type CrawlerKind = \"auto\" | \"crawlee\" | \"playwright\" | \"puppeteer\";\n\nexport const CRAWLER_KINDS: CrawlerKind[] = [\"auto\", \"crawlee\", \"playwright\", \"puppeteer\"];\n\nexport type SitemapMode =\n | { kind: \"auto\" }\n | { kind: \"sitemap-only\" }\n | { kind: \"html-only\" }\n | { kind: \"selector\"; selector: string };\n\nexport function parseSitemapOption(value: string): SitemapMode {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(\"invalid --sitemap '': use auto, sitemap-only, html-only or a CSS selector\");\n }\n const key = trimmed.toLowerCase();\n if (key === \"auto\") return { kind: \"auto\" };\n if (key === \"sitemap-only\") return { kind: \"sitemap-only\" };\n if (key === \"html-only\") return { kind: \"html-only\" };\n return { kind: \"selector\", selector: trimmed };\n}\n\nconst BINARY_LINK_RE =\n /\\.(css|js|mjs|cjs|map|png|jpe?g|gif|svg|webp|avif|ico|bmp|tiff?|woff2?|ttf|otf|eot|zip|gz|tgz|tar|rar|7z|bz2|xz|zst|mp3|mp4|m4a|webm|mov|avi|wmv|flv|xlsx?|pptx?|odt|ods|odp|rtf|dmg|exe|msi|apk|iso|bin|wasm|deb|rpm)(\\?.*)?$/i;\n\nconst PDF_URL_RE = /\\.pdf(\\?|#|$)/i;\n\nconst DOC_URL_RE = /\\.docx?(\\?|#|$)/i;\n\nconst EPUB_URL_RE = /\\.epub(\\?|#|$)/i;\n\ninterface CrawlOptions {\n crawler: CrawlerKind;\n maxPages: number;\n depth: number;\n maxLen: number;\n overlap: number;\n tags?: string[];\n urlFilter?: string[];\n htmlFilter?: string;\n filePassword?: string;\n log: (msg: string) => void;\n sitemap?: SitemapMode;\n}\n\ninterface RunOptions extends CrawlOptions {\n followLinks: boolean;\n linkSelector?: string;\n selectorStats: { hits: number; misses: number };\n}\n\nexport interface CrawlResult {\n docs: LoadedDoc[];\n skipped: SkippedFile[];\n}\n\ninterface PageDeps {\n maxLen: number;\n overlap: number;\n cliTags?: string[];\n urlFilter?: string[];\n htmlFilter?: string;\n filePassword?: string;\n followLinks?: boolean;\n linkSelector?: string;\n selectorStats: { hits: number; misses: number };\n}\n\nprocess.env.CRAWLEE_STORAGE_DIR ??= mkdtempSync(path.join(tmpdir(), \"gresmcp-crawl-\"));\n\nasync function freshQueue(): Promise<RequestQueue> {\n return RequestQueue.open(`gresmcp-${randomUUID()}`);\n}\n\nfunction normalizeSeedUrl(seed: string): string {\n let url: URL;\n try {\n url = new URL(seed.trim());\n } catch {\n throw new Error(`invalid URL '${seed}'`);\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new Error(`unsupported URL protocol '${url.protocol.replace(\":\", \"\")}' (use http or https)`);\n }\n url.hash = \"\";\n return url.toString();\n}\n\nfunction responseStatus(response: unknown): number | undefined {\n if (!response || typeof response !== \"object\") return undefined;\n const res = response as { status?: unknown; statusCode?: unknown };\n if (typeof res.status === \"number\") return res.status;\n if (typeof res.status === \"function\") {\n const value = (res.status as () => unknown)();\n return typeof value === \"number\" ? value : undefined;\n }\n if (typeof res.statusCode === \"number\") return res.statusCode;\n return undefined;\n}\n\nfunction toText(body: string | Buffer): string {\n return typeof body === \"string\" ? body : body.toString(\"utf-8\");\n}\n\nfunction titleFor(url: string, fallback?: string): string {\n const trimmed = fallback?.trim();\n if (trimmed) return trimmed;\n try {\n const segment = new URL(url).pathname.split(\"/\").filter(Boolean).pop();\n const name = segment ? decodeURIComponent(segment) : \"\";\n return name || url;\n } catch {\n return url;\n }\n}\n\nfunction unionTags(...lists: (string[] | undefined)[]): string[] | undefined {\n const out: string[] = [];\n const seen = new Set<string>();\n for (const list of lists) {\n for (const tag of list ?? []) {\n const value = tag.trim();\n if (!value) continue;\n const key = value.toLowerCase();\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(value);\n }\n }\n return out.length > 0 ? out : undefined;\n}\n\nfunction buildDoc(\n url: string,\n kind: \"html\" | \"md\" | \"plain\",\n text: string,\n page: ExtractedPage | undefined,\n deps: PageDeps,\n): LoadedDoc | undefined {\n const chunkOpts = { maxLen: deps.maxLen, overlap: deps.overlap };\n const chunks = kind === \"plain\" ? chunkPlain(text, chunkOpts) : chunkMarkdown(text, chunkOpts);\n if (chunks.length === 0) return undefined;\n const title = kind === \"html\"\n ? titleFor(url, page?.title)\n : kind === \"md\"\n ? mdTitle(text) ?? titleFor(url)\n : titleFor(url);\n const metadata: Record<string, unknown> = { source_url: url, crawled_at: new Date().toISOString() };\n if (page?.description) metadata.description = page.description;\n const tags = unionTags(page?.tags, deps.cliTags);\n if (tags) metadata.tags = tags;\n return { source: url, title, chunks, metadata };\n}\n\nfunction dedupeDocs(docs: LoadedDoc[]): LoadedDoc[] {\n const bySource = new Map<string, LoadedDoc>();\n for (const doc of docs) {\n if (!bySource.has(doc.source)) bySource.set(doc.source, doc);\n }\n return [...bySource.values()];\n}\n\ninterface PdfBuildResult {\n doc?: LoadedDoc;\n reason?: string;\n}\n\nasync function buildPdfDoc(url: string, data: Uint8Array, deps: PageDeps): Promise<PdfBuildResult> {\n try {\n const pdf = await pdfToDoc(data, { password: deps.filePassword });\n if (!pdf.markdown.trim()) {\n const reason =\n pdf.pageCount > 0 && pdf.imageOnlyPages.length === pdf.pageCount\n ? \"image-only PDF (no text layer; likely scanned)\"\n : \"no extractable text from PDF\";\n return { reason };\n }\n const chunks = chunkMarkdown(pdf.markdown, { maxLen: deps.maxLen, overlap: deps.overlap });\n if (chunks.length === 0) return { reason: \"no chunks produced\" };\n const metadata: Record<string, unknown> = { source_url: url, crawled_at: new Date().toISOString() };\n if (pdf.pageCount > 0) metadata.pdf_pages = pdf.pageCount;\n if (pdf.imageOnlyPages.length > 0) metadata.pdf_image_only_pages = pdf.imageOnlyPages.length;\n const tags = unionTags(undefined, deps.cliTags);\n if (tags) metadata.tags = tags;\n return { doc: { source: url, title: pdf.title?.trim() || titleFor(url), chunks, metadata } };\n } catch (err) {\n return { reason: err instanceof Error ? err.message : \"PDF parse failed\" };\n }\n}\n\ninterface EpubBuildResult {\n doc?: LoadedDoc;\n reason?: string;\n}\n\nasync function buildEpubDoc(url: string, data: Uint8Array, deps: PageDeps): Promise<EpubBuildResult> {\n try {\n const epub = await epubFromBuffer(data);\n if (!epub.markdown.trim()) {\n return {\n reason: epub.encrypted\n ? \"DRM-protected EPUB (encryption.xml; no readable text)\"\n : \"no extractable text from EPUB\",\n };\n }\n const chunks = chunkMarkdown(epub.markdown, { maxLen: deps.maxLen, overlap: deps.overlap });\n if (chunks.length === 0) return { reason: \"no chunks produced\" };\n const metadata: Record<string, unknown> = {\n source_url: url,\n crawled_at: new Date().toISOString(),\n epub_chapters: epub.chapters,\n };\n if (epub.author) metadata.epub_author = epub.author;\n if (epub.language) metadata.epub_language = epub.language;\n if (epub.encrypted) metadata.epub_encrypted = true;\n const tags = unionTags(undefined, deps.cliTags);\n if (tags) metadata.tags = tags;\n return { doc: { source: url, title: epub.title?.trim() || titleFor(url), chunks, metadata } };\n } catch (err) {\n return { reason: err instanceof Error ? err.message : \"EPUB parse failed\" };\n }\n}\n\nfunction shortReason(err: Error): string {\n const message = (err?.message ?? String(err)).replace(/\\s+/g, \" \").trim();\n const contentType = /served Content-Type ([^,\\s]+),/.exec(message);\n if (contentType) return `unsupported content-type '${contentType[1]}'`;\n return message.slice(0, 200);\n}\n\ninterface WordBuildResult {\n doc?: LoadedDoc;\n reason?: string;\n}\n\nasync function buildDocDoc(url: string, data: Uint8Array, deps: PageDeps): Promise<WordBuildResult> {\n try {\n const word = await docToDoc(data, { password: deps.filePassword });\n if (!word.markdown.trim()) {\n return { reason: \"no extractable text from Word document\" };\n }\n const chunkOpts = { maxLen: deps.maxLen, overlap: deps.overlap };\n const chunks = word.format === \"docx\"\n ? chunkMarkdown(word.markdown, chunkOpts)\n : chunkPlain(word.markdown, chunkOpts);\n if (chunks.length === 0) return { reason: \"no chunks produced\" };\n const metadata: Record<string, unknown> = {\n source_url: url,\n crawled_at: new Date().toISOString(),\n doc_format: word.format,\n };\n if (word.encrypted) metadata.doc_encrypted = true;\n const tags = unionTags(undefined, deps.cliTags);\n if (tags) metadata.tags = tags;\n return { doc: { source: url, title: word.title?.trim() || titleFor(url), chunks, metadata } };\n } catch (err) {\n return { reason: err instanceof Error ? err.message : \"Word document parse failed\" };\n }\n}\n\ninterface CrawlSink {\n docs: LoadedDoc[];\n skipped: SkippedFile[];\n shellUrls?: string[];\n}\n\nasync function crawlWithCheerio(\n queue: RequestQueue,\n seedUrls: string[],\n opts: RunOptions,\n sink: CrawlSink,\n): Promise<void> {\n const crawler = new CheerioCrawler({\n requestQueue: queue,\n maxRequestsPerCrawl: Math.max(1, opts.maxPages),\n maxCrawlDepth: Math.max(0, opts.depth),\n additionalMimeTypes: [\"text/plain\", \"text/markdown\", \"application/pdf\", \"application/msword\", \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", \"application/epub+zip\", \"application/zip\", \"application/octet-stream\"],\n async requestHandler(ctx) {\n const { request, response, contentType, body, $ } = ctx;\n const url = request.loadedUrl ?? request.url;\n const status = responseStatus(response);\n if (status === undefined || status < 200 || status >= 300) {\n sink.skipped.push({ path: url, reason: status === undefined ? \"no HTTP response\" : `HTTP ${status}` });\n return;\n }\n const type = contentType?.type ?? \"\";\n if (type === \"text/html\" || type === \"application/xhtml+xml\") {\n const html = typeof body === \"string\" ? body : toText(body as Buffer);\n const page = extractPage(html, { filter: opts.htmlFilter });\n if (page.likelyShell) {\n sink.shellUrls?.push(url);\n sink.skipped.push({ path: url, reason: \"likely JS-rendered shell\" });\n return;\n }\n if (opts.htmlFilter && !page.filterMatched) {\n sink.skipped.push({ path: url, reason: `html filter '${opts.htmlFilter}' matched nothing` });\n return;\n }\n if (!page.markdown.trim()) {\n sink.skipped.push({ path: url, reason: \"empty\" });\n return;\n }\n const doc = buildDoc(url, \"html\", page.markdown, page, sinkDeps(opts));\n if (!doc) {\n sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n sink.docs.push(doc);\n if (opts.followLinks !== false) {\n const selector = opts.linkSelector;\n if (selector) {\n if ($(selector).length > 0) {\n opts.selectorStats.hits += 1;\n await ctx.enqueueLinks({\n selector,\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: opts.urlFilter,\n });\n } else {\n opts.selectorStats.misses += 1;\n }\n } else {\n await ctx.enqueueLinks({\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: opts.urlFilter,\n });\n }\n }\n } else if (type === \"text/markdown\") {\n const doc = buildDoc(url, \"md\", toText(body as Buffer), undefined, sinkDeps(opts));\n if (!doc) {\n sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n sink.docs.push(doc);\n } else if (type === \"text/plain\") {\n const doc = buildDoc(url, \"plain\", toText(body as Buffer), undefined, sinkDeps(opts));\n if (!doc) {\n sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n sink.docs.push(doc);\n } else if (type === \"application/pdf\") {\n const data = typeof body === \"string\"\n ? new TextEncoder().encode(body)\n : new Uint8Array(body as Buffer);\n const { doc, reason } = await buildPdfDoc(url, data, sinkDeps(opts));\n if (reason || !doc) {\n sink.skipped.push({ path: url, reason: reason ?? \"PDF produced no document\" });\n return;\n }\n sink.docs.push(doc);\n } else if (type === \"application/msword\" || type === \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\") {\n const data = typeof body === \"string\"\n ? new TextEncoder().encode(body)\n : new Uint8Array(body as Buffer);\n const { doc, reason } = await buildDocDoc(url, data, sinkDeps(opts));\n if (reason || !doc) {\n sink.skipped.push({ path: url, reason: reason ?? \"Word document produced no document\" });\n return;\n }\n sink.docs.push(doc);\n } else if (type === \"application/epub+zip\" || type === \"application/zip\") {\n const data = typeof body === \"string\"\n ? new TextEncoder().encode(body)\n : new Uint8Array(body as Buffer);\n const { doc, reason } = await buildEpubDoc(url, data, sinkDeps(opts));\n if (reason || !doc) {\n sink.skipped.push({ path: url, reason: reason ?? \"EPUB produced no document\" });\n return;\n }\n sink.docs.push(doc);\n } else if (type === \"application/octet-stream\") {\n // servers often mislabel doc/docx as octet-stream; docToDoc sniffs the real format.\n // .epub URLs get the epub parser instead (also commonly mislabeled)\n const data = typeof body === \"string\"\n ? new TextEncoder().encode(body)\n : new Uint8Array(body as Buffer);\n if (EPUB_URL_RE.test(url)) {\n const { doc, reason } = await buildEpubDoc(url, data, sinkDeps(opts));\n if (reason || !doc) {\n sink.skipped.push({ path: url, reason: reason ?? \"EPUB produced no document\" });\n return;\n }\n sink.docs.push(doc);\n return;\n }\n const { doc, reason } = await buildDocDoc(url, data, sinkDeps(opts));\n if (reason || !doc) {\n sink.skipped.push({ path: url, reason: reason ?? \"Word document produced no document\" });\n return;\n }\n sink.docs.push(doc);\n } else {\n sink.skipped.push({ path: url, reason: `unsupported content-type '${type}'` });\n }\n },\n async failedRequestHandler(ctx, error) {\n const url = ctx.request.loadedUrl ?? ctx.request.url;\n sink.skipped.push({ path: url, reason: shortReason(error) });\n },\n });\n\n try {\n await crawler.run(seedUrls);\n } finally {\n await crawler.teardown().catch(() => {});\n }\n}\n\nfunction sinkDeps(opts: RunOptions): PageDeps {\n return {\n maxLen: opts.maxLen,\n overlap: opts.overlap,\n cliTags: opts.tags,\n urlFilter: opts.urlFilter,\n htmlFilter: opts.htmlFilter,\n filePassword: opts.filePassword,\n followLinks: opts.followLinks,\n linkSelector: opts.linkSelector,\n selectorStats: opts.selectorStats,\n };\n}\n\nasync function importOptional(name: string): Promise<Record<string, unknown> | undefined> {\n try {\n return (await import(name)) as Record<string, unknown>;\n } catch {\n return undefined;\n }\n}\n\nasync function requireBrowserEngine(kind: \"playwright\" | \"puppeteer\"): Promise<void> {\n const moduleName = kind === \"playwright\" ? \"playwright\" : \"puppeteer\";\n const mod = await importOptional(moduleName);\n if (!mod) {\n const install = kind === \"playwright\"\n ? \"npm i -g playwright && npx playwright install chromium\"\n : \"npm i -g puppeteer\";\n throw new Error(`--crawler ${kind} requires ${moduleName}, which is not installed (install it with: ${install})`);\n }\n}\n\ninterface BrowserHandlerDeps extends PageDeps {\n sink: CrawlSink;\n}\n\nasync function handleBrowserPdf(url: string, deps: BrowserHandlerDeps): Promise<void> {\n try {\n const res = await fetch(url, { redirect: \"follow\" });\n if (!res.ok) {\n deps.sink.skipped.push({ path: url, reason: `HTTP ${res.status}` });\n return;\n }\n const data = new Uint8Array(await res.arrayBuffer());\n const { doc, reason } = await buildPdfDoc(url, data, deps);\n if (reason || !doc) {\n deps.sink.skipped.push({ path: url, reason: reason ?? \"PDF produced no document\" });\n return;\n }\n deps.sink.docs.push(doc);\n } catch (err) {\n deps.sink.skipped.push({ path: url, reason: err instanceof Error ? err.message : \"PDF fetch failed\" });\n }\n}\n\nasync function handleBrowserDoc(url: string, deps: BrowserHandlerDeps): Promise<void> {\n try {\n const res = await fetch(url, { redirect: \"follow\" });\n if (!res.ok) {\n deps.sink.skipped.push({ path: url, reason: `HTTP ${res.status}` });\n return;\n }\n const data = new Uint8Array(await res.arrayBuffer());\n const { doc, reason } = await buildDocDoc(url, data, deps);\n if (reason || !doc) {\n deps.sink.skipped.push({ path: url, reason: reason ?? \"Word document produced no document\" });\n return;\n }\n deps.sink.docs.push(doc);\n } catch (err) {\n deps.sink.skipped.push({ path: url, reason: err instanceof Error ? err.message : \"Word document fetch failed\" });\n }\n}\n\nasync function handleBrowserEpub(url: string, deps: BrowserHandlerDeps): Promise<void> {\n try {\n const res = await fetch(url, { redirect: \"follow\" });\n if (!res.ok) {\n deps.sink.skipped.push({ path: url, reason: `HTTP ${res.status}` });\n return;\n }\n const data = new Uint8Array(await res.arrayBuffer());\n const { doc, reason } = await buildEpubDoc(url, data, deps);\n if (reason || !doc) {\n deps.sink.skipped.push({ path: url, reason: reason ?? \"EPUB produced no document\" });\n return;\n }\n deps.sink.docs.push(doc);\n } catch (err) {\n deps.sink.skipped.push({ path: url, reason: err instanceof Error ? err.message : \"EPUB fetch failed\" });\n }\n}\n\nasync function handleBrowserPage(ctx: any, deps: BrowserHandlerDeps): Promise<void> {\n const request = ctx.request as { url: string; loadedUrl?: string };\n const url = request.loadedUrl ?? request.url;\n if (PDF_URL_RE.test(url)) {\n await handleBrowserPdf(url, deps);\n return;\n }\n if (DOC_URL_RE.test(url)) {\n await handleBrowserDoc(url, deps);\n return;\n }\n if (EPUB_URL_RE.test(url)) {\n await handleBrowserEpub(url, deps);\n return;\n }\n const status = responseStatus(ctx.response);\n if (status === undefined || status < 200 || status >= 300) {\n deps.sink.skipped.push({ path: url, reason: status === undefined ? \"no HTTP response\" : `HTTP ${status}` });\n return;\n }\n const html = await (ctx.page as { content(): Promise<string> }).content();\n const page = extractPage(html, { filter: deps.htmlFilter });\n if (deps.htmlFilter && !page.filterMatched) {\n deps.sink.skipped.push({ path: url, reason: `html filter '${deps.htmlFilter}' matched nothing` });\n return;\n }\n if (!page.markdown.trim()) {\n deps.sink.skipped.push({ path: url, reason: \"empty after render\" });\n return;\n }\n const doc = buildDoc(url, \"html\", page.markdown, page, deps);\n if (!doc) {\n deps.sink.skipped.push({ path: url, reason: \"no chunks produced\" });\n return;\n }\n deps.sink.docs.push(doc);\n if (deps.followLinks !== false) {\n const selector = deps.linkSelector;\n if (selector) {\n const elements = await (ctx.page as { $$(selector: string): Promise<unknown[]> }).$$(selector);\n if (elements.length > 0) {\n deps.selectorStats.hits += 1;\n await ctx.enqueueLinks({\n selector,\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: deps.urlFilter,\n });\n } else {\n deps.selectorStats.misses += 1;\n }\n } else {\n await ctx.enqueueLinks({\n strategy: \"same-hostname\",\n exclude: [BINARY_LINK_RE],\n globs: deps.urlFilter,\n });\n }\n }\n}\n\nasync function crawlWithBrowser(\n kind: \"playwright\" | \"puppeteer\",\n queue: RequestQueue,\n seedUrls: string[],\n opts: RunOptions,\n sink: CrawlSink,\n): Promise<void> {\n const crawler = kind === \"playwright\"\n ? new PlaywrightCrawler({\n requestQueue: queue,\n maxRequestsPerCrawl: Math.max(1, opts.maxPages),\n maxCrawlDepth: Math.max(0, opts.depth),\n preNavigationHooks: [\n (_ctx: unknown, gotoOptions: { waitUntil?: string; timeout?: number }) => {\n gotoOptions.waitUntil = \"networkidle\";\n gotoOptions.timeout = 30_000;\n },\n ],\n requestHandler: (ctx: any) => handleBrowserPage(ctx, { ...sinkDeps(opts), sink }),\n failedRequestHandler: (ctx: any, error: Error) => {\n const request = ctx.request as { url: string; loadedUrl?: string };\n sink.skipped.push({ path: request.loadedUrl ?? request.url, reason: shortReason(error) });\n },\n } as never)\n : new PuppeteerCrawler({\n requestQueue: queue,\n maxRequestsPerCrawl: Math.max(1, opts.maxPages),\n maxCrawlDepth: Math.max(0, opts.depth),\n preNavigationHooks: [\n (_ctx: unknown, gotoOptions: { waitUntil?: string; timeout?: number }) => {\n gotoOptions.waitUntil = \"networkidle2\";\n gotoOptions.timeout = 30_000;\n },\n ],\n requestHandler: (ctx: any) => handleBrowserPage(ctx, { ...sinkDeps(opts), sink }),\n failedRequestHandler: (ctx: any, error: Error) => {\n const request = ctx.request as { url: string; loadedUrl?: string };\n sink.skipped.push({ path: request.loadedUrl ?? request.url, reason: shortReason(error) });\n },\n } as never);\n\n try {\n await crawler.run(seedUrls);\n } finally {\n await crawler.teardown().catch(() => {});\n }\n}\n\nfunction normalizeSitemapUrls(urls: string[]): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n for (const raw of urls) {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n continue;\n }\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") continue;\n url.hash = \"\";\n const key = url.toString();\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(key);\n }\n return out;\n}\n\nfunction applyUrlFilter(urls: string[], globs: string[] | undefined): string[] {\n if (!globs || globs.length === 0) return urls;\n const requests = urls.map((url) => new CrawleeRequest({ url }));\n const patterns = constructGlobObjectsFromGlobs(globs);\n return filterRequestsByPatterns(requests, patterns).map((r) => r.url);\n}\n\nasync function loadSitemap(urls: string[]): Promise<string[]> {\n try {\n const sitemap = await Sitemap.load(urls, undefined, { reportNetworkErrors: false });\n return normalizeSitemapUrls(sitemap.urls);\n } catch {\n return [];\n }\n}\n\nasync function discoverSitemapUrls(seedUrl: string): Promise<string[] | undefined> {\n const origin = new URL(seedUrl).origin;\n const fromSitemapXml = await loadSitemap([`${origin}/sitemap.xml`]);\n if (fromSitemapXml.length > 0) return fromSitemapXml;\n try {\n const robots = await RobotsTxtFile.find(seedUrl);\n const referenced = robots.getSitemaps();\n if (referenced.length > 0) {\n const fromRobots = await loadSitemap(referenced);\n if (fromRobots.length > 0) return fromRobots;\n }\n } catch {\n // robots.txt unreachable or malformed — treated as no sitemap\n }\n return undefined;\n}\n\nasync function runCrawl(kind: CrawlerKind, seedUrls: string[], opts: RunOptions): Promise<CrawlResult> {\n if (kind === \"playwright\" || kind === \"puppeteer\") {\n await requireBrowserEngine(kind);\n const sink: CrawlSink = { docs: [], skipped: [] };\n const queue = await freshQueue();\n await crawlWithBrowser(kind, queue, seedUrls, opts, sink);\n return { docs: dedupeDocs(sink.docs), skipped: sink.skipped };\n }\n\n const shellUrls: string[] = [];\n const sink: CrawlSink = { docs: [], skipped: [], shellUrls };\n const staticQueue = await freshQueue();\n await crawlWithCheerio(staticQueue, seedUrls, opts, sink);\n if (kind !== \"auto\" || shellUrls.length === 0) {\n return { docs: dedupeDocs(sink.docs), skipped: sink.skipped };\n }\n\n opts.log(\n `${shellUrls.length} page(s) look JS-rendered; retrying with playwright (install: npm i -g playwright && npx playwright install chromium) ...`,\n );\n const mod = await importOptional(\"playwright\");\n if (!mod) {\n return { docs: dedupeDocs(sink.docs), skipped: sink.skipped };\n }\n const browserSink: CrawlSink = { docs: [], skipped: [] };\n const browserQueue = await freshQueue();\n await crawlWithBrowser(\"playwright\", browserQueue, shellUrls, opts, browserSink);\n return {\n docs: dedupeDocs([...sink.docs, ...browserSink.docs]),\n skipped: [...sink.skipped, ...browserSink.skipped],\n };\n}\n\nexport async function crawlWebsite(seed: string, opts: CrawlOptions): Promise<CrawlResult> {\n const seedUrl = normalizeSeedUrl(seed);\n const kind = opts.crawler;\n const mode: SitemapMode = opts.sitemap ?? { kind: \"auto\" };\n const selectorStats = { hits: 0, misses: 0 };\n\n if (mode.kind === \"auto\" || mode.kind === \"sitemap-only\") {\n const sitemapUrls = await discoverSitemapUrls(seedUrl);\n if (sitemapUrls) {\n const filtered = applyUrlFilter(sitemapUrls, opts.urlFilter);\n const detail = filtered.length < sitemapUrls.length\n ? `${filtered.length} matching --url-filter`\n : `${filtered.length} URL(s)`;\n opts.log(`sitemap: ${sitemapUrls.length} URL(s) discovered, ${detail} to crawl`);\n return runCrawl(kind, filtered, { ...opts, followLinks: false, selectorStats });\n }\n if (mode.kind === \"sitemap-only\") {\n opts.log(`warning: no sitemap.xml and no sitemaps in robots.txt found for ${seedUrl}; nothing to ingest`);\n return { docs: [], skipped: [] };\n }\n opts.log(\"no sitemap found; falling back to HTML link crawling\");\n }\n\n const result = await runCrawl(kind, [seedUrl], {\n ...opts,\n followLinks: true,\n linkSelector: mode.kind === \"selector\" ? mode.selector : undefined,\n selectorStats,\n });\n if (mode.kind === \"selector\" && selectorStats.hits === 0 && selectorStats.misses > 0) {\n opts.log(`warning: --sitemap selector '${mode.selector}' matched no links`);\n }\n return result;\n}\n\nexport interface FeedUrlOptions {\n crawler?: CrawlerKind;\n sitemap?: SitemapMode;\n maxPages?: number;\n depth?: number;\n urlFilter?: string[];\n htmlFilter?: string;\n filePassword?: string;\n replace?: boolean;\n dryRun?: boolean;\n batchSize?: number;\n maxLen?: number;\n overlap?: number;\n tags?: string[];\n metadata?: Record<string, unknown>;\n log?: (msg: string) => void;\n progress?: FeedProgress;\n}\n\nexport async function feedUrl(\n ks: KnowledgeSource,\n url: string,\n opts: FeedUrlOptions = {},\n): Promise<FeedSummary> {\n const log = opts.log ?? ((m: string) => console.log(m));\n const kind: CrawlerKind = opts.crawler ?? \"auto\";\n if (!CRAWLER_KINDS.includes(kind)) {\n throw new Error(`unknown crawler '${kind}' (use auto, crawlee, playwright or puppeteer)`);\n }\n const maxPages = opts.maxPages && opts.maxPages > 0 ? Math.floor(opts.maxPages) : 999;\n const depth = typeof opts.depth === \"number\" && Number.isFinite(opts.depth) && opts.depth >= 0\n ? Math.floor(opts.depth)\n : 5;\n const maxLen = opts.maxLen ?? 1200;\n const overlap = opts.overlap ?? 180;\n\n const { docs, skipped } = await crawlWebsite(url, {\n crawler: kind,\n maxPages,\n depth,\n maxLen,\n overlap,\n tags: opts.tags,\n urlFilter: opts.urlFilter,\n htmlFilter: opts.htmlFilter,\n filePassword: opts.filePassword,\n sitemap: opts.sitemap,\n log,\n });\n for (const s of skipped) {\n log(`skipped ${s.path}: ${s.reason}`);\n }\n const progress = opts.progress ?? new FeedProgress({ total: docs.length, rejected: skipped.length });\n const summary = await feedDocs(ks, docs, {\n replace: opts.replace,\n dryRun: opts.dryRun,\n batchSize: opts.batchSize,\n tags: opts.tags,\n metadata: opts.metadata,\n log,\n progress,\n });\n return { ...summary, skippedFiles: [...summary.skippedFiles, ...skipped] };\n}\n\ntry {\n if (typeof log?.setLevel === \"function\" && log.LEVELS) {\n log.setLevel(log.LEVELS.ERROR);\n }\n} catch {\n}\n","import pg from \"pg\";\r\nimport { databaseUrl, normalizeUrl, ollamaUrl } from \"./config.js\";\r\nimport { entryTableName } from \"./db.js\";\r\nimport { probeModel } from \"./ollama.js\";\r\n\r\nexport const MIN_NODE_MAJOR = 20;\r\nexport const MIN_PGVECTOR_VERSION = \"0.5.0\";\r\nconst DB_CONNECT_TIMEOUT_MS = 5_000;\r\nconst OLLAMA_TIMEOUT_MS = 10_000;\r\n\r\nexport type CheckStatus = \"ok\" | \"warn\" | \"fail\" | \"skip\";\r\n\r\nexport interface CheckResult {\r\n id: string;\r\n status: CheckStatus;\r\n detail: string;\r\n}\r\n\r\nexport interface KsInfo {\r\n id: string;\r\n name: string;\r\n embedding_model: string;\r\n embedding_dim: number;\r\n ollama_url: string;\r\n}\r\n\r\nexport interface CheckOptions {\r\n model: string;\r\n url?: string;\r\n probe?: boolean;\r\n}\r\n\r\nexport function compareVersions(a: string, b: string): number {\r\n const pa = a.split(/[.-]/).map((s) => parseInt(s, 10) || 0);\r\n const pb = b.split(/[.-]/).map((s) => parseInt(s, 10) || 0);\r\n const len = Math.max(pa.length, pb.length);\r\n for (let i = 0; i < len; i++) {\r\n const d = (pa[i] ?? 0) - (pb[i] ?? 0);\r\n if (d !== 0) return d < 0 ? -1 : 1;\r\n }\r\n return 0;\r\n}\r\n\r\nexport function modelMatches(tag: string, wanted: string): boolean {\r\n if (tag === wanted) return true;\r\n if (wanted.includes(\":\")) return false;\r\n return tag === `${wanted}:latest`;\r\n}\r\n\r\nfunction errMsg(err: unknown): string {\r\n return err instanceof Error ? err.message : String(err);\r\n}\r\n\r\nfunction shortVersion(v: string): string {\r\n return v.split(/\\s+/).slice(0, 2).join(\" \") || v;\r\n}\r\n\r\ntype TagResult = { names: string[] } | { error: string };\r\n\r\nasync function fetchTags(baseUrl: string): Promise<TagResult> {\r\n try {\r\n const res = await fetch(`${normalizeUrl(baseUrl)}/api/tags`, {\r\n headers: { accept: \"application/json\" },\r\n signal: AbortSignal.timeout(OLLAMA_TIMEOUT_MS),\r\n });\r\n if (!res.ok) return { error: `HTTP ${res.status}` };\r\n const data = (await res.json()) as { models?: { name?: string; model?: string }[] };\r\n const names = (data.models ?? [])\r\n .map((m) => m.name ?? m.model ?? \"\")\r\n .filter(Boolean);\r\n return { names };\r\n } catch (err) {\r\n return { error: errMsg(err) };\r\n }\r\n}\r\n\r\nasync function checkOneModel(\r\n id: string,\r\n model: string,\r\n baseUrl: string,\r\n names: string[],\r\n ks: KsInfo | undefined,\r\n probe: boolean,\r\n): Promise<CheckResult> {\r\n const scope = ks ? ` (ks '${ks.name}')` : \"\";\r\n if (!names.some((n) => modelMatches(n, model))) {\r\n return {\r\n id,\r\n status: \"fail\",\r\n detail: `model '${model}' not found at ${baseUrl}${scope} — run: ollama pull ${model}`,\r\n };\r\n }\r\n if (probe) {\r\n try {\r\n const { dim } = await probeModel(baseUrl, model);\r\n if (ks && dim !== ks.embedding_dim) {\r\n return {\r\n id,\r\n status: \"fail\",\r\n detail: `model '${model}' serves dim=${dim} but ks '${ks.name}' expects dim=${ks.embedding_dim}`,\r\n };\r\n }\r\n return { id, status: \"ok\", detail: `model '${model}' available at ${baseUrl}${scope} (dim=${dim})` };\r\n } catch (err) {\r\n return { id, status: \"fail\", detail: `probe of model '${model}' failed — ${errMsg(err)}${scope}` };\r\n }\r\n }\r\n return { id, status: \"ok\", detail: `model '${model}' available at ${baseUrl}${scope}` };\r\n}\r\n\r\nexport async function runChecks(opts: CheckOptions): Promise<CheckResult[]> {\r\n const results: CheckResult[] = [];\r\n\r\n const major = Number(process.versions.node.split(\".\")[0]);\r\n results.push({\r\n id: \"node\",\r\n status: Number.isFinite(major) && major >= MIN_NODE_MAJOR ? \"ok\" : \"fail\",\r\n detail: `Node ${process.versions.node} (>= ${MIN_NODE_MAJOR} required)`,\r\n });\r\n\r\n let client: pg.Client | undefined;\r\n let dbUp = false;\r\n let kss: KsInfo[] = [];\r\n try {\r\n try {\r\n client = new pg.Client({\r\n connectionString: databaseUrl(),\r\n connectionTimeoutMillis: DB_CONNECT_TIMEOUT_MS,\r\n });\r\n client.on(\"error\", () => {});\r\n await client.connect();\r\n const v = await client.query(\"SELECT version() AS v\");\r\n dbUp = true;\r\n results.push({\r\n id: \"postgres\",\r\n status: \"ok\",\r\n detail: `PostgreSQL reachable at ${databaseUrl()} (${shortVersion(String(v.rows[0]?.v ?? \"\"))})`,\r\n });\r\n } catch (err) {\r\n results.push({\r\n id: \"postgres\",\r\n status: \"fail\",\r\n detail: `PostgreSQL not reachable at ${databaseUrl()} — ${errMsg(err)}`,\r\n });\r\n }\r\n\r\n if (dbUp && client) {\r\n try {\r\n await client.query(`CREATE EXTENSION IF NOT EXISTS vector`);\r\n const res = await client.query(\"SELECT extversion AS v FROM pg_extension WHERE extname = 'vector'\");\r\n const ver = res.rows[0]?.v as string | undefined;\r\n if (!ver) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"fail\",\r\n detail: \"pgvector extension not installed — install it on the PostgreSQL server (https://github.com/pgvector/pgvector)\",\r\n });\r\n } else if (compareVersions(ver, MIN_PGVECTOR_VERSION) < 0) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"warn\",\r\n detail: `pgvector ${ver} installed (>= ${MIN_PGVECTOR_VERSION} required for HNSW indexes; older versions fall back to sequential scans)`,\r\n });\r\n } else {\r\n results.push({ id: \"pgvector\", status: \"ok\", detail: `pgvector ${ver} installed` });\r\n }\r\n } catch (err) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"fail\",\r\n detail: `pgvector unavailable — ${errMsg(err)}`,\r\n });\r\n }\r\n } else {\r\n results.push({ id: \"pgvector\", status: \"skip\", detail: \"pgvector check skipped — PostgreSQL unreachable\" });\r\n }\r\n\r\n if (dbUp && client) {\r\n try {\r\n const hasKs = await client.query(\"SELECT to_regclass('ks') IS NOT NULL AS present\");\r\n if (!hasKs.rows[0]?.present) {\r\n results.push({ id: \"schema\", status: \"fail\", detail: \"schema missing — run: gresmcp init\" });\r\n } else {\r\n const ksRes = await client.query(\r\n \"SELECT id, name, embedding_model, embedding_dim, ollama_url FROM ks ORDER BY name\",\r\n );\r\n kss = ksRes.rows as KsInfo[];\r\n const missing: string[] = [];\r\n for (const ks of kss) {\r\n const r = await client.query(\"SELECT to_regclass($1) IS NOT NULL AS present\", [entryTableName(ks)]);\r\n if (!r.rows[0]?.present) missing.push(ks.name);\r\n }\r\n if (missing.length > 0) {\r\n results.push({\r\n id: \"schema\",\r\n status: \"fail\",\r\n detail: `entry table missing for: ${missing.join(\", \")} — run: gresmcp init`,\r\n });\r\n } else {\r\n results.push({\r\n id: \"schema\",\r\n status: \"ok\",\r\n detail: `schema ready (${kss.length} knowledge source(s))`,\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n results.push({ id: \"schema\", status: \"fail\", detail: `schema check failed — ${errMsg(err)}` });\r\n }\r\n } else {\r\n results.push({ id: \"schema\", status: \"skip\", detail: \"schema check skipped — PostgreSQL unreachable\" });\r\n }\r\n } finally {\r\n if (client) {\r\n try {\r\n await client.end();\r\n } catch {}\r\n }\r\n }\r\n\r\n const defaultUrl = ollamaUrl(opts.url);\r\n const tagCache = new Map<string, Promise<TagResult>>();\r\n const getTags = (baseUrl: string): Promise<TagResult> => {\r\n const key = normalizeUrl(baseUrl);\r\n let entry = tagCache.get(key);\r\n if (!entry) {\r\n entry = fetchTags(key);\r\n tagCache.set(key, entry);\r\n }\r\n return entry;\r\n };\r\n\r\n const defaultTags = await getTags(defaultUrl);\r\n results.push(\r\n \"error\" in defaultTags\r\n ? { id: \"ollama\", status: \"fail\", detail: `Ollama not reachable at ${defaultUrl} — ${defaultTags.error}` }\r\n : { id: \"ollama\", status: \"ok\", detail: `Ollama reachable at ${defaultUrl} (${defaultTags.names.length} model(s))` },\r\n );\r\n\r\n const tags = await getTags(defaultUrl);\r\n if (\"error\" in tags) {\r\n results.push({\r\n id: \"model\",\r\n status: \"skip\",\r\n detail: `Ollama unreachable at ${defaultUrl} — cannot verify model '${opts.model}'`,\r\n });\r\n } else {\r\n results.push(await checkOneModel(\"model\", opts.model, defaultUrl, tags.names, undefined, opts.probe ?? false));\r\n }\r\n\r\n for (const ks of kss) {\r\n const tags = await getTags(ks.ollama_url);\r\n if (\"error\" in tags) {\r\n results.push({\r\n id: `model:${ks.name}`,\r\n status: \"fail\",\r\n detail: `Ollama not reachable at ${ks.ollama_url} (required by ks '${ks.name}') — ${tags.error}`,\r\n });\r\n continue;\r\n }\r\n results.push(\r\n await checkOneModel(`model:${ks.name}`, ks.embedding_model, ks.ollama_url, tags.names, ks, opts.probe ?? false),\r\n );\r\n }\r\n\r\n return results;\r\n}\r\n","export const VERSION = \"1.3.0\";\r\n"],"mappings":"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","names":["res","fs","path","path","markdown","pct","fs","path","log","mkdtempSync","tmpdir","path","mkdtempSync","path","tmpdir","doc","reason","sink","log","tags","ensureEntryTable"]}