A command-line tool (and GUI wrapper) that sends text prompts to AI models and returns AI-generated responses.
This workspace contains two binaries:
- gia - Command-line interface
- giagui - GUI wrapper for gia
- Uses command line arguments as the main prompt
- Roles & Tasks - Load AI role definitions and task instructions from markdown files
- Audio recording - Record audio prompts natively with
-aflag, or push-to-talk with-A(hold SPACE to talk); no external dependencies - Smart file support - Include any files or directories
-fflag: Automatically detects media files (JPEG, PNG, WebP, HEIC, PDF, OGG, OPUS, MP3, M4A, MP4) vs text files- Supports directories (processes all files recursively with auto-detection)
- Optional additional input from clipboard or stdin (auto-detects text vs images)
- Output responses to stdout (default) or clipboard
- Persistent conversation history with resume capability
- Multi-API key support with automatic fallback
- Comprehensive logging to stderr
- Simple and fast CLI interface
📊 View Input/Output Flow Diagram - Visual overview of all input sources and output destinations
First add the tap with:
brew tap panjamo/gia
and then install with:
brew install gia
Update with:
brew upgrade gia
Uninstall with:
brew uninstall gia
Remove the tap with:
brew untap gia
For more information on Homebrew, visit:
brew help, man brew or check Homebrew's documentation.
Download the .pkg file according your macOS architecture from the releases page and install it.
tbd
-
Clone this repository
-
Install Rust if you haven't already
-
Build the project:
# Build both binaries cargo build --release # Or build specific binaries cargo build --release -p gia # CLI only cargo build --release -p giagui # GUI only
Binaries will be located at:
target/release/gia(orgia.exeon Windows)target/release/giagui(orgiagui.exeon Windows)
Set your API key as an environment variable:
export GEMINI_API_KEY="your_api_key_here"On Windows:
set GEMINI_API_KEY=your_api_key_hereFor automatic fallback on rate limits, set multiple keys separated by pipe (|):
export GEMINI_API_KEY="key1|key2|key3"To get an API key, visit: https://makersuite.google.com/app/apikey
Install and start Ollama from https://ollama.ai, then use the -m flag:
gia -m "ollama::llama3.2" "your prompt here"Configure the default AI model (default: gemini-2.5-flash-lite):
# Set default model globally
export GIA_DEFAULT_MODEL="gemini-2.5-pro"
# Use Ollama model as default
export GIA_DEFAULT_MODEL="ollama::llama3.2"Windows:
set GIA_DEFAULT_MODEL=gemini-2.5-pro
set GIA_DEFAULT_MODEL=ollama::llama3.2Configure the context window limit (default: 8000):
export CONTEXT_WINDOW_LIMIT=10000GEMINI_API_KEY- Gemini API key(s), pipe-separated for fallback:key1|key2|key3GIA_DEFAULT_MODEL- Default AI model (default:gemini-2.5-flash-lite)GIA_AUDIO_DEVICE- Default audio input device for recordingCONTEXT_WINDOW_LIMIT- Context window size limit (default: 8000)RUST_LOG- Logging level:debug,info,error(outputs to stderr)GIA_LOG_TO_FILE- Enable per-conversation file logging:1
gia --help # Full help with all options and examples
gia -h # Short help with basic usageGIA automatically combines input from multiple sources:
- Command line: Main prompt (required, except when using
-aalone) - Audio recording: With
-aflag (native recording), or-Afor push-to-talk (hold SPACE); no external dependencies - Stdin: Automatically detected when piped
- Clipboard: With
-cflag only - Text files: With
-fflag (any extension) - Files: With
-fflag (auto-detects media vs text files) - Output: Response written to stdout (default)
The GUI provides a simple interface to interact with GIA:
Features:
- Multi-line prompt input
- Custom options field
- Clipboard input toggle (
-c) - Browser output toggle (
--browser-output) - Auto-resume conversations after first prompt
- Response display with copy to clipboard
- Show conversation in browser (Ctrl+O)
- Audio recording support (Ctrl+R)
Keyboard Shortcuts:
- Ctrl+Enter: Send prompt
- Ctrl+R: Send with audio recording
- Ctrl+L: Clear form
- Ctrl+Shift+C: Copy response to clipboard
- Ctrl+O: Show conversation in browser
- F1: Show help
Requirements:
giamust be installed and available in PATH
Running:
cargo run -p giagui
# or after building
./target/release/giagui# Direct AI questions:
gia "What is artificial intelligence?"
gia "Explain quantum computing"
# With roles/tasks:
gia -t rust-dev "Explain this code" -c
gia -t code-review -t security-audit "Review this PR"
# Audio recording (auto-generates prompt):
gia --record-audio
gia -a # Short option
# Push-to-talk recording (hold SPACE to talk, release to pause, ENTER to finish, ESC to cancel):
gia --record-audio-ptt
gia -A # Short option
gia -A --role EN --no-save # Push-to-talk transcription only
# Audio recording with custom prompt:
gia --record-audio "Transcribe and summarize this audio"
# Audio recording with specific device:
gia --list-audio-devices # List available devices
gia --audio-device "Microphone Array" --record-audio # Use specific device
GIA_AUDIO_DEVICE="Microphone Array" gia --record-audio # Use env var
# Audio recording with custom dialog text (URL-encoded, %0A = newline):
gia --record-audio --audio-dialog-text "Please%20speak%20your%20command%0APress%20Yes%20when%20done"
# Transcribe-only mode (no conversation history saved):
gia --record-audio --role EN --no-save # English transcription only
gia --record-audio --role DE --no-save # German transcription only
gia "Transcribe this" --record-audio --no-save # Custom prompt transcription
# With clipboard input:
gia "Summarize this text" -c
# With stdin input (automatic):
echo "data to process" | gia "Analyze this data"# Create role/task files:
# ~/.gia/roles/rust-dev.md - AI persona definitions
# ~/.gia/tasks/code-review.md - Specific task instructions
# Use roles/tasks (searches roles/ first, then tasks/):
gia -t rust-dev "Optimize this function" -c
gia -t code-review -t security-audit "Review changes"# Add clipboard content to prompt:
gia "Explain this code" -c
# Stdin is automatically detected:
echo "machine learning data" | gia "Analyze this"
# Combine stdin and clipboard:
echo "extra context" | gia "Main question about this topic" -c
# Include text files:
gia "Summarize these documents" -f doc1.txt -f doc2.txt
# Include entire directories (processes all files recursively):
gia "Analyze the codebase" -f src/
gia "Review all documentation" -f docs/ -f README.md
# Include audio/video files (auto-detected as media):
gia "Transcribe this recording" -f meeting.mp3
gia "What is discussed in this video?" -f presentation.mp4
# Combine multiple input sources (auto-detection):
gia "Analyze code, docs, and diagram" -f README.md -f main.rs -f diagram.png
gia "Analyze audio and images" -f recording.mp3 -f screenshot.png# Analyze a single image (auto-detected):
gia "What do you see in this image?" -f photo.jpg
# Compare multiple images (auto-detected):
gia "What are the differences between these images?" -f image1.jpg -f image2.png
# Analyze image from clipboard (copy image first):
gia "What do you see in this image?" -c
# Combine file image with clipboard text:
gia "Explain this diagram" -f diagram.png -c
# Mix clipboard image with additional text prompt:
gia "Describe the technical aspects of this screenshot" -c
# Image with stdin input:
echo "Focus on the technical aspects" | gia "Analyze this screenshot" -f screenshot.png# Default stdout output:
gia "What is machine learning?"
# Output to clipboard instead:
gia "Write a poem about coding" -o
# Output to file (~/.gia/outputs/) AND open browser preview:
gia "Generate markdown documentation" -b
# Output raw markdown (skip plain-text conversion, useful for piping):
gia "Write a summary" -M
gia "Write a summary" --markdown
# With additional input and clipboard output:
gia "Translate to Spanish" -c -oConversations are saved in ~/.gia/conversations/ with consistent naming:
- JSON:
conversation-slug-abc1.json - Markdown:
conversation-slug-abc1.md - Output files:
conversation-slug-abc1_20250107_143022.md
# Resume latest conversation:
gia --resume "continue our discussion"
gia -R "continue our discussion" # Short option
# Resume by index (from -l list), ID, or hash:
gia --resume 0 "continue" # Index 0 = newest conversation
gia --resume 2 "follow up" # Index 2 from list
gia --resume conversation-slug-abc1 "follow up"
gia --resume abc1 "follow up" # Match by 4-char hash
# List all saved conversations (tabular output):
gia --list-conversations
gia -l 5 # List top 5 conversations
gia -l # List all conversations
# Display conversation (follows normal output options):
gia -s # Show latest conversation (stdout)
gia -s 0 # Show newest (index 0)
gia -s abc1 # Show by hash (stdout)
gia -s -o # Show latest conversation (clipboard)
gia -s -b # Show latest conversation (file + browser)[PROMPT_TEXT]- Prompt text for the AI (main input)-t, --role <NAME>- Load role/task from ~/.gia/roles/ or ~/.gia/tasks/ (can be used multiple times)-a, --record-audio- Record audio input natively (auto-generates prompt if no text provided)-A, --record-audio-ptt- Push-to-talk recording: hold SPACE to talk, release to pause, ENTER to finish, ESC to cancel (macOS: needs Input Monitoring permission)--audio-device <DEVICE>- Specify audio input device for recording (overrides GIA_AUDIO_DEVICE)--audio-dialog-text <TEXT>- URL-encoded text shown before the recording confirmation dialog (e.g.Hello%0AWorldfor newlines)--list-audio-devices- List all available audio input devices and exit-c, --clipboard-input- Add clipboard content to prompt (auto-detects images vs text)-f, --file <FILE_OR_DIR>- Add file or directory to prompt (auto-detects media vs text; directories processed recursively)-o, --clipboard-output- Write response to clipboard instead of stdout-b, --browser-output- Write output to file (~/.gia/outputs/, path copied to clipboard) AND open browser preview-M, --markdown- Output raw markdown to stdout (skip plain-text conversion, useful for piping to markdown renderers)-r, --resume [ID]- Resume last conversation or specify conversation ID-R- Resume the very last conversation-l, --list-conversations [NUMBER]- List saved conversations (optionally limit number)-s, --show-conversation [ID]- Show conversation (follows output options: stdout/clipboard/file+browser)-m, --model <MODEL>- Specify model (default: gemini-2.5-flash-lite)--no-save- Don't save to conversation history (transcribe-only mode)- Gemini models: see https://ai.google.dev/gemini-api/docs/models
- Ollama models: use
ollama::model-nameformat (e.g.,ollama::llama3.2)
Device selection follows this priority (highest to lowest):
--audio-deviceCLI parameterGIA_AUDIO_DEVICEenvironment variable- Default system audio input device
Logging is written to stderr with different levels:
- Set
RUST_LOG=debugfor detailed logs - Set
RUST_LOG=infofor general information - Set
RUST_LOG=errorfor errors only
Example:
RUST_LOG=debug gia -p "Hello world"# Direct questions:
gia "What are the benefits of using Rust?"
gia "How does machine learning work?"
gia "Write a haiku about programming"# Copy code to clipboard first, then:
gia "Explain this Rust code" -c
# Or pipe code via stdin:
echo "fn main() { println!('Hello'); }" | gia "Explain this Rust code"# Copy text to clipboard first, then add it to your prompt:
gia "Summarize this text" -c
gia "Translate to Spanish" -c
gia "Fix any errors in this code" -c
# Output to clipboard instead of stdout:
gia "Rewrite this professionally" -c -otokio- Async runtimegenai- AI API client (Gemini, Ollama)serde- JSON serializationclap- Command line parsinganyhow- Error handlinglog+env_logger- Loggingarboard- Clipboard operations (text and images)image- Image processing and PNG conversionwebbrowser- Browser openingcomrak- Markdown to HTML renderingbase64- Base64 encoding for data URLs
MIT License