code-automaton

中文文档
1.6.2发布于 2026/11/03MITES Module构建来源已验证

Code Automaton — a terminal agentic coding tool with session recall.

原始使用文档
文档目录12 节
  1. Sessions
  2. Scrolling back
  3. Renaming a session
  4. Install
  5. Develop
  6. Steering a running turn
  7. Images
  8. Tools
  9. Commands
  10. Config
  11. Releasing
  12. License

Code Automaton

A terminal agentic coding tool with session recall. It runs against any OpenAI-compatible API (DeepSeek by default), with a full-screen TUI and multiple live sessions per terminal.

Sessions

coda keeps several conversations open at once in a single terminal. Each session streams independently: switch away from a busy session and its response keeps accumulating, then switch back to see it.

coda starts on a new session, with the cursor already in the input — a saved session is never opened for you. Your previous sessions are one keypress away: press ← (or Ctrl+R) to open the picker, and Esc returns you to the new session. The picker has a text prompt:

  • Type a message and press Enter → starts a brand-new session with that message as its first turn.
  • Type /command and press Enter → runs that command (/help, /rename, …) instead of starting a session. An unknown command is reported in the picker and the picker stays open so you can fix it.
  • Press Enter with nothing typed → opens the session highlighted with ↑/↓.
  • Ctrl+X deletes the highlighted session; Alt+R renames it.
  • Typing does not filter the list — use ↑/↓ to move through it.

In the picker every printable key is text for the new session's message; no letter is a shortcut, so a message can start with any character. Delete and rename are the modifier chords Ctrl+X and Alt+R, so they never collide with typing.

KeyAction
EnterSend the current line — or, mid-turn, fold it into the running turn
←Empty input: open picker · non-empty: move cursor left
→ / Home / EndMove the cursor
Ctrl+A / Ctrl+EJump to start / end of line
Backspace / DeleteDelete before / under the cursor
Ctrl+W / Alt+BackspaceDelete previous word
Alt+DDelete next word
Ctrl+U / Ctrl+KDelete to start / end of line
Alt+B / Alt+FMove back / forward one word
↑ / ↓Scroll transcript one line
PgUp / PgDnScroll transcript one page
Mouse wheelScroll transcript (3 lines per notch)
End (scrolled back)Jump back to the newest output
Ctrl+ROpen the session picker
type (in picker)Enter starts a new session with that text (does not filter the list). A /command runs the command instead
↑ / ↓ (in picker)Move through sessions
Enter with nothing typedOpen the highlighted session
Ctrl+X (in picker)Delete the highlighted session
Alt+R (in picker)Rename the highlighted session
Esc (in picker)Close the picker
Alt+RRename the current session (Enter saves, Esc cancels)
Ctrl+VAttach the clipboard image (image-only clipboard; see Images)
Ctrl+TNew session
Ctrl+XClose the current session
Ctrl+CExit
/helpShow the command and key reference
/quit · /exitExit (same as typing quit / exit; sessions are saved)

Sessions are saved as JSON in ~/.coda/sessions/ (mode 600) and reloaded the next time you start coda.

Opening the picker re-reads that directory, so sessions started, renamed or deleted in another terminal show up here too: new sessions are added, renames and new messages are picked up, and sessions deleted elsewhere disappear. A session that is still running a turn in this terminal is left alone — its in-flight output has not been written yet, so it would be clobbered.

The picker is always sorted most-recently-updated first, so two terminals list the sessions they can both see in the same order. A session that has not been used yet is not on disk (an empty session is not saved), so it appears only in the terminal that started it until its first message.

A session you open is locked for as long as this terminal is on it, so a second terminal cannot open the same session and overwrite your work. The lock is advisory — a small <id>.lock file beside the session, refreshed with a heartbeat while coda runs — and is released when you switch away, close the session, or quit. By default coda will not open the session at all while another terminal holds it, and says which process does; that is the loss-proof default, since two writers to one session silently overwrite each other. A lock left by a terminal that crashed goes stale on its own (a dead process on the same machine, or a heartbeat older than 30 seconds across machines) and is taken over automatically.

Scrolling back

Long answers and tool output scroll past the visible window. coda keeps the whole transcript of the session and scrolls through it:

  • Mouse wheel — scrolls the transcript a few lines per notch.
  • ↑/↓ — one line at a time; PgUp/PgDn — a page.
  • End — returns to the newest output.

The header shows ▲ scrolled back N while you are reading history. Scrolling is independent of streaming: a reply that is still arriving keeps appending at the tail without yanking you back down, so you can read earlier output while the model is still writing.

