@f5-sales-demo/xcsh 21.4.0 → 21.5.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": "@f5-sales-demo/xcsh",
4
- "version": "21.4.0",
4
+ "version": "21.5.0",
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",
@@ -61,13 +61,13 @@
61
61
  },
62
62
  "dependencies": {
63
63
  "@agentclientprotocol/sdk": "1.3.0",
64
- "@f5-sales-demo/pi-agent-core": "21.4.0",
65
- "@f5-sales-demo/pi-ai": "21.4.0",
66
- "@f5-sales-demo/pi-natives": "21.4.0",
67
- "@f5-sales-demo/pi-resource-management": "21.4.0",
68
- "@f5-sales-demo/pi-tui": "21.4.0",
69
- "@f5-sales-demo/pi-utils": "21.4.0",
70
- "@f5-sales-demo/xcsh-stats": "21.4.0",
64
+ "@f5-sales-demo/pi-agent-core": "21.5.0",
65
+ "@f5-sales-demo/pi-ai": "21.5.0",
66
+ "@f5-sales-demo/pi-natives": "21.5.0",
67
+ "@f5-sales-demo/pi-resource-management": "21.5.0",
68
+ "@f5-sales-demo/pi-tui": "21.5.0",
69
+ "@f5-sales-demo/pi-utils": "21.5.0",
70
+ "@f5-sales-demo/xcsh-stats": "21.5.0",
71
71
  "@mozilla/readability": "^0.6",
72
72
  "@sinclair/typebox": "^0.34",
73
73
  "@xterm/headless": "^6.0",
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "21.4.0",
21
- "commit": "f4df1169036003716fae08f7825efe0483b03fb4",
22
- "shortCommit": "f4df116",
20
+ "version": "21.5.0",
21
+ "commit": "5c35c5a1a0d9725f5db96095758e81073345f205",
22
+ "shortCommit": "5c35c5a",
23
23
  "branch": "main",
24
- "tag": "v21.4.0",
25
- "commitDate": "2026-09-01T02:20:18+00:00",
26
- "buildDate": "2026-09-01T02:51:00.403Z",
24
+ "tag": "v21.5.0",
25
+ "commitDate": "2026-09-01T12:45:11+00:00",
26
+ "buildDate": "2026-09-01T13:15:33.169Z",
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/f4df1169036003716fae08f7825efe0483b03fb4",
32
- "releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v21.4.0"
31
+ "commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/5c35c5a1a0d9725f5db96095758e81073345f205",
32
+ "releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v21.5.0"
33
33
  };
@@ -12,7 +12,7 @@ export function getLoginOptions(): LoginOption[] {
12
12
  id: "google-vertex",
13
13
  kind: "local",
14
14
  name: "Google Cloud Vertex AI (Corporate)",
15
- description: "Corporate Google Cloud account · ADC · Gemini 3.7 Flash HIGH",
15
+ description: "Enterprise Vertex subscription · browser sign-in · Gemini 3.7 Flash HIGH",
16
16
  available: true,
17
17
  loginOrder: -100,
18
18
  },
@@ -1354,6 +1354,32 @@ export class SelectorController {
1354
1354
  async #handleVertexLogin(): Promise<void> {
1355
1355
  const runtime = defaultVertexLoginRuntime;
1356
1356
  try {
1357
+ const authStorage = this.ctx.session.modelRegistry.authStorage;
1358
+ let accessToken = await authStorage.getApiKey("google-vertex");
1359
+ if (!accessToken) {
1360
+ this.ctx.showStatus("Authenticating Corporate Vertex with the authorized Google enterprise flow…");
1361
+ await authStorage.login("google-vertex", {
1362
+ onAuth: info => {
1363
+ this.ctx.chatContainer.addChild(new Text(theme.fg("dim", info.url), 1, 0));
1364
+ if (isHeadlessTerminal(runtime.environment)) {
1365
+ this.ctx.chatContainer.addChild(new Text(theme.fg("dim", MANUAL_LOGIN_TIP), 1, 0));
1366
+ } else {
1367
+ this.ctx.openInBrowser(info.url);
1368
+ }
1369
+ this.ctx.ui.requestRender();
1370
+ },
1371
+ onPrompt: prompt =>
1372
+ this.#promptLoginValue({
1373
+ message: prompt.message,
1374
+ placeholder: prompt.placeholder,
1375
+ allowEmpty: prompt.allowEmpty,
1376
+ }),
1377
+ onProgress: message => this.ctx.showStatus(message),
1378
+ onManualCodeInput: () => this.ctx.oauthManualInput.waitForInput("google-vertex"),
1379
+ });
1380
+ accessToken = await authStorage.getApiKey("google-vertex");
1381
+ if (!accessToken) throw new Error("Vertex OAuth authentication did not return an access token");
1382
+ }
1357
1383
  const detected = await detectVertexProject(runtime);
