7.0 KiB
Default Agents — Design
Date: 2026-04-23 Status: Approved
Goal
Ship ClaudeDo with a curated set of default agents so that users have useful agents available on first launch, without losing the file-based ownership model (user-editable, user-deletable). Provide a "Restore defaults" action to recover missing defaults on demand.
Agents to Ship
Six markdown agents covering the common stages of task execution plus one general-purpose agent:
| File | Focus |
|---|---|
code-reviewer.md |
Review diff for bugs, logic errors, convention adherence. Flags only high-confidence issues. |
test-writer.md |
Generate unit/integration tests for changed code. Follows existing test patterns. |
debugger.md |
Systematic root-cause analysis — reproduce, isolate, hypothesize, verify. |
security-reviewer.md |
OWASP-style audit focused on auth, SQL injection, input handling, secret exposure. |
explorer.md |
Fast codebase navigation and answering "where/how" questions. Terse output. |
researcher.md |
General-purpose research, doc summarization, analysis, investigation. Non-code. |
Each file uses Claude Code's standard agent frontmatter:
---
name: <agent name>
description: <one-line description>
---
<system prompt body>
Content target: ~20–40 lines per file. Style matches the existing Claude Code agent conventions.
Behavior
Seed on first launch, restore on demand:
- Bundled agents live alongside the Worker binary at
<AppContext.BaseDirectory>/DefaultAgents/*.md. - At Worker startup, for each bundled file: if
~/.todo-app/agents/<name>.mddoes NOT exist, copy it in. If it exists, leave it alone — the user owns their copy. - A "Restore default agents" button in the settings modal re-runs the same check, restoring any that the user has deleted.
The seed path and the restore path are the same code — only the invocation differs (startup vs. hub call).
Components
DefaultAgents/*.md (bundled content)
Location: src/ClaudeDo.Worker/DefaultAgents/
Packaging: <Content Include="DefaultAgents\*.md" CopyToOutputDirectory="PreserveNewest" /> in ClaudeDo.Worker.csproj.
At runtime they land at <AppContext.BaseDirectory>/DefaultAgents/*.md next to the executable.
DefaultAgentSeeder (new service)
Location: src/ClaudeDo.Worker/Services/DefaultAgentSeeder.cs
public sealed class DefaultAgentSeeder
{
public DefaultAgentSeeder(string bundleDir, string targetDir);
public Task<SeedResult> SeedMissingAsync(CancellationToken ct = default);
}
public sealed record SeedResult(int Copied, int Skipped);
Behavior of SeedMissingAsync:
- If
bundleDirdoesn't exist, log warning and return(0, 0). - Enumerate
*.mdinbundleDir. - For each file, if the target path (
targetDir/<filename>) is missing, copy it; else incrementSkipped. - Create
targetDirif missing (consistent with existingAgentFileService.WriteAsync). - Per-file exceptions are caught and logged; the seeder continues with the next file. The method itself does not throw for individual file failures.
Program.cs wiring
After AgentFileService registration and before app.Run():
var bundleDir = Path.Combine(AppContext.BaseDirectory, "DefaultAgents");
var seeder = new DefaultAgentSeeder(bundleDir, agentsDir);
await seeder.SeedMissingAsync();
builder.Services.AddSingleton(seeder);
The seeder is also registered as a singleton so the hub can invoke it for the restore flow.
WorkerHub.RestoreDefaultAgents
Location: add method to existing src/ClaudeDo.Worker/Hub/WorkerHub.cs.
Signature: public async Task<SeedResult> RestoreDefaultAgents()
Behavior:
- Calls
DefaultAgentSeeder.SeedMissingAsync(). - Returns the
SeedResultto the caller. - No separate broadcast — the UI will call
GetAgentsafter the restore returns, reusing the existing refresh path.
UI — Settings Modal
Location: src/ClaudeDo.Ui/Views/Modals/SettingsModalView.axaml + SettingsModalViewModel.
Add a "Restore default agents" button to the modal. On click:
- Disable the button, show a spinner label.
- Call
WorkerClient.RestoreDefaultAgentsAsync(). - Show a brief inline confirmation:
"Restored {Copied} agent(s)"or"All defaults already present". - Trigger the existing agent list refresh so the new files appear immediately in the rest of the UI.
WorkerClient method
Add Task<SeedResult> RestoreDefaultAgentsAsync(CancellationToken ct = default) to WorkerClient — thin wrapper that invokes the hub method.
Data Flow
Startup:
Worker starts → DefaultAgentSeeder.SeedMissingAsync()
→ copies missing files into ~/.todo-app/agents/
AgentFileService.ScanAsync() (on first GetAgents call) → sees the seeded files
User restores:
Settings modal button click
→ WorkerClient.RestoreDefaultAgentsAsync()
→ WorkerHub.RestoreDefaultAgents()
→ DefaultAgentSeeder.SeedMissingAsync()
→ returns SeedResult(copied, skipped)
UI shows confirmation, triggers GetAgents refresh
Error Handling
| Failure | Behavior |
|---|---|
Missing DefaultAgents/ bundle dir |
Log warning, return (0, 0). Startup proceeds. |
| Individual file copy failure (disk, permissions) | Catch per-file, log, continue with the remaining files. |
| Corrupt bundled markdown (no valid frontmatter) | Copied anyway — the AgentFileService frontmatter parser already falls back to filename-as-name. |
| Startup seeder exception (unexpected) | Log as warning, do not crash the Worker. Agents can still be restored via the button. |
Hub RestoreDefaultAgents exception |
Propagate to client as SignalR error; UI shows a generic "Restore failed" message. |
Testing
Unit: tests/ClaudeDo.Worker.Tests/Services/DefaultAgentSeederTests.cs
- Seeds all files when target dir is empty.
- Skips files that already exist.
- Preserves existing user-modified files (file mtime / content unchanged).
- Returns accurate
SeedResultcounts. - Handles missing bundle dir gracefully (returns
(0, 0), no throw). - Creates target dir if it doesn't exist.
Integration: extend tests/ClaudeDo.Worker.Tests/Hub/AgentSettingsHubTests.cs
RestoreDefaultAgentsinvokes the seeder and returns the count.
No UI tests. The project has no UI test harness; settings modal behavior is exercised manually.
Build / Packaging
src/ClaudeDo.Worker/ClaudeDo.Worker.csproj gains:
<ItemGroup>
<Content Include="DefaultAgents\*.md">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
No new NuGet dependencies.
Out of Scope
- Editing bundled agents in-place (user edits their copy under
~/.todo-app/agents/; bundle is read-only by convention). - Versioning / updating user copies when the bundled version changes. If a bundled agent is improved in a later release, the user's copy is not overwritten. A future release may add a "diff / reset to bundled" flow, but not now.
- Packaging as embedded resources. Content files copied to output are simpler, inspectable on disk, and consistent with the file-based agent model.