Some checks failed
Release Gate / gate (push) Has been cancelled
- 도구 동등화: task/todo/tool-search + plan/worktree/team/cron 도구군 추가 및 ToolRegistry 등록\n- claw-code CamelCase 별칭 정규화 확장: EnterPlanMode/EnterWorktree/TeamCreate/CronCreate 등 -> 내부 snake_case 매핑\n- AgentLoop 런타임 강화: Code 탭 전용 도구 토글(CodeSettings) 반영, 비활성 도구 자동 차단\n- Worktree 상태 복원 연결: .ax/worktree_state.json 기반 루트 탐색/활성 worktree 복원 및 BuildContext 연동\n- 권한/플러그인 하드닝 기존 반영분 유지: target 기반 권한 판정 + internal 모드 플러그인 경로/manifest 검증\n- 설정 연동(UI): SettingsWindow Code 패널에 Plan/Worktree/Team/Cron 도구 on/off 토글 추가\n- 테스트 보강: AgentParityTools/AgentLoopE2E에 worktree 지속성, alias 정규화, 설정 차단 시나리오 추가\n- 검증 완료: dotnet build(경고0/오류0), ParityBenchmark 11/11, ReplayStability 12/12, 전체 371/371, release-gate 통과\n- 문서 동기화: AGENT_ROADMAP/NEXT_ROADMAP/CLAW_CODE_PARITY_PLAN 수치 및 기준 최신화
49 lines
2.0 KiB
C#
49 lines
2.0 KiB
C#
using System.IO;
|
|
using System.Text.Json;
|
|
|
|
namespace AxCopilot.Services.Agent;
|
|
|
|
public sealed class EnterWorktreeTool : IAgentTool
|
|
{
|
|
public string Name => "enter_worktree";
|
|
public string Description => "Enter or create a nested worktree path inside current WorkFolder.";
|
|
|
|
public ToolParameterSchema Parameters => new()
|
|
{
|
|
Properties = new()
|
|
{
|
|
["path"] = new() { Type = "string", Description = "Relative worktree path." },
|
|
["create"] = new() { Type = "boolean", Description = "Create directory if missing (default true)." }
|
|
},
|
|
Required = ["path"]
|
|
};
|
|
|
|
public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
|
|
{
|
|
var relative = args.TryGetProperty("path", out var pathEl) ? (pathEl.GetString() ?? "").Trim() : "";
|
|
if (string.IsNullOrWhiteSpace(relative))
|
|
return Task.FromResult(ToolResult.Fail("path is required."));
|
|
if (string.IsNullOrWhiteSpace(context.WorkFolder) || !Directory.Exists(context.WorkFolder))
|
|
return Task.FromResult(ToolResult.Fail("valid WorkFolder is required."));
|
|
|
|
var create = !args.TryGetProperty("create", out var createEl) || createEl.ValueKind != JsonValueKind.False;
|
|
var root = WorktreeStateStore.ResolveRoot(context.WorkFolder);
|
|
var full = Path.GetFullPath(Path.Combine(root, relative));
|
|
if (!full.StartsWith(root, StringComparison.OrdinalIgnoreCase))
|
|
return Task.FromResult(ToolResult.Fail("worktree path must stay inside WorkFolder."));
|
|
|
|
if (!Directory.Exists(full))
|
|
{
|
|
if (!create)
|
|
return Task.FromResult(ToolResult.Fail("worktree path does not exist."));
|
|
Directory.CreateDirectory(full);
|
|
}
|
|
|
|
var state = WorktreeStateStore.Load(root);
|
|
state.Active = full;
|
|
WorktreeStateStore.Save(root, state);
|
|
context.WorkFolder = full;
|
|
return Task.FromResult(ToolResult.Ok($"Entered worktree: {full}"));
|
|
}
|
|
}
|