The Problem
Professionals who need real‑time AI assistance during meetings, interviews, or presentations often face a choice between expensive, closed‑source tools that record and transmit conversation data, or open‑source alternatives that are either too heavyweight or lack native performance. The result is either compromised privacy or a sluggish user experience.
What This Does
Pluely is a privacy‑first AI assistant (the open‑source counterpart of the $15 M company Cluely) that runs as a native Tauri app (~10 MB). The frontend is a React + TypeScript codebase (src/) that presents an always‑on overlay, captures audio via src‑tauri/src/speaker/*.rs modules, and sends transcripts to an AI provider selected through src/config/ai-providers.constants.ts. The backend is Rust (src‑tauri/); src‑tauri/src/main.rs boots the Tauri window, while src‑tauri/src/lib.rs exposes the core API. Audio capture flows through src‑tauri/src/speaker/mod.rs → platform‑specific files (linux.rs, macos.rs, windows.rs). The UI components (src/components/ui/) render the overlay, and hooks such as src/hooks/useSystemAudio.ts and src/hooks/useCompletion.ts orchestrate listening, transcription, and response display. Data is persisted in a SQLite database under src‑tauri/src/db/main.rs with migrations in src‑tauri/src/db/migrations/. The app is completely undetectable in video calls, screen shares, and recordings because it injects its UI via the Tauri window layer rather than an overlay DOM element.
How It Is Wired
- Entry points:
index.htmlloadssrc/main.tsx, which creates the Tauri window and starts the React app. - Import graph: 189 files were analysed; 174 internal TypeScript modules and 15 Rust modules have 177 import edges. Four modules participate in a circular dependency:
src/pages/chats/components/View.tsx,src/hooks/index.ts,src/hooks/useSystemAudio.ts, andsrc/components/ui/index. - Hubs & cycles:
src/components/ui/indexis imported by 3 modules and itself imports 17, giving it an instability of 0.85. The hook cycle (mentioned above) forces runtime guard‑clauses and complicates static analysis. - Oversized files:
src/hooks/useCompletion.ts,src/hooks/useSystemAudio.ts, andsrc‑tauri/src/api.rseach exceed 800 lines, making changes ripple widely. - High branching density:
src/lib/database/chat-history.action.ts,src/lib/functions/ai-response.function.ts, andsrc/lib/functions/stt.function.tscontain 133 branch points over ~449 lines, indicating decision‑heavy logic that would benefit from decomposition.
How To Use It
| Step | Command / File |
|---|---|
| Clone | git clone https://github.com/moses-y/pluely (use the URL verbatim) |
| Install dependencies | npm install (or pnpm install) – defined in package.json |
| Configure AI provider | Edit src/config/ai-providers.constants.ts and set API_KEY env‑var; the file also lists supported providers in src/lib/storage/ai-providers.ts. |
| Run development build | npm run tauri dev – this invokes cargo tauri which builds the Rust backend and starts the React dev server. |
| Production build | npm run tauri build – produces .dmg, .msi, .exe, .deb, .rpm, or .AppImage bundles. |
No secrets are committed; any required API keys are injected at runtime via environment variables.
Real‑World Use
During a video call, the user’s microphone is captured by src‑tauri/src/speaker/macos.rs (or the appropriate platform module). src/hooks/useSystemAudio.ts streams the audio to the STT pipeline (src/lib/functions/stt.function.ts). The transcript is sent to the selected AI provider (configured in src/config/ai-providers.constants.ts). The response is rendered in src/components/Overlay.tsx and displayed as a floating panel that follows the cursor. Because the UI is rendered inside the Tauri window, it does not appear as a separate browser tab and is invisible to most screen‑share detection. The user can toggle the assistant on/off via the global shortcut defined in src/pages/shortcuts/components/Cursor.tsx.
Code Health & Issues
- [HIGH] Pin third‑party GitHub Actions to a commit SHA –
.github/workflows/publish.ymlreferencesdtolnay/rust-toolchain@stableandtauri-apps/tauri-action@v0.5.16; tags can move, risking secret exposure. - [HIGH] Add a test suite – 189 source files with no test coverage; any regression reaches production undetected.
- [MEDIUM] Enable Dependabot or Renovate – two manifests exist but no update bot is configured; advisories may go unpatched.
- [MEDIUM] Gate pull requests on a dependency vulnerability scan – CI lacks a dependency‑review step; a known‑vulnerable package could merge unnoticed.
- [MEDIUM] Move large binaries to Git LFS –
images/app-image.pngis 6.1 MB; every clone/checkout transfers unnecessary data. - [MEDIUM] Set
persist-credentials: falseon checkout –.github/workflows/publish.ymlkeeps the token in.git/configfor all later steps, allowing a malicious post‑install script to read pushable credentials. - [LOW] Set
timeout-minuteson workflow jobs – no job timeout is set; a wedged step could run past the six‑hour default. - [LOW] Add convention files – missing
.editorconfig,.gitattributes, and formatter config; inconsistent editor settings across contributors.
Measured static‑analysis findings (deterministic, not opinion):
- Deep nesting x28 in
src/components/ui/chart.tsx,src/pages/app/components/completion/Input.tsx,src/pages/audio/components/AudioSelection.tsx(max indent depth 8). - Duplicated code blocks: 596 repeated 6‑line blocks across 38 files, e.g.,
src/components/Selection/index.tsx,src/pages/shortcuts/components/Cursor.tsx,src/components/ui/input.tsx,src/components/ui/textarea.tsx. - Import‑cycle member x4 (listed above).
- Oversized file x3 (
useCompletion.ts,useSystemAudio.ts,api.rs). - High branching density x6 in
chat‑history.action.ts,ai‑response.function.ts,stt.function.ts.
The Bottom Line
Pluely delivers a lightweight, privacy‑preserving AI assistant that runs natively via Tauri and stays invisible during calls, which is a strong technical achievement for an open‑source project. However, the codebase suffers from circular imports, oversized modules, and a complete absence of test coverage, and the CI pipeline lacks dependency‑pinning and vulnerability scanning. It is well‑suited for developers or teams comfortable with Rust‑React integration who need a customizable, low‑footprint AI helper, but it requires investment in testing, CI hygiene, and modularisation before it can be safely shipped in a production environment.