@f5-sales-demo/xcsh 22.3.1 → 22.3.3
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/package.json +8 -8
- package/src/extensibility/plugins/marketplace/builtin-marketplace-snapshot.ts +1 -1
- package/src/extensibility/plugins/marketplace/builtin-marketplace.provenance.json +3 -3
- package/src/internal-urls/api-catalog-qmd-index.generated.ts +2 -2
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/documentation-repository.ts +41 -7
- package/src/modes/controllers/input-controller.ts +13 -13
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "22.3.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "22.3.3",
|
|
21
|
+
"commit": "82917afa08ee15956c363dacfb1c0f4511c74d3e",
|
|
22
|
+
"shortCommit": "82917af",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v22.3.
|
|
25
|
-
"commitDate": "2026-09-
|
|
26
|
-
"buildDate": "2026-09-
|
|
24
|
+
"tag": "v22.3.3",
|
|
25
|
+
"commitDate": "2026-09-28T13:54:02Z",
|
|
26
|
+
"buildDate": "2026-09-28T14:30:23.798Z",
|
|
27
27
|
"dirty": true,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5-sales-demo/xcsh",
|
|
30
30
|
"repoSlug": "f5-sales-demo/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v22.3.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/82917afa08ee15956c363dacfb1c0f4511c74d3e",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v22.3.3"
|
|
33
33
|
};
|
|
@@ -6,12 +6,13 @@ import os from "node:os";
|
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { gunzipSync } from "node:zlib";
|
|
8
8
|
import { createStore } from "@tobilu/qmd";
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
import {
|
|
10
|
+
DOCUMENTATION_SOURCES,
|
|
11
|
+
type DocumentationAsset,
|
|
12
|
+
type DocumentationDocument,
|
|
13
|
+
type DocumentationRepository,
|
|
14
|
+
type DocumentationSearchResult,
|
|
15
|
+
type DocumentationSource,
|
|
15
16
|
} from "./documentation-resolve";
|
|
16
17
|
import { extractVerifiedDocumentationAsset, type VerifiedDocumentationAsset } from "./documentation-snapshot";
|
|
17
18
|
|
|
@@ -263,6 +264,19 @@ function lexicalDocumentationQuery(query: string): string {
|
|
|
263
264
|
return query.replace(/^\s*(?:what|who)\s+(?:is|are)\s+/i, "").trim() || query;
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
const SUPPORT_QUERY = /\b(?:troubleshoot|support|knowledge[- ]base|error|failure|issue|K[0-9]{6,})\b/i;
|
|
268
|
+
const CONFIGURATION_QUERY = /\b(?:configure|configuration|set\s*up|procedure|instructions?|how\s+(?:do|can|to))\b/i;
|
|
269
|
+
const CONCEPTUAL_QUERY = /\b(?:what\s+(?:is|are)|overview|product|solution|capabilities|benefits)\b/i;
|
|
270
|
+
const MARKETING_TOPIC =
|
|
271
|
+
/\b(?:client[- ]side defense|distributed cloud|web (?:app|application) and api protection|multi[- ]cloud networking|dns load balancer|bot defense|api security|app connect|appstack|content delivery network|cdn|mobile app shield|synthetic monitoring|web app scanning)\b/i;
|
|
272
|
+
|
|
273
|
+
function preferredDocumentationSource(query: string): DocumentationSource | undefined {
|
|
274
|
+
if (SUPPORT_QUERY.test(query)) return "my-f5-com";
|
|
275
|
+
if (CONFIGURATION_QUERY.test(query)) return "docs-cloud-f5-com";
|
|
276
|
+
if (CONCEPTUAL_QUERY.test(query) || MARKETING_TOPIC.test(query)) return "www-f5-com";
|
|
277
|
+
return undefined;
|
|
278
|
+
}
|
|
279
|
+
|
|
266
280
|
export function createEmbeddedDocumentationRepository(
|
|
267
281
|
assets: EmbeddedDocumentationAssets,
|
|
268
282
|
options: EmbeddedDocumentationRepositoryOptions = {},
|
|
@@ -301,7 +315,27 @@ export function createEmbeddedDocumentationRepository(
|
|
|
301
315
|
},
|
|
302
316
|
search: async (query, source, limit): Promise<readonly DocumentationSearchResult[]> => {
|
|
303
317
|
const current = await state();
|
|
304
|
-
const
|
|
318
|
+
const lexicalQuery = lexicalDocumentationQuery(query);
|
|
319
|
+
const preferredSource = source ? undefined : preferredDocumentationSource(query);
|
|
320
|
+
const results = source
|
|
321
|
+
? await current.store.searchLex(lexicalQuery, { limit, collection: source })
|
|
322
|
+
: (
|
|
323
|
+
await Promise.all(
|
|
324
|
+
DOCUMENTATION_SOURCES.map(collection =>
|
|
325
|
+
current.store.searchLex(lexicalQuery, { limit, collection }),
|
|
326
|
+
),
|
|
327
|
+
)
|
|
328
|
+
).flat();
|
|
329
|
+
results.sort((left, right) => {
|
|
330
|
+
const sourceOrder =
|
|
331
|
+
Number(right.collectionName === preferredSource) - Number(left.collectionName === preferredSource);
|
|
332
|
+
return (
|
|
333
|
+
sourceOrder ||
|
|
334
|
+
right.score - left.score ||
|
|
335
|
+
left.collectionName.localeCompare(right.collectionName) ||
|
|
336
|
+
left.displayPath.localeCompare(right.displayPath)
|
|
337
|
+
);
|
|
338
|
+
});
|
|
305
339
|
const rows: DocumentationSearchResult[] = [];
|
|
306
340
|
const lookup = current.database.query(
|
|
307
341
|
"SELECT source, stable_path, title, original_url, markdown FROM documentation_documents WHERE source = ? AND stable_path = ?",
|
|
@@ -281,6 +281,19 @@ export class InputController {
|
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
+
// Handle built-in slash commands
|
|
285
|
+
const slashResult = await executeBuiltinSlashCommand(text, {
|
|
286
|
+
ctx: this.ctx,
|
|
287
|
+
handleBackgroundCommand: () => this.handleBackgroundCommand(),
|
|
288
|
+
});
|
|
289
|
+
if (slashResult === true) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
if (typeof slashResult === "string") {
|
|
293
|
+
// Command handled but returned remaining text to use as prompt
|
|
294
|
+
text = slashResult;
|
|
295
|
+
}
|
|
296
|
+
|
|
284
297
|
const runner = this.ctx.session.extensionRunner;
|
|
285
298
|
let inputImages = this.ctx.pendingImages.length > 0 ? [...this.ctx.pendingImages] : undefined;
|
|
286
299
|
|
|
@@ -301,19 +314,6 @@ export class InputController {
|
|
|
301
314
|
|
|
302
315
|
if (!text) return;
|
|
303
316
|
|
|
304
|
-
// Handle built-in slash commands
|
|
305
|
-
const slashResult = await executeBuiltinSlashCommand(text, {
|
|
306
|
-
ctx: this.ctx,
|
|
307
|
-
handleBackgroundCommand: () => this.handleBackgroundCommand(),
|
|
308
|
-
});
|
|
309
|
-
if (slashResult === true) {
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
if (typeof slashResult === "string") {
|
|
313
|
-
// Command handled but returned remaining text to use as prompt
|
|
314
|
-
text = slashResult;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
317
|
// Handle skill commands (/skill:name [args])
|
|
318
318
|
if (text.startsWith("/skill:")) {
|
|
319
319
|
const spaceIndex = text.indexOf(" ");
|