Skip to content

joshdholtz/wassup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

88 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Wassup logo

CI License Gem

Wassup is a scriptable terminal dashboard that creates real-time, interactive displays of data from various sources. Configure panes and content logic in a Supfile and then run wassup to launch your customized dashboard.

โœจ Features

  • ๐Ÿ“Š Multi-pane dashboard with flexible grid layout
  • ๐Ÿ”„ Real-time updates with configurable refresh intervals
  • โŒจ๏ธ Interactive navigation with keyboard controls
  • ๐ŸŽจ Color-coded display with alert levels
  • ๐Ÿš€ Built-in integrations for GitHub, CircleCI, Netlify, and Shortcut
  • ๐Ÿ“„ Multi-page content within individual panes
  • ๐Ÿ›ก๏ธ Rate limiting for API calls
  • ๐Ÿ”ง Debug mode for testing configurations
  • โšก Performance optimizations with battery-conscious updates

wassup-demo.mov

๐Ÿš€ Quick Start

Basic Custom Content

add_pane do |pane|
  pane.height = 0.5
  pane.width = 0.5
  pane.top = 0
  pane.left = 0

  pane.title = "Current Time"
  pane.interval = 1

  pane.content do |content|
    content.add_row(`date`)
  end
end

GitHub Integration

add_pane do |pane|
  pane.height = 0.5
  pane.width = 0.5
  pane.top = 0
  pane.left = 0

  pane.title = "GitHub PRs"
  pane.highlight = true
  pane.interval = 60 * 5

  pane.type = Panes::GitHub::PullRequests.new(
    org: 'fastlane',
    repo: 'fastlane',
    show_username: true,
    show_interactions: true
  )
end

Custom API Content

require 'json'
require 'rest-client'

add_pane do |pane|
  pane.height = 0.5
  pane.width = 0.5
  pane.top = 0
  pane.left = 0

  pane.highlight = true
  pane.title = "Open PRs - fastlane/fastlane"
  pane.interval = 60 * 5

  pane.content do |content|
    resp = RestClient.get "https://api.github.com/repos/fastlane/fastlane/pulls"
    json = JSON.parse(resp)
    json.each do |pr|
      display = "##{pr["number"]} #{pr["title"]}"
      content.add_row(display, pr["html_url"])
    end
  end
  
  pane.selection do |url|
    `open #{url}`
  end
end

Installation

Add this line to your application's Gemfile:

gem 'wassup'

And then execute:

$ bundle install

Or install it yourself as:

$ gem install wassup

๐Ÿ“‹ Built-in Integrations

GitHub

Monitor pull requests, releases, and search results across your repositories.

# Pull Requests
pane.type = Panes::GitHub::PullRequests.new(
  org: 'organization',
  repo: 'repository',
  show_username: true,        # Show PR author
  show_interactions: true     # Show comments/reactions
)

# Releases
pane.type = Panes::GitHub::Releases.new(
  org: 'organization',
  repo: 'repository'
)

# Search
pane.type = Panes::GitHub::Search.new(
  org: 'organization',
  repo: 'repository',         # Optional - searches all org repos if nil
  query: 'is:pr is:open',     # GitHub search query
  show_repo: true,            # Show repository name
  show_username: true,        # Show author
  show_interactions: true     # Show interaction counts
)

CircleCI

Monitor workflow status across your projects.

pane.type = Panes::CircleCI::Workflows.new(
  vcs: 'github',
  org: 'organization',
  repo: 'repository'
)

Netlify

Track deployment status for your sites.

pane.type = Panes::Netlify::Deploys.new(
  site_id: 'your-netlify-site-id'
)

Shortcut

Monitor stories and tasks in your project management.

# Single query
pane.type = Panes::Shortcut::Stories.new(
  query: 'owner:username'
)

# Multiple queries as pages
pane.type = Panes::Shortcut::Stories.new(
  query_pages: {
    "My Stories": "owner:username",
    "Team Stories": "team:development",
    "In Progress": "state:\"In Progress\""
  }
)

โš™๏ธ Configuration

Pane Properties

