Configuration & Hooks

buildwithnexus keeps everything it needs in a single directory: ~/.buildwithnexus/. Your config, your API keys, your session history, your downloaded local models, and your hook settings all live there. This page covers that layout, how providers and models are chosen, the permission modes that gate mutating tools, and the Claude-Code-compatible lifecycle hooks.

The ~/.buildwithnexus/ Directory

Created on first run. No daemon, no database, no server — just files.

Path
Contents
config.json
Default provider, model, permission mode, and UI preferences.
.env.keys
API keys for remote providers. Written 0600 (owner read/write only).
history
Persistent REPL input history (recalled with the arrow keys and Ctrl+R).
sessions/
One saved transcript per run, restored by continue / resume.
models/
Local GGUF model files, scanned at setup to auto-detect local providers.
settings.json
User-level lifecycle hooks (see Hooks).
trusted.json
Folders you've trusted to run project-level hooks.

A project can also carry its own .buildwithnexus/settings.json checked into the repo. Project settings apply only after you trust the folder.

Providers & Models

buildwithnexus talks to models over two wire protocols and ships 8 built-in providers — five remote (you supply an API key) and three local (running on your own machine). Local providers are auto-detected at setup by probing the Ollama API and scanning the models/ folder for GGUF files.

RemoteAPI key
Anthropic · OpenAI · OpenRouter · Groq · Hugging Face
Keys read from ~/.buildwithnexus/.env.keys or the environment.
LocalAuto-detected
Ollama · llama.cpp server · LM Studio
No key, no network — runs entirely on your machine.

Two wire protocols

Every provider speaks one of two protocols. Anthropic Messages is its own format; the OpenAI chat-completions format covers everything else — so one OpenAI-compatible client reaches OpenAI, OpenRouter, Groq, Hugging Face, Ollama, llama.cpp, and LM Studio.

Protocol
Providers
Anthropic Messages
Anthropic
OpenAI chat-completions
OpenAI, OpenRouter, Groq, Hugging Face, Ollama, llama.cpp server, LM Studio

The default provider and model live in config.json; the setup wizard writes them for you, and you can switch at any time from the REPL or per-run on the command line.

// ~/.buildwithnexus/config.json
{
  "provider": "anthropic",
  "model": "claude-sonnet-4-5",
  "permissionMode": "ask"
}

API keys are never sent to a non-HTTPS endpoint, and key-like tokens are redacted from any error surfaced to the screen.

Permission Modes

Reads run freely. The mutating tools — write_file, edit_file, run_command — are gated by the active permission mode. Set it in config.json, or switch it for a single run.

ask
Default
Confirm every mutating tool before it runs. Edits preview as an inline diff.
auto
Run unattended
Apply changes without prompting — except for sensitive paths and catastrophic commands.
readonly
Look, don't touch
Reads only. Every mutating tool is refused.

Some things always prompt, even under auto:

Sensitive paths

  • ~/.ssh
  • .env files and *.pem keys
  • The buildwithnexus key store

Hard guarantees

  • Catastrophic commands always require confirmation
  • File tools stay confined to the working directory
  • API keys never sent to a non-HTTPS endpoint
  • Key-like tokens redacted from surfaced errors

Hooks

buildwithnexus supports Claude-Code-compatible lifecycle hooks: shell commands that fire at specific points in a run. Configure them in settings.json — user-level at ~/.buildwithnexus/settings.json, project-level at .buildwithnexus/settings.json in the repo.

The six events

SessionStart
A run begins — seed context or warm up the environment.
UserPromptSubmit
You submit a prompt — inspect or augment it before the model sees it.
PreToolUse
Before a tool runs — the one event that can deny the call.
PostToolUse
After a tool finishes — lint, format, or log the result.
Stop
The agent finishes responding.
SessionEnd
The run wraps up — clean up or archive.
// ~/.buildwithnexus/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "edit_file|write_file",
        "hooks": [
          { "type": "command", "command": "cargo fmt" }
        ]
      }
    ]
  }
}

User vs. project settings

Scope
Location
When it runs
User
~/.buildwithnexus/settings.json
Always — for every project on your machine.
Project
.buildwithnexus/settings.json
Only after you trust the folder.

The per-folder trust model

Project hooks ship inside repositories, so they don't run until you explicitly trust the folder. Trusted folders are recorded in ~/.buildwithnexus/trusted.json. Until then, a cloned repo's hooks are inert — pulling someone else's project can't execute commands on your machine.

Cloned a repo with hooks?
Nothing runs until you trust the folder
Trust is recorded in trusted.json — revoke it any time

Project hooks can deny, never grant

A trusted project hook on PreToolUse can block a tool call, but it can never authorize one — the permission gate is the only thing that grants. A hook denies a call in one of two ways:

exit 2
Non-zero deny
Exit code 2 blocks the tool call outright.
permissionDecision
Structured deny
Emit JSON with a permissionDecision of deny.
// PreToolUse hook output — block this tool call
{ "permissionDecision": "deny", "reason": "writes to generated/ are not allowed" }

Sensible defaults mean most people never touch config.json or settings.json — the setup wizard handles providers and models, ask keeps you in control, and hooks are entirely opt-in.