420f00494f
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.
3.0 KiB
3.0 KiB
06 — Config System
harness-core/src/config/.
Locations & precedence (lowest → highest)
- Bundled defaults (compiled in)
- Global:
~/.config/ai-harness/config.json - Project chain: walk up from cwd collecting
.harness/config.json, apply root-most first - 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):
- Agents —
agent/*.md→AgentDef(see 04-multiagent.md). - Commands —
command/*.md→CommandDef { name (filename), description, agent?, model?, template }. Invoked as/name argsin the TUI; template substitutes$ARGUMENTS/$1..$9and becomes the user message, optionally switching agent/model for that run. - Skills —
skill/<name>/SKILL.md→ advertised (name + description) in a system prompt section; the full body is fetched on demand via the built-inskilltool.