Back to onyxcode.app

Onyx Code Documentation

What is Onyx Code

Onyx Code is a privacy-first AI coding editor built on the VS Code foundation. It bundles a local inference engine (llama-server) plus a curated catalog of GGUF models, so chat and autocomplete work fully offline by default.

External servers (Ollama, LM Studio, OpenAI-compatible) are supported as an opt-in backend swap. Everything you would expect from VS Code is present (extensions, themes, keybindings, settings sync via import). The AI-specific surfaces sit alongside, scoped under the onyxcode.*settings namespace and an “Onyx” activity-bar item on the left rail with a chat sidebar on the right.

Pricing and licensing

Onyx Code is a one-time purchase. The Free tier covers local chat, inline autocomplete, local models, and the codebase index. Onyx Code Pro unlocks Plan and Auto agent modes, additional MCP servers, project memory, whole-codebase mode, and other Pro surfaces. The in-app activation flow uses a 16-character code emailed at purchase plus an emailed 6-digit verification code, runs on up to 3 devices per license, verifies offline against an embedded Ed25519 public key, and supports an offline-activation file for air-gapped machines. For the full activation, recovery, and device-management reference, see Licensing and activation.

Sibling product: Onyx Chat

onyxchat.appis a standalone Claude-Desktop-shaped local-AI chat app that reuses ~75-80% of Onyx Code's substrate. It is not part of Onyx Code; mentions of “Onyx Chat Pro” in the activation docs refer to that sibling product.

Quick start

Five minutes from download to your first AI reply. The onboarding wizard runs automatically on first launch.

  1. Install - download the signed installer from onyxcode.app. Open the app; the onboarding wizard runs automatically the first time.
  2. Pick a model - the wizard recommends models that fit your hardware. Confirm a download (or skip and add a .gguf from disk later).
  3. Open the chat - press Cmd+L (macOS) / Ctrl+L (Windows / Linux), or click the speech-bubble icon in the right sidebar.
  4. Ask a question - type in the chat input and press Enter. Reference files in your workspace with @ mentions.
  5. Apply changes - when the AI proposes code, the diff opens for review. Click Keep or Discard per file.
bash
# Reference a file in chat
@src/components/Header.tsx
"Refactor this to extract the search bar into its own component"

# Multiple file mentions per turn
@src/index.ts @src/utils/auth.ts
"Make these match the pattern in auth.ts"

Onboarding wizard

Auto-launched on first run; re-runnable any time via Command Palette → Onyx Code: Show Onboarding Wizard.

Steps

  1. Welcome - short intro and a hardware-detection summary (e.g. Apple Silicon, 36 GB unified memory).
  2. Download a Model - recommended-for-your-hardware picks plus an Add from File...path for offline imports. Includes the “How AI quality works” callout, per-card “Light model” badge on 3B-or-smaller picks, and the Codestral starter+background flow when a 5 GB+ model is picked.
  3. Import from VS Code - detects an existing VS Code install and offers to copy five categories with checkboxes: Settings, Keybindings, Snippets, Themes, and Extensions.
  4. Privacy summary - explains Air-Gap, Activity Log, Prompt Sanitizer, and .onyxnoai. Skipping is allowed; Air-Gap can be toggled later.
  5. You're All Set - the wizard closes; the chat sidebar opens.

Completion is tracked under onyxcode.onboarding.completed; clearing it triggers the wizard on next launch.

Licensing and activation

Onyx Code Pro is a one-time purchase. Activation runs locally: the desktop verifies a signed JWT against an embedded Ed25519 public key, then caches the license under your OS secret store. No background subscription, no recurring charges, no telemetry tied to the license.

Free vs Pro

The Free tier covers local chat, inline autocomplete, local GGUF models, and the codebase index for as long as you use the editor. Onyx Code Pro unlocks Plan and Auto agent modes, additional MCP servers beyond the bundled pack, project memory across sessions, whole-codebase (long-context) mode, and other Pro-only surfaces. A status-bar pill on the left shows the current tier (Onyx Free or PRO); click it to open the License Panel.

Activating Pro (online, code + email verification)

After purchase, you receive a 16-character activation code by email (Crockford alphabet, no ambiguous characters). Online activation also confirms you control the purchase inbox via a one-time email code, so a code shared without inbox access cannot unlock Pro online. To activate:

  1. Open the Command Palette (Cmd+Shift+P / Ctrl+Shift+P) and run Onyx: Activate Pro, or type /activate in chat, click Activate Pro in the License Panel, or use the Already Have Pro? step in the Welcome wizard on first run.
  2. Enter your 16-character code and the email you bought with, then click Send Verification Code. If they match your license, a 6-digit code is emailed to that address.
  3. Enter the 6-digit verification code and click Activate.
  4. The desktop POSTs the code, email, verification code, your hashed Machine ID, and the app version to the licensing server. On success, the server returns a signed JWT that this device caches in secret storage. The status bar flips to PRO.

Activation requires an internet connection. If you are permanently air-gapped, use Activate from Offline File instead (see below).

Activating offline (license file)

For machines that cannot reach the internet, mint a .onyxlicense file from any internet-connected device at onyxcode.app (direct buyers) or at codesnatch.io/onyx/offline-activation (codesnatch members), copy it to the air-gapped machine, then run Onyx: Activate from Offline File (also reachable as /activate-file in chat, or from the License Panel). The file is verified against the embedded public key with no network call. Offline files are valid for 365 days; mint a new one before expiry to renew.

Already activated on this device

Running Onyx: Activate Pro (or /activate) on a device that already holds an active Pro license does not present the input form. The desktop short-circuits to an Onyx Code Pro is already active on this device dialog showing your purchase email and three buttons:

  • View License opens the License Panel with full license details.
  • Manage Devices jumps to the device list for the current license.
  • Close dismisses the dialog.

The licensing service refuses to send a fresh activation request in this state as a second-layer guard, so a DevTools bypass of the dialog still cannot burn a duplicate activation or knock the device off its current binding. To activate with a different code, run Onyx: Deactivate This Device first.

Lost your activation code (recovery)

Run Onyx: Resend Activation Code by Email (or click Lost your code? in the License Panel). Enter the email address you used at purchase. The server checks for an active license under that email and, if one exists, re-mails the 16-character code.

The recovery endpoint is designed not to leak which addresses have purchased Onyx Code Pro. Several defenses run in layers:

  • Identical response shape. Whether or not the email matches, the server returns the same status code, body, and headers. The desktop toast is the same in both cases (Request received. If this email has an active Onyx Code Pro license, the activation code will arrive in your inbox shortly.).
  • Constant-time floor. Every response is padded to at least 350 ms so a missing license cannot complete faster than a successful send and reveal itself by timing.
  • Three rate-limit keys. 3 requests per 24 hours per email address, 10 per hour per IP, and 5 per 24 hours per machine. The tightest one binds; the 429 response never says which key tripped.
  • Origin check. The endpoint requires an X-Onyx-Client: desktop/<version> header that every production build sends. Casual scrapers without this header fail closed with the same generic response.
  • Client-side cooldown. The desktop adds a 60-second cooldown after each request, persisted across app restarts. Accidental double-clicks (or a slow-network retry) cannot fire repeat requests within that window.

Managing devices

One Onyx Code Pro license runs on up to 3 devices at a time. Run Onyx: Manage Devices (or /manage-devices in chat) to see the devices bound to your license. Each row shows the device label (OS hostname when available), platform, app version, and last-seen date.

