akashcli 4.7.8__tar.gz → 4.8.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.
- {akashcli-4.7.8 → akashcli-4.8.0}/PKG-INFO +1 -1
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/cli.py +59 -11
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli.egg-info/PKG-INFO +1 -1
- {akashcli-4.7.8 → akashcli-4.8.0}/pyproject.toml +1 -1
- {akashcli-4.7.8 → akashcli-4.8.0}/README.md +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/__init__.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/_net.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/auth.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/client.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/config.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/crypto.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/env_manager.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/exceptions.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/exec.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/integrity.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/logger.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/models.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/p2p.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/packages.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/relay.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/restore.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/snapshot_crypto.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/storage.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/terminal.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/updater.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/uploader.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli/utils.py +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli.egg-info/SOURCES.txt +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli.egg-info/dependency_links.txt +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli.egg-info/entry_points.txt +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli.egg-info/requires.txt +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/akashcli.egg-info/top_level.txt +0 -0
- {akashcli-4.7.8 → akashcli-4.8.0}/setup.cfg +0 -0
|
@@ -19,7 +19,7 @@ from .config import ConfigManager, DEFAULT_STORAGE_URL
|
|
|
19
19
|
from .exceptions import AkashError
|
|
20
20
|
from .exec import _device_fingerprint
|
|
21
21
|
from .uploader import VaultUploader
|
|
22
|
-
from .updater import show_update_warning_if_available, check_for_updates, format_update_box, mark_update_printed
|
|
22
|
+
from .updater import show_update_warning_if_available, check_for_updates, format_update_box, mark_update_printed, is_newer_version
|
|
23
23
|
|
|
24
24
|
atexit.register(show_update_warning_if_available)
|
|
25
25
|
|
|
@@ -361,23 +361,38 @@ def update():
|
|
|
361
361
|
|
|
362
362
|
print(f" {_Y}⚡{_RS} New version available: {_DM}{__version__}{_RS} {_C}→{_RS} {_G}{latest}{_RS}")
|
|
363
363
|
with _Spin(f"updating akashcli to v{latest}…"):
|
|
364
|
-
cmd = [sys.executable, "-m", "pip", "install", "-U", "akashcli", "--break-system-packages"]
|
|
364
|
+
cmd = [sys.executable, "-m", "pip", "install", "-U", "--no-cache-dir", f"akashcli=={latest}", "--break-system-packages"]
|
|
365
365
|
res = subprocess.run(cmd, capture_output=True, text=True)
|
|
366
366
|
if res.returncode != 0:
|
|
367
|
-
cmd = [sys.executable, "-m", "pip", "install", "-U", "akashcli"]
|
|
367
|
+
cmd = [sys.executable, "-m", "pip", "install", "-U", "--no-cache-dir", f"akashcli=={latest}"]
|
|
368
368
|
res = subprocess.run(cmd, capture_output=True, text=True)
|
|
369
|
+
if res.returncode != 0:
|
|
370
|
+
# Fallback to general upgrade if pinned version is waiting on PyPI CDN propagation
|
|
371
|
+
cmd = [sys.executable, "-m", "pip", "install", "-U", "--no-cache-dir", "akashcli", "--break-system-packages"]
|
|
372
|
+
res = subprocess.run(cmd, capture_output=True, text=True)
|
|
373
|
+
|
|
374
|
+
# Verify what version is actually installed now in a fresh Python runtime
|
|
375
|
+
chk = subprocess.run(
|
|
376
|
+
[sys.executable, "-c", "import importlib.metadata; print(importlib.metadata.version('akashcli'))"],
|
|
377
|
+
capture_output=True,
|
|
378
|
+
text=True
|
|
379
|
+
)
|
|
380
|
+
curr = chk.stdout.strip() if chk.returncode == 0 else ""
|
|
369
381
|
|
|
370
|
-
if
|
|
371
|
-
_ok(f"Successfully updated akashcli to {_G}v{latest}{_RS}!")
|
|
382
|
+
if curr == latest or (curr and not is_newer_version(latest, curr)):
|
|
383
|
+
_ok(f"Successfully updated akashcli to {_G}v{curr or latest}{_RS}!")
|
|
372
384
|
try:
|
|
373
385
|
from .integrity import seal
|
|
374
386
|
seal()
|
|
375
387
|
_ok("Integrity manifest re-sealed.")
|
|
376
388
|
except Exception:
|
|
377
389
|
pass
|
|
390
|
+
elif res.returncode == 0:
|
|
391
|
+
_warn(f"pip reported success, but installed version is still v{curr or __version__}.")
|
|
392
|
+
_info(f"PyPI CDN may take 1-2 minutes to replicate. Try: {_cy(f'pip install -U --no-cache-dir akashcli=={latest}')}")
|
|
378
393
|
else:
|
|
379
394
|
_err(f"Update failed: {res.stderr or res.stdout}")
|
|
380
|
-
_info(f"Please run manually: {_cy('pip install -U akashcli')}")
|
|
395
|
+
_info(f"Please run manually: {_cy(f'pip install -U --no-cache-dir akashcli=={latest}')}")
|
|
381
396
|
mark_update_printed()
|
|
382
397
|
_p()
|
|
383
398
|
|
|
@@ -3205,18 +3220,39 @@ _LAST_UNDO_DIR = Path.home() / ".akash" / "undo_vault"
|
|
|
3205
3220
|
def _save_undo_checkpoint():
|
|
3206
3221
|
try:
|
|
3207
3222
|
import tarfile
|
|
3223
|
+
cwd = Path.cwd().resolve()
|
|
3224
|
+
home = Path.home().resolve()
|
|
3225
|
+
# Never archive the full home directory or system root!
|
|
3226
|
+
if cwd == home or cwd == Path("/") or str(cwd).startswith(("/proc", "/sys", "/dev")):
|
|
3227
|
+
return
|
|
3208
3228
|
_LAST_UNDO_DIR.mkdir(parents=True, exist_ok=True)
|
|
3209
3229
|
undo_tar = _LAST_UNDO_DIR / "workspace_last.tar.gz"
|
|
3230
|
+
excluded = {".git", "venv", "__pycache__", ".akash", "storage", ".termux", "node_modules", ".cache", "build", "dist"}
|
|
3210
3231
|
with tarfile.open(undo_tar, "w:gz") as tar:
|
|
3232
|
+
count = 0
|
|
3211
3233
|
for item in os.listdir("."):
|
|
3212
|
-
if item in (".
|
|
3234
|
+
if item in excluded or item.startswith(".") or os.path.islink(item):
|
|
3235
|
+
continue
|
|
3236
|
+
p = Path(item)
|
|
3237
|
+
if not p.exists() or p.is_symlink():
|
|
3213
3238
|
continue
|
|
3214
|
-
|
|
3215
|
-
|
|
3239
|
+
try:
|
|
3240
|
+
if p.is_file() and p.stat().st_size > 5 * 1024 * 1024:
|
|
3241
|
+
continue
|
|
3242
|
+
except Exception:
|
|
3243
|
+
continue
|
|
3244
|
+
tar.add(item, recursive=True, filter=lambda ti: None if (ti.name in excluded or ti.issym()) else ti)
|
|
3245
|
+
count += 1
|
|
3246
|
+
if count > 100:
|
|
3247
|
+
break
|
|
3216
3248
|
except Exception:
|
|
3217
3249
|
pass
|
|
3218
3250
|
|
|
3219
3251
|
def _restore_undo_checkpoint() -> tuple[bool, str]:
|
|
3252
|
+
cwd = Path.cwd().resolve()
|
|
3253
|
+
home = Path.home().resolve()
|
|
3254
|
+
if cwd == home or cwd == Path("/"):
|
|
3255
|
+
return False, "Undo snapshot is disabled when running in root or home directory for safety."
|
|
3220
3256
|
undo_tar = _LAST_UNDO_DIR / "workspace_last.tar.gz"
|
|
3221
3257
|
if not undo_tar.exists():
|
|
3222
3258
|
return False, "No undo checkpoint available for this session."
|
|
@@ -3451,7 +3487,10 @@ def mcp_serve(
|
|
|
3451
3487
|
ws.send(json.dumps({
|
|
3452
3488
|
"type": "tool_response",
|
|
3453
3489
|
"id": call_id,
|
|
3454
|
-
"result": {
|
|
3490
|
+
"result": {
|
|
3491
|
+
"content": [{"type": "text", "text": f"⛔ Security Policy Block: {sec_reason}\nCommand: {cmd}"}],
|
|
3492
|
+
"isError": True
|
|
3493
|
+
}
|
|
3455
3494
|
}))
|
|
3456
3495
|
else:
|
|
3457
3496
|
if any(k in cmd for k in ["touch", "mkdir", "mv", "cp", "sed", ">", ">>", "python", "npm", "pip"]):
|
|
@@ -3465,6 +3504,8 @@ def mcp_serve(
|
|
|
3465
3504
|
exec_cmd += " -y"
|
|
3466
3505
|
if re.search(r"\bdu\b", exec_cmd) and "-x" not in exec_cmd:
|
|
3467
3506
|
exec_cmd = re.sub(r"\bdu\b", "du -x", exec_cmd)
|
|
3507
|
+
if re.search(r"\btermux-location\b", exec_cmd) and "-r" not in exec_cmd:
|
|
3508
|
+
exec_cmd = re.sub(r"\btermux-location\b", "termux-location -r once", exec_cmd)
|
|
3468
3509
|
|
|
3469
3510
|
# Process-group-isolated runner: immune to pipe deadlocks & orphaned subshells
|
|
3470
3511
|
import os, signal
|
|
@@ -3509,10 +3550,17 @@ def mcp_serve(
|
|
|
3509
3550
|
ec_icon = f"{_G}✓{_RS}" if returncode == 0 else f"{_R}✗{_RS}"
|
|
3510
3551
|
print(f"{ts_pfx} {ec_icon} {ec_color}exec:{_RS} {disp_cmd} {ec_color}[{returncode}]{_RS} {_dim(f'{elapsed_ms:.1f}ms')}")
|
|
3511
3552
|
|
|
3553
|
+
if returncode != 0:
|
|
3554
|
+
res_content = bounded_out or f"Command exited with status code {returncode} (no output)"
|
|
3555
|
+
if not res_content.startswith("⛔"):
|
|
3556
|
+
res_content = f"⛔ Command execution failed (exit code {returncode}):\n{res_content}"
|
|
3557
|
+
else:
|
|
3558
|
+
res_content = bounded_out or "(command completed successfully with no output)"
|
|
3559
|
+
|
|
3512
3560
|
ws.send(json.dumps({
|
|
3513
3561
|
"type": "tool_response",
|
|
3514
3562
|
"id": call_id,
|
|
3515
|
-
"result": {"content": [{"type": "text", "text":
|
|
3563
|
+
"result": {"content": [{"type": "text", "text": res_content}], "isError": returncode != 0}
|
|
3516
3564
|
}))
|
|
3517
3565
|
elif t_name == "akash_undo":
|
|
3518
3566
|
with _Spin("undo: reverting workspace to checkpoint", min_seconds=0.25, prefix=ts_pfx):
|
|
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
|