@f5xc-salesdemos/xcsh 18.5.0 → 18.5.1

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.5.0",
4
+ "version": "18.5.1",
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.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",
50
+ "@f5xc-salesdemos/xcsh-stats": "18.5.1",
51
+ "@f5xc-salesdemos/pi-agent-core": "18.5.1",
52
+ "@f5xc-salesdemos/pi-ai": "18.5.1",
53
+ "@f5xc-salesdemos/pi-natives": "18.5.1",
54
+ "@f5xc-salesdemos/pi-tui": "18.5.1",
55
+ "@f5xc-salesdemos/pi-utils": "18.5.1",
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.5.0",
21
- "commit": "50d87af3879c08179ba1f0bb790ec3928c3b41ea",
22
- "shortCommit": "50d87af",
20
+ "version": "18.5.1",
21
+ "commit": "2a2609d390a936b17a34ca06aa955b347715d133",
22
+ "shortCommit": "2a2609d",
23
23
  "branch": "main",
24
- "tag": "v18.5.0",
25
- "commitDate": "2026-04-21T07:29:16Z",
26
- "buildDate": "2026-04-21T07:56:37.534Z",
24
+ "tag": "v18.5.1",
25
+ "commitDate": "2026-04-21T18:42:07Z",
26
+ "buildDate": "2026-04-21T19:21:35.113Z",
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/50d87af3879c08179ba1f0bb790ec3928c3b41ea",
32
- "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.5.0"
31
+ "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/2a2609d390a936b17a34ca06aa955b347715d133",
32
+ "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.5.1"
33
33
  };
@@ -7,16 +7,22 @@ const CONTINUATION_BAR = "┃";
7
7
  // render output is 3 terminal cells. Anything narrower than prefix+3 would
8
8
  // overflow the requested width — bail out instead.
9
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.
10
+ // Two-column layout: the gutter (col 0..GUTTER_WIDTH-1) stays outside the
11
+ // userMessageBg painted region and holds the π icon on the first content
12
+ // line / two spaces on continuations — mirroring how GutterBlock renders
13
+ // its ● indicator at col 0. The painted region starts at col GUTTER_WIDTH
14
+ // and hosts the ┃ accent bar on every content line (including the first).
12
15
  const GUTTER_WIDTH = 2;
13
16
  const GUTTER_PAD = " ";
14
17
 
15
18
  /**
16
- * Renders a user message as an F5-branded admonition block: pi icon on the
17
- * first content line, heavy vertical bar on continuations (both in `border`
18
- * color), `userMessageBg` painted across the full requested width, and a
19
- * leading blank spacer separating the prompt from the preceding block.
19
+ * Renders a user message as an F5-branded admonition block with a two-column
20
+ * layout: the π icon sits in the gutter at col 0 on the first content line
21
+ * (outside the painted region, matching the `●` indicator pattern used by
22
+ * `GutterBlock`); the heavy vertical bar renders at col GUTTER_WIDTH inside
23
+ * `userMessageBg` on every content line including the first. Both glyphs use
24
+ * the `border` fg. The bg is painted across the full requested width, and a
25
+ * leading blank spacer separates the prompt from the preceding block.
20
26
  */
21
27
  export class UserMessageComponent extends Container {
22
28
  constructor(text: string, synthetic = false) {
@@ -29,13 +35,10 @@ export class UserMessageComponent extends Container {
29
35
  }
30
36
 
31
37
  override render(width: number): string[] {
32
- const piPrefix = `${theme.icon.pi} `;
33
38
  const contPrefix = `${CONTINUATION_BAR} `;
34
- // Prefix width is theme-dependent Unicode π is 1 col, Nerd Font
35
- // glyph and ASCII "pi" are 2 cols. Measure both and reserve the
36
- // larger so every content line leaves room for either shape.
37
- const prefixWidth = Math.max(visibleWidth(piPrefix), visibleWidth(contPrefix));
38
- const innerWidth = width - GUTTER_WIDTH - prefixWidth;
39
+ // π lives in the fixed-width gutter (see the content map below), so it
40
+ // does not factor into innerWidth. Only contPrefix eats content budget.
41
+ const innerWidth = width - GUTTER_WIDTH - visibleWidth(contPrefix);
39
42
  if (innerWidth < MIN_MARKDOWN_WIDTH) {
40
43
  return [];
41
44
  }
@@ -52,12 +55,25 @@ export class UserMessageComponent extends Container {
52
55
  return raw;
53
56
  }
54
57
 
58
+ // First-line gutter: π icon padded to exactly GUTTER_WIDTH cells. The
59
+ // glyph width is theme-dependent (Unicode π = 1 col, Nerd Font PUA = 2
60
+ // cols, ASCII "pi" = 2 cols); right-pad with spaces so the gutter
61
+ // occupies a fixed slot and the ┃ bar at col GUTTER_WIDTH aligns across
62
+ // every content line.
63
+ const piIcon = theme.icon.pi;
64
+ const piPadSize = Math.max(0, GUTTER_WIDTH - visibleWidth(piIcon));
65
+ // Pad inside the theme.fg wrap so the border-fg escape, glyph, and
66
+ // pad space form one contiguous span (no intervening fg reset). This
67
+ // matches the shape the raw-escape assertion in test 6 looks for.
68
+ const piGutter = theme.fg("border", piIcon + " ".repeat(piPadSize));
69
+
55
70
  const leading = raw.slice(0, firstContent);
56
71
  const content = raw.slice(firstContent).map((line, i) => {
57
- const prefix = theme.fg("border", i === 0 ? piPrefix : contPrefix);
72
+ const prefix = theme.fg("border", contPrefix);
58
73
  const combined = prefix + line;
59
74
  const pad = Math.max(0, width - GUTTER_WIDTH - visibleWidth(combined));
60
- return GUTTER_PAD + theme.bg("userMessageBg", combined + padding(pad));
75
+ const gutter = i === 0 ? piGutter : GUTTER_PAD;
76
+ return gutter + theme.bg("userMessageBg", combined + padding(pad));
61
77
  });
62
78
 
63
79
  return [...leading, ...content];