WHAT THIS IS
============
The Gitea client is the API foundation that every orchestration
module depends on — graph_store.py, knowledge_ingester.py, the
playbook engine, and tasks.py in timmy-home.
Until now it was 60 lines and 3 methods (get_file, create_file,
update_file). This made every orchestration module hand-roll its
own urllib calls with no retry, no pagination, and no error
handling.
WHAT CHANGED
============
Expanded from 60 → 519 lines. Still zero dependencies (pure stdlib).
File operations: get_file, create_file, update_file (unchanged API)
Issues: list, get, create, comment, find_unassigned
Pull Requests: list, get, create, review, get_diff
Branches: create, delete
Labels: list, add_to_issue
Notifications: list, mark_read
Repository: get_repo, list_org_repos
RELIABILITY
===========
- Retry with random jitter on 429/5xx (same pattern as SessionDB)
- Automatic pagination across multi-page results
- Defensive None handling on assignees/labels (audit bug fix)
- GiteaError exception with status_code/url attributes
- Token loading from ~/.timmy/gemini_gitea_token or env vars
WHAT IT FIXES
=============
- tasks.py crashed with TypeError when iterating None assignees
on issues created without setting one (Gitea returns null).
find_unassigned_issues() now uses 'or []' on the assignees
field, matching the same defensive pattern used in SessionDB.
- No module provided issue commenting, PR reviewing, branch
management, or label operations — the playbook engine could
describe these operations but not execute them.
BACKWARD COMPATIBILITY
======================
The three original methods (get_file, create_file, update_file)
maintain identical signatures. graph_store.py and
knowledge_ingester.py import and call them without changes.
TESTS
=====
27 new tests — all pass:
- Core HTTP (5): auth, params, body encoding, None filtering
- Retry (5): 429, 502, 503, non-retryable 404, max exhaustion
- Pagination (3): single page, multi-page, max_items
- Issues (4): list, comment, None assignees, label exclusion
- Pull requests (2): create, review
- Backward compat (4): signatures, constructor env fallback
- Token config (2): missing file, valid file
- Error handling (2): attributes, exception hierarchy
Signed-off-by: gemini <gemini@hermes.local>