autosnippet 3.0.3 → 3.0.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 +85 -240
- package/dashboard/dist/assets/{icons-Cdq22n2i.js → icons-eQ_rWCus.js} +97 -102
- package/dashboard/dist/assets/index-B3Nnkdxi.js +133 -0
- package/dashboard/dist/assets/index-BFNDAqh3.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/lib/core/AstAnalyzer.js +2 -2
- package/lib/core/ast/ensure-grammars.js +2 -0
- package/lib/core/ast/index.js +8 -0
- package/lib/core/ast/lang-rust.js +695 -0
- package/lib/core/discovery/PythonDiscoverer.js +3 -0
- package/lib/core/discovery/RustDiscoverer.js +467 -0
- package/lib/core/discovery/index.js +3 -0
- package/lib/core/enhancement/django-enhancement.js +169 -3
- package/lib/core/enhancement/fastapi-enhancement.js +149 -3
- package/lib/core/enhancement/go-grpc-enhancement.js +4 -0
- package/lib/core/enhancement/go-web-enhancement.js +6 -0
- package/lib/core/enhancement/index.js +5 -0
- package/lib/core/enhancement/langchain-enhancement.js +233 -0
- package/lib/core/enhancement/ml-enhancement.js +265 -0
- package/lib/core/enhancement/nextjs-enhancement.js +219 -0
- package/lib/core/enhancement/node-server-enhancement.js +178 -4
- package/lib/core/enhancement/react-enhancement.js +165 -4
- package/lib/core/enhancement/rust-tokio-enhancement.js +231 -0
- package/lib/core/enhancement/rust-web-enhancement.js +256 -0
- package/lib/core/enhancement/spring-enhancement.js +2 -0
- package/lib/core/enhancement/vue-enhancement.js +143 -2
- package/lib/external/ai/AiProvider.js +45 -6
- package/lib/external/mcp/handlers/bootstrap/skills.js +2 -0
- package/lib/external/mcp/handlers/bootstrap.js +33 -9
- package/lib/external/mcp/handlers/guard.js +42 -0
- package/lib/http/routes/candidates.js +7 -1
- package/lib/service/chat/ChatAgent.js +1 -0
- package/lib/service/chat/tools.js +5 -1
- package/lib/service/guard/ComplianceReporter.js +20 -7
- package/lib/service/guard/GuardCheckEngine.js +156 -5
- package/lib/service/guard/SourceFileCollector.js +15 -0
- package/package.json +28 -6
- package/skills/autosnippet-coldstart/SKILL.md +4 -2
- package/skills/autosnippet-concepts/SKILL.md +5 -3
- package/skills/autosnippet-reference-rust/SKILL.md +401 -0
- package/skills/autosnippet-structure/SKILL.md +1 -1
- package/templates/recipes-setup/README.md +2 -2
- package/templates/recipes-setup/_template.md +1 -1
- package/dashboard/dist/assets/index-ClkyPkDX.js +0 -133
- package/dashboard/dist/assets/index-t4QrJwv1.css +0 -1
|
@@ -48,7 +48,7 @@ description: Cold-start knowledge base initialization. Full 9-dimension analysis
|
|
|
48
48
|
| 字段 | 类型 | 说明 |
|
|
49
49
|
|------|------|------|
|
|
50
50
|
| `language` | string | 主语言名称 |
|
|
51
|
-
| `extraDimensions` | array | 语言特有的额外分析维度(如 Swift Concurrency、ObjC Block 模式、Go goroutine/channel、Python async/decorator、Java Stream/Optional、Dart Widget/BLoC/Riverpod 等) |
|
|
51
|
+
| `extraDimensions` | array | 语言特有的额外分析维度(如 Swift Concurrency、ObjC Block 模式、Go goroutine/channel、Python async/decorator、Java Stream/Optional、Dart Widget/BLoC/Riverpod、Rust ownership/borrowing/lifetime/trait 等) |
|
|
52
52
|
| `typicalPatterns` | array | 该语言中典型的代码模式提示 |
|
|
53
53
|
| `commonAntiPatterns` | array | 该语言常见反模式(bad/why/fix) |
|
|
54
54
|
| `suggestedGuardRules` | array | 建议的 Guard 规则(pattern/severity/message) |
|
|
@@ -224,7 +224,7 @@ description: Cold-start knowledge base initialization. Full 9-dimension analysis
|
|
|
224
224
|
{
|
|
225
225
|
"title": "[must] UI 更新必须在主线程",
|
|
226
226
|
"trigger": "@agent-threading",
|
|
227
|
-
"code": "// ✅ 正确 — 使用语言/框架提供的主线程机制\n// Swift: @MainActor func updateUI() { ... }\n// JS/TS: 无需显式处理(单线程)但 Web Worker 返回需 postMessage\n// Python: 使用 loop.call_soon_threadsafe() 或框架 API\n// Go: 使用 channel 或 sync 包\n// Java/Kotlin: runOnUiThread { ... } 或 Dispatchers.Main\n\n// ❌ 错误 — 在后台线程直接操作 UI",
|
|
227
|
+
"code": "// ✅ 正确 — 使用语言/框架提供的主线程机制\n// Swift: @MainActor func updateUI() { ... }\n// JS/TS: 无需显式处理(单线程)但 Web Worker 返回需 postMessage\n// Python: 使用 loop.call_soon_threadsafe() 或框架 API\n// Go: 使用 channel 或 sync 包\n// Java/Kotlin: runOnUiThread { ... } 或 Dispatchers.Main\n// Rust: 使用 tokio::spawn + channel 或 Arc<Mutex<T>> 跨线程共享\n// Dart: 使用 WidgetsBinding.instance.addPostFrameCallback 或 setState\n\n// ❌ 错误 — 在后台线程直接操作 UI",
|
|
228
228
|
"summary_cn": "UI 更新必须在主线程/主 Actor 执行,违反会导致崩溃或数据竞争",
|
|
229
229
|
"summary_en": "UI updates must run on the main thread/actor to prevent crashes and data races",
|
|
230
230
|
"language": "<primaryLanguage>",
|
|
@@ -939,6 +939,7 @@ description: Cold-start knowledge base initialization. Full 9-dimension analysis
|
|
|
939
939
|
> - **autosnippet-reference-kotlin** — Kotlin 专属:空安全/协程/Flow/sealed class/DSL/Compose
|
|
940
940
|
> - **autosnippet-reference-go** — Go 专属:错误处理/接口组合/goroutine/channel/Context/测试
|
|
941
941
|
> - **autosnippet-reference-dart** — Dart (Flutter) 专属:空安全/Widget 设计/状态管理(BLoC/Riverpod)/Freezed/Clean Architecture/测试
|
|
942
|
+
> - **autosnippet-reference-rust** — Rust 专属:所有权/借用/生命周期/trait 系统/错误处理(Result/Option/?)/async-await/unsafe/宏/Cargo 约定
|
|
942
943
|
|
|
943
944
|
---
|
|
944
945
|
|
|
@@ -982,3 +983,4 @@ description: Cold-start knowledge base initialization. Full 9-dimension analysis
|
|
|
982
983
|
- **autosnippet-reference-kotlin**: Kotlin 业界最佳实践参考(空安全/协程/Flow/sealed class/DSL/Compose)
|
|
983
984
|
- **autosnippet-reference-go**: Go 业界最佳实践参考(错误处理/接口组合/goroutine/channel/Context/测试)
|
|
984
985
|
- **autosnippet-reference-dart**: Dart (Flutter) 业界最佳实践参考(空安全/Widget 设计/BLoC/Riverpod/Freezed/Clean Architecture/测试)
|
|
986
|
+
- **autosnippet-reference-rust**: Rust 业界最佳实践参考(所有权/借用/生命周期/trait 系统/错误处理/async-await/unsafe/Cargo 约定)
|
|
@@ -129,8 +129,10 @@ This is a conceptual map. Skills stay semantic; MCP provides capability.
|
|
|
129
129
|
- Java: `["import java.util.List;"]`
|
|
130
130
|
- Kotlin: `["import kotlinx.coroutines.*"]`
|
|
131
131
|
- JS/TS: `["import fs from 'node:fs'"]`
|
|
132
|
+
- Dart: `["import 'package:flutter/material.dart'"]`
|
|
133
|
+
- Rust: `["use std::collections::HashMap;"]`
|
|
132
134
|
- **`trigger`**: MUST start with `@` (e.g. `@request-manager`). kebab-case, no spaces.
|
|
133
|
-
- **`language`**: MUST be one of the supported languages (lowercase): `swift`, `objectivec`, `go`, `python`, `java`, `kotlin`, `javascript`, `typescript`.
|
|
135
|
+
- **`language`**: MUST be one of the supported languages (lowercase): `swift`, `objectivec`, `go`, `python`, `java`, `kotlin`, `javascript`, `typescript`, `dart`, `rust`.
|
|
134
136
|
- **`kind`**: MUST be one of: `rule`, `pattern`, `fact`.
|
|
135
137
|
- **`doClause`**: English imperative sentence, ≤60 tokens.
|
|
136
138
|
- **`description`**: 中文摘要 ≤80字。
|
|
@@ -169,7 +171,7 @@ This is a conceptual map. Skills stay semantic; MCP provides capability.
|
|
|
169
171
|
| `title` | 标准用法的名称 | 人工命名 | **必填**;**中文**;简短精准(✅ "颜色工具方法"、"异步请求处理";❌ 避免 "Use xxx");≤20 字 |
|
|
170
172
|
| `trigger` | 触发词(Snippet/检索) | 人工命名 | **必填**;`@` 开头,kebab-case、无空格;唯一 |
|
|
171
173
|
| `category` | 8 类标准分类 | 人工判断 | **必填**;必须为 8 类之一 |
|
|
172
|
-
| `language` | 代码语言 | 从代码确定 | **必填**;支持 `swift` / `objectivec` / `go` / `python` / `java` / `kotlin` / `javascript` / `typescript` |
|
|
174
|
+
| `language` | 代码语言 | 从代码确定 | **必填**;支持 `swift` / `objectivec` / `go` / `python` / `java` / `kotlin` / `javascript` / `typescript` / `dart` / `rust` |
|
|
173
175
|
| `kind` | 知识类型 | 人工/AI | **必填**;`rule` / `pattern` / `fact` |
|
|
174
176
|
| `doClause` | 英文祈使句指令 | AI/人工 | **必填**;≤60 tokens |
|
|
175
177
|
| `description` | 中文功能摘要 | 人工/AI | **必填**;≤80字 |
|
|
@@ -263,7 +265,7 @@ This is a conceptual map. Skills stay semantic; MCP provides capability.
|
|
|
263
265
|
- [ ] **doClause**: 英文祈使句(≠60 tokens)
|
|
264
266
|
- [ ] **description**: 中文摘要 ≤80字
|
|
265
267
|
- [ ] **category**: ONE of View/Service/Tool/Model/Network/Storage/UI/Utility
|
|
266
|
-
- [ ] **language**: `swift`/`objectivec`/`go`/`python`/`java`/`kotlin`/`javascript`/`typescript`
|
|
268
|
+
- [ ] **language**: `swift`/`objectivec`/`go`/`python`/`java`/`kotlin`/`javascript`/`typescript`/`dart`/`rust`
|
|
267
269
|
- [ ] **headers**: 完整 import 语句数组(无 import 传 `[]`)
|
|
268
270
|
- [ ] **usageGuide**: Markdown `###` 章节格式
|
|
269
271
|
- [ ] **knowledgeType**: `code-pattern` / `architecture` / `best-practice` 等
|
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
```skill
|
|
2
|
+
---
|
|
3
|
+
name: autosnippet-reference-rust
|
|
4
|
+
description: Rust 业界最佳实践参考。涵盖所有权与借用、生命周期、trait 系统、错误处理(Result/Option/?)、async/await、unsafe、宏、测试、Cargo 约定,为冷启动分析提供高质量参考标准。
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Rust 最佳实践参考 (Industry Reference)
|
|
8
|
+
|
|
9
|
+
> 本 Skill 为 **autosnippet-coldstart** 的 Companion Skill。在冷启动分析 Rust 项目时,请参考以下业界标准产出高质量候选。
|
|
10
|
+
> **来源**: The Rust Book, Rust API Guidelines, Clippy Lints, Rust Design Patterns (unofficial), Rust RFC, Tokio Best Practices
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. 项目结构与 Cargo 约定
|
|
15
|
+
|
|
16
|
+
### 核心规则
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"title": "Rust: Cargo 项目结构与模块组织",
|
|
21
|
+
"content": {
|
|
22
|
+
"markdown": "## Rust: Cargo 项目结构与模块组织\n\n### 标准模式\n```rust\n// ✅ 标准 Cargo 项目布局\nmyproject/\n├── Cargo.toml // 包元数据 + 依赖\n├── Cargo.lock // 锁定依赖版本 (bin crate 必须提交)\n├── src/\n│ ├── main.rs // 二进制入口 (bin crate)\n│ ├── lib.rs // 库入口 (lib crate)\n│ ├── config.rs // 模块文件\n│ └── handlers/\n│ ├── mod.rs // 子模块声明 (传统方式)\n│ └── user.rs\n├── tests/ // 集成测试 (每个文件为独立 crate)\n│ └── integration_test.rs\n├── benches/ // 基准测试\n│ └── benchmark.rs\n├── examples/ // 示例代码\n│ └── demo.rs\n└── build.rs // 构建脚本 (可选)\n\n// ✅ Cargo workspace (多 crate 项目)\n[workspace]\nmembers = [\n \"crates/core\",\n \"crates/api\",\n \"crates/cli\",\n]\n\n// ✅ 模块声明\n// src/lib.rs\npub mod config;\npub mod handlers;\nmod internal; // 私有模块\n\n// ❌ 不要在 lib crate 提交 Cargo.lock\n// ❌ 不要创建过深的模块层级 (>4 层需考虑拆 crate)\n```",
|
|
23
|
+
"pattern": "src/main.rs src/lib.rs tests/ benches/ examples/ Cargo.toml",
|
|
24
|
+
"rationale": "Cargo 约定布局提供零配置的构建体验,workspace 支持大型项目的 crate 拆分"
|
|
25
|
+
},
|
|
26
|
+
"description": "Rust: Cargo 项目结构与模块组织",
|
|
27
|
+
"kind": "fact",
|
|
28
|
+
"doClause": "Apply the Rust pattern as described",
|
|
29
|
+
"language": "rust",
|
|
30
|
+
"headers": [],
|
|
31
|
+
"category": "Tool",
|
|
32
|
+
"knowledgeType": "architecture",
|
|
33
|
+
"scope": "universal",
|
|
34
|
+
"antiPattern": {
|
|
35
|
+
"bad": "单个 crate 超过 10000 行无模块拆分",
|
|
36
|
+
"why": "编译时间线性增长,代码内聚性下降",
|
|
37
|
+
"fix": "按领域拆分为 workspace 多 crate: core, api, cli"
|
|
38
|
+
},
|
|
39
|
+
"reasoning": {
|
|
40
|
+
"whyStandard": "Cargo Book - Package Layout; Rust API Guidelines",
|
|
41
|
+
"sources": ["The Cargo Book", "Rust API Guidelines"],
|
|
42
|
+
"confidence": 0.95
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### 项目结构原则
|
|
48
|
+
|
|
49
|
+
| 原则 | 说明 | 示例 |
|
|
50
|
+
|------|------|------|
|
|
51
|
+
| 按功能拆 crate | 一个 crate 解决一个领域 | `core/`, `api/`, `cli/` |
|
|
52
|
+
| lib + bin 分离 | 逻辑在 lib.rs,入口在 main.rs | `main.rs` 仅调用 `lib.rs` |
|
|
53
|
+
| workspace 共享依赖 | 减少重复编译 | `[workspace.dependencies]` |
|
|
54
|
+
| 模块文件 vs 目录 | 简单用 `foo.rs`,复杂用 `foo/mod.rs` | Rust 2018 edition 推荐前者 |
|
|
55
|
+
| features 管理可选功能 | 编译期条件编译 | `#[cfg(feature = "serde")]` |
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 2. 所有权与借用
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"title": "Rust: 所有权、借用与生命周期规范",
|
|
64
|
+
"content": {
|
|
65
|
+
"markdown": "## Rust: 所有权、借用与生命周期\n\n### 标准模式\n```rust\n// ✅ 优先借用而非获取所有权\nfn process(data: &[u8]) -> Result<Output, Error> { ... }\nfn display(name: &str) { ... } // &str 而非 String\n\n// ✅ 需要修改时使用可变借用\nfn update(config: &mut Config) { ... }\n\n// ✅ 需要所有权时使用 move\nfn spawn_task(data: Vec<u8>) {\n tokio::spawn(async move {\n process(&data).await;\n });\n}\n\n// ✅ Clone: 仅在语义上确实需要独立副本时\nlet backup = config.clone();\n\n// ✅ Cow 用于可能不需要克隆的场景\nuse std::borrow::Cow;\nfn normalize(input: &str) -> Cow<'_, str> {\n if input.contains(' ') {\n Cow::Owned(input.replace(' ', '_'))\n } else {\n Cow::Borrowed(input)\n }\n}\n\n// ✅ 生命周期: 仅在编译器无法推断时显式标注\nfn longest<'a>(x: &'a str, y: &'a str) -> &'a str {\n if x.len() > y.len() { x } else { y }\n}\n\n// ❌ 不要过度 clone() 来\"解决\"借用检查\n// ❌ 不要用 Rc/Arc 替代合理的生命周期设计\n// ❌ 不要为了方便而到处使用 'static\n```",
|
|
66
|
+
"rationale": "所有权系统是 Rust 的核心创新,正确使用可消除数据竞争和内存安全问题"
|
|
67
|
+
},
|
|
68
|
+
"description": "Rust: 所有权、借用与生命周期规范",
|
|
69
|
+
"kind": "rule",
|
|
70
|
+
"doClause": "Apply the Rust pattern as described",
|
|
71
|
+
"language": "rust",
|
|
72
|
+
"headers": [],
|
|
73
|
+
"knowledgeType": "code-standard",
|
|
74
|
+
"antiPattern": {
|
|
75
|
+
"bad": "data.clone() // 到处 clone 绕过借用检查",
|
|
76
|
+
"why": "掩盖了设计问题,增加不必要的内存分配",
|
|
77
|
+
"fix": "重新设计数据流,使用借用或 Cow 减少克隆"
|
|
78
|
+
},
|
|
79
|
+
"reasoning": {
|
|
80
|
+
"whyStandard": "The Rust Book Ch.4 - Understanding Ownership",
|
|
81
|
+
"sources": ["The Rust Book", "Rust Nomicon"],
|
|
82
|
+
"confidence": 0.95
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 所有权决策表
|
|
88
|
+
|
|
89
|
+
| 场景 | 推荐方式 | 说明 |
|
|
90
|
+
|------|---------|------|
|
|
91
|
+
| 只读访问 | `&T` | 不可变借用 |
|
|
92
|
+
| 需要修改 | `&mut T` | 可变借用 |
|
|
93
|
+
| 转移所有权 | `T` (by value) | 函数需要拥有数据 |
|
|
94
|
+
| 可能需要克隆 | `Cow<'_, T>` | 延迟到实际需要时 |
|
|
95
|
+
| 共享所有权 | `Arc<T>` | 跨线程共享 |
|
|
96
|
+
| 内部可变性 | `RefCell<T>` / `Mutex<T>` | 运行时借用检查 |
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 3. 错误处理
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
{
|
|
104
|
+
"title": "Rust: 错误处理最佳实践 (Result/Option/?)",
|
|
105
|
+
"content": {
|
|
106
|
+
"markdown": "## Rust: 错误处理最佳实践\n\n### 标准模式\n```rust\n// ✅ 定义领域错误枚举\n#[derive(Debug, thiserror::Error)]\npub enum AppError {\n #[error(\"database error: {0}\")]\n Database(#[from] sqlx::Error),\n #[error(\"not found: {entity} with id {id}\")]\n NotFound { entity: &'static str, id: String },\n #[error(\"validation failed: {0}\")]\n Validation(String),\n}\n\n// ✅ 使用 ? 操作符传播错误\npub fn load_config(path: &Path) -> Result<Config, AppError> {\n let content = std::fs::read_to_string(path)?;\n let config: Config = serde_json::from_str(&content)?;\n Ok(config)\n}\n\n// ✅ 对于 main/顶层使用 anyhow::Result\nfn main() -> anyhow::Result<()> {\n let config = load_config(Path::new(\"config.toml\"))?;\n run_server(config).await?;\n Ok(())\n}\n\n// ✅ Option 用于可选值,不用于错误\nfn find_user(id: u64) -> Option<User> { ... }\n\n// ✅ 组合子链式处理\nlet name = user\n .as_ref()\n .map(|u| u.name.as_str())\n .unwrap_or(\"anonymous\");\n\n// ❌ 避免 unwrap() 在生产代码中\n// ❌ 不要用 panic! 处理预期错误\n// ❌ 不要返回 Box<dyn Error> (库代码应用具体类型)\n```",
|
|
107
|
+
"rationale": "Rust 通过类型系统强制错误处理,消除了未处理异常的风险"
|
|
108
|
+
},
|
|
109
|
+
"description": "Rust: 错误处理最佳实践",
|
|
110
|
+
"kind": "rule",
|
|
111
|
+
"doClause": "Apply the Rust pattern as described",
|
|
112
|
+
"language": "rust",
|
|
113
|
+
"headers": [],
|
|
114
|
+
"knowledgeType": "code-standard",
|
|
115
|
+
"antiPattern": {
|
|
116
|
+
"bad": "value.unwrap() // 生产代码中直接 unwrap",
|
|
117
|
+
"why": "None/Err 时 panic,导致程序崩溃",
|
|
118
|
+
"fix": "使用 ? 传播、unwrap_or_default()、expect(\"明确原因\") 或 match"
|
|
119
|
+
},
|
|
120
|
+
"reasoning": {
|
|
121
|
+
"whyStandard": "The Rust Book Ch.9 - Error Handling; thiserror/anyhow 是社区标准",
|
|
122
|
+
"sources": ["The Rust Book", "thiserror crate", "anyhow crate"],
|
|
123
|
+
"confidence": 0.95
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 错误处理策略
|
|
129
|
+
|
|
130
|
+
| 场景 | 工具 | 说明 |
|
|
131
|
+
|------|------|------|
|
|
132
|
+
| 库代码 | `thiserror` | 定义具体错误枚举 |
|
|
133
|
+
| 应用代码 | `anyhow` | 灵活的动态错误类型 |
|
|
134
|
+
| 错误传播 | `?` 操作符 | 自动 From 转换 + 提前返回 |
|
|
135
|
+
| 可选值 | `Option<T>` | `None` 不是错误 |
|
|
136
|
+
| 不可恢复 | `panic!` | 仅用于程序 bug / 不变量违反 |
|
|
137
|
+
| 上下文添加 | `.context("msg")?` | anyhow 上下文链 |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 4. Trait 系统与泛型
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"title": "Rust: Trait 与泛型最佳实践",
|
|
146
|
+
"content": {
|
|
147
|
+
"markdown": "## Rust: Trait 与泛型\n\n### 标准模式\n```rust\n// ✅ trait 定义行为契约\npub trait Repository {\n type Error;\n fn find_by_id(&self, id: &str) -> Result<Option<Entity>, Self::Error>;\n fn save(&self, entity: &Entity) -> Result<(), Self::Error>;\n}\n\n// ✅ 泛型函数约束用 trait bounds\npub fn process<T: Serialize + Debug>(item: &T) -> Result<String, Error> { ... }\n\n// ✅ 复杂 bounds 用 where 子句\npub fn merge<I, T>(iter: I) -> Vec<T>\nwhere\n I: IntoIterator<Item = T>,\n T: Ord + Clone,\n{ ... }\n\n// ✅ impl Trait 用于返回类型 (隐藏具体类型)\npub fn create_handler() -> impl Handler { ... }\n\n// ✅ 常用 derive 宏\n#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]\npub struct UserId(String);\n\n// ✅ 为自定义类型实现标准 trait\nimpl Display for AppError {\n fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { ... }\n}\n\n// ❌ 不要过度泛型化 — 具体类型足够时不用泛型\n// ❌ 不要在热路径使用 dyn Trait (有虚表开销)\n```",
|
|
148
|
+
"rationale": "Trait 是 Rust 的多态核心,零成本抽象通过单态化实现"
|
|
149
|
+
},
|
|
150
|
+
"description": "Rust: Trait 与泛型最佳实践",
|
|
151
|
+
"kind": "rule",
|
|
152
|
+
"doClause": "Apply the Rust pattern as described",
|
|
153
|
+
"language": "rust",
|
|
154
|
+
"headers": [],
|
|
155
|
+
"knowledgeType": "code-standard",
|
|
156
|
+
"antiPattern": {
|
|
157
|
+
"bad": "fn process(item: &dyn Any)",
|
|
158
|
+
"why": "丢失类型信息,需要运行时向下转型",
|
|
159
|
+
"fix": "使用泛型 fn process<T: MyTrait>(item: &T) 保持静态分发"
|
|
160
|
+
},
|
|
161
|
+
"reasoning": {
|
|
162
|
+
"whyStandard": "The Rust Book Ch.10 - Generic Types, Traits",
|
|
163
|
+
"sources": ["The Rust Book", "Rust API Guidelines"],
|
|
164
|
+
"confidence": 0.9
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 5. 异步编程 (async/await)
|
|
172
|
+
|
|
173
|
+
```json
|
|
174
|
+
{
|
|
175
|
+
"title": "Rust: 异步编程最佳实践 (tokio/async)",
|
|
176
|
+
"content": {
|
|
177
|
+
"markdown": "## Rust: 异步编程 (tokio)\n\n### 标准模式\n```rust\n// ✅ tokio 运行时入口\n#[tokio::main]\nasync fn main() -> anyhow::Result<()> {\n let listener = TcpListener::bind(\"0.0.0.0:8080\").await?;\n // ...\n Ok(())\n}\n\n// ✅ async fn 返回 Future\nasync fn fetch_data(url: &str) -> Result<Response, reqwest::Error> {\n reqwest::get(url).await?.json().await\n}\n\n// ✅ 并发执行多个 Future\nlet (users, orders) = tokio::try_join!(\n fetch_users(),\n fetch_orders(),\n)?;\n\n// ✅ spawn 独立任务\ntokio::spawn(async move {\n if let Err(e) = background_job(data).await {\n tracing::error!(\"background job failed: {e}\");\n }\n});\n\n// ✅ 使用 select! 竞争\ntokio::select! {\n result = operation() => handle(result),\n _ = tokio::time::sleep(Duration::from_secs(5)) => {\n return Err(TimeoutError);\n }\n}\n\n// ❌ 不要在 async 中调用阻塞 API (用 spawn_blocking)\n// ❌ 不要持有 MutexGuard 跨 await 点\n// ❌ 不要在 async fn 中使用 std::sync::Mutex (用 tokio::sync::Mutex)\n```",
|
|
178
|
+
"rationale": "Rust async 是零成本抽象,编译为状态机,tokio 是事实标准运行时"
|
|
179
|
+
},
|
|
180
|
+
"description": "Rust: 异步编程最佳实践",
|
|
181
|
+
"kind": "rule",
|
|
182
|
+
"doClause": "Apply the Rust pattern as described",
|
|
183
|
+
"language": "rust",
|
|
184
|
+
"headers": [],
|
|
185
|
+
"knowledgeType": "code-standard",
|
|
186
|
+
"antiPattern": {
|
|
187
|
+
"bad": "let guard = mutex.lock().unwrap();\nsome_async_fn().await; // 持有锁跨 await",
|
|
188
|
+
"why": "std::sync::MutexGuard 不是 Send,且跨 await 点持有锁会阻塞",
|
|
189
|
+
"fix": "限制锁的作用域,或使用 tokio::sync::Mutex"
|
|
190
|
+
},
|
|
191
|
+
"reasoning": {
|
|
192
|
+
"whyStandard": "Tokio Tutorial; Async Book",
|
|
193
|
+
"sources": ["Tokio Documentation", "The Async Book"],
|
|
194
|
+
"confidence": 0.9
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## 6. Unsafe 使用规范
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"title": "Rust: unsafe 使用规范",
|
|
206
|
+
"content": {
|
|
207
|
+
"markdown": "## Rust: unsafe\n\n### 标准模式\n```rust\n// ✅ unsafe 块应尽可能小,并加安全注释\n/// # Safety\n/// `ptr` must be a valid, aligned pointer to an initialized `T`.\nunsafe fn deref_raw<T>(ptr: *const T) -> &T {\n // SAFETY: caller guarantees ptr is valid and aligned\n &*ptr\n}\n\n// ✅ 封装 unsafe 为安全 API\npub fn get_unchecked(slice: &[u8], index: usize) -> Option<u8> {\n if index < slice.len() {\n // SAFETY: index is bounds-checked above\n Some(unsafe { *slice.get_unchecked(index) })\n } else {\n None\n }\n}\n\n// ✅ FFI unsafe 隔离在专用模块\nmod ffi {\n extern \"C\" {\n fn external_fn(ptr: *const u8, len: usize) -> i32;\n }\n pub fn safe_wrapper(data: &[u8]) -> i32 {\n // SAFETY: passing valid slice pointer and length\n unsafe { external_fn(data.as_ptr(), data.len()) }\n }\n}\n\n// ❌ 不要在应用代码中随意使用 unsafe\n// ❌ 不要省略 SAFETY 注释\n// ❌ 不要用 unsafe 绕过借用检查器\n```",
|
|
208
|
+
"rationale": "unsafe 是 Rust 安全系统的逃生舱口,必须谨慎使用并充分文档化"
|
|
209
|
+
},
|
|
210
|
+
"description": "Rust: unsafe 使用规范",
|
|
211
|
+
"kind": "rule",
|
|
212
|
+
"doClause": "Apply the Rust pattern as described",
|
|
213
|
+
"language": "rust",
|
|
214
|
+
"headers": [],
|
|
215
|
+
"knowledgeType": "code-standard",
|
|
216
|
+
"antiPattern": {
|
|
217
|
+
"bad": "unsafe { ... } // 无 SAFETY 注释的大块 unsafe",
|
|
218
|
+
"why": "无法审计安全性,违反 Rust 的安全契约",
|
|
219
|
+
"fix": "缩小 unsafe 范围,每个 unsafe 块添加 SAFETY 注释说明前置条件"
|
|
220
|
+
},
|
|
221
|
+
"reasoning": {
|
|
222
|
+
"whyStandard": "The Rustonomicon; Rust API Guidelines - Unsafe",
|
|
223
|
+
"sources": ["The Rustonomicon", "Rust API Guidelines"],
|
|
224
|
+
"confidence": 0.95
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 7. 结构体设计与构建器
|
|
232
|
+
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"title": "Rust: 结构体设计模式 (Builder / Newtype / Default)",
|
|
236
|
+
"content": {
|
|
237
|
+
"markdown": "## Rust: 结构体设计模式\n\n### 标准模式\n```rust\n// ✅ Builder 模式 — 多个可选参数\n#[derive(Debug)]\npub struct ServerConfig {\n host: String,\n port: u16,\n max_connections: usize,\n tls: bool,\n}\n\nimpl ServerConfig {\n pub fn builder() -> ServerConfigBuilder {\n ServerConfigBuilder::default()\n }\n}\n\n#[derive(Default)]\npub struct ServerConfigBuilder {\n host: Option<String>,\n port: Option<u16>,\n max_connections: Option<usize>,\n tls: bool,\n}\n\nimpl ServerConfigBuilder {\n pub fn host(mut self, host: impl Into<String>) -> Self {\n self.host = Some(host.into()); self\n }\n pub fn port(mut self, port: u16) -> Self {\n self.port = Some(port); self\n }\n pub fn build(self) -> Result<ServerConfig, ConfigError> {\n Ok(ServerConfig {\n host: self.host.unwrap_or_else(|| \"localhost\".to_string()),\n port: self.port.unwrap_or(8080),\n max_connections: self.max_connections.unwrap_or(100),\n tls: self.tls,\n })\n }\n}\n\n// ✅ Newtype 模式 — 类型安全包装\npub struct UserId(pub u64);\npub struct Email(String);\n\nimpl Email {\n pub fn new(value: impl Into<String>) -> Result<Self, ValidationError> {\n let s = value.into();\n if s.contains('@') { Ok(Self(s)) } else { Err(ValidationError::InvalidEmail) }\n }\n}\n\n// ✅ Default trait\nimpl Default for Config {\n fn default() -> Self {\n Self { timeout: Duration::from_secs(30), retries: 3 }\n }\n}\n\n// ✅ new() 构造函数约定\nimpl UserService {\n pub fn new(repo: Arc<dyn UserRepository>) -> Self {\n Self { repo }\n }\n}\n```",
|
|
238
|
+
"rationale": "Builder 解决多参数构造,Newtype 提供类型安全,Default 提供零值语义"
|
|
239
|
+
},
|
|
240
|
+
"description": "Rust: 结构体设计模式",
|
|
241
|
+
"kind": "fact",
|
|
242
|
+
"doClause": "Apply the Rust pattern as described",
|
|
243
|
+
"language": "rust",
|
|
244
|
+
"headers": [],
|
|
245
|
+
"knowledgeType": "architecture",
|
|
246
|
+
"antiPattern": {
|
|
247
|
+
"bad": "pub fn new(a: &str, b: &str, c: u16, d: bool, e: usize) -> Self",
|
|
248
|
+
"why": "5+ 参数构造函数可读性和可维护性差",
|
|
249
|
+
"fix": "使用 Builder 模式或参数结构体"
|
|
250
|
+
},
|
|
251
|
+
"reasoning": {
|
|
252
|
+
"whyStandard": "Rust Design Patterns - Builder; Rust API Guidelines - C-BUILDER",
|
|
253
|
+
"sources": ["Rust Design Patterns", "Rust API Guidelines"],
|
|
254
|
+
"confidence": 0.9
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 8. 测试规范
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"title": "Rust: 测试最佳实践",
|
|
266
|
+
"content": {
|
|
267
|
+
"markdown": "## Rust: 测试最佳实践\n\n### 标准模式\n```rust\n// ✅ 单元测试 — 放在同一文件底部的 tests 模块\n#[cfg(test)]\nmod tests {\n use super::*;\n\n #[test]\n fn test_parse_valid_input() {\n let result = parse(\"hello\").unwrap();\n assert_eq!(result, Expected { name: \"hello\" });\n }\n\n #[test]\n #[should_panic(expected = \"empty input\")]\n fn test_parse_empty_panics() {\n parse(\"\").unwrap();\n }\n\n #[test]\n fn test_error_case() {\n let err = parse(\"invalid\").unwrap_err();\n assert!(matches!(err, ParseError::Invalid { .. }));\n }\n}\n\n// ✅ 集成测试 — tests/ 目录,每个文件独立 crate\n// tests/api_test.rs\nuse myproject::api;\n\n#[tokio::test]\nasync fn test_create_user() {\n let app = setup_test_app().await;\n let resp = app.post(\"/users\").json(&new_user).send().await;\n assert_eq!(resp.status(), StatusCode::CREATED);\n}\n\n// ✅ 测试 fixtures & helpers\n// tests/common/mod.rs\npub fn setup_test_db() -> TestDb { ... }\n\n// ✅ proptest / quickcheck 基于属性的测试\nproptest! {\n #[test]\n fn roundtrip_serialize(val: MyStruct) {\n let encoded = serde_json::to_string(&val)?;\n let decoded: MyStruct = serde_json::from_str(&encoded)?;\n prop_assert_eq!(val, decoded);\n }\n}\n\n// ❌ 不要忽略失败的测试 (#[ignore] 应有注释说明)\n// ❌ 不要用全局状态 — 测试可能并行执行\n```",
|
|
268
|
+
"rationale": "Rust 内建测试框架零配置,同文件单元测试是社区标准做法"
|
|
269
|
+
},
|
|
270
|
+
"description": "Rust: 测试最佳实践",
|
|
271
|
+
"kind": "rule",
|
|
272
|
+
"doClause": "Apply the Rust pattern as described",
|
|
273
|
+
"language": "rust",
|
|
274
|
+
"headers": [],
|
|
275
|
+
"knowledgeType": "code-standard",
|
|
276
|
+
"antiPattern": {
|
|
277
|
+
"bad": "#[ignore] fn test_broken() { ... } // 无注释的 ignore",
|
|
278
|
+
"why": "被忽略的测试会被遗忘,技术债积累",
|
|
279
|
+
"fix": "添加注释说明原因和修复计划,或真正修复测试"
|
|
280
|
+
},
|
|
281
|
+
"reasoning": {
|
|
282
|
+
"whyStandard": "The Rust Book Ch.11 - Writing Automated Tests",
|
|
283
|
+
"sources": ["The Rust Book", "Rust Testing Guide"],
|
|
284
|
+
"confidence": 0.9
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 9. 命名约定
|
|
292
|
+
|
|
293
|
+
```json
|
|
294
|
+
{
|
|
295
|
+
"title": "Rust: 命名约定 (RFC 430)",
|
|
296
|
+
"content": {
|
|
297
|
+
"markdown": "## Rust: 命名约定\n\n### 标准模式\n```rust\n// ✅ 类型 & Trait: UpperCamelCase\nstruct HttpClient { ... }\ntrait IntoIterator { ... }\nenum ParseError { ... }\n\n// ✅ 函数 & 方法 & 变量: snake_case\nfn parse_config(path: &Path) -> Result<Config> { ... }\nlet user_name = \"alice\";\n\n// ✅ 常量 & 静态变量: SCREAMING_SNAKE_CASE\nconst MAX_RETRIES: u32 = 3;\nstatic GLOBAL_CONFIG: OnceLock<Config> = OnceLock::new();\n\n// ✅ 模块 & crate: snake_case\nmod http_client;\n// Cargo.toml: name = \"my-crate\" (kebab-case)\n// use: use my_crate::... (自动转 snake_case)\n\n// ✅ 生命周期: 短小的小写字母\nfn parse<'a>(input: &'a str) -> &'a str { ... }\n\n// ✅ 类型参数: 单大写字母或描述性名称\nfn process<T: Send>(item: T) { ... }\nfn query<Conn: DatabaseConnection>(conn: &Conn) { ... }\n\n// ✅ 转换方法命名约定\nimpl Foo {\n fn as_bar(&self) -> &Bar { ... } // 廉价引用转换\n fn to_bar(&self) -> Bar { ... } // 可能有开销的转换\n fn into_bar(self) -> Bar { ... } // 消费 self 的转换\n}\n\n// ❌ 不要用 camelCase 命名函数\n// ❌ 不要用匈牙利命名法\n```",
|
|
298
|
+
"rationale": "RFC 430 规定了 Rust 的命名约定,Clippy 会自动检查命名风格"
|
|
299
|
+
},
|
|
300
|
+
"description": "Rust: 命名约定",
|
|
301
|
+
"kind": "rule",
|
|
302
|
+
"doClause": "Apply the Rust pattern as described",
|
|
303
|
+
"language": "rust",
|
|
304
|
+
"headers": [],
|
|
305
|
+
"knowledgeType": "code-standard",
|
|
306
|
+
"antiPattern": {
|
|
307
|
+
"bad": "fn parseConfig() { ... } // camelCase 函数名",
|
|
308
|
+
"why": "违反 Rust 命名约定 (RFC 430),Clippy 会发出警告",
|
|
309
|
+
"fix": "fn parse_config() { ... } // snake_case"
|
|
310
|
+
},
|
|
311
|
+
"reasoning": {
|
|
312
|
+
"whyStandard": "RFC 430 - Naming Conventions; Rust API Guidelines",
|
|
313
|
+
"sources": ["RFC 430", "Rust API Guidelines"],
|
|
314
|
+
"confidence": 0.95
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### 转换方法命名速查
|
|
320
|
+
|
|
321
|
+
| 前缀 | 所有权 | 开销 | 示例 |
|
|
322
|
+
|------|--------|------|------|
|
|
323
|
+
| `as_` | 借用 → 借用 | 零成本 | `as_str()`, `as_bytes()` |
|
|
324
|
+
| `to_` | 借用 → 拥有 | 可能分配 | `to_string()`, `to_vec()` |
|
|
325
|
+
| `into_` | 拥有 → 拥有 | 消费 self | `into_inner()`, `into_vec()` |
|
|
326
|
+
| `from_` | 静态构造 | 变化 | `from_str()`, `from_utf8()` |
|
|
327
|
+
| `try_` | 可能失败 | 返回 Result | `try_from()`, `try_into()` |
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 10. 性能与惯用法
|
|
332
|
+
|
|
333
|
+
```json
|
|
334
|
+
{
|
|
335
|
+
"title": "Rust: 性能与惯用法",
|
|
336
|
+
"content": {
|
|
337
|
+
"markdown": "## Rust: 性能与惯用法\n\n### 标准模式\n```rust\n// ✅ 迭代器链 (零成本抽象)\nlet sum: u64 = items.iter()\n .filter(|x| x.is_valid())\n .map(|x| x.value())\n .sum();\n\n// ✅ 使用 collect 进行类型驱动的转换\nlet names: Vec<String> = users.iter().map(|u| u.name.clone()).collect();\nlet lookup: HashMap<&str, &User> = users.iter().map(|u| (u.id.as_str(), u)).collect();\n\n// ✅ 预分配容量\nlet mut results = Vec::with_capacity(items.len());\n\n// ✅ 使用 &str 而非 String 作为函数参数\nfn greet(name: &str) { println!(\"Hello, {name}\"); }\n\n// ✅ 使用 impl Into<String> 接受多种输入类型\nfn set_name(&mut self, name: impl Into<String>) {\n self.name = name.into();\n}\n\n// ✅ match 穷举 + 编译器保证\nmatch status {\n Status::Active => handle_active(),\n Status::Inactive => handle_inactive(),\n // 新增变体时编译器会报错\n}\n\n// ✅ 使用 clippy 全套 lint\n#![warn(clippy::all, clippy::pedantic)]\n\n// ❌ 不要手动循环能用迭代器解决的问题\n// ❌ 不要忽略 clippy 警告\n```",
|
|
338
|
+
"rationale": "Rust 迭代器是零成本抽象,编译后与手写循环性能相当"
|
|
339
|
+
},
|
|
340
|
+
"description": "Rust: 性能与惯用法",
|
|
341
|
+
"kind": "rule",
|
|
342
|
+
"doClause": "Apply the Rust pattern as described",
|
|
343
|
+
"language": "rust",
|
|
344
|
+
"headers": [],
|
|
345
|
+
"knowledgeType": "code-standard",
|
|
346
|
+
"antiPattern": {
|
|
347
|
+
"bad": "let mut result = Vec::new(); for item in &items { if item.valid { result.push(item.val); } }",
|
|
348
|
+
"why": "手动循环不如迭代器链表达力强,且可能遗漏预分配",
|
|
349
|
+
"fix": "items.iter().filter(|i| i.valid).map(|i| i.val).collect()"
|
|
350
|
+
},
|
|
351
|
+
"reasoning": {
|
|
352
|
+
"whyStandard": "The Rust Book Ch.13 - Iterators; Clippy documentation",
|
|
353
|
+
"sources": ["The Rust Book", "Clippy Lints"],
|
|
354
|
+
"confidence": 0.9
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## 11. 宏使用规范
|
|
362
|
+
|
|
363
|
+
### 宏选择策略
|
|
364
|
+
|
|
365
|
+
| 场景 | 推荐方式 | 说明 |
|
|
366
|
+
|------|---------|------|
|
|
367
|
+
| 派生标准 trait | `#[derive(...)]` | 零成本,编译期生成 |
|
|
368
|
+
| 减少样板代码 | 声明宏 `macro_rules!` | 简单模式匹配 |
|
|
369
|
+
| 需要类型检查 | 过程宏 `proc_macro` | 复杂但强大 |
|
|
370
|
+
| 属性注解 | `#[attribute]` | 如 `#[tokio::main]`, `#[test]` |
|
|
371
|
+
| 编译期断言 | `static_assert!` | 类型/大小检查 |
|
|
372
|
+
|
|
373
|
+
### 常用 derive 宏清单
|
|
374
|
+
|
|
375
|
+
```text
|
|
376
|
+
调试: Debug
|
|
377
|
+
拷贝: Clone, Copy
|
|
378
|
+
比较: PartialEq, Eq, PartialOrd, Ord
|
|
379
|
+
哈希: Hash
|
|
380
|
+
默认值: Default
|
|
381
|
+
序列化: Serialize, Deserialize (serde)
|
|
382
|
+
错误类型: Error (thiserror)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## 12. 并发与同步原语
|
|
388
|
+
|
|
389
|
+
### 选择指南
|
|
390
|
+
|
|
391
|
+
| 场景 | 推荐 | 说明 |
|
|
392
|
+
|------|------|------|
|
|
393
|
+
| 跨线程共享不可变数据 | `Arc<T>` | 引用计数 |
|
|
394
|
+
| 跨线程共享可变数据 | `Arc<Mutex<T>>` | 互斥锁 |
|
|
395
|
+
| 读多写少 | `Arc<RwLock<T>>` | 读写锁 |
|
|
396
|
+
| 单次初始化 | `OnceLock<T>` / `LazyLock<T>` | std 1.80+ |
|
|
397
|
+
| 消息传递 | `mpsc::channel` | 多生产者单消费者 |
|
|
398
|
+
| async 消息传递 | `tokio::sync::mpsc` | 异步通道 |
|
|
399
|
+
| 原子操作 | `AtomicBool` / `AtomicUsize` | 无锁 |
|
|
400
|
+
|
|
401
|
+
```
|
|
@@ -66,7 +66,7 @@ The knowledge graph captures **relationships between Recipes** (dependencies, ex
|
|
|
66
66
|
The SPM dependency structure is stored in `AutoSnippet/AutoSnippet.spmmap.json`:
|
|
67
67
|
- **`graph.packages`**: Package declarations with targets
|
|
68
68
|
- **`graph.edges`**: "from depends on to" relationships
|
|
69
|
-
- **Update**: Run `asd spm-map` from project root to refresh (supports SPM / Node / Go / JVM / Python)
|
|
69
|
+
- **Update**: Run `asd spm-map` from project root to refresh (supports SPM / Node / Go / JVM / Python / Dart / Rust)
|
|
70
70
|
|
|
71
71
|
---
|
|
72
72
|
|
|
@@ -42,10 +42,10 @@ V2 知识库中的 Recipe 按 `knowledgeType` 自动归入三类 kind,影响
|
|
|
42
42
|
| `title` | string | 标题(英文名,单行) | ≤50 字,建议动词开头 |
|
|
43
43
|
| `trigger` | string | 触发词 | **MUST** 以 `@` 开头,小写+下划线,无空格 |
|
|
44
44
|
| `category` | string | **分类(MUST 为 8 个标准值之一)** | `View`, `Service`, `Tool`, `Model`, `Network`, `Storage`, `UI`, `Utility` |
|
|
45
|
-
| `language` | string | 编程语言 | `swift`、`objectivec`、`go`、`python`、`java`、`kotlin`、`javascript`、`typescript` |
|
|
45
|
+
| `language` | string | 编程语言 | `swift`、`objectivec`、`go`、`python`、`java`、`kotlin`、`javascript`、`typescript`、`dart`、`rust` |
|
|
46
46
|
| `summary_cn` | string | 中文概述 | ≤100 字 |
|
|
47
47
|
| `summary_en` | string | 英文概述 | ≤100 words |
|
|
48
|
-
| `headers` | array | **完整 import/include 语句** | Swift: `["import Foundation"]`;ObjC: `["#import <UIKit/UIKit.h>"]`;Go: `["import \"fmt\""]`;Python: `["import os"]`;Java: `["import java.util.List;"]`;JS/TS: `["import fs from 'node:fs'"]` |
|
|
48
|
+
| `headers` | array | **完整 import/include 语句** | Swift: `["import Foundation"]`;ObjC: `["#import <UIKit/UIKit.h>"]`;Go: `["import \"fmt\""]`;Python: `["import os"]`;Java: `["import java.util.List;"]`;JS/TS: `["import fs from 'node:fs'"]`;Dart: `["import 'package:flutter/material.dart'"]`;Rust: `["use std::collections::HashMap;"]` |
|
|
49
49
|
|
|
50
50
|
### 可选字段(强烈推荐)
|
|
51
51
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
title: Your Recipe Title Here (English, ≤50 chars, verb-based)
|
|
4
4
|
trigger: @my_trigger
|
|
5
5
|
category: Network # MUST be one of: View, Service, Tool, Model, Network, Storage, UI, Utility
|
|
6
|
-
language: swift # swift, objectivec, go, python, java, kotlin, javascript, typescript
|
|
6
|
+
language: swift # swift, objectivec, go, python, java, kotlin, javascript, typescript, dart, rust
|
|
7
7
|
summary_cn: 中文概述,≤100 字,描述该 Recipe 的用途
|
|
8
8
|
summary_en: English summary, ≤100 words
|
|
9
9
|
headers: ["import Foundation"] # 完整 import 语句数组
|