diff --git a/package-lock.json b/package-lock.json
index f3bf8fa616..ea985a7be0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
"packages/*"
],
"dependencies": {
- "ink": "npm:@jrichman/ink@6.5.0",
+ "ink": "npm:@jrichman/ink@6.6.3",
"latest-version": "^9.0.0",
"node-fetch-native": "^1.6.7",
"proper-lockfile": "^4.1.2",
@@ -92,46 +92,6 @@
"zod": "^3.25.0 || ^4.0.0"
}
},
- "node_modules/@alcalzone/ansi-tokenize": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.2.2.tgz",
- "integrity": "sha512-mkOh+Wwawzuf5wa30bvc4nA+Qb6DIrGWgBhRR/Pw4T9nsgYait8izvXkNyU78D6Wcu3Z+KUdwCmLCxlWjEotYA==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^6.2.1",
- "is-fullwidth-code-point": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@alcalzone/ansi-tokenize/node_modules/ansi-styles": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
- "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@alcalzone/ansi-tokenize/node_modules/is-fullwidth-code-point": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
- "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
- "license": "MIT",
- "dependencies": {
- "get-east-asian-width": "^1.3.1"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -10089,14 +10049,13 @@
},
"node_modules/ink": {
"name": "@jrichman/ink",
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/@jrichman/ink/-/ink-6.5.0.tgz",
- "integrity": "sha512-S4g/ng7fPZmFwclO82iWkOce8vDLy/FIDgHIfkCWGOehqHe6dexHsmq3kNQD21okh198pA5SAQTCqNQJb/svRQ==",
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/@jrichman/ink/-/ink-6.6.3.tgz",
+ "integrity": "sha512-0v4S7TbbF2tpQrfqH1btwLgTgH+K0vY2BJbokTE5Lk1KBr4TqZ+Pyo+geSD5F+zytX6G2ajGHBQyHk8yGK4C7A==",
"license": "MIT",
"dependencies": {
- "@alcalzone/ansi-tokenize": "^0.2.1",
"ansi-escapes": "^7.0.0",
- "ansi-styles": "^6.2.1",
+ "ansi-styles": "^6.2.3",
"auto-bind": "^5.0.1",
"chalk": "^5.6.0",
"cli-boxes": "^3.0.0",
@@ -10105,6 +10064,7 @@
"code-excerpt": "^4.0.0",
"es-toolkit": "^1.39.10",
"indent-string": "^5.0.0",
+ "is-fullwidth-code-point": "^5.0.0",
"is-in-ci": "^2.0.0",
"mnemonist": "^0.40.3",
"patch-console": "^2.0.0",
@@ -10174,9 +10134,9 @@
}
},
"node_modules/ink/node_modules/ansi-styles": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
- "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -10197,6 +10157,21 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/ink/node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/ink/node_modules/is-in-ci": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-in-ci/-/is-in-ci-2.0.0.tgz",
@@ -17551,7 +17526,7 @@
"fzf": "^0.5.2",
"glob": "^12.0.0",
"highlight.js": "^11.11.1",
- "ink": "npm:@jrichman/ink@6.5.0",
+ "ink": "npm:@jrichman/ink@6.6.3",
"ink-gradient": "^3.0.0",
"ink-spinner": "^5.0.0",
"latest-version": "^9.0.0",
diff --git a/package.json b/package.json
index 8bb5f25e20..cb4b743336 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,7 @@
"pre-commit": "node scripts/pre-commit.js"
},
"overrides": {
- "ink": "npm:@jrichman/ink@6.5.0",
+ "ink": "npm:@jrichman/ink@6.6.3",
"wrap-ansi": "9.0.2",
"cliui": {
"wrap-ansi": "7.0.0"
@@ -136,7 +136,7 @@
"yargs": "^17.7.2"
},
"dependencies": {
- "ink": "npm:@jrichman/ink@6.5.0",
+ "ink": "npm:@jrichman/ink@6.6.3",
"latest-version": "^9.0.0",
"node-fetch-native": "^1.6.7",
"proper-lockfile": "^4.1.2",
diff --git a/packages/cli/package.json b/packages/cli/package.json
index 072f2b8a72..95a570bf58 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -49,7 +49,7 @@
"fzf": "^0.5.2",
"glob": "^12.0.0",
"highlight.js": "^11.11.1",
- "ink": "npm:@jrichman/ink@6.5.0",
+ "ink": "npm:@jrichman/ink@6.6.3",
"ink-gradient": "^3.0.0",
"ink-spinner": "^5.0.0",
"latest-version": "^9.0.0",
diff --git a/packages/cli/src/ui/components/InputPrompt.test.tsx b/packages/cli/src/ui/components/InputPrompt.test.tsx
index 626f4fa61e..49dd08ac53 100644
--- a/packages/cli/src/ui/components/InputPrompt.test.tsx
+++ b/packages/cli/src/ui/components/InputPrompt.test.tsx
@@ -2222,85 +2222,67 @@ describe('InputPrompt', () => {
name: 'mid-word',
text: 'hello world',
visualCursor: [0, 3],
- expected: `hel${chalk.inverse('l')}o world`,
},
{
name: 'at the beginning of the line',
text: 'hello',
visualCursor: [0, 0],
- expected: `${chalk.inverse('h')}ello`,
},
{
name: 'at the end of the line',
text: 'hello',
visualCursor: [0, 5],
- expected: `hello${chalk.inverse(' ')}`,
},
{
name: 'on a highlighted token',
text: 'run @path/to/file',
visualCursor: [0, 9],
- expected: `@path/${chalk.inverse('t')}o/file`,
},
{
name: 'for multi-byte unicode characters',
text: 'hello π world',
visualCursor: [0, 6],
- expected: `hello ${chalk.inverse('π')} world`,
},
{
name: 'after multi-byte unicode characters',
text: 'πA',
visualCursor: [0, 1],
- expected: `π${chalk.inverse('A')}`,
},
{
name: 'at the end of a line with unicode characters',
text: 'hello π',
visualCursor: [0, 8],
- expected: `hello π`, // skip checking inverse ansi due to ink truncation bug
},
{
name: 'at the end of a short line with unicode characters',
text: 'π',
visualCursor: [0, 1],
- expected: `π${chalk.inverse(' ')}`,
},
{
name: 'on an empty line',
text: '',
visualCursor: [0, 0],
- expected: chalk.inverse(' '),
},
{
name: 'on a space between words',
text: 'hello world',
visualCursor: [0, 5],
- expected: `hello${chalk.inverse(' ')}world`,
},
])(
'should display cursor correctly $name',
- async ({ name, text, visualCursor, expected }) => {
+ async ({ text, visualCursor }) => {
mockBuffer.text = text;
mockBuffer.lines = [text];
mockBuffer.viewportVisualLines = [text];
mockBuffer.visualCursor = visualCursor as [number, number];
props.config.getUseBackgroundColor = () => false;
- const { stdout, unmount } = await renderWithProviders(
+ const renderResult = await renderWithProviders(
,
);
- await waitFor(() => {
- const frame = stdout.lastFrameRaw();
- expect(stripAnsi(frame)).toContain(stripAnsi(expected));
- if (
- name !== 'at the end of a line with unicode characters' &&
- name !== 'on a highlighted token'
- ) {
- expect(frame).toContain('\u001b[7m');
- }
- });
- unmount();
+ await renderResult.waitUntilReady();
+ await expect(renderResult).toMatchSvgSnapshot();
+ renderResult.unmount();
},
);
});
@@ -2316,7 +2298,6 @@ describe('InputPrompt', () => {
[1, 0],
[2, 0],
],
- expected: `sec${chalk.inverse('o')}nd line`,
},
{
name: 'at the beginning of a line',
@@ -2326,7 +2307,6 @@ describe('InputPrompt', () => {
[0, 0],
[1, 0],
],
- expected: `${chalk.inverse('s')}econd line`,
},
{
name: 'at the end of a line',
@@ -2336,11 +2316,10 @@ describe('InputPrompt', () => {
[0, 0],
[1, 0],
],
- expected: `first line${chalk.inverse(' ')}`,
},
])(
'should display cursor correctly $name in a multiline block',
- async ({ name, text, visualCursor, expected, visualToLogicalMap }) => {
+ async ({ text, visualCursor, visualToLogicalMap }) => {
mockBuffer.text = text;
mockBuffer.lines = text.split('\n');
mockBuffer.viewportVisualLines = text.split('\n');
@@ -2350,20 +2329,12 @@ describe('InputPrompt', () => {
>;
props.config.getUseBackgroundColor = () => false;
- const { stdout, unmount } = await renderWithProviders(
+ const renderResult = await renderWithProviders(
,
);
- await waitFor(() => {
- const frame = stdout.lastFrameRaw();
- expect(stripAnsi(frame)).toContain(stripAnsi(expected));
- if (
- name !== 'at the end of a line with unicode characters' &&
- name !== 'on a highlighted token'
- ) {
- expect(frame).toContain('\u001b[7m');
- }
- });
- unmount();
+ await renderResult.waitUntilReady();
+ await expect(renderResult).toMatchSvgSnapshot();
+ renderResult.unmount();
},
);
@@ -2380,18 +2351,12 @@ describe('InputPrompt', () => {
];
props.config.getUseBackgroundColor = () => false;
- const { stdout, unmount } = await renderWithProviders(
+ const renderResult = await renderWithProviders(
,
);
- await waitFor(() => {
- const frame = stdout.lastFrameRaw();
- const lines = frame.split('\n');
- // The line with the cursor should just be an inverted space inside the box border
- expect(
- lines.find((l) => l.includes(chalk.inverse(' '))),
- ).not.toBeUndefined();
- });
- unmount();
+ await renderResult.waitUntilReady();
+ await expect(renderResult).toMatchSvgSnapshot();
+ renderResult.unmount();
});
});
});
@@ -2412,22 +2377,14 @@ describe('InputPrompt', () => {
];
props.config.getUseBackgroundColor = () => false;
- const { stdout, unmount } = await renderWithProviders(
+ const renderResult = await renderWithProviders(
,
);
- await waitFor(() => {
- const frame = stdout.lastFrameRaw();
- // Check that all lines, including the empty one, are rendered.
- // This implicitly tests that the Box wrapper provides height for the empty line.
- expect(frame).toContain('hello');
- expect(frame).toContain('world');
- expect(frame).toContain(chalk.inverse(' '));
- const outputLines = frame.trim().split('\n');
- // The number of lines should be 2 for the border plus 3 for the content.
- expect(outputLines.length).toBe(5);
- });
- unmount();
+ await renderResult.waitUntilReady();
+ await expect(renderResult).toMatchSvgSnapshot();
+
+ renderResult.unmount();
});
});
@@ -4088,14 +4045,12 @@ describe('InputPrompt', () => {
it('should not show inverted cursor when shell is focused', async () => {
props.isEmbeddedShellFocused = true;
props.focus = false;
- const { stdout, unmount } = await renderWithProviders(
+ const renderResult = await renderWithProviders(
,
);
- await waitFor(() => {
- expect(stdout.lastFrame()).not.toContain(`{chalk.inverse(' ')}`);
- });
- expect(stdout.lastFrame()).toMatchSnapshot();
- unmount();
+ await renderResult.waitUntilReady();
+ await expect(renderResult).toMatchSvgSnapshot();
+ renderResult.unmount();
});
});
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-at-the-beginning-of-a-line-in-a-multiline-block.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-at-the-beginning-of-a-line-in-a-multiline-block.snap.svg
new file mode 100644
index 0000000000..fcea0df1b1
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-at-the-beginning-of-a-line-in-a-multiline-block.snap.svg
@@ -0,0 +1,19 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-line-in-a-multiline-block.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-line-in-a-multiline-block.snap.svg
new file mode 100644
index 0000000000..5adfc3cb31
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-line-in-a-multiline-block.snap.svg
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-in-the-middle-of-a-line-in-a-multiline-block.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-in-the-middle-of-a-line-in-a-multiline-block.snap.svg
new file mode 100644
index 0000000000..7df089a056
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-correctly-in-the-middle-of-a-line-in-a-multiline-block.snap.svg
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-on-a-blank-line-in-a-multiline-block.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-on-a-blank-line-in-a-multiline-block.snap.svg
new file mode 100644
index 0000000000..f72c857aa9
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-multi-line-scenarios-should-display-cursor-on-a-blank-line-in-a-multiline-block.snap.svg
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-after-multi-byte-unicode-characters-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-after-multi-byte-unicode-characters-.snap.svg
new file mode 100644
index 0000000000..22dcd7b4c3
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-after-multi-byte-unicode-characters-.snap.svg
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-beginning-of-the-line-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-beginning-of-the-line-.snap.svg
new file mode 100644
index 0000000000..ac451d2472
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-beginning-of-the-line-.snap.svg
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-line-with-unicode-cha-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-line-with-unicode-cha-.snap.svg
new file mode 100644
index 0000000000..ef6550eef8
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-line-with-unicode-cha-.snap.svg
@@ -0,0 +1,14 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-short-line-with-unico-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-short-line-with-unico-.snap.svg
new file mode 100644
index 0000000000..b6d655a8d1
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-a-short-line-with-unico-.snap.svg
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-the-line-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-the-line-.snap.svg
new file mode 100644
index 0000000000..166f5725b7
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-at-the-end-of-the-line-.snap.svg
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-for-multi-byte-unicode-characters-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-for-multi-byte-unicode-characters-.snap.svg
new file mode 100644
index 0000000000..46d7df69e4
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-for-multi-byte-unicode-characters-.snap.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-mid-word-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-mid-word-.snap.svg
new file mode 100644
index 0000000000..d583a10183
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-mid-word-.snap.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-a-highlighted-token-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-a-highlighted-token-.snap.svg
new file mode 100644
index 0000000000..0e2c0a1fbd
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-a-highlighted-token-.snap.svg
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-a-space-between-words-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-a-space-between-words-.snap.svg
new file mode 100644
index 0000000000..e57d234d13
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-a-space-between-words-.snap.svg
@@ -0,0 +1,16 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-an-empty-line-.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-an-empty-line-.snap.svg
new file mode 100644
index 0000000000..7d9249acb5
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-Highlighting-and-Cursor-Display-single-line-scenarios-should-display-cursor-correctly-on-an-empty-line-.snap.svg
@@ -0,0 +1,15 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-multiline-rendering-should-correctly-render-multiline-input-including-blank-lines.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-multiline-rendering-should-correctly-render-multiline-input-including-blank-lines.snap.svg
new file mode 100644
index 0000000000..d562880d0d
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-multiline-rendering-should-correctly-render-multiline-input-including-blank-lines.snap.svg
@@ -0,0 +1,20 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-snapshots-should-not-show-inverted-cursor-when-shell-is-focused.snap.svg b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-snapshots-should-not-show-inverted-cursor-when-shell-is-focused.snap.svg
new file mode 100644
index 0000000000..5a102dc728
--- /dev/null
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt-InputPrompt-snapshots-should-not-show-inverted-cursor-when-shell-is-focused.snap.svg
@@ -0,0 +1,18 @@
+
\ No newline at end of file
diff --git a/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap
index 5a2819702e..ab6fe9b928 100644
--- a/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap
+++ b/packages/cli/src/ui/components/__snapshots__/InputPrompt.test.tsx.snap
@@ -1,5 +1,95 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+exports[`InputPrompt > Highlighting and Cursor Display > multi-line scenarios > should display cursor correctly 'at the beginning of a line' in a multiline block 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > first line β
+β second line β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > multi-line scenarios > should display cursor correctly 'at the end of a line' in a multiline block 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > first line β
+β second line β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > multi-line scenarios > should display cursor correctly 'in the middle of a line' in a multiline block 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > first line β
+β second line β
+β third line β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > multi-line scenarios > should display cursor on a blank line in a multiline block 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > first line β
+β β
+β third line β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'after multi-byte unicode characters' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > πA β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'at the beginning of the line' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'at the end of a line with unicode chaβ¦' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello π β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'at the end of a short line with unicoβ¦' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > π β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'at the end of the line' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'for multi-byte unicode characters' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello π world β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'mid-word' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello world β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'on a highlighted token' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > run @path/to/file β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'on a space between words' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello world β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
+exports[`InputPrompt > Highlighting and Cursor Display > single-line scenarios > should display cursor correctly 'on an empty line' 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > Type your message or @path/to/file β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
exports[`InputPrompt > History Navigation and Completion Suppression > should not render suggestions during history navigation 1`] = `
"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
> second message
@@ -78,11 +168,18 @@ exports[`InputPrompt > mouse interaction > should toggle paste expansion on doub
"
`;
+exports[`InputPrompt > multiline rendering > should correctly render multiline input including blank lines 1`] = `
+"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
+β > hello β
+β β
+β world β
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
+`;
+
exports[`InputPrompt > snapshots > should not show inverted cursor when shell is focused 1`] = `
"ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
> Type your message or @path/to/file
-ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-"
+ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ"
`;
exports[`InputPrompt > snapshots > should render correctly in shell mode 1`] = `
diff --git a/packages/cli/src/ui/utils/TableRenderer.tsx b/packages/cli/src/ui/utils/TableRenderer.tsx
index 6143571f6a..986a3e61e0 100644
--- a/packages/cli/src/ui/utils/TableRenderer.tsx
+++ b/packages/cli/src/ui/utils/TableRenderer.tsx
@@ -5,16 +5,16 @@
*/
import React, { useMemo } from 'react';
-import { styledCharsToString } from '@alcalzone/ansi-tokenize';
import {
Text,
Box,
- type StyledChar,
+ StyledLine,
toStyledCharacters,
- styledCharsWidth,
wordBreakStyledChars,
wrapStyledChars,
widestLineFromStyledChars,
+ styledCharsWidth,
+ styledCharsToString,
} from 'ink';
import { theme } from '../semantic-colors.js';
import { parseMarkdownToANSI } from './markdownParsingUtils.js';
@@ -31,22 +31,22 @@ const COLUMN_PADDING = 2;
const TABLE_MARGIN = 2;
/**
- * Parses markdown to StyledChar array by first converting to ANSI.
+ * Parses markdown to StyledLine by first converting to ANSI.
* This ensures character counts are accurate (markdown markers are removed
* and styles are applied to the character's internal style object).
*/
-const parseMarkdownToStyledChars = (
+const parseMarkdownToStyledLine = (
text: string,
defaultColor?: string,
-): StyledChar[] => {
+): StyledLine => {
const ansi = parseMarkdownToANSI(text, defaultColor);
return toStyledCharacters(ansi);
};
-const calculateWidths = (styledChars: StyledChar[]) => {
- const contentWidth = styledCharsWidth(styledChars);
+const calculateWidths = (styledLine: StyledLine) => {
+ const contentWidth = styledCharsWidth(styledLine);
- const words: StyledChar[][] = wordBreakStyledChars(styledChars);
+ const words: StyledLine[] = wordBreakStyledChars(styledLine);
const maxWordWidth = widestLineFromStyledChars(words);
return { contentWidth, maxWordWidth };
@@ -67,10 +67,10 @@ export const TableRenderer: React.FC = ({
rows,
terminalWidth,
}) => {
- const styledHeaders = useMemo(
+ const styledHeaders = useMemo(
() =>
headers.map((header) =>
- parseMarkdownToStyledChars(
+ parseMarkdownToStyledLine(
stripUnsafeCharacters(header),
theme.text.link,
),
@@ -78,11 +78,11 @@ export const TableRenderer: React.FC = ({
[headers],
);
- const styledRows = useMemo(
+ const styledRows = useMemo(
() =>
rows.map((row) =>
row.map((cell) =>
- parseMarkdownToStyledChars(
+ parseMarkdownToStyledLine(
stripUnsafeCharacters(cell),
theme.text.primary,
),
@@ -100,14 +100,14 @@ export const TableRenderer: React.FC = ({
// --- Define Constraints per Column ---
const constraints = Array.from({ length: numColumns }).map(
(_, colIndex) => {
- const headerStyledChars = styledHeaders[colIndex] || [];
+ const headerStyledLine = styledHeaders[colIndex] || StyledLine.empty(0);
let { contentWidth: maxContentWidth, maxWordWidth } =
- calculateWidths(headerStyledChars);
+ calculateWidths(headerStyledLine);
styledRows.forEach((row) => {
- const cellStyledChars = row[colIndex] || [];
+ const cellStyledLine = row[colIndex] || StyledLine.empty(0);
const { contentWidth: cellWidth, maxWordWidth: cellWordWidth } =
- calculateWidths(cellStyledChars);
+ calculateWidths(cellStyledLine);
maxContentWidth = Math.max(maxContentWidth, cellWidth);
maxWordWidth = Math.max(maxWordWidth, cellWordWidth);
@@ -176,16 +176,16 @@ export const TableRenderer: React.FC = ({
// --- Pre-wrap and Optimize Widths ---
const actualColumnWidths = new Array(numColumns).fill(0);
- const wrapAndProcessRow = (row: StyledChar[][]) => {
+ const wrapAndProcessRow = (row: StyledLine[]) => {
const rowResult: ProcessedLine[][] = [];
// Ensure we iterate up to numColumns, filling with empty cells if needed
for (let colIndex = 0; colIndex < numColumns; colIndex++) {
- const cellStyledChars = row[colIndex] || [];
+ const cellStyledLine = row[colIndex] || StyledLine.empty(0);
const allocatedWidth = finalContentWidths[colIndex];
const contentWidth = Math.max(1, allocatedWidth);
const wrappedStyledLines = wrapStyledChars(
- cellStyledChars,
+ cellStyledLine,
contentWidth,
);
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-column-widths-based-on-ren-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-column-widths-based-on-ren-.snap.svg
index b2704f56ba..6a97dd54e7 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-column-widths-based-on-ren-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-column-widths-based-on-ren-.snap.svg
@@ -14,25 +14,25 @@
β
ββββββββββΌβββββββββΌβββββββββ€
β
- 123456
+ 123456
β
- Normal
+ Normal
β
- Short
+ Short
β
β
- Short
+ Short
β
- 123456
+ 123456
β
- Normal
+ Normal
β
β
- Normal
+ Normal
β
- Short
+ Short
β
- 123456
+ 123456
β
ββββββββββ΄βββββββββ΄βββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-width-correctly-for-conten-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-width-correctly-for-conten-.snap.svg
index f631406225..688b197308 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-width-correctly-for-conten-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-calculates-width-correctly-for-conten-.snap.svg
@@ -14,31 +14,25 @@
β
βββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ€
β
- Visit Google (
- https://google.com
- )
+ Visit Google (https://google.com)
β
- Plain Text
+ Plain Text
β
- More Info
+ More Info
β
β
- Info Here
+ Info Here
β
- Visit Bing (
- https://bing.com
- )
+ Visit Bing (https://bing.com)
β
- Links
+ Links
β
β
- Check This
+ Check This
β
- Search
+ Search
β
- Visit Yahoo (
- https://yahoo.com
- )
+ Visit Yahoo (https://yahoo.com)
β
βββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-does-not-parse-markdown-inside-code-s-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-does-not-parse-markdown-inside-code-s-.snap.svg
index 08eab7e946..6cec80aff1 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-does-not-parse-markdown-inside-code-s-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-does-not-parse-markdown-inside-code-s-.snap.svg
@@ -14,26 +14,25 @@
β
βββββββββββββββββββΌβββββββββββββββββββββββΌβββββββββββββββββββ€
β
- **not bold**
+ **not bold**
β
- _not italic_
+ _not italic_
β
- ~~not strike~~
+ ~~not strike~~
β
β
- [not link](url)
+ [not link](url)
β
- <u>not underline</u>
+ <u>not underline</u>
β
- https://not.link
+ https://not.link
β
β
- Normal Text
+ Normal Text
β
- More Code:
- *test*
+ More Code: *test*
β
- ***nested***
+ ***nested***
β
βββββββββββββββββββ΄βββββββββββββββββββββββ΄βββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-nested-markdown-styles-recurs-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-nested-markdown-styles-recurs-.snap.svg
index b15120756b..2ac94409d3 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-nested-markdown-styles-recurs-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-nested-markdown-styles-recurs-.snap.svg
@@ -14,31 +14,25 @@
β
βββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββ€
β
- Bold with
- Italic
- and Strike
+ Bold with Italic and Strike
β
- Normal
+ Normal
β
- Short
+ Short
β
β
- Short
+ Short
β
- Bold with
- Italic
- and Strike
+ Bold with Italic and Strike
β
- Normal
+ Normal
β
β
- Normal
+ Normal
β
- Short
+ Short
β
- Bold with
- Italic
- and Strike
+ Bold with Italic and Strike
β
βββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-non-ASCII-characters-emojis-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-non-ASCII-characters-emojis-.snap.svg
index a4410812dd..2526b9c7d3 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-non-ASCII-characters-emojis-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-non-ASCII-characters-emojis-.snap.svg
@@ -14,18 +14,18 @@
β
ββββββββββββββββΌβββββββββββββΌββββββββββββββββ€
β
- Start π End
+ Start π End
β
- δ½ ε₯½δΈη
+ δ½ ε₯½δΈη
β
- Rocket π Man
+ Rocket π Man
β
β
- Thumbs π Up
+ Thumbs π Up
β
- γγγ«γ‘γ―
+ γγγ«γ‘γ―
β
- Fire π₯
+ Fire π₯
β
ββββββββββββββββ΄βββββββββββββ΄ββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-wrapped-bold-headers-without-showing-markers.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-wrapped-bold-headers-without-showing-markers.snap.svg
index 99ba8aff43..3ba3b1176c 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-wrapped-bold-headers-without-showing-markers.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-handles-wrapped-bold-headers-without-showing-markers.snap.svg
@@ -31,15 +31,15 @@
β
βββββββββββββββΌββββββββΌββββββββββ€
β
- Data 1
+ Data 1
β
- Data
+ Data
β
- Data 3
+ Data 3
β
β
β
- 2
+ 2
β
β
βββββββββββββββ΄ββββββββ΄ββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-3x3-table-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-3x3-table-correctly.snap.svg
index ef39407726..59e54e66de 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-3x3-table-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-3x3-table-correctly.snap.svg
@@ -14,25 +14,25 @@
β
ββββββββββββββββΌβββββββββββββββΌβββββββββββββββ€
β
- Row 1, Col 1
+ Row 1, Col 1
β
- Row 1, Col 2
+ Row 1, Col 2
β
- Row 1, Col 3
+ Row 1, Col 3
β
β
- Row 2, Col 1
+ Row 2, Col 1
β
- Row 2, Col 2
+ Row 2, Col 2
β
- Row 2, Col 3
+ Row 2, Col 3
β
β
- Row 3, Col 1
+ Row 3, Col 1
β
- Row 3, Col 2
+ Row 3, Col 2
β
- Row 3, Col 3
+ Row 3, Col 3
β
ββββββββββββββββ΄βββββββββββββββ΄βββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-complex-table-with-mixed-content-lengths-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-complex-table-with-mixed-content-lengths-correctly.snap.svg
index 251476d9e1..73c93ab257 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-complex-table-with-mixed-content-lengths-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-complex-table-with-mixed-content-lengths-correctly.snap.svg
@@ -93,105 +93,105 @@
β
βββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββΌββββββΌβββββββββΌββββββββββΌββββββββ€
β
- The primary architecture
+ The primary architecture
β
- Each message is processed
+ Each message is processed
β
- Historical data indicates a
+ Historical data indicates a
β
- A multi-layered defense
+ A multi-layered defense
β
- INF
+ INF
β
- Active
+ Active
β
- v2.4
+ v2.4
β
- J.
+ J.
β
β
- utilizes a decoupled
+ utilizes a decoupled
β
- through a series of
+ through a series of
β
- significant reduction in
+ significant reduction in
β
- strategy incorporates
+ strategy incorporates
β
β
β
β
- Doe
+ Doe
β
β
- microservices approach,
+ microservices approach,
β
- specialized workers that
+ specialized workers that
β
- tail latency when utilizing
+ tail latency when utilizing
β
- content security policies,
+ content security policies,
β
β
β
β
β
β
- leveraging container
+ leveraging container
β
- handle data transformation,
+ handle data transformation,
β
- edge computing nodes closer
+ edge computing nodes closer
β
- input sanitization
+ input sanitization
β
β
β
β
β
β
- orchestration for
+ orchestration for
β
- validation, and persistent
+ validation, and persistent
β
- to the geographic location
+ to the geographic location
β
- libraries, and regular
+ libraries, and regular
β
β
β
β
β
β
- scalability and fault
+ scalability and fault
β
- storage using a persistent
+ storage using a persistent
β
- of the end-user base.
+ of the end-user base.
β
- automated penetration
+ automated penetration
β
β
β
β
β
β
- tolerance in high-load
+ tolerance in high-load
β
- queue.
+ queue.
β
β
- testing routines.
+ testing routines.
β
β
β
β
β
β
- scenarios.
+ scenarios.
β
β
- Monitoring tools have
+ Monitoring tools have
β
β
β
@@ -200,85 +200,85 @@
β
β
β
- The pipeline features
+ The pipeline features
β
- captured a steady increase
+ captured a steady increase
β
- Developers are required to
+ Developers are required to
β
β
β
β
β
β
- This layer provides the
+ This layer provides the
β
- built-in retry mechanisms
+ built-in retry mechanisms
β
- in throughput efficiency
+ in throughput efficiency
β
- undergo mandatory security
+ undergo mandatory security
β
β
β
β
β
β
- fundamental building blocks
+ fundamental building blocks
β
- with exponential backoff to
+ with exponential backoff to
β
- since the introduction of
+ since the introduction of
β
- training focusing on the
+ training focusing on the
β
β
β
β
β
β
- for service discovery, load
+ for service discovery, load
β
- ensure message delivery
+ ensure message delivery
β
- the vectorized query engine
+ the vectorized query engine
β
- OWASP Top Ten to ensure that
+ OWASP Top Ten to ensure that
β
β
β
β
β
β
- balancing, and
+ balancing, and
β
- integrity even during
+ integrity even during
β
- in the primary data
+ in the primary data
β
- security is integrated into
+ security is integrated into
β
β
β
β
β
β
- inter-service communication
+ inter-service communication
β
- transient network or service
+ transient network or service
β
- warehouse.
+ warehouse.
β
- the initial design phase.
+ the initial design phase.
β
β
β
β
β
β
- via highly efficient
+ via highly efficient
β
- failures.
+ failures.
β
β
β
@@ -287,12 +287,12 @@
β
β
β
- protocol buffers.
+ protocol buffers.
β
β
- Resource utilization
+ Resource utilization
β
- The implementation of a
+ The implementation of a
β
β
β
@@ -300,85 +300,85 @@
β
β
β
- Horizontal autoscaling is
+ Horizontal autoscaling is
β
- metrics demonstrate that
+ metrics demonstrate that
β
- robust Identity and Access
+ robust Identity and Access
β
β
β
β
β
β
- Advanced telemetry and
+ Advanced telemetry and
β
- triggered automatically
+ triggered automatically
β
- the transition to
+ the transition to
β
- Management system ensures
+ Management system ensures
β
β
β
β
β
β
- logging integrations allow
+ logging integrations allow
β
- based on the depth of the
+ based on the depth of the
β
- serverless compute for
+ serverless compute for
β
- that the principle of least
+ that the principle of least
β
β
β
β
β
β
- for real-time monitoring of
+ for real-time monitoring of
β
- processing queue, ensuring
+ processing queue, ensuring
β
- intermittent tasks has
+ intermittent tasks has
β
- privilege is strictly
+ privilege is strictly
β
β
β
β
β
β
- system health and rapid
+ system health and rapid
β
- consistent performance
+ consistent performance
β
- resulted in a thirty
+ resulted in a thirty
β
- enforced across all
+ enforced across all
β
β
β
β
β
β
- identification of
+ identification of
β
- during unexpected traffic
+ during unexpected traffic
β
- percent cost optimization.
+ percent cost optimization.
β
- environments.
+ environments.
β
β
β
β
β
β
- bottlenecks within the
+ bottlenecks within the
β
- spikes.
+ spikes.
β
β
β
@@ -387,7 +387,7 @@
β
β
β
- service mesh.
+ service mesh.
β
β
β
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-long-headers-and-4-columns-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-long-headers-and-4-columns-correctly.snap.svg
index 828c7fd9fa..b6a4cbe442 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-long-headers-and-4-columns-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-long-headers-and-4-columns-correctly.snap.svg
@@ -32,31 +32,31 @@
β
βββββββββββββββββΌββββββββββββββββΌβββββββββββββββββββΌβββββββββββββββββββ€
β
- Data 1.1
+ Data 1.1
β
- Data 1.2
+ Data 1.2
β
- Data 1.3
+ Data 1.3
β
- Data 1.4
+ Data 1.4
β
β
- Data 2.1
+ Data 2.1
β
- Data 2.2
+ Data 2.2
β
- Data 2.3
+ Data 2.3
β
- Data 2.4
+ Data 2.4
β
β
- Data 3.1
+ Data 3.1
β
- Data 3.2
+ Data 3.2
β
- Data 3.3
+ Data 3.3
β
- Data 3.4
+ Data 3.4
β
βββββββββββββββββ΄ββββββββββββββββ΄βββββββββββββββββββ΄βββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-mixed-emojis-As-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-mixed-emojis-As-.snap.svg
index 3e76bc05e3..fbbc9070d3 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-mixed-emojis-As-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-mixed-emojis-As-.snap.svg
@@ -14,18 +14,18 @@
β
βββββββββββββββββΌββββββββββββββββββββΌβββββββββββββββββ€
β
- δ½ ε₯½ π
+ δ½ ε₯½ π
β
- γγγ«γ‘γ― π
+ γγγ«γ‘γ― π
β
- μλ
νμΈμ π
+ μλ
νμΈμ π
β
β
- World π
+ World π
β
- Code π»
+ Code π»
β
- Pizza π
+ Pizza π
β
βββββββββββββββββ΄ββββββββββββββββββββ΄βββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-Asian-chara-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-Asian-chara-.snap.svg
index 7f31b51548..7970df8065 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-Asian-chara-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-Asian-chara-.snap.svg
@@ -14,18 +14,18 @@
β
ββββββββββββββββΌββββββββββββββββββΌββββββββββββββββ€
β
- δ½ ε₯½
+ δ½ ε₯½
β
- γγγ«γ‘γ―
+ γγγ«γ‘γ―
β
- μλ
νμΈμ
+ μλ
νμΈμ
β
β
- δΈη
+ δΈη
β
- δΈη
+ δΈη
β
- μΈκ³
+ μΈκ³
β
ββββββββββββββββ΄ββββββββββββββββββ΄ββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-emojis-and-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-emojis-and-.snap.svg
index a3abd45c53..dc5cc190f7 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-emojis-and-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-a-table-with-only-emojis-and-.snap.svg
@@ -14,18 +14,18 @@
β
ββββββββββββΌββββββββββββΌβββββββββββ€
β
- Smile π
+ Smile π
β
- Fire π₯
+ Fire π₯
β
- Love π
+ Love π
β
β
- Cool π
+ Cool π
β
- Star β
+ Star β
β
- Blue π
+ Blue π
β
ββββββββββββ΄ββββββββββββ΄βββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-complex-markdown-in-rows-and-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-complex-markdown-in-rows-and-.snap.svg
index b48572438b..8b3cc61d04 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-complex-markdown-in-rows-and-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-complex-markdown-in-rows-and-.snap.svg
@@ -12,41 +12,39 @@
β
βββββββββββββββββΌββββββββββββββββββββββββββββββ€
β
- Bold
+ Bold
β
- Bold Text
+ Bold Text
β
β
- Italic
+ Italic
β
- Italic Text
+ Italic Text
β
β
- Combined
+ Combined
β
- Bold and Italic
+ Bold and Italic
β
β
- Link
+ Link
β
- Google (
- https://google.com
- )
+ Google (https://google.com)
β
β
- Code
+ Code
β
- const x = 1
+ const x = 1
β
β
- Strikethrough
+ Strikethrough
β
- Strike
+ Strike
β
β
- Underline
+ Underline
β
- Underline
+ Underline
β
βββββββββββββββββ΄ββββββββββββββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-headers-are-em-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-headers-are-em-.snap.svg
index 180c7aeb56..b2523badcd 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-headers-are-em-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-headers-are-em-.snap.svg
@@ -10,9 +10,9 @@
β
ββββββββββΌβββββββββ€
β
- Data 1
+ Data 1
β
- Data 2
+ Data 2
β
ββββββββββ΄βββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-there-are-more-.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-there-are-more-.snap.svg
index 685260b84d..8e2f17383b 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-there-are-more-.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-renders-correctly-when-there-are-more-.snap.svg
@@ -14,9 +14,9 @@
β
ββββββββββββΌβββββββββββΌβββββββββββ€
β
- Data 1
+ Data 1
β
- Data 2
+ Data 2
β
β
ββββββββββββ΄βββββββββββ΄βββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-strips-bold-markers-from-headers-and-renders-them-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-strips-bold-markers-from-headers-and-renders-them-correctly.snap.svg
index bc33d9e78a..af6fd33fc5 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-strips-bold-markers-from-headers-and-renders-them-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-strips-bold-markers-from-headers-and-renders-them-correctly.snap.svg
@@ -14,11 +14,11 @@
β
βββββββββββββββΌββββββββββββββββΌβββββββββββββββ€
β
- Data 1
+ Data 1
β
- Data 2
+ Data 2
β
- Data 3
+ Data 3
β
βββββββββββββββ΄ββββββββββββββββ΄βββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-all-long-columns-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-all-long-columns-correctly.snap.svg
index d69f29ece4..94f5cff65a 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-all-long-columns-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-all-long-columns-correctly.snap.svg
@@ -14,38 +14,38 @@
β
ββββββββββββββββββΌβββββββββββββββββΌββββββββββββββββββ€
β
- This is a very
+ This is a very
β
- This is also a
+ This is also a
β
- And this is the
+ And this is the
β
β
- long text that
+ long text that
β
- very long text
+ very long text
β
- third long text
+ third long text
β
β
- needs wrapping
+ needs wrapping
β
- that needs
+ that needs
β
- that needs
+ that needs
β
β
- in column 1
+ in column 1
β
- wrapping in
+ wrapping in
β
- wrapping in
+ wrapping in
β
β
β
- column 2
+ column 2
β
- column 3
+ column 3
β
ββββββββββββββββββ΄βββββββββββββββββ΄ββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-columns-with-punctuation-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-columns-with-punctuation-correctly.snap.svg
index f16cdd29ae..1b801041d0 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-columns-with-punctuation-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-columns-with-punctuation-correctly.snap.svg
@@ -14,37 +14,37 @@
β
βββββββββββββββββββββΌββββββββββββββββΌββββββββββββββββββ€
β
- Start. Stop.
+ Start. Stop.
β
- Semi; colon:
+ Semi; colon:
β
- At@ Hash#
+ At@ Hash#
β
β
- Comma, separated.
+ Comma, separated.
β
- Pipe| Slash/
+ Pipe| Slash/
β
- Dollar$
+ Dollar$
β
β
- Exclamation!
+ Exclamation!
β
- Backslash\
+ Backslash\
β
- Percent% Caret^
+ Percent% Caret^
β
β
- Question?
+ Question?
β
β
- Ampersand&
+ Ampersand&
β
β
- hyphen-ated
+ hyphen-ated
β
β
- Asterisk*
+ Asterisk*
β
βββββββββββββββββββββ΄ββββββββββββββββ΄ββββββββββββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-long-cell-content-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-long-cell-content-correctly.snap.svg
index f46137df13..3e99ee7f52 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-long-cell-content-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-long-cell-content-correctly.snap.svg
@@ -14,20 +14,20 @@
β
βββββββββΌββββββββββββββββββββββββββββββΌββββββββ€
β
- Short
+ Short
β
- This is a very long cell
+ This is a very long cell
β
- Short
+ Short
β
β
β
- content that should wrap to
+ content that should wrap to
β
β
β
β
- multiple lines
+ multiple lines
β
β
βββββββββ΄ββββββββββββββββββββββββββββββ΄ββββββββ
diff --git a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-mixed-long-and-short-columns-correctly.snap.svg b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-mixed-long-and-short-columns-correctly.snap.svg
index f517dc3632..0a352660ea 100644
--- a/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-mixed-long-and-short-columns-correctly.snap.svg
+++ b/packages/cli/src/ui/utils/__snapshots__/TableRenderer-TableRenderer-wraps-mixed-long-and-short-columns-correctly.snap.svg
@@ -14,21 +14,21 @@
β
βββββββββΌβββββββββββββββββββββββββββΌβββββββββ€
β
- Tiny
+ Tiny
β
- This is a very long text
+ This is a very long text
β
- Not so
+ Not so
β
β
β
- that definitely needs to
+ that definitely needs to
β
- long
+ long
β
β
β
- wrap to the next line
+ wrap to the next line
β
β
βββββββββ΄βββββββββββββββββββββββββββ΄βββββββββ