1358
1384
  const proposed = await this.#promptLoginValue({
1359
1385
  message: detected
@@ -1369,8 +1395,8 @@ export class SelectorController {
1369
1395
  }
1370
1396
 
1371
1397
  try {
1372
- this.ctx.showStatus("Validating Vertex AI Application Default Credentials and Gemini 3.7 Flash access…");
1373
- await validateVertexLogin(runtime, project);
1398
+ this.ctx.showStatus("Validating Vertex AI OAuth credentials and Gemini 3.7 Flash access…");
1399
+ await validateVertexLogin(runtime, project, accessToken);
1374
1400
  } catch (error) {
1375
1401
  const action = await this.#showLoginRecovery(
1376
1402
  { stage: "validation", error: vertexFailureGuidance(error, project), canEdit: true },
@@ -1381,10 +1407,8 @@ export class SelectorController {
1381
1407
  this.ctx.showStatus("Vertex AI login cancelled. Existing configuration unchanged.");
1382
1408
  return;
1383
1409
  }
1384
- if (action === "edit") {
1385
- await runtime.loginApplicationDefault(isHeadlessTerminal(runtime.environment));
1386
- }
1387
- await validateVertexLogin(runtime, project);
1410
+ if (action === "edit") throw new Error("Retry `/login google-vertex` to authenticate again.");
1411
+ await validateVertexLogin(runtime, project, accessToken);
1388
1412
  }
1389
1413
 
1390
1414
  const applied = await applyModelAfterLogin(this.ctx.session, GOOGLE_VERTEX_LOGIN_MODEL_CHOICE);
@@ -43,7 +43,7 @@ export function vertexFailureGuidance(error: unknown, project?: string): string
43
43
  const message = error instanceof Error ? error.message : String(error);
44
44
  const projectArg = project ? ` --project ${project}` : "";
45
45
  if (/credential|unauthenticated|login|access token/i.test(message)) {
46
- return "Application Default Credentials are required. Run `gcloud auth application-default login`.";
46
+ return "Vertex OAuth credentials are unavailable. Run `/login google-vertex` and sign in again.";
47
47
  }
48
48
  if (/billing/i.test(message)) return `Enable billing for the selected project:${projectArg}`;
49
49
  if (/serviceusage|api.*disabled|not.*enabled/i.test(message)) {
@@ -55,8 +55,12 @@ export function vertexFailureGuidance(error: unknown, project?: string): string
55
55
  return `Vertex AI could not access ${VERTEX_LOGIN_MODEL} in global: ${message}`;
56
56
  }
57
57
 
58
- export async function validateVertexLogin(runtime: VertexLoginRuntime, project: string): Promise<void> {
59
- const accessToken = await runtime.applicationDefaultAccessToken();
58
+ export async function validateVertexLogin(
59
+ runtime: VertexLoginRuntime,
60
+ project: string,
61
+ oauthAccessToken?: string,
62
+ ): Promise<void> {
63
+ const accessToken = oauthAccessToken ?? (await runtime.applicationDefaultAccessToken());
60
64
  if (!accessToken) throw new Error("Application Default Credentials are unavailable");
61
65
  await runtime.validateModel(project, VERTEX_LOGIN_LOCATION, accessToken);
62
66
  }