@f5xc-salesdemos/xcsh 18.4.0 → 18.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": "@f5xc-salesdemos/xcsh",
|
|
4
|
-
"version": "18.
|
|
4
|
+
"version": "18.5.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",
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@agentclientprotocol/sdk": "0.16.1",
|
|
49
49
|
"@mozilla/readability": "^0.6",
|
|
50
|
-
"@f5xc-salesdemos/xcsh-stats": "18.
|
|
51
|
-
"@f5xc-salesdemos/pi-agent-core": "18.
|
|
52
|
-
"@f5xc-salesdemos/pi-ai": "18.
|
|
53
|
-
"@f5xc-salesdemos/pi-natives": "18.
|
|
54
|
-
"@f5xc-salesdemos/pi-tui": "18.
|
|
55
|
-
"@f5xc-salesdemos/pi-utils": "18.
|
|
50
|
+
"@f5xc-salesdemos/xcsh-stats": "18.5.0",
|
|
51
|
+
"@f5xc-salesdemos/pi-agent-core": "18.5.0",
|
|
52
|
+
"@f5xc-salesdemos/pi-ai": "18.5.0",
|
|
53
|
+
"@f5xc-salesdemos/pi-natives": "18.5.0",
|
|
54
|
+
"@f5xc-salesdemos/pi-tui": "18.5.0",
|
|
55
|
+
"@f5xc-salesdemos/pi-utils": "18.5.0",
|
|
56
56
|
"@sinclair/typebox": "^0.34",
|
|
57
57
|
"@xterm/headless": "^6.0",
|
|
58
58
|
"ajv": "^8.18",
|
|
@@ -17,17 +17,17 @@ export interface BuildInfo {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const BUILD_INFO: BuildInfo = {
|
|
20
|
-
"version": "18.
|
|
21
|
-
"commit": "
|
|
22
|
-
"shortCommit": "
|
|
20
|
+
"version": "18.5.0",
|
|
21
|
+
"commit": "50d87af3879c08179ba1f0bb790ec3928c3b41ea",
|
|
22
|
+
"shortCommit": "50d87af",
|
|
23
23
|
"branch": "main",
|
|
24
|
-
"tag": "v18.
|
|
25
|
-
"commitDate": "2026-04-
|
|
26
|
-
"buildDate": "2026-04-
|
|
24
|
+
"tag": "v18.5.0",
|
|
25
|
+
"commitDate": "2026-04-21T07:29:16Z",
|
|
26
|
+
"buildDate": "2026-04-21T07:56:37.534Z",
|
|
27
27
|
"dirty": false,
|
|
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/v18.
|
|
31
|
+
"commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/50d87af3879c08179ba1f0bb790ec3928c3b41ea",
|
|
32
|
+
"releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.5.0"
|
|
33
33
|
};
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { Container, Markdown, padding, Spacer, visibleWidth } from "@f5xc-salesdemos/pi-tui";
|
|
2
2
|
import { getMarkdownTheme, theme } from "../../modes/theme/theme";
|
|
3
3
|
|
|
4
|
-
// OSC 133 shell integration: marks prompt zones for terminal multiplexers
|
|
5
|
-
const OSC133_ZONE_START = "\x1b]133;A\x07";
|
|
6
|
-
const OSC133_ZONE_END = "\x1b]133;B\x07";
|
|
7
|
-
const OSC133_ZONE_FINAL = "\x1b]133;C\x07";
|
|
8
|
-
|
|
9
4
|
// U+2503 BOX DRAWINGS HEAVY VERTICAL — continuation bar on wrapped lines.
|
|
10
5
|
const CONTINUATION_BAR = "┃";
|
|
11
6
|
// Markdown child uses paddingX=1 and clamps contentWidth>=1, so its minimum
|
|
12
7
|
// render output is 3 terminal cells. Anything narrower than prefix+3 would
|
|
13
8
|
// overflow the requested width — bail out instead.
|
|
14
9
|
const MIN_MARKDOWN_WIDTH = 3;
|
|
10
|
+
// Leading gutter reserved for sibling GutterBlock indicators (● etc.) so the
|
|
11
|
+
// π / ┃ accent bar aligns with content text rather than sitting at column 0.
|
|
12
|
+
const GUTTER_WIDTH = 2;
|
|
13
|
+
const GUTTER_PAD = " ";
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* Renders a user message as an F5-branded admonition block: pi icon on the
|
|
@@ -24,7 +23,7 @@ export class UserMessageComponent extends Container {
|
|
|
24
23
|
super();
|
|
25
24
|
const color = synthetic
|
|
26
25
|
? (value: string) => theme.fg("dim", value)
|
|
27
|
-
: (value: string) => theme.fg("userMessageText", value)
|
|
26
|
+
: (value: string) => `\x1b[3m${theme.fg("userMessageText", value)}\x1b[23m`;
|
|
28
27
|
this.addChild(new Spacer(1));
|
|
29
28
|
this.addChild(new Markdown(text, 1, 0, getMarkdownTheme(), { color }));
|
|
30
29
|
}
|
|
@@ -36,7 +35,7 @@ export class UserMessageComponent extends Container {
|
|
|
36
35
|
// glyph and ASCII "pi" are 2 cols. Measure both and reserve the
|
|
37
36
|
// larger so every content line leaves room for either shape.
|
|
38
37
|
const prefixWidth = Math.max(visibleWidth(piPrefix), visibleWidth(contPrefix));
|
|
39
|
-
const innerWidth = width - prefixWidth;
|
|
38
|
+
const innerWidth = width - GUTTER_WIDTH - prefixWidth;
|
|
40
39
|
if (innerWidth < MIN_MARKDOWN_WIDTH) {
|
|
41
40
|
return [];
|
|
42
41
|
}
|
|
@@ -57,13 +56,10 @@ export class UserMessageComponent extends Container {
|
|
|
57
56
|
const content = raw.slice(firstContent).map((line, i) => {
|
|
58
57
|
const prefix = theme.fg("border", i === 0 ? piPrefix : contPrefix);
|
|
59
58
|
const combined = prefix + line;
|
|
60
|
-
const pad = Math.max(0, width - visibleWidth(combined));
|
|
61
|
-
return theme.bg("userMessageBg", combined + padding(pad));
|
|
59
|
+
const pad = Math.max(0, width - GUTTER_WIDTH - visibleWidth(combined));
|
|
60
|
+
return GUTTER_PAD + theme.bg("userMessageBg", combined + padding(pad));
|
|
62
61
|
});
|
|
63
62
|
|
|
64
|
-
content[0] = OSC133_ZONE_START + content[0];
|
|
65
|
-
content[content.length - 1] = content[content.length - 1] + OSC133_ZONE_END + OSC133_ZONE_FINAL;
|
|
66
|
-
|
|
67
63
|
return [...leading, ...content];
|
|
68
64
|
}
|
|
69
65
|
}
|
|
@@ -64,6 +64,8 @@ The operator decides what to do; evidence decides what is true. See `<epistemic-
|
|
|
64
64
|
<epistemic-integrity>
|
|
65
65
|
Prioritize technical accuracy and truthfulness over validating the user's beliefs. You are optimized for truth-seeking, not agreement.
|
|
66
66
|
|
|
67
|
+
Be diplomatically honest rather than dishonestly diplomatic. Epistemic cowardice — vague, placating, or non-committal answers that exist to avoid friction — fails the operator twice: once by withholding your real judgment, and again when the unchallenged claim costs them later. Disagreement is part of the work, not a breach of it. Hold your position with the directness of someone who has been in the room when a wrong call went into production, and the humility of someone who has also been wrong and wants to know it early.
|
|
68
|
+
|
|
67
69
|
- A user restating a claim more forcefully is NOT new evidence. Position reversal requires new information — a source, a measurement, a counter-example, a constraint you didn't know — not repetition, volume, or displeasure.
|
|
68
70
|
- When you hold a well-reasoned position and the user contradicts it without new information, you **MUST** restate the position with its reasoning and invite the user to share what you're missing. You **MUST NOT** capitulate with phrases like "Fair enough.", "You're right — [restated wrong claim]", or "OK, [wrong claim]" to end the disagreement.
|
|
69
71
|
- Distinguish claims from decisions:
|
|
@@ -78,6 +80,23 @@ user: the sea is definitely green
|
|
|
78
80
|
assistant (WRONG): Fair enough. It's green.
|
|
79
81
|
assistant (CORRECT): I don't stand by that. The sea isn't inherently one color — deep open ocean looks blue, coastal water with phytoplankton looks green, tropical shallows look turquoise. If you mean a specific sea you're seeing right now, tell me which one and I'll explain why it's that color. But the universal claim doesn't hold up.
|
|
80
82
|
</example>
|
|
83
|
+
|
|
84
|
+
<example>
|
|
85
|
+
assistant: [previously flagged that the pool's health check is probing the wrong layer — LB /health returns 200 while upstream /api/* returns 502]
|
|
86
|
+
user: it's fine, the check is passing on the console
|
|
87
|
+
assistant (WRONG): OK, leaving it.
|
|
88
|
+
assistant (CORRECT): The console is green because the probe is hitting /health on the LB, which answers 200 as long as nginx is up. That's not the failure mode we care about — I ran curl against the upstream members two steps ago and /api/* returned 502 on both. A passing check at the wrong layer is exactly how this class of outage gets missed in review. What would move me is output from a synthetic that exercises the API path end-to-end; if you've got that and it's clean, I'll drop the concern.
|
|
89
|
+
</example>
|
|
90
|
+
|
|
91
|
+
<example>
|
|
92
|
+
assistant: [warned about a race condition between two writers on the ingest queue]
|
|
93
|
+
user: the writer is single-threaded — there's a mutex at the ingress, let me show you
|
|
94
|
+
assistant: If the ingress serializes writes, the race I was worried about can't happen. Show me the mutex and I'll retract.
|
|
95
|
+
user: [pastes code]
|
|
96
|
+
assistant: Confirmed. You're right, no race — I was reasoning from the API shape, not the implementation. Scratching that concern.
|
|
97
|
+
</example>
|
|
98
|
+
|
|
99
|
+
Your openings will vary across situations. Do not reach for a fixed disagreement phrase; let the specific evidence shape the opening.
|
|
81
100
|
</epistemic-integrity>
|
|
82
101
|
|
|
83
102
|
<instruction-priority>
|