@moon791017/neo-skills 1.0.33 → 1.0.35

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/GEMINI.md CHANGED
@@ -113,3 +113,5 @@ When interacting with this codebase or using the extension, the agent follows th
113
113
  * **JavaScript 現代語法專家:** 跨版本 JavaScript 專家 (ES6-ES2025+),專注於現代化語法、模組系統與高效能開發模式。
114
114
 
115
115
  * **Vue 現代開發專家:** 專注於 Vue 3 Composition API (`<script setup>`)、Pinia 狀態管理與 Vue Router 4,嚴格遵循官方 Style Guide 與最佳實踐。
116
+
117
+ * **Rust 專家 (`skills/neo-rust`)**: 用於開發、重構或審查 Rust 應用程式的專家技能,涵蓋 ownership、borrowing、Result/Option 與現代 Rust 設計模式。
package/README.md CHANGED
@@ -60,13 +60,16 @@
60
60
  ### 9. Vue 開發專家
61
61
  * **Vue 3 現代開發專家 (`skills/neo-vue`)**:專注於 Vue 3 Composition API (`<script setup>`)、Pinia 狀態管理與 Vue Router 4。嚴格遵循官方 Style Guide 與最佳實踐,並提供反模式 (Anti-Patterns) 的避坑指引。
62
62
 
63
- ### 10. 需求釐清助手
63
+ ### 10. Rust 開發專家
64
+ * **Rust 專家 (`skills/neo-rust`)**:用於開發、重構或審查 Rust 應用程式的專家技能,涵蓋 ownership、borrowing、Result/Option 與現代 Rust 設計模式。
65
+
66
+ ### 11. 需求釐清助手
64
67
  * **需求釐清**:系統化引導用戶釐清模糊需求,並將其轉化為結構化的規格文件(背景、功能、約束、驗收標準)。
65
68
 
66
- ### 11. AI 開發流程健檢
69
+ ### 12. AI 開發流程健檢
67
70
  * **AI 助手開發治理 (`skills/neo-agent-harness`)**:檢查專案規則、測試、CI、審查流程與安全防護是否足夠清楚,協助 AI 助手更穩定、更安全地參與開發。
68
71
 
69
- ### 12. 安全守衛 (Security Guard)
72
+ ### 13. 安全守衛 (Security Guard)
70
73
  * **主動防護 (`secret-guard.ts`)**:作為 CLI 的中介軟體 (Hook),自動攔截並掃描所有工具執行的參數。若偵測到敏感資訊(如環境設定檔、私鑰、雲端憑證等)將強制阻擋執行,防止機密外洩。
71
74
 
72
75
  ## 📂 系統架構
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "neo-skills",
3
3
  "description": "A universal capability extension for Gemini CLI",
