@f5xc-salesdemos/xcsh 19.20.1 → 19.21.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": "19.20.1",
4
+ "version": "19.21.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",
@@ -50,12 +50,12 @@
50
50
  "dependencies": {
51
51
  "@agentclientprotocol/sdk": "0.16.1",
52
52
  "@mozilla/readability": "^0.6",
53
- "@f5xc-salesdemos/xcsh-stats": "19.20.1",
54
- "@f5xc-salesdemos/pi-agent-core": "19.20.1",
55
- "@f5xc-salesdemos/pi-ai": "19.20.1",
56
- "@f5xc-salesdemos/pi-natives": "19.20.1",
57
- "@f5xc-salesdemos/pi-tui": "19.20.1",
58
- "@f5xc-salesdemos/pi-utils": "19.20.1",
53
+ "@f5xc-salesdemos/xcsh-stats": "19.21.0",
54
+ "@f5xc-salesdemos/pi-agent-core": "19.21.0",
55
+ "@f5xc-salesdemos/pi-ai": "19.21.0",
56
+ "@f5xc-salesdemos/pi-natives": "19.21.0",
57
+ "@f5xc-salesdemos/pi-tui": "19.21.0",
58
+ "@f5xc-salesdemos/pi-utils": "19.21.0",
59
59
  "@sinclair/typebox": "^0.34",
60
60
  "@xterm/headless": "^6.0",
61
61
  "ajv": "^8.20",
@@ -204,7 +204,7 @@ export async function setupTool(prereq: Prerequisite): Promise<SetupResult> {
204
204
  tool: prereq.tool,
205
205
  wasInstalled: !installAttempted,
206
206
  installAttempted,
207
- installSuccess: installAttempted ? true : false,
207
+ installSuccess: !!installAttempted,
208
208
  authenticated: true,
209
209
  };
210
210
  }
@@ -214,7 +214,7 @@ export async function setupTool(prereq: Prerequisite): Promise<SetupResult> {
214
214
  tool: prereq.tool,
215
215
  wasInstalled: !installAttempted,
216
216
  installAttempted,
217
- installSuccess: installAttempted ? true : false,
217
+ installSuccess: installSuccess,
218
218
  authenticated: auth.authenticated,
219
219
  user: auth.user,
220
220
  authLoginCmd: auth.authenticated ? undefined : prereq.authLoginCmd,
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "19.20.1",
21
- "commit": "0ecbb73107f9ece06f7f82f243ff413ff30d6f06",
22
- "shortCommit": "0ecbb73",
20
+ "version": "19.21.0",
21
+ "commit": "b79f79549c5d8c7645ad7484d9231fd39de83c2e",
22
+ "shortCommit": "b79f795",
23
23
  "branch": "main",
24
- "tag": "v19.20.1",
25
- "commitDate": "2026-06-09T12:19:32Z",
26
- "buildDate": "2026-06-09T12:49:05.875Z",
24
+ "tag": "v19.21.0",
25
+ "commitDate": "2026-06-09T14:18:30-04:00",
26
+ "buildDate": "2026-06-09T18:46:50.615Z",
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/0ecbb73107f9ece06f7f82f243ff413ff30d6f06",
32
- "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.20.1"
31
+ "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/b79f79549c5d8c7645ad7484d9231fd39de83c2e",
32
+ "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.21.0"
33
33
  };
