@fromsvenwithlove/devops-issues-cli
Version:
AI-powered CLI tool and library for Azure DevOps work item management with Claude agents
189 lines (168 loc) • 7.75 kB
JavaScript
import { program } from 'commander';
import { config } from 'dotenv';
import { readFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import chalk from 'chalk';
import listCommand from '../src/commands/list.js';
import cacheCommand from '../src/commands/cache.js';
import exploreCommand from '../src/commands/explore.js';
import createCommand from '../src/commands/create.js';
import { bulkCreateCommand, interactiveHierarchyBuilder } from '../src/commands/bulk-create.js';
import { runInteractiveMode } from '../src/interactive/index.js';
import validateCommand from '../src/commands/validate.js';
import templatesCommand from '../src/commands/templates.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Load environment variables
config();
// Read package.json for version
const packageJson = JSON.parse(
readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')
);
program
.name('devops-issues')
.description('AI-powered CLI tool for Azure DevOps work item management with Claude agents')
.version(packageJson.version)
.option('--no-interactive', 'Run in non-interactive mode');
// If no arguments provided, run interactive mode
if (process.argv.length === 2) {
runInteractiveMode();
} else {
program
.command('list')
.description('List all issues assigned to you')
.option('-s, --state <state>', 'Filter by state (e.g., Active, Resolved)')
.option('-t, --type <type>', 'Filter by work item type (e.g., Bug, Task)')
.option('-l, --limit <number>', 'Limit number of results', parseInt)
.option('--json', 'Output in JSON format')
.option('--minimal', 'Minimal output (ID and title only)')
.option('--no-color', 'Disable colored output')
.action(listCommand);
program
.command('cache')
.description('Manage cache for work items')
.argument('[action]', 'Action to perform: status, clear, refresh')
.action(cacheCommand);
program
.command('explore')
.description('Explore work items in interactive tree view')
.option('-s, --state <state>', 'Filter by state (e.g., Active, Resolved)')
.option('-t, --type <type>', 'Filter by work item type (e.g., Bug, Task)')
.action(exploreCommand);
program
.command('create')
.description('Create a new work item under a parent')
.argument('[parentId]', 'Parent work item ID (optional - launches wizard if omitted)')
.argument('[title]', 'Title for the new work item (optional - prompts if omitted)')
.action(createCommand);
program
.command('bulk-create')
.description('Create multiple work items from hierarchical JSON file')
.argument('[file]', 'Path to JSON file containing work item hierarchy')
.option('--dry-run', 'Validate and preview without creating work items')
.option('--preview', 'Show hierarchy preview before creation')
.option('-y, --yes', 'Skip confirmation prompt')
.option('--save-mapping', 'Save temporary ID to actual ID mapping')
.option('-v, --verbose', 'Show detailed output')
.action(async (file, options) => {
if (!file) {
console.log('Starting interactive hierarchy builder...');
await interactiveHierarchyBuilder();
} else {
await bulkCreateCommand(file, options);
}
});
program
.command('validate')
.description('Validate work item JSON file against schema')
.argument('<file>', 'Path to JSON file to validate')
.option('-v, --verbose', 'Show detailed structure analysis')
.action(validateCommand);
program
.command('templates')
.description('Manage and generate from work item templates')
.argument('[action]', 'Action: list, show, generate')
.option('-c, --category <category>', 'Filter templates by category')
.option('-t, --template <key>', 'Specify template key')
.option('-o, --output <file>', 'Output filename for generated template')
.option('--json', 'Output raw JSON for show command')
.option('--full', 'Show full template content')
.action(templatesCommand);
program
.command('agents')
.description('List and display Claude agents for work item generation')
.argument('[action]', 'Action: list, show')
.option('-a, --agent <key>', 'Specify agent key to show')
.option('-c, --category <category>', 'Filter agents by category (workitem, development)')
.action(async (action, options) => {
// Import agents functionality
const { agents, getAgentList, getWorkItemAgents, getDevelopmentAgents } = await import('../agents/index.js');
switch (action) {
case 'list':
console.log(chalk.blue('🤖 Available Claude Agents:\n'));
if (options.category === 'workitem') {
console.log(chalk.cyan('Work Item Generation Agents:'));
getWorkItemAgents().forEach(agent => {
console.log(` ${chalk.green(agent.key)} - ${agent.name}`);
console.log(` ${chalk.gray(agent.description)}`);
});
} else if (options.category === 'development') {
console.log(chalk.cyan('Development Support Agents:'));
getDevelopmentAgents().forEach(agent => {
console.log(` ${chalk.green(agent.key)} - ${agent.name}`);
console.log(` ${chalk.gray(agent.description)}`);
});
} else {
// Show all categories
console.log(chalk.cyan('Work Item Generation:'));
getWorkItemAgents().forEach(agent => {
console.log(` ${chalk.green(agent.key)} - ${agent.name}`);
});
console.log('');
console.log(chalk.cyan('Development Support:'));
getDevelopmentAgents().forEach(agent => {
console.log(` ${chalk.green(agent.key)} - ${agent.name}`);
});
console.log('');
console.log(chalk.cyan('System:'));
console.log(` ${chalk.green('orchestrator')} - ${agents.orchestrator.name}`);
}
break;
case 'show':
const agentKey = options.agent;
if (!agentKey) {
console.log(chalk.red('Agent key required. Use --agent <key> or see: devops-issues agents list'));
process.exit(1);
}
const agent = agents[agentKey];
if (!agent) {
console.log(chalk.red(`Agent '${agentKey}' not found`));
process.exit(1);
}
console.log(chalk.blue(`🤖 Agent: ${agent.name}`));
console.log(chalk.gray(`Description: ${agent.description}`));
console.log(chalk.gray(`File: ${agent.file}`));
console.log('');
console.log(chalk.blue('Agent Content:'));
console.log(agent.content);
break;
default:
console.log(chalk.blue('🤖 Claude Agents for Azure DevOps\n'));
console.log('Available commands:');
console.log(' list - Show all available agents');
console.log(' show - Display specific agent content');
console.log('');
console.log('Usage examples:');
console.log(' devops-issues agents list');
console.log(' devops-issues agents list --category workitem');
console.log(' devops-issues agents show --agent userStory');
}
});
program.parse();
// If --no-interactive flag is used with no command, show help
if (program.opts().noInteractive && !process.argv.slice(2).some(arg => ['list', 'cache', 'explore', 'create', 'bulk-create', '--version', '-V', '--help', '-h'].includes(arg))) {
program.help();
}
}