Skip to main content

Inzen CLI Bot

PyPI Downloads PyPI Version Python Version

Building a Windows Executable & Installer

To create a standalone Windows EXE and one-click installer:

  1. Build the EXE:
  • Install PyInstaller: pip install pyinstaller
  • Run the build script: build_exe.bat
  • The EXE will appear in the dist/ folder.
  1. Create an Installer (optional):
  • Use Inno Setup or NSIS to package the EXE and any required files.
  • See installer.iss.example for a sample Inno Setup script (if present).

Note: The EXE includes Python and all dependencies—no Python install required for users.

Building Linux .deb and .rpm Packages

nfpm works cross-platform, so you can build Linux packages from Windows, macOS, or Linux without a VM.

1. Install nfpm (one-time)

Windows (PowerShell) — choose one:

# Scoop
scoop install nfpm

# Chocolatey
choco install nfpm

# winget
winget install GoReleaser.nfpm

# Direct download (no package manager required)
$tag = "v2.43.2"
$url = "https://github.com/goreleaser/nfpm/releases/download/$tag/nfpm_Windows_x86_64.zip"
Invoke-WebRequest $url -OutFile "$env:TEMP\nfpm.zip"
Expand-Archive "$env:TEMP\nfpm.zip" -DestinationPath "$env:LOCALAPPDATA\nfpm" -Force
$env:PATH += ";$env:LOCALAPPDATA\nfpm"  # add permanently via System Properties > Environment Variables

Linux / macOS:

# Homebrew
brew install nfpm

# Direct binary
curl -sfL https://install.goreleaser.com/github.com/goreleaser/nfpm.sh | sh

2. Build the packages

Windows (PowerShell):

.\build_linux_packages.ps1

Linux / macOS:

./build_linux_packages.sh

This produces:

  • dist/linux/inzen-bot_<version>_<arch>.deb
  • dist/linux/inzen-bot_<version>_<arch>.rpm

The packages install the standalone binary under /opt/inzen-cli-bot/, expose both bot and inzen_cli_bot on the system PATH, include the project docs under /usr/share/doc/inzen-cli-bot/, and print a post-install reminder to run bot --setup.

On Git tags matching v*, GitHub Actions builds and attaches all release installers to the matching GitHub Release automatically:

  • Windows standalone EXE
  • Windows installer EXE
  • Linux .deb
  • Linux .rpm

Inzen CLI Bot one-shot response with token usage footer

No browser. No switching apps. Just ask and keep working.

Contents


Security & Secrets

  • Never commit real API keys or secrets. Only .env.example should be public.
  • The .gitignore excludes .env, .venv/, and build artifacts by default.


Features


Code Style

  • Use ruff for linting: uv run ruff check .
  • Use black for formatting: uv run black .
  • Add type hints to all functions.
  • Named sessions — keep separate threads for different projects, all stored locally
  • Interactive REPLbot --chat for a persistent conversation without re-typing flags
  • Token & cost tracking — per-message footer and a bot --usage summary table across all providers
  • Session export — dump any session to markdown or plain text
  • Secure by default — local data files are user-only (600/700), session names are validated against path traversal

Install

pip install inzen-bot

Or with uv:

uv add inzen-bot

Setup

1. Run interactive setup (recommended)

bot --setup

This wizard will:

  • Ask which providers you want to use
  • Ask for model/base URL where needed
  • Store API keys securely in your OS keyring (when available)
  • Save provider settings to ~/.bot/config.json

2. Or set API keys manually

Inzen CLI Bot reads your API keys from environment variables.

Linux / macOS — add to your ~/.bashrc or ~/.zshrc:

export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."        # optional

Then reload:

source ~/.bashrc

Windows (PowerShell) — set permanently:

[System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-...", "User")

Restart your terminal after running this.

For Ollama and llama.cpp no API key is needed — just make sure the local server is running before use.

2. Verify it works

bot hello

You should see a streamed response from Claude with a token usage footer. If you get an error, check your API key:

# Linux / macOS
echo $ANTHROPIC_API_KEY

# Windows PowerShell
echo $env:ANTHROPIC_API_KEY

Usage

Ask anything — history is automatic so you can follow up naturally:

bot how do I format a drive in Ubuntu?
bot step 2?
bot step 3?

Conversation history showing colour-coded USER and ASSISTANT turns

Common flags:

# Use a specific provider for one query
bot --provider openai explain RAID levels

# Run setup wizard again
bot --setup

# Update from latest GitHub release
bot --update

# Set local-provider endpoints without editing config.json
bot --set-ollama-url http://localhost:11434
bot --set-llamacpp-url http://localhost:8080

# See API key status (keyring/env)
bot --credentials-list

# Update or remove a stored API key
bot --credentials-update anthropic
bot --credentials-remove anthropic

# Switch default provider permanently
bot --set-provider ollama

# Switch model
bot --set-model claude-opus-4-5

# Toggle insecure remote HTTP provider endpoints in config
bot --allow-insecure-http
bot --no-allow-insecure-http

# View conversation history
bot --history

# Purge data older than the configured retention window
bot --purge

# Clear history
bot --clear

# List all configured providers
bot --providers

# Override the system prompt for one query
bot --system "You are a Python expert" explain decorators

# Redact likely secrets in history/export output
bot --history --redact-secrets

# Export outside safe directories (disabled by default for safety)
bot --export myproject --output /tmp/myproject.md --unsafe-output

bot --update checks the latest GitHub release and updates in place for Python installs, Linux .deb/.rpm package installs, and Windows installer-based installs.


Interactive Mode

Use --chat for a persistent REPL — no need to retype flags between messages.

# Start a persistent chat session
bot --chat

# Start with an opening message, then continue the conversation
bot --chat explain how systemd services work

# Use a named session in interactive mode
bot --session myproject --chat

Inside the chat session the following slash commands are available:

Command Description
/help Show available commands
/history Print the conversation so far
/clear Clear conversation history for this session
/exit Exit chat mode (also: /quit, q)

Interactive chat REPL showing multi-turn conversation and /help output


Named Sessions

Named sessions let you maintain separate, persistent conversation threads — useful for keeping different projects or topics isolated.

# Start or continue a named session
bot --session myproject what is a venv

# Pick up where you left off
bot --session myproject how do I activate it

# List all saved sessions
bot --sessions

# Export a session to markdown
bot --export myproject

# Export to a file
bot --export myproject --output myproject.md

# Delete a session
bot --clear-session myproject

Sessions are stored as JSON files in ~/.bot/sessions/ and are independent of provider — you can switch providers mid-session.

Session list showing provider, message count, and preview

Session export to markdown


Token Usage

Every response includes a per-message token and cost footer. Run bot --usage to see cumulative totals across all providers:

Token usage summary across multiple providers

# View cumulative usage across all providers
bot --usage

Providers

Provider Requires Notes
anthropic ANTHROPIC_API_KEY Default. Claude models.
openai OPENAI_API_KEY GPT models. Also works for Groq, Together, etc.
ollama Ollama running Local inference. Free to run.
llamacpp llama.cpp running Local inference via OpenAI-compatible server.

Configured providers list with active provider marked

Ollama quickstart

# Install from https://ollama.ai, then:
ollama pull llama3
ollama serve
bot --set-provider ollama
bot hello from the terminal

llama.cpp quickstart

# Build llama.cpp from https://github.com/ggerganov/llama.cpp, then run the server:
./server -m your-model.gguf --port 8080
bot --set-provider llamacpp
bot what is quantisation

Using Groq or other OpenAI-compatible APIs

Point the OpenAI provider at any compatible endpoint via ~/.bot/config.json:

{
  "providers": {
    "groq": {
      "model": "llama-3.3-70b-versatile",
      "api_key_env": "GROQ_API_KEY",
      "base_url": "https://api.groq.com/openai/v1"
    }
  }
}

Configuration

Config and history live in ~/.bot/, with user-only file permissions on Linux and macOS:

~/.bot/                           (chmod 700)
├── config.json                   (chmod 600) — provider settings and defaults
├── history_anthropic.json        (chmod 600) — conversation history per provider
├── history_openai.json           (chmod 600)
├── history_ollama.json           (chmod 600)
├── usage_anthropic.json          (chmod 600) — cumulative token/cost data
└── sessions/                     (chmod 700)
    └── myproject.json            (chmod 600)

History is capped at 50 message pairs per provider. You can edit ~/.bot/config.json directly to customise models, add providers, or set custom base URLs.

Security-related defaults in config.json:

{
  "security": {
    "safe_output": true,
    "redact_secrets": false,
    "warn_dangerous_commands": true,
    "allowed_export_dirs": ["."],
    "allowed_hosts": [],
    "allow_insecure_http": false,
    "request_timeout_seconds": 30,
    "max_retries": 2,
    "retention_days": 30
  }
}

Security

  • File permissions~/.bot/ and all data files are created with user-only permissions (700/600) on Linux and macOS so other users on the same machine cannot read your history, API keys, or session data.
  • Session name validation — session names are validated against a strict allowlist (letters, numbers, ., _, -) to prevent path traversal attacks. Names like ../etc/passwd are rejected at the CLI boundary.
  • Safe exports--output writes are restricted to allowed directories by default; use --unsafe-output to bypass for one command.
  • Secrets redaction — use --redact-secrets to mask common key/token patterns in --history and --export output.
  • Network guardrails — provider base_url values are validated (https by default for non-local hosts), with configurable host allowlists, timeouts, and retry limits.
  • Outbound warning guardrail — bot warns before printing responses that appear to contain dangerous shell command suggestions.
  • Retention controls — use --purge to delete history, usage, and session files older than the configured retention window.
  • Security log — export, clear, purge, and config changes are recorded in a local redacted JSONL audit log at ~/.bot/security.log.
  • Security policy — see SECURITY.md for reporting guidance and supported-version details.
  • Threat model — see THREAT_MODEL.md for threat boundaries, mitigations, and residual risks.
  • API keys — keys are never written to disk; they are read only from environment variables at runtime.

Requirements

  • Python 3.12+
  • anthropic — Anthropic/Claude provider
  • openai — OpenAI and llama.cpp providers
  • rich — terminal rendering
  • click — CLI framework

Cross-platform

Works on Linux, macOS, and Windows. Config and history paths resolve correctly on all platforms via Path.home(). File permission hardening applies on Unix only; Windows uses its own ACL-based access controls.


Built by

Inzen — AI consulting and LLM application development.


Contributing

git clone https://github.com/benwalkerai/bot
cd bot
uv sync --group dev
uv run pytest          # run tests
uv run ruff check .    # lint

CI runs automatically on every push and pull request via GitHub Actions — tests and ruff must pass before merging.


Releasing

Current automated release flow

From v0.3.6 onward, releases are published through GitHub Actions and include:

  • PyPI package publish (inzen-bot)
  • Windows installer EXE
  • Linux .deb
  • Linux .rpm

The release pipeline validates that the Git tag version matches pyproject.toml before assets are published.

Recommended: one-click release (workflow dispatch)

Use the Cut Release workflow in GitHub Actions:

  1. Open ActionsCut Release.
  2. Click Run workflow on main.
  3. Choose release_type (patch, minor, or major).
  4. Optional: set version (for explicit version, e.g. 0.3.7).

What this workflow does automatically:

  1. Bumps version in pyproject.toml (and bump-my-version metadata).
  2. Runs release checks:
  • uv run pytest -v
  • uv run ruff check .
  • uv lock --check
  • uv run pip-audit
  1. Regenerates CHANGELOG.md with git-cliff.
  2. Commits release files to main.
  3. Creates and pushes tag vX.Y.Z.
  4. Triggers:
  • publish.yml to publish on PyPI
  • release-assets.yml to publish Windows/Linux assets

Manual fallback (if needed)

# 1) Bump version without auto-commit/tag
uv run bump-my-version bump patch --no-commit --no-tag

# 2) Regenerate changelog
uv run git-cliff --output CHANGELOG.md

# 3) Run release checks
uv run pytest -v
uv run ruff check .
uv lock --check
uv run pip-audit

# 4) Commit and tag
git add pyproject.toml uv.lock CHANGELOG.md
git commit -m "chore: bump version to <version>"
git tag -a v<version> -m "v<version>"

# 5) Push
git push origin main
git push origin v<version>

Required repository secret for publish:

  • PYPI_API_TOKEN

License

GPL-3.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

inzen_bot-0.3.7.tar.gz (51.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

inzen_bot-0.3.7-py3-none-any.whl (41.2 kB view details)

Uploaded Python 3

File details

Details for the file inzen_bot-0.3.7.tar.gz.

File metadata

  • Download URL: inzen_bot-0.3.7.tar.gz
  • Upload date:
  • Size: 51.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for inzen_bot-0.3.7.tar.gz
Algorithm Hash digest
SHA256 ca23dd6be5b07840c8573c0fa65a2a1d0b262bafb9f36137e06b59d5fccb84ff
MD5 8482827a87b2887d445278a68f75bbde
BLAKE2b-256 aafc5facc0ff5d291270e719b322ad73480570bf0ca62dfc7c6a613f350b417f

See more details on using hashes here.

File details

Details for the file inzen_bot-0.3.7-py3-none-any.whl.

File metadata

  • Download URL: inzen_bot-0.3.7-py3-none-any.whl
  • Upload date:
  • Size: 41.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for inzen_bot-0.3.7-py3-none-any.whl
Algorithm Hash digest
SHA256 f6a57d62305db0888c614f30edb97afb3eef66dc88b059ce87342b83d4abce85
MD5 74264903d0890ac829b27499e5a9a44a
BLAKE2b-256 df17ad95624e1d900d249a993bd5056285e180ad3874f35577b57f499371b18a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.7 This release

2 files

0.3.6

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page