UNPKG

gh-legacy

Version:

A powerful GitHub CLI tool for automatic repository ownership transfer to trusted beneficiaries after periods of inactivity

123 lines (110 loc) 4.73 kB
#!/usr/bin/env node const { Command } = require('commander'); const program = new Command(); const { init } = require('../commands/init'); const { heartbeat } = require('../commands/heartbeat'); const { addBeneficiary } = require('../commands/addBeneficiary'); const { triggerAccess } = require('../commands/triggerAccess'); const { listBeneficiaries } = require('../commands/list'); const { resendEmail } = require('../commands/resendEmail'); const encryptToken = require('../encryptToken'); const readline = require('readline'); const os = require('os'); const { execSync } = require('child_process'); require('dotenv').config(); program .name('gh-legacy') .description('GitHub Legacy Access CLI - Repository Ownership Transfer System') .version('0.1.0'); program .command('init') .description('Initialize configuration') .action(init); program .command('heartbeat') .description('Send a heartbeat signal to reset the inactivity timer') .action(heartbeat); program .command('add-beneficiary') .description('Add a trusted beneficiary for repository ownership transfer') .argument('<repo>', 'GitHub repository (owner/repo)') .argument('<email>', 'Beneficiary email address') .argument('<githubUsername>', 'Beneficiary GitHub username') .argument('<accessAfter>', 'Delay before granting access (e.g., "3 months", "1 year")') .action((repo, email, githubUsername, accessAfter) => { addBeneficiary({ repo, email, githubUsername, accessAfter }); }); program .command('trigger-access') .description('Evaluate and grant access to beneficiaries if conditions are met') .option('--auto', 'Skip confirmation prompt') .option('-d, --detail <repo>', 'Process only the specified repo (owner/repo)') .action((options) => { triggerAccess(options); }); program .command('auto-trigger') .description('Automatically check and grant access without confirmation (for scheduling)') .option('-d, --detail <repo>', 'Process only the specified repo (owner/repo)') .action(async (options) => { await triggerAccess({ ...options, auto: true }); if (options.detail) { // OS detection and scheduling const platform = os.platform(); let scheduleCmd = ''; let scheduleMsg = ''; let interval = 1; // Default interval in minutes, now set to 1 if (platform === 'win32') { // Windows: use schtasks const taskName = `GH-Legacy Auto Trigger - ${options.detail.replace('/', '-')}`; scheduleCmd = `schtasks /create /tn "${taskName}" /tr "gh-legacy auto-trigger -d ${options.detail}" /sc minute /mo ${interval}`; scheduleMsg = `Scheduled Windows Task: ${taskName} to run every ${interval} minutes.`; } else if (platform === 'linux' || platform === 'darwin') { // Linux/Mac: use crontab const cronLine = `*/${interval} * * * * gh-legacy auto-trigger -d ${options.detail}`; scheduleCmd = `echo "${cronLine}" | crontab -l 2>/dev/null | grep -v 'gh-legacy auto-trigger -d ${options.detail}' ; echo "${cronLine}" | crontab -`; scheduleMsg = `Added to crontab: ${cronLine}`; } const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question(`\nWould you like to schedule this command to run automatically every ${interval} minutes? (Y/n) `, (answer) => { if (answer.trim().toLowerCase() === 'y' || answer.trim() === '') { try { execSync(scheduleCmd, { stdio: 'inherit', shell: true }); console.log(`\n✅ ${scheduleMsg}`); } catch (err) { console.error('❌ Failed to schedule the task automatically. Please try manually.'); } } else { console.log('Skipping automatic scheduling.'); } rl.close(); }); } }); program .command('resend-email') .description('Resend emails to granted beneficiaries with updated template') .action(resendEmail); program .command('list') .description('List configured beneficiaries with detailed status') .action(listBeneficiaries); program .command('status') .description('Show current system status and pending transfers') .action(listBeneficiaries); program .command('token') .description('Configure your GitHub token for gh-legacy') .action(() => { const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('Enter your GitHub token: ', (token) => { encryptToken(token); rl.close(); }); }); program.parse();