intuned-runtime 1.3.3__tar.gz → 1.3.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.
Files changed (121) hide show
  1. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/PKG-INFO +2 -1
  2. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/attempt_api_command.py +3 -0
  3. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/attempt_authsession_check_command.py +3 -0
  4. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/attempt_authsession_create_command.py +3 -0
  5. intuned_runtime-1.3.8/intuned_cli/commands/authsession_record_command.py +59 -0
  6. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/run_api_command.py +3 -0
  7. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/run_authsession_create_command.py +4 -0
  8. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/run_authsession_update_command.py +3 -0
  9. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/run_authsession_validate_command.py +3 -0
  10. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/__test__/test_api.py +1 -0
  11. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/__test__/test_authsession.py +2 -0
  12. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/api.py +2 -0
  13. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/authsession.py +4 -0
  14. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/save.py +2 -2
  15. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/types.py +1 -0
  16. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/__test__/test_browser.py +12 -0
  17. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/browser.py +6 -0
  18. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/wrapper.py +2 -1
  19. intuned_runtime-1.3.8/intuned_runtime/captcha/__init__.py +6 -0
  20. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/pyproject.toml +2 -1
  21. intuned_runtime-1.3.8/runtime/browser/extensions/__init__.py +7 -0
  22. intuned_runtime-1.3.8/runtime/browser/extensions/intuned_extension.py +261 -0
  23. intuned_runtime-1.3.8/runtime/browser/extensions/intuned_extension_server.py +208 -0
  24. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/launch_chromium.py +22 -5
  25. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/env.py +4 -0
  26. intuned_runtime-1.3.8/runtime/helpers/__init__.py +17 -0
  27. intuned_runtime-1.3.8/runtime/helpers/extensions.py +428 -0
  28. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/types/settings_types.py +37 -4
  29. intuned_runtime-1.3.3/intuned_cli/commands/authsession_record_command.py +0 -52
  30. intuned_runtime-1.3.3/runtime/browser/extensions/__init__.py +0 -3
  31. intuned_runtime-1.3.3/runtime/browser/extensions/intuned_extension.py +0 -87
  32. intuned_runtime-1.3.3/runtime/helpers/__init__.py +0 -6
  33. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/LICENSE +0 -0
  34. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/README.md +0 -0
  35. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/__init__.py +0 -0
  36. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/__init__.py +0 -0
  37. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/attempt_authsession_command.py +0 -0
  38. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/attempt_command.py +0 -0
  39. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/authsession_command.py +0 -0
  40. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/command.py +0 -0
  41. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/deploy_command.py +0 -0
  42. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/init_command.py +0 -0
  43. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/run_authsession_command.py +0 -0
  44. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/run_command.py +0 -0
  45. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/commands/save_command.py +0 -0
  46. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/__test__/__init__.py +0 -0
  47. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/controller/deploy.py +0 -0
  48. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/__test__/test_traces.py +0 -0
  49. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/api_helpers.py +0 -0
  50. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/auth_session_helpers.py +0 -0
  51. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/backend.py +0 -0
  52. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/confirmation.py +0 -0
  53. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/console.py +0 -0
  54. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/error.py +0 -0
  55. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/exclusions.py +0 -0
  56. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/get_auth_parameters.py +0 -0
  57. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/help.py +0 -0
  58. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/import_function.py +0 -0
  59. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/timeout.py +0 -0
  60. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_cli/utils/traces.py +0 -0
  61. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/__init__.py +0 -0
  62. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/__init__.py +0 -0
  63. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/browser/__init__.py +0 -0
  64. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/browser/save_state.py +0 -0
  65. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/__init__.py +0 -0
  66. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/auth_session/__init__.py +0 -0
  67. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/auth_session/check.py +0 -0
  68. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/auth_session/create.py +0 -0
  69. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/auth_session/load.py +0 -0
  70. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/project.py +0 -0
  71. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/run.py +0 -0
  72. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/run_interface.py +0 -0
  73. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/project/type_check.py +0 -0
  74. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/commands/root.py +0 -0
  75. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/logger.py +0 -0
  76. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/utils/ai_source_project.py +0 -0
  77. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/utils/code_tree.py +0 -0
  78. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/utils/run_apis.py +0 -0
  79. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/utils/setup_ide_functions_token.py +0 -0
  80. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/utils/unix_socket.py +0 -0
  81. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_internal_cli/utils/wrapper.py +0 -0
  82. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/intuned_runtime/__init__.py +0 -0
  83. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/__init__.py +0 -0
  84. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/backend_functions/__init__.py +0 -0
  85. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/backend_functions/_call_backend_function.py +0 -0
  86. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/backend_functions/get_auth_session_parameters.py +0 -0
  87. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/__init__.py +0 -0
  88. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/extensions/helpers.py +0 -0
  89. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/helpers.py +0 -0
  90. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/launch_browser.py +0 -0
  91. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/launch_camoufox.py +0 -0
  92. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/browser/storage_state.py +0 -0
  93. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/constants.py +0 -0
  94. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/context/__init__.py +0 -0
  95. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/context/context.py +0 -0
  96. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/errors/__init__.py +0 -0
  97. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/errors/auth_session_errors.py +0 -0
  98. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/errors/run_api_errors.py +0 -0
  99. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/errors/trace_errors.py +0 -0
  100. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/helpers/attempt_store.py +0 -0
  101. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/helpers/extend_payload.py +0 -0
  102. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/helpers/extend_timeout.py +0 -0
  103. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/helpers/get_auth_session_parameters.py +0 -0
  104. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/py.typed +0 -0
  105. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/__init__.py +0 -0
  106. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/intuned_settings.py +0 -0
  107. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/playwright_context.py +0 -0
  108. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/playwright_tracing.py +0 -0
  109. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/pydantic_encoder.py +0 -0
  110. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/run_api.py +0 -0
  111. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/setup_context_hook.py +0 -0
  112. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/traces.py +0 -0
  113. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/run/types.py +0 -0
  114. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/types/__init__.py +0 -0
  115. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/types/payload.py +0 -0
  116. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/types/run_types.py +0 -0
  117. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/utils/__init__.py +0 -0
  118. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/utils/anyio.py +0 -0
  119. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime/utils/config_loader.py +0 -0
  120. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime_helpers/__init__.py +0 -0
  121. {intuned_runtime-1.3.3 → intuned_runtime-1.3.8}/runtime_helpers/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: intuned-runtime
