threadlines 0.2.19 → 0.2.21

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.
@@ -246,7 +246,7 @@ async function checkCommand(options) {
246
246
  console.log('');
247
247
  process.exit(0);
248
248
  }
249
- console.log(chalk_1.default.green(`✓ Found ${gitDiff.changedFiles.length} changed file(s)\n`));
249
+ console.log(chalk_1.default.green(`✓ Found ${gitDiff.changedFiles.length} changed file(s) (context: ${reviewContext})\n`));
250
250
  // Log the files being sent
251
251
  for (const file of gitDiff.changedFiles) {
252
252
  logger_1.logger.info(` → ${file}`);
package/dist/git/diff.js CHANGED
@@ -190,8 +190,17 @@ async function getPRDiff(repoRoot, targetBranch, logger) {
190
190
  /**
191
191
  * Get diff for a specific commit (or HEAD if no SHA provided).
192
192
  *
193
- * Uses `git show` which works reliably with shallow clones (depth=1).
194
- * This is safer than `HEAD~1...HEAD` which requires depth >= 2.
193
+ * Fetches the parent commit on-demand to ensure git show can generate a proper diff.
194
+ * This works regardless of CI checkout depth settings (depth=1 or depth=2).
195
+ *
196
+ * Strategy:
197
+ * 1. Get parent SHA using plumbing command (git cat-file -p) to read raw commit object
198
+ * - Plumbing commands ignore .git/shallow boundaries and show actual parent SHA
199
+ * - Porcelain commands (git show) respect shallow boundaries and hide parents in shallow clones
200
+ * - This is critical for CI environments that use shallow clones (depth=1)
201
+ * 2. Parse first parent line (handles standard commits and merge commits)
202
+ * 3. Fetch parent commit if available (git fetch origin <parentSHA> --depth=1)
203
+ * 4. Use git show to get diff (now parent is available for comparison)
195
204
  *
196
205
  * Used by:
197
206
  * - All CI environments for push/commit context (GitHub, GitLab, Bitbucket, Vercel)
@@ -202,7 +211,58 @@ async function getPRDiff(repoRoot, targetBranch, logger) {
202
211
  */
203
212
  async function getCommitDiff(repoRoot, sha = 'HEAD') {
204
213
  const git = (0, simple_git_1.default)(repoRoot);
205
- // Get diff using git show
214
+ // Fetch parent commit on-demand to ensure git show can generate a proper diff
215
+ // This works regardless of CI checkout depth settings (depth=1 or depth=2)
216
+ // If parent is already available, fetch is fast/no-op; if not, we fetch it
217
+ // Get parent SHA using plumbing command (git cat-file) instead of porcelain (git show)
218
+ // Plumbing commands ignore .git/shallow boundaries and show the actual parent SHA
219
+ // Porcelain commands (git show) respect shallow boundaries and hide parents in shallow clones
220
+ // This is critical for CI environments that use shallow clones (depth=1)
221
+ let parentSha;
222
+ try {
223
+ // Use git cat-file -p to read raw commit object (plumbing command)
224
+ // This ignores shallow boundaries and shows the actual parent SHA
225
+ const commitObject = (0, child_process_1.execSync)(`git cat-file -p ${sha}`, {
226
+ encoding: 'utf-8',
227
+ cwd: repoRoot
228
+ });
229
+ // Parse commit object to find first parent line
230
+ // Standard commits have one parent; merge commits have multiple parents
231
+ // We use the first parent (standard for diffing against previous state of branch)
232
+ const lines = commitObject.split('\n');
233
+ const parentLine = lines.find(line => line.startsWith('parent '));
234
+ if (!parentLine) {
235
+ throw new Error(`Commit ${sha} has no parent (it might be the root commit of the repository)`);
236
+ }
237
+ // Extract SHA from "parent <sha>" line
238
+ parentSha = parentLine.split(' ')[1].trim();
239
+ if (!parentSha || parentSha.length !== 40) {
240
+ throw new Error(`Invalid parent SHA format: "${parentSha}"`);
241
+ }
242
+ }
243
+ catch (error) {
244
+ const errorMessage = error instanceof Error ? error.message : String(error);
245
+ throw new Error(`Failed to get parent commit SHA for ${sha}. ` +
246
+ `This is required to generate a proper diff. ` +
247
+ `Error: ${errorMessage}`);
248
+ }
249
+ // Fetch parent commit (root commits have no parent, so this won't execute for them)
250
+ if (parentSha && parentSha.length === 40) {
251
+ try {
252
+ // Fetch just this one commit (depth=1 is fine, we only need the parent)
253
+ await git.fetch(['origin', parentSha, '--depth=1']);
254
+ }
255
+ catch (error) {
256
+ const errorMessage = error instanceof Error ? error.message : String(error);
257
+ throw new Error(`Failed to fetch parent commit ${parentSha} from origin. ` +
258
+ `This is required to generate a proper diff in shallow clones. ` +
259
+ `Ensure 'origin' remote is configured and accessible. ` +
260
+ `Error: ${errorMessage}`);
261
+ }
262
+ }
263
+ // If no parent (root commit), git show will show the full commit content
264
+ // This is expected behavior for root commits
265
+ // Get diff using git show (now parent should be available)
206
266
  let diff;
207
267
  let changedFiles;
208
268
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threadlines",
3
- "version": "0.2.19",
3
+ "version": "0.2.21",
4
4
  "description": "Threadlines CLI - AI-powered linter based on your natural language documentation",
5
5
  "main": "dist/index.js",
6
6
  "bin": {