forgexa-cli 1.36.3__tar.gz → 1.37.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.
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/PKG-INFO +1 -1
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/__init__.py +1 -1
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/agent_core.py +5 -3
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/daemon.py +30 -5
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli.egg-info/PKG-INFO +1 -1
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/pyproject.toml +1 -1
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/README.md +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/_build_config.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/_local_bind.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/autoupgrade.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/main.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli/py.typed +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli.egg-info/SOURCES.txt +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli.egg-info/dependency_links.txt +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli.egg-info/entry_points.txt +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli.egg-info/requires.txt +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/forgexa_cli.egg-info/top_level.txt +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/setup.cfg +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_auth_and_runtime_commands.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_autoupgrade.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_check_command.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_expiry_warnings_and_revoke.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_local_bind_commands.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_runtime_credentials.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_session_credentials.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_silent_install.py +0 -0
- {forgexa_cli-1.36.3 → forgexa_cli-1.37.1}/tests/test_upgrade_observability.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""forgexa-cli — Forgexa command-line client."""
|
|
2
|
-
__version__ = "1.
|
|
2
|
+
__version__ = "1.37.1"
|
|
@@ -1427,9 +1427,10 @@ def prepare_claude_environment(
|
|
|
1427
1427
|
Claude use its default config, cache, and session locations under a
|
|
1428
1428
|
writable task sandbox.
|
|
1429
1429
|
|
|
1430
|
-
Mirror only stable authentication and settings files
|
|
1431
|
-
|
|
1432
|
-
|
|
1430
|
+
Mirror only stable authentication and settings files, including Claude
|
|
1431
|
+
Code's current credential store. Runtime state such as session-env,
|
|
1432
|
+
projects, task locks, and history must never cross into an isolated daemon
|
|
1433
|
+
invocation. Do not set CLAUDE_CODE_DEBUG_LOGS_DIR:
|
|
1433
1434
|
Claude Code 2.1.63 treats a directory supplied through that variable as
|
|
1434
1435
|
a file after TodoWrite and exits with EISDIR.
|
|
1435
1436
|
"""
|
|
@@ -1444,6 +1445,7 @@ def prepare_claude_environment(
|
|
|
1444
1445
|
|
|
1445
1446
|
source_files = [
|
|
1446
1447
|
(Path.home() / ".claude.json", sandbox_root / ".claude.json"),
|
|
1448
|
+
(Path.home() / ".claude" / ".credentials.json", home_claude_dir / ".credentials.json"),
|
|
1447
1449
|
(Path.home() / ".claude" / "settings.json", home_claude_dir / "settings.json"),
|
|
1448
1450
|
(Path.home() / ".claude" / "settings.local.json", home_claude_dir / "settings.local.json"),
|
|
1449
1451
|
]
|
|
@@ -910,7 +910,7 @@ except (ImportError, ModuleNotFoundError):
|
|
|
910
910
|
# DAEMON_VERSION is the protocol/logic version of the daemon code.
|
|
911
911
|
# Kept in sync with pyproject.toml version via bump-version.sh.
|
|
912
912
|
# CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
|
|
913
|
-
DAEMON_VERSION = "1.
|
|
913
|
+
DAEMON_VERSION = "1.37.1"
|
|
914
914
|
|
|
915
915
|
|
|
916
916
|
def _detect_client_type() -> str:
|
|
@@ -4764,6 +4764,8 @@ class ProcessManager:
|
|
|
4764
4764
|
signals, which strongly indicates a pre-call CLI failure printed as
|
|
4765
4765
|
plain text (for example "API Error: 429 ...").
|
|
4766
4766
|
"""
|
|
4767
|
+
if result.failure_code == "all_agents_rate_limited":
|
|
4768
|
+
return False
|
|
4767
4769
|
error_text = ProcessManager._failure_pattern_channels(result).lower()
|
|
4768
4770
|
return (
|
|
4769
4771
|
any(p in error_text for p in ProcessManager.RATE_LIMIT_PATTERNS)
|
|
@@ -8656,6 +8658,17 @@ class RuntimeDaemon:
|
|
|
8656
8658
|
return
|
|
8657
8659
|
|
|
8658
8660
|
try:
|
|
8661
|
+
# Analysis-continuity P0 (design doc §九 P0-5, R1-c): capture the
|
|
8662
|
+
# pre-wipe HEAD so the deleted analysis docs remain recoverable
|
|
8663
|
+
# from git history via this exact commit.
|
|
8664
|
+
try:
|
|
8665
|
+
pre_wipe_sha = (
|
|
8666
|
+
await self.workspace_manager._git(
|
|
8667
|
+
"rev-parse", "HEAD", cwd=workspace_path,
|
|
8668
|
+
)
|
|
8669
|
+
).strip()
|
|
8670
|
+
except Exception:
|
|
8671
|
+
pre_wipe_sha = "unknown"
|
|
8659
8672
|
# Stage all deletions with git rm
|
|
8660
8673
|
await self.workspace_manager._git(
|
|
8661
8674
|
"rm", "-r", "--cached", "--ignore-unmatch",
|
|
@@ -8664,18 +8677,24 @@ class RuntimeDaemon:
|
|
|
8664
8677
|
)
|
|
8665
8678
|
# Remove physical files
|
|
8666
8679
|
shutil.rmtree(str(dir_to_wipe), ignore_errors=True)
|
|
8667
|
-
# Commit the wipe so the branch diff is clean
|
|
8680
|
+
# Commit the wipe so the branch diff is clean. The pre-wipe HEAD in
|
|
8681
|
+
# the message documents where the old docs can be recovered from.
|
|
8668
8682
|
_git_name, _git_email = _resolve_git_author(task.project)
|
|
8683
|
+
_wipe_msg = (
|
|
8684
|
+
f"cleanup: wipe analysis docs in {output_dir_norm} before fresh re-analysis"
|
|
8685
|
+
)
|
|
8686
|
+
if pre_wipe_sha and pre_wipe_sha != "unknown":
|
|
8687
|
+
_wipe_msg += f" [pre-wipe HEAD {pre_wipe_sha}]"
|
|
8669
8688
|
await self.workspace_manager._git(
|
|
8670
8689
|
"-c", f"user.name={_git_name}",
|
|
8671
8690
|
"-c", f"user.email={_git_email}",
|
|
8672
8691
|
"commit", "-m",
|
|
8673
|
-
|
|
8692
|
+
_wipe_msg,
|
|
8674
8693
|
cwd=workspace_path,
|
|
8675
8694
|
)
|
|
8676
8695
|
logger.info(
|
|
8677
|
-
"Wiped %d analysis doc(s) from %s for task %s (fresh analysis)",
|
|
8678
|
-
len(existing_files), output_dir_norm, task.task_id,
|
|
8696
|
+
"Wiped %d analysis doc(s) from %s for task %s (fresh analysis; pre-wipe HEAD %s)",
|
|
8697
|
+
len(existing_files), output_dir_norm, task.task_id, pre_wipe_sha,
|
|
8679
8698
|
)
|
|
8680
8699
|
except Exception as _wipe_err:
|
|
8681
8700
|
# Wipe failure on a fresh analysis is not safe to ignore:
|
|
@@ -11391,6 +11410,12 @@ class RuntimeDaemon:
|
|
|
11391
11410
|
base = workspace_path / doc_dir.lstrip("./")
|
|
11392
11411
|
req_type = input_data.get("requirement_type", "feature")
|
|
11393
11412
|
candidate_paths = [str(base / fname) for fname in _get_analysis_outputs_for_type(req_type)]
|
|
11413
|
+
# Analysis-continuity P2: collect the machine-readable refinement
|
|
11414
|
+
# report so the server can verify feedback coverage and baseline
|
|
11415
|
+
# commitments before promoting the candidate (missing file is
|
|
11416
|
+
# handled server-side as a needs_review condition).
|
|
11417
|
+
if input_data.get("analysis_mode") == "refine":
|
|
11418
|
+
candidate_paths.append(str(base / "refinement-report.json"))
|
|
11394
11419
|
|
|
11395
11420
|
existing_artifact_paths = {a.get("path", "").replace("\\", "/") for a in result.artifacts}
|
|
11396
11421
|
|
|
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
|
|
File without changes
|
|
File without changes
|