@renfeng/ai-code-review 1.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/LICENSE +21 -0
- package/README.md +77 -0
- package/dist/api/gitlab-api.d.ts +63 -0
- package/dist/api/gitlab-api.d.ts.map +1 -0
- package/dist/api/gitlab-api.js +218 -0
- package/dist/api/gitlab-api.js.map +1 -0
- package/dist/bin/index.d.ts +10 -0
- package/dist/bin/index.d.ts.map +1 -0
- package/dist/bin/index.js +57 -0
- package/dist/bin/index.js.map +1 -0
- package/dist/config/glab-config.loader.d.ts +14 -0
- package/dist/config/glab-config.loader.d.ts.map +1 -0
- package/dist/config/glab-config.loader.js +87 -0
- package/dist/config/glab-config.loader.js.map +1 -0
- package/dist/errors/error-handler.d.ts +45 -0
- package/dist/errors/error-handler.d.ts.map +1 -0
- package/dist/errors/error-handler.js +134 -0
- package/dist/errors/error-handler.js.map +1 -0
- package/dist/logging/index.d.ts +2 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +2 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.service.d.ts +34 -0
- package/dist/logging/logger.service.d.ts.map +1 -0
- package/dist/logging/logger.service.js +91 -0
- package/dist/logging/logger.service.js.map +1 -0
- package/dist/servers/git-server.d.ts +17 -0
- package/dist/servers/git-server.d.ts.map +1 -0
- package/dist/servers/git-server.js +73 -0
- package/dist/servers/git-server.js.map +1 -0
- package/dist/servers/gitlab-server.d.ts +18 -0
- package/dist/servers/gitlab-server.d.ts.map +1 -0
- package/dist/servers/gitlab-server.js +102 -0
- package/dist/servers/gitlab-server.js.map +1 -0
- package/dist/services/git-tools.service.d.ts +111 -0
- package/dist/services/git-tools.service.d.ts.map +1 -0
- package/dist/services/git-tools.service.js +157 -0
- package/dist/services/git-tools.service.js.map +1 -0
- package/dist/services/review-tools.service.d.ts +77 -0
- package/dist/services/review-tools.service.d.ts.map +1 -0
- package/dist/services/review-tools.service.js +289 -0
- package/dist/services/review-tools.service.js.map +1 -0
- package/dist/tools/git-tools.d.ts +8 -0
- package/dist/tools/git-tools.d.ts.map +1 -0
- package/dist/tools/git-tools.js +161 -0
- package/dist/tools/git-tools.js.map +1 -0
- package/dist/tools/gitlab-tools.d.ts +8 -0
- package/dist/tools/gitlab-tools.d.ts.map +1 -0
- package/dist/tools/gitlab-tools.js +155 -0
- package/dist/tools/gitlab-tools.js.map +1 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ai-code-review contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# AI Code Review
|
|
2
|
+
|
|
3
|
+
A [Kiro power](https://kiro.dev/docs/powers/) for AI-assisted code review automation with reusable skills.
|
|
4
|
+
|
|
5
|
+
## What's Included
|
|
6
|
+
|
|
7
|
+
### Power: `code-review`
|
|
8
|
+
|
|
9
|
+
Two MCP servers from the `ai-code-review` npm package:
|
|
10
|
+
- `git` — platform-agnostic git operations (clone, diff, show, log, grep)
|
|
11
|
+
- `gitlab` — GitLab API tools (MR metadata, draft notes, publish, todos)
|
|
12
|
+
|
|
13
|
+
### Skills
|
|
14
|
+
|
|
15
|
+
| Skill | Description | Install URL |
|
|
16
|
+
|-------|-------------|-------------|
|
|
17
|
+
| `code-change-review` | Platform-agnostic diff analysis. Traces callers, types, imports, tests. Produces structured findings JSON. | `skills/code-change-review` |
|
|
18
|
+
| `gitlab-mr-review` | End-to-end GitLab MR review. Clones, analyzes, posts draft notes, publishes with verdict. Supports batch reviews. | `skills/gitlab-mr-review` |
|
|
19
|
+
| `gitlab-todo-triage` | GitLab todo list cleanup. Marks merged/closed/draft MRs as done, delegates open MRs for review. | `skills/gitlab-todo-triage` |
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
### Power
|
|
24
|
+
|
|
25
|
+
In Kiro: Powers panel → Add power from GitHub → paste this repo URL.
|
|
26
|
+
|
|
27
|
+
Or for local development: Powers panel → Add power from Local Path → select this directory.
|
|
28
|
+
|
|
29
|
+
### Skills
|
|
30
|
+
|
|
31
|
+
Each skill can be imported independently:
|
|
32
|
+
|
|
33
|
+
In Kiro: Agent Steering & Skills → `+` → Import a skill → GitHub → paste the skill subdirectory URL:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
https://github.com/<user>/<repo>/tree/main/skills/code-change-review
|
|
37
|
+
https://github.com/<user>/<repo>/tree/main/skills/gitlab-mr-review
|
|
38
|
+
https://github.com/<user>/<repo>/tree/main/skills/gitlab-todo-triage
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Prerequisites
|
|
42
|
+
|
|
43
|
+
- Node.js 18+ (for `npx` to run the MCP servers)
|
|
44
|
+
- `GITLAB_TOKEN` configured for the `gitlab` server (or resolvable from `glab` config)
|
|
45
|
+
- SSH keys configured for git clone operations
|
|
46
|
+
|
|
47
|
+
## MCP Server Configuration
|
|
48
|
+
|
|
49
|
+
The power uses `npx @renfeng/ai-code-review@latest` to run the MCP servers. After installing the power, the servers are configured automatically:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"git": {
|
|
55
|
+
"command": "npx",
|
|
56
|
+
"args": ["-y", "@renfeng/ai-code-review@latest", "git"]
|
|
57
|
+
},
|
|
58
|
+
"gitlab": {
|
|
59
|
+
"command": "npx",
|
|
60
|
+
"args": ["-y", "@renfeng/ai-code-review@latest", "gitlab"],
|
|
61
|
+
"env": {}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Agent Setup
|
|
68
|
+
|
|
69
|
+
The `gitlab-mr-review` skill delegates code analysis to a `Code Change Reviewer` subagent. The power's onboarding instructions (in POWER.md) include the full agent definition to copy into `.kiro/agents/code-change-reviewer.md`.
|
|
70
|
+
|
|
71
|
+
## Contributing
|
|
72
|
+
|
|
73
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). If this project helps you, share your experience — what worked, what could be better.
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
MIT
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitLab API client for review-related operations.
|
|
3
|
+
*
|
|
4
|
+
* Trimmed from auto-reviewers — only methods used by ReviewToolsService are kept.
|
|
5
|
+
*/
|
|
6
|
+
import { Logger } from '../logging/logger.service.js';
|
|
7
|
+
export interface GitLabConfig {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
token: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class GitLabAPI {
|
|
12
|
+
private baseUrl;
|
|
13
|
+
private token;
|
|
14
|
+
private logger;
|
|
15
|
+
constructor(config: GitLabConfig, logger?: Logger);
|
|
16
|
+
private httpGet;
|
|
17
|
+
private httpPost;
|
|
18
|
+
private httpPut;
|
|
19
|
+
private httpDelete;
|
|
20
|
+
getMergeRequest(project: string, mr: number): Promise<{
|
|
21
|
+
source_branch: string;
|
|
22
|
+
target_branch: string;
|
|
23
|
+
} | null>;
|
|
24
|
+
getMergeRequestMetadata(project: string, mr: number): Promise<{
|
|
25
|
+
source_branch: string;
|
|
26
|
+
target_branch: string;
|
|
27
|
+
}>;
|
|
28
|
+
getMergeRequestVersions(project: string, mr: number): Promise<Array<{
|
|
29
|
+
head_commit_sha: string;
|
|
30
|
+
base_commit_sha: string;
|
|
31
|
+
start_commit_sha: string;
|
|
32
|
+
}>>;
|
|
33
|
+
getDiscussions(project: string, mr: number): Promise<unknown[]>;
|
|
34
|
+
resolveDiscussion(project: string, mr: number, discussionId: string): Promise<void>;
|
|
35
|
+
getDraftNotes(project: string, mr: number): Promise<Array<{
|
|
36
|
+
id: number;
|
|
37
|
+
note: string;
|
|
38
|
+
line_code?: string | null;
|
|
39
|
+
position?: {
|
|
40
|
+
new_path?: string;
|
|
41
|
+
old_path?: string;
|
|
42
|
+
new_line?: number | null;
|
|
43
|
+
old_line?: number | null;
|
|
44
|
+
};
|
|
45
|
+
}>>;
|
|
46
|
+
postDraftNote(project: string, mr: number, body: Record<string, unknown>): Promise<{
|
|
47
|
+
id: number;
|
|
48
|
+
line_code: string | null;
|
|
49
|
+
}>;
|
|
50
|
+
deleteDraftNote(project: string, mr: number, draftNoteId: number): Promise<void>;
|
|
51
|
+
bulkPublishDraftNotes(project: string, mr: number): Promise<boolean>;
|
|
52
|
+
getTodos(state?: string): Promise<unknown[]>;
|
|
53
|
+
markTodoDone(todoId: number): Promise<{
|
|
54
|
+
id: number;
|
|
55
|
+
state: string;
|
|
56
|
+
}>;
|
|
57
|
+
getCurrentUser(): Promise<{
|
|
58
|
+
username: string;
|
|
59
|
+
id: number;
|
|
60
|
+
}>;
|
|
61
|
+
postNote(project: string, mr: number, body: string): Promise<unknown>;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=gitlab-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab-api.d.ts","sourceRoot":"","sources":["../../src/api/gitlab-api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAGtD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,MAAM;YAMnC,OAAO;YAwBP,QAAQ;YAkBR,OAAO;YAkBP,UAAU;IAgBlB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAM9G,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IAM/G,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAQpJ,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAY/D,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnF,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;IAM5N,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAK5H,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKhF,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmCpE,QAAQ,CAAC,KAAK,SAAY,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAY/C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAOpE,cAAc,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAQ3D,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAI5E"}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitLab API client for review-related operations.
|
|
3
|
+
*
|
|
4
|
+
* Trimmed from auto-reviewers — only methods used by ReviewToolsService are kept.
|
|
5
|
+
*/
|
|
6
|
+
import { Logger } from '../logging/logger.service.js';
|
|
7
|
+
import { ErrorHandler } from '../errors/error-handler.js';
|
|
8
|
+
export class GitLabAPI {
|
|
9
|
+
baseUrl;
|
|
10
|
+
token;
|
|
11
|
+
logger;
|
|
12
|
+
constructor(config, logger) {
|
|
13
|
+
this.baseUrl = `${config.baseUrl}/api/v4`;
|
|
14
|
+
this.token = config.token;
|
|
15
|
+
this.logger = logger || new Logger('GitLabAPI');
|
|
16
|
+
}
|
|
17
|
+
async httpGet(url, accept = "application/json") {
|
|
18
|
+
return ErrorHandler.withRetry(async () => {
|
|
19
|
+
this.logger.debug('HTTP GET request', { url });
|
|
20
|
+
const response = await fetch(url, {
|
|
21
|
+
headers: { Accept: accept, Authorization: `Bearer ${this.token}` },
|
|
22
|
+
});
|
|
23
|
+
if (response.ok) {
|
|
24
|
+
const data = await response.json();
|
|
25
|
+
this.logger.debug('HTTP GET success', { url, status: response.status });
|
|
26
|
+
return { data, nextPage: response.headers.get("x-next-page") || undefined };
|
|
27
|
+
}
|
|
28
|
+
if (response.status === 404) {
|
|
29
|
+
this.logger.debug('HTTP GET not found', { url, status: 404 });
|
|
30
|
+
return { data: null };
|
|
31
|
+
}
|
|
32
|
+
let errorDetails = "";
|
|
33
|
+
try {
|
|
34
|
+
const errorBody = await response.json();
|
|
35
|
+
errorDetails = `: ${JSON.stringify(errorBody)}`;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
try {
|
|
39
|
+
errorDetails = `: ${await response.text()}`;
|
|
40
|
+
}
|
|
41
|
+
catch { /* ignore */ }
|
|
42
|
+
}
|
|
43
|
+
const error = new Error(`${response.status} ${response.statusText}${errorDetails}`);
|
|
44
|
+
this.logger.error('HTTP GET failed', error, { url, status: response.status });
|
|
45
|
+
throw error;
|
|
46
|
+
}, { maxRetries: 3, delayMs: 1000, backoffMultiplier: 2 });
|
|
47
|
+
}
|
|
48
|
+
async httpPost(url, body) {
|
|
49
|
+
return ErrorHandler.withRetry(async () => {
|
|
50
|
+
this.logger.debug('HTTP POST request', { url });
|
|
51
|
+
const response = await fetch(url, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` },
|
|
54
|
+
body: JSON.stringify(body),
|
|
55
|
+
});
|
|
56
|
+
if (response.ok) {
|
|
57
|
+
const text = await response.text();
|
|
58
|
+
return text ? JSON.parse(text) : {};
|
|
59
|
+
}
|
|
60
|
+
let details = '';
|
|
61
|
+
try {
|
|
62
|
+
details = `: ${await response.text()}`;
|
|
63
|
+
}
|
|
64
|
+
catch { /* ignore */ }
|
|
65
|
+
throw new Error(`POST ${url} failed: ${response.status} ${response.statusText}${details}`);
|
|
66
|
+
}, { maxRetries: 2, delayMs: 1000, backoffMultiplier: 2 });
|
|
67
|
+
}
|
|
68
|
+
async httpPut(url, body) {
|
|
69
|
+
return ErrorHandler.withRetry(async () => {
|
|
70
|
+
this.logger.debug('HTTP PUT request', { url });
|
|
71
|
+
const response = await fetch(url, {
|
|
72
|
+
method: 'PUT',
|
|
73
|
+
headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` },
|
|
74
|
+
body: JSON.stringify(body),
|
|
75
|
+
});
|
|
76
|
+
if (response.ok) {
|
|
77
|
+
const text = await response.text();
|
|
78
|
+
return text ? JSON.parse(text) : {};
|
|
79
|
+
}
|
|
80
|
+
let details = '';
|
|
81
|
+
try {
|
|
82
|
+
details = `: ${await response.text()}`;
|
|
83
|
+
}
|
|
84
|
+
catch { /* ignore */ }
|
|
85
|
+
throw new Error(`PUT ${url} failed: ${response.status} ${response.statusText}${details}`);
|
|
86
|
+
}, { maxRetries: 2, delayMs: 1000, backoffMultiplier: 2 });
|
|
87
|
+
}
|
|
88
|
+
async httpDelete(url) {
|
|
89
|
+
return ErrorHandler.withRetry(async () => {
|
|
90
|
+
this.logger.debug('HTTP DELETE request', { url });
|
|
91
|
+
const response = await fetch(url, {
|
|
92
|
+
method: 'DELETE',
|
|
93
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
94
|
+
});
|
|
95
|
+
if (response.ok)
|
|
96
|
+
return;
|
|
97
|
+
let details = '';
|
|
98
|
+
try {
|
|
99
|
+
details = `: ${await response.text()}`;
|
|
100
|
+
}
|
|
101
|
+
catch { /* ignore */ }
|
|
102
|
+
throw new Error(`DELETE ${url} failed: ${response.status} ${response.statusText}${details}`);
|
|
103
|
+
}, { maxRetries: 2, delayMs: 1000, backoffMultiplier: 2 });
|
|
104
|
+
}
|
|
105
|
+
// --- MR Metadata ---
|
|
106
|
+
async getMergeRequest(project, mr) {
|
|
107
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}`;
|
|
108
|
+
const { data } = await this.httpGet(url);
|
|
109
|
+
return data;
|
|
110
|
+
}
|
|
111
|
+
async getMergeRequestMetadata(project, mr) {
|
|
112
|
+
const data = await this.getMergeRequest(project, mr);
|
|
113
|
+
if (!data)
|
|
114
|
+
throw new Error(`MR !${mr} not found in project ${project}`);
|
|
115
|
+
return { source_branch: data.source_branch, target_branch: data.target_branch };
|
|
116
|
+
}
|
|
117
|
+
async getMergeRequestVersions(project, mr) {
|
|
118
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/versions`;
|
|
119
|
+
const { data } = await this.httpGet(url);
|
|
120
|
+
return data || [];
|
|
121
|
+
}
|
|
122
|
+
// --- Discussions ---
|
|
123
|
+
async getDiscussions(project, mr) {
|
|
124
|
+
const discussions = [];
|
|
125
|
+
let page = 1;
|
|
126
|
+
do {
|
|
127
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/discussions?per_page=100&page=${page}`;
|
|
128
|
+
const { data, nextPage } = await this.httpGet(url);
|
|
129
|
+
if (data)
|
|
130
|
+
discussions.push(...data);
|
|
131
|
+
page = nextPage ? parseInt(nextPage) : 0;
|
|
132
|
+
} while (page);
|
|
133
|
+
return discussions;
|
|
134
|
+
}
|
|
135
|
+
async resolveDiscussion(project, mr, discussionId) {
|
|
136
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/discussions/${discussionId}`;
|
|
137
|
+
await this.httpPut(url, { resolved: true });
|
|
138
|
+
}
|
|
139
|
+
// --- Draft Notes ---
|
|
140
|
+
async getDraftNotes(project, mr) {
|
|
141
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/draft_notes`;
|
|
142
|
+
const { data } = await this.httpGet(url);
|
|
143
|
+
return data || [];
|
|
144
|
+
}
|
|
145
|
+
async postDraftNote(project, mr, body) {
|
|
146
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/draft_notes`;
|
|
147
|
+
return this.httpPost(url, body);
|
|
148
|
+
}
|
|
149
|
+
async deleteDraftNote(project, mr, draftNoteId) {
|
|
150
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/draft_notes/${draftNoteId}`;
|
|
151
|
+
await this.httpDelete(url);
|
|
152
|
+
}
|
|
153
|
+
async bulkPublishDraftNotes(project, mr) {
|
|
154
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/draft_notes/bulk_publish`;
|
|
155
|
+
try {
|
|
156
|
+
await this.httpPost(url, {});
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
catch (bulkErr) {
|
|
160
|
+
this.logger.warn('bulk_publish failed, falling back to individual publish', {
|
|
161
|
+
project, mr, error: bulkErr instanceof Error ? bulkErr.message : String(bulkErr),
|
|
162
|
+
});
|
|
163
|
+
try {
|
|
164
|
+
const drafts = await this.getDraftNotes(project, mr);
|
|
165
|
+
if (drafts.length === 0)
|
|
166
|
+
return true;
|
|
167
|
+
let published = 0;
|
|
168
|
+
for (const draft of drafts) {
|
|
169
|
+
try {
|
|
170
|
+
const pubUrl = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/draft_notes/${draft.id}/publish`;
|
|
171
|
+
await this.httpPut(pubUrl, {});
|
|
172
|
+
published++;
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
this.logger.warn(`Failed to publish draft ${draft.id}`, {
|
|
176
|
+
error: err instanceof Error ? err.message : String(err),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
this.logger.info(`Individual publish fallback: ${published}/${drafts.length} drafts published`);
|
|
181
|
+
return published === drafts.length;
|
|
182
|
+
}
|
|
183
|
+
catch (fallbackErr) {
|
|
184
|
+
this.logger.error('Individual publish fallback also failed', fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr)));
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// --- Todos ---
|
|
190
|
+
async getTodos(state = 'pending') {
|
|
191
|
+
const todos = [];
|
|
192
|
+
let page = 1;
|
|
193
|
+
do {
|
|
194
|
+
const url = `${this.baseUrl}/todos?state=${state}&per_page=100&page=${page}`;
|
|
195
|
+
const { data, nextPage } = await this.httpGet(url);
|
|
196
|
+
if (data)
|
|
197
|
+
todos.push(...data);
|
|
198
|
+
page = nextPage ? parseInt(nextPage) : 0;
|
|
199
|
+
} while (page);
|
|
200
|
+
return todos;
|
|
201
|
+
}
|
|
202
|
+
async markTodoDone(todoId) {
|
|
203
|
+
const url = `${this.baseUrl}/todos/${todoId}/mark_as_done`;
|
|
204
|
+
return this.httpPost(url, {});
|
|
205
|
+
}
|
|
206
|
+
// --- Current User ---
|
|
207
|
+
async getCurrentUser() {
|
|
208
|
+
const url = `${this.baseUrl}/user`;
|
|
209
|
+
const { data } = await this.httpGet(url);
|
|
210
|
+
return data;
|
|
211
|
+
}
|
|
212
|
+
// --- Post note (for slash commands like /approve, /request_changes) ---
|
|
213
|
+
async postNote(project, mr, body) {
|
|
214
|
+
const url = `${this.baseUrl}/projects/${encodeURIComponent(project)}/merge_requests/${mr}/notes`;
|
|
215
|
+
return this.httpPost(url, { body });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=gitlab-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitlab-api.js","sourceRoot":"","sources":["../../src/api/gitlab-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ai-code-review entry point
|
|
4
|
+
*
|
|
5
|
+
* Routes to the git or gitlab MCP server based on the subcommand:
|
|
6
|
+
* ai-code-review git → Git MCP server
|
|
7
|
+
* ai-code-review gitlab → GitLab MCP server
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ai-code-review entry point
|
|
4
|
+
*
|
|
5
|
+
* Routes to the git or gitlab MCP server based on the subcommand:
|
|
6
|
+
* ai-code-review git → Git MCP server
|
|
7
|
+
* ai-code-review gitlab → GitLab MCP server
|
|
8
|
+
*/
|
|
9
|
+
import { config } from 'dotenv';
|
|
10
|
+
config();
|
|
11
|
+
function displayHelp() {
|
|
12
|
+
console.log(`
|
|
13
|
+
ai-code-review
|
|
14
|
+
|
|
15
|
+
USAGE:
|
|
16
|
+
ai-code-review <SUBCOMMAND>
|
|
17
|
+
|
|
18
|
+
SUBCOMMANDS:
|
|
19
|
+
git Start the Git MCP server (clone, diff, show, log, grep)
|
|
20
|
+
gitlab Start the GitLab MCP server (MR metadata, draft notes, publish, todos)
|
|
21
|
+
|
|
22
|
+
EXAMPLES:
|
|
23
|
+
npx @renfeng/ai-code-review git
|
|
24
|
+
npx @renfeng/ai-code-review gitlab
|
|
25
|
+
`);
|
|
26
|
+
}
|
|
27
|
+
async function main() {
|
|
28
|
+
const subcommand = process.argv[2];
|
|
29
|
+
if (!subcommand || subcommand === '--help' || subcommand === '-h') {
|
|
30
|
+
displayHelp();
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
if (subcommand === 'git') {
|
|
34
|
+
const { GitMCPServer } = await import('../servers/git-server.js');
|
|
35
|
+
const server = new GitMCPServer();
|
|
36
|
+
process.on('SIGINT', async () => { await server.shutdown(); process.exit(0); });
|
|
37
|
+
process.on('SIGTERM', async () => { await server.shutdown(); process.exit(0); });
|
|
38
|
+
await server.run();
|
|
39
|
+
}
|
|
40
|
+
else if (subcommand === 'gitlab') {
|
|
41
|
+
const { GitLabMCPServer } = await import('../servers/gitlab-server.js');
|
|
42
|
+
const server = new GitLabMCPServer();
|
|
43
|
+
process.on('SIGINT', async () => { await server.shutdown(); process.exit(0); });
|
|
44
|
+
process.on('SIGTERM', async () => { await server.shutdown(); process.exit(0); });
|
|
45
|
+
await server.run();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error(`Error: Unknown subcommand: ${subcommand}`);
|
|
49
|
+
console.error('Available subcommands: git, gitlab');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
main().catch((error) => {
|
|
54
|
+
console.error('Fatal error:', error.message);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":";AAEA;;;;;;GAMG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,MAAM,EAAE,CAAC;AAET,SAAS,WAAW;IAClB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;CAab,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEnC,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAClE,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAElC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;SAAM,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QAErC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,8BAA8B,UAAU,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads GitLab host and token from glab CLI configuration.
|
|
3
|
+
*
|
|
4
|
+
* glab stores its config as YAML at a platform-specific path:
|
|
5
|
+
* macOS: ~/Library/Application Support/glab-cli/config.yml
|
|
6
|
+
* Linux: ~/.config/glab-cli/config.yml
|
|
7
|
+
* Windows: %APPDATA%/glab-cli/config.yml
|
|
8
|
+
*/
|
|
9
|
+
export interface GlabHostConfig {
|
|
10
|
+
gitlabUrl: string;
|
|
11
|
+
gitlabToken: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function loadGlabConfig(hostname?: string): GlabHostConfig | null;
|
|
14
|
+
//# sourceMappingURL=glab-config.loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glab-config.loader.d.ts","sourceRoot":"","sources":["../../src/config/glab-config.loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAkDD,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAsBvE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads GitLab host and token from glab CLI configuration.
|
|
3
|
+
*
|
|
4
|
+
* glab stores its config as YAML at a platform-specific path:
|
|
5
|
+
* macOS: ~/Library/Application Support/glab-cli/config.yml
|
|
6
|
+
* Linux: ~/.config/glab-cli/config.yml
|
|
7
|
+
* Windows: %APPDATA%/glab-cli/config.yml
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
10
|
+
import { join } from 'node:path';
|
|
11
|
+
import { homedir, platform } from 'node:os';
|
|
12
|
+
function getGlabConfigPath() {
|
|
13
|
+
const home = homedir();
|
|
14
|
+
switch (platform()) {
|
|
15
|
+
case 'darwin':
|
|
16
|
+
return join(home, 'Library', 'Application Support', 'glab-cli', 'config.yml');
|
|
17
|
+
case 'win32':
|
|
18
|
+
return join(process.env.APPDATA ?? join(home, 'AppData', 'Roaming'), 'glab-cli', 'config.yml');
|
|
19
|
+
default:
|
|
20
|
+
return join(process.env.XDG_CONFIG_HOME ?? join(home, '.config'), 'glab-cli', 'config.yml');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function parseGlabConfig(content) {
|
|
24
|
+
const hosts = new Map();
|
|
25
|
+
const lines = content.split('\n');
|
|
26
|
+
let inHosts = false;
|
|
27
|
+
let currentHost = null;
|
|
28
|
+
let currentEntry = {};
|
|
29
|
+
for (const line of lines) {
|
|
30
|
+
if (/^hosts:\s*$/.test(line)) {
|
|
31
|
+
inHosts = true;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!inHosts)
|
|
35
|
+
continue;
|
|
36
|
+
if (line.length > 0 && !line.startsWith(' ') && !line.startsWith('\t')) {
|
|
37
|
+
if (currentHost)
|
|
38
|
+
hosts.set(currentHost, currentEntry);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
const hostMatch = line.match(/^ {4}(\S+):\s*$/);
|
|
42
|
+
if (hostMatch) {
|
|
43
|
+
if (currentHost)
|
|
44
|
+
hosts.set(currentHost, currentEntry);
|
|
45
|
+
currentHost = hostMatch[1];
|
|
46
|
+
currentEntry = {};
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (currentHost) {
|
|
50
|
+
const propMatch = line.match(/^ {8}(\w[\w_-]*):\s*(.+)$/);
|
|
51
|
+
if (propMatch) {
|
|
52
|
+
const [, key, rawValue] = propMatch;
|
|
53
|
+
const value = rawValue.replace(/^!!null\s*/, '').replace(/^["']|["']$/g, '').trim();
|
|
54
|
+
if (key === 'token')
|
|
55
|
+
currentEntry.token = value;
|
|
56
|
+
if (key === 'api_protocol')
|
|
57
|
+
currentEntry.apiProtocol = value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (currentHost && !hosts.has(currentHost))
|
|
62
|
+
hosts.set(currentHost, currentEntry);
|
|
63
|
+
return hosts;
|
|
64
|
+
}
|
|
65
|
+
export function loadGlabConfig(hostname) {
|
|
66
|
+
const configPath = getGlabConfigPath();
|
|
67
|
+
if (!existsSync(configPath))
|
|
68
|
+
return null;
|
|
69
|
+
let content;
|
|
70
|
+
try {
|
|
71
|
+
content = readFileSync(configPath, 'utf-8');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
if (!hostname) {
|
|
77
|
+
const hostMatch = content.match(/^host:\s*(\S+)/m);
|
|
78
|
+
hostname = hostMatch?.[1] ?? 'gitlab.com';
|
|
79
|
+
}
|
|
80
|
+
const hosts = parseGlabConfig(content);
|
|
81
|
+
const entry = hosts.get(hostname);
|
|
82
|
+
if (!entry?.token)
|
|
83
|
+
return null;
|
|
84
|
+
const protocol = entry.apiProtocol ?? 'https';
|
|
85
|
+
return { gitlabUrl: `${protocol}://${hostname}`, gitlabToken: entry.token };
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=glab-config.loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glab-config.loader.js","sourceRoot":"","sources":["../../src/config/glab-config.loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAO5C,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACnB,KAAK,QAAQ;YACX,OAAO,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAChF,KAAK,OAAO;YACV,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QACjG;YACE,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;IAChG,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoD,CAAC;IAC1E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,WAAW,GAAkB,IAAI,CAAC;IACtC,IAAI,YAAY,GAA6C,EAAE,CAAC;IAEhE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;YAAC,SAAS;QAAC,CAAC;QAC3D,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACvE,IAAI,WAAW;gBAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YACtD,MAAM;QACR,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAChD,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,WAAW;gBAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;YACtD,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC3B,YAAY,GAAG,EAAE,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC1D,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC;gBACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpF,IAAI,GAAG,KAAK,OAAO;oBAAE,YAAY,CAAC,KAAK,GAAG,KAAK,CAAC;gBAChD,IAAI,GAAG,KAAK,cAAc;oBAAE,YAAY,CAAC,WAAW,GAAG,KAAK,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,WAAW,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACjF,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,QAAiB;IAC9C,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACnD,QAAQ,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC;IAC5C,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IAE/B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,IAAI,OAAO,CAAC;IAC9C,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,MAAM,QAAQ,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handler
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent error handling with retry logic and clear error messages.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MCPError extends Error {
|
|
7
|
+
code: string;
|
|
8
|
+
details?: Record<string, unknown> | undefined;
|
|
9
|
+
cause?: Error | undefined;
|
|
10
|
+
constructor(message: string, code: string, details?: Record<string, unknown> | undefined, cause?: Error | undefined);
|
|
11
|
+
toJSON(): Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare enum ErrorCategory {
|
|
14
|
+
CONFIGURATION = "configuration",
|
|
15
|
+
VALIDATION = "validation",
|
|
16
|
+
GIT_OPERATION = "git_operation",
|
|
17
|
+
API_CALL = "api_call",
|
|
18
|
+
NETWORK = "network",
|
|
19
|
+
PERMISSION = "permission",
|
|
20
|
+
NOT_FOUND = "not_found",
|
|
21
|
+
INTERNAL = "internal"
|
|
22
|
+
}
|
|
23
|
+
export interface RetryOptions {
|
|
24
|
+
maxRetries: number;
|
|
25
|
+
delayMs: number;
|
|
26
|
+
backoffMultiplier: number;
|
|
27
|
+
onRetry?: (attempt: number, error: Error) => void;
|
|
28
|
+
}
|
|
29
|
+
export declare const DEFAULT_RETRY_OPTIONS: RetryOptions;
|
|
30
|
+
export declare class ErrorHandler {
|
|
31
|
+
private static logger;
|
|
32
|
+
static withRetry<T>(operation: () => Promise<T>, options?: Partial<RetryOptions>): Promise<T>;
|
|
33
|
+
static isTransient(error: Error): boolean;
|
|
34
|
+
static formatError(error: Error): string;
|
|
35
|
+
static toMCPError(error: unknown, code: string, details?: Record<string, unknown>): MCPError;
|
|
36
|
+
static wrap<T>(operation: () => Promise<T>, errorCode: string, _errorMessage: string, details?: Record<string, unknown>): Promise<T>;
|
|
37
|
+
private static delay;
|
|
38
|
+
static configurationError(message: string, details?: Record<string, unknown>): MCPError;
|
|
39
|
+
static validationError(message: string, details?: Record<string, unknown>): MCPError;
|
|
40
|
+
static gitOperationError(message: string, details?: Record<string, unknown>, cause?: Error): MCPError;
|
|
41
|
+
static apiCallError(message: string, details?: Record<string, unknown>, cause?: Error): MCPError;
|
|
42
|
+
static notFoundError(message: string, details?: Record<string, unknown>): MCPError;
|
|
43
|
+
static permissionError(message: string, details?: Record<string, unknown>): MCPError;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/errors/error-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,qBAAa,QAAS,SAAQ,KAAK;IAGxB,IAAI,EAAE,MAAM;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjC,KAAK,CAAC,EAAE,KAAK;gBAHpB,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA,EACjC,KAAK,CAAC,EAAE,KAAK,YAAA;IAStB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMlC;AAED,oBAAY,aAAa;IACvB,aAAa,kBAAkB;IAC/B,UAAU,eAAe;IACzB,aAAa,kBAAkB;IAC/B,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,qBAAqB,EAAE,YAInC,CAAC;AAEF,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA8B;WAEtC,SAAS,CAAC,CAAC,EACtB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,GAAE,OAAO,CAAC,YAAY,CAAM,GAClC,OAAO,CAAC,CAAC,CAAC;IA4Bb,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAYzC,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAYxC,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ;WAM/E,IAAI,CAAC,CAAC,EACjB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvG,OAAO,CAAC,CAAC,CAAC;IAUb,OAAO,CAAC,MAAM,CAAC,KAAK;IAIpB,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ;IAIvF,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ;IAIpF,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,QAAQ;IAIrG,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,QAAQ;IAIhG,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ;IAIlF,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ;CAGrF"}
|