Skip to main content

A TUI for Rally (Broadcom) work item management

Project description

Rally TUI & CLI

Rally CLI Logo

CI PyPI version Python

A terminal user interface (TUI) and command-line interface (CLI) for browsing and managing Rally (Broadcom) work items.

Features

CLI Features (NEW)

  • Query tickets: rally-cli tickets --current-iteration --my-tickets
  • Post comments: rally-cli comment S459344 "message"
  • Multiple output formats: text, JSON, CSV for scripting
  • Supports all ticket types: Stories (S/US), Defects (DE), Tasks (TA), Test Cases (TC)

TUI Features

  • Browse Rally tickets in a navigable list
  • View ticket details in a split-pane layout
  • Keyboard-driven interface with vim-style navigation
  • Color-coded ticket types (User Stories, Defects, Tasks, Test Cases)
  • State indicators: Visual workflow state with symbols (. not started, + in progress, - done, accepted)
  • Sorting options: Sort by most recent (default), state flow, owner, or parent (press o to cycle)
  • Splash screen: ASCII art "RALLY TUI" greeting on startup
  • Theme support: Full Textual theme support (catppuccin, nord, dracula, etc.) via command palette, persisted between sessions
  • Copy URL: Press y to copy Rally ticket URL to clipboard
  • Set Points: Press p to set story points on selected ticket
  • Set State: Press s to change ticket state (Defined, In Progress, Completed, etc.)
  • Parent Requirement: Must select a parent Feature before moving to "In Progress" state
  • Quick Create: Press w to create a new workitem (User Story or Defect)
  • Toggle Notes: Press n to toggle between description and notes view
  • Assign Owner: Press a to assign a ticket to a team member (individual or bulk)
  • Sprint Filter: Press i to filter tickets by iteration/sprint
  • My Items Filter: Press u to toggle showing only your tickets
  • Team Breakdown: Press b to view ticket count and points breakdown by owner for a sprint
  • Wide View: Press v to toggle wide view mode showing owner, points, and parent columns
  • User settings: Preferences saved to ~/.config/rally-tui/config.json
  • Settings UI: Press F2 to open settings screen and configure theme, log level, and parent options
  • Keybindings UI: Press F3 to view/edit keyboard shortcuts with Vim and Emacs presets
  • File logging: Logs to ~/.config/rally-tui/rally-tui.log with configurable log level
  • Log redaction: Sensitive data (API keys, emails, user names) automatically redacted from logs
  • Default filter: When connected, shows only tickets in the current iteration owned by you
  • Discussions: View ticket discussions and add comments
  • Attachments: Press A (Shift+a) to view, download, or upload ticket attachments (includes embedded images from description/notes)
  • Local caching: Tickets cached to ~/.cache/rally-tui/ for performance and offline access
  • Cache refresh: Press r to manually refresh the ticket cache
  • Loading indicator: Visual feedback in status bar when fetching tickets from API
  • Async API client: High-performance httpx-based async Rally client with concurrent operations
  • Project scoping: All queries are automatically scoped to your project to prevent cross-project data leakage
  • CI pipeline: GitHub Actions workflow with tests, linting, type checking, and coverage reports

Status

Version 1.1.0 - Full CLI v1.0, append-by-default for rich text fields, query fix.

What's New in 1.1.0

  • Append by Default: --notes, --description, and --ac now append to existing content instead of overwriting
  • Overwrite Flag: --overwrite flag for explicit replacement of rich text fields
  • Query Fix: Fixed tickets show query requiring parentheses for Rally WSAPI

What's New in 1.0.0

  • Full CLI: tickets show, tickets update, tickets delete, tickets search, tickets summary
  • Rich Subcommands: features, iterations, releases, tags, attachments, users, open
  • Shell Completions: rally-cli completions for bash/zsh/fish

What's New in 0.8.2

  • CLI Ticket Creation: rally-cli tickets create "Title" --type UserStory --points 3
  • Backlog Support: --backlog flag to create tickets without iteration assignment
  • Project Logo: Added project branding
  • PyPI Release Workflow: Automated publishing on version tags

