theboardtui 0.1.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/README.md +156 -0
- package/dist/App.js +129 -0
- package/dist/components/BoardDetail.js +50 -0
- package/dist/components/BoardsList.js +93 -0
- package/dist/components/ChatInterface.js +115 -0
- package/dist/components/CompactList.js +22 -0
- package/dist/components/Dashboard.js +74 -0
- package/dist/components/Layout.js +6 -0
- package/dist/components/Login.js +62 -0
- package/dist/components/MembersList.js +117 -0
- package/dist/components/Navigation.js +132 -0
- package/dist/components/ProblemDetail.js +576 -0
- package/dist/components/ProblemForm.js +126 -0
- package/dist/components/ProblemsList.js +118 -0
- package/dist/components/QuickActions.js +173 -0
- package/dist/components/QuickCreate.js +159 -0
- package/dist/components/ReportViewer.js +7 -0
- package/dist/components/Settings.js +53 -0
- package/dist/components/StatusMonitor.js +47 -0
- package/dist/components/layout/Container.js +6 -0
- package/dist/components/layout/Grid.js +6 -0
- package/dist/components/layout/Header.js +8 -0
- package/dist/components/layout/Section.js +6 -0
- package/dist/components/layout/Stack.js +7 -0
- package/dist/components/ui/Badge.js +16 -0
- package/dist/components/ui/Button.js +19 -0
- package/dist/components/ui/Card.js +15 -0
- package/dist/components/ui/Divider.js +9 -0
- package/dist/components/ui/ErrorDisplay.js +10 -0
- package/dist/components/ui/Input.js +13 -0
- package/dist/components/ui/List.js +13 -0
- package/dist/components/ui/Panel.js +11 -0
- package/dist/components/ui/Spinner.js +16 -0
- package/dist/design/borders.js +51 -0
- package/dist/design/colors.js +45 -0
- package/dist/design/index.js +30 -0
- package/dist/design/spacing.js +41 -0
- package/dist/design/typography.js +62 -0
- package/dist/index.js +43 -0
- package/dist/lib/api.js +204 -0
- package/dist/lib/asciiArt.js +56 -0
- package/dist/lib/auth.js +55 -0
- package/dist/lib/browser.js +68 -0
- package/dist/lib/commands.js +53 -0
- package/dist/lib/config.js +100 -0
- package/dist/lib/scrollIndicators.js +29 -0
- package/dist/lib/theme.js +33 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/viewport.js +32 -0
- package/dist/utils/formatters.js +114 -0
- package/package.json +48 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { Box, Text } from "ink";
|
|
4
|
+
import { apiGet } from "../lib/api.js";
|
|
5
|
+
import { formatStatus, formatDate } from "../utils/formatters.js";
|
|
6
|
+
import { statusPending, statusAnalyzing, muted } from "../lib/theme.js";
|
|
7
|
+
import Card from "./ui/Card.js";
|
|
8
|
+
import Spinner from "./ui/Spinner.js";
|
|
9
|
+
import Stack from "./layout/Stack.js";
|
|
10
|
+
import ErrorDisplay from "./ui/ErrorDisplay.js";
|
|
11
|
+
export default function StatusMonitor({ problemId, pollInterval = 5000 }) {
|
|
12
|
+
const [runs, setRuns] = useState([]);
|
|
13
|
+
const [loading, setLoading] = useState(true);
|
|
14
|
+
const [error, setError] = useState("");
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!problemId)
|
|
17
|
+
return;
|
|
18
|
+
loadStatus();
|
|
19
|
+
const interval = setInterval(loadStatus, pollInterval);
|
|
20
|
+
return () => clearInterval(interval);
|
|
21
|
+
}, [problemId, pollInterval]);
|
|
22
|
+
const loadStatus = async () => {
|
|
23
|
+
if (!problemId)
|
|
24
|
+
return;
|
|
25
|
+
try {
|
|
26
|
+
setLoading(true);
|
|
27
|
+
setError("");
|
|
28
|
+
const data = await apiGet(`/api/problems/${problemId}/analysis-runs`).catch(() => ({ analysisRuns: [] }));
|
|
29
|
+
setRuns(data.analysisRuns || []);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
setError(err.message || "Failed to load status");
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
setLoading(false);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const activeRuns = runs.filter((run) => run.status === "pending" || run.status === "analyzing");
|
|
39
|
+
const recentRuns = runs.slice(0, 5);
|
|
40
|
+
if (loading && runs.length === 0) {
|
|
41
|
+
return (_jsx(Card, { variant: "outlined", title: "Status Monitor", children: _jsx(Spinner, { message: "Loading status..." }) }));
|
|
42
|
+
}
|
|
43
|
+
if (error) {
|
|
44
|
+
return (_jsx(Card, { variant: "outlined", title: "Status Monitor", children: _jsx(ErrorDisplay, { error: error, maxWidth: Math.min(70, (process.stdout.columns || 80) - 4) }) }));
|
|
45
|
+
}
|
|
46
|
+
return (_jsx(Card, { variant: "outlined", title: "Status Monitor", children: _jsxs(Stack, { direction: "vertical", gap: "sm", children: [activeRuns.length > 0 && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { bold: true, children: "Active Analyses" }), activeRuns.map((run) => (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Text, { children: [run.status === "analyzing" ? statusAnalyzing("●") : statusPending("●"), " ", run.id.slice(0, 8)] }), _jsx(Text, { children: muted(formatDate(run.createdAt)) })] }, run.id)))] })), recentRuns.length > 0 && (_jsxs(Box, { flexDirection: "column", gap: 1, children: [_jsx(Text, { bold: true, children: "Recent Runs" }), recentRuns.map((run) => (_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", children: [_jsxs(Text, { children: [formatStatus(run.status), " ", run.id.slice(0, 8)] }), _jsx(Text, { children: muted(formatDate(run.createdAt)) })] }, run.id)))] })), runs.length === 0 && (_jsx(Text, { children: muted("No analysis runs found") }))] }) }));
|
|
47
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from "ink";
|
|
3
|
+
import { padding } from "../../design/index.js";
|
|
4
|
+
export default function Container({ children, padding: paddingSize = "md" }) {
|
|
5
|
+
return (_jsx(Box, { paddingX: padding[paddingSize], paddingY: padding[paddingSize], children: children }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from "ink";
|
|
3
|
+
import { gap } from "../../design/index.js";
|
|
4
|
+
export default function Grid({ children, columns = 2, gap: gapSize = "md" }) {
|
|
5
|
+
return (_jsx(Box, { flexDirection: "row", flexWrap: "wrap", gap: gap[gapSize], children: children }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { colors, gap } from "../../design/index.js";
|
|
5
|
+
import Divider from "../ui/Divider.js";
|
|
6
|
+
export default function Header({ title, subtitle, actions }) {
|
|
7
|
+
return (_jsxs(Box, { flexDirection: "column", gap: gap.sm, children: [_jsxs(Box, { flexDirection: "row", justifyContent: "space-between", alignItems: "center", children: [_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: chalk.hex(colors.primary).bold(title) }), subtitle && (_jsx(Text, { children: chalk.hex(colors.muted)(subtitle) }))] }), actions && _jsx(Box, { children: actions })] }), _jsx(Divider, {})] }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from "ink";
|
|
3
|
+
import { gap, padding } from "../../design/index.js";
|
|
4
|
+
export default function Section({ children, title, gap: gapSize = "md", padding: paddingSize = "none" }) {
|
|
5
|
+
return (_jsxs(Box, { flexDirection: "column", gap: gap[gapSize], paddingX: padding[paddingSize], paddingY: padding[paddingSize], children: [title && (_jsx(Box, {})), children] }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from "ink";
|
|
3
|
+
import { gap } from "../../design/index.js";
|
|
4
|
+
export default function Stack({ children, direction = "vertical", gap: gapSize = "sm", align = "start" }) {
|
|
5
|
+
const alignItems = align === "start" ? "flex-start" : align === "center" ? "center" : "flex-end";
|
|
6
|
+
return (_jsx(Box, { flexDirection: direction === "vertical" ? "column" : "row", gap: gap[gapSize], alignItems: alignItems, children: children }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { colors, semanticColors } from "../../design/index.js";
|
|
5
|
+
export default function Badge({ children, variant = "default" }) {
|
|
6
|
+
const colorMap = {
|
|
7
|
+
default: semanticColors.text.secondary,
|
|
8
|
+
primary: colors.primary,
|
|
9
|
+
success: colors.approve,
|
|
10
|
+
warning: colors.warning,
|
|
11
|
+
danger: colors.danger,
|
|
12
|
+
muted: colors.muted,
|
|
13
|
+
};
|
|
14
|
+
const color = colorMap[variant];
|
|
15
|
+
return _jsx(Text, { children: chalk.hex(color)(String(children)) });
|
|
16
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { colors, semanticColors } from "../../design/index.js";
|
|
5
|
+
export default function Button({ children, variant = "primary", disabled = false, focused = false }) {
|
|
6
|
+
if (disabled) {
|
|
7
|
+
return _jsx(Text, { children: chalk.hex(semanticColors.text.disabled)(String(children)) });
|
|
8
|
+
}
|
|
9
|
+
const colorMap = {
|
|
10
|
+
primary: colors.primary,
|
|
11
|
+
secondary: semanticColors.text.secondary,
|
|
12
|
+
danger: colors.danger,
|
|
13
|
+
};
|
|
14
|
+
const color = colorMap[variant];
|
|
15
|
+
const text = focused
|
|
16
|
+
? chalk.hex(color).bold(`▶ ${String(children)}`)
|
|
17
|
+
: chalk.hex(color)(String(children));
|
|
18
|
+
return _jsx(Text, { children: text });
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { colors, semanticColors, padding, borderChars } from "../../design/index.js";
|
|
5
|
+
export default function Card({ children, variant = "default", title, padding: paddingSize = "md" }) {
|
|
6
|
+
const pad = padding[paddingSize];
|
|
7
|
+
const borderColor = semanticColors.border.default;
|
|
8
|
+
const borderTop = variant === "outlined"
|
|
9
|
+
? chalk.hex(borderColor)(borderChars.horizontal.repeat(50))
|
|
10
|
+
: "";
|
|
11
|
+
const borderBottom = variant === "outlined"
|
|
12
|
+
? chalk.hex(borderColor)(borderChars.horizontal.repeat(50))
|
|
13
|
+
: "";
|
|
14
|
+
return (_jsxs(Box, { flexDirection: "column", children: [title && (_jsx(Box, { paddingX: pad, paddingY: 1, children: _jsx(Text, { bold: true, children: chalk.hex(colors.foreground)(title) }) })), borderTop && (_jsx(Box, { paddingX: pad, children: _jsx(Text, { children: borderTop }) })), _jsx(Box, { paddingX: pad, paddingY: title ? 1 : pad, children: children }), borderBottom && (_jsx(Box, { paddingX: pad, children: _jsx(Text, { children: borderBottom }) }))] }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { borderChars, semanticColors } from "../../design/index.js";
|
|
5
|
+
export default function Divider({ length = 50, variant = "horizontal" }) {
|
|
6
|
+
const char = variant === "double" ? "═" : borderChars.horizontal;
|
|
7
|
+
const line = char.repeat(length);
|
|
8
|
+
return _jsx(Text, { children: chalk.hex(semanticColors.border.default)(line) });
|
|
9
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import { formatError } from "../../utils/formatters.js";
|
|
4
|
+
import { muted } from "../../lib/theme.js";
|
|
5
|
+
export default function ErrorDisplay({ error, maxWidth = 70, showHelpText = false, helpText }) {
|
|
6
|
+
if (!error)
|
|
7
|
+
return null;
|
|
8
|
+
const errorLines = formatError(error, maxWidth);
|
|
9
|
+
return (_jsxs(Box, { flexDirection: "column", gap: 0, children: [errorLines.map((line, index) => (_jsx(Text, { children: line }, index))), showHelpText && helpText && (_jsxs(_Fragment, { children: [_jsx(Box, { height: 1 }), _jsx(Text, { children: muted(helpText) })] }))] }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import TextInput from "ink-text-input";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { semanticColors, padding } from "../../design/index.js";
|
|
6
|
+
export default function Input({ value, onChange, onSubmit, placeholder, label, error, focused = false, mask, }) {
|
|
7
|
+
const borderColor = error
|
|
8
|
+
? semanticColors.border.error
|
|
9
|
+
: focused
|
|
10
|
+
? semanticColors.border.focus
|
|
11
|
+
: semanticColors.border.default;
|
|
12
|
+
return (_jsxs(Box, { flexDirection: "column", gap: padding.xs, children: [label && (_jsx(Text, { children: chalk.hex(semanticColors.text.primary).bold(label) })), _jsxs(Box, { children: [_jsxs(Text, { children: [chalk.hex(borderColor)(">"), " "] }), _jsx(TextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: placeholder, mask: mask }), focused && _jsx(Text, { children: chalk.inverse(" ") })] }), error && (_jsx(Text, { children: chalk.hex(semanticColors.border.error)(error) }))] }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from "ink";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { colors, gap } from "../../design/index.js";
|
|
5
|
+
export function ListItem({ children, selected = false, focused = false }) {
|
|
6
|
+
const indicator = selected || focused
|
|
7
|
+
? chalk.hex(colors.primary)("▶ ")
|
|
8
|
+
: " ";
|
|
9
|
+
return (_jsx(Box, { children: _jsxs(Text, { children: [indicator, children] }) }));
|
|
10
|
+
}
|
|
11
|
+
export default function List({ children, gap: gapSize = "sm" }) {
|
|
12
|
+
return (_jsx(Box, { flexDirection: "column", gap: gap[gapSize], children: children }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from "ink";
|
|
3
|
+
import { semanticColors, padding } from "../../design/index.js";
|
|
4
|
+
export default function Panel({ children, padding: paddingSize = "md", border = true }) {
|
|
5
|
+
const pad = padding[paddingSize];
|
|
6
|
+
const borderColor = semanticColors.border.default;
|
|
7
|
+
if (!border) {
|
|
8
|
+
return (_jsx(Box, { paddingX: pad, paddingY: pad, children: children }));
|
|
9
|
+
}
|
|
10
|
+
return (_jsx(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", children: _jsx(Box, { paddingX: pad, paddingY: pad, children: children }) }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect } from "react";
|
|
3
|
+
import { Text } from "ink";
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { colors } from "../../design/index.js";
|
|
6
|
+
const spinnerFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
7
|
+
export default function Spinner({ message = "Loading..." }) {
|
|
8
|
+
const [frame, setFrame] = useState(0);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const interval = setInterval(() => {
|
|
11
|
+
setFrame((prev) => (prev + 1) % spinnerFrames.length);
|
|
12
|
+
}, 100);
|
|
13
|
+
return () => clearInterval(interval);
|
|
14
|
+
}, []);
|
|
15
|
+
return (_jsxs(Text, { children: [chalk.hex(colors.primary)(spinnerFrames[frame]), " ", message] }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const borderStyle = {
|
|
2
|
+
none: "none",
|
|
3
|
+
solid: "solid",
|
|
4
|
+
double: "double",
|
|
5
|
+
round: "round",
|
|
6
|
+
bold: "bold",
|
|
7
|
+
};
|
|
8
|
+
export const borderChars = {
|
|
9
|
+
horizontal: "─",
|
|
10
|
+
vertical: "│",
|
|
11
|
+
topLeft: "┌",
|
|
12
|
+
topRight: "┐",
|
|
13
|
+
bottomLeft: "└",
|
|
14
|
+
bottomRight: "┘",
|
|
15
|
+
cross: "┼",
|
|
16
|
+
tLeft: "├",
|
|
17
|
+
tRight: "┤",
|
|
18
|
+
tTop: "┬",
|
|
19
|
+
tBottom: "┴",
|
|
20
|
+
cornerTopLeft: "╭",
|
|
21
|
+
cornerTopRight: "╮",
|
|
22
|
+
cornerBottomLeft: "╰",
|
|
23
|
+
cornerBottomRight: "╯",
|
|
24
|
+
};
|
|
25
|
+
export const borderRadius = {
|
|
26
|
+
none: "",
|
|
27
|
+
sm: " ",
|
|
28
|
+
md: " ",
|
|
29
|
+
lg: " ",
|
|
30
|
+
};
|
|
31
|
+
export const borderWidth = {
|
|
32
|
+
none: 0,
|
|
33
|
+
thin: 1,
|
|
34
|
+
medium: 2,
|
|
35
|
+
thick: 3,
|
|
36
|
+
};
|
|
37
|
+
export function createBorder(style = "round", width = "thin") {
|
|
38
|
+
if (style === "round") {
|
|
39
|
+
return {
|
|
40
|
+
top: borderChars.horizontal.repeat(borderWidth[width]),
|
|
41
|
+
bottom: borderChars.horizontal.repeat(borderWidth[width]),
|
|
42
|
+
left: borderChars.vertical,
|
|
43
|
+
right: borderChars.vertical,
|
|
44
|
+
topLeft: borderChars.topLeft,
|
|
45
|
+
topRight: borderChars.topRight,
|
|
46
|
+
bottomLeft: borderChars.bottomLeft,
|
|
47
|
+
bottomRight: borderChars.bottomRight,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return createBorder("round", width);
|
|
51
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const colors = {
|
|
2
|
+
primary: "#4c6fff",
|
|
3
|
+
secondary: "#17d4ff",
|
|
4
|
+
approve: "#3dd68c",
|
|
5
|
+
warning: "#facc15",
|
|
6
|
+
danger: "#ef4444",
|
|
7
|
+
muted: "#9ca3af",
|
|
8
|
+
foreground: "#ffffff",
|
|
9
|
+
background: "#050816",
|
|
10
|
+
ink: "#050816",
|
|
11
|
+
surface: "#0b1020",
|
|
12
|
+
};
|
|
13
|
+
export const semanticColors = {
|
|
14
|
+
text: {
|
|
15
|
+
primary: colors.foreground,
|
|
16
|
+
secondary: colors.muted,
|
|
17
|
+
disabled: colors.muted,
|
|
18
|
+
},
|
|
19
|
+
background: {
|
|
20
|
+
default: colors.background,
|
|
21
|
+
surface: colors.surface,
|
|
22
|
+
elevated: colors.surface,
|
|
23
|
+
},
|
|
24
|
+
border: {
|
|
25
|
+
default: colors.muted,
|
|
26
|
+
focus: colors.primary,
|
|
27
|
+
error: colors.danger,
|
|
28
|
+
},
|
|
29
|
+
status: {
|
|
30
|
+
pending: colors.warning,
|
|
31
|
+
analyzing: colors.primary,
|
|
32
|
+
completed: colors.approve,
|
|
33
|
+
failed: colors.danger,
|
|
34
|
+
},
|
|
35
|
+
interactive: {
|
|
36
|
+
primary: colors.primary,
|
|
37
|
+
secondary: colors.secondary,
|
|
38
|
+
hover: colors.primary,
|
|
39
|
+
active: colors.primary,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export function getColor(path) {
|
|
43
|
+
const [category, name] = path.split(".");
|
|
44
|
+
return semanticColors[category][name];
|
|
45
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export * from "./colors.js";
|
|
2
|
+
export * from "./typography.js";
|
|
3
|
+
export * from "./spacing.js";
|
|
4
|
+
export * from "./borders.js";
|
|
5
|
+
import { colors } from "./colors.js";
|
|
6
|
+
import { fontSize, fontWeight, lineHeight, textStyles } from "./typography.js";
|
|
7
|
+
import { spacing, padding, margin, gap } from "./spacing.js";
|
|
8
|
+
import { borderStyle, borderChars, borderRadius, borderWidth, createBorder } from "./borders.js";
|
|
9
|
+
export const designSystem = {
|
|
10
|
+
colors,
|
|
11
|
+
typography: {
|
|
12
|
+
fontSize,
|
|
13
|
+
fontWeight,
|
|
14
|
+
lineHeight,
|
|
15
|
+
textStyles,
|
|
16
|
+
},
|
|
17
|
+
spacing: {
|
|
18
|
+
spacing,
|
|
19
|
+
padding,
|
|
20
|
+
margin,
|
|
21
|
+
gap,
|
|
22
|
+
},
|
|
23
|
+
borders: {
|
|
24
|
+
borderStyle,
|
|
25
|
+
borderChars,
|
|
26
|
+
borderRadius,
|
|
27
|
+
borderWidth,
|
|
28
|
+
createBorder,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const spacing = {
|
|
2
|
+
0: 0,
|
|
3
|
+
1: 1,
|
|
4
|
+
2: 2,
|
|
5
|
+
3: 3,
|
|
6
|
+
4: 4,
|
|
7
|
+
5: 5,
|
|
8
|
+
6: 6,
|
|
9
|
+
8: 8,
|
|
10
|
+
10: 10,
|
|
11
|
+
12: 12,
|
|
12
|
+
16: 16,
|
|
13
|
+
20: 20,
|
|
14
|
+
24: 24,
|
|
15
|
+
};
|
|
16
|
+
export const padding = {
|
|
17
|
+
none: spacing[0],
|
|
18
|
+
xs: spacing[1],
|
|
19
|
+
sm: spacing[2],
|
|
20
|
+
md: spacing[4],
|
|
21
|
+
lg: spacing[6],
|
|
22
|
+
xl: spacing[8],
|
|
23
|
+
"2xl": spacing[12],
|
|
24
|
+
};
|
|
25
|
+
export const margin = {
|
|
26
|
+
none: spacing[0],
|
|
27
|
+
xs: spacing[1],
|
|
28
|
+
sm: spacing[2],
|
|
29
|
+
md: spacing[4],
|
|
30
|
+
lg: spacing[6],
|
|
31
|
+
xl: spacing[8],
|
|
32
|
+
"2xl": spacing[12],
|
|
33
|
+
};
|
|
34
|
+
export const gap = {
|
|
35
|
+
none: spacing[0],
|
|
36
|
+
xs: spacing[1],
|
|
37
|
+
sm: spacing[2],
|
|
38
|
+
md: spacing[4],
|
|
39
|
+
lg: spacing[6],
|
|
40
|
+
xl: spacing[8],
|
|
41
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const fontSize = {
|
|
2
|
+
xs: 0.75,
|
|
3
|
+
sm: 0.875,
|
|
4
|
+
base: 1,
|
|
5
|
+
lg: 1.125,
|
|
6
|
+
xl: 1.25,
|
|
7
|
+
"2xl": 1.5,
|
|
8
|
+
"3xl": 1.875,
|
|
9
|
+
"4xl": 2.25,
|
|
10
|
+
};
|
|
11
|
+
export const fontWeight = {
|
|
12
|
+
normal: 400,
|
|
13
|
+
medium: 500,
|
|
14
|
+
semibold: 600,
|
|
15
|
+
bold: 700,
|
|
16
|
+
extrabold: 800,
|
|
17
|
+
};
|
|
18
|
+
export const lineHeight = {
|
|
19
|
+
none: 1,
|
|
20
|
+
tight: 1.25,
|
|
21
|
+
snug: 1.375,
|
|
22
|
+
normal: 1.5,
|
|
23
|
+
relaxed: 1.625,
|
|
24
|
+
loose: 2,
|
|
25
|
+
};
|
|
26
|
+
export const textStyles = {
|
|
27
|
+
title: {
|
|
28
|
+
fontSize: fontSize["3xl"],
|
|
29
|
+
fontWeight: fontWeight.extrabold,
|
|
30
|
+
lineHeight: lineHeight.tight,
|
|
31
|
+
},
|
|
32
|
+
heading: {
|
|
33
|
+
fontSize: fontSize["2xl"],
|
|
34
|
+
fontWeight: fontWeight.bold,
|
|
35
|
+
lineHeight: lineHeight.tight,
|
|
36
|
+
},
|
|
37
|
+
subheading: {
|
|
38
|
+
fontSize: fontSize.xl,
|
|
39
|
+
fontWeight: fontWeight.semibold,
|
|
40
|
+
lineHeight: lineHeight.snug,
|
|
41
|
+
},
|
|
42
|
+
body: {
|
|
43
|
+
fontSize: fontSize.base,
|
|
44
|
+
fontWeight: fontWeight.normal,
|
|
45
|
+
lineHeight: lineHeight.normal,
|
|
46
|
+
},
|
|
47
|
+
bodySmall: {
|
|
48
|
+
fontSize: fontSize.sm,
|
|
49
|
+
fontWeight: fontWeight.normal,
|
|
50
|
+
lineHeight: lineHeight.normal,
|
|
51
|
+
},
|
|
52
|
+
label: {
|
|
53
|
+
fontSize: fontSize.sm,
|
|
54
|
+
fontWeight: fontWeight.medium,
|
|
55
|
+
lineHeight: lineHeight.normal,
|
|
56
|
+
},
|
|
57
|
+
caption: {
|
|
58
|
+
fontSize: fontSize.xs,
|
|
59
|
+
fontWeight: fontWeight.normal,
|
|
60
|
+
lineHeight: lineHeight.normal,
|
|
61
|
+
},
|
|
62
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { render } from "ink";
|
|
4
|
+
import App from "./App.js";
|
|
5
|
+
import dotenv from "dotenv";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { dirname, join } from "path";
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
dotenv.config({ path: join(__dirname, "../.env") });
|
|
11
|
+
dotenv.config({ path: join(__dirname, "../.env.local") });
|
|
12
|
+
process.stdin.on("error", (err) => {
|
|
13
|
+
if (err.code !== "EIO") {
|
|
14
|
+
console.error("stdin error:", err);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
process.on("SIGINT", () => {
|
|
18
|
+
process.exit(0);
|
|
19
|
+
});
|
|
20
|
+
process.on("SIGTERM", () => {
|
|
21
|
+
process.exit(0);
|
|
22
|
+
});
|
|
23
|
+
process.on("uncaughtException", (err) => {
|
|
24
|
+
if (err.code === "EIO") {
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.error("Uncaught exception:", err);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
33
|
+
console.error("Unhandled rejection at:", promise, "reason:", reason);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
36
|
+
process.stdout.write("\x1b[2J\x1b[H");
|
|
37
|
+
const { waitUntilExit } = render(_jsx(App, {}));
|
|
38
|
+
waitUntilExit().catch((err) => {
|
|
39
|
+
if (err.code !== "EIO") {
|
|
40
|
+
console.error("Error waiting for exit:", err);
|
|
41
|
+
}
|
|
42
|
+
process.exit(0);
|
|
43
|
+
});
|