@f5xc-salesdemos/xcsh 19.48.0 → 19.49.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.48.0",
4
+ "version": "19.49.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",
@@ -54,13 +54,13 @@
54
54
  "dependencies": {
55
55
  "@agentclientprotocol/sdk": "0.16.1",
56
56
  "@mozilla/readability": "^0.6",
57
- "@f5xc-salesdemos/xcsh-stats": "19.48.0",
58
- "@f5xc-salesdemos/pi-agent-core": "19.48.0",
59
- "@f5xc-salesdemos/pi-ai": "19.48.0",
60
- "@f5xc-salesdemos/pi-natives": "19.48.0",
61
- "@f5xc-salesdemos/pi-resource-management": "19.48.0",
62
- "@f5xc-salesdemos/pi-tui": "19.48.0",
63
- "@f5xc-salesdemos/pi-utils": "19.48.0",
57
+ "@f5xc-salesdemos/xcsh-stats": "19.49.0",
58
+ "@f5xc-salesdemos/pi-agent-core": "19.49.0",
59
+ "@f5xc-salesdemos/pi-ai": "19.49.0",
60
+ "@f5xc-salesdemos/pi-natives": "19.49.0",
61
+ "@f5xc-salesdemos/pi-resource-management": "19.49.0",
62
+ "@f5xc-salesdemos/pi-tui": "19.49.0",
63
+ "@f5xc-salesdemos/pi-utils": "19.49.0",
64
64
  "@sinclair/typebox": "^0.34",
65
65
  "@xterm/headless": "^6.0",
66
66
  "ajv": "^8.20",
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "19.48.0",
21
- "commit": "d0c5ae1622948405d6d1efdf5d664ec72ffbb7dd",
22
- "shortCommit": "d0c5ae1",
20
+ "version": "19.49.0",
21
+ "commit": "fb72a3cf675798ecef6816224a5152ff7a032bbb",
22
+ "shortCommit": "fb72a3c",
23
23
  "branch": "main",
24
- "tag": "v19.48.0",
25
- "commitDate": "2026-06-25T19:38:18Z",
26
- "buildDate": "2026-06-25T20:04:08.080Z",
24
+ "tag": "v19.49.0",
25
+ "commitDate": "2026-06-25T23:35:47Z",
26
+ "buildDate": "2026-06-26T00:02:45.777Z",
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/d0c5ae1622948405d6d1efdf5d664ec72ffbb7dd",
32
- "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.48.0"
31
+ "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/fb72a3cf675798ecef6816224a5152ff7a032bbb",
32
+ "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.49.0"
33
33
  };
