akashcli 4.8.1__tar.gz → 4.8.3__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.1 → akashcli-4.8.3}/PKG-INFO +1 -1
  2. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/cli.py +88 -22
  3. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli.egg-info/PKG-INFO +1 -1
  4. {akashcli-4.8.1 → akashcli-4.8.3}/pyproject.toml +1 -1
  5. {akashcli-4.8.1 → akashcli-4.8.3}/README.md +0 -0
  6. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/__init__.py +0 -0
  7. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/_net.py +0 -0
  8. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/auth.py +0 -0
  9. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/client.py +0 -0
  10. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/config.py +0 -0
  11. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/crypto.py +0 -0
  12. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/env_manager.py +0 -0
  13. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/exceptions.py +0 -0
  14. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/exec.py +0 -0
  15. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/integrity.py +0 -0
  16. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/logger.py +0 -0
  17. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/models.py +0 -0
  18. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/p2p.py +0 -0
  19. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/packages.py +0 -0
  20. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/relay.py +0 -0
  21. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/restore.py +0 -0
  22. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/snapshot_crypto.py +0 -0
  23. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/storage.py +0 -0
  24. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/terminal.py +0 -0
  25. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/updater.py +0 -0
  26. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/uploader.py +0 -0
  27. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli/utils.py +0 -0
  28. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli.egg-info/SOURCES.txt +0 -0
  29. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli.egg-info/dependency_links.txt +0 -0
  30. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli.egg-info/entry_points.txt +0 -0
  31. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli.egg-info/requires.txt +0 -0
  32. {akashcli-4.8.1 → akashcli-4.8.3}/akashcli.egg-info/top_level.txt +0 -0
  33. {akashcli-4.8.1 → akashcli-4.8.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akashcli
3
- Version: 4.8.1
3
+ Version: 4.8.3
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
@@ -51,7 +51,7 @@ class _Spin:
51
51
  _FRAMES = ("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏")
52
52
 
53
53
  def __init__(self, label: str, min_seconds: float = 0.35, disabled: bool = False, prefix: str = ""):
54
- self._label = label
54
+ self._label = re.sub(r'[\r\n\t]+', ' ', str(label)).strip()
55
55
  self._prefix = prefix
56
56
  self._disabled = disabled or (not sys.stdout.isatty())
57
57
  self._min_seconds = min_seconds
@@ -90,7 +90,7 @@ class _Spin:
90
90
  return self
91
91
 
92
92
  def update(self, label: str):
93
- self._label = label
93
+ self._label = re.sub(r'[\r\n\t]+', ' ', str(label)).strip()
94
94
 
95
95
  def __exit__(self, *_):
96
96
  if self._disabled:
@@ -2774,43 +2774,103 @@ def _render_inspection_card(r: dict) -> None:
2774
2774
 
2775
2775
 
2776
2776
  @agent_app.command("list")
2777
+ @agent_app.command("ls", hidden=True)
2778
+ @agent_app.command("ids", hidden=True)
2779
+ @agent_app.command("profiles", hidden=True)
2777
2780
  def agent_list(raw: bool = typer.Option(False, "--json", help="Raw JSON output")):
2778
- """List all locally saved Agent Profile IDs and their credentials."""
2781
+ """List all locally saved Agent & MCP Profile IDs, credentials, and launch commands."""
2779
2782
  import json
2780
2783
  from pathlib import Path
2784
+
2785
+ is_raw = bool(raw is True)
2781
2786
  agents_file = Path.home() / ".akash" / "agents.json"
2782
2787
  if not agents_file.exists():
2783
- _info("no saved agent profiles found - create one with: akash agent create")
2788
+ _p()
2789
+ _info("No saved agent profiles found. Create one with: " + _cy("akash mcp create -n Dev -r @coder"))
2790
+ _p()
2784
2791
  return
2785
2792
 
2786
2793
  try:
2787
- agents = json.loads(agents_file.read_text())
2794
+ agents = json.loads(agents_file.read_text(encoding="utf-8"))
2788
2795
  except Exception:
2789
2796
  agents = {}
2790
2797
 
2791
2798
  if not agents:
2792
- _info("no saved agent profiles found - create one with: akash agent create")
2799
+ _p()
2800
+ _info("No saved agent profiles found. Create one with: " + _cy("akash mcp create -n Dev -r @coder"))
2801
+ _p()
2793
2802
  return
2794
2803
 
2795
- if raw:
2804
+ if is_raw:
2796
2805
  print(json.dumps(agents, indent=2))
2797
2806
  return
2798
2807
 
2808
+ default_pid = next(reversed(list(agents.keys())))
2809
+
2799
2810
  _p()
2800
- print(f" {_C}◈{_RS} {_W}Available Agent Profile IDs{_RS} {_dim(f'({len(agents)})')}")
2801
- _p()
2802
- print(f" {_DM}{'ID':<6} {'NAME':<20} {'CLIENT ID':<26} MCP LAUNCH COMMAND{_RS}")
2803
- print(f" {_GR}{'─'*75}{_RS}")
2811
+ print(f" {_C}◈{_RS} {_W}Akash MCP Profiles & Agent IDs{_RS} {_dim(f'({len(agents)} configured)')}")
2812
+ print(f" {_GR}{'─'*76}{_RS}")
2813
+
2814
+ hdr_status = f"{'STATUS':<11}"
2815
+ hdr_id = f"{'ID':<8}"
2816
+ hdr_name = f"{'NAME':<16}"
2817
+ hdr_cid = f"{'CLIENT ID SUFFIX':<18}"
2818
+ hdr_scopes = "ROLE / SCOPES"
2819
+ print(f" {_DM}{hdr_status}{hdr_id}{hdr_name}{hdr_cid}{hdr_scopes}{_RS}")
2820
+ print(f" {_GR}{'─'*76}{_RS}")
2821
+
2822
+ last_suffix = ""
2804
2823
  for pid, data in agents.items():
2805
- name = data.get("name", "Agent")[:19]
2806
- cid = data.get("client_id", "?")
2807
- cid_short = cid[:22] + "…" if len(cid) > 22 else cid
2808
- cmd_hint = f"akash mcp serve --id {pid}"
2809
- print(f" {_ye(pid):<15} {_W}{name:<20}{_RS} {_dim(cid_short):<35} {_C}{cmd_hint}{_RS}")
2824
+ is_default = (pid == default_pid)
2825
+ status_txt = "● active" if is_default else "○ idle"
2826
+ status_color = _G if is_default else _DM
2827
+
2828
+ name = data.get("name", "Agent")
2829
+ if len(name) > 14:
2830
+ name = name[:13] + "…"
2831
+
2832
+ cid = data.get("client_id", "")
2833
+ suffix = f"...{cid[-4:]}" if len(cid) >= 4 else cid
2834
+ if is_default:
2835
+ last_suffix = cid[-4:] if len(cid) >= 4 else cid
2836
+
2837
+ raw_scopes = data.get("scopes", "*")
2838
+ if raw_scopes == "*":
2839
+ scope_desc = "@full (All access)"
2840
+ elif "fs:no_delete" in raw_scopes and "workspace:write" in raw_scopes:
2841
+ scope_desc = "@coder (Safe Dev)"
2842
+ elif "workspace:write" in raw_scopes:
2843
+ scope_desc = "@editor (Code Edit)"
2844
+ elif "exec:read_only" in raw_scopes:
2845
+ scope_desc = "@viewer (Read-Only)"
2846
+ else:
2847
+ scope_desc = raw_scopes.split(",")[0] if raw_scopes else "custom"
2848
+
2849
+ # Safe alignment with ANSI colors
2850
+ c_status = f"{status_color}{status_txt}{_RS}" + " " * max(0, 11 - len(status_txt))
2851
+ c_id = f"{_ye(pid)}{_RS}" + " " * max(0, 8 - len(pid))
2852
+ c_name = f"{_W}{name}{_RS}" + " " * max(0, 16 - len(name))
2853
+ c_cid = f"{_cy(suffix)}{_RS}" + " " * max(0, 18 - len(suffix))
2854
+ c_scopes = f"{_dim(scope_desc)}"
2855
+
2856
+ print(f" {c_status}{c_id}{c_name}{c_cid}{c_scopes}")
2857
+
2858
+ print(f" {_GR}{'─'*76}{_RS}")
2810
2859
  _p()
2811
- _info("To launch: akash mcp serve --id <ID>")
2860
+ print(f" {_W}Quick Launch:{_RS}")
2861
+ print(f" • Use default profile : {_C}akash mcp serve{_RS}")
2862
+ suffix_hint = f" {_dim('(or: --id ' + last_suffix + ')')}" if last_suffix else ""
2863
+ print(f" • Use specific ID : {_C}akash mcp serve --id {default_pid}{_RS}{suffix_hint}")
2864
+ print(f" • Inspect permissions : {_C}akash mcp info {default_pid}{_RS}")
2865
+ print(f" • Create new profile : {_C}akash mcp create -n Dev -r @coder{_RS}")
2812
2866
  _p()
2813
2867
 
2868
+ @mcp_app.callback(invoke_without_command=True)
2869
+ def mcp_callback(ctx: typer.Context):
2870
+ """Model Context Protocol (MCP) server & AI agent tool bridge."""
2871
+ if ctx.invoked_subcommand is None:
2872
+ agent_list()
2873
+
2814
2874
 
2815
2875
 
2816
2876
  def _resolve_agent_id(target_id: str) -> tuple[str, str, str]:
@@ -3603,7 +3663,9 @@ def mcp_serve(
3603
3663
  print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
3604
3664
  print(" " + _DM + "Workspace : " + _RS + _cy(str(Path.cwd())))
3605
3665
  print(" " + _DM + "Gateway : " + _RS + _dim(base))
3606
- print(" " + _DM + "Profile : " + _RS + _ye(pname) + " " + _dim("(" + (profile_id or "custom") + ")"))
3666
+ cid_suffix = f"...{cid[-4:]}" if cid and len(cid) >= 4 else ""
3667
+ suffix_tag = f" · client: {cid_suffix}" if cid_suffix else ""
3668
+ print(" " + _DM + "Profile : " + _RS + _ye(pname) + " " + _dim("(" + (profile_id or "custom") + suffix_tag + ")"))
3607
3669
  print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
3608
3670
  print(" " + _DM + "Active Tools:" + _RS)
3609
3671
  print(" • akash_exec_command " + _dim("(Safe terminal runner)"))
@@ -3679,7 +3741,8 @@ def mcp_serve(
3679
3741
 
3680
3742
  if t_name == "akash_exec_command":
3681
3743
  cmd = args.get("command", "")
3682
- disp_cmd = cmd if len(cmd) <= 32 else cmd[:29] + "…"
3744
+ one_line_cmd = re.sub(r'[\r\n\t]+', ' ', cmd).strip()
3745
+ disp_cmd = one_line_cmd if len(one_line_cmd) <= 36 else one_line_cmd[:33] + "…"
3683
3746
 
3684
3747
  is_safe, sec_reason = _sanitize_agent_command(cmd, scopes=cached.get("scopes", "*"))
3685
3748
  if not is_safe:
@@ -3788,7 +3851,8 @@ def mcp_serve(
3788
3851
 
3789
3852
  elif t_name == "akash_read_file":
3790
3853
  f_path = args.get("path", "")
3791
- disp_f = f_path if len(f_path) <= 32 else f_path[:29] + "…"
3854
+ c_f = re.sub(r'[\r\n\t]+', ' ', f_path).strip()
3855
+ disp_f = c_f if len(c_f) <= 36 else c_f[:33] + "…"
3792
3856
  with _Spin(f"read: {disp_f}", min_seconds=0.15, prefix=ts_pfx):
3793
3857
  res_text, is_err = _handle_tool_read_file(args, cached.get("scopes", "*"))
3794
3858
  elapsed_ms = (time.monotonic() - t0) * 1000
@@ -3802,7 +3866,8 @@ def mcp_serve(
3802
3866
 
3803
3867
  elif t_name == "akash_write_file":
3804
3868
  f_path = args.get("path", "")
3805
- disp_f = f_path if len(f_path) <= 32 else f_path[:29] + "…"
3869
+ c_f = re.sub(r'[\r\n\t]+', ' ', f_path).strip()
3870
+ disp_f = c_f if len(c_f) <= 36 else c_f[:33] + "…"
3806
3871
  _save_undo_checkpoint()
3807
3872
  with _Spin(f"write: {disp_f}", min_seconds=0.15, prefix=ts_pfx):
3808
3873
  res_text, is_err = _handle_tool_write_file(args, cached.get("scopes", "*"))
@@ -3817,7 +3882,8 @@ def mcp_serve(
3817
3882
 
3818
3883
  elif t_name == "akash_list_dir":
3819
3884
  d_path = args.get("path", ".")
3820
- disp_d = d_path if len(d_path) <= 32 else d_path[:29] + "…"
3885
+ c_d = re.sub(r'[\r\n\t]+', ' ', d_path).strip()
3886
+ disp_d = c_d if len(c_d) <= 36 else c_d[:33] + "…"
3821
3887
  with _Spin(f"list: {disp_d}", min_seconds=0.15, prefix=ts_pfx):
3822
3888
  res_text, is_err = _handle_tool_list_dir(args, cached.get("scopes", "*"))
3823
3889
  elapsed_ms = (time.monotonic() - t0) * 1000
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akashcli
3
- Version: 4.8.1
3
+ Version: 4.8.3
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.1"
3
+ version = "4.8.3"
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
File without changes