threadlines 0.1.10 → 0.1.12
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/dist/commands/check.js +23 -1
- package/dist/git/diff.js +24 -7
- package/dist/git/repo.js +6 -30
- package/dist/utils/ci-detection.js +3 -1
- package/package.json +1 -1
package/dist/commands/check.js
CHANGED
|
@@ -89,6 +89,9 @@ async function checkCommand(options) {
|
|
|
89
89
|
// 2. Determine review target and get git diff
|
|
90
90
|
let gitDiff;
|
|
91
91
|
let reviewContext = { type: 'local' };
|
|
92
|
+
let commitSha = undefined;
|
|
93
|
+
let commitMessage = undefined;
|
|
94
|
+
let prTitle = undefined;
|
|
92
95
|
// Validate mutually exclusive flags
|
|
93
96
|
const explicitFlags = [options.branch, options.commit, options.file, options.folder, options.files].filter(Boolean);
|
|
94
97
|
if (explicitFlags.length > 1) {
|
|
@@ -121,6 +124,12 @@ async function checkCommand(options) {
|
|
|
121
124
|
console.log(chalk_1.default.gray(`📝 Collecting git changes for commit: ${options.commit}...`));
|
|
122
125
|
gitDiff = await (0, diff_1.getCommitDiff)(repoRoot, options.commit);
|
|
123
126
|
reviewContext = { type: 'commit', value: options.commit };
|
|
127
|
+
commitSha = options.commit;
|
|
128
|
+
// Fetch commit message (reliable when we have SHA)
|
|
129
|
+
const message = await (0, diff_1.getCommitMessage)(repoRoot, options.commit);
|
|
130
|
+
if (message) {
|
|
131
|
+
commitMessage = message;
|
|
132
|
+
}
|
|
124
133
|
}
|
|
125
134
|
else {
|
|
126
135
|
// Auto-detect CI environment or use local changes
|
|
@@ -131,6 +140,10 @@ async function checkCommand(options) {
|
|
|
131
140
|
console.log(chalk_1.default.gray(`📝 Collecting git changes for ${autoTarget.type.toUpperCase()}: ${autoTarget.value}...`));
|
|
132
141
|
gitDiff = await (0, diff_1.getPRMRDiff)(repoRoot, autoTarget.sourceBranch, autoTarget.targetBranch);
|
|
133
142
|
reviewContext = { type: autoTarget.type, value: autoTarget.value };
|
|
143
|
+
// Use PR title from GitLab CI (reliable env var)
|
|
144
|
+
if (autoTarget.prTitle) {
|
|
145
|
+
prTitle = autoTarget.prTitle;
|
|
146
|
+
}
|
|
134
147
|
}
|
|
135
148
|
else if (autoTarget.type === 'branch') {
|
|
136
149
|
// Branch: use branch vs base
|
|
@@ -143,6 +156,12 @@ async function checkCommand(options) {
|
|
|
143
156
|
console.log(chalk_1.default.gray(`📝 Collecting git changes for commit: ${autoTarget.value}...`));
|
|
144
157
|
gitDiff = await (0, diff_1.getCommitDiff)(repoRoot, autoTarget.value);
|
|
145
158
|
reviewContext = { type: 'commit', value: autoTarget.value };
|
|
159
|
+
commitSha = autoTarget.value;
|
|
160
|
+
// Fetch commit message (reliable when we have SHA)
|
|
161
|
+
const message = await (0, diff_1.getCommitMessage)(repoRoot, autoTarget.value);
|
|
162
|
+
if (message) {
|
|
163
|
+
commitMessage = message;
|
|
164
|
+
}
|
|
146
165
|
}
|
|
147
166
|
else {
|
|
148
167
|
// Fallback: local development
|
|
@@ -210,7 +229,10 @@ async function checkCommand(options) {
|
|
|
210
229
|
apiKey,
|
|
211
230
|
account,
|
|
212
231
|
repoName: repoName || undefined,
|
|
213
|
-
branchName: branchName || undefined
|
|
232
|
+
branchName: branchName || undefined,
|
|
233
|
+
commitSha: commitSha,
|
|
234
|
+
commitMessage: commitMessage,
|
|
235
|
+
prTitle: prTitle
|
|
214
236
|
});
|
|
215
237
|
// 7. Display results (with filtering if --full not specified)
|
|
216
238
|
displayResults(response, options.full || false);
|
package/dist/git/diff.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getGitDiff = getGitDiff;
|
|
7
7
|
exports.getBranchDiff = getBranchDiff;
|
|
8
|
+
exports.getCommitMessage = getCommitMessage;
|
|
8
9
|
exports.getCommitDiff = getCommitDiff;
|
|
9
10
|
exports.getPRMRDiff = getPRMRDiff;
|
|
10
11
|
const simple_git_1 = __importDefault(require("simple-git"));
|
|
@@ -23,11 +24,11 @@ async function getGitDiff(repoRoot) {
|
|
|
23
24
|
let diff;
|
|
24
25
|
if (status.staged.length > 0) {
|
|
25
26
|
// Use staged changes
|
|
26
|
-
diff = await git.diff(['--cached']);
|
|
27
|
+
diff = await git.diff(['--cached', '-U200']);
|
|
27
28
|
}
|
|
28
29
|
else if (status.files.length > 0) {
|
|
29
30
|
// Use unstaged changes
|
|
30
|
-
diff = await git.diff();
|
|
31
|
+
diff = await git.diff(['-U200']);
|
|
31
32
|
}
|
|
32
33
|
else {
|
|
33
34
|
// No changes
|
|
@@ -73,7 +74,7 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
73
74
|
const previousCommit = await git.revparse(['HEAD~1']).catch(() => null);
|
|
74
75
|
if (previousCommit) {
|
|
75
76
|
// Use commit-based diff instead
|
|
76
|
-
const diff = await git.diff([`${previousCommit}..HEAD
|
|
77
|
+
const diff = await git.diff([`${previousCommit}..HEAD`, '-U200']);
|
|
77
78
|
const diffSummary = await git.diffSummary([`${previousCommit}..HEAD`]);
|
|
78
79
|
const changedFiles = diffSummary.files.map(f => f.file);
|
|
79
80
|
return {
|
|
@@ -135,7 +136,7 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
135
136
|
}
|
|
136
137
|
// Get diff between base and branch (cumulative diff of all commits)
|
|
137
138
|
// Format: git diff base...branch (three-dot notation finds common ancestor)
|
|
138
|
-
const diff = await git.diff([`${base}...${branchName}
|
|
139
|
+
const diff = await git.diff([`${base}...${branchName}`, '-U200']);
|
|
139
140
|
// Get list of changed files
|
|
140
141
|
const diffSummary = await git.diffSummary([`${base}...${branchName}`]);
|
|
141
142
|
const changedFiles = diffSummary.files.map(f => f.file);
|
|
@@ -144,6 +145,22 @@ async function getBranchDiff(repoRoot, branchName, baseBranch) {
|
|
|
144
145
|
changedFiles
|
|
145
146
|
};
|
|
146
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Get commit message for a specific commit SHA
|
|
150
|
+
* Returns full commit message (subject + body) or null if commit not found
|
|
151
|
+
*/
|
|
152
|
+
async function getCommitMessage(repoRoot, sha) {
|
|
153
|
+
const git = (0, simple_git_1.default)(repoRoot);
|
|
154
|
+
try {
|
|
155
|
+
// Get full commit message (subject + body)
|
|
156
|
+
const message = await git.show([sha, '--format=%B', '--no-patch']);
|
|
157
|
+
return message.trim() || null;
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
// Commit not found or invalid
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
147
164
|
/**
|
|
148
165
|
* Get diff for a specific commit
|
|
149
166
|
*/
|
|
@@ -160,7 +177,7 @@ async function getCommitDiff(repoRoot, sha) {
|
|
|
160
177
|
let changedFiles;
|
|
161
178
|
try {
|
|
162
179
|
// Get diff using git show
|
|
163
|
-
diff = await git.show([sha, '--format=', '--no-color']);
|
|
180
|
+
diff = await git.show([sha, '--format=', '--no-color', '-U200']);
|
|
164
181
|
// Get changed files using git show --name-only
|
|
165
182
|
const commitFiles = await git.show([sha, '--name-only', '--format=', '--pretty=format:']);
|
|
166
183
|
changedFiles = commitFiles
|
|
@@ -171,7 +188,7 @@ async function getCommitDiff(repoRoot, sha) {
|
|
|
171
188
|
catch (error) {
|
|
172
189
|
// Fallback: try git diff format
|
|
173
190
|
try {
|
|
174
|
-
diff = await git.diff([`${sha}^..${sha}
|
|
191
|
+
diff = await git.diff([`${sha}^..${sha}`, '-U200']);
|
|
175
192
|
// Get files from diff summary
|
|
176
193
|
const diffSummary = await git.diffSummary([`${sha}^..${sha}`]);
|
|
177
194
|
changedFiles = diffSummary.files.map(f => f.file);
|
|
@@ -197,7 +214,7 @@ async function getPRMRDiff(repoRoot, sourceBranch, targetBranch) {
|
|
|
197
214
|
}
|
|
198
215
|
// Get diff between target and source (cumulative diff)
|
|
199
216
|
// Format: git diff target...source (three-dot notation finds common ancestor)
|
|
200
|
-
const diff = await git.diff([`${targetBranch}...${sourceBranch}
|
|
217
|
+
const diff = await git.diff([`${targetBranch}...${sourceBranch}`, '-U200']);
|
|
201
218
|
// Get list of changed files
|
|
202
219
|
const diffSummary = await git.diffSummary([`${targetBranch}...${sourceBranch}`]);
|
|
203
220
|
const changedFiles = diffSummary.files.map(f => f.file);
|
package/dist/git/repo.js
CHANGED
|
@@ -7,46 +7,22 @@ exports.getRepoName = getRepoName;
|
|
|
7
7
|
exports.getBranchName = getBranchName;
|
|
8
8
|
const simple_git_1 = __importDefault(require("simple-git"));
|
|
9
9
|
/**
|
|
10
|
-
* Gets
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* Gets the raw git remote URL from origin.
|
|
11
|
+
* Returns the URL exactly as Git provides it - no parsing or normalization.
|
|
12
|
+
* Server-side can normalize variations if needed based on actual data.
|
|
13
13
|
*/
|
|
14
14
|
async function getRepoName(repoRoot) {
|
|
15
15
|
const git = (0, simple_git_1.default)(repoRoot);
|
|
16
16
|
try {
|
|
17
17
|
const remotes = await git.getRemotes(true);
|
|
18
18
|
const origin = remotes.find(r => r.name === 'origin');
|
|
19
|
-
if (!origin) {
|
|
20
|
-
console.log(' [DEBUG] No origin remote found');
|
|
19
|
+
if (!origin || !origin.refs?.fetch) {
|
|
21
20
|
return null;
|
|
22
21
|
}
|
|
23
|
-
if
|
|
24
|
-
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
const url = origin.refs.fetch;
|
|
28
|
-
console.log(` [DEBUG] Git remote URL: ${url}`);
|
|
29
|
-
// Parse repo name from common URL formats:
|
|
30
|
-
// - https://github.com/user/repo.git
|
|
31
|
-
// - git@github.com:user/repo.git
|
|
32
|
-
// - https://gitlab.com/user/repo.git
|
|
33
|
-
// - git@gitlab.com:user/repo.git
|
|
34
|
-
const patterns = [
|
|
35
|
-
/(?:github\.com|gitlab\.com)[\/:]([^\/]+\/[^\/]+?)(?:\.git)?$/,
|
|
36
|
-
/([^\/]+\/[^\/]+?)(?:\.git)?$/
|
|
37
|
-
];
|
|
38
|
-
for (const pattern of patterns) {
|
|
39
|
-
const match = url.match(pattern);
|
|
40
|
-
if (match && match[1]) {
|
|
41
|
-
console.log(` [DEBUG] Matched repo name: ${match[1]}`);
|
|
42
|
-
return match[1];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
console.log(' [DEBUG] No pattern matched the remote URL');
|
|
46
|
-
return null;
|
|
22
|
+
// Return raw URL - let server handle normalization if needed
|
|
23
|
+
return origin.refs.fetch;
|
|
47
24
|
}
|
|
48
25
|
catch (error) {
|
|
49
|
-
console.log(` [DEBUG] Error getting repo name: ${error.message}`);
|
|
50
26
|
return null;
|
|
51
27
|
}
|
|
52
28
|
}
|
|
@@ -22,12 +22,14 @@ function getAutoReviewTarget() {
|
|
|
22
22
|
const targetBranch = process.env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME;
|
|
23
23
|
const sourceBranch = process.env.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME;
|
|
24
24
|
const mrNumber = process.env.CI_MERGE_REQUEST_IID;
|
|
25
|
+
const mrTitle = process.env.CI_MERGE_REQUEST_TITLE; // Reliable GitLab CI env var
|
|
25
26
|
if (targetBranch && sourceBranch && mrNumber) {
|
|
26
27
|
return {
|
|
27
28
|
type: 'mr',
|
|
28
29
|
value: mrNumber,
|
|
29
30
|
sourceBranch,
|
|
30
|
-
targetBranch
|
|
31
|
+
targetBranch,
|
|
32
|
+
prTitle: mrTitle || undefined // Only include if present
|
|
31
33
|
};
|
|
32
34
|
}
|
|
33
35
|
}
|