-
Notifications
You must be signed in to change notification settings - Fork 0
Add workspace-level isolation info #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
515a24f
e52844f
540a376
a698fa8
cfdb811
dc94660
59c3e43
838fc85
3af2955
0855748
d1027ca
8321eb5
d255fe7
b977efd
cdab83f
38674fd
988001e
400dd64
7e96544
10cd2e0
91f925c
fcdb365
6006979
0c49991
0eb68f2
8cd0808
4aea66a
6eac4df
5f1a814
e243d4c
16e2130
42d1cd4
1d22efc
8e86908
cf33e12
ee35041
5bf761c
5bf4092
1d74665
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,7 @@ use tauri::State; | |
| use crate::pty::PtyManager; | ||
| use crate::socket::SocketManager; | ||
| use crate::backend::BackendManager; | ||
| use std::path::Path; | ||
|
|
||
| #[tauri::command] | ||
| pub async fn spawn_pty( | ||
|
|
@@ -108,3 +109,158 @@ pub fn get_backend_port( | |
| .get_port() | ||
| .ok_or_else(|| "Backend port not available yet".to_string()) | ||
| } | ||
|
|
||
| //============================================================================ | ||
| // APP DETECTION COMMANDS | ||
| //============================================================================ | ||
|
|
||
| #[derive(serde::Serialize)] | ||
| pub struct InstalledApp { | ||
| pub id: String, | ||
| pub name: String, | ||
| pub path: String, | ||
| } | ||
|
|
||
| // Shared app definitions (id, display name, app path) | ||
| const APP_DEFINITIONS: &[(&str, &str, &str)] = &[ | ||
| // Code Editors | ||
| ("cursor", "Cursor", "/Applications/Cursor.app"), | ||
| ("vscode", "Visual Studio Code", "/Applications/Visual Studio Code.app"), | ||
| ("windsurf", "Windsurf", "/Applications/Windsurf.app"), | ||
| ("zed", "Zed", "/Applications/Zed.app"), | ||
| ("sublime", "Sublime Text", "/Applications/Sublime Text.app"), | ||
| ("nova", "Nova", "/Applications/Nova.app"), | ||
|
|
||
| // JetBrains IDEs | ||
| ("webstorm", "WebStorm", "/Applications/WebStorm.app"), | ||
| ("intellij", "IntelliJ IDEA", "/Applications/IntelliJ IDEA.app"), | ||
| ("pycharm", "PyCharm", "/Applications/PyCharm.app"), | ||
| ("phpstorm", "PhpStorm", "/Applications/PhpStorm.app"), | ||
| ("rubymine", "RubyMine", "/Applications/RubyMine.app"), | ||
| ("goland", "GoLand", "/Applications/GoLand.app"), | ||
| ("clion", "CLion", "/Applications/CLion.app"), | ||
| ("fleet", "Fleet", "/Applications/Fleet.app"), | ||
| ("rider", "Rider", "/Applications/Rider.app"), | ||
| ("androidstudio", "Android Studio", "/Applications/Android Studio.app"), | ||
|
|
||
| // Apple IDEs | ||
| ("xcode", "Xcode", "/Applications/Xcode.app"), | ||
|
|
||
| // Terminals | ||
| ("terminal", "Terminal", "/System/Applications/Utilities/Terminal.app"), | ||
| ("iterm", "iTerm", "/Applications/iTerm.app"), | ||
| ("warp", "Warp", "/Applications/Warp.app"), | ||
| ]; | ||
|
|
||
| /// Get list of installed development apps on macOS | ||
| #[tauri::command] | ||
| pub fn get_installed_apps() -> Result<Vec<InstalledApp>, String> { | ||
| #[cfg(not(target_os = "macos"))] | ||
| { | ||
| return Ok(Vec::new()); | ||
| } | ||
|
|
||
| #[cfg(target_os = "macos")] | ||
| { | ||
| let mut apps = Vec::new(); | ||
|
|
||
| for (id, name, path) in APP_DEFINITIONS { | ||
| if Path::new(path).exists() { | ||
| apps.push(InstalledApp { | ||
| id: id.to_string(), | ||
| name: name.to_string(), | ||
| path: path.to_string(), | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| Ok(apps) | ||
| } | ||
| } | ||
|
|
||
| /// Open a workspace directory in a specific app | ||
| #[tauri::command] | ||
| pub fn open_in_app(app_id: String, workspace_path: String) -> Result<String, String> { | ||
| #[cfg(not(target_os = "macos"))] | ||
| { | ||
| return Err("This feature is only available on macOS".to_string()); | ||
| } | ||
|
Comment on lines
+181
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add workspace path validation before launching. Reject non-existent or non-directory inputs early to avoid confusing failures. @@
pub fn open_in_app(app_id: String, workspace_path: String) -> Result<String, String> {
@@
{
- // Find the app name from our shared definitions
+ // Validate workspace path
+ if !Path::new(&workspace_path).is_dir() {
+ return Err(format!("Workspace path is not a directory: {}", workspace_path));
+ }
+
+ // Find the app name from our shared definitions
let app_name = APP_DEFINITIONSAlso applies to: 246-253 🤖 Prompt for AI Agents |
||
|
|
||
| #[cfg(target_os = "macos")] | ||
| { | ||
| // Find the app name from our shared definitions | ||
| let app_name = APP_DEFINITIONS | ||
| .iter() | ||
| .find(|(id, _, _)| *id == app_id.as_str()) | ||
| .map(|(_, name, _)| *name) | ||
| .ok_or_else(|| format!("Unknown app: {}", app_id))?; | ||
|
|
||
| // Terminal apps need special handling via AppleScript | ||
| let output = match app_id.as_str() { | ||
| "terminal" => { | ||
| let script = format!( | ||
| r#"tell application "Terminal" | ||
| activate | ||
| do script "cd '{}'" | ||
| end tell"#, | ||
| workspace_path.replace("'", "'\\''") | ||
| ); | ||
| std::process::Command::new("osascript") | ||
| .arg("-e") | ||
| .arg(&script) | ||
| .output() | ||
| .map_err(|e| format!("Failed to open Terminal: {}", e))? | ||
| } | ||
| "iterm" => { | ||
| let script = format!( | ||
| r#"tell application "iTerm" | ||
| activate | ||
| create window with default profile | ||
| tell current session of current window | ||
| write text "cd '{}'" | ||
| end tell | ||
| end tell"#, | ||
| workspace_path.replace("'", "'\\''") | ||
| ); | ||
| std::process::Command::new("osascript") | ||
| .arg("-e") | ||
| .arg(&script) | ||
| .output() | ||
| .map_err(|e| format!("Failed to open iTerm: {}", e))? | ||
| } | ||
|
Comment on lines
+198
to
+230
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: AppleScript string injection/breakage with paths containing double quotes. workspace_path is interpolated inside an AppleScript string (do script "cd '…'"). If the path contains a " character, the AppleScript string terminates, causing failure or code injection. Replace manual quoting with osascript argv + quoted form of POSIX path to avoid crafting shell/AppleScript strings by hand. Apply this diff for Terminal and iTerm: @@
- let output = match app_id.as_str() {
- "terminal" => {
- let script = format!(
- r#"tell application "Terminal"
- activate
- do script "cd '{}'"
- end tell"#,
- workspace_path.replace("'", "'\\''")
- );
- std::process::Command::new("osascript")
- .arg("-e")
- .arg(&script)
- .output()
- .map_err(|e| format!("Failed to open Terminal: {}", e))?
- }
+ let output = match app_id.as_str() {
+ "terminal" => {
+ std::process::Command::new("osascript")
+ .arg("-e")
+ .arg(r#"on run argv
+tell application "Terminal"
+ activate
+ do script "cd " & quoted form of POSIX path of (item 1 of argv)
+end tell
+end run"#)
+ .arg("--")
+ .arg(&workspace_path)
+ .output()
+ .map_err(|e| format!("Failed to open Terminal: {}", e))?
+ }
@@
- "iterm" => {
- let script = format!(
- r#"tell application "iTerm"
- activate
- create window with default profile
- tell current session of current window
- write text "cd '{}'"
- end tell
- end tell"#,
- workspace_path.replace("'", "'\\''")
- );
- std::process::Command::new("osascript")
- .arg("-e")
- .arg(&script)
- .output()
- .map_err(|e| format!("Failed to open iTerm: {}", e))?
- }
+ "iterm" => {
+ std::process::Command::new("osascript")
+ .arg("-e")
+ .arg(r#"on run argv
+tell application "iTerm"
+ activate
+ create window with default profile
+ tell current session of current window
+ write text "cd " & quoted form of POSIX path of (item 1 of argv)
+ end tell
+end tell
+end run"#)
+ .arg("--")
+ .arg(&workspace_path)
+ .output()
+ .map_err(|e| format!("Failed to open iTerm: {}", e))?
+ }🤖 Prompt for AI Agents |
||
| "warp" => { | ||
| let script = format!( | ||
| r#"tell application "Warp" | ||
| activate | ||
| end tell | ||
| do shell script "open -a Warp '{}'"#, | ||
| workspace_path.replace("'", "'\\''") | ||
| ); | ||
| std::process::Command::new("osascript") | ||
| .arg("-e") | ||
| .arg(&script) | ||
| .output() | ||
| .map_err(|e| format!("Failed to open Warp: {}", e))? | ||
| } | ||
|
Comment on lines
+231
to
+244
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainWarp likely won’t cd into the workspace; also still vulnerable to quoting issues. The current Warp branch runs open -a Warp '' via AppleScript. This typically opens Warp but does not set the working directory. Also, quoting is still hand-rolled. At minimum, switch to argv + quoted form: - "warp" => {
- let script = format!(
- r#"tell application "Warp"
- activate
- end tell
- do shell script "open -a Warp '{}'"#,
- workspace_path.replace("'", "'\\''")
- );
- std::process::Command::new("osascript")
- .arg("-e")
- .arg(&script)
- .output()
- .map_err(|e| format!("Failed to open Warp: {}", e))?
- }
+ "warp" => {
+ std::process::Command::new("osascript")
+ .arg("-e")
+ .arg(r#"on run argv
+tell application "Warp" to activate
+do shell script "open -a Warp " & quoted form of POSIX path of (item 1 of argv)
+end run"#)
+ .arg("--")
+ .arg(&workspace_path)
+ .output()
+ .map_err(|e| format!("Failed to open Warp: {}", e))?
+ }Note: This still won’t cd into the directory. If Warp’s AppleScript API allows writing text to the active session, mirror the iTerm approach; otherwise document the limitation or gate Warp until proper cwd support is implemented. I'll verify the concerns in this review comment by examining the codebase and researching the relevant technologies.<!-- [scratchpad_update]
Now let me examine the actual code and check if there's an iTerm handler for comparison:<!-- [scratchpad_update_2]
Now let me check the repository for the actual code and iTerm implementation:<!-- [scratchpad_update_3]
[scratchpad_pending]
Based on my research, I now have sufficient information to verify this review comment. Let me check the actual code in the repository and finalize my assessment: Length of output: 29 🏁 Script executed: #!/bin/bash
# View the exact code at lines 231-244 in commands.rs
sed -n '231,244p' git/src-tauri/src/commands.rsLength of output: 72 🏁 Script executed: #!/bin/bash
# Find the iTerm handler for comparison
rg -n "iterm" git/src-tauri/src/commands.rs -i -A 15 -B 2Length of output: 69 Length of output: 1269 🏁 Script executed: #!/bin/bash
# Use fd with --exec to show the file content directly
fd "commands.rs" --type f --exec cat {} \; | sed -n '231,244p'Length of output: 542 🏁 Script executed: #!/bin/bash
# Search for "iterm" in any commands.rs file found
fd "commands.rs" --type f --exec rg -n "iterm" {} -i -A 15 -B 2 \;Length of output: 2024 Length of output: 48 Improve quoting safety, but note Warp won't set working directory regardless; recommend gating. The current code uses hand-rolled quoting ( The suggested diff improves shell safety but won't cause Warp to cd into the workspace. Given Warp's AppleScript limitations, consider either:
🤖 Prompt for AI Agents |
||
| // IDEs and editors work with standard open command | ||
| _ => { | ||
| std::process::Command::new("open") | ||
| .arg("-a") | ||
| .arg(app_name) | ||
| .arg(&workspace_path) | ||
| .output() | ||
| .map_err(|e| format!("Failed to open app: {}", e))? | ||
| } | ||
| }; | ||
|
|
||
| if !output.status.success() { | ||
| return Err(format!( | ||
| "Failed to open {}: {}", | ||
| app_name, | ||
| String::from_utf8_lossy(&output.stderr) | ||
| )); | ||
| } | ||
|
|
||
| Ok(format!("Opened in {}", app_name)) | ||
| } | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
Uh oh!
There was an error while loading. Please reload this page.