forgexa-cli 1.24.0__tar.gz → 1.24.2__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 (24) hide show
  1. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/PKG-INFO +1 -1
  2. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli/__init__.py +1 -1
  3. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli/daemon.py +60 -12
  4. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli.egg-info/PKG-INFO +1 -1
  5. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/pyproject.toml +1 -1
  6. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/README.md +0 -0
  7. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli/_build_config.py +0 -0
  8. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli/autoupgrade.py +0 -0
  9. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli/main.py +0 -0
  10. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli/py.typed +0 -0
  11. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli.egg-info/SOURCES.txt +0 -0
  12. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli.egg-info/dependency_links.txt +0 -0
  13. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli.egg-info/entry_points.txt +0 -0
  14. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli.egg-info/requires.txt +0 -0
  15. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/forgexa_cli.egg-info/top_level.txt +0 -0
  16. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/setup.cfg +0 -0
  17. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_auth_and_runtime_commands.py +0 -0
  18. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_autoupgrade.py +0 -0
  19. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_check_command.py +0 -0
  20. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_expiry_warnings_and_revoke.py +0 -0
  21. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_runtime_credentials.py +0 -0
  22. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_session_credentials.py +0 -0
  23. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_silent_install.py +0 -0
  24. {forgexa_cli-1.24.0 → forgexa_cli-1.24.2}/tests/test_upgrade_observability.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.24.0
3
+ Version: 1.24.2
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-Expression: MIT
@@ -1,2 +1,2 @@
1
1
  """forgexa-cli — Forgexa command-line client."""
2
- __version__ = "1.24.0"
2
+ __version__ = "1.24.2"
@@ -870,7 +870,7 @@ except (ImportError, ModuleNotFoundError):
870
870
  # DAEMON_VERSION is the protocol/logic version of the daemon code.
871
871
  # Kept in sync with pyproject.toml version via bump-version.sh.
872
872
  # CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
873
- DAEMON_VERSION = "1.24.0"
873
+ DAEMON_VERSION = "1.24.2"
874
874
 
875
875
 
876
876
  def _detect_client_type() -> str:
@@ -10735,6 +10735,38 @@ class RuntimeDaemon:
10735
10735
  logger.info("deployment_merge GC: removed %d worktree(s)", removed)
10736
10736
  return removed
10737
10737
 
10738
+ @staticmethod
10739
+ def _scan_conflicted_files_for_markers(
10740
+ workspace_path: Path, conflicted_files: list[str],
10741
+ ) -> list[str]:
10742
+ """Return the subset of ``conflicted_files`` still containing conflict
10743
+ markers.
10744
+
10745
+ Scoped to files actually in conflict — a previous whole-repo ``git grep``
10746
+ matched legitimate content (Markdown Setext H1 underlines like
10747
+ ``Title\\n=======``, CodeMirror mode fixtures, patch context, etc.) and
10748
+ falsely reported ``precheck_failed`` on every merge for documentation-
10749
+ heavy projects. AI can only leave stray markers in files it touched;
10750
+ unrelated files are not its business.
10751
+
10752
+ Marker detection: a real git conflict block always has ``<<<<<<<`` at
10753
+ the start (and ``>>>>>>>`` at the end). ``=======`` alone is NOT
10754
+ matched — it is indistinguishable from a Markdown Setext heading
10755
+ underline and would re-introduce the false positive. The start/end
10756
+ markers are unique enough to be definitive.
10757
+ """
10758
+ marker_re = re.compile(r"^(?:<<<<<<<|>>>>>>>)", re.MULTILINE)
10759
+ found: list[str] = []
10760
+ for fpath in conflicted_files:
10761
+ full_path = workspace_path / fpath
10762
+ try:
10763
+ content = full_path.read_text(errors="replace")
10764
+ except (OSError, UnicodeDecodeError):
10765
+ continue
10766
+ if marker_re.search(content):
10767
+ found.append(fpath)
10768
+ return found
10769
+
10738
10770
  async def _execute_deployment_merge_job(self, aj: dict, conn: "ServerConnection"):
