diff --git a/scripts/setup.sh b/scripts/setup.sh index d1c2eb42..f32f39ef 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -423,10 +423,12 @@ install_go() { esac echo " Installing Go ${GOLANG_VERSION} from official tarball..." curl -fsSL "https://go.dev/dl/go${GOLANG_VERSION}.linux-${GO_ARCH}.tar.gz" -o /tmp/go.tar.gz - sudo rm -rf /usr/local/go - sudo tar -C /usr/local -xzf /tmp/go.tar.gz + rm -rf "$HOME/.local/go" + mkdir -p "$HOME/.local" + tar -C "$HOME/.local" -xzf /tmp/go.tar.gz rm /tmp/go.tar.gz - export PATH="/usr/local/go/bin:$PATH" + export GOPATH="$HOME/.local/go-path" + export PATH="$HOME/.local/go/bin:$GOPATH/bin:$PATH" ;; brew) brew install go @@ -503,7 +505,7 @@ fi echo "" echo "── cliamp ──" -GOPATH_BIN="${GOPATH:-$HOME/go}/bin" +GOPATH_BIN="${GOPATH:-$HOME/.local/go-path}/bin" export PATH="$GOPATH_BIN:$PATH" if has cliamp; then @@ -844,7 +846,7 @@ echo "════════════════════════ echo "" echo "Notes:" echo " • PulseAudio null sink starts automatically with the server" -echo " • Make sure ~/go/bin is in your PATH for cliamp" +echo " • Make sure ~/.local/go/bin and ~/.local/go-path/bin are in your PATH for Go tools" echo " • Make sure ~/.cargo/bin is in your PATH for Rust tools" echo " • sharp, whisper-cpp, mlx-audio can be installed from Settings > Applications" echo "" diff --git a/src/servers/api/cliamp/websocket.ts b/src/servers/api/cliamp/websocket.ts index 530e3634..f00e4e90 100644 --- a/src/servers/api/cliamp/websocket.ts +++ b/src/servers/api/cliamp/websocket.ts @@ -2,7 +2,7 @@ import type { ServerWebSocket } from 'bun'; import { spawn, type Subprocess } from 'bun'; import { resolve, normalize, dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { getHomeDir } from '@@/data-path'; +import { getHomeDirForRole } from '@@/data-path'; const __dirname = dirname(fileURLToPath(import.meta.url)); const ASOUNDRC_PATH = join(__dirname, 'asoundrc'); @@ -49,12 +49,18 @@ const validateFilePaths = (files: string[], homeDir: string): string[] | null => const findCliamp = (): string | null => { const which = Bun.which('cliamp'); if (which) return which; - const goPath = process.env.GOPATH ?? `${process.env.HOME}/go`; - const goBin = `${goPath}/bin/cliamp`; - try { - const stat = Bun.spawnSync({ cmd: ['test', '-x', goBin], stdout: 'ignore', stderr: 'ignore' }); - if (stat.exitCode === 0) return goBin; - } catch { /* ignore */ } + const candidates = [ + process.env.GOPATH ? `${process.env.GOPATH}/bin/cliamp` : null, + `${process.env.HOME}/.local/go-path/bin/cliamp`, + `${process.env.HOME}/go/bin/cliamp`, + ]; + for (const bin of candidates) { + if (!bin) continue; + try { + const stat = Bun.spawnSync({ cmd: ['test', '-x', bin], stdout: 'ignore', stderr: 'ignore' }); + if (stat.exitCode === 0) return bin; + } catch { /* ignore */ } + } return null; }; @@ -62,7 +68,7 @@ const shellEscape = (s: string) => `'${s.replace(/'/g, "'\\''")}'`; export const cliampWebsocket = { async open(ws: ServerWebSocket) { - const { email, files: filesParam } = ws.data; + const { email, role, files: filesParam } = ws.data; if (!filesParam) { sendOutput(ws, '\r\n[Error] No files specified.\r\n'); @@ -75,7 +81,7 @@ export const cliampWebsocket = { return; } - const homeDir = getHomeDir(email); + const homeDir = getHomeDirForRole(email, role); const rawFiles = [filesParam]; // Resolve paths relative to user home dir diff --git a/src/workspaces/officerdev/src/apps/FileBrowser/CliampPanel.tsx b/src/workspaces/officerdev/src/apps/FileBrowser/CliampPanel.tsx index 8c66328f..ab47e49b 100644 --- a/src/workspaces/officerdev/src/apps/FileBrowser/CliampPanel.tsx +++ b/src/workspaces/officerdev/src/apps/FileBrowser/CliampPanel.tsx @@ -1,34 +1,20 @@ import { useCallback } from 'react'; import { useSearchParams } from 'react-router'; -import { X } from 'lucide-react'; +import { Music } from 'lucide-react'; import { TerminalView } from '../Terminal/Terminal'; import { AudioStreamPlayer } from './AudioStreamPlayer'; export const CliampPanelHeader = () => { - const [searchParams, setSearchParams] = useSearchParams(); + const [searchParams] = useSearchParams(); const playPath = searchParams.get('play') ?? ''; const fileName = playPath.split('/').pop() ?? 'cliamp'; - const handleClose = useCallback(() => { - setSearchParams((prev) => { - const next = new URLSearchParams(prev); - next.delete('play'); - return next; - }); - }, [setSearchParams]); - return ( -
- {fileName} + <> + + {fileName} - -
+ ); };