Metadata-Version: 2.5
Name: shelp-llm
Version: 0.5.0
Summary: `cmd??` — instant, man-page-grounded cheat sheets for shell commands, expandable into an agentic chat
Project-URL: Homepage, https://github.com/HenryNebula/shelp
Project-URL: Repository, https://github.com/HenryNebula/shelp
Project-URL: Changelog, https://github.com/HenryNebula/shelp/releases
License-Expression: MIT
License-File: LICENSE
Keywords: cheatsheet,cli,llm,man,shell
Classifier: Environment :: Console
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.11
Requires-Dist: openai>=3.19.2
Requires-Dist: rich>=13.0
Description-Content-Type: text/markdown

# shelp

[![CI](https://github.com/HenryNebula/shelp/actions/workflows/ci.yml/badge.svg)](https://github.com/HenryNebula/shelp/actions/workflows/ci.yml)

`cmd?` → TL;DR. `cmd??` → a full, man-page-grounded cheat sheet. `??` → chat.
All backed by your choice of model via **OpenRouter** (or any local
OpenAI-compatible server) — no agent harness, no vendor lock.

```console
$ jq?                     # TL;DR — one-liner + 5 common invocations
$ ffmpeg??                # full sheet: tasks · flags · gotchas · preview safely
c) chat · r) regenerate · q) quit
$ tar?? list a tar.gz     # sheet + inline answer
$ ??                      # general chat (shelp's own agentic loop)
```

(IPython muscle memory: `obj?` → docstring, `obj??` → source.)

## Setup

Python 3.11+, plus either an [OpenRouter](https://openrouter.ai/keys) key or
any OpenAI-compatible endpoint:

```bash
uv tool install shelp-llm         # PyPI dist name; installs the `shelp` command
export OPENROUTER_API_KEY=sk-or-…
shelp init zsh && exec zsh        # or: shelp init bash && exec bash
```

(`pipx install shelp-llm` works too; `uvx --from shelp-llm shelp jq` tries it
without installing.) Straight from the repo instead of PyPI:

```bash
uv tool install git+https://github.com/HenryNebula/shelp
```

Upgrades: `uv tool upgrade shelp-llm` — or for a git install, re-run its
install command.

### PowerShell (Windows; PS 7 recommended, 5.1 supported)

```powershell
uv tool install shelp-llm
shelp init powershell             # writes shelp.ps1 + a line in $PROFILE
```

Works in Windows Terminal and in pwsh on macOS/Linux. PS 5.1 gets the same
Enter-handler layer (only the `CommandNotFoundHandler` fallback needs
PSReadLine ≥ 2.3.6, probed at load). The trigger intercepts the raw buffer
before PowerShell parses it, so bare `??` works even though PS 7 defines
`??` as an operator. Question text travels via an env var (PS 5.1 mangles
quotes in native args), and cmdlet triggers (`Get-ChildItem??`, `gci?`)
harvest `Get-Help` — via one PowerShell spawn on the generation path only,
so cache hits stay fast.

Chat's tool speaks **your** shell (the plugin stamps it): PowerShell in PS
sessions, bash in Git Bash (with `MSYS_NO_PATHCONV=1` so `/etc` in a
question isn't rewritten to a Windows path), never cmd.exe. Sheets for
Windows exes that answer `/?` instead of `--help` (ipconfig, robocopy) are
harvested too.

For development: clone, `uv sync`, then `uv run shelp …`
(`.envrc.example` shows optional uv cache/venv relocation), or
`uv tool install --editable .` for a live-installed copy.
Releases: push a `v*` tag — CI builds the wheel, attaches it to a GitHub
Release, and publishes to PyPI as `shelp-llm`
(`.github/workflows/release.yml`).

Config (environment, all optional except the key with remote providers):

| var | default | |
|---|---|---|
| `SHELP_API_KEY` / `OPENROUTER_API_KEY` | — | provider key (unneeded for local servers) |
| `SHELP_MODEL` | `nvidia/nemotron-3-ultra-550b-a55b:free` | any OpenRouter slug |
| `SHELP_CHAT_MODEL` | = `SHELP_MODEL` | stronger model for chat if you like |
| `SHELP_BASE_URL` | `https://openrouter.ai/api/v1` | any OpenAI-compatible endpoint |
| `SHELP_CACHE_DIR` | `$XDG_CACHE_HOME/shelp` (else `~/.cache/shelp`; Windows: `%LOCALAPPDATA%\shelp\cache`) | sheets + chat sessions |
| `SHELP_NO_PAGER` | unset | never page long sheets |

The default model is on OpenRouter's free tier (≈20 req/min, 200 req/day —
plenty for sheet generation). Free variants come and go, and some keys
restrict which providers they may use — if you get a 404 "no allowed
providers", point `SHELP_MODEL` at another `:free` slug.

**Fully offline:** `export SHELP_BASE_URL=http://localhost:30000/v1
SHELP_API_KEY=local SHELP_MODEL=qwen3.5-4b` (llama-server's OpenAI endpoint).
Tool calling in chat depends on the local model's support for it.

## The chat (`??`, `c`, `shelp chat <cmd>`)

shelp's own agentic loop — ~150 lines, no framework:

- streams replies; one tool: `shell` (bash on POSIX, PowerShell on Windows —
  the shell the plugin stamped, so a Git Bash session gets bash, never cmd.exe)
- read-only lookups (`man`, `--help`, `Get-Help`, `Get-ChildItem`, `which`,
  `ls`, `cat`, `grep`, pipes of those) auto-run; **anything else asks `y/N`
  first** (chaining, redirection, substitution, or unknown commands)
- sessions persist per command under the cache dir and **resume** on re-entry;
  `shelp chat <cmd> --new` starts clean; `q`/Ctrl-D exits

## Commands

| | |
|---|---|
| `shelp <cmd> [--refresh] [--raw] [--short]` | sheet / TL;DR |
| `shelp chat [cmd] [question] [--new]` | agentic chat |
| `shelp warm tar rsync ffmpeg` | pre-generate sheets |
| `shelp list` / `prune [--older-than Nd] [--all]` | cache management |
| `shelp doctor [--live]` | provider check + ping |

Sheets are grounded in the **local** man page + `--help` (so they match the
installed flavor/version), cached with hash invalidation, and hand-editable —
`shelp show --raw <cmd>` then set `pinned: true` in the front-matter to opt out
of auto-regeneration. First generation per command: ~5–15s depending on
provider (it streams while generating); after that: ~0.2s.

Design notes: [DESIGN.md](DESIGN.md).

## License

MIT — see [LICENSE](LICENSE).
