threadlines 0.2.10 → 0.2.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/git/diff.js CHANGED
@@ -7,6 +7,7 @@ exports.getCommitMessage = getCommitMessage;
7
7
  exports.getCommitAuthor = getCommitAuthor;
8
8
  exports.getCommitDiff = getCommitDiff;
9
9
  const simple_git_1 = __importDefault(require("simple-git"));
10
+ const child_process_1 = require("child_process");
10
11
  /**
11
12
  * Get commit message for a specific commit SHA
12
13
  * Returns full commit message (subject + body) or null if commit not found
@@ -26,26 +27,25 @@ async function getCommitMessage(repoRoot, sha) {
26
27
  /**
27
28
  * Get commit author name and email for a specific commit SHA or HEAD.
28
29
  *
29
- * Uses git log to extract author information from the commit.
30
+ * Uses raw git log command to extract author information.
30
31
  * Works in all environments where git is available.
31
32
  */
32
33
  async function getCommitAuthor(repoRoot, sha) {
33
- const git = (0, simple_git_1.default)(repoRoot);
34
34
  try {
35
- let logResult;
36
- if (sha) {
37
- // Use git log for specific commit SHA
38
- logResult = await git.log({ from: sha, to: sha, maxCount: 1 });
39
- }
40
- else {
41
- // Use git log for HEAD (local environment only)
42
- logResult = await git.log({ maxCount: 1 });
43
- }
44
- if (!logResult.latest) {
35
+ // Use raw git command (same as test scripts) - more reliable than simple-git API
36
+ const commitRef = sha || 'HEAD';
37
+ const command = `git log -1 --format="%an <%ae>" ${commitRef}`;
38
+ const output = (0, child_process_1.execSync)(command, {
39
+ encoding: 'utf-8',
40
+ cwd: repoRoot
41
+ }).trim();
42
+ // Parse output: "Name <email>"
43
+ const match = output.match(/^(.+?)\s*<(.+?)>$/);
44
+ if (!match) {
45
45
  return null;
46
46
  }
47
- const name = logResult.latest.author_name?.trim();
48
- const email = logResult.latest.author_email?.trim();
47
+ const name = match[1].trim();
48
+ const email = match[2].trim();
49
49
  if (!name || !email) {
50
50
  return null;
51
51
  }
@@ -83,7 +83,7 @@ async function getDiff(repoRoot) {
83
83
  const git = (0, simple_git_1.default)(repoRoot);
84
84
  const eventName = process.env.GITHUB_EVENT_NAME;
85
85
  const baseRef = process.env.GITHUB_BASE_REF;
86
- // PR Context: Fetch base branch and compare with HEAD (merge commit)
86
+ // PR Context: Only pull_request events have GITHUB_BASE_REF set
87
87
  if (eventName === 'pull_request') {
88
88
  if (!baseRef) {
89
89
  throw new Error('GitHub PR context detected but GITHUB_BASE_REF is missing. ' +
@@ -91,10 +91,19 @@ async function getDiff(repoRoot) {
91
91
  }
92
92
  // Fetch base branch on-demand (works with shallow clones)
93
93
  logger_1.logger.debug(`Fetching base branch: origin/${baseRef}`);
94
- await git.fetch(['origin', `${baseRef}:refs/remotes/origin/${baseRef}`, '--depth=1']);
95
- logger_1.logger.debug(`PR context, using origin/${baseRef}...HEAD`);
96
- const diff = await git.diff([`origin/${baseRef}...HEAD`, '-U200']);
97
- const diffSummary = await git.diffSummary([`origin/${baseRef}...HEAD`]);
94
+ try {
95
+ await git.fetch(['origin', `${baseRef}:refs/remotes/origin/${baseRef}`, '--depth=1']);
96
+ }
97
+ catch (fetchError) {
98
+ throw new Error(`Failed to fetch base branch origin/${baseRef}. ` +
99
+ `This is required for PR diff comparison. Error: ${fetchError instanceof Error ? fetchError.message : 'Unknown error'}`);
100
+ }
101
+ logger_1.logger.debug(`PR context, using origin/${baseRef}..HEAD (two dots for direct comparison)`);
102
+ // Use two dots (..) instead of three dots (...) for direct comparison
103
+ // Three dots requires finding merge base which can fail with shallow clones
104
+ // Two dots shows all changes in HEAD that aren't in origin/${baseRef}
105
+ const diff = await git.diff([`origin/${baseRef}..HEAD`, '-U200']);
106
+ const diffSummary = await git.diffSummary([`origin/${baseRef}..HEAD`]);
98
107
  const changedFiles = diffSummary.files.map(f => f.file);
99
108
  return {
100
109
  diff: diff || '',
@@ -102,13 +111,15 @@ async function getDiff(repoRoot) {
102
111
  };
103
112
  }
104
113
  // Any push (main or feature branch): Review last commit only
105
- const diff = await git.diff(['HEAD~1...HEAD', '-U200']);
106
- const diffSummary = await git.diffSummary(['HEAD~1...HEAD']);
107
- const changedFiles = diffSummary.files.map(f => f.file);
108
- return {
109
- diff: diff || '',
110
- changedFiles
111
- };
114
+ // Use git show HEAD - works with shallow clones and shows the commit diff
115
+ const diff = await git.show(['HEAD', '--format=', '--no-color', '-U200']);
116
+ // Extract changed files from git show
117
+ const showNameOnly = await git.show(['HEAD', '--name-only', '--format=', '--pretty=format:']);
118
+ const changedFiles = showNameOnly
119
+ .split('\n')
120
+ .filter(line => line.trim().length > 0)
121
+ .map(line => line.trim());
122
+ return { diff: diff || '', changedFiles };
112
123
  }
113
124
  /**
114
125
  * Gets repository name for GitHub Actions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threadlines",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "Threadlines CLI - AI-powered linter based on your natural language documentation",
5
5
  "main": "dist/index.js",
6
6
  "bin": {