@progress/kendo-angular-mcp 1.5.3-beta.a42c596b.0 → 1.6.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 +594 -2991
- package/package.json +1 -1
- package/proto/service.proto +0 -66
package/dist/index.js
CHANGED
|
@@ -1,914 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import{McpServer as Ut}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as $t}from"@modelcontextprotocol/sdk/server/stdio.js";import{dirname as vt,join as kt}from"path";import{fileURLToPath as At}from"url";import{loadLicense as lt,decodeLicenseKey as ct,decodeLicenseEvidence as dt}from"@progress/kendo-licensing/utils";var B=class extends Error{constructor(t){super(t),this.name="LicenseError"}};function oe(e){return e.replace(/^\uFEFF/,"")}async function ne(e){let t=null,s=null;try{let o=lt();if(!o.success){let n=new B(o.message);throw e&&await e("license_load_failed",{error:o.message}).catch(()=>{}),n}try{t=(await ct(o.value)).licenses.find(async r=>!!(await dt(r)).userId)}catch(n){console.log(n.message),e&&await e("license_load_failed",{error:n.message||"Unknown decoding error"}).catch(()=>{})}if(!t)return[oe(o.value),null]}catch(o){return s=o.message||"Unknown error loading license.",e&&await e("license_load_failed",{error:s}).catch(()=>{}),[null,s]}return[oe(t),null]}import R from"node:fs";import _ from"node:path";var F=!1,N=process.env.DEBUG_LOG_FILE,se=!!(N&&typeof N=="string");if(se){let e=_.resolve(N),t=_.dirname(e);if(t!=="."&&t!==process.cwd()&&!R.existsSync(t))try{R.mkdirSync(t,{recursive:!0})}catch(s){console.error("Error creating log directory:",s)}if(!R.existsSync(e))try{R.writeFileSync(e,"")}catch(s){console.error("Error creating log file:",s)}}else F=!1;F=se&&!!N&&R.existsSync(_.resolve(N));function m(...e){if(F&&N){let o=`${new Date().toISOString()}: ${e.join(" ")}
|
|
3
|
+
`,n=_.resolve(N);R.appendFile(n,o,r=>{r&&console.error("Error writing to log file:",r)})}}import pt from"@grpc/proto-loader";import D from"@grpc/grpc-js";import ie from"path";import ae from"fs";import{fileURLToPath as ut}from"url";var mt=ut(import.meta.url),gt=ie.dirname(mt),le={version:"unknown"},re=ie.resolve(gt,"../package.json");ae.existsSync(re)&&(le=JSON.parse(ae.readFileSync(re,"utf-8")));function ht(e){return e.replace(/\u2014/g,"--").replace(/\u2013/g,"-").replace(/[^\x20-\x7E]/g,"")}var M=class{constructor(t,s,o){this.contextApiUrl=t;this.protoPath=s;this.options=o;this.toolNameHeader="assistant";let n=pt.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"),m("Using ContextApi URl:",this.contextApiUrl);let r=D.loadPackageDefinition(n);this.client=new r.ContextQueryService(this.contextApiUrl||"contextapi.telerik.com:443",this.isDev?D.credentials.createInsecure():D.credentials.createSsl())}async getMetadata({meta:t}={meta:{}}){let[s,o]=this.isDev?["fake_license",null]:await ne((g,b)=>this.logEvent(g,b)),n=process.env.CONTEXTAPI_API_KEY,r=n&&typeof n=="string",a=s&&typeof s=="string";if(!a&&!r&&o)throw new Error(`Failed to authenticate with API key or License key!
|
|
2
4
|
|
|
3
|
-
// packages/angular/src/index.ts
|
|
4
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
-
|
|
7
|
-
// packages/angular/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
|
-
CORRECT: \`<label for="qty">Quantity</label><input type="number" id="qty">\`
|
|
496
|
-
WRONG: \`<span>Email</span><input type="email">\` (no association)
|
|
497
|
-
WRONG: \`<input type="email" placeholder="Email">\` (placeholder as label)
|
|
498
|
-
|
|
499
|
-
**2. Button Accessibility** (WCAG 4.1.2, 2.4.6, 2.5.3)
|
|
500
|
-
All buttons need accessible names describing their purpose.
|
|
501
|
-
CORRECT: \`<button type="button">Save Changes</button>\`
|
|
502
|
-
CORRECT: \`<button aria-label="Close dialog"><svg aria-hidden="true" focusable="false">...</svg></button>\`
|
|
503
|
-
WRONG: \`<button><svg>...</svg></button>\` (no accessible name)
|
|
504
|
-
WRONG: \`<button>Click here</button>\` (generic text)
|
|
505
|
-
|
|
506
|
-
**3. Popup/Menu Triggers** (WCAG 4.1.2, 1.3.1)
|
|
507
|
-
Indicate popup purpose and state using aria-haspopup, aria-expanded, aria-controls.
|
|
508
|
-
CORRECT: \`<button aria-expanded="false" aria-haspopup="menu" aria-controls="menu-id">Settings</button>\`
|
|
509
|
-
|
|
510
|
-
**4. Image Accessibility** (WCAG 1.1.1)
|
|
511
|
-
Informative: \`<img src="chart.png" alt="Sales increased 25% in Q4 2024">\`
|
|
512
|
-
Functional: \`<a href="/home"><img src="logo.png" alt="Company Name Home"></a>\`
|
|
513
|
-
Decorative: \`<img src="border.png" alt="" role="presentation">\`
|
|
514
|
-
Complex: \`<img src="chart.png" alt="Sales data" aria-describedby="desc-id">\`
|
|
515
|
-
WRONG: Missing alt, filename as alt, generic alt for decorative images
|
|
516
|
-
|
|
517
|
-
**5. Link Accessibility** (WCAG 2.4.4, 2.4.6)
|
|
518
|
-
Links must be descriptive and understandable out of context.
|
|
519
|
-
CORRECT: \`<a href="/products">View All Products</a>\`
|
|
520
|
-
CORRECT: \`<a href="/article" aria-label="Read more about New Product Launch">Read more</a>\`
|
|
521
|
-
WRONG: "Click here", "Read more", "Learn more" without context
|
|
522
|
-
|
|
523
|
-
**6. Form Validation** (WCAG 3.3.1, 3.3.2, 3.3.3)
|
|
524
|
-
Errors must be identified, associated with inputs, and provide suggestions. Use aria-describedby, aria-invalid="true", and role="alert".
|
|
525
|
-
|
|
526
|
-
**7. Heading Structure** (WCAG 1.3.1, 2.4.6)
|
|
527
|
-
Each page must have an \`<h1>\` that describes its content. Use hierarchical, descriptive headings with no skipped levels (h1\u2192h2\u2192h3).
|
|
528
|
-
CORRECT: \`<h1>Dashboard</h1> <h2>Sales</h2> <h3>By Region</h3>\`
|
|
529
|
-
WRONG: No \`<h1>\` on the page, or skipping levels (h1\u2192h3)
|
|
530
|
-
If a heading should look smaller than its semantic level, use CSS: \`<h2 class="text-sm">Subtitle</h2>\`
|
|
531
|
-
|
|
532
|
-
**8. Page Component Landmark Rules** (WCAG 1.3.1, 4.1.2)
|
|
533
|
-
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.
|
|
534
|
-
- Avoid adding \`<main>\`, \`role="main"\`, \`<header>\`, or \`<footer>\` in page components \u2014 the layout typically provides them. Duplicating them can cause \`landmark-no-duplicate-main\` and \`landmark-main-is-top-level\` violations.
|
|
535
|
-
- Avoid adding \`role="banner"\` or using a semantic \`<header>\` element in page components \u2014 the layout's \`<header>\` already claims the banner landmark. Adding another causes \`landmark-banner-is-top-level\` violations.
|
|
536
|
-
- Avoid adding \`role="contentinfo"\` to elements inside page components \u2014 the contentinfo landmark should be a top-level landmark, not nested inside \`<main>\` or other landmarks. Nesting it can cause \`landmark-contentinfo-is-top-level\` violations.
|
|
537
|
-
- When multiple \`<section>\` or \`<nav>\` elements exist on a page, give each a unique \`aria-label\` to avoid \`landmark-unique\` violations.
|
|
538
|
-
|
|
539
|
-
**9. ARIA Role and Attribute Restrictions** (WCAG 4.1.2)
|
|
540
|
-
Only use ARIA roles that are valid for the given HTML element. Avoid adding \`aria-label\` or \`aria-labelledby\` to elements that do not permit naming.
|
|
541
|
-
- \`<article>\` has an implicit \`article\` role. Do NOT override it with \`role="listitem"\`, \`role="button"\`, \`role="link"\`, or any other role \u2014 none are allowed on \`<article>\`. Use \`<li>\` for list items, \`<button>\` for interactive cards, or \`<a>\` for clickable cards instead.
|
|
542
|
-
- \`<button>\` already has an implicit \`button\` role. Do NOT add \`role="listitem"\` or other incompatible roles.
|
|
543
|
-
- \`<span>\` and \`<div>\` without roles are generic elements. Do NOT add \`aria-label\` to them \u2014 it is a prohibited attribute on elements with no accessible role and can cause \`aria-prohibited-attr\` violations. Instead, use \`role="img"\` + \`aria-label\` for visual indicators, or use visually hidden text.
|
|
544
|
-
- Do NOT add \`aria-label\` to non-interactive \`<div>\` wrappers \u2014 it has no effect and triggers violations.
|
|
545
|
-
- \`aria-pressed\` is only valid on elements with \`role="button"\`, \`role="checkbox"\`, \`role="menuitemcheckbox"\`, \`role="option"\`, \`role="radio"\`, or \`role="switch"\`. Do NOT use \`aria-pressed\` on elements with \`role="listitem"\` or other roles.
|
|
546
|
-
CORRECT: \`<ul role="list"><li class="product-card">...</li></ul>\` (listitem inside list)
|
|
547
|
-
CORRECT: \`<span role="img" aria-label="Status: pending" class="status-dot"></span>\` (role added before aria-label)
|
|
548
|
-
CORRECT: \`<span class="status-dot" aria-hidden="true"></span><span class="visually-hidden">Pending</span>\` (hidden text alternative)
|
|
549
|
-
WRONG: \`<article role="listitem">\` (listitem not allowed on article)
|
|
550
|
-
WRONG: \`<article role="button">\` (button not allowed on article \u2014 use \`<button>\` or \`<div role="button">\`)
|
|
551
|
-
WRONG: \`<span aria-label="pending" class="status-dot"></span>\` (aria-label prohibited on generic span)
|
|
552
|
-
WRONG: \`<div aria-label="Product badges" class="badges"></div>\` (aria-label prohibited on generic div)
|
|
553
|
-
|
|
554
|
-
**Quick Checklist:**
|
|
555
|
-
- **Forms:** Associated labels, aria-required on required fields, autocomplete attributes, aria-describedby for errors, aria-invalid for invalid fields, fieldsets with legends
|
|
556
|
-
- **Buttons/Links:** Accessible names, aria-label for icon buttons, aria-hidden on decorative icons, descriptive link text
|
|
557
|
-
- **Popups/Dialogs:** aria-haspopup, aria-expanded, aria-controls, role="dialog", aria-modal="true", aria-labelledby, focus trap, Escape to close
|
|
558
|
-
- **Images:** alt on all images, descriptive alt for informative, empty alt for decorative, aria-describedby for complex
|
|
559
|
-
- **Structure:** One h1, logical heading hierarchy, avoid \`<main>\`, \`<header>\`, \`<footer>\`, \`role="main"\`, \`role="contentinfo"\`, \`role="banner"\` in page/route components (the layout may already provide them), use \`<section>\` or \`<div>\` as page-level wrappers, unique aria-labels on duplicate landmark types
|
|
560
|
-
- **ARIA Rules:** Avoid adding \`aria-label\` to generic \`<span>\`/\`<div>\` without a role, avoid using \`role="listitem"\` or \`role="button"\` on \`<article>\` \u2014 use \`<li>\` for list items, add \`role="img"\` before \`aria-label\` on visual indicators, \`aria-pressed\` only on button-like roles
|
|
561
|
-
- **Scrollable Regions:** Any scrollable container must have \`tabindex="0"\` or contain keyboard-interactive children
|
|
562
|
-
- **Nested Interactive:** Do not add interactive role/tabindex to a container that already has focusable children
|
|
563
|
-
- **List Roles:** \`role="list"\` containers must have \`role="listitem"\` children \u2014 prefer \`<ul>/<li>\` natively
|
|
564
|
-
- **Dynamic Content:** role="status"/aria-live="polite" for updates, role="alert"/aria-live="assertive" for critical alerts
|
|
565
|
-
- **Keyboard/Focus:** All interactive elements keyboard accessible, logical focus order, visible focus indicators, no keyboard traps (except modals)
|
|
566
|
-
- **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`;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// packages/mcp-common/src/lib/heartbeat.ts
|
|
570
|
-
var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
|
|
571
|
-
function startHeartbeat(options) {
|
|
572
|
-
const {
|
|
573
|
-
serverName,
|
|
574
|
-
contextApi: contextApi2,
|
|
575
|
-
additionalFields = {},
|
|
576
|
-
intervalMs = ONE_DAY_MS
|
|
577
|
-
} = options;
|
|
578
|
-
const eventName = `mcp_server_heartbeat`;
|
|
579
|
-
const sendHeartbeat = async () => {
|
|
580
|
-
try {
|
|
581
|
-
const fields = {
|
|
582
|
-
server_name: serverName,
|
|
583
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
584
|
-
...additionalFields
|
|
585
|
-
};
|
|
586
|
-
await contextApi2.logEvent(eventName, fields);
|
|
587
|
-
} catch (error) {
|
|
588
|
-
log(`Failed to send heartbeat for ${serverName}:`, error);
|
|
589
|
-
}
|
|
590
|
-
};
|
|
591
|
-
sendHeartbeat();
|
|
592
|
-
const intervalId = setInterval(sendHeartbeat, intervalMs);
|
|
593
|
-
return () => {
|
|
594
|
-
clearInterval(intervalId);
|
|
595
|
-
log(`Heartbeat stopped for ${serverName}`);
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// packages/mcp-common/src/lib/getting-started-params.ts
|
|
600
|
-
import { z as z3 } from "zod";
|
|
601
|
-
var KendoThemes = ["default", "bootstrap", "material", "fluent"];
|
|
602
|
-
function createGettingStartedInputSchema(suiteName, defaultProjectName) {
|
|
603
|
-
return {
|
|
604
|
-
projectName: z3.string().default(defaultProjectName).describe(
|
|
605
|
-
"The name of the project. Used as the project folder name when creating a new project."
|
|
606
|
-
),
|
|
607
|
-
createNewProject: z3.boolean().default(true).describe(
|
|
608
|
-
`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.`
|
|
609
|
-
),
|
|
610
|
-
theme: z3.enum(KendoThemes).default("default").describe(
|
|
611
|
-
"The Kendo UI theme to use. Determines which theme package is installed and imported."
|
|
612
|
-
)
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
// packages/angular/src/lib/constants.ts
|
|
617
|
-
var ANGULAR_SUITE_NAME = "Kendo UI for Angular";
|
|
618
|
-
var Suite = "angular";
|
|
619
|
-
var PRODUCT_LINE = "kendo";
|
|
620
|
-
var AngularComponents = [
|
|
621
|
-
"AIPrompt",
|
|
622
|
-
"ActionSheet",
|
|
623
|
-
"AppBar",
|
|
624
|
-
"ArcGauge",
|
|
625
|
-
"AutoComplete",
|
|
626
|
-
"Avatar",
|
|
627
|
-
"Badge",
|
|
628
|
-
"Barcode",
|
|
629
|
-
"BottomNavigation",
|
|
630
|
-
"BreadCrumb",
|
|
631
|
-
"Button",
|
|
632
|
-
"ButtonGroup",
|
|
633
|
-
"Calendar",
|
|
634
|
-
"Card",
|
|
635
|
-
"ChartWizard",
|
|
636
|
-
"Charts",
|
|
637
|
-
"CheckBox",
|
|
638
|
-
"Chip",
|
|
639
|
-
"ChipList",
|
|
640
|
-
"ChunkProgressBar",
|
|
641
|
-
"CircularGauge",
|
|
642
|
-
"CircularProgressBar",
|
|
643
|
-
"ColorGradient",
|
|
644
|
-
"ColorPalette",
|
|
645
|
-
"ColorPicker",
|
|
646
|
-
"ComboBox",
|
|
647
|
-
"ContextMenu",
|
|
648
|
-
"ConversationalUI",
|
|
649
|
-
"DataQuery",
|
|
650
|
-
"DateInput",
|
|
651
|
-
"DateMath",
|
|
652
|
-
"DatePicker",
|
|
653
|
-
"DateRange",
|
|
654
|
-
"DateTimePicker",
|
|
655
|
-
"Diagram",
|
|
656
|
-
"Dialog",
|
|
657
|
-
"DragandDrop",
|
|
658
|
-
"Drawer",
|
|
659
|
-
"Drawing",
|
|
660
|
-
"DropDownButton",
|
|
661
|
-
"DropDownList",
|
|
662
|
-
"DropDownTree",
|
|
663
|
-
"Editor",
|
|
664
|
-
"ExcelExport",
|
|
665
|
-
"ExpansionPanel",
|
|
666
|
-
"FileSaver",
|
|
667
|
-
"FileSelect",
|
|
668
|
-
"Filter",
|
|
669
|
-
"FlatColorPicker",
|
|
670
|
-
"FloatingActionButton",
|
|
671
|
-
"FloatingLabel",
|
|
672
|
-
"Forms",
|
|
673
|
-
"FormField",
|
|
674
|
-
"Gantt",
|
|
675
|
-
"Gauges",
|
|
676
|
-
"General",
|
|
677
|
-
"Grid",
|
|
678
|
-
"GridLayout",
|
|
679
|
-
"Icon",
|
|
680
|
-
"InlineAIPrompt",
|
|
681
|
-
"Label",
|
|
682
|
-
"LinearGauge",
|
|
683
|
-
"ListBox",
|
|
684
|
-
"ListView",
|
|
685
|
-
"Loader",
|
|
686
|
-
"Map",
|
|
687
|
-
"MaskedTextBox",
|
|
688
|
-
"Menu",
|
|
689
|
-
"MultiColumnComboBox",
|
|
690
|
-
"MultiSelect",
|
|
691
|
-
"MultiSelectTree",
|
|
692
|
-
"MultiViewCalendar",
|
|
693
|
-
"Notification",
|
|
694
|
-
"NumericTextBox",
|
|
695
|
-
"OTPInput",
|
|
696
|
-
"Pager",
|
|
697
|
-
"PanelBar",
|
|
698
|
-
"PDFExport",
|
|
699
|
-
"PDFViewer",
|
|
700
|
-
"PivotGrid",
|
|
701
|
-
"Popover",
|
|
702
|
-
"Popup",
|
|
703
|
-
"ProgressBar",
|
|
704
|
-
"PromptBox",
|
|
705
|
-
"QRCode",
|
|
706
|
-
"RadialGauge",
|
|
707
|
-
"RadioButton",
|
|
708
|
-
"RangeSlider",
|
|
709
|
-
"Rating",
|
|
710
|
-
"Ripple",
|
|
711
|
-
"Sankey",
|
|
712
|
-
"Scheduler",
|
|
713
|
-
"ScrollView",
|
|
714
|
-
"Signature",
|
|
715
|
-
"Skeleton",
|
|
716
|
-
"Slider",
|
|
717
|
-
"SmartPasteButton",
|
|
718
|
-
"Sortable",
|
|
719
|
-
"StockChart",
|
|
720
|
-
"Sparkline",
|
|
721
|
-
"SpeechToTextButton",
|
|
722
|
-
"SplitButton",
|
|
723
|
-
"Splitter",
|
|
724
|
-
"Spreadsheet",
|
|
725
|
-
"StackLayout",
|
|
726
|
-
"Stepper",
|
|
727
|
-
"SVGIcon",
|
|
728
|
-
"Switch",
|
|
729
|
-
"TabStrip",
|
|
730
|
-
"TextArea",
|
|
731
|
-
"TextBox",
|
|
732
|
-
"TileLayout",
|
|
733
|
-
"Timeline",
|
|
734
|
-
"TimePicker",
|
|
735
|
-
"ToolBar",
|
|
736
|
-
"Tooltip",
|
|
737
|
-
"TreeList",
|
|
738
|
-
"TreeView",
|
|
739
|
-
"Typography",
|
|
740
|
-
"Upload",
|
|
741
|
-
"Window"
|
|
742
|
-
];
|
|
743
|
-
var COMPONENT_PACKAGE_MAP = /* @__PURE__ */ new Map([
|
|
744
|
-
["actionsheet", "@progress/kendo-angular-navigation"],
|
|
745
|
-
["aiprompt", "@progress/kendo-angular-conversational-ui"],
|
|
746
|
-
["appbar", "@progress/kendo-angular-navigation"],
|
|
747
|
-
["arcgauge", "@progress/kendo-angular-gauges"],
|
|
748
|
-
["autocomplete", "@progress/kendo-angular-dropdowns"],
|
|
749
|
-
["avatar", "@progress/kendo-angular-layout"],
|
|
750
|
-
["badge", "@progress/kendo-angular-indicators"],
|
|
751
|
-
["barcode", "@progress/kendo-angular-barcodes"],
|
|
752
|
-
["bottomnavigation", "@progress/kendo-angular-navigation"],
|
|
753
|
-
["breadcrumb", "@progress/kendo-angular-navigation"],
|
|
754
|
-
["button", "@progress/kendo-angular-buttons"],
|
|
755
|
-
["buttongroup", "@progress/kendo-angular-buttons"],
|
|
756
|
-
["calendar", "@progress/kendo-angular-dateinputs"],
|
|
757
|
-
["card", "@progress/kendo-angular-layout"],
|
|
758
|
-
["chartwizard", "@progress/kendo-angular-chart-wizard"],
|
|
759
|
-
["checkbox", "@progress/kendo-angular-inputs"],
|
|
760
|
-
["chip", "@progress/kendo-angular-buttons"],
|
|
761
|
-
["chiplist", "@progress/kendo-angular-buttons"],
|
|
762
|
-
["chunkprogressbar", "@progress/kendo-angular-progressbar"],
|
|
763
|
-
["circulargauge", "@progress/kendo-angular-gauges"],
|
|
764
|
-
["circularprogressbar", "@progress/kendo-angular-progressbar"],
|
|
765
|
-
["colorgradient", "@progress/kendo-angular-inputs"],
|
|
766
|
-
["colorpalette", "@progress/kendo-angular-inputs"],
|
|
767
|
-
["colorpicker", "@progress/kendo-angular-inputs"],
|
|
768
|
-
["combobox", "@progress/kendo-angular-dropdowns"],
|
|
769
|
-
["contextmenu", "@progress/kendo-angular-menu"],
|
|
770
|
-
["dataquery", "@progress/kendo-data-query"],
|
|
771
|
-
["dateinput", "@progress/kendo-angular-dateinputs"],
|
|
772
|
-
["datemath", "@progress/kendo-date-math"],
|
|
773
|
-
["datepicker", "@progress/kendo-angular-dateinputs"],
|
|
774
|
-
["daterangepicker", "@progress/kendo-angular-dateinputs"],
|
|
775
|
-
["datetimepicker", "@progress/kendo-angular-dateinputs"],
|
|
776
|
-
["diagram", "@progress/kendo-angular-diagrams"],
|
|
777
|
-
["dialog", "@progress/kendo-angular-dialog"],
|
|
778
|
-
["drawer", "@progress/kendo-angular-layout"],
|
|
779
|
-
["drawing", "@progress/kendo-drawing"],
|
|
780
|
-
["dropdownbutton", "@progress/kendo-angular-buttons"],
|
|
781
|
-
["dropdownlist", "@progress/kendo-angular-dropdowns"],
|
|
782
|
-
["dropdowntree", "@progress/kendo-angular-dropdowns"],
|
|
783
|
-
["editor", "@progress/kendo-angular-editor"],
|
|
784
|
-
["excelexport", "@progress/kendo-angular-excel-export"],
|
|
785
|
-
["expansionpanel", "@progress/kendo-angular-layout"],
|
|
786
|
-
["filesaver", "@progress/kendo-file-saver"],
|
|
787
|
-
["fileselect", "@progress/kendo-angular-upload"],
|
|
788
|
-
["filter", "@progress/kendo-angular-filter"],
|
|
789
|
-
["flatcolorpicker", "@progress/kendo-angular-inputs"],
|
|
790
|
-
["floatingactionbutton", "@progress/kendo-angular-buttons"],
|
|
791
|
-
["floatinglabel", "@progress/kendo-angular-label"],
|
|
792
|
-
["formfield", "@progress/kendo-angular-inputs"],
|
|
793
|
-
["forms", "@progress/kendo-angular-inputs"],
|
|
794
|
-
["gantt", "@progress/kendo-angular-gantt"],
|
|
795
|
-
["grid", "@progress/kendo-angular-grid"],
|
|
796
|
-
["gridlayout", "@progress/kendo-angular-layout"],
|
|
797
|
-
["icon", "@progress/kendo-angular-icons"],
|
|
798
|
-
["inlineaiprompt", "@progress/kendo-angular-conversational-ui"],
|
|
799
|
-
["label", "@progress/kendo-angular-label"],
|
|
800
|
-
["lineargauge", "@progress/kendo-angular-gauges"],
|
|
801
|
-
["listbox", "@progress/kendo-angular-listbox"],
|
|
802
|
-
["listview", "@progress/kendo-angular-listview"],
|
|
803
|
-
["loader", "@progress/kendo-angular-indicators"],
|
|
804
|
-
["map", "@progress/kendo-angular-map"],
|
|
805
|
-
["maskedtextbox", "@progress/kendo-angular-inputs"],
|
|
806
|
-
["menu", "@progress/kendo-angular-menu"],
|
|
807
|
-
["multicolumncombobox", "@progress/kendo-angular-dropdowns"],
|
|
808
|
-
["multiselect", "@progress/kendo-angular-dropdowns"],
|
|
809
|
-
["multiselecttree", "@progress/kendo-angular-dropdowns"],
|
|
810
|
-
["multiviewcalendar", "@progress/kendo-angular-dateinputs"],
|
|
811
|
-
["notification", "@progress/kendo-angular-notification"],
|
|
812
|
-
["numerictextbox", "@progress/kendo-angular-inputs"],
|
|
813
|
-
["otpinput", "@progress/kendo-angular-inputs"],
|
|
814
|
-
["pager", "@progress/kendo-angular-pager"],
|
|
815
|
-
["panelbar", "@progress/kendo-angular-layout"],
|
|
816
|
-
["pdfexport", "@progress/kendo-angular-pdf-export"],
|
|
817
|
-
["pdfviewer", "@progress/kendo-angular-pdfviewer"],
|
|
818
|
-
["pivotgrid", "@progress/kendo-angular-pivotgrid"],
|
|
819
|
-
["popover", "@progress/kendo-angular-tooltip"],
|
|
820
|
-
["popup", "@progress/kendo-angular-popup"],
|
|
821
|
-
["progressbar", "@progress/kendo-angular-progressbar"],
|
|
822
|
-
["promptbox", "@progress/kendo-angular-conversational-ui"],
|
|
823
|
-
["qrcode", "@progress/kendo-angular-barcodes"],
|
|
824
|
-
["radialgauge", "@progress/kendo-angular-gauges"],
|
|
825
|
-
["radiobutton", "@progress/kendo-angular-inputs"],
|
|
826
|
-
["rangeslider", "@progress/kendo-angular-inputs"],
|
|
827
|
-
["rating", "@progress/kendo-angular-inputs"],
|
|
828
|
-
["ripple", "@progress/kendo-angular-ripple"],
|
|
829
|
-
["sankey", "@progress/kendo-angular-charts"],
|
|
830
|
-
["scheduler", "@progress/kendo-angular-scheduler"],
|
|
831
|
-
["scrollview", "@progress/kendo-angular-scrollview"],
|
|
832
|
-
["signature", "@progress/kendo-angular-inputs"],
|
|
833
|
-
["skeleton", "@progress/kendo-angular-indicators"],
|
|
834
|
-
["slider", "@progress/kendo-angular-inputs"],
|
|
835
|
-
["smartpastebutton", "@progress/kendo-angular-buttons"],
|
|
836
|
-
["sortable", "@progress/kendo-angular-sortable"],
|
|
837
|
-
["sparkline", "@progress/kendo-angular-charts"],
|
|
838
|
-
["speechtotextbutton", "@progress/kendo-angular-buttons"],
|
|
839
|
-
["splitbutton", "@progress/kendo-angular-buttons"],
|
|
840
|
-
["splitter", "@progress/kendo-angular-layout"],
|
|
841
|
-
["spreadsheet", "@progress/kendo-angular-spreadsheet"],
|
|
842
|
-
["stacklayout", "@progress/kendo-angular-layout"],
|
|
843
|
-
["stepper", "@progress/kendo-angular-layout"],
|
|
844
|
-
["stockchart", "@progress/kendo-angular-charts"],
|
|
845
|
-
["svgicon", "@progress/kendo-angular-icons"],
|
|
846
|
-
["switch", "@progress/kendo-angular-inputs"],
|
|
847
|
-
["tabstrip", "@progress/kendo-angular-layout"],
|
|
848
|
-
["textarea", "@progress/kendo-angular-inputs"],
|
|
849
|
-
["textbox", "@progress/kendo-angular-inputs"],
|
|
850
|
-
["tilelayout", "@progress/kendo-angular-layout"],
|
|
851
|
-
["timeline", "@progress/kendo-angular-layout"],
|
|
852
|
-
["timepicker", "@progress/kendo-angular-dateinputs"],
|
|
853
|
-
["toolbar", "@progress/kendo-angular-toolbar"],
|
|
854
|
-
["treelist", "@progress/kendo-angular-treelist"],
|
|
855
|
-
["treeview", "@progress/kendo-angular-treeview"],
|
|
856
|
-
["typography", "@progress/kendo-angular-typography"],
|
|
857
|
-
["upload", "@progress/kendo-angular-upload"],
|
|
858
|
-
["window", "@progress/kendo-angular-dialog"],
|
|
859
|
-
["charts", "@progress/kendo-angular-charts"],
|
|
860
|
-
["conversationalui", "@progress/kendo-angular-conversational-ui"],
|
|
861
|
-
["tooltip", "@progress/kendo-angular-tooltip"]
|
|
862
|
-
]);
|
|
863
|
-
|
|
864
|
-
// packages/angular/src/lib/grpc-client.ts
|
|
865
|
-
var protoPath = join(
|
|
866
|
-
dirname(fileURLToPath2(import.meta.url)),
|
|
867
|
-
"../proto/service.proto"
|
|
868
|
-
);
|
|
869
|
-
var contextApi = new ContextAPI("contextapi.telerik.com:443", protoPath, {
|
|
870
|
-
libName: Suite
|
|
871
|
-
});
|
|
872
|
-
var validateUserLicense = async () => {
|
|
873
|
-
return contextApi.validateUserLicense();
|
|
874
|
-
};
|
|
875
|
-
|
|
876
|
-
// packages/angular/src/index.ts
|
|
877
|
-
import fs3 from "fs";
|
|
878
|
-
import path3 from "path";
|
|
879
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
880
|
-
|
|
881
|
-
// packages/kendo-ui-agent/src/lib/tools-factory.ts
|
|
882
|
-
import { z as z4 } from "zod";
|
|
883
|
-
|
|
884
|
-
// packages/kendo-ui-agent/src/lib/ui-agent-tool.ts
|
|
885
|
-
var UIAgentTool = class {
|
|
886
|
-
constructor(name, config, cb) {
|
|
887
|
-
this.name = name;
|
|
888
|
-
this.config = config;
|
|
889
|
-
this.cb = cb;
|
|
890
|
-
}
|
|
891
|
-
register(mcpServer) {
|
|
892
|
-
this.server = mcpServer;
|
|
893
|
-
this.server.registerTool(this.name, this.config, this.cb);
|
|
894
|
-
}
|
|
895
|
-
hasAccess(accessType) {
|
|
896
|
-
if (!this.config.requiredAccess || this.config.requiredAccess.length === 0) {
|
|
897
|
-
return true;
|
|
898
|
-
}
|
|
899
|
-
return accessType === "full" || this.config.requiredAccess.includes(accessType);
|
|
900
|
-
}
|
|
901
|
-
};
|
|
902
|
-
|
|
903
|
-
// packages/kendo-ui-agent/src/lib/templates/validator.ts
|
|
904
|
-
var renderValidatorResponse = (ctx, frameworkValidationSteps) => `# ${ctx.suiteName} - Code Validation & Quality Assurance
|
|
5
|
+
License Error: ${o}`);let i=new D.Metadata;if(a)try{i.add("x-license-key",s)}catch(g){throw m("Error adding license key to metadata:",g),new Error(`Failed to use license key: ${g.message}`)}r&&i.add("x-api-key",n),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:le.version,os:process.platform,node_version:process.version});return i.add("x-request-metadata",ht(d)),i}async query(t,s){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.query(t,o,(a,i)=>{a?r(new Error(a)):n(i)})})}async getApiRefMatches(t,s){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.getApiRefMatches(t,o,(a,i)=>{a?r(new Error(a)):n(i)})})}async queryCssUtils(t,s){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.cssUtilsSearch(t,o,(a,i)=>{a?(m("Error querying CSS Utils:",a),r(new Error(a))):n(i)})})}async queryIconsSearch(t,s){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.iconsSearch(t,o,(a,i)=>{a?(m("Error querying Icons Search:",a),r(new Error(a))):n(i)})})}async queryBuildingBlocks(t,s){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.buildingBlocksSearch(t,o,(a,i)=>{a?(m("Error querying Building Blocks:",a),r(new Error(a))):n(i)})})}async validateUserLicense(){let t=await this.getMetadata();return new Promise((s,o)=>{this.client.validateUserLicense(null,t,(n,r)=>{n?(m("Error validating user license:",n),o(new Error(n))):s(r)})})}async queryThemeGenerate(t,s){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.generateTheme(t,o,(a,i)=>{a?(m("Error querying context API/GenerateTheme:",a),r(new Error(a))):n(i)})})}async recordOrchestratorUserRequest({meta:t}){let s=await this.getMetadata({meta:t});return new Promise((o,n)=>{this.client.recordOrchestratorUserRequest(null,s,(r,a)=>{r?(m("Error recording orchestrator user request:",r),n(new Error(r))):o(a)})})}async recordToolUserRequest({toolName:t,meta:s}){let o=await this.getMetadata({meta:s});return new Promise((n,r)=>{this.client.recordToolUserRequest({tool_name:t},o,(a,i)=>{a?(m("Error recording tool user request:",a),r(new Error(a))):n(i)})})}async logEvent(t,s){let o="h8utJ6rk4PpIWX4JMn9beQDsjVUri6KV0XYfiVwq";if(!o||typeof o!="string"){m("LOGGING_API_KEY not configured, skipping log event");return}let n=new D.Metadata;return n.add("x-api-key",o),new Promise((r,a)=>{this.client.logEvent({event_name:t,fields:s||{}},n,(i,d)=>{i?(m("Error logging event:",i),a(new Error(i))):r()})})}};import{z as q}from"zod";var io=q.object({user_id:q.string(),user_email:q.string().email()});import{z as k}from"zod";var ft=k.object({Product:k.object({Id:k.number().int(),Code:k.string(),Name:k.string()}),License:k.nullable(k.object({Id:k.number().int(),Name:k.string(),Type:k.string(),Active:k.boolean()})),Availability:k.array(k.object({LicenseStart:k.nullable(k.string().datetime()),LicenseEnd:k.nullable(k.string().datetime())})),IsLicenseAvailable:k.optional(k.boolean())}),po=k.array(ft);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 s=await e();return s.toLocaleLowerCase()==="agentic_ui_generator"?"agent":s.toLocaleLowerCase()==="ai_coding_assistants"?"assistant":"none"}function de(){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...">`\nCORRECT: `<label for="qty">Quantity</label><input type="number" id="qty">`\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 must 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- Avoid adding `<main>`, `role="main"`, `<header>`, or `<footer>` in page components \u2014 the layout typically provides them. Duplicating them can cause `landmark-no-duplicate-main` and `landmark-main-is-top-level` violations.\n- Avoid adding `role="banner"` or using a semantic `<header>` element in page components \u2014 the layout\'s `<header>` already claims the banner landmark. Adding another causes `landmark-banner-is-top-level` violations.\n- Avoid adding `role="contentinfo"` to elements inside page components \u2014 the contentinfo landmark should be a top-level landmark, not nested inside `<main>` or other landmarks. Nesting it can cause `landmark-contentinfo-is-top-level` violations.\n- When multiple `<section>` or `<nav>` elements exist on a page, give each a unique `aria-label` to avoid `landmark-unique` violations.\n\n**9. ARIA Role and Attribute Restrictions** (WCAG 4.1.2)\nOnly use ARIA roles that are valid for the given HTML element. Avoid adding `aria-label` or `aria-labelledby` to elements that do not permit naming.\n- `<article>` has an implicit `article` role. Do NOT override it with `role="listitem"`, `role="button"`, `role="link"`, or any other role \u2014 none are allowed on `<article>`. Use `<li>` for list items, `<button>` for interactive cards, or `<a>` for clickable cards instead.\n- `<button>` already has an implicit `button` role. Do NOT add `role="listitem"` or other incompatible roles.\n- `<span>` and `<div>` without roles are generic elements. Do NOT add `aria-label` to them \u2014 it is a prohibited attribute on elements with no accessible role and can cause `aria-prohibited-attr` violations. Instead, use `role="img"` + `aria-label` for visual indicators, or use visually hidden text.\n- Do NOT add `aria-label` to non-interactive `<div>` wrappers \u2014 it has no effect and triggers violations.\n- `aria-pressed` is only valid on elements with `role="button"`, `role="checkbox"`, `role="menuitemcheckbox"`, `role="option"`, `role="radio"`, or `role="switch"`. Do NOT use `aria-pressed` on elements with `role="listitem"` or other roles.\nCORRECT: `<ul role="list"><li class="product-card">...</li></ul>` (listitem inside list)\nCORRECT: `<span role="img" aria-label="Status: pending" class="status-dot"></span>` (role added before aria-label)\nCORRECT: `<span class="status-dot" aria-hidden="true"></span><span class="visually-hidden">Pending</span>` (hidden text alternative)\nWRONG: `<article role="listitem">` (listitem not allowed on article)\nWRONG: `<article role="button">` (button not allowed on article \u2014 use `<button>` or `<div role="button">`)\nWRONG: `<span aria-label="pending" class="status-dot"></span>` (aria-label prohibited on generic span)\nWRONG: `<div aria-label="Product badges" class="badges"></div>` (aria-label prohibited on generic div)\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>`, `<footer>`, `role="main"`, `role="contentinfo"`, `role="banner"` in page/route components (the layout may already provide them), use `<section>` or `<div>` as page-level wrappers, unique aria-labels on duplicate landmark types\n- **ARIA Rules:** Avoid adding `aria-label` to generic `<span>`/`<div>` without a role, avoid using `role="listitem"` or `role="button"` on `<article>` \u2014 use `<li>` for list items, add `role="img"` before `aria-label` on visual indicators, `aria-pressed` only on button-like roles\n- **Scrollable Regions:** Any scrollable container must have `tabindex="0"` or contain keyboard-interactive children\n- **Nested Interactive:** Do not add interactive role/tabindex to a container that already has focusable children\n- **List Roles:** `role="list"` containers must have `role="listitem"` children \u2014 prefer `<ul>/<li>` natively\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 yt=1440*60*1e3;function pe(e){let{serverName:t,contextApi:s,additionalFields:o={},intervalMs:n=yt}=e,r="mcp_server_heartbeat",a=async()=>{try{let d={server_name:t,timestamp:new Date().toISOString(),...o};await s.logEvent(r,d)}catch(d){m(`Failed to send heartbeat for ${t}:`,d)}};a();let i=setInterval(a,n);return()=>{clearInterval(i),m(`Heartbeat stopped for ${t}`)}}import{z as K}from"zod";var bt=["default","bootstrap","material","fluent"];function ue(e,t){return{projectName:K.string().default(t).describe("The name of the project. Used as the project folder name when creating a new project."),createNewProject:K.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:K.enum(bt).default("default").describe("The Kendo UI theme to use. Determines which theme package is installed and imported.")}}var l="Kendo UI for Angular",T="angular",I="kendo",O=["AIPrompt","ActionSheet","AppBar","ArcGauge","AutoComplete","Avatar","Badge","Barcode","BottomNavigation","BreadCrumb","Button","ButtonGroup","Calendar","Card","ChartWizard","Charts","CheckBox","Chip","ChipList","ChunkProgressBar","CircularGauge","CircularProgressBar","ColorGradient","ColorPalette","ColorPicker","ComboBox","ContextMenu","ConversationalUI","DataQuery","DateInput","DateMath","DatePicker","DateRange","DateTimePicker","Diagram","Dialog","DragandDrop","Drawer","Drawing","DropDownButton","DropDownList","DropDownTree","Editor","ExcelExport","ExpansionPanel","FileSaver","FileSelect","Filter","FlatColorPicker","FloatingActionButton","FloatingLabel","Forms","FormField","Gantt","Gauges","General","Grid","GridLayout","Icon","InlineAIPrompt","Label","LinearGauge","ListBox","ListView","Loader","Map","MaskedTextBox","Menu","MultiColumnComboBox","MultiSelect","MultiSelectTree","MultiViewCalendar","Notification","NumericTextBox","OTPInput","Pager","PanelBar","PDFExport","PDFViewer","PivotGrid","Popover","Popup","ProgressBar","PromptBox","QRCode","RadialGauge","RadioButton","RangeSlider","Rating","Ripple","Sankey","Scheduler","ScrollView","Signature","Skeleton","Slider","SmartPasteButton","Sortable","StockChart","Sparkline","SpeechToTextButton","SplitButton","Splitter","Spreadsheet","StackLayout","Stepper","SVGIcon","Switch","TabStrip","TextArea","TextBox","TileLayout","Timeline","TimePicker","ToolBar","Tooltip","TreeList","TreeView","Typography","Upload","Window"],me=new Map([["actionsheet","@progress/kendo-angular-navigation"],["aiprompt","@progress/kendo-angular-conversational-ui"],["appbar","@progress/kendo-angular-navigation"],["arcgauge","@progress/kendo-angular-gauges"],["autocomplete","@progress/kendo-angular-dropdowns"],["avatar","@progress/kendo-angular-layout"],["badge","@progress/kendo-angular-indicators"],["barcode","@progress/kendo-angular-barcodes"],["bottomnavigation","@progress/kendo-angular-navigation"],["breadcrumb","@progress/kendo-angular-navigation"],["button","@progress/kendo-angular-buttons"],["buttongroup","@progress/kendo-angular-buttons"],["calendar","@progress/kendo-angular-dateinputs"],["card","@progress/kendo-angular-layout"],["chartwizard","@progress/kendo-angular-chart-wizard"],["checkbox","@progress/kendo-angular-inputs"],["chip","@progress/kendo-angular-buttons"],["chiplist","@progress/kendo-angular-buttons"],["chunkprogressbar","@progress/kendo-angular-progressbar"],["circulargauge","@progress/kendo-angular-gauges"],["circularprogressbar","@progress/kendo-angular-progressbar"],["colorgradient","@progress/kendo-angular-inputs"],["colorpalette","@progress/kendo-angular-inputs"],["colorpicker","@progress/kendo-angular-inputs"],["combobox","@progress/kendo-angular-dropdowns"],["contextmenu","@progress/kendo-angular-menu"],["dataquery","@progress/kendo-data-query"],["dateinput","@progress/kendo-angular-dateinputs"],["datemath","@progress/kendo-date-math"],["datepicker","@progress/kendo-angular-dateinputs"],["daterangepicker","@progress/kendo-angular-dateinputs"],["datetimepicker","@progress/kendo-angular-dateinputs"],["diagram","@progress/kendo-angular-diagrams"],["dialog","@progress/kendo-angular-dialog"],["drawer","@progress/kendo-angular-layout"],["drawing","@progress/kendo-drawing"],["dropdownbutton","@progress/kendo-angular-buttons"],["dropdownlist","@progress/kendo-angular-dropdowns"],["dropdowntree","@progress/kendo-angular-dropdowns"],["editor","@progress/kendo-angular-editor"],["excelexport","@progress/kendo-angular-excel-export"],["expansionpanel","@progress/kendo-angular-layout"],["filesaver","@progress/kendo-file-saver"],["fileselect","@progress/kendo-angular-upload"],["filter","@progress/kendo-angular-filter"],["flatcolorpicker","@progress/kendo-angular-inputs"],["floatingactionbutton","@progress/kendo-angular-buttons"],["floatinglabel","@progress/kendo-angular-label"],["formfield","@progress/kendo-angular-inputs"],["forms","@progress/kendo-angular-inputs"],["gantt","@progress/kendo-angular-gantt"],["grid","@progress/kendo-angular-grid"],["gridlayout","@progress/kendo-angular-layout"],["icon","@progress/kendo-angular-icons"],["inlineaiprompt","@progress/kendo-angular-conversational-ui"],["label","@progress/kendo-angular-label"],["lineargauge","@progress/kendo-angular-gauges"],["listbox","@progress/kendo-angular-listbox"],["listview","@progress/kendo-angular-listview"],["loader","@progress/kendo-angular-indicators"],["map","@progress/kendo-angular-map"],["maskedtextbox","@progress/kendo-angular-inputs"],["menu","@progress/kendo-angular-menu"],["multicolumncombobox","@progress/kendo-angular-dropdowns"],["multiselect","@progress/kendo-angular-dropdowns"],["multiselecttree","@progress/kendo-angular-dropdowns"],["multiviewcalendar","@progress/kendo-angular-dateinputs"],["notification","@progress/kendo-angular-notification"],["numerictextbox","@progress/kendo-angular-inputs"],["otpinput","@progress/kendo-angular-inputs"],["pager","@progress/kendo-angular-pager"],["panelbar","@progress/kendo-angular-layout"],["pdfexport","@progress/kendo-angular-pdf-export"],["pdfviewer","@progress/kendo-angular-pdfviewer"],["pivotgrid","@progress/kendo-angular-pivotgrid"],["popover","@progress/kendo-angular-tooltip"],["popup","@progress/kendo-angular-popup"],["progressbar","@progress/kendo-angular-progressbar"],["promptbox","@progress/kendo-angular-conversational-ui"],["qrcode","@progress/kendo-angular-barcodes"],["radialgauge","@progress/kendo-angular-gauges"],["radiobutton","@progress/kendo-angular-inputs"],["rangeslider","@progress/kendo-angular-inputs"],["rating","@progress/kendo-angular-inputs"],["ripple","@progress/kendo-angular-ripple"],["sankey","@progress/kendo-angular-charts"],["scheduler","@progress/kendo-angular-scheduler"],["scrollview","@progress/kendo-angular-scrollview"],["signature","@progress/kendo-angular-inputs"],["skeleton","@progress/kendo-angular-indicators"],["slider","@progress/kendo-angular-inputs"],["smartpastebutton","@progress/kendo-angular-buttons"],["sortable","@progress/kendo-angular-sortable"],["sparkline","@progress/kendo-angular-charts"],["speechtotextbutton","@progress/kendo-angular-buttons"],["splitbutton","@progress/kendo-angular-buttons"],["splitter","@progress/kendo-angular-layout"],["spreadsheet","@progress/kendo-angular-spreadsheet"],["stacklayout","@progress/kendo-angular-layout"],["stepper","@progress/kendo-angular-layout"],["stockchart","@progress/kendo-angular-charts"],["svgicon","@progress/kendo-angular-icons"],["switch","@progress/kendo-angular-inputs"],["tabstrip","@progress/kendo-angular-layout"],["textarea","@progress/kendo-angular-inputs"],["textbox","@progress/kendo-angular-inputs"],["tilelayout","@progress/kendo-angular-layout"],["timeline","@progress/kendo-angular-layout"],["timepicker","@progress/kendo-angular-dateinputs"],["toolbar","@progress/kendo-angular-toolbar"],["treelist","@progress/kendo-angular-treelist"],["treeview","@progress/kendo-angular-treeview"],["typography","@progress/kendo-angular-typography"],["upload","@progress/kendo-angular-upload"],["window","@progress/kendo-angular-dialog"],["charts","@progress/kendo-angular-charts"],["conversationalui","@progress/kendo-angular-conversational-ui"],["tooltip","@progress/kendo-angular-tooltip"]]);var wt=kt(vt(At(import.meta.url)),"../proto/service.proto"),G=new M("contextapi.telerik.com:443",wt,{libName:T});var ge=async()=>G.validateUserLicense();import _t from"fs";import st from"path";import{fileURLToPath as Mt}from"url";import{z as v}from"zod";var C=class{constructor(t,s,o){this.name=t;this.config=s;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 L=(e,t)=>`# ${e.suiteName} - Code Validation & Quality Assurance
|
|
905
6
|
|
|
906
7
|
## Comprehensive Code Validation Checklist
|
|
907
8
|
Execute these validation steps systematically to ensure high-quality, maintainable code:
|
|
908
9
|
|
|
909
10
|
### Validation Phase: Framework-Specific Validation
|
|
910
11
|
|
|
911
|
-
${
|
|
12
|
+
${t}
|
|
912
13
|
|
|
913
14
|
### Validation Phase: General Code Quality & Best Practices
|
|
914
15
|
|
|
@@ -945,97 +46,148 @@ Responsive Design:
|
|
|
945
46
|
- Graceful error handling for all user interactions
|
|
946
47
|
- Meaningful error messages for users
|
|
947
48
|
- Network error handling for API calls
|
|
948
|
-
`;
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
-
|
|
962
|
-
-
|
|
963
|
-
- Use
|
|
964
|
-
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
-
|
|
969
|
-
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
49
|
+
`;var V=()=>`## UX/UI Design Best Practices
|
|
50
|
+
|
|
51
|
+
> **These are default guidelines \u2014 follow them when the user has not stated otherwise.** If the user explicitly requests different behavior (e.g., a specific component size, a custom row limit, alternate breakpoints, a different layout pattern), defer to the user's stated preference and disregard the conflicting default below. Only accessibility and WCAG requirements (contrast ratios, focus indicators, semantic HTML, ARIA) apply regardless of user preference.
|
|
52
|
+
|
|
53
|
+
Follow these principles when building or reviewing any UI. They apply regardless of the visual style requested.
|
|
54
|
+
|
|
55
|
+
### Visual Hierarchy & Typography
|
|
56
|
+
- Use a strict 3-level heading hierarchy: page title (h1) \u2192 section heading (h2) \u2192 component label (h3). Never skip levels.
|
|
57
|
+
- Body text line length: 60\u201380 characters maximum. Wider lines reduce readability.
|
|
58
|
+
- Numeric and currency columns must use \`font-variant-numeric: tabular-nums\` to keep digits column-aligned.
|
|
59
|
+
- Never use more than 2 typefaces in a single interface.
|
|
60
|
+
|
|
61
|
+
### Color & Contrast
|
|
62
|
+
- Body text contrast ratio: \u2265 4.5:1 against its background.
|
|
63
|
+
- Large text (\u2265 18pt / 14pt bold) and UI component boundaries: \u2265 3:1.
|
|
64
|
+
- Use only the 5 semantic color slots \u2014 primary, success, warning, error, info \u2014 for meaning. Do not invent new semantic colors.
|
|
65
|
+
- Never use color alone to convey status or meaning (8% of men have color vision deficiency). Always pair color with an icon or text label.
|
|
66
|
+
- Never use red and green as the sole distinguishing colors.
|
|
67
|
+
|
|
68
|
+
### Component Sizing & Density
|
|
69
|
+
- Never mix size variants within the same form or toolbar. Pick one: \`"small"\`, \`"medium"\`, or \`"large"\` and apply it consistently.
|
|
70
|
+
- \`"small"\` (24px) = data-dense tools. \`"medium"\` (32px) = default. \`"large"\` (40px) = comfortable/consumer-facing.
|
|
71
|
+
|
|
72
|
+
### Motion & Animation
|
|
73
|
+
- Always support \`prefers-reduced-motion: reduce\` \u2014 set transition durations to \u2264 0.01ms in that media query.
|
|
74
|
+
- Micro-interactions (button press, tooltip): 150\u2013250ms. Panel transitions (drawer, sidebar): 300\u2013400ms.
|
|
75
|
+
- Never animate layout properties that cause reflow (width, height, margin, padding). Animate transform and opacity instead.
|
|
76
|
+
|
|
77
|
+
### Interaction Patterns
|
|
78
|
+
- Never set \`outline: none\` globally. Keyboard focus indicators are required (WCAG 2.4.7).
|
|
79
|
+
- Loading states: prefer Skeleton loader for content areas, overlay + ProgressBar for blocking operations, disabled button + inline spinner for async submission.
|
|
80
|
+
- Error recovery: inline validation near the field for form errors; notification/toast for API/system errors.
|
|
81
|
+
- Every icon-only button must have a visible tooltip and an \`aria-label\`.
|
|
82
|
+
- Never show tooltips on disabled elements \u2014 disabled elements cannot receive focus.
|
|
83
|
+
|
|
84
|
+
### Responsive Design
|
|
85
|
+
- Breakpoints (defaults \u2014 use the project's breakpoint system if one is already established): Mobile < 640px | Tablet 640\u20131024px | Desktop 1024\u20131440px | Wide > 1440px.
|
|
86
|
+
- Constrain max content width to 1440px with \`margin: 0 auto\` on wide viewports, unless a different maximum is already defined by the project.
|
|
87
|
+
- On mobile (< 480px), data grids must switch to stacked/card layout \u2014 tabular layout is unusable at that width.
|
|
88
|
+
- Schedulers/complex data views are not viable on mobile; provide a simplified alternative or a clear message.
|
|
89
|
+
|
|
90
|
+
### UX Writing
|
|
91
|
+
- Input labels describe *what* the field is. Placeholder text hints at *format or example* \u2014 never use placeholder as a substitute for a label.
|
|
92
|
+
- Button labels must be specific action verbs: "Save Changes", "Delete Record", "Export CSV" \u2014 not "Submit", "OK", or "Yes".
|
|
93
|
+
- Error messages must be specific and actionable: "Email address is already registered" not "Error 409".
|
|
94
|
+
- Table/grid column headers: Title Case. Never ALL CAPS.
|
|
95
|
+
- Empty states must explain why it's empty and offer a next action (e.g., "No records found. Add your first item.").
|
|
96
|
+
|
|
97
|
+
### Data Presentation
|
|
98
|
+
- Numeric and currency values must be right-aligned in table/grid columns.
|
|
99
|
+
- Never display raw ISO 8601 date strings (e.g., \`2024-01-15T09:30:00Z\`) \u2014 always format for the locale (e.g., "15 Jan 2024").
|
|
100
|
+
- Never render more than 200 rows in a fully-loaded table. Use pagination or virtual scrolling for larger datasets.
|
|
101
|
+
- Never leave grid columns without explicit widths \u2014 causes layout jank on load and sort operations.
|
|
102
|
+
|
|
103
|
+
### Chart Type Selection
|
|
104
|
+
- **Line / Area**: continuous quantitative data over time (trends, rates).
|
|
105
|
+
- **Bar (vertical)**: discrete time periods or ordered categories.
|
|
106
|
+
- **Horizontal Bar**: comparing named categories (rankings, survey results).
|
|
107
|
+
- **Donut (not Pie)**: part-to-whole proportions with \u2264 6 segments. Avoid Pie charts \u2014 the center hole of a Donut makes area estimation easier.
|
|
108
|
+
- **Avoid**: 3D charts, dual-axis charts (misleading), charts with > 7 series in the same view.
|
|
109
|
+
- Chart legend placement: below the chart.
|
|
110
|
+
|
|
111
|
+
### Dialog vs Window Decisions
|
|
112
|
+
- **Dialog (modal)**: use when the user must respond before continuing. Title should be action-oriented: "Delete this record?" not "Confirmation".
|
|
113
|
+
- **Window (non-modal)**: use when content can exist alongside the background (resizable/draggable panels, editors).
|
|
114
|
+
- Destructive dialog actions (delete, overwrite) must use the error theme color.
|
|
115
|
+
- Every dialog must be closable via Escape key and have a clearly labeled close control.
|
|
116
|
+
|
|
117
|
+
### Form Validation Display Rules
|
|
118
|
+
- Show field-level validation errors **after the first blur** (not on initial render, not on every keystroke).
|
|
119
|
+
- Display error text inline, directly below the field \u2014 never in a toast or far from the field.
|
|
120
|
+
- On form-level submit failure, focus the first invalid field automatically.
|
|
121
|
+
- Required fields: mark with an asterisk (*) and include a legend. Do not mark optional fields \u2014 label them "(optional)" only if most fields are required.
|
|
122
|
+
|
|
123
|
+
### Grid Data Volume & Scrolling Strategy
|
|
124
|
+
- Never render more than 200 rows without pagination or virtual scrolling.
|
|
125
|
+
- Use **pagination** when users need to navigate by page number, see total row count, or perform export/select-all operations.
|
|
126
|
+
- Use **virtual scrolling** when the dataset is very large (thousands of rows) and users scroll continuously rather than jumping to pages.
|
|
127
|
+
- Default page size: 25 rows. Offer page size options (10, 25, 50) as defaults unless the project specifies otherwise.
|
|
128
|
+
|
|
129
|
+
### Grid Feature Selection
|
|
130
|
+
Enable only the Grid features genuinely required for the workflow. Each enabled feature adds UI chrome, event listeners, and DOM nodes. Start with the minimum set and add only when user stories require it:
|
|
131
|
+
- \`sortable\` \u2014 when users need to find specific rows in non-obvious order
|
|
132
|
+
- \`filterable\` \u2014 for datasets > 50 rows with varied values; skip for small fixed lists
|
|
133
|
+
- \`groupable\` \u2014 only when hierarchical analysis is a core workflow
|
|
134
|
+
- \`reorderable\` / \`resizable\` \u2014 when user customization of the view is a stated requirement
|
|
135
|
+
- \`selectable\` \u2014 only when batch actions exist
|
|
136
|
+
- \`editable\` \u2014 only when inline data entry is the primary workflow, not for read-only display
|
|
137
|
+
|
|
138
|
+
### Form Layout Defaults
|
|
139
|
+
These are defaults \u2014 respect the project's existing form conventions if established:
|
|
140
|
+
- Prefer single-column form layout \u2014 easier to read and complete than multi-column.
|
|
141
|
+
- Use two-column layout only for tightly related field pairs (First Name / Last Name, Start Date / End Date).
|
|
142
|
+
- Align labels above their fields for complex forms; inline labels work only for very short forms (2\u20133 fields).
|
|
143
|
+
- Place the primary action (Save / Submit) at the bottom left; Cancel or secondary actions to its right.
|
|
144
|
+
|
|
145
|
+
### Whitespace Defaults
|
|
146
|
+
When no design token system is defined by the project, apply these minimum spacing values:
|
|
147
|
+
- Section separators: \u2265 24px vertical gap between distinct content areas.
|
|
148
|
+
- Card internal padding: 16\u201324px.
|
|
149
|
+
- Form field vertical gap: \u2265 16px between fields (24px for multi-column groups).
|
|
150
|
+
- Page left/right margin: 24\u201332px minimum, even at desktop widths.`;var U=(e,t)=>{let s=L({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.":"",n=e.components?e.components.join(", "):"components";return`# \u{1F3AF} ${e.suiteName} - Execution Plan
|
|
984
151
|
|
|
985
152
|
**Current Goal:**
|
|
986
153
|
|
|
987
|
-
${
|
|
154
|
+
${e.userIntent}
|
|
988
155
|
|
|
989
156
|
**Requirements Summary:**
|
|
990
|
-
- **Framework:** ${
|
|
991
|
-
${
|
|
992
|
-
- Ensure to use ONLY ${
|
|
993
|
-
- And use the ${
|
|
994
|
-
- Ensure that after you read the plan you use exactly the ${
|
|
995
|
-
|
|
996
|
-
- And use the ${
|
|
997
|
-
|
|
157
|
+
- **Framework:** ${e.libKey}
|
|
158
|
+
${e.includeComponentsDocs?`- **Component Library:** ${e.suiteName}
|
|
159
|
+
- Ensure to use ONLY ${e.suiteName} components for all UI elements.
|
|
160
|
+
- And use the ${e.codeAssistantName} tool to get ${e.suiteName} component documentation and code snippets.
|
|
161
|
+
- 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}.
|
|
162
|
+
`:""}${e.includeLayout?`- **Layout:** Yes
|
|
163
|
+
- And use the ${e.layoutAssistantName} tool to get Kendo CSS utility classes needed for layout structure and responsive design.
|
|
164
|
+
`:""}${e.includeIcons?`- **Icons:** Yes
|
|
998
165
|
- Use icons that align with the project theme and enhance usability.
|
|
999
|
-
- Use the ${
|
|
1000
|
-
|
|
166
|
+
- Use the ${e.iconAssistantName} tool to search for icons that fit the theme and purpose of your project.
|
|
167
|
+
`:""}${e.includeTheming?`- **Custom Theming:**
|
|
1001
168
|
- Create a custom theme that aligns with the current goal and branding needs.
|
|
1002
169
|
- Use Kendo Themes and Design System guidelines.
|
|
1003
170
|
- Make sure to include strict CSS variables or theme requirements from the current goal.
|
|
1004
|
-
- And use the ${
|
|
1005
|
-
|
|
171
|
+
- And use the ${e.styleAssistantName} tool to create a custom theme for your project.
|
|
172
|
+
`:""}${e.includeResponsive?`- **Responsive:**
|
|
1006
173
|
- Ensure the layout is fully responsive across mobile, tablet, and desktop views.
|
|
1007
|
-
${
|
|
1008
|
-
|
|
174
|
+
- And use the ${e.layoutAssistantName} tool to get Kendo CSS utility classes needed for responsive design.
|
|
175
|
+
`:""}
|
|
1009
176
|
- **Accessible (WCAG 2.2 Level AA):**
|
|
1010
|
-
- CRITICAL: You must call the ${
|
|
177
|
+
- CRITICAL: You must call the ${e.accessibilityAssistantName} tool with includeGeneralGuidelines=true on your first call to get WCAG 2.2 Level AA guidelines.
|
|
1011
178
|
- For subsequent calls, use includeGeneralGuidelines=false to get only component-specific accessibility information.
|
|
1012
179
|
- Ensure all components meet WCAG 2.2 Level AA standards.
|
|
1013
180
|
|
|
1014
|
-
${includeLayout
|
|
1015
|
-
**LAYOUT MODE: KENDO DESIGN SYSTEM CSS UTILITIES**
|
|
181
|
+
${e.includeLayout?`**STYLING AND LAYOUT REQUIREMENTS:**
|
|
1016
182
|
## CRITICAL DESIGN SYSTEM CONSTRAINTS
|
|
1017
183
|
- **USE ONLY KENDO DESIGN SYSTEM UTILITIES** for ALL styling, layout, spacing, positioning, and responsive behavior
|
|
1018
184
|
- Avoid custom CSS, inline styles, or other CSS framework classes
|
|
1019
|
-
- The ${
|
|
185
|
+
- The ${e.layoutAssistantName} tool will provide the specific Kendo CSS utility classes needed
|
|
1020
186
|
- All layout requirements must use Kendo utilities exclusively
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
- Do NOT use any utility-first CSS classes (e.g., from Tailwind) for layout or styling.
|
|
1026
|
-
- Focus on leveraging the built-in capabilities of Kendo UI components and writing custom CSS as needed to achieve the desired design and layout.
|
|
1027
|
-
` : ""}
|
|
1028
|
-
${ctx.layoutMode === "tailwind" ? `**STYLING AND LAYOUT REQUIREMENTS:**
|
|
1029
|
-
**LAYOUT MODE: TAILWIND**
|
|
1030
|
-
- In this mode, you should use Tailwind CSS utility classes for layout and styling.
|
|
1031
|
-
- Do NOT write custom CSS or use vanilla CSS for layout or styling.
|
|
1032
|
-
- Focus on leveraging Tailwind's utility-first approach to achieve the desired design and layout, while still using Kendo UI components for functionality.
|
|
1033
|
-
` : ""}
|
|
1034
|
-
${ctx.includeFigmaD2C ? `**DESIGN EXTRACTION FROM FIGMA FILE**
|
|
1035
|
-
- 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.
|
|
1036
|
-
- Extracted design information should be used to get information about the layout, styles, design tokens and assets that can be used within the project.
|
|
1037
|
-
- 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.
|
|
1038
|
-
` : ""}
|
|
187
|
+
|
|
188
|
+
`:""}---
|
|
189
|
+
|
|
190
|
+
${V()}
|
|
1039
191
|
|
|
1040
192
|
---
|
|
1041
193
|
|
|
@@ -1049,13 +201,13 @@ Follow these steps strictly in order to achieve a complete and polished implemen
|
|
|
1049
201
|
**MANDATORY REQUIREMENT:**
|
|
1050
202
|
|
|
1051
203
|
- Before implementing any UI components or features, you must call the accessibility assistant with general guidelines
|
|
1052
|
-
- On your first call to "${
|
|
204
|
+
- On your first call to "${e.accessibilityAssistantName}", set "includeGeneralGuidelines=true" to get foundational WCAG 2.2 Level AA best practices
|
|
1053
205
|
- These general guidelines apply to all components and must be considered throughout implementation
|
|
1054
206
|
- For all subsequent calls, set "includeGeneralGuidelines=false" to get only component-specific information
|
|
1055
207
|
|
|
1056
208
|
**First tool call (includes general WCAG guidelines):**
|
|
1057
209
|
\`\`\`
|
|
1058
|
-
${
|
|
210
|
+
${e.accessibilityAssistantName}({
|
|
1059
211
|
query="What are the accessibility requirements for [COMPONENT_NAME]?",
|
|
1060
212
|
component="[COMPONENT_NAME]",
|
|
1061
213
|
includeGeneralGuidelines=true // ONLY true on first call
|
|
@@ -1064,11 +216,11 @@ ${ctx.accessibilityAssistantName}({
|
|
|
1064
216
|
|
|
1065
217
|
**Step 2: Get Component-Specific Accessibility Information**
|
|
1066
218
|
|
|
1067
|
-
For each additional ${
|
|
219
|
+
For each additional ${e.suiteName} component you plan to use, call the tool with "includeGeneralGuidelines=false":
|
|
1068
220
|
|
|
1069
221
|
**Tool call example:**
|
|
1070
222
|
\`\`\`
|
|
1071
|
-
${
|
|
223
|
+
${e.accessibilityAssistantName}({
|
|
1072
224
|
query="What are the accessibility features and requirements for [COMPONENT_NAME]? Include ARIA attributes, keyboard navigation, and screen reader support.",
|
|
1073
225
|
component="[COMPONENT_NAME]",
|
|
1074
226
|
includeGeneralGuidelines=false // false for all calls after the first
|
|
@@ -1077,112 +229,13 @@ ${ctx.accessibilityAssistantName}({
|
|
|
1077
229
|
|
|
1078
230
|
**Example:**
|
|
1079
231
|
\`\`\`
|
|
1080
|
-
${
|
|
232
|
+
${e.accessibilityAssistantName}({
|
|
1081
233
|
query="How to associate the label with another component or HTML input?",
|
|
1082
234
|
component="Label",
|
|
1083
235
|
includeGeneralGuidelines=false
|
|
1084
236
|
})
|
|
1085
237
|
\`\`\`
|
|
1086
|
-
|
|
1087
|
-
${ctx.includeFigmaD2C ? `### Phase: Design Extraction and Analysis
|
|
1088
|
-
|
|
1089
|
-
**IMPORTANT DESIGN EXTRACTION REQUIRMENTS**
|
|
1090
|
-
- Use the ${ctx.figmaD2CToolName} tool to extract design information from the provided Figma file URL.
|
|
1091
|
-
- Analyze the extracted design information to identify key layout structures, components, styles, and design tokens.
|
|
1092
|
-
- Use the insights from the design analysis to inform your implementation in the next phases, ensuring alignment with the original design intent.
|
|
1093
|
-
- Follow ALL three extraction steps sequentially \u2014 each step is MANDATORY.
|
|
1094
|
-
- Complete the verification checklist after each step before proceeding to the next.
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
**Step 1: Extract Base Design Information from Figma**
|
|
1098
|
-
- 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.
|
|
1099
|
-
- 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.
|
|
1100
|
-
- **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.
|
|
1101
|
-
- **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.
|
|
1102
|
-
|
|
1103
|
-
**Tool call example:**
|
|
1104
|
-
\`\`\`
|
|
1105
|
-
${ctx.figmaD2CToolName}({
|
|
1106
|
-
url: [Figma URL from prompt]
|
|
1107
|
-
depth: 10 // Consider more depth only if the user prompt explicitly states to extract deeply.
|
|
1108
|
-
})
|
|
1109
|
-
\`\`\`
|
|
1110
|
-
|
|
1111
|
-
**Step 1 Completion Checklist (MUST satisfy before proceeding):**
|
|
1112
|
-
- [ ] Have I captured all top-level layout containers (headers, footers, main sections)?
|
|
1113
|
-
- [ ] Have I identified all major structural components?
|
|
1114
|
-
- [ ] Have I created and outputted a structured list of node IDs and their labels?
|
|
1115
|
-
- [ ] Have I visually analyzed the design snapshot to correlate nodes with design elements?
|
|
1116
|
-
|
|
1117
|
-
**Step 2: Extract Main Nodes Design**
|
|
1118
|
-
- 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.
|
|
1119
|
-
- 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.
|
|
1120
|
-
- **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.
|
|
1121
|
-
|
|
1122
|
-
**Tool call example:**
|
|
1123
|
-
\`\`\`
|
|
1124
|
-
${ctx.figmaD2CToolName}({
|
|
1125
|
-
fileKey: [The fileKey extracted from Step 1]
|
|
1126
|
-
nodeIds: [Array of main node IDs identified from Step 1]
|
|
1127
|
-
depth: 10 // Deeper extraction for main nodes to capture necessary details.
|
|
1128
|
-
})
|
|
1129
|
-
\`\`\`
|
|
1130
|
-
|
|
1131
|
-
**Step 2 Completion Checklist (MUST satisfy before proceeding):**
|
|
1132
|
-
- [ ] Have I captured all interactive components (buttons, inputs, navigation elements)?
|
|
1133
|
-
- [ ] Have I identified all typography styles and text elements?
|
|
1134
|
-
- [ ] Have I extracted all color tokens and design system values?
|
|
1135
|
-
- [ ] Have I documented child node IDs that need deeper extraction in Step 3?
|
|
1136
|
-
|
|
1137
|
-
**Step 3: Extract Child Node Details (MANDATORY)**
|
|
1138
|
-
**CRITICAL:** After Step 2, you MUST proceed to Step 3. Extract ALL child nodes identified in Step 2. Do not skip this step.
|
|
1139
|
-
|
|
1140
|
-
- 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.
|
|
1141
|
-
- Use the node IDs from the node-id attribute to fetch these specific child nodes with sufficient depth to capture all critical design details.
|
|
1142
|
-
- **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.
|
|
1143
|
-
|
|
1144
|
-
**Tool call example:**
|
|
1145
|
-
\`\`\`
|
|
1146
|
-
${ctx.figmaD2CToolName}({
|
|
1147
|
-
fileKey: [The fileKey extracted from Step 1]
|
|
1148
|
-
nodeIds: [Array of ALL child node IDs identified from Step 2]
|
|
1149
|
-
depth: 15 // Targeted deeper extraction for specific nodes. Increase if needed.
|
|
1150
|
-
})
|
|
1151
|
-
\`\`\`
|
|
1152
|
-
|
|
1153
|
-
**Step 3 Completion Checklist (MUST satisfy before proceeding):**
|
|
1154
|
-
- [ ] Have I captured ALL leaf-level components (buttons, icons, form inputs)?
|
|
1155
|
-
- [ ] Have I extracted all spacing, padding, and margin values?
|
|
1156
|
-
- [ ] Have I identified all border styles, shadows, and visual effects?
|
|
1157
|
-
- [ ] Are there any remaining truncated nodes? (If yes, apply depth escalation)
|
|
1158
|
-
|
|
1159
|
-
**Iterative Extraction and Stopping Condition**
|
|
1160
|
-
Continue iterating over the extraction process following these rules:
|
|
1161
|
-
- **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.
|
|
1162
|
-
- After each iteration, verify that no new child nodes require deeper extraction.
|
|
1163
|
-
- If depth escalation is needed after 3 passes, document the limitation and proceed with available data.
|
|
1164
|
-
|
|
1165
|
-
**MANDATORY: Design Extraction Verification (Complete BEFORE Code Generation Phase)**
|
|
1166
|
-
Before proceeding to any code generation or implementation phase, you MUST produce and output a verification summary containing:
|
|
1167
|
-
|
|
1168
|
-
1. **Component Inventory:** List all UI components discovered (buttons, inputs, cards, navigation elements, etc.)
|
|
1169
|
-
2. **Hierarchy Map:** Show the parent-child relationships of major layout sections
|
|
1170
|
-
3. **Design Tokens Identified:**
|
|
1171
|
-
- Colors (with hex/rgba values)
|
|
1172
|
-
- Typography (font families, sizes, weights)
|
|
1173
|
-
- Spacing values (margins, paddings, gaps)
|
|
1174
|
-
- Border styles and effects
|
|
1175
|
-
4. **Gaps and Limitations:** Explicitly state any design elements that could not be fully extracted
|
|
1176
|
-
|
|
1177
|
-
**This verification summary serves as the design specification for implementation. Do not proceed to Code Generation until this summary is complete.**
|
|
1178
|
-
|
|
1179
|
-
**Additional Extraction During Implementation:**
|
|
1180
|
-
- 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.
|
|
1181
|
-
- If additional extraction is needed, apply the same depth escalation logic and verification steps.
|
|
1182
|
-
` : ""}
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
${includeLayout ? `
|
|
238
|
+
${e.includeLayout?`
|
|
1186
239
|
### Phase: Layout Foundation
|
|
1187
240
|
|
|
1188
241
|
**Step 1: Create Base Layout Structure**
|
|
@@ -1193,16 +246,16 @@ ${includeLayout ? `
|
|
|
1193
246
|
|
|
1194
247
|
**Tool call example:**
|
|
1195
248
|
\`\`\`
|
|
1196
|
-
${
|
|
249
|
+
${e.layoutAssistantName}({
|
|
1197
250
|
prompt="Provide Kendo Design System utility classes for the following layout structure: [LAYOUT DESCRIPTION HERE]",
|
|
1198
251
|
includeBuildingBlockExamples=true // Optional, include examples of Kendo building blocks (Grid, Flex, Stack, etc.)
|
|
1199
252
|
})
|
|
1200
253
|
\`\`\`
|
|
1201
|
-
|
|
1202
|
-
${
|
|
254
|
+
`:""}
|
|
255
|
+
${e.includeComponentsDocs?`
|
|
1203
256
|
### Phase: Component Integration
|
|
1204
257
|
**Step 1: Identify and Implement Core Components**
|
|
1205
|
-
Based on your current goal, analyze what other ${
|
|
258
|
+
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:
|
|
1206
259
|
|
|
1207
260
|
**Component Selection Guidelines:**
|
|
1208
261
|
- **Landing Pages**: Consider Button, Card, Form components, Layout containers, Navigation elements
|
|
@@ -1210,17 +263,17 @@ Based on your current goal, analyze what other ${ctx.suiteName} components are n
|
|
|
1210
263
|
- **Data Entry**: Consider Form, TextBox, DatePicker, DropDownList, Upload, Validation components
|
|
1211
264
|
- **Content Management**: Consider Grid, Editor, TreeView, FileManager, Dialog components
|
|
1212
265
|
- **E-commerce**: Consider ListView, Card, Button, Rating, Badge, Carousel components
|
|
1213
|
-
${
|
|
266
|
+
${o}
|
|
1214
267
|
|
|
1215
268
|
**IMPORTANT COMPONENT USAGE REQUIREMENTS:**
|
|
1216
|
-
- Make sure to identify all necessary features related to the ${
|
|
1217
|
-
- Make sure to identify specific features needed for other ${
|
|
1218
|
-
- Make sure to generate a query for ${
|
|
269
|
+
- Make sure to identify all necessary features related to the ${n} based on the current goal.
|
|
270
|
+
- Make sure to identify specific features needed for other ${e.suiteName} components based on the current goal.
|
|
271
|
+
- Make sure to generate a query for ${e.codeAssistantName} tool for each component and call the tool for each specific feature or functionality.
|
|
1219
272
|
- 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.
|
|
1220
273
|
|
|
1221
274
|
**Tool call examples:**
|
|
1222
275
|
\`\`\`
|
|
1223
|
-
${
|
|
276
|
+
${e.codeAssistantName}({
|
|
1224
277
|
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' -->
|
|
1225
278
|
component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', 'Chart', etc. -->
|
|
1226
279
|
})
|
|
@@ -1228,33 +281,40 @@ ${dragDropGuidance}
|
|
|
1228
281
|
|
|
1229
282
|
For broad queries, break them down into specific features (e.g., paging, sorting, filtering for Grid) and call the tool separately for each feature:
|
|
1230
283
|
\`\`\`
|
|
1231
|
-
${
|
|
284
|
+
${e.codeAssistantName}({
|
|
1232
285
|
query="How to implement [SPECIFIC_FEATURE] in [COMPONENT_NAME]?" <!-- For example: 'paging in Grid' -->
|
|
1233
286
|
component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', etc. -->
|
|
1234
287
|
})
|
|
1235
288
|
\`\`\`
|
|
1236
289
|
|
|
1237
290
|
\`\`\`
|
|
1238
|
-
${
|
|
291
|
+
${e.codeAssistantName}({
|
|
1239
292
|
query="How to implement [SPECIFIC_FEATURE] in [COMPONENT_NAME]?" <!-- For example: 'sorting in Grid' -->
|
|
1240
293
|
component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', etc. -->
|
|
1241
294
|
})
|
|
1242
295
|
\`\`\`
|
|
1243
296
|
|
|
1244
297
|
\`\`\`
|
|
1245
|
-
${
|
|
298
|
+
${e.codeAssistantName}({
|
|
1246
299
|
query="How to implement [SPECIFIC_FEATURE] in [COMPONENT_NAME]?" <!-- For example: 'filtering in Grid' -->
|
|
1247
300
|
component="[COMPONENT_NAME]" <!-- For example: 'Grid', 'Button', etc. -->
|
|
1248
301
|
})
|
|
1249
302
|
\`\`\`
|
|
1250
|
-
|
|
1251
|
-
${
|
|
303
|
+
`:""}
|
|
304
|
+
${e.includeResponsive?`
|
|
1252
305
|
### Phase: Layout Responsive Finalization
|
|
1253
306
|
|
|
1254
307
|
**Step 1: Implement Responsive Behavior**
|
|
1255
|
-
${responsiveKDSGuidance}${responsiveVanillaCSSGuidance}${responsiveTailwindCSSGuidance}` : ""}
|
|
1256
308
|
|
|
1257
|
-
|
|
309
|
+
**Tool call example:**
|
|
310
|
+
\`\`\`
|
|
311
|
+
${e.layoutAssistantName}({
|
|
312
|
+
prompt="Provide Kendo Design System utility classes to make the following layout structure responsive across mobile, tablet, and desktop views: [LAYOUT DESCRIPTION HERE]",
|
|
313
|
+
includeBuildingBlockExamples=false // Optional, include examples of Kendo building blocks (Grid, Flex, Stack, etc.)
|
|
314
|
+
})
|
|
315
|
+
\`\`\`
|
|
316
|
+
`:""}
|
|
317
|
+
${e.includeTheming?`
|
|
1258
318
|
**Step 2: Custom Theme Implementation**
|
|
1259
319
|
|
|
1260
320
|
**CUSTOM THEME REQUIREMENTS:**
|
|
@@ -1264,13 +324,13 @@ ${ctx.includeTheming ? `
|
|
|
1264
324
|
|
|
1265
325
|
**Tool call example:**
|
|
1266
326
|
\`\`\`
|
|
1267
|
-
${
|
|
327
|
+
${e.styleAssistantName}({
|
|
1268
328
|
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.",
|
|
1269
329
|
includeThemeVariables=true // Optional, include specific CSS variables for colors, typography, spacing, etc.
|
|
1270
330
|
})
|
|
1271
331
|
\`\`\`
|
|
1272
|
-
|
|
1273
|
-
${
|
|
332
|
+
`:""}
|
|
333
|
+
${e.includeIcons?`
|
|
1274
334
|
**Step 3: Iconography and Visual Enhancements**
|
|
1275
335
|
|
|
1276
336
|
**ICONOGRAPHY GUIDELINES:**
|
|
@@ -1280,64 +340,61 @@ ${ctx.includeIcons ? `
|
|
|
1280
340
|
|
|
1281
341
|
**Tool call example:**
|
|
1282
342
|
\`\`\`
|
|
1283
|
-
${
|
|
343
|
+
${e.iconAssistantName}({
|
|
1284
344
|
query="Suggest icons that fit the theme and purpose of the following current goal: [CURRENT GOAL HERE]. Provide icon names and usage context.",
|
|
1285
345
|
})
|
|
1286
346
|
\`\`\`
|
|
1287
|
-
|
|
347
|
+
`:""}
|
|
1288
348
|
### Phase: Code Generation
|
|
1289
349
|
**IMPORTANT:** Do NOT generate ANY code or create files until ALL information gathering phases (1-3) are complete.
|
|
1290
350
|
**Step 1: Generate Complete Implementation**
|
|
1291
|
-
After completing all information gathering phases above, generate the complete ${
|
|
351
|
+
After completing all information gathering phases above, generate the complete ${e.libKey} component/page implementation:
|
|
1292
352
|
**Code Generation Requirements:**
|
|
1293
|
-
- Create complete, functional ${
|
|
1294
|
-
- Include all identified ${
|
|
353
|
+
- Create complete, functional ${e.libKey} components/pages
|
|
354
|
+
- Include all identified ${e.suiteName} components with their configurations
|
|
1295
355
|
- Apply ALL Kendo Design System utility classes gathered from layout assistant
|
|
1296
356
|
- Implement proper component event handling and data binding
|
|
1297
357
|
- Ensure responsive behavior using Kendo utility classes
|
|
1298
358
|
- Include necessary import statements and dependencies
|
|
1299
359
|
|
|
1300
|
-
${
|
|
360
|
+
${t.injectedPlan??""}
|
|
1301
361
|
|
|
1302
362
|
### Phase: Validation and Finalization
|
|
1303
363
|
|
|
1304
364
|
**Step 1: Code Validation**
|
|
1305
365
|
** CRITICAL REQUIREMENT: You MUST validate the generated UI code using this comprehensive checklist to ensure code quality and compliance:**
|
|
1306
366
|
|
|
1307
|
-
${
|
|
367
|
+
${s}
|
|
1308
368
|
|
|
1309
369
|
**Step 2: Final Review and Testing**
|
|
1310
370
|
** Implementation Validation:**
|
|
1311
|
-
${
|
|
1312
|
-
-
|
|
1313
|
-
-
|
|
1314
|
-
|
|
371
|
+
${e.includeComponentsDocs?` - Components render correctly without errors
|
|
372
|
+
- Running \`npm run build\` compiles the application successfully without any build errors or crashes.
|
|
373
|
+
- All ${e.suiteName} component features function as expected
|
|
374
|
+
- Event handling and data binding operate correctly`:""}
|
|
375
|
+
${e.includeResponsive?"- Responsive layout works across breakpoints":""}
|
|
1315
376
|
|
|
1316
377
|
**Quick Fixes (if needed):**
|
|
1317
378
|
|
|
1318
379
|
After code implementation and validation you can make quick fixes as needed:
|
|
1319
|
-
-
|
|
1320
|
-
- Use ${
|
|
380
|
+
- If any build errors are found, fix them and re-run the application.
|
|
381
|
+
- Use ${e.codeAssistantName} for component-specific issues
|
|
382
|
+
- Use ${e.layoutAssistantName} for styling adjustments
|
|
1321
383
|
|
|
1322
384
|
+### Before You Begin
|
|
1323
|
-
- When following/executing the plan call tools are defined from the same function_ecosystem/MCP_server which ${
|
|
385
|
+
- When following/executing the plan call tools are defined from the same function_ecosystem/MCP_server which ${e.name} was called.
|
|
1324
386
|
- Do NOT generate or suggest any code until all tools have been used and validated responses are incorporated.
|
|
1325
387
|
- Focus on planning and sequencing.
|
|
1326
388
|
- Summarize the components, layouts, and utilities gathered.
|
|
1327
|
-
- Confirm all required inputs from tools have been provided
|
|
1328
|
-
};
|
|
1329
|
-
|
|
1330
|
-
// packages/kendo-ui-agent/src/lib/templates/assistant-orchestrator.ts
|
|
1331
|
-
var renderAssistantOrchestratorResponse = (ctx) => {
|
|
1332
|
-
return `# ${ctx.suiteName} Assistant
|
|
389
|
+
- Confirm all required inputs from tools have been provided.`};var j=e=>`# ${e.suiteName} Assistant
|
|
1333
390
|
|
|
1334
391
|
**What you're looking for:**
|
|
1335
392
|
|
|
1336
|
-
${
|
|
393
|
+
${e.userIntent}
|
|
1337
394
|
|
|
1338
395
|
**Available Tools:**
|
|
1339
|
-
- **${
|
|
1340
|
-
- **${
|
|
396
|
+
- **${e.codeAssistantName}** - Get component documentation, features, and usage examples
|
|
397
|
+
- **${e.iconAssistantName}** - Search for icons from the Kendo icon library
|
|
1341
398
|
|
|
1342
399
|
---
|
|
1343
400
|
|
|
@@ -1347,7 +404,7 @@ Follow these steps to find the right components and resources:
|
|
|
1347
404
|
|
|
1348
405
|
### Step 1: Identify Components
|
|
1349
406
|
|
|
1350
|
-
Based on your needs, consider these ${
|
|
407
|
+
Based on your needs, consider these ${e.suiteName} component categories:
|
|
1351
408
|
|
|
1352
409
|
**Common Use Cases:**
|
|
1353
410
|
- **Data Display**: Grid, ListView, TreeView, Card, TileLayout
|
|
@@ -1360,10 +417,10 @@ Based on your needs, consider these ${ctx.suiteName} component categories:
|
|
|
1360
417
|
|
|
1361
418
|
**How to explore components:**
|
|
1362
419
|
|
|
1363
|
-
Use the ${
|
|
420
|
+
Use the ${e.codeAssistantName} tool to learn about specific components:
|
|
1364
421
|
|
|
1365
422
|
\`\`\`
|
|
1366
|
-
${
|
|
423
|
+
${e.codeAssistantName}({
|
|
1367
424
|
query: "What are the main features of [COMPONENT_NAME]?",
|
|
1368
425
|
component: "[COMPONENT_NAME]"
|
|
1369
426
|
})
|
|
@@ -1371,14 +428,14 @@ ${ctx.codeAssistantName}({
|
|
|
1371
428
|
|
|
1372
429
|
**Examples:**
|
|
1373
430
|
\`\`\`
|
|
1374
|
-
${
|
|
431
|
+
${e.codeAssistantName}({
|
|
1375
432
|
query: "How to use Grid with paging and sorting?",
|
|
1376
433
|
component: "Grid"
|
|
1377
434
|
})
|
|
1378
435
|
\`\`\`
|
|
1379
436
|
|
|
1380
437
|
\`\`\`
|
|
1381
|
-
${
|
|
438
|
+
${e.codeAssistantName}({
|
|
1382
439
|
query: "What features does DatePicker have?",
|
|
1383
440
|
component: "DatePicker"
|
|
1384
441
|
})
|
|
@@ -1389,37 +446,37 @@ ${ctx.codeAssistantName}({
|
|
|
1389
446
|
- Break complex queries into multiple calls focusing on one feature at a time
|
|
1390
447
|
- Specify the exact component name in the component parameter
|
|
1391
448
|
|
|
1392
|
-
${
|
|
449
|
+
${e.includeIcons?`
|
|
1393
450
|
### Step 2: Find Icons
|
|
1394
451
|
|
|
1395
|
-
Use the ${
|
|
452
|
+
Use the ${e.iconAssistantName} tool to search for icons:
|
|
1396
453
|
|
|
1397
454
|
\`\`\`
|
|
1398
|
-
${
|
|
455
|
+
${e.iconAssistantName}({
|
|
1399
456
|
query: "Search for icons related to [YOUR THEME/PURPOSE]"
|
|
1400
457
|
})
|
|
1401
458
|
\`\`\`
|
|
1402
459
|
|
|
1403
460
|
**Examples:**
|
|
1404
461
|
\`\`\`
|
|
1405
|
-
${
|
|
462
|
+
${e.iconAssistantName}({
|
|
1406
463
|
query: "icons for navigation menu"
|
|
1407
464
|
})
|
|
1408
465
|
\`\`\`
|
|
1409
466
|
|
|
1410
467
|
\`\`\`
|
|
1411
|
-
${
|
|
468
|
+
${e.iconAssistantName}({
|
|
1412
469
|
query: "icons for user actions like edit, delete, save"
|
|
1413
470
|
})
|
|
1414
471
|
\`\`\`
|
|
1415
|
-
|
|
472
|
+
`:""}
|
|
1416
473
|
|
|
1417
474
|
### Step 3: Review and Implement
|
|
1418
475
|
|
|
1419
476
|
After gathering information:
|
|
1420
|
-
1. Review the component documentation provided by ${
|
|
1421
|
-
2. Check which icons are available from ${
|
|
1422
|
-
3. Use the official ${
|
|
477
|
+
1. Review the component documentation provided by ${e.codeAssistantName}
|
|
478
|
+
2. Check which icons are available from ${e.iconAssistantName}
|
|
479
|
+
3. Use the official ${e.suiteName} documentation for detailed implementation guides
|
|
1423
480
|
4. Refer to the component examples and code snippets provided
|
|
1424
481
|
|
|
1425
482
|
---
|
|
@@ -1427,1490 +484,144 @@ After gathering information:
|
|
|
1427
484
|
## Getting Started
|
|
1428
485
|
|
|
1429
486
|
**Next Actions:**
|
|
1430
|
-
1. Start by calling ${
|
|
1431
|
-
2. ${
|
|
1432
|
-
3. Follow the ${
|
|
487
|
+
1. Start by calling ${e.codeAssistantName} for the components you need
|
|
488
|
+
2. ${e.includeIcons?`Search for icons using ${e.iconAssistantName}`:"Review the component documentation"}
|
|
489
|
+
3. Follow the ${e.suiteName} official documentation for implementation details
|
|
1433
490
|
|
|
1434
491
|
**Important Notes:**
|
|
1435
492
|
- These tools provide documentation and guidance, not code generation
|
|
1436
|
-
- Always refer to official ${
|
|
1437
|
-
- Tool responses include usage examples and best practices`;
|
|
1438
|
-
};
|
|
1439
|
-
|
|
1440
|
-
// packages/kendo-ui-agent/src/lib/templates/shared-validation.ts
|
|
1441
|
-
var getSharedValidationSteps = (uiLibrary, designSystem) => ({
|
|
1442
|
-
SETUP_VALIDATION: `
|
|
493
|
+
- Always refer to official ${e.suiteName} documentation for the most up-to-date information
|
|
494
|
+
- Tool responses include usage examples and best practices`;var E=(e,t)=>({SETUP_VALIDATION:`
|
|
1443
495
|
UI Library Setup:
|
|
1444
|
-
- ${
|
|
1445
|
-
- ${
|
|
1446
|
-
- ${
|
|
1447
|
-
- Globalization and localization properly configured for ${
|
|
1448
|
-
- Required ${
|
|
1449
|
-
PERFORMANCE_OPTIMIZATION: `
|
|
496
|
+
- ${e} modules properly imported and configured
|
|
497
|
+
- ${e} theme properly loaded and applied
|
|
498
|
+
- ${e} license properly configured
|
|
499
|
+
- Globalization and localization properly configured for ${e} components
|
|
500
|
+
- Required ${e} dependencies installed and up-to-date`,PERFORMANCE_OPTIMIZATION:`
|
|
1450
501
|
Performance Optimization:
|
|
1451
502
|
- Efficient rendering patterns to prevent unnecessary re-renders
|
|
1452
|
-
- Lazy loading of ${
|
|
1453
|
-
- Virtualization enabled for large datasets in ${
|
|
1454
|
-
- Only required ${
|
|
1455
|
-
|
|
1456
|
-
${
|
|
1457
|
-
- Prioritize the ${designSystem} Design System utilities
|
|
503
|
+
- Lazy loading of ${e} components when appropriate
|
|
504
|
+
- Virtualization enabled for large datasets in ${e} components
|
|
505
|
+
- Only required ${e} modules imported and tree-shaken`,THEME_AND_STYLING:`
|
|
506
|
+
${e} Theme & Styling:
|
|
507
|
+
- Prioritize the ${t} Design System utilities
|
|
1458
508
|
- Avoid custom CSS or other framework classes
|
|
1459
509
|
- Do not use inline styles
|
|
1460
|
-
- Consistent ${
|
|
510
|
+
- Consistent ${e} theme application across all components
|
|
1461
511
|
- Custom theme variables properly defined and scoped
|
|
1462
|
-
- ${
|
|
1463
|
-
- Brand colors integrated with ${
|
|
1464
|
-
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
512
|
+
- ${e} icon fonts properly loaded and optimized
|
|
513
|
+
- Brand colors integrated with ${e} component themes`});function Ct(e,t){let s;try{s=JSON.parse(e)}catch{return e}let o=s?.Item;if(!o)return e;let n=[],r=o.FullName??o.Name??"",a=o.Type??"",i=o.Summary??"",d=o.SyntaxContent??"";n.push(`## API Reference Item
|
|
514
|
+
- Name: ${r}
|
|
515
|
+
- Type: ${a}
|
|
516
|
+
- Summary: ${i}
|
|
517
|
+
- Syntax: ${d}`);let g=s.RelatedItemsByType?.return_type;if(g?.length){let p=g[0].Text;p&&n.push(`- Return Type: ${p}`)}let b=o.Examples??[];if(b.length>0){let p=`## Examples
|
|
518
|
+
`,c=0;for(let y of b){let A=(y.Component??"").toLowerCase(),w=t.toLowerCase();if(A&&A!==w&&A!=="general")continue;c+=1;let S=y.Code??"";p+=`### Example ${c}
|
|
519
|
+
\`\`\`
|
|
520
|
+
${S}
|
|
521
|
+
\`\`\`
|
|
522
|
+
`}c>0&&n.push(p)}let h=s.RelatedItemsByType??{},f=[];for(let[p,c]of Object.entries(h))if(!(p==="return_type"||p==="render_fragment"))for(let y of c??[]){let A=y.FullName??"",w=y.ShortText??"";f.push(`### ${A} (${p})
|
|
523
|
+
${w}`)}return f.length>0&&n.push(`## Additional Context
|
|
524
|
+
`+f.join(`
|
|
525
|
+
---
|
|
526
|
+
`)),n.join(`
|
|
1476
527
|
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
--color-app-surface: var( --kendo-color-app-surface );
|
|
1480
|
-
--color-on-app-surface: var( --kendo-color-on-app-surface );
|
|
1481
|
-
--color-subtle: var( --kendo-color-subtle );
|
|
1482
|
-
--color-surface: var( --kendo-color-surface );
|
|
1483
|
-
--color-surface-alt: var( --kendo-color-surface-alt );
|
|
1484
|
-
--color-border: var( --kendo-color-border );
|
|
1485
|
-
--color-border-alt: var( --kendo-color-border-alt );
|
|
1486
|
-
/* Base */
|
|
1487
|
-
--color-base-subtle: var( --kendo-color-base-subtle );
|
|
1488
|
-
--color-base-subtle-hover: var( --kendo-color-base-subtle-hover );
|
|
1489
|
-
--color-base-subtle-active: var( --kendo-color-base-subtle-active );
|
|
1490
|
-
--color-base: var( --kendo-color-base );
|
|
1491
|
-
--color-base-hover: var( --kendo-color-base-hover );
|
|
1492
|
-
--color-base-active: var( --kendo-color-base-active );
|
|
1493
|
-
--color-base-emphasis: var( --kendo-color-base-emphasis );
|
|
1494
|
-
--color-base-on-subtle: var( --kendo-color-base-on-subtle );
|
|
1495
|
-
--color-on-base: var( --kendo-color-on-base );
|
|
1496
|
-
--color-base-on-surface: var( --kendo-color-base-on-surface );
|
|
1497
|
-
/* Primary */
|
|
1498
|
-
--color-primary-subtle: var( --kendo-color-primary-subtle );
|
|
1499
|
-
--color-primary-subtle-hover: var( --kendo-color-primary-subtle-hover );
|
|
1500
|
-
--color-primary-subtle-active: var( --kendo-color-primary-subtle-active );
|
|
1501
|
-
--color-primary: var( --kendo-color-primary );
|
|
1502
|
-
--color-primary-hover: var( --kendo-color-primary-hover );
|
|
1503
|
-
--color-primary-active: var( --kendo-color-primary-active );
|
|
1504
|
-
--color-primary-emphasis: var( --kendo-color-primary-emphasis );
|
|
1505
|
-
--color-primary-on-subtle: var( --kendo-color-primary-on-subtle );
|
|
1506
|
-
--color-on-primary: var( --kendo-color-on-primary );
|
|
1507
|
-
--color-primary-on-surface: var( --kendo-color-primary-on-surface );
|
|
1508
|
-
/* Secondary */
|
|
1509
|
-
--color-secondary-subtle: var( --kendo-color-secondary-subtle );
|
|
1510
|
-
--color-secondary-subtle-hover: var( --kendo-color-secondary-subtle-hover );
|
|
1511
|
-
--color-secondary-subtle-active: var( --kendo-color-secondary-subtle-active );
|
|
1512
|
-
--color-secondary: var( --kendo-color-secondary );
|
|
1513
|
-
--color-secondary-hover: var( --kendo-color-secondary-hover );
|
|
1514
|
-
--color-secondary-active: var( --kendo-color-secondary-active );
|
|
1515
|
-
--color-secondary-emphasis: var( --kendo-color-secondary-emphasis );
|
|
1516
|
-
--color-secondary-on-subtle: var( --kendo-color-secondary-on-subtle );
|
|
1517
|
-
--color-on-secondary: var( --kendo-color-on-secondary );
|
|
1518
|
-
--color-secondary-on-surface: var( --kendo-color-secondary-on-surface );
|
|
1519
|
-
/* Tertiary */
|
|
1520
|
-
--color-tertiary-subtle: var( --kendo-color-tertiary-subtle );
|
|
1521
|
-
--color-tertiary-subtle-hover: var( --kendo-color-tertiary-subtle-hover );
|
|
1522
|
-
--color-tertiary-subtle-active: var( --kendo-color-tertiary-subtle-active );
|
|
1523
|
-
--color-tertiary: var( --kendo-color-tertiary );
|
|
1524
|
-
--color-tertiary-hover: var( --kendo-color-tertiary-hover );
|
|
1525
|
-
--color-tertiary-active: var( --kendo-color-tertiary-active );
|
|
1526
|
-
--color-tertiary-emphasis: var( --kendo-color-tertiary-emphasis );
|
|
1527
|
-
--color-tertiary-on-subtle: var( --kendo-color-tertiary-on-subtle );
|
|
1528
|
-
--color-on-tertiary: var( --kendo-color-on-tertiary );
|
|
1529
|
-
--color-tertiary-on-surface: var( --kendo-color-tertiary-on-surface );
|
|
1530
|
-
/* Info */
|
|
1531
|
-
--color-info-subtle: var( --kendo-color-info-subtle );
|
|
1532
|
-
--color-info-subtle-hover: var( --kendo-color-info-subtle-hover );
|
|
1533
|
-
--color-info-subtle-active: var( --kendo-color-info-subtle-active );
|
|
1534
|
-
--color-info: var( --kendo-color-info );
|
|
1535
|
-
--color-info-hover: var( --kendo-color-info-hover );
|
|
1536
|
-
--color-info-active: var( --kendo-color-info-active );
|
|
1537
|
-
--color-info-emphasis: var( --kendo-color-info-emphasis );
|
|
1538
|
-
--color-info-on-subtle: var( --kendo-color-info-on-subtle );
|
|
1539
|
-
--color-on-info: var( --kendo-color-on-info );
|
|
1540
|
-
--color-info-on-surface: var( --kendo-color-info-on-surface );
|
|
1541
|
-
/* Success */
|
|
1542
|
-
--color-success-subtle: var( --kendo-color-success-subtle );
|
|
1543
|
-
--color-success-subtle-hover: var( --kendo-color-success-subtle-hover );
|
|
1544
|
-
--color-success-subtle-active: var( --kendo-color-success-subtle-active );
|
|
1545
|
-
--color-success: var( --kendo-color-success );
|
|
1546
|
-
--color-success-hover: var( --kendo-color-success-hover );
|
|
1547
|
-
--color-success-active: var( --kendo-color-success-active );
|
|
1548
|
-
--color-success-emphasis: var( --kendo-color-success-emphasis );
|
|
1549
|
-
--color-success-on-subtle: var( --kendo-color-success-on-subtle );
|
|
1550
|
-
--color-on-success: var( --kendo-color-on-success );
|
|
1551
|
-
--color-success-on-surface: var( --kendo-color-success-on-surface );
|
|
1552
|
-
/* Warning */
|
|
1553
|
-
--color-warning-subtle: var( --kendo-color-warning-subtle );
|
|
1554
|
-
--color-warning-subtle-hover: var( --kendo-color-warning-subtle-hover );
|
|
1555
|
-
--color-warning-subtle-active: var( --kendo-color-warning-subtle-active );
|
|
1556
|
-
--color-warning: var( --kendo-color-warning );
|
|
1557
|
-
--color-warning-hover: var( --kendo-color-warning-hover );
|
|
1558
|
-
--color-warning-active: var( --kendo-color-warning-active );
|
|
1559
|
-
--color-warning-emphasis: var( --kendo-color-warning-emphasis );
|
|
1560
|
-
--color-warning-on-subtle: var( --kendo-color-warning-on-subtle );
|
|
1561
|
-
--color-on-warning: var( --kendo-color-on-warning );
|
|
1562
|
-
--color-warning-on-surface: var( --kendo-color-warning-on-surface );
|
|
1563
|
-
/* Error */
|
|
1564
|
-
--color-error-subtle: var( --kendo-color-error-subtle );
|
|
1565
|
-
--color-error-subtle-hover: var( --kendo-color-error-subtle-hover );
|
|
1566
|
-
--color-error-subtle-active: var( --kendo-color-error-subtle-active );
|
|
1567
|
-
--color-error: var( --kendo-color-error );
|
|
1568
|
-
--color-error-hover: var( --kendo-color-error-hover );
|
|
1569
|
-
--color-error-active: var( --kendo-color-error-active );
|
|
1570
|
-
--color-error-emphasis: var( --kendo-color-error-emphasis );
|
|
1571
|
-
--color-error-on-subtle: var( --kendo-color-error-on-subtle );
|
|
1572
|
-
--color-on-error: var( --kendo-color-on-error );
|
|
1573
|
-
--color-error-on-surface: var( --kendo-color-error-on-surface );
|
|
1574
|
-
/* Light */
|
|
1575
|
-
--color-light-subtle: var( --kendo-color-light-subtle );
|
|
1576
|
-
--color-light-subtle-hover: var( --kendo-color-light-subtle-hover );
|
|
1577
|
-
--color-light-subtle-active: var( --kendo-color-light-subtle-active );
|
|
1578
|
-
--color-light: var( --kendo-color-light );
|
|
1579
|
-
--color-light-hover: var( --kendo-color-light-hover );
|
|
1580
|
-
--color-light-active: var( --kendo-color-light-active );
|
|
1581
|
-
--color-light-emphasis: var( --kendo-color-light-emphasis );
|
|
1582
|
-
--color-light-on-subtle: var( --kendo-color-light-on-subtle );
|
|
1583
|
-
--color-on-light: var( --kendo-color-on-light );
|
|
1584
|
-
--color-light-on-surface: var( --kendo-color-light-on-surface );
|
|
1585
|
-
/* Dark */
|
|
1586
|
-
--color-dark-subtle: var( --kendo-color-dark-subtle );
|
|
1587
|
-
--color-dark-subtle-hover: var( --kendo-color-dark-subtle-hover );
|
|
1588
|
-
--color-dark-subtle-active: var( --kendo-color-dark-subtle-active );
|
|
1589
|
-
--color-dark: var( --kendo-color-dark );
|
|
1590
|
-
--color-dark-hover: var( --kendo-color-dark-hover );
|
|
1591
|
-
--color-dark-active: var( --kendo-color-dark-active );
|
|
1592
|
-
--color-dark-emphasis: var( --kendo-color-dark-emphasis );
|
|
1593
|
-
--color-dark-on-subtle: var( --kendo-color-dark-on-subtle );
|
|
1594
|
-
--color-on-dark: var( --kendo-color-on-dark );
|
|
1595
|
-
--color-dark-on-surface: var( --kendo-color-dark-on-surface );
|
|
1596
|
-
/* Inverse */
|
|
1597
|
-
--color-inverse-subtle: var( --kendo-color-inverse-subtle );
|
|
1598
|
-
--color-inverse-subtle-hover: var( --kendo-color-inverse-subtle-hover );
|
|
1599
|
-
--color-inverse-subtle-active: var( --kendo-color-inverse-subtle-active );
|
|
1600
|
-
--color-inverse: var( --kendo-color-inverse );
|
|
1601
|
-
--color-inverse-hover: var( --kendo-color-inverse-hover );
|
|
1602
|
-
--color-inverse-active: var( --kendo-color-inverse-active );
|
|
1603
|
-
--color-inverse-emphasis: var( --kendo-color-inverse-emphasis );
|
|
1604
|
-
--color-inverse-on-subtle: var( --kendo-color-inverse-on-subtle );
|
|
1605
|
-
--color-on-inverse: var( --kendo-color-on-inverse );
|
|
1606
|
-
--color-inverse-on-surface: var( --kendo-color-inverse-on-surface );
|
|
1607
|
-
/* Series A */
|
|
1608
|
-
--color-series-a: var( --kendo-color-series-a );
|
|
1609
|
-
--color-series-a-bold: var( --kendo-color-series-a-bold );
|
|
1610
|
-
--color-series-a-bolder: var( --kendo-color-series-a-bolder );
|
|
1611
|
-
--color-series-a-subtle: var( --kendo-color-series-a-subtle );
|
|
1612
|
-
--color-series-a-subtler: var( --kendo-color-series-a-subtler );
|
|
1613
|
-
/* Series B */
|
|
1614
|
-
--color-series-b: var( --kendo-color-series-b );
|
|
1615
|
-
--color-series-b-bold: var( --kendo-color-series-b-bold );
|
|
1616
|
-
--color-series-b-bolder: var( --kendo-color-series-b-bolder );
|
|
1617
|
-
--color-series-b-subtle: var( --kendo-color-series-b-subtle );
|
|
1618
|
-
--color-series-b-subtler: var( --kendo-color-series-b-subtler );
|
|
1619
|
-
/* Series C */
|
|
1620
|
-
--color-series-c: var( --kendo-color-series-c );
|
|
1621
|
-
--color-series-c-bold: var( --kendo-color-series-c-bold );
|
|
1622
|
-
--color-series-c-bolder: var( --kendo-color-series-c-bolder );
|
|
1623
|
-
--color-series-c-subtle: var( --kendo-color-series-c-subtle );
|
|
1624
|
-
--color-series-c-subtler: var( --kendo-color-series-c-subtler );
|
|
1625
|
-
/* Series D */
|
|
1626
|
-
--color-series-d: var( --kendo-color-series-d );
|
|
1627
|
-
--color-series-d-bold: var( --kendo-color-series-d-bold );
|
|
1628
|
-
--color-series-d-bolder: var( --kendo-color-series-d-bolder );
|
|
1629
|
-
--color-series-d-subtle: var( --kendo-color-series-d-subtle );
|
|
1630
|
-
--color-series-d-subtler: var( --kendo-color-series-d-subtler );
|
|
1631
|
-
/* Series E */
|
|
1632
|
-
--color-series-e: var( --kendo-color-series-e );
|
|
1633
|
-
--color-series-e-bold: var( --kendo-color-series-e-bold );
|
|
1634
|
-
--color-series-e-bolder: var( --kendo-color-series-e-bolder );
|
|
1635
|
-
--color-series-e-subtle: var( --kendo-color-series-e-subtle );
|
|
1636
|
-
--color-series-e-subtler: var( --kendo-color-series-e-subtler );
|
|
1637
|
-
/* Series F */
|
|
1638
|
-
--color-series-f: var( --kendo-color-series-f );
|
|
1639
|
-
--color-series-f-bold: var( --kendo-color-series-f-bold );
|
|
1640
|
-
--color-series-f-bolder: var( --kendo-color-series-f-bolder );
|
|
1641
|
-
--color-series-f-subtle: var( --kendo-color-series-f-subtle );
|
|
1642
|
-
--color-series-f-subtler: var( --kendo-color-series-f-subtler );
|
|
1643
|
-
|
|
1644
|
-
/* Typography */
|
|
1645
|
-
--font-sans: var( --kendo-font-family-sans );
|
|
1646
|
-
--font-serif: var( --kendo-font-family-sans-serif );
|
|
1647
|
-
--font-mono: var( --kendo-font-family-monospace );
|
|
1648
|
-
--text-xs: var( --kendo-font-size-xs );
|
|
1649
|
-
--text-xs--line-height: var( --kendo-line-height-xs );
|
|
1650
|
-
--text-sm: var( --kendo-font-size-sm );
|
|
1651
|
-
--text-sm--line-height: var( --kendo-line-height-sm );
|
|
1652
|
-
--text-base: var( --kendo-font-size );
|
|
1653
|
-
--text-base--line-height: var( --kendo-line-height );
|
|
1654
|
-
--text-lg: var( --kendo-font-size-lg );
|
|
1655
|
-
--text-lg--line-height: var( --kendo-line-height-lg );
|
|
1656
|
-
|
|
1657
|
-
--radius-none: var( --kendo-border-radius-none );
|
|
1658
|
-
--radius-xs: var( --kendo-border-radius-xs );
|
|
1659
|
-
--radius-sm: var( --kendo-border-radius-sm );
|
|
1660
|
-
--radius-md: var( --kendo-border-radius-md );
|
|
1661
|
-
--radius-lg: var( --kendo-border-radius-lg );
|
|
1662
|
-
--radius-xl: var( --kendo-border-radius-xl );
|
|
1663
|
-
--radius-2xl: var( --kendo-border-radius-xxl );
|
|
1664
|
-
--radius-3xl: var( --kendo-border-radius-xxxl );
|
|
1665
|
-
--radius-4xl: 1.5rem;
|
|
1666
|
-
--radius-full: var( --kendo-border-radius-full );
|
|
1667
|
-
|
|
1668
|
-
/* Breakpoints */
|
|
1669
|
-
--breakpoint-sm: 576px;
|
|
1670
|
-
--breakpoint-md: 768px;
|
|
1671
|
-
--breakpoint-lg: 992px;
|
|
1672
|
-
--breakpoint-xl: 1200px;
|
|
1673
|
-
--breakpoint-2xl: 1400px;
|
|
1674
|
-
}`;
|
|
1675
|
-
|
|
1676
|
-
// packages/kendo-ui-agent/src/lib/tools-factory.ts
|
|
1677
|
-
function formatApiRefItemFromJson(rawValue, component) {
|
|
1678
|
-
let data;
|
|
1679
|
-
try {
|
|
1680
|
-
data = JSON.parse(rawValue);
|
|
1681
|
-
} catch {
|
|
1682
|
-
return rawValue;
|
|
1683
|
-
}
|
|
1684
|
-
const item = data?.Item;
|
|
1685
|
-
if (!item) {
|
|
1686
|
-
return rawValue;
|
|
1687
|
-
}
|
|
1688
|
-
const sectionParts = [];
|
|
1689
|
-
const name = item.FullName ?? item.Name ?? "";
|
|
1690
|
-
const type = item.Type ?? "";
|
|
1691
|
-
const summary = item.Summary ?? "";
|
|
1692
|
-
const syntax = item.SyntaxContent ?? "";
|
|
1693
|
-
sectionParts.push(
|
|
1694
|
-
`## API Reference Item
|
|
1695
|
-
- Name: ${name}
|
|
1696
|
-
- Type: ${type}
|
|
1697
|
-
- Summary: ${summary}
|
|
1698
|
-
- Syntax: ${syntax}`
|
|
1699
|
-
);
|
|
1700
|
-
const returnTypeItems = data.RelatedItemsByType?.["return_type"];
|
|
1701
|
-
if (returnTypeItems?.length) {
|
|
1702
|
-
const returnType = returnTypeItems[0].Text;
|
|
1703
|
-
if (returnType) {
|
|
1704
|
-
sectionParts.push(`- Return Type: ${returnType}`);
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
const examples = item.Examples ?? [];
|
|
1708
|
-
if (examples.length > 0) {
|
|
1709
|
-
let exampleSection = "## Examples\n";
|
|
1710
|
-
let exampleIndex = 0;
|
|
1711
|
-
for (const example of examples) {
|
|
1712
|
-
const exComponent = (example.Component ?? "").toLowerCase();
|
|
1713
|
-
const compLower = component.toLowerCase();
|
|
1714
|
-
if (exComponent && exComponent !== compLower && exComponent !== "general") {
|
|
1715
|
-
continue;
|
|
1716
|
-
}
|
|
1717
|
-
exampleIndex += 1;
|
|
1718
|
-
const code = example.Code ?? "";
|
|
1719
|
-
exampleSection += `### Example ${exampleIndex}
|
|
1720
|
-
\`\`\`
|
|
1721
|
-
${code}
|
|
1722
|
-
\`\`\`
|
|
1723
|
-
`;
|
|
1724
|
-
}
|
|
1725
|
-
if (exampleIndex > 0) {
|
|
1726
|
-
sectionParts.push(exampleSection);
|
|
1727
|
-
}
|
|
1728
|
-
}
|
|
1729
|
-
const related = data.RelatedItemsByType ?? {};
|
|
1730
|
-
const additionalContextItems = [];
|
|
1731
|
-
for (const [relationType, relatedItems] of Object.entries(related)) {
|
|
1732
|
-
if (relationType === "return_type" || relationType === "render_fragment") {
|
|
1733
|
-
continue;
|
|
1734
|
-
}
|
|
1735
|
-
for (const relatedItem of relatedItems ?? []) {
|
|
1736
|
-
const fullName = relatedItem.FullName ?? "";
|
|
1737
|
-
const shortText = relatedItem.ShortText ?? "";
|
|
1738
|
-
additionalContextItems.push(`### ${fullName} (${relationType})
|
|
1739
|
-
${shortText}`);
|
|
1740
|
-
}
|
|
1741
|
-
}
|
|
1742
|
-
if (additionalContextItems.length > 0) {
|
|
1743
|
-
sectionParts.push("## Additional Context\n" + additionalContextItems.join("\n---\n"));
|
|
1744
|
-
}
|
|
1745
|
-
return sectionParts.join("\n\n");
|
|
1746
|
-
}
|
|
1747
|
-
var LAYOUT_MODE = process.env.KENDO_UIA_LAYOUT_MODE || "utils";
|
|
1748
|
-
function createOrchestratorTool(config, templateOptions, contextApi2) {
|
|
1749
|
-
const {
|
|
1750
|
-
name,
|
|
1751
|
-
title,
|
|
1752
|
-
description,
|
|
1753
|
-
layoutAssistantName: layoutAssistantName2,
|
|
1754
|
-
codeAssistantName: codeAssistantName2,
|
|
1755
|
-
styleAssistantName: styleAssistantName2,
|
|
1756
|
-
iconAssistantName: iconAssistantName2,
|
|
1757
|
-
accessibilityAssistantName: accessibilityAssistantName2,
|
|
1758
|
-
figmaD2CToolName: figmaD2CToolName2,
|
|
1759
|
-
suiteName,
|
|
1760
|
-
libKey,
|
|
1761
|
-
components
|
|
1762
|
-
} = config;
|
|
1763
|
-
const tool = new UIAgentTool(
|
|
1764
|
-
name,
|
|
1765
|
-
{
|
|
1766
|
-
title,
|
|
1767
|
-
description,
|
|
1768
|
-
requiredAccess: config.requiredAccess,
|
|
1769
|
-
inputSchema: {
|
|
1770
|
-
userIntent: z4.string().describe(
|
|
1771
|
-
`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.`
|
|
1772
|
-
),
|
|
1773
|
-
needsComponentsDocsConfidence: z4.number().min(0).max(1).default(1).describe(
|
|
1774
|
-
"Confidence (0-1) to include Component Documentation assistance. Default is 1."
|
|
1775
|
-
),
|
|
1776
|
-
needsLayoutConfidence: z4.number().min(0).max(1).default(0).describe(
|
|
1777
|
-
"Confidence (0-1) to include Layout assistance. Default is 0."
|
|
1778
|
-
),
|
|
1779
|
-
needsStylingConfidence: z4.number().min(0).max(1).default(0).describe(
|
|
1780
|
-
"Confidence (0-1) to include Theming/Styling assistance. Default is 0."
|
|
1781
|
-
),
|
|
1782
|
-
needsResponsiveBehaviorConfidence: z4.number().min(0).max(1).default(0).describe(
|
|
1783
|
-
"Confidence (0-1) to include Responsive Behavior assistance. Default is 0."
|
|
1784
|
-
),
|
|
1785
|
-
needsIconsConfidence: z4.number().min(0).max(1).default(0).describe(
|
|
1786
|
-
"Confidence (0-1) to include Icons assistance. Default is 0."
|
|
1787
|
-
),
|
|
1788
|
-
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),
|
|
1789
|
-
componentsNeeded: z4.array(z4.enum(components)).optional().describe(
|
|
1790
|
-
`Optional list of specific ${suiteName} components needed for the project.`
|
|
1791
|
-
)
|
|
1792
|
-
}
|
|
1793
|
-
},
|
|
1794
|
-
async ({
|
|
1795
|
-
userIntent,
|
|
1796
|
-
needsComponentsDocsConfidence,
|
|
1797
|
-
needsLayoutConfidence,
|
|
1798
|
-
needsStylingConfidence,
|
|
1799
|
-
needsResponsiveBehaviorConfidence,
|
|
1800
|
-
needsIconsConfidence,
|
|
1801
|
-
needsFigmaD2CConfidence,
|
|
1802
|
-
componentsNeeded
|
|
1803
|
-
}, { _meta }) => {
|
|
1804
|
-
log("UI Orchestrator called with:", {
|
|
1805
|
-
userIntent,
|
|
1806
|
-
needsComponentsDocsConfidence,
|
|
1807
|
-
needsLayoutConfidence,
|
|
1808
|
-
needsStylingConfidence,
|
|
1809
|
-
needsResponsiveBehaviorConfidence,
|
|
1810
|
-
needsIconsConfidence
|
|
1811
|
-
});
|
|
1812
|
-
try {
|
|
1813
|
-
await contextApi2.recordOrchestratorUserRequest({
|
|
1814
|
-
meta: {
|
|
1815
|
-
userIntent,
|
|
1816
|
-
componentsNeeded,
|
|
1817
|
-
_meta
|
|
1818
|
-
}
|
|
1819
|
-
});
|
|
1820
|
-
} catch (error) {
|
|
1821
|
-
throw getGrpcError(error);
|
|
1822
|
-
}
|
|
1823
|
-
const clientCapabilities = tool.server?.server.getClientCapabilities?.();
|
|
1824
|
-
const supportsElicitation = clientCapabilities?.elicitation;
|
|
1825
|
-
let forceIncludeCustomTheming;
|
|
1826
|
-
if (supportsElicitation && needsStylingConfidence > 0.3 && needsStylingConfidence <= 0.6) {
|
|
1827
|
-
const result = await tool.server?.server.elicitInput({
|
|
1828
|
-
message: "I was unable to determine if you need custom Kendo Theme assistant. Can you please confirm?",
|
|
1829
|
-
requestedSchema: {
|
|
1830
|
-
type: "object",
|
|
1831
|
-
properties: {
|
|
1832
|
-
includeCustomTheming: {
|
|
1833
|
-
type: "boolean",
|
|
1834
|
-
description: "Whether to include Custom Theming assistance in the workflow."
|
|
1835
|
-
}
|
|
1836
|
-
},
|
|
1837
|
-
required: ["includeCustomTheming"]
|
|
1838
|
-
}
|
|
1839
|
-
});
|
|
1840
|
-
if (result?.action === "accept" && result.content?.includeCustomTheming) {
|
|
1841
|
-
forceIncludeCustomTheming = true;
|
|
1842
|
-
}
|
|
1843
|
-
}
|
|
1844
|
-
const response = renderOrchestratorResponse(
|
|
1845
|
-
{
|
|
1846
|
-
name,
|
|
1847
|
-
userIntent,
|
|
1848
|
-
includeComponentsDocs: needsComponentsDocsConfidence > 0.3,
|
|
1849
|
-
includeTheming: needsStylingConfidence > 0.6 || !!forceIncludeCustomTheming,
|
|
1850
|
-
includeLayout: needsLayoutConfidence > 0.5,
|
|
1851
|
-
includeIcons: needsIconsConfidence > 0.6,
|
|
1852
|
-
includeResponsive: needsLayoutConfidence > 0.5 && needsResponsiveBehaviorConfidence > 0.4,
|
|
1853
|
-
includeFigmaD2C: needsFigmaD2CConfidence,
|
|
1854
|
-
layoutAssistantName: layoutAssistantName2,
|
|
1855
|
-
codeAssistantName: codeAssistantName2,
|
|
1856
|
-
styleAssistantName: styleAssistantName2,
|
|
1857
|
-
iconAssistantName: iconAssistantName2,
|
|
1858
|
-
accessibilityAssistantName: accessibilityAssistantName2,
|
|
1859
|
-
figmaD2CToolName: figmaD2CToolName2,
|
|
1860
|
-
suiteName,
|
|
1861
|
-
libKey,
|
|
1862
|
-
layoutMode: LAYOUT_MODE,
|
|
1863
|
-
components: componentsNeeded
|
|
1864
|
-
},
|
|
1865
|
-
templateOptions
|
|
1866
|
-
);
|
|
1867
|
-
return {
|
|
1868
|
-
content: [
|
|
1869
|
-
{
|
|
1870
|
-
type: "text",
|
|
1871
|
-
text: response
|
|
1872
|
-
}
|
|
1873
|
-
]
|
|
1874
|
-
};
|
|
1875
|
-
}
|
|
1876
|
-
);
|
|
1877
|
-
return tool;
|
|
1878
|
-
}
|
|
1879
|
-
function createAssistantOrchestratorTool(config, contextApi2) {
|
|
1880
|
-
const {
|
|
1881
|
-
name,
|
|
1882
|
-
title,
|
|
1883
|
-
description,
|
|
1884
|
-
iconAssistantName: iconAssistantName2,
|
|
1885
|
-
codeAssistantName: codeAssistantName2,
|
|
1886
|
-
suiteName,
|
|
1887
|
-
libKey,
|
|
1888
|
-
components
|
|
1889
|
-
} = config;
|
|
1890
|
-
const tool = new UIAgentTool(
|
|
1891
|
-
name,
|
|
1892
|
-
{
|
|
1893
|
-
title,
|
|
1894
|
-
description,
|
|
1895
|
-
inputSchema: {
|
|
1896
|
-
userIntent: z4.string().describe(
|
|
1897
|
-
`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}.`
|
|
1898
|
-
),
|
|
1899
|
-
needsIconsConfidence: z4.number().min(0).max(1).default(0.7).describe(
|
|
1900
|
-
"Confidence (0-1) to include Icons assistance. Default is 0.7."
|
|
1901
|
-
),
|
|
1902
|
-
componentsNeeded: z4.array(z4.enum(components)).optional().describe(
|
|
1903
|
-
`Optional list of specific ${suiteName} components you want to learn about.`
|
|
1904
|
-
)
|
|
1905
|
-
},
|
|
1906
|
-
requiredAccess: config.requiredAccess
|
|
1907
|
-
},
|
|
1908
|
-
async ({
|
|
1909
|
-
userIntent,
|
|
1910
|
-
needsIconsConfidence,
|
|
1911
|
-
componentsNeeded
|
|
1912
|
-
}, { _meta }) => {
|
|
1913
|
-
log("Assistant Orchestrator called with:", {
|
|
1914
|
-
userIntent,
|
|
1915
|
-
needsIconsConfidence,
|
|
1916
|
-
componentsNeeded
|
|
1917
|
-
});
|
|
1918
|
-
try {
|
|
1919
|
-
await contextApi2.recordOrchestratorUserRequest({
|
|
1920
|
-
meta: {
|
|
1921
|
-
userIntent,
|
|
1922
|
-
componentsNeeded,
|
|
1923
|
-
_meta
|
|
1924
|
-
}
|
|
1925
|
-
});
|
|
1926
|
-
} catch (error) {
|
|
1927
|
-
throw getGrpcError(error);
|
|
1928
|
-
}
|
|
1929
|
-
const response = renderAssistantOrchestratorResponse({
|
|
1930
|
-
name,
|
|
1931
|
-
userIntent,
|
|
1932
|
-
includeComponentsDocs: true,
|
|
1933
|
-
// Always true for assistant mode
|
|
1934
|
-
includeIcons: needsIconsConfidence > 0.5,
|
|
1935
|
-
codeAssistantName: codeAssistantName2,
|
|
1936
|
-
iconAssistantName: iconAssistantName2,
|
|
1937
|
-
suiteName,
|
|
1938
|
-
libKey,
|
|
1939
|
-
components: componentsNeeded
|
|
1940
|
-
});
|
|
1941
|
-
return {
|
|
1942
|
-
content: [
|
|
1943
|
-
{
|
|
1944
|
-
type: "text",
|
|
1945
|
-
text: response
|
|
1946
|
-
}
|
|
1947
|
-
]
|
|
1948
|
-
};
|
|
1949
|
-
}
|
|
1950
|
-
);
|
|
1951
|
-
return tool;
|
|
1952
|
-
}
|
|
1953
|
-
function createLayoutAssistantTool(config, contextApi2) {
|
|
1954
|
-
const {
|
|
1955
|
-
name,
|
|
1956
|
-
title,
|
|
1957
|
-
description,
|
|
1958
|
-
suiteName: _suiteName,
|
|
1959
|
-
libKey,
|
|
1960
|
-
getPreContent
|
|
1961
|
-
} = config;
|
|
1962
|
-
return new UIAgentTool(
|
|
1963
|
-
name,
|
|
1964
|
-
{
|
|
1965
|
-
title,
|
|
1966
|
-
description,
|
|
1967
|
-
requiredAccess: LAYOUT_MODE === "utils" ? config.requiredAccess : ["none"],
|
|
1968
|
-
inputSchema: {
|
|
1969
|
-
prompt: z4.string().describe(
|
|
1970
|
-
`An enhanced prompt describing the HTML layout structure, design requirements or specific visual effects you want to achieve.`
|
|
1971
|
-
),
|
|
1972
|
-
includeBuildingBlockExamples: z4.boolean().describe(
|
|
1973
|
-
"Whether to include building block examples. Defaults to false."
|
|
1974
|
-
).default(false)
|
|
1975
|
-
}
|
|
1976
|
-
},
|
|
1977
|
-
async ({ prompt, includeBuildingBlockExamples }, { _meta }) => {
|
|
1978
|
-
log("Layout Assistant called with:", {
|
|
1979
|
-
prompt,
|
|
1980
|
-
includeBuildingBlockExamples
|
|
1981
|
-
});
|
|
1982
|
-
try {
|
|
1983
|
-
const cssResponse = await contextApi2.queryCssUtils({ query: prompt }, { _meta });
|
|
1984
|
-
let finalMarkdown = cssResponse.values.join("\n") || "No CSS utilities found for the given prompt.";
|
|
1985
|
-
const preContent = getPreContent?.() ?? "";
|
|
1986
|
-
const buildLayout = (buildingBlockMd) => {
|
|
1987
|
-
return `${preContent}
|
|
528
|
+
`)}function he(e,t,s){let{name:o,title:n,description:r,layoutAssistantName:a,codeAssistantName:i,styleAssistantName:d,iconAssistantName:g,accessibilityAssistantName:b,suiteName:h,libKey:f,components:p}=e,c=new C(o,{title:n,description:r,requiredAccess:e.requiredAccess,inputSchema:{userIntent:v.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:v.number().min(0).max(1).default(1).describe("Confidence (0-1) to include Component Documentation assistance. Default is 1."),needsLayoutConfidence:v.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Layout assistance. Default is 0."),needsStylingConfidence:v.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Theming/Styling assistance. Default is 0."),needsResponsiveBehaviorConfidence:v.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Responsive Behavior assistance. Default is 0."),needsIconsConfidence:v.number().min(0).max(1).default(0).describe("Confidence (0-1) to include Icons assistance. Default is 0."),componentsNeeded:v.array(v.enum(p)).optional().describe(`Optional list of specific ${h} components needed for the project.`)}},async({userIntent:y,needsComponentsDocsConfidence:A,needsLayoutConfidence:w,needsStylingConfidence:S,needsResponsiveBehaviorConfidence:x,needsIconsConfidence:Z,componentsNeeded:ee},{_meta:rt})=>{m("UI Orchestrator called with:",{userIntent:y,needsComponentsDocsConfidence:A,needsLayoutConfidence:w,needsStylingConfidence:S,needsResponsiveBehaviorConfidence:x,needsIconsConfidence:Z});try{await s.recordOrchestratorUserRequest({meta:{userIntent:y,componentsNeeded:ee,_meta:rt}})}catch($){throw P($)}let it=c.server?.server.getClientCapabilities?.()?.elicitation,te;if(it&&S>.3&&S<=.6){let $=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"]}});$?.action==="accept"&&$.content?.includeCustomTheming&&(te=!0)}return{content:[{type:"text",text:U({name:o,userIntent:y,includeComponentsDocs:A>.3,includeTheming:S>.6||!!te,includeLayout:w>.5,includeIcons:Z>.6,includeResponsive:w>.5&&x>.4,layoutAssistantName:a,codeAssistantName:i,styleAssistantName:d,iconAssistantName:g,accessibilityAssistantName:b,suiteName:h,libKey:f,components:ee},t)}]}});return c}function fe(e,t){let{name:s,title:o,description:n,iconAssistantName:r,codeAssistantName:a,suiteName:i,libKey:d,components:g}=e;return new C(s,{title:o,description:n,inputSchema:{userIntent:v.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:v.number().min(0).max(1).default(.7).describe("Confidence (0-1) to include Icons assistance. Default is 0.7."),componentsNeeded:v.array(v.enum(g)).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})=>{m("Assistant Orchestrator called with:",{userIntent:h,needsIconsConfidence:f,componentsNeeded:p});try{await t.recordOrchestratorUserRequest({meta:{userIntent:h,componentsNeeded:p,_meta:c}})}catch(A){throw P(A)}return{content:[{type:"text",text:j({name:s,userIntent:h,includeComponentsDocs:!0,includeIcons:f>.5,codeAssistantName:a,iconAssistantName:r,suiteName:i,libKey:d,components:p})}]}})}function ye(e,t){let{name:s,title:o,description:n,suiteName:r,libKey:a,getPreContent:i}=e;return new C(s,{title:o,description:n,requiredAccess:e.requiredAccess,inputSchema:{prompt:v.string().describe("An enhanced prompt describing the HTML layout structure, design requirements or specific visual effects you want to achieve."),includeBuildingBlockExamples:v.boolean().describe("Whether to include building block examples. Defaults to false.").default(!1)}},async({prompt:d,includeBuildingBlockExamples:g},{_meta:b})=>{m("Layout Assistant called with:",{prompt:d,includeBuildingBlockExamples:g});try{let f=(await t.queryCssUtils({query:d},{_meta:b})).values.join(`
|
|
529
|
+
`)||"No CSS utilities found for the given prompt.",p=i?.()??"",c=y=>`${p}
|
|
1988
530
|
|
|
1989
531
|
# Kendo Design System CSS Utilities
|
|
1990
532
|
|
|
1991
|
-
${
|
|
1992
|
-
${
|
|
1993
|
-
`;
|
|
1994
|
-
};
|
|
1995
|
-
if (includeBuildingBlockExamples) {
|
|
1996
|
-
try {
|
|
1997
|
-
const buildingBlocksResponse = await contextApi2.queryBuildingBlocks({
|
|
1998
|
-
query: prompt,
|
|
1999
|
-
lib_name: libKey
|
|
2000
|
-
}, { _meta });
|
|
2001
|
-
let buildingBlockMd = "";
|
|
2002
|
-
if (buildingBlocksResponse.items?.length > 0) {
|
|
2003
|
-
buildingBlockMd = `
|
|
533
|
+
${f}
|
|
534
|
+
${y??""}
|
|
535
|
+
`;if(g)try{let y=await t.queryBuildingBlocks({query:d,lib_name:a},{_meta:b}),A="";y.items?.length>0&&(A=`
|
|
2004
536
|
## Building Blocks Examples
|
|
2005
537
|
|
|
2006
538
|
The examples here are for demonstration purpose how CSS utils can be implemented in various building blocks.
|
|
2007
539
|
However, consider your own design requirements and specifics in order to implement your templates/building blocks correctly.
|
|
2008
540
|
|
|
2009
|
-
${
|
|
2010
|
-
|
|
2011
|
-
### ${item.name}
|
|
541
|
+
${y.items.map(w=>`
|
|
542
|
+
### ${w.name}
|
|
2012
543
|
|
|
2013
|
-
${
|
|
544
|
+
${w.description}
|
|
2014
545
|
|
|
2015
546
|
\`\`\`code
|
|
2016
|
-
${
|
|
2017
|
-
\`\`\`
|
|
2018
|
-
`
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
} catch (buildingBlockError) {
|
|
2023
|
-
log("Error calling building-blocks service:", buildingBlockError);
|
|
2024
|
-
finalMarkdown = buildLayout();
|
|
2025
|
-
}
|
|
2026
|
-
} else {
|
|
2027
|
-
finalMarkdown = buildLayout();
|
|
2028
|
-
}
|
|
2029
|
-
return {
|
|
2030
|
-
content: [
|
|
2031
|
-
{
|
|
2032
|
-
type: "text",
|
|
2033
|
-
text: finalMarkdown
|
|
2034
|
-
}
|
|
2035
|
-
]
|
|
2036
|
-
};
|
|
2037
|
-
} catch (error) {
|
|
2038
|
-
throw getGrpcError(error);
|
|
2039
|
-
}
|
|
2040
|
-
}
|
|
2041
|
-
);
|
|
2042
|
-
}
|
|
2043
|
-
function createStyleAssistantTool(config, contextApi2) {
|
|
2044
|
-
const { name, title, description, libKey: _libKey, getPreContent } = config;
|
|
2045
|
-
return new UIAgentTool(
|
|
2046
|
-
name,
|
|
2047
|
-
{
|
|
2048
|
-
title,
|
|
2049
|
-
description,
|
|
2050
|
-
requiredAccess: config.requiredAccess,
|
|
2051
|
-
inputSchema: {
|
|
2052
|
-
prompt: z4.string().describe(
|
|
2053
|
-
`A natural language description of the desired visual style or theme. For example: 'Create a modern dark theme with high contrast'.`
|
|
2054
|
-
)
|
|
2055
|
-
}
|
|
2056
|
-
},
|
|
2057
|
-
async ({ prompt }, { _meta }) => {
|
|
2058
|
-
log("Style Assistant called with:", { prompt });
|
|
2059
|
-
let formattedCSS = "";
|
|
2060
|
-
try {
|
|
2061
|
-
const result = await contextApi2.queryThemeGenerate({ prompt }, { _meta });
|
|
2062
|
-
if (result.variables_json) {
|
|
2063
|
-
const theme = JSON.parse(result.variables_json);
|
|
2064
|
-
let cssBlocks = [];
|
|
2065
|
-
if (theme) {
|
|
2066
|
-
for (const key of Object.keys(theme)) {
|
|
2067
|
-
if (typeof theme[key] === "string") {
|
|
2068
|
-
cssBlocks.push(`${key}: ${theme[key]}`);
|
|
2069
|
-
}
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
formattedCSS = cssBlocks.join("\n\n");
|
|
2073
|
-
}
|
|
2074
|
-
} catch (error) {
|
|
2075
|
-
throw getGrpcError(error);
|
|
2076
|
-
}
|
|
2077
|
-
const preContent = getPreContent?.() ?? "";
|
|
2078
|
-
const response = formattedCSS ? `Use the following CSS variables to style the web application, including colors, typography, spacing, and component appearance.
|
|
547
|
+
${w.code}
|
|
548
|
+
\`\`\`
|
|
549
|
+
`).join(`
|
|
550
|
+
`)}`),f=c(A)}catch(y){m("Error calling building-blocks service:",y),f=c()}else f=c();return{content:[{type:"text",text:f}]}}catch(h){throw P(h)}})}function be(e,t){let{name:s,title:o,description:n,libKey:r,getPreContent:a}=e;return new C(s,{title:o,description:n,requiredAccess:e.requiredAccess,inputSchema:{prompt:v.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})=>{m("Style Assistant called with:",{prompt:i});let g="";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]}`);g=c.join(`
|
|
551
|
+
|
|
552
|
+
`)}}catch(f){throw P(f)}let b=a?.()??"";return{content:[{type:"text",text:g?`Use the following CSS variables to style the web application, including colors, typography, spacing, and component appearance.
|
|
2079
553
|
Ensure the variables are applied consistently across all relevant elements.
|
|
2080
554
|
Do NOT set any inline styles. CSS variables should be defined in global or component-level CSS files, or via supported theming mechanisms.
|
|
2081
555
|
|
|
2082
|
-
${
|
|
556
|
+
${b}
|
|
2083
557
|
|
|
2084
558
|
## Generated CSS Variables
|
|
2085
559
|
|
|
2086
560
|
\`\`\`css
|
|
2087
|
-
${
|
|
2088
|
-
\`\`\`
|
|
2089
|
-
|
|
2090
|
-
return {
|
|
2091
|
-
content: [
|
|
2092
|
-
{
|
|
2093
|
-
type: "text",
|
|
2094
|
-
text: response
|
|
2095
|
-
},
|
|
2096
|
-
LAYOUT_MODE === "tailwind" ? {
|
|
2097
|
-
type: "text",
|
|
2098
|
-
text: `Note: For layout and spacing, use Tailwind CSS utility classes to structure your layout and apply spacing between elements.
|
|
2099
|
-
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.
|
|
2100
|
-
|
|
2101
|
-
<taiwind_bridge_example>
|
|
2102
|
-
${tailwindBridgeExample}
|
|
2103
|
-
</taiwind_bridge_example>
|
|
2104
|
-
`
|
|
2105
|
-
} : LAYOUT_MODE === "vanilla" ? {
|
|
2106
|
-
type: "text",
|
|
2107
|
-
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."
|
|
2108
|
-
} : {
|
|
2109
|
-
type: "text",
|
|
2110
|
-
text: "Note: For layout and spacing, use the Layout Assistant tool to get the appropriate Kendo CSS utility classes."
|
|
2111
|
-
}
|
|
2112
|
-
]
|
|
2113
|
-
};
|
|
2114
|
-
}
|
|
2115
|
-
);
|
|
2116
|
-
}
|
|
2117
|
-
function createIconSearchTool(config, contextApi2) {
|
|
2118
|
-
const { name, title, description, libKey: _libKey, getPostContent } = config;
|
|
2119
|
-
return new UIAgentTool(
|
|
2120
|
-
name,
|
|
2121
|
-
{
|
|
2122
|
-
title,
|
|
2123
|
-
description,
|
|
2124
|
-
requiredAccess: config.requiredAccess,
|
|
2125
|
-
inputSchema: {
|
|
2126
|
-
query: z4.string().describe(
|
|
2127
|
-
"A search query for finding icons. Be specific about the icon purpose, style, or action."
|
|
2128
|
-
),
|
|
2129
|
-
limit: z4.number().min(0.1).max(1).default(0.1).describe(
|
|
2130
|
-
`The proportion of matching icons to return (0.1 = 1 icon, 0.5 = 5 icons, 1.0 = many icons). Default is 0.1.`
|
|
2131
|
-
)
|
|
2132
|
-
}
|
|
2133
|
-
},
|
|
2134
|
-
async ({ query, limit }, { _meta }) => {
|
|
2135
|
-
log("Icon Search called with:", { query, limit });
|
|
2136
|
-
try {
|
|
2137
|
-
const result = await contextApi2.queryIconsSearch({
|
|
2138
|
-
query,
|
|
2139
|
-
limit: limit * 100
|
|
2140
|
-
}, { _meta });
|
|
2141
|
-
const postContent = getPostContent?.() ?? "";
|
|
2142
|
-
const response = `${result.values.join("\n\n")}
|
|
2143
|
-
|
|
2144
|
-
${postContent}`;
|
|
2145
|
-
return {
|
|
2146
|
-
content: [
|
|
2147
|
-
{
|
|
2148
|
-
type: "text",
|
|
2149
|
-
text: response
|
|
2150
|
-
}
|
|
2151
|
-
]
|
|
2152
|
-
};
|
|
2153
|
-
} catch (error) {
|
|
2154
|
-
throw getGrpcError(error);
|
|
2155
|
-
}
|
|
2156
|
-
}
|
|
2157
|
-
);
|
|
2158
|
-
}
|
|
2159
|
-
function createCodeAssistantTool(config, contextApi2) {
|
|
2160
|
-
const {
|
|
2161
|
-
name,
|
|
2162
|
-
title,
|
|
2163
|
-
description,
|
|
2164
|
-
libKey,
|
|
2165
|
-
suiteName: _suiteName,
|
|
2166
|
-
components,
|
|
2167
|
-
componentAliases,
|
|
2168
|
-
getPostContent
|
|
2169
|
-
} = config;
|
|
2170
|
-
return new UIAgentTool(
|
|
2171
|
-
name,
|
|
2172
|
-
{
|
|
2173
|
-
title,
|
|
2174
|
-
description,
|
|
2175
|
-
requiredAccess: config.requiredAccess,
|
|
2176
|
-
inputSchema: {
|
|
2177
|
-
query: z4.string().describe("The query to search for."),
|
|
2178
|
-
component: z4.enum(components).describe(
|
|
2179
|
-
"The component to search for. If not specified, use General."
|
|
2180
|
-
)
|
|
2181
|
-
}
|
|
2182
|
-
},
|
|
2183
|
-
async ({ query, component }, { _meta }) => {
|
|
2184
|
-
log("Code Assistant called with:", { query, component });
|
|
2185
|
-
let resolvedComponent = component;
|
|
2186
|
-
if (componentAliases) {
|
|
2187
|
-
const alias = componentAliases[component];
|
|
2188
|
-
if (alias) {
|
|
2189
|
-
resolvedComponent = alias;
|
|
2190
|
-
}
|
|
2191
|
-
}
|
|
2192
|
-
try {
|
|
2193
|
-
const response = await contextApi2.query({
|
|
2194
|
-
query,
|
|
2195
|
-
component: resolvedComponent?.toLowerCase() ?? "general",
|
|
2196
|
-
lib_name: libKey,
|
|
2197
|
-
text_matches_count: 3,
|
|
2198
|
-
code_matches_count: 0,
|
|
2199
|
-
allowed_types: ["documentation"]
|
|
2200
|
-
}, { _meta });
|
|
2201
|
-
const cleanedValues = response.values.map(
|
|
2202
|
-
(val) => val.replace(/\0/g, "")
|
|
2203
|
-
);
|
|
2204
|
-
const postContent = getPostContent?.({ component }) ?? "";
|
|
2205
|
-
const combinedResponse = `${cleanedValues.join("\n\n")}
|
|
2206
|
-
|
|
2207
|
-
${postContent}`;
|
|
2208
|
-
return {
|
|
2209
|
-
content: [
|
|
2210
|
-
{
|
|
2211
|
-
type: "text",
|
|
2212
|
-
text: combinedResponse
|
|
2213
|
-
}
|
|
2214
|
-
]
|
|
2215
|
-
};
|
|
2216
|
-
} catch (error) {
|
|
2217
|
-
throw getGrpcError(error);
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
2220
|
-
);
|
|
2221
|
-
}
|
|
2222
|
-
function createAccessibilityAssistantTool(config, contextApi2) {
|
|
2223
|
-
const {
|
|
2224
|
-
name,
|
|
2225
|
-
title,
|
|
2226
|
-
description,
|
|
2227
|
-
libKey,
|
|
2228
|
-
suiteName: _suiteName,
|
|
2229
|
-
components,
|
|
2230
|
-
componentAliases
|
|
2231
|
-
} = config;
|
|
2232
|
-
return new UIAgentTool(
|
|
2233
|
-
name,
|
|
2234
|
-
{
|
|
2235
|
-
title,
|
|
2236
|
-
description,
|
|
2237
|
-
requiredAccess: config.requiredAccess,
|
|
2238
|
-
inputSchema: {
|
|
2239
|
-
query: z4.string().describe("The query to search for."),
|
|
2240
|
-
component: z4.enum(components).describe(
|
|
2241
|
-
"The component to search for. If not specified, use General."
|
|
2242
|
-
),
|
|
2243
|
-
includeGeneralGuidelines: z4.boolean().default(false).describe(
|
|
2244
|
-
"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."
|
|
2245
|
-
)
|
|
2246
|
-
}
|
|
2247
|
-
},
|
|
2248
|
-
async ({ query, component, includeGeneralGuidelines }, { _meta }) => {
|
|
2249
|
-
log("Accessibility Assistant called with:", {
|
|
2250
|
-
query,
|
|
2251
|
-
component,
|
|
2252
|
-
includeGeneralGuidelines
|
|
2253
|
-
});
|
|
2254
|
-
let resolvedComponent = component;
|
|
2255
|
-
if (componentAliases) {
|
|
2256
|
-
const alias = componentAliases[component];
|
|
2257
|
-
if (alias) {
|
|
2258
|
-
resolvedComponent = alias;
|
|
2259
|
-
}
|
|
2260
|
-
}
|
|
2261
|
-
try {
|
|
2262
|
-
let finalResponse = "";
|
|
2263
|
-
if (includeGeneralGuidelines) {
|
|
2264
|
-
const generalGuidelines = getAccessibilityGuidelines();
|
|
2265
|
-
finalResponse += "# WCAG 2.2 Level AA General Accessibility Guidelines\n\n";
|
|
2266
|
-
finalResponse += generalGuidelines;
|
|
2267
|
-
finalResponse += "\n\n---\n\n";
|
|
2268
|
-
}
|
|
2269
|
-
const response = await contextApi2.getApiRefMatches({
|
|
2270
|
-
query,
|
|
2271
|
-
component: resolvedComponent?.toLowerCase() ?? "general",
|
|
2272
|
-
lib_name: libKey,
|
|
2273
|
-
filters_json: '{"type":{"$in":["accessibility"]}}'
|
|
2274
|
-
}, { _meta });
|
|
2275
|
-
const cleanedValues = response.values.map(
|
|
2276
|
-
(val) => val.replace(/\0/g, "")
|
|
2277
|
-
);
|
|
2278
|
-
const formattedValues = cleanedValues.map(
|
|
2279
|
-
(val) => formatApiRefItemFromJson(val, resolvedComponent?.toLowerCase() ?? "general")
|
|
2280
|
-
);
|
|
2281
|
-
const componentResult = formattedValues.join("\n\n");
|
|
2282
|
-
if (componentResult) {
|
|
2283
|
-
if (includeGeneralGuidelines) {
|
|
2284
|
-
finalResponse += "# Component-Specific Accessibility Information\n\n";
|
|
2285
|
-
}
|
|
2286
|
-
finalResponse += componentResult;
|
|
2287
|
-
} else if (!includeGeneralGuidelines) {
|
|
2288
|
-
finalResponse = "No component-specific accessibility guidelines found.";
|
|
2289
|
-
}
|
|
2290
|
-
return {
|
|
2291
|
-
content: [
|
|
2292
|
-
{
|
|
2293
|
-
type: "text",
|
|
2294
|
-
text: finalResponse
|
|
2295
|
-
}
|
|
2296
|
-
]
|
|
2297
|
-
};
|
|
2298
|
-
} catch (error) {
|
|
2299
|
-
throw getGrpcError(error);
|
|
2300
|
-
}
|
|
2301
|
-
}
|
|
2302
|
-
);
|
|
2303
|
-
}
|
|
2304
|
-
function getGrpcError(error) {
|
|
2305
|
-
const errorObj = error;
|
|
2306
|
-
if (errorObj.code === 16 /* UNAUTHENTICATED */) {
|
|
2307
|
-
return new Error(
|
|
2308
|
-
"Error: You are not authenticated. Please verify the Telerik License Key provided is valid."
|
|
2309
|
-
);
|
|
2310
|
-
} else if (errorObj.code === 8 /* RESOURCE_EXHAUSTED */) {
|
|
2311
|
-
return new Error(
|
|
2312
|
-
`Error: You have exceeded the extension quota. Upgrade to subscription licensing to unlock full access. Message: ${errorObj.message}.`
|
|
2313
|
-
);
|
|
2314
|
-
} else if (errorObj.code === 7 /* PERMISSION_DENIED */) {
|
|
2315
|
-
return new Error(
|
|
2316
|
-
"Error: You do not have permission to access this resource. Please verify that you have a valid license."
|
|
2317
|
-
);
|
|
2318
|
-
} else {
|
|
2319
|
-
return new Error(
|
|
2320
|
-
`Error: An error occurred while calling the service. Please try again later.
|
|
2321
|
-
|
|
2322
|
-
Error Code: ${errorObj.code} Error Message: ${errorObj.message}`
|
|
2323
|
-
);
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
561
|
+
${g}
|
|
562
|
+
\`\`\`
|
|
563
|
+
`:"No CSS variables were generated for the given prompt."}]}})}function ve(e,t){let{name:s,title:o,description:n,libKey:r,getPostContent:a}=e;return new C(s,{title:o,description:n,requiredAccess:e.requiredAccess,inputSchema:{query:v.string().describe("A search query for finding icons. Be specific about the icon purpose, style, or action."),limit:v.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:g})=>{m("Icon Search called with:",{query:i,limit:d});try{let b=await t.queryIconsSearch({query:i,limit:d*100},{_meta:g}),h=a?.()??"";return{content:[{type:"text",text:`${b.values.join(`
|
|
2326
564
|
|
|
2327
|
-
|
|
2328
|
-
var FigmaAPIError = class extends Error {
|
|
2329
|
-
constructor(status, body) {
|
|
2330
|
-
super(`Figma API error ${status}: ${body}`);
|
|
2331
|
-
this.status = status;
|
|
2332
|
-
this.body = body;
|
|
2333
|
-
this.name = "FigmaAPIError";
|
|
2334
|
-
}
|
|
2335
|
-
};
|
|
565
|
+
`)}
|
|
2336
566
|
|
|
2337
|
-
|
|
2338
|
-
var FigmaClient = class {
|
|
2339
|
-
constructor(apiKey) {
|
|
2340
|
-
this.retryConfig = {
|
|
2341
|
-
maxRetries: 3,
|
|
2342
|
-
baseDelayMs: 1e3,
|
|
2343
|
-
maxDelayMs: 3e4
|
|
2344
|
-
};
|
|
2345
|
-
this.apiKey = apiKey;
|
|
2346
|
-
}
|
|
2347
|
-
/**
|
|
2348
|
-
* Fetch file metadata including node and component counts
|
|
2349
|
-
*/
|
|
2350
|
-
async getFileMeta(fileKey) {
|
|
2351
|
-
const fileResponse = await this.getFile(fileKey, { depth: 1 });
|
|
2352
|
-
const counts = this.countNodesAndComponents(fileResponse.document);
|
|
2353
|
-
return {
|
|
2354
|
-
nodeCount: counts.nodes,
|
|
2355
|
-
componentCount: counts.components
|
|
2356
|
-
};
|
|
2357
|
-
}
|
|
2358
|
-
/**
|
|
2359
|
-
* Fetch a specific file with optional depth parameter
|
|
2360
|
-
*/
|
|
2361
|
-
async getFile(fileKey, options) {
|
|
2362
|
-
const url = this.buildFileUrl(fileKey, options);
|
|
2363
|
-
return this.fetchWithRetry(url);
|
|
2364
|
-
}
|
|
2365
|
-
/**
|
|
2366
|
-
* Fetch specific nodes by ID
|
|
2367
|
-
*/
|
|
2368
|
-
async getNodes(fileKey, nodeIds, options) {
|
|
2369
|
-
const url = this.buildNodesUrl(fileKey, nodeIds, options);
|
|
2370
|
-
return this.fetchWithRetry(url);
|
|
2371
|
-
}
|
|
2372
|
-
/**
|
|
2373
|
-
* Get export URLs for node images
|
|
2374
|
-
*/
|
|
2375
|
-
async getImages(fileKey, nodeIds, options) {
|
|
2376
|
-
const url = this.buildImagesUrl(fileKey, nodeIds, options);
|
|
2377
|
-
return this.fetchWithRetry(url);
|
|
2378
|
-
}
|
|
2379
|
-
/**
|
|
2380
|
-
* Get download URLs for embedded image fills
|
|
2381
|
-
* Returns a map of imageRef hashes to temporary S3 download URLs
|
|
2382
|
-
*/
|
|
2383
|
-
async getImageFills(fileKey) {
|
|
2384
|
-
const url = `https://api.figma.com/v1/files/${fileKey}/images`;
|
|
2385
|
-
return this.fetchWithRetry(url);
|
|
2386
|
-
}
|
|
2387
|
-
/**
|
|
2388
|
-
* Core fetch method with retry logic
|
|
2389
|
-
*/
|
|
2390
|
-
async fetchWithRetry(url) {
|
|
2391
|
-
let lastError = null;
|
|
2392
|
-
for (let attempt = 0; attempt < this.retryConfig.maxRetries; attempt++) {
|
|
2393
|
-
try {
|
|
2394
|
-
const response = await fetch(url, {
|
|
2395
|
-
headers: {
|
|
2396
|
-
"X-Figma-Token": this.apiKey,
|
|
2397
|
-
"Content-Type": "application/json"
|
|
2398
|
-
}
|
|
2399
|
-
});
|
|
2400
|
-
if (response.status === 429) {
|
|
2401
|
-
const retryAfter = response.headers.get("Retry-After");
|
|
2402
|
-
const delayMs = retryAfter ? parseInt(retryAfter) * 1e3 : this.calculateBackoff(attempt);
|
|
2403
|
-
await this.sleep(delayMs);
|
|
2404
|
-
continue;
|
|
2405
|
-
}
|
|
2406
|
-
if (!response.ok) {
|
|
2407
|
-
const body = await response.text();
|
|
2408
|
-
throw new FigmaAPIError(response.status, body);
|
|
2409
|
-
}
|
|
2410
|
-
return await response.json();
|
|
2411
|
-
} catch (err) {
|
|
2412
|
-
lastError = err;
|
|
2413
|
-
if (err instanceof FigmaAPIError && err.status >= 400 && err.status < 500) {
|
|
2414
|
-
throw err;
|
|
2415
|
-
}
|
|
2416
|
-
if (attempt < this.retryConfig.maxRetries - 1) {
|
|
2417
|
-
await this.sleep(this.calculateBackoff(attempt));
|
|
2418
|
-
}
|
|
2419
|
-
}
|
|
2420
|
-
}
|
|
2421
|
-
throw lastError ?? new Error("Max retries exceeded");
|
|
2422
|
-
}
|
|
2423
|
-
/**
|
|
2424
|
-
* Calculate exponential backoff with jitter
|
|
2425
|
-
*/
|
|
2426
|
-
calculateBackoff(attempt) {
|
|
2427
|
-
const delay = this.retryConfig.baseDelayMs * Math.pow(2, attempt);
|
|
2428
|
-
const jitter = Math.random() * 0.3 * delay;
|
|
2429
|
-
return Math.min(delay + jitter, this.retryConfig.maxDelayMs);
|
|
2430
|
-
}
|
|
2431
|
-
sleep(ms) {
|
|
2432
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2433
|
-
}
|
|
2434
|
-
buildFileUrl(fileKey, options) {
|
|
2435
|
-
const base = `https://api.figma.com/v1/files/${fileKey}`;
|
|
2436
|
-
const params = new URLSearchParams();
|
|
2437
|
-
if (options?.depth) {
|
|
2438
|
-
params.set("depth", options.depth.toString());
|
|
2439
|
-
}
|
|
2440
|
-
return params.toString() ? `${base}?${params}` : base;
|
|
2441
|
-
}
|
|
2442
|
-
buildNodesUrl(fileKey, nodeIds, options) {
|
|
2443
|
-
const base = `https://api.figma.com/v1/files/${fileKey}/nodes`;
|
|
2444
|
-
const params = new URLSearchParams();
|
|
2445
|
-
params.set("ids", nodeIds.join(","));
|
|
2446
|
-
if (options?.depth) {
|
|
2447
|
-
params.set("depth", options.depth.toString());
|
|
2448
|
-
}
|
|
2449
|
-
return `${base}?${params}`;
|
|
2450
|
-
}
|
|
2451
|
-
buildImagesUrl(fileKey, nodeIds, options) {
|
|
2452
|
-
const base = `https://api.figma.com/v1/images/${fileKey}`;
|
|
2453
|
-
const params = new URLSearchParams();
|
|
2454
|
-
params.set("ids", nodeIds.join(","));
|
|
2455
|
-
if (options?.format) params.set("format", options.format);
|
|
2456
|
-
if (options?.scale) params.set("scale", options.scale.toString());
|
|
2457
|
-
return `${base}?${params}`;
|
|
2458
|
-
}
|
|
2459
|
-
/**
|
|
2460
|
-
* Recursively count nodes and components in the document tree
|
|
2461
|
-
*/
|
|
2462
|
-
countNodesAndComponents(node) {
|
|
2463
|
-
let nodes = 1;
|
|
2464
|
-
let components = node.type === "COMPONENT" || node.type === "COMPONENT_SET" ? 1 : 0;
|
|
2465
|
-
if (node.children) {
|
|
2466
|
-
for (const child of node.children) {
|
|
2467
|
-
const childCounts = this.countNodesAndComponents(child);
|
|
2468
|
-
nodes += childCounts.nodes;
|
|
2469
|
-
components += childCounts.components;
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
return { nodes, components };
|
|
2473
|
-
}
|
|
2474
|
-
};
|
|
567
|
+
${h}`}]}}catch(b){throw P(b)}})}function ke(e,t){let{name:s,title:o,description:n,libKey:r,suiteName:a,components:i,componentAliases:d,getPostContent:g}=e;return new C(s,{title:o,description:n,requiredAccess:e.requiredAccess,inputSchema:{query:v.string().describe("The query to search for."),component:v.enum(i).describe("The component to search for. If not specified, use General.")}},async({query:b,component:h},{_meta:f})=>{m("Code Assistant called with:",{query:b,component:h});let p=h;if(d){let c=d[h];c&&(p=c)}try{let y=(await t.query({query:b,component:p?.toLowerCase()??"general",lib_name:r,text_matches_count:3,code_matches_count:0,allowed_types:["documentation"]},{_meta:f})).values.map(S=>S.replace(/\0/g,"")),A=g?.({component:h})??"";return{content:[{type:"text",text:`${y.join(`
|
|
2475
568
|
|
|
2476
|
-
|
|
2477
|
-
function parseFigmaUrl(url) {
|
|
2478
|
-
const invalidResult = {
|
|
2479
|
-
fileKey: "",
|
|
2480
|
-
type: "unknown",
|
|
2481
|
-
isDevMode: false,
|
|
2482
|
-
isValid: false
|
|
2483
|
-
};
|
|
2484
|
-
if (!url || typeof url !== "string") {
|
|
2485
|
-
return invalidResult;
|
|
2486
|
-
}
|
|
2487
|
-
let parsed;
|
|
2488
|
-
try {
|
|
2489
|
-
parsed = new URL(url.trim());
|
|
2490
|
-
} catch {
|
|
2491
|
-
return invalidResult;
|
|
2492
|
-
}
|
|
2493
|
-
const validDomains = ["figma.com", "www.figma.com"];
|
|
2494
|
-
if (!validDomains.includes(parsed.hostname)) {
|
|
2495
|
-
return invalidResult;
|
|
2496
|
-
}
|
|
2497
|
-
const pathParts = parsed.pathname.split("/").filter(Boolean);
|
|
2498
|
-
if (pathParts.length < 2) {
|
|
2499
|
-
return invalidResult;
|
|
2500
|
-
}
|
|
2501
|
-
const typeMap = {
|
|
2502
|
-
file: "file",
|
|
2503
|
-
design: "design",
|
|
2504
|
-
proto: "proto",
|
|
2505
|
-
board: "board"
|
|
2506
|
-
};
|
|
2507
|
-
const type = typeMap[pathParts[0]] || "unknown";
|
|
2508
|
-
const fileKey = pathParts[1];
|
|
2509
|
-
if (!/^[a-zA-Z0-9]+$/.test(fileKey)) {
|
|
2510
|
-
return invalidResult;
|
|
2511
|
-
}
|
|
2512
|
-
const fileName = pathParts[2] ? decodeURIComponent(pathParts[2]).replace(/-/g, " ") : void 0;
|
|
2513
|
-
const nodeIdParam = parsed.searchParams.get("node-id");
|
|
2514
|
-
let nodeId;
|
|
2515
|
-
let nodeIds;
|
|
2516
|
-
if (nodeIdParam) {
|
|
2517
|
-
const rawIds = nodeIdParam.split(",").map((id) => id.trim()).filter(Boolean);
|
|
2518
|
-
nodeIds = rawIds.map((id) => id.replace(/-/g, ":"));
|
|
2519
|
-
nodeId = nodeIds[0];
|
|
2520
|
-
}
|
|
2521
|
-
const branchKey = parsed.searchParams.get("t") ?? void 0;
|
|
2522
|
-
const isDevMode = parsed.searchParams.get("m") === "dev";
|
|
2523
|
-
return {
|
|
2524
|
-
fileKey,
|
|
2525
|
-
fileName,
|
|
2526
|
-
nodeId,
|
|
2527
|
-
nodeIds,
|
|
2528
|
-
type,
|
|
2529
|
-
branchKey,
|
|
2530
|
-
isDevMode,
|
|
2531
|
-
isValid: true
|
|
2532
|
-
};
|
|
2533
|
-
}
|
|
569
|
+
`)}
|
|
2534
570
|
|
|
2535
|
-
|
|
2536
|
-
var NodeFetcher = class {
|
|
2537
|
-
constructor(client) {
|
|
2538
|
-
this.client = client;
|
|
2539
|
-
}
|
|
2540
|
-
/**
|
|
2541
|
-
* Fetch a design starting from a file or specific node(s)
|
|
2542
|
-
*
|
|
2543
|
-
* @param fileKey - The Figma file key
|
|
2544
|
-
* @param nodeIds - Optional node ID(s) - can be string or string[]
|
|
2545
|
-
* @param options - Fetch options including depth
|
|
2546
|
-
* @returns Fetch result with root node and stats
|
|
2547
|
-
*/
|
|
2548
|
-
async fetch(fileKey, nodeIds, options = {}) {
|
|
2549
|
-
const initialDepth = options.initialDepth ?? 10;
|
|
2550
|
-
const fetchImages = options.fetchImages ?? true;
|
|
2551
|
-
const imageFormat = options.imageFormat ?? "png";
|
|
2552
|
-
const imageScale = options.imageScale ?? 2;
|
|
2553
|
-
const stats = {
|
|
2554
|
-
totalNodesFetched: 0,
|
|
2555
|
-
apiCallsMade: 0,
|
|
2556
|
-
imagesFetched: 0
|
|
2557
|
-
};
|
|
2558
|
-
let nodeIdArray;
|
|
2559
|
-
if (!nodeIds) {
|
|
2560
|
-
nodeIdArray = [];
|
|
2561
|
-
} else if (typeof nodeIds === "string") {
|
|
2562
|
-
nodeIdArray = [nodeIds];
|
|
2563
|
-
} else {
|
|
2564
|
-
nodeIdArray = nodeIds;
|
|
2565
|
-
}
|
|
2566
|
-
let rootNode;
|
|
2567
|
-
let fetchedNodes = [];
|
|
2568
|
-
if (nodeIdArray.length > 0) {
|
|
2569
|
-
const response = await this.client.getNodes(fileKey, nodeIdArray, { depth: initialDepth });
|
|
2570
|
-
stats.apiCallsMade++;
|
|
2571
|
-
for (const nodeId of nodeIdArray) {
|
|
2572
|
-
const nodeData = response.nodes[nodeId]?.document;
|
|
2573
|
-
if (!nodeData) {
|
|
2574
|
-
throw new Error(`Node ${nodeId} not found`);
|
|
2575
|
-
}
|
|
2576
|
-
fetchedNodes.push(nodeData);
|
|
2577
|
-
}
|
|
2578
|
-
if (fetchedNodes.length === 1) {
|
|
2579
|
-
rootNode = fetchedNodes[0];
|
|
2580
|
-
} else {
|
|
2581
|
-
rootNode = this.createContainerNode(fetchedNodes);
|
|
2582
|
-
}
|
|
2583
|
-
} else {
|
|
2584
|
-
const response = await this.client.getFile(fileKey, { depth: initialDepth });
|
|
2585
|
-
stats.apiCallsMade++;
|
|
2586
|
-
rootNode = response.document;
|
|
2587
|
-
fetchedNodes = [rootNode];
|
|
2588
|
-
}
|
|
2589
|
-
stats.totalNodesFetched += this.countNodes(rootNode);
|
|
2590
|
-
const images = [];
|
|
2591
|
-
if (fetchImages && nodeIdArray.length > 0) {
|
|
2592
|
-
try {
|
|
2593
|
-
const imageResult = await this.fetchNodeImages(
|
|
2594
|
-
fileKey,
|
|
2595
|
-
nodeIdArray,
|
|
2596
|
-
fetchedNodes,
|
|
2597
|
-
{ format: imageFormat, scale: imageScale }
|
|
2598
|
-
);
|
|
2599
|
-
images.push(...imageResult.images);
|
|
2600
|
-
stats.apiCallsMade += imageResult.apiCalls;
|
|
2601
|
-
stats.imagesFetched = images.length;
|
|
2602
|
-
} catch (error) {
|
|
2603
|
-
console.warn("Failed to fetch images:", error);
|
|
2604
|
-
}
|
|
2605
|
-
}
|
|
2606
|
-
return {
|
|
2607
|
-
rootNode,
|
|
2608
|
-
fetchedNodes,
|
|
2609
|
-
images,
|
|
2610
|
-
stats
|
|
2611
|
-
};
|
|
2612
|
-
}
|
|
2613
|
-
/**
|
|
2614
|
-
* Fetch and download images for specified nodes
|
|
2615
|
-
*/
|
|
2616
|
-
async fetchNodeImages(fileKey, nodeIds, nodes, options) {
|
|
2617
|
-
const imageResponse = await this.client.getImages(fileKey, nodeIds, options);
|
|
2618
|
-
let apiCalls = 1;
|
|
2619
|
-
const images = [];
|
|
2620
|
-
for (let i = 0; i < nodeIds.length; i++) {
|
|
2621
|
-
const nodeId = nodeIds[i];
|
|
2622
|
-
const imageUrl = imageResponse.images[nodeId];
|
|
2623
|
-
if (imageUrl) {
|
|
2624
|
-
try {
|
|
2625
|
-
const imageData = await this.downloadImage(imageUrl, options.format);
|
|
2626
|
-
const node = nodes[i];
|
|
2627
|
-
images.push({
|
|
2628
|
-
nodeId,
|
|
2629
|
-
nodeName: node?.name || "Unknown",
|
|
2630
|
-
data: imageData,
|
|
2631
|
-
mimeType: this.getMimeType(options.format),
|
|
2632
|
-
url: imageUrl
|
|
2633
|
-
});
|
|
2634
|
-
} catch (error) {
|
|
2635
|
-
console.warn(`Failed to download image for node ${nodeId}:`, error);
|
|
2636
|
-
}
|
|
2637
|
-
}
|
|
2638
|
-
}
|
|
2639
|
-
return { images, apiCalls };
|
|
2640
|
-
}
|
|
2641
|
-
/**
|
|
2642
|
-
* Download an image from a URL and convert to base64
|
|
2643
|
-
*/
|
|
2644
|
-
async downloadImage(url, format) {
|
|
2645
|
-
const response = await fetch(url);
|
|
2646
|
-
if (!response.ok) {
|
|
2647
|
-
throw new Error(`Failed to download image: ${response.statusText}`);
|
|
2648
|
-
}
|
|
2649
|
-
if (format === "svg") {
|
|
2650
|
-
const svgText = await response.text();
|
|
2651
|
-
return Buffer.from(svgText, "utf-8").toString("base64");
|
|
2652
|
-
} else {
|
|
2653
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
2654
|
-
return Buffer.from(arrayBuffer).toString("base64");
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
/**
|
|
2658
|
-
* Get MIME type for image format
|
|
2659
|
-
*/
|
|
2660
|
-
getMimeType(format) {
|
|
2661
|
-
switch (format) {
|
|
2662
|
-
case "png":
|
|
2663
|
-
return "image/png";
|
|
2664
|
-
case "jpg":
|
|
2665
|
-
return "image/jpeg";
|
|
2666
|
-
case "svg":
|
|
2667
|
-
return "image/svg+xml";
|
|
2668
|
-
default:
|
|
2669
|
-
return "image/png";
|
|
2670
|
-
}
|
|
2671
|
-
}
|
|
2672
|
-
/**
|
|
2673
|
-
* Create a synthetic container node that wraps multiple nodes
|
|
2674
|
-
*/
|
|
2675
|
-
createContainerNode(nodes) {
|
|
2676
|
-
return {
|
|
2677
|
-
id: "container-" + Date.now(),
|
|
2678
|
-
name: "Multi-Node Container",
|
|
2679
|
-
type: "GROUP",
|
|
2680
|
-
visible: true,
|
|
2681
|
-
children: nodes
|
|
2682
|
-
};
|
|
2683
|
-
}
|
|
2684
|
-
/**
|
|
2685
|
-
* Count total nodes in a tree
|
|
2686
|
-
*/
|
|
2687
|
-
countNodes(node) {
|
|
2688
|
-
let count = 1;
|
|
2689
|
-
if (node.children) {
|
|
2690
|
-
for (const child of node.children) {
|
|
2691
|
-
count += this.countNodes(child);
|
|
2692
|
-
}
|
|
2693
|
-
}
|
|
2694
|
-
return count;
|
|
2695
|
-
}
|
|
2696
|
-
};
|
|
571
|
+
${A}`}]}}catch(c){throw P(c)}})}function Ae(e,t){let{name:s,title:o,description:n,libKey:r,suiteName:a,components:i,componentAliases:d}=e;return new C(s,{title:o,description:n,requiredAccess:e.requiredAccess,inputSchema:{query:v.string().describe("The query to search for."),component:v.enum(i).describe("The component to search for. If not specified, use General."),includeGeneralGuidelines:v.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:g,component:b,includeGeneralGuidelines:h},{_meta:f})=>{m("Accessibility Assistant called with:",{query:g,component:b,includeGeneralGuidelines:h});let p=b;if(d){let c=d[b];c&&(p=c)}try{let c="";if(h){let x=de();c+=`# WCAG 2.2 Level AA General Accessibility Guidelines
|
|
2697
572
|
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
requiredAccess
|
|
2704
|
-
}, contextApi2) {
|
|
2705
|
-
return new UIAgentTool(
|
|
2706
|
-
name,
|
|
2707
|
-
{
|
|
2708
|
-
title: "Figma Design to Code",
|
|
2709
|
-
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.",
|
|
2710
|
-
inputSchema: {
|
|
2711
|
-
url: z5.string().describe(
|
|
2712
|
-
"Figma file or node URL (e.g., https://www.figma.com/file/...)"
|
|
2713
|
-
).optional(),
|
|
2714
|
-
fileKey: z5.string().describe("Figma file key (alternative to URL)").optional(),
|
|
2715
|
-
nodeIds: z5.array(z5.string()).describe("Array of specific node IDs to fetch (alternative to URL)").optional(),
|
|
2716
|
-
depth: z5.number().min(1).max(20).default(10).describe("Initial fetch depth (1-20, default: 10)")
|
|
2717
|
-
},
|
|
2718
|
-
requiredAccess
|
|
2719
|
-
},
|
|
2720
|
-
async ({ url, fileKey, nodeIds, depth }) => {
|
|
2721
|
-
const client = new FigmaClient(figmaApiKey);
|
|
2722
|
-
const fetcher = new NodeFetcher(client);
|
|
2723
|
-
let fileKeyToUse = fileKey;
|
|
2724
|
-
let nodeIdsToUse;
|
|
2725
|
-
if (fileKeyToUse) {
|
|
2726
|
-
if (nodeIds && nodeIds.length > 0) {
|
|
2727
|
-
nodeIdsToUse = nodeIds.length === 1 ? nodeIds[0] : nodeIds;
|
|
2728
|
-
}
|
|
2729
|
-
} else if (url) {
|
|
2730
|
-
const parsed = parseFigmaUrl(url);
|
|
2731
|
-
if (!parsed.isValid || !parsed.fileKey) {
|
|
2732
|
-
throw new Error(
|
|
2733
|
-
"Invalid Figma URL. Please provide a valid Figma file or frame URL."
|
|
2734
|
-
);
|
|
2735
|
-
}
|
|
2736
|
-
fileKeyToUse = parsed.fileKey;
|
|
2737
|
-
if (parsed.nodeId) {
|
|
2738
|
-
nodeIdsToUse = parsed.nodeId;
|
|
2739
|
-
}
|
|
2740
|
-
} else {
|
|
2741
|
-
throw new Error("Please provide either a Figma URL, fileKey, or both.");
|
|
2742
|
-
}
|
|
2743
|
-
const fetchResult = await fetcher.fetch(fileKeyToUse, nodeIdsToUse, {
|
|
2744
|
-
initialDepth: depth,
|
|
2745
|
-
fetchImages: true,
|
|
2746
|
-
imageFormat: "png",
|
|
2747
|
-
imageScale: 2
|
|
2748
|
-
});
|
|
2749
|
-
const resultJson = {
|
|
2750
|
-
name: fetchResult.rootNode.name,
|
|
2751
|
-
type: fetchResult.rootNode.type,
|
|
2752
|
-
rootNode: fetchResult.rootNode,
|
|
2753
|
-
fetchedNodes: fetchResult.fetchedNodes,
|
|
2754
|
-
meta: {
|
|
2755
|
-
fileKey,
|
|
2756
|
-
nodeIds
|
|
2757
|
-
}
|
|
2758
|
-
};
|
|
2759
|
-
let backendResponse;
|
|
2760
|
-
try {
|
|
2761
|
-
const nodeJsons = fetchResult.fetchedNodes.map(
|
|
2762
|
-
(node) => JSON.stringify(node)
|
|
2763
|
-
);
|
|
2764
|
-
backendResponse = await contextApi2.processFigmaDesign({
|
|
2765
|
-
node_jsons: nodeJsons
|
|
2766
|
-
});
|
|
2767
|
-
} catch (error) {
|
|
2768
|
-
console.error("Backend processing failed:", error);
|
|
2769
|
-
return {
|
|
2770
|
-
content: [
|
|
2771
|
-
{
|
|
2772
|
-
type: "text",
|
|
2773
|
-
text: JSON.stringify(
|
|
2774
|
-
{
|
|
2775
|
-
error: {
|
|
2776
|
-
message: `Backend processing failed: ${error.message}`,
|
|
2777
|
-
code: error.code || "UNKNOWN"
|
|
2778
|
-
},
|
|
2779
|
-
figma_data: resultJson
|
|
2780
|
-
},
|
|
2781
|
-
null,
|
|
2782
|
-
2
|
|
2783
|
-
)
|
|
2784
|
-
}
|
|
2785
|
-
]
|
|
2786
|
-
};
|
|
2787
|
-
}
|
|
2788
|
-
const content = [];
|
|
2789
|
-
content.push({
|
|
2790
|
-
type: "text",
|
|
2791
|
-
text: `# Figma Design Extraction Results
|
|
2792
|
-
Successfully fetched design data for file key ${fileKeyToUse} with for nodes [${nodeIds?.join(", ")}].
|
|
2793
|
-
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:`
|
|
2794
|
-
});
|
|
2795
|
-
backendResponse.layout_pseudo_codes.forEach((layoutCode, index) => {
|
|
2796
|
-
const [nodeName, nodeId] = ((index2) => {
|
|
2797
|
-
const node = fetchResult.fetchedNodes[index2];
|
|
2798
|
-
return node ? [node.name, node.id] : ["Unknown Node", "unknown_id"];
|
|
2799
|
-
})(index);
|
|
2800
|
-
content.push({
|
|
2801
|
-
type: "text",
|
|
2802
|
-
text: `## Psuedo-code Layout - Node: ${nodeName} (${nodeId})
|
|
2803
|
-
|
|
2804
|
-
` + layoutCode,
|
|
2805
|
-
_meta: {
|
|
2806
|
-
description: `Psuedo-code Layout - Node: ${nodeName} (${nodeId})`
|
|
2807
|
-
},
|
|
2808
|
-
annotations: {
|
|
2809
|
-
audience: ["assistant"]
|
|
2810
|
-
}
|
|
2811
|
-
});
|
|
2812
|
-
});
|
|
2813
|
-
content.push({
|
|
2814
|
-
type: "text",
|
|
2815
|
-
text: `## Design Tokens - File: ${fileKey} for Nodes: [${nodeIds?.join(", ")}]
|
|
2816
|
-
|
|
2817
|
-
` + backendResponse.design_tokens,
|
|
2818
|
-
_meta: {
|
|
2819
|
-
description: `Design Tokens - File: ${fileKey} for Nodes: [${nodeIds?.join(", ")}]`
|
|
2820
|
-
},
|
|
2821
|
-
annotations: {
|
|
2822
|
-
audience: ["assistant"]
|
|
2823
|
-
}
|
|
2824
|
-
});
|
|
2825
|
-
if (fetchResult.images && fetchResult.images.length > 0) {
|
|
2826
|
-
for (const image of fetchResult.images) {
|
|
2827
|
-
content.push({
|
|
2828
|
-
type: "image",
|
|
2829
|
-
data: image.data,
|
|
2830
|
-
mimeType: image.mimeType,
|
|
2831
|
-
_meta: {
|
|
2832
|
-
description: `Design snapshot of ${image.nodeName} (${image.nodeId})`
|
|
2833
|
-
},
|
|
2834
|
-
annotations: {
|
|
2835
|
-
audience: ["assistant"]
|
|
2836
|
-
}
|
|
2837
|
-
});
|
|
2838
|
-
}
|
|
2839
|
-
}
|
|
2840
|
-
content.push({
|
|
2841
|
-
type: "text",
|
|
2842
|
-
text: `# Analysis Instructions and Next Steps
|
|
2843
|
-
|
|
2844
|
-
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.
|
|
2845
|
-
If more design details are needed, consider asking for additional nodes or deeper fetches to gather more information about specific areas of the design.`
|
|
2846
|
-
});
|
|
2847
|
-
return {
|
|
2848
|
-
content
|
|
2849
|
-
};
|
|
2850
|
-
}
|
|
2851
|
-
);
|
|
2852
|
-
}
|
|
573
|
+
`,c+=x,c+=`
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
`}let S=(await t.getApiRefMatches({query:g,component:p?.toLowerCase()??"general",lib_name:r,filters_json:'{"type":{"$in":["accessibility"]}}'},{_meta:f})).values.map(x=>x.replace(/\0/g,"")).map(x=>Ct(x,p?.toLowerCase()??"general")).join(`
|
|
2853
578
|
|
|
2854
|
-
|
|
2855
|
-
var orchestratorToolName = (prefix) => `${prefix}_ui_generator`;
|
|
2856
|
-
var assistantOrchestratorToolName = (prefix) => `${prefix}_assistant`;
|
|
2857
|
-
var layoutAssistantName = (prefix) => `${prefix}_layout_assistant`;
|
|
2858
|
-
var codeAssistantName = (prefix) => `${prefix}_component_assistant`;
|
|
2859
|
-
var styleAssistantName = (prefix) => `${prefix}_style_assistant`;
|
|
2860
|
-
var iconAssistantName = (prefix) => `${prefix}_icon_assistant`;
|
|
2861
|
-
var accessibilityAssistantName = (prefix) => `${prefix}_accessibility_assistant`;
|
|
2862
|
-
var gettingStartedAssistantName = (prefix) => `${prefix}_getting_started_assistant`;
|
|
2863
|
-
var figmaD2CToolName = (prefix) => `${prefix}_figma_d2c`;
|
|
579
|
+
`);return S?(h&&(c+=`# Component-Specific Accessibility Information
|
|
2864
580
|
|
|
2865
|
-
|
|
2866
|
-
|
|
581
|
+
`),c+=S):h||(c="No component-specific accessibility guidelines found."),{content:[{type:"text",text:c}]}}catch(c){throw P(c)}})}function P(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.
|
|
582
|
+
|
|
583
|
+
Error Code: ${t.code} Error Message: ${t.message}`)}var we=e=>`${e}_ui_generator`,Ce=e=>`${e}_assistant`,Se=e=>`${e}_layout_assistant`,Te=e=>`${e}_component_assistant`,xe=e=>`${e}_style_assistant`,Ie=e=>`${e}_icon_assistant`,Ne=e=>`${e}_accessibility_assistant`,Ee=e=>`${e}_getting_started_assistant`;var Pe=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.
|
|
2867
584
|
|
|
2868
585
|
Use the tool when:
|
|
2869
586
|
- Want to build or modify a complete page or section layout
|
|
2870
587
|
- You are creating and applying custom themes via the Kendo Design System
|
|
2871
|
-
- You need guidance on correct ${
|
|
588
|
+
- You need guidance on correct ${e} component selection and configuration
|
|
2872
589
|
- You want to enforce best practices in styling, performance, and accessibility
|
|
2873
590
|
|
|
2874
591
|
Returns:
|
|
2875
|
-
A detailed execution plan with validated tool calls, parameters, and reasoning \u2014 ensuring consistent, high-quality UI generation
|
|
2876
|
-
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.
|
|
592
|
+
A detailed execution plan with validated tool calls, parameters, and reasoning \u2014 ensuring consistent, high-quality UI generation.`,Re=e=>`Provides guidance for discovering and using ${e} components and icons. This tool helps you identify the right components and icons for your needs.
|
|
2877
593
|
|
|
2878
594
|
Use this tool when:
|
|
2879
|
-
- You need to discover which ${
|
|
595
|
+
- You need to discover which ${e} components are suitable for a specific use case
|
|
2880
596
|
- You want to understand component features and capabilities
|
|
2881
597
|
- You need to find appropriate icons for your UI
|
|
2882
598
|
- You want to gather component documentation and examples
|
|
2883
599
|
|
|
2884
600
|
Returns:
|
|
2885
|
-
A focused plan for gathering component documentation and icon suggestions using the Component Assistant and Icon Assistant tools
|
|
2886
|
-
var layoutToolDescription = `Retrieves Progress/Kendo Design System CSS utility classes and styling recommendations based on layout and design requirements.
|
|
601
|
+
A focused plan for gathering component documentation and icon suggestions using the Component Assistant and Icon Assistant tools.`,De=`Retrieves Progress/Kendo Design System CSS utility classes and styling recommendations based on layout and design requirements.
|
|
2887
602
|
Use this tool to find the right CSS utilities for styling Kendo UI components or general web elements.
|
|
2888
603
|
It analyzes the provided design context and returns relevant utility classes with explanations and examples.
|
|
2889
|
-
Best suited for styling questions related to typography, spacing, colors, layout, transforms, and other utilities in the Progress/Kendo Design System
|
|
2890
|
-
var styleToolDescription = `Generates CSS variables using an external style agent based on the user's styling prompt.
|
|
604
|
+
Best suited for styling questions related to typography, spacing, colors, layout, transforms, and other utilities in the Progress/Kendo Design System.`,Oe=`Generates CSS variables using an external style agent based on the user's styling prompt.
|
|
2891
605
|
|
|
2892
606
|
Use this tool when the user wants to:
|
|
2893
607
|
- Update the visual theme of an application
|
|
2894
608
|
- Modify color schemes
|
|
2895
609
|
- Restyle the UI with CSS variables
|
|
2896
610
|
|
|
2897
|
-
The tool outputs a set of CSS variable definitions ready to be applied to style files
|
|
2898
|
-
var iconToolDescription = `Searches for icons in the Telerik Icons library.
|
|
611
|
+
The tool outputs a set of CSS variable definitions ready to be applied to style files.`,Ge=`Searches for icons in the Telerik Icons library.
|
|
2899
612
|
Use this tool when the user needs to find specific icons for UI components or design elements.
|
|
2900
613
|
It supports searching by icon name, category, or keyword and returns matching icons from the Telerik Icons library.
|
|
2901
|
-
|
|
2902
|
-
var codeAssistantToolDescription = (suiteName) => `Provides answers and retrieves official documentation for ${suiteName}.
|
|
614
|
+
`,Le=e=>`Provides answers and retrieves official documentation for ${e}.
|
|
2903
615
|
|
|
2904
616
|
Use this tool when the user asks about:
|
|
2905
|
-
- ${
|
|
617
|
+
- ${e} features or capabilities
|
|
2906
618
|
- Specific components (e.g., Grid, Chart, Editor)
|
|
2907
619
|
- Implementation details, configuration, or best practices
|
|
2908
|
-
- How to use or customize components in ${
|
|
620
|
+
- How to use or customize components in ${e}
|
|
2909
621
|
|
|
2910
622
|
Set the user's full question as the 'query' parameter.
|
|
2911
|
-
If the question refers to a specific ${
|
|
2912
|
-
|
|
2913
|
-
var accessibilityToolDescription = (suiteName) => `Retrieves accessibility guidance for ${suiteName} components with optional general WCAG 2.2 Level AA guidelines.
|
|
623
|
+
If the question refers to a specific ${e} component, include its name in the 'component' parameter.
|
|
624
|
+
`,Ue=e=>`Retrieves accessibility guidance for ${e} components with optional general WCAG 2.2 Level AA guidelines.
|
|
2914
625
|
|
|
2915
626
|
Use this tool when:
|
|
2916
627
|
- You need component-specific accessibility information and API references
|
|
@@ -2928,11 +639,7 @@ Set 'includeGeneralGuidelines=true' ONLY on the first call to include general WC
|
|
|
2928
639
|
Returns:
|
|
2929
640
|
- When includeGeneralGuidelines=true: General WCAG 2.2 Level AA guidelines + component-specific recommendations
|
|
2930
641
|
- When includeGeneralGuidelines=false: Only component-specific accessibility recommendations
|
|
2931
|
-
`;
|
|
2932
|
-
|
|
2933
|
-
// packages/kendo-ui-agent/src/lib/validation/angular-validation-steps.ts
|
|
2934
|
-
var sharedSteps = getSharedValidationSteps("Kendo UI", "Kendo");
|
|
2935
|
-
var ANGULAR_VALIDATION_STEPS = `
|
|
642
|
+
`;var W=E("Kendo UI","Kendo"),z=`
|
|
2936
643
|
### Angular Component Validation
|
|
2937
644
|
Component Structure:
|
|
2938
645
|
- Use proper @Component decorator configuration
|
|
@@ -2940,25 +647,22 @@ Component Structure:
|
|
|
2940
647
|
- Correct selector naming convention (kebab-case)
|
|
2941
648
|
- Appropriate template and style file organization
|
|
2942
649
|
|
|
2943
|
-
${
|
|
650
|
+
${W.SETUP_VALIDATION}
|
|
2944
651
|
- Kendo animations module configured (if animations are used)
|
|
2945
652
|
- Internationalization properly configured for Kendo components
|
|
2946
653
|
|
|
2947
|
-
${
|
|
654
|
+
${W.PERFORMANCE_OPTIMIZATION}
|
|
2948
655
|
- OnPush change detection strategy where appropriate
|
|
2949
656
|
- Efficient trackBy functions for *ngFor with Kendo components
|
|
2950
657
|
- Minimal unnecessary change detection cycles
|
|
2951
658
|
|
|
2952
|
-
${
|
|
659
|
+
${W.THEME_AND_STYLING}
|
|
2953
660
|
- Proper theme switching functionality (if implemented)
|
|
2954
661
|
- Only ONE theme reference exists across angular.json and styles files
|
|
2955
662
|
- Make sure theme import mechanism is consistent with existing project setup
|
|
2956
663
|
|
|
2957
664
|
Accessibility
|
|
2958
|
-
- Accessibility guidelines retrieved and applied to all components`;
|
|
2959
|
-
|
|
2960
|
-
// packages/kendo-ui-agent/src/lib/validation/angular-additional-plan.ts
|
|
2961
|
-
var ANGULAR_ADDITIONAL_PLAN = `**Angular Specific Requirements:**
|
|
665
|
+
- Accessibility guidelines retrieved and applied to all components`;var H=`**Angular Specific Requirements:**
|
|
2962
666
|
|
|
2963
667
|
**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:
|
|
2964
668
|
1. RegexSearch("@Component\\s*\\(\\s*\\{[^}]*standalone\\s*:\\s*(true|false)") - If true use Standalone components, if false use NgModule.
|
|
@@ -2989,11 +693,7 @@ var ANGULAR_ADDITIONAL_PLAN = `**Angular Specific Requirements:**
|
|
|
2989
693
|
2. Match the discovered patterns in all generated code
|
|
2990
694
|
3. Maintain consistent formatting, indentation, and code organization with existing files
|
|
2991
695
|
4. Always use the same theme import mechanism (unless user specifies otherwise)
|
|
2992
|
-
`;
|
|
2993
|
-
|
|
2994
|
-
// packages/kendo-ui-agent/src/lib/validation/react-validation-steps.ts
|
|
2995
|
-
var sharedSteps2 = getSharedValidationSteps("Kendo UI", "KendoReact");
|
|
2996
|
-
var REACT_VALIDATION_STEPS = `
|
|
696
|
+
`;var Y=E("Kendo UI","KendoReact"),Q=`
|
|
2997
697
|
### React Component Validation
|
|
2998
698
|
Component Structure:
|
|
2999
699
|
- Use proper function component patterns with Hooks
|
|
@@ -3001,85 +701,22 @@ Component Structure:
|
|
|
3001
701
|
- Appropriate file organization (components, hooks, utils)
|
|
3002
702
|
- Props interface/type definitions where needed
|
|
3003
703
|
|
|
3004
|
-
${
|
|
704
|
+
${Y.SETUP_VALIDATION}
|
|
3005
705
|
- KendoReact license validation (if required)
|
|
3006
706
|
- Appropriate bundler configuration for KendoReact packages
|
|
3007
707
|
|
|
3008
|
-
${
|
|
708
|
+
${Y.PERFORMANCE_OPTIMIZATION}
|
|
3009
709
|
- React.memo for components that receive stable props
|
|
3010
710
|
- useMemo/useCallback for expensive computations and callbacks
|
|
3011
711
|
- Proper key props for list rendering with KendoReact components
|
|
3012
712
|
|
|
3013
|
-
${
|
|
713
|
+
${Y.THEME_AND_STYLING}
|
|
3014
714
|
- Proper theme switching functionality (if implemented)
|
|
3015
715
|
- Only ONE theme import exists across the application
|
|
3016
716
|
- Make sure theme import mechanism is consistent with existing project setup
|
|
3017
717
|
|
|
3018
718
|
Accessibility
|
|
3019
|
-
- Accessibility guidelines retrieved and applied to all components`;
|
|
3020
|
-
|
|
3021
|
-
// packages/kendo-ui-agent/src/index.ts
|
|
3022
|
-
var Tools = {
|
|
3023
|
-
createOrchestrator: createOrchestratorTool,
|
|
3024
|
-
createAssistantOrchestrator: createAssistantOrchestratorTool,
|
|
3025
|
-
createLayoutAssistant: createLayoutAssistantTool,
|
|
3026
|
-
createStyleAssistant: createStyleAssistantTool,
|
|
3027
|
-
createIconSearch: createIconSearchTool,
|
|
3028
|
-
createCodeAssistant: createCodeAssistantTool,
|
|
3029
|
-
createAccessibilityAssistant: createAccessibilityAssistantTool,
|
|
3030
|
-
createFigmaD2C: createFigmaD2CTool
|
|
3031
|
-
};
|
|
3032
|
-
var ToolNames = {
|
|
3033
|
-
orchestrator: orchestratorToolName,
|
|
3034
|
-
assistantOrchestrator: assistantOrchestratorToolName,
|
|
3035
|
-
layoutAssistant: layoutAssistantName,
|
|
3036
|
-
codeAssistant: codeAssistantName,
|
|
3037
|
-
styleAssistant: styleAssistantName,
|
|
3038
|
-
iconAssistant: iconAssistantName,
|
|
3039
|
-
accessibilityAssistant: accessibilityAssistantName,
|
|
3040
|
-
gettingStartedAssistant: gettingStartedAssistantName,
|
|
3041
|
-
figmaD2C: figmaD2CToolName
|
|
3042
|
-
};
|
|
3043
|
-
var ToolDescriptions = {
|
|
3044
|
-
orchestrator: orchestratorToolDescription,
|
|
3045
|
-
assistantOrchestrator: assistantOrchestratorToolDescription,
|
|
3046
|
-
layoutAssistant: layoutToolDescription,
|
|
3047
|
-
styleAssistant: styleToolDescription,
|
|
3048
|
-
iconAssistant: iconToolDescription,
|
|
3049
|
-
codeAssistant: codeAssistantToolDescription,
|
|
3050
|
-
accessibilityAssistant: accessibilityToolDescription
|
|
3051
|
-
};
|
|
3052
|
-
var Templates = {
|
|
3053
|
-
Orchestrator: {
|
|
3054
|
-
render: renderOrchestratorResponse
|
|
3055
|
-
},
|
|
3056
|
-
Validator: {
|
|
3057
|
-
render: renderValidatorResponse
|
|
3058
|
-
},
|
|
3059
|
-
SharedValidation: {
|
|
3060
|
-
getSteps: getSharedValidationSteps
|
|
3061
|
-
}
|
|
3062
|
-
};
|
|
3063
|
-
var Validation = {
|
|
3064
|
-
Angular: {
|
|
3065
|
-
steps: ANGULAR_VALIDATION_STEPS,
|
|
3066
|
-
additionalPlan: ANGULAR_ADDITIONAL_PLAN
|
|
3067
|
-
},
|
|
3068
|
-
React: {
|
|
3069
|
-
steps: REACT_VALIDATION_STEPS
|
|
3070
|
-
}
|
|
3071
|
-
};
|
|
3072
|
-
var UIAgent = {
|
|
3073
|
-
Tools,
|
|
3074
|
-
ToolNames,
|
|
3075
|
-
ToolDescriptions,
|
|
3076
|
-
Templates,
|
|
3077
|
-
Validation
|
|
3078
|
-
};
|
|
3079
|
-
|
|
3080
|
-
// packages/angular/src/lib/instructions/layout.ts
|
|
3081
|
-
var CODE_ASSISTANT_NAME = UIAgent.ToolNames.codeAssistant("kendo");
|
|
3082
|
-
var getLayoutInstructions = () => `# Kendo Design System Guidelines for ${ANGULAR_SUITE_NAME}
|
|
719
|
+
- Accessibility guidelines retrieved and applied to all components`;var St={createOrchestrator:he,createAssistantOrchestrator:fe,createLayoutAssistant:ye,createStyleAssistant:be,createIconSearch:ve,createCodeAssistant:ke,createAccessibilityAssistant:Ae},Tt={orchestrator:we,assistantOrchestrator:Ce,layoutAssistant:Se,codeAssistant:Te,styleAssistant:xe,iconAssistant:Ie,accessibilityAssistant:Ne,gettingStartedAssistant:Ee},xt={orchestrator:Pe,assistantOrchestrator:Re,layoutAssistant:De,styleAssistant:Oe,iconAssistant:Ge,codeAssistant:Le,accessibilityAssistant:Ue},It={Orchestrator:{render:U},Validator:{render:L},SharedValidation:{getSteps:E}},Nt={Angular:{steps:z,additionalPlan:H},React:{steps:Q}},u={Tools:St,ToolNames:Tt,ToolDescriptions:xt,Templates:It,Validation:Nt};var Et=u.ToolNames.codeAssistant("kendo"),$e=()=>`# Kendo Design System Guidelines for ${l}
|
|
3083
720
|
|
|
3084
721
|
## Setting up Styles/CSS
|
|
3085
722
|
|
|
@@ -3106,17 +743,155 @@ Alternatively, you can also consume them directly from the Unpkg CDN.
|
|
|
3106
743
|
|
|
3107
744
|
## Ready-to-use Layout Components
|
|
3108
745
|
|
|
3109
|
-
In the ${
|
|
746
|
+
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.
|
|
3110
747
|
|
|
3111
|
-
For any Layout component you can also call the ${
|
|
748
|
+
For any Layout component you can also call the ${Et} tool in order to get specific API reference and docs.
|
|
3112
749
|
|
|
3113
|
-
- ${
|
|
750
|
+
- ${l} Card component.
|
|
3114
751
|
- Generally, it is recommended to use 100% width (e.g., \`<kendo-card width="100%">\`)
|
|
3115
752
|
- If needed, use specific width based on the layout requirements (e.g., \`<kendo-card width="150px">\`)
|
|
3116
|
-
|
|
753
|
+
- Avoid applying additional styling properties such as \`display\`, \`flex\`, \`grid\`, or other layout-specific CSS to layout components such as GridLayout, Splitter, StackLayout and TileLayout. Use the component's built-in parameters and the Kendo CSS utility classes instead.
|
|
754
|
+
|
|
755
|
+
## Page Shell Patterns
|
|
756
|
+
|
|
757
|
+
Choose the pattern that matches the page structure:
|
|
758
|
+
|
|
759
|
+
**Pattern A \u2014 Sidebar + Main Content**
|
|
760
|
+
\`\`\`css
|
|
761
|
+
.app-shell {
|
|
762
|
+
display: flex;
|
|
763
|
+
height: 100vh;
|
|
764
|
+
}
|
|
765
|
+
.sidebar {
|
|
766
|
+
width: 240px;
|
|
767
|
+
flex-shrink: 0;
|
|
768
|
+
}
|
|
769
|
+
.main-content {
|
|
770
|
+
flex: 1;
|
|
771
|
+
min-width: 0; /* Critical: prevents flex children from overflowing */
|
|
772
|
+
overflow: auto;
|
|
773
|
+
}
|
|
774
|
+
\`\`\`
|
|
775
|
+
|
|
776
|
+
**Pattern B \u2014 Centered Single-Column (forms, detail pages)**
|
|
777
|
+
\`\`\`css
|
|
778
|
+
.page-container {
|
|
779
|
+
max-width: 960px;
|
|
780
|
+
margin: 0 auto;
|
|
781
|
+
padding: 0 1rem;
|
|
782
|
+
}
|
|
783
|
+
\`\`\`
|
|
784
|
+
|
|
785
|
+
**Pattern C \u2014 Master-Detail Split**
|
|
786
|
+
\`\`\`css
|
|
787
|
+
.split-container {
|
|
788
|
+
display: grid;
|
|
789
|
+
grid-template-columns: 420px 1fr;
|
|
790
|
+
height: 100%;
|
|
791
|
+
}
|
|
792
|
+
\`\`\`
|
|
793
|
+
|
|
794
|
+
## Dashboard Layout
|
|
795
|
+
|
|
796
|
+
**KPI metric row** (auto-responsive, min 180px per card):
|
|
797
|
+
\`\`\`css
|
|
798
|
+
.kpi-row {
|
|
799
|
+
display: grid;
|
|
800
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
801
|
+
gap: 1rem;
|
|
802
|
+
}
|
|
803
|
+
\`\`\`
|
|
804
|
+
|
|
805
|
+
**Side-by-side charts** (equal width, no overflow):
|
|
806
|
+
\`\`\`css
|
|
807
|
+
.chart-row {
|
|
808
|
+
display: grid;
|
|
809
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
810
|
+
gap: 1rem;
|
|
811
|
+
}
|
|
812
|
+
\`\`\`
|
|
813
|
+
|
|
814
|
+
## Critical Sizing Rules
|
|
815
|
+
|
|
816
|
+
- **\`min-width: 0\`** on every flex/grid child that contains a Kendo component \u2014 the single most common cause of layout overflow.
|
|
817
|
+
- **Grid component** always requires an explicit height (e.g., \`[height]="'500px'"\` or \`flex: 1; min-height: 0\` inside a flex column).
|
|
818
|
+
- **Chart component** always requires an explicit height (e.g., \`style="height: 300px"\`).
|
|
819
|
+
- Never leave Grid column widths unset \u2014 without a height, Grid renders all rows and expands the page indefinitely..
|
|
820
|
+
- Constrain page content to \`max-width: 1440px\` with \`margin: 0 auto\` to prevent unbounded wide-screen stretching, unless the project defines a different maximum content width.
|
|
821
|
+
|
|
822
|
+
## Dark Theme Completeness
|
|
3117
823
|
|
|
3118
|
-
|
|
3119
|
-
|
|
824
|
+
Kendo themes style \`.k-*\` component selectors only. Always add these two lines to \`styles.scss\` or the global CSS file after any theme import:
|
|
825
|
+
|
|
826
|
+
\`\`\`scss
|
|
827
|
+
html, body {
|
|
828
|
+
background-color: var(--kendo-body-bg);
|
|
829
|
+
color: var(--kendo-body-text);
|
|
830
|
+
}
|
|
831
|
+
\`\`\`
|
|
832
|
+
|
|
833
|
+
Without this, dark-themed components render on a white page.
|
|
834
|
+
|
|
835
|
+
## Surface Hierarchy
|
|
836
|
+
|
|
837
|
+
Kendo themes define four surface levels \u2014 do not introduce custom surfaces outside this system:
|
|
838
|
+
1. **Page background** (\`var(--kendo-body-bg)\`) \u2014 lowest surface, applied to \`html, body\`
|
|
839
|
+
2. **Component background** (\`var(--kendo-component-bg)\`) \u2014 cards, panels, Grid body
|
|
840
|
+
3. **Header / hover surface** (\`var(--kendo-grid-header-bg)\`) \u2014 Grid headers, highlighted rows
|
|
841
|
+
4. **Active / selected surface** \u2014 managed by the theme automatically
|
|
842
|
+
|
|
843
|
+
Custom cards and containers must use \`var(--kendo-component-bg)\` for their background \u2014 never \`#fff\` or other hardcoded values. Hardcoded light colors in custom templates (Grid cell templates, custom component content) break dark mode.
|
|
844
|
+
|
|
845
|
+
## Splitter Usage Boundary
|
|
846
|
+
|
|
847
|
+
Use the \`kendo-splitter\` component only for **user-resizable** content areas (e.g., master-detail panels, side-by-side editors). Do **not** use it for static page layout \u2014 CSS Grid and Flexbox handle that with zero JavaScript overhead.
|
|
848
|
+
|
|
849
|
+
## Inline Input Width
|
|
850
|
+
|
|
851
|
+
\`kendo-dropdownlist\`, \`kendo-datepicker\`, \`kendo-textbox\`, and similar inline inputs are \`display: inline-block\` by default and will **not** fill their container automatically. Apply \`style="width: 100%"\` or wrap in a layout container to ensure consistent sizing in forms.
|
|
852
|
+
|
|
853
|
+
## Popup Z-Index Trap
|
|
854
|
+
|
|
855
|
+
CSS \`transform\` (including \`translate3d(0,0,0)\` GPU-compositing tricks) on any ancestor element creates a new stacking context. This clips Kendo popups (which use \`z-index ~10000\`), causing DropDownList, DatePicker, and ComboBox popups to appear behind other elements. Avoid \`transform\` on layout ancestors that contain Kendo overlay components.
|
|
856
|
+
`;var _e=()=>`## Design Standards for ${l} Theming
|
|
857
|
+
|
|
858
|
+
### Color & Contrast Requirements
|
|
859
|
+
- Body text contrast: \u2265 4.5:1. Large text / UI component borders: \u2265 3:1.
|
|
860
|
+
- Use only the 5 semantic color slots: **primary, success, warning, error, info**. Never invent ad-hoc semantic colors.
|
|
861
|
+
- Never use color alone to convey meaning \u2014 always pair with an icon or text label.
|
|
862
|
+
|
|
863
|
+
### Typography
|
|
864
|
+
- Prefer a single font family per application; defer to the project's established font stack if one already exists. When introducing or changing a font, test it against Grid headers, DatePicker, DropDownList, and Chart axes.
|
|
865
|
+
- Numeric and currency values require \`font-variant-numeric: tabular-nums\` to stay column-aligned.
|
|
866
|
+
|
|
867
|
+
### Override Priority (highest \u2192 lowest)
|
|
868
|
+
\`\`\`
|
|
869
|
+
$kendo-* SCSS variables \u2190 compile-time, highest priority
|
|
870
|
+
CSS custom properties \u2190 runtime, can be scoped per class
|
|
871
|
+
className overrides \u2190 avoid; breaks on theme updates
|
|
872
|
+
!important \u2190 never use; defeats theme state classes
|
|
873
|
+
\`\`\`
|
|
874
|
+
|
|
875
|
+
### One Theme Per Application
|
|
876
|
+
Never import more than one Kendo theme package in the same application. Mixing themes (e.g., Default + Bootstrap) causes cascade conflicts that are extremely difficult to debug and doubles the CSS bundle weight.
|
|
877
|
+
|
|
878
|
+
### Semantic Colors via CSS Variables
|
|
879
|
+
Always reference semantic colors through Kendo CSS variables rather than hardcoded hex values:
|
|
880
|
+
- \`var(--kendo-color-success)\` not \`#28a745\`
|
|
881
|
+
- \`var(--kendo-color-error)\` not \`#dc3545\`
|
|
882
|
+
|
|
883
|
+
Hardcoded hex values do not adapt to theme switches, swatches, or dark mode.
|
|
884
|
+
|
|
885
|
+
### Custom Template Color Safety
|
|
886
|
+
Custom content inside Grid cell templates and custom component templates must use CSS variables for colors \u2014 never hardcoded light colors:
|
|
887
|
+
- CORRECT: \`color: var(--kendo-body-text); background: var(--kendo-component-bg)\`
|
|
888
|
+
- WRONG: \`color: #333; background: #ffffff\`
|
|
889
|
+
|
|
890
|
+
This is the most common source of dark mode breakage in custom UI.
|
|
891
|
+
|
|
892
|
+
---
|
|
893
|
+
|
|
894
|
+
## Applying CSS Variables in ${l}
|
|
3120
895
|
|
|
3121
896
|
Apply these CSS variables in the Angular application using one of these methods:
|
|
3122
897
|
|
|
@@ -3178,11 +953,7 @@ export class ThemeService {
|
|
|
3178
953
|
}
|
|
3179
954
|
}
|
|
3180
955
|
\`\`\`
|
|
3181
|
-
`;
|
|
3182
|
-
|
|
3183
|
-
// packages/angular/src/lib/instructions/icons.ts
|
|
3184
|
-
var CODE_ASSISTANT_NAME2 = UIAgent.ToolNames.codeAssistant("kendo");
|
|
3185
|
-
var getIconsInstructions = () => `## Using ${ANGULAR_SUITE_NAME} Icons
|
|
956
|
+
`;var Me=u.ToolNames.codeAssistant("kendo"),Be=()=>`## Using ${l} Icons
|
|
3186
957
|
|
|
3187
958
|
Important: Attempt to prioritize SVG icons over font icons.
|
|
3188
959
|
|
|
@@ -3190,13 +961,13 @@ Important: Attempt to prioritize SVG icons over font icons.
|
|
|
3190
961
|
|
|
3191
962
|
- Make sure @progress/kendo-svg-icons is installed.
|
|
3192
963
|
- Make sure @progress/kendo-angular-icons is installed.
|
|
3193
|
-
- You can call ${
|
|
964
|
+
- You can call ${Me} tool for ${l} SVGIcon component for docs and API reference.
|
|
3194
965
|
- [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.
|
|
3195
|
-
- [optional] If using font icons you can call ${
|
|
966
|
+
- [optional] If using font icons you can call ${Me} tool for ${l} Icon component for docs and API reference.
|
|
3196
967
|
|
|
3197
968
|
### Examples
|
|
3198
969
|
|
|
3199
|
-
Using ${
|
|
970
|
+
Using ${l} SVGIcon component:
|
|
3200
971
|
|
|
3201
972
|
\`\`\`ts
|
|
3202
973
|
import { Component } from "@angular/core";
|
|
@@ -3217,7 +988,7 @@ export class AppComponent {
|
|
|
3217
988
|
|
|
3218
989
|
\`\`\`
|
|
3219
990
|
|
|
3220
|
-
Using ${
|
|
991
|
+
Using ${l} Icon component:
|
|
3221
992
|
|
|
3222
993
|
\`\`\`ts
|
|
3223
994
|
import { Component } from "@angular/core";
|
|
@@ -3233,43 +1004,29 @@ import { KENDO_ICONS } from "@progress/kendo-angular-icons";
|
|
|
3233
1004
|
})
|
|
3234
1005
|
export class AppComponent {}
|
|
3235
1006
|
\`\`\`
|
|
3236
|
-
`;
|
|
3237
|
-
|
|
3238
|
-
// packages/angular/src/lib/instructions/components-common.ts
|
|
3239
|
-
var getComponentsCommonInstructions = (ctx) => {
|
|
3240
|
-
const normComponent = ctx.component?.trim().toLowerCase();
|
|
3241
|
-
const installPackage = COMPONENT_PACKAGE_MAP.get(normComponent);
|
|
3242
|
-
let content = `## ${ANGULAR_SUITE_NAME} Common Guidelines
|
|
1007
|
+
`;var Fe=e=>{let t=e.component?.trim().toLowerCase(),s=me.get(t),o=`## ${l} Common Guidelines
|
|
3243
1008
|
|
|
3244
|
-
`;
|
|
3245
|
-
if (installPackage) {
|
|
3246
|
-
content += `### Package Installation
|
|
1009
|
+
`;return s&&(o+=`### Package Installation
|
|
3247
1010
|
Always use minimal, targeted package installation.
|
|
3248
1011
|
Ensure all necessary Angular packages are installed, including @angular/localize.
|
|
3249
1012
|
|
|
3250
1013
|
Process:
|
|
3251
1014
|
1. Identify the required components
|
|
3252
1015
|
2. Determine the specific Kendo Angular packages needed
|
|
3253
|
-
3. Use the "ng add ${
|
|
1016
|
+
3. Use the "ng add ${s}" command
|
|
3254
1017
|
|
|
3255
|
-
For ${
|
|
3256
|
-
|
|
3257
|
-
}
|
|
3258
|
-
if (ctx.componentInstructions) {
|
|
3259
|
-
content += `
|
|
1018
|
+
For ${e.component} component: \`ng add ${s}\`
|
|
1019
|
+
`),e.componentInstructions&&(o+=`
|
|
3260
1020
|
## Component-Specific Guidelines
|
|
3261
1021
|
|
|
3262
|
-
${
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
return content;
|
|
3266
|
-
};
|
|
1022
|
+
${e.componentInstructions}
|
|
1023
|
+
`),o+=`
|
|
1024
|
+
## Types and Interfaces
|
|
3267
1025
|
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
const createProjectSection = createNewProject ? `## Step ${stepCounter++}: Install Angular CLI
|
|
1026
|
+
Always use the correct ${l} types for component inputs, outputs, and event handler parameters.
|
|
1027
|
+
Do not substitute plain strings, plain objects, or \`any\` for a typed union, enum, or interface provided by the library.
|
|
1028
|
+
Import all required types from the appropriate ${l} package.
|
|
1029
|
+
`,o};function qe(e="kendo-angular-app",t=!0,s="default"){let o=t?`These instructions will walk you through creating a new Angular project and setting up ${l}.`:`These instructions will walk you through adding ${l} to your existing Angular project.`,n=1,r=t?`## Step ${n++}: Install Angular CLI
|
|
3273
1030
|
|
|
3274
1031
|
First, ensure the Angular CLI is installed globally:
|
|
3275
1032
|
|
|
@@ -3277,24 +1034,23 @@ First, ensure the Angular CLI is installed globally:
|
|
|
3277
1034
|
npm install -g @angular/cli@latest
|
|
3278
1035
|
\`\`\`
|
|
3279
1036
|
|
|
3280
|
-
## Step ${
|
|
1037
|
+
## Step ${n++}: Create the Project
|
|
3281
1038
|
|
|
3282
1039
|
Create a new Angular project using the Angular CLI:
|
|
3283
1040
|
|
|
3284
1041
|
\`\`\`bash
|
|
3285
|
-
ng new ${
|
|
1042
|
+
ng new ${e} --style=css --ai-config=none --no-ssr --routing --zoneless=false --minimal=true
|
|
3286
1043
|
\`\`\`
|
|
3287
1044
|
|
|
3288
1045
|
Navigate to the project directory:
|
|
3289
1046
|
|
|
3290
1047
|
\`\`\`bash
|
|
3291
|
-
cd ${
|
|
1048
|
+
cd ${e}
|
|
3292
1049
|
\`\`\`
|
|
3293
1050
|
|
|
3294
|
-
|
|
3295
|
-
return `# Getting Started with ${ANGULAR_SUITE_NAME}
|
|
1051
|
+
`:"";return`# Getting Started with ${l}
|
|
3296
1052
|
|
|
3297
|
-
${
|
|
1053
|
+
${o}
|
|
3298
1054
|
|
|
3299
1055
|
Execute the following steps in order.
|
|
3300
1056
|
|
|
@@ -3307,9 +1063,9 @@ Before you begin, ensure you have:
|
|
|
3307
1063
|
- **Node.js 18 or later** installed on your machine
|
|
3308
1064
|
- If Node.js is not available, you need to install the latest Node.js automatically as a preliminary step before installing the Angular CLI tool.
|
|
3309
1065
|
|
|
3310
|
-
${
|
|
1066
|
+
${r}## Step ${n++}: Configure animations
|
|
3311
1067
|
|
|
3312
|
-
This ensures animations that ${
|
|
1068
|
+
This ensures animations that ${l} components rely on are configurated correctly.
|
|
3313
1069
|
|
|
3314
1070
|
1. Open the \`src/app/app.config.ts\` file and add animations like this.
|
|
3315
1071
|
\`\`\`typescript
|
|
@@ -3325,21 +1081,21 @@ export const appConfig: ApplicationConfig = {
|
|
|
3325
1081
|
};
|
|
3326
1082
|
\`\`\`
|
|
3327
1083
|
|
|
3328
|
-
## Step ${
|
|
1084
|
+
## Step ${n++}: Install ${l} Packages
|
|
3329
1085
|
|
|
3330
1086
|
Use angular CLI to install grid package. While installing, confirm that you also want to install the underlying npm package with the suggested version from the ng tool.
|
|
3331
1087
|
|
|
3332
1088
|
\`\`\`bash
|
|
3333
|
-
ng add @progress/kendo-angular-grid@latest --skip-confirmation --theme=${
|
|
1089
|
+
ng add @progress/kendo-angular-grid@latest --skip-confirmation --theme=${s}
|
|
3334
1090
|
\`\`\`
|
|
3335
1091
|
|
|
3336
|
-
Use npm to install additional required ${
|
|
1092
|
+
Use npm to install additional required ${l} packages:
|
|
3337
1093
|
|
|
3338
1094
|
\`\`\`bash
|
|
3339
1095
|
npm install @progress/kendo-angular-barcodes @progress/kendo-angular-chart-wizard @progress/kendo-angular-charts @progress/kendo-angular-dateinputs @progress/kendo-angular-diagrams @progress/kendo-angular-editor @progress/kendo-angular-filter @progress/kendo-angular-gantt @progress/kendo-angular-gauges @progress/kendo-angular-icons @progress/kendo-angular-listbox @progress/kendo-angular-listview @progress/kendo-angular-map @progress/kendo-angular-pdfviewer @progress/kendo-angular-pivotgrid @progress/kendo-angular-ripple @progress/kendo-angular-scheduler @progress/kendo-angular-scrollview @progress/kendo-angular-sortable @progress/kendo-angular-spreadsheet @progress/kendo-angular-tooltip @progress/kendo-angular-treelist @progress/kendo-angular-typography @progress/kendo-file-saver
|
|
3340
1096
|
\`\`\`
|
|
3341
1097
|
|
|
3342
|
-
## Step ${
|
|
1098
|
+
## Step ${n++}: Activate Kendo license
|
|
3343
1099
|
|
|
3344
1100
|
This step is required to use Kendo UI for Angular components without watermarks and with access to all features. At this point, the customer have the correct license file, and the command should be run to activate the component in this specific project. Run the following command to activate your license:
|
|
3345
1101
|
|
|
@@ -3354,7 +1110,7 @@ ng cache clean
|
|
|
3354
1110
|
\`\`\`
|
|
3355
1111
|
|
|
3356
1112
|
|
|
3357
|
-
## Step ${
|
|
1113
|
+
## Step ${n++}: Install the Kendo utils package
|
|
3358
1114
|
|
|
3359
1115
|
Add the following script to index.html to include the Kendo theme utils, which are required for the themes to work correctly:
|
|
3360
1116
|
|
|
@@ -3362,9 +1118,9 @@ Add the following script to index.html to include the Kendo theme utils, which a
|
|
|
3362
1118
|
<link rel="stylesheet" href="https://unpkg.com/@progress/kendo-theme-utils/dist/all.css" />
|
|
3363
1119
|
\`\`\`
|
|
3364
1120
|
|
|
3365
|
-
${
|
|
1121
|
+
${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.`}
|
|
3366
1122
|
|
|
3367
|
-
## Step ${
|
|
1123
|
+
## Step ${n++}: Create Sample Page
|
|
3368
1124
|
|
|
3369
1125
|
Add the sample page below to your application to verify that everything is working correctly.
|
|
3370
1126
|
|
|
@@ -3391,7 +1147,7 @@ export class App {}
|
|
|
3391
1147
|
\`\`\`html
|
|
3392
1148
|
<div class="k-d-flex k-flex-col k-gap-5 k-p-6">
|
|
3393
1149
|
<div class="k-d-flex k-flex-col k-align-items-center k-gap-3 k-py-4">
|
|
3394
|
-
<h1 class="k-h2 k-text-center">${
|
|
1150
|
+
<h1 class="k-h2 k-text-center">${l}</h1>
|
|
3395
1151
|
<p class="k-h5 k-text-center k-color-subtle k-font-weight-normal k-max-w-3xl">
|
|
3396
1152
|
Create sophisticated Angular UIs with AI-powered agents using natural language prompts
|
|
3397
1153
|
</p>
|
|
@@ -3498,19 +1254,15 @@ export class App {}
|
|
|
3498
1254
|
}
|
|
3499
1255
|
\`\`\`
|
|
3500
1256
|
|
|
3501
|
-
## Step ${
|
|
1257
|
+
## Step ${n++}: Run Your Application
|
|
3502
1258
|
|
|
3503
1259
|
**Verification:** Automatically run the application. Do not just inform the user\u2014execute the following command and keep the application running:
|
|
3504
1260
|
|
|
3505
1261
|
\`\`\`bash
|
|
3506
|
-
cd ${
|
|
1262
|
+
cd ${e} && ng serve
|
|
3507
1263
|
\`\`\`
|
|
3508
1264
|
|
|
3509
|
-
|
|
3510
|
-
}
|
|
3511
|
-
|
|
3512
|
-
// packages/angular/src/lib/instructions/grid.ts
|
|
3513
|
-
var gridInstructions = `
|
|
1265
|
+
`}var Ke=`
|
|
3514
1266
|
## Grid Data Binding
|
|
3515
1267
|
|
|
3516
1268
|
MUST use kendoGridBinding directive for basic Grid operations
|
|
@@ -3524,10 +1276,96 @@ Always use kendoGridBinding for:
|
|
|
3524
1276
|
Implementation: <kendo-grid [kendoGridBinding]="data">
|
|
3525
1277
|
|
|
3526
1278
|
Use manual binding for complex custom scenarios.
|
|
3527
|
-
`;
|
|
3528
1279
|
|
|
3529
|
-
|
|
3530
|
-
|
|
1280
|
+
## Manual Data Binding
|
|
1281
|
+
|
|
1282
|
+
When using manual binding (without kendoGridBinding), every enabled Grid data operation requires a corresponding event handler that applies the operation to the data manually.
|
|
1283
|
+
The \`@progress/kendo-data-query\` package provides matching helpers (e.g. \`filterBy()\`, \`orderBy()\`, \`process()\`) that can be used directly inside these handlers.
|
|
1284
|
+
When multiple data operations are enabled at once, the preferred approach is a single \`dataStateChange\` handler using the \`process()\` helper.
|
|
1285
|
+
|
|
1286
|
+
Filtering example:
|
|
1287
|
+
\`\`\`typescript
|
|
1288
|
+
import { filterBy, CompositeFilterDescriptor } from '@progress/kendo-data-query';
|
|
1289
|
+
|
|
1290
|
+
onFilterChange(filter: CompositeFilterDescriptor): void {
|
|
1291
|
+
this.gridData = filterBy(this.sourceData, filter);
|
|
1292
|
+
}
|
|
1293
|
+
\`\`\`
|
|
1294
|
+
\`\`\`html
|
|
1295
|
+
<kendo-grid [data]="gridData" [filterable]="true" (filterChange)="onFilterChange($event)">
|
|
1296
|
+
\`\`\`
|
|
1297
|
+
|
|
1298
|
+
## kendoButton Must Not Be Combined with Command Directives
|
|
1299
|
+
|
|
1300
|
+
Never apply kendoButton to the same element as any of these Grid command directives - they render their own button internally.
|
|
1301
|
+
Instead, apply only the command directive to the button element.
|
|
1302
|
+
Placing kendoButton on the same host element introduces a second component on the same node, which Angular does not allow and causes a runtime error.
|
|
1303
|
+
|
|
1304
|
+
Affected directives:
|
|
1305
|
+
- kendoGridExcelCommand
|
|
1306
|
+
- kendoGridCSVCommand
|
|
1307
|
+
- kendoGridPDFCommand
|
|
1308
|
+
- kendoGridAddCommand
|
|
1309
|
+
- kendoGridEditCommand
|
|
1310
|
+
- kendoGridSaveCommand
|
|
1311
|
+
- kendoGridCancelCommand
|
|
1312
|
+
- kendoGridRemoveCommand
|
|
1313
|
+
|
|
1314
|
+
WRONG: <button kendoGridExcelCommand kendoButton>Export to Excel</button>
|
|
1315
|
+
CORRECT: <button kendoGridExcelCommand>Export to Excel</button>
|
|
1316
|
+
`;var Ve=`
|
|
1317
|
+
## kendoButton Must Not Be Combined with Command Directives
|
|
1318
|
+
|
|
1319
|
+
Never apply kendoButton to the same element as any of these TreeList command directives - they render their own button internally.
|
|
1320
|
+
Placing kendoButton on the same host element introduces a second component on the same node, which Angular does not allow and causes a runtime error.
|
|
1321
|
+
|
|
1322
|
+
Affected directives:
|
|
1323
|
+
- kendoTreeListExcelCommand
|
|
1324
|
+
- kendoTreeListPDFCommand
|
|
1325
|
+
|
|
1326
|
+
WRONG: <button kendoTreeListExcelCommand kendoButton>Export to Excel</button>
|
|
1327
|
+
CORRECT: <button kendoTreeListExcelCommand>Export to Excel</button>
|
|
1328
|
+
`;var je=`
|
|
1329
|
+
## kendoButton Must Not Be Combined with Command Directives
|
|
1330
|
+
|
|
1331
|
+
Never apply kendoButton to the same element as any of these ListView command directives - they render their own button internally.
|
|
1332
|
+
Placing kendoButton on the same host element introduces a second component on the same node, which Angular does not allow and causes a runtime error.
|
|
1333
|
+
|
|
1334
|
+
Affected directives:
|
|
1335
|
+
- kendoListViewAddCommand
|
|
1336
|
+
- kendoListViewEditCommand
|
|
1337
|
+
- kendoListViewSaveCommand
|
|
1338
|
+
- kendoListViewCancelCommand
|
|
1339
|
+
- kendoListViewRemoveCommand
|
|
1340
|
+
|
|
1341
|
+
WRONG: <button kendoListViewAddCommand kendoButton>Add</button>
|
|
1342
|
+
CORRECT: <button kendoListViewAddCommand>Add</button>
|
|
1343
|
+
`;var We=`
|
|
1344
|
+
## kendoButton Must Not Be Combined with Command Directives
|
|
1345
|
+
|
|
1346
|
+
Never apply kendoButton to the same element as the Scheduler PDF command directive - it renders its own button internally.
|
|
1347
|
+
Placing kendoButton on the same host element introduces a second component on the same node, which Angular does not allow and causes a runtime error.
|
|
1348
|
+
|
|
1349
|
+
Affected directives:
|
|
1350
|
+
- kendoSchedulerPDFCommand
|
|
1351
|
+
|
|
1352
|
+
WRONG: <button kendoSchedulerPDFCommand kendoButton>Export to PDF</button>
|
|
1353
|
+
CORRECT: <button kendoSchedulerPDFCommand>Export to PDF</button>
|
|
1354
|
+
`;var ze=`
|
|
1355
|
+
## kendoButton Must Not Be Combined with Action Directives
|
|
1356
|
+
|
|
1357
|
+
Never apply kendoButton to the same element as any of these Window action directives - they render their own button internally.
|
|
1358
|
+
Placing kendoButton on the same host element introduces a second component on the same node, which Angular does not allow and causes a runtime error.
|
|
1359
|
+
|
|
1360
|
+
Affected directives:
|
|
1361
|
+
- kendoWindowCloseAction
|
|
1362
|
+
- kendoWindowMaximizeAction
|
|
1363
|
+
- kendoWindowMinimizeAction
|
|
1364
|
+
- kendoWindowRestoreAction
|
|
1365
|
+
|
|
1366
|
+
WRONG: <button kendoWindowCloseAction kendoButton></button>
|
|
1367
|
+
CORRECT: <button kendoWindowCloseAction></button>
|
|
1368
|
+
`;var He=`
|
|
3531
1369
|
## Charts Data Binding
|
|
3532
1370
|
|
|
3533
1371
|
Never bind the Chart's data to a getter property. Using a getter causes the chart to rerender on every Angular change detection cycle.
|
|
@@ -3535,96 +1373,65 @@ Never bind the Chart's data to a getter property. Using a getter causes the char
|
|
|
3535
1373
|
BAD: get chartData() { return [ /* data items */ ] }
|
|
3536
1374
|
GOOD: public chartData = [ /* data items */ ];
|
|
3537
1375
|
GOOD: public chartData = this.data.map(...)
|
|
3538
|
-
`;
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
var dropdownComponents = [
|
|
3542
|
-
"combobox",
|
|
3543
|
-
"dropdownlist",
|
|
3544
|
-
"dropdowntree",
|
|
3545
|
-
"multicolumncombobox",
|
|
3546
|
-
"multiselect",
|
|
3547
|
-
"multiselecttree",
|
|
3548
|
-
"autocomplete"
|
|
3549
|
-
];
|
|
3550
|
-
var dropdownsInstructions = (component) => {
|
|
3551
|
-
if (component === "autocomplete") {
|
|
3552
|
-
return autoCompleteInstructions;
|
|
3553
|
-
}
|
|
3554
|
-
if (component === "dropdowntree") {
|
|
3555
|
-
return dropDownTreeInstructions;
|
|
3556
|
-
}
|
|
3557
|
-
if (component === "multiselecttree") {
|
|
3558
|
-
return multiSelectTreeInstructions;
|
|
3559
|
-
}
|
|
3560
|
-
if (component === "multicolumncombobox") {
|
|
3561
|
-
return multiColumnComboBoxInstructions;
|
|
3562
|
-
}
|
|
3563
|
-
return dropdownCommonInstructions(component);
|
|
3564
|
-
};
|
|
3565
|
-
var dropdownCommonInstructions = (component) => `
|
|
3566
|
-
## ${component}
|
|
3567
|
-
When implementing or updating the ${component} component, always follow these rules for \`textField\` and \`valueField\`:
|
|
1376
|
+
`;var Ye=["combobox","dropdownlist","dropdowntree","multicolumncombobox","multiselect","multiselecttree","autocomplete"],Qe=e=>e==="autocomplete"?Rt:e==="dropdowntree"?Dt:e==="multiselecttree"?Ot:e==="multicolumncombobox"?Gt:Pt(e),Pt=e=>`
|
|
1377
|
+
## ${e}
|
|
1378
|
+
When implementing or updating the ${e} component, always follow these rules for \`textField\` and \`valueField\`:
|
|
3568
1379
|
|
|
3569
1380
|
### Primitive Data
|
|
3570
|
-
If the data is an array of primitives (e.g., data=[
|
|
1381
|
+
If the data is an array of primitives (e.g., [data]="['A', 'B']"), never set \`textField\` or \`valueField\`:
|
|
1382
|
+
\`\`\`html
|
|
1383
|
+
<kendo-dropdownlist [data]="['A', 'B']"></kendo-dropdownlist>
|
|
1384
|
+
\`\`\`
|
|
3571
1385
|
|
|
3572
1386
|
### Complex Data
|
|
3573
|
-
If the data is an array of objects (e.g., data=[{ id, name }]), always set both \`textField\` and \`valueField\`:
|
|
1387
|
+
If the data is an array of objects (e.g., [data]="[{ id, name }]"), always set both \`textField\` and \`valueField\`:
|
|
3574
1388
|
- \`textField\` is the property to display (e.g., "name")
|
|
3575
1389
|
- \`valueField\` is the property for value binding (e.g., "id")
|
|
3576
1390
|
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
1391
|
+
\`\`\`html
|
|
1392
|
+
<kendo-dropdownlist
|
|
1393
|
+
[data]="[{ id: 1, name: 'A' }, { id: 2, name: 'B' }]"
|
|
1394
|
+
textField="name"
|
|
1395
|
+
valueField="id">
|
|
1396
|
+
</kendo-dropdownlist>
|
|
1397
|
+
\`\`\`
|
|
1398
|
+
|
|
1399
|
+
If \`valuePrimitive\` is true, the value must be a primitive and \`valueField\` is required:
|
|
1400
|
+
\`\`\`html
|
|
1401
|
+
<kendo-dropdownlist
|
|
1402
|
+
[data]="[{ id: 1, name: 'A' }, { id: 2, name: 'B' }]"
|
|
1403
|
+
textField="name"
|
|
1404
|
+
valueField="id"
|
|
1405
|
+
[valuePrimitive]="true"
|
|
1406
|
+
[(ngModel)]="selectedValue">
|
|
1407
|
+
</kendo-dropdownlist>
|
|
1408
|
+
\`\`\`
|
|
1409
|
+
\`\`\`typescript
|
|
1410
|
+
public selectedValue = 2;
|
|
1411
|
+
\`\`\`
|
|
1412
|
+
|
|
1413
|
+
If \`valuePrimitive\` is false, which is the default, the value must be an object and \`valueField\` is required:
|
|
1414
|
+
\`\`\`html
|
|
1415
|
+
<kendo-dropdownlist
|
|
1416
|
+
[data]="[{ id: 1, name: 'A' }, { id: 2, name: 'B' }]"
|
|
1417
|
+
textField="name"
|
|
1418
|
+
valueField="id"
|
|
1419
|
+
[valuePrimitive]="false"
|
|
1420
|
+
[(ngModel)]="selectedValue">
|
|
1421
|
+
</kendo-dropdownlist>
|
|
1422
|
+
\`\`\`
|
|
1423
|
+
\`\`\`typescript
|
|
1424
|
+
public selectedValue = { id: 2, name: 'B' };
|
|
1425
|
+
\`\`\`
|
|
1426
|
+
`,Rt=`
|
|
3580
1427
|
## AutoComplete
|
|
3581
1428
|
|
|
3582
1429
|
### Primitive Data
|
|
3583
|
-
If the data is an array of primitives (e.g., data=[
|
|
1430
|
+
If the data is an array of primitives (e.g., [data]="['A', 'B']"), never set \`valueField\`.
|
|
3584
1431
|
|
|
3585
1432
|
### Complex Data
|
|
3586
|
-
If the data is an array of objects (e.g., data=[{ id, name }]), always set \`valueField\` to a string property for value binding (e.g., "id").
|
|
3587
|
-
|
|
3588
|
-
var dropDownTreeInstructions = `
|
|
3589
|
-
## DropDownTree
|
|
3590
|
-
When implementing or updating the DropDownTree component, always follow these rules:
|
|
3591
|
-
|
|
3592
|
-
Always set both \`textField\` and \`valueField\`:
|
|
3593
|
-
- \`textField\` is the property to display (e.g., "name")
|
|
3594
|
-
- \`valueField\` is the property for value binding (e.g., "id")
|
|
3595
|
-
When \`valueField\` and \`textField\` are string[], always specify \`valueDepth\`.
|
|
3596
|
-
|
|
3597
|
-
### Primitive \`value\`
|
|
3598
|
-
If the \`value\` is of a primitive type, \`valuePrimitive\` must be true and \`dataItem\` is required.
|
|
3599
|
-
The \`value\` property of the \`dataItem\` will be associated with the \`valueField\`.
|
|
3600
|
-
`;
|
|
3601
|
-
var multiSelectTreeInstructions = `
|
|
3602
|
-
## MultiSelectTree
|
|
3603
|
-
When implementing or updating the MultiSelectTree component, always follow these rules:
|
|
3604
|
-
|
|
3605
|
-
Always set both \`textField\` and \`valueField\`:
|
|
3606
|
-
- \`textField\` is the property to display (e.g., "name")
|
|
3607
|
-
- \`valueField\` is the property for value binding (e.g., "id")
|
|
3608
|
-
When \`valueField\` and \`textField\` are string[], always specify \`valueDepth\`.
|
|
3609
|
-
|
|
3610
|
-
### Primitive \`value\`
|
|
3611
|
-
If the \`value\` is of a primitive type, \`valuePrimitive\` must be true and \`dataItems\` is required.
|
|
3612
|
-
The \`value\` property of the \`dataItems\` will be associated with the \`valueField\`.
|
|
3613
|
-
`;
|
|
3614
|
-
var multiColumnComboBoxInstructions = `
|
|
3615
|
-
## MultiColumnComboBox
|
|
3616
|
-
When implementing or updating the MultiColumnComboBox component, always follow these rules:
|
|
3617
|
-
|
|
3618
|
-
Always set both \`textField\` and \`valueField\`:
|
|
3619
|
-
- \`textField\` is the property to display (e.g., "name")
|
|
3620
|
-
- \`valueField\` is the property for value binding (e.g., "id")
|
|
3621
|
-
|
|
3622
|
-
### Primitive \`value\`
|
|
3623
|
-
If the \`value\` is of a primitive type, \`valuePrimitive\` must be true.
|
|
3624
|
-
`;
|
|
3625
|
-
|
|
3626
|
-
// packages/angular/src/lib/instructions/smart-grid.ts
|
|
3627
|
-
var smartGridInstructions = `
|
|
1433
|
+
If the data is an array of objects (e.g., [data]="[{ id, name }]"), always set \`valueField\` to a string property for value binding (e.g., "id").
|
|
1434
|
+
`,Dt='\n## DropDownTree\nWhen implementing or updating the DropDownTree component, always follow these rules:\n\nAlways set both `textField` and `valueField`:\n- `textField` is the property to display (e.g., "name")\n- `valueField` is the property for value binding (e.g., "id")\nWhen `valueField` and `textField` are string[], always specify `valueDepth`.\n\n### Primitive `value`\nIf the `value` is of a primitive type, `valuePrimitive` must be true and `dataItem` is required.\nThe `value` property of the `dataItem` will be associated with the `valueField`.\n',Ot='\n## MultiSelectTree\nWhen implementing or updating the MultiSelectTree component, always follow these rules:\n\nAlways set both `textField` and `valueField`:\n- `textField` is the property to display (e.g., "name")\n- `valueField` is the property for value binding (e.g., "id")\nWhen `valueField` and `textField` are string[], always specify `valueDepth`.\n\n### Primitive `value`\nIf the `value` is of a primitive type, `valuePrimitive` must be true and `dataItems` is required.\nThe `value` property of the `dataItems` will be associated with the `valueField`.\n',Gt='\n## MultiColumnComboBox\nWhen implementing or updating the MultiColumnComboBox component, always follow these rules:\n\nAlways set both `textField` and `valueField`:\n- `textField` is the property to display (e.g., "name")\n- `valueField` is the property for value binding (e.g., "id")\n\n### Primitive `value`\nIf the `value` is of a primitive type, `valuePrimitive` must be true.\n';var Je=`
|
|
3628
1435
|
|
|
3629
1436
|
## Smart Grid (AI-Enhanced) Instructions
|
|
3630
1437
|
|
|
@@ -3643,210 +1450,6 @@ Suggestion Examples by Domain:
|
|
|
3643
1450
|
|
|
3644
1451
|
Required Disclaimer:
|
|
3645
1452
|
"The examples use a Telerik-hosted AI service for demonstration purposes only. For production applications, use an AI service that understands your specific domain, data, and business requirements."
|
|
3646
|
-
`;
|
|
3647
|
-
|
|
3648
|
-
// packages/angular/src/lib/tools/index.ts
|
|
3649
|
-
function getAngularComponentInstructions(component) {
|
|
3650
|
-
const normComponent = component?.trim().toLowerCase();
|
|
3651
|
-
if (normComponent === "grid") {
|
|
3652
|
-
return [gridInstructions, smartGridInstructions].join("\n\n");
|
|
3653
|
-
}
|
|
3654
|
-
if (normComponent === "charts") {
|
|
3655
|
-
return chartsInstructions;
|
|
3656
|
-
}
|
|
3657
|
-
if (dropdownComponents.includes(normComponent)) {
|
|
3658
|
-
return dropdownsInstructions(normComponent);
|
|
3659
|
-
}
|
|
3660
|
-
return void 0;
|
|
3661
|
-
}
|
|
3662
|
-
var LAYOUT_ASSISTANT_NAME = UIAgent.ToolNames.layoutAssistant(PRODUCT_LINE);
|
|
3663
|
-
var CODE_ASSISTANT_NAME3 = UIAgent.ToolNames.codeAssistant(PRODUCT_LINE);
|
|
3664
|
-
var STYLE_ASSISTANT_NAME = UIAgent.ToolNames.styleAssistant(PRODUCT_LINE);
|
|
3665
|
-
var FIGMA_D2C_TOOL_NAME = UIAgent.ToolNames.figmaD2C(PRODUCT_LINE);
|
|
3666
|
-
var ICON_ASSISTANT_NAME = UIAgent.ToolNames.iconAssistant(PRODUCT_LINE);
|
|
3667
|
-
var GET_STARTED_TOOL_NAME = UIAgent.ToolNames.gettingStartedAssistant(PRODUCT_LINE);
|
|
3668
|
-
var ACCESSIBILITY_ASSISTANT_NAME = UIAgent.ToolNames.accessibilityAssistant(PRODUCT_LINE);
|
|
3669
|
-
function createAngularTools(contextApi2, accessType, mcpServer) {
|
|
3670
|
-
const allTools = [
|
|
3671
|
-
// Orchestrator Tool
|
|
3672
|
-
UIAgent.Tools.createOrchestrator(
|
|
3673
|
-
{
|
|
3674
|
-
name: UIAgent.ToolNames.orchestrator(PRODUCT_LINE),
|
|
3675
|
-
title: "Kendo UI Generator",
|
|
3676
|
-
description: UIAgent.ToolDescriptions.orchestrator(ANGULAR_SUITE_NAME),
|
|
3677
|
-
layoutAssistantName: LAYOUT_ASSISTANT_NAME,
|
|
3678
|
-
codeAssistantName: CODE_ASSISTANT_NAME3,
|
|
3679
|
-
styleAssistantName: STYLE_ASSISTANT_NAME,
|
|
3680
|
-
iconAssistantName: ICON_ASSISTANT_NAME,
|
|
3681
|
-
accessibilityAssistantName: ACCESSIBILITY_ASSISTANT_NAME,
|
|
3682
|
-
figmaD2CToolName: FIGMA_D2C_TOOL_NAME,
|
|
3683
|
-
suiteName: ANGULAR_SUITE_NAME,
|
|
3684
|
-
libKey: Suite,
|
|
3685
|
-
components: AngularComponents,
|
|
3686
|
-
requiredAccess: ["agent"]
|
|
3687
|
-
},
|
|
3688
|
-
{
|
|
3689
|
-
validationSteps: UIAgent.Validation.Angular.steps,
|
|
3690
|
-
injectedPlan: UIAgent.Validation.Angular.additionalPlan
|
|
3691
|
-
},
|
|
3692
|
-
contextApi2
|
|
3693
|
-
),
|
|
3694
|
-
// Assistant Orchestrator Tool (for assistant mode only)
|
|
3695
|
-
UIAgent.Tools.createAssistantOrchestrator(
|
|
3696
|
-
{
|
|
3697
|
-
name: "kendo_angular_assistant",
|
|
3698
|
-
title: "Kendo UI Assistant",
|
|
3699
|
-
description: UIAgent.ToolDescriptions.assistantOrchestrator(ANGULAR_SUITE_NAME),
|
|
3700
|
-
codeAssistantName: CODE_ASSISTANT_NAME3,
|
|
3701
|
-
iconAssistantName: ICON_ASSISTANT_NAME,
|
|
3702
|
-
suiteName: ANGULAR_SUITE_NAME,
|
|
3703
|
-
libKey: Suite,
|
|
3704
|
-
components: AngularComponents,
|
|
3705
|
-
requiredAccess: ["assistant"]
|
|
3706
|
-
},
|
|
3707
|
-
contextApi2
|
|
3708
|
-
),
|
|
3709
|
-
// Layout Assistant Tool
|
|
3710
|
-
UIAgent.Tools.createLayoutAssistant(
|
|
3711
|
-
{
|
|
3712
|
-
name: LAYOUT_ASSISTANT_NAME,
|
|
3713
|
-
title: "Kendo UI Layout Assistant",
|
|
3714
|
-
description: UIAgent.ToolDescriptions.layoutAssistant,
|
|
3715
|
-
suiteName: ANGULAR_SUITE_NAME,
|
|
3716
|
-
libKey: Suite,
|
|
3717
|
-
getPreContent: getLayoutInstructions,
|
|
3718
|
-
requiredAccess: ["agent"]
|
|
3719
|
-
},
|
|
3720
|
-
contextApi2
|
|
3721
|
-
),
|
|
3722
|
-
// Style Assistant Tool
|
|
3723
|
-
UIAgent.Tools.createStyleAssistant(
|
|
3724
|
-
{
|
|
3725
|
-
name: STYLE_ASSISTANT_NAME,
|
|
3726
|
-
title: "Kendo UI Style Assistant",
|
|
3727
|
-
description: UIAgent.ToolDescriptions.styleAssistant,
|
|
3728
|
-
libKey: Suite,
|
|
3729
|
-
getPreContent: getStyleInstructions,
|
|
3730
|
-
requiredAccess: ["agent"]
|
|
3731
|
-
},
|
|
3732
|
-
contextApi2
|
|
3733
|
-
),
|
|
3734
|
-
// Icon Search Tool
|
|
3735
|
-
UIAgent.Tools.createIconSearch(
|
|
3736
|
-
{
|
|
3737
|
-
name: ICON_ASSISTANT_NAME,
|
|
3738
|
-
title: "Kendo UI Icon Assistant",
|
|
3739
|
-
description: UIAgent.ToolDescriptions.iconAssistant,
|
|
3740
|
-
libKey: Suite,
|
|
3741
|
-
getPostContent: getIconsInstructions,
|
|
3742
|
-
requiredAccess: ["assistant", "agent"]
|
|
3743
|
-
},
|
|
3744
|
-
contextApi2
|
|
3745
|
-
),
|
|
3746
|
-
// Code Assistant Tool
|
|
3747
|
-
UIAgent.Tools.createCodeAssistant(
|
|
3748
|
-
{
|
|
3749
|
-
name: CODE_ASSISTANT_NAME3,
|
|
3750
|
-
title: "Kendo UI Component Assistant",
|
|
3751
|
-
description: UIAgent.ToolDescriptions.codeAssistant(ANGULAR_SUITE_NAME),
|
|
3752
|
-
libKey: Suite,
|
|
3753
|
-
suiteName: ANGULAR_SUITE_NAME,
|
|
3754
|
-
components: AngularComponents,
|
|
3755
|
-
getPostContent: ({ component }) => {
|
|
3756
|
-
const componentInstructions = getAngularComponentInstructions(component);
|
|
3757
|
-
return getComponentsCommonInstructions({ component, componentInstructions });
|
|
3758
|
-
},
|
|
3759
|
-
requiredAccess: ["assistant", "agent"]
|
|
3760
|
-
},
|
|
3761
|
-
contextApi2
|
|
3762
|
-
),
|
|
3763
|
-
// Getting Started Tool
|
|
3764
|
-
new UIAgentTool(
|
|
3765
|
-
GET_STARTED_TOOL_NAME,
|
|
3766
|
-
{
|
|
3767
|
-
title: "Kendo UI Getting Started",
|
|
3768
|
-
description: `Creates a new Angular project with Angular CLI and provides essential getting started guidance for ${ANGULAR_SUITE_NAME} including installation, configuration, and setup instructions.`,
|
|
3769
|
-
requiredAccess: ["agent"],
|
|
3770
|
-
inputSchema: createGettingStartedInputSchema(ANGULAR_SUITE_NAME, "kendo-angular-app")
|
|
3771
|
-
},
|
|
3772
|
-
async ({ projectName, createNewProject, theme }, { _meta }) => {
|
|
3773
|
-
try {
|
|
3774
|
-
await contextApi2.recordToolUserRequest({
|
|
3775
|
-
toolName: GET_STARTED_TOOL_NAME,
|
|
3776
|
-
meta: {
|
|
3777
|
-
projectName,
|
|
3778
|
-
createNewProject,
|
|
3779
|
-
theme,
|
|
3780
|
-
_meta
|
|
3781
|
-
}
|
|
3782
|
-
});
|
|
3783
|
-
} catch (error) {
|
|
3784
|
-
console.error("Error recording tool request:", error);
|
|
3785
|
-
}
|
|
3786
|
-
const instructions = getGettingStartedInstructions(projectName, createNewProject, theme);
|
|
3787
|
-
return {
|
|
3788
|
-
content: [
|
|
3789
|
-
{
|
|
3790
|
-
type: "text",
|
|
3791
|
-
text: instructions
|
|
3792
|
-
}
|
|
3793
|
-
]
|
|
3794
|
-
};
|
|
3795
|
-
}
|
|
3796
|
-
),
|
|
3797
|
-
// Accessibility Tool
|
|
3798
|
-
UIAgent.Tools.createAccessibilityAssistant(
|
|
3799
|
-
{
|
|
3800
|
-
name: ACCESSIBILITY_ASSISTANT_NAME,
|
|
3801
|
-
title: "Kendo UI Accessibility Assistant",
|
|
3802
|
-
description: UIAgent.ToolDescriptions.accessibilityAssistant(ANGULAR_SUITE_NAME),
|
|
3803
|
-
libKey: Suite,
|
|
3804
|
-
suiteName: ANGULAR_SUITE_NAME,
|
|
3805
|
-
components: AngularComponents,
|
|
3806
|
-
requiredAccess: ["agent"]
|
|
3807
|
-
},
|
|
3808
|
-
contextApi2
|
|
3809
|
-
),
|
|
3810
|
-
// Figma Design-to-Code Tool (only when FIGMA_API_KEY is set)
|
|
3811
|
-
...process.env.FIGMA_API_KEY ? [UIAgent.Tools.createFigmaD2C(
|
|
3812
|
-
{ name: FIGMA_D2C_TOOL_NAME, figmaApiKey: process.env.FIGMA_API_KEY, requiredAccess: ["agent"] },
|
|
3813
|
-
contextApi2
|
|
3814
|
-
)] : []
|
|
3815
|
-
];
|
|
3816
|
-
return allTools.filter((tool) => tool.hasAccess(accessType));
|
|
3817
|
-
}
|
|
1453
|
+
`;function Lt(e){let t=e?.trim().toLowerCase();if(t==="grid")return[Ke,Je].join(`
|
|
3818
1454
|
|
|
3819
|
-
|
|
3820
|
-
var __filename2 = fileURLToPath3(import.meta.url);
|
|
3821
|
-
var __dirname2 = path3.dirname(__filename2);
|
|
3822
|
-
var packageJsonPath2 = path3.resolve(__dirname2, "../package.json");
|
|
3823
|
-
var packageJson2 = JSON.parse(fs3.readFileSync(packageJsonPath2, "utf-8"));
|
|
3824
|
-
var server = new McpServer({
|
|
3825
|
-
name: "kendo-mcp",
|
|
3826
|
-
title: "Kendo MCP Server",
|
|
3827
|
-
version: packageJson2.version
|
|
3828
|
-
});
|
|
3829
|
-
async function startServer() {
|
|
3830
|
-
const transport = new StdioServerTransport();
|
|
3831
|
-
log("Starting server...");
|
|
3832
|
-
const accessType = await checkAccess(async () => {
|
|
3833
|
-
const response = await validateUserLicense();
|
|
3834
|
-
const entitlement = response?.entitlement;
|
|
3835
|
-
return entitlement?.Product?.Code || entitlement?.product?.code;
|
|
3836
|
-
});
|
|
3837
|
-
if (accessType !== "none") {
|
|
3838
|
-
contextApi.toolNameHeader = accessType === "agent" || accessType === "full" ? "agent" : "assistant";
|
|
3839
|
-
const angularTools = createAngularTools(contextApi, accessType, server);
|
|
3840
|
-
angularTools.forEach((tool) => tool.register(server));
|
|
3841
|
-
startHeartbeat({
|
|
3842
|
-
serverName: "angular",
|
|
3843
|
-
contextApi,
|
|
3844
|
-
additionalFields: {
|
|
3845
|
-
version: packageJson2.version,
|
|
3846
|
-
access_type: accessType
|
|
3847
|
-
}
|
|
3848
|
-
});
|
|
3849
|
-
}
|
|
3850
|
-
await server.connect(transport);
|
|
3851
|
-
}
|
|
3852
|
-
startServer();
|
|
1455
|
+
`);if(t==="treelist")return Ve;if(t==="listview")return je;if(t==="scheduler")return We;if(t==="window")return ze;if(t==="charts")return He;if(Ye.includes(t))return Qe(t)}var Xe=u.ToolNames.layoutAssistant(I),J=u.ToolNames.codeAssistant(I),Ze=u.ToolNames.styleAssistant(I),X=u.ToolNames.iconAssistant(I),et=u.ToolNames.gettingStartedAssistant(I),tt=u.ToolNames.accessibilityAssistant(I);function ot(e,t){return[u.Tools.createOrchestrator({name:u.ToolNames.orchestrator(I),title:"Kendo UI Generator",description:u.ToolDescriptions.orchestrator(l),layoutAssistantName:Xe,codeAssistantName:J,styleAssistantName:Ze,iconAssistantName:X,accessibilityAssistantName:tt,suiteName:l,libKey:T,components:O,requiredAccess:["agent"]},{validationSteps:u.Validation.Angular.steps,injectedPlan:u.Validation.Angular.additionalPlan},e),u.Tools.createAssistantOrchestrator({name:"kendo_angular_assistant",title:"Kendo UI Assistant",description:u.ToolDescriptions.assistantOrchestrator(l),codeAssistantName:J,iconAssistantName:X,suiteName:l,libKey:T,components:O,requiredAccess:["assistant"]},e),u.Tools.createLayoutAssistant({name:Xe,title:"Kendo UI Layout Assistant",description:u.ToolDescriptions.layoutAssistant,suiteName:l,libKey:T,getPreContent:$e,requiredAccess:["agent"]},e),u.Tools.createStyleAssistant({name:Ze,title:"Kendo UI Style Assistant",description:u.ToolDescriptions.styleAssistant,libKey:T,getPreContent:_e,requiredAccess:["agent"]},e),u.Tools.createIconSearch({name:X,title:"Kendo UI Icon Assistant",description:u.ToolDescriptions.iconAssistant,libKey:T,getPostContent:Be,requiredAccess:["assistant","agent"]},e),u.Tools.createCodeAssistant({name:J,title:"Kendo UI Component Assistant",description:u.ToolDescriptions.codeAssistant(l),libKey:T,suiteName:l,components:O,getPostContent:({component:o})=>{let n=Lt(o);return Fe({component:o,componentInstructions:n})},requiredAccess:["assistant","agent"]},e),new C(et,{title:"Kendo UI Getting Started",description:`Creates a new Angular project with Angular CLI and provides essential getting started guidance for ${l} including installation, configuration, and setup instructions.`,requiredAccess:["agent"],inputSchema:ue(l,"kendo-angular-app")},async({projectName:o,createNewProject:n,theme:r},{_meta:a})=>{try{await e.recordToolUserRequest({toolName:et,meta:{projectName:o,createNewProject:n,theme:r,_meta:a}})}catch(d){console.error("Error recording tool request:",d)}return{content:[{type:"text",text:qe(o,n,r)}]}}),u.Tools.createAccessibilityAssistant({name:tt,title:"Kendo UI Accessibility Assistant",description:u.ToolDescriptions.accessibilityAssistant(l),libKey:T,suiteName:l,components:O,requiredAccess:["agent"]},e)].filter(o=>o.hasAccess(t))}var Bt=Mt(import.meta.url),Ft=st.dirname(Bt),qt=st.resolve(Ft,"../package.json"),at=JSON.parse(_t.readFileSync(qt,"utf-8")),nt=new Ut({name:"kendo-mcp",title:"Kendo MCP Server",version:at.version});async function Kt(){let e=new $t;m("Starting server...");let t=await ce(async()=>{let o=(await ge())?.entitlement;return o?.Product?.Code||o?.product?.code});t!=="none"&&(G.toolNameHeader=t==="agent"||t==="full"?"agent":"assistant",ot(G,t).forEach(o=>o.register(nt)),pe({serverName:"angular",contextApi:G,additionalFields:{version:at.version,access_type:t}})),await nt.connect(e)}Kt();
|