32 Commits

Author SHA1 Message Date
b46dd3a72b Complete TASK-022: tolerate incomplete Gitea branch timestamps
Continues Codex's paused in-progress fix in this worktree (confirmed
safe to pick up by the human product owner). A missing or malformed
branch commit timestamp no longer fails the whole branch page; the
latest-branch picker now filters to branches with a known timestamp
before selecting the max, and reports Failed (not Empty) when none
are known. Adds the one missing test case from the in-progress
coverage (all branches with unknown timestamps) plus an explicit
test proving the reference screen never depended on the field.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 22:19:39 +09:00
ca8620958a feat: sort repositories by recent update 2026-08-26 21:48:07 +09:00
5e414a663a fix: use saveable repository list keys 2026-08-26 21:33:07 +09:00
5778dc9b2a fix: recover safely from OAuth callback failures 2026-08-26 18:41:17 +09:00
31b43c6466 Add TASK-016: partial release hardening
Fixes the recorded P3 CodeBrowserViewModel Main-dispatcher issue,
scans the whole repo for secrets, and reviews the manifest/backup/
token-storage security posture. Minification and any authenticated-
screen device regression are explicitly left blocked: this agent
cannot enter a password to complete Gitea login, confirmed with the
human product owner rather than silently skipped.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 16:44:59 +09:00
f14be3ac90 Add TASK-015: read-only Gitea notifications
Signed-in users can view notifications (unread-only or all), paginated,
and jump from an issue/PR notification to that repository's work items.
No mark-read/unread/pinned write endpoint is exposed, matching the
existing single-write-scope posture from ADR-004.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 15:55:19 +09:00
4fe3bf1c9f Implement TASK-014: organizations and repository org filter
Adds read-only GET /user/orgs and GET /orgs/{org}/repos to
GiteaRepositoryBrowserApi (a third interface, OrganizationsRepository),
reusing existing repository mapping rather than duplicating it.

Repository list gains an organization filter chip row (all + one per
org), keeping the existing recent-push sort and paging. Organizations
are fetched once per session and cached; a failure to load them
degrades to an empty filter row instead of blocking the repository
list itself. Filtering only applies to the all-repositories mode,
since Gitea star is not organization-scoped.

Closes MVP outcome #2 in docs/product.md. No task file existed
beforehand; created it first per AGENTS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 15:34:22 +09:00
7756ec4d7e Implement TASK-013: typed application navigation
Replace MainActivity's three independent booleans (browsingCode/
browsingHistory/browsingWorkItems) with one typed List<Route> back
stack, restorable through configuration change and process death.

Route holds only stable primitives (owner/name/ref/ref-kind), never
tokens or content. A genuine LIFO stack, not just a refactor: back now
correctly unwinds through arbitrarily nested screens instead of
relying on which boolean happened to still be true underneath another.

No task file existed for this task beforehand (only proposed in an
earlier handoff document); created it first per AGENTS.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 15:19:56 +09:00
c397fbeea9 Implement TASK-008: pull-request and issue read-only UI
Separate issue and PR list/detail tabs, paginated, with comments
(issues) and reviews+comments (PRs). Deleted/unavailable authors
render a fixed placeholder instead of crashing or inventing identity;
every status is a text label, never color-only.

Reuses TASK-010 directly; no shared/domain file touched. Both list
types dedupe by number per page. Entry point is a new button on the
repository references screen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 15:08:26 +09:00
429668bf26 Implement TASK-007: commit history and change viewer UI
Paginated commit history for the current ref, commit detail with
distinguished added/modified/deleted/renamed file status, bounded and
explicitly-truncated patch text, and a ref comparison flow validating
one entered ref against the currently open ref as base.

Reuses TASK-004's listCommits and this session's own TASK-009
HistoryRepository; no shared/domain file touched. Entry point is a new
history button on the existing code browser header.

Self-review caught and fixed a bug before writing tests: a failed
commit-detail fetch discarded which commit had failed, so retry
silently reloaded the whole list instead of re-fetching the commit the
user tried to open.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 14:56:43 +09:00
3c17476e92 Implement TASK-009: commit history and diff read-only API contracts
Implemented directly at human product owner's direction, independent
of Codex's separate uncommitted attempt at the same task (not read or
referenced here).

- CommitDetail (reusing CommitSummary) with per-file added/modified/
  deleted/renamed/other status; deleted-author and missing-rename-path
  cases handled without crashing or inventing data.
- BoundedPatch for commit and comparison diffs, sourced from Gitea's
  .diff raw-text endpoints (JSON commit/compare objects only carry
  file status, not diff content); byte limit then line limit, both
  constructor-injected and validated positive.
- Comparison uses one combined base...head path segment, built by
  concatenating both refs before a single addPathSegment call so each
  is escaped exactly once; pagination computed locally since Gitea's
  compare endpoint has no server-side paging.
- Reuses Page<T> and ApiFailure; no put/delete/postForm call anywhere
  in the file (read-only, as required).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 14:17:54 +09:00
