Files
gh-human-frontier-labs-inc-…/scripts/analyze_requirements.py
2025-11-29 18:47:30 +08:00

245 lines
7.3 KiB
Python

#!/usr/bin/env python3
"""
Requirement analyzer for Bubble Tea TUIs.
Extracts structured requirements from natural language.
"""
import re
from typing import Dict, List
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from utils.validators import RequirementValidator
# TUI archetype keywords
ARCHETYPE_KEYWORDS = {
'file-manager': ['file', 'directory', 'browse', 'navigator', 'ranger', 'three-column'],
'installer': ['install', 'package', 'progress', 'setup', 'installation'],
'dashboard': ['dashboard', 'monitor', 'real-time', 'metrics', 'status'],
'form': ['form', 'input', 'wizard', 'configuration', 'settings'],
'viewer': ['view', 'display', 'log', 'text', 'document', 'reader'],
'chat': ['chat', 'message', 'conversation', 'messaging'],
'table-viewer': ['table', 'data', 'spreadsheet', 'grid'],
'menu': ['menu', 'select', 'choose', 'options'],
'editor': ['edit', 'editor', 'compose', 'write']
}
def extract_requirements(description: str) -> Dict:
"""
Extract structured requirements from description.
Args:
description: Natural language TUI description
Returns:
Dictionary with structured requirements
Example:
>>> reqs = extract_requirements("Build a log viewer with search")
>>> reqs['archetype']
'viewer'
"""
# Validate input
validator = RequirementValidator()
validation = validator.validate_description(description)
desc_lower = description.lower()
# Extract archetype
archetype = classify_tui_type(description)
# Extract features
features = identify_features(description)
# Extract interactions
interactions = identify_interactions(description)
# Extract data types
data_types = identify_data_types(description)
# Determine view type
views = determine_view_type(description)
# Special requirements
special = identify_special_requirements(description)
requirements = {
'archetype': archetype,
'features': features,
'interactions': interactions,
'data_types': data_types,
'views': views,
'special_requirements': special,
'original_description': description,
'validation': validation.to_dict()
}
return requirements
def classify_tui_type(description: str) -> str:
"""Classify TUI archetype from description."""
desc_lower = description.lower()
# Score each archetype
scores = {}
for archetype, keywords in ARCHETYPE_KEYWORDS.items():
score = sum(1 for kw in keywords if kw in desc_lower)
if score > 0:
scores[archetype] = score
if not scores:
return 'general'
# Return highest scoring archetype
return max(scores.items(), key=lambda x: x[1])[0]
def identify_features(description: str) -> List[str]:
"""Identify features from description."""
features = []
desc_lower = description.lower()
feature_keywords = {
'navigation': ['navigate', 'move', 'browse', 'arrow'],
'selection': ['select', 'choose', 'pick'],
'search': ['search', 'find', 'filter', 'query'],
'editing': ['edit', 'modify', 'change', 'update'],
'display': ['display', 'show', 'view', 'render'],
'input': ['input', 'enter', 'type'],
'progress': ['progress', 'loading', 'install'],
'preview': ['preview', 'peek', 'preview pane'],
'scrolling': ['scroll', 'scrollable'],
'sorting': ['sort', 'order', 'rank'],
'filtering': ['filter', 'narrow'],
'highlighting': ['highlight', 'emphasize', 'mark']
}
for feature, keywords in feature_keywords.items():
if any(kw in desc_lower for kw in keywords):
features.append(feature)
return features if features else ['display']
def identify_interactions(description: str) -> Dict[str, List[str]]:
"""Identify user interaction types."""
desc_lower = description.lower()
keyboard = []
mouse = []
# Keyboard interactions
kbd_keywords = {
'navigation': ['arrow', 'hjkl', 'navigate', 'move'],
'selection': ['enter', 'select', 'choose'],
'search': ['/', 'search', 'find'],
'quit': ['q', 'quit', 'exit', 'esc'],
'help': ['?', 'help']
}
for interaction, keywords in kbd_keywords.items():
if any(kw in desc_lower for kw in keywords):
keyboard.append(interaction)
# Default keyboard interactions
if not keyboard:
keyboard = ['navigation', 'selection', 'quit']
# Mouse interactions
if any(word in desc_lower for word in ['mouse', 'click', 'drag']):
mouse = ['click', 'scroll']
return {
'keyboard': keyboard,
'mouse': mouse
}
def identify_data_types(description: str) -> List[str]:
"""Identify data types being displayed."""
desc_lower = description.lower()
data_type_keywords = {
'files': ['file', 'directory', 'folder'],
'text': ['text', 'log', 'document'],
'tabular': ['table', 'data', 'rows', 'columns'],
'messages': ['message', 'chat', 'conversation'],
'packages': ['package', 'dependency', 'module'],
'metrics': ['metric', 'stat', 'data point'],
'config': ['config', 'setting', 'option']
}
data_types = []
for dtype, keywords in data_type_keywords.items():
if any(kw in desc_lower for kw in keywords):
data_types.append(dtype)
return data_types if data_types else ['text']
def determine_view_type(description: str) -> str:
"""Determine if single or multi-view."""
desc_lower = description.lower()
multi_keywords = ['multi-view', 'multiple view', 'tabs', 'tabbed', 'switch', 'views']
three_pane_keywords = ['three', 'three-column', 'three pane']
if any(kw in desc_lower for kw in three_pane_keywords):
return 'three-pane'
elif any(kw in desc_lower for kw in multi_keywords):
return 'multi'
else:
return 'single'
def identify_special_requirements(description: str) -> List[str]:
"""Identify special requirements."""
desc_lower = description.lower()
special = []
special_keywords = {
'validation': ['validate', 'validation', 'check'],
'real-time': ['real-time', 'live', 'streaming'],
'async': ['async', 'background', 'concurrent'],
'persistence': ['save', 'persist', 'store'],
'theming': ['theme', 'color', 'style']
}
for req, keywords in special_keywords.items():
if any(kw in desc_lower for kw in keywords):
special.append(req)
return special
def main():
"""Test requirement analyzer."""
print("Testing Requirement Analyzer\n" + "=" * 50)
test_cases = [
"Build a log viewer with search and highlighting",
"Create a file manager with three-column view",
"Design an installer with progress bars",
"Make a form wizard with validation"
]
for i, desc in enumerate(test_cases, 1):
print(f"\n{i}. Testing: '{desc}'")
reqs = extract_requirements(desc)
print(f" Archetype: {reqs['archetype']}")
print(f" Features: {', '.join(reqs['features'])}")
print(f" Data types: {', '.join(reqs['data_types'])}")
print(f" View type: {reqs['views']}")
print(f" Validation: {reqs['validation']['summary']}")
print("\n✅ All tests passed!")
if __name__ == "__main__":
main()