replx-agent 2.0.0__py3-none-any.whl

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.

Potentially problematic release.


This version of replx-agent might be problematic. Click here for more details.

Files changed (46) hide show
  1. replx_agent/__init__.py +3 -0
  2. replx_agent/__main__.py +5 -0
  3. replx_agent/commands.py +131 -0
  4. replx_agent/helpers/__init__.py +3 -0
  5. replx_agent/helpers/scanner.py +308 -0
  6. replx_agent/pkg/__init__.py +11 -0
  7. replx_agent/pkg/compiler.py +153 -0
  8. replx_agent/pkg/registry.py +387 -0
  9. replx_agent/pkg/service.py +690 -0
  10. replx_agent/pkg/store.py +83 -0
  11. replx_agent/protocol/__init__.py +11 -0
  12. replx_agent/protocol/repl.py +1029 -0
  13. replx_agent/protocol/storage.py +1018 -0
  14. replx_agent/rpc/__init__.py +3 -0
  15. replx_agent/rpc/protocol.py +220 -0
  16. replx_agent/server/__init__.py +3 -0
  17. replx_agent/server/__main__.py +4 -0
  18. replx_agent/server/command_dispatcher.py +49 -0
  19. replx_agent/server/connection_manager.py +654 -0
  20. replx_agent/server/core.py +1221 -0
  21. replx_agent/server/handlers/__init__.py +24 -0
  22. replx_agent/server/handlers/exec.py +553 -0
  23. replx_agent/server/handlers/filesystem.py +383 -0
  24. replx_agent/server/handlers/firmware.py +118 -0
  25. replx_agent/server/handlers/i2c.py +23 -0
  26. replx_agent/server/handlers/package.py +182 -0
  27. replx_agent/server/handlers/repl.py +188 -0
  28. replx_agent/server/handlers/session.py +205 -0
  29. replx_agent/server/handlers/spi.py +23 -0
  30. replx_agent/server/handlers/transfer.py +600 -0
  31. replx_agent/server/handlers/uart.py +32 -0
  32. replx_agent/server/session_manager.py +391 -0
  33. replx_agent/server/tcp.py +207 -0
  34. replx_agent/terminal.py +566 -0
  35. replx_agent/transport/__init__.py +32 -0
  36. replx_agent/transport/serial.py +220 -0
  37. replx_agent/utils/__init__.py +95 -0
  38. replx_agent/utils/constants.py +78 -0
  39. replx_agent/utils/device_info.py +183 -0
  40. replx_agent/utils/exceptions.py +31 -0
  41. replx_agent-2.0.0.dist-info/METADATA +74 -0
  42. replx_agent-2.0.0.dist-info/RECORD +46 -0
  43. replx_agent-2.0.0.dist-info/WHEEL +5 -0
  44. replx_agent-2.0.0.dist-info/entry_points.txt +2 -0
  45. replx_agent-2.0.0.dist-info/licenses/LICENSE +21 -0
  46. replx_agent-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,83 @@
1
+ import os
2
+ import json
3
+ import base64
4
+ import threading
5
+ import urllib.request
6
+ from pathlib import Path
7
+
8
+ from replx_agent.utils.constants import HTTP_REQUEST_TIMEOUT
9
+ from replx_agent.utils.exceptions import PkgError
10
+
11
+
12
+ class StoreManager:
13
+ HOME_STORE = Path.home() / ".replx"
14
+ HOME_STAGING = HOME_STORE / ".staging"
15
+ META_NAME = "registry.json"
16
+ # Serializes store mutations (meta writes, clean) across agent threads.
17
+ LOCK = threading.RLock()
18
+
19
+ @staticmethod
20
+ def ensure_home_store():
21
+ StoreManager.HOME_STORE.mkdir(parents=True, exist_ok=True)
22
+ (StoreManager.HOME_STORE / "core").mkdir(exist_ok=True)
23
+ (StoreManager.HOME_STORE / "device").mkdir(exist_ok=True)
24
+ StoreManager.HOME_STAGING.mkdir(parents=True, exist_ok=True)
25
+
26
+ @staticmethod
27
+ def pkg_root() -> str:
28
+ StoreManager.ensure_home_store()
29
+ return str(StoreManager.HOME_STORE)
30
+
31
+ @staticmethod
32
+ def local_meta_path() -> str:
33
+ return os.path.join(StoreManager.pkg_root(), StoreManager.META_NAME)
34
+
35
+ @staticmethod
36
+ def gh_headers() -> dict:
37
+ hdrs = {"User-Agent": "replx"}
38
+ tok = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
39
+ if tok:
40
+ hdrs["Authorization"] = f"******"
41
+ return hdrs
42
+
43
+ @staticmethod
44
+ def load_local_meta() -> dict:
45
+ p = StoreManager.local_meta_path()
46
+ if not os.path.exists(p):
47
+ return {"targets": {}, "items": {}}
48
+ try:
49
+ with open(p, "r", encoding="utf-8") as f:
50
+ return json.load(f)
51
+ except Exception:
52
+ return {"targets": {}, "items": {}}
53
+
54
+ @staticmethod
55
+ def save_local_meta(meta: dict):
56
+ p = StoreManager.local_meta_path()
57
+ tmp = p + ".tmp"
58
+ os.makedirs(os.path.dirname(p), exist_ok=True)
59
+ with open(tmp, "w", encoding="utf-8") as f:
60
+ json.dump(meta, f, ensure_ascii=False, indent=2)
61
+ os.replace(tmp, p)
62
+
63
+ @staticmethod
64
+ def load_remote_meta(owner: str, repo: str, ref_: str) -> dict:
65
+ url = f"https://api.github.com/repos/{owner}/{repo}/contents/{StoreManager.META_NAME}?ref={ref_}"
66
+ req = urllib.request.Request(url, headers=StoreManager.gh_headers())
67
+ with urllib.request.urlopen(req, timeout=HTTP_REQUEST_TIMEOUT) as r:
68
+ data = json.load(r)
69
+ b64 = (data.get("content") or "").replace("\n", "")
70
+ if not b64:
71
+ raise PkgError("Remote meta has no content.")
72
+ txt = base64.b64decode(b64.encode("utf-8")).decode("utf-8")
73
+ return json.loads(txt)
74
+
75
+ @staticmethod
76
+ def refresh_meta_if_online(owner: str, repo: str, ref_: str) -> bool:
77
+ try:
78
+ remote = StoreManager.load_remote_meta(owner, repo, ref_)
79
+ with StoreManager.LOCK:
80
+ StoreManager.save_local_meta(remote)
81
+ return True
82
+ except Exception:
83
+ return False
@@ -0,0 +1,11 @@
1
+
2
+ from .repl import ReplProtocol
3
+ from .storage import DeviceStorage, SerialStorage, create_storage
4
+
5
+ __all__ = [
6
+ "ReplProtocol",
7
+ # Storage API
8
+ "DeviceStorage",
9
+ "SerialStorage",
10
+ "create_storage",
11
+ ]