Feature Summary

  • CLI Interface: rally-cli tickets, rally-cli comment, rally-cli tickets create, rally-cli tickets update/delete/show/search/summary
  • TUI: Two-panel layout with vim navigation, themes, and keyboard customization
  • Bulk Operations: Multi-select with Space, bulk actions with m (parent, state, iteration, points, owner, yank)
  • Local Caching: Stale-while-revalidate for instant startup, press r to refresh
  • Sprint Filtering: Press i for iteration picker, u for My Items, b for team breakdown
  • Discussions & Comments: View (d) and add comments (c) on tickets
  • Attachments: View, download, upload with A (Shift+a)
  • Configurable Keybindings: Vim/Emacs profiles, press F3 to customize
  • 904+ tests passing across Python 3.11, 3.12, 3.13

See docs/PLAN.md for the full roadmap.

Requirements

  • Python 3.11+
  • A modern terminal with color support

Installation

PyPI version

From PyPI (Recommended)

# Using pipx (isolated environment - recommended)
pipx install rally-tui

# Or using pip
pip install rally-tui

From Source (Development)

# Clone the repository
git clone https://github.com/dan-elliott-appneta/rally-cli.git
cd rally-cli

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# Install in development mode
pip install -e ".[dev]"

Usage

Check Version

rally-tui --version
# Output: rally-tui 1.1.0

Running with Rally API

# Set environment variables
export RALLY_APIKEY=your_api_key_here
export RALLY_WORKSPACE="Your Workspace"
export RALLY_PROJECT="Your Project"

# Run the TUI
rally-tui

Running in Offline Mode

# Without RALLY_APIKEY, the app runs with sample data
rally-tui

CLI (Command-Line Interface)

In addition to the TUI, rally-cli provides a non-interactive CLI for scripting and automation:

# Query tickets in current iteration
rally-cli tickets --current-iteration --my-tickets

# Post a comment to a ticket
rally-cli comment S459344 "Deployed to staging"

# Export to JSON for scripting
rally-cli --format json tickets --current-iteration | jq '.data[].formatted_id'

# Export to CSV for spreadsheets
rally-cli --format csv tickets --current-iteration > sprint.csv

Supported ticket prefixes: S, US (stories), DE (defects), TA (tasks), TC (test cases)

See docs/CLI.md for full CLI documentation.

Environment Variables

Variable Description Default
RALLY_SERVER Rally server hostname rally1.rallydev.com
RALLY_APIKEY Rally API key (required for API access) (none)
RALLY_WORKSPACE Workspace name (from API)
RALLY_PROJECT Project name (from API)

Keyboard Navigation

Key Context Action
Ctrl+P any Open command palette
j / ↓ list Move down
k / ↑ list Move up
g list Jump to top
G list Jump to bottom
Space list Toggle selection on current ticket
Ctrl+A list Select all / Deselect all tickets
m list Open bulk actions menu
/ list Search/filter tickets
Enter list/search Select item (or confirm search)
Esc any Clear filter / Go back
Tab list/detail Switch panel
t any Toggle dark/light theme
y list/detail Copy ticket URL to clipboard
s list/detail Set ticket state
p list/detail Set story points
n list/detail Toggle description/notes
d list/detail Open discussions
a list/detail Assign owner to ticket
A (Shift+a) list/detail View/download/upload attachments
i list/detail Filter by iteration/sprint
u list/detail Toggle My Items filter
o list Cycle sort mode (Recent/State/Owner/Parent)
b list Team breakdown (requires sprint filter)
v list Toggle wide view mode
r list/detail Refresh ticket cache
w list/detail New workitem
F2 any Open settings
F3 any Open keybindings
c discussion Add comment
Ctrl+S comment/settings Submit/Save
q any Quit

User Settings

Settings are stored in ~/.config/rally-tui/config.json:

{
  "theme": "dark",
  "theme_name": "catppuccin-mocha",
  "log_level": "INFO",
  "parent_options": ["F12345", "F12346", "F12347"],
  "keybinding_profile": "vim",
  "keybindings": {
    "navigation.down": "j",
    "navigation.up": "k"
  },
  "cache_enabled": true,
  "cache_ttl_minutes": 5,
  "cache_auto_refresh": true
}

