Skip to content

pivanov/cursor-cli

Repository files navigation

cursor-cli

A terminal REPL for the Cursor agent, built on the Cursor TypeScript SDK (@cursor/february).

Send prompts, watch streamed thinking + tool calls + diffs in your terminal, resume past sessions, swap themes - all without leaving the shell.

cursor-sdk.mp4

Requirements

  • Node.js ≥ 22
  • A Cursor API key - set CURSOR_API_KEY in your environment or in .env.local at the repo root.

Install & run

bun install
cp .env.example .env.local      # paste your CURSOR_API_KEY
bun run dev

Or with npm/pnpm:

npm install
echo "CURSOR_API_KEY=sk-..." > .env.local
npm run dev

Run from anywhere (cursor-cli on $PATH)

bun run install:local writes a small shell wrapper to dist/cursor-cli and symlinks it into ~/.local/bin/cursor-cli. After that, cursor-cli works from any directory:

bun run install:local
# add to PATH if it isn't already:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc

cd ~/some/project
cursor-cli                       # opens the REPL with cwd preserved

The wrapper execs bun run src/cli.ts "$@" against this checkout, so the SDK's session store writes per the user's cwd while module resolution still uses this project's node_modules.

Custom destination:

bun run install:local --link=/usr/local/bin

Why a wrapper, not a single-file binary

bun build --compile would produce one self-contained executable, but @cursor/february statically imports the userland sqlite3 package

  • a native (.node) binding loaded via node-pre-gyp / bindings. That fails three ways under --compile:
  1. Bun can't embed .node files into a compiled binary.
  2. The compiled binary's sealed virtual filesystem (/$bunfs/) can't reach host node_modules/ for runtime requires, even with --external.
  3. bindings walks the runtime filesystem looking for the caller's package.json - those paths don't exist inside the binary.

If @cursor/february switched its local-runtime store to node:sqlite (stable in Node ≥ 22.5) or bun:sqlite (Bun builtin), this CLI could compile to a single ~70 MB self-contained executable just like ls-prove does. Until then, the wrapper is the cleanest portable distribution.

Slash commands

Command Description
/help Show keyboard shortcuts and command list
/clear Reset the current session (rotates agent)
/sessions Browse, resume, archive, or delete sessions
/model Switch the active model
/theme Pick a theme (dark, light, daltonized, ANSI)
/exit Quit

Keyboard shortcuts

Readline-style line editing (Ctrl+A/E/B/F/W/U/K, Alt+B/F/Backspace), Shift+Enter for newline, ↑/↓ for history, Esc to dismiss overlays, Ctrl+C twice to exit.

Project layout

src/
├── cli.ts        entrypoint
├── repl/         Ink components + REPL state
├── sdk/          @cursor/february adapter (typed surface)
└── session/      persisted agent-id store

Scripts

  • bun run dev - start the REPL
  • bun run install:local - install the cursor-cli wrapper into ~/.local/bin
  • bun run lint - Biome + tsc + knip
  • bun run lint:fix - auto-fix what's safe

Background

A weekend exploration of the @cursor/february private alpha - roughly 30 hours from bun init to the first usable REPL. Built to stress the SDK from an integrator's seat and put concrete feedback in front of the Cursor team.

License

MIT - see LICENSE.

About

A terminal REPL for the Cursor agent, built on the Cursor TypeScript SDK

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors