Initial commit
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
# Default worktree tab config
|
# Default worktree tab config
|
||||||
# Stored in ~/.warp/default_tab_configs/ — you can customize this file!
|
# Stored in ~/.warp-core/default_tab_configs/ — you can customize this file!
|
||||||
# Any customizations will apply for any new worktree configs going forward that are created from the "New worktree config" flow
|
# Any customizations will apply for any new worktree configs going forward that are created from the "New worktree config" flow
|
||||||
#
|
#
|
||||||
# This config is used by the "Worktree in" submenu to quickly create
|
# This config is used by the "Worktree in" submenu to quickly create
|
||||||
# worktrees under ~/.warp/worktrees/<repo-name>/<worktree-name> for your
|
# worktrees under ~/.warp-core/worktrees/<repo-name>/<worktree-name> for your
|
||||||
# known repositories.
|
# known repositories.
|
||||||
|
|
||||||
name = "Worktree"
|
name = "Worktree"
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::ai::agent::AIAgentAttachment;
|
|||||||
/// based on the agent's working directory.
|
/// based on the agent's working directory.
|
||||||
#[cfg_attr(target_family = "wasm", allow(dead_code))]
|
#[cfg_attr(target_family = "wasm", allow(dead_code))]
|
||||||
pub(crate) fn attachments_download_dir(working_dir: &Path) -> PathBuf {
|
pub(crate) fn attachments_download_dir(working_dir: &Path) -> PathBuf {
|
||||||
working_dir.join(".warp").join("attachments")
|
working_dir.join(".warp-core").join("attachments")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extracts the filename component from a path, stripping any directory prefixes.
|
/// Extracts the filename component from a path, stripping any directory prefixes.
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ pub struct BlocklistAIController {
|
|||||||
ambient_agent_task_id: Option<AmbientAgentTaskId>,
|
ambient_agent_task_id: Option<AmbientAgentTaskId>,
|
||||||
|
|
||||||
/// Per-session directory for downloading file attachments.
|
/// Per-session directory for downloading file attachments.
|
||||||
/// Set by the agent driver based on the workspace directory (e.g. `{working_dir}/.warp/attachments`).
|
/// Set by the agent driver based on the workspace directory (e.g. `{working_dir}/.warp-core/attachments`).
|
||||||
attachments_download_dir: Option<std::path::PathBuf>,
|
attachments_download_dir: Option<std::path::PathBuf>,
|
||||||
|
|
||||||
/// Pending auto-resume tasks that are waiting for network connectivity.
|
/// Pending auto-resume tasks that are waiting for network connectivity.
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ impl FileBasedMCPManager {
|
|||||||
/// config location.
|
/// config location.
|
||||||
///
|
///
|
||||||
/// "Global" means the installation was detected outside of a user repository:
|
/// "Global" means the installation was detected outside of a user repository:
|
||||||
/// - For `MCPProvider::Warp`: `warp_data_dir()` (i.e. `~/.warp/.mcp.json`).
|
/// - For `MCPProvider::Warp`: `warp_data_dir()` (i.e. `~/.warp-core/.mcp.json`).
|
||||||
/// - For any other provider: the user's home directory (e.g. `~/.claude.json`).
|
/// - For any other provider: the user's home directory (e.g. `~/.claude.json`).
|
||||||
///
|
///
|
||||||
/// Project-scoped installations (those detected inside a repo) are not considered
|
/// Project-scoped installations (those detected inside a repo) are not considered
|
||||||
@@ -409,11 +409,11 @@ impl FileBasedMCPManager {
|
|||||||
/// when its config does not specify `working_directory`.
|
/// when its config does not specify `working_directory`.
|
||||||
///
|
///
|
||||||
/// The spawn root is the directory the config was discovered in, with one
|
/// The spawn root is the directory the config was discovered in, with one
|
||||||
/// exception: global Warp installs are discovered in `~/.warp/` (Warp's data
|
/// exception: global Warp installs are discovered in `~/.warp-core/` (Warp's data
|
||||||
/// dir) which isn't a useful cwd for spawned processes, so they are remapped
|
/// dir) which isn't a useful cwd for spawned processes, so they are remapped
|
||||||
/// to the home directory instead.
|
/// to the home directory instead.
|
||||||
/// - Project-scoped installations: the repo root.
|
/// - Project-scoped installations: the repo root.
|
||||||
/// - Global installations (`~/.warp/.mcp.json`, `~/.claude.json`, etc.): the
|
/// - Global installations (`~/.warp-core/.mcp.json`, `~/.claude.json`, etc.): the
|
||||||
/// home directory.
|
/// home directory.
|
||||||
///
|
///
|
||||||
/// If the installation is referenced from multiple roots, the lexicographically
|
/// If the installation is referenced from multiple roots, the lexicographically
|
||||||
@@ -429,7 +429,7 @@ impl FileBasedMCPManager {
|
|||||||
.sorted()
|
.sorted()
|
||||||
.next()?;
|
.next()?;
|
||||||
|
|
||||||
// Global Warp installs live under `~/.warp/`, which is internal Warp state
|
// Global Warp installs live under `~/.warp-core/`, which is internal Warp state
|
||||||
// rather than a meaningful working directory. Map them to the home dir so
|
// rather than a meaningful working directory. Map them to the home dir so
|
||||||
// all global installs (Warp and third-party) share a consistent cwd.
|
// all global installs (Warp and third-party) share a consistent cwd.
|
||||||
if discovery_root == warp_data_dir() {
|
if discovery_root == warp_data_dir() {
|
||||||
|
|||||||
@@ -29,13 +29,13 @@ static ENV_VAR_REGEX: LazyLock<Regex> =
|
|||||||
LazyLock::new(|| Regex::new(r"\$\{([^}]+)\}").expect("Regex is valid"));
|
LazyLock::new(|| Regex::new(r"\$\{([^}]+)\}").expect("Regex is valid"));
|
||||||
|
|
||||||
/// Matches home config paths that are exactly one directory deep (e.g. `.codex/config.toml`,
|
/// Matches home config paths that are exactly one directory deep (e.g. `.codex/config.toml`,
|
||||||
/// `.warp/.mcp.json`), capturing the parent directory component.
|
/// `.warp-core/.mcp.json`), capturing the parent directory component.
|
||||||
static HOME_SUBDIR_REGEX: LazyLock<Regex> =
|
static HOME_SUBDIR_REGEX: LazyLock<Regex> =
|
||||||
LazyLock::new(|| Regex::new(r"^([^/]+)/[^/]+$").expect("Regex is valid"));
|
LazyLock::new(|| Regex::new(r"^([^/]+)/[^/]+$").expect("Regex is valid"));
|
||||||
|
|
||||||
/// Returns the subdirectory under the home directory that needs its own [`DirectoryWatcher`],
|
/// Returns the subdirectory under the home directory that needs its own [`DirectoryWatcher`],
|
||||||
/// inferred from the provider's home config path. Matches paths that are exactly one directory
|
/// inferred from the provider's home config path. Matches paths that are exactly one directory
|
||||||
/// deep (e.g. `.codex/config.toml` → `.codex`, `.warp/.mcp.json` → `.warp`). Returns `None`
|
/// deep (e.g. `.codex/config.toml` → `.codex`, `.warp-core/.mcp.json` → `.warp-core`). Returns `None`
|
||||||
/// when the config file lives directly in the home dir (e.g. `.claude.json`) and is already
|
/// when the config file lives directly in the home dir (e.g. `.claude.json`) and is already
|
||||||
/// covered by `HomeDirectoryWatcher`.
|
/// covered by `HomeDirectoryWatcher`.
|
||||||
fn home_subdir_to_watch(provider: MCPProvider) -> Option<PathBuf> {
|
fn home_subdir_to_watch(provider: MCPProvider) -> Option<PathBuf> {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ impl MCPProvider {
|
|||||||
/// Returns the path of the provider's config file relative to the home directory.
|
/// Returns the path of the provider's config file relative to the home directory.
|
||||||
pub fn home_config_path(&self) -> &'static Path {
|
pub fn home_config_path(&self) -> &'static Path {
|
||||||
match self {
|
match self {
|
||||||
MCPProvider::Warp => Path::new(".warp/.mcp.json"),
|
MCPProvider::Warp => Path::new(".warp-core/.mcp.json"),
|
||||||
MCPProvider::Claude => Path::new(".claude.json"),
|
MCPProvider::Claude => Path::new(".claude.json"),
|
||||||
MCPProvider::Codex => Path::new(".codex/config.toml"),
|
MCPProvider::Codex => Path::new(".codex/config.toml"),
|
||||||
MCPProvider::Agents => Path::new(".agents/.mcp.json"),
|
MCPProvider::Agents => Path::new(".agents/.mcp.json"),
|
||||||
@@ -102,7 +102,7 @@ impl MCPProvider {
|
|||||||
/// Returns the path of the provider's config file relative to a project root.
|
/// Returns the path of the provider's config file relative to a project root.
|
||||||
pub fn project_config_path(&self) -> &'static Path {
|
pub fn project_config_path(&self) -> &'static Path {
|
||||||
match self {
|
match self {
|
||||||
MCPProvider::Warp => Path::new(".warp/.mcp.json"),
|
MCPProvider::Warp => Path::new(".warp-core/.mcp.json"),
|
||||||
MCPProvider::Claude => Path::new(".mcp.json"),
|
MCPProvider::Claude => Path::new(".mcp.json"),
|
||||||
MCPProvider::Codex => Path::new(".codex/config.toml"),
|
MCPProvider::Codex => Path::new(".codex/config.toml"),
|
||||||
MCPProvider::Agents => Path::new(".agents/.mcp.json"),
|
MCPProvider::Agents => Path::new(".agents/.mcp.json"),
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ impl TemplatableMCPServerManager {
|
|||||||
|
|
||||||
// For file-based MCP installations without an explicit `working_directory`,
|
// For file-based MCP installations without an explicit `working_directory`,
|
||||||
// default the spawn cwd to the directory the config was discovered in
|
// default the spawn cwd to the directory the config was discovered in
|
||||||
// (repo root for project-scoped configs, ~/.warp/ or ~ for globals). This
|
// (repo root for project-scoped configs, ~/.warp-core/ or ~ for globals). This
|
||||||
// matches user expectations for repo-relative commands in `.mcp.json`.
|
// matches user expectations for repo-relative commands in `.mcp.json`.
|
||||||
// Cloud-templated installations (lookup returns None) are unaffected and
|
// Cloud-templated installations (lookup returns None) are unaffected and
|
||||||
// continue to inherit Warp's process cwd.
|
// continue to inherit Warp's process cwd.
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ fn extract_skill_parent_directory_different_providers() {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let repo = home_dir.join("repo");
|
let repo = home_dir.join("repo");
|
||||||
let providers = [".warp", ".claude", ".codex", ".cursor", ".gemini"];
|
let providers = [".warp-core", ".claude", ".codex", ".cursor", ".gemini"];
|
||||||
for provider in providers {
|
for provider in providers {
|
||||||
let path = repo
|
let path = repo
|
||||||
.join(provider)
|
.join(provider)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ fn write_skill_file(path: &Path, name: &str, description: &str, body: &str) -> R
|
|||||||
#[test]
|
#[test]
|
||||||
fn resolve_from_skill_dirs_by_directory_scan_resolves_home_skill_dir() -> Result<()> {
|
fn resolve_from_skill_dirs_by_directory_scan_resolves_home_skill_dir() -> Result<()> {
|
||||||
let temp_dir = tempfile::TempDir::new().context("Failed to create temp dir")?;
|
let temp_dir = tempfile::TempDir::new().context("Failed to create temp dir")?;
|
||||||
let skill_dir = temp_dir.path().join(".warp").join("skills");
|
let skill_dir = temp_dir.path().join(".warp-core").join("skills");
|
||||||
let skill_path = skill_dir.join("my-skill").join("SKILL.md");
|
let skill_path = skill_dir.join("my-skill").join("SKILL.md");
|
||||||
|
|
||||||
write_skill_file(
|
write_skill_file(
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ fn try_insert_skill(
|
|||||||
///
|
///
|
||||||
/// Two skills are considered duplicates only when they share the same owning directory
|
/// Two skills are considered duplicates only when they share the same owning directory
|
||||||
/// **and** identical content — which is the common case when a tool like `npx skills`
|
/// **and** identical content — which is the common case when a tool like `npx skills`
|
||||||
/// symlinks the same skill under `~/.agents/skills/`, `~/.warp/skills/`, `~/.claude/skills/`, etc.
|
/// symlinks the same skill under `~/.agents/skills/`, `~/.warp-core/skills/`, `~/.claude/skills/`, etc.
|
||||||
///
|
///
|
||||||
/// Each element of `skill_paths` is a `(dir_path, skill_file_path)` tuple where
|
/// Each element of `skill_paths` is a `(dir_path, skill_file_path)` tuple where
|
||||||
/// `dir_path` is the directory that owns the skill.
|
/// `dir_path` is the directory that owns the skill.
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ pub fn run() -> Result<()> {
|
|||||||
|
|
||||||
/// Returns a vector of validated plugin directory paths in the plugins directory.
|
/// Returns a vector of validated plugin directory paths in the plugins directory.
|
||||||
///
|
///
|
||||||
/// This assumes that all plugins are located in ~/.warp/plugins.
|
/// This assumes that all plugins are located in ~/.warp-core/plugins.
|
||||||
fn plugin_paths() -> Vec<PathBuf> {
|
fn plugin_paths() -> Vec<PathBuf> {
|
||||||
const PLUGIN_PATH_SUFFIX: &str = ".warp/plugins";
|
const PLUGIN_PATH_SUFFIX: &str = ".warp-core/plugins";
|
||||||
|
|
||||||
dirs::home_dir()
|
dirs::home_dir()
|
||||||
.map(|home_dir| home_dir.join(PLUGIN_PATH_SUFFIX))
|
.map(|home_dir| home_dir.join(PLUGIN_PATH_SUFFIX))
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
//! One-time migration that gives the Preview channel its own config
|
//! One-time migration that gives the Preview channel its own config
|
||||||
//! directory (`~/.warp-preview`) on macOS.
|
//! directory (`~/.warp-core-preview`) on macOS.
|
||||||
//!
|
//!
|
||||||
//! Historically, Stable and Preview shared `~/.warp` on macOS. To give
|
//! Historically, Stable and Preview shared `~/.warp-core` on macOS. To give
|
||||||
//! Preview its own directory without breaking existing users, this migration
|
//! Preview its own directory without breaking existing users, this migration
|
||||||
//! symlinks each top-level entry from `~/.warp` into `~/.warp-preview` on
|
//! symlinks each top-level entry from `~/.warp-core` into `~/.warp-core-preview` on
|
||||||
//! first launch, so existing configuration (keybindings, themes, workflows,
|
//! first launch, so existing configuration (keybindings, themes, workflows,
|
||||||
//! etc.) remains available to Preview.
|
//! etc.) remains available to Preview.
|
||||||
//!
|
//!
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ fn is_symlink_to(link: &Path, expected_target: &Path) -> bool {
|
|||||||
#[test]
|
#[test]
|
||||||
fn creates_symlinks_for_top_level_entries() {
|
fn creates_symlinks_for_top_level_entries() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let old_dir = tmp.path().join(".warp");
|
let old_dir = tmp.path().join(".warp-core");
|
||||||
let new_dir = tmp.path().join(".warp-preview");
|
let new_dir = tmp.path().join(".warp-core-preview");
|
||||||
|
|
||||||
fs::create_dir(&old_dir).unwrap();
|
fs::create_dir(&old_dir).unwrap();
|
||||||
fs::write(old_dir.join("keybindings.yaml"), "bindings").unwrap();
|
fs::write(old_dir.join("keybindings.yaml"), "bindings").unwrap();
|
||||||
@@ -42,8 +42,8 @@ fn creates_symlinks_for_top_level_entries() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn skips_when_new_dir_already_exists() {
|
fn skips_when_new_dir_already_exists() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let old_dir = tmp.path().join(".warp");
|
let old_dir = tmp.path().join(".warp-core");
|
||||||
let new_dir = tmp.path().join(".warp-preview");
|
let new_dir = tmp.path().join(".warp-core-preview");
|
||||||
|
|
||||||
fs::create_dir(&old_dir).unwrap();
|
fs::create_dir(&old_dir).unwrap();
|
||||||
fs::write(old_dir.join("keybindings.yaml"), "bindings").unwrap();
|
fs::write(old_dir.join("keybindings.yaml"), "bindings").unwrap();
|
||||||
@@ -58,8 +58,8 @@ fn skips_when_new_dir_already_exists() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn skips_when_old_dir_does_not_exist() {
|
fn skips_when_old_dir_does_not_exist() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let old_dir = tmp.path().join(".warp");
|
let old_dir = tmp.path().join(".warp-core");
|
||||||
let new_dir = tmp.path().join(".warp-preview");
|
let new_dir = tmp.path().join(".warp-core-preview");
|
||||||
|
|
||||||
// old_dir intentionally not created.
|
// old_dir intentionally not created.
|
||||||
migrate_config_dir_via_symlinks(&old_dir, &new_dir);
|
migrate_config_dir_via_symlinks(&old_dir, &new_dir);
|
||||||
@@ -70,8 +70,8 @@ fn skips_when_old_dir_does_not_exist() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn skips_ds_store_and_dot_underscore_files() {
|
fn skips_ds_store_and_dot_underscore_files() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let old_dir = tmp.path().join(".warp");
|
let old_dir = tmp.path().join(".warp-core");
|
||||||
let new_dir = tmp.path().join(".warp-preview");
|
let new_dir = tmp.path().join(".warp-core-preview");
|
||||||
|
|
||||||
fs::create_dir(&old_dir).unwrap();
|
fs::create_dir(&old_dir).unwrap();
|
||||||
fs::write(old_dir.join(".DS_Store"), "metadata").unwrap();
|
fs::write(old_dir.join(".DS_Store"), "metadata").unwrap();
|
||||||
@@ -88,8 +88,8 @@ fn skips_ds_store_and_dot_underscore_files() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn skips_excluded_files() {
|
fn skips_excluded_files() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let old_dir = tmp.path().join(".warp");
|
let old_dir = tmp.path().join(".warp-core");
|
||||||
let new_dir = tmp.path().join(".warp-preview");
|
let new_dir = tmp.path().join(".warp-core-preview");
|
||||||
|
|
||||||
fs::create_dir(&old_dir).unwrap();
|
fs::create_dir(&old_dir).unwrap();
|
||||||
fs::write(old_dir.join("settings.toml"), "[settings]").unwrap();
|
fs::write(old_dir.join("settings.toml"), "[settings]").unwrap();
|
||||||
@@ -104,8 +104,8 @@ fn skips_excluded_files() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn is_idempotent() {
|
fn is_idempotent() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let old_dir = tmp.path().join(".warp");
|
let old_dir = tmp.path().join(".warp-core");
|
||||||
let new_dir = tmp.path().join(".warp-preview");
|
let new_dir = tmp.path().join(".warp-core-preview");
|
||||||
|
|
||||||
fs::create_dir(&old_dir).unwrap();
|
fs::create_dir(&old_dir).unwrap();
|
||||||
fs::write(old_dir.join("keybindings.yaml"), "bindings").unwrap();
|
fs::write(old_dir.join("keybindings.yaml"), "bindings").unwrap();
|
||||||
|
|||||||
@@ -1373,7 +1373,7 @@ define_settings_group!(AISettings, settings: [
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Whether file-based MCP servers from third-party AI tools (e.g. Claude, Codex) should
|
// Whether file-based MCP servers from third-party AI tools (e.g. Claude, Codex) should
|
||||||
// be automatically detected and spawned. Warp-native config files (.warp/.mcp.json) are
|
// be automatically detected and spawned. Warp-native config files (.warp-core/.mcp.json) are
|
||||||
// always detected and spawned, regardless of this setting.
|
// always detected and spawned, regardless of this setting.
|
||||||
file_based_mcp_enabled: FileBasedMcpEnabled {
|
file_based_mcp_enabled: FileBasedMcpEnabled {
|
||||||
type: bool,
|
type: bool,
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ pub struct TabConfigPaneNode {
|
|||||||
|
|
||||||
// ── TabConfig ───────────────────────────────────────────────────────
|
// ── TabConfig ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
/// A tab config loaded from a `.toml` file in `~/.warp/tab_configs/`.
|
/// A tab config loaded from a `.toml` file in `~/.warp-core/tab_configs/`.
|
||||||
///
|
///
|
||||||
/// Pane layout is defined with a flat `[[panes]]` array where the first entry
|
/// Pane layout is defined with a flat `[[panes]]` array where the first entry
|
||||||
/// is the root and splits reference children by ID.
|
/// is the root and splits reference children by ID.
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ pub fn is_tab_config_toml(path: &Path) -> bool {
|
|||||||
.any(|dir| path.starts_with(dir))
|
.any(|dir| path.starts_with(dir))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures `~/.warp/default_tab_configs/worktree.toml` exists, creating it
|
/// Ensures `~/.warp-core/default_tab_configs/worktree.toml` exists, creating it
|
||||||
/// from the embedded template if missing. Returns the path to the file.
|
/// from the embedded template if missing. Returns the path to the file.
|
||||||
#[cfg(feature = "local_fs")]
|
#[cfg(feature = "local_fs")]
|
||||||
pub(crate) fn ensure_default_worktree_config() -> PathBuf {
|
pub(crate) fn ensure_default_worktree_config() -> PathBuf {
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ impl LocalWorkflows {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over file-based workflows loaded from the `.warp/workflows` directory in
|
/// Returns an iterator over file-based workflows loaded from the `.warp-core/workflows` directory in
|
||||||
/// the `working_directory`.
|
/// the `working_directory`.
|
||||||
///
|
///
|
||||||
/// The loaded workflows vector is cached.
|
/// The loaded workflows vector is cached.
|
||||||
|
|||||||
@@ -6348,7 +6348,7 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the default tab config template to an unused path in `~/.warp/tab_configs/`
|
/// Writes the default tab config template to an unused path in `~/.warp-core/tab_configs/`
|
||||||
/// and opens it respecting the user's configured editor setting.
|
/// and opens it respecting the user's configured editor setting.
|
||||||
#[cfg(feature = "local_fs")]
|
#[cfg(feature = "local_fs")]
|
||||||
fn create_and_open_new_tab_config(&mut self, ctx: &mut ViewContext<Self>) {
|
fn create_and_open_new_tab_config(&mut self, ctx: &mut ViewContext<Self>) {
|
||||||
@@ -6387,7 +6387,7 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Snapshots the given tab's pane layout and writes it as a new tab config
|
/// Snapshots the given tab's pane layout and writes it as a new tab config
|
||||||
/// TOML to `~/.warp/tab_configs/`, then opens the file in the user's editor.
|
/// TOML to `~/.warp-core/tab_configs/`, then opens the file in the user's editor.
|
||||||
#[cfg(feature = "local_fs")]
|
#[cfg(feature = "local_fs")]
|
||||||
fn save_current_tab_as_new_config(&mut self, tab_index: usize, ctx: &mut ViewContext<Self>) {
|
fn save_current_tab_as_new_config(&mut self, tab_index: usize, ctx: &mut ViewContext<Self>) {
|
||||||
use crate::tab_configs::session_config::{tab_config_from_pane_snapshot, write_tab_config};
|
use crate::tab_configs::session_config::{tab_config_from_pane_snapshot, write_tab_config};
|
||||||
@@ -9234,7 +9234,7 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Opens a worktree in the given repo using the default worktree tab config,
|
/// Opens a worktree in the given repo using the default worktree tab config,
|
||||||
/// saving the materialized config to `~/.warp/tab_configs/` first.
|
/// saving the materialized config to `~/.warp-core/tab_configs/` first.
|
||||||
/// The branch name is auto-generated.
|
/// The branch name is auto-generated.
|
||||||
#[cfg(feature = "local_fs")]
|
#[cfg(feature = "local_fs")]
|
||||||
fn open_worktree_in_repo(&mut self, repo_path: String, ctx: &mut ViewContext<Self>) {
|
fn open_worktree_in_repo(&mut self, repo_path: String, ctx: &mut ViewContext<Self>) {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ pub static SKILL_PROVIDER_DEFINITIONS: LazyLock<Vec<SkillProviderDefinition>> =
|
|||||||
},
|
},
|
||||||
SkillProviderDefinition {
|
SkillProviderDefinition {
|
||||||
provider: SkillProvider::Warp,
|
provider: SkillProvider::Warp,
|
||||||
skills_path: PathBuf::from(".warp").join("skills"),
|
skills_path: PathBuf::from(".warp-core").join("skills"),
|
||||||
},
|
},
|
||||||
SkillProviderDefinition {
|
SkillProviderDefinition {
|
||||||
provider: SkillProvider::Claude,
|
provider: SkillProvider::Claude,
|
||||||
|
|||||||
@@ -47,21 +47,20 @@ pub fn test_preview_config_dir_migration() -> Builder {
|
|||||||
.add_named_assertion(
|
.add_named_assertion(
|
||||||
"new directory exists and is a real directory",
|
"new directory exists and is a real directory",
|
||||||
|_app, _window_id| {
|
|_app, _window_id| {
|
||||||
let new_dir = home_dir().join(".warp-preview");
|
let new_dir = home_dir().join(".warp-core-preview");
|
||||||
|
|
||||||
if !new_dir.is_dir() {
|
if !new_dir.is_dir() {
|
||||||
return AssertionOutcome::failure(
|
return AssertionOutcome::failure(
|
||||||
".warp-preview should be a directory".to_string(),
|
".warp-core-preview should be a directory".to_string(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// It should be a real directory, not a symlink.
|
|
||||||
let is_symlink = new_dir
|
let is_symlink = new_dir
|
||||||
.symlink_metadata()
|
.symlink_metadata()
|
||||||
.map(|m| m.file_type().is_symlink())
|
.map(|m| m.file_type().is_symlink())
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
if is_symlink {
|
if is_symlink {
|
||||||
return AssertionOutcome::failure(
|
return AssertionOutcome::failure(
|
||||||
".warp-preview should not itself be a symlink".to_string(),
|
".warp-core-preview should not itself be a symlink".to_string(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AssertionOutcome::Success
|
AssertionOutcome::Success
|
||||||
@@ -71,8 +70,8 @@ pub fn test_preview_config_dir_migration() -> Builder {
|
|||||||
"expected entries are symlinks pointing to old dir",
|
"expected entries are symlinks pointing to old dir",
|
||||||
|_app, _window_id| {
|
|_app, _window_id| {
|
||||||
let home = home_dir();
|
let home = home_dir();
|
||||||
let old_dir = home.join(".warp");
|
let old_dir = home.join(".warp-core");
|
||||||
let new_dir = home.join(".warp-preview");
|
let new_dir = home.join(".warp-core-preview");
|
||||||
|
|
||||||
for name in ["keybindings.yaml", "themes", "workflows", ".mcp.json"] {
|
for name in ["keybindings.yaml", "themes", "workflows", ".mcp.json"] {
|
||||||
let link = new_dir.join(name);
|
let link = new_dir.join(name);
|
||||||
@@ -110,7 +109,7 @@ pub fn test_preview_config_dir_migration() -> Builder {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.add_named_assertion("excluded files were not symlinked", |_app, _window_id| {
|
.add_named_assertion("excluded files were not symlinked", |_app, _window_id| {
|
||||||
let new_dir = home_dir().join(".warp-preview");
|
let new_dir = home_dir().join(".warp-core-preview");
|
||||||
|
|
||||||
for name in [".DS_Store", "._somefile", "settings.toml"] {
|
for name in [".DS_Store", "._somefile", "settings.toml"] {
|
||||||
if new_dir.join(name).exists() {
|
if new_dir.join(name).exists() {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ pub trait LanguageServerCandidate: Send + Sync {
|
|||||||
self.is_installed_on_path(executor).await
|
self.is_installed_on_path(executor).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to install the server into the `.warp/` directory.
|
/// Attempts to install the server into the `.warp-core/` directory.
|
||||||
///
|
///
|
||||||
/// The executor provides the user's PATH environment variable, which may be needed
|
/// The executor provides the user's PATH environment variable, which may be needed
|
||||||
/// for servers that rely on external tools (e.g. gopls needs `go`).
|
/// for servers that rely on external tools (e.g. gopls needs `go`).
|
||||||
|
|||||||
@@ -112,22 +112,20 @@ pub fn parse_uname_output(output: &str) -> Result<RemotePlatform> {
|
|||||||
|
|
||||||
/// Returns the remote directory where the binary is installed, keyed by channel.
|
/// Returns the remote directory where the binary is installed, keyed by channel.
|
||||||
///
|
///
|
||||||
/// - stable: `~/.warp/remote-server`
|
/// - stable: `~/.warp-core/remote-server`
|
||||||
/// - preview: `~/.warp-preview/remote-server`
|
/// - preview: `~/.warp-core-preview/remote-server`
|
||||||
/// - dev: `~/.warp-dev/remote-server`
|
/// - dev: `~/.warp-core-dev/remote-server`
|
||||||
/// - local: `~/.warp-local/remote-server`
|
/// - local: `~/.warp-core-local/remote-server`
|
||||||
/// - integration: `~/.warp-dev/remote-server`
|
/// - integration: `~/.warp-core-dev/remote-server`
|
||||||
/// - warp-oss: `~/.warp-oss/remote-server`
|
/// - warp-core-oss: `~/.warp-core-oss/remote-server`
|
||||||
pub fn remote_server_dir() -> String {
|
pub fn remote_server_dir() -> String {
|
||||||
let warp_dir = match ChannelState::channel() {
|
let warp_dir = match ChannelState::channel() {
|
||||||
Channel::Stable => ".warp",
|
Channel::Stable => ".warp-core",
|
||||||
Channel::Preview => ".warp-preview",
|
Channel::Preview => ".warp-core-preview",
|
||||||
Channel::Dev | Channel::Integration => ".warp-dev",
|
Channel::Dev | Channel::Integration => ".warp-core-dev",
|
||||||
Channel::Local => ".warp-local",
|
Channel::Local => ".warp-core-local",
|
||||||
Channel::Oss => {
|
Channel::Oss => {
|
||||||
// TODO(alokedesai): need to figure out how remote server works with warp-oss
|
".warp-core-dev"
|
||||||
// For now, return what Dev returns.
|
|
||||||
".warp-dev"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
format!("~/{warp_dir}/remote-server")
|
format!("~/{warp_dir}/remote-server")
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ pub struct RunAgentArgs {
|
|||||||
///
|
///
|
||||||
/// Format: `skill_name`, `repo:skill_name`, or `org/repo:skill_name`
|
/// Format: `skill_name`, `repo:skill_name`, or `org/repo:skill_name`
|
||||||
///
|
///
|
||||||
/// Skills are searched in `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
/// Skills are searched in `.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
||||||
/// If a repo is specified, searches only that repo. If org is also specified,
|
/// If a repo is specified, searches only that repo. If org is also specified,
|
||||||
/// validates the repo's git remote matches the expected org.
|
/// validates the repo's git remote matches the expected org.
|
||||||
///
|
///
|
||||||
@@ -357,7 +357,7 @@ pub struct RunCloudArgs {
|
|||||||
///
|
///
|
||||||
/// Format: `skill_name`, `repo:skill_name`, or `org/repo:skill_name`
|
/// Format: `skill_name`, `repo:skill_name`, or `org/repo:skill_name`
|
||||||
///
|
///
|
||||||
/// Skills are searched in `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
/// Skills are searched in `.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
||||||
/// If a repo is specified, searches only that repo. If org is also specified,
|
/// If a repo is specified, searches only that repo. If org is also specified,
|
||||||
/// validates the repo's git remote matches the expected org.
|
/// validates the repo's git remote matches the expected org.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ pub struct CreateScheduleArgs {
|
|||||||
///
|
///
|
||||||
/// Format: `repo:skill_name` or `org/repo:skill_name`
|
/// Format: `repo:skill_name` or `org/repo:skill_name`
|
||||||
///
|
///
|
||||||
/// Skills are searched in `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
/// Skills are searched in `.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
||||||
/// The skill is resolved at runtime in the agent's cloud environment.
|
/// The skill is resolved at runtime in the agent's cloud environment.
|
||||||
///
|
///
|
||||||
/// When used with --prompt, the skill provides the base context and the prompt is the user task.
|
/// When used with --prompt, the skill provides the base context and the prompt is the user task.
|
||||||
@@ -186,7 +186,7 @@ pub struct UpdateScheduleArgs {
|
|||||||
///
|
///
|
||||||
/// Format: `skill_name`, `repo:skill_name`, or `org/repo:skill_name`
|
/// Format: `skill_name`, `repo:skill_name`, or `org/repo:skill_name`
|
||||||
///
|
///
|
||||||
/// Skills are searched in `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
/// Skills are searched in `.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, and `.codex/skills/` directories.
|
||||||
/// The skill is resolved at runtime in the agent's cloud environment.
|
/// The skill is resolved at runtime in the agent's cloud environment.
|
||||||
#[arg(long = "skill", value_name = "SPEC", conflicts_with = "remove_skill")]
|
#[arg(long = "skill", value_name = "SPEC", conflicts_with = "remove_skill")]
|
||||||
pub skill: Option<SkillSpec>,
|
pub skill: Option<SkillSpec>,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::{fmt, str::FromStr};
|
|||||||
/// A skill specifier that can reference a skill in a specific repo or search the current directory.
|
/// A skill specifier that can reference a skill in a specific repo or search the current directory.
|
||||||
///
|
///
|
||||||
/// The skill identifier (after the optional `repo:` or `org/repo:` prefix) can be either:
|
/// The skill identifier (after the optional `repo:` or `org/repo:` prefix) can be either:
|
||||||
/// - A **simple skill name** - searched across skill directories with precedence (`.agents/skills/`, `.warp/skills/`, `.claude/skills/`, `.codex/skills/`)
|
/// - A **simple skill name** - searched across skill directories with precedence (`.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, `.codex/skills/`)
|
||||||
/// - A **full path to SKILL.md** - resolved directly without precedence
|
/// - A **full path to SKILL.md** - resolved directly without precedence
|
||||||
///
|
///
|
||||||
/// # Formats
|
/// # Formats
|
||||||
@@ -19,7 +19,7 @@ use std::{fmt, str::FromStr};
|
|||||||
///
|
///
|
||||||
/// Simple skill names (searched with directory precedence):
|
/// Simple skill names (searched with directory precedence):
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// code-review // searches .agents/skills/, .warp/skills/, .claude/skills/, .codex/skills/
|
/// code-review // searches .agents/skills/, .warp-core/skills/, .claude/skills/, .codex/skills/
|
||||||
/// warp-internal:code-review // searches in "warp-internal" repo
|
/// warp-internal:code-review // searches in "warp-internal" repo
|
||||||
/// warpdotdev/warp-internal:code-review // searches in specific org/repo
|
/// warpdotdev/warp-internal:code-review // searches in specific org/repo
|
||||||
/// ```
|
/// ```
|
||||||
@@ -38,7 +38,7 @@ pub struct SkillSpec {
|
|||||||
pub repo: Option<String>,
|
pub repo: Option<String>,
|
||||||
/// The skill identifier - either a simple name or a full path to SKILL.md.
|
/// The skill identifier - either a simple name or a full path to SKILL.md.
|
||||||
///
|
///
|
||||||
/// - **Simple name** (e.g., `"code-review"`): Searched across `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, `.codex/skills/`
|
/// - **Simple name** (e.g., `"code-review"`): Searched across `.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, `.codex/skills/`
|
||||||
/// in precedence order. The name is used to construct paths like `.claude/skills/code-review/SKILL.md`.
|
/// in precedence order. The name is used to construct paths like `.claude/skills/code-review/SKILL.md`.
|
||||||
///
|
///
|
||||||
/// - **Full path** (e.g., `".claude/skills/code-review/SKILL.md"`): Resolved directly without precedence.
|
/// - **Full path** (e.g., `".claude/skills/code-review/SKILL.md"`): Resolved directly without precedence.
|
||||||
@@ -87,7 +87,7 @@ impl SkillSpec {
|
|||||||
/// - `deploy`
|
/// - `deploy`
|
||||||
///
|
///
|
||||||
/// Full paths are resolved directly, while simple names are searched across
|
/// Full paths are resolved directly, while simple names are searched across
|
||||||
/// skill directories in precedence order (`.agents/skills/`, `.warp/skills/`, `.claude/skills/`, `.codex/skills/`).
|
/// skill directories in precedence order (`.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, `.codex/skills/`).
|
||||||
///
|
///
|
||||||
/// Uses cross-platform path semantics via [`std::path::Path`].
|
/// Uses cross-platform path semantics via [`std::path::Path`].
|
||||||
pub fn is_full_path(&self) -> bool {
|
pub fn is_full_path(&self) -> bool {
|
||||||
|
|||||||
@@ -24,11 +24,15 @@ use crate::{
|
|||||||
AppId,
|
AppId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The name of the directory in which to put non-global Warp-specific files.
|
/// The name of the directory in which to put non-global Warp Core-specific files.
|
||||||
///
|
///
|
||||||
/// This should be used, for example, as the base directory under which
|
/// This should be used, for example, as the base directory under which
|
||||||
/// repository workflows would be stored (in "./.warp/workflows").
|
/// repository workflows would be stored (in "./.warp-core/workflows").
|
||||||
pub const WARP_CONFIG_DIR: &str = ".warp";
|
pub const WARP_CONFIG_DIR: &str = ".warp-core";
|
||||||
|
|
||||||
|
/// The legacy config directory name used by Warp before the rename to Warp Core.
|
||||||
|
/// Used for auto-migration on first launch.
|
||||||
|
pub const LEGACY_WARP_CONFIG_DIR: &str = ".warp";
|
||||||
|
|
||||||
/// The name of the folder that stores Warp execution logs and network logs.
|
/// The name of the folder that stores Warp execution logs and network logs.
|
||||||
/// This is currently only used on Windows to maintain backwards compatibility.
|
/// This is currently only used on Windows to maintain backwards compatibility.
|
||||||
@@ -59,15 +63,142 @@ pub fn warp_home_config_dir_name() -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the home-relative Warp config directory for the current channel and data profile.
|
/// Returns the home-relative Warp Core config directory for the current channel and data profile.
|
||||||
///
|
///
|
||||||
/// Unlike [`data_dir`] and [`config_local_dir`] on non-macOS platforms, this intentionally keeps
|
/// Unlike [`data_dir`] and [`config_local_dir`] on non-macOS platforms, this intentionally keeps
|
||||||
/// Warp-authored, user-facing config under a `.warp*` directory in the home directory instead of
|
/// user-facing config under a `.warp-core*` directory in the home directory instead of
|
||||||
/// using the platform XDG/AppData project directories.
|
/// using the platform XDG/AppData project directories.
|
||||||
pub fn warp_home_config_dir() -> Option<PathBuf> {
|
pub fn warp_home_config_dir() -> Option<PathBuf> {
|
||||||
dirs::home_dir().map(|home_dir| home_dir.join(warp_home_config_dir_name()))
|
dirs::home_dir().map(|home_dir| home_dir.join(warp_home_config_dir_name()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the legacy `~/.warp*` config directory path for the current channel,
|
||||||
|
/// used to detect and migrate data from a previous Warp installation.
|
||||||
|
pub fn legacy_warp_home_config_dir() -> Option<PathBuf> {
|
||||||
|
let base = LEGACY_WARP_CONFIG_DIR;
|
||||||
|
let dir_name = match ChannelState::channel() {
|
||||||
|
Channel::Stable | Channel::Preview => base.to_owned(),
|
||||||
|
Channel::Oss => format!("{base}-oss"),
|
||||||
|
Channel::Dev => format!("{base}-dev"),
|
||||||
|
Channel::Integration => format!("{base}-integration"),
|
||||||
|
Channel::Local => format!("{base}-local"),
|
||||||
|
};
|
||||||
|
let dir_name = if let Some(data_profile) = ChannelState::data_profile() {
|
||||||
|
format!("{dir_name}-{data_profile}")
|
||||||
|
} else {
|
||||||
|
dir_name
|
||||||
|
};
|
||||||
|
dirs::home_dir().map(|home_dir| home_dir.join(dir_name))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Migrates the legacy `~/.warp*` config directory to `~/.warp-core*` if needed.
|
||||||
|
///
|
||||||
|
/// This runs once on first launch after the rename. It creates symlinks from the
|
||||||
|
/// old directory entries into the new directory, preserving access to existing
|
||||||
|
/// configuration (keybindings, themes, workflows, skills, etc.).
|
||||||
|
///
|
||||||
|
/// This is a no-op if:
|
||||||
|
/// - The new directory already exists.
|
||||||
|
/// - The old directory does not exist.
|
||||||
|
pub fn migrate_legacy_config_dir_if_needed() {
|
||||||
|
let Some(old_dir) = legacy_warp_home_config_dir() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(new_dir) = warp_home_config_dir() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if new_dir.exists() || !old_dir.exists() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::symlink;
|
||||||
|
|
||||||
|
if let Err(err) = std::fs::create_dir(&new_dir) {
|
||||||
|
if err.kind() != std::io::ErrorKind::AlreadyExists {
|
||||||
|
log::warn!(
|
||||||
|
"Failed to create config directory {}: {err}",
|
||||||
|
new_dir.display()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let entries = match std::fs::read_dir(&old_dir) {
|
||||||
|
Ok(entries) => entries,
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!(
|
||||||
|
"Failed to read legacy config directory {}: {err}",
|
||||||
|
old_dir.display()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut migrated = 0u32;
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let name = entry.file_name();
|
||||||
|
let name_str = name.to_string_lossy();
|
||||||
|
|
||||||
|
if name_str == ".DS_Store" || name_str.starts_with("._") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target = old_dir.join(&name);
|
||||||
|
let link = new_dir.join(&name);
|
||||||
|
|
||||||
|
if let Err(err) = symlink(&target, &link) {
|
||||||
|
log::warn!(
|
||||||
|
"Failed to symlink {} -> {}: {err}",
|
||||||
|
link.display(),
|
||||||
|
target.display()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
migrated += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log::info!(
|
||||||
|
"Migrated legacy config directory: created {migrated} symlinks in {}",
|
||||||
|
new_dir.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
fn copy_dir_recursive(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||||
|
std::fs::create_dir_all(dst)?;
|
||||||
|
for entry in std::fs::read_dir(src)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let ty = entry.file_type()?;
|
||||||
|
let dest = dst.join(entry.file_name());
|
||||||
|
if ty.is_dir() {
|
||||||
|
copy_dir_recursive(&entry.path(), &dest)?;
|
||||||
|
} else {
|
||||||
|
std::fs::copy(entry.path(), dest)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = copy_dir_recursive(&old_dir, &new_dir) {
|
||||||
|
log::warn!(
|
||||||
|
"Failed to copy legacy config directory {} to {}: {err}",
|
||||||
|
old_dir.display(),
|
||||||
|
new_dir.display()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
log::info!(
|
||||||
|
"Migrated legacy config directory {} to {}",
|
||||||
|
old_dir.display(),
|
||||||
|
new_dir.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn warp_home_skills_dir() -> Option<PathBuf> {
|
pub fn warp_home_skills_dir() -> Option<PathBuf> {
|
||||||
warp_home_config_dir().map(|warp_config_dir| warp_config_dir.join("skills"))
|
warp_home_config_dir().map(|warp_config_dir| warp_config_dir.join("skills"))
|
||||||
}
|
}
|
||||||
@@ -78,8 +209,8 @@ pub fn warp_home_mcp_config_file_path() -> Option<PathBuf> {
|
|||||||
|
|
||||||
/// Returns the macOS config directory name for the current channel.
|
/// Returns the macOS config directory name for the current channel.
|
||||||
///
|
///
|
||||||
/// Stable uses `.warp`, while other channels include a channel suffix
|
/// Stable uses `.warp-core`, while other channels include a channel suffix
|
||||||
/// (e.g., `.warp-dev`, `.warp-local`).
|
/// (e.g., `.warp-core-dev`, `.warp-core-local`).
|
||||||
///
|
///
|
||||||
/// These suffixes are persisted on disk as directory names and must not be
|
/// These suffixes are persisted on disk as directory names and must not be
|
||||||
/// changed once established, or existing user data will be orphaned.
|
/// changed once established, or existing user data will be orphaned.
|
||||||
@@ -275,7 +406,7 @@ pub fn app_group_container_path() -> Option<PathBuf> {
|
|||||||
|
|
||||||
let fm = NSFileManager::defaultManager();
|
let fm = NSFileManager::defaultManager();
|
||||||
// Keep in sync with Entitlements.plist
|
// Keep in sync with Entitlements.plist
|
||||||
let group_id = format!("{}.dev.warp", crate::macos::APPLE_TEAM_ID);
|
let group_id = format!("{}.dev.warpcore", crate::macos::APPLE_TEAM_ID);
|
||||||
let group_id = NSString::from_str(&group_id);
|
let group_id = NSString::from_str(&group_id);
|
||||||
// containerURLForSecurityApplicationGroupIdentifier always returns a value on macOS (unlike iOS).
|
// containerURLForSecurityApplicationGroupIdentifier always returns a value on macOS (unlike iOS).
|
||||||
// We have to double-check that the path points to a directory we can actually use. In addition to
|
// We have to double-check that the path points to a directory we can actually use. In addition to
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ fn test_data_dir_path() {
|
|||||||
// ChannelState, by default, is configured for Channel::Oss.
|
// ChannelState, by default, is configured for Channel::Oss.
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "macos")] {
|
if #[cfg(target_os = "macos")] {
|
||||||
assert_eq!(data_dir(), home_dir.join(".warp-oss"));
|
assert_eq!(data_dir(), home_dir.join(".warp-core-oss"));
|
||||||
} else if #[cfg(target_os = "linux")] {
|
} else if #[cfg(target_os = "linux")] {
|
||||||
assert_eq!(data_dir(), home_dir.join(".local/share/warp-oss"));
|
assert_eq!(data_dir(), home_dir.join(".local/share/warp-oss"));
|
||||||
} else if #[cfg(windows)] {
|
} else if #[cfg(windows)] {
|
||||||
@@ -25,7 +25,7 @@ fn test_config_local_dir_path() {
|
|||||||
// ChannelState, by default, is configured for Channel::Oss.
|
// ChannelState, by default, is configured for Channel::Oss.
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "macos")] {
|
if #[cfg(target_os = "macos")] {
|
||||||
assert_eq!(config_local_dir(), home_dir.join(".warp-oss"));
|
assert_eq!(config_local_dir(), home_dir.join(".warp-core-oss"));
|
||||||
} else if #[cfg(target_os = "linux")] {
|
} else if #[cfg(target_os = "linux")] {
|
||||||
assert_eq!(config_local_dir(), home_dir.join(".config/warp-oss"));
|
assert_eq!(config_local_dir(), home_dir.join(".config/warp-oss"));
|
||||||
} else if #[cfg(windows)] {
|
} else if #[cfg(windows)] {
|
||||||
@@ -40,8 +40,8 @@ fn test_config_local_dir_path() {
|
|||||||
fn test_warp_home_config_dir_path() {
|
fn test_warp_home_config_dir_path() {
|
||||||
let home_dir = home_dir().expect("Should be able to compute home directory");
|
let home_dir = home_dir().expect("Should be able to compute home directory");
|
||||||
let expected_dir_name = match ChannelState::data_profile() {
|
let expected_dir_name = match ChannelState::data_profile() {
|
||||||
Some(data_profile) => format!(".warp-oss-{data_profile}"),
|
Some(data_profile) => format!(".warp-core-oss-{data_profile}"),
|
||||||
None => ".warp-oss".to_string(),
|
None => ".warp-core-oss".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -654,7 +654,7 @@ pub enum FeatureFlag {
|
|||||||
|
|
||||||
/// Enables platform skills support (--skill flag) for agent runs.
|
/// Enables platform skills support (--skill flag) for agent runs.
|
||||||
///
|
///
|
||||||
/// Skills are loaded from `.agents/skills/`, `.warp/skills/`, `.claude/skills/`, and `.codex/skills/`
|
/// Skills are loaded from `.agents/skills/`, `.warp-core/skills/`, `.claude/skills/`, and `.codex/skills/`
|
||||||
/// directories to provide base prompts for agent runs.
|
/// directories to provide base prompts for agent runs.
|
||||||
OzPlatformSkills,
|
OzPlatformSkills,
|
||||||
/// Enables Oz identity federation commands.
|
/// Enables Oz identity federation commands.
|
||||||
|
|||||||
Reference in New Issue
Block a user