close
Skip to content

Repository files navigation

FLASH CLI

FLASH (Fast Local Agent SHell) CLI is an AI-powered command-line interface that allows you to interact with local (or remote) Ollama models while having the ability to execute shell commands directly or through the AI.

Watch the video on YouTube

Features

  • Interactive AI Chat: Chat with local or self-hosted models served by Ollama, directly from your terminal.
  • Switchable Backend: Point Flash at localhost or any remote Ollama server via a single config option.
  • Shell Command Execution:
    • AI can use a shell tool to execute commands and see their output.
    • Manually execute shell commands using the ! prefix.
  • flash:// Links: Open Flash from a browser or another app with a prompt ready to go (flash://?prompt=What+is+Python).
  • Image Recognition: Send a local image to a vision-capable model with /image <path> [prompt], or let the AI open one itself with its view_image tool.
  • Page Screenshots: The AI renders a page it built in a headless browser with its screenshot tool and looks at the result, so it can see a broken layout instead of guessing from the HTML.
  • Page Control: The AI opens a page with open_page and then clicks buttons, fills forms, presses keys, and runs JavaScript on it with interact, seeing a fresh screenshot, the page's elements, and its console errors after every step, so it can debug what a page does, not just how it looks.
  • Voice Mode: /voice on downloads a Vosk speech model and a Piper voice, then lets you talk to Flash and hear its replies, with typing still available at any time.
  • Context Management: Automatic history trimming to stay within token limits.
  • Markdown Support: Rich formatting for AI responses in the terminal.

Installation

Quick install (pipx)

Install Flash with a single command. The script clones this repo into a temporary directory, installs it with pipx, and cleans up after itself:

curl -fsSL https://raw.githubusercontent.com/Natuworkguy/Flash/main/install.sh | bash

Once installed, run it with:

flash

To uninstall:

curl -fsSL https://raw.githubusercontent.com/Natuworkguy/Flash/main/install.sh | bash -s -- --uninstall

Or, if you already have the repo cloned locally:

./install.sh --uninstall

Manual install

  1. Clone the repository:

    git clone https://github.com/Natuworkguy/Flash
    cd Flash
  2. Install dependencies:

    pip install -r requirements.txt
  3. Install and start Ollama:

    Flash talks to an Ollama server. Install Ollama, start it, and pull a model that supports tool calling:

    ollama pull llama3.1

    By default, Flash connects to a local server at http://localhost:11434. To use a remote server, set OLLAMA_HOST (see Configuration).

Flash Onyx (recommended model)

Flash Onyx is a series of custom Ollama models built for Flash: a base model with Flash's persona and tuned parameters baked in. Each one lives in a single Modelfile under models/ that declares its name and sizes at the top, and models/build.py builds whatever a Modelfile declares.

The current release, Flash Onyx 2, is gemma4 in two sizes. 12b runs on consumer hardware; 31b is the flagship and wants a bigger GPU.

python3 models/build.py models/flash-onyx-2.Modelfile             # every size
python3 models/build.py models/flash-onyx-2.Modelfile --size 31b  # just one

Flash Onyx 1 is the previous release, built on llama3.1:

python3 models/build.py models/flash-onyx-1.Modelfile

Then set MODEL to whichever you built (flash-onyx-2:31b, flash-onyx-1, and so on) in ~/.flash.env or your environment.

Run

python3 run.py

Configuration

FLASH CLI is configured through environment variables. You can create a .flash.env file in your home directory:

MODEL=llama3.1
OLLAMA_HOST=http://localhost:11434

Environment Variables

See docs/CONFIGURATION.md.

Switching servers

  • Local (default): leave OLLAMA_HOST unset, or set it to http://localhost:11434.
  • Remote server: set OLLAMA_HOST to the other machine, e.g. OLLAMA_HOST=http://192.168.1.50:11434 or OLLAMA_HOST=https://ollama.example.com.

Make sure the target server is reachable and that MODEL has been pulled on it.

Usage

Start the CLI by running:

python run.py

Internal Commands

  • /help or /?: Display the help message.
  • /model: Show the currently active model and Ollama host.
  • /clear: Clear the conversation history.
  • /image <path> [prompt]: Send a local image to the model.
  • /version: Show the current version and check GitHub for updates.
  • /update: Update Flash to the latest version (requires pipx).
  • /bye: Exit the application.

Image Recognition

/image <path> [prompt] attaches a local image (.png, .jpg, .jpeg, .webp, .gif, .bmp) to your next message and sends both to the model. If you leave off the prompt, Flash asks it to describe the image. This requires a vision-capable model text-only models will ignore the image or error. Pull one and switch to it first, e.g.:

ollama pull llama3.2-vision

Flash Onyx 2+ is vision capable.

/model llama3.2-vision
/image ~/Pictures/screenshot.png What's going on in this UI?

The model can also open an image on its own with the view_image tool, so you can just name the file in a normal message and let it look:

Why does the legend in ~/Desktop/plot.png overlap the bars?

It accepts the same file types (up to 20 MB) and sees the image for that turn only, calling view_image again later if it needs another look.

Voice mode

/voice on turns Flash into something you can talk to. The first time it runs it downloads the two models it needs into ~/.flash/models: a Vosk speech-recognition model for listening (about 40 MB) and a Piper voice for speaking (about 60 MB). After that everything runs locally, with no audio leaving the machine.

/voice on

With voice mode on, press Enter on an empty prompt to start talking. Flash records until you stop, prints what it heard, and sends it as your message; the reply is printed as usual and read aloud. It then listens again on its own, so a conversation carries on hands-free with no keypress between turns. Say nothing for eight seconds (VOICE_NO_SPEECH_SECONDS), or press Ctrl+C, and it hands the prompt back. Typing works exactly as before, so slash commands and long paths can still be typed rather than dictated.