3
- Version: 1.3.3
3
+ Version: 1.3.8
4
4
  Summary: Runtime SDK that powers browser automation projects running on Intuned
5
5
  License: Elastic-2.0
6
6
  License-File: LICENSE
@@ -27,6 +27,7 @@ Requires-Dist: jsonc-parser (>=1.1.5,<2.0.0)
27
27
  Requires-Dist: more-termcolor (>=1.1.3,<2.0.0)
28
28
  Requires-Dist: pathspec (>=0.12.1,<0.13.0)
29
29
  Requires-Dist: pydantic (>=2.10.6,<3.0.0)
30
+ Requires-Dist: pyee (>=11.1.0)
30
31
  Requires-Dist: pyright (>=1.1.387,<2.0.0)
31
32
  Requires-Dist: python-dotenv (==1.0.1)
32
33
  Requires-Dist: pytimeparse (>=1.1.8,<2.0.0)
@@ -19,6 +19,7 @@ async def attempt__api(
19
19
  output_file: str | None = None,
20
20
  trace: bool = False,
21
21
  keep_browser_open: bool = False,
22
+ cdp_url: str | None = None,
22
23
  ):
23
24
  """Executes an Intuned API attempt with parameters
24
25
 
@@ -32,6 +33,7 @@ async def attempt__api(
32
33
  output_file (str | None, optional): [-o/--output-file]. Output file path. Defaults to None.
33
34
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
34
35
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
36
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
35
37
  """
36
38
 
37
39
  await assert_auth_consistent(auth_session)
@@ -54,4 +56,5 @@ async def attempt__api(
54
56
  output_file=output_file,
55
57
  trace=trace,
56
58
  keep_browser_open=keep_browser_open,
59
+ cdp_url=cdp_url,
57
60
  )
