Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
23d8020
Add `chatDefaultOpen` parameter to close chat sidebar by default
brandonmcconnell Oct 10, 2025
2b6cc30
chore: remove unused imports
brandonmcconnell Oct 10, 2025
55c5ae4
feat: pass `chatDefaultOpen` to all uses of `CopilotSidebar` in Dojo
brandonmcconnell Oct 10, 2025
12b99c9
fix: hide mobile header when `sidebarHidden=true` (`sidebar=false`)
brandonmcconnell Oct 10, 2025
81c55e0
chore: consolidate redundant base styles
brandonmcconnell Oct 10, 2025
13eb1f2
fix: enforce body background/foreground colors (currently broken on 404)
brandonmcconnell Oct 10, 2025
5a32c88
fix: support dark mode on code tabs
brandonmcconnell Oct 12, 2025
0d00569
chore: untrack and remove .DS_Store
brandonmcconnell Oct 12, 2025
6c45d0d
feat: improve dark mode styles
brandonmcconnell Oct 12, 2025
5c0947c
feat: allow overriding theme via url `theme` param
brandonmcconnell Oct 12, 2025
5e4e660
fix: match background to chat background color
brandonmcconnell Oct 12, 2025
3180abe
feat: finesse iframe'd styling for dojo examples
brandonmcconnell Oct 12, 2025
3945029
fix: remove content rounded corners when used in iframe
brandonmcconnell Oct 12, 2025
dd88f96
fix: use `neutral` color instead of `gray` when in iframe
brandonmcconnell Oct 13, 2025
900d101
feat: add light and dark mode support for Monaco code editor
brandonmcconnell Oct 13, 2025
54fffc8
feat: remove shadow from active tab in code editor tabs
brandonmcconnell Oct 13, 2025
95880fe
fix: use copilotkit docs bg color for code editor on dark mode
brandonmcconnell Oct 13, 2025
34dad7d
feat: lighten code tabs active tab on light mode
brandonmcconnell Oct 13, 2025
c096b7f
feat: offset tabs bg-color on dark mode
brandonmcconnell Oct 13, 2025
52dd4c5
feat: offset tabs bg-color on dark mode from 10% to 5%
brandonmcconnell Oct 13, 2025
326d5ee
feat: round corners on code viewer contents to show as visually nested
brandonmcconnell Oct 13, 2025
97d5892
feat: refine how we mix background color
brandonmcconnell Oct 13, 2025
b45f6c5
feat: change bg mix opacity from 10% to 8% for light mode
brandonmcconnell Oct 13, 2025
709ad9e
feat: change bg mix opacity from 8% to 3% for light mode
brandonmcconnell Oct 13, 2025
3f9579c
fix(code-viewer): remove bottom border
brandonmcconnell Oct 13, 2025
57ef411
feat(code-viewer): refine CodeEditor wrapper border color
brandonmcconnell Oct 13, 2025
75d73e8
fix(code-viewer): collapse redundant x-axis borders
brandonmcconnell Oct 13, 2025
8d09050
feat(code-viewer): refine border colors
brandonmcconnell Oct 13, 2025
080435b
feat: add hook check for if the dojo is iframed from cpk docs
brandonmcconnell Oct 13, 2025
a4856a8
fix: dojo sidebar collapsing, add theme color when in cpk iframe
brandonmcconnell Oct 13, 2025
70dd4cb
feat: remove override forcing primary color
brandonmcconnell Oct 13, 2025
ebc595d
fix: don't round corners on FileTree, even when in iframe
brandonmcconnell Oct 13, 2025
77f19d9
Merge branch 'main' into brandon/iframe-dojo
brandonmcconnell Oct 13, 2025
9dd0583
Merge branch 'main' into brandon/iframe-dojo
brandonmcconnell Oct 13, 2025
8162291
fix: fix e2e test error
brandonmcconnell Oct 13, 2025
f9855ec
Merge branch 'main' into brandon/iframe-dojo
brandonmcconnell Oct 14, 2025
94f56a5
chore: update files.json
brandonmcconnell Oct 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion typescript-sdk/apps/dojo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"start": "npm run generate-content-json && next start",
"lint": "next lint",
"mastra:dev": "mastra dev",
"generate-content-json": "npx tsx scripts/generate-content-json.ts"
"generate-content-json": "npx tsx scripts/generate-content-json.ts",
"run-everything": "./scripts/prep-dojo-everything.js && ./scripts/run-dojo-everything.js"
},
"dependencies": {
"@ag-ui/a2a-middleware": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import filesJSON from '../../../files.json'
import Readme from "@/components/readme/readme";
import CodeViewer from "@/components/code-viewer/code-viewer";
import { useURLParams } from "@/contexts/url-params-context";
import { cn } from "@/lib/utils";

type FileItem = {
name: string;
Expand All @@ -24,6 +25,7 @@ interface Props {
}

export default function FeatureLayout({ children, params }: Props) {
const { sidebarHidden } = useURLParams();
const { integrationId } = React.use(params);
const pathname = usePathname();
const { view } = useURLParams();
Expand Down Expand Up @@ -58,7 +60,13 @@ export default function FeatureLayout({ children, params }: Props) {
}, [children, codeFiles, readme, view])

return (
<div className="bg-white rounded-lg w-full h-full overflow-hidden">
<div className={cn(
"bg-white w-full h-full overflow-hidden",
// if used in iframe, match background to chat background color, otherwise, use white
sidebarHidden && "bg-(--copilot-kit-background-color)",
// if not used in iframe, round the corners of the content area
!sidebarHidden && "rounded-lg",
)}>
<div className="flex flex-col h-full overflow-auto">
{content}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { CopilotKit, useCoAgent, useCopilotAction, useCopilotChat } from "@copil
import { CopilotChat, CopilotSidebar } from "@copilotkit/react-ui";
import { useMobileView } from "@/utils/use-mobile-view";
import { useMobileChat } from "@/utils/use-mobile-chat";
import { useURLParams } from "@/contexts/url-params-context";

const extensions = [StarterKit];

Expand All @@ -25,6 +26,7 @@ interface PredictiveStateUpdatesProps {
export default function PredictiveStateUpdates({ params }: PredictiveStateUpdatesProps) {
const { integrationId } = React.use(params);
const { isMobile } = useMobileView();
const { chatDefaultOpen } = useURLParams();
const defaultChatHeight = 50;
const { isChatOpen, setChatHeight, setIsChatOpen, isDragging, chatHeight, handleDragStart } =
useMobileChat(defaultChatHeight);
Expand Down Expand Up @@ -162,7 +164,7 @@ export default function PredictiveStateUpdates({ params }: PredictiveStateUpdate
</>
) : (
<CopilotSidebar
defaultOpen={true}
defaultOpen={chatDefaultOpen}
suggestions={[
{
title: "Write a pirate story",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import "@copilotkit/react-ui/styles.css";
import "./style.css";
import { useMobileView } from "@/utils/use-mobile-view";
import { useMobileChat } from "@/utils/use-mobile-chat";
import { useURLParams } from "@/contexts/url-params-context";

interface SharedStateProps {
params: Promise<{
Expand All @@ -17,6 +18,7 @@ interface SharedStateProps {
export default function SharedState({ params }: SharedStateProps) {
const { integrationId } = React.use(params);
const { isMobile } = useMobileView();
const { chatDefaultOpen } = useURLParams();
const defaultChatHeight = 50;
const { isChatOpen, setChatHeight, setIsChatOpen, isDragging, chatHeight, handleDragStart } =
useMobileChat(defaultChatHeight);
Expand Down Expand Up @@ -137,7 +139,7 @@ export default function SharedState({ params }: SharedStateProps) {
</>
) : (
<CopilotSidebar
defaultOpen={true}
defaultOpen={chatDefaultOpen}
labels={{
title: chatTitle,
initial: initialLabel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CopilotKit, useCoAgent, useLangGraphInterrupt } from "@copilotkit/react
import { CopilotSidebar } from "@copilotkit/react-ui";
import { useMobileView } from "@/utils/use-mobile-view";
import { useMobileChat } from "@/utils/use-mobile-chat";
import { useURLParams } from "@/contexts/url-params-context";

interface SubgraphsProps {
params: Promise<{
Expand Down Expand Up @@ -152,6 +153,7 @@ function InterruptHumanInTheLoop<TAgent extends AvailableAgents>({
export default function Subgraphs({ params }: SubgraphsProps) {
const { integrationId } = React.use(params);
const { isMobile } = useMobileView();
const { chatDefaultOpen } = useURLParams();
const defaultChatHeight = 50;
const {
isChatOpen,
Expand Down Expand Up @@ -240,7 +242,7 @@ export default function Subgraphs({ params }: SubgraphsProps) {
{/* Chat Content */}
<div className="flex-1 flex flex-col min-h-0 overflow-hidden pb-16">
<CopilotSidebar
defaultOpen={true}
defaultOpen={chatDefaultOpen}
labels={{
title: chatTitle,
initial: initialLabel,
Expand All @@ -260,7 +262,7 @@ export default function Subgraphs({ params }: SubgraphsProps) {
</>
) : (
<CopilotSidebar
defaultOpen={true}
defaultOpen={chatDefaultOpen}
labels={{
title: chatTitle,
initial: initialLabel,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
import React, { useState } from "react";
import "@copilotkit/react-ui/styles.css";
import { CopilotKit, useCopilotAction } from "@copilotkit/react-core";
import { CopilotSidebar, CopilotPopup } from "@copilotkit/react-ui";
import { CopilotSidebar } from "@copilotkit/react-ui";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import { useURLParams } from "@/contexts/url-params-context";

interface ToolBasedGenerativeUIProps {
params: Promise<{
Expand All @@ -26,9 +27,10 @@ interface Haiku {

export default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {
const { integrationId } = React.use(params);
const { chatDefaultOpen } = useURLParams();

const chatProps = {
defaultOpen: true,
defaultOpen: chatDefaultOpen,
labels: {
title: "Haiku Generator",
initial: "I'm a haiku generator 👋. How can I help you?",
Expand Down
82 changes: 72 additions & 10 deletions typescript-sdk/apps/dojo/src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@
--anthropic: hsl(240 80% 60%); /* Bright blue */
--cohere: hsl(0 80% 60%); /* Bright red */ --background: oklch(1 0 0); --foreground: oklch(0.145 0 0);

--cpk-docs-dark-bg: oklch(0.274 0.006 286.033);
--cpk-docs-primary: oklch(0.55 0.25 285);
}

.dark {
Expand Down Expand Up @@ -233,15 +235,6 @@
--chart-5: oklch(0.645 0.246 16.439);
}

@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground font-sans;
}
}

@theme inline {
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
Expand Down Expand Up @@ -278,13 +271,82 @@
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
--color-cpk-docs-dark-bg: var(--cpk-docs-dark-bg);
--color-cpk-docs-primary: var(--cpk-docs-primary);

/* supporting variables for color-mix (see related color-mix-* utilities below */
--color-mix-from: var(--tw-mix-from);
--color-mix-to: var(--tw-mix-to);
--color-mix: var(--tw-mix);
}

@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
/*
TODO: remove important modifier (!)
after troubleshooting why the dojo
sidebar text is white when on 404 pages
*/
@apply bg-background! text-foreground! font-sans;
}
}

/* hide scroll decoration on code blocks */
.monaco-editor .overflow-guard .scroll-decoration {
@apply hidden!;
}

@utility mix-from-* {
--tw-mix-from-color: --value(--color-*, color, [color]);
--tw-mix-from-opacity: --modifier(--opacity-*, [percentage]);
--tw-mix-from-opacity: calc(--modifier(number) * 1%);
--tw-mix-from-opacity: calc(--modifier([number]) * 100%);
--tw-mix-from: --alpha(var(--tw-mix-from-color) / var(--tw-mix-from-opacity, 100%));
/* calculate the final color-mix result */
--tw-mix: color-mix(color-mix(in srgb, var(--color-mix-from), var(--color-mix-to) var(--tw-mix-percent, 50%)) var(--tw-mix-opacity, 100%), transparent);
@supports (color: color-mix(in lab, red, red)) {
--tw-mix: color-mix(color-mix(in oklab, var(--color-mix-from), var(--color-mix-to) var(--tw-mix-percent, 50%)) var(--tw-mix-opacity, 100%), transparent);
}
/* redefining the color variables here to ensure they receive the latest values */
--color-mix-from: var(--tw-mix-from);
--color-mix-to: var(--tw-mix-to);
--color-mix: var(--tw-mix);
}

@utility mix-to-* {
--tw-mix-to-color: --value(--color-*, color, [color]);
--tw-mix-to-opacity: --modifier(--opacity-*, [percentage]);
--tw-mix-to-opacity: calc(--modifier(number) * 1%);
--tw-mix-to-opacity: calc(--modifier([number]) * 100%);
--tw-mix-to: --alpha(var(--tw-mix-to-color) / var(--tw-mix-to-opacity, 100%));
/* calculate the final color-mix result */
--tw-mix: color-mix(color-mix(in srgb, var(--color-mix-from), var(--color-mix-to) var(--tw-mix-percent, 50%)) var(--tw-mix-opacity, 100%), transparent);
@supports (color: color-mix(in lab, red, red)) {
--tw-mix: color-mix(color-mix(in oklab, var(--color-mix-from), var(--color-mix-to) var(--tw-mix-percent, 50%)) var(--tw-mix-opacity, 100%), transparent);
}
/* redefining the color variables here to ensure they receive the latest values */
--color-mix-from: var(--tw-mix-from);
--color-mix-to: var(--tw-mix-to);
--color-mix: var(--tw-mix);
}

@utility mix-* {
--tw-mix-percent: --value(--opacity-*, [percentage]);
--tw-mix-percent: calc(--value(number) * 1%);
--tw-mix-percent: calc(--value([number]) * 100%);
--tw-mix-opacity: --modifier(--opacity-*, [percentage]);
--tw-mix-opacity: calc(--modifier(number) * 1%);
--tw-mix-opacity: calc(--modifier([number]) * 100%);
/* calculate the final color-mix result */
--tw-mix: color-mix(in srgb, color-mix(in srgb, var(--color-mix-from), var(--color-mix-to) var(--tw-mix-percent, 50%)) var(--tw-mix-opacity, 100%), transparent);
@supports (color: color-mix(in lab, red, red)) {
--tw-mix: color-mix(in oklab, color-mix(in oklab, var(--color-mix-from), var(--color-mix-to) var(--tw-mix-percent, 50%)) var(--tw-mix-opacity, 100%), transparent);
}
/* redefining the color variables here to ensure they receive the latest values */
--color-mix-from: var(--tw-mix-from);
--color-mix-to: var(--tw-mix-to);
--color-mix: var(--tw-mix);
}
20 changes: 7 additions & 13 deletions typescript-sdk/apps/dojo/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import "@copilotkit/react-ui/styles.css";
import { ThemeProvider } from "@/components/theme-provider";
import { ThemeWrapper } from "@/components/theme-wrapper";
import { MainLayout } from "@/components/layout/main-layout";
import { URLParamsProvider } from "@/contexts/url-params-context";

Expand All @@ -30,19 +30,13 @@ export default function RootLayout({
return (
<html lang="en" suppressHydrationWarning>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<ThemeProvider
attribute="class"
defaultTheme="light"
enableSystem={false}
themes={['light']}
disableTransitionOnChange
>
<Suspense>
<URLParamsProvider>
<Suspense>
<URLParamsProvider>
<ThemeWrapper>
<MainLayout>{children}</MainLayout>
</URLParamsProvider>
</Suspense>
</ThemeProvider>
</ThemeWrapper>
</URLParamsProvider>
</Suspense>
</body>
</html>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export function CodeEditor({ file, onFileChange }: CodeEditorProps) {
}
};

const theme = useTheme();
const { forcedTheme, resolvedTheme } = useTheme();
const currentTheme = forcedTheme || resolvedTheme;

if (file?.language === "ts") file.language = "typescript";

Expand All @@ -36,7 +37,7 @@ export function CodeEditor({ file, onFileChange }: CodeEditorProps) {
enabled: false,
},
}}
theme="vs-dark"
theme={currentTheme !== "dark" ? "light" : "vs-dark"}
/>
</div>
) : (
Expand Down
Loading
Loading