Skip to content

ChristopherTrimboli/linux-ai

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

12 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

linux-ai

As an avid Ubuntu user I was horribly disgusted with the lack of support for Linux in the ChatGPT app, alternative open source projects suffer from feature bloat. So I told Claude to make the best Linux AI app for my own use. Enjoy if works for you too. :)

Core Philosophy

  1. We are not competing in the agentic coding realm. Just use Cursor bro.

  2. This will always be free open software with no paid subscription tiers with locked features.

  3. This is not a local-ai monolith to run all your niche weirdo local AI LLMs and tinker with CUDA.

This is an app for integrating AI intelligence into your Linux computer.


What it is

πŸ“– Documentation: https://christophertrimboli.github.io/linux-ai/

A Linux-first AI chat app that can act on your computer through a small set of built-in tools, available as both a desktop app and a CLI. Bring your own API key (Anthropic, OpenAI, or any OpenAI-compatible endpoint, including a local one).

  • Desktop app β€” Tauri 2 (Rust) + Svelte 5. Tiny, fast, native WebKitGTK.
  • CLI (lai) β€” one-shot prompts, stdin piping, and an interactive chat REPL.
  • Shared Rust core (la-core) β€” both front ends use the exact same engine: multi-provider streaming, tool execution, approval gating, and local history.

Built-in tools (v1)

Tool Risk What it does
system_info read-only OS, kernel, CPU, memory, disk usage
read_file read-only Read a text file (within allowed roots)
list_dir read-only List a directory
search_files read-only Recursive name/content search
write_file mutating Create/overwrite a file (needs approval)
run_shell mutating Run a shell command (needs approval)
open mutating Open a file/URL with xdg-open (needs approval)

Read-only tools run automatically. Mutating tools require explicit approval (an inline card in the desktop app, a [y/N] prompt in the CLI) unless you enable auto-approve. File access is restricted to configured roots (your home directory by default) and shell commands are screened against a deny-list.

Voice input (speech-to-text)

The desktop app has a mic button in the composer. Click it to record from your default input device (it turns red while listening), click again to stop β€” the audio is encoded to WAV locally and transcribed via an OpenAI-compatible /audio/transcriptions endpoint, then dropped into the input box for you to edit and send. The provider and model are configurable under Settings β†’ Voice input.

