@morya-ui/setup 0.3.4 → 0.3.5
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 +11 -7
- package/bin/morya-ui-setup.js +0 -0
- package/package.json +3 -5
- package/src/cli.mjs +13 -36
- package/src/install.mjs +82 -11
- package/src/mcp.mjs +1 -1
- package/template/.agents/skills/morya-ui-pages/SKILL.md +50 -46
- package/template/.agents/skills/morya-ui-pages/evals/evals.json +16 -16
- package/template/.agents/skills/morya-ui-pages/references/decision-recipes.md +72 -5
- package/template/.agents/skills/morya-ui-pages/references/optional-companions.md +38 -83
- package/template/.agents/skills/morya-ui-pages/references/page-layouts.md +46 -54
- package/template/.agents/skills/morya-ui-pages/references/review-checklist.md +14 -15
- package/template/.agents/skills/morya-ui-pages/references/style-presets.md +31 -59
- package/template/.agents/skills/morya-ui-pages/references/surfaces.md +3 -3
- package/template/.agents/skills/morya-ui-pages/references/visual-craft.md +59 -151
- package/template/.cursor/rules/design-system.mdc +3 -3
- package/template/.cursor/rules/page-layout.mdc +23 -23
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Morya UI contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
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
|
|
12
|
+
Installs / upgrades the UI library and any existing `@morya-ui/*` packages to **latest**, copies first-party Agent skills / Cursor rules / design docs from `design-kit`, installs optional companion skills at **latest** via the [skills CLI](https://skills.sh/), 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
|
|
|
@@ -24,16 +24,19 @@ On a TTY, `full` / `ai` will prompt for optional Agent skills (required `morya-u
|
|
|
24
24
|
Other common commands:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
# AI config + MCP
|
|
27
|
+
# Upgrade deps + AI config + MCP (skips styles injection)
|
|
28
28
|
npx @morya-ui/setup ai
|
|
29
29
|
|
|
30
|
-
#
|
|
30
|
+
# Upgrade deps + styles only
|
|
31
31
|
npx @morya-ui/setup app
|
|
32
32
|
|
|
33
33
|
# Non-interactive skill selection
|
|
34
34
|
npx @morya-ui/setup ai --yes
|
|
35
35
|
npx @morya-ui/setup ai --skills=morya-ui-pages,frontend-design,impeccable
|
|
36
36
|
npx @morya-ui/setup ai --skills=all
|
|
37
|
+
|
|
38
|
+
# Refresh AI template / MCP without touching dependencies
|
|
39
|
+
npx @morya-ui/setup ai --skip-install
|
|
37
40
|
```
|
|
38
41
|
|
|
39
42
|
### Options
|
|
@@ -46,7 +49,7 @@ npx @morya-ui/setup ai --skills=all
|
|
|
46
49
|
| `--yes` / `-y` | Use default skills without prompting |
|
|
47
50
|
| `--force` | Overwrite existing template files and the `morya-ui` MCP entry |
|
|
48
51
|
| `--dry-run` | Print actions without writing or installing |
|
|
49
|
-
| `--skip-install` | Do not install `morya-ui` |
|
|
52
|
+
| `--skip-install` | Do not install / upgrade `morya-ui` or `@morya-ui/*` |
|
|
50
53
|
| `--skip-template` | Do not copy AI skill / rules / docs (also skips companion skill install) |
|
|
51
54
|
| `--skip-mcp` | Do not write `.cursor/mcp.json` |
|
|
52
55
|
| `--skip-styles` | Do not inject `styles.css` |
|
|
@@ -57,7 +60,7 @@ npx @morya-ui/setup ai --skills=all
|
|
|
57
60
|
|
|
58
61
|
| Id | Default | Install | Role |
|
|
59
62
|
| --- | --- | --- | --- |
|
|
60
|
-
| `morya-ui-pages` | required | template (from this package) | Page generation with `M*` +
|
|
63
|
+
| `morya-ui-pages` | required | template (from this package) | Page generation with `M*` + snippets / decisions (composition-first) |
|
|
61
64
|
| `frontend-design` | optional | skills CLI → `anthropics/skills` (latest) | Express / brand visual taste |
|
|
62
65
|
| `fixing-accessibility` | optional | skills CLI → `ibelick/ui-skills` (latest) | A11y audit and targeted fixes |
|
|
63
66
|
| `impeccable` | optional | skills CLI → `pbakaus/impeccable` (latest) | Named polish / audit / redesign passes |
|
|
@@ -66,9 +69,10 @@ Catalog: [`catalog/skills.json`](./catalog/skills.json).
|
|
|
66
69
|
|
|
67
70
|
### Conflict policy
|
|
68
71
|
|
|
72
|
+
- Dependencies: always install / upgrade `morya-ui@latest` and any existing `@morya-ui/*` (e.g. `@morya-ui/nuxt`) to `@latest` unless `--skip-install`.
|
|
69
73
|
- Template files and `.cursor/rules/*`: **skip** if the destination exists (unless `--force`).
|
|
70
74
|
- Companion skills (`skills-cli`): always reinstall/update to **latest** when selected.
|
|
71
|
-
- `.cursor/mcp.json`: merge other servers; skip existing `morya-ui` entry unless `--force`.
|
|
75
|
+
- `.cursor/mcp.json`: merge other servers; skip existing `morya-ui` entry unless `--force`. New or forced entries use `npx -y @morya-ui/mcp@latest`.
|
|
72
76
|
- `package.json` `check:colors`: add only if missing (unless `--force`).
|
|
73
77
|
- Styles: inject only when an entry file is found and the import is not already present.
|
|
74
78
|
|
|
@@ -94,7 +98,7 @@ Writes / merges:
|
|
|
94
98
|
"mcpServers": {
|
|
95
99
|
"morya-ui": {
|
|
96
100
|
"command": "npx",
|
|
97
|
-
"args": ["-y", "@morya-ui/mcp"]
|
|
101
|
+
"args": ["-y", "@morya-ui/mcp@latest"]
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
}
|
package/bin/morya-ui-setup.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morya-ui/setup",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.3.
|
|
5
|
-
"packageManager": "pnpm@10.12.4",
|
|
4
|
+
"version": "0.3.5",
|
|
6
5
|
"description": "One-shot setup for morya-ui: install the library, Cursor MCP, Agent skills, and design config.",
|
|
7
6
|
"license": "MIT",
|
|
8
7
|
"homepage": "https://github.com/morya-space/morya-ui/tree/main/packages/setup#readme",
|
|
@@ -32,7 +31,6 @@
|
|
|
32
31
|
},
|
|
33
32
|
"scripts": {
|
|
34
33
|
"sync-template": "node ./scripts/sync-template.mjs",
|
|
35
|
-
"build": "pnpm run sync-template"
|
|
36
|
-
"prepublishOnly": "pnpm run build"
|
|
34
|
+
"build": "pnpm run sync-template"
|
|
37
35
|
}
|
|
38
|
-
}
|
|
36
|
+
}
|
package/src/cli.mjs
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
1
|
import { dirname, join, resolve } from 'node:path'
|
|
3
2
|
import { fileURLToPath } from 'node:url'
|
|
4
3
|
import { copyTemplate } from './copy-template.mjs'
|
|
5
|
-
import { readJson } from './fs-utils.mjs'
|
|
6
4
|
import { installMoryaUi } from './install.mjs'
|
|
7
5
|
import { mergeMcpConfig } from './mcp.mjs'
|
|
8
6
|
import { ensureCheckColorsScript } from './package-json.mjs'
|
|
@@ -25,7 +23,8 @@ const MODES = new Set(['app', 'ai', 'full'])
|
|
|
25
23
|
const MODE_DEFAULTS = {
|
|
26
24
|
full: {},
|
|
27
25
|
app: { skipTemplate: true, skipMcp: true, skipScripts: true },
|
|
28
|
-
ai
|
|
26
|
+
// ai still upgrades morya-ui / @morya-ui/* to latest unless --skip-install
|
|
27
|
+
ai: { skipStyles: true },
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const SKIP_FLAGS = {
|
|
@@ -47,15 +46,15 @@ export function printHelp() {
|
|
|
47
46
|
console.log(`Usage: morya-ui-setup [command] [options]
|
|
48
47
|
|
|
49
48
|
Commands:
|
|
50
|
-
(default) / full
|
|
51
|
-
app
|
|
52
|
-
ai
|
|
49
|
+
(default) / full Upgrade morya packages to latest, AI template, MCP, styles, check:colors
|
|
50
|
+
app Upgrade morya packages to latest and inject styles.css
|
|
51
|
+
ai Upgrade morya packages to latest, copy Agent skills / rules / DESIGN,
|
|
53
52
|
merge Cursor MCP, add check:colors
|
|
54
53
|
|
|
55
54
|
Default command:
|
|
56
|
-
- install morya-ui
|
|
55
|
+
- install / upgrade morya-ui@latest and any existing @morya-ui/* to @latest
|
|
57
56
|
- copy DESIGN.md, selected Agent skills, Cursor rules
|
|
58
|
-
- merge .cursor/mcp.json for @morya-ui/mcp
|
|
57
|
+
- merge .cursor/mcp.json for @morya-ui/mcp@latest
|
|
59
58
|
- inject import 'morya-ui/styles.css' into the app entry when found
|
|
60
59
|
- add check:colors script when missing
|
|
61
60
|
|
|
@@ -66,7 +65,7 @@ Options:
|
|
|
66
65
|
--yes Use default skills without prompting (CI / non-interactive)
|
|
67
66
|
--force Overwrite existing template files and MCP server entry
|
|
68
67
|
--dry-run Print actions without writing or installing
|
|
69
|
-
--skip-install Skip dependency install
|
|
68
|
+
--skip-install Skip dependency install / upgrade
|
|
70
69
|
--skip-template Skip copying AI template files
|
|
71
70
|
--skip-mcp Skip writing .cursor/mcp.json
|
|
72
71
|
--skip-styles Skip injecting styles.css
|
|
@@ -170,24 +169,6 @@ function rel(cwd, path) {
|
|
|
170
169
|
return path.startsWith(cwd) ? path.slice(cwd.length).replace(/^[\\/]/, '') || path : path
|
|
171
170
|
}
|
|
172
171
|
|
|
173
|
-
/**
|
|
174
|
-
* @param {string} cwd
|
|
175
|
-
*/
|
|
176
|
-
function hasMoryaUiDependency(cwd) {
|
|
177
|
-
const path = join(cwd, 'package.json')
|
|
178
|
-
if (!existsSync(path)) return false
|
|
179
|
-
try {
|
|
180
|
-
const pkg = readJson(path)
|
|
181
|
-
return Boolean(
|
|
182
|
-
pkg.dependencies?.['morya-ui']
|
|
183
|
-
|| pkg.devDependencies?.['morya-ui']
|
|
184
|
-
|| pkg.peerDependencies?.['morya-ui'],
|
|
185
|
-
)
|
|
186
|
-
} catch {
|
|
187
|
-
return false
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
172
|
/**
|
|
192
173
|
* @param {ReturnType<typeof parseArgs>} options
|
|
193
174
|
*/
|
|
@@ -210,13 +191,6 @@ export async function runSetup(options) {
|
|
|
210
191
|
console.log(`@morya-ui/setup [${mode}] → ${cwd}${dryRun ? ' (dry-run)' : ''}`)
|
|
211
192
|
console.log('')
|
|
212
193
|
|
|
213
|
-
if (mode === 'ai' && !hasMoryaUiDependency(cwd)) {
|
|
214
|
-
console.log(
|
|
215
|
-
'Warning: morya-ui is not listed in package.json. Run `npx @morya-ui/setup app` first (or pnpm add morya-ui).',
|
|
216
|
-
)
|
|
217
|
-
console.log('')
|
|
218
|
-
}
|
|
219
|
-
|
|
220
194
|
const catalog = loadSkillsCatalog()
|
|
221
195
|
let selectedSkills = []
|
|
222
196
|
let aiInclude
|
|
@@ -235,7 +209,8 @@ export async function runSetup(options) {
|
|
|
235
209
|
console.log('')
|
|
236
210
|
}
|
|
237
211
|
|
|
238
|
-
|
|
212
|
+
// Always ensure morya-ui@latest; also bump any existing @morya-ui/* (nuxt, mcp, …).
|
|
213
|
+
const install = installMoryaUi(cwd, { pm, dryRun, skipInstall, ensureCore: true })
|
|
239
214
|
|
|
240
215
|
const template = skipTemplate
|
|
241
216
|
? { copied: [], skipped: [], forced: [], skippedStep: true }
|
|
@@ -262,10 +237,12 @@ export async function runSetup(options) {
|
|
|
262
237
|
: ensureCheckColorsScript(cwd, { force, dryRun })
|
|
263
238
|
|
|
264
239
|
console.log('--- Summary ---')
|
|
240
|
+
const pkgList = (install.packages || []).join(', ') || 'morya-ui'
|
|
265
241
|
if (install.skipped) {
|
|
266
242
|
console.log(`Install: skipped (${install.reason}) — would run: ${install.command}`)
|
|
267
243
|
} else {
|
|
268
|
-
console.log(`Install:
|
|
244
|
+
console.log(`Install: upgraded to latest (${install.pm}) — ${pkgList}`)
|
|
245
|
+
console.log(` $ ${install.command}`)
|
|
269
246
|
}
|
|
270
247
|
|
|
271
248
|
if (template.skippedStep) {
|
package/src/install.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs'
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { execSync } from 'node:child_process'
|
|
4
|
+
import { readJson } from './fs-utils.mjs'
|
|
4
5
|
|
|
5
6
|
const LOCKFILES = [
|
|
6
7
|
{ pm: 'pnpm', file: 'pnpm-lock.yaml' },
|
|
@@ -8,6 +9,9 @@ const LOCKFILES = [
|
|
|
8
9
|
{ pm: 'npm', file: 'package-lock.json' },
|
|
9
10
|
]
|
|
10
11
|
|
|
12
|
+
const CORE_PACKAGE = 'morya-ui'
|
|
13
|
+
const SCOPE_PREFIX = '@morya-ui/'
|
|
14
|
+
|
|
11
15
|
export function detectPackageManager(cwd, explicit) {
|
|
12
16
|
if (explicit) {
|
|
13
17
|
if (!['pnpm', 'yarn', 'npm'].includes(explicit)) {
|
|
@@ -21,43 +25,110 @@ export function detectPackageManager(cwd, explicit) {
|
|
|
21
25
|
return 'pnpm'
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Collect morya-ui / @morya-ui/* names from package.json.
|
|
30
|
+
* Always includes `morya-ui` when ensureCore is true (full / app).
|
|
31
|
+
* @param {Record<string, unknown> | null} pkg
|
|
32
|
+
* @param {{ ensureCore?: boolean }} [opts]
|
|
33
|
+
* @returns {string[]}
|
|
34
|
+
*/
|
|
35
|
+
export function collectMoryaPackages(pkg, { ensureCore = true } = {}) {
|
|
36
|
+
const names = new Set()
|
|
37
|
+
if (pkg && typeof pkg === 'object') {
|
|
38
|
+
for (const field of ['dependencies', 'devDependencies', 'optionalDependencies']) {
|
|
39
|
+
const deps = pkg[field]
|
|
40
|
+
if (!deps || typeof deps !== 'object') continue
|
|
41
|
+
for (const name of Object.keys(deps)) {
|
|
42
|
+
if (name === CORE_PACKAGE || name.startsWith(SCOPE_PREFIX)) {
|
|
43
|
+
names.add(name)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (ensureCore) names.add(CORE_PACKAGE)
|
|
49
|
+
return [...names].sort()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {string} pm
|
|
54
|
+
* @param {string[]} packages bare package names
|
|
55
|
+
*/
|
|
56
|
+
export function installCommand(pm, packages) {
|
|
57
|
+
const specs = packages.map((name) => `${name}@latest`)
|
|
58
|
+
const joined = specs.join(' ')
|
|
25
59
|
switch (pm) {
|
|
26
60
|
case 'pnpm':
|
|
27
|
-
return
|
|
61
|
+
return `pnpm add ${joined}`
|
|
28
62
|
case 'yarn':
|
|
29
|
-
return
|
|
63
|
+
return `yarn add ${joined}`
|
|
30
64
|
case 'npm':
|
|
31
|
-
return
|
|
65
|
+
return `npm install ${joined}`
|
|
32
66
|
default:
|
|
33
67
|
throw new Error(`Unknown package manager: ${pm}`)
|
|
34
68
|
}
|
|
35
69
|
}
|
|
36
70
|
|
|
37
71
|
/**
|
|
38
|
-
*
|
|
72
|
+
* Install / upgrade `morya-ui` and any existing `@morya-ui/*` deps to the npm `latest` tag.
|
|
73
|
+
* @returns {{
|
|
74
|
+
* pm: string,
|
|
75
|
+
* command: string,
|
|
76
|
+
* packages: string[],
|
|
77
|
+
* skipped?: boolean,
|
|
78
|
+
* reason?: string,
|
|
79
|
+
* }}
|
|
39
80
|
*/
|
|
40
|
-
export function installMoryaUi(cwd, {
|
|
81
|
+
export function installMoryaUi(cwd, {
|
|
82
|
+
pm,
|
|
83
|
+
dryRun = false,
|
|
84
|
+
skipInstall = false,
|
|
85
|
+
ensureCore = true,
|
|
86
|
+
} = {}) {
|
|
41
87
|
const resolved = detectPackageManager(cwd, pm)
|
|
42
|
-
const
|
|
88
|
+
const pkgPath = join(cwd, 'package.json')
|
|
89
|
+
|
|
90
|
+
let pkg = null
|
|
91
|
+
if (existsSync(pkgPath)) {
|
|
92
|
+
try {
|
|
93
|
+
pkg = readJson(pkgPath)
|
|
94
|
+
} catch {
|
|
95
|
+
pkg = null
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const packages = collectMoryaPackages(pkg, { ensureCore })
|
|
100
|
+
const command = packages.length
|
|
101
|
+
? installCommand(resolved, packages)
|
|
102
|
+
: installCommand(resolved, [CORE_PACKAGE])
|
|
43
103
|
|
|
44
104
|
if (skipInstall) {
|
|
45
|
-
return { pm: resolved, command, skipped: true, reason: 'skip-install' }
|
|
105
|
+
return { pm: resolved, command, packages, skipped: true, reason: 'skip-install' }
|
|
46
106
|
}
|
|
47
107
|
|
|
48
|
-
if (!existsSync(
|
|
108
|
+
if (!existsSync(pkgPath)) {
|
|
49
109
|
return {
|
|
50
110
|
pm: resolved,
|
|
51
111
|
command,
|
|
112
|
+
packages,
|
|
52
113
|
skipped: true,
|
|
53
114
|
reason: 'no-package-json',
|
|
54
115
|
}
|
|
55
116
|
}
|
|
56
117
|
|
|
118
|
+
if (!packages.length) {
|
|
119
|
+
return {
|
|
120
|
+
pm: resolved,
|
|
121
|
+
command,
|
|
122
|
+
packages,
|
|
123
|
+
skipped: true,
|
|
124
|
+
reason: 'no-morya-packages',
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
57
128
|
if (dryRun) {
|
|
58
|
-
return { pm: resolved, command, skipped: true, reason: 'dry-run' }
|
|
129
|
+
return { pm: resolved, command, packages, skipped: true, reason: 'dry-run' }
|
|
59
130
|
}
|
|
60
131
|
|
|
61
132
|
execSync(command, { cwd, stdio: 'inherit', shell: true })
|
|
62
|
-
return { pm: resolved, command }
|
|
133
|
+
return { pm: resolved, command, packages }
|
|
63
134
|
}
|
package/src/mcp.mjs
CHANGED
|
@@ -5,10 +5,10 @@ description: >
|
|
|
5
5
|
morya-ui component library — admin CRUD (list, form, dashboard, detail,
|
|
6
6
|
settings), auth and onboarding, empty and error states, wizards, overlays,
|
|
7
7
|
marketing/landing and pricing pages, docs chrome, and hybrid product UI.
|
|
8
|
-
Trigger on: morya-ui, M* components, --m-* tokens, golden pages,
|
|
9
|
-
列表页, 表单页, 仪表盘, 登录页, 注册, 空状态, 向导, 落地页, 官网,
|
|
10
|
-
login, dashboard, settings, onboarding, or “用组件库做页面”. Prefer
|
|
11
|
-
skill over generic frontend-design, impeccable, or ui-ux-pro-max when the
|
|
8
|
+
Trigger on: morya-ui, M* components, --m-* tokens, golden pages, page snippets,
|
|
9
|
+
后台页, 列表页, 表单页, 仪表盘, 登录页, 注册, 空状态, 向导, 落地页, 官网,
|
|
10
|
+
landing, login, dashboard, settings, onboarding, or “用组件库做页面”. Prefer
|
|
11
|
+
this skill over generic frontend-design, impeccable, or ui-ux-pro-max when the
|
|
12
12
|
implementation stack is morya-ui; those companions may deepen taste and polish
|
|
13
13
|
after structure/contract are fixed (see references/optional-companions.md).
|
|
14
14
|
Do not use for backend-only work or for authoring new components inside the
|
|
@@ -22,7 +22,9 @@ Guide agents that **consume morya-ui** across the full product surface — not o
|
|
|
22
22
|
Two layers always apply:
|
|
23
23
|
|
|
24
24
|
1. **Contract** — only `M*` controls, `--m-*` tokens, real APIs (MCP/docs). Never invent props or mix UI kits.
|
|
25
|
-
2. **Craft** — pick the right surface pattern, then apply intentional visual direction (distilled from Frontend Design / Impeccable / UI-UX-Pro-Max ideas).
|
|
25
|
+
2. **Craft** — pick the right surface pattern, then apply intentional visual direction (distilled from Frontend Design / Impeccable / UI-UX-Pro-Max ideas). Ops stays disciplined; expressive surfaces (landing, auth brand moments, empty states) may take a justified aesthetic risk — still on-token and on-component.
|
|
26
|
+
|
|
27
|
+
**Default build path (composition-first):** pin surface → L2 decisions + page snippets → craft → validate. Golden pages are an **optional** whole-page block-order check — not the default clone target.
|
|
26
28
|
|
|
27
29
|
When companions conflict with this skill or project `DESIGN.md`, **this skill wins**.
|
|
28
30
|
|
|
@@ -30,14 +32,14 @@ When companions conflict with this skill or project `DESIGN.md`, **this skill wi
|
|
|
30
32
|
|
|
31
33
|
| Lane | Surfaces | Primary references |
|
|
32
34
|
| --- | --- | --- |
|
|
33
|
-
| **Ops** | list, form, dashboard, detail, settings, filter drawer, CRUD dialog | [page-layouts.md](references/page-layouts.md)
|
|
34
|
-
| **Account** | login, register, invite, forgot/reset password, profile | [surfaces.md](references/surfaces.md) § Account |
|
|
35
|
-
| **Flow** | onboarding, empty state, wizard/stepper, success/result | [surfaces.md](references/surfaces.md) § Flow |
|
|
35
|
+
| **Ops** | list, form, dashboard, detail, settings, filter drawer, CRUD dialog | [page-layouts.md](references/page-layouts.md) block order + snippets |
|
|
36
|
+
| **Account** | login, register, invite, forgot/reset password, profile | [surfaces.md](references/surfaces.md) § Account + `auth-split-shell` |
|
|
37
|
+
| **Flow** | onboarding, empty state, wizard/stepper, success/result | [surfaces.md](references/surfaces.md) § Flow + empty/result/wizard snippets |
|
|
36
38
|
| **System** | 404 / error, permission denied, maintenance | [surfaces.md](references/surfaces.md) § System |
|
|
37
39
|
| **Express** | marketing landing, pricing, feature showcase, docs marketing chrome | [surfaces.md](references/surfaces.md) § Express + [visual-craft.md](references/visual-craft.md) |
|
|
38
|
-
| **Overlay** | dialog, drawer, popover, command menu as the main UI | [surfaces.md](references/surfaces.md) § Overlay |
|
|
40
|
+
| **Overlay** | dialog, drawer, popover, command menu as the main UI | [surfaces.md](references/surfaces.md) § Overlay + form-in-dialog/drawer snippets |
|
|
39
41
|
|
|
40
|
-
Unclear brief → ask **one** short question, or default: Ops → closest
|
|
42
|
+
Unclear brief → ask **one** short question, or default: Ops → closest page-layout checklist + snippets; public marketing → Express.
|
|
41
43
|
|
|
42
44
|
Full taxonomy: [references/surfaces.md](references/surfaces.md).
|
|
43
45
|
|
|
@@ -45,7 +47,7 @@ Full taxonomy: [references/surfaces.md](references/surfaces.md).
|
|
|
45
47
|
|
|
46
48
|
1. `morya-ui` installed; `morya-ui/styles.css` imported.
|
|
47
49
|
2. Prefer `@morya-ui/mcp` — never invent prop / event / slot names.
|
|
48
|
-
3.
|
|
50
|
+
3. Component APIs, decision recipes, page snippets, and feedback rules come from `@morya-ui/mcp`. Golden pages are optional assembly demos. Without MCP, use this skill's `references/`. Project `DESIGN.md` overrides generic taste when the AI pack is merged.
|
|
49
51
|
|
|
50
52
|
## Workflow
|
|
51
53
|
|
|
@@ -57,69 +59,69 @@ State explicitly (even briefly in thinking):
|
|
|
57
59
|
- **Audience** — who uses this screen
|
|
58
60
|
- **Surface** — from the map above
|
|
59
61
|
- **Single job** — what the first viewport must accomplish
|
|
60
|
-
- **Style direction** — resolve in this order (see [style-presets.md](references/style-presets.md)):
|
|
61
|
-
1. User **reference**
|
|
62
|
-
2.
|
|
63
|
-
3. **
|
|
64
|
-
4.
|
|
62
|
+
- **Style direction** — resolve in this order (see [style-presets.md](references/style-presets.md); **no preset catalog**):
|
|
63
|
+
1. User **reference** or **explicit description** → **must follow** (map to `--m-*` + `M*`; never substitute another face)
|
|
64
|
+
2. No description, but **clear prompt cues** → infer and **state your reading** in one sentence
|
|
65
|
+
3. **Uncertain** → **ask once** for a description or reference; do not invent the full look first
|
|
66
|
+
4. User says “直接写 / 你看着办” with still no cues → quiet flat on-token admin face, **say so**; never default glass/neon/aurora
|
|
65
67
|
|
|
66
|
-
Golden pages lock **
|
|
68
|
+
Golden pages (when used) lock **block order**, not aesthetics. Blindly cloning golden visuals makes pages feel stiff — prefer composing snippets.
|
|
67
69
|
|
|
68
|
-
For Express / branded Account moments, also draft a tiny **design plan** (see [visual-craft.md](references/visual-craft.md)): palette roles mapped to `--m-*` (extend only if the project already customizes theme), type roles, layout concept, one signature element. For Ops,
|
|
70
|
+
For Express / branded Account moments, also draft a tiny **design plan** (see [visual-craft.md](references/visual-craft.md)): palette roles mapped to `--m-*` (extend only if the project already customizes theme), type roles, layout concept, one signature element. For Ops, Ops polish + the resolved direction is enough unless the user asks for a redesign.
|
|
69
71
|
|
|
70
72
|
### 2. Load the smallest useful references
|
|
71
73
|
|
|
72
74
|
| Need | Prefer (MCP) | Else read |
|
|
73
75
|
| --- | --- | --- |
|
|
74
|
-
| Ops pattern | `recommend_page` → **`
|
|
75
|
-
| Style direction | `recommend_page({ style })` / **`
|
|
76
|
-
| Account / Express / empty / result |
|
|
76
|
+
| Ops pattern + snippets | `recommend_page` → **`suggestedSnippets`** / **`get_page_snippet`** + **`recommend_component`** | [page-layouts.md](references/page-layouts.md) + [decision-recipes.md](references/decision-recipes.md) |
|
|
77
|
+
| Style direction | `recommend_page({ style })` / **`get_style_direction`** | [style-presets.md](references/style-presets.md) |
|
|
78
|
+
| Account / Express / empty / result | snippets (`auth-split-shell`, `empty-block`, `result-block`, …) + `recommend_page` | [surfaces.md](references/surfaces.md) |
|
|
79
|
+
| Optional whole-page block order | `get_golden_page` only when unsure of section order or user asks to mirror a golden sample | [page-layouts.md](references/page-layouts.md) |
|
|
77
80
|
| Visual direction | — | [visual-craft.md](references/visual-craft.md) + [style-presets.md](references/style-presets.md) |
|
|
78
|
-
| Components / **API truth** | `search` / **`get_component`** / `get_example` / **`recommend_component`** (
|
|
81
|
+
| Components / **API truth** | `search` / **`get_component`** / `get_example` / **`recommend_component`** (L2 recipes + `relatedSnippets`) | [decision-recipes.md](references/decision-recipes.md) + [component-index.md](references/component-index.md) |
|
|
79
82
|
| Tokens / rules | `get_design_rules` | [design-system.md](references/design-system.md) |
|
|
80
|
-
| Snippet | `get_page_snippet` | golden / surface excerpt |
|
|
81
83
|
| Feedback API | — | [feedback.md](references/feedback.md) |
|
|
82
84
|
| **Required checks** | **`validate_usage`** (every `M*` you used) + `validate_page` | [review-checklist.md](references/review-checklist.md) |
|
|
83
85
|
|
|
84
86
|
### 3. Compose
|
|
85
87
|
|
|
86
|
-
**Ops:**
|
|
88
|
+
**Ops:** follow [page-layouts.md](references/page-layouts.md) **block-order checklist**; fill each block with **`get_page_snippet`** / `suggestedSnippets` (filters, table, header actions, form-in-dialog, confirm-delete, …). Apply the resolved **style direction** for density/chrome/copy; prefer `MPage*` over custom chrome. Do not freeze every Ops page into identical chrome. List density/sider cues (`dense` / `rail`) inform craft — do not invent new golden-page variants.
|
|
87
89
|
|
|
88
|
-
**Account / Flow / System:** centered or split shells with `MCard` / `MForm` / `MEmpty` / `MResult` (see surfaces); keep controls as `M*`. Persistent form errors use field `errorMessage` or a token-styled `role="alert"` — `<MMessage>` is the `message` host, not an inline alert.
|
|
90
|
+
**Account / Flow / System:** centered or split shells with `MCard` / `MForm` / `MEmpty` / `MResult` (see surfaces + snippets); keep controls as `M*`. Persistent form errors use field `errorMessage` or a token-styled `role="alert"` — `<MMessage>` is the `message` host, not an inline alert.
|
|
89
91
|
|
|
90
92
|
**Express:** hero + sections with intentional hierarchy; interactive bits still `MButton` / `MTag` / etc.; atmosphere via layout, motion, and tokens — not a second component library.
|
|
91
93
|
|
|
92
|
-
**Overlay:** build the host page lightly; put the real job inside `MDialog` / `MDrawer` / `MCommandMenu
|
|
94
|
+
**Overlay:** build the host page lightly; put the real job inside `MDialog` / `MDrawer` / `MCommandMenu` (use `form-in-dialog` / `form-in-drawer` snippets).
|
|
93
95
|
|
|
94
96
|
### 4. Wire real API usage
|
|
95
97
|
|
|
96
98
|
- Import from `morya-ui` (or documented subpath + style).
|
|
97
|
-
- **Selection + key props:** call MCP **`recommend_component`** (by query or `decision` id) and apply the returned **recipe** (`props` / `slots` / `events`)
|
|
98
|
-
- Forms: `MForm` + fields; `@submit` + `type="submit"` (or documented footer button pattern on `form-in-dialog`).
|
|
99
|
+
- **Selection + key props:** call MCP **`recommend_component`** (by query or `decision` id) and apply the returned **recipe** (`props` / `slots` / `events`), **antiPatterns**, and **`relatedSnippets`**. Without MCP, read [decision-recipes.md](references/decision-recipes.md). Then confirm full API with `get_component` / `get_example`.
|
|
100
|
+
- Forms: `MForm` + fields; `@submit` + `type="submit"` (or documented footer button pattern on `form-in-dialog` snippet).
|
|
99
101
|
- Tables: `columns` + `rows` + `row-key`; `#cell-{key}`. There is no `data` prop. For full-viewport admin lists whose main job is one table, consider `MPageContent fill` + `MTable fill paginator`; skip `fill` for embedded/short/whole-page-scroll cases (see [page-layouts.md](references/page-layouts.md)).
|
|
100
102
|
- Enums → `MSelect` / `MTreeSelect`; action menus → `MDropdown`.
|
|
101
|
-
- Destructive → `MConfirmDialog` / `MConfirmPopup` (`confirm-choice`).
|
|
103
|
+
- Destructive → `MConfirmDialog` / `MConfirmPopup` (`confirm-choice` + `confirm-delete` snippet).
|
|
102
104
|
- Feedback → default **`message`**; `toast` only for summary+detail / async; persistent form errors → `errorMessage` / `role="alert"` (`feedback-choice`). See [feedback.md](references/feedback.md).
|
|
103
105
|
- Motion → intensity with `useMotion` (`full` / `reduced` / `none`); overlay enter/exit with `transition` prop or `createMoryaUI({ motion: { transitions } })` — do not invent a second animation stack. Prefer MCP / docs `motion` guide.
|
|
104
106
|
- **Before craft:** for each unfamiliar or newly written `M*` usage, call MCP **`get_component` / `get_example`**, then **`validate_usage`**. Fix every `unknown-prop` / `unknown-event` before delivery.
|
|
105
|
-
- `recommend_page(includeScaffold: true)`
|
|
107
|
+
- `recommend_page(includeScaffold: true)` may return golden source as a **structure reference** — remap copy/data only; default path does **not** require cloning the whole page. Never treat generated fallback as the visual target.
|
|
106
108
|
|
|
107
109
|
### 5. Craft pass (always — lane-aware + companions)
|
|
108
110
|
|
|
109
111
|
Run **before** delivery. Do not stop at a structurally correct shell.
|
|
110
112
|
|
|
111
|
-
1. Resolve **style direction** ([style-presets.md](references/style-presets.md)) — reference
|
|
113
|
+
1. Resolve **style direction** ([style-presets.md](references/style-presets.md)) — reference/description first; else prompt cues; else **ask**; never silent AI face. **No preset catalog.**
|
|
112
114
|
2. Apply lane craft from [visual-craft.md](references/visual-craft.md):
|
|
113
|
-
- **Ops / Operate:**
|
|
114
|
-
- **Account / Flow:** one calm brand or empty-state cue from §
|
|
115
|
-
- **Express / Persuade:** short design plan + one signature; avoid AI-default looks; optional 1–2 token-only motions via `useMotion`.
|
|
115
|
+
- **Ops / Operate:** resolved direction + § Ops polish (one primary, menu icons, `MStatus`, designed empty, no decorative cards).
|
|
116
|
+
- **Account / Flow:** one calm brand or empty-state cue from § Shell recipes; form errors via `errorMessage` / token `role="alert"`.
|
|
117
|
+
- **Express / Persuade:** short design plan + one signature; avoid AI-default looks; optional 1–2 token-only motions via `useMotion`. Signature ≠ unearned gradient/glass/neon.
|
|
116
118
|
3. **If companions are already installed** (see [optional-companions.md](references/optional-companions.md)):
|
|
117
|
-
- Express / brand → may load **`frontend-design`** for POV after contract
|
|
118
|
-
- User asks 更大胆/更克制/polish/audit → may load **`impeccable`** command (`bolder` / `quieter` / `polish` / …)
|
|
119
|
-
- Mood/industry keywords only → optional **`ui-ux-pro-max`** search, then map to
|
|
119
|
+
- Express / brand → may load **`frontend-design`** for POV after contract **and style direction** are fixed
|
|
120
|
+
- User asks 更大胆/更克制/polish/audit → may load **`impeccable`** command (`bolder` / `quieter` / `polish` / …) **inside** the resolved direction
|
|
121
|
+
- Mood/industry keywords only → optional **`ui-ux-pro-max`** search, then map to `--m-*` (not a preset id)
|
|
120
122
|
- a11y pass → optional **`fixing-accessibility`** after visual
|
|
121
|
-
- Max **one** visual companion per task; always remediate with `M*` + `--m
|
|
122
|
-
4. If companions are **absent**, use distilled visual-craft / style-
|
|
123
|
+
- Max **one** visual companion per task; always remediate with `M*` + `--m-*`; strip companion-added AI atmosphere the user did not ask for
|
|
124
|
+
4. If companions are **absent**, use distilled visual-craft / style-direction — do **not** block or ask to install mid-task.
|
|
123
125
|
5. **All lanes:** responsive, focus visible, domain-real copy. User **reference** overrides companion taste within the morya contract.
|
|
124
126
|
|
|
125
127
|
Named polish modes (`quieter` | `bolder` | `clarify` | `audit` | …): extra pass when the user asks to improve an existing screen.
|
|
@@ -141,10 +143,12 @@ Do not deliver with unresolved `unknown-prop` / `unknown-event`.
|
|
|
141
143
|
- No hand-rolled table/modal when `MTable` / `MDialog` / `MDrawer` fit.
|
|
142
144
|
- No invented props / events / slots.
|
|
143
145
|
- No defaulting every success to `toast`.
|
|
144
|
-
- No substituting a generated scaffold for
|
|
145
|
-
- Ops surfaces follow
|
|
146
|
+
- No substituting a generated scaffold for a real golden sample when the user asked to mirror one — but default path composes snippets, not full-page clones.
|
|
147
|
+
- Ops surfaces follow page-layout **block order** — do not replace them with marketing heroes.
|
|
146
148
|
- Express surfaces still use `M*` for controls and `--m-*` for color/space; do not introduce shadcn/Element/etc. stacks suggested by generic design skills.
|
|
147
149
|
- Soft-load companions only; never require Impeccable / UI-UX-Pro-Max / Frontend Design to be installed.
|
|
150
|
+
- Do **not** invent decorative glass / neon / aurora / neumorph / full-page gradients unless the **user reference or description** clearly asks for them.
|
|
151
|
+
- Do **not** add new golden-page craft variants (`list-page-*`); express density/sider via style direction + polish.
|
|
148
152
|
|
|
149
153
|
## Soft companions
|
|
150
154
|
|
|
@@ -154,7 +158,7 @@ If already installed in the consumer project, **combine** them after structure +
|
|
|
154
158
|
| --- | --- | --- |
|
|
155
159
|
| `frontend-design` | Express / branded Account moments | Distinctive design plan + signature (taste) |
|
|
156
160
|
| `impeccable` | Polish / bolder / quieter / audit / delight asks | Named Operate/Persuade craft passes |
|
|
157
|
-
| `ui-ux-pro-max` | Mood / industry keyword search for Express | Keywords → map to `--m-*`
|
|
161
|
+
| `ui-ux-pro-max` | Mood / industry keyword search for Express | Keywords → map to `--m-*` (no preset ids) |
|
|
158
162
|
| `fixing-accessibility` | a11y audit after visual | Names, keyboard, focus on top of `M*` |
|
|
159
163
|
|
|
160
164
|
Routing, conflict rules, and load budget: [optional-companions.md](references/optional-companions.md). Distilled craft in [visual-craft.md](references/visual-craft.md) + [style-presets.md](references/style-presets.md) keeps this skill **standalone**.
|
|
@@ -164,7 +168,7 @@ Routing, conflict rules, and load budget: [optional-companions.md](references/op
|
|
|
164
168
|
- Vue 3 `<script setup lang="ts">`.
|
|
165
169
|
- PascalCase `M*` in templates.
|
|
166
170
|
- Domain-real copy and data shapes (not placeholder “示例 / Name / No data” when the brief names a product).
|
|
167
|
-
- Scoped CSS minimal; tokens only (`color-mix`
|
|
171
|
+
- Scoped CSS minimal; tokens only (`color-mix` OK). Prefer **flat** surfaces; gradients / glass / glow **only** when the user/reference asks (control widths may be inline).
|
|
168
172
|
- Craft pass completed for the lane (see step 5).
|
|
169
173
|
- For multi-file asks: sensible `views/` / `components/` split; otherwise one SFC is fine.
|
|
170
174
|
|
|
@@ -173,9 +177,9 @@ Routing, conflict rules, and load budget: [optional-companions.md](references/op
|
|
|
173
177
|
| File | Read when |
|
|
174
178
|
| --- | --- |
|
|
175
179
|
| [surfaces.md](references/surfaces.md) | Choosing / composing non-Ops (and hybrid) surfaces |
|
|
176
|
-
| [page-layouts.md](references/page-layouts.md) | Ops
|
|
177
|
-
| [style-presets.md](references/style-presets.md) | Style resolution
|
|
178
|
-
| [visual-craft.md](references/visual-craft.md) | Ops polish,
|
|
180
|
+
| [page-layouts.md](references/page-layouts.md) | Ops block-order checklists (fill with snippets) |
|
|
181
|
+
| [style-presets.md](references/style-presets.md) | Style resolution (no preset catalog) |
|
|
182
|
+
| [visual-craft.md](references/visual-craft.md) | Ops polish, shell recipes, anti-defaults, polish modes |
|
|
179
183
|
| [design-system.md](references/design-system.md) | Principles, tokens, bans |
|
|
180
184
|
| [component-index.md](references/component-index.md) | Catalog + decision-id index |
|
|
181
185
|
| [decision-recipes.md](references/decision-recipes.md) | Scenario → component → key props (generated; offline MCP mirror) |
|