A simple CLI utility to chat with LLMs.
- Replace `$` and `Bun.spawn` with `execa` for process execution - Swap `Bun.JSONL.parse` for native `JSON.parse` and use `node:readline` for stdin handling |
||
|---|---|---|
| src | ||
| tts | ||
| .gitignore | ||
| .npmrc | ||
| AGENTS.md | ||
| biome.json | ||
| index.ts | ||
| package.json | ||
| pnpm-lock.yaml | ||
| README.md | ||
| sea-config.json | ||
| testRender.ts | ||
| tsconfig.json | ||
| tts.ts | ||
lmc
A Bun-based CLI tool for LLM chats with terminal native streaming.
Features
- Streaming markdown rendering — incremental rendering with syntax highlighting
- Conversation persistence — chat history saved to JSON
- Model configuration — persist model preferences to JSON
- Reasoning display — thinking tokens rendered in style on stderr
- Usage stats — input/output tokens and tokens/sec rate after each response
- TTY-aware — automatically disables markdown rendering when output is piped
- Text-to-speech —
ttscsub-command for streaming TTS via Kokoro model
Requirements
Installation
bun install
bun build:js
bun link
# For ttsc only
cp -r tts ~/.ttsc
Package to come later
Usage
Chat (lmc)
lmc [options] <prompt...>
| Flag | Short | Type | Description |
|---|---|---|---|
--new |
-n |
boolean | Start a new conversation (clear history) |
--model |
-m |
string | Set model name for this session |
--config |
-c |
boolean | Initialize a new config file (~/.lmc_config.json) |
--plain |
— | boolean | Disable markdown rendering for both stdout and stderr |
--plainOut |
— | boolean | Disable markdown rendering for stdout only |
--plainErr |
— | boolean | Disable markdown rendering for stderr only |
Examples:
lmc --config # Initialize/edit config
lmc --new "Introduce yourself." # New conversation
lmc "What is TypeScript?" # Continue most recent chat
lmc -m llama3 "Explain quantum computing" # Chat with specific model on-the-fly
lmc --plain "Plain text output" # No markdown rendering
Text-to-Speech (ttsc)
echo "text" | ttsc [options]
| Flag | Short | Type | Description |
|---|---|---|---|
--wait |
-w |
boolean | Wait for all processing before exiting (don't auto-play) |
--url |
-u |
boolean | Fetch text from a URL instead of stdin |
Examples:
echo "Hello, world!" | ttsc
echo "Read this aloud" | ttsc --wait
echo "https://example.com" | ttsc --url
Requires: uv
Wants:
mpvfor playbacksoxfor wav merging with--wait
Development
bun run dev # dev run
bun run prod # run bundled output
bun run check # biome lint + format + organize imports
Architecture
index.ts — LMC entry point, orchestration
tts.ts — TTSC entry point, orchestration
src/render/index.ts — Renderer class: streams LLM response, buffers markdown
src/render/markdown.ts — renderMarkdown(): syntax-highlighted markdown via Bun.markdown + Shiki
src/conversation/ — Conversation persistence
src/config/ — App config persistence
tts/ — TTS python stub (Kokoro pipeline)
out/ — Bundled output (index.js, tts.js)
Configuration
- Conversation history:
~/.lmc_convo.json - Model config:
~/.lmc_config.json - TTS files:
~/.ttsc/
Dependencies
| Package | Purpose |
|---|---|
ai (Vercel AI SDK) |
Streaming text/usage |
@clack/prompts |
Interactive prompts and spinner |
@cliffy/table |
ASCII table rendering |
@mozilla/readability |
HTML-to-text extraction (ttsc) |
chalk |
Terminal string styling |
happy-dom |
DOM parsing for URLs (ttsc) |
shiki |
Syntax highlighting (kanagawa-wave theme) |
terminal-link |
Clickable terminal hyperlinks |