Skip to content

arturkorb3/cli-agent

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cli-agent

A zero-dependency CLI and coding agent for Node.js (>= 20): an LLM driven always-self-aware agent with hands on your terminal. Ported from the architecture of the EVA project.

Features

  • Shell access — PowerShell on Windows, bash/sh on Linux/macOS, with timeouts and output capping. Every shell command is treated as arbitrary code execution and asks for approval by default.
  • File work — the agent can inspect, create and edit files in your workspace. Proposed edits are shown before approval, and line endings are preserved so CRLF files do not turn into mixed-line-ending files.
  • Code navigation — the agent can list project files and search source text across the workspace, while skipping noisy directories such as node_modules and .git.
  • Project context — a user-authored AGENTS.md (or CLAUDE.md / .cli-agent.md) in the workspace is loaded into the system prompt at startup, so the agent knows the project's build/test commands, conventions and constraints. The file stays human-owned; the agent never rewrites it.
  • Web access — the agent can fetch web pages as readable text and search the web via DuckDuckGo; no separate search API key is needed.
  • Providers — Anthropic (Messages API) and OpenAI-compatible providers (OpenAI, Azure, Ollama, OpenRouter, …) with streaming, transient-error retries, Anthropic prompt caching and optional reasoning/thinking modes.
  • Sessions — chats are stored under ~/.cli-agent/sessions/ and can be resumed by id or prefix. The agent can recall details from the current session even after they have left terminal scrollback, without opening arbitrary files outside the workspace.
  • History compaction — old turns condense into a digest + memory block; the recent window and tail stay verbatim; cut points are quantized so prompt caching keeps working.
  • TUI — streamed markdown-lite output, thinking indicator, spinner, tool-call/observation formatting, approval prompts, input history, multi-line input via trailing \.
  • Approval system — in-workspace read tools run automatically, but file writes and every shell command are gated by policy (AUTO_YES, ALLOW_SHELL); declining with freeform text hands the model your feedback as the new instruction. Shell child processes are started with a minimal, sanitized environment so provider/API-key variables from the agent process are not inherited by default.
  • Workspace confinement — workspace reads are frictionless. Reads outside the workspace require approval unless ALLOW_OUTSIDE_WORKSPACE=1. The agent's own configuration, session logs and state remain protected even when outside-workspace reads are enabled. Private or loopback network requests require separate approval unless ALLOW_PRIVATE_NETWORK=1.
  • Self-model/self explains what the running agent is: available capabilities, security policy, model/provider details and runtime state. The report is derived from the live code and tests rather than from a hand-written static description.
  • Self-improvement — the agent keeps a small friction/requirements backlog for things that got in the way or were requested during use. /improve reviews that backlog and proposes changes; implementing one still follows the normal approval and test workflow.

Setup

Prerequisite: Node.js >= 20 must be installed.

Run the guided setup once:

node src/index.js setup

or, after package installation/linking:

cli-agent setup

The wizard writes the agent's trusted configuration to your user config directory outside any repository (%APPDATA%\cli-agent\config.env on Windows, ~/Library/Application Support/cli-agent/config.env on macOS, ~/.config/cli-agent/config.env on Linux). The generated config.env is based on .env.example, with your answers filled in. Repository .env files are treated as application/repository config and are not loaded as cli-agent configuration.

The wizard can also install a small cli-agent launcher into a user bin directory. If that directory is not already on PATH, it asks before updating your user PATH / shell profile automatically; if you decline, it prints the manual PATH instruction instead.

Then start a session:

npm start
# or: cli-agent

Usage

cli-agent               new session
cli-agent resume [id]   resume latest (or given) session; id prefixes work
cli-agent --list        recent sessions

Inside the chat: /help, /status, /self [section], /improve, /sessions, /resume [id], /new, /image <path>, /paste-image, /pi [text], /compaction [preview|new], /delete <id>, /diff [n|path|last], /undo [n|path|last], /last [n], /full, /model [id], exit.

Command reference:

  • /status — model, session, history and cumulative token usage (↑input ↓output, prompt-cache share as ⚡cached).
  • /self [section] — the agent's live self-model: overview, anatomy, architecture, tools, capabilities, policy, friction, model, vitals.
  • /improve — review the friction/requirements backlog and propose improvements (read-only). To actually implement one, just say what you want; in the agent's own repo that is ordinary self-development. /self friction lists open items.
  • /compaction [preview|new] — raw vs. compacted history; preview prints the memory block; new starts a fresh session seeded with the compacted history (the old append-only log is left intact).
  • /diff [n|path|last] — files changed this session, independent of git; <index>/<path> shows one file's net change, last only the latest. Each diff has an action header (Create/Update/Delete(path)), a summary (Added N lines, removed M lines) and a left line-number gutter; long unchanged runs fold as ... N unchanged lines omitted .... Baselines persist in the session folder and survive resume/restart.
  • /undo [n|path|last] — revert a file to its session baseline (restore the original, or remove a file the session created); last undoes just the most recent change; no argument lists the revertable files.
  • /sessions, /resume [id], /new, /delete <id> — list sessions (with token totals), switch, start fresh, or remove a non-current session (by id, prefix or list index).
  • /image <path>, /paste-image, /pi [text] — attach an image to your next message, import one from the clipboard, or send a clipboard image immediately with an optional question. Clipboard import uses built-in Windows support, xclip/wl-paste on Linux, and pngpaste on macOS. Image bytes are stored as per-session blobs and sent only on the first model call for that message; later tool-loop calls use a compact reference to keep context small.
  • /last [n], /full — re-show recent tool output; /model [id] — show or switch the model; exit/quit — leave (the session stays resumable).

