/
psklyarov
/
agent-replacer
Обзор
Документация
Войти
/
psklyarov
/
agent-replacer
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/main/java/com/example/agentreplacer/run/ConfirmController.java
79 строк
4 KB
pavelsklyarov
v2
15 дек 2025, 12:02
15 дек 2025, 12:02
2babcfa
Код
Авторство
О чём код?
package com.example.agentreplacer.run; import com.example.agentreplacer.chat.ChatService; import com.example.agentreplacer.plan.ChangePlan; import com.example.agentreplacer.bitbucket.BitbucketProperties; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.file.Path; import java.util.Map; @RestController @RequestMapping("/api/run") public class ConfirmController { private final PendingChangeManager pending; private final ChatService chatService; private final BitbucketProperties props; private static final Logger log = LoggerFactory.getLogger(ConfirmController.class); public ConfirmController(PendingChangeManager pending, ChatService chatService, BitbucketProperties props) { this.pending = pending; this.chatService = chatService; this.props = props; } @PostMapping("/{sessionId}/confirm") public ResponseEntity<?> confirm(@PathVariable("sessionId") String sessionId, @RequestBody Map<String, String> body) { log.info("Confirm called for session {}", sessionId); String repoSlug = body.get("repoSlug"); String baseBranch = body.get("baseBranch"); String decision = body.get("decision"); if (repoSlug == null || baseBranch == null || decision == null) { log.warn("Confirm invalid request: repoSlug/baseBranch/decision are required"); return ResponseEntity.badRequest().body(Map.of("error", "repoSlug, baseBranch, decision required")); } var pc = pending.get(sessionId, repoSlug, baseBranch); if (pc == null) { log.warn("Confirm not found in pending: session={}, repo={}, base={}", sessionId, repoSlug, baseBranch); return ResponseEntity.badRequest().body(Map.of("error", "nothing pending for given repo/branch")); } try { Path repoDir = pc.getRepoDir(); ChangePlan plan = pc.getPlan(); try (Git git = Git.open(repoDir.toFile())) { git.add().addFilepattern(".").call(); String commitMsg = plan.getCommitMessage() != null ? plan.getCommitMessage() : plan.getTaskNumber() + ": bulk changes"; if ("approve".equalsIgnoreCase(decision)) { git.commit().setMessage(commitMsg).call(); git.push().setCredentialsProvider(creds()).call(); chatService.addAssistantMessage(sessionId, "Подтверждено. Коммит выполнен: " + repoSlug + " → " + baseBranch); log.info("Confirm approve committed: repo={} base={}", repoSlug, baseBranch); } else { String featureNamePrefix = plan.getBranchName() == null ? "feature/" + plan.getTaskNumber() : plan.getBranchName(); String featureBranch = featureNamePrefix + "-" + baseBranch.replace('/', '-'); git.checkout().setCreateBranch(true).setName(featureBranch).call(); git.add().addFilepattern(".").call(); git.commit().setMessage(commitMsg).call(); git.push().setCredentialsProvider(creds()).call(); chatService.addAssistantMessage(sessionId, "Отклонено. Изменения отправлены в ветку: " + featureBranch + " (" + repoSlug + "). Создайте PR вручную."); log.info("Confirm reject pushed to feature: repo={} feature={}", repoSlug, featureBranch); } } pending.remove(sessionId, repoSlug, baseBranch); return ResponseEntity.ok(Map.of("status", "ok")); } catch (Exception e) { log.error("Confirm failed: {}", e.getMessage(), e); return ResponseEntity.internalServerError().body(Map.of("error", e.getMessage())); } } private UsernamePasswordCredentialsProvider creds() { return new UsernamePasswordCredentialsProvider(props.getUsername(), props.getPassword()); } }