A terminal coding agent — like Claude Code, powered by the Nocturne API. It reads and edits files, runs commands, searches your codebase, and accepts pasted images, all from a single cross-platform binary.
╭────────────────────────────────────────────────────────╮
│ ◗ Nocturne coding agent · v0.3.0 │
│ │
│ model navy:gpt-5.5 │
│ cwd ~/projects/my-app │
╰─────────────────────────────────────────────────────────╯
› build a small http server in main.go and run it
● write_file(main.go)
└ Wrote 412 bytes to main.go
● run_command go run main.go &
└ listening on :8080
macOS / Linux
curl -fsSL https://nocturnecode.lol/install.sh | shWindows (PowerShell)
irm https://nocturnecode.lol/install.ps1 | iexThe hosted installer grabs a prebuilt binary for your OS/arch from
nocturnecode.lol/bin/, falls back to GitHub Releases, then falls back to building
from source if Go is available. Override the source repo with
NOCTURNE_REPO=you/your-fork and the install location with
NOCTURNE_INSTALL_DIR.
From source (Go 1.26+):
git clone https://github.com/lightight/nocturnecli && cd nocturnecli
make install # -> ~/.local/bin/nocturne
# or: go build -o nocturne . && ./nocturneNocturne needs an API key. Get one from your Nocturne account page,
then launch Nocturne and save it once with /key:
nocturne
› /key noct_your_keyThe key is written to ~/.config/nocturne/config.json (macOS: ~/Library/Application Support/nocturne),
with file permissions 0600, and reused for every project on your machine. No export, no per-folder
.env. A bare /key also works: it saves whatever key is already loaded.
If you'd rather manage the key yourself, Nocturne still reads NOCTURNE_API from a local .env file or
the environment. Precedence is: an exported environment variable first, then the saved config, then a
local .env — so a stale project .env can never silently override the key you saved with /key.
Nocturne verifies the key on startup. If it has expired or stopped working you'll be told to create a
new one at nocturne.lol/account — then save it with /key as above.
The default model is navy:gpt-5.5; change it with /model <id> in-app or -m on the command
line. Model availability is per-account, so use an id you've been granted.
nocturne # interactive TUI
nocturne cowork # interactive TUI in cowork (computer-use) mode
nocturne -p "fix the test in foo_test.go" # one-shot, non-interactive (auto-runs tools)
nocturne cowork -p "organize my ~/Downloads" # one-shot with computer-use tools
nocturne -m some-model # override the model for this run
nocturne update # self-update to the latest release
nocturne update --check # check for a newer release without installing
nocturne serve --addr :8080 --bin ./dist # host docs, installers, and relay
nocturne --helpReplies stream live by default — tokens appear as the model writes them, then
settle into the final formatted answer. Toggle it with /stream.
| Command | Does |
|---|---|
/help |
list commands |
/model [id] |
open the model picker, or set a model by id |
/models |
list the models your account can use |
/level |
thinking level: off · normal · extended |
/key [noct_…] |
save your API key to the private config (remembered everywhere) |
/image <path> |
attach an image file (or Ctrl+V for the clipboard) |
/auto |
toggle auto-accept for edits & commands |
/stream |
toggle live response streaming (on by default) |
/cd <dir> |
change the working directory |
/cowork |
toggle computer-use mode (screen control + whole filesystem) |
/plan |
plan mode — explore read-only, run again to approve & execute |
/tokens |
show token usage, context size & quota |
/compact |
summarize the conversation to free up context |
/resume |
resume a saved chat from this directory |
/new |
start a new chat |
/remote |
control this session from your browser (E2E-encrypted) |
/clear |
clear the conversation (starts a new session) |
/init |
generate a NOCTURNE.md for the project |
/update |
update Nocturne to the latest release |
/exit |
quit (Ctrl+C also works) |
- Enter — send · Alt+Enter — newline · Ctrl+V — paste a clipboard image
- PgUp/PgDn — scroll the transcript · Esc — interrupt a running request · Ctrl+C — quit
- Type
/to open the command menu; ↑/↓ to move, Tab to complete, Enter to run.
Nocturne runs as a full-screen TUI and reflows when you resize the terminal.
Attach an image three ways:
- press Ctrl+V to grab an image off the system clipboard,
/image diagram.png, or- drag a file into the terminal / mention a path inline, e.g.
explain ./diagram.png.
The model can actually see the image when you're on a vision-capable model (marked
vision in /model / /models, e.g. navy:claude-haiku-4.5, navy:gpt-5.4-mini,
navy:gpt-5.5, navy:gemini-3.5-flash). On a non-vision model the image still attaches, and Nocturne
has a vision model describe it before sending that description as text.
Clipboard image support uses native helpers:
pngpaste/AppleScript on macOS,wl-paste/xclipon Linux, and PowerShell on Windows.
Cowork mode lets Nocturne work the whole computer, not just the project directory — inspired by
desktop agents that see the screen and act on it. Start it with nocturne cowork, toggle it
mid-session with /cowork, or just ask for something that needs it: the agent can request cowork
mode itself, and you approve once.
In cowork mode the agent can:
- see the screen —
screenshotcaptures the display and a vision model reads it, - drive the GUI — click, move, scroll, type, and press keys (each action needs your approval unless you've enabled auto-accept),
- open things — apps, files, folders, and URLs,
- navigate the whole filesystem — absolute paths anywhere, not just the working directory.
Screen work needs the Accessibility permission on macOS (System Settings → Privacy & Security → Accessibility) and Screen Recording for screenshots. Screenshots report the screen size in points vs. pixels so click coordinates land correctly on Retina displays. On a non-vision model the capture is described by a vision model as text (clickable elements included, with pixel coordinates) — clicking, typing, and scrolling work the same either way, since they take plain JSON arguments.
Backends:
screencapture+ CoreGraphics/System Events on macOS, PowerShell on Windows, and a built-in pure-Go X11 backend on Linux — no extra packages to install on any platform (xdotool+grim/scrot/ImageMagick are used only as fallbacks when no X server is reachable, e.g. a native Wayland session without XWayland).
- Chats are saved automatically, scoped to the directory they ran in.
/resumeopens a picker of saved chats from the current directory and restores one (messages, model, transcript). /compactsummarizes the conversation into a compact brief and continues from it, freeing up context. The summary is kept silently as context — it isn't dumped into the chat. Nocturne also compacts automatically at 90% of the selected model's reported context window./tokensshows the live context size.- Scroll the transcript with PgUp/PgDn or the mouse wheel. Text selection, copy, and paste continue to work natively. The input box wraps long prompts onto new lines (it grows as you type) instead of scrolling text off.
- While a reply streams, in-progress tool calls show as a tidy
● preparing tool call…line rather than raw<tool …>text.
Run /remote to drive the session from a phone or another computer. Nocturne
registers an end-to-end encrypted session with the hosted relay and prints a
public URL + a 6-character pairing code:
Remote control · end-to-end encrypted
open https://nocturnecode.lol/r/m6x8q2p4bkx7y
code DNUH9W
Open the URL on any device and enter the code. You can then send messages and
watch replies (and tool activity) stream in live. The browser box mirrors the
terminal's: slash commands autocomplete in a menu (/model, /plan,
/compact, …) and run in the session, the draft is synced both ways as you
type, and while the agent is working the Send button becomes a Stop button
that interrupts it. Everything between the browser
and the terminal is end-to-end encrypted with AES-256-GCM using a key derived
from the pairing code (PBKDF2). The pairing code never crosses the wire; the
relay only sees opaque ciphertext, and a wrong code simply can't decrypt
anything. Run /remote off to stop. Tool approvals still happen at the terminal,
so the human at the keyboard stays in control.
Use NOCTURNE_RELAY=https://your-host.example to point /remote at a different
relay while developing or self-hosting.
nocturne serve runs the docs site, hosted install scripts, optional binary
downloads, and the encrypted remote-control relay:
make dist
nocturne serve --addr :8080 --bin ./distPut it behind HTTPS at nocturnecode.lol with your reverse proxy of choice. The
browser remote client needs HTTPS for Web Crypto, and the server honors
X-Forwarded-Proto: https when it templates the hosted installer URLs.
/modelopens an arrow-key picker of every model your account can use, with pricing andreasoning/visiontags;/model <id>sets one directly./models(ornocturne models) lists them. The list comes fromGET /api/ai/config./level off|normal|extendedcontrols how much reasoning models think before answering.extendedalso unlocks thetasktool: the model can delegate a self-contained sub-task to a sub-agent with its own agent loop and full tool access (aliases:agent,subagent). You approve the delegation once; inside the sub-agent tools run without further prompts, and its final report comes back as the tool result. Sub-agents run at extended thinking and can't spawn sub-agents of their own./tokensshows session tokens, your daily quota (used / cap / remaining, straight from thequotaobject the API returns on every call), and the current model + thinking level.
The Nocturne endpoint is a plain completion API with no native function-calling, so
Nocturne drives tools with a small prompt protocol: the model emits
<tool name="…">{json}</tool> blocks, the CLI executes them (read_file, write_file,
edit_file, list_dir, search, run_command), feeds the results back wrapped in
<tool_result>, and loops until the model returns a plain-text answer. Edits and
commands ask for confirmation unless auto-accept is on.
Not every model follows the protocol perfectly, so Nocturne is defensive about it:
edit_fileis whitespace-tolerant — it matches exactly first, then falls back to a line-based match ignoring trailing whitespace and indentation (re-indenting your replacement to the file), so a near-missold_stringstill lands. It never silently no-ops: results are clearlyEDIT APPLIED:orEDIT FAILED:, and a failure shows the closest matching text.- Tolerant tool-call parsing — recovers from the malformed JSON weaker models emit (extra
braces, trailing junk, raw newlines inside strings) and the function-call-style
<tool>name(…)variant, and de-duplicates repeated calls. - A short few-shot demo is prepended to every request and the system prompt forbids the "I'll do it… Done" no-op, which stops weaker models refusing or claiming success without acting.
- Transient upstream errors (502/503/504) are retried automatically.
Reliability still varies by model — capable ones (e.g. navy:claude-haiku-4.5,
navy:deepseek-v4-pro, gpt-5.5) edit dependably; smaller/erratic ones less so. Switch any
time with /model. (Some models are also hosted on third-party providers that occasionally
return 502 — that's upstream, not Nocturne.)
Set NOCTURNE_DEBUG=/path/to/log to dump raw requests and responses for troubleshooting.
MIT — see LICENSE.