@@ -15,6 +15,7 @@ async def attempt__authsession__check(
15
15
  headless: bool = False,
16
16
  trace: bool = False,
17
17
  keep_browser_open: bool = False,
18
+ cdp_url: str | None = None,
18
19
  ):
19
20
  """Check an existing auth session
20
21
 
@@ -25,6 +26,7 @@ async def attempt__authsession__check(
25
26
  headless (bool, optional): [--headless]. Run the API in headless mode (default: False). This will not open a browser window.
26
27
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
27
28
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
29
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
28
30
  """
29
31
  await assert_auth_enabled()
30
32
 
@@ -41,4 +43,5 @@ async def attempt__authsession__check(
41
43
  proxy=proxy,
42
44
  trace=trace,
43
45
  keep_browser_open=keep_browser_open,
46
+ cdp_url=cdp_url,
44
47
  )
@@ -17,6 +17,7 @@ async def attempt__authsession__create(
17
17
  headless: bool = False,
18
18
  trace: bool = False,
19
19
  keep_browser_open: bool = False,
20
+ cdp_url: str | None = None,
20
21
  ):
21
22
  """Create a new auth session
22
23
 
@@ -28,6 +29,7 @@ async def attempt__authsession__create(
28
29
  headless (bool, optional): [--headless]. Run the API in headless mode (default: False). This will not open a browser window.
29
30
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
30
31
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
32
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
31
33
  """
32
34
  await assert_auth_enabled(auth_type="API")
33
35
 
@@ -47,4 +49,5 @@ async def attempt__authsession__create(
47
49
  proxy=proxy,
48
50
  trace=trace,
49
51
  keep_browser_open=keep_browser_open,
52
+ cdp_url=cdp_url,
50
53
  )
@@ -0,0 +1,59 @@
1
+ import pytimeparse # type: ignore
2
+
3
+ from intuned_cli.controller.authsession import execute_record_auth_session_cli
4
+ from intuned_cli.utils.auth_session_helpers import assert_auth_enabled
5
+ from intuned_cli.utils.auth_session_helpers import get_auth_session_recorder_parameters
6
+ from intuned_cli.utils.wrapper import cli_command
7
+ from runtime.env import get_is_auth_session_recorder_enabled
8
+
9
+ if get_is_auth_session_recorder_enabled():
10
+
11
+ @cli_command
12
+ async def authsession__record(
13
+ *,
14
+ id: str | None = None,
15
+ check_attempts: int = 1,
16
+ proxy: str | None = None,
17
+ timeout: str = "10 min",
18
+ headless: bool = False,
19
+ trace: bool = False,
20
+ keep_browser_open: bool = False,
21
+ cdp_url: str | None = None,
22
+ ):
23
+ """Record a recorder-based auth session and then execute an AuthSession:Validate run to validate it
24
+
25
+ Args:
26
+ id (str | None, optional): ID of the auth session to record. If not provided, a new ID will be generated.
27
+ check_attempts (int, optional): [--check-attempts]. Number of attempts to check the auth session validity after it is created. Defaults to 1.
28
+ proxy (str | None, optional): [--proxy]. Proxy URL to use for recorder session and validation. Defaults to None.
29
+ timeout (str, optional): [--timeout]. Timeout for the auth session command - seconds or pytimeparse-formatted string. Defaults to "10 min".
30
+ headless (bool, optional): [--headless]. Run the auth session validation in headless mode (default: False). This will not open a browser window. The recorder will always be non-headless.
31
+ trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
32
+ keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
33
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
34
+ """
35
+
36
+ await assert_auth_enabled(auth_type="MANUAL")
37
+
38
+ timeout_value = pytimeparse.parse(timeout) # type: ignore
39
+ if timeout_value is None:
40
+ raise ValueError(
41
+ f"Invalid timeout format: {timeout}. Please use a valid time format like '10 min' or '600 seconds'."
42
+ )
43
+
44
+ start_url, finish_url = await get_auth_session_recorder_parameters()
45
+
46
+ await execute_record_auth_session_cli(
47
+ start_url=start_url,
48
+ finish_url=finish_url,
49
+ id=id,
50
+ check_retries=check_attempts,
51
+ headless=headless,
52
+ proxy=proxy,
53
+ timeout=timeout_value,
54
+ trace=trace,
55
+ keep_browser_open=keep_browser_open,
56
+ cdp_url=cdp_url,
57
+ )
58
+ else:
59
+ authsession__record = None # type: ignore
@@ -24,6 +24,7 @@ async def run__api(
24
24
  output_file: str | None = None,
25
25
  trace: bool = False,
26
26
  keep_browser_open: bool = False,
27
+ cdp_url: str | None = None,
27
28
  ):
