@@ -63,11 +63,12 @@ use crate::cli::agent::hook::{
6363use crate :: database:: settings:: Setting ;
6464use crate :: os:: Os ;
6565use crate :: theme:: StyledText ;
66+ use crate :: util:: paths:: PathResolver ;
6667use crate :: util:: {
6768 self ,
6869 MCP_SERVER_TOOL_DELIMITER ,
69- directories,
7070 file_uri,
71+ paths,
7172} ;
7273
7374pub const DEFAULT_AGENT_NAME : & str = "q_cli_default" ;
@@ -84,7 +85,7 @@ pub enum AgentConfigError {
8485 error : Box < jsonschema:: ValidationError < ' static > > ,
8586 } ,
8687 #[ error( "Encountered directory error: {0}" ) ]
87- Directories ( #[ from] util:: directories :: DirectoryError ) ,
88+ Directories ( #[ from] util:: paths :: DirectoryError ) ,
8889 #[ error( "Encountered io error: {0}" ) ]
8990 Io ( #[ from] std:: io:: Error ) ,
9091 #[ error( "Failed to parse legacy mcp config: {0}" ) ]
@@ -165,7 +166,7 @@ pub struct Agent {
165166 #[ serde( default ) ]
166167 #[ schemars( schema_with = "tool_settings_schema" ) ]
167168 pub tools_settings : HashMap < ToolSettingTarget , serde_json:: Value > ,
168- /// Whether or not to include the legacy ~/.aws/amazonq/mcp.json in the agent
169+ /// Whether or not to include the legacy global MCP configuration in the agent
169170 /// You can reference tools brought in by these servers as just as you would with the servers
170171 /// you configure in the mcpServers field in this config
171172 #[ serde( default ) ]
@@ -193,15 +194,12 @@ impl Default for Agent {
193194 set. extend ( default_approve) ;
194195 set
195196 } ,
196- resources : vec ! [
197- "file://AmazonQ.md" ,
198- "file://AGENTS.md" ,
199- "file://README.md" ,
200- "file://.amazonq/rules/**/*.md" ,
201- ]
202- . into_iter ( )
203- . map ( Into :: into)
204- . collect :: < Vec < _ > > ( ) ,
197+ resources : {
198+ let mut resources = Vec :: new ( ) ;
199+ resources. extend ( paths:: workspace:: DEFAULT_AGENT_RESOURCES . iter ( ) . map ( |& s| s. into ( ) ) ) ;
200+ resources. push ( format ! ( "file://{}" , paths:: workspace:: RULES_PATTERN ) . into ( ) ) ;
201+ resources
202+ } ,
205203 hooks : Default :: default ( ) ,
206204 tools_settings : Default :: default ( ) ,
207205 use_legacy_mcp_json : true ,
@@ -342,14 +340,15 @@ impl Agent {
342340 /// Retrieves an agent by name. It does so via first seeking the given agent under local dir,
343341 /// and falling back to global dir if it does not exist in local.
344342 pub async fn get_agent_by_name ( os : & Os , agent_name : & str ) -> eyre:: Result < ( Agent , PathBuf ) > {
343+ let resolver = PathResolver :: new ( os) ;
345344 let config_path: Result < PathBuf , PathBuf > = ' config: {
346345 // local first, and then fall back to looking at global
347- let local_config_dir = directories :: chat_local_agent_dir ( os ) ?. join ( format ! ( "{agent_name}.json" ) ) ;
346+ let local_config_dir = resolver . workspace ( ) . agents_dir ( ) ?. join ( format ! ( "{agent_name}.json" ) ) ;
348347 if os. fs . exists ( & local_config_dir) {
349348 break ' config Ok ( local_config_dir) ;
350349 }
351350
352- let global_config_dir = directories :: chat_global_agent_path ( os ) ?. join ( format ! ( "{agent_name}.json" ) ) ;
351+ let global_config_dir = resolver . global ( ) . agents_dir ( ) ?. join ( format ! ( "{agent_name}.json" ) ) ;
353352 if os. fs . exists ( & global_config_dir) {
354353 break ' config Ok ( global_config_dir) ;
355354 }
@@ -542,20 +541,21 @@ impl Agents {
542541 vec ! [ ]
543542 } ;
544543
544+ let resolver = PathResolver :: new ( os) ;
545545 let mut global_mcp_config = None :: < McpServerConfig > ;
546546
547547 let mut local_agents = ' local: {
548548 // We could be launching from the home dir, in which case the global and local agents
549549 // are the same set of agents. If that is the case, we simply skip this.
550- match ( std:: env:: current_dir ( ) , directories :: home_dir ( os) ) {
550+ match ( std:: env:: current_dir ( ) , paths :: home_dir ( os) ) {
551551 ( Ok ( cwd) , Ok ( home_dir) ) if cwd == home_dir => break ' local Vec :: < Agent > :: new ( ) ,
552552 _ => {
553553 // noop, we keep going with the extraction of local agents (even if we have an
554554 // error retrieving cwd or home_dir)
555555 } ,
556556 }
557557
558- let Ok ( path) = directories :: chat_local_agent_dir ( os ) else {
558+ let Ok ( path) = resolver . workspace ( ) . agents_dir ( ) else {
559559 break ' local Vec :: < Agent > :: new ( ) ;
560560 } ;
561561 let Ok ( files) = os. fs . read_dir ( path) . await else {
@@ -585,7 +585,7 @@ impl Agents {
585585 } ;
586586
587587 let mut global_agents = ' global: {
588- let Ok ( path) = directories :: chat_global_agent_path ( os ) else {
588+ let Ok ( path) = resolver . global ( ) . agents_dir ( ) else {
589589 break ' global Vec :: < Agent > :: new ( ) ;
590590 } ;
591591 let files = match os. fs . read_dir ( & path) . await {
@@ -629,10 +629,11 @@ impl Agents {
629629 // there.
630630 // Note that this config is not what q chat uses. It merely serves as an example.
631631 ' example_config: {
632- let Ok ( path ) = directories :: example_agent_config ( os ) else {
632+ let Ok ( agents_dir ) = resolver . global ( ) . agents_dir ( ) else {
633633 error ! ( "Error obtaining example agent path." ) ;
634634 break ' example_config;
635635 } ;
636+ let path = agents_dir. join ( "agent_config.json.example" ) ;
636637 if os. fs . exists ( & path) {
637638 break ' example_config;
638639 }
@@ -744,7 +745,7 @@ impl Agents {
744745 if mcp_enabled {
745746 ' load_legacy_mcp_json: {
746747 if global_mcp_config. is_none ( ) {
747- let Ok ( global_mcp_path) = directories :: chat_legacy_global_mcp_config ( os ) else {
748+ let Ok ( global_mcp_path) = resolver . global ( ) . mcp_config ( ) else {
748749 tracing:: error!( "Error obtaining legacy mcp json path. Skipping" ) ;
749750 break ' load_legacy_mcp_json;
750751 } ;
@@ -906,7 +907,8 @@ async fn load_agents_from_entries(
906907/// Loads legacy mcp config by combining workspace and global config.
907908/// In case of a server naming conflict, the workspace config is prioritized.
908909async fn load_legacy_mcp_config ( os : & Os ) -> eyre:: Result < Option < McpServerConfig > > {
909- let global_mcp_path = directories:: chat_legacy_global_mcp_config ( os) ?;
910+ let resolver = PathResolver :: new ( os) ;
911+ let global_mcp_path = resolver. global ( ) . mcp_config ( ) ?;
910912 let global_mcp_config = match McpServerConfig :: load_from_file ( os, global_mcp_path) . await {
911913 Ok ( config) => Some ( config) ,
912914 Err ( e) => {
@@ -915,7 +917,7 @@ async fn load_legacy_mcp_config(os: &Os) -> eyre::Result<Option<McpServerConfig>
915917 } ,
916918 } ;
917919
918- let workspace_mcp_path = directories :: chat_legacy_workspace_mcp_config ( os ) ?;
920+ let workspace_mcp_path = resolver . workspace ( ) . mcp_config ( ) ?;
919921 let workspace_mcp_config = match McpServerConfig :: load_from_file ( os, workspace_mcp_path) . await {
920922 Ok ( config) => Some ( config) ,
921923 Err ( e) => {
0 commit comments