~bigbes/sr-ht-compare

9df88758 — bigbes 30 days ago
web: tighten diff and file-tree spacing

Address three spacing complaints in the compare view:

- File tree: switch @pierre/trees to the "compact" density preset (24px
  rows, 0.8 factor) so folder/child rows read as a dense index rather
  than an airy list.
- Diff blocks: drop the inter-file gap (.diff-file margin-bottom
  1rem -> .5rem) and the tree/diff column gap (1rem -> .75rem).
- File tree height: size the mount to its content height (capped at the
  viewport) instead of always filling the viewport, removing the band of
  empty tree background below the last file. Re-measures on resize and on
  every tree change (expand/collapse) via tree.subscribe.

Rebuilt and re-hashed the embedded bundle and stylesheet.
5ca23c05 — bigbes 30 days ago
web: content-hash the bundle and colour the status column

Two diff-view fixes reported against the deployed instance.

Empty file tree after an upgrade: bundle.js had a stable filename served with a
1-hour cache, so browsers kept a pre-fix bundle and the @pierre/trees sidebar
rendered blank. Content-hash the bundle like the stylesheet — Makefile emits
bundle.<sha256[:8]>.js, server.go globs it into a BundleHref, the templates
reference {{.BundleHref}}, and the hashed name is served immutable. A deploy now
always busts the cache.

Unreadable status column: the changed-files table rendered A/M/D in the dim
default cell colour, near-invisible on the dark chrome. Render each status as a
semantic .diff-status badge (added=green, modified=amber, deleted=red,
renamed=blue) with light/dark variants, via statusClass/statusLabel helpers and
a small self-contained style block (the sourcehut-derived main.min.css can't be
rebuilt locally).

Tests resolve the hashed bundle via a bundleName helper and assert its immutable
cache header; docs updated for the hashed filename.
53d7b970 — bigbes 30 days ago
docs: note that static assets are embedded and need a rebuild

web/static is //go:embed-ed into the binary, so `make css`/`make bundle` alone
don't reach the running daemon — re-run `make build` after either. Documents the
stale-asset gotcha in the build section.
4a741216 — bigbes 30 days ago
docs: spec for inline code comments on diffs

Draft proposal for line-anchored comment threads on the commit and compare
pages. Records the key finding that storage is already available through
sr-ht-core (Postgres via the database package + connection-string), that the
service is stateless by choice rather than by limitation, and that @pierre/diffs
already provides the thread UI primitives (DiffLineAnnotation + renderAnnotation
+ onDiffLineClick). Covers the anchoring model, schema, authz reuse, HTTP API,
frontend wiring, config, and a commit-first phasing.
4e7c6329 — bigbes 30 days ago
web: full-width split diff view with a rendered file tree

Make the commit and compare pages full-bleed and default to the side-by-side
(split) diff, so the layout matches a conventional diff viewer: file tree on
the left, split diff on the right.

- layout.html renders the content wrapper with a per-page ContainerClass;
  chrome() defaults it to "container" and the commit/compare handlers set
  "container-fluid" for the diff views (the nav stays centered).
- app.ts defaults DEFAULT_LAYOUT to "split".
- Fix the @pierre/trees sidebar rendering blank: its virtualized container
  collapses to zero height unless the mount has a definite height, so
  sizeTreeRoot() gives #tree-root a viewport-height panel (re-applied on
  resize). Rebuilt the vendored bundle.
a4853d05 — Eugene Blikh 30 days ago
rename module to sourcecraft.dev/bigbes/sr-ht-compare; depend on sourcecraft sr-ht-core
c1ae0fc5 — bigbes 30 days ago
go.mod: tidy and complete the README

go mod tidy promotes fernet-go and vaughan0/go-ini from indirect to
direct (the cmd entry point imports go-ini and the smoke test imports
fernet) and drops stale transitive checksums for AWS S3/CLI packages that
core-go pulls but compare.sr.ht never imports. The require block is
otherwise unchanged; build and tests stay green.

README: correct the architecture to reflect the go-git in-process backend
(no runtime git shell-out), document the full local development recipe
(config.ini template, key generation, dev-stub, forging a login cookie),
the deployment steps (install, config propagation for nav, DNS,
internal-ipnet, nginx, User=git systemd), and design notes recording the
go-git decision, the 10 MB bundle rationale, and the pending LICENSE.
6db8684c — bigbes 30 days ago
cmd/comparesrht: daemon entry point, startup validation, dev stub

Wire the compare.sr.ht daemon on core-go's server.New: it runs
crypto.InitCrypto, parses -b/-d/-m/-p, and drives the standard SourceHut
warm-shutdown loop (SIGINT). We deliberately skip WithDefaultMiddleware
(it demands Postgres/Redis and 401s anonymous viewers) and instead
install the web package's documented middleware chain — RealIP, Recoverer,
Logger, config.Middleware, authz.Middleware — inside a Group on the
anonymous router.

validateConfig checks every required key up front (network-key, webhook
key, repos root, a git.sr.ht API origin candidate, meta and compare
origins) with a single clear fatal, so a misconfiguration fails loudly at
startup rather than as a deep panic in config.GetAPI on the first request.

A build-and-exec smoke test proves the binary starts against a synthesized
config, answers /healthz 200, and exits cleanly on SIGINT in under 15s.

