feat(worker): session skill registry (install/update/remove, pinned clone)
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using ClaudeDo.Data.Git;
|
||||
|
||||
namespace ClaudeDo.Worker.Skills;
|
||||
|
||||
public sealed class GitRepoCloner : IRepoCloner
|
||||
{
|
||||
private readonly GitService _git;
|
||||
|
||||
public GitRepoCloner(GitService git) => _git = git;
|
||||
|
||||
public async Task<ClonedRepo> CloneAsync(string url, string destDir, CancellationToken ct)
|
||||
{
|
||||
var parentDir = Path.GetDirectoryName(destDir);
|
||||
if (!string.IsNullOrEmpty(parentDir))
|
||||
Directory.CreateDirectory(parentDir);
|
||||
|
||||
var (exitCode, stderr) = await RunGitAsync(["clone", "--depth", "1", url, destDir], ct);
|
||||
if (exitCode != 0)
|
||||
throw new InvalidOperationException($"git clone '{url}' failed (exit {exitCode}): {stderr}");
|
||||
|
||||
var pinnedRef = await _git.RevParseHeadAsync(destDir, ct);
|
||||
return new ClonedRepo(destDir, pinnedRef);
|
||||
}
|
||||
|
||||
private static async Task<(int ExitCode, string Stderr)> RunGitAsync(IEnumerable<string> args, CancellationToken ct)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "git",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
StandardOutputEncoding = Encoding.UTF8,
|
||||
StandardErrorEncoding = Encoding.UTF8,
|
||||
};
|
||||
foreach (var a in args) psi.ArgumentList.Add(a);
|
||||
|
||||
using var proc = new Process { StartInfo = psi };
|
||||
proc.Start();
|
||||
|
||||
await using var ctr = ct.Register(() =>
|
||||
{
|
||||
try { proc.Kill(entireProcessTree: true); }
|
||||
catch { /* already exited */ }
|
||||
});
|
||||
|
||||
var stdoutTask = proc.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = proc.StandardError.ReadToEndAsync();
|
||||
|
||||
await proc.WaitForExitAsync(CancellationToken.None);
|
||||
await stdoutTask;
|
||||
var stderr = await stderrTask;
|
||||
|
||||
ct.ThrowIfCancellationRequested();
|
||||
|
||||
return (proc.ExitCode, stderr.TrimEnd());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user