@@ -196,6 +196,7 @@ export class InteractiveMode implements InteractiveModeContext {
196
196
  #eventBus?: EventBus;
197
197
  #eventBusUnsubscribers: Array<() => void> = [];
198
198
  #welcomeComponent?: WelcomeComponent;
199
+ #currentPlugins: import("./components/welcome-checks").UnifiedPluginStatus[] = [];
199
200
 
200
201
  constructor(
201
202
  session: AgentSession,
@@ -343,6 +344,7 @@ export class InteractiveMode implements InteractiveModeContext {
343
344
  // Build unified plugin list from service status contributions + marketplace
344
345
  const pluginContributions = this.session.extensionRunner?.getAllRegisteredServiceStatuses() ?? [];
345
346
  const plugins = !startupQuiet ? await buildUnifiedPluginList(pluginContributions).catch(() => []) : [];
347
+ this.#currentPlugins = plugins;
346
348
 
347
349
  const fixableServices: FixableService[] = [];
348
350
  for (const contribution of pluginContributions) {
@@ -953,8 +955,17 @@ export class InteractiveMode implements InteractiveModeContext {
953
955
  if (idx !== -1) {
954
956
  currentServices[idx] = updated;
955
957
  this.#welcomeComponent?.setServices([...currentServices]);
956
- this.ui.requestRender();
957
958
  }
959
+ const pluginIdx = this.#currentPlugins.findIndex(p => p.name.toLowerCase() === service.name.toLowerCase());
960
+ if (pluginIdx !== -1) {
961
+ this.#currentPlugins[pluginIdx] = {
962
+ ...this.#currentPlugins[pluginIdx],
963
+ state: updated.state,
964
+ hint: updated.hint,
965
+ };
966
+ this.#welcomeComponent?.setPlugins([...this.#currentPlugins]);
967
+ }
968
+ this.ui.requestRender();
958
969
  }
959
970
  }
960
971
 
@@ -43,6 +43,82 @@ API calls to the same F5 XC tenant reuse a single TLS connection — sequential
43
43
 
44
44
  For HTTPS: replace `"http": {"port": 80}` with `"https_auto_cert": {"http_redirect": true, "default_header": {}, "tls_config": {"default_security": {}}, "no_mtls": {}}`. For no pool (advertise only): omit `default_route_pools`.
45
45
 
46
+ **HTTP LB advertising (`advertise_where`)** — Four mutually exclusive top-level choices:
47
+ - `"advertise_on_public_default_vip": {}` — default public VIP on Regional Edges
48
+ - `"advertise_on_public": {}` — public VIP (optionally specify `public_ip` ref); use when asked for "public VIP" WITHOUT "default"
49
+ - `"do_not_advertise": {}` — disabled
50
+ - `"advertise_custom": {"advertise_where": […]}` — custom CE/virtual site targeting (see below)
51
+
52
+ **CRITICAL**: "public VIP" = `advertise_on_public`, "public default VIP" = `advertise_on_public_default_vip`. Do NOT conflate these.
53
+
54
+ To advertise on **Customer Edge (CE) sites or virtual sites**, use `"advertise_custom"` with an `advertise_where` array. Each entry requires ONE site-targeting choice AND ONE port choice:
55
+
56
+ |Site-targeting field|Required sub-fields|Notes|
57
+ |---|---|---|
58
+ |`virtual_site`|`virtual_site: {name, namespace}`, `network`|Ref NOT validated — use for CE virtual sites|
59
+ |`site`|`site: {name, namespace}`, `network`|Ref IS validated (400 if site doesn't exist)|
60
+ |`virtual_site_with_vip`|`virtual_site: {name, namespace}`, `ip` (required), `network`|Custom VIP address|
61
+ |`vk8s_service`|oneOf: `site: {name, namespace}` OR `virtual_site: {name, namespace}`|vK8s service network|
62
+ |`advertise_on_public`|`public_ip?: {name, namespace}`|RE public VIP|
63
+
64
+ `network` values — map natural language precisely (6 valid for HTTP LB advertising):
65
+ - "inside and outside" → `SITE_NETWORK_INSIDE_AND_OUTSIDE`
66
+ - "inside only" or "inside network" (without "and outside") → `SITE_NETWORK_INSIDE`
67
+ - "outside only" or "outside network" (without "and inside") → `SITE_NETWORK_OUTSIDE`
68
+ - "outside with internet VIP" → `SITE_NETWORK_OUTSIDE_WITH_INTERNET_VIP`
69
+ - "inside and outside with internet VIP" → `SITE_NETWORK_INSIDE_AND_OUTSIDE_WITH_INTERNET_VIP`
70
+ - "service network" → `SITE_NETWORK_SERVICE`
71
+ - **NOT valid for LB advertising**: `SITE_NETWORK_IP_FABRIC` (API rejects with 400)
72
+
73
+ **CRITICAL**: "inside and outside" = `SITE_NETWORK_INSIDE_AND_OUTSIDE` (not `SITE_NETWORK_INSIDE`). Always check whether the phrase says both "inside AND outside" or just one.
74
+
75
+ Port choices (orthogonal): `"use_default_port": {}` (default) | `"port": <int>` | `"port_ranges": "80,443,8080-8191"`
76
+
77
+ **CRITICAL — "virtual site with VIP" or "using VIP address X"** → must use `virtual_site_with_vip` (NOT `virtual_site`). This requires `ip` field. Example: `{"virtual_site_with_vip": {"virtual_site": {"name": "<n>", "namespace": "<ns>"}, "ip": "10.0.0.100", "network": "SITE_NETWORK_SPECIFIED_VIP_OUTSIDE"}, "use_default_port": {}}`. Network options: `SITE_NETWORK_SPECIFIED_VIP_OUTSIDE` or `SITE_NETWORK_SPECIFIED_VIP_INSIDE`.
78
+
79
+ **CRITICAL — port field**: The `advertise_where` port is a SEPARATE concept from the LB protocol port (`http.port` or `https_auto_cert.port`). When the phrase says "advertise on port X" or "on port X" or "using port X" in the context of custom advertising, set `"port": X` inside the `advertise_where` entry. Do NOT use `use_default_port`. Do NOT change the LB type to HTTPS because the advertise port is 8443.
80
+
81
+ Example — port 8443 in advertise_where: `{"virtual_site": {…, "network": "SITE_NETWORK_INSIDE_AND_OUTSIDE"}, "port": 8443}`
82
+
83
+ **CRITICAL — all 7 SiteNetwork values work with BOTH `virtual_site` AND `site`**. "IP fabric network" = `SITE_NETWORK_IP_FABRIC` — valid for `virtual_site` too. Do NOT ask for alternatives; immediately use the matching enum.
84
+
85
+ Example — advertise on a Customer Edge virtual site, inside and outside:
86
+ ```json
87
+ {
88
+ "metadata": {"name": "<lb-name>", "namespace": "<ns>"},
89
+ "spec": {
90
+ "domains": ["<domain>"],
91
+ "advertise_custom": {
92
+ "advertise_where": [
93
+ {
94
+ "virtual_site": {
95
+ "virtual_site": {"name": "<vsite-name>", "namespace": "<ns>"},
96
+ "network": "SITE_NETWORK_INSIDE_AND_OUTSIDE"
97
+ },
98
+ "use_default_port": {}
99
+ }
100
+ ]
101
+ },
102
+ "http": {"port": 80},
103
+ "default_route_pools": [
104
+ {"pool": {"namespace": "<ns>", "name": "<pool-name>"}, "weight": 1, "priority": 1}
105
+ ]
106
+ }
107
+ }
108
+ ```
109
+
110
+ **Virtual site resource** — When asked to create a virtual site targeting CE sites, POST to `/api/config/namespaces/{namespace}/virtual_sites`:
111
+ ```json
112
+ {
113
+ "metadata": {"name": "<vsite-name>", "namespace": "<ns>"},
114
+ "spec": {
115
+ "site_type": "CUSTOMER_EDGE",
116
+ "site_selector": {"expressions": ["ves.io/siteName in (<ce-site-name>)"]}
117
+ }
118
+ }
119
+ ```
120
+ `site_type`: `CUSTOMER_EDGE` for CE/SMSv2 sites · `REGIONAL_EDGE` for PoPs · `NGINX_ONE` for NGINX One nodes. The `ves.io/siteName` label is automatically applied to all sites — use it in expressions to target specific CE sites by name.
121
+
46
122
  **Resource disambiguation**: Several F5 XC resource types have similar names but different API paths. When the user's intent maps to one of these, use the exact API path shown:
47
123
 
48
124
  |User says|Catalog category|API path segment|NOT|