Skip to content

webui v2#1533

Draft
MichaelMure wants to merge 158 commits intotrunkfrom
webui2
Draft

webui v2#1533
MichaelMure wants to merge 158 commits intotrunkfrom
webui2

Conversation

@MichaelMure
Copy link
Copy Markdown
Contributor

No description provided.

MichaelMure and others added 3 commits March 13, 2026 13:09
Squashed from webui2 branch — adds the complete new React/Vite/shadcn
webui (webui2/) along with Go backend additions for code browsing,
multi-repo support, and server config API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
@sudoforge sudoforge changed the title Webui2 [POC] new web ui Mar 13, 2026
Comment thread api/http/git_serve_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
Comment thread api/http/auth_handler.go Fixed
MichaelMure and others added 2 commits March 15, 2026 00:22
Go backend:
- Remove api/http/git_browse_handler.go and git_serve_handler.go
- Remove GetPath() from RepoCommon interface and all implementations
- Remove GetRepo() (dead code) from RepoCache
- Remove old RepoBrowse interface/types from repository/repo.go
  (now in repository/browse.go from trunk)
- Remove duplicate RepoBrowse method implementations from gogit.go
- cache: keep trunk's IsDefaultRepo() and BrowseRepo(), drop GetPath()
- commands/webui.go: use trunk's setupRoutes structure while keeping
  OAuth provider support and ServerConfig
- Fix graphql_test.go: update NewHandler calls to pass ServerConfig

webui2 frontend:
- Delete src/lib/gitApi.ts (REST client, now replaced by GraphQL)
- Rewrite CodePage, CommitPage, CommitList, FileDiffView using Apollo
- Update FileViewer to use GraphQL GitBlob type (drop download button)
- Update FileTree and RefSelector to use generated types with uppercase
  enum values (BLOB/TREE/BRANCH/TAG)
- Run codegen to regenerate TypeScript types for git.graphql
- Remove /api proxy from vite.config.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sandhose and others added 17 commits March 29, 2026 18:35
adapt tsconfig files for TS 6.0 defaults:
- remove `strict` (now default true)
- remove `module` (now default esnext)
- remove `baseUrl` (deprecated, paths work without it)
- remove `useDefineForClassFields` (default for ES2022+)
- remove `DOM.Iterable` from lib (merged into DOM)
- add explicit `types: ["node"]` to tsconfig.node (TS6 defaults to [])
- add vite-env.d.ts for vite client type declarations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- install oxlint, oxlint-tsgolint, and oxfmt
- configure oxlint with typescript, react, import, unicorn plugins
- enable type-aware linting and type-check (replaces tsc in CI)
- configure oxfmt with import sorting and tailwind class sorting
- add lint, lint:fix, fmt, fmt:check, and check scripts
- ignore generated graphql files from both tools

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
run oxfmt across the entire codebase to establish consistent formatting
with import sorting and tailwind class sorting

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- add `void` to unhandled promises (no-floating-promises)
- wrap async handlers passed to React event props (no-misused-promises)
- stabilize allLabels/allAuthors/allIdentities with useMemo to avoid
  new array references on every render (exhaustive-deps)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
migrate from vite 6 to vite 8 (rolldown-based):
- upgrade vite to 8.0.3 and @vitejs/plugin-react to 6.0.1
- rename build.rollupOptions to build.rolldownOptions
- convert manualChunks from object form (removed) to function form

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
let rolldown handle chunk splitting automatically instead of
manually mapping vendor dependencies to named chunks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
upgrade @graphql-codegen/cli to 6.2.1,
@graphql-codegen/typescript and typescript-operations to 5.0.9

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
replace react-router-dom v6 with react-router v7, updating all
imports from "react-router-dom" to "react-router"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- upgrade @apollo/client from v3 to v4, add rxjs peer dependency
- move hook imports to @apollo/client/react (new canonical path)
- move ApolloProvider import to @apollo/client/react
- use explicit HttpLink instead of implicit uri option
- update codegen to use @apollo/client/react for generated hooks
- remove unused localState and incrementalHandler boilerplate

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
migrate from tailwind v3 to v4:
- replace postcss-based setup with @tailwindcss/vite plugin
- rewrite index.css: @tailwind directives → @import "tailwindcss",
  JS theme config → CSS @theme inline block
- replace tailwindcss-animate with tw-animate-css
- load @tailwindcss/typography via @plugin directive
- configure dark mode via @custom-variant
- delete tailwind.config.ts and postcss.config.js

rename classes per v4 spec:
- shadow → shadow-sm, shadow-sm → shadow-xs
- rounded → rounded-sm
- outline-none → outline-hidden

also fix type errors from apollo v4 (add explicit query types),
react-router v7 (void navigate promises), and react-markdown v10
(move className to wrapper div)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
replace individual @radix-ui/react-* packages with the unified
radix-ui package and update all imports accordingly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
the unified radix-ui package exports Slot as a namespace object,
not a component directly — use Slot.Root instead

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
replace react-router v7 with @tanstack/react-router for fully
type-safe routing with typed Link params and search params

- define code-based route tree with createRootRoute/createRoute
- register router type for global type inference
- add typed validateSearch for code page search params (ref, path, type)
- replace NavLink with Link + useMatchRoute for active state detection
- replace useSearchParams with useSearch/useNavigate
- replace useRouteError/isRouteErrorResponse with errorComponent props
- use typed Link params instead of string interpolation for all routes
- replace navigate(-1) with window.history.back()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MichaelMure and others added 26 commits April 8, 2026 21:45
isDefault was barely working

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
The generated docs still had the removed OAuth flags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The generated man page still had the removed OAuth flags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These are TypeScript incremental build caches and shouldn't be tracked.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
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>
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>
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>
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>
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>
- 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>
@MichaelMure MichaelMure changed the title [POC] new web ui webui v2 Apr 9, 2026
sandhose and others added 3 commits April 9, 2026 13:32
- 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>
- 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>
- 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants