Skip to content

feat(web): port Home page from platform repo, wire up React Query + HeyAPI client#31061

Closed
ashleeradka wants to merge 1 commit into
mainfrom
devin/1779142403-port-home-page
Closed

feat(web): port Home page from platform repo, wire up React Query + HeyAPI client#31061
ashleeradka wants to merge 1 commit into
mainfrom
devin/1779142403-port-home-page

Conversation

@ashleeradka
Copy link
Copy Markdown
Contributor

@ashleeradka ashleeradka commented May 18, 2026

Part of LUM-1601

Why

The web app migration from vellum-assistant-platform (Next.js) to vellum-assistant (Vite + React Router v7) requires moving feature domains incrementally. The Home page is the first real feature domain to land, chosen because it:

  1. Uses React Query — naturally requires wiring up QueryClientProvider + HeyAPI client config, completing the runtime half of LUM-1601 with a real consumer (not premature infrastructure)
  2. Has a hand-written API layer — daemon endpoints not in the Django OpenAPI schema, so it uses the HeyAPI client for HTTP but doesn't require generated *Options() hooks or the full codegen pipeline
  3. Self-contained — 9 component files + 6 data-layer files with a clean dependency surface

What changed

Infrastructure (LUM-1601 runtime wiring)

  • src/lib/query-client.ts — Configured QueryClient singleton
  • src/lib/api-client.ts — HeyAPI createClient singleton for daemon endpoints (docs)
  • src/lib/api-errors.tsassertHasResponse utility for narrowing HeyAPI response types
  • src/main.tsxQueryClientProvider wrapping the router

Avatar domain (src/domains/avatar/)

  • Types, API wrappers, SVG compositor, useAssistantAvatar hook
  • AnimatedAvatar + ChatAvatar components (src/components/avatar/)

Home domain (src/domains/home/)

  • TypesFeedItem, HomeFeedResponse, RelationshipState, etc.
  • APIfetchHomeFeed, fetchRelationshipState, updateFeedItemStatus, triggerFeedAction
  • HooksuseHomeFeedQuery (with optimistic updates + visibility-change refetch), useHomeStateQuery
  • UtilssortFeedItems, groupByTime, filterByCategory, excludeHighUrgency, getPresentCategories
  • ComponentsHomePage, HomeGreetingHeader, HomeSuggestionPillBar, HomeFeedList, HomeFeedFilterBar, HomeRecapRow, HomeDetailPanel, HomeGenericDetail, HomeToolPermissionCard

Shared utilities

  • src/hooks/use-is-mobile.tsuseSyncExternalStore-based media query hook
  • src/components/resizable-panel.tsx — Draggable split-pane with pointer capture + localStorage persistence

Design library enhancement

  • packages/design-library/src/components/button.tsx — Added outlined variant, compact size, leftIcon/rightIcon/iconOnly props with proper Tailwind styling (previously had placeholder vdl-btn-* classes with no CSS definitions)

Routing

  • Added /home route in routes.tsx

