forgexa-cli 1.15.2__tar.gz → 1.15.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.15.2
3
+ Version: 1.15.3
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.15.2"
2
+ __version__ = "1.15.3"
@@ -523,7 +523,7 @@ except (ImportError, ModuleNotFoundError):
523
523
  # DAEMON_VERSION is the protocol/logic version of the daemon code.
524
524
  # Kept in sync with pyproject.toml version via bump-version.sh.
525
525
  # CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
526
- DAEMON_VERSION = "1.15.2"
526
+ DAEMON_VERSION = "1.15.3"
527
527
 
528
528
 
529
529
  def _detect_client_type() -> str:
@@ -7986,9 +7986,41 @@ class RuntimeDaemon:
7986
7986
  else:
7987
7987
  base = workspace_path
7988
7988
 
7989
+ # --- Read e2e intents from test-intent.json (all requirement types) ---
7990
+ # Not gated by _requires_structured_artifacts so that bugfix with e2e
7991
+ # intents gets the same E2E chain validation as feature/improvement.
7992
+ _e2e_intent_ids: set[str] = set()
7993
+ _analysis_dir = (
7994
+ _input.get("analysis_output_dir")
7995
+ or (_input.get("context") or {}).get("analysis_output_dir")
7996
+ or ""
7997
+ )
7998
+ if _analysis_dir:
7999
+ _ti_path = workspace_path / _analysis_dir / "test-intent.json"
8000
+ if _ti_path.exists():
8001
+ try:
8002
+ _ti_data = _json.loads(
8003
+ _ti_path.read_text(encoding="utf-8")
8004
+ )
8005
+ for _ti in _ti_data.get("intents", []):
8006
+ if (_ti.get("automation_target") or "").lower() == "e2e":
8007
+ _ti_id = (
8008
+ _ti.get("id")
8009
+ or _ti.get("test_id")
8010
+ or _ti.get("intent_id")
8011
+ )
8012
+ if _ti_id:
8013
+ _e2e_intent_ids.add(str(_ti_id))
8014
+ except (_json.JSONDecodeError, UnicodeDecodeError):
8015
+ # test-intent.json parse errors are reported
8016
+ # by the analysis node validation; stay silent here.
8017
+ pass
8018
+ # True when e2e intents exist — drives test-cases.json / cm requirement
8019
+ _requires_e2e_artifacts = bool(_e2e_intent_ids)
8020
+
7989
8021
  # --- test-cases.json validation ---
7990
- # Required for feature/improvement; optional (but validated
7991
- # if present) for all other testing node types.
8022
+ # Required for feature/improvement (always), or any type with e2e intents
8023
+ # (e.g. a UI bugfix whose test-intent.json has automation_target='e2e').
7992
8024
  tc_path = base / "test-cases.json"
7993
8025
  if tc_path.exists():
7994
8026
  try:
@@ -8012,9 +8044,58 @@ class RuntimeDaemon:
8012
8044
  p0_cases = [c for c in cases if c.get("priority") == "P0"]
8013
8045
  if not p0_cases:
8014
8046
  issues.append("No P0 priority test cases found in test-cases.json")
8047
+
8048
+ # --- E2E conditional chain validation ---
8049
+ # Fires for any type when test-intent.json contains
8050
+ # automation_target='e2e' intents (feature, improvement,
8051
+ # bugfix, ...). Pure backend types without e2e intents
8052
+ # are unaffected.
8053
+ if _e2e_intent_ids:
8054
+ # Check 1: every e2e intent must have >=1 e2e test case
8055
+ _e2e_case_refs: set[str] = set()
8056
+ for _tc in cases:
8057
+ if (_tc.get("test_type") or "").lower() == "e2e":
8058
+ _ref = str(
8059
+ _tc.get("intent_id")
8060
+ or _tc.get("test_intent_id")
8061
+ or ""
8062
+ )
8063
+ if _ref:
8064
+ _e2e_case_refs.add(_ref)
8065
+ _missing_e2e = _e2e_intent_ids - _e2e_case_refs
8066
+ if _missing_e2e:
8067
+ issues.append(
8068
+ f"test-cases.json missing e2e test cases for intents: "
8069
+ f"{sorted(_missing_e2e)}. Each test intent with "
8070
+ f"automation_target='e2e' must have at least one "
8071
+ f"test_type='e2e' test case."
8072
+ )
8073
+
8074
+ # Check 2: every e2e test case must have non-empty
8075
+ # script_content (and script_path file must exist if set)
8076
+ for _tc in cases:
8077
+ if (_tc.get("test_type") or "").lower() != "e2e":
8078
+ continue
8079
+ _tc_id = _tc.get("id", "?")
8080
+ _script = (_tc.get("script_content") or "").strip()
8081
+ if not _script:
8082
+ issues.append(
8083
+ f"E2E test case {_tc_id} has empty 'script_content'. "
8084
+ f"You MUST generate the Playwright TypeScript script "
8085
+ f"and embed the full content in script_content."
8086
+ )
8087
+ else:
8088
+ _sp = (_tc.get("script_path") or "").strip()
8089
+ if _sp:
8090
+ _sp_full = workspace_path / _sp
8091
+ if not _sp_full.exists():
8092
+ issues.append(
8093
+ f"E2E test case {_tc_id} script_path "
8094
+ f"'{_sp}' does not exist on disk."
8095
+ )
8015
8096
  except (_json.JSONDecodeError, UnicodeDecodeError) as e:
8016
8097
  issues.append(f"test-cases.json is not valid JSON: {e}")
8017
- elif _requires_structured_artifacts:
8098
+ elif _requires_structured_artifacts or _requires_e2e_artifacts:
8018
8099
  issues.append(f"test-cases.json not found in {doc_dir or 'workspace root'}")
8019
8100
 
8020
8101
  # --- coverage-matrix.json validation ---
@@ -8029,7 +8110,7 @@ class RuntimeDaemon:
8029
8110
  issues.append(f"Uncovered acceptance criteria in coverage-matrix.json: {ids}")
8030
8111
  except (_json.JSONDecodeError, UnicodeDecodeError) as e:
8031
8112
  issues.append(f"coverage-matrix.json is not valid JSON: {e}")
8032
- elif _requires_structured_artifacts:
8113
+ elif _requires_structured_artifacts or _requires_e2e_artifacts:
8033
8114
  issues.append(f"coverage-matrix.json not found in {doc_dir or 'workspace root'}")
8034
8115
 
8035
8116
  # --- test-report.md validation ---
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forgexa-cli
3
- Version: 1.15.2
3
+ Version: 1.15.3
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.15.2"
3
+ version = "1.15.3"
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