akashcli 4.8.7__tar.gz → 4.8.8__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.
Files changed (33) hide show
  1. {akashcli-4.8.7 → akashcli-4.8.8}/PKG-INFO +1 -1
  2. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/__init__.py +1 -1
  3. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/cli.py +26 -26
  4. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli.egg-info/PKG-INFO +1 -1
  5. {akashcli-4.8.7 → akashcli-4.8.8}/pyproject.toml +1 -1
  6. {akashcli-4.8.7 → akashcli-4.8.8}/README.md +0 -0
  7. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/_net.py +0 -0
  8. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/auth.py +0 -0
  9. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/client.py +0 -0
  10. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/config.py +0 -0
  11. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/crypto.py +0 -0
  12. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/env_manager.py +0 -0
  13. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/exceptions.py +0 -0
  14. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/exec.py +0 -0
  15. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/integrity.py +0 -0
  16. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/logger.py +0 -0
  17. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/models.py +0 -0
  18. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/p2p.py +0 -0
  19. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/packages.py +0 -0
  20. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/relay.py +0 -0
  21. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/restore.py +0 -0
  22. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/snapshot_crypto.py +0 -0
  23. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/storage.py +0 -0
  24. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/terminal.py +0 -0
  25. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/updater.py +0 -0
  26. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/uploader.py +0 -0
  27. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli/utils.py +0 -0
  28. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli.egg-info/SOURCES.txt +0 -0
  29. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli.egg-info/dependency_links.txt +0 -0
  30. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli.egg-info/entry_points.txt +0 -0
  31. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli.egg-info/requires.txt +0 -0
  32. {akashcli-4.8.7 → akashcli-4.8.8}/akashcli.egg-info/top_level.txt +0 -0
  33. {akashcli-4.8.7 → akashcli-4.8.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akashcli
3
- Version: 4.8.7
3
+ Version: 4.8.8
4
4
  Summary: Akash CLI — secure remote shell relay, file vault, and device management
5
5
  License-Expression: MIT
6
6
  Keywords: akash,cli,relay,remote-shell,vault
@@ -2,7 +2,7 @@ try:
2
2
  from importlib.metadata import version
3
3
  __version__ = version("akashcli")
4
4
  except Exception:
5
- __version__ = "4.8.7"
5
+ __version__ = "4.8.8"
6
6
 
7
7
  AKASH_VERSION = __version__
8
8
 
@@ -136,7 +136,7 @@ def _resolve_client(url_override: str = None, require_key: bool = False, silent:
136
136
 
137
137
 
138
138
  _GUEST_WARNING = (
139
- f" {_Y}⚠{_RS} {_Y}Running as guest{_RS} - not logged in.\n"
139
+ f" {_Y}!{_RS} {_Y}Running as guest{_RS} - not logged in.\n"
140
140
  f" {_DM}Features are limited and your data won't be saved to the cloud.\n"
141
141
  f" Run {_RS}{_C}akash login{_RS}{_DM} to unlock full access.{_RS}"
142
142
  )
@@ -243,7 +243,7 @@ def _print_help():
243
243
  f" {C}devices{RS} {DM}[--revoke NAME]{RS} list or manage enrolled devices",
244
244
  "",
245
245
  f" {DM}AI AGENTS & MCP{RS}",
246
- f" {C}mcp{RS} {DM}<serve|share|create|list…>{RS} AI agent & MCP tool bridge (Codex, Claude, Cursor)",
246
+ f" {C}mcp{RS} {DM}<serve|share|create|list…>{RS} AI agent & MCP tool bridge (Cursor, Claude, ChatGPT)",
247
247
  "",
248
248
  f" {DM}FILES & CLOUD VAULT{RS}",
249
249
  f" {C}cloud{RS} {DM}<upload|files|stream|delete…>{RS} cloud file vault & media streaming engine",
@@ -359,7 +359,7 @@ def update():
359
359
  _p()
360
360
  return
361
361
 
362
- print(f" {_Y}⚡{_RS} New version available: {_DM}{__version__}{_RS} {_C}→{_RS} {_G}{latest}{_RS}")
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
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)
@@ -464,10 +464,10 @@ def cmd_url(
464
464
  _info("To reset URL : akash url --reset")
465
465
  _p()
466
466
  def _storage_discontinued_notice():
467
- print(f"\n{_R}⚠️ [SERVICE DISCONTINUED] Cloud storage & upload services are disabled.{_RS}")
467
+ print(f"\n{_R}!️ [SERVICE DISCONTINUED] Cloud storage & upload services are disabled.{_RS}")
468
468
  print(f" {_DM}Public cloud uploading has been discontinued due to lack of funds and hosting costs.{_RS}")
469
469
  print(f" {_DM}We are actively seeking sponsors to help restore community storage infrastructure.{_RS}\n")
470
- print(f" {_C}💖 Sponsoring the project:{_RS}")
470
+ print(f" {_C}Sponsoring the project:{_RS}")
471
471
  print(f" Run {_YE}akash sponsor{_RS} or visit {_CY}https://github.com/juniorsir/akashcli#sponsorship{_RS}\n")
472
472
  raise typer.Exit(1)
473
473
 
@@ -476,7 +476,7 @@ def _storage_discontinued_notice():
476
476
  def cmd_sponsor():
477
477
  """Information on sponsoring Akash CLI to restore storage services."""
478
478
  print(f"\n{_C}╔═══════════════════════════════════════════════════════════════╗{_RS}")
479
- print(f"{_C}║ 💖 SPONSOR AKASH CLI INFRASTRUCTURE ║{_RS}")
479
+ print(f"{_C}║ SPONSOR AKASH CLI INFRASTRUCTURE ║{_RS}")
480
480
  print(f"{_C}╚═══════════════════════════════════════════════════════════════╝{_RS}\n")
481
481
  print(f" {_B}Status Update:{_RS}")
482
482
  print(f" Public cloud storage and file uploading services have been")
@@ -692,7 +692,7 @@ def _interactive_explorer(vfs, root_name="/"):
692
692
  sys.stdout.write(f" {_GR}────────────────────────────────────────────────────────────{_RS}\r\n")
693
693
 
694
694
  full_path = "".join([n[1] + ("/" if n[1] != "/" and not n[1].endswith("/") else "") for n in path_stack])
695
- sys.stdout.write(f" 📂 {_C}{full_path}{_RS}\r\n")
695
+ sys.stdout.write(f" [DIR] {_C}{full_path}{_RS}\r\n")
696
696
  sys.stdout.write(f" {_GR}────────────────────────────────────────────────────────────{_RS}\r\n")
697
697
 
698
698
  if not keys:
@@ -704,7 +704,7 @@ def _interactive_explorer(vfs, root_name="/"):
704
704
  child = children[k]
705
705
  is_sel = (actual_idx == selected_idx)
706
706
  cursor = f"{_G}> {_RS}" if is_sel else " "
707
- icon = "📁" if child["type"] == "dir" else "📄"
707
+ icon = "[DIR]" if child["type"] == "dir" else "[FILE]"
708
708
 
709
709
  display_name = k[:35] + ("…" if len(k) > 35 else "")
710
710
  if child["type"] == "dir":
@@ -2704,11 +2704,11 @@ def env_pull(
2704
2704
 
2705
2705
  mcp_app = typer.Typer(help="Model Context Protocol (MCP) server & AI agent tool bridge.")
2706
2706
  agent_app = mcp_app
2707
- app.add_typer(mcp_app, name="mcp", help="MCP server · AI agent tools · Claude/Cursor/Codex bridge")
2707
+ app.add_typer(mcp_app, name="mcp", help="MCP server · AI agent tools · Claude/Cursor/ChatGPT bridge")
2708
2708
  app.add_typer(mcp_app, name="agent", hidden=True, help="Alias for akash mcp")
2709
2709
 
2710
2710
  def _render_inspection_card(r: dict) -> None:
2711
- print(f"\n {_C}╭─ ⚡ INCOMING AGENT DEVICE REGISTRATION ────────────────────────────{_RS}")
2711
+ print(f"\n {_C}╭─ ◈ INCOMING AGENT DEVICE REGISTRATION ────────────────────────────{_RS}")
2712
2712
  print(f" {_GR}│{_RS} {_DM}Request ID :{_RS} {_ye(r['request_id'])}")
2713
2713
  print(f" {_GR}│{_RS} {_DM}Client Name :{_RS} {_W}{r['client_name']}{_RS}")
2714
2714
  print(f" {_GR}│{_RS} {_DM}Client ID :{_RS} {_dim(r['client_id'])}")
@@ -2868,7 +2868,7 @@ def agent_list(raw: bool = typer.Option(False, "--json", help="Raw JSON output")
2868
2868
 
2869
2869
  print(f" {_GR}{'─'*76}{_RS}")
2870
2870
  if expired_count > 0:
2871
- print(f" {_Y}⚡{_RS} {_W}{expired_count} profile(s) expired.{_RS} {_DM}Run {_cy('akash mcp renew <id>')} to extend or {_cy('akash mcp rm --expired')} to clean up.{_RS}\n")
2871
+ print(f" {_Y}◈{_RS} {_W}{expired_count} profile(s) expired.{_RS} {_DM}Run {_cy('akash mcp renew <id>')} to extend or {_cy('akash mcp rm --expired')} to clean up.{_RS}\n")
2872
2872
  else:
2873
2873
  _p()
2874
2874
  print(f" {_W}Quick Launch:{_RS}")
@@ -3036,7 +3036,7 @@ def agent_info(
3036
3036
  mcp_url = f"{base}/mcp?{params}"
3037
3037
 
3038
3038
  _p()
3039
- print(f" {_C}╭─ 🤖 AGENT PERMISSION DETAILS: {_W}{name}{_RS} {_dim('(' + pid + ')')}")
3039
+ print(f" {_C}╭─ AGENT PERMISSION DETAILS: {_W}{name}{_RS} {_dim('(' + pid + ')')}")
3040
3040
  print(f" {_GR}│{_RS} {_DM}Profile ID :{_RS} {_ye(pid)}")
3041
3041
  print(f" {_GR}│{_RS} {_DM}Client ID :{_RS} {_dim(cid)}")
3042
3042
  st_col = _G if "active" in status.lower() else (_Y if "pending" in status.lower() else _R)
@@ -3614,7 +3614,7 @@ def _handle_tool_read_file(args: dict, scopes: str) -> tuple[str, bool]:
3614
3614
  try:
3615
3615
  target_path.relative_to(cwd)
3616
3616
  except ValueError:
3617
- return f"⛔ Permission denied by scope 'fs:cwd_only': Path '{path_str}' is outside working directory ({cwd}).", True
3617
+ return f"[BLOCKED] Permission denied by scope 'fs:cwd_only': Path '{path_str}' is outside working directory ({cwd}).", True
3618
3618
 
3619
3619
  if not target_path.exists():
3620
3620
  return f"Error: File '{path_str}' not found.", True
@@ -3667,13 +3667,13 @@ def _handle_tool_write_file(args: dict, scopes: str) -> tuple[str, bool]:
3667
3667
  scopes_list = [s.strip().lower() for s in scopes.split(",") if s.strip()]
3668
3668
  if "*" not in scopes_list and "@full" not in scopes_list:
3669
3669
  if "exec:read_only" in scopes_list or "@viewer" in scopes_list:
3670
- return "⛔ Permission denied: Agent is in read-only mode ('exec:read_only'). File writing is blocked.", True
3670
+ return "[BLOCKED] Permission denied: Agent is in read-only mode ('exec:read_only'). File writing is blocked.", True
3671
3671
  if "fs:cwd_only" in scopes_list:
3672
3672
  cwd = Path.cwd().resolve()
3673
3673
  try:
3674
3674
  target_path.relative_to(cwd)
3675
3675
  except ValueError:
3676
- return f"⛔ Permission denied by scope 'fs:cwd_only': Path '{path_str}' is outside working directory ({cwd}).", True
3676
+ return f"[BLOCKED] Permission denied by scope 'fs:cwd_only': Path '{path_str}' is outside working directory ({cwd}).", True
3677
3677
 
3678
3678
  if target_path.exists() and not overwrite:
3679
3679
  return f"Error: File '{path_str}' already exists and overwrite is set to False.", True
@@ -3704,7 +3704,7 @@ def _handle_tool_list_dir(args: dict, scopes: str) -> tuple[str, bool]:
3704
3704
  try:
3705
3705
  target_path.relative_to(cwd)
3706
3706
  except ValueError:
3707
- return f"⛔ Permission denied by scope 'fs:cwd_only': Path '{path_str}' is outside working directory ({cwd}).", True
3707
+ return f"[BLOCKED] Permission denied by scope 'fs:cwd_only': Path '{path_str}' is outside working directory ({cwd}).", True
3708
3708
 
3709
3709
  if not target_path.exists():
3710
3710
  return f"Error: Path '{path_str}' not found.", True
@@ -3731,18 +3731,18 @@ def _handle_tool_list_dir(args: dict, scopes: str) -> tuple[str, bool]:
3731
3731
  ptr = "└── " if is_last else "├── "
3732
3732
  sub_pfx = " " if is_last else "│ "
3733
3733
  if entry.is_dir():
3734
- output_lines.append(f"{prefix}{ptr}📁 {entry.name}/")
3734
+ output_lines.append(f"{prefix}{ptr}[DIR] {entry.name}/")
3735
3735
  if cur_depth < depth and not entry.is_symlink():
3736
3736
  _walk(entry, cur_depth + 1, prefix + sub_pfx)
3737
3737
  elif entry.is_symlink():
3738
- output_lines.append(f"{prefix}{ptr}🔗 {entry.name} -> {os.readlink(entry)}")
3738
+ output_lines.append(f"{prefix}{ptr}[LINK] {entry.name} -> {os.readlink(entry)}")
3739
3739
  else:
3740
3740
  try:
3741
3741
  sz = entry.stat().st_size
3742
3742
  sz_str = f"{sz / 1024:.1f}KB" if sz >= 1024 else f"{sz}B"
3743
3743
  except Exception:
3744
3744
  sz_str = "?"
3745
- output_lines.append(f"{prefix}{ptr}📄 {entry.name} ({sz_str})")
3745
+ output_lines.append(f"{prefix}{ptr}[FILE] {entry.name} ({sz_str})")
3746
3746
  if len(filtered) > 100:
3747
3747
  output_lines.append(f"{prefix}... [{len(filtered) - 100} more items omitted]")
3748
3748
 
@@ -3852,7 +3852,7 @@ def mcp_serve(
3852
3852
  if ack.get("type") == "pending_approval":
3853
3853
  req_id = ack.get("request_id", "?")
3854
3854
  sys.stdout.write(chr(13) + chr(27) + "[2K"); sys.stdout.flush()
3855
- print("\n " + _Y + "⚡" + _RS + " " + _W + "New device registration pending:" + _RS)
3855
+ print("\n " + _Y + "◈" + _RS + " " + _W + "New device registration pending:" + _RS)
3856
3856
  print(" " + _DM + "Request ID : " + _RS + _ye(req_id))
3857
3857
  print(" " + _DM + "Device FP : " + _RS + _dim(dev_fp))
3858
3858
  print()
@@ -3908,7 +3908,7 @@ def mcp_serve(
3908
3908
  "type": "tool_response",
3909
3909
  "id": call_id,
3910
3910
  "result": {
3911
- "content": [{"type": "text", "text": f"⛔ Security Policy Block: {sec_reason}\nCommand: {cmd}"}],
3911
+ "content": [{"type": "text", "text": f"[BLOCKED] Security Policy Block: {sec_reason}\nCommand: {cmd}"}],
3912
3912
  "isError": True
3913
3913
  }
3914
3914
  }))
@@ -3957,11 +3957,11 @@ def mcp_serve(
3957
3957
  except Exception:
3958
3958
  raw_out = ""
3959
3959
  elapsed_ms = 25000.0
3960
- raw_out = raw_out or "⛔ Command timed out after 25 seconds."
3960
+ raw_out = raw_out or "[BLOCKED] Command timed out after 25 seconds."
3961
3961
  returncode = 124
3962
3962
  except Exception as cmd_err:
3963
3963
  elapsed_ms = (time.monotonic() - t0) * 1000
3964
- raw_out = f"⛔ Command execution error: {cmd_err}"
3964
+ raw_out = f"[BLOCKED] Command execution error: {cmd_err}"
3965
3965
  returncode = 1
3966
3966
 
3967
3967
  bounded_out = _smart_truncate_output(raw_out)
@@ -3973,8 +3973,8 @@ def mcp_serve(
3973
3973
 
3974
3974
  if returncode != 0:
3975
3975
  res_content = bounded_out or f"Command exited with status code {returncode} (no output)"
3976
- if not res_content.startswith("⛔"):
3977
- res_content = f"⛔ Command execution failed (exit code {returncode}):\n{res_content}"
3976
+ if not res_content.startswith("[BLOCKED]"):
3977
+ res_content = f"[BLOCKED] Command execution failed (exit code {returncode}):\n{res_content}"
3978
3978
  else:
3979
3979
  res_content = bounded_out or "(command completed successfully with no output)"
3980
3980
 
@@ -4081,7 +4081,7 @@ def mcp_serve(
4081
4081
  reconnect_attempts += 1
4082
4082
  backoff = min(1.2 * (1.5 ** min(reconnect_attempts, 6)), 30.0) + random.uniform(0.1, 0.4)
4083
4083
  now_t = datetime.datetime.now().strftime("%H:%M:%S")
4084
- print(f" {_GR}{now_t}{_RS} {_Y}⚠{_RS} {_dim(f'Worker disconnected ({e}). Reconnecting in {backoff:.1f}s (attempt {reconnect_attempts})…')}")
4084
+ print(f" {_GR}{now_t}{_RS} {_Y}!{_RS} {_dim(f'Worker disconnected ({e}). Reconnecting in {backoff:.1f}s (attempt {reconnect_attempts})…')}")
4085
4085
  time.sleep(backoff)
4086
4086
 
4087
4087
  @agent_app.command("share")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akashcli
3
- Version: 4.8.7
3
+ Version: 4.8.8
4
4
  Summary: Akash CLI — secure remote shell relay, file vault, and device management
5
5
  License-Expression: MIT
6
6
  Keywords: akash,cli,relay,remote-shell,vault
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "akashcli"
3
- version = "4.8.7"
3
+ version = "4.8.8"
4
4
  description = "Akash CLI — secure remote shell relay, file vault, and device management"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
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