defmodule Services do def start_all do start_external_services() start_internal_services() end defp start_external_services do {:ok, _} = Application.ensure_all_started(:briefly) end defp start_internal_services do # Start Globals first, since it is the foundation for config. Services.Globals.start_link() # Start UI.Queue next, since other services may want to log messages # during their startup. UI.Queue.start_link() # Start core services that don't depend on CLI configuration Registry.start_link(keys: :unique, name: MCP.ClientRegistry) Services.Once.start_link() Services.Notes.start_link() Services.Conversation.Interrupts.start_link([]) Services.BackupFile.start_link() Services.TempFile.start_link([]) Services.FileCache.start_link() # Start TaskSupervisor commonly used by services to spawn supervised tasks # Ensure Task.Supervisor is started only once case Process.whereis(Services.TaskSupervisor) do nil -> Task.Supervisor.start_link(name: Services.TaskSupervisor) _ -> {:ok, Process.whereis(Services.TaskSupervisor)} end end @doc """ Starts services that depend on CLI configuration. These services must be started AFTER set_globals() is called because they need to read configuration settings parsed from CLI arguments in set_globals(). """ def start_config_dependent_services(_command \\ nil) do Services.NamePool.start_link() Services.Approvals.start_link() Services.Approvals.Gate.start_link([]) # MCP is started lazily on-demand when a completion needs MCP-backed tools. # It is started from AI.Tools.basic_tools, which is always called for any # agent that has access to tools, making it a logical place to start MCP # on-demand. It is guarded with a pid check to ensure it is only started # once. :ok end end