forgexa-cli 1.9.0__tar.gz → 1.9.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.
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/PKG-INFO +1 -1
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli/__init__.py +1 -1
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli/daemon.py +25 -2
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli.egg-info/PKG-INFO +1 -1
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/pyproject.toml +1 -1
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/README.md +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli/_build_config.py +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli/main.py +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli/py.typed +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli.egg-info/SOURCES.txt +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli.egg-info/dependency_links.txt +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli.egg-info/entry_points.txt +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli.egg-info/requires.txt +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/forgexa_cli.egg-info/top_level.txt +0 -0
- {forgexa_cli-1.9.0 → forgexa_cli-1.9.2}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""forgexa-cli — Forgexa command-line client."""
|
|
2
|
-
__version__ = "1.9.
|
|
2
|
+
__version__ = "1.9.2"
|
|
@@ -396,7 +396,7 @@ except (ImportError, ModuleNotFoundError):
|
|
|
396
396
|
# DAEMON_VERSION is the protocol/logic version of the daemon code.
|
|
397
397
|
# Kept in sync with pyproject.toml version via bump-version.sh.
|
|
398
398
|
# CLIENT_TYPE identifies which packaging/distribution this daemon runs in.
|
|
399
|
-
DAEMON_VERSION = "1.9.
|
|
399
|
+
DAEMON_VERSION = "1.9.2"
|
|
400
400
|
|
|
401
401
|
|
|
402
402
|
def _detect_client_type() -> str:
|
|
@@ -2842,6 +2842,11 @@ class ProcessManager:
|
|
|
2842
2842
|
Uses `opencode run --format json --dir <cwd>` for headless execution.
|
|
2843
2843
|
The message is passed as a positional argument.
|
|
2844
2844
|
NOTE: `--dir` is the correct flag (not `--cwd` which is invalid).
|
|
2845
|
+
|
|
2846
|
+
Each invocation gets an isolated XDG_DATA_HOME so that concurrent
|
|
2847
|
+
opencode runs do not share the same SQLite database, which causes
|
|
2848
|
+
'Failed to run the query PRAGMA wal_checkpoint(PASSIVE)' errors and
|
|
2849
|
+
exit code 1 when multiple tasks run simultaneously.
|
|
2845
2850
|
"""
|
|
2846
2851
|
cmd = [
|
|
2847
2852
|
agent.command, "run",
|
|
@@ -2856,7 +2861,23 @@ class ProcessManager:
|
|
|
2856
2861
|
# -- ensures yargs treats everything after it as positional args, not flags.
|
|
2857
2862
|
# Without this, prompts containing --flag-like text cause yargs to print help and exit 1.
|
|
2858
2863
|
cmd += ["--", prompt]
|
|
2859
|
-
|
|
2864
|
+
|
|
2865
|
+
# Isolate each opencode run in its own data directory to prevent
|
|
2866
|
+
# concurrent processes from racing on the shared SQLite WAL file.
|
|
2867
|
+
tmp_data_root = tempfile.mkdtemp(prefix=f"opencode-{task_id[:8]}-")
|
|
2868
|
+
try:
|
|
2869
|
+
isolated_data_dir = Path(tmp_data_root) / "opencode"
|
|
2870
|
+
isolated_data_dir.mkdir()
|
|
2871
|
+
# Copy auth.json so provider credentials are available.
|
|
2872
|
+
auth_src = Path.home() / ".local" / "share" / "opencode" / "auth.json"
|
|
2873
|
+
if auth_src.exists():
|
|
2874
|
+
shutil.copy2(auth_src, isolated_data_dir / "auth.json")
|
|
2875
|
+
env = os.environ.copy()
|
|
2876
|
+
env["XDG_DATA_HOME"] = tmp_data_root
|
|
2877
|
+
result = await self._run_cli(cmd, cwd, timeout, task_id, on_chunk=on_chunk, env=env)
|
|
2878
|
+
finally:
|
|
2879
|
+
shutil.rmtree(tmp_data_root, ignore_errors=True)
|
|
2880
|
+
|
|
2860
2881
|
parsed_metrics = self._parse_agent_jsonl_output(result.stdout)
|
|
2861
2882
|
result.metrics.update(parsed_metrics)
|
|
2862
2883
|
return result
|
|
@@ -2991,6 +3012,7 @@ class ProcessManager:
|
|
|
2991
3012
|
self, cmd: list[str], cwd: Path, timeout: int, task_id: str,
|
|
2992
3013
|
stdin_input: str | None = None,
|
|
2993
3014
|
on_chunk: Any = None,
|
|
3015
|
+
env: dict | None = None,
|
|
2994
3016
|
) -> TaskResult:
|
|
2995
3017
|
try:
|
|
2996
3018
|
proc = await asyncio.create_subprocess_exec(
|
|
@@ -2999,6 +3021,7 @@ class ProcessManager:
|
|
|
2999
3021
|
stderr=asyncio.subprocess.PIPE,
|
|
3000
3022
|
stdin=asyncio.subprocess.PIPE if stdin_input else None,
|
|
3001
3023
|
cwd=str(cwd),
|
|
3024
|
+
env=env,
|
|
3002
3025
|
limit=100 * 1024 * 1024, # 100MB line buffer for large agent output
|
|
3003
3026
|
start_new_session=True, # own process group → killpg on timeout kills all children
|
|
3004
3027
|
)
|
|
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
|