@morya-ui/setup 0.2.7 → 0.2.8

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.
Files changed (31) hide show
  1. package/README.md +2 -8
  2. package/package.json +1 -1
  3. package/src/cli.mjs +9 -28
  4. package/src/styles.mjs +2 -87
  5. package/template/.agents/skills/morya-ui-pages/SKILL.md +1 -3
  6. package/template/.agents/skills/morya-ui-pages/references/component-index.md +7 -1
  7. package/template/.agents/skills/morya-ui-pages/references/design-system.md +1 -1
  8. package/template/.agents/skills/morya-ui-pages/references/feedback.md +1 -1
  9. package/template/.agents/skills/morya-ui-pages/references/page-layouts.md +10 -10
  10. package/template/.agents/skills/morya-ui-pages/references/surfaces.md +3 -3
  11. package/template/.cursor/rules/component-usage.mdc +2 -2
  12. package/template/.cursor/rules/design-system.mdc +5 -5
  13. package/template/.cursor/rules/page-layout.mdc +7 -9
  14. package/template/DESIGN.md +14 -14
  15. package/template/design-tokens/tokens.css +0 -55
  16. package/template/design-tokens/tokens.json +0 -77
  17. package/template/docs/components.md +0 -145
  18. package/template/docs/feedback-message-vs-toast.md +0 -103
  19. package/template/docs/golden-pages/dashboard-page.vue +0 -103
  20. package/template/docs/golden-pages/empty-state.vue +0 -66
  21. package/template/docs/golden-pages/form-page.vue +0 -107
  22. package/template/docs/golden-pages/landing-page.vue +0 -328
  23. package/template/docs/golden-pages/list-page.vue +0 -138
  24. package/template/docs/golden-pages/login-page.vue +0 -191
  25. package/template/src/examples/DashboardPageExample.vue +0 -103
  26. package/template/src/examples/EmptyStateExample.vue +0 -66
  27. package/template/src/examples/FormPageExample.vue +0 -107
  28. package/template/src/examples/LandingPageExample.vue +0 -328
  29. package/template/src/examples/ListPageExample.vue +0 -138
  30. package/template/src/examples/LoginPageExample.vue +0 -191
  31. package/template/src/styles/morya-app-shell.css +0 -6
