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,101 @@
|
|
|
1
|
+
# Next.js 技术栈指南
|
|
2
|
+
|
|
3
|
+
适用于 Next.js 13+(App Router)和 Next.js 12 以下(Pages Router)。
|
|
4
|
+
|
|
5
|
+
> **使用方式:** 同步时从 manifest 读取 `styleStrategy` 字段,只执行"源文件读取策略"中对应策略的那一节。若 `notes` 字段非空,以 `notes` 覆盖本文件中的冲突建议。样式方案细节参考 `stack-react.md`。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 发现命令
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 判断 App Router 还是 Pages Router
|
|
13
|
+
ls app/ src/app/ pages/ src/pages/ 2>/dev/null
|
|
14
|
+
|
|
15
|
+
# App Router:发现页面和布局文件
|
|
16
|
+
find app src/app -type f -name "page.tsx" -o -name "layout.tsx" -o -name "loading.tsx" -o -name "error.tsx" \
|
|
17
|
+
| grep -v node_modules | sort
|
|
18
|
+
|
|
19
|
+
# Pages Router:发现页面文件
|
|
20
|
+
find pages src/pages -type f \( -name "*.tsx" -o -name "*.jsx" \) \
|
|
21
|
+
| grep -v node_modules | grep -v "_app" | grep -v "_document" | grep -v "api" | sort
|
|
22
|
+
|
|
23
|
+
# 发现共享组件
|
|
24
|
+
find components src/components -type f \( -name "*.tsx" -o -name "*.jsx" \) \
|
|
25
|
+
| grep -v node_modules | sort
|
|
26
|
+
|
|
27
|
+
# 设计系统文件候选
|
|
28
|
+
ls tailwind.config.js tailwind.config.ts \
|
|
29
|
+
styles/globals.css src/styles/globals.css \
|
|
30
|
+
styles/tokens.css src/styles/tokens.css \
|
|
31
|
+
lib/theme.ts src/lib/theme.ts 2>/dev/null
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 平台配置模板
|
|
37
|
+
|
|
38
|
+
**App Router:**
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"web": {
|
|
42
|
+
"label": "Web",
|
|
43
|
+
"stackRef": "references/stack-nextjs.md",
|
|
44
|
+
"uiFilePatterns": [
|
|
45
|
+
"app/**/page.tsx",
|
|
46
|
+
"app/**/layout.tsx"
|
|
47
|
+
],
|
|
48
|
+
"designSystemFile": "<token 文件或 null>"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Pages Router:**
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"web": {
|
|
57
|
+
"label": "Web",
|
|
58
|
+
"stackRef": "references/stack-nextjs.md",
|
|
59
|
+
"uiFilePatterns": [
|
|
60
|
+
"pages/**/*.tsx",
|
|
61
|
+
"src/pages/**/*.tsx"
|
|
62
|
+
],
|
|
63
|
+
"designSystemFile": "<token 文件或 null>"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 源文件读取策略
|
|
71
|
+
|
|
72
|
+
### App Router 特有
|
|
73
|
+
|
|
74
|
+
- **`page.tsx`**:页面主体,是主要的 UI 源文件
|
|
75
|
+
- **`layout.tsx`**:包裹 page 的壳(导航栏、侧边栏等)。若 page 的外观依赖 layout,同时读取最近一层的 layout.tsx
|
|
76
|
+
- **`loading.tsx`**:骨架屏或加载态,是一个独立的 `uiState`
|
|
77
|
+
- **`error.tsx`**:错误态,也是独立的 `uiState`
|
|
78
|
+
- **Server Components vs Client Components**:对 HTML 生成无影响,都读取 `return` 的 JSX 结构
|
|
79
|
+
|
|
80
|
+
### 路由参数
|
|
81
|
+
|
|
82
|
+
- `[id]`、`[slug]` 等动态段在 HTML 备份中用占位值替代(如 `123`、`example-post`)
|
|
83
|
+
|
|
84
|
+
### Metadata
|
|
85
|
+
|
|
86
|
+
- `export const metadata = { title: '...' }` → 设置 HTML `<title>`
|
|
87
|
+
|
|
88
|
+
### 样式方案
|
|
89
|
+
|
|
90
|
+
参考 `stack-react.md` 中对应样式方案的读取策略(Tailwind / CSS Modules / styled-components)。
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 常见 Gotchas
|
|
95
|
+
|
|
96
|
+
- **API Routes**:`app/api/` 或 `pages/api/` 下的文件不是 UI,`uiFilePatterns` 中排除(用 `grep -v api` 过滤)
|
|
97
|
+
- **`_app.tsx` / `_document.tsx`**:全局配置文件,不直接对应某个界面;若影响全局样式(如注入 CSS 变量),在生成 HTML 时纳入上下文
|
|
98
|
+
- **Middleware**:`middleware.ts` 不是 UI 文件
|
|
99
|
+
- **图片优化**:`<Image>` 组件 → HTML 中用 `<img>` 替代,设置对应的 `width`/`height`/`object-fit`
|
|
100
|
+
- **Link 组件**:`<Link href="...">` → HTML 中用 `<a>` 替代
|
|
101
|
+
- **`use client` / `use server`**:不影响 HTML 生成,忽略这些指令
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# React 技术栈指南
|
|
2
|
+
|
|
3
|
+
适用于 React + Vite / CRA / 纯 React 项目(不含 Next.js,见 stack-nextjs.md)。
|
|
4
|
+
|
|
5
|
+
> **使用方式:** 同步时从 manifest 读取 `styleStrategy` 字段,只执行下方"源文件读取策略"中对应策略的那一节,忽略其他节。若 `styleStrategy` 为 `unknown`,则读取源文件内容后自行判断。若 `notes` 字段非空,以 `notes` 覆盖本文件中的冲突建议。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 发现命令
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 发现页面/视图级组件(优先)
|
|
13
|
+
find src -type f \( -name "*.tsx" -o -name "*.jsx" \) \
|
|
14
|
+
| grep -v node_modules | grep -v __tests__ | grep -v ".test." | grep -v ".spec." \
|
|
15
|
+
| grep -E "(pages|views|screens|Page|View|Screen)" | sort
|
|
16
|
+
|
|
17
|
+
# 发现所有 React 组件(若上面结果太少)
|
|
18
|
+
find src -type f \( -name "*.tsx" -o -name "*.jsx" \) \
|
|
19
|
+
| grep -v node_modules | grep -v __tests__ | grep -v ".test." | grep -v ".spec." | sort
|
|
20
|
+
|
|
21
|
+
# 发现设计系统文件候选
|
|
22
|
+
ls src/styles/tokens.css src/styles/variables.css src/styles/theme.ts src/theme.ts \
|
|
23
|
+
src/styles/design-tokens.ts tailwind.config.js tailwind.config.ts \
|
|
24
|
+
src/design-system/index.ts 2>/dev/null
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 平台配置模板
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"web": {
|
|
34
|
+
"label": "Web",
|
|
35
|
+
"stackRef": "references/stack-react.md",
|
|
36
|
+
"uiFilePatterns": [
|
|
37
|
+
"src/pages/**/*.tsx",
|
|
38
|
+
"src/views/**/*.tsx"
|
|
39
|
+
],
|
|
40
|
+
"designSystemFile": "<检测到的 token 文件,或 null>"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`uiFilePatterns` 根据发现命令的实际结果推导目录层级,优先选择 `pages/`、`views/`、`screens/` 等语义目录,避免把整个 `src/components/**` 都纳入(太宽泛)。
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 样式方案识别
|
|
50
|
+
|
|
51
|
+
初始化时检测项目使用的样式方案,记录到 manifest 的平台配置中(`styleStrategy` 字段):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# 检测 Tailwind
|
|
55
|
+
ls tailwind.config.js tailwind.config.ts 2>/dev/null
|
|
56
|
+
grep -r "tailwindcss" package.json 2>/dev/null
|
|
57
|
+
|
|
58
|
+
# 检测 CSS Modules
|
|
59
|
+
find src -name "*.module.css" -o -name "*.module.scss" | head -3 2>/dev/null
|
|
60
|
+
|
|
61
|
+
# 检测 styled-components / emotion
|
|
62
|
+
grep -E '"styled-components"|"@emotion/react"' package.json 2>/dev/null
|
|
63
|
+
|
|
64
|
+
# 检测 CSS-in-JS (vanilla-extract, stitches, etc.)
|
|
65
|
+
grep -E '"@vanilla-extract"|"@stitches"' package.json 2>/dev/null
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## 源文件读取策略
|
|
71
|
+
|
|
72
|
+
### Tailwind CSS
|
|
73
|
+
|
|
74
|
+
- 读取 `tailwind.config.js` / `tailwind.config.ts` 中的 `theme.extend`,提取自定义颜色、字体、间距
|
|
75
|
+
- class 名(如 `text-sm font-medium text-gray-700`)映射为实际 CSS 值,写入 HTML `<style>` 块中
|
|
76
|
+
- 不要直接在 HTML 中使用 Tailwind class(离线时无法渲染)
|
|
77
|
+
- 颜色:`text-gray-700` → `color: #374151`;布局:`flex flex-col gap-4` → `display:flex; flex-direction:column; gap:1rem`
|
|
78
|
+
|
|
79
|
+
### CSS Modules
|
|
80
|
+
|
|
81
|
+
- 同时读取与源文件同名的 `.module.css` / `.module.scss`
|
|
82
|
+
- 将 class 中的样式声明提取到 HTML `<style>` 块中
|
|
83
|
+
- `styles.container` → 对应 `.container` 选择器的内容
|
|
84
|
+
|
|
85
|
+
### styled-components / emotion
|
|
86
|
+
|
|
87
|
+
- CSS 定义内联在 JS 中,从组件定义处提取样式字符串
|
|
88
|
+
- 动态样式(依赖 props 的)取默认态或最常见态的值
|
|
89
|
+
|
|
90
|
+
### 普通 CSS / SCSS
|
|
91
|
+
|
|
92
|
+
- 读取源文件 `import` 的 CSS 文件,提取相关规则
|
|
93
|
+
|
|
94
|
+
### 内联 style prop
|
|
95
|
+
|
|
96
|
+
- 直接转换为 HTML `style` 属性
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 组件 Props 与 UI 状态
|
|
101
|
+
|
|
102
|
+
React 组件的 UI 状态通常来自:
|
|
103
|
+
- `useState`:`const [isLoading, setIsLoading] = useState(false)`
|
|
104
|
+
- Props:`interface Props { variant: 'primary' | 'ghost'; disabled?: boolean }`
|
|
105
|
+
- 外部 store(Zustand/Redux):查看组件订阅的 slice
|
|
106
|
+
|
|
107
|
+
识别 UI 状态时,检查 TypeScript 类型定义和 `if/switch` 条件渲染分支,这些分支就是需要在 HTML 中体现的 `uiStates`。
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 常见 Gotchas
|
|
112
|
+
|
|
113
|
+
- **Context / Provider**:`ThemeProvider`、`AuthContext` 等 wrapper 不需要在 HTML 中体现,只还原视觉层
|
|
114
|
+
- **lazy import**:`React.lazy(() => import('./Page'))` 中的组件路径是真实源文件,正常处理
|
|
115
|
+
- **动态 className**:`clsx(styles.btn, { [styles.active]: isActive })` → 生成所有可能的 class 组合,在 HTML 中用独立区块展示各状态
|
|
116
|
+
- **图片 / SVG import**:`import logo from './logo.svg'` → HTML 中用占位矩形替代,标注尺寸和描述
|
|
117
|
+
- **国际化字符串**:`t('key')` → 保留 key 名或使用中文描述性文字
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# SwiftUI 技术栈指南
|
|
2
|
+
|
|
3
|
+
适用于 iOS / macOS / visionOS 的 SwiftUI 项目,支持单平台和多平台双目录结构。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 发现命令
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 发现 iOS UI 文件
|
|
11
|
+
find . -type f \( -name "*View.swift" -o -name "*Screen.swift" \) \
|
|
12
|
+
| grep -v ".build" | grep -v "Tests" | grep -v "Preview" | sort
|
|
13
|
+
|
|
14
|
+
# 发现 macOS UI 文件(常在单独目录)
|
|
15
|
+
find . -type f \( -name "*View.swift" -o -name "*Section.swift" -o -name "*Card.swift" \) \
|
|
16
|
+
| grep -v ".build" | grep -v "Tests" | sort
|
|
17
|
+
|
|
18
|
+
# 发现设计系统文件
|
|
19
|
+
find . -type f \( -name "*DesignSystem.swift" -o -name "*Theme.swift" -o -name "*Style.swift" \) \
|
|
20
|
+
| grep -v ".build" | grep -v "Tests" | head -5
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
将发现的文件按目录分组,推导出各平台的目录前缀,生成 patterns。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 平台识别逻辑
|
|
28
|
+
|
|
29
|
+
SwiftUI 项目通常有两种结构:
|
|
30
|
+
|
|
31
|
+
**单 target(iOS/macOS 共用):**
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"app": {
|
|
35
|
+
"label": "App",
|
|
36
|
+
"uiFilePatterns": ["<AppModule>/**/*View.swift", "<AppModule>/**/*Screen.swift"],
|
|
37
|
+
"designSystemFile": "<AppModule>/<Name>DesignSystem.swift"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**双 target(iOS + macOS 分离目录):**
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"ios": {
|
|
46
|
+
"label": "iOS",
|
|
47
|
+
"uiFilePatterns": ["<iOSModule>/**/*View.swift", "<iOSModule>/**/*Screen.swift"],
|
|
48
|
+
"designSystemFile": "<iOSModule>/<Name>DesignSystem.swift"
|
|
49
|
+
},
|
|
50
|
+
"macos": {
|
|
51
|
+
"label": "macOS",
|
|
52
|
+
"uiFilePatterns": ["<macOSModule>/**/*View.swift", "<macOSModule>/**/*Section.swift", "<macOSModule>/**/*Card.swift"],
|
|
53
|
+
"designSystemFile": "<macOSModule>/<Name>DesignSystem.swift"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
检测到 UI 文件后,通过目录路径判断是单 target 还是双 target,告知用户并按需拆分。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 设计系统文件候选
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
find . -name "*DesignSystem.swift" -o -name "*Theme.swift" -o -name "*Tokens.swift" \
|
|
66
|
+
| grep -v ".build" | grep -v Tests
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
SwiftUI 的设计 token 通常以 `Color` 扩展、`Font` 扩展、`CGFloat` 常量的形式定义:
|
|
70
|
+
|
|
71
|
+
```swift
|
|
72
|
+
extension Color {
|
|
73
|
+
static let background = Color("Background")
|
|
74
|
+
static let accent = Color("AccentColor")
|
|
75
|
+
}
|
|
76
|
+
extension CGFloat {
|
|
77
|
+
static let cornerRadius: CGFloat = 12
|
|
78
|
+
static let spacing: CGFloat = 16
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 源文件读取策略
|
|
85
|
+
|
|
86
|
+
SwiftUI 视图是声明式的,一个文件通常完整描述一个界面。读取时:
|
|
87
|
+
|
|
88
|
+
1. **读主视图文件**:包含 `body` 的 `View` struct
|
|
89
|
+
2. **识别 UI 状态来源**:
|
|
90
|
+
- `@State private var isLoading: Bool` → state 驱动
|
|
91
|
+
- `enum ViewState { case idle, loading, error }` → 枚举驱动
|
|
92
|
+
- 函数参数 / `@Binding` → 外部注入
|
|
93
|
+
3. **处理子视图**:若文件中有 `SomeChildView()` 调用且子视图影响视觉,读取对应文件。优先处理项目内部自定义组件;系统组件(`Button`、`List`、`NavigationView`)凭知识推断。
|
|
94
|
+
4. **读取设计系统文件**:提取颜色常量名、字体定义、间距值,用于生成 CSS 变量。
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## HTML 生成注意事项
|
|
99
|
+
|
|
100
|
+
- SwiftUI 的颜色常量名(如 `Color.accent`)直接映射为 CSS 变量名(`--accent`)
|
|
101
|
+
- `cornerRadius`、`padding`、`spacing` 等 `CGFloat` 常量转换为对应 CSS 值(px)
|
|
102
|
+
- `HStack`/`VStack`/`ZStack` → `display: flex` + `flex-direction`
|
|
103
|
+
- `LazyVGrid`/`LazyHGrid` → `display: grid`
|
|
104
|
+
- `.frame(width:height:)` → `width`/`height`,`.frame(maxWidth: .infinity)` → `width: 100%`
|
|
105
|
+
- Dark mode(`.colorScheme`)→ `@media (prefers-color-scheme: dark)`
|
|
106
|
+
- SF Symbols 用 Unicode 字符或 emoji 近似替代,不引用外部图标库
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 常见 Gotchas
|
|
111
|
+
|
|
112
|
+
- **Preview 文件**:`*_Previews.swift` 或 `PreviewProvider` 不是 UI 源文件,检测时排除
|
|
113
|
+
- **SwiftUI Representable**:`UIViewRepresentable` / `NSViewRepresentable` 包装的 UIKit/AppKit 视图,HTML 生成时只还原视觉外观,不还原底层实现
|
|
114
|
+
- **条件编译**:`#if os(iOS)` 块注意按平台分别处理
|
|
115
|
+
- **Assets Catalog**:颜色可能定义在 `.xcassets` 而非 Swift 代码,读设计系统文件时若颜色名以字符串引用(`Color("Background")`),需在 Assets 中查找实际值
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Vue / Nuxt 技术栈指南
|
|
2
|
+
|
|
3
|
+
适用于 Vue 3 + Vite、Vue 2、以及 Nuxt 3 / Nuxt 2 项目。
|
|
4
|
+
|
|
5
|
+
> **使用方式:** 同步时从 manifest 读取 `styleStrategy` 字段,只执行"样式方案"中对应策略的那一节。若 `notes` 字段非空,以 `notes` 覆盖本文件中的冲突建议。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 发现命令
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# 判断是否为 Nuxt
|
|
13
|
+
ls nuxt.config.ts nuxt.config.js 2>/dev/null
|
|
14
|
+
|
|
15
|
+
# Nuxt 3:发现页面文件
|
|
16
|
+
find pages -type f -name "*.vue" | grep -v node_modules | sort
|
|
17
|
+
|
|
18
|
+
# Vue 通用:发现视图/页面组件
|
|
19
|
+
find src -type f -name "*.vue" \
|
|
20
|
+
| grep -v node_modules | grep -v __tests__ | grep -v ".test." \
|
|
21
|
+
| grep -E "(views|pages|screens|layouts)" | sort
|
|
22
|
+
|
|
23
|
+
# Vue 通用:发现所有组件
|
|
24
|
+
find src -type f -name "*.vue" \
|
|
25
|
+
| grep -v node_modules | grep -v __tests__ | sort
|
|
26
|
+
|
|
27
|
+
# 设计系统文件候选
|
|
28
|
+
ls src/styles/variables.css src/styles/tokens.css \
|
|
29
|
+
src/styles/variables.scss src/assets/styles/variables.scss \
|
|
30
|
+
src/theme.ts src/plugins/theme.ts \
|
|
31
|
+
tailwind.config.js tailwind.config.ts \
|
|
32
|
+
uno.config.ts 2>/dev/null
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 平台配置模板
|
|
38
|
+
|
|
39
|
+
**Vue + Vite:**
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"web": {
|
|
43
|
+
"label": "Web",
|
|
44
|
+
"stackRef": "references/stack-vue.md",
|
|
45
|
+
"uiFilePatterns": [
|
|
46
|
+
"src/views/**/*.vue",
|
|
47
|
+
"src/pages/**/*.vue"
|
|
48
|
+
],
|
|
49
|
+
"designSystemFile": "<token 文件或 null>"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Nuxt 3:**
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"web": {
|
|
58
|
+
"label": "Web",
|
|
59
|
+
"stackRef": "references/stack-vue.md",
|
|
60
|
+
"uiFilePatterns": [
|
|
61
|
+
"pages/**/*.vue",
|
|
62
|
+
"layouts/**/*.vue"
|
|
63
|
+
],
|
|
64
|
+
"designSystemFile": "<token 文件或 null>"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 源文件读取策略
|
|
72
|
+
|
|
73
|
+
### 单文件组件(SFC)结构
|
|
74
|
+
|
|
75
|
+
Vue SFC(`.vue`)把模板、脚本、样式放在同一文件:
|
|
76
|
+
|
|
77
|
+
```vue
|
|
78
|
+
<template> ← UI 结构,重点读取
|
|
79
|
+
<script setup lang="ts"> ← 状态定义
|
|
80
|
+
<style scoped> ← 局部样式,直接使用
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
读取顺序:
|
|
84
|
+
1. 先读 `<template>` 确定 UI 结构和状态分支
|
|
85
|
+
2. 读 `<script setup>` 中的 `ref`、`computed`、`defineProps` 确定状态来源
|
|
86
|
+
3. 读 `<style scoped>` / `<style module>` 提取样式规则,直接内联到 HTML `<style>` 中
|
|
87
|
+
|
|
88
|
+
### Composition API 状态识别
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const isLoading = ref(false) // → uiState: loading
|
|
92
|
+
const error = ref<string | null>(null) // → uiState: error
|
|
93
|
+
const props = defineProps<{ // → 多态变体
|
|
94
|
+
variant: 'primary' | 'ghost'
|
|
95
|
+
}>()
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Options API 状态识别
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
data() {
|
|
102
|
+
return { isOpen: false, activeTab: 'general' }
|
|
103
|
+
}
|
|
104
|
+
computed: {
|
|
105
|
+
isEmpty() { return this.items.length === 0 }
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 样式方案
|
|
110
|
+
|
|
111
|
+
**`<style scoped>`(最常见):**
|
|
112
|
+
直接提取样式规则,添加到 HTML `<style>` 中(去掉 scoped 特性)。
|
|
113
|
+
|
|
114
|
+
**`<style module>`:**
|
|
115
|
+
通过 `$style.className` 引用,将 CSS Modules 的类名提取并内联。
|
|
116
|
+
|
|
117
|
+
**Tailwind / UnoCSS:**
|
|
118
|
+
参考 `stack-react.md` 中的 Tailwind 处理策略(class 映射为实际 CSS 值)。
|
|
119
|
+
UnoCSS class 处理方式与 Tailwind 相同。
|
|
120
|
+
|
|
121
|
+
**全局变量(SCSS variables):**
|
|
122
|
+
若 `<style>` 中有 `@use '~/styles/variables' as *`,需同时读取对应变量文件。
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Nuxt 特有
|
|
127
|
+
|
|
128
|
+
- **`layouts/`**:类似 Next.js 的 layout,包裹页面的壳(导航、侧边栏)。当 page 依赖某个 layout 时,一并读取
|
|
129
|
+
- **Nuxt auto-imports**:`useRoute()`、`useFetch()` 等不需要显式 import,读取时知道这些是 Nuxt 内置即可,不影响 HTML 生成
|
|
130
|
+
- **`server/` 目录**:API 路由,不是 UI 文件,排除
|
|
131
|
+
- **`composables/`**:状态逻辑,按需读取影响 UI 的部分
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 常见 Gotchas
|
|
136
|
+
|
|
137
|
+
- **`v-if` / `v-show`**:条件渲染分支通常就是不同的 `uiState`,在 HTML 中分别展示
|
|
138
|
+
- **`v-for`**:用 2-3 个典型数据项展示列表状态
|
|
139
|
+
- **`<RouterView>` / `<NuxtPage>`**:在 HTML 中用占位区域替代,标注"子页面区域"
|
|
140
|
+
- **`<Transition>`**:HTML 中只展示静态状态,不还原动画
|
|
141
|
+
- **图片**:`<img :src="...">`、`<NuxtImg>` → `<img>` 占位,设置尺寸
|
|
142
|
+
- **Slot**:`<slot>` 用有代表性的内容填充(参考组件的典型用法)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# 技术栈检测索引
|
|
2
|
+
|
|
3
|
+
初始化时读取此文件,确定项目技术栈并加载对应的 `stack-*.md`。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 检测规则(按优先级从高到低)
|
|
8
|
+
|
|
9
|
+
检测到信号后即停止,取优先级最高的匹配。多平台项目(如 SwiftUI iOS+macOS)在单个 stack 文件中处理。
|
|
10
|
+
|
|
11
|
+
| 优先级 | 技术栈 | 检测信号 | Reference 文件 |
|
|
12
|
+
|--------|--------|---------|----------------|
|
|
13
|
+
| 1 | SwiftUI | 存在 `*.xcodeproj` 或 `Package.swift`,且项目中有 `*View.swift` | `stack-swiftui.md` |
|
|
14
|
+
| 2 | Flutter | 存在 `pubspec.yaml`,且 `lib/` 下有 `*.dart` | (暂无,手动配置) |
|
|
15
|
+
| 3 | Electron | `package.json` 含 `"electron"` 依赖,且存在 main/renderer 目录分离 | `stack-electron.md` |
|
|
16
|
+
| 4 | Next.js | 存在 `next.config.js` 或 `next.config.ts`,或 `package.json` 含 `"next"` | `stack-nextjs.md` |
|
|
17
|
+
| 5 | Nuxt | 存在 `nuxt.config.ts` / `nuxt.config.js`,或 `package.json` 含 `"nuxt"` | `stack-vue.md` |
|
|
18
|
+
| 6 | SvelteKit | 存在 `svelte.config.js`,或 `package.json` 含 `"@sveltejs/kit"` | (暂无,手动配置) |
|
|
19
|
+
| 7 | Vue | `package.json` 含 `"vue"`,且存在 `*.vue` 文件 | `stack-vue.md` |
|
|
20
|
+
| 8 | React | `package.json` 含 `"react"`,且存在 `*.tsx` 或 `*.jsx` 文件 | `stack-react.md` |
|
|
21
|
+
| 9 | Angular | 存在 `angular.json` | (暂无,手动配置) |
|
|
22
|
+
| — | 未知 | 以上均不匹配 | 手动配置 |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## "暂无 Reference" 的处理
|
|
27
|
+
|
|
28
|
+
若检测到的技术栈暂无对应 reference 文件,告知用户:
|
|
29
|
+
|
|
30
|
+
> "检测到技术栈 `<栈名>`,但暂无对应的自动配置预设。将引导您手动填写 platforms 配置。如您日后希望为此栈添加预设,可创建 `references/stack-<name>.md` 并参照已有文件的格式。"
|
|
31
|
+
|
|
32
|
+
然后手动引导用户填写:
|
|
33
|
+
- `uiFilePatterns`:询问"您的 UI 组件/视图文件在哪些目录?常用什么文件扩展名?"
|
|
34
|
+
- `designSystemFile`:询问"是否有集中定义颜色、字体等 token 的文件?"
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 新增栈的流程
|
|
39
|
+
|
|
40
|
+
当遇到本索引未覆盖的技术栈时:
|
|
41
|
+
1. 手动完成初始化
|
|
42
|
+
2. 在此索引表中添加一行(优先级参考相近的栈)
|
|
43
|
+
3. 创建 `references/stack-<name>.md`(参照已有格式)
|
|
44
|
+
|
|
45
|
+
这样下次遇到相同栈时就能自动处理。
|