@f5xc-salesdemos/xcsh 18.36.0 → 18.36.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": "18.36.0",
4
+ "version": "18.36.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",
@@ -48,12 +48,12 @@
48
48
  "dependencies": {
49
49
  "@agentclientprotocol/sdk": "0.16.1",
50
50
  "@mozilla/readability": "^0.6",
51
- "@f5xc-salesdemos/xcsh-stats": "18.36.0",
52
- "@f5xc-salesdemos/pi-agent-core": "18.36.0",
53
- "@f5xc-salesdemos/pi-ai": "18.36.0",
54
- "@f5xc-salesdemos/pi-natives": "18.36.0",
55
- "@f5xc-salesdemos/pi-tui": "18.36.0",
56
- "@f5xc-salesdemos/pi-utils": "18.36.0",
51
+ "@f5xc-salesdemos/xcsh-stats": "18.36.2",
52
+ "@f5xc-salesdemos/pi-agent-core": "18.36.2",
53
+ "@f5xc-salesdemos/pi-ai": "18.36.2",
54
+ "@f5xc-salesdemos/pi-natives": "18.36.2",
55
+ "@f5xc-salesdemos/pi-tui": "18.36.2",
56
+ "@f5xc-salesdemos/pi-utils": "18.36.2",
57
57
  "@sinclair/typebox": "^0.34",
58
58
  "@xterm/headless": "^6.0",
59
59
  "ajv": "^8.18",
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "18.36.0",
21
- "commit": "e184ba33c5bf2f52613a85f40b7ebd0d5043deb5",
22
- "shortCommit": "e184ba3",
20
+ "version": "18.36.2",
21
+ "commit": "bb67816d2bcb454ea8926788b836edae474dcec2",
22
+ "shortCommit": "bb67816",
23
23
  "branch": "main",
24
- "tag": "v18.36.0",
25
- "commitDate": "2026-05-04T03:30:53Z",
26
- "buildDate": "2026-05-04T03:50:55.993Z",
24
+ "tag": "v18.36.2",
25
+ "commitDate": "2026-05-04T05:42:12Z",
26
+ "buildDate": "2026-05-04T06:06:55.405Z",
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/e184ba33c5bf2f52613a85f40b7ebd0d5043deb5",
32
- "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.36.0"
31
+ "commitUrl": "https://github.com/f5xc-salesdemos/xcsh/commit/bb67816d2bcb454ea8926788b836edae474dcec2",
32
+ "releaseUrl": "https://github.com/f5xc-salesdemos/xcsh/releases/tag/v18.36.2"
33
33
  };