Makefile: build ./comparesrht from ./cmd/comparesrht, run-dev binds
localhost:5090 against a local config.ini, install ships the binary and
static assets. contrib/dev-stub is a stdlib-only fake git.sr.ht GraphQL
API returning fixed public repos for local development, and the systemd
unit now stops with KillSignal=SIGINT to hit the warm-shutdown path.
71475299 — bigbes a month ago
web: http server, sourcehut chrome, compare/commit pages

Implement the compare.sr.ht HTTP layer over the committed core/gitx/authz
packages:

- Server assembly (New) from shared SourceHut config: [git.sr.ht] repos,
  [meta.sr.ht]/[compare.sr.ht] origins, [sr.ht] site-name/environment, and
  the hashed stylesheet resolved by globbing the embedded static FS.
- Routes: landing, repo page, compare (base..base...head, .patch escape
  hatch), single-commit (+.patch), embedded static assets, healthz. Compare
  form GET canonicalizes to a clean URL via 302.
- SourceHut chrome port to html/template: nav service switcher (canonical
  order, paste/pages/hub excluded, compare active), login/logout with
  return_to, environment banner.
- Embedded compare-data JSON (template.JS so html/template's script-context
  escaper leaves it verbatim; json.Marshal's HTML escaping blocks a
  </script> breakout) plus the vendored bundle.js scaffold.
- httptest coverage with a stub Authorizer and a real git-CLI fixture repo.

The cmd layer must wire, in order: RealIP, Recoverer, Logger,
config.Middleware(conf,"compare.sr.ht"), authz.Middleware.
9473e260 — bigbes a month ago
gitx: repository access and ref-to-ref diffs on go-git

Implement the git access layer for compare.sr.ht on go-git v5 (no runtime
git binary). Public surface: Open (owner/name validated via core, bare-repo
HEAD check, ErrNotFound on any miss); Refs/DefaultBranch; ResolveCommit/Log/
Parents; Diff/RawDiff/DiffStat/MergeBase/CommitPatch.

- Diffs route through DiffTreeWithOptions(DetectRenames) so old/new tree order
  is explicit: three-dot uses the merge base as old side, two-dot uses base;
  CommitPatch diffs a commit against its parent (root vs empty tree, merge vs
  first parent, ParentSHAs exposed for the banner).
- Patch text is generated in memory then capped (5 MiB page, 50 MiB raw,
  injectable override for tests) and cut at a "diff --git" file boundary so the
  browser parser never sees a torn hunk; ctx timeout (10s) guards runaways.
- FileChange status/counts/binary derived purely from go-git FilePatches
  (mapFilePatches); Log excludes base's full reachable set for correct
  base..head semantics.

Tests build fixtures by driving the real git CLI in t.TempDir(). Fidelity gate
(TestPatchFidelity) confirms go-git emits standard git headers — diff --git,
index, rename from/to, "Binary files ... differ", @@ hunks — parseable by the
frontend parsePatchFiles(). 82% coverage.

core validators reject ^/~ so navigation revs are resolved to SHAs in tests.
94142bd8 — bigbes a month ago
frontend: pierre diffs/trees bundle and sourcehut theme css

Vendored esbuild bundle (frontend/src/app.ts) rendering @pierre/diffs
FileDiff per file and a @pierre/trees FileTree sidebar against the SSR
#compare-data contract, plus scss/main.scss (base + compare views)
compiled and content-hashed into web/static/.
0f5e8de5 — bigbes a month ago
authz: unified-login identity and git.sr.ht GraphQL authorization

Add the authz package: cookie-derived identity and per-request repository
authorization delegated to git.sr.ht's internal GraphQL API, with no local
database.

- identity.go: UsernameFromRequest decrypts the sr.ht.unified-login.v1 Fernet
  cookie to a bare username ("" for anonymous, never rejects); Middleware/
  ForContext carry it in the request context.
- authz.go: Authorizer interface + GQLAuthorizer over core-go client.Do. Repo
  strips a leading ~ from the owner, maps null user/repository to
  core.ErrNotFound (never leaking existence) and transport/GraphQL failures to
  a wrapped non-NotFound error. MyRepos paginates me{repositories} to a 500-repo
  cap. A mutex-guarded TTL cache memoizes positive and not-found Repo results
  (keyed viewer\0owner\0name) but never transport errors, with lazy expiry and
  opportunistic sweeps.
- Tests: in-memory config (generated Fernet + ed25519 keys) + httptest server
  asserting the Internal auth header decrypts to the expected viewer; covers
  cookie round-trip, found/null/500 repo cases, per-viewer cache keying, TTL
  expiry, transport-error non-caching, and MyRepos pagination.
e1835fae — bigbes a month ago
compare.sr.ht: project foundation — core package, build scaffolding, core-go fork pin

Bootstrap the go.bigb.es/sourcehut-compare service:

- go.mod (go 1.26.4) pinning core-go to the private fork
  git.srht.bigb.es/~bigbes/core-go @ c2c2f3848fa9 via a replace directive;
  go.sum populated by a throwaway smoke build importing core-go
  config/crypto/client/server + chi + logrus (gates API drift from the
  verification baseline fdb3662 to upstream 71b2787).
- core/: pure domain package — sentinel errors, owner/repo/ref validation
  (check-ref-format-style, hostile-input hardened), and the compare-spec
  grammar (ParseCompareSpec, three-dot/two-dot, percent-unescape). Table
  tests at 97% coverage.
- Makefile (all/build/test/css/bundle/run-dev/install), config.example.ini
  documenting the shared keys read in place, contrib/ nginx block and
  systemd unit, README skeleton, .gitignore.

core-go dep deps and go mod tidy are deferred to later phases per plan.