28
29
  """Execute an API run with parameters
29
30
 
@@ -41,6 +42,7 @@ async def run__api(
41
42
  output_file (str | None, optional): [-o/--output-file]. Output file path. Defaults to None.
42
43
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
43
44
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
45
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
44
46
  """
45
47
  auth_session_auto_recreate = not no_auth_session_auto_recreate
46
48
 
@@ -72,4 +74,5 @@ async def run__api(
72
74
  output_file=output_file,
73
75
  trace=trace,
74
76
  keep_browser_open=keep_browser_open,
77
+ cdp_url=cdp_url,
75
78
  )
@@ -21,6 +21,7 @@ async def _run_auth_session_create_impl(
21
21
  headless: bool = False,
22
22
  trace: bool = False,
23
23
  keep_browser_open: bool = False,
24
+ cdp_url: str | None = None,
24
25
  ):
25
26
  """Execute an AuthSession:Create run to create an auth session
26
27
 
@@ -34,6 +35,8 @@ async def _run_auth_session_create_impl(
34
35
  headless (bool, optional): [--headless]. Run the API in headless mode (default: False). This will not open a browser window.
35
36
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
36
37
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
38
+
39
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
37
40
  """
38
41
 
39
42
  await assert_auth_enabled(auth_type="API")
@@ -56,6 +59,7 @@ async def _run_auth_session_create_impl(
56
59
  timeout=timeout_value,
57
60
  trace=trace,
58
61
  keep_browser_open=keep_browser_open,
62
+ cdp_url=cdp_url,
59
63
  )
60
64
 
61
65
 
@@ -21,6 +21,7 @@ async def _run_update_authsession_impl(
21
21
  headless: bool = False,
22
22
  trace: bool = False,
23
23
  keep_browser_open: bool = False,
24
+ cdp_url: str | None = None,
24
25
  ):
25
26
  """Execute an AuthSession:Update run to update an existing auth session
26
27
 
@@ -34,6 +35,7 @@ async def _run_update_authsession_impl(
34
35
  headless (bool, optional): [--headless]. Run the API in headless mode (default: False). This will not open a browser window.
35
36
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
36
37
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
38
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
37
39
  """
38
40
  await assert_auth_enabled(auth_type="API")
39
41
 
@@ -57,6 +59,7 @@ async def _run_update_authsession_impl(
57
59
  timeout=timeout_value,
58
60
  trace=trace,
59
61
  keep_browser_open=keep_browser_open,
62
+ cdp_url=cdp_url,
60
63
  )
61
64
 
62
65
 
@@ -20,6 +20,7 @@ async def _run_validate_authsession_impl(
20
20
  headless: bool = False,
21
21
  trace: bool = False,
22
22
  keep_browser_open: bool = False,
23
+ cdp_url: str | None = None,
23
24
  ):
24
25
  """Execute an AuthSession:Validate run to validate an auth session
25
26
 
@@ -33,6 +34,7 @@ async def _run_validate_authsession_impl(
33
34
  headless (bool, optional): [--headless]. Run the API in headless mode (default: False). This will not open a browser window.
34
35
  trace (bool, optional): [--trace]. Capture a trace of each attempt, useful for debugging. Defaults to False.
35
36
  keep_browser_open (bool, optional): [--keep-browser-open]. Keep the last browser open after execution for debugging. Defaults to False.
37
+ cdp_url (str | None, optional): [--cdp-url]. [Experimental] Chrome DevTools Protocol URL to connect to an existing browser instance. Disables proxy, headless, keep_browser_open options. Defaults to None.
36
38
  """
