scai
Version:
> **AI-powered CLI for local code analysis, commit message suggestions, and natural-language queries.** 100% local, private, GDPR-friendly, made in Denmark/EU with ❤️.
98 lines (97 loc) • 4.49 kB
JavaScript
import path from 'path';
import { execSync } from 'child_process';
import { Config } from '../config.js';
import { ensureGitHubAuth } from './auth.js';
import chalk from 'chalk';
/**
* Executes a Git command inside the specified working directory.
*/
function runGitCommand(cmd, cwd) {
return execSync(cmd, { cwd, encoding: 'utf-8' }).trim();
}
/**
* Retrieves the owner and repo name from the Git remote URL inside the indexDir.
* This ensures we get the correct GitHub repo owner and name, regardless of current working directory.
*/
function getRepoOwnerAndNameFromGit(indexDir) {
try {
const originUrl = runGitCommand('git config --get remote.origin.url', indexDir).trim();
console.log(`🔗 Git origin URL from '${indexDir}': ${originUrl}`);
// Handle both SSH and HTTPS formats, with or without extra slashes
// Examples:
// - git@github.com:owner/repo.git
// - git@github.com:/owner/repo.git
// - https://github.com/owner/repo.git
const match = originUrl.match(/github[^:/]*[:/]\/?(.+?)(?:\.git)?$/);
if (!match)
throw new Error("❌ Could not parse GitHub repo from origin URL.");
const [owner, repo] = match[1].split('/');
if (!owner || !repo)
throw new Error("❌ Failed to extract owner or repo name from URL.");
console.log(`✅ Parsed from Git: owner='${owner}', repo='${repo}'`);
return { owner, repo };
}
catch (error) {
console.warn(`⚠️ Failed to parse GitHub info from Git config in '${indexDir}': ${error instanceof Error ? error.message : error}`);
throw error;
}
}
/**
* Fallback: Extracts GitHub repo owner and name from the index directory path.
*/
function getRepoOwnerAndNameFromIndexDir(indexDir) {
const parts = path.resolve(indexDir).split(path.sep);
const repo = parts.pop();
const owner = parts.pop();
console.log(`📁 Parsed from indexDir: owner='${owner}', repo='${repo}'`);
return { owner, repo };
}
/**
* Get the GitHub repo details, always from the configured indexDir.
* Prefers Git config, falls back to parsing the path.
*/
export async function getRepoDetails() {
let indexDir = path.normalize(Config.getIndexDir()); // Fetch the current indexDir
const currentDir = path.normalize(process.cwd()); // Get the current working directory
if (!indexDir) {
console.log("❌ indexDir is not configured. Setting up a new index for the current directory...");
// Automatically set the index directory for the current directory
await setIndexDirForCurrentDir(currentDir);
// Now that the indexDir is set, fetch it again
indexDir = Config.getIndexDir();
}
console.log(chalk.yellow(`📦 Resolving GitHub repo info from indexDir: ${indexDir}`));
// Check if the current directory is the same as the index directory
if (path.resolve(currentDir) !== path.resolve(indexDir)) {
console.log(`🚧 Current directory is not the index directory. Setting up new index...`);
// Use the existing functionality to set up a new index directory
await setIndexDirForCurrentDir(currentDir);
// Now update indexDir to the newly set one
indexDir = Config.getIndexDir(); // Re-fetch the updated indexDir
}
// Ensure the repository authentication is available
await ensureAuthCredentials();
// Proceed with the normal flow to fetch the repo details
try {
return getRepoOwnerAndNameFromGit(indexDir); // Try fetching from Git config
}
catch {
console.log("🔁 Falling back to extracting from indexDir path...");
return getRepoOwnerAndNameFromIndexDir(indexDir); // Fallback if Git config fails
}
}
async function setIndexDirForCurrentDir(currentDir) {
console.log(`🔧 Setting up index directory for the current directory: ${currentDir}`);
// Use the existing scai index set functionality to set the index directory
await Config.setIndexDir(currentDir);
// After setting the index, verify the directory is set correctly
const indexDir = Config.getIndexDir();
console.log(`✅ Index directory set to: ${indexDir}`);
}
async function ensureAuthCredentials() {
const token = await ensureGitHubAuth();
if (!token) {
throw new Error('❌ GitHub authentication token not found. Please authenticate first.');
}
console.log('✅ GitHub authentication credentials are valid.');
}