mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-18 14:44:21 +01:00
feat(goose-cli): theme persistence & selection (#1693)
Co-authored-by: Bradley Axen <baxen@squareup.com>
This commit is contained in:
@@ -11,6 +11,7 @@ pub enum InputResult {
|
|||||||
AddExtension(String),
|
AddExtension(String),
|
||||||
AddBuiltin(String),
|
AddBuiltin(String),
|
||||||
ToggleTheme,
|
ToggleTheme,
|
||||||
|
SelectTheme(String),
|
||||||
Retry,
|
Retry,
|
||||||
ListPrompts(Option<String>),
|
ListPrompts(Option<String>),
|
||||||
PromptCommand(PromptCommandOptions),
|
PromptCommand(PromptCommandOptions),
|
||||||
@@ -103,6 +104,22 @@ fn handle_slash_command(input: &str) -> Option<InputResult> {
|
|||||||
Some(InputResult::Retry)
|
Some(InputResult::Retry)
|
||||||
}
|
}
|
||||||
"/t" => Some(InputResult::ToggleTheme),
|
"/t" => Some(InputResult::ToggleTheme),
|
||||||
|
s if s.starts_with("/t ") => {
|
||||||
|
let t = s
|
||||||
|
.strip_prefix("/t ")
|
||||||
|
.unwrap_or_default()
|
||||||
|
.trim()
|
||||||
|
.to_lowercase();
|
||||||
|
if ["light", "dark", "ansi"].contains(&t.as_str()) {
|
||||||
|
Some(InputResult::SelectTheme(t))
|
||||||
|
} else {
|
||||||
|
println!(
|
||||||
|
"Theme Unavailable: {} Available themes are: light, dark, ansi",
|
||||||
|
t
|
||||||
|
);
|
||||||
|
Some(InputResult::Retry)
|
||||||
|
}
|
||||||
|
}
|
||||||
"/prompts" => Some(InputResult::ListPrompts(None)),
|
"/prompts" => Some(InputResult::ListPrompts(None)),
|
||||||
s if s.starts_with(CMD_PROMPTS) => {
|
s if s.starts_with(CMD_PROMPTS) => {
|
||||||
// Parse arguments for /prompts command
|
// Parse arguments for /prompts command
|
||||||
@@ -234,6 +251,7 @@ fn print_help() {
|
|||||||
"Available commands:
|
"Available commands:
|
||||||
/exit or /quit - Exit the session
|
/exit or /quit - Exit the session
|
||||||
/t - Toggle Light/Dark/Ansi theme
|
/t - Toggle Light/Dark/Ansi theme
|
||||||
|
/t <name> - Set theme directly (light, dark, ansi)
|
||||||
/extension <command> - Add a stdio extension (format: ENV1=val1 command args...)
|
/extension <command> - Add a stdio extension (format: ENV1=val1 command args...)
|
||||||
/builtin <names> - Add builtin extensions by name (comma-separated)
|
/builtin <names> - Add builtin extensions by name (comma-separated)
|
||||||
/prompts [--extension <name>] - List all available prompts, optionally filtered by extension
|
/prompts [--extension <name>] - List all available prompts, optionally filtered by extension
|
||||||
|
|||||||
@@ -499,6 +499,28 @@ impl Session {
|
|||||||
output::set_theme(new_theme);
|
output::set_theme(new_theme);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input::InputResult::SelectTheme(theme_name) => {
|
||||||
|
save_history(&mut editor);
|
||||||
|
|
||||||
|
let new_theme = match theme_name.as_str() {
|
||||||
|
"light" => {
|
||||||
|
println!("Switching to Light theme");
|
||||||
|
output::Theme::Light
|
||||||
|
}
|
||||||
|
"dark" => {
|
||||||
|
println!("Switching to Dark theme");
|
||||||
|
output::Theme::Dark
|
||||||
|
}
|
||||||
|
"ansi" => {
|
||||||
|
println!("Switching to Ansi theme");
|
||||||
|
output::Theme::Ansi
|
||||||
|
}
|
||||||
|
_ => output::Theme::Dark,
|
||||||
|
};
|
||||||
|
output::set_theme(new_theme);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
input::InputResult::Retry => continue,
|
input::InputResult::Retry => continue,
|
||||||
input::InputResult::ListPrompts(extension) => {
|
input::InputResult::ListPrompts(extension) => {
|
||||||
save_history(&mut editor);
|
save_history(&mut editor);
|
||||||
|
|||||||
@@ -67,6 +67,17 @@ pub fn set_theme(theme: Theme) {
|
|||||||
.set_param("GOOSE_CLI_THEME", Value::String(theme.as_config_string()))
|
.set_param("GOOSE_CLI_THEME", Value::String(theme.as_config_string()))
|
||||||
.expect("Failed to set theme");
|
.expect("Failed to set theme");
|
||||||
CURRENT_THEME.with(|t| *t.borrow_mut() = theme);
|
CURRENT_THEME.with(|t| *t.borrow_mut() = theme);
|
||||||
|
|
||||||
|
let config = Config::global();
|
||||||
|
let theme_str = match theme {
|
||||||
|
Theme::Light => "light",
|
||||||
|
Theme::Dark => "dark",
|
||||||
|
Theme::Ansi => "ansi",
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = config.set_param("GOOSE_CLI_THEME", Value::String(theme_str.to_string())) {
|
||||||
|
eprintln!("Failed to save theme setting to config: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_theme() -> Theme {
|
pub fn get_theme() -> Theme {
|
||||||
|
|||||||
@@ -556,6 +556,14 @@ All commands support tab completion. Press `<Tab>` after a slash (/) to cycle th
|
|||||||
|
|
||||||
Goose CLI supports several shortcuts and built-in commands for easier navigation.
|
Goose CLI supports several shortcuts and built-in commands for easier navigation.
|
||||||
|
|
||||||
|
### Keyboard Navigation
|
||||||
|
|
||||||
- **`Ctrl+C`** - Interrupt the current request
|
- **`Ctrl+C`** - Interrupt the current request
|
||||||
- **`Ctrl+J`** - Add a newline
|
- **`Ctrl+J`** - Add a newline
|
||||||
- **`Cmd+Up/Down arrows`** - Navigate through command history
|
- **`Cmd+Up/Down arrows`** - Navigate through command history
|
||||||
|
|
||||||
|
### Slash Commands
|
||||||
|
- **`/exit` or `/quit`** - Exit the session
|
||||||
|
- **`/t`** - Toggle between Light/Dark/Ansi themes
|
||||||
|
- **`/t <theme>`** - Set theme directly (`/t light`, `/t dark`, or `/t ansi`)
|
||||||
|
- **`/?` or `/help`** - Display the help menu
|
||||||
|
|||||||
@@ -319,7 +319,8 @@ export function useMessageStream({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fetch updated session metadata with token counts
|
// Fetch updated session metadata with token counts
|
||||||
const sessionId = (extraMetadataRef.current.body as Record<string, unknown>)?.session_id as string;
|
const sessionId = (extraMetadataRef.current.body as Record<string, unknown>)
|
||||||
|
?.session_id as string;
|
||||||
if (sessionId) {
|
if (sessionId) {
|
||||||
try {
|
try {
|
||||||
const sessionResponse = await getSessionHistory({
|
const sessionResponse = await getSessionHistory({
|
||||||
@@ -335,9 +336,12 @@ export function useMessageStream({
|
|||||||
totalTokens: sessionResponse.data.metadata.total_tokens || null,
|
totalTokens: sessionResponse.data.metadata.total_tokens || null,
|
||||||
inputTokens: sessionResponse.data.metadata.input_tokens || null,
|
inputTokens: sessionResponse.data.metadata.input_tokens || null,
|
||||||
outputTokens: sessionResponse.data.metadata.output_tokens || null,
|
outputTokens: sessionResponse.data.metadata.output_tokens || null,
|
||||||
accumulatedTotalTokens: sessionResponse.data.metadata.accumulated_total_tokens || null,
|
accumulatedTotalTokens:
|
||||||
accumulatedInputTokens: sessionResponse.data.metadata.accumulated_input_tokens || null,
|
sessionResponse.data.metadata.accumulated_total_tokens || null,
|
||||||
accumulatedOutputTokens: sessionResponse.data.metadata.accumulated_output_tokens || null,
|
accumulatedInputTokens:
|
||||||
|
sessionResponse.data.metadata.accumulated_input_tokens || null,
|
||||||
|
accumulatedOutputTokens:
|
||||||
|
sessionResponse.data.metadata.accumulated_output_tokens || null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user