@@ -0,0 +1,147 @@
1
+ # xcsh Chrome Extension Bridge — Tool API Reference
2
+
3
+ > Surfaced via `xcsh://extension`. The xcsh assistant drives the browser through
4
+ > the Chrome extension bridge (native messaging → service worker → CDP). Knowing
5
+ > which tool to use — and which to avoid — for each interaction is essential for
6
+ > deterministic, non-fragile automation.
7
+
8
+ ---
9
+
10
+ ## Deterministic click path (PREFERRED)
11
+
12
+ ### `click_element { js, wait_ms? }`
13
+ **Use for:** clicking any element that exists in the page's main document.
14
+
15
+ `js` is a JavaScript expression that returns the target **Element** (or null). The
16
+ extension resolves geometry from the renderer (`DOM.getContentQuads` — CSS viewport
17
+ px with transforms/zoom/DPR baked in) and **hit-tests** the point
18
+ (`document.elementFromPoint`) before dispatching the trusted click. On occlusion it
19
+ re-scrolls once, then **fails loudly** naming the occluder — never a silent mis-click.
20
+ `wait_ms` polls for async elements (CDK portals, lazy content).
21
+
22
+ **Guarantees:**
23
+ - Deterministic across window sizes and zoom levels (layout-engine coords, not JS rects).
24
+ - Catches overlays (CDK portals, dialogs) and tells you what's in the way.
25
+ - Holds the element handle atomically across scroll → measure → verify → click.
26
+
27
+ **Build the `js` arg via** `buildElementResolverScript(selector)` (the same catalogue
28
+ selector grammar: `text('…')`, `role:text('…')`, `role[name='…']`, CSS, row-scoped `>>`)
29
+ so the click resolves the same element the workflow YAML names.
30
+
31
+ ---
32
+
33
+ ### `click { ref }`
34
+ Use when you already have an AX `ref` handle (from `read_ax`). Routes through
35
+ `click_element` internally — same determinism guarantees.
36
+
37
+ ### `click_xy { x, y }`
38
+ **Last-resort.** Only for viewport points with no backing element (e.g. a computed
39
+ portal-overlay coordinate, or testing a specific pixel). Skips hit-testing.
40
+
41
+ ---
42
+
43
+ ## CDK-portal / typeahead (REQUIRED for CDK portals)
44
+
45
+ ### `label_select { selector, value, label_value?, wait_ms? }`
46
+ **Use for:** any CDK-portal typeahead (`.cdk-overlay-container`): label-selector
47
+ key/operator/value steps, vsui "Type to search" inputs.
48
+
49
+ The extension keeps the input **focused throughout** (uses plain `Runtime.evaluate`,
50
+ NOT `evaluateWithRecovery` which detaches the debugger and kills focus). It:
51
+ 1. Clicks the input (focus).
52
+ 2. Types `value` via `Input.insertText` (keeps focus).
53
+ 3. Polls the CDK portal for a matching option (`span` in `.cdk-overlay-container`).
54
+ 4. Clicks the option via trusted CDP.
55
+ 5. If `label_value` is provided, enters it into the value field that appears (uses the
56
+ secret-textarea real-typing path if it's a `<textarea>`).
57
+
58
+ **Why mandatory for CDK portals:** `javascript_tool` routes through `evaluateWithRecovery`
59
+ which DETACHES the CDP debugger on timeout — killing input focus and closing the portal.
60
+ `label_select` uses plain `Runtime.evaluate` and holds focus end-to-end.
61
+
62
+ ---
63
+
64
+ ## Input (trusted)
65
+
66
+ ### `type_text { text }`
67
+ Inserts text via `Input.insertText` into the currently-focused element. Fires genuine
68
+ trusted input events that Angular's ControlValueAccessor and vsui pick up. Use this
69
+ (or `fill` via page-actions) for text fields, not programmatic value setting.
70
+
71
+ ### `key_press { key }`
72
+ Dispatches a trusted `Input.dispatchKeyEvent` (keyDown + keyUp) for the named key
73
+ (e.g. `"Enter"`, `"Tab"`, `"Escape"`, `"Backspace"`).
74
+
75
+ ### `form_input { ref, value }`
76
+ Sets a form field's value via `Runtime.callFunctionOn` — the Angular-compat path that
77
+ bypasses vsui's value-descriptor patching. Use when `fill` isn't available.
78
+
79
+ ---
80
+
81
+ ## DOM inspection (caution: defocuses active input)
82
+
83
+ ### `javascript_tool { code }`
84
+ Evaluates arbitrary JavaScript and returns the result. Routes through
85
+ `evaluateWithRecovery` — **IMPORTANT: this defocuses the currently-focused input and
86
+ closes any open CDK portal / vsui dropdown.** Never call it between a typeahead open
87
+ and a portal selection. Safe for reading DOM state BEFORE opening a typeahead.
88
+
89
+ ### `read_ax { }` / `find { selector }`
90
+ Reads the accessibility tree or finds AX nodes by selector. Both freeze the MV3
91
+ service worker on heavy F5 XC SPA pages (30s+) — prefer `javascript_tool` for quick
92
+ DOM queries. `read_ax` is usable on lighter pages.
93
+
94
+ ### `get_page_text { }`
95
+ Returns the visible text content of the current page.
96
+
97
+ ---
98
+
99
+ ## Navigation
100
+
101
+ ### `navigate { url }`
102
+ Navigates to a URL. Auto-accepts `beforeunload` ("Leave site?") dialogs — so a dirty
103
+ form's dialog does NOT block navigation. Wait for the target page to settle before
104
+ querying the DOM.
105
+
106
+ ### `wait_for { selector, context?, timeoutMs? }` / `assert_text { selector, expected }`
107
+ Wait for an element to appear / assert text. Use these as post-navigation settle points.
108
+
109
+ ---
110
+
111
+ ## Tab management
112
+
113
+ ### `tabs_list`, `tabs_create`, `tabs_close`
114
+ Enumerate, open, and close browser tabs. Useful for multi-tab flows or checking that a
115
+ navigation landed on the intended page.
116
+
117
+ ---
118
+
119
+ ## Screenshot (avoid in automation)
120
+
121
+ ### `screenshot { }` → base64 JPEG
122
+ Captures a scaled canvas screenshot. **Avoid in automation loops** — `captureVisibleTab`
123
+ freezes the MV3 service worker event loop on retina Mac displays, blocking all
124
+ subsequent bridge requests for several seconds.
125
+
126
+ ---
127
+
128
+ ## Debugging tools
129
+
130
+ ### `read_console { pattern? }` / `read_network { pattern? }`
131
+ Read Chrome DevTools console logs or network requests. Use for debugging — not required
132
+ in deterministic create/read/update/delete flows.
133
+
134
+ ---
135
+
136
+ ## Summary: which tool for which job
137
+
138
+ | Situation | Tool |
139
+ |-----------|------|
140
+ | Click a button/tab/link in the page | `click_element` (buildElementResolverScript) |
141
+ | Click inside a CDK portal option | `label_select` (the ONLY reliable path) |
142
+ | Fill a text input | page-actions `fill` → `type_text` under the hood |
143
+ | Select from a vsui listbox | page-actions `selectOption` → `click_element` + poll |
144
+ | Need current DOM state | `javascript_tool` (but check there's no open typeahead first) |
145
+ | Navigate between pages | `navigate` |
146
+ | Verify something appeared | `wait_for` / `assert_text` |
147
+ | Raw coordinates only | `click_xy` (last resort) |
@@ -13,6 +13,7 @@ import { XCSHApiClient } from "./xcsh-api-client";
13
13
  import {
14
14
  deriveTenantFromUrl,
15
15
  hasEnvOverride,
16
+ isInjectableContextEnvKey,
16
17
  normalizeApiUrl,
17
18
  RESERVED_ENV_KEYS,
18
19
  RESERVED_ENV_MESSAGES,
@@ -1388,10 +1389,13 @@ export class ContextService {
1388
1389
  // Inject context profile name for API tool identity surfacing
1389
1390
  merged[XCSH_CONTEXT_NAME] = context.name;
1390
1391
 
1391
- // Inject all additional env vars from context.env map
1392
+ // Inject additional env vars from context.env. Allowlist: only XCSH_-namespaced
1393
+ // non-reserved keys may reach the subprocess — a project-local context file is
1394
+ // untrusted input, so anything outside the XCSH_ namespace (LD_PRELOAD,
1395
+ // NODE_OPTIONS, PATH, …) is refused and can never run code.
1392
1396
  if (context.env) {
1393
1397
  for (const [key, value] of Object.entries(context.env)) {
1394
- if (!process.env[key] && !(RESERVED_ENV_KEYS.has(key) && key in merged)) merged[key] = value;
1398
+ if (isInjectableContextEnvKey(key) && !process.env[key]) merged[key] = value;
1395
1399
  }
1396
1400
  }
1397
1401
 
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import {
8
8
  AUTH_ENV_KEYS,
9
+ isInjectableContextEnvKey,
9
10
  isSensitiveEnvKey,
10
11
  RESERVED_ENV_KEYS,
11
12
  SECRET_ENV_PATTERNS,
@@ -20,6 +21,7 @@ import {
20
21
 
21
22
  export {
22
23
  AUTH_ENV_KEYS,
24
+ isInjectableContextEnvKey,
23
25
  isSensitiveEnvKey,
24
26
  RESERVED_ENV_KEYS,
25
27
  SECRET_ENV_PATTERNS,