Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## [1.0.1] — 2026-06-17

### Fixes
- fix(setup): register MCP sidecars from a stable path when the app runs from a
DMG or App Translocation mount. Previously the `lumen-mcp`/`lumen-tok` paths
written to `~/.claude.json` pointed inside the ejected `/Volumes/…` mount, so
Claude Code failed to launch the server with
`ENOENT … posix_spawn '/Volumes/…/lumen-mcp'`. The sidecars are now copied to
`~/Library/Application Support/io.speedata.lumen/bin/` and registered there.

## [1.0.0] — 2026-06-09

### Features
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lumenator/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lumenator",
"version": "1.0.0",
"version": "1.0.1",
"scripts": {
"ng": "ng",
"start": "ng serve",
Expand Down
2 changes: 1 addition & 1 deletion lumenator/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "Lumen"
version = "1.0.0"
version = "1.0.1"
description = "macOS menu-bar app for Claude Code — live context gauge, cost, and optimizer"
authors = ["HackPoint"]
license = "MIT"
Expand Down
45 changes: 43 additions & 2 deletions lumenator/src-tauri/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,47 @@ fn find_binary(name: &str) -> Option<PathBuf> {
None
}

fn app_support_dir() -> PathBuf {
home().join("Library/Application Support/io.speedata.lumen")
}

// macOS runs unsigned / quarantined apps from ephemeral, read-only locations:
// a mounted DMG (`/Volumes/…`) or a Gatekeeper App Translocation mount
// (`/private/var/folders/…/AppTranslocation/…`). Both disappear when the DMG is
// ejected or the app is moved, leaving the MCP `command` path we recorded in
// ~/.claude.json dangling — Claude Code then fails with
// `ENOENT … posix_spawn '/Volumes/…/lumen-mcp'`.
fn is_ephemeral_path(p: &std::path::Path) -> bool {
let s = p.to_string_lossy();
s.starts_with("/Volumes/") || s.contains("/AppTranslocation/")
}

// Resolve a sidecar binary to a path that survives the DMG being ejected. If the
// bundled binary lives on an ephemeral mount, copy it into a stable, user-writable
// location (`…/io.speedata.lumen/bin/<name>`) and return that; otherwise return
// the resolved path unchanged. Copying the standalone Mach-O preserves its
// embedded code signature, so it still launches.
fn stable_binary(name: &str) -> Option<PathBuf> {
let found = find_binary(name)?;
if !is_ephemeral_path(&found) {
return Some(found);
}
let bin_dir = app_support_dir().join("bin");
if std::fs::create_dir_all(&bin_dir).is_err() {
return Some(found); // fall back rather than failing setup outright
}
let dest = bin_dir.join(name);
if std::fs::copy(&found, &dest).is_err() {
return Some(found);
}
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let _ = std::fs::set_permissions(&dest, std::fs::Permissions::from_mode(0o755));
}
Some(dest)
}

fn db_path() -> String {
std::env::var("LUMEN_DB").unwrap_or_else(|_| {
home()
Expand Down Expand Up @@ -537,8 +578,8 @@ fn run_setup() -> Vec<SetupStep> {
}

// 2. Resolve binary paths
let mcp_bin = find_binary("lumen-mcp");
let tok_bin = find_binary("lumen-tok");
let mcp_bin = stable_binary("lumen-mcp");
let tok_bin = stable_binary("lumen-tok");

let mcp_str = mcp_bin
.as_ref()
Expand Down
2 changes: 1 addition & 1 deletion lumenator/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Lumen",
"version": "1.0.0",
"version": "1.0.1",
"identifier": "io.speedata.lumen",
"build": {
"frontendDist": "../dist/lumenator/browser",
Expand Down
Loading