feat(forgejo): snapshot PR diffs and files into session storage #14

Merged
lucas merged 1 commit from feat/f-9 into main 2026-10-15 17:29:15 +02:00
Collaborator

forgejo_get_pr_diff now writes the complete PR diff to session storage (local://pr-<n>@<head7>/<path>.diff). Each changed file gets its own file, with old and new line numbers in a gutter. The snapshot is pinned to the head SHA, reused on repeat calls, and comes back as a summary that lists every changed file. since_sha replaces paths and snapshots only what changed after that commit, using the compare API, raw files fetched at both SHAs, and a local git diff --no-index. forgejo_read_file_at_ref writes the file to local://tree@<sha7>/<path> and returns its size and line count. forgejo_read_pr no longer shows a partial file list. Both tools attach typed details, rendered by new web cards, and the preview gallery has a "Forgejo tools" section.

Decisions

  • git diff --no-index labels deleted files a/P a/P and added files b/P b/P, and keeps the a//b/ dirs in rename from/to lines. diffTrees rewrites these header lines into the PR-diff shape. This is the contingency the plan allowed for; renames are still detected by -M.
  • writeSnapshotDir checks whether the target exists before renaming. On Linux, rename(2) silently replaces an empty directory, which a zero-file snapshot is.
  • safeRelPath also rejects paths that contain \.
  • In since mode, too-large rows come after the files git diffed.
  • The web cards use a shared SnapshotLine (snapshot PathChip plus an inline CopyButton) and INLINE_COPY_CLASS in forgejo/ui.tsx, because the default CopyButton floats over the row and only shows on hover.
  • Repo paths containing %, # or ? are written to disk correctly, but the local:// URLs printed for them are not encoded.

Verification

  • bun test src/forgejo in apps/server: 171 pass, 0 fail. New tests cover analyzeDiffChunk, octal and C-escaped path unquoting, safeRelPath, writeSnapshotDir, writeFileAtomic, renderIndex, renderInline, toDetails, and diffTrees (added, deleted, modified, renamed, identical, and an empty old tree). The filterDiff, formatChangedFile and sliceNumberedLines tests are removed.
  • bun run typecheck at the repo root: protocol, server and web all exit 0.
  • Smoke script with a fake Forgejo client (since deleted):
    • Full mode writes the snapshot, index and manifest; the second call returns reused: true.
    • Since mode returns D and M rows with correct gutters.
    • A bad since_sha returns since_sha nope not found.
    • Without a local:// root the call returns the session-storage error.
    • Read-file writes tree@<sha7>/<path> with the right line count; a bad ref returns ref "no-such-branch" not found.
  • The SDK's resolveLocalUrlToPath maps local://pr-8@fafd5d9/..., local://pr-8@fafd5d9.md and local://tree@fafd5d9/... to the local root.
  • Web cards: every preview fixture was rendered through ForgejoTool with renderToStaticMarkup. The 3-file list is open; the 12-file list is collapsed; the 35-file case shows the note with a copy button. Flags, reused and truncated tags render, and both read-file cards render. There was no visual check in a browser: the managed Chromium can't start here because system libraries are missing.
  • Not run: the plan's live check against PR #8. It needs the deck server restarted with this change.

Closes #9

`forgejo_get_pr_diff` now writes the complete PR diff to session storage (`local://pr-<n>@<head7>/<path>.diff`). Each changed file gets its own file, with old and new line numbers in a gutter. The snapshot is pinned to the head SHA, reused on repeat calls, and comes back as a summary that lists every changed file. `since_sha` replaces `paths` and snapshots only what changed after that commit, using the compare API, raw files fetched at both SHAs, and a local `git diff --no-index`. `forgejo_read_file_at_ref` writes the file to `local://tree@<sha7>/<path>` and returns its size and line count. `forgejo_read_pr` no longer shows a partial file list. Both tools attach typed `details`, rendered by new web cards, and the preview gallery has a "Forgejo tools" section. ## Decisions - `git diff --no-index` labels deleted files `a/P a/P` and added files `b/P b/P`, and keeps the `a/`/`b/` dirs in `rename from/to` lines. `diffTrees` rewrites these header lines into the PR-diff shape. This is the contingency the plan allowed for; renames are still detected by `-M`. - `writeSnapshotDir` checks whether the target exists before renaming. On Linux, `rename(2)` silently replaces an empty directory, which a zero-file snapshot is. - `safeRelPath` also rejects paths that contain `\`. - In since mode, `too-large` rows come after the files git diffed. - The web cards use a shared `SnapshotLine` (snapshot `PathChip` plus an inline `CopyButton`) and `INLINE_COPY_CLASS` in `forgejo/ui.tsx`, because the default `CopyButton` floats over the row and only shows on hover. - Repo paths containing `%`, `#` or `?` are written to disk correctly, but the `local://` URLs printed for them are not encoded. ## Verification - `bun test src/forgejo` in `apps/server`: 171 pass, 0 fail. New tests cover `analyzeDiffChunk`, octal and C-escaped path unquoting, `safeRelPath`, `writeSnapshotDir`, `writeFileAtomic`, `renderIndex`, `renderInline`, `toDetails`, and `diffTrees` (added, deleted, modified, renamed, identical, and an empty old tree). The `filterDiff`, `formatChangedFile` and `sliceNumberedLines` tests are removed. - `bun run typecheck` at the repo root: protocol, server and web all exit 0. - Smoke script with a fake Forgejo client (since deleted): - Full mode writes the snapshot, index and manifest; the second call returns `reused: true`. - Since mode returns D and M rows with correct gutters. - A bad `since_sha` returns `since_sha nope not found`. - Without a `local://` root the call returns the session-storage error. - Read-file writes `tree@<sha7>/<path>` with the right line count; a bad ref returns `ref "no-such-branch" not found`. - The SDK's `resolveLocalUrlToPath` maps `local://pr-8@fafd5d9/...`, `local://pr-8@fafd5d9.md` and `local://tree@fafd5d9/...` to the local root. - Web cards: every preview fixture was rendered through `ForgejoTool` with `renderToStaticMarkup`. The 3-file list is open; the 12-file list is collapsed; the 35-file case shows the note with a copy button. Flags, `reused` and `truncated` tags render, and both read-file cards render. There was no visual check in a browser: the managed Chromium can't start here because system libraries are missing. - Not run: the plan's live check against PR #8. It needs the deck server restarted with this change. Closes #9
forgejo_get_pr_diff writes the whole PR diff to local:// as one
line-numbered .diff per changed file, pinned to the head commit and reused
on repeat calls, and returns a summary listing every changed file.
since_sha replaces paths and snapshots only what changed after a commit.
forgejo_read_file_at_ref snapshots the file to local://tree@<sha7>/<path>;
forgejo_read_pr drops its truncated file list. Both tools get web cards
and preview fixtures.

Refs #9

Co-Authored-By: Claude Opus 5.5 via omp-deck
lucas merged commit 23c4efe512 into main 2026-10-15 17:29:15 +02:00
lucas deleted branch feat/f-9 2026-10-15 17:29:16 +02:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
lucas/omp-deck!14
No description provided.