Important: The parent_options array must be configured with valid Feature IDs from your Rally workspace. These are shown when selecting a parent for a ticket before moving to "In Progress" state. If not configured, you can still enter a custom Feature ID manually.

Keybinding Profiles: vim (default), emacs, or custom. Press F3 to view and edit keybindings.

  • Vim profile: j/k navigation, g/G jump, / search
  • Emacs profile: Ctrl+n/Ctrl+p navigation, Ctrl+a/Ctrl+e jump

Cache Settings:

  • cache_enabled: Enable/disable local caching (default: true)
  • cache_ttl_minutes: Cache time-to-live in minutes (default: 5)
  • cache_auto_refresh: Automatically refresh stale cache in background (default: true)

Cache files are stored in ~/.cache/rally-tui/ and are automatically refreshed when stale. Press r to manually refresh.

Available themes: textual-dark, textual-light, catppuccin-mocha, catppuccin-latte, nord, gruvbox, dracula, tokyo-night, monokai, flexoki, solarized-light

Log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL

Logs are written to ~/.config/rally-tui/rally-tui.log with automatic rotation (5MB max, 3 backups).

Development

Project Structure

rally-cli/
├── pyproject.toml           # Project config and dependencies
├── src/rally_tui/           # Main application code
│   ├── app.py               # Textual application entry point
│   ├── app.tcss             # CSS stylesheet
│   ├── config.py            # Rally API config (pydantic-settings)
│   ├── user_settings.py     # User preferences (~/.config/rally-tui/)
│   ├── models/
│   │   ├── ticket.py        # Ticket dataclass
│   │   ├── discussion.py    # Discussion dataclass
│   │   ├── iteration.py     # Iteration dataclass
│   │   ├── attachment.py    # Attachment dataclass
│   │   └── sample_data.py   # Sample data for offline mode
│   ├── screens/
│   │   ├── splash_screen.py      # SplashScreen (startup)
│   │   ├── discussion_screen.py  # DiscussionScreen
│   │   ├── comment_screen.py     # CommentScreen
│   │   ├── points_screen.py      # PointsScreen (set story points)
│   │   ├── state_screen.py       # StateScreen (change ticket state)
│   │   ├── iteration_screen.py   # IterationScreen (filter by sprint)
│   │   ├── parent_screen.py      # ParentScreen (select parent Feature)
│   │   ├── config_screen.py      # ConfigScreen (edit settings)
│   │   ├── keybindings_screen.py # KeybindingsScreen (edit shortcuts)
│   │   ├── bulk_actions_screen.py # BulkActionsScreen (multi-select operations)
│   │   ├── quick_ticket_screen.py # QuickTicketScreen (create tickets)
│   │   └── attachments_screen.py  # AttachmentsScreen (view/download/upload)
│   ├── widgets/
│   │   ├── ticket_list.py   # TicketList widget (left panel, state sorting)
│   │   ├── ticket_detail.py # TicketDetail widget (right panel)
│   │   ├── status_bar.py    # StatusBar widget (rally-tui banner, project, status)
│   │   └── search_input.py  # SearchInput widget (search mode)
│   ├── utils/               # Utility functions
│   │   ├── html_to_text.py  # HTML to plain text converter
│   │   ├── logging.py       # File-based logging configuration
│   │   └── keybindings.py   # Keybinding profiles and utilities
│   └── services/            # Rally API client layer
│       ├── protocol.py      # RallyClientProtocol interface
│       ├── rally_client.py  # Real Rally API client (sync, pyral)
│       ├── async_rally_client.py  # Async Rally API client (httpx)
│       ├── rally_api.py     # Rally WSAPI constants and helpers
│       ├── mock_client.py   # MockRallyClient for testing
│       ├── async_mock_client.py   # AsyncMockRallyClient for testing
│       ├── cache_manager.py # Local file caching for tickets
│       ├── caching_client.py      # CachingRallyClient wrapper (sync)
│       └── async_caching_client.py # AsyncCachingRallyClient wrapper
├── tests/
│   ├── conftest.py               # Pytest fixtures
│   ├── test_ticket_model.py      # Model unit tests
│   ├── test_discussion_model.py  # Discussion model tests
│   ├── test_iteration_model.py   # Iteration model tests
│   ├── test_ticket_list.py       # TicketList widget tests
│   ├── test_ticket_detail.py     # TicketDetail widget tests
│   ├── test_splash_screen.py     # SplashScreen tests
│   ├── test_discussion_screen.py # DiscussionScreen tests
│   ├── test_comment_screen.py    # CommentScreen tests
│   ├── test_points_screen.py     # PointsScreen tests
│   ├── test_state_screen.py      # StateScreen tests
│   ├── test_iteration_screen.py  # IterationScreen tests
│   ├── test_parent_screen.py     # ParentScreen tests
│   ├── test_config_screen.py     # ConfigScreen tests
│   ├── test_bulk_actions_screen.py # BulkActionsScreen tests
│   ├── test_quick_ticket_screen.py # QuickTicketScreen tests
│   ├── test_attachments_screen.py  # AttachmentsScreen tests
│   ├── test_attachment_model.py    # Attachment model tests
│   ├── test_filter_integration.py # Filter integration tests
│   ├── test_status_bar.py        # StatusBar widget tests
│   ├── test_search_input.py      # SearchInput widget tests
│   ├── test_services.py          # Service layer tests
│   ├── test_mock_client_discussions.py  # MockClient discussion tests
│   ├── test_config.py            # Configuration tests
│   ├── test_user_settings.py     # User settings tests
│   ├── test_rally_client.py      # RallyClient tests
│   ├── test_html_to_text.py      # HTML conversion tests
│   ├── test_logging.py           # Logging module tests
│   ├── test_keybindings.py       # Keybinding utilities tests
│   ├── test_keybindings_screen.py # KeybindingsScreen tests
│   ├── test_cache_manager.py     # CacheManager tests
│   ├── test_caching_client.py    # CachingRallyClient tests
│   ├── test_rally_api.py         # Rally API helpers tests
│   ├── test_async_mock_client.py # AsyncMockRallyClient tests
│   ├── test_app_async_integration.py # App async integration tests
│   └── test_snapshots.py         # Visual regression tests
└── docs/
    ├── API.md               # Rally WSAPI reference
    ├── PLAN.md              # Development roadmap
    └── ITERATION_*.md       # Implementation guides (1-14)

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=rally_tui

