prsmith 1.1.0 → 2.0.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 +15 -0
- package/README.md +124 -43
- package/bin/cli.js +183 -31
- package/eslint.config.js +8 -6
- package/package.json +1 -1
- package/src/ai.js +118 -0
- package/src/batch.js +206 -0
- package/src/config.js +8 -3
- package/src/formatter.js +40 -9
- package/src/github.js +153 -0
- package/src/prompts.js +114 -21
- package/src/templates.js +5 -9
- package/tests/features.test.js +210 -0
- package/tests/formatter.test.js +32 -28
package/CHANGELOG.md
CHANGED
|
@@ -2,9 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.0.0] - 2026-06-01
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **GitHub Integration**: Direct comment posting to PRs and full integrated Review Submission support, featuring auto-detection of repository details from local Git configs.
|
|
10
|
+
- **AI "Rude-to-Polite" Polish**: A unified client supporting Gemini, OpenAI, and Groq over lightweight native HTTP requests, translating harsh or blunt feedback into constructive and polite reviews.
|
|
11
|
+
- **Interactive Batch Review Mode (`prsmith batch`)**: Loop through multiple issues in a single terminal session, compile them into a unified report, and optionally post them as separate native inline review comments on GitHub.
|
|
12
|
+
- **File & Line Context**: Link your comments directly to code files and line numbers, generating clickable GitHub deep links when repo details are available.
|
|
13
|
+
- **Before & After Code Snippets**: Show differences between original and proposed code structures in collapsible `<details>` blocks with syntax highlighting.
|
|
14
|
+
|
|
5
15
|
## [1.1.0] - 2026-06-01
|
|
6
16
|
|
|
7
17
|
### Added
|
|
18
|
+
|
|
8
19
|
- **Clipboard Integration**: Automatically copies the generated markdown to your clipboard (`clipboardy`).
|
|
9
20
|
- **Editor Prompts**: The `issue` and `fix` interactive prompts now intelligently launch your default system `$EDITOR` (e.g. VS Code, vim) for a seamless multi-line typing experience.
|
|
10
21
|
- **CLI Arguments**: You can completely bypass the interactive mode by supplying flags: `-s`, `-t`, `-i`, `-f`.
|
|
@@ -15,6 +26,7 @@ All notable changes to this project will be documented in this file.
|
|
|
15
26
|
## [1.0.2] - 2026-05-31
|
|
16
27
|
|
|
17
28
|
### Added
|
|
29
|
+
|
|
18
30
|
- Integrated `commander` to provide robust native support for CLI flags (`-h`, `--help`, `-v`, `--version`).
|
|
19
31
|
- Graceful termination handling: Intercepting `ExitPromptError` to display a friendly message when users abort the interactive prompt (e.g., via `Ctrl+C`) instead of throwing stack traces.
|
|
20
32
|
- Custom author branding and detailed bio added to the README footer.
|
|
@@ -22,16 +34,19 @@ All notable changes to this project will be documented in this file.
|
|
|
22
34
|
## [1.0.1] - 2026-05-31
|
|
23
35
|
|
|
24
36
|
### Fixed
|
|
37
|
+
|
|
25
38
|
- Re-configured Git Hooks (Husky) to ensure `npm test` and `npm run lint` run reliably on pre-commit.
|
|
26
39
|
- Resolved invalid path structures in `package.json` for the executable `bin` field.
|
|
27
40
|
- Fixed a bug in `inquirer` by migrating legacy `"list"` prompt types to `"select"` to prevent CLI crashes.
|
|
28
41
|
|
|
29
42
|
### Changed
|
|
43
|
+
|
|
30
44
|
- Massively overhauled `README.md` for NPM compatibility: Replaced unsupported Mermaid diagrams with elegant ASCII flowcharts, incorporated GitHub/NPM badges, and structured sections with collapsible `<details>` HTML tags for premium rendering on the NPM website.
|
|
31
45
|
|
|
32
46
|
## [1.0.0] - 2026-05-31
|
|
33
47
|
|
|
34
48
|
### Added
|
|
49
|
+
|
|
35
50
|
- Interactive CLI prompts to generate PR review comments.
|
|
36
51
|
- Formatter to generate markdown based on severity, title, issue, and fix.
|
|
37
52
|
- Initial setup for linting, testing, and CI.
|
package/README.md
CHANGED
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
[](https://github.com/TarunyaProgrammer/PRSmith_NPMPackage/actions)
|
|
7
7
|
|
|
8
|
-
<p><b>Forge professional pull request review comments directly from the terminal.</b></p>
|
|
8
|
+
<p><b>Forge professional pull request review comments and submit integrated reviews directly from the terminal.</b></p>
|
|
9
9
|
</div>
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
|
-
PRSmith streamlines the process of writing code reviews by providing an interactive prompt that generates consistently formatted, polite, and actionable Markdown comments.
|
|
13
|
+
PRSmith streamlines the process of writing code reviews by providing an interactive prompt that generates consistently formatted, polite, and actionable Markdown comments. With **v2.0.0**, PRSmith evolves into an **intelligent, automated, production-grade Code Review suite** featuring AI-powered tone polishing, direct GitHub integrations, file context, and batch review loops.
|
|
14
14
|
|
|
15
15
|
## Architecture Flow
|
|
16
16
|
|
|
17
|
-
The tool operates via a straightforward interactive flow, generating structured markdown from your inputs.
|
|
17
|
+
The tool operates via a straightforward interactive flow, generating structured markdown from your inputs and supporting remote integrations.
|
|
18
18
|
|
|
19
19
|
```text
|
|
20
20
|
┌──────────────────────────┐
|
|
@@ -23,7 +23,12 @@ The tool operates via a straightforward interactive flow, generating structured
|
|
|
23
23
|
▼
|
|
24
24
|
┌──────────────────────────┐
|
|
25
25
|
│ Interactive Prompts │
|
|
26
|
-
│ (
|
|
26
|
+
│ (File, Snippets, Issue) │
|
|
27
|
+
└────────────┬─────────────┘
|
|
28
|
+
▼
|
|
29
|
+
┌──────────────────────────┐
|
|
30
|
+
│ AI Polish (Optional) │
|
|
31
|
+
│ (Gemini, OpenAI, Groq) │
|
|
27
32
|
└────────────┬─────────────┘
|
|
28
33
|
▼
|
|
29
34
|
┌──────────────────────────┐
|
|
@@ -31,7 +36,8 @@ The tool operates via a straightforward interactive flow, generating structured
|
|
|
31
36
|
└────────────┬─────────────┘
|
|
32
37
|
▼
|
|
33
38
|
┌──────────────────────────┐
|
|
34
|
-
│
|
|
39
|
+
│ Export / Direct Post │
|
|
40
|
+
│ (GitHub, Clipboard, File)│
|
|
35
41
|
└──────────────────────────┘
|
|
36
42
|
```
|
|
37
43
|
|
|
@@ -45,86 +51,160 @@ Install globally to use it anywhere on your machine.
|
|
|
45
51
|
npm install -g prsmith
|
|
46
52
|
```
|
|
47
53
|
|
|
48
|
-
|
|
54
|
+
---
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
## ⚡ Key Features (v2.0.0)
|
|
57
|
+
|
|
58
|
+
PRSmith has been completely overhauled with a set of powerful new features:
|
|
59
|
+
|
|
60
|
+
1. **🚀 GitHub Integration (PR Comments & Reviews)**:
|
|
61
|
+
- Post your generated review comment directly to a Pull Request as an issue comment, or as a native GitHub code review.
|
|
62
|
+
- **Zero-Config Repo Auto-Detection**: Auto-detects the repository owner and name from your local `.git/config` remotes.
|
|
63
|
+
2. **✨ AI "Rude-to-Polite" Polish**:
|
|
64
|
+
- Polishes blunt or harsh descriptions into constructive, professional, and empathetic reviews.
|
|
65
|
+
- Built-in support for **Gemini** (default), **OpenAI**, and **Groq** via lightweight native HTTP requests.
|
|
66
|
+
3. **📁 File & Line Number Context**:
|
|
67
|
+
- Link your feedback directly to code files and line ranges (e.g. `src/utils.js:45-50`).
|
|
68
|
+
- If GitHub integration is active, PRSmith generates **clickable GitHub deep links** straight to the code!
|
|
69
|
+
4. **🔍 Before/After Code Snippet Comparisons**:
|
|
70
|
+
- Provide original and proposed code blocks. Outputs collapsible `<details>` blocks featuring gorgeous syntax highlighting.
|
|
71
|
+
5. **📦 Batch Review Mode (`prsmith batch`)**:
|
|
72
|
+
- Run a single review runner loop to review multiple files or issues in one go.
|
|
73
|
+
- Export all bundled reviews together: copy them, save to a report, or **submit a native multi-comment review on GitHub** in a single click!
|
|
74
|
+
|
|
75
|
+
---
|
|
55
76
|
|
|
56
77
|
## 💻 Usage
|
|
57
78
|
|
|
58
|
-
### Interactive Mode
|
|
59
|
-
|
|
79
|
+
### 1. Fully Interactive Mode
|
|
80
|
+
|
|
81
|
+
The simplest way to use PRSmith:
|
|
60
82
|
|
|
61
83
|
```bash
|
|
62
84
|
prsmith
|
|
63
85
|
```
|
|
64
|
-
This will launch the interactive prompt. When asked to describe the issue or fix, your default terminal editor will launch, allowing you to write multi-line markdown!
|
|
65
86
|
|
|
66
|
-
|
|
87
|
+
This starts the wizard, prompting you for:
|
|
88
|
+
|
|
89
|
+
- Severity level & Title
|
|
90
|
+
- Problem description & Suggested fix (opens your system's default `$EDITOR` like VS Code, Vim, or Nano for comfortable multi-line editing)
|
|
91
|
+
- Optional File & Line context
|
|
92
|
+
- Optional Before & After code snippets
|
|
93
|
+
- Optional AI Polish toggle
|
|
94
|
+
|
|
95
|
+
### 2. Interactive Batch Mode (New)
|
|
67
96
|
|
|
68
|
-
|
|
97
|
+
Review multiple issues in a single terminal session and compile them into a unified report:
|
|
69
98
|
|
|
70
99
|
```bash
|
|
71
|
-
prsmith
|
|
100
|
+
prsmith batch
|
|
72
101
|
```
|
|
73
102
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
103
|
+
At the end of the batch review, an interactive menu allows you to copy the unified report, save it to a file, or **submit all comments at once as native inline review threads** on a GitHub PR.
|
|
104
|
+
|
|
105
|
+
### 3. Non-Interactive CLI Flags
|
|
106
|
+
|
|
107
|
+
Bypass the prompts entirely for fast operations or CI/CD pipelines:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
prsmith -s Critical -t "Resource Leak" -i "The connection is never closed." -f "Add a finally block." -p "src/db.js" -l "12-15" --ai --github --pr 42
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
| Flag | Full | Description |
|
|
114
|
+
| :--------- | :----------- | :----------------------------------------------------------------- |
|
|
115
|
+
| `-s` | `--severity` | Severity level (e.g., Critical, Suggestion) |
|
|
116
|
+
| `-t` | `--title` | The review title |
|
|
117
|
+
| `-i` | `--issue` | Description of the problem |
|
|
118
|
+
| `-f` | `--fix` | Suggested solution |
|
|
119
|
+
| `-o` | `--out` | Save generated markdown to a specific file |
|
|
120
|
+
| `-p` | `--path` | File path context of code under review |
|
|
121
|
+
| `-l` | `--line` | Line number or range (e.g. `12` or `45-50`) |
|
|
122
|
+
| `--lang` | `--lang` | Programming language for code highlighting (default: `javascript`) |
|
|
123
|
+
| `--before` | `--before` | Original code snippet (Before) |
|
|
124
|
+
| `--after` | `--after` | Proposed code snippet (After) |
|
|
125
|
+
| `--ai` | `--ai` | Toggle AI-assisted polishing for constructive tone |
|
|
126
|
+
| `--github` | `--github` | Post comments directly to GitHub |
|
|
127
|
+
| `--pr` | `--pr` | The GitHub Pull Request number |
|
|
128
|
+
| `--repo` | `--repo` | GitHub repository in `owner/repo` format |
|
|
129
|
+
|
|
130
|
+
---
|
|
81
131
|
|
|
82
|
-
|
|
132
|
+
## 🛠️ Configuration (`.prsmith.json`)
|
|
83
133
|
|
|
84
|
-
|
|
134
|
+
To enable AI polishing and GitHub integration, create a `.prsmith.json` file in your home directory (`~/`) or current project working directory:
|
|
85
135
|
|
|
86
136
|
```json
|
|
87
137
|
{
|
|
138
|
+
"githubToken": "ghp_yourGitHubPersonalAccessToken",
|
|
139
|
+
"aiProvider": "gemini",
|
|
140
|
+
"aiApiKey": "AI_PROVIDER_API_KEY",
|
|
141
|
+
"aiModel": "gemini-1.5-flash",
|
|
142
|
+
"defaultBranch": "main",
|
|
88
143
|
"templates": {
|
|
89
144
|
"Nitpick": "This is just a tiny nitpick, no pressure to fix.",
|
|
90
145
|
"Security": "CRITICAL SECURITY VULNERABILITY DETECTED."
|
|
91
146
|
}
|
|
92
147
|
}
|
|
93
148
|
```
|
|
94
|
-
If you pass `-s Nitpick` (or select it in the CLI), PRSmith will automatically use your custom text!
|
|
95
149
|
|
|
96
|
-
|
|
97
|
-
<summary><b>Click to view an Example Interaction</b></summary>
|
|
150
|
+
### AI Configuration Mappings:
|
|
98
151
|
|
|
99
|
-
|
|
152
|
+
- **`aiProvider`**: `gemini` (default), `openai`, or `groq`.
|
|
153
|
+
- **`aiModel`**:
|
|
154
|
+
- Gemini default: `gemini-1.5-flash`
|
|
155
|
+
- OpenAI default: `gpt-4o-mini`
|
|
156
|
+
- Groq default: `llama-3.3-70b-versatile`
|
|
157
|
+
- Credentials can also be supplied via **Environment Variables**:
|
|
158
|
+
- `GITHUB_TOKEN`
|
|
159
|
+
- `GEMINI_API_KEY`
|
|
160
|
+
- `OPENAI_API_KEY`
|
|
161
|
+
- `GROQ_API_KEY`
|
|
100
162
|
|
|
101
|
-
|
|
163
|
+
---
|
|
102
164
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
| **Severity** | `<kbd>Critical</kbd>` |
|
|
106
|
-
| **Title** | `Scope Issue` |
|
|
107
|
-
| **Issue** | `Utility functions are nested incorrectly.` |
|
|
108
|
-
| **Suggested Fix** | `Move them to module scope.` |
|
|
165
|
+
<details>
|
|
166
|
+
<summary><b>Click to view an Example Markdown Output</b></summary>
|
|
109
167
|
|
|
110
|
-
|
|
168
|
+
<br/>
|
|
111
169
|
|
|
112
|
-
|
|
113
|
-
### Critical: Scope Issue
|
|
170
|
+
### Suggestion: Optimized Loop
|
|
114
171
|
|
|
115
|
-
The
|
|
172
|
+
The implementation works, but there may be a cleaner approach.
|
|
173
|
+
|
|
174
|
+
📁 **File:** [`src/utils/math.js:15-20`](https://github.com/tarunyaprogrammer/PRSmith/blob/main/src/utils/math.js#L15)
|
|
116
175
|
|
|
117
176
|
**Problem**
|
|
118
177
|
|
|
119
|
-
|
|
178
|
+
The current `forEach` iteration is performing multiple lookups on a large array, which has a noticeable performance overhead in hot paths.
|
|
120
179
|
|
|
121
180
|
**Suggested Fix**
|
|
122
181
|
|
|
123
|
-
|
|
182
|
+
We can optimize this by storing the length in a local variable and utilizing a standard `for-i` loop.
|
|
183
|
+
|
|
184
|
+
<details>
|
|
185
|
+
<summary>🔍 View Code Diff / Comparison</summary>
|
|
186
|
+
|
|
187
|
+
**Before:**
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
items.forEach((item) => {
|
|
191
|
+
doCalculation(item);
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**After:**
|
|
196
|
+
|
|
197
|
+
```javascript
|
|
198
|
+
const len = items.length;
|
|
199
|
+
for (let i = 0; i < len; i++) {
|
|
200
|
+
doCalculation(items[i]);
|
|
201
|
+
}
|
|
124
202
|
```
|
|
125
203
|
|
|
126
204
|
</details>
|
|
127
205
|
|
|
206
|
+
</details>
|
|
207
|
+
|
|
128
208
|
---
|
|
129
209
|
|
|
130
210
|
## Development & Contribution
|
|
@@ -152,6 +232,7 @@ npm run lint
|
|
|
152
232
|
# Format the code
|
|
153
233
|
npm run format
|
|
154
234
|
```
|
|
235
|
+
|
|
155
236
|
</details>
|
|
156
237
|
|
|
157
238
|
## License
|
package/bin/cli.js
CHANGED
|
@@ -1,64 +1,216 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import fs from
|
|
4
|
-
import path from
|
|
5
|
-
import { fileURLToPath } from
|
|
6
|
-
import chalk from
|
|
7
|
-
import { program } from
|
|
8
|
-
import clipboardy from
|
|
9
|
-
import updateNotifier from
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { program } from 'commander';
|
|
8
|
+
import clipboardy from 'clipboardy';
|
|
9
|
+
import updateNotifier from 'update-notifier';
|
|
10
|
+
import inquirer from 'inquirer';
|
|
11
|
+
import { getReviewData } from '../src/prompts.js';
|
|
12
|
+
import { generateMarkdown } from '../src/formatter.js';
|
|
13
|
+
import { loadConfig } from '../src/config.js';
|
|
14
|
+
import { polishText } from '../src/ai.js';
|
|
15
|
+
import { detectGithubRepo, postPRComment } from '../src/github.js';
|
|
16
|
+
import { runBatchReview } from '../src/batch.js';
|
|
13
17
|
|
|
14
18
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
19
|
const __dirname = path.dirname(__filename);
|
|
16
20
|
const pkg = JSON.parse(
|
|
17
|
-
fs.readFileSync(path.join(__dirname,
|
|
21
|
+
fs.readFileSync(path.join(__dirname, '../package.json'), 'utf8')
|
|
18
22
|
);
|
|
19
23
|
|
|
20
24
|
updateNotifier({ pkg }).notify();
|
|
21
25
|
|
|
26
|
+
// Define 'batch' command
|
|
22
27
|
program
|
|
23
|
-
.
|
|
24
|
-
.description(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
.command('batch')
|
|
29
|
+
.description(
|
|
30
|
+
'Start an interactive batch review loop to bundle multiple comments.'
|
|
31
|
+
)
|
|
32
|
+
.action(async () => {
|
|
33
|
+
try {
|
|
34
|
+
const config = loadConfig();
|
|
35
|
+
await runBatchReview(config);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
if (error.name === 'ExitPromptError') {
|
|
38
|
+
console.log(chalk.yellow('\nYou have quit Batch Review Mode :) \n'));
|
|
39
|
+
process.exit(0);
|
|
40
|
+
}
|
|
41
|
+
console.error(chalk.red('\nSomething went wrong in Batch Mode.\n'));
|
|
42
|
+
console.error(error);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Main program CLI options
|
|
48
|
+
program
|
|
49
|
+
.name('prsmith')
|
|
50
|
+
.description(
|
|
51
|
+
'Forge professional pull request review comments directly from the terminal.'
|
|
52
|
+
)
|
|
53
|
+
.version(pkg.version, '-v, --version', 'Output the current version')
|
|
54
|
+
.helpOption('-h, --help', 'Display help for command')
|
|
55
|
+
|
|
56
|
+
// Existing Options
|
|
57
|
+
.option(
|
|
58
|
+
'-s, --severity <level>',
|
|
59
|
+
'Severity of the issue (e.g. Critical, Major, Minor, Suggestion)'
|
|
60
|
+
)
|
|
61
|
+
.option('-t, --title <title>', 'Title of the review')
|
|
62
|
+
.option('-i, --issue <issue>', 'Description of the issue')
|
|
63
|
+
.option('-f, --fix <fix>', 'Suggested fix')
|
|
64
|
+
.option('-o, --out <file>', 'Save the output to a markdown file')
|
|
65
|
+
|
|
66
|
+
// New Options (v2.0.0)
|
|
67
|
+
.option(
|
|
68
|
+
'-p, --path <filepath>',
|
|
69
|
+
'File path context of the code being reviewed'
|
|
70
|
+
)
|
|
71
|
+
.option('-l, --line <range>', 'Line number or range (e.g. 12 or 45-50)')
|
|
72
|
+
.option(
|
|
73
|
+
'--lang <language>',
|
|
74
|
+
'Programming language for code syntax highlighting',
|
|
75
|
+
'javascript'
|
|
76
|
+
)
|
|
77
|
+
.option('--before <code>', 'Original code snippet (Before)')
|
|
78
|
+
.option('--after <code>', 'Proposed code snippet (After)')
|
|
79
|
+
.option('--ai', 'Automatically polish description and fix with AI for tone')
|
|
80
|
+
.option(
|
|
81
|
+
'--github',
|
|
82
|
+
'Post the review comment directly to a GitHub Pull Request'
|
|
83
|
+
)
|
|
84
|
+
.option('--pr <prNumber>', 'The Pull Request number to post comment to')
|
|
85
|
+
.option(
|
|
86
|
+
'--repo <owner/repo>',
|
|
87
|
+
"GitHub repository in 'owner/repo' format (otherwise auto-detected)"
|
|
88
|
+
)
|
|
89
|
+
|
|
32
90
|
.action(async (options) => {
|
|
91
|
+
// If the subcommand 'batch' is run, this main action is skipped automatically by Commander
|
|
33
92
|
try {
|
|
34
93
|
console.log(
|
|
35
|
-
chalk.cyan(
|
|
94
|
+
chalk.cyan('\nPRSmith - Professional PR Review Comment Generator\n')
|
|
36
95
|
);
|
|
37
96
|
|
|
38
97
|
const config = loadConfig();
|
|
39
|
-
|
|
98
|
+
|
|
99
|
+
// Get the rest of review data interactively or via flags
|
|
100
|
+
let data = await getReviewData(options, config);
|
|
101
|
+
|
|
102
|
+
// Perform AI Polish if requested
|
|
103
|
+
if (data.ai) {
|
|
104
|
+
console.log(chalk.yellow('\n✨ Polishing comments with AI...'));
|
|
105
|
+
data.issue = await polishText(
|
|
106
|
+
data.issue,
|
|
107
|
+
'Problem Description',
|
|
108
|
+
config
|
|
109
|
+
);
|
|
110
|
+
data.fix = await polishText(data.fix, 'Suggested Fix', config);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Generate the markdown block
|
|
40
114
|
const markdown = generateMarkdown(data, config);
|
|
41
115
|
|
|
42
|
-
console.log(chalk.green(
|
|
116
|
+
console.log(chalk.green('\nGenerated Comment:\n'));
|
|
43
117
|
console.log(markdown);
|
|
44
118
|
|
|
45
|
-
|
|
46
|
-
|
|
119
|
+
// Clipboard integration
|
|
120
|
+
try {
|
|
121
|
+
clipboardy.writeSync(markdown);
|
|
122
|
+
console.log(chalk.green('✅ Comment copied to clipboard!'));
|
|
123
|
+
} catch {
|
|
124
|
+
console.warn(
|
|
125
|
+
chalk.yellow('⚠️ Could not write to clipboard automatically.')
|
|
126
|
+
);
|
|
127
|
+
}
|
|
47
128
|
|
|
129
|
+
// Save to file if output specified
|
|
48
130
|
if (options.out) {
|
|
49
131
|
const outPath = path.resolve(process.cwd(), options.out);
|
|
50
|
-
fs.writeFileSync(outPath, markdown,
|
|
51
|
-
console.log(chalk.green(`✅ Comment saved to ${outPath}
|
|
132
|
+
fs.writeFileSync(outPath, markdown, 'utf8');
|
|
133
|
+
console.log(chalk.green(`✅ Comment saved to ${outPath}`));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Post to GitHub if specified
|
|
137
|
+
if (options.github || options.pr || options.repo) {
|
|
138
|
+
const detectedRepo = detectGithubRepo();
|
|
139
|
+
let owner = '';
|
|
140
|
+
let repoName = '';
|
|
141
|
+
|
|
142
|
+
if (options.repo) {
|
|
143
|
+
const parts = options.repo.split('/');
|
|
144
|
+
if (parts.length === 2) {
|
|
145
|
+
owner = parts[0];
|
|
146
|
+
repoName = parts[1];
|
|
147
|
+
}
|
|
148
|
+
} else if (detectedRepo) {
|
|
149
|
+
owner = detectedRepo.owner;
|
|
150
|
+
repoName = detectedRepo.repo;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const prQuestions = [];
|
|
154
|
+
if (!owner || !repoName) {
|
|
155
|
+
prQuestions.push(
|
|
156
|
+
{
|
|
157
|
+
type: 'input',
|
|
158
|
+
name: 'owner',
|
|
159
|
+
message: 'GitHub repository owner:',
|
|
160
|
+
validate: (val) => val.trim() !== '' || 'Owner is required.',
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'input',
|
|
164
|
+
name: 'repoName',
|
|
165
|
+
message: 'GitHub repository name:',
|
|
166
|
+
validate: (val) => val.trim() !== '' || 'Repo name is required.',
|
|
167
|
+
}
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!options.pr) {
|
|
172
|
+
prQuestions.push({
|
|
173
|
+
type: 'input',
|
|
174
|
+
name: 'prNumber',
|
|
175
|
+
message: 'Pull Request Number:',
|
|
176
|
+
validate: (val) =>
|
|
177
|
+
/^\d+$/.test(val.trim()) || 'PR number must be an integer.',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const prAnswers =
|
|
182
|
+
prQuestions.length > 0 ? await inquirer.prompt(prQuestions) : {};
|
|
183
|
+
|
|
184
|
+
const finalOwner = owner || prAnswers.owner;
|
|
185
|
+
const finalRepo = repoName || prAnswers.repoName;
|
|
186
|
+
const finalPr = options.pr || prAnswers.prNumber;
|
|
187
|
+
|
|
188
|
+
console.log(
|
|
189
|
+
chalk.yellow('\n🚀 Posting comment directly to GitHub PR...')
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const commentUrl = await postPRComment(
|
|
193
|
+
finalOwner,
|
|
194
|
+
finalRepo,
|
|
195
|
+
finalPr,
|
|
196
|
+
markdown,
|
|
197
|
+
config
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
console.log(
|
|
201
|
+
chalk.green(`🎉 Success! Comment posted to GitHub PR #${finalPr}`)
|
|
202
|
+
);
|
|
203
|
+
console.log(chalk.green(`🔗 Comment Link: ${commentUrl}\n`));
|
|
52
204
|
}
|
|
53
205
|
} catch (error) {
|
|
54
|
-
if (error.name ===
|
|
55
|
-
console.log(chalk.yellow(
|
|
206
|
+
if (error.name === 'ExitPromptError') {
|
|
207
|
+
console.log(chalk.yellow('\nYou have quit in b/w :) \n'));
|
|
56
208
|
process.exit(0);
|
|
57
209
|
}
|
|
58
|
-
console.error(chalk.red(
|
|
210
|
+
console.error(chalk.red('\nSomething went wrong.\n'));
|
|
59
211
|
console.error(error);
|
|
60
212
|
process.exit(1);
|
|
61
213
|
}
|
|
62
214
|
});
|
|
63
215
|
|
|
64
|
-
program.parse(process.argv);
|
|
216
|
+
program.parse(process.argv);
|
package/eslint.config.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import js from
|
|
1
|
+
import js from '@eslint/js';
|
|
2
2
|
|
|
3
3
|
export default [
|
|
4
4
|
js.configs.recommended,
|
|
5
5
|
{
|
|
6
6
|
languageOptions: {
|
|
7
|
-
ecmaVersion:
|
|
8
|
-
sourceType:
|
|
7
|
+
ecmaVersion: 'latest',
|
|
8
|
+
sourceType: 'module',
|
|
9
9
|
globals: {
|
|
10
|
-
process:
|
|
11
|
-
console:
|
|
10
|
+
process: 'readonly',
|
|
11
|
+
console: 'readonly',
|
|
12
|
+
fetch: 'readonly',
|
|
13
|
+
global: 'readonly',
|
|
12
14
|
},
|
|
13
15
|
},
|
|
14
16
|
rules: {
|
|
15
|
-
|
|
17
|
+
'no-unused-vars': 'warn',
|
|
16
18
|
},
|
|
17
19
|
},
|
|
18
20
|
];
|