harveyz-skill 0.6.2 → 0.7.0
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/CHANGELOG.md +89 -0
- package/README.md +85 -39
- package/bin/cli.js +444 -51
- package/hooks/check-similar-branch/check-similar-branch.sh +75 -0
- package/lib/bundles.js +74 -7
- package/lib/installer.js +256 -30
- package/lib/targets.js +22 -13
- package/package.json +8 -6
- package/skills/analysis/git-cleanup/SKILL.md +189 -0
- package/skills/design/sync-design-html/SKILL.md +354 -0
- package/skills/design/sync-design-html/references/stack-electron.md +119 -0
- package/skills/design/sync-design-html/references/stack-nextjs.md +101 -0
- package/skills/design/sync-design-html/references/stack-react.md +117 -0
- package/skills/design/sync-design-html/references/stack-swiftui.md +115 -0
- package/skills/design/sync-design-html/references/stack-vue.md +142 -0
- package/skills/design/sync-design-html/references/stacks.md +45 -0
- package/skills/web-fetch/article-fetcher/SKILL.md +95 -509
- package/skills/web-fetch/article-fetcher/references/__pycache__/article_utils.cpython-314.pyc +0 -0
- package/skills/web-fetch/article-fetcher/references/article_utils.py +32 -5
- package/skills/web-fetch/article-fetcher/scripts/playwright_web.py +172 -0
- package/skills/web-fetch/article-fetcher/scripts/playwright_xcom.py +221 -0
- package/skills/web-fetch/article-fetcher/scripts/validate_article.py +36 -0
- package/skills/web-fetch/article-fetcher/tests/test_security.py +257 -0
- package/skills-index.json +18 -4
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: git-cleanup
|
|
3
|
+
description: "梳理并清理本地 git 分支。规则匹配 + LLM 语义分析,分组确认后批量删除废弃分支。触发词:清理分支、branch cleanup、梳理分支、删除旧分支、整理分支"
|
|
4
|
+
user_invocable: true
|
|
5
|
+
version: "1.0.0"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# SKILL.md — git-cleanup
|
|
9
|
+
|
|
10
|
+
> **版本:** v1.0.0
|
|
11
|
+
> **定位:** 周期性梳理本地 git 分支,识别可安全删除的废弃分支
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 触发条件
|
|
16
|
+
|
|
17
|
+
- "清理分支" / "整理分支" / "梳理分支"
|
|
18
|
+
- "branch cleanup" / "删除旧分支"
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Step 1:读取配置
|
|
23
|
+
|
|
24
|
+
检查 `.claude/branch-cleanup.md` 是否存在:
|
|
25
|
+
|
|
26
|
+
**存在** → 解析三段内容:
|
|
27
|
+
- `## Always Delete` 段:每行 `` `pattern` `` 为必删 glob 规则
|
|
28
|
+
- `## Always Keep` 段:每行 `` `pattern` `` 为必留 glob 规则
|
|
29
|
+
- `## LLM 判断上下文` 段:整段文本作为 LLM 分析的 context
|
|
30
|
+
|
|
31
|
+
**不存在** → 使用内置默认规则,执行完毕后提示生成配置文件:
|
|
32
|
+
- Always Delete:`chore/bump-*`、`chore/sync-*`、`chore/fix-*`
|
|
33
|
+
- Always Keep:`test/*`
|
|
34
|
+
- LLM context:「通用项目。保留标准:功能仍在迭代的分支、测试框架。删除标准:一次性任务、已完成的独立功能。」
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Step 2:收集分支数据
|
|
39
|
+
|
|
40
|
+
运行以下命令,记录结果:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
git branch --show-current # 记录当前分支名
|
|
44
|
+
git branch # 所有本地分支列表
|
|
45
|
+
git branch --merged staging # 已合并进 staging 的子集
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**跳过列表(不参与任何分析):** `main`、`staging`、当前分支名
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Step 3:分类
|
|
53
|
+
|
|
54
|
+
对每条本地分支(不在跳过列表中),按以下优先级归类:
|
|
55
|
+
|
|
56
|
+
**预处理:** 先排除跳过列表(main、staging、当前分支名),剩余分支参与以下分类。
|
|
57
|
+
|
|
58
|
+
1. **未合并进 staging** → 直接归入 `GROUP_KEEP`,标注 `[未合并]`
|
|
59
|
+
2. **已合并 + 命中 Always Keep** → 归入 `GROUP_KEEP`,标注 `[规则保留: <pattern>]`
|
|
60
|
+
3. **已合并 + 命中 Always Delete** → 归入 `GROUP_DELETE_RULE`,标注 `[规则: <pattern>]`
|
|
61
|
+
4. **已合并 + 未命中任何规则** → 归入 `GROUP_AMBIGUOUS`,待 LLM 分析
|
|
62
|
+
|
|
63
|
+
**glob 匹配规则:** `*` 匹配任意字符(不含 `/`)。`chore/bump-*` 匹配 `chore/bump-0.3.0`,不匹配 `feature/bump-test`。
|
|
64
|
+
|
|
65
|
+
⚠️ **优先级冲突:** 若同一分支同时命中 Always Keep 和 Always Delete,**Always Keep 优先**(保留)。
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Step 4:LLM 分析 GROUP_AMBIGUOUS
|
|
70
|
+
|
|
71
|
+
若 `GROUP_AMBIGUOUS` 为空,跳过 Step 4,直接进入 Step 5。
|
|
72
|
+
|
|
73
|
+
若 `GROUP_AMBIGUOUS` 非空,执行以下步骤:
|
|
74
|
+
|
|
75
|
+
**4a. 收集每条分支的最近 commit message:**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git log -1 --format="%s" <branch>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**4b. 内嵌分析(直接在当前上下文推断,无需单独调用):**
|
|
82
|
+
|
|
83
|
+
根据以下 prompt 逻辑对每条分支作出判断:
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
项目上下文:
|
|
87
|
+
<来自配置文件的 LLM 判断上下文>
|
|
88
|
+
|
|
89
|
+
保留标准:功能仍在迭代、测试框架、基础设施、近期可能继续开发
|
|
90
|
+
删除标准:一次性任务(已完成)、独立功能(已合并不再扩展)、重构(已完成)
|
|
91
|
+
|
|
92
|
+
待判断:
|
|
93
|
+
- <branch> | <最近 commit message>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
每条分支输出 `keep` 或 `delete` + 一句中文理由,分配到:
|
|
97
|
+
- `GROUP_KEEP`,标注 `[LLM 保留: <理由>]`
|
|
98
|
+
- `GROUP_DELETE_LLM`,标注理由
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Step 5:分组展示 + 逐组确认
|
|
103
|
+
|
|
104
|
+
**边界情况:** 若三个分组均为空(仓库只有主干分支或当前 repo 无需清理),打印「✅ 所有分支已整理,无需清理」,跳到 Step 7。
|
|
105
|
+
|
|
106
|
+
### 组 A — 明显可删(规则命中)
|
|
107
|
+
|
|
108
|
+
若 `GROUP_DELETE_RULE` 非空,展示并等待确认:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
━━━ 组 A:明显可删(规则命中,共 N 条)━━━
|
|
112
|
+
• chore/bump-0.3.0 [规则: chore/bump-*]
|
|
113
|
+
• chore/fix-lockfile [规则: chore/fix-*]
|
|
114
|
+
|
|
115
|
+
确认删除这 N 条?[y = 删除 / n = 跳过]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 组 B — LLM 建议删除
|
|
119
|
+
|
|
120
|
+
若 `GROUP_DELETE_LLM` 非空,展示并等待确认:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
━━━ 组 B:LLM 建议删除(共 N 条)━━━
|
|
124
|
+
• feature/agent-friendly-cli — 文档类功能,已完成,不再扩展
|
|
125
|
+
• feat/skill-vars-substitution — 重构任务,已合并
|
|
126
|
+
|
|
127
|
+
确认删除这 N 条?[y = 删除 / n = 跳过]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 组 C — 保留清单(仅展示,无需操作)
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
━━━ 组 C:保留(共 N 条)━━━
|
|
134
|
+
• feature/mermaid-diagram-skill [规则保留]
|
|
135
|
+
• test/harness-skills-eval [规则保留]
|
|
136
|
+
• feature/tool-version-detection [未合并]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Step 6:执行删除
|
|
142
|
+
|
|
143
|
+
对用户确认的分组,逐条执行:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
git branch -d <branch>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
- 成功 → 记录已删除
|
|
150
|
+
- 失败(-d 安全检查拒绝)→ 报告错误,跳过,继续执行
|
|
151
|
+
|
|
152
|
+
**检查 remote 同名分支:**
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
git branch -r | grep "origin/<branch>"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
若存在,在删除后统一提示:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
⚠️ 以下分支有对应的 remote 分支,需手动清理:
|
|
162
|
+
git push origin --delete <branch1>
|
|
163
|
+
git push origin --delete <branch2>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Step 7:收尾
|
|
169
|
+
|
|
170
|
+
**打印执行摘要:**
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
✅ 清理完成
|
|
174
|
+
删除:N 条
|
|
175
|
+
保留:M 条
|
|
176
|
+
|
|
177
|
+
当前分支列表:
|
|
178
|
+
• <branch1>
|
|
179
|
+
• <branch2>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**若本次无配置文件,询问:**
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
未检测到 .claude/branch-cleanup.md。
|
|
186
|
+
是否根据本次规则生成配置文件,方便下次复用?[y/n]
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
若用户确认,生成 `.claude/branch-cleanup.md`,内容包含本次使用的 Always Delete / Always Keep 规则和 LLM context。
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sync-design-html
|
|
3
|
+
description: Use after any UI source file change — detects changed view/component files via git diff and syncs them to high-fidelity HTML design backups. Maintains a manifest as the source-of-truth mapping between source files and HTML previews. Also invocable as a post-step from /ship or /review. Trigger when user says "sync design", "update HTML preview", "design changed", or after UI code edits.
|
|
4
|
+
version: "3.0.0"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Sync Design HTML
|
|
8
|
+
|
|
9
|
+
检测前端视图文件变动,同步更新高保真 HTML 设计备份文件。
|
|
10
|
+
|
|
11
|
+
**Announce at start:** "I'm using sync-design-html to detect UI changes and update HTML design backups."
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 步骤 ①:读取 Manifest
|
|
16
|
+
|
|
17
|
+
读取 `docs/reference/design-html-manifest.json`。
|
|
18
|
+
|
|
19
|
+
**如果文件不存在:**
|
|
20
|
+
执行【附录 A:首次初始化流程】,完成后继续步骤 ②。
|
|
21
|
+
|
|
22
|
+
**如果文件存在且 `entries` 为空:**
|
|
23
|
+
执行【附录 B:已有 HTML 扫描流程】,完成后继续步骤 ②。
|
|
24
|
+
|
|
25
|
+
**如果文件存在且有 entries:**
|
|
26
|
+
直接继续步骤 ②。
|
|
27
|
+
|
|
28
|
+
## 步骤 ②:全局 Diff 检测
|
|
29
|
+
|
|
30
|
+
将 `manifest.config.platforms` 中所有平台的 `uiFilePatterns` 和 `designSystemFile`(非 null)汇总,传给 git 作为过滤参数:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git diff <manifest.baseBranch>...HEAD --name-only -- <pattern1> <pattern2> ...
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
用 git 原生 glob 支持过滤(`**` 跨目录 glob 可正确处理),而非先拉全量再手动筛。
|
|
37
|
+
|
|
38
|
+
**如果过滤后列表为空:**
|
|
39
|
+
输出:"当前分支相对于 `<baseBranch>` 无 UI 文件变动,无需同步。" 然后退出。
|
|
40
|
+
|
|
41
|
+
**否则:** 将过滤后的文件列表记为 `<changedFiles>`,继续步骤 ③。
|
|
42
|
+
|
|
43
|
+
## 步骤 ③:识别设计系统文件变动
|
|
44
|
+
|
|
45
|
+
检查 `<changedFiles>` 中是否包含各平台的 `designSystemFile`(跳过值为 `null` 的平台)。
|
|
46
|
+
|
|
47
|
+
**如果包含设计系统文件:**
|
|
48
|
+
|
|
49
|
+
对每个包含的设计系统文件,询问用户:
|
|
50
|
+
|
|
51
|
+
> "`<设计系统文件名>` 发生变动。是否重新生成所有 `<platform>` HTML 设计文件?(推荐:是,确保全局 token 一致)"
|
|
52
|
+
|
|
53
|
+
- **用户选「是」:** 将该平台 manifest 中的所有 entries 加入待处理队列,后续执行全量重新生成。将设计系统文件从 `<changedFiles>` 中移除。
|
|
54
|
+
- **用户选「否」:** 保留 `<changedFiles>` 中的设计系统文件,后续按普通视图文件处理。
|
|
55
|
+
|
|
56
|
+
**如果不包含设计系统文件:** 直接继续步骤 ④。
|
|
57
|
+
|
|
58
|
+
## 步骤 ④:Entry 查找与路由
|
|
59
|
+
|
|
60
|
+
对 `<changedFiles>` 中的每个文件(去重:同一 entry 只触发一次):
|
|
61
|
+
|
|
62
|
+
1. **检查是否在 `manifest.ignoredFiles` 中:** 如果是,跳过。
|
|
63
|
+
|
|
64
|
+
2. **在 manifest.entries 中查找 sourceFiles 包含该文件的 entry:**
|
|
65
|
+
- 找到 → 加入**更新队列**
|
|
66
|
+
- 未找到 → 加入**新建队列**
|
|
67
|
+
|
|
68
|
+
处理完所有文件后:
|
|
69
|
+
- 更新队列非空 → 执行【步骤 ⑤-A:更新流程】
|
|
70
|
+
- 新建队列非空 → 执行【步骤 ⑤-B:新建流程】
|
|
71
|
+
- 两者均为空 → 输出"所有变动文件已在忽略列表中,无需同步。",退出。
|
|
72
|
+
|
|
73
|
+
## 步骤 ⑤-A:更新流程
|
|
74
|
+
|
|
75
|
+
对更新队列中的每个 entry,按顺序执行:
|
|
76
|
+
|
|
77
|
+
### a. 获取精确增量 Diff
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
git diff <entry.lastSyncCommit 或 manifest.baseBranch(如无 lastSyncCommit)>...HEAD -- <entry.sourceFiles 用空格分隔>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### b. 读取上下文
|
|
84
|
+
|
|
85
|
+
依次读取,**后读的内容优先级更高,可覆盖前面的通用指引**:
|
|
86
|
+
|
|
87
|
+
1. `manifest.config.designSpec`(设计规范文件;若不存在则跳过)
|
|
88
|
+
2. 该 entry 所属平台的 `designSystemFile`(若有)
|
|
89
|
+
3. 该平台 `stackRef` 指向的 reference 文件(通用技术栈策略)
|
|
90
|
+
4. 该平台 `styleStrategy` 字段 —— 在 reference 的多种样式策略中,只执行与此字段匹配的那一条;若字段为 `null` 或 reference 中无对应策略,则从源文件内容自行判断
|
|
91
|
+
5. 该平台 `notes` 字段 —— 项目特定约定(如需读取额外文件、某类组件的特殊处理方式等),与 reference 冲突时以 `notes` 为准
|
|
92
|
+
6. `<entry.htmlFile>`(当前 HTML 文件;若不存在则降级为全量生成:读取所有 `entry.sourceFiles` 完整源码)
|
|
93
|
+
|
|
94
|
+
### c. 判断更新范围
|
|
95
|
+
|
|
96
|
+
- **全量重新生成**(entry 在步骤 ③ 的全量队列中):读取所有 `entry.sourceFiles` 完整源码重新生成。
|
|
97
|
+
- **增量更新**(普通视图变动):根据 diff 判断受影响的 UI 状态或组件区块,只替换该部分,保留未变动结构。
|
|
98
|
+
|
|
99
|
+
生成要求见【HTML 生成质量约束】。
|
|
100
|
+
|
|
101
|
+
### d. 写回 HTML 文件
|
|
102
|
+
|
|
103
|
+
## 步骤 ⑤-B:新建流程
|
|
104
|
+
|
|
105
|
+
对新建队列中的每个文件,依次执行:
|
|
106
|
+
|
|
107
|
+
### a. 检查 pattern 覆盖(配置演进)
|
|
108
|
+
|
|
109
|
+
在询问用户之前,先检查:该文件所在目录是否被现有任一 `uiFilePatterns` 覆盖?
|
|
110
|
+
|
|
111
|
+
- **未覆盖** → 在后续询问中附带提示:
|
|
112
|
+
> "此文件目录 `<dir>/` 未在当前配置中。是否将 `<建议 pattern>` 加入 `<platform>.uiFilePatterns`,以便未来自动检测此目录下的变动?"
|
|
113
|
+
- 用户选「是」→ 更新 `manifest.config.platforms[platform].uiFilePatterns`,并在步骤 ⑥ 一并写回
|
|
114
|
+
- 用户选「否」→ 此文件作为 one-off entry 处理,不修改 patterns
|
|
115
|
+
|
|
116
|
+
### b. 询问用户
|
|
117
|
+
|
|
118
|
+
依次提问:
|
|
119
|
+
|
|
120
|
+
1. `发现未映射的 UI 文件:<文件路径>。要为它创建 HTML 设计备份吗?`
|
|
121
|
+
- **跳过并永久忽略:** 加入 `manifest.ignoredFiles`,结束此文件处理。
|
|
122
|
+
- **本次跳过:** 不修改 ignoredFiles。
|
|
123
|
+
- **是:** 继续。
|
|
124
|
+
|
|
125
|
+
2. `屏幕/组件名是什么?(kebab-case,如 "task-history")`
|
|
126
|
+
|
|
127
|
+
3. `这个界面有哪些 UI 状态?(逗号分隔,如 idle, loading, error)`
|
|
128
|
+
|
|
129
|
+
4. `一句话描述这个界面的功能:`
|
|
130
|
+
|
|
131
|
+
根据文件路径匹配 `manifest.config.platforms` 确定所属平台;无法自动匹配时询问用户。
|
|
132
|
+
|
|
133
|
+
### c. 读取上下文
|
|
134
|
+
|
|
135
|
+
依次读取,**后读的内容优先级更高,可覆盖前面的通用指引**:
|
|
136
|
+
|
|
137
|
+
1. `manifest.config.designSpec`(若存在)
|
|
138
|
+
2. 该平台的 `designSystemFile`(若有)
|
|
139
|
+
3. 该平台 `stackRef` 指向的 reference 文件(通用技术栈策略)
|
|
140
|
+
4. 该平台 `styleStrategy` 字段 —— 只执行 reference 中与此字段匹配的样式处理策略;若为 `null` 则从源文件自行判断
|
|
141
|
+
5. 该平台 `notes` 字段 —— 项目特定约定,与 reference 冲突时以 `notes` 为准
|
|
142
|
+
6. 源文件完整内容(及 `notes` 或 reference 中指定的关联文件)
|
|
143
|
+
7. `manifest.config.outputDir` 下**已有的同平台** HTML 文件(选一个作风格参考)
|
|
144
|
+
|
|
145
|
+
### d. 生成完整高保真 HTML
|
|
146
|
+
|
|
147
|
+
生成要求见【HTML 生成质量约束】。
|
|
148
|
+
|
|
149
|
+
输出路径:`<manifest.config.outputDir>/<screenName>-<platform>-design.html`
|
|
150
|
+
|
|
151
|
+
### e. 在 Manifest 新增 Entry
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"id": "<screenName>-<platform>",
|
|
156
|
+
"platform": "<platform>",
|
|
157
|
+
"htmlFile": "<outputDir>/<screenName>-<platform>-design.html",
|
|
158
|
+
"sourceFiles": ["<文件路径>"],
|
|
159
|
+
"uiStates": ["<状态列表>"],
|
|
160
|
+
"lastSyncCommit": null,
|
|
161
|
+
"description": "<用户输入的描述>"
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## 步骤 ⑥:确认与 Manifest 写回
|
|
166
|
+
|
|
167
|
+
### 输出同步摘要
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
本次同步摘要:
|
|
171
|
+
更新:
|
|
172
|
+
· <entry.id>(<htmlFile>)— <变动范围>
|
|
173
|
+
新建:
|
|
174
|
+
· <screenName>-<platform>-design.html(<description>)
|
|
175
|
+
配置变更:
|
|
176
|
+
· <platform>.uiFilePatterns 新增 <pattern>
|
|
177
|
+
忽略:
|
|
178
|
+
· <文件路径>(加入 ignoredFiles)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**用户选「是」:**
|
|
182
|
+
1. `git rev-parse HEAD` 获取当前 commit hash
|
|
183
|
+
2. 将所有已处理 entry 的 `lastSyncCommit` 更新为该 hash
|
|
184
|
+
3. 写回 `docs/reference/design-html-manifest.json`(含配置演进的 patterns 变更)
|
|
185
|
+
4. 询问是否 `git add` 并给出建议 commit message:
|
|
186
|
+
`chore: sync HTML design backups — <entry id 列表>`
|
|
187
|
+
|
|
188
|
+
**用户选「否」:**
|
|
189
|
+
输出:"同步未确认。HTML 文件已写入磁盘但 manifest 未更新。"
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## HTML 生成质量约束
|
|
194
|
+
|
|
195
|
+
1. **Token 来源:** 所有颜色、字体、间距值从当次读取的设计规范和设计系统文件中提取,不得凭记忆填写。
|
|
196
|
+
|
|
197
|
+
2. **CSS 变量命名:** 与设计规范文件中的 token 名完全一致(以实际读取为准,不预设变量名)。
|
|
198
|
+
|
|
199
|
+
3. **UI 状态完整性:** `entry.uiStates` 中的每个状态必须在 HTML 中有对应可视区块或 class 切换。
|
|
200
|
+
|
|
201
|
+
4. **离线可用:** 禁止引用任何外部 URL。样式全部内联在 `<style>` 中,单文件可直接在浏览器打开预览。
|
|
202
|
+
|
|
203
|
+
5. **风格对齐:** 与同项目已有 HTML 文件保持一致的代码风格:CSS 变量声明格式、状态区块注释格式(`/* ── 状态名 ── */`)、整体结构顺序。
|
|
204
|
+
|
|
205
|
+
6. **高保真要求:** 尺寸、圆角、阴影、字号、行高尽量还原设计规范;规范未涉及的参考设计系统文件中的具体值。
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 附录 A:首次初始化流程
|
|
210
|
+
|
|
211
|
+
(manifest 文件不存在时执行)
|
|
212
|
+
|
|
213
|
+
### A-1. 询问基础配置
|
|
214
|
+
|
|
215
|
+
1. `这个项目的 base 分支是什么?(如 main / staging)`
|
|
216
|
+
2. `HTML 设计备份存放在哪个目录?(默认:docs/reference/design-previews/)`
|
|
217
|
+
3. `设计规范文件路径是什么?(如 DESIGN.md;若无请留空)`
|
|
218
|
+
|
|
219
|
+
### A-2. 自动检测技术栈
|
|
220
|
+
|
|
221
|
+
先读取 `references/stacks.md`(包含所有已知栈的检测信号),然后依次执行以下检测:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# 1. 语言级特征文件
|
|
225
|
+
find . -maxdepth 4 -name "*.xcodeproj" -o -name "Package.swift" 2>/dev/null | grep -v node_modules | head -3
|
|
226
|
+
find . -maxdepth 3 -name "pubspec.yaml" 2>/dev/null | head -3
|
|
227
|
+
|
|
228
|
+
# 2. 读取 package.json(若存在)
|
|
229
|
+
cat package.json 2>/dev/null
|
|
230
|
+
|
|
231
|
+
# 3. 框架配置文件
|
|
232
|
+
ls next.config.js next.config.ts nuxt.config.ts nuxt.config.js svelte.config.js angular.json astro.config.mjs tauri.conf.json 2>/dev/null
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
根据 `references/stacks.md` 中的检测规则匹配技术栈,加载对应的 `references/stack-<name>.md`。
|
|
236
|
+
|
|
237
|
+
**可能检测到多个栈**(如 Electron 同时含 `electron` 和 `react`):按 `stacks.md` 中的优先级取最具体的一个,次要技术作为备注记录。
|
|
238
|
+
|
|
239
|
+
### A-3. 运行发现命令
|
|
240
|
+
|
|
241
|
+
从加载的 `stack-*.md` 中读取【发现命令】,执行以发现项目中实际存在的 UI 文件:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
# 示例(实际命令见各 stack-*.md)
|
|
245
|
+
find src -type f \( -name "*.tsx" -o -name "*.vue" \) | grep -v node_modules | grep -v test | grep -v spec | grep -v __tests__ | sort
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
将发现的文件按目录分组,推导出 `uiFilePatterns`(取最小覆盖的 glob,避免过于宽泛)。
|
|
249
|
+
|
|
250
|
+
同时按 `stack-*.md` 中的【设计系统文件候选】自动探测是否存在对应文件:
|
|
251
|
+
```bash
|
|
252
|
+
ls <候选路径1> <候选路径2> ... 2>/dev/null
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
同时探测实际样式方案(`styleStrategy`):
|
|
256
|
+
```bash
|
|
257
|
+
# Tailwind
|
|
258
|
+
ls tailwind.config.js tailwind.config.ts 2>/dev/null
|
|
259
|
+
|
|
260
|
+
# CSS Modules
|
|
261
|
+
find src -name "*.module.css" -o -name "*.module.scss" 2>/dev/null | head -3
|
|
262
|
+
|
|
263
|
+
# vanilla-extract
|
|
264
|
+
find src -name "*.css.ts" -o -name "*.css.js" 2>/dev/null | head -3
|
|
265
|
+
|
|
266
|
+
# styled-components / emotion
|
|
267
|
+
grep -E '"styled-components"|"@emotion/react"' package.json 2>/dev/null
|
|
268
|
+
|
|
269
|
+
# UnoCSS
|
|
270
|
+
ls uno.config.ts uno.config.js 2>/dev/null
|
|
271
|
+
|
|
272
|
+
# 若以上均无匹配,检查是否有全局 CSS 或 SCSS
|
|
273
|
+
find src -name "*.scss" -o -name "variables.css" 2>/dev/null | head -3
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
按检测结果确定 `styleStrategy` 值:`tailwind` / `css-modules` / `vanilla-extract` / `styled-components` / `emotion` / `unocss` / `scss` / `css` / `unknown`。若检测到多种混用,记录主要策略,其余在 `notes` 中说明。
|
|
277
|
+
|
|
278
|
+
### A-4. 展示检测结果并请用户确认
|
|
279
|
+
|
|
280
|
+
输出检测摘要,格式如下:
|
|
281
|
+
|
|
282
|
+
```
|
|
283
|
+
检测到技术栈:<栈名称>(参考文件:references/stack-<name>.md)
|
|
284
|
+
|
|
285
|
+
建议平台配置:
|
|
286
|
+
<platform-id>(<label>)
|
|
287
|
+
uiFilePatterns:
|
|
288
|
+
· <pattern1>(发现 N 个文件)
|
|
289
|
+
· <pattern2>(发现 M 个文件)
|
|
290
|
+
designSystemFile: <路径 或 未检测到>
|
|
291
|
+
styleStrategy: <检测到的样式方案>
|
|
292
|
+
|
|
293
|
+
以上配置是否正确?可告知我需要调整的部分。
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
等待用户确认或修改。若用户提出调整,按其意见修改配置后再次展示确认。
|
|
297
|
+
|
|
298
|
+
确认后,追加询问:
|
|
299
|
+
|
|
300
|
+
> `这个项目有哪些与参考文档不同的约定需要记录?(如特殊的全局组件、非标准文件位置、样式混用规则等;若无请留空)`
|
|
301
|
+
|
|
302
|
+
将用户输入记为该平台的 `notes`(空字符串或 `null` 均可)。这些 notes 在每次同步时会覆盖 reference 中冲突的通用建议。
|
|
303
|
+
|
|
304
|
+
### A-5. 创建 Manifest
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"version": 3,
|
|
309
|
+
"baseBranch": "<用户输入>",
|
|
310
|
+
"config": {
|
|
311
|
+
"outputDir": "<用户输入>",
|
|
312
|
+
"designSpec": "<路径 或 null>",
|
|
313
|
+
"platforms": {
|
|
314
|
+
"<platform-id>": {
|
|
315
|
+
"label": "<平台展示名>",
|
|
316
|
+
"stackRef": "references/stack-<name>.md",
|
|
317
|
+
"uiFilePatterns": ["<自动推导的 glob>"],
|
|
318
|
+
"designSystemFile": "<路径 或 null>",
|
|
319
|
+
"styleStrategy": "<检测到的样式方案>",
|
|
320
|
+
"notes": "<用户补充的项目特定约定,或 null>"
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
"entries": [],
|
|
325
|
+
"ignoredFiles": []
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**字段说明:**
|
|
330
|
+
- `stackRef`:通用技术栈参考,同步时作为基础策略加载
|
|
331
|
+
- `styleStrategy`:样式方案标识,同步时从 reference 中只执行对应策略,避免猜测
|
|
332
|
+
- `notes`:项目特定约定,优先级高于 reference,记录与通用参考不符的部分
|
|
333
|
+
|
|
334
|
+
继续执行主流程步骤 ②。
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 附录 B:已有 HTML 扫描流程
|
|
339
|
+
|
|
340
|
+
(manifest 存在但 `entries` 为空时执行)
|
|
341
|
+
|
|
342
|
+
1. 扫描 `manifest.config.outputDir` 下所有 `*.html` 文件。
|
|
343
|
+
2. 对每个 HTML 文件,询问用户:
|
|
344
|
+
|
|
345
|
+
> `发现现有 HTML 文件:<文件名>。要为它建立 manifest 映射吗?`
|
|
346
|
+
|
|
347
|
+
- **跳过:** 不处理,继续下一个。
|
|
348
|
+
- **是:** 依次询问:
|
|
349
|
+
1. `对应哪些源文件?(相对于项目根的路径,多个用逗号分隔)`
|
|
350
|
+
2. `覆盖哪些 UI 状态?(如 idle, loading,用逗号分隔)`
|
|
351
|
+
3. `一句话描述:`
|
|
352
|
+
- 构造 entry(`lastSyncCommit` 设为 `null`)加入 `entries`。
|
|
353
|
+
|
|
354
|
+
3. 全部处理完毕后,写入 manifest,继续步骤 ②。
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Electron 技术栈指南
|
|
2
|
+
|
|
3
|
+
适用于 Electron 应用的渲染进程 UI。
|
|
4
|
+
|
|
5
|
+
> **使用方式:** 同步时从 manifest 读取 `styleStrategy` 字段,只执行渲染层对应 stack 文件中匹配策略的那一节。若 `notes` 字段非空,以 `notes` 覆盖本文件中的冲突建议。Electron 渲染层通常是 React 或 Vue,本文件处理 Electron 特有的目录结构和注意事项;样式方案细节参考 `stack-react.md` 或 `stack-vue.md`。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 发现命令
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 识别渲染层框架
|
|
13
|
+
cat package.json | grep -E '"react"|"vue"|"svelte"'
|
|
14
|
+
|
|
15
|
+
# 发现渲染进程目录结构(常见布局)
|
|
16
|
+
ls src/renderer src/renderer/src src/web src/ui 2>/dev/null
|
|
17
|
+
|
|
18
|
+
# 发现页面/视图级组件
|
|
19
|
+
find src -type d \( -name "pages" -o -name "views" -o -name "screens" -o -name "windows" \) \
|
|
20
|
+
| grep -v node_modules | head -10
|
|
21
|
+
|
|
22
|
+
# 发现所有渲染层 UI 文件(根据检测到的框架选扩展名)
|
|
23
|
+
find src/renderer -type f \( -name "*.tsx" -o -name "*.jsx" -o -name "*.vue" \) \
|
|
24
|
+
| grep -v node_modules | grep -v __tests__ | grep -v ".test." | sort
|
|
25
|
+
|
|
26
|
+
# 发现设计系统文件
|
|
27
|
+
ls src/renderer/src/styles/tokens.css \
|
|
28
|
+
src/renderer/styles/variables.css \
|
|
29
|
+
src/renderer/src/theme.ts \
|
|
30
|
+
src/styles/tokens.css \
|
|
31
|
+
tailwind.config.js tailwind.config.ts 2>/dev/null
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 平台配置模板
|
|
37
|
+
|
|
38
|
+
```json
|
|
39
|
+
{
|
|
40
|
+
"renderer": {
|
|
41
|
+
"label": "Renderer",
|
|
42
|
+
"stackRef": "references/stack-electron.md",
|
|
43
|
+
"uiFilePatterns": [
|
|
44
|
+
"src/renderer/src/pages/**/*.tsx",
|
|
45
|
+
"src/renderer/src/views/**/*.tsx"
|
|
46
|
+
],
|
|
47
|
+
"designSystemFile": "<检测到的 token 文件,或 null>"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Electron 特有目录结构
|
|
55
|
+
|
|
56
|
+
常见项目布局(不同脚手架有差异):
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
# electron-vite / electron-builder + Vite
|
|
60
|
+
src/
|
|
61
|
+
main/ ← 主进程(Node.js),不含 UI
|
|
62
|
+
preload/ ← preload 脚本,不含 UI
|
|
63
|
+
renderer/ ← 渲染进程(React/Vue)← 扫描这里
|
|
64
|
+
src/
|
|
65
|
+
pages/
|
|
66
|
+
components/
|
|
67
|
+
styles/
|
|
68
|
+
|
|
69
|
+
# Electron Forge
|
|
70
|
+
src/
|
|
71
|
+
index.ts ← 主进程入口
|
|
72
|
+
renderer.ts ← 渲染进程入口
|
|
73
|
+
components/ ← UI 组件 ← 扫描这里
|
|
74
|
+
pages/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
初始化时通过 `ls src/main src/preload src/renderer` 判断是哪种结构,只扫描渲染层目录。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 多窗口支持
|
|
82
|
+
|
|
83
|
+
Electron 应用可能有多个独立窗口(主窗口、偏好设置、托盘弹窗等),每个窗口对应不同的入口。若发现多个窗口目录,每个窗口可配置为独立的 platform(或在同一 platform 下作为不同 entry):
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"main-window": {
|
|
88
|
+
"label": "主窗口",
|
|
89
|
+
"uiFilePatterns": ["src/renderer/pages/**/*.tsx"],
|
|
90
|
+
"designSystemFile": "src/renderer/styles/tokens.css"
|
|
91
|
+
},
|
|
92
|
+
"settings-window": {
|
|
93
|
+
"label": "设置窗口",
|
|
94
|
+
"uiFilePatterns": ["src/settings/**/*.tsx"],
|
|
95
|
+
"designSystemFile": "src/renderer/styles/tokens.css"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 源文件读取策略
|
|
103
|
+
|
|
104
|
+
渲染层框架对应的样式读取策略见:
|
|
105
|
+
- React 渲染层 → `stack-react.md` 中的"源文件读取策略"
|
|
106
|
+
- Vue 渲染层 → `stack-vue.md` 中的"源文件读取策略"
|
|
107
|
+
|
|
108
|
+
Electron 特有补充:
|
|
109
|
+
- **IPC 调用**(`ipcRenderer.invoke()`)在 HTML 备份中显示为占位状态(loading 或默认值),不需还原真实数据
|
|
110
|
+
- **Node.js API**(`fs`、`path`、`shell`)只在主进程中使用,渲染层不会出现
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 常见 Gotchas
|
|
115
|
+
|
|
116
|
+
- **主进程文件**:`src/main/`、`src/background.ts`、`preload.ts` 等不是 UI 文件,`uiFilePatterns` 中明确排除
|
|
117
|
+
- **Electron 特定 API**:`remote.app`、`nativeTheme` 等在 HTML 中取固定值(如 `nativeTheme` 取 light 模式)
|
|
118
|
+
- **窗口尺寸**:Electron 窗口通常有固定或最小尺寸,HTML 预览设置对应的 `max-width` 和最小高度以还原真实比例
|
|
119
|
+
- **系统原生控件**:标题栏、`<webview>`、系统对话框在 HTML 中用灰色矩形占位,标注"系统原生控件"
|