# Update snapshot baselines
pytest --snapshot-update

Continuous Integration

The project uses GitHub Actions for CI. On every PR:

  • Tests: Run across Python 3.11, 3.12, 3.13
  • Lint: Ruff check and format verification
  • Type Check: Mypy static type analysis
  • Coverage: Reports uploaded to Codecov

All checks must pass before merging.

See TESTING.md for detailed testing documentation.

Documentation

Technology Stack

Versioning

This project uses Semantic Versioning:

  • Version is defined in pyproject.toml
  • Accessible as rally_tui.__version__ in code
  • Displayed with rally-tui --version
  • Shown on splash screen at startup

Version format: MAJOR.MINOR.PATCH

  • MAJOR: Incompatible API changes
  • MINOR: New features (backwards compatible)
  • PATCH: Bug fixes (backwards compatible)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rally_tui-1.1.0.tar.gz (214.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rally_tui-1.1.0-py3-none-any.whl (186.7 kB view details)

Uploaded Python 3

File details

Details for the file rally_tui-1.1.0.tar.gz.

File metadata

  • Download URL: rally_tui-1.1.0.tar.gz
  • Upload date:
  • Size: 214.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for rally_tui-1.1.0.tar.gz
Algorithm Hash digest
SHA256 2446c6f58ba97de7e72c4235ff4021c9efc3a7b8d556a5da9851f25391aaedb7
MD5 5d086a4aa8203f680baed92f9d359191
BLAKE2b-256 73f38f8cb10a1e57000a0497dba718e333efc3f5ee4e4f56ef738af9f0b68cd0

See more details on using hashes here.

File details

Details for the file rally_tui-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: rally_tui-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 186.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for rally_tui-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2dbc78076f09183f73b038af47c630ca3bf571957cab7d147ec22cfb1198986c
MD5 bda0a5112da07d6cdcc2b784441c1212
BLAKE2b-256 fd260a66d29d473f723197ca093b246a4e334b0ed808b7f3648c38159eb0ac7e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page