Slice 5: Gitea forge - PRs and Merge & clean up

New internal/forge (provider-abstracted, Gitea impl via code.gitea.io/sdk/gitea) with tested remote-URL parsing and read+write ops: list open PRs, and merge-and-cleanup (squash-merge + delete head branch when head/base share a repo). Service resolves repo->owner/repo from remotes (prefers origin) and records a pr-merged event; config gains GITEA_URL/GITEA_TOKEN (forge disabled without both). MCP tools list_prs and merge_and_cleanup_pr (merge tool tells Claude to confirm first, 1.4). HTTP GET /api/repo/prs, POST /api/repo/pr/merge. New <pr-list> component with a confirming Merge & clean up button, hidden when no forge. Verified graceful-disabled path; real merge pending token + a designated PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-09-20 08:37:51 -04:00
parent 2b77e15b36
commit 9d1519222c
16 changed files with 657 additions and 13 deletions
+12
View File
@@ -62,6 +62,18 @@
project and this activity, so you stay on the same page.
</p>
<h2>Pull requests: Merge &amp; clean up</h2>
<p>
When a repository is hosted on your Gitea server, its open pull requests
appear under the details panel. Each has a <strong>Merge &amp; clean up</strong>
button: it squash-merges the pull request and <strong>deletes its
branch</strong> in one step, so finished work doesn't leave branches lying
around. You'll be asked to confirm — it names the pull request and the branch
that will be deleted — because it can't be undone (the merged history stays
on the server; only the branch is removed). If you don't use a Gitea server,
this section stays hidden.
</p>
<h2>Handing a project off to Claude</h2>
<p>
When GitManager is connected to Claude, you can hand the current project
+6 -1
View File
@@ -11,6 +11,7 @@
<script type="module" src="/components/repo-detail/repo-detail.js"></script>
<script type="module" src="/components/activity-feed/activity-feed.js"></script>
<script type="module" src="/components/handoff-bar/handoff-bar.js"></script>
<script type="module" src="/components/pr-list/pr-list.js"></script>
<style>
header {
display: flex;
@@ -31,6 +32,7 @@
gap: 16px;
align-items: start;
}
.right { display: grid; gap: 16px; }
@media (max-width: 720px) { .cols { grid-template-columns: 1fr; } }
</style>
</head>
@@ -44,7 +46,10 @@
<handoff-bar></handoff-bar>
<div class="cols">
<repo-list></repo-list>
<repo-detail></repo-detail>
<div class="right">
<repo-detail></repo-detail>
<pr-list hidden></pr-list>
</div>
</div>
<activity-feed></activity-feed>
</main>