diff --git a/.gitea/workflows/build-release.yml b/.gitea/workflows/build-release.yml index 96ab3f0..d28e780 100644 --- a/.gitea/workflows/build-release.yml +++ b/.gitea/workflows/build-release.yml @@ -71,6 +71,15 @@ jobs: Write-Host "=== Build output ===" Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\* + - name: Build and package MCP bridge binary + shell: powershell + run: | + $env:Path = "$env:EXTRA_PATH;$env:Path" + cd src-tauri + cargo build --release --bin wraith-mcp-bridge + Write-Host "Bridge binary built:" + Get-ChildItem target\release\wraith-mcp-bridge.exe + - name: Download jsign shell: powershell run: | @@ -95,7 +104,10 @@ jobs: run: | $env:Path = "$env:EXTRA_PATH;$env:Path" $token = [System.IO.File]::ReadAllText("$env:TEMP\aztoken.txt") - $binaries = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe + # Sign NSIS installers + MCP bridge binary + $binaries = @() + $binaries += Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe + $binaries += Get-Item src-tauri\target\release\wraith-mcp-bridge.exe -ErrorAction SilentlyContinue foreach ($binary in $binaries) { Write-Host "Signing: $($binary.FullName)" java -jar jsign.jar --storetype AZUREKEYVAULT --keystore "${{ secrets.AZURE_KEY_VAULT_URL }}" --storepass $token --alias "${{ secrets.AZURE_CERT_NAME }}" --tsaurl http://timestamp.digicert.com --tsmode RFC3161 $binary.FullName @@ -110,6 +122,13 @@ jobs: $giteaUrl = "https://git.command.vigilcyber.com" $headers = @{ Authorization = "token ${{ secrets.GIT_TOKEN }}" } + # Upload MCP bridge binary + $bridge = "src-tauri\target\release\wraith-mcp-bridge.exe" + if (Test-Path $bridge) { + Write-Host "Uploading: wraith-mcp-bridge.exe" + Invoke-RestMethod -Uri "$giteaUrl/api/packages/vstockwell/generic/wraith/$ver/wraith-mcp-bridge.exe" -Method PUT -Headers $headers -ContentType "application/octet-stream" -InFile $bridge + } + $installers = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe foreach ($file in $installers) { $hash = (Get-FileHash $file.FullName -Algorithm SHA256).Hash.ToLower() @@ -184,10 +203,20 @@ jobs: $releaseId = $release.id Write-Host "Release v$ver created (id: $releaseId)" - $installers = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe $uploadHeaders = @{ Authorization = "token ${{ secrets.GIT_TOKEN }}" } + + # Attach installer(s) + $installers = Get-ChildItem -Recurse src-tauri\target\release\bundle\nsis\*.exe foreach ($file in $installers) { Write-Host "Attaching $($file.Name) to release..." Invoke-RestMethod -Uri "$giteaUrl/api/v1/repos/vstockwell/wraith/releases/$releaseId/assets?name=$($file.Name)" -Method POST -Headers $uploadHeaders -ContentType "application/octet-stream" -InFile $file.FullName Write-Host "Attached: $($file.Name)" } + + # Attach MCP bridge binary + $bridge = "src-tauri\target\release\wraith-mcp-bridge.exe" + if (Test-Path $bridge) { + Write-Host "Attaching wraith-mcp-bridge.exe to release..." + Invoke-RestMethod -Uri "$giteaUrl/api/v1/repos/vstockwell/wraith/releases/$releaseId/assets?name=wraith-mcp-bridge.exe" -Method POST -Headers $uploadHeaders -ContentType "application/octet-stream" -InFile $bridge + Write-Host "Attached: wraith-mcp-bridge.exe" + } diff --git a/.gitignore b/.gitignore index 564d1c1..1ce53e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ dist/ src-tauri/target/ +src-tauri/binaries/ *.log .DS_Store diff --git a/src-tauri/src/pty/mod.rs b/src-tauri/src/pty/mod.rs index 8341b9d..667cd35 100644 --- a/src-tauri/src/pty/mod.rs +++ b/src-tauri/src/pty/mod.rs @@ -96,12 +96,7 @@ impl PtyService { .openpty(PtySize { rows, cols, pixel_width: 0, pixel_height: 0 }) .map_err(|e| format!("Failed to open PTY: {}", e))?; - let mut cmd = CommandBuilder::new(shell_path); - - // Auto-inject MCP server config so AI CLIs discover the bridge. - // Claude Code reads CLAUDE_MCP_SERVERS env var for server config. - let mcp_config = r#"{"wraith":{"command":"wraith-mcp-bridge","args":[]}}"#; - cmd.env("CLAUDE_MCP_SERVERS", mcp_config); + let cmd = CommandBuilder::new(shell_path); let child = pair.slave .spawn_command(cmd)