#!/usr/bin/env python3 """ Pure Issue Management CLI Dedicated CLI interface for issue management operations, providing clean separation from document processing and TDD workflow functionality. This CLI focuses exclusively on issue operations: - Listing and viewing issues - Creating and closing issues - Project management (milestones, priorities, states) - Issue metadata and bulk operations Architecture: Uses the unified cli/ framework for consistent command structure. """ import sys import argparse from pathlib import Path from typing import Optional # Add project root to path for imports project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from cli.core import CLIFramework from tddai import TddaiError def create_parser() -> argparse.ArgumentParser: """Create argument parser for issue CLI.""" parser = argparse.ArgumentParser( prog='issue', description='Pure Issue Management CLI - Dedicated interface for issue operations', formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: issue list # List all issues issue list --open # List only open issues issue show 42 # Show issue details issue create "Bug fix" "Description" # Create new issue issue close 42 "Fixed the problem" # Close issue with comment issue assign 42 milestone-1 # Assign to milestone issue priority 42 high # Set priority issue state 42 "In Progress" # Set project state Focus Areas: - Issue browsing and management - Project organization (milestones, priorities) - Bulk operations and metadata management - Integration with various issue tracking backends Related Commands: tddai - TDD workflow management with issue context markitect - Document processing and template operations """ ) subparsers = parser.add_subparsers(dest='command', help='Available issue commands') # List issues list_parser = subparsers.add_parser('list', help='List issues') list_parser.add_argument('--open', action='store_true', help='Show only open issues') list_parser.add_argument('--format', choices=['table', 'json', 'csv'], default='table', help='Output format') # Show issue details show_parser = subparsers.add_parser('show', help='Show issue details') show_parser.add_argument('issue_number', type=int, help='Issue number') # Create issue create_parser = subparsers.add_parser('create', help='Create new issue') create_parser.add_argument('title', help='Issue title') create_parser.add_argument('description', help='Issue description') create_parser.add_argument('--type', choices=['bug', 'enhancement', 'feature'], default='enhancement', help='Issue type') create_parser.add_argument('--priority', choices=['low', 'medium', 'high', 'critical'], help='Issue priority') # Close issue close_parser = subparsers.add_parser('close', help='Close issue') close_parser.add_argument('issue_number', type=int, help='Issue number') close_parser.add_argument('comment', nargs='?', default='', help='Closing comment') # Assign to milestone assign_parser = subparsers.add_parser('assign', help='Assign issue to milestone') assign_parser.add_argument('issue_number', type=int, help='Issue number') assign_parser.add_argument('milestone_id', type=int, help='Milestone ID') # Set priority priority_parser = subparsers.add_parser('priority', help='Set issue priority') priority_parser.add_argument('issue_number', type=int, help='Issue number') priority_parser.add_argument('priority', choices=['low', 'medium', 'high', 'critical'], help='Priority level') # Set state state_parser = subparsers.add_parser('state', help='Set issue project state') state_parser.add_argument('issue_number', type=int, help='Issue number') state_parser.add_argument('state', help='Project state') # Export/bulk operations export_parser = subparsers.add_parser('export', help='Export issues in various formats') export_parser.add_argument('--format', choices=['csv', 'json', 'tsv'], default='csv', help='Export format') export_parser.add_argument('--output', help='Output file (default: stdout)') export_parser.add_argument('--filter', choices=['open', 'closed', 'all'], default='all', help='Filter issues') # Milestones milestone_parser = subparsers.add_parser('milestones', help='List milestones') return parser def main(): """Main entry point for issue CLI.""" parser = create_parser() args = parser.parse_args() if not args.command: parser.print_help() sys.exit(1) # Initialize CLI framework try: cli = CLIFramework() except Exception as e: print(f"Error initializing CLI framework: {e}") sys.exit(1) # Execute commands try: if args.command == 'list': if args.open: cli.list_open_issues() else: cli.list_issues() elif args.command == 'show': cli.show_issue(args.issue_number) elif args.command == 'create': kwargs = {} if hasattr(args, 'priority') and args.priority: kwargs['priority'] = args.priority cli.create_issue(args.title, args.description, args.type, **kwargs) elif args.command == 'close': cli.close_issue(args.issue_number, args.comment) elif args.command == 'assign': cli.assign_issue_to_milestone(args.issue_number, args.milestone_id) elif args.command == 'priority': cli.set_issue_priority(args.issue_number, args.priority) elif args.command == 'state': cli.move_issue_to_state(args.issue_number, args.state) elif args.command == 'export': # Export functionality if args.format == 'csv': cli.export_issues_csv(args.output) elif args.format == 'json': cli.export_issues_json(args.output) elif args.format == 'tsv': cli.export_issue_index(args.output) elif args.command == 'milestones': cli.list_milestones() else: print(f"Unknown command: {args.command}") parser.print_help() sys.exit(1) except TddaiError as e: print(f"Issue CLI Error: {e}") sys.exit(1) except Exception as e: print(f"Unexpected error: {e}") sys.exit(1) if __name__ == '__main__': main()