updating profile flow

This commit is contained in:
kai
2025-12-06 18:20:49 -05:00
parent 02364f800a
commit cf3cfd02ed
3 changed files with 114 additions and 7 deletions

View File

@@ -1,6 +1,9 @@
# tito/commands/login.py
import webbrowser
import time
import json
import urllib.parse
from pathlib import Path
from argparse import ArgumentParser, Namespace
from rich.prompt import Confirm
from tito.commands.base import BaseCommand
@@ -37,7 +40,39 @@ class LoginCommand(BaseCommand):
receiver = AuthReceiver()
try:
port = receiver.start()
target_url = f"{ENDPOINTS['cli_login']}?redirect_port={port}"
# Construct URL with optional profile pre-fill
params = {"redirect_port": str(port)}
# Try to read local profile for auto-fill
try:
# Check project root first, then global home
project_profile = Path("profile.json").resolve()
global_profile = Path.home() / ".tinytorch" / "profile.json"
profile_path = None
if project_profile.exists():
profile_path = project_profile
elif global_profile.exists():
profile_path = global_profile
if profile_path:
self.console.print(f"[dim]Reading profile from: {profile_path}[/dim]")
with open(profile_path, 'r') as f:
profile = json.load(f)
self.console.print(f"[dim]Found profile data: {profile.get('email', 'No email')}[/dim]")
if "email" in profile: params["email"] = profile["email"]
if "name" in profile: params["name"] = profile["name"]
if "affiliation" in profile: params["affiliation"] = profile["affiliation"]
else:
self.console.print(f"[yellow]No profile found (checked ./profile.json and {global_profile})[/yellow]")
except Exception as e:
self.console.print(f"[red]Failed to read profile: {e}[/red]")
query_string = urllib.parse.urlencode(params)
target_url = f"{ENDPOINTS['cli_login']}?{query_string}"
self.console.print(f"Opening browser to: [cyan]{target_url}[/cyan]")
self.console.print("Waiting for authentication...")
webbrowser.open(target_url)

View File

@@ -390,6 +390,19 @@ class SetupCommand(BaseCommand):
if login_result == 0:
self.console.print("[green]✅ Successfully connected to the TinyTorch community![/green]")
# Post-login profile update prompt
self.console.print()
self.console.print(Panel(
"[bold magenta]✨ Update Community Profile ✨[/bold magenta]\n\n"
"Your CLI is now connected. Would you like to update your profile on the TinyTorch community website?",
title="Community Profile Update",
border_style="magenta",
box=box.ROUNDED
))
if Confirm.ask("[bold]Update your community profile?[/bold]", default=True):
self.console.print("[dim]Opening profile editor...[/dim]")
webbrowser.open("https://tinytorch.ai/community/?action=profile")
else:
self.console.print("[yellow]⚠️ Community connection failed or was cancelled. You can try again later with 'tito login'.[/yellow]")
except Exception as e:

View File

@@ -66,10 +66,10 @@ def save_credentials(data: Dict[str, str]) -> None:
except OSError:
pass
# Print file update notification
console = get_console()
relative_path = p.relative_to(Path.home())
console.print(f"[dim]📝 Updated: ~/{relative_path}[/dim]")
# File update notification removed for cleaner UX
# console = get_console()
# relative_path = p.relative_to(Path.home())
# console.print(f"[dim]📝 Updated: ~/{relative_path}[/dim]")
def load_credentials() -> Optional[Dict[str, str]]:
p = _credentials_path()
@@ -213,10 +213,69 @@ class CallbackHandler(http.server.BaseHTTPRequestHandler):
}
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.send_header('Content-type', 'text/html; charset=utf-8')
self.end_headers()
html_content = "<html><body><h1>🔥 Tinytorch <h1> <h2>Login Successful</h2><p>You can close this window and return to the CLI.</p><p><a href='https://tinytorch.netlify.app/dashboard'>Go to TinyTorch Dashboard</a></p><script>window.close()</script></body></html>"
html_content = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TinyTorch CLI Login</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #f8f9fa;
color: #333;
}
.card {
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
text-align: center;
max-width: 400px;
}
h1 { color: #FF5733; margin-bottom: 0.5rem; }
h2 { margin-top: 0; margin-bottom: 1.5rem; font-weight: 600; }
p { color: #666; line-height: 1.5; margin-bottom: 1.5rem; }
.button {
display: inline-block;
background: #FF5733;
color: white;
text-decoration: none;
padding: 10px 20px;
border-radius: 6px;
font-weight: 500;
transition: background 0.2s;
}
.button:hover { background: #E64A29; }
.success-icon { font-size: 48px; margin-bottom: 1rem; display: block; }
</style>
</head>
<body>
<div class="card">
<span class="success-icon">✅</span>
<h1>Tiny🔥Torch</h1>
<h2>Login Successful</h2>
<p>You have successfully authenticated with the CLI. You can now close this window and return to your terminal.</p>
<a href="https://tinytorch.netlify.app/dashboard" class="button">Go to Dashboard</a>
</div>
<script>
// Optional: Attempt to close window automatically after delay
setTimeout(() => {
// window.close(); // Most browsers block this unless script opened window
}, 3000);
</script>
</body>
</html>
"""
self.wfile.write(html_content.encode('utf-8'))
self.wfile.flush()