@aws/nx-plugin 0.104.0 → 0.105.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE-THIRD-PARTY +406 -436
  2. package/package.json +12 -12
  3. package/src/infra/app/__snapshots__/generator.spec.ts.snap +21 -21
  4. package/src/open-api/ts-client/__snapshots__/generator.composite-types.spec.ts.snap +438 -0
  5. package/src/open-api/ts-client/files/client.gen.ts.template +20 -0
  6. package/src/open-api/utils/codegen-data/languages.js +7 -3
  7. package/src/open-api/utils/codegen-data/languages.js.map +1 -1
  8. package/src/open-api/utils/normalise.js +17 -0
  9. package/src/open-api/utils/normalise.js.map +1 -1
  10. package/src/preset/__snapshots__/generator.spec.ts.snap +4 -4
  11. package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +4 -4
  12. package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +9 -9
  13. package/src/py/strands-agent/react-connection/__snapshots__/generator.spec.ts.snap +129 -4
  14. package/src/py/strands-agent/react-connection/serve-local.js +1 -1
  15. package/src/py/strands-agent/react-connection/serve-local.js.map +1 -1
  16. package/src/trpc/react/__snapshots__/generator.spec.ts.snap +4 -1
  17. package/src/ts/lib/__snapshots__/generator.spec.ts.snap +3 -1
  18. package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +3 -3
  19. package/src/ts/mcp-server/generator.js +1 -0
  20. package/src/ts/mcp-server/generator.js.map +1 -1
  21. package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeAssistantMessage.tsx.template +71 -0
  22. package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeChatInput.tsx.template +65 -0
  23. package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeCursor.tsx.template +10 -0
  24. package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/CloudscapeUserMessage.tsx.template +42 -0
  25. package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/copilot.css.template +128 -0
  26. package/src/ts/react-website/agui/files/cloudscape/src/components/copilot/index.tsx.template +46 -0
  27. package/src/ts/react-website/agui/files/{src → common/src}/components/AguiProvider.tsx.template +10 -2
  28. package/src/ts/react-website/agui/files/default/src/components/copilot/index.tsx.template +5 -0
  29. package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnAssistantMessage.tsx.template +71 -0
  30. package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnChatInput.tsx.template +117 -0
  31. package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnCursor.tsx.template +23 -0
  32. package/src/ts/react-website/agui/files/shadcn/src/components/copilot/ShadcnUserMessage.tsx.template +49 -0
  33. package/src/ts/react-website/agui/files/shadcn/src/components/copilot/copilot.css.template +116 -0
  34. package/src/ts/react-website/agui/files/shadcn/src/components/copilot/index.tsx.template +46 -0
  35. package/src/ts/react-website/agui/generator.d.ts +3 -0
  36. package/src/ts/react-website/agui/generator.js +28 -1
  37. package/src/ts/react-website/agui/generator.js.map +1 -1
  38. package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +42 -38
  39. package/src/ts/strands-agent/__snapshots__/generator.spec.ts.snap +1 -1
  40. package/src/ts/strands-agent/generator.js +1 -0
  41. package/src/ts/strands-agent/generator.js.map +1 -1
  42. package/src/utils/agent-core-constructs/files/terraform/core/agent-core/runtime.tf.template +1 -1
  43. package/src/utils/files/common/shadcn/src/components/ui/avatar.tsx.template +53 -0
  44. package/src/utils/files/common/shadcn/src/components/ui/textarea.tsx.template +18 -0
  45. package/src/utils/files/website/hooks/sigv4/useSigV4.tsx.template +4 -1
  46. package/src/utils/py.js +20 -18
  47. package/src/utils/py.js.map +1 -1
  48. package/src/utils/versions.d.ts +59 -58
  49. package/src/utils/versions.js +58 -57
  50. package/src/utils/versions.js.map +1 -1
  51. /package/src/ts/react-website/agui/files/{src → common/src}/hooks/useAgui__agentNameClassName__.tsx.template +0 -0