coda enables terminal mouse reporting (SGR, 1000+1006) while it runs, so the wheel scrolls its transcript — the whole session, not just what happens to be on screen. The tradeoff is that the terminal stops doing its own wheel scrollback and drag-to-select while coda is open; hold Shift while dragging to select and copy text, which is the standard escape hatch in Windows Terminal and most other emulators. Mouse reporting is switched off on exit, including on Ctrl+C and SIGTERM.

If dragging to select is more important to you than the wheel, disable mouse reporting entirely:

export CODA_MOUSE=off

coda then leaves the mouse alone — the terminal's own drag-to-select and wheel scrollback work as usual — and the transcript is scrolled with ↑/↓, PgUp/PgDn, and End instead. This is the fix when a terminal does not honour Shift-to-select, or when Shift-drag selects unreliably.

coda also repaints its frame in place rather than erasing the screen on every render. A full-screen erase per frame — and with a streaming reply there is one per chunk — left the terminal with nothing to scroll. The screen is cleared once at startup; after that each frame overwrites in place, and the last frame is left on screen at exit so it stays in the terminal's own scrollback.

Renaming a session

A session names itself after its first message. To rename it, press Alt+R in the chat view — or type /rename — and the input line turns into a title editor, pre-filled with the current title. Typing /rename Some title renames it directly, without the editor. From the session picker, Alt+R renames the session currently highlighted in the list.

  • Enter saves. Esc cancels and keeps the old title.
  • ←/→, Home/End, Backspace, and the usual Ctrl+A/Ctrl+E/Ctrl+W and Alt+B/Alt+F/Alt+D editing keys all work while editing.
  • Clearing the title and pressing Enter returns it to auto-titling, so the next message names the session again.

The new title is written to disk immediately and shows in the header and the picker.

Install

npm install -g code-automaton

The package is named code-automaton, but the command it installs is coda:

coda --version
coda --help

You need an API key. Export it in your shell, or put it in a .env file:

export CODA_API_KEY=sk-...

.env is optional and is read from the current directory, then from the project root. coda parses it itself — there is nothing to source and no dotenv-cli needed. Variables already set in your environment always win, so an exported key takes precedence over .env.

The -g matters: a bare npm install code-automaton only links the coda command into ./node_modules/.bin/, which is not on your PATH.

Develop

From a clone, install dependencies and run straight from the TypeScript source — tsx compiles on the fly, so there is no build step:

npm install
cp .env.example .env   # then put your CODA_API_KEY in .env
npm run dev

Pass CLI flags through with --:

npm run dev -- --help
npm run dev -- --version

The globally installed coda runs the compiled output in dist/, which only refreshes when you build:

npm run build
node dist/index.js

So npm run dev reflects your edits immediately and coda does not — rebuild before testing a change through the global command.

Steering a running turn

While a turn is running — which, with tool calls, can be a while — pressing Enter does not queue your text for later. It folds it into the turn: the message is appended to the conversation, and because the full history is re-sent on every step of the agent loop, the model sees it at its next step, typically between tool calls. It appears in the transcript as (mid-turn) ….

That means you can interrupt a long bash command or redirect a multi-step task without waiting for it to finish. It is best-effort rather than an abort: if the model was already composing its final answer, the steer arrives after it. To stop a turn outright, close the session (Ctrl+X) or start a new one (Ctrl+T).

Images

Attach a screenshot to a message and the model can reason about it:

InputWhat it does
Ctrl+VAttaches the clipboard image, if the clipboard holds an image and no text
/pasteAttaches the clipboard image regardless of any accompanying text
/image <path>Attaches an image file (png, jpeg, webp, gif; max 5 MB)

Ctrl+V only fires when the clipboard is image-only, so ordinary text pastes still reach the terminal. A clipboard can hold an image and text at once — copying a chart from a spreadsheet, or a browser image with its source URL — and in that case text paste wins. Use /paste when you want the image anyway.

Messages carrying an image are routed to a vision model; everything else goes to the text model. Both are configured separately (see Config), so a text-only setup keeps working unchanged.

Attachments are stored in the session as a [image: path] placeholder rather than the image bytes: a 1 MB screenshot would otherwise put ~1.4 MB of base64 into every session file. The file is re-read when the session is reloaded, so a moved or deleted image degrades to the placeholder.

Clipboard access is WSL-only, because Windows Terminal cannot pass image data to a program through standard input — the clipboard is read from the Windows side via PowerShell. On macOS/Linux use /image <path>.

Tools

  • read_file — read a file
  • write_file — create/overwrite a file
  • edit_file — replace the first occurrence of a string
  • list_dir — list a directory
  • bash — run a shell command

