Doesn't the read me keep repeating itself
Standalone CLI agent. Original code. Original voice. Zero platform lock-in.
Orbit is a terminal-native AI agent built from scratch โ no LangChain, no Semantic Kernel, no wrapper. Just Node.js, DeepSeek (or any OpenAI-compatible API), and a clean set of file/shell tools.
He reads. He writes. He runs commands. He plans. He learns.
Orbit runs anywhere Node.js 18+ does. He's 100% native โ zero dependencies.
macOS:
brew install node # if you don't have Node yet
node -v # should be 18.x+
p npm install
git clone https://github.com/tgoapple/orbit-agent
cd orbit-agent
cp .env.example .env # add your API key
./orbit-agent # or: node src/cli.mjsLinux (Ubuntu/Debian):
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v # should be 18.x+
npm install
git clone https://github.com/tgoapple/orbit-agent
cd orbit-agent
cp .env.example .env # add your API key
node src/cli.mjs # (no ./orbit-agent script on Linux)Windows (PowerShell):
# Install Node.js from https://nodejs.org (v18+)
# Or with winget:
winget install OpenJS.NodeJS.LTS
node -v # should be 18.x+
npm install
git clone https://github.com/tgoapple/orbit-agent
cd orbit-agent
copy .env.example .env # add your API key
node src/cli.mjsOrbit uses zero npm dependencies โ just Node.js built-in modules (
fs,path,child_process,os,readline,fetch). If you have Node 18+, you have everything. Nonpm installneeded (but doesn't hurt).
- Node.js 18+ โ check with
node -v - npm โ comes with Node.js
- An API key โ DeepSeek, OpenAI, OpenRouter, or any OpenAI-compatible provider
git clone https://github.com/YOUR_USER/orbit-agent.git
cd orbit-agentnpm installcp .env.example .envThen edit .env with your API key. For DeepSeek (recommended โ cheap, fast, good):
OPENAI_API_KEY=sk-your-deepseek-key-here
OPENAI_BASE_URL=https://api.deepseek.com/v1
OPENAI_MODEL=deepseek-chatFor OpenAI:
OPENAI_API_KEY=sk-your-openai-key-here
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mininode src/cli.mjsOr the shorthand:
./orbit-agentThat's it. You're talking to Orbit.
For faster responses on subsequent messages, run Orbit as a persistent daemon:
node src/orbit-harness.mjsThis keeps Orbit in memory on TCP port 12999. Send messages via netcat:
echo 'Hello' | nc localhost 12999What it fixes: No cold starts. Module imports, persona, and session stay loaded between messages.
Without daemon: Every message loads everything from scratch (5-15s startup). With daemon: First message takes 5-15s, everything after is instant (1-2s).
Custom port:
node src/orbit-harness.mjs --port 7899Or via environment:
HARNESS_PORT=7899 node src/orbit-harness.mjs./orbit-agentJust start typing. Orbit responds, remembers the conversation, and uses tools when needed.
In-session commands:
| Command | What it does | |---
Single response, no persistence:
./orbit-agent --one-shot "What's on my Desktop?"Keep different conversations separate:
./orbit-agent --session coding
./orbit-agent --session trading
./orbit-agent --session personal| Tool | What it does | |---
You: Build me a simple stopwatch HTML page on my Desktop
Orbit: Let me plan that out and build it.
[uses plan tool, then supervise tool with write_file + open steps]
Done. Open at ~/Desktop/stopwatch.html. It's a clean CSS stopwatch
with lap functionality. Open it in your browser.
You: I need help setting up a Discord bot
Orbit: Let me load the Discord skill.
[uses load_skill("discord-skill")]
Got it. Here's what you need...
orbit-agent/
โโโ src/
โ โโโ cli.mjs # Main entry โ interactive REPL + one-shot
โ โโโ tools.mjs # All 8 tool implementations
โ โโโ config.mjs # Env-based configuration loader
โ โโโ session-store.mjs # Persistent JSON session storage
โ โโโ openai-client.mjs # OpenAI-compatible API client
โโโ personas/
โ โโโ default.md # System prompt โ who Orbit is
โโโ data/
โ โโโ memory.md # Long-term memory (read at startup, write to remember)
โ โโโ sessions/ # Saved conversations (auto-managed)
โโโ SOUL.md # Identity document โ read this one first
โโโ .env.example # Copy to .env and add your API key
โโโ package.json # Dependencies (just node-fetch)
โโโ README.md # You're here
All settings go in .env (copy from .env.example):
| Variable | Required | Default | Description | |---
DeepSeek (recommended โ $0.14/M tokens):
OPENAI_BASE_URL=https://api.deepseek.com/v1
OPENAI_MODEL=deepseek-chatOpenAI:
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-miniOpenRouter:
OPENAI_BASE_URL=https://openrouter.ai/api/v1
OPENAI_MODEL=openai/gpt-4o-miniAny local model (Ollama, LocalAI, etc.):
OPENAI_BASE_URL=http://localhost:11434/v1
OPENAI_MODEL=qwen2.5:7bEdit personas/default.md โ this is his system prompt. Make him more formal, more technical, or completely different.
Edit SOUL.md โ this is his identity. The code stays the same, but who he is changes.
Set WORKSPACE_ROOT in .env:
WORKSPACE_ROOT=~/Documents/ProjectsOrbit can load skills on demand. Set SKILL_DIR to a folder containing skill folders, each with a SKILL.md file.
Want to create a skill? Just make a folder:
my-skills/
โโโ trading/
โ โโโ SKILL.md
โโโ design/
โ โโโ SKILL.md
โโโ sysadmin/
โโโ SKILL.md
Orbit can run as a Telegram bot. The bridge script (orbit-telegram-bridge.mjs) is not included in this repo, but the pattern is simple:
- Create a bot with @BotFather on Telegram
- Write a 200-line polling script: get updates from Telegram โ write to bridge JSON โ read response โ send back
- Run it as a background service
Orbit has one runtime dependency: node-fetch (used only if running Node <18). Node 18+ uses the built-in fetch.
Everything else is native Node.js โ fs, path, child_process, os.
- Your API key lives in
.envโ this file is in.gitignoreso it never gets pushed - File tools are scoped to
WORKSPACE_ROOTโ Orbit can't escape it - All data stays local. No telemetry. No phone home.
MIT โ do whatever you want with it. Make it yours.
"He's one day old and already making fish tanks." โ Orbit's creator, Day 1
"Good instinct. That's the right question to start with." โ Nicole, Orbit's mentor