- 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
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>
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
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
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