utim-cli 1.45.8__tar.gz → 1.46.0__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.46.0}/PKG-INFO +1 -1
- {utim_cli-1.45.8 → utim_cli-1.46.0}/pyproject.toml +1 -1
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/auth.py +47 -60
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/utim.py +5 -8
- {utim_cli-1.45.8 → utim_cli-1.46.0/utim_cli.egg-info}/PKG-INFO +1 -1
- {utim_cli-1.45.8 → utim_cli-1.46.0}/CHANGELOG.md +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/LICENSE +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/MANIFEST.in +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/README.md +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/setup.cfg +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/setup.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/agent.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/backup.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/blender_agent.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/bootstrap.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/client_utils.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/config.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/constants.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/context_pruner.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/doctor.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/knowledge_graph.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/logger.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/mcp_clean_wrapper.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/mcp_client.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/mcp_registry.json +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/orchestrator.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/reflection.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/report.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/scrapy_search.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/auth.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/db.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/email_utils.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/firebase.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/history.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/logging_config.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/models.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/rate_limit.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/router.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/auth_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/completion_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/credit_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/quota_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/session_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/routes/share_routes.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/server/server.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/share.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/share_tui.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/situational_scoring.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/state.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tools.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/__init__.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/history_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/mcp_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/model_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/resume_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/tools_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/tui/update_dialog.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/vector_memory.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli/workspace.py +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli.egg-info/SOURCES.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli.egg-info/dependency_links.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli.egg-info/entry_points.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/utim_cli.egg-info/requires.txt +0 -0
- {utim_cli-1.45.8 → utim_cli-1.46.0}/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.
|
|
7
|
+
version = "1.46.0"
|
|
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,82 +90,69 @@ 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
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
f"{WEB_URL}/auth"
|
|
111
|
-
f"?callback={urllib.parse.quote(callback_url)}"
|
|
112
|
-
)
|
|
113
|
-
|
|
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
|
-
|
|
95
|
+
# ANSI escape codes for formatting
|
|
96
|
+
PURPLE = "\033[1;35m"
|
|
97
|
+
BLUE = "\033[1;34m"
|
|
98
|
+
YELLOW = "\033[1;33m"
|
|
99
|
+
WHITE = "\033[1;37m"
|
|
100
|
+
RESET = "\033[0m"
|
|
101
|
+
DIM = "\033[2m"
|
|
102
|
+
|
|
103
|
+
print(f"\n {PURPLE}UTIM CLI Sign-In{RESET}")
|
|
104
|
+
print(" 1. Visit the UTIM Profile page in your browser:")
|
|
105
|
+
print(f" {BLUE}{WEB_URL}/profile{RESET}")
|
|
106
|
+
print(f" 2. Copy your {WHITE}UTIM API Key{RESET}.")
|
|
107
|
+
print(" 3. Paste the key below to log in.\n")
|
|
108
|
+
|
|
118
109
|
import sys
|
|
119
110
|
sys.stdout.flush()
|
|
120
111
|
|
|
121
|
-
#
|
|
122
|
-
threading.Thread(target=webbrowser.open, args=(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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()
|
|
112
|
+
# Try to open the profile page in a background thread for convenience
|
|
113
|
+
threading.Thread(target=webbrowser.open, args=(f"{WEB_URL}/profile",), daemon=True).start()
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
api_key = input(" Enter UTIM API Key (or press Enter to cancel): ").strip()
|
|
117
|
+
except (EOFError, KeyboardInterrupt):
|
|
118
|
+
print("\n \033[1;33mCancelled.\033[0m\n")
|
|
119
|
+
sys.stdout.flush()
|
|
120
|
+
return
|
|
136
121
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
if not api_key:
|
|
123
|
+
print("\n \033[1;33mCancelled.\033[0m\n")
|
|
124
|
+
sys.stdout.flush()
|
|
140
125
|
return
|
|
141
126
|
|
|
142
|
-
|
|
143
|
-
|
|
127
|
+
print(f" {DIM}Verifying with UTIM server…{RESET}")
|
|
128
|
+
sys.stdout.flush()
|
|
144
129
|
try:
|
|
145
|
-
resp = requests.
|
|
146
|
-
f"{SERVER_URL}/auth/
|
|
147
|
-
|
|
130
|
+
resp = requests.get(
|
|
131
|
+
f"{SERVER_URL}/auth/me",
|
|
132
|
+
headers={"X-API-Key": api_key},
|
|
148
133
|
timeout=15,
|
|
149
134
|
)
|
|
150
|
-
resp.
|
|
135
|
+
if resp.status_code != 200:
|
|
136
|
+
print(f" \033[1;31m✗ Invalid API Key or server error (HTTP {resp.status_code}).\033[0m\n")
|
|
137
|
+
sys.stdout.flush()
|
|
138
|
+
return
|
|
151
139
|
payload = resp.json()
|
|
152
140
|
except Exception as exc:
|
|
153
|
-
|
|
141
|
+
print(f" \033[1;31m✗ Verification failed: {exc}\033[0m\n")
|
|
142
|
+
sys.stdout.flush()
|
|
154
143
|
return
|
|
155
144
|
|
|
156
145
|
# Persist credentials
|
|
157
|
-
config.set("token",
|
|
146
|
+
config.set("token", "direct_key") # sentinel
|
|
158
147
|
config.set("email", payload["email"])
|
|
159
|
-
config.set("uid",
|
|
160
|
-
config.set("name", payload.get("display_name"
|
|
161
|
-
config.set("api_key",
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
f" [dim]Credits:[/dim] [bold]{payload['credits']:,.0f} UTIM[/bold]\n"
|
|
168
|
-
)
|
|
148
|
+
config.set("uid", payload["user_id"])
|
|
149
|
+
config.set("name", payload.get("display_name") or payload["email"].split("@")[0])
|
|
150
|
+
config.set("api_key", api_key)
|
|
151
|
+
|
|
152
|
+
print(f" {YELLOW}✓ Welcome back!{RESET}\n")
|
|
153
|
+
print(f" Signed in as {BLUE}{payload['email']}{RESET}\n")
|
|
154
|
+
print(f" Credits: {payload['credits']:,.0f} UTIM\n")
|
|
155
|
+
sys.stdout.flush()
|
|
169
156
|
|
|
170
157
|
|
|
171
158
|
# ── HTML templates ────────────────────────────────────────────────────────────
|
|
@@ -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.
|
|
588
|
+
console.print(f"\n [bold white]U Think I Make[/bold white] [dim]v1.46.0[/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.
|
|
2694
|
+
current_ver = "1.46.0"
|
|
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.
|
|
2890
|
+
print("U Think I Make v1.46.0")
|
|
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
|