In approval mode, file-write approvals show the proposed diff before you answer; when a write is auto-approved (e.g. AUTO_YES), the applied diff is shown inline right after the tool runs, so changes are always visible. Token usage is reported by all three adapters (Anthropic, OpenAI Chat, OpenAI Responses) and persisted with each assistant event.

At an approval prompt (allow? [y/N/e/d/f]): y approves, e opens the proposed file content in your editor when the pending write is editable, d opens the proposed change as a side-by-side diff in your editor when REVEAL_EDITS=1 (the terminal keeps focus unless you press d), f shows the full command, empty/n declines, /last [n] shows recent tool output and asks again, and any other text declines WITH that text as feedback for the agent. Set COPILOT_EDITOR, EDITOR or VISUAL to choose the editor. The agent waits for the editor process to close, then shows the updated diff and asks again; for VS Code use code --wait so closing the edited tab resumes the approval.

Ctrl+C while a turn is running aborts the in-flight model request immediately (a running tool is stopped at the next action boundary; press twice to force quit); at the input prompt it exits the program. An unexpected crash during a turn is caught, reported, and (opt-in) recorded as friction, so the session survives it.

Large terminal pastes use bracketed paste when supported by the terminal: the CLI echoes a compact [pasted <n> lines, <n> chars] marker but sends the full pasted text to the model. Short pastes stay visible in the input so you can edit them normally.

Configuration (.env)

Variable Default Meaning
PROVIDER anthropic anthropic | openai | openai_responses | fake
MODEL model id
API_KEY also accepts ANTHROPIC_API_KEY / OPENAI_API_KEY
ENDPOINT provider default custom API endpoint
MAX_TOKENS 4096 response cap
PROMPT_CACHE 1 Anthropic prompt caching
THINKING off Anthropic: enables extended thinking (1/adaptive or token budget). OpenAI (Responses API only): low/medium/high sets reasoning effort (other truthy = medium), truthy also requests visible summaries; unset = no reasoning on gpt-5.1+; ignored by Chat Completions
STREAM 1 stream responses
LLM_TIMEOUT 180 request timeout (s)
LLM_RETRIES 2 retries on transient model errors (never after streaming started)
MAX_STEPS 50 max tool-loop steps per turn before pausing
TEMPERATURE provider default sampling temperature (opt-in; some models reject a non-default value)
HISTORY_BUDGET 300000 chars before compaction kicks in
HISTORY_KEEP 50 events kept verbatim at the tail
STATE_DIR ~/.cli-agent where sessions, prompt history and generated state are stored
AUTO_YES 0 approve everything (no prompts)
ALLOW_SHELL 0 auto-approve shell commands. By default every shell command asks, even apparently read-only ones, because shell text is not a reliable safety boundary. Shell child processes receive a sanitized environment (no inherited provider/API-key variables by default), but shell access is still arbitrary code execution. Note: enabling this effectively bypasses file-write approval too — an auto-approved shell command can write/delete files (rm, Remove-Item, > file). Treat it as full trust.
ALLOW_OUTSIDE_WORKSPACE 0 auto-approve file reads outside the workspace (otherwise gated); does not affect network access and does not unlock protected cli-agent config/state paths
ALLOW_PRIVATE_NETWORK 0 auto-approve web requests to private, loopback or link-local addresses such as localhost or 169.254.x.x (otherwise gated)
COPILOT_EDITOR notepad on Windows, vi elsewhere editor for editable file-write approvals (e); EDITOR and VISUAL are also accepted
REVEAL_EDITS 0 at a write approval, d opens the proposed change as a side-by-side diff in your editor (needs AUTO_YES=0)
REVEAL_CMD code editor CLI for the reveal; must support --diff a b (e.g. code, cursor)
FRICTION_NOTES 0 offer, at the turn boundary, to draft a richer note for friction that fired (raw signals are always logged to the backlog regardless)
PROMPT_SPOTLIGHT 1 mark tool output as untrusted data in the model context (hidden from the terminal); set 0 to disable
DEBUG_SSE off path to a file; appends every SSE event type + payload gist (Responses API) — for diagnosing which reasoning/summary events a model emits. Note: reasoning summaries are sparse — short thinking bursts often produce none (model behavior, not a bug)

Layout

src/
  core.js           provider-neutral agent loop
  config.js         trusted user configuration
  adapters/         provider integrations and streaming/retry handling
  tools/            shell, file, search, session and web capabilities
  session.js        resumable session storage
  session_awareness.js session-memory prompt text
  context.js        history compaction
  approval.js       approval policy and editor-assisted approvals
  diff.js           session-scoped diffs and undo support
  vision.js         image attachments and clipboard image import
  reveal.js         optional editor diff reveal for proposed writes
  project.js        AGENTS.md / CLAUDE.md project context loader
  self.js           live self-model
  friction.js       friction/requirements backlog
  tui.js            terminal UI
  index.js          entry point / chat loop
test/               node --test suite

Tests

npm test

About

Zero-dependency, provider-neutral CLI coding agent for Node.js with a live, drift-proof self-model

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors