scai 0.1.77 → 0.1.79

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/README.md CHANGED
@@ -139,7 +139,7 @@ SCAI supports an integrated review flow for GitHub pull requests. To get started
139
139
  scai git review
140
140
  ```
141
141
 
142
- Use `-a` to list all PRs that require your review:
142
+ Use `-a` to list all PRs that require a review:
143
143
 
144
144
  ```sh
145
145
  scai git review -a
@@ -365,7 +365,7 @@ export async function reviewPullRequestCmd(branch = 'main', showAll = false) {
365
365
  try {
366
366
  const token = await ensureGitHubAuth();
367
367
  const username = await getGitHubUsername(token);
368
- const { owner, repo } = getRepoDetails();
368
+ const { owner, repo } = await getRepoDetails();
369
369
  const prsWithReviewRequested = await getPullRequestsForReview(token, owner, repo, username, branch, !showAll);
370
370
  if (prsWithReviewRequested.length === 0)
371
371
  return;
package/dist/config.js CHANGED
@@ -97,8 +97,6 @@ export const Config = {
97
97
  await this.setRepoIndexDir(scaiRepoRoot, absPath); // Set the indexDir for the repo
98
98
  // Ensure base folders exist
99
99
  fs.mkdirSync(scaiRepoRoot, { recursive: true });
100
- fs.mkdirSync(path.join(scaiRepoRoot, 'summaries'), { recursive: true });
101
- fs.mkdirSync(path.join(scaiRepoRoot, 'metadata'), { recursive: true });
102
100
  // Init DB if not exists
103
101
  const dbPath = path.join(scaiRepoRoot, 'db.sqlite');
104
102
  if (!fs.existsSync(dbPath)) {
@@ -50,7 +50,7 @@ export async function fetchPullRequestDiff(pr, token) {
50
50
  }
51
51
  export async function submitReview(prNumber, body, event, comments) {
52
52
  const token = await ensureGitHubAuth();
53
- const { owner, repo } = getRepoDetails();
53
+ const { owner, repo } = await getRepoDetails();
54
54
  const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`;
55
55
  const res = await fetch(url, {
56
56
  method: 'POST',
@@ -61,11 +61,40 @@ export async function submitReview(prNumber, body, event, comments) {
61
61
  body: JSON.stringify({
62
62
  body,
63
63
  event,
64
- comments
64
+ comments,
65
65
  }),
66
66
  });
67
67
  if (!res.ok) {
68
68
  const errorText = await res.text();
69
+ // Attempt to parse error body
70
+ let parsed = {};
71
+ try {
72
+ parsed = JSON.parse(errorText);
73
+ }
74
+ catch (_) {
75
+ // leave as raw text if parsing fails
76
+ }
77
+ const knownErrors = Array.isArray(parsed.errors) ? parsed.errors.join('; ') : '';
78
+ // Handle known error cases
79
+ if (res.status === 422) {
80
+ if (knownErrors.includes('Can not approve your own pull request')) {
81
+ console.warn(`⚠️ Skipping approval: You cannot approve your own pull request.`);
82
+ return;
83
+ }
84
+ if (knownErrors.includes('Comments may only be specified on pull requests with a diff')) {
85
+ console.warn(`⚠️ Cannot post comments: PR has no diff.`);
86
+ return;
87
+ }
88
+ if (knownErrors.includes('path is missing') || knownErrors.includes('line is missing')) {
89
+ console.warn(`⚠️ Some inline comments are missing a path or line number. Skipping review.`);
90
+ return;
91
+ }
92
+ if (knownErrors.includes('Position is invalid') || knownErrors.includes('line must be part of the diff')) {
93
+ console.warn(`⚠️ One or more comment positions are invalid — probably outside the diff. Skipping review.`);
94
+ return;
95
+ }
96
+ }
97
+ // Unknown error
69
98
  throw new Error(`Failed to submit review: ${res.status} ${res.statusText} - ${errorText}`);
70
99
  }
71
100
  console.log(`✅ Submitted ${event} review for PR #${prNumber}`);
@@ -73,7 +102,7 @@ export async function submitReview(prNumber, body, event, comments) {
73
102
  export async function postInlineComment(prNumber, commitId, path, body, line, side = 'RIGHT', reviewId = null // Associate with a review if available
74
103
  ) {
75
104
  const token = await ensureGitHubAuth();
76
- const { owner, repo } = getRepoDetails();
105
+ const { owner, repo } = await getRepoDetails();
77
106
  const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/comments`;
78
107
  const res = await fetch(url, {
79
108
  method: 'POST',
@@ -96,26 +125,3 @@ export async function postInlineComment(prNumber, commitId, path, body, line, si
96
125
  }
97
126
  console.log(`💬 Posted inline comment on ${path}:${line}`);
98
127
  }
99
- export async function createReviewForPR(prNumber, body, event = 'COMMENT') {
100
- const token = await ensureGitHubAuth();
101
- const { owner, repo } = getRepoDetails();
102
- const url = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/reviews`;
103
- const res = await fetch(url, {
104
- method: 'POST',
105
- headers: {
106
- Authorization: `token ${token}`,
107
- Accept: 'application/vnd.github.v3+json',
108
- },
109
- body: JSON.stringify({
110
- body,
111
- event,
112
- }),
113
- });
114
- if (!res.ok) {
115
- const errorText = await res.text();
116
- throw new Error(`Failed to create review: ${res.status} ${res.statusText} - ${errorText}`);
117
- }
118
- const review = await res.json();
119
- console.log(`✅ Created review for PR #${prNumber}`);
120
- return review.id; // Return the review ID to be used for inline comments
121
- }
@@ -2,7 +2,7 @@ import { ensureGitHubAuth } from './auth.js';
2
2
  import { getRepoDetails } from './repo.js';
3
3
  export async function validateGitHubTokenAgainstRepo() {
4
4
  const token = await ensureGitHubAuth();
5
- const { owner, repo } = getRepoDetails();
5
+ const { owner, repo } = await getRepoDetails();
6
6
  const response = await fetch(`https://api.github.com/repos/${owner}/${repo}`, {
7
7
  headers: {
8
8
  Authorization: `Bearer ${token}`,
@@ -1,6 +1,7 @@
1
1
  import path from 'path';
2
2
  import { execSync } from 'child_process';
3
3
  import { Config } from '../config.js';
4
+ import { ensureGitHubAuth } from './auth.js';
4
5
  /**
5
6
  * Executes a Git command inside the specified working directory.
6
7
  */
@@ -41,17 +42,44 @@ function getRepoOwnerAndNameFromIndexDir(indexDir) {
41
42
  * Get the GitHub repo details, always from the configured indexDir.
42
43
  * Prefers Git config, falls back to parsing the path.
43
44
  */
44
- export function getRepoDetails() {
45
- const indexDir = Config.getIndexDir();
45
+ export async function getRepoDetails() {
46
+ let indexDir = Config.getIndexDir(); // Fetch the current indexDir
47
+ const currentDir = process.cwd(); // Get the current working directory
46
48
  if (!indexDir) {
47
49
  throw new Error("❌ indexDir is not configured.");
48
50
  }
49
51
  console.log(`📦 Resolving GitHub repo info from indexDir: ${indexDir}`);
52
+ // Check if the current directory is the same as the index directory
53
+ if (currentDir !== indexDir) {
54
+ console.log(`🚧 Current directory is not the index directory. Setting up new index...`);
55
+ // Use the existing functionality to set up a new index directory
56
+ await setIndexDirForCurrentDir(currentDir);
57
+ // Now update indexDir to the newly set one
58
+ indexDir = Config.getIndexDir(); // Re-fetch the updated indexDir
59
+ }
60
+ // Ensure the repository authentication is available
61
+ ensureAuthCredentials();
62
+ // Proceed with the normal flow to fetch the repo details
50
63
  try {
51
- return getRepoOwnerAndNameFromGit(indexDir);
64
+ return getRepoOwnerAndNameFromGit(indexDir); // Try fetching from Git config
52
65
  }
53
66
  catch {
54
67
  console.log("🔁 Falling back to extracting from indexDir path...");
55
- return getRepoOwnerAndNameFromIndexDir(indexDir);
68
+ return getRepoOwnerAndNameFromIndexDir(indexDir); // Fallback if Git config fails
69
+ }
70
+ }
71
+ async function setIndexDirForCurrentDir(currentDir) {
72
+ console.log(`🔧 Setting up index directory for the current directory: ${currentDir}`);
73
+ // Use the existing scai index set functionality to set the index directory
74
+ await Config.setIndexDir(currentDir);
75
+ // After setting the index, verify the directory is set correctly
76
+ const indexDir = Config.getIndexDir();
77
+ console.log(`✅ Index directory set to: ${indexDir}`);
78
+ }
79
+ async function ensureAuthCredentials() {
80
+ const token = await ensureGitHubAuth();
81
+ if (!token) {
82
+ throw new Error('❌ GitHub authentication token not found. Please authenticate first.');
56
83
  }
84
+ console.log('✅ GitHub authentication credentials are valid.');
57
85
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scai",
3
- "version": "0.1.77",
3
+ "version": "0.1.79",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "scai": "./dist/index.js"