Skip to main content

Sidekick

A local-first terminal companion you can talk to — chat, voice, and 17 tools, on your hardware.

Python 3.12+ Textual TUI Ollama License: MIT Tests

No cloud account required. No API bill by default. Your files, memory, and voice never leave your machine unless you hand it a key.

See it

Slash autocomplete with fuzzy filtering, right in the prompt:

Slash autocomplete

A grounded answer — real tools, real system data, streamed live:

Grounded answer

Screenshots are real SVG captures of the app running headless (docs/shot.py), not mockups.

$ sk brief
╭─ sidekick brief  Sat 2026-09-19 11:58 ─╮
│ CPU: AMD Ryzen 7 4800H (16 threads)     │
│ Mem: 7.2Gi · GPU: GTX 1650 4GB          │
│ /dev/nvme0n1p8  133G  117G  8.5G  94% / │
╰─────────────────────────────────────────╯
│ ! disk 94% full — clean ~/Downloads…    │

$ sk run "what is the ideal llm i can run on my device"
• qwen3:4b (2.5 GB): fits comfortably in your 4096 MiB VRAM.
• llama3.2:3b (2.0 GB): another good option.

$ sk talk
[Enter] to record, [Enter] to stop. /quit exits.
heard> what files are in the sidekick repo

Why sidekick

Sidekick Typical cloud agent
Runs fully offline (Ollama) ✅ ❌
Voice input, transcribed on your CPU ✅ ❌
Copy/paste that works in-terminal ✅ drag-select, ctrl+y, /copy varies
Answers grounded in your system, not guessed ✅ deterministic grounding prompt-only
Skills you can read (SKILL.md, incl. superpowers) ✅ varies
371-test suite incl. prompt-regression evals ✅ rare

Quickstart

uv tool install sidekick-agent[voice]   # global `sk`, STT included
sk init                                  # guided first-run: hardware → model → verify
sk                                       # fullscreen chat — start here (`sk tui` works too)

No clone, no build — installs straight from PyPI. Requires Python 3.12+. Without [voice] you get everything except Talk/mic (installs on first use instead). Local path needs Ollama (ollama serve, pull qwen2.5-coder:7b for smarts or llama3.2:3b for speed).

Install

Channel Command
PyPI / uv uv tool install sidekick-agent[voice]
PyPI / pipx pipx install sidekick-agent[voice]
PyPI / pip pip install sidekick-agent[voice]
AUR (Arch) yay -S python-sidekick-agent
conda-forge conda install -c conda-forge sidekick-agent (feedstock lives in a separate repo)

The published name is sidekick-agent (the sidekick name is taken on PyPI); the command stays sk. Version is a single source of truth in src/sk/__init__.py. Publishing is automatic and credential-free: when a PR is merged to main of the canonical repo Faisal01011/sidekick with a bumped __version__, GitHub Actions trusted-publishes to PyPI and opens a GitHub Release (forks can never publish) — details in packaging/README.md.

From source (dev):

git clone https://github.com/Faisal01011/sidekick && cd sidekick
uv tool install -e ".[voice]"   # editable dev install; STT included
sk doctor

Chat

One input, two surfaces — fullscreen TUI and plain-text REPL share every command:

sk                   # fullscreen chat with streaming + themes — start here
sk tui --model fast  # same, explicit form
sk chat              # fallback REPL: dumb terminals, screen readers, broken TUIs

