@cdoing/opentuicli 0.1.21 → 0.1.26

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.
@@ -1,148 +0,0 @@
1
- /**
2
- * Home Route — landing screen with logo, project info, shortcuts, and quick actions
3
- *
4
- * Responsive: adapts layout based on terminal dimensions.
5
- * - Small terminals (< 60 cols or < 20 rows): compact layout, no logo
6
- * - Medium terminals: smaller logo, condensed info
7
- * - Large terminals: full figlet logo, spacious layout
8
- */
9
-
10
- import { TextAttributes } from "@opentui/core";
11
- import { useTerminalDimensions } from "@opentui/react";
12
- import { useTheme } from "../context/theme";
13
- import { InputArea } from "../components/input-area";
14
- import type { ImageAttachment } from "@cdoing/ai";
15
-
16
- // Full figlet logo (ANSI Shadow)
17
- const LOGO_FULL = [
18
- " ██████╗██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ",
19
- "██╔════╝██╔══██╗██╔═══██╗██║████╗ ██║██╔════╝ ",
20
- "██║ ██║ ██║██║ ██║██║██╔██╗ ██║██║ ███╗",
21
- "██║ ██║ ██║██║ ██║██║██║╚██╗██║██║ ██║",
22
- "╚██████╗██████╔╝╚██████╔╝██║██║ ╚████║╚██████╔╝",
23
- " ╚═════╝╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ",
24
- ];
25
-
26
- // Compact logo for smaller terminals
27
- const LOGO_COMPACT = [
28
- "┌─┐┌┐ ┌─┐┬┌┐┌┌─┐",
29
- "│ │││ ││││││││ ┬",
30
- "└─┘└┘└─┘└─┘┘└┘└─┘",
31
- ];
32
-
33
- export function Home(props: {
34
- provider: string;
35
- model: string;
36
- workingDir: string;
37
- themeId: string;
38
- onAction?: (action: string) => void;
39
- onSubmit?: (text: string, images?: ImageAttachment[]) => void;
40
- }) {
41
- const { theme } = useTheme();
42
- const t = theme;
43
- const dims = useTerminalDimensions();
44
- const w = dims.width || 80;
45
- const h = dims.height || 24;
46
-
47
- const shortDir = () => {
48
- const home = process.env.HOME || "";
49
- const d = props.workingDir;
50
- return home && d.startsWith(home) ? "~" + d.slice(home.length) : d;
51
- };
52
-
53
- const subtitle = "Multi-provider AI coding assistant";
54
- const version = "v0.1.1";
55
-
56
- // Determine layout size
57
- const isSmall = w < 60 || h < 20;
58
- const isMedium = !isSmall && (w < 80 || h < 30);
59
-
60
- // Pick logo
61
- const logo = isSmall ? null : isMedium ? LOGO_COMPACT : LOGO_FULL;
62
-
63
- // Build info lines
64
- const infoLines = [
65
- ["Provider", props.provider],
66
- ["Model", props.model],
67
- ["Theme", props.themeId],
68
- ["Directory", shortDir()],
69
- ];
70
- const maxKeyLen = Math.max(...infoLines.map(([k]) => k.length));
71
-
72
- // Quick actions
73
- const actions = [
74
- { key: "Enter", label: "Send message / start session", id: "start" },
75
- { key: "Ctrl+P", label: "Command palette", id: "commands" },
76
- { key: "Ctrl+O", label: "Switch model", id: "model" },
77
- { key: "Ctrl+T", label: "Change theme", id: "theme" },
78
- { key: "Ctrl+N", label: "New session", id: "new" },
79
- { key: "Ctrl+S", label: "Browse sessions", id: "sessions" },
80
- { key: "/setup", label: "Setup wizard", id: "setup" },
81
- { key: "Ctrl+C", label: "Quit", id: "quit" },
82
- ];
83
- const maxActionKey = Math.max(...actions.map((a) => a.key.length));
84
-
85
- return (
86
- <box flexDirection="column" flexGrow={1} flexShrink={1} overflow="hidden">
87
- <box flexDirection="column" alignItems="center" justifyContent="center" flexGrow={1}>
88
- {/* Logo */}
89
- {logo && logo.map((line, i) => (
90
- <text key={`logo-${i}`} fg={t.primary} attributes={TextAttributes.BOLD}>
91
- {line}
92
- </text>
93
- ))}
94
-
95
- {/* Subtitle + version */}
96
- <text fg={t.textDim}>
97
- {subtitle}
98
- </text>
99
- <text fg={t.textMuted}>
100
- {version}
101
- </text>
102
-
103
- <text>{""}</text>
104
-
105
- {/* Info section */}
106
- {infoLines.map(([key, val], i) => {
107
- const line = `${key.padStart(maxKeyLen)} ${val}`;
108
- return (
109
- <text key={`info-${i}`} fg={t.textDim}>
110
- {line}
111
- </text>
112
- );
113
- })}
114
-
115
- <text>{""}</text>
116
-
117
- {/* Actions */}
118
- <text fg={t.primary} attributes={TextAttributes.BOLD}>
119
- {"Actions"}
120
- </text>
121
- {actions.map((action, i) => {
122
- const line = `${action.key.padStart(maxActionKey)} ${action.label}`;
123
- return (
124
- <text key={`act-${i}`} fg={t.textMuted}>
125
- {line}
126
- </text>
127
- );
128
- })}
129
-
130
- <text>{""}</text>
131
-
132
- {/* Footer */}
133
- <text fg={t.textDim}>
134
- {"Powered by @opentui/react + @cdoing/ai"}
135
- </text>
136
- </box>
137
-
138
- {/* Input bar at bottom — user can start typing immediately */}
139
- {props.onSubmit && (
140
- <InputArea
141
- onSubmit={props.onSubmit}
142
- workingDir={props.workingDir}
143
- placeholder="Start typing to begin a session... (/ commands, @ context)"
144
- />
145
- )}
146
- </box>
147
- );
148
- }