answer42 0.2.8__tar.gz → 0.2.9__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.8 → answer42-0.2.9}/PKG-INFO +1 -1
- {answer42-0.2.8 → answer42-0.2.9}/pyproject.toml +1 -1
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/server.py +29 -3
- {answer42-0.2.8 → answer42-0.2.9}/.gitignore +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/LICENSE +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/README.md +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/credentials.example.json +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/docs/agent-installation.md +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/docs/architecture.md +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/docs/assets/answer42-logo.png +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/docs/assets/platform42-logo.svg +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/docs/installation.md +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/scripts/build_cf.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/scripts/build_pages.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/scripts/e2e_stable.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/scripts/openclaw_mcp_autoreload.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/scripts/rag_cli.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/Configuration.xml +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl" +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/src/client_cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/client_cf/Configuration.xml +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/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.8 → answer42-0.2.9}/src/mcp_1c/__init__.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/assets/__init__.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/bridge.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/credentials.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/os_support.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/platform.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/protocol.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/rag/__init__.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/rag/detect.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/rag/model.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/rag/parsers.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/rag/service.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/rag/store.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/recorder.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/release_helper.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/runtime.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/src/mcp_1c/skill_installer.py +0 -0
- {answer42-0.2.8 → answer42-0.2.9}/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.9
|
|
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.9"
|
|
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"
|
|
@@ -41,6 +41,7 @@ from .recorder import RecordingSession
|
|
|
41
41
|
mcp = FastMCP("Answer42")
|
|
42
42
|
_RAG = RagService()
|
|
43
43
|
_RAG_ENABLED = os.getenv("ONEC_MCP_DISABLE_RAG", "").strip().lower() not in {"1", "true", "yes", "on"}
|
|
44
|
+
_CREDENTIAL_STORE_ENABLED = os.getenv("ONEC_MCP_DISABLE_CREDENTIAL_STORE", "").strip().lower() not in {"1", "true", "yes", "on"}
|
|
44
45
|
DEFAULT_SESSION = "default"
|
|
45
46
|
STATE_FILE = os_support.runtime_path("ONEC_MCP_SESSION_STATE", "sessions.json")
|
|
46
47
|
AUTORELOAD_PID_FILE = os_support.runtime_path("ONEC_MCP_AUTORELOAD_PID_FILE", "answer42-autoreload.pid")
|
|
@@ -2024,9 +2025,21 @@ def export_eventlog(
|
|
|
2024
2025
|
return {"path": str(exported), "format": fmt, "eventlog_dir": str(eventlog_path)}
|
|
2025
2026
|
|
|
2026
2027
|
|
|
2028
|
+
def _credential_store_disabled_error() -> RuntimeError:
|
|
2029
|
+
return RuntimeError("Credential store is disabled by --disable-credential-store or ONEC_MCP_DISABLE_CREDENTIAL_STORE.")
|
|
2030
|
+
|
|
2031
|
+
|
|
2032
|
+
def _lookup_credentials(base_url: str) -> dict[str, str] | None:
|
|
2033
|
+
if not _CREDENTIAL_STORE_ENABLED:
|
|
2034
|
+
return None
|
|
2035
|
+
return _credentials_store().lookup(base_url)
|
|
2036
|
+
|
|
2037
|
+
|
|
2027
2038
|
@mcp.tool()
|
|
2028
2039
|
def credentials_check(base_url: str) -> dict[str, object]:
|
|
2029
2040
|
"""Check whether credentials exist for a base URL without returning secrets."""
|
|
2041
|
+
if not _CREDENTIAL_STORE_ENABLED:
|
|
2042
|
+
return {"base_url": base_url, "found": False, "disabled": True}
|
|
2030
2043
|
credentials = _credentials_store().lookup(base_url)
|
|
2031
2044
|
if credentials is None:
|
|
2032
2045
|
return {"base_url": base_url, "found": False}
|
|
@@ -2048,6 +2061,8 @@ def credentials_save(
|
|
|
2048
2061
|
login/password pairs so that ``start_session`` can pick them up automatically
|
|
2049
2062
|
without exposing secrets in MCP tool-call arguments.
|
|
2050
2063
|
"""
|
|
2064
|
+
if not _CREDENTIAL_STORE_ENABLED:
|
|
2065
|
+
raise _credential_store_disabled_error()
|
|
2051
2066
|
updated = _credentials_store().upsert(url, username, password)
|
|
2052
2067
|
return {
|
|
2053
2068
|
"url": url,
|
|
@@ -2061,6 +2076,8 @@ def credentials_remove(
|
|
|
2061
2076
|
url: Annotated[str, "Exact URL pattern to remove from the credentials store"],
|
|
2062
2077
|
) -> dict[str, object]:
|
|
2063
2078
|
"""Remove a credential entry from the local store by exact URL match."""
|
|
2079
|
+
if not _CREDENTIAL_STORE_ENABLED:
|
|
2080
|
+
raise _credential_store_disabled_error()
|
|
2064
2081
|
removed = _credentials_store().remove(url)
|
|
2065
2082
|
return {"url": url, "removed": removed}
|
|
2066
2083
|
|
|
@@ -2068,6 +2085,8 @@ def credentials_remove(
|
|
|
2068
2085
|
@mcp.tool()
|
|
2069
2086
|
def credentials_list() -> list[dict[str, str]]:
|
|
2070
2087
|
"""List configured credential URL patterns (no usernames or passwords)."""
|
|
2088
|
+
if not _CREDENTIAL_STORE_ENABLED:
|
|
2089
|
+
return []
|
|
2071
2090
|
return _credentials_store().list_entries()
|
|
2072
2091
|
|
|
2073
2092
|
|
|
@@ -2333,7 +2352,7 @@ async def _connect_test_client_impl(
|
|
|
2333
2352
|
raise ValueError("base_url or connection_value is required")
|
|
2334
2353
|
r_base = r_value
|
|
2335
2354
|
if not r_user and not r_pass:
|
|
2336
|
-
credentials =
|
|
2355
|
+
credentials = _lookup_credentials(r_base)
|
|
2337
2356
|
if credentials:
|
|
2338
2357
|
r_user = credentials["username"]
|
|
2339
2358
|
r_pass = credentials["password"]
|
|
@@ -2399,7 +2418,7 @@ async def _connect_test_client_impl(
|
|
|
2399
2418
|
target_connection_mode = mode
|
|
2400
2419
|
|
|
2401
2420
|
if not r_user and not r_pass and r_base:
|
|
2402
|
-
credentials =
|
|
2421
|
+
credentials = _lookup_credentials(r_base)
|
|
2403
2422
|
if credentials:
|
|
2404
2423
|
r_user = credentials["username"]
|
|
2405
2424
|
r_pass = credentials["password"]
|
|
@@ -4065,7 +4084,7 @@ async def _run() -> None:
|
|
|
4065
4084
|
|
|
4066
4085
|
|
|
4067
4086
|
def main(argv: list[str] | None = None) -> None:
|
|
4068
|
-
global _RAG_ENABLED
|
|
4087
|
+
global _RAG_ENABLED, _CREDENTIAL_STORE_ENABLED
|
|
4069
4088
|
|
|
4070
4089
|
argv = list(sys.argv[1:] if argv is None else argv)
|
|
4071
4090
|
if argv and argv[0] in {"install-skills", "skills-install"}:
|
|
@@ -4082,6 +4101,12 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
4082
4101
|
default=os.getenv("ONEC_MCP_DISABLE_RAG", "").strip().lower() in {"1", "true", "yes", "on"},
|
|
4083
4102
|
help="disable built-in Answer42 RAG tools and RAG enrichment",
|
|
4084
4103
|
)
|
|
4104
|
+
parser.add_argument(
|
|
4105
|
+
"--disable-credential-store",
|
|
4106
|
+
action="store_true",
|
|
4107
|
+
default=os.getenv("ONEC_MCP_DISABLE_CREDENTIAL_STORE", "").strip().lower() in {"1", "true", "yes", "on"},
|
|
4108
|
+
help="disable loading, saving and automatic lookup of credentials from the local credential store",
|
|
4109
|
+
)
|
|
4085
4110
|
parser.add_argument(
|
|
4086
4111
|
"--rag-source-dir",
|
|
4087
4112
|
action="append",
|
|
@@ -4120,6 +4145,7 @@ def main(argv: list[str] | None = None) -> None:
|
|
|
4120
4145
|
args = parser.parse_args(argv)
|
|
4121
4146
|
|
|
4122
4147
|
_RAG_ENABLED = not args.disable_rag
|
|
4148
|
+
_CREDENTIAL_STORE_ENABLED = not args.disable_credential_store
|
|
4123
4149
|
logging.basicConfig(level=getattr(logging, args.log_level.upper(), logging.INFO))
|
|
4124
4150
|
if _RAG_ENABLED:
|
|
4125
4151
|
_register_startup_rag_source_dirs(args.rag_source_dir or [], args.rag_source_prefix, not args.rag_source_no_recursive, args.rag_source_max_depth)
|
|
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
|
|
File without changes
|
|
File without changes
|