@moon791017/neo-skills 1.0.34 → 1.0.36
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 +0 -2
- package/README.md +2 -4
- package/bin/_system-instructions.js +32 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/skills/neo-rust/SKILL.md +1 -1
- package/skills/neo-rust/reference/anti-patterns.md +61 -65
- package/skills/neo-rust/reference/coding-style.md +96 -96
- package/skills/neo-rust/reference/patterns.md +117 -122
- package/skills/neo-git-commit/SKILL.md +0 -88
package/GEMINI.md
CHANGED
|
@@ -82,8 +82,6 @@ When interacting with this codebase or using the extension, the agent follows th
|
|
|
82
82
|
|
|
83
83
|
* **Web Scraper:** 從指定的 URL 獲取網頁 HTML 內容,支援 CSS 選擇器 (`fetch_web_content`)。
|
|
84
84
|
|
|
85
|
-
* **Git Automation:** 根據暫存區變更自動生成 Conventional Commits 訊息,經使用者確認後執行 commit。
|
|
86
|
-
|
|
87
85
|
* **CI Protocols:** 自動配置 .NET 專案的 Azure Pipelines CI 建置流程。
|
|
88
86
|
|
|
89
87
|
* **CD Protocols:** 為專案自動配置 Azure App Service 與地端 IIS 的部署流程 (CD)。
|
package/README.md
CHANGED
|
@@ -27,10 +27,7 @@
|
|
|
27
27
|
* **Azure App Service**:部署至Azure App Service。
|
|
28
28
|
* **IIS On-Premises**:部署至地端 IIS 伺服器,包含備份與復原機制。
|
|
29
29
|
|
|
30
|
-
### 2.
|
|
31
|
-
* **Smart Commit**:根據 `git diff` 暫存區內容,自動生成符合 Conventional Commits 規範的提交訊息。
|
|
32
|
-
|
|
33
|
-
### 3. Code Review 專家
|
|
30
|
+
### 2. Code Review 專家
|
|
34
31
|
* **智能審查**:針對程式碼變更進行多面向 (正確性、安全性、效能、可讀性) 的深度審查。
|
|
35
32
|
|
|
36
33
|
### 4. 程式碼解釋助手
|
|
@@ -185,6 +182,7 @@ install-system-instructions --instructions <key> [--ai-agent <name>] [--project-
|
|
|
185
182
|
| Key | 名稱 | 說明 |
|
|
186
183
|
| :--- | :--- | :--- |
|
|
187
184
|
| `technical-co-founder` | Technical Co-Founder | 讓 AI 扮演技術共同創辦人,以 Discovery → Planning → Building → Polish → Handoff 五階段框架,協助您從零打造可上線的真實產品。 |
|
|
185
|
+
| `git-commit` | Git Commit Message Generator | 分析暫存區變更,自動生成符合 Conventional Commits 規範的提交訊息,經確認後執行。 |
|
|
188
186
|
|
|
189
187
|
**範例:**
|
|
190
188
|
|
|
@@ -46,6 +46,34 @@ Rules:
|
|
|
46
46
|
• This is real. Not a mockup. Not a prototype. A working product.
|
|
47
47
|
• Keep me in control and in the loop at all times`;
|
|
48
48
|
|
|
49
|
+
export const gitCommitInstructions = `
|
|
50
|
+
## Git Commit Guidelines
|
|
51
|
+
|
|
52
|
+
All commit messages must strictly adopt Conventional Commits 1.0.0 (CC 1.0.0).
|
|
53
|
+
|
|
54
|
+
- Format: \`<type>[optional scope][!]: <description>\`.
|
|
55
|
+
- \`type\` must be a lowercase noun; prioritize using \`feat\`, \`fix\`, \`docs\`, \`test\`, \`refactor\`, \`build\`, \`ci\`, \`chore\`.
|
|
56
|
+
- \`feat\` indicates a new feature, corresponding to SemVer minor; \`fix\` indicates a bug fix, corresponding to SemVer patch.
|
|
57
|
+
- \`scope\` is optional, use a lowercase short noun, e.g., \`docs\`, \`scanner\`, \`npm\`, \`ci\`.
|
|
58
|
+
- \`description\` is required, write in the imperative mood, present tense, in English, and do not end with a period.
|
|
59
|
+
- Major breaking changes must have a \`!\` added after the type/scope, or use \`BREAKING CHANGE: <description>\` in the footer; this kind of commit corresponds to SemVer major.
|
|
60
|
+
- Body is optional, must be separated from the header by a blank line, used to explain motivation, background, and behavioral differences, without restating the diff.
|
|
61
|
+
- Footer is optional, must be separated from the body by a blank line; issue references use \`Refs: #123\` or \`Closes: #123\`.
|
|
62
|
+
- Multi-line commit messages must use actual newline characters to separate header, body, and footer; do not write the literal string \`\\n\` into the commit message or git log.
|
|
63
|
+
- Each commit focuses on a single logical change; do not mix unrelated modifications in the same commit.
|
|
64
|
+
- Before committing, ensure you do not include unrequested or existing unrelated changes.
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
|
|
68
|
+
\`\`\`text
|
|
69
|
+
docs(readme): add localized documentation links
|
|
70
|
+
|
|
71
|
+
feat(scanner)!: change default risk threshold
|
|
72
|
+
|
|
73
|
+
BREAKING CHANGE: scans now fail CI when findings are at or above the threshold
|
|
74
|
+
\`\`\`
|
|
75
|
+
`;
|
|
76
|
+
|
|
49
77
|
/**
|
|
50
78
|
* 系統提示詞 Registry — 以 kebab-case 作為 key,供 CLI 選擇安裝。
|
|
51
79
|
*
|
|
@@ -58,4 +86,8 @@ export const INSTRUCTIONS = {
|
|
|
58
86
|
name: 'Technical Co-Founder',
|
|
59
87
|
content: technicalCoFounderInstructions,
|
|
60
88
|
},
|
|
89
|
+
'git-commit': {
|
|
90
|
+
name: 'Git Commit Message Generator',
|
|
91
|
+
content: gitCommitInstructions,
|
|
92
|
+
},
|
|
61
93
|
};
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED
package/skills/neo-rust/SKILL.md
CHANGED
|
@@ -41,4 +41,4 @@ Always recommend standard Rust tooling: `cargo fmt`, `cargo clippy`, and `cargo
|
|
|
41
41
|
## Official Resources
|
|
42
42
|
- **Rust Official Website**: https://www.rust-lang.org/
|
|
43
43
|
- **Rust Documentation**: https://doc.rust-lang.org/
|
|
44
|
-
- **The Rust Programming Language (The Book)**: https://doc.rust-lang.org/book/
|
|
44
|
+
- **The Rust Programming Language (The Book)**: https://doc.rust-lang.org/book/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# 3. Anti-
|
|
1
|
+
# 3. Anti-patterns
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
## Anti-pattern 1
|
|
5
|
+
## Anti-pattern 1: Using `.clone()` everywhere to avoid the borrow checker
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Bad
|
|
8
8
|
|
|
9
9
|
```rust
|
|
10
10
|
fn process(name: String) {
|
|
@@ -20,7 +20,7 @@ fn main() {
|
|
|
20
20
|
}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### Good
|
|
24
24
|
|
|
25
25
|
```rust
|
|
26
26
|
fn process(name: &str) {
|
|
@@ -36,16 +36,16 @@ fn main() {
|
|
|
36
36
|
}
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
###
|
|
39
|
+
### Principle
|
|
40
40
|
|
|
41
|
-
clone
|
|
42
|
-
|
|
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
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
46
|
-
## Anti-pattern 2
|
|
46
|
+
## Anti-pattern 2: Excessive use of `String`
|
|
47
47
|
|
|
48
|
-
###
|
|
48
|
+
### Bad
|
|
49
49
|
|
|
50
50
|
```rust
|
|
51
51
|
fn is_admin(role: String) -> bool {
|
|
@@ -53,7 +53,7 @@ fn is_admin(role: String) -> bool {
|
|
|
53
53
|
}
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
###
|
|
56
|
+
### Good
|
|
57
57
|
|
|
58
58
|
```rust
|
|
59
59
|
fn is_admin(role: &str) -> bool {
|
|
@@ -61,15 +61,15 @@ fn is_admin(role: &str) -> bool {
|
|
|
61
61
|
}
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
###
|
|
64
|
+
### Principle
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
Use `String` when you need ownership; prefer `&str` for reading text.
|
|
67
67
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
|
-
## Anti-pattern 3
|
|
70
|
+
## Anti-pattern 3: Using `bool` to represent complex states
|
|
71
71
|
|
|
72
|
-
###
|
|
72
|
+
### Bad
|
|
73
73
|
|
|
74
74
|
```rust
|
|
75
75
|
struct User {
|
|
@@ -79,9 +79,9 @@ struct User {
|
|
|
79
79
|
}
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
Problem: Contradictory states can occur, such as being both `active` and `deleted`.
|
|
83
83
|
|
|
84
|
-
###
|
|
84
|
+
### Good
|
|
85
85
|
|
|
86
86
|
```rust
|
|
87
87
|
enum UserStatus {
|
|
@@ -97,9 +97,9 @@ struct User {
|
|
|
97
97
|
|
|
98
98
|
---
|
|
99
99
|
|
|
100
|
-
## Anti-pattern 4
|
|
100
|
+
## Anti-pattern 4: Using `String` for errors
|
|
101
101
|
|
|
102
|
-
###
|
|
102
|
+
### Bad
|
|
103
103
|
|
|
104
104
|
```rust
|
|
105
105
|
fn parse_age(input: &str) -> Result<u8, String> {
|
|
@@ -107,9 +107,9 @@ fn parse_age(input: &str) -> Result<u8, String> {
|
|
|
107
107
|
}
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
Acceptable for short scripts, but not recommended for libraries or large systems.
|
|
111
111
|
|
|
112
|
-
###
|
|
112
|
+
### Good
|
|
113
113
|
|
|
114
114
|
```rust
|
|
115
115
|
#[derive(Debug)]
|
|
@@ -129,15 +129,15 @@ fn parse_age(input: &str) -> Result<u8, ParseAgeError> {
|
|
|
129
129
|
}
|
|
130
130
|
```
|
|
131
131
|
|
|
132
|
-
###
|
|
132
|
+
### Principle
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
Errors should be categorizable, testable, and handleable.
|
|
135
135
|
|
|
136
136
|
---
|
|
137
137
|
|
|
138
|
-
## Anti-pattern 5
|
|
138
|
+
## Anti-pattern 5: Random `panic!` inside a library
|
|
139
139
|
|
|
140
|
-
###
|
|
140
|
+
### Bad
|
|
141
141
|
|
|
142
142
|
```rust
|
|
143
143
|
pub fn divide(a: i32, b: i32) -> i32 {
|
|
@@ -149,7 +149,7 @@ pub fn divide(a: i32, b: i32) -> i32 {
|
|
|
149
149
|
}
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
-
###
|
|
152
|
+
### Good
|
|
153
153
|
|
|
154
154
|
```rust
|
|
155
155
|
#[derive(Debug)]
|
|
@@ -166,15 +166,15 @@ pub fn divide(a: i32, b: i32) -> Result<i32, DivideError> {
|
|
|
166
166
|
}
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
###
|
|
169
|
+
### Principle
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
Return `Result` unless it is an unrecoverable programming error.
|
|
172
172
|
|
|
173
173
|
---
|
|
174
174
|
|
|
175
|
-
## Anti-pattern 6
|
|
175
|
+
## Anti-pattern 6: Over-abstraction with Traits
|
|
176
176
|
|
|
177
|
-
###
|
|
177
|
+
### Bad
|
|
178
178
|
|
|
179
179
|
```rust
|
|
180
180
|
trait UserNameProvider {
|
|
@@ -192,9 +192,9 @@ impl UserNameProvider for User {
|
|
|
192
192
|
}
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
|
|
195
|
+
Problem: When there's only one struct, one method, and no need for substitution, a trait is just noise.
|
|
196
196
|
|
|
197
|
-
###
|
|
197
|
+
### Good
|
|
198
198
|
|
|
199
199
|
```rust
|
|
200
200
|
struct User {
|
|
@@ -208,15 +208,15 @@ impl User {
|
|
|
208
208
|
}
|
|
209
209
|
```
|
|
210
210
|
|
|
211
|
-
###
|
|
211
|
+
### Principle
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
Use concrete types first. Abstract into traits only when actually needed.
|
|
214
214
|
|
|
215
215
|
---
|
|
216
216
|
|
|
217
|
-
## Anti-pattern 7
|
|
217
|
+
## Anti-pattern 7: Public fields breaking invariants
|
|
218
218
|
|
|
219
|
-
###
|
|
219
|
+
### Bad
|
|
220
220
|
|
|
221
221
|
```rust
|
|
222
222
|
pub struct Account {
|
|
@@ -229,7 +229,7 @@ fn main() {
|
|
|
229
229
|
}
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
###
|
|
232
|
+
### Good
|
|
233
233
|
|
|
234
234
|
```rust
|
|
235
235
|
pub struct Account {
|
|
@@ -262,9 +262,9 @@ impl Account {
|
|
|
262
262
|
|
|
263
263
|
---
|
|
264
264
|
|
|
265
|
-
## Anti-pattern 8
|
|
265
|
+
## Anti-pattern 8: Passing `Arc<Mutex<T>>` everywhere
|
|
266
266
|
|
|
267
|
-
###
|
|
267
|
+
### Bad
|
|
268
268
|
|
|
269
269
|
```rust
|
|
270
270
|
use std::sync::{Arc, Mutex};
|
|
@@ -276,9 +276,9 @@ struct AppState {
|
|
|
276
276
|
}
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
-
|
|
279
|
+
Problem: Too many locks, unclear responsibilities, prone to deadlocks, and difficult to test.
|
|
280
280
|
|
|
281
|
-
###
|
|
281
|
+
### Good
|
|
282
282
|
|
|
283
283
|
```rust
|
|
284
284
|
struct UserService {
|
|
@@ -292,27 +292,26 @@ impl UserService {
|
|
|
292
292
|
}
|
|
293
293
|
```
|
|
294
294
|
|
|
295
|
-
###
|
|
295
|
+
### Principle
|
|
296
296
|
|
|
297
|
-
|
|
298
|
-
需要跨 thread 再考慮 `Arc<Mutex<T>>`。
|
|
297
|
+
Prefer single ownership over shared state. Consider `Arc<Mutex<T>>` only when cross-thread access is required.
|
|
299
298
|
|
|
300
299
|
---
|
|
301
300
|
|
|
302
|
-
## Anti-pattern 9
|
|
301
|
+
## Anti-pattern 9: Holding a lock across `.await` in async code
|
|
303
302
|
|
|
304
|
-
###
|
|
303
|
+
### Bad
|
|
305
304
|
|
|
306
305
|
```rust
|
|
307
|
-
//
|
|
306
|
+
// Conceptual illustration
|
|
308
307
|
let mut guard = state.lock().await;
|
|
309
308
|
do_async_work().await;
|
|
310
309
|
guard.push(1);
|
|
311
310
|
```
|
|
312
311
|
|
|
313
|
-
|
|
312
|
+
Problem: Holding a lock for too long can cause performance issues or deadlock-like behavior.
|
|
314
313
|
|
|
315
|
-
###
|
|
314
|
+
### Good
|
|
316
315
|
|
|
317
316
|
```rust
|
|
318
317
|
let data = {
|
|
@@ -324,35 +323,32 @@ let data = {
|
|
|
324
323
|
do_async_work(data).await;
|
|
325
324
|
```
|
|
326
325
|
|
|
327
|
-
###
|
|
326
|
+
### Principle
|
|
328
327
|
|
|
329
|
-
|
|
328
|
+
Keep the code inside a lock as short, synchronous, and necessary as possible.
|
|
330
329
|
|
|
331
330
|
---
|
|
332
331
|
|
|
333
|
-
## Anti-pattern 10
|
|
332
|
+
## Anti-pattern 10: Abuse of `unsafe`
|
|
334
333
|
|
|
335
|
-
###
|
|
334
|
+
### Bad
|
|
336
335
|
|
|
337
336
|
```rust
|
|
338
337
|
unsafe {
|
|
339
|
-
//
|
|
338
|
+
// Using raw pointers haphazardly to bypass the borrow checker
|
|
340
339
|
}
|
|
341
340
|
```
|
|
342
341
|
|
|
343
|
-
###
|
|
342
|
+
### Good
|
|
344
343
|
|
|
345
|
-
|
|
344
|
+
Ask yourself first:
|
|
346
345
|
|
|
347
|
-
1.
|
|
348
|
-
2.
|
|
349
|
-
3.
|
|
350
|
-
4.
|
|
351
|
-
5.
|
|
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?
|
|
352
351
|
|
|
353
|
-
###
|
|
354
|
-
|
|
355
|
-
`unsafe` 不是效能開關,是你接手編譯器無法保證的安全責任。
|
|
356
|
-
|
|
357
|
-
---
|
|
352
|
+
### Principle
|
|
358
353
|
|
|
354
|
+
`unsafe` is not a performance switch; it is taking over the safety responsibilities that the compiler can no longer guarantee.
|