@arabold/docs-mcp-server 1.4.0 → 1.4.2
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/README.md +12 -3
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
A MCP server for fetching and searching 3rd party package documentation.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## ✨ Key Features
|
|
6
|
+
|
|
7
|
+
- 🌐 **Scrape & Index:** Fetch documentation from web sources or local files.
|
|
8
|
+
- 🧠 **Smart Processing:** Utilize semantic splitting and OpenAI embeddings for meaningful content chunks.
|
|
9
|
+
- 💾 **Efficient Storage:** Store data in SQLite, leveraging `sqlite-vec` for vector search and FTS5 for full-text search.
|
|
10
|
+
- 🔍 **Hybrid Search:** Combine vector and full-text search for relevant results across different library versions.
|
|
11
|
+
- ⚙️ **Job Management:** Handle scraping tasks asynchronously with a robust job queue and management tools (MCP & CLI).
|
|
12
|
+
- 🐳 **Easy Deployment:** Run the server easily using the provided Docker image.
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
This project provides a Model Context Protocol (MCP) server designed to scrape, process, index, and search documentation for various software libraries and packages. It fetches content from specified URLs, splits it into meaningful chunks using semantic splitting techniques, generates vector embeddings using OpenAI, and stores the data in an SQLite database. The server utilizes `sqlite-vec` for efficient vector similarity search and FTS5 for full-text search capabilities, combining them for hybrid search results. It supports versioning, allowing documentation for different library versions (including unversioned content) to be stored and queried distinctly.
|
|
8
17
|
|
|
9
18
|
The server exposes MCP tools for:
|
|
10
19
|
|
|
@@ -59,7 +68,7 @@ Run the server using the pre-built Docker image available on GitHub Container Re
|
|
|
59
68
|
- `-i`: Keep STDIN open, crucial for MCP communication over stdio.
|
|
60
69
|
- `--rm`: Automatically remove the container when it exits.
|
|
61
70
|
- `-e OPENAI_API_KEY="..."`: **Required.** Set your OpenAI API key.
|
|
62
|
-
- `-v docs-mcp-data:/data`: **Required for persistence.** Mounts a Docker named volume
|
|
71
|
+
- `-v docs-mcp-data:/data`: **Required for persistence.** Mounts a Docker named volume `docs-mcp-data` to the container's `/data` directory, where the database is stored. You can replace `docs-mcp-data` with a specific host path if preferred (e.g., `-v /path/on/host:/data`).
|
|
63
72
|
- `ghcr.io/arabold/docs-mcp-server:latest`: Specifies the public Docker image to use.
|
|
64
73
|
|
|
65
74
|
This is the recommended approach for integrating with tools like Claude Desktop or Cline.
|
package/dist/cli.js
CHANGED
|
@@ -16,7 +16,7 @@ import { Command } from "commander";
|
|
|
16
16
|
// package.json
|
|
17
17
|
var package_default = {
|
|
18
18
|
name: "@arabold/docs-mcp-server",
|
|
19
|
-
version: "1.
|
|
19
|
+
version: "1.4.1",
|
|
20
20
|
description: "MCP server for fetching and searching documentation",
|
|
21
21
|
type: "module",
|
|
22
22
|
bin: {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../package.json"],"sourcesContent":["#!/usr/bin/env node\nimport \"dotenv/config\";\nimport { Command } from \"commander\";\nimport packageJson from \"../package.json\";\nimport { PipelineManager } from \"./pipeline/PipelineManager\";\nimport { DocumentManagementService } from \"./store/DocumentManagementService\";\nimport { FindVersionTool, ListLibrariesTool, ScrapeTool, SearchTool } from \"./tools\";\nimport { LogLevel, setLogLevel } from \"./utils/logger\";\n\nconst formatOutput = (data: unknown) => JSON.stringify(data, null, 2);\n\nasync function main() {\n let docService: DocumentManagementService | undefined;\n let pipelineManager: PipelineManager | undefined;\n\n try {\n docService = new DocumentManagementService();\n await docService.initialize();\n\n // Instantiate PipelineManager for CLI use\n pipelineManager = new PipelineManager(docService); // Assign inside try\n // Start the manager for the CLI session\n await pipelineManager.start();\n\n const tools = {\n listLibraries: new ListLibrariesTool(docService),\n findVersion: new FindVersionTool(docService),\n scrape: new ScrapeTool(docService, pipelineManager), // Pass manager\n search: new SearchTool(docService),\n };\n\n const program = new Command();\n\n // Handle cleanup on SIGINT\n process.on(\"SIGINT\", async () => {\n if (pipelineManager) await pipelineManager.stop(); // Check before stopping\n if (docService) await docService.shutdown(); // Check before stopping\n process.exit(0);\n });\n\n program\n .name(\"docs-mcp\")\n .description(\"CLI for managing documentation vector store\")\n .version(packageJson.version)\n // Add global options for logging level\n .option(\"--verbose\", \"Enable verbose (debug) logging\", false)\n .option(\"--silent\", \"Disable all logging except errors\", false);\n\n program\n .command(\"scrape <library> <url>\") // Remove <version> as positional\n .description(\"Scrape and index documentation from a URL\")\n .option(\"-v, --version <string>\", \"Version of the library (optional)\") // Add optional version flag\n .option(\"-p, --max-pages <number>\", \"Maximum pages to scrape\", \"100\")\n .option(\"-d, --max-depth <number>\", \"Maximum navigation depth\", \"3\")\n .option(\"-c, --max-concurrency <number>\", \"Maximum concurrent page requests\", \"3\")\n .option(\"--ignore-errors\", \"Ignore errors during scraping\", true)\n .action(async (library, url, options) => {\n // Update action parameters\n const result = await tools.scrape.execute({\n url,\n library,\n version: options.version, // Get version from options\n options: {\n maxPages: Number.parseInt(options.maxPages),\n maxDepth: Number.parseInt(options.maxDepth),\n maxConcurrency: Number.parseInt(options.maxConcurrency),\n ignoreErrors: options.ignoreErrors,\n },\n // CLI always waits for completion (default behavior)\n });\n // Type guard to satisfy TypeScript\n if (\"pagesScraped\" in result) {\n console.log(`✅ Successfully scraped ${result.pagesScraped} pages`);\n } else {\n // This branch should not be hit by the CLI\n console.log(`🚀 Scraping job started with ID: ${result.jobId}`);\n }\n });\n\n program\n .command(\"search <library> <query>\") // Remove <version> as positional\n .description(\n \"Search documents in a library. Version matching examples:\\n\" +\n \" - search react --version 18.0.0 'hooks' -> matches docs for React 18.0.0 or earlier versions\\n\" +\n \" - search react --version 18.0.0 'hooks' --exact-match -> only matches React 18.0.0\\n\" +\n \" - search typescript --version 5.x 'types' -> matches any TypeScript 5.x.x version\\n\" +\n \" - search typescript --version 5.2.x 'types' -> matches any TypeScript 5.2.x version\",\n )\n .option(\n \"-v, --version <string>\", // Add optional version flag\n \"Version of the library (optional, supports ranges)\",\n )\n .option(\"-l, --limit <number>\", \"Maximum number of results\", \"5\")\n .option(\n \"-e, --exact-match\",\n \"Only use exact version match (e.g., '18.0.0' matches only 18.0.0, not 17.x.x) (default: false)\",\n false,\n )\n .action(async (library, query, options) => {\n // Update action parameters\n const result = await tools.search.execute({\n library,\n version: options.version, // Get version from options\n query,\n limit: Number.parseInt(options.limit),\n exactMatch: options.exactMatch,\n });\n console.log(formatOutput(result.results));\n });\n\n program\n .command(\"list\")\n .description(\"List all available libraries and their versions\")\n .action(async () => {\n const result = await tools.listLibraries.execute();\n console.log(formatOutput(result.libraries));\n });\n\n program\n .command(\"find-version <library>\") // Remove [targetVersion] positional\n .description(\"Find the best matching version for a library\")\n .option(\n \"-v, --version <string>\", // Add optional version flag\n \"Target version to match (optional, supports ranges)\",\n )\n .action(async (library, options) => {\n // Update action parameters\n const versionInfo = await tools.findVersion.execute({\n library,\n targetVersion: options.version, // Get version from options\n });\n // findVersion.execute now returns a string, handle potential error messages within it\n if (!versionInfo) {\n // Should not happen with current tool logic, but good practice\n throw new Error(\"Failed to get version information\");\n }\n console.log(versionInfo); // Log the descriptive string from the tool\n });\n\n program\n .command(\"remove <library>\") // Library as positional argument\n .description(\"Remove documents for a specific library and version\")\n .option(\n \"-v, --version <string>\",\n \"Version to remove (optional, removes unversioned if omitted)\",\n )\n .action(async (library, options) => {\n // library is now the first arg\n if (!docService) {\n throw new Error(\"Document service not initialized.\");\n }\n const { version } = options; // Get version from options\n try {\n await docService.removeAllDocuments(library, version);\n console.log(\n `✅ Successfully removed documents for ${library}${version ? `@${version}` : \" (unversioned)\"}.`,\n );\n } catch (error) {\n console.error(\n `❌ Failed to remove documents for ${library}${version ? `@${version}` : \" (unversioned)\"}:`,\n error instanceof Error ? error.message : String(error),\n );\n // Re-throw to trigger the main catch block for shutdown\n throw error;\n }\n });\n\n // Hook to set log level after parsing global options but before executing command action\n program.hook(\"preAction\", (thisCommand) => {\n // Global options are attached to the program (thisCommand)\n const options = thisCommand.opts();\n if (options.silent) {\n // If silent is true, it overrides verbose\n setLogLevel(LogLevel.ERROR);\n } else if (options.verbose) {\n setLogLevel(LogLevel.DEBUG);\n }\n // Otherwise, the default LogLevel.INFO remains set from logger.ts\n });\n\n await program.parseAsync();\n } catch (error) {\n console.error(\"Error:\", error instanceof Error ? error.message : String(error));\n if (pipelineManager) await pipelineManager.stop(); // Check before stopping\n if (docService) await docService.shutdown();\n process.exit(1);\n }\n\n // Clean shutdown after successful execution\n if (pipelineManager) await pipelineManager.stop(); // Check before stopping\n await docService.shutdown();\n process.exit(0);\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n","{\n \"name\": \"@arabold/docs-mcp-server\",\n \"version\": \"1.3.0\",\n \"description\": \"MCP server for fetching and searching documentation\",\n \"type\": \"module\",\n \"bin\": {\n \"docs-server\": \"dist/server.js\",\n \"docs-cli\": \"dist/cli.js\"\n },\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/arabold/docs-mcp-server.git\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\",\n \"package.json\"\n ],\n \"scripts\": {\n \"prepare\": \"husky || true\",\n \"build\": \"tsup\",\n \"cli\": \"node --enable-source-maps dist/cli.js\",\n \"start\": \"node --enable-source-maps dist/server.js\",\n \"dev:cli\": \"npm run build && node --enable-source-maps dist/cli.js\",\n \"server\": \"node --enable-source-maps --watch dist/server.js\",\n \"dev:server\": \"run-p \\\"build -- --watch\\\" \\\"server\\\"\",\n \"test\": \"vitest\",\n \"lint\": \"biome check .\",\n \"format\": \"biome format . --write\",\n \"db:generate\": \"drizzle-kit generate\",\n \"db:push\": \"drizzle-kit push\"\n },\n \"dependencies\": {\n \"@langchain/community\": \"^0.3.34\",\n \"@langchain/openai\": \"^0.5.0\",\n \"@modelcontextprotocol/sdk\": \"^1.6.1\",\n \"axios\": \"^1.8.3\",\n \"axios-retry\": \"^4.5.0\",\n \"better-sqlite3\": \"^11.9.1\",\n \"commander\": \"^13.1.0\",\n \"dompurify\": \"^3.2.4\",\n \"dotenv\": \"^16.4.7\",\n \"drizzle-orm\": \"^0.41.0\",\n \"env-paths\": \"^3.0.0\",\n \"fuse.js\": \"^7.1.0\",\n \"jsdom\": \"^26.0.0\",\n \"langchain\": \"0.3.19\",\n \"pg\": \"^8.14.0\",\n \"remark\": \"^15.0.1\",\n \"remark-gfm\": \"^4.0.1\",\n \"remark-html\": \"^16.0.1\",\n \"semver\": \"^7.7.1\",\n \"sqlite-vec\": \"^0.1.7-alpha.2\",\n \"turndown\": \"^7.2.0\",\n \"zod\": \"^3.24.2\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"1.9.4\",\n \"@commitlint/cli\": \"^19.8.0\",\n \"@commitlint/config-conventional\": \"^19.8.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@semantic-release/github\": \"^11.0.1\",\n \"@semantic-release/npm\": \"^12.0.1\",\n \"@types/better-sqlite3\": \"^7.6.12\",\n \"@types/jsdom\": \"~21.1.7\",\n \"@types/lint-staged\": \"~13.3.0\",\n \"@types/node\": \"^20.17.23\",\n \"@types/node-fetch\": \"^2.6.12\",\n \"@types/pg\": \"~8.11.11\",\n \"@types/semver\": \"^7.5.8\",\n \"@types/turndown\": \"^5.0.5\",\n \"drizzle-kit\": \"^0.30.5\",\n \"husky\": \"^9.1.7\",\n \"lint-staged\": \"^15.5.0\",\n \"memfs\": \"^4.17.0\",\n \"npm-run-all\": \"^4.1.5\",\n \"semantic-release\": \"^24.2.3\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.8.2\",\n \"vite\": \"^6.2.1\",\n \"vitest\": \"^3.0.8\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"lint-staged\": {\n \"*.{js,ts,jsx,tsx,json,md}\": [\n \"biome check --apply --no-errors-on-unmatched\",\n \"biome format --write --no-errors-on-unmatched\"\n ]\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../package.json"],"sourcesContent":["#!/usr/bin/env node\nimport \"dotenv/config\";\nimport { Command } from \"commander\";\nimport packageJson from \"../package.json\";\nimport { PipelineManager } from \"./pipeline/PipelineManager\";\nimport { DocumentManagementService } from \"./store/DocumentManagementService\";\nimport { FindVersionTool, ListLibrariesTool, ScrapeTool, SearchTool } from \"./tools\";\nimport { LogLevel, setLogLevel } from \"./utils/logger\";\n\nconst formatOutput = (data: unknown) => JSON.stringify(data, null, 2);\n\nasync function main() {\n let docService: DocumentManagementService | undefined;\n let pipelineManager: PipelineManager | undefined;\n\n try {\n docService = new DocumentManagementService();\n await docService.initialize();\n\n // Instantiate PipelineManager for CLI use\n pipelineManager = new PipelineManager(docService); // Assign inside try\n // Start the manager for the CLI session\n await pipelineManager.start();\n\n const tools = {\n listLibraries: new ListLibrariesTool(docService),\n findVersion: new FindVersionTool(docService),\n scrape: new ScrapeTool(docService, pipelineManager), // Pass manager\n search: new SearchTool(docService),\n };\n\n const program = new Command();\n\n // Handle cleanup on SIGINT\n process.on(\"SIGINT\", async () => {\n if (pipelineManager) await pipelineManager.stop(); // Check before stopping\n if (docService) await docService.shutdown(); // Check before stopping\n process.exit(0);\n });\n\n program\n .name(\"docs-mcp\")\n .description(\"CLI for managing documentation vector store\")\n .version(packageJson.version)\n // Add global options for logging level\n .option(\"--verbose\", \"Enable verbose (debug) logging\", false)\n .option(\"--silent\", \"Disable all logging except errors\", false);\n\n program\n .command(\"scrape <library> <url>\") // Remove <version> as positional\n .description(\"Scrape and index documentation from a URL\")\n .option(\"-v, --version <string>\", \"Version of the library (optional)\") // Add optional version flag\n .option(\"-p, --max-pages <number>\", \"Maximum pages to scrape\", \"100\")\n .option(\"-d, --max-depth <number>\", \"Maximum navigation depth\", \"3\")\n .option(\"-c, --max-concurrency <number>\", \"Maximum concurrent page requests\", \"3\")\n .option(\"--ignore-errors\", \"Ignore errors during scraping\", true)\n .action(async (library, url, options) => {\n // Update action parameters\n const result = await tools.scrape.execute({\n url,\n library,\n version: options.version, // Get version from options\n options: {\n maxPages: Number.parseInt(options.maxPages),\n maxDepth: Number.parseInt(options.maxDepth),\n maxConcurrency: Number.parseInt(options.maxConcurrency),\n ignoreErrors: options.ignoreErrors,\n },\n // CLI always waits for completion (default behavior)\n });\n // Type guard to satisfy TypeScript\n if (\"pagesScraped\" in result) {\n console.log(`✅ Successfully scraped ${result.pagesScraped} pages`);\n } else {\n // This branch should not be hit by the CLI\n console.log(`🚀 Scraping job started with ID: ${result.jobId}`);\n }\n });\n\n program\n .command(\"search <library> <query>\") // Remove <version> as positional\n .description(\n \"Search documents in a library. Version matching examples:\\n\" +\n \" - search react --version 18.0.0 'hooks' -> matches docs for React 18.0.0 or earlier versions\\n\" +\n \" - search react --version 18.0.0 'hooks' --exact-match -> only matches React 18.0.0\\n\" +\n \" - search typescript --version 5.x 'types' -> matches any TypeScript 5.x.x version\\n\" +\n \" - search typescript --version 5.2.x 'types' -> matches any TypeScript 5.2.x version\",\n )\n .option(\n \"-v, --version <string>\", // Add optional version flag\n \"Version of the library (optional, supports ranges)\",\n )\n .option(\"-l, --limit <number>\", \"Maximum number of results\", \"5\")\n .option(\n \"-e, --exact-match\",\n \"Only use exact version match (e.g., '18.0.0' matches only 18.0.0, not 17.x.x) (default: false)\",\n false,\n )\n .action(async (library, query, options) => {\n // Update action parameters\n const result = await tools.search.execute({\n library,\n version: options.version, // Get version from options\n query,\n limit: Number.parseInt(options.limit),\n exactMatch: options.exactMatch,\n });\n console.log(formatOutput(result.results));\n });\n\n program\n .command(\"list\")\n .description(\"List all available libraries and their versions\")\n .action(async () => {\n const result = await tools.listLibraries.execute();\n console.log(formatOutput(result.libraries));\n });\n\n program\n .command(\"find-version <library>\") // Remove [targetVersion] positional\n .description(\"Find the best matching version for a library\")\n .option(\n \"-v, --version <string>\", // Add optional version flag\n \"Target version to match (optional, supports ranges)\",\n )\n .action(async (library, options) => {\n // Update action parameters\n const versionInfo = await tools.findVersion.execute({\n library,\n targetVersion: options.version, // Get version from options\n });\n // findVersion.execute now returns a string, handle potential error messages within it\n if (!versionInfo) {\n // Should not happen with current tool logic, but good practice\n throw new Error(\"Failed to get version information\");\n }\n console.log(versionInfo); // Log the descriptive string from the tool\n });\n\n program\n .command(\"remove <library>\") // Library as positional argument\n .description(\"Remove documents for a specific library and version\")\n .option(\n \"-v, --version <string>\",\n \"Version to remove (optional, removes unversioned if omitted)\",\n )\n .action(async (library, options) => {\n // library is now the first arg\n if (!docService) {\n throw new Error(\"Document service not initialized.\");\n }\n const { version } = options; // Get version from options\n try {\n await docService.removeAllDocuments(library, version);\n console.log(\n `✅ Successfully removed documents for ${library}${version ? `@${version}` : \" (unversioned)\"}.`,\n );\n } catch (error) {\n console.error(\n `❌ Failed to remove documents for ${library}${version ? `@${version}` : \" (unversioned)\"}:`,\n error instanceof Error ? error.message : String(error),\n );\n // Re-throw to trigger the main catch block for shutdown\n throw error;\n }\n });\n\n // Hook to set log level after parsing global options but before executing command action\n program.hook(\"preAction\", (thisCommand) => {\n // Global options are attached to the program (thisCommand)\n const options = thisCommand.opts();\n if (options.silent) {\n // If silent is true, it overrides verbose\n setLogLevel(LogLevel.ERROR);\n } else if (options.verbose) {\n setLogLevel(LogLevel.DEBUG);\n }\n // Otherwise, the default LogLevel.INFO remains set from logger.ts\n });\n\n await program.parseAsync();\n } catch (error) {\n console.error(\"Error:\", error instanceof Error ? error.message : String(error));\n if (pipelineManager) await pipelineManager.stop(); // Check before stopping\n if (docService) await docService.shutdown();\n process.exit(1);\n }\n\n // Clean shutdown after successful execution\n if (pipelineManager) await pipelineManager.stop(); // Check before stopping\n await docService.shutdown();\n process.exit(0);\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error:\", error);\n process.exit(1);\n});\n","{\n \"name\": \"@arabold/docs-mcp-server\",\n \"version\": \"1.4.1\",\n \"description\": \"MCP server for fetching and searching documentation\",\n \"type\": \"module\",\n \"bin\": {\n \"docs-server\": \"dist/server.js\",\n \"docs-cli\": \"dist/cli.js\"\n },\n \"license\": \"MIT\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/arabold/docs-mcp-server.git\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\",\n \"package.json\"\n ],\n \"scripts\": {\n \"prepare\": \"husky || true\",\n \"build\": \"tsup\",\n \"cli\": \"node --enable-source-maps dist/cli.js\",\n \"start\": \"node --enable-source-maps dist/server.js\",\n \"dev:cli\": \"npm run build && node --enable-source-maps dist/cli.js\",\n \"server\": \"node --enable-source-maps --watch dist/server.js\",\n \"dev:server\": \"run-p \\\"build -- --watch\\\" \\\"server\\\"\",\n \"test\": \"vitest\",\n \"lint\": \"biome check .\",\n \"format\": \"biome format . --write\",\n \"db:generate\": \"drizzle-kit generate\",\n \"db:push\": \"drizzle-kit push\"\n },\n \"dependencies\": {\n \"@langchain/community\": \"^0.3.34\",\n \"@langchain/openai\": \"^0.5.0\",\n \"@modelcontextprotocol/sdk\": \"^1.6.1\",\n \"axios\": \"^1.8.3\",\n \"axios-retry\": \"^4.5.0\",\n \"better-sqlite3\": \"^11.9.1\",\n \"commander\": \"^13.1.0\",\n \"dompurify\": \"^3.2.4\",\n \"dotenv\": \"^16.4.7\",\n \"drizzle-orm\": \"^0.41.0\",\n \"env-paths\": \"^3.0.0\",\n \"fuse.js\": \"^7.1.0\",\n \"jsdom\": \"^26.0.0\",\n \"langchain\": \"0.3.19\",\n \"pg\": \"^8.14.0\",\n \"remark\": \"^15.0.1\",\n \"remark-gfm\": \"^4.0.1\",\n \"remark-html\": \"^16.0.1\",\n \"semver\": \"^7.7.1\",\n \"sqlite-vec\": \"^0.1.7-alpha.2\",\n \"turndown\": \"^7.2.0\",\n \"zod\": \"^3.24.2\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"1.9.4\",\n \"@commitlint/cli\": \"^19.8.0\",\n \"@commitlint/config-conventional\": \"^19.8.0\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@semantic-release/github\": \"^11.0.1\",\n \"@semantic-release/npm\": \"^12.0.1\",\n \"@types/better-sqlite3\": \"^7.6.12\",\n \"@types/jsdom\": \"~21.1.7\",\n \"@types/lint-staged\": \"~13.3.0\",\n \"@types/node\": \"^20.17.23\",\n \"@types/node-fetch\": \"^2.6.12\",\n \"@types/pg\": \"~8.11.11\",\n \"@types/semver\": \"^7.5.8\",\n \"@types/turndown\": \"^5.0.5\",\n \"drizzle-kit\": \"^0.30.5\",\n \"husky\": \"^9.1.7\",\n \"lint-staged\": \"^15.5.0\",\n \"memfs\": \"^4.17.0\",\n \"npm-run-all\": \"^4.1.5\",\n \"semantic-release\": \"^24.2.3\",\n \"tsup\": \"^8.4.0\",\n \"typescript\": \"^5.8.2\",\n \"vite\": \"^6.2.1\",\n \"vitest\": \"^3.0.8\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"lint-staged\": {\n \"*.{js,ts,jsx,tsx,json,md}\": [\n \"biome check --apply --no-errors-on-unmatched\",\n \"biome format --write --no-errors-on-unmatched\"\n ]\n }\n}\n"],"mappings":"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","names":[]}
|