Manager web: - Replace favicon.ico (both default & classic themes) with new H icon - Compact heicode-logo.svg from 204KB base64 blob to 5KB - Replace classic theme logo.png (was still old NewAPI icon) Client (cc-haha): - Fix isInBundledMode() to detect Bun-compiled sidecars that have no explicit embeddedFiles — checks process.execPath basename instead - Add well-known ripgrep install paths (/opt/homebrew/bin, /usr/local/bin, ~/.cargo/bin, etc.) as fallback when PATH is incomplete in Tauri sidecar Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,12 +11,32 @@ export function isRunningWithBun(): boolean {
|
||||
|
||||
/**
|
||||
* Detects if running as a Bun-compiled standalone executable.
|
||||
* This checks for embedded files which are present in compiled binaries.
|
||||
*
|
||||
* Original heuristic only checked `Bun.embeddedFiles.length > 0`, which
|
||||
* fails when the build doesn't explicitly embed data files (e.g. the
|
||||
* Tauri sidecar built by `desktop/scripts/build-sidecars.ts`).
|
||||
*
|
||||
* Compiled Bun standalones always include built-in tools (ripgrep, etc.)
|
||||
* dispatched via argv[0], so we need a broader detection:
|
||||
* 1. Embedded files present → definitely bundled.
|
||||
* 2. Running under Bun but process.execPath is NOT the bun runtime
|
||||
* binary itself → we're inside a compiled standalone.
|
||||
*
|
||||
* See: https://github.com/NanmiCoder/cc-haha/issues/433
|
||||
*/
|
||||
export function isInBundledMode(): boolean {
|
||||
return (
|
||||
typeof Bun !== 'undefined' &&
|
||||
Array.isArray(Bun.embeddedFiles) &&
|
||||
Bun.embeddedFiles.length > 0
|
||||
)
|
||||
if (typeof Bun === 'undefined') {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check 1: explicit embedded files (original check)
|
||||
if (Array.isArray(Bun.embeddedFiles) && Bun.embeddedFiles.length > 0) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check 2: in `bun run script.ts`, process.execPath is the bun runtime
|
||||
// binary (e.g. "/usr/local/bin/bun"). In a compiled standalone, it's
|
||||
// the custom binary (e.g. "heicode-sidecar-aarch64-apple-darwin").
|
||||
const basename = process.execPath.split(/[/\\]/).pop()?.toLowerCase() ?? ''
|
||||
return basename !== 'bun' && basename !== 'bun.exe'
|
||||
}
|
||||
|
||||
@@ -68,6 +68,45 @@ function findUsableSystemRipgrep(): string | null {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Well-known directories where ripgrep may be installed but missing from
|
||||
* the sidecar's PATH. Tauri collects env via `zsh -l -c "env -0"` which
|
||||
* reads *login-shell* config (~/.zprofile) — interactive-shell additions
|
||||
* in ~/.zshrc (e.g. Homebrew's `eval` block) are skipped, so
|
||||
* /opt/homebrew/bin is often absent.
|
||||
*
|
||||
* See: https://github.com/NanmiCoder/cc-haha/issues/433
|
||||
*/
|
||||
function wellKnownRipgrepPaths(): string[] {
|
||||
if (process.platform === 'win32') {
|
||||
// On Windows the PATH search + findExecutable is usually sufficient;
|
||||
// add common Scoop / Cargo paths just in case.
|
||||
const home = homedir()
|
||||
return [
|
||||
path.join(home, 'scoop', 'shims', 'rg.exe'),
|
||||
path.join(home, '.cargo', 'bin', 'rg.exe'),
|
||||
]
|
||||
}
|
||||
|
||||
const home = homedir()
|
||||
return [
|
||||
// Homebrew — Apple Silicon
|
||||
'/opt/homebrew/bin/rg',
|
||||
// Homebrew — Intel Mac / Linuxbrew default
|
||||
'/usr/local/bin/rg',
|
||||
// System package manager (apt, dnf, pacman …)
|
||||
'/usr/bin/rg',
|
||||
// Cargo install
|
||||
path.join(home, '.cargo', 'bin', 'rg'),
|
||||
// Snap (Ubuntu)
|
||||
'/snap/bin/rg',
|
||||
// Nix single-user
|
||||
path.join(home, '.nix-profile', 'bin', 'rg'),
|
||||
// Nix multi-user
|
||||
'/run/current-system/sw/bin/rg',
|
||||
]
|
||||
}
|
||||
|
||||
function systemRipgrepCandidates(): string[] {
|
||||
const candidates: string[] = []
|
||||
const seen = new Set<string>()
|
||||
@@ -100,6 +139,12 @@ function systemRipgrepCandidates(): string[] {
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: well-known install locations that may not be in PATH,
|
||||
// especially when launched as a Tauri sidecar from Finder/Dock.
|
||||
for (const p of wellKnownRipgrepPaths()) {
|
||||
addCandidate(p)
|
||||
}
|
||||
|
||||
return candidates
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user