A SvelteKit-based Single Page Application (SPA) that monitors GitHub Actions workflows across multiple repositories organized into groups. The dashboard provides real-time visibility into workflow statuses, helping teams track CI/CD pipeline health across their projects with improved organization and navigation.
- Frontend Framework: SvelteKit with TypeScript
- Styling: Plain CSS with responsive design
- Configuration: YAML-based static configuration
- API Integration: GitHub REST API v4
- Build Tool: Vite
- Package Manager: npm
octowatch/
├── src/
│ ├── routes/
│ │ ├── +layout.svelte # Main layout
│ │ ├── +page.svelte # Groups overview page
│ │ └── groups/
│ │ └── [slug]/
│ │ └── +page.svelte # Individual group monitoring
│ ├── lib/
│ │ ├── components/ # Reusable UI components
│ │ │ ├── RefreshButton.svelte # Manual refresh component
│ │ │ └── HeaderActions.svelte # Coordinated refresh & settings buttons
│ │ ├── services/ # API and business logic
│ │ │ ├── github-api.ts # GitHub API client
│ │ │ ├── config-loader.ts # YAML configuration loader with groups
│ │ │ └── token-storage.ts # Token and user settings storage
│ │ ├── types/ # TypeScript type definitions
│ │ │ └── github.ts # Repository and RepositoryGroup interfaces
│ │ └── utils/ # Utility functions
│ │ └── date-formatter.ts
│ ├── app.html # HTML template
│ ├── app.css # Global styles
│ └── app.d.ts # TypeScript declarations
├── static/
│ └── config.yaml # Repository groups configuration
├── package.json
└── README.md
- Repository Groups: Organize repositories into logical groups for better management
- Multi-Page Navigation: Home page shows groups, dedicated pages for each group
- Collapsible Table View: Display repositories with expandable workflow details
- Cumulative Status Aggregation: Smart status rollup showing worst-case per repository
- Real-time Auto-refresh: Configurable intervals with config file watching
- Configuration Management: YAML-based repository groups configuration with hot-reload
- Responsive Design: Card-based groups overview and table layout with mobile support
- Error Handling: Comprehensive error display and graceful degradation
- Dependabot Filtering: User setting to hide workflows triggered by Dependabot
- Settings Management: Persistent localStorage-based settings with intuitive UI
- Home Page (/): Displays all repository groups as cards with descriptions and repository counts
- Group Pages (/groups/[slug]): Individual group monitoring with collapsible table view
- Breadcrumb Navigation: Easy navigation between groups overview and specific groups
- Detailed Workflow View: Click to see individual workflow run details
- Filtering & Sorting: Filter by status, sort by last updated
- Historical Data: Show workflow run history and trends
- Notifications: Browser notifications for status changes
- Multiple Branch Support: Monitor different branches per repository
- Group-level Status: Aggregate status indicators across entire groups
The dashboard uses a unified table approach with collapsible functionality:
Main Component: src/routes/+page.svelte
- Complete dashboard logic in single file
- Repository summary rows (collapsed by default)
- Expandable workflow detail rows
- Real-time updates and configuration watching
Supporting Components:
HeaderActions.svelte- Reusable coordinated refresh and settings buttonsRefreshButton.svelte- Manual refresh component- Configuration and API services in
src/lib/services/
Repository Summary Row:
interface RepositorySummary {
repository: Repository;
cumulativeStatus: 'success' | 'failure' | 'in_progress' | 'cancelled' | 'unknown';
statusText: string; // e.g., "2 failed, 3 passed"
runCount: number;
lastActivity: Date;
isExpanded: boolean;
}Workflow Detail Row (shown when expanded):
interface WorkflowDetail {
workflowRun: WorkflowRun;
indentLevel: number;
parentRepository: Repository;
}Cumulative Status Priority:
- Failure (highest) - Any workflow failed
- In Progress - Workflows running (if no failures)
- Success - All workflows passed
- Cancelled - All workflows cancelled
- Unknown (lowest) - Indeterminate state
interface Repository {
name: string;
owner: string;
url: string;
branch: string;
enabled: boolean;
}
interface RepositoryGroup {
name: string;
slug: string;
description: string;
enabled: boolean;
repositories: Repository[];
}
interface Config {
repository_groups?: RepositoryGroup[];
repositories?: Repository[]; // Legacy support
github: {
api_url: string;
};
dashboard: {
title?: string;
refresh_interval: number;
max_runs_to_fetch: number;
show_statuses: string[];
};
}interface WorkflowRun {
id: number;
name: string;
status: 'queued' | 'in_progress' | 'completed';
conclusion: 'success' | 'failure' | 'cancelled' | 'skipped' | null;
created_at: string;
updated_at: string;
html_url: string;
head_branch: string;
head_sha: string;
actor: {
login: string;
};
}
interface Repository {
id: number;
name: string;
full_name: string;
owner: {
login: string;
};
default_branch: string;
}GET /repos/{owner}/{repo}/actions/runs- List workflow runsGET /repos/{owner}/{repo}- Get repository informationGET /repos/{owner}/{repo}/actions/workflows- List workflows
- Unauthenticated: 60 requests per hour per IP
- Authenticated: 5,000 requests per hour per token
- Recommendation: Use personal access token for production
- Network Errors: Show connection error message with retry option
- API Rate Limiting: Display rate limit status and reset time
- Authentication Errors: Guide user to configure access token
- Repository Not Found: Mark repository as invalid in UI
- Configuration Errors: Validate YAML and show parsing errors
- Success: #28a745 (green)
- Failure: #d73a49 (red)
- In Progress: #ffc107 (yellow)
- Cancelled: #6c757d (gray)
- Background: #f6f8fa (light gray)
- Cards: #ffffff (white)
- Text: #24292e (dark gray)
- Header: Application title and description
- Controls: Refresh button with auto-refresh status indicator
- Table Layout: Collapsible table with repository summary rows
- Expandable Details: Click to reveal individual workflow runs
- Loading States: Progressive loading with existing data preserved
- Empty States: Helpful messages when no data available
- Desktop: Full table with all columns visible
- Tablet/Mobile: Horizontal scroll with minimum table width
- Touch-friendly: Large click targets for expand/collapse buttons
- Compact: Reduced padding and font sizes on smaller screens
- SvelteKit project setup with TypeScript
- Collapsible table layout implementation
- Real GitHub API integration
- YAML configuration with hot-reload
- Cumulative status aggregation logic
- GitHub API client with error handling
- Real workflow data fetching and display
- Auto-refresh functionality with configurable intervals
- Configuration file watching and auto-reload
- Responsive design with mobile support
- Collapsible repository view
- Smart status priority aggregation
- Loading states with existing data preservation
- Comprehensive error handling and display
- Real-time config changes without restart
- GitHub token management with secure localStorage storage
- Token validation and format checking (supports all GitHub token formats)
- Settings popup with intuitive UI
- Dependabot workflow filtering capability
- Persistent user preferences across sessions
- Reusable HeaderActions component with coordinated refresh and settings buttons
- Multi-branch monitoring per repository
- Workflow run history and trends
- Browser notifications for status changes
- GitHub authentication for private repos
- Filtering and sorting capabilities
- Custom dashboard themes
repository_groups:
- name: "Frontend Projects"
slug: "frontend"
description: "Web applications and UI libraries"
enabled: true
repositories:
- name: "my-app"
owner: "mycompany"
url: "https://github.com/mycompany/my-app"
branch: "main"
enabled: true
# Dashboard settings
dashboard:
title: "My Project Dashboard"
refresh_interval: 30
max_runs_to_fetch: 20
show_statuses: ["success", "failure", "in_progress"]
# GitHub API settings
github:
api_url: "https://api.github.com"- Compatible with Vercel, Netlify, GitHub Pages
- Requires CORS configuration for GitHub API calls
- Tokens managed via browser localStorage through Settings UI
- Never commit GitHub tokens to repository
- Tokens stored securely in browser localStorage
- Implement proper CORS policies
- Consider using GitHub Apps for enhanced security
- Client-side token storage uses browser localStorage (secure for SPA)
- Token validation prevents invalid formats from being stored
- Supported Token Formats:
- Classic tokens (40-character hexadecimal strings)
- Fine-grained personal access tokens (
ghp_...) - New GitHub PAT format (
github_pat_...) - OAuth tokens (
gho_...) - User-to-server tokens (
ghu_...) - Server-to-server tokens (
ghs_...) - Refresh tokens (
ghr_...)
- Multi-Branch Monitoring: Track multiple branches per repository
- Workflow Filtering: Show only specific workflows (e.g., CI, deployment)
- Team Management: User authentication and team-based repository access
- Metrics & Analytics: Workflow success rates, average run times
- Slack/Email Integration: Notifications for workflow status changes
- Custom Themes: Dark mode and customizable color schemes
- Export Functionality: Export status reports to PDF/CSV
- Webhook Integration: Real-time updates via GitHub webhooks
- Collapsible Table Interface: Single-page dashboard with expandable repository rows
- Smart Status Aggregation: Failure > In Progress > Success priority system
- Real-time Updates: Configurable auto-refresh (default 30s) + config file watching (5s)
- GitHub API Integration: Full workflow run fetching with comprehensive error handling
- Configuration Management:
static/config.yamlwith hot-reload capability - Responsive Design: Mobile-friendly with horizontal scroll and touch-optimized controls
- Error Handling: Network errors, API rate limits, repository access issues
- TypeScript: Full type safety across the application
- Settings Management: Secure token storage and user preferences in localStorage
- Enhanced Token Validation: Support for all GitHub token formats (classic, ghp_, github_pat_, etc.)
- Reusable Components: HeaderActions component with coordinated refresh and settings buttons
- Dependabot Filtering: Option to hide workflows triggered by Dependabot (actor-based filtering)
- Single Page Application: All logic in
src/routes/+page.sveltefor simplicity - Static Configuration: Config in
static/config.yamlserved by SvelteKit automatically - No Backend Required: Pure frontend solution using GitHub's public API
- Progressive Enhancement: Works without JavaScript for basic HTML table
- Minimal Dependencies: Only essential packages (SvelteKit, TypeScript, js-yaml)
- Client-side Settings: User preferences stored securely in localStorage
- Actor-based Filtering: Workflow filtering based on GitHub actor information
- Component Architecture: Reusable HeaderActions component eliminates code duplication
- Initial Load: ~1-2s for 5-10 repositories
- Auto-refresh: Background updates without UI blocking
- Config Changes: 5-second detection cycle for development
- Memory Usage: Minimal state management, efficient re-rendering
- Bundle Size: Optimized for fast loading with SvelteKit
This design document reflects the current implementation as of October 2025.