@astryx-vue/cli 0.4.1 → 0.4.3
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/CONTRIBUTING.md +53 -0
- package/README.md +10 -162
- package/README.zh-CN.md +10 -161
- package/dist/index.js +2196 -384
- package/package.json +2 -1
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# 维护 `@astryx-vue/cli`
|
|
2
|
+
|
|
3
|
+
这个文件只写给改这个包的人。使用说明在文档站的 `/guide/cli`,包里没有第二份。
|
|
4
|
+
|
|
5
|
+
## 文本从哪来
|
|
6
|
+
|
|
7
|
+
CLI 不另存一份组件文档。`scripts/generate-catalog.mjs` 读:
|
|
8
|
+
|
|
9
|
+
- `apps/docs/components/demos/*/meta.ts`:名字、分组和顺序
|
|
10
|
+
- `apps/docs/docs/{en,zh}/components/<slug>/`:用法、props、插槽、事件和示例标题
|
|
11
|
+
- `apps/docs/components/demos/<slug>/*.vue`:那些页面指向的示例源码
|
|
12
|
+
- `apps/docs/components/demo-infra/reference/*.json`:anatomy 和无障碍信息
|
|
13
|
+
- `apps/docs/docs/{en,zh}/guide` 和 `themes`:搜索主题和正文,以及 `theme` 用的主题记录、`init` 用的安装命令和代码片段
|
|
14
|
+
- `apps/docs/docs/{en,zh}/guide/migration.md`:`upgrade` 打印的升级小节,和它去源码里找的旧名字
|
|
15
|
+
- `apps/docs/components/playground/pages/*.vue`:模板源码;`templateManifest.ts`:模板标题和分类
|
|
16
|
+
- 每个 `packages/*/package.json`:判断组件属于哪个包、版本和说明
|
|
17
|
+
|
|
18
|
+
模板的说明和关键词是手写的,在 `packages/cli/src/generate/template-meta/`,每类模板一个文件,由 `template-meta.ts` 合并。它们属于源数据,不是生成物。
|
|
19
|
+
|
|
20
|
+
示例的标题和说明按语言各存一份,代码两种语言只存一份。两个页面指向同一个 `.vue` 文件;如果一个页面改了代码、另一个没改,生成时直接报错并指出是哪个组件的第几个示例。
|
|
21
|
+
|
|
22
|
+
结果提交在 `packages/cli/src/generated/catalog.json`。
|
|
23
|
+
|
|
24
|
+
## 改完文档或模板之后
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
pnpm --filter @astryx-vue/cli generate
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`pnpm check` 会跑 `generate:check`。它在这些情况下失败:`catalog.json` 过期、某个包里有 PascalCase 导出没有任何组件文档引用、某个演练场页面在 `template-meta.ts` 里没有元数据。`./icons`、`./locale`、CSS 和包根不算组件导出。
|
|
31
|
+
|
|
32
|
+
只要 catalog 变了就要有 CLI 的 changeset,否则 npm 上的用户拿到的还是旧目录;`scripts/check-cli-catalog-release.mjs` 会在 PR 里拦住漏发。
|
|
33
|
+
|
|
34
|
+
## 在本仓库里直接跑
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
pnpm --filter @astryx-vue/cli build
|
|
38
|
+
node packages/cli/bin/astryx-vue.mjs component Button
|
|
39
|
+
node packages/cli/bin/astryx-vue.mjs composable useClipboard
|
|
40
|
+
node packages/cli/bin/astryx-vue.mjs docs guide/dark-mode --dense
|
|
41
|
+
node packages/cli/bin/astryx-vue.mjs template --list
|
|
42
|
+
node packages/cli/bin/astryx-vue.mjs template login-card --skeleton
|
|
43
|
+
node packages/cli/bin/astryx-vue.mjs build "登录页"
|
|
44
|
+
node packages/cli/bin/astryx-vue.mjs search login --type template
|
|
45
|
+
node packages/cli/bin/astryx-vue.mjs manifest --json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 相关包
|
|
49
|
+
|
|
50
|
+
| 包 | 是什么 |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `@astryx-vue/core` | 这个 CLI 记录的那些 Vue 组件 |
|
|
53
|
+
| `@astryx-vue/themes` | Neutral、Butter、Chocolate、Gothic、Matcha、Stone、Y2K |
|
package/README.md
CHANGED
|
@@ -71,177 +71,25 @@ Global flags:
|
|
|
71
71
|
| `--zh` | Simplified Chinese where the docs have a translation. |
|
|
72
72
|
| `--cwd <dir>` | Project directory. Defaults to the working directory; `template` and `init` write inside it, and `upgrade`/`doctor` read it. |
|
|
73
73
|
|
|
74
|
-
A composable takes `useClipboard` or `use-clipboard`. `component useClipboard` still prints it, and adds a line that points at the `composable` command. `component --list` lists components only. `search --type` accepts `component`, `composable`, `doc`, or `template`; composable hits carry `domain: "composable"` and a `command` that points at `composable <Name>`. A query that hits a name outranks one that only hits page text. Each result names the package it comes from, ranked by score and then, when scores tie, by domain (component, composable, doc, template) and name, so the order never moves between runs.
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
## Docs
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
The full command reference — JSON envelopes, error codes, template rules, `init` block rules, and the maintainer steps — lives on the docs site: <https://astryx-vue.pages.dev/en/guide/cli>. The site is the only copy of that text; this README stays short on purpose.
|
|
79
78
|
|
|
80
|
-
|
|
79
|
+
## Programmatic use
|
|
81
80
|
|
|
82
|
-
|
|
81
|
+
```ts
|
|
82
|
+
import { assertResponse, runCli } from '@astryx-vue/cli'
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
`upgrade` reads the `@astryx-vue/core` version from the project's `package.json` and compares it with the version this CLI was generated from. It never asks the network.
|
|
87
|
-
|
|
88
|
-
- Older: it prints every section of the upgrade guide — what changed, how it was written before, how it is written now, what to do — then looks through the project's own sources for the old names the guide replaces, and lists file and line. A theme target name only counts as an object key (`progressbar: {`), because the same word is also an HTML tag; a property or option name counts as a word, in camelCase or kebab-case.
|
|
89
|
-
- Current: it says nothing needs doing and prints the changelog link.
|
|
90
|
-
- Not installed, or a range it cannot read as a version: it says that, and either names the install command for the project's package manager or prints every form.
|
|
91
|
-
|
|
92
|
-
Both lists come from `apps/docs/docs/{en,zh}/guide/migration.md`: the sections are the page's `###` sections, and the old names are the names its section titles and its `Removed | Use instead` table state.
|
|
93
|
-
|
|
94
|
-
## Doctor
|
|
95
|
-
|
|
96
|
-
`doctor` reports five checks and changes nothing:
|
|
97
|
-
|
|
98
|
-
| Check | Fails or warns when |
|
|
99
|
-
| --- | --- |
|
|
100
|
-
| `core-version` | `@astryx-vue/core` is missing (fail), its range cannot be read as a version, or it is older or newer than this CLI's catalog (warn) |
|
|
101
|
-
| `themes-installed` | `@astryx-vue/themes` is not a dependency (fail) |
|
|
102
|
-
| `vue-version` | `vue` is missing (fail) or below 3.5.0 (warn) |
|
|
103
|
-
| `theme-stylesheet` | No `@astryx-vue/themes/*.css` import is found (fail), or the file name is not one of the built-in themes (warn) |
|
|
104
|
-
| `theme-attribute` | No `data-astryx-theme` is found (warn; Neutral works without it) |
|
|
105
|
-
|
|
106
|
-
Exit code is `0` when every check passed or only warned, and `1` when one failed; the text still prints, and `--json` returns `doctor.report`. Sources are read from the project directory, skipping `node_modules`, build output, and hidden directories.
|
|
107
|
-
|
|
108
|
-
## Templates
|
|
109
|
-
|
|
110
|
-
`template --list` prints all 57 playground pages. `--type page` is the only kind today; `--type block` answers with a note instead of an error.
|
|
111
|
-
|
|
112
|
-
Every template carries a hand-written one-sentence description and a keyword list in English and Chinese, in `src/generate/template-meta/` (one file per template category). The component list is extracted from the page's `@astryx-vue/core` imports, so it cannot drift from the source. Each record also carries `dependencies`, the npm packages the page imports; a ready page names only `vue` and `@astryx-vue/core`, and the catalog generator fails when a ready page pulls in anything else. That is why `template --list`, `template <slug>`, and their `--json` forms can say exactly what a copied page needs.
|
|
113
|
-
|
|
114
|
-
Some pages import a package a project cannot install: five use `@astryx-vue/playground-charts`, a path alias that only exists inside the docs playground. Those are marked `isReady: false` with the reason. A page is ready when every non-relative import it really performs is `vue` or `@astryx-vue/core`; text inside a code sample the page displays, such as `@astryxdesign/core`, is page content and does not count. `--list` and `template <slug>` still show them; copying is refused with `ERR_TEMPLATE_NOT_READY`.
|
|
115
|
-
|
|
116
|
-
`template <slug> <path>` writes one file:
|
|
117
|
-
|
|
118
|
-
- a path that ends in a file name, or that already names a file, is the target file;
|
|
119
|
-
- anything else is a directory and receives `<PascalCaseSlug>.vue`;
|
|
120
|
-
- an existing file is only replaced with `--overwrite` (or `-f`), otherwise `ERR_FILE_EXISTS`;
|
|
121
|
-
- a path outside the project directory is refused with `ERR_PATH_TRAVERSAL`.
|
|
122
|
-
|
|
123
|
-
Copying rewrites the playground's `/template-assets/…` photo paths to an inline grey placeholder and reports how many it replaced, so the file renders without the docs site. It does not copy any asset and does not install anything: it names the packages the project's `package.json` does not list, plus an install command with the lockfile's package manager.
|
|
124
|
-
|
|
125
|
-
`--skeleton` prints the component tags with layout attributes only: `gap`, `padding`, `width`, `maxWidth`, `height`, `columns`, `axis`, `justify`, `align`, `density`, `variant`, `hasDivider`, and the `rowGap`/`columnGap`/`contentPadding`/`minHeight` variants. Text, bindings other than layout, event handlers, and native HTML wrappers are dropped, so a page positioned with plain `<div>` reads flatter than it renders. The skeleton is a structure reference, not a compilable file.
|
|
126
|
-
|
|
127
|
-
## Build
|
|
128
|
-
|
|
129
|
-
`build "<idea>"` ranks the templates locally: field-weighted keyword matching over slug, title, description, keywords, and the components a page uses, with rare words counting more than common ones. No network, no model, same answer every run. Chinese is matched by character pairs, so no spaces are needed.
|
|
130
|
-
|
|
131
|
-
- `TEMPLATE` is the closest page. `OTHER TEMPLATES` is the next two. A page that cannot be copied keeps its place only when it answers the idea clearly better, and it is marked with the reason.
|
|
132
|
-
- `COMPONENTS` (up to 6) and `COMPOSABLES` (up to 4) come from the same ranking `search` uses, so the two commands cannot disagree. When the idea names fewer pieces than the limit, the recommended page's own components fill the rest, marked as such.
|
|
133
|
-
- A weak match is dropped rather than padded. An idea nothing matches returns no template and says so.
|
|
134
|
-
- `build` with no idea prints the workflow: find a template, copy it, then look up each component before writing code.
|
|
135
|
-
|
|
136
|
-
## JSON envelopes
|
|
137
|
-
|
|
138
|
-
Success responses are `{ apiVersion: 1, type, data }`. `template`, `build`, and `docs` responses carry `package` for where the records come from (`@astryx-vue/cli` for templates, `@astryx-vue/docs` for pages). Every template entry of `template.list`, `template.show`, and `template.skeleton` carries its own `dependencies` array next to `components`. `component.detail` and `composable.detail` carry the owning package, and every entry of `component.list` and `composable.list` carries its own, because one list can span packages.
|
|
139
|
-
|
|
140
|
-
| Type | Command |
|
|
141
|
-
| --- | --- |
|
|
142
|
-
| `template.list`, `template.show`, `template.skeleton`, `template.copy` | `template` |
|
|
143
|
-
| `build.help`, `build.kit` | `build` |
|
|
144
|
-
| `component.list`, `component.detail` | `component` |
|
|
145
|
-
| `composable.list`, `composable.detail` | `composable` |
|
|
146
|
-
| `docs.list`, `docs.detail` | `docs` |
|
|
147
|
-
| `search` | `search` |
|
|
148
|
-
| `manifest` | `manifest` |
|
|
149
|
-
| `theme.list`, `theme.detail` | `theme` |
|
|
150
|
-
| `upgrade.report` | `upgrade` |
|
|
151
|
-
| `doctor.report` | `doctor` |
|
|
152
|
-
| `init.run` | `init` |
|
|
153
|
-
| `help`, `version` | `--help`, `--version`, or no arguments with `--json` |
|
|
154
|
-
|
|
155
|
-
Exit codes are `0` for success, `1` when the command ran but failed, and `2` for invalid usage. Branch on `code` in the JSON envelope, not on the message text.
|
|
156
|
-
|
|
157
|
-
| Code | When |
|
|
158
|
-
| --- | --- |
|
|
159
|
-
| `ERR_UNKNOWN_TEMPLATE` | No template matches the slug. Up to five close slugs come back as suggestions. |
|
|
160
|
-
| `ERR_TEMPLATE_NOT_READY` | The template imports a package the project cannot install. |
|
|
161
|
-
| `ERR_FILE_EXISTS` | The target file exists and `--overwrite` was not passed. |
|
|
162
|
-
| `ERR_PATH_TRAVERSAL` | A target path resolves outside the project directory. |
|
|
163
|
-
| `ERR_INVALID_ARGUMENT` | Two modes were combined, a value is outside its choices, or the idea is blank. |
|
|
164
|
-
| `ERR_UNKNOWN_COMPONENT`, `ERR_UNKNOWN_COMPOSABLE`, `ERR_UNKNOWN_TOPIC` | No record matches the name. |
|
|
165
|
-
| `ERR_UNKNOWN_AGENT` | `--agent` is not `cursor`, `claude`, `codex`, `hermes`, or `all`. |
|
|
166
|
-
| `ERR_UNKNOWN_FEATURE` | `--features` names something other than `agents`. |
|
|
167
|
-
| `ERR_UNKNOWN_THEME` | No theme has that slug or display name. |
|
|
168
|
-
|
|
169
|
-
`manifest --json` carries the same list per command, so an agent can read the codes without this table.
|
|
170
|
-
|
|
171
|
-
## Agent block
|
|
172
|
-
|
|
173
|
-
`init` prints the setup guide — which packages to install (canary ones with `@canary`, once they are on npm), the theme import, the locale snippet, and what to verify — and writes this managed block:
|
|
174
|
-
|
|
175
|
-
```html
|
|
176
|
-
<!-- Maintained by astryx-vue, do not edit manually -->
|
|
177
|
-
...
|
|
178
|
-
<!-- astryx-vue block end -->
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
If the file is missing, the command creates it. If the markers are already there, every run replaces only the block with freshly generated text. Other text stays. If the file exists without the markers, the block is appended. A second run still rewrites the block; it does not skip because the markers are already present. When the generated text matches, the bytes stay the same.
|
|
182
|
-
|
|
183
|
-
The block names every package the catalog covers. A package npm does not serve yet (a `private` one) is still named, but with a note and no install command, so nobody is sent to a 404; a published canary package would get the `@canary` specifier. Then it teaches the three-step workflow (`build` to pick a page, `template` to copy it, `component`/`composable`/`docs` before writing code), lists the lookup commands, and says how to run the binary. It does not paste the component catalog.
|
|
184
|
-
|
|
185
|
-
The install command in the guide follows the project: the `packageManager` field first, then `pnpm-lock.yaml`, `yarn.lock`, `bun.lock(b)`, or `package-lock.json`. With neither, all four forms are listed. `--features` is optional now; passing `agents` is the same as leaving it out, and any other feature is `ERR_UNKNOWN_FEATURE`.
|
|
186
|
-
|
|
187
|
-
Where it writes:
|
|
188
|
-
|
|
189
|
-
- no `--agent`: the first agent file the project already has, in the order `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `.hermes.md`, `HERMES.md`; `AGENTS.md` when none exists;
|
|
190
|
-
- `--agent cursor` or `--agent codex`: `AGENTS.md`;
|
|
191
|
-
- `--agent claude`: `CLAUDE.md`;
|
|
192
|
-
- `--agent hermes`: `.hermes.md`, or `HERMES.md` when the project already has that file;
|
|
193
|
-
- `--agent all`: every known file that exists, or `AGENTS.md` when none does;
|
|
194
|
-
- `--agent-docs-path <file>`: exactly that file, relative to the project directory. Missing directories are created; a path outside the project is refused with `ERR_PATH_TRAVERSAL`.
|
|
195
|
-
|
|
196
|
-
## Where the text comes from
|
|
197
|
-
|
|
198
|
-
The CLI does not keep a second copy of the component docs. `packages/cli/scripts/generate-catalog.mjs` reads:
|
|
199
|
-
|
|
200
|
-
- `apps/docs/components/demos/*/meta.ts` for names, groups, and order
|
|
201
|
-
- `apps/docs/docs/{en,zh}/components/<slug>/` for usage, props, slots, events, and example titles
|
|
202
|
-
- `apps/docs/components/demos/<slug>/*.vue` for the example source those pages point at
|
|
203
|
-
- `apps/docs/components/demo-infra/reference/*.json` for anatomy and accessibility
|
|
204
|
-
- `apps/docs/docs/{en,zh}/guide` and `themes` for search topics, topic bodies, and the theme records (`theme`), plus the install commands and snippets `init` prints
|
|
205
|
-
- `apps/docs/docs/{en,zh}/guide/migration.md` for the upgrade guide's sections and the old names `upgrade` searches for
|
|
206
|
-
- `apps/docs/components/playground/pages/*.vue` for the template sources, and `templateManifest.ts` for their titles and categories
|
|
207
|
-
- every `packages/*/package.json` for which package owns a component, and its exports when a page does not show an import
|
|
208
|
-
|
|
209
|
-
The template descriptions and keywords are hand-written in `packages/cli/src/generate/template-meta/`, one file per template category, and merged by `template-meta.ts`. They are source data, not a generated file.
|
|
210
|
-
|
|
211
|
-
Example titles and descriptions are kept once per language, but the example code is stored once for both: both pages point at the same `.vue` file. The generator stops with an error naming the component and the example number if the two pages ever show different code, so one language cannot silently borrow the other's snippet. `examplesFor()` in `packages/cli/src/catalog.ts` is the only place that picks a language back out.
|
|
212
|
-
|
|
213
|
-
The result is committed at `packages/cli/src/generated/catalog.json`. `pnpm --filter @astryx-vue/cli build` regenerates it and bundles it into `dist`, which is what the published tarball runs. After a docs or template change, regenerate it and commit the diff:
|
|
214
|
-
|
|
215
|
-
```sh
|
|
216
|
-
pnpm --filter @astryx-vue/cli generate
|
|
84
|
+
const result = await runCli(['search', 'dialog', '--json'], { cwd: process.cwd() })
|
|
85
|
+
const found = assertResponse(result.stdout, 'search')
|
|
217
86
|
```
|
|
218
87
|
|
|
219
|
-
`
|
|
220
|
-
|
|
221
|
-
`catalog.packages` lists every package the catalog covers (`core`, `themes`, `richtext`, `charts`, `lab`) with its directory, whether it publishes only under the `canary` tag, and whether it is `published`. `published` is false for a `private` package: npm has no version of it, so no output prints an install command for it. A component's `package` is the one that exports it by subpath, else the one that has a source entry for it.
|
|
222
|
-
|
|
223
|
-
`swizzle`, `discover`, `gap-report`, `integration`, and `blog` are not part of this package, and there is no MCP server. `theme`, `upgrade`, and `doctor` print guidance and reports; none of them edits a project file.
|
|
88
|
+
`runCli` takes the same arguments as the binary and returns `{ exitCode, stdout, stderr }`. `assertResponse` narrows the envelope to the type you expect.
|
|
224
89
|
|
|
225
|
-
##
|
|
90
|
+
## Contributing
|
|
226
91
|
|
|
227
|
-
|
|
228
|
-
| --- | --- |
|
|
229
|
-
| `@astryx-vue/core` | The Vue components this CLI documents |
|
|
230
|
-
| `@astryx-vue/themes` | Neutral, Butter, Chocolate, Gothic, Matcha, Stone, and Y2K |
|
|
231
|
-
|
|
232
|
-
## Try it in this repo
|
|
233
|
-
|
|
234
|
-
```sh
|
|
235
|
-
pnpm --filter @astryx-vue/cli build
|
|
236
|
-
node packages/cli/bin/astryx-vue.mjs component Button
|
|
237
|
-
node packages/cli/bin/astryx-vue.mjs composable useClipboard
|
|
238
|
-
node packages/cli/bin/astryx-vue.mjs docs guide/dark-mode --dense
|
|
239
|
-
node packages/cli/bin/astryx-vue.mjs template --list
|
|
240
|
-
node packages/cli/bin/astryx-vue.mjs template login-card --skeleton
|
|
241
|
-
node packages/cli/bin/astryx-vue.mjs build "login page with SSO"
|
|
242
|
-
node packages/cli/bin/astryx-vue.mjs search login --type template
|
|
243
|
-
node packages/cli/bin/astryx-vue.mjs manifest --json
|
|
244
|
-
```
|
|
92
|
+
Where the text comes from, how to regenerate the catalog, and how to run the command from a checkout are in [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
245
93
|
|
|
246
94
|
## License
|
|
247
95
|
|
package/README.zh-CN.md
CHANGED
|
@@ -71,176 +71,25 @@ npm run astryx-vue -- component Button
|
|
|
71
71
|
| `--zh` | 文档有中文版时用简体中文。 |
|
|
72
72
|
| `--cwd <dir>` | 项目目录,默认当前工作目录;`template` 和 `init` 只往这里面写,`upgrade` 和 `doctor` 只在这里读。 |
|
|
73
73
|
|
|
74
|
-
组合式函数可写 `useClipboard` 或 `use-clipboard`。`component useClipboard` 也能查到,并多印一行指向 `composable` 命令。`component --list` 只列组件。`search --type` 接受 `component`、`composable`、`doc`、`template`;组合式函数命中的结果是 `domain: "composable"`,`command` 指向 `composable <Name>`。命中名字的结果排在只命中正文的结果前面。每条结果都标出来自哪个包;分数相同时按领域(组件、组合式函数、文档、模板)再按名字排序,跑两次顺序不会变。
|
|
75
74
|
|
|
76
|
-
|
|
75
|
+
## 完整文档
|
|
77
76
|
|
|
78
|
-
|
|
77
|
+
命令的完整说明——JSON 信封、错误码、模板规则、`init` 区块规则、维护者步骤——都在文档站:<https://astryx-vue.pages.dev/guide/cli>。这份正文只在文档站维护,包里的 README 故意保持简短。
|
|
79
78
|
|
|
80
|
-
|
|
79
|
+
## 在代码里调用
|
|
81
80
|
|
|
82
|
-
|
|
81
|
+
```ts
|
|
82
|
+
import { assertResponse, runCli } from '@astryx-vue/cli'
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
`upgrade` 读项目 `package.json` 里 `@astryx-vue/core` 的版本,和这个 CLI 生成时对应的版本比,不联网。
|
|
87
|
-
|
|
88
|
-
- 比 CLI 旧:打印升级指南的每一节(变了什么、以前怎么写、现在怎么写、怎么改),再在项目自己的源码里找出指南里被替换掉的旧名字,列出文件和行号。主题挂点名只认对象键(`progressbar: {`),因为同一个词也是 HTML 标签;属性和选项名按单词认,camelCase 和 kebab-case 都算。
|
|
89
|
-
- 已经一样:说明不用升级,并给出更新日志链接。
|
|
90
|
-
- 没装,或版本写法读不出来:说明情况,并按项目包管理器给出安装命令(读不出包管理器就列全部写法)。
|
|
91
|
-
|
|
92
|
-
这两份内容都来自 `apps/docs/docs/{en,zh}/guide/migration.md`:小节就是页面的 `###` 小节,旧名字来自小节标题和页面里 `Removed | Use instead` 表格。
|
|
93
|
-
|
|
94
|
-
## 体检
|
|
95
|
-
|
|
96
|
-
`doctor` 报告五项检查,不改任何文件:
|
|
97
|
-
|
|
98
|
-
| 检查 | 什么时候失败或提醒 |
|
|
99
|
-
| --- | --- |
|
|
100
|
-
| `core-version` | 没装 `@astryx-vue/core`(失败);版本写法读不出来,或比 CLI 的 catalog 旧/新(提醒) |
|
|
101
|
-
| `themes-installed` | 没有依赖 `@astryx-vue/themes`(失败) |
|
|
102
|
-
| `vue-version` | 没装 `vue`(失败)或低于 3.5.0(提醒) |
|
|
103
|
-
| `theme-stylesheet` | 没找到任何 `@astryx-vue/themes/*.css` 引入(失败),或文件名不是内置主题(提醒) |
|
|
104
|
-
| `theme-attribute` | 没找到 `data-astryx-theme`(提醒;Neutral 不写也能用) |
|
|
105
|
-
|
|
106
|
-
全部通过或只有提醒时退出码是 `0`,有失败时是 `1`,文本照样打印;`--json` 返回 `doctor.report`。只读项目目录里的源码,跳过 `node_modules`、构建产物和隐藏目录。
|
|
107
|
-
|
|
108
|
-
## 模板
|
|
109
|
-
|
|
110
|
-
`template --list` 列出全部 57 个演练场页面。目前 `--type` 只有 `page` 一种;`--type block` 会给一句说明,不报错。
|
|
111
|
-
|
|
112
|
-
每个模板都有一句手写说明和中英两套关键词,放在 `src/generate/template-meta/`,每类模板一个文件。组件清单从页面里 `@astryx-vue/core` 的 import 自动提取,不会和源码脱节。每条记录还带 `dependencies`:这个页面 import 了哪些 npm 包。可复制的模板只会有 `vue` 和 `@astryx-vue/core`,可复制模板若多引一个包,生成 catalog 时直接报错。所以 `template --list`、`template <slug>` 和它们的 `--json` 都能直接说清落地要装什么。
|
|
113
|
-
|
|
114
|
-
有些页面引用了用户项目装不上的包:5 个用 `@astryx-vue/playground-charts`(只存在于文档站演练场的路径别名)。这些标为 `isReady: false` 并写明原因。判断标准是页面真正执行的导入:只要非相对导入都是 `vue` 或 `@astryx-vue/core` 就算可复制;页面里展示的示例代码文本(例如 `@astryxdesign/core`)属于页面内容,不算导入。`--list` 和 `template <slug>` 照样能看,复制会被拒绝,报 `ERR_TEMPLATE_NOT_READY`。
|
|
115
|
-
|
|
116
|
-
`template <slug> <path>` 只写一个文件:
|
|
117
|
-
|
|
118
|
-
- 以文件名结尾的路径,或本身就指向一个文件的路径,就写这个文件;
|
|
119
|
-
- 其余都当作目录,写入 `<PascalCaseSlug>.vue`;
|
|
120
|
-
- 已存在的文件要加 `--overwrite`(或 `-f`)才覆盖,否则报 `ERR_FILE_EXISTS`;
|
|
121
|
-
- 越出项目目录的路径报 `ERR_PATH_TRAVERSAL`。
|
|
122
|
-
|
|
123
|
-
复制时会把演练场的 `/template-assets/…` 图片地址换成一个内联的灰色占位图,并报告替换了多少处,这样文件不依赖文档站也能渲染。它不复制任何资源文件,也不安装任何东西:只列出项目 `package.json` 里没有的包,再按锁文件对应的包管理器给一条安装命令。
|
|
124
|
-
|
|
125
|
-
`--skeleton` 只输出组件标签和布局属性:`gap`、`padding`、`width`、`maxWidth`、`height`、`columns`、`axis`、`justify`、`align`、`density`、`variant`、`hasDivider`,以及 `rowGap`/`columnGap`/`contentPadding`/`minHeight`。文字、布局以外的绑定、事件处理函数和原生 HTML 包裹层都会丢掉,所以用 `<div>` 定位置的页面看起来会比实际更平。骨架是结构参考,不是能直接编译的文件。
|
|
126
|
-
|
|
127
|
-
## build
|
|
128
|
-
|
|
129
|
-
`build "<想法>"` 在本地给模板打分:对 slug、标题、说明、关键词和页面用到的组件做字段加权关键词匹配,越少见的词权重越高。没有网络,没有模型,同一句话每次结果一样。中文按字符二元组匹配,不需要空格分词。
|
|
130
|
-
|
|
131
|
-
- `TEMPLATE` 是最接近的页面,`OTHER TEMPLATES` 是接下来两个。不能复制的页面只有在明显更贴合时才排到前面,并标出原因。
|
|
132
|
-
- `COMPONENTS`(最多 6 个)和 `COMPOSABLES`(最多 4 个)用的是 `search` 那套排序,两个命令不会互相矛盾。想法里点到的部件不够时,用推荐页面自己用到的组件补齐,并标出来源。
|
|
133
|
-
- 命中太弱的直接丢掉,不凑数。完全没命中时不给模板,并说明这一点。
|
|
134
|
-
- 不带想法时 `build` 打印工作流:先找模板,再复制,最后写代码前逐个查组件。
|
|
135
|
-
|
|
136
|
-
## JSON 信封
|
|
137
|
-
|
|
138
|
-
成功响应是 `{ apiVersion: 1, type, data }`。`template`、`build`、`docs` 的响应带 `package`,说明记录来自哪个包(模板是 `@astryx-vue/cli`,文档页是 `@astryx-vue/docs`)。`template.list`、`template.show`、`template.skeleton` 的每条模板记录在 `components` 旁边带 `dependencies`。`component.detail` 和 `composable.detail` 带所属的包;`component.list` 和 `composable.list` 的每一条各自带 `package`,因为一个列表可能横跨多个包。
|
|
139
|
-
|
|
140
|
-
| 类型 | 命令 |
|
|
141
|
-
| --- | --- |
|
|
142
|
-
| `template.list`、`template.show`、`template.skeleton`、`template.copy` | `template` |
|
|
143
|
-
| `build.help`、`build.kit` | `build` |
|
|
144
|
-
| `component.list`、`component.detail` | `component` |
|
|
145
|
-
| `composable.list`、`composable.detail` | `composable` |
|
|
146
|
-
| `docs.list`、`docs.detail` | `docs` |
|
|
147
|
-
| `search` | `search` |
|
|
148
|
-
| `manifest` | `manifest` |
|
|
149
|
-
| `theme.list`、`theme.detail` | `theme` |
|
|
150
|
-
| `upgrade.report` | `upgrade` |
|
|
151
|
-
| `doctor.report` | `doctor` |
|
|
152
|
-
| `init.run` | `init` |
|
|
153
|
-
| `help`、`version` | `--help`、`--version`,或带 `--json` 不带参数 |
|
|
154
|
-
|
|
155
|
-
退出码:成功 `0`,命令跑了但没成功 `1`,用法错误 `2`。分支判断请用信封里的 `code`,不要匹配消息文本。
|
|
156
|
-
|
|
157
|
-
| 错误码 | 什么时候出现 |
|
|
158
|
-
| --- | --- |
|
|
159
|
-
| `ERR_UNKNOWN_TEMPLATE` | 没有模板匹配这个 slug。会附带最多 5 个相近的 slug。 |
|
|
160
|
-
| `ERR_TEMPLATE_NOT_READY` | 模板引用了项目装不上的包。 |
|
|
161
|
-
| `ERR_FILE_EXISTS` | 目标文件已存在,且没加 `--overwrite`。 |
|
|
162
|
-
| `ERR_PATH_TRAVERSAL` | 目标路径越出了项目目录。 |
|
|
163
|
-
| `ERR_INVALID_ARGUMENT` | 两个模式混用、取值不在选项内,或想法是空白串。 |
|
|
164
|
-
| `ERR_UNKNOWN_COMPONENT`、`ERR_UNKNOWN_COMPOSABLE`、`ERR_UNKNOWN_TOPIC` | 没有记录匹配这个名字。 |
|
|
165
|
-
| `ERR_UNKNOWN_AGENT` | `--agent` 不是 `cursor`、`claude`、`codex`、`hermes` 或 `all`。 |
|
|
166
|
-
| `ERR_UNKNOWN_FEATURE` | `--features` 写了 `agents` 以外的东西。 |
|
|
167
|
-
|
|
168
|
-
`manifest --json` 按命令携带同一份错误码列表,agent 不用读这张表。
|
|
169
|
-
|
|
170
|
-
## agent 区块
|
|
171
|
-
|
|
172
|
-
`init` 先打印接入说明(装哪些包、canary 的带 `@canary`(前提是已经发到 npm)、主题样式引哪一行、语言怎么提供、改完怎么验证),再写入这个受管理区块:
|
|
173
|
-
|
|
174
|
-
```html
|
|
175
|
-
<!-- Maintained by astryx-vue, do not edit manually -->
|
|
176
|
-
...
|
|
177
|
-
<!-- astryx-vue block end -->
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
文件不存在就创建。已经有标记时,每次只替换区块内容,其余文字保持不动。文件存在但没有标记时,把区块追加到末尾。第二次运行仍然重写区块,不会因为标记已存在就跳过;生成内容一致时字节不变。
|
|
181
|
-
|
|
182
|
-
区块开头列一遍 catalog 覆盖的包。npm 上还没有的包(仓库里标了 `private`)照样列名字,但会写明「还没发布到 npm」并且不给安装命令,免得有人照着敲一个 404;已经发布的 canary 包才会写成 `@canary`。然后写三步工作流(用 `build` 挑页面,用 `template` 复制,写代码前用 `component`/`composable`/`docs` 查),加上查询命令清单和怎么运行这个命令。它不会把组件目录贴进来。
|
|
183
|
-
|
|
184
|
-
接入说明里的安装命令跟着项目走:先看 `packageManager` 字段,再看 `pnpm-lock.yaml`、`yarn.lock`、`bun.lock(b)`、`package-lock.json`。两样都没有就把四种写法都列出来。`--features` 现在是可选的,写 `agents` 和不写一样,写别的仍然是 `ERR_UNKNOWN_FEATURE`。
|
|
185
|
-
|
|
186
|
-
写到哪里:
|
|
187
|
-
|
|
188
|
-
- 不加 `--agent`:项目里已经有的第一个 agent 文件,顺序是 `AGENTS.md`、`CLAUDE.md`、`.cursorrules`、`.hermes.md`、`HERMES.md`;都没有就写 `AGENTS.md`;
|
|
189
|
-
- `--agent cursor` 或 `--agent codex`:`AGENTS.md`;
|
|
190
|
-
- `--agent claude`:`CLAUDE.md`;
|
|
191
|
-
- `--agent hermes`:`.hermes.md`;项目里已有 `HERMES.md` 时写它;
|
|
192
|
-
- `--agent all`:已经存在的全部已知文件;一个都没有就写 `AGENTS.md`;
|
|
193
|
-
- `--agent-docs-path <file>`:就写这个文件,相对项目目录解析。缺的目录会自动创建,越出项目目录报 `ERR_PATH_TRAVERSAL`。
|
|
194
|
-
|
|
195
|
-
## 文本从哪来
|
|
196
|
-
|
|
197
|
-
CLI 不另存一份组件文档。`packages/cli/scripts/generate-catalog.mjs` 读:
|
|
198
|
-
|
|
199
|
-
- `apps/docs/components/demos/*/meta.ts`:名字、分组和顺序
|
|
200
|
-
- `apps/docs/docs/{en,zh}/components/<slug>/`:用法、props、插槽、事件和示例标题
|
|
201
|
-
- `apps/docs/components/demos/<slug>/*.vue`:那些页面指向的示例源码
|
|
202
|
-
- `apps/docs/components/demo-infra/reference/*.json`:anatomy 和无障碍信息
|
|
203
|
-
- `apps/docs/docs/{en,zh}/guide` 和 `themes`:搜索主题和正文,以及 `theme` 用的主题记录、`init` 用的安装命令和代码片段
|
|
204
|
-
- `apps/docs/docs/{en,zh}/guide/migration.md`:`upgrade` 打印的升级小节,和它去源码里找的旧名字
|
|
205
|
-
- `apps/docs/components/playground/pages/*.vue`:模板源码;`templateManifest.ts`:模板标题和分类
|
|
206
|
-
- 每个 `packages/*/package.json`:判断组件属于哪个包、版本和说明(`upgrade`/`doctor`/`init` 用);页面里没写 import 时用它的 exports 推断
|
|
207
|
-
|
|
208
|
-
模板的说明和关键词是手写的,在 `packages/cli/src/generate/template-meta/`,每类模板一个文件,由 `template-meta.ts` 合并,属于源数据,不是生成物。
|
|
209
|
-
|
|
210
|
-
示例的标题和说明按语言各存一份,但示例代码两种语言只存一份:两个页面指向的是同一个 `.vue` 文件。以后要是一个页面改了代码、另一个没改,生成时直接报错并指出是哪个组件的第几个示例,不会让一种语言悄悄用上另一种的代码。取回某种语言的示例只走 `packages/cli/src/catalog.ts` 里的 `examplesFor()`。
|
|
211
|
-
|
|
212
|
-
结果提交在 `packages/cli/src/generated/catalog.json`。`pnpm --filter @astryx-vue/cli build` 会重新生成并打进 `dist`,也就是 npm 包实际运行的那份。文档或模板改过之后,重新生成并提交 diff:
|
|
213
|
-
|
|
214
|
-
```sh
|
|
215
|
-
pnpm --filter @astryx-vue/cli generate
|
|
84
|
+
const result = await runCli(['search', 'dialog', '--json'], { cwd: process.cwd() })
|
|
85
|
+
const found = assertResponse(result.stdout, 'search')
|
|
216
86
|
```
|
|
217
87
|
|
|
218
|
-
`
|
|
219
|
-
|
|
220
|
-
`catalog.packages` 列出 catalog 覆盖的每个包(`core`、`themes`、`richtext`、`charts`、`lab`),带目录、「是否只发 canary」的标记,以及 `published`。`private` 的包 `published` 是 false:npm 上没有它的版本,所以任何输出都不会给它写安装命令。组件的 `package` 取「有它这个子路径导出的包」,没有就取「`src/` 里有它这个目录的包」。
|
|
88
|
+
`runCli` 收的参数和命令行一致,返回 `{ exitCode, stdout, stderr }`。`assertResponse` 按你要的类型校验信封。
|
|
221
89
|
|
|
222
|
-
|
|
90
|
+
## 参与开发
|
|
223
91
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
| 包 | 是什么 |
|
|
227
|
-
| --- | --- |
|
|
228
|
-
| `@astryx-vue/core` | 这个 CLI 记录的那些 Vue 组件 |
|
|
229
|
-
| `@astryx-vue/themes` | Neutral、Butter、Chocolate、Gothic、Matcha、Stone、Y2K |
|
|
230
|
-
|
|
231
|
-
## 在本仓库里试
|
|
232
|
-
|
|
233
|
-
```sh
|
|
234
|
-
pnpm --filter @astryx-vue/cli build
|
|
235
|
-
node packages/cli/bin/astryx-vue.mjs component Button
|
|
236
|
-
node packages/cli/bin/astryx-vue.mjs composable useClipboard
|
|
237
|
-
node packages/cli/bin/astryx-vue.mjs docs guide/dark-mode --dense
|
|
238
|
-
node packages/cli/bin/astryx-vue.mjs template --list
|
|
239
|
-
node packages/cli/bin/astryx-vue.mjs template login-card --skeleton
|
|
240
|
-
node packages/cli/bin/astryx-vue.mjs build "登录页"
|
|
241
|
-
node packages/cli/bin/astryx-vue.mjs search login --type template
|
|
242
|
-
node packages/cli/bin/astryx-vue.mjs manifest --json
|
|
243
|
-
```
|
|
92
|
+
文本从哪来、怎么重新生成目录、怎么在本仓库里直接跑这个命令,见 [CONTRIBUTING.md](./CONTRIBUTING.md)。
|
|
244
93
|
|
|
245
94
|
## 许可
|
|
246
95
|
|