@f5xc-salesdemos/xcsh 19.44.0 → 19.44.2
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 +8 -8
- package/src/browser/extension-page-actions.ts +44 -3
- package/src/browser/input-commit.ts +23 -1
- package/src/internal-urls/build-info.generated.ts +8 -8
- package/src/internal-urls/console-catalog.generated.ts +765 -9
- package/src/internal-urls/console-field-metadata-types.ts +7 -0
- package/src/internal-urls/console-field-metadata.generated.ts +330 -8
- package/src/internal-urls/console-resolve.ts +16 -3
- package/src/prompts/system/system-prompt.md +2 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5xc-salesdemos/xcsh",
|
|
4
|
-
"version": "19.44.
|
|
4
|
+
"version": "19.44.2",
|
|
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.44.
|
|
58
|
-
"@f5xc-salesdemos/pi-agent-core": "19.44.
|
|
59
|
-
"@f5xc-salesdemos/pi-ai": "19.44.
|
|
60
|
-
"@f5xc-salesdemos/pi-natives": "19.44.
|
|
61
|
-
"@f5xc-salesdemos/pi-resource-management": "19.44.
|
|
62
|
-
"@f5xc-salesdemos/pi-tui": "19.44.
|
|
63
|
-
"@f5xc-salesdemos/pi-utils": "19.44.
|
|
57
|
+
"@f5xc-salesdemos/xcsh-stats": "19.44.2",
|
|
58
|
+
"@f5xc-salesdemos/pi-agent-core": "19.44.2",
|
|
59
|
+
"@f5xc-salesdemos/pi-ai": "19.44.2",
|
|
60
|
+
"@f5xc-salesdemos/pi-natives": "19.44.2",
|
|
61
|
+
"@f5xc-salesdemos/pi-resource-management": "19.44.2",
|
|
62
|
+
"@f5xc-salesdemos/pi-tui": "19.44.2",
|
|
63
|
+
"@f5xc-salesdemos/pi-utils": "19.44.2",
|
|
64
64
|
"@sinclair/typebox": "^0.34",
|
|
65
65
|
"@xterm/headless": "^6.0",
|
|
66
66
|
"ajv": "^8.20",
|
|
@@ -130,7 +130,8 @@ if(sel.includes('>>')){
|
|
|
130
130
|
if(!el)return JSON.stringify({found:false,error:'no match for '+sel});
|
|
131
131
|
el.scrollIntoView({block:'center',inline:'center'});
|
|
132
132
|
const r=el.getBoundingClientRect();
|
|
133
|
-
|
|
133
|
+
const inGrid=!!el.closest&&!!el.closest('ngx-datatable,datatable-body-cell,datatable-body-row,[class*=datatable]');
|
|
134
|
+
return JSON.stringify({found:true,x:Math.round(r.x+r.width/2),y:Math.round(r.y+r.height/2),tag:el.tagName,txt:(el.textContent||'').trim().slice(0,30),inGrid:inGrid,val:(el.value!==undefined&&el.value!==null?String(el.value):'')});
|
|
134
135
|
})()`;
|
|
135
136
|
}
|
|
136
137
|
|
|
@@ -179,8 +180,20 @@ if(!el)return JSON.stringify({filled:false,error:'selector not found: '+sel});
|
|
|
179
180
|
el.scrollIntoView({block:'center',inline:'center'});el.focus();
|
|
180
181
|
let p=Object.getPrototypeOf(el),d;while(p){d=Object.getOwnPropertyDescriptor(p,'value');if(d&&d.set)break;p=Object.getPrototypeOf(p);}
|
|
181
182
|
const v=${val};d&&d.set?d.set.call(el,v):el.value=v;
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
// Commit to Angular's form model: input+change first. ngx-datatable inline-edit
|
|
184
|
+
// cells differ in how they persist: http-lb "Domains" (vsui-input) commits on
|
|
185
|
+
// BLUR, while ip-prefix-set "IPv4 Prefix" reverts on a bare blur and only persists
|
|
186
|
+
// on an Enter keydown. So for inputs inside a datatable we dispatch Enter BEFORE
|
|
187
|
+
// blur (Enter commits the row; the subsequent blur then re-renders from a model
|
|
188
|
+
// that already holds the value, instead of reverting). Plain textboxes get only
|
|
189
|
+
// blur/focusout — no synthetic Enter, which would risk a premature form submit.
|
|
190
|
+
el.dispatchEvent(new Event('input',{bubbles:true}));
|
|
191
|
+
el.dispatchEvent(new Event('change',{bubbles:true}));
|
|
192
|
+
const inGrid=!!el.closest&&!!el.closest('ngx-datatable,datatable-body-cell,datatable-body-row,[class*=datatable]');
|
|
193
|
+
if(inGrid){for(const t of['keydown','keypress','keyup'])el.dispatchEvent(new KeyboardEvent(t,{bubbles:true,key:'Enter',code:'Enter',keyCode:13,which:13}));}
|
|
194
|
+
el.dispatchEvent(new Event('blur',{bubbles:true}));
|
|
195
|
+
el.dispatchEvent(new Event('focusout',{bubbles:true}));
|
|
196
|
+
return JSON.stringify({filled:true,val:el.value,inGrid:inGrid});
|
|
184
197
|
})()`;
|
|
185
198
|
}
|
|
186
199
|
|
|
@@ -214,6 +227,34 @@ export class ExtensionPageActions implements PageActions {
|
|
|
214
227
|
}
|
|
215
228
|
|
|
216
229
|
async fill(selector: string, value: string, _context?: string): Promise<void> {
|
|
230
|
+
// Probe the element: location, current value, and whether it's an
|
|
231
|
+
// ngx-datatable inline-edit cell. Most console inputs commit reliably via
|
|
232
|
+
// the native-setter path (buildFillScript) — that's what the verified
|
|
233
|
+
// resources use. But ngx-datatable inline cells (e.g. ip-prefix-set's
|
|
234
|
+
// "IPv4 Prefix") do NOT pick up a synthetic value-setter: the cell stays
|
|
235
|
+
// ng-untouched and the reactive form reports the field empty at save. Those
|
|
236
|
+
// cells only commit through REAL keystrokes (each keydown runs inside
|
|
237
|
+
// Angular's NgZone), so for grid inputs we focus the cell and type via CDP.
|
|
238
|
+
const probe = await evalJson(this.#ext, buildResolverScript(selector));
|
|
239
|
+
if (!probe?.found) {
|
|
240
|
+
throw new Error(`fill("${selector}"): ${probe?.error ?? "selector not found"}`);
|
|
241
|
+
}
|
|
242
|
+
if (probe.inGrid) {
|
|
243
|
+
await this.#ext.clickXy(probe.x as number, probe.y as number);
|
|
244
|
+
await new Promise(r => setTimeout(r, 200));
|
|
245
|
+
// Clear any pre-existing text (Backspace ×N) so re-fills are clean —
|
|
246
|
+
// fresh Add-Item rows are empty, so this is a no-op for create.
|
|
247
|
+
const curLen = typeof probe.val === "string" ? probe.val.length : 0;
|
|
248
|
+
for (let i = 0; i < curLen; i++) await this.#ext.keyPress("Backspace").catch(() => {});
|
|
249
|
+
await this.#ext.typeText(value);
|
|
250
|
+
await new Promise(r => setTimeout(r, 200));
|
|
251
|
+
// Enter commits the inline row to the model; Angular marks it ng-valid.
|
|
252
|
+
await this.#ext.keyPress("Enter").catch(() => {});
|
|
253
|
+
await new Promise(r => setTimeout(r, 300));
|
|
254
|
+
const after = await evalJson(this.#ext, buildResolverScript(selector));
|
|
255
|
+
if (typeof after?.val === "string" && after.val.includes(value)) return;
|
|
256
|
+
// Real typing didn't stick — fall through to the native-setter backstop.
|
|
257
|
+
}
|
|
217
258
|
const result = await evalJson(this.#ext, buildFillScript(selector, value));
|
|
218
259
|
if (!result?.filled) {
|
|
219
260
|
throw new Error(`fill("${selector}"): ${result?.error ?? "could not set value"}`);
|
|
@@ -18,10 +18,16 @@
|
|
|
18
18
|
* `.toString()` — the same pattern used by dom-context/dt-context.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
/** Minimal KeyboardEvent constructor shape — typed loosely because this module
|
|
22
|
+
* is type-checked under the webworker lib (no DOM `KeyboardEvent` global) but is
|
|
23
|
+
* injected into and runs in the page, where `view.KeyboardEvent` exists. */
|
|
24
|
+
type KeyboardEventCtor = new (type: string, init?: { bubbles?: boolean; key?: string; code?: string }) => unknown;
|
|
25
|
+
|
|
21
26
|
interface CommittableElement {
|
|
22
27
|
value: string;
|
|
23
|
-
ownerDocument?: { defaultView?: { Event?: typeof Event } | null } | null;
|
|
28
|
+
ownerDocument?: { defaultView?: { Event?: typeof Event; KeyboardEvent?: KeyboardEventCtor } | null } | null;
|
|
24
29
|
dispatchEvent(event: unknown): unknown;
|
|
30
|
+
closest?(selector: string): unknown;
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
export function commitInputValue(el: CommittableElement, value: string): void {
|
|
@@ -46,6 +52,22 @@ export function commitInputValue(el: CommittableElement, value: string): void {
|
|
|
46
52
|
// console's vsui-input commits to the model on blur, not on keystroke).
|
|
47
53
|
el.dispatchEvent(new EventCtor("input", { bubbles: true }));
|
|
48
54
|
el.dispatchEvent(new EventCtor("change", { bubbles: true }));
|
|
55
|
+
// ngx-datatable inline-edit cells that persist on Enter (ip-prefix-set
|
|
56
|
+
// "IPv4 Prefix") revert on a bare blur. For inputs inside a datatable,
|
|
57
|
+
// dispatch Enter BEFORE blur so the row commits first; http-lb "Domains"
|
|
58
|
+
// (commits on blur) is unaffected because blur still fires afterwards.
|
|
59
|
+
// Only the page provides KeyboardEvent (this module type-checks under the
|
|
60
|
+
// webworker lib, which has no DOM KeyboardEvent global) — if absent, skip
|
|
61
|
+
// the best-effort Enter and let the blur below carry the commit.
|
|
62
|
+
const KeyCtor = view?.KeyboardEvent;
|
|
63
|
+
const inGrid =
|
|
64
|
+
typeof el.closest === "function" &&
|
|
65
|
+
!!el.closest("ngx-datatable,datatable-body-cell,datatable-body-row,[class*=datatable]");
|
|
66
|
+
if (inGrid && KeyCtor) {
|
|
67
|
+
for (const t of ["keydown", "keypress", "keyup"] as const) {
|
|
68
|
+
el.dispatchEvent(new KeyCtor(t, { bubbles: true, key: "Enter", code: "Enter" }));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
49
71
|
el.dispatchEvent(new EventCtor("blur", { bubbles: false }));
|
|
50
72
|
el.dispatchEvent(new EventCtor("focusout", { bubbles: true }));
|
|
51
73
|
}
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "19.44.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "19.44.2",
|
|
21
|
+
"commit": "6e93a54c64e7bdd78d54b56b0c0237025aa420c7",
|
|
22
|
+
"shortCommit": "6e93a54",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v19.44.
|
|
25
|
-
"commitDate": "2026-06-
|
|
26
|
-
"buildDate": "2026-06-
|
|
24
|
+
"tag": "v19.44.2",
|
|
25
|
+
"commitDate": "2026-06-25T00:16:19Z",
|
|
26
|
+
"buildDate": "2026-06-25T00:38:03.351Z",
|
|
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/v19.44.
|
|
31
|
+
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/6e93a54c64e7bdd78d54b56b0c0237025aa420c7",
|
|
32
|
+
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.44.2"
|
|
33
33
|
};
|