Skip to content

Commit b0eb4ab

Browse files
fix: bundle agent sidecar in app resources, fix path resolution for production builds
1 parent ff4dba9 commit b0eb4ab

2 files changed

Lines changed: 28 additions & 12 deletions

File tree

crates/session/src/claude.rs

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,29 @@ impl ClaudeSession {
104104
permission_mode: Option<&str>,
105105
session_id: Option<&str>,
106106
) -> Result<(Self, mpsc::UnboundedReceiver<AgentEvent>)> {
107-
// Resolve the sidecar script path relative to the executable, not cwd.
108-
// In dev mode the exe is in target/debug/, so we walk up to find the workspace root.
109-
// In production the sidecar would be bundled alongside the binary.
107+
// Resolve the sidecar script path.
108+
// Priority: 1) Bundled in app (production) 2) Dev workspace 3) CARGO_MANIFEST_DIR
110109
let sidecar_path = std::env::current_exe()
111110
.ok()
112111
.and_then(|exe| {
113-
// Walk up from exe path to find workspace root
114-
let mut dir = exe.parent()?;
112+
// Production: bundled as a resource next to the binary
113+
// macOS: App.app/Contents/Resources/agent-sidecar/index.mjs
114+
// Linux/Windows: next to the binary in agent-sidecar/
115+
let exe_dir = exe.parent()?;
116+
117+
// macOS .app bundle: binary is in Contents/MacOS/, resources in Contents/Resources/
118+
let macos_resource = exe_dir.parent()
119+
.map(|contents| contents.join("Resources/agent-sidecar/index.mjs"));
120+
if let Some(ref p) = macos_resource {
121+
if p.exists() { return macos_resource; }
122+
}
123+
124+
// Linux/Windows: resources next to the binary
125+
let beside_exe = exe_dir.join("agent-sidecar/index.mjs");
126+
if beside_exe.exists() { return Some(beside_exe); }
127+
128+
// Dev mode: walk up from target/debug/ to find workspace root
129+
let mut dir = exe_dir;
115130
for _ in 0..10 {
116131
let candidate = dir.join(SIDECAR_SCRIPT);
117132
if candidate.exists() {
@@ -122,15 +137,11 @@ impl ClaudeSession {
122137
None
123138
})
124139
.or_else(|| {
125-
// Fallback: try from CARGO_MANIFEST_DIR (set at compile time).
126-
// This crate is at crates/session/, sidecar is at crates/tauri-app/agent-sidecar/
140+
// Fallback: CARGO_MANIFEST_DIR (compile time)
127141
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
128-
// Go up to workspace root (crates/session -> crates -> root)
129142
let workspace_root = manifest_dir.parent()?.parent()?;
130143
let candidate = workspace_root.join(SIDECAR_SCRIPT);
131-
if candidate.exists() {
132-
return Some(candidate);
133-
}
144+
if candidate.exists() { return Some(candidate); }
134145
None
135146
})
136147
.unwrap_or_else(|| std::path::PathBuf::from(SIDECAR_SCRIPT));

crates/tauri-app/tauri.conf.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@
3232
"active": true,
3333
"targets": "all",
3434
"createUpdaterArtifacts": true,
35-
"icon": ["icons/32x32.png", "icons/icon.png", "icons/icon.ico"]
35+
"icon": ["icons/32x32.png", "icons/icon.png", "icons/icon.ico"],
36+
"resources": [
37+
"agent-sidecar/index.mjs",
38+
"agent-sidecar/node_modules/**/*",
39+
"agent-sidecar/package.json"
40+
]
3641
},
3742
"plugins": {
3843
"updater": {

0 commit comments

Comments
 (0)