4
- "version": "0.57.1",
4
+ "version": "0.59.0",
5
5
  "mcpServers": {
6
6
  "neo-skills": {
7
7
  "command": "node",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moon791017/neo-skills",
3
- "version": "1.0.33",
3
+ "version": "1.0.35",
4
4
  "type": "module",
5
5
  "description": "Neo Skills: A Universal Expert Agent Extension",
6
6
  "homepage": "https://neo-blog-iota.vercel.app/",
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: neo-rust
3
+ description: 用於開發、重構或審查 Rust 應用程式的專家技能。涵蓋 ownership、borrowing、Result/Option 與現代 Rust 設計模式。當使用者要求撰寫 Rust 程式碼、進行 Code Review 或討論 Rust 架構時使用。
4
+ metadata:
5
+ pattern: tool-wrapper, reviewer
6
+ domain: rust
7
+ ---
8
+
9
+ # Neo Rust Expert
10
+
11
+ You are an expert Rust developer. Your goal is to write safe, maintainable, and idiomatic Rust code by strictly following the official design patterns and avoiding anti-patterns.
12
+
13
+ ## Core Directives
14
+
15
+ Before writing or reviewing any Rust code, you MUST follow the "Perceive-Reason-Act" loop:
16
+
17
+ 1. **Perceive**: Understand the user's intent. Is it a new feature, a refactor, or a code review?
18
+ 2. **Reason**: Load the appropriate reference files based on the task:
19
+ - For writing new code or architecture design, load `reference/patterns.md` and `reference/coding-style.md`.
20
+ - For code review or debugging, load `reference/anti-patterns.md` to spot common mistakes.
21
+ 3. **Act**: Execute the task adhering strictly to the loaded guidelines.
22
+
23
+ ## When Writing Code
24
+ - Prioritize Borrowing over Ownership where applicable (`&str` instead of `String`).
25
+ - Handle errors gracefully using `Result<T, E>`. Never use `.unwrap()` or `panic!()` in library or production code.
26
+ - Represent "no value" with `Option<T>`, never with magic values like empty strings or `-1`.
27
+ - Use the Type System to prevent invalid states (e.g., Typestate, Newtype, Smart Constructors).
28
+ - Ensure resource cleanup using RAII/Drop.
29
+ - Prefer explicit composition over shared mutable state. Default to single ownership.
30
+
31
+ ## When Reviewing Code
32
+ 1. Load `reference/anti-patterns.md`.
33
+ 2. Check for unnecessary `.clone()`, excessive use of `String`, and improper error handling.
34
+ 3. Verify that `Arc<Mutex<T>>` is not overused where message passing or simple ownership would suffice.
35
+ 4. Check naming conventions against `reference/coding-style.md`.
36
+ 5. Provide actionable feedback with code examples demonstrating the "Good" approach.
37
+
38
+ ## Tools & Formatting
39
+ Always recommend standard Rust tooling: `cargo fmt`, `cargo clippy`, and `cargo check`.
40
+
41
+ ## Official Resources
42
+ - **Rust Official Website**: https://www.rust-lang.org/
43
+ - **Rust Documentation**: https://doc.rust-lang.org/
44
+ - **The Rust Programming Language (The Book)**: https://doc.rust-lang.org/book/
@@ -0,0 +1,354 @@
1
+ # 3. Anti-patterns
2
+
3
+ ---
4
+
5
+ ## Anti-pattern 1: Using `.clone()` everywhere to avoid the borrow checker
6
+
7
+ ### Bad
8
+
9
+ ```rust
10
+ fn process(name: String) {
11
+ println!("{name}");
12
+ }
13
+
14
+ fn main() {
15
+ let name = String::from("Alice");
16
+
17
+ process(name.clone());
18
+ process(name.clone());
19
+ process(name.clone());
20
+ }
21
+ ```
22
+
23
+ ### Good
24
+
25
+ ```rust
26
+ fn process(name: &str) {
27
+ println!("{name}");
28
+ }
29
+
30
+ fn main() {
31
+ let name = String::from("Alice");
32
+
33
+ process(&name);
34
+ process(&name);
35
+ process(&name);
36
+ }
37
+ ```
38
+
39
+ ### Principle
40
+
41
+ `.clone()` is not forbidden, but you should know why you are cloning.
42
+ If you only need to read the data, use a borrow instead.
43
+
44
+ ---
45
+
46
+ ## Anti-pattern 2: Excessive use of `String`
47
+
48
+ ### Bad
49
+
50
+ ```rust
51
+ fn is_admin(role: String) -> bool {
52
+ role == "admin"
53
+ }
54
+ ```
55
+
56
+ ### Good
57
+
58
+ ```rust
59
+ fn is_admin(role: &str) -> bool {
60
+ role == "admin"
61
+ }
62
+ ```
63
+
64
+ ### Principle
65
+
66
+ Use `String` when you need ownership; prefer `&str` for reading text.
67
+
68
+ ---
69
+
70
+ ## Anti-pattern 3: Using `bool` to represent complex states
71
+
72
+ ### Bad
73
+
74
+ ```rust
75
+ struct User {
76
+ is_active: bool,
77
+ is_deleted: bool,
78
+ is_locked: bool,
79
+ }
80
+ ```
81
+
82
+ Problem: Contradictory states can occur, such as being both `active` and `deleted`.
83
+
84
+ ### Good
85
+
86
+ ```rust
87
+ enum UserStatus {
88
+ Active,
89
+ Deleted,
90
+ Locked,
91
+ }
92
+
93
+ struct User {
94
+ status: UserStatus,
95
+ }
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Anti-pattern 4: Using `String` for errors
101
+
102
+ ### Bad
103
+
104
+ ```rust
105
+ fn parse_age(input: &str) -> Result<u8, String> {
106
+ input.parse::<u8>().map_err(|_| "invalid age".to_string())
107
+ }
108
+ ```
109
+
110
+ Acceptable for short scripts, but not recommended for libraries or large systems.
111
+
112
+ ### Good
113
+
114
+ ```rust
115
+ #[derive(Debug)]
116
+ enum ParseAgeError {
117
+ InvalidNumber,
118
+ TooLarge,
119
+ }
120
+
121
+ fn parse_age(input: &str) -> Result<u8, ParseAgeError> {
122
+ let age = input.parse::<u8>().map_err(|_| ParseAgeError::InvalidNumber)?;
123
+
124
+ if age > 120 {
125
+ return Err(ParseAgeError::TooLarge);
126
+ }
127
+
128
+ Ok(age)
129
+ }
130
+ ```
131
+
132
+ ### Principle
133
+
134
+ Errors should be categorizable, testable, and handleable.
135
+
136
+ ---
137
+
138
+ ## Anti-pattern 5: Random `panic!` inside a library
139
+
140
+ ### Bad
141
+
142
+ ```rust
143
+ pub fn divide(a: i32, b: i32) -> i32 {
144
+ if b == 0 {
145
+ panic!("divide by zero");
146
+ }
147
+
148
+ a / b
149
+ }
150
+ ```
151
+
152
+ ### Good
153
+
154
+ ```rust
155
+ #[derive(Debug)]
156
+ pub enum DivideError {
157
+ DivideByZero,
158
+ }
159
+
160
+ pub fn divide(a: i32, b: i32) -> Result<i32, DivideError> {
161
+ if b == 0 {
162
+ return Err(DivideError::DivideByZero);
163
+ }
164
+
165
+ Ok(a / b)
166
+ }
167
+ ```
168
+
169
+ ### Principle
170
+
171
+ Return `Result` unless it is an unrecoverable programming error.
172
+
173
+ ---
174
+
175
+ ## Anti-pattern 6: Over-abstraction with Traits
176
+
177
+ ### Bad
178
+
179
+ ```rust
180
+ trait UserNameProvider {
181
+ fn user_name(&self) -> &str;
182
+ }
183
+
184
+ struct User {
185
+ name: String,
186
+ }
187
+
188
+ impl UserNameProvider for User {
189
+ fn user_name(&self) -> &str {
190
+ &self.name
191
+ }
192
+ }
193
+ ```
194
+
195
+ Problem: When there's only one struct, one method, and no need for substitution, a trait is just noise.
196
+
197
+ ### Good
198
+
199
+ ```rust
200
+ struct User {
201
+ name: String,
202
+ }
203
+
204
+ impl User {
205
+ fn name(&self) -> &str {
206
+ &self.name
207
+ }
208
+ }
209
+ ```
210
+
211
+ ### Principle
212
+
213
+ Use concrete types first. Abstract into traits only when actually needed.
214
+
215
+ ---
216
+
217
+ ## Anti-pattern 7: Public fields breaking invariants
218
+
219
+ ### Bad
220
+
221
+ ```rust
222
+ pub struct Account {
223
+ pub balance: i64,
224
+ }
225
+
226
+ fn main() {
227
+ let mut account = Account { balance: 100 };
228
+ account.balance = -999;
229
+ }
230
+ ```
231
+
232
+ ### Good
233
+
234
+ ```rust
235
+ pub struct Account {
236
+ balance: i64,
237
+ }
238
+
239
+ impl Account {
240
+ pub fn new(balance: i64) -> Result<Self, String> {
241
+ if balance < 0 {
242
+ return Err("balance cannot be negative".to_string());
243
+ }
244
+
245
+ Ok(Self { balance })
246
+ }
247
+
248
+ pub fn balance(&self) -> i64 {
249
+ self.balance
250
+ }
251
+
252
+ pub fn deposit(&mut self, amount: i64) -> Result<(), String> {
253
+ if amount <= 0 {
254
+ return Err("amount must be positive".to_string());
255
+ }
256
+
257
+ self.balance += amount;
258
+ Ok(())
259
+ }
260
+ }
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Anti-pattern 8: Passing `Arc<Mutex<T>>` everywhere
266
+
267
+ ### Bad
268
+
269
+ ```rust
270
+ use std::sync::{Arc, Mutex};
271
+
272
+ struct AppState {
273
+ users: Arc<Mutex<Vec<String>>>,
274
+ logs: Arc<Mutex<Vec<String>>>,
275
+ configs: Arc<Mutex<Vec<String>>>,
276
+ }
277
+ ```
278
+
279
+ Problem: Too many locks, unclear responsibilities, prone to deadlocks, and difficult to test.
280
+
281
+ ### Good
282
+
283
+ ```rust
284
+ struct UserService {
285
+ users: Vec<String>,
286
+ }
287
+
288
+ impl UserService {
289
+ fn create_user(&mut self, name: String) {
290
+ self.users.push(name);
291
+ }
292
+ }
293
+ ```
294
+
295
+ ### Principle
296
+
297
+ Prefer single ownership over shared state. Consider `Arc<Mutex<T>>` only when cross-thread access is required.
298
+
299
+ ---
300
+
301
+ ## Anti-pattern 9: Holding a lock across `.await` in async code
302
+
303
+ ### Bad
304
+
305
+ ```rust
306
+ // Conceptual illustration
307
+ let mut guard = state.lock().await;
308
+ do_async_work().await;
309
+ guard.push(1);
310
+ ```
311
+
312
+ Problem: Holding a lock for too long can cause performance issues or deadlock-like behavior.
313
+
314
+ ### Good
315
+
316
+ ```rust
317
+ let data = {
318
+ let mut guard = state.lock().await;
319
+ guard.push(1);
320
+ guard.clone()
321
+ };
322
+
323
+ do_async_work(data).await;
324
+ ```
325
+
326
+ ### Principle
327
+
328
+ Keep the code inside a lock as short, synchronous, and necessary as possible.
329
+
330
+ ---
331
+
332
+ ## Anti-pattern 10: Abuse of `unsafe`
333
+
334
+ ### Bad
335
+
336
+ ```rust
337
+ unsafe {
338
+ // Using raw pointers haphazardly to bypass the borrow checker
339
+ }
340
+ ```
341
+
342
+ ### Good
343
+
344
+ Ask yourself first:
345
+
346
+ 1. Can the design be changed using ownership?
347
+ 2. Can `Rc` / `Arc` be used?
348
+ 3. Can `RefCell` / `Mutex` be used?
349
+ 4. Can the data structure be split?
350
+ 5. Do you really need FFI, SIMD, or low-level memory operations?
351
+
352
+ ### Principle
353
+
354
+ `unsafe` is not a performance switch; it is taking over the safety responsibilities that the compiler can no longer guarantee.