- Install
- Quickstart
- Interactive REPL
- Providers
- Files, sessions & output styles
- One-shot
ask - Slash commands
- Auth & API keys
- Skills & subagents
- MCP, hooks, custom commands
- Permissions, output styles, status line
- Talking to the running app
- Expose as HTTP server
- External agent clients (acp-serve)
- Subcommand reference
- Troubleshooting
Install
Pick the path that matches your OS — the native binaries are the default. Or skip install entirely and try it in your browser first: same prompt against Claude, DeepSeek, OpenAI, Gemini side-by-side, no setup.
macOS & Linux (native binary)
curl -fsSL https://lingcode.dev/install-cli.sh | sh
Downloads a tarball to ~/.lingcode/cli/ and symlinks it to ~/.local/bin/lingcode. macOS tarballs are signed + notarized; the Linux tarball is unsigned. The bundled Node bridge ships inside, so the Claude provider works without LingCode.app installed (you still need Node.js and an API key).
Windows (native binary)
iwr -useb https://lingcode.dev/install-cli.ps1 | iex
Downloads a Bun-compiled lingcode.exe to %LOCALAPPDATA%\Programs\lingcode\ and adds it to your User PATH. PowerShell 5.1+ (ships with Windows 10/11); x64 and ARM64 both supported. The installer auto-detects AVX2 and falls back to a baseline build on older CPUs / VMs. The binary is unsigned in v0.9.x — Windows Defender SmartScreen will warn on first run; click More info → Run anyway. Authenticode signing is on the roadmap. After install, lingcode upgrade handles future versions in-place (the running .exe is renamed to lingcode.exe.old while the new binary takes its slot).
After install — in the same PowerShell window:
# Free first chat — no signup needed, uses LingModel (free tier)
lingcode run --provider lingmodel "hello"
# For higher limits or other providers: grab a token at
# https://lingcode.dev/cli-token.html and run
lingcode providers login
That's it. lingcode run "<prompt>" drops into a multi-turn > REPL on the same session after each one-shot — type follow-ups, /quit to exit. If you closed the terminal before testing, just reopen any PowerShell window; the install added lingcode to your User PATH.
From an installed LingCode.app
/Applications/LingCode.app/Contents/Resources/bin/lingcode install
The install subcommand tries /usr/local/bin first, falls back to ~/.local/bin, prints a PATH hint if needed.
Quickstart
# One command to store a key in the Keychain (opens browser)
lingcode auth login
# Interactive session (Claude by default)
lingcode
# Interactive session with another provider
lingcode --provider ollama --model llama3.2
lingcode --provider groq --model llama-3.1-70b-versatile
# One-shot
lingcode ask "explain this error" < build.log
echo "what's 2+2?" | lingcode ask -
# Check your setup
lingcode auth status
lingcode --help
Interactive REPL
lingcode with no arguments drops you into an interactive multi-turn session. It's the same as lingcode repl, just shorter to type.
The REPL has two flavors depending on provider:
- Claude mode — full agentic loop: tool use, file edits, MCP servers, hooks, session resumption, permission prompts, colored diffs. Runs via the bundled Node bridge +
@anthropic-ai/claude-agent-sdk. - OpenAI-compatible mode — full agentic loop with tool dispatch, MCP servers, Skills, subagents, hooks, and custom slash commands on any OpenAI-compatible endpoint: OpenAI, Groq, Together, OpenRouter, Mistral, xAI, Fireworks, Ollama, DeepSeek, and custom proxies.
Input editor
When stdin is a TTY, you get a proper line editor:
↑ / ↓ | Recall previous / next input |
← / → / Home / End | Cursor movement |
Tab | Complete slash commands (builtin + custom) |
Trailing \ | Continue the input on the next line |
Ctrl-C | Cancel running query (Claude) / abort line |
Ctrl-D | Exit on empty line, otherwise delete character |
| Bracket-paste | Paste multi-line clipboard content as one input |
Prompt
The REPL prompt shows turn count and cumulative cost once they're non-zero:
lingcode> explain this repo
…
lingcode [1t $0.003]> now suggest a refactor
…
lingcode [2t $0.011]>
Providers
Pick with --provider; override model, base URL, or API key env var as needed. Every provider runs the agent loop with tool calls by default.
| Provider | Env var | Default model | Tools? |
|---|---|---|---|
claude (default) | ANTHROPIC_API_KEY | SDK default (Sonnet) | ✓ |
deepseek-claude | DEEPSEEK_API_KEY | deepseek-v4-pro[1m] | ✓ |
deepseek-compat | DEEPSEEK_API_KEY | deepseek-v4-flash | ✓ |
openai | OPENAI_API_KEY | gpt-4o-mini | ✓ |
gemini | GEMINI_API_KEY | gemini-2.5-flash | ✓ |
kimi | MOONSHOT_API_KEY | kimi-k2.6 | ✓ |
qwen | DASHSCOPE_API_KEY | (provider default) | ✓ |
groq | GROQ_API_KEY | llama-3.1-70b-versatile | ✓ |
together | TOGETHER_API_KEY | Llama-3.3-70B-Instruct-Turbo | ✓ |
openrouter | OPENROUTER_API_KEY | anthropic/claude-sonnet-4 | ✓ |
mistral | MISTRAL_API_KEY | mistral-large-latest | ✓ |
xai | XAI_API_KEY | grok-2-latest | ✓ |
fireworks | FIREWORKS_API_KEY | llama-v3p1-70b-instruct | ✓ |
ollama | — (none) | llama3.2 | ✓ |
Two ways to use DeepSeek
deepseek-compat uses DeepSeek's OpenAI-compatible endpoint with lingcode's own agent loop. deepseek-claude uses DeepSeek's Anthropic-compatible endpoint, which lets the polished Claude path (full Agent SDK, sessions, hooks, Skills, subagents) drive DeepSeek-V4 — banner shows (claude→deepseek). The deepseek-claude path is more featureful but skips MCP servers and image input (DeepSeek's compat layer ignores those fields).
lingcode --provider deepseek-claude # full Claude UX, deepseek-v4-pro[1m]
lingcode --provider deepseek-compat # OpenAI-format, deepseek-v4-flash by default
lingcode --provider deepseek-compat --model deepseek-v4-pro
Any OpenAI-compatible endpoint
lingcode --provider openai \
--base-url https://my-proxy.example.com/v1 \
--api-key-env MY_KEY_VAR \
--model gpt-4o
Tool use, MCP servers, hooks, Skills, subagents, custom slash commands, output styles, settings.json permission patterns, and the configurable status line all work on every provider. Session resumption and image attachments via --file are Claude-only (those depend on the Agent SDK); OpenAI-compatible providers get image input via --image in text-only mode.
Linux & Windows notes
The native CLI builds and runs identically on Linux x86_64 / ARM64 and on Windows x64 / ARM64. Two differences vs. macOS:
- App-IPC subcommands are absent.
lingcode ping / open / status / watch / installonly exist on macOS — they talk to LingCode.app's Unix socket. On Linux and Windows you run headless against your provider directly. - Secret store is a JSON file at
$XDG_CONFIG_HOME/lingcode/keys.jsonon Linux (defaulting to~/.config/lingcode/keys.json),%LOCALAPPDATA%\lingcode\config\keys.jsonon Windows, or~/.lingcode/credentials.jsonon the npm/Node fallback — all in place of the macOS Keychain.lingcode auth login / set / status / deletestill work the same way; environment variables are honored on every platform.
Files, sessions & output styles
The CLI is the part of LingCode you'll script against, point at log files, and leave running in a tab next to your editor. A handful of features make that less awkward than just typing prompts into a black rectangle — most of them are in the npm-distributed Node version starting at v0.12; the Swift CLI has subsets of the same surface.
Attach files inline with @
Type @ followed by a path and the file's contents are read off disk and prepended to your prompt as a code block before the model sees it. Same pattern as Cursor, Codex, and Claude Code.
> summarize @README.md and explain what the build pipeline does in @scripts/ship.sh
Repeated mentions of the same file get deduplicated. Files over 200 KB are skipped with a note suggesting the Read tool with offset/limit instead — the model still has a path to read them, just not all at once. Paths resolve against the current working directory; absolute paths also work.
Fetch URLs with WebFetch
A built-in tool the model can call to grab an HTTP/HTTPS URL, strip the HTML to readable text, and reason about it. No MCP setup required — it's listed in the tool schema alongside Read/Write/Bash. Like other side-effectful tools it always prompts for permission in the TTY (talking to arbitrary servers can leak referrer info or IPs, so we don't auto-approve it).
> what does Anthropic say about prompt caching pricing? Check their docs.
<assistant calls WebFetch on docs.anthropic.com/...>
Allow WebFetch? [WebFetch] [y/N]
Export a conversation as markdown
While you're in the REPL, /export <path> writes the current session to a markdown file — alternating ## You / ## Assistant sections with tool calls and results inlined as block quotes. Useful for handing off a working session to a teammate, pasting into a PR description, or just archiving an investigation.
> /export ~/Desktop/refactor-notes.md
(wrote 4823 bytes to ~/Desktop/refactor-notes.md)
Persistent sessions
Opt in once and every REPL run writes its transcript to ~/.lingcode/sessions/<timestamp>.json as you chat:
lingcode config set saveHistory true
Then:
lingcode history— list saved sessions, newest firstlingcode --resume <id>— pick up where you left off (the new REPL boots with the prior turns in context)lingcode history show <id>— print a saved session to stdout as markdownlingcode history export <id> <path>— write it to a file
Persistence is off by default because most uses of the CLI are one-shot or transient; flipping it on is one config line when you change your mind.
Output styles
Three knobs for response shape, set as a config value the CLI reads on every call:
lingcode config set output-style compact # 1–3 sentences unless thoroughness is needed
lingcode config set output-style verbose # show reasoning + intermediate work
lingcode config set output-style concise # no preamble, no pleasantries
lingcode config unset output-style # back to model default
It works by appending a system-prompt directive each turn, so the change takes effect immediately — no REPL restart needed. The model still chooses how to answer; this just nudges it toward your preferred shape.
One-shot ask
# Simple
lingcode ask "summarise this repo's architecture"
# Pipe content in
cat error.log | lingcode ask "explain this"
# Read the entire prompt from stdin
echo "what is 2+2?" | lingcode ask -
# Switch provider
lingcode ask --provider groq "quick: what does this regex do? /\d{3}-\d{4}/"
# Claude with full tool use, auto-approved
lingcode ask --provider claude --yolo "add a .gitignore entry for .DS_Store"
# Attach a file
lingcode ask --provider claude --file screenshot.png "what's wrong in this UI?"
# Structured output (good for scripts)
lingcode ask --output-format stream-json "fix the failing test in main.swift"
Useful flags
--continue | Resume the most recent Claude session in this directory |
--resume <id> | Resume a specific session by ID |
--file <path> | Attach a file (image, PDF, text). Repeatable. Claude only. |
--allowed-tools Read,Write | Allow only these tools (Claude only) |
--disallowed-tools Bash | Disallow these tools |
--add-dir ~/other | Extra directory the agent can touch. Repeatable. |
--thinking | Enable Claude's extended thinking |
--system-prompt "..." | Override the system prompt |
--append-system-prompt "..." | Append to the system prompt |
--output-format text|json|stream-json | Output shape |
--output path/out.md | Write the response to a file |
--verbose | Don't truncate tool input/output |
--yolo | Auto-allow every tool call. Dangerous. |
Slash commands
Type these at the REPL prompt.
Every provider
/help | List commands |
/model <name> | Switch model mid-session |
/mode <mode> | Change permission mode (default / acceptEdits / plan / dontAsk / bypassPermissions) |
/yolo | Bypass all permission prompts |
/cost | Cumulative token usage + USD estimate (priced per model) |
/tools | List available built-in tools |
/commands | List custom slash commands from .claude/commands/ |
/skills | List loaded Skills from .claude/skills/ |
/agents | List subagents from .claude/agents/ (OpenAI-compat; on Claude, subagents come from the Agent SDK's built-in Task) |
/output-styles | List loaded output styles |
/session | Show current session id (use with --resume) |
/reset | Clear conversation (Claude: also starts a fresh session) |
/export [path] | Save transcript as markdown |
/clear | Clear screen |
/quit | Exit |
Claude-only
/compact | Summarise and compress conversation history |
/doctor | Diagnose environment (node, API key, bridge, MCP, hooks) |
/init | Generate CLAUDE.md for the current project |
OpenAI-compatible only
/system <text> | Replace the system prompt for this session |
/image <path> | Attach a PNG/JPG/GIF/WEBP image to the next turn (OpenAI-compat mode) |
/mcp | Show connected MCP servers and their tool inventory |
Custom
Put a Markdown file at .claude/commands/<name>.md and invoke it as /project:<name>. Files at ~/.claude/commands/ are invoked as /user:<name>. Bare /<name> checks project first, then user. Any text after the command name is appended to the body.
$ echo "Explain the changes staged in git in plain English." > .claude/commands/explain-staged.md
$ lingcode
lingcode> /project:explain-staged
Auth & API keys
Three sources, checked in this order: environment variable, OS secret store (macOS Keychain on Mac, chmod-600 ~/.config/lingcode/keys.json on Linux), config file. Any one is enough.
# Browser-assisted: pick a provider with arrow keys (12 supported), opens its
# console, prompts for the key, stores in the Keychain. Offers to set the
# chosen provider as default.
lingcode auth login
# Skip the picker
lingcode auth login --provider deepseek
lingcode auth login --provider openai
# Direct
lingcode auth set anthropic sk-ant-...
lingcode auth set deepseek sk-...
# See what's configured (values masked)
lingcode auth status
# Remove a key
lingcode auth delete anthropic
About OAuth: Anthropic does not issue OAuth client IDs to third-party CLIs, so a true /login OAuth flow is not possible. lingcode auth login is the practical replacement — it opens the console in your browser, waits for you to paste the key, and stores it.
Other providers (openai, groq, together, openrouter, mistral, xai, fireworks, ollama) don't use the Keychain path — just set their environment variable in your shell:
export OPENAI_API_KEY=sk-...
export GROQ_API_KEY=gsk-...
Skills & subagents
Both load from the same paths Claude Code uses, so existing libraries work unchanged. Project files in .claude/, user-level files in ~/.claude/, project wins on name clash.
Skills
An expertise packet the model can pull in when it's relevant. Put one at .claude/skills/<name>/SKILL.md with YAML frontmatter:
---
name: pr-reviewer
description: Review a GitHub PR with focus on security, correctness, and style.
---
When asked to review a PR, fetch it via `gh pr view`, then check:
1. Security issues (injection, auth bypass)
2. Correctness (edge cases, error handling)
3. Style (matches repo conventions)
Loaded automatically into the system prompt on every provider. Disable with --no-skills; list with /skills.
Subagents
A focused agent the model can dispatch to via the Task tool — runs in a fresh context with its own system prompt and (optionally) its own model and tool subset. Put one at .claude/agents/<name>.md:
---
name: flake-hunter
description: Diagnose intermittently-failing tests by rerunning and correlating with recent commits.
model: deepseek-v4-pro
tools: Read, Grep, Bash
---
Check git log for recent changes near the failing test. Run the test N times
and look for non-determinism: time, network, randomness, parallel ordering.
The model invokes a subagent with Task(agent: "flake-hunter", prompt: "..."). Subagents run sequentially, can't recursively spawn more subagents (no Task-in-Task), and inherit the parent's permission decider. List with /agents.
On the Claude provider, subagents come from the Agent SDK's built-in Task tool — works the same way to the model.
MCP servers, hooks, custom commands
Compatible with Claude Code's project conventions, on every provider.
MCP servers
Put a .mcp.json at the project root (or ~/.claude.json globally):
{
"mcpServers": {
"filesystem": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."]
}
}
}
Override with --mcp-config <path>. Disable with --no-mcp. Both Claude and OpenAI-compat providers consume MCP stdio servers — connected tools show up alongside built-ins in the model's tool list.
Hooks
Put hooks in .claude/settings.json. They run as shell commands with CLAUDE_TOOL_NAME, CLAUDE_TOOL_INPUT, CLAUDE_TOOL_RESULT (for PostToolUse), and CLAUDE_USER_PROMPT (for UserPromptSubmit) in the environment. LINGCODE_* mirrors are also set if you'd rather not depend on Claude-branded names. Hooks fire on every provider.
{
"hooks": {
"PreToolUse": [
{ "matcher": "Write|Edit", "hooks": [{ "type": "command", "command": "echo about to edit: $CLAUDE_TOOL_INPUT" }] }
],
"UserPromptSubmit": [
{ "hooks": [{ "type": "command", "command": "logger -t lingcode \"$CLAUDE_USER_PROMPT\"" }] }
],
"Stop": [
{ "hooks": [{ "type": "command", "command": "say done" }] }
]
}
}
Custom slash commands
Markdown files under .claude/commands/ (project) or ~/.claude/commands/ (user). Same format as Claude Code — the file body is the prompt.
Permissions, output styles, status line
Three more .claude/settings.json blocks. All three apply on every provider.
Permission patterns
Fine-grained allow/deny/ask rules layered on top of the chosen permission mode. Glob syntax: * matches any run of non-slash characters, ** matches a path. Precedence: deny > ask > allow. Ask forces an interactive prompt even under --yolo.
{
"permissions": {
"allow": ["Bash(git *)", "Read(**/*.swift)"],
"deny": ["Bash(rm *)", "Bash(curl *)"],
"ask": ["Write(**)", "Edit(**)"]
}
}
Hardcoded security rules
A small set of destructive patterns are blocked unconditionally — your settings cannot override them. These compile once at startup and fire before any permission round-trip:
rm -rf /and recursive deletes of system rootmkfs(format a filesystem)ddwriting to raw disk devices- Writes to
/etc,/System - Tampering with
~/.ssh/authorized_keys - Fork bomb patterns
These rules apply to every provider and every session — REPL, ask, serve, and acp-serve. They wrap the permission decider chain so the veto fires even when --yolo or an external ACP client would otherwise auto-approve.
Output styles
Append a custom voice / format to the system prompt. Save styles under .claude/output-styles/<name>.md (or ~/.claude/output-styles/). Pick one with --output-style <name>; list with /output-styles. The built-in engineer style is the default.
Status line
Customize the prompt with a shell command. Runs once per turn (not per keystroke), 2-second timeout, falls back silently to the default prompt on failure.
{
"statusLine": {
"type": "command",
"command": "printf '%s · %st · $%s' \"$LINGCODE_MODEL\" \"$LINGCODE_TURN\" \"$LINGCODE_COST_USD\""
}
}
Env vars passed in: LINGCODE_SESSION, LINGCODE_MODEL, LINGCODE_TURN, LINGCODE_INPUT_TOKENS, LINGCODE_OUTPUT_TOKENS, LINGCODE_COST_USD, LINGCODE_CWD. Claude Code's CLAUDE_* mirrors are set too.
Background tasks
Long-running shell processes (dev servers, watchers) start with Bash(run_in_background: true) and return a task id immediately. Poll with the Monitor tool — it returns only the new bytes since the last poll, plus whether the process is still running. Monitor(action: "list") shows everything; Monitor(action: "kill", id: "bg_3") stops one. Cap of 8 concurrent background tasks per session.
Talking to the running app
When LingCode.app is open, these commands drive it over a Unix socket at ~/Library/Application Support/LingCode/ipc.sock:
| Command | What it does |
|---|---|
lingcode ping | Check whether the app is running and responsive. |
lingcode open path/to/file.swift | Open a file or folder in the app (launches it if needed). |
lingcode status | Focused project and any active agent runs. |
lingcode ask "..." | Route the prompt through the app; stream its answer to stdout. |
lingcode watch | Tail agent activity in real time. Ctrl-C to stop. |
Pass --headless to ask to force local execution even with the app open.
Expose as HTTP server
lingcode serve runs a long-lived HTTP server that exposes the agent over Server-Sent Events. Use it to drive LingCode from a VS Code extension, web UI, or scripts on another box — same agent core that powers the REPL and one-shot ask.
lingcode serve # bind 127.0.0.1:7878
lingcode serve --port 8080
lingcode serve --bind 0.0.0.0 --allow-remote # opt in to non-loopback
lingcode serve --new-token # rotate the bearer token
lingcode serve --bridge-daemon auto # reuse a running bridge daemon
Auth: Authorization: Bearer <token>. The token is generated on first start, written to ~/.lingcode/server.token (chmod 600), and printed to stderr. Bind defaults to loopback; non-loopback requires --allow-remote.
Endpoints (v1)
GET /v1/ping | Liveness + version |
POST /v1/agent/ask | SSE stream of agent events |
POST /v1/agent/permission/{requestId} | Allow/deny a Claude tool call |
POST /v1/agent/cancel/{queryId} | Cancel an in-flight query |
Streaming an agent query
TOKEN=$(cat ~/.lingcode/server.token)
# Liveness
curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:7878/v1/ping
# Streaming ask (-N disables curl buffering)
curl -N -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"provider":"claude","prompt":"list files","cwd":"'"$PWD"'"}' \
http://127.0.0.1:7878/v1/agent/ask
SSE frames carry one event per JSON object. Claude events: query_started, assistant_text, tool_use, tool_result, permission_request, permission_resolved, token_usage, query_finished (terminal), query_failed / query_cancelled / error. DeepSeek and OpenAI-compat providers emit a subset — they include tool_use but skip permission_request (tools execute without interactive approval).
Tool-permission round-trip
When Claude requests a tool that needs approval, you'll see a permission_request SSE event with a requestId. POST allow/deny back:
curl -s -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"behavior":"allow"}' \
http://127.0.0.1:7878/v1/agent/permission/<requestId>
Or {"behavior":"deny","message":"…"} to refuse with a hint shown back to the model. The SSE stream resumes when the decision arrives.
Multi-account & daemon reuse
Pass "account": "work" in the ask body to select a per-request keychain slot (matches lingcode auth login --account work). Pass --bridge-daemon auto at startup to reuse a running lingcode bridge daemon-start instead of cold-spawning Node per Claude query — saves ~200–500ms per request.
CORS is deny-by-default and TLS is not implemented — front with caddy / nginx / cloudflared if you expose the server beyond the host.
External agent clients (acp-serve)
lingcode acp-serve runs a stdio-based Agent Control Protocol (ACP) host. External editors and AI clients — such as Zed or gemini-cli — can drive the full LingCode agent loop without going through the HTTP server. Any provider works.
# Drive the Claude agent over stdio
lingcode acp-serve --agent claude
# Drive a DeepSeek agent
lingcode acp-serve --agent deepseek
# Drive any OpenAI-compatible provider
lingcode acp-serve --agent openai-compat:groq
lingcode acp-serve --agent openai-compat:openrouter
# Set the working directory (defaults to cwd)
lingcode acp-serve --agent claude --cwd ~/my-project
The ACP protocol is a JSON-lines message exchange over stdin/stdout. Each agent session is multi-turn and stateful — the external client issues prompts and receives a structured stream of events (assistant_text, tool_use, tool_result, permission_request, and terminal frames like session_finished).
Security rules fire before every ACP round-trip: HardcodedDenyDecider blocks destructive patterns regardless of client instructions; ACPClientPermissionDecider then forwards remaining requests to the external client for allow/deny.
Credential resolution uses the same chain as the REPL: macOS Keychain → environment variable → config file. No extra auth configuration needed if you already have keys stored via lingcode auth login.
Subcommand reference
| Subcommand | Purpose |
|---|---|
repl (default) | Interactive multi-turn session. lingcode with no args. |
ask | One-shot prompt; supports streaming, JSON output, attachments, resume. |
auth | login / set / get / delete / status against the OS secret store. |
config | Read or write ~/.lingcode/config.json — defaults, stored keys. |
init | Generate a CLAUDE.md for the current project by analysing the repo. |
history | List past sessions from ~/.lingcode/history.jsonl. |
completion zsh|bash|fish | Print a shell completion script. |
ping | IPC probe for the running app. |
open | Open file or folder in the running app. |
status | App focus / agent status. |
watch | Stream live agent activity. |
install | Symlink lingcode onto your PATH. |
serve | Run an HTTP server (/v1/agent/ask SSE) so external clients can drive the agent. Details. |
acp-serve | Run a stdio-based ACP host for external editors (Zed, gemini-cli). Details. |
Troubleshooting
lingcode: ANTHROPIC_API_KEY is not set
Fix with lingcode auth login, or export in your shell, or run lingcode config set anthropic-api-key sk-ant-....
lingcode: <PROVIDER_API_KEY> is not set
OpenAI-compatible providers use plain env vars. For custom names: lingcode --provider openai --api-key-env MY_KEY.
lingcode: couldn't find Claude agent bridge
The Claude provider needs bridge.mjs, which ships inside LingCode.app or the standalone CLI tarball. Either install LingCode.app at /Applications, or point at a dev copy with export LINGCODE_AGENT_BRIDGE_DIR=/path/to/agent-bridge.
lingcode: bundled Node.js runtime is missing
The macOS CLI tarball ships its own Node — you shouldn't need to install one. If this error appears, the bundled binary went missing (corrupted install, manual deletion, or a Linux build): reinstall lingcode (curl -fsSL https://lingcode.dev/install-cli.sh | sh). As a fallback, install Node.js (nodejs.org) or set NODE to an explicit path. Only the Claude provider uses Node; OpenAI-compatible providers are pure Swift.
Rate-limited / 429 / overloaded
Both ask and repl retry automatically with exponential backoff (up to 5 attempts, up to 60s apart). You'll see rate limited (attempt N/5) — retrying in Xs… on stderr.
The app responds, but I wanted headless
lingcode ask routes through the app by default when it's open. Pass --headless to force local execution.
I pasted an API key into my terminal
Rotate it at the provider's dashboard. Anything in your shell history or tmux scrollback should be treated as leaked. Prefer lingcode auth login (browser paste) or lingcode auth set <provider> <key> — neither writes the key to stdout.