@f5xc-salesdemos/xcsh 19.23.1 → 19.24.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.23.1",
4
+ "version": "19.24.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.23.1",
54
- "@f5xc-salesdemos/pi-agent-core": "19.23.1",
55
- "@f5xc-salesdemos/pi-ai": "19.23.1",
56
- "@f5xc-salesdemos/pi-natives": "19.23.1",
57
- "@f5xc-salesdemos/pi-tui": "19.23.1",
58
- "@f5xc-salesdemos/pi-utils": "19.23.1",
53
+ "@f5xc-salesdemos/xcsh-stats": "19.24.0",
54
+ "@f5xc-salesdemos/pi-agent-core": "19.24.0",
55
+ "@f5xc-salesdemos/pi-ai": "19.24.0",
56
+ "@f5xc-salesdemos/pi-natives": "19.24.0",
57
+ "@f5xc-salesdemos/pi-tui": "19.24.0",
58
+ "@f5xc-salesdemos/pi-utils": "19.24.0",
59
59
  "@sinclair/typebox": "^0.34",
60
60
  "@xterm/headless": "^6.0",
61
61
  "ajv": "^8.20",
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "19.23.1",
21
- "commit": "b1a85a4920cd93796d6b73b7aea3685dde5aaefc",
22
- "shortCommit": "b1a85a4",
20
+ "version": "19.24.0",
21
+ "commit": "b6d2c75111b6a2e4e599661cb3c89156385d1a60",
22
+ "shortCommit": "b6d2c75",
23
23
  "branch": "main",
24
- "tag": "v19.23.1",
25
- "commitDate": "2026-06-09T23:43:51-04:00",
26
- "buildDate": "2026-06-10T04:14:47.865Z",
24
+ "tag": "v19.24.0",
25
+ "commitDate": "2026-06-10T12:18:46-04:00",
26
+ "buildDate": "2026-06-10T16:58:17.950Z",
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/b1a85a4920cd93796d6b73b7aea3685dde5aaefc",
32
- "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.23.1"
31
+ "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/b6d2c75111b6a2e4e599661cb3c89156385d1a60",
32
+ "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.24.0"
33
33
  };
@@ -151,6 +151,13 @@ export const TERRAFORM_INDEX: TerraformIndex = {
151
151
  resource_count: 4,
152
152
  resources: ["app_setting", "app_type", "discovery", "filter_set"],
153
153
  },
