@rlabs-inc/gemini-mcp 0.6.2 → 0.7.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 +46 -43
- package/dist/cli/commands/config.d.ts +8 -0
- package/dist/cli/commands/config.js +147 -0
- package/dist/cli/commands/image.d.ts +7 -0
- package/dist/cli/commands/image.js +133 -0
- package/dist/cli/commands/query.d.ts +7 -0
- package/dist/cli/commands/query.js +94 -0
- package/dist/cli/commands/research.d.ts +7 -0
- package/dist/cli/commands/research.js +147 -0
- package/dist/cli/commands/search.d.ts +7 -0
- package/dist/cli/commands/search.js +152 -0
- package/dist/cli/commands/speak.d.ts +7 -0
- package/dist/cli/commands/speak.js +168 -0
- package/dist/cli/commands/tokens.d.ts +8 -0
- package/dist/cli/commands/tokens.js +105 -0
- package/dist/cli/commands/video.d.ts +7 -0
- package/dist/cli/commands/video.js +154 -0
- package/dist/cli/config.d.ts +23 -0
- package/dist/cli/config.js +89 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.js +180 -0
- package/dist/cli/ui/box.d.ts +20 -0
- package/dist/cli/ui/box.js +112 -0
- package/dist/cli/ui/colors.d.ts +46 -0
- package/dist/cli/ui/colors.js +106 -0
- package/dist/cli/ui/index.d.ts +21 -0
- package/dist/cli/ui/index.js +42 -0
- package/dist/cli/ui/progress.d.ts +37 -0
- package/dist/cli/ui/progress.js +125 -0
- package/dist/cli/ui/spinner.d.ts +42 -0
- package/dist/cli/ui/spinner.js +96 -0
- package/dist/cli/ui/theme.d.ts +48 -0
- package/dist/cli/ui/theme.js +200 -0
- package/dist/gemini-client.d.ts +1 -0
- package/dist/gemini-client.js +35 -8
- package/dist/index.d.ts +6 -3
- package/dist/index.js +26 -218
- package/dist/server.d.ts +7 -0
- package/dist/server.js +221 -0
- package/dist/tools/deep-research.js +9 -2
- package/package.json +9 -3
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Color Utilities
|
|
3
|
+
*
|
|
4
|
+
* Uses ANSI escape codes directly for zero dependencies.
|
|
5
|
+
* Respects NO_COLOR and FORCE_COLOR environment variables.
|
|
6
|
+
* Bun handles these natively in TTY detection.
|
|
7
|
+
*/
|
|
8
|
+
// ANSI escape codes
|
|
9
|
+
const ESC = '\x1b[';
|
|
10
|
+
const RESET = `${ESC}0m`;
|
|
11
|
+
// Check if colors should be used
|
|
12
|
+
function shouldUseColors() {
|
|
13
|
+
// NO_COLOR takes precedence (https://no-color.org/)
|
|
14
|
+
if (process.env.NO_COLOR !== undefined)
|
|
15
|
+
return false;
|
|
16
|
+
// FORCE_COLOR overrides TTY detection
|
|
17
|
+
if (process.env.FORCE_COLOR !== undefined)
|
|
18
|
+
return true;
|
|
19
|
+
// Check if stdout is a TTY
|
|
20
|
+
return process.stdout.isTTY ?? false;
|
|
21
|
+
}
|
|
22
|
+
const colorsEnabled = shouldUseColors();
|
|
23
|
+
// Color function factory
|
|
24
|
+
function createColor(code) {
|
|
25
|
+
return (text) => {
|
|
26
|
+
if (!colorsEnabled)
|
|
27
|
+
return text;
|
|
28
|
+
return `${ESC}${code}m${text}${RESET}`;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Foreground colors
|
|
32
|
+
export const black = createColor('30');
|
|
33
|
+
export const red = createColor('31');
|
|
34
|
+
export const green = createColor('32');
|
|
35
|
+
export const yellow = createColor('33');
|
|
36
|
+
export const blue = createColor('34');
|
|
37
|
+
export const magenta = createColor('35');
|
|
38
|
+
export const cyan = createColor('36');
|
|
39
|
+
export const white = createColor('37');
|
|
40
|
+
// Bright foreground colors
|
|
41
|
+
export const brightBlack = createColor('90');
|
|
42
|
+
export const brightRed = createColor('91');
|
|
43
|
+
export const brightGreen = createColor('92');
|
|
44
|
+
export const brightYellow = createColor('93');
|
|
45
|
+
export const brightBlue = createColor('94');
|
|
46
|
+
export const brightMagenta = createColor('95');
|
|
47
|
+
export const brightCyan = createColor('96');
|
|
48
|
+
export const brightWhite = createColor('97');
|
|
49
|
+
// Background colors
|
|
50
|
+
export const bgBlack = createColor('40');
|
|
51
|
+
export const bgRed = createColor('41');
|
|
52
|
+
export const bgGreen = createColor('42');
|
|
53
|
+
export const bgYellow = createColor('43');
|
|
54
|
+
export const bgBlue = createColor('44');
|
|
55
|
+
export const bgMagenta = createColor('45');
|
|
56
|
+
export const bgCyan = createColor('46');
|
|
57
|
+
export const bgWhite = createColor('47');
|
|
58
|
+
// Text styles
|
|
59
|
+
export const bold = createColor('1');
|
|
60
|
+
export const dim = createColor('2');
|
|
61
|
+
export const italic = createColor('3');
|
|
62
|
+
export const underline = createColor('4');
|
|
63
|
+
export const inverse = createColor('7');
|
|
64
|
+
export const strikethrough = createColor('9');
|
|
65
|
+
// RGB color support (for themes)
|
|
66
|
+
export function rgb(r, g, b) {
|
|
67
|
+
return (text) => {
|
|
68
|
+
if (!colorsEnabled)
|
|
69
|
+
return text;
|
|
70
|
+
return `${ESC}38;2;${r};${g};${b}m${text}${RESET}`;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function bgRgb(r, g, b) {
|
|
74
|
+
return (text) => {
|
|
75
|
+
if (!colorsEnabled)
|
|
76
|
+
return text;
|
|
77
|
+
return `${ESC}48;2;${r};${g};${b}m${text}${RESET}`;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// 256 color support
|
|
81
|
+
export function color256(code) {
|
|
82
|
+
return (text) => {
|
|
83
|
+
if (!colorsEnabled)
|
|
84
|
+
return text;
|
|
85
|
+
return `${ESC}38;5;${code}m${text}${RESET}`;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Hex color support (convenience)
|
|
89
|
+
export function hex(hexColor) {
|
|
90
|
+
const h = hexColor.replace('#', '');
|
|
91
|
+
const r = parseInt(h.substring(0, 2), 16);
|
|
92
|
+
const g = parseInt(h.substring(2, 4), 16);
|
|
93
|
+
const b = parseInt(h.substring(4, 6), 16);
|
|
94
|
+
return rgb(r, g, b);
|
|
95
|
+
}
|
|
96
|
+
// Utility exports
|
|
97
|
+
export const colors = {
|
|
98
|
+
enabled: colorsEnabled,
|
|
99
|
+
reset: RESET,
|
|
100
|
+
};
|
|
101
|
+
// Chainable style builder
|
|
102
|
+
export function style(...styles) {
|
|
103
|
+
return (text) => {
|
|
104
|
+
return styles.reduce((t, s) => s(t), text);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Components for Gemini CLI
|
|
3
|
+
*
|
|
4
|
+
* Beautiful, theme-aware terminal UI components.
|
|
5
|
+
*/
|
|
6
|
+
export * from './colors.js';
|
|
7
|
+
export { getTheme, setTheme, t, themes } from './theme.js';
|
|
8
|
+
export type { Theme } from './theme.js';
|
|
9
|
+
export { Spinner, spinner, spinners } from './spinner.js';
|
|
10
|
+
export type { SpinnerOptions } from './spinner.js';
|
|
11
|
+
export { Progress, progress } from './progress.js';
|
|
12
|
+
export type { ProgressOptions } from './progress.js';
|
|
13
|
+
export { box, header, success, error, warning, info } from './box.js';
|
|
14
|
+
export type { BoxOptions } from './box.js';
|
|
15
|
+
export declare function print(message: string): void;
|
|
16
|
+
export declare function printSuccess(message: string): void;
|
|
17
|
+
export declare function printError(message: string): void;
|
|
18
|
+
export declare function printWarning(message: string): void;
|
|
19
|
+
export declare function printInfo(message: string): void;
|
|
20
|
+
export declare function printMuted(message: string): void;
|
|
21
|
+
export declare function nl(count?: number): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Components for Gemini CLI
|
|
3
|
+
*
|
|
4
|
+
* Beautiful, theme-aware terminal UI components.
|
|
5
|
+
*/
|
|
6
|
+
// Colors
|
|
7
|
+
export * from './colors.js';
|
|
8
|
+
// Theme system
|
|
9
|
+
export { getTheme, setTheme, t, themes } from './theme.js';
|
|
10
|
+
// Components
|
|
11
|
+
export { Spinner, spinner, spinners } from './spinner.js';
|
|
12
|
+
export { Progress, progress } from './progress.js';
|
|
13
|
+
export { box, header, success, error, warning, info } from './box.js';
|
|
14
|
+
// Quick print helpers using theme
|
|
15
|
+
import { getTheme } from './theme.js';
|
|
16
|
+
export function print(message) {
|
|
17
|
+
console.log(message);
|
|
18
|
+
}
|
|
19
|
+
export function printSuccess(message) {
|
|
20
|
+
const theme = getTheme();
|
|
21
|
+
console.log(`${theme.colors.success(theme.symbols.success)} ${message}`);
|
|
22
|
+
}
|
|
23
|
+
export function printError(message) {
|
|
24
|
+
const theme = getTheme();
|
|
25
|
+
console.error(`${theme.colors.error(theme.symbols.error)} ${message}`);
|
|
26
|
+
}
|
|
27
|
+
export function printWarning(message) {
|
|
28
|
+
const theme = getTheme();
|
|
29
|
+
console.log(`${theme.colors.warning(theme.symbols.warning)} ${message}`);
|
|
30
|
+
}
|
|
31
|
+
export function printInfo(message) {
|
|
32
|
+
const theme = getTheme();
|
|
33
|
+
console.log(`${theme.colors.info(theme.symbols.info)} ${message}`);
|
|
34
|
+
}
|
|
35
|
+
export function printMuted(message) {
|
|
36
|
+
const theme = getTheme();
|
|
37
|
+
console.log(theme.colors.muted(message));
|
|
38
|
+
}
|
|
39
|
+
// Newline helper
|
|
40
|
+
export function nl(count = 1) {
|
|
41
|
+
console.log('\n'.repeat(count - 1));
|
|
42
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Bar for CLI
|
|
3
|
+
*
|
|
4
|
+
* Animated progress indicators for long-running operations.
|
|
5
|
+
*/
|
|
6
|
+
export interface ProgressOptions {
|
|
7
|
+
total?: number;
|
|
8
|
+
width?: number;
|
|
9
|
+
complete?: string;
|
|
10
|
+
incomplete?: string;
|
|
11
|
+
head?: string;
|
|
12
|
+
showPercent?: boolean;
|
|
13
|
+
showEta?: boolean;
|
|
14
|
+
showValue?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare class Progress {
|
|
17
|
+
private current;
|
|
18
|
+
private total;
|
|
19
|
+
private width;
|
|
20
|
+
private complete;
|
|
21
|
+
private incomplete;
|
|
22
|
+
private head;
|
|
23
|
+
private showPercent;
|
|
24
|
+
private showEta;
|
|
25
|
+
private showValue;
|
|
26
|
+
private startTime;
|
|
27
|
+
private stream;
|
|
28
|
+
private label;
|
|
29
|
+
constructor(options?: ProgressOptions);
|
|
30
|
+
start(label?: string): this;
|
|
31
|
+
update(value: number, label?: string): this;
|
|
32
|
+
increment(amount?: number): this;
|
|
33
|
+
private render;
|
|
34
|
+
done(message?: string): void;
|
|
35
|
+
fail(message?: string): void;
|
|
36
|
+
}
|
|
37
|
+
export declare function progress(options?: ProgressOptions): Progress;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress Bar for CLI
|
|
3
|
+
*
|
|
4
|
+
* Animated progress indicators for long-running operations.
|
|
5
|
+
*/
|
|
6
|
+
import { getTheme } from './theme.js';
|
|
7
|
+
export class Progress {
|
|
8
|
+
current = 0;
|
|
9
|
+
total;
|
|
10
|
+
width;
|
|
11
|
+
complete;
|
|
12
|
+
incomplete;
|
|
13
|
+
head;
|
|
14
|
+
showPercent;
|
|
15
|
+
showEta;
|
|
16
|
+
showValue;
|
|
17
|
+
startTime = Date.now();
|
|
18
|
+
stream = process.stderr;
|
|
19
|
+
label = '';
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
const theme = getTheme();
|
|
22
|
+
this.total = options.total ?? 100;
|
|
23
|
+
this.width = options.width ?? 30;
|
|
24
|
+
this.complete = options.complete ?? '█';
|
|
25
|
+
this.incomplete = options.incomplete ?? '░';
|
|
26
|
+
this.head = options.head ?? '█';
|
|
27
|
+
this.showPercent = options.showPercent ?? true;
|
|
28
|
+
this.showEta = options.showEta ?? true;
|
|
29
|
+
this.showValue = options.showValue ?? false;
|
|
30
|
+
}
|
|
31
|
+
start(label) {
|
|
32
|
+
if (label)
|
|
33
|
+
this.label = label;
|
|
34
|
+
this.startTime = Date.now();
|
|
35
|
+
this.current = 0;
|
|
36
|
+
// Hide cursor
|
|
37
|
+
this.stream.write('\x1b[?25l');
|
|
38
|
+
this.render();
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
update(value, label) {
|
|
42
|
+
this.current = Math.min(value, this.total);
|
|
43
|
+
if (label)
|
|
44
|
+
this.label = label;
|
|
45
|
+
this.render();
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
increment(amount = 1) {
|
|
49
|
+
return this.update(this.current + amount);
|
|
50
|
+
}
|
|
51
|
+
render() {
|
|
52
|
+
const theme = getTheme();
|
|
53
|
+
const percent = this.current / this.total;
|
|
54
|
+
const completed = Math.floor(this.width * percent);
|
|
55
|
+
const remaining = this.width - completed;
|
|
56
|
+
// Build bar
|
|
57
|
+
let bar = '';
|
|
58
|
+
if (completed > 0) {
|
|
59
|
+
bar += theme.colors.primary(this.complete.repeat(completed - 1));
|
|
60
|
+
bar += theme.colors.highlight(this.head);
|
|
61
|
+
}
|
|
62
|
+
bar += theme.colors.muted(this.incomplete.repeat(remaining));
|
|
63
|
+
// Build status
|
|
64
|
+
const parts = [];
|
|
65
|
+
if (this.label) {
|
|
66
|
+
parts.push(this.label);
|
|
67
|
+
}
|
|
68
|
+
parts.push(bar);
|
|
69
|
+
if (this.showPercent) {
|
|
70
|
+
parts.push(theme.colors.text(`${Math.floor(percent * 100)}%`));
|
|
71
|
+
}
|
|
72
|
+
if (this.showValue) {
|
|
73
|
+
parts.push(theme.colors.muted(`(${this.current}/${this.total})`));
|
|
74
|
+
}
|
|
75
|
+
if (this.showEta && percent > 0 && percent < 1) {
|
|
76
|
+
const elapsed = (Date.now() - this.startTime) / 1000;
|
|
77
|
+
const estimatedTotal = elapsed / percent;
|
|
78
|
+
const eta = Math.ceil(estimatedTotal - elapsed);
|
|
79
|
+
parts.push(theme.colors.muted(`(${formatTime(eta)})`));
|
|
80
|
+
}
|
|
81
|
+
this.stream.write(`\r\x1b[K${parts.join(' ')}`);
|
|
82
|
+
}
|
|
83
|
+
done(message) {
|
|
84
|
+
const theme = getTheme();
|
|
85
|
+
this.current = this.total;
|
|
86
|
+
// Clear and show final state
|
|
87
|
+
this.stream.write('\r\x1b[K');
|
|
88
|
+
if (message) {
|
|
89
|
+
this.stream.write(`${theme.colors.success(theme.symbols.success)} ${message}\n`);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const elapsed = (Date.now() - this.startTime) / 1000;
|
|
93
|
+
this.stream.write(`${theme.colors.success(theme.symbols.success)} ${this.label || 'Complete'} ` +
|
|
94
|
+
`${theme.colors.muted(`(${formatTime(elapsed)})`)}\n`);
|
|
95
|
+
}
|
|
96
|
+
// Show cursor
|
|
97
|
+
this.stream.write('\x1b[?25h');
|
|
98
|
+
}
|
|
99
|
+
fail(message) {
|
|
100
|
+
const theme = getTheme();
|
|
101
|
+
this.stream.write('\r\x1b[K');
|
|
102
|
+
this.stream.write(`${theme.colors.error(theme.symbols.error)} ${message || 'Failed'}\n`);
|
|
103
|
+
this.stream.write('\x1b[?25h');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Format seconds to human readable
|
|
107
|
+
function formatTime(seconds) {
|
|
108
|
+
if (seconds < 60) {
|
|
109
|
+
return `${Math.ceil(seconds)}s`;
|
|
110
|
+
}
|
|
111
|
+
else if (seconds < 3600) {
|
|
112
|
+
const mins = Math.floor(seconds / 60);
|
|
113
|
+
const secs = Math.ceil(seconds % 60);
|
|
114
|
+
return `${mins}m ${secs}s`;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
const hours = Math.floor(seconds / 3600);
|
|
118
|
+
const mins = Math.floor((seconds % 3600) / 60);
|
|
119
|
+
return `${hours}h ${mins}m`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Convenience function
|
|
123
|
+
export function progress(options) {
|
|
124
|
+
return new Progress(options);
|
|
125
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animated Spinner for CLI
|
|
3
|
+
*
|
|
4
|
+
* Beautiful loading indicators that work in any terminal.
|
|
5
|
+
*/
|
|
6
|
+
export interface SpinnerOptions {
|
|
7
|
+
text?: string;
|
|
8
|
+
color?: (text: string) => string;
|
|
9
|
+
frames?: string[];
|
|
10
|
+
interval?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class Spinner {
|
|
13
|
+
private text;
|
|
14
|
+
private color;
|
|
15
|
+
private frames;
|
|
16
|
+
private interval;
|
|
17
|
+
private currentFrame;
|
|
18
|
+
private timer;
|
|
19
|
+
private stream;
|
|
20
|
+
constructor(options?: SpinnerOptions);
|
|
21
|
+
start(text?: string): this;
|
|
22
|
+
private render;
|
|
23
|
+
update(text: string): this;
|
|
24
|
+
stop(): this;
|
|
25
|
+
success(text?: string): void;
|
|
26
|
+
error(text?: string): void;
|
|
27
|
+
warn(text?: string): void;
|
|
28
|
+
info(text?: string): void;
|
|
29
|
+
private stopWithSymbol;
|
|
30
|
+
}
|
|
31
|
+
export declare function spinner(options?: SpinnerOptions | string): Spinner;
|
|
32
|
+
export declare const spinners: {
|
|
33
|
+
dots: string[];
|
|
34
|
+
line: string[];
|
|
35
|
+
circle: string[];
|
|
36
|
+
arc: string[];
|
|
37
|
+
pulse: string[];
|
|
38
|
+
bounce: string[];
|
|
39
|
+
arrows: string[];
|
|
40
|
+
moon: string[];
|
|
41
|
+
clock: string[];
|
|
42
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animated Spinner for CLI
|
|
3
|
+
*
|
|
4
|
+
* Beautiful loading indicators that work in any terminal.
|
|
5
|
+
*/
|
|
6
|
+
import { getTheme } from './theme.js';
|
|
7
|
+
export class Spinner {
|
|
8
|
+
text;
|
|
9
|
+
color;
|
|
10
|
+
frames;
|
|
11
|
+
interval;
|
|
12
|
+
currentFrame = 0;
|
|
13
|
+
timer = null;
|
|
14
|
+
stream = process.stderr;
|
|
15
|
+
constructor(options = {}) {
|
|
16
|
+
const theme = getTheme();
|
|
17
|
+
this.text = options.text ?? 'Loading...';
|
|
18
|
+
this.color = options.color ?? theme.colors.primary;
|
|
19
|
+
this.frames = options.frames ?? theme.symbols.spinner;
|
|
20
|
+
this.interval = options.interval ?? 80;
|
|
21
|
+
}
|
|
22
|
+
start(text) {
|
|
23
|
+
if (text)
|
|
24
|
+
this.text = text;
|
|
25
|
+
if (this.timer)
|
|
26
|
+
return this;
|
|
27
|
+
// Hide cursor
|
|
28
|
+
this.stream.write('\x1b[?25l');
|
|
29
|
+
this.timer = setInterval(() => {
|
|
30
|
+
this.render();
|
|
31
|
+
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
|
|
32
|
+
}, this.interval);
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
35
|
+
render() {
|
|
36
|
+
// Clear line and write spinner
|
|
37
|
+
const frame = this.color(this.frames[this.currentFrame]);
|
|
38
|
+
this.stream.write(`\r${frame} ${this.text}`);
|
|
39
|
+
}
|
|
40
|
+
update(text) {
|
|
41
|
+
this.text = text;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
stop() {
|
|
45
|
+
if (this.timer) {
|
|
46
|
+
clearInterval(this.timer);
|
|
47
|
+
this.timer = null;
|
|
48
|
+
}
|
|
49
|
+
// Clear line and show cursor
|
|
50
|
+
this.stream.write('\r\x1b[K\x1b[?25h');
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
success(text) {
|
|
54
|
+
this.stopWithSymbol('success', text);
|
|
55
|
+
}
|
|
56
|
+
error(text) {
|
|
57
|
+
this.stopWithSymbol('error', text);
|
|
58
|
+
}
|
|
59
|
+
warn(text) {
|
|
60
|
+
this.stopWithSymbol('warning', text);
|
|
61
|
+
}
|
|
62
|
+
info(text) {
|
|
63
|
+
this.stopWithSymbol('info', text);
|
|
64
|
+
}
|
|
65
|
+
stopWithSymbol(type, text) {
|
|
66
|
+
if (this.timer) {
|
|
67
|
+
clearInterval(this.timer);
|
|
68
|
+
this.timer = null;
|
|
69
|
+
}
|
|
70
|
+
const theme = getTheme();
|
|
71
|
+
const symbol = theme.symbols[type];
|
|
72
|
+
const color = theme.colors[type];
|
|
73
|
+
const message = text ?? this.text;
|
|
74
|
+
// Clear line, print result, show cursor
|
|
75
|
+
this.stream.write(`\r\x1b[K${color(symbol)} ${message}\n\x1b[?25h`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Convenience function
|
|
79
|
+
export function spinner(options) {
|
|
80
|
+
if (typeof options === 'string') {
|
|
81
|
+
return new Spinner({ text: options });
|
|
82
|
+
}
|
|
83
|
+
return new Spinner(options);
|
|
84
|
+
}
|
|
85
|
+
// Pre-configured spinners for common operations
|
|
86
|
+
export const spinners = {
|
|
87
|
+
dots: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
|
|
88
|
+
line: ['-', '\\', '|', '/'],
|
|
89
|
+
circle: ['◐', '◓', '◑', '◒'],
|
|
90
|
+
arc: ['◜', '◠', '◝', '◞', '◡', '◟'],
|
|
91
|
+
pulse: ['█', '▓', '▒', '░', '▒', '▓'],
|
|
92
|
+
bounce: ['⠁', '⠂', '⠄', '⠂'],
|
|
93
|
+
arrows: ['←', '↖', '↑', '↗', '→', '↘', '↓', '↙'],
|
|
94
|
+
moon: ['🌑', '🌒', '🌓', '🌔', '🌕', '🌖', '🌗', '🌘'],
|
|
95
|
+
clock: ['🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚', '🕛'],
|
|
96
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme System for Gemini CLI
|
|
3
|
+
*
|
|
4
|
+
* Provides beautiful, consistent styling across all CLI output.
|
|
5
|
+
* Default theme adapts to terminal colors.
|
|
6
|
+
*/
|
|
7
|
+
export interface Theme {
|
|
8
|
+
name: string;
|
|
9
|
+
colors: {
|
|
10
|
+
primary: (text: string) => string;
|
|
11
|
+
secondary: (text: string) => string;
|
|
12
|
+
success: (text: string) => string;
|
|
13
|
+
error: (text: string) => string;
|
|
14
|
+
warning: (text: string) => string;
|
|
15
|
+
info: (text: string) => string;
|
|
16
|
+
muted: (text: string) => string;
|
|
17
|
+
text: (text: string) => string;
|
|
18
|
+
highlight: (text: string) => string;
|
|
19
|
+
};
|
|
20
|
+
symbols: {
|
|
21
|
+
success: string;
|
|
22
|
+
error: string;
|
|
23
|
+
warning: string;
|
|
24
|
+
info: string;
|
|
25
|
+
spinner: string[];
|
|
26
|
+
arrow: string;
|
|
27
|
+
bullet: string;
|
|
28
|
+
pointer: string;
|
|
29
|
+
star: string;
|
|
30
|
+
};
|
|
31
|
+
box: {
|
|
32
|
+
topLeft: string;
|
|
33
|
+
topRight: string;
|
|
34
|
+
bottomLeft: string;
|
|
35
|
+
bottomRight: string;
|
|
36
|
+
horizontal: string;
|
|
37
|
+
vertical: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export declare const terminalTheme: Theme;
|
|
41
|
+
export declare const neonTheme: Theme;
|
|
42
|
+
export declare const minimalTheme: Theme;
|
|
43
|
+
export declare const oceanTheme: Theme;
|
|
44
|
+
export declare const forestTheme: Theme;
|
|
45
|
+
export declare const themes: Record<string, Theme>;
|
|
46
|
+
export declare function setTheme(themeName: string): void;
|
|
47
|
+
export declare function getTheme(): Theme;
|
|
48
|
+
export declare function t(): Theme;
|