Say "interrupt" while Flash is talking and it stops mid-sentence and listens for what you say next, so you never have to sit through an answer that started off wrong. "stop talking" and "be quiet" work too, as does Ctrl+C, and the word can be changed with VOICE_INTERRUPT_WORD. It is matched as a whole word, so "the interrupted process" is just a message.

Say "voice off" (or "stop listening", "exit voice mode") to end the conversation. That hands the prompt back but leaves voice mode armed, so pressing Enter starts talking again without re-enabling anything. To turn the feature off altogether, type /voice off; the setting is saved in ~/.flash.env as VOICE, so voice mode survives a restart either way.

Only the prose of a reply is spoken. Code blocks, tables, and URLs are skipped, because they are on screen already and unpleasant to listen to, and a long answer is cut at a sentence once it passes VOICE_MAX_CHARS. Flash also tells the model that it is being heard rather than read, so replies in voice mode come back shorter and plainer.

Voice mode needs three extra packages: vosk, piper-tts, and sounddevice. install.sh and install.ps1 install them for you, so this is only needed if you installed Flash some other way. Flash installed with pipx keeps its own environment, so the packages go in with inject:

pipx inject flash vosk piper-tts sounddevice

For a plain pip install of Flash it is the extra instead:

pip install "flash[voice]"

/voice on prints whichever of the two commands fits your install. On Linux sounddevice also needs PortAudio from the system (apt install libportaudio2); the macOS and Windows wheels bundle it. The voice and the listening model can be swapped with VOICE_PIPER_VOICE and VOICE_VOSK_MODEL, and the microphone's sensitivity tuned with VOICE_SILENCE_THRESHOLD; see docs/CONFIGURATION.md.

Page screenshots

The screenshot tool renders a local .html file or a URL in a headless Chromium and attaches the picture, so a vision-capable model can check what it built rather than trusting its own source:

Build me a pricing page in ~/Desktop/pricing.html, then check how it
looks on a phone.

It takes a viewport width and height, captures the whole scrollable page with full_page, and reports any JavaScript errors the page threw while rendering, which is usually what explains a section that came out empty.

Clicking through a page

A screenshot is a still picture, so for a page with buttons or a form the AI opens it with open_page and then drives it with interact, one action per call:

Open ~/Desktop/signup.html, fill in the form, submit it, and tell me why
the confirmation never shows up.

The browser stays open between calls, so the page keeps its state while the AI works through a flow. interact takes an action (click, fill, press, hover, select, scroll, wait, eval, back, reload, close) and a selector, which can be the number Flash prints beside each element, a CSS selector, or the text on the element itself. Every call answers with where the page is now, what can be clicked or typed into next, and the JavaScript errors the page threw, with a screenshot attached. The eval action runs JavaScript against the live page and returns the result, which is how the AI inspects state a picture cannot show.

Both tools need Playwright's Chromium, which install.sh and install.ps1 download for you. Installing Flash another way means running it yourself:

playwright install chromium

Updates

Flash checks main on GitHub for a newer version on startup and shows it in the banner if one is available. Run /version anytime to check on demand, or /update to install it. Flash re-runs the same pipx-based steps install.sh uses, so it needs pipx on PATH. If you cloned the repo manually, update with git pull instead.

You can also check and update from outside the REPL:

flash --update          # check for a newer version and, if found, confirm and install it
flash --update --force  # reinstall from `main` unconditionally, no confirmation

Direct Shell Execution

You can run shell commands directly without AI intervention:

  • !ls -la
  • !git status
  • !echo "Hello"

flash:// Links

Flash can open from a link. install.sh and install.ps1 register the handler for you; after a manual install, register it once yourself:

flash --register-url-scheme

Then a link like flash://?prompt=What+is+Python starts a Flash session with that prompt queued. Pass the same URL on the command line to test it without a browser:

flash "flash://?prompt=What+is+Python"

The prompt is URL-encoded, so use + or %20 for spaces. Flash always shows the prompt and asks before sending it to the model. Any web page can open a flash:// link, so nothing runs unattended. For the same reason, URL prompts may not start with / or !: they carry questions for the model, never Flash commands or shell escapes.

To remove the handler (the uninstallers do this too):

flash --unregister-url-scheme

Registration is per-user: it writes HKCU\Software\Classes\flash on Windows and ~/.local/share/applications/flash-url.desktop on Linux/BSD. It cannot be installed on macOS, which resolves URL schemes from application bundles only. Passing a flash:// URL on the command line still works everywhere.

AI Interaction

Simply type your request. If the AI needs to see the contents of a file or run a command to answer your question, it can invoke the shell tool automatically. It can also look at an image file with the view_image tool, search the web via Duck Duck Go, and show it's reasoning.

License

The Flash CLI, the Modelfiles under models/, and the system prompts in them are MIT licensed. See LICENSE.

A published Flash Onyx model is a derivative of the base model it is built on, and that base license travels with it. The MIT license above covers the Modelfile and the prompt, not the weights underneath:

  • Flash Onyx 2.x is built on gemma4, which Ollama ships under the Apache License 2.0.
  • Flash Onyx 1 is built on llama3.1, which ships under the Llama 3.1 Community License. Its terms include a naming requirement for any derivative model you distribute.

models/build.py copies this repository's LICENSE into every model it builds, together with a pointer to the base model's own terms, so ollama show --license flash-onyx-2.2:12b prints both. Check the base model's license with ollama show --license gemma4 before publishing a build.

About

An AI-powered command-line interface that bridges natural language and shell execution.

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages