@arabold/docs-mcp-server 1.7.0 → 1.8.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/README.md +24 -2
- package/dist/{chunk-FAZDXJQN.js → chunk-ADZQJG2M.js} +328 -254
- package/dist/chunk-ADZQJG2M.js.map +1 -0
- package/dist/cli.js +22 -3
- package/dist/cli.js.map +1 -1
- package/dist/server.js +34 -11
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-FAZDXJQN.js.map +0 -1
|
@@ -144,55 +144,8 @@ var logger = {
|
|
|
144
144
|
}
|
|
145
145
|
};
|
|
146
146
|
|
|
147
|
-
//
|
|
148
|
-
|
|
149
|
-
for (let i = 0; i < 256; ++i) {
|
|
150
|
-
byteToHex.push((i + 256).toString(16).slice(1));
|
|
151
|
-
}
|
|
152
|
-
function unsafeStringify(arr, offset = 0) {
|
|
153
|
-
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// node_modules/uuid/dist/esm-node/rng.js
|
|
157
|
-
import crypto from "node:crypto";
|
|
158
|
-
var rnds8Pool = new Uint8Array(256);
|
|
159
|
-
var poolPtr = rnds8Pool.length;
|
|
160
|
-
function rng() {
|
|
161
|
-
if (poolPtr > rnds8Pool.length - 16) {
|
|
162
|
-
crypto.randomFillSync(rnds8Pool);
|
|
163
|
-
poolPtr = 0;
|
|
164
|
-
}
|
|
165
|
-
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// node_modules/uuid/dist/esm-node/native.js
|
|
169
|
-
import crypto2 from "node:crypto";
|
|
170
|
-
var native_default = {
|
|
171
|
-
randomUUID: crypto2.randomUUID
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
// node_modules/uuid/dist/esm-node/v4.js
|
|
175
|
-
function v4(options, buf, offset) {
|
|
176
|
-
if (native_default.randomUUID && !buf && !options) {
|
|
177
|
-
return native_default.randomUUID();
|
|
178
|
-
}
|
|
179
|
-
options = options || {};
|
|
180
|
-
const rnds = options.random || (options.rng || rng)();
|
|
181
|
-
rnds[6] = rnds[6] & 15 | 64;
|
|
182
|
-
rnds[8] = rnds[8] & 63 | 128;
|
|
183
|
-
if (buf) {
|
|
184
|
-
offset = offset || 0;
|
|
185
|
-
for (let i = 0; i < 16; ++i) {
|
|
186
|
-
buf[offset + i] = rnds[i];
|
|
187
|
-
}
|
|
188
|
-
return buf;
|
|
189
|
-
}
|
|
190
|
-
return unsafeStringify(rnds);
|
|
191
|
-
}
|
|
192
|
-
var v4_default = v4;
|
|
193
|
-
|
|
194
|
-
// src/utils/url.ts
|
|
195
|
-
import psl from "psl";
|
|
147
|
+
// src/scraper/fetcher/HttpFetcher.ts
|
|
148
|
+
import axios from "axios";
|
|
196
149
|
|
|
197
150
|
// src/utils/errors.ts
|
|
198
151
|
var ScraperError = class extends Error {
|
|
@@ -224,67 +177,7 @@ var RedirectError = class extends ScraperError {
|
|
|
224
177
|
}
|
|
225
178
|
};
|
|
226
179
|
|
|
227
|
-
// src/utils/url.ts
|
|
228
|
-
var defaultNormalizerOptions = {
|
|
229
|
-
ignoreCase: true,
|
|
230
|
-
removeHash: true,
|
|
231
|
-
removeTrailingSlash: true,
|
|
232
|
-
removeQuery: false,
|
|
233
|
-
removeIndex: true
|
|
234
|
-
};
|
|
235
|
-
function normalizeUrl(url, options = defaultNormalizerOptions) {
|
|
236
|
-
try {
|
|
237
|
-
const parsedUrl = new URL(url);
|
|
238
|
-
const finalOptions = { ...defaultNormalizerOptions, ...options };
|
|
239
|
-
const normalized = new URL(parsedUrl.origin + parsedUrl.pathname);
|
|
240
|
-
if (finalOptions.removeIndex) {
|
|
241
|
-
normalized.pathname = normalized.pathname.replace(
|
|
242
|
-
/\/index\.(html|htm|asp|php|jsp)$/i,
|
|
243
|
-
"/"
|
|
244
|
-
);
|
|
245
|
-
}
|
|
246
|
-
if (finalOptions.removeTrailingSlash && normalized.pathname.length > 1) {
|
|
247
|
-
normalized.pathname = normalized.pathname.replace(/\/+$/, "");
|
|
248
|
-
}
|
|
249
|
-
const preservedHash = !finalOptions.removeHash ? parsedUrl.hash : "";
|
|
250
|
-
const preservedSearch = !finalOptions.removeQuery ? parsedUrl.search : "";
|
|
251
|
-
let result = normalized.origin + normalized.pathname;
|
|
252
|
-
if (preservedSearch) {
|
|
253
|
-
result += preservedSearch;
|
|
254
|
-
}
|
|
255
|
-
if (preservedHash) {
|
|
256
|
-
result += preservedHash;
|
|
257
|
-
}
|
|
258
|
-
if (finalOptions.ignoreCase) {
|
|
259
|
-
result = result.toLowerCase();
|
|
260
|
-
}
|
|
261
|
-
return result;
|
|
262
|
-
} catch {
|
|
263
|
-
return url;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
function validateUrl(url) {
|
|
267
|
-
try {
|
|
268
|
-
new URL(url);
|
|
269
|
-
} catch (error) {
|
|
270
|
-
throw new InvalidUrlError(url, error instanceof Error ? error : void 0);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
function hasSameHostname(urlA, urlB) {
|
|
274
|
-
return urlA.hostname.toLowerCase() === urlB.hostname.toLowerCase();
|
|
275
|
-
}
|
|
276
|
-
function hasSameDomain(urlA, urlB) {
|
|
277
|
-
const domainA = psl.get(urlA.hostname.toLowerCase());
|
|
278
|
-
const domainB = psl.get(urlB.hostname.toLowerCase());
|
|
279
|
-
return domainA !== null && domainA === domainB;
|
|
280
|
-
}
|
|
281
|
-
function isSubpath(baseUrl, targetUrl) {
|
|
282
|
-
const basePath = baseUrl.pathname.endsWith("/") ? baseUrl.pathname : `${baseUrl.pathname}/`;
|
|
283
|
-
return targetUrl.pathname.startsWith(basePath);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
180
|
// src/scraper/fetcher/HttpFetcher.ts
|
|
287
|
-
import axios from "axios";
|
|
288
181
|
var HttpFetcher = class {
|
|
289
182
|
MAX_RETRIES = 6;
|
|
290
183
|
BASE_DELAY = 1e3;
|
|
@@ -394,29 +287,6 @@ var FileFetcher = class {
|
|
|
394
287
|
}
|
|
395
288
|
};
|
|
396
289
|
|
|
397
|
-
// src/scraper/strategies/BaseScraperStrategy.ts
|
|
398
|
-
import { URL as URL2 } from "node:url";
|
|
399
|
-
|
|
400
|
-
// src/pipeline/errors.ts
|
|
401
|
-
var PipelineError = class extends Error {
|
|
402
|
-
constructor(message, cause) {
|
|
403
|
-
super(message);
|
|
404
|
-
this.cause = cause;
|
|
405
|
-
this.name = this.constructor.name;
|
|
406
|
-
if (cause?.stack) {
|
|
407
|
-
this.stack = `${this.stack}
|
|
408
|
-
Caused by: ${cause.stack}`;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
|
-
var PipelineStateError = class extends PipelineError {
|
|
413
|
-
};
|
|
414
|
-
var CancellationError = class extends PipelineError {
|
|
415
|
-
constructor(message = "Operation cancelled") {
|
|
416
|
-
super(message);
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
|
|
420
290
|
// src/scraper/processor/HtmlProcessor.ts
|
|
421
291
|
import createDOMPurify from "dompurify";
|
|
422
292
|
import { JSDOM } from "jsdom";
|
|
@@ -439,7 +309,7 @@ var HtmlProcessor = class {
|
|
|
439
309
|
"input",
|
|
440
310
|
"textarea",
|
|
441
311
|
"select",
|
|
442
|
-
"form",
|
|
312
|
+
// "form", // Known issue: Some pages use alerts for important content
|
|
443
313
|
".ads",
|
|
444
314
|
".advertisement",
|
|
445
315
|
".banner",
|
|
@@ -472,18 +342,16 @@ var HtmlProcessor = class {
|
|
|
472
342
|
".signup-form",
|
|
473
343
|
".tooltip",
|
|
474
344
|
".dropdown-menu",
|
|
475
|
-
".alert",
|
|
345
|
+
// ".alert", // Known issue: Some pages use alerts for important content
|
|
476
346
|
".breadcrumb",
|
|
477
347
|
".pagination",
|
|
478
|
-
'[role="alert"]',
|
|
348
|
+
// '[role="alert"]', // Known issue: Some pages use alerts for important content
|
|
479
349
|
'[role="banner"]',
|
|
480
350
|
'[role="dialog"]',
|
|
481
351
|
'[role="alertdialog"]',
|
|
482
352
|
'[role="region"][aria-label*="skip" i]',
|
|
483
353
|
'[aria-modal="true"]',
|
|
484
|
-
".noprint"
|
|
485
|
-
"figure",
|
|
486
|
-
"sup"
|
|
354
|
+
".noprint"
|
|
487
355
|
];
|
|
488
356
|
constructor(options) {
|
|
489
357
|
this.turndownService = new TurndownService({
|
|
@@ -514,9 +382,17 @@ var HtmlProcessor = class {
|
|
|
514
382
|
}
|
|
515
383
|
}
|
|
516
384
|
}
|
|
385
|
+
const text3 = (() => {
|
|
386
|
+
const clone = element.cloneNode(true);
|
|
387
|
+
const brElements = Array.from(clone.querySelectorAll("br"));
|
|
388
|
+
for (const br of brElements) {
|
|
389
|
+
br.replaceWith("\n");
|
|
390
|
+
}
|
|
391
|
+
return clone.textContent;
|
|
392
|
+
})();
|
|
517
393
|
return `
|
|
518
394
|
\`\`\`${language}
|
|
519
|
-
${
|
|
395
|
+
${text3}
|
|
520
396
|
\`\`\`
|
|
521
397
|
`;
|
|
522
398
|
}
|
|
@@ -622,6 +498,136 @@ var MarkdownProcessor = class {
|
|
|
622
498
|
}
|
|
623
499
|
};
|
|
624
500
|
|
|
501
|
+
// node_modules/uuid/dist/esm-node/stringify.js
|
|
502
|
+
var byteToHex = [];
|
|
503
|
+
for (let i = 0; i < 256; ++i) {
|
|
504
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
505
|
+
}
|
|
506
|
+
function unsafeStringify(arr, offset = 0) {
|
|
507
|
+
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// node_modules/uuid/dist/esm-node/rng.js
|
|
511
|
+
import crypto from "node:crypto";
|
|
512
|
+
var rnds8Pool = new Uint8Array(256);
|
|
513
|
+
var poolPtr = rnds8Pool.length;
|
|
514
|
+
function rng() {
|
|
515
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
516
|
+
crypto.randomFillSync(rnds8Pool);
|
|
517
|
+
poolPtr = 0;
|
|
518
|
+
}
|
|
519
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// node_modules/uuid/dist/esm-node/native.js
|
|
523
|
+
import crypto2 from "node:crypto";
|
|
524
|
+
var native_default = {
|
|
525
|
+
randomUUID: crypto2.randomUUID
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
// node_modules/uuid/dist/esm-node/v4.js
|
|
529
|
+
function v4(options, buf, offset) {
|
|
530
|
+
if (native_default.randomUUID && !buf && !options) {
|
|
531
|
+
return native_default.randomUUID();
|
|
532
|
+
}
|
|
533
|
+
options = options || {};
|
|
534
|
+
const rnds = options.random || (options.rng || rng)();
|
|
535
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
536
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
537
|
+
if (buf) {
|
|
538
|
+
offset = offset || 0;
|
|
539
|
+
for (let i = 0; i < 16; ++i) {
|
|
540
|
+
buf[offset + i] = rnds[i];
|
|
541
|
+
}
|
|
542
|
+
return buf;
|
|
543
|
+
}
|
|
544
|
+
return unsafeStringify(rnds);
|
|
545
|
+
}
|
|
546
|
+
var v4_default = v4;
|
|
547
|
+
|
|
548
|
+
// src/utils/url.ts
|
|
549
|
+
import psl from "psl";
|
|
550
|
+
var defaultNormalizerOptions = {
|
|
551
|
+
ignoreCase: true,
|
|
552
|
+
removeHash: true,
|
|
553
|
+
removeTrailingSlash: true,
|
|
554
|
+
removeQuery: false,
|
|
555
|
+
removeIndex: true
|
|
556
|
+
};
|
|
557
|
+
function normalizeUrl(url, options = defaultNormalizerOptions) {
|
|
558
|
+
try {
|
|
559
|
+
const parsedUrl = new URL(url);
|
|
560
|
+
const finalOptions = { ...defaultNormalizerOptions, ...options };
|
|
561
|
+
const normalized = new URL(parsedUrl.origin + parsedUrl.pathname);
|
|
562
|
+
if (finalOptions.removeIndex) {
|
|
563
|
+
normalized.pathname = normalized.pathname.replace(
|
|
564
|
+
/\/index\.(html|htm|asp|php|jsp)$/i,
|
|
565
|
+
"/"
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
if (finalOptions.removeTrailingSlash && normalized.pathname.length > 1) {
|
|
569
|
+
normalized.pathname = normalized.pathname.replace(/\/+$/, "");
|
|
570
|
+
}
|
|
571
|
+
const preservedHash = !finalOptions.removeHash ? parsedUrl.hash : "";
|
|
572
|
+
const preservedSearch = !finalOptions.removeQuery ? parsedUrl.search : "";
|
|
573
|
+
let result = normalized.origin + normalized.pathname;
|
|
574
|
+
if (preservedSearch) {
|
|
575
|
+
result += preservedSearch;
|
|
576
|
+
}
|
|
577
|
+
if (preservedHash) {
|
|
578
|
+
result += preservedHash;
|
|
579
|
+
}
|
|
580
|
+
if (finalOptions.ignoreCase) {
|
|
581
|
+
result = result.toLowerCase();
|
|
582
|
+
}
|
|
583
|
+
return result;
|
|
584
|
+
} catch {
|
|
585
|
+
return url;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
function validateUrl(url) {
|
|
589
|
+
try {
|
|
590
|
+
new URL(url);
|
|
591
|
+
} catch (error) {
|
|
592
|
+
throw new InvalidUrlError(url, error instanceof Error ? error : void 0);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
function hasSameHostname(urlA, urlB) {
|
|
596
|
+
return urlA.hostname.toLowerCase() === urlB.hostname.toLowerCase();
|
|
597
|
+
}
|
|
598
|
+
function hasSameDomain(urlA, urlB) {
|
|
599
|
+
const domainA = psl.get(urlA.hostname.toLowerCase());
|
|
600
|
+
const domainB = psl.get(urlB.hostname.toLowerCase());
|
|
601
|
+
return domainA !== null && domainA === domainB;
|
|
602
|
+
}
|
|
603
|
+
function isSubpath(baseUrl, targetUrl) {
|
|
604
|
+
const basePath = baseUrl.pathname.endsWith("/") ? baseUrl.pathname : `${baseUrl.pathname}/`;
|
|
605
|
+
return targetUrl.pathname.startsWith(basePath);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// src/scraper/strategies/BaseScraperStrategy.ts
|
|
609
|
+
import { URL as URL2 } from "node:url";
|
|
610
|
+
|
|
611
|
+
// src/pipeline/errors.ts
|
|
612
|
+
var PipelineError = class extends Error {
|
|
613
|
+
constructor(message, cause) {
|
|
614
|
+
super(message);
|
|
615
|
+
this.cause = cause;
|
|
616
|
+
this.name = this.constructor.name;
|
|
617
|
+
if (cause?.stack) {
|
|
618
|
+
this.stack = `${this.stack}
|
|
619
|
+
Caused by: ${cause.stack}`;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
var PipelineStateError = class extends PipelineError {
|
|
624
|
+
};
|
|
625
|
+
var CancellationError = class extends PipelineError {
|
|
626
|
+
constructor(message = "Operation cancelled") {
|
|
627
|
+
super(message);
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
|
|
625
631
|
// src/scraper/strategies/BaseScraperStrategy.ts
|
|
626
632
|
var DEFAULT_MAX_PAGES = 100;
|
|
627
633
|
var DEFAULT_MAX_DEPTH = 3;
|
|
@@ -1315,57 +1321,54 @@ var LibraryNotFoundError = class extends ToolError {
|
|
|
1315
1321
|
}
|
|
1316
1322
|
};
|
|
1317
1323
|
|
|
1318
|
-
// src/tools/
|
|
1319
|
-
var
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
this.
|
|
1324
|
+
// src/tools/FetchUrlTool.ts
|
|
1325
|
+
var FetchUrlTool = class {
|
|
1326
|
+
constructor(httpFetcher, fileFetcher, processor) {
|
|
1327
|
+
this.processor = processor;
|
|
1328
|
+
this.fetchers = [httpFetcher, fileFetcher];
|
|
1323
1329
|
}
|
|
1330
|
+
/**
|
|
1331
|
+
* Collection of fetchers that will be tried in order for a given URL.
|
|
1332
|
+
*/
|
|
1333
|
+
fetchers;
|
|
1334
|
+
/**
|
|
1335
|
+
* Fetches content from a URL and converts it to Markdown.
|
|
1336
|
+
* Supports both HTTP/HTTPS URLs and local file URLs (file://).
|
|
1337
|
+
* @returns The processed Markdown content
|
|
1338
|
+
* @throws {ToolError} If fetching or processing fails
|
|
1339
|
+
*/
|
|
1324
1340
|
async execute(options) {
|
|
1325
|
-
const {
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
)
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
if (!exactMatch) {
|
|
1333
|
-
const versionResult = await this.docService.findBestVersion(library, version);
|
|
1334
|
-
versionToSearch = versionResult.bestMatch;
|
|
1335
|
-
}
|
|
1336
|
-
const results = await this.docService.searchStore(
|
|
1337
|
-
library,
|
|
1338
|
-
versionToSearch,
|
|
1339
|
-
query,
|
|
1340
|
-
limit
|
|
1341
|
+
const { url } = options;
|
|
1342
|
+
const canFetchResults = this.fetchers.map((f) => f.canFetch(url));
|
|
1343
|
+
const fetcherIndex = canFetchResults.findIndex((result) => result === true);
|
|
1344
|
+
if (fetcherIndex === -1) {
|
|
1345
|
+
throw new ToolError(
|
|
1346
|
+
`Invalid URL: ${url}. Must be an HTTP/HTTPS URL or a file:// URL.`,
|
|
1347
|
+
this.constructor.name
|
|
1341
1348
|
);
|
|
1342
|
-
|
|
1343
|
-
|
|
1349
|
+
}
|
|
1350
|
+
const fetcher = this.fetchers[fetcherIndex];
|
|
1351
|
+
try {
|
|
1352
|
+
logger.info(`\u{1F4E1} Fetching ${url}...`);
|
|
1353
|
+
const rawContent = await fetcher.fetch(url, {
|
|
1354
|
+
followRedirects: options.followRedirects ?? true,
|
|
1355
|
+
maxRetries: 3
|
|
1356
|
+
});
|
|
1357
|
+
logger.info("\u{1F504} Converting to Markdown...");
|
|
1358
|
+
const processed = await this.processor.process(rawContent);
|
|
1359
|
+
logger.info(`\u2705 Successfully converted ${url} to Markdown`);
|
|
1360
|
+
return processed.content;
|
|
1344
1361
|
} catch (error) {
|
|
1345
|
-
if (error instanceof
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
message: error.message,
|
|
1351
|
-
suggestions: error.suggestions
|
|
1352
|
-
}
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
|
-
if (error instanceof VersionNotFoundError) {
|
|
1356
|
-
logger.info(`\u2139\uFE0F Version not found: ${error.message}`);
|
|
1357
|
-
return {
|
|
1358
|
-
results: [],
|
|
1359
|
-
error: {
|
|
1360
|
-
message: error.message,
|
|
1361
|
-
availableVersions: error.availableVersions
|
|
1362
|
-
}
|
|
1363
|
-
};
|
|
1362
|
+
if (error instanceof ScraperError) {
|
|
1363
|
+
throw new ToolError(
|
|
1364
|
+
`Failed to fetch or process URL: ${error.message}`,
|
|
1365
|
+
this.constructor.name
|
|
1366
|
+
);
|
|
1364
1367
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1368
|
+
throw new ToolError(
|
|
1369
|
+
`Failed to fetch or process URL: ${error instanceof Error ? error.message : String(error)}`,
|
|
1370
|
+
this.constructor.name
|
|
1367
1371
|
);
|
|
1368
|
-
throw error;
|
|
1369
1372
|
}
|
|
1370
1373
|
}
|
|
1371
1374
|
};
|
|
@@ -1531,72 +1534,69 @@ var ScrapeTool = class {
|
|
|
1531
1534
|
}
|
|
1532
1535
|
};
|
|
1533
1536
|
|
|
1534
|
-
// src/tools/
|
|
1535
|
-
var
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
* Creates an instance of ListJobsTool.
|
|
1540
|
-
* @param manager The PipelineManager instance.
|
|
1541
|
-
*/
|
|
1542
|
-
constructor(manager) {
|
|
1543
|
-
this.manager = manager;
|
|
1537
|
+
// src/tools/SearchTool.ts
|
|
1538
|
+
var SearchTool = class {
|
|
1539
|
+
docService;
|
|
1540
|
+
constructor(docService) {
|
|
1541
|
+
this.docService = docService;
|
|
1544
1542
|
}
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
startedAt: job.startedAt?.toISOString() ?? null,
|
|
1561
|
-
finishedAt: job.finishedAt?.toISOString() ?? null,
|
|
1562
|
-
error: job.error?.message ?? null
|
|
1563
|
-
})
|
|
1543
|
+
async execute(options) {
|
|
1544
|
+
const { library, version, query, limit = 5, exactMatch = false } = options;
|
|
1545
|
+
if (exactMatch && (!version || version === "latest")) {
|
|
1546
|
+
await this.docService.validateLibraryExists(library);
|
|
1547
|
+
const versions = await this.docService.listVersions(library);
|
|
1548
|
+
throw new VersionNotFoundError(
|
|
1549
|
+
library,
|
|
1550
|
+
"latest",
|
|
1551
|
+
versions
|
|
1552
|
+
// versions already has the correct { version: string, indexed: boolean } format
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
const resolvedVersion = version || "latest";
|
|
1556
|
+
logger.info(
|
|
1557
|
+
`\u{1F50D} Searching ${library}@${resolvedVersion} for: ${query}${exactMatch ? " (exact match)" : ""}`
|
|
1564
1558
|
);
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1559
|
+
try {
|
|
1560
|
+
await this.docService.validateLibraryExists(library);
|
|
1561
|
+
let versionToSearch = resolvedVersion;
|
|
1562
|
+
if (!exactMatch) {
|
|
1563
|
+
const versionResult = await this.docService.findBestVersion(library, version);
|
|
1564
|
+
versionToSearch = versionResult.bestMatch;
|
|
1565
|
+
}
|
|
1566
|
+
const results = await this.docService.searchStore(
|
|
1567
|
+
library,
|
|
1568
|
+
versionToSearch,
|
|
1569
|
+
query,
|
|
1570
|
+
limit
|
|
1571
|
+
);
|
|
1572
|
+
logger.info(`\u2705 Found ${results.length} matching results`);
|
|
1573
|
+
return { results };
|
|
1574
|
+
} catch (error) {
|
|
1575
|
+
if (error instanceof LibraryNotFoundError) {
|
|
1576
|
+
logger.info(`\u2139\uFE0F Library not found: ${error.message}`);
|
|
1577
|
+
return {
|
|
1578
|
+
results: [],
|
|
1579
|
+
error: {
|
|
1580
|
+
message: error.message,
|
|
1581
|
+
suggestions: error.suggestions
|
|
1582
|
+
}
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1585
|
+
if (error instanceof VersionNotFoundError) {
|
|
1586
|
+
logger.info(`\u2139\uFE0F Version not found: ${error.message}`);
|
|
1587
|
+
return {
|
|
1588
|
+
results: [],
|
|
1589
|
+
error: {
|
|
1590
|
+
message: error.message,
|
|
1591
|
+
availableVersions: error.availableVersions
|
|
1592
|
+
}
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
logger.error(
|
|
1596
|
+
`\u274C Search failed: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1597
|
+
);
|
|
1598
|
+
throw error;
|
|
1588
1599
|
}
|
|
1589
|
-
const jobInfo = {
|
|
1590
|
-
id: job.id,
|
|
1591
|
-
library: job.library,
|
|
1592
|
-
version: job.version,
|
|
1593
|
-
status: job.status,
|
|
1594
|
-
createdAt: job.createdAt.toISOString(),
|
|
1595
|
-
startedAt: job.startedAt?.toISOString() ?? null,
|
|
1596
|
-
finishedAt: job.finishedAt?.toISOString() ?? null,
|
|
1597
|
-
error: job.error?.message ?? null
|
|
1598
|
-
};
|
|
1599
|
-
return { job: jobInfo };
|
|
1600
1600
|
}
|
|
1601
1601
|
};
|
|
1602
1602
|
|
|
@@ -1657,6 +1657,75 @@ var CancelJobTool = class {
|
|
|
1657
1657
|
}
|
|
1658
1658
|
};
|
|
1659
1659
|
|
|
1660
|
+
// src/tools/GetJobInfoTool.ts
|
|
1661
|
+
var GetJobInfoTool = class {
|
|
1662
|
+
manager;
|
|
1663
|
+
/**
|
|
1664
|
+
* Creates an instance of GetJobInfoTool.
|
|
1665
|
+
* @param manager The PipelineManager instance.
|
|
1666
|
+
*/
|
|
1667
|
+
constructor(manager) {
|
|
1668
|
+
this.manager = manager;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Executes the tool to retrieve simplified info for a specific job.
|
|
1672
|
+
* @param input - The input parameters, containing the jobId.
|
|
1673
|
+
* @returns A promise that resolves with the simplified job info or null if not found.
|
|
1674
|
+
*/
|
|
1675
|
+
async execute(input) {
|
|
1676
|
+
const job = await this.manager.getJob(input.jobId);
|
|
1677
|
+
if (!job) {
|
|
1678
|
+
return { job: null };
|
|
1679
|
+
}
|
|
1680
|
+
const jobInfo = {
|
|
1681
|
+
id: job.id,
|
|
1682
|
+
library: job.library,
|
|
1683
|
+
version: job.version,
|
|
1684
|
+
status: job.status,
|
|
1685
|
+
createdAt: job.createdAt.toISOString(),
|
|
1686
|
+
startedAt: job.startedAt?.toISOString() ?? null,
|
|
1687
|
+
finishedAt: job.finishedAt?.toISOString() ?? null,
|
|
1688
|
+
error: job.error?.message ?? null
|
|
1689
|
+
};
|
|
1690
|
+
return { job: jobInfo };
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1693
|
+
|
|
1694
|
+
// src/tools/ListJobsTool.ts
|
|
1695
|
+
var ListJobsTool = class {
|
|
1696
|
+
manager;
|
|
1697
|
+
// Change property name and type
|
|
1698
|
+
/**
|
|
1699
|
+
* Creates an instance of ListJobsTool.
|
|
1700
|
+
* @param manager The PipelineManager instance.
|
|
1701
|
+
*/
|
|
1702
|
+
constructor(manager) {
|
|
1703
|
+
this.manager = manager;
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Executes the tool to retrieve a list of pipeline jobs.
|
|
1707
|
+
* @param input - The input parameters, optionally including a status filter.
|
|
1708
|
+
* @returns A promise that resolves with the list of simplified job objects.
|
|
1709
|
+
* @throws {PipelineStateError} If the pipeline manager is somehow unavailable.
|
|
1710
|
+
*/
|
|
1711
|
+
async execute(input) {
|
|
1712
|
+
const jobs = await this.manager.getJobs(input.status);
|
|
1713
|
+
const simplifiedJobs = jobs.map(
|
|
1714
|
+
(job) => ({
|
|
1715
|
+
id: job.id,
|
|
1716
|
+
library: job.library,
|
|
1717
|
+
version: job.version,
|
|
1718
|
+
status: job.status,
|
|
1719
|
+
createdAt: job.createdAt.toISOString(),
|
|
1720
|
+
startedAt: job.startedAt?.toISOString() ?? null,
|
|
1721
|
+
finishedAt: job.finishedAt?.toISOString() ?? null,
|
|
1722
|
+
error: job.error?.message ?? null
|
|
1723
|
+
})
|
|
1724
|
+
);
|
|
1725
|
+
return { jobs: simplifiedJobs };
|
|
1726
|
+
}
|
|
1727
|
+
};
|
|
1728
|
+
|
|
1660
1729
|
// src/tools/RemoveTool.ts
|
|
1661
1730
|
var RemoveToolInputSchema = {
|
|
1662
1731
|
type: "object",
|
|
@@ -11269,7 +11338,8 @@ var DocumentManagementService = class {
|
|
|
11269
11338
|
dbPath = path3.join(dbDir, "documents.db");
|
|
11270
11339
|
logger.debug(`\u{1F4BE} Using database directory from DOCS_MCP_STORE_PATH: ${dbDir}`);
|
|
11271
11340
|
} else {
|
|
11272
|
-
const
|
|
11341
|
+
const projectRoot = path3.resolve(import.meta.dirname, "..");
|
|
11342
|
+
const oldDbDir = path3.join(projectRoot, ".store");
|
|
11273
11343
|
const oldDbPath = path3.join(oldDbDir, "documents.db");
|
|
11274
11344
|
const oldDbExists = existsSync(oldDbPath);
|
|
11275
11345
|
if (oldDbExists) {
|
|
@@ -11498,17 +11568,21 @@ var DocumentManagementService = class {
|
|
|
11498
11568
|
export {
|
|
11499
11569
|
setLogLevel,
|
|
11500
11570
|
logger,
|
|
11571
|
+
HttpFetcher,
|
|
11572
|
+
FileFetcher,
|
|
11573
|
+
HtmlProcessor,
|
|
11501
11574
|
PipelineJobStatus,
|
|
11502
11575
|
PipelineManager,
|
|
11576
|
+
CancelJobTool,
|
|
11503
11577
|
VersionNotFoundError,
|
|
11504
|
-
|
|
11578
|
+
FetchUrlTool,
|
|
11505
11579
|
FindVersionTool,
|
|
11506
|
-
ListLibrariesTool,
|
|
11507
|
-
ScrapeTool,
|
|
11508
|
-
ListJobsTool,
|
|
11509
11580
|
GetJobInfoTool,
|
|
11510
|
-
|
|
11581
|
+
ListJobsTool,
|
|
11582
|
+
ListLibrariesTool,
|
|
11511
11583
|
RemoveTool,
|
|
11584
|
+
ScrapeTool,
|
|
11585
|
+
SearchTool,
|
|
11512
11586
|
DocumentManagementService
|
|
11513
11587
|
};
|
|
11514
|
-
//# sourceMappingURL=chunk-
|
|
11588
|
+
//# sourceMappingURL=chunk-ADZQJG2M.js.map
|