UNPKG

ubon

Version:

Security scanner for AI-generated apps (Cursor, Lovable, Windsurf, v0). Catches hardcoded secrets, prompt injection, hallucinated imports, Server Actions / Edge runtime mistakes, and the vibe-coded vulnerabilities traditional linters miss.

97 lines 3.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getChangedFilesSince = getChangedFilesSince; exports.getRecentCommitHashes = getRecentCommitHashes; exports.ensureGitRepo = ensureGitRepo; exports.createBranchCommitPush = createBranchCommitPush; exports.tryOpenPullRequest = tryOpenPullRequest; const child_process_1 = require("child_process"); function getChangedFilesSince(ref, cwd) { try { const out = (0, child_process_1.execFileSync)('git', ['diff', '--name-only', ref], { cwd, encoding: 'utf8' }); return out.split('\n').map(s => s.trim()).filter(Boolean); } catch { return []; } } function getRecentCommitHashes(depth, cwd) { try { const out = (0, child_process_1.execFileSync)('git', ['rev-list', `--max-count=${depth}`, 'HEAD'], { cwd, encoding: 'utf8' }); return out.split('\n').map(s => s.trim()).filter(Boolean); } catch { return []; } } function ensureGitRepo(cwd) { try { (0, child_process_1.execFileSync)('git', ['rev-parse', '--is-inside-work-tree'], { cwd, stdio: 'ignore' }); return true; } catch { return false; } } function isValidBranchName(branch) { const res = (0, child_process_1.spawnSync)('git', ['check-ref-format', '--branch', branch], { encoding: 'utf8', stdio: 'ignore' }); return res.status === 0; } function createBranchCommitPush(options) { const base = options.baseBranch || 'main'; const branch = options.featureBranch; if (!isValidBranchName(branch)) return { pushed: false }; try { // Ensure up-to-date try { (0, child_process_1.execFileSync)('git', ['fetch', '--all', '--prune'], { cwd: options.cwd, stdio: 'ignore' }); } catch { } // Create and switch to feature branch (0, child_process_1.execFileSync)('git', ['checkout', '-B', branch, base], { cwd: options.cwd, stdio: 'inherit' }); // Stage and commit (0, child_process_1.execFileSync)('git', ['add', '-A'], { cwd: options.cwd, stdio: 'inherit' }); // If nothing to commit, skip commit step try { (0, child_process_1.execFileSync)('git', ['commit', '-m', options.title], { cwd: options.cwd, stdio: 'inherit' }); } catch { } // Push branch (0, child_process_1.execFileSync)('git', ['push', '-u', 'origin', branch], { cwd: options.cwd, stdio: 'inherit' }); // Get repo url const remote = (0, child_process_1.execFileSync)('git', ['config', '--get', 'remote.origin.url'], { cwd: options.cwd, encoding: 'utf8' }).trim(); const remoteUrl = remote.replace(/^git@github.com:/, 'https://github.com/').replace(/\.git$/, ''); return { pushed: true, remoteUrl }; } catch { return { pushed: false }; } } function tryOpenPullRequest(cwd, base, head, title, body) { // Try with GitHub CLI if available try { (0, child_process_1.execFileSync)('gh', ['--version'], { cwd, stdio: 'ignore' }); const args = ['pr', 'create', '-B', base, '-H', head, '-t', title]; if (body) args.push('-b', body); (0, child_process_1.execFileSync)('gh', args, { cwd, stdio: 'inherit' }); // Best-effort; URL is printed by gh return { created: true }; } catch { } // Fallback: provide compare URL try { const remote = (0, child_process_1.execFileSync)('git', ['config', '--get', 'remote.origin.url'], { cwd, encoding: 'utf8' }).trim(); const remoteUrl = remote.replace(/^git@github.com:/, 'https://github.com/').replace(/\.git$/, ''); const url = `${remoteUrl}/compare/${base}...${head}?expand=1&title=${encodeURIComponent(title)}`; return { created: false, url }; } catch { return { created: false }; } } //# sourceMappingURL=git.js.map