~bigbes/sr-ht-dolt

ref: 4d178626e1f2d04330127c394e0684a78a2d7102 sr-ht-dolt/web/templates d---------
17fa0f16 — Eugene Blikh 9 days ago
web: render through ecore's pages and its error page

The page list, the per-page parse loop and the view-template loop are
gone: pages discovers every file in templates/, so a page is registered
by existing, and one that defines no content block is refused at startup
rather than served as chrome around a hole. 404.html and 403.html are
gone with them — the shared error page carries the same body, and its
prose is deliberately the same for a database that is not there and one
the viewer may not see.

The renderer that replaced them closes a leak: the old one wrote
"template render error: "+err.Error() into the response body, handing
the viewer template names and field paths. pages answers a fixed
sentence and returns the error for the log.

reltime and abstime come from chrome.Funcs now; ours called every future
instant "just now", where the shared one says "in 3 weeks".
bf7897cd — Eugene Blikh 9 days ago
web: draw the chrome from sr-ht-ecore

The brand, the service switcher, the login block, the environment banner
and the database listing were a local port of core.sr.ht's nav — one of
five such ports on this instance, and they had already drifted. They are
now sourcecraft.dev/bigbes/sr-ht-ecore/chrome, the one copy every custom
service draws from.

Deleted: web/chrome.go entire (navEntry, networkOrder, networkExcluded,
buildNetwork, basePage, loginURL, logoutURL), templates/nav.html,
templates/icons/circle.svg (ecore inlines the identical SVG), the
repoList partial, and the local dict/shortHash duplicates.

Added: one chrome.Service built in newApp from our config section with
the hashed stylesheet href set on it, a chrome.Page per request through
app.page, chrome.Attach on every template set, and chrome.Funcs as the
base of the funcmap. Handlers embed chrome.Page in their view structs
instead of copying its fields; the row browser sets ContainerClass to
container-fluid, since its column count is the table's and not ours.

Three behaviour changes come with ecore's policy, all deliberate: the
profile link now prefers hub's ~username page when hub.sr.ht is
configured (it was always meta's /profile), the brand carries a fixed
15rem min-width so the switcher starts at the same x on every service,
and a binary built without a stylesheet renders bare rather than linking
an empty href. The nav test went with the code it tested — ordering,
exclusions and login URLs are ecore's to cover — and what replaced it
asserts only what is ours: that pages are drawn through the chrome at
all, and that the row browser is full-bleed.

The auth path is untouched: a foreign bearer token is still accepted as
a meta.sr.ht PAT.
25541bcd — Eugene Blikh 9 days ago
gitignore the in-repo git worktree directories

Agent worktrees are created under .worktrees/<branch> (and, in the older
repos of this family, .claude/worktrees/<branch>) so that they never
scatter as sibling directories next to the checkout. Neither path was
ignored here, so a worktree showed up as untracked in every git status
taken from the main checkout.
bb8ce43b — Eugene Blikh 11 days ago
web: restyle dashboard and database lists after git.sr.ht

Replace the bare 'Your databases' heading and compact grid with the
git.sr.ht dashboard layout: a sidebar column with a welcome blurb plus
block buttons (create database, configure dolt credentials), and the
shared event-list cards for the database list. The repoList partial now
renders each database as an event card — name, visibility as small
muted text (non-public only, like git.sr.ht), description below — and
the profile page picks the same partial up automatically.

Adds a 'lower' template func for the visibility label and drops the now
unused .repo-list grid from main.scss (.event-list ships with the core
theme already).
8527f0fd — Eugene Blikh 13 days ago
feat(web/beads): hierarchy in the milestone view

Arrange each milestone as a shallow hierarchy instead of a flat list.
- Put the milestone-typed issue(s) on top as the milestone's heads.
- Nest tasks under their epics via parent-child dependency edges,
  with a done/total rollup on the epic row; membership stays label-based.
- Keep remaining members as a loose tail; blocks edges are ignored.
- Read the dependencies table optionally, degrading to a flat list.
- Extend fixtures and real-data logging to cover the hierarchy.
8e89f8a0 — Eugene Blikh 29 days ago
feat(web/beads): promote milestones to their own view/tab

Move the milestone rollup off the board and into a dedicated "Milestones" tab
(a registered View, companion to Beads via the same fingerprint). The tab is
richer than the old board panel: per-milestone progress bar, done/open/in-progress
counts, and the issue list under each milestone (open-work first, closed struck
through), each linking to its beads detail. Issues with no milestone label are
summarized in a footnote. A beads DB with no milestone labels still gets the tab,
showing an empty-state hint.

Removes the board's inline milestone panel and the collectMilestones/BeadMilestone
helpers it used; the grouping now lives in the milestones view.
5c5479c4 — Eugene Blikh 29 days ago
feat(web/beads): ready markers, milestone rollup, transitive dependency tree

Three additions surfacing more of the bd data model:

- Ready: a ⚡ marker on actionable-now cards and a "Ready only" board filter.
  "Ready" mirrors bd's ready set exactly — open, unblocked, not template/
  ephemeral. As part of this, parent-child edges no longer count as blockers
  (a subtask is not blocked by its open epic), which was over-filling Stalled
  and under-counting ready; the board now matches bd's is_blocked/ready
  accounting (verified: 111 ready on tarantool-etcd, == ready_issues).

- Milestone rollup: a board panel with per-"milestone:<name>" label progress
  bars (done/total), each linking to that label's filtered board.

- Transitive dependency tree on the detail page: the full prerequisite chain
  ("everything this waits on") and the reverse ("everything this unblocks"),
  walked from the edge set with depth/'node caps and cycle guard, indented by
  depth. Shown only when it reaches past the direct edges, so it never just
  repeats the flat Depends-on / Depended-on-by lists.
88a1d379 — Eugene Blikh 29 days ago
feat(web/beads): filters for the parade board

Add a filter bar to the beads board: text search (id/title), issue type,
priority, assignee, and label. Filters are query-param based (GET, sticky
across submits) and applied server-side before lane bucketing, so the marquee
counts reflect the filtered set. Dropdown options are collected from the full
issue set (they don't shrink as filters narrow the board); a Clear link shows
when any filter is active. Verified on the 143-issue tarantool-etcd board
(type=bug → 30).
57832d6c — Eugene Blikh 30 days ago
feat(web/beads): close reason in Comments tab; synthesize subtask-add history

- Close reason placement: show it as a block at the end of the Comments tab
  (which carries no closed event), while the History tab shows it inline as the
  closed event — so it appears in whichever tab you're on, without duplication
  within a tab. (Reverts the outright removal.)

- History now includes dependency/subtask additions. beads logs no audit event
  for a link, but the dependencies row records created_at/created_by, so
  buildDetail synthesizes "added subtask X" / "added dependency on X" timeline
  entries (Kind "dep", own accent). On an epic this surfaces when each child was
  linked. Guarded on created_at so older schemas without it emit nothing.

- pre.field-body style de-scoped from .bead-detail so the Comments-tab close
  reason wraps (overflow-wrap: anywhere) instead of overflowing.
1b35456a — Eugene Blikh 30 days ago
refine(web/beads): concise label events, drop standalone close reason, wrap long lines

- Label audit events collapse to one line ("added label milestone:m3") instead
  of a "label added" header plus a redundant "Added label: …" body. The label
  name is taken after the first colon so namespaced labels survive.
- Remove the standalone Close reason block below the activity: the reason
  already shows as the History tab's `closed` event, so it was a duplicate.
- Add overflow-wrap: anywhere to the timeline body, comment body, and
  field-body pre so a very long single-line reason wraps instead of overflowing.
2ee66fb8 — Eugene Blikh 30 days ago
feat(web/beads): epic view with subtask rollup, tabbed Comments/History

Three additions to the beads issue detail:

- Epic mode: when the viewed issue is issue_type=epic, render a Subtasks panel
  — its parent-child children (deps pointing at the epic) with a done/total
  progress meter, sorted open-work-first with closed sinking to the bottom.

- Activity is now a two-tab strip (pure-CSS, no JS): Comments keeps the plain
  thread; History merges comments and the audit-log events table into one
  time-sorted timeline with humanized change lines ("changed status to
  in_progress", "updated priority to 0", "closed the issue" + reason).

- Close reason moved from the top metadata table to its own block at the very
  bottom, after the activity — it reads as a closing note, not a header field.

Verified end-to-end against a real 143-issue beads store (tarantool-etcd) via
the env-guarded TestRealBeadsStore smoke test; unit-covered with a dedicated
epic/history fixture.
b7e8d134 — Eugene Blikh 30 days ago
feat(web): Overview/Tables/Beads tab bar + full issue fields on beads detail

Give every database page a consistent three-tab bar — Overview, Tables,
then the applicable views (Beads) — in that order. Previously the bar only
carried [views, Tables] and the Overview page marked Tables active, so there
was no way to tell you were on the overview. viewtabs now takes an explicit
Current sentinel ("overview" | "tables" | view slug) and the tree/table row
pages render the bar too (handlers compute applicable views for the ref).

Surface the issue fields the beads detail pane was dropping. The closure
reason (close_reason) recorded by `bd close -r` was never shown; auditing
against bd's own field set also turned up estimated_minutes, external_ref,
spec_id, and started_at. All render conditionally, so issues that don't set
them stay uncluttered.
51a5acf9 — Eugene Blikh 30 days ago
style(web): restyle the beads parade in the todo.sr.ht idiom

The board still read as a rounded-card kanban from another app. Re-skin
every surface in sourcehut's own issue-tracker language (todo.sr.ht):
flat and square — no border-radius, no shadows, no tints — hairline gray
borders, monospace ids, striped-on-hover rows instead of cards, and
squared bordered labels (the sourcehut .label: 1px border, no radius).
The summary becomes a flat hairline strip and each lane a squared column
with a 2px accent cap. The Mardi Gras hues survive only as small square
swatches and the lane cap, never as fills, so the view looks like a
native sourcehut tracker in both the light and dark themes. Verified via
a headless light/dark render. Test asserts the renamed summary class.
76bf70dd — Eugene Blikh 30 days ago
fix(web): make the beads view inherit the SourceHut theme

The beads board shipped its own Mardi Gras palette — a purple→green
marquee gradient and saturated solid lane fills — that clashed with
SourceHut's flat, utilitarian dark theme, and the detail pane's field
labels were a hardcoded dark purple with no dark-mode override, leaving
"Created by / Owner / Description" unreadable on the dark background.

Drive everything from CSS variables that mirror core.sr.ht's Bootstrap
palette for both the light default and the prefers-color-scheme: dark
variant sourcehut ships (the same media query it uses), so the view
inherits the host theme instead of fighting it. Lane hues become muted
Mardi Gras accents (gold/green/violet/gray) used only as thin borders and
low-alpha tints — never as body text — so contrast holds on either theme.
The marquee is now a flat stat row, lanes an understated panel with an
accent underline, and detail labels a readable muted caption. Verified
light and dark via a headless render.
8f5ae3f0 — Eugene Blikh 30 days ago
feat(web): Mardi Gras beads view

Render a beads (bd) issue database as a Mardi Gras parade board: four
lanes — Rolling (in progress), Lined Up (open & ready), Stalled (open &
blocked), Past Stand (done) — plus a marquee of per-lane counts. Cards
show id/title/type/priority/assignee/labels and blocked-by/blocks counts;
an issue-detail pane (?issue=<id>) shows the full issue with its
dependency edges in both directions and its comments thread.

Fingerprints on the issues + dependencies tables and reads everything
through the browse layer (column-name-keyed, so column order is
irrelevant), capped at 2000 rows/table. Status is bucketed via
custom_statuses with name heuristics as a fallback; "blocked" means
is_blocked or an open blocking dependency. Plugs into the view registry
via init()+RegisterView with no framework edits. Purple/gold/green
palette scoped in the template (no scss rebuild needed).
4520d5cf — Eugene Blikh 30 days ago
feat(web): pluggable alternative-view registry for repositories

A repository can now expose specialized, read-only "views" chosen by the
shape of its tables, while the generic table browser stays available as a
fallback. A View fingerprints the tables (Applies), builds a model from
the browse layer (Build), and renders its own template; views register at
init time via RegisterView and are dispatched by slug at
/~user/db/view/{slug}. The overview shows a tab per applicable view.

The template loader parses each registered view's template with the
shared chrome, so a new view plugs in by adding two files (its .go with
init()+RegisterView and its .html) plus nothing else — no edits to the
registry, router, loader, or handlers. Build receives the request query
values so a view can offer sub-modes (e.g. a detail pane). No SQL engine
is involved; views read through the existing BrowseSession surface.
944a35e9 — Eugene Blikh a month ago
web: router, handlers, and sourcehut chrome

Chi route table per plan, SourceHut chrome port (nav/layout from
core.sr.ht Bootstrap structure), dual-flow clone box, dolt-key
association page with hash-fragment prefill, same-origin CSRF checks.
Handlers depend on small injected interfaces (StoreManager, RepoStore,
BrowseOpener, UserResolver) with production adapters included.