flavor-code 1.3.20 → 1.3.22

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.
@@ -38,7 +38,7 @@ import {
38
38
  useStdout,
39
39
  use_app_default,
40
40
  use_input_default
41
- } from "./chunk-3HWWQV2A.js";
41
+ } from "./chunk-SUSLIHXO.js";
42
42
  import "./chunk-OTYFL4AG.js";
43
43
  import {
44
44
  execFileNoThrow
@@ -612,6 +612,16 @@ function highlightCode(source, language = void 0) {
612
612
 
613
613
  // src/ui/markdown.tsx
614
614
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
615
+ var CODE_BLOCK_BORDER = {
616
+ top: "\u2500",
617
+ bottom: "\u2500",
618
+ left: " ",
619
+ right: " ",
620
+ topLeft: "\u256D",
621
+ topRight: "\u256E",
622
+ bottomLeft: "\u2570",
623
+ bottomRight: "\u256F"
624
+ };
615
625
  function MarkdownViewInner({ text }) {
616
626
  const stablePrefixRef = useRef2("");
617
627
  if (!text.startsWith(stablePrefixRef.current)) stablePrefixRef.current = "";
@@ -690,35 +700,29 @@ function HeadingView({ token }) {
690
700
  return /* @__PURE__ */ jsx(Text, { children: styled });
691
701
  }
692
702
  function CodeBlock({ token }) {
693
- const { stdout } = useStdout();
694
- const columns = stdout?.columns ?? 80;
695
- const innerWidth = Math.max(20, columns - 6);
696
703
  const styledSource = useMemo2(() => highlightCode(token.text, token.lang), [token.text, token.lang]);
697
704
  const lines = useMemo2(() => styledSource.split("\n"), [styledSource]);
698
- const truncated = useMemo2(() => lines.map((line) => truncateToWidth(line, innerWidth - 2)), [lines, innerWidth]);
699
705
  const langLabel = token.lang?.trim();
700
706
  const label = langLabel && langLabel.length > 0 ? langLabel : "code";
701
- const topBarWidth = Math.max(0, columns - 4 - label.length - 4);
702
707
  return (
703
- // Code blocks are self-contained painted regions. Marking the region
704
- // opaque prevents ScrollBox's incremental renderer from blitting cached
705
- // blank cells over clean, single-line code bodies during transcript
706
- // scrolls/redraws.
707
- /* @__PURE__ */ jsxs(Box_default, { flexDirection: "column", paddingX: 1, opaque: true, children: [
708
- /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
709
- "\u256D\u2500 ",
710
- /* @__PURE__ */ jsx(Text, { color: "cyan", children: label }),
711
- " ",
712
- "\u2500".repeat(topBarWidth),
713
- "\u256E"
714
- ] }),
715
- /* @__PURE__ */ jsx(Box_default, { flexDirection: "column", paddingX: 1, children: truncated.map((line, i) => /* @__PURE__ */ jsx(Text, { color: "gray", children: line }, i)) }),
716
- /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
717
- "\u2570",
718
- "\u2500".repeat(Math.max(0, columns - 6)),
719
- "\u256F"
720
- ] })
721
- ] })
708
+ // Let Yoga derive the border and text width from the actual parent box.
709
+ // A fenced block may be nested under list indentation, and terminal
710
+ // resizes can change that width without changing this memoized token.
711
+ // Building a line from process.stdout.columns overflows those narrower
712
+ // parents and desynchronizes the terminal's physical auto-wrap cursor.
713
+ /* @__PURE__ */ jsx(
714
+ Box_default,
715
+ {
716
+ flexDirection: "column",
717
+ width: "100%",
718
+ paddingX: 1,
719
+ borderStyle: CODE_BLOCK_BORDER,
720
+ borderColor: "gray",
721
+ borderText: { content: ` ${label} `, position: "top", align: "start", offset: 1 },
722
+ opaque: true,
723
+ children: /* @__PURE__ */ jsx(Box_default, { flexDirection: "column", paddingX: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx(Text, { color: "gray", wrap: "truncate-end", children: line.length > 0 ? line : " " }, i)) })
724
+ }
725
+ )
722
726
  );
723
727
  }
