answer42 0.2.8__tar.gz → 0.2.10__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.
Files changed (58) hide show
  1. {answer42-0.2.8 → answer42-0.2.10}/PKG-INFO +1 -1
  2. {answer42-0.2.8 → answer42-0.2.10}/pyproject.toml +1 -1
  3. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
  4. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
  5. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/server.py +34 -4
  6. {answer42-0.2.8 → answer42-0.2.10}/.gitignore +0 -0
  7. {answer42-0.2.8 → answer42-0.2.10}/LICENSE +0 -0
  8. {answer42-0.2.8 → answer42-0.2.10}/README.md +0 -0
  9. {answer42-0.2.8 → answer42-0.2.10}/credentials.example.json +0 -0
  10. {answer42-0.2.8 → answer42-0.2.10}/docs/agent-installation.md +0 -0
  11. {answer42-0.2.8 → answer42-0.2.10}/docs/architecture.md +0 -0
  12. {answer42-0.2.8 → answer42-0.2.10}/docs/assets/answer42-logo.png +0 -0
  13. {answer42-0.2.8 → answer42-0.2.10}/docs/assets/platform42-logo.svg +0 -0
  14. {answer42-0.2.8 → answer42-0.2.10}/docs/installation.md +0 -0
  15. {answer42-0.2.8 → answer42-0.2.10}/scripts/build_cf.py +0 -0
  16. {answer42-0.2.8 → answer42-0.2.10}/scripts/build_pages.py +0 -0
  17. {answer42-0.2.8 → answer42-0.2.10}/scripts/e2e_stable.py +0 -0
  18. {answer42-0.2.8 → answer42-0.2.10}/scripts/openclaw_mcp_autoreload.py +0 -0
  19. {answer42-0.2.8 → answer42-0.2.10}/scripts/rag_cli.py +0 -0
  20. {answer42-0.2.8 → answer42-0.2.10}/src/cf/ConfigDumpInfo.xml +0 -0
  21. {answer42-0.2.8 → answer42-0.2.10}/src/cf/Configuration.xml +0 -0
  22. {answer42-0.2.8 → answer42-0.2.10}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
  23. {answer42-0.2.8 → answer42-0.2.10}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl" +0 -0
  24. {answer42-0.2.8 → answer42-0.2.10}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
  25. {answer42-0.2.8 → answer42-0.2.10}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
  26. {answer42-0.2.8 → answer42-0.2.10}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
  27. {answer42-0.2.8 → answer42-0.2.10}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
  28. {answer42-0.2.8 → answer42-0.2.10}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
  29. {answer42-0.2.8 → answer42-0.2.10}/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
  30. {answer42-0.2.8 → answer42-0.2.10}/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
  31. {answer42-0.2.8 → answer42-0.2.10}/src/client_cf/ConfigDumpInfo.xml +0 -0
  32. {answer42-0.2.8 → answer42-0.2.10}/src/client_cf/Configuration.xml +0 -0
  33. {answer42-0.2.8 → answer42-0.2.10}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
  34. {answer42-0.2.8 → answer42-0.2.10}/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
  35. {answer42-0.2.8 → answer42-0.2.10}/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
  36. {answer42-0.2.8 → answer42-0.2.10}/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
  37. {answer42-0.2.8 → answer42-0.2.10}/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
  38. {answer42-0.2.8 → answer42-0.2.10}/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
  39. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/__init__.py +0 -0
  40. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/assets/__init__.py +0 -0
  41. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
  42. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
  43. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/bridge.py +0 -0
  44. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/credentials.py +0 -0
  45. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/os_support.py +0 -0
  46. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/platform.py +0 -0
  47. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/protocol.py +0 -0
  48. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/rag/__init__.py +0 -0
  49. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/rag/detect.py +0 -0
  50. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/rag/model.py +0 -0
  51. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/rag/parsers.py +0 -0
  52. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/rag/service.py +0 -0
  53. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/rag/store.py +0 -0
  54. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/recorder.py +0 -0
  55. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/release_helper.py +0 -0
  56. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/runtime.py +0 -0
  57. {answer42-0.2.8 → answer42-0.2.10}/src/mcp_1c/skill_installer.py +0 -0
  58. {answer42-0.2.8 → answer42-0.2.10}/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.8
3
+ Version: 0.2.10
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.8"
3
+ version = "0.2.10"
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 = _credentials_store().lookup(r_base)
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 = _credentials_store().lookup(r_base)
2421
+ credentials = _lookup_credentials(r_base)
2403
2422
  if credentials:
2404
2423
  r_user = credentials["username"]
2405
2424
  r_pass = credentials["password"]
@@ -4029,7 +4048,11 @@ def screenshot(
4029
4048
  else:
4030
4049
  os.environ["DISPLAY"] = previous_display
4031
4050
  except ImportError as exc:
4032
- raise RuntimeError("Install screenshot extra: pip install '.[screenshot]' or mss") from exc
4051
+ raise RuntimeError(
4052
+ "Screenshot support requires the optional dependency 'mss'. "
4053
+ "Install it with: pip install 'answer42[screenshot]' "
4054
+ "or, for pipx installs: pipx inject answer42 mss."
4055
+ ) from exc
4033
4056
 
4034
4057
  data = output_path.read_bytes()
4035
4058
  result = {"path": str(output_path), "bytes": len(data), "base64": base64.b64encode(data).decode("ascii")}
@@ -4065,7 +4088,7 @@ async def _run() -> None:
4065
4088
 
4066
4089
 
4067
4090
  def main(argv: list[str] | None = None) -> None:
4068
- global _RAG_ENABLED
4091
+ global _RAG_ENABLED, _CREDENTIAL_STORE_ENABLED
4069
4092
 
4070
4093
  argv = list(sys.argv[1:] if argv is None else argv)
4071
4094
  if argv and argv[0] in {"install-skills", "skills-install"}:
@@ -4082,6 +4105,12 @@ def main(argv: list[str] | None = None) -> None:
4082
4105
  default=os.getenv("ONEC_MCP_DISABLE_RAG", "").strip().lower() in {"1", "true", "yes", "on"},
4083
4106
  help="disable built-in Answer42 RAG tools and RAG enrichment",
4084
4107
  )
4108
+ parser.add_argument(
4109
+ "--disable-credential-store",
4110
+ action="store_true",
4111
+ default=os.getenv("ONEC_MCP_DISABLE_CREDENTIAL_STORE", "").strip().lower() in {"1", "true", "yes", "on"},
4112
+ help="disable loading, saving and automatic lookup of credentials from the local credential store",
4113
+ )
4085
4114
  parser.add_argument(
4086
4115
  "--rag-source-dir",
4087
4116
  action="append",
@@ -4120,6 +4149,7 @@ def main(argv: list[str] | None = None) -> None:
4120
4149
  args = parser.parse_args(argv)
4121
4150
 
4122
4151
  _RAG_ENABLED = not args.disable_rag
4152
+ _CREDENTIAL_STORE_ENABLED = not args.disable_credential_store
4123
4153
  logging.basicConfig(level=getattr(logging, args.log_level.upper(), logging.INFO))
4124
4154
  if _RAG_ENABLED:
4125
4155
  _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