Skip to main content
Glama
stateMachine.ts3.26 kB
/** * Issue Creation Wizard State Machine * * This module implements a state machine for managing transitions between steps * in the Jira Issue Creation Wizard. It ensures that transitions follow the correct * sequence and that all required data is present before allowing advancement. */ import { createError, createSuccess, ErrorCode } from '../../errors/types' import { log } from '../../utils/logger' import { checkStepRequirements, getMissingRequirements } from './stepRequirements' import { WizardStep, WIZARD_STEP_ORDER } from './types' import type { WizardState } from './types' import type { ErrorResult } from '../../errors/types' /** * Defines the allowed transitions between wizard steps */ export const ALLOWED_TRANSITIONS: Record<WizardStep, WizardStep[]> = { [WizardStep.INITIATE]: [WizardStep.PROJECT_SELECTION], [WizardStep.PROJECT_SELECTION]: [WizardStep.INITIATE, WizardStep.ISSUE_TYPE_SELECTION], [WizardStep.ISSUE_TYPE_SELECTION]: [WizardStep.PROJECT_SELECTION, WizardStep.FIELD_COMPLETION], [WizardStep.FIELD_COMPLETION]: [WizardStep.ISSUE_TYPE_SELECTION, WizardStep.REVIEW], [WizardStep.REVIEW]: [WizardStep.FIELD_COMPLETION, WizardStep.SUBMISSION], [WizardStep.SUBMISSION]: [WizardStep.REVIEW], } /** * Checks if a transition from current step to target step is allowed */ export function isValidTransition(currentStep: WizardStep, targetStep: WizardStep): boolean { if (!ALLOWED_TRANSITIONS[currentStep]) { log(`ERROR: No transitions defined for step ${currentStep}`) return false } return ALLOWED_TRANSITIONS[currentStep].includes(targetStep) } /** * Attempts to transition the state to a new step, checking requirements and validity * @param forceStepTransition If true, allows any transition regardless of normal rules */ export function transitionState( currentState: WizardState, targetStep: WizardStep, forceStepTransition = false, ): { success: true; data: WizardState } | ErrorResult { // If forcing, allow any transition directly if (forceStepTransition) { return createSuccess({ ...currentState, currentStep: targetStep, timestamp: Date.now(), }) } // No change in step if (currentState.currentStep === targetStep) { return createSuccess({ ...currentState }) } // Check if transition is allowed if (!isValidTransition(currentState.currentStep, targetStep)) { return createError( ErrorCode.INVALID_PARAMETERS, `Invalid transition from ${currentState.currentStep} to ${targetStep}`, ) } // Going backward is always allowed if the transition is valid if (WIZARD_STEP_ORDER[targetStep] < WIZARD_STEP_ORDER[currentState.currentStep]) { return createSuccess({ ...currentState, currentStep: targetStep, timestamp: Date.now(), }) } // Going forward requires checking requirements if (!checkStepRequirements(currentState, currentState.currentStep)) { const missing = getMissingRequirements(currentState, currentState.currentStep) return createError( ErrorCode.INVALID_PARAMETERS, `Cannot advance to ${targetStep} because current step ${currentState.currentStep} is incomplete. Missing: ${missing.join(', ')}`, ) } // All checks passed return createSuccess({ ...currentState, currentStep: targetStep, timestamp: Date.now(), }) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tbreeding/jira-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server