Convention compliance applied during the move

  • Removed all "use client" directives (Vite SPA, not needed)
  • All filenames are kebab-case
  • All imports use .js extensions (NodeNext module resolution)
  • No Next.js imports (AppImage replaced with plain <img>)
  • Design library components imported via @vellum/design-library/components/*
  • Shared cross-domain code placed in top-level hooks/, components/, lib/ per CONVENTIONS.md
  • Domain-specific code lives within domains/home/ and domains/avatar/
  • Exact version pinning on all new dependencies (no ^ or ~)

Safety

  • Additive only — no existing files modified beyond main.tsx (QueryClientProvider wrapper), routes.tsx (new route), and package.json (new deps)
  • Design library Button changes are backwards-compatible — all new props are optional with existing defaults
  • Lint and typecheck pass (only pre-existing Ref type mismatch in design library)

Test plan

  • bun run lint — passes
  • bun run typecheck — passes (only pre-existing error)
  • CI checks

Link to Devin session: https://app.devin.ai/sessions/536ceadb023a4059908b0609b9833bc1
Requested by: @ashleeradka


Open in Devin Review

…eyAPI client

Part of LUM-1601

- Wire up QueryClientProvider in main.tsx with configured QueryClient
- Add HeyAPI client singleton (src/lib/api-client.ts) for daemon endpoints
- Add API error utilities (src/lib/api-errors.ts)
- Port avatar system: types, API, SVG compositor, useAssistantAvatar hook,
  AnimatedAvatar + ChatAvatar components
- Port Home domain: types, API layer, feed utils, useHomeFeedQuery +
  useHomeStateQuery hooks, all page components (greeting header, suggestion
  pills, feed list, filter bar, recap rows, detail panel)
- Port shared components: ResizablePanel, useIsMobile hook
- Enhance design library Button: add outlined variant, compact size,
  leftIcon/rightIcon/iconOnly props with proper Tailwind styling
- Add /home route in routes.tsx
- All files follow new repo conventions: kebab-case filenames, no
  'use client' directives, no Next.js imports, .js extension imports

Co-Authored-By: ashlee@vellum.ai <ashlee@vellum.ai>
@linear
Copy link
Copy Markdown

linear Bot commented May 18, 2026

LUM-1601

@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@socket-security
Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​types/​bun@​1.3.121001004995100
Added@​vellumai/​assistant@​0.8.27510010097100
Added@​vellumai/​cli@​0.8.28010010098100
Added@​vellumai/​credential-executor@​0.8.28110010097100
Added@​types/​node@​25.5.01001008196100

View full report

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment thread apps/web/bun.lock
Comment on lines +8 to +12
"@hey-api/client-fetch": "^0.13.1",
"@tanstack/react-query": "5.90.21",
"@vellum/design-library": "file:../../packages/design-library",
"lucide-react": "^1.16.0",
"motion": "^12.39.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 bun.lock workspace section has ^ prefixes inconsistent with exact-pinned package.json

The bun.lock workspace dependencies section records "^0.13.1", "^1.16.0", and "^12.39.0" for the three newly added packages, while package.json correctly has exact versions ("0.13.1", "1.16.0", "12.39.0"). This indicates the lockfile was generated from a state where package.json had ^ prefixes (violating the exact-pinning rule in AGENTS.md), and the lockfile was never regenerated after correcting the package.json. The root bunfig.toml sets [install] exact = true, so this should not have occurred if bun add --exact was used. The lockfile needs to be regenerated via bun install to bring it into sync with the package.json constraints.

Prompt for agents
The bun.lock file's workspace section shows caret (^) version ranges for @hey-api/client-fetch, lucide-react, and motion, but the package.json correctly pins these to exact versions. This discrepancy means the lockfile was generated when the package.json still had ^ prefixes. To fix: run `cd apps/web && bun install` to regenerate the lockfile from the current (correct) package.json. This will update the workspace section in bun.lock to show exact versions matching package.json. The root bunfig.toml has [install] exact = true which should prevent this in the future when using `bun add`.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +25 to +33
function parsePathNumbers(d: string): number[] {
const nums: number[] = [];
const re = /-?\d+\.?\d*(?:e[+-]?\d+)?/gi;
let m: RegExpExecArray | null;
while ((m = re.exec(d)) !== null) {
nums.push(parseFloat(m[0]));
}
return nums;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 SVG path number regex may misparse compact SVG notation

The regex /-?\d+\.?\d*(?:e[+-]?\d+)?/gi in parsePathNumbers and wobblePath requires at least one digit before an optional decimal (\d+\.?\d*). SVG path data allows numbers starting with just a decimal point (e.g., .5 meaning 0.5), which this regex won't match. Additionally, compact notation like 1.5.3 (meaning coordinates 1.5 and 0.3) would be parsed as 1.5 and 3 instead of 1.5 and 0.3, producing a 10x wobble error on the second coordinate. This only matters if bodyShape.svgPath from the server uses such compact notation. If paths are generated with explicit leading zeros (e.g., 0.3), this is a non-issue.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant