@juspay/yama 2.4.2 → 2.6.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 +14 -0
- package/dist/cli/cli.js +74 -3
- package/dist/index.js +4 -0
- package/dist/v2/config/ConfigLoader.d.ts +7 -2
- package/dist/v2/config/ConfigLoader.js +29 -10
- package/dist/v2/config/DefaultConfig.js +13 -0
- package/dist/v2/core/LearningOrchestrator.js +21 -5
- package/dist/v2/core/MCPServerManager.d.ts +44 -3
- package/dist/v2/core/MCPServerManager.js +204 -6
- package/dist/v2/core/YamaV2Orchestrator.d.ts +20 -1
- package/dist/v2/core/YamaV2Orchestrator.js +168 -58
- package/dist/v2/exploration/ContextExplorerService.d.ts +11 -1
- package/dist/v2/exploration/ContextExplorerService.js +64 -12
- package/dist/v2/exploration/types.d.ts +1 -0
- package/dist/v2/learning/types.d.ts +2 -0
- package/dist/v2/memory/MemoryManager.d.ts +20 -4
- package/dist/v2/memory/MemoryManager.js +30 -5
- package/dist/v2/prompts/PromptBuilder.d.ts +10 -2
- package/dist/v2/prompts/PromptBuilder.js +70 -59
- package/dist/v2/prompts/ReviewSystemPrompt.d.ts +29 -1
- package/dist/v2/prompts/ReviewSystemPrompt.js +34 -43
- package/dist/v2/providers/ProviderToolset.d.ts +54 -0
- package/dist/v2/providers/ProviderToolset.js +399 -0
- package/dist/v2/types/config.types.d.ts +40 -9
- package/dist/v2/types/mcp.types.d.ts +105 -193
- package/dist/v2/types/mcp.types.js +9 -2
- package/dist/v2/types/v2.types.d.ts +7 -2
- package/dist/v2/utils/ProviderDetector.d.ts +57 -0
- package/dist/v2/utils/ProviderDetector.js +187 -0
- package/package.json +3 -2
|
@@ -1,212 +1,124 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP
|
|
3
|
-
*
|
|
2
|
+
* MCP (Model Context Protocol) response type definitions.
|
|
3
|
+
*
|
|
4
|
+
* These describe the shapes Yama reads back from VCS MCP tool calls
|
|
5
|
+
* (Bitbucket / GitHub pull requests, diffs, code search, Jira issues).
|
|
6
|
+
*
|
|
7
|
+
* The fictional `NeuroLinkAPI`/`callTool` interface and the unused
|
|
8
|
+
* server-management helper types were removed when the dead VCSProvider
|
|
9
|
+
* classes were deleted — only these still-used response shapes (re-exported
|
|
10
|
+
* from src/index.ts) remain.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Bitbucket/GitHub Pull Request response from a PR-read tool call
|
|
4
14
|
*/
|
|
5
|
-
export interface MCPStatus {
|
|
6
|
-
totalServers: number;
|
|
7
|
-
totalTools: number;
|
|
8
|
-
servers: MCPServerStatus[];
|
|
9
|
-
}
|
|
10
|
-
export interface MCPServerStatus {
|
|
11
|
-
id: string;
|
|
12
|
-
connected: boolean;
|
|
13
|
-
tools: string[];
|
|
14
|
-
lastHealthCheck?: Date;
|
|
15
|
-
error?: string;
|
|
16
|
-
}
|
|
17
15
|
export interface GetPullRequestResponse {
|
|
18
|
-
id
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
state: "OPEN" | "MERGED" | "DECLINED";
|
|
27
|
-
source: {
|
|
28
|
-
branch: {
|
|
29
|
-
name: string;
|
|
16
|
+
id?: number | string;
|
|
17
|
+
number?: number;
|
|
18
|
+
title?: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
state?: string;
|
|
21
|
+
source?: {
|
|
22
|
+
branch?: {
|
|
23
|
+
name?: string;
|
|
30
24
|
};
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
repository?: {
|
|
26
|
+
full_slug?: string;
|
|
33
27
|
};
|
|
34
28
|
};
|
|
35
|
-
destination
|
|
36
|
-
branch
|
|
37
|
-
name
|
|
29
|
+
destination?: {
|
|
30
|
+
branch?: {
|
|
31
|
+
name?: string;
|
|
38
32
|
};
|
|
39
|
-
|
|
40
|
-
|
|
33
|
+
repository?: {
|
|
34
|
+
full_slug?: string;
|
|
41
35
|
};
|
|
42
36
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
reviewers: Reviewer[];
|
|
46
|
-
active_comments?: Comment[];
|
|
47
|
-
file_changes?: FileChange[];
|
|
48
|
-
}
|
|
49
|
-
export interface Reviewer {
|
|
50
|
-
user: {
|
|
51
|
-
name: string;
|
|
52
|
-
displayName: string;
|
|
53
|
-
emailAddress?: string;
|
|
54
|
-
};
|
|
55
|
-
approved: boolean;
|
|
56
|
-
status: "APPROVED" | "UNAPPROVED" | "NEEDS_WORK";
|
|
57
|
-
}
|
|
58
|
-
export interface Comment {
|
|
59
|
-
id: number;
|
|
60
|
-
text: string;
|
|
61
|
-
author: {
|
|
62
|
-
name: string;
|
|
63
|
-
displayName: string;
|
|
64
|
-
};
|
|
65
|
-
createdDate: string;
|
|
66
|
-
updatedDate: string;
|
|
67
|
-
anchor?: CommentAnchor;
|
|
68
|
-
}
|
|
69
|
-
export interface CommentAnchor {
|
|
70
|
-
filePath: string;
|
|
71
|
-
lineFrom: number;
|
|
72
|
-
lineTo: number;
|
|
73
|
-
lineType: "ADDED" | "REMOVED" | "CONTEXT";
|
|
74
|
-
}
|
|
75
|
-
export interface FileChange {
|
|
76
|
-
path: string;
|
|
77
|
-
file?: string;
|
|
78
|
-
type: "ADD" | "MODIFY" | "DELETE" | "RENAME";
|
|
79
|
-
}
|
|
80
|
-
export interface DiffLine {
|
|
81
|
-
source_line: number | null;
|
|
82
|
-
destination_line: number | null;
|
|
83
|
-
type: "ADDED" | "REMOVED" | "CONTEXT";
|
|
84
|
-
content: string;
|
|
85
|
-
}
|
|
86
|
-
export interface DiffHunk {
|
|
87
|
-
source_start: number;
|
|
88
|
-
source_length: number;
|
|
89
|
-
destination_start: number;
|
|
90
|
-
destination_length: number;
|
|
91
|
-
lines: DiffLine[];
|
|
92
|
-
}
|
|
93
|
-
export interface DiffFile {
|
|
94
|
-
file_path: string;
|
|
95
|
-
old_path?: string;
|
|
96
|
-
status: "added" | "modified" | "deleted" | "renamed";
|
|
97
|
-
hunks: DiffHunk[];
|
|
98
|
-
}
|
|
99
|
-
export interface GetPullRequestDiffResponse {
|
|
100
|
-
files: DiffFile[];
|
|
101
|
-
stats?: {
|
|
102
|
-
additions: number;
|
|
103
|
-
deletions: number;
|
|
104
|
-
files_changed: number;
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
export interface AddCommentRequest {
|
|
108
|
-
workspace: string;
|
|
109
|
-
repository: string;
|
|
110
|
-
pull_request_id: number;
|
|
111
|
-
comment_text: string;
|
|
112
|
-
file_path: string;
|
|
113
|
-
line_number: number;
|
|
114
|
-
line_type: "ADDED" | "REMOVED" | "CONTEXT";
|
|
115
|
-
suggestion?: string;
|
|
116
|
-
parent_comment_id?: number;
|
|
117
|
-
}
|
|
118
|
-
export interface AddCommentResponse {
|
|
119
|
-
id: number;
|
|
120
|
-
text: string;
|
|
121
|
-
author: string;
|
|
122
|
-
createdDate: string;
|
|
123
|
-
anchor?: CommentAnchor;
|
|
124
|
-
}
|
|
125
|
-
export interface UpdatePullRequestRequest {
|
|
126
|
-
workspace: string;
|
|
127
|
-
repository: string;
|
|
128
|
-
pull_request_id: number;
|
|
129
|
-
title?: string;
|
|
130
|
-
description?: string;
|
|
131
|
-
reviewers?: string[];
|
|
132
|
-
}
|
|
133
|
-
export interface GetFileContentResponse {
|
|
134
|
-
content: string;
|
|
135
|
-
path: string;
|
|
136
|
-
size: number;
|
|
137
|
-
encoding?: string;
|
|
138
|
-
}
|
|
139
|
-
export interface ListDirectoryContentResponse {
|
|
140
|
-
path: string;
|
|
141
|
-
items: DirectoryItem[];
|
|
142
|
-
}
|
|
143
|
-
export interface DirectoryItem {
|
|
144
|
-
type: "file" | "directory";
|
|
145
|
-
path: string;
|
|
146
|
-
name: string;
|
|
147
|
-
size?: number;
|
|
148
|
-
}
|
|
149
|
-
export interface SearchCodeResponse {
|
|
150
|
-
results: SearchResult[];
|
|
151
|
-
totalCount: number;
|
|
152
|
-
}
|
|
153
|
-
export interface SearchResult {
|
|
154
|
-
file: string;
|
|
155
|
-
line: number;
|
|
156
|
-
content: string;
|
|
157
|
-
matches: string[];
|
|
158
|
-
}
|
|
159
|
-
export interface GetIssueResponse {
|
|
160
|
-
key: string;
|
|
161
|
-
id: string;
|
|
162
|
-
summary: string;
|
|
163
|
-
description: string;
|
|
164
|
-
status: {
|
|
165
|
-
name: string;
|
|
166
|
-
category: string;
|
|
37
|
+
head?: {
|
|
38
|
+
ref?: string;
|
|
167
39
|
};
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
description: string;
|
|
40
|
+
base?: {
|
|
41
|
+
ref?: string;
|
|
171
42
|
};
|
|
172
|
-
|
|
173
|
-
|
|
43
|
+
user?: {
|
|
44
|
+
login?: string;
|
|
174
45
|
};
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
emailAddress: string;
|
|
46
|
+
author?: {
|
|
47
|
+
username?: string;
|
|
178
48
|
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
49
|
+
created_on?: string;
|
|
50
|
+
createdAt?: string;
|
|
51
|
+
updated_on?: string;
|
|
52
|
+
updatedAt?: string;
|
|
53
|
+
links?: {
|
|
54
|
+
html?: {
|
|
55
|
+
href?: string;
|
|
56
|
+
};
|
|
182
57
|
};
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
customFields?: Record<string, any>;
|
|
186
|
-
}
|
|
187
|
-
export interface SearchIssuesRequest {
|
|
188
|
-
jql: string;
|
|
189
|
-
maxResults?: number;
|
|
190
|
-
startAt?: number;
|
|
191
|
-
}
|
|
192
|
-
export interface SearchIssuesResponse {
|
|
193
|
-
issues: GetIssueResponse[];
|
|
194
|
-
total: number;
|
|
195
|
-
startAt: number;
|
|
196
|
-
maxResults: number;
|
|
58
|
+
html_url?: string;
|
|
59
|
+
[key: string]: unknown;
|
|
197
60
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Pull request diff response from a diff-read tool call
|
|
63
|
+
*/
|
|
64
|
+
export interface GetPullRequestDiffResponse {
|
|
65
|
+
diffs?: Array<{
|
|
66
|
+
source?: {
|
|
67
|
+
path?: string;
|
|
68
|
+
};
|
|
69
|
+
destination?: {
|
|
70
|
+
path?: string;
|
|
71
|
+
};
|
|
72
|
+
lines?: Array<{
|
|
73
|
+
type?: string;
|
|
74
|
+
content?: string;
|
|
75
|
+
line_number?: number;
|
|
76
|
+
old_line_number?: number;
|
|
77
|
+
}>;
|
|
78
|
+
}>;
|
|
79
|
+
files?: Array<{
|
|
80
|
+
filename?: string;
|
|
81
|
+
patch?: string;
|
|
82
|
+
changes?: number;
|
|
83
|
+
additions?: number;
|
|
84
|
+
deletions?: number;
|
|
85
|
+
}>;
|
|
86
|
+
[key: string]: unknown;
|
|
201
87
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Jira issue response from an issue-read tool call
|
|
90
|
+
*/
|
|
91
|
+
export interface GetIssueResponse {
|
|
92
|
+
key?: string;
|
|
93
|
+
id?: string;
|
|
94
|
+
fields?: {
|
|
95
|
+
summary?: string;
|
|
96
|
+
description?: string;
|
|
97
|
+
status?: {
|
|
98
|
+
name?: string;
|
|
99
|
+
};
|
|
100
|
+
issuetype?: {
|
|
101
|
+
name?: string;
|
|
102
|
+
};
|
|
103
|
+
[key: string]: unknown;
|
|
207
104
|
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
105
|
+
[key: string]: unknown;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Code search response from a code-search tool call
|
|
109
|
+
*/
|
|
110
|
+
export interface SearchCodeResponse {
|
|
111
|
+
results?: Array<{
|
|
112
|
+
file?: {
|
|
113
|
+
path?: string;
|
|
114
|
+
};
|
|
115
|
+
path?: string;
|
|
116
|
+
lines?: Array<{
|
|
117
|
+
content?: string;
|
|
118
|
+
line_number?: number;
|
|
119
|
+
}>;
|
|
120
|
+
content?: string;
|
|
121
|
+
}>;
|
|
122
|
+
[key: string]: unknown;
|
|
211
123
|
}
|
|
212
124
|
//# sourceMappingURL=mcp.types.d.ts.map
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP
|
|
3
|
-
*
|
|
2
|
+
* MCP (Model Context Protocol) response type definitions.
|
|
3
|
+
*
|
|
4
|
+
* These describe the shapes Yama reads back from VCS MCP tool calls
|
|
5
|
+
* (Bitbucket / GitHub pull requests, diffs, code search, Jira issues).
|
|
6
|
+
*
|
|
7
|
+
* The fictional `NeuroLinkAPI`/`callTool` interface and the unused
|
|
8
|
+
* server-management helper types were removed when the dead VCSProvider
|
|
9
|
+
* classes were deleted — only these still-used response shapes (re-exported
|
|
10
|
+
* from src/index.ts) remain.
|
|
4
11
|
*/
|
|
5
12
|
export {};
|
|
6
13
|
//# sourceMappingURL=mcp.types.js.map
|
|
@@ -4,10 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export interface ReviewRequest {
|
|
6
6
|
mode: "pr";
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
provider?: "github" | "bitbucket";
|
|
8
|
+
workspace?: string;
|
|
9
|
+
repository?: string;
|
|
10
|
+
owner?: string;
|
|
11
|
+
repo?: string;
|
|
12
|
+
prNumber?: number;
|
|
9
13
|
pullRequestId?: number;
|
|
10
14
|
branch?: string;
|
|
15
|
+
cloneUrl?: string;
|
|
11
16
|
dryRun?: boolean;
|
|
12
17
|
verbose?: boolean;
|
|
13
18
|
configPath?: string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Detection Utility
|
|
3
|
+
* Automatically detects GitHub vs Bitbucket from environment, CLI params, or URLs
|
|
4
|
+
*/
|
|
5
|
+
import type { ReviewRequest } from "../types/v2.types.js";
|
|
6
|
+
export type VCSProvider = "github" | "bitbucket";
|
|
7
|
+
export declare class ProviderDetector {
|
|
8
|
+
/**
|
|
9
|
+
* Detect VCS provider with intelligent fallback chain
|
|
10
|
+
* Priority: GitHub env → Request params → Clone URL → Config default → Bitbucket
|
|
11
|
+
*/
|
|
12
|
+
static detect(request: ReviewRequest, env?: NodeJS.ProcessEnv, configDefault?: VCSProvider): VCSProvider;
|
|
13
|
+
/**
|
|
14
|
+
* Extract the hostname from a clone/remote URL.
|
|
15
|
+
* Supports SCP/SSH form (git@host:owner/repo, no scheme) and standard URLs.
|
|
16
|
+
* Returns a lowercased hostname, or '' if it cannot be determined.
|
|
17
|
+
*/
|
|
18
|
+
private static extractHostname;
|
|
19
|
+
/**
|
|
20
|
+
* Detect provider from a clone/remote URL.
|
|
21
|
+
*
|
|
22
|
+
* Classification is based on the parsed HOSTNAME (not substring matching) to
|
|
23
|
+
* avoid spoofing via crafted paths or hosts such as
|
|
24
|
+
* "https://github.com.evil.com/...".
|
|
25
|
+
*/
|
|
26
|
+
static detectFromUrl(url: string): VCSProvider;
|
|
27
|
+
/**
|
|
28
|
+
* Returns true when the host's first DNS label equals `label` AND the host
|
|
29
|
+
* is not a spoof where a public domain (e.g. "github.com") is embedded as a
|
|
30
|
+
* sub-label (e.g. "github.com.evil.com"). The latter is detected by a second
|
|
31
|
+
* label that is a common public TLD.
|
|
32
|
+
*/
|
|
33
|
+
private static firstLabelIs;
|
|
34
|
+
/**
|
|
35
|
+
* Extract owner from GitHub URL or context
|
|
36
|
+
* github.com:owner/repo.git → owner
|
|
37
|
+
* https://github.com/owner/repo → owner
|
|
38
|
+
*/
|
|
39
|
+
static extractGitHubOwner(url: string): string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Extract repo name from GitHub URL
|
|
42
|
+
* github.com:owner/repo.git → repo
|
|
43
|
+
* https://github.com/owner/repo → repo
|
|
44
|
+
*/
|
|
45
|
+
static extractGitHubRepo(url: string): string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Extract workspace from Bitbucket URL
|
|
48
|
+
* bitbucket.com:workspace/repo.git → workspace
|
|
49
|
+
*/
|
|
50
|
+
static extractBitbucketWorkspace(url: string): string | null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Helper to detect provider from ReviewRequest
|
|
54
|
+
* Usage: const provider = detectProvider(request);
|
|
55
|
+
*/
|
|
56
|
+
export declare function detectProvider(request: ReviewRequest, configDefault?: VCSProvider): VCSProvider;
|
|
57
|
+
//# sourceMappingURL=ProviderDetector.d.ts.map
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Detection Utility
|
|
3
|
+
* Automatically detects GitHub vs Bitbucket from environment, CLI params, or URLs
|
|
4
|
+
*/
|
|
5
|
+
export class ProviderDetector {
|
|
6
|
+
/**
|
|
7
|
+
* Detect VCS provider with intelligent fallback chain
|
|
8
|
+
* Priority: GitHub env → Request params → Clone URL → Config default → Bitbucket
|
|
9
|
+
*/
|
|
10
|
+
static detect(request, env = process.env, configDefault) {
|
|
11
|
+
// 1. Explicit provider in request
|
|
12
|
+
if (request.provider) {
|
|
13
|
+
return request.provider;
|
|
14
|
+
}
|
|
15
|
+
// 2. GitHub Actions environment
|
|
16
|
+
if (env.GITHUB_SERVER_URL ||
|
|
17
|
+
env.GITHUB_REPOSITORY ||
|
|
18
|
+
env.GITHUB_ACTION ||
|
|
19
|
+
env.GITHUB_ACTIONS === "true") {
|
|
20
|
+
return "github";
|
|
21
|
+
}
|
|
22
|
+
// 3. GitHub CLI parameters
|
|
23
|
+
if (request.owner || request.prNumber !== undefined) {
|
|
24
|
+
// If owner is provided, it's GitHub
|
|
25
|
+
if (request.owner) {
|
|
26
|
+
return "github";
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// 4. Bitbucket CLI parameters
|
|
30
|
+
if (request.workspace) {
|
|
31
|
+
return "bitbucket";
|
|
32
|
+
}
|
|
33
|
+
// 5. Clone URL detection
|
|
34
|
+
if (request.cloneUrl) {
|
|
35
|
+
return ProviderDetector.detectFromUrl(request.cloneUrl);
|
|
36
|
+
}
|
|
37
|
+
// 6. Config-level default
|
|
38
|
+
if (configDefault) {
|
|
39
|
+
return configDefault;
|
|
40
|
+
}
|
|
41
|
+
// 7. Fallback to Bitbucket (backward compatibility)
|
|
42
|
+
return "bitbucket";
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Extract the hostname from a clone/remote URL.
|
|
46
|
+
* Supports SCP/SSH form (git@host:owner/repo, no scheme) and standard URLs.
|
|
47
|
+
* Returns a lowercased hostname, or '' if it cannot be determined.
|
|
48
|
+
*/
|
|
49
|
+
static extractHostname(url) {
|
|
50
|
+
try {
|
|
51
|
+
// SCP/SSH form has no scheme: [user@]host:path (path is not //...)
|
|
52
|
+
if (!url.includes("://")) {
|
|
53
|
+
const scpMatch = url.match(/^(?:[^@/]+@)?([^/:]+):(?!\/)/);
|
|
54
|
+
if (scpMatch) {
|
|
55
|
+
return scpMatch[1].toLowerCase();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Standard URL form. Prepend a scheme if missing so URL() can parse it.
|
|
59
|
+
const withScheme = url.includes("://") ? url : `https://${url}`;
|
|
60
|
+
return new URL(withScheme).hostname.toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return "";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Detect provider from a clone/remote URL.
|
|
68
|
+
*
|
|
69
|
+
* Classification is based on the parsed HOSTNAME (not substring matching) to
|
|
70
|
+
* avoid spoofing via crafted paths or hosts such as
|
|
71
|
+
* "https://github.com.evil.com/...".
|
|
72
|
+
*/
|
|
73
|
+
static detectFromUrl(url) {
|
|
74
|
+
const host = ProviderDetector.extractHostname(url);
|
|
75
|
+
// GitHub.com and GitHub Enterprise (e.g. github.enterprise.com).
|
|
76
|
+
// The first-label check covers Enterprise hosts whose first label is
|
|
77
|
+
// literally "github" (github.enterprise.com), while rejecting spoofs
|
|
78
|
+
// like "github.com.evil.com" where "github.com" is used as a sub-label.
|
|
79
|
+
if (host === "github.com" ||
|
|
80
|
+
host.endsWith(".github.com") ||
|
|
81
|
+
ProviderDetector.firstLabelIs(host, "github")) {
|
|
82
|
+
return "github";
|
|
83
|
+
}
|
|
84
|
+
// Bitbucket.org and Bitbucket Server/Data Center variants
|
|
85
|
+
if (host === "bitbucket.org" ||
|
|
86
|
+
host.endsWith(".bitbucket.org") ||
|
|
87
|
+
ProviderDetector.firstLabelIs(host, "bitbucket")) {
|
|
88
|
+
return "bitbucket";
|
|
89
|
+
}
|
|
90
|
+
// Default to Bitbucket if unclear (backward compatibility)
|
|
91
|
+
return "bitbucket";
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns true when the host's first DNS label equals `label` AND the host
|
|
95
|
+
* is not a spoof where a public domain (e.g. "github.com") is embedded as a
|
|
96
|
+
* sub-label (e.g. "github.com.evil.com"). The latter is detected by a second
|
|
97
|
+
* label that is a common public TLD.
|
|
98
|
+
*/
|
|
99
|
+
static firstLabelIs(host, label) {
|
|
100
|
+
const labels = host.split(".");
|
|
101
|
+
if (labels[0] !== label) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
// Reject "<label>.<tld>.<...>" spoofs (e.g. github.com.evil.com).
|
|
105
|
+
const tlds = new Set(["com", "org", "net", "io", "co", "dev"]);
|
|
106
|
+
if (labels.length > 2 && tlds.has(labels[1])) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Extract owner from GitHub URL or context
|
|
113
|
+
* github.com:owner/repo.git → owner
|
|
114
|
+
* https://github.com/owner/repo → owner
|
|
115
|
+
*/
|
|
116
|
+
static extractGitHubOwner(url) {
|
|
117
|
+
try {
|
|
118
|
+
// SSH format: git@github.com:owner/repo.git
|
|
119
|
+
const sshMatch = url.match(/git@github\.com:([^/]+)\//);
|
|
120
|
+
if (sshMatch) {
|
|
121
|
+
return sshMatch[1];
|
|
122
|
+
}
|
|
123
|
+
// HTTPS format: https://github.com/owner/repo
|
|
124
|
+
const httpsMatch = url.match(/github\.com\/([^/]+)\//);
|
|
125
|
+
if (httpsMatch) {
|
|
126
|
+
return httpsMatch[1];
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Extract repo name from GitHub URL
|
|
136
|
+
* github.com:owner/repo.git → repo
|
|
137
|
+
* https://github.com/owner/repo → repo
|
|
138
|
+
*/
|
|
139
|
+
static extractGitHubRepo(url) {
|
|
140
|
+
try {
|
|
141
|
+
// SSH format: git@github.com:owner/repo.git
|
|
142
|
+
const sshMatch = url.match(/\/([^/]+?)(?:\.git)?$/);
|
|
143
|
+
if (sshMatch) {
|
|
144
|
+
return sshMatch[1];
|
|
145
|
+
}
|
|
146
|
+
// HTTPS format: https://github.com/owner/repo
|
|
147
|
+
const httpsMatch = url.match(/\/([^/]+?)(?:\.git)?$/);
|
|
148
|
+
if (httpsMatch) {
|
|
149
|
+
return httpsMatch[1];
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Extract workspace from Bitbucket URL
|
|
159
|
+
* bitbucket.com:workspace/repo.git → workspace
|
|
160
|
+
*/
|
|
161
|
+
static extractBitbucketWorkspace(url) {
|
|
162
|
+
try {
|
|
163
|
+
// SSH format: git@bitbucket.org:workspace/repo.git
|
|
164
|
+
const match = url.match(/bitbucket[^:]*:([^/]+)\//);
|
|
165
|
+
if (match) {
|
|
166
|
+
return match[1];
|
|
167
|
+
}
|
|
168
|
+
// HTTPS format: https://bitbucket.org/workspace/repo
|
|
169
|
+
const httpsMatch = url.match(/bitbucket\.org\/([^/]+)\//);
|
|
170
|
+
if (httpsMatch) {
|
|
171
|
+
return httpsMatch[1];
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Helper to detect provider from ReviewRequest
|
|
182
|
+
* Usage: const provider = detectProvider(request);
|
|
183
|
+
*/
|
|
184
|
+
export function detectProvider(request, configDefault) {
|
|
185
|
+
return ProviderDetector.detect(request, process.env, configDefault);
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=ProviderDetector.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juspay/yama",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Enterprise-grade Pull Request automation toolkit with AI-powered code review and description enhancement",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pr",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
],
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "rimraf dist && tsc && tsc-alias",
|
|
57
|
+
"build:action": "npm run build",
|
|
57
58
|
"dev": "tsx watch src/cli/cli.ts",
|
|
58
59
|
"dev:run": "tsx src/cli/cli.ts",
|
|
59
60
|
"mcp:git:server": "uvx mcp-server-git || npx -y @modelcontextprotocol/server-git",
|
|
@@ -159,7 +160,7 @@
|
|
|
159
160
|
],
|
|
160
161
|
"overrides": {
|
|
161
162
|
"@semantic-release/npm": "^13.1.2",
|
|
162
|
-
"undici": "
|
|
163
|
+
"undici": "~7.22.0"
|
|
163
164
|
}
|
|
164
165
|
},
|
|
165
166
|
"lint-staged": {
|