/ src / commands / repo.ts
repo.ts
  1  import { Command } from 'commander';
  2  import { get, post, request } from '../http.js';
  3  import { confirm } from '@inquirer/prompts';
  4  import ora from 'ora';
  5  
  6  export function repoCommand(): Command {
  7    const repo = new Command('repo').description('Work with AtomGit repositories');
  8  
  9    repo
 10      .command('create <name>')
 11      .description('Create a new repository')
 12      .option('-d, --description <desc>', 'Description of the repository')
 13      .option('--public', 'Make the new repository public')
 14      .option('--private', 'Make the new repository private')
 15      .action(async (name: string, options: { description?: string; public?: boolean; private?: boolean }) => {
 16        const spinner = ora('Creating repository...').start();
 17  
 18        const body = {
 19          name,
 20          description: options.description || '',
 21          private: options.private ?? false,
 22          auto_init: true
 23        };
 24  
 25        try {
 26          const result = await post('/user/repos', body) as { html_url?: string; full_name?: string };
 27          spinner.succeed(`Created repository ${result.full_name}`);
 28          // eslint-disable-next-line no-console
 29          console.log(`\n  ${result.html_url}`);
 30        } catch (error) {
 31          spinner.fail('Failed to create repository');
 32          // eslint-disable-next-line no-console
 33          console.error(error instanceof Error ? error.message : error);
 34          process.exitCode = 1;
 35        }
 36      });
 37  
 38    repo
 39      .command('delete <repository>')
 40      .description('Delete a repository')
 41      .option('-y, --yes', 'Skip confirmation prompt')
 42      .action(async (repository: string, options: { yes?: boolean }) => {
 43        if (!options.yes) {
 44          const confirmed = await confirm({
 45            message: `Are you sure you want to delete ${repository}? This cannot be undone.`,
 46            default: false
 47          });
 48          if (!confirmed) {
 49            // eslint-disable-next-line no-console
 50            console.log('Aborted.');
 51            return;
 52          }
 53        }
 54  
 55        const spinner = ora(`Deleting ${repository}...`).start();
 56  
 57        try {
 58          const response = await request(`/repos/${repository}`, { method: 'DELETE' });
 59          if (response.ok || response.status === 204) {
 60            spinner.succeed(`Deleted repository ${repository}`);
 61          } else {
 62            throw new Error(`HTTP ${response.status}: ${response.statusText}`);
 63          }
 64        } catch (error) {
 65          spinner.fail('Failed to delete repository');
 66          // eslint-disable-next-line no-console
 67          console.error(error instanceof Error ? error.message : error);
 68          process.exitCode = 1;
 69        }
 70      });
 71  
 72    repo
 73      .command('list')
 74      .description('List your repositories')
 75      .action(async () => {
 76        try {
 77          // AtomGit API v5 endpoint for user repos
 78          const data = await get('/user/repos');
 79          // eslint-disable-next-line no-console
 80          console.log(JSON.stringify(data, null, 2));
 81        } catch (error) {
 82          // eslint-disable-next-line no-console
 83          console.error('Failed to list repos:', error instanceof Error ? error.message : error);
 84          process.exitCode = 1;
 85        }
 86      });
 87  
 88    repo
 89      .command('view')
 90      .description('View repository details')
 91      .argument('[owner/repo]', 'Repository in owner/repo format')
 92      .action(async (repoPath?: string) => {
 93        try {
 94          if (!repoPath) {
 95            // eslint-disable-next-line no-console
 96            console.error('Repository path required (e.g., owner/repo)');
 97            process.exitCode = 1;
 98            return;
 99          }
100          // AtomGit API v5 endpoint
101          const data = await get(`/repos/${repoPath}`);
102          // eslint-disable-next-line no-console
103          console.log(JSON.stringify(data, null, 2));
104        } catch (error) {
105          // eslint-disable-next-line no-console
106          console.error('Failed to view repo:', error instanceof Error ? error.message : error);
107          process.exitCode = 1;
108        }
109      });
110  
111    return repo;
112  }