@drisp/cli 0.4.1 → 0.4.4

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.
@@ -0,0 +1,502 @@
1
+ // src/ui/theme/themes.ts
2
+ var darkTheme = {
3
+ name: "dark",
4
+ // ── Text hierarchy ──────────────────────────────────────
5
+ text: "#c9d1d9",
6
+ // Primary text. Warm gray, not pure white.
7
+ textMuted: "#848d97",
8
+ // Dim text. Bumped from #6e7681 for AA compliance (~4.8:1).
9
+ textInverse: "#0d1117",
10
+ // Text on colored backgrounds.
11
+ // ── Accent ──────────────────────────────────────────────
12
+ border: "#2d333b",
13
+ // Bumped from #1e2a38 for visibility (~2.2:1 vs bg).
14
+ accent: "#58a6ff",
15
+ // Blue. Focus bar, branding, selection, links.
16
+ accentSecondary: "#bc8cff",
17
+ // Soft purple. Permission events.
18
+ // ── Status ──────────────────────────────────────────────
19
+ status: {
20
+ success: "#3fb950",
21
+ // Green. Completion, done glyphs.
22
+ error: "#f85149",
23
+ // Red. Failures, blocks, Tool Fail.
24
+ warning: "#d29922",
25
+ // Amber. Active stage, zero-result tint, caution.
26
+ info: "#58a6ff",
27
+ // Blue. Agent messages, Run OK.
28
+ working: "#d29922",
29
+ // Amber. Spinner state (same as warning).
30
+ neutral: "#9da5ae"
31
+ // Mid gray. Bumped from #8b949e for AA (~4.8:1).
32
+ },
33
+ // ── Context bar ─────────────────────────────────────────
34
+ contextBar: {
35
+ track: "#1e2a38",
36
+ // Empty segment track.
37
+ low: "#3fb950",
38
+ // Green. 0–50% budget used.
39
+ medium: "#d29922",
40
+ // Amber. 50–80% budget used.
41
+ high: "#f85149"
42
+ // Red. 80–100% budget used.
43
+ },
44
+ // ── Dialog borders ──────────────────────────────────────
45
+ dialog: {
46
+ borderPermission: "#d29922",
47
+ // Amber border for permission prompts.
48
+ borderQuestion: "#58a6ff"
49
+ // Blue border for question prompts.
50
+ },
51
+ // ── Input ───────────────────────────────────────────────
52
+ inputPrompt: "#388bfd",
53
+ // Blue "input" keyword in prompt.
54
+ inputChevron: "#484f58",
55
+ // Bumped from #30363d for visibility (~2.8:1).
56
+ inputBackground: "#141a21",
57
+ // Slight lift so the input row reads as its own surface.
58
+ // ── Feed ────────────────────────────────────────────────
59
+ feed: {
60
+ headerLabel: "#848d97",
61
+ // Matches textMuted.
62
+ stripeBackground: "#161b22",
63
+ // Bumped from #0d1521 for visible alternation.
64
+ focusBackground: "#1b2a3f"
65
+ // Blue tint for focused row.
66
+ },
67
+ // ── User messages ───────────────────────────────────────
68
+ userMessage: {
69
+ text: "#6e7681",
70
+ // Dimmed text for user messages in the message panel.
71
+ background: "#151d2b",
72
+ // Blue-tinted lift — differentiates user turns from agent.
73
+ border: "#30363d",
74
+ // Subtle border.
75
+ agentBorder: "#2a4a6a",
76
+ // Steel blue left border for agent messages.
77
+ focusBorder: "#58a6ff"
78
+ // Accent blue for focused message indicator.
79
+ },
80
+ // ── Badges ──────────────────────────────────────────────
81
+ badge: {
82
+ error: { bg: "#4b1014", fg: "#ff7b72" },
83
+ running: { bg: "#4a3a0c", fg: "#fbbf24" },
84
+ idle: { bg: "#10321d", fg: "#3fb950" },
85
+ search: { bg: "#1b2a3f" },
86
+ command: { bg: "#2a1b3f" }
87
+ },
88
+ // ── Detail view ─────────────────────────────────────────
89
+ detail: {
90
+ title: "#c9d1d9",
91
+ subject: "#58a6ff"
92
+ },
93
+ // ── Tool pills ──────────────────────────────────────────
94
+ toolPill: {
95
+ safe: { bg: "#0e2233", fg: "#5ba3cc" },
96
+ mutating: { bg: "#2a1d0a", fg: "#d4a44a" },
97
+ browser: { bg: "#0b2625", fg: "#5cc4ba" },
98
+ neutral: { bg: "#141a22", fg: "#7d8590" },
99
+ skill: { bg: "#2a0f24", fg: "#c98ab8" },
100
+ "subagent.spawn": { bg: "#0a2e22", fg: "#5cc4a0" },
101
+ "subagent.return": { bg: "#0a2e22", fg: "#56b492" }
102
+ }
103
+ };
104
+ var lightTheme = {
105
+ name: "light",
106
+ // ── Text hierarchy ──────────────────────────────────────
107
+ text: "#1f2328",
108
+ // Near-black. Strong contrast.
109
+ textMuted: "#656d76",
110
+ // Medium gray. Same role as dark textMuted.
111
+ textInverse: "#ffffff",
112
+ // White on colored backgrounds.
113
+ // ── Accent ──────────────────────────────────────────────
114
+ border: "#8c959f",
115
+ // Darker neutral border so frame lines stay visible on white.
116
+ accent: "#0969da",
117
+ // Darker blue for light backgrounds.
118
+ accentSecondary: "#8250df",
119
+ // Purple, darkened for readability.
120
+ // ── Status ──────────────────────────────────────────────
121
+ status: {
122
+ success: "#1a7f37",
123
+ // Dark green. Readable on white.
124
+ error: "#cf222e",
125
+ // Dark red.
126
+ warning: "#9a6700",
127
+ // Dark amber.
128
+ info: "#0969da",
129
+ // Dark blue. Matches accent.
130
+ working: "#9a6700",
131
+ // Dark amber.
132
+ neutral: "#656d76"
133
+ // Mid gray.
134
+ },
135
+ // ── Context bar ─────────────────────────────────────────
136
+ contextBar: {
137
+ track: "#d0d7de",
138
+ // Light gray track.
139
+ low: "#1a7f37",
140
+ medium: "#9a6700",
141
+ high: "#cf222e"
142
+ },
143
+ // ── Dialog borders ──────────────────────────────────────
144
+ dialog: {
145
+ borderPermission: "#9a6700",
146
+ borderQuestion: "#0969da"
147
+ },
148
+ // ── Input ───────────────────────────────────────────────
149
+ inputPrompt: "#0969da",
150
+ inputChevron: "#656d76",
151
+ inputBackground: "#f3f6f9",
152
+ // ── Feed ────────────────────────────────────────────────
153
+ feed: {
154
+ headerLabel: "#656d76",
155
+ stripeBackground: "#f6f8fa",
156
+ focusBackground: "#ddf4ff"
157
+ // Light blue tint for focused row.
158
+ },
159
+ // ── User messages ───────────────────────────────────────
160
+ userMessage: {
161
+ text: "#8b949e",
162
+ // Dimmed text for user messages in the message panel.
163
+ background: "#edf2fb",
164
+ // Blue-tinted lift — differentiates user turns from agent.
165
+ border: "#8c959f",
166
+ agentBorder: "#6cb0e0",
167
+ // Medium blue on white bg.
168
+ focusBorder: "#0969da"
169
+ // Accent blue for focused message indicator.
170
+ },
171
+ // ── Badges ──────────────────────────────────────────────
172
+ badge: {
173
+ error: { bg: "#ffebe9", fg: "#cf222e" },
174
+ running: { bg: "#fff8c5", fg: "#9a6700" },
175
+ idle: { bg: "#dafbe1", fg: "#1a7f37" },
176
+ search: { bg: "#ddf4ff" },
177
+ command: { bg: "#fbefff" }
178
+ },
179
+ // ── Detail view ─────────────────────────────────────────
180
+ detail: {
181
+ title: "#1f2328",
182
+ subject: "#0969da"
183
+ },
184
+ // ── Tool pills ──────────────────────────────────────────
185
+ toolPill: {
186
+ safe: { bg: "#ddf4ff", fg: "#0550ae" },
187
+ mutating: { bg: "#fff8c5", fg: "#7c5200" },
188
+ browser: { bg: "#dafbe1", fg: "#116329" },
189
+ neutral: { bg: "#f6f8fa", fg: "#424a53" },
190
+ skill: { bg: "#fbefff", fg: "#6639ba" },
191
+ "subagent.spawn": { bg: "#dafbe1", fg: "#116329" },
192
+ "subagent.return": { bg: "#dafbe1", fg: "#1a7f37" }
193
+ }
194
+ };
195
+ var highContrastTheme = {
196
+ name: "high-contrast",
197
+ // ── Text hierarchy ──────────────────────────────────────
198
+ text: "#f0f6fc",
199
+ // Near-white. Maximum brightness.
200
+ textMuted: "#9ea7b3",
201
+ // Bumped from #7d8590 for better contrast (~5.2:1).
202
+ textInverse: "#010409",
203
+ // Near-black.
204
+ // ── Accent ──────────────────────────────────────────────
205
+ border: "#71b7ff",
206
+ accent: "#71b7ff",
207
+ // Brighter blue. Punches through.
208
+ accentSecondary: "#d2a8ff",
209
+ // Bright purple.
210
+ // ── Status ──────────────────────────────────────────────
211
+ status: {
212
+ success: "#56d364",
213
+ // Bright green. Higher saturation.
214
+ error: "#ff7b72",
215
+ // Bright red. Softened for readability.
216
+ warning: "#e3b341",
217
+ // Bright amber.
218
+ info: "#71b7ff",
219
+ // Bright blue.
220
+ working: "#e3b341",
221
+ // Bright amber.
222
+ neutral: "#b1bac4"
223
+ // Bumped from #9ea7b3 for HC (~6.0:1).
224
+ },
225
+ // ── Context bar ─────────────────────────────────────────
226
+ contextBar: {
227
+ track: "#3d444d",
228
+ // HC track — brighter than dark.
229
+ low: "#56d364",
230
+ medium: "#e3b341",
231
+ high: "#ff7b72"
232
+ },
233
+ // ── Dialog borders ──────────────────────────────────────
234
+ dialog: {
235
+ borderPermission: "#e3b341",
236
+ borderQuestion: "#71b7ff"
237
+ },
238
+ // ── Input ───────────────────────────────────────────────
239
+ inputPrompt: "#71b7ff",
240
+ inputChevron: "#9ea7b3",
241
+ // Bumped from #7d8590 for visibility.
242
+ inputBackground: "#16202b",
243
+ // ── Feed ────────────────────────────────────────────────
244
+ feed: {
245
+ headerLabel: "#9ea7b3",
246
+ // Matches textMuted.
247
+ stripeBackground: "#0d1521",
248
+ // Bumped from #0b141f for visible alternation.
249
+ focusBackground: "#1a3350"
250
+ // Brighter blue tint for HC.
251
+ },
252
+ // ── User messages ───────────────────────────────────────
253
+ userMessage: {
254
+ text: "#7d8590",
255
+ // Dimmed text for user messages in the message panel.
256
+ background: "#1a2436",
257
+ // Blue-tinted lift — differentiates user turns from agent.
258
+ border: "#444c56",
259
+ // Bumped from #3d444d for HC visibility.
260
+ agentBorder: "#5599cc",
261
+ // Brighter blue for HC.
262
+ focusBorder: "#71b7ff"
263
+ // Accent blue for focused message indicator.
264
+ },
265
+ // ── Badges ──────────────────────────────────────────────
266
+ badge: {
267
+ error: { bg: "#6e1b16", fg: "#ff7b72" },
268
+ running: { bg: "#5c4813", fg: "#e3b341" },
269
+ idle: { bg: "#154228", fg: "#56d364" },
270
+ search: { bg: "#1a3350" },
271
+ command: { bg: "#301e50" }
272
+ },
273
+ // ── Detail view ─────────────────────────────────────────
274
+ detail: {
275
+ title: "#f0f6fc",
276
+ subject: "#71b7ff"
277
+ },
278
+ // ── Tool pills ──────────────────────────────────────────
279
+ toolPill: {
280
+ safe: { bg: "#122d42", fg: "#a2d2ff" },
281
+ mutating: { bg: "#3a2e10", fg: "#f0d070" },
282
+ browser: { bg: "#0f3520", fg: "#7ee28b" },
283
+ neutral: { bg: "#1c2128", fg: "#b1bac4" },
284
+ skill: { bg: "#2b1a40", fg: "#e0c0ff" },
285
+ "subagent.spawn": { bg: "#0f3520", fg: "#7ee28b" },
286
+ "subagent.return": { bg: "#0f3520", fg: "#6bcc79" }
287
+ }
288
+ };
289
+ var THEMES = {
290
+ dark: darkTheme,
291
+ light: lightTheme,
292
+ "high-contrast": highContrastTheme
293
+ };
294
+ function resolveTheme(name) {
295
+ if (name && name in THEMES) {
296
+ return THEMES[name];
297
+ }
298
+ return darkTheme;
299
+ }
300
+
301
+ // src/ui/theme/ThemeContext.tsx
302
+ import { createContext, useContext } from "react";
303
+ var ThemeContext = createContext(darkTheme);
304
+ var ThemeProvider = ThemeContext.Provider;
305
+ function useTheme() {
306
+ return useContext(ThemeContext);
307
+ }
308
+
309
+ // src/setup/components/StepStatus.tsx
310
+ import { Text, Box } from "ink";
311
+ import { jsx, jsxs } from "react/jsx-runtime";
312
+ function StepStatus({ status, message }) {
313
+ const theme = useTheme();
314
+ const icon = status === "success" ? "\u2713" : status === "error" ? "\u2717" : "\u280B";
315
+ const color = status === "success" ? theme.status.success : status === "error" ? theme.status.error : theme.status.working;
316
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", marginTop: 1, children: [
317
+ /* @__PURE__ */ jsxs(Text, { color, bold: true, children: [
318
+ icon,
319
+ " "
320
+ ] }),
321
+ /* @__PURE__ */ jsx(Text, { color, children: message })
322
+ ] });
323
+ }
324
+
325
+ // src/setup/steps/McpOptionsStep.tsx
326
+ import { useState as useState2, useCallback, useEffect as useEffect2, useRef as useRef2 } from "react";
327
+ import { Box as Box3, Text as Text3 } from "ink";
328
+
329
+ // src/setup/components/StepSelector.tsx
330
+ import { useEffect, useRef, useState } from "react";
331
+ import { Box as Box2, Text as Text2, useInput } from "ink";
332
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
333
+ function getInitialCursor(options, initialValue) {
334
+ if (initialValue) {
335
+ const initialIndex = options.findIndex(
336
+ (option) => option.value === initialValue && !option.disabled
337
+ );
338
+ if (initialIndex >= 0) {
339
+ return initialIndex;
340
+ }
341
+ }
342
+ const firstEnabled = options.findIndex((option) => !option.disabled);
343
+ return firstEnabled >= 0 ? firstEnabled : 0;
344
+ }
345
+ function StepSelector({
346
+ options,
347
+ onSelect,
348
+ isActive = true,
349
+ initialValue,
350
+ onHighlight,
351
+ gap = 0
352
+ }) {
353
+ const theme = useTheme();
354
+ const [cursor, setCursor] = useState(
355
+ () => getInitialCursor(options, initialValue)
356
+ );
357
+ const highlightedRef = useRef(void 0);
358
+ const moveCursor = (direction) => {
359
+ setCursor((prev) => {
360
+ if (options.length <= 1) {
361
+ return prev;
362
+ }
363
+ let next = prev;
364
+ for (let i = 0; i < options.length; i += 1) {
365
+ const candidate = Math.max(
366
+ 0,
367
+ Math.min(next + direction, options.length - 1)
368
+ );
369
+ if (candidate === next) {
370
+ return prev;
371
+ }
372
+ next = candidate;
373
+ if (!options[next]?.disabled) {
374
+ return next;
375
+ }
376
+ }
377
+ return prev;
378
+ });
379
+ };
380
+ useInput(
381
+ (_input, key) => {
382
+ if (key.downArrow) {
383
+ moveCursor(1);
384
+ } else if (key.upArrow) {
385
+ moveCursor(-1);
386
+ } else if (key.return) {
387
+ const opt = options[cursor];
388
+ if (!opt.disabled) {
389
+ onSelect(opt.value);
390
+ }
391
+ }
392
+ },
393
+ { isActive }
394
+ );
395
+ useEffect(() => {
396
+ if (!onHighlight) {
397
+ return;
398
+ }
399
+ const option = options[cursor];
400
+ if (option.disabled) {
401
+ return;
402
+ }
403
+ if (highlightedRef.current === option.value) {
404
+ return;
405
+ }
406
+ highlightedRef.current = option.value;
407
+ onHighlight(option.value);
408
+ }, [cursor, options, onHighlight]);
409
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", gap, children: options.map((opt, i) => {
410
+ const isCursor = i === cursor;
411
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
412
+ /* @__PURE__ */ jsxs2(
413
+ Text2,
414
+ {
415
+ color: opt.disabled ? theme.textMuted : isCursor ? theme.accent : theme.text,
416
+ bold: isCursor && !opt.disabled,
417
+ inverse: isCursor && !opt.disabled,
418
+ dimColor: opt.disabled,
419
+ children: [
420
+ isCursor ? " > " : " ",
421
+ opt.label,
422
+ isCursor ? " " : ""
423
+ ]
424
+ }
425
+ ),
426
+ opt.description && !opt.disabled ? /* @__PURE__ */ jsx2(Box2, { paddingLeft: 5, children: /* @__PURE__ */ jsxs2(Text2, { dimColor: true, italic: true, children: [
427
+ "\u21B3 ",
428
+ opt.description
429
+ ] }) }) : null
430
+ ] }, opt.value);
431
+ }) });
432
+ }
433
+
434
+ // src/setup/steps/McpOptionsStep.tsx
435
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
436
+ function McpOptionsStep({ servers, onComplete }) {
437
+ const theme = useTheme();
438
+ const [serverIndex, setServerIndex] = useState2(0);
439
+ const choicesRef = useRef2({});
440
+ const autoSkippedRef = useRef2(false);
441
+ useEffect2(() => {
442
+ if (servers.length === 0 && !autoSkippedRef.current) {
443
+ autoSkippedRef.current = true;
444
+ onComplete({});
445
+ }
446
+ }, [servers.length, onComplete]);
447
+ const handleSelect = useCallback(
448
+ (value) => {
449
+ const server = servers[serverIndex];
450
+ const selectedOption = server.options[Number(value)];
451
+ choicesRef.current = {
452
+ ...choicesRef.current,
453
+ [server.serverName]: selectedOption.env
454
+ };
455
+ if (serverIndex + 1 < servers.length) {
456
+ setServerIndex((prev) => prev + 1);
457
+ } else {
458
+ onComplete(choicesRef.current);
459
+ }
460
+ },
461
+ [serverIndex, servers, onComplete]
462
+ );
463
+ if (servers.length === 0) {
464
+ return null;
465
+ }
466
+ const currentServer = servers[serverIndex];
467
+ const selectorOptions = currentServer.options.map((opt, i) => ({
468
+ label: i === 0 ? `${opt.label} (default)` : opt.label,
469
+ value: String(i)
470
+ }));
471
+ return /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", children: [
472
+ /* @__PURE__ */ jsx3(Text3, { bold: true, color: theme.accent, children: "Configure MCP servers" }),
473
+ /* @__PURE__ */ jsxs3(Text3, { color: theme.textMuted, children: [
474
+ "Server ",
475
+ serverIndex + 1,
476
+ " of ",
477
+ servers.length,
478
+ ":",
479
+ " ",
480
+ /* @__PURE__ */ jsx3(Text3, { bold: true, children: currentServer.serverName })
481
+ ] }),
482
+ /* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx3(
483
+ StepSelector,
484
+ {
485
+ options: selectorOptions,
486
+ onSelect: handleSelect
487
+ },
488
+ currentServer.serverName
489
+ ) })
490
+ ] });
491
+ }
492
+
493
+ export {
494
+ darkTheme,
495
+ resolveTheme,
496
+ ThemeProvider,
497
+ useTheme,
498
+ StepSelector,
499
+ StepStatus,
500
+ McpOptionsStep
501
+ };
502
+ //# sourceMappingURL=chunk-2HR7FV3M.js.map