@arabold/docs-mcp-server 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.
@@ -1279,6 +1279,17 @@ var VersionNotFoundError = class extends ToolError {
1279
1279
  return this.availableVersions.sort((a, b) => semver.compare(b.version, a.version))[0];
1280
1280
  }
1281
1281
  };
1282
+ var LibraryNotFoundError = class extends ToolError {
1283
+ constructor(requestedLibrary, suggestions = []) {
1284
+ let message = `Library '${requestedLibrary}' not found.`;
1285
+ if (suggestions.length > 0) {
1286
+ message += ` Did you mean one of these: ${suggestions.join(", ")}?`;
1287
+ }
1288
+ super(message, "SearchTool");
1289
+ this.requestedLibrary = requestedLibrary;
1290
+ this.suggestions = suggestions;
1291
+ }
1292
+ };
1282
1293
 
1283
1294
  // src/tools/SearchTool.ts
1284
1295
  var SearchTool = class {
@@ -1292,6 +1303,7 @@ var SearchTool = class {
1292
1303
  `\u{1F50D} Searching ${library}@${version} for: ${query}${exactMatch ? " (exact match)" : ""}`
1293
1304
  );
1294
1305
  try {
1306
+ await this.docService.validateLibraryExists(library);
1295
1307
  let versionToSearch = version;
1296
1308
  if (!exactMatch) {
1297
1309
  const versionResult = await this.docService.findBestVersion(library, version);
@@ -1306,6 +1318,16 @@ var SearchTool = class {
1306
1318
  logger.info(`\u2705 Found ${results.length} matching results`);
1307
1319
  return { results };
1308
1320
  } catch (error) {
1321
+ if (error instanceof LibraryNotFoundError) {
1322
+ logger.info(`\u2139\uFE0F Library not found: ${error.message}`);
1323
+ return {
1324
+ results: [],
1325
+ error: {
1326
+ message: error.message,
1327
+ suggestions: error.suggestions
1328
+ }
1329
+ };
1330
+ }
1309
1331
  if (error instanceof VersionNotFoundError) {
1310
1332
  logger.info(`\u2139\uFE0F Version not found: ${error.message}`);
1311
1333
  return {
@@ -1659,6 +1681,7 @@ var RemoveTool = class {
1659
1681
  // src/store/DocumentManagementService.ts
1660
1682
  import { mkdirSync } from "node:fs";
1661
1683
  import path3 from "node:path";
1684
+ import Fuse from "fuse.js";
1662
1685
  import semver3 from "semver";
1663
1686
 
1664
1687
  // src/splitter/SemanticMarkdownSplitter.ts
@@ -10912,6 +10935,14 @@ var DocumentStore = class {
10912
10935
  batchSize: 512
10913
10936
  });
10914
10937
  }
10938
+ /**
10939
+ * Escapes a query string for use with SQLite FTS5 MATCH operator.
10940
+ * Wraps the query in double quotes and escapes internal double quotes.
10941
+ */
10942
+ escapeFtsQuery(query) {
10943
+ const escapedQuotes = query.replace(/"/g, '""');
10944
+ return `"${escapedQuotes}"`;
10945
+ }
10915
10946
  /**
10916
10947
  * Initializes database connection and ensures readiness
10917
10948
  */
@@ -11057,6 +11088,7 @@ var DocumentStore = class {
11057
11088
  async findByContent(library, version, query, limit) {
11058
11089
  try {
11059
11090
  const embedding = await this.embeddings.embedQuery(query);
11091
+ const ftsQuery = this.escapeFtsQuery(query);
11060
11092
  const stmt = this.db.prepare(`
11061
11093
  WITH vec_scores AS (
11062
11094
  SELECT
@@ -11099,7 +11131,8 @@ var DocumentStore = class {
11099
11131
  limit,
11100
11132
  library.toLowerCase(),
11101
11133
  version.toLowerCase(),
11102
- query,
11134
+ ftsQuery,
11135
+ // Use the escaped query
11103
11136
  limit
11104
11137
  );
11105
11138
  const rankedResults = this.assignRanks(rawResults);
@@ -11254,16 +11287,53 @@ var DocumentManagementService = class {
11254
11287
  );
11255
11288
  this.splitter = greedySplitter;
11256
11289
  }
11290
+ /**
11291
+ * Initializes the underlying document store.
11292
+ */
11257
11293
  async initialize() {
11258
11294
  await this.store.initialize();
11259
11295
  }
11296
+ /**
11297
+ * Shuts down the underlying document store.
11298
+ */
11260
11299
  async shutdown() {
11261
11300
  logger.info("\u{1F50C} Shutting down store manager");
11262
11301
  await this.store.shutdown();
11263
11302
  }
11264
11303
  /**
11265
- * Returns a list of all available versions for a library.
11266
- * Only returns versions that follow semver format.
11304
+ * Validates if a library exists in the store (either versioned or unversioned).
11305
+ * Throws LibraryNotFoundError with suggestions if the library is not found.
11306
+ * @param library The name of the library to validate.
11307
+ * @throws {LibraryNotFoundError} If the library does not exist.
11308
+ */
11309
+ async validateLibraryExists(library) {
11310
+ logger.info(`\u{1F50E} Validating existence of library: ${library}`);
11311
+ const normalizedLibrary = library.toLowerCase();
11312
+ const versions = await this.listVersions(normalizedLibrary);
11313
+ const hasUnversioned = await this.exists(normalizedLibrary, "");
11314
+ if (versions.length === 0 && !hasUnversioned) {
11315
+ logger.warn(`\u26A0\uFE0F Library '${library}' not found.`);
11316
+ const allLibraries = await this.listLibraries();
11317
+ const libraryNames = allLibraries.map((lib) => lib.library);
11318
+ let suggestions = [];
11319
+ if (libraryNames.length > 0) {
11320
+ const fuse = new Fuse(libraryNames, {
11321
+ // Configure fuse.js options if needed (e.g., threshold)
11322
+ // isCaseSensitive: false, // Handled by normalizing library names
11323
+ // includeScore: true,
11324
+ threshold: 0.4
11325
+ // Adjust threshold for desired fuzziness (0=exact, 1=match anything)
11326
+ });
11327
+ const results = fuse.search(normalizedLibrary);
11328
+ suggestions = results.slice(0, 3).map((result) => result.item);
11329
+ logger.info(`\u{1F50D} Found suggestions: ${suggestions.join(", ")}`);
11330
+ }
11331
+ throw new LibraryNotFoundError(library, suggestions);
11332
+ }
11333
+ logger.info(`\u2705 Library '${library}' confirmed to exist.`);
11334
+ }
11335
+ /**
11336
+ * Returns a list of all available semantic versions for a library.
11267
11337
  */
11268
11338
  async listVersions(library) {
11269
11339
  const versions = await this.store.queryUniqueVersions(library);
@@ -11428,4 +11498,4 @@ export {
11428
11498
  RemoveTool,
11429
11499
  DocumentManagementService
11430
11500
  };
11431
- //# sourceMappingURL=chunk-Y3EE54SV.js.map
11501
+ //# sourceMappingURL=chunk-75KNYK47.js.map