@morya-ui/mcp 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +154 -151
- package/bin/morya-ui-mcp.js +2 -2
- package/data/catalog.json +40 -40
- package/data/example-coverage.json +2 -2
- package/data/golden-pages/dashboard-page.vue +138 -138
- package/data/golden-pages/detail-page.vue +178 -178
- package/data/golden-pages/empty-state.vue +56 -56
- package/data/golden-pages/form-in-dialog.vue +166 -166
- package/data/golden-pages/form-page.vue +107 -107
- package/data/golden-pages/landing-page.vue +358 -358
- package/data/golden-pages/list-page-dense.vue +168 -166
- package/data/golden-pages/list-page-rail.vue +272 -270
- package/data/golden-pages/list-page.vue +222 -220
- package/data/golden-pages/login-page.vue +231 -231
- package/data/golden-pages/result-page.vue +84 -84
- package/data/golden-pages/settings-page.vue +163 -163
- package/data/golden-pages/wizard-form.vue +182 -182
- package/dist/__tests__/fidelity.test.d.ts +1 -0
- package/dist/__tests__/fidelity.test.js +88 -0
- package/dist/__tests__/page-snippets.test.js +42 -5
- package/dist/__tests__/tools.test.js +49 -29
- package/dist/decisions.d.ts +2 -0
- package/dist/decisions.js +34 -6
- package/dist/golden-pages.d.ts +6 -1
- package/dist/golden-pages.js +34 -33
- package/dist/index.js +52 -9
- package/dist/page-snippets.js +1041 -280
- package/dist/patterns.d.ts +4 -2
- package/dist/patterns.js +35 -6
- package/dist/reference-brief.d.ts +55 -0
- package/dist/reference-brief.js +468 -0
- package/dist/style-presets.d.ts +13 -32
- package/dist/style-presets.js +100 -291
- package/dist/style-shells.d.ts +20 -0
- package/dist/style-shells.js +249 -0
- package/dist/tools.d.ts +21 -3
- package/dist/tools.js +496 -424
- package/package.json +11 -13
package/dist/style-presets.js
CHANGED
|
@@ -1,322 +1,131 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Structure still comes from golden pages;
|
|
2
|
+
* Visual style direction for generated pages — no named preset catalog.
|
|
3
|
+
* Structure still comes from golden pages; look follows the user’s reference / words.
|
|
4
4
|
*/
|
|
5
5
|
/** How agents pick a visual direction before coding. */
|
|
6
6
|
export const styleResolution = {
|
|
7
7
|
priorityZh: [
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
12
|
-
'已安装 frontend-design / impeccable 时:结构与契约仍用 morya-ui-pages + MCP;companion
|
|
8
|
+
'【最高优先】用户给了明确参考(截图 / 设计稿 / 现有页 / URL /「像 XX」)或明确描述了风格 → 必须按用户指定执行,映射到 --m-* + M*,不要换组件库、不要改成另一套脸',
|
|
9
|
+
'用户未点名、但提示词有明确气质/行业线索 → 按提示推断并在回复里用一句话点名你理解的风格;装饰性毛玻璃/霓虹/整页渐变等仅当提示明确要求',
|
|
10
|
+
'不确定(无参考、无线索)→ 必须先向用户询问一次,请其说明或贴参考;在用户回答前不要擅自发明完整视觉',
|
|
11
|
+
'用户回答「你看着办 / 直接写」且仍无线索 → 用克制、扁平、token 实色的安静后台脸,并在回复里说明;禁止默认毛玻璃/霓虹/紫渐变/新拟态',
|
|
12
|
+
'已安装 frontend-design / impeccable 时:结构与契约仍用 morya-ui-pages + MCP;companion 只加深已定方向,不得推翻用户指定或未询问就换脸',
|
|
13
13
|
],
|
|
14
14
|
priorityEn: [
|
|
15
|
-
'User
|
|
16
|
-
'
|
|
17
|
-
'
|
|
18
|
-
'
|
|
19
|
-
'If frontend-design / impeccable are installed: structure + contract still from morya-ui-pages + MCP; companions only deepen
|
|
15
|
+
'【Highest】User gave a clear reference (screenshot / mock / page / URL / “like X”) or explicitly described a style → follow it; map to --m-* + M*; never switch kits or substitute another look',
|
|
16
|
+
'No explicit description, but the prompt has clear mood / industry cues → infer and state your reading in one sentence; decorative glass/neon/full-page gradients only when clearly requested',
|
|
17
|
+
'Uncertain (no reference, vague cues) → must ask once for a description or reference before inventing the full look',
|
|
18
|
+
'User says “your call / just ship” with still no cues → use a quiet flat on-token admin face and say so; never default glass/neon/purple-mesh/neumorph',
|
|
19
|
+
'If frontend-design / impeccable are installed: structure + contract still from morya-ui-pages + MCP; companions only deepen the chosen direction — never override an explicit user choice or invent a look without asking',
|
|
20
20
|
],
|
|
21
21
|
hardRulesZh: [
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
22
|
+
'用户明确参考 / 明确描述优先于一切 companion 与默认启发式',
|
|
23
|
+
'没有命名风格预设表;不要把页面硬套进固定「风格 id」',
|
|
24
|
+
'黄金样例管区块顺序与 API,不管死审美;结构可镜像,视觉必须跟参考 / 用户描述 / 已说明的推断走',
|
|
25
|
+
'任何方向仍只用 morya-ui 的 M* 与 --m-*(可用 color-mix),禁止第二套 UI kit 与裸 hex 主题色',
|
|
26
|
+
'风格不确定时先问用户,禁止静默套一套 AI 默认脸(紫蓝 aurora、奶油衬线陶土、霓虹、未要求的毛玻璃/渐变)',
|
|
25
27
|
'Frontend Design / Impeccable / UI-UX-Pro-Max 与本 skill 冲突时,以 morya-ui-pages + DESIGN.md + MCP 为准',
|
|
26
28
|
],
|
|
27
29
|
hardRulesEn: [
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
30
|
+
'An explicit user reference or style description outranks every companion and every heuristic',
|
|
31
|
+
'There is no named style-preset catalog; do not force pages into fixed style ids',
|
|
32
|
+
'Golden pages lock block order and APIs, not the only aesthetic; mirror structure, follow reference / user words / stated inference for craft',
|
|
33
|
+
'Every look still uses morya-ui M* and --m-* only (color-mix OK); no second UI kit or raw hex theme colors',
|
|
34
|
+
'When style is uncertain, ask first — never silently apply an AI-default face (purple aurora, cream+serif+terracotta, neon, unsolicited glass/gradients)',
|
|
31
35
|
'When Frontend Design / Impeccable / UI-UX-Pro-Max conflict with this skill, morya-ui-pages + DESIGN.md + MCP win',
|
|
32
36
|
],
|
|
33
37
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
cues: ['扁平表面', 'MPageFilters plain 或轻 filled', '默认 density', '无侧栏氛围色'],
|
|
44
|
-
cuesEn: ['Flat surfaces', 'Plain or light filled filters', 'Default density', 'No sider wash'],
|
|
45
|
-
apply: [
|
|
46
|
-
'镜像 list/form 黄金结构与 Ops polish',
|
|
47
|
-
'MPageContent 默认 density;筛选可 plain',
|
|
48
|
-
'不要额外氛围渐变或大段说明',
|
|
49
|
-
],
|
|
50
|
-
applyEn: [
|
|
51
|
-
'Mirror list/form golden structure + Ops polish',
|
|
52
|
-
'Default MPageContent density; filters may stay plain',
|
|
53
|
-
'No atmosphere gradients or long marketing copy',
|
|
54
|
-
],
|
|
55
|
-
avoid: ['营销 hero', '多主色块抢焦点'],
|
|
56
|
-
avoidEn: ['Marketing hero', 'Competing accent blocks'],
|
|
57
|
-
listGoldenPage: 'list-page',
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
id: 'soft',
|
|
61
|
-
title: '柔和留白',
|
|
62
|
-
titleEn: 'Soft spacious',
|
|
63
|
-
summary: '更松的间距与说明文案,筛选带浅底,表格仍干净,适合运营/内容后台。',
|
|
64
|
-
summaryEn: 'Roomier spacing and descriptions, soft filter band, clean table — ops/content admin.',
|
|
65
|
-
lanes: ['ops', 'account', 'flow'],
|
|
66
|
-
keywords: ['soft', 'spacious', '柔和', '留白', '轻松', '友好', '运营', '内容', 'breathing'],
|
|
67
|
-
cues: ['MPageContent density="spacious"', 'MPageFilters variant="filled"', 'MPageHeader 带短 description', '状态用 MStatus'],
|
|
68
|
-
cuesEn: ['MPageContent density="spacious"', 'Filled filters', 'Short header description', 'MStatus for row state'],
|
|
69
|
-
apply: [
|
|
70
|
-
'标题下保留一句域说明',
|
|
71
|
-
'筛选用 filled;高级项 collapsible',
|
|
72
|
-
'行操作 text/small;空态 MEmpty 带下一步',
|
|
73
|
-
],
|
|
74
|
-
applyEn: [
|
|
75
|
-
'Keep one domain sentence under the title',
|
|
76
|
-
'Filled filters; collapsible advanced fields',
|
|
77
|
-
'Text/small row actions; MEmpty with a next step',
|
|
78
|
-
],
|
|
79
|
-
avoid: ['compact 挤成工具台', '装饰 Card 包表格'],
|
|
80
|
-
avoidEn: ['Forced compact toolkit feel', 'Decorative Card around the table'],
|
|
81
|
-
listGoldenPage: 'list-page',
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
id: 'dense',
|
|
85
|
-
title: '高密度工具台',
|
|
86
|
-
titleEn: 'Dense toolkit',
|
|
87
|
-
summary: '紧凑控件与表格,信息优先,适合监控、运维、交易员类界面。',
|
|
88
|
-
summaryEn: 'Tight controls and tables, information-first — monitoring, ops, trader-like UIs.',
|
|
89
|
-
lanes: ['ops'],
|
|
90
|
-
keywords: ['dense', 'compact', '高密', '紧凑', '工具台', '运维', '监控', 'power user', 'trading'],
|
|
91
|
-
cues: ['MPageContent density="compact"', '表格 size="small"', '筛选控件更窄', '少 description'],
|
|
92
|
-
cuesEn: ['Compact page density', 'size="small" table', 'Narrower filters', 'Minimal descriptions'],
|
|
93
|
-
apply: [
|
|
94
|
-
'compact + 小尺寸表格/按钮',
|
|
95
|
-
'筛选一行尽量排完;高级项折叠',
|
|
96
|
-
'全视口主列表可考虑 fill',
|
|
97
|
-
],
|
|
98
|
-
applyEn: [
|
|
99
|
-
'Compact density + small table/buttons',
|
|
100
|
-
'Fit filters on one row; collapse advanced',
|
|
101
|
-
'Full-viewport main lists may use fill',
|
|
102
|
-
],
|
|
103
|
-
avoid: ['大留白 KPI 条', '营销文案腔'],
|
|
104
|
-
avoidEn: ['Large airy KPI strips', 'Marketing voice'],
|
|
105
|
-
listGoldenPage: 'list-page-dense',
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
id: 'rail',
|
|
109
|
-
title: '侧栏强调',
|
|
110
|
-
titleEn: 'Accent rail',
|
|
111
|
-
summary: '侧栏/顶栏用 primary 的 token 氛围,主内容仍克制,适合有品牌色的 B 端。',
|
|
112
|
-
summaryEn: 'Token wash on sider/header, calm content — branded B2B shells.',
|
|
113
|
-
lanes: ['ops', 'account'],
|
|
114
|
-
keywords: ['rail', 'accent', '侧栏', '强调', '品牌', 'brand', 'colored sider', '主色'],
|
|
115
|
-
cues: [
|
|
116
|
-
'侧栏或顶栏 scoped 背景用 color-mix(primary)',
|
|
117
|
-
'菜单项全带 icon',
|
|
118
|
-
'内容区保持安静',
|
|
119
|
-
],
|
|
120
|
-
cuesEn: [
|
|
121
|
-
'Sider/header scoped bg via color-mix(primary)',
|
|
122
|
-
'Menu icons on every item',
|
|
123
|
-
'Content area stays calm',
|
|
124
|
-
],
|
|
125
|
-
apply: [
|
|
126
|
-
'仅 chrome 做氛围,不把表格做成营销块',
|
|
127
|
-
'主按钮仍唯一 primary',
|
|
128
|
-
'颜色只用 --m-* / color-mix',
|
|
129
|
-
],
|
|
130
|
-
applyEn: [
|
|
131
|
-
'Atmosphere on chrome only — not on the data table',
|
|
132
|
-
'Still one filled primary',
|
|
133
|
-
'Colors only via --m-* / color-mix',
|
|
134
|
-
],
|
|
135
|
-
avoid: ['整页渐变背景', '紫蓝 AI 默认渐变'],
|
|
136
|
-
avoidEn: ['Full-page gradient backgrounds', 'Purple-indigo AI default gradients'],
|
|
137
|
-
listGoldenPage: 'list-page-rail',
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
id: 'studio',
|
|
141
|
-
title: '工作室呼吸感',
|
|
142
|
-
titleEn: 'Studio breath',
|
|
143
|
-
summary: '更强的标题层级与章节感,适合设计/协作/知识类产品后台。',
|
|
144
|
-
summaryEn: 'Stronger title hierarchy and sectioning — design, collab, knowledge products.',
|
|
145
|
-
lanes: ['ops', 'flow', 'express'],
|
|
146
|
-
keywords: ['studio', 'editorial', '工作室', '呼吸', '设计', '协作', '知识', 'creative', 'craft'],
|
|
147
|
-
cues: [
|
|
148
|
-
'MPageHeader 标题更醒目 + description',
|
|
149
|
-
'可用 MPageSection 分组次要块',
|
|
150
|
-
'空态/引导更精致(仍 MEmpty)',
|
|
151
|
-
],
|
|
152
|
-
cuesEn: [
|
|
153
|
-
'Stronger MPageHeader + description',
|
|
154
|
-
'MPageSection for secondary groups',
|
|
155
|
-
'Richer empty/guidance still via MEmpty',
|
|
156
|
-
],
|
|
157
|
-
apply: [
|
|
158
|
-
'层级靠字号与间距,不靠花哨阴影',
|
|
159
|
-
'可加 1 个 token 氛围(径向淡彩)',
|
|
160
|
-
'表格保持直接放 PageContent',
|
|
161
|
-
],
|
|
162
|
-
applyEn: [
|
|
163
|
-
'Hierarchy via type and space, not heavy shadows',
|
|
164
|
-
'Optional one token wash (radial tint)',
|
|
165
|
-
'Keep the table directly in PageContent',
|
|
166
|
-
],
|
|
167
|
-
avoid: ['报纸多栏排版', '一排实心按钮'],
|
|
168
|
-
avoidEn: ['Broadsheet multi-column look', 'Wall of filled buttons'],
|
|
169
|
-
listGoldenPage: 'list-page',
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
id: 'ink',
|
|
173
|
-
title: '线框极简',
|
|
174
|
-
titleEn: 'Ink minimal',
|
|
175
|
-
summary: '强调边框与结构线,少填充,适合偏工具/文档气质的界面。',
|
|
176
|
-
summaryEn: 'Border-forward, little fill — tool/docs-like calm.',
|
|
177
|
-
lanes: ['ops', 'system', 'flow'],
|
|
178
|
-
keywords: ['ink', 'minimal', '线框', '极简', 'border', 'outline', '文档', 'docs', 'hairline'],
|
|
179
|
-
cues: [
|
|
180
|
-
'MPageFilters variant="plain"',
|
|
181
|
-
'MTable bordered',
|
|
182
|
-
'少用 filled 表面与 muted section',
|
|
183
|
-
],
|
|
184
|
-
cuesEn: [
|
|
185
|
-
'Plain filters',
|
|
186
|
-
'Bordered table',
|
|
187
|
-
'Few filled/muted surfaces',
|
|
188
|
-
],
|
|
189
|
-
apply: [
|
|
190
|
-
'用边框分区,不用大底色块',
|
|
191
|
-
'字重克制;主按钮仍唯一',
|
|
192
|
-
'避免零圆角报纸风(反 AI 默认)',
|
|
193
|
-
],
|
|
194
|
-
applyEn: [
|
|
195
|
-
'Partition with borders, not large fills',
|
|
196
|
-
'Restrained weight; one primary button',
|
|
197
|
-
'Avoid zero-radius broadsheet (anti AI-default)',
|
|
198
|
-
],
|
|
199
|
-
avoid: ['暖奶油衬线套装', '多层阴影当个性'],
|
|
200
|
-
avoidEn: ['Warm cream + serif kit', 'Multi-layer shadows as personality'],
|
|
201
|
-
listGoldenPage: 'list-page',
|
|
202
|
-
},
|
|
203
|
-
];
|
|
204
|
-
const aliasToId = {
|
|
205
|
-
quiet: 'quiet',
|
|
206
|
-
classic: 'quiet',
|
|
207
|
-
克制: 'quiet',
|
|
208
|
-
经典: 'quiet',
|
|
209
|
-
默认: 'quiet',
|
|
210
|
-
soft: 'soft',
|
|
211
|
-
spacious: 'soft',
|
|
212
|
-
柔和: 'soft',
|
|
213
|
-
留白: 'soft',
|
|
214
|
-
柔和留白: 'soft',
|
|
215
|
-
dense: 'dense',
|
|
216
|
-
compact: 'dense',
|
|
217
|
-
高密: 'dense',
|
|
218
|
-
紧凑: 'dense',
|
|
219
|
-
工具台: 'dense',
|
|
220
|
-
rail: 'rail',
|
|
221
|
-
accent: 'rail',
|
|
222
|
-
侧栏: 'rail',
|
|
223
|
-
强调: 'rail',
|
|
224
|
-
品牌: 'rail',
|
|
225
|
-
studio: 'studio',
|
|
226
|
-
editorial: 'studio',
|
|
227
|
-
工作室: 'studio',
|
|
228
|
-
呼吸: 'studio',
|
|
229
|
-
ink: 'ink',
|
|
230
|
-
minimal: 'ink',
|
|
231
|
-
线框: 'ink',
|
|
232
|
-
极简: 'ink',
|
|
233
|
-
};
|
|
234
|
-
export function findStylePreset(idOrAlias) {
|
|
235
|
-
const raw = idOrAlias.trim();
|
|
38
|
+
/** List golden craft keywords only (density / sider chrome) — not a style catalog. */
|
|
39
|
+
const denseHints = /dense|compact|高密|紧凑|工具台|监控列表|cms/i;
|
|
40
|
+
const railHints = /rail|侧栏强调|品牌侧栏|colored\s*sider|accent\s*rail/i;
|
|
41
|
+
/**
|
|
42
|
+
* Pick list golden craft variant from free-text style/intent.
|
|
43
|
+
* Returns null to keep the canonical list-page.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveListCraftVariant(text) {
|
|
46
|
+
const raw = (text || '').trim();
|
|
236
47
|
if (!raw)
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (
|
|
241
|
-
return
|
|
242
|
-
|
|
243
|
-
if (byId)
|
|
244
|
-
return byId;
|
|
245
|
-
const ranked = stylePresets
|
|
246
|
-
.map((preset) => ({ preset, score: scoreStylePreset(preset, raw) }))
|
|
247
|
-
.sort((a, b) => b.score - a.score);
|
|
248
|
-
return ranked[0] && ranked[0].score >= 25 ? ranked[0].preset : undefined;
|
|
249
|
-
}
|
|
250
|
-
export function scoreStylePreset(preset, query) {
|
|
251
|
-
const normalized = query.toLowerCase().trim();
|
|
252
|
-
if (!normalized)
|
|
253
|
-
return 0;
|
|
254
|
-
let score = 0;
|
|
255
|
-
if (normalized === preset.id || normalized.includes(preset.id))
|
|
256
|
-
score += 50;
|
|
257
|
-
for (const keyword of preset.keywords) {
|
|
258
|
-
const key = keyword.toLowerCase();
|
|
259
|
-
if (normalized === key)
|
|
260
|
-
score += 40;
|
|
261
|
-
else if (normalized.includes(key))
|
|
262
|
-
score += 12;
|
|
263
|
-
}
|
|
264
|
-
if (normalized.includes(preset.title.toLowerCase()))
|
|
265
|
-
score += 25;
|
|
266
|
-
if (normalized.includes(preset.titleEn.toLowerCase()))
|
|
267
|
-
score += 25;
|
|
268
|
-
return score;
|
|
48
|
+
return null;
|
|
49
|
+
if (railHints.test(raw))
|
|
50
|
+
return 'list-page-rail';
|
|
51
|
+
if (denseHints.test(raw))
|
|
52
|
+
return 'list-page-dense';
|
|
53
|
+
return null;
|
|
269
54
|
}
|
|
270
55
|
/**
|
|
271
|
-
* Resolve
|
|
272
|
-
*
|
|
56
|
+
* Resolve visual direction from an optional free-text style string and/or intent.
|
|
57
|
+
* No preset catalog — explicit user words win; otherwise ask or carefully infer.
|
|
273
58
|
*/
|
|
274
59
|
export function resolveStyleDirection(args) {
|
|
275
60
|
const explicit = args.style?.trim();
|
|
276
61
|
if (explicit) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
guidanceZh: `已选风格「${preset.title}」(${preset.id})。在黄金结构上套用该预设的 apply,并遵守 avoid。`,
|
|
285
|
-
guidanceEn: `Style “${preset.titleEn}” (${preset.id}) selected. Apply its cues on the golden structure; honor avoid.`,
|
|
286
|
-
};
|
|
287
|
-
}
|
|
62
|
+
return {
|
|
63
|
+
resolution: 'explicit',
|
|
64
|
+
summary: explicit,
|
|
65
|
+
confidence: 100,
|
|
66
|
+
guidanceZh: `用户已指定风格方向:「${explicit}」。在黄金结构上落实到 M* + --m-*,不要换成另一套脸。`,
|
|
67
|
+
guidanceEn: `User specified style direction: “${explicit}”. Implement on the golden structure with M* + --m-*; do not substitute another look.`,
|
|
68
|
+
};
|
|
288
69
|
}
|
|
289
|
-
const
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
const best = ranked[0];
|
|
294
|
-
const candidates = ranked.slice(0, 4).map((item) => ({
|
|
295
|
-
id: item.preset.id,
|
|
296
|
-
title: item.preset.title,
|
|
297
|
-
titleEn: item.preset.titleEn,
|
|
298
|
-
score: item.score,
|
|
299
|
-
}));
|
|
300
|
-
if (best && best.score >= 20) {
|
|
70
|
+
const intent = (args.intent || '').trim();
|
|
71
|
+
const cueScore = scoreStyleCues(intent);
|
|
72
|
+
if (intent && cueScore >= 20) {
|
|
73
|
+
const summary = summarizeStyleCues(intent);
|
|
301
74
|
return {
|
|
302
75
|
resolution: 'inferred',
|
|
303
|
-
|
|
304
|
-
confidence:
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
guidanceEn: `Inferred style “${best.preset.titleEn}” (${best.preset.id}). User may switch: ${candidates.map((c) => `${c.id}/${c.titleEn}`).join(', ')}.`,
|
|
76
|
+
summary,
|
|
77
|
+
confidence: cueScore,
|
|
78
|
+
guidanceZh: `从提示词推断风格方向:「${summary}」。若不符请用户纠正。不确定时应先问,不要静默发明。`,
|
|
79
|
+
guidanceEn: `Inferred style direction: “${summary}”. Ask the user to correct if wrong. When unsure, ask — do not invent silently.`,
|
|
308
80
|
};
|
|
309
81
|
}
|
|
310
82
|
return {
|
|
311
|
-
resolution: '
|
|
83
|
+
resolution: 'ask',
|
|
312
84
|
confidence: 0,
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
title: preset.title,
|
|
316
|
-
titleEn: preset.titleEn,
|
|
317
|
-
score: 0,
|
|
318
|
-
})),
|
|
319
|
-
guidanceZh: '未检测到明确风格。若用户已给参考样式,按参考提取并映射到 --m-*;否则用一句话请用户从 quiet/soft/dense/rail/studio/ink 中选,或按提示词域启发式选择(不要永远 quiet)。',
|
|
320
|
-
guidanceEn: 'No clear style. If the user gave a reference, extract cues onto --m-*; otherwise ask once among quiet/soft/dense/rail/studio/ink, or pick by domain heuristic (do not always use quiet).',
|
|
85
|
+
guidanceZh: '风格不确定:请先向用户询问(描述气质,或贴参考图/现有页)。有明确参考或明确描述时必须跟用户。禁止在未询问时套 AI 默认渐变/霓虹/毛玻璃。',
|
|
86
|
+
guidanceEn: 'Style uncertain: ask the user for a short description or a reference. When they give a reference or clear words, follow them. Never apply AI-default gradients/neon/glass without asking.',
|
|
321
87
|
};
|
|
322
88
|
}
|
|
89
|
+
function scoreStyleCues(query) {
|
|
90
|
+
const q = query.toLowerCase();
|
|
91
|
+
let score = 0;
|
|
92
|
+
const hits = [
|
|
93
|
+
[/毛玻璃|glass|frosted|霓虹|neon|渐变|gradient|新拟态|neumorph|大屏|datav|暗黑|cyber/i, 35],
|
|
94
|
+
[/简洁|克制|扁平|flat|商务|erp|crm|政企|政务|国企|留白|极简|黑白|卡片|看板|仪表盘|cms|内容管理/i, 28],
|
|
95
|
+
[/像.+一样|参考|截图|设计稿|mock|figma/i, 40],
|
|
96
|
+
[/saas|工具后台|运营后台|监控|安全/i, 18],
|
|
97
|
+
];
|
|
98
|
+
for (const [re, pts] of hits) {
|
|
99
|
+
if (re.test(q))
|
|
100
|
+
score += pts;
|
|
101
|
+
}
|
|
102
|
+
return score;
|
|
103
|
+
}
|
|
104
|
+
function summarizeStyleCues(intent) {
|
|
105
|
+
const q = intent.toLowerCase();
|
|
106
|
+
if (/毛玻璃|glass|frosted/.test(q))
|
|
107
|
+
return '半透明毛玻璃气质(仅当用户明确要求)';
|
|
108
|
+
if (/霓虹|neon|暗黑科技|cyber/.test(q))
|
|
109
|
+
return '深色 + 克制科技强调';
|
|
110
|
+
if (/渐变|gradient/.test(q))
|
|
111
|
+
return '有克制的色彩渐变(chrome/品牌条,非 aurora)';
|
|
112
|
+
if (/新拟态|neumorph/.test(q))
|
|
113
|
+
return '新拟态柔和凹凸(展示向)';
|
|
114
|
+
if (/大屏|wallboard|datav/.test(q))
|
|
115
|
+
return '深色数据大屏:大数字、轻动态';
|
|
116
|
+
if (/政企|政务|国企/.test(q))
|
|
117
|
+
return '方正严谨、偏政企正式';
|
|
118
|
+
if (/erp|crm|商务/.test(q))
|
|
119
|
+
return '稳重商务、清晰分区';
|
|
120
|
+
if (/看板|仪表盘|kpi|卡片/.test(q))
|
|
121
|
+
return '模块化卡片/指标看板';
|
|
122
|
+
if (/cms|内容管理/.test(q))
|
|
123
|
+
return '紧凑表格优先的内容管理';
|
|
124
|
+
if (/极简|黑白|排版/.test(q))
|
|
125
|
+
return '黑白灰、排版层级';
|
|
126
|
+
if (/扁平|flat/.test(q))
|
|
127
|
+
return '纯色扁平、少阴影';
|
|
128
|
+
if (/简洁|克制|留白|saas|工具/.test(q))
|
|
129
|
+
return '简洁克制、少装饰';
|
|
130
|
+
return '按提示词气质落地(克制、token 实色优先)';
|
|
131
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Token-only signature shells for Account / Express / Flow / Ops.
|
|
3
|
+
* Pasteable CSS — no hex; brand differences belong in theme overrides.
|
|
4
|
+
*/
|
|
5
|
+
export interface StyleShell {
|
|
6
|
+
id: string;
|
|
7
|
+
surface: string;
|
|
8
|
+
titleZh: string;
|
|
9
|
+
titleEn: string;
|
|
10
|
+
signatureZh: string;
|
|
11
|
+
signatureEn: string;
|
|
12
|
+
whenZh: string;
|
|
13
|
+
whenEn: string;
|
|
14
|
+
css: string;
|
|
15
|
+
htmlHintZh: string;
|
|
16
|
+
htmlHintEn: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const styleShells: StyleShell[];
|
|
19
|
+
export declare function findStyleShell(idOrSurface: string): StyleShell | undefined;
|
|
20
|
+
export declare function listStyleShells(surface?: string): StyleShell[];
|