Commands

Slash commands are typed into the input and sent with Enter.

CommandWhat it does
/help, /?Print the command and key reference into the transcript
/quit, /exitExit coda and save sessions. Same as typing quit / exit, or Ctrl+C
/pasteAttach the clipboard image (see Images)
/image <path>Attach an image file (see Images)
/rename <title>Rename the current session. With no title, opens the interactive title editor (same as Alt+R)

A line that begins with / but names no known command is not sent to the model. Instead coda reports unknown command: … in the transcript and leaves your text in the input so you can correct it (or press Esc to clear it). This keeps a typo like /quti from being interpreted as a prompt. A bare / on its own is exempt and is sent as ordinary text (e.g. a pasted absolute path).

Config

Env varDefault
CODA_API_KEY(required; falls back to DEEPSEEK_API_KEY, OPENAI_API_KEY, then ANTHROPIC_API_KEY)
CODA_BASE_URLhttps://api.deepseek.com (also reads DEEPSEEK_BASE_URL / OPENAI_BASE_URL)
CODA_MODELdeepseek-chat (also reads DEEPSEEK_MODEL / OPENAI_MODEL)
CODA_SESSIONS_DIR~/.coda/sessions (also reads the older DSC_SESSIONS_DIR)
CODA_MOUSEon — set to off to leave mouse selection to the terminal (see Scrolling back)
CODA_VISION_MODELthe value of CODA_MODEL
CODA_VISION_BASE_URLthe value of CODA_BASE_URL
CODA_VISION_API_KEYthe value of CODA_API_KEY

The CODA_VISION_* variables select the model used for messages containing an image. They fall back to their text counterparts, but a model without vision support will silently ignore the image rather than error — so set them explicitly if you attach screenshots.

If no API key is found, coda exits with an error explaining the variable names it looked for.

Note: ANTHROPIC_BASE_URL is intentionally not read. Anthropic-shaped URLs (e.g. https://api.deepseek.com/anthropic) are not OpenAI-compatible and would fail; only the key is borrowed from ANTHROPIC_API_KEY, so pair it with an explicit CODA_BASE_URL if you rely on that fallback.

Releasing

Releases are staged by CI on a version tag, then approved by hand. main is protected, so the version bump must land through a pull request — a direct git push to main is rejected by the repository rule, and a tag pushed before the bump is merged would point at a commit that is not on the branch. The order below keeps the two consistent:

# 1. Bump the version on a branch (npm version also builds dist/).
npm version patch                 # or minor / major — commits 1.4.3 + tags locally
git switch -c chore/release-$(node -p "require('./package.json').version")
git push -u origin chore/release-$(node -p "require('./package.json').version")

# 2. Open a PR and merge it. Do NOT squash: that rewrites the commit the
#    local version tag points at. Use a merge commit or fast-forward.
gh pr create --fill && gh pr merge --merge

# 3. Now push the tag, once its commit is on main.
git switch main && git pull --ff-only
git push origin v$(node -p "require('./package.json').version")

CI builds, checks the tag matches package.json, smoke-tests the artifact and runs npm stage publish --provenance. It also creates a GitHub release.

Then approve the staged version in the npm web UI (account → Staged packages). That approval is the 2FA proof-of-presence, so it stays manual — and it is why the CI token needs no 2FA bypass. Once approved, mark the release Latest:

gh release edit v1.4.3 --latest   # substitute the version just released

The release is created with --latest=false because a staged version is not installable yet; "Latest" should follow what npm actually serves.

Before deciding to reuse a version number, check the per-version endpoint — the top-level package document is cached and can lag:

curl -s https://registry.npmjs.org/code-automaton/<version>

License

MIT — see LICENSE.

版本与发布记录

code-automaton 共发布 20 个版本,首次发布于 2026/10/31;过去 12 个月发布了 20 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.6.2latest2026/11/03今天
1.6.12026/11/03今天
1.6.02026/11/03今天
1.5.12026/11/03今天
1.5.02026/11/03今天
1.4.42026/11/03今天

关于 code-automaton 的常见问题

code-automaton 是什么?

代码自动-一个终端代理编码工具与会话召回。

如何安装 code-automaton?

在项目目录运行 npm install code-automaton,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 coda,可以用 npx coda 直接运行。

code-automaton 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/code-automaton 是否存在。

code-automaton 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

code-automaton 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

code-automaton 可以商用吗?

code-automaton 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

code-automaton 还在维护吗?

最新版本 1.6.2 发布于 2026/11/03(今天);至今共发布 20 个版本,其中过去 12 个月发布了 20 个;首次发布于 2026/10/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。