724
728
  function BlockquoteView({ token }) {
@@ -864,29 +868,6 @@ var ANSI_RE = /\x1B\[[0-?]*[ -/]*[@-~]/g;
864
868
  function stripAnsi2(value) {
865
869
  return value.replace(ANSI_RE, "");
866
870
  }
867
- function visibleWidth(value) {
868
- let width = 0;
869
- for (const ch of stripAnsi2(value)) {
870
- width += charWidth(ch.codePointAt(0) ?? 0);
871
- }
872
- return width;
873
- }
874
- function truncateToWidth(value, width) {
875
- if (width <= 0) return "";
876
- const stripped = stripAnsi2(value);
877
- if (visibleWidth(stripped) <= width) return value;
878
- const prefix = value.match(/^\x1B\[[0-?]*[ -/]*[@-~]*/)?.[0] ?? "";
879
- const suffix = "\x1B[0m";
880
- let out = "";
881
- let visual = 0;
882
- for (const ch of stripped) {
883
- const cw = charWidth(ch.codePointAt(0) ?? 0);
884
- if (visual + cw > width - 1) break;
885
- out += ch;
886
- visual += cw;
887
- }
888
- return prefix + out + "\u2026" + suffix;
889
- }
890
871
  function renderInlineText(tokens) {
891
872
  let out = "";
892
873
  for (const tok of tokens) {
@@ -1537,25 +1518,79 @@ ObjC.import("AppKit");
1537
1518
  ObjC.import("Foundation");
1538
1519
  ObjC.import("stdlib");
1539
1520
 
1540
- const pasteboard = $.NSPasteboard.generalPasteboard;
1541
- let data = pasteboard.dataForType($.NSPasteboardTypePNG);
1542
- if (!data) {
1543
- const tiff = pasteboard.dataForType($.NSPasteboardTypeTIFF);
1544
- if (tiff) {
1521
+ function isBridgeMethod(value, method) {
1522
+ return value !== null && value !== undefined
1523
+ && typeof value[method] === "function";
1524
+ }
1525
+
1526
+ function pngDataFromTiff(tiff) {
1527
+ if (!isBridgeMethod(tiff, "base64EncodedStringWithOptions")) {
1528
+ return null;
1529
+ }
1530
+ try {
1545
1531
  const representation = $.NSBitmapImageRep.imageRepWithData(tiff);
1546
- if (representation) {
1547
- data = representation.representationUsingTypeProperties(
1548
- $.NSBitmapImageFileTypePNG,
1549
- $({})
1550
- );
1532
+ if (!isBridgeMethod(representation, "representationUsingTypeProperties")) {
1533
+ return null;
1551
1534
  }
1535
+ const converted = representation.representationUsingTypeProperties(
1536
+ $.NSBitmapImageFileTypePNG,
1537
+ $({})
1538
+ );
1539
+ return isBridgeMethod(converted, "base64EncodedStringWithOptions")
1540
+ ? converted
1541
+ : null;
1542
+ } catch (error) {
1543
+ return null;
1552
1544
  }
1553
1545
  }
1554
- if (!data) {
1546
+
1547
+ function base64FromData(data) {
1548
+ if (!isBridgeMethod(data, "base64EncodedStringWithOptions")) {
1549
+ return null;
1550
+ }
1551
+ try {
1552
+ const encoded = data.base64EncodedStringWithOptions(0);
1553
+ if (!encoded) {
1554
+ return null;
1555
+ }
1556
+ const unwrapped = ObjC.unwrap(encoded);
1557
+ return typeof unwrapped === "string" && unwrapped.length > 0
1558
+ ? unwrapped
1559
+ : null;
1560
+ } catch (error) {
1561
+ return null;
1562
+ }
1563
+ }
1564
+
1565
+ try {
1566
+ const pasteboard = $.NSPasteboard.generalPasteboard;
1567
+ let encoded = null;
1568
+ if (isBridgeMethod(pasteboard, "dataForType")) {
1569
+ encoded = base64FromData(pasteboard.dataForType($.NSPasteboardTypePNG));
1570
+ if (!encoded) {
1571
+ encoded = base64FromData(
1572
+ pngDataFromTiff(pasteboard.dataForType($.NSPasteboardTypeTIFF))
1573
+ );
1574
+ }
1575
+ }
1576
+
1577
+ // Some macOS applications do not advertise a direct public.png or
1578
+ // public.tiff payload. NSImage can ask AppKit to read any image type the
1579
+ // pasteboard promises (for example PDF, HEIC, or a lazily supplied image),
1580
+ // after which TIFFRepresentation gives us a stable raster conversion path.
1581
+ if (!encoded) {
1582
+ const image = $.NSImage.alloc.initWithPasteboard(pasteboard);
1583
+ if (image !== null && image !== undefined) {
1584
+ encoded = base64FromData(pngDataFromTiff(image.TIFFRepresentation));
1585
+ }
1586
+ }
1587
+ if (!encoded) {
1588
+ $.exit(3);
1589
+ }
1590
+ console.log(encoded);
1591
+ } catch (error) {
1555
1592
  $.exit(3);
1556
1593
  }
1557
- const encoded = data.base64EncodedStringWithOptions(0);
1558
- console.log(ObjC.unwrap(encoded));
1559
1594
  `.trim();
1560
1595
  function shouldReadClipboardImage(input, key, isPasted) {
1561
1596
  return (key.ctrl || key.meta === true) && input.toLowerCase() === "v" || isPasted && input.length === 0;
@@ -34407,6 +34407,10 @@ var Ink = class {
34407
34407
  }
34408
34408
  if (this.currentNode !== null) {
34409
34409
  this.render(this.currentNode);
34410
+ if (this.rootNode.yogaNode?.getComputedWidth() !== this.terminalColumns) {
34411
+ this.rootNode.onComputeLayout?.();
34412
+ this.onRender();
34413
+ }
34410
34414
  }
34411
34415
  };
34412
34416
  resolveExitPromise = () => {
@@ -10,7 +10,7 @@ import {
10
10
  useStdout,
11
11
  use_app_default,
12
12
  use_input_default
13
- } from "./chunk-3HWWQV2A.js";
13
+ } from "./chunk-SUSLIHXO.js";
14
14
  import "./chunk-OTYFL4AG.js";
15
15
  import "./chunk-RQTYHUMK.js";
16
16
  import "./chunk-S32JRDZK.js";
package/dist/cli-main.js CHANGED
@@ -880,9 +880,9 @@ function createProgram(dependencies = {}) {
880
880
  }
881
881
  async function runInteractiveCli(props) {
882
882
  const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
883
- import("./claude-ink-3K3NG7BF.js"),
883
+ import("./claude-ink-6CEG2XZZ.js"),
884
884
  import("react"),
885
- import("./app-EGG3BYQQ.js")
885
+ import("./app-MWGRT3BJ.js")
886
886
  ]);
887
887
  const instance = await render(createElement(
888
888
  AlternateScreen,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flavor-code",
3
- "version": "1.3.20",
3
+ "version": "1.3.22",
4
4
  "author": "YachuanWzh",
5
5
  "type": "module",
6
6
  "publishConfig": {