diff --git a/Cargo.lock b/Cargo.lock index 2b97d48bbf..5d09eec222 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18322,6 +18322,7 @@ dependencies = [ "gpui", "schemars", "serde", + "uuid", "workspace-hack", ] diff --git a/crates/agent/src/active_thread.rs b/crates/agent/src/active_thread.rs index daec26a733..5dddbd23ad 100644 --- a/crates/agent/src/active_thread.rs +++ b/crates/agent/src/active_thread.rs @@ -2965,6 +2965,11 @@ impl ActiveThread { )) }; + let first_default_user_rules_id = project_context + .default_user_rules + .first() + .map(|user_rules| user_rules.uuid); + let rules_files = project_context .worktrees .iter() @@ -3015,8 +3020,13 @@ impl ActiveThread { .icon_color(Color::Ignored) // TODO: Figure out a way to pass focus handle here so we can display the `OpenPromptLibrary` keybinding .tooltip(Tooltip::text("View User Rules")) - .on_click(|_event, window, cx| { - window.dispatch_action(Box::new(OpenPromptLibrary), cx) + .on_click(move |_event, window, cx| { + window.dispatch_action( + Box::new(OpenPromptLibrary { + prompt_to_focus: first_default_user_rules_id, + }), + cx, + ) }), ), ) diff --git a/crates/agent/src/assistant_panel.rs b/crates/agent/src/assistant_panel.rs index 1f450921f7..f8f3c923ab 100644 --- a/crates/agent/src/assistant_panel.rs +++ b/crates/agent/src/assistant_panel.rs @@ -25,7 +25,7 @@ use language_model::{LanguageModelProviderTosView, LanguageModelRegistry}; use language_model_selector::ToggleModelSelector; use project::Project; use prompt_library::{PromptLibrary, open_prompt_library}; -use prompt_store::PromptBuilder; +use prompt_store::{PromptBuilder, PromptId}; use proto::Plan; use settings::{Settings, update_settings_file}; use time::UtcOffset; @@ -83,7 +83,7 @@ pub fn init(cx: &mut App) { if let Some(panel) = workspace.panel::(cx) { workspace.focus_panel::(window, cx); panel.update(cx, |panel, cx| { - panel.deploy_prompt_library(&OpenPromptLibrary, window, cx) + panel.deploy_prompt_library(&OpenPromptLibrary::default(), window, cx) }); } }) @@ -488,7 +488,7 @@ impl AssistantPanel { fn deploy_prompt_library( &mut self, - _: &OpenPromptLibrary, + action: &OpenPromptLibrary, _window: &mut Window, cx: &mut Context, ) { @@ -502,6 +502,7 @@ impl AssistantPanel { None, )) }), + action.prompt_to_focus.map(|uuid| PromptId::User { uuid }), cx, ) .detach_and_log_err(cx); @@ -1119,7 +1120,7 @@ impl AssistantPanel { "New Text Thread", NewTextThread.boxed_clone(), ) - .action("Prompt Library", Box::new(OpenPromptLibrary)) + .action("Prompt Library", Box::new(OpenPromptLibrary::default())) .action("Settings", Box::new(OpenConfiguration)) .separator() .action( diff --git a/crates/agent/src/thread_store.rs b/crates/agent/src/thread_store.rs index 5de5d7404a..74787016fd 100644 --- a/crates/agent/src/thread_store.rs +++ b/crates/agent/src/thread_store.rs @@ -24,8 +24,8 @@ use heed::types::SerdeBincode; use language_model::{LanguageModelToolUseId, Role, TokenUsage}; use project::{Project, Worktree}; use prompt_store::{ - DefaultUserRulesContext, ProjectContext, PromptBuilder, PromptStore, PromptsUpdatedEvent, - RulesFileContext, WorktreeContext, + DefaultUserRulesContext, ProjectContext, PromptBuilder, PromptId, PromptStore, + PromptsUpdatedEvent, RulesFileContext, WorktreeContext, }; use serde::{Deserialize, Serialize}; use settings::{Settings as _, SettingsStore}; @@ -246,6 +246,10 @@ impl ThreadStore { .into_iter() .flat_map(|(contents, prompt_metadata)| match contents { Ok(contents) => Some(DefaultUserRulesContext { + uuid: match prompt_metadata.id { + PromptId::User { uuid } => uuid, + PromptId::EditWorkflow => return None, + }, title: prompt_metadata.title.map(|title| title.to_string()), contents, }), diff --git a/crates/assistant/src/assistant_panel.rs b/crates/assistant/src/assistant_panel.rs index 317780e727..4760d4454f 100644 --- a/crates/assistant/src/assistant_panel.rs +++ b/crates/assistant/src/assistant_panel.rs @@ -27,7 +27,7 @@ use language_model::{ }; use project::Project; use prompt_library::{PromptLibrary, open_prompt_library}; -use prompt_store::PromptBuilder; +use prompt_store::{PromptBuilder, PromptId}; use search::{BufferSearchBar, buffer_search::DivRegistrar}; use settings::{Settings, update_settings_file}; @@ -62,7 +62,7 @@ pub fn init(cx: &mut App) { if let Some(panel) = workspace.panel::(cx) { workspace.focus_panel::(window, cx); panel.update(cx, |panel, cx| { - panel.deploy_prompt_library(&OpenPromptLibrary, window, cx) + panel.deploy_prompt_library(&OpenPromptLibrary::default(), window, cx) }); } }); @@ -272,7 +272,10 @@ impl AssistantPanel { menu.context(focus_handle.clone()) .action("New Chat", Box::new(NewChat)) .action("History", Box::new(DeployHistory)) - .action("Prompt Library", Box::new(OpenPromptLibrary)) + .action( + "Prompt Library", + Box::new(OpenPromptLibrary::default()), + ) .action("Configure", Box::new(ShowConfiguration)) .action(zoom_label, Box::new(ToggleZoom)) })) @@ -1043,7 +1046,7 @@ impl AssistantPanel { fn deploy_prompt_library( &mut self, - _: &OpenPromptLibrary, + action: &OpenPromptLibrary, _window: &mut Window, cx: &mut Context, ) { @@ -1057,6 +1060,7 @@ impl AssistantPanel { None, )) }), + action.prompt_to_focus.map(|uuid| PromptId::User { uuid }), cx, ) .detach_and_log_err(cx); diff --git a/crates/prompt_library/Cargo.toml b/crates/prompt_library/Cargo.toml index b9bfaa61d6..c37707d300 100644 --- a/crates/prompt_library/Cargo.toml +++ b/crates/prompt_library/Cargo.toml @@ -29,6 +29,6 @@ settings.workspace = true theme.workspace = true ui.workspace = true util.workspace = true +workspace-hack.workspace = true workspace.workspace = true zed_actions.workspace = true -workspace-hack.workspace = true diff --git a/crates/prompt_library/src/prompt_library.rs b/crates/prompt_library/src/prompt_library.rs index 3d6e97b724..5ed987f955 100644 --- a/crates/prompt_library/src/prompt_library.rs +++ b/crates/prompt_library/src/prompt_library.rs @@ -75,6 +75,7 @@ pub fn open_prompt_library( language_registry: Arc, inline_assist_delegate: Box, make_completion_provider: Arc Box>, + prompt_to_focus: Option, cx: &mut App, ) -> Task>> { let store = PromptStore::global(cx); @@ -88,7 +89,12 @@ pub fn open_prompt_library( .find_map(|window| window.downcast::()); if let Some(existing_window) = existing_window { existing_window - .update(cx, |_, window, _| window.activate_window()) + .update(cx, |prompt_library, window, cx| { + if let Some(prompt_to_focus) = prompt_to_focus { + prompt_library.load_prompt(prompt_to_focus, true, window, cx); + } + window.activate_window() + }) .ok(); Some(existing_window) @@ -120,14 +126,18 @@ pub fn open_prompt_library( }, |window, cx| { cx.new(|cx| { - PromptLibrary::new( + let mut prompt_library = PromptLibrary::new( store, language_registry, inline_assist_delegate, make_completion_provider, window, cx, - ) + ); + if let Some(prompt_to_focus) = prompt_to_focus { + prompt_library.load_prompt(prompt_to_focus, true, window, cx); + } + prompt_library }) }, ) diff --git a/crates/prompt_store/src/prompts.rs b/crates/prompt_store/src/prompts.rs index 54aa632c98..6b143440c2 100644 --- a/crates/prompt_store/src/prompts.rs +++ b/crates/prompt_store/src/prompts.rs @@ -15,6 +15,7 @@ use std::{ }; use text::LineEnding; use util::{ResultExt, get_system_shell}; +use uuid::Uuid; #[derive(Debug, Clone, Serialize)] pub struct ProjectContext { @@ -51,6 +52,7 @@ impl ProjectContext { #[derive(Debug, Clone, Serialize)] pub struct DefaultUserRulesContext { + pub uuid: Uuid, pub title: Option, pub contents: String, } @@ -409,6 +411,7 @@ mod test { }), }]; let default_user_rules = vec![DefaultUserRulesContext { + uuid: Uuid::nil(), title: Some("Rules title".into()), contents: "Rules contents".into(), }]; diff --git a/crates/zed_actions/Cargo.toml b/crates/zed_actions/Cargo.toml index 94c970fd2f..3778d19621 100644 --- a/crates/zed_actions/Cargo.toml +++ b/crates/zed_actions/Cargo.toml @@ -13,3 +13,4 @@ gpui.workspace = true schemars.workspace = true serde.workspace = true workspace-hack.workspace = true +uuid.workspace = true diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 2579d856d6..6c1852f882 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -190,13 +190,21 @@ pub mod agent { } pub mod assistant { - use gpui::{action_with_deprecated_aliases, actions, impl_actions}; + use gpui::{actions, impl_action_with_deprecated_aliases, impl_actions}; use schemars::JsonSchema; use serde::Deserialize; + use uuid::Uuid; actions!(assistant, [ToggleFocus, ShowConfiguration]); - action_with_deprecated_aliases!( + #[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)] + #[serde(deny_unknown_fields)] + pub struct OpenPromptLibrary { + #[serde(skip)] + pub prompt_to_focus: Option, + } + + impl_action_with_deprecated_aliases!( assistant, OpenPromptLibrary, ["assistant::DeployPromptLibrary"]