Add orch control commands

This commit is contained in:
2026-03-19 14:21:20 +08:00
parent f1785b314f
commit ae272855f6
10 changed files with 1644 additions and 43 deletions
+108 -2
View File
@@ -26,6 +26,31 @@ func newDispatchWorkspacePreparer(cmd *cobra.Command, opts dispatchOptions) stor
}
}
func newAttemptReuseWorkspacePreparer(cmd *cobra.Command, task store.Task, attempt *store.TaskAttempt) store.DispatchWorkspacePreparer {
if attempt == nil || attempt.WorktreePath == "" {
return nil
}
workspaceRoot, ok := deriveWorkspaceRootFromAttempt(task.RunID, task.TaskID, attempt.WorktreePath)
if !ok {
return nil
}
baseRef := attempt.BaseRef
if strings.TrimSpace(baseRef) == "" {
baseRef = attempt.BaseCommit
}
opts := dispatchOptions{
repoPath: attempt.WorktreePath,
workspaceRoot: workspaceRoot,
strictWorktree: true,
baseRef: baseRef,
}
return newDispatchWorkspacePreparer(cmd, opts)
}
func dispatchUsesWorktree(opts dispatchOptions) bool {
return strings.TrimSpace(opts.repoPath) != "" ||
strings.TrimSpace(opts.workspaceRoot) != "" ||
@@ -94,11 +119,15 @@ func resolveRepoRoot(ctx context.Context, repoPath string) (string, error) {
return "", fmt.Errorf("resolve repo path: %w", err)
}
stdout, _, err := runGit(ctx, absPath, "rev-parse", "--show-toplevel")
if _, _, err := runGit(ctx, absPath, "rev-parse", "--show-toplevel"); err != nil {
return "", protocol.InvalidInput("repo-path must point to a Git worktree", err)
}
commonDir, err := resolveCommonGitDir(ctx, absPath)
if err != nil {
return "", protocol.InvalidInput("repo-path must point to a Git worktree", err)
}
return strings.TrimSpace(stdout), nil
return filepath.Dir(commonDir), nil
}
func resolveDispatchBase(ctx context.Context, repoRoot, workspaceRoot, requestedBaseRef string, strict bool) (string, string, error) {
@@ -242,6 +271,27 @@ func buildAttemptWorktreePath(workspaceRoot, runID, taskID string, attemptNo int
)
}
func deriveWorkspaceRootFromAttempt(runID, taskID, worktreePath string) (string, bool) {
suffix := filepath.Join(
sanitizePathSegment(runID),
sanitizePathSegment(taskID),
filepath.Base(worktreePath),
)
parent := filepath.Dir(worktreePath)
if filepath.Base(parent) != sanitizePathSegment(taskID) {
return "", false
}
runDir := filepath.Dir(parent)
if filepath.Base(runDir) != sanitizePathSegment(runID) {
return "", false
}
root := filepath.Dir(runDir)
if filepath.Clean(filepath.Join(root, suffix)) != filepath.Clean(worktreePath) {
return "", false
}
return root, true
}
func sanitizeGitSegment(value string) string {
return sanitizeSegment(value)
}
@@ -301,3 +351,59 @@ func runGit(ctx context.Context, repoRoot string, args ...string) (string, strin
}
return "", message, fmt.Errorf("git %s: %s", strings.Join(args, " "), message)
}
func cleanupAttemptWorktree(ctx context.Context, attempt store.TaskAttempt, force bool) error {
if strings.TrimSpace(attempt.WorktreePath) == "" {
return nil
}
if _, err := os.Stat(attempt.WorktreePath); err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("stat worktree path: %w", err)
}
repoRoot, err := resolveRepoRootFromExistingWorktree(ctx, attempt.WorktreePath)
if err != nil {
if force {
return os.RemoveAll(attempt.WorktreePath)
}
return err
}
args := []string{"worktree", "remove"}
if force {
args = append(args, "--force")
}
args = append(args, attempt.WorktreePath)
if _, _, err := runGit(ctx, repoRoot, args...); err != nil {
if force {
return os.RemoveAll(attempt.WorktreePath)
}
return err
}
return nil
}
func resolveRepoRootFromExistingWorktree(ctx context.Context, worktreePath string) (string, error) {
commonDir, err := resolveCommonGitDir(ctx, worktreePath)
if err != nil {
return "", err
}
return filepath.Dir(commonDir), nil
}
func resolveCommonGitDir(ctx context.Context, repoPath string) (string, error) {
stdout, _, err := runGit(ctx, repoPath, "rev-parse", "--path-format=absolute", "--git-common-dir")
if err != nil {
return "", err
}
commonDir := strings.TrimSpace(stdout)
if !filepath.IsAbs(commonDir) {
commonDir = filepath.Join(repoPath, commonDir)
}
return filepath.Clean(commonDir), nil
}