From 1ca1803fee732cc6713b8a960a9aa2da14bd8600 Mon Sep 17 00:00:00 2001
From: Rob Macrae
Date: Tue, 14 Jul 2026 21:05:15 +0100
Subject: [PATCH 1/5] fix(desktop): don't keep booting the sandbox VM after the
user accepts an update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Accepting "Update & restart" tears the whole stack down and relaunches, but the
sandbox VM thread kept staging/downloading the image and booting the VM during the
~minutes-long update download — only to be killed on restart. Now an UPDATING flag
is set on accept: start_sandbox_vm bails before staging/boot (and stops the VM if the
update lands mid-boot), and a VM-only stop_sandbox_vm() halts an already-running VM
while leaving workerd/frontend up so the update-progress bar keeps working.
---
desktop/app/src-tauri/src/main.rs | 51 ++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/desktop/app/src-tauri/src/main.rs b/desktop/app/src-tauri/src/main.rs
index d2fb38d..e334a6b 100644
--- a/desktop/app/src-tauri/src/main.rs
+++ b/desktop/app/src-tauri/src/main.rs
@@ -26,6 +26,16 @@ fn pid_file_path(data_dir: &Path) -> PathBuf {
data_dir.join("desktop-services.pid")
}
+/// Set once the user accepts an auto-update ("Update & restart"). The whole stack is
+/// about to be torn down and relaunched, so we must NOT keep spinning up heavy
+/// processes (especially the sandbox VM boot / image download) during the ~minutes
+/// download — `start_sandbox_vm` checks this and bails.
+static UPDATING: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
+
+fn is_updating() -> bool {
+ UPDATING.load(std::sync::atomic::Ordering::SeqCst)
+}
+
/// Progress of an in-flight auto-update, emitted to the GUI as `update-progress`
/// so the frontend can show a download bar (the native "Update available" dialog
/// otherwise gives no feedback between "Update & restart" and the relaunch).
@@ -665,6 +675,13 @@ impl DesktopServices {
data_dir: &Path,
resource_root: &Path,
) -> Result<(), vm::VMError> {
+ // The user accepted an app update → don't spin the VM up (or download its image)
+ // just to tear it all down on the imminent relaunch.
+ if is_updating() {
+ eprintln!("[vm] app update accepted — skipping sandbox VM startup");
+ return Ok(());
+ }
+
// Check if VM resources exist
let vm_resource_paths = vm::image::VMResourcePaths::from_resource_root(resource_root);
@@ -775,9 +792,20 @@ impl DesktopServices {
};
config = config.with_cmdline(cmdline);
- // Create and start VM
+ // Create and start VM — unless an update was accepted while we were staging.
+ if is_updating() {
+ eprintln!("[vm] app update accepted — not booting sandbox VM");
+ return Ok(());
+ }
let mut vm = create_platform_vm();
vm.start(&config)?;
+ // If the update landed during boot, stop the VM we just started rather than
+ // waiting 120s for health only to tear it down on relaunch.
+ if is_updating() {
+ eprintln!("[vm] app update accepted mid-boot — stopping sandbox VM");
+ let _ = vm.stop();
+ return Ok(());
+ }
// Wait for sandbox to be healthy
eprintln!("Waiting for sandbox VM to become healthy...");
@@ -836,6 +864,19 @@ impl DesktopServices {
}
}
+ /// Stop ONLY the sandbox VM (leave workerd/frontend running). Used when the user
+ /// accepts an update: the heavy VM shouldn't keep running/booting during the
+ /// download, but the frontend must stay up so the update-progress bar keeps working.
+ fn stop_sandbox_vm(&self) {
+ if let Ok(mut vm_lock) = self.sandbox_vm.lock() {
+ if let Some(ref mut vm) = *vm_lock {
+ eprintln!("Stopping sandbox VM (app update in progress)...");
+ let _ = vm.stop();
+ }
+ *vm_lock = None;
+ }
+ }
+
fn shutdown(&self) {
// Stop sandbox VM first
if let Ok(mut vm_lock) = self.sandbox_vm.lock() {
@@ -1130,6 +1171,7 @@ fn main() {
use tauri_plugin_dialog::{DialogExt, MessageDialogButtons};
use tauri_plugin_updater::UpdaterExt;
let handle = app.handle().clone();
+ let upd_services = Arc::clone(&services);
tauri::async_runtime::spawn(async move {
let updater = match handle.updater() {
Ok(u) => u,
@@ -1158,6 +1200,13 @@ fn main() {
return;
}
+ // The user chose update+restart. Everything is about to be torn down and
+ // relaunched, so stop spinning up the heavy sandbox VM during the ~minutes
+ // download: flag it so start_sandbox_vm won't (re)boot, and stop any VM that
+ // already came up. Leave workerd/frontend running so this progress UI works.
+ UPDATING.store(true, std::sync::atomic::Ordering::SeqCst);
+ upd_services.stop_sandbox_vm();
+
// Tell the GUI a download is starting so it can show a progress bar,
// then stream progress from the download closure. Emits are throttled
// to once per MB so a ~190MB download doesn't flood IPC.
From dccaf2c6261130efe2b2c1c910c6e383a6773898 Mon Sep 17 00:00:00 2001
From: Rob Macrae
Date: Tue, 14 Jul 2026 21:11:54 +0100
Subject: [PATCH 2/5] feat(desktop): tee backend service logs to startup.log
(diagnose startup failures)
A Finder-launched .app has no attached terminal, so the workerd/D1 output that
explains WHY startup failed (e.g. a port bind error) vanished into inherited stderr.
Now spawn_binary pipes + tees each service's stdout/stderr to the console AND a
per-boot /startup.log (truncated each launch, headed with the chosen
control-plane/frontend/d1/sandbox ports). Adds a read_startup_log command so the
loading screen can show it when the backend doesn't come up.
---
desktop/app/src-tauri/src/commands.rs | 14 +++++
desktop/app/src-tauri/src/main.rs | 81 ++++++++++++++++++++++++++-
2 files changed, 92 insertions(+), 3 deletions(-)
diff --git a/desktop/app/src-tauri/src/commands.rs b/desktop/app/src-tauri/src/commands.rs
index f26fbc2..fa53f03 100644
--- a/desktop/app/src-tauri/src/commands.rs
+++ b/desktop/app/src-tauri/src/commands.rs
@@ -616,6 +616,20 @@ pub fn get_app_version(app: tauri::AppHandle) -> String {
app.package_info().version.to_string()
}
+/// Read this boot's startup log (`/startup.log`) — the teed workerd / D1
+/// output plus the chosen ports — so the loading screen can show WHY the backend
+/// failed to start (a Finder-launched .app has no console). Empty string if none.
+#[tauri::command]
+pub fn read_startup_log(app: tauri::AppHandle) -> String {
+ use tauri::Manager;
+ app.path()
+ .app_data_dir()
+ .ok()
+ .map(|d| d.join("startup.log"))
+ .and_then(|p| std::fs::read_to_string(p).ok())
+ .unwrap_or_default()
+}
+
#[derive(Serialize, Clone)]
pub struct OrcabotAccount {
pub email: String,
diff --git a/desktop/app/src-tauri/src/main.rs b/desktop/app/src-tauri/src/main.rs
index e334a6b..34ec695 100644
--- a/desktop/app/src-tauri/src/main.rs
+++ b/desktop/app/src-tauri/src/main.rs
@@ -211,6 +211,34 @@ fn ensure_port_env(var: &str, preferred: u16, used: &[u16]) -> u16 {
port
}
+/// Tee a child process stream line-by-line to the console AND (if available) the
+/// per-boot startup log, each line prefixed with the service label. Runs on its own
+/// thread so it drains the pipe continuously (never blocking the child on a full buffer).
+fn tee_child_stream(
+ stream: R,
+ label: String,
+ log_path: Option,
+ is_err: bool,
+) {
+ use std::io::{BufRead, BufReader, Write};
+ std::thread::spawn(move || {
+ let mut logf =
+ log_path.and_then(|p| std::fs::OpenOptions::new().create(true).append(true).open(p).ok());
+ for line in BufReader::new(stream).lines() {
+ let Ok(line) = line else { break };
+ let out = format!("[{}] {}", label, line);
+ if is_err {
+ eprintln!("{}", out);
+ } else {
+ println!("{}", out);
+ }
+ if let Some(ref mut f) = logf {
+ let _ = writeln!(f, "{}", out);
+ }
+ }
+ });
+}
+
/// Per-boot token that gates dev-auth to the trusted host frontend. Generated
/// once at startup, passed to the control-plane worker (`SURFACE_TOKEN`) and
/// handed to the GUI webview via the `get_surface_token` command. The sandbox VM
@@ -471,6 +499,13 @@ impl DesktopServices {
);
}
+ // Start the per-boot startup log with the chosen ports — the first thing to check
+ // when startup fails (was a default busy? did allocation move a service?).
+ self.reset_startup_log(&format!(
+ "ports: control-plane={} frontend={} d1-shim={} sandbox={}",
+ cp_port, fe_port, d1_port, sandbox_host_port
+ ));
+
if cp_port != 8787 || fe_port != 8788 || d1_port != 9001 || sandbox_host_port != 8080 {
eprintln!(
"[ports] a default port was busy — using control-plane={} frontend={} d1-shim={} sandbox={}",
@@ -846,24 +881,63 @@ impl DesktopServices {
let mut command = Command::new(binary_path);
command.args(args);
- command.stdout(Stdio::inherit());
- command.stderr(Stdio::inherit());
+ // Tee stdout+stderr to the console AND /startup.log. A Finder-launched
+ // .app has no attached terminal, so inherited output vanishes — this keeps a
+ // per-boot record of WHY a service failed (surfaced in the loading screen and
+ // recoverable as a file).
+ command.stdout(Stdio::piped());
+ command.stderr(Stdio::piped());
for (key, value) in envs {
command.env(key, value);
}
match command.spawn() {
- Ok(child) => {
+ Ok(mut child) => {
+ let log_path = self.startup_log_path();
+ if let Some(out) = child.stdout.take() {
+ tee_child_stream(out, label.to_string(), log_path.clone(), false);
+ }
+ if let Some(err) = child.stderr.take() {
+ tee_child_stream(err, label.to_string(), log_path, true);
+ }
if let Ok(mut children) = self.children.lock() {
children.push(child);
}
}
Err(err) => {
eprintln!("Failed to start {}: {}", label, err);
+ self.append_startup_log(&format!("[{}] FAILED TO START: {}", label, err));
}
}
}
+ /// `/startup.log` — where service output is teed for post-mortem.
+ fn startup_log_path(&self) -> Option {
+ self
+ .data_dir
+ .lock()
+ .ok()
+ .and_then(|dd| dd.clone())
+ .map(|d| d.join("startup.log"))
+ }
+
+ fn append_startup_log(&self, line: &str) {
+ if let Some(p) = self.startup_log_path() {
+ use std::io::Write;
+ if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open(p) {
+ let _ = writeln!(f, "{}", line);
+ }
+ }
+ }
+
+ /// Truncate the startup log at the start of a boot and write a header, so it only
+ /// ever reflects the CURRENT startup attempt (not accumulated across launches).
+ fn reset_startup_log(&self, header: &str) {
+ if let Some(p) = self.startup_log_path() {
+ let _ = std::fs::write(p, format!("=== Orcabot desktop startup ===\n{}\n", header));
+ }
+ }
+
/// Stop ONLY the sandbox VM (leave workerd/frontend running). Used when the user
/// accepts an update: the heavy VM shouldn't keep running/booting during the
/// download, but the frontend must stay up so the update-progress bar keeps working.
@@ -1053,6 +1127,7 @@ fn main() {
commands::reveal_workspace,
commands::get_ports,
commands::get_app_version,
+ commands::read_startup_log,
commands::verify_orcabot_account,
commands::set_cloud_credential,
commands::sign_in_google_loopback,
From bf3fe8ef3833122322717d4c5393c842fb79a138 Mon Sep 17 00:00:00 2001
From: Rob Macrae
Date: Tue, 14 Jul 2026 21:14:32 +0100
Subject: [PATCH 3/5] feat(desktop): show backend logs on startup failure;
remove "Open anyway"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- On the startup-failure screen, fetch and display the teed backend server logs
(read_startup_log → /startup.log) below the port/health summary, so a
user (or their nephew) can see WHY the services didn't come up without a terminal.
The diag box now scrolls for long logs.
- Remove the "Open anyway →" option: proceeding to the dashboard while the required
backend (web interface / control plane) is down just yields a broken app, so it was
a trap. Retry / Quit remain.
---
desktop/app/loading.html | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/desktop/app/loading.html b/desktop/app/loading.html
index c4825d1..b8ed215 100644
--- a/desktop/app/loading.html
+++ b/desktop/app/loading.html
@@ -34,7 +34,8 @@
.foot .warn { color:var(--warn); }
.diag { margin-top:10px; font-size:.72rem; color:var(--muted); font-family: ui-monospace, Menlo, monospace;
background: rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.08); border-radius:8px;
- padding:8px 10px; user-select:text; display:none; white-space:pre-wrap; text-align:left; }
+ padding:8px 10px; user-select:text; display:none; white-space:pre-wrap; text-align:left;
+ max-height:260px; overflow:auto; }
.actions { margin-top:18px; display:flex; gap:12px; align-items:center; justify-content:center; min-height:34px; }
.btn { font: inherit; font-size:.85rem; font-weight:600; padding:7px 16px; border-radius:9px; cursor:pointer;
border:1px solid rgba(255,255,255,.16); background:rgba(255,255,255,.05); color:var(--fg); }
@@ -56,7 +57,6 @@
@@ -100,6 +100,20 @@
function stepUrl(s){ return 'http://127.0.0.1:' + PORTS[s.portKey] + s.path; }
var t0 = Date.now(), quipIdx = 0, quipStep = null, doneRedirect = false, failed = false, curStartedAt = {}, cur = null;
+ var STARTUP_LOG = '';
+ // Pull the teed backend logs (/startup.log) from the Tauri host so the
+ // failure screen can show WHY the services didn't come up.
+ function fetchStartupLog(){
+ try {
+ if (window.__TAURI__ && window.__TAURI__.core) {
+ window.__TAURI__.core.invoke('read_startup_log')
+ .then(function(t){ STARTUP_LOG = (t && t.trim()) ? t : '(startup log is empty)'; render(); })
+ .catch(function(){ STARTUP_LOG = '(could not read startup log)'; render(); });
+ return;
+ }
+ } catch (e) {}
+ STARTUP_LOG = '(startup log unavailable)';
+ }
var $ = function(id){ return document.getElementById(id); };
STEPS.forEach(function(s){
var li = document.createElement('li'); li.id = 'li-'+s.id;
@@ -136,10 +150,15 @@
$('stage').textContent = "Orcabot couldn't finish starting up";
$('quip').textContent = 'The background services didn’t come up. A previous instance may still be running, or a port is in use.';
$('hint').textContent = '';
- $('diag').style.display = 'block'; $('diag').textContent = diagText();
+ $('diag').style.display = 'block';
+ // Show the port/health summary plus the actual backend logs (workerd/D1),
+ // which explain WHY startup failed (e.g. a port bind error) — otherwise
+ // invisible in a Finder-launched .app.
+ $('diag').textContent = diagText()
+ + '\n\n─── background server logs ───\n'
+ + (STARTUP_LOG || '(fetching…)');
$('retryBtn').classList.remove('hidden');
$('quitBtn').classList.remove('hidden');
- $('openAnyway').classList.remove('hidden');
return;
}
cur = current();
@@ -149,7 +168,6 @@
$('quip').textContent = cur.quips[quipIdx % cur.quips.length];
var waited = (Date.now() - (curStartedAt[cur.id]||t0))/1000;
$('hint').innerHTML = waited > (cur.slow||12) ? ' · '+cur.label+' is taking longer than usual…' : '';
- if (elapsed() > MANUAL_AFTER){ $('openAnyway').classList.remove('hidden'); }
}
function tick(){
@@ -158,12 +176,11 @@
.then(function(){
var ready = STEPS.every(function(s){ return !s.required || s.up; });
if (ready && !doneRedirect){ doneRedirect = true; render(); setTimeout(function(){ window.location.replace(redirectUrl()); }, 500); return; }
- if (!ready && elapsed() >= FAIL_AFTER){ failed = true; }
+ if (!ready && elapsed() >= FAIL_AFTER){ failed = true; fetchStartupLog(); }
render();
});
}
- $('openAnyway').addEventListener('click', function(){ window.location.replace(redirectUrl()); });
$('retryBtn').addEventListener('click', function(){ window.location.reload(); });
$('quitBtn').addEventListener('click', function(){
try { window.__TAURI__.core.invoke('quit_app'); } catch(e) { try { window.close(); } catch(_){} }
From 682e9af71d1cd8bd659756a5051fb6a7b307e548 Mon Sep 17 00:00:00 2001
From: Rob Macrae
Date: Tue, 14 Jul 2026 22:15:29 +0100
Subject: [PATCH 4/5] fix(desktop): require macOS 13.5 + warn on download page
The bundled workerd binary (npm workerd >= 1.20240924.0) is built with
minos 13.5, so it crashes at launch on older macOS with
`dyld: Symbol not found: __libcpp_verbose_abort`, taking down both the
control-plane and frontend workerd and leaving the app stuck at
"couldn't finish starting up". No eligible workerd targets a lower OS:
the last minos-11.5 build (1.20240919.0) predates our frontend's
nodejs_compat_v2 compat_date floor (2024-09-23), which OpenNext requires.
- Bump macOS minimumSystemVersion 13.0 -> 13.5 so macOS blocks launch on
unsupported versions with a clear native dialog instead of a broken
partial startup.
- Download page: state "Requires macOS 13.5 or later" under the button
and best-effort warn pre-13.5 visitors (Chromium UA Client Hints only;
advisory, never disables the download) to save a wasted download.
Co-Authored-By: Claude Opus 4.8 (1M context)
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
---
desktop/app/src-tauri/tauri.conf.json | 2 +-
frontend/src/app/download/download.css | 5 +++
frontend/src/app/download/page.tsx | 59 +++++++++++++++++++++++++-
3 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/desktop/app/src-tauri/tauri.conf.json b/desktop/app/src-tauri/tauri.conf.json
index 9649467..fb8b28b 100644
--- a/desktop/app/src-tauri/tauri.conf.json
+++ b/desktop/app/src-tauri/tauri.conf.json
@@ -48,7 +48,7 @@
"macOS": {
"entitlements": "entitlements.plist",
"signingIdentity": "Developer ID Application: Robert Macrae (3927MKQNPA)",
- "minimumSystemVersion": "13.0"
+ "minimumSystemVersion": "13.5"
}
},
"plugins": {
diff --git a/frontend/src/app/download/download.css b/frontend/src/app/download/download.css
index 00ec930..039aacf 100644
--- a/frontend/src/app/download/download.css
+++ b/frontend/src/app/download/download.css
@@ -47,6 +47,11 @@
margin-bottom: 1rem;
}
+.dl-req {
+ margin: -0.5rem 0 1rem;
+ font-size: 0.85rem;
+}
+
.dl-btn {
display: inline-flex;
flex-direction: column;
diff --git a/frontend/src/app/download/page.tsx b/frontend/src/app/download/page.tsx
index 677f5a3..173026b 100644
--- a/frontend/src/app/download/page.tsx
+++ b/frontend/src/app/download/page.tsx
@@ -1,7 +1,7 @@
// Copyright 2026 Rob Macrae. All rights reserved.
// SPDX-License-Identifier: LicenseRef-Proprietary
-// REVISION: download-page-v1
+// REVISION: download-page-v2-min-os-warn
"use client";
import "./download.css";
@@ -17,10 +17,54 @@ import {
const GITHUB_RELEASES = "https://github.com/Hyper-Int/OrcaBot/releases/latest";
+// Minimum macOS the bundled workerd runtime supports (built with minos 13.5).
+// Older Macs crash at startup (dyld: __libcpp_verbose_abort not found), so we
+// surface the requirement before the download rather than after a broken launch.
+const MIN_MACOS = "13.5";
+
+const MODULE_REVISION = "download-page-v2-min-os-warn";
+if (typeof window !== "undefined") {
+ // eslint-disable-next-line no-console
+ console.log(`[download] REVISION: ${MODULE_REVISION} loaded at ${new Date().toISOString()}`);
+}
+
+// Best-effort check to save pre-13.5 users a wasted download. Only Chromium
+// exposes the real macOS version (UA Client Hints); Safari/Firefox don't, and
+// navigator.userAgent is privacy-frozen at "10_15_7" on macOS. So this is
+// advisory only — it never disables the button (a wrong guess must not block a
+// valid download). Returns the detected version string when confidently < 13.5.
+async function detectOldMacOS(): Promise {
+ try {
+ const uaData = (navigator as unknown as {
+ userAgentData?: {
+ platform?: string;
+ getHighEntropyValues?: (hints: string[]) => Promise<{ platformVersion?: string }>;
+ };
+ }).userAgentData;
+ if (!uaData?.getHighEntropyValues || uaData.platform !== "macOS") return null;
+ const hints = await uaData.getHighEntropyValues(["platformVersion"]);
+ const raw = String(hints.platformVersion || "");
+ const parts = raw.split(".").map((n) => parseInt(n, 10) || 0);
+ const [maj, min] = parts;
+ // major 10 (or 0) = privacy-frozen "10.15.7" or a pre-ARM Mac — can't trust
+ // it as a real version, so don't warn (avoid false positives).
+ if (!maj || maj === 10) return null;
+ if (maj < 13 || (maj === 13 && min < 5)) return raw;
+ return null;
+ } catch {
+ return null;
+ }
+}
+
export default function DownloadPage() {
const [release, setRelease] = React.useState(null);
const [error, setError] = React.useState(null);
const [loading, setLoading] = React.useState(true);
+ const [oldMac, setOldMac] = React.useState(null);
+
+ React.useEffect(() => {
+ detectOldMacOS().then(setOldMac);
+ }, []);
React.useEffect(() => {
let cancelled = false;
@@ -56,6 +100,14 @@ export default function DownloadPage() {
Run Claude Code, Codex, and a full sandboxed stack locally — no setup.
+ {oldMac && (
+
+ You appear to be on macOS {oldMac}. Orcabot requires macOS {MIN_MACOS} or
+ later and won’t start on older versions — updating macOS first will save
+ you a wasted download.
+
+ )}
+
{loading && Loading the latest release…
}
{error && (
@@ -81,6 +133,9 @@ export default function DownloadPage() {
)}
+
+ Requires macOS {MIN_MACOS} or later · Apple Silicon
+
v{release.version}
Latest
@@ -127,7 +182,7 @@ export default function DownloadPage() {
)}
- macOS 13+ · Apple Silicon. Existing installs update automatically.
+ macOS {MIN_MACOS}+ · Apple Silicon. Existing installs update automatically.
From ba332be7dbf9b6ffa546004b05e35179c329d329 Mon Sep 17 00:00:00 2001
From: Rob Macrae
Date: Tue, 14 Jul 2026 22:18:32 +0100
Subject: [PATCH 5/5] chore(desktop): bump to 0.8.0, point at VM image v3
0.7.0 was already released, so ship the macOS 13.5 startup fix as 0.8.0.
Commit the vm-image.json v2->v3 pin, which already shipped in the 0.7.0
build (sandbox-v3.img) but was never committed.
Co-Authored-By: Claude Opus 4.8 (1M context)
Claude-Session: https://claude.ai/code/session_014t8Ukp4NPWtqJ55X261wMZ
---
desktop/app/src-tauri/Cargo.lock | 2 +-
desktop/app/src-tauri/Cargo.toml | 2 +-
desktop/app/src-tauri/tauri.conf.json | 2 +-
desktop/app/src-tauri/vm-image.json | 6 +++---
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/desktop/app/src-tauri/Cargo.lock b/desktop/app/src-tauri/Cargo.lock
index 520af62..32708a0 100644
--- a/desktop/app/src-tauri/Cargo.lock
+++ b/desktop/app/src-tauri/Cargo.lock
@@ -2305,7 +2305,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "orcabot-desktop"
-version = "0.6.0"
+version = "0.8.0"
dependencies = [
"ctrlc",
"filetime",
diff --git a/desktop/app/src-tauri/Cargo.toml b/desktop/app/src-tauri/Cargo.toml
index 318e462..e135246 100644
--- a/desktop/app/src-tauri/Cargo.toml
+++ b/desktop/app/src-tauri/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "orcabot-desktop"
-version = "0.6.0"
+version = "0.8.0"
edition = "2021"
description = "Orcabot Desktop shell"
license = "UNLICENSED"
diff --git a/desktop/app/src-tauri/tauri.conf.json b/desktop/app/src-tauri/tauri.conf.json
index fb8b28b..5bcc87f 100644
--- a/desktop/app/src-tauri/tauri.conf.json
+++ b/desktop/app/src-tauri/tauri.conf.json
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Orcabot",
- "version": "0.6.0",
+ "version": "0.8.0",
"identifier": "com.orcabot.desktop",
"build": {
"beforeDevCommand": "sh -c \"cd ../../frontend && NEXT_PUBLIC_API_URL=http://localhost:8787 NEXT_PUBLIC_SITE_URL=http://localhost:8788 NEXT_PUBLIC_DEV_MODE_ENABLED=true NEXT_PUBLIC_DESKTOP_MODE=true npx wrangler dev -c wrangler.toml --port 8788\"",
diff --git a/desktop/app/src-tauri/vm-image.json b/desktop/app/src-tauri/vm-image.json
index 306a2f0..d2732ae 100644
--- a/desktop/app/src-tauri/vm-image.json
+++ b/desktop/app/src-tauri/vm-image.json
@@ -1,5 +1,5 @@
{
- "version": "v2",
- "sha256": "eba0a9e5c17778f5de08371dd9bcb46aa3697a827d8c0ed7c801a465c907f633",
- "url": "https://github.com/Hyper-Int/OrcaBot/releases/download/vm-image-v2/sandbox.img.gz"
+ "version": "v3",
+ "sha256": "a040638617597b660ea8baef915d4de70267fa48632f910fc892d9115313daa4",
+ "url": "https://github.com/Hyper-Int/OrcaBot/releases/download/vm-image-v3/sandbox.img.gz"
}