Migrate frontend to Vite + Hono CopilotKit runtime

Replaces the Next.js scaffold with a Vite SPA paired with a Hono
sidecar that hosts the CopilotKit runtime and proxies AG-UI traffic
to the MAF backend. Adds dev/prod Dockerfile, .dockerignore,
.gitignore, pnpm workspace config, and updates entrypoints
(main.tsx / App.tsx / index.css / index.html) plus the service
worker accordingly.

Server middleware reconciles MAF MESSAGES_SNAPSHOT id mismatches
so post-tool-call assistant text doesn't render twice, suppresses
duplicate text emitted alongside render tools, and strips OpenAI
training-token leaks from streamed deltas.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Carlos Escalante
2026-04-29 22:01:40 -06:00
parent c4768e6912
commit 5f2a4105f3
14 changed files with 7182 additions and 2067 deletions

View File

@@ -1,12 +1,15 @@
@import "tailwindcss";
@import "tw-animate-css";
@import "shadcn/tailwind.css";
@import "@fontsource-variable/noto-sans";
@import "@fontsource-variable/ibm-plex-sans";
@import "tailwindcss";
@import "tw-animate-css";
@import "@copilotkit/react-core/v2/styles.css";
@custom-variant dark (&:is(.dark *));
:root {
--font-sans: "Noto Sans Variable", sans-serif;
--font-heading: "IBM Plex Sans Variable", sans-serif;
--background: oklch(1 0 0);
--foreground: oklch(0.141 0.005 285.823);
--card: oklch(1 0 0);
@@ -39,6 +42,8 @@
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
--sidebar-border: oklch(0.92 0.004 286.32);
--sidebar-ring: oklch(0.705 0.015 286.067);
--copilot-kit-primary-color: var(--primary);
}
.dark {
@@ -73,11 +78,39 @@
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.552 0.016 285.938);
--copilot-kit-primary-color: var(--primary);
}
/* Wire CopilotKit v2 CSS variables to WealthySmart's dark palette.
The v2 CSS sets --background/--muted/etc directly on [data-copilotkit]
elements (unlayered), overriding inherited values from .dark on <html>.
Using html.dark [data-copilotkit] (specificity 0,2,1) beats the v2's
own .dark [data-copilotkit] (specificity 0,2,0) and restores dark mode. */
html.dark [data-copilotkit] {
--background: oklch(0.141 0.005 285.823);
--foreground: oklch(0.985 0 0);
--card: oklch(0.21 0.006 285.885);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.21 0.006 285.885);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.437 0.078 188.216);
--primary-foreground: oklch(0.984 0.014 180.72);
--secondary: oklch(0.274 0.006 286.033);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.274 0.006 286.033);
--muted-foreground: oklch(0.705 0.015 286.067);
--accent: oklch(0.274 0.006 286.033);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.552 0.016 285.938);
}
@theme inline {
--font-sans: 'Noto Sans Variable', sans-serif;
--font-heading: 'IBM Plex Sans Variable', sans-serif;
--font-sans: var(--font-sans);
--font-heading: var(--font-heading);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
@@ -121,13 +154,11 @@
@layer base {
* {
@apply border-border outline-ring/50;
}
}
body {
@apply bg-background text-foreground;
}
html {
@apply font-sans;
}
font-family: var(--font-sans);
}
}
/* Privacy mode: blur sensitive financial data */