Type / and an autocomplete popup filters all 20+ commands — Enter completes, Tab too, Esc dismisses, ↑/↓ navigates. F1 opens a generated cheatsheet (keys + commands, built from the same tables as the dispatcher, so it can't rot).

TUI keys: Enter sends · ctrl+j/alt+enter newline · ↑/↓ history · ctrl+y copies · ctrl+g push-to-talk · pgup/pgdn scroll · F1 help · F2 dark/light theme · F3 sessions drawer. Answers stream live as Markdown with role colors; approvals arrive as cards with timeout; the status bar shows model · session · last-turn time/tokens.

Voice

sk talk [-d SECS] [--stt-model base] [--device hw:2,0]  # Enter records, Enter stops
sk mic-test                                             # peak dB + silent/quiet/good verdict

Capture via the OS-native recorder (arecord/ALSA on Linux, sox/ffmpeg on macOS), transcription via local faster-whisper int8, transcript lands editable in the prompt. In the TUI, ctrl+g (or the mic pill) does the same. Voice never leaves your machine; recordings are temp files, deleted after each take.

MCP server

sk mcp [--allow-writes]   # JSON-RPC 2.0 over stdio, zero new deps

All 17 tools, same safety policy (SSRF guards, write blocklists, hard-refusals). Reads auto-run; shell/writes/delete need --allow-writes, else a clean denied error. Stdout carries protocol only. Claude Desktop snippet:

{ "mcpServers": { "sidekick": { "command": "sk", "args": ["mcp"] } } }

Providers (BYO key)

sk connect     # pick provider → paste key (hidden) → pick model → ping. Done.

One guided flow: numbered provider list (local ones skip keys), live validation before anything saves, curated model list (TTS/image junk filtered, recommended pre-highlighted, Enter accepts), and a 5-token ping instead of a full agent turn. Advanced paths still work: sk auth add/list/status/remove, sk model, sk setup (connect + hook), sk config --provider openai --api-key sk-..., /provider groq inside chat.

Presets: ollama|openai|groq|together|deepseek|openrouter|google|lmstudio|anthropic|custom (anthropic speaks the native Messages API; the rest are OpenAI-compatible). Any OpenAI-compatible endpoint works via --provider custom --base-url https://... --api-key .... Preferred: SIDEKICK_API_KEY env (never touches disk); file keys are chmod 600 and masked in --show. The Anthropic backend marks the static system prompt + tool definitions cacheable (repeat turns up to 10x cheaper); OpenAI-compatible providers cache matching prefixes automatically server-side.

Command reference

Command What
sk / sk tui [--continue] Fullscreen chat, fresh session each launch
sk chat [--continue] Fallback plain-text REPL (dumb terminals, screen readers, TUI issues)
/sessions, /resume <n>, /sessions delete <n>, /fork [n] List, switch, delete, branch past sessions
sk run "task" [--yes] [--model auto|fast|smart|name] [--json] Single-shot agent run (auto-router picks the model; --json emits one machine-readable document + exit codes, use with --yes unattended)
sk brief [-p PATH] [--smart] Morning digest: system + git + todos + memories, instant without LLM
sk remember/recall/memories/forget Long-term memory (FTS5 search, auto-injected)
sk todo add/list/done/clear Todos
sk history / sk oops Shell log / explain last failure
sk export [SESSION] [--out f.md] Session transcript as Markdown (turns + tool calls)
sk audit [--session S] [--format md|json] Compliance log: tool runs, approve/deny, local-vs-egress
sk stats [--session S] [--format md|json] Usage + cost estimates from audit rows (turns, tools, tokens)
sk hook-install [--write] Bash/zsh logging hook
sk skills / sk skills-search / sk skills-install superpowers / sk daemon [--once] / sk daemon-install Skill packs (obra/superpowers) / background watcher (systemd)
sk mcp [--allow-writes] MCP server over stdio (17 tools, safe defaults)
sk doctor / `sk models [pull prune ]/sk config/sk version/sk upgrade [--check]`
sk init / sk setup / sk connect Guided first-run / full setup / provider key flow

Packs use the SKILL.md frontmatter format. The prompt carries a relevance-ranked index; the agent loads full instructions on demand via the skill tool. fast/smart resolve per provider (Ollama: llama3.2:3b/qwen2.5-coder:7b, Groq: gpt-oss-20b/120b).

Architecture

flowchart TB
    U([you]) --> CLI[sk / sk run]
    U --> TUI[sk tui: autocomplete, streaming, mic pill]
    U --> VOICE[sk talk: arecord + faster-whisper]
    CLI --> SLASH[slash.py: /commands, no LLM]
    TUI --> SLASH
    VOICE --> AGENT
    CLI --> AGENT[agent.py: stream → tools → synthesize]
    TUI --> AGENT
    AGENT --> GROUND[deterministic grounding: ~/paths, URLs,\nsysinfo — injected before the model sees the prompt]
    AGENT --> TOOLS[tools.py: 17 tools, allowlists,\nhard-blocks, SSRF guard]
    AGENT --> MEM[(store.py: history, memories FTS5,\ntodos, shell log)]
    AGENT --> SKILLS[skills: relevance-ranked SKILL.md index]

Design bets that paid off: deterministic grounding beats prompt instructions (small models ignore rules but can't argue with injected facts), text-JSON fallback (coders emit tools as text over the OpenAI endpoint), FTS5 over vectors (zero deps, instant, no embedding server on a 4GB box), parallel reads (approval-gated tools stay serial; independent reads run concurrently with failures isolated), capability profiles over hope (known models declare their tool protocol; the router reads them instead of paying a probing 400).

Safety

Reads auto-run. Writes, deletes, and general shell need approval (inline [y/N] in TUI, prompt in CLI), HOME//tmp only, ≤100KB, never ~/.ssh, ~/.gnupg, /etc, /usr. Multi-tool turns with destructive actions get one plan review up front instead of per-tool prompts (silent in --yes//yolo; denials execute nothing). shell hard-refuses rm -rf /, mkfs, dd to devices, fork bombs even with approval. read_url/web_search block localhost/private IPs. API keys chmod 600, masked in output.

Tests

uv run --python 3.12 --with ".[test]" pytest tests -q   # 371 passed: unit + regression + Textual pilot, no Ollama needed

The eval harness (tests/test_eval.py) locks in every past quality bug as an offline regression test. A suite-wide fixture guarantees tests never touch your live ~/.sidekick/.

Config

~/.sidekick/config.toml (provider, model, base_url override, api_key, …). Env overrides: SIDEKICK_PROVIDER, SIDEKICK_MODEL, SIDEKICK_BASE_URL, SIDEKICK_API_KEY. Data stays home: history.db, skills/, nudges.log, input_history, tui-errors.log.

History budget: history_budget_tokens (default 3000) caps per-turn history; over-budget sessions compact to a rolling summary via the current model (DB history stays complete). Lower it for small-context models.

Per-project config: a .sidekick.toml in any repo layers over the global file (nearest one walking up from cwd). It may set provider, model, max_steps, temperature, plus a [project] table (docs files injected into the prompt, memory_namespace, approved_commands for shell). api_key/base_url are never read from project files (global/env only) — sk config --show prints the active project and any ignored keys. sk --cwd PATH runs any command as if in that directory.

Roadmap

See ROADMAP.md — the shared plan (vision, v0.2.0 / v0.3.0 milestones, done list). It changes by pull request only.

License

MIT — do what you want, shout-outs appreciated.

Release files for sidekick-agent 0.11.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sidekick-agent 0.11.0
File Size Uploaded
sidekick_agent-0.11.0.tar.gz 172.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sidekick-agent 0.11.0
File Interpreter ABI Platform
sidekick_agent-0.11.0-py3-none-any.whl Python 3 none any Details

Total release size: 293.1 kB

Release files / sidekick_agent-0.11.0.tar.gz

Download URL sidekick_agent-0.11.0.tar.gz
Size 172.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1675580e0fb8a7fc3e6cd7c5d2b951629e6c5811da20d22d6a5ee44ca30d5e82
BLAKE2b-256 checksum
How to use checksums
d2ee20a3b271534f6d78187e3a920729d6fc3a7c9716d62652ccaa792ae7cc83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release files / sidekick_agent-0.11.0-py3-none-any.whl

Download URL sidekick_agent-0.11.0-py3-none-any.whl
Size 120.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a2722b7136d7031643408eed43e7503e1d65553487914eb8f4cb20bd3cd63598
BLAKE2b-256 checksum
How to use checksums
29af5fbf890a998caa43d0a8bb170d75dc48dc02e942850e2f217a68fb43bb58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

0.13.0

2 release files

0.12.0

2 release files

This release

0.11.0 This release

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page