SaaS banking demo: customer-ready on CopilotKit v2 (FOR-138)#5180
Merged
AlemTuzlak merged 23 commits intoJun 5, 2026
Merged
Conversation
- Switch imports from @copilotkit/react-core to /v2 - Replace useCopilotReadable with useAgentContext (stringify object value) - Convert navigateToPageAndPerform parameters array to a Zod object schema
- Switch imports from @copilotkit/react-core to /v2 - Replace useCopilotReadable with useAgentContext - Convert all useHumanInTheLoop and useFrontendTool parameters to Zod schemas (addNewCard, assignPolicyToCard, addNoteToTransaction, showTransactions, setCardPin, showAndApproveTransactions) - Convert v1 available: "enabled"/"disabled" to v2 boolean - Fix React 19 useReducer typing by extracting changePinReducer and dropping explicit generics
- Switch imports from @copilotkit/react-core to /v2 - Replace useCopilotReadable with useAgentContext (stringify team) - Convert removeMember, changeMemberRole, changeMemberTeam parameters to Zod schemas - Fix React 19 useReducer typing by extracting dialogStateReducer and dropping explicit generics
- Switch imports from @copilotkit/react-core to /v2 in layout.tsx and actions.ts - Replace useCopilotReadable with useAgentContext - Stringify the credit cards/policies/transactions context value to satisfy the JsonSerializable type
Replace the in-memory `data` literal in `api/v1/data.ts` with a file-seeded, module-singleton store: - `src/data/seed.json` holds the seed (cards, team, policies, transactions) with refreshed dates (within ~60 days of 2026-06-02) and valid future card expiries. - `src/lib/store.ts` deep-clones the seed at module init and exposes typed read accessors (cards/team/policies/transactions, findCard, findPolicy, findTransaction) plus the exact mutator set the routes use (addCard, updateCardPin, assignPolicyToCard, addPolicy, updateTransaction, addMember, updateMember, removeMember). - All `src/app/api/v1/**/route.ts` files now read/write through the store. `data.ts` retains the shared interfaces/enums/CARD_COLORS/ generateUniqueId and drops the literal `data` constant. - Mutations persist for the running server process and reset to seed on restart (intentional demo behavior; no disk write-back). - Domain-data only — conversation threads/memory live in a separate ticket (FOR-137). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace toy team names and @example.com emails with credible professional names and @northwind.example addresses (preserve ids, roles, team assignments). Default Admin is Alex Morgan. - Set <title> metadata to IDENTITY.brand (Northwind Finance). - Add formatCurrency helper in lib/utils.ts and route all money rendering (transactions list, credit-card details, dashboard + cards summary tiles) through it so amounts always render as $10,000.00 / -$1,000.00. - Instruct the Northwind Copilot prompt to treat the rendered showTransactions list as the single source of truth so prose no longer restates counts/totals and contradicts the rendered list. - Remove stray console.log and tighten == to === in components/layout.tsx.
The banking showcase was migrated to CopilotKit v2 but `src/app/layout.tsx`
still imported the removed `@copilotkit/react-ui/styles.css`, causing every
route to 500 with "Module not found". Drop the dead import.
Banking is still on Tailwind v3, while the v2 stylesheet
(`@copilotkit/react-core/v2/styles.css`) is pre-compiled Tailwind v4 output
containing bare `@layer base { ... }` rules. Tailwind v3's PostCSS plugin
rejects `@layer base` without a matching `@tailwind base` directive, so any
CSS import routed through the JS/TSX pipeline fails the build. Move the v2
stylesheet load to a server-side `fs.readFileSync` + inline `<style>` tag in
the root layout so the CSS reaches the browser without passing through
PostCSS / Tailwind v3. This avoids a full Tailwind v4 migration of the app.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ally Banking was on Tailwind v3, which made the pre-compiled v2 stylesheet (`@copilotkit/react-core/v2/styles.css`, built as Tailwind v4 output) incompatible with the PostCSS pipeline. A temporary inline-CSS hack in `layout.tsx` worked around this. Migrate to Tailwind v4 to match the canonical v2 demos and remove the hack. - package.json: tailwindcss ^4, add @tailwindcss/postcss ^4, replace tailwindcss-animate with tw-animate-css (v4 drop-in) - postcss.config.mjs: switch plugin to @tailwindcss/postcss - globals.css: use @import "tailwindcss" + @import "tw-animate-css"; add @custom-variant dark for the existing .dark/.light class toggle; move shadcn color/radius mapping into @theme inline (preserves bg-background/text-foreground/rounded-{lg,md,sm} semantics) - tailwind.config.ts: deleted; theme now lives in CSS - components.json: clear stale tailwind.config reference - layout.tsx: drop the readFileSync/dangerouslySetInnerHTML inline-CSS workaround; import "@copilotkit/react-core/v2/styles.css" the normal way alongside ./globals.css Verified: tsc clean, next build clean, Playwright-rendered all four pages (/, /dashboard, /cards, /team) with computed-style checks (sidebar bg-gray-900 dark, rounded-lg=8px, .border=1px) and opened the copilot popup which renders fully styled with the v2 stylesheet.
Adds a CI-safe Playwright smoke test that verifies the banking showcase
boots and the CopilotKit v2 popup opens with its configured suggestion
pills, without invoking the agent (so it runs in CI without secrets).
Covers:
- Document title shows the Northwind Finance brand
- Credit-cards dashboard renders ("Credit Cards" heading)
- CopilotPopup launcher opens the dialog (Northwind Copilot)
- Three suggestion pills render: View transactions, Add a card,
Assign a policy
The dev server gets a dummy OPENAI_API_KEY so the runtime route boots,
but the test never sends a chat message or clicks a suggestion.
.gitignore: ignore test-results/, playwright-report/, and
tsconfig.tsbuildinfo so they don't become clutter.
Remove the /Hydration/i pattern from the ignored-console-errors filter so
Next.js hydration mismatches surface as real failures, and add a
page.on("pageerror", ...) listener that records uncaught exceptions and
asserts none occurred. pageerrors are not filtered — any uncaught
exception fails the smoke test.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace v1-era hooks/data references with the actual v2 surface: useAgentContext / useFrontendTool / useHumanInTheLoop from @copilotkit/react-core/v2, the Hono runtime route, the seed.json + store data layer, and the Northwind identity. Drop mentions of removed SQL/MSA/ServiceNow/RAG features. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…p stale lockfile
package.json was pinning next@14 / react@18, but the root pnpm.overrides
were already forcing next@16 / react@19 at install time and the code uses
Next 16 async params. Bump the declared ranges to ^16.0.10 / ^19 (and
@types/react{,-dom} to ^19) so the manifest matches reality and matches
the v2 reference demos (mcp-apps, generative-ui-playground).
Also drop examples/showcases/banking/pnpm-lock.yaml: the demo is a
workspace package (listed in root pnpm-workspace.yaml and resolved in the
root pnpm-lock.yaml), so the per-demo lockfile was vestigial v1 cruft
that contradicted the v2 migration.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- cards PUT handler: stop console.info'ing the request body, which included the plaintext PIN on every PIN-change request. - wrapper.tsx: drop the duplicate ./globals.css import (already imported in app/layout.tsx, which is the canonical place). - copilot-context.tsx: replace window.location.pathname read during render with usePathname() from next/navigation, matching how components/layout.tsx already derives the current route. - next.config.mjs: remove the eslint.ignoreDuringBuilds block — Next 16 no longer runs ESLint at build, and the key now produces an "Unrecognized key(s): 'eslint'" warning. Confirmed warning is gone. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The migration mounted the low-level CopilotKitProvider, which omits the
ThreadsProvider that holds the rendered message thread, so the agent ran but
the transcript stayed empty. Use the full CopilotKit provider, and set
useSingleEndpoint={false} to match the multi-endpoint Hono route (the default
single-endpoint transport 404s against it).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…deps Display-only generative UI must use useComponent (not useFrontendTool): its render is unconditional so the card persists after the tool call completes. Also pass [transactions, cards] as deps so the renderer re-registers when the data loads -- otherwise the closure captures the initial empty transactions and the list renders empty. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📣 Social Copy GeneratorGenerate social media copies (Twitter/X, LinkedIn, Blog Post) for this PR using Claude.
|
Contributor
|
Size Change: 0 B Total Size: 979 kB ℹ️ View Unchanged
|
AlemTuzlak
approved these changes
Jun 5, 2026
mxmzb
pushed a commit
that referenced
this pull request
Jun 25, 2026
Continues the closed draft #5183 on top of the merged #5180. Adds: v2 Threads as a docked chat side panel + inbox; the self-learning teachable policy-exception gate (symptom-only over-limit gate, justifying-exception unlock, recipe withheld; OSS default, env-gated CopilotKitIntelligence); the Aurora design system; a reusable teach-mode cookbook (examples/showcases/teach-mode/); and a learning-track plan. 53 files, scoped to examples/showcases/{banking,teach-mode}. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mxmzb
added a commit
that referenced
this pull request
Jun 25, 2026
…g + Aurora UI (#5266) ## What this is The consolidated, Jerel-owned PR for the **SaaS banking demo** (FOR-137), built on top of the now-merged **#5180** (Maxim, FOR-138). It continues the closed draft **#5183**, rebuilt cleanly on current `main`. Scope: **53 files, entirely within `examples/showcases/banking` + `examples/showcases/teach-mode`.** <img width="1358" height="763" alt="image" src="https://github.com/user-attachments/assets/2ad50912-077e-4a03-821b-047e487a7c8d" /> <img width="1600" height="894" alt="image" src="https://github.com/user-attachments/assets/f80d894f-a24c-4d77-af83-0d1cf1369b18" /> <img width="800" height="451" alt="image" src="https://github.com/user-attachments/assets/c8d6abe5-2e70-4ad1-87af-8aa6529906dc" /> ## What's added (on top of #5180) - 🎨 **Aurora design system** — premium light/violet fintech redesign (lavender canvas, violet→indigo brand, gradient cards, hand-rolled SVG statistics sparkline, Inter). Restyle-only; all wiring preserved. - 🪟 **Chat as a docked side panel + Threads inbox** — v2 `useThreads`; the chat is a right-docked `CopilotSidebar`; Threads live as an **inbox button in the panel header** (conversation list, new / archive / select). - 🧠 **Self-learning teachable gate** — approving an over-limit transaction is blocked with a **symptom-only** error; a human unlocks it by filing a **justifying** policy exception; the agent gets tools + distractors but **never the unlock recipe**. OSS mode is the default; `CopilotKitIntelligence` is env-gated. - 📘 **Reusable teach-mode cookbook** — `examples/showcases/teach-mode/` (the 5-role teachable-loop contract + banking↔e-commerce mapping + adoption checklist + recording seam + `verify-teachable-gate.sh`). - 🗺️ **Learning-track plan** — `LEARNING-TRACK-PLAN.md`: how to make the live learn→distill→retrieve loop work + the teachable-demo UX (suggested prompt, inline HITL, recording vignette). ## Status / notes - **Draft.** Runs in **OSS mode** (only `OPENAI_API_KEY`); no Intelligence backend required. - The **live** self-learning loop (record→distill→`/knowledge`→fresh-agent-learns) is gated on the react-core recording hook (`e103a19`) + an Intelligence backend — see `LEARNING-TRACK-PLAN.md`. The teachable **mechanics** (gate + unlock) work today and are REST-verifiable (`verify-teachable-gate.sh`). - cc @mxmzb — consolidated demo PR per Sam's ask; builds directly on your merged #5180. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Makes the
examples/showcases/banking/SaaS demo customer-ready by migrating it to CopilotKit v2 and polishing it into a credible, reliable reference. Closes the non-memory gaps from FOR-133's assessment (FOR-138).BuiltInAgent+createCopilotHonoHandler+InMemoryAgentRunner),CopilotKitprovider +CopilotPopup, hooks moved to@copilotkit/react-core/v2(useAgentContext,useHumanInTheLoop,useComponent, Zod params), onworkspace:*packages.src/data/seed.jsonbehind a typedsrc/lib/store.ts(in-memory, resets to seed on restart). Clean seam left for the memory track (FOR-137).@northwind.example, refreshed transaction dates + future card expiries,Intlcurrency formatting.params, Tailwind v4 (so the v2 stylesheet imports normally), correctnext/reactversions, single lockfile, accurate v2 README.Verified live (real OpenAI key)
Full golden path works end-to-end: chat renders → "show transactions for card 4242" renders the generative-UI list → "add a card" → HITL approval card → Approve → new card appears in the grid. 0 console errors. Build + typecheck + smoke test green; no committed secrets.
Three v2 chat-rendering bugs were found and fixed by running it live: use the full
CopilotKitprovider (not the low-levelCopilotKitProvider, which omitsThreadsProvider); setuseSingleEndpoint={false}to match the multi-endpoint route; and useuseComponentwith adepsarray for display-only generative UI (avoids a stale-closure empty render).Non-goals (deliberately out of scope)
enterprise-brexdemo + repointing its deploy.Test plan
pnpm --filter demo-saas-copilot buildsucceedspnpm --filter demo-saas-copilot exec tsc --noEmitcleanpnpm --filter demo-saas-copilot test:e2epassesOPENAI_API_KEYset: run the golden path (transactions gen-UI, add-card HITL → approve → grid update)Known minor follow-ups
showDevConsolesurfaces the v2 Web Inspector / announcement banner.🤖 Generated with Claude Code