akashcli 4.4.0__tar.gz → 4.4.1__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 (31) hide show
  1. {akashcli-4.4.0 → akashcli-4.4.1}/PKG-INFO +1 -1
  2. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/cli.py +95 -45
  3. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli.egg-info/PKG-INFO +1 -1
  4. {akashcli-4.4.0 → akashcli-4.4.1}/pyproject.toml +1 -1
  5. {akashcli-4.4.0 → akashcli-4.4.1}/README.md +0 -0
  6. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/__init__.py +0 -0
  7. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/auth.py +0 -0
  8. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/client.py +0 -0
  9. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/config.py +0 -0
  10. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/crypto.py +0 -0
  11. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/env_manager.py +0 -0
  12. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/exceptions.py +0 -0
  13. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/exec.py +0 -0
  14. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/integrity.py +0 -0
  15. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/logger.py +0 -0
  16. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/models.py +0 -0
  17. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/p2p.py +0 -0
  18. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/packages.py +0 -0
  19. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/relay.py +0 -0
  20. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/restore.py +0 -0
  21. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/snapshot_crypto.py +0 -0
  22. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/storage.py +0 -0
  23. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/terminal.py +0 -0
  24. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/uploader.py +0 -0
  25. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli/utils.py +0 -0
  26. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli.egg-info/SOURCES.txt +0 -0
  27. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli.egg-info/dependency_links.txt +0 -0
  28. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli.egg-info/entry_points.txt +0 -0
  29. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli.egg-info/requires.txt +0 -0
  30. {akashcli-4.4.0 → akashcli-4.4.1}/akashcli.egg-info/top_level.txt +0 -0
  31. {akashcli-4.4.0 → akashcli-4.4.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akashcli
3
- Version: 4.4.0
3
+ Version: 4.4.1
4
4
  Summary: Akash CLI — secure remote shell relay, file vault, and device management
5
5
  License: MIT
6
6
  Keywords: akash,cli,relay,remote-shell,vault
@@ -966,27 +966,37 @@ def run(
966
966
  reauth: bool = typer.Option(False, "--reauth", help="Force re-authentication"),
967
967
  save: bool = typer.Option(False, "--save", help="Upload command output to cloud"),
968
968
  save_name: Optional[str] = typer.Option(None, "--save-name", help="Filename for saved output"),
969
- device: Optional[str] = typer.Option(None, "--device","-d",help="Target device label (default: auto)"),
969
+ device: Optional[str] = typer.Option(None, "--device", "-d",
970
+ help="Run on a device (set up with: akash serve --label NAME)"),
970
971
  ):
971
- """Run a command — on the server or on a specific enrolled device.
972
+ """Run a command — locally, on the server, or on an enrolled device.
972
973
 
973
- Token cached 24 h — instant reconnect every time.
974
+ No login needed:
975
+ akash run "df -h" runs locally
976
+ akash run "ls" --save runs locally, uploads output
974
977
 
975
- Examples:
976
- akash run "ls -la ~" # run on server
977
- akash run "df -h" --device termux # run on your phone
978
- akash run "df -h" --device laptop # run on your laptop
979
- akash run "pip list" --save # save output to cloud
978
+ With login:
979
+ akash run "df -h" runs on server
980
+ akash run "df -h" --device termux runs on your phone
981
+ akash run "pip list" --save runs on server, saves output
982
+
983
+ To make a device reachable:
984
+ 1. On that device: akash login --label termux && akash serve
985
+ 2. From anywhere: akash run "cmd" --device termux
980
986
  """
981
987
  from .exec import acquire_exec_token, run_command, _clear_cached_token
982
988
 
983
989
  try:
984
990
  api_key, base = _resolve_client(url)
985
991
 
986
- # ── No key + device flag → relay needs auth ───────────────────────
992
+ # ── --device but no key ───────────────────────────────────────────
987
993
  if device is not None and not api_key:
988
- print(_GUEST_WARNING)
989
- _err("relay requires an API key. Run `akash login` first.")
994
+ _warn("relay requires an API key.")
995
+ _p()
996
+ _info(f"To run on {_cy(device.strip() or 'a device')} you need to log in first:")
997
+ _info(f" {_cy('akash login')} save your API key on this machine")
998
+ _info(f" {_cy('akash serve')} run on the target device to make it reachable")
999
+ _p()
990
1000
  raise typer.Exit(1)
991
1001
 
992
1002
  # ── Device relay path ─────────────────────────────────────────────
@@ -1130,39 +1140,52 @@ def _build_ws_url_for_run(token: str, base_url: str) -> str:
1130
1140
  def shell(
1131
1141
  url: Optional[str] = typer.Option(None, "--url", help="Override server URL"),
1132
1142
  reauth: bool = typer.Option(False, "--reauth", help="Force re-authentication"),
1133
- device: Optional[str] = typer.Option(None, "--device","-d", help="Target device label (default: auto)"),
1143
+ device: Optional[str] = typer.Option(None, "--device", "-d",
1144
+ help="Device label to connect to (set up with: akash serve --label NAME)"),
1134
1145
  ):
1135
- """Open an interactive shell — on the server or on an enrolled device.
1146
+ """Open a shell — local, server, or on any enrolled device.
1136
1147
 
1137
- Full PTY — colours, arrow keys, tab completion, Ctrl-C all work.
1138
- Token cached 24 h — instant reconnect.
1148
+ No login needed:
1149
+ akash shell open a local bash shell
1139
1150
 
1140
- Examples:
1141
- akash shell # server shell
1142
- akash shell --device termux # shell on your phone
1143
- akash shell --device laptop # shell on your laptop
1144
- akash shell --device # auto (works if only 1 device enrolled)
1151
+ With login (akash login):
1152
+ akash shell full server shell (persistent, coloured)
1153
+ akash shell --device termux relay shell on your phone
1154
+ akash shell --device laptop relay shell on your laptop
1155
+ akash shell --device auto-pick (works if only 1 device enrolled)
1156
+
1157
+ To make a device reachable:
1158
+ 1. On that device: akash login --label termux && akash serve
1159
+ 2. From anywhere: akash shell --device termux
1145
1160
  """
1146
1161
  from .exec import acquire_exec_token, run_shell, _clear_cached_token
1162
+ import shutil as _sh, subprocess as _sp
1147
1163
 
1148
1164
  try:
1149
1165
  api_key, base = _resolve_client(url)
1150
1166
 
1151
- # ── No key + device flag → relay needs auth ───────────────────────
1167
+ # ── --device flag but no key ──────────────────────────────────────
1152
1168
  if device is not None and not api_key:
1153
- print(_GUEST_WARNING)
1154
- _err("relay requires an API key. Run `akash login` first.")
1169
+ _warn("relay requires an API key.")
1170
+ _p()
1171
+ _info(f"To connect to {_cy(device.strip() or 'a device')} you need to log in first:")
1172
+ _info(f" {_cy('akash login')} save your API key on this machine")
1173
+ _info(f" {_cy('akash serve')} run on the target device to make it reachable")
1174
+ _p()
1155
1175
  raise typer.Exit(1)
1156
1176
 
1157
1177
  # ── Device relay path ─────────────────────────────────────────────
1158
1178
  if device is not None:
1159
1179
  from .relay import connect_shell
1160
1180
  label = device.strip() if device.strip() else None
1161
- _info(f"connecting to device {_cy(label or 'auto')}…")
1181
+ _p()
1182
+ _info(f"connecting to {_cy(label or 'auto')}…")
1162
1183
  try:
1163
1184
  exit_code = connect_shell(api_key, base, target=label)
1164
1185
  except RuntimeError as e:
1165
1186
  _err(str(e))
1187
+ _p()
1188
+ _info(f"Make sure the device is running: {_cy('akash serve')}")
1166
1189
  raise typer.Exit(1)
1167
1190
  _p()
1168
1191
  _info("session closed")
@@ -1170,20 +1193,17 @@ def shell(
1170
1193
  raise typer.Exit(exit_code)
1171
1194
  return
1172
1195
 
1173
- # ── No key → local PTY shell fallback ────────────────────────────
1196
+ # ── No key → silent local shell ───────────────────────────────────
1174
1197
  if not api_key:
1175
- import shutil as _sh
1176
- print(_GUEST_WARNING)
1177
- _p()
1178
1198
  shell_bin = os.environ.get("SHELL") or _sh.which("bash") or _sh.which("sh") or "/bin/sh"
1179
- _info(f"opening local shell {_dim(shell_bin)}")
1199
+ _info(f"local shell {_dim(shell_bin)} {_dim('· tip: run akash login to unlock remote shells')}")
1180
1200
  _p()
1181
- import subprocess as _sp
1182
1201
  result = _sp.run([shell_bin])
1183
1202
  _p()
1184
1203
  _info("session closed")
1185
1204
  raise typer.Exit(result.returncode)
1186
1205
 
1206
+ # ── Server shell ──────────────────────────────────────────────────
1187
1207
  if reauth:
1188
1208
  _clear_cached_token()
1189
1209
  _info("cleared cached token — re-authenticating…")
@@ -1215,23 +1235,43 @@ def devices(
1215
1235
  revoke: Optional[str] = typer.Option(None, "--revoke", "-r", help="Revoke (unenroll) a device by label"),
1216
1236
  raw: bool = typer.Option(False, "--json", help="Raw JSON output"),
1217
1237
  ):
1218
- """List enrolled devices or revoke one.
1238
+ """List enrolled devices — or revoke one.
1219
1239
 
1220
- Each device you log in on with `akash login --label` appears here.
1221
- The server tracks when each device last authenticated.
1240
+ Each device you run `akash serve` on appears here.
1241
+ Connect from anywhere with: akash shell --device NAME
1222
1242
 
1223
1243
  Examples:
1224
1244
  akash devices list all enrolled devices
1225
1245
  akash devices --revoke laptop remove a device
1246
+
1247
+ Setup:
1248
+ akash login --label phone name this device
1249
+ akash serve register it as reachable
1226
1250
  """
1227
1251
  try:
1228
- api_key, base = _resolve_client(require_key=True)
1252
+ api_key, base = _resolve_client(require_key=False)
1229
1253
  except typer.Exit:
1230
1254
  raise
1231
1255
  except Exception as e:
1232
1256
  _err(str(e))
1233
1257
  raise typer.Exit(1)
1234
1258
 
1259
+ if not api_key:
1260
+ _p()
1261
+ _info("no devices yet — here's how to set up remote access:")
1262
+ _p()
1263
+ print(f" {_DM}Step 1 — on each device you want to reach:{_RS}")
1264
+ print(f" {_cy('akash login --label termux')} {_DM}(name this device){_RS}")
1265
+ print(f" {_cy('akash serve')} {_DM}(keep running — makes it reachable){_RS}")
1266
+ _p()
1267
+ print(f" {_DM}Step 2 — from anywhere:{_RS}")
1268
+ print(f" {_cy('akash shell --device termux')} {_DM}(open a shell on it){_RS}")
1269
+ print(f" {_cy('akash run --device termux \"cmd\"')} {_DM}(run a command on it){_RS}")
1270
+ _p()
1271
+ _info(f"Run {_cy('akash login')} first to save your API key.")
1272
+ _p()
1273
+ raise typer.Exit(0)
1274
+
1235
1275
  _hdrs = {"x-api-key": api_key, "Origin": "https://akash.cli"}
1236
1276
 
1237
1277
  if revoke:
@@ -1298,18 +1338,17 @@ def serve(
1298
1338
  status: bool = typer.Option(False, "--status", help="Show serve daemon status"),
1299
1339
  stop: bool = typer.Option(False, "--stop", help="Stop background serve daemon"),
1300
1340
  ):
1301
- """Make this device reachable via `akash shell --device` and `akash run --device`.
1341
+ """Make this device reachable for remote shell and run.
1302
1342
 
1303
- Registers this machine with the relay server and waits for incoming
1304
- shell/run requests. The connection is brokered through your cloud server —
1305
- no public IP required.
1343
+ Run this once on a device to register it. Then from any other
1344
+ machine: akash shell --device NAME or akash run --device NAME
1306
1345
 
1307
1346
  Examples:
1308
- akash serve # foreground (Ctrl-C to stop)
1309
- akash serve --daemon # background daemon
1310
- akash serve --status # check if daemon is running
1311
- akash serve --stop # kill daemon
1312
- akash serve --label termux # override device label
1347
+ akash serve start in foreground (Ctrl-C to stop)
1348
+ akash serve --daemon run as background daemon
1349
+ akash serve --status check if daemon is running
1350
+ akash serve --stop stop the daemon
1351
+ akash serve --label myphone use a custom label
1313
1352
  """
1314
1353
  from .relay import serve as _serve, serve_status, serve_stop
1315
1354
 
@@ -1320,7 +1359,8 @@ def serve(
1320
1359
  _ok(f"running {_dim('pid ' + pid_str)}")
1321
1360
  _info(f"logs {st['log']}")
1322
1361
  else:
1323
- _info("not running — start with: akash serve --daemon")
1362
+ _info("not running")
1363
+ _info(f"start with: {_cy('akash serve')} or {_cy('akash serve --daemon')}")
1324
1364
  return
1325
1365
 
1326
1366
  if stop:
@@ -1331,13 +1371,23 @@ def serve(
1331
1371
  return
1332
1372
 
1333
1373
  try:
1334
- api_key, base = _resolve_client(url, require_key=True)
1374
+ api_key, base = _resolve_client(url, require_key=False)
1335
1375
  except typer.Exit:
1336
1376
  raise
1337
1377
  except Exception as e:
1338
1378
  _err(str(e))
1339
1379
  raise typer.Exit(1)
1340
1380
 
1381
+ if not api_key:
1382
+ _p()
1383
+ _warn("not logged in — can't register with relay server.")
1384
+ _p()
1385
+ _info("Run this first:")
1386
+ print(f" {_cy('akash login --label myphone')} {_DM}# name this device{_RS}")
1387
+ print(f" {_cy('akash serve')} {_DM}# then run this{_RS}")
1388
+ _p()
1389
+ raise typer.Exit(1)
1390
+
1341
1391
  # Resolve label: flag > config > "default"
1342
1392
  from .exec import _device_label as _cfg_label
1343
1393
  resolved_label = (label or _cfg_label() or "default").strip()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: akashcli
3
- Version: 4.4.0
3
+ Version: 4.4.1
4
4
  Summary: Akash CLI — secure remote shell relay, file vault, and device management
5
5
  License: MIT
6
6
  Keywords: akash,cli,relay,remote-shell,vault
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "akashcli"
3
- version = "4.4.0"
3
+ version = "4.4.1"
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