@arabold/docs-mcp-server 1.30.0 → 1.31.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/assets/main.css +1 -1
- package/dist/index.js +505 -184
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/main.css +1 -1
package/dist/index.js
CHANGED
|
@@ -1579,7 +1579,7 @@ function createMcpServerInstance(tools, readOnly = false) {
|
|
|
1579
1579
|
"Re-scrape a previously indexed library version, updating only changed pages.",
|
|
1580
1580
|
{
|
|
1581
1581
|
library: z.string().trim().describe("Library name."),
|
|
1582
|
-
version: z.string().trim().optional().describe("Library version (optional, refreshes
|
|
1582
|
+
version: z.string().trim().optional().describe("Library version (optional, refreshes latest if omitted).")
|
|
1583
1583
|
},
|
|
1584
1584
|
{
|
|
1585
1585
|
title: "Refresh Library Version",
|
|
@@ -1833,7 +1833,7 @@ ${formattedJob}`);
|
|
|
1833
1833
|
"Remove indexed documentation for a library version. Use only if explicitly instructed.",
|
|
1834
1834
|
{
|
|
1835
1835
|
library: z.string().trim().describe("Library name."),
|
|
1836
|
-
version: z.string().trim().optional().describe("Library version (optional, removes
|
|
1836
|
+
version: z.string().trim().optional().describe("Library version (optional, removes latest if omitted).")
|
|
1837
1837
|
},
|
|
1838
1838
|
{
|
|
1839
1839
|
title: "Remove Library Documentation",
|
|
@@ -7180,6 +7180,24 @@ let PipelineFactory$1 = class PipelineFactory {
|
|
|
7180
7180
|
];
|
|
7181
7181
|
}
|
|
7182
7182
|
};
|
|
7183
|
+
function compareVersionsDescending(a, b) {
|
|
7184
|
+
const aIsUnversioned = a === "" || a === null || a === void 0;
|
|
7185
|
+
const bIsUnversioned = b === "" || b === null || b === void 0;
|
|
7186
|
+
if (aIsUnversioned && bIsUnversioned) return 0;
|
|
7187
|
+
if (aIsUnversioned) return -1;
|
|
7188
|
+
if (bIsUnversioned) return 1;
|
|
7189
|
+
const aSemver = semver__default.valid(a) ?? semver__default.valid(semver__default.coerce(a));
|
|
7190
|
+
const bSemver = semver__default.valid(b) ?? semver__default.valid(semver__default.coerce(b));
|
|
7191
|
+
if (aSemver && bSemver) {
|
|
7192
|
+
return semver__default.rcompare(aSemver, bSemver);
|
|
7193
|
+
}
|
|
7194
|
+
const aLower = a.toLowerCase();
|
|
7195
|
+
const bLower = b.toLowerCase();
|
|
7196
|
+
return bLower.localeCompare(aLower);
|
|
7197
|
+
}
|
|
7198
|
+
function sortVersionsDescending(versions) {
|
|
7199
|
+
return [...versions].sort(compareVersionsDescending);
|
|
7200
|
+
}
|
|
7183
7201
|
class HierarchicalAssemblyStrategy {
|
|
7184
7202
|
/**
|
|
7185
7203
|
* Determines if this strategy can handle the given content type.
|
|
@@ -8887,22 +8905,7 @@ class DocumentStore {
|
|
|
8887
8905
|
});
|
|
8888
8906
|
}
|
|
8889
8907
|
for (const versions of libraryMap.values()) {
|
|
8890
|
-
versions.sort((a, b) =>
|
|
8891
|
-
if (a.version === "" && b.version !== "") {
|
|
8892
|
-
return -1;
|
|
8893
|
-
}
|
|
8894
|
-
if (a.version !== "" && b.version === "") {
|
|
8895
|
-
return 1;
|
|
8896
|
-
}
|
|
8897
|
-
if (a.version === "" && b.version === "") {
|
|
8898
|
-
return 0;
|
|
8899
|
-
}
|
|
8900
|
-
try {
|
|
8901
|
-
return semver__default.compare(a.version, b.version);
|
|
8902
|
-
} catch (_error) {
|
|
8903
|
-
return a.version.localeCompare(b.version);
|
|
8904
|
-
}
|
|
8905
|
-
});
|
|
8908
|
+
versions.sort((a, b) => compareVersionsDescending(a.version, b.version));
|
|
8906
8909
|
}
|
|
8907
8910
|
return libraryMap;
|
|
8908
8911
|
} catch (error) {
|
|
@@ -9680,10 +9683,12 @@ class DocumentManagementService {
|
|
|
9680
9683
|
}
|
|
9681
9684
|
/**
|
|
9682
9685
|
* Returns a list of all available semantic versions for a library.
|
|
9686
|
+
* Sorted in descending order (latest first).
|
|
9683
9687
|
*/
|
|
9684
9688
|
async listVersions(library) {
|
|
9685
9689
|
const versions = await this.store.queryUniqueVersions(library);
|
|
9686
|
-
|
|
9690
|
+
const validVersions = versions.filter((v) => semver__default.valid(v));
|
|
9691
|
+
return sortVersionsDescending(validVersions);
|
|
9687
9692
|
}
|
|
9688
9693
|
/**
|
|
9689
9694
|
* Checks if documents exist for a given library and optional version.
|
|
@@ -9761,7 +9766,7 @@ class DocumentManagementService {
|
|
|
9761
9766
|
async removeAllDocuments(library, version) {
|
|
9762
9767
|
const normalizedVersion = this.normalizeVersion(version);
|
|
9763
9768
|
logger.info(
|
|
9764
|
-
`🗑️ Removing all documents from ${library}@${normalizedVersion || "
|
|
9769
|
+
`🗑️ Removing all documents from ${library}@${normalizedVersion || "latest"} store`
|
|
9765
9770
|
);
|
|
9766
9771
|
const count = await this.store.deletePages(library, normalizedVersion);
|
|
9767
9772
|
logger.info(`🗑️ Deleted ${count} documents`);
|
|
@@ -9792,17 +9797,15 @@ class DocumentManagementService {
|
|
|
9792
9797
|
*/
|
|
9793
9798
|
async removeVersion(library, version) {
|
|
9794
9799
|
const normalizedVersion = this.normalizeVersion(version);
|
|
9795
|
-
logger.debug(`Removing version: ${library}@${normalizedVersion || "
|
|
9800
|
+
logger.debug(`Removing version: ${library}@${normalizedVersion || "latest"}`);
|
|
9796
9801
|
const result = await this.store.removeVersion(library, normalizedVersion, true);
|
|
9797
9802
|
logger.info(`🗑️ Removed ${result.documentsDeleted} documents`);
|
|
9798
9803
|
if (result.versionDeleted && result.libraryDeleted) {
|
|
9799
9804
|
logger.info(`🗑️ Completely removed library ${library} (was last version)`);
|
|
9800
9805
|
} else if (result.versionDeleted) {
|
|
9801
|
-
logger.info(`🗑️ Removed version ${library}@${normalizedVersion || "
|
|
9806
|
+
logger.info(`🗑️ Removed version ${library}@${normalizedVersion || "latest"}`);
|
|
9802
9807
|
} else {
|
|
9803
|
-
logger.warn(
|
|
9804
|
-
`⚠️ Version ${library}@${normalizedVersion || "[no version]"} not found`
|
|
9805
|
-
);
|
|
9808
|
+
logger.warn(`⚠️ Version ${library}@${normalizedVersion || "latest"} not found`);
|
|
9806
9809
|
const libraryRecord = await this.store.getLibrary(library);
|
|
9807
9810
|
if (libraryRecord) {
|
|
9808
9811
|
const versions = await this.store.queryUniqueVersions(library);
|
|
@@ -10538,6 +10541,29 @@ function registerEventsRoute(server, eventBus) {
|
|
|
10538
10541
|
});
|
|
10539
10542
|
});
|
|
10540
10543
|
}
|
|
10544
|
+
const PrimaryButton = ({
|
|
10545
|
+
children,
|
|
10546
|
+
type = "button",
|
|
10547
|
+
class: className = "",
|
|
10548
|
+
disabled = false,
|
|
10549
|
+
...rest
|
|
10550
|
+
}) => {
|
|
10551
|
+
const baseClasses = "w-full flex justify-center py-1.5 px-3 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors duration-150";
|
|
10552
|
+
const disabledClasses = disabled ? "opacity-50 cursor-not-allowed" : "";
|
|
10553
|
+
const combinedClasses = `${baseClasses} ${disabledClasses} ${className}`.trim();
|
|
10554
|
+
return /* @__PURE__ */ jsx("button", { type, class: combinedClasses, disabled, ...rest, children });
|
|
10555
|
+
};
|
|
10556
|
+
const AddJobButton = () => {
|
|
10557
|
+
return /* @__PURE__ */ jsx(
|
|
10558
|
+
PrimaryButton,
|
|
10559
|
+
{
|
|
10560
|
+
"hx-get": "/web/jobs/new",
|
|
10561
|
+
"hx-target": "#addJobForm",
|
|
10562
|
+
"hx-swap": "innerHTML",
|
|
10563
|
+
children: "Add New Documentation"
|
|
10564
|
+
}
|
|
10565
|
+
);
|
|
10566
|
+
};
|
|
10541
10567
|
const Toast = () => {
|
|
10542
10568
|
return /* @__PURE__ */ jsx(
|
|
10543
10569
|
"div",
|
|
@@ -10666,7 +10692,7 @@ const Layout = ({
|
|
|
10666
10692
|
children,
|
|
10667
10693
|
eventClientConfig
|
|
10668
10694
|
}) => {
|
|
10669
|
-
const versionString = version || "1.
|
|
10695
|
+
const versionString = version || "1.31.0";
|
|
10670
10696
|
const versionInitializer = `versionUpdate({ currentVersion: ${`'${versionString}'`} })`;
|
|
10671
10697
|
return /* @__PURE__ */ jsxs("html", { lang: "en", children: [
|
|
10672
10698
|
/* @__PURE__ */ jsxs("head", { children: [
|
|
@@ -11014,17 +11040,7 @@ function registerIndexRoute(server, config) {
|
|
|
11014
11040
|
}
|
|
11015
11041
|
)
|
|
11016
11042
|
] }),
|
|
11017
|
-
/* @__PURE__ */ jsx("section", { class: "mb-8", children: /* @__PURE__ */ jsx("div", { id: "addJobForm", children: /* @__PURE__ */ jsx(
|
|
11018
|
-
"button",
|
|
11019
|
-
{
|
|
11020
|
-
type: "button",
|
|
11021
|
-
"hx-get": "/web/jobs/new",
|
|
11022
|
-
"hx-target": "#addJobForm",
|
|
11023
|
-
"hx-swap": "innerHTML",
|
|
11024
|
-
class: "w-full flex justify-center py-1.5 px-3 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors duration-150",
|
|
11025
|
-
children: "Add New Documentation"
|
|
11026
|
-
}
|
|
11027
|
-
) }) }),
|
|
11043
|
+
/* @__PURE__ */ jsx("section", { class: "mb-8", children: /* @__PURE__ */ jsx("div", { id: "addJobForm", children: /* @__PURE__ */ jsx(AddJobButton, {}) }) }),
|
|
11028
11044
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
11029
11045
|
/* @__PURE__ */ jsx("h2", { class: "text-xl font-semibold mb-2 text-gray-900 dark:text-white", children: "Indexed Documentation" }),
|
|
11030
11046
|
/* @__PURE__ */ jsx(
|
|
@@ -11155,10 +11171,12 @@ const ProgressBar = ({ progress, showText = true }) => {
|
|
|
11155
11171
|
) })
|
|
11156
11172
|
] });
|
|
11157
11173
|
};
|
|
11158
|
-
const LoadingSpinner = (
|
|
11174
|
+
const LoadingSpinner = ({
|
|
11175
|
+
class: className = "text-white"
|
|
11176
|
+
}) => /* @__PURE__ */ jsxs(
|
|
11159
11177
|
"svg",
|
|
11160
11178
|
{
|
|
11161
|
-
class:
|
|
11179
|
+
class: `animate-spin h-4 w-4 ${className}`,
|
|
11162
11180
|
xmlns: "http://www.w3.org/2000/svg",
|
|
11163
11181
|
fill: "none",
|
|
11164
11182
|
viewBox: "0 0 24 24",
|
|
@@ -11293,6 +11311,17 @@ function registerJobListRoutes(server, listJobsTool) {
|
|
|
11293
11311
|
return /* @__PURE__ */ jsx(JobList, { jobs: result.jobs });
|
|
11294
11312
|
});
|
|
11295
11313
|
}
|
|
11314
|
+
const AddVersionButton = ({ libraryName }) => {
|
|
11315
|
+
return /* @__PURE__ */ jsx(
|
|
11316
|
+
PrimaryButton,
|
|
11317
|
+
{
|
|
11318
|
+
"hx-get": `/web/libraries/${encodeURIComponent(libraryName)}/add-version-form`,
|
|
11319
|
+
"hx-target": "#add-version-form-container",
|
|
11320
|
+
"hx-swap": "innerHTML",
|
|
11321
|
+
children: "Add New Version"
|
|
11322
|
+
}
|
|
11323
|
+
);
|
|
11324
|
+
};
|
|
11296
11325
|
const Alert = ({ type, title, message }) => {
|
|
11297
11326
|
let iconSvg;
|
|
11298
11327
|
let colorClasses;
|
|
@@ -11437,17 +11466,39 @@ const Tooltip = ({ text, position = "top" }) => {
|
|
|
11437
11466
|
);
|
|
11438
11467
|
};
|
|
11439
11468
|
const ScrapeFormContent = ({
|
|
11440
|
-
defaultExcludePatterns
|
|
11469
|
+
defaultExcludePatterns,
|
|
11470
|
+
initialValues,
|
|
11471
|
+
mode = "new"
|
|
11441
11472
|
}) => {
|
|
11442
|
-
const
|
|
11473
|
+
const isAddVersionMode = mode === "add-version";
|
|
11474
|
+
const urlValue = initialValues?.url || "";
|
|
11475
|
+
const libraryValue = initialValues?.library || "";
|
|
11476
|
+
const maxPagesValue = initialValues?.maxPages?.toString() || "";
|
|
11477
|
+
const maxDepthValue = initialValues?.maxDepth?.toString() || "";
|
|
11478
|
+
const scopeValue = initialValues?.scope || "subpages";
|
|
11479
|
+
const includePatternsValue = initialValues?.includePatterns || "";
|
|
11480
|
+
const scrapeModeValue = initialValues?.scrapeMode || ScrapeMode.Auto;
|
|
11481
|
+
const followRedirectsValue = initialValues?.followRedirects ?? true;
|
|
11482
|
+
const ignoreErrorsValue = initialValues?.ignoreErrors ?? true;
|
|
11483
|
+
const excludePatternsText = initialValues?.excludePatterns !== void 0 ? initialValues.excludePatterns : defaultExcludePatterns?.join("\n") || "";
|
|
11484
|
+
const headersJson = JSON.stringify(initialValues?.headers || []);
|
|
11485
|
+
const closeButtonAttrs = isAddVersionMode ? {
|
|
11486
|
+
"hx-get": `/web/libraries/${encodeURIComponent(libraryValue)}/add-version-button`,
|
|
11487
|
+
"hx-target": "#add-version-form-container",
|
|
11488
|
+
"hx-swap": "innerHTML"
|
|
11489
|
+
} : {
|
|
11490
|
+
"hx-get": "/web/jobs/new-button",
|
|
11491
|
+
"hx-target": "#addJobForm",
|
|
11492
|
+
"hx-swap": "innerHTML"
|
|
11493
|
+
};
|
|
11494
|
+
const formTarget = isAddVersionMode ? "#add-version-form-container" : "#addJobForm";
|
|
11495
|
+
const title = isAddVersionMode ? "Add New Version" : "Add New Documentation";
|
|
11443
11496
|
return /* @__PURE__ */ jsxs("div", { class: "mt-4 p-4 bg-white dark:bg-gray-800 rounded-lg shadow border border-gray-300 dark:border-gray-600 relative animate-[fadeSlideIn_0.2s_ease-out]", children: [
|
|
11444
11497
|
/* @__PURE__ */ jsx(
|
|
11445
11498
|
"button",
|
|
11446
11499
|
{
|
|
11447
11500
|
type: "button",
|
|
11448
|
-
|
|
11449
|
-
"hx-target": "#addJobForm",
|
|
11450
|
-
"hx-swap": "innerHTML",
|
|
11501
|
+
...closeButtonAttrs,
|
|
11451
11502
|
class: "absolute top-3 right-3 p-1 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-150",
|
|
11452
11503
|
title: "Close",
|
|
11453
11504
|
children: /* @__PURE__ */ jsx(
|
|
@@ -11471,16 +11522,20 @@ const ScrapeFormContent = ({
|
|
|
11471
11522
|
)
|
|
11472
11523
|
}
|
|
11473
11524
|
),
|
|
11474
|
-
/* @__PURE__ */ jsx("h3", { class: "text-xl font-semibold text-gray-900 dark:text-white mb-2 pr-8", children:
|
|
11525
|
+
/* @__PURE__ */ jsx("h3", { class: "text-xl font-semibold text-gray-900 dark:text-white mb-2 pr-8", children: title }),
|
|
11475
11526
|
/* @__PURE__ */ jsxs(
|
|
11476
11527
|
"form",
|
|
11477
11528
|
{
|
|
11478
11529
|
"hx-post": "/web/jobs/scrape",
|
|
11479
|
-
"hx-target":
|
|
11530
|
+
"hx-target": formTarget,
|
|
11480
11531
|
"hx-swap": "innerHTML",
|
|
11481
11532
|
class: "space-y-2",
|
|
11482
|
-
"
|
|
11533
|
+
"data-initial-url": urlValue,
|
|
11534
|
+
"data-initial-headers": headersJson,
|
|
11535
|
+
"x-data": "{\n url: '',\n hasPath: false,\n headers: [],\n checkUrlPath() {\n try {\n const url = new URL(this.url);\n this.hasPath = url.pathname !== '/' && url.pathname !== '';\n } catch (e) {\n this.hasPath = false;\n }\n }\n }",
|
|
11536
|
+
"x-init": "\n url = $el.dataset.initialUrl || '';\n headers = JSON.parse($el.dataset.initialHeaders || '[]');\n checkUrlPath();\n ",
|
|
11483
11537
|
children: [
|
|
11538
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: "formMode", value: mode }),
|
|
11484
11539
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
11485
11540
|
/* @__PURE__ */ jsxs("div", { class: "flex items-center", children: [
|
|
11486
11541
|
/* @__PURE__ */ jsx(
|
|
@@ -11521,6 +11576,7 @@ const ScrapeFormContent = ({
|
|
|
11521
11576
|
"x-model": "url",
|
|
11522
11577
|
"x-on:input": "checkUrlPath",
|
|
11523
11578
|
"x-on:paste": "$nextTick(() => checkUrlPath())",
|
|
11579
|
+
placeholder: "https://docs.example.com/library/",
|
|
11524
11580
|
class: "mt-0.5 block w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
|
11525
11581
|
}
|
|
11526
11582
|
),
|
|
@@ -11555,13 +11611,18 @@ const ScrapeFormContent = ({
|
|
|
11555
11611
|
),
|
|
11556
11612
|
/* @__PURE__ */ jsx(Tooltip, { text: "The name of the library you're documenting. This will be used when searching." })
|
|
11557
11613
|
] }),
|
|
11558
|
-
/* @__PURE__ */
|
|
11614
|
+
isAddVersionMode ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11615
|
+
/* @__PURE__ */ jsx("input", { type: "hidden", name: "library", value: libraryValue }),
|
|
11616
|
+
/* @__PURE__ */ jsx("div", { class: "mt-0.5 px-2 py-1 text-sm text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 rounded-md border border-gray-300 dark:border-gray-600", children: /* @__PURE__ */ jsx("span", { safe: true, children: libraryValue }) })
|
|
11617
|
+
] }) : /* @__PURE__ */ jsx(
|
|
11559
11618
|
"input",
|
|
11560
11619
|
{
|
|
11561
11620
|
type: "text",
|
|
11562
11621
|
name: "library",
|
|
11563
11622
|
id: "library",
|
|
11564
11623
|
required: true,
|
|
11624
|
+
value: libraryValue,
|
|
11625
|
+
placeholder: "e.g. react, vue, express",
|
|
11565
11626
|
class: "mt-0.5 block w-full px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
|
11566
11627
|
}
|
|
11567
11628
|
)
|
|
@@ -11576,7 +11637,7 @@ const ScrapeFormContent = ({
|
|
|
11576
11637
|
children: "Version (optional)"
|
|
11577
11638
|
}
|
|
11578
11639
|
),
|
|
11579
|
-
/* @__PURE__ */ jsx(Tooltip, { text: "Specify the version of the library documentation you're indexing. This allows for version-specific searches." })
|
|
11640
|
+
/* @__PURE__ */ jsx(Tooltip, { text: "Specify the version of the library documentation you're indexing (e.g. 2.0.0). Leave empty or enter 'latest' to index without a specific version. This allows for version-specific searches." })
|
|
11580
11641
|
] }),
|
|
11581
11642
|
/* @__PURE__ */ jsx(
|
|
11582
11643
|
"input",
|
|
@@ -11584,6 +11645,7 @@ const ScrapeFormContent = ({
|
|
|
11584
11645
|
type: "text",
|
|
11585
11646
|
name: "version",
|
|
11586
11647
|
id: "version",
|
|
11648
|
+
placeholder: "e.g. 2.0.0 or leave empty for latest",
|
|
11587
11649
|
class: "mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
|
11588
11650
|
}
|
|
11589
11651
|
)
|
|
@@ -11592,7 +11654,9 @@ const ScrapeFormContent = ({
|
|
|
11592
11654
|
"div",
|
|
11593
11655
|
{
|
|
11594
11656
|
class: "bg-gray-50 dark:bg-gray-900 p-2 rounded-md",
|
|
11595
|
-
"
|
|
11657
|
+
"data-should-open": isAddVersionMode && (maxPagesValue || maxDepthValue || scopeValue !== "subpages" || includePatternsValue || excludePatternsText || scrapeModeValue !== ScrapeMode.Auto) ? "true" : "false",
|
|
11658
|
+
"x-data": "{ open: false }",
|
|
11659
|
+
"x-init": "open = $el.dataset.shouldOpen === 'true'",
|
|
11596
11660
|
children: [
|
|
11597
11661
|
/* @__PURE__ */ jsxs(
|
|
11598
11662
|
"button",
|
|
@@ -11645,6 +11709,7 @@ const ScrapeFormContent = ({
|
|
|
11645
11709
|
id: "maxPages",
|
|
11646
11710
|
min: "1",
|
|
11647
11711
|
placeholder: "1000",
|
|
11712
|
+
value: maxPagesValue,
|
|
11648
11713
|
class: "mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
|
11649
11714
|
}
|
|
11650
11715
|
)
|
|
@@ -11669,6 +11734,7 @@ const ScrapeFormContent = ({
|
|
|
11669
11734
|
id: "maxDepth",
|
|
11670
11735
|
min: "0",
|
|
11671
11736
|
placeholder: "3",
|
|
11737
|
+
value: maxDepthValue,
|
|
11672
11738
|
class: "mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
|
11673
11739
|
}
|
|
11674
11740
|
)
|
|
@@ -11704,9 +11770,9 @@ const ScrapeFormContent = ({
|
|
|
11704
11770
|
id: "scope",
|
|
11705
11771
|
class: "mt-0.5 block w-full max-w-sm pl-2 pr-10 py-1 text-base border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white",
|
|
11706
11772
|
children: [
|
|
11707
|
-
/* @__PURE__ */ jsx("option", { value: "subpages", selected:
|
|
11708
|
-
/* @__PURE__ */ jsx("option", { value: "hostname", children: "Hostname" }),
|
|
11709
|
-
/* @__PURE__ */ jsx("option", { value: "domain", children: "Domain" })
|
|
11773
|
+
/* @__PURE__ */ jsx("option", { value: "subpages", selected: scopeValue === "subpages", children: "Subpages (Default)" }),
|
|
11774
|
+
/* @__PURE__ */ jsx("option", { value: "hostname", selected: scopeValue === "hostname", children: "Hostname" }),
|
|
11775
|
+
/* @__PURE__ */ jsx("option", { value: "domain", selected: scopeValue === "domain", children: "Domain" })
|
|
11710
11776
|
]
|
|
11711
11777
|
}
|
|
11712
11778
|
)
|
|
@@ -11730,7 +11796,9 @@ const ScrapeFormContent = ({
|
|
|
11730
11796
|
id: "includePatterns",
|
|
11731
11797
|
rows: "2",
|
|
11732
11798
|
placeholder: "e.g. docs/* or /api\\/v1.*/",
|
|
11733
|
-
class: "mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white"
|
|
11799
|
+
class: "mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white",
|
|
11800
|
+
safe: true,
|
|
11801
|
+
children: includePatternsValue
|
|
11734
11802
|
}
|
|
11735
11803
|
)
|
|
11736
11804
|
] }),
|
|
@@ -11754,10 +11822,10 @@ const ScrapeFormContent = ({
|
|
|
11754
11822
|
rows: "5",
|
|
11755
11823
|
safe: true,
|
|
11756
11824
|
class: "mt-0.5 block w-full max-w-sm px-2 py-1 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-white font-mono text-xs",
|
|
11757
|
-
children:
|
|
11825
|
+
children: excludePatternsText
|
|
11758
11826
|
}
|
|
11759
11827
|
),
|
|
11760
|
-
/* @__PURE__ */ jsx("p", { class: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: "Default patterns are pre-filled. Edit to customize or clear to exclude nothing." })
|
|
11828
|
+
/* @__PURE__ */ jsx("p", { class: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: isAddVersionMode ? "Patterns from previous version. Edit as needed." : "Default patterns are pre-filled. Edit to customize or clear to exclude nothing." })
|
|
11761
11829
|
] }),
|
|
11762
11830
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
11763
11831
|
/* @__PURE__ */ jsxs("div", { class: "flex items-center", children: [
|
|
@@ -11787,9 +11855,30 @@ const ScrapeFormContent = ({
|
|
|
11787
11855
|
id: "scrapeMode",
|
|
11788
11856
|
class: "mt-0.5 block w-full max-w-sm pl-2 pr-10 py-1 text-base border border-gray-300 dark:border-gray-600 focus:outline-none focus:ring-primary-500 focus:border-primary-500 sm:text-sm rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-white",
|
|
11789
11857
|
children: [
|
|
11790
|
-
/* @__PURE__ */ jsx(
|
|
11791
|
-
|
|
11792
|
-
|
|
11858
|
+
/* @__PURE__ */ jsx(
|
|
11859
|
+
"option",
|
|
11860
|
+
{
|
|
11861
|
+
value: ScrapeMode.Auto,
|
|
11862
|
+
selected: scrapeModeValue === ScrapeMode.Auto,
|
|
11863
|
+
children: "Auto (Default)"
|
|
11864
|
+
}
|
|
11865
|
+
),
|
|
11866
|
+
/* @__PURE__ */ jsx(
|
|
11867
|
+
"option",
|
|
11868
|
+
{
|
|
11869
|
+
value: ScrapeMode.Fetch,
|
|
11870
|
+
selected: scrapeModeValue === ScrapeMode.Fetch,
|
|
11871
|
+
children: "Fetch"
|
|
11872
|
+
}
|
|
11873
|
+
),
|
|
11874
|
+
/* @__PURE__ */ jsx(
|
|
11875
|
+
"option",
|
|
11876
|
+
{
|
|
11877
|
+
value: ScrapeMode.Playwright,
|
|
11878
|
+
selected: scrapeModeValue === ScrapeMode.Playwright,
|
|
11879
|
+
children: "Playwright"
|
|
11880
|
+
}
|
|
11881
|
+
)
|
|
11793
11882
|
]
|
|
11794
11883
|
}
|
|
11795
11884
|
)
|
|
@@ -11858,7 +11947,7 @@ const ScrapeFormContent = ({
|
|
|
11858
11947
|
id: "followRedirects",
|
|
11859
11948
|
name: "followRedirects",
|
|
11860
11949
|
type: "checkbox",
|
|
11861
|
-
checked:
|
|
11950
|
+
checked: followRedirectsValue,
|
|
11862
11951
|
class: "h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700"
|
|
11863
11952
|
}
|
|
11864
11953
|
),
|
|
@@ -11878,7 +11967,7 @@ const ScrapeFormContent = ({
|
|
|
11878
11967
|
id: "ignoreErrors",
|
|
11879
11968
|
name: "ignoreErrors",
|
|
11880
11969
|
type: "checkbox",
|
|
11881
|
-
checked:
|
|
11970
|
+
checked: ignoreErrorsValue,
|
|
11882
11971
|
class: "h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700"
|
|
11883
11972
|
}
|
|
11884
11973
|
),
|
|
@@ -12009,23 +12098,12 @@ function getEffectiveExclusionPatterns(userPatterns) {
|
|
|
12009
12098
|
}
|
|
12010
12099
|
return DEFAULT_EXCLUSION_PATTERNS;
|
|
12011
12100
|
}
|
|
12012
|
-
const ScrapeFormButton = () => /* @__PURE__ */ jsx(
|
|
12013
|
-
"button",
|
|
12014
|
-
{
|
|
12015
|
-
type: "button",
|
|
12016
|
-
"hx-get": "/web/jobs/new",
|
|
12017
|
-
"hx-target": "#addJobForm",
|
|
12018
|
-
"hx-swap": "innerHTML",
|
|
12019
|
-
class: "w-full flex justify-center py-1.5 px-3 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-600 hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500 transition-colors duration-150",
|
|
12020
|
-
children: "Add New Documentation"
|
|
12021
|
-
}
|
|
12022
|
-
);
|
|
12023
12101
|
function registerNewJobRoutes(server, scrapeTool) {
|
|
12024
12102
|
server.get("/web/jobs/new", async () => {
|
|
12025
12103
|
return /* @__PURE__ */ jsx(ScrapeForm, { defaultExcludePatterns: DEFAULT_EXCLUSION_PATTERNS });
|
|
12026
12104
|
});
|
|
12027
12105
|
server.get("/web/jobs/new-button", async () => {
|
|
12028
|
-
return /* @__PURE__ */ jsx(
|
|
12106
|
+
return /* @__PURE__ */ jsx(AddJobButton, {});
|
|
12029
12107
|
});
|
|
12030
12108
|
server.post(
|
|
12031
12109
|
"/web/jobs/scrape",
|
|
@@ -12061,11 +12139,11 @@ function registerNewJobRoutes(server, scrapeTool) {
|
|
|
12061
12139
|
}
|
|
12062
12140
|
);
|
|
12063
12141
|
}
|
|
12142
|
+
const normalizedVersion = !body.version || body.version.trim() === "" || body.version.trim().toLowerCase() === "latest" ? null : body.version.trim();
|
|
12064
12143
|
const scrapeOptions = {
|
|
12065
12144
|
url: body.url,
|
|
12066
12145
|
library: body.library,
|
|
12067
|
-
version:
|
|
12068
|
-
// Handle empty string as null
|
|
12146
|
+
version: normalizedVersion,
|
|
12069
12147
|
waitForCompletion: false,
|
|
12070
12148
|
// Don't wait in UI
|
|
12071
12149
|
options: {
|
|
@@ -12084,16 +12162,20 @@ function registerNewJobRoutes(server, scrapeTool) {
|
|
|
12084
12162
|
};
|
|
12085
12163
|
const result = await scrapeTool.execute(scrapeOptions);
|
|
12086
12164
|
if ("jobId" in result) {
|
|
12165
|
+
const versionDisplay = normalizedVersion || "latest";
|
|
12087
12166
|
reply.header(
|
|
12088
12167
|
"HX-Trigger",
|
|
12089
12168
|
JSON.stringify({
|
|
12090
12169
|
toast: {
|
|
12091
|
-
message:
|
|
12170
|
+
message: `Indexing started for ${body.library}@${versionDisplay}`,
|
|
12092
12171
|
type: "success"
|
|
12093
12172
|
}
|
|
12094
12173
|
})
|
|
12095
12174
|
);
|
|
12096
|
-
|
|
12175
|
+
if (body.formMode === "add-version") {
|
|
12176
|
+
return /* @__PURE__ */ jsx(AddVersionButton, { libraryName: body.library });
|
|
12177
|
+
}
|
|
12178
|
+
return /* @__PURE__ */ jsx(AddJobButton, {});
|
|
12097
12179
|
}
|
|
12098
12180
|
return /* @__PURE__ */ jsx(Alert, { type: "warning", message: "Job finished unexpectedly quickly." });
|
|
12099
12181
|
} catch (error) {
|
|
@@ -12119,15 +12201,16 @@ function registerNewJobRoutes(server, scrapeTool) {
|
|
|
12119
12201
|
const VersionDetailsRow = ({
|
|
12120
12202
|
version,
|
|
12121
12203
|
libraryName,
|
|
12122
|
-
showDelete = true
|
|
12123
|
-
|
|
12204
|
+
showDelete = true,
|
|
12205
|
+
showRefresh = false
|
|
12124
12206
|
}) => {
|
|
12125
12207
|
const indexedDate = version.indexedAt ? new Date(version.indexedAt).toLocaleDateString() : "N/A";
|
|
12126
|
-
const versionLabel = version.ref.version || "
|
|
12208
|
+
const versionLabel = version.ref.version || "Latest";
|
|
12127
12209
|
const versionParam = version.ref.version || "";
|
|
12128
12210
|
const sanitizedLibraryName = libraryName.replace(/[^a-zA-Z0-9-_]/g, "-");
|
|
12129
12211
|
const sanitizedVersionParam = versionParam.replace(/[^a-zA-Z0-9-_]/g, "-");
|
|
12130
12212
|
const rowId = `row-${sanitizedLibraryName}-${sanitizedVersionParam}`;
|
|
12213
|
+
const initialIsRefreshing = isActiveStatus(version.status);
|
|
12131
12214
|
const defaultStateClasses = "text-red-700 border border-red-700 hover:bg-red-700 hover:text-white focus:ring-4 focus:outline-none focus:ring-red-300 dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:focus:ring-red-800 dark:hover:bg-red-500";
|
|
12132
12215
|
const confirmingStateClasses = "bg-red-600 text-white border-red-600 focus:ring-4 focus:outline-none focus:ring-red-300 dark:bg-red-700 dark:border-red-700 dark:focus:ring-red-800";
|
|
12133
12216
|
return (
|
|
@@ -12139,14 +12222,16 @@ const VersionDetailsRow = ({
|
|
|
12139
12222
|
class: "flex justify-between items-center py-1 border-b border-gray-200 dark:border-gray-600 last:border-b-0",
|
|
12140
12223
|
"data-library-name": libraryName,
|
|
12141
12224
|
"data-version-param": versionParam,
|
|
12142
|
-
"
|
|
12225
|
+
"data-is-refreshing": initialIsRefreshing ? "true" : "false",
|
|
12226
|
+
"x-data": "{ \n library: $el.dataset.libraryName, \n version: $el.dataset.versionParam, \n confirming: $el.dataset.confirming === 'true', \n isDeleting: false,\n isRefreshing: $el.dataset.isRefreshing === 'true',\n setRefreshing(val) {\n this.isRefreshing = !!val;\n this.$el.dataset.isRefreshing = val ? 'true' : 'false';\n },\n init() {\n const rowId = this.$el.id;\n const myLibrary = this.library;\n const myVersion = this.version;\n \n document.body.addEventListener('job-status-change', (e) => {\n const job = e.detail;\n const jobVersion = job.version || '';\n if (job.library === myLibrary && jobVersion === myVersion) {\n const newValue = ['queued', 'running'].includes(job.status);\n const el = document.getElementById(rowId);\n if (el) {\n el.dispatchEvent(new CustomEvent('set-refreshing', { detail: newValue, bubbles: true }));\n }\n }\n });\n }\n }",
|
|
12227
|
+
"x-on:set-refreshing": "setRefreshing($event.detail)",
|
|
12143
12228
|
children: [
|
|
12144
12229
|
/* @__PURE__ */ jsx(
|
|
12145
12230
|
"span",
|
|
12146
12231
|
{
|
|
12147
12232
|
class: "text-sm text-gray-900 dark:text-white w-1/4 truncate",
|
|
12148
12233
|
title: versionLabel,
|
|
12149
|
-
children: version.ref.version ? /* @__PURE__ */ jsx(VersionBadge, { version: version.ref.version }) : /* @__PURE__ */ jsx("span", { children: "
|
|
12234
|
+
children: version.ref.version ? /* @__PURE__ */ jsx(VersionBadge, { version: version.ref.version }) : /* @__PURE__ */ jsx("span", { class: "text-gray-600 dark:text-gray-400", children: "Latest" })
|
|
12150
12235
|
}
|
|
12151
12236
|
),
|
|
12152
12237
|
/* @__PURE__ */ jsxs("div", { class: "flex space-x-2 text-sm text-gray-600 dark:text-gray-400 w-3/4 justify-end items-center", children: [
|
|
@@ -12166,66 +12251,117 @@ const VersionDetailsRow = ({
|
|
|
12166
12251
|
/* @__PURE__ */ jsx("span", { class: "font-semibold", safe: true, children: indexedDate })
|
|
12167
12252
|
] })
|
|
12168
12253
|
] }),
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
12178
|
-
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
}
|
|
12203
|
-
|
|
12204
|
-
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
|
|
12215
|
-
|
|
12216
|
-
|
|
12254
|
+
/* @__PURE__ */ jsxs("div", { class: "flex items-center ml-2 space-x-1", children: [
|
|
12255
|
+
showRefresh && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12256
|
+
/* @__PURE__ */ jsx("template", { "x-if": "!isRefreshing", children: /* @__PURE__ */ jsxs(
|
|
12257
|
+
"button",
|
|
12258
|
+
{
|
|
12259
|
+
type: "button",
|
|
12260
|
+
class: "font-medium rounded-lg text-sm p-1 w-6 h-6 text-center inline-flex items-center justify-center transition-colors duration-150 ease-in-out text-gray-500 border border-gray-300 hover:bg-gray-100 hover:text-gray-700 focus:ring-4 focus:outline-none focus:ring-gray-200 dark:border-gray-600 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:hover:bg-gray-600",
|
|
12261
|
+
title: "Refresh this version (re-scrape changed pages)",
|
|
12262
|
+
"x-on:click": "\n isRefreshing = true;\n $root.dataset.isRefreshing = 'true';\n $el.dispatchEvent(new CustomEvent('trigger-refresh', { bubbles: true }));\n ",
|
|
12263
|
+
"hx-post": `/web/libraries/${encodeURIComponent(libraryName)}/versions/${encodeURIComponent(versionParam)}/refresh`,
|
|
12264
|
+
"hx-swap": "none",
|
|
12265
|
+
"hx-trigger": "trigger-refresh",
|
|
12266
|
+
children: [
|
|
12267
|
+
/* @__PURE__ */ jsx(
|
|
12268
|
+
"svg",
|
|
12269
|
+
{
|
|
12270
|
+
class: "w-4 h-4",
|
|
12271
|
+
"aria-hidden": "true",
|
|
12272
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
12273
|
+
fill: "none",
|
|
12274
|
+
viewBox: "0 0 24 24",
|
|
12275
|
+
children: /* @__PURE__ */ jsx(
|
|
12276
|
+
"path",
|
|
12277
|
+
{
|
|
12278
|
+
stroke: "currentColor",
|
|
12279
|
+
"stroke-linecap": "round",
|
|
12280
|
+
"stroke-linejoin": "round",
|
|
12281
|
+
"stroke-width": "2",
|
|
12282
|
+
d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
|
|
12283
|
+
}
|
|
12284
|
+
)
|
|
12285
|
+
}
|
|
12286
|
+
),
|
|
12287
|
+
/* @__PURE__ */ jsx("span", { class: "sr-only", children: "Refresh version" })
|
|
12288
|
+
]
|
|
12289
|
+
}
|
|
12290
|
+
) }),
|
|
12291
|
+
/* @__PURE__ */ jsx("template", { "x-if": "isRefreshing", children: /* @__PURE__ */ jsxs(
|
|
12292
|
+
"button",
|
|
12293
|
+
{
|
|
12294
|
+
type: "button",
|
|
12295
|
+
class: "font-medium rounded-lg text-sm p-1 w-6 h-6 text-center inline-flex items-center justify-center transition-colors duration-150 ease-in-out text-gray-500 border border-gray-300 dark:border-gray-600 dark:text-gray-400",
|
|
12296
|
+
title: "Refresh in progress...",
|
|
12297
|
+
disabled: true,
|
|
12298
|
+
children: [
|
|
12299
|
+
/* @__PURE__ */ jsx(LoadingSpinner, { class: "text-gray-500 dark:text-gray-400" }),
|
|
12300
|
+
/* @__PURE__ */ jsx("span", { class: "sr-only", children: "Refreshing..." })
|
|
12301
|
+
]
|
|
12302
|
+
}
|
|
12303
|
+
) })
|
|
12304
|
+
] }),
|
|
12305
|
+
showDelete && /* @__PURE__ */ jsxs(
|
|
12306
|
+
"button",
|
|
12307
|
+
{
|
|
12308
|
+
type: "button",
|
|
12309
|
+
class: "font-medium rounded-lg text-sm p-1 min-w-6 h-6 text-center inline-flex items-center justify-center transition-colors duration-150 ease-in-out",
|
|
12310
|
+
title: "Remove this version",
|
|
12311
|
+
"x-bind:class": `confirming ? '${confirmingStateClasses}' : '${defaultStateClasses}'`,
|
|
12312
|
+
"x-bind:disabled": "isDeleting",
|
|
12313
|
+
"x-on:click": "\n if (confirming) {\n isDeleting = true;\n window.confirmationManager.clear($root.id);\n $el.dispatchEvent(new CustomEvent('confirmed-delete', { bubbles: true }));\n } else {\n confirming = true;\n isDeleting = false;\n window.confirmationManager.start($root.id);\n }\n ",
|
|
12314
|
+
"hx-delete": `/web/libraries/${encodeURIComponent(libraryName)}/versions/${encodeURIComponent(versionParam)}`,
|
|
12315
|
+
"hx-target": `#${rowId}`,
|
|
12316
|
+
"hx-swap": "outerHTML",
|
|
12317
|
+
"hx-trigger": "confirmed-delete",
|
|
12318
|
+
children: [
|
|
12319
|
+
/* @__PURE__ */ jsxs("span", { "x-show": "!confirming && !isDeleting", children: [
|
|
12320
|
+
/* @__PURE__ */ jsx(
|
|
12321
|
+
"svg",
|
|
12322
|
+
{
|
|
12323
|
+
class: "w-4 h-4",
|
|
12324
|
+
"aria-hidden": "true",
|
|
12325
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
12326
|
+
fill: "none",
|
|
12327
|
+
viewBox: "0 0 18 20",
|
|
12328
|
+
children: /* @__PURE__ */ jsx(
|
|
12329
|
+
"path",
|
|
12330
|
+
{
|
|
12331
|
+
stroke: "currentColor",
|
|
12332
|
+
"stroke-linecap": "round",
|
|
12333
|
+
"stroke-linejoin": "round",
|
|
12334
|
+
"stroke-width": "2",
|
|
12335
|
+
d: "M1 5h16M7 8v8m4-8v8M7 1h4a1 1 0 0 1 1 1v3H6V2a1 1 0 0 1-1-1ZM3 5h12v13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V5Z"
|
|
12336
|
+
}
|
|
12337
|
+
)
|
|
12338
|
+
}
|
|
12339
|
+
),
|
|
12340
|
+
/* @__PURE__ */ jsx("span", { class: "sr-only", children: "Remove version" })
|
|
12341
|
+
] }),
|
|
12342
|
+
/* @__PURE__ */ jsxs("span", { "x-show": "confirming && !isDeleting", class: "mx-1", children: [
|
|
12343
|
+
"Confirm?",
|
|
12344
|
+
/* @__PURE__ */ jsx("span", { class: "sr-only", children: "Confirm delete" })
|
|
12345
|
+
] }),
|
|
12346
|
+
/* @__PURE__ */ jsxs("span", { "x-show": "isDeleting", children: [
|
|
12347
|
+
/* @__PURE__ */ jsx(LoadingSpinner, {}),
|
|
12348
|
+
/* @__PURE__ */ jsx("span", { class: "sr-only", children: "Loading..." })
|
|
12349
|
+
] })
|
|
12350
|
+
]
|
|
12351
|
+
}
|
|
12352
|
+
)
|
|
12353
|
+
] })
|
|
12217
12354
|
]
|
|
12218
12355
|
}
|
|
12219
12356
|
)
|
|
12220
12357
|
);
|
|
12221
12358
|
};
|
|
12222
12359
|
const LibraryDetailCard = ({ library }) => {
|
|
12223
|
-
const versions = library.versions
|
|
12360
|
+
const versions = library.versions || [];
|
|
12224
12361
|
const latestVersion = versions[0];
|
|
12225
|
-
return (
|
|
12226
|
-
|
|
12227
|
-
|
|
12228
|
-
/* @__PURE__ */ jsx("h3", { class: "text-lg font-medium text-gray-900 dark:text-white mb-1", children: /* @__PURE__ */ jsx("span", { safe: true, children: library.name }) }),
|
|
12362
|
+
return /* @__PURE__ */ jsxs("div", { class: "block p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600 mb-4", children: [
|
|
12363
|
+
/* @__PURE__ */ jsx("div", { class: "flex justify-between items-start mb-1", children: /* @__PURE__ */ jsxs("div", { children: [
|
|
12364
|
+
/* @__PURE__ */ jsx("h3", { class: "text-lg font-medium text-gray-900 dark:text-white", children: /* @__PURE__ */ jsx("span", { safe: true, children: library.name }) }),
|
|
12229
12365
|
latestVersion?.sourceUrl ? /* @__PURE__ */ jsx("div", { class: "text-sm text-gray-500 dark:text-gray-400", children: /* @__PURE__ */ jsx(
|
|
12230
12366
|
"a",
|
|
12231
12367
|
{
|
|
@@ -12235,31 +12371,43 @@ const LibraryDetailCard = ({ library }) => {
|
|
|
12235
12371
|
safe: true,
|
|
12236
12372
|
children: latestVersion.sourceUrl
|
|
12237
12373
|
}
|
|
12238
|
-
) }) : null
|
|
12239
|
-
|
|
12240
|
-
|
|
12241
|
-
|
|
12242
|
-
|
|
12243
|
-
|
|
12244
|
-
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12257
|
-
|
|
12258
|
-
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12374
|
+
) }) : null
|
|
12375
|
+
] }) }),
|
|
12376
|
+
/* @__PURE__ */ jsx(
|
|
12377
|
+
"div",
|
|
12378
|
+
{
|
|
12379
|
+
class: "mt-2",
|
|
12380
|
+
id: "version-list",
|
|
12381
|
+
"hx-get": `/web/libraries/${encodeURIComponent(library.name)}/versions-list`,
|
|
12382
|
+
"hx-trigger": "library-change from:body",
|
|
12383
|
+
"hx-swap": "morph:innerHTML",
|
|
12384
|
+
children: versions.length > 0 ? versions.map((v) => {
|
|
12385
|
+
const adapted = {
|
|
12386
|
+
id: -1,
|
|
12387
|
+
ref: { library: library.name, version: v.version },
|
|
12388
|
+
status: v.status,
|
|
12389
|
+
progress: v.progress,
|
|
12390
|
+
counts: {
|
|
12391
|
+
documents: v.documentCount,
|
|
12392
|
+
uniqueUrls: v.uniqueUrlCount
|
|
12393
|
+
},
|
|
12394
|
+
indexedAt: v.indexedAt,
|
|
12395
|
+
sourceUrl: v.sourceUrl ?? void 0
|
|
12396
|
+
};
|
|
12397
|
+
return /* @__PURE__ */ jsx(
|
|
12398
|
+
VersionDetailsRow,
|
|
12399
|
+
{
|
|
12400
|
+
libraryName: library.name,
|
|
12401
|
+
version: adapted,
|
|
12402
|
+
showDelete: true,
|
|
12403
|
+
showRefresh: true
|
|
12404
|
+
}
|
|
12405
|
+
);
|
|
12406
|
+
}) : /* @__PURE__ */ jsx("p", { class: "text-sm text-gray-500 dark:text-gray-400 italic", children: "No versions indexed." })
|
|
12407
|
+
}
|
|
12408
|
+
),
|
|
12409
|
+
/* @__PURE__ */ jsx("div", { id: "add-version-form-container", class: "mt-4", children: /* @__PURE__ */ jsx(AddVersionButton, { libraryName: library.name }) })
|
|
12410
|
+
] });
|
|
12263
12411
|
};
|
|
12264
12412
|
const LibrarySearchCard = ({ library }) => {
|
|
12265
12413
|
return /* @__PURE__ */ jsxs("div", { class: "block p-4 bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-300 dark:border-gray-600 mb-4", children: [
|
|
@@ -12285,7 +12433,7 @@ const LibrarySearchCard = ({ library }) => {
|
|
|
12285
12433
|
children: [
|
|
12286
12434
|
/* @__PURE__ */ jsx("option", { value: "", children: "Latest" }),
|
|
12287
12435
|
" ",
|
|
12288
|
-
library.versions.map((version) => /* @__PURE__ */ jsx("option", { value: version.version || "
|
|
12436
|
+
library.versions.map((version) => /* @__PURE__ */ jsx("option", { value: version.version || "latest", safe: true, children: version.version || "Latest" }))
|
|
12289
12437
|
]
|
|
12290
12438
|
}
|
|
12291
12439
|
),
|
|
@@ -12359,7 +12507,7 @@ const SearchResultSkeletonItem = () => /* @__PURE__ */ jsxs("div", { class: "blo
|
|
|
12359
12507
|
/* @__PURE__ */ jsx("div", { class: "h-[0.8em] bg-gray-200 dark:bg-gray-700 rounded w-full mb-2" }),
|
|
12360
12508
|
/* @__PURE__ */ jsx("div", { class: "h-[0.8em] bg-gray-200 dark:bg-gray-700 rounded w-5/6" })
|
|
12361
12509
|
] });
|
|
12362
|
-
function registerLibraryDetailRoutes(server, listLibrariesTool, searchTool) {
|
|
12510
|
+
function registerLibraryDetailRoutes(server, listLibrariesTool, searchTool, scrapeTool, docService) {
|
|
12363
12511
|
server.get(
|
|
12364
12512
|
"/libraries/:libraryName",
|
|
12365
12513
|
async (request, reply) => {
|
|
@@ -12367,7 +12515,7 @@ function registerLibraryDetailRoutes(server, listLibrariesTool, searchTool) {
|
|
|
12367
12515
|
try {
|
|
12368
12516
|
const result = await listLibrariesTool.execute();
|
|
12369
12517
|
const libraryInfo = result.libraries.find(
|
|
12370
|
-
(lib) => lib.name === libraryName
|
|
12518
|
+
(lib) => lib.name.toLowerCase() === libraryName.toLowerCase()
|
|
12371
12519
|
);
|
|
12372
12520
|
if (!libraryInfo) {
|
|
12373
12521
|
reply.status(404).send("Library not found");
|
|
@@ -12404,7 +12552,7 @@ function registerLibraryDetailRoutes(server, listLibrariesTool, searchTool) {
|
|
|
12404
12552
|
reply.status(400).send("Search query is required.");
|
|
12405
12553
|
return;
|
|
12406
12554
|
}
|
|
12407
|
-
const versionParam = version === "
|
|
12555
|
+
const versionParam = version === "latest" ? void 0 : version;
|
|
12408
12556
|
try {
|
|
12409
12557
|
const searchResult = await searchTool.execute({
|
|
12410
12558
|
library: libraryName,
|
|
@@ -12423,9 +12571,128 @@ function registerLibraryDetailRoutes(server, listLibrariesTool, searchTool) {
|
|
|
12423
12571
|
}
|
|
12424
12572
|
}
|
|
12425
12573
|
);
|
|
12574
|
+
server.get(
|
|
12575
|
+
"/web/libraries/:libraryName/versions-list",
|
|
12576
|
+
async (request, reply) => {
|
|
12577
|
+
const { libraryName } = request.params;
|
|
12578
|
+
try {
|
|
12579
|
+
const result = await listLibrariesTool.execute();
|
|
12580
|
+
const libraryInfo = result.libraries.find(
|
|
12581
|
+
(lib) => lib.name.toLowerCase() === libraryName.toLowerCase()
|
|
12582
|
+
);
|
|
12583
|
+
if (!libraryInfo) {
|
|
12584
|
+
reply.status(404).send("Library not found");
|
|
12585
|
+
return;
|
|
12586
|
+
}
|
|
12587
|
+
const versions = libraryInfo.versions || [];
|
|
12588
|
+
reply.type("text/html; charset=utf-8");
|
|
12589
|
+
if (versions.length === 0) {
|
|
12590
|
+
return /* @__PURE__ */ jsx("p", { class: "text-sm text-gray-500 dark:text-gray-400 italic", children: "No versions indexed." });
|
|
12591
|
+
}
|
|
12592
|
+
return /* @__PURE__ */ jsx(Fragment, { children: versions.map((v) => {
|
|
12593
|
+
const adapted = {
|
|
12594
|
+
id: -1,
|
|
12595
|
+
ref: { library: libraryInfo.name, version: v.version },
|
|
12596
|
+
status: v.status,
|
|
12597
|
+
progress: v.progress,
|
|
12598
|
+
counts: {
|
|
12599
|
+
documents: v.documentCount,
|
|
12600
|
+
uniqueUrls: v.uniqueUrlCount
|
|
12601
|
+
},
|
|
12602
|
+
indexedAt: v.indexedAt,
|
|
12603
|
+
sourceUrl: v.sourceUrl ?? void 0
|
|
12604
|
+
};
|
|
12605
|
+
return /* @__PURE__ */ jsx(
|
|
12606
|
+
VersionDetailsRow,
|
|
12607
|
+
{
|
|
12608
|
+
libraryName: libraryInfo.name,
|
|
12609
|
+
version: adapted,
|
|
12610
|
+
showDelete: true,
|
|
12611
|
+
showRefresh: true
|
|
12612
|
+
}
|
|
12613
|
+
);
|
|
12614
|
+
}) });
|
|
12615
|
+
} catch (error) {
|
|
12616
|
+
logger.error(`Failed to fetch versions for ${libraryName}: ${error}`);
|
|
12617
|
+
reply.status(500).send("Internal Server Error");
|
|
12618
|
+
}
|
|
12619
|
+
}
|
|
12620
|
+
);
|
|
12621
|
+
server.get(
|
|
12622
|
+
"/web/libraries/:libraryName/add-version-button",
|
|
12623
|
+
async (request, reply) => {
|
|
12624
|
+
const { libraryName } = request.params;
|
|
12625
|
+
reply.type("text/html; charset=utf-8");
|
|
12626
|
+
return /* @__PURE__ */ jsx(AddVersionButton, { libraryName });
|
|
12627
|
+
}
|
|
12628
|
+
);
|
|
12629
|
+
server.get(
|
|
12630
|
+
"/web/libraries/:libraryName/add-version-form",
|
|
12631
|
+
async (request, reply) => {
|
|
12632
|
+
const { libraryName } = request.params;
|
|
12633
|
+
try {
|
|
12634
|
+
const result = await listLibrariesTool.execute();
|
|
12635
|
+
const libraryInfo = result.libraries.find(
|
|
12636
|
+
(lib) => lib.name.toLowerCase() === libraryName.toLowerCase()
|
|
12637
|
+
);
|
|
12638
|
+
if (!libraryInfo) {
|
|
12639
|
+
reply.status(404).send("Library not found");
|
|
12640
|
+
return;
|
|
12641
|
+
}
|
|
12642
|
+
const versions = libraryInfo.versions || [];
|
|
12643
|
+
const latestVersion = versions[0];
|
|
12644
|
+
let initialValues = {
|
|
12645
|
+
library: libraryName
|
|
12646
|
+
};
|
|
12647
|
+
if (latestVersion) {
|
|
12648
|
+
const summaries = await docService.listLibraries();
|
|
12649
|
+
const libSummary = summaries.find(
|
|
12650
|
+
(s) => s.library.toLowerCase() === libraryName.toLowerCase()
|
|
12651
|
+
);
|
|
12652
|
+
if (libSummary) {
|
|
12653
|
+
const versionSummary = libSummary.versions.find(
|
|
12654
|
+
(v) => v.ref.version === (latestVersion.version || "") || !latestVersion.version && v.ref.version === ""
|
|
12655
|
+
);
|
|
12656
|
+
if (versionSummary) {
|
|
12657
|
+
const scraperConfig = await docService.getScraperOptions(
|
|
12658
|
+
versionSummary.id
|
|
12659
|
+
);
|
|
12660
|
+
if (scraperConfig) {
|
|
12661
|
+
const opts = scraperConfig.options;
|
|
12662
|
+
initialValues = {
|
|
12663
|
+
library: libraryName,
|
|
12664
|
+
url: scraperConfig.sourceUrl,
|
|
12665
|
+
maxPages: opts.maxPages,
|
|
12666
|
+
maxDepth: opts.maxDepth,
|
|
12667
|
+
scope: opts.scope,
|
|
12668
|
+
includePatterns: opts.includePatterns?.join("\n"),
|
|
12669
|
+
excludePatterns: opts.excludePatterns?.join("\n"),
|
|
12670
|
+
scrapeMode: opts.scrapeMode,
|
|
12671
|
+
headers: opts.headers ? Object.entries(opts.headers).map(([name, value]) => ({
|
|
12672
|
+
name,
|
|
12673
|
+
value
|
|
12674
|
+
})) : void 0,
|
|
12675
|
+
followRedirects: opts.followRedirects,
|
|
12676
|
+
ignoreErrors: opts.ignoreErrors
|
|
12677
|
+
};
|
|
12678
|
+
}
|
|
12679
|
+
}
|
|
12680
|
+
}
|
|
12681
|
+
}
|
|
12682
|
+
reply.type("text/html; charset=utf-8");
|
|
12683
|
+
return /* @__PURE__ */ jsx(ScrapeFormContent, { initialValues, mode: "add-version" });
|
|
12684
|
+
} catch (error) {
|
|
12685
|
+
logger.error(
|
|
12686
|
+
`Failed to load add-version form for ${libraryName}: ${error}`
|
|
12687
|
+
);
|
|
12688
|
+
reply.type("text/html; charset=utf-8");
|
|
12689
|
+
return /* @__PURE__ */ jsx(Alert, { type: "error", message: "Failed to load the add version form." });
|
|
12690
|
+
}
|
|
12691
|
+
}
|
|
12692
|
+
);
|
|
12426
12693
|
}
|
|
12427
12694
|
const LibraryItem = ({ library }) => {
|
|
12428
|
-
const versions = library.versions
|
|
12695
|
+
const versions = library.versions || [];
|
|
12429
12696
|
const latestVersion = versions[0];
|
|
12430
12697
|
return (
|
|
12431
12698
|
// Use Flowbite Card structure with updated padding and border, and white background
|
|
@@ -12514,7 +12781,7 @@ const LibraryList = ({ libraries }) => {
|
|
|
12514
12781
|
}
|
|
12515
12782
|
);
|
|
12516
12783
|
};
|
|
12517
|
-
function registerLibrariesRoutes(server, listLibrariesTool, removeTool) {
|
|
12784
|
+
function registerLibrariesRoutes(server, listLibrariesTool, removeTool, refreshVersionTool) {
|
|
12518
12785
|
server.get("/web/libraries", async (_request, reply) => {
|
|
12519
12786
|
try {
|
|
12520
12787
|
const result = await listLibrariesTool.execute();
|
|
@@ -12529,9 +12796,16 @@ function registerLibrariesRoutes(server, listLibrariesTool, removeTool) {
|
|
|
12529
12796
|
"/web/libraries/:libraryName/versions/:versionParam",
|
|
12530
12797
|
async (request, reply) => {
|
|
12531
12798
|
const { libraryName, versionParam } = request.params;
|
|
12532
|
-
const version = versionParam === "
|
|
12799
|
+
const version = versionParam === "latest" ? void 0 : versionParam;
|
|
12533
12800
|
try {
|
|
12534
12801
|
await removeTool.execute({ library: libraryName, version });
|
|
12802
|
+
const result = await listLibrariesTool.execute();
|
|
12803
|
+
const libraryStillExists = result.libraries.some(
|
|
12804
|
+
(lib) => lib.name.toLowerCase() === libraryName.toLowerCase()
|
|
12805
|
+
);
|
|
12806
|
+
if (!libraryStillExists) {
|
|
12807
|
+
reply.header("HX-Redirect", "/");
|
|
12808
|
+
}
|
|
12535
12809
|
reply.status(204).send();
|
|
12536
12810
|
} catch (error) {
|
|
12537
12811
|
logger.error(
|
|
@@ -12541,6 +12815,46 @@ function registerLibrariesRoutes(server, listLibrariesTool, removeTool) {
|
|
|
12541
12815
|
}
|
|
12542
12816
|
}
|
|
12543
12817
|
);
|
|
12818
|
+
server.post(
|
|
12819
|
+
"/web/libraries/:libraryName/versions/:versionParam/refresh",
|
|
12820
|
+
async (request, reply) => {
|
|
12821
|
+
const { libraryName, versionParam } = request.params;
|
|
12822
|
+
const version = versionParam === "latest" || versionParam === "" ? void 0 : versionParam;
|
|
12823
|
+
try {
|
|
12824
|
+
await refreshVersionTool.execute({
|
|
12825
|
+
library: libraryName,
|
|
12826
|
+
version,
|
|
12827
|
+
waitForCompletion: false
|
|
12828
|
+
});
|
|
12829
|
+
const versionDisplay = version || "latest";
|
|
12830
|
+
reply.header(
|
|
12831
|
+
"HX-Trigger",
|
|
12832
|
+
JSON.stringify({
|
|
12833
|
+
toast: {
|
|
12834
|
+
message: `Refresh started for ${libraryName}@${versionDisplay}`,
|
|
12835
|
+
type: "success"
|
|
12836
|
+
}
|
|
12837
|
+
})
|
|
12838
|
+
);
|
|
12839
|
+
reply.status(204).send();
|
|
12840
|
+
} catch (error) {
|
|
12841
|
+
logger.error(
|
|
12842
|
+
`Failed to refresh ${libraryName}@${versionParam}: ${error}`
|
|
12843
|
+
);
|
|
12844
|
+
const errorMessage = error instanceof Error ? error.message : "Failed to refresh version.";
|
|
12845
|
+
reply.header(
|
|
12846
|
+
"HX-Trigger",
|
|
12847
|
+
JSON.stringify({
|
|
12848
|
+
toast: {
|
|
12849
|
+
message: errorMessage,
|
|
12850
|
+
type: "error"
|
|
12851
|
+
}
|
|
12852
|
+
})
|
|
12853
|
+
);
|
|
12854
|
+
reply.status(500).send();
|
|
12855
|
+
}
|
|
12856
|
+
}
|
|
12857
|
+
);
|
|
12544
12858
|
}
|
|
12545
12859
|
function formatNumber(num) {
|
|
12546
12860
|
if (num >= 1e9) {
|
|
@@ -12616,12 +12930,19 @@ async function registerWebService(server, docService, pipeline, eventBus, config
|
|
|
12616
12930
|
const listJobsTool = new ListJobsTool(pipeline);
|
|
12617
12931
|
const scrapeTool = new ScrapeTool(pipeline);
|
|
12618
12932
|
const removeTool = new RemoveTool(docService, pipeline);
|
|
12933
|
+
const refreshVersionTool = new RefreshVersionTool(pipeline);
|
|
12619
12934
|
const searchTool = new SearchTool(docService);
|
|
12620
12935
|
const cancelJobTool = new CancelJobTool(pipeline);
|
|
12621
12936
|
const clearCompletedJobsTool = new ClearCompletedJobsTool(pipeline);
|
|
12622
12937
|
registerIndexRoute(server, config);
|
|
12623
|
-
registerLibrariesRoutes(server, listLibrariesTool, removeTool);
|
|
12624
|
-
registerLibraryDetailRoutes(
|
|
12938
|
+
registerLibrariesRoutes(server, listLibrariesTool, removeTool, refreshVersionTool);
|
|
12939
|
+
registerLibraryDetailRoutes(
|
|
12940
|
+
server,
|
|
12941
|
+
listLibrariesTool,
|
|
12942
|
+
searchTool,
|
|
12943
|
+
scrapeTool,
|
|
12944
|
+
docService
|
|
12945
|
+
);
|
|
12625
12946
|
registerJobListRoutes(server, listJobsTool);
|
|
12626
12947
|
registerNewJobRoutes(server, scrapeTool);
|
|
12627
12948
|
registerCancelJobRoute(server, cancelJobTool);
|
|
@@ -12683,7 +13004,7 @@ class AppServer {
|
|
|
12683
13004
|
try {
|
|
12684
13005
|
if (telemetry.isEnabled()) {
|
|
12685
13006
|
telemetry.setGlobalContext({
|
|
12686
|
-
appVersion: "1.
|
|
13007
|
+
appVersion: "1.31.0",
|
|
12687
13008
|
appPlatform: process.platform,
|
|
12688
13009
|
appNodeVersion: process.version,
|
|
12689
13010
|
appServicesEnabled: this.getActiveServicesList(),
|
|
@@ -14347,11 +14668,11 @@ class PipelineWorker {
|
|
|
14347
14668
|
if (!scraperOptions.isRefresh) {
|
|
14348
14669
|
await this.store.removeAllDocuments(library, version);
|
|
14349
14670
|
logger.info(
|
|
14350
|
-
`💾 Cleared store for ${library}@${version || "
|
|
14671
|
+
`💾 Cleared store for ${library}@${version || "latest"} before scraping.`
|
|
14351
14672
|
);
|
|
14352
14673
|
} else {
|
|
14353
14674
|
logger.info(
|
|
14354
|
-
`🔄 Refresh operation - preserving existing data for ${library}@${version || "
|
|
14675
|
+
`🔄 Refresh operation - preserving existing data for ${library}@${version || "latest"}.`
|
|
14355
14676
|
);
|
|
14356
14677
|
}
|
|
14357
14678
|
await this.scraperService.scrape(
|
|
@@ -14503,7 +14824,7 @@ class PipelineManager {
|
|
|
14503
14824
|
for (const version of runningVersions) {
|
|
14504
14825
|
await this.store.updateVersionStatus(version.id, VersionStatus.QUEUED);
|
|
14505
14826
|
logger.info(
|
|
14506
|
-
`🔄 Reset interrupted job to QUEUED: ${version.library_name}@${version.name || "
|
|
14827
|
+
`🔄 Reset interrupted job to QUEUED: ${version.library_name}@${version.name || "latest"}`
|
|
14507
14828
|
);
|
|
14508
14829
|
}
|
|
14509
14830
|
const queuedVersions = await this.store.getVersionsByStatus([VersionStatus.QUEUED]);
|
|
@@ -14524,7 +14845,7 @@ class PipelineManager {
|
|
|
14524
14845
|
parsedScraperOptions = JSON.parse(version.scraper_options);
|
|
14525
14846
|
} catch (error) {
|
|
14526
14847
|
logger.warn(
|
|
14527
|
-
`⚠️ Failed to parse scraper options for ${version.library_name}@${version.name || "
|
|
14848
|
+
`⚠️ Failed to parse scraper options for ${version.library_name}@${version.name || "latest"}: ${error}`
|
|
14528
14849
|
);
|
|
14529
14850
|
}
|
|
14530
14851
|
}
|
|
@@ -14631,7 +14952,7 @@ class PipelineManager {
|
|
|
14631
14952
|
this.jobMap.set(jobId, job);
|
|
14632
14953
|
this.jobQueue.push(jobId);
|
|
14633
14954
|
logger.info(
|
|
14634
|
-
`📝 Job enqueued: ${jobId} for ${library}${normalizedVersion ? `@${normalizedVersion}` : " (
|
|
14955
|
+
`📝 Job enqueued: ${jobId} for ${library}${normalizedVersion ? `@${normalizedVersion}` : " (latest)"}`
|
|
14635
14956
|
);
|
|
14636
14957
|
await this.updateJobStatus(job, PipelineJobStatus.QUEUED);
|
|
14637
14958
|
if (this.isRunning) {
|
|
@@ -14665,7 +14986,7 @@ class PipelineManager {
|
|
|
14665
14986
|
}
|
|
14666
14987
|
if (versionInfo && versionInfo.status !== VersionStatus.COMPLETED) {
|
|
14667
14988
|
logger.info(
|
|
14668
|
-
`⚠️ Version ${library}@${normalizedVersion || "
|
|
14989
|
+
`⚠️ Version ${library}@${normalizedVersion || "latest"} has status "${versionInfo.status}". Performing full re-scrape instead of refresh.`
|
|
14669
14990
|
);
|
|
14670
14991
|
return this.enqueueJobWithStoredOptions(library, normalizedVersion);
|
|
14671
14992
|
}
|
|
@@ -14677,11 +14998,11 @@ class PipelineManager {
|
|
|
14677
14998
|
}
|
|
14678
14999
|
if (pages.length === 0) {
|
|
14679
15000
|
throw new Error(
|
|
14680
|
-
`No pages found for ${library}@${normalizedVersion || "
|
|
15001
|
+
`No pages found for ${library}@${normalizedVersion || "latest"}. Use scrape_docs to index it first.`
|
|
14681
15002
|
);
|
|
14682
15003
|
}
|
|
14683
15004
|
logger.info(
|
|
14684
|
-
`🔄 Preparing refresh job for ${library}@${normalizedVersion || "
|
|
15005
|
+
`🔄 Preparing refresh job for ${library}@${normalizedVersion || "latest"} with ${pages.length} page(s)`
|
|
14685
15006
|
);
|
|
14686
15007
|
const initialQueue = pages.map((page) => ({
|
|
14687
15008
|
url: page.url,
|
|
@@ -14705,7 +15026,7 @@ class PipelineManager {
|
|
|
14705
15026
|
// Mark this as a refresh operation
|
|
14706
15027
|
};
|
|
14707
15028
|
logger.info(
|
|
14708
|
-
`📝 Enqueueing refresh job for ${library}@${normalizedVersion || "
|
|
15029
|
+
`📝 Enqueueing refresh job for ${library}@${normalizedVersion || "latest"}`
|
|
14709
15030
|
);
|
|
14710
15031
|
return this.enqueueScrapeJob(library, normalizedVersion, scraperOptions);
|
|
14711
15032
|
} catch (error) {
|
|
@@ -14727,7 +15048,7 @@ class PipelineManager {
|
|
|
14727
15048
|
const stored = await this.store.getScraperOptions(versionId);
|
|
14728
15049
|
if (!stored) {
|
|
14729
15050
|
throw new Error(
|
|
14730
|
-
`No stored scraper options found for ${library}@${normalizedVersion || "
|
|
15051
|
+
`No stored scraper options found for ${library}@${normalizedVersion || "latest"}`
|
|
14731
15052
|
);
|
|
14732
15053
|
}
|
|
14733
15054
|
const storedOptions = stored.options;
|
|
@@ -14738,7 +15059,7 @@ class PipelineManager {
|
|
|
14738
15059
|
...storedOptions
|
|
14739
15060
|
};
|
|
14740
15061
|
logger.info(
|
|
14741
|
-
`🔄 Re-indexing ${library}@${normalizedVersion || "
|
|
15062
|
+
`🔄 Re-indexing ${library}@${normalizedVersion || "latest"} with stored options from ${stored.sourceUrl}`
|
|
14742
15063
|
);
|
|
14743
15064
|
return this.enqueueScrapeJob(library, normalizedVersion, completeOptions);
|
|
14744
15065
|
} catch (error) {
|
|
@@ -15774,7 +16095,7 @@ async function removeAction(library, options, command) {
|
|
|
15774
16095
|
function createRemoveCommand(program) {
|
|
15775
16096
|
return program.command("remove <library>").description("Remove documents for a specific library and version").option(
|
|
15776
16097
|
"-v, --version <string>",
|
|
15777
|
-
"Version to remove (optional, removes
|
|
16098
|
+
"Version to remove (optional, removes latest if omitted)"
|
|
15778
16099
|
).option(
|
|
15779
16100
|
"--server-url <url>",
|
|
15780
16101
|
"URL of external pipeline worker RPC (e.g., http://localhost:8080/api)"
|
|
@@ -16170,7 +16491,7 @@ function createCliProgram() {
|
|
|
16170
16491
|
const commandStartTimes = /* @__PURE__ */ new Map();
|
|
16171
16492
|
let globalEventBus = null;
|
|
16172
16493
|
let globalTelemetryService = null;
|
|
16173
|
-
program.name("docs-mcp-server").description("Unified CLI, MCP Server, and Web Interface for Docs MCP Server.").version("1.
|
|
16494
|
+
program.name("docs-mcp-server").description("Unified CLI, MCP Server, and Web Interface for Docs MCP Server.").version("1.31.0").addOption(
|
|
16174
16495
|
new Option("--verbose", "Enable verbose (debug) logging").conflicts("silent")
|
|
16175
16496
|
).addOption(new Option("--silent", "Disable all logging except errors")).addOption(
|
|
16176
16497
|
new Option("--telemetry", "Enable telemetry collection").env("DOCS_MCP_TELEMETRY").argParser((value) => {
|
|
@@ -16204,7 +16525,7 @@ function createCliProgram() {
|
|
|
16204
16525
|
if (shouldEnableTelemetry()) {
|
|
16205
16526
|
if (telemetry.isEnabled()) {
|
|
16206
16527
|
telemetry.setGlobalContext({
|
|
16207
|
-
appVersion: "1.
|
|
16528
|
+
appVersion: "1.31.0",
|
|
16208
16529
|
appPlatform: process.platform,
|
|
16209
16530
|
appNodeVersion: process.version,
|
|
16210
16531
|
appInterface: "cli",
|