package/src/tools/bash.ts CHANGED
@@ -730,7 +730,12 @@ function getBashVerboseSetting(): boolean {
730
730
 
731
731
  export const bashToolRenderer = {
732
732
  renderCall(args: BashRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
733
- const summaryText = args.description ?? formatBashCommand(args);
733
+ let summaryText: string | undefined;
734
+ if (args.description) {
735
+ summaryText = args.description;
736
+ } else if (args.command) {
737
+ summaryText = formatBashCommand(args).replace(/\s*\\\r?\n\s*/g, " ");
738
+ }
734
739
  const text = renderStatusLine({ icon: "pending", title: "Bash", description: summaryText }, uiTheme);
735
740
  return new Text(text, 0, 0);
736
741
  },
@@ -773,9 +778,8 @@ export const bashToolRenderer = {
773
778
  const hasAsyncDetails = details?.async != null;
774
779
  const forceExpand = isError || hasAsyncDetails || hasSixelOutput;
775
780
  if (!verbose && !expanded && !forceExpand) {
776
- const rawCmd = args?.command;
777
- const summaryText =
778
- args?.description ?? (rawCmd && rawCmd.length > 60 ? `${rawCmd.slice(0, 60)}…` : rawCmd) ?? "…";
781
+ const rawCmd = args?.command?.replace(/\s*\\\r?\n\s*/g, " ");
782
+ const summaryText = args?.description ?? rawCmd ?? undefined;
779
783
 
780
784
  if (options.isPartial) {
781
785
  const lineCount = rawOutputLines.filter(l => l.trim().length > 0).length;
@@ -46,7 +46,9 @@ export async function checkAuth(pi: GlabExecApi): Promise<boolean> {
46
46
 
47
47
  export async function execGlab(pi: GlabExecApi, args: string[], signal?: AbortSignal): Promise<GlabExecResult> {
48
48
  const result = await pi.exec("glab", args, { signal, cwd: pi.cwd });
49
- if (result.killed) throw new Error("Command was cancelled");
49
+ // Bun.spawn sets killed=true even on successful exits — only treat as
50
+ // cancelled when killed AND no stdout was captured (actual signal kill).
51
+ if (result.killed && !result.stdout && result.code !== 0) throw new Error("Command was cancelled");
50
52
  if (result.code !== 0) {
51
53
  const stderr = result.stderr.toLowerCase();
52
54
  if (stderr.includes("auth") || stderr.includes("not logged in") || stderr.includes("token")) {
package/src/tools/glab.ts CHANGED
@@ -23,12 +23,18 @@ function makeExecApi(cwd: string): GlabExecApi {
23
23
  return {
24
24
  cwd,
25
25
  async exec(command: string, args: string[], options?: { signal?: AbortSignal; cwd?: string }) {
26
+ // Check abort before spawning, but do NOT pass signal to Bun.spawn.
27
+ // glab commands complete in <1s — passing the signal causes a race where
28
+ // xcsh's AbortSignal fires (e.g. on model completion) and kills the child
29
+ // process before we can read its output.
30
+ if (options?.signal?.aborted) {
31
+ return { stdout: "", stderr: "Command was cancelled before starting", code: 1, killed: true };
32
+ }
26
33
  const child = Bun.spawn([command, ...args], {
27
34
  cwd: options?.cwd ?? cwd,
28
35
  stdin: "ignore",
29
36
  stdout: "pipe",
30
37
  stderr: "pipe",
31
- signal: options?.signal,
32
38
  });
33
39
  if (!child.stdout || !child.stderr) {
34
40
  return { stdout: "", stderr: "Failed to capture output", code: 1, killed: false };
@@ -245,8 +251,7 @@ export class GlabIssueListTool implements AgentTool<typeof glabIssueListSchema,
245
251
  }
246
252
 
247
253
  const args = ["issue", "list", "--output", "json", "--repo", project];
248
- if (params.state === "opened") args.push("--opened");
249
- else if (params.state === "closed") args.push("--closed");
254
+ if (params.state === "closed") args.push("--closed");
250
255
  else if (params.state === "all") args.push("--all");
251
256
  if (params.labels?.length) args.push("--label", params.labels.join(","));
252
257
  if (params.assignee) args.push("--assignee", params.assignee);
@@ -351,8 +356,7 @@ export class GlabSearchTool implements AgentTool<typeof glabSearchSchema, GlabTo
351
356
  "--per-page",
352
357
  String(limit),
353
358
  ];
354
- if (params.state === "opened") restArgs.push("--opened");
355
- else if (params.state === "closed") restArgs.push("--closed");
359
+ if (params.state === "closed") restArgs.push("--closed");
356
360
  else if (params.state === "all") restArgs.push("--all");
357
361
  if (params.labels?.length) restArgs.push("--label", params.labels.join(","));
358
362
 
@@ -95,7 +95,9 @@ export class XcshApiTool implements AgentTool<typeof xcshApiSchema, XcshApiToolD
95
95
 
96
96
  try {
97
97
  const response = await fetch(url, init);
98
- const bodyText = await response.text();
98
+ const raw = await response.text();
99
+ const contentType = response.headers.get("content-type") ?? "";
100
+ const bodyText = contentType.includes("application/json") ? JSON.stringify(JSON.parse(raw)) : raw;
99
101
  const statusLine = `${response.status} ${response.statusText}`;
100
102
 
101
103
  return {