Rally TUI & CLI
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
oto 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
yto copy Rally ticket URL to clipboard - Set Points: Press
pto set story points on selected ticket - Set State: Press
sto change ticket state (Defined, In Progress, Completed, etc.) - Parent Requirement: Must select a parent Feature before moving to "In Progress" state
- Quick Create: Press
wto create a new workitem (User Story or Defect) - Toggle Notes: Press
nto toggle between description and notes view - Assign Owner: Press
ato assign a ticket to a team member (individual or bulk) - Sprint Filter: Press
ito filter tickets by iteration/sprint - My Items Filter: Press
uto toggle showing only your tickets - Team Breakdown: Press
bto view ticket count and points breakdown by owner for a sprint - Wide View: Press
vto toggle wide view mode showing owner, points, and parent columns - User settings: Preferences saved to
~/.config/rally-tui/config.json - Settings UI: Press
F2to open settings screen and configure theme, log level, and parent options - Keybindings UI: Press
F3to view/edit keyboard shortcuts with Vim and Emacs presets - File logging: Logs to
~/.config/rally-tui/rally-tui.logwith 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
rto 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.2.0 - Schedule state fixes, defect fields, owner filter fix.
What's New in 1.2.0
--stateFix:tickets update --statenow sets Rally's standardScheduleStatefield directly instead of failing on a project-scopedFlowStatelookup- Error Surfacing:
tickets updatenow raises on Rally-side rejections (e.g. an invalid--statevalue) instead of silently reporting success with no change - Defect Fields:
--defect-stateand--resolutionoptions fortickets update(Defect only) - Owner Filter Fix: Fixed
--my-ticketsnot filtering by owner
What's New in 1.1.0
- Append by Default:
--notes,--description, and--acnow append to existing content instead of overwriting - Overwrite Flag:
--overwriteflag for explicit replacement of rich text fields - Query Fix: Fixed
tickets showquery 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 completionsfor bash/zsh/fish
What's New in 0.8.2
- CLI Ticket Creation:
rally-cli tickets create "Title" --type UserStory --points 3 - Backlog Support:
--backlogflag 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 withm(parent, state, iteration, points, owner, yank) - Local Caching: Stale-while-revalidate for instant startup, press
rto refresh - Sprint Filtering: Press
ifor iteration picker,ufor My Items,bfor 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
F3to customize - 1200+ 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
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.2.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
- USER.md - User Manual - Complete guide to using Rally TUI
- API.md - Rally WSAPI Python developer guide
- PLAN.md - Development roadmap and architecture
- ITERATION_1.md - Iteration 1 implementation guide (complete)
- ITERATION_2.md - Iteration 2 implementation guide (complete)
- ITERATION_3.md - Iteration 3 implementation guide (complete)
- ITERATION_4.md - Iteration 4 implementation guide (complete)
- ITERATION_5.md - Iteration 5 implementation guide (complete)
- ITERATION_6.md - Iteration 6 implementation guide (complete)
- ITERATION_8.md - Iteration 8 implementation guide (Discussions & Comments)
- ITERATION_9.md - Iteration 9 implementation guide (Configurable Keybindings)
- ITERATION_10.md - Iteration 10 implementation guide (Iteration & User Filtering)
- ITERATION_12.md - Iteration 12 implementation guide (Bulk Operations)
- ITERATION_13.md - Iteration 13 implementation guide (Attachments)
- ITERATION_14.md - Iteration 14 implementation guide (Local Caching)
Technology Stack
- Textual - Modern Python TUI framework
- pyral - Rally REST API toolkit (sync)
- httpx - Async HTTP client for Rally API
- tenacity - Retry logic for API calls
- pytest-textual-snapshot - Visual regression testing
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
Release files for rally-tui 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rally_tui-1.2.0.tar.gz | 215.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rally_tui-1.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 403.3 kB
Release files / rally_tui-1.2.0.tar.gz
| Download URL | rally_tui-1.2.0.tar.gz |
|---|---|
| Size | 215.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d3e289ee089ca266fa43d9f4c55fb2bfb5f53cb05d8a7293aeffb1c55251adc1
|
|
BLAKE2b-256 checksum How to use checksums |
51cd5ce370cf71bd6d849446d79b5f0dfd2dab6328d03b0b79f8a82096a4088d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / rally_tui-1.2.0-py3-none-any.whl
| Download URL | rally_tui-1.2.0-py3-none-any.whl |
|---|---|
| Size | 187.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3e0b3ee4382836dd3b28d57166db64f9c71181b1281fe25b4e281b524b5236d7
|
|
BLAKE2b-256 checksum How to use checksums |
63d85041ec1338feec8339496d009c6cfa8ad699365ef04d02ad60f5ef6e6a7c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|