igniteui-theming 25.1.0 → 25.2.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.d.ts +75 -0
- package/dist/index.js +12 -0
- package/dist/json/components/bootstrap.json +1 -0
- package/dist/json/components/fluent.json +1 -0
- package/dist/json/components/indigo.json +1 -0
- package/dist/json/components/material.json +1 -0
- package/{json → dist/json}/components/themes.json +31 -1
- package/dist/mcp/generators/css.d.ts +7 -4
- package/dist/mcp/generators/css.js +129 -104
- package/dist/mcp/generators/sass.js +227 -254
- package/dist/mcp/index.js +259 -323
- package/dist/mcp/knowledge/color-usage.js +524 -502
- package/dist/mcp/knowledge/colors.js +61 -50
- package/dist/mcp/knowledge/component-metadata.js +697 -598
- package/dist/mcp/knowledge/component-themes.js +70 -57
- package/dist/mcp/knowledge/custom-palettes.js +4 -9
- package/dist/mcp/knowledge/docs/colors/guidance.js +4 -0
- package/dist/mcp/knowledge/docs/colors/usage.js +4 -0
- package/dist/mcp/knowledge/docs/layout/functions/border-radius.js +4 -0
- package/dist/mcp/knowledge/docs/layout/functions/pad.js +4 -0
- package/dist/mcp/knowledge/docs/layout/functions/sizable.js +4 -0
- package/dist/mcp/knowledge/docs/layout/mixins/sizable.js +4 -0
- package/dist/mcp/knowledge/docs/layout/mixins/sizing.js +4 -0
- package/dist/mcp/knowledge/docs/layout/mixins/spacing.js +4 -0
- package/dist/mcp/knowledge/docs/layout/overview.js +4 -0
- package/dist/mcp/knowledge/docs/setup/platform.js +4 -0
- package/dist/mcp/knowledge/elevations.d.ts +1 -1
- package/dist/mcp/knowledge/elevations.js +26 -12
- package/dist/mcp/knowledge/index.js +23 -87
- package/dist/mcp/knowledge/layout-docs.d.ts +1 -1
- package/dist/mcp/knowledge/multipliers.js +5 -0
- package/dist/mcp/knowledge/palettes.js +29 -17
- package/dist/mcp/knowledge/platforms/angular.js +98 -120
- package/dist/mcp/knowledge/platforms/blazor.js +39 -34
- package/dist/mcp/knowledge/platforms/common.js +83 -68
- package/dist/mcp/knowledge/platforms/index.js +265 -242
- package/dist/mcp/knowledge/platforms/react.js +43 -35
- package/dist/mcp/knowledge/platforms/webcomponents.js +266 -292
- package/dist/mcp/knowledge/sass-api.js +1 -0
- package/dist/mcp/knowledge/typography.js +13 -5
- package/dist/mcp/resources/index.js +1 -0
- package/dist/mcp/resources/presets.js +409 -508
- package/dist/mcp/theming/dist/json/colors/meta/multipliers.js +50 -0
- package/dist/mcp/theming/dist/json/colors/presets/palettes.js +85 -0
- package/dist/mcp/theming/dist/json/components/themes.js +5792 -0
- package/dist/mcp/theming/dist/json/elevations/indigo.js +29 -0
- package/dist/mcp/theming/dist/json/elevations/material.js +3 -0
- package/dist/mcp/theming/dist/json/typography/presets/typescales.js +621 -0
- package/dist/mcp/tools/descriptions.js +98 -154
- package/dist/mcp/tools/handlers/color.js +58 -56
- package/dist/mcp/tools/handlers/component-theme.js +163 -225
- package/dist/mcp/tools/handlers/component-tokens.js +159 -219
- package/dist/mcp/tools/handlers/custom-palette.js +138 -179
- package/dist/mcp/tools/handlers/elevations.js +27 -28
- package/dist/mcp/tools/handlers/index.js +11 -0
- package/dist/mcp/tools/handlers/layout.js +125 -176
- package/dist/mcp/tools/handlers/palette.js +105 -120
- package/dist/mcp/tools/handlers/platform.js +289 -311
- package/dist/mcp/tools/handlers/resource.js +22 -31
- package/dist/mcp/tools/handlers/theme.js +86 -103
- package/dist/mcp/tools/handlers/typography.js +29 -30
- package/dist/mcp/tools/index.js +13 -0
- package/dist/mcp/tools/schemas.js +239 -218
- package/dist/mcp/utils/color.js +277 -239
- package/dist/mcp/utils/preprocessing.js +57 -30
- package/dist/mcp/utils/result.js +43 -45
- package/dist/mcp/utils/sass.js +271 -191
- package/dist/mcp/utils/theming-resolve.d.ts +19 -0
- package/dist/mcp/utils/theming-resolve.js +57 -0
- package/dist/mcp/utils/types.js +96 -53
- package/dist/mcp/validators/custom-palette.js +218 -243
- package/dist/mcp/validators/index.js +3 -0
- package/dist/mcp/validators/palette.js +231 -229
- package/dist/tailwind/utilities/bootstrap.css +1 -0
- package/dist/tailwind/utilities/fluent.css +1 -0
- package/dist/tailwind/utilities/indigo.css +1 -0
- package/dist/tailwind/utilities/material.css +1 -0
- package/package.json +45 -64
- package/sass/json/README.md +12 -7
- package/sass/themes/_mixins.scss +1 -0
- package/sass/themes/components/button-group/_button-group-theme.scss +42 -0
- package/sass/themes/components/grid/_grid-theme.scss +1 -1
- package/sass/themes/schemas/components/dark/_button-group.scss +173 -50
- package/sass/themes/schemas/components/dark/_grid.scss +0 -16
- package/sass/themes/schemas/components/light/_button-group.scss +221 -99
- package/sass/themes/schemas/components/light/_grid.scss +14 -20
- package/LICENSE +0 -21
- package/README.md +0 -391
- package/dist/mcp/json/colors/presets/palettes.json.js +0 -13
- package/dist/mcp/json/components/themes.json.js +0 -143
- package/dist/mcp/json/elevations/indigo.json.js +0 -8
- package/dist/mcp/json/elevations/material.json.js +0 -8
- package/dist/mcp/json/typography/presets/typescales.json.js +0 -17
- package/dist/mcp/knowledge/docs/colors/guidance.md.js +0 -4
- package/dist/mcp/knowledge/docs/colors/usage.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/functions/border-radius.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/functions/pad.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/functions/sizable.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/mixins/sizable.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/mixins/sizing.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/mixins/spacing.md.js +0 -4
- package/dist/mcp/knowledge/docs/layout/overview.md.js +0 -4
- package/dist/mcp/knowledge/docs/setup/platform.md.js +0 -4
- package/dist/mcp/vite-env.d.ts +0 -18
- package/index.js +0 -5
- package/json/components/bootstrap.json +0 -1
- package/json/components/fluent.json +0 -1
- package/json/components/indigo.json +0 -1
- package/json/components/material.json +0 -1
- package/tailwind/utilities/bootstrap.css +0 -1
- package/tailwind/utilities/fluent.css +0 -1
- package/tailwind/utilities/indigo.css +0 -1
- package/tailwind/utilities/material.css +0 -1
- /package/{json → dist/json}/colors/meta/multipliers.json +0 -0
- /package/{json → dist/json}/colors/meta/palette.json +0 -0
- /package/{json → dist/json}/colors/presets/palettes.json +0 -0
- /package/{json → dist/json}/elevations/indigo.json +0 -0
- /package/{json → dist/json}/elevations/material.json +0 -0
- /package/{json → dist/json}/typography/presets/typescales.json +0 -0
- /package/{tailwind → dist/tailwind}/themes/base.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/dark/bootstrap.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/dark/fluent.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/dark/indigo.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/dark/material.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/light/bootstrap.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/light/fluent.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/light/indigo.css +0 -0
- /package/{tailwind → dist/tailwind}/themes/light/material.css +0 -0
|
@@ -1,334 +1,312 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { resolve, dirname } from "node:path";
|
|
1
|
+
import { PLATFORM_METADATA, detectPlatformFromDependencies, isLicensedPackage } from "../../knowledge/platforms/index.js";
|
|
3
2
|
import { z } from "zod";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
//#region src/tools/handlers/platform.ts
|
|
6
|
+
/**
|
|
7
|
+
* Handler for detect_platform tool.
|
|
8
|
+
*
|
|
9
|
+
* Detects the target platform (Angular, Web Components, React, Blazor, or Generic)
|
|
10
|
+
* from package.json dependencies and project config files.
|
|
11
|
+
*
|
|
12
|
+
* Uses a multi-signal detection approach:
|
|
13
|
+
* 1. Ignite UI packages (HIGH confidence)
|
|
14
|
+
* 2. Config files like angular.json, vite.config.ts, etc. (MEDIUM-HIGH confidence)
|
|
15
|
+
* 3. Framework packages as fallback (LOW confidence)
|
|
16
|
+
* 4. Generic (standalone) mode when no Ignite UI product is detected
|
|
17
|
+
*
|
|
18
|
+
* When multiple platforms are detected with significant confidence,
|
|
19
|
+
* returns an ambiguous result prompting user to specify explicitly.
|
|
20
|
+
*
|
|
21
|
+
* When no Ignite UI product is found, returns "generic" platform
|
|
22
|
+
* with tool eligibility guidance and Sass load path configuration help.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Zod schema for validating package.json structure.
|
|
26
|
+
* Only validates the fields we need for platform detection.
|
|
27
|
+
*/
|
|
28
|
+
var packageJsonSchema = z.object({
|
|
29
|
+
dependencies: z.record(z.string()).optional(),
|
|
30
|
+
devDependencies: z.record(z.string()).optional()
|
|
8
31
|
});
|
|
32
|
+
/**
|
|
33
|
+
* Format a detection signal for human-readable output.
|
|
34
|
+
*/
|
|
9
35
|
function formatSignal(signal) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return `framework: ${signal.package}`;
|
|
17
|
-
default:
|
|
18
|
-
return "unknown";
|
|
19
|
-
}
|
|
36
|
+
switch (signal.type) {
|
|
37
|
+
case "ignite_package": return `package: ${signal.package}`;
|
|
38
|
+
case "config_file": return `config: ${signal.file}`;
|
|
39
|
+
case "framework_package": return `framework: ${signal.package}`;
|
|
40
|
+
default: return "unknown";
|
|
41
|
+
}
|
|
20
42
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Lookup table mapping config file patterns to Sass load path guidance.
|
|
45
|
+
* Add new entries here when supporting additional build tools.
|
|
46
|
+
*/
|
|
47
|
+
var SASS_CONFIG_GUIDANCE = [
|
|
48
|
+
{
|
|
49
|
+
match: "exact",
|
|
50
|
+
key: "angular.json",
|
|
51
|
+
description: "An `angular.json` config file was detected. To use Sass output from this MCP, ensure your Angular project includes `node_modules` in the Sass load paths:",
|
|
52
|
+
lang: "json",
|
|
53
|
+
code: [
|
|
54
|
+
"// In angular.json → architect → build → options:",
|
|
55
|
+
"\"stylePreprocessorOptions\": {",
|
|
56
|
+
" \"includePaths\": [\"node_modules\"]",
|
|
57
|
+
"}"
|
|
58
|
+
].join("\n")
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
match: "prefix",
|
|
62
|
+
key: "vite.config",
|
|
63
|
+
description: "A Vite config file was detected. To use Sass output from this MCP, ensure your Vite config includes `node_modules` in the Sass load paths:",
|
|
64
|
+
lang: "js",
|
|
65
|
+
code: [
|
|
66
|
+
"// In vite.config.ts/js:",
|
|
67
|
+
"css: {",
|
|
68
|
+
" preprocessorOptions: {",
|
|
69
|
+
" scss: {",
|
|
70
|
+
" loadPaths: ['node_modules']",
|
|
71
|
+
" }",
|
|
72
|
+
" }",
|
|
73
|
+
"}"
|
|
74
|
+
].join("\n")
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
match: "prefix",
|
|
78
|
+
key: "next.config",
|
|
79
|
+
description: "A Next.js config file was detected. To use Sass output from this MCP, ensure your Next.js config includes `node_modules` in the Sass load paths:",
|
|
80
|
+
lang: "js",
|
|
81
|
+
code: [
|
|
82
|
+
"// In next.config.js/mjs/ts:",
|
|
83
|
+
"sassOptions: {",
|
|
84
|
+
" loadPaths: ['node_modules']",
|
|
85
|
+
"}"
|
|
86
|
+
].join("\n")
|
|
87
|
+
}
|
|
62
88
|
];
|
|
63
|
-
|
|
89
|
+
var SASS_CONFIG_FALLBACK = "To use Sass output from this MCP, ensure your project's Sass compiler has `node_modules` in its `loadPaths`. The exact configuration depends on your build tool — Angular CLI uses `includePaths` in `angular.json`, while most other tools (Vite, Next.js, sass CLI) use `loadPaths`. Investigate the project's build configuration to find the right place to add this.";
|
|
90
|
+
/**
|
|
91
|
+
* Find Sass configuration guidance for a given config file name.
|
|
92
|
+
*/
|
|
64
93
|
function findSassGuidance(fileName) {
|
|
65
|
-
|
|
66
|
-
(entry) => entry.match === "exact" ? fileName === entry.key : fileName.startsWith(entry.key)
|
|
67
|
-
);
|
|
94
|
+
return SASS_CONFIG_GUIDANCE.find((entry) => entry.match === "exact" ? fileName === entry.key : fileName.startsWith(entry.key));
|
|
68
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* Build the "Available Tools" and "Not Available" sections for generic mode.
|
|
98
|
+
*/
|
|
69
99
|
function buildToolEligibilitySection() {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
return [
|
|
101
|
+
"### Available Tools",
|
|
102
|
+
"",
|
|
103
|
+
"The following tools work in generic (standalone) mode:",
|
|
104
|
+
"",
|
|
105
|
+
"- `create_palette` — Generate color palettes",
|
|
106
|
+
"- `create_custom_palette` — Generate fully custom palettes",
|
|
107
|
+
"- `create_typography` — Set up typography/type scales",
|
|
108
|
+
"- `create_elevations` — Configure shadow/elevation system",
|
|
109
|
+
"- `create_theme` — Generate a complete theme",
|
|
110
|
+
"- `set_size` / `set_spacing` / `set_roundness` — Layout tokens (use `scope` with a custom CSS selector or omit for `:root`; do **not** use `component` as it targets Ignite UI component selectors)",
|
|
111
|
+
"- `get_color` — Get CSS variable references for palette colors",
|
|
112
|
+
"- `read_resource` — Read theming reference data",
|
|
113
|
+
"",
|
|
114
|
+
"### Not Available in Generic Mode",
|
|
115
|
+
"",
|
|
116
|
+
"- `create_component_theme` — Requires a specific Ignite UI product platform (angular, webcomponents, react, or blazor) for component selectors and variable prefixes",
|
|
117
|
+
"- `get_component_design_tokens` — Returns tokens for Ignite UI framework components which are not present in generic mode",
|
|
118
|
+
""
|
|
119
|
+
];
|
|
90
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Build the "Sass Configuration" section based on detected config file signals.
|
|
123
|
+
*/
|
|
91
124
|
function buildSassConfigSection(signals) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
"",
|
|
105
|
-
`\`\`\`${guidance.lang}`,
|
|
106
|
-
guidance.code,
|
|
107
|
-
"```",
|
|
108
|
-
""
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return lines;
|
|
125
|
+
const lines = ["### Sass Configuration", ""];
|
|
126
|
+
const configFileSignals = signals.filter((s) => s.type === "config_file");
|
|
127
|
+
if (configFileSignals.length === 0) {
|
|
128
|
+
lines.push(SASS_CONFIG_FALLBACK, "");
|
|
129
|
+
return lines;
|
|
130
|
+
}
|
|
131
|
+
for (const signal of configFileSignals) {
|
|
132
|
+
if (signal.type !== "config_file") continue;
|
|
133
|
+
const guidance = findSassGuidance(signal.file);
|
|
134
|
+
if (guidance) lines.push(guidance.description, "", `\`\`\`${guidance.lang}`, guidance.code, "```", "");
|
|
135
|
+
}
|
|
136
|
+
return lines;
|
|
113
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Build the "Output Format Notes" section based on whether igniteui-theming is installed.
|
|
140
|
+
*/
|
|
114
141
|
function buildOutputFormatNotes(hasThemingPackage) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"",
|
|
120
|
-
"- **CSS output** works without any local installation — the MCP compiles Sass to CSS server-side.",
|
|
121
|
-
"- **Sass output** requires `igniteui-theming` to be resolvable in your project. Run `npm install igniteui-theming` to install it, then configure `loadPaths` as described above."
|
|
122
|
-
);
|
|
123
|
-
} else {
|
|
124
|
-
lines.push(
|
|
125
|
-
"The `igniteui-theming` package is installed in this project.",
|
|
126
|
-
"",
|
|
127
|
-
"- **CSS output** is compiled server-side by the MCP — no Sass toolchain needed.",
|
|
128
|
-
"- **Sass output** uses `@use 'igniteui-theming' as *;` and requires the `loadPaths` configuration described above."
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
return lines;
|
|
142
|
+
const lines = ["### Output Format Notes", ""];
|
|
143
|
+
if (!hasThemingPackage) lines.push("The `igniteui-theming` package was **not found** in this project's dependencies.", "", "- **CSS output** works without any local installation — the MCP compiles Sass to CSS server-side.", "- **Sass output** requires `igniteui-theming` to be resolvable in your project. Run `npm install igniteui-theming` to install it, then configure `loadPaths` as described above.");
|
|
144
|
+
else lines.push("The `igniteui-theming` package is installed in this project.", "", "- **CSS output** is compiled server-side by the MCP — no Sass toolchain needed.", "- **Sass output** uses `@use 'igniteui-theming' as *;` and requires the `loadPaths` configuration described above.");
|
|
145
|
+
return lines;
|
|
132
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Build response text for ambiguous detection (multiple Ignite UI platforms found).
|
|
149
|
+
*/
|
|
133
150
|
function buildAmbiguousResponse(result) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
lines.push(
|
|
156
|
-
"### Action Required",
|
|
157
|
-
"",
|
|
158
|
-
"Please specify the platform explicitly when calling theme generation tools:",
|
|
159
|
-
""
|
|
160
|
-
);
|
|
161
|
-
for (const alt of alternatives) {
|
|
162
|
-
const metadata = PLATFORM_METADATA[alt.platform];
|
|
163
|
-
lines.push(`- Use \`platform: '${alt.platform}'\` for ${metadata.name}`);
|
|
164
|
-
}
|
|
165
|
-
return lines;
|
|
151
|
+
const alternatives = result.alternatives;
|
|
152
|
+
const lines = [
|
|
153
|
+
"## Platform Detection Result",
|
|
154
|
+
"",
|
|
155
|
+
"**Status:** Ambiguous - Multiple platforms detected",
|
|
156
|
+
"",
|
|
157
|
+
"The project appears to contain dependencies for multiple Ignite UI platforms. This might be a monorepo or a project transitioning between frameworks.",
|
|
158
|
+
"",
|
|
159
|
+
"### Detected Platforms",
|
|
160
|
+
""
|
|
161
|
+
];
|
|
162
|
+
for (const alt of alternatives) {
|
|
163
|
+
const metadata = PLATFORM_METADATA[alt.platform];
|
|
164
|
+
lines.push(`#### ${metadata.name}`, `- **Confidence:** ${alt.confidence}%`, `- **Signals:** ${alt.signals.map(formatSignal).join(", ")}`, `- **Theming module:** \`${metadata.themingModule}\``, "");
|
|
165
|
+
}
|
|
166
|
+
lines.push("### Action Required", "", "Please specify the platform explicitly when calling theme generation tools:", "");
|
|
167
|
+
for (const alt of alternatives) {
|
|
168
|
+
const metadata = PLATFORM_METADATA[alt.platform];
|
|
169
|
+
lines.push(`- Use \`platform: '${alt.platform}'\` for ${metadata.name}`);
|
|
170
|
+
}
|
|
171
|
+
return lines;
|
|
166
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Build response text for generic (standalone) mode.
|
|
175
|
+
*/
|
|
167
176
|
function buildGenericResponse(result, hasThemingPackage) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
""
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
lines.push(
|
|
186
|
-
...buildToolEligibilitySection(),
|
|
187
|
-
...buildSassConfigSection(result.signals ?? []),
|
|
188
|
-
...buildOutputFormatNotes(hasThemingPackage)
|
|
189
|
-
);
|
|
190
|
-
return lines;
|
|
177
|
+
const metadata = PLATFORM_METADATA.generic;
|
|
178
|
+
const lines = [
|
|
179
|
+
"## Platform Detection Result",
|
|
180
|
+
"",
|
|
181
|
+
`**Detected Platform:** ${metadata.name}`,
|
|
182
|
+
`**Confidence:** ${result.confidence}`,
|
|
183
|
+
`**Theming Module:** \`${metadata.themingModule}\``,
|
|
184
|
+
"",
|
|
185
|
+
metadata.description,
|
|
186
|
+
""
|
|
187
|
+
];
|
|
188
|
+
if (result.signals && result.signals.length > 0) lines.push(`**Detection Signals:** ${result.signals.map(formatSignal).join(", ")}`, "");
|
|
189
|
+
lines.push(...buildToolEligibilitySection(), ...buildSassConfigSection(result.signals ?? []), ...buildOutputFormatNotes(hasThemingPackage));
|
|
190
|
+
return lines;
|
|
191
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Build response text for a single detected Ignite UI platform.
|
|
194
|
+
*/
|
|
192
195
|
function buildPlatformResponse(result, licensed) {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (platform === "angular" && licensed) {
|
|
219
|
-
usageLine += " and `licensed: true`";
|
|
220
|
-
}
|
|
221
|
-
usageLine += " to ensure the correct Sass syntax is generated for this platform.";
|
|
222
|
-
lines.push("### Usage", "", usageLine, "", metadata.description);
|
|
223
|
-
if (result.confidence === "low") {
|
|
224
|
-
lines.push(
|
|
225
|
-
"",
|
|
226
|
-
"### Note",
|
|
227
|
-
"",
|
|
228
|
-
"Detection confidence is **low**. This means no Ignite UI package was found, only framework packages. Please verify this is the correct platform before generating themes."
|
|
229
|
-
);
|
|
230
|
-
} else if (result.confidence === "medium") {
|
|
231
|
-
lines.push(
|
|
232
|
-
"",
|
|
233
|
-
"### Note",
|
|
234
|
-
"",
|
|
235
|
-
"Detection confidence is **medium**. Consider verifying the platform if the generated code doesn't work as expected."
|
|
236
|
-
);
|
|
237
|
-
}
|
|
238
|
-
return lines;
|
|
196
|
+
const platform = result.platform;
|
|
197
|
+
const metadata = PLATFORM_METADATA[platform];
|
|
198
|
+
const lines = [
|
|
199
|
+
"## Platform Detection Result",
|
|
200
|
+
"",
|
|
201
|
+
`**Detected Platform:** ${metadata.name}`,
|
|
202
|
+
`**Confidence:** ${result.confidence}`
|
|
203
|
+
];
|
|
204
|
+
if (result.detectedPackage) {
|
|
205
|
+
lines.push(`**Detected Package:** ${result.detectedPackage}`);
|
|
206
|
+
if (platform === "angular") {
|
|
207
|
+
const isLicensed = isLicensedPackage(result.detectedPackage);
|
|
208
|
+
lines.push(`**Package Type:** ${isLicensed ? "Licensed (@infragistics)" : "Open Source (npm)"}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (result.signals && result.signals.length > 0) lines.push(`**Detection Signals:** ${result.signals.map(formatSignal).join(", ")}`);
|
|
212
|
+
const themingModule = platform === "angular" && licensed ? metadata.licensedThemingModule : metadata.themingModule;
|
|
213
|
+
lines.push(`**Theming Module:** \`${themingModule}\``, "");
|
|
214
|
+
let usageLine = `When generating theme code, use \`platform: '${platform}'\``;
|
|
215
|
+
if (platform === "angular" && licensed) usageLine += " and `licensed: true`";
|
|
216
|
+
usageLine += " to ensure the correct Sass syntax is generated for this platform.";
|
|
217
|
+
lines.push("### Usage", "", usageLine, "", metadata.description);
|
|
218
|
+
if (result.confidence === "low") lines.push("", "### Note", "", "Detection confidence is **low**. This means no Ignite UI package was found, only framework packages. Please verify this is the correct platform before generating themes.");
|
|
219
|
+
else if (result.confidence === "medium") lines.push("", "### Note", "", "Detection confidence is **medium**. Consider verifying the platform if the generated code doesn't work as expected.");
|
|
220
|
+
return lines;
|
|
239
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Build response text when no platform could be determined (error/null state).
|
|
224
|
+
*/
|
|
240
225
|
function buildNullPlatformResponse(result) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
226
|
+
return [
|
|
227
|
+
"## Platform Detection Result",
|
|
228
|
+
"",
|
|
229
|
+
"**Platform:** Not detected",
|
|
230
|
+
`**Reason:** ${result.reason}`,
|
|
231
|
+
"",
|
|
232
|
+
"### Recommendation",
|
|
233
|
+
"",
|
|
234
|
+
"Please specify the platform explicitly when calling theme generation tools:",
|
|
235
|
+
"",
|
|
236
|
+
"- Use `platform: 'angular'` for Ignite UI for Angular",
|
|
237
|
+
"- Use `platform: 'webcomponents'` for Ignite UI for Web Components",
|
|
238
|
+
"- Use `platform: 'react'` for Ignite UI for React",
|
|
239
|
+
"- Use `platform: 'blazor'` for Ignite UI for Blazor",
|
|
240
|
+
"- Use `platform: 'generic'` for platform-agnostic output"
|
|
241
|
+
];
|
|
257
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* Handle the detect_platform tool invocation.
|
|
245
|
+
*/
|
|
258
246
|
async function handleDetectPlatform(params) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return {
|
|
323
|
-
content: [
|
|
324
|
-
{
|
|
325
|
-
type: "text",
|
|
326
|
-
text: lines.join("\n")
|
|
327
|
-
}
|
|
328
|
-
],
|
|
329
|
-
structuredData: response
|
|
330
|
-
};
|
|
247
|
+
const packageJsonPath = params.packageJsonPath ?? "./package.json";
|
|
248
|
+
const resolvedPath = resolve(process.cwd(), packageJsonPath);
|
|
249
|
+
const projectRoot = dirname(resolvedPath);
|
|
250
|
+
let result;
|
|
251
|
+
let parsedDeps = {};
|
|
252
|
+
let parsedDevDeps = {};
|
|
253
|
+
try {
|
|
254
|
+
const packageJsonContent = await readFile(resolvedPath, "utf-8");
|
|
255
|
+
const parseResult = packageJsonSchema.safeParse(JSON.parse(packageJsonContent));
|
|
256
|
+
if (!parseResult.success) result = {
|
|
257
|
+
platform: null,
|
|
258
|
+
confidence: "none",
|
|
259
|
+
signals: [],
|
|
260
|
+
reason: `Invalid package.json structure: ${parseResult.error.message}`
|
|
261
|
+
};
|
|
262
|
+
else {
|
|
263
|
+
const packageJson = parseResult.data;
|
|
264
|
+
parsedDeps = packageJson.dependencies ?? {};
|
|
265
|
+
parsedDevDeps = packageJson.devDependencies ?? {};
|
|
266
|
+
result = detectPlatformFromDependencies(parsedDeps, parsedDevDeps, projectRoot);
|
|
267
|
+
}
|
|
268
|
+
} catch (error) {
|
|
269
|
+
result = {
|
|
270
|
+
platform: null,
|
|
271
|
+
confidence: "none",
|
|
272
|
+
signals: [],
|
|
273
|
+
reason: `Could not read package.json: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const hasThemingPackage = "igniteui-theming" in {
|
|
277
|
+
...parsedDeps,
|
|
278
|
+
...parsedDevDeps
|
|
279
|
+
};
|
|
280
|
+
const response = {
|
|
281
|
+
platform: result.platform,
|
|
282
|
+
confidence: result.confidence,
|
|
283
|
+
reason: result.reason,
|
|
284
|
+
signals: result.signals
|
|
285
|
+
};
|
|
286
|
+
if (result.ambiguous && result.alternatives) {
|
|
287
|
+
response.ambiguous = true;
|
|
288
|
+
response.alternatives = result.alternatives;
|
|
289
|
+
}
|
|
290
|
+
if (result.detectedPackage) {
|
|
291
|
+
response.detectedPackage = result.detectedPackage;
|
|
292
|
+
response.licensed = isLicensedPackage(result.detectedPackage);
|
|
293
|
+
}
|
|
294
|
+
if (result.platform) {
|
|
295
|
+
const metadata = PLATFORM_METADATA[result.platform];
|
|
296
|
+
response.platformInfo = {
|
|
297
|
+
name: metadata.name,
|
|
298
|
+
packageName: metadata.packageName,
|
|
299
|
+
themingModule: metadata.themingModule,
|
|
300
|
+
description: metadata.description
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
content: [{
|
|
305
|
+
type: "text",
|
|
306
|
+
text: (result.ambiguous && result.alternatives ? buildAmbiguousResponse(result) : result.platform === "generic" ? buildGenericResponse(result, hasThemingPackage) : result.platform ? buildPlatformResponse(result, response.licensed) : buildNullPlatformResponse(result)).join("\n")
|
|
307
|
+
}],
|
|
308
|
+
structuredData: response
|
|
309
|
+
};
|
|
331
310
|
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
};
|
|
311
|
+
//#endregion
|
|
312
|
+
export { handleDetectPlatform };
|