37
39
  await assert_auth_enabled()
38
40
 
@@ -54,6 +56,7 @@ async def _run_validate_authsession_impl(
54
56
  timeout=timeout_value,
55
57
  trace=trace,
56
58
  keep_browser_open=keep_browser_open,
59
+ cdp_url=cdp_url,
57
60
  )
58
61
 
59
62
 
@@ -206,6 +206,7 @@ class TestAttemptApi:
206
206
  headless=False,
207
207
  proxy=None,
208
208
  keep_browser_open=False,
209
+ cdp_url=None,
209
210
  )
210
211
 
211
212
  attempt_api_mocks.get_cli_run_options.reset_mock()
@@ -333,6 +333,7 @@ class TestRunCheck:
333
333
  headless=False,
334
334
  proxy=None,
335
335
  keep_browser_open=False,
336
+ cdp_url=None,
336
337
  )
337
338
 
338
339
  attempt_api_mocks.get_cli_run_options.reset_mock()
@@ -599,6 +600,7 @@ class TestRunCreate:
599
600
  headless=False,
600
601
  proxy=None,
601
602
  keep_browser_open=False,
603
+ cdp_url=None,
602
604
  )
603
605
 
604
606
  attempt_api_mocks.get_cli_run_options.reset_mock()
@@ -190,6 +190,7 @@ async def attempt_api(
190
190
  headless = kwargs.get("headless")
191
191
  proxy = kwargs.get("proxy")
192
192
  keep_browser_open = kwargs.get("keep_browser_open")
193
+ cdp_url = kwargs.get("cdp_url")
193
194
  with cli_trace(trace_id) as tracing:
194
195
  async with extendable_timeout(timeout):
195
196
  result = await run_api(
@@ -204,6 +205,7 @@ async def attempt_api(
204
205
  headless=headless,
205
206
  proxy=ProxyConfig.parse_from_str(proxy) if proxy else None,
206
207
  keep_browser_open=keep_browser_open,
208
+ cdp_url=cdp_url,
207
209
  ),
208
210
  tracing=tracing,
209
211
  ),
@@ -244,6 +244,7 @@ async def run_check(
244
244
  headless = kwargs.get("headless")
245
245
  proxy = kwargs.get("proxy")
246
246
  keep_browser_open = kwargs.get("keep_browser_open")
247
+ cdp_url = kwargs.get("cdp_url")
247
248
  with cli_trace(trace_id) as tracing:
248
249
  async with extendable_timeout(timeout):
249
250
  result = await run_api(
@@ -256,6 +257,7 @@ async def run_check(
256
257
  headless=headless,
257
258
  proxy=ProxyConfig.parse_from_str(proxy) if proxy else None,
258
259
  keep_browser_open=keep_browser_open,
260
+ cdp_url=cdp_url,
259
261
  ),
260
262
  auth=Auth(
261
263
  session=StateSession(
@@ -287,6 +289,7 @@ async def run_create(
287
289
  headless = kwargs.get("headless")
288
290
  proxy = kwargs.get("proxy")
289
291
  keep_browser_open = kwargs.get("keep_browser_open")
292
+ cdp_url = kwargs.get("cdp_url")
290
293
  with cli_trace(trace_id) as tracing:
291
294
  async with extendable_timeout(timeout):
292
295
  result = await run_api(
@@ -299,6 +302,7 @@ async def run_create(
299
302
  headless=headless,
300
303
  proxy=ProxyConfig.parse_from_str(proxy) if proxy else None,
301
304
  keep_browser_open=keep_browser_open,
305
+ cdp_url=cdp_url,
302
306
  ),
303
307
  retrieve_session=True,
304
308
  tracing=tracing,
@@ -60,8 +60,8 @@ async def validate_intuned_project():
60
60
 
61
61
 
62
62
  def validate_project_name(project_name: str):
63
- if len(project_name) > 50:
64
- raise CLIError("Project name must be 50 characters or less.")
63
+ if len(project_name) > 200:
64
+ raise CLIError("Project name must be 200 characters or less.")
65
65
 
66
66
  project_name_regex = r"^[a-z0-9]+(?:[-_][a-z0-9]+)*$"
67
67
  if not re.match(project_name_regex, project_name):
@@ -29,6 +29,7 @@ class BaseExecuteCommandOptionsWithoutTrace(TypedDict):
29
29
  timeout: float
30
30
  proxy: NotRequired[str | None]
31
31
  keep_browser_open: bool
32
+ cdp_url: NotRequired[str | None]
32
33
 
33
34
 
34
35
  class BaseExecuteCommandOptions(BaseExecuteCommandOptionsWithoutTrace):
@@ -48,6 +48,18 @@ async def browser_mocks():
48
48
 
49
49
 
50
50
  class TestBrowser:
51
+ @pytest.mark.asyncio
52
+ @pytest.mark.asyncio
53
+ async def test_returns_cdp_options_if_cdp_url_is_passed(self, browser_mocks: BrowserMocks):
54
+ from intuned_cli.utils.browser import get_cli_run_options
55
+
56
+ options = await get_cli_run_options(
57
+ cdp_url="cdp_url",
58
+ )
59
+ assert options.environment == "cdp"
60
+ assert type(options) is CDPRunOptions
61
+ assert options.cdp_address == "cdp_url"
62
+
51
63
  @pytest.mark.asyncio
52
64
  async def test_returns_standalone_options_if_keep_browser_open_is_false(self, browser_mocks: BrowserMocks):
53
65
  from intuned_cli.utils.browser import get_cli_run_options
@@ -17,8 +17,14 @@ async def get_cli_run_options(
17
17
  headless: bool = False,
18
18
  proxy: ProxyConfig | None = None,
19
19
  keep_browser_open: bool = False,
20
+ cdp_url: str | None = None,
20
21
  ):
21
22
  global _current_browser_context_manager, _current_browser_context
23
+ if cdp_url is not None:
24
+ await close_cli_browser()
25
+ return CDPRunOptions(
26
+ cdp_address=cdp_url,
27
+ )
22
28
  if not keep_browser_open:
23
29
  return StandaloneRunOptions(
24
30
  headless=headless,
@@ -27,7 +27,8 @@ def cli_command(fn: Callable[P, Awaitable[R]]) -> Callable[P, R]:
27
27
  @wraps(fn)
28
28
  @run_sync
29
29
  async def wrapper(*args: Any, **kwargs: Any) -> R:
30
- keep_open = kwargs.get("keep_browser_open", False)
30
+ cdp_url = kwargs.get("cdp_url", None)
31
+ keep_open = (cdp_url is None) and (bool(kwargs.get("keep_browser_open", False)))
31
32
  if keep_open:
32
33
  console.print(
33
34
  "[bold]--keep-browser-open is set, the CLI will not close the last browser after the command completes.[/bold]"
@@ -0,0 +1,6 @@
1
+ from runtime.helpers.extensions import on_captcha_event
2
+ from runtime.helpers.extensions import pause_captcha_solver
3
+ from runtime.helpers.extensions import resume_captcha_solver
4
+ from runtime.helpers.extensions import wait_for_captcha_solve
5
+
6
+ __all__ = ["on_captcha_event", "wait_for_captcha_solve", "pause_captcha_solver", "resume_captcha_solver"]
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "intuned-runtime"
7
- version = "1.3.3"
7
+ version = "1.3.8"
8
8
  description = "Runtime SDK that powers browser automation projects running on Intuned"
9
9
  authors = [ "Intuned Developers <engineering@intunedhq.com>",]
10
10
  readme = "README.md"
@@ -52,6 +52,7 @@ pytimeparse = "^1.1.8"
52
52
  rich = "^14.1.0"
53
53
  jsonc-parser = "^1.1.5"
54
54
  pyyaml = "^6.0.3"
55
+ pyee = ">=11.1.0"
55
56
 
56
57
  [tool.poetry.scripts]
57
58
  intuned = "intuned_cli:run"
@@ -0,0 +1,7 @@
1
+ from .helpers import build_extensions_list
2
+ from .intuned_extension_server import clean_intuned_extension_server
3
+
4
+ __all__ = [
5
+ "build_extensions_list",
6
+ "clean_intuned_extension_server",
7
+ ]