@moon791017/neo-skills 1.1.14 → 1.1.17

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 CHANGED
@@ -63,6 +63,7 @@
63
63
  | 技能開發 | `generate-skill` | 建立、更新、審查或最佳化 Agent Skill,包含規格、觸發描述、延伸資源、評估資料與設計模式。 |
64
64
  | 可觀測性 | `neo-opentelemetry` | 解釋 OpenTelemetry 概念、規劃或審查 Collector 架構與設定、處理維運排障、安全、零程式 instrumentation 及相容性遷移。 |
65
65
  | 文字潤飾 | `neo-stop-slop` | 去除繁中或英文中的 AI 腔、贅詞、公式化句式,支援文件、註解、commit message 與 PR 說明。 |
66
+ | PR 產出 | `neo-pr` | 詢問或自動偵測 Repository 來源與目標分支,擷取變更並產生重點式且去 AI 腔的 PR Title 與 PR Description。 |
66
67
 
67
68
  `generate-skill` 位於 `.agents/skills/`,可由 Agent Skills CLI 探索與安裝;其餘技能位於 `skills/`。
68
69
 
@@ -84,48 +85,18 @@ node bin/install-skills.js
84
85
 
85
86
  ### Agent Skills CLI 安裝
86
87
 
87
- Agent Skills CLI 會從 GitHub repository 探索 `skills/` 與 `.agents/skills/`。請明確指定目標 Agent,避免使用 `--all` 時同時選取不支援全域安裝的 Agent。
88
-
89
- | Agent | `--agent` ID |
90
- | :--- | :--- |
91
- | Claude Code | `claude-code` |
92
- | Copilot CLI | `github-copilot` |
93
- | Codex | `codex` |
94
- | Antigravity CLI | `antigravity-cli` |
95
-
96
- 安裝全部技能到目前專案(以 Codex 為例):
97
-
98
- ```bash
99
- npx skills add Benknightdark/neo-skills --skill '*' --agent codex -y
100
- ```
101
-
102
- 安裝全部技能到全域(以 Codex 為例):
103
-
104
- ```bash
105
- npx skills add Benknightdark/neo-skills --skill '*' --agent codex -g -y
106
- ```
107
-
108
- 同時安裝到多個 Agent 時,重複傳入 `--agent`:
88
+ 安裝全部技能到目前專案:
109
89
 
110
90
  ```bash
111
- npx skills add Benknightdark/neo-skills --skill '*' \
112
- --agent codex \
113
- --agent antigravity-cli \
114
- -g -y
91
+ npx skills add Benknightdark/neo-skills --skill --all -y
115
92
  ```
116
93
 
117
- 只安裝指定技能時,重複傳入 `--skill`:
94
+ 安裝全部技能到全域:
118
95
 
119
96
  ```bash
120
- npx skills add Benknightdark/neo-skills \
121
- --skill neo-typescript \
122
- --skill neo-vue \
123
- --agent codex \
124
- -y
97
+ npx skills add Benknightdark/neo-skills --skill --all -g -y
125
98
  ```
126
99
 
127
- > `--all` 等同同時選取全部技能與全部 Agent。不要使用 `--all -g` 表示「全域安裝全部技能」;Eve 與 PromptScript 僅支援專案範圍,會使該組合回報安裝失敗。
128
-
129
100
  ## 系統提示詞安裝
130
101
 
131
102
  Agent Skills 規格同步的是技能目錄;`AGENTS.md`、`CLAUDE.md`、Copilot instructions 或 Antigravity `agents.md` 這類指導檔需要另外安裝。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moon791017/neo-skills",
3
- "version": "1.1.14",
3
+ "version": "1.1.17",
4
4
  "type": "module",
5
5
  "description": "Neo Skills: A Universal AI Agent Skills Extension",