7d122d4388 Implement TASK-010: pull-request and issue read-only API contracts
Frozen domain/data contracts for issues, pull requests, reviews, and
comments so TASK-008's UI can be built without touching shared layers.

- Separate immutable IssueSummary/Detail and PullRequestSummary/Detail
  models; WorkItemAuthor.Unavailable instead of inventing an identity
  for deleted/null authors.
- PullRequestState derived from Gitea's merged flag + open/closed
  state (no single field already encodes "merged").
- listIssues drops entries with a non-null pull_request field so
  Gitea's issue-list endpoint (which also returns PRs) never
  duplicates listPullRequests, done client-side rather than trusting
  an unverified query parameter.
- Reuses existing Page<T> and ApiFailure rather than new parallel
  types. Read-only: no put/delete/postForm call anywhere in the file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 14:08:21 +09:00
525a0aa2ff Add Favorites tab backed by Gitea star (first write endpoint)
TASK-018, human product owner priority-1 request. Adds write:user
OAuth scope (ADR-004) and relaxes OAuthClientConfig's read-only guard
to an explicit, hard-coded write-scope allow-list rather than a
general write-scope allowance. GiteaRepositoryBrowserApi gains star/
unstar/listStarred via a new RepositoryFavorites interface, reusing
its existing repository mapping. RepositoryListViewModel tracks an
ALL/FAVORITES mode; toggling favorite confirms against the server
before updating UI state rather than acting optimistically.

No create/edit/merge/close/comment endpoint is introduced. Favorite
state is never cached locally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 13:51:04 +09:00
93b8d587ee Sort repositories by recent push, page the list, show last-pushed branch
TASK-017, human product owner priority-1 request. Repository list now
requests sort=updated&order=desc from Gitea, loads 5 repositories per
page with explicit prev/next navigation, and each visible row
independently fetches and shows its most recently committed branch.

Removes the legacy eager-loading RepositoryListApi in favor of the
existing paged GiteaRepositoryBrowser.listRepositories. Fixes two
issues found in self-review: missing error handling on page
navigation, and repositories with no default branch (empty repos)
previously failing the whole page instead of just that row.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 13:24:31 +09:00
fdda16442a Review and freeze TASK-004/005/006; fix 409/422 typed failures
Independent read-only review of 8a47d30/bbbff77/16c46a5 per
handoff/claude-master-handoff.md's review-and-freeze step. Verified
build/test/lint independently rather than trusting recorded evidence.

Fixed P2: requireSuccess() collapsed HTTP 409/422 into the generic
InvalidResponse, which would have blocked TASK-007's planned
conflict/unprocessable error states. Added ApiFailure.Conflict and
ApiFailure.Unprocessable with test coverage.

Recorded a P3 (CPU-bound work on the Main dispatcher in
CodeBrowserViewModel) for TASK-016 rather than fixing it now. Closed
TASK-005/006's mutual contract-freeze checkboxes. No P0/P1 found.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 12:54:46 +09:00
16c46a5c54 feat: browse repository source by ref 2026-08-26 10:35:20 +09:00
bbbff77a5e feat: browse repository branches and tags 2026-08-26 10:24:19 +09:00
8a47d30ab5 feat: add read-only repository browsing API 2026-08-26 10:13:22 +09:00
ed2121be76 fix: preserve Unicode boundaries in source preview 2026-08-26 09:54:02 +09:00
4f5faf373a Implement TASK-006A source content classifier
Pure-Kotlin classifier for feature/codebrowser/content/ that turns
already-loaded SourceContent bytes into bounded text, binary, Git LFS
pointer, unsupported-encoding, or oversized results with caller-supplied
positive byte/character/line limits, per handoff/task-006a-ready.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 09:48:39 +09:00
965d55d760 docs: activate Claude TASK-006A handoff 2026-08-25 23:29:20 +09:00
57d1c090b1 docs: add Codex Claude handoff workspace 2026-08-25 23:27:21 +09:00
fc9d78a2d6 docs: record repository login E2E verification 2026-08-25 23:22:30 +09:00
a4451e9d16 feat: add Gitea login and repository list 2026-08-25 23:21:47 +09:00
fd052654cf Record TASK-002A development handoff 2026-08-25 22:13:36 +09:00
6da016cf7b Implement OAuth PKCE protocol core 2026-08-25 22:13:23 +09:00
177786ef11 Adopt serial agent handoff workflow 2026-08-25 22:04:29 +09:00
29faab8a97 Assign code content classifier to Claude 2026-08-25 22:02:37 +09:00
09292823e4 Define Codex and Claude workstreams 2026-08-25 21:57:53 +09:00
a2cc7d4ca3 Add repository browsing domain foundation 2026-08-25 21:52:40 +09:00
75aa5f83e5 Bootstrap Android Compose application 2026-08-25 21:42:50 +09:00
dd9a70839c chore: initialize UBGitea engineering harness 2026-08-25 21:18:26 +09:00