package/README.md CHANGED
@@ -9,7 +9,7 @@ Docs (zh/en):
9
9
  - [Agent Skill](https://morya-space.github.io/morya-ui/docs/agent-skill) — `morya-ui-pages` behavior
10
10
  - [Quick start](https://morya-space.github.io/morya-ui/docs/quick-start) — install and first component
11
11
 
12
- Installs the UI library, copies Agent skill / Cursor rules / design docs from `design-kit`, merges Cursor MCP for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp), injects `import 'morya-ui/styles.css'`, and writes `src/styles/morya-app-shell.css` with its entry import.
12
+ Installs the UI library, copies Agent skill / Cursor rules / design docs from `design-kit`, merges Cursor MCP for [`@morya-ui/mcp`](https://www.npmjs.com/package/@morya-ui/mcp), and injects `import 'morya-ui/styles.css'`.
13
13
 
14
14
  ## Usage
15
15
 
@@ -40,7 +40,7 @@ npx @morya-ui/setup app
40
40
  | `--skip-install` | Do not install `morya-ui` |
41
41
  | `--skip-template` | Do not copy AI skill / rules / docs / tokens |
42
42
  | `--skip-mcp` | Do not write `.cursor/mcp.json` |
43
- | `--skip-styles` | Do not inject `styles.css` / write app-shell CSS |
43
+ | `--skip-styles` | Do not inject `styles.css` |
44
44
  | `--skip-scripts` | Do not add `check:colors` to `package.json` |
45
45
  | `-h`, `--help` | Show help |
46
46
 
@@ -64,12 +64,7 @@ From the package `template/` (synced from repo `design-kit/`):
64
64
  - `DESIGN.md`
65
65
  - `.agents/skills/morya-ui-pages/`
66
66
  - `.cursor/rules/`
67
- - `docs/` (component index, golden pages, feedback guide)
68
- - `design-tokens/`
69
67
  - `scripts/check-raw-colors.mjs`
70
- - `src/examples/`
71
-
72
- `morya-app-shell.css` is written by the CLI (not copied from the template tree).
73
68
 
74
69
  ### MCP (Cursor)
75
70
 
@@ -96,7 +91,6 @@ Looks for `src/main.ts` / `.js` / `.tsx` / `.jsx`, root `main.*`, `src/app.ts` /
96
91
 
97
92
  ```ts
98
93
  import 'morya-ui/styles.css'
99
- import './styles/morya-app-shell.css'
100
94
  ```
101
95
 
102
96
  The CLI does **not** call `app.use(MoryaUI)` or edit `App.vue`.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@morya-ui/setup",
3
3
  "type": "module",
4
- "version": "0.2.7",
4
+ "version": "0.2.8",
5
5
  "description": "One-shot setup for morya-ui: install the library, Cursor MCP, Agent skills, and design config.",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/morya-space/morya-ui/tree/main/packages/setup#readme",
package/src/cli.mjs CHANGED
@@ -6,7 +6,7 @@ import { readJson } from './fs-utils.mjs'
6
6
  import { installMoryaUi } from './install.mjs'
7
7
  import { mergeMcpConfig } from './mcp.mjs'
8
8
  import { ensureCheckColorsScript } from './package-json.mjs'
9
- import { ensureShellStyles, ensureStylesImport } from './styles.mjs'
9
+ import { ensureStylesImport } from './styles.mjs'
10
10
 
11
11
  const __dirname = dirname(fileURLToPath(import.meta.url))
12
12
  const PKG_ROOT = resolve(__dirname, '..')
@@ -14,15 +14,12 @@ const TEMPLATE_ROOT = join(PKG_ROOT, 'template')
14
14
 
15
15
  const MODES = new Set(['app', 'ai', 'full'])
16
16
 
17
- /** AI pack paths under template/ (excludes runtime src/styles — owned by app mode). */
17
+ /** AI pack paths under template/. */
18
18
  const AI_TEMPLATE_INCLUDE = [
19
19
  'DESIGN.md',
20
20
  '.agents/skills/morya-ui-pages',
21
21
  '.cursor/rules',
22
- 'docs',
23
- 'design-tokens',
24
22
  'scripts/check-raw-colors.mjs',
25
- 'src/examples',
26
23
  ]
27
24
 
28
25
  /** Mode → default skips (user --skip-* can only add more skips). */
@@ -45,16 +42,15 @@ export function printHelp() {
45
42
 
46
43
  Commands:
47
44
  (default) / full Install morya-ui, AI template, MCP, styles, check:colors
48
- app Install morya-ui and inject styles / app-shell CSS
49
- ai Copy Agent skill / rules / DESIGN / docs / tokens / examples,
45
+ app Install morya-ui and inject styles.css
46
+ ai Copy Agent skill / rules / DESIGN,
50
47
  merge Cursor MCP, add check:colors
51
48
 
52
49
  Default command:
53
50
  - install morya-ui
54
- - copy DESIGN.md, Agent skill, Cursor rules, docs, tokens, examples
51
+ - copy DESIGN.md, Agent skill, Cursor rules
55
52
  - merge .cursor/mcp.json for @morya-ui/mcp
56
53
  - inject import 'morya-ui/styles.css' into the app entry when found
57
- - write src/styles/morya-app-shell.css and inject its import
58
54
  - add check:colors script when missing
59
55
 
60
56
  Options:
@@ -65,7 +61,7 @@ Options:
65
61
  --skip-install Skip dependency install
66
62
  --skip-template Skip copying AI template files
67
63
  --skip-mcp Skip writing .cursor/mcp.json
68
- --skip-styles Skip injecting styles.css / app-shell CSS
64
+ --skip-styles Skip injecting styles.css
69
65
  --skip-scripts Skip adding check:colors to package.json
70
66
  -h, --help Show this help
71
67
  `)
@@ -210,10 +206,6 @@ export async function runSetup(options) {
210
206
  ? { action: 'skipped', reason: 'skip-styles' }
211
207
  : ensureStylesImport(cwd, { dryRun })
212
208
 
213
- const shell = skipStyles
214
- ? { fileAction: 'skipped', importAction: 'skipped', reason: 'skip-styles' }
215
- : ensureShellStyles(cwd, { dryRun, force })
216
-
217
209
  const scripts = skipScripts
218
210
  ? { action: 'skipped-flag' }
219
211
  : ensureCheckColorsScript(cwd, { force, dryRun })
@@ -256,17 +248,6 @@ export async function runSetup(options) {
256
248
  console.log(" import 'morya-ui/styles.css'")
257
249
  }
258
250
 
259
- if (shell.reason === 'skip-styles') {
260
- console.log('Shell CSS: skipped (--skip-styles or ai mode)')
261
- } else {
262
- console.log(
263
- `Shell CSS: file ${shell.fileAction}`
264
- + (shell.path ? ` (${rel(cwd, shell.path)})` : '')
265
- + `, import ${shell.importAction}`
266
- + (shell.entry ? ` (${rel(cwd, shell.entry)})` : ''),
267
- )
268
- }
269
-
270
251
  if (scripts.action === 'skipped-flag') {
271
252
  console.log('Scripts: skipped (--skip-scripts or app mode)')
272
253
  } else {
@@ -276,18 +257,18 @@ export async function runSetup(options) {
276
257
  console.log('')
277
258
  console.log('Next:')
278
259
  if (mode === 'app') {
279
- console.log(' 1. Ensure styles.css + morya-app-shell.css imports are in your app entry.')
260
+ console.log(' 1. Ensure the styles.css import is in your app entry.')
280
261
  console.log(' 2. Optional AI pack: npx @morya-ui/setup ai')
281
262
  } else if (mode === 'ai') {
282
263
  console.log(' 1. Restart Cursor (or reload MCP) so morya-ui MCP tools appear.')
283
264
  console.log(' 2. Have the agent read DESIGN.md before generating pages.')
284
265
  console.log(' 3. Optional: pnpm check:colors')
285
266
  } else {
286
- console.log(' 1. Ensure styles.css + morya-app-shell.css imports are in your app entry.')
267
+ console.log(' 1. Ensure the styles.css import is in your app entry.')
287
268
  console.log(' 2. Restart Cursor (or reload MCP) so morya-ui MCP tools appear.')
288
269
  console.log(' 3. Have the agent read DESIGN.md before generating pages.')
289
270
  console.log(' 4. Optional: pnpm check:colors')
290
271
  }
291
272
 
292
- return { mode, install, template, mcp, styles, shell, scripts }
273
+ return { mode, install, template, mcp, styles, scripts }
293
274
  }
package/src/styles.mjs CHANGED
@@ -1,10 +1,8 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
2
- import { dirname, join, relative, resolve } from 'node:path'
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs'
2
+ import { join, resolve } from 'node:path'
3
3
 
4
4
  const STYLE_IMPORT = "import 'morya-ui/styles.css'"
5
5
  const STYLE_MARKER = 'morya-ui/styles.css'
6
- const SHELL_MARKER = 'morya-app-shell.css'
7
- const SHELL_REL = 'src/styles/morya-app-shell.css'
8
6
 
9
7
  const CANDIDATES = [
10
8
  'src/main.ts',
@@ -17,14 +15,6 @@ const CANDIDATES = [
17
15
  'src/app.js',
18
16
  ]
19
17
 
20
- const SHELL_CSS = `html,
21
- body,
22
- #app {
23
- height: 100%;
24
- margin: 0;
25
- }
26
- `
27
-
28
18
  /**
29
19
  * @param {string} cwd
30
20
  * @returns {string | null} absolute path
@@ -100,16 +90,6 @@ export function injectStyleImport(source) {
100
90
  return injectImportLine(source, STYLE_IMPORT, STYLE_MARKER)
101
91
  }
102
92
 
103
- /**
104
- * @param {string} entryFile absolute
105
- * @param {string} shellFile absolute
106
- */
107
- export function shellImportLine(entryFile, shellFile) {
108
- let rel = relative(dirname(entryFile), shellFile).replace(/\\/g, '/')
109
- if (!rel.startsWith('.')) rel = `./${rel}`
110
- return `import '${rel}'`
111
- }
112
-
113
93
  /**
114
94
  * @returns {{
115
95
  * action: 'injected' | 'skipped' | 'missing-entry',
@@ -137,68 +117,3 @@ export function ensureStylesImport(cwd, { dryRun = false } = {}) {
137
117
 
138
118
  return { action: 'injected', path: entry, dryRun }
139
119
  }
140
-
141
- /**
142
- * Write morya-app-shell.css (height chain) and inject its import into the entry.
143
- * @returns {{
144
- * fileAction: 'written' | 'skipped' | 'dry-run',
145
- * importAction: 'injected' | 'skipped' | 'missing-entry',
146
- * path?: string,
147
- * entry?: string,
148
- * reason?: string,
149
- * dryRun?: boolean
150
- * }}
151
- */
152
- export function ensureShellStyles(cwd, { dryRun = false, force = false } = {}) {
153
- const shellFile = join(cwd, SHELL_REL)
154
- const entry = findEntryFile(cwd)
155
-
156
- let fileAction = 'skipped'
157
- if (!existsSync(shellFile) || force) {
158
- if (dryRun) {
159
- fileAction = 'dry-run'
160
- }
161
- else {
162
- mkdirSync(dirname(shellFile), { recursive: true })
163
- writeFileSync(shellFile, SHELL_CSS, 'utf8')
164
- fileAction = 'written'
165
- }
166
- }
167
-
168
- if (!entry) {
169
- return {
170
- fileAction,
171
- importAction: 'missing-entry',
172
- path: shellFile,
173
- reason: 'no-entry-found',
174
- dryRun,
175
- }
176
- }
177
-
178
- const importLine = shellImportLine(entry, shellFile)
179
- const original = readFileSync(entry, 'utf8')
180
- const { source, changed, reason } = injectImportLine(original, importLine, SHELL_MARKER)
181
-
182
- if (!changed) {
183
- return {
184
- fileAction,
185
- importAction: 'skipped',
186
- path: shellFile,
187
- entry,
188
- reason: reason || 'already-present',
189
- dryRun,
190
- }
191
- }
192
-
193
- if (!dryRun) {
194
- writeFileSync(entry, source, 'utf8')
195
- }
196
-
197
- return {
198
- fileAction,
199
- importAction: 'injected',
200
- path: shellFile,
201
- entry,
202
- dryRun,
203
- }
204
- }
@@ -44,9 +44,7 @@ Full taxonomy: [references/surfaces.md](references/surfaces.md).
44
44
 
45
45
  1. `morya-ui` installed; `morya-ui/styles.css` imported.
46
46
  2. Prefer `@morya-ui/mcp` — never invent prop / event / slot names.
47
- 3. If the AI config pack is merged, prefer project files over bundled copies:
48
- - `DESIGN.md`
49
- - `docs/golden-pages/*.vue`, `docs/components.md`, `docs/feedback-message-vs-toast.md`
47
+ 3. Golden pages, component APIs, and feedback rules come from `@morya-ui/mcp`. Without MCP, use this skill's `references/`. Project `DESIGN.md` overrides generic taste when the AI pack is merged.
50
48
 
51
49
  ## Workflow
52
50
 
@@ -32,7 +32,11 @@ Full API: docs site `/components` or MCP (`get_component`, `search`, `validate_u
32
32
  | `<MMessage>` | Persistent in-page error / warning |
33
33
  | `MEmpty` | No-data / first-use / filtered empty (not an error) |
34
34
  | `MResult` | Terminal outcome: success, failure, 403 / 404 / 500 |
35
- | `MProgressBar` / `MProgressSpinner` / `MSkeleton` / `MBlockUI` | Loading / blocking |
35
+ | `MLoading` / `v-loading` / `loading.service` | **Default** region or fullscreen loading mask |
36
+ | `MSkeleton` | Layout is already known; placeholder while content arrives |
37
+ | `MProgressBar` | Determinate progress |
38
+ | `MProgressSpinner` | Inline spinner only, not a region mask |
39
+ | `MBlockUI` | Block interaction without a loading message |
36
40
 
37
41
  ## Overlays & menus
38
42
 
@@ -59,6 +63,7 @@ Full API: docs site `/components` or MCP (`get_component`, `search`, `validate_u
59
63
  | Marketing landing | `landing-page` golden + `MButton` / `MTag` / `MAccordion` |
60
64
  | Empty list / zero state | `MEmpty` (+ `empty-state` golden or `MTable` `#empty`) |
61
65
  | Submit success / HTTP error page | `MResult` |
66
+ | Region or page is waiting | `MLoading`, `v-loading`, or `loading.service`; known layout → `MSkeleton` |
62
67
  | Local capped scroll | Explicit `MScrollbar` |
63
68
  | Admin sider nav | `MMenu` |
64
69
 
@@ -69,5 +74,6 @@ Full API: docs site `/components` or MCP (`get_component`, `search`, `validate_u
69
74
  | `MDropdown` as form enum | `MSelect` |
70
75
  | Hand `<table>` | `MTable` |
71
76
  | Hand modal div | `MDialog` |
77
+ | Hand spinner or `MProgressSpinner` as a region / page mask | `MLoading` / `v-loading` |
72
78
  | Extra `MCard` around every `MPage*` block | Use page components' own surface/gap |
73
79
  | Assume undocumented props | MCP / docs lookup |
@@ -87,7 +87,7 @@ import 'morya-ui/styles.css'
87
87
  | Card radius | `--m-radius-md` |
88
88
  | Card shadow | `--m-shadow-md` |
89
89
 
90
- Full machine-readable set: project `design-tokens/tokens.json` (runtime truth remains `morya-ui/styles.css`).
90
+ Full set: MCP `get_design_rules`. Runtime truth remains `morya-ui/styles.css`.
91
91
 
92
92
  ## Bans
93
93
 
@@ -46,7 +46,7 @@ toast.success({
46
46
  ## Prefer `<MMessage>` / form-level errors
47
47
 
48
48
  - Field validation: component `invalid` / `errorMessage` (preferred).
49
- - Form-level persistent errors (login/auth): token-styled `role="alert"` bar as in `docs/golden-pages/login-page.vue`.
49
+ - Form-level persistent errors (login/auth): token-styled `role="alert"` bar as in MCP `get_golden_page` `login-page`.
50
50
  - Note: `<MMessage>` today is primarily the **message service host** (`messages` / teleport). Do not invent a `severity` + default-slot Alert API unless docs add it.
51
51
 
52
52
  ```vue
@@ -1,15 +1,15 @@
1
1
  # Page layouts
2
2
 
3
- When generating a full page, pick a type and **mirror the golden-page block order**. Prefer project files when present:
4
-
5
- | Type | Golden page | Runnable example |
6
- | --- | --- | --- |
7
- | List | `docs/golden-pages/list-page.vue` | `src/examples/ListPageExample.vue` |
8
- | Form | `docs/golden-pages/form-page.vue` | `src/examples/FormPageExample.vue` |
9
- | Dashboard | `docs/golden-pages/dashboard-page.vue` | `src/examples/DashboardPageExample.vue` |
10
- | Login | `docs/golden-pages/login-page.vue` | `src/examples/LoginPageExample.vue` |
11
- | Landing | `docs/golden-pages/landing-page.vue` | `src/examples/LandingPageExample.vue` |
12
- | Empty | `docs/golden-pages/empty-state.vue` | `src/examples/EmptyStateExample.vue` |
3
+ When generating a full page, pick a type and **mirror the golden-page block order**. Source: MCP `get_golden_page`.
4
+
5
+ | Type | `get_golden_page` id |
6
+ | --- | --- |
7
+ | List | `list-page` |
8
+ | Form | `form-page` |
9
+ | Dashboard | `dashboard-page` |
10
+ | Login | `login-page` |
11
+ | Landing | `landing-page` |
12
+ | Empty | `empty-state` |
13
13
 
14
14
  Via MCP: `recommend_page` → `get_golden_page`; local edits: `get_page_snippet` (`filters`, `toolbar`, `form-actions`, `scrollable-panel`, …).
15
15
 
@@ -17,7 +17,7 @@ Pick a lane, then a surface. Prefer project golden pages for **Ops**; use the re
17
17
 
18
18
  | Surface | Job | Recipe |
19
19
  | --- | --- | --- |
20
- | Login / register | Authenticate with trust | Golden: `docs/golden-pages/login-page.vue` — split brand + `MForm` (`MInput`, `MInputPassword`); form-level errors via token `role="alert"` (not Toast) |
20
+ | Login / register | Authenticate with trust | Golden: MCP `get_golden_page` `login-page` — split brand + `MForm` (`MInput`, `MInputPassword`); form-level errors via token `role="alert"` (not Toast) |
21
21
  | Invite / accept | Join org | Same shell; show org name clearly |
22
22
  | Forgot / reset | Recover access | Short form + success state with next step |
23
23
  | Profile / account | Edit self | Settings-like sections; avatar via `MAvatar` |
@@ -28,7 +28,7 @@ Keep credential forms quiet: one primary CTA, clear labels, no decorative noise
28
28
 
29
29
  | Surface | Job | Recipe |
30
30
  | --- | --- | --- |
31
- | Empty state | Invite first action | Golden: `docs/golden-pages/empty-state.vue` — `MEmpty` + primary/secondary `MButton` in `#extra` |
31
+ | Empty state | Invite first action | Golden: MCP `get_golden_page` `empty-state` — `MEmpty` + primary/secondary `MButton` in `#extra` |
32
32
  | Onboarding | Teach the product path | `MStepper` or paced cards; one decision per step; finish → Ops home |
33
33
  | Wizard | Multi-step create | `MStepper` + `MForm` per step + sticky actions (`上一步` / `下一步` / `提交`) |
34
34
  | Success / result | Confirm completion | `MResult` (`status="success"` / `error` …) + next actions (`查看详情` / `返回列表`) |
@@ -51,7 +51,7 @@ Use when the brief is landing, pricing, launch, or docs marketing — **not** fo
51
51
 
52
52
  | Surface | Job | Recipe |
53
53
  | --- | --- | --- |
54
- | Landing | Convert / explain product | Golden: `docs/golden-pages/landing-page.vue` — one-job hero; CTAs → `MButton`; chips → `MTag`; FAQ → `MAccordion` |
54
+ | Landing | Convert / explain product | Golden: MCP `get_golden_page` `landing-page` — one-job hero; CTAs → `MButton`; chips → `MTag`; FAQ → `MAccordion` |
55
55
  | Pricing | Choose a plan | Clear plan cards (`MCard`) + primary CTA; highlight recommended plan without clutter |
56
56
  | Feature showcase | Prove capability | Alternating media/copy; live `M*` demo only if lightweight |
57
57
  | Docs marketing chrome | Frame documentation | Header + nav using `M*` where suitable; content area stays readable |
@@ -23,7 +23,7 @@ import { MButton, MInput } from 'morya-ui'
23
23
  - 单行操作结果 → `message.success/info/warn/error('…')`
24
24
  - 有标题 + 详情 / 异步通知 → `toast.*({ summary, detail })`
25
25
  - 表单区常驻错误 → `<MMessage>` 或字段 `errorMessage`
26
- - 详见 `docs/feedback-message-vs-toast.md`
26
+ - 详见 skill `references/feedback.md`
27
27
 
28
28
  ## Props 约定
29
29
 
@@ -38,4 +38,4 @@ import { MButton, MInput } from 'morya-ui'
38
38
  - 用 `MDropdown` 代替 Select 做枚举选择。
39
39
  - 手写 table/modal 替代 `MTable` / `MDialog`。
40
40
 
41
- 完整清单:`docs/components.md`
41
+ 完整清单:MCP,或 skill `references/component-index.md`
@@ -1,17 +1,17 @@
1
1
  ---
2
- description: Morya UI 设计系统第一信源。生成或修改 UI 前必读 DESIGN.md 与 design-tokens。
2
+ description: Morya UI 设计系统第一信源。生成或修改 UI 前必读 DESIGN.md。
3
3
  alwaysApply: true
4
4
  ---
5
5
 
6
6
  # Morya UI 设计系统
7
7
 
8
- 1. **先读** 项目根目录 `DESIGN.md`,再读 `docs/components.md`。
8
+ 1. **先读** 项目根目录 `DESIGN.md`。组件选型用 MCP,或 skill `references/component-index.md`。
9
9
  2. **只用** `morya-ui` 的 `M*` 组件;全局样式 `morya-ui/styles.css`。
10
10
  3. **颜色/间距/圆角** 使用 `--m-*` CSS 变量,禁止裸 hex/rgb(见 `scripts/check-raw-colors.mjs`)。
11
- 4. **页面结构** 对齐 `docs/golden-pages/`(列表 / 表单 / 仪表盘 / 登录 / 落地 / 空状态),不要发明新布局范式。
11
+ 4. **页面结构** 用 MCP `get_golden_page`(`list-page` / `form-page` / `dashboard-page` / `login-page` / `landing-page` / `empty-state`),不要发明新布局范式。
12
12
  5. **表单选项** 用 `MSelect` / `MTreeSelect`;**动作菜单** 用 `MDropdown`。
13
13
  6. 不确定 API 时查文档站或 MCP,**禁止臆造 prop**。
14
14
  7. 根节点用 `MConfigProvider`;后台布局用 `MLayout` 系列。
15
- 8. **操作反馈默认 `message` API**;仅 `summary + detail` 或异步通知用 `toast`;表单常驻错误用 `<MMessage>`。见 `docs/feedback-message-vs-toast.md`。
15
+ 8. **操作反馈默认 `message` API**;仅 `summary + detail` 或异步通知用 `toast`;表单常驻错误用 `<MMessage>`。见 skill `references/feedback.md`。
16
16
 
17
- Token 参考:`design-tokens/tokens.json`
17
+ Token 参考:MCP `get_design_rules`(运行时以 `morya-ui/styles.css` 为准)
@@ -7,14 +7,14 @@ alwaysApply: false
7
7
 
8
8
  生成完整页面时,先确定类型并 **复制黄金样例结构**:
9
9
 
10
- | 类型 | 模板 |
10
+ | 类型 | MCP `get_golden_page` |
11
11
  | --- | --- |
12
- | 列表页 | `docs/golden-pages/list-page.vue` |
13
- | 表单页 | `docs/golden-pages/form-page.vue`(仅长表单 / 独立配置页) |
14
- | 仪表盘 | `docs/golden-pages/dashboard-page.vue` |
15
- | 登录页 | `docs/golden-pages/login-page.vue` |
16
- | 营销落地 | `docs/golden-pages/landing-page.vue` |
17
- | 空状态 | `docs/golden-pages/empty-state.vue` |
12
+ | 列表页 | `list-page` |
13
+ | 表单页 | `form-page`(仅长表单 / 独立配置页) |
14
+ | 仪表盘 | `dashboard-page` |
15
+ | 登录页 | `login-page` |
16
+ | 营销落地 | `landing-page` |
17
+ | 空状态 | `empty-state` |
18
18
 
19
19
  ## 列表内新建 / 编辑(默认)
20
20
 
@@ -69,5 +69,3 @@ alwaysApply: false
69
69
  - 整页:`recommend_page` → `get_golden_page` → `get_design_rules`
70
70
  - 局部:`get_page_snippet`(如 `filters` / `toolbar` / `form-actions` / `scrollable-panel`)
71
71
  - 可选:`validate_page`(参考建议,不阻断)
72
-
73
- 引用可运行示例:`src/examples/*PageExample.vue`
@@ -1,6 +1,6 @@
1
1
  # Morya UI 设计系统(AI 第一信源)
2
2
 
3
- > 基于 `morya-ui` v0.2.6。生成或审查业务页面时,**必须先遵守本文**,再查阅 `docs/components.md` 与 `docs/golden-pages/`。
3
+ > 基于 `morya-ui` v0.2.6。生成或审查业务页面时,**必须先遵守本文**。样例用 MCP `get_golden_page`,组件 API 用 MCP,反馈选型见 `morya-ui-pages` skill 的 `references/feedback.md`。
4
4
 
5
5
  ## 1. 设计原则
6
6
 
@@ -49,14 +49,14 @@ import 'morya-ui/styles.css'
49
49
 
50
50
  ## 3. 页面类型与黄金样例
51
51
 
52
- | 类型 | 参考文件 | 必备区块 |
52
+ | 类型 | MCP `get_golden_page` | 必备区块 |
53
53
  | --- | --- | --- |
54
- | 列表页 | `docs/golden-pages/list-page.vue` | 面包屑、筛选区、工具栏、表格、分页 |
55
- | 表单页 | `docs/golden-pages/form-page.vue` | 面包屑、分组表单、`MForm` / `MFormItem`、提交/取消 |
56
- | 仪表盘 | `docs/golden-pages/dashboard-page.vue` | 统计卡片栅格、图表区占位、快捷入口 / 最近列表 |
57
- | 登录页 | `docs/golden-pages/login-page.vue` | 品牌区 + `MForm` / `MInputPassword`;表单级错误用 token 告警条 |
58
- | 营销落地 | `docs/golden-pages/landing-page.vue` | 单任务首屏、分节、`MButton` / `MTag` / `MAccordion` |
59
- | 空状态 | `docs/golden-pages/empty-state.vue` | `MEmpty` + 说明 + 主 CTA;可嵌列表 `#empty` |
54
+ | 列表页 | `list-page` | 面包屑、筛选区、工具栏、表格、分页 |
55
+ | 表单页 | `form-page` | 面包屑、分组表单、`MForm` / `MFormItem`、提交/取消 |
56
+ | 仪表盘 | `dashboard-page` | 统计卡片栅格、图表区占位、快捷入口 / 最近列表 |
57
+ | 登录页 | `login-page` | 品牌区 + `MForm` / `MInputPassword`;表单级错误用 token 告警条 |
58
+ | 营销落地 | `landing-page` | 单任务首屏、分节、`MButton` / `MTag` / `MAccordion` |
59
+ | 空状态 | `empty-state` | `MEmpty` + 说明 + 主 CTA;可嵌列表 `#empty` |
60
60
 
61
61
  生成 **Ops** 页面时:结构对齐对应黄金样例,用 `MPage*` 拼装,尽量少写 scoped CSS。
62
62
  生成 **Account / Express / Flow** 页面时:对齐上表样例;允许有节制的 scoped 布局,但颜色/间距仍用 `--m-*`。
@@ -65,7 +65,7 @@ import 'morya-ui/styles.css'
65
65
 
66
66
  - 使用 `MForm` + `MFormItem`,`name` 与校验规则对应。
67
67
  - **从列表新建/编辑(字段约 ≤8、单段表单)默认用 `MDialog` + `MForm`,不要为每个实体再开独立路由表单页。**
68
- - 多分组、长流程、向导式录入再用独立表单页(`docs/golden-pages/form-page.vue`)或 `MDrawer`。
68
+ - 多分组、长流程、向导式录入再用独立表单页(MCP `get_golden_page` `form-page`)或 `MDrawer`。
69
69
  - 字段组件自带 `label` / `invalid` / `helpText` 时优先用组件 prop(如 `MInput`、`MSelect`),复杂表单再用 `MFormItem` 包一层。
70
70
  - 尺寸:默认 medium;密集后台可 `size="small"` 或 ConfigProvider `globalDensity`。
71
71
  - 宽度:筛选项 `fluid` 慎用;独立表单页主栏 `max-width: 40rem` 左右。
@@ -88,11 +88,11 @@ import 'morya-ui/styles.css'
88
88
  | 表单区常驻错误 | token 告警条 / 字段 `errorMessage` |
89
89
  | 字段说明 | `MTooltip` |
90
90
 
91
- **选型细则见 [`docs/feedback-message-vs-toast.md`](docs/feedback-message-vs-toast.md)。AI 生成代码时:无 `detail` 的操作回执一律用 `message`,不要默认 Toast。**
91
+ **选型细则见 `morya-ui-pages` skill 的 `references/feedback.md`。AI 生成代码时:无 `detail` 的操作回执一律用 `message`,不要默认 Toast。**
92
92
 
93
93
  ## 7. 设计令牌(摘要)
94
94
 
95
- 完整定义见 `design-tokens/tokens.json`。
95
+ 完整定义见 MCP `get_design_rules`。运行时以 `morya-ui/styles.css` 为准。
96
96
 
97
97
  | 用途 | 变量 |
98
98
  | --- | --- |
@@ -117,11 +117,11 @@ import 'morya-ui/styles.css'
117
117
  ## 9. AI 工作流
118
118
 
119
119
  1. 读本文 → 确定页面类型(列表 / 表单 / 仪表盘)。
120
- 2. 打开对应 `docs/golden-pages/*.vue` 与 `src/examples/*.vue`。
121
- 3. 查 `docs/components.md` 选型。
120
+ 2. 用 MCP `get_golden_page` 读取对应样例。
121
+ 3. 用 MCP `search` / `get_component` / `recommend_component` 选型。
122
122
  4. 不确定 API 时查文档站或 MCP,**不要臆造 prop 名**。
123
123
  5. 完成后运行 `pnpm check:colors`(若已配置)。
124
- 6. 操作反馈见 `docs/feedback-message-vs-toast.md`:**默认 `message`,有 detail 才用 `toast`**。
124
+ 6. 操作反馈见 skill `references/feedback.md`:**默认 `message`,有 detail 才用 `toast`**。
125
125
 
126
126
  ## 10. 相关资源
127
127
 
@@ -1,55 +0,0 @@
1
- /**
2
- * Morya UI design tokens (compiled view for AI / static tooling).
3
- * Runtime source of truth: morya-ui/styles.css
4
- * Do not hand-edit hex values in business code — use --m-* variables.
5
- */
6
- :root {
7
- --m-color-primary: #2563eb;
8
- --m-color-primary-hover: #1d4ed8;
9
- --m-color-surface: #ffffff;
10
- --m-color-text: #0f172a;
11
- --m-color-text-muted: #64748b;
12
- --m-color-border: #e2e8f0;
13
- --m-color-focus-ring: #2563eb;
14
- --m-color-success: #159570;
15
- --m-color-info: #2563eb;
16
- --m-color-warning: #d97706;
17
- --m-color-help: #9333ea;
18
- --m-color-danger: #dc2626;
19
- --m-color-contrast: #0f172a;
20
- --m-color-contrast-fg: #ffffff;
21
- --m-overlay-scrim: rgb(15 23 42 / 0.55);
22
-
23
- --m-control-height-small: 28px;
24
- --m-control-height-medium: 34px;
25
- --m-control-height-large: 40px;
26
- --m-radius-control: 3px;
27
- --m-space-1: 0.25rem;
28
- --m-space-2: 0.5rem;
29
- --m-space-3: 0.75rem;
30
- --m-space-4: 1rem;
31
- --m-space-6: 1.5rem;
32
- --m-space-8: 2rem;
33
- --m-radius-sm: 0.25rem;
34
- --m-radius-md: 0.5rem;
35
- --m-radius-lg: 0.75rem;
36
- --m-shadow-sm: 0 1px 2px rgb(15 23 42 / 0.25);
37
- --m-shadow-md: 0 0.75rem 2rem rgb(15 23 42 / 0.16);
38
- --m-shadow-lg: 0 1rem 3rem rgb(15 23 42 / 0.25);
39
- --m-font-sans: Inter, ui-sans-serif, system-ui, sans-serif;
40
- --m-motion-fast: 150ms;
41
- --m-motion-normal: 250ms;
42
- --m-motion-ease: cubic-bezier(0.2, 0, 0, 1);
43
- --m-z-base: 1000;
44
- }
45
-
46
- [data-theme="dark"] {
47
- --m-color-primary: #60a5fa;
48
- --m-color-primary-hover: #93c5fd;
49
- --m-color-surface: #0f172a;
50
- --m-color-text: #f8fafc;
51
- --m-color-text-muted: #94a3b8;
52
- --m-color-border: #334155;
53
- --m-color-danger: #fca5a5;
54
- --m-overlay-scrim: rgb(2 6 23 / 0.72);
55
- }
@@ -1,77 +0,0 @@
1
- {
2
- "$schema": "https://design-tokens.github.io/community-group/format/",
3
- "meta": {
4
- "name": "morya-ui",
5
- "version": "0.2.6",
6
- "source": "morya-ui/src/theme/styles.css",
7
- "prefix": "m"
8
- },
9
- "color": {
10
- "primary": { "value": "#2563eb", "dark": "#60a5fa" },
11
- "primary-hover": { "value": "#1d4ed8", "dark": "#93c5fd" },
12
- "surface": { "value": "#ffffff", "dark": "#0f172a" },
13
- "text": { "value": "#0f172a", "dark": "#f8fafc" },
14
- "text-muted": { "value": "#64748b", "dark": "#94a3b8" },
15
- "border": { "value": "#e2e8f0", "dark": "#334155" },
16
- "focus-ring": { "value": "#2563eb", "dark": "#93c5fd" },
17
- "success": { "value": "#159570", "dark": "#5eead4" },
18
- "info": { "value": "#2563eb", "dark": "#93c5fd" },
19
- "warning": { "value": "#d97706", "dark": "#fbbf24" },
20
- "help": { "value": "#9333ea", "dark": "#c084fc" },
21
- "danger": { "value": "#dc2626", "dark": "#fca5a5" },
22
- "contrast": { "value": "#0f172a", "dark": "#f8fafc" },
23
- "contrast-fg": { "value": "#ffffff", "dark": "#0f172a" },
24
- "overlay-scrim": { "value": "rgb(15 23 42 / 0.55)", "dark": "rgb(2 6 23 / 0.72)" }
25
- },
26
- "control": {
27
- "height": { "small": "28px", "medium": "34px", "large": "40px" },
28
- "font": { "small": "14px", "medium": "14px", "large": "15px" },
29
- "padding-x": { "small": "10px", "medium": "12px", "large": "14px" },
30
- "affix-size": "2rem"
31
- },
32
- "space": {
33
- "1": "0.25rem",
34
- "2": "0.5rem",
35
- "3": "0.75rem",
36
- "4": "1rem",
37
- "6": "1.5rem",
38
- "8": "2rem"
39
- },
40
- "radius": {
41
- "control": "3px",
42
- "sm": "0.25rem",
43
- "md": "0.5rem",
44
- "lg": "0.75rem",
45
- "full": "9999px"
46
- },
47
- "shadow": {
48
- "sm": "0 1px 2px rgb(15 23 42 / 0.25)",
49
- "md": "0 0.75rem 2rem rgb(15 23 42 / 0.16)",
50
- "lg": "0 1rem 3rem rgb(15 23 42 / 0.25)"
51
- },
52
- "font": {
53
- "sans": "Inter, ui-sans-serif, system-ui, sans-serif",
54
- "size": { "xs": "0.75rem", "sm": "0.8125rem", "md": "0.875rem", "lg": "1.125rem" }
55
- },
56
- "motion": {
57
- "fast": "150ms",
58
- "normal": "250ms",
59
- "ease": "cubic-bezier(0.2, 0, 0, 1)"
60
- },
61
- "zIndex": {
62
- "base": 1000,
63
- "dropdown": "calc(var(--m-z-base) + 50)",
64
- "toast": "calc(var(--m-z-base) + 100)"
65
- },
66
- "cssVarMap": {
67
- "color.primary": "--m-color-primary",
68
- "color.surface": "--m-color-surface",
69
- "color.text": "--m-color-text",
70
- "color.textMuted": "--m-color-text-muted",
71
- "color.border": "--m-color-border",
72
- "color.danger": "--m-color-danger",
73
- "space.4": "--m-space-4",
74
- "radius.md": "--m-radius-md",
75
- "shadow.md": "--m-shadow-md"
76
- }
77
- }