Initial public release of Warp.
Repo-Sync-Origin: warpdotdev/warp-internal@12af1d983b
@@ -0,0 +1,982 @@
|
||||
[package]
|
||||
authors = ["Warp Team <dev@warp.dev>"]
|
||||
default-run = "warp-oss"
|
||||
description = "The cloud-backed terminal for individuals and teams"
|
||||
edition = "2021"
|
||||
autobins = false
|
||||
name = "warp"
|
||||
version = "0.1.0"
|
||||
publish.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[lib]
|
||||
name = "warp"
|
||||
path = "src/lib.rs"
|
||||
|
||||
# We define separate targets for each channel (stable, preview, dev) so that we can
|
||||
# bundle with its own icon, app name, and channel-specific configuration (such as
|
||||
# flag overrides). Otherwise these binaries are exactly identical to our main binary.
|
||||
|
||||
[[bin]]
|
||||
name = "warp-oss"
|
||||
path = "src/bin/oss.rs"
|
||||
test = false
|
||||
|
||||
[[bin]]
|
||||
name = "warp"
|
||||
path = "src/bin/local.rs"
|
||||
test = false
|
||||
|
||||
[[bin]]
|
||||
name = "stable"
|
||||
path = "src/bin/stable.rs"
|
||||
test = false
|
||||
|
||||
[[bin]]
|
||||
name = "dev"
|
||||
path = "src/bin/dev.rs"
|
||||
test = false
|
||||
|
||||
[[bin]]
|
||||
name = "preview"
|
||||
path = "src/bin/preview.rs"
|
||||
required-features = ["preview_channel"]
|
||||
test = false
|
||||
|
||||
[[bin]]
|
||||
name = "generate_settings_schema"
|
||||
path = "src/bin/generate_settings_schema.rs"
|
||||
test = false
|
||||
|
||||
[dependencies]
|
||||
addr = "0.15.6"
|
||||
ai.workspace = true
|
||||
anyhow.workspace = true
|
||||
arrayvec.workspace = true
|
||||
asset_cache.workspace = true
|
||||
asset_macro.workspace = true
|
||||
async-broadcast.workspace = true
|
||||
async-channel.workspace = true
|
||||
async-compat.workspace = true
|
||||
async-fs.workspace = true
|
||||
async-recursion.workspace = true
|
||||
async-stream.workspace = true
|
||||
async-trait.workspace = true
|
||||
base64.workspace = true
|
||||
bimap = "0.6.2"
|
||||
bincode.workspace = true
|
||||
bitflags.workspace = true
|
||||
bitflags-serde-legacy.workspace = true
|
||||
blocking.workspace = true
|
||||
bounded-vec-deque = "0.1"
|
||||
bytecount = "0.6.9"
|
||||
bytes.workspace = true
|
||||
byte-unit = "5.1.4"
|
||||
cfg-if.workspace = true
|
||||
channel_versions.workspace = true
|
||||
chrono.workspace = true
|
||||
clap.workspace = true
|
||||
command = { workspace = true }
|
||||
command-corrections.workspace = true
|
||||
command-signatures-v2 = { workspace = true, optional = true }
|
||||
computer_use.workspace = true
|
||||
crc.workspace = true
|
||||
content_inspector = "0.2.4"
|
||||
concat-idents.workspace = true
|
||||
csv = "1.3.1"
|
||||
cynic.workspace = true
|
||||
dashmap.workspace = true
|
||||
deltae = "0.3.1"
|
||||
derivative.workspace = true
|
||||
dhat = { version = "0.3.2", optional = true }
|
||||
diesel.workspace = true
|
||||
difflib = { git = "https://github.com/warpdotdev/difflib.git", rev = "114177e7d8e1f8017baca397f943e11644b14d63" }
|
||||
directories.workspace = true
|
||||
dirs.workspace = true
|
||||
dunce.workspace = true
|
||||
email_address = { git = "https://github.com/warpdotdev/rust-email_address", branch = "main" }
|
||||
embed_plist = "1.2"
|
||||
enclose = "1.1.8"
|
||||
enum-iterator.workspace = true
|
||||
event-listener = "5.4.0"
|
||||
field_mask.workspace = true
|
||||
firebase.workspace = true
|
||||
flate2 = "1.0.17"
|
||||
float-cmp.workspace = true
|
||||
futures-lite.workspace = true
|
||||
futures-util.workspace = true
|
||||
futures.workspace = true
|
||||
fuzzy_match.workspace = true
|
||||
getset.workspace = true
|
||||
handlebars.workspace = true
|
||||
hex.workspace = true
|
||||
http.workspace = true
|
||||
http_client.workspace = true
|
||||
image.workspace = true
|
||||
infer = "0.19.0"
|
||||
jaq-json.workspace = true
|
||||
jaq-all.workspace = true
|
||||
jemalloc_pprof = { version = "0.8.1", optional = true, features = [
|
||||
"symbolize",
|
||||
] }
|
||||
lsp-types = "0.97.0"
|
||||
indexmap = { version = "2.0.2", features = ["serde"] }
|
||||
input_classifier.workspace = true
|
||||
instant.workspace = true
|
||||
ipc.workspace = true
|
||||
itertools.workspace = true
|
||||
kmeans_colors = { version = "0.5", default-features = false, features = [
|
||||
"palette_color",
|
||||
] }
|
||||
lazy_static.workspace = true
|
||||
libc.workspace = true
|
||||
line-ending.workspace = true
|
||||
log.workspace = true
|
||||
log-panics = { version = "2.1.0", features = ["with-backtrace"] }
|
||||
lsp.workspace = true
|
||||
warp_logging.workspace = true
|
||||
sentry = { workspace = true, optional = true }
|
||||
lz4_flex = "0.11"
|
||||
markdown_parser.workspace = true
|
||||
memchr.workspace = true
|
||||
memo-map.workspace = true
|
||||
mermaid_to_svg.workspace = true
|
||||
num-traits.workspace = true
|
||||
num_cpus = "1.13.0"
|
||||
oauth2.workspace = true
|
||||
once_cell.workspace = true
|
||||
ordered-float.workspace = true
|
||||
os_info = { version = "3.7.0", default-features = false }
|
||||
palette = { version = "0.6.0", default-features = false, features = ["std"] }
|
||||
parking_lot = { version = "0.12.1", features = ["serde"] }
|
||||
paste = "1.0"
|
||||
pathfinder_color = "0.5.0"
|
||||
pathfinder_geometry.workspace = true
|
||||
persistence.workspace = true
|
||||
pin-project.workspace = true
|
||||
plist = "1"
|
||||
pprof = { workspace = true, optional = true, features = ["protobuf-codec"] }
|
||||
prost.workspace = true
|
||||
prost-types.workspace = true
|
||||
rand.workspace = true
|
||||
rangemap.workspace = true
|
||||
rayon.workspace = true
|
||||
regex-automata = "0.4.6"
|
||||
regex.workspace = true
|
||||
reqwest.workspace = true
|
||||
rust-embed.workspace = true
|
||||
sentry-log = { workspace = true, optional = true }
|
||||
inventory = "0.3"
|
||||
schemars = "1"
|
||||
serde.workspace = true
|
||||
serde_bytes.workspace = true
|
||||
serde-bytes-repr.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_regex = "1.1.0"
|
||||
serde_urlencoded.workspace = true
|
||||
serde_with.workspace = true
|
||||
serde_yaml.workspace = true
|
||||
session-sharing-protocol.workspace = true
|
||||
settings.workspace = true
|
||||
settings_value = { workspace = true, features = ["derive"] }
|
||||
sha2.workspace = true
|
||||
shellexpand.workspace = true
|
||||
shell-words = "1.1.0"
|
||||
shlex = "1.3.0"
|
||||
siphasher = "0.3.11"
|
||||
similar.workspace = true
|
||||
simple_logger.workspace = true
|
||||
smallvec.workspace = true
|
||||
smol_str.workspace = true
|
||||
static_assertions.workspace = true
|
||||
string-offset.workspace = true
|
||||
sum_tree.workspace = true
|
||||
tabwriter = "1.4"
|
||||
tempfile.workspace = true
|
||||
thiserror.workspace = true
|
||||
thousands = "0.2.0"
|
||||
tikv-jemallocator = { version = "0.6", optional = true, features = [
|
||||
"override_allocator_on_supported_platforms",
|
||||
] }
|
||||
toml = "0.8.13"
|
||||
tracing.workspace = true
|
||||
ui_components.workspace = true
|
||||
unicase = "2.7.0"
|
||||
unicode-width.workspace = true
|
||||
unindent = "0.1.7"
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
urlocator.workspace = true
|
||||
uuid.workspace = true
|
||||
warp_cli.workspace = true
|
||||
validator = "0.19.0"
|
||||
variant_count = "1.1.0"
|
||||
vec1.workspace = true
|
||||
version-compare.workspace = true
|
||||
vte.workspace = true
|
||||
walkdir.workspace = true
|
||||
warp-workflows.workspace = true
|
||||
warp_completer.workspace = true
|
||||
warp_core.workspace = true
|
||||
warp_editor.workspace = true
|
||||
warp_graphql.workspace = true
|
||||
warp_js = { workspace = true, optional = true }
|
||||
warp_server_client.workspace = true
|
||||
warp_util.workspace = true
|
||||
warpui = { workspace = true, features = ["schema_gen", "settings_value"] }
|
||||
voice_input = { workspace = true, optional = true }
|
||||
warpui_extras = { workspace = true, features = ["default", "user_preferences-toml"] }
|
||||
syntax_tree.workspace = true
|
||||
languages.workspace = true
|
||||
warp_terminal.workspace = true
|
||||
websocket.workspace = true
|
||||
wgpu = { workspace = true, optional = true }
|
||||
natural_language_detection.workspace = true
|
||||
onboarding.workspace = true
|
||||
aho-corasick = "1.1.3"
|
||||
strum.workspace = true
|
||||
strum_macros.workspace = true
|
||||
reqwest-eventsource = { workspace = true }
|
||||
lasso.workspace = true
|
||||
counter = "0.6.0"
|
||||
typed-path.workspace = true
|
||||
urlencoding = "2.1.3"
|
||||
mime_guess = "2.0"
|
||||
warp_multi_agent_api.workspace = true
|
||||
remote_server.workspace = true
|
||||
repo_metadata.workspace = true
|
||||
vim.workspace = true
|
||||
rmcp = { workspace = true, features = ["client"] }
|
||||
warp_isolation_platform.workspace = true
|
||||
warp_ripgrep.workspace = true
|
||||
warp_managed_secrets.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
block.workspace = true
|
||||
cocoa.workspace = true
|
||||
core-foundation.workspace = true
|
||||
mach2 = "0.5"
|
||||
objc.workspace = true
|
||||
objc2-foundation = { workspace = true, features = ["NSBundle"] }
|
||||
permissions = "0.4.1"
|
||||
pprof = { workspace = true, optional = true, features = ["frame-pointer"] }
|
||||
security-framework-sys = "2.0.0"
|
||||
|
||||
[target.'cfg(not(target_os = "macos"))'.dependencies]
|
||||
winit = { workspace = true }
|
||||
wgpu.workspace = true
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
app-installation-detection.workspace = true
|
||||
async-io.workspace = true
|
||||
axum.workspace = true
|
||||
comfy-table = "7.1.4"
|
||||
inquire = "0.9.1"
|
||||
diesel = { workspace = true, features = ["sqlite", "chrono"] }
|
||||
diesel_migrations = { version = "2.2.0", features = ["sqlite"] }
|
||||
env_logger.workspace = true
|
||||
git2 = { version = "0.20.4", default-features = false, features = [
|
||||
"vendored-libgit2",
|
||||
] }
|
||||
http_server.workspace = true
|
||||
hyper.workspace = true
|
||||
libsqlite3-sys = { version = "0.33.0", features = ["bundled"] }
|
||||
mio = { version = "1.1.1", features = ["os-poll", "os-ext"] }
|
||||
tokio.workspace = true
|
||||
tokio-util.workspace = true
|
||||
|
||||
# AWS SDK (loading credentials for BYO LLM)
|
||||
aws-config = { version = "1.8.12", features = ["credentials-login"] }
|
||||
aws-credential-types = "1"
|
||||
aws-sdk-sts = "1"
|
||||
aws-types = "1"
|
||||
|
||||
rmcp = { workspace = true, features = [
|
||||
"auth",
|
||||
"transport-streamable-http-client-reqwest",
|
||||
"transport-sse-client-reqwest",
|
||||
"transport-child-process",
|
||||
] }
|
||||
notify-debouncer-full.workspace = true
|
||||
rquickjs = { workspace = true, optional = true }
|
||||
rustls.workspace = true
|
||||
syntect = "5.0"
|
||||
sysinfo.workspace = true
|
||||
warp-command-signatures = { workspace = true, features = ["embed-signatures"] }
|
||||
is_executable = "1.0.1"
|
||||
gethostname = "1.1.0"
|
||||
watcher.workspace = true
|
||||
warp_files.workspace = true
|
||||
tantivy = "0.26.0"
|
||||
|
||||
[target.'cfg(target_family = "wasm")'.dependencies]
|
||||
console_error_panic_hook = { version = "0.1.6" }
|
||||
# We only have an indirect dependency on this crate; we depend on reqwest-eventsource@0.6.0 which depends on
|
||||
# futures-timer@3.0.2. For whatever unfortunate reason, this crate doesn't automatically enable its feature
|
||||
# required for wasm-compatibility when targeting wasm. So we need to explicitly specify this dependency when
|
||||
# targeting wasm and leverage the fact that cargo enables the superset of enabled features for a given crate.
|
||||
futures-timer = { version = "3.0.2", features = ["wasm-bindgen"] }
|
||||
js-sys = "0.3.63"
|
||||
# Make sure we embed the data into the wasm binary even when running in debug
|
||||
# mode, as it cannot be read directly from the filesystem.
|
||||
rust-embed = { workspace = true, features = ["debug-embed"] }
|
||||
syntect = { version = "5.0", default-features = false, features = [
|
||||
"default-fancy",
|
||||
] }
|
||||
wasm-bindgen.workspace = true
|
||||
# We need to make sure that "js" is enabled as a feature when using wasm.
|
||||
getrandom = { version = "0.2", features = ["js"] }
|
||||
gloo.workspace = true
|
||||
serde-wasm-bindgen = "0.6.5"
|
||||
# For wasm, we don't use the feature "embed-signatures".
|
||||
warp-command-signatures = { workspace = true }
|
||||
web-sys.workspace = true
|
||||
warp_web_event_bus.workspace = true
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
cvt = "0.1.1"
|
||||
signal-hook = "0.3.17"
|
||||
signal-hook-mio = { version = "0.2.4", features = ["support-v1_0"] }
|
||||
nix = { workspace = true, features = [
|
||||
"fs",
|
||||
"hostname",
|
||||
"resource",
|
||||
"signal",
|
||||
"socket",
|
||||
"term",
|
||||
"uio",
|
||||
"user",
|
||||
"mman",
|
||||
] }
|
||||
|
||||
[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies]
|
||||
crash-handler = { version = "0.6.3", optional = true }
|
||||
minidumper = { version = "0.8.3", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
freedesktop-desktop-entry = "0.5.0"
|
||||
x11rb.workspace = true
|
||||
zbus.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
bytemuck.workspace = true
|
||||
windows = { workspace = true, features = [
|
||||
"Wdk_Foundation",
|
||||
"Wdk_Storage_FileSystem",
|
||||
"Win32_Security",
|
||||
"Win32_Storage",
|
||||
"Win32_Storage_FileSystem",
|
||||
"Win32_System_Console",
|
||||
"Win32_System_Diagnostics_Debug",
|
||||
"Win32_System_Environment",
|
||||
"Win32_System_IO",
|
||||
"Win32_System_ProcessStatus",
|
||||
"Win32_System_SystemInformation",
|
||||
"Win32_System_Threading",
|
||||
"Win32_System_LibraryLoader",
|
||||
"Win32_System_WindowsProgramming",
|
||||
"Win32_UI_WindowsAndMessaging",
|
||||
] }
|
||||
windows-registry = { workspace = true }
|
||||
windows-result = { workspace = true }
|
||||
winreg.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
ai = { workspace = true, features = ["test-util"] }
|
||||
async-process.workspace = true
|
||||
jsonschema = { workspace = true, default-features = false }
|
||||
async-executor = "1.5.1"
|
||||
command = { workspace = true, features = ["test-util"] }
|
||||
ctor = "0.1.18"
|
||||
http_client = { workspace = true, features = ["test-util"] }
|
||||
mockall = "0.13.1"
|
||||
mockito.workspace = true
|
||||
serial_test = "0.8.0"
|
||||
sum_tree = { workspace = true, features = ["test-util"] }
|
||||
virtual-fs.workspace = true
|
||||
warp_completer = { workspace = true, features = ["test-util"] }
|
||||
warp_core = { workspace = true, features = ["test-util"] }
|
||||
warp_editor = { workspace = true, features = ["test-util"] }
|
||||
warp_server_client = { workspace = true, features = ["test-util"] }
|
||||
warp_terminal = { workspace = true, features = ["test-util"] }
|
||||
warpui = { workspace = true, features = ["test-util"] }
|
||||
warpui_extras = { workspace = true, features = ["test-util"] }
|
||||
warp_files = { workspace = true, features = ["test-util"] }
|
||||
repo_metadata = { workspace = true, features = ["test-util"] }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "process", "time"] }
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0"
|
||||
cc = "1.0"
|
||||
cfg_aliases.workspace = true
|
||||
prost-build.workspace = true
|
||||
sha2.workspace = true
|
||||
tempfile.workspace = true
|
||||
walkdir = "2.3.2"
|
||||
warp_util.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
embed-resource = "3.0"
|
||||
|
||||
# Note that we support channel-specific enables for these features
|
||||
[features]
|
||||
ai_resume_button = []
|
||||
autoupdate = []
|
||||
figma_detection = []
|
||||
bundled_skills = []
|
||||
agent_mode = []
|
||||
agent_mode_computer_use = []
|
||||
agent_mode_debug = []
|
||||
agent_mode_primary_xml = []
|
||||
agent_mode_pre_plan_xml = []
|
||||
agent_onboarding = []
|
||||
agent_shared_sessions = []
|
||||
ask_user_question = []
|
||||
changelog = []
|
||||
clear_autosuggestion_on_escape = []
|
||||
cloud_object_initial_load = ["enforce_revisions_to_cloud_objects"]
|
||||
codebase_index_speedbump = []
|
||||
cocoa_sentry = ["crash_reporting"]
|
||||
command_predictor = []
|
||||
context_line_review_comments = []
|
||||
completions_v2 = [
|
||||
"plugin_host",
|
||||
"warp_completer/v2",
|
||||
"dep:command-signatures-v2",
|
||||
]
|
||||
crash_reporting = [
|
||||
"dep:sentry",
|
||||
"dep:sentry-log",
|
||||
"dep:minidumper",
|
||||
"dep:crash-handler",
|
||||
"warp_logging/crash_reporting",
|
||||
"ai/crash_reporting",
|
||||
]
|
||||
creating_shared_sessions = []
|
||||
cross_repo_context = []
|
||||
codebase_index_persistence = ["full_source_code_embedding"]
|
||||
default = [
|
||||
"agent_mode",
|
||||
"viewing_shared_sessions",
|
||||
"render_continuous_block_selections_with_single_border",
|
||||
"settings_import",
|
||||
"shared_with_me",
|
||||
"block_toolbelt_save_as_workflow",
|
||||
"remove_alt_screen_padding",
|
||||
"less_horizontal_terminal_padding",
|
||||
"session_sharing_acls",
|
||||
"external_agent_mode_context",
|
||||
"shell_selector",
|
||||
"minimalist_ui",
|
||||
"avatar_in_tab_bar",
|
||||
"full_screen_zen_mode",
|
||||
"workflow_aliases",
|
||||
"ligatures",
|
||||
"dynamic_workflow_enums",
|
||||
"rect_selection",
|
||||
"reload_stale_conversation_files",
|
||||
"loginless_conversion",
|
||||
"warp_packs",
|
||||
"ai_rules",
|
||||
"suggested_rules",
|
||||
"default_waterfall_mode",
|
||||
"am_workflows",
|
||||
"autoupdate_ui_revamp",
|
||||
"render_agent_mode_output_markdown",
|
||||
"agent_mode_primary_xml",
|
||||
"agent_mode_pre_plan_xml",
|
||||
"command_correction_key",
|
||||
"kitty_images",
|
||||
"global_ai_analytics_collection",
|
||||
"grep_tool",
|
||||
"validate_autosuggestions",
|
||||
"clear_autosuggestion_on_escape",
|
||||
"file_retrieval_tools",
|
||||
"mcp_server",
|
||||
"fast_forward_autoexecute_button",
|
||||
"image_as_context",
|
||||
"command_palette_file_search",
|
||||
"usage_based_pricing",
|
||||
"ai_context_menu",
|
||||
"at_menu_outside_of_ai_mode",
|
||||
"agent_management_view",
|
||||
"agent_management_details_view",
|
||||
"interactive_conversation_management_view",
|
||||
"shared_block_title_generation",
|
||||
"tab_close_button_on_left",
|
||||
"ai_resume_button",
|
||||
"code_find_replace",
|
||||
"ai_context_menu_code",
|
||||
"agent_decides_command_execution",
|
||||
"linked_code_blocks",
|
||||
"drive_objects_as_context",
|
||||
"search_codebase_ui",
|
||||
"profiles_design_revamp",
|
||||
"multi_profile",
|
||||
"tabbed_editor_view",
|
||||
"allow_opening_file_links_using_editor_env",
|
||||
"read_image_files",
|
||||
"selection_as_context",
|
||||
"changed_lines_only_apply_diff_result",
|
||||
"undo_closed_panes",
|
||||
"revert_diff_hunk",
|
||||
"code_review_save_changes",
|
||||
"create_project_flow",
|
||||
"get_started_tab",
|
||||
"file_tree",
|
||||
"vim_code_editor",
|
||||
"code_launch_modal",
|
||||
"allow_ignoring_input_suggestions",
|
||||
"mcp_oauth",
|
||||
"expand_edit_to_pane",
|
||||
"fallback_model_load_output_messaging",
|
||||
"api_key_authentication",
|
||||
"api_key_management",
|
||||
"summarization_cancellation_confirmation",
|
||||
"ui_zoom",
|
||||
"discard_per_file_and_all_changes",
|
||||
"auto_open_code_review_pane",
|
||||
"diff_set_as_context",
|
||||
"summarize_conversation_command",
|
||||
"inline_code_review",
|
||||
"web_search_ui",
|
||||
"agent_shared_sessions",
|
||||
"integration_command",
|
||||
"artifact_command",
|
||||
"cloud_environments",
|
||||
"create_environment_slash_command",
|
||||
"code_review_find",
|
||||
"shared_session_long_running_commands",
|
||||
"mcp_grouped_server_context",
|
||||
"fork_from_command",
|
||||
"context_window_usage_v2",
|
||||
"ambient_agents_command_line",
|
||||
"ambient_agents_image_upload",
|
||||
"scheduled_ambient_agents",
|
||||
"warp_managed_secrets",
|
||||
"v4a_file_diffs",
|
||||
"classic_completions",
|
||||
"force_classic_completions",
|
||||
"team_api_keys",
|
||||
"agent_tips",
|
||||
"pluggable_notifications",
|
||||
"agent_onboarding",
|
||||
"global_search",
|
||||
"cloud_conversations",
|
||||
"list_skills",
|
||||
"ask_user_question",
|
||||
"bundled_skills",
|
||||
"ambient_agents_rtc",
|
||||
"cloud_mode",
|
||||
"cloud_mode_from_local_session",
|
||||
"cloud_mode_image_context",
|
||||
"agent_mode_computer_use",
|
||||
"oz_platform_skills",
|
||||
"sync_ambient_plans",
|
||||
"conversation_artifacts",
|
||||
"agent_view",
|
||||
"agent_view_block_context",
|
||||
"agent_view_conversation_list_view",
|
||||
"inline_slash_commands",
|
||||
"inline_history_menu",
|
||||
"inline_model_selector",
|
||||
"oz_launch_modal",
|
||||
"open_warp_launch_modal",
|
||||
"new_tab_styling",
|
||||
"richtext_multiselect",
|
||||
"inline_profile_selector",
|
||||
"web_fetch_ui",
|
||||
"oz_changelog_updates",
|
||||
"skill_arguments",
|
||||
"incremental_auto_reload",
|
||||
"active_conversation_requires_interaction",
|
||||
"figma_detection",
|
||||
"file_based_mcp",
|
||||
"inline_repo_menu",
|
||||
"kitty_keyboard_protocol",
|
||||
"inline_menu_headers",
|
||||
"github_pr_prompt_chip",
|
||||
"conversations_as_context",
|
||||
"markdown_tables",
|
||||
"markdown_mermaid",
|
||||
"blocklist_markdown_images",
|
||||
"pr_comments_slash_command",
|
||||
"pr_comments_v2",
|
||||
"pr_comments_skill",
|
||||
"revert_to_checkpoints",
|
||||
"rewind_slash_command",
|
||||
"hoa_code_review",
|
||||
"warpify_footer",
|
||||
"agent_toolbar_editor",
|
||||
"configurable_toolbar",
|
||||
"transfer_control_tool",
|
||||
"hoa_notifications",
|
||||
"open_code_notifications",
|
||||
"cli_agent_rich_input",
|
||||
"vertical_tabs",
|
||||
"tab_configs",
|
||||
"hoa_onboarding_flow",
|
||||
"hoa_remote_control",
|
||||
"codex_notifications",
|
||||
"trim_trailing_blank_lines",
|
||||
"open_warp_new_settings_modes",
|
||||
"skip_firebase_anonymous_user",
|
||||
"settings_file",
|
||||
]
|
||||
# Enable this feature to automatically perform heap profiling. NOTE: This will
|
||||
# substantially slow down program execution.
|
||||
dhat_heap_profiling = ["dep:dhat"]
|
||||
dynamic_workflow_enums = []
|
||||
editable_markdown_mermaid = []
|
||||
default_adeberry_theme = []
|
||||
drag_tabs_to_windows = []
|
||||
embedded_code_review_comments = []
|
||||
agent_management_view = []
|
||||
agent_management_details_view = []
|
||||
interactive_conversation_management_view = []
|
||||
default_waterfall_mode = []
|
||||
enforce_revisions_to_cloud_objects = []
|
||||
suggested_agent_mode_workflows = []
|
||||
ssh_tmux_wrapper = []
|
||||
ssh_enable_host_denylist_in_settings = []
|
||||
extern_plist = []
|
||||
fast_dev = ["skip_login"]
|
||||
full_screen_zen_mode = []
|
||||
global_ai_analytics_banner = []
|
||||
global_ai_analytics_collection = []
|
||||
grab_the_baton_editing = []
|
||||
grep_tool = []
|
||||
# This feature is enabled in graphical builds of Warp, and groups together other features
|
||||
# that are not needed in headless builds. Because Cargo features are additive, the default
|
||||
# feature set is for a minimal build of Warp, and we add on GUI-specific features here.
|
||||
# For the most part, including GUI code in headless builds is fine; the main use case is
|
||||
# for things that pull in external dependencies.
|
||||
gui = ["voice_input"]
|
||||
msys2_shells = []
|
||||
file_retrieval_tools = []
|
||||
welcome_tab = []
|
||||
get_started_tab = []
|
||||
code_mode_chip = []
|
||||
github_pr_prompt_chip = []
|
||||
create_project_flow = []
|
||||
agent_mode_evals = [
|
||||
"integration_tests",
|
||||
"full_source_code_embedding",
|
||||
"cross_repo_context",
|
||||
"rust-embed/debug-embed",
|
||||
"warpui/log_named_telemetry_events",
|
||||
"warp_logging/agent_mode_evals",
|
||||
]
|
||||
ambient_agents_command_line = []
|
||||
ambient_agents_image_upload = []
|
||||
scheduled_ambient_agents = []
|
||||
allow_ignoring_input_suggestions = []
|
||||
inline_slash_commands = ["agent_view"]
|
||||
|
||||
# Enable this feature to track heap usage and automatically produce a heap
|
||||
# profile report when app memory usage exceeds a 10GB threshold.
|
||||
#
|
||||
# Enabled on WarpDev by default.
|
||||
heap_usage_tracking = ["jemalloc_pprof", "crash_reporting"]
|
||||
image_as_context = []
|
||||
in_band_generators_ssh = []
|
||||
jemalloc = ["dep:tikv-jemallocator", "ai/jemalloc"]
|
||||
jemalloc_with_profiling = ["jemalloc", "tikv-jemallocator/profiling"]
|
||||
jemalloc_auto_heap_profiling = ["jemalloc_with_profiling"]
|
||||
jemalloc_pprof = ["jemalloc_with_profiling", "dep:jemalloc_pprof"]
|
||||
run_generators_with_cmd_exe = []
|
||||
inline_ssh_banner = []
|
||||
kitty_images = []
|
||||
kitty_keyboard_protocol = []
|
||||
ligatures = []
|
||||
trim_trailing_blank_lines = []
|
||||
cli_agent_rich_input = []
|
||||
list_skills = []
|
||||
# This feature is enabled in build.rs when compiling for platforms which
|
||||
# support having a local tty/shell session. It can be used to conditionally
|
||||
# include dependencies that should only exist in such environments.
|
||||
local_tty = []
|
||||
local_computer_use = []
|
||||
# This feature is enabled in build.rs when compiling for platforms which
|
||||
# have APIs for interacting with a local filesystem. It can be used to
|
||||
# conditionally include dependencies that should only exist in such
|
||||
# environments.
|
||||
local_fs = [
|
||||
"ai/local_fs",
|
||||
"lsp/local_fs",
|
||||
"persistence/local_fs",
|
||||
"repo_metadata/local_fs",
|
||||
"warp_core/local_fs",
|
||||
]
|
||||
log_expensive_frames_in_sentry = []
|
||||
markdown_tables = []
|
||||
markdown_mermaid = []
|
||||
mcp_server = []
|
||||
mcp_oauth = []
|
||||
mcp_debugging_ids = []
|
||||
notebook_parameter = []
|
||||
oz_changelog_updates = []
|
||||
personal_cloud_objects = []
|
||||
# Remote-backed tty that connects to a PTY-like interface via a server.
|
||||
remote_tty = []
|
||||
# Fix for cursor reflow bug during window resize, from Alacritty resizing logic.
|
||||
resize_fix = []
|
||||
pluggable_notifications = []
|
||||
# This enables `read_files` to support images.
|
||||
read_image_files = []
|
||||
# This feature enables plugin support in Warp. Note that its typically checked
|
||||
# directly, rather than via the `FeatureFlag` enum, because its value is
|
||||
# required early in the app lifecycle prior to `FeatureFlag` initialization.
|
||||
plugin_host = ["dep:rquickjs", "dep:warp_js", "warp_cli/plugin_host"]
|
||||
# Enable this feature to automatically perform CPU profiling via pprof. The
|
||||
# generated profile will be written to profile.pb in the current directory.
|
||||
# NOTE: This may slow down program execution.
|
||||
pprof_cpu_profiling = ["dep:pprof"]
|
||||
predict_am_queries = []
|
||||
quake_mode = []
|
||||
record_app_active_events = []
|
||||
recording_mode = []
|
||||
# This feature should only be enabled when building a release bundle with
|
||||
# the bundle script, and can be used to conditionally enable functionality
|
||||
# accordingly.
|
||||
release_bundle = ["rust-embed/debug-embed", "warp_core/release_bundle"]
|
||||
render_agent_mode_output_markdown = []
|
||||
render_continuous_block_selections_with_single_border = []
|
||||
rich_history = []
|
||||
richtext_multiselect = []
|
||||
runtime_feature_flags = []
|
||||
selectable_prompt = []
|
||||
settings_file = []
|
||||
settings_import = []
|
||||
sequential_storage = []
|
||||
session_sharing = []
|
||||
session_sharing_acls = []
|
||||
skip_login = []
|
||||
# This feature should only be enabled when building a self-contained binary with the bundle script.
|
||||
standalone = []
|
||||
prompt_suggestions_via_maa = []
|
||||
voice_input = ["dep:voice_input"]
|
||||
system_theme = []
|
||||
tab_close_button_on_left = []
|
||||
team_features_override = []
|
||||
team_workflows = ["team_features_override"]
|
||||
toggle_bootstrap_block = []
|
||||
# Feature enabled only when app is compiled for integration tests.
|
||||
integration_tests = [
|
||||
"warp_cli/integration_tests",
|
||||
"warpui/integration_tests",
|
||||
"warpui/test-util",
|
||||
"warp_core/integration_tests",
|
||||
]
|
||||
traces = []
|
||||
viewing_shared_sessions = []
|
||||
workflow_aliases = []
|
||||
rect_selection = []
|
||||
alacritty_settings_import = []
|
||||
shared_with_me = []
|
||||
ai_rules = []
|
||||
am_workflows = []
|
||||
less_horizontal_terminal_padding = []
|
||||
shell_selector = []
|
||||
shared_session_long_running_commands = []
|
||||
block_toolbelt_save_as_workflow = []
|
||||
blocklist_markdown_table_rendering = []
|
||||
blocklist_markdown_images = []
|
||||
minimalist_ui = []
|
||||
remove_alt_screen_padding = []
|
||||
loginless_conversion = []
|
||||
external_agent_mode_context = []
|
||||
avatar_in_tab_bar = []
|
||||
ssh_drag_and_drop = []
|
||||
permanent_autosuggestion_hint = []
|
||||
cycle_next_command_suggestion = []
|
||||
multi_workspace = []
|
||||
ime_marked_text = []
|
||||
partial_next_command_suggestions = []
|
||||
drive_objects_as_context = []
|
||||
iterm_images = []
|
||||
validate_autosuggestions = []
|
||||
autoupdate_ui_revamp = []
|
||||
warp_packs = []
|
||||
suggested_rules = []
|
||||
command_correction_key = []
|
||||
full_source_code_embedding = []
|
||||
use_tantivy_search = []
|
||||
agent_management_popup = []
|
||||
simulate_github_unauthed = []
|
||||
reload_stale_conversation_files = []
|
||||
nld_fasttext_model = ["input_classifier/fasttext"]
|
||||
nld_onnx_model = ["input_classifier/onnx_candle"]
|
||||
shared_block_title_generation = []
|
||||
retry_truncated_code_responses = []
|
||||
usage_based_pricing = []
|
||||
ai_context_menu = []
|
||||
at_menu_outside_of_ai_mode = []
|
||||
agent_decides_command_execution = []
|
||||
fast_forward_autoexecute_button = []
|
||||
code_find_replace = []
|
||||
command_palette_file_search = []
|
||||
conversation_filter = []
|
||||
ai_context_menu_commands = []
|
||||
preview_channel = []
|
||||
ai_context_menu_code = []
|
||||
expand_edit_to_pane = []
|
||||
fallback_model_load_output_messaging = []
|
||||
profiles_design_revamp = []
|
||||
search_codebase_ui = []
|
||||
changed_lines_only_apply_diff_result = []
|
||||
linked_code_blocks = []
|
||||
tabbed_editor_view = []
|
||||
selection_as_context = []
|
||||
send_telemetry_to_file = []
|
||||
multi_profile = []
|
||||
pr_comments_slash_command = []
|
||||
pr_comments_v2 = []
|
||||
pr_comments_skill = []
|
||||
conversation_artifacts = []
|
||||
conversations_as_context = []
|
||||
sync_ambient_plans = []
|
||||
projects = []
|
||||
vim_code_editor = []
|
||||
allow_opening_file_links_using_editor_env = []
|
||||
nld_improvements = ["nld_onnx_model"]
|
||||
undo_closed_panes = []
|
||||
revert_diff_hunk = []
|
||||
code_review_save_changes = []
|
||||
file_tree = []
|
||||
code_launch_modal = []
|
||||
api_key_authentication = []
|
||||
api_key_management = []
|
||||
diff_set_as_context = []
|
||||
discard_per_file_and_all_changes = []
|
||||
ui_zoom = []
|
||||
summarization_cancellation_confirmation = []
|
||||
code_review_find = []
|
||||
auto_open_code_review_pane = []
|
||||
inline_code_review = []
|
||||
integration_command = []
|
||||
artifact_command = []
|
||||
cloud_environments = []
|
||||
create_environment_slash_command = []
|
||||
summarize_conversation_command = []
|
||||
mcp_grouped_server_context = []
|
||||
web_search_ui = []
|
||||
web_fetch_ui = []
|
||||
fork_from_command = []
|
||||
context_window_usage_v2 = []
|
||||
global_search = []
|
||||
file_and_diff_set_comments = []
|
||||
revert_to_checkpoints = []
|
||||
rewind_slash_command = []
|
||||
agent_view = []
|
||||
agent_view_block_context = ["agent_view"]
|
||||
warp_managed_secrets = []
|
||||
v4a_file_diffs = []
|
||||
agent_tips = []
|
||||
agent_toolbar_editor = ["agent_view"]
|
||||
cloud_conversations = []
|
||||
agent_view_prompt_chip = ["agent_view"]
|
||||
ambient_agents_rtc = []
|
||||
team_api_keys = []
|
||||
classic_completions = []
|
||||
cloud_mode = []
|
||||
cloud_mode_from_local_session = []
|
||||
cloud_mode_image_context = []
|
||||
force_classic_completions = []
|
||||
agent_view_conversation_list_view = ["agent_view"]
|
||||
inline_history_menu = ["agent_view"]
|
||||
inline_repo_menu = ["agent_view"]
|
||||
summarization_via_message_replacement = []
|
||||
lsp_as_a_tool = []
|
||||
inline_model_selector = ["agent_view"]
|
||||
inline_profile_selector = ["agent_view"]
|
||||
oz_platform_skills = []
|
||||
oz_identity_federation = []
|
||||
oz_launch_modal = []
|
||||
open_warp_launch_modal = []
|
||||
new_tab_styling = []
|
||||
file_based_mcp = []
|
||||
skill_arguments = []
|
||||
active_conversation_requires_interaction = []
|
||||
incremental_auto_reload = []
|
||||
orchestration = []
|
||||
orchestration_v2 = ["orchestration"]
|
||||
orchestration_event_push = ["orchestration_v2"]
|
||||
pending_user_query_indicator = []
|
||||
queue_slash_command = []
|
||||
inline_menu_headers = []
|
||||
directory_tab_colors = []
|
||||
open_warp_new_settings_modes = []
|
||||
hoa_code_review = []
|
||||
vertical_tabs = []
|
||||
vertical_tabs_summary_mode = []
|
||||
tab_configs = []
|
||||
agent_harness = []
|
||||
oz_handoff = []
|
||||
hoa_notifications = []
|
||||
open_code_notifications = []
|
||||
transfer_control_tool = []
|
||||
skip_firebase_anonymous_user = []
|
||||
solo_user_byok = []
|
||||
configurable_toolbar = []
|
||||
warpify_footer = []
|
||||
hoa_onboarding_flow = []
|
||||
git_operations_in_code_review = []
|
||||
hoa_remote_control = []
|
||||
codex_notifications = []
|
||||
cloud_mode_setup_v2 = ["cloud_mode"]
|
||||
cloud_mode_input_v2 = ["cloud_mode"]
|
||||
|
||||
[package.metadata.bundle.bin.warp-oss]
|
||||
category = "public.app-category.developer-tools"
|
||||
copyright = "© 2025, Denver Technologies, Inc"
|
||||
identifier = "dev.warp.WarpOss"
|
||||
name = "WarpOss"
|
||||
resources = ["assets/onboarding"]
|
||||
icon = ["channels/oss/icon/no-padding/512x512.png", "channels/oss/icon/no-padding/icon.ico"]
|
||||
short_description = "The open-source, cloud-backed terminal for individuals and teams."
|
||||
|
||||
[package.metadata.bundle.bin.stable]
|
||||
category = "public.app-category.developer-tools"
|
||||
copyright = "© 2025, Denver Technologies, Inc"
|
||||
identifier = "dev.warp.Warp-Stable"
|
||||
name = "Warp"
|
||||
osx_frameworks = [
|
||||
"frameworks/default/Sentry-Dynamic-WithARM64e.xcframework/macos-arm64_arm64e_x86_64/Sentry.framework",
|
||||
]
|
||||
resources = ["assets/onboarding"]
|
||||
short_description = "The cloud-backed terminal for individuals and teams, stable build."
|
||||
|
||||
[package.metadata.bundle.bin.preview]
|
||||
category = "public.app-category.developer-tools"
|
||||
copyright = "© 2025, Denver Technologies, Inc"
|
||||
identifier = "dev.warp.Warp-Preview"
|
||||
name = "WarpPreview"
|
||||
osx_frameworks = [
|
||||
"frameworks/default/Sentry-Dynamic-WithARM64e.xcframework/macos-arm64_arm64e_x86_64/Sentry.framework",
|
||||
]
|
||||
resources = ["assets/onboarding"]
|
||||
short_description = "The cloud-backed terminal for individuals and teams, feature preview build."
|
||||
|
||||
[package.metadata.bundle.bin.dev]
|
||||
category = "public.app-category.developer-tools"
|
||||
copyright = "© 2025, Denver Technologies, Inc"
|
||||
identifier = "dev.warp.Warp-Dev"
|
||||
name = "WarpDev"
|
||||
osx_frameworks = [
|
||||
"frameworks/dev/Sentry-Dynamic-WithARM64e.xcframework/macos-arm64_arm64e_x86_64/Sentry.framework",
|
||||
]
|
||||
resources = ["assets/onboarding"]
|
||||
short_description = "The cloud-backed terminal for individuals and teams, developer build."
|
||||
|
||||
[package.metadata.bundle.bin.warp]
|
||||
category = "public.app-category.developer-tools"
|
||||
copyright = "© 2025, Denver Technologies, Inc"
|
||||
identifier = "dev.warp.Warp-Local"
|
||||
name = "WarpLocal"
|
||||
resources = ["assets/onboarding"]
|
||||
short_description = "The cloud-backed terminal for individuals and teams, developer build."
|
||||
|
||||
[package.metadata.cargo-udeps.ignore]
|
||||
normal = ["embed_plist"]
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>dev.warp.WarpDockTilePlugin</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>WarpDockTilePlugin</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>WarpDockTilePlugin</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>WarpDockTilePlugin</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,20 @@
|
||||
BUNDLE_NAME = WarpDockTilePlugin.docktileplugin
|
||||
OBJC_FILES = WarpDockTilePlugin.m
|
||||
FRAMEWORKS = -framework Cocoa -framework AppKit -framework Foundation
|
||||
# Compile a universal binary for both arm64 and x86_64.
|
||||
CFLAGS = -fobjc-arc -bundle -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) -arch arm64 -arch x86_64
|
||||
LDFLAGS = -ObjC
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(BUNDLE_NAME)
|
||||
|
||||
$(BUNDLE_NAME): $(OBJC_FILES)
|
||||
mkdir -p $(BUNDLE_NAME)/Contents/MacOS
|
||||
clang $(CFLAGS) $(LDFLAGS) $(FRAMEWORKS) $(OBJC_FILES) -o $(BUNDLE_NAME)/Contents/MacOS/WarpDockTilePlugin
|
||||
cp Info.plist $(BUNDLE_NAME)/Contents/
|
||||
mkdir -p $(BUNDLE_NAME)/Contents/Resources
|
||||
cp Resources/* $(BUNDLE_NAME)/Contents/Resources/
|
||||
|
||||
clean:
|
||||
rm -rf $(BUNDLE_NAME)
|
||||
@@ -0,0 +1,23 @@
|
||||
Implements a dock tile plugin for Warp.
|
||||
|
||||
The plugin is used to update the dock tile icon when the app icon changes and allows for app icon changes to be persisted across app restarts. Without the plugin, the icon state reverts to the default upon the first time the app quits (although for some reason after the first quit the icon state is preserved).
|
||||
|
||||
The plugin is implemented in Objective-C and is built using the `clang` compiler
|
||||
with the `-bundle` flag. See the Makefile for more details.
|
||||
|
||||
The plugin is installed into the app bundle at `Contents/PlugIns/WarpDockTilePlugin.docktileplugin` and is bundled using the script/mac/bundle script. It is built as a universal binary for both arm64 and x86_64.
|
||||
|
||||
The plugin is a simple Objective-C program that listens for notifications from the mainapplication when the app icon changes. When it receives a notification, it updates the dock tile icon.
|
||||
|
||||
See Mac documentation for more details:
|
||||
https://developer.apple.com/documentation/appkit/nsdocktileplugin?language=objc
|
||||
|
||||
Note, that during development, MacOS is not great about reloading the plugin when changes are made.
|
||||
|
||||
The suggested workflow after rebuilding is to
|
||||
1. Remove the icon from the dock.
|
||||
2. Run `killall Dock && killall SystemUIServer`
|
||||
|
||||
Also, there is a sample plugin at [MacDockTileSample](https://github.com/CartBlanche/MacDockTileSample) that is helpful for installing and iterating on.
|
||||
|
||||
Another tip is to add file based debug logs rather than using NSLog, as it's impossible to find where NSLogs are being written to.
|
||||
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 282 KiB |
|
After Width: | Height: | Size: 616 KiB |
|
After Width: | Height: | Size: 326 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 147 KiB |
|
After Width: | Height: | Size: 430 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 583 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 626 KiB |
@@ -0,0 +1,12 @@
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface WarpDockTilePlugIn : NSObject <NSDockTilePlugIn>
|
||||
{
|
||||
id iconChangedObserver;
|
||||
id defaultsObserver;
|
||||
}
|
||||
|
||||
@property(strong) id iconChangedObserver;
|
||||
@property(strong) id defaultsObserver;
|
||||
@end
|
||||
@@ -0,0 +1,228 @@
|
||||
#include "WarpDockTilePlugin.h"
|
||||
|
||||
@implementation WarpDockTilePlugIn {
|
||||
NSFileHandle *_logFileHandle;
|
||||
}
|
||||
|
||||
@synthesize iconChangedObserver;
|
||||
@synthesize defaultsObserver;
|
||||
|
||||
- (void)logMessage:(NSString *)message {
|
||||
if (_logFileHandle) {
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss.SSS"];
|
||||
NSString *timestamp = [formatter stringFromDate:[NSDate date]];
|
||||
NSString *logEntry = [NSString stringWithFormat:@"[%@] %@\n", timestamp, message];
|
||||
[_logFileHandle writeData:[logEntry dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[_logFileHandle synchronizeFile];
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
@try {
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
[formatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"];
|
||||
NSString *timestamp = [formatter stringFromDate:[NSDate date]];
|
||||
NSString *logPath = [NSString stringWithFormat:@"/tmp/warp_docktile_%@.log", timestamp];
|
||||
NSError *error = nil;
|
||||
[[NSFileManager defaultManager] createFileAtPath:logPath contents:nil attributes:nil];
|
||||
_logFileHandle = [NSFileHandle fileHandleForWritingAtPath:logPath];
|
||||
[self logMessage:@"WarpDockTilePlugin initialized"];
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Exception during initialization: %@\nStack trace: %@",
|
||||
exception.reason,
|
||||
exception.callStackSymbols);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateAppIcon:(NSDockTile *)tile {
|
||||
@try {
|
||||
[self logMessage:@"updateAppIcon called"];
|
||||
// Retrieve the bundle ID for the main app from the Info.plist file in the plugin bundle
|
||||
NSBundle *pluginBundle = [NSBundle bundleForClass:[self class]];
|
||||
NSString *path = [[pluginBundle bundlePath] stringByAppendingPathComponent:@"Contents/Info.plist"];
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
|
||||
NSString *bundleId = dict[@"MainAppBundleIdentifier"];
|
||||
BOOL isDev = [bundleId containsString:@"Dev"];
|
||||
BOOL isPreview = [bundleId containsString:@"Preview"];
|
||||
BOOL isLocal = [bundleId containsString:@"Local"];
|
||||
[self logMessage:[NSString stringWithFormat:@"Plugin Bundle ID: %@", bundleId]];
|
||||
|
||||
// Initialize the user defaults for the main app
|
||||
NSUserDefaults *hostDefaults = [[NSUserDefaults alloc] initWithSuiteName:bundleId];
|
||||
[hostDefaults synchronize];
|
||||
|
||||
// Get the icon name from the user defaults
|
||||
NSString* appIconName = [hostDefaults stringForKey:@"AppIcon"];
|
||||
|
||||
// Check if the user has set a non-default icon. If the AppIcon key is nil, empty, or "Default", reset to the
|
||||
// icon bundled with the app by setting the content to "nil". Using the icon bundled in the app will allow macOS
|
||||
// to handle the icon, including respecting "Icon & Widget Style" setting and applying a color filter. Non-
|
||||
// default icons do not respect that setting.
|
||||
NSString* cleanName = [[appIconName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]] lowercaseString];
|
||||
if (!appIconName || [appIconName length] == 0 || [cleanName isEqualToString:@"default"]) {
|
||||
[self logMessage:@"User has default icon, resetting dock tile to system default"];
|
||||
[tile setContentView:nil];
|
||||
[tile display];
|
||||
return;
|
||||
}
|
||||
|
||||
NSString* iconFileName = [self convertAppIconNameToFileName:appIconName isDev:isDev isLocal:isLocal isPreview:isPreview];
|
||||
[self logMessage:[NSString stringWithFormat:@"Icon file name: %@", iconFileName]];
|
||||
|
||||
// Load the icon image
|
||||
NSImage* currentImage = [self LoadDockTileImage:iconFileName];
|
||||
|
||||
// Set the image on the dock tile
|
||||
// 256 x 256 is the preferred size for retina dock icons.
|
||||
NSImageView* imageView = [[NSImageView alloc] initWithFrame:NSMakeRect(0, 0, 256, 256)];
|
||||
[imageView setImage:currentImage];
|
||||
[imageView setImageScaling:NSImageScaleProportionallyUpOrDown];
|
||||
[tile setContentView:imageView];
|
||||
[tile display];
|
||||
|
||||
[self logMessage:[NSString stringWithFormat:@"Dock tile updated with icon: %@", iconFileName]];
|
||||
} @catch (NSException *exception) {
|
||||
[self logMessage:[NSString stringWithFormat:@"Exception updating dock tile icon: %@\nStack trace: %@\nTile: %@",
|
||||
exception.reason,
|
||||
exception.callStackSymbols,
|
||||
tile ? @"valid" : @"nil"]];
|
||||
}
|
||||
}
|
||||
|
||||
// See app_icon.rs for the rust version of this conversion.
|
||||
- (NSString*)convertAppIconNameToFileName:(NSString*)appIconName isDev:(BOOL)isDev isLocal:(BOOL)isLocal isPreview:(BOOL)isPreview {
|
||||
// First remove quotes and convert to lowercase
|
||||
NSString* cleanName = [[appIconName stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]] lowercaseString];
|
||||
|
||||
NSDictionary* mapping = @{
|
||||
@"aurora": @"aurora",
|
||||
@"classic1": @"classic_1",
|
||||
@"classic2": @"classic_2",
|
||||
@"classic3": @"classic_3",
|
||||
@"comets": @"comets",
|
||||
@"glasssky": @"glass_sky",
|
||||
@"glitch": @"glitch",
|
||||
@"glow": @"glow",
|
||||
@"holographic": @"holographic",
|
||||
@"mono": @"mono",
|
||||
@"neon": @"neon",
|
||||
@"original": @"original",
|
||||
@"starburst": @"starburst",
|
||||
@"sticker": @"sticker",
|
||||
@"warpone": @"blue",
|
||||
@"cow": @"cow"
|
||||
};
|
||||
|
||||
NSString* fileName = mapping[cleanName];
|
||||
|
||||
// If the mapping doesn't exist, return the default icon
|
||||
// conditional on whether this is a local, dev, or preview build.
|
||||
return fileName ?: isLocal ? @"local" : isDev ? @"dev" : isPreview ? @"preview" : @"warp_2";
|
||||
}
|
||||
|
||||
// Helper function to load named image from the plugin's resource bundle
|
||||
- (NSImage*)LoadDockTileImage:(NSString*)imageName {
|
||||
NSBundle* pluginBundle = [NSBundle bundleForClass:[self class]];
|
||||
NSString* imagePath = [pluginBundle pathForResource:imageName ofType:@"png"];
|
||||
[self logMessage:[NSString stringWithFormat:@"Image path: %@", imagePath]];
|
||||
if (imagePath == nil) {
|
||||
[self logMessage:[NSString stringWithFormat:@"Could not find image named %@ in the plugin resources", imageName]];
|
||||
return nil;
|
||||
}
|
||||
return [[NSImage alloc] initWithContentsOfFile:imagePath];
|
||||
}
|
||||
|
||||
// Protocol method that is invoked by the system when the dock for Warp is updated.
|
||||
// Note that we listen for direct changes to the AppIcon key in the user defaults.
|
||||
- (void)setDockTile:(NSDockTile *)dockTile {
|
||||
@try {
|
||||
[self logMessage:[NSString stringWithFormat:@"setDockTile called with tile: %@", dockTile ? @"valid" : @"nil"]];
|
||||
if (dockTile) {
|
||||
// Get the bundle ID for setting up user defaults observation
|
||||
NSBundle *pluginBundle = [NSBundle bundleForClass:[WarpDockTilePlugIn class]];
|
||||
NSString *path = [[pluginBundle bundlePath] stringByAppendingPathComponent:@"Contents/Info.plist"];
|
||||
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
|
||||
NSString *bundleId = dict[@"MainAppBundleIdentifier"];
|
||||
|
||||
[self logMessage:[NSString stringWithFormat:@"Main app bundleId: %@", bundleId]];
|
||||
|
||||
// Set up user defaults observer
|
||||
NSUserDefaults *hostDefaults = [[NSUserDefaults alloc] initWithSuiteName:bundleId];
|
||||
[hostDefaults addObserver:self
|
||||
forKeyPath:@"AppIcon"
|
||||
options:NSKeyValueObservingOptionNew
|
||||
context:(__bridge void * _Nullable)(dockTile)];
|
||||
self.defaultsObserver = hostDefaults;
|
||||
|
||||
[self logMessage:[NSString stringWithFormat:@"Host defaults: %@", hostDefaults]];
|
||||
|
||||
// Make sure the icon is updated from the get-go as well.
|
||||
[self updateAppIcon:dockTile];
|
||||
} else {
|
||||
[self logMessage:@"No docktile, clearing icon observer"];
|
||||
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self.iconChangedObserver];
|
||||
self.iconChangedObserver = nil;
|
||||
if (self.defaultsObserver) {
|
||||
[(NSUserDefaults *)self.defaultsObserver removeObserver:self forKeyPath:@"AppIcon"];
|
||||
self.defaultsObserver = nil;
|
||||
}
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
[self logMessage:[NSString stringWithFormat:@"Exception in setDockTile: %@\nStack trace: %@\nDockTile: %@",
|
||||
exception.reason,
|
||||
exception.callStackSymbols,
|
||||
dockTile ? @"valid" : @"nil"]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
@try {
|
||||
[self logMessage:@"WarpDockTilePlugin deallocating"];
|
||||
if (self.iconChangedObserver) {
|
||||
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self.iconChangedObserver];
|
||||
self.iconChangedObserver = nil;
|
||||
}
|
||||
if (self.defaultsObserver) {
|
||||
[(NSUserDefaults *)self.defaultsObserver removeObserver:self forKeyPath:@"AppIcon"];
|
||||
self.defaultsObserver = nil;
|
||||
}
|
||||
|
||||
if (_logFileHandle) {
|
||||
[self logMessage:@"Closing log file"];
|
||||
[_logFileHandle closeFile];
|
||||
_logFileHandle = nil;
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
NSLog(@"Exception during deallocation: %@\nStack trace: %@",
|
||||
exception.reason,
|
||||
exception.callStackSymbols);
|
||||
}
|
||||
}
|
||||
|
||||
// KVO callback method
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary<NSKeyValueChangeKey,id> *)change
|
||||
context:(void *)context {
|
||||
@try {
|
||||
if ([keyPath isEqualToString:@"AppIcon"]) {
|
||||
[self logMessage:@"AppIcon value changed in user defaults"];
|
||||
NSDockTile *dockTile = (__bridge NSDockTile *)context;
|
||||
[self updateAppIcon:dockTile];
|
||||
}
|
||||
} @catch (NSException *exception) {
|
||||
[self logMessage:[NSString stringWithFormat:@"Exception in KVO handler: %@\nStack trace: %@\nKeyPath: %@\nObject: %@\nChange: %@",
|
||||
exception.reason,
|
||||
exception.callStackSymbols,
|
||||
keyPath,
|
||||
object,
|
||||
change]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
After Width: | Height: | Size: 793 KiB |
|
After Width: | Height: | Size: 830 KiB |
|
After Width: | Height: | Size: 671 KiB |
|
After Width: | Height: | Size: 716 KiB |
|
After Width: | Height: | Size: 529 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 433 KiB |
|
After Width: | Height: | Size: 422 KiB |
|
After Width: | Height: | Size: 467 KiB |
|
After Width: | Height: | Size: 982 KiB |
|
After Width: | Height: | Size: 723 KiB |
|
After Width: | Height: | Size: 792 KiB |
|
After Width: | Height: | Size: 686 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 321 KiB |
|
After Width: | Height: | Size: 382 KiB |
|
After Width: | Height: | Size: 494 KiB |
|
After Width: | Height: | Size: 299 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 644 KiB |
|
After Width: | Height: | Size: 475 KiB |
|
After Width: | Height: | Size: 272 KiB |
|
After Width: | Height: | Size: 987 KiB |
|
After Width: | Height: | Size: 532 KiB |
|
After Width: | Height: | Size: 777 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 896 KiB |
|
After Width: | Height: | Size: 895 KiB |
|
After Width: | Height: | Size: 968 KiB |
|
After Width: | Height: | Size: 959 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
After Width: | Height: | Size: 590 KiB |
|
After Width: | Height: | Size: 648 KiB |
|
After Width: | Height: | Size: 539 KiB |
|
After Width: | Height: | Size: 584 KiB |
|
After Width: | Height: | Size: 523 KiB |
|
After Width: | Height: | Size: 583 KiB |
|
After Width: | Height: | Size: 612 KiB |
|
After Width: | Height: | Size: 692 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 1.8 MiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 762 KiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 822 KiB |
|
After Width: | Height: | Size: 886 KiB |
|
After Width: | Height: | Size: 943 KiB |
|
After Width: | Height: | Size: 1024 KiB |
|
After Width: | Height: | Size: 590 KiB |
|
After Width: | Height: | Size: 663 KiB |
|
After Width: | Height: | Size: 760 KiB |
|
After Width: | Height: | Size: 827 KiB |
|
After Width: | Height: | Size: 194 KiB |
|
After Width: | Height: | Size: 254 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 226 KiB |
|
After Width: | Height: | Size: 187 KiB |
|
After Width: | Height: | Size: 377 KiB |
|
After Width: | Height: | Size: 504 KiB |
|
After Width: | Height: | Size: 554 KiB |
|
After Width: | Height: | Size: 770 KiB |
|
After Width: | Height: | Size: 871 KiB |
|
After Width: | Height: | Size: 677 KiB |
|
After Width: | Height: | Size: 813 KiB |
|
After Width: | Height: | Size: 724 KiB |
|
After Width: | Height: | Size: 859 KiB |