@f5xc-salesdemos/xcsh 18.79.0 → 18.80.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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5xc-salesdemos/xcsh",
|
|
4
|
-
"version": "18.
|
|
4
|
+
"version": "18.80.0",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/f5xc-salesdemos/xcsh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@agentclientprotocol/sdk": "0.16.1",
|
|
50
50
|
"@mozilla/readability": "^0.6",
|
|
51
|
-
"@f5xc-salesdemos/xcsh-stats": "18.
|
|
52
|
-
"@f5xc-salesdemos/pi-agent-core": "18.
|
|
53
|
-
"@f5xc-salesdemos/pi-ai": "18.
|
|
54
|
-
"@f5xc-salesdemos/pi-natives": "18.
|
|
55
|
-
"@f5xc-salesdemos/pi-tui": "18.
|
|
56
|
-
"@f5xc-salesdemos/pi-utils": "18.
|
|
51
|
+
"@f5xc-salesdemos/xcsh-stats": "18.80.0",
|
|
52
|
+
"@f5xc-salesdemos/pi-agent-core": "18.80.0",
|
|
53
|
+
"@f5xc-salesdemos/pi-ai": "18.80.0",
|
|
54
|
+
"@f5xc-salesdemos/pi-natives": "18.80.0",
|
|
55
|
+
"@f5xc-salesdemos/pi-tui": "18.80.0",
|
|
56
|
+
"@f5xc-salesdemos/pi-utils": "18.80.0",
|
|
57
57
|
"@sinclair/typebox": "^0.34",
|
|
58
58
|
"@xterm/headless": "^6.0",
|
|
59
59
|
"ajv": "^8.18",
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "18.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "18.80.0",
|
|
21
|
+
"commit": "7c19c50d50c5dacf1cb9e16ec599044ee32e1645",
|
|
22
|
+
"shortCommit": "7c19c50",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v18.
|
|
25
|
-
"commitDate": "2026-05-
|
|
26
|
-
"buildDate": "2026-05-
|
|
24
|
+
"tag": "v18.80.0",
|
|
25
|
+
"commitDate": "2026-05-25T05:57:39Z",
|
|
26
|
+
"buildDate": "2026-05-25T06:19:42.244Z",
|
|
27
27
|
"dirty": true,
|
|
28
28
|
"prNumber": "",
|
|
29
29
|
"repoUrl": "https://github.com/f5xc-salesdemos/xcsh",
|
|
30
30
|
"repoSlug": "f5xc-salesdemos/xcsh",
|
|
31
|
-
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/
|
|
32
|
-
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.
|
|
31
|
+
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/7c19c50d50c5dacf1cb9e16ec599044ee32e1645",
|
|
32
|
+
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.80.0"
|
|
33
33
|
};
|
package/src/tools/xcsh-api.ts
CHANGED
|
@@ -6,9 +6,7 @@ import xcshApiDescription from "../prompts/tools/xcsh-api.md" with { type: "text
|
|
|
6
6
|
import { type ContextEnv, createContextEnv } from "../services/context-env";
|
|
7
7
|
import type { ToolSession } from ".";
|
|
8
8
|
|
|
9
|
-
//
|
|
10
|
-
// Replaces hardcoded startsWith("ves-io")/startsWith("system")/startsWith("shared")
|
|
11
|
-
// with data-driven classification aligned to x-f5xc-namespace-profile extension.
|
|
9
|
+
// Namespace filtering driven by x-f5xc-namespace-profile from enriched API specs.
|
|
12
10
|
|
|
13
11
|
type NamespaceType = "system" | "shared" | "default" | "custom";
|
|
14
12
|
|
|
@@ -133,6 +131,7 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
133
131
|
#contextEnv: ContextEnv;
|
|
134
132
|
#lastApiBase = "";
|
|
135
133
|
#listablePathsCache: string[] | null = null;
|
|
134
|
+
#autoExpandPathsCache: string[] | null = null;
|
|
136
135
|
#expandedNamespaces = new Set<string>();
|
|
137
136
|
|
|
138
137
|
constructor(session: ToolSession) {
|
|
@@ -180,7 +179,11 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
180
179
|
const CONFIG_PREFIX = "/api/config/namespaces/{namespace}/";
|
|
181
180
|
// Only include app/security types (keyword filter). Reduces batch from ~136 to ~42 paths,
|
|
182
181
|
// cutting expansion time by ~3× and eliminating infrastructure noise from the response.
|
|
182
|
+
// Healthcheck is included in batch content (for HC labels) but NOT in the auto-expand
|
|
183
|
+
// trigger list — direct GET to /healthchecks should not trigger a full namespace expansion.
|
|
183
184
|
const APP_KW =
|
|
185
|
+
/loadbalancer|pool|firewall|healthcheck|_policys|setting|type|mitigation|identification|network|route|host|definition|rate_limiter|prefix_set|cdn|waf|api_/i;
|
|
186
|
+
const AUTO_EXPAND_KW =
|
|
184
187
|
/loadbalancer|pool|firewall|_policys|setting|type|mitigation|identification|network|route|host|definition|rate_limiter|prefix_set|cdn|waf|api_/i;
|
|
185
188
|
const META_EXCL = /policy_set|policy_rule|data_polic/i;
|
|
186
189
|
for (const summary of summaries) {
|
|
@@ -200,6 +203,11 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
200
203
|
}
|
|
201
204
|
}
|
|
202
205
|
}
|
|
206
|
+
// Build separate auto-expand trigger list (excludes healthcheck)
|
|
207
|
+
this.#autoExpandPathsCache = paths.filter(p => {
|
|
208
|
+
const last = p.split("/").filter(Boolean).at(-1) ?? "";
|
|
209
|
+
return AUTO_EXPAND_KW.test(last);
|
|
210
|
+
});
|
|
203
211
|
this.#listablePathsCache = paths;
|
|
204
212
|
return paths;
|
|
205
213
|
} catch {
|
|
@@ -459,15 +467,22 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
459
467
|
// Core types get detailed per-resource output with spec summaries.
|
|
460
468
|
// Secondary types get a compact count to reduce batch response noise.
|
|
461
469
|
// Shorter, focused output helps the model find relationship data directly.
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
const
|
|
470
|
+
const getRawTypeName = (r: BatchEntry) => r.path.split("/").pop() ?? r.path;
|
|
471
|
+
// Human-readable type name for display: http_loadbalancers → load balancers, origin_pools → origin pools
|
|
472
|
+
const humanizeType = (raw: string): string =>
|
|
473
|
+
raw
|
|
474
|
+
.replace(/^http_/, "")
|
|
475
|
+
.replace(/_/g, " ")
|
|
476
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
477
|
+
.replace(/([a-z])(balancer|checker)/gi, "$1 $2");
|
|
478
|
+
const coreTypes = relevantData.filter(r => SPEC_TYPES.test(getRawTypeName(r)));
|
|
479
|
+
const secondaryTypes = relevantData.filter(r => !SPEC_TYPES.test(getRawTypeName(r)));
|
|
465
480
|
|
|
466
481
|
if (coreTypes.length > 0) {
|
|
467
482
|
sections.push(`Namespace resource inventory (${coreTypes.length} core types):\n`);
|
|
468
483
|
let idx = 1;
|
|
469
484
|
for (const r of coreTypes) {
|
|
470
|
-
const typeName =
|
|
485
|
+
const typeName = humanizeType(getRawTypeName(r));
|
|
471
486
|
const items = (r.parsed?.items as Array<Record<string, unknown>> | undefined) ?? [];
|
|
472
487
|
if (items.length === 0) {
|
|
473
488
|
sections.push(`${idx}. ${typeName}: ${r.itemCount} item(s)`);
|
|
@@ -486,7 +501,7 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
486
501
|
if (secondaryTypes.length > 0) {
|
|
487
502
|
const secondaryCount = secondaryTypes.reduce((sum, r) => sum + (r.itemCount ?? 0), 0);
|
|
488
503
|
sections.push(
|
|
489
|
-
`\n(+${secondaryTypes.length} other types with ${secondaryCount} items: ${secondaryTypes.map(r =>
|
|
504
|
+
`\n(+${secondaryTypes.length} other types with ${secondaryCount} items: ${secondaryTypes.map(r => humanizeType(getRawTypeName(r))).join(", ")})`,
|
|
490
505
|
);
|
|
491
506
|
}
|
|
492
507
|
|
|
@@ -540,6 +555,15 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
540
555
|
if (spec.monitoring != null) labels.push("monitoring-mode");
|
|
541
556
|
else if (spec.blocking != null) labels.push("blocking-mode");
|
|
542
557
|
}
|
|
558
|
+
if (/healthcheck/i.test(rType)) {
|
|
559
|
+
if (spec.http_health_check != null) {
|
|
560
|
+
labels.push("http");
|
|
561
|
+
const httpHC = spec.http_health_check as Record<string, unknown>;
|
|
562
|
+
if (typeof httpHC.path === "string") labels.push(`path=${httpHC.path}`);
|
|
563
|
+
} else if (spec.tcp_health_check != null) {
|
|
564
|
+
labels.push("tcp");
|
|
565
|
+
}
|
|
566
|
+
}
|
|
543
567
|
if (labels.length > 0) {
|
|
544
568
|
summaryLines.push(`${rName}: ${labels.join(", ")}`);
|
|
545
569
|
}
|
|
@@ -642,12 +666,15 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
|
|
|
642
666
|
// File-based cache in #executeBatch prevents redundant API calls across sessions.
|
|
643
667
|
if (params.method === "GET" && !params.payload) {
|
|
644
668
|
const listablePaths = this.#loadListablePaths();
|
|
645
|
-
|
|
669
|
+
// Use the auto-expand trigger list (excludes healthcheck) to decide WHETHER to expand.
|
|
670
|
+
// The batch itself uses the full listablePaths (includes healthcheck) for content.
|
|
671
|
+
const triggerPaths = this.#autoExpandPathsCache ?? listablePaths;
|
|
672
|
+
if (triggerPaths.length > 0) {
|
|
646
673
|
const normalized = params.path.replace(
|
|
647
674
|
/\/api\/config\/namespaces\/[^/]+\//,
|
|
648
675
|
"/api/config/namespaces/{namespace}/",
|
|
649
676
|
);
|
|
650
|
-
if (
|
|
677
|
+
if (triggerPaths.includes(params.path) || triggerPaths.includes(normalized)) {
|
|
651
678
|
const nsMatch = params.path.match(/\/api\/config\/namespaces\/([^/]+)\//);
|
|
652
679
|
const ns = params.params?.namespace ?? (nsMatch?.[1] && nsMatch[1] !== "{namespace}" ? nsMatch[1] : "");
|
|
653
680
|
if (ns && !this.#expandedNamespaces.has(ns)) {
|