@f5-sales-demo/xcsh 21.35.0 → 21.35.1
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5-sales-demo/xcsh",
|
|
4
|
-
"version": "21.35.
|
|
4
|
+
"version": "21.35.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/f5-sales-demo/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@agentclientprotocol/sdk": "1.4.0",
|
|
66
|
-
"@f5-sales-demo/pi-agent-core": "21.35.
|
|
67
|
-
"@f5-sales-demo/pi-ai": "21.35.
|
|
68
|
-
"@f5-sales-demo/pi-natives": "21.35.
|
|
69
|
-
"@f5-sales-demo/pi-resource-management": "21.35.
|
|
70
|
-
"@f5-sales-demo/pi-tui": "21.35.
|
|
71
|
-
"@f5-sales-demo/pi-utils": "21.35.
|
|
72
|
-
"@f5-sales-demo/xcsh-stats": "21.35.
|
|
66
|
+
"@f5-sales-demo/pi-agent-core": "21.35.1",
|
|
67
|
+
"@f5-sales-demo/pi-ai": "21.35.1",
|
|
68
|
+
"@f5-sales-demo/pi-natives": "21.35.1",
|
|
69
|
+
"@f5-sales-demo/pi-resource-management": "21.35.1",
|
|
70
|
+
"@f5-sales-demo/pi-tui": "21.35.1",
|
|
71
|
+
"@f5-sales-demo/pi-utils": "21.35.1",
|
|
72
|
+
"@f5-sales-demo/xcsh-stats": "21.35.1",
|
|
73
73
|
"@mozilla/readability": "^0.6",
|
|
74
74
|
"@sinclair/typebox": "0.34.52",
|
|
75
75
|
"@xterm/headless": "^6.0",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import type { ApiCatalogCategory, ApiCatalogIndex } from "./api-catalog-types";
|
|
3
|
+
|
|
4
|
+
export interface ApiCatalogDiscoveryDocument {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly categoryName: string;
|
|
7
|
+
readonly markdown: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ApiCatalogDiscoveryCorpus {
|
|
11
|
+
readonly catalogVersion: string;
|
|
12
|
+
readonly documents: readonly ApiCatalogDiscoveryDocument[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ApiCatalogDiscoveryCandidate {
|
|
16
|
+
readonly categoryName: string;
|
|
17
|
+
readonly destination: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function normalizeApiCatalogDiscoveryTerm(value: string): string {
|
|
21
|
+
return value.toLowerCase().replace(/[_\s]+/g, "-");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** The legacy text predicate extracted without changing its semantics. */
|
|
25
|
+
export function matchesBaselineCatalogDiscoveryTerm(term: string, values: readonly string[]): boolean {
|
|
26
|
+
const normalized = normalizeApiCatalogDiscoveryTerm(term);
|
|
27
|
+
return values.some(value => normalizeApiCatalogDiscoveryTerm(value).includes(normalized));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function categoryDocument(category: ApiCatalogCategory): ApiCatalogDiscoveryDocument {
|
|
31
|
+
const destination = `xcsh://api-catalog/${category.name}`;
|
|
32
|
+
const operations = category.operations.flatMap(operation => [
|
|
33
|
+
`- Operation: ${operation.name}`,
|
|
34
|
+
` - Alias: ${(operation.operationAliases ?? []).join(", ")}`,
|
|
35
|
+
` - Description: ${operation.description}`,
|
|
36
|
+
` - Method: ${operation.method.toUpperCase()}`,
|
|
37
|
+
` - Path: ${operation.path}`,
|
|
38
|
+
` - Operation ID: ${operation.operationId}`,
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
id: `category:${category.name}`,
|
|
43
|
+
categoryName: category.name,
|
|
44
|
+
markdown: [
|
|
45
|
+
`# ${category.displayName}`,
|
|
46
|
+
"",
|
|
47
|
+
`- Category: ${category.name}`,
|
|
48
|
+
`- Destination: ${destination}`,
|
|
49
|
+
"",
|
|
50
|
+
"## Operations",
|
|
51
|
+
...(operations.length > 0 ? operations : ["- None"]),
|
|
52
|
+
"",
|
|
53
|
+
].join("\n"),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Produces a stable, authoritative-only corpus. It intentionally contains no
|
|
59
|
+
* tenant data, credentials, generated examples, or speculative API fields.
|
|
60
|
+
*/
|
|
61
|
+
export function buildApiCatalogDiscoveryCorpus(
|
|
62
|
+
index: ApiCatalogIndex,
|
|
63
|
+
data: Readonly<Record<string, ApiCatalogCategory>>,
|
|
64
|
+
): ApiCatalogDiscoveryCorpus {
|
|
65
|
+
return {
|
|
66
|
+
catalogVersion: index.version,
|
|
67
|
+
documents: Object.values(data)
|
|
68
|
+
.slice()
|
|
69
|
+
.sort((left, right) => left.name.localeCompare(right.name))
|
|
70
|
+
.map(categoryDocument),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function fingerprintApiCatalogDiscoveryCorpus(
|
|
75
|
+
corpus: ApiCatalogDiscoveryCorpus,
|
|
76
|
+
sourceSha: string,
|
|
77
|
+
engineVersion: string,
|
|
78
|
+
): string {
|
|
79
|
+
const bytes = JSON.stringify({
|
|
80
|
+
sourceSha,
|
|
81
|
+
catalogVersion: corpus.catalogVersion,
|
|
82
|
+
engineVersion,
|
|
83
|
+
documents: corpus.documents,
|
|
84
|
+
});
|
|
85
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Byte-equivalent baseline candidate selection for the existing renderer.
|
|
90
|
+
* Ranking is intentionally unchanged: canonical CRUD promotion stays in the
|
|
91
|
+
* renderer where it has access to API-spec evidence.
|
|
92
|
+
*/
|
|
93
|
+
export function rankBaselineCatalogDiscovery(
|
|
94
|
+
term: string,
|
|
95
|
+
corpus: ApiCatalogDiscoveryCorpus,
|
|
96
|
+
): readonly ApiCatalogDiscoveryCandidate[] {
|
|
97
|
+
return corpus.documents
|
|
98
|
+
.filter(document => matchesBaselineCatalogDiscoveryTerm(term, [document.markdown]))
|
|
99
|
+
.map(document => ({
|
|
100
|
+
categoryName: document.categoryName,
|
|
101
|
+
destination: `xcsh://api-catalog/${document.categoryName}`,
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { matchesBaselineCatalogDiscoveryTerm, normalizeApiCatalogDiscoveryTerm } from "./api-catalog-discovery";
|
|
1
2
|
import type {
|
|
2
3
|
ApiCatalogCategory,
|
|
3
4
|
ApiCatalogCategorySummary,
|
|
@@ -7,10 +8,6 @@ import type {
|
|
|
7
8
|
import type { ApiSpecDomainResource, ApiSpecIndex } from "./api-spec-types";
|
|
8
9
|
import type { InternalResource, InternalUrl } from "./types";
|
|
9
10
|
|
|
10
|
-
function normalizeSearchTerm(s: string): string {
|
|
11
|
-
return s.toLowerCase().replace(/[_\s]+/g, "-");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
11
|
function normalizeApiPath(apiPath: string): string {
|
|
15
12
|
return apiPath.replace(/\{(?:metadata|system_metadata)\.(namespace|name)\}/g, "{$1}");
|
|
16
13
|
}
|
|
@@ -165,13 +162,15 @@ function renderCatalogSearch(
|
|
|
165
162
|
term: string,
|
|
166
163
|
specIndex?: ApiSpecIndex,
|
|
167
164
|
): string {
|
|
168
|
-
const normalized = normalizeSearchTerm(term);
|
|
169
165
|
const matchingResources = (specIndex?.domains ?? []).flatMap(domain =>
|
|
170
166
|
domain.resources
|
|
171
167
|
.filter(resource =>
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
matchesBaselineCatalogDiscoveryTerm(term, [
|
|
169
|
+
resource.name,
|
|
170
|
+
resource.description,
|
|
171
|
+
resource.descriptionShort ?? "",
|
|
172
|
+
...(resource.apiPaths ?? []),
|
|
173
|
+
]),
|
|
175
174
|
)
|
|
176
175
|
.map(resource => ({ domain: domain.domain, resource })),
|
|
177
176
|
);
|
|
@@ -188,11 +187,14 @@ function renderCatalogSearch(
|
|
|
188
187
|
const category = data[summary.name];
|
|
189
188
|
return (
|
|
190
189
|
resourceCategoryNames.has(summary.name) ||
|
|
191
|
-
[summary.name, summary.displayName]
|
|
190
|
+
matchesBaselineCatalogDiscoveryTerm(term, [summary.name, summary.displayName]) ||
|
|
192
191
|
(category?.operations ?? []).some(operation =>
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
matchesBaselineCatalogDiscoveryTerm(term, [
|
|
193
|
+
operation.name,
|
|
194
|
+
operation.description,
|
|
195
|
+
operation.path,
|
|
196
|
+
operation.operationId,
|
|
197
|
+
]),
|
|
196
198
|
)
|
|
197
199
|
);
|
|
198
200
|
})
|
|
@@ -573,8 +575,8 @@ function renderListableTypes(
|
|
|
573
575
|
function renderUnknownCategory(requested: string, summaries: readonly ApiCatalogCategorySummary[]): string {
|
|
574
576
|
const suggestions = summaries
|
|
575
577
|
.filter(c => {
|
|
576
|
-
const norm =
|
|
577
|
-
const normName =
|
|
578
|
+
const norm = normalizeApiCatalogDiscoveryTerm(requested);
|
|
579
|
+
const normName = normalizeApiCatalogDiscoveryTerm(c.name);
|
|
578
580
|
return normName.includes(norm) || norm.includes(normName.slice(0, 4));
|
|
579
581
|
})
|
|
580
582
|
.slice(0, 5);
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "21.35.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "21.35.1",
|
|
21
|
+
"commit": "40f00db4bf790b604f5aeed3762eaa469b707392",
|
|
22
|
+
"shortCommit": "40f00db",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v21.35.
|
|
25
|
-
"commitDate": "2026-09-
|
|
26
|
-
"buildDate": "2026-09-
|
|
24
|
+
"tag": "v21.35.1",
|
|
25
|
+
"commitDate": "2026-09-20T21:15:00+00:00",
|
|
26
|
+
"buildDate": "2026-09-20T22:15:10.342Z",
|
|
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/v21.35.
|
|
31
|
+
"commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/40f00db4bf790b604f5aeed3762eaa469b707392",
|
|
32
|
+
"releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v21.35.1"
|
|
33
33
|
};
|