@copilotkitnext/react 1.52.0-next.5 → 1.52.0-next.6
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.
- package/dist/components/WildcardToolCallRender.cjs +13 -13
- package/dist/components/WildcardToolCallRender.cjs.map +1 -1
- package/dist/components/WildcardToolCallRender.mjs +13 -13
- package/dist/components/WildcardToolCallRender.mjs.map +1 -1
- package/dist/components/chat/CopilotChat.cjs.map +1 -1
- package/dist/components/chat/CopilotChat.mjs.map +1 -1
- package/dist/components/chat/CopilotChatAssistantMessage.cjs +36 -28
- package/dist/components/chat/CopilotChatAssistantMessage.cjs.map +1 -1
- package/dist/components/chat/CopilotChatAssistantMessage.mjs +37 -29
- package/dist/components/chat/CopilotChatAssistantMessage.mjs.map +1 -1
- package/dist/components/chat/CopilotChatAudioRecorder.cjs +2 -2
- package/dist/components/chat/CopilotChatAudioRecorder.cjs.map +1 -1
- package/dist/components/chat/CopilotChatAudioRecorder.mjs +2 -2
- package/dist/components/chat/CopilotChatAudioRecorder.mjs.map +1 -1
- package/dist/components/chat/CopilotChatInput.cjs +59 -51
- package/dist/components/chat/CopilotChatInput.cjs.map +1 -1
- package/dist/components/chat/CopilotChatInput.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatInput.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatInput.mjs +59 -51
- package/dist/components/chat/CopilotChatInput.mjs.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.cjs +12 -7
- package/dist/components/chat/CopilotChatMessageView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.mjs +12 -7
- package/dist/components/chat/CopilotChatMessageView.mjs.map +1 -1
- package/dist/components/chat/CopilotChatReasoningMessage.cjs +24 -20
- package/dist/components/chat/CopilotChatReasoningMessage.cjs.map +1 -1
- package/dist/components/chat/CopilotChatReasoningMessage.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatReasoningMessage.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatReasoningMessage.mjs +25 -21
- package/dist/components/chat/CopilotChatReasoningMessage.mjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionPill.cjs +6 -5
- package/dist/components/chat/CopilotChatSuggestionPill.cjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionPill.mjs +6 -5
- package/dist/components/chat/CopilotChatSuggestionPill.mjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.cjs +24 -12
- package/dist/components/chat/CopilotChatSuggestionView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.mjs +25 -13
- package/dist/components/chat/CopilotChatSuggestionView.mjs.map +1 -1
- package/dist/components/chat/CopilotChatToggleButton.cjs +7 -6
- package/dist/components/chat/CopilotChatToggleButton.cjs.map +1 -1
- package/dist/components/chat/CopilotChatToggleButton.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatToggleButton.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatToggleButton.mjs +7 -6
- package/dist/components/chat/CopilotChatToggleButton.mjs.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.cjs +29 -24
- package/dist/components/chat/CopilotChatUserMessage.cjs.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.mjs +30 -25
- package/dist/components/chat/CopilotChatUserMessage.mjs.map +1 -1
- package/dist/components/chat/CopilotChatView.cjs +45 -35
- package/dist/components/chat/CopilotChatView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatView.d.cts +1 -1
- package/dist/components/chat/CopilotChatView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatView.d.mts +1 -1
- package/dist/components/chat/CopilotChatView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatView.mjs +45 -35
- package/dist/components/chat/CopilotChatView.mjs.map +1 -1
- package/dist/components/chat/CopilotModalHeader.cjs +8 -8
- package/dist/components/chat/CopilotModalHeader.cjs.map +1 -1
- package/dist/components/chat/CopilotModalHeader.d.cts.map +1 -1
- package/dist/components/chat/CopilotModalHeader.d.mts.map +1 -1
- package/dist/components/chat/CopilotModalHeader.mjs +8 -8
- package/dist/components/chat/CopilotModalHeader.mjs.map +1 -1
- package/dist/components/chat/CopilotPopupView.cjs +20 -15
- package/dist/components/chat/CopilotPopupView.cjs.map +1 -1
- package/dist/components/chat/CopilotPopupView.d.cts.map +1 -1
- package/dist/components/chat/CopilotPopupView.d.mts.map +1 -1
- package/dist/components/chat/CopilotPopupView.mjs +20 -15
- package/dist/components/chat/CopilotPopupView.mjs.map +1 -1
- package/dist/components/chat/CopilotSidebarView.cjs +54 -43
- package/dist/components/chat/CopilotSidebarView.cjs.map +1 -1
- package/dist/components/chat/CopilotSidebarView.d.cts.map +1 -1
- package/dist/components/chat/CopilotSidebarView.d.mts.map +1 -1
- package/dist/components/chat/CopilotSidebarView.mjs +55 -44
- package/dist/components/chat/CopilotSidebarView.mjs.map +1 -1
- package/dist/components/ui/button.cjs +42 -42
- package/dist/components/ui/button.cjs.map +1 -1
- package/dist/components/ui/button.mjs +42 -42
- package/dist/components/ui/button.mjs.map +1 -1
- package/dist/components/ui/dropdown-menu.cjs +7 -6
- package/dist/components/ui/dropdown-menu.cjs.map +1 -1
- package/dist/components/ui/dropdown-menu.mjs +7 -6
- package/dist/components/ui/dropdown-menu.mjs.map +1 -1
- package/dist/components/ui/tooltip.cjs +3 -2
- package/dist/components/ui/tooltip.cjs.map +1 -1
- package/dist/components/ui/tooltip.mjs +3 -2
- package/dist/components/ui/tooltip.mjs.map +1 -1
- package/dist/hooks/use-component.cjs +18 -5
- package/dist/hooks/use-component.cjs.map +1 -1
- package/dist/hooks/use-component.d.cts +21 -7
- package/dist/hooks/use-component.d.cts.map +1 -1
- package/dist/hooks/use-component.d.mts +21 -7
- package/dist/hooks/use-component.d.mts.map +1 -1
- package/dist/hooks/use-component.mjs +18 -5
- package/dist/hooks/use-component.mjs.map +1 -1
- package/dist/hooks/use-default-render-tool.cjs +2 -2
- package/dist/hooks/use-default-render-tool.cjs.map +1 -1
- package/dist/hooks/use-default-render-tool.d.cts +3 -3
- package/dist/hooks/use-default-render-tool.d.cts.map +1 -1
- package/dist/hooks/use-default-render-tool.d.mts +3 -3
- package/dist/hooks/use-default-render-tool.d.mts.map +1 -1
- package/dist/hooks/use-default-render-tool.mjs +2 -2
- package/dist/hooks/use-default-render-tool.mjs.map +1 -1
- package/dist/hooks/use-render-tool.cjs +15 -9
- package/dist/hooks/use-render-tool.cjs.map +1 -1
- package/dist/hooks/use-render-tool.d.cts +9 -9
- package/dist/hooks/use-render-tool.d.cts.map +1 -1
- package/dist/hooks/use-render-tool.d.mts +9 -9
- package/dist/hooks/use-render-tool.d.mts.map +1 -1
- package/dist/hooks/use-render-tool.mjs +15 -9
- package/dist/hooks/use-render-tool.mjs.map +1 -1
- package/dist/index.umd.js +429 -339
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/utils.cjs +2 -1
- package/dist/lib/utils.cjs.map +1 -1
- package/dist/lib/utils.mjs +3 -2
- package/dist/lib/utils.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/eslint-rules/README.md +52 -0
- package/eslint-rules/require-cpk-prefix.mjs +375 -0
- package/eslint.config.mjs +17 -0
- package/package.json +8 -7
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint rule: require-cpk-prefix
|
|
3
|
+
*
|
|
4
|
+
* Enforces that Tailwind utility classes in className attributes and
|
|
5
|
+
* class-helper calls (cn, twMerge, cva, clsx) use the `cpk:` prefix.
|
|
6
|
+
* Also detects the prefix in the wrong position (after variants instead of before).
|
|
7
|
+
*
|
|
8
|
+
* In Tailwind v4 with prefix(cpk), the prefix MUST come before all variants:
|
|
9
|
+
* cpk:dark:hover:bg-white ✓ (generates CSS)
|
|
10
|
+
* dark:hover:cpk:bg-white ✗ (generates NO CSS)
|
|
11
|
+
*
|
|
12
|
+
* Detection logic reused from scripts/add-cpk-prefix.mjs.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const PREFIX = "cpk:";
|
|
16
|
+
|
|
17
|
+
// ── Tailwind utility detection ──────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
const SINGLE_WORD_UTILITIES = new Set([
|
|
20
|
+
"absolute","antialiased","block","border","capitalize","collapse",
|
|
21
|
+
"container","contents","fixed","flex","grid","grow","hidden","inline",
|
|
22
|
+
"inline-block","inline-flex","inline-grid","invisible","isolate","italic",
|
|
23
|
+
"lowercase","ordinal","outline","overflow","overline","relative","resize",
|
|
24
|
+
"ring","rounded","shadow","shrink","static","sticky","table","truncate",
|
|
25
|
+
"underline","uppercase","visible","prose",
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const JS_VALUE_WORDS = new Set([
|
|
29
|
+
"absolute","static","relative","fixed","sticky",
|
|
30
|
+
"contents","none","auto","inherit","initial","unset","revert",
|
|
31
|
+
"block","inline","flex","grid","hidden",
|
|
32
|
+
"smooth","instant","nearest",
|
|
33
|
+
"button","submit","reset",
|
|
34
|
+
"input","transcribe","processing",
|
|
35
|
+
"recording","idle",
|
|
36
|
+
"text","password","email","number","tel","url","search",
|
|
37
|
+
"top","bottom","left","right","start","end",
|
|
38
|
+
"compact","expanded",
|
|
39
|
+
"before","after",
|
|
40
|
+
"open","closed",
|
|
41
|
+
"default","destructive","outline","secondary","ghost","link",
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
const VARIANT_RE = /^(?:dark|hover|focus|focus-visible|focus-within|active|disabled|visited|checked|required|invalid|first|last|odd|even|only|empty|enabled|read-only|placeholder-shown|autofill|default|indeterminate|open|closed|group-hover|group-focus|peer-hover|peer-focus|peer-checked|placeholder|before|after|selection|marker|first-line|first-letter|file|sm|md|lg|xl|2xl|portrait|landscape|motion-safe|motion-reduce|contrast-more|contrast-less|forced-colors|print|ltr|rtl|aria-invalid|aria-checked|aria-disabled|aria-expanded|aria-hidden|aria-pressed|aria-readonly|aria-required|aria-selected|has-\[.+?\]|not-\[.+?\]|group-data-\[.+?\]|supports-\[.+?\]|min-\[.+?\]|max-\[.+?\]|data-\[.+?\]|aria-\[.+?\]|\[.+?\]):/;
|
|
45
|
+
|
|
46
|
+
function stripVariants(token) {
|
|
47
|
+
let base = token;
|
|
48
|
+
let iterations = 0;
|
|
49
|
+
while (VARIANT_RE.test(base) && iterations < 20) {
|
|
50
|
+
base = base.replace(VARIANT_RE, "");
|
|
51
|
+
iterations++;
|
|
52
|
+
}
|
|
53
|
+
return base;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function isBaseUtility(base) {
|
|
57
|
+
if (!base) return false;
|
|
58
|
+
|
|
59
|
+
let b = base;
|
|
60
|
+
if (b.startsWith("-") || b.startsWith("!")) b = b.slice(1);
|
|
61
|
+
|
|
62
|
+
const slashIdx = b.indexOf("/");
|
|
63
|
+
let bNoOpacity = b;
|
|
64
|
+
if (slashIdx > 0 && !b.includes("[")) {
|
|
65
|
+
bNoOpacity = b.slice(0, slashIdx);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (SINGLE_WORD_UTILITIES.has(bNoOpacity)) return true;
|
|
69
|
+
|
|
70
|
+
const prefixes = [
|
|
71
|
+
"bg-","text-","font-","p-","px-","py-","pt-","pb-","pl-","pr-",
|
|
72
|
+
"m-","mx-","my-","mt-","mb-","ml-","mr-",
|
|
73
|
+
"w-","h-","min-w-","max-w-","min-h-","max-h-","size-",
|
|
74
|
+
"flex-","grid-","col-","row-","auto-cols-","auto-rows-",
|
|
75
|
+
"gap-","gap-x-","gap-y-","space-x-","space-y-",
|
|
76
|
+
"items-","justify-","self-","content-","place-",
|
|
77
|
+
"border-","rounded-","ring-","outline-","divide-","shadow-",
|
|
78
|
+
"z-","inset-","inset-x-","inset-y-","top-","right-","bottom-","left-","start-","end-",
|
|
79
|
+
"leading-","tracking-","whitespace-","break-","indent-","align-",
|
|
80
|
+
"decoration-","underline-offset-",
|
|
81
|
+
"opacity-","overflow-","object-","float-","clear-",
|
|
82
|
+
"transition-","duration-","ease-","delay-","animate-",
|
|
83
|
+
"scale-","rotate-","translate-","skew-","origin-",
|
|
84
|
+
"cursor-","pointer-events-","select-","touch-","scroll-","snap-",
|
|
85
|
+
"accent-","caret-","will-change-","contain-",
|
|
86
|
+
"fill-","stroke-","aspect-","columns-",
|
|
87
|
+
"from-","via-","to-","gradient-",
|
|
88
|
+
"backdrop-","blur-","brightness-","contrast-","drop-shadow-",
|
|
89
|
+
"grayscale-","hue-rotate-","invert-","saturate-","sepia-",
|
|
90
|
+
"ring-offset-",
|
|
91
|
+
"list-","order-","basis-","grow-","shrink-",
|
|
92
|
+
"sr-","appearance-",
|
|
93
|
+
"transform-",
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
for (const p of prefixes) {
|
|
97
|
+
if (bNoOpacity.startsWith(p)) return true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (b.startsWith("[") && b.endsWith("]")) return true;
|
|
101
|
+
if (/\[.+\]/.test(b)) return true;
|
|
102
|
+
if (/\(/.test(b) && /^[a-z]/.test(b)) return true;
|
|
103
|
+
|
|
104
|
+
if (/^(line-through|no-underline|normal-case|not-italic|subpixel-antialiased|table-auto|table-fixed|border-collapse|border-separate|sr-only|not-sr-only|break-words|break-all|break-normal|overflow-auto|overflow-hidden|overflow-visible|overflow-scroll|overflow-x-auto|overflow-x-hidden|overflow-y-auto|overflow-y-hidden|overflow-y-scroll|inline-block|inline-flex|inline-grid|flow-root|list-item|outline-hidden|outline-none|bg-clip-padding|bg-gradient-to-t|bg-gradient-to-b|bg-gradient-to-l|bg-gradient-to-r|not-prose|transform-gpu)$/.test(bNoOpacity))
|
|
105
|
+
return true;
|
|
106
|
+
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function looksLikeTailwindUtility(token) {
|
|
111
|
+
if (!token) return false;
|
|
112
|
+
if (token.startsWith(PREFIX)) return false;
|
|
113
|
+
if (token.startsWith("@")) return false;
|
|
114
|
+
if (token.startsWith("data-") && !token.includes(":")) return false;
|
|
115
|
+
|
|
116
|
+
let base = stripVariants(token);
|
|
117
|
+
if (!base) return false;
|
|
118
|
+
|
|
119
|
+
// Already prefixed somewhere after stripping known variants.
|
|
120
|
+
// Uses includes() instead of startsWith() to handle unknown variants
|
|
121
|
+
// that aren't in VARIANT_RE (e.g. *: child variant, &: nesting).
|
|
122
|
+
if (base.includes(PREFIX)) return false;
|
|
123
|
+
|
|
124
|
+
return isBaseUtility(base);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Token prefixing ─────────────────────────────────────────────────────────
|
|
128
|
+
// In Tailwind v4 with prefix(cpk), the prefix MUST come before all variants:
|
|
129
|
+
// cpk:dark:hover:bg-white ✓
|
|
130
|
+
// dark:hover:cpk:bg-white ✗ (generates no CSS)
|
|
131
|
+
|
|
132
|
+
function prefixToken(token) {
|
|
133
|
+
if (!looksLikeTailwindUtility(token)) return token;
|
|
134
|
+
return PREFIX + token;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Detect tokens where cpk: is placed after variant(s) instead of before them.
|
|
138
|
+
// e.g. dark:cpk:bg-white, hover:cpk:text-blue, dark:hover:cpk:bg-red
|
|
139
|
+
const WRONG_PREFIX_RE = /^((?:[a-z][-a-z0-9]*(?:\[.*?\])?:|\[.*?\]:)+)cpk:(.+)$/;
|
|
140
|
+
|
|
141
|
+
function hasWrongPrefixPosition(token) {
|
|
142
|
+
return WRONG_PREFIX_RE.test(token);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function fixPrefixPosition(token) {
|
|
146
|
+
return token.replace(WRONG_PREFIX_RE, "cpk:$1$2");
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ── ESLint rule ─────────────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
const rule = {
|
|
152
|
+
meta: {
|
|
153
|
+
type: "suggestion",
|
|
154
|
+
docs: {
|
|
155
|
+
description:
|
|
156
|
+
"Enforce cpk: prefix on Tailwind utility classes in className attributes",
|
|
157
|
+
},
|
|
158
|
+
fixable: "code",
|
|
159
|
+
schema: [],
|
|
160
|
+
messages: {
|
|
161
|
+
missingPrefix:
|
|
162
|
+
"'{{token}}' is missing the 'cpk:' prefix. Use '{{fixed}}' instead. See eslint-rules/README.md for why.",
|
|
163
|
+
wrongPrefixPosition:
|
|
164
|
+
"'{{token}}' has 'cpk:' in the wrong position. The prefix must come BEFORE variants. Use '{{fixed}}' instead. See eslint-rules/README.md for why.",
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
create(context) {
|
|
169
|
+
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
170
|
+
const CLASS_HELPERS = new Set(["cn", "twMerge", "cva", "clsx"]);
|
|
171
|
+
const checked = new WeakSet();
|
|
172
|
+
|
|
173
|
+
// ── String-literal checker ────────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
function checkStringLiteral(node) {
|
|
176
|
+
if (checked.has(node)) return;
|
|
177
|
+
checked.add(node);
|
|
178
|
+
|
|
179
|
+
const value = node.value;
|
|
180
|
+
if (typeof value !== "string" || !value.trim()) return;
|
|
181
|
+
|
|
182
|
+
// Skip single-word strings that look like JS values, not class names
|
|
183
|
+
const trimmed = value.trim();
|
|
184
|
+
if (!trimmed.includes(" ") && !trimmed.includes("\t")) {
|
|
185
|
+
if (JS_VALUE_WORDS.has(trimmed)) return;
|
|
186
|
+
if (
|
|
187
|
+
!trimmed.includes("-") &&
|
|
188
|
+
!trimmed.includes(":") &&
|
|
189
|
+
!trimmed.includes("[")
|
|
190
|
+
)
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Work with the raw source to get accurate positions
|
|
195
|
+
const src = sourceCode.getText(node);
|
|
196
|
+
const inner = src.slice(1, -1); // strip quotes
|
|
197
|
+
const innerStart = node.range[0] + 1;
|
|
198
|
+
|
|
199
|
+
const regex = /\S+/g;
|
|
200
|
+
let match;
|
|
201
|
+
while ((match = regex.exec(inner)) !== null) {
|
|
202
|
+
const token = match[0];
|
|
203
|
+
const rangeStart = innerStart + match.index;
|
|
204
|
+
const rangeEnd = rangeStart + token.length;
|
|
205
|
+
|
|
206
|
+
if (hasWrongPrefixPosition(token)) {
|
|
207
|
+
const fixed = fixPrefixPosition(token);
|
|
208
|
+
context.report({
|
|
209
|
+
node,
|
|
210
|
+
messageId: "wrongPrefixPosition",
|
|
211
|
+
data: { token, fixed },
|
|
212
|
+
fix(fixer) {
|
|
213
|
+
return fixer.replaceTextRange([rangeStart, rangeEnd], fixed);
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
} else if (looksLikeTailwindUtility(token)) {
|
|
217
|
+
const fixed = prefixToken(token);
|
|
218
|
+
context.report({
|
|
219
|
+
node,
|
|
220
|
+
messageId: "missingPrefix",
|
|
221
|
+
data: { token, fixed },
|
|
222
|
+
fix(fixer) {
|
|
223
|
+
return fixer.replaceTextRange([rangeStart, rangeEnd], fixed);
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// ── Template-literal quasi checker ────────────────────────────────────
|
|
231
|
+
|
|
232
|
+
function checkQuasi(quasi) {
|
|
233
|
+
if (checked.has(quasi)) return;
|
|
234
|
+
checked.add(quasi);
|
|
235
|
+
|
|
236
|
+
const raw = quasi.value.raw;
|
|
237
|
+
if (!raw || !raw.trim()) return;
|
|
238
|
+
|
|
239
|
+
// Find where the raw content starts in the source.
|
|
240
|
+
// TemplateElement ranges include delimiters (` or ${ or }).
|
|
241
|
+
const srcSlice = sourceCode.text.slice(quasi.range[0], quasi.range[1]);
|
|
242
|
+
const rawIdx = srcSlice.indexOf(raw);
|
|
243
|
+
const contentStart = quasi.range[0] + (rawIdx >= 0 ? rawIdx : 1);
|
|
244
|
+
|
|
245
|
+
const regex = /\S+/g;
|
|
246
|
+
let match;
|
|
247
|
+
while ((match = regex.exec(raw)) !== null) {
|
|
248
|
+
const token = match[0];
|
|
249
|
+
const rangeStart = contentStart + match.index;
|
|
250
|
+
const rangeEnd = rangeStart + token.length;
|
|
251
|
+
|
|
252
|
+
if (hasWrongPrefixPosition(token)) {
|
|
253
|
+
const fixed = fixPrefixPosition(token);
|
|
254
|
+
context.report({
|
|
255
|
+
node: quasi,
|
|
256
|
+
messageId: "wrongPrefixPosition",
|
|
257
|
+
data: { token, fixed },
|
|
258
|
+
fix(fixer) {
|
|
259
|
+
return fixer.replaceTextRange([rangeStart, rangeEnd], fixed);
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
} else if (looksLikeTailwindUtility(token)) {
|
|
263
|
+
const fixed = prefixToken(token);
|
|
264
|
+
context.report({
|
|
265
|
+
node: quasi,
|
|
266
|
+
messageId: "missingPrefix",
|
|
267
|
+
data: { token, fixed },
|
|
268
|
+
fix(fixer) {
|
|
269
|
+
return fixer.replaceTextRange([rangeStart, rangeEnd], fixed);
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// ── Recursive expression walker ───────────────────────────────────────
|
|
277
|
+
|
|
278
|
+
function checkExpression(node) {
|
|
279
|
+
if (!node) return;
|
|
280
|
+
|
|
281
|
+
switch (node.type) {
|
|
282
|
+
case "Literal":
|
|
283
|
+
case "StringLiteral": // babel parser
|
|
284
|
+
if (typeof node.value === "string") checkStringLiteral(node);
|
|
285
|
+
break;
|
|
286
|
+
|
|
287
|
+
case "JSXExpressionContainer":
|
|
288
|
+
checkExpression(node.expression);
|
|
289
|
+
break;
|
|
290
|
+
|
|
291
|
+
case "TemplateLiteral":
|
|
292
|
+
for (const quasi of node.quasis) checkQuasi(quasi);
|
|
293
|
+
for (const expr of node.expressions) checkExpression(expr);
|
|
294
|
+
break;
|
|
295
|
+
|
|
296
|
+
case "ConditionalExpression":
|
|
297
|
+
checkExpression(node.consequent);
|
|
298
|
+
checkExpression(node.alternate);
|
|
299
|
+
break;
|
|
300
|
+
|
|
301
|
+
case "LogicalExpression":
|
|
302
|
+
// e.g. isActive && "bg-blue-500"
|
|
303
|
+
checkExpression(node.left);
|
|
304
|
+
checkExpression(node.right);
|
|
305
|
+
break;
|
|
306
|
+
|
|
307
|
+
case "CallExpression":
|
|
308
|
+
if (isClassHelper(node.callee)) {
|
|
309
|
+
for (const arg of node.arguments) checkExpression(arg);
|
|
310
|
+
}
|
|
311
|
+
break;
|
|
312
|
+
|
|
313
|
+
case "ArrayExpression":
|
|
314
|
+
for (const el of node.elements) {
|
|
315
|
+
if (el) checkExpression(el);
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
|
|
319
|
+
case "ObjectExpression":
|
|
320
|
+
// For cva variant objects: { variant: { default: "...", ... } }
|
|
321
|
+
for (const prop of node.properties) {
|
|
322
|
+
if (prop.value) checkExpression(prop.value);
|
|
323
|
+
}
|
|
324
|
+
break;
|
|
325
|
+
|
|
326
|
+
case "SpreadElement":
|
|
327
|
+
break;
|
|
328
|
+
|
|
329
|
+
default:
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function isClassHelper(callee) {
|
|
335
|
+
if (!callee) return false;
|
|
336
|
+
if (callee.type === "Identifier") {
|
|
337
|
+
return CLASS_HELPERS.has(callee.name);
|
|
338
|
+
}
|
|
339
|
+
// Handle e.g. module.cn()
|
|
340
|
+
if (callee.type === "MemberExpression" && callee.property) {
|
|
341
|
+
const name =
|
|
342
|
+
callee.property.type === "Identifier"
|
|
343
|
+
? callee.property.name
|
|
344
|
+
: callee.property.value;
|
|
345
|
+
return CLASS_HELPERS.has(name);
|
|
346
|
+
}
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ── Visitors ──────────────────────────────────────────────────────────
|
|
351
|
+
|
|
352
|
+
return {
|
|
353
|
+
JSXAttribute(node) {
|
|
354
|
+
if (
|
|
355
|
+
node.name &&
|
|
356
|
+
node.name.type === "JSXIdentifier" &&
|
|
357
|
+
node.name.name === "className" &&
|
|
358
|
+
node.value
|
|
359
|
+
) {
|
|
360
|
+
checkExpression(node.value);
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
CallExpression(node) {
|
|
365
|
+
if (isClassHelper(node.callee)) {
|
|
366
|
+
for (const arg of node.arguments) {
|
|
367
|
+
checkExpression(arg);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
};
|
|
372
|
+
},
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
export default rule;
|
package/eslint.config.mjs
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import { config as reactConfig } from "@copilotkitnext/eslint-config/react-internal";
|
|
2
|
+
import requireCpkPrefix from "./eslint-rules/require-cpk-prefix.mjs";
|
|
2
3
|
|
|
3
4
|
export default [
|
|
4
5
|
...reactConfig,
|
|
5
6
|
{
|
|
7
|
+
plugins: {
|
|
8
|
+
copilotkit: {
|
|
9
|
+
rules: {
|
|
10
|
+
"require-cpk-prefix": requireCpkPrefix,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
6
14
|
rules: {
|
|
7
15
|
// Disable PropTypes validation since we use TypeScript for type checking
|
|
8
16
|
"react/prop-types": "off",
|
|
17
|
+
"copilotkit/require-cpk-prefix": "warn",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
// Disable cpk: prefix rule in test files — tests contain user-provided
|
|
21
|
+
// className overrides that intentionally omit the prefix.
|
|
22
|
+
{
|
|
23
|
+
files: ["**/__tests__/**", "**/*.test.*", "**/*.spec.*"],
|
|
24
|
+
rules: {
|
|
25
|
+
"copilotkit/require-cpk-prefix": "off",
|
|
9
26
|
},
|
|
10
27
|
},
|
|
11
28
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkitnext/react",
|
|
3
|
-
"version": "1.52.0-next.
|
|
3
|
+
"version": "1.52.0-next.6",
|
|
4
4
|
"description": "React components for CopilotKit2",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"types": "./dist/index.d.cts",
|
|
@@ -32,13 +32,14 @@
|
|
|
32
32
|
"concurrently": "^9.1.0",
|
|
33
33
|
"eslint": "^9.30.0",
|
|
34
34
|
"jsdom": "^26.1.0",
|
|
35
|
-
"
|
|
35
|
+
"postcss": "^8.5.6",
|
|
36
36
|
"rxjs": "^7.8.1",
|
|
37
|
+
"tailwindcss": "^4.0.8",
|
|
37
38
|
"tsdown": "^0.20.3",
|
|
38
39
|
"typescript": "5.8.2",
|
|
39
40
|
"vitest": "^3.2.4",
|
|
40
|
-
"@copilotkitnext/eslint-config": "1.52.0-next.
|
|
41
|
-
"@copilotkitnext/typescript-config": "1.52.0-next.
|
|
41
|
+
"@copilotkitnext/eslint-config": "1.52.0-next.6",
|
|
42
|
+
"@copilotkitnext/typescript-config": "1.52.0-next.6"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
45
|
"@ag-ui/client": "0.0.45",
|
|
@@ -57,9 +58,9 @@
|
|
|
57
58
|
"tw-animate-css": "^1.3.5",
|
|
58
59
|
"use-stick-to-bottom": "^1.1.1",
|
|
59
60
|
"zod": "^3.25.75",
|
|
60
|
-
"@copilotkitnext/core": "1.52.0-next.
|
|
61
|
-
"@copilotkitnext/shared": "1.52.0-next.
|
|
62
|
-
"@copilotkitnext/web-inspector": "1.52.0-next.
|
|
61
|
+
"@copilotkitnext/core": "1.52.0-next.6",
|
|
62
|
+
"@copilotkitnext/shared": "1.52.0-next.6",
|
|
63
|
+
"@copilotkitnext/web-inspector": "1.52.0-next.6"
|
|
63
64
|
},
|
|
64
65
|
"peerDependencies": {
|
|
65
66
|
"react": ">=16.8.0",
|