@morya-ui/setup 0.2.6 → 0.2.7
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/README.md +24 -5
- package/package.json +1 -1
- package/src/cli.mjs +92 -15
- package/src/copy-template.mjs +18 -2
- package/src/fs-utils.mjs +2 -1
- package/template/DESIGN.md +2 -2
- package/template/design-tokens/tokens.json +1 -1
- package/template/docs/feedback-message-vs-toast.md +5 -5
package/README.md
CHANGED
|
@@ -4,10 +4,12 @@ One-shot setup for consumer Vue projects using [`morya-ui`](https://www.npmjs.co
|
|
|
4
4
|
|
|
5
5
|
Docs (zh/en):
|
|
6
6
|
|
|
7
|
-
- [
|
|
7
|
+
- [One-shot setup](https://morya-space.github.io/morya-ui/docs/setup) — CLI commands and options
|
|
8
|
+
- [AI setup](https://morya-space.github.io/morya-ui/docs/ai-setup) — Agent workflow
|
|
8
9
|
- [Agent Skill](https://morya-space.github.io/morya-ui/docs/agent-skill) — `morya-ui-pages` behavior
|
|
10
|
+
- [Quick start](https://morya-space.github.io/morya-ui/docs/quick-start) — install and first component
|
|
9
11
|
|
|
10
|
-
Installs the UI library, copies Agent skill / Cursor rules / design docs from `
|
|
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.
|
|
11
13
|
|
|
12
14
|
## Usage
|
|
13
15
|
|
|
@@ -17,6 +19,16 @@ In your app project root:
|
|
|
17
19
|
npx @morya-ui/setup
|
|
18
20
|
```
|
|
19
21
|
|
|
22
|
+
Other common commands:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# AI config + MCP only (library already installed)
|
|
26
|
+
npx @morya-ui/setup ai
|
|
27
|
+
|
|
28
|
+
# Library + styles only
|
|
29
|
+
npx @morya-ui/setup app
|
|
30
|
+
```
|
|
31
|
+
|
|
20
32
|
### Options
|
|
21
33
|
|
|
22
34
|
| Flag | Meaning |
|
|
@@ -32,6 +44,12 @@ npx @morya-ui/setup
|
|
|
32
44
|
| `--skip-scripts` | Do not add `check:colors` to `package.json` |
|
|
33
45
|
| `-h`, `--help` | Show help |
|
|
34
46
|
|
|
47
|
+
Example: MCP only:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx @morya-ui/setup ai --skip-template --skip-scripts
|
|
51
|
+
```
|
|
52
|
+
|
|
35
53
|
### Conflict policy
|
|
36
54
|
|
|
37
55
|
- Template files and `.cursor/rules/*`: **skip** if the destination exists (unless `--force`).
|
|
@@ -41,7 +59,7 @@ npx @morya-ui/setup
|
|
|
41
59
|
|
|
42
60
|
### What gets copied
|
|
43
61
|
|
|
44
|
-
From the package `template/` (synced from repo `
|
|
62
|
+
From the package `template/` (synced from repo `design-kit/`):
|
|
45
63
|
|
|
46
64
|
- `DESIGN.md`
|
|
47
65
|
- `.agents/skills/morya-ui-pages/`
|
|
@@ -50,7 +68,8 @@ From the package `template/` (synced from repo `ai-design-config/`):
|
|
|
50
68
|
- `design-tokens/`
|
|
51
69
|
- `scripts/check-raw-colors.mjs`
|
|
52
70
|
- `src/examples/`
|
|
53
|
-
|
|
71
|
+
|
|
72
|
+
`morya-app-shell.css` is written by the CLI (not copied from the template tree).
|
|
54
73
|
|
|
55
74
|
### MCP (Cursor)
|
|
56
75
|
|
|
@@ -85,7 +104,7 @@ The CLI does **not** call `app.use(MoryaUI)` or edit `App.vue`.
|
|
|
85
104
|
## Local development (this monorepo)
|
|
86
105
|
|
|
87
106
|
```bash
|
|
88
|
-
pnpm setup:sync-template # refresh packages/setup/template from
|
|
107
|
+
pnpm setup:sync-template # refresh packages/setup/template from design-kit
|
|
89
108
|
pnpm setup:build
|
|
90
109
|
node packages/setup/bin/morya-ui-setup.js --cwd /path/to/app --dry-run
|
|
91
110
|
```
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morya-ui/setup",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.7",
|
|
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
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs'
|
|
1
2
|
import { dirname, join, resolve } from 'node:path'
|
|
2
3
|
import { fileURLToPath } from 'node:url'
|
|
3
4
|
import { copyTemplate } from './copy-template.mjs'
|
|
5
|
+
import { readJson } from './fs-utils.mjs'
|
|
4
6
|
import { installMoryaUi } from './install.mjs'
|
|
5
7
|
import { mergeMcpConfig } from './mcp.mjs'
|
|
6
8
|
import { ensureCheckColorsScript } from './package-json.mjs'
|
|
@@ -10,6 +12,26 @@ const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
|
10
12
|
const PKG_ROOT = resolve(__dirname, '..')
|
|
11
13
|
const TEMPLATE_ROOT = join(PKG_ROOT, 'template')
|
|
12
14
|
|
|
15
|
+
const MODES = new Set(['app', 'ai', 'full'])
|
|
16
|
+
|
|
17
|
+
/** AI pack paths under template/ (excludes runtime src/styles — owned by app mode). */
|
|
18
|
+
const AI_TEMPLATE_INCLUDE = [
|
|
19
|
+
'DESIGN.md',
|
|
20
|
+
'.agents/skills/morya-ui-pages',
|
|
21
|
+
'.cursor/rules',
|
|
22
|
+
'docs',
|
|
23
|
+
'design-tokens',
|
|
24
|
+
'scripts/check-raw-colors.mjs',
|
|
25
|
+
'src/examples',
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
/** Mode → default skips (user --skip-* can only add more skips). */
|
|
29
|
+
const MODE_DEFAULTS = {
|
|
30
|
+
full: {},
|
|
31
|
+
app: { skipTemplate: true, skipMcp: true, skipScripts: true },
|
|
32
|
+
ai: { skipInstall: true, skipStyles: true },
|
|
33
|
+
}
|
|
34
|
+
|
|
13
35
|
const SKIP_FLAGS = {
|
|
14
36
|
'--skip-install': 'skipInstall',
|
|
15
37
|
'--skip-template': 'skipTemplate',
|
|
@@ -19,14 +41,20 @@ const SKIP_FLAGS = {
|
|
|
19
41
|
}
|
|
20
42
|
|
|
21
43
|
export function printHelp() {
|
|
22
|
-
console.log(`Usage: morya-ui-setup [options]
|
|
44
|
+
console.log(`Usage: morya-ui-setup [command] [options]
|
|
45
|
+
|
|
46
|
+
Commands:
|
|
47
|
+
(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,
|
|
50
|
+
merge Cursor MCP, add check:colors
|
|
23
51
|
|
|
24
|
-
|
|
52
|
+
Default command:
|
|
25
53
|
- install morya-ui
|
|
26
54
|
- copy DESIGN.md, Agent skill, Cursor rules, docs, tokens, examples
|
|
27
55
|
- merge .cursor/mcp.json for @morya-ui/mcp
|
|
28
56
|
- inject import 'morya-ui/styles.css' into the app entry when found
|
|
29
|
-
- write src/styles/morya-app-shell.css
|
|
57
|
+
- write src/styles/morya-app-shell.css and inject its import
|
|
30
58
|
- add check:colors script when missing
|
|
31
59
|
|
|
32
60
|
Options:
|
|
@@ -48,6 +76,7 @@ Options:
|
|
|
48
76
|
*/
|
|
49
77
|
export function parseArgs(argv) {
|
|
50
78
|
const options = {
|
|
79
|
+
mode: 'full',
|
|
51
80
|
cwd: process.cwd(),
|
|
52
81
|
pm: undefined,
|
|
53
82
|
force: false,
|
|
@@ -66,6 +95,10 @@ export function parseArgs(argv) {
|
|
|
66
95
|
options.help = true
|
|
67
96
|
continue
|
|
68
97
|
}
|
|
98
|
+
if (MODES.has(arg)) {
|
|
99
|
+
options.mode = arg
|
|
100
|
+
continue
|
|
101
|
+
}
|
|
69
102
|
if (arg === '--force') {
|
|
70
103
|
options.force = true
|
|
71
104
|
continue
|
|
@@ -101,6 +134,11 @@ export function parseArgs(argv) {
|
|
|
101
134
|
throw new Error(`Unknown argument: ${arg}`)
|
|
102
135
|
}
|
|
103
136
|
|
|
137
|
+
const defaults = MODE_DEFAULTS[options.mode] || {}
|
|
138
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
139
|
+
if (value) options[key] = true
|
|
140
|
+
}
|
|
141
|
+
|
|
104
142
|
return options
|
|
105
143
|
}
|
|
106
144
|
|
|
@@ -109,11 +147,30 @@ function rel(cwd, path) {
|
|
|
109
147
|
return path.startsWith(cwd) ? path.slice(cwd.length).replace(/^[\\/]/, '') || path : path
|
|
110
148
|
}
|
|
111
149
|
|
|
150
|
+
/**
|
|
151
|
+
* @param {string} cwd
|
|
152
|
+
*/
|
|
153
|
+
function hasMoryaUiDependency(cwd) {
|
|
154
|
+
const path = join(cwd, 'package.json')
|
|
155
|
+
if (!existsSync(path)) return false
|
|
156
|
+
try {
|
|
157
|
+
const pkg = readJson(path)
|
|
158
|
+
return Boolean(
|
|
159
|
+
pkg.dependencies?.['morya-ui']
|
|
160
|
+
|| pkg.devDependencies?.['morya-ui']
|
|
161
|
+
|| pkg.peerDependencies?.['morya-ui'],
|
|
162
|
+
)
|
|
163
|
+
} catch {
|
|
164
|
+
return false
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
112
168
|
/**
|
|
113
169
|
* @param {ReturnType<typeof parseArgs>} options
|
|
114
170
|
*/
|
|
115
171
|
export async function runSetup(options) {
|
|
116
172
|
const {
|
|
173
|
+
mode,
|
|
117
174
|
cwd,
|
|
118
175
|
force,
|
|
119
176
|
dryRun,
|
|
@@ -125,14 +182,25 @@ export async function runSetup(options) {
|
|
|
125
182
|
pm,
|
|
126
183
|
} = options
|
|
127
184
|
|
|
128
|
-
console.log(`@morya-ui/setup → ${cwd}${dryRun ? ' (dry-run)' : ''}`)
|
|
185
|
+
console.log(`@morya-ui/setup [${mode}] → ${cwd}${dryRun ? ' (dry-run)' : ''}`)
|
|
129
186
|
console.log('')
|
|
130
187
|
|
|
188
|
+
if (mode === 'ai' && !hasMoryaUiDependency(cwd)) {
|
|
189
|
+
console.log(
|
|
190
|
+
'Warning: morya-ui is not listed in package.json. Run `npx @morya-ui/setup app` first (or pnpm add morya-ui).',
|
|
191
|
+
)
|
|
192
|
+
console.log('')
|
|
193
|
+
}
|
|
194
|
+
|
|
131
195
|
const install = installMoryaUi(cwd, { pm, dryRun, skipInstall })
|
|
132
196
|
|
|
133
197
|
const template = skipTemplate
|
|
134
198
|
? { copied: [], skipped: [], forced: [], skippedStep: true }
|
|
135
|
-
: copyTemplate(TEMPLATE_ROOT, cwd, {
|
|
199
|
+
: copyTemplate(TEMPLATE_ROOT, cwd, {
|
|
200
|
+
force,
|
|
201
|
+
dryRun,
|
|
202
|
+
include: mode === 'ai' || mode === 'full' ? AI_TEMPLATE_INCLUDE : undefined,
|
|
203
|
+
})
|
|
136
204
|
|
|
137
205
|
const mcp = skipMcp
|
|
138
206
|
? { path: join(cwd, '.cursor', 'mcp.json'), action: 'skipped-flag' }
|
|
@@ -158,7 +226,7 @@ export async function runSetup(options) {
|
|
|
158
226
|
}
|
|
159
227
|
|
|
160
228
|
if (template.skippedStep) {
|
|
161
|
-
console.log('Template: skipped (--skip-template)')
|
|
229
|
+
console.log('Template: skipped (--skip-template or app mode)')
|
|
162
230
|
} else {
|
|
163
231
|
console.log(
|
|
164
232
|
`Template: ${template.copied.length} copied, ${template.forced.length} overwritten, ${template.skipped.length} skipped`,
|
|
@@ -172,13 +240,13 @@ export async function runSetup(options) {
|
|
|
172
240
|
}
|
|
173
241
|
|
|
174
242
|
if (mcp.action === 'skipped-flag') {
|
|
175
|
-
console.log('MCP: skipped (--skip-mcp)')
|
|
243
|
+
console.log('MCP: skipped (--skip-mcp or app mode)')
|
|
176
244
|
} else {
|
|
177
245
|
console.log(`MCP: ${mcp.action} (${rel(cwd, mcp.path) || '.cursor/mcp.json'})`)
|
|
178
246
|
}
|
|
179
247
|
|
|
180
248
|
if (styles.reason === 'skip-styles') {
|
|
181
|
-
console.log('Styles: skipped (--skip-styles)')
|
|
249
|
+
console.log('Styles: skipped (--skip-styles or ai mode)')
|
|
182
250
|
} else if (styles.action === 'injected') {
|
|
183
251
|
console.log(`Styles: injected into ${rel(cwd, styles.path)}`)
|
|
184
252
|
} else if (styles.action === 'skipped') {
|
|
@@ -189,7 +257,7 @@ export async function runSetup(options) {
|
|
|
189
257
|
}
|
|
190
258
|
|
|
191
259
|
if (shell.reason === 'skip-styles') {
|
|
192
|
-
console.log('Shell CSS: skipped (--skip-styles)')
|
|
260
|
+
console.log('Shell CSS: skipped (--skip-styles or ai mode)')
|
|
193
261
|
} else {
|
|
194
262
|
console.log(
|
|
195
263
|
`Shell CSS: file ${shell.fileAction}`
|
|
@@ -200,17 +268,26 @@ export async function runSetup(options) {
|
|
|
200
268
|
}
|
|
201
269
|
|
|
202
270
|
if (scripts.action === 'skipped-flag') {
|
|
203
|
-
console.log('Scripts: skipped (--skip-scripts)')
|
|
271
|
+
console.log('Scripts: skipped (--skip-scripts or app mode)')
|
|
204
272
|
} else {
|
|
205
273
|
console.log(`Scripts: check:colors ${scripts.action}`)
|
|
206
274
|
}
|
|
207
275
|
|
|
208
276
|
console.log('')
|
|
209
277
|
console.log('Next:')
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
278
|
+
if (mode === 'app') {
|
|
279
|
+
console.log(' 1. Ensure styles.css + morya-app-shell.css imports are in your app entry.')
|
|
280
|
+
console.log(' 2. Optional AI pack: npx @morya-ui/setup ai')
|
|
281
|
+
} else if (mode === 'ai') {
|
|
282
|
+
console.log(' 1. Restart Cursor (or reload MCP) so morya-ui MCP tools appear.')
|
|
283
|
+
console.log(' 2. Have the agent read DESIGN.md before generating pages.')
|
|
284
|
+
console.log(' 3. Optional: pnpm check:colors')
|
|
285
|
+
} else {
|
|
286
|
+
console.log(' 1. Ensure styles.css + morya-app-shell.css imports are in your app entry.')
|
|
287
|
+
console.log(' 2. Restart Cursor (or reload MCP) so morya-ui MCP tools appear.')
|
|
288
|
+
console.log(' 3. Have the agent read DESIGN.md before generating pages.')
|
|
289
|
+
console.log(' 4. Optional: pnpm check:colors')
|
|
290
|
+
}
|
|
214
291
|
|
|
215
|
-
return { install, template, mcp, styles, shell, scripts }
|
|
292
|
+
return { mode, install, template, mcp, styles, shell, scripts }
|
|
216
293
|
}
|
package/src/copy-template.mjs
CHANGED
|
@@ -20,11 +20,27 @@ function listFiles(dir) {
|
|
|
20
20
|
return out
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* @param {string} rel
|
|
25
|
+
* @param {string[] | undefined} include
|
|
26
|
+
*/
|
|
27
|
+
function matchesInclude(rel, include) {
|
|
28
|
+
if (!include || include.length === 0) return true
|
|
29
|
+
const norm = rel.replace(/\\/g, '/')
|
|
30
|
+
return include.some((prefix) => {
|
|
31
|
+
const p = prefix.replace(/\\/g, '/')
|
|
32
|
+
return norm === p || norm.startsWith(`${p}/`)
|
|
33
|
+
})
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
/**
|
|
24
37
|
* Copy template tree into target cwd.
|
|
38
|
+
* @param {string} templateRoot
|
|
39
|
+
* @param {string} cwd
|
|
40
|
+
* @param {{ force?: boolean, dryRun?: boolean, include?: string[] }} [options]
|
|
25
41
|
* @returns {{ copied: string[], skipped: string[], forced: string[] }}
|
|
26
42
|
*/
|
|
27
|
-
export function copyTemplate(templateRoot, cwd, { force = false, dryRun = false } = {}) {
|
|
43
|
+
export function copyTemplate(templateRoot, cwd, { force = false, dryRun = false, include } = {}) {
|
|
28
44
|
const copied = []
|
|
29
45
|
const skipped = []
|
|
30
46
|
const forced = []
|
|
@@ -35,7 +51,7 @@ export function copyTemplate(templateRoot, cwd, { force = false, dryRun = false
|
|
|
35
51
|
)
|
|
36
52
|
}
|
|
37
53
|
|
|
38
|
-
const files = listFiles(templateRoot)
|
|
54
|
+
const files = listFiles(templateRoot).filter((rel) => matchesInclude(rel, include))
|
|
39
55
|
for (const rel of files) {
|
|
40
56
|
const from = join(templateRoot, rel)
|
|
41
57
|
const to = join(cwd, rel)
|
package/src/fs-utils.mjs
CHANGED
|
@@ -2,7 +2,8 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
|
2
2
|
import { dirname } from 'node:path'
|
|
3
3
|
|
|
4
4
|
export function readJson(path) {
|
|
5
|
-
|
|
5
|
+
const text = readFileSync(path, 'utf8').replace(/^\uFEFF/, '')
|
|
6
|
+
return JSON.parse(text)
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
export function writeJson(path, value, { dryRun = false } = {}) {
|
package/template/DESIGN.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Morya UI 设计系统(AI 第一信源)
|
|
2
2
|
|
|
3
|
-
> 基于 `morya-ui` v0.
|
|
3
|
+
> 基于 `morya-ui` v0.2.6。生成或审查业务页面时,**必须先遵守本文**,再查阅 `docs/components.md` 与 `docs/golden-pages/`。
|
|
4
4
|
|
|
5
5
|
## 1. 设计原则
|
|
6
6
|
|
|
@@ -108,7 +108,7 @@ import 'morya-ui/styles.css'
|
|
|
108
108
|
|
|
109
109
|
## 8. 禁止项
|
|
110
110
|
|
|
111
|
-
- 禁止引入第二套 UI
|
|
111
|
+
- 禁止引入第二套 UI 库混用同一页面。
|
|
112
112
|
- 禁止在业务 CSS 中写死主题色;暗色模式必须能随 `[data-theme="dark"]` 生效。
|
|
113
113
|
- 禁止用 `<div onclick>` 代替 `<button>` / `MButton`。
|
|
114
114
|
- 禁止 Select 与 Dropdown 混用:选项选择用 `MSelect` / `MTreeSelect`;动作菜单用 `MDropdown`。
|
|
@@ -88,13 +88,13 @@ message.error('操作失败')
|
|
|
88
88
|
| 删除确认用 Message/Toast | `MConfirmDialog` |
|
|
89
89
|
| 所有反馈都用 Toast | 默认改 Message,仅 detail 场景保留 Toast |
|
|
90
90
|
|
|
91
|
-
##
|
|
91
|
+
## 概念对照
|
|
92
92
|
|
|
93
|
-
|
|
|
93
|
+
| API | 用途 |
|
|
94
94
|
| --- | --- |
|
|
95
|
-
| `message` |
|
|
96
|
-
| `toast` |
|
|
97
|
-
| `<MMessage>` |
|
|
95
|
+
| `message` | 轻量、短暂的操作反馈(默认首选) |
|
|
96
|
+
| `toast` | 带摘要 + 详情、或需停留更久的通知 |
|
|
97
|
+
| `<MMessage>` | 页面内常驻提示条(如表单顶部错误) |
|
|
98
98
|
|
|
99
99
|
## 相关文档
|
|
100
100
|
|