answer42 0.2.6__tar.gz → 0.2.8__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.
- {answer42-0.2.6 → answer42-0.2.8}/PKG-INFO +1 -1
- {answer42-0.2.6 → answer42-0.2.8}/pyproject.toml +1 -1
- {answer42-0.2.6 → answer42-0.2.8}/scripts/build_pages.py +1 -2
- answer42-0.2.8/src/mcp_1c/__init__.py +22 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/server.py +36 -6
- answer42-0.2.6/src/mcp_1c/__init__.py +0 -4
- {answer42-0.2.6 → answer42-0.2.8}/.gitignore +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/LICENSE +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/README.md +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/credentials.example.json +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/docs/agent-installation.md +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/docs/architecture.md +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/docs/assets/answer42-logo.png +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/docs/assets/platform42-logo.svg +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/docs/installation.md +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/scripts/build_cf.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/scripts/e2e_stable.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/scripts/openclaw_mcp_autoreload.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/scripts/rag_cli.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/Configuration.xml +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Catalogs//320/237/320/241_/320/222/320/273/320/260/320/264/320/265/320/273/320/265/321/206.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Catalogs//320/237/320/241_/320/241/320/277/321/200/320/260/320/262/320/276/321/207/320/275/320/270/320/2721.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Configuration.xml +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Ext/ManagerModule.bsl" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Ext/ObjectModule.bsl" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Templates//320/236/321/201/320/275/320/276/320/262/320/275/320/260/321/217/320/241/321/205/320/265/320/274/320/260/320/232/320/276/320/274/320/277/320/276/320/275/320/276/320/262/320/272/320/270/320/224/320/260/320/275/320/275/321/213/321/205/Ext/Template.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Templates//320/236/321/201/320/275/320/276/320/262/320/275/320/260/321/217/320/241/321/205/320/265/320/274/320/260/320/232/320/276/320/274/320/277/320/276/320/275/320/276/320/262/320/272/320/270/320/224/320/260/320/275/320/275/321/213/321/205.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262.xml" +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/assets/__init__.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/bridge.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/credentials.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/os_support.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/platform.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/protocol.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/rag/__init__.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/rag/detect.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/rag/model.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/rag/parsers.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/rag/service.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/rag/store.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/recorder.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/release_helper.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/runtime.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/skill_installer.py +0 -0
- {answer42-0.2.6 → answer42-0.2.8}/src/mcp_1c/window_control.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: answer42
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Answer42 — The Answer to Life, Universe, and 1C — UI Driver. MCP-powered 1C:Enterprise UI automation: click, fill, navigate, test, and introspect managed forms through the test-client API
|
|
5
5
|
Author: Marvin (AI Assistant), 42Clouds, and contributors
|
|
6
6
|
Author-email: "Kosolapov Stanislav (proDOOMman)" <prodoomman@gmail.com>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "answer42"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.8"
|
|
4
4
|
description = "Answer42 — The Answer to Life, Universe, and 1C — UI Driver. MCP-powered 1C:Enterprise UI automation: click, fill, navigate, test, and introspect managed forms through the test-client API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -27,8 +27,7 @@ NAV = [
|
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
CSS = """
|
|
30
|
-
:root { color-scheme:
|
|
31
|
-
@media (prefers-color-scheme: light) { :root { --bg:#f7f9ff; --panel:#ffffff; --text:#111827; --muted:#526078; --link:#0369a1; --line:#dbe3f5; --code:#f1f5f9; } }
|
|
30
|
+
:root { color-scheme: dark; --bg:#0b1020; --panel:#111936; --text:#eef3ff; --muted:#aebbe2; --link:#67e8f9; --line:#2b365f; --code:#080d1c; }
|
|
32
31
|
* { box-sizing: border-box; }
|
|
33
32
|
body { margin:0; font:16px/1.62 Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color:var(--text); background:radial-gradient(circle at 20% 0%, rgba(103,232,249,.18), transparent 28rem), var(--bg); }
|
|
34
33
|
.wrapper { max-width: 1120px; margin: 0 auto; padding: 28px 20px 56px; }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""MCP server for 1C:Enterprise test manager automation."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import tomllib
|
|
6
|
+
|
|
7
|
+
__all__ = ["__version__"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _version_from_pyproject() -> str:
|
|
11
|
+
pyproject = Path(__file__).resolve().parents[2] / "pyproject.toml"
|
|
12
|
+
try:
|
|
13
|
+
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
|
|
14
|
+
return str(data.get("project", {}).get("version") or "0+unknown")
|
|
15
|
+
except Exception:
|
|
16
|
+
return "0+unknown"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
__version__ = version("answer42")
|
|
21
|
+
except PackageNotFoundError:
|
|
22
|
+
__version__ = _version_from_pyproject()
|
|
@@ -25,6 +25,7 @@ from typing import Annotated, Any
|
|
|
25
25
|
|
|
26
26
|
from mcp.server.fastmcp import FastMCP
|
|
27
27
|
|
|
28
|
+
from . import __version__
|
|
28
29
|
from . import os_support
|
|
29
30
|
from . import platform as _platform
|
|
30
31
|
from . import runtime
|
|
@@ -2251,10 +2252,37 @@ def _client_failure_diagnostics(sess: SessionState, error: Exception, target_con
|
|
|
2251
2252
|
return RuntimeError(message)
|
|
2252
2253
|
|
|
2253
2254
|
|
|
2255
|
+
def _test_client_startup_error_from_logs(sess: SessionState) -> str:
|
|
2256
|
+
"""Return a meaningful early startup error from test-client logs, if any."""
|
|
2257
|
+
fragments: list[str] = []
|
|
2258
|
+
for path in (sess.client_log_dir / "test_client_1c_out.log", sess.client_log_dir / "test_client_stdout.log"):
|
|
2259
|
+
tail = _tail_text_file(path, max_lines=120, max_chars=30000)
|
|
2260
|
+
if tail:
|
|
2261
|
+
fragments.append(tail)
|
|
2262
|
+
if not fragments:
|
|
2263
|
+
return ""
|
|
2264
|
+
|
|
2265
|
+
text = "\n".join(fragments)
|
|
2266
|
+
auth_lines = [line for line in text.splitlines() if _looks_like_auth_failure(line)]
|
|
2267
|
+
if auth_lines:
|
|
2268
|
+
return "\n".join(auth_lines[-20:])
|
|
2269
|
+
|
|
2270
|
+
meaningful = _extract_error_lines(text, max_lines=20)
|
|
2271
|
+
if meaningful and any(marker in meaningful.lower() for marker in _EVENTLOG_ERROR_MARKERS):
|
|
2272
|
+
return meaningful
|
|
2273
|
+
return ""
|
|
2274
|
+
|
|
2275
|
+
|
|
2254
2276
|
async def _wait_for_test_client_ready(sess: SessionState, host: str, port: int, timeout: float) -> None:
|
|
2255
2277
|
deadline = time.time() + timeout
|
|
2256
2278
|
proc = sess.test_client_process
|
|
2257
2279
|
while time.time() < deadline:
|
|
2280
|
+
startup_error = _test_client_startup_error_from_logs(sess)
|
|
2281
|
+
if startup_error:
|
|
2282
|
+
message = f"Test client startup error before opening test port {host}:{port}:\n{startup_error}"
|
|
2283
|
+
message = _append_file_tail(message, "Лог stdout/stderr клиента тестирования", sess.client_log_dir / "test_client_stdout.log")
|
|
2284
|
+
message = _append_file_tail(message, "Лог 1С /Out клиента тестирования", sess.client_log_dir / "test_client_1c_out.log")
|
|
2285
|
+
raise RuntimeError(message)
|
|
2258
2286
|
if proc is not None and proc.poll() is not None:
|
|
2259
2287
|
message = f"Test client process exited before opening test port {host}:{port}; exit_code={proc.returncode}"
|
|
2260
2288
|
message = _append_file_tail(message, "Лог stdout/stderr клиента тестирования", sess.client_log_dir / "test_client_stdout.log")
|
|
@@ -4036,15 +4064,17 @@ async def _run() -> None:
|
|
|
4036
4064
|
_SESSIONS.clear()
|
|
4037
4065
|
|
|
4038
4066
|
|
|
4039
|
-
def main() -> None:
|
|
4067
|
+
def main(argv: list[str] | None = None) -> None:
|
|
4040
4068
|
global _RAG_ENABLED
|
|
4041
4069
|
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4070
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
4071
|
+
if argv and argv[0] in {"install-skills", "skills-install"}:
|
|
4072
|
+
raise SystemExit(skill_installer.main(argv[1:]))
|
|
4073
|
+
if argv and argv[0] in {"release", "release-pypi"}:
|
|
4074
|
+
raise SystemExit(release_helper.main(argv[1:]))
|
|
4046
4075
|
|
|
4047
4076
|
parser = argparse.ArgumentParser(description="MCP server for 1C:Enterprise test manager")
|
|
4077
|
+
parser.add_argument("--version", action="version", version=f"answer42 {__version__}")
|
|
4048
4078
|
parser.add_argument("--log-level", default=os.getenv("ONEC_MCP_LOG_LEVEL", "INFO"))
|
|
4049
4079
|
parser.add_argument(
|
|
4050
4080
|
"--disable-rag",
|
|
@@ -4087,7 +4117,7 @@ def main() -> None:
|
|
|
4087
4117
|
default=float(os.getenv("ONEC_MCP_DEV_RESTART_TIMEOUT", "30")),
|
|
4088
4118
|
help="seconds of no file changes before the OpenClaw MCP autoreload watchdog triggers reload",
|
|
4089
4119
|
)
|
|
4090
|
-
args = parser.parse_args()
|
|
4120
|
+
args = parser.parse_args(argv)
|
|
4091
4121
|
|
|
4092
4122
|
_RAG_ENABLED = not args.disable_rag
|
|
4093
4123
|
logging.basicConfig(level=getattr(logging, args.log_level.upper(), logging.INFO))
|
|
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
|
|
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
|
|
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
|