@f5xc-salesdemos/xcsh 19.15.0 → 19.15.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@f5xc-salesdemos/xcsh",
|
|
4
|
-
"version": "19.15.
|
|
4
|
+
"version": "19.15.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",
|
|
@@ -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.15.
|
|
54
|
-
"@f5xc-salesdemos/pi-agent-core": "19.15.
|
|
55
|
-
"@f5xc-salesdemos/pi-ai": "19.15.
|
|
56
|
-
"@f5xc-salesdemos/pi-natives": "19.15.
|
|
57
|
-
"@f5xc-salesdemos/pi-tui": "19.15.
|
|
58
|
-
"@f5xc-salesdemos/pi-utils": "19.15.
|
|
53
|
+
"@f5xc-salesdemos/xcsh-stats": "19.15.2",
|
|
54
|
+
"@f5xc-salesdemos/pi-agent-core": "19.15.2",
|
|
55
|
+
"@f5xc-salesdemos/pi-ai": "19.15.2",
|
|
56
|
+
"@f5xc-salesdemos/pi-natives": "19.15.2",
|
|
57
|
+
"@f5xc-salesdemos/pi-tui": "19.15.2",
|
|
58
|
+
"@f5xc-salesdemos/pi-utils": "19.15.2",
|
|
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.15.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "19.15.2",
|
|
21
|
+
"commit": "64103505bda7d95e1a15c5002b3ad1ac3d8e0c9c",
|
|
22
|
+
"shortCommit": "6410350",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v19.15.
|
|
25
|
-
"commitDate": "2026-06-
|
|
26
|
-
"buildDate": "2026-06-
|
|
24
|
+
"tag": "v19.15.2",
|
|
25
|
+
"commitDate": "2026-06-08T03:42:17Z",
|
|
26
|
+
"buildDate": "2026-06-08T04:04:32.761Z",
|
|
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.15.
|
|
31
|
+
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/64103505bda7d95e1a15c5002b3ad1ac3d8e0c9c",
|
|
32
|
+
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v19.15.2"
|
|
33
33
|
};
|
|
@@ -8,6 +8,8 @@ export interface ProfileCollector {
|
|
|
8
8
|
readonly id: string;
|
|
9
9
|
/** Human-readable name */
|
|
10
10
|
readonly name: string;
|
|
11
|
+
/** Fields this collector is the authoritative source for. Overwrites even pre-existing values. */
|
|
12
|
+
readonly authoritativeFields?: readonly string[];
|
|
11
13
|
/** Check if this collector can run (binary exists, platform ok, etc.) */
|
|
12
14
|
available(): Promise<boolean>;
|
|
13
15
|
/** Run the collector and return partial profile fields to merge */
|
|
@@ -147,7 +147,12 @@ export async function seedProfile(): Promise<UserProfile> {
|
|
|
147
147
|
const META_FIELDS = new Set(["sources", "observations", "updatedAt", "_fieldOwnership"]);
|
|
148
148
|
const FORBIDDEN_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
149
149
|
|
|
150
|
-
export function reconcileProfile(
|
|
150
|
+
export function reconcileProfile(
|
|
151
|
+
target: UserProfile,
|
|
152
|
+
source: Partial<UserProfile>,
|
|
153
|
+
sourceId: string,
|
|
154
|
+
authoritativeFields?: ReadonlySet<string>,
|
|
155
|
+
): void {
|
|
151
156
|
const ownership = target._fieldOwnership ?? {};
|
|
152
157
|
|
|
153
158
|
for (const [key, value] of Object.entries(source)) {
|
|
@@ -160,7 +165,8 @@ export function reconcileProfile(target: UserProfile, source: Partial<UserProfil
|
|
|
160
165
|
|
|
161
166
|
if (currentOwner === "user") continue;
|
|
162
167
|
if (currentOwner && currentOwner !== sourceId) continue;
|
|
163
|
-
|
|
168
|
+
const isAuthoritative = authoritativeFields?.has(k) ?? false;
|
|
169
|
+
if (!currentOwner && !isAuthoritative && target[k] !== undefined && target[k] !== null) continue;
|
|
164
170
|
|
|
165
171
|
Object.defineProperty(target, k, { value, writable: true, enumerable: true, configurable: true });
|
|
166
172
|
if (!currentOwner) {
|
|
@@ -183,7 +189,10 @@ export async function reconcileFromCollectors(): Promise<UserProfile> {
|
|
|
183
189
|
continue;
|
|
184
190
|
}
|
|
185
191
|
const partial = await collector.collect();
|
|
186
|
-
|
|
192
|
+
const authoritative = collector.authoritativeFields?.length
|
|
193
|
+
? new Set(collector.authoritativeFields)
|
|
194
|
+
: undefined;
|
|
195
|
+
reconcileProfile(profile, partial, collector.id, authoritative);
|
|
187
196
|
(profile.sources as Record<string, string>)[collector.id] = new Date().toISOString();
|
|
188
197
|
logger.debug(`Profile collector '${collector.id}' reconciled`);
|
|
189
198
|
} catch (err: unknown) {
|
package/src/tui/output-block.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface OutputBlockOptions {
|
|
|
21
21
|
sections?: Array<{ label?: string; lines: string[] }>;
|
|
22
22
|
width: number;
|
|
23
23
|
applyBg?: boolean;
|
|
24
|
-
/** Override the state-derived border color.
|
|
24
|
+
/** Override the state-derived border color. Always takes precedence, including on error. Use for branded core tools. */
|
|
25
25
|
borderColor?: ThemeColor;
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -39,14 +39,11 @@ export function renderOutputBlock(options: OutputBlockOptions, theme: Theme): st
|
|
|
39
39
|
const v = theme.boxSharp.vertical;
|
|
40
40
|
const cap = h.repeat(3);
|
|
41
41
|
const lineWidth = Math.max(0, width);
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
// override is always cleared on error so all tools show a consistent error border; use F5_TOOL_BORDER_COLOR.
|
|
42
|
+
// borderColorOverride (F5 brand chrome) always takes precedence;
|
|
43
|
+
// built-in tools without an override use dim borders regardless of error state.
|
|
45
44
|
const resolvedBorderColor: ThemeColor =
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
: (borderColorOverride ??
|
|
49
|
-
(state === "warning" ? "warning" : state === "running" || state === "pending" ? "spinnerAccent" : "dim"));
|
|
45
|
+
borderColorOverride ??
|
|
46
|
+
(state === "warning" ? "warning" : state === "running" || state === "pending" ? "spinnerAccent" : "dim");
|
|
50
47
|
const border = (text: string) => theme.fg(resolvedBorderColor, text);
|
|
51
48
|
const bgFn = (() => {
|
|
52
49
|
if (!state || !applyBg) return undefined;
|