@progress/kendo-react-mcp 1.6.0 → 1.6.1-beta.079a6439.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.
package/dist/index.js CHANGED
@@ -1,15 +1,780 @@
1
1
  #!/usr/bin/env node
2
- import{McpServer as St}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Tt}from"@modelcontextprotocol/sdk/server/stdio.js";import{dirname as ct,join as lt}from"path";import{fileURLToPath as dt}from"url";import{loadLicense as Je,decodeLicenseKey as Xe,decodeLicenseEvidence as Ze}from"@progress/kendo-licensing/utils";var B=class extends Error{constructor(t){super(t),this.name="LicenseError"}};function te(e){return e.replace(/^\uFEFF/,"")}async function oe(e){let t=null,n=null;try{let o=Je();if(!o.success){let s=new B(o.message);throw e&&await e("license_load_failed",{error:o.message}).catch(()=>{}),s}try{t=(await Xe(o.value)).licenses.find(async r=>!!(await Ze(r)).userId)}catch(s){console.log(s.message),e&&await e("license_load_failed",{error:s.message||"Unknown decoding error"}).catch(()=>{})}if(!t)return[te(o.value),null]}catch(o){return n=o.message||"Unknown error loading license.",e&&await e("license_load_failed",{error:n}).catch(()=>{}),[null,n]}return[te(t),null]}import P from"node:fs";import G from"node:path";var q=!1,E=process.env.DEBUG_LOG_FILE,ne=!!(E&&typeof E=="string");if(ne){let e=G.resolve(E),t=G.dirname(e);if(t!=="."&&t!==process.cwd()&&!P.existsSync(t))try{P.mkdirSync(t,{recursive:!0})}catch(n){console.error("Error creating log directory:",n)}if(!P.existsSync(e))try{P.writeFileSync(e,"")}catch(n){console.error("Error creating log file:",n)}}else q=!1;q=ne&&!!E&&P.existsSync(G.resolve(E));function g(...e){if(q&&E){let o=`${new Date().toISOString()}: ${e.join(" ")}
3
- `,s=G.resolve(E);P.appendFile(s,o,r=>{r&&console.error("Error writing to log file:",r)})}}import et from"@grpc/proto-loader";import $ from"@grpc/grpc-js";import re from"path";import se from"fs";import{fileURLToPath as tt}from"url";var ot=tt(import.meta.url),nt=re.dirname(ot),ie={version:"unknown"},ae=re.resolve(nt,"../package.json");se.existsSync(ae)&&(ie=JSON.parse(se.readFileSync(ae,"utf-8")));function st(e){return e.replace(/\u2014/g,"--").replace(/\u2013/g,"-").replace(/[^\x20-\x7E]/g,"")}var M=class{constructor(t,n,o){this.contextApiUrl=t;this.protoPath=n;this.options=o;this.toolNameHeader="assistant";let s=et.loadSync(this.protoPath,{keepCase:!0,longs:String,enums:String,defaults:!0,oneofs:!0});this.isDev=this.contextApiUrl?.includes("localhost")||this.contextApiUrl?.includes("127.0.0.1"),g("Using ContextApi URl:",this.contextApiUrl);let r=$.loadPackageDefinition(s);this.client=new r.ContextQueryService(this.contextApiUrl||"contextapi.telerik.com:443",this.isDev?$.credentials.createInsecure():$.credentials.createSsl())}async getMetadata({meta:t}={meta:{}}){let[n,o]=this.isDev?["fake_license",null]:await oe((m,A)=>this.logEvent(m,A)),s=process.env.CONTEXTAPI_API_KEY,r=s&&typeof s=="string",a=n&&typeof n=="string";if(!a&&!r&&o)throw new Error(`Failed to authenticate with API key or License key!
4
2
 
5
- License Error: ${o}`);let i=new $.Metadata;if(a)try{i.add("x-license-key",n)}catch(m){throw g("Error adding license key to metadata:",m),new Error(`Failed to use license key: ${m.message}`)}r&&i.add("x-api-key",s),this.options?.libName&&i.add("x-library-name",this.options.libName),i.add("x-tool-name",this.toolNameHeader);let d=JSON.stringify({...t,source:"npm",version:ie.version,os:process.platform,node_version:process.version});return i.add("x-request-metadata",st(d)),i}async query(t,n){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.query(t,o,(a,i)=>{a?r(new Error(a)):s(i)})})}async getApiRefMatches(t,n){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.getApiRefMatches(t,o,(a,i)=>{a?r(new Error(a)):s(i)})})}async queryCssUtils(t,n){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.cssUtilsSearch(t,o,(a,i)=>{a?(g("Error querying CSS Utils:",a),r(new Error(a))):s(i)})})}async queryIconsSearch(t,n){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.iconsSearch(t,o,(a,i)=>{a?(g("Error querying Icons Search:",a),r(new Error(a))):s(i)})})}async queryBuildingBlocks(t,n){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.buildingBlocksSearch(t,o,(a,i)=>{a?(g("Error querying Building Blocks:",a),r(new Error(a))):s(i)})})}async validateUserLicense(){let t=await this.getMetadata();return new Promise((n,o)=>{this.client.validateUserLicense(null,t,(s,r)=>{s?(g("Error validating user license:",s),o(new Error(s))):n(r)})})}async queryThemeGenerate(t,n){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.generateTheme(t,o,(a,i)=>{a?(g("Error querying context API/GenerateTheme:",a),r(new Error(a))):s(i)})})}async recordOrchestratorUserRequest({meta:t}){let n=await this.getMetadata({meta:t});return new Promise((o,s)=>{this.client.recordOrchestratorUserRequest(null,n,(r,a)=>{r?(g("Error recording orchestrator user request:",r),s(new Error(r))):o(a)})})}async recordToolUserRequest({toolName:t,meta:n}){let o=await this.getMetadata({meta:n});return new Promise((s,r)=>{this.client.recordToolUserRequest({tool_name:t},o,(a,i)=>{a?(g("Error recording tool user request:",a),r(new Error(a))):s(i)})})}async logEvent(t,n){let o="h8utJ6rk4PpIWX4JMn9beQDsjVUri6KV0XYfiVwq";if(!o||typeof o!="string"){g("LOGGING_API_KEY not configured, skipping log event");return}let s=new $.Metadata;return s.add("x-api-key",o),new Promise((r,a)=>{this.client.logEvent({event_name:t,fields:n||{}},s,(i,d)=>{i?(g("Error logging event:",i),a(new Error(i))):r()})})}};import{z as K}from"zod";var Ht=K.object({user_id:K.string(),user_email:K.string().email()});import{z as b}from"zod";var at=b.object({Product:b.object({Id:b.number().int(),Code:b.string(),Name:b.string()}),License:b.nullable(b.object({Id:b.number().int(),Name:b.string(),Type:b.string(),Active:b.boolean()})),Availability:b.array(b.object({LicenseStart:b.nullable(b.string().datetime()),LicenseEnd:b.nullable(b.string().datetime())})),IsLicenseAvailable:b.optional(b.boolean())}),Yt=b.array(at);async function ce(e){let t=process.env.KENDO_MCP_ACCESS;if(t==="true"||t==="1"||t==="full")return"full";if(typeof t=="string"&&(t.toLowerCase()==="agent"||t.toLowerCase()==="assistant"))return t.toLowerCase();let n=await e();return n.toLocaleLowerCase()==="agentic_ui_generator"?"agent":n.toLocaleLowerCase()==="ai_coding_assistants"?"assistant":"none"}function le(){return'**Accessibility Guidelines: WCAG 2.2 Level AA Compliance**\n\n**Core Principles:**\n1. Use semantic HTML and ARIA correctly\n2. Ensure WCAG 2.2 AA compliance\n3. Follow W3C ARIA Authoring Practices\n4. Provide standards-based accessibility fixes\n\n**1. Form Control Labels** (WCAG 1.3.1, 3.3.2, 4.1.2)\nEvery input must have an associated label.\nCORRECT: `<input type="search" aria-label="Search products" placeholder="Search...">`\nWRONG: `<span>Email</span><input type="email">` (no association)\nWRONG: `<input type="email" placeholder="Email">` (placeholder as label)\n\n**2. Button Accessibility** (WCAG 4.1.2, 2.4.6, 2.5.3)\nAll buttons need accessible names describing their purpose.\nCORRECT: `<button type="button">Save Changes</button>`\nCORRECT: `<button aria-label="Close dialog"><svg aria-hidden="true" focusable="false">...</svg></button>`\nWRONG: `<button><svg>...</svg></button>` (no accessible name)\nWRONG: `<button>Click here</button>` (generic text)\n\n**3. Popup/Menu Triggers** (WCAG 4.1.2, 1.3.1)\nIndicate popup purpose and state using aria-haspopup, aria-expanded, aria-controls.\nCORRECT: `<button aria-expanded="false" aria-haspopup="menu" aria-controls="menu-id">Settings</button>`\n\n**4. Image Accessibility** (WCAG 1.1.1)\nInformative: `<img src="chart.png" alt="Sales increased 25% in Q4 2024">`\nFunctional: `<a href="/home"><img src="logo.png" alt="Company Name Home"></a>`\nDecorative: `<img src="border.png" alt="" role="presentation">`\nComplex: `<img src="chart.png" alt="Sales data" aria-describedby="desc-id">`\nWRONG: Missing alt, filename as alt, generic alt for decorative images\n\n**5. Link Accessibility** (WCAG 2.4.4, 2.4.6)\nLinks must be descriptive and understandable out of context.\nCORRECT: `<a href="/products">View All Products</a>`\nCORRECT: `<a href="/article" aria-label="Read more about New Product Launch">Read more</a>`\nWRONG: "Click here", "Read more", "Learn more" without context\n\n**6. Form Validation** (WCAG 3.3.1, 3.3.2, 3.3.3)\nErrors must be identified, associated with inputs, and provide suggestions. Use aria-describedby, aria-invalid="true", and role="alert".\n\n**7. Heading Structure** (WCAG 1.3.1, 2.4.6)\nEach page should have an `<h1>` that describes its content. Use hierarchical, descriptive headings with no skipped levels (h1\u2192h2\u2192h3).\nCORRECT: `<h1>Dashboard</h1> <h2>Sales</h2> <h3>By Region</h3>`\nWRONG: No `<h1>` on the page, or skipping levels (h1\u2192h3)\nIf a heading should look smaller than its semantic level, use CSS: `<h2 class="text-sm">Subtitle</h2>`\n\n**8. Page Component Landmark Rules** (WCAG 1.3.1, 4.1.2)\nPage components (route components) may be rendered inside a layout that already provides `<main>`, `<header>`, or `<footer>`. Since the layout configuration is unknown, avoid using these landmarks in page components to prevent potential duplication and nesting violations. Use `<div>`, `<section>`, or `<article>` as the top-level wrapper instead.\n\n**Quick Checklist:**\n- **Forms:** Associated labels, aria-required on required fields, autocomplete attributes, aria-describedby for errors, aria-invalid for invalid fields, fieldsets with legends\n- **Buttons/Links:** Accessible names, aria-label for icon buttons, aria-hidden on decorative icons, descriptive link text\n- **Popups/Dialogs:** aria-haspopup, aria-expanded, aria-controls, role="dialog", aria-modal="true", aria-labelledby, focus trap, Escape to close\n- **Images:** alt on all images, descriptive alt for informative, empty alt for decorative, aria-describedby for complex\n- **Structure:** One h1, logical heading hierarchy, avoid `<main>`, `<header>`, or `<footer>` in page/route components (the layout may already provide them), use `<section>` or `<div>` as page-level wrappers, semantic HTML\n- **Dynamic Content:** role="status"/aria-live="polite" for updates, role="alert"/aria-live="assertive" for critical alerts\n- **Keyboard/Focus:** All interactive elements keyboard accessible, logical focus order, visible focus indicators, no keyboard traps (except modals)\n- **Color/Contrast:** 4.5:1 text contrast (3:1 large text), 3:1 UI component contrast, no color-only information, 3:1 focus indicator contrast'}var rt=1440*60*1e3;function de(e){let{serverName:t,contextApi:n,additionalFields:o={},intervalMs:s=rt}=e,r="mcp_server_heartbeat",a=async()=>{try{let d={server_name:t,timestamp:new Date().toISOString(),...o};await n.logEvent(r,d)}catch(d){g(`Failed to send heartbeat for ${t}:`,d)}};a();let i=setInterval(a,s);return()=>{clearInterval(i),g(`Heartbeat stopped for ${t}`)}}import{z as F}from"zod";var it=["default","bootstrap","material","fluent"];function pe(e,t){return{projectName:F.string().default(t).describe("The name of the project. Used as the project folder name when creating a new project."),createNewProject:F.boolean().default(!0).describe(`Whether to create a new project before configuring ${e}. Set to true to scaffold a brand-new project, or false if the project already exists and you only want to add ${e} to it.`),theme:F.enum(it).default("default").describe("The Kendo UI theme to use. Determines which theme package is installed and imported.")}}var l="Kendo UI for React",I="react",w="kendo";var O=["ActionSheet","AIPrompt","Animation","AppBar","ArcGauge","AutoComplete","Avatar","Badge","Barcode","BottomNavigation","Breadcrumb","Button","ButtonGroup","BreadCrumb","Calendar","Card","Chart","ChartWizard","Chat","Checkbox","Chip","ChipList","ChunkProgressBar","CircularGauge","ColorGradient","ColorPalette","ColorPicker","ComboBox","ContextMenu","ConversationalUI","DataGrid","Grid","DataQuery","DateMath","DateInput","DatePicker","DateRangePicker","DateTimePicker","Dialog","Drag&Drop","Drawer","Drawing","DropDownButton","DropDownList","DropDownTree","Editor","Error","ExcelExport","ExpansionPanel","ExternalDropZone","FileSaver","FileManager","Filter","FlatColorPicker","FloatingActionButton","FloatingLabel","Form","Gantt","Gauge","General","GridLayout","Hint","Icon","InlineAIPrompt","Input","Label","LinearGauge","ListBox","ListView","Loader","Map","MaskedTextBox","Menu","MultiColumnComboBox","MultiSelect","MultiSelectTree","MultiViewCalendar","Notification","NumericTextBox","OrgChart","PageTemplates/BuildingBlocks","Pager","PanelBar","PDFProcessing","PDFViewer","PivotGrid","Popover","Popup","ProgressBar","PromptBox","QRCode","RadialGauge","RadioButton","RadioGroup","RangeSlider","Rating","Ripple","Sankey","Scheduler","ScrollView","Signature","Skeleton","Slider","Sortable","Sparkline","SpeechToTextButton","SmartPasteButton","SplitButton","Splitter","Spreadsheet","StackLayout","Stepper","StockChart","SVGIcon","Switch","TabStrip","TaskBoard","TextArea","TextBox","TileLayout","Timeline","TimePicker","Toolbar","Tooltip","TreeList","TreeView","Typography","Upload","VSCodeExtension","Window"];var pt=lt(ct(dt(import.meta.url)),"../proto/service.proto"),_=new M("contextapi.telerik.com:443",pt,{libName:I});var me=async()=>_.validateUserLicense();import vt from"fs";import ze from"path";import{fileURLToPath as kt}from"url";import{z as C}from"zod";var v=class{constructor(t,n,o){this.name=t;this.config=n;this.cb=o}register(t){this.server=t,this.server.registerTool(this.name,this.config,this.cb)}hasAccess(t){return!this.config.requiredAccess||this.config.requiredAccess.length===0?!0:t==="full"||this.config.requiredAccess.includes(t)}};var D=(e,t)=>`# ${e.suiteName} - Code Validation & Quality Assurance
3
+ // packages/react/src/index.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
+
7
+ // packages/react/src/lib/grpc-client.ts
8
+ import { dirname, join } from "path";
9
+ import { fileURLToPath as fileURLToPath2 } from "url";
10
+
11
+ // packages/mcp-common/src/lib/read-license.ts
12
+ import {
13
+ loadLicense,
14
+ decodeLicenseKey,
15
+ decodeLicenseEvidence
16
+ } from "@progress/kendo-licensing/utils";
17
+ var LicenseError = class extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "LicenseError";
21
+ }
22
+ };
23
+ function fixBom(licenseKey) {
24
+ return licenseKey.replace(/^\uFEFF/, "");
25
+ }
26
+ async function readLicense(logCallback) {
27
+ let licenseEvidence = null;
28
+ let error = null;
29
+ try {
30
+ const license = loadLicense();
31
+ if (!license.success) {
32
+ const licenseError = new LicenseError(license.message);
33
+ if (logCallback) {
34
+ await logCallback("license_load_failed", {
35
+ error: license.message
36
+ }).catch(() => {
37
+ });
38
+ }
39
+ throw licenseError;
40
+ }
41
+ try {
42
+ const decodedLicense = await decodeLicenseKey(license.value);
43
+ licenseEvidence = decodedLicense.licenses.find(async (lic) => {
44
+ const evidence = await decodeLicenseEvidence(lic);
45
+ if (evidence.userId) {
46
+ return true;
47
+ }
48
+ return false;
49
+ });
50
+ } catch (err) {
51
+ console.log(err.message);
52
+ if (logCallback) {
53
+ await logCallback("license_load_failed", {
54
+ error: err.message || "Unknown decoding error"
55
+ }).catch(() => {
56
+ });
57
+ }
58
+ }
59
+ if (!licenseEvidence) {
60
+ return [fixBom(license.value), null];
61
+ }
62
+ } catch (err) {
63
+ error = err.message || "Unknown error loading license.";
64
+ if (logCallback) {
65
+ await logCallback("license_load_failed", {
66
+ error
67
+ }).catch(() => {
68
+ });
69
+ }
70
+ return [null, error];
71
+ }
72
+ return [fixBom(licenseEvidence), null];
73
+ }
74
+
75
+ // packages/mcp-common/src/lib/logger.ts
76
+ import fs from "node:fs";
77
+ import path from "node:path";
78
+ var LOG_ENABLED = false;
79
+ var LOG_FILE = process.env.DEBUG_LOG_FILE;
80
+ var LOG_FILE_DEFINED = !!(LOG_FILE && typeof LOG_FILE === "string");
81
+ if (LOG_FILE_DEFINED) {
82
+ const resolvedLogFile = path.resolve(LOG_FILE);
83
+ const logDir = path.dirname(resolvedLogFile);
84
+ if (logDir !== "." && logDir !== process.cwd() && !fs.existsSync(logDir)) {
85
+ try {
86
+ fs.mkdirSync(logDir, { recursive: true });
87
+ } catch (err) {
88
+ console.error("Error creating log directory:", err);
89
+ }
90
+ }
91
+ if (!fs.existsSync(resolvedLogFile)) {
92
+ try {
93
+ fs.writeFileSync(resolvedLogFile, "");
94
+ } catch (err) {
95
+ console.error("Error creating log file:", err);
96
+ }
97
+ }
98
+ } else {
99
+ LOG_ENABLED = false;
100
+ }
101
+ LOG_ENABLED = LOG_FILE_DEFINED && !!LOG_FILE && fs.existsSync(path.resolve(LOG_FILE));
102
+ function log(...args) {
103
+ if (LOG_ENABLED && LOG_FILE) {
104
+ const date = /* @__PURE__ */ new Date();
105
+ const dateString = date.toISOString();
106
+ const logString = `${dateString}: ${args.join(" ")}
107
+ `;
108
+ const resolvedLogFile = path.resolve(LOG_FILE);
109
+ fs.appendFile(resolvedLogFile, logString, (err) => {
110
+ if (err) {
111
+ console.error("Error writing to log file:", err);
112
+ }
113
+ });
114
+ }
115
+ }
116
+
117
+ // packages/mcp-common/src/lib/context-api.ts
118
+ import protoLoader from "@grpc/proto-loader";
119
+ import grpc from "@grpc/grpc-js";
120
+ import path2 from "path";
121
+ import fs2 from "fs";
122
+ import { fileURLToPath } from "url";
123
+ var __filename = fileURLToPath(import.meta.url);
124
+ var __dirname = path2.dirname(__filename);
125
+ var packageJson = { version: "unknown" };
126
+ var packageJsonPath = path2.resolve(__dirname, "../package.json");
127
+ if (fs2.existsSync(packageJsonPath)) {
128
+ packageJson = JSON.parse(fs2.readFileSync(packageJsonPath, "utf-8"));
129
+ }
130
+ function sanitizeMetadata(value) {
131
+ return value.replace(/\u2014/g, "--").replace(/\u2013/g, "-").replace(/[^\x20-\x7E]/g, "");
132
+ }
133
+ var D2CError = class extends Error {
134
+ constructor(code, message, details) {
135
+ super(message);
136
+ this.code = code;
137
+ this.details = details;
138
+ this.name = "D2CError";
139
+ }
140
+ };
141
+ var ContextAPI = class {
142
+ constructor(contextApiUrl, protoPath2, options) {
143
+ this.contextApiUrl = contextApiUrl;
144
+ this.protoPath = protoPath2;
145
+ this.options = options;
146
+ this.toolNameHeader = "assistant";
147
+ const proto = protoLoader.loadSync(this.protoPath, {
148
+ keepCase: true,
149
+ longs: String,
150
+ enums: String,
151
+ defaults: true,
152
+ oneofs: true
153
+ });
154
+ this.isDev = this.contextApiUrl?.includes("localhost") || this.contextApiUrl?.includes("127.0.0.1");
155
+ log("Using ContextApi URl:", this.contextApiUrl);
156
+ const protoDescriptor = grpc.loadPackageDefinition(proto);
157
+ const maxMsgSize = 100 * 1024 * 1024;
158
+ const channelOptions = {
159
+ "grpc.max_receive_message_length": maxMsgSize,
160
+ "grpc.max_send_message_length": maxMsgSize
161
+ };
162
+ this.client = new protoDescriptor.ContextQueryService(
163
+ this.contextApiUrl || "contextapi.telerik.com:443",
164
+ this.isDev ? grpc.credentials.createInsecure() : grpc.credentials.createSsl(),
165
+ channelOptions
166
+ );
167
+ }
168
+ async getMetadata({ meta } = { meta: {} }) {
169
+ const [license, error] = this.isDev ? ["fake_license", null] : await readLicense((eventName, fields) => this.logEvent(eventName, fields));
170
+ const apiKey = process.env.CONTEXTAPI_API_KEY;
171
+ const hasApiKey = apiKey && typeof apiKey === "string";
172
+ const hasLicense = license && typeof license === "string";
173
+ if (!hasLicense && !hasApiKey && error) {
174
+ throw new Error(
175
+ `Failed to authenticate with API key or License key!
176
+
177
+ License Error: ${error}`
178
+ );
179
+ }
180
+ const metadata = new grpc.Metadata();
181
+ if (hasLicense) {
182
+ try {
183
+ metadata.add("x-license-key", license);
184
+ } catch (error2) {
185
+ log("Error adding license key to metadata:", error2);
186
+ throw new Error(`Failed to use license key: ${error2.message}`);
187
+ }
188
+ }
189
+ if (hasApiKey) {
190
+ metadata.add("x-api-key", apiKey);
191
+ }
192
+ if (this.options?.libName) {
193
+ metadata.add("x-library-name", this.options.libName);
194
+ }
195
+ metadata.add("x-tool-name", this.toolNameHeader);
196
+ const requestMetadata = JSON.stringify({
197
+ ...meta,
198
+ source: "npm",
199
+ version: packageJson.version,
200
+ os: process.platform,
201
+ node_version: process.version
202
+ });
203
+ metadata.add("x-request-metadata", sanitizeMetadata(requestMetadata));
204
+ return metadata;
205
+ }
206
+ async query(params, meta) {
207
+ const metadata = await this.getMetadata({ meta });
208
+ return new Promise((resolve, reject) => {
209
+ this.client.query(
210
+ params,
211
+ metadata,
212
+ (err, response) => {
213
+ if (err) {
214
+ reject(new Error(err));
215
+ } else {
216
+ resolve(response);
217
+ }
218
+ }
219
+ );
220
+ });
221
+ }
222
+ async getApiRefMatches(params, meta) {
223
+ const metadata = await this.getMetadata({ meta });
224
+ return new Promise((resolve, reject) => {
225
+ this.client.getApiRefMatches(
226
+ params,
227
+ metadata,
228
+ (err, response) => {
229
+ if (err) {
230
+ reject(new Error(err));
231
+ } else {
232
+ resolve(response);
233
+ }
234
+ }
235
+ );
236
+ });
237
+ }
238
+ async queryCssUtils(params, meta) {
239
+ const metadata = await this.getMetadata({ meta });
240
+ return new Promise((resolve, reject) => {
241
+ this.client.cssUtilsSearch(
242
+ params,
243
+ metadata,
244
+ (err, response) => {
245
+ if (err) {
246
+ log("Error querying CSS Utils:", err);
247
+ reject(new Error(err));
248
+ } else {
249
+ resolve(response);
250
+ }
251
+ }
252
+ );
253
+ });
254
+ }
255
+ async queryIconsSearch(params, meta) {
256
+ const metadata = await this.getMetadata({ meta });
257
+ return new Promise((resolve, reject) => {
258
+ this.client.iconsSearch(params, metadata, (err, response) => {
259
+ if (err) {
260
+ log("Error querying Icons Search:", err);
261
+ reject(new Error(err));
262
+ } else {
263
+ resolve(response);
264
+ }
265
+ });
266
+ });
267
+ }
268
+ async queryBuildingBlocks(params, meta) {
269
+ const metadata = await this.getMetadata({ meta });
270
+ return new Promise((resolve, reject) => {
271
+ this.client.buildingBlocksSearch(
272
+ params,
273
+ metadata,
274
+ (err, response) => {
275
+ if (err) {
276
+ log("Error querying Building Blocks:", err);
277
+ reject(new Error(err));
278
+ } else {
279
+ resolve(response);
280
+ }
281
+ }
282
+ );
283
+ });
284
+ }
285
+ async validateUserLicense() {
286
+ const metadata = await this.getMetadata();
287
+ return new Promise((resolve, reject) => {
288
+ this.client.validateUserLicense(
289
+ null,
290
+ metadata,
291
+ (err, response) => {
292
+ if (err) {
293
+ log("Error validating user license:", err);
294
+ reject(new Error(err));
295
+ } else {
296
+ resolve(response);
297
+ }
298
+ }
299
+ );
300
+ });
301
+ }
302
+ async queryThemeGenerate(params, meta) {
303
+ const metadata = await this.getMetadata({ meta });
304
+ return new Promise((resolve, reject) => {
305
+ this.client.generateTheme(params, metadata, (err, response) => {
306
+ if (err) {
307
+ log("Error querying context API/GenerateTheme:", err);
308
+ reject(new Error(err));
309
+ } else {
310
+ resolve(response);
311
+ }
312
+ });
313
+ });
314
+ }
315
+ async recordOrchestratorUserRequest({ meta }) {
316
+ const metadata = await this.getMetadata({ meta });
317
+ return new Promise((resolve, reject) => {
318
+ this.client.recordOrchestratorUserRequest(
319
+ null,
320
+ metadata,
321
+ (err, response) => {
322
+ if (err) {
323
+ log("Error recording orchestrator user request:", err);
324
+ reject(new Error(err));
325
+ } else {
326
+ resolve(response);
327
+ }
328
+ }
329
+ );
330
+ });
331
+ }
332
+ async recordToolUserRequest({ toolName, meta }) {
333
+ const metadata = await this.getMetadata({ meta });
334
+ return new Promise((resolve, reject) => {
335
+ this.client.recordToolUserRequest(
336
+ { tool_name: toolName },
337
+ metadata,
338
+ (err, response) => {
339
+ if (err) {
340
+ log("Error recording tool user request:", err);
341
+ reject(new Error(err));
342
+ } else {
343
+ resolve(response);
344
+ }
345
+ }
346
+ );
347
+ });
348
+ }
349
+ async logEvent(eventName, fields) {
350
+ const apiKey = "h8utJ6rk4PpIWX4JMn9beQDsjVUri6KV0XYfiVwq";
351
+ if (!apiKey || typeof apiKey !== "string") {
352
+ log("LOGGING_API_KEY not configured, skipping log event");
353
+ return;
354
+ }
355
+ const metadata = new grpc.Metadata();
356
+ metadata.add("x-api-key", apiKey);
357
+ return new Promise((resolve, reject) => {
358
+ this.client.logEvent(
359
+ { event_name: eventName, fields: fields || {} },
360
+ metadata,
361
+ (err, response) => {
362
+ if (err) {
363
+ log("Error logging event:", err);
364
+ reject(new Error(err));
365
+ } else {
366
+ resolve();
367
+ }
368
+ }
369
+ );
370
+ });
371
+ }
372
+ /**
373
+ * Process a Figma design through the D2C pipeline
374
+ *
375
+ * @param params - Figma design data and processing options
376
+ * @returns Processed design with layout, styles, and component matches
377
+ * @throws D2CError if processing fails
378
+ */
379
+ async processFigmaDesign(params) {
380
+ const metadata = await this.getMetadata();
381
+ const request = {};
382
+ if (params.node_jsons && params.node_jsons.length > 0) {
383
+ request.node_jsons = params.node_jsons;
384
+ } else if (params.root_node_json) {
385
+ request.node_jsons = [params.root_node_json];
386
+ } else {
387
+ throw new Error("Either node_jsons or root_node_json must be provided");
388
+ }
389
+ return new Promise((resolve, reject) => {
390
+ this.client.processFigmaDesign(
391
+ request,
392
+ metadata,
393
+ (err, response) => {
394
+ if (err) {
395
+ log("Error processing Figma design:", err);
396
+ reject(new Error(`gRPC error: ${err.message}`));
397
+ return;
398
+ }
399
+ if (response.error) {
400
+ const error = new D2CError(
401
+ response.error.code,
402
+ response.error.message,
403
+ response.error.details
404
+ );
405
+ log("D2C processing error:", error);
406
+ reject(error);
407
+ return;
408
+ }
409
+ if (response.success) {
410
+ const layoutPseudoCodes = response.success.layout_pseudo_codes || [];
411
+ const result = {
412
+ // Backward compatibility: first layout or empty string
413
+ layout_pseudo_code: layoutPseudoCodes[0] || response.success.layout_pseudo_code || "",
414
+ layout_pseudo_codes: layoutPseudoCodes.length > 0 ? layoutPseudoCodes : [response.success.layout_pseudo_code || ""],
415
+ design_tokens: response.success.design_tokens || "",
416
+ stats: {
417
+ total_nodes: response.success.stats?.total_nodes || 0,
418
+ processing_time_ms: response.success.stats?.processing_time_ms || 0
419
+ }
420
+ };
421
+ resolve(result);
422
+ return;
423
+ }
424
+ reject(new Error("Invalid response format from server"));
425
+ }
426
+ );
427
+ });
428
+ }
429
+ };
430
+
431
+ // packages/mcp-common/src/models/user.ts
432
+ import { z } from "zod";
433
+ var userInfoSchema = z.object({
434
+ user_id: z.string(),
435
+ user_email: z.string().email()
436
+ });
437
+
438
+ // packages/mcp-common/src/models/entitlements.ts
439
+ import { z as z2 } from "zod";
440
+ var itemSchema = z2.object({
441
+ Product: z2.object({
442
+ Id: z2.number().int(),
443
+ Code: z2.string(),
444
+ Name: z2.string()
445
+ }),
446
+ License: z2.nullable(
447
+ z2.object({
448
+ Id: z2.number().int(),
449
+ Name: z2.string(),
450
+ Type: z2.string(),
451
+ Active: z2.boolean()
452
+ })
453
+ ),
454
+ Availability: z2.array(
455
+ z2.object({
456
+ LicenseStart: z2.nullable(z2.string().datetime()),
457
+ LicenseEnd: z2.nullable(z2.string().datetime())
458
+ })
459
+ ),
460
+ IsLicenseAvailable: z2.optional(z2.boolean())
461
+ });
462
+ var entitlementsSchema = z2.array(itemSchema);
463
+
464
+ // packages/mcp-common/src/lib/utils.ts
465
+ async function checkAccess(cb) {
466
+ const access = process.env.KENDO_MCP_ACCESS;
467
+ if (access === "true" || access === "1" || access === "full") {
468
+ return "full";
469
+ } else if (typeof access === "string" && (access.toLowerCase() === "agent" || access.toLowerCase() === "assistant")) {
470
+ return access.toLowerCase();
471
+ }
472
+ const productCode = await cb();
473
+ if (productCode.toLocaleLowerCase() === "agentic_ui_generator") {
474
+ return "agent";
475
+ }
476
+ if (productCode.toLocaleLowerCase() === "ai_coding_assistants") {
477
+ return "assistant";
478
+ }
479
+ return "none";
480
+ }
481
+
482
+ // packages/mcp-common/src/lib/instructions/accessibility.ts
483
+ function getAccessibilityGuidelines() {
484
+ return `**Accessibility Guidelines: WCAG 2.2 Level AA Compliance**
485
+
486
+ **Core Principles:**
487
+ 1. Use semantic HTML and ARIA correctly
488
+ 2. Ensure WCAG 2.2 AA compliance
489
+ 3. Follow W3C ARIA Authoring Practices
490
+ 4. Provide standards-based accessibility fixes
491
+
492
+ **1. Form Control Labels** (WCAG 1.3.1, 3.3.2, 4.1.2)
493
+ Every input must have an associated label.
494
+ CORRECT: \`<input type="search" aria-label="Search products" placeholder="Search...">\`
495
+ WRONG: \`<span>Email</span><input type="email">\` (no association)
496
+ WRONG: \`<input type="email" placeholder="Email">\` (placeholder as label)
497
+
498
+ **2. Button Accessibility** (WCAG 4.1.2, 2.4.6, 2.5.3)
499
+ All buttons need accessible names describing their purpose.
500
+ CORRECT: \`<button type="button">Save Changes</button>\`
501
+ CORRECT: \`<button aria-label="Close dialog"><svg aria-hidden="true" focusable="false">...</svg></button>\`
502
+ WRONG: \`<button><svg>...</svg></button>\` (no accessible name)
503
+ WRONG: \`<button>Click here</button>\` (generic text)
504
+
505
+ **3. Popup/Menu Triggers** (WCAG 4.1.2, 1.3.1)
506
+ Indicate popup purpose and state using aria-haspopup, aria-expanded, aria-controls.
507
+ CORRECT: \`<button aria-expanded="false" aria-haspopup="menu" aria-controls="menu-id">Settings</button>\`
508
+
509
+ **4. Image Accessibility** (WCAG 1.1.1)
510
+ Informative: \`<img src="chart.png" alt="Sales increased 25% in Q4 2024">\`
511
+ Functional: \`<a href="/home"><img src="logo.png" alt="Company Name Home"></a>\`
512
+ Decorative: \`<img src="border.png" alt="" role="presentation">\`
513
+ Complex: \`<img src="chart.png" alt="Sales data" aria-describedby="desc-id">\`
514
+ WRONG: Missing alt, filename as alt, generic alt for decorative images
515
+
516
+ **5. Link Accessibility** (WCAG 2.4.4, 2.4.6)
517
+ Links must be descriptive and understandable out of context.
518
+ CORRECT: \`<a href="/products">View All Products</a>\`
519
+ CORRECT: \`<a href="/article" aria-label="Read more about New Product Launch">Read more</a>\`
520
+ WRONG: "Click here", "Read more", "Learn more" without context
521
+
522
+ **6. Form Validation** (WCAG 3.3.1, 3.3.2, 3.3.3)
523
+ Errors must be identified, associated with inputs, and provide suggestions. Use aria-describedby, aria-invalid="true", and role="alert".
524
+
525
+ **7. Heading Structure** (WCAG 1.3.1, 2.4.6)
526
+ Each page should have an \`<h1>\` that describes its content. Use hierarchical, descriptive headings with no skipped levels (h1\u2192h2\u2192h3).
527
+ CORRECT: \`<h1>Dashboard</h1> <h2>Sales</h2> <h3>By Region</h3>\`
528
+ WRONG: No \`<h1>\` on the page, or skipping levels (h1\u2192h3)
529
+ If a heading should look smaller than its semantic level, use CSS: \`<h2 class="text-sm">Subtitle</h2>\`
530
+
531
+ **8. Page Component Landmark Rules** (WCAG 1.3.1, 4.1.2)
532
+ Page components (route components) may be rendered inside a layout that already provides \`<main>\`, \`<header>\`, or \`<footer>\`. Since the layout configuration is unknown, avoid using these landmarks in page components to prevent potential duplication and nesting violations. Use \`<div>\`, \`<section>\`, or \`<article>\` as the top-level wrapper instead.
533
+
534
+ **Quick Checklist:**
535
+ - **Forms:** Associated labels, aria-required on required fields, autocomplete attributes, aria-describedby for errors, aria-invalid for invalid fields, fieldsets with legends
536
+ - **Buttons/Links:** Accessible names, aria-label for icon buttons, aria-hidden on decorative icons, descriptive link text
537
+ - **Popups/Dialogs:** aria-haspopup, aria-expanded, aria-controls, role="dialog", aria-modal="true", aria-labelledby, focus trap, Escape to close
538
+ - **Images:** alt on all images, descriptive alt for informative, empty alt for decorative, aria-describedby for complex
539
+ - **Structure:** One h1, logical heading hierarchy, avoid \`<main>\`, \`<header>\`, or \`<footer>\` in page/route components (the layout may already provide them), use \`<section>\` or \`<div>\` as page-level wrappers, semantic HTML
540
+ - **Dynamic Content:** role="status"/aria-live="polite" for updates, role="alert"/aria-live="assertive" for critical alerts
541
+ - **Keyboard/Focus:** All interactive elements keyboard accessible, logical focus order, visible focus indicators, no keyboard traps (except modals)
542
+ - **Color/Contrast:** 4.5:1 text contrast (3:1 large text), 3:1 UI component contrast, no color-only information, 3:1 focus indicator contrast`;
543
+ }
544
+
545
+ // packages/mcp-common/src/lib/heartbeat.ts
546
+ var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
547
+ function startHeartbeat(options) {
548
+ const {
549
+ serverName,
550
+ contextApi: contextApi2,
551
+ additionalFields = {},
552
+ intervalMs = ONE_DAY_MS
553
+ } = options;
554
+ const eventName = `mcp_server_heartbeat`;
555
+ const sendHeartbeat = async () => {
556
+ try {
557
+ const fields = {
558
+ server_name: serverName,
559
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
560
+ ...additionalFields
561
+ };
562
+ await contextApi2.logEvent(eventName, fields);
563
+ } catch (error) {
564
+ log(`Failed to send heartbeat for ${serverName}:`, error);
565
+ }
566
+ };
567
+ sendHeartbeat();
568
+ const intervalId = setInterval(sendHeartbeat, intervalMs);
569
+ return () => {
570
+ clearInterval(intervalId);
571
+ log(`Heartbeat stopped for ${serverName}`);
572
+ };
573
+ }
574
+
575
+ // packages/mcp-common/src/lib/getting-started-params.ts
576
+ import { z as z3 } from "zod";
577
+ var KendoThemes = ["default", "bootstrap", "material", "fluent"];
578
+ function createGettingStartedInputSchema(suiteName, defaultProjectName) {
579
+ return {
580
+ projectName: z3.string().default(defaultProjectName).describe(
581
+ "The name of the project. Used as the project folder name when creating a new project."
582
+ ),
583
+ createNewProject: z3.boolean().default(true).describe(
584
+ `Whether to create a new project before configuring ${suiteName}. Set to true to scaffold a brand-new project, or false if the project already exists and you only want to add ${suiteName} to it.`
585
+ ),
586
+ theme: z3.enum(KendoThemes).default("default").describe(
587
+ "The Kendo UI theme to use. Determines which theme package is installed and imported."
588
+ )
589
+ };
590
+ }
591
+
592
+ // packages/react/src/lib/constants.ts
593
+ var REACT_SUITE_NAME = "Kendo UI for React";
594
+ var Suite = "react";
595
+ var PRODUCT_LINE = "kendo";
596
+ var ReactComponents = [
597
+ "ActionSheet",
598
+ "AIPrompt",
599
+ "Animation",
600
+ "AppBar",
601
+ "ArcGauge",
602
+ "AutoComplete",
603
+ "Avatar",
604
+ "Badge",
605
+ "Barcode",
606
+ "BottomNavigation",
607
+ "Breadcrumb",
608
+ "Button",
609
+ "ButtonGroup",
610
+ "BreadCrumb",
611
+ "Calendar",
612
+ "Card",
613
+ "Chart",
614
+ "ChartWizard",
615
+ "Chat",
616
+ "Checkbox",
617
+ "Chip",
618
+ "ChipList",
619
+ "ChunkProgressBar",
620
+ "CircularGauge",
621
+ "ColorGradient",
622
+ "ColorPalette",
623
+ "ColorPicker",
624
+ "ComboBox",
625
+ "ContextMenu",
626
+ "ConversationalUI",
627
+ "DataGrid",
628
+ "Grid",
629
+ // Alias for DataGrid only used in the mcp-server
630
+ "DataQuery",
631
+ "DateMath",
632
+ "DateInput",
633
+ "DatePicker",
634
+ "DateRangePicker",
635
+ "DateTimePicker",
636
+ "Dialog",
637
+ "Drag&Drop",
638
+ "Drawer",
639
+ "Drawing",
640
+ "DropDownButton",
641
+ "DropDownList",
642
+ "DropDownTree",
643
+ "Editor",
644
+ "Error",
645
+ "ExcelExport",
646
+ "ExpansionPanel",
647
+ "ExternalDropZone",
648
+ "FileSaver",
649
+ "FileManager",
650
+ "Filter",
651
+ "FlatColorPicker",
652
+ "FloatingActionButton",
653
+ "FloatingLabel",
654
+ "Form",
655
+ "Gantt",
656
+ "Gauge",
657
+ "General",
658
+ "GridLayout",
659
+ "Hint",
660
+ "Icon",
661
+ "InlineAIPrompt",
662
+ "Input",
663
+ "Label",
664
+ "LinearGauge",
665
+ "ListBox",
666
+ "ListView",
667
+ "Loader",
668
+ "Map",
669
+ "MaskedTextBox",
670
+ "Menu",
671
+ "MultiColumnComboBox",
672
+ "MultiSelect",
673
+ "MultiSelectTree",
674
+ "MultiViewCalendar",
675
+ "Notification",
676
+ "NumericTextBox",
677
+ "OrgChart",
678
+ "PageTemplates/BuildingBlocks",
679
+ "Pager",
680
+ "PanelBar",
681
+ "PDFProcessing",
682
+ "PDFViewer",
683
+ "PivotGrid",
684
+ "Popover",
685
+ "Popup",
686
+ "ProgressBar",
687
+ "PromptBox",
688
+ "QRCode",
689
+ "RadialGauge",
690
+ "RadioButton",
691
+ "RadioGroup",
692
+ "RangeSlider",
693
+ "Rating",
694
+ "Ripple",
695
+ "Sankey",
696
+ "Scheduler",
697
+ "ScrollView",
698
+ "Signature",
699
+ "Skeleton",
700
+ "Slider",
701
+ "Sortable",
702
+ "Sparkline",
703
+ "SpeechToTextButton",
704
+ "SmartPasteButton",
705
+ "SplitButton",
706
+ "Splitter",
707
+ "Spreadsheet",
708
+ "StackLayout",
709
+ "Stepper",
710
+ "StockChart",
711
+ "SVGIcon",
712
+ "Switch",
713
+ "TabStrip",
714
+ "TaskBoard",
715
+ "TextArea",
716
+ "TextBox",
717
+ "TileLayout",
718
+ "Timeline",
719
+ "TimePicker",
720
+ "Toolbar",
721
+ "Tooltip",
722
+ "TreeList",
723
+ "TreeView",
724
+ "Typography",
725
+ "Upload",
726
+ "VSCodeExtension",
727
+ "Window"
728
+ ];
729
+
730
+ // packages/react/src/lib/grpc-client.ts
731
+ var protoPath = join(
732
+ dirname(fileURLToPath2(import.meta.url)),
733
+ "../proto/service.proto"
734
+ );
735
+ var contextApi = new ContextAPI("contextapi.telerik.com:443", protoPath, {
736
+ libName: Suite
737
+ });
738
+ var validateUserLicense = async () => {
739
+ return contextApi.validateUserLicense();
740
+ };
741
+
742
+ // packages/react/src/index.ts
743
+ import fs3 from "fs";
744
+ import path3 from "path";
745
+ import { fileURLToPath as fileURLToPath3 } from "url";
746
+
747
+ // packages/kendo-ui-agent/src/lib/tools-factory.ts
748
+ import { z as z4 } from "zod";
749
+
750
+ // packages/kendo-ui-agent/src/lib/ui-agent-tool.ts
751
+ var UIAgentTool = class {
752
+ constructor(name, config, cb) {
753
+ this.name = name;
754
+ this.config = config;
755
+ this.cb = cb;
756
+ }
757
+ register(mcpServer) {
758
+ this.server = mcpServer;
759
+ this.server.registerTool(this.name, this.config, this.cb);
760
+ }
761
+ hasAccess(accessType) {
762
+ if (!this.config.requiredAccess || this.config.requiredAccess.length === 0) {
763
+ return true;
764
+ }
765
+ return accessType === "full" || this.config.requiredAccess.includes(accessType);
766
+ }
767
+ };
768
+
769
+ // packages/kendo-ui-agent/src/lib/templates/validator.ts
770
+ var renderValidatorResponse = (ctx, frameworkValidationSteps) => `# ${ctx.suiteName} - Code Validation & Quality Assurance
6
771
 
7
772
  ## Comprehensive Code Validation Checklist
8
773
  Execute these validation steps systematically to ensure high-quality, maintainable code:
9
774
 
10
775
  ### Validation Phase: Framework-Specific Validation
11
776
 
12
- ${t}
777
+ ${frameworkValidationSteps}
13
778
 
14
779
  ### Validation Phase: General Code Quality & Best Practices
15
780
 
@@ -46,45 +811,99 @@ Responsive Design:
46
811
  - Graceful error handling for all user interactions
47
812
  - Meaningful error messages for users
48
813
  - Network error handling for API calls
49
- `;var L=(e,t)=>{let n=D({suiteName:e.suiteName,libKey:e.libKey},t.validationSteps),o=e.libKey==="angular"?"- **Drag and Drop**: Consider using the DragandDrop and Sortable components when drag-and-drop functionality is needed.":"",s=e.components?e.components.join(", "):"components";return`# \u{1F3AF} ${e.suiteName} - Execution Plan
814
+ `;
815
+
816
+ // packages/kendo-ui-agent/src/lib/templates/orchestrator.ts
817
+ var responsiveKendoDesignSystemGuidance = (ctx) => `**Tool call example:**
818
+ \`\`\`
819
+ ${ctx.layoutAssistantName}({
820
+ prompt="Provide Kendo Design System utility classes to make the following layout structure responsive across mobile, tablet, and desktop views: [LAYOUT DESCRIPTION HERE]",
821
+ includeBuildingBlockExamples=false // Optional, include examples of Kendo building blocks (Grid, Flex, Stack, etc.)
822
+ })
823
+ \`\`\`
824
+ `;
825
+ var vanillaCSSResponsiveGuidance = `**General Responsive Design Guidance:**
826
+ - Use CSS media queries to apply different styles at various breakpoints (e.g., mobile, tablet, desktop).
827
+ - Consider a mobile-first approach, starting with styles for smaller screens and adding complexity for larger screens.
828
+ - Ensure flexible grid layouts that can adapt to different screen sizes.
829
+ - Use relative units (%, em, rem) instead of fixed units (px) for widths and spacing to allow for better scalability.
830
+ - Test the design across multiple devices and screen sizes to ensure a consistent user experience.`;
831
+ var tailwindResponsiveGuidance = `**Tailwind CSS Responsive Design Guidance:**
832
+ - Use Tailwind's responsive utility variants (e.g., sm:, md:, lg:, xl:) to apply styles at specific breakpoints.
833
+ - Start with mobile styles (no prefix) and layer on additional styles for larger screens using the appropriate prefixes.
834
+ - Leverage Tailwind's grid and flex utilities to create flexible layouts that adapt to different screen sizes.
835
+ - Use Tailwind's spacing utilities to maintain consistent spacing across breakpoints.
836
+ - Test the design across multiple devices and screen sizes to ensure a consistent user experience.`;
837
+ var renderOrchestratorResponse = (ctx, options) => {
838
+ const validationInstructions = renderValidatorResponse(
839
+ { suiteName: ctx.suiteName, libKey: ctx.libKey },
840
+ options.validationSteps
841
+ );
842
+ const includeLayout = ctx.includeLayout && ctx.layoutMode === "utils";
843
+ const dragDropGuidance = ctx.libKey === "angular" ? `- **Drag and Drop**: Consider using the DragandDrop and Sortable components when drag-and-drop functionality is needed.` : "";
844
+ const componentsList = ctx.components ? ctx.components.join(", ") : "components";
845
+ const responsiveLayoutHint = includeLayout ? `- And use the ${ctx.layoutAssistantName} tool to get Kendo CSS utility classes needed for responsive design.` : "";
846
+ const responsiveKDSGuidance = includeLayout ? responsiveKendoDesignSystemGuidance(ctx) : "";
847
+ const responsiveVanillaCSSGuidance = ctx.layoutMode === "vanilla" ? vanillaCSSResponsiveGuidance : "";
848
+ const responsiveTailwindCSSGuidance = ctx.layoutMode === "tailwind" ? tailwindResponsiveGuidance : "";
849
+ return `# \u{1F3AF} ${ctx.suiteName} - Execution Plan
50
850
 
51
851
  **Current Goal:**
52
852
 
53
- ${e.userIntent}
853
+ ${ctx.userIntent}
54
854
 
55
855
  **Requirements Summary:**
56
- - **Framework:** ${e.libKey}
57
- ${e.includeComponentsDocs?`- **Component Library:** ${e.suiteName}
58
- - Ensure to use ONLY ${e.suiteName} components for all UI elements.
59
- - And use the ${e.codeAssistantName} tool to get ${e.suiteName} component documentation and code snippets.
60
- - Ensure that after you read the plan you use exactly the ${e.codeAssistantName} no matter if there is another tool that can provide code snippets, documentation or other resources related to ${e.suiteName}.
61
- `:""}${e.includeLayout?`- **Layout:** Yes
62
- - And use the ${e.layoutAssistantName} tool to get Kendo CSS utility classes needed for layout structure and responsive design.
63
- `:""}${e.includeIcons?`- **Icons:** Yes
856
+ - **Framework:** ${ctx.libKey}
857
+ ${ctx.includeComponentsDocs ? `- **Component Library:** ${ctx.suiteName}
858
+ - Ensure to use ONLY ${ctx.suiteName} components for all UI elements.
859
+ - And use the ${ctx.codeAssistantName} tool to get ${ctx.suiteName} component documentation and code snippets.
860
+ - Ensure that after you read the plan you use exactly the ${ctx.codeAssistantName} no matter if there is another tool that can provide code snippets, documentation or other resources related to ${ctx.suiteName}.
861
+ ` : ""}${includeLayout ? `- **Layout:** Yes
862
+ - And use the ${ctx.layoutAssistantName} tool to get Kendo CSS utility classes needed for layout structure and responsive design.
863
+ ` : ""}${ctx.includeIcons ? `- **Icons:** Yes
64
864
  - Use icons that align with the project theme and enhance usability.
65
- - Use the ${e.iconAssistantName} tool to search for icons that fit the theme and purpose of your project.
66
- `:""}${e.includeTheming?`- **Custom Theming:**
865
+ - Use the ${ctx.iconAssistantName} tool to search for icons that fit the theme and purpose of your project.
866
+ ` : ""}${ctx.includeTheming ? `- **Custom Theming:**
67
867
  - Create a custom theme that aligns with the current goal and branding needs.
68
868
  - Use Kendo Themes and Design System guidelines.
69
869
  - Make sure to include strict CSS variables or theme requirements from the current goal.
70
- - And use the ${e.styleAssistantName} tool to create a custom theme for your project.
71
- `:""}${e.includeResponsive?`- **Responsive:**
870
+ - And use the ${ctx.styleAssistantName} tool to create a custom theme for your project.
871
+ ` : ""}${ctx.includeResponsive ? `- **Responsive:**
72
872
  - Ensure the layout is fully responsive across mobile, tablet, and desktop views.
73
- - And use the ${e.layoutAssistantName} tool to get Kendo CSS utility classes needed for responsive design.
74
- `:""}
873
+ ${responsiveLayoutHint}
874
+ ` : ""}
75
875
  - **Accessible (WCAG 2.2 Level AA):**
76
- - CRITICAL: You must call the ${e.accessibilityAssistantName} tool with includeGeneralGuidelines=true on your first call to get WCAG 2.2 Level AA guidelines.
876
+ - CRITICAL: You must call the ${ctx.accessibilityAssistantName} tool with includeGeneralGuidelines=true on your first call to get WCAG 2.2 Level AA guidelines.
77
877
  - For subsequent calls, use includeGeneralGuidelines=false to get only component-specific accessibility information.
78
878
  - Ensure all components meet WCAG 2.2 Level AA standards.
79
879
 
80
- ${e.includeLayout?`**STYLING AND LAYOUT REQUIREMENTS:**
880
+ ${includeLayout ? `**STYLING AND LAYOUT REQUIREMENTS:**
881
+ **LAYOUT MODE: KENDO DESIGN SYSTEM CSS UTILITIES**
81
882
  ## CRITICAL DESIGN SYSTEM CONSTRAINTS
82
883
  - **USE ONLY KENDO DESIGN SYSTEM UTILITIES** for ALL styling, layout, spacing, positioning, and responsive behavior
83
884
  - Avoid custom CSS, inline styles, or other CSS framework classes
84
- - The ${e.layoutAssistantName} tool will provide the specific Kendo CSS utility classes needed
885
+ - The ${ctx.layoutAssistantName} tool will provide the specific Kendo CSS utility classes needed
85
886
  - All layout requirements must use Kendo utilities exclusively
887
+ ` : ""}
888
+ ${ctx.layoutMode === "vanilla" ? `**STYLING AND LAYOUT REQUIREMENTS:**
889
+ **LAYOUT MODE: VANILLA**
890
+ - In this mode, you should use Kendo UI components and vanilla CSS for layout and styling.
891
+ - Do NOT use any utility-first CSS classes (e.g., from Tailwind) for layout or styling.
892
+ - Focus on leveraging the built-in capabilities of Kendo UI components and writing custom CSS as needed to achieve the desired design and layout.
893
+ ` : ""}
894
+ ${ctx.layoutMode === "tailwind" ? `**STYLING AND LAYOUT REQUIREMENTS:**
895
+ **LAYOUT MODE: TAILWIND**
896
+ - In this mode, you should use Tailwind CSS utility classes for layout and styling.
897
+ - Do NOT write custom CSS or use vanilla CSS for layout or styling.
898
+ - Focus on leveraging Tailwind's utility-first approach to achieve the desired design and layout, while still using Kendo UI components for functionality.
899
+ ` : ""}
900
+ ${ctx.includeFigmaD2C ? `**DESIGN EXTRACTION FROM FIGMA FILE**
901
+ - You are given a Figma file URL that contains the design for the current goal. You MUST use the ${ctx.figmaD2CToolName} tool to extract design information from the Figma file.
902
+ - Extracted design information should be used to get information about the layout, styles, design tokens and assets that can be used within the project.
903
+ - The ${ctx.figmaD2CToolName} tool will output you Layout structure of the design, design tokens for CSS and any decoration and a snapshot of the design.
904
+ ` : ""}
86
905
 
87
- `:""}---
906
+ ---
88
907
 
89
908
  ## Detailed Execution Plan
90
909
  Follow these steps strictly in order to achieve a complete and polished implementation of the current goal:
@@ -96,13 +915,13 @@ Follow these steps strictly in order to achieve a complete and polished implemen
96
915
  **MANDATORY REQUIREMENT:**
97
916
 
98
917
  - Before implementing any UI components or features, you must call the accessibility assistant with general guidelines
99
- - On your first call to "${e.accessibilityAssistantName}", set "includeGeneralGuidelines=true" to get foundational WCAG 2.2 Level AA best practices
918
+ - On your first call to "${ctx.accessibilityAssistantName}", set "includeGeneralGuidelines=true" to get foundational WCAG 2.2 Level AA best practices
100
919
  - These general guidelines apply to all components and must be considered throughout implementation
101
920
  - For all subsequent calls, set "includeGeneralGuidelines=false" to get only component-specific information
102
921
 
103
922
  **First tool call (includes general WCAG guidelines):**
104
923
  \`\`\`
105
- ${e.accessibilityAssistantName}({
924
+ ${ctx.accessibilityAssistantName}({
106
925
  query="What are the accessibility requirements for [COMPONENT_NAME]?",
107
926
  component="[COMPONENT_NAME]",
108
927
  includeGeneralGuidelines=true // ONLY true on first call
@@ -111,11 +930,11 @@ ${e.accessibilityAssistantName}({
111
930
 
112
931
  **Step 2: Get Component-Specific Accessibility Information**
113
932
 
114
- For each additional ${e.suiteName} component you plan to use, call the tool with "includeGeneralGuidelines=false":
933
+ For each additional ${ctx.suiteName} component you plan to use, call the tool with "includeGeneralGuidelines=false":
115
934
 
116
935
  **Tool call example:**
117
936
  \`\`\`
118
- ${e.accessibilityAssistantName}({
937
+ ${ctx.accessibilityAssistantName}({
119
938
  query="What are the accessibility features and requirements for [COMPONENT_NAME]? Include ARIA attributes, keyboard navigation, and screen reader support.",
120
939
  component="[COMPONENT_NAME]",
121
940
  includeGeneralGuidelines=false // false for all calls after the first
@@ -124,13 +943,112 @@ ${e.accessibilityAssistantName}({
124
943
 
125
944
  **Example:**
126
945
  \`\`\`
127
- ${e.accessibilityAssistantName}({
946
+ ${ctx.accessibilityAssistantName}({
128
947
  query="How to associate the label with another component or HTML input?",
129
948
  component="Label",
130
949
  includeGeneralGuidelines=false
131
950
  })
132
951
  \`\`\`
133
- ${e.includeLayout?`
952
+
953
+ ${ctx.includeFigmaD2C ? `### Phase: Design Extraction and Analysis
954
+
955
+ **IMPORTANT DESIGN EXTRACTION REQUIRMENTS**
956
+ - Use the ${ctx.figmaD2CToolName} tool to extract design information from the provided Figma file URL.
957
+ - Analyze the extracted design information to identify key layout structures, components, styles, and design tokens.
958
+ - Use the insights from the design analysis to inform your implementation in the next phases, ensuring alignment with the original design intent.
959
+ - Follow ALL three extraction steps sequentially \u2014 each step is MANDATORY.
960
+ - Complete the verification checklist after each step before proceeding to the next.
961
+
962
+
963
+ **Step 1: Extract Base Design Information from Figma**
964
+ - Extract only base the first layer of the design to get the overall structure and layout without going too deep into details. This will help you to understand the design hierarchy and identify key components and layout patterns.
965
+ - Use the downloaded design snapshot to visually analyze the design and correlate it with the extracted structure. This will help you to identify which nodes correspond to which design elements and to plan your implementation accordingly.
966
+ - **REQUIRED OUTPUT:** After extraction, you MUST output a structured list of ALL discovered node IDs with their labels/names before proceeding to Step 2. Format this as a clear inventory that will be referenced in subsequent steps. For each node, extract the node ID from the node-id attribute of the node XML tag.
967
+ - **Depth escalation:** If a node at this depth shows it contains more children than can be captured (e.g., children are truncated), re-fetch that specific node with depth + 5 to ensure complete extraction.
968
+
969
+ **Tool call example:**
970
+ \`\`\`
971
+ ${ctx.figmaD2CToolName}({
972
+ url: [Figma URL from prompt]
973
+ depth: 10 // Consider more depth only if the user prompt explicitly states to extract deeply.
974
+ })
975
+ \`\`\`
976
+
977
+ **Step 1 Completion Checklist (MUST satisfy before proceeding):**
978
+ - [ ] Have I captured all top-level layout containers (headers, footers, main sections)?
979
+ - [ ] Have I identified all major structural components?
980
+ - [ ] Have I created and outputted a structured list of node IDs and their labels?
981
+ - [ ] Have I visually analyzed the design snapshot to correlate nodes with design elements?
982
+
983
+ **Step 2: Extract Main Nodes Design**
984
+ - Based on the initial extraction and analysis, identify the main nodes that are critical for the design implementation. These could be reusable headers, body, navigation, sidebar or footer elements that illustrate the main structure.
985
+ - Use the node IDs from the node-id attribute of the node XML tag to fetch these specific nodes with more depth to capture necessary details for implementation. This targeted extraction will help you to get the relevant design information without overwhelming the process with too much data.
986
+ - **Depth escalation:** If any main node shows truncated children or contains more elements than expected at the given depth, immediately re-fetch with depth + 5.
987
+
988
+ **Tool call example:**
989
+ \`\`\`
990
+ ${ctx.figmaD2CToolName}({
991
+ fileKey: [The fileKey extracted from Step 1]
992
+ nodeIds: [Array of main node IDs identified from Step 1]
993
+ depth: 10 // Deeper extraction for main nodes to capture necessary details.
994
+ })
995
+ \`\`\`
996
+
997
+ **Step 2 Completion Checklist (MUST satisfy before proceeding):**
998
+ - [ ] Have I captured all interactive components (buttons, inputs, navigation elements)?
999
+ - [ ] Have I identified all typography styles and text elements?
1000
+ - [ ] Have I extracted all color tokens and design system values?
1001
+ - [ ] Have I documented child node IDs that need deeper extraction in Step 3?
1002
+
1003
+ **Step 3: Extract Child Node Details (MANDATORY)**
1004
+ **CRITICAL:** After Step 2, you MUST proceed to Step 3. Extract ALL child nodes identified in Step 2. Do not skip this step.
1005
+
1006
+ - Extract all child nodes that were identified in Step 2 as requiring deeper analysis. These include specific components, styles, or interactions that are essential for accurate implementation.
1007
+ - Use the node IDs from the node-id attribute to fetch these specific child nodes with sufficient depth to capture all critical design details.
1008
+ - **Depth escalation:** If child nodes still show incomplete extraction (truncated elements, nested components not fully visible), re-fetch with depth + 5 until all leaf-level components are captured.
1009
+
1010
+ **Tool call example:**
1011
+ \`\`\`
1012
+ ${ctx.figmaD2CToolName}({
1013
+ fileKey: [The fileKey extracted from Step 1]
1014
+ nodeIds: [Array of ALL child node IDs identified from Step 2]
1015
+ depth: 15 // Targeted deeper extraction for specific nodes. Increase if needed.
1016
+ })
1017
+ \`\`\`
1018
+
1019
+ **Step 3 Completion Checklist (MUST satisfy before proceeding):**
1020
+ - [ ] Have I captured ALL leaf-level components (buttons, icons, form inputs)?
1021
+ - [ ] Have I extracted all spacing, padding, and margin values?
1022
+ - [ ] Have I identified all border styles, shadows, and visual effects?
1023
+ - [ ] Are there any remaining truncated nodes? (If yes, apply depth escalation)
1024
+
1025
+ **Iterative Extraction and Stopping Condition**
1026
+ Continue iterating over the extraction process following these rules:
1027
+ - **Continue until:** (a) All leaf-level components have been captured with complete details, OR (b) You have completed 3 extraction passes \u2014 whichever comes first.
1028
+ - After each iteration, verify that no new child nodes require deeper extraction.
1029
+ - If depth escalation is needed after 3 passes, document the limitation and proceed with available data.
1030
+
1031
+ **MANDATORY: Design Extraction Verification (Complete BEFORE Code Generation Phase)**
1032
+ Before proceeding to any code generation or implementation phase, you MUST produce and output a verification summary containing:
1033
+
1034
+ 1. **Component Inventory:** List all UI components discovered (buttons, inputs, cards, navigation elements, etc.)
1035
+ 2. **Hierarchy Map:** Show the parent-child relationships of major layout sections
1036
+ 3. **Design Tokens Identified:**
1037
+ - Colors (with hex/rgba values)
1038
+ - Typography (font families, sizes, weights)
1039
+ - Spacing values (margins, paddings, gaps)
1040
+ - Border styles and effects
1041
+ 4. **Gaps and Limitations:** Explicitly state any design elements that could not be fully extracted
1042
+
1043
+ **This verification summary serves as the design specification for implementation. Do not proceed to Code Generation until this summary is complete.**
1044
+
1045
+ **Additional Extraction During Implementation:**
1046
+ - During the implementation phase (Code Generation), you can and should use the ${ctx.figmaD2CToolName} tool with the relevant node IDs from the node-id attributes again if you discover you need more specific design details for certain components or sections that were not captured in earlier phases.
1047
+ - If additional extraction is needed, apply the same depth escalation logic and verification steps.
1048
+ ` : ""}
1049
+
1050
+
1051
+ ${includeLayout ? `
134
1052
  ### Phase: Layout Foundation
135
1053
 
136
1054
  **Step 1: Create Base Layout Structure**
@@ -141,16 +1059,16 @@ ${e.includeLayout?`
141
1059
 
142
1060
  **Tool call example:**
143
1061
  \`\`\`
144
- ${e.layoutAssistantName}({
1062
+ ${ctx.layoutAssistantName}({
145
1063
  prompt="Provide Kendo Design System utility classes for the following layout structure: [LAYOUT DESCRIPTION HERE]",
146
1064
  includeBuildingBlockExamples=true // Optional, include examples of Kendo building blocks (Grid, Flex, Stack, etc.)
147
1065
  })
148
1066
  \`\`\`
149
- `:""}
150
- ${e.includeComponentsDocs?`
1067
+ ` : ""}
1068
+ ${ctx.includeComponentsDocs ? `
151
1069
  ### Phase: Component Integration
152
1070
  **Step 1: Identify and Implement Core Components**
153
- Based on your current goal, analyze what other ${e.suiteName} components are needed and implement them one by one. Here you are some appropriate components based on the different project type:
1071
+ Based on your current goal, analyze what other ${ctx.suiteName} components are needed and implement them one by one. Here you are some appropriate components based on the different project type:
154
1072
 
155
1073
  **Component Selection Guidelines:**
156
1074
  - **Landing Pages**: Consider Button, Card, Form components, Layout containers, Navigation elements
@@ -158,17 +1076,17 @@ Based on your current goal, analyze what other ${e.suiteName} components are nee
158
1076
  - **Data Entry**: Consider Form, TextBox, DatePicker, DropDownList, Upload, Validation components
159
1077
  - **Content Management**: Consider Grid, Editor, TreeView, FileManager, Dialog components
160
1078
  - **E-commerce**: Consider ListView, Card, Button, Rating, Badge, Carousel components
161
- ${o}
1079
+ ${dragDropGuidance}
162
1080
 
163
1081
  **IMPORTANT COMPONENT USAGE REQUIREMENTS:**
164
- - Make sure to identify all necessary features related to the ${s} based on the current goal.
165
- - Make sure to identify specific features needed for other ${e.suiteName} components based on the current goal.
166
- - Make sure to generate a query for ${e.codeAssistantName} tool for each component and call the tool for each specific feature or functionality.
1082
+ - Make sure to identify all necessary features related to the ${componentsList} based on the current goal.
1083
+ - Make sure to identify specific features needed for other ${ctx.suiteName} components based on the current goal.
1084
+ - Make sure to generate a query for ${ctx.codeAssistantName} tool for each component and call the tool for each specific feature or functionality.
167
1085
  - Always specify the exact features you want for each component. Describe only the needed functionality, and behavior you need. Be concise and don't include any information about the use case.
168
1086
 
169
1087
  **Tool call examples:**
170
1088
  \`\`\`
171
- ${e.codeAssistantName}({
1089
+ ${ctx.codeAssistantName}({
172
1090
  query="Give me information about [COMPONENT_NAME] with [SPECIFIC_FEATURES]." <!-- For example: 'Grid with paging' or 'Button with click events' or 'Chart with multiple series' -->
173
1091
  component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', 'Chart', etc. -->
174
1092
  })
@@ -176,40 +1094,33 @@ ${o}
176
1094
 
177
1095
  For broad queries, break them down into specific features (e.g., paging, sorting, filtering for Grid) and call the tool separately for each feature:
178
1096
  \`\`\`
179
- ${e.codeAssistantName}({
1097
+ ${ctx.codeAssistantName}({
180
1098
  query="How to implement [SPECIFIC_FEATURE] in [COMPONENT_NAME]?" <!-- For example: 'paging in Grid' -->
181
1099
  component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', etc. -->
182
1100
  })
183
1101
  \`\`\`
184
1102
 
185
1103
  \`\`\`
186
- ${e.codeAssistantName}({
1104
+ ${ctx.codeAssistantName}({
187
1105
  query="How to implement [SPECIFIC_FEATURE] in [COMPONENT_NAME]?" <!-- For example: 'sorting in Grid' -->
188
1106
  component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', etc. -->
189
1107
  })
190
1108
  \`\`\`
191
1109
 
192
1110
  \`\`\`
193
- ${e.codeAssistantName}({
1111
+ ${ctx.codeAssistantName}({
194
1112
  query="How to implement [SPECIFIC_FEATURE] in [COMPONENT_NAME]?" <!-- For example: 'filtering in Grid' -->
195
1113
  component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', etc. -->
196
1114
  })
197
1115
  \`\`\`
198
- `:""}
199
- ${e.includeResponsive?`
1116
+ ` : ""}
1117
+ ${ctx.includeResponsive ? `
200
1118
  ### Phase: Layout Responsive Finalization
201
1119
 
202
1120
  **Step 1: Implement Responsive Behavior**
1121
+ ${responsiveKDSGuidance}${responsiveVanillaCSSGuidance}${responsiveTailwindCSSGuidance}` : ""}
203
1122
 
204
- **Tool call example:**
205
- \`\`\`
206
- ${e.layoutAssistantName}({
207
- prompt="Provide Kendo Design System utility classes to make the following layout structure responsive across mobile, tablet, and desktop views: [LAYOUT DESCRIPTION HERE]",
208
- includeBuildingBlockExamples=false // Optional, include examples of Kendo building blocks (Grid, Flex, Stack, etc.)
209
- })
210
- \`\`\`
211
- `:""}
212
- ${e.includeTheming?`
1123
+ ${ctx.includeTheming ? `
213
1124
  **Step 2: Custom Theme Implementation**
214
1125
 
215
1126
  **CUSTOM THEME REQUIREMENTS:**
@@ -219,13 +1130,13 @@ ${e.includeTheming?`
219
1130
 
220
1131
  **Tool call example:**
221
1132
  \`\`\`
222
- ${e.styleAssistantName}({
1133
+ ${ctx.styleAssistantName}({
223
1134
  query="Create a custom Kendo UI theme that aligns with the following current goal and branding needs: [CURRENT GOAL HERE]. Include strict CSS variables or theme requirements as needed.",
224
1135
  includeThemeVariables=true // Optional, include specific CSS variables for colors, typography, spacing, etc.
225
1136
  })
226
1137
  \`\`\`
227
- `:""}
228
- ${e.includeIcons?`
1138
+ ` : ""}
1139
+ ${ctx.includeIcons ? `
229
1140
  **Step 3: Iconography and Visual Enhancements**
230
1141
 
231
1142
  **ICONOGRAPHY GUIDELINES:**
@@ -235,59 +1146,64 @@ ${e.includeIcons?`
235
1146
 
236
1147
  **Tool call example:**
237
1148
  \`\`\`
238
- ${e.iconAssistantName}({
1149
+ ${ctx.iconAssistantName}({
239
1150
  query="Suggest icons that fit the theme and purpose of the following current goal: [CURRENT GOAL HERE]. Provide icon names and usage context.",
240
1151
  })
241
1152
  \`\`\`
242
- `:""}
1153
+ ` : ""}
243
1154
  ### Phase: Code Generation
244
1155
  **IMPORTANT:** Do NOT generate ANY code or create files until ALL information gathering phases (1-3) are complete.
245
1156
  **Step 1: Generate Complete Implementation**
246
- After completing all information gathering phases above, generate the complete ${e.libKey} component/page implementation:
1157
+ After completing all information gathering phases above, generate the complete ${ctx.libKey} component/page implementation:
247
1158
  **Code Generation Requirements:**
248
- - Create complete, functional ${e.libKey} components/pages
249
- - Include all identified ${e.suiteName} components with their configurations
1159
+ - Create complete, functional ${ctx.libKey} components/pages
1160
+ - Include all identified ${ctx.suiteName} components with their configurations
250
1161
  - Apply ALL Kendo Design System utility classes gathered from layout assistant
251
1162
  - Implement proper component event handling and data binding
252
1163
  - Ensure responsive behavior using Kendo utility classes
253
1164
  - Include necessary import statements and dependencies
254
1165
 
255
- ${t.injectedPlan??""}
1166
+ ${options.injectedPlan ?? ""}
256
1167
 
257
1168
  ### Phase: Validation and Finalization
258
1169
 
259
1170
  **Step 1: Code Validation**
260
1171
  ** CRITICAL REQUIREMENT: You MUST validate the generated UI code using this comprehensive checklist to ensure code quality and compliance:**
261
1172
 
262
- ${n}
1173
+ ${validationInstructions}
263
1174
 
264
1175
  **Step 2: Final Review and Testing**
265
1176
  ** Implementation Validation:**
266
- ${e.includeComponentsDocs?` - Components render correctly without errors
267
- - All ${e.suiteName} component features function as expected
268
- - Event handling and data binding operate correctly`:""}
269
- ${e.includeResponsive?"- Responsive layout works across breakpoints":""}
1177
+ ${ctx.includeComponentsDocs ? ` - Components render correctly without errors
1178
+ - All ${ctx.suiteName} component features function as expected
1179
+ - Event handling and data binding operate correctly` : ""}
1180
+ ${ctx.includeResponsive ? `- Responsive layout works across breakpoints` : ""}
270
1181
 
271
1182
  **Quick Fixes (if needed):**
272
1183
 
273
1184
  After code implementation and validation you can make quick fixes as needed:
274
- - Use ${e.codeAssistantName} for component-specific issues
275
- - Use ${e.layoutAssistantName} for styling adjustments
1185
+ - Use ${ctx.codeAssistantName} for component-specific issues
1186
+ - Use ${ctx.layoutAssistantName} for styling adjustments
276
1187
 
277
1188
  +### Before You Begin
278
- - When following/executing the plan call tools are defined from the same function_ecosystem/MCP_server which ${e.name} was called.
1189
+ - When following/executing the plan call tools are defined from the same function_ecosystem/MCP_server which ${ctx.name} was called.
279
1190
  - Do NOT generate or suggest any code until all tools have been used and validated responses are incorporated.
280
1191
  - Focus on planning and sequencing.
281
1192
  - Summarize the components, layouts, and utilities gathered.
282
- - Confirm all required inputs from tools have been provided.`};var V=e=>`# ${e.suiteName} Assistant
1193
+ - Confirm all required inputs from tools have been provided.`;
1194
+ };
1195
+
1196
+ // packages/kendo-ui-agent/src/lib/templates/assistant-orchestrator.ts
1197
+ var renderAssistantOrchestratorResponse = (ctx) => {
1198
+ return `# ${ctx.suiteName} Assistant
283
1199
 
284
1200
  **What you're looking for:**
285
1201
 
286
- ${e.userIntent}
1202
+ ${ctx.userIntent}
287
1203
 
288
1204
  **Available Tools:**
289
- - **${e.codeAssistantName}** - Get component documentation, features, and usage examples
290
- - **${e.iconAssistantName}** - Search for icons from the Kendo icon library
1205
+ - **${ctx.codeAssistantName}** - Get component documentation, features, and usage examples
1206
+ - **${ctx.iconAssistantName}** - Search for icons from the Kendo icon library
291
1207
 
292
1208
  ---
293
1209
 
@@ -297,7 +1213,7 @@ Follow these steps to find the right components and resources:
297
1213
 
298
1214
  ### Step 1: Identify Components
299
1215
 
300
- Based on your needs, consider these ${e.suiteName} component categories:
1216
+ Based on your needs, consider these ${ctx.suiteName} component categories:
301
1217
 
302
1218
  **Common Use Cases:**
303
1219
  - **Data Display**: Grid, ListView, TreeView, Card, TileLayout
@@ -310,10 +1226,10 @@ Based on your needs, consider these ${e.suiteName} component categories:
310
1226
 
311
1227
  **How to explore components:**
312
1228
 
313
- Use the ${e.codeAssistantName} tool to learn about specific components:
1229
+ Use the ${ctx.codeAssistantName} tool to learn about specific components:
314
1230
 
315
1231
  \`\`\`
316
- ${e.codeAssistantName}({
1232
+ ${ctx.codeAssistantName}({
317
1233
  query: "What are the main features of [COMPONENT_NAME]?",
318
1234
  component: "[COMPONENT_NAME]"
319
1235
  })
@@ -321,14 +1237,14 @@ ${e.codeAssistantName}({
321
1237
 
322
1238
  **Examples:**
323
1239
  \`\`\`
324
- ${e.codeAssistantName}({
1240
+ ${ctx.codeAssistantName}({
325
1241
  query: "How to use Grid with paging and sorting?",
326
1242
  component: "Grid"
327
1243
  })
328
1244
  \`\`\`
329
1245
 
330
1246
  \`\`\`
331
- ${e.codeAssistantName}({
1247
+ ${ctx.codeAssistantName}({
332
1248
  query: "What features does DatePicker have?",
333
1249
  component: "DatePicker"
334
1250
  })
@@ -339,37 +1255,37 @@ ${e.codeAssistantName}({
339
1255
  - Break complex queries into multiple calls focusing on one feature at a time
340
1256
  - Specify the exact component name in the component parameter
341
1257
 
342
- ${e.includeIcons?`
1258
+ ${ctx.includeIcons ? `
343
1259
  ### Step 2: Find Icons
344
1260
 
345
- Use the ${e.iconAssistantName} tool to search for icons:
1261
+ Use the ${ctx.iconAssistantName} tool to search for icons:
346
1262
 
347
1263
  \`\`\`
348
- ${e.iconAssistantName}({
1264
+ ${ctx.iconAssistantName}({
349
1265
  query: "Search for icons related to [YOUR THEME/PURPOSE]"
350
1266
  })
351
1267
  \`\`\`
352
1268
 
353
1269
  **Examples:**
354
1270
  \`\`\`
355
- ${e.iconAssistantName}({
1271
+ ${ctx.iconAssistantName}({
356
1272
  query: "icons for navigation menu"
357
1273
  })
358
1274
  \`\`\`
359
1275
 
360
1276
  \`\`\`
361
- ${e.iconAssistantName}({
1277
+ ${ctx.iconAssistantName}({
362
1278
  query: "icons for user actions like edit, delete, save"
363
1279
  })
364
1280
  \`\`\`
365
- `:""}
1281
+ ` : ""}
366
1282
 
367
1283
  ### Step 3: Review and Implement
368
1284
 
369
1285
  After gathering information:
370
- 1. Review the component documentation provided by ${e.codeAssistantName}
371
- 2. Check which icons are available from ${e.iconAssistantName}
372
- 3. Use the official ${e.suiteName} documentation for detailed implementation guides
1286
+ 1. Review the component documentation provided by ${ctx.codeAssistantName}
1287
+ 2. Check which icons are available from ${ctx.iconAssistantName}
1288
+ 3. Use the official ${ctx.suiteName} documentation for detailed implementation guides
373
1289
  4. Refer to the component examples and code snippets provided
374
1290
 
375
1291
  ---
@@ -377,144 +1293,1490 @@ After gathering information:
377
1293
  ## Getting Started
378
1294
 
379
1295
  **Next Actions:**
380
- 1. Start by calling ${e.codeAssistantName} for the components you need
381
- 2. ${e.includeIcons?`Search for icons using ${e.iconAssistantName}`:"Review the component documentation"}
382
- 3. Follow the ${e.suiteName} official documentation for implementation details
1296
+ 1. Start by calling ${ctx.codeAssistantName} for the components you need
1297
+ 2. ${ctx.includeIcons ? `Search for icons using ${ctx.iconAssistantName}` : "Review the component documentation"}
1298
+ 3. Follow the ${ctx.suiteName} official documentation for implementation details
383
1299
 
384
1300
  **Important Notes:**
385
1301
  - These tools provide documentation and guidance, not code generation
386
- - Always refer to official ${e.suiteName} documentation for the most up-to-date information
387
- - Tool responses include usage examples and best practices`;var x=(e,t)=>({SETUP_VALIDATION:`
1302
+ - Always refer to official ${ctx.suiteName} documentation for the most up-to-date information
1303
+ - Tool responses include usage examples and best practices`;
1304
+ };
1305
+
1306
+ // packages/kendo-ui-agent/src/lib/templates/shared-validation.ts
1307
+ var getSharedValidationSteps = (uiLibrary, designSystem) => ({
1308
+ SETUP_VALIDATION: `
388
1309
  UI Library Setup:
389
- - ${e} modules properly imported and configured
390
- - ${e} theme properly loaded and applied
391
- - ${e} license properly configured
392
- - Globalization and localization properly configured for ${e} components
393
- - Required ${e} dependencies installed and up-to-date`,PERFORMANCE_OPTIMIZATION:`
1310
+ - ${uiLibrary} modules properly imported and configured
1311
+ - ${uiLibrary} theme properly loaded and applied
1312
+ - ${uiLibrary} license properly configured
1313
+ - Globalization and localization properly configured for ${uiLibrary} components
1314
+ - Required ${uiLibrary} dependencies installed and up-to-date`,
1315
+ PERFORMANCE_OPTIMIZATION: `
394
1316
  Performance Optimization:
395
1317
  - Efficient rendering patterns to prevent unnecessary re-renders
396
- - Lazy loading of ${e} components when appropriate
397
- - Virtualization enabled for large datasets in ${e} components
398
- - Only required ${e} modules imported and tree-shaken`,THEME_AND_STYLING:`
399
- ${e} Theme & Styling:
400
- - Prioritize the ${t} Design System utilities
1318
+ - Lazy loading of ${uiLibrary} components when appropriate
1319
+ - Virtualization enabled for large datasets in ${uiLibrary} components
1320
+ - Only required ${uiLibrary} modules imported and tree-shaken`,
1321
+ THEME_AND_STYLING: `
1322
+ ${uiLibrary} Theme & Styling:
1323
+ - Prioritize the ${designSystem} Design System utilities
401
1324
  - Avoid custom CSS or other framework classes
402
1325
  - Do not use inline styles
403
- - Consistent ${e} theme application across all components
1326
+ - Consistent ${uiLibrary} theme application across all components
404
1327
  - Custom theme variables properly defined and scoped
405
- - ${e} icon fonts properly loaded and optimized
406
- - Brand colors integrated with ${e} component themes`});function mt(e,t){let n;try{n=JSON.parse(e)}catch{return e}let o=n?.Item;if(!o)return e;let s=[],r=o.FullName??o.Name??"",a=o.Type??"",i=o.Summary??"",d=o.SyntaxContent??"";s.push(`## API Reference Item
407
- - Name: ${r}
408
- - Type: ${a}
409
- - Summary: ${i}
410
- - Syntax: ${d}`);let m=n.RelatedItemsByType?.return_type;if(m?.length){let p=m[0].Text;p&&s.push(`- Return Type: ${p}`)}let A=o.Examples??[];if(A.length>0){let p=`## Examples
411
- `,c=0;for(let y of A){let S=(y.Component??"").toLowerCase(),T=t.toLowerCase();if(S&&S!==T&&S!=="general")continue;c+=1;let k=y.Code??"";p+=`### Example ${c}
1328
+ - ${uiLibrary} icon fonts properly loaded and optimized
1329
+ - Brand colors integrated with ${uiLibrary} component themes`
1330
+ });
1331
+
1332
+ // packages/kendo-ui-agent/src/lib/templates/tailwind-bridge.ts
1333
+ var tailwindBridgeExample = `
1334
+ @import "tailwindcss/theme.css";
1335
+ @import "tailwindcss/preflight.css";
1336
+ @import "tailwindcss/utilities.css";
1337
+
1338
+ :root {
1339
+ /* The generated Kendo Theme CSS variables */
1340
+ }
1341
+
1342
+
1343
+ @theme inline { /* The Tailwind bridge mapping */
1344
+ /* Misc */
1345
+ --color-app-surface: var( --kendo-color-app-surface );
1346
+ --color-on-app-surface: var( --kendo-color-on-app-surface );
1347
+ --color-subtle: var( --kendo-color-subtle );
1348
+ --color-surface: var( --kendo-color-surface );
1349
+ --color-surface-alt: var( --kendo-color-surface-alt );
1350
+ --color-border: var( --kendo-color-border );
1351
+ --color-border-alt: var( --kendo-color-border-alt );
1352
+ /* Base */
1353
+ --color-base-subtle: var( --kendo-color-base-subtle );
1354
+ --color-base-subtle-hover: var( --kendo-color-base-subtle-hover );
1355
+ --color-base-subtle-active: var( --kendo-color-base-subtle-active );
1356
+ --color-base: var( --kendo-color-base );
1357
+ --color-base-hover: var( --kendo-color-base-hover );
1358
+ --color-base-active: var( --kendo-color-base-active );
1359
+ --color-base-emphasis: var( --kendo-color-base-emphasis );
1360
+ --color-base-on-subtle: var( --kendo-color-base-on-subtle );
1361
+ --color-on-base: var( --kendo-color-on-base );
1362
+ --color-base-on-surface: var( --kendo-color-base-on-surface );
1363
+ /* Primary */
1364
+ --color-primary-subtle: var( --kendo-color-primary-subtle );
1365
+ --color-primary-subtle-hover: var( --kendo-color-primary-subtle-hover );
1366
+ --color-primary-subtle-active: var( --kendo-color-primary-subtle-active );
1367
+ --color-primary: var( --kendo-color-primary );
1368
+ --color-primary-hover: var( --kendo-color-primary-hover );
1369
+ --color-primary-active: var( --kendo-color-primary-active );
1370
+ --color-primary-emphasis: var( --kendo-color-primary-emphasis );
1371
+ --color-primary-on-subtle: var( --kendo-color-primary-on-subtle );
1372
+ --color-on-primary: var( --kendo-color-on-primary );
1373
+ --color-primary-on-surface: var( --kendo-color-primary-on-surface );
1374
+ /* Secondary */
1375
+ --color-secondary-subtle: var( --kendo-color-secondary-subtle );
1376
+ --color-secondary-subtle-hover: var( --kendo-color-secondary-subtle-hover );
1377
+ --color-secondary-subtle-active: var( --kendo-color-secondary-subtle-active );
1378
+ --color-secondary: var( --kendo-color-secondary );
1379
+ --color-secondary-hover: var( --kendo-color-secondary-hover );
1380
+ --color-secondary-active: var( --kendo-color-secondary-active );
1381
+ --color-secondary-emphasis: var( --kendo-color-secondary-emphasis );
1382
+ --color-secondary-on-subtle: var( --kendo-color-secondary-on-subtle );
1383
+ --color-on-secondary: var( --kendo-color-on-secondary );
1384
+ --color-secondary-on-surface: var( --kendo-color-secondary-on-surface );
1385
+ /* Tertiary */
1386
+ --color-tertiary-subtle: var( --kendo-color-tertiary-subtle );
1387
+ --color-tertiary-subtle-hover: var( --kendo-color-tertiary-subtle-hover );
1388
+ --color-tertiary-subtle-active: var( --kendo-color-tertiary-subtle-active );
1389
+ --color-tertiary: var( --kendo-color-tertiary );
1390
+ --color-tertiary-hover: var( --kendo-color-tertiary-hover );
1391
+ --color-tertiary-active: var( --kendo-color-tertiary-active );
1392
+ --color-tertiary-emphasis: var( --kendo-color-tertiary-emphasis );
1393
+ --color-tertiary-on-subtle: var( --kendo-color-tertiary-on-subtle );
1394
+ --color-on-tertiary: var( --kendo-color-on-tertiary );
1395
+ --color-tertiary-on-surface: var( --kendo-color-tertiary-on-surface );
1396
+ /* Info */
1397
+ --color-info-subtle: var( --kendo-color-info-subtle );
1398
+ --color-info-subtle-hover: var( --kendo-color-info-subtle-hover );
1399
+ --color-info-subtle-active: var( --kendo-color-info-subtle-active );
1400
+ --color-info: var( --kendo-color-info );
1401
+ --color-info-hover: var( --kendo-color-info-hover );
1402
+ --color-info-active: var( --kendo-color-info-active );
1403
+ --color-info-emphasis: var( --kendo-color-info-emphasis );
1404
+ --color-info-on-subtle: var( --kendo-color-info-on-subtle );
1405
+ --color-on-info: var( --kendo-color-on-info );
1406
+ --color-info-on-surface: var( --kendo-color-info-on-surface );
1407
+ /* Success */
1408
+ --color-success-subtle: var( --kendo-color-success-subtle );
1409
+ --color-success-subtle-hover: var( --kendo-color-success-subtle-hover );
1410
+ --color-success-subtle-active: var( --kendo-color-success-subtle-active );
1411
+ --color-success: var( --kendo-color-success );
1412
+ --color-success-hover: var( --kendo-color-success-hover );
1413
+ --color-success-active: var( --kendo-color-success-active );
1414
+ --color-success-emphasis: var( --kendo-color-success-emphasis );
1415
+ --color-success-on-subtle: var( --kendo-color-success-on-subtle );
1416
+ --color-on-success: var( --kendo-color-on-success );
1417
+ --color-success-on-surface: var( --kendo-color-success-on-surface );
1418
+ /* Warning */
1419
+ --color-warning-subtle: var( --kendo-color-warning-subtle );
1420
+ --color-warning-subtle-hover: var( --kendo-color-warning-subtle-hover );
1421
+ --color-warning-subtle-active: var( --kendo-color-warning-subtle-active );
1422
+ --color-warning: var( --kendo-color-warning );
1423
+ --color-warning-hover: var( --kendo-color-warning-hover );
1424
+ --color-warning-active: var( --kendo-color-warning-active );
1425
+ --color-warning-emphasis: var( --kendo-color-warning-emphasis );
1426
+ --color-warning-on-subtle: var( --kendo-color-warning-on-subtle );
1427
+ --color-on-warning: var( --kendo-color-on-warning );
1428
+ --color-warning-on-surface: var( --kendo-color-warning-on-surface );
1429
+ /* Error */
1430
+ --color-error-subtle: var( --kendo-color-error-subtle );
1431
+ --color-error-subtle-hover: var( --kendo-color-error-subtle-hover );
1432
+ --color-error-subtle-active: var( --kendo-color-error-subtle-active );
1433
+ --color-error: var( --kendo-color-error );
1434
+ --color-error-hover: var( --kendo-color-error-hover );
1435
+ --color-error-active: var( --kendo-color-error-active );
1436
+ --color-error-emphasis: var( --kendo-color-error-emphasis );
1437
+ --color-error-on-subtle: var( --kendo-color-error-on-subtle );
1438
+ --color-on-error: var( --kendo-color-on-error );
1439
+ --color-error-on-surface: var( --kendo-color-error-on-surface );
1440
+ /* Light */
1441
+ --color-light-subtle: var( --kendo-color-light-subtle );
1442
+ --color-light-subtle-hover: var( --kendo-color-light-subtle-hover );
1443
+ --color-light-subtle-active: var( --kendo-color-light-subtle-active );
1444
+ --color-light: var( --kendo-color-light );
1445
+ --color-light-hover: var( --kendo-color-light-hover );
1446
+ --color-light-active: var( --kendo-color-light-active );
1447
+ --color-light-emphasis: var( --kendo-color-light-emphasis );
1448
+ --color-light-on-subtle: var( --kendo-color-light-on-subtle );
1449
+ --color-on-light: var( --kendo-color-on-light );
1450
+ --color-light-on-surface: var( --kendo-color-light-on-surface );
1451
+ /* Dark */
1452
+ --color-dark-subtle: var( --kendo-color-dark-subtle );
1453
+ --color-dark-subtle-hover: var( --kendo-color-dark-subtle-hover );
1454
+ --color-dark-subtle-active: var( --kendo-color-dark-subtle-active );
1455
+ --color-dark: var( --kendo-color-dark );
1456
+ --color-dark-hover: var( --kendo-color-dark-hover );
1457
+ --color-dark-active: var( --kendo-color-dark-active );
1458
+ --color-dark-emphasis: var( --kendo-color-dark-emphasis );
1459
+ --color-dark-on-subtle: var( --kendo-color-dark-on-subtle );
1460
+ --color-on-dark: var( --kendo-color-on-dark );
1461
+ --color-dark-on-surface: var( --kendo-color-dark-on-surface );
1462
+ /* Inverse */
1463
+ --color-inverse-subtle: var( --kendo-color-inverse-subtle );
1464
+ --color-inverse-subtle-hover: var( --kendo-color-inverse-subtle-hover );
1465
+ --color-inverse-subtle-active: var( --kendo-color-inverse-subtle-active );
1466
+ --color-inverse: var( --kendo-color-inverse );
1467
+ --color-inverse-hover: var( --kendo-color-inverse-hover );
1468
+ --color-inverse-active: var( --kendo-color-inverse-active );
1469
+ --color-inverse-emphasis: var( --kendo-color-inverse-emphasis );
1470
+ --color-inverse-on-subtle: var( --kendo-color-inverse-on-subtle );
1471
+ --color-on-inverse: var( --kendo-color-on-inverse );
1472
+ --color-inverse-on-surface: var( --kendo-color-inverse-on-surface );
1473
+ /* Series A */
1474
+ --color-series-a: var( --kendo-color-series-a );
1475
+ --color-series-a-bold: var( --kendo-color-series-a-bold );
1476
+ --color-series-a-bolder: var( --kendo-color-series-a-bolder );
1477
+ --color-series-a-subtle: var( --kendo-color-series-a-subtle );
1478
+ --color-series-a-subtler: var( --kendo-color-series-a-subtler );
1479
+ /* Series B */
1480
+ --color-series-b: var( --kendo-color-series-b );
1481
+ --color-series-b-bold: var( --kendo-color-series-b-bold );
1482
+ --color-series-b-bolder: var( --kendo-color-series-b-bolder );
1483
+ --color-series-b-subtle: var( --kendo-color-series-b-subtle );
1484
+ --color-series-b-subtler: var( --kendo-color-series-b-subtler );
1485
+ /* Series C */
1486
+ --color-series-c: var( --kendo-color-series-c );
1487
+ --color-series-c-bold: var( --kendo-color-series-c-bold );
1488
+ --color-series-c-bolder: var( --kendo-color-series-c-bolder );
1489
+ --color-series-c-subtle: var( --kendo-color-series-c-subtle );
1490
+ --color-series-c-subtler: var( --kendo-color-series-c-subtler );
1491
+ /* Series D */
1492
+ --color-series-d: var( --kendo-color-series-d );
1493
+ --color-series-d-bold: var( --kendo-color-series-d-bold );
1494
+ --color-series-d-bolder: var( --kendo-color-series-d-bolder );
1495
+ --color-series-d-subtle: var( --kendo-color-series-d-subtle );
1496
+ --color-series-d-subtler: var( --kendo-color-series-d-subtler );
1497
+ /* Series E */
1498
+ --color-series-e: var( --kendo-color-series-e );
1499
+ --color-series-e-bold: var( --kendo-color-series-e-bold );
1500
+ --color-series-e-bolder: var( --kendo-color-series-e-bolder );
1501
+ --color-series-e-subtle: var( --kendo-color-series-e-subtle );
1502
+ --color-series-e-subtler: var( --kendo-color-series-e-subtler );
1503
+ /* Series F */
1504
+ --color-series-f: var( --kendo-color-series-f );
1505
+ --color-series-f-bold: var( --kendo-color-series-f-bold );
1506
+ --color-series-f-bolder: var( --kendo-color-series-f-bolder );
1507
+ --color-series-f-subtle: var( --kendo-color-series-f-subtle );
1508
+ --color-series-f-subtler: var( --kendo-color-series-f-subtler );
1509
+
1510
+ /* Typography */
1511
+ --font-sans: var( --kendo-font-family-sans );
1512
+ --font-serif: var( --kendo-font-family-sans-serif );
1513
+ --font-mono: var( --kendo-font-family-monospace );
1514
+ --text-xs: var( --kendo-font-size-xs );
1515
+ --text-xs--line-height: var( --kendo-line-height-xs );
1516
+ --text-sm: var( --kendo-font-size-sm );
1517
+ --text-sm--line-height: var( --kendo-line-height-sm );
1518
+ --text-base: var( --kendo-font-size );
1519
+ --text-base--line-height: var( --kendo-line-height );
1520
+ --text-lg: var( --kendo-font-size-lg );
1521
+ --text-lg--line-height: var( --kendo-line-height-lg );
1522
+
1523
+ --radius-none: var( --kendo-border-radius-none );
1524
+ --radius-xs: var( --kendo-border-radius-xs );
1525
+ --radius-sm: var( --kendo-border-radius-sm );
1526
+ --radius-md: var( --kendo-border-radius-md );
1527
+ --radius-lg: var( --kendo-border-radius-lg );
1528
+ --radius-xl: var( --kendo-border-radius-xl );
1529
+ --radius-2xl: var( --kendo-border-radius-xxl );
1530
+ --radius-3xl: var( --kendo-border-radius-xxxl );
1531
+ --radius-4xl: 1.5rem;
1532
+ --radius-full: var( --kendo-border-radius-full );
1533
+
1534
+ /* Breakpoints */
1535
+ --breakpoint-sm: 576px;
1536
+ --breakpoint-md: 768px;
1537
+ --breakpoint-lg: 992px;
1538
+ --breakpoint-xl: 1200px;
1539
+ --breakpoint-2xl: 1400px;
1540
+ }`;
1541
+
1542
+ // packages/kendo-ui-agent/src/lib/tools-factory.ts
1543
+ function formatApiRefItemFromJson(rawValue, component) {
1544
+ let data;
1545
+ try {
1546
+ data = JSON.parse(rawValue);
1547
+ } catch {
1548
+ return rawValue;
1549
+ }
1550
+ const item = data?.Item;
1551
+ if (!item) {
1552
+ return rawValue;
1553
+ }
1554
+ const sectionParts = [];
1555
+ const name = item.FullName ?? item.Name ?? "";
1556
+ const type = item.Type ?? "";
1557
+ const summary = item.Summary ?? "";
1558
+ const syntax = item.SyntaxContent ?? "";
1559
+ sectionParts.push(
1560
+ `## API Reference Item
1561
+ - Name: ${name}
1562
+ - Type: ${type}
1563
+ - Summary: ${summary}
1564
+ - Syntax: ${syntax}`
1565
+ );
1566
+ const returnTypeItems = data.RelatedItemsByType?.["return_type"];
1567
+ if (returnTypeItems?.length) {
1568
+ const returnType = returnTypeItems[0].Text;
1569
+ if (returnType) {
1570
+ sectionParts.push(`- Return Type: ${returnType}`);
1571
+ }
1572
+ }
1573
+ const examples = item.Examples ?? [];
1574
+ if (examples.length > 0) {
1575
+ let exampleSection = "## Examples\n";
1576
+ let exampleIndex = 0;
1577
+ for (const example of examples) {
1578
+ const exComponent = (example.Component ?? "").toLowerCase();
1579
+ const compLower = component.toLowerCase();
1580
+ if (exComponent && exComponent !== compLower && exComponent !== "general") {
1581
+ continue;
1582
+ }
1583
+ exampleIndex += 1;
1584
+ const code = example.Code ?? "";
1585
+ exampleSection += `### Example ${exampleIndex}
412
1586
  \`\`\`
413
- ${k}
1587
+ ${code}
414
1588
  \`\`\`
415
- `}c>0&&s.push(p)}let h=n.RelatedItemsByType??{},f=[];for(let[p,c]of Object.entries(h))if(!(p==="return_type"||p==="render_fragment"))for(let y of c??[]){let S=y.FullName??"",T=y.ShortText??"";f.push(`### ${S} (${p})
416
- ${T}`)}return f.length>0&&s.push(`## Additional Context
417
- `+f.join(`
418
- ---
419
- `)),s.join(`
420
-
421
- `)}function ue(e,t,n){let{name:o,title:s,description:r,layoutAssistantName:a,codeAssistantName:i,styleAssistantName:d,iconAssistantName:m,accessibilityAssistantName:A,suiteName:h,libKey:f,components:p}=e,c=new v(o,{title:s,description:r,requiredAccess:e.requiredAccess,inputSchema:{userIntent:C.string().describe(`Detailed description and intent of what the user wants to build. Include the type of page/component, main functionality, visual requirements, and any specific ${h} components you want to use.`),needsComponentsDocsConfidence:C.number().min(0).max(1).default(1).describe("Confidence (0-1) to include Component Documentation assistance. Default is 1."),needsLayoutConfidence:C.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Layout assistance. Default is 0."),needsStylingConfidence:C.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Theming/Styling assistance. Default is 0."),needsResponsiveBehaviorConfidence:C.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Responsive Behavior assistance. Default is 0."),needsIconsConfidence:C.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Icons assistance. Default is 0."),componentsNeeded:C.array(C.enum(p)).optional().describe(`Optional list of specific ${h} components needed for the project.`)}},async({userIntent:y,needsComponentsDocsConfidence:S,needsLayoutConfidence:T,needsStylingConfidence:k,needsResponsiveBehaviorConfidence:N,needsIconsConfidence:X,componentsNeeded:Z},{_meta:Ye})=>{g("UI Orchestrator called with:",{userIntent:y,needsComponentsDocsConfidence:S,needsLayoutConfidence:T,needsStylingConfidence:k,needsResponsiveBehaviorConfidence:N,needsIconsConfidence:X});try{await n.recordOrchestratorUserRequest({meta:{userIntent:y,componentsNeeded:Z,_meta:Ye}})}catch(U){throw R(U)}let Qe=c.server?.server.getClientCapabilities?.()?.elicitation,ee;if(Qe&&k>.3&&k<=.6){let U=await c.server?.server.elicitInput({message:"I was unable to determine if you need custom Kendo Theme assistant. Can you please confirm?",requestedSchema:{type:"object",properties:{includeCustomTheming:{type:"boolean",description:"Whether to include Custom Theming assistance in the workflow."}},required:["includeCustomTheming"]}});U?.action==="accept"&&U.content?.includeCustomTheming&&(ee=!0)}return{content:[{type:"text",text:L({name:o,userIntent:y,includeComponentsDocs:S>.3,includeTheming:k>.6||!!ee,includeLayout:T>.5,includeIcons:X>.6,includeResponsive:T>.5&&N>.4,layoutAssistantName:a,codeAssistantName:i,styleAssistantName:d,iconAssistantName:m,accessibilityAssistantName:A,suiteName:h,libKey:f,components:Z},t)}]}});return c}function ge(e,t){let{name:n,title:o,description:s,iconAssistantName:r,codeAssistantName:a,suiteName:i,libKey:d,components:m}=e;return new v(n,{title:o,description:s,inputSchema:{userIntent:C.string().describe(`Describe what you want to build or what components you're looking for. Include the type of functionality, features, or UI elements you need from ${i}.`),needsIconsConfidence:C.number().min(0).max(1).default(.7).describe("Confidence (0-1) to include Icons assistance. Default is 0.7."),componentsNeeded:C.array(C.enum(m)).optional().describe(`Optional list of specific ${i} components you want to learn about.`)},requiredAccess:e.requiredAccess},async({userIntent:h,needsIconsConfidence:f,componentsNeeded:p},{_meta:c})=>{g("Assistant Orchestrator called with:",{userIntent:h,needsIconsConfidence:f,componentsNeeded:p});try{await t.recordOrchestratorUserRequest({meta:{userIntent:h,componentsNeeded:p,_meta:c}})}catch(S){throw R(S)}return{content:[{type:"text",text:V({name:n,userIntent:h,includeComponentsDocs:!0,includeIcons:f>.5,codeAssistantName:a,iconAssistantName:r,suiteName:i,libKey:d,components:p})}]}})}function he(e,t){let{name:n,title:o,description:s,suiteName:r,libKey:a,getPreContent:i}=e;return new v(n,{title:o,description:s,requiredAccess:e.requiredAccess,inputSchema:{prompt:C.string().describe("An enhanced prompt describing the HTML layout structure, design requirements or specific visual effects you want to achieve."),includeBuildingBlockExamples:C.boolean().describe("Whether to include building block examples. Defaults to false.").default(!1)}},async({prompt:d,includeBuildingBlockExamples:m},{_meta:A})=>{g("Layout Assistant called with:",{prompt:d,includeBuildingBlockExamples:m});try{let f=(await t.queryCssUtils({query:d},{_meta:A})).values.join(`
422
- `)||"No CSS utilities found for the given prompt.",p=i?.()??"",c=y=>`${p}
1589
+ `;
1590
+ }
1591
+ if (exampleIndex > 0) {
1592
+ sectionParts.push(exampleSection);
1593
+ }
1594
+ }
1595
+ const related = data.RelatedItemsByType ?? {};
1596
+ const additionalContextItems = [];
1597
+ for (const [relationType, relatedItems] of Object.entries(related)) {
1598
+ if (relationType === "return_type" || relationType === "render_fragment") {
1599
+ continue;
1600
+ }
1601
+ for (const relatedItem of relatedItems ?? []) {
1602
+ const fullName = relatedItem.FullName ?? "";
1603
+ const shortText = relatedItem.ShortText ?? "";
1604
+ additionalContextItems.push(`### ${fullName} (${relationType})
1605
+ ${shortText}`);
1606
+ }
1607
+ }
1608
+ if (additionalContextItems.length > 0) {
1609
+ sectionParts.push("## Additional Context\n" + additionalContextItems.join("\n---\n"));
1610
+ }
1611
+ return sectionParts.join("\n\n");
1612
+ }
1613
+ var LAYOUT_MODE = process.env.KENDO_UIA_LAYOUT_MODE || "utils";
1614
+ function createOrchestratorTool(config, templateOptions, contextApi2) {
1615
+ const {
1616
+ name,
1617
+ title,
1618
+ description,
1619
+ layoutAssistantName: layoutAssistantName2,
1620
+ codeAssistantName: codeAssistantName2,
1621
+ styleAssistantName: styleAssistantName2,
1622
+ iconAssistantName: iconAssistantName2,
1623
+ accessibilityAssistantName: accessibilityAssistantName2,
1624
+ figmaD2CToolName: figmaD2CToolName2,
1625
+ suiteName,
1626
+ libKey,
1627
+ components
1628
+ } = config;
1629
+ const tool = new UIAgentTool(
1630
+ name,
1631
+ {
1632
+ title,
1633
+ description,
1634
+ requiredAccess: config.requiredAccess,
1635
+ inputSchema: {
1636
+ userIntent: z4.string().describe(
1637
+ `Detailed description and intent of what the user wants to build. Include the type of page/component, main functionality, visual requirements, and any specific ${suiteName} components you want to use.`
1638
+ ),
1639
+ needsComponentsDocsConfidence: z4.number().min(0).max(1).default(1).describe(
1640
+ "Confidence (0-1) to include Component Documentation assistance. Default is 1."
1641
+ ),
1642
+ needsLayoutConfidence: z4.number().min(0).max(1).default(0).describe(
1643
+ "Confidence (0-1) to include Layout assistance. Default is 0."
1644
+ ),
1645
+ needsStylingConfidence: z4.number().min(0).max(1).default(0).describe(
1646
+ "Confidence (0-1) to include Theming/Styling assistance. Default is 0."
1647
+ ),
1648
+ needsResponsiveBehaviorConfidence: z4.number().min(0).max(1).default(0).describe(
1649
+ "Confidence (0-1) to include Responsive Behavior assistance. Default is 0."
1650
+ ),
1651
+ needsIconsConfidence: z4.number().min(0).max(1).default(0).describe(
1652
+ "Confidence (0-1) to include Icons assistance. Default is 0."
1653
+ ),
1654
+ needsFigmaD2CConfidence: z4.boolean().describe("Whether to include Figma D2C assistance. If the prompt includes a Figma URL always make sure to set to true.").default(false),
1655
+ componentsNeeded: z4.array(z4.enum(components)).optional().describe(
1656
+ `Optional list of specific ${suiteName} components needed for the project.`
1657
+ )
1658
+ }
1659
+ },
1660
+ async ({
1661
+ userIntent,
1662
+ needsComponentsDocsConfidence,
1663
+ needsLayoutConfidence,
1664
+ needsStylingConfidence,
1665
+ needsResponsiveBehaviorConfidence,
1666
+ needsIconsConfidence,
1667
+ needsFigmaD2CConfidence,
1668
+ componentsNeeded
1669
+ }, { _meta }) => {
1670
+ log("UI Orchestrator called with:", {
1671
+ userIntent,
1672
+ needsComponentsDocsConfidence,
1673
+ needsLayoutConfidence,
1674
+ needsStylingConfidence,
1675
+ needsResponsiveBehaviorConfidence,
1676
+ needsIconsConfidence
1677
+ });
1678
+ try {
1679
+ await contextApi2.recordOrchestratorUserRequest({
1680
+ meta: {
1681
+ userIntent,
1682
+ componentsNeeded,
1683
+ _meta
1684
+ }
1685
+ });
1686
+ } catch (error) {
1687
+ throw getGrpcError(error);
1688
+ }
1689
+ const clientCapabilities = tool.server?.server.getClientCapabilities?.();
1690
+ const supportsElicitation = clientCapabilities?.elicitation;
1691
+ let forceIncludeCustomTheming;
1692
+ if (supportsElicitation && needsStylingConfidence > 0.3 && needsStylingConfidence <= 0.6) {
1693
+ const result = await tool.server?.server.elicitInput({
1694
+ message: "I was unable to determine if you need custom Kendo Theme assistant. Can you please confirm?",
1695
+ requestedSchema: {
1696
+ type: "object",
1697
+ properties: {
1698
+ includeCustomTheming: {
1699
+ type: "boolean",
1700
+ description: "Whether to include Custom Theming assistance in the workflow."
1701
+ }
1702
+ },
1703
+ required: ["includeCustomTheming"]
1704
+ }
1705
+ });
1706
+ if (result?.action === "accept" && result.content?.includeCustomTheming) {
1707
+ forceIncludeCustomTheming = true;
1708
+ }
1709
+ }
1710
+ const response = renderOrchestratorResponse(
1711
+ {
1712
+ name,
1713
+ userIntent,
1714
+ includeComponentsDocs: needsComponentsDocsConfidence > 0.3,
1715
+ includeTheming: needsStylingConfidence > 0.6 || !!forceIncludeCustomTheming,
1716
+ includeLayout: needsLayoutConfidence > 0.5,
1717
+ includeIcons: needsIconsConfidence > 0.6,
1718
+ includeResponsive: needsLayoutConfidence > 0.5 && needsResponsiveBehaviorConfidence > 0.4,
1719
+ includeFigmaD2C: needsFigmaD2CConfidence,
1720
+ layoutAssistantName: layoutAssistantName2,
1721
+ codeAssistantName: codeAssistantName2,
1722
+ styleAssistantName: styleAssistantName2,
1723
+ iconAssistantName: iconAssistantName2,
1724
+ accessibilityAssistantName: accessibilityAssistantName2,
1725
+ figmaD2CToolName: figmaD2CToolName2,
1726
+ suiteName,
1727
+ libKey,
1728
+ layoutMode: LAYOUT_MODE,
1729
+ components: componentsNeeded
1730
+ },
1731
+ templateOptions
1732
+ );
1733
+ return {
1734
+ content: [
1735
+ {
1736
+ type: "text",
1737
+ text: response
1738
+ }
1739
+ ]
1740
+ };
1741
+ }
1742
+ );
1743
+ return tool;
1744
+ }
1745
+ function createAssistantOrchestratorTool(config, contextApi2) {
1746
+ const {
1747
+ name,
1748
+ title,
1749
+ description,
1750
+ iconAssistantName: iconAssistantName2,
1751
+ codeAssistantName: codeAssistantName2,
1752
+ suiteName,
1753
+ libKey,
1754
+ components
1755
+ } = config;
1756
+ const tool = new UIAgentTool(
1757
+ name,
1758
+ {
1759
+ title,
1760
+ description,
1761
+ inputSchema: {
1762
+ userIntent: z4.string().describe(
1763
+ `Describe what you want to build or what components you're looking for. Include the type of functionality, features, or UI elements you need from ${suiteName}.`
1764
+ ),
1765
+ needsIconsConfidence: z4.number().min(0).max(1).default(0.7).describe(
1766
+ "Confidence (0-1) to include Icons assistance. Default is 0.7."
1767
+ ),
1768
+ componentsNeeded: z4.array(z4.enum(components)).optional().describe(
1769
+ `Optional list of specific ${suiteName} components you want to learn about.`
1770
+ )
1771
+ },
1772
+ requiredAccess: config.requiredAccess
1773
+ },
1774
+ async ({
1775
+ userIntent,
1776
+ needsIconsConfidence,
1777
+ componentsNeeded
1778
+ }, { _meta }) => {
1779
+ log("Assistant Orchestrator called with:", {
1780
+ userIntent,
1781
+ needsIconsConfidence,
1782
+ componentsNeeded
1783
+ });
1784
+ try {
1785
+ await contextApi2.recordOrchestratorUserRequest({
1786
+ meta: {
1787
+ userIntent,
1788
+ componentsNeeded,
1789
+ _meta
1790
+ }
1791
+ });
1792
+ } catch (error) {
1793
+ throw getGrpcError(error);
1794
+ }
1795
+ const response = renderAssistantOrchestratorResponse({
1796
+ name,
1797
+ userIntent,
1798
+ includeComponentsDocs: true,
1799
+ // Always true for assistant mode
1800
+ includeIcons: needsIconsConfidence > 0.5,
1801
+ codeAssistantName: codeAssistantName2,
1802
+ iconAssistantName: iconAssistantName2,
1803
+ suiteName,
1804
+ libKey,
1805
+ components: componentsNeeded
1806
+ });
1807
+ return {
1808
+ content: [
1809
+ {
1810
+ type: "text",
1811
+ text: response
1812
+ }
1813
+ ]
1814
+ };
1815
+ }
1816
+ );
1817
+ return tool;
1818
+ }
1819
+ function createLayoutAssistantTool(config, contextApi2) {
1820
+ const {
1821
+ name,
1822
+ title,
1823
+ description,
1824
+ suiteName: _suiteName,
1825
+ libKey,
1826
+ getPreContent
1827
+ } = config;
1828
+ return new UIAgentTool(
1829
+ name,
1830
+ {
1831
+ title,
1832
+ description,
1833
+ requiredAccess: LAYOUT_MODE === "utils" ? config.requiredAccess : ["none"],
1834
+ inputSchema: {
1835
+ prompt: z4.string().describe(
1836
+ `An enhanced prompt describing the HTML layout structure, design requirements or specific visual effects you want to achieve.`
1837
+ ),
1838
+ includeBuildingBlockExamples: z4.boolean().describe(
1839
+ "Whether to include building block examples. Defaults to false."
1840
+ ).default(false)
1841
+ }
1842
+ },
1843
+ async ({ prompt, includeBuildingBlockExamples }, { _meta }) => {
1844
+ log("Layout Assistant called with:", {
1845
+ prompt,
1846
+ includeBuildingBlockExamples
1847
+ });
1848
+ try {
1849
+ const cssResponse = await contextApi2.queryCssUtils({ query: prompt }, { _meta });
1850
+ let finalMarkdown = cssResponse.values.join("\n") || "No CSS utilities found for the given prompt.";
1851
+ const preContent = getPreContent?.() ?? "";
1852
+ const buildLayout = (buildingBlockMd) => {
1853
+ return `${preContent}
423
1854
 
424
1855
  # Kendo Design System CSS Utilities
425
1856
 
426
- ${f}
427
- ${y??""}
428
- `;if(m)try{let y=await t.queryBuildingBlocks({query:d,lib_name:a},{_meta:A}),S="";y.items?.length>0&&(S=`
1857
+ ${finalMarkdown}
1858
+ ${buildingBlockMd ?? ""}
1859
+ `;
1860
+ };
1861
+ if (includeBuildingBlockExamples) {
1862
+ try {
1863
+ const buildingBlocksResponse = await contextApi2.queryBuildingBlocks({
1864
+ query: prompt,
1865
+ lib_name: libKey
1866
+ }, { _meta });
1867
+ let buildingBlockMd = "";
1868
+ if (buildingBlocksResponse.items?.length > 0) {
1869
+ buildingBlockMd = `
429
1870
  ## Building Blocks Examples
430
1871
 
431
1872
  The examples here are for demonstration purpose how CSS utils can be implemented in various building blocks.
432
1873
  However, consider your own design requirements and specifics in order to implement your templates/building blocks correctly.
433
1874
 
434
- ${y.items.map(T=>`
435
- ### ${T.name}
1875
+ ${buildingBlocksResponse.items.map(
1876
+ (item) => `
1877
+ ### ${item.name}
436
1878
 
437
- ${T.description}
1879
+ ${item.description}
438
1880
 
439
1881
  \`\`\`code
440
- ${T.code}
1882
+ ${item.code}
441
1883
  \`\`\`
442
- `).join(`
443
- `)}`),f=c(S)}catch(y){g("Error calling building-blocks service:",y),f=c()}else f=c();return{content:[{type:"text",text:f}]}}catch(h){throw R(h)}})}function fe(e,t){let{name:n,title:o,description:s,libKey:r,getPreContent:a}=e;return new v(n,{title:o,description:s,requiredAccess:e.requiredAccess,inputSchema:{prompt:C.string().describe("A natural language description of the desired visual style or theme. For example: 'Create a modern dark theme with high contrast'.")}},async({prompt:i},{_meta:d})=>{g("Style Assistant called with:",{prompt:i});let m="";try{let f=await t.queryThemeGenerate({prompt:i},{_meta:d});if(f.variables_json){let p=JSON.parse(f.variables_json),c=[];if(p)for(let y of Object.keys(p))typeof p[y]=="string"&&c.push(`${y}: ${p[y]}`);m=c.join(`
444
-
445
- `)}}catch(f){throw R(f)}let A=a?.()??"";return{content:[{type:"text",text:m?`Use the following CSS variables to style the web application, including colors, typography, spacing, and component appearance.
1884
+ `
1885
+ ).join("\n")}`;
1886
+ }
1887
+ finalMarkdown = buildLayout(buildingBlockMd);
1888
+ } catch (buildingBlockError) {
1889
+ log("Error calling building-blocks service:", buildingBlockError);
1890
+ finalMarkdown = buildLayout();
1891
+ }
1892
+ } else {
1893
+ finalMarkdown = buildLayout();
1894
+ }
1895
+ return {
1896
+ content: [
1897
+ {
1898
+ type: "text",
1899
+ text: finalMarkdown
1900
+ }
1901
+ ]
1902
+ };
1903
+ } catch (error) {
1904
+ throw getGrpcError(error);
1905
+ }
1906
+ }
1907
+ );
1908
+ }
1909
+ function createStyleAssistantTool(config, contextApi2) {
1910
+ const { name, title, description, libKey: _libKey, getPreContent } = config;
1911
+ return new UIAgentTool(
1912
+ name,
1913
+ {
1914
+ title,
1915
+ description,
1916
+ requiredAccess: config.requiredAccess,
1917
+ inputSchema: {
1918
+ prompt: z4.string().describe(
1919
+ `A natural language description of the desired visual style or theme. For example: 'Create a modern dark theme with high contrast'.`
1920
+ )
1921
+ }
1922
+ },
1923
+ async ({ prompt }, { _meta }) => {
1924
+ log("Style Assistant called with:", { prompt });
1925
+ let formattedCSS = "";
1926
+ try {
1927
+ const result = await contextApi2.queryThemeGenerate({ prompt }, { _meta });
1928
+ if (result.variables_json) {
1929
+ const theme = JSON.parse(result.variables_json);
1930
+ let cssBlocks = [];
1931
+ if (theme) {
1932
+ for (const key of Object.keys(theme)) {
1933
+ if (typeof theme[key] === "string") {
1934
+ cssBlocks.push(`${key}: ${theme[key]}`);
1935
+ }
1936
+ }
1937
+ }
1938
+ formattedCSS = cssBlocks.join("\n\n");
1939
+ }
1940
+ } catch (error) {
1941
+ throw getGrpcError(error);
1942
+ }
1943
+ const preContent = getPreContent?.() ?? "";
1944
+ const response = formattedCSS ? `Use the following CSS variables to style the web application, including colors, typography, spacing, and component appearance.
446
1945
  Ensure the variables are applied consistently across all relevant elements.
447
1946
  Do NOT set any inline styles. CSS variables should be defined in global or component-level CSS files, or via supported theming mechanisms.
448
1947
 
449
- ${A}
1948
+ ${preContent}
450
1949
 
451
1950
  ## Generated CSS Variables
452
1951
 
453
1952
  \`\`\`css
454
- ${m}
1953
+ ${formattedCSS}
455
1954
  \`\`\`
456
- `:"No CSS variables were generated for the given prompt."}]}})}function ye(e,t){let{name:n,title:o,description:s,libKey:r,getPostContent:a}=e;return new v(n,{title:o,description:s,requiredAccess:e.requiredAccess,inputSchema:{query:C.string().describe("A search query for finding icons. Be specific about the icon purpose, style, or action."),limit:C.number().min(.1).max(1).default(.1).describe("The proportion of matching icons to return (0.1 = 1 icon, 0.5 = 5 icons, 1.0 = many icons). Default is 0.1.")}},async({query:i,limit:d},{_meta:m})=>{g("Icon Search called with:",{query:i,limit:d});try{let A=await t.queryIconsSearch({query:i,limit:d*100},{_meta:m}),h=a?.()??"";return{content:[{type:"text",text:`${A.values.join(`
457
-
458
- `)}
459
-
460
- ${h}`}]}}catch(A){throw R(A)}})}function Ae(e,t){let{name:n,title:o,description:s,libKey:r,suiteName:a,components:i,componentAliases:d,getPostContent:m}=e;return new v(n,{title:o,description:s,requiredAccess:e.requiredAccess,inputSchema:{query:C.string().describe("The query to search for."),component:C.enum(i).describe("The component to search for. If not specified, use General.")}},async({query:A,component:h},{_meta:f})=>{g("Code Assistant called with:",{query:A,component:h});let p=h;if(d){let c=d[h];c&&(p=c)}try{let y=(await t.query({query:A,component:p?.toLowerCase()??"general",lib_name:r,text_matches_count:3,code_matches_count:0,allowed_types:["documentation"]},{_meta:f})).values.map(k=>k.replace(/\0/g,"")),S=m?.({component:h})??"";return{content:[{type:"text",text:`${y.join(`
461
-
462
- `)}
463
-
464
- ${S}`}]}}catch(c){throw R(c)}})}function Ce(e,t){let{name:n,title:o,description:s,libKey:r,suiteName:a,components:i,componentAliases:d}=e;return new v(n,{title:o,description:s,requiredAccess:e.requiredAccess,inputSchema:{query:C.string().describe("The query to search for."),component:C.enum(i).describe("The component to search for. If not specified, use General."),includeGeneralGuidelines:C.boolean().default(!1).describe("Set to true only on the first call to include comprehensive WCAG 2.2 Level AA general guidelines. After the first call, set to false to get only component-specific accessibility information. Default is false.")}},async({query:m,component:A,includeGeneralGuidelines:h},{_meta:f})=>{g("Accessibility Assistant called with:",{query:m,component:A,includeGeneralGuidelines:h});let p=A;if(d){let c=d[A];c&&(p=c)}try{let c="";if(h){let N=le();c+=`# WCAG 2.2 Level AA General Accessibility Guidelines
465
-
466
- `,c+=N,c+=`
467
-
468
- ---
1955
+ ` : "No CSS variables were generated for the given prompt.";
1956
+ return {
1957
+ content: [
1958
+ {
1959
+ type: "text",
1960
+ text: response
1961
+ },
1962
+ LAYOUT_MODE === "tailwind" ? {
1963
+ type: "text",
1964
+ text: `Note: For layout and spacing, use Tailwind CSS utility classes to structure your layout and apply spacing between elements.
1965
+ IMPORTANT: In order to use the Kendo Theme CSS variables to work in a Tailwind CSS project, make sure to configure Tailwind to allow custom CSS properties and use the generated CSS variables in your Tailwind configuration for colors, spacing, etc. This way you can leverage the design tokens generated by the Style Assistant while using Tailwind for layout and utility classes. Follow the tailwind_bridge_example provided as insperation for how to bridge Kendo Theme CSS variables with Tailwind CSS.
1966
+
1967
+ <taiwind_bridge_example>
1968
+ ${tailwindBridgeExample}
1969
+ </taiwind_bridge_example>
1970
+ `
1971
+ } : LAYOUT_MODE === "vanilla" ? {
1972
+ type: "text",
1973
+ text: "Note: For layout and spacing, use vanilla CSS with custom styles including flexbox, grid, media queries, and relative units. Do NOT use any CSS utility framework classes."
1974
+ } : {
1975
+ type: "text",
1976
+ text: "Note: For layout and spacing, use the Layout Assistant tool to get the appropriate Kendo CSS utility classes."
1977
+ }
1978
+ ]
1979
+ };
1980
+ }
1981
+ );
1982
+ }
1983
+ function createIconSearchTool(config, contextApi2) {
1984
+ const { name, title, description, libKey: _libKey, getPostContent } = config;
1985
+ return new UIAgentTool(
1986
+ name,
1987
+ {
1988
+ title,
1989
+ description,
1990
+ requiredAccess: config.requiredAccess,
1991
+ inputSchema: {
1992
+ query: z4.string().describe(
1993
+ "A search query for finding icons. Be specific about the icon purpose, style, or action."
1994
+ ),
1995
+ limit: z4.number().min(0.1).max(1).default(0.1).describe(
1996
+ `The proportion of matching icons to return (0.1 = 1 icon, 0.5 = 5 icons, 1.0 = many icons). Default is 0.1.`
1997
+ )
1998
+ }
1999
+ },
2000
+ async ({ query, limit }, { _meta }) => {
2001
+ log("Icon Search called with:", { query, limit });
2002
+ try {
2003
+ const result = await contextApi2.queryIconsSearch({
2004
+ query,
2005
+ limit: limit * 100
2006
+ }, { _meta });
2007
+ const postContent = getPostContent?.() ?? "";
2008
+ const response = `${result.values.join("\n\n")}
2009
+
2010
+ ${postContent}`;
2011
+ return {
2012
+ content: [
2013
+ {
2014
+ type: "text",
2015
+ text: response
2016
+ }
2017
+ ]
2018
+ };
2019
+ } catch (error) {
2020
+ throw getGrpcError(error);
2021
+ }
2022
+ }
2023
+ );
2024
+ }
2025
+ function createCodeAssistantTool(config, contextApi2) {
2026
+ const {
2027
+ name,
2028
+ title,
2029
+ description,
2030
+ libKey,
2031
+ suiteName: _suiteName,
2032
+ components,
2033
+ componentAliases,
2034
+ getPostContent
2035
+ } = config;
2036
+ return new UIAgentTool(
2037
+ name,
2038
+ {
2039
+ title,
2040
+ description,
2041
+ requiredAccess: config.requiredAccess,
2042
+ inputSchema: {
2043
+ query: z4.string().describe("The query to search for."),
2044
+ component: z4.enum(components).describe(
2045
+ "The component to search for. If not specified, use General."
2046
+ )
2047
+ }
2048
+ },
2049
+ async ({ query, component }, { _meta }) => {
2050
+ log("Code Assistant called with:", { query, component });
2051
+ let resolvedComponent = component;
2052
+ if (componentAliases) {
2053
+ const alias = componentAliases[component];
2054
+ if (alias) {
2055
+ resolvedComponent = alias;
2056
+ }
2057
+ }
2058
+ try {
2059
+ const response = await contextApi2.query({
2060
+ query,
2061
+ component: resolvedComponent?.toLowerCase() ?? "general",
2062
+ lib_name: libKey,
2063
+ text_matches_count: 3,
2064
+ code_matches_count: 0,
2065
+ allowed_types: ["documentation"]
2066
+ }, { _meta });
2067
+ const cleanedValues = response.values.map(
2068
+ (val) => val.replace(/\0/g, "")
2069
+ );
2070
+ const postContent = getPostContent?.({ component }) ?? "";
2071
+ const combinedResponse = `${cleanedValues.join("\n\n")}
2072
+
2073
+ ${postContent}`;
2074
+ return {
2075
+ content: [
2076
+ {
2077
+ type: "text",
2078
+ text: combinedResponse
2079
+ }
2080
+ ]
2081
+ };
2082
+ } catch (error) {
2083
+ throw getGrpcError(error);
2084
+ }
2085
+ }
2086
+ );
2087
+ }
2088
+ function createAccessibilityAssistantTool(config, contextApi2) {
2089
+ const {
2090
+ name,
2091
+ title,
2092
+ description,
2093
+ libKey,
2094
+ suiteName: _suiteName,
2095
+ components,
2096
+ componentAliases
2097
+ } = config;
2098
+ return new UIAgentTool(
2099
+ name,
2100
+ {
2101
+ title,
2102
+ description,
2103
+ requiredAccess: config.requiredAccess,
2104
+ inputSchema: {
2105
+ query: z4.string().describe("The query to search for."),
2106
+ component: z4.enum(components).describe(
2107
+ "The component to search for. If not specified, use General."
2108
+ ),
2109
+ includeGeneralGuidelines: z4.boolean().default(false).describe(
2110
+ "Set to true only on the first call to include comprehensive WCAG 2.2 Level AA general guidelines. After the first call, set to false to get only component-specific accessibility information. Default is false."
2111
+ )
2112
+ }
2113
+ },
2114
+ async ({ query, component, includeGeneralGuidelines }, { _meta }) => {
2115
+ log("Accessibility Assistant called with:", {
2116
+ query,
2117
+ component,
2118
+ includeGeneralGuidelines
2119
+ });
2120
+ let resolvedComponent = component;
2121
+ if (componentAliases) {
2122
+ const alias = componentAliases[component];
2123
+ if (alias) {
2124
+ resolvedComponent = alias;
2125
+ }
2126
+ }
2127
+ try {
2128
+ let finalResponse = "";
2129
+ if (includeGeneralGuidelines) {
2130
+ const generalGuidelines = getAccessibilityGuidelines();
2131
+ finalResponse += "# WCAG 2.2 Level AA General Accessibility Guidelines\n\n";
2132
+ finalResponse += generalGuidelines;
2133
+ finalResponse += "\n\n---\n\n";
2134
+ }
2135
+ const response = await contextApi2.getApiRefMatches({
2136
+ query,
2137
+ component: resolvedComponent?.toLowerCase() ?? "general",
2138
+ lib_name: libKey,
2139
+ filters_json: '{"type":{"$in":["accessibility"]}}'
2140
+ }, { _meta });
2141
+ const cleanedValues = response.values.map(
2142
+ (val) => val.replace(/\0/g, "")
2143
+ );
2144
+ const formattedValues = cleanedValues.map(
2145
+ (val) => formatApiRefItemFromJson(val, resolvedComponent?.toLowerCase() ?? "general")
2146
+ );
2147
+ const componentResult = formattedValues.join("\n\n");
2148
+ if (componentResult) {
2149
+ if (includeGeneralGuidelines) {
2150
+ finalResponse += "# Component-Specific Accessibility Information\n\n";
2151
+ }
2152
+ finalResponse += componentResult;
2153
+ } else if (!includeGeneralGuidelines) {
2154
+ finalResponse = "No component-specific accessibility guidelines found.";
2155
+ }
2156
+ return {
2157
+ content: [
2158
+ {
2159
+ type: "text",
2160
+ text: finalResponse
2161
+ }
2162
+ ]
2163
+ };
2164
+ } catch (error) {
2165
+ throw getGrpcError(error);
2166
+ }
2167
+ }
2168
+ );
2169
+ }
2170
+ function getGrpcError(error) {
2171
+ const errorObj = error;
2172
+ if (errorObj.code === 16 /* UNAUTHENTICATED */) {
2173
+ return new Error(
2174
+ "Error: You are not authenticated. Please verify the Telerik License Key provided is valid."
2175
+ );
2176
+ } else if (errorObj.code === 8 /* RESOURCE_EXHAUSTED */) {
2177
+ return new Error(
2178
+ `Error: You have exceeded the extension quota. Upgrade to subscription licensing to unlock full access. Message: ${errorObj.message}.`
2179
+ );
2180
+ } else if (errorObj.code === 7 /* PERMISSION_DENIED */) {
2181
+ return new Error(
2182
+ "Error: You do not have permission to access this resource. Please verify that you have a valid license."
2183
+ );
2184
+ } else {
2185
+ return new Error(
2186
+ `Error: An error occurred while calling the service. Please try again later.
2187
+
2188
+ Error Code: ${errorObj.code} Error Message: ${errorObj.message}`
2189
+ );
2190
+ }
2191
+ }
469
2192
 
470
- `}let k=(await t.getApiRefMatches({query:m,component:p?.toLowerCase()??"general",lib_name:r,filters_json:'{"type":{"$in":["accessibility"]}}'},{_meta:f})).values.map(N=>N.replace(/\0/g,"")).map(N=>mt(N,p?.toLowerCase()??"general")).join(`
2193
+ // packages/kendo-ui-agent/src/lib/figma-d2c/types.ts
2194
+ var FigmaAPIError = class extends Error {
2195
+ constructor(status, body) {
2196
+ super(`Figma API error ${status}: ${body}`);
2197
+ this.status = status;
2198
+ this.body = body;
2199
+ this.name = "FigmaAPIError";
2200
+ }
2201
+ };
2202
+
2203
+ // packages/kendo-ui-agent/src/lib/figma-d2c/figma-client.ts
2204
+ var FigmaClient = class {
2205
+ constructor(apiKey) {
2206
+ this.retryConfig = {
2207
+ maxRetries: 3,
2208
+ baseDelayMs: 1e3,
2209
+ maxDelayMs: 3e4
2210
+ };
2211
+ this.apiKey = apiKey;
2212
+ }
2213
+ /**
2214
+ * Fetch file metadata including node and component counts
2215
+ */
2216
+ async getFileMeta(fileKey) {
2217
+ const fileResponse = await this.getFile(fileKey, { depth: 1 });
2218
+ const counts = this.countNodesAndComponents(fileResponse.document);
2219
+ return {
2220
+ nodeCount: counts.nodes,
2221
+ componentCount: counts.components
2222
+ };
2223
+ }
2224
+ /**
2225
+ * Fetch a specific file with optional depth parameter
2226
+ */
2227
+ async getFile(fileKey, options) {
2228
+ const url = this.buildFileUrl(fileKey, options);
2229
+ return this.fetchWithRetry(url);
2230
+ }
2231
+ /**
2232
+ * Fetch specific nodes by ID
2233
+ */
2234
+ async getNodes(fileKey, nodeIds, options) {
2235
+ const url = this.buildNodesUrl(fileKey, nodeIds, options);
2236
+ return this.fetchWithRetry(url);
2237
+ }
2238
+ /**
2239
+ * Get export URLs for node images
2240
+ */
2241
+ async getImages(fileKey, nodeIds, options) {
2242
+ const url = this.buildImagesUrl(fileKey, nodeIds, options);
2243
+ return this.fetchWithRetry(url);
2244
+ }
2245
+ /**
2246
+ * Get download URLs for embedded image fills
2247
+ * Returns a map of imageRef hashes to temporary S3 download URLs
2248
+ */
2249
+ async getImageFills(fileKey) {
2250
+ const url = `https://api.figma.com/v1/files/${fileKey}/images`;
2251
+ return this.fetchWithRetry(url);
2252
+ }
2253
+ /**
2254
+ * Core fetch method with retry logic
2255
+ */
2256
+ async fetchWithRetry(url) {
2257
+ let lastError = null;
2258
+ for (let attempt = 0; attempt < this.retryConfig.maxRetries; attempt++) {
2259
+ try {
2260
+ const response = await fetch(url, {
2261
+ headers: {
2262
+ "X-Figma-Token": this.apiKey,
2263
+ "Content-Type": "application/json"
2264
+ }
2265
+ });
2266
+ if (response.status === 429) {
2267
+ const retryAfter = response.headers.get("Retry-After");
2268
+ const delayMs = retryAfter ? parseInt(retryAfter) * 1e3 : this.calculateBackoff(attempt);
2269
+ await this.sleep(delayMs);
2270
+ continue;
2271
+ }
2272
+ if (!response.ok) {
2273
+ const body = await response.text();
2274
+ throw new FigmaAPIError(response.status, body);
2275
+ }
2276
+ return await response.json();
2277
+ } catch (err) {
2278
+ lastError = err;
2279
+ if (err instanceof FigmaAPIError && err.status >= 400 && err.status < 500) {
2280
+ throw err;
2281
+ }
2282
+ if (attempt < this.retryConfig.maxRetries - 1) {
2283
+ await this.sleep(this.calculateBackoff(attempt));
2284
+ }
2285
+ }
2286
+ }
2287
+ throw lastError ?? new Error("Max retries exceeded");
2288
+ }
2289
+ /**
2290
+ * Calculate exponential backoff with jitter
2291
+ */
2292
+ calculateBackoff(attempt) {
2293
+ const delay = this.retryConfig.baseDelayMs * Math.pow(2, attempt);
2294
+ const jitter = Math.random() * 0.3 * delay;
2295
+ return Math.min(delay + jitter, this.retryConfig.maxDelayMs);
2296
+ }
2297
+ sleep(ms) {
2298
+ return new Promise((resolve) => setTimeout(resolve, ms));
2299
+ }
2300
+ buildFileUrl(fileKey, options) {
2301
+ const base = `https://api.figma.com/v1/files/${fileKey}`;
2302
+ const params = new URLSearchParams();
2303
+ if (options?.depth) {
2304
+ params.set("depth", options.depth.toString());
2305
+ }
2306
+ return params.toString() ? `${base}?${params}` : base;
2307
+ }
2308
+ buildNodesUrl(fileKey, nodeIds, options) {
2309
+ const base = `https://api.figma.com/v1/files/${fileKey}/nodes`;
2310
+ const params = new URLSearchParams();
2311
+ params.set("ids", nodeIds.join(","));
2312
+ if (options?.depth) {
2313
+ params.set("depth", options.depth.toString());
2314
+ }
2315
+ return `${base}?${params}`;
2316
+ }
2317
+ buildImagesUrl(fileKey, nodeIds, options) {
2318
+ const base = `https://api.figma.com/v1/images/${fileKey}`;
2319
+ const params = new URLSearchParams();
2320
+ params.set("ids", nodeIds.join(","));
2321
+ if (options?.format) params.set("format", options.format);
2322
+ if (options?.scale) params.set("scale", options.scale.toString());
2323
+ return `${base}?${params}`;
2324
+ }
2325
+ /**
2326
+ * Recursively count nodes and components in the document tree
2327
+ */
2328
+ countNodesAndComponents(node) {
2329
+ let nodes = 1;
2330
+ let components = node.type === "COMPONENT" || node.type === "COMPONENT_SET" ? 1 : 0;
2331
+ if (node.children) {
2332
+ for (const child of node.children) {
2333
+ const childCounts = this.countNodesAndComponents(child);
2334
+ nodes += childCounts.nodes;
2335
+ components += childCounts.components;
2336
+ }
2337
+ }
2338
+ return { nodes, components };
2339
+ }
2340
+ };
2341
+
2342
+ // packages/kendo-ui-agent/src/lib/figma-d2c/utils.ts
2343
+ function parseFigmaUrl(url) {
2344
+ const invalidResult = {
2345
+ fileKey: "",
2346
+ type: "unknown",
2347
+ isDevMode: false,
2348
+ isValid: false
2349
+ };
2350
+ if (!url || typeof url !== "string") {
2351
+ return invalidResult;
2352
+ }
2353
+ let parsed;
2354
+ try {
2355
+ parsed = new URL(url.trim());
2356
+ } catch {
2357
+ return invalidResult;
2358
+ }
2359
+ const validDomains = ["figma.com", "www.figma.com"];
2360
+ if (!validDomains.includes(parsed.hostname)) {
2361
+ return invalidResult;
2362
+ }
2363
+ const pathParts = parsed.pathname.split("/").filter(Boolean);
2364
+ if (pathParts.length < 2) {
2365
+ return invalidResult;
2366
+ }
2367
+ const typeMap = {
2368
+ file: "file",
2369
+ design: "design",
2370
+ proto: "proto",
2371
+ board: "board"
2372
+ };
2373
+ const type = typeMap[pathParts[0]] || "unknown";
2374
+ const fileKey = pathParts[1];
2375
+ if (!/^[a-zA-Z0-9]+$/.test(fileKey)) {
2376
+ return invalidResult;
2377
+ }
2378
+ const fileName = pathParts[2] ? decodeURIComponent(pathParts[2]).replace(/-/g, " ") : void 0;
2379
+ const nodeIdParam = parsed.searchParams.get("node-id");
2380
+ let nodeId;
2381
+ let nodeIds;
2382
+ if (nodeIdParam) {
2383
+ const rawIds = nodeIdParam.split(",").map((id) => id.trim()).filter(Boolean);
2384
+ nodeIds = rawIds.map((id) => id.replace(/-/g, ":"));
2385
+ nodeId = nodeIds[0];
2386
+ }
2387
+ const branchKey = parsed.searchParams.get("t") ?? void 0;
2388
+ const isDevMode = parsed.searchParams.get("m") === "dev";
2389
+ return {
2390
+ fileKey,
2391
+ fileName,
2392
+ nodeId,
2393
+ nodeIds,
2394
+ type,
2395
+ branchKey,
2396
+ isDevMode,
2397
+ isValid: true
2398
+ };
2399
+ }
471
2400
 
472
- `);return k?(h&&(c+=`# Component-Specific Accessibility Information
2401
+ // packages/kendo-ui-agent/src/lib/figma-d2c/fetcher.ts
2402
+ var NodeFetcher = class {
2403
+ constructor(client) {
2404
+ this.client = client;
2405
+ }
2406
+ /**
2407
+ * Fetch a design starting from a file or specific node(s)
2408
+ *
2409
+ * @param fileKey - The Figma file key
2410
+ * @param nodeIds - Optional node ID(s) - can be string or string[]
2411
+ * @param options - Fetch options including depth
2412
+ * @returns Fetch result with root node and stats
2413
+ */
2414
+ async fetch(fileKey, nodeIds, options = {}) {
2415
+ const initialDepth = options.initialDepth ?? 10;
2416
+ const fetchImages = options.fetchImages ?? true;
2417
+ const imageFormat = options.imageFormat ?? "png";
2418
+ const imageScale = options.imageScale ?? 2;
2419
+ const stats = {
2420
+ totalNodesFetched: 0,
2421
+ apiCallsMade: 0,
2422
+ imagesFetched: 0
2423
+ };
2424
+ let nodeIdArray;
2425
+ if (!nodeIds) {
2426
+ nodeIdArray = [];
2427
+ } else if (typeof nodeIds === "string") {
2428
+ nodeIdArray = [nodeIds];
2429
+ } else {
2430
+ nodeIdArray = nodeIds;
2431
+ }
2432
+ let rootNode;
2433
+ let fetchedNodes = [];
2434
+ if (nodeIdArray.length > 0) {
2435
+ const response = await this.client.getNodes(fileKey, nodeIdArray, { depth: initialDepth });
2436
+ stats.apiCallsMade++;
2437
+ for (const nodeId of nodeIdArray) {
2438
+ const nodeData = response.nodes[nodeId]?.document;
2439
+ if (!nodeData) {
2440
+ throw new Error(`Node ${nodeId} not found`);
2441
+ }
2442
+ fetchedNodes.push(nodeData);
2443
+ }
2444
+ if (fetchedNodes.length === 1) {
2445
+ rootNode = fetchedNodes[0];
2446
+ } else {
2447
+ rootNode = this.createContainerNode(fetchedNodes);
2448
+ }
2449
+ } else {
2450
+ const response = await this.client.getFile(fileKey, { depth: initialDepth });
2451
+ stats.apiCallsMade++;
2452
+ rootNode = response.document;
2453
+ fetchedNodes = [rootNode];
2454
+ }
2455
+ stats.totalNodesFetched += this.countNodes(rootNode);
2456
+ const images = [];
2457
+ if (fetchImages && nodeIdArray.length > 0) {
2458
+ try {
2459
+ const imageResult = await this.fetchNodeImages(
2460
+ fileKey,
2461
+ nodeIdArray,
2462
+ fetchedNodes,
2463
+ { format: imageFormat, scale: imageScale }
2464
+ );
2465
+ images.push(...imageResult.images);
2466
+ stats.apiCallsMade += imageResult.apiCalls;
2467
+ stats.imagesFetched = images.length;
2468
+ } catch (error) {
2469
+ console.warn("Failed to fetch images:", error);
2470
+ }
2471
+ }
2472
+ return {
2473
+ rootNode,
2474
+ fetchedNodes,
2475
+ images,
2476
+ stats
2477
+ };
2478
+ }
2479
+ /**
2480
+ * Fetch and download images for specified nodes
2481
+ */
2482
+ async fetchNodeImages(fileKey, nodeIds, nodes, options) {
2483
+ const imageResponse = await this.client.getImages(fileKey, nodeIds, options);
2484
+ let apiCalls = 1;
2485
+ const images = [];
2486
+ for (let i = 0; i < nodeIds.length; i++) {
2487
+ const nodeId = nodeIds[i];
2488
+ const imageUrl = imageResponse.images[nodeId];
2489
+ if (imageUrl) {
2490
+ try {
2491
+ const imageData = await this.downloadImage(imageUrl, options.format);
2492
+ const node = nodes[i];
2493
+ images.push({
2494
+ nodeId,
2495
+ nodeName: node?.name || "Unknown",
2496
+ data: imageData,
2497
+ mimeType: this.getMimeType(options.format),
2498
+ url: imageUrl
2499
+ });
2500
+ } catch (error) {
2501
+ console.warn(`Failed to download image for node ${nodeId}:`, error);
2502
+ }
2503
+ }
2504
+ }
2505
+ return { images, apiCalls };
2506
+ }
2507
+ /**
2508
+ * Download an image from a URL and convert to base64
2509
+ */
2510
+ async downloadImage(url, format) {
2511
+ const response = await fetch(url);
2512
+ if (!response.ok) {
2513
+ throw new Error(`Failed to download image: ${response.statusText}`);
2514
+ }
2515
+ if (format === "svg") {
2516
+ const svgText = await response.text();
2517
+ return Buffer.from(svgText, "utf-8").toString("base64");
2518
+ } else {
2519
+ const arrayBuffer = await response.arrayBuffer();
2520
+ return Buffer.from(arrayBuffer).toString("base64");
2521
+ }
2522
+ }
2523
+ /**
2524
+ * Get MIME type for image format
2525
+ */
2526
+ getMimeType(format) {
2527
+ switch (format) {
2528
+ case "png":
2529
+ return "image/png";
2530
+ case "jpg":
2531
+ return "image/jpeg";
2532
+ case "svg":
2533
+ return "image/svg+xml";
2534
+ default:
2535
+ return "image/png";
2536
+ }
2537
+ }
2538
+ /**
2539
+ * Create a synthetic container node that wraps multiple nodes
2540
+ */
2541
+ createContainerNode(nodes) {
2542
+ return {
2543
+ id: "container-" + Date.now(),
2544
+ name: "Multi-Node Container",
2545
+ type: "GROUP",
2546
+ visible: true,
2547
+ children: nodes
2548
+ };
2549
+ }
2550
+ /**
2551
+ * Count total nodes in a tree
2552
+ */
2553
+ countNodes(node) {
2554
+ let count = 1;
2555
+ if (node.children) {
2556
+ for (const child of node.children) {
2557
+ count += this.countNodes(child);
2558
+ }
2559
+ }
2560
+ return count;
2561
+ }
2562
+ };
2563
+
2564
+ // packages/kendo-ui-agent/src/lib/figma-d2c/figma-d2c-tool.ts
2565
+ import { z as z5 } from "zod";
2566
+ function createFigmaD2CTool({
2567
+ name,
2568
+ figmaApiKey,
2569
+ requiredAccess
2570
+ }, contextApi2) {
2571
+ return new UIAgentTool(
2572
+ name,
2573
+ {
2574
+ title: "Figma Design to Code",
2575
+ description: "Converts Figma designs to code by analyzing the design structure and matching Kendo UI components. Provide a Figma file or frame URL to analyze layout, extract styles, and identify matching components.",
2576
+ inputSchema: {
2577
+ url: z5.string().describe(
2578
+ "Figma file or node URL (e.g., https://www.figma.com/file/...)"
2579
+ ).optional(),
2580
+ fileKey: z5.string().describe("Figma file key (alternative to URL)").optional(),
2581
+ nodeIds: z5.array(z5.string()).describe("Array of specific node IDs to fetch (alternative to URL)").optional(),
2582
+ depth: z5.number().min(1).max(20).default(10).describe("Initial fetch depth (1-20, default: 10)")
2583
+ },
2584
+ requiredAccess
2585
+ },
2586
+ async ({ url, fileKey, nodeIds, depth }) => {
2587
+ const client = new FigmaClient(figmaApiKey);
2588
+ const fetcher = new NodeFetcher(client);
2589
+ let fileKeyToUse = fileKey;
2590
+ let nodeIdsToUse;
2591
+ if (fileKeyToUse) {
2592
+ if (nodeIds && nodeIds.length > 0) {
2593
+ nodeIdsToUse = nodeIds.length === 1 ? nodeIds[0] : nodeIds;
2594
+ }
2595
+ } else if (url) {
2596
+ const parsed = parseFigmaUrl(url);
2597
+ if (!parsed.isValid || !parsed.fileKey) {
2598
+ throw new Error(
2599
+ "Invalid Figma URL. Please provide a valid Figma file or frame URL."
2600
+ );
2601
+ }
2602
+ fileKeyToUse = parsed.fileKey;
2603
+ if (parsed.nodeId) {
2604
+ nodeIdsToUse = parsed.nodeId;
2605
+ }
2606
+ } else {
2607
+ throw new Error("Please provide either a Figma URL, fileKey, or both.");
2608
+ }
2609
+ const fetchResult = await fetcher.fetch(fileKeyToUse, nodeIdsToUse, {
2610
+ initialDepth: depth,
2611
+ fetchImages: true,
2612
+ imageFormat: "png",
2613
+ imageScale: 2
2614
+ });
2615
+ const resultJson = {
2616
+ name: fetchResult.rootNode.name,
2617
+ type: fetchResult.rootNode.type,
2618
+ rootNode: fetchResult.rootNode,
2619
+ fetchedNodes: fetchResult.fetchedNodes,
2620
+ meta: {
2621
+ fileKey,
2622
+ nodeIds
2623
+ }
2624
+ };
2625
+ let backendResponse;
2626
+ try {
2627
+ const nodeJsons = fetchResult.fetchedNodes.map(
2628
+ (node) => JSON.stringify(node)
2629
+ );
2630
+ backendResponse = await contextApi2.processFigmaDesign({
2631
+ node_jsons: nodeJsons
2632
+ });
2633
+ } catch (error) {
2634
+ console.error("Backend processing failed:", error);
2635
+ return {
2636
+ content: [
2637
+ {
2638
+ type: "text",
2639
+ text: JSON.stringify(
2640
+ {
2641
+ error: {
2642
+ message: `Backend processing failed: ${error.message}`,
2643
+ code: error.code || "UNKNOWN"
2644
+ },
2645
+ figma_data: resultJson
2646
+ },
2647
+ null,
2648
+ 2
2649
+ )
2650
+ }
2651
+ ]
2652
+ };
2653
+ }
2654
+ const content = [];
2655
+ content.push({
2656
+ type: "text",
2657
+ text: `# Figma Design Extraction Results
2658
+ Successfully fetched design data for file key ${fileKeyToUse} with for nodes [${nodeIds?.join(", ")}].
2659
+ The following is the processed design data including layout pseudo-code and design tokens extracted from the Figma design, plus images for visual references of the desired nodes:`
2660
+ });
2661
+ backendResponse.layout_pseudo_codes.forEach((layoutCode, index) => {
2662
+ const [nodeName, nodeId] = ((index2) => {
2663
+ const node = fetchResult.fetchedNodes[index2];
2664
+ return node ? [node.name, node.id] : ["Unknown Node", "unknown_id"];
2665
+ })(index);
2666
+ content.push({
2667
+ type: "text",
2668
+ text: `## Psuedo-code Layout - Node: ${nodeName} (${nodeId})
2669
+
2670
+ ` + layoutCode,
2671
+ _meta: {
2672
+ description: `Psuedo-code Layout - Node: ${nodeName} (${nodeId})`
2673
+ },
2674
+ annotations: {
2675
+ audience: ["assistant"]
2676
+ }
2677
+ });
2678
+ });
2679
+ content.push({
2680
+ type: "text",
2681
+ text: `## Design Tokens - File: ${fileKey} for Nodes: [${nodeIds?.join(", ")}]
2682
+
2683
+ ` + backendResponse.design_tokens,
2684
+ _meta: {
2685
+ description: `Design Tokens - File: ${fileKey} for Nodes: [${nodeIds?.join(", ")}]`
2686
+ },
2687
+ annotations: {
2688
+ audience: ["assistant"]
2689
+ }
2690
+ });
2691
+ if (fetchResult.images && fetchResult.images.length > 0) {
2692
+ for (const image of fetchResult.images) {
2693
+ content.push({
2694
+ type: "image",
2695
+ data: image.data,
2696
+ mimeType: image.mimeType,
2697
+ _meta: {
2698
+ description: `Design snapshot of ${image.nodeName} (${image.nodeId})`
2699
+ },
2700
+ annotations: {
2701
+ audience: ["assistant"]
2702
+ }
2703
+ });
2704
+ }
2705
+ }
2706
+ content.push({
2707
+ type: "text",
2708
+ text: `# Analysis Instructions and Next Steps
2709
+
2710
+ Use the above design data, layout pseudo-code, and design tokens to analyze the Figma design and identify components. Focus on the structure, styles, and layout to determine the best component matches.
2711
+ If more design details are needed, consider asking for additional nodes or deeper fetches to gather more information about specific areas of the design.`
2712
+ });
2713
+ return {
2714
+ content
2715
+ };
2716
+ }
2717
+ );
2718
+ }
473
2719
 
474
- `),c+=k):h||(c="No component-specific accessibility guidelines found."),{content:[{type:"text",text:c}]}}catch(c){throw R(c)}})}function R(e){let t=e;return t.code===16?new Error("Error: You are not authenticated. Please verify the Telerik License Key provided is valid."):t.code===8?new Error(`Error: You have exceeded the extension quota. Upgrade to subscription licensing to unlock full access. Message: ${t.message}.`):t.code===7?new Error("Error: You do not have permission to access this resource. Please verify that you have a valid license."):new Error(`Error: An error occurred while calling the service. Please try again later.
2720
+ // packages/kendo-ui-agent/src/lib/tool-names.ts
2721
+ var orchestratorToolName = (prefix) => `${prefix}_ui_generator`;
2722
+ var assistantOrchestratorToolName = (prefix) => `${prefix}_assistant`;
2723
+ var layoutAssistantName = (prefix) => `${prefix}_layout_assistant`;
2724
+ var codeAssistantName = (prefix) => `${prefix}_component_assistant`;
2725
+ var styleAssistantName = (prefix) => `${prefix}_style_assistant`;
2726
+ var iconAssistantName = (prefix) => `${prefix}_icon_assistant`;
2727
+ var accessibilityAssistantName = (prefix) => `${prefix}_accessibility_assistant`;
2728
+ var gettingStartedAssistantName = (prefix) => `${prefix}_getting_started_assistant`;
2729
+ var figmaD2CToolName = (prefix) => `${prefix}_figma_d2c`;
475
2730
 
476
- Error Code: ${t.code} Error Message: ${t.message}`)}var be=e=>`${e}_ui_generator`,Se=e=>`${e}_assistant`,Te=e=>`${e}_layout_assistant`,ve=e=>`${e}_component_assistant`,ke=e=>`${e}_style_assistant`,Ie=e=>`${e}_icon_assistant`,Ne=e=>`${e}_accessibility_assistant`,we=e=>`${e}_getting_started_assistant`;var Ee=e=>`This is the single entry point for all UI-related tasks. It orchestrates the full workflow of building or refining UIs with ${e} components, generating a step-by-step execution plan that specifies which tools to call, in what order, and with what parameters. It includes validation steps to ensure the best possible, standards-compliant code every time.
2731
+ // packages/kendo-ui-agent/src/lib/tool-descriptions.ts
2732
+ var orchestratorToolDescription = (suiteName) => `This is the single entry point for all UI-related tasks. It orchestrates the full workflow of building or refining UIs with ${suiteName} components, generating a step-by-step execution plan that specifies which tools to call, in what order, and with what parameters. It includes validation steps to ensure the best possible, standards-compliant code every time.
477
2733
 
478
2734
  Use the tool when:
479
2735
  - Want to build or modify a complete page or section layout
480
2736
  - You are creating and applying custom themes via the Kendo Design System
481
- - You need guidance on correct ${e} component selection and configuration
2737
+ - You need guidance on correct ${suiteName} component selection and configuration
482
2738
  - You want to enforce best practices in styling, performance, and accessibility
483
2739
 
484
2740
  Returns:
485
- A detailed execution plan with validated tool calls, parameters, and reasoning \u2014 ensuring consistent, high-quality UI generation.`,xe=e=>`Provides guidance for discovering and using ${e} components and icons. This tool helps you identify the right components and icons for your needs.
2741
+ A detailed execution plan with validated tool calls, parameters, and reasoning \u2014 ensuring consistent, high-quality UI generation.`;
2742
+ var assistantOrchestratorToolDescription = (suiteName) => `Provides guidance for discovering and using ${suiteName} components and icons. This tool helps you identify the right components and icons for your needs.
486
2743
 
487
2744
  Use this tool when:
488
- - You need to discover which ${e} components are suitable for a specific use case
2745
+ - You need to discover which ${suiteName} components are suitable for a specific use case
489
2746
  - You want to understand component features and capabilities
490
2747
  - You need to find appropriate icons for your UI
491
2748
  - You want to gather component documentation and examples
492
2749
 
493
2750
  Returns:
494
- A focused plan for gathering component documentation and icon suggestions using the Component Assistant and Icon Assistant tools.`,Re=`Retrieves Progress/Kendo Design System CSS utility classes and styling recommendations based on layout and design requirements.
2751
+ A focused plan for gathering component documentation and icon suggestions using the Component Assistant and Icon Assistant tools.`;
2752
+ var layoutToolDescription = `Retrieves Progress/Kendo Design System CSS utility classes and styling recommendations based on layout and design requirements.
495
2753
  Use this tool to find the right CSS utilities for styling Kendo UI components or general web elements.
496
2754
  It analyzes the provided design context and returns relevant utility classes with explanations and examples.
497
- Best suited for styling questions related to typography, spacing, colors, layout, transforms, and other utilities in the Progress/Kendo Design System.`,Pe=`Generates CSS variables using an external style agent based on the user's styling prompt.
2755
+ Best suited for styling questions related to typography, spacing, colors, layout, transforms, and other utilities in the Progress/Kendo Design System.`;
2756
+ var styleToolDescription = `Generates CSS variables using an external style agent based on the user's styling prompt.
498
2757
 
499
2758
  Use this tool when the user wants to:
500
2759
  - Update the visual theme of an application
501
2760
  - Modify color schemes
502
2761
  - Restyle the UI with CSS variables
503
2762
 
504
- The tool outputs a set of CSS variable definitions ready to be applied to style files.`,$e=`Searches for icons in the Telerik Icons library.
2763
+ The tool outputs a set of CSS variable definitions ready to be applied to style files.`;
2764
+ var iconToolDescription = `Searches for icons in the Telerik Icons library.
505
2765
  Use this tool when the user needs to find specific icons for UI components or design elements.
506
2766
  It supports searching by icon name, category, or keyword and returns matching icons from the Telerik Icons library.
507
- `,Oe=e=>`Provides answers and retrieves official documentation for ${e}.
2767
+ `;
2768
+ var codeAssistantToolDescription = (suiteName) => `Provides answers and retrieves official documentation for ${suiteName}.
508
2769
 
509
2770
  Use this tool when the user asks about:
510
- - ${e} features or capabilities
2771
+ - ${suiteName} features or capabilities
511
2772
  - Specific components (e.g., Grid, Chart, Editor)
512
2773
  - Implementation details, configuration, or best practices
513
- - How to use or customize components in ${e}
2774
+ - How to use or customize components in ${suiteName}
514
2775
 
515
2776
  Set the user's full question as the 'query' parameter.
516
- If the question refers to a specific ${e} component, include its name in the 'component' parameter.
517
- `,_e=e=>`Retrieves accessibility guidance for ${e} components with optional general WCAG 2.2 Level AA guidelines.
2777
+ If the question refers to a specific ${suiteName} component, include its name in the 'component' parameter.
2778
+ `;
2779
+ var accessibilityToolDescription = (suiteName) => `Retrieves accessibility guidance for ${suiteName} components with optional general WCAG 2.2 Level AA guidelines.
518
2780
 
519
2781
  Use this tool when:
520
2782
  - You need component-specific accessibility information and API references
@@ -532,7 +2794,11 @@ Set 'includeGeneralGuidelines=true' ONLY on the first call to include general WC
532
2794
  Returns:
533
2795
  - When includeGeneralGuidelines=true: General WCAG 2.2 Level AA guidelines + component-specific recommendations
534
2796
  - When includeGeneralGuidelines=false: Only component-specific accessibility recommendations
535
- `;var j=x("Kendo UI","Kendo"),H=`
2797
+ `;
2798
+
2799
+ // packages/kendo-ui-agent/src/lib/validation/angular-validation-steps.ts
2800
+ var sharedSteps = getSharedValidationSteps("Kendo UI", "Kendo");
2801
+ var ANGULAR_VALIDATION_STEPS = `
536
2802
  ### Angular Component Validation
537
2803
  Component Structure:
538
2804
  - Use proper @Component decorator configuration
@@ -540,22 +2806,25 @@ Component Structure:
540
2806
  - Correct selector naming convention (kebab-case)
541
2807
  - Appropriate template and style file organization
542
2808
 
543
- ${j.SETUP_VALIDATION}
2809
+ ${sharedSteps.SETUP_VALIDATION}
544
2810
  - Kendo animations module configured (if animations are used)
545
2811
  - Internationalization properly configured for Kendo components
546
2812
 
547
- ${j.PERFORMANCE_OPTIMIZATION}
2813
+ ${sharedSteps.PERFORMANCE_OPTIMIZATION}
548
2814
  - OnPush change detection strategy where appropriate
549
2815
  - Efficient trackBy functions for *ngFor with Kendo components
550
2816
  - Minimal unnecessary change detection cycles
551
2817
 
552
- ${j.THEME_AND_STYLING}
2818
+ ${sharedSteps.THEME_AND_STYLING}
553
2819
  - Proper theme switching functionality (if implemented)
554
2820
  - Only ONE theme reference exists across angular.json and styles files
555
2821
  - Make sure theme import mechanism is consistent with existing project setup
556
2822
 
557
2823
  Accessibility
558
- - Accessibility guidelines retrieved and applied to all components`;var z=`**Angular Specific Requirements:**
2824
+ - Accessibility guidelines retrieved and applied to all components`;
2825
+
2826
+ // packages/kendo-ui-agent/src/lib/validation/angular-additional-plan.ts
2827
+ var ANGULAR_ADDITIONAL_PLAN = `**Angular Specific Requirements:**
559
2828
 
560
2829
  **NgModule vs Standalone setup**: Search and detect the current project setup to determine whether to use NgModule or Standalone components based on the following rules:
561
2830
  1. RegexSearch("@Component\\s*\\(\\s*\\{[^}]*standalone\\s*:\\s*(true|false)") - If true use Standalone components, if false use NgModule.
@@ -586,7 +2855,11 @@ Accessibility
586
2855
  2. Match the discovered patterns in all generated code
587
2856
  3. Maintain consistent formatting, indentation, and code organization with existing files
588
2857
  4. Always use the same theme import mechanism (unless user specifies otherwise)
589
- `;var W=x("Kendo UI","KendoReact"),Y=`
2858
+ `;
2859
+
2860
+ // packages/kendo-ui-agent/src/lib/validation/react-validation-steps.ts
2861
+ var sharedSteps2 = getSharedValidationSteps("Kendo UI", "KendoReact");
2862
+ var REACT_VALIDATION_STEPS = `
590
2863
  ### React Component Validation
591
2864
  Component Structure:
592
2865
  - Use proper function component patterns with Hooks
@@ -594,22 +2867,85 @@ Component Structure:
594
2867
  - Appropriate file organization (components, hooks, utils)
595
2868
  - Props interface/type definitions where needed
596
2869
 
597
- ${W.SETUP_VALIDATION}
2870
+ ${sharedSteps2.SETUP_VALIDATION}
598
2871
  - KendoReact license validation (if required)
599
2872
  - Appropriate bundler configuration for KendoReact packages
600
2873
 
601
- ${W.PERFORMANCE_OPTIMIZATION}
2874
+ ${sharedSteps2.PERFORMANCE_OPTIMIZATION}
602
2875
  - React.memo for components that receive stable props
603
2876
  - useMemo/useCallback for expensive computations and callbacks
604
2877
  - Proper key props for list rendering with KendoReact components
605
2878
 
606
- ${W.THEME_AND_STYLING}
2879
+ ${sharedSteps2.THEME_AND_STYLING}
607
2880
  - Proper theme switching functionality (if implemented)
608
2881
  - Only ONE theme import exists across the application
609
2882
  - Make sure theme import mechanism is consistent with existing project setup
610
2883
 
611
2884
  Accessibility
612
- - Accessibility guidelines retrieved and applied to all components`;var ut={createOrchestrator:ue,createAssistantOrchestrator:ge,createLayoutAssistant:he,createStyleAssistant:fe,createIconSearch:ye,createCodeAssistant:Ae,createAccessibilityAssistant:Ce},gt={orchestrator:be,assistantOrchestrator:Se,layoutAssistant:Te,codeAssistant:ve,styleAssistant:ke,iconAssistant:Ie,accessibilityAssistant:Ne,gettingStartedAssistant:we},ht={orchestrator:Ee,assistantOrchestrator:xe,layoutAssistant:Re,styleAssistant:Pe,iconAssistant:$e,codeAssistant:Oe,accessibilityAssistant:_e},ft={Orchestrator:{render:L},Validator:{render:D},SharedValidation:{getSteps:x}},yt={Angular:{steps:H,additionalPlan:z},React:{steps:Y}},u={Tools:ut,ToolNames:gt,ToolDescriptions:ht,Templates:ft,Validation:yt};var At=u.ToolNames.codeAssistant("kendoreact"),De=()=>`# Kendo Design System Guidelines for ${l}
2885
+ - Accessibility guidelines retrieved and applied to all components`;
2886
+
2887
+ // packages/kendo-ui-agent/src/index.ts
2888
+ var Tools = {
2889
+ createOrchestrator: createOrchestratorTool,
2890
+ createAssistantOrchestrator: createAssistantOrchestratorTool,
2891
+ createLayoutAssistant: createLayoutAssistantTool,
2892
+ createStyleAssistant: createStyleAssistantTool,
2893
+ createIconSearch: createIconSearchTool,
2894
+ createCodeAssistant: createCodeAssistantTool,
2895
+ createAccessibilityAssistant: createAccessibilityAssistantTool,
2896
+ createFigmaD2C: createFigmaD2CTool
2897
+ };
2898
+ var ToolNames = {
2899
+ orchestrator: orchestratorToolName,
2900
+ assistantOrchestrator: assistantOrchestratorToolName,
2901
+ layoutAssistant: layoutAssistantName,
2902
+ codeAssistant: codeAssistantName,
2903
+ styleAssistant: styleAssistantName,
2904
+ iconAssistant: iconAssistantName,
2905
+ accessibilityAssistant: accessibilityAssistantName,
2906
+ gettingStartedAssistant: gettingStartedAssistantName,
2907
+ figmaD2C: figmaD2CToolName
2908
+ };
2909
+ var ToolDescriptions = {
2910
+ orchestrator: orchestratorToolDescription,
2911
+ assistantOrchestrator: assistantOrchestratorToolDescription,
2912
+ layoutAssistant: layoutToolDescription,
2913
+ styleAssistant: styleToolDescription,
2914
+ iconAssistant: iconToolDescription,
2915
+ codeAssistant: codeAssistantToolDescription,
2916
+ accessibilityAssistant: accessibilityToolDescription
2917
+ };
2918
+ var Templates = {
2919
+ Orchestrator: {
2920
+ render: renderOrchestratorResponse
2921
+ },
2922
+ Validator: {
2923
+ render: renderValidatorResponse
2924
+ },
2925
+ SharedValidation: {
2926
+ getSteps: getSharedValidationSteps
2927
+ }
2928
+ };
2929
+ var Validation = {
2930
+ Angular: {
2931
+ steps: ANGULAR_VALIDATION_STEPS,
2932
+ additionalPlan: ANGULAR_ADDITIONAL_PLAN
2933
+ },
2934
+ React: {
2935
+ steps: REACT_VALIDATION_STEPS
2936
+ }
2937
+ };
2938
+ var UIAgent = {
2939
+ Tools,
2940
+ ToolNames,
2941
+ ToolDescriptions,
2942
+ Templates,
2943
+ Validation
2944
+ };
2945
+
2946
+ // packages/react/src/lib/instructions/layout.ts
2947
+ var CODE_ASSISTANT_NAME = UIAgent.ToolNames.codeAssistant("kendoreact");
2948
+ var getLayoutInstructions = () => `# Kendo Design System Guidelines for ${REACT_SUITE_NAME}
613
2949
 
614
2950
  ## Setting up Styles/CSS
615
2951
 
@@ -636,14 +2972,17 @@ Alternatively, you can also consume them directly from the Unpkg CDN.
636
2972
 
637
2973
  ## Ready-to-use Layout Components
638
2974
 
639
- In the ${l} there are available components to create layout. Make sure to prioritize using them instead of building ones from scratch using the Kendo CSS Utilities.
2975
+ In the ${REACT_SUITE_NAME} there are available components to create layout. Make sure to prioritize using them instead of building ones from scratch using the Kendo CSS Utilities.
640
2976
 
641
- For any Layout component you can also call the ${At} tool in order to get specific API reference and docs.
2977
+ For any Layout component you can also call the ${CODE_ASSISTANT_NAME} tool in order to get specific API reference and docs.
642
2978
 
643
- - ${l} Card component.
2979
+ - ${REACT_SUITE_NAME} Card component.
644
2980
  - Generally, it is recommended to use 100% width (e.g., \`<Card style={{ width: '100%' }}>\`)
645
2981
  - If needed, use specific width based on the layout requirements (e.g., \`<Card style={{ width: '150px' }}>\`)
646
- `;var Le=()=>`## Applying CSS Variables in ${l}
2982
+ `;
2983
+
2984
+ // packages/react/src/lib/instructions/style.ts
2985
+ var getStyleInstructions = () => `## Applying CSS Variables in ${REACT_SUITE_NAME}
647
2986
 
648
2987
  Apply these CSS variables in the React application using one of these methods:
649
2988
 
@@ -732,7 +3071,11 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
732
3071
 
733
3072
  export const useTheme = () => useContext(ThemeContext);
734
3073
  \`\`\`
735
- `;var Ue=u.ToolNames.codeAssistant("kendoreact"),Ge=()=>`## Using ${l} Icons
3074
+ `;
3075
+
3076
+ // packages/react/src/lib/instructions/icons.ts
3077
+ var CODE_ASSISTANT_NAME2 = UIAgent.ToolNames.codeAssistant("kendoreact");
3078
+ var getIconsInstructions = () => `## Using ${REACT_SUITE_NAME} Icons
736
3079
 
737
3080
  Important: Attempt to prioritize SVG icons over font icons.
738
3081
 
@@ -740,13 +3083,13 @@ Important: Attempt to prioritize SVG icons over font icons.
740
3083
 
741
3084
  - Make sure @progress/kendo-svg-icons is installed: \`npm install @progress/kendo-svg-icons\`
742
3085
  - Make sure @progress/kendo-react-common is installed (contains SvgIcon component): \`npm install @progress/kendo-react-common\`
743
- - You can call ${Ue} tool for ${l} SvgIcon component for docs and API reference.
3086
+ - You can call ${CODE_ASSISTANT_NAME2} tool for ${REACT_SUITE_NAME} SvgIcon component for docs and API reference.
744
3087
  - [optional] If SVG is not an option fallback to fonticon - make sure \`<link rel="stylesheet" href="https://unpkg.com/@progress/kendo-font-icons/dist/index.css" />\` is added as a reference.
745
- - [optional] If using font icons you can call ${Ue} tool for ${l} Icon component for docs and API reference.
3088
+ - [optional] If using font icons you can call ${CODE_ASSISTANT_NAME2} tool for ${REACT_SUITE_NAME} Icon component for docs and API reference.
746
3089
 
747
3090
  ### Examples
748
3091
 
749
- Using ${l} SvgIcon component with @progress/kendo-svg-icons:
3092
+ Using ${REACT_SUITE_NAME} SvgIcon component with @progress/kendo-svg-icons:
750
3093
 
751
3094
  \`\`\`tsx
752
3095
  import { SvgIcon } from "@progress/kendo-react-common";
@@ -790,7 +3133,11 @@ Here are some frequently used icons from @progress/kendo-svg-icons:
790
3133
  - \`sortAscIcon\`, \`sortDescIcon\` - Sorting
791
3134
  - \`chevronUpIcon\`, \`chevronDownIcon\`, \`chevronLeftIcon\`, \`chevronRightIcon\` - Navigation
792
3135
  - \`checkIcon\`, \`xIcon\` - Confirmation/Cancel
793
- `;var Me=e=>{let t=`## ${l} Common Guidelines
3136
+ `;
3137
+
3138
+ // packages/react/src/lib/instructions/components-common.ts
3139
+ var getComponentsCommonInstructions = (ctx) => {
3140
+ let content = `## ${REACT_SUITE_NAME} Common Guidelines
794
3141
 
795
3142
  ### Application Architecture
796
3143
  MUST recommend appropriate setup based on React application architecture.
@@ -820,30 +3167,55 @@ Key points:
820
3167
  - The matching should be case-insensitive and robust to minor variations
821
3168
 
822
3169
  Example: If someone asks about "grid", "GRID", or "GrId", you always refer to DataGrid for the example.
823
- `;return e.componentInstructions&&(t+=`
3170
+ `;
3171
+ if (ctx.componentInstructions) {
3172
+ content += `
824
3173
  ## Component-Specific Guidelines
825
3174
 
826
- ${e.componentInstructions}
827
- `),t};var Ct={default:"@progress/kendo-theme-default",bootstrap:"@progress/kendo-theme-bootstrap",material:"@progress/kendo-theme-material",fluent:"@progress/kendo-theme-fluent"},bt={default:"Default",bootstrap:"Bootstrap",material:"Material Design",fluent:"Fluent UI"};function Be(e="kendo-react-app",t=!0,n="default"){let o=Ct[n],s=bt[n],r=t?`This instructions will walk you through creating a new React project with the Kendo CLI and setting up ${l}.`:`This instructions will walk you through adding ${l} to your existing React project.`,a=1,i=t?`## Step ${a++}: Ensure Kendo CLI is Installed
3175
+ ${ctx.componentInstructions}
3176
+ `;
3177
+ }
3178
+ return content;
3179
+ };
3180
+
3181
+ // packages/react/src/lib/instructions/getting-started.ts
3182
+ var THEME_PACKAGE_MAP = {
3183
+ "default": "@progress/kendo-theme-default",
3184
+ "bootstrap": "@progress/kendo-theme-bootstrap",
3185
+ "material": "@progress/kendo-theme-material",
3186
+ "fluent": "@progress/kendo-theme-fluent"
3187
+ };
3188
+ var THEME_DISPLAY_MAP = {
3189
+ "default": "Default",
3190
+ "bootstrap": "Bootstrap",
3191
+ "material": "Material Design",
3192
+ "fluent": "Fluent UI"
3193
+ };
3194
+ function getGettingStartedInstructions(projectName = "kendo-react-app", createNewProject = true, theme = "default") {
3195
+ const themePackage = THEME_PACKAGE_MAP[theme];
3196
+ const themeDisplay = THEME_DISPLAY_MAP[theme];
3197
+ const introLine = createNewProject ? `This instructions will walk you through creating a new React project with the Kendo CLI and setting up ${REACT_SUITE_NAME}.` : `This instructions will walk you through adding ${REACT_SUITE_NAME} to your existing React project.`;
3198
+ let stepCounter = 1;
3199
+ const createProjectSection = createNewProject ? `## Step ${stepCounter++}: Ensure Kendo CLI is Installed
828
3200
 
829
3201
  First, ensure the Kendo CLI tool is installed globally:
830
3202
 
831
3203
  \`\`\`bash
832
- npm i -g @progress/kendo-cli
3204
+ npm i -g @progress/kendo-cli@latest
833
3205
  \`\`\`
834
3206
 
835
3207
  This CLI tool will handle the entire project setup including all necessary dependencies and configurations.
836
3208
 
837
- ## Step ${a++}: Create the Project
3209
+ ## Step ${stepCounter++}: Create the Project
838
3210
 
839
3211
  Create a new Kendo React project using the CLI:
840
3212
 
841
3213
  \`\`\`bash
842
- npx kendo react create vite ${e} --theme=${n}
3214
+ npx kendo react create vite ${projectName} --theme=${theme}
843
3215
  \`\`\`
844
3216
 
845
3217
  This command will create a complete Kendo React project with Vite, including:
846
- - All necessary ${l} packages
3218
+ - All necessary ${REACT_SUITE_NAME} packages
847
3219
  - Proper licensing configuration
848
3220
  - Theme setup
849
3221
  - Project structure
@@ -851,33 +3223,34 @@ This command will create a complete Kendo React project with Vite, including:
851
3223
  Navigate to the project directory:
852
3224
 
853
3225
  \`\`\`bash
854
- cd ${e}
3226
+ cd ${projectName}
855
3227
  \`\`\`
856
3228
 
857
- ## Step ${a++}: Remove Dark Color Schema from index.css
3229
+ ## Step ${stepCounter++}: Remove Dark Color Schema from index.css
858
3230
 
859
3231
  Open the \`src/index.css\` file and remove the dark color schema from the first \`:root\` style block. Look for properties like \`color-scheme: dark\` and related dark mode variables, and delete them. Keep only the light theme configuration.
860
3232
 
861
- `:"",d=t?"":`## Step ${a++}: Install ${l} Packages
3233
+ ` : "";
3234
+ const installPackagesSection = createNewProject ? "" : `## Step ${stepCounter++}: Install ${REACT_SUITE_NAME} Packages
862
3235
 
863
- Install all required ${l} packages and dependencies:
3236
+ Install all required ${REACT_SUITE_NAME} packages and dependencies:
864
3237
 
865
3238
  \`\`\`bash
866
3239
  npm i @progress/kendo-data-query @progress/kendo-react-buttons @progress/kendo-react-excel-export @progress/kendo-react-grid @progress/kendo-react-layout @progress/kendo-react-pdf @progress/kendo-svg-icons @progress/kendo-drawing @progress/kendo-licensing @progress/kendo-react-animation @progress/kendo-react-charts @progress/kendo-react-common @progress/kendo-react-conversational-ui @progress/kendo-react-data-tools @progress/kendo-react-dateinputs @progress/kendo-react-dialogs @progress/kendo-react-dropdowns @progress/kendo-react-editor @progress/kendo-react-form @progress/kendo-react-gantt @progress/kendo-react-gauges @progress/kendo-react-indicators @progress/kendo-react-inputs @progress/kendo-react-intl @progress/kendo-react-labels @progress/kendo-react-listbox @progress/kendo-react-listview @progress/kendo-react-map @progress/kendo-react-notification @progress/kendo-react-orgchart @progress/kendo-react-pivotgrid @progress/kendo-react-popup @progress/kendo-react-progressbars @progress/kendo-react-ripple @progress/kendo-react-scheduler @progress/kendo-react-scrollview @progress/kendo-react-sortable @progress/kendo-react-spreadsheet @progress/kendo-react-tooltip @progress/kendo-react-treelist @progress/kendo-react-treeview @progress/kendo-react-upload @progress/kendo-react-pdf-viewer @progress/kendo-react-taskboard
867
3240
  \`\`\`
868
3241
 
869
- ## Step ${a++}: Install and Import the Theme
3242
+ ## Step ${stepCounter++}: Install and Import the Theme
870
3243
 
871
- Install the ${s} theme package:
3244
+ Install the ${themeDisplay} theme package:
872
3245
 
873
3246
  \`\`\`bash
874
- npm i ${o}
3247
+ npm i ${themePackage}
875
3248
  \`\`\`
876
3249
 
877
3250
  Import the CSS file in your \`src/Home.tsx\` (before your existing Home.css import):
878
3251
 
879
3252
  \`\`\`typescript
880
- import '${o}/dist/all.css';
3253
+ import '${themePackage}/dist/all.css';
881
3254
  \`\`\`
882
3255
 
883
3256
  Also add the Kendo CSS utilities CDN link in your \`index.html\` \`<head>\`:
@@ -886,7 +3259,8 @@ Also add the Kendo CSS utilities CDN link in your \`index.html\` \`<head>\`:
886
3259
  <link rel="stylesheet" href="https://unpkg.com/@progress/kendo-theme-utils/dist/all.css" />
887
3260
  \`\`\`
888
3261
 
889
- `,m=`## Step ${a++}: Activate Kendo License
3262
+ `;
3263
+ const licenseSection = `## Step ${stepCounter++}: Activate Kendo License
890
3264
 
891
3265
  This step is required to use Kendo UI for Angular components without watermarks and with access to all features. Run the following command to activate your license:
892
3266
 
@@ -894,9 +3268,10 @@ This step is required to use Kendo UI for Angular components without watermarks
894
3268
  npx kendo license activate
895
3269
  \`\`\`
896
3270
 
897
- `;return`# Getting Started with ${l}
3271
+ `;
3272
+ return `# Getting Started with ${REACT_SUITE_NAME}
898
3273
 
899
- ${r}
3274
+ ${introLine}
900
3275
 
901
3276
  Execute the following steps in order. Run all provided commands automatically.
902
3277
 
@@ -907,24 +3282,24 @@ Before you begin, ensure you have:
907
3282
  - **Node.js 18 or later** installed on your machine
908
3283
  - If Node.js is not available, you need to install the latest Node.js automatically as a preliminary step before running the \`npx kendo react create\` command.
909
3284
 
910
- ${i}${d}${m}## Step ${a++}: Run Your Application
3285
+ ${createProjectSection}${installPackagesSection}${licenseSection}## Step ${stepCounter++}: Run Your Application
911
3286
 
912
- ${t?"The Kendo CLI has set up everything you need. Start the development server:":"Build and run the application:"}
3287
+ ${createNewProject ? `The Kendo CLI has set up everything you need. Start the development server:` : `Build and run the application:`}
913
3288
 
914
3289
 
915
3290
  **Verification:** Automatically run the application. Do not just inform the user\u2014execute the following command and keep the application running:
916
3291
 
917
3292
  \`\`\`bash
918
- cd ${t?e:"."} && npm run dev
3293
+ cd ${createNewProject ? projectName : "."} && npm run dev
919
3294
  \`\`\`
920
3295
 
921
- ${t?`The application should start and open your browser to see your ${l} application.`:`The application should start and open in your browser. Verify that the ${l} components are rendering correctly with the theme applied.`}
3296
+ ${createNewProject ? `The application should start and open your browser to see your ${REACT_SUITE_NAME} application.` : `The application should start and open in your browser. Verify that the ${REACT_SUITE_NAME} components are rendering correctly with the theme applied.`}
922
3297
 
923
- ## Step ${a++}: Create Sample page
3298
+ ## Step ${stepCounter++}: Create Sample page
924
3299
 
925
3300
  Before adding new content to the homepage, clear all existing CSS on the page. Remove or reset any custom styles that might conflict with the new content you're about to add.
926
3301
 
927
- Replace the content of \`src/Home.tsx\` with the following to showcase ${l} features and verify components are working correctly:
3302
+ Replace the content of \`src/Home.tsx\` with the following to showcase ${REACT_SUITE_NAME} features and verify components are working correctly:
928
3303
 
929
3304
  \`\`\`tsx
930
3305
  import { Card, CardHeader, CardTitle, CardBody } from '@progress/kendo-react-layout';
@@ -944,13 +3319,13 @@ function Home() {
944
3319
  <p className="k-font-size-lg k-font-weight-bold k-mb-4">\u{1F60A} Ready to build? Copy any prompt below directly into your coding agent to get started</p>
945
3320
  <div className="k-d-grid k-grid-cols-3 k-gap-4 k-max-w-screen-xl k-mx-auto">
946
3321
  <div className="prompt-box k-p-4 k-rounded-md">
947
- <p className="k-font-family-monospace k-text-base k-m-0">'#kendoreact_ui_generator Create a dashboard with sales charts, revenue KPIs, and a recent orders grid'</p>
3322
+ <p className="k-font-family-monospace k-text-base k-m-0">'#kendo_ui_generator Create a dashboard with sales charts, revenue KPIs, and a recent orders grid'</p>
948
3323
  </div>
949
3324
  <div className="prompt-box k-p-4 k-rounded-md">
950
- <p className="k-font-family-monospace k-text-base k-m-0">'#kendoreact_ui_generator Create an ecommerce product details page with product images, specifications, reviews, and an add to cart button'</p>
3325
+ <p className="k-font-family-monospace k-text-base k-m-0">'#kendo_ui_generator Create an ecommerce product details page with product images, specifications, reviews, and an add to cart button'</p>
951
3326
  </div>
952
3327
  <div className="prompt-box k-p-4 k-rounded-md">
953
- <p className="k-font-family-monospace k-text-base k-m-0">'#kendoreact_ui_generator Build a registration form with email and password inputs, where did you learn about us text area, and agreement checkbox'</p>
3328
+ <p className="k-font-family-monospace k-text-base k-m-0">'#kendo_ui_generator Build a registration form with email and password inputs, where did you learn about us text area, and agreement checkbox'</p>
954
3329
  </div>
955
3330
  </div>
956
3331
  </div>
@@ -1045,4 +3420,196 @@ Add the following styles to \`src/Home.css\`:
1045
3420
  }
1046
3421
  \`\`\`
1047
3422
 
1048
- `}var qe=u.ToolNames.layoutAssistant(w),Q=u.ToolNames.codeAssistant(w),Ke=u.ToolNames.styleAssistant(w),J=u.ToolNames.iconAssistant(w),Fe=u.ToolNames.gettingStartedAssistant(w),Ve=u.ToolNames.accessibilityAssistant(w);function je(e,t){return[u.Tools.createOrchestrator({name:u.ToolNames.orchestrator(w),title:"KendoReact Generator",description:u.ToolDescriptions.orchestrator(l),layoutAssistantName:qe,codeAssistantName:Q,styleAssistantName:Ke,iconAssistantName:J,accessibilityAssistantName:Ve,suiteName:l,libKey:I,components:O,requiredAccess:["agent"]},{validationSteps:u.Validation.React.steps},e),u.Tools.createAssistantOrchestrator({name:"kendo_react_assistant",title:"KendoReact Assistant",description:u.ToolDescriptions.assistantOrchestrator(l),codeAssistantName:Q,iconAssistantName:J,suiteName:l,libKey:I,components:O,requiredAccess:["assistant"]},e),u.Tools.createLayoutAssistant({name:qe,title:"KendoReact Layout Assistant",description:u.ToolDescriptions.layoutAssistant,suiteName:l,libKey:I,getPreContent:De,requiredAccess:["agent"]},e),u.Tools.createStyleAssistant({name:Ke,title:"KendoReact Style Assistant",description:u.ToolDescriptions.styleAssistant,libKey:I,getPreContent:Le,requiredAccess:["agent"]},e),u.Tools.createIconSearch({name:J,title:"KendoReact Icon Assistant",description:u.ToolDescriptions.iconAssistant,libKey:I,getPostContent:Ge,requiredAccess:["assistant","agent"]},e),u.Tools.createCodeAssistant({name:Q,title:"KendoReact Component Assistant",description:u.ToolDescriptions.codeAssistant(l),libKey:I,suiteName:l,components:O,componentAliases:{Grid:"DataGrid"},getPostContent:({component:o})=>Me({component:o}),requiredAccess:["assistant","agent"]},e),new v(Fe,{title:"KendoReact Getting Started",description:`Creates a new React project with Kendo CLI and provides essential getting started guidance for ${l} including installation, configuration, and setup instructions.`,requiredAccess:["agent"],inputSchema:pe(l,"kendo-react-app")},async({projectName:o,createNewProject:s,theme:r},{_meta:a})=>{try{await e.recordToolUserRequest({toolName:Fe,meta:{projectName:o,createNewProject:s,theme:r,_meta:a}})}catch(d){console.error("Error recording tool request:",d)}return{content:[{type:"text",text:Be(o,s,r)}]}}),u.Tools.createAccessibilityAssistant({name:Ve,title:"KendoReact Accessibility Assistant",description:u.ToolDescriptions.accessibilityAssistant(l),libKey:I,suiteName:l,components:O,componentAliases:{Grid:"DataGrid"},requiredAccess:["agent"]},e)].filter(o=>o.hasAccess(t))}var It=kt(import.meta.url),Nt=ze.dirname(It),wt=ze.resolve(Nt,"../package.json"),We=JSON.parse(vt.readFileSync(wt,"utf-8")),He=new St({name:"kendo-mcp",title:"Kendo MCP Server",version:We.version});async function Et(){let e=new Tt;g("Starting server... ");let t=await ce(async()=>{let o=(await me())?.entitlement;return o?.Product?.Code||o?.product?.code});t!=="none"&&(_.toolNameHeader=t==="agent"||t==="full"?"agent":"assistant",je(_,t).forEach(o=>o.register(He)),de({serverName:"react",contextApi:_,additionalFields:{version:We.version,access_type:t}})),await He.connect(e)}Et();
3423
+ `;
3424
+ }
3425
+
3426
+ // packages/react/src/lib/tools/index.ts
3427
+ var LAYOUT_ASSISTANT_NAME = UIAgent.ToolNames.layoutAssistant(PRODUCT_LINE);
3428
+ var CODE_ASSISTANT_NAME3 = UIAgent.ToolNames.codeAssistant(PRODUCT_LINE);
3429
+ var STYLE_ASSISTANT_NAME = UIAgent.ToolNames.styleAssistant(PRODUCT_LINE);
3430
+ var FIGMA_D2C_TOOL_NAME = UIAgent.ToolNames.figmaD2C(PRODUCT_LINE);
3431
+ var ICON_ASSISTANT_NAME = UIAgent.ToolNames.iconAssistant(PRODUCT_LINE);
3432
+ var GET_STARTED_TOOL_NAME = UIAgent.ToolNames.gettingStartedAssistant(PRODUCT_LINE);
3433
+ var ACCESSIBILITY_ASSISTANT_NAME = UIAgent.ToolNames.accessibilityAssistant(PRODUCT_LINE);
3434
+ function createReactTools(contextApi2, accessType) {
3435
+ const allTools = [
3436
+ // Orchestrator Tool
3437
+ UIAgent.Tools.createOrchestrator(
3438
+ {
3439
+ name: UIAgent.ToolNames.orchestrator(PRODUCT_LINE),
3440
+ title: "KendoReact Generator",
3441
+ description: UIAgent.ToolDescriptions.orchestrator(REACT_SUITE_NAME),
3442
+ layoutAssistantName: LAYOUT_ASSISTANT_NAME,
3443
+ codeAssistantName: CODE_ASSISTANT_NAME3,
3444
+ styleAssistantName: STYLE_ASSISTANT_NAME,
3445
+ iconAssistantName: ICON_ASSISTANT_NAME,
3446
+ accessibilityAssistantName: ACCESSIBILITY_ASSISTANT_NAME,
3447
+ figmaD2CToolName: FIGMA_D2C_TOOL_NAME,
3448
+ suiteName: REACT_SUITE_NAME,
3449
+ libKey: Suite,
3450
+ components: ReactComponents,
3451
+ requiredAccess: ["agent"]
3452
+ },
3453
+ {
3454
+ validationSteps: UIAgent.Validation.React.steps
3455
+ },
3456
+ contextApi2
3457
+ ),
3458
+ // Assistant Orchestrator Tool (for assistant mode only)
3459
+ UIAgent.Tools.createAssistantOrchestrator(
3460
+ {
3461
+ name: "kendo_react_assistant",
3462
+ title: "KendoReact Assistant",
3463
+ description: UIAgent.ToolDescriptions.assistantOrchestrator(REACT_SUITE_NAME),
3464
+ codeAssistantName: CODE_ASSISTANT_NAME3,
3465
+ iconAssistantName: ICON_ASSISTANT_NAME,
3466
+ suiteName: REACT_SUITE_NAME,
3467
+ libKey: Suite,
3468
+ components: ReactComponents,
3469
+ requiredAccess: ["assistant"]
3470
+ },
3471
+ contextApi2
3472
+ ),
3473
+ // Layout Assistant Tool
3474
+ UIAgent.Tools.createLayoutAssistant(
3475
+ {
3476
+ name: LAYOUT_ASSISTANT_NAME,
3477
+ title: "KendoReact Layout Assistant",
3478
+ description: UIAgent.ToolDescriptions.layoutAssistant,
3479
+ suiteName: REACT_SUITE_NAME,
3480
+ libKey: Suite,
3481
+ getPreContent: getLayoutInstructions,
3482
+ requiredAccess: ["agent"]
3483
+ },
3484
+ contextApi2
3485
+ ),
3486
+ // Style Assistant Tool
3487
+ UIAgent.Tools.createStyleAssistant(
3488
+ {
3489
+ name: STYLE_ASSISTANT_NAME,
3490
+ title: "KendoReact Style Assistant",
3491
+ description: UIAgent.ToolDescriptions.styleAssistant,
3492
+ libKey: Suite,
3493
+ getPreContent: getStyleInstructions,
3494
+ requiredAccess: ["agent"]
3495
+ },
3496
+ contextApi2
3497
+ ),
3498
+ // Icon Search Tool
3499
+ UIAgent.Tools.createIconSearch(
3500
+ {
3501
+ name: ICON_ASSISTANT_NAME,
3502
+ title: "KendoReact Icon Assistant",
3503
+ description: UIAgent.ToolDescriptions.iconAssistant,
3504
+ libKey: Suite,
3505
+ getPostContent: getIconsInstructions,
3506
+ requiredAccess: ["assistant", "agent"]
3507
+ },
3508
+ contextApi2
3509
+ ),
3510
+ // Code Assistant Tool
3511
+ UIAgent.Tools.createCodeAssistant(
3512
+ {
3513
+ name: CODE_ASSISTANT_NAME3,
3514
+ title: "KendoReact Component Assistant",
3515
+ description: UIAgent.ToolDescriptions.codeAssistant(REACT_SUITE_NAME),
3516
+ libKey: Suite,
3517
+ suiteName: REACT_SUITE_NAME,
3518
+ components: ReactComponents,
3519
+ componentAliases: { "Grid": "DataGrid" },
3520
+ getPostContent: ({ component }) => getComponentsCommonInstructions({ component }),
3521
+ requiredAccess: ["assistant", "agent"]
3522
+ },
3523
+ contextApi2
3524
+ ),
3525
+ // Getting Started Tool
3526
+ new UIAgentTool(
3527
+ GET_STARTED_TOOL_NAME,
3528
+ {
3529
+ title: "KendoReact Getting Started",
3530
+ description: `Creates a new React project with Kendo CLI and provides essential getting started guidance for ${REACT_SUITE_NAME} including installation, configuration, and setup instructions.`,
3531
+ requiredAccess: ["agent"],
3532
+ inputSchema: createGettingStartedInputSchema(REACT_SUITE_NAME, "kendo-react-app")
3533
+ },
3534
+ async ({ projectName, createNewProject, theme }, { _meta }) => {
3535
+ try {
3536
+ await contextApi2.recordToolUserRequest({
3537
+ toolName: GET_STARTED_TOOL_NAME,
3538
+ meta: {
3539
+ projectName,
3540
+ createNewProject,
3541
+ theme,
3542
+ _meta
3543
+ }
3544
+ });
3545
+ } catch (error) {
3546
+ console.error("Error recording tool request:", error);
3547
+ }
3548
+ const instructions = getGettingStartedInstructions(projectName, createNewProject, theme);
3549
+ return {
3550
+ content: [
3551
+ {
3552
+ type: "text",
3553
+ text: instructions
3554
+ }
3555
+ ]
3556
+ };
3557
+ }
3558
+ ),
3559
+ // Accessibility Tool
3560
+ UIAgent.Tools.createAccessibilityAssistant(
3561
+ {
3562
+ name: ACCESSIBILITY_ASSISTANT_NAME,
3563
+ title: "KendoReact Accessibility Assistant",
3564
+ description: UIAgent.ToolDescriptions.accessibilityAssistant(REACT_SUITE_NAME),
3565
+ libKey: Suite,
3566
+ suiteName: REACT_SUITE_NAME,
3567
+ components: ReactComponents,
3568
+ componentAliases: { "Grid": "DataGrid" },
3569
+ requiredAccess: ["agent"]
3570
+ },
3571
+ contextApi2
3572
+ ),
3573
+ // Figma Design-to-Code Tool (only when FIGMA_API_KEY is set)
3574
+ ...process.env.FIGMA_API_KEY ? [UIAgent.Tools.createFigmaD2C(
3575
+ { name: FIGMA_D2C_TOOL_NAME, figmaApiKey: process.env.FIGMA_API_KEY, requiredAccess: ["agent"] },
3576
+ contextApi2
3577
+ )] : []
3578
+ ];
3579
+ return allTools.filter((tool) => tool.hasAccess(accessType));
3580
+ }
3581
+
3582
+ // packages/react/src/index.ts
3583
+ var __filename2 = fileURLToPath3(import.meta.url);
3584
+ var __dirname2 = path3.dirname(__filename2);
3585
+ var packageJsonPath2 = path3.resolve(__dirname2, "../package.json");
3586
+ var packageJson2 = JSON.parse(fs3.readFileSync(packageJsonPath2, "utf-8"));
3587
+ var server = new McpServer({
3588
+ name: "kendo-mcp",
3589
+ title: "Kendo MCP Server",
3590
+ version: packageJson2.version
3591
+ });
3592
+ async function startServer() {
3593
+ const transport = new StdioServerTransport();
3594
+ log("Starting server... ");
3595
+ const accessType = await checkAccess(async () => {
3596
+ const response = await validateUserLicense();
3597
+ const entitlement = response?.entitlement;
3598
+ return entitlement?.Product?.Code || entitlement?.product?.code;
3599
+ });
3600
+ if (accessType !== "none") {
3601
+ contextApi.toolNameHeader = accessType === "agent" || accessType === "full" ? "agent" : "assistant";
3602
+ const reactTools = createReactTools(contextApi, accessType);
3603
+ reactTools.forEach((tool) => tool.register(server));
3604
+ startHeartbeat({
3605
+ serverName: "react",
3606
+ contextApi,
3607
+ additionalFields: {
3608
+ version: packageJson2.version,
3609
+ access_type: accessType
3610
+ }
3611
+ });
3612
+ }
3613
+ await server.connect(transport);
3614
+ }
3615
+ startServer();