UNPKG

@morodomi/ait3

Version:

AIT³ Development Platform - AI + Ticket + Test + Tool driven development methodology

69 lines (68 loc) 3.22 kB
import { ValidationError, TicketNotFoundError } from '../../common/errors.js'; import { getStatusColor, getPriorityColor } from '../../common/table-utils.js'; import { TimeUtils, IDUtils } from '../../common/utils.js'; import { STYLES } from '../../common/styles.js'; import { formatTicketLocation } from '../../common/utils/location-utils.js'; export async function showTicket(args, services) { // Input validation - ID format if (!args.id || !IDUtils.isValidTicketId(args.id)) { throw new ValidationError('Invalid ticket ID format. Use local format (0001) or GitHub format (#70, 70)', 'id'); } try { // Execute business logic through service layer const ticket = await services.ticketService.getTicket(args.id); if (!ticket) { throw new TicketNotFoundError(args.id); } // Generate formatted output const messageParts = [ // Header STYLES.bold(`Ticket #${ticket.id}: ${ticket.title}`), '', // Metadata section STYLES.bold('INFO:'), formatMetadataField('Status', ticket.status, getStatusColor(ticket.status)), formatMetadataField('Priority', ticket.priority, getPriorityColor(ticket.priority)), formatMetadataField('Created', TimeUtils.formatDate(ticket.created)), formatMetadataField('Updated', TimeUtils.formatDate(ticket.updated)), ]; // Optional metadata fields if (ticket.assignee) { messageParts.push(formatMetadataField('Assignee', ticket.assignee)); } const labelsText = ticket.labels.length > 0 ? ticket.labels.join(', ') : '(none)'; messageParts.push(formatMetadataField('Labels', labelsText)); // Add location information const locationDisplay = formatTicketLocation(ticket, services.ticketService); messageParts.push(formatMetadataField('LOCATION', locationDisplay)); // Separator messageParts.push(''); messageParts.push(STYLES.muted('────────────────────────────────────')); // Description section messageParts.push(''); messageParts.push(STYLES.bold('Description:')); messageParts.push(''); const description = ticket.description || '(No description provided)'; messageParts.push(description); return { success: true, message: messageParts.join('\n'), data: ticket }; } catch (error) { // Error handling - convert service layer errors to appropriate CLI errors if (error instanceof ValidationError || error instanceof TicketNotFoundError) { throw error; // Re-throw validation and not found errors as-is } // Wrap other errors with context throw new Error(`Failed to show ticket: ${error instanceof Error ? error.message : String(error)}`); } } // Helper functions function formatMetadataField(label, value, colorFn) { const formattedValue = colorFn ? colorFn(value) : value; return ` ${STYLES.muted(label + ':')} ${formattedValue}`; }