Files
darman 420f00494f M0: scaffold Cargo workspace, core types, event bus, permission engine, storage actor
Sets up the Cargo workspace (harness-core, harness-tools, harness-providers, harness-mcp, harness-lsp, harness-app, harness-tui) and the ten architecture docs under docs/. harness-core gets its foundational types (session/message/part/model ids), an in-process event bus, a table-driven permission evaluate function, and a SQLite-backed storage actor with schema and roundtrip coverage. Every crate compiles empty and a bin stub prints its version.
2026-07-10 16:19:27 +02:00

3.0 KiB

06 — Config System

harness-core/src/config/.

Locations & precedence (lowest → highest)

  1. Bundled defaults (compiled in)
  2. Global: ~/.config/ai-harness/config.json
  3. Project chain: walk up from cwd collecting .harness/config.json, apply root-most first
  4. Env overrides (AI_HARNESS_MODEL, AI_HARNESS_CONFIG, provider key env vars)

JSONC via jsonc-parser (comments + trailing commas). Deep-merge objects, replace arrays. After merge: string interpolation of {env:VAR} and {file:path} (the latter useful for prompts).

Schema

pub struct Config {
    pub model: Option<String>,                    // "anthropic/claude-sonnet-4-5"
    pub small_model: Option<String>,              // titles/summaries/compaction
    pub providers: HashMap<String, ProviderConfig>,  // { enabled, api_key, base_url }
    pub agents: HashMap<String, AgentPatch>,      // patch semantics over loaded agent defs
    pub permissions: Vec<Rule>,                   // ordered; last-match-wins
    pub orchestration: OrchestrationConfig,       // { depth_limit: 3, job_board: true,
                                                  //   max_reusable_per_agent: 2, reminders: None }
    pub mcp: HashMap<String, McpServerConfig>,    // { command, args, env, enabled }
    pub lsp: HashMap<String, LspServerConfig>,    // { command, args, extensions: ["rs"] }
    pub tui: TuiConfig,                           // theme; keybinds later
    pub instructions: Vec<String>,                // files appended to system prompt (AGENTS.md, ...)
}

pub struct Rule { pub permission: String, pub pattern: String, pub action: Action }

Example:

{
  "model": "github-copilot/claude-sonnet-4.5",
  "small_model": "openai/gpt-4o-mini",
  "providers": {
    "anthropic": { "api_key": "{env:ANTHROPIC_API_KEY}" }
  },
  "agents": {
    "explorer": { "model": "github-copilot/gpt-4o", "temperature": 0 },
    "designer": { "disable": true },
    // unknown key + prompt/model → custom agent
    "reviewer": { "mode": "subagent", "prompt": "{file:./prompts/reviewer.md}" }
  },
  "permissions": [
    { "permission": "bash", "pattern": "git status*", "action": "allow" },
    { "permission": "edit", "pattern": "*.lock", "action": "deny" }
  ],
  "mcp": {
    "context7": { "command": "npx", "args": ["-y", "@upstash/context7-mcp"] }
  }
}

Markdown asset loading (config/markdown.rs)

All three kinds use YAML frontmatter + markdown body, from ~/.config/ai-harness/<kind>/ (global) and <project>/.harness/<kind>/ (project wins by name):

  • Agentsagent/*.mdAgentDef (see 04-multiagent.md).
  • Commandscommand/*.mdCommandDef { name (filename), description, agent?, model?, template }. Invoked as /name args in the TUI; template substitutes $ARGUMENTS / $1..$9 and becomes the user message, optionally switching agent/model for that run.
  • Skillsskill/<name>/SKILL.md → advertised (name + description) in a system prompt section; the full body is fetched on demand via the built-in skill tool.