MCP 2.3.0: tea_file_edit, exact-text replacements in one file (#13)
Closes#12. A commit through the MCP needs the whole file in one call, and one model answer carries about 100 KB at most; tea_file_edit reads a file at the branch, applies exact-text replacements in order (each old text exactly once in the file as it stands), commits one update with the file's sha, and answers with the new size and sha256 to check against the caller's copy. 40 tests pass from a clean checkout on hb-5. Merged on the owner's say-so in the chat.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SKUMBXauq7XVN4BhTXjCSM
Teahub home-screen icon and link-preview card (#11)
- apple-touch-icon.png: the cup on Teahub green (#2f9e44), opaque 180x180, linked from header.tmpl
- og-card.png: 1200x630 link-preview card (the home page hero), 15 KB
- head_opengraph.tmpl: Gitea 28.0.0's; site pages get the absolute card URL with size and alt,
and twitter:card summary_large_image
- src/: the HTML the two PNGs are rendered from
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XvDrpBDoAJjW8z1kaa3GAa
Being signed in to teahub.xyz, or connected to Tea MCP in chat, is the gate,
as the operator put it. This takes out 9fece6d's browser sign-in: GET /domains
is open and bounded again (only teahub.xyz may read it, 8 searches a minute
per client and 20 in all, answers kept ten minutes), and the same search is
the tea_domains tool, behind the connector's sign-in.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6
/domains/sign-in and /domains/callback do Tea MCP's own Gitea OAuth (the
Green Tea MCP app) in the browser, keep only the name from Gitea, and leave a
signed, HttpOnly cookie on mcp.teahub.xyz for 30 days. GET /domains wants it
(401 with a sign-in link otherwise) and rate-limits per person. The Domains
tab sends that cookie, offers the sign-in on a 401, and runs the waiting
search on the way back. Tested end to end against a Gitea 28 and Cloudflare.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6
gitea/custom: the old factory's home page and dashboard, ported to Gitea 28.
The signed-out home is Teahub = Git + Tea + Time beside the cup; the
dashboard keeps the feed and puts Domains | Repository | Organization above
the contribution heatmap. Green tea colours for Gitea's light, dark and auto
themes, and the 🍵 mark. gitea/sync-custom.sh puts it on green-tea's volume;
gitea/fly.toml names the site Teahub and sets the meta tags.
mcp 2.2: GET /domains, the old factory's Cloudflare Registrar search (a live
check of the exact names, suggestions, prices). Only GITEA_URL may read it
from a browser; 8 searches a minute per client and 20 in all; answers kept
ten minutes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6
tea_actions lists runs from /actions/runs (ids, numbers, workflows, conclusions) and tea_action_logs reads one run's jobs, their steps and the last lines of each job's log. Gitea 1.24 had neither endpoint; 28 has both. Tried against a copy of prod's data on 28 before this commit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6
green-tea's fly.toml was only on hb-5 (~/green-tea), on the floating
docker.gitea.com/gitea:1.24 tag. It moves here unchanged apart from the
image, which is now an exact release. Deploy from gitea/ after a volume
snapshot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6