@cdoing/cli 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/.cdoing/permissions.json +8 -0
- package/dist/callbacks.d.ts +17 -0
- package/dist/callbacks.d.ts.map +1 -0
- package/dist/callbacks.js +265 -0
- package/dist/callbacks.js.map +1 -0
- package/dist/chat.d.ts +27 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +57 -0
- package/dist/chat.js.map +1 -0
- package/dist/commands.d.ts +22 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +452 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +84 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +427 -0
- package/dist/config.js.map +1 -0
- package/dist/help.d.ts +9 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +167 -0
- package/dist/help.js.map +1 -0
- package/dist/history.d.ts +51 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +207 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +220 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth.d.ts +13 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +182 -0
- package/dist/oauth.js.map +1 -0
- package/dist/review.d.ts +26 -0
- package/dist/review.d.ts.map +1 -0
- package/dist/review.js +198 -0
- package/dist/review.js.map +1 -0
- package/dist/serve.d.ts +23 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +293 -0
- package/dist/serve.js.map +1 -0
- package/dist/tools.d.ts +14 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +57 -0
- package/dist/tools.js.map +1 -0
- package/dist/ui/App.d.ts +24 -0
- package/dist/ui/App.d.ts.map +1 -0
- package/dist/ui/App.js +321 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/MessageList.d.ts +14 -0
- package/dist/ui/MessageList.d.ts.map +1 -0
- package/dist/ui/MessageList.js +147 -0
- package/dist/ui/MessageList.js.map +1 -0
- package/dist/ui/SessionBrowser.d.ts +18 -0
- package/dist/ui/SessionBrowser.d.ts.map +1 -0
- package/dist/ui/SessionBrowser.js +149 -0
- package/dist/ui/SessionBrowser.js.map +1 -0
- package/dist/ui/SetupWizard.d.ts +23 -0
- package/dist/ui/SetupWizard.d.ts.map +1 -0
- package/dist/ui/SetupWizard.js +402 -0
- package/dist/ui/SetupWizard.js.map +1 -0
- package/dist/ui/Spinner.d.ts +15 -0
- package/dist/ui/Spinner.d.ts.map +1 -0
- package/dist/ui/Spinner.js +111 -0
- package/dist/ui/Spinner.js.map +1 -0
- package/dist/ui/StatusBar.d.ts +16 -0
- package/dist/ui/StatusBar.d.ts.map +1 -0
- package/dist/ui/StatusBar.js +56 -0
- package/dist/ui/StatusBar.js.map +1 -0
- package/dist/ui/UserInput.d.ts +13 -0
- package/dist/ui/UserInput.d.ts.map +1 -0
- package/dist/ui/UserInput.js +872 -0
- package/dist/ui/UserInput.js.map +1 -0
- package/dist/ui/hooks/helpers.d.ts +55 -0
- package/dist/ui/hooks/helpers.d.ts.map +1 -0
- package/dist/ui/hooks/helpers.js +304 -0
- package/dist/ui/hooks/helpers.js.map +1 -0
- package/dist/ui/hooks/useAgent.d.ts +60 -0
- package/dist/ui/hooks/useAgent.d.ts.map +1 -0
- package/dist/ui/hooks/useAgent.js +213 -0
- package/dist/ui/hooks/useAgent.js.map +1 -0
- package/dist/ui/hooks/useChat.d.ts +74 -0
- package/dist/ui/hooks/useChat.d.ts.map +1 -0
- package/dist/ui/hooks/useChat.js +819 -0
- package/dist/ui/hooks/useChat.js.map +1 -0
- package/dist/ui/theme.d.ts +73 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +214 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/types.d.ts +37 -0
- package/dist/ui/types.d.ts.map +1 -0
- package/dist/ui/types.js +3 -0
- package/dist/ui/types.js.map +1 -0
- package/package.json +33 -0
- package/src/callbacks.ts +294 -0
- package/src/chat.ts +72 -0
- package/src/commands.ts +425 -0
- package/src/config.ts +462 -0
- package/src/help.ts +182 -0
- package/src/history.ts +205 -0
- package/src/index.ts +248 -0
- package/src/oauth.ts +164 -0
- package/src/review.ts +233 -0
- package/src/serve.ts +290 -0
- package/src/tools.ts +104 -0
- package/src/ui/App.tsx +426 -0
- package/src/ui/MessageList.tsx +222 -0
- package/src/ui/SessionBrowser.tsx +161 -0
- package/src/ui/SetupWizard.tsx +412 -0
- package/src/ui/Spinner.tsx +103 -0
- package/src/ui/StatusBar.tsx +106 -0
- package/src/ui/UserInput.tsx +954 -0
- package/src/ui/hooks/helpers.ts +271 -0
- package/src/ui/hooks/useAgent.ts +270 -0
- package/src/ui/hooks/useChat.ts +943 -0
- package/src/ui/theme.ts +326 -0
- package/src/ui/types.ts +41 -0
- package/tsconfig.json +18 -0
package/src/ui/theme.ts
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme system — provides dark and light color palettes for the CLI.
|
|
3
|
+
*
|
|
4
|
+
* On light terminals, dark colors (gray, dimColor) become invisible.
|
|
5
|
+
* This module centralizes all colors so every component can adapt.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { loadConfig, saveConfig } from "../config";
|
|
9
|
+
|
|
10
|
+
// ── Theme types ──────────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
export type ThemeName = "dark" | "light" | "auto";
|
|
13
|
+
|
|
14
|
+
export interface ThemeColors {
|
|
15
|
+
// Primary text
|
|
16
|
+
text: string;
|
|
17
|
+
textBold: string;
|
|
18
|
+
textDim: string;
|
|
19
|
+
|
|
20
|
+
// Prompt / input
|
|
21
|
+
prompt: string; // ❯ and ● symbols
|
|
22
|
+
cursor: string; // ▊ cursor
|
|
23
|
+
placeholder: string; // ghost / placeholder text
|
|
24
|
+
|
|
25
|
+
// Accent colors
|
|
26
|
+
accent: string; // primary accent (headers, highlights)
|
|
27
|
+
accentSecondary: string; // secondary accent
|
|
28
|
+
|
|
29
|
+
// Semantic colors
|
|
30
|
+
success: string;
|
|
31
|
+
warning: string;
|
|
32
|
+
error: string;
|
|
33
|
+
info: string;
|
|
34
|
+
|
|
35
|
+
// UI chrome
|
|
36
|
+
border: string;
|
|
37
|
+
separator: string;
|
|
38
|
+
selected: string; // selected item text
|
|
39
|
+
selectedBg: string; // selected item background
|
|
40
|
+
|
|
41
|
+
// Status bar
|
|
42
|
+
provider: string;
|
|
43
|
+
model: string;
|
|
44
|
+
mode: string;
|
|
45
|
+
|
|
46
|
+
// Markdown
|
|
47
|
+
heading1: string;
|
|
48
|
+
heading2: string;
|
|
49
|
+
bullet: string;
|
|
50
|
+
listNumber: string;
|
|
51
|
+
codeBlock: string;
|
|
52
|
+
horizontalRule: string;
|
|
53
|
+
|
|
54
|
+
// Suggestions
|
|
55
|
+
suggestionFile: string;
|
|
56
|
+
suggestionProvider: string;
|
|
57
|
+
suggestionTool: string;
|
|
58
|
+
suggestionDefault: string;
|
|
59
|
+
|
|
60
|
+
// Tool activity
|
|
61
|
+
toolRunning: string;
|
|
62
|
+
toolDone: string;
|
|
63
|
+
toolError: string;
|
|
64
|
+
toolPreview: string;
|
|
65
|
+
|
|
66
|
+
// Spinner
|
|
67
|
+
spinner: string;
|
|
68
|
+
elapsed: string;
|
|
69
|
+
|
|
70
|
+
// Session browser
|
|
71
|
+
sessionTitle: string;
|
|
72
|
+
sessionDate: string;
|
|
73
|
+
sessionMeta: string;
|
|
74
|
+
|
|
75
|
+
// Background jobs
|
|
76
|
+
bgJobs: string;
|
|
77
|
+
|
|
78
|
+
// Context bar colors
|
|
79
|
+
contextLow: string;
|
|
80
|
+
contextMed: string;
|
|
81
|
+
contextHigh: string;
|
|
82
|
+
|
|
83
|
+
// Whether to use dimColor prop (invisible on light terminals)
|
|
84
|
+
useDim: boolean;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// ── Dark theme (default — optimized for dark terminal backgrounds) ──────────
|
|
88
|
+
|
|
89
|
+
const darkTheme: ThemeColors = {
|
|
90
|
+
text: "white",
|
|
91
|
+
textBold: "white",
|
|
92
|
+
textDim: "gray",
|
|
93
|
+
|
|
94
|
+
prompt: "green",
|
|
95
|
+
cursor: "green",
|
|
96
|
+
placeholder: "gray",
|
|
97
|
+
|
|
98
|
+
accent: "cyan",
|
|
99
|
+
accentSecondary: "blueBright",
|
|
100
|
+
|
|
101
|
+
success: "green",
|
|
102
|
+
warning: "yellow",
|
|
103
|
+
error: "red",
|
|
104
|
+
info: "yellow",
|
|
105
|
+
|
|
106
|
+
border: "gray",
|
|
107
|
+
separator: "gray",
|
|
108
|
+
selected: "white",
|
|
109
|
+
selectedBg: "cyan",
|
|
110
|
+
|
|
111
|
+
provider: "cyan",
|
|
112
|
+
model: "white",
|
|
113
|
+
mode: "green",
|
|
114
|
+
|
|
115
|
+
heading1: "blueBright",
|
|
116
|
+
heading2: "cyan",
|
|
117
|
+
bullet: "red",
|
|
118
|
+
listNumber: "magenta",
|
|
119
|
+
codeBlock: "gray",
|
|
120
|
+
horizontalRule: "gray",
|
|
121
|
+
|
|
122
|
+
suggestionFile: "magenta",
|
|
123
|
+
suggestionProvider: "yellow",
|
|
124
|
+
suggestionTool: "green",
|
|
125
|
+
suggestionDefault: "cyan",
|
|
126
|
+
|
|
127
|
+
toolRunning: "yellow",
|
|
128
|
+
toolDone: "green",
|
|
129
|
+
toolError: "red",
|
|
130
|
+
toolPreview: "gray",
|
|
131
|
+
|
|
132
|
+
spinner: "yellow",
|
|
133
|
+
elapsed: "gray",
|
|
134
|
+
|
|
135
|
+
sessionTitle: "white",
|
|
136
|
+
sessionDate: "yellow",
|
|
137
|
+
sessionMeta: "gray",
|
|
138
|
+
|
|
139
|
+
bgJobs: "magenta",
|
|
140
|
+
|
|
141
|
+
contextLow: "green",
|
|
142
|
+
contextMed: "yellow",
|
|
143
|
+
contextHigh: "red",
|
|
144
|
+
|
|
145
|
+
useDim: true,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// ── Light theme (optimized for light / white terminal backgrounds) ──────────
|
|
149
|
+
|
|
150
|
+
const lightTheme: ThemeColors = {
|
|
151
|
+
text: "black",
|
|
152
|
+
textBold: "black",
|
|
153
|
+
textDim: "blackBright",
|
|
154
|
+
|
|
155
|
+
prompt: "green",
|
|
156
|
+
cursor: "green",
|
|
157
|
+
placeholder: "blackBright",
|
|
158
|
+
|
|
159
|
+
accent: "blue",
|
|
160
|
+
accentSecondary: "blue",
|
|
161
|
+
|
|
162
|
+
success: "green",
|
|
163
|
+
warning: "yellow",
|
|
164
|
+
error: "red",
|
|
165
|
+
info: "blue",
|
|
166
|
+
|
|
167
|
+
border: "blackBright",
|
|
168
|
+
separator: "blackBright",
|
|
169
|
+
selected: "white",
|
|
170
|
+
selectedBg: "blue",
|
|
171
|
+
|
|
172
|
+
provider: "blue",
|
|
173
|
+
model: "black",
|
|
174
|
+
mode: "green",
|
|
175
|
+
|
|
176
|
+
heading1: "blue",
|
|
177
|
+
heading2: "blue",
|
|
178
|
+
bullet: "red",
|
|
179
|
+
listNumber: "magenta",
|
|
180
|
+
codeBlock: "blackBright",
|
|
181
|
+
horizontalRule: "blackBright",
|
|
182
|
+
|
|
183
|
+
suggestionFile: "magenta",
|
|
184
|
+
suggestionProvider: "blue",
|
|
185
|
+
suggestionTool: "green",
|
|
186
|
+
suggestionDefault: "blue",
|
|
187
|
+
|
|
188
|
+
toolRunning: "yellow",
|
|
189
|
+
toolDone: "green",
|
|
190
|
+
toolError: "red",
|
|
191
|
+
toolPreview: "blackBright",
|
|
192
|
+
|
|
193
|
+
spinner: "blue",
|
|
194
|
+
elapsed: "blackBright",
|
|
195
|
+
|
|
196
|
+
sessionTitle: "black",
|
|
197
|
+
sessionDate: "blue",
|
|
198
|
+
sessionMeta: "blackBright",
|
|
199
|
+
|
|
200
|
+
bgJobs: "magenta",
|
|
201
|
+
|
|
202
|
+
contextLow: "green",
|
|
203
|
+
contextMed: "yellow",
|
|
204
|
+
contextHigh: "red",
|
|
205
|
+
|
|
206
|
+
useDim: false, // dimColor is invisible on light backgrounds
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// ── Theme registry ───────────────────────────────────────────────────────────
|
|
210
|
+
|
|
211
|
+
const themes: Record<string, ThemeColors> = {
|
|
212
|
+
dark: darkTheme,
|
|
213
|
+
light: lightTheme,
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// ── Auto-detection ───────────────────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Best-effort detect if the terminal has a light background.
|
|
220
|
+
* Checks multiple signals:
|
|
221
|
+
* - COLORFGBG (set by iTerm2, rxvt, some others)
|
|
222
|
+
* - TERMINAL_EMULATOR / TERM_PROGRAM specific defaults
|
|
223
|
+
* - macOS defaults for Terminal.app
|
|
224
|
+
* Falls back to dark if unknown.
|
|
225
|
+
*/
|
|
226
|
+
function detectTheme(): "dark" | "light" {
|
|
227
|
+
// COLORFGBG is the most reliable signal (format: "fg;bg" or "fg;...;bg")
|
|
228
|
+
const colorfgbg = process.env.COLORFGBG;
|
|
229
|
+
if (colorfgbg) {
|
|
230
|
+
const parts = colorfgbg.split(";");
|
|
231
|
+
const bg = parseInt(parts[parts.length - 1], 10);
|
|
232
|
+
// Background color index: 0-6 = dark, 7-15 = light (ANSI palette)
|
|
233
|
+
if (!isNaN(bg) && bg >= 7) return "light";
|
|
234
|
+
if (!isNaN(bg) && bg < 7) return "dark";
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// VS Code terminal sets VSCODE_TERMINAL_DARK env or TERM_PROGRAM=vscode
|
|
238
|
+
const termProgram = process.env.TERM_PROGRAM || "";
|
|
239
|
+
if (termProgram === "vscode") {
|
|
240
|
+
// VS Code sets this for its integrated terminal
|
|
241
|
+
const colorTheme = process.env.VSCODE_CLI_QUALITY || "";
|
|
242
|
+
// Best effort — assume user's VS Code theme matches
|
|
243
|
+
return colorTheme === "stable" ? "dark" : "dark";
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// macOS Terminal.app defaults to a light profile
|
|
247
|
+
if (termProgram === "Apple_Terminal") {
|
|
248
|
+
return "light";
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// iTerm2 — check the profile name or ITERM_PROFILE
|
|
252
|
+
if (termProgram === "iTerm.app") {
|
|
253
|
+
const profile = (process.env.ITERM_PROFILE || "").toLowerCase();
|
|
254
|
+
if (profile.includes("light") || profile.includes("solarized light")) return "light";
|
|
255
|
+
return "dark";
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Windows Terminal
|
|
259
|
+
if (process.env.WT_SESSION) {
|
|
260
|
+
return "dark"; // Windows Terminal defaults to dark
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return "dark";
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// ── Current theme state ──────────────────────────────────────────────────────
|
|
267
|
+
|
|
268
|
+
let _currentThemeName: ThemeName = "auto";
|
|
269
|
+
let _currentTheme: ThemeColors = darkTheme;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Initialize theme from stored config. Call once at startup.
|
|
273
|
+
*/
|
|
274
|
+
export function initTheme(): void {
|
|
275
|
+
const config = loadConfig();
|
|
276
|
+
const stored = (config as any).theme as string | undefined;
|
|
277
|
+
if (stored === "light" || stored === "dark") {
|
|
278
|
+
_currentThemeName = stored;
|
|
279
|
+
_currentTheme = themes[stored];
|
|
280
|
+
} else {
|
|
281
|
+
_currentThemeName = "auto";
|
|
282
|
+
_currentTheme = themes[detectTheme()];
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Get the current theme colors.
|
|
288
|
+
*/
|
|
289
|
+
export function getTheme(): ThemeColors {
|
|
290
|
+
return _currentTheme;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Get the current theme name.
|
|
295
|
+
*/
|
|
296
|
+
export function getThemeName(): ThemeName {
|
|
297
|
+
return _currentThemeName;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Switch theme and persist to config.
|
|
302
|
+
*/
|
|
303
|
+
export function setTheme(name: ThemeName): string {
|
|
304
|
+
_currentThemeName = name;
|
|
305
|
+
if (name === "auto") {
|
|
306
|
+
const detected = detectTheme();
|
|
307
|
+
_currentTheme = themes[detected];
|
|
308
|
+
// Remove theme from config so it auto-detects next time
|
|
309
|
+
const config = loadConfig();
|
|
310
|
+
delete (config as any).theme;
|
|
311
|
+
saveConfig(config);
|
|
312
|
+
return `Theme: auto (detected: ${detected})`;
|
|
313
|
+
}
|
|
314
|
+
_currentTheme = themes[name] || darkTheme;
|
|
315
|
+
const config = loadConfig();
|
|
316
|
+
(config as any).theme = name;
|
|
317
|
+
saveConfig(config);
|
|
318
|
+
return `Theme: ${name}`;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* List available themes.
|
|
323
|
+
*/
|
|
324
|
+
export function getAvailableThemes(): string[] {
|
|
325
|
+
return ["auto", "dark", "light"];
|
|
326
|
+
}
|
package/src/ui/types.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type MessageRole = "user" | "assistant" | "system" | "tool" | "shell";
|
|
2
|
+
|
|
3
|
+
export interface ChatMessage {
|
|
4
|
+
id: string;
|
|
5
|
+
role: MessageRole;
|
|
6
|
+
content: string;
|
|
7
|
+
toolName?: string;
|
|
8
|
+
isError?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ToolActivity {
|
|
12
|
+
name: string;
|
|
13
|
+
preview: string;
|
|
14
|
+
status: "running" | "done" | "error";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface UsageInfo {
|
|
18
|
+
inputTokens: number;
|
|
19
|
+
outputTokens: number;
|
|
20
|
+
totalTokens: number;
|
|
21
|
+
cost?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface ContextUsage {
|
|
25
|
+
/** Current context input tokens (running total for this session) */
|
|
26
|
+
inputTokens: number;
|
|
27
|
+
/** Max tokens for the active model's context window */
|
|
28
|
+
maxTokens: number;
|
|
29
|
+
/** Percentage used (0–100) */
|
|
30
|
+
percent: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface BackgroundJob {
|
|
34
|
+
id: string;
|
|
35
|
+
prompt: string;
|
|
36
|
+
status: "running" | "done" | "error";
|
|
37
|
+
result?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
startedAt: number;
|
|
40
|
+
completedAt?: number;
|
|
41
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"declaration": true,
|
|
11
|
+
"declarationMap": true,
|
|
12
|
+
"sourceMap": true,
|
|
13
|
+
"resolveJsonModule": true,
|
|
14
|
+
"jsx": "react"
|
|
15
|
+
},
|
|
16
|
+
"include": ["src/**/*"],
|
|
17
|
+
"exclude": ["node_modules", "dist"]
|
|
18
|
+
}
|