strat-gameplay-webapp/backend/terminal_client/help_text.py
Cal Corum d7caa75310 CLAUDE: Add manual outcome testing to terminal client and Phase 3 planning
Terminal Client Enhancements:
- Added list_outcomes command to display all PlayOutcome values
- Added resolve_with <outcome> command for testing specific scenarios
- TAB completion for all outcome names
- Full help documentation and examples
- Infrastructure ready for Week 7 integration

Files Modified:
- terminal_client/commands.py - list_outcomes() and forced outcome support
- terminal_client/repl.py - do_list_outcomes() and do_resolve_with() commands
- terminal_client/completions.py - VALID_OUTCOMES and complete_resolve_with()
- terminal_client/help_text.py - Help entries for new commands

Phase 3 Planning:
- Created comprehensive Week 7 implementation plan (25 pages)
- 6 major tasks covering strategic decisions and result charts
- Updated 00-index.md to mark Week 6 as 100% complete
- Documented manual outcome testing feature

Week 6: 100% Complete 
Phase 3 Week 7: Ready to begin

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 20:53:47 -05:00

383 lines
12 KiB
Python

"""
Help text and documentation for terminal client commands.
Provides detailed, formatted help text for all REPL commands
with usage examples and option descriptions.
Author: Claude
Date: 2025-10-27
"""
from typing import Dict
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.markdown import Markdown
from rich import box
console = Console()
class HelpFormatter:
"""Format and display help text for commands."""
@staticmethod
def show_command_help(command_name: str, help_data: Dict) -> None:
"""
Display detailed help for a specific command.
Args:
command_name: Name of the command
help_data: Dictionary with help information
{
'summary': 'Brief description',
'usage': 'command [OPTIONS]',
'options': [
{'name': '--option', 'type': 'TYPE', 'desc': 'Description'}
],
'examples': ['example 1', 'example 2']
}
"""
# Build help text
help_text = []
# Summary
help_text.append(f"**{command_name}** - {help_data.get('summary', 'No description')}")
help_text.append("")
# Usage
if 'usage' in help_data:
help_text.append("**USAGE:**")
help_text.append(f" {help_data['usage']}")
help_text.append("")
# Display in panel
if help_text:
md = Markdown("\n".join(help_text[:3])) # Just summary and usage
panel = Panel(
md,
title=f"[bold cyan]Help: {command_name}[/bold cyan]",
border_style="cyan",
box=box.ROUNDED
)
console.print(panel)
console.print()
# Options
if 'options' in help_data and help_data['options']:
console.print("[bold cyan]OPTIONS:[/bold cyan]")
# Create options table
table = Table(box=box.SIMPLE, show_header=False, padding=(0, 2))
table.add_column("Option", style="cyan", no_wrap=True)
table.add_column("Type", style="yellow")
table.add_column("Description", style="white")
for opt in help_data['options']:
table.add_row(
opt['name'],
opt.get('type', ''),
opt.get('desc', '')
)
console.print(table)
console.print()
# Examples
if 'examples' in help_data and help_data['examples']:
console.print("[bold cyan]EXAMPLES:[/bold cyan]")
for example in help_data['examples']:
console.print(f" {example}")
console.print()
# Notes
if 'notes' in help_data:
console.print(f"[dim]{help_data['notes']}[/dim]")
console.print()
@staticmethod
def show_command_list() -> None:
"""Display list of all available commands."""
console.print("\n[bold cyan]Available Commands:[/bold cyan]\n")
# Game Management
console.print("[bold yellow]Game Management:[/bold yellow]")
console.print(" new_game Create a new game with test lineups and start it")
console.print(" list_games List all games in state manager")
console.print(" use_game Switch to a different game")
console.print(" status Display current game state")
console.print(" box_score Display box score")
console.print()
# Gameplay
console.print("[bold yellow]Gameplay:[/bold yellow]")
console.print(" defensive Submit defensive decision")
console.print(" offensive Submit offensive decision")
console.print(" resolve Resolve the current play")
console.print(" resolve_with Resolve with a specific outcome (testing)")
console.print(" quick_play Auto-play multiple plays")
console.print()
# Testing
console.print("[bold yellow]Testing & Development:[/bold yellow]")
console.print(" list_outcomes Show all available PlayOutcome values")
console.print()
# Utilities
console.print("[bold yellow]Utilities:[/bold yellow]")
console.print(" config Show configuration")
console.print(" clear Clear the screen")
console.print(" help Show help for commands")
console.print(" quit/exit Exit the REPL")
console.print()
console.print("[dim]Type 'help <command>' for detailed information.[/dim]")
console.print("[dim]Use TAB for auto-completion of commands and options.[/dim]\n")
# Detailed help data for each command
HELP_DATA = {
'new_game': {
'summary': 'Create a new game with test lineups and start it immediately',
'usage': 'new_game [--league LEAGUE] [--home-team ID] [--away-team ID]',
'options': [
{
'name': '--league',
'type': 'sba|pd',
'desc': 'League type (default: sba)'
},
{
'name': '--home-team',
'type': 'INT',
'desc': 'Home team ID (default: 1)'
},
{
'name': '--away-team',
'type': 'INT',
'desc': 'Away team ID (default: 2)'
}
],
'examples': [
'new_game',
'new_game --league pd',
'new_game --league sba --home-team 5 --away-team 3'
]
},
'defensive': {
'summary': 'Submit defensive decision for the current play',
'usage': 'defensive [--alignment TYPE] [--infield DEPTH] [--outfield DEPTH] [--hold BASES]',
'options': [
{
'name': '--alignment',
'type': 'STRING',
'desc': 'Defensive alignment: normal, shifted_left, shifted_right, extreme_shift (default: normal)'
},
{
'name': '--infield',
'type': 'STRING',
'desc': 'Infield depth: in, normal, back, double_play (default: normal)'
},
{
'name': '--outfield',
'type': 'STRING',
'desc': 'Outfield depth: in, normal, back (default: normal)'
},
{
'name': '--hold',
'type': 'LIST',
'desc': 'Comma-separated bases to hold runners: 1,2,3 (default: none)'
}
],
'examples': [
'defensive',
'defensive --alignment shifted_left',
'defensive --infield double_play --hold 1,3',
'defensive --alignment extreme_shift --infield back --outfield back'
]
},
'offensive': {
'summary': 'Submit offensive decision for the current play',
'usage': 'offensive [--approach TYPE] [--steal BASES] [--hit-run] [--bunt]',
'options': [
{
'name': '--approach',
'type': 'STRING',
'desc': 'Batting approach: normal, contact, power, patient (default: normal)'
},
{
'name': '--steal',
'type': 'LIST',
'desc': 'Comma-separated bases to steal: 2,3 (default: none)'
},
{
'name': '--hit-run',
'type': 'FLAG',
'desc': 'Execute hit-and-run play (default: false)'
},
{
'name': '--bunt',
'type': 'FLAG',
'desc': 'Attempt bunt (default: false)'
}
],
'examples': [
'offensive',
'offensive --approach power',
'offensive --steal 2',
'offensive --steal 2,3 --hit-run',
'offensive --approach contact --bunt'
]
},
'resolve': {
'summary': 'Resolve the current play using submitted decisions',
'usage': 'resolve',
'options': [],
'examples': [
'resolve'
],
'notes': 'Both defensive and offensive decisions must be submitted before resolving.'
},
'list_outcomes': {
'summary': 'Display all available PlayOutcome values for manual outcome testing',
'usage': 'list_outcomes',
'options': [],
'examples': [
'list_outcomes'
],
'notes': 'Shows a categorized table of all play outcomes. Use these values with resolve_with command.'
},
'resolve_with': {
'summary': 'Resolve current play with a specific outcome (bypassing dice rolls)',
'usage': 'resolve_with <OUTCOME>',
'options': [
{
'name': 'OUTCOME',
'type': 'STRING',
'desc': 'PlayOutcome enum value. Use list_outcomes to see all available values.'
}
],
'examples': [
'resolve_with single_1',
'resolve_with homerun',
'resolve_with groundball_a',
'resolve_with double_uncapped',
'resolve_with strikeout'
],
'notes': 'Experimental feature for testing specific scenarios without random dice rolls. Useful for testing runner advancement, scoring, and game state changes with known outcomes.'
},
'quick_play': {
'summary': 'Auto-play multiple plays with default decisions',
'usage': 'quick_play [COUNT]',
'options': [
{
'name': 'COUNT',
'type': 'INT',
'desc': 'Number of plays to execute (default: 1). Positional argument.'
}
],
'examples': [
'quick_play',
'quick_play 10',
'quick_play 27 # Play roughly 3 innings',
'quick_play 100 # Play full game quickly'
]
},
'status': {
'summary': 'Display current game state',
'usage': 'status',
'options': [],
'examples': [
'status'
]
},
'box_score': {
'summary': 'Display box score for the current game',
'usage': 'box_score',
'options': [],
'examples': [
'box_score'
]
},
'list_games': {
'summary': 'List all games currently loaded in state manager',
'usage': 'list_games',
'options': [],
'examples': [
'list_games'
]
},
'use_game': {
'summary': 'Switch to a different game',
'usage': 'use_game <GAME_ID>',
'options': [
{
'name': 'GAME_ID',
'type': 'UUID',
'desc': 'UUID of the game to switch to. Positional argument.'
}
],
'examples': [
'use_game a1b2c3d4-e5f6-7890-abcd-ef1234567890',
'use_game <TAB> # Use tab completion to see available games'
]
},
'config': {
'summary': 'Show terminal client configuration',
'usage': 'config',
'options': [],
'examples': [
'config'
]
},
'clear': {
'summary': 'Clear the screen',
'usage': 'clear',
'options': [],
'examples': [
'clear'
]
}
}
def get_help_text(command: str) -> Dict:
"""
Get help data for a command.
Args:
command: Command name
Returns:
Help data dictionary or empty dict if not found
"""
return HELP_DATA.get(command, {})
def show_help(command: str = None) -> None:
"""
Show help for a command or list all commands.
Args:
command: Command name or None for command list
"""
if command:
help_data = get_help_text(command)
if help_data:
HelpFormatter.show_command_help(command, help_data)
else:
console.print(f"[yellow]No help available for '{command}'[/yellow]")
console.print("[dim]Type 'help' to see all available commands.[/dim]")
else:
HelpFormatter.show_command_list()