Property Type Description
height Float Height as percentage of terminal (0.0 to 1.0)
width Float Width as percentage of terminal (0.0 to 1.0)
top Float Top position as percentage (0.0 to 1.0)
left Float Left position as percentage (0.0 to 1.0)
title String Pane title displayed in border
description String Description shown in help mode
highlight Boolean Enable row highlighting and selection
interval Integer/Float Refresh interval in seconds
show_refresh Boolean Show refresh animation
alert_level AlertLevel Alert level for visual emphasis

Alert Levels

pane.alert_level = AlertLevel::HIGH     # Red - Critical alerts
pane.alert_level = AlertLevel::MEDIUM   # Yellow - Warnings
pane.alert_level = AlertLevel::LOW      # Cyan - Information

Content and Selection

pane.content do |content|
  # Add rows to display
  content.add_row("Display text", data_object)
  
  # Add rows to specific pages
  content.add_row("Page 1 content", data, page: "Page 1")
  content.add_row("Page 2 content", data, page: "Page 2")
  
  # Color-coded text
  content.add_row("[fg=red]Error[fg=white] - [fg=green]Success")
end

# Define selection actions
pane.selection do |selected_data|
  # Default action (Enter key)
  `open #{selected_data['url']}`
end

pane.selection('o', 'Open in browser') do |data|
  `open #{data['html_url']}`
end

pane.selection('c', 'Copy to clipboard') do |data|
  `echo '#{data['title']}' | pbcopy`
end

๐Ÿ”ง Environment Setup

Required Environment Variables

# GitHub integration
export WASSUP_GITHUB_USERNAME="your-username"
export WASSUP_GITHUB_ACCESS_TOKEN="your-personal-access-token"

# CircleCI integration
export WASSUP_CIRCLE_CI_API_TOKEN="your-circleci-token"

# Netlify integration
export WASSUP_NETLIFY_TOKEN="your-netlify-token"

# Shortcut integration
export WASSUP_SHORTCUT_TOKEN="your-shortcut-token"

GitHub Token Setup

  1. Go to GitHub Settings โ†’ Developer settings โ†’ Personal access tokens
  2. Generate a new token with these scopes:
    • repo - Full control of private repositories
    • public_repo - Access public repositories
    • user - Read user profile data

๐ŸŽฎ Keyboard Controls

Key Action
1-9 Focus specific panes
j/k Move selection up/down
h/l Navigate between pages
Enter Execute selection action
r Force refresh current pane
? Show help
q Quit
c Copy error to clipboard (when error occurs)

๐Ÿš€ Usage

Basic Usage

# Run with default Supfile
wassup

# Run with custom file
wassup MySupfile

# Debug mode to test individual panes
wassup --debug

# Run with socket port for external monitoring
wassup Supfile 8080

Advanced Examples

Dashboard Layout

# Top row - GitHub PRs and Releases
add_pane do |pane|
  pane.height = 0.5; pane.width = 0.5; pane.top = 0; pane.left = 0
  pane.title = "GitHub PRs"
  pane.type = Panes::GitHub::PullRequests.new(org: 'myorg', repo: 'myrepo')
end

add_pane do |pane|
  pane.height = 0.5; pane.width = 0.5; pane.top = 0; pane.left = 0.5
  pane.title = "Releases"
  pane.type = Panes::GitHub::Releases.new(org: 'myorg', repo: 'myrepo')
end

# Bottom row - CircleCI and custom content
add_pane do |pane|
  pane.height = 0.5; pane.width = 0.5; pane.top = 0.5; pane.left = 0
  pane.title = "CI Status"
  pane.type = Panes::CircleCI::Workflows.new(vcs: 'github', org: 'myorg', repo: 'myrepo')
end

add_pane do |pane|
  pane.height = 0.5; pane.width = 0.5; pane.top = 0.5; pane.left = 0.5
  pane.title = "System Status"
  pane.interval = 30
  pane.content do |content|
    uptime = `uptime`.strip
    load_avg = uptime.match(/load average: (.+)$/)[1]
    content.add_row("Load: #{load_avg}")
    content.add_row("Uptime: #{uptime}")
  end
end

Multi-page Content

