feat(worker): add DefaultAgentSeeder for first-launch agent seeding
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
60
src/ClaudeDo.Worker/Services/DefaultAgentSeeder.cs
Normal file
60
src/ClaudeDo.Worker/Services/DefaultAgentSeeder.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ClaudeDo.Worker.Services;
|
||||
|
||||
public sealed record SeedResult(int Copied, int Skipped);
|
||||
|
||||
public sealed class DefaultAgentSeeder
|
||||
{
|
||||
private readonly string _bundleDir;
|
||||
private readonly string _targetDir;
|
||||
private readonly ILogger<DefaultAgentSeeder>? _logger;
|
||||
|
||||
public DefaultAgentSeeder(string bundleDir, string targetDir, ILogger<DefaultAgentSeeder>? logger = null)
|
||||
{
|
||||
_bundleDir = bundleDir;
|
||||
_targetDir = targetDir;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task<SeedResult> SeedMissingAsync(CancellationToken ct = default)
|
||||
{
|
||||
if (!Directory.Exists(_bundleDir))
|
||||
{
|
||||
_logger?.LogWarning("DefaultAgents bundle dir not found: {Dir}", _bundleDir);
|
||||
return new SeedResult(0, 0);
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(_targetDir);
|
||||
|
||||
int copied = 0;
|
||||
int skipped = 0;
|
||||
|
||||
foreach (var src in Directory.EnumerateFiles(_bundleDir, "*.md"))
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
var fileName = Path.GetFileName(src);
|
||||
var dst = Path.Combine(_targetDir, fileName);
|
||||
|
||||
if (File.Exists(dst))
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var input = File.OpenRead(src);
|
||||
using var output = File.Create(dst);
|
||||
await input.CopyToAsync(output, ct);
|
||||
copied++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger?.LogWarning(ex, "Failed to copy default agent {File}", fileName);
|
||||
}
|
||||
}
|
||||
|
||||
return new SeedResult(copied, skipped);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user