UNPKG

@pimzino/claude-code-spec-workflow

Version:

Automated workflows for Claude Code. Includes spec-driven development (Requirements → Design → Tasks → Implementation) with intelligent task execution, optional steering documents and streamlined bug fix workflow (Report → Analyze → Fix → Verify). We have

674 lines 24.4 kB
/** * Shared type definitions for the dashboard frontend and backend * This file provides common interfaces and types that can be used * across the entire dashboard application to ensure type safety. */ import type { Task, RequirementDetail, CodeReuseCategory, SteeringStatus, Bug, Spec } from '../parser'; import type { TunnelStatus, TunnelInfo, TunnelOptions } from '../tunnel/types'; export type { Task, RequirementDetail, CodeReuseCategory, SteeringStatus, Bug, Spec, TunnelStatus, TunnelInfo, TunnelOptions }; /** * Extended Project interface for dashboard display * Represents a project with its specs, bugs, and metadata */ export interface Project { /** Absolute path to the project directory */ path: string; /** Display name of the project */ name: string; /** Hierarchy level for nested project display (0 = root) */ level: number; /** Whether this project has an active dashboard session */ hasActiveSession: boolean; /** All specifications found in this project */ specs: Spec[]; /** All bugs found in this project (optional as not all projects have bugs) */ bugs?: Bug[]; /** Steering document status (if available) */ steeringStatus?: SteeringStatus; /** Current git branch (if git repo) */ gitBranch?: string; /** Current git commit hash (if git repo) */ gitCommit?: string; } /** * WebSocket message types for real-time communication * Uses discriminated unions for type-safe message handling */ export type WebSocketMessage = InitialDataMessage | UpdateDataMessage | BugUpdateMessage | SteeringUpdateMessage | ErrorDataMessage | TunnelStartedMessage | TunnelStoppedMessage | TunnelMetricsMessage | TunnelVisitorMessage | ProjectUpdateMessage | ActiveSessionsUpdateMessage | GitUpdateMessage | NewProjectMessage | RemoveProjectMessage; export interface InitialDataMessage { type: 'initial'; data: InitialData; } export interface UpdateDataMessage { type: 'update'; data: UpdateData; } export interface BugUpdateMessage { type: 'bug-update'; data: UpdateData; } export interface SteeringUpdateMessage { type: 'steering-update'; data: SteeringStatus; } export interface ErrorDataMessage { type: 'error'; data: ErrorData; } export interface TunnelStartedMessage { type: 'tunnel:started'; data: TunnelInfo; } export interface TunnelStoppedMessage { type: 'tunnel:stopped'; data: Record<string, unknown>; } export interface TunnelMetricsMessage { type: 'tunnel:metrics:updated'; data: TunnelMetrics; } export interface TunnelVisitorMessage { type: 'tunnel:visitor:new'; data: TunnelVisitor; } export interface ProjectUpdateMessage { type: 'project-update'; projectPath: string; data: any; } export interface ActiveSessionsUpdateMessage { type: 'active-sessions-update'; data: ActiveSession[]; } export interface GitUpdateMessage { type: 'git-update'; projectPath: string; gitBranch: string; gitCommit: string; } export interface NewProjectMessage { type: 'new-project'; data: Project; } export interface RemoveProjectMessage { type: 'remove-project'; data: { path: string; }; } /** * Tunnel metrics data */ export interface TunnelMetrics { /** Current number of active viewers */ viewers: number; /** Total requests served */ totalRequests?: number; /** Data transferred in bytes */ dataTransferred?: number; /** Uptime in milliseconds */ uptime?: number; } /** * Tunnel visitor information */ export interface TunnelVisitor { /** Visitor IP address (anonymized) */ ip: string; /** User agent string */ userAgent?: string; /** Referrer URL */ referrer?: string; /** Timestamp of first visit */ firstVisit: Date; /** Location information (if available) */ location?: { country?: string; city?: string; }; } /** * Initial data sent when client connects */ export interface InitialData { /** All specifications found */ specs: Spec[]; /** All bugs found */ bugs: Bug[]; /** Current tunnel status */ tunnelStatus: TunnelStatus; /** Server configuration info */ config?: { version?: string; buildTime?: string; }; } /** * Update data sent when files change */ export interface UpdateData { /** Updated projects (partial update) */ projects: Project[]; /** Timestamp of the update */ timestamp: number; /** Files that triggered the update */ changedFiles?: string[]; } /** * Error data for communication errors */ export interface ErrorData { /** Error message */ message: string; /** Error code for programmatic handling */ code?: string; /** Additional error context */ details?: Record<string, unknown>; } /** * Application state interface for reactive frontend state * Comprehensive state management for the multi-project dashboard */ export interface AppState { /** All projects loaded in the dashboard */ projects: Project[]; /** Currently selected project (null if none) */ selectedProject: Project | null; /** Currently selected specification (null if none) */ selectedSpec: Spec | null; /** List of active sessions (specs/bugs being worked on) */ activeSessions: ActiveSession[]; /** WebSocket connection status */ connected: boolean; /** WebSocket instance (null if not connected) */ ws: globalThis.WebSocket | null; /** Current tunnel status (null if no tunnel) */ tunnelStatus: TunnelStatus | null; /** Current UI theme */ theme: 'light' | 'dark' | 'system'; /** Username for the current session */ username: string; /** Active tab in the dashboard */ activeTab: 'active' | 'projects'; /** Whether to show completed specs/tasks */ showCompleted: boolean; /** Pending project route (when projects haven't loaded yet) */ pendingProjectRoute: string | null; /** Expanded state for requirements sections (spec name -> expanded) */ expandedRequirements: Record<string, boolean>; /** Expanded state for design sections (spec name -> expanded) */ expandedDesigns: Record<string, boolean>; /** Expanded state for task sections (spec name -> expanded) */ expandedTasks: Record<string, boolean>; /** Expanded state for requirement accordions (specName-reqId -> expanded) */ expandedRequirementAccordions: Record<string, boolean>; /** Selected task IDs (spec name -> task ID) */ selectedTasks: Record<string, string>; /** Collapsed state for completed tasks (spec name -> collapsed) */ collapsedCompletedTasks: Record<string, boolean>; /** Markdown preview modal state */ markdownPreview: MarkdownPreviewState; /** Cache for grouped projects (invalidated when projects change) */ _groupedProjectsCache: GroupedProjectsCache | null; /** Cache for computed color values */ _colorValueCache: Record<string, string>; /** Pre-computed data for project tabs to avoid reactivity issues */ projectTabsData: ProjectTabData[]; } /** * Active session representing a spec or bug being worked on */ export interface ActiveSession { /** Type of session - spec or bug */ type: 'spec' | 'bug'; /** Path to the project containing this item */ projectPath: string; /** Name of the spec */ specName?: string; /** Name of the bug */ bugName?: string; /** Current task ID being worked on (for specs) - deprecated, use task.id */ currentTaskId?: string; /** Current task object being worked on (for specs) */ task?: Task; /** Total number of tasks (for specs) */ totalTasks?: number; /** Progress percentage (0-100) */ progress?: number; /** Pre-computed project color value for performance */ projectColorValue?: string; } /** * Markdown preview modal state */ export interface MarkdownPreviewState { /** Whether the preview is visible */ show: boolean; /** Title of the preview modal */ title: string; /** Rendered HTML content */ content: string; /** Raw markdown content */ rawContent: string; /** Whether content is currently loading */ loading: boolean; } /** * Cache for grouped projects to avoid expensive re-computation */ export interface GroupedProjectsCache { /** Number of projects when cache was created */ projectsCount: number; /** Hash of project paths for cache invalidation */ projectsHash: string; /** Cached grouped project data */ data: Project[]; } /** * Pre-computed project tab data for performance */ export interface ProjectTabData { /** Project path */ path: string; /** Display name */ name: string; /** Hierarchy level */ level: number; /** Whether project has an active session */ hasActiveSession: boolean; /** Pre-computed color value */ colorValue: string; /** Primary color class name */ colorPrimary: string; /** Whether next project is top-level */ isNextTopLevel: boolean; /** Whether previous project is nested */ isPrevNested: boolean; /** Project specs */ specs: Spec[]; /** Project bugs (optional as not all projects have bugs) */ bugs?: Bug[]; } /** * UI-specific state management types * These types represent different aspects of the user interface state */ /** * Expanded state management for different UI sections */ export interface ExpandedStates { /** Requirements sections (spec name -> expanded state) */ requirements: Record<string, boolean>; /** Design sections (spec name -> expanded state) */ designs: Record<string, boolean>; /** Task sections (spec name -> expanded state) */ tasks: Record<string, boolean>; /** Requirement accordions (specName-reqId -> expanded state) */ requirementAccordions: Record<string, boolean>; /** Completed task sections (spec name -> collapsed state) */ collapsedCompletedTasks: Record<string, boolean>; } /** * Selection state management for interactive elements */ export interface SelectedItems { /** Selected project (null if none) */ project: Project | null; /** Selected specification (null if none) */ spec: Spec | null; /** Selected tasks per spec (spec name -> task ID) */ tasks: Record<string, string>; /** Currently active tab */ activeTab: 'active' | 'projects'; } /** * Cache management interfaces for performance optimization */ export interface CacheManagement { /** Grouped projects cache with invalidation data */ groupedProjects: GroupedProjectsCache | null; /** Color value cache for projects (path -> RGB string) */ colorValues: Record<string, string>; /** Pre-computed project tabs data */ projectTabsData: ProjectTabData[]; } /** * Navigation state for routing and history management */ export interface NavigationState { /** Current active tab */ activeTab: 'active' | 'projects'; /** Pending project route when projects haven't loaded */ pendingProjectRoute: string | null; /** Whether to show completed items */ showCompleted: boolean; } /** * Theme and user preference state */ export interface UserPreferences { /** Current theme setting */ theme: 'light' | 'dark' | 'system'; /** Username for display */ username: string; /** Show/hide completed items preference */ showCompleted: boolean; } /** * Color scheme for project visualization * Extended to include dark mode variants */ export interface ColorScheme { /** Primary color (e.g., 'indigo-600') */ primary: string; /** Light background color (e.g., 'indigo-100') */ light: string; /** Ring/focus color (e.g., 'indigo-500') */ ring: string; /** Dark mode variant */ dark?: { /** Primary color for dark mode */ primary: string; /** Light background for dark mode */ light: string; }; } /** * Grouped project structure for dashboard display */ export interface GroupedProject { /** Group identifier */ groupId: string; /** Group display name */ groupName: string; /** Projects in this group */ projects: Project[]; /** Color scheme for the group */ colorScheme: ColorScheme; /** Whether the group is expanded in UI */ expanded: boolean; } /** * Dashboard configuration options */ export interface DashboardOptions { /** Port to run the dashboard on */ port?: number; /** Whether to open browser automatically */ open?: boolean; /** Watch for file changes */ watch?: boolean; /** Enable tunnel functionality */ tunnel?: boolean; /** Tunnel options */ tunnelOptions?: TunnelOptions; } /** * File watcher event types */ export interface FileWatchEvent { /** Type of file system event */ type: 'add' | 'change' | 'unlink' | 'addDir' | 'unlinkDir'; /** Absolute path to the changed file/directory */ path: string; /** Relative path from project root */ relativePath: string; /** Timestamp of the event */ timestamp: number; } /** * Task execution context for generated commands */ export interface TaskExecutionContext { /** Name of the spec */ specName: string; /** Task ID being executed */ taskId: string; /** Full task object */ task: Task; /** Associated requirements */ requirements: RequirementDetail[]; /** Code to leverage (from _Leverage: section) */ leverage?: string[]; } /** * Dashboard server status information */ export interface ServerStatus { /** Whether the server is running */ running: boolean; /** Port the server is listening on */ port?: number; /** Start time of the server */ startTime?: Date; /** Number of connected clients */ connections: number; /** Server version */ version?: string; } /** * Statistics about the current dashboard session */ export interface DashboardStats { /** Total number of projects */ totalProjects: number; /** Total number of specs */ totalSpecs: number; /** Number of completed specs */ completedSpecs: number; /** Number of specs in progress */ inProgressSpecs: number; /** Total number of tasks */ totalTasks: number; /** Number of completed tasks */ completedTasks: number; /** Total number of bugs */ totalBugs: number; /** Number of resolved bugs */ resolvedBugs: number; } /** * Frontend-specific extensions to core types */ /** * Extended Spec interface for UI state */ export interface UISpec extends Spec { /** Whether the spec is expanded in the UI */ isExpanded?: boolean; /** Currently selected task ID */ selectedTaskId?: string; /** Computed progress percentage (0-100) */ progressPercentage?: number; } /** * Extended Task interface for UI state */ export interface UITask extends Task { /** Whether the task is visible in current filter */ isVisible?: boolean; /** Indentation level for nested display */ indentLevel?: number; /** Whether task details are expanded */ detailsExpanded?: boolean; } /** * Extended Bug interface for UI state */ export interface UIBug extends Bug { /** Whether the bug is expanded in the UI */ isExpanded?: boolean; /** Computed age in days */ ageInDays?: number; } /** * Type guards for runtime type checking */ export declare function isWebSocketMessage(obj: unknown): obj is WebSocketMessage; export declare function isInitialDataMessage(msg: WebSocketMessage): msg is InitialDataMessage; export declare function isUpdateDataMessage(msg: WebSocketMessage): msg is UpdateDataMessage; export declare function isBugUpdateMessage(msg: WebSocketMessage): msg is BugUpdateMessage; export declare function isSteeringUpdateMessage(msg: WebSocketMessage): msg is SteeringUpdateMessage; export declare function isErrorDataMessage(msg: WebSocketMessage): msg is ErrorDataMessage; export declare function isTunnelStartedMessage(msg: WebSocketMessage): msg is TunnelStartedMessage; export declare function isTunnelStoppedMessage(msg: WebSocketMessage): msg is TunnelStoppedMessage; export declare function isTunnelMetricsMessage(msg: WebSocketMessage): msg is TunnelMetricsMessage; export declare function isTunnelVisitorMessage(msg: WebSocketMessage): msg is TunnelVisitorMessage; export declare function isProjectUpdateMessage(msg: WebSocketMessage): msg is ProjectUpdateMessage; export declare function isActiveSessionsUpdateMessage(msg: WebSocketMessage): msg is ActiveSessionsUpdateMessage; export declare function isGitUpdateMessage(msg: WebSocketMessage): msg is GitUpdateMessage; export declare function isNewProjectMessage(msg: WebSocketMessage): msg is NewProjectMessage; export declare function isRemoveProjectMessage(msg: WebSocketMessage): msg is RemoveProjectMessage; /** * State mutation methods interface * Defines method signatures for managing application state */ export interface AppStateMethods { /** Switch between 'active' and 'projects' tabs */ switchTab(_tab: 'active' | 'projects'): void; /** Select a project and switch to projects tab */ selectProject(_project: Project | null): void; /** Select a project from an active session */ selectProjectFromSession(_session: ActiveSession): void; /** Select a project from a task link */ selectProjectFromTask(_projectPath: string, _itemName: string, _sessionType?: 'spec' | 'bug'): void; /** Toggle requirements section expansion for a spec */ toggleRequirementsExpanded(_specName: string): void; /** Check if requirements section is expanded for a spec */ isRequirementsExpanded(_specName: string): boolean; /** Toggle design section expansion for a spec */ toggleDesignExpanded(_specName: string): void; /** Check if design section is expanded for a spec */ isDesignExpanded(_specName: string): boolean; /** Toggle tasks section expansion for a spec */ toggleTasksExpanded(_specName: string): void; /** Check if tasks section is expanded for a spec */ isTasksExpanded(_specName: string): boolean; /** Toggle requirement accordion expansion */ toggleRequirementAccordion(_specName: string, _requirementId: string): void; /** Check if requirement accordion is expanded */ isRequirementExpanded(_specName: string, _requirementId: string): boolean; /** Select a task for a spec */ selectTask(_specName: string, _taskId: string): void; /** Check if a task is selected for a spec */ isTaskSelected(_specName: string, _taskId: string): boolean; /** Get the selected task ID for a spec */ selectedTaskId(_specName: string): string | undefined; /** Get the selected task object for a spec */ getSelectedTask(_specName: string): Task | null; /** Initialize selected task for a spec (first incomplete task) */ initializeSelectedTask(_spec: Spec): void; /** Connect to WebSocket server */ connectWebSocket(): void; /** Handle incoming WebSocket messages */ handleWebSocketMessage(_message: WebSocketMessage): void; /** Get visible specs for a project (filtered by showCompleted) */ getVisibleSpecs(_project: Project): Spec[]; /** Get visible bugs for a project (filtered by showCompleted) */ getVisibleBugs(_project: Project): Bug[]; /** Toggle show/hide completed items */ toggleShowCompleted(): void; /** Get cached grouped projects, rebuilding if necessary */ getCachedGroupedProjects(): Project[]; /** Get grouped projects for template use */ getGroupedProjects(): Project[]; /** Update pre-computed project tabs data */ updateProjectTabsData(): void; /** Get color scheme for a project path */ getProjectColor(_projectPath: string): ColorScheme; /** Get CSS classes for project color */ getProjectColorClasses(_projectPath: string, _type?: 'text' | 'bg' | 'bg-primary' | 'border' | 'border-l' | 'border-r'): string; /** Get project color value (RGB string) */ getProjectColorValue(_projectPath: string): string; /** Get project tab styles for a project */ getProjectTabStyles(_project: Project): string[]; /** Get project badge styles */ getProjectBadgeStyles(_project: Project): string[]; /** Get number of specs in progress for a project */ getSpecsInProgress(_project: Project): number; /** Get number of completed specs for a project */ getSpecsCompleted(_project: Project): number; /** Get total number of tasks for a project */ getTotalTasks(_project: Project): number; /** Get number of open specs for a project */ getOpenSpecsCount(_project: Project): number; /** Get number of open bugs for a project */ getOpenBugsCount(_project: Project): number; /** Get number of bugs in progress for a project */ getBugsInProgress(_project: Project): number; /** Get number of resolved bugs for a project */ getBugsResolved(_project: Project): number; /** Get task number for an active session */ getTaskNumber(_activeSession: ActiveSession): number; /** Get total task count for a spec session */ getSpecTaskCount(_activeSession: ActiveSession): number; /** Get progress percentage for a spec session */ getSpecProgress(_activeSession: ActiveSession): number; /** Get next incomplete task for a spec session */ getNextTask(_activeSession: ActiveSession): Task | null; /** Get current task for a spec */ getCurrentTask(_spec: Spec): Task | null; /** Initialize browser routing */ initializeRouting(): void; /** Handle route changes */ handleRouteChange(): void; /** Update browser URL based on current state */ updateURL(): void; /** Convert project to URL-friendly slug */ getProjectSlug(_project: Project): string; /** Copy next task command to clipboard */ copyNextTaskCommand(_spec: Spec, _event: Event): void; /** Copy orchestrate command to clipboard */ copyOrchestrateCommand(_spec: Spec, _event: Event): void; /** Sort projects by name */ sortProjects(): void; /** Sort specs by status and name */ sortSpecs(_specs: Spec[]): void; /** Sort bugs by status and creation date */ sortBugs(_bugs: Bug[]): void; /** Normalize projects data from server */ normalizeProjects(_projects: Project[]): Project[]; /** Find first incomplete task in a task list */ findFirstIncompleteTask(_tasks: Task[]): Task | null; /** Scroll to a specific requirement element */ scrollToRequirement(_specName: string, _requirementId: string): void; /** Check current tunnel status */ checkTunnelStatus(): Promise<void>; /** Start tunnel for sharing dashboard */ startTunnel(): Promise<void>; /** Stop active tunnel */ stopTunnel(): Promise<void>; /** Format tunnel expiry time */ formatTunnelExpiry(_expiresAt: string): string; } /** * Complete application state interface including methods * Combines reactive state properties with state mutation methods */ export interface CompleteAppState extends AppState, AppStateMethods { /** Number of projects with active sessions */ readonly activeSessionCount: number; /** Grouped projects list for template use */ readonly groupedProjectsList: Project[]; } /** * Utility types for common patterns */ /** Status types that can be used throughout the application */ export type StatusType = 'not-started' | 'requirements' | 'design' | 'tasks' | 'in-progress' | 'completed'; /** Theme options for the dashboard */ export type ThemeType = 'light' | 'dark' | 'system'; /** Tab types for navigation */ export type TabType = 'active' | 'projects'; /** Event handler types for common interactions */ export type ProjectSelectHandler = (_project: Project | null) => void; export type SpecSelectHandler = (_spec: Spec | null) => void; export type TaskSelectHandler = (_task: Task | null) => void; export type ThemeChangeHandler = (_theme: ThemeType) => void; /** * Constants for common values */ export declare const DEFAULT_DASHBOARD_OPTIONS: Required<DashboardOptions>; export declare const STATUS_PRIORITY: Record<StatusType, number>; export declare const BUG_STATUS_PRIORITY: Record<Bug['status'], number>; //# sourceMappingURL=dashboard.types.d.ts.map