154
+ {
155
+ name: "Monitoring",
156
+ slug: "monitoring",
157
+ description: "Log receivers, alert policies, APM, and global logging configuration",
158
+ resource_count: 4,
159
+ resources: ["alert_receiver", "apm", "global_log_receiver", "log_receiver"],
160
+ },
154
161
  {
155
162
  name: "Certificates",
156
163
  slug: "certificates",
@@ -165,20 +172,6 @@ export const TERRAFORM_INDEX: TerraformIndex = {
165
172
  resource_count: 4,
166
173
  resources: ["ike1", "ike2", "ike_phase1_profile", "ike_phase2_profile"],
167
174
  },
168
- {
169
- name: "Monitoring",
170
- slug: "monitoring",
171
- description: "Log receivers, alert policies, APM, and global logging configuration",
172
- resource_count: 4,
173
- resources: ["alert_receiver", "apm", "global_log_receiver", "log_receiver"],
174
- },
175
- {
176
- name: "Authentication",
177
- slug: "authentication",
178
- description: "Authentication methods, cloud credentials, and secret management",
179
- resource_count: 3,
180
- resources: ["authentication", "cloud_credentials", "secret_management_access"],
181
- },
182
175
  {
183
176
  name: "DNS",
184
177
  slug: "dns",
@@ -194,11 +187,18 @@ export const TERRAFORM_INDEX: TerraformIndex = {
194
187
  resources: ["bigip_http_proxy", "data_group", "irule"],
195
188
  },
196
189
  {
197
- name: "Cloud Resources",
198
- slug: "cloud-resources",
199
- description: "Cloud elastic IPs, address allocators, and geo-location resources",
190
+ name: "Authentication",
191
+ slug: "authentication",
192
+ description: "Authentication methods, cloud credentials, and secret management",
193
+ resource_count: 3,
194
+ resources: ["authentication", "cloud_credentials", "secret_management_access"],
195
+ },
196
+ {
197
+ name: "Uncategorized",
198
+ slug: "uncategorized",
199
+ description: "Resources pending categorization",
200
200
  resource_count: 2,
201
- resources: ["address_allocator", "cloud_elastic_ip"],
201
+ resources: ["application_profiles", "authorization_server"],
202
202
  },
203
203
  {
204
204
  name: "Organization",
@@ -208,11 +208,18 @@ export const TERRAFORM_INDEX: TerraformIndex = {
208
208
  resources: ["namespace", "tenant_configuration"],
209
209
  },
210
210
  {
211
- name: "Uncategorized",
212
- slug: "uncategorized",
213
- description: "Resources pending categorization",
211
+ name: "Cloud Resources",
212
+ slug: "cloud-resources",
213
+ description: "Cloud elastic IPs, address allocators, and geo-location resources",
214
214
  resource_count: 2,
215
- resources: ["application_profiles", "authorization_server"],
215
+ resources: ["address_allocator", "cloud_elastic_ip"],
216
+ },
217
+ {
218
+ name: "Subscriptions",
219
+ slug: "subscriptions",
220
+ description: "Cloud subscription management and metering",
221
+ resource_count: 1,
222
+ resources: ["cminstance"],
216
223
  },
217
224
  {
218
225
  name: "Integrations",
@@ -228,13 +235,6 @@ export const TERRAFORM_INDEX: TerraformIndex = {
228
235
  resource_count: 1,
229
236
  resources: ["policer"],
230
237
  },
231
- {
232
- name: "Subscriptions",
233
- slug: "subscriptions",
234
- description: "Cloud subscription management and metering",
235
- resource_count: 1,
236
- resources: ["cminstance"],
237
- },
238
238
  ],
239
239
  resources: {
240
240
  address_allocator: {
@@ -10,7 +10,7 @@
10
10
  * - Events: AgentSessionEvent objects streamed as they occur
11
11
  * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response
12
12
  */
13
- import { $env, readJsonl, Snowflake, VERSION } from "@f5xc-salesdemos/pi-utils";
13
+ import { $env, readJsonl, Snowflake, setLocale, VERSION } from "@f5xc-salesdemos/pi-utils";
14
14
  import type {
15
15
  ExtensionUIContext,
16
16
  ExtensionUIDialogOptions,
@@ -528,9 +528,10 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
528
528
  // =================================================================
529
529
 
530
530
  case "prompt": {
531
- // Don't await - events will stream
532
- // Extension commands are executed immediately, file prompt templates are expanded
533
- // If streaming and streamingBehavior specified, queues via steer/followUp
531
+ if (command.locale) {
532
+ setLocale(command.locale);
533
+ await session.refreshBaseSystemPrompt();
534
+ }
534
535
  session
535
536
  .prompt(command.message, {
536
537
  images: command.images,
@@ -569,6 +570,16 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
569
570
  return success(id, "new_session", { cancelled });
570
571
  }
571
572
 
573
+ // =================================================================
574
+ // Locale
575
+ // =================================================================
576
+
577
+ case "set_locale": {
578
+ setLocale(command.locale);
579
+ await session.refreshBaseSystemPrompt();
580
+ return success(id, "set_locale");
581
+ }
582
+
572
583
  // =================================================================
573
584
  // State
574
585
  // =================================================================
@@ -17,13 +17,23 @@ import type { TodoPhase } from "../../tools/todo-write";
17
17
 
18
18
  export type RpcCommand =
19
19
  // Prompting
20
- | { id?: string; type: "prompt"; message: string; images?: ImageContent[]; streamingBehavior?: "steer" | "followUp" }
20
+ | {
21
+ id?: string;
22
+ type: "prompt";
23
+ message: string;
24
+ locale?: string;
25
+ images?: ImageContent[];
26
+ streamingBehavior?: "steer" | "followUp";
27
+ }
21
28
  | { id?: string; type: "steer"; message: string; images?: ImageContent[] }
22
29
  | { id?: string; type: "follow_up"; message: string; images?: ImageContent[] }
23
30
  | { id?: string; type: "abort" }
24
31
  | { id?: string; type: "abort_and_prompt"; message: string; images?: ImageContent[] }
25
32
  | { id?: string; type: "new_session"; parentSession?: string }
26
33
 
34
+ // Locale
35
+ | { id?: string; type: "set_locale"; locale: string }
36
+
27
37
  // State
28
38
  | { id?: string; type: "get_state" }
29
39
  | { id?: string; type: "set_todos"; phases: TodoPhase[] }
@@ -106,6 +116,9 @@ export type RpcResponse =
106
116
  | { id?: string; type: "response"; command: "abort_and_prompt"; success: true }
107
117
  | { id?: string; type: "response"; command: "new_session"; success: true; data: { cancelled: boolean } }
108
118
 
119
+ // Locale
120
+ | { id?: string; type: "response"; command: "set_locale"; success: true }
121
+
109
122
  // State
110
123
  | { id?: string; type: "response"; command: "get_state"; success: true; data: RpcSessionState }
111
124
  | { id?: string; type: "response"; command: "set_todos"; success: true; data: { todoPhases: TodoPhase[] } }
@@ -42,6 +42,12 @@ The SE decides what to do; evidence decides what is true. See `<epistemic-integr
42
42
  - When producing customer-facing content, maintain a professional tone appropriate to the audience.
43
43
  </communication>
44
44
 
45
+ {{#if locale}}
46
+ <language>
47
+ The user's display language is {{locale.name}} ({{locale.code}}). You **MUST** respond in {{locale.name}} unless the user explicitly asks for a different language. Technical terms, code, CLI commands, API names, and resource identifiers remain in their original form — only natural-language prose is translated.
48
+ </language>
49
+ {{/if}}
50
+
45
51
  <epistemic-integrity>
46
52
  Prioritize technical accuracy and truthfulness over validating the user's beliefs. You are optimized for truth-seeking, not agreement.
47
53
 
package/src/sdk.ts CHANGED
@@ -17,6 +17,8 @@ import {
17
17
  $flag,
18
18
  getAgentDbPath,
19
19
  getAgentDir,
20
+ getLocale,
21
+ getLocaleDisplayName,
20
22
  getProjectDir,
21
23
  logger,
22
24
  postmortem,
@@ -1493,6 +1495,10 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1493
1495
  // No computer profile — hint block omitted
1494
1496
  }
1495
1497
 
1498
+ const currentLocale = getLocale();
1499
+ const localeName = currentLocale !== "en" ? getLocaleDisplayName(currentLocale) : undefined;
1500
+ const localeForPrompt = localeName ? { code: currentLocale, name: localeName } : undefined;
1501
+
1496
1502
  const defaultPrompt = await buildSystemPromptInternal({
1497
1503
  cwd,
1498
1504
  skills,
@@ -1510,6 +1516,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1510
1516
  eagerTasks,
1511
1517
  secretsEnabled,
1512
1518
  context: contextForPrompt,
1519
+ locale: localeForPrompt,
1513
1520
  userProfile,
1514
1521
  computerProfile,
1515
1522
  knowledgeTopics,
@@ -1540,6 +1547,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
1540
1547
  eagerTasks,
1541
1548
  secretsEnabled,
1542
1549
  context: contextForPrompt,
1550
+ locale: localeForPrompt,
1543
1551
  userProfile,
1544
1552
  computerProfile,
1545
1553
  knowledgeTopics,
@@ -459,6 +459,8 @@ export interface BuildSystemPromptOptions {
459
459
  credentialSource: string;
460
460
  authStatus: string;
461
461
  };
462
+ /** Locale for LLM response language. When set and non-English, a `<language>` block is injected into the system prompt. */
463
+ locale?: { code: string; name: string };
462
464
  /** Compact user profile hint injected into Workspace section. Omit when no profile exists. */
463
465
  userProfile?: {
464
466
  name: string;
@@ -669,6 +671,7 @@ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}):
669
671
  eagerTasks,
670
672
  secretsEnabled,
671
673
  context,
674
+ locale: options.locale,
672
675
  userProfile: options.userProfile,
673
676
  computerProfile: options.computerProfile,
674
677
  knowledgeTopics: options.knowledgeTopics,