@@ -0,0 +1,42 @@
1
+ import { CopilotChatUserMessage } from '@copilotkit/react-core/v2';
2
+ import type { CopilotChatUserMessageProps } from '@copilotkit/react-core/v2';
3
+ import ChatBubble from '@cloudscape-design/chat-components/chat-bubble';
4
+ import Avatar from '@cloudscape-design/chat-components/avatar';
5
+
6
+ const flattenContent = (
7
+ content: CopilotChatUserMessageProps['message']['content'],
8
+ ): string => {
9
+ if (!content) return '';
10
+ if (typeof content === 'string') return content;
11
+ return content
12
+ .filter(
13
+ (part): part is { type: 'text'; text: string } =>
14
+ !!part &&
15
+ typeof part === 'object' &&
16
+ 'type' in part &&
17
+ (part as { type?: unknown }).type === 'text' &&
18
+ 'text' in part &&
19
+ typeof (part as { text?: unknown }).text === 'string',
20
+ )
21
+ .map((part) => part.text)
22
+ .join('\n');
23
+ };
24
+
25
+ const CloudscapeUserMessageImpl = ({ message }: CopilotChatUserMessageProps) => (
26
+ <ChatBubble
27
+ ariaLabel="Your message"
28
+ type="outgoing"
29
+ avatar={<Avatar ariaLabel="You" tooltipText="You" initials="Me" />}
30
+ >
31
+ <div style={{ whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
32
+ {flattenContent(message.content)}
33
+ </div>
34
+ </ChatBubble>
35
+ );
36
+
37
+ export const CloudscapeUserMessage = Object.assign(
38
+ CloudscapeUserMessageImpl,
39
+ CopilotChatUserMessage,
40
+ );
41
+
42
+ export default CloudscapeUserMessage;
@@ -0,0 +1,128 @@
1
+ /* Explicit styles for the Streamdown markdown output (CopilotKit emits
2
+ * unprefixed Tailwind utilities that the website's Tailwind build can't see). */
3
+
4
+ .copilotkit-cloudscape-messages {
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 12px;
8
+ padding: 16px;
9
+ }
10
+
11
+ .copilotkit-cloudscape-input {
12
+ padding: 12px 16px 16px;
13
+ background: var(--awsui-color-background-container-content, #ffffff);
14
+ border-top: 1px solid var(--awsui-color-border-divider-default, #dfe3e6);
15
+ }
16
+
17
+ .copilotkit-cloudscape-messages [data-streamdown='strong'] {
18
+ font-weight: 600;
19
+ }
20
+ .copilotkit-cloudscape-messages [data-streamdown='emphasis'] {
21
+ font-style: italic;
22
+ }
23
+ .copilotkit-cloudscape-messages [data-streamdown='paragraph'],
24
+ .copilotkit-cloudscape-messages > p {
25
+ margin: 0.5em 0;
26
+ }
27
+
28
+ .copilotkit-cloudscape-messages [data-streamdown='heading-1'],
29
+ .copilotkit-cloudscape-messages [data-streamdown='heading-2'],
30
+ .copilotkit-cloudscape-messages [data-streamdown='heading-3'],
31
+ .copilotkit-cloudscape-messages [data-streamdown='heading-4'],
32
+ .copilotkit-cloudscape-messages [data-streamdown='heading-5'],
33
+ .copilotkit-cloudscape-messages [data-streamdown='heading-6'] {
34
+ font-weight: 600;
35
+ line-height: 1.3;
36
+ margin: 0.8em 0 0.4em;
37
+ }
38
+ .copilotkit-cloudscape-messages [data-streamdown='heading-1'] {
39
+ font-size: 1.5em;
40
+ }
41
+ .copilotkit-cloudscape-messages [data-streamdown='heading-2'] {
42
+ font-size: 1.3em;
43
+ }
44
+ .copilotkit-cloudscape-messages [data-streamdown='heading-3'] {
45
+ font-size: 1.15em;
46
+ }
47
+
48
+ .copilotkit-cloudscape-messages [data-streamdown='unordered-list'] {
49
+ list-style: disc;
50
+ padding-inline-start: 1.5em;
51
+ margin: 0.5em 0;
52
+ }
53
+ .copilotkit-cloudscape-messages [data-streamdown='ordered-list'] {
54
+ list-style: decimal;
55
+ padding-inline-start: 1.5em;
56
+ margin: 0.5em 0;
57
+ }
58
+ .copilotkit-cloudscape-messages [data-streamdown='list-item'] {
59
+ margin: 0.25em 0;
60
+ }
61
+
62
+ .copilotkit-cloudscape-messages [data-streamdown='inline-code'],
63
+ .copilotkit-cloudscape-messages code {
64
+ background: rgba(0, 0, 0, 0.06);
65
+ border-radius: 4px;
66
+ padding: 0.1em 0.35em;
67
+ font-family: var(--font-family-monospace, ui-monospace, monospace);
68
+ font-size: 0.9em;
69
+ }
70
+
71
+ .copilotkit-cloudscape-messages [data-streamdown='code-block'] {
72
+ background: rgba(0, 0, 0, 0.04);
73
+ border: 1px solid rgba(0, 0, 0, 0.08);
74
+ border-radius: 8px;
75
+ margin: 0.75em 0;
76
+ max-width: 100%;
77
+ overflow: hidden;
78
+ }
79
+ .copilotkit-cloudscape-messages [data-streamdown='code-block'] pre {
80
+ margin: 0;
81
+ padding: 12px 16px;
82
+ overflow-x: auto;
83
+ white-space: pre;
84
+ font-family: var(--font-family-monospace, ui-monospace, monospace);
85
+ font-size: 0.85em;
86
+ line-height: 1.5;
87
+ }
88
+ .copilotkit-cloudscape-messages [data-streamdown='code-block'] code {
89
+ background: transparent;
90
+ padding: 0;
91
+ white-space: pre;
92
+ }
93
+
94
+ .copilotkit-cloudscape-messages [data-streamdown='blockquote'] {
95
+ border-inline-start: 3px solid rgba(0, 0, 0, 0.15);
96
+ margin: 0.5em 0;
97
+ padding-inline-start: 1em;
98
+ color: rgba(0, 0, 0, 0.65);
99
+ }
100
+
101
+ .copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] {
102
+ border-collapse: collapse;
103
+ margin: 0.75em 0;
104
+ max-width: 100%;
105
+ overflow-x: auto;
106
+ width: auto;
107
+ }
108
+ .copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] th,
109
+ .copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] td {
110
+ border: 1px solid rgba(0, 0, 0, 0.12);
111
+ padding: 6px 10px;
112
+ text-align: start;
113
+ }
114
+ .copilotkit-cloudscape-messages table[data-streamdown='table-wrapper'] th {
115
+ background: rgba(0, 0, 0, 0.04);
116
+ font-weight: 600;
117
+ }
118
+
119
+ .copilotkit-cloudscape-messages [data-streamdown='link'] {
120
+ color: var(--awsui-color-text-link-default, #0972d3);
121
+ text-decoration: underline;
122
+ }
123
+
124
+ .copilotkit-cloudscape-messages [data-streamdown='horizontal-rule'] {
125
+ border: 0;
126
+ border-top: 1px solid rgba(0, 0, 0, 0.12);
127
+ margin: 1em 0;
128
+ }
@@ -0,0 +1,46 @@
1
+ import {
2
+ CopilotChat as CopilotChatBase,
3
+ CopilotSidebar as CopilotSidebarBase,
4
+ CopilotPopup as CopilotPopupBase,
5
+ CopilotChatView,
6
+ type CopilotChatProps,
7
+ type CopilotSidebarProps,
8
+ type CopilotPopupProps,
9
+ } from '@copilotkit/react-core/v2';
10
+ import { CloudscapeAssistantMessage } from './CloudscapeAssistantMessage';
11
+ import { CloudscapeUserMessage } from './CloudscapeUserMessage';
12
+ import { CloudscapeChatInput } from './CloudscapeChatInput';
13
+ import { CloudscapeCursor } from './CloudscapeCursor';
14
+ import './copilot.css';
15
+
16
+ const NoopFeather: typeof CopilotChatView.Feather = () => null;
17
+
18
+ export const cloudscapeCopilotTheme = {
19
+ messageView: {
20
+ assistantMessage: CloudscapeAssistantMessage,
21
+ userMessage: CloudscapeUserMessage,
22
+ cursor: CloudscapeCursor,
23
+ className: 'copilotkit-cloudscape-messages',
24
+ },
25
+ input: CloudscapeChatInput,
26
+ scrollView: { feather: NoopFeather },
27
+ } as const;
28
+
29
+ export const CopilotChat = (props: CopilotChatProps) => (
30
+ <CopilotChatBase {...cloudscapeCopilotTheme} {...props} />
31
+ );
32
+
33
+ export const CopilotSidebar = (props: CopilotSidebarProps) => (
34
+ <CopilotSidebarBase {...cloudscapeCopilotTheme} {...props} />
35
+ );
36
+
37
+ export const CopilotPopup = (props: CopilotPopupProps) => (
38
+ <CopilotPopupBase {...cloudscapeCopilotTheme} {...props} />
39
+ );
40
+
41
+ export {
42
+ CloudscapeAssistantMessage,
43
+ CloudscapeUserMessage,
44
+ CloudscapeChatInput,
45
+ CloudscapeCursor,
46
+ };
@@ -1,8 +1,13 @@
1
- import { CopilotKitProvider } from '@copilotkit/react-core/v2';
1
+ import {
2
+ CopilotKitProvider,
3
+ WildcardToolCallRender,
4
+ } from '@copilotkit/react-core/v2';
2
5
  import '@copilotkit/react-core/v2/styles.css';
3
6
  import { type FC, type PropsWithChildren, useMemo } from 'react';
4
7
  import type { AbstractAgent } from '@ag-ui/client';
5
8
 
9
+ const renderToolCalls = [WildcardToolCallRender];
10
+
6
11
  export const AguiProvider: FC<PropsWithChildren> = ({ children }) => {
7
12
  const selfManagedAgents = useMemo<Record<string, AbstractAgent>>(
8
13
  () => ({}),
@@ -10,7 +15,10 @@ export const AguiProvider: FC<PropsWithChildren> = ({ children }) => {
10
15
  );
11
16
 
12
17
  return (
13
- <CopilotKitProvider selfManagedAgents={selfManagedAgents}>
18
+ <CopilotKitProvider
19
+ selfManagedAgents={selfManagedAgents}
20
+ renderToolCalls={renderToolCalls}
21
+ >
14
22
  {children}
15
23
  </CopilotKitProvider>
16
24
  );
@@ -0,0 +1,5 @@
1
+ export {
2
+ CopilotChat,
3
+ CopilotSidebar,
4
+ CopilotPopup,
5
+ } from '@copilotkit/react-core/v2';
@@ -0,0 +1,71 @@
1
+ import {
2
+ CopilotChatAssistantMessage,
3
+ CopilotChatToolCallsView,
4
+ } from '@copilotkit/react-core/v2';
5
+ import type { CopilotChatAssistantMessageProps } from '@copilotkit/react-core/v2';
6
+ import { Copy, Sparkles } from 'lucide-react';
7
+ import {
8
+ Avatar,
9
+ AvatarFallback,
10
+ } from '<%= scopeAlias %>common-shadcn/components/ui/avatar';
11
+ import { Button } from '<%= scopeAlias %>common-shadcn/components/ui/button';
12
+ import { cn } from '<%= scopeAlias %>common-shadcn/lib/utils';
13
+
14
+ const ShadcnAssistantMessageImpl = ({
15
+ message,
16
+ messages,
17
+ }: CopilotChatAssistantMessageProps) => {
18
+ const hasContent = !!(message.content && message.content.trim().length > 0);
19
+
20
+ const handleCopy = () => {
21
+ if (typeof message.content === 'string') {
22
+ void navigator.clipboard?.writeText(message.content);
23
+ }
24
+ };
25
+
26
+ return (
27
+ <div className="group flex items-start gap-3 py-2">
28
+ <Avatar className="bg-primary/10 border-primary/20 mt-0.5 border">
29
+ <AvatarFallback className="bg-transparent">
30
+ <Sparkles className="text-primary size-4" />
31
+ </AvatarFallback>
32
+ </Avatar>
33
+ <div className="flex min-w-0 flex-1 flex-col gap-1.5">
34
+ <div
35
+ className={cn(
36
+ 'bg-muted/60 text-foreground rounded-2xl rounded-tl-sm px-4 py-3',
37
+ 'copilotkit-shadcn-markdown',
38
+ )}
39
+ >
40
+ <CopilotChatAssistantMessage.MarkdownRenderer
41
+ content={message.content ?? ''}
42
+ />
43
+ </div>
44
+ {message.toolCalls && message.toolCalls.length > 0 && (
45
+ <CopilotChatToolCallsView message={message} messages={messages} />
46
+ )}
47
+ {hasContent && (
48
+ <div className="text-muted-foreground flex items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100">
49
+ <Button
50
+ type="button"
51
+ variant="ghost"
52
+ size="icon"
53
+ className="size-7"
54
+ aria-label="Copy message"
55
+ onClick={handleCopy}
56
+ >
57
+ <Copy className="size-3.5" />
58
+ </Button>
59
+ </div>
60
+ )}
61
+ </div>
62
+ </div>
63
+ );
64
+ };
65
+
66
+ export const ShadcnAssistantMessage = Object.assign(
67
+ ShadcnAssistantMessageImpl,
68
+ CopilotChatAssistantMessage,
69
+ );
70
+
71
+ export default ShadcnAssistantMessage;
@@ -0,0 +1,117 @@
1
+ import {
2
+ useRef,
3
+ useState,
4
+ useEffect,
5
+ type KeyboardEvent,
6
+ } from 'react';
7
+ import {
8
+ CopilotChatInput,
9
+ type CopilotChatInputProps,
10
+ } from '@copilotkit/react-core/v2';
11
+ import { ArrowUp, Square } from 'lucide-react';
12
+ import { Button } from '<%= scopeAlias %>common-shadcn/components/ui/button';
13
+ import { Textarea } from '<%= scopeAlias %>common-shadcn/components/ui/textarea';
14
+ import { cn } from '<%= scopeAlias %>common-shadcn/lib/utils';
15
+
16
+ const MAX_ROWS = 8;
17
+
18
+ const ShadcnChatInputImpl = ({
19
+ value,
20
+ onChange,
21
+ onSubmitMessage,
22
+ onStop,
23
+ isRunning,
24
+ autoFocus,
25
+ mode,
26
+ }: CopilotChatInputProps) => {
27
+ const [internalValue, setInternalValue] = useState('');
28
+ const textareaRef = useRef<HTMLTextAreaElement | null>(null);
29
+ const currentValue = value ?? internalValue;
30
+ const disabled = mode === 'processing';
31
+
32
+ useEffect(() => {
33
+ const el = textareaRef.current;
34
+ if (!el) return;
35
+ el.style.height = 'auto';
36
+ const lineHeight = parseFloat(getComputedStyle(el).lineHeight || '20');
37
+ el.style.height = `${Math.min(el.scrollHeight, lineHeight * MAX_ROWS)}px`;
38
+ }, [currentValue]);
39
+
40
+ const setValue = (next: string) => {
41
+ onChange?.(next);
42
+ if (value === undefined) setInternalValue(next);
43
+ };
44
+
45
+ const submit = () => {
46
+ const trimmed = currentValue.trim();
47
+ if (!trimmed) return;
48
+ onSubmitMessage?.(trimmed);
49
+ if (value === undefined) setInternalValue('');
50
+ };
51
+
52
+ const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
53
+ if (event.key === 'Enter' && !event.shiftKey) {
54
+ event.preventDefault();
55
+ submit();
56
+ }
57
+ };
58
+
59
+ return (
60
+ <div className="px-4 pb-4 pt-2">
61
+ <div
62
+ className={cn(
63
+ 'bg-background border-input focus-within:border-ring focus-within:ring-ring/30',
64
+ 'flex items-end gap-2 rounded-3xl border px-3 py-2',
65
+ 'shadow-[0_2px_10px_rgba(0,0,0,0.06)]',
66
+ 'focus-within:ring-4 transition-[border,box-shadow]',
67
+ )}
68
+ >
69
+ <Textarea
70
+ ref={textareaRef}
71
+ value={currentValue}
72
+ onChange={(event) => setValue(event.target.value)}
73
+ onKeyDown={handleKeyDown}
74
+ disabled={disabled}
75
+ autoFocus={autoFocus}
76
+ placeholder="Ask me anything..."
77
+ rows={1}
78
+ className={cn(
79
+ 'flex-1 resize-none border-0 bg-transparent p-2 shadow-none',
80
+ 'focus-visible:ring-0 focus-visible:ring-offset-0',
81
+ 'min-h-0 max-h-48 leading-6',
82
+ )}
83
+ />
84
+ {isRunning ? (
85
+ <Button
86
+ type="button"
87
+ variant="secondary"
88
+ size="icon"
89
+ onClick={onStop}
90
+ aria-label="Stop"
91
+ className="size-9 rounded-full"
92
+ >
93
+ <Square className="size-4" fill="currentColor" />
94
+ </Button>
95
+ ) : (
96
+ <Button
97
+ type="button"
98
+ size="icon"
99
+ onClick={submit}
100
+ disabled={disabled || !currentValue.trim()}
101
+ aria-label="Send message"
102
+ className="size-9 rounded-full"
103
+ >
104
+ <ArrowUp className="size-4" />
105
+ </Button>
106
+ )}
107
+ </div>
108
+ </div>
109
+ );
110
+ };
111
+
112
+ export const ShadcnChatInput = Object.assign(
113
+ ShadcnChatInputImpl,
114
+ CopilotChatInput,
115
+ );
116
+
117
+ export default ShadcnChatInput;
@@ -0,0 +1,23 @@
1
+ import { CopilotChatMessageView } from '@copilotkit/react-core/v2';
2
+ import { cn } from '<%= scopeAlias %>common-shadcn/lib/utils';
3
+
4
+ export const ShadcnCursor: typeof CopilotChatMessageView.Cursor = () => (
5
+ <div
6
+ role="status"
7
+ aria-label="Generating response"
8
+ className="flex items-center gap-1 px-4 py-2"
9
+ >
10
+ {[0, 1, 2].map((i) => (
11
+ <span
12
+ key={i}
13
+ className={cn(
14
+ 'bg-muted-foreground/60 size-1.5 rounded-full',
15
+ 'animate-bounce',
16
+ )}
17
+ style={{ animationDelay: `${i * 120}ms` }}
18
+ />
19
+ ))}
20
+ </div>
21
+ );
22
+
23
+ export default ShadcnCursor;
@@ -0,0 +1,49 @@
1
+ import { CopilotChatUserMessage } from '@copilotkit/react-core/v2';
2
+ import type {
3
+ CopilotChatUserMessageProps,
4
+ UserMessage,
5
+ } from '@copilotkit/react-core/v2';
6
+ import { User } from 'lucide-react';
7
+ import {
8
+ Avatar,
9
+ AvatarFallback,
10
+ } from '<%= scopeAlias %>common-shadcn/components/ui/avatar';
11
+
12
+ const flattenContent = (content: UserMessage['content']): string => {
13
+ if (!content) return '';
14
+ if (typeof content === 'string') return content;
15
+ return content
16
+ .filter(
17
+ (part): part is { type: 'text'; text: string } =>
18
+ !!part &&
19
+ typeof part === 'object' &&
20
+ 'type' in part &&
21
+ (part as { type?: unknown }).type === 'text' &&
22
+ 'text' in part &&
23
+ typeof (part as { text?: unknown }).text === 'string',
24
+ )
25
+ .map((part) => part.text)
26
+ .join('\n');
27
+ };
28
+
29
+ const ShadcnUserMessageImpl = ({ message }: CopilotChatUserMessageProps) => (
30
+ <div className="flex items-start justify-end gap-3 py-2">
31
+ <div className="flex min-w-0 max-w-[85%] flex-col items-end gap-1.5">
32
+ <div className="bg-primary text-primary-foreground rounded-2xl rounded-tr-sm px-4 py-2.5 whitespace-pre-wrap break-words">
33
+ {flattenContent(message.content)}
34
+ </div>
35
+ </div>
36
+ <Avatar className="bg-secondary mt-0.5">
37
+ <AvatarFallback className="bg-transparent">
38
+ <User className="text-secondary-foreground size-4" />
39
+ </AvatarFallback>
40
+ </Avatar>
41
+ </div>
42
+ );
43
+
44
+ export const ShadcnUserMessage = Object.assign(
45
+ ShadcnUserMessageImpl,
46
+ CopilotChatUserMessage,
47
+ );
48
+
49
+ export default ShadcnUserMessage;
@@ -0,0 +1,116 @@
1
+ /* Explicit styles for the Streamdown markdown output (CopilotKit emits
2
+ * unprefixed Tailwind utilities that the website's Tailwind build can't see). */
3
+
4
+ .copilotkit-shadcn-markdown {
5
+ font-size: 0.95rem;
6
+ line-height: 1.55;
7
+ }
8
+
9
+ .copilotkit-shadcn-markdown [data-streamdown='strong'] {
10
+ font-weight: 600;
11
+ }
12
+
13
+ .copilotkit-shadcn-markdown [data-streamdown='emphasis'] {
14
+ font-style: italic;
15
+ }
16
+
17
+ .copilotkit-shadcn-markdown [data-streamdown='paragraph'] {
18
+ margin: 0.35em 0;
19
+ }
20
+
21
+ .copilotkit-shadcn-markdown [data-streamdown='heading-1'],
22
+ .copilotkit-shadcn-markdown [data-streamdown='heading-2'],
23
+ .copilotkit-shadcn-markdown [data-streamdown='heading-3'],
24
+ .copilotkit-shadcn-markdown [data-streamdown='heading-4'] {
25
+ font-weight: 600;
26
+ line-height: 1.3;
27
+ margin: 0.7em 0 0.35em;
28
+ }
29
+ .copilotkit-shadcn-markdown [data-streamdown='heading-1'] {
30
+ font-size: 1.35em;
31
+ }
32
+ .copilotkit-shadcn-markdown [data-streamdown='heading-2'] {
33
+ font-size: 1.2em;
34
+ }
35
+ .copilotkit-shadcn-markdown [data-streamdown='heading-3'] {
36
+ font-size: 1.05em;
37
+ }
38
+
39
+ .copilotkit-shadcn-markdown [data-streamdown='unordered-list'] {
40
+ list-style: disc;
41
+ padding-inline-start: 1.5em;
42
+ margin: 0.4em 0;
43
+ }
44
+ .copilotkit-shadcn-markdown [data-streamdown='ordered-list'] {
45
+ list-style: decimal;
46
+ padding-inline-start: 1.5em;
47
+ margin: 0.4em 0;
48
+ }
49
+ .copilotkit-shadcn-markdown [data-streamdown='list-item'] {
50
+ margin: 0.2em 0;
51
+ }
52
+
53
+ .copilotkit-shadcn-markdown [data-streamdown='inline-code'],
54
+ .copilotkit-shadcn-markdown code {
55
+ background: var(--background);
56
+ border-radius: 4px;
57
+ padding: 0.1em 0.35em;
58
+ font-family: var(--font-mono, ui-monospace, monospace);
59
+ font-size: 0.88em;
60
+ color: inherit;
61
+ }
62
+
63
+ .copilotkit-shadcn-markdown [data-streamdown='code-block'] {
64
+ background: var(--background);
65
+ border: 1px solid var(--border);
66
+ border-radius: 10px;
67
+ margin: 0.6em 0;
68
+ overflow: hidden;
69
+ max-width: 100%;
70
+ }
71
+ .copilotkit-shadcn-markdown [data-streamdown='code-block'] pre {
72
+ margin: 0;
73
+ padding: 10px 14px;
74
+ overflow-x: auto;
75
+ font-family: var(--font-mono, ui-monospace, monospace);
76
+ font-size: 0.85em;
77
+ line-height: 1.5;
78
+ }
79
+ .copilotkit-shadcn-markdown [data-streamdown='code-block'] code {
80
+ background: transparent;
81
+ padding: 0;
82
+ }
83
+
84
+ .copilotkit-shadcn-markdown [data-streamdown='blockquote'] {
85
+ border-inline-start: 3px solid var(--border);
86
+ margin: 0.5em 0;
87
+ padding-inline-start: 1em;
88
+ color: var(--muted-foreground);
89
+ }
90
+
91
+ .copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] {
92
+ border-collapse: collapse;
93
+ margin: 0.6em 0;
94
+ max-width: 100%;
95
+ }
96
+ .copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] th,
97
+ .copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] td {
98
+ border: 1px solid var(--border);
99
+ padding: 6px 10px;
100
+ text-align: start;
101
+ }
102
+ .copilotkit-shadcn-markdown table[data-streamdown='table-wrapper'] th {
103
+ background: var(--muted);
104
+ font-weight: 600;
105
+ }
106
+
107
+ .copilotkit-shadcn-markdown [data-streamdown='link'] {
108
+ color: var(--primary);
109
+ text-decoration: underline;
110
+ }
111
+
112
+ .copilotkit-shadcn-markdown [data-streamdown='horizontal-rule'] {
113
+ border: 0;
114
+ border-top: 1px solid var(--border);
115
+ margin: 1em 0;
116
+ }
@@ -0,0 +1,46 @@
1
+ import {
2
+ CopilotChat as CopilotChatBase,
3
+ CopilotSidebar as CopilotSidebarBase,
4
+ CopilotPopup as CopilotPopupBase,
5
+ CopilotChatView,
6
+ type CopilotChatProps,
7
+ type CopilotSidebarProps,
8
+ type CopilotPopupProps,
9
+ } from '@copilotkit/react-core/v2';
10
+ import { ShadcnAssistantMessage } from './ShadcnAssistantMessage';
11
+ import { ShadcnUserMessage } from './ShadcnUserMessage';
12
+ import { ShadcnChatInput } from './ShadcnChatInput';
13
+ import { ShadcnCursor } from './ShadcnCursor';
14
+ import './copilot.css';
15
+
16
+ const NoopFeather: typeof CopilotChatView.Feather = () => null;
17
+
18
+ export const shadcnCopilotTheme = {
19
+ messageView: {
20
+ assistantMessage: ShadcnAssistantMessage,
21
+ userMessage: ShadcnUserMessage,
22
+ cursor: ShadcnCursor,
23
+ className: 'flex flex-col gap-3 px-4 py-6',
24
+ },
25
+ input: ShadcnChatInput,
26
+ scrollView: { feather: NoopFeather },
27
+ } as const;
28
+
29
+ export const CopilotChat = (props: CopilotChatProps) => (
30
+ <CopilotChatBase {...shadcnCopilotTheme} {...props} />
31
+ );
32
+
33
+ export const CopilotSidebar = (props: CopilotSidebarProps) => (
34
+ <CopilotSidebarBase {...shadcnCopilotTheme} {...props} />
35
+ );
36
+
37
+ export const CopilotPopup = (props: CopilotPopupProps) => (
38
+ <CopilotPopupBase {...shadcnCopilotTheme} {...props} />
39
+ );
40
+
41
+ export {
42
+ ShadcnAssistantMessage,
43
+ ShadcnUserMessage,
44
+ ShadcnChatInput,
45
+ ShadcnCursor,
46
+ };
@@ -22,5 +22,8 @@ export interface AgUiReactConnectionOptions {
22
22
  * `selfManagedAgents` registry) and wraps `<App />` in it. Each invocation
23
23
  * AST-patches `AguiProvider` to register one more agent hook — running the
24
24
  * generator multiple times is idempotent and additive.
25
+ *
26
+ * Also vends a `src/components/copilot` theme module picked from the
27
+ * website's `metadata.uxProvider` (cloudscape / shadcn / default).
25
28
  */
26
29
  export declare const addAgUiReactConnection: (tree: Tree, options: AgUiReactConnectionOptions) => Promise<void>;