Commit log

a96414e fix(web): resolve remaining non-story lint warnings

Click to expand commit body
- Fix unsafe type assertion in file-viewer: use instanceof check
  for click target, suppress shiki dynamic import casts with comments.
- Suppress no-unassigned-import in apollo-client.d.ts (declaration merging).
- Remove unused LabelColor and BrandedLabel types from label-editor story.

Remaining 31 warnings are all in story files: oxlint can't resolve
makeFragmentData's generic constraint with optional $fragmentName.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

61e7ff4 fix(web): resolve fragment masking type warnings in routes and auth

Click to expand commit body
- Select fields directly alongside fragment spreads in route queries
  so they're accessible without unmasking (BugSummary, IdentitySummary,
  LabelFields in bug list, bug detail, and user profile queries).
- Fix useAuth query to spread ...IdentitySummary with direct field
  selections instead of @unmask (preserves $fragmentRefs brand).
- Fix StatusFilter | null type in applyFilters.
- Fix CommentData type to union of create + add-comment fragments.

Lint warnings: 148 → 33 (remaining are oxlint limitations with
makeFragmentData generics in stories + eslint unsafe assertions in
file-viewer).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

558ddfb refactor(web): switch to codegen useFragment, fix storybook + types

Click to expand commit body
- Replace Apollo's useSuspenseFragment with codegen's useFragment
  (zero-cost cast) for all fragment-consuming components. Apollo's
  useSuspenseFragment can be used selectively later for @defer support.
- Set dataMasking: false — fragment colocation is enforced at the type
  level via codegen's $fragmentRefs branding (inlineFragmentTypes: "mask").
- Add apollo-client.d.ts with GraphQLCodegenDataMasking TypeOverrides.
- Add withApollo + withCachedFragments storybook decorators for stories
  that use Apollo hooks (useAuth, useMutation).
- Use makeFragmentData in stories for proper fragment type branding.
- Mock useSuspenseFragment as passthrough in snapshot test setup.
- Add timeline and title-editor stories + snapshot tests.
- Fix useAuth query to spread ...IdentitySummary alongside direct fields.
- Fix lint: route property order, storybook meta component/title.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

dab57be refactor(web): apply fragment colocation to timeline and code browser

Click to expand commit body
- Timeline: define TimelineItems fragment on BugTimelineItemConnection,
  receive masked data via `timeline` prop, unmask with useSuspenseFragment
- FileViewer: define FileViewerBlob fragment on GitBlob, receive masked
  data via `blob` prop
- FileTree: replace wide GitTreeEntry import with local interface (data
  comes from two merged queries, fragment doesn't fit)
- BugDetail query now spreads ...TimelineItems instead of inlining
- Blob query now spreads ...FileViewerBlob instead of inlining

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

8bb7f67 refactor(web): add GitRefFields fragment for ref-selector

Click to expand commit body
Define a GitRefFields fragment in ref-selector.tsx and use it in the
CodePageRefs query. The RefSelector takes unmasked fragment data
directly (no useSuspenseFragment needed — it's a self-contained UI
component) and its onSelect callback returns the shortName string.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

c2257be refactor(web): rename fragment props from 'from' to semantic names

Click to expand commit body
Rename fragment data props to match their domain meaning:
- AuthorAvatar: from → author
- LabelBadge/LabelBadgeLink: from → label

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

dd9897b feat(web): enable Apollo data masking with useSuspenseFragment

Click to expand commit body
Enable dataMasking on the Apollo Client and adopt useSuspenseFragment
for fragment colocation. Components now receive masked fragment data
via a `from` prop typed with FragmentType, and unmask it internally.
This prepares the codebase for @defer support on fragments.

Components updated:
- CommentCard.AuthorAvatar: from={identity}
- LabelBadge/LabelBadgeLink: from={label}

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

04704cf refactor(web): use typed document nodes, eliminate wide type imports

Click to expand commit body
Replace wide GraphQL type imports (GitRef) with query-derived types
using ResultOf. Un-export fragment consts that are only used locally
for codegen registration. Replace GitRef with RefsQueryRef in the
ref-selector and code layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

bdae9e2 refactor(web): switch to graphql-codegen client-preset

Click to expand commit body
Replace typescript + typescript-operations + typescript-react-apollo
plugins with the client-preset. This generates typed document nodes and
a graphql() function, removing the need for generated hooks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

053a6a1 Merge remote-tracking branch 'origin/trunk' into webui2

Quentin Gliech created

8ff8063 refactor(web): use head.shortName for default branch

Click to expand commit body
Now that Repository.head returns a GitRef instead of GitCommit, we can
use the ref name directly instead of hash-matching against the refs
list.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

c5f816a repo,graphql: get a ref from HEAD instead of a commit

Michael Muré created

f5dc9c4 repo,graphql: get a ref from HEAD instead of a commit (#1552)

Michael Muré created

a13bc93 chore(web): remove and gitignore tsbuildinfo files

Click to expand commit body
These are TypeScript incremental build caches and shouldn't be tracked.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

ad61a91 revert: restore trunk webui man page

Click to expand commit body
The generated man page still had the removed OAuth flags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

2d78e7a revert: restore trunk webui CLI docs

Click to expand commit body
The generated docs still had the removed OAuth flags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

bdce82b fix: handle "_" as default repo in HTTP handlers

Click to expand commit body
The webui uses "_" as the URL slug for the default repository. Add it
alongside "" in the gitfile and upload handler switch cases so they
resolve to DefaultRepo() correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

8916d88 revert: remove _ convention and redundant Name() changes

Click to expand commit body
Revert the upload handler, ResolveRepo, Name() cache change, and
resolver guard — all unnecessary since trunk already handles default
repos via IsDefaultRepo(). The _ convention stays in the frontend URL
routing only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

1db970d fix(web): use /gitfile endpoint instead of removed /gitraw

Click to expand commit body
The git raw handler was removed in favor of the unified /gitfile
endpoint (#1550) which supports both hash and ref+path lookups.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

98d657f refactor: remove git raw endpoint and SyncLocalRef

Click to expand commit body
Drop git_raw_handler.go — blob-by-ref+path is now handled by the
existing git_file_handler (#1550). Also remove the SyncLocalRef/
SyncLocalRefs cache machinery and BlobAtPath cache passthrough, which
are not needed by the webui.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

1c26ee9 Merge remote-tracking branch 'origin/trunk' into webui2

Quentin Gliech created

89436e5 refactor(web): use Repository.head to find default branch

Click to expand commit body
Replace GitRef.isDefault (removed in #1551) with hash matching against
Repository.head to determine the default branch for the tree redirect.
Falls back to the first ref or "master" if no match is found.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

6166764 docs(web): update README and vite config after auth removal

Click to expand commit body
Remove references to /auth and /gitraw proxy routes, the auth/
select-identity route, and the multi-mode auth section. Update auth
docs to reflect the simplified local-only approach.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

399c01b feat(web): preload user identity query at root route

Click to expand commit body
Fire the UserIdentity query in the root route's beforeLoad so it's
already in the Apollo cache before any component calling useAuth()
renders.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

6077d7b refactor(web): drop AuthProvider, use Apollo cache directly

Click to expand commit body
The useAuth hook now just wraps a useQuery call. Apollo deduplicates and
caches the result, so a dedicated React context is unnecessary.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

c70eaee refactor(web): simplify auth to local-only mode

Click to expand commit body
Remove multi-mode auth (external/readonly) from the frontend. The auth
context now always fetches the user identity via GraphQL (local mode).
Drop the ServerConfig query, OAuth select-identity route, and sign-in/
sign-out UI from the header.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

a16f266 refactor: rip out auth system from webui backend

Click to expand commit body
Remove the OAuth/session-based authentication system that was prototyped
on this branch. This includes the provider abstraction, session store,
auth HTTP handler, ServerConfig GraphQL type, and all related wiring in
the webui command. The simple fixed-identity middleware from trunk is
preserved.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

bbe521e graphql: replace GitRef.isDefault by Repository.head (#1551)

Click to expand commit body
isDefault was barely working

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Michael Muré and Copilot created

88df361 repo: ReadData return a reader, improve the http handler (#1549)

Michael Muré created

44fc7f6 graphql: add tree-->lastcommit, further optimize history querying (#1547)

Michael Muré created

c4375a3 api/http: add support for ref+path to get a blob content (#1550)

Michael Muré created

66f1bc3 graphql: replace GitRef.isDefault by Repository.head (#1551)

Click to expand commit body
isDefault was barely working

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Michael Muré and Copilot created

e77b465 repo: ReadData return a reader, improve the http handler (#1549)

Michael Muré created

27f3d18 webui2: add pnpm in tool-versions

Michael Muré created

251a67a graphql: add tree-->lastcommit, further optimize history querying (#1547)

Michael Muré created

ab21af1 fix(web): improve muted-foreground contrast ratio for WCAG AA compliance

Click to expand commit body
Darken --muted-foreground from oklch(0.552) to oklch(0.541) in light
mode, raising the contrast ratio on muted backgrounds from 4.39:1 to
~4.55:1 (WCAG AA minimum is 4.5:1).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

9bb2551 Install @vitest/ui

Quentin Gliech created

3948b97 fix(web): remove redundant setProjectAnnotations setup for storybook tests

Click to expand commit body
Since Storybook 10.3, @storybook/addon-vitest auto-provisions preview
annotations for browser tests. Remove setupFiles from the storybook
project to let auto-provisioning handle it, keeping it only for the
snapshot project which uses composeStories.

Also switch snapshot tests to pre-load shiki in beforeAll instead of
using act(), and temporarily disable a11y checks on stories with
color contrast and aria-label violations (to be fixed separately).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

520ecd7 feat(web): add test coverage with v8 provider

Click to expand commit body
Add @vitest/coverage-v8 and a test:coverage script. Coverage excludes
generated files, route tree, stories, and test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

4ef18a4 fix(web): flush async shiki highlighter in snapshot tests

Click to expand commit body
The useShikiHighlighter() hook loads asynchronously via useEffect, so
snapshots were sometimes taken before syntax highlighting completed.
Await getHighlighter() inside act() after Story.run() to ensure
deterministic snapshots with highlighted content.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

f1cae64 feat(web): scope commit history to current file/directory path

Click to expand commit body
The History button now passes the current path as a search param, so
viewing history from a subdirectory or file shows only commits touching
that path. Also update README for listbox primitives and path-scoped
commit route.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

853eb84 fix(web): fix status tab highlight and author filter active state

Click to expand commit body
- parseQueryString now returns null status when no status: token is
  present, so tabs don't falsely highlight "Open" for free-text queries
- buildQueryString omits status: prefix when status is null
- Sync search bar draft with URL query changes via useEffect
- Resolve author query value back to humanId so the author filter
  button shows as active with avatar when an author: filter is set

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

b2d77ec refactor(web): migrate dropdown menus to floating-ui with keyboard navigation

Click to expand commit body
Replace Base UI Popover in all interactive list menus with @floating-ui/react
hooks (useFloating, useListNavigation, useInteractions, etc.) for proper
keyboard-navigable listboxes with ARIA roles.

- Add @floating-ui/react dependency
- Create pure presentational Listbox.* compound components in ui/listbox.tsx
  (Content, ScrollArea, Search, Item, Group, GroupLabel, Empty, Footer)
- Migrate IssueFilters (sort, labels, authors) with full keyboard nav
- Migrate LabelEditor to floating-ui with roving tabIndex
- Migrate RefSelector with virtual focus and grouped items
- Migrate QueryInput completions to FloatingPortal + useListNavigation
- Add stories for Listbox primitives, IssueFilters, and LabelEditor

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

082abb4 fix(web): use compact icon button sizes

Click to expand commit body
Theme toggle: icon → icon-sm (32px instead of 36px).
FileViewer copy button: icon with size-7 override → icon-xs (24px).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

c725d46 refactor(web): switch to base-vega preset for closer new-york sizing

Click to expand commit body
Reinstall shadcn components with base-vega preset (zinc base color).
Brings back familiar sizing: h-9 default buttons, rounded-md,
shadow-xs on inputs/outlines. Closer to the original new-york
style than base-nova was.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

f255a21 refactor(web): migrate from Radix UI to Base UI via shadcn

Click to expand commit body
Reinstall shadcn/ui components with --base base to use @base-ui/react
instead of radix-ui. Key API changes:

- Button: uses Base UI's Button primitive, no more asChild/Slot
- Popover: adds Positioner layer between Portal and Popup
- Avatar/Separator/Badge/Input: new Base UI primitives
- All asChild usages migrated to render prop or direct props

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

af799cb feat(web): add light/dark theme switcher to Storybook toolbar

Click to expand commit body
Add a global theme toolbar (sun/moon icons) that toggles the .dark
class on the iframe's <html> element, matching the app's dark mode
mechanism. All components and Shiki themes respond correctly.

Rename preview.ts → preview.tsx for JSX decorator support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

d3e71e4 fix(web): ensure readable text in code blocks before Shiki loads

Click to expand commit body
Set prose-pre:text-foreground so code blocks have proper contrast
against bg-muted even when Shiki hasn't loaded yet (no .shiki class).
Previously the text color came from prose-invert which could be
near-white in some contexts.

Also add an UnlabeledCodeBlock story to test this case.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

075b4e7 fix(web): use bg-muted as fallback for non-highlighted code blocks

Click to expand commit body
Shiki's .shiki class overrides the background with its theme color.
For code blocks without a language (no Shiki), bg-muted provides a
visible container. This ensures both highlighted and plain code
blocks look correct in light and dark mode.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created

43df8f0 fix(web): remove bg-muted/40 from Markdown code blocks

Click to expand commit body
The tinted background was washing out Shiki's light-colored tokens
(e.g. comments). Let Shiki's own theme background handle it — the
border alone provides enough visual separation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Quentin Gliech and Claude Opus 4.6 (1M context) created