It defaults to the openai provider with gpt-4o-transcribe (OpenAI's current best transcription model β€” lower word-error-rate than whisper-1 at the same price). Other suggested options: gpt-4o-mini-transcribe (cheaper/faster) or whisper-1 (legacy).

Other STT providers work too:

  • OpenRouter β€” select the openrouter provider and a slugged model like openai/gpt-4o-transcribe or openai/whisper-1 (uses OpenRouter's JSON audio API and your existing OpenRouter key).
  • Local / offline β€” point a provider at a whisper.cpp / faster-whisper server and use its model name (whisper-large-v3, whisper-large-v3-turbo, …).

Repository layout

linux-ai/
  crates/
    core/        # la-core: providers, tools, agent loop, SQLite store, config
    cli/         # `lai` binary
  desktop/
    src/         # Svelte 5 + Vite frontend
    src-tauri/   # Tauri 2 Rust app (depends on la-core)

Prerequisites

  • Rust stable 1.88 or newer (developed on 1.96). Install/upgrade with rustup update stable.
  • For the desktop app only, Node.js 18+ and the Tauri Linux system libraries:
# Debian/Ubuntu
sudo apt update
sudo apt install -y \
  libwebkit2gtk-4.1-dev build-essential curl wget file \
  libxdo-dev libssl-dev libdbus-1-dev libasound2-dev \
  libayatana-appindicator3-dev librsvg2-dev pkg-config
# Fedora
sudo dnf install -y webkit2gtk4.1-devel openssl-devel curl wget file \
  libxdo-devel dbus-devel libappindicator-gtk3-devel librsvg2-devel alsa-lib-devel

The CLI and core do not require any of the above β€” only a Rust toolchain.

Build & run

CLI

# from the repo root
cargo build --release -p linux-ai-cli      # builds ./target/release/lai
cargo install --path crates/cli            # installs `lai` onto your PATH

Desktop app

cd desktop
npm install
npm run tauri dev        # dev build with hot reload
npm run tauri build      # produces a .deb and an AppImage under src-tauri/target/release/bundle

Snap

A snap/snapcraft.yaml is included for building/distributing as a snap (strict confinement). Build it locally with snapcraft, or let the Snap workflow build/publish it. Note that strict confinement sandboxes the computer-access tools to your home directory β€” for full system access prefer the .deb/AppImage. See the Snap guide for details.

The desktop bundle targets (deb, appimage) and icons are configured in desktop/src-tauri/tauri.conf.json. Icons are generated by desktop/src-tauri/gen_icons.py.

Dock icon (GNOME / Ubuntu)

Installed .deb / AppImage builds register their own icon. But when running npm run tauri dev (or any unpackaged binary) on Wayland, GNOME shows a generic dock icon because it resolves icons by matching a window's app_id to an installed .desktop file. The app sets its app_id to dev.linux-ai.app (enableGTKAppId in the Tauri config); run this once to install a matching desktop entry + themed icons for your user:

desktop/install-desktop-entry.sh            # install (re-run anytime)
desktop/install-desktop-entry.sh --uninstall

Restart the app (or log out/in) and the dock will show the real icon.

Using the CLI

lai "what is using port 8080?"       # one-shot prompt
cat error.log | lai "explain this"    # pipe stdin into the prompt
lai chat                              # interactive REPL (Ctrl-D / 'exit' to quit)

lai providers                         # list providers and whether a key is set
lai models openai                     # list known models for a provider
lai auth anthropic                    # store an API key in the OS keyring
lai config                            # show config + data file locations

lai -p openai -m gpt-4o "hello"       # override provider/model for one run
lai -y "tidy up ~/Downloads"          # auto-approve tool actions for this run

Configuration & secrets

  • Config: ~/.config/linux-ai/config.toml (created on first run).
  • History: ~/.local/share/linux-ai/linux-ai.db (SQLite).
  • API keys are resolved in this order: OS keyring β†’ environment variable (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, ...) β†’ plaintext api_key in the config. Store keys with lai auth <provider> or via the desktop Settings panel.

Out of the box there are providers for Anthropic, OpenAI, OpenRouter (access 400+ models behind one key, e.g. openrouter/auto), and a local OpenAI-compatible endpoint (Ollama). You can add any other OpenAI-compatible endpoint by editing the [providers.*] tables in the config and pointing base_url at it.

Security model

  • Mutating tools are gated behind explicit approval by default.
  • Filesystem tools are confined to configured roots (home directory by default).
  • Shell commands are screened against a configurable deny-list.
  • Everything runs locally; the only network calls are to the LLM provider you configure.

Releases

Pushing a version tag builds and publishes a GitHub Release with the production artifacts for both x86_64 and aarch64 Linux (CLI tarball + .deb + AppImage per arch) via .github/workflows/release.yml:

git tag v0.1.0
git push origin v0.1.0

You can also trigger it manually from the Actions tab (provide the tag as input). The workflow uses the committed Cargo.lock and desktop/package-lock.json, so make sure those are committed.

Versioning

The git tag is the single source of truth for a release's version. Tags must be semver (vMAJOR.MINOR.PATCH, optionally -rc.1 etc.); the workflow rejects anything else. At build time it strips the leading v and stamps that version into the workspace Cargo.toml (which every crate and the CLI inherit) and desktop/package.json. The desktop bundle has no version of its own in tauri.conf.json β€” it inherits the workspace crate version β€” so the CLI, the crates, and the .deb/AppImage all carry the exact tag version with nothing to keep in sync by hand. The 0.1.0 checked into the repo is just the dev default.

Not in v1 (possible future work)

  • MCP client support for external tools
  • Voice input/output
  • Vision-based computer use (screenshot + mouse/keyboard control)

License

MIT β€” see LICENSE.

About

As an avid Ubuntu user I was horribly disgusted with the lack of support for Linux in the ChatGPT app... enjoy the result.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors