[Bugfix #1137] Fix gitea forge preset against the real tea CLI - #1146
[Bugfix #1137] Fix gitea forge preset against the real tea CLI#1146pseudoseed wants to merge 4 commits into
Conversation
The gitea preset invoked `tea <entity> list/view/whoami/comment`, whose
flattened `--fields` output (or missing flags/subcommands) doesn't match the
Gitea REST shape that forge-contracts.ts and the jq normalizers assume. Route
the read concepts through `tea api`, the raw REST passthrough that returns
exactly that shape:
- user-identity: `tea api user | jq .login` (`tea whoami` has no --output json)
- pr-view: `tea api repos/<repo>/pulls/N` → PrViewResult
- pr-list: `tea api repos/<repo>/pulls?state=open` → PrListItem[]
(now also populates real reviewRequests/isDraft/body)
- pr-exists: `tea api repos/<repo>/pulls?state=all` with nested .head.ref/.merged
- issue-view: `tea api repos/<repo>/issues/N` + a second call for the comments
ARRAY (Gitea's issue object reports `comments` as an int count,
which would crash consumers' `.comments.filter(...)`)
- recently-merged: `tea api repos/<repo>/pulls?state=closed`, filter .merged,
using the real .merged_at
- issue-comment: `tea comments add` (`tea issues` has no `comment` subcommand)
`tea api` needs an explicit owner/repo path segment (unlike `tea <entity>`,
which auto-detects it from the local git remote), and most concepts are invoked
without CODEV_REPO set, so each api-based script derives owner/repo from the
origin remote, honoring CODEV_REPO when present.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stubs a fake `tea` on PATH answering `api <endpoint>` with captured Gitea REST fixtures (tea isn't in CI, per cluesmith#920), points the scripts at a throwaway repo with a gitea remote, runs each real script, and asserts the normalized output conforms to forge-contracts.ts — incl. comments-as-array, merged-only filtering, open/merged/closed pr-exists cases, and CODEV_REPO override. Also updates the cluesmith#568 pr-exists assertion for gitea to match the new `state=all` query param (was `--state all` flag). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
waleedkadous
left a comment
There was a problem hiding this comment.
Excellent work — thank you for the disciplined re-do, and apologies for the review latency. This is what a model bugfix PR looks like: every tea-CLI deficiency documented in-script with reasoning, the REST passthrough returning exactly the shape forge-contracts.ts expects, and a genuinely well-built regression suite (fake tea on PATH serving captured REST fixtures, the real scripts executed, contract-shape assertions, the comments-as-int crash and null-login team reviewers both covered). We verified every output mapping field-by-field against the contracts — all conform — and the switch from string-interpolated jq to --arg in pr-exists is a quiet security improvement worth crediting.
One substantive question before merge, and two optional polish items:
1. Pagination cap (the one we'd like addressed or answered). Gitea servers cap page size at max_response_items (default 50), so ?limit=200 likely returns 50 items with no client-side pagination in the raw passthrough. That means pr-exists?state=all can false-negative for a branch whose PR isn't in the most recent ~50 (which would block a porch pr_exists gate), and recently-merged (previously --limit 1000) can miss on a busy repo. A pagination loop (page=1..N until a short page) would settle it — or at minimum a comment documenting the server-side cap and the false-negative window, so the next debugger isn't blind. Happy with either; we'd just like the behavior to be chosen rather than inherited.
2. (Polish, optional) With no origin remote or an unusual URL, REPO silently becomes empty/garbage and tea api "repos//…" fails with a confusing 404. An explicit [ -n "$REPO" ] || { echo "…set CODEV_REPO" >&2; exit 1; } naming the remedy would fit this repo's fail-fast convention — ideally factored once since the derivation appears in five scripts.
3. (Polish, optional) A failed comments fetch silently yields comments: [] — indistinguishable from "no comments" for consumers reading issue discussion. A stderr warning on the degraded path would keep the graceful behavior while leaving a trace.
Verdict: approve once item 1 is addressed (fix or documented caveat — your choice). Items 2–3 are welcome in this PR or a follow-up, contributor's choice.
Fixes #1137.
Bugfix-protocol re-do of the earlier SPIR-style PR #1138 (now closed), per maintainer request. Same root cause, plus a real regression test.
Problem
The
giteaforge preset was authored against the Gitea REST API JSON shape, but the scripts invoke theteaCLI, whose output shape differs — and several concepts referenced flags/fields/subcommandsteadoesn't have. Per the in-repo#920note,teawasn't available in the authoring environment, so the preset was never run end-to-end.Fix
Route the read concepts through
tea api(raw REST passthrough returning the shapeforge-contracts.ts+ the jq normalizers expect):tea api user | jq .login(tea whoamihas no--output json)tea api repos/<repo>/pulls/N→PrViewResult(incl. additions/deletions)tea api repos/<repo>/pulls?state=open→PrListItem[]tea api repos/<repo>/pulls?state=allwith nested.head.ref/.mergedtea api repos/<repo>/issues/N+ a second call for the comments array (Gitea reportscommentsas an int count, which would crash.comments.filter(...))tea api repos/<repo>/pulls?state=closed, filter.merged, using real.merged_attea comments add(tea issueshas nocommentsubcommand)tea apineeds an explicit owner/repo path segment, so each api-based script derives owner/repo from the origin remote (honoringCODEV_REPOwhen set).Testing
teaon PATH answeringapi <endpoint>with captured Gitea REST fixtures (tea isn't in CI, per vscode: editor-tab webview for rich backlog search #920), runs each real script, and asserts the normalized output conforms toforge-contracts.ts— incl. comments-as-array, merged-only filtering, open/merged/closedpr-exists, andCODEV_REPOoverride.pr-existsassertion for the newstate=allquery param.🤖 Generated with Claude Code