omp-fabric 1.25.20 → 1.25.21

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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.25.21
4
+
5
+ ### Fixed
6
+
7
+ - **Truncation marker no longer leaks raw JSON into the TUI.** `[[omp-fabric:truncated]]` payloads are now parsed by a host-free `src/core/truncation-marker.ts` and rendered as a styled `output truncated` arc badge at the read, grep, path-list, bash, and non-core `renderBody` sites.
8
+ - **Failed results carry visual weight.** Bash bodies and call titles show a `failed` arc badge with the exit code when `success === false`, in addition to the existing error-colored lines.
9
+ - **Long bash titles stay on one screen.** The title's first command line caps at 120 characters with an ellipsis; the full line is still reachable in the expanded body.
10
+ - **Expanded multicall rows gain a status-colored gutter.** Success, running, and failed rows each get their own gutter color; collapsed rows stay flat and all rows remain width-bounded.
11
+
3
12
  ## 1.25.20
4
13
 
5
14
  ### Changed
@@ -4,8 +4,9 @@ import {
4
4
  isFabricAgentToolPreview,
5
5
  selectPreviewTextLines,
6
6
  shouldSkipWriteDiffBytes,
7
- shouldSkipWriteDiffComplexity
8
- } from "./chunk-WQUMHDOS.js";
7
+ shouldSkipWriteDiffComplexity,
8
+ splitTruncationNotice
9
+ } from "./chunk-ESPCTYVX.js";
9
10
  import {
10
11
  countNewlines,
11
12
  resolveShikiTheme
@@ -2744,6 +2745,17 @@ var CONTENT_LANGUAGE_DETECTION_CHARS = positiveEnvInteger(
2744
2745
  "CODE_PREVIEW_CONTENT_LANGUAGE_DETECTION_CHARS",
2745
2746
  5e4
2746
2747
  );
2748
+ var bashExitCode = (audit) => {
2749
+ const value = resultDetails(audit)?.exitCode;
2750
+ return typeof value === "number" && Number.isSafeInteger(value) && value !== 0 ? value : void 0;
2751
+ };
2752
+ var bashFailureArc = (audit, theme) => {
2753
+ if (audit.success !== false) return null;
2754
+ const exitCode = bashExitCode(audit);
2755
+ return arcItemStyled(theme, theme.fg("error", exitCode === void 0 ? "failed" : `failed \xB7 exit ${exitCode}`));
2756
+ };
2757
+ var BASH_TITLE_COMMAND_CHARS = 120;
2758
+ var truncateBashTitleCommand = (line) => line.length <= BASH_TITLE_COMMAND_CHARS ? line : `${line.slice(0, BASH_TITLE_COMMAND_CHARS - 1)}\u2026`;
2747
2759
  var recordOf = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
2748
2760
  var stringOf = (value) => typeof value === "string" ? value : void 0;
2749
2761
  var numberOf = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
@@ -2796,6 +2808,12 @@ var resultOutput = (audit) => {
2796
2808
  const record = recordOf(result);
2797
2809
  return stringOf(record?.output) ?? stringOf(record?.text) ?? contentOutput(record?.content);
2798
2810
  };
2811
+ var stripTruncationNotice = (value) => {
2812
+ const notice = splitTruncationNotice(value);
2813
+ if (!notice) return { output: value };
2814
+ const trimmed = notice.text.endsWith("\n") ? notice.text.slice(0, -1) : notice.text;
2815
+ return { output: trimmed, badge: notice.label };
2816
+ };
2799
2817
  var resultDetails = (audit) => {
2800
2818
  const preview = recordOf(audit.preview);
2801
2819
  const previewDetails = recordOf(preview?.details);
@@ -3409,8 +3427,9 @@ var renderDiff = (diff, filePath, theme, options, limitOverride) => {
3409
3427
  };
3410
3428
  var renderRead = (audit, theme, options) => {
3411
3429
  if (!options.expanded && !options.settings.readContentPreview) return null;
3412
- const output = resultOutput(audit);
3413
- if (output === void 0) return null;
3430
+ const raw = resultOutput(audit);
3431
+ if (raw === void 0) return null;
3432
+ const { output, badge } = stripTruncationNotice(raw);
3414
3433
  const filePath = argString(audit, "path") ?? "";
3415
3434
  if (/^Read image file/i.test(output)) {
3416
3435
  return { lines: [theme.fg("dim", escapeControlChars3(output))], hidden: 0 };
@@ -3425,6 +3444,7 @@ var renderRead = (audit, theme, options) => {
3425
3444
  });
3426
3445
  if (notice) pushArcItem(rendered.lines, arcItem(theme, notice));
3427
3446
  else if (truncated) pushArcItem(rendered.lines, arcItem(theme, "Output truncated by read"));
3447
+ if (badge) pushArcItem(rendered.lines, arcItem(theme, badge));
3428
3448
  return rendered;
3429
3449
  };
3430
3450
  var getWriteBefore = (audit) => {
@@ -3628,7 +3648,7 @@ var renderGrepRowLine = (row, highlighted, audit, theme) => {
3628
3648
  };
3629
3649
  var renderGrep = (audit, theme, options) => {
3630
3650
  if (!options.expanded && !options.settings.grepResultPreview) return null;
3631
- const output = resultOutput(audit)?.replace(/\r?\n$/, "");
3651
+ const { output, badge } = stripTruncationNotice(resultOutput(audit) ?? "");
3632
3652
  if (!output || output === "No matches found") {
3633
3653
  return { lines: [theme.fg("muted", output || "No matches found")], hidden: 0 };
3634
3654
  }
@@ -3684,6 +3704,7 @@ var renderGrep = (audit, theme, options) => {
3684
3704
  if (skipHighlight) {
3685
3705
  pushArcItem(lines, arcItem(theme, "Syntax highlighting skipped for large grep output"));
3686
3706
  }
3707
+ if (badge) pushArcItem(lines, arcItem(theme, badge));
3687
3708
  return { lines, hidden: selected.hidden };
3688
3709
  };
3689
3710
  var NERD_BY_NAME = {
@@ -3738,7 +3759,7 @@ var pathIcon = (filePath, directory, mode) => {
3738
3759
  var renderPathList = (audit, theme, options) => {
3739
3760
  const enabled2 = audit.tool === "find" ? options.settings.findResultPreview : options.settings.lsResultPreview;
3740
3761
  if (!options.expanded && !enabled2) return null;
3741
- const output = resultOutput(audit)?.replace(/\r?\n$/, "") ?? "";
3762
+ const { output, badge } = stripTruncationNotice(resultOutput(audit) ?? "");
3742
3763
  const emptyMarker = audit.tool === "find" ? "No files found matching pattern" : "(empty directory)";
3743
3764
  if (!output || output === emptyMarker) {
3744
3765
  return {
@@ -3810,6 +3831,7 @@ var renderPathList = (audit, theme, options) => {
3810
3831
  }
3811
3832
  }
3812
3833
  flush();
3834
+ if (badge) pushArcItem(lines, arcItem(theme, badge));
3813
3835
  return { lines, hidden: selected.hidden };
3814
3836
  };
3815
3837
  var renderBash = (audit, theme, options) => {
@@ -3819,19 +3841,25 @@ var renderBash = (audit, theme, options) => {
3819
3841
  const command = bashCommand(audit);
3820
3842
  const displayCommand = escapeControlChars3(command.replace(/\r\n/g, "\n"));
3821
3843
  const commandLines = displayCommand.split("\n");
3844
+ const showFirstCommandLine = options.expanded;
3822
3845
  const highlightedCommand = command ? highlightCode(
3823
3846
  displayCommand,
3824
3847
  "bash",
3825
3848
  options.invalidate
3826
3849
  ) : null;
3827
- const lines = commandLines.slice(1).map(
3828
- (line, index) => `${theme.fg("dim", " ")}${highlightedCommand?.[index + 1] ?? theme.fg("accent", line)}`
3850
+ const bodyCommandLines = showFirstCommandLine ? commandLines : commandLines.slice(1);
3851
+ const highlightOffset = showFirstCommandLine ? 0 : 1;
3852
+ const lines = bodyCommandLines.map(
3853
+ (line, index) => `${theme.fg("dim", " ")}${highlightedCommand?.[index + highlightOffset] ?? theme.fg("accent", line)}`
3829
3854
  );
3830
- const output = resultOutput(audit)?.replace(/\r?\n$/, "") ?? "";
3855
+ const { output, badge } = stripTruncationNotice(resultOutput(audit) ?? "");
3831
3856
  if (!output || output === "(no output)") {
3832
3857
  if (!output && audit.fromTrace) {
3833
3858
  return { lines: [...lines, theme.fg("dim", "output not retained across reload")], hidden: 0 };
3834
3859
  }
3860
+ const failure2 = bashFailureArc(audit, theme);
3861
+ if (failure2) pushArcItem(lines, failure2);
3862
+ if (badge) pushArcItem(lines, arcItem(theme, badge));
3835
3863
  return {
3836
3864
  lines: [...lines, theme.fg("muted", output || "No output")],
3837
3865
  hidden: 0
@@ -3849,9 +3877,12 @@ var renderBash = (audit, theme, options) => {
3849
3877
  const text = theme.fg(audit.success === false ? "error" : "muted", escapeControlChars3(entry.line) || " ");
3850
3878
  lines.push(text);
3851
3879
  }
3880
+ const failure = bashFailureArc(audit, theme);
3881
+ if (failure) pushArcItem(lines, failure);
3852
3882
  if (nativeTruncated(audit)) {
3853
3883
  pushArcItem(lines, arcItem(theme, `Output truncated by ${audit.tool ?? "shell"}`));
3854
3884
  }
3885
+ if (badge) pushArcItem(lines, arcItem(theme, badge));
3855
3886
  const fullOutputPath = stringOf(resultDetails(audit)?.fullOutputPath);
3856
3887
  if (fullOutputPath) pushArcItem(lines, arcItem(theme, `Full output: ${escapeControlChars3(fullOutputPath)}`));
3857
3888
  return { lines, hidden: selected.hidden };
@@ -3915,7 +3946,7 @@ var coreToolTitle = (audit, theme, options) => {
3915
3946
  const filePath = argString(audit, "path") ?? "";
3916
3947
  if (audit.tool === "bash") {
3917
3948
  const command = bashCommand(audit);
3918
- const firstLine = command.split("\n")[0] ?? "";
3949
+ const firstLine = truncateBashTitleCommand(command.split("\n")[0] ?? "");
3919
3950
  const language = "bash";
3920
3951
  const highlighted = firstLine ? highlightCode(firstLine, language, options.invalidate)?.[0] : void 0;
3921
3952
  const timeout = numberOf(audit.args?.timeout);
@@ -4457,6 +4488,20 @@ var callHeadlinePreview = (audit) => {
4457
4488
  const args = audit.args ?? {};
4458
4489
  return providerCallDetail(provider, tool, args, audit.result, audit.preview) || headlineArg(args) || structuralCallDetail(provider, tool, args, audit.result);
4459
4490
  };
4491
+ var resultDetailsOf = (audit) => {
4492
+ const preview = audit.preview;
4493
+ if (typeof preview === "object" && preview !== null) {
4494
+ const details = preview.details;
4495
+ if (typeof details === "object" && details !== null) return details;
4496
+ }
4497
+ const result = audit.result;
4498
+ if (typeof result === "object" && result !== null) {
4499
+ const details = result.details;
4500
+ if (typeof details === "object" && details !== null) return details;
4501
+ }
4502
+ return void 0;
4503
+ };
4504
+ var finiteExitCode = (value) => typeof value === "number" && Number.isSafeInteger(value) && value !== 0 ? value : void 0;
4460
4505
  var nestedResultTruncated = (audit) => {
4461
4506
  if (audit.resultTruncated === true) return true;
4462
4507
  const result = audit.result;
@@ -4469,7 +4514,13 @@ var nestedResultTruncated = (audit) => {
4469
4514
  };
4470
4515
  function nestedCallTitle(audit, theme, invalidate, core) {
4471
4516
  const title = nestedCallTitleText(audit, theme, invalidate, core);
4472
- return nestedResultTruncated(audit) ? `${title} ${theme.fg("warning", "\xB7 truncated")}` : title;
4517
+ const markers = [];
4518
+ if (audit.success === false) {
4519
+ const exitCode = finiteExitCode(resultDetailsOf(audit)?.exitCode);
4520
+ markers.push(theme.fg("error", exitCode === void 0 ? "\xB7 failed" : `\xB7 failed \xB7 exit ${exitCode}`));
4521
+ }
4522
+ if (nestedResultTruncated(audit)) markers.push(theme.fg("warning", "\xB7 truncated"));
4523
+ return markers.length > 0 ? `${title} ${markers.join(" ")}` : title;
4473
4524
  }
4474
4525
  var nestedCallTitleText = (audit, theme, invalidate, core) => {
4475
4526
  const coreTitle = core ? coreToolTitle(audit, theme, { ...core, ...invalidate ? { invalidate } : {} }) : null;
@@ -4669,26 +4720,28 @@ var renderFabricMulticallPartial = (input, theme, invalidate) => {
4669
4720
  core: input.core,
4670
4721
  ...invalidate ? { invalidate } : {}
4671
4722
  });
4723
+ const gutterColor = audit.success === false ? "error" : audit.success === void 0 ? "warning" : "success";
4724
+ const gutter = theme.fg(gutterColor, "\u2502");
4725
+ const withGutter = (row) => `${gutter} ${row}`;
4672
4726
  let callRow = `${glyph} ${nestedCallTitle(audit, theme, invalidate, input.core)}`;
4673
4727
  if (audit.success === false && audit.error) {
4674
4728
  callRow += ` ${theme.fg("dim", "\u203A")} ${theme.fg("error", truncateOneLine(safeTerminalText(audit.error), 240))}`;
4675
4729
  } else if (previewLines[0]) {
4676
4730
  callRow += ` ${previewLines[0]}`;
4677
4731
  }
4678
- rows.push(callRow);
4732
+ rows.push(input.expanded ? withGutter(callRow) : callRow);
4679
4733
  if (audit.success !== false && input.preview?.auditIndex === auditIndex) {
4680
- for (const line of input.preview.body.split("\n")) rows.push(` ${line}`);
4734
+ for (const line of input.preview.body.split("\n")) rows.push(input.expanded ? withGutter(` ${line}`) : ` ${line}`);
4681
4735
  if (input.preview.hidden > 0) {
4682
- rows.push(
4683
- theme.fg(
4684
- "dim",
4685
- ` \u2026 ${input.preview.hidden} more ${input.preview.hidden === 1 ? "line" : "lines"}`
4686
- )
4736
+ const moreRow = theme.fg(
4737
+ "dim",
4738
+ ` \u2026 ${input.preview.hidden} more ${input.preview.hidden === 1 ? "line" : "lines"}`
4687
4739
  );
4740
+ rows.push(input.expanded ? withGutter(moreRow) : moreRow);
4688
4741
  }
4689
4742
  }
4690
4743
  if (audit.success !== false && previewLines.length > 1) {
4691
- for (const line of previewLines.slice(1)) rows.push(line);
4744
+ for (const line of previewLines.slice(1)) rows.push(input.expanded ? withGutter(line) : line);
4692
4745
  }
4693
4746
  }
4694
4747
  const callsHidden = input.audits.length - callsShown.length;
@@ -5030,4 +5083,4 @@ export {
5030
5083
  formatJsonAsYaml,
5031
5084
  formatFabricValue
5032
5085
  };
5033
- //# sourceMappingURL=chunk-5SSQD7TW.js.map
5086
+ //# sourceMappingURL=chunk-7NWMFYD3.js.map