magscope.scripting
==================

.. py:module:: magscope.scripting

.. autoapi-nested-parse::

   Utilities for registering and executing scripted automation flows.

   This module provides the runtime that powers MagScope's lightweight
   automation system. Users describe a sequence of actions in a script file
   by instantiating :class:`Script` and adding IPC :class:`Command` instances.
   The resulting steps are validated against :class:`ScriptRegistry` to ensure
   that each call is valid before being executed by :class:`ScriptManager`.

   Only methods decorated with :func:`register_script_command` are exposed to the
   script environment. Script execution runs in its own manager process and
   communicates with other parts of the application through the standard IPC
   mechanism.



Attributes
----------

.. autoapisummary::

   magscope.scripting.logger


Classes
-------

.. autoapisummary::

   magscope.scripting.ScriptStep
   magscope.scripting.ScriptCommandRegistration
   magscope.scripting.Script
   magscope.scripting.ScriptRegistry
   magscope.scripting.ScriptStatus
   magscope.scripting.ScriptManager


Module Contents
---------------

.. py:data:: logger

.. py:class:: ScriptStep

   Structured representation of a single scripted action.


   .. py:attribute:: command
      :type:  magscope.ipc_commands.Command


   .. py:attribute:: wait
      :type:  bool
      :value: False



.. py:class:: ScriptCommandRegistration

   Metadata binding a script-visible method to its IPC command type.


   .. py:attribute:: cls_name
      :type:  str


   .. py:attribute:: meth_name
      :type:  str


   .. py:attribute:: command_type
      :type:  type[magscope.ipc_commands.Command]


   .. py:attribute:: callable
      :type:  Callable


.. py:class:: Script

   Container that records the steps of a user-authored script.


   .. py:attribute:: steps
      :type:  list[ScriptStep]
      :value: []



   .. py:method:: append(command: magscope.ipc_commands.Command, *, wait: bool = False)

      Append an IPC command to the script.



.. py:class:: ScriptRegistry

   Tracks scriptable methods that managers expose to the scripting API.


   .. py:attribute:: avoided_names
      :value: ['sentinel', 'send_ipc']



   .. py:attribute:: _methods
      :type:  dict[type[magscope.ipc_commands.Command], ScriptCommandRegistration]


   .. py:method:: __call__(command_type: type[magscope.ipc_commands.Command]) -> ScriptCommandRegistration

      Return the registered callable for ``command_type``.

      Raises:
          ValueError: If ``command_type`` has not been registered.



   .. py:method:: register_class_methods(cls)

      Inspect ``cls`` for scriptable methods and add them to the registry.



   .. py:method:: check_script(script: Iterable[ScriptStep], *, command_registry=None)

      Validate a compiled script before it is executed.

      Checks include verifying that the method exists, arguments bind against
      the callable signature, and that reserved flags such as ``wait`` have
      the correct types. When ``command_registry`` is provided, the command must
      also map to a registered IPC handler so that ScriptManager can dispatch
      it.



   .. py:method:: _collect_script_registrations(cls)
      :staticmethod:


      Yield scriptable methods declared on ``cls`` and its bases.



   .. py:method:: get_class_name(cls)
      :staticmethod:


      Return the class name for a class or instance.



.. py:class:: ScriptStatus

   Bases: :py:obj:`enum.StrEnum`


   Lifecycle stages of a script managed by :class:`ScriptManager`.


   .. py:attribute:: EMPTY
      :value: 'Empty'



   .. py:attribute:: LOADED
      :value: 'Loaded'



   .. py:attribute:: RUNNING
      :value: 'Running'



   .. py:attribute:: PAUSED
      :value: 'Paused'



   .. py:attribute:: FINISHED
      :value: 'Finished'



   .. py:attribute:: ERROR
      :value: 'Error'



.. py:class:: ScriptManager

   Bases: :py:obj:`magscope.processes.ManagerProcessBase`


   Process that coordinates script execution and forwards IPC messages.


   .. py:attribute:: _script
      :type:  list[ScriptStep]
      :value: []



   .. py:attribute:: _script_index
      :type:  int
      :value: 0



   .. py:attribute:: _script_length
      :type:  int
      :value: 0



   .. py:attribute:: script_registry


   .. py:attribute:: _script_status
      :type:  ScriptStatus


   .. py:attribute:: _script_waiting
      :type:  bool
      :value: False



   .. py:attribute:: _script_sleep_duration
      :type:  float | None
      :value: None



   .. py:attribute:: _script_sleep_start
      :type:  float
      :value: 0



   .. py:method:: setup()

      Initialise process state.

      Currently no special setup is required, but the hook is retained for
      symmetry with other :class:`ManagerProcessBase` implementations.



   .. py:method:: do_main_loop()

      Main loop executed by the process infrastructure.



   .. py:method:: start_script()

      Start the currently loaded script from the beginning.



   .. py:method:: pause_script()

      Pause the running script.



   .. py:method:: resume_script()

      Resume a script that was previously paused.



   .. py:method:: load_script(path)

      Load and validate a script from ``path``.

      The script file is executed in an isolated namespace. Exactly one
      :class:`Script` instance must be created in that file; its recorded
      steps are copied locally after validation.



   .. py:method:: _execute_script_step(step: ScriptStep)

      Dispatch a single script step to its owning manager.



   .. py:method:: update_waiting()

      Let the script resume after waiting for a previous step to finish.



   .. py:method:: start_sleep(duration: float)

      Pause the script for ``duration`` seconds.



   .. py:method:: _do_sleep()

      Check whether the scripted sleep period has elapsed.



   .. py:method:: _send_script_step_update(current_step: int | None, *, description: str | None = None)

      Notify the GUI of the current script position.



   .. py:method:: _format_script_step(step: ScriptStep) -> str
      :staticmethod:


      Return a user-friendly description of a script step.



   .. py:method:: _set_script_status(status)

      Notify the GUI that the script status has changed.



   .. py:method:: _handle_script_error(message: str, *, details: str | None)

      Report a script error to the GUI and transition to the error state.



