JD.AI is configured through JSON files, project instruction files, slash commands, and CLI flags. No configuration is required to get started — sensible defaults apply out of the box.
Settings are resolved in this priority order (highest wins):
| Priority | Source | Scope | Set via |
|---|---|---|---|
| 1 | CLI flags | Process | --provider, --model, --system-prompt, etc. |
| 2 | Session state | Session | /model set, /provider, /autorun, /permissions |
| 3 | Per-project defaults | Project | /default project provider, /default project model |
| 4 | Global defaults | User | /default provider, /default model |
| 5 | Environment variables | System | OPENAI_API_KEY, OLLAMA_ENDPOINT, etc. |
| 6 | Built-in defaults | Application | Hard-coded fallbacks |
{
"defaults": {
"provider": "openai",
"model": "gpt-4o"
},
"projectDefaults": {
"/home/user/projects/my-app": {
"provider": "ollama",
"model": "llama3.2:latest"
},
"C:\\Projects\\enterprise-api": {
"provider": "azure-openai",
"model": "gpt-4o"
}
}
}| Field | Type | Description |
|---|---|---|
defaults |
object | Global default provider and model |
defaults.provider |
string? | Provider identifier (e.g. "openai", "ollama", "anthropic") |
defaults.model |
string? | Model identifier (e.g. "gpt-4o", "llama3.2:latest") |
projectDefaults |
object | Per-project overrides, keyed by absolute project path |
projectDefaults.<path>.provider |
string? | Project-specific provider override |
projectDefaults.<path>.model |
string? | Project-specific model override |
All fields are optional. Null/missing values fall through to the next priority level.
/default # Show current defaults (global + project)
/default provider openai # Set global default provider
/default model gpt-4o # Set global default model
/default project provider ollama # Set per-project default provider
/default project model llama3.2 # Set per-project default model
Per-project defaults are stored in .jdai/defaults.json in the project root directory:
{
"defaultProvider": "ollama",
"defaultModel": "llama3.2:latest"
}These override global defaults when JD.AI is launched from that project directory.
JDAI.md is a Markdown file placed in the repository root. JD.AI reads it at session start and injects its contents into the system prompt.
JD.AI searches for instruction files in priority order. All discovered files are merged, with JDAI.md taking highest priority:
| Priority | File | Notes |
|---|---|---|
| 1 | JDAI.md |
JD.AI native |
| 2 | CLAUDE.md |
Recognized instruction filename |
| 3 | AGENTS.md |
Recognized instruction filename |
| 4 | .github/copilot-instructions.md |
Recognized instruction filename |
| 5 | .jdai/instructions.md |
Dot-directory variant |
# Build & Test
- Build: `dotnet build MyProject.slnx`
- Test: `dotnet test --filter "Category!=Integration"`
- Format: `dotnet format MyProject.slnx`
- Lint: build must pass with zero warnings
# Code Style
- File-scoped namespaces
- XML doc comments on all public APIs
- Async/await throughout (no .Result or .Wait())
- ILogger<T> for logging, never Console.WriteLine
# Git Conventions
- Conventional commits (feat:, fix:, chore:, etc.)
- PR branches: feature/, fix/, chore/
# Project Notes
- Authentication module is in src/Auth/ — uses JWT
- Database migrations: `dotnet ef database update`| ✅ Include | ❌ Exclude |
|---|---|
| Build/test commands | Obvious language conventions |
| Code style rules that differ from defaults | Standard patterns the AI already knows |
| Project-specific conventions | Detailed API documentation |
| Architecture decisions | File-by-file code descriptions |
| Environment quirks | Information that changes frequently |
/instructions # Show all loaded instruction content
~/.jdai/config.json is managed by the AtomicConfigStore class, which provides:
- Cross-process safety: File-level lock via
config.json.lock - In-process safety:
SemaphoreSlimfor concurrent access - Retry policy: 5 retries with exponential backoff (50ms → 100ms → 200ms → 400ms → 800ms)
- Current config is backed up to
config.json.bak - New config is written to
config.json.tmp - Temp file is atomically moved to
config.json
- If
config.jsonis empty or contains invalid JSON, a new empty config is returned - The
.bakfile can be manually restored if needed - Round-trip validation: serialized JSON is deserialized before writing to catch serialization bugs
File exists + valid JSON → deserialized config
File exists + empty → empty config (defaults)
File exists + invalid → empty config (defaults)
File missing → empty config (defaults)
JD.AI uses native .jdai locations for skills/plugins and keeps .claude skills as lower-precedence legacy inputs.
| Path | Scope |
|---|---|
<install>/skills/ |
Bundled baseline skills |
~/.jdai/skills/ |
User-managed skills |
.jdai/skills/ |
Workspace skills |
~/.claude/skills/ |
Legacy skills (lower precedence) |
.claude/skills/ |
Legacy skills (lower precedence) |
Skill runtime policy/config:
| Path | Scope |
|---|---|
~/.jdai/skills.json |
User skill lifecycle config |
.jdai/skills.json |
Workspace overrides |
| Path | Scope |
|---|---|
~/.jdai/plugins/ |
Personal plugins |
.jdai/plugins/ |
Project plugins |
~/.jdai/hooks.json |
Hook profiles and toggles |
See Skills and Plugins for lifecycle, precedence, and gating details.
~/.jdai/
├── config.json # Global defaults (managed by AtomicConfigStore)
├── config.json.bak # Backup of previous config
├── config.json.lock # File lock (transient)
├── skills/ # User-managed skills
├── skills.json # User skills lifecycle config
├── runtime/
│ └── skills/ # Active staged skills for current runtime
├── credentials/ # Encrypted credential store
├── sessions.db # SQLite session database
├── update-check.json # NuGet update cache (24h TTL)
├── exports/ # Exported session JSON files
└── models/ # Local GGUF models
└── registry.json # Model manifest
| Command | Effect |
|---|---|
/autorun |
Toggle auto-approve for tool execution |
/permissions |
Toggle all permission checks |
/compact |
Force context compaction |
/clear |
Clear conversation history |
/spinner [style] |
Change spinner animation style |
/config list |
Show persisted runtime settings |
/config get <key> |
Read a persisted runtime setting |
/config set <key> <value> |
Write a persisted runtime setting |
Note: output_style=json is session-only and will not persist as startup default.
The /update workflow reads these settings from updates:
updates.enabled(bool)updates.allowPromptTrigger(bool)updates.requireApproval(bool)updates.components.daemon(bool)updates.components.gateway(bool)updates.components.tui(bool)updates.drainTimeout(timespan)updates.reconnectTimeout(timespan)
These settings control whether update orchestration is enabled, whether prompt-triggered flows are allowed, whether apply needs approval, which components participate, and drain/reconnect timing windows.
prompt_cache=onprompt_cache_ttl=5m- Optional extended TTL:
/config set prompt_cache_ttl 1h
See Prompt Caching Reference for provider support, thresholds, and behavior.
- CLI Reference — CLI flags that override configuration
- Environment Variables — env var reference
- Providers Reference — provider configuration
- Prompt Caching Reference — cache policy and runtime controls
- User Guide: Configuration
- Configuration (guide) — tutorial-style guide