To free a slot on a device other than the one you are currently using, click the Remove button next to it. The server sends a confirmation link to your purchase email; opening that link on the current device within 15 minutes removes the target device. The link is single-use and bound to the requesting machine, so it cannot be replayed from somewhere else.

To remove the device you are currently on, run Onyx: Deactivate This Device instead. The server rejects requests to remove the calling device via Manage Devices with a dedicated error, so the local-deactivate path is the only way to free your own slot.

Refreshing the license

Online licenses are cached as 30-day JWTs. A background scheduler ticks every 6 hours and refreshes the token once it enters its last week of validity, so the cache renews on its own as long as you are online. To force a refresh (after a network switch, after toggling Air-Gap off, or just to verify your license is still good), run Onyx: Refresh License Now or click Refresh Now in the License Panel.

Offline-file licenses (365 days) are self-contained and do not refresh. The Refresh Now button is hidden when the current license is an offline file. When the 365-day window is within 30 days of expiry the desktop shows a soft notification with a one-click link to onyxcode.app/offline-activation where you can mint a fresh file; if the window closes before you renew, the desktop drops to Free and shows a recovery notification with the same link.

Deactivating this device

Run Onyx: Deactivate This Device (or /deactivate) to clear the cached license locally and release the device slot on the server. The license itself is preserved; you can re-activate on this machine any time, or use the slot on a different machine. Deactivation requires an internet connection so the server-side release succeeds. If Air-Gap Mode is on, the command refuses and points you at Manage Devices from another machine.

The License Panel

Run Onyx: Open License Panel (or /license in chat, or click the status-bar tier badge) to open a unified license overview. Pro users see their purchase email, license source, and cache-expiry date plus buttons for Refresh Now, Manage Devices, Show Machine ID, and Deactivate. Free users see a short tier explainer plus Activate Pro, Activate from File, Lost your code?, and Show Machine ID.

Machine ID

The Machine ID is a SHA-256 one-way hash of a stable per-install identifier. The server sees only this hash, never the underlying identifier or any device-fingerprinting data. Run Onyx: Show This Device's ID to display it; you only need it for offline activation (paste it into the offline-activation form to mint a file bound to this machine) or for support tickets.

Chat

The chat panel is Onyx's main AI surface. It lives in the right auxiliary bar and supports streaming markdown rendering, file mentions, attachments, sessions, slash commands, smart apply, and per-message quick actions.

Chat panel

  • Where:right auxiliary bar, “Chat” view in the “Onyx Code” container.
  • Open / close: Cmd+L (primary) or Cmd+I (secondary).
  • Setting: onyxcode.chat.enabled - hide the panel without uninstalling.

Chat-input toolbar

A single row of square icon buttons sits below the textarea:

ButtonWhat it does
Air-Gap shieldBrand-green when on; click opens Privacy settings.
.onyxrulesBrand-green when a rules file is loaded; click opens it, or scaffolds .onyxrules from a template if none exists.
.onyxnoaiBrand-green when .onyxnoai is loaded or the workspace AI kill switch is on.
Agent-mode pillPlan / Ask / Edit-auto / Auto. Opens upward-anchored picker.
Apply-mode wandAuto / Manual apply.
WorktreeRun-in-worktree toggle (see Agent mode).
Model selectorActive chat-model picker.
Token counterPill showing used tokens vs the active model's context window.
Send / StopClaude-style dimmed-primary at rest; swaps to Stop while streaming.

File mentions (@path)

Type @in the chat input to start an autocomplete dropdown that lists files in the workspace. Picking one attaches that file's content to the next message. Multiple mentions allowed per turn.

text
Explain @src/components/Header.tsx and propose a refactor

Refactor @src/index.ts to match the patterns in @src/utils/auth.ts

Sessions and history

Every chat is auto-saved on each turn. The last active session is automatically reopened on app launch, so resuming work after a quit lands you exactly where you left off. Older sessions are pruned past a hard cap. Use /new to start a fresh session and save the current to history.

Auto-summarize on context fill

When the assembled prompt crosses ~70% of the active model's context window, the oldest half of the conversation is replaced with a short model-generated summary. Toggle with onyxcode.chat.autoSummarize (default on). Use /summarize to compress earlier turns immediately.

Whole-codebase mode (long-context)

For workspaces small enough to fit your model's context window, Onyx can send the entire repo to the AI as ambient context, bypassing semantic search. Toggle onyxcode.chat.wholeCodebaseMode (default off, per-workspace). Honors .gitignore plus a workspace-local .onyxignore.

Ambient git-diff context

When the workspace is a git repository, Onyx auto-injects a compact summary of your uncommitted changes into the system prompt. Use /diff to inspect. Settings: onyxcode.chat.gitDiffMode (default auto) and onyxcode.chat.gitDiffMaxBytes (default 4 KB).

Chat export

Use /export to save the current conversation to a .md (Markdown, human-readable) or .json (full session, round-trip safe) file via a save dialog.

Inline autocomplete

As-you-type FIM (fill-in-the-middle) suggestions in the editor, rendered as ghost text. Tab accepts; Esc dismisses.

Capabilities

  • Multi-line completions (default on).
  • Cross-file context - function signatures and imports from open tabs feed the prompt.
  • Smart trigger - suppresses suggestions while you are deleting, inside strings/comments, or just after dismissing one.
  • Predictive edits - heuristic, no AI call. After you change a value-like token, Onyx scans the same file for structurally similar lines and suggests the same change as ghost text.

Speculative decoding

A small “draft” model speculates several tokens ahead, which the main model verifies in a single batched step. Cuts FIM latency by 30-50% on Apple Silicon and CUDA when the draft architecture matches.

Settings

settings.json
{
  "onyxcode.autocomplete.enabled": true,
  "onyxcode.autocomplete.multiLine": true,
  "onyxcode.autocomplete.crossFileContext": true,
  "onyxcode.autocomplete.smartTrigger": true,
  "onyxcode.autocomplete.predictiveEdits": true,
  "onyxcode.autocomplete.debounceMs": 400,
  "onyxcode.autocomplete.maxTokens": 128,
  "onyxcode.autocomplete.temperature": 0.1,
  "onyxcode.ai.fimTemplate": "auto",
  "onyxcode.ai.speculativeDecoding.enabled": true,
  "onyxcode.ai.draftMax": 8
}

Onyx Tab - next-edit prediction (Zeta)

A third autocomplete provider, branded Onyx Tab. Powered by Zed Industries' open-source Zeta-2 model (Apache 2.0, GGUF, runs on the bundled llama-server unchanged). Free tier. After a substantive edit, Onyx reads the last 20 edits in a ring buffer and fires a local inference request to a dedicated llama-server process on port 12347. If the model returns a meaningfully different rewrite of your cursor's line, it appears as inline ghost text.

Cursor-jump: when you rename an identifier and Tab-accept the Zeta prediction, the cursor automatically jumps to the next occurrence of the old identifier in the file. A subtle → Tab hint appears at each pending site. Tab again accepts and jumps to the next.

ProviderWhen it firesWhat it predicts
FIMAs you typeCode that fills the gap at the cursor.
Predictive EditsAfter you change a value-like tokenSame change on structurally similar lines. No model call.
Next-edit predictionAfter any substantive editRewrite of the cursor's line based on recent edit history. ML-trained, local Zeta-2.

