Enhancing Pieces CLI User Experience Major Improvements Needed
Hey guys! Let's dive deep into the user experience of the Pieces CLI. We've spotted some areas that could seriously use a glow-up to make it more user-friendly and boost overall satisfaction. This isn't just about making things look pretty; it's about making the CLI more intuitive, discoverable, and a joy to use.
π¨ UX Enhancement Comprehensive User Experience Improvements
Summary
The Pieces CLI has some user experience quirks that can make it a bit of a puzzle sometimes. These issues mess with how easily you can find stuff, how smoothly you can use it, and how happy you are with the whole experience. We're talking about everything from command names that don't quite click to error messages that leave you scratching your head, and even missing progress updates that make you wonder if the CLI's just taking a coffee break. Let's break it down, shall we?
Key UX Issues Identified
1. π Command Discoverability Problems
Current Issues:
- Some commands have names that aren't super obvious (like, what's the deal with
execute
versusrun
?). - There's no built-in search to help you find the command you need.
- Command suggestions only pop up if you make a typo, not if you're just exploring.
- The difference between
pieces run
(interactive) andpieces execute
(run code) is kinda confusing.
Command discoverability is key, and right now, we're falling a bit short. You shouldn't need a secret decoder ring to figure out what each command does. We need to make it easier to find and understand the right tool for the job.
Example of Confusion:
# What's the difference?
pieces run # Starts interactive session
pieces execute # Runs a code snippet
pieces open # Opens... what exactly?
# User expects:
pieces repl # Clear: starts REPL
pieces run-snippet # Clear: executes code
pieces open-asset # Clear: opens an asset
See what I mean? It's not immediately clear what each of these commands does. A little renaming could go a long way here.
2. β Poor Error Messages
Current State:
# Unhelpful error
$ pieces invalid-command
Error: UNKNOWN EXCEPTION
# No actionable information
$ pieces list assets --invalid-flag
Error: Invalid argument
# Technical jargon exposed
$ pieces ask "question"
Error: WebSocket connection failed: [Errno 61] Connection refused
Error messages are like little breadcrumbs guiding you back on the right path. But right now, they're more like cryptic notes left by a mischievous gnome. An UNKNOWN EXCEPTION
? That's not going to help anyone! We need errors that actually tell you what's up, why it happened, and how to fix it.
Missing:
- What went wrong
- Why it went wrong
- How to fix it
- Where to get help
3. β³ Missing Progress Indicators
Problems:
- No feedback during long operations β it's like the CLI's gone radio silent.
- You're left guessing if it's actually working or just frozen in time.
- No estimated time to completion β are we talking seconds or centuries?
- Silent failures can look like the CLI's just hanging, which is super frustrating.
Progress indicators are your CLI's way of saying, "Hey, I'm on it!" Without them, you're flying blind. We need to give users a heads-up that things are happening, and maybe even a countdown timer for the suspense.
# Current experience
$ pieces search "complex query"
# ... nothing for 30 seconds ...
# Is it working? Frozen? Network issue?
4. π Inconsistent Output Formatting
Issues:
- ASCII art separators (
###########
) look like they're straight out of the 90s. - Spacing between sections is all over the place.
- No options for structured output (like JSON or YAML) β talk about inflexible!
- Wide content gets mangled and looks messy.
Output formatting is like the CLI's outfit β it should be clean, consistent, and easy on the eyes. Right now, it's a bit of a fashion disaster. Let's bring it into the 21st century with some modern styling and structured output options.
# Current output
##########################
Asset Name: My Code
##########################
Language: Python
##########################
# Desired output
ββ Asset: My Code ββββββββββββββ
β Language: Python β
β Created: 2024-01-15 β
β Tags: algorithm, sorting β
ββββββββββββββββββββββββββββββββ
Proposed Solutions
Alright, enough with the problems β let's talk solutions! We've got some ideas brewing that should make the Pieces CLI a whole lot smoother.
Solution 1: Enhanced Command Structure
First up, let's make those commands crystal clear. We're talking aliases, intuitive names, and a structure that just makes sense. Think of it as giving the CLI a linguistic facelift.
# src/pieces/commands/improved_commands.py
class CommandAliases:
"""User-friendly command aliases"""
ALIASES = {
# Clear, intuitive names
'repl': 'run',
'interactive': 'run',
'shell': 'run',
'run-snippet': 'execute',
'exec': 'execute',
'run-code': 'execute',
'open-asset': 'open',
'view': 'open',
'show': 'open',
# Common typos
'lisr': 'list',
'seach': 'search',
'cerate': 'create',
}
class ImprovedCommands:
"""Commands with better UX"""
@command(
name="search",
aliases=["find", "query", "lookup"],
description="Search for assets, conversations, or anything in Pieces"
)
def search_command(self, query: str, type: str = "all"):
"""Unified search across all content"""
# Show immediate feedback
with Progress() as progress:
task = progress.add_task(f"Searching for '{query}'...", total=100)
# Search different types
results = {
'assets': self.search_assets(query, progress, task),
'conversations': self.search_conversations(query, progress, task),
'collections': self.search_collections(query, progress, task),
}
# Display results in organized way
self.display_search_results(results, query)
Solution 2: Intelligent Error Handling
Next, we're tackling those gnarly error messages. We want to transform them from cryptic riddles into helpful advice. Imagine error messages that actually tell you what's wrong and how to fix it β now we're talking!
# src/pieces/errors/user_friendly.py
class UserFriendlyError:
"""Transform technical errors into helpful messages"""
ERROR_MAPPINGS = {
ConnectionError: {
'message': "Cannot connect to Pieces OS",
'reasons': [
"Pieces OS may not be running",
"Network connection issues",
"Firewall blocking connection"
],
'solutions': [
"Ensure Pieces OS is running: pieces status",
"Check your network connection",
"Try restarting Pieces OS: pieces restart"
],
'help_link': "https://docs.pieces.app/troubleshooting/connection"
},
AuthenticationError: {
'message': "Authentication failed",
'reasons': [
"Invalid or expired credentials",
"Not logged in"
],
'solutions': [
"Log in again: pieces login",
"Check your account status at pieces.app"
],
'help_link': "https://docs.pieces.app/auth"
}
}
@classmethod
def format_error(cls, error: Exception) -> str:
"""Format error for user consumption"""
error_type = type(error)
if error_type in cls.ERROR_MAPPINGS:
mapping = cls.ERROR_MAPPINGS[error_type]
# Build user-friendly message
output = []
output.append(f"β {mapping['message']}")
output.append("")
if mapping.get('reasons'):
output.append("Possible reasons:")
for reason in mapping['reasons']:
output.append(f" β’ {reason}")
output.append("")
if mapping.get('solutions'):
output.append("Try these solutions:")
for i, solution in enumerate(mapping['solutions'], 1):
output.append(f" {i}. {solution}")
output.append("")
if mapping.get('help_link'):
output.append(f"π More help: {mapping['help_link']}")
return "\n".join(output)
# Fallback for unknown errors
return cls.format_unknown_error(error)
Solution 3: Rich Progress Indicators
Let's ditch the silent treatment and add some progress indicators! We want you to know what's happening under the hood, whether it's a spinner, a progress bar, or even live output streaming. No more guessing games!
# src/pieces/ui/progress.py
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn
from rich.console import Console
from typing import Optional, Callable
class RichProgress:
"""Enhanced progress indicators for better UX"""
def __init__(self):
self.console = Console()
def with_spinner(self, message: str, task: Callable):
"""Show spinner for indeterminate progress"""
with self.console.status(message, spinner="dots"):
return task()
def with_progress_bar(self,
items: list,
task: Callable,
description: str = "Processing"):
"""Show progress bar for determinate progress"""
with Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
BarColumn(),
TextColumn("[progress.percentage]{task.percentage:>3.0f}%"
),
console=self.console
) as progress:
task_id = progress.add_task(description, total=len(items))
results = []
for item in items:
result = task(item)
results.append(result)
progress.advance(task_id)
return results
def live_output(self, generator, title: str = "Output"):
"""Display live streaming output"""
from rich.live import Live
from rich.panel import Panel
output_lines = []
with Live(
Panel("", title=title, border_style="green"),
refresh_per_second=4,
console=self.console
) as live:
for chunk in generator:
output_lines.append(chunk)
content = "".join(output_lines)
live.update(Panel(content, title=title, border_style="green"))
return "".join(output_lines)
Solution 4: Modern Output Formatting
Time to give the CLI's output a makeover! We're talking sleek tables, panels, and trees β all styled with the Rich library. Say goodbye to ASCII art and hello to beautiful, readable output.
# src/pieces/ui/formatters.py
from rich.table import Table
from rich.panel import Panel
from rich.tree import Tree
from rich.syntax import Syntax
from typing import Dict, List, Any
class ModernFormatters:
"""Modern, beautiful output formatting"""
@staticmethod
def format_asset(asset: Dict[str, Any]) -> Panel:
"""Format asset with modern box drawing"""
from rich.console import Group
from rich.align import Align
# Create formatted content
content = Group(
f"[bold]Language:[/bold] {asset.get('language', 'Unknown')}",
f"[bold]Created:[/bold] {asset.get('created', 'Unknown')}",
f"[bold]Tags:[/bold] {', '.join(asset.get('tags', [])}",
"",
Syntax(
asset.get('content', ''),
asset.get('language', 'text'),
theme="monokai",
line_numbers=True
)
)
return Panel(
content,
title=f"π {asset.get('name', 'Untitled')}",
border_style="blue",
padding=(1, 2)
)
@staticmethod
def format_table(data: List[Dict], title: str = None) -> Table:
"""Create beautiful tables"""
table = Table(title=title, show_lines=True)
# Auto-detect columns
if data:
for key in data[0].keys():
table.add_column(key.title(), style="cyan")
for row in data:
table.add_row(*[str(v) for v in row.values()])
return table
@staticmethod
def format_tree(data: Dict, title: str = "Structure") -> Tree:
"""Format hierarchical data as tree"""
tree = Tree(f"[bold]{title}[/bold]")
def add_nodes(node: Tree, data: Dict):
for key, value in data.items():
if isinstance(value, dict):
branch = node.add(f"π {key}")
add_nodes(branch, value)
else:
node.add(f"π {key}: {value}")
add_nodes(tree, data)
return tree
Solution 5: Command Search & Discovery
Let's make finding commands a breeze! We're building a search system that understands typos, aliases, and even keywords in descriptions. Plus, we'll add suggestions to help you out when you're not quite sure what you're looking for.
# src/pieces/commands/search.py
from difflib import get_close_matches
from typing import List, Optional
class CommandSearch:
"""Enhanced command discovery"""
def __init__(self, commands: Dict[str, Command]):
self.commands = commands
self.build_search_index()
def build_search_index(self):
"""Build search index for commands"""
self.index = {}
for name, cmd in self.commands.items():
# Index by name
self.index[name] = cmd
# Index by aliases
for alias in cmd.aliases:
self.index[alias] = cmd
# Index by keywords in description
words = cmd.description.lower().split()
for word in words:
if word not in self.index:
self.index[word] = []
self.index[word].append(cmd)
def search(self, query: str) -> List[Command]:
"""Search commands by query"""
query = query.lower()
results = set()
# Exact match
if query in self.index:
results.add(self.index[query])
# Fuzzy match
matches = get_close_matches(query, self.index.keys(), n=5, cutoff=0.6)
for match in matches:
if isinstance(self.index[match], list):
results.update(self.index[match])
else:
results.add(self.index[match])
return list(results)
def suggest_command(self, invalid_cmd: str) -> Optional[str]:
"""Suggest correct command for typos"""
suggestions = self.search(invalid_cmd)
if suggestions:
# Format suggestion
suggestion = suggestions[0]
return (
f"Command '{invalid_cmd}' not found. "
f"Did you mean '{suggestion.name}'?\n\n"
f"Run 'pieces {suggestion.name} --help' for usage."
)
return None
Solution 6: Interactive Help System
Finally, let's add an interactive help system that guides you through the CLI's features and workflows. Think of it as a friendly tour guide for your command-line adventures.
# src/pieces/help/interactive.py
class InteractiveHelp:
"""Interactive help system for better discoverability"""
def show_interactive_help(self):
"""Show interactive command browser"""
from rich.prompt import Prompt
from rich.console import Console
console = Console()
while True:
console.print("\n[bold]Pieces CLI Help[/bold]")
console.print("1. Browse commands by category")
console.print("2. Search for a command")
console.print("3. View common workflows")
console.print("4. Troubleshooting guide")
console.print("5. Exit help")
choice = Prompt.ask(
"\nWhat would you like help with?",
choices=["1", "2", "3", "4", "5"],
default="1"
)
if choice == "1":
self.browse_by_category()
elif choice == "2":
self.search_commands()
elif choice == "3":
self.show_workflows()
elif choice == "4":
self.show_troubleshooting()
else:
break
def browse_by_category(self):
"""Browse commands organized by category"""
categories = {
"Asset Management": ["create", "list", "search", "delete", "open"],
"AI & Copilot": ["ask", "explain", "generate", "complete"],
"Configuration": ["config", "login", "logout", "status"],
"Collaboration": ["share", "conversation", "commit"],
}
# Show category menu
# ... implementation ...
Implementation Timeline
So, how are we going to make all this happen? Hereβs the plan:
Week 1 Foundation
- [ ] Implement command aliases system
- [ ] Create user-friendly error formatter
- [ ] Add basic progress indicators
Week 2 Rich UI
- [ ] Integrate Rich library for formatting
- [ ] Implement modern output formatters
- [ ] Add progress bars and spinners
Week 3 Discovery
- [ ] Build command search system
- [ ] Implement interactive help
- [ ] Add command suggestions
Week 4 Polish
- [ ] Add output format options (
--format json/yaml/table
) - [ ] Implement color themes
- [ ] Add accessibility features
Success Metrics
How will we know if we've nailed it? Here are the metrics we'll be watching:
- Command discovery time: < 10 seconds
- Error resolution rate: > 80% self-service
- User satisfaction: > 4.5/5 stars
- Support ticket reduction: 50%
Before/After Examples
Let's see a sneak peek of the transformation:
Before:
$ pieces lst asstes
Error: Unknown command
$ pieces list assets
######################
Asset 1
######################
After:
$ pieces lst asstes
Command 'lst asstes' not found. Did you mean 'list assets'?
Run 'pieces list assets --help' for usage.
$ pieces list assets
ββ Your Assets (showing 1-10 of 45) ββββββββββββββββββββββ
β π Quick Sort Algorithm Python 2 days ago β
β π API Response Handler TypeScript 3 days ago β
β π Database Connection Pool Java 1 week ago β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Press 'n' for next page, 'p' for previous, 'q' to quit