forgexa-cli 1.2.6__tar.gz → 1.2.7__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: Forgexa CLI — command-line client and AI agent runtime for the Forgexa platform
5
5
  Author-email: Jason Sun <dev.winds@gmail.com>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
1
  """forgexa-cli — Forgexa command-line client."""
2
- __version__ = "1.2.6"
2
+ __version__ = "1.2.7"
@@ -242,6 +242,47 @@ def get_hardware_id() -> str:
242
242
  return uuid.uuid4().hex[:24]
243
243
 
244
244
 
245
+ def get_os_info() -> str:
246
+ """Return a concise OS/arch summary string, e.g. 'macOS 15.0 arm64', 'Ubuntu 24.04 x86_64'."""
247
+ system = platform.system()
248
+ machine = platform.machine()
249
+ if system == "Darwin":
250
+ # e.g. "macOS 15.0 arm64"
251
+ mac_ver = platform.mac_ver()[0] or platform.release()
252
+ return f"macOS {mac_ver} {machine}"
253
+ elif system == "Linux":
254
+ # Try to get distro name+version from /etc/os-release
255
+ distro = _get_linux_distro()
256
+ if distro:
257
+ return f"{distro} {machine}"
258
+ return f"Linux {platform.release().split('-')[0]} {machine}"
259
+ elif system == "Windows":
260
+ # e.g. "Windows 10.0 AMD64"
261
+ win_ver = platform.version().split('.')[0:2]
262
+ return f"Windows {'.'.join(win_ver)} {machine}"
263
+ else:
264
+ return f"{system} {platform.release()} {machine}"
265
+
266
+
267
+ def _get_linux_distro() -> str:
268
+ """Parse /etc/os-release to get distro name and version, e.g. 'Ubuntu 24.04'."""
269
+ try:
270
+ with open("/etc/os-release") as f:
271
+ info = {}
272
+ for line in f:
273
+ line = line.strip()
274
+ if "=" in line:
275
+ key, _, val = line.partition("=")
276
+ info[key] = val.strip('"')
277
+ name = info.get("NAME", "")
278
+ version = info.get("VERSION_ID", "")
279
+ if name:
280
+ return f"{name} {version}".strip()
281
+ except OSError:
282
+ pass
283
+ return ""
284
+
285
+
245
286
  # ── Data Classes ──
246
287
 
247
288
 
@@ -726,6 +767,35 @@ class WorkspaceManager:
726
767
  )
727
768
  except RuntimeError as exc2:
728
769
  logger.warning("Failed to reset to origin/%s: %s", default_branch, exc2)
770
+ else:
771
+ # Non-fresh-start (design/coding/testing): ensure working tree
772
+ # is on the correct branch and has the latest commits from remote.
773
+ # This is critical for cross-machine execution where a previous
774
+ # node on another daemon pushed commits to the branch.
775
+ logger.info("Syncing worktree %s to latest origin/%s", ws_path, branch_name)
776
+ try:
777
+ await self._git("checkout", branch_name, cwd=ws_path)
778
+ except RuntimeError:
779
+ # Branch might not exist locally yet — create tracking branch
780
+ try:
781
+ await self._git(
782
+ "checkout", "-B", branch_name, f"origin/{branch_name}",
783
+ cwd=ws_path,
784
+ )
785
+ except RuntimeError as exc:
786
+ logger.warning("Failed to checkout %s: %s", branch_name, exc)
787
+ # Reset working tree to match remote branch (fast-forward)
788
+ try:
789
+ await self._git(
790
+ "reset", "--hard", f"origin/{branch_name}",
791
+ cwd=ws_path,
792
+ )
793
+ except RuntimeError as exc:
794
+ # Remote branch might not exist yet (first node in graph)
795
+ logger.debug(
796
+ "Could not reset to origin/%s: %s — branch may not exist on remote yet",
797
+ branch_name, exc,
798
+ )
729
799
  return ws_path
730
800
 
731
801
  # Ensure _main repo is present and up-to-date
@@ -1761,6 +1831,7 @@ class HeartbeatService:
1761
1831
  "active_tasks": self._active_tasks,
1762
1832
  "available_agents": self._agents,
1763
1833
  "system_metrics": self._collect_system_metrics(),
1834
+ "os_info": get_os_info(),
1764
1835
  },
1765
1836
  timeout=10,
1766
1837
  )
@@ -1941,6 +2012,7 @@ class ServerConnection:
1941
2012
  "daemon_id": self.daemon_id,
1942
2013
  "hardware_id": self.hardware_id,
1943
2014
  "device_name": platform.node(),
2015
+ "os_info": get_os_info(),
1944
2016
  "available_agents": agent_dicts,
1945
2017
  "max_concurrent_tasks": max_concurrent,
1946
2018
  "capabilities": {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.2.6
3
+ Version: 1.2.7
4
4
  Summary: Forgexa CLI — command-line client and AI agent runtime for the Forgexa platform
5
5
  Author-email: Jason Sun <dev.winds@gmail.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "forgexa-cli"
3
- version = "1.2.6"
3
+ version = "1.2.7"
4
4
  description = "Forgexa CLI — command-line client and AI agent runtime for the Forgexa platform"
5
5
  requires-python = ">=3.9"
6
6
  license = { text = "MIT" }
File without changes
File without changes