add_pane do |pane|
  pane.height = 1.0; pane.width = 1.0; pane.top = 0; pane.left = 0
  pane.title = "Multi-page Dashboard"
  pane.highlight = true
  pane.interval = 60

  pane.content do |content|
    # GitHub PRs page
    github_prs = fetch_github_prs()
    github_prs.each do |pr|
      content.add_row("##{pr['number']} #{pr['title']}", pr, page: "GitHub PRs")
    end

    # CircleCI page
    workflows = fetch_circleci_workflows()
    workflows.each do |workflow|
      content.add_row("#{workflow['name']} - #{workflow['status']}", workflow, page: "CircleCI")
    end

    # System metrics page
    content.add_row("CPU: #{`top -l 1 | grep "CPU usage"`}", nil, page: "System")
    content.add_row("Memory: #{`top -l 1 | grep "PhysMem"`}", nil, page: "System")
  end
end

Error Handling with Alerts

add_pane do |pane|
  pane.height = 0.5; pane.width = 1.0; pane.top = 0; pane.left = 0
  pane.title = "Service Status"
  pane.interval = 60
  pane.alert_level = AlertLevel::HIGH

  pane.content do |content|
    begin
      services = check_services()
      services.each do |service|
        status_color = service[:status] == 'up' ? 'green' : 'red'
        content.add_row("[fg=#{status_color}]#{service[:name]}: #{service[:status]}")
      end
    rescue => e
      content.add_row("[fg=red]Error: #{e.message}")
    end
  end
end

๐Ÿ› ๏ธ Troubleshooting

Common Issues

API Rate Limiting

GitHub API has rate limits. Wassup includes built-in rate limiting:

  • Authenticated requests: 5,000 per hour
  • Search API: 30 requests per minute
  • Rate limit information is displayed in debug mode

Authentication Errors

# Check if your tokens are set correctly
echo $WASSUP_GITHUB_ACCESS_TOKEN
echo $WASSUP_GITHUB_USERNAME

# Test token validity
curl -H "Authorization: token $WASSUP_GITHUB_ACCESS_TOKEN" https://api.github.com/user

Terminal Size Issues

Wassup requires a minimum terminal size. If panes appear corrupted:

  1. Resize your terminal window
  2. Press r to refresh the display
  3. Check that your pane dimensions don't exceed 1.0

Debug Mode

Use debug mode to test individual panes:

wassup --debug

This will:

  • Show detailed error messages
  • Display API rate limit information
  • Allow testing panes in isolation

Performance Tips

Battery Optimization

Wassup includes battery-conscious updates:

  • Longer refresh intervals when on battery power
  • Reduced API calls during low battery
  • Configurable performance settings

Memory Usage

For large datasets:

  • Use pagination in your content blocks
  • Limit the number of rows returned
  • Consider using shorter refresh intervals for critical data only

๐Ÿ”ง Development

Setup

git clone https://github.com/joshdholtz/wassup.git
cd wassup
bin/setup

Running Tests

rake spec

Interactive Console

bin/console

Installation

# Install locally
bundle exec rake install

# Release new version
bundle exec rake release

Creating New Pane Types

  1. Create a new class in lib/wassup/panes/
  2. Inherit from Wassup::Pane
  3. Implement the required methods:
    • content - Returns the pane content
    • selection - Handles selection actions

Example:

module Wassup
  module Panes
    module MyService
      class MyPane < Wassup::Pane
        def initialize(api_key:)
          @api_key = api_key
        end

        def content
          # Fetch and return content
        end

        def selection(data)
          # Handle selection
        end
      end
    end
  end
end

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guide for details.

Ways to Contribute

  1. Bug Reports - Found a bug? Open an issue
  2. Feature Requests - Have an idea? Start a discussion
  3. Code Contributions - Submit a pull request
  4. Documentation - Help improve our docs
  5. New Integrations - Add support for new services

Development Guidelines

  • Follow existing code style and patterns
  • Add tests for new features
  • Update documentation for new functionality
  • Ensure all tests pass before submitting PR

This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Wassup project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

About

Easily scriptable terminal dashboard

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

 

Contributors 3

  •  
  •  
  •