@runtypelabs/ink-components 0.2.2 → 0.3.0
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/dist/index.d.ts +9 -3
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ComponentProps } from 'react';
|
|
2
|
+
import { ComponentProps, ReactNode } from 'react';
|
|
3
3
|
import InkSpinner from 'ink-spinner';
|
|
4
4
|
|
|
5
5
|
type InkSpinnerType = ComponentProps<typeof InkSpinner>['type'];
|
|
@@ -11,7 +11,7 @@ interface SpinnerProps {
|
|
|
11
11
|
declare function Spinner({ label, color, type, }: SpinnerProps): react_jsx_runtime.JSX.Element;
|
|
12
12
|
|
|
13
13
|
interface StatusBarProps {
|
|
14
|
-
left?:
|
|
14
|
+
left?: ReactNode;
|
|
15
15
|
center?: string;
|
|
16
16
|
right?: string;
|
|
17
17
|
}
|
|
@@ -25,6 +25,11 @@ interface StreamOutputProps {
|
|
|
25
25
|
/** Lines to scroll up from the bottom (0 = follow latest) */
|
|
26
26
|
scrollOffset?: number;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Render raw markdown content to terminal-styled text with ANSI color codes.
|
|
30
|
+
* Uses the module-level `marked` + `marked-terminal` configuration.
|
|
31
|
+
*/
|
|
32
|
+
declare function renderMarkdownToTerminal(content: string): string;
|
|
28
33
|
declare function StreamOutput({ content, isStreaming, enableMarkdown, maxVisibleLines, scrollOffset, }: StreamOutputProps): react_jsx_runtime.JSX.Element;
|
|
29
34
|
|
|
30
35
|
interface ErrorDisplayProps {
|
|
@@ -34,6 +39,7 @@ interface ErrorDisplayProps {
|
|
|
34
39
|
declare function ErrorDisplay({ error, context }: ErrorDisplayProps): react_jsx_runtime.JSX.Element;
|
|
35
40
|
|
|
36
41
|
declare const theme: {
|
|
42
|
+
readonly backgroundDeep: "#000000";
|
|
37
43
|
readonly background: "#1b212b";
|
|
38
44
|
readonly surface: "#202733";
|
|
39
45
|
readonly surfaceMuted: "#1d2430";
|
|
@@ -72,4 +78,4 @@ interface ToolResult {
|
|
|
72
78
|
duration?: number;
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
export { ErrorDisplay, type ErrorDisplayProps, Spinner, type SpinnerProps, StatusBar, type StatusBarProps, StreamOutput, type StreamOutputProps, type StreamPhase, type Theme, type ToolResult, theme };
|
|
81
|
+
export { ErrorDisplay, type ErrorDisplayProps, Spinner, type SpinnerProps, StatusBar, type StatusBarProps, StreamOutput, type StreamOutputProps, type StreamPhase, type Theme, type ToolResult, renderMarkdownToTerminal, theme };
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import InkSpinner from "ink-spinner";
|
|
|
4
4
|
|
|
5
5
|
// src/theme.ts
|
|
6
6
|
var theme = {
|
|
7
|
+
backgroundDeep: "#000000",
|
|
7
8
|
background: "#1b212b",
|
|
8
9
|
surface: "#202733",
|
|
9
10
|
surfaceMuted: "#1d2430",
|
|
@@ -63,7 +64,7 @@ function StatusBar({ left, center, right }) {
|
|
|
63
64
|
paddingX: theme.panelPaddingX,
|
|
64
65
|
paddingY: theme.panelPaddingY,
|
|
65
66
|
children: [
|
|
66
|
-
/* @__PURE__ */ jsx2(Box2, { flexGrow: 1, children: /* @__PURE__ */ jsx2(Text2, { color: theme.textMuted, children: left }) }),
|
|
67
|
+
/* @__PURE__ */ jsx2(Box2, { flexGrow: 1, children: typeof left === "string" ? /* @__PURE__ */ jsx2(Text2, { color: theme.textMuted, children: left }) : left }),
|
|
67
68
|
center && /* @__PURE__ */ jsx2(Box2, { flexGrow: 1, justifyContent: "center", children: /* @__PURE__ */ jsx2(Text2, { color: theme.accent, children: center }) }),
|
|
68
69
|
right && /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsx2(Text2, { color: theme.textSubtle, children: right }) })
|
|
69
70
|
]
|
|
@@ -154,6 +155,11 @@ marked.use(
|
|
|
154
155
|
}
|
|
155
156
|
)
|
|
156
157
|
);
|
|
158
|
+
function renderMarkdownToTerminal(content) {
|
|
159
|
+
const stripped = stripAnsi(content);
|
|
160
|
+
if (!stripped) return "";
|
|
161
|
+
return marked.parse(stripped).trimEnd();
|
|
162
|
+
}
|
|
157
163
|
function StreamOutput({
|
|
158
164
|
content,
|
|
159
165
|
isStreaming,
|
|
@@ -208,6 +214,7 @@ export {
|
|
|
208
214
|
Spinner,
|
|
209
215
|
StatusBar,
|
|
210
216
|
StreamOutput,
|
|
217
|
+
renderMarkdownToTerminal,
|
|
211
218
|
theme
|
|
212
219
|
};
|
|
213
220
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Spinner.tsx","../src/theme.ts","../src/components/StatusBar.tsx","../src/components/StreamOutput.tsx","../src/components/ErrorDisplay.tsx"],"sourcesContent":["import type { ComponentProps } from 'react'\nimport { Box, Text } from 'ink'\nimport InkSpinner from 'ink-spinner'\nimport { theme } from '../theme.js'\n\ntype InkSpinnerType = ComponentProps<typeof InkSpinner>['type']\n\nexport interface SpinnerProps {\n label?: string\n color?: string\n type?: InkSpinnerType\n}\n\nexport function Spinner({\n label = 'Loading...',\n color = theme.spinner,\n type = 'dots',\n}: SpinnerProps) {\n return (\n <Box>\n <Text color={color}>\n <InkSpinner type={type} />\n </Text>\n <Text color={theme.textMuted}> {label}</Text>\n </Box>\n )\n}\n","export const theme = {\n background: '#1b212b',\n surface: '#202733',\n surfaceMuted: '#1d2430',\n surfaceElevated: '#252d3b',\n text: '#d8d3c9',\n textMuted: '#918b84',\n textSubtle: '#66625d',\n accent: '#8fc4bf',\n accentActive: '#a7d8d2',\n success: '#8ecb73',\n warning: '#d8ae63',\n danger: '#c97b73',\n border: '#394252',\n borderActive: '#546077',\n error: '#c97b73',\n info: '#8fc4bf',\n muted: '#918b84',\n primary: '#8fc4bf',\n secondary: '#a7d8d2',\n spinner: '#8fc4bf',\n progress: '#8fc4bf',\n label: '#d8d3c9',\n dimLabel: '#66625d',\n highlight: 'bold',\n separator: ' · ',\n sectionGap: 1,\n panelPaddingX: 1,\n panelPaddingY: 0,\n} as const\n\nexport type Theme = typeof theme\n","import { Box, Text } from 'ink'\nimport { theme } from '../theme.js'\n\nexport interface StatusBarProps {\n left?: string\n center?: string\n right?: string\n}\n\nexport function StatusBar({ left, center, right }: StatusBarProps) {\n return (\n <Box\n borderStyle=\"single\"\n borderColor={theme.border}\n backgroundColor={theme.background}\n paddingX={theme.panelPaddingX}\n paddingY={theme.panelPaddingY}\n >\n <Box flexGrow={1}>\n <Text color={theme.textMuted}>{left}</Text>\n </Box>\n {center && (\n <Box flexGrow={1} justifyContent=\"center\">\n <Text color={theme.accent}>{center}</Text>\n </Box>\n )}\n {right && (\n <Box>\n <Text color={theme.textSubtle}>{right}</Text>\n </Box>\n )}\n </Box>\n )\n}\n","import { useMemo } from 'react'\nimport { Box, Text } from 'ink'\nimport chalk from 'chalk'\nimport InkSpinner from 'ink-spinner'\nimport { type MarkedExtension, marked } from 'marked'\n// @ts-expect-error marked-terminal has no type declarations\nimport { markedTerminal } from 'marked-terminal'\nimport stripAnsi from 'strip-ansi'\nimport { theme } from '../theme.js'\n\nexport interface StreamOutputProps {\n content: string\n isStreaming: boolean\n enableMarkdown?: boolean\n maxVisibleLines?: number\n /** Lines to scroll up from the bottom (0 = follow latest) */\n scrollOffset?: number\n}\n\nconst bodyText = chalk.hex(theme.text)\nconst mutedText = chalk.hex(theme.textMuted)\nconst subtleText = chalk.hex(theme.textSubtle)\nconst accentText = chalk.hex(theme.accent)\nconst accentActiveText = chalk.hex(theme.accentActive)\nconst successText = chalk.hex(theme.success)\nconst warningText = chalk.hex(theme.warning)\nconst dangerText = chalk.hex(theme.danger)\n\nconst markdownHighlightTheme = {\n default: bodyText,\n keyword: accentText,\n built_in: accentActiveText,\n type: accentActiveText,\n literal: accentText,\n number: successText,\n regexp: warningText,\n string: bodyText,\n subst: accentText,\n symbol: bodyText,\n class: accentActiveText,\n function: accentActiveText,\n title: accentActiveText,\n params: mutedText,\n comment: subtleText,\n doctag: subtleText,\n meta: subtleText,\n 'meta-keyword': accentText,\n 'meta-string': mutedText,\n section: accentText,\n tag: accentText,\n name: accentActiveText,\n 'builtin-name': accentActiveText,\n attr: accentText,\n attribute: accentText,\n variable: accentActiveText,\n bullet: mutedText,\n code: successText,\n emphasis: accentText,\n strong: accentActiveText,\n formula: accentText,\n link: accentActiveText,\n quote: mutedText,\n addition: successText,\n deletion: dangerText,\n} as const\n\n// Configure marked with terminal renderer once at module level.\nmarked.use(\n markedTerminal(\n {\n code: successText,\n blockquote: mutedText,\n html: subtleText,\n heading: accentText,\n firstHeading: accentActiveText.bold,\n hr: subtleText,\n listitem: bodyText,\n list: (body: string) => bodyText(body),\n table: mutedText,\n paragraph: bodyText,\n strong: accentActiveText.bold,\n em: accentText.italic,\n codespan: successText,\n del: subtleText.strikethrough,\n link: accentActiveText,\n href: mutedText.underline,\n text: bodyText,\n showSectionPrefix: false,\n reflowText: false,\n },\n {\n ignoreIllegals: true,\n theme: markdownHighlightTheme,\n }\n ) as MarkedExtension\n)\n\nexport function StreamOutput({\n content,\n isStreaming,\n enableMarkdown = true,\n maxVisibleLines,\n scrollOffset = 0,\n}: StreamOutputProps) {\n const rendered = useMemo(() => {\n // Strip incoming ANSI codes, then re-render via marked-terminal if enabled\n const stripped = stripAnsi(content)\n if (!stripped) return ''\n if (enableMarkdown) {\n return (marked.parse(stripped) as string).trimEnd()\n }\n return stripped\n }, [content, enableMarkdown])\n\n // Window to N lines with optional scroll offset from bottom\n const visible = useMemo(() => {\n if (!maxVisibleLines) return rendered\n const lines = rendered.split('\\n')\n const totalLines = lines.length\n const clampedOffset = Math.min(scrollOffset, Math.max(0, totalLines - maxVisibleLines))\n const end = totalLines - clampedOffset\n const start = Math.max(0, end - maxVisibleLines)\n return lines.slice(start, end).join('\\n')\n }, [rendered, maxVisibleLines, scrollOffset])\n\n return (\n <Box flexDirection=\"column\">\n {visible && <Text color={theme.text}>{visible}</Text>}\n {isStreaming && (\n <Box>\n <Text color={theme.textMuted}>\n <InkSpinner type=\"dots\" />\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n","import { Box, Text } from 'ink'\nimport { theme } from '../theme.js'\n\nexport interface ErrorDisplayProps {\n error: Error | string\n context?: string\n}\n\nexport function ErrorDisplay({ error, context }: ErrorDisplayProps) {\n const message = error instanceof Error ? error.message : error\n const cause =\n error instanceof Error && error.cause ? String(error.cause) : undefined\n\n return (\n <Box flexDirection=\"column\" marginTop={theme.sectionGap}>\n <Text color={theme.danger} bold>\n Error{context ? ` ${context}` : ''}: {message}\n </Text>\n {cause && <Text color={theme.textMuted}>Cause: {cause}</Text>}\n </Box>\n )\n}\n"],"mappings":"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","names":["Box","Text","jsx","jsxs","Box","Text","Box","Text","InkSpinner","jsx","jsxs","Box","Text","InkSpinner","Box","Text","jsxs","Box","Text"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/Spinner.tsx","../src/theme.ts","../src/components/StatusBar.tsx","../src/components/StreamOutput.tsx","../src/components/ErrorDisplay.tsx"],"sourcesContent":["import type { ComponentProps } from 'react'\nimport { Box, Text } from 'ink'\nimport InkSpinner from 'ink-spinner'\nimport { theme } from '../theme.js'\n\ntype InkSpinnerType = ComponentProps<typeof InkSpinner>['type']\n\nexport interface SpinnerProps {\n label?: string\n color?: string\n type?: InkSpinnerType\n}\n\nexport function Spinner({\n label = 'Loading...',\n color = theme.spinner,\n type = 'dots',\n}: SpinnerProps) {\n return (\n <Box>\n <Text color={color}>\n <InkSpinner type={type} />\n </Text>\n <Text color={theme.textMuted}> {label}</Text>\n </Box>\n )\n}\n","export const theme = {\n backgroundDeep: '#000000',\n background: '#1b212b',\n surface: '#202733',\n surfaceMuted: '#1d2430',\n surfaceElevated: '#252d3b',\n text: '#d8d3c9',\n textMuted: '#918b84',\n textSubtle: '#66625d',\n accent: '#8fc4bf',\n accentActive: '#a7d8d2',\n success: '#8ecb73',\n warning: '#d8ae63',\n danger: '#c97b73',\n border: '#394252',\n borderActive: '#546077',\n error: '#c97b73',\n info: '#8fc4bf',\n muted: '#918b84',\n primary: '#8fc4bf',\n secondary: '#a7d8d2',\n spinner: '#8fc4bf',\n progress: '#8fc4bf',\n label: '#d8d3c9',\n dimLabel: '#66625d',\n highlight: 'bold',\n separator: ' · ',\n sectionGap: 1,\n panelPaddingX: 1,\n panelPaddingY: 0,\n} as const\n\nexport type Theme = typeof theme\n","import type { ReactNode } from 'react'\nimport { Box, Text } from 'ink'\nimport { theme } from '../theme.js'\n\nexport interface StatusBarProps {\n left?: ReactNode\n center?: string\n right?: string\n}\n\nexport function StatusBar({ left, center, right }: StatusBarProps) {\n return (\n <Box\n borderStyle=\"single\"\n borderColor={theme.border}\n backgroundColor={theme.background}\n paddingX={theme.panelPaddingX}\n paddingY={theme.panelPaddingY}\n >\n <Box flexGrow={1}>\n {typeof left === 'string' ? (\n <Text color={theme.textMuted}>{left}</Text>\n ) : (\n left\n )}\n </Box>\n {center && (\n <Box flexGrow={1} justifyContent=\"center\">\n <Text color={theme.accent}>{center}</Text>\n </Box>\n )}\n {right && (\n <Box>\n <Text color={theme.textSubtle}>{right}</Text>\n </Box>\n )}\n </Box>\n )\n}\n","import { useMemo } from 'react'\nimport { Box, Text } from 'ink'\nimport chalk from 'chalk'\nimport InkSpinner from 'ink-spinner'\nimport { type MarkedExtension, marked } from 'marked'\n// @ts-expect-error marked-terminal has no type declarations\nimport { markedTerminal } from 'marked-terminal'\nimport stripAnsi from 'strip-ansi'\nimport { theme } from '../theme.js'\n\nexport interface StreamOutputProps {\n content: string\n isStreaming: boolean\n enableMarkdown?: boolean\n maxVisibleLines?: number\n /** Lines to scroll up from the bottom (0 = follow latest) */\n scrollOffset?: number\n}\n\nconst bodyText = chalk.hex(theme.text)\nconst mutedText = chalk.hex(theme.textMuted)\nconst subtleText = chalk.hex(theme.textSubtle)\nconst accentText = chalk.hex(theme.accent)\nconst accentActiveText = chalk.hex(theme.accentActive)\nconst successText = chalk.hex(theme.success)\nconst warningText = chalk.hex(theme.warning)\nconst dangerText = chalk.hex(theme.danger)\n\nconst markdownHighlightTheme = {\n default: bodyText,\n keyword: accentText,\n built_in: accentActiveText,\n type: accentActiveText,\n literal: accentText,\n number: successText,\n regexp: warningText,\n string: bodyText,\n subst: accentText,\n symbol: bodyText,\n class: accentActiveText,\n function: accentActiveText,\n title: accentActiveText,\n params: mutedText,\n comment: subtleText,\n doctag: subtleText,\n meta: subtleText,\n 'meta-keyword': accentText,\n 'meta-string': mutedText,\n section: accentText,\n tag: accentText,\n name: accentActiveText,\n 'builtin-name': accentActiveText,\n attr: accentText,\n attribute: accentText,\n variable: accentActiveText,\n bullet: mutedText,\n code: successText,\n emphasis: accentText,\n strong: accentActiveText,\n formula: accentText,\n link: accentActiveText,\n quote: mutedText,\n addition: successText,\n deletion: dangerText,\n} as const\n\n// Configure marked with terminal renderer once at module level.\nmarked.use(\n markedTerminal(\n {\n code: successText,\n blockquote: mutedText,\n html: subtleText,\n heading: accentText,\n firstHeading: accentActiveText.bold,\n hr: subtleText,\n listitem: bodyText,\n list: (body: string) => bodyText(body),\n table: mutedText,\n paragraph: bodyText,\n strong: accentActiveText.bold,\n em: accentText.italic,\n codespan: successText,\n del: subtleText.strikethrough,\n link: accentActiveText,\n href: mutedText.underline,\n text: bodyText,\n showSectionPrefix: false,\n reflowText: false,\n },\n {\n ignoreIllegals: true,\n theme: markdownHighlightTheme,\n }\n ) as MarkedExtension\n)\n\n/**\n * Render raw markdown content to terminal-styled text with ANSI color codes.\n * Uses the module-level `marked` + `marked-terminal` configuration.\n */\nexport function renderMarkdownToTerminal(content: string): string {\n const stripped = stripAnsi(content)\n if (!stripped) return ''\n return (marked.parse(stripped) as string).trimEnd()\n}\n\nexport function StreamOutput({\n content,\n isStreaming,\n enableMarkdown = true,\n maxVisibleLines,\n scrollOffset = 0,\n}: StreamOutputProps) {\n const rendered = useMemo(() => {\n // Strip incoming ANSI codes, then re-render via marked-terminal if enabled\n const stripped = stripAnsi(content)\n if (!stripped) return ''\n if (enableMarkdown) {\n return (marked.parse(stripped) as string).trimEnd()\n }\n return stripped\n }, [content, enableMarkdown])\n\n // Window to N lines with optional scroll offset from bottom\n const visible = useMemo(() => {\n if (!maxVisibleLines) return rendered\n const lines = rendered.split('\\n')\n const totalLines = lines.length\n const clampedOffset = Math.min(scrollOffset, Math.max(0, totalLines - maxVisibleLines))\n const end = totalLines - clampedOffset\n const start = Math.max(0, end - maxVisibleLines)\n return lines.slice(start, end).join('\\n')\n }, [rendered, maxVisibleLines, scrollOffset])\n\n return (\n <Box flexDirection=\"column\">\n {visible && <Text color={theme.text}>{visible}</Text>}\n {isStreaming && (\n <Box>\n <Text color={theme.textMuted}>\n <InkSpinner type=\"dots\" />\n </Text>\n </Box>\n )}\n </Box>\n )\n}\n","import { Box, Text } from 'ink'\nimport { theme } from '../theme.js'\n\nexport interface ErrorDisplayProps {\n error: Error | string\n context?: string\n}\n\nexport function ErrorDisplay({ error, context }: ErrorDisplayProps) {\n const message = error instanceof Error ? error.message : error\n const cause =\n error instanceof Error && error.cause ? String(error.cause) : undefined\n\n return (\n <Box flexDirection=\"column\" marginTop={theme.sectionGap}>\n <Text color={theme.danger} bold>\n Error{context ? ` ${context}` : ''}: {message}\n </Text>\n {cause && <Text color={theme.textMuted}>Cause: {cause}</Text>}\n </Box>\n )\n}\n"],"mappings":"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","names":["Box","Text","jsx","jsxs","Box","Text","Box","Text","InkSpinner","jsx","jsxs","Box","Text","InkSpinner","Box","Text","jsxs","Box","Text"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/ink-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared Ink (React for CLI) components for the Runtype CLI — spinners, status bars, streaming output, and error displays.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Runtype Labs",
|