fix: Manager favicon/logo + ripgrep sidecar detection (#433 #208)

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:
2026-05-15 16:23:15 +08:00
co-authored by Claude Opus 4.6
parent 3e7ed0202d
commit 460bdcc951
6 changed files with 73 additions and 8 deletions
+26 -6
View File
@@ -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'
}
+45
View File
@@ -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
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB