Compare commits

...

2 Commits

Author SHA1 Message Date
mike
f906e6666a -init-
Some checks failed
Docker Build and Push / build-and-push (push) Failing after 10s
Tests / test (bash) (push) Failing after 9s
Tests / test (zsh) (push) Failing after 10s
Tests / lint (push) Successful in 8s
Tests / docker (push) Successful in 6s
2025-12-11 09:14:52 +01:00
mike
3cb1b57ac5 all 2025-12-11 08:48:13 +01:00
4 changed files with 114 additions and 269 deletions

72
ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,72 @@
User Input (Tab×2 or CLI)
┌───────────────────────────────────────┐
│ Entry Points │
├───────────────────────────────────────┤
│ • _finishsh() - Tab completion │
│ • command_command() - CLI mode │
└───────────────┬───────────────────────┘
┌───────────────────────────────────────┐
│ Configuration Layer │
├───────────────────────────────────────┤
│ acsh_load_config() │
│ • Read ~/.finish/config │
│ • Set ACSH_PROVIDER, ACSH_ENDPOINT │
│ • Set ACSH_ACTIVE_API_KEY (if needed) │
└───────────────┬───────────────────────┘
┌───────────────────────────────────────┐
│ Cache Layer │
├───────────────────────────────────────┤
│ • Check cache_dir/acsh-{hash}.txt │
│ • Return cached completions if exists │
└───────────────┬───────────────────────┘
↓ (cache miss)
┌───────────────────────────────────────┐
│ Context Builder │
├───────────────────────────────────────┤
│ _build_prompt() │
│ • Command history (sanitized) │
│ • Terminal info (env vars, cwd) │
│ • Recent files (ls -ld) │
│ • Help message (cmd --help) │
└───────────────┬───────────────────────┘
┌───────────────────────────────────────┐
│ Payload Builder │
├───────────────────────────────────────┤
│ _build_payload() │
│ • Format: {model, messages, temp} │
│ • Provider-specific options: │
│ - Ollama: {format:"json"} │
│ - LMStudio: {stream:true} │
│ - OpenAI: {response_format} │
└───────────────┬───────────────────────┘
┌───────────────────────────────────────┐
│ LLM Provider Layer │
├───────────────────────────────────────┤
│ openai_completion() │
│ • curl to endpoint │
│ • Ollama: no auth header │
│ • Others: Authorization header if key │
│ • Parse response (JSON/streaming) │
└───────────────┬───────────────────────┘
┌───────────────────────────────────────┐
│ Response Parser │
├───────────────────────────────────────┤
│ • Extract completions array │
│ • Fallback parsing for non-JSON │
│ • Filter command-like lines │
└───────────────┬───────────────────────┘
┌───────────────────────────────────────┐
│ Output Layer │
├───────────────────────────────────────┤
│ • Write to cache │
│ • Log usage (tokens, cost) │
│ • Return COMPREPLY array (completion) │
│ • or stdout (CLI mode) │
└───────────────────────────────────────┘

View File

@@ -26,7 +26,7 @@ RUN apt-get update && \
WORKDIR /opt/finish
# Copy application files
COPY finish.sh /usr/bin/finish
COPY src/finish.sh /usr/bin/finish
COPY README.md LICENSE ./
# Make script executable

307
README.md
View File

@@ -1,300 +1,73 @@
```markdown
# finish.sh
Command-line completion powered by local LLMs. Press `Tab` twice and get intelligent suggestions based on your terminal context.
AI-powered shell completion that runs 100 % on your machine.
## Quick Start
One command and your terminal learns what you type next.
### One-Line Install (Recommended)
## Install
```bash
curl -sSL https://git.appmodel.nl/tour/finish/raw/branch/main/docs/install.sh | bash
source ~/.bashrc # or ~/.zshrc
```
### Manual Installation
Press `Tab` twice on any partial command and finish.sh suggests the rest—no cloud, no data leak, no latency.
## How it works
1. Captures your current directory, recent history, env vars.
2. Builds a concise prompt for a local LLM (LM-Studio, Ollama, or any OpenAI-compatible endpoint).
3. Returns ranked completions in <200 ms, cached for instant replay.
## Use
```bash
git clone https://git.appmodel.nl/tour/finish.git finish
cd finish
./finish.sh install
source ~/.bashrc
docker <Tab><Tab> # → docker run -it --rm ubuntu bash
git commit <Tab><Tab> # → git commit -m "feat: add finish.sh"
# large files <Tab><Tab> # → find . -type f -size +100M
```
### Other Installation Methods
See [Installation](#installation) below for package managers, Docker, and more options.
## What It Does
finish.sh enhances your terminal with context-aware command suggestions. It analyzes:
- Current directory and recent files
- Command history
- Environment variables
- Command help output
Then generates relevant completions using a local LLM.
## Features
**Local by Default**
Runs with LM-Studio on localhost. No external API calls, no data leaving your machine.
**Context-Aware**
Understands what you're doing based on your environment and history.
**Cached**
Stores recent queries locally for instant responses.
**Flexible**
Switch between different models and providers easily.
## Configuration
View current settings:
Dry-run mode:
```bash
finish config
finish --dry-run "tar czf backup.tar.gz"
```
Change the endpoint or model:
## Configure
```bash
finish config set endpoint http://plato.lan:1234/v1/chat/completions
finish config set model your-model-name
```
Select a model interactively:
```bash
finish model
```
## Usage
Type a command and press `Tab` twice:
```bash
docker <TAB><TAB>
git commit <TAB><TAB>
ffmpeg <TAB><TAB>
```
Natural language works too:
```bash
# find large files <TAB><TAB>
# compress to zip <TAB><TAB>
```
Test it without executing:
```bash
finish command "your command"
finish command --dry-run "your command"
```
## Installation
### Quick Install (Linux/macOS)
The fastest way to get started:
```bash
curl -sSL https://git.appmodel.nl/tour/finish/raw/branch/main/docs/install.sh | bash
source ~/.bashrc # or ~/.zshrc for zsh
finish model
```
### Package Managers
#### Homebrew (macOS)
```bash
brew tap appmodel/finish
brew install finish
finish install
source ~/.bashrc
```
#### APT (Debian/Ubuntu)
Download the `.deb` package from [releases](https://git.appmodel.nl/tour/finish/releases):
```bash
sudo dpkg -i finish_*.deb
sudo apt-get install -f # Install dependencies
finish install
source ~/.bashrc
```
### Docker
Run finish.sh in a container:
```bash
# Build the image
docker build -t finish .
# Run interactively
docker run -it finish
# Or use docker-compose
docker-compose up -d finish
docker-compose exec finish bash
```
Inside the container:
```bash
finish install
source ~/.bashrc
finish model # Configure your LLM endpoint
```
### From Source
```bash
git clone https://git.appmodel.nl/tour/finish.git finish
cd finish
chmod +x finish.sh
sudo ln -s $PWD/finish.sh /usr/local/bin/finish
finish install
source ~/.bashrc
```
## Requirements
- Bash 4.0+ or Zsh 5.0+
- curl
- jq
- bc
- bash-completion (recommended)
- LM-Studio or Ollama (for LLM inference)
## Directory Structure
```
~/.finish/
├── config # Configuration file
├── finish.log # Usage log
└── cache/ # Cached completions
```
## Commands
```bash
finish install # Set up finish
finish remove # Uninstall
finish config # Show/edit configuration
finish model # Select model
finish enable # Enable completions
finish disable # Disable completions
finish clear # Clear cache and logs
finish usage # Show usage statistics
finish system # Show system information
finish --help # Show help
finish config set endpoint http://plato.lan:11434/v1/chat/completions
finish config set model codellama:13b
finish model # interactive picker
```
## Providers
Currently supports:
| Provider | Auth | URL | Notes |
|-----------|------|-----------------------------|---------|
| LM-Studio | none | `http://localhost:1234/v1` | default |
| Ollama | none | `http://localhost:11434` | |
| OpenAI | key | `https://api.openai.com/v1` | |
- **LM-Studio** (default) - Local models via OpenAI-compatible API
- **Ollama** - Local models via Ollama API
Add others by editing `~/.finish/config`.
Add custom providers by editing `finish.sh` and adding entries to `_finish_modellist`.
## Development
### Local Development
Clone and link for development:
## Commands
```bash
git clone https://git.appmodel.nl/tour/finish.git finish
cd finish
ln -s $PWD/finish.sh $HOME/.local/bin/finish
finish install
finish install # hook into shell
finish remove # uninstall
finish clear # wipe cache & logs
finish usage # tokens & cost
```
### Running Tests
## Requirements
```bash
# Install BATS testing framework
sudo apt-get install bats # Ubuntu/Debian
# Run tests
./run_tests.sh
# Or use Docker
docker build -f Dockerfile.test -t finish:test .
docker run --rm finish:test
```
### Building Packages
#### Debian Package
```bash
# Install build dependencies
sudo apt-get install debhelper devscripts
# Build the package
dpkg-buildpackage -us -uc -b
# Package will be created in parent directory
ls ../*.deb
```
#### Docker Images
```bash
# Production image
docker build -t finish:latest .
# Test image
docker build -f Dockerfile.test -t finish:test .
# Using docker-compose
docker-compose build
```
## Distribution & Publishing
### Creating a Release
1. Update version in `finish.sh` (ACSH_VERSION)
2. Update version in `debian/changelog`
3. Update version in `homebrew/finish.rb`
4. Create and push a git tag:
```bash
git tag -a v0.5.0 -m "Release version 0.5.0"
git push origin v0.5.0
```
This triggers the GitHub Actions workflow which:
- Builds release artifacts
- Creates Debian packages
- Publishes Docker images to GitHub Container Registry
- Creates a GitHub release with downloadable assets
### Homebrew Formula
After creating a release, update the Homebrew formula:
1. Calculate SHA256 of the release tarball:
```bash
curl -sL https://git.appmodel.nl/tour/finish/archive/v0.5.0.tar.gz | sha256sum
```
2. Update `homebrew/finish.rb` with the new SHA256 and version
3. Submit to your Homebrew tap or the main Homebrew repository
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Bash ≥4 or Zsh ≥5, curl, jq, bc.
Optional: bash-completion.
## License
BSD 2-Clause License. See LICENSE file.
BSD 2-Clause.
```

2
finish.sh → src/finish.sh Normal file → Executable file
View File

@@ -1,6 +1,6 @@
#!/bin/bash
###############################################################################
# Enhanced Error Handling #
# -ver 1- Enhanced Error Handling #
###############################################################################
error_exit() {