Right-click “Generate Tests for Selection”

Editor context menu, or Command Palette → Onyx: Generate Tests for Selection. Sends the selected code to chat with a pre-filled prompt asking for tests. The test file is pre-declared as the response target so Smart Apply lands the proposed test file in the right path automatically.

Models

Onyx ships a bundled llama-server and supports any GGUF model on disk plus external OpenAI-compatible servers.

AI Settings panel

Open from the left activity bar (Onyx icon → Models view) or via Command Palette → Onyx: Browse Models / Onyx: Open Embeddings. Three tabs: Models, Browse Models, Embeddings.

Models tab

Downloaded models from ~/.onyxcode/models/. Each card shows file size, parameter count, and download date. The list is split into Chat models and the Onyx Tab (Inline Edit Prediction) section. Activating a card switches the chat backend; the active model gets a brand-green Active badge.

Browse Models tab

A curated featured catalog plus HuggingFace search. Models are tagged Recommended for your hardware based on detected RAM and GPU. Search results can be sorted by Popular, Name, VRAM (largest model first), or Context(largest context window first). The expandable “Which model version should I pick?” callout explains Q4 / Q5 / Q8. Models with 3B parameters or fewer get a yellow Light model badge.

Model A/B comparison (Pro)

Run one prompt against several models side by side to see which one is best for your work, before committing to it. In chat, type /compare followed by your prompt, then pick 2 to 5 installed models (the picker remembers your last set). Running /compare with no prompt shows a Choose Models button to pick the set ahead of time. Onyx assembles the context once and feeds every model the same prompt, so the only variable is the model.

Locally, models run one at a time (only one model is resident in memory at once), so a comparison loads each model in turn. Each model is confirmed fully loaded before it answers, so swapping between local models is reliable. This means it works on any machine that can run a single model, with no extra setup; the trade-off is that each added model adds a load, so a run takes longer than a normal chat. Your currently active model runs first to save a reload, and your active chat model is restored when the comparison finishes.

While a model works, its panel shows a live status (loading, generating) instead of the raw answer. When it finishes it shows Completed with a metrics line (approximate tokens, wall-clock seconds, and tokens per second), labelled Model A, Model B, and so on with the real model name beside it. Each result is collapsed by default; expand the ones you want to read and compare. Per result you can Keep This Answer (drops it into the chat so you can apply its code) or Make Active Model (switches your normal chat backend to it). A Change Models button below the comparison re-opens the picker and re-runs the same prompt with a different set.

text
/compare write a debounce hook in TypeScript

Embeddings tab

The active embedding model decides which files RAG retrieves on every chat turn. The bundled default is Jina v2 Base Code, a code-tuned embedder that runs on any machine (4 GB+ RAM). The curated featured list lets you swap it: Nomic Embed Text v1.5 for general text, or Nomic Embed Code for maximum retrieval quality on capable hardware. Nomic Embed Code needs 16 GB+ RAM(a ~4.4 GB model that builds a larger, slower index), so it is hidden on machines that can’t run it and offered as an opt-in upgrade where they can.

External backend (Ollama / LM Studio / OpenAI-compatible)

