Add hidden prompt_to_focus field to OpenPromptLibrary action (#29062)

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2025-04-18 14:39:40 -06:00 committed by GitHub
parent 327fee4d22
commit 73a767fc45
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 60 additions and 18 deletions

1
Cargo.lock generated
View file

@ -18322,6 +18322,7 @@ dependencies = [
"gpui", "gpui",
"schemars", "schemars",
"serde", "serde",
"uuid",
"workspace-hack", "workspace-hack",
] ]

View file

@ -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 let rules_files = project_context
.worktrees .worktrees
.iter() .iter()
@ -3015,8 +3020,13 @@ impl ActiveThread {
.icon_color(Color::Ignored) .icon_color(Color::Ignored)
// TODO: Figure out a way to pass focus handle here so we can display the `OpenPromptLibrary` keybinding // TODO: Figure out a way to pass focus handle here so we can display the `OpenPromptLibrary` keybinding
.tooltip(Tooltip::text("View User Rules")) .tooltip(Tooltip::text("View User Rules"))
.on_click(|_event, window, cx| { .on_click(move |_event, window, cx| {
window.dispatch_action(Box::new(OpenPromptLibrary), cx) window.dispatch_action(
Box::new(OpenPromptLibrary {
prompt_to_focus: first_default_user_rules_id,
}),
cx,
)
}), }),
), ),
) )

View file

@ -25,7 +25,7 @@ use language_model::{LanguageModelProviderTosView, LanguageModelRegistry};
use language_model_selector::ToggleModelSelector; use language_model_selector::ToggleModelSelector;
use project::Project; use project::Project;
use prompt_library::{PromptLibrary, open_prompt_library}; use prompt_library::{PromptLibrary, open_prompt_library};
use prompt_store::PromptBuilder; use prompt_store::{PromptBuilder, PromptId};
use proto::Plan; use proto::Plan;
use settings::{Settings, update_settings_file}; use settings::{Settings, update_settings_file};
use time::UtcOffset; use time::UtcOffset;
@ -83,7 +83,7 @@ pub fn init(cx: &mut App) {
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) { if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
workspace.focus_panel::<AssistantPanel>(window, cx); workspace.focus_panel::<AssistantPanel>(window, cx);
panel.update(cx, |panel, 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( fn deploy_prompt_library(
&mut self, &mut self,
_: &OpenPromptLibrary, action: &OpenPromptLibrary,
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
@ -502,6 +502,7 @@ impl AssistantPanel {
None, None,
)) ))
}), }),
action.prompt_to_focus.map(|uuid| PromptId::User { uuid }),
cx, cx,
) )
.detach_and_log_err(cx); .detach_and_log_err(cx);
@ -1119,7 +1120,7 @@ impl AssistantPanel {
"New Text Thread", "New Text Thread",
NewTextThread.boxed_clone(), NewTextThread.boxed_clone(),
) )
.action("Prompt Library", Box::new(OpenPromptLibrary)) .action("Prompt Library", Box::new(OpenPromptLibrary::default()))
.action("Settings", Box::new(OpenConfiguration)) .action("Settings", Box::new(OpenConfiguration))
.separator() .separator()
.action( .action(

View file

@ -24,8 +24,8 @@ use heed::types::SerdeBincode;
use language_model::{LanguageModelToolUseId, Role, TokenUsage}; use language_model::{LanguageModelToolUseId, Role, TokenUsage};
use project::{Project, Worktree}; use project::{Project, Worktree};
use prompt_store::{ use prompt_store::{
DefaultUserRulesContext, ProjectContext, PromptBuilder, PromptStore, PromptsUpdatedEvent, DefaultUserRulesContext, ProjectContext, PromptBuilder, PromptId, PromptStore,
RulesFileContext, WorktreeContext, PromptsUpdatedEvent, RulesFileContext, WorktreeContext,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use settings::{Settings as _, SettingsStore}; use settings::{Settings as _, SettingsStore};
@ -246,6 +246,10 @@ impl ThreadStore {
.into_iter() .into_iter()
.flat_map(|(contents, prompt_metadata)| match contents { .flat_map(|(contents, prompt_metadata)| match contents {
Ok(contents) => Some(DefaultUserRulesContext { 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()), title: prompt_metadata.title.map(|title| title.to_string()),
contents, contents,
}), }),

View file

@ -27,7 +27,7 @@ use language_model::{
}; };
use project::Project; use project::Project;
use prompt_library::{PromptLibrary, open_prompt_library}; use prompt_library::{PromptLibrary, open_prompt_library};
use prompt_store::PromptBuilder; use prompt_store::{PromptBuilder, PromptId};
use search::{BufferSearchBar, buffer_search::DivRegistrar}; use search::{BufferSearchBar, buffer_search::DivRegistrar};
use settings::{Settings, update_settings_file}; use settings::{Settings, update_settings_file};
@ -62,7 +62,7 @@ pub fn init(cx: &mut App) {
if let Some(panel) = workspace.panel::<AssistantPanel>(cx) { if let Some(panel) = workspace.panel::<AssistantPanel>(cx) {
workspace.focus_panel::<AssistantPanel>(window, cx); workspace.focus_panel::<AssistantPanel>(window, cx);
panel.update(cx, |panel, 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()) menu.context(focus_handle.clone())
.action("New Chat", Box::new(NewChat)) .action("New Chat", Box::new(NewChat))
.action("History", Box::new(DeployHistory)) .action("History", Box::new(DeployHistory))
.action("Prompt Library", Box::new(OpenPromptLibrary)) .action(
"Prompt Library",
Box::new(OpenPromptLibrary::default()),
)
.action("Configure", Box::new(ShowConfiguration)) .action("Configure", Box::new(ShowConfiguration))
.action(zoom_label, Box::new(ToggleZoom)) .action(zoom_label, Box::new(ToggleZoom))
})) }))
@ -1043,7 +1046,7 @@ impl AssistantPanel {
fn deploy_prompt_library( fn deploy_prompt_library(
&mut self, &mut self,
_: &OpenPromptLibrary, action: &OpenPromptLibrary,
_window: &mut Window, _window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
@ -1057,6 +1060,7 @@ impl AssistantPanel {
None, None,
)) ))
}), }),
action.prompt_to_focus.map(|uuid| PromptId::User { uuid }),
cx, cx,
) )
.detach_and_log_err(cx); .detach_and_log_err(cx);

