@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.
Files changed (118) hide show
  1. package/.cdoing/permissions.json +8 -0
  2. package/dist/callbacks.d.ts +17 -0
  3. package/dist/callbacks.d.ts.map +1 -0
  4. package/dist/callbacks.js +265 -0
  5. package/dist/callbacks.js.map +1 -0
  6. package/dist/chat.d.ts +27 -0
  7. package/dist/chat.d.ts.map +1 -0
  8. package/dist/chat.js +57 -0
  9. package/dist/chat.js.map +1 -0
  10. package/dist/commands.d.ts +22 -0
  11. package/dist/commands.d.ts.map +1 -0
  12. package/dist/commands.js +452 -0
  13. package/dist/commands.js.map +1 -0
  14. package/dist/config.d.ts +84 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +427 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/help.d.ts +9 -0
  19. package/dist/help.d.ts.map +1 -0
  20. package/dist/help.js +167 -0
  21. package/dist/help.js.map +1 -0
  22. package/dist/history.d.ts +51 -0
  23. package/dist/history.d.ts.map +1 -0
  24. package/dist/history.js +207 -0
  25. package/dist/history.js.map +1 -0
  26. package/dist/index.d.ts +7 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +220 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/oauth.d.ts +13 -0
  31. package/dist/oauth.d.ts.map +1 -0
  32. package/dist/oauth.js +182 -0
  33. package/dist/oauth.js.map +1 -0
  34. package/dist/review.d.ts +26 -0
  35. package/dist/review.d.ts.map +1 -0
  36. package/dist/review.js +198 -0
  37. package/dist/review.js.map +1 -0
  38. package/dist/serve.d.ts +23 -0
  39. package/dist/serve.d.ts.map +1 -0
  40. package/dist/serve.js +293 -0
  41. package/dist/serve.js.map +1 -0
  42. package/dist/tools.d.ts +14 -0
  43. package/dist/tools.d.ts.map +1 -0
  44. package/dist/tools.js +57 -0
  45. package/dist/tools.js.map +1 -0
  46. package/dist/ui/App.d.ts +24 -0
  47. package/dist/ui/App.d.ts.map +1 -0
  48. package/dist/ui/App.js +321 -0
  49. package/dist/ui/App.js.map +1 -0
  50. package/dist/ui/MessageList.d.ts +14 -0
  51. package/dist/ui/MessageList.d.ts.map +1 -0
  52. package/dist/ui/MessageList.js +147 -0
  53. package/dist/ui/MessageList.js.map +1 -0
  54. package/dist/ui/SessionBrowser.d.ts +18 -0
  55. package/dist/ui/SessionBrowser.d.ts.map +1 -0
  56. package/dist/ui/SessionBrowser.js +149 -0
  57. package/dist/ui/SessionBrowser.js.map +1 -0
  58. package/dist/ui/SetupWizard.d.ts +23 -0
  59. package/dist/ui/SetupWizard.d.ts.map +1 -0
  60. package/dist/ui/SetupWizard.js +402 -0
  61. package/dist/ui/SetupWizard.js.map +1 -0
  62. package/dist/ui/Spinner.d.ts +15 -0
  63. package/dist/ui/Spinner.d.ts.map +1 -0
  64. package/dist/ui/Spinner.js +111 -0
  65. package/dist/ui/Spinner.js.map +1 -0
  66. package/dist/ui/StatusBar.d.ts +16 -0
  67. package/dist/ui/StatusBar.d.ts.map +1 -0
  68. package/dist/ui/StatusBar.js +56 -0
  69. package/dist/ui/StatusBar.js.map +1 -0
  70. package/dist/ui/UserInput.d.ts +13 -0
  71. package/dist/ui/UserInput.d.ts.map +1 -0
  72. package/dist/ui/UserInput.js +872 -0
  73. package/dist/ui/UserInput.js.map +1 -0
  74. package/dist/ui/hooks/helpers.d.ts +55 -0
  75. package/dist/ui/hooks/helpers.d.ts.map +1 -0
  76. package/dist/ui/hooks/helpers.js +304 -0
  77. package/dist/ui/hooks/helpers.js.map +1 -0
  78. package/dist/ui/hooks/useAgent.d.ts +60 -0
  79. package/dist/ui/hooks/useAgent.d.ts.map +1 -0
  80. package/dist/ui/hooks/useAgent.js +213 -0
  81. package/dist/ui/hooks/useAgent.js.map +1 -0
  82. package/dist/ui/hooks/useChat.d.ts +74 -0
  83. package/dist/ui/hooks/useChat.d.ts.map +1 -0
  84. package/dist/ui/hooks/useChat.js +819 -0
  85. package/dist/ui/hooks/useChat.js.map +1 -0
  86. package/dist/ui/theme.d.ts +73 -0
  87. package/dist/ui/theme.d.ts.map +1 -0
  88. package/dist/ui/theme.js +214 -0
  89. package/dist/ui/theme.js.map +1 -0
  90. package/dist/ui/types.d.ts +37 -0
  91. package/dist/ui/types.d.ts.map +1 -0
  92. package/dist/ui/types.js +3 -0
  93. package/dist/ui/types.js.map +1 -0
  94. package/package.json +33 -0
  95. package/src/callbacks.ts +294 -0
  96. package/src/chat.ts +72 -0
  97. package/src/commands.ts +425 -0
  98. package/src/config.ts +462 -0
  99. package/src/help.ts +182 -0
  100. package/src/history.ts +205 -0
  101. package/src/index.ts +248 -0
  102. package/src/oauth.ts +164 -0
  103. package/src/review.ts +233 -0
  104. package/src/serve.ts +290 -0
  105. package/src/tools.ts +104 -0
  106. package/src/ui/App.tsx +426 -0
  107. package/src/ui/MessageList.tsx +222 -0
  108. package/src/ui/SessionBrowser.tsx +161 -0
  109. package/src/ui/SetupWizard.tsx +412 -0
  110. package/src/ui/Spinner.tsx +103 -0
  111. package/src/ui/StatusBar.tsx +106 -0
  112. package/src/ui/UserInput.tsx +954 -0
  113. package/src/ui/hooks/helpers.ts +271 -0
  114. package/src/ui/hooks/useAgent.ts +270 -0
  115. package/src/ui/hooks/useChat.ts +943 -0
  116. package/src/ui/theme.ts +326 -0
  117. package/src/ui/types.ts +41 -0
  118. package/tsconfig.json +18 -0
@@ -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
+ }
@@ -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
+ }