[{"slug":"index","title":"Documentation","group":"概览","lede":"An AI coding agent that lives in your terminal. Hand it a natural-language task and it will autonomously read, edit, run, and self-verify. These docs walk you from a fresh install to every feature AtomCode offers.","sections":[{"id":"atomcode-documentation","heading":"AtomCode Documentation","body":"An AI coding agent that lives in your terminal. Hand it a natural-language task and it will autonomously read, edit, run, and self-verify. These docs walk you from a fresh install to every feature AtomCode offers. v4.24.2 许可证 MIT 语言 Rust 1.88+ 平台 macOS · Linux · HarmonyOS PC · Windows 100% AI 生成"},{"id":"three-steps-to-start","heading":"Three steps to start","body":"Install — one curl command or build from source. See Quickstart . Log in or configure a model — AtomGit OAuth is the easiest path; any OpenAI-compatible API key also works. See Login Methods and Configuration . Ask away — run atomcode inside any project directory and describe your task in natural language. Tip For a quick taste, run a single command: atomcode -p \"give me a brief overview of this repo\" — one-shot execution with the result piped to stdout."},{"id":"documentation-map","heading":"Documentation map","body":""},{"id":"quickstart","heading":"Quickstart","body":"Install paths, the 3-step first-run wizard, your first task, and the atomcode uninstall flow."},{"id":"configuration","heading":"Configuration","body":"Every ~/.atomcode/config.toml field, per-provider examples, plus the vision preprocessor (so non-vision models can still answer about images)."},{"id":"login-methods","heading":"Login Methods","body":"AtomGit OAuth one-click login (auto-persisted) versus API key setup, side by side."},{"id":"basic-usage","heading":"Basic Usage","body":"How to phrase tasks, common CLI flags, file references, multiline input, and image attachments / screenshots (Ctrl+V / drag-and-drop)."},{"id":"slash-commands","heading":"Slash Commands","body":"Reference table for the 30+ built-in slash commands: sessions, models, undo, issues, conversation modes, and the extension ecosystem."},{"id":"keybindings","heading":"Keybindings","body":"Every TUI keybinding: input, navigation, selection, copy, and more."},{"id":"built-in-tools","heading":"Built-in Tools","body":"All 21 built-in tools categorised: filesystem/shell, code graph, web, and automation."},{"id":"sessions-undo","heading":"Sessions & Undo","body":"Persistent session restore, /undo rollback, and clearing or compacting context."},{"id":"project-instructions","heading":"Project Instructions","body":"Use .atomcode.md to give AtomCode project-level conventions to follow."},{"id":"skills","heading":"Skills","body":"Write your own skills to extend the slash-command ecosystem."},{"id":"plugin-system","heading":"Plugin System","body":"One-click install other people's skill / command / hook packs from any git repo — Claude Code ecosystem compatible."},{"id":"mcp-integration","heading":"MCP Integration","body":"Plug external MCP servers in via .mcp.json — expose GitHub, databases, Playwright, and more to your model."},{"id":"faq","heading":"FAQ","body":"Install issues, model connectivity, permission prompts, context overflows, and other common questions."},{"id":"feedback-contributing","heading":"Feedback & contributing","body":"AtomCode is open source — issues and pull requests welcome: Repository: https://atomgit.com/atomgit_atomcode/atomcode Issues: run /issue from inside AtomCode to file one quickly License: MIT © 2026 AtomCode · MIT 报告问题"}]},{"slug":"getting-started","title":"Quickstart","group":"开始","lede":"Install AtomCode, run the first-time wizard, and complete your first task in a few minutes.","sections":[{"id":"quickstart","heading":"Quickstart","body":"Install AtomCode, run the first-time wizard, and complete your first task in a few minutes."},{"id":"requirements","heading":"Requirements","body":"OS : macOS (Apple Silicon or Intel), Linux, Windows, or HarmonyOS PC Rust toolchain : 1.75+ (only required when building from source) LLM : an API key for any supported provider, or an AtomGit account (for OAuth login)"},{"id":"install","heading":"Install","body":""},{"id":"option-1-one-click-install-recommended","heading":"Option 1: one-click install (recommended)","body":"On macOS, Linux, or HarmonyOS PC: curl -fsSL https://raw.atomgit.com/atomgit_atomcode/atomcode/raw/main/scripts/install.sh | sh The script downloads the prebuilt binary for your platform and places it at ~/.local/bin/atomcode . Make sure that directory is on your PATH . On Windows PowerShell: irm https://raw.atomgit.com/atomgit_atomcode/atomcode/raw/main/scripts/install.ps1 | iex It downloads the Windows x64 prebuilt binary and updates PATH ; open a fresh terminal to use the atomcode command."},{"id":"option-2-install-using-npm","heading":"Option 2: install using npm","body":"If you already have Node.js 18+ installed, install globally with npm: npm install -g @atomgit.com/atomcode The package uses optionalDependencies to pull the prebuilt binary for your platform (macOS x64 / arm64, Linux x64 / arm64, Windows x64, HarmonyOS arm64) — one command, cross-platform."},{"id":"option-3-install-using-homebrew","heading":"Option 3: install using Homebrew","body":"If you have Homebrew installed, install the cask (macOS x64 / arm64, Linux x64 / arm64): brew install --cask atomcode The cask downloads the prebuilt binary for your platform and links it to your PATH automatically."},{"id":"option-4-build-from-source","heading":"Option 4: build from source","body":"git clone https://atomgit.com/atomgit_atomcode/atomcode.git cd atomcode cargo build --release cp target/release/atomcode ~/.local/bin/ Release builds take longer to compile but produce a small, fast binary. For day-to-day development a plain cargo build is fine."},{"id":"verify-the-install","heading":"Verify the install","body":"atomcode --version You should see something like atomcode 4.20.x (build-id) ."},{"id":"first-run","heading":"First run","body":"Just run: atomcode The first launch shows a 3-step onboarding wizard (you can re-open it any time with /welcome ):"},{"id":"step-13-welcome","heading":"Step 1/3 · Welcome","body":"███ █████ ███ █ █ ████ ███ ████ █████ █ █ █ █ █ ██ ██ █ █ █ █ █ █ █████ █ █ █ █ █ █ █ █ █ █ █ █ ████ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ███ █ █ ████ ███ ████ █████ AtomCode Version 4.23.3 · AI coding agent in your terminal • Multi-step agent loop · built-in code-graph tools • Compatible with any OpenAI-style API • Free tokens via CodingPlan Press Enter to continue. Ctrl+C exits at any point."},{"id":"step-23-language-choose-your-language-选择语言","heading":"Step 2/3 · Language (Choose your language / 选择语言)","body":"1. Auto-detect (LC_ALL / LANG) 2. English 3. 简体中文 (Simplified Chinese) 1-3 select · Enter confirm · ← back · Esc skip Your choice takes effect immediately and is written to the locale field of ~/.atomcode/config.toml . Run /language later to change it."},{"id":"step-33-setup-how-would-you-like-to-start","heading":"Step 3/3 · Setup (how would you like to start?)","body":"1. One-click with AtomGit CodingPlan (recommended · free tokens + auto-configured provider) 2. Configure a provider manually (you have an API key) 3. Skip and explore the TUI first (run /login or /provider later) 1-3 select · Enter confirm · ← back · Esc skip CodingPlan — the recommended path; equivalent to running /login inside the TUI. The browser opens AtomGit OAuth; after you log in, free tokens are claimed automatically and the granted model list is written as a provider config. Configure manually — equivalent to /provider : open the provider manager to fill in key / base URL / model. Skip — jump straight into the TUI and run /login or /provider later. For a deeper breakdown see Login Methods . You can re-open the wizard any time with /welcome ."},{"id":"your-first-task","heading":"Your first task","body":"cd into a project you know, launch atomcode, and just describe what you want: cd ~/projects/my-web-app atomcode > give me a brief overview of this project's directory layout and tech stack AtomCode autonomously: Runs list_directory , read_file , and similar tools to explore the code; Identifies key descriptor files ( package.json / Cargo.toml / …); Returns a structured summary. Tip Not sure what to ask? Try: \" fix every typo in the README \", \" add TypeScript types to the functions in src/utils.ts \", \" run the tests and fix any failures \"."},{"id":"uninstall","heading":"Uninstall","body":"When you're done with AtomCode, the built-in uninstall subcommand cleans up in one shot. It asks group-by-group whether to delete: the binary plus the PATH edits the installer made, credentials such as ~/.atomcode/auth.toml , and runtime state such as ~/.atomcode/sessions/ ."},{"id":"interactive-recommended","heading":"Interactive (recommended)","body":"atomcode uninstall Each group prompts y/N with a sensible default (binary = yes, credentials = no, state = yes) — pressing Enter is a reasonable choice."},{"id":"non-interactive","heading":"Non-interactive","body":"# Fully automatic: take the default decisions, no prompts atomcode uninstall --yes # Wipe everything (including the entire ~/.atomcode/ directory) atomcode uninstall --purge # Only remove the binary and PATH edits; keep ~/.atomcode/ intact atomcode uninstall --keep-data # Just print the plan; do nothing atomcode uninstall --dry-run Heads up --purge also deletes all session history, memories, custom provider configs, and OAuth tokens . It is irreversible. If you might use AtomCode again, prefer the interactive default or --keep-data ."},{"id":"next-steps","heading":"Next steps","body":"Configuration — manage multiple providers and models. Basic Usage — CLI flags and best practices for phrasing tasks. Slash Commands — get fluent with /resume , /undo , /diff , and friends. © 2026 AtomCode · MIT 报告问题"}]},{"slug":"login","title":"Login Methods","group":"开始","lede":"AtomCode supports two ways to connect to an LLM: AtomGit CodingPlan (with free tokens) and traditional API keys. This page helps you pick the right path and walks through the binding.","sections":[{"id":"login-methods","heading":"Login Methods","body":"AtomCode supports two ways to connect to an LLM: AtomGit CodingPlan (with free tokens) and traditional API keys. This page helps you pick the right path and walks through the binding."},{"id":"two-methods-at-a-glance","heading":"Two methods at a glance","body":"Method Command Who it's for AtomGit CodingPlan /login Recommended — one command runs OAuth, claims free tokens, and auto-configures provider and model API key /provider or hand-edit config Users with their own OpenAI / Claude / DeepSeek key As of v4.24.2 /codingplan has been folded into /login ; the previous \"OAuth-only without claiming tokens\" entry has been removed."},{"id":"atomgit-codingplan-recommended","heading":"AtomGit CodingPlan (recommended)","body":"AtomGit is the open-source code-hosting platform run by CSDN / OpenAtom Open Source Foundation, and AtomCode natively integrates its OAuth and CodingPlan. /login is the lowest-friction entry point for new users: a single action logs you in → claims free token quota → auto-generates a provider config from the granted model list. After that one command you can start chatting immediately. Re-running it after you're already signed in idempotently re-syncs the model list — no double-claim."},{"id":"from-the-first-run-wizard","heading":"From the first-run wizard","body":"The first time you run atomcode , the 3-step wizard pops up automatically. Step 1 (welcome): press Enter. Step 2 (language): press 1 / 2 / 3 to pick. Step 3 (setup): pick One-click with AtomGit CodingPlan (option 1). The browser opens the AtomGit authorization page — click Allow. After authorization, the TUI claims CodingPlan and writes the provider config. No need to touch config.toml — start sending messages. If you skipped earlier and want to redo the wizard, run /welcome any time."},{"id":"from-an-existing-session","heading":"From an existing session","body":"Once inside the TUI, run: /login The browser opens to complete authorization, claim CodingPlan, and refresh the provider list. Running it again re-syncs the model list — the local AtomGit* providers are updated to the latest entitled models."},{"id":"from-the-command-line","heading":"From the command line","body":"atomcode login Useful in scripts, remote servers, or container images for a one-shot setup. The CLI subcommand and the TUI /login share the same flow and emit the same report. Note: atomcode codingplan is kept as a hidden alias so existing scripts and muscle memory don't break after the fold."},{"id":"check-status-log-out","heading":"Check status / log out","body":"atomcode status # or /status in the TUI — includes CodingPlan usage and expiry atomcode logout # or /logout in the TUI — clears the OAuth token"},{"id":"api-key-method","heading":"API key method","body":"To use your own OpenAI / Claude / DeepSeek / GLM key, there are three ways:"},{"id":"option-a-provider-in-the-tui","heading":"Option A: /provider in the TUI","body":"Type /provider in the TUI. Pick \"Add a new provider\" and follow the prompts to enter type, base URL, API key, model, etc. The configuration is written back to ~/.atomcode/config.toml ."},{"id":"option-b-hand-edit-the-config-file","heading":"Option B: hand-edit the config file","body":"Edit ~/.atomcode/config.toml directly and add a [providers.*] entry; see ProviderConfig fields ."},{"id":"option-c-one-shot-cli-override","heading":"Option C: one-shot CLI override","body":"Don't want to touch the config file and only need a different provider for one run? Add flags at launch: atomcode --provider deepseek --model deepseek-reasoner"},{"id":"which-one-should-i-pick","heading":"Which one should I pick?","body":"First-time user → CodingPlan ( /login ) — free tokens, just use it. Already have your own API key → skip /login and use the API key path ( /provider or hand-edit config). If you also need AtomGit integrations ( /issue , etc.), running /login later will claim CodingPlan and register AtomGit-* providers as a side effect. Running in CI / scripts → API key via config file or env vars. Fully offline → configure an Ollama provider — no login required."},{"id":"next-steps","heading":"Next steps","body":"Basic Usage — first thing after logging in: learn how to phrase tasks. Slash Commands — /provider , /model , /status in detail. © 2026 AtomCode · MIT 报告问题"}]},{"slug":"configuration","title":"Configuration","group":"开始","lede":"AtomCode's config is TOML, supports any number of providers side by side, and lets you switch on the fly. This page explains every field and shows examples for common providers.","sections":[{"id":"configuration","heading":"Configuration","body":"AtomCode's config is TOML, supports any number of providers side by side, and lets you switch on the fly. This page explains every field and shows examples for common providers."},{"id":"config-file-location","heading":"Config file location","body":"Default path: macOS / Linux / HarmonyOS PC: ~/.atomcode/config.toml Windows: %USERPROFILE%\\.atomcode\\config.toml You can also use --config /path/to/config.toml to point at any file. On the first run, if the file is missing, the 3-step wizard walks you through initial setup."},{"id":"minimal-example","heading":"Minimal example","body":"default_provider = \"deepseek\" [providers.deepseek] type = \"openai\" api_key = \"sk-xxxxxxxxxxxxxxxx\" model = \"deepseek-chat\" base_url = \"https://api.deepseek.com/v1\" context_window = 64000 This config is enough to launch atomcode and start chatting with DeepSeek."},{"id":"top-level-fields","heading":"Top-level fields","body":"Field Type Description default_provider string Provider used at launch (must match a key under [providers.*] ) default_workdir string? Default working directory. /cd writes back here; restored next launch providers table Map of provider name to ProviderConfig vision_preprocessor_provider string? When the main provider can't see images but the user attaches one, forward it to this provider for OCR / description; the result is spliced back into the prompt as text. See Vision preprocessor"},{"id":"provider-config","heading":"ProviderConfig fields","body":"Fields available under each [providers.xxx] table: Field Type Required Description type string yes Provider protocol — currently openai , claude , or ollama api_key string? conditional API key. Optional for ollama . OAuth providers omit this — the token is read from ~/.atomcode/auth.toml automatically model string yes Model name, e.g. deepseek-chat , gpt-4o , claude-sonnet-4-6 base_url string yes API base URL, pointing at the actual endpoint. e.g. https://api.deepseek.com/v1 , http://localhost:11434 context_window integer no Model context window (tokens), default 64000. Default 8000 for ollama max_tokens integer? no Max output tokens per response. Defaults to context_window / 4 when unset system_prompt string? no Override the default system prompt. Rarely needed user_agent string? no Override the HTTP User-Agent — useful when the upstream blocks the default UA Why default to 64K instead of 128K? Even when a model advertises 128K+, its effective attention window is usually much smaller. An oversized context triggers \"lost in the middle\" failures and disables AtomCode's compaction strategy. 64K is empirically the most robust default; bump it yourself if your model is solid at higher values."},{"id":"common-provider-examples","heading":"Common provider examples","body":""},{"id":"claude-anthropic","heading":"Claude (Anthropic)","body":"[providers.claude] type = \"claude\" api_key = \"sk-ant-...\" model = \"claude-sonnet-4-6\" context_window = 128000"},{"id":"openai","heading":"OpenAI","body":"[providers.openai] type = \"openai\" api_key = \"sk-...\" model = \"gpt-4o\" context_window = 128000"},{"id":"deepseek","heading":"DeepSeek","body":"[providers.deepseek] type = \"openai\" api_key = \"sk-...\" model = \"deepseek-chat\" base_url = \"https://api.deepseek.com/v1\" context_window = 64000"},{"id":"zhipu-glm","heading":"Zhipu GLM","body":"[providers.glm] type = \"openai\" api_key = \"...\" model = \"glm-4-plus\" base_url = \"https://open.bigmodel.cn/api/paas/v4\" context_window = 128000"},{"id":"tongyi-qianwen-qwen","heading":"Tongyi Qianwen (Qwen)","body":"[providers.qwen] type = \"openai\" api_key = \"sk-...\" model = \"qwen-plus\" base_url = \"https://dashscope.aliyuncs.com/compatible-mode/v1\" context_window = 128000"},{"id":"siliconflow","heading":"SiliconFlow","body":"[providers.siliconflow] type = \"openai\" api_key = \"sk-...\" model = \"Qwen/Qwen2.5-72B-Instruct\" base_url = \"https://api.siliconflow.cn/v1\""},{"id":"ollama-local","heading":"Ollama (local)","body":"[providers.ollama] type = \"ollama\" model = \"llama3.2\" base_url = \"http://localhost:11434\" context_window = 8000 Heads up Function-calling support varies a lot across Ollama models; weaker local models may not invoke tools reliably. Prefer the Instruct variants of Qwen2.5 / Llama3.2."},{"id":"multiple-providers-and-quick-switching","heading":"Multiple providers and quick switching","body":"Config files can host any number of providers in parallel: default_provider = \"claude\" [providers.claude] type = \"claude\" api_key = \"sk-ant-...\" model = \"claude-sonnet-4-6\" [providers.deepseek] type = \"openai\" api_key = \"sk-...\" model = \"deepseek-chat\" base_url = \"https://api.deepseek.com/v1\" [providers.local] type = \"ollama\" model = \"qwen2.5:14b\" base_url = \"http://localhost:11434\" In the TUI, switch between entries with /provider , or switch only the model under the current provider with /model . The CLI also accepts one-shot overrides: atomcode --provider deepseek --model deepseek-reasoner"},{"id":"vision-preprocessor","heading":"Vision preprocessor","body":"When the active provider's model can't read images (text-only models like DeepSeek-V3 / Kimi) and the user attaches an image , AtomCode doesn't refuse — it forwards the image to a separate \"vision preprocessor\" provider for OCR + description, then splices the resulting text into the user message before sending to the main model. To enable: name an image-capable provider key as vision_preprocessor_provider in the config: default_provider = \"deepseek\" vision_preprocessor_provider = \"qwen-vl\" [providers.deepseek] type = \"openai\" api_key = \"sk-...\" model = \"deepseek-chat\" base_url = \"https://api.deepseek.com/v1\" [providers.qwen-vl] type = \"openai\" api_key = \"sk-...\" model = \"Qwen/Qwen3-VL-32B-Instruct\" base_url = \"https://api.siliconflow.cn/v1\" qwen-vl must be an existing key under [providers.*] , and its model must support vision input (common ones: Qwen3-VL-* / GLM-4V-* / claude-3+ / gpt-4o / gemini-* ). When the active provider can already see images, the preprocessor is skipped — the raw image bytes are sent directly. The /login flow auto-picks a VL/OCR model from the granted model list and writes this field for you (you can override afterwards). VL calls use an idle timeout : no total cap as long as the stream keeps producing chunks; the request times out after 30 seconds with no activity. On failure the main model still receives a \"vision recognition failed\" notice rather than a silent drop. For usage-level details see Basic Usage · Image attachments / screenshots ."},{"id":"three-ways-to-edit-the-config","heading":"Three ways to edit the config","body":"Hand-edit — open ~/.atomcode/config.toml in your favourite editor. /config in the TUI — atomcode opens the config in your default editor. /provider in the TUI — interactively add / edit / remove providers; changes are written back to disk."},{"id":"next-steps","heading":"Next steps","body":"Login Methods — skip manual key management with AtomGit OAuth. Basic Usage — see how CLI flags can override config for one run. © 2026 AtomCode · MIT 报告问题"}]},{"slug":"basic-usage","title":"Basic Usage","group":"使用","lede":"Get fluent with CLI flags, how to phrase tasks, how to give the model context, and how to move between several tasks.","sections":[{"id":"basic-usage","heading":"Basic Usage","body":"Get fluent with CLI flags, how to phrase tasks, how to give the model context, and how to move between several tasks."},{"id":"launching","heading":"Launching","body":"# Launch the TUI in the current directory atomcode # Specify a working directory atomcode -C /path/to/project # Override provider / model for this run only atomcode --provider claude --model claude-sonnet-4-6 # Continue the previous session atomcode -c atomcode --continue # Use a specific config file atomcode --config ./custom.toml # Skip all permission prompts, auto-approve every tool call atomcode -y atomcode --dangerously-skip-permissions"},{"id":"cli-flag-reference","heading":"CLI flag reference","body":"Flag Short Purpose --dir PATH -C Working directory; defaults to the current directory --continue -c Continue the previous session instead of starting a new one --provider NAME — Override the default provider --model NAME — Override the current provider's model --config PATH — Use the given config file --prompt TEXT -p Non-interactive mode: one-shot execution, reply to stdout --prompt-file PATH — Read prompt from file (useful for long input; mutually exclusive with -p ) --verbose -v In non-interactive mode, print tool calls and token usage to stderr --max-turns N — Cap the number of agent loop iterations; prevents runaway loops --disable-tools LIST — Comma-separated tools to disable, e.g. --disable-tools bash,web_fetch --dangerously-skip-permissions -y Skip all permission prompts — auto-approve every tool call (bash, file edits, MCP, etc.). A ⚠ BYPASS badge is shown in the TUI status bar while active Tip --disable-tools makes disabled tools completely invisible to the model (they don't appear in the schemas), so the model won't keep trying to call them. Useful for sandbox evals, offline environments, and CI without network. Warning -y / --dangerously-skip-permissions bypasses all permission prompts, including bash execution, file writes, and MCP tool calls. The agent can execute arbitrary actions without confirmation. Only use this flag when: Running in CI/CD pipelines or other automated environments Executing benchmarks inside a sandbox or container Working on non-critical projects where you trust the agent's built-in safety constraints"},{"id":"how-to-phrase-tasks","heading":"How to phrase tasks","body":"AtomCode's agent loop is only as good as the task description you provide. A few rules of thumb: State goals, not steps — \"Fix the 404 after login\", not \"Open src/auth/callback.ts, delete line 27, then…\". The model has plenty of exploration ability. Name your constraints — say them out loud: \"preserve API compatibility\", \"don't touch test files\", \"use TypeScript not JS\". Provide a verification method — \"after the fix, run npm test to confirm\" lets the model close the self-verification loop. Discuss before editing — when direction is unclear, first ask it to \"analyse this module and propose a refactor plan\"; once aligned, let it implement."},{"id":"example-tasks","heading":"Example tasks","body":"# Bug fix > Fix the bug where users are redirected to 404 after OAuth callback; restore the original path after callback. # New feature > Add a dark mode toggle to the settings page using Tailwind's dark: prefix, persisted in localStorage. # Refactor > Refactor src/db/*.ts to use a connection pool while keeping the public API unchanged; run npm test after. # Tests > Write unit tests for src/payment/processor.ts, covering all exception branches. # Code understanding > Briefly explain this repo's directory layout, build entry point, and the responsibilities of the core modules."},{"id":"multiline-input","heading":"Multiline input","body":"In the TUI: Enter sends the message. Shift+Enter / Ctrl+Enter / Ctrl+J insert a newline (requires Kitty keyboard protocol: kitty / WezTerm / Alacritty / iTerm2 ≥3.5 / Windows Terminal ≥1.21). Alt+Enter inserts a newline (works in most terminals, but Windows Terminal binds it to \"toggle fullscreen\" by default — unbind in settings). The input area grows with content."},{"id":"at-mention","heading":"@ file references","body":"Type @ in the input (preceded by whitespace or line start) to pop up a menu of files and directories in the project. This is the fastest way to point the model at a specific path — you handle locating, the model decides via read_file what to expand and how much to read."},{"id":"interaction","heading":"Interaction","body":"Trigger — @ only triggers when preceded by whitespace or line start. A mid-string @ like email@host.com won't pop the menu — avoiding accidental triggers. Filtering — type to substring-match (case-insensitive). @cra hits crates/ ; @toml hits every *.toml . Drill in — type / to enter a directory; the menu scopes to that directory. @crates/ → @crates/atomcode-cli/ → … Navigation — ↑ / ↓ move; Enter or Tab select; Esc closes without inserting. Insertion form — on select, the @xxx in the input is replaced with the @full/relative/path (directories get a trailing / ) plus a trailing space; the cursor sits after the space, ready for more typing. Backspace to keep picking — delete the trailing space and the menu re-opens in place, handy for drilling further from the current directory."},{"id":"where-candidates-come-from","heading":"Where candidates come from","body":"All files and directories under the project root — both files and dirs can be selected; dirs are marked with a trailing / . Honours .gitignore (and global ignore, .git/info/exclude ); ignored paths never appear. .git/ internals are excluded — almost nobody wants to @ -reference git metadata. Dotfiles stay — .env , .atomcode.md , and other dot-prefixed files are matchable (provided gitignore doesn't suppress them). Cross-level fuzzy matching — once you start typing a filter, matches reach across directory levels (not just the current scope's direct children). With an empty filter only the current scope's direct children are shown. Ordering : direct children of the current scope first → directories before files → alphabetical."},{"id":"what-it-means-for-the-model","heading":"What it means for the model","body":"On submit, @crates/atomcode-cli/src/main.rs is sent to the model as literal text — AtomCode does not read and inline the file content in the frontend. The model sees the path and decides to call the built-in read_file tool as needed. Benefits: Large files don't get blindly stuffed into context — the token budget stays predictable. When you reference a directory, the model can list first and then read selectively. Re-referencing the same path doesn't inline the content twice. Tip If you want to force a file's contents into the conversation directly (e.g. a tight code review where you don't want another read_file round trip), use paste — drop the content into the input. Bracketed paste collapses it to an [paste #N] placeholder and ships the full payload on submit."},{"id":"limits","heading":"Limits","body":"The candidate menu shows at most 30 entries ; typing more filter characters narrows the results. Paths with spaces don't appear in candidates — the @ reference uses whitespace as a terminator. The file index is built once per session ; files created during the session don't appear until you switch sessions or restart. Symlinks are not followed. No size or type filtering — every non-ignored file shows up."},{"id":"pasting-long-text","heading":"Pasting long text","body":"AtomCode supports bracketed paste. When you paste a chunky block (e.g. a wall of logs), the TUI collapses it to a compact [paste #N · 132 lines] indicator so the input doesn't blow up. The full payload is sent on submit."},{"id":"image-attach","heading":"Image attachments / screenshots","body":"Beyond text, you can also drop images into the conversation — error screenshots, UI mocks, whiteboard photos. AtomCode offers three entry points: Ctrl+V — when the system clipboard holds an image (you just Cmd+Shift+4 -captured something, copied an image from a browser, etc.), Ctrl+V attaches it directly. This is the fallback for macOS + iTerm2 where Cmd+V doesn't forward the image to the PTY, and works in any terminal. Cmd+V (macOS / iTerm2, with one-time setup) — iTerm2 → Settings → Profiles → Keys → Key Mappings, map ⌘V to Send Hex Codes: 0x16 ; from then on Cmd+V == Ctrl+V. Finder drag / iTerm2 path drop — drag an image onto the terminal window; iTerm2 / WezTerm and friends paste the file path as plaintext. AtomCode recognises an absolute path + .png / .jpg / .jpeg / .gif / .webp extension + existing file + size ≤ 20MB, and attaches it automatically. The raw path string is removed from the input. On a successful attach, an [Image #N] marker is inserted in the input; the bytes ride along with the message on submit. The status bar also shows Image in clipboard · ctrl+v to paste when an unpasted image is sitting in the clipboard."},{"id":"how-non-vision-models-handle-images","heading":"How non-vision models handle images","body":"When the active provider can't take image input (text-only models like DeepSeek-V3 / Kimi), AtomCode doesn't refuse — it routes the image to a separate VL preprocessor (a vision model like Qwen3-VL / GLM-4V) for OCR + description, then splices the result into the user message as text before sending to the main model. So you can \"drop a screenshot and ask\" regardless of the main model. Which model does the preprocessor use? Controlled by vision_preprocessor_provider in the config — see Configuration · Vision preprocessor . The /login flow auto-picks a VL/OCR model from the granted list and sets the field for you. VL calls use an idle timeout : as long as the stream keeps producing chunks there's no total cap; it only times out after 30 seconds of silence. On failure you get a VL preprocess failed warning — image recognition fails but the message still goes through. Tip If the current model supports vision (Claude 3+ / GPT-4o / Gemini / Qwen-VL, etc.), the raw image bytes are sent directly — the preprocessor is skipped."},{"id":"switching-sessions-and-directories","heading":"Switching sessions and directories","body":"/resume — switch between or restore previous sessions /session — start a clean session /cd or just type cd /path — switch working directory (status bar updates live) /clear — clear messages in the current session /compact — compact history to free up context budget Full behaviour at Sessions & Undo ."},{"id":"inspecting-cost-and-diff","heading":"Inspecting cost and diff","body":"/cost — token output for this session plus context usage (estimated when the API doesn't report usage) /diff — git diff of uncommitted changes in the working directory /undo — roll back every file edit from the last turn"},{"id":"next-steps","heading":"Next steps","body":"Slash Commands — full reference for the 30+ commands Keybindings — fluency at the keyboard pays off quickly © 2026 AtomCode · MIT 报告问题"}]},{"slug":"slash-commands","title":"Slash Commands","group":"使用","lede":"Start an input with / in the TUI to trigger a command and get an autocomplete menu. The 30+ built-in commands are organised below; commands loaded from Skills and Plugins also appear in the menu automatically.","sections":[{"id":"slash-commands","heading":"Slash Commands","body":"Start an input with / in the TUI to trigger a command and get an autocomplete menu. The 30+ built-in commands are organised below; commands loaded from Skills and Plugins also appear in the menu automatically."},{"id":"core","heading":"Core","body":"Command Purpose /login Recommended — one command runs AtomGit OAuth + claims CodingPlan free tokens + auto-configures a provider from the granted model list. The lowest-friction entry point for first-time users; re-running after you're already signed in idempotently re-syncs the model list. As of v4.24.2 /codingplan has been folded into /login ; the standalone entry has been removed /resume Open the session picker to restore any previously persisted session (messages, directory, and model state) /session Start a fresh, clean session /bg Send the current session to the background and open a new foreground; subcommands: /bg list , /bg <N> , /bg drop <N> , /bg help . See Background sessions /background <task> Compatibility entry: start a one-shot task in a /bg slot ( details ) /rename <new-name> Rename the current session (changes the display name in the /resume picker) /provider Open the provider manager: add / edit / remove / switch /model Switch models within the current provider, or jump across providers /cd Change working directory and write it back as default_workdir . You can also just type cd /path (no slash prefix)"},{"id":"tools-utilities","heading":"Tools & utilities","body":"Command Purpose /undo · /undo N Roll conversation memory back to before the last turn (or turn N) and restore that prompt into the input box; rewinds memory only — does not revert files on disk /diff Show the git diff of uncommitted changes in the working directory /cost Show output tokens for the current session. APIs without usage reporting are estimated automatically /context Show this turn's context budget breakdown: system prompt, tool defs, cold-zone compaction, total messages, and context-window usage /compact Compact history: summarise earlier messages to free up context budget /clear Clear the current session's messages (working directory and model are kept) /init Scan the working directory and generate / refresh the .atomcode.md project instructions file — covering build / test commands, tech-stack summary, layout, etc.; injected as system prompt on subsequent launches /background <task> Dispatch a task to an isolated background agent (read-only-leaning tool subset) without polluting the main conversation. Useful for \"go check X on the side\" sort of light exploration. See Background sessions /worktree <subcommand> Git worktree isolation: create a new branch with its own worktree, list existing worktrees, done squash worktree changes back to the main branch, cleanup remove finished worktrees /issue Interactive wizard: file a new issue against the AtomGit repository for the current git repo (requires OAuth login; cwd must be a clone of an atomgit.com repository)"},{"id":"conversation-modes-thinking","heading":"Conversation modes & thinking","body":"Command Purpose /plan Switch to Plan mode : read-only exploration. The model can call read_file / grep / list_directory and other non-writing tools, but edit_file / bash are blocked. Useful for getting alignment before action /build Switch back to Build mode (the default): all tools available — read, write, execute. /plan and /build are freely interchangeable /think on / off Toggle extended thinking (for supported models — Claude / DeepSeek-R1 / GLM-4.5 / …). When on, the model surfaces its reasoning at the cost of latency and tokens /think budget <N> Cap the thinking token budget (Claude family); controls reasoning length"},{"id":"persistent-memory","heading":"Persistent memory","body":"Command Purpose /remember <content> Write to project-scoped memory (default scope, bound to the current working directory) /remember --global <content> Write to global memory (shared across all projects) /forget <keyword> Delete every entry in global + project memory matching the keyword (case-insensitive) /memory Show all active memories, grouped by [Global] / [Project] Full usage and best practices at Persistent Memory ."},{"id":"extension-ecosystem","heading":"Extension ecosystem","body":"Command Purpose /setup On first run, install the bundled atomcode-automation-recommender skill into ~/.atomcode/skills/ , append .atomcode/local/ to project .gitignore , and write .atomcode/setup-state.json (signals hash + atomcode version + installed list) under a project-level lock. Then invoke the recommender skill — it scans the project (languages, frameworks, hooks already in use), searches the web, and proposes additional atomcode skills to install for this codebase. Subsequent runs skip the seed install and re-invoke the skill directly. Extra text after the command is forwarded to the skill as a steering hint, e.g. /setup focus on testing . The CLI form atomcode setup --force forces a clean reinstall of seed files even when their content hash matches /skills Browse loaded skills (project- and user-level). Each skill also appears as a standalone slash command in the menu — trigger with /<skill-name> /plugin Open the interactive plugin manager — browse marketplaces, install/uninstall plugins, add/remove marketplaces from one screen /plugin marketplace add|remove|update|list Manage marketplace registrations (add clones a git repo, remove deletes, update pulls latest, list shows all) /plugin install <plugin>@<marketplace> Install a plugin from the named marketplace /plugin uninstall <plugin>@<marketplace> Uninstall an installed plugin (the marketplace registration is kept) /plugin list List locally installed plugins /plugin reload Reload all plugins (re-scan disk, refresh skill/hook registration) See Skills and Plugin System for details."},{"id":"mcp-integration","heading":"MCP integration","body":"Command Purpose /mcp List successfully connected MCP servers and their status (failed servers don't show here — only as red error lines in the session area) /mcp tools <server> Async-list the remote tools actually exposed by a specific MCP server (you'll be told if it times out or fails) /mcp reload Re-read .mcp.json / ~/.atomcode/mcp.json and reconnect every server in the background Full configuration and usage at MCP Integration ."},{"id":"web-ui-sync","heading":"Web UI & sync","body":"Command What it does /webui Launch the browser interface and open it (binds 127.0.0.1:13457 by default — local only). The current TUI session is attached to live sync automatically /webui --host <addr> Bind the server to a given address; /webui lan equals --host 0.0.0.0 (exposes it to the LAN). Pair with a 蒲公英 virtual IP for remote access — see Remote Access /webui stop Stop the webui server /sync Attach the current TUI to a running webui session (run /webui first). Both ends sync live in both directions; multiple browsers / terminals can watch the same session /sync off Leave sync and return to a standalone session More in Web UI ."},{"id":"config-help","heading":"Config & help","body":"Command Purpose /status Show login status, current provider, model, context budget, CodingPlan usage and reset time /whoami Show the username / email of the current AtomGit-logged-in user /config Show the path of ~/.atomcode/config.toml /reload Hot-reload ~/.atomcode/config.toml from disk — external edits (or changes from another terminal's /login ) take effect without restarting atomcode /language Switch UI language: auto-detect ( LC_ALL / LANG ), English, or Simplified Chinese. Takes effect immediately and is written back to ~/.atomcode/config.toml /welcome Re-open the 3-step first-run wizard (welcome → language → setup). Non-empty sessions are confirmed with a y/N before clearing the screen. Both language and default onboarding path can be revisited here /logout Clear the AtomGit OAuth token /upgrade Auto-upgrade to the latest version; /upgrade rollback reverts to the previous version /guide Built-in onboarding guide: /guide lists topics you can ask about (quickstart, switch model, MCP, Skills, memory, background tasks, context, keybindings, config); /guide <topic> explains it right in the chat (first run auto-installs the atomcode-skills plugin) /help List every available slash command /keys Show the keyboard-shortcut reference (grouped by input / history / session / modal navigation, with per-terminal compatibility notes for Shift+Enter and Alt+Enter ). See Keybindings /quit Exit atomcode (or hit Ctrl+C twice)"},{"id":"tips","heading":"Tips","body":"Autocomplete — typing / pops up the menu immediately; use ↑↓ to navigate, Tab / Enter to confirm. Fuzzy match — completion supports substring matching, e.g. /prov hits /provider . Interrupt the model — while the model is streaming, press Esc to interrupt; you can then enter a new command or prompt. Skills appear in the menu — once you add your own commands under Skills , they show up in the menu in the same format."},{"id":"typical-workflows","heading":"Typical workflows","body":""},{"id":"first-launch-one-click-onboarding","heading":"First launch — one-click onboarding","body":"> /login ✔ Logged in as alice (alice, alice@example.com) ✔ CodingPlan claimed — CodingPlan Free · expires 2026-05-22 (29d / 30d) ✔ 3 models registered as AtomGit-* providers ✔ Default provider set to AtomGit-GLM > hello"},{"id":"check-cost-before-wrapping-up","heading":"Check cost before wrapping up","body":"> refactor src/db to use a connection pool ... (AI works) > /cost Session token usage - Total output tokens: 8342 - Current turn tokens: 2156 - Context: 42K / 128K"},{"id":"rewind-and-re-ask-when-the-answer-goes-sideways","heading":"Rewind and re-ask when the answer goes sideways","body":"> add JSDoc to every function ... (the reply went off the rails) > /undo Rolled back to turn 3 of 3. ⚠ Only conversation memory was rewound; files on disk were not restored. Revert code manually or check /diff. (your last prompt is back in the input box — edit and resend)"},{"id":"swap-the-model-when-it-underperforms","heading":"Swap the model when it underperforms","body":"> /model > (pick claude-opus-4-6 from the popup) > try again — this time preserve existing comments"},{"id":"next-steps","heading":"Next steps","body":"Keybindings — pair commands with keybindings to double your speed Sessions & Undo — full behaviour of /resume , /undo , /compact © 2026 AtomCode · MIT 报告问题"}]},{"slug":"keybindings","title":"Keybindings","group":"使用","lede":"AtomCode's TUI is built on ratatui + crossterm; common keybindings stick close to the conventions of mainstream terminal tools. Run /keys in a session to dump this table into the current scrollback, or /help for the slash-command list.","sections":[{"id":"keybindings","heading":"Keybindings","body":"AtomCode's TUI is built on ratatui + crossterm; common keybindings stick close to the conventions of mainstream terminal tools. Run /keys in a session to dump this table into the current scrollback, or /help for the slash-command list."},{"id":"input-editing","heading":"Input editing","body":"Key Action Enter Send the message Ctrl+J Insert newline (universal — sends a literal LF byte that every terminal accepts) \\ then Enter Insert newline (atomcode fallback — a trailing backslash makes the line a continuation, works in every terminal) Alt+Enter Insert newline (most terminals; macOS Apple Terminal needs \"Use Option as Meta key\" enabled under Settings → Profiles → Keyboard; Windows Terminal reserves it by default — release in settings) Shift+Enter Insert newline (only terminals that disambiguate the modifier: Kitty / WezTerm / iTerm2 with Report Modifiers / Windows Terminal / Ghostty / Warp. Apple Terminal, xterm, GNOME Terminal, VS Code integrated terminal all collapse it to Enter — use Ctrl+J or \\ + Enter instead) Ctrl+Enter Insert newline (requires a Kitty-keyboard-protocol terminal such as Kitty or WezTerm) Esc Clear current input / interrupt streaming output ↑ / ↓ Browse input history Tab Accept completion (slash-command menu, file paths, etc.) Ctrl+U Clear entire line Ctrl+W Delete a word Ctrl+K Delete from cursor to end of line Ctrl+A Move cursor to line start Ctrl+E Move cursor to line end"},{"id":"browse-scroll","heading":"Browse & scroll","body":"Key Action Shift+↑ / Shift+↓ Scroll one line PageUp / PageDown Scroll one page (10 lines) Alt+↑ / Alt+↓ Jump to previous / next message (macOS Apple Terminal: enable Settings → Profiles → Keyboard → \"Use Option as Meta key\" first) Ctrl+↑ / Ctrl+↓ Jump to previous / next user message Home / End Jump to top / bottom of the conversation Mouse wheel Scroll inside the chat area (atomcode captures the wheel) Ctrl+L Clear the current session's messages"},{"id":"selection-copy","heading":"Selection & copy","body":"Key / action Effect Mouse drag Select text in the chat area (atomcode-managed; auto-scrolls at selection edges) Shift+ mouse drag Use the host terminal's native selection (bypasses atomcode; better for cross-viewport copy) Ctrl+Shift+C Copy selection to system clipboard /copy Copy the AI's last complete reply Right-click menu Some terminals offer direct copy/paste (depends on the terminal, not atomcode)"},{"id":"control-flow","heading":"Control flow","body":"Key Action Esc Cancel the in-progress tool call or streaming output Ctrl+C First press cancels the current action; second consecutive press exits Ctrl+D Exits when the input box is empty"},{"id":"tool-permission-dialog","heading":"Tool permission dialog","body":"When the model is about to execute a dangerous action (destructive bash, writing sensitive files, deleting source code, etc.), AtomCode pops a confirmation dialog: Key Action y / Enter Allow once a Always allow this pattern for the current session n / Esc Deny Don't get greedy \"Always allow\" is granted per tool name + argument pattern and only for the current session — it resets next launch. For permanent cross-session exceptions, manage them in config (e.g. allowlists for specific paths)."},{"id":"next-steps","heading":"Next steps","body":"Slash Commands — pair keybindings with command completion Sessions & Undo — what /undo actually undoes © 2026 AtomCode · MIT 报告问题"}]},{"slug":"sessions","title":"Sessions & Undo","group":"使用","lede":"AtomCode persists every conversation by default, so you can restore, resume, clear, or compact at any time. A single /undo rewinds conversation memory back to any earlier turn.","sections":[{"id":"sessions-undo","heading":"Sessions & Undo","body":"AtomCode persists every conversation by default, so you can restore, resume, clear, or compact at any time. A single /undo rewinds conversation memory back to any earlier turn."},{"id":"session-lifecycle","heading":"Session lifecycle","body":"Each atomcode launch creates a session. A session contains: Full message history (user prompts, AI replies, tool calls) The associated working directory The associated provider / model Token usage stats File-history snapshots of every file edit made in that session Session data is persisted under ~/.atomcode/sessions/ , grouped by project (working-directory hash)."},{"id":"resuming-sessions","heading":"Resuming sessions","body":""},{"id":"continue-the-last-one-from-the-cli","heading":"Continue the last one from the CLI","body":"atomcode -c # or atomcode --continue The most common case: pick up exactly where you left off yesterday."},{"id":"switch-sessions-inside-the-tui","heading":"Switch sessions inside the TUI","body":"/resume Opens the session picker. It lists this project's historical sessions newest-first; jump to any of them quickly. Each entry uses the most recent user prompt as its label for easy recognition."},{"id":"start-a-clean-new-session","heading":"Start a clean new session","body":"/session Spin up a fresh context without changing the working directory. Good for \"the previous task is wrapped — onto something totally unrelated\"."},{"id":"bg","heading":"Background sessions ( /bg )","body":"Need to juggle multiple tasks without losing the current conversation? /bg parks the current session in the background and opens a fresh foreground — switch back any time. Up to 16 concurrent background slots . Command What it does /bg Send the current session to the background and open a new foreground /bg list (alias /bg ls ) List all background sessions: slot, ID, state, created, summary /bg <N> Resume slot N as foreground (the current foreground is swapped to background) /bg drop <N> Drop background slot N /bg help (aliases -h , --help ) Show built-in help"},{"id":"session-states","heading":"Session states","body":"The state column in /bg list reflects what each background session is doing: running — the model loop is still executing; tool calls and output keep advancing in the background idle — the model turn finished; waiting for your next prompt done — the session was explicitly ended cancelled / error — interrupted, or the background run hit an error So /bg isn't just \"suspend\" — the model actually keeps working in the background; when you switch back, the result is already there."},{"id":"background-task-one-shot-dispatch","heading":"/background <task> — one-shot dispatch","body":"If you don't want to swap foreground/background manually and just want to \"have it look something up real quick\", use the /background compatibility entry: /background list every unused dependency under src It starts a one-shot task in a /bg slot (configured with a read-only tool subset by default so the main conversation context isn't polluted). When done, check /bg list , use /bg <N> to read the result, /bg drop <N> to discard. Typical pattern The foreground is debugging module A; the model is editing and running cargo check (slow). You realise you also want to refactor module B — /bg straight to a new foreground for B. The build on A finishes in the background, state flips to done ; /bg 1 to switch back and read the result."},{"id":"clear-vs-compact-vs-new-session","heading":"Clear vs compact vs new session","body":"Command Keeps history Keeps session ID When to use /clear No Yes \"Reset the dialogue\" within the same session; keep the session entry so you can /resume later /compact Partial (summarised) Yes Context is filling up but you don't want to lose the earlier thread /session Starts new thread No (new ID) Beginning a completely unrelated task"},{"id":"rewinding-conversation-memory-with-undo","heading":"Rewinding conversation memory with /undo","body":"/undo rewinds conversation memory to before a given turn — removing that turn and everything after it — and drops the prompt you typed for that turn back into the input box so you can edit and resend it. /undo # rewind the last turn /undo N # rewind to turn N (1-based; counts only the prompts you actually typed) The scrollback dividers for the removed turns are cleared too, and the session is saved immediately — so your next /resume reflects the rewound state. Where the boundary is /undo rewinds conversation memory only — it does not restore files on disk. If the AI edited code during those turns, those changes stay in your working tree; use /diff to review and revert them manually, or rely on git. You can't /undo while a turn is in flight — press Esc to cancel it first."},{"id":"inspecting-and-trimming-cost","heading":"Inspecting and trimming cost","body":"/cost Shows cumulative input / output tokens for the current session. When the number approaches the provider's context_window : Use /compact to compact history (early messages become a summary) Or just /session and start fresh To avoid keeping large tool-call results, tell the model in the prompt to \"stop re-reading those big files\""},{"id":"multi-project-workflows","heading":"Multi-project workflows","body":"AtomCode groups sessions by working directory. Recommended ways to switch: From the CLI, specify with -C While running, use /cd ; default_workdir is persisted automatically"},{"id":"next-steps","heading":"Next steps","body":"Project Instructions — lock in per-project context with .atomcode.md © 2026 AtomCode · MIT 报告问题"}]},{"slug":"tools","title":"Built","group":"进阶","lede":"AtomCode currently ships 21 built-in tools, grouped into four categories: filesystem & shell, code graph, web, automation. The model picks tools per task — you almost never need to specify by hand.","sections":[{"id":"built-in-tools","heading":"Built-in Tools","body":"AtomCode currently ships 21 built-in tools, grouped into four categories: filesystem & shell, code graph, web, automation. The model picks tools per task — you almost never need to specify by hand."},{"id":"filesystem-shell-9","heading":"Filesystem & shell (9)","body":"Tool Purpose Confirmation? read_file Read file content; supports line offset and range No write_file Write a full file (overwrite) Sensitive paths: yes edit_file String-match local edits; returns the edited context Sensitive paths: yes search_replace Batch string replacements; good for multi-line / multi-site patterns Sensitive paths: yes bash Run shell commands; destructive commands trigger the permission dialog Destructive: yes grep Regex search with ripgrep semantics No glob Filename glob matching (e.g. src/**/*.ts ) No list_directory List directory contents No change_dir Switch the agent's current working directory No Sensitive paths Writes to paths like /etc , ~/.ssh , and shell rc files always trigger the permission dialog — \"always allow\" cannot skip them. Likewise, rm on source files always needs explicit confirmation. Background long-running tasks Pass run_in_background: true to bash and the command launches as a detached process and returns immediately with a PID and a log-file path; the process survives across conversation turns — ideal for dev servers, file watchers, and tunnels, without blocking the session. Destructive-command guard High-risk commands like rm -rf , dd , mkfs , and sudo , plus schema-destroying database migrations (e.g. migrate:fresh , db:reset ), always force a permission prompt. This confirmation always fires — even a prior \"always allow\" on bash cannot skip it."},{"id":"code-graph-8","heading":"Code graph (8)","body":"This is what sets AtomCode apart from generic agents. With the code-graph index, the model can pinpoint symbols, references, and call relationships without scanning the entire tree — especially valuable on large repos. Tool Purpose list_symbols List all symbols defined in a file or directory (functions, classes, constants, …) read_symbol Read a symbol's full definition surgically, without dragging the entire file into context find_references Find every location that references a symbol trace_callers Walk the caller chain of a function backwards trace_callees Expand a function's downstream calls trace_chain Search for a possible call chain between two symbols file_deps Analyse a file's imports / dependency graph blast_radius Estimate the files / symbols a change to a given symbol could affect"},{"id":"typical-scenarios","heading":"Typical scenarios","body":"Pre-refactor risk assessment — \"How big is the blast if I change formatDate 's signature?\" The model calls blast_radius + find_references . Bug root-causing — \"Why doesn't this button respond?\" Start at the entry function and trace_callees downward. Understanding unfamiliar code — \"Walk me through AuthService.login \" → read_symbol + trace_callees ."},{"id":"web-2","heading":"Web (2)","body":"Tool Purpose web_search Search the web for keywords; returns a list of title / snippet / URL web_fetch Fetch a URL and convert it to markdown for the model Typical uses: looking up the latest docs, comparing library APIs, reading a GitHub issue. In offline environments or to save cost, disable them with --disable-tools web_search,web_fetch ."},{"id":"automation-2","heading":"Automation (2)","body":"Tool Purpose auto_fix Run the project's lint / typecheck and iterate over the error list until clean use_skill Invoke a user-defined skill — package a multi-step flow as a reusable command See Skills for details."},{"id":"disabling-specific-tools","heading":"Disabling specific tools","body":"Use the --disable-tools flag at launch to hide tools from the model entirely. For example, inside the SWE-bench sandbox: atomcode -p \"solve this issue\" --disable-tools web_search,web_fetch Disabled tools don't appear in the tool schemas, so the model won't attempt to call a tool guaranteed to fail."},{"id":"next-steps","heading":"Next steps","body":"Sessions & Undo — every file-edit tool routes through file-history, so /undo can roll back changes Skills — wrap your own workflows with use_skill © 2026 AtomCode · MIT 报告问题"}]},{"slug":"skills","title":"Skills","group":"进阶","lede":"A skill is a user-defined, reusable command — basically a chunk of markdown with frontmatter telling the AI \"here's how to handle this kind of task\". Once you've written one, it shows up alongside the built-in slash commands in the menu, or can be invoked on-demand by the use_skill tool.","sections":[{"id":"skills","heading":"Skills","body":"A skill is a user-defined, reusable command — basically a chunk of markdown with frontmatter telling the AI \"here's how to handle this kind of task\". Once you've written one, it shows up alongside the built-in slash commands in the menu, or can be invoked on-demand by the use_skill tool."},{"id":"what-skills-are-good-for","heading":"What skills are good for","body":"Codifying frequent workflows: cutting a release, writing a changelog, running regression tests, generating weekly reports… Wrapping complex tasks that need step-by-step guidance: refactor playbooks, bug root-cause analysis, performance tuning Making the model follow your defined steps and validation rules on a specific topic"},{"id":"skill-file-layout","heading":"Skill file layout","body":"A skill is usually a directory containing at least a SKILL.md : my-skills/ ├── release/ │ └── SKILL.md ├── write-changelog/ │ └── SKILL.md └── debug-flaky-test/ ├── SKILL.md └── references/ └── pattern-library.md A typical SKILL.md : --- name: release description: Cut a new release tag, update the changelog, and publish --- ## When to use When the user says \"ship a new version\", \"cut a release\", or \"tag it\". ## Steps 1. Inspect `git log` for changes since the last release. 2. Ask the user to confirm the semver bump (patch / minor / major). 3. Add the new entry to `CHANGELOG.md`. 4. Run `pnpm build` and ensure it passes. 5. Create the git tag `v<version>` with release notes. 6. Run `pnpm publish` (or the corresponding publish command). ## Rules - Version numbers must follow semver. - Never skip tests — fix any failure first. - If publish fails, roll back the local tag and changelog edits."},{"id":"skill-directories","heading":"Skill directories","body":"AtomCode loads skills from a few well-known locations: Global : ~/.atomcode/skills/ Project-level : .atomcode/skills/ at the current working directory or any ancestor (if present) Project-level skills override same-named globals, so you can define the same name with different flows per project."},{"id":"invocation","heading":"Invocation","body":""},{"id":"via-slash-command","heading":"Via slash command","body":"Every successfully loaded skill appears in the slash-command completion menu: > /release > /write-changelog > /debug-flaky-test"},{"id":"via-the-menu","heading":"Via the $ menu","body":"Type a $ at the start of the input box to pop up a skills menu (the same set of invocable skills that /skills lists); keep typing to filter, press Tab to complete the highlighted name, and submit $<name> [args] to invoke that skill. It's a parallel entry point to slash commands: / drives slash-command completion, while $ is dedicated to picking a skill and can carry arguments inline, e.g. $brainstorming help me design login ."},{"id":"model-driven-invocation","heading":"Model-driven invocation","body":"The model can call the use_skill tool itself to run a relevant skill as a sub-flow. If you say \"publish a new version\", the model may pick this skill on its own without you typing /release ."},{"id":"tips-for-writing-a-good-skill","heading":"Tips for writing a good skill","body":"Be specific in the description — it's the menu's blurb, and the main signal the model uses to decide whether this skill applies. Order matters — the model reads top-to-bottom; put strong dependencies up front. Make branches explicit — \"if build fails …; otherwise …\" is far more reliable than letting the model guess. List red lines — put hard rules in a dedicated \"Rules\" section to maximise compliance. Use sub-docs when needed — park long references in references/*.md and leave a one-liner like \"see … if needed\" in SKILL.md ."},{"id":"与项目指令的分工","heading":"Versus project instructions","body":"Scenario Where it belongs Always-on project conventions (tech stack, code style, commands) .atomcode.md A specific workflow that needs to be triggered explicitly Skill A one-off ad-hoc requirement Just write it in the prompt"},{"id":"next-steps","heading":"Next steps","body":"Basic Usage — back to everyday workflows FAQ — why isn't my skill showing up in the menu? © 2026 AtomCode · MIT 报告问题"}]},{"slug":"mcp","title":"MCP Integration","group":"进阶","lede":"MCP (Model Context Protocol) is an open protocol that plugs the \"tools\" exposed by external programs or HTTP services into AtomCode, so the model can call them like built-in tools. Since v4.20.4, AtomCode ships a built-in MCP client and re-uses the same mcpServers configuration block as Cursor and others.","sections":[{"id":"mcp-integration","heading":"MCP Integration","body":"MCP (Model Context Protocol) is an open protocol that plugs the \"tools\" exposed by external programs or HTTP services into AtomCode, so the model can call them like built-in tools. Since v4.20.4, AtomCode ships a built-in MCP client and re-uses the same mcpServers configuration block as Cursor and others."},{"id":"what-it-enables","heading":"What it enables","body":"Operate GitHub, GitLab, Jira, and other external services via official MCP servers Connect to Postgres / MySQL / DuckDB and other databases Use community servers for the filesystem, Playwright browser, Slack messages, and more Expose your team's domain-specific tools to the model without modifying atomcode source"},{"id":"two-config-locations","heading":"Two config locations","body":"Path Scope <project-root>/.mcp.json Current project only — good for living next to the code ~/.atomcode/mcp.json User global, shared across every project Both can coexist; same-named servers prefer the project-level entry (it overrides the user-level one). The repo's .mcp.json.example ships heavily-commented stdio + HTTP templates — start from there."},{"id":"config-schema","heading":"Config schema","body":"The top-level key is fixed at mcpServers (the legacy servers key still works). Each server should pick one transport: stdio : command (required) + optional args , env , timeout_ms , disabled HTTP : url (required) + optional headers , auth , timeout_ms , disabled If a server has both command and url , the current implementation treats it as stdio ( command ). To avoid ambiguity, don't write both. Strings support ${VAR} and ${VAR:-default} environment expansion; never hard-code sensitive tokens — keep them in env vars. disabled: true temporarily turns off a server without removing the entry."},{"id":"stdio-example-local-subprocess","heading":"stdio example (local subprocess)","body":"{ \"mcpServers\": { \"filesystem\": { \"command\": \"npx\", \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/tmp\"], \"timeout_ms\": 10000 } } }"},{"id":"http-example-remote-endpoint","heading":"HTTP example (remote endpoint)","body":"{ \"mcpServers\": { \"github\": { \"url\": \"https://api.githubcopilot.com/mcp/\", \"headers\": { \"Authorization\": \"Bearer ${GITHUB_TOKEN}\" }, \"timeout_ms\": 30000 } } }"},{"id":"github-remote-mcp-oauth","heading":"GitHub remote MCP + OAuth","body":"{ \"mcpServers\": { \"github\": { \"url\": \"https://api.githubcopilot.com/mcp/\", \"auth\": { \"type\": \"oauth\", \"provider\": \"github\" } } } } Before first use, you need AtomCode's own GitHub OAuth App client id, then run: atomcode mcp add-github-oauth --global ATOMCODE_GITHUB_MCP_CLIENT_ID=<client_id> atomcode mcp login github atomcode Inside the TUI you can also set the env var and run /mcp login github ; after a successful login, /mcp reload reconnects."},{"id":"one-line-server-add","heading":"One-line server add","body":"atomcode mcp add writes the stdio config to JSON for you — no hand-editing required: # Write to project-root .mcp.json (current directory by default) atomcode mcp add playwright npx @playwright/mcp@latest # Write to user-global ~/.atomcode/mcp.json atomcode mcp add playwright npx @playwright/mcp@latest --global # Pin a specific project directory atomcode mcp add playwright npx @playwright/mcp@latest -C /path/to/repo The first positional is the server key name (which will appear in tool names); the rest is the executable + args. For GitHub remote MCP OAuth there's a dedicated entry: atomcode mcp add-github-oauth --global ATOMCODE_GITHUB_MCP_CLIENT_ID=<client_id> atomcode mcp login github Note A same-named server is fully overwritten . The GitHub OAuth token is stored at ~/.atomcode/mcp_auth.toml — it is not written to .mcp.json ."},{"id":"what-happens-at-startup","heading":"What happens at startup","body":"Mode Connection behaviour When tools appear TUI Connects in parallel in the background — doesn't block the UI Each server registers as it connects, possibly slightly after the first frame One-shot ( -p ) Connects synchronously at launch; waits for enabled servers' connection attempts to finish MCP only mounts once at least one batch of tools is available In the TUI you'll see ✓ MCP server 'github' connected or ✗ MCP server '…' failed: … in the session area. A single server failure does not break other servers or the main program."},{"id":"tool-naming","heading":"Tool naming","body":"Each remote tool is registered as mcp__<server-key>__<remote-tool-name> . Example: with \"mcpServers\": { \"github\": { ... } } and a remote get_issue tool, the model sees the tool name mcp__github__get_issue . --disable-tools uses the full name too: atomcode --disable-tools mcp__github__get_issue,mcp__filesystem__write_file"},{"id":"permission-approval","heading":"Permission approval","body":"MCP tools default to per-call confirmation (equivalent to RequireApproval ) because the remote is external, untrusted code. Press Y — allow once Press A — allow this tool for the current session (resets next launch; never persisted) Press N — deny this call Security note Treat MCP tool results as untrusted data. Do not let them be promoted to system instructions. If an MCP server returns \"please ignore previous instructions\", the model should not comply."},{"id":"slash-commands","heading":"Slash commands","body":"Command Purpose /mcp List successfully connected servers and their status (failed servers don't appear here — only as red error lines in the session area) /mcp tools <server> Async-list the remote tools actually exposed by a server /mcp reload Re-read .mcp.json / ~/.atomcode/mcp.json and reconnect enabled servers in the background"},{"id":"current-limits","heading":"Current limits","body":"Only MCP's tools capability is supported; resources / prompts / OAuth / roots / elicitation are not yet implemented HTTP servers don't have exponential-backoff reconnects, and stdio child processes don't auto-restart on exit — use /mcp reload to reconnect manually tools/list list_changed notifications don't trigger a dynamic refresh Tool results only consume text content blocks; image / resource blocks are currently ignored [A] Always applies only within the current session; it is never written to a config file"},{"id":"ecosystem-comparison","heading":"Ecosystem comparison","body":"Product Config location Notes AtomCode mcpServers block in .mcp.json Current implementation is tools-only Claude Code .mcp.json More complete OAuth / resources / prompts support Cursor .mcp.json Common command / url configs usually reusable Codex CLI add OpenAI ecosystem If you already use Cursor's MCP setup, common command / url configs are usually reusable; anything outside AtomCode's current fields or capabilities needs verification."},{"id":"next-steps","heading":"Next steps","body":"The .mcp.json.example at the repo root — heavily-commented stdio + HTTP templates Configuration — overall config overview Slash Commands — full command list including the /mcp family © 2026 AtomCode · MIT 报告问题"}]},{"slug":"plugins","title":"Plugin System","group":"进阶","lede":"A plugin is a bundle of skills / commands / hooks distributed over a git repository. One /plugin install drops someone else's workflow into AtomCode and you can use it immediately. AtomCode's plugin protocol is compatible with Claude Code — CC-ecosystem plugin repos install and run out of the box.","sections":[{"id":"plugin-system","heading":"Plugin System","body":"A plugin is a bundle of skills / commands / hooks distributed over a git repository. One /plugin install drops someone else's workflow into AtomCode and you can use it immediately. AtomCode's plugin protocol is compatible with Claude Code — CC-ecosystem plugin repos install and run out of the box."},{"id":"core-concepts","heading":"Core concepts","body":"Marketplace — a git repository whose root contains .atomcode-plugin/marketplace.json or .claude-plugin/marketplace.json , declaring the plugins it provides. Plugin — an entry in a marketplace. It can be a subdirectory of the same repo, or it can point to an external git repository ( url / github / git ) or a local path ( local ). Skill / Command / Hook — the three asset types a plugin contributes. Skills and commands are namespaced with plugin-name: (to avoid collisions); hooks fire on events."},{"id":"command-reference","heading":"Command reference","body":"Command Purpose /plugin Open the interactive plugin manager (↑/↓ to select, Enter to confirm, Esc to go back). Browse marketplaces, install/uninstall plugins, add/remove marketplaces — all from one screen /plugin marketplace add <url> Clone a git repo and register it as a marketplace /plugin marketplace remove <name> Remove a registered marketplace (refuses if any of its plugins are still installed) /plugin marketplace update <name> Pull the latest commit for a marketplace repo, refreshing its plugin list /plugin marketplace list List all registered marketplaces /plugin install <plugin>@<marketplace> Install a plugin from the named marketplace /plugin uninstall <plugin>@<marketplace> Uninstall an installed plugin (the marketplace registration is kept) /plugin list List all locally installed plugins /plugin reload Reload all plugins (re-scan disk, refresh skill/hook registration)"},{"id":"install-a-plugin","heading":"Install a plugin","body":""},{"id":"method-1-interactive-manager-recommended","heading":"Method 1: interactive manager (recommended)","body":"Type /plugin in the TUI (no subcommand) to open a full-screen interactive manager. Navigate with arrow keys, confirm with Enter: /plugin # → Opens the manager home screen: # Browse & install — Browse a marketplace's plugins, Enter to install/uninstall # Add marketplace… — Type/paste a git URL to add a new marketplace # Remove marketplace… — Pick a marketplace to remove # Installed (N) — View installed plugins, Enter to uninstall Installed plugins show a ✓ mark; pressing Enter toggles install/uninstall. Cloning and installing are async — a status line appears at the bottom during the operation and the list refreshes automatically when done."},{"id":"method-2-slash-command-subcommands","heading":"Method 2: slash-command subcommands","body":"# 1. Register the marketplace (clones its git repo locally) /plugin marketplace add https://gitcode.com/gmq123/ascend-model-agent-plugin # 2. Install one of its plugins /plugin install ascend-model-agent-plugin@ascend-model-agent-plugin # 3. List installed plugins /plugin list"},{"id":"method-3-cli","heading":"Method 3: CLI","body":"atomcode plugin marketplace add <git-url> atomcode plugin install <plugin>@<marketplace> atomcode plugin list atomcode plugin uninstall <plugin>@<marketplace> atomcode plugin marketplace remove|update|list The CLI and TUI share the ~/.atomcode/plugins/ directory; anything installed on one side is visible on the other immediately."},{"id":"after-install","heading":"After install","body":"Skills contributed by the plugin appear in the / menu with a <plugin-name>: prefix, e.g. /ascend-model-agent-plugin:ascend-model-verification . The model can also invoke these skills through the UseSkill tool. Hooks activate immediately — since v4.21.1, /plugin install rebuilds the hook executor automatically; no need to /cd or restart."},{"id":"directory-layout","heading":"Directory layout","body":"~/.atomcode/plugins/ ├── marketplaces.json # Registered marketplace metadata ├── installed_plugins.json # Status records for installed plugins ├── marketplaces/ │ └── <marketplace-name>/ # The marketplace repository clone │ ├── .claude-plugin/marketplace.json │ └── <plugin-subdir>/ # Inline plugin └── installed/ └── <marketplace>/<plugin>/ # Clones of plugins from external sources"},{"id":"pluginjson-shape","heading":"plugin.json shape","body":"The plugin.json in each plugin's root (or its .claude-plugin/ / .atomcode-plugin/ subdirectory): { \"name\": \"my-plugin\", \"version\": \"1.0.0\", \"description\": \"What it does\", \"skills\": [\"./skills\"], // Also accepts the string \"skills\" \"commands\": [\"./commands\"], \"hooks\": { // Also accepts a path string \"hooks.json\" \"UserPromptSubmit\": [{ \"hooks\": [{ \"type\": \"command\", \"command\": \"python \\\"${CLAUDE_PLUGIN_ROOT}/hook.py\\\"\", \"timeout\": 5 }] }] } }"},{"id":"hook-events","heading":"Hook events","body":"Plugins can hook the following events (matching CC): Event When it fires Typical use UserPromptSubmit After the user submits a message, before the LLM call Inject additional context / route / block PreToolUse Before a tool call Validation, blocking, argument rewriting PostToolUse After a tool call Audit, side effects SessionStart Session startup Warm-up, logging SessionEnd Session end Cleanup, archiving Notification System notification Forward to external alert channels"},{"id":"userpromptsubmit-io-protocol","heading":"UserPromptSubmit IO protocol","body":"The hook receives JSON on stdin and decides what to do via stdout: { \"session_id\": \"...\", \"hook_event_name\": \"UserPromptSubmit\", \"prompt\": \"the user's input text\", \"cwd\": \"/working/directory\" } The hook can respond in the following ways (highest priority first): Non-zero exit code — blocks the prompt; reason is taken from stderr. JSON on stdout {\"decision\": \"block\", \"reason\": \"...\"} — block with an explicit reason. JSON on stdout {\"hookSpecificOutput\": {\"additionalContext\": \"...\"}} — append additionalContext to the user message as extra LLM context. Plain text on stdout — the whole block is injected as additionalContext . Empty stdout / unparseable JSON — passthrough; the prompt reaches the LLM unchanged. When parsing stdout, AtomCode first tries the last non-empty line as JSON; on failure it falls back to whole-text injection — so a hook script can print debug output earlier without affecting the final decision."},{"id":"path-variables","heading":"Path variables","body":"Hook command strings can reference these environment variables (injected by the executor): ${CLAUDE_PLUGIN_ROOT} — absolute path of the plugin install directory (CC compatible). ${ATOMCODE_PLUGIN_ROOT} — same thing, atomcode alias. These are real environment variables expanded by the shell itself, not string substitutions — install paths with spaces, quotes, $ , or ; won't break the command."},{"id":"marketplace-management","heading":"Marketplace management","body":"# List registered marketplaces /plugin marketplace list # Pull the latest commit (refreshes the plugin list this marketplace exposes) /plugin marketplace update <name> # Remove (refuses if any plugin from this marketplace is still installed) /plugin marketplace remove <name>"},{"id":"walkthrough-installing-the-ascend-plugin","heading":"Walkthrough: installing the Ascend plugin","body":"/plugin marketplace add https://gitcode.com/gmq123/ascend-model-agent-plugin # > cloning marketplace from https://gitcode.com/... # > marketplace `ascend-model-agent-plugin` added at 7a59537 (1 plugins) /plugin install ascend-model-agent-plugin@ascend-model-agent-plugin # > installing `...`... # > installed `ascend-model-agent-plugin@ascend-model-agent-plugin` — 23 skills loaded, 5 skipped # This plugin installs a UserPromptSubmit hook (workflow_planner_hook.py). # When you say \"help me verify Qwen3 adaptation on Ascend\", it injects a # workflow JSON and routes the model through the ascend-model-verification # skill pipeline. help me verify Qwen3 adaptation on Ascend"},{"id":"known-limits","heading":"Known limits","body":"Unsupported CC events : Stop / PreCompact / SubagentStop are silently skipped. Multi-line indented JSON output : when a hook prints with print(json.dumps(..., indent=2)) , the last line is } , which our last-line JSON parser fails on — falling back to plain-text injection. Functionally it still works (the LLM still reads the content) but it's not on the structured path. Hook authors should use single-line json.dumps(...) output. Strict skill-name validation : [a-z0-9_-] , matching CC. Skill names with / or mixed case are skipped."},{"id":"next-steps","heading":"Next steps","body":"Skills — write your own skills; they work inside plugins too. Slash Commands — full /plugin command list. MCP Integration — another path for connecting external tools; complementary to plugins. © 2026 AtomCode · MIT 报告问题"}]},{"slug":"memory","title":"Persistent Memory","group":"进阶","lede":"Use /remember to capture stray preferences, conventions, and commands. AtomCode injects them into the system prompt on every turn. It complements .atomcode.md project instructions : instructions are for full specs; memory is for the \"oh, I should tell it about that\" facts.","sections":[{"id":"persistent-memory","heading":"Persistent Memory","body":"Use /remember to capture stray preferences, conventions, and commands. AtomCode injects them into the system prompt on every turn. It complements .atomcode.md project instructions : instructions are for full specs; memory is for the \"oh, I should tell it about that\" facts."},{"id":"command-overview","heading":"Command overview","body":"Command Effect /remember <content> Record an entry in project memory (default scope, bound to the current working directory) /remember --global <content> Record an entry in global memory (shared across all projects) /forget <keyword> Delete every entry in global + project memory matching the keyword (case-insensitive); the output lists what got removed /memory Show all active memory entries, grouped under [Global] / [Project] , with disk paths"},{"id":"storage-locations","heading":"Storage locations","body":"Scope Path Global ~/.atomcode/memory.md (or $ATOMCODE_HOME/memory.md ) Project <project_root>/.atomcode/memory.md The format is plain Markdown — one entry per - -prefixed list item. Use /remember or hand-edit; AtomCode rereads on the next turn. Lines not starting with - are ignored , so feel free to add comments, blank lines, or grouping headings without affecting entries."},{"id":"how-the-model-uses-memory","heading":"How the model \"uses\" memory","body":"For every request, AtomCode merges global + project memory and injects it into the system prompt ( crates/atomcode-core/src/agent/prompt.rs:64 ), formatted as: === MEMORY === The user has asked you to remember these facts and preferences: [Global] - Prefers concise answers, no long-winded explanations - Reply in Chinese, but write commit messages in English [Project: atomcode] - Test command is cargo test --workspace --no-fail-fast - When CI fails, first check .github/workflows/ci.yml lines 78-92 The model sees this block on every turn. There is no \"semantic retrieval\" or \"on-demand recall\" — it's unconditional full injection. The more entries, the more tokens per turn. Prune stale entries to keep this tight."},{"id":"capacity-limits","heading":"Capacity limits","body":"Limit Value What happens at the limit Single memory file size 64 KB Only the trailing 64 KB is read (aligned to line boundaries — UTF-8 characters are never split) Total characters in the injected prompt 4000 chars Truncated with a trailing [...truncated, run /memory to review] note Once you hit the limit, use /forget to clean up — drop entries that are no longer relevant."},{"id":"suggested-uses","heading":"Suggested uses","body":""},{"id":"1-project-specific-commands-conventions-footguns-project-sco","heading":"1. Project-specific commands, conventions, footguns (project scope)","body":"> /remember use npm run check for type-checking (not npm run typecheck) > /remember when CI fails, check .github/workflows/ci.yml lines 78-92 first > /remember never use sed -i in this repo (macOS/Linux behaviour differs) > /remember DB migration SQL must run on staging before main"},{"id":"2-global-coding-preferences-workflows-global","heading":"2. Global coding preferences, workflows (global)","body":"> /remember --global run tests before committing > /remember --global don't git push on your own — let me confirm manually > /remember --global reply in Chinese but write commit messages in English > /remember --global prefer editing existing files — don't create docs (*.md) on your own"},{"id":"3-personal-or-team-info-global","heading":"3. Personal or team info (global)","body":"> /remember --global my GitHub username is alice > /remember --global default timezone Asia/Shanghai > /remember --global team standup is Mon/Wed/Fri at 9:30"},{"id":"4-cleaning-up-stale-memories","heading":"4. Cleaning up stale memories","body":"> /forget npm run check [project] - use npm run check for type-checking (not npm run typecheck) (removed 1 matching entry) > /memory [Global] (/Users/alice/.atomcode/memory.md) - run tests before committing - don't git push on your own — let me confirm manually [Project] (/Users/alice/code/myrepo/.atomcode/memory.md) - when CI fails, check .github/workflows/ci.yml lines 78-92 first"},{"id":"memory-vs-project-instructions-vs-session-history","heading":"Memory vs project instructions vs session history","body":"AtomCode offers three ways to persist \"context\", each with a different role: .atomcode.md Memory (memory.md) Sessions ( /resume ) Best for Full specs, tech stack, detailed conventions Stray facts, personal preferences, command cheats Past conversation + tool calls Scope Project Project + global One specific session How to add Hand-edit /remember or hand-edit Auto-saved per conversation Injection Loaded into system prompt at startup Injected into system prompt every turn Restored wholesale via /resume Token cost High (full doc) Capped at 4000 chars Bounded by the context window Typical combinations: Team conventions in .atomcode.md (commit it; shared by everyone) Personal preferences via /remember --global (only on your machine) Project-specific footguns via /remember (lives in the project's local .atomcode/memory.md ; commit or gitignore your call) Whether to commit .atomcode/memory.md : if the team also uses AtomCode and the memory is project knowledge (footguns, conventions), commit it; if it's personal notes, add it to .gitignore ."},{"id":"next-steps","heading":"Next steps","body":"Project Instructions — the best home for full specs Slash Commands — full command reference Sessions & Undo — the details of /resume © 2026 AtomCode · MIT 报告问题"}]},{"slug":"project-instructions","title":"Project Instructions","group":"进阶","lede":"Drop a .atomcode.md in your project root to pin tech-stack details, conventions, and preferences. AtomCode injects it into the system prompt at startup, so you don't have to repeat the rules every conversation.","sections":[{"id":"project-instructions","heading":"Project Instructions","body":"Drop a .atomcode.md in your project root to pin tech-stack details, conventions, and preferences. AtomCode injects it into the system prompt at startup, so you don't have to repeat the rules every conversation."},{"id":"why-bother","heading":"Why bother","body":"A typical scenario: your team uses the Composition API exclusively — Options API is banned. Every time you ask AtomCode to write a new component, you have to remind it. With .atomcode.md , that preference rides along on every conversation automatically."},{"id":"file-location","heading":"File location","body":"Default path: .atomcode.md at the project root AtomCode walks upwards from the current working directory until it finds the file, or hits $HOME If the file doesn't exist, no related content appears in the system prompt"},{"id":"example","heading":"Example","body":"# Project Instructions This is a Vue 3 + TypeScript project using Pinia for state, Tailwind for styles, and Vitest for unit tests. ## Conventions - Components must use `<script setup lang=\"ts\">` Composition API - Only Tailwind for styling — no inline style attributes, no standalone .css files - All API calls go through `src/services/*`; never fetch directly in components - State lives in Pinia stores — components keep no derived global state ## Commands - Dev: `pnpm dev` - Typecheck: `pnpm typecheck` - Tests: `pnpm test` - Build: `pnpm build` ## Notes - Do not modify `src/generated/*` — it's auto-generated from OpenAPI - Test coverage must stay above 80%; new modules must ship with unit tests"},{"id":"tips-for-writing-atomcodemd","heading":"Tips for writing .atomcode.md","body":"Only write what's different from the norm — the model already knows generic best practices; don't repeat them here. Prefer commands over descriptions — \"run tests with pnpm test \", not \"please run the unit tests\". Use imperatives — \"Use X\", \"Don't Y\" — avoid hedge words like \"suggest\", \"if possible\". List forbidden zones — call out files / directories that must not be touched. The model is highly compliant. Keep it short — every line costs tokens; 30-80 lines is usually plenty. Tip If you have repetitive workflows (e.g. the same set of commands every bug fix), don't bloat .atomcode.md — write a Skill instead. It's clearer and more reusable."},{"id":"relationship-to-agentsmd-claudemd-geminimd","heading":"Relationship to AGENTS.md / CLAUDE.md / GEMINI.md","body":"AtomCode natively supports AGENTS.md , the open standard for AI coding agent context. If you have a project that already uses AGENTS.md , AtomCode will pick it up automatically — no extra setup needed. The lookup order is: .atomcode.md ATOMCODE.md AGENTS.md CLAUDE.md / claude.md First match wins. If you also use Claude Code or Gemini CLI in the same project, they each have their own instruction files: AtomCode → .atomcode.md or AGENTS.md Claude Code → CLAUDE.md Gemini CLI → GEMINI.md These don't conflict. By using AGENTS.md , you can share the same instruction file across multiple AI coding tools that follow the open standard."},{"id":"next-steps","heading":"Next steps","body":"Skills — abstract reusable workflows into commands © 2026 AtomCode · MIT 报告问题"}]},{"slug":"webui","title":"Web UI","group":"进阶","lede":"Besides the terminal TUI, AtomCode ships a built-in browser interface : type /webui in the TUI to launch it, then chat, browse session history, add/edit/delete model providers, and upload images in the browser — and use /sync to mirror one session live between the terminal and the browser. It reuses this machine's login, models, and session history, so there's nothing extra to configure.","sections":[{"id":"web-ui","heading":"Web UI","body":"Besides the terminal TUI, AtomCode ships a built-in browser interface : type /webui in the TUI to launch it, then chat, browse session history, add/edit/delete model providers, and upload images in the browser — and use /sync to mirror one session live between the terminal and the browser. It reuses this machine's login, models, and session history, so there's nothing extra to configure."},{"id":"start-stop","heading":"Start & stop","body":"Run these in the AtomCode TUI input box: # Launch the webui and open the browser (binds 127.0.0.1:13457 by default — local only) /webui # Stop the webui server /webui stop On launch, AtomCode starts a local HTTP server and opens your browser to a URL like http://127.0.0.1:13457/?token=<one-time token> . The token in the URL is the credential — it's equivalent to a password , so don't share it. The current TUI session is also attached to live sync automatically (see Live sync across devices below). Localhost only by default The webui binds 127.0.0.1 , reachable only from this machine. To open it from a phone, do not expose it with --host 0.0.0.0 ; use the 蒲公英 virtual-LAN approach instead — see Remote Access ."},{"id":"what-the-interface-offers","heading":"What the interface offers","body":"The browser UI brings the terminal's capabilities into a graphical interface: Area What you can do Sidebar Session history grouped by project, search sessions, start a new chat, rename / delete sessions; collapses to an icon rail (a drawer on mobile). Model selector Switch provider / model right under the input box; same-named models are disambiguated with a provider tag. Model config Add / edit / delete providers in settings: name, type (openai / claude / ollama), model, Base URL, API key, context window, and set-as-default. Settings Theme (light / dark), language (中 / EN), model config, and the remote-access entry. Image attachments Paste or pick images to send with a message (2 MB each); non-vision models fall back to VL; thumbnails show in history. Tool execution Tool calls show their arguments and output inline, expandable line by line, both live and in history. Attach menu (+) Upload an image, pick a file for context, or insert a Skill. Working directory Switch the working dir, browse folders, create a new folder, set a default working dir."},{"id":"live-sync","heading":"Live sync across devices","body":"Behind the webui is a LiveSession : one session can be open in the terminal and multiple browser tabs at once, and every input, streamed AI reply, and tool result is broadcast live to all connected views — a viewer that joins late first receives a snapshot replay. When you run /webui , the current TUI session is attached automatically — messages you send in the terminal appear in the browser, and vice versa. In another TUI, run /sync to attach to the running webui session (a /webui must already be running). /sync off — leave sync and return to a standalone session. This makes \"start in the terminal, watch progress on a phone / tablet\" — or several people watching the same agent session — possible."},{"id":"remote-access","heading":"Remote access","body":"Want to open the webui from a phone without exposing it publicly? Use a 蒲公英 (Oray PGY) virtual LAN: bind the server to the virtual IP with /webui --host <virtual IP> , then scan the QR in the Remote Access panel. Full walkthrough in Remote Access ."},{"id":"next","heading":"Next","body":"Remote Access — open the webui from a phone over 蒲公英, safely Headless & Daemon — the daemon and HTTP/SSE API behind the webui Slash Commands — quick reference for /webui , /sync and more © 2026 AtomCode · MIT 报告问题"}]},{"slug":"webui-remote-access","title":"Remote Access","group":"进阶","lede":"By default the AtomCode webui only listens on loopback ( 127.0.0.1 ), so your phone and other devices can't reach it. With a virtual LAN built by 蒲公英 (Oray PGY) you can open the webui from a phone or tablet securely — no public IP, nothing exposed to the internet. This page walks through the full connection flow and the security notes.","sections":[{"id":"remote-access","heading":"Remote Access","body":"By default the AtomCode webui only listens on loopback ( 127.0.0.1 ), so your phone and other devices can't reach it. With a virtual LAN built by 蒲公英 (Oray PGY) you can open the webui from a phone or tablet securely — no public IP, nothing exposed to the internet. This page walks through the full connection flow and the security notes."},{"id":"how-it-works","heading":"How it works","body":"蒲公英 is a remote-networking tool. Once it's installed on both this machine and your phone, signed into the same account and joined to the same network , the two devices sit on one virtual LAN and can talk over a 蒲公英 virtual IP . As long as the webui is bound to that virtual IP, your phone can reach it. The whole link is a private peer-to-peer network — your machine is never exposed to the public internet . Why not just open it to the internet The webui / daemon has no built-in authentication; whoever reaches it effectively gains execution rights for every tool on your machine (including bash , write , edit ). So do not use --host 0.0.0.0 to expose it to the public internet or an open LAN. The 蒲公英 virtual LAN plus a one-time access token is the safe remote path intended for regular users."},{"id":"prerequisites","heading":"Prerequisites","body":"You can already launch the AtomCode webui on this machine. 蒲公英 is installed on both this machine and your phone: https://pgy.oray.com . Both devices are signed into the same 蒲公英 account and joined to the same network ."},{"id":"steps","heading":"Steps","body":""},{"id":"1-connect-蒲公英-and-get-the-virtual-ip","heading":"1. Connect 蒲公英 and get the virtual IP","body":"Sign in and join the network in the 蒲公英 client on this machine, then note the virtual IP assigned to it (looks like 10.x.x.x ). On the phone, just sign into the same account and join the same network — no IP to remember."},{"id":"2-bind-the-webui-to-the-virtual-ip","heading":"2. Bind the webui to the virtual IP","body":"By default the webui binds loopback only, which your phone can't reach. In the AtomCode TUI, relaunch the webui with --host pointed at the 蒲公英 virtual IP: /webui --host 10.x.x.x Replace 10.x.x.x with the virtual IP you noted above. Once bound, the webui is reachable from any device on the same virtual LAN."},{"id":"3-scan-to-connect-from-the-remote-access-panel","heading":"3. Scan to connect from the Remote Access panel","body":"Open the Remote Access panel (the phone icon) in the top-right of the webui. AtomCode detects the 蒲公英 status and produces: a ready-to-open remote URL (already carrying the access token); a matching QR code . Scan the QR with your phone, or copy the URL into the phone's browser. The phone must be signed into the same 蒲公英 account and on the same network. The access token is a password The remote URL carries a one-time access token ( ?token=… ) that is equivalent to a password : anyone who gets the full link can operate your machine. Don't post it in chats, screenshot it out, or paste it on a public page."},{"id":"troubleshooting","heading":"Troubleshooting","body":"The Remote Access panel shows different hints depending on what it detects. Map them as follows: Panel hint Meaning What to do 蒲公英 not detected 蒲公英 isn't installed, or the client isn't running. Install and sign into 蒲公英 on both machine and phone, join the same network, then hit \"Re-check\". No virtual IP yet 蒲公英 is installed but hasn't joined a network. Connect / join the network in the 蒲公英 client, get a virtual IP, then \"Re-check\". webui bound to localhost only 蒲公英 is detected, but the webui still listens on loopback. Relaunch with /webui --host <virtual IP> as in step 2, then refresh this page. Phone can't open it / hangs The two ends aren't on the same network, or a firewall blocks it. Confirm both devices share the same 蒲公英 account and network; check that the machine's firewall allows the webui port."},{"id":"next","heading":"Next","body":"Headless & Daemon — the daemon and HTTP/SSE API behind the webui FAQ — common remote / login gotchas © 2026 AtomCode · MIT 报告问题"}]},{"slug":"faq","title":"FAQ","group":"运维","lede":"A roundup of questions that keep coming up in user channels and issues. If yours isn't here, run /issue from inside AtomCode to file one, or open it on the AtomGit repository .","sections":[{"id":"faq","heading":"FAQ","body":"A roundup of questions that keep coming up in user channels and issues. If yours isn't here, run /issue from inside AtomCode to file one, or open it on the AtomGit repository ."},{"id":"install-launch","heading":"Install & launch","body":""},{"id":"the-install-script-fails-or-times-out","heading":"The install script fails or times out","body":"The one-click installer pulls the binary from GitCode releases by default. If the network blocks it: Download the archive for your platform manually from the releases page and drop atomcode onto your PATH ; or build from source: cargo install --path crates/atomcode (requires Rust 1.80+)."},{"id":"running-atomcode-says-command-not-found","heading":"Running atomcode says \"command not found\"","body":"The install directory isn't on your PATH . The default location is ~/.atomcode/bin — add it to your shell rc file: export PATH=\"$HOME/.atomcode/bin:$PATH\""},{"id":"macos-says-cannot-be-opened-because-the-developer-cannot-be-","heading":"macOS says \"cannot be opened because the developer cannot be verified\"","body":"Either click \"Open Anyway\" under System Settings → Privacy & Security, or run: xattr -d com.apple.quarantine $(which atomcode)"},{"id":"login-models","heading":"Login & models","body":""},{"id":"the-browser-doesnt-open-during-oauth-login","heading":"The browser doesn't open during OAuth login","body":"Check whether you're on a remote server without a desktop session. For remote environments, prefer API-key login (see Login Methods ), or finish OAuth locally and copy ~/.atomcode/auth.json to the same path on the server."},{"id":"cant-reach-the-model-hangs-forever-timeouts","heading":"Can't reach the model / hangs forever / timeouts","body":"First check that base_url in ~/.atomcode/config.toml is reachable — curl the matching /v1/models endpoint; On corporate networks it's usually a proxy issue — set HTTPS_PROXY and retry; If you're in mainland China hitting an overseas model, verify your egress network. You can run /model to switch to AtomGit's official channel first to prove the whole pipeline works."},{"id":"how-do-i-switch-models","heading":"How do I switch models?","body":"Inside a session, just type /model and pick from the menu. To persist the choice, edit the model field in ~/.atomcode/config.toml . See Configuration ."},{"id":"context-overflow-context-length-exceeded","heading":"Context overflow / \"context length exceeded\"","body":"Run /compact to have the model summarise the conversation so far and keep going; or /clear to wipe the current context and start over (history is kept as a session — you can /resume at any time); Avoid pasting a whole giant file into a prompt; let AtomCode use its file tools to read what it needs."},{"id":"permissions-safety","heading":"Permissions & safety","body":""},{"id":"confirming-every-command-gets-annoying","heading":"Confirming every command gets annoying","body":"That's the default safety policy. You can: Allow ad-hoc: pick \"Always allow this kind of action\" in the confirmation prompt; Allow via config: add commands to the [permissions] allowlist in config.toml ."},{"id":"where-does-atomcode-send-my-code","heading":"Where does AtomCode send my code?","body":"Only to the model endpoint you've configured in config.toml . Project files are read locally by tools and shipped as part of the prompt; AtomCode itself does not upload or telemeter code content."},{"id":"can-i-disable-specific-tools","heading":"Can I disable specific tools?","body":"Yes — under [tools] in config.toml , set disabled = [\"shell\", \"web_fetch\"] to block tools you don't want the model to use."},{"id":"usage-interaction","heading":"Usage & interaction","body":""},{"id":"how-do-i-point-it-at-a-specific-file","heading":"How do I point it at a specific file?","body":"Type @ in the input to trigger file completion, e.g. walk me through @src/main.rs entry logic . You can also just describe the path and the tool will call read_file on its own."},{"id":"how-do-i-enter-a-multiline-prompt","heading":"How do I enter a multiline prompt?","body":"Shift + Enter , Alt + Enter , or Ctrl + Enter insert a newline; Enter sends. Full reference at Keybindings ."},{"id":"how-do-i-roll-back-a-bad-edit","heading":"How do I roll back a bad edit?","body":"Run /undo to revert the file changes produced by the last tool turn. See Sessions & Undo ."},{"id":"can-i-resume-the-previous-session","heading":"Can I resume the previous session?","body":"Yes. Launch with --continue (or -c ) to pick up the last session, or run /resume from inside a new session and pick one from the history list."},{"id":"skills-project-instructions","heading":"Skills & project instructions","body":""},{"id":"my-skill-doesnt-show-up-in-the-menu","heading":"My skill doesn't show up in the menu","body":"Check the path: globally ~/.atomcode/skills/<name>/SKILL.md , per-project .atomcode/skills/<name>/SKILL.md ; Check the frontmatter: both name and description are required; Restart atomcode or run /reload to rescan."},{"id":"whats-the-difference-between-atomcodemd-and-a-skill","heading":"What's the difference between .atomcode.md and a skill?","body":"The former is an \"always on\" project-level convention; the latter is an explicitly invoked workflow. See Skills · Versus project instructions ."},{"id":"troubleshooting","heading":"Troubleshooting","body":"Logs first For any problem, step one is to look at ~/.atomcode/logs/ . Launching with --log-level debug prints far more detailed request/response logs."},{"id":"when-filing-an-issue-please-include","heading":"When filing an issue, please include","body":"The output of atomcode --version ; Your OS and architecture; Minimal repro steps for the error; Relevant logs (redact your API key)."},{"id":"next-steps","heading":"Next steps","body":"Back to overview Quickstart — install from scratch Configuration — every adjustable option © 2026 AtomCode · MIT 报告问题"}]}]