View file

@ -29,6 +29,6 @@ settings.workspace = true
theme.workspace = true theme.workspace = true
ui.workspace = true ui.workspace = true
util.workspace = true util.workspace = true
workspace-hack.workspace = true
workspace.workspace = true workspace.workspace = true
zed_actions.workspace = true zed_actions.workspace = true
workspace-hack.workspace = true

View file

@ -75,6 +75,7 @@ pub fn open_prompt_library(
language_registry: Arc<LanguageRegistry>, language_registry: Arc<LanguageRegistry>,
inline_assist_delegate: Box<dyn InlineAssistDelegate>, inline_assist_delegate: Box<dyn InlineAssistDelegate>,
make_completion_provider: Arc<dyn Fn() -> Box<dyn CompletionProvider>>, make_completion_provider: Arc<dyn Fn() -> Box<dyn CompletionProvider>>,
prompt_to_focus: Option<PromptId>,
cx: &mut App, cx: &mut App,
) -> Task<Result<WindowHandle<PromptLibrary>>> { ) -> Task<Result<WindowHandle<PromptLibrary>>> {
let store = PromptStore::global(cx); let store = PromptStore::global(cx);
@ -88,7 +89,12 @@ pub fn open_prompt_library(
.find_map(|window| window.downcast::<PromptLibrary>()); .find_map(|window| window.downcast::<PromptLibrary>());
if let Some(existing_window) = existing_window { if let Some(existing_window) = 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(); .ok();
Some(existing_window) Some(existing_window)
@ -120,14 +126,18 @@ pub fn open_prompt_library(
}, },
|window, cx| { |window, cx| {
cx.new(|cx| { cx.new(|cx| {
PromptLibrary::new( let mut prompt_library = PromptLibrary::new(
store, store,
language_registry, language_registry,
inline_assist_delegate, inline_assist_delegate,
make_completion_provider, make_completion_provider,
window, window,
cx, cx,
) );
if let Some(prompt_to_focus) = prompt_to_focus {
prompt_library.load_prompt(prompt_to_focus, true, window, cx);
}
prompt_library
}) })
}, },
) )

View file

@ -15,6 +15,7 @@ use std::{
}; };
use text::LineEnding; use text::LineEnding;
use util::{ResultExt, get_system_shell}; use util::{ResultExt, get_system_shell};
use uuid::Uuid;
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct ProjectContext { pub struct ProjectContext {
@ -51,6 +52,7 @@ impl ProjectContext {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
pub struct DefaultUserRulesContext { pub struct DefaultUserRulesContext {
pub uuid: Uuid,
pub title: Option<String>, pub title: Option<String>,
pub contents: String, pub contents: String,
} }
@ -409,6 +411,7 @@ mod test {
}), }),
}]; }];
let default_user_rules = vec![DefaultUserRulesContext { let default_user_rules = vec![DefaultUserRulesContext {
uuid: Uuid::nil(),
title: Some("Rules title".into()), title: Some("Rules title".into()),
contents: "Rules contents".into(), contents: "Rules contents".into(),
}]; }];

View file

@ -13,3 +13,4 @@ gpui.workspace = true
schemars.workspace = true schemars.workspace = true
serde.workspace = true serde.workspace = true
workspace-hack.workspace = true workspace-hack.workspace = true
uuid.workspace = true

View file

@ -190,13 +190,21 @@ pub mod agent {
} }
pub mod assistant { 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 schemars::JsonSchema;
use serde::Deserialize; use serde::Deserialize;
use uuid::Uuid;
actions!(assistant, [ToggleFocus, ShowConfiguration]); 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<Uuid>,
}
impl_action_with_deprecated_aliases!(
assistant, assistant,
OpenPromptLibrary, OpenPromptLibrary,
["assistant::DeployPromptLibrary"] ["assistant::DeployPromptLibrary"]