6
6
  "homepage": "https://neo-blog-iota.vercel.app/",
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: neo-pr
3
+ description: >
4
+ Use this skill when the user asks to create, draft, review, format, or generate a Pull
5
+ Request (PR) title and description, specify target or source branches for a repository,
6
+ or convert git branch diffs into concise, high-impact, non-AI-slop PR content.
7
+ license: MIT
8
+ compatibility: Requires Python 3.10+ (uv or python3) for git-pr-extractor.py, and Node.js for analyze-slop.js validation.
9
+ metadata:
10
+ author: Ben Knight Dark
11
+ version: "1.0.0"
12
+ patterns: generator, reviewer, inversion
13
+ ---
14
+
15
+ # Neo PR Generator & Refiner
16
+
17
+ `neo-pr` is an expert skill engineered to generate precise, concise, and non-AI-slop Pull Request (PR) titles and descriptions for Git repositories. It proactively guides the user to clarify repository and branch targets, extracts change histories, and outputs clear, highly structured PR content.
18
+
19
+ ---
20
+
21
+ ## Gotchas
22
+
23
+ * **Non-existent or Unaligned Branches**: If the specified source or target branch does not exist locally or on remote, prompt the user to run `git fetch` or provide the correct branch name. Do not invent non-existent base branches.
24
+ * **Overly Long Diffs and Token Overhead**: If the branch diff spans dozens of files or thousands of lines, inspect `git diff --stat` and commit logs first to gain high-level context instead of loading full diffs at once.
25
+ * **De-slop Does Not Mean Removing Technical Substance**: When stripping AI fluff, eliminate throat-clearing openers (e.g., "It is worth noting that...", "This PR aims to..."), but strictly preserve essential context, key logic shifts, breaking changes, and test instructions.
26
+
27
+ ---
28
+
29
+ ## Workflow Checklist
30
+
31
+ - [ ] **Step 1 — Perceive (Gather Branch & Repository Context)**: Identify the repository path, source branch (`source branch`), and target branch (`target branch`). If unspecified, prompt the user or detect the current Git state.
32
+ - [ ] **Step 2 — Reason & Load References (Load Templates & Guidelines)**: Read [pr-template.md](file:///Users/ben/projects/neo-skills/skills/neo-pr/references/pr-template.md) for structural standards and de-slop conventions.
33
+ - [ ] **Step 3 — Act: Extract Diff (Fetch Change Record)**: Execute the helper script `git-pr-extractor.py` to retrieve commit logs, file statistics, and diff snippets.
34
+ - [ ] **Step 4 — Act: Generate & De-slop (Produce Concise PR Content)**: Write a Conventional Commits title and bulleted PR description while eliminating all AI tells.
35
+ - [ ] **Step 5 — Verify (Quality Check)**: Verify that the generated title and description adhere to de-slop standards (optionally run `analyze-slop.js` to score density).
36
+
37
+ ---
38
+
39
+ ## Detailed Guidelines
40
+
41
+ ### Step 1 — Perceive (Gather Branch & Repository Context)
42
+
43
+ Determine the following core parameters:
44
+ 1. **Repository Context**: Current working directory or specified GitHub/GitLab workspace.
45
+ 2. **Source Branch**: Branch containing the new changes (e.g., `feature/user-auth` or current checked-out branch).
46
+ 3. **Target Branch**: Base branch to merge into (e.g., `main`, `master`, or `develop`).
47
+
48
+ If the user has not specified branches, ask with a concise prompt:
49
+ > "Please specify your **source branch** (e.g., `feature/xxx`) and **target branch** (e.g., `main` or `develop`). If omitted, I will default to PRing the current branch into `main`."
50
+
51
+ ---
52
+
53
+ ### Step 2 — Reason & Load References
54
+
55
+ Load relevant design documents based on diff scope:
56
+ * **PR Structure & Template**: Read `references/pr-template.md` for standard markdown sections.
57
+ * **De-slop Rules**: Apply core `neo-stop-slop` principles (active voice, remove filler phrases, focus on objective facts).
58
+
59
+ ---
60
+
61
+ ### Step 3 — Act: Extract Diff (Fetch Change Record)
62
+
63
+ Run `git-pr-extractor.py` non-interactively in the target repository directory:
64
+ ```bash
65
+ python3 skills/neo-pr/scripts/git-pr-extractor.py --target-branch <target> --source-branch <source>
66
+ ```
67
+
68
+ Alternatively, run native Git commands if script execution is unavailable:
69
+ ```bash
70
+ git log <target>..<source> --oneline
71
+ git diff <target>..<source> --stat
72
+ ```
73
+
74
+ ---
75
+
76
+ ### Step 4 — Act: Generate & De-slop (Produce Concise PR Content)
77
+
78
+ Construct the PR Title and Description based on extracted commit and diff context.
79
+
80
+ #### 1. PR Title Standard (Conventional Commits)
81
+ * Format: `<type>(<scope>): <short summary>`
82
+ * Example: `feat(auth): 新增 JWT 驗證與 Token 自動刷新`
83
+ * Rules:
84
+ - Do not begin with filler phrases ("This PR implements...", "A commit to...").
85
+ - Keep under 50 characters, imperative mood, direct and actionable.
86
+
87
+ #### 2. PR Output Standard Structure
88
+ The PR output must strictly consist of only the following two sections:
89
+
90
+ ```markdown
91
+ 標題:
92
+ <Conventional Commits 格式標題>
93
+
94
+ 內容:
95
+ - 列點並重點化的說明重要變更內容(包含主要模組/檔案調整、邏輯變更與重大影響)。
96
+ ```
97
+
98
+ #### 3. Strict De-slop Rules
99
+ * ❌ Never use: "It is worth noting that", "Needless to say", "This PR aims to", "In summary", "Clearly".
100
+ * ❌ Avoid hyperbolic fluff: "dramatically improves", "seamlessly integrates", "highly robust".
101
+ * ⭕ Use concrete facts & metrics: "reduces response latency by 30ms", "fixes NullReferenceException on null payload".
102
+
103
+ ---
104
+
105
+ ### Step 5 — Verify (Quality Check)
106
+
107
+ 1. Ensure no critical modifications are omitted from the generated title or description.
108
+ 2. Run de-slop score check if `skills/neo-stop-slop/scripts/analyze-slop.js` is available:
109
+ ```bash
110
+ node skills/neo-stop-slop/scripts/analyze-slop.js --input "<generated PR description>" --format json
111
+ ```
112
+ Confirm `slopDensityScore` is **under 0.5%** (Grade **A+**).
@@ -0,0 +1,14 @@
1
+ {
2
+ "should_trigger": [
3
+ "Help me generate a PR title and description for merging feature/user-auth into main",
4
+ "Draft a clean, bulleted Pull Request description with no AI slop",
5
+ "Ask me for source and target branches, then generate concise PR content",
6
+ "Extract git diff and output a structured PR title and body"
7
+ ],
8
+ "should_not_trigger": [
9
+ "Perform a code review on this file and report security risks",
10
+ "Run git status to show my current uncommitted changes",
11
+ "Write a git commit message for fixing the crash bug",
12
+ "Rewrite this technical blog post to remove AI tells"
13
+ ]
14
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "skill_name": "neo-pr",
3
+ "evals": [
4
+ {
5
+ "id": 1,
6
+ "prompt": "Generate a concise, non-AI-slop PR title and description for merging feature/user-auth into main.",
7
+ "expected_output": "A PR title adhering to Conventional Commits format under '標題:', and a bulleted markdown PR description under '內容:' with no AI fluff phrases.",
8
+ "assertions": [
9
+ "PR Title complies with Conventional Commits format under 標題:",
10
+ "PR Description includes bullet points summarizing key changes under 內容:",
11
+ "Content is structured strictly with bullet points",
12
+ "Does not contain AI tells like 'It is worth noting that' or 'This PR aims to'"
13
+ ]
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,47 @@
1
+ # PR Title & Description Standard Reference
2
+
3
+ This document serves as the standard PR output template and Anti-Slop writing reference for the `neo-pr` skill.
4
+
5
+ ---
6
+
7
+ ## 1. PR Title Standard (Conventional Commits)
8
+
9
+ Titles must be clear, concise, and directly reflect the underlying changes using Conventional Commits format:
10
+
11
+ `<type>(<scope>): <description>`
12
+
13
+ ### Common Types:
14
+ * `feat`: A new feature
15
+ * `fix`: A bug fix
16
+ * `refactor`: A code change that neither fixes a bug nor adds a feature
17
+ * `docs`: Documentation changes only
18
+ * `test`: Adding missing tests or correcting existing tests
19
+ * `chore`: Changes to the build process, auxiliary tools, or dependencies
20
+ * `perf`: A code change that improves performance
21
+
22
+ ---
23
+
24
+ ## 2. PR Description Template
25
+
26
+ The PR output format must strictly follow:
27
+
28
+ ```markdown
29
+ 標題:
30
+ <type>(<scope>): <short summary>
31
+
32
+ 內容:
33
+ - **[重要變更/關鍵模組 1]**:說明具體調整內容與目的。
34
+ - **[重要變更/關鍵模組 2]**:說明具體調整內容與目的。
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 3. Anti-Slop Conversion Table
40
+
41
+ When drafting PR descriptions, rigorously filter out filler words according to the following mapping:
42
+
43
+ | ❌ Fluff Phrase | ⭕ Clean Alternative | Explanation |
44
+ | :--- | :--- | :--- |
45
+ | It is worth noting that this PR refactors auth logic. | 重構驗證邏輯,改用統一中介軟體。 | Delete throat-clearing openers; use direct action verbs. |
46
+ | This PR aims to resolve a potential crash during login. | 修復登入時因 null 使用者引發的閃退問題。 | Omit "This PR aims to"; state goal and root cause directly. |
47
+ | In summary, this change seamlessly boosts system performance. | 減少 DB 查詢,降低 API 延遲 40ms。 | Replace "seamlessly" with concrete metrics. |
@@ -0,0 +1,100 @@
1
+ # /// script
2
+ # dependencies = []
3
+ # ///
4
+
5
+ """
6
+ git-pr-extractor.py
7
+
8
+ Non-interactive Git diff and commit extraction script.
9
+ Given target_branch and source_branch, fetches Git logs, changed files, and diff summary,
10
+ then outputs JSON formatted data to stdout.
11
+ """
12
+
13
+ import argparse
14
+ import json
15
+ import os
16
+ import subprocess
17
+ import sys
18
+
19
+ def run_command(cmd, cwd=None):
20
+ result = subprocess.run(
21
+ cmd,
22
+ cwd=cwd,
23
+ stdout=subprocess.PIPE,
24
+ stderr=subprocess.PIPE,
25
+ text=True
26
+ )
27
+ return result.returncode, result.stdout, result.stderr
28
+
29
+ def main():
30
+ parser = argparse.ArgumentParser(description="Extract git diff and commit information for PR generation.")
31
+ parser.add_argument("--target-branch", default="main", help="Target base branch (e.g. main, develop)")
32
+ parser.add_argument("--source-branch", default="HEAD", help="Source feature branch (e.g. feature/auth, HEAD)")
33
+ parser.add_argument("--repo-path", default=".", help="Path to git repository")
34
+ parser.add_argument("--max-diff-lines", type=int, default=500, help="Maximum lines of diff to include")
35
+
36
+ args = parser.parse_args()
37
+ repo_path = os.path.abspath(args.repo_path)
38
+
39
+ # Verify if directory is inside a valid Git workspace
40
+ code, out, err = run_command(["git", "rev-parse", "--is-inside-work-tree"], cwd=repo_path)
41
+ if code != 0:
42
+ sys.stderr.write(f"Error: Path {repo_path} is not a valid git repository.\n{err}")
43
+ sys.exit(1)
44
+
45
+ # Retrieve current branch name for fallback reference
46
+ _, current_branch, _ = run_command(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=repo_path)
47
+ current_branch = current_branch.strip()
48
+
49
+ source = args.source_branch
50
+ if source == "HEAD":
51
+ source_name = current_branch
52
+ else:
53
+ source_name = source
54
+
55
+ target = args.target_branch
56
+ rev_range = f"{target}..{source}"
57
+
58
+ # 1. Fetch Commit History
59
+ code, log_out, log_err = run_command(["git", "log", rev_range, "--oneline"], cwd=repo_path)
60
+ if code != 0:
61
+ sys.stderr.write(f"Error executing git log for range {rev_range}:\n{log_err}")
62
+ sys.exit(1)
63
+
64
+ commits = [line.strip() for line in log_out.strip().split("\n") if line.strip()]
65
+
66
+ # 2. Fetch git diff --stat Summary
67
+ _, stat_out, _ = run_command(["git", "diff", rev_range, "--stat"], cwd=repo_path)
68
+
69
+ # 3. Fetch List of Modified Files
70
+ _, name_status_out, _ = run_command(["git", "diff", rev_range, "--name-status"], cwd=repo_path)
71
+ changed_files = []
72
+ for line in name_status_out.strip().split("\n"):
73
+ if line.strip():
74
+ parts = line.strip().split(maxsplit=1)
75
+ if len(parts) == 2:
76
+ changed_files.append({"status": parts[0], "file": parts[1]})
77
+
78
+ # 4. Fetch Truncated Git Diff Output (Prevents Token Overhead)
79
+ _, diff_out, _ = run_command(["git", "diff", rev_range], cwd=repo_path)
80
+ diff_lines = diff_out.split("\n")
81
+ is_truncated = len(diff_lines) > args.max_diff_lines
82
+ short_diff = "\n".join(diff_lines[:args.max_diff_lines])
83
+
84
+ output_data = {
85
+ "repository_path": repo_path,
86
+ "target_branch": target,
87
+ "source_branch": source_name,
88
+ "commit_count": len(commits),
89
+ "commits": commits,
90
+ "stat_summary": stat_out.strip(),
91
+ "changed_files": changed_files,
92
+ "diff_snippet": short_diff,
93
+ "diff_truncated": is_truncated
94
+ }
95
+
96
+ # Output JSON string exclusively to stdout
97
+ print(json.dumps(output_data, ensure_ascii=False, indent=2))
98
+
99
+ if __name__ == "__main__":
100
+ main()