akashcli 4.7.5__tar.gz → 4.7.6__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.
- {akashcli-4.7.5 → akashcli-4.7.6}/PKG-INFO +1 -1
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/cli.py +20 -15
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli.egg-info/PKG-INFO +1 -1
- {akashcli-4.7.5 → akashcli-4.7.6}/pyproject.toml +1 -1
- {akashcli-4.7.5 → akashcli-4.7.6}/README.md +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/__init__.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/_net.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/auth.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/client.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/config.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/crypto.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/env_manager.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/exceptions.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/exec.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/integrity.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/logger.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/models.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/p2p.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/packages.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/relay.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/restore.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/snapshot_crypto.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/storage.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/terminal.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/updater.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/uploader.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli/utils.py +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli.egg-info/SOURCES.txt +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli.egg-info/dependency_links.txt +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli.egg-info/entry_points.txt +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli.egg-info/requires.txt +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/akashcli.egg-info/top_level.txt +0 -0
- {akashcli-4.7.5 → akashcli-4.7.6}/setup.cfg +0 -0
|
@@ -47,11 +47,12 @@ def _gr(s: str) -> str: return f"{_GR}{s}{_RS}"
|
|
|
47
47
|
|
|
48
48
|
# ── Spinner (single-line, no flicker) ────────────────────────────────────────
|
|
49
49
|
class _Spin:
|
|
50
|
-
"""Minimal inline spinner with instant frame-0 rendering, smooth
|
|
50
|
+
"""Minimal inline spinner with instant frame-0 rendering, smooth visibility, and clean cleanup."""
|
|
51
51
|
_FRAMES = ("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏")
|
|
52
52
|
|
|
53
|
-
def __init__(self, label: str, min_seconds: float = 0.35, disabled: bool = False):
|
|
53
|
+
def __init__(self, label: str, min_seconds: float = 0.35, disabled: bool = False, prefix: str = ""):
|
|
54
54
|
self._label = label
|
|
55
|
+
self._prefix = prefix
|
|
55
56
|
self._disabled = disabled or (not sys.stdout.isatty())
|
|
56
57
|
self._min_seconds = min_seconds
|
|
57
58
|
self._i = 0
|
|
@@ -65,18 +66,21 @@ class _Spin:
|
|
|
65
66
|
import threading, time
|
|
66
67
|
self._active = True
|
|
67
68
|
self._t0 = time.monotonic()
|
|
68
|
-
|
|
69
|
-
sys.stdout.write(
|
|
69
|
+
pfx = self._prefix + " " if self._prefix else " "
|
|
70
|
+
sys.stdout.write(f"\r{pfx}{_C}{self._FRAMES[0]}{_RS} {_DM}{self._label}{_RS} ")
|
|
70
71
|
sys.stdout.flush()
|
|
71
72
|
|
|
72
73
|
def _spin():
|
|
73
74
|
time.sleep(0.04)
|
|
74
75
|
while self._active:
|
|
75
76
|
f = self._FRAMES[self._i % len(self._FRAMES)]
|
|
76
|
-
|
|
77
|
+
now = time.monotonic()
|
|
78
|
+
dur = now - self._t0
|
|
79
|
+
dur_str = f" {_dim(f'({dur:.1f}s)')}" if dur >= 1.0 else ""
|
|
80
|
+
sys.stdout.write(f"\r\033[2K{pfx}{_C}{f}{_RS} {_DM}{self._label}{_RS}{dur_str} ")
|
|
77
81
|
sys.stdout.flush()
|
|
78
82
|
self._i += 1
|
|
79
|
-
time.sleep(0.
|
|
83
|
+
time.sleep(0.06)
|
|
80
84
|
|
|
81
85
|
self._thread = threading.Thread(target=_spin, daemon=True)
|
|
82
86
|
self._thread.start()
|
|
@@ -95,7 +99,7 @@ class _Spin:
|
|
|
95
99
|
self._active = False
|
|
96
100
|
if self._thread:
|
|
97
101
|
self._thread.join(timeout=0.2)
|
|
98
|
-
sys.stdout.write(
|
|
102
|
+
sys.stdout.write("\r\033[2K")
|
|
99
103
|
sys.stdout.flush()
|
|
100
104
|
|
|
101
105
|
def _resolve_client(url_override: str = None, require_key: bool = False, silent: bool = False):
|
|
@@ -3420,6 +3424,7 @@ def mcp_serve(
|
|
|
3420
3424
|
args = frame.get("arguments", {})
|
|
3421
3425
|
t0 = time.monotonic()
|
|
3422
3426
|
now_str = datetime.datetime.now().strftime("%H:%M:%S")
|
|
3427
|
+
ts_pfx = f" {_GR}{now_str}{_RS}"
|
|
3423
3428
|
|
|
3424
3429
|
if t_name == "akash_exec_command":
|
|
3425
3430
|
cmd = args.get("command", "")
|
|
@@ -3427,7 +3432,7 @@ def mcp_serve(
|
|
|
3427
3432
|
|
|
3428
3433
|
is_safe, sec_reason = _sanitize_agent_command(cmd, scopes=cached.get("scopes", "*"))
|
|
3429
3434
|
if not is_safe:
|
|
3430
|
-
print(f"
|
|
3435
|
+
print(f"{ts_pfx} {_R}🚨 Blocked{_RS} -> {disp_cmd} {_dim('(' + sec_reason + ')')}")
|
|
3431
3436
|
ws.send(json.dumps({
|
|
3432
3437
|
"type": "tool_response",
|
|
3433
3438
|
"id": call_id,
|
|
@@ -3437,9 +3442,9 @@ def mcp_serve(
|
|
|
3437
3442
|
if any(k in cmd for k in ["touch", "mkdir", "mv", "cp", "sed", ">", ">>", "python", "npm", "pip"]):
|
|
3438
3443
|
_save_undo_checkpoint()
|
|
3439
3444
|
|
|
3440
|
-
# Instant frame-0 animated spinner with
|
|
3445
|
+
# Instant frame-0 animated spinner with live visibility
|
|
3441
3446
|
try:
|
|
3442
|
-
with _Spin(f"
|
|
3447
|
+
with _Spin(f"exec: {disp_cmd}", min_seconds=0.25, prefix=ts_pfx):
|
|
3443
3448
|
r = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=60)
|
|
3444
3449
|
elapsed_ms = (time.monotonic() - t0) * 1000
|
|
3445
3450
|
raw_out = r.stdout + r.stderr
|
|
@@ -3453,7 +3458,7 @@ def mcp_serve(
|
|
|
3453
3458
|
|
|
3454
3459
|
ec_color = _G if returncode == 0 else _R
|
|
3455
3460
|
ec_icon = f"{_G}✓{_RS}" if returncode == 0 else f"{_R}✗{_RS}"
|
|
3456
|
-
print(f"
|
|
3461
|
+
print(f"{ts_pfx} {ec_icon} {ec_color}exec:{_RS} {disp_cmd} {ec_color}[{returncode}]{_RS} {_dim(f'{elapsed_ms:.1f}ms')}")
|
|
3457
3462
|
|
|
3458
3463
|
ws.send(json.dumps({
|
|
3459
3464
|
"type": "tool_response",
|
|
@@ -3461,10 +3466,10 @@ def mcp_serve(
|
|
|
3461
3466
|
"result": {"content": [{"type": "text", "text": bounded_out or "(no output)"}], "isError": returncode != 0}
|
|
3462
3467
|
}))
|
|
3463
3468
|
elif t_name == "akash_undo":
|
|
3464
|
-
with _Spin("undo: reverting workspace to checkpoint", min_seconds=0.
|
|
3469
|
+
with _Spin("undo: reverting workspace to checkpoint", min_seconds=0.25, prefix=ts_pfx):
|
|
3465
3470
|
ok, msg_txt = _restore_undo_checkpoint()
|
|
3466
3471
|
icon = f"{_G}✓{_RS}" if ok else f"{_R}✗{_RS}"
|
|
3467
|
-
print(f"
|
|
3472
|
+
print(f"{ts_pfx} {icon} {(_G if ok else _R)}undo:{_RS} {_dim(msg_txt)}")
|
|
3468
3473
|
ws.send(json.dumps({
|
|
3469
3474
|
"type": "tool_response",
|
|
3470
3475
|
"id": call_id,
|
|
@@ -3474,10 +3479,10 @@ def mcp_serve(
|
|
|
3474
3479
|
elif t_name == "akash_checkpoint_create":
|
|
3475
3480
|
label = args.get("label", "agent_checkpoint")
|
|
3476
3481
|
from .terminal import build_snapshot
|
|
3477
|
-
with _Spin(f"checkpoint: {label} (packing workspace)", min_seconds=0.
|
|
3482
|
+
with _Spin(f"checkpoint: {label} (packing workspace)", min_seconds=0.25, prefix=ts_pfx):
|
|
3478
3483
|
_, manifest, _ = build_snapshot(label=label)
|
|
3479
3484
|
elapsed_ms = (time.monotonic() - t0) * 1000
|
|
3480
|
-
print(f"
|
|
3485
|
+
print(f"{ts_pfx} {_C}📸 checkpoint:{_RS} {_dim(label)} ({len(manifest.get('files', []))} files) {_dim(f'{elapsed_ms:.1f}ms')}")
|
|
3481
3486
|
ws.send(json.dumps({
|
|
3482
3487
|
"type": "tool_response",
|
|
3483
3488
|
"id": call_id,
|
|
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
|