emile-cli
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Fail
- rimraf — Recursive directory removal in package-lock.json
- exec() — Shell command execution in src/agent/agent.js
- process.env — Environment variable access in src/agent/agent.js
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Terminal-based AI coding agent — provider-agnostic, MCP-ready, with live reasoning streams, prompt caching, plans mode and a skills system. Pure ES modules, zero build step.
emile
A terminal-based AI coding agent that lives in your workspace.
Connects to any OpenAI-compatible LLM provider (Requesty, OpenRouter, OpenCode) with built-in tools, MCP integration, prompt caching, reasoning control, and a Claude Code–style streaming UI.
What is this?
emile is a coding agent you run from your terminal. You give it a task in plain, and it reads files, writes code, runs commands, and iterates — all within your current working directory. Think of it as a pair-programmer that never gets tired of refactoring.
It's built to be provider-agnostic: it talks to any OpenAI-compatible API, so you're not locked into a single vendor. The agent loop supports tool calls, reasoning models (with live thinking streams), prompt caching to cut costs, and a skills system that injects domain expertise into the system prompt on demand.
This is a personal project that grew into something useful enough to share. It's opinionated, lightweight (one dependency tree, no native modules), and designed to feel fast in the terminal.
Features
- Live reasoning streams — watch the model think in real time before it writes code, with expand/collapse toggle
- Progressive response streaming — assistant text appears inside the response box as provider deltas arrive; the waiting indicator remains visible through metadata-only chunks instead of leaving a silent gap
- Built-in file tools — read, write, edit (diff-based), search, and run shell commands, all with safe-mode gating
- MCP integration — connect external tool servers via Model Context Protocol (STDIO transport)
- Prompt caching — Requesty provider supports cache headers to reduce cost on repeated context
- Reasoning effort control — dial reasoning depth from
lowtomaxper session or per run - Plans mode — agent drafts an implementation plan and waits for your approval before touching files
- Skills system — 40+ YAML-based skill modules (architecture, TDD, React patterns, security, etc.) that auto-inject into the system prompt when relevant
- User-authored project rules — optional
.emilerulespreferences, with compatibleAGENTS.md/.clinerules/.cursorrulesfallbacks - Session persistence — conversations are saved per workspace; resume, switch, export to Markdown, or rewind to edit your last message
- Opt-in web search — OpenRouter's provider-operated web search can be enabled per run or with
/websearch; search charges may apply even on free model routes - Context tracking and adaptive compression — real token usage in the footer; history compresses at 80% of the active model's catalog window
- Claude Code–style UI — boxed writing field, autocomplete for slash commands,
Escto cancel a draft, Tokyo Night color palette throughout - Dynamic terminal title — the tab reports real activity such as thinking, responding, context compression and safe tool summaries
- Zero-dependency spinner — custom Braille spinner with no external animation library
Quick start
Prerequisites
- Node.js >= 18 (uses native ES modules and
fetch) - An API key for a supported provider (see Configuration)
Install
git clone https://github.com/mc33p/emile-cli.git
cd emile-cli
npm install
npm link # makes `emile` available globally
Or run it directly without linking:
node bin/emile.js
Configure
On first run, emile will walk you through a setup wizard to pick a provider and enter your API key. You can also pre-configure via environment variables:
export EMILE_PROVIDER=requesty
export REQUESTY_API_KEY=your-key-here
export EMILE_DEFAULT_MODEL=anthropic/claude-3.5-sonnet
export EMILE_DEFAULT_EFFORT=low
export EMILE_WEB_SEARCH=false # set true only when OpenRouter search is wanted
Run
emile # start interactive REPL
emile "Add input validation to src/api.js"
emile -m openai/gpt-4o -e high "Refactor the auth module"
emile -p "Build a REST API for a todo app" # plans mode
emile -H # resume a previous session
---
## CLI reference
| Flag | Description | Default |
|------|-------------|---------|
| `-m, --model <model>` | Model ID (provider-prefixed, e.g. `anthropic/claude-3.5-sonnet`) | `anthropic/claude-3.5-sonnet` |
| `-e, --effort <level>` | Reasoning effort: `low`, `medium`, `high`, `max`, `min`, `none` | `low` |
| `-p, --plans` | Enable plans mode (agent drafts a plan before executing) | `false` |
| `--no-cache` | Bypass prompt caching | caching on |
| `-s, --skills <list>` | Comma-separated skills to activate (default: auto-detected and task-relevant) | `all` |
| `-H, --history` | Select and resume a past session | `false` |
| `--no-safe` | Bypass the safe-execution gate for shell commands | safe mode on |
| `--dry-run` | Simulate file changes and command execution without writing | `false` |
| `--web-search` | Enable OpenRouter web search; additional provider charges may apply | `false` |
| `--export-thinking` | Include model reasoning in `/export` output (explicit opt-in) | `false` |
| `--max-session-size <bytes>` | Maximum size of each persisted session snapshot; old tool results are trimmed when needed | `10485760` |
| `--max-loop-iterations <n>` | Maximum agent tool-loop iterations per turn (safety cap) | `40` |
| `--verbose` | Show setup and MCP initialization logs | `false` |
---
## Slash commands
Inside the interactive REPL, type `/` to see autocomplete. Available commands:
| Command | Description |
|---------|-------------|
| `/connect` | Reconfigure API provider and key |
| `/model` | Search and switch the active model; type to filter or use ↑/↓ to scroll the full live list |
| `/switch` `/sessions` | Resume a previous session |
| `/sessions clean <days>` | Delete saved sessions older than the specified number of days |
| `/new` `/clear` | Start a fresh session |
| `/rewind` | Remove your last message (and the agent's reply) and re-edit it |
| `/undo [N]` | Revert the last file modification, or the last N changes after confirmation |
| `/cost` | Show cumulative token usage and estimated cost |
| `/export [--export-thinking]` | Export the current session as Markdown; include reasoning only with explicit opt-in |
| `/rules` | Inspect the active user-authored project rules source |
| `/thinking` | Toggle reasoning visibility (expanded by default; collapsed shows a ghost one-liner) |
| `/maxloop <n>` | Set the agent tool-loop iteration cap (default `40`); persists in the per-user configuration |
| `/websearch` | Toggle OpenRouter provider web search; warns about possible additional charges |
| `/help` | Show the in-app command reference |
| `exit` | Quit the CLI |
**Keyboard shortcuts in the prompt:**
| Key | Action |
|-----|--------|
| `Tab` | Accept autocomplete suggestion / toggle plans mode |
| `Up` `Down` | Navigate autocomplete entries |
| `Shift+Enter` | Insert a newline without sending the prompt |
| `Esc` | Clear the current draft without sending |
| `Ctrl+C` | Exit immediately |
| Paste | Keep the complete pasted text, including multiple lines, editable; press `Enter` separately to send it |
**While the agent is working** the same full prompt remains visible and writable: spinner, reasoning and response output stay above it, while the blinking cursor remains at the active draft. `Tab` completes slash commands, `Esc` or `Ctrl+C` cancel the current turn without closing the CLI, and text confirmed with `Enter` is queued for the next turn. Queued `/` lines run as slash commands between turns.
**While the agent is working** the same full prompt remains visible and writable: spinner, reasoning and response output stay above it, while the blinking cursor remains at the active draft. `Tab` completes slash commands, `Esc` or `Ctrl+C` cancel the current turn without closing the CLI, and text confirmed with `Enter` is queued for the next turn. Queued `/` lines run as slash commands between turns.
---
## Built-in tools
The agent has direct access to these file-system and shell tools. All write operations are gated by safe mode (use `--no-safe` to bypass at your own risk).
| Tool | What it does |
|------|-------------|
| `readFile` | Read file contents (with line caching for large files) |
| `writeFile` | Create or overwrite a file |
| `editFile` | Apply targeted string replacements (diff-based, with undo tracking) |
| `listDir` | List directory contents |
| `findFiles` | Find files by glob pattern |
| `grepSearch` | Search file contents with regex |
| `runCommand` | Execute shell commands (safe-mode gated, dry-run aware) with a workspace-contained session cwd; network-to-shell pipes receive an explicit injection warning |
External tools from MCP servers are exposed alongside these with an `mcp__<server>__<tool>` naming convention.
When enabled, OpenRouter web search is sent as a provider-operated server tool;
it is not sent to Requesty or other providers. Search results are returned by
the provider and should be treated as untrusted external data.
---
## Skills system
Skills are YAML-frontmatter markdown files in `.agent/skills/`. Each skill defines a `name`, `description`, and `keywords`. When the agent detects a keyword match in your prompt, the skill's body is injected into the system prompt — giving the model domain-specific guidance without bloating context on every turn.
The project ships with 40+ built-in skills:
architecture clean-code tdd-workflow code-review-checklist
react-patterns nextjs-best-practices tailwind-patterns frontend-design
python-patterns nodejs-best-practices database-design api-patterns
testing-patterns systematic-debugging performance-profiling vulnerability-scanner
deployment-procedures server-management bash-linux powershell-windows
seo-fundamentals i18n-localization mobile-design game-development
mcp-builder plan-writing documentation-templates brainstorming
parallel-agents intelligent-routing red-team-tactics behavioral-modes
Activate a subset with `-s`:
```bash
emile -s clean-code,tdd-workflow,react-patterns "Refactor the dashboard components"
Add your own by dropping a SKILL.md into .agent/skills/your-skill/:
---
name: my-skill
description: "Guidance for my specific workflow. Triggers on keywords: deploy, release."
keywords: [deploy, release, ship]
---
Your markdown instructions here...
MCP integration
emile supports Model Context Protocol servers via STDIO transport. Configure servers in mcp.json at your project root:
{
"mcpServers": {
"everything": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-everything"],
"env": {}
}
}
}
On startup, the CLI connects to each configured server, discovers its tools, and exposes them to the agent alongside the built-in tools. MCP tool calls are namespaced as mcp__<server>__<tool> to avoid collisions.
Configuration
Environment variables
| Variable | Purpose | Default |
|---|---|---|
EMILE_PROVIDER |
API provider: requesty, openrouter, opencode, opencode-go |
requesty |
REQUESTY_API_KEY |
API key for Requesty | — |
OPENROUTER_API_KEY |
API key for OpenRouter | — |
OPENCODE_API_KEY |
API key for OpenCode | — |
EMILE_DEFAULT_MODEL |
Default model ID | anthropic/claude-3.5-sonnet |
EMILE_DEFAULT_EFFORT |
Default reasoning effort | low |
EMILE_MAX_LOOP_ITERATIONS |
Maximum agent tool-loop iterations per turn | 40 |
EMILE_CONFIG_DIR |
Override the per-user configuration directory (isolated runs/tests) | OS user config directory |
User configuration and credentials
Provider/model settings are persisted in an OS user configuration directory and loaded on every startup, so the connect wizard is not required again when Emile is launched from another workspace. Provider API keys are never written to the settings JSON:
- Windows: credentials are encrypted with DPAPI for the current Windows user.
- macOS/Linux: credentials are encrypted with AES-256-GCM in a separate credentials file; the fallback key file is owner-only where the platform supports POSIX modes. This protects the JSON/settings surface but is not equivalent to an OS keychain because the same OS user can access both files.
The workspace .emile/ directory remains for sessions, undo history, MCP consent, enhanced web-search flags and other local runtime state. Tavily and Firecrawl credentials configured through /tavily and /firecrawl are also stored in protected credential storage, not in .emile/web.json. The exact user-config path can be overridden with EMILE_CONFIG_DIR for isolated environments and tests. Environment variables remain supported as a non-persistent fallback.
Project rules
To apply your own always-on preferences to a workspace, create .emilerules at its root. Emile does not generate default rules: the file belongs to you and its contents are sent to the active model on every session. Do not place secrets in it. If .emilerules is absent, Emile can reuse user-maintained AGENTS.md, .clinerules, or .cursorrules files, in that order. Use /rules to see which source is active.
Supported providers
| Provider | Base URL | Notes |
|---|---|---|
| Requesty | https://router.requesty.ai/v1 |
Default; supports prompt caching |
| OpenRouter | https://openrouter.ai/api/v1 |
Broad live/cache-backed model catalog; searchable from /model |
| OpenCode | https://opencode.ai/zen/v1 |
Curated gateway; live model list searchable from /model |
| OpenCode Go | https://opencode.ai/zen/go/v1 |
Curated open-source models; live model list searchable from /model |
Any OpenAI-compatible endpoint works — the client uses the openai SDK under the hood.
Project structure
emile-cli/
├── bin/
│ └── emile.js # Entry point
├── src/
│ ├── cli.js # Command parsing, REPL loop, slash commands
│ ├── config.js # Config load/save, env var resolution
│ ├── models.js # Dynamic OpenRouter model catalog + static fallback
│ ├── ui/model-picker.js # Bounded incremental /model search UI
│ ├── prompt.js # System prompt assembly
│ ├── rules.js # Optional user-authored project rules discovery
│ ├── skills.js # YAML skill parsing + keyword matching
│ ├── plans.js # Plans mode: draft, approval, status
│ ├── history.js # Session persistence (save/restore/list)
│ ├── mcp.js # MCP server lifecycle + tool bridging
│ ├── commands.js # Connect/model wizards
│ ├── agent/ # Agent loop, session stats, history compression
│ ├── api/ # OpenAI-compatible client + retry
│ ├── tools/ # Tool schemas, security gates, per-tool handlers
│ └── ui/ # Terminal rendering (theme, boxes, prompt, thinking…)
├── .agent/skills/ # Skill modules (YAML frontmatter + markdown)
├── .emile/ # Workspace runtime state: sessions, undo, MCP consent (gitignored)
├── mcp.json # MCP server configuration
└── package.json
Architecture
The agent runs a simple but powerful loop:
User input
|
v
+----------+ +--------------+ +---------------+
| System |--->| LLM API call |--->| Parse response |
| Prompt + | | (streaming) | | (text + tools) |
| Skills + | +--------------+ +-------+-------+
| Tools + | | |
| History | v v
+----------+ +--------------+ +---------------+
| Thinking | | Has tool calls?|
| stream | +-------+-------+
| (live) | |
+--------------+ No --+-- Yes
| |
v v
Print Execute tools
response -> append results
-> loop back to LLM
- System prompt is assembled from the base prompt + active skills + tool definitions
- Context policy estimates the full payload before the turn and compresses older history only at 80% of the active model's catalog window
- Streaming response is parsed chunk-by-chunk: cumulative reasoning is reduced to unseen text before live rendering, text accumulates, and tool calls are assembled
- Tool execution runs built-in handlers or MCP bridges, with safe-mode and dry-run checks
- Results are appended to the message history and the loop continues until the model stops requesting tools
- Context tracking updates on every API response using real
usagetokens, with a pre-call character-based estimate as fallback
Process & Engineering
This project follows formal Software Engineering practices (documentation as the single source of truth, Spec-Driven Development, feature registry and disciplined Git workflow):
.clinerules/AGENTS.md— mandatory AI-agent rules loaded every session: required context reading (cache-conscious), doc synchronization after every change, SDD adherence, security gates and the single-branch Git workflow.- Git workflow — ongoing code and documentation work stays on
development; commits stage only the files of the current scope — nevergit add .. The workflow does not switch branches, create worktrees, merge, rebase or pull as a routine task step. See.clinerulesRule 8 and CONTRIBUTING.md. specs/— Spec-Driven Development (SDD): every implementation starts from a spec (spec.md→plan.md→tasks.md), with standardized templates and a traceable lifecycle. See the full workflow.features/— catalog of delivered features, each traceable to its source spec. See the index.- ADRs — architecture decisions documented in
docs/adr/. - CHANGELOG — change history in Keep a Changelog format.
Documentation index
| Document | Contents | Status |
|---|---|---|
| Product (PRD) | Vision, user stories, functional requirements | 🟢 Current |
| Architecture | System diagrams, agent loop, module map | 🟢 Current |
| Visual Identity (TUI) | Design system: Tokyo Night palette, components, visual-debt backlog | 🟢 Current |
| Code Quality & Security | Risk classification, threat surfaces, secure coding, gates | 🟢 Current |
| Roadmap | Phases 0–4: foundation, UI overhaul, automated quality, robustness, distribution | 🟢 Current |
| Glossary | Domain terms (plans mode, skills, MCP, prompt caching…) | 🟢 Current |
| Code Improvements | Prioritized codebase improvement backlog (robustness, security, testing) | 🟢 Current |
| Decisions (ADRs) | Architecture decisions (stack, quality gates, active prompt output) | 🟢 Current |
The
.agent/directory contains generic AI agent kit configuration (agents, skills, workflows) — it is not product documentation.
Contributing
This is a personal project, but issues and pull requests are welcome. See the contribution guide for the full SDD workflow, branch/commit conventions, and quality gates. Quick pointers:
- New skill: Add
.agent/skills/your-skill/SKILL.mdwith valid YAML frontmatter - New tool: Add a definition + handler to
src/tools.jsfollowing the existing pattern - New provider: Add a
baseURLbranch insrc/api.jsand an env var insrc/config.js - Bug fix: Open an issue with reproduction steps, or submit a PR with a clear description
Development
git clone https://github.com/mc33p/emile-cli.git
cd emile-cli
npm install
node bin/emile.js --verbose # run from source with debug output
npm test # run the regression suite
npm run lint # lint src/, test/ and bin/
No build step — the project runs raw ES modules. Syntax-check individual files with node --check src/<file>.js.
License
MIT — do what you want, just keep the copyright notice.
Built for people who think faster than they type.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found