10739
10771
  """Execute a deployment_merge AIJob: git merge + conflict resolution.
10740
10772
 
@@ -10827,9 +10859,22 @@ class RuntimeDaemon:
10827
10859
  project_key=_proj_key,
10828
10860
  )
10829
10861
 
10830
- # Determine base SHA: use recorded base, else default branch HEAD.
10862
+ # Determine base SHA: use recorded base, else the integration
10863
+ # branch's current HEAD (NOT the default branch — the first merge
10864
+ # onto a manually-created integration branch must build on that
10865
+ # branch's content, not an unrelated default branch; otherwise the
10866
+ # candidate's history diverges from the integration branch and the
10867
+ # FF-only promote can never succeed).
10831
10868
  if base_integration_sha:
10832
10869
  base_ref = base_integration_sha
10870
+ elif integration_branch:
10871
+ try:
10872
+ base_ref = (await git("rev-parse", f"origin/{integration_branch}", cwd=workspace_path)).strip()
10873
+ except RuntimeError:
10874
+ try:
10875
+ base_ref = (await git("rev-parse", f"origin/{default_branch}", cwd=workspace_path)).strip()
10876
+ except RuntimeError:
10877
+ base_ref = "HEAD"
10833
10878
  else:
10834
10879
  try:
10835
10880
  base_ref = (await git("rev-parse", f"origin/{default_branch}", cwd=workspace_path)).strip()
@@ -11125,16 +11170,12 @@ class RuntimeDaemon:
11125
11170
  # deterministic precheck + reporting block below.
11126
11171
 
11127
11172
  # Deterministic precheck: scan for residual conflict markers.
11128
- # Applies to both clean merges and AI-resolved merges.
11173
+ # Applies to both clean merges and AI-resolved merges. Scoped to
11174
+ # files actually in conflict — see _scan_conflicted_files_for_markers.
11129
11175
  candidate_sha = (await git("rev-parse", "HEAD", cwd=workspace_path)).strip()
11130
- marker_proc = await asyncio.create_subprocess_exec(
11131
- "git", "grep", "-l", "-E", r"^(<<<<<<<|=======|>>>>>>>)",
11132
- cwd=str(workspace_path),
11133
- stdout=asyncio.subprocess.PIPE,
11134
- stderr=asyncio.subprocess.DEVNULL,
11176
+ marker_files = self._scan_conflicted_files_for_markers(
11177
+ workspace_path, conflicted_files,
11135
11178
  )
11136
- marker_stdout, _ = await marker_proc.communicate()
11137
- marker_files = [f.strip() for f in marker_stdout.decode().strip().splitlines() if f.strip()]
11138
11179
 
11139
11180
  if marker_files:
11140
11181
  logger.warning(
@@ -11175,9 +11216,16 @@ class RuntimeDaemon:
11175
11216
  return
11176
11217
 
11177
11218
  # Push the candidate commit to origin so external CI can check it
11178
- # out and subsequent merges can fetch it as a base.
11219
+ # out and subsequent merges can fetch it as a base. Force-push
11220
+ # because the candidate ref is ephemeral — a re-merge (new train
11221
+ # round, baseline resync) produces a different commit history that
11222
+ # is NOT a fast-forward of the previous candidate.
11179
11223
  try:
11180
- await git("push", "origin", f"HEAD:{candidate_ref}", cwd=workspace_path)
11224
+ await git(
11225
+ "push", "origin", f"+HEAD:{candidate_ref}",
11226
+ cwd=workspace_path,
11227
+ timeout=settings.GIT_PUSH_TIMEOUT,
11228
+ )
11181
11229
  except RuntimeError as exc:
11182
11230
  logger.warning(
11183
11231
  "deployment_merge: job %s candidate push failed: %s", job_id, exc,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.24.0
3
+ Version: 1.24.2
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-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "forgexa-cli"
3
- version = "1.24.0"
3
+ version = "1.24.2"
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 = "MIT"
File without changes
File without changes