AI Settings → Models tab → Connect to External Server. Point Onyx at any OpenAI-compatible endpoint (http://localhost:11434 for Ollama, http://localhost:1234 for LM Studio). Onyx never silently polls the external endpoint at startup; the probe runs only when you open the section or click Connect.

settings.json
{
  // Bundled engine ports (defaults)
  "onyxcode.ai.port": 12345,
  "onyxcode.ai.embeddingPort": 12346,

  // Models directory
  "onyxcode.ai.modelsPath": "~/.onyxcode/models/",

  // GPU offload (number of layers, or "auto")
  "onyxcode.ai.gpuLayers": "auto"
}

Codestral first-load UX

When the wizard recommends the ~14 GB Codestral model, Onyx installs a ~1 GB starter (Qwen 2.5 Coder 1.5B) in the foreground so chat works in ~2 minutes; the big model streams to disk in the background. A status-bar pill shows progress. When the big model finishes, a notification offers Switch / Keep current.

Bundled inference engine

Onyx bundles the llama.cpp llama-server binary. Two processes run: chat (default port 12345) and embedding (default port 12346). Flash-attention 2 forced on, KV cache prefix reuse enabled.

Codebase indexing and RAG

Onyx indexes your workspace into a local vector store so the AI can retrieve the most relevant code blocks per chat turn without you mentioning them.

Index lifecycle

  • Background indexing runs on workspace open if onyxcode.index.enabled is on.
  • Watch mode keeps the index incrementally updated as files change.
  • Persisted snapshot survives restarts; /reindex rebuilds from scratch, /reindex-clear wipes both the in-memory index and the on-disk snapshot.

How retrieval works

On every chat turn, Onyx embeds the user message, runs cosine similarity against the vector store, and injects the top-5 most relevant code blocks into the system prompt. The /workspace <query> slash command widens that to top-15 for harder questions.

Workspace primer

A compact snapshot of the workspace (top-level layout, README excerpt, manifest summary) is auto-generated on first chat in a workspace and injected into every system prompt. Run /primer to inspect or refresh it.

Settings

settings.json
{
  "onyxcode.index.enabled": true,
  "onyxcode.index.maxFileSizeKB": 512,
  "onyxcode.index.maxTotalFiles": 5000,
  "onyxcode.index.concurrency": 4,
  "onyxcode.index.persistEnabled": true,
  "onyxcode.index.watchEnabled": true,
  "onyxcode.index.excludeGlobs": {},
  "onyxcode.ai.rag.enabled": true,
  "onyxcode.ai.rag.excludePatterns": [
    "node_modules", ".git", "dist", "build"
  ]
}

Project configuration files

Onyx reads a small set of files at the workspace root that customize how the AI behaves on this project. Run /init once to scaffold all of them with starter templates.

ONYX.md - project overview

Human-readable overview of the project (what it is, key folders, conventions, how to run). Injected into every chat system prompt so the AI starts each turn with project context.

ONYX.md
# acme-dashboard

Next.js 14 + Prisma + Postgres dashboard for internal ops.

## Layout
- `app/` - App-router routes; server components by default.
- `lib/db.ts` - Prisma client singleton.
- `scripts/` - One-off migrations and admin helpers.

## Conventions
- TypeScript strict; no `any`.
- Server actions over client-side fetch.
- Tailwind utilities; one shared `Button` in `components/ui/`.

## How to run
- `pnpm dev` - local dev server on :3000.
- `pnpm test` - Vitest, integration tests hit a local Postgres.

.onyxrules - project rules

Plain-text rules loaded into every chat (naming conventions, framework choices, what to avoid, testing commands). 16 KB max. If Onyx finds a .cursorrules instead, it loads that file unchanged so existing Cursor users get zero-friction parity.

.onyxrules
# Stack
- TypeScript strict mode, React 19, Tailwind v4.
- Server actions only; no client-side fetch.

# Style
- Match my tab indentation.
- Don't add JSDoc unless I ask.

# Don't
- Edit anything under dist/ or .next/.
- Suggest npm install for packages already in package.json.

.onyxnoai - privacy excludes

Gitignore-syntax patterns the AI should never see (chat, autocomplete, RAG indexing). Built-in defaults already cover common secrets (**/.env, **/secrets/**, **/*.pem, **/.aws/**, **/.ssh/**, **/id_rsa*). Use !pattern to negate.

.onyxnoai
# Project-specific privacy excludes (gitignore syntax).
# Built-in defaults already cover .env, secrets/**, *.pem, .aws/**, .ssh/**.

# Whole directories
infra/private/**
ops/runbooks/**

# Specific files
docs/internal-launch-checklist.md

# Negate the default so a sample env file *is* visible to the AI
!**/.env.example

.onyxignore - whole-codebase mode excludes

Gitignore-syntax patterns to exclude from the onyxcode.chat.wholeCodebaseMode snapshot only. Distinct from .onyxnoai (which hides files from the AI entirely). Use this to keep large generated files, fixtures, or vendored code out of the whole-repo prompt.

.onyxignore
# Drop generated + vendored content from whole-codebase mode prompts.
**/*.generated.ts
**/__generated__/**
docs/**/*.md
fixtures/large-corpus/**

# But re-include the architecture overview if it lives under a
# .gitignore'd folder.
!docs/internal/architecture.md

.onyx/instructions.md - extended instructions

Long-form structured instructions (standing rules, things to avoid, testing strategy). Injected into every system prompt. Probe order: configured instructionsFile .onyxrulesONYX.md.cursorrules .onyx/instructions.md. First match wins. 4 KB cap by default.

/init - scaffold all four files

Running /init from chat scaffolds the four files above in one pass. Existing files are left untouched. Onyx asks Use AI to Generate, Use Template, or Cancel. Quick (template) is the trailing-edge primary on macOS so the default Enter key gets a deterministic outcome.

Agent mode

The agent mode picker chooses how much autonomy the AI has. The chat-input pill (next to the model selector) shows the current mode; the slash commands /plan, /ask, /edit, /auto switch it.

Modes

  • Plan - AI proposes changes, drafts code, and lists actions, but never edits files or runs commands. Read-only by design.
  • Ask before edits (default) - AI confirms each file write, shell command, and mutating tool call before executing.
  • Edit automatically - AI auto-applies file edits but still confirms shell commands and mutating tool calls.
  • Auto - runs unattended. Available only inside a worktree; falls back to Ask outside one. The status bar shows a brand-prominent → Auto mode · <branch> pill while active so the unattended state is visible even when you switch files.

Permissions

Three layers, top to bottom (deny tiers always beat allow tiers, regardless of mode):

  1. .onyxnoai + built-in defaults (deny tier) - .env, secrets, private keys, plus user-listed patterns. The agent host vetoes matching reads even in Auto / Bypass-Approvals mode.
  2. File-based rules in .onyx/permissions.json (committable, fine-grained per command / path / tool) - the recommended layer for everything else.
  3. Settings-based onyxcode.agent.alwaysAllow.* (legacy, all-or-nothing per tool kind, kept for migration parity).

A deny pattern always wins over every allow above it - including session-level Bypass Approvals - so a careless local override can never re-enable something the team explicitly denied.

.onyx/permissions.json - AI approval rules

Two files, both at the workspace root under .onyx/:

FileStatusPurpose
.onyx/permissions.jsoncommittedTeam-wide rules, reviewed in PRs.
.onyx/permissions.local.jsongitignored (auto-appended on first write)This machine's overrides - host-specific paths, your personal allowlist.

Both files share the shape below. It is intentionally aligned with Claude Code's .claude/settings.json so you can paste snippets verbatim:

.onyx/permissions.json
{
  "version": 1,
  "permissions": {
    "allow": [
      "Shell(git log:*)",
      "Shell(npm test)",
      "Shell(npm run build:*)",
      "Read(./src/**)",
      "MCP(filesystem:listDirectory)",
      "MCP(github:*)"
    ],
    "deny": [
      "Shell(rm:*)",
      "Shell(curl:*)",
      "Shell(git push:--force*)",
      "Read(./.env*)",
      "Write(./.env*)",
      "Write(./node_modules/**)"
    ]
  }
}

Pattern grammar

  • Shell(<command>) - exact command-line match.
  • Shell(<prefix>:*) - word-boundary prefix match. Shell(git log:*) matches git log, git log -3, git log --oneline -10; does not match git logger.
  • Read(<glob>) / Write(<glob>) - workspace-relative glob (** and * supported). Leading ./ is stripped.
  • MCP(<server>:<tool>) - exact MCP tool match; MCP(<server>:*) matches every tool on a server.
  • Bash(...) is accepted as an alias for Shell(...) so Claude Code snippets paste cleanly. The parser normalizes to the canonical Shell(...) form on first edit.

Precedence (highest to lowest)

  1. .onyxnoai patterns + built-in .env / private-key defaults (read tier only; reads matching these are denied even in Auto / Bypass-Approvals).
  2. deny patterns in .onyx/permissions.local.json.
  3. deny patterns in .onyx/permissions.json.
  4. Session Bypass Approvals / Autopilot (still beaten by any deny above).
  5. allow patterns in .onyx/permissions.local.json.
  6. allow patterns in .onyx/permissions.json.
  7. Built-in heuristics (working-directory read auto-approve, shell allowlist, protected-glob write checks).
  8. Fallback: prompt the user with the confirmation card.

Recommended starter content

Seed your .onyx/permissions.json with at least these deny entries to protect secrets and the dependency tree:

.onyx/permissions.json
{
  "version": 1,
  "permissions": {
    "deny": [
      "Read(./.env*)",
      "Write(./.env*)",
      "Read(./.git/config)",
      "Write(./node_modules/**)"
    ]
  }
}
Belt-and-suspenders. Use .onyx/permissions.json deny patterns for explicit, committed AI read denials AND list the same paths in .onyxnoai to also hide them from the embedding indexer, FIM, and RAG context assembly. Since 2026-05-15 .onyxnoai also gates direct AI reads at the deny tier, beating Auto mode and Bypass-Approvals, so the two systems cover overlapping but complementary surface area.

Quick open and editing

Type /permissions in the chat panel to open the file (creates it from a starter deny list - recursive remove, force push, curl, .env, and node_modules/ writes - if it is missing). Any text editor works; the file is plain JSON and ships with a registered JSON schema, so editing it inside Onyx Code gives inline validation, autocomplete on the pattern strings, and hover-help with the grammar reference.

Carousel scope picker

When a confirmation card appears in the chat input carousel, the Always Allow submenu offers four file-based actions for both shell and MCP tools:

  • Always allow this command (project) - writes Shell(<cmd>) or MCP(<server>:<tool>) to .onyx/permissions.json.
  • Always allow this prefix (project) / Always allow all server tools (project) - writes the wildcard form.
  • The same two with (on this machine) - writes to .onyx/permissions.local.json instead.

Each click is one file write, debounced 250 ms to coalesce rapid clicks. The rule survives across windows, sessions, and (for project scope) across teammates via git.

Try it yourself

bash
# 1. In a workspace, create .onyx/permissions.json:
{ "version": 1, "permissions": { "allow": ["Shell(echo hello:*)"], "deny": ["Shell(rm:*)"] } }

# 2. Open the chat panel in "Ask before edits" mode.
# 3. Ask the AI to run `echo hello world` -> tool runs silently, no card.
# 4. Ask the AI to run `rm -rf /tmp/some-file` -> denied; the file is untouched.
# 5. Ask the AI to run `curl example.com` -> confirmation card (file unknown).

Migration from legacy approvals

The first time a post-2026-05-15 build runs in a workspace that had old chat/autoconfirm approvals, three sources are silently migrated into .onyx/permissions.local.json:

Legacy sourceMigrated pattern
Workspace chat/autoconfirm for run_in_terminalShell(*) (broad, mirrors what the storage key actually granted)
chat/autoconfirm-combination entries with argsNarrow Shell(<command>) per entry
chat/servers/autoconfirm MCP server allowlistsMCP(<defId>:*) per server

Settings-based fallback (legacy)

For migration parity, the all-or-nothing settings still work and live alongside the file- based system:

settings.json
{
  "onyxcode.agent.mode": "ask",                  // plan / ask / editAuto / auto
  "onyxcode.agent.alwaysAllow.fileRead": true,
  "onyxcode.agent.alwaysAllow.fileWrite": false,
  "onyxcode.agent.alwaysAllow.shellExec": false,

  // Bypass confirmation for specific MCP tools
  "onyxcode.agent.alwaysAllow.mcp": [
    "filesystem:listDirectory",
    "git:status"
  ]
}

Worktree-sandboxed agents

When the user picks Run in worktree from the chat toolbar, Onyx creates an isolated git worktree. The agent runs inside the worktree with Auto-mode permissions, so file writes and shell commands can run without prompting, without affecting the main branch.

  • Apply menu: Apply / Discard / Keep choices route through the worktree back to the main tree.
  • Resume on launch: worktrees that survived a hard quit prompt with [Keep] / [Discard All] on next launch.
  • Stuck-state recovery: if a previous run crashed and left an on-disk .onyx-agents/<sessionId>/ directory that git no longer tracks, the next Run in worktree click cleans up automatically.
  • .gitignore auto-suggestion: after the first worktree creation in a repo, Onyx offers to add .onyx-agents/ to .gitignore.
  • Prerequisites: workspace must be a git repository.

MCP support

Model Context Protocol (MCP) servers are subprocesses that expose tools (filesystem, git, search, custom integrations) the agent can call. Onyx ships a curated bundle and supports custom servers.

/mcp slash command

bash
/mcp                        # List every configured server with status badges
/mcp restart filesystem     # Restart a server by id
/mcp stop git               # Stop one
/mcp logs sqlite            # Print recent stdout/stderr
/mcp add                    # Interactive add flow

Bundled MCP server pack

Four ready-to-use stdio presets, each one click to install from the /mcp panel's Bundled Servers subsection:

  • filesystem - read / list files within the workspace. Backed by npx @modelcontextprotocol/server-filesystem.
  • git - git status, git log, git diff, git show. Backed by uvx mcp-server-git.
  • sqlite - query a local SQLite database from the agent. Backed by uvx mcp-server-sqlite.
  • fetch - GET arbitrary HTTP(S) URLs. When Air-Gap Mode is on, the Install button is replaced by a red Blocked by Air-Gap pill.

Air-Gap interaction

Active enforcement. Adding an HTTP-transport MCP server while Air-Gap Mode is on is actively blocked: the MCP server is stopped the moment it tries to start, and a one-time-per-server warning toast fires. Stdio-transport servers are always allowed (local processes, no network). HTTP MCPs pointing at localhost / 127.0.0.1 / ::1 / unix: / pipe: are also allowed under Air-Gap.

OAuth-protected MCP servers

Onyx Code defers to VS Code's native OAuth handshake. The MCP server responds 401 with a WWW-Authenticateheader, Onyx discovers the authorization server via RFC 8414 metadata, performs dynamic client registration if needed, opens your system browser at the provider's /authorizepage, captures the auth code via a localhost redirect, exchanges it for a token, and stores the token via VS Code's auth provider.

Project memory

Long-term context the agent maintains across chat sessions. Memory files live under the user profile (not the workspace) so they survive git clean.

/memory slash command

bash
/memory                        # Print MEMORY.md index + every memory file in this workspace
/memory show user_role.md      # Print one memory file
/memory delete feedback.md     # Remove one

readMemory and writeMemory agent tools

The agent calls these directly when running. writeMemory(filename, type, body) persists a YAML-frontmatter Markdown file with id, type, created_at, updated_at. readMemory(filename) returns the contents. Visible in the activity log (kind agent_tool) but not in the chat surface.

Use cases

  • Remember the user's role / preferences across chats.
  • Track architecture decisions the user explained once.
  • Carry forward known issues or workarounds.

Smart Apply and proposed changes

When the AI returns code that targets a file, Onyx stages it as a pending change instead of writing to disk. Cursor-style: nothing on the filesystem moves until the user explicitly accepts.

Apply modes

  • Auto (default) - diff editor opens for review with inline Keep / Discard buttons per file.
  • Manual - code blocks render with copy / apply buttons; you trigger each apply individually.

Switch via onyxcode.chat.applyMode.

Partial-edit merging and reindent

When the AI returns a code block that clearly targets only part of a file (e.g. one function rewritten with a leading // ... existing code ... marker), Smart Apply merges it into the file in place rather than replacing the whole document. The merged result is reindented to match the surrounding indentation style.

Keyboard shortcuts and status glyphs

  • Cmd+Shift+Enter / Ctrl+Shift+Enter keeps every pending change.
  • Cmd+Shift+Backspace / Ctrl+Shift+Backspace discards them all.
  • Each pending file in the panel renders a status glyph (added / modified / deleted / conflict).

Code-block path annotations

When the AI emits a fenced code block like the example below (language + colon + relative path), Onyx routes the block to that file directly, skipping the language-match fallback.

markdown
```typescript:src/foo.ts
export function foo() {}
```

Quality guardrails

A set of automatic defenses that catch common small-model failure modes before they reach the user or the filesystem. All run on every chat reply; none require setup.

Repetition / loop guard

Small (1.5B-3B) coder models occasionally spiral into infinite repetition. Onyx runs a mid-stream loop check (after the buffer crosses ~1 KB, every ~512 chars thereafter) and a post-stream within-line list check. When a loop fires, the stream aborts and the pre-loop content is salvaged.

Surface:a yellow chip below the message (“Reply trimmed because the model started repeating itself”) with a primary Switch to a 7B+ model action that opens the Browse Models tab, plus a secondary Show what was trimmed toggle.

Repetition penalty

Every chat completion sends repeat_penalty to the inference engine. Default 1.1 is almost imperceptible on capable models but reliably stops small models from looping. Tunable via onyxcode.chat.repeatPenalty (1.0-1.5).

Destructive-edit guard

Before Smart Apply auto-stages a proposed file replacement, two triggers can suppress auto-stage and prompt the user instead.

  • Shrink trigger- proposed content is under 30% of the original (catches the small-model “blanked the imports” case).
  • Large-rewrite trigger - actual line-diff (LCS-based) shows 100+ add+remove lines on a 50+-line file.

System-prompt hardening

The base chat system prompt carries explicit rules: when producing a code block intended to replace a file, output the FULL file content with only the requested changes; never delete imports, declarations, or unrelated code unless asked; do not repeat the same sentence, phrase, or list item.

Privacy and security

Onyx runs locally by default and exposes structured controls for users with stricter requirements.

Air-Gap mode

Blocks all outbound network traffic from Onyx Code. Model downloads, marketplace, auto-update, external server probes, MCP HTTP servers - all fail closed. Localhost stays available, so the bundled inference engine works.

  • Toggle: Command Palette → Onyx: Toggle Air-Gap Mode, or click the status-bar pill.
  • Status pill:“AIR-GAPPED” in brand green when on.
  • Setting: onyx.privacy.airGapMode (default off).

Three enforcement layers.

  1. In-app gatedFetch wraps every outbound call from Onyx code paths (HuggingFace browser, model downloads, local AI client, external context probe, embedding service, MCP gallery, auto-update). Calls throw AirGapBlockedError before the network stack is touched.
  2. Extension-host air-gap check runs inside every MCP HTTP and SSE transport (McpHTTPHandle._fetchInternal, both the common ext-host path and the desktop Node runtime path). The air-gap callback is a required constructor parameter on McpHTTPHandle, so any future MCP transport subclass that forgets to wire it up is a compile-time TypeScript error - not a silent privacy leak.
  3. Electron session.webRequest.onBeforeRequest aborts any non-loopback HTTP/HTTPS/WS/WSS request that slips past the first two layers and logs it to main.log as [Air-Gap] Blocked outbound request: .... Note: 0.0.0.0 is nottreated as loopback (it's a wildcard bind address that routes to LAN interfaces on Linux/macOS), so SSRF attempts via crafted MCP URLs to http://0.0.0.0:<port>/ are correctly blocked.

Verify Air-Gap (try this yourself)

bash
# 1. Toggle Air-Gap on; confirm the green AIR-GAPPED pill at bottom-left.
# 2. Open AI Settings -> Models -> Browse Models and search anything.
#    Expect "Search failed. Check your internet connection."
# 3. Confirm main.log recorded the block:
tail -20 ~/Library/Application\ Support/code-oss-dev/logs/*/main.log | grep "Air-Gap"

# 4. lsof socket check - proves no outbound socket was opened:
PIDS=$(pgrep -f "Onyx Code.app/Contents" | paste -sd, -)
lsof -nP -iTCP -a -p "$PIDS" -sTCP:ESTABLISHED | grep -v "127\.0\.0\.1\|::1\|localhost"

Workspace AI kill switch

Disables every AI surface (chat, autocomplete, RAG, agent tools) for one workspace. Useful when you open a regulated codebase and don't want anything calling out to a model. Toggle: Command Palette → Onyx: Toggle Workspace AI, or status bar pill. Status pill: AI: off or, when partial via .onyxnoai, AI: limited.

Prompt sanitizer

Every chat send and attached file is scanned locally for secret patterns (AWS keys, GitHub PATs, OpenAI keys, Slack tokens, JWTs, PEM private keys, certificates, env-style secrets, plus a high-entropy fallback). On detection, a non-blocking dialog offers Redact and Send / Send anyway / Cancel. Redacted spans are replaced with <REDACTED:patternId> markers before the prompt leaves the renderer.

settings.json
{
  "onyxcode.privacy.promptSanitizer.patterns": {
    "aws-access-key-id": false       // I never paste these; reduce noise
  },
  "onyxcode.privacy.promptSanitizer.customPatterns": [
    {
      "id": "internal-employee-id",
      "regex": "EMP-[0-9]{6}",
      "description": "Internal employee identifier"
    }
  ],
  "onyxcode.privacy.promptSanitizer.entropyThreshold": 4.7
}

What gets sent (after Redact and Send):

text
The token is <REDACTED:github-pat>. Why does the OAuth flow fail?

Activity log and audit PDF

Every AI interaction (chat / autocomplete / model download / MCP tool call / agent file edit) appends one line to a local JSONL audit log. The schema is metadata only - no prompt text, no completion text, no file contents.

  • Storage: ~/.onyxcode/activity-log/<YYYY-MM>.jsonl (monthly rotation).
  • Settings: onyx.privacy.activityLog.enabled (default on), onyx.privacy.activityLog.retentionDays (default 365).
  • Commands: Onyx: Show AI Activity Log, Onyx: Export AI Activity Audit (PDF).
2026-05.jsonl (one event per line)
{"kind":"chat","ts":"2026-05-09T14:32:11.482Z","workspace":"acme-dashboard","model":"qwen2.5-coder-7b-instruct-q5_k_m","tokens_in":1842,"tokens_out":612,"latency_ms":4318,"net":false}

No prompt, response, content, text, body, message, or completion field ever appears, by _sanitise() construction. The audit PDF is rendered offscreen with nodeIntegration:false and inline-only CSS, so it generates correctly under Air-Gap.

Event kinds: chat, fim, embed, download, license_refresh, agent_tool (built-in agent tools), mcp_call (MCP server tool calls), redaction, chat_loop_trim, chat_destructive_guard, next_edit_pred. MCP tool invocations are logged separately as mcp_call so operators can filter activity by MCP server usage independently of first-party tool use.

Binary integrity (SHA-256)

The bundled llama-server binary is SHA-256 verified at every spawn against a pinned .sha256 sidecar file. Hash mismatch refuses to spawn with a logged error. The binary path is resolved at build time, never via $PATH - preventing PATH-hijacking attacks. All three inference processes (chat 12345, embedding 12346, next-edit 12347) spawn with --host 127.0.0.1 and cannot accept LAN connections. spawn() calls pass args as arrays - no shell interpolation.

Children are SIGKILL-reaped on graceful Electron shutdown, on synchronous process.on('exit'), and via a constructor-side lsof + ps basename scan at startup. Non-Onyx processes on the same port are never touched (basename exact-match on 'llama-server').

No telemetry

Every upstream VS Code telemetry endpoint has been emptied at the product.json level. The telemetry toggles are still present in settings (for compatibility with upstream extensions that read them), but they have nowhere to send data even if turned on. The network-layer Air-Gap and the empty-endpoint stripping are independent defense layers - either alone guarantees no Onyx-authored telemetry leaves your machine.

Audit posture

Onyx maintains a canonical security checklist (~60 numbered items across 12 sections: network egress, process spawning, file system, IPC/Electron, injection, config security, privacy, MCP trust, supply chain, DoS, error disclosure, Air-Gap integrity). An automated audit skill walks the entire checklist and records a finding (pass / warn / fail + file:line evidence) for every item. The checklist and findings live in the repo and are open for review.

Workflow helpers

Small AI-powered actions that sit alongside the editor's source-control and PR flows.

Draft commit message from staged changes

Command Palette → Onyx: Draft Commit Message from Staged Changes. Reads git diff --cached, sends to the active model, drafts a commit message, and inserts it into the source-control input box (or copies to clipboard if no SCM provider is registered).

conventional format (default - type(scope): subject):

text
feat(chat): persist loop-trim original on the message

Previously the loop-guard chip lost its "show what was trimmed" content
on session reload. Snapshot the pre-trim model output (capped at 4 KB)
on a new loopTrimmedOriginal field so the toggle survives.

Drafted with Onyx Code

freeform format (no type/scope, no enforced subject prefix):

text
Persist the loop-trim original on the message so the chip's "Show what
was trimmed" toggle survives a session reload.

Drafted with Onyx Code

The Drafted with Onyx Code trailer is gated by onyxcode.git.appendSignature; the drafter skips re-appending if the model already wrote one.

Draft PR description from this branch

Command Palette → Onyx: Draft PR Description from This Branch. Computes git diff base..HEAD against the configured base (typically main), sends to the model, drafts a PR description with Summary + Test Plan sections, and copies to clipboard. Rejects model output that's missing the structured sections (catches small-model failures) with a “try a stronger model” hint.

Status bar indicators

All in the bottom status bar; clicks open the relevant settings or panel.

PillWhenClick
AIR-GAPPEDonyx.privacy.airGapMode is on.Opens Privacy settings.
AI: off / AI: limitedWorkspace AI kill switch on, or .onyxnoai patterns active.Opens Privacy settings.
Index statusonyxcode.index.enabled is on.States: scanning, indexing N%, indexed N blocks, failed.
Model downloadAny model download in flight.Opens AI Settings → Browse Models with the active download highlighted.
AI statusAlways when AI service is enabled.Model name + health dot (green / amber / red).
→ Auto mode · <branch>Agent mode is set to Auto AND at least one chat session has an active worktree.Persistent visual signal that the AI is running unattended. Lists every active branch on hover when more than one session is in Auto. The pill disappears the moment you exit Auto or the worktree is removed.
→ Onyx TabAlways (or hidden if next-edit prediction is disabled).Opens Browse Models. Two states: ready (Zeta-2 installed) or (Get) (not installed).

Slash commands reference

Type / at the start of a chat input. The command list and their args:

CommandWhat it does
/helpShow every command in the chat.
/initScaffold ONYX.md, .onyxrules, .onyxnoai, and .onyx/instructions.md at the workspace root.
/onyxrulesOpen or create .onyxrules.
/onyxnoaiOpen or create .onyxnoai.
/permissionsOpen or create .onyx/permissions.json (committed AI approval rules). Creates from a starter deny list if missing.
/instructionsShow the project-specific instructions the AI receives.
/primerShow the workspace primer.
/newStart a new chat; save the current to history.
/clearReset the AI's view of the conversation; visible messages stay.
/summarizeCompress earlier turns into a model-generated summary now.
/attachmentsList every file attached to the current chat.
/file <path>Attach a file by path.
/search <query>Semantic search over the codebase index - no AI call.
/workspace <query>Same as a normal chat turn but with wider RAG (top-15 instead of top-5).
/diffPrint the current uncommitted git diff.
/exportExport the conversation to .md or .json.
/statsActive chat model, embedding model, index status - all in one view.
/contextLive context-window usage breakdown.
/modelShow the active chat model details.
/compare <prompt>Pro. Run the prompt across 2 to 5 models side by side (locally one model loads at a time), then keep the best answer or make a model active.
/embedding-modelShow the active embedding model + index status.
/tabShow Onyx Tab status (Zeta-2 install / running, paths, settings).
/reindexRebuild the codebase index from scratch.
/reindex-clearWipe the index and on-disk snapshot (no rebuild).
/planSwitch agent mode to Plan.
/askSwitch agent mode to Ask before edits.
/editSwitch agent mode to Edit automatically.
/autoSwitch agent mode to Auto (requires worktree).
/mcp [sub] [id]Manage MCP servers; subcommands: list, start, stop, restart, logs, add.
/memory [sub] [name]Show / read / delete project memory files.
/licenseOpen the License Panel: tier badge, license details, and one-click buttons for every license action.
/activateOpen the activation dialog for a 16-character code plus email verification. If Pro is already active on this device, short-circuits to an 'already activated' dialog with View License / Manage Devices / Close buttons instead of presenting the input form.
/activate-fileOpen the OS file picker to activate from a .onyxlicense file (offline activation, no network call).
/deactivateClear the cached license on this machine AND release its slot server-side. The license itself is preserved; you can re-activate any time, on this or another machine.
/manage-devicesList devices bound to your Pro license and request removal of one. Removal requires a 15-minute email-confirmation link opened on this device.

Command Palette reference

Press F1 (or Cmd+Shift+P / Ctrl+Shift+P). All Onyx commands sit under the Onyx category.

CommandWhat it does
Onyx: Toggle Onyx Code ChatShow / hide the chat panel.
Onyx: Browse ModelsOpen AI Settings - Browse Models tab.
Onyx: Open EmbeddingsOpen AI Settings - Embeddings tab.
Onyx: Toggle Air-Gap ModeBlock / unblock outbound network.
Onyx: Open Privacy SettingsJump to the Privacy settings group.
Onyx: Toggle Workspace AIDisable / enable AI surfaces in the active workspace.
Onyx: Show AI Activity LogRender the audit log as a Markdown table.
Onyx: Export AI Activity Audit (PDF)Generate a signed audit PDF.
Onyx: Draft Commit Message from Staged ChangesInsert a commit message into the SCM input.
Onyx: Draft PR Description from This BranchCopy a PR description to the clipboard.
Onyx: Generate Tests for SelectionSend the editor selection to chat with a tests prompt.
Onyx: Rebuild Codebase IndexForce a full reindex.
Onyx: Clear Codebase IndexWipe the index and the on-disk snapshot.
Onyx Code: Show Onboarding WizardRe-run the first-run wizard.
Onyx: Import Settings from VS CodeRun the VS Code import flow outside the wizard.
Onyx: Activate ProOpen the centered modal dialog for a 16-character activation code plus email verification. If Pro is already active on this device, short-circuits to an 'already activated' dialog with View License / Manage Devices / Close buttons.
Onyx: Activate from Offline FileOpen the OS file picker for a .onyxlicense file. Verifies the embedded JWT against the bundled public key with no network call.
Onyx: Show This Device's IDOpen a dialog with the SHA-256 hash of the local install identifier and a Copy ID button. Needed for offline activation.
Onyx: Deactivate This DeviceClear the cached license on this machine AND release its slot server-side. The license itself is preserved.
Onyx: Refresh License NowForce-refresh the cached JWT against the licensing server. The background scheduler normally handles this in the token's last week.
Onyx: Resend Activation Code by EmailLost-your-code recovery. Constant-time response and a 60-second client cooldown; non-disclosing wording so the toast cannot be used to enumerate purchase emails.
Onyx: Manage DevicesList the devices bound to your Pro license and request removal of one (other than the current device). Removal requires a 15-minute confirmation link opened on this device.
Onyx: Open License PanelOpen the unified License panel: tier badge, license details for Pro users, machine ID, and one-click buttons for every license action above.

Keyboard shortcuts

Shortcut (macOS)Shortcut (Win/Linux)Action
Cmd+LCtrl+LToggle Onyx Code Chat (primary)
Cmd+ICtrl+IToggle Onyx Code Chat (secondary)
Cmd+Shift+EnterCtrl+Shift+EnterKeep All Proposed Changes
Cmd+Shift+BackspaceCtrl+Shift+BackspaceDiscard All Proposed Changes
TabTabAccept the current inline autocomplete suggestion
EscEscDismiss the current inline autocomplete suggestion

All standard VS Code shortcuts apply unchanged. Customize via Preferences → Keyboard Shortcuts.

Settings reference

Every setting lives under the unified Onyx Codeparent in the Settings Editor's left tree.

Privacy

KeyDefaultNotes
onyx.privacy.airGapModefalseBlock all outbound network.
onyx.privacy.workspaceAiDisabledfalseResource-scoped kill switch.
onyx.privacy.activityLog.enabledtrueMaster toggle for the audit log.
onyx.privacy.activityLog.retentionDays3651-3650.
onyxcode.privacy.promptSanitizer.enabledtruePre-send secret scan.
onyxcode.privacy.promptSanitizer.patterns{}Per-id overrides.
onyxcode.privacy.promptSanitizer.customPatterns[]User-defined regex patterns.
onyxcode.privacy.promptSanitizer.entropyThreshold4.5Shannon entropy threshold for the high-entropy fallback.
onyxcode.privacy.promptSanitizer.highEntropyFallbacktrueToggle the entropy fallback.

AI

KeyDefaultNotes
onyxcode.ai.modelsPath~/.onyxcode/models/Where downloaded GGUF files live.
onyxcode.ai.port12345Bundled chat server port.
onyxcode.ai.embeddingPort12346Bundled embedding server port.
onyxcode.ai.embeddingModelPath(blank)Advanced override; auto-discover.
onyxcode.ai.embeddingPoolingModeper modelmean / cls / last.
onyxcode.ai.activeBackend(UI managed)Do not hand-edit.
onyxcode.ai.fimTemplateautoauto / qwen / deepseek / starcoder / codestral.
onyxcode.ai.speculativeDecoding.enabledtrue
onyxcode.ai.draftModelPath(blank)Auto-discover when blank.
onyxcode.ai.draftMax82-16 speculative tokens.
onyxcode.ai.gpuLayersautoNumber of layers to offload to GPU.
onyxcode.ai.rag.enabledtrue
onyxcode.ai.rag.excludePatterns(see code)Default excludes node_modules etc.

Chat

KeyDefaultNotes
onyxcode.chat.enabledtrueShow the panel.
onyxcode.chat.maxTokens4096Max response length.
onyxcode.chat.temperature0.70-2.
onyxcode.chat.repeatPenalty1.11.0 disables.
onyxcode.chat.warnOnLightModeltrueOnce-per-session notice.
onyxcode.chat.applyModeautoauto (diff editor) / manual (buttons).
onyxcode.chat.contextWindowautoauto or numeric override.
onyxcode.chat.gitDiffModeautoauto / never.
onyxcode.chat.gitDiffMaxBytes4096Cap on the injected git diff.
onyxcode.chat.autoSummarizetrueAuto-condense old turns at ~70% context.
onyxcode.chat.instructionsFile.onyx/instructions.mdPath probed for project instructions.
onyxcode.chat.instructionsMaxBytes4096Cap on the injected instructions file.

Agent

KeyDefaultNotes
onyxcode.agent.modeaskplan / ask / editAuto / auto.
onyxcode.agent.alwaysAllow.fileReadtrue
onyxcode.agent.alwaysAllow.fileWritefalse
onyxcode.agent.alwaysAllow.shellExecfalse
onyxcode.agent.alwaysAllow.mcp[]Strings of <server>:<tool>.

Autocomplete

KeyDefaultNotes
onyxcode.autocomplete.enabledtrue
onyxcode.autocomplete.multiLinetrue
onyxcode.autocomplete.crossFileContexttrue
onyxcode.autocomplete.smartTriggertrue
onyxcode.autocomplete.predictiveEditstrue
onyxcode.autocomplete.debounceMs400
onyxcode.autocomplete.maxTokens128Provider also stops at \n\n.
onyxcode.autocomplete.temperature0.1
onyxcode.autocomplete.nextEditPrediction.enabledtrueMaster toggle for Zeta next-edit predictions.
onyxcode.autocomplete.nextEditPrediction.modelPath(blank)Explicit Zeta GGUF path; auto-discover when blank.

Codebase Index

KeyDefaultNotes
onyxcode.index.enabledtrue
onyxcode.index.maxFileSizeKB512
onyxcode.index.maxTotalFiles5000
onyxcode.index.concurrency4
onyxcode.index.persistEnabledtrue
onyxcode.index.watchEnabledtrue
onyxcode.index.excludeGlobs{}

Git Helpers

KeyDefaultNotes
onyxcode.git.commitMessageFormatconventionalOr freeform.
onyxcode.git.maxDiffBytes327681 KB - 256 KB.
onyxcode.git.appendSignaturetrueAppend "Drafted with Onyx Code".

Files and folders Onyx writes

PathScopePurpose
~/.onyxcode/models/userDownloaded GGUF chat / draft / embedding models.
~/.onyxcode/activity-log/<YYYY-MM>.jsonluserAudit log; one event per line.
~/.onyxcode/memory/<workspace-hash>/userProject-memory files (MEMORY.md + per-topic .md files).
~/Library/Application Support/Onyx Code/user (macOS)App state, sessions, snapshots of indices. Equivalents on Win / Linux.
<workspace>/ONYX.mdworkspaceProject overview.
<workspace>/.onyxrulesworkspaceProject rules.
<workspace>/.onyxnoaiworkspacePrivacy excludes.
<workspace>/.onyx/instructions.mdworkspaceExtended instructions.
<workspace>/.onyx/permissions.jsonworkspace (committed)Team-wide AI approval rules (allow / deny patterns).
<workspace>/.onyx/permissions.local.jsonworkspace (gitignored)Per-machine overrides; auto-appended to .gitignore on first write.
<workspace>/.vscode/settings.jsonworkspaceWhen workspaceAiDisabled is set, persists there.

Glossary

  • FIM (fill-in-the-middle) - the prompt format used for inline autocomplete: prefix + suffix around the cursor, model fills the gap.
  • GGUF - the quantized model file format used by llama.cpp. Onyx Code uses GGUF for both chat and embedding models.
  • Quantization- compresses a model's weights to fit in less RAM at a small quality cost. Q4_K_M is the typical “balanced” choice.
  • Speculative decoding - a small draft model speculates several tokens ahead of the main model, which verifies them in a single batched step.
  • RAG (retrieval-augmented generation) - embed all workspace files, retrieve the most semantically similar chunks per chat turn, and inject them into the prompt.
  • MCP (Model Context Protocol) - a JSON-RPC protocol for connecting agents to external tool servers (filesystem, git, web search, custom integrations).
  • Worktree - a separate working directory backed by the same git repository, so the agent can edit files and run commands without affecting your main branch.
  • Light model - a model with 3 billion parameters or fewer. Onyx surfaces a yellow badge on these and auto-applies extra guardrails when one is active.
  • Air-Gap Mode - block-all-outbound for users on regulated networks. When on, only localhost connections succeed.
  • Activity log - append-only JSONL audit trail of every AI interaction. Counts and metadata only - never prompt or completion text.
  • Smart-attach - when an attached file is too large to fit raw (16 KB+), Onyx swaps the full content for an outline + top-K RAG blocks view.
  • Workspace primer - a compact snapshot of the workspace layout, README excerpt, and manifest summary. Auto-generated on first chat in a workspace.
  • Ambient git-diff context - the auto-injected summary of your uncommitted git changes added to the system prompt when there are pending edits.
  • Predictive edits - heuristic, no AI call. Same-value matching on structurally similar lines.
  • Zeta- Zed Industries' open-source ML model for next-edit prediction; a Seed-Coder-8B-Base fine-tune (Zeta-2) distributed as GGUF, Apache 2.0. Bundled in Onyx as the inline-edit-prediction provider.
  • Next-edit prediction- ML-trained at-cursor prediction. After a substantive edit, Zeta-2 reads the last 20 edits and predicts a rewrite of the cursor's line, offered as inline ghost text (Tab to accept, Esc to dismiss).