utim-cli 1.45.8__tar.gz → 1.45.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {utim_cli-1.45.8/utim_cli.egg-info → utim_cli-1.45.9}/PKG-INFO +1 -1
- {utim_cli-1.45.8 → utim_cli-1.45.9}/pyproject.toml +1 -1
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/auth.py +28 -53
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/utim.py +5 -8
- {utim_cli-1.45.8 → utim_cli-1.45.9/utim_cli.egg-info}/PKG-INFO +1 -1
- {utim_cli-1.45.8 → utim_cli-1.45.9}/CHANGELOG.md +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/LICENSE +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/MANIFEST.in +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/README.md +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/setup.cfg +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/setup.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/agent.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/backup.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/blender_agent.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/bootstrap.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/client_utils.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/config.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/constants.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/context_pruner.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/doctor.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/knowledge_graph.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/logger.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/mcp_clean_wrapper.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/mcp_client.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/mcp_registry.json +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/orchestrator.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/reflection.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/report.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/scrapy_search.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/auth.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/db.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/email_utils.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/firebase.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/history.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/logging_config.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/models.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/rate_limit.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/router.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/auth_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/completion_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/credit_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/quota_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/session_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/routes/share_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/server/server.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/share.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/share_tui.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/situational_scoring.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/state.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tools.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/history_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/mcp_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/model_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/resume_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/tools_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/tui/update_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/vector_memory.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli/workspace.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli.egg-info/SOURCES.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli.egg-info/dependency_links.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli.egg-info/entry_points.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli.egg-info/requires.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.45.9}/utim_cli.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "utim-cli"
|
|
7
|
-
version = "1.45.
|
|
7
|
+
version = "1.45.9"
|
|
8
8
|
description = "UTIM – Universal Terminal Intelligence Manager. A powerful agentic AI coding assistant for your terminal."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -90,79 +90,54 @@ class _AuthCallbackHandler(http.server.BaseHTTPRequestHandler):
|
|
|
90
90
|
|
|
91
91
|
def login() -> None:
|
|
92
92
|
"""
|
|
93
|
-
|
|
94
|
-
ID token for a UTIM API key from the production server.
|
|
93
|
+
Sign in by prompting the user to copy their UTIM API key from the web dashboard.
|
|
95
94
|
"""
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
except OSError:
|
|
102
|
-
# Fallback: bind to a random free port allocated by the OS if 31415 is in use
|
|
103
|
-
httpd = socketserver.TCPServer(("", 0), _AuthCallbackHandler)
|
|
104
|
-
port = httpd.server_address[1]
|
|
105
|
-
|
|
106
|
-
callback_url = f"http://localhost:{port}/auth/callback"
|
|
107
|
-
|
|
108
|
-
# Build the auth redirect URL pointing to our website auth page.
|
|
109
|
-
auth_url = (
|
|
110
|
-
f"{WEB_URL}/auth"
|
|
111
|
-
f"?callback={urllib.parse.quote(callback_url)}"
|
|
112
|
-
)
|
|
95
|
+
console.print(f"\n [bold {PURPLE}]UTIM CLI Sign-In[/bold {PURPLE}]")
|
|
96
|
+
console.print(" 1. Visit the UTIM Profile page in your browser:")
|
|
97
|
+
console.print(f" [bold {BLUE}]{WEB_URL}/profile[/bold {BLUE}]")
|
|
98
|
+
console.print(" 2. Copy your [bold white]UTIM API Key[/bold white].")
|
|
99
|
+
console.print(" 3. Paste the key below to log in.\n")
|
|
113
100
|
|
|
114
|
-
console.print(f"\n [bold {PURPLE}]Opening browser for sign-in…[/bold {PURPLE}]")
|
|
115
|
-
console.print(f" [dim]If the browser doesn't open, visit:[/dim]")
|
|
116
|
-
console.print(f" [bold {BLUE}]{auth_url}[/bold {BLUE}]\n")
|
|
117
|
-
|
|
118
101
|
import sys
|
|
119
102
|
sys.stdout.flush()
|
|
120
103
|
|
|
121
|
-
#
|
|
122
|
-
threading.Thread(target=webbrowser.open, args=(
|
|
123
|
-
|
|
124
|
-
# Block until the callback arrives with a 5-minute timeout
|
|
125
|
-
import time
|
|
126
|
-
httpd.timeout = 1.0
|
|
127
|
-
start_time = time.time()
|
|
128
|
-
while not _AuthCallbackHandler.received:
|
|
129
|
-
if time.time() - start_time > 300:
|
|
130
|
-
console.print(f" [bold red]✗ Authentication timed out (5 minutes).[/bold red]\n")
|
|
131
|
-
httpd.server_close()
|
|
132
|
-
return
|
|
133
|
-
httpd.handle_request()
|
|
134
|
-
|
|
135
|
-
httpd.server_close()
|
|
104
|
+
# Try to open the profile page in a background thread for convenience
|
|
105
|
+
threading.Thread(target=webbrowser.open, args=(f"{WEB_URL}/profile",), daemon=True).start()
|
|
136
106
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
107
|
+
try:
|
|
108
|
+
api_key = input(" Enter UTIM API Key (or press Enter to cancel): ").strip()
|
|
109
|
+
except (EOFError, KeyboardInterrupt):
|
|
110
|
+
console.print("\n [yellow]Cancelled.[/yellow]\n")
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
if not api_key:
|
|
114
|
+
console.print("\n [yellow]Cancelled.[/yellow]\n")
|
|
140
115
|
return
|
|
141
116
|
|
|
142
|
-
# Exchange Firebase ID token → UTIM API key
|
|
143
117
|
console.print(f" [dim]Verifying with UTIM server…[/dim]")
|
|
144
118
|
try:
|
|
145
|
-
resp = requests.
|
|
146
|
-
f"{SERVER_URL}/auth/
|
|
147
|
-
|
|
119
|
+
resp = requests.get(
|
|
120
|
+
f"{SERVER_URL}/auth/me",
|
|
121
|
+
headers={"X-API-Key": api_key},
|
|
148
122
|
timeout=15,
|
|
149
123
|
)
|
|
150
|
-
resp.
|
|
124
|
+
if resp.status_code != 200:
|
|
125
|
+
console.print(f" [bold red]✗ Invalid API Key or server error (HTTP {resp.status_code}).[/bold red]\n")
|
|
126
|
+
return
|
|
151
127
|
payload = resp.json()
|
|
152
128
|
except Exception as exc:
|
|
153
|
-
console.print(f" [bold red]✗
|
|
129
|
+
console.print(f" [bold red]✗ Verification failed: {exc}[/bold red]\n")
|
|
154
130
|
return
|
|
155
131
|
|
|
156
132
|
# Persist credentials
|
|
157
|
-
config.set("token",
|
|
133
|
+
config.set("token", "direct_key") # sentinel
|
|
158
134
|
config.set("email", payload["email"])
|
|
159
|
-
config.set("uid",
|
|
160
|
-
config.set("name", payload.get("display_name"
|
|
161
|
-
config.set("api_key",
|
|
135
|
+
config.set("uid", payload["user_id"])
|
|
136
|
+
config.set("name", payload.get("display_name") or payload["email"].split("@")[0])
|
|
137
|
+
config.set("api_key", api_key)
|
|
162
138
|
|
|
163
|
-
greeting = "Welcome! Your account has been created." if payload.get("is_new_user") else "Welcome back!"
|
|
164
139
|
console.print(
|
|
165
|
-
f" [bold {YELLOW}]✓
|
|
140
|
+
f" [bold {YELLOW}]✓ Welcome back![/bold {YELLOW}]\n"
|
|
166
141
|
f" [dim]Signed in as[/dim] [bold {BLUE}]{payload['email']}[/bold {BLUE}]\n"
|
|
167
142
|
f" [dim]Credits:[/dim] [bold]{payload['credits']:,.0f} UTIM[/bold]\n"
|
|
168
143
|
)
|
|
@@ -585,7 +585,7 @@ def _print_animated_banner():
|
|
|
585
585
|
# Speed up for spaces to make it feel more like typing
|
|
586
586
|
time.sleep(0.002 if char == " " else 0.005)
|
|
587
587
|
|
|
588
|
-
console.print(f"\n [bold white]U Think I Make[/bold white] [dim]v1.45.
|
|
588
|
+
console.print(f"\n [bold white]U Think I Make[/bold white] [dim]v1.45.9[/dim]")
|
|
589
589
|
user_email = config.email
|
|
590
590
|
user_type = "UTIM Community"
|
|
591
591
|
api_key = config.get("api_key")
|
|
@@ -2420,10 +2420,7 @@ def _build_pt_app(orchestrator, last_sigint):
|
|
|
2420
2420
|
if STATE["busy"]:
|
|
2421
2421
|
console.print(f"\n[dim yellow]⚠ Cannot execute command {text} while agent is busy.[/dim yellow]")
|
|
2422
2422
|
return
|
|
2423
|
-
|
|
2424
|
-
run_in_terminal(lambda: _handle_command(cmd_word, orchestrator, event.app), in_executor=True)
|
|
2425
|
-
else:
|
|
2426
|
-
run_in_terminal(lambda: _handle_command(cmd_word, orchestrator, event.app))
|
|
2423
|
+
run_in_terminal(lambda: _handle_command(cmd_word, orchestrator, event.app))
|
|
2427
2424
|
return
|
|
2428
2425
|
|
|
2429
2426
|
# Check if the user pasted a UTIM share URL/ID
|
|
@@ -2439,7 +2436,7 @@ def _build_pt_app(orchestrator, last_sigint):
|
|
|
2439
2436
|
auth.login()
|
|
2440
2437
|
except Exception as exc:
|
|
2441
2438
|
console.print(f"\n [bold red]✗ Login failed: {exc}[/bold red]\n")
|
|
2442
|
-
run_in_terminal(run_auth_login
|
|
2439
|
+
run_in_terminal(run_auth_login)
|
|
2443
2440
|
# Restore their prompt text so they don't have to retype it
|
|
2444
2441
|
input_field.text = text
|
|
2445
2442
|
return
|
|
@@ -2694,7 +2691,7 @@ def check_and_update_background():
|
|
|
2694
2691
|
return
|
|
2695
2692
|
|
|
2696
2693
|
latest_ver = resp.json().get("version", "")
|
|
2697
|
-
current_ver = "1.45.
|
|
2694
|
+
current_ver = "1.45.9"
|
|
2698
2695
|
|
|
2699
2696
|
def parse_ver(v):
|
|
2700
2697
|
return [int(x) for x in v.split(".") if x.isdigit()]
|
|
@@ -2890,7 +2887,7 @@ app = typer.Typer()
|
|
|
2890
2887
|
def version_callback(value: bool):
|
|
2891
2888
|
if value:
|
|
2892
2889
|
import typer
|
|
2893
|
-
print("U Think I Make v1.45.
|
|
2890
|
+
print("U Think I Make v1.45.9")
|
|
2894
2891
|
raise typer.Exit()
|
|
2895
2892
|
|
|
2896
2893
|
@app.callback(invoke_without_command=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|