refactor: align routing internals and refresh framework docstrings
- rename several Falyx and Command internal helpers with leading underscores - rename parallel terminology to concurrent across ActionGroup and SharedContext - update completer and routing references to match current routed API names - add and revise module, class, and method docstrings across core modules - refresh package copyright headers for 2026
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
"""
|
"""Falyx CLI Framework
|
||||||
Falyx CLI Framework
|
|
||||||
|
|
||||||
Copyright (c) 2025 rtj.dev LLC.
|
Copyright (c) 2026 rtj.dev LLC.
|
||||||
Licensed under the MIT License. See LICENSE file for details.
|
Licensed under the MIT License. See LICENSE file for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""
|
"""Falyx CLI Framework
|
||||||
Falyx CLI Framework
|
|
||||||
|
|
||||||
Copyright (c) 2025 rtj.dev LLC.
|
Copyright (c) 2026 rtj.dev LLC.
|
||||||
Licensed under the MIT License. See LICENSE file for details.
|
Licensed under the MIT License. See LICENSE file for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""
|
"""Falyx CLI Framework
|
||||||
Falyx CLI Framework
|
|
||||||
|
|
||||||
Copyright (c) 2025 rtj.dev LLC.
|
Copyright (c) 2026 rtj.dev LLC.
|
||||||
Licensed under the MIT License. See LICENSE file for details.
|
Licensed under the MIT License. See LICENSE file for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `Action`, the core atomic unit in the Falyx CLI framework, used to wrap and
|
||||||
Defines `Action`, the core atomic unit in the Falyx CLI framework, used to wrap and
|
|
||||||
execute a single callable or coroutine with structured lifecycle support.
|
execute a single callable or coroutine with structured lifecycle support.
|
||||||
|
|
||||||
An `Action` is the simplest building block in Falyx's execution model, enabling
|
An `Action` is the simplest building block in Falyx's execution model, enabling
|
||||||
@@ -50,8 +49,7 @@ from falyx.utils import ensure_async
|
|||||||
|
|
||||||
|
|
||||||
class Action(BaseAction):
|
class Action(BaseAction):
|
||||||
"""
|
"""Action wraps a simple function or coroutine into a standard executable unit.
|
||||||
Action wraps a simple function or coroutine into a standard executable unit.
|
|
||||||
|
|
||||||
It supports:
|
It supports:
|
||||||
- Optional retry logic.
|
- Optional retry logic.
|
||||||
@@ -148,8 +146,8 @@ class Action(BaseAction):
|
|||||||
self.enable_retry()
|
self.enable_retry()
|
||||||
|
|
||||||
def get_infer_target(self) -> tuple[Callable[..., Any], None]:
|
def get_infer_target(self) -> tuple[Callable[..., Any], None]:
|
||||||
"""
|
"""Returns the callable to be used for argument inference.
|
||||||
Returns the callable to be used for argument inference.
|
|
||||||
By default, it returns the action itself.
|
By default, it returns the action itself.
|
||||||
"""
|
"""
|
||||||
return self.action, None
|
return self.action, None
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ActionFactory`, a dynamic Falyx Action that defers the construction of its
|
||||||
Defines `ActionFactory`, a dynamic Falyx Action that defers the construction of its
|
|
||||||
underlying logic to runtime using a user-defined factory function.
|
underlying logic to runtime using a user-defined factory function.
|
||||||
|
|
||||||
This pattern is useful when the specific Action to execute cannot be determined until
|
This pattern is useful when the specific Action to execute cannot be determined until
|
||||||
@@ -46,8 +45,7 @@ from falyx.utils import ensure_async
|
|||||||
|
|
||||||
|
|
||||||
class ActionFactory(BaseAction):
|
class ActionFactory(BaseAction):
|
||||||
"""
|
"""Dynamically creates and runs another Action at runtime using a factory function.
|
||||||
Dynamically creates and runs another Action at runtime using a factory function.
|
|
||||||
|
|
||||||
This is useful for generating context-specific behavior (e.g., dynamic HTTPActions)
|
This is useful for generating context-specific behavior (e.g., dynamic HTTPActions)
|
||||||
where the structure of the next action depends on runtime values.
|
where the structure of the next action depends on runtime values.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ActionGroup`, a Falyx Action that executes multiple sub-actions concurrently
|
||||||
Defines `ActionGroup`, a Falyx Action that executes multiple sub-actions concurrently
|
using asynchronous concurrency.
|
||||||
using asynchronous parallelism.
|
|
||||||
|
|
||||||
`ActionGroup` is designed for workflows where several independent actions can run
|
`ActionGroup` is designed for workflows where several independent actions can run
|
||||||
simultaneously to improve responsiveness and reduce latency. It ensures robust error
|
simultaneously to improve responsiveness and reduce latency. It ensures robust error
|
||||||
@@ -9,7 +8,7 @@ isolation, shared result tracking, and full lifecycle hook integration while pre
|
|||||||
Falyx's introspectability and chaining capabilities.
|
Falyx's introspectability and chaining capabilities.
|
||||||
|
|
||||||
Key Features:
|
Key Features:
|
||||||
- Executes all actions in parallel via `asyncio.gather`
|
- Executes all actions concurrently via `asyncio.gather`
|
||||||
- Aggregates results as a list of `(name, result)` tuples
|
- Aggregates results as a list of `(name, result)` tuples
|
||||||
- Collects and reports multiple errors without interrupting execution
|
- Collects and reports multiple errors without interrupting execution
|
||||||
- Compatible with `SharedContext`, `OptionsManager`, and `last_result` injection
|
- Compatible with `SharedContext`, `OptionsManager`, and `last_result` injection
|
||||||
@@ -27,11 +26,11 @@ Raises:
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
ActionGroup(
|
ActionGroup(
|
||||||
name="ParallelChecks",
|
name="ConcurrentChecks",
|
||||||
actions=[Action(...), Action(...), ChainedAction(...)],
|
actions=[Action(...), Action(...), ChainedAction(...)],
|
||||||
)
|
)
|
||||||
|
|
||||||
This module complements `ChainedAction` by offering breadth-wise (parallel) execution
|
This module complements `ChainedAction` by offering breadth-wise (concurrent) execution
|
||||||
as opposed to depth-wise (sequential) execution.
|
as opposed to depth-wise (sequential) execution.
|
||||||
"""
|
"""
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -54,14 +53,13 @@ from falyx.themes.colors import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class ActionGroup(BaseAction, ActionListMixin):
|
class ActionGroup(BaseAction, ActionListMixin):
|
||||||
"""
|
"""ActionGroup executes multiple actions concurrently.
|
||||||
ActionGroup executes multiple actions concurrently in parallel.
|
|
||||||
|
|
||||||
It is ideal for independent tasks that can be safely run simultaneously,
|
It is ideal for independent tasks that can be safely run simultaneously,
|
||||||
improving overall throughput and responsiveness of workflows.
|
improving overall throughput and responsiveness of workflows.
|
||||||
|
|
||||||
Core features:
|
Core features:
|
||||||
- Parallel execution of all contained actions.
|
- Concurrent execution of all contained actions.
|
||||||
- Shared last_result injection across all actions if configured.
|
- Shared last_result injection across all actions if configured.
|
||||||
- Aggregated collection of individual results as (name, result) pairs.
|
- Aggregated collection of individual results as (name, result) pairs.
|
||||||
- Hook lifecycle support (before, on_success, on_error, after, on_teardown).
|
- Hook lifecycle support (before, on_success, on_error, after, on_teardown).
|
||||||
@@ -75,7 +73,7 @@ class ActionGroup(BaseAction, ActionListMixin):
|
|||||||
|
|
||||||
Best used for:
|
Best used for:
|
||||||
- Batch processing multiple independent tasks.
|
- Batch processing multiple independent tasks.
|
||||||
- Reducing latency for workflows with parallelizable steps.
|
- Reducing latency for workflows with concurrent steps.
|
||||||
- Isolating errors while maximizing successful execution.
|
- Isolating errors while maximizing successful execution.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -173,7 +171,7 @@ class ActionGroup(BaseAction, ActionListMixin):
|
|||||||
combined_args = args + self.args
|
combined_args = args + self.args
|
||||||
combined_kwargs = {**self.kwargs, **kwargs}
|
combined_kwargs = {**self.kwargs, **kwargs}
|
||||||
|
|
||||||
shared_context = SharedContext(name=self.name, action=self, is_parallel=True)
|
shared_context = SharedContext(name=self.name, action=self, is_concurrent=True)
|
||||||
if self.shared_context:
|
if self.shared_context:
|
||||||
shared_context.set_shared_result(self.shared_context.last_result())
|
shared_context.set_shared_result(self.shared_context.last_result())
|
||||||
updated_kwargs = self._maybe_inject_last_result(combined_kwargs)
|
updated_kwargs = self._maybe_inject_last_result(combined_kwargs)
|
||||||
@@ -229,7 +227,7 @@ class ActionGroup(BaseAction, ActionListMixin):
|
|||||||
action.register_hooks_recursively(hook_type, hook)
|
action.register_hooks_recursively(hook_type, hook)
|
||||||
|
|
||||||
async def preview(self, parent: Tree | None = None):
|
async def preview(self, parent: Tree | None = None):
|
||||||
label = [f"[{OneColors.MAGENTA_b}]⏩ ActionGroup (parallel)[/] '{self.name}'"]
|
label = [f"[{OneColors.MAGENTA_b}]⏩ ActionGroup (concurrent)[/] '{self.name}'"]
|
||||||
if self.inject_last_result:
|
if self.inject_last_result:
|
||||||
label.append(f" [dim](receives '{self.inject_into}')[/dim]")
|
label.append(f" [dim](receives '{self.inject_into}')[/dim]")
|
||||||
tree = parent.add("".join(label)) if parent else Tree("".join(label))
|
tree = parent.add("".join(label)) if parent else Tree("".join(label))
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Provides reusable mixins for managing collections of `BaseAction` instances
|
||||||
Provides reusable mixins for managing collections of `BaseAction` instances
|
|
||||||
within composite Falyx actions such as `ActionGroup` or `ChainedAction`.
|
within composite Falyx actions such as `ActionGroup` or `ChainedAction`.
|
||||||
|
|
||||||
The primary export, `ActionListMixin`, encapsulates common functionality for
|
The primary export, `ActionListMixin`, encapsulates common functionality for
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines strongly-typed enums used throughout the Falyx CLI framework for
|
||||||
Defines strongly-typed enums used throughout the Falyx CLI framework for
|
|
||||||
representing common structured values like file formats, selection return types,
|
representing common structured values like file formats, selection return types,
|
||||||
and confirmation modes.
|
and confirmation modes.
|
||||||
|
|
||||||
@@ -28,8 +27,7 @@ from enum import Enum
|
|||||||
|
|
||||||
|
|
||||||
class FileType(Enum):
|
class FileType(Enum):
|
||||||
"""
|
"""Represents supported file types for reading and writing in Falyx Actions.
|
||||||
Represents supported file types for reading and writing in Falyx Actions.
|
|
||||||
|
|
||||||
Used by `LoadFileAction` and `SaveFileAction` to determine how to parse or
|
Used by `LoadFileAction` and `SaveFileAction` to determine how to parse or
|
||||||
serialize file content. Includes alias resolution for common extensions like
|
serialize file content. Includes alias resolution for common extensions like
|
||||||
@@ -91,8 +89,7 @@ class FileType(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class SelectionReturnType(Enum):
|
class SelectionReturnType(Enum):
|
||||||
"""
|
"""Controls what is returned from a `SelectionAction` when using a selection map.
|
||||||
Controls what is returned from a `SelectionAction` when using a selection map.
|
|
||||||
|
|
||||||
Determines how the user's choice(s) from a `dict[str, SelectionOption]` are
|
Determines how the user's choice(s) from a `dict[str, SelectionOption]` are
|
||||||
transformed and returned by the action.
|
transformed and returned by the action.
|
||||||
@@ -145,8 +142,7 @@ class SelectionReturnType(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class ConfirmType(Enum):
|
class ConfirmType(Enum):
|
||||||
"""
|
"""Enum for defining prompt styles in confirmation dialogs.
|
||||||
Enum for defining prompt styles in confirmation dialogs.
|
|
||||||
|
|
||||||
Used by confirmation actions to control user input behavior and available choices.
|
Used by confirmation actions to control user input behavior and available choices.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Core action system for Falyx.
|
||||||
Core action system for Falyx.
|
|
||||||
|
|
||||||
This module defines the building blocks for executable actions and workflows,
|
This module defines the building blocks for executable actions and workflows,
|
||||||
providing a structured way to compose, execute, recover, and manage sequences of
|
providing a structured way to compose, execute, recover, and manage sequences of
|
||||||
@@ -14,13 +13,13 @@ Core guarantees:
|
|||||||
- Consistent timing and execution context tracking for each run.
|
- Consistent timing and execution context tracking for each run.
|
||||||
- Unified, predictable result handling and error propagation.
|
- Unified, predictable result handling and error propagation.
|
||||||
- Optional last_result injection to enable flexible, data-driven workflows.
|
- Optional last_result injection to enable flexible, data-driven workflows.
|
||||||
- Built-in support for retries, rollbacks, parallel groups, chaining, and fallback
|
- Built-in support for retries, rollbacks, concurrent groups, chaining, and fallback
|
||||||
recovery.
|
recovery.
|
||||||
|
|
||||||
Key components:
|
Key components:
|
||||||
- Action: wraps a function or coroutine into a standard executable unit.
|
- Action: wraps a function or coroutine into a standard executable unit.
|
||||||
- ChainedAction: runs actions sequentially, optionally injecting last results.
|
- ChainedAction: runs actions sequentially, optionally injecting last results.
|
||||||
- ActionGroup: runs actions in parallel and gathers results.
|
- ActionGroup: runs actions concurrently and gathers results.
|
||||||
- ProcessAction: executes CPU-bound functions in a separate process.
|
- ProcessAction: executes CPU-bound functions in a separate process.
|
||||||
- LiteralInputAction: injects static values into workflows.
|
- LiteralInputAction: injects static values into workflows.
|
||||||
- FallbackAction: gracefully recovers from failures or missing data.
|
- FallbackAction: gracefully recovers from failures or missing data.
|
||||||
@@ -46,8 +45,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class BaseAction(ABC):
|
class BaseAction(ABC):
|
||||||
"""
|
"""Base class for actions. Actions can be simple functions or more
|
||||||
Base class for actions. Actions can be simple functions or more
|
|
||||||
complex actions like `ChainedAction` or `ActionGroup`. They can also
|
complex actions like `ChainedAction` or `ActionGroup`. They can also
|
||||||
be run independently or as part of Falyx.
|
be run independently or as part of Falyx.
|
||||||
|
|
||||||
@@ -115,8 +113,8 @@ class BaseAction(ABC):
|
|||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def get_infer_target(self) -> tuple[Callable[..., Any] | None, dict[str, Any] | None]:
|
def get_infer_target(self) -> tuple[Callable[..., Any] | None, dict[str, Any] | None]:
|
||||||
"""
|
"""Returns the callable to be used for argument inference.
|
||||||
Returns the callable to be used for argument inference.
|
|
||||||
By default, it returns None.
|
By default, it returns None.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError("get_infer_target must be implemented by subclasses")
|
raise NotImplementedError("get_infer_target must be implemented by subclasses")
|
||||||
@@ -128,9 +126,7 @@ class BaseAction(ABC):
|
|||||||
self.shared_context = shared_context
|
self.shared_context = shared_context
|
||||||
|
|
||||||
def get_option(self, option_name: str, default: Any = None) -> Any:
|
def get_option(self, option_name: str, default: Any = None) -> Any:
|
||||||
"""
|
"""Resolve an option from the OptionsManager if present, else default."""
|
||||||
Resolve an option from the OptionsManager if present, otherwise use the fallback.
|
|
||||||
"""
|
|
||||||
if self.options_manager:
|
if self.options_manager:
|
||||||
return self.options_manager.get(option_name, default)
|
return self.options_manager.get(option_name, default)
|
||||||
return default
|
return default
|
||||||
@@ -158,8 +154,8 @@ class BaseAction(ABC):
|
|||||||
def prepare(
|
def prepare(
|
||||||
self, shared_context: SharedContext, options_manager: OptionsManager | None = None
|
self, shared_context: SharedContext, options_manager: OptionsManager | None = None
|
||||||
) -> BaseAction:
|
) -> BaseAction:
|
||||||
"""
|
"""Prepare the action specifically for sequential (ChainedAction) execution.
|
||||||
Prepare the action specifically for sequential (ChainedAction) execution.
|
|
||||||
Can be overridden for chain-specific logic.
|
Can be overridden for chain-specific logic.
|
||||||
"""
|
"""
|
||||||
self.set_shared_context(shared_context)
|
self.set_shared_context(shared_context)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ChainedAction`, a core Falyx construct for executing a sequence of actions
|
||||||
Defines `ChainedAction`, a core Falyx construct for executing a sequence of actions
|
|
||||||
in strict order, optionally injecting results from previous steps into subsequent ones.
|
in strict order, optionally injecting results from previous steps into subsequent ones.
|
||||||
|
|
||||||
`ChainedAction` is designed for linear workflows where each step may depend on
|
`ChainedAction` is designed for linear workflows where each step may depend on
|
||||||
@@ -86,8 +85,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class ChainedAction(BaseAction, ActionListMixin):
|
class ChainedAction(BaseAction, ActionListMixin):
|
||||||
"""
|
"""ChainedAction executes a sequence of actions one after another.
|
||||||
ChainedAction executes a sequence of actions one after another.
|
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Supports optional automatic last_result injection (auto_inject).
|
- Supports optional automatic last_result injection (auto_inject).
|
||||||
@@ -276,8 +274,7 @@ class ChainedAction(BaseAction, ActionListMixin):
|
|||||||
async def _rollback(
|
async def _rollback(
|
||||||
self, rollback_stack: list[tuple[Action, tuple[Any, ...], dict[str, Any]]]
|
self, rollback_stack: list[tuple[Action, tuple[Any, ...], dict[str, Any]]]
|
||||||
):
|
):
|
||||||
"""
|
"""Roll back all executed actions in reverse order.
|
||||||
Roll back all executed actions in reverse order.
|
|
||||||
|
|
||||||
Rollbacks run even if a fallback recovered from failure,
|
Rollbacks run even if a fallback recovered from failure,
|
||||||
ensuring consistent undo of all side effects.
|
ensuring consistent undo of all side effects.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ConfirmAction`, a Falyx Action that prompts the user for confirmation
|
||||||
Defines `ConfirmAction`, a Falyx Action that prompts the user for confirmation
|
|
||||||
before continuing execution.
|
before continuing execution.
|
||||||
|
|
||||||
`ConfirmAction` supports a wide range of confirmation strategies, including:
|
`ConfirmAction` supports a wide range of confirmation strategies, including:
|
||||||
@@ -62,8 +61,7 @@ from falyx.validators import word_validator, words_validator
|
|||||||
|
|
||||||
|
|
||||||
class ConfirmAction(BaseAction):
|
class ConfirmAction(BaseAction):
|
||||||
"""
|
"""Action to confirm an operation with the user.
|
||||||
Action to confirm an operation with the user.
|
|
||||||
|
|
||||||
There are several ways to confirm an action, such as using a simple
|
There are several ways to confirm an action, such as using a simple
|
||||||
yes/no prompt. You can also use a confirmation type that requires the user
|
yes/no prompt. You can also use a confirmation type that requires the user
|
||||||
@@ -97,8 +95,7 @@ class ConfirmAction(BaseAction):
|
|||||||
inject_last_result: bool = True,
|
inject_last_result: bool = True,
|
||||||
inject_into: str = "last_result",
|
inject_into: str = "last_result",
|
||||||
):
|
):
|
||||||
"""
|
"""Initialize the ConfirmAction.
|
||||||
Initialize the ConfirmAction.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
message (str): The confirmation message to display.
|
message (str): The confirmation message to display.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `FallbackAction`, a lightweight recovery Action used within `ChainedAction`
|
||||||
Defines `FallbackAction`, a lightweight recovery Action used within `ChainedAction`
|
|
||||||
pipelines to gracefully handle errors or missing results from a preceding step.
|
pipelines to gracefully handle errors or missing results from a preceding step.
|
||||||
|
|
||||||
When placed immediately after a failing or null-returning Action, `FallbackAction`
|
When placed immediately after a failing or null-returning Action, `FallbackAction`
|
||||||
@@ -46,8 +45,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class FallbackAction(Action):
|
class FallbackAction(Action):
|
||||||
"""
|
"""FallbackAction provides a default value if the previous action failed or
|
||||||
FallbackAction provides a default value if the previous action failed or
|
|
||||||
returned None.
|
returned None.
|
||||||
|
|
||||||
It injects the last result and checks:
|
It injects the last result and checks:
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `HTTPAction` for making HTTP requests using aiohttp.
|
||||||
Defines an Action subclass for making HTTP requests using aiohttp within Falyx workflows.
|
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Automatic reuse of aiohttp.ClientSession via SharedContext
|
- Automatic reuse of aiohttp.ClientSession via SharedContext
|
||||||
@@ -32,8 +31,7 @@ async def close_shared_http_session(context: ExecutionContext) -> None:
|
|||||||
|
|
||||||
|
|
||||||
class HTTPAction(Action):
|
class HTTPAction(Action):
|
||||||
"""
|
"""An Action for executing HTTP requests using aiohttp with shared session reuse.
|
||||||
An Action for executing HTTP requests using aiohttp with shared session reuse.
|
|
||||||
|
|
||||||
This action integrates seamlessly into Falyx pipelines, with automatic session
|
This action integrates seamlessly into Falyx pipelines, with automatic session
|
||||||
management, result injection, and lifecycle hook support. It is ideal for CLI-driven
|
management, result injection, and lifecycle hook support. It is ideal for CLI-driven
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""BaseIOAction: A base class for stream- or buffer-based IO-driven Actions.
|
||||||
BaseIOAction: A base class for stream- or buffer-based IO-driven Actions.
|
|
||||||
|
|
||||||
This module defines `BaseIOAction`, a specialized variant of `BaseAction`
|
This module defines `BaseIOAction`, a specialized variant of `BaseAction`
|
||||||
that interacts with standard input and output, enabling command-line pipelines,
|
that interacts with standard input and output, enabling command-line pipelines,
|
||||||
@@ -29,8 +28,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class BaseIOAction(BaseAction):
|
class BaseIOAction(BaseAction):
|
||||||
"""
|
"""Base class for IO-driven Actions that operate on stdin/stdout input streams.
|
||||||
Base class for IO-driven Actions that operate on stdin/stdout input streams.
|
|
||||||
|
|
||||||
Designed for use in shell pipelines or programmatic workflows that pass data
|
Designed for use in shell pipelines or programmatic workflows that pass data
|
||||||
through chained commands. It handles reading input, transforming it, and
|
through chained commands. It handles reading input, transforming it, and
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `LiteralInputAction`, a lightweight Falyx Action that injects a static,
|
||||||
Defines `LiteralInputAction`, a lightweight Falyx Action that injects a static,
|
|
||||||
predefined value into a `ChainedAction` workflow.
|
predefined value into a `ChainedAction` workflow.
|
||||||
|
|
||||||
This Action is useful for embedding literal values (e.g., strings, numbers,
|
This Action is useful for embedding literal values (e.g., strings, numbers,
|
||||||
@@ -43,8 +42,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class LiteralInputAction(Action):
|
class LiteralInputAction(Action):
|
||||||
"""
|
"""LiteralInputAction injects a static value into a ChainedAction.
|
||||||
LiteralInputAction injects a static value into a ChainedAction.
|
|
||||||
|
|
||||||
This allows embedding hardcoded values mid-pipeline, useful when:
|
This allows embedding hardcoded values mid-pipeline, useful when:
|
||||||
- Providing default or fallback inputs.
|
- Providing default or fallback inputs.
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `LoadFileAction`, a Falyx Action for reading and parsing the contents of a
|
||||||
Defines `LoadFileAction`, a Falyx Action for reading and parsing the contents of a file
|
file at runtime in a structured, introspectable, and lifecycle-aware manner.
|
||||||
at runtime in a structured, introspectable, and lifecycle-aware manner.
|
|
||||||
|
|
||||||
This action supports multiple common file types—including plain text, structured data
|
This action supports multiple common file types—including plain text, structured data
|
||||||
formats (JSON, YAML, TOML), tabular formats (CSV, TSV), XML, and raw Path objects—
|
formats (JSON, YAML, TOML), tabular formats (CSV, TSV), XML, and raw Path objects—
|
||||||
@@ -57,8 +56,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class LoadFileAction(BaseAction):
|
class LoadFileAction(BaseAction):
|
||||||
"""
|
"""LoadFileAction loads and parses the contents of a file at runtime.
|
||||||
LoadFileAction loads and parses the contents of a file at runtime.
|
|
||||||
|
|
||||||
This action supports multiple common file formats—including plain text, JSON,
|
This action supports multiple common file formats—including plain text, JSON,
|
||||||
YAML, TOML, XML, CSV, and TSV—and returns a parsed representation of the file.
|
YAML, TOML, XML, CSV, and TSV—and returns a parsed representation of the file.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `MenuAction`, a one-shot, interactive menu-style Falyx Action that presents
|
||||||
Defines `MenuAction`, a one-shot, interactive menu-style Falyx Action that presents
|
|
||||||
a set of labeled options to the user and executes the corresponding action based on
|
a set of labeled options to the user and executes the corresponding action based on
|
||||||
their selection.
|
their selection.
|
||||||
|
|
||||||
@@ -57,8 +56,7 @@ from falyx.utils import chunks
|
|||||||
|
|
||||||
|
|
||||||
class MenuAction(BaseAction):
|
class MenuAction(BaseAction):
|
||||||
"""
|
"""MenuAction displays a one-time interactive menu of predefined options,
|
||||||
MenuAction displays a one-time interactive menu of predefined options,
|
|
||||||
each mapped to a corresponding Action.
|
each mapped to a corresponding Action.
|
||||||
|
|
||||||
Unlike the main Falyx menu system, `MenuAction` is intended for scoped,
|
Unlike the main Falyx menu system, `MenuAction` is intended for scoped,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ProcessAction`, a Falyx Action that executes a blocking or CPU-bound function
|
||||||
Defines `ProcessAction`, a Falyx Action that executes a blocking or CPU-bound function
|
|
||||||
in a separate process using `concurrent.futures.ProcessPoolExecutor`.
|
in a separate process using `concurrent.futures.ProcessPoolExecutor`.
|
||||||
|
|
||||||
This is useful for offloading expensive computations or subprocess-compatible operations
|
This is useful for offloading expensive computations or subprocess-compatible operations
|
||||||
@@ -54,8 +53,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class ProcessAction(BaseAction):
|
class ProcessAction(BaseAction):
|
||||||
"""
|
"""ProcessAction runs a function in a separate process using ProcessPoolExecutor.
|
||||||
ProcessAction runs a function in a separate process using ProcessPoolExecutor.
|
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Executes CPU-bound or blocking tasks without blocking the main event loop.
|
- Executes CPU-bound or blocking tasks without blocking the main event loop.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ProcessPoolAction`, a parallelized action executor that distributes
|
||||||
Defines `ProcessPoolAction`, a parallelized action executor that distributes
|
|
||||||
tasks across multiple processes using Python's `concurrent.futures.ProcessPoolExecutor`.
|
tasks across multiple processes using Python's `concurrent.futures.ProcessPoolExecutor`.
|
||||||
|
|
||||||
This module enables structured execution of CPU-bound tasks in parallel while
|
This module enables structured execution of CPU-bound tasks in parallel while
|
||||||
@@ -37,8 +36,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ProcessTask:
|
class ProcessTask:
|
||||||
"""
|
"""Represents a callable task with its arguments for parallel execution.
|
||||||
Represents a callable task with its arguments for parallel execution.
|
|
||||||
|
|
||||||
This lightweight container is used to queue individual tasks for execution
|
This lightweight container is used to queue individual tasks for execution
|
||||||
inside a `ProcessPoolAction`.
|
inside a `ProcessPoolAction`.
|
||||||
@@ -62,8 +60,7 @@ class ProcessTask:
|
|||||||
|
|
||||||
|
|
||||||
class ProcessPoolAction(BaseAction):
|
class ProcessPoolAction(BaseAction):
|
||||||
"""
|
"""Executes a set of independent tasks in parallel using a process pool.
|
||||||
Executes a set of independent tasks in parallel using a process pool.
|
|
||||||
|
|
||||||
`ProcessPoolAction` is ideal for CPU-bound tasks that benefit from
|
`ProcessPoolAction` is ideal for CPU-bound tasks that benefit from
|
||||||
concurrent execution in separate processes. Each task is wrapped in a
|
concurrent execution in separate processes. Each task is wrapped in a
|
||||||
@@ -147,7 +144,7 @@ class ProcessPoolAction(BaseAction):
|
|||||||
async def _run(self, *args, **kwargs) -> Any:
|
async def _run(self, *args, **kwargs) -> Any:
|
||||||
if not self.actions:
|
if not self.actions:
|
||||||
raise EmptyPoolError(f"[{self.name}] No actions to execute.")
|
raise EmptyPoolError(f"[{self.name}] No actions to execute.")
|
||||||
shared_context = SharedContext(name=self.name, action=self, is_parallel=True)
|
shared_context = SharedContext(name=self.name, action=self, is_concurrent=True)
|
||||||
if self.shared_context:
|
if self.shared_context:
|
||||||
shared_context.set_shared_result(self.shared_context.last_result())
|
shared_context.set_shared_result(self.shared_context.last_result())
|
||||||
if self.inject_last_result and self.shared_context:
|
if self.inject_last_result and self.shared_context:
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `PromptMenuAction`, a Falyx Action that prompts the user to choose from
|
||||||
Defines `PromptMenuAction`, a Falyx Action that prompts the user to choose from
|
|
||||||
a list of labeled options using a single-line prompt input. Each option corresponds
|
a list of labeled options using a single-line prompt input. Each option corresponds
|
||||||
to a `MenuOption` that wraps a description and an executable action.
|
to a `MenuOption` that wraps a description and an executable action.
|
||||||
|
|
||||||
@@ -29,8 +28,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class PromptMenuAction(BaseAction):
|
class PromptMenuAction(BaseAction):
|
||||||
"""
|
"""Displays a single-line interactive prompt for selecting an option from a menu.
|
||||||
Displays a single-line interactive prompt for selecting an option from a menu.
|
|
||||||
|
|
||||||
`PromptMenuAction` is a lightweight alternative to `MenuAction`, offering a more
|
`PromptMenuAction` is a lightweight alternative to `MenuAction`, offering a more
|
||||||
compact selection interface. Instead of rendering a full table, it displays
|
compact selection interface. Instead of rendering a full table, it displays
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `SaveFileAction`, a Falyx Action for writing structured or unstructured data
|
||||||
Defines `SaveFileAction`, a Falyx Action for writing structured or unstructured data
|
|
||||||
to a file in a variety of supported formats.
|
to a file in a variety of supported formats.
|
||||||
|
|
||||||
Supports overwrite control, automatic directory creation, and full lifecycle hook
|
Supports overwrite control, automatic directory creation, and full lifecycle hook
|
||||||
@@ -41,8 +40,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class SaveFileAction(BaseAction):
|
class SaveFileAction(BaseAction):
|
||||||
"""
|
"""Saves data to a file in the specified format.
|
||||||
Saves data to a file in the specified format.
|
|
||||||
|
|
||||||
`SaveFileAction` serializes and writes input data to disk using the format
|
`SaveFileAction` serializes and writes input data to disk using the format
|
||||||
defined by `file_type`. It supports plain text and structured formats like
|
defined by `file_type`. It supports plain text and structured formats like
|
||||||
@@ -101,8 +99,7 @@ class SaveFileAction(BaseAction):
|
|||||||
inject_last_result: bool = False,
|
inject_last_result: bool = False,
|
||||||
inject_into: str = "data",
|
inject_into: str = "data",
|
||||||
):
|
):
|
||||||
"""
|
"""SaveFileAction allows saving data to a file.
|
||||||
SaveFileAction allows saving data to a file.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): Name of the action.
|
name (str): Name of the action.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `SelectFileAction`, a Falyx Action that allows users to select one or more
|
||||||
Defines `SelectFileAction`, a Falyx Action that allows users to select one or more
|
|
||||||
files from a target directory and optionally return either their content or path,
|
files from a target directory and optionally return either their content or path,
|
||||||
parsed based on a selected `FileType`.
|
parsed based on a selected `FileType`.
|
||||||
|
|
||||||
@@ -72,8 +71,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class SelectFileAction(BaseAction):
|
class SelectFileAction(BaseAction):
|
||||||
"""
|
"""SelectFileAction allows users to select a file(s) from a directory and return:
|
||||||
SelectFileAction allows users to select a file(s) from a directory and return:
|
|
||||||
- file content (as text, JSON, CSV, etc.)
|
- file content (as text, JSON, CSV, etc.)
|
||||||
- or the file path itself.
|
- or the file path itself.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `SelectionAction`, a highly flexible Falyx Action for interactive or
|
||||||
Defines `SelectionAction`, a highly flexible Falyx Action for interactive or headless
|
headless selection from a list or dictionary of user-defined options.
|
||||||
selection from a list or dictionary of user-defined options.
|
|
||||||
|
|
||||||
This module powers workflows that require prompting the user for input, selecting
|
This module powers workflows that require prompting the user for input, selecting
|
||||||
configuration presets, branching execution paths, or collecting multiple values
|
configuration presets, branching execution paths, or collecting multiple values
|
||||||
@@ -56,9 +55,8 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class SelectionAction(BaseAction):
|
class SelectionAction(BaseAction):
|
||||||
"""
|
"""A Falyx Action for interactively or programmatically selecting one or more
|
||||||
A Falyx Action for interactively or programmatically selecting one or more items
|
items from a list or dictionary of options.
|
||||||
from a list or dictionary of options.
|
|
||||||
|
|
||||||
`SelectionAction` supports both `list[str]` and `dict[str, SelectionOption]`
|
`SelectionAction` supports both `list[str]` and `dict[str, SelectionOption]`
|
||||||
inputs. It renders a prompt (unless `never_prompt=True`), validates user input
|
inputs. It renders a prompt (unless `never_prompt=True`), validates user input
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Execute shell commands with input substitution."""
|
"""Execute shell commands with input substitution."""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -16,8 +16,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class ShellAction(BaseIOAction):
|
class ShellAction(BaseIOAction):
|
||||||
"""
|
"""ShellAction wraps a shell command template for CLI pipelines.
|
||||||
ShellAction wraps a shell command template for CLI pipelines.
|
|
||||||
|
|
||||||
This Action takes parsed input (from stdin, literal, or last_result),
|
This Action takes parsed input (from stdin, literal, or last_result),
|
||||||
substitutes it into the provided shell command template, and executes
|
substitutes it into the provided shell command template, and executes
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `SignalAction`, a lightweight Falyx Action that raises a `FlowSignal`
|
||||||
Defines `SignalAction`, a lightweight Falyx Action that raises a `FlowSignal`
|
|
||||||
(such as `BackSignal`, `QuitSignal`, or `BreakChainSignal`) during execution to
|
(such as `BackSignal`, `QuitSignal`, or `BreakChainSignal`) during execution to
|
||||||
alter or exit the CLI flow.
|
alter or exit the CLI flow.
|
||||||
|
|
||||||
@@ -33,8 +32,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class SignalAction(Action):
|
class SignalAction(Action):
|
||||||
"""
|
"""A hook-compatible action that raises a control flow signal when invoked.
|
||||||
A hook-compatible action that raises a control flow signal when invoked.
|
|
||||||
|
|
||||||
`SignalAction` raises a `FlowSignal` (e.g., `BackSignal`, `QuitSignal`,
|
`SignalAction` raises a `FlowSignal` (e.g., `BackSignal`, `QuitSignal`,
|
||||||
`BreakChainSignal`) during execution. It is commonly used to exit menus,
|
`BreakChainSignal`) during execution. It is commonly used to exit menus,
|
||||||
@@ -59,8 +57,7 @@ class SignalAction(Action):
|
|||||||
super().__init__(name, action=self.raise_signal, hooks=hooks)
|
super().__init__(name, action=self.raise_signal, hooks=hooks)
|
||||||
|
|
||||||
async def raise_signal(self, *args, **kwargs):
|
async def raise_signal(self, *args, **kwargs):
|
||||||
"""
|
"""Raises the configured `FlowSignal`.
|
||||||
Raises the configured `FlowSignal`.
|
|
||||||
|
|
||||||
This method is called internally by the Falyx runtime and is the core
|
This method is called internally by the Falyx runtime and is the core
|
||||||
behavior of the action. All hooks surrounding execution are still triggered.
|
behavior of the action. All hooks surrounding execution are still triggered.
|
||||||
@@ -74,8 +71,7 @@ class SignalAction(Action):
|
|||||||
|
|
||||||
@signal.setter
|
@signal.setter
|
||||||
def signal(self, value: FlowSignal):
|
def signal(self, value: FlowSignal):
|
||||||
"""
|
"""Validates that the provided value is a `FlowSignal`.
|
||||||
Validates that the provided value is a `FlowSignal`.
|
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
TypeError: If `value` is not an instance of `FlowSignal`.
|
TypeError: If `value` is not an instance of `FlowSignal`.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `UserInputAction`, a Falyx Action that prompts the user for input using
|
||||||
Defines `UserInputAction`, a Falyx Action that prompts the user for input using
|
|
||||||
Prompt Toolkit and returns the result as a string.
|
Prompt Toolkit and returns the result as a string.
|
||||||
|
|
||||||
This action is ideal for interactive CLI workflows that require user input mid-pipeline.
|
This action is ideal for interactive CLI workflows that require user input mid-pipeline.
|
||||||
@@ -40,8 +39,7 @@ from falyx.themes.colors import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class UserInputAction(BaseAction):
|
class UserInputAction(BaseAction):
|
||||||
"""
|
"""Prompts the user for textual input and returns their response.
|
||||||
Prompts the user for textual input and returns their response.
|
|
||||||
|
|
||||||
`UserInputAction` uses Prompt Toolkit to gather input with optional validation,
|
`UserInputAction` uses Prompt Toolkit to gather input with optional validation,
|
||||||
lifecycle hook compatibility, and support for default text. If `inject_last_result`
|
lifecycle hook compatibility, and support for default text. If `inject_last_result`
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Provides the `BottomBar` class for managing a customizable bottom status bar in
|
||||||
Provides the `BottomBar` class for managing a customizable bottom status bar in
|
|
||||||
Falyx-based CLI applications.
|
Falyx-based CLI applications.
|
||||||
|
|
||||||
The bottom bar is rendered using `prompt_toolkit` and supports:
|
The bottom bar is rendered using `prompt_toolkit` and supports:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Command abstraction for the Falyx CLI framework.
|
"""Command abstraction for the Falyx CLI framework.
|
||||||
|
|
||||||
This module defines the `Command` class, which represents a single executable
|
This module defines the `Command` class, which represents a single executable
|
||||||
@@ -302,14 +302,14 @@ class Command(BaseModel):
|
|||||||
|
|
||||||
@field_validator("action", mode="before")
|
@field_validator("action", mode="before")
|
||||||
@classmethod
|
@classmethod
|
||||||
def wrap_callable_as_async(cls, action: Any) -> Any:
|
def _wrap_callable_as_async(cls, action: Any) -> Any:
|
||||||
if isinstance(action, BaseAction):
|
if isinstance(action, BaseAction):
|
||||||
return action
|
return action
|
||||||
elif callable(action):
|
elif callable(action):
|
||||||
return ensure_async(action)
|
return ensure_async(action)
|
||||||
raise TypeError("Action must be a callable or an instance of BaseAction")
|
raise TypeError("Action must be a callable or an instance of BaseAction")
|
||||||
|
|
||||||
def get_argument_definitions(self) -> list[dict[str, Any]]:
|
def _get_argument_definitions(self) -> list[dict[str, Any]]:
|
||||||
if self.arguments:
|
if self.arguments:
|
||||||
return self.arguments
|
return self.arguments
|
||||||
elif callable(self.argument_config) and isinstance(
|
elif callable(self.argument_config) and isinstance(
|
||||||
@@ -361,7 +361,7 @@ class Command(BaseModel):
|
|||||||
program=self.program,
|
program=self.program,
|
||||||
options_manager=self.options_manager,
|
options_manager=self.options_manager,
|
||||||
)
|
)
|
||||||
for arg_def in self.get_argument_definitions():
|
for arg_def in self._get_argument_definitions():
|
||||||
self.arg_parser.add_argument(*arg_def.pop("flags"), **arg_def)
|
self.arg_parser.add_argument(*arg_def.pop("flags"), **arg_def)
|
||||||
|
|
||||||
if isinstance(self.arg_parser, CommandArgumentParser) and self.execution_options:
|
if isinstance(self.arg_parser, CommandArgumentParser) and self.execution_options:
|
||||||
@@ -429,7 +429,7 @@ class Command(BaseModel):
|
|||||||
if should_prompt_user(confirm=self.confirm, options=self.options_manager):
|
if should_prompt_user(confirm=self.confirm, options=self.options_manager):
|
||||||
if self.preview_before_confirm:
|
if self.preview_before_confirm:
|
||||||
await self.preview()
|
await self.preview()
|
||||||
if not await confirm_async(self.confirmation_prompt):
|
if not await confirm_async(self._confirmation_prompt):
|
||||||
logger.info("[Command:%s] Cancelled by user.", self.key)
|
logger.info("[Command:%s] Cancelled by user.", self.key)
|
||||||
raise CancelSignal(f"[Command:{self.key}] Cancelled by confirmation.")
|
raise CancelSignal(f"[Command:{self.key}] Cancelled by confirmation.")
|
||||||
|
|
||||||
@@ -458,7 +458,7 @@ class Command(BaseModel):
|
|||||||
return self._context.result if self._context else None
|
return self._context.result if self._context else None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def confirmation_prompt(self) -> FormattedText:
|
def _confirmation_prompt(self) -> FormattedText:
|
||||||
"""Generate a styled prompt_toolkit FormattedText confirmation message."""
|
"""Generate a styled prompt_toolkit FormattedText confirmation message."""
|
||||||
if self.confirm_message and self.confirm_message != "Are you sure?":
|
if self.confirm_message and self.confirm_message != "Are you sure?":
|
||||||
return FormattedText([("class:confirm", self.confirm_message)])
|
return FormattedText([("class:confirm", self.confirm_message)])
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Shared command execution engine for the Falyx CLI framework.
|
"""Shared command execution engine for the Falyx CLI framework.
|
||||||
|
|
||||||
This module defines `CommandExecutor`, a low-level execution service responsible
|
This module defines `CommandExecutor`, a low-level execution service responsible
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Standalone command runner for the Falyx CLI framework.
|
"""Standalone command runner for the Falyx CLI framework.
|
||||||
|
|
||||||
This module defines `CommandRunner`, a developer-facing convenience wrapper for
|
This module defines `CommandRunner`, a developer-facing convenience wrapper for
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Prompt Toolkit completion support for routed Falyx command input.
|
"""Prompt Toolkit completion support for routed Falyx command input.
|
||||||
|
|
||||||
This module defines `FalyxCompleter`, the interactive completion layer used by
|
This module defines `FalyxCompleter`, the interactive completion layer used by
|
||||||
@@ -12,7 +12,7 @@ Completion behavior is split into two phases:
|
|||||||
1. Namespace completion
|
1. Namespace completion
|
||||||
While the user is still selecting a command or namespace entry, completion
|
While the user is still selecting a command or namespace entry, completion
|
||||||
candidates are derived from the active namespace via
|
candidates are derived from the active namespace via
|
||||||
`iter_completion_names`. Namespace-level help flags such as `-h`, `--help`,
|
`completion_names`. Namespace-level help flags such as `-h`, `--help`,
|
||||||
`-T`, and `--tldr` are also suggested when appropriate.
|
`-T`, and `--tldr` are also suggested when appropriate.
|
||||||
|
|
||||||
2. Leaf-command completion
|
2. Leaf-command completion
|
||||||
@@ -131,7 +131,7 @@ class FalyxCompleter(Completer):
|
|||||||
committed_tokens,
|
committed_tokens,
|
||||||
stub=stub,
|
stub=stub,
|
||||||
cursor_at_end_of_token=cursor_at_end,
|
cursor_at_end_of_token=cursor_at_end,
|
||||||
context=context,
|
invocation_context=context,
|
||||||
is_preview=is_preview,
|
is_preview=is_preview,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ class FalyxCompleter(Completer):
|
|||||||
list[str]: Matching namespace entry keys and aliases.
|
list[str]: Matching namespace entry keys and aliases.
|
||||||
"""
|
"""
|
||||||
results: list[str] = []
|
results: list[str] = []
|
||||||
for name in namespace.iter_completion_names:
|
for name in namespace.completion_names:
|
||||||
if name.upper().startswith(prefix.upper()):
|
if name.upper().startswith(prefix.upper()):
|
||||||
results.append(name.lower() if prefix.islower() else name)
|
results.append(name.lower() if prefix.islower() else name)
|
||||||
return results
|
return results
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Completion route models for routed Falyx autocompletion.
|
"""Completion route models for routed Falyx autocompletion.
|
||||||
|
|
||||||
This module defines `CompletionRoute`, a lightweight value object used by the
|
This module defines `CompletionRoute`, a lightweight value object used by the
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Configuration loader and schema definitions for the Falyx CLI framework.
|
"""Configuration loader and schema definitions for the Falyx CLI framework.
|
||||||
|
|
||||||
This module supports config-driven initialization of CLI commands and submenus
|
This module supports config-driven initialization of CLI commands and submenus
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Global console instance for Falyx CLI applications."""
|
"""Global console instance for Falyx CLI applications."""
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Context models for Falyx execution and invocation state.
|
"""Context models for Falyx execution and invocation state.
|
||||||
|
|
||||||
This module defines the core context objects used throughout Falyx to track both
|
This module defines the core context objects used throughout Falyx to track both
|
||||||
@@ -229,9 +229,9 @@ class SharedContext(BaseModel):
|
|||||||
results (list[Any]): Captures results from each action, in order of execution.
|
results (list[Any]): Captures results from each action, in order of execution.
|
||||||
errors (list[tuple[int, BaseException]]): Indexed list of errors from failed actions.
|
errors (list[tuple[int, BaseException]]): Indexed list of errors from failed actions.
|
||||||
current_index (int): Index of the currently executing action (used in chains).
|
current_index (int): Index of the currently executing action (used in chains).
|
||||||
is_parallel (bool): Whether the context is used in parallel mode (ActionGroup).
|
is_concurrent (bool): Whether the context is used in concurrent mode (ActionGroup).
|
||||||
shared_result (Any | None): Optional shared value available to all actions in
|
shared_result (Any | None): Optional shared value available to all actions in
|
||||||
parallel mode.
|
concurrent mode.
|
||||||
share (dict[str, Any]): Custom shared key-value store for user-defined
|
share (dict[str, Any]): Custom shared key-value store for user-defined
|
||||||
communication
|
communication
|
||||||
between actions (e.g., flags, intermediate data, settings).
|
between actions (e.g., flags, intermediate data, settings).
|
||||||
@@ -254,7 +254,7 @@ class SharedContext(BaseModel):
|
|||||||
results: list[Any] = Field(default_factory=list)
|
results: list[Any] = Field(default_factory=list)
|
||||||
errors: list[tuple[int, BaseException]] = Field(default_factory=list)
|
errors: list[tuple[int, BaseException]] = Field(default_factory=list)
|
||||||
current_index: int = -1
|
current_index: int = -1
|
||||||
is_parallel: bool = False
|
is_concurrent: bool = False
|
||||||
shared_result: Any | None = None
|
shared_result: Any | None = None
|
||||||
|
|
||||||
share: dict[str, Any] = Field(default_factory=dict)
|
share: dict[str, Any] = Field(default_factory=dict)
|
||||||
@@ -269,11 +269,11 @@ class SharedContext(BaseModel):
|
|||||||
|
|
||||||
def set_shared_result(self, result: Any) -> None:
|
def set_shared_result(self, result: Any) -> None:
|
||||||
self.shared_result = result
|
self.shared_result = result
|
||||||
if self.is_parallel:
|
if self.is_concurrent:
|
||||||
self.results.append(result)
|
self.results.append(result)
|
||||||
|
|
||||||
def last_result(self) -> Any:
|
def last_result(self) -> Any:
|
||||||
if self.is_parallel:
|
if self.is_concurrent:
|
||||||
return self.shared_result
|
return self.shared_result
|
||||||
return self.results[-1] if self.results else None
|
return self.results[-1] if self.results else None
|
||||||
|
|
||||||
@@ -284,9 +284,9 @@ class SharedContext(BaseModel):
|
|||||||
self.share[key] = value
|
self.share[key] = value
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
parallel_label = "Parallel" if self.is_parallel else "Sequential"
|
concurrent_label = "Concurrent" if self.is_concurrent else "Sequential"
|
||||||
return (
|
return (
|
||||||
f"<{parallel_label}SharedContext '{self.name}' | "
|
f"<{concurrent_label}SharedContext '{self.name}' | "
|
||||||
f"Results: {self.results} | "
|
f"Results: {self.results} | "
|
||||||
f"Errors: {self.errors}>"
|
f"Errors: {self.errors}>"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Provides debug logging hooks for Falyx action execution.
|
||||||
Provides debug logging hooks for Falyx action execution.
|
|
||||||
|
|
||||||
This module defines lifecycle hook functions (`log_before`, `log_success`, `log_after`, `log_error`)
|
This module defines lifecycle hook functions (`log_before`, `log_success`, `log_after`, `log_error`)
|
||||||
that can be registered with a `HookManager` to trace command execution.
|
that can be registered with a `HookManager` to trace command execution.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Defines all custom exception classes used in the Falyx CLI framework.
|
"""Defines all custom exception classes used in the Falyx CLI framework.
|
||||||
|
|
||||||
These exceptions provide structured error handling for common failure cases,
|
These exceptions provide structured error handling for common failure cases,
|
||||||
|
|||||||
@@ -1,10 +1,50 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
|
"""Execution option enums for the Falyx command runtime.
|
||||||
|
|
||||||
|
This module defines `ExecutionOption`, the enum used to represent optional
|
||||||
|
execution-scoped behaviors that a command may choose to expose through its
|
||||||
|
argument parser.
|
||||||
|
|
||||||
|
Execution options are distinct from normal command inputs. They control runtime
|
||||||
|
behavior around command execution rather than the business-logic arguments
|
||||||
|
passed to the underlying action. Typical examples include summary output,
|
||||||
|
retry configuration, and confirmation handling.
|
||||||
|
|
||||||
|
`ExecutionOption` is used by Falyx components such as `Command` and
|
||||||
|
`CommandArgumentParser` to declaratively enable execution-level flags and to
|
||||||
|
normalize user- or config-provided option names into a validated enum value.
|
||||||
|
|
||||||
|
The enum also implements custom missing-value handling so string inputs can be
|
||||||
|
resolved case-insensitively with helpful error messages.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
class ExecutionOption(Enum):
|
class ExecutionOption(Enum):
|
||||||
|
"""Enumerates optional execution-scoped behaviors supported by Falyx.
|
||||||
|
|
||||||
|
`ExecutionOption` identifies runtime features that can be enabled on a
|
||||||
|
command independently of its normal argument schema. When present, these
|
||||||
|
options typically cause `CommandArgumentParser` to expose additional flags
|
||||||
|
that affect how the command is executed rather than what the command does.
|
||||||
|
|
||||||
|
Supported options:
|
||||||
|
SUMMARY: Enable summary-related execution flags and reporting behavior.
|
||||||
|
RETRY: Enable retry-related execution flags such as retry count, delay,
|
||||||
|
and backoff.
|
||||||
|
CONFIRM: Enable confirmation-related execution flags such as forcing or
|
||||||
|
skipping confirmation prompts.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- These values are intended for execution control, not domain-specific
|
||||||
|
command input.
|
||||||
|
- String values are normalized case-insensitively through `_missing_()`
|
||||||
|
so config and user input can be converted into enum members with
|
||||||
|
friendlier validation behavior.
|
||||||
|
"""
|
||||||
|
|
||||||
SUMMARY = "summary"
|
SUMMARY = "summary"
|
||||||
RETRY = "retry"
|
RETRY = "retry"
|
||||||
CONFIRM = "confirm"
|
CONFIRM = "confirm"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Provides the `ExecutionRegistry`, a centralized runtime store for capturing and
|
||||||
Provides the `ExecutionRegistry`, a centralized runtime store for capturing and inspecting
|
inspecting the execution history of Falyx actions.
|
||||||
the execution history of Falyx actions.
|
|
||||||
|
|
||||||
The registry automatically records every `ExecutionContext` created during action
|
The registry automatically records every `ExecutionContext` created during action
|
||||||
execution—including context metadata, results, exceptions, duration, and tracebacks.
|
execution—including context metadata, results, exceptions, duration, and tracebacks.
|
||||||
@@ -63,8 +62,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class ExecutionRegistry:
|
class ExecutionRegistry:
|
||||||
"""
|
"""Global registry for recording and inspecting Falyx action executions.
|
||||||
Global registry for recording and inspecting Falyx action executions.
|
|
||||||
|
|
||||||
This class captures every `ExecutionContext` created by Falyx Actions,
|
This class captures every `ExecutionContext` created by Falyx Actions,
|
||||||
tracking metadata, results, exceptions, and performance metrics. It enables
|
tracking metadata, results, exceptions, and performance metrics. It enables
|
||||||
@@ -96,8 +94,7 @@ class ExecutionRegistry:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def record(cls, context: ExecutionContext):
|
def record(cls, context: ExecutionContext):
|
||||||
"""
|
"""Record an execution context and assign a unique index.
|
||||||
Record an execution context and assign a unique index.
|
|
||||||
|
|
||||||
This method logs the context, appends it to the registry,
|
This method logs the context, appends it to the registry,
|
||||||
and makes it available for future summary or filtering.
|
and makes it available for future summary or filtering.
|
||||||
@@ -115,8 +112,7 @@ class ExecutionRegistry:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all(cls) -> list[ExecutionContext]:
|
def get_all(cls) -> list[ExecutionContext]:
|
||||||
"""
|
"""Return all recorded execution contexts in order of execution.
|
||||||
Return all recorded execution contexts in order of execution.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list[ExecutionContext]: All stored action contexts.
|
list[ExecutionContext]: All stored action contexts.
|
||||||
@@ -125,8 +121,7 @@ class ExecutionRegistry:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_name(cls, name: str) -> list[ExecutionContext]:
|
def get_by_name(cls, name: str) -> list[ExecutionContext]:
|
||||||
"""
|
"""Return all executions recorded under a given action name.
|
||||||
Retrieve all executions recorded under a given action name.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
name (str): The name of the action.
|
name (str): The name of the action.
|
||||||
@@ -138,8 +133,7 @@ class ExecutionRegistry:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_latest(cls) -> ExecutionContext:
|
def get_latest(cls) -> ExecutionContext:
|
||||||
"""
|
"""Return the most recent execution context.
|
||||||
Return the most recent execution context.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ExecutionContext: The last recorded context.
|
ExecutionContext: The last recorded context.
|
||||||
@@ -148,8 +142,7 @@ class ExecutionRegistry:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def clear(cls):
|
def clear(cls):
|
||||||
"""
|
"""Clear all stored execution data and reset internal indices.
|
||||||
Clear all stored execution data and reset internal indices.
|
|
||||||
|
|
||||||
This operation is destructive and cannot be undone.
|
This operation is destructive and cannot be undone.
|
||||||
"""
|
"""
|
||||||
@@ -167,8 +160,7 @@ class ExecutionRegistry:
|
|||||||
last_result: bool = False,
|
last_result: bool = False,
|
||||||
status: Literal["all", "success", "error"] = "all",
|
status: Literal["all", "success", "error"] = "all",
|
||||||
):
|
):
|
||||||
"""
|
"""Display a formatted Rich table of recorded executions.
|
||||||
Display a formatted Rich table of recorded executions.
|
|
||||||
|
|
||||||
Supports filtering by action name, index, or execution status.
|
Supports filtering by action name, index, or execution status.
|
||||||
Can optionally show only the last result or a specific indexed result.
|
Can optionally show only the last result or a specific indexed result.
|
||||||
|
|||||||
1147
falyx/falyx.py
1147
falyx/falyx.py
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines the `HookManager` and `HookType` used in the Falyx CLI framework to manage
|
||||||
Defines the `HookManager` and `HookType` used in the Falyx CLI framework to manage
|
|
||||||
execution lifecycle hooks around actions and commands.
|
execution lifecycle hooks around actions and commands.
|
||||||
|
|
||||||
The hook system enables structured callbacks for important stages in a Falyx action's
|
The hook system enables structured callbacks for important stages in a Falyx action's
|
||||||
@@ -31,8 +30,7 @@ Hook = Union[
|
|||||||
|
|
||||||
|
|
||||||
class HookType(Enum):
|
class HookType(Enum):
|
||||||
"""
|
"""Enum for supported hook lifecycle phases in Falyx.
|
||||||
Enum for supported hook lifecycle phases in Falyx.
|
|
||||||
|
|
||||||
HookType is used to classify lifecycle events that can be intercepted
|
HookType is used to classify lifecycle events that can be intercepted
|
||||||
with user-defined callbacks.
|
with user-defined callbacks.
|
||||||
@@ -91,8 +89,7 @@ class HookType(Enum):
|
|||||||
|
|
||||||
|
|
||||||
class HookManager:
|
class HookManager:
|
||||||
"""
|
"""Manages lifecycle hooks for a command or action.
|
||||||
Manages lifecycle hooks for a command or action.
|
|
||||||
|
|
||||||
`HookManager` tracks user-defined callbacks to be run at key points in a command's
|
`HookManager` tracks user-defined callbacks to be run at key points in a command's
|
||||||
lifecycle: before execution, on success, on error, after completion, and during
|
lifecycle: before execution, on success, on error, after completion, and during
|
||||||
@@ -114,8 +111,7 @@ class HookManager:
|
|||||||
}
|
}
|
||||||
|
|
||||||
def register(self, hook_type: HookType | str, hook: Hook):
|
def register(self, hook_type: HookType | str, hook: Hook):
|
||||||
"""
|
"""Register a new hook for a given lifecycle phase.
|
||||||
Register a new hook for a given lifecycle phase.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hook_type (HookType | str): The hook category (e.g. "before", "on_success").
|
hook_type (HookType | str): The hook category (e.g. "before", "on_success").
|
||||||
@@ -128,8 +124,7 @@ class HookManager:
|
|||||||
self._hooks[hook_type].append(hook)
|
self._hooks[hook_type].append(hook)
|
||||||
|
|
||||||
def clear(self, hook_type: HookType | None = None):
|
def clear(self, hook_type: HookType | None = None):
|
||||||
"""
|
"""Clear registered hooks for one or all hook types.
|
||||||
Clear registered hooks for one or all hook types.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hook_type (HookType | None): If None, clears all hooks.
|
hook_type (HookType | None): If None, clears all hooks.
|
||||||
@@ -141,8 +136,7 @@ class HookManager:
|
|||||||
self._hooks[ht] = []
|
self._hooks[ht] = []
|
||||||
|
|
||||||
async def trigger(self, hook_type: HookType, context: ExecutionContext):
|
async def trigger(self, hook_type: HookType, context: ExecutionContext):
|
||||||
"""
|
"""Invoke all hooks registered for a given lifecycle phase.
|
||||||
Invoke all hooks registered for a given lifecycle phase.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hook_type (HookType): The lifecycle phase to trigger.
|
hook_type (HookType): The lifecycle phase to trigger.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines reusable lifecycle hooks for Falyx Actions and Commands.
|
||||||
Defines reusable lifecycle hooks for Falyx Actions and Commands.
|
|
||||||
|
|
||||||
This module includes:
|
This module includes:
|
||||||
- `spinner_before_hook`: Automatically starts a spinner before an action runs.
|
- `spinner_before_hook`: Automatically starts a spinner before an action runs.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Project and global initializer for Falyx CLI environments.
|
||||||
Project and global initializer for Falyx CLI environments.
|
|
||||||
|
|
||||||
This module defines functions to bootstrap a new Falyx-based CLI project or
|
This module defines functions to bootstrap a new Falyx-based CLI project or
|
||||||
create a global user-level configuration in `~/.config/falyx`.
|
create a global user-level configuration in `~/.config/falyx`.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Global logger instance for Falyx CLI applications."""
|
"""Global logger instance for Falyx CLI applications."""
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `MenuOption` and `MenuOptionMap`, core components used to construct
|
||||||
Defines `MenuOption` and `MenuOptionMap`, core components used to construct
|
|
||||||
interactive menus within Falyx Actions such as `MenuAction` and `PromptMenuAction`.
|
interactive menus within Falyx Actions such as `MenuAction` and `PromptMenuAction`.
|
||||||
|
|
||||||
Each `MenuOption` represents a single actionable choice with a description,
|
Each `MenuOption` represents a single actionable choice with a description,
|
||||||
|
|||||||
@@ -1,9 +1,40 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Defines `FalyxMode`, an enum representing the different modes of operation for Falyx."""
|
"""Runtime mode definitions for the Falyx CLI framework.
|
||||||
|
|
||||||
|
This module defines `FalyxMode`, the enum used to represent the high-level
|
||||||
|
operating mode of a Falyx application during parsing, routing, rendering, and
|
||||||
|
execution.
|
||||||
|
|
||||||
|
These modes describe the current intent of the runtime rather than any
|
||||||
|
particular command. They are used throughout Falyx to coordinate behavior such
|
||||||
|
as whether the application should show an interactive menu, execute a routed
|
||||||
|
command, render help output, preview a command, or surface an error state.
|
||||||
|
|
||||||
|
`FalyxMode` is commonly stored in shared runtime state and passed through
|
||||||
|
invocation and parsing layers so UI rendering and execution flow remain
|
||||||
|
consistent across CLI and menu-driven entrypoints.
|
||||||
|
"""
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
class FalyxMode(Enum):
|
class FalyxMode(Enum):
|
||||||
|
"""Enumerates the high-level runtime modes used by Falyx.
|
||||||
|
|
||||||
|
`FalyxMode` provides a small set of application-wide states that describe
|
||||||
|
how the current invocation should be handled.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
MENU: Interactive menu mode using Prompt Toolkit input and menu
|
||||||
|
rendering.
|
||||||
|
COMMAND: Direct command-execution mode for routed CLI or programmatic
|
||||||
|
invocation.
|
||||||
|
PREVIEW: Non-executing preview mode used to inspect a command before it
|
||||||
|
runs.
|
||||||
|
HELP: Help-rendering mode for namespace, command, or TLDR output.
|
||||||
|
ERROR: Error state used when invocation handling should surface a
|
||||||
|
failure condition.
|
||||||
|
"""
|
||||||
|
|
||||||
MENU = "menu"
|
MENU = "menu"
|
||||||
COMMAND = "command"
|
COMMAND = "command"
|
||||||
PREVIEW = "preview"
|
PREVIEW = "preview"
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
|
"""Namespace entry model for nested Falyx applications.
|
||||||
|
|
||||||
|
This module defines `FalyxNamespace`, the lightweight metadata container used to
|
||||||
|
register one `Falyx` instance inside another as a routed namespace entry.
|
||||||
|
|
||||||
|
A `FalyxNamespace` describes how a nested application should appear and behave
|
||||||
|
from the perspective of its parent namespace. It stores the public-facing key,
|
||||||
|
description, aliases, styling, and visibility flags used for routing,
|
||||||
|
completion, help rendering, and menu display, while holding a reference to the
|
||||||
|
child `Falyx` runtime that should take over once the namespace is entered.
|
||||||
|
|
||||||
|
This model is intentionally small and declarative. It does not implement
|
||||||
|
routing, rendering, or execution itself; those responsibilities remain with the
|
||||||
|
parent and child `Falyx` instances.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
@@ -11,6 +27,26 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FalyxNamespace:
|
class FalyxNamespace:
|
||||||
|
"""Represents a nested `Falyx` application exposed as a namespace entry.
|
||||||
|
|
||||||
|
`FalyxNamespace` is used by a parent `Falyx` instance to register and
|
||||||
|
describe a child `Falyx` runtime as a routable namespace. It provides the
|
||||||
|
metadata needed to expose that child namespace consistently across command
|
||||||
|
resolution, completion, help output, and menu rendering.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
key: Primary identifier used to enter the namespace.
|
||||||
|
description: User-facing description of the namespace.
|
||||||
|
namespace: Nested `Falyx` instance activated when this namespace is
|
||||||
|
selected.
|
||||||
|
aliases: Optional alternate names that may also resolve to the same
|
||||||
|
namespace.
|
||||||
|
help_text: Optional short help text used in listings or help output.
|
||||||
|
style: Rich style used when rendering the namespace key or aliases.
|
||||||
|
hidden: Whether the namespace should be omitted from visible menus and
|
||||||
|
help listings.
|
||||||
|
"""
|
||||||
|
|
||||||
key: str
|
key: str
|
||||||
description: str
|
description: str
|
||||||
namespace: Falyx
|
namespace: Falyx
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""Manages global or scoped CLI options across namespaces for Falyx commands.
|
"""Manages global or scoped CLI options across namespaces for Falyx commands.
|
||||||
|
|
||||||
The `OptionsManager` provides a centralized interface for retrieving, setting, toggling,
|
The `OptionsManager` provides a centralized interface for retrieving, setting, toggling,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""
|
"""Falyx CLI Framework
|
||||||
Falyx CLI Framework
|
|
||||||
|
|
||||||
Copyright (c) 2025 rtj.dev LLC.
|
Copyright (c) 2026 rtj.dev LLC.
|
||||||
Licensed under the MIT License. See LICENSE file for details.
|
Licensed under the MIT License. See LICENSE file for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines the `Argument` dataclass used by `CommandArgumentParser` to represent
|
||||||
Defines the `Argument` dataclass used by `CommandArgumentParser` to represent
|
|
||||||
individual command-line parameters in a structured, introspectable format.
|
individual command-line parameters in a structured, introspectable format.
|
||||||
|
|
||||||
Each `Argument` instance describes one CLI input, including its flags, type,
|
Each `Argument` instance describes one CLI input, including its flags, type,
|
||||||
@@ -42,8 +41,7 @@ from falyx.parser.argument_action import ArgumentAction
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Argument:
|
class Argument:
|
||||||
"""
|
"""Represents a command-line argument.
|
||||||
Represents a command-line argument.
|
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
flags (tuple[str, ...]): Short and long flags for the argument.
|
flags (tuple[str, ...]): Short and long flags for the argument.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines `ArgumentAction`, an enum used to standardize the behavior of CLI arguments
|
||||||
Defines `ArgumentAction`, an enum used to standardize the behavior of CLI arguments
|
|
||||||
defined within Falyx command configurations.
|
defined within Falyx command configurations.
|
||||||
|
|
||||||
Each member of this enum maps to a valid `argparse` like actions or Falyx-specific
|
Each member of this enum maps to a valid `argparse` like actions or Falyx-specific
|
||||||
@@ -24,8 +23,7 @@ from enum import Enum
|
|||||||
|
|
||||||
|
|
||||||
class ArgumentAction(Enum):
|
class ArgumentAction(Enum):
|
||||||
"""
|
"""Defines the action to be taken when the argument is encountered.
|
||||||
Defines the action to be taken when the argument is encountered.
|
|
||||||
|
|
||||||
This enum mirrors the core behavior of Python's `argparse` actions, with a few
|
This enum mirrors the core behavior of Python's `argparse` actions, with a few
|
||||||
Falyx-specific extensions. It is used when defining command-line arguments for
|
Falyx-specific extensions. It is used when defining command-line arguments for
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""CommandArgumentParser implementation for the Falyx CLI framework.
|
"""CommandArgumentParser implementation for the Falyx CLI framework.
|
||||||
|
|
||||||
This module provides a structured, extensible argument parsing system designed
|
This module provides a structured, extensible argument parsing system designed
|
||||||
@@ -273,8 +273,7 @@ class CommandArgumentParser:
|
|||||||
self._add_tldr()
|
self._add_tldr()
|
||||||
|
|
||||||
def add_tldr_examples(self, examples: list[TLDRInput]) -> None:
|
def add_tldr_examples(self, examples: list[TLDRInput]) -> None:
|
||||||
"""
|
"""Add TLDR examples to the parser.
|
||||||
Add TLDR examples to the parser.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
examples (list[TLDRInput]): List of TLDRExample instances or (usage, description) tuples.
|
examples (list[TLDRInput]): List of TLDRExample instances or (usage, description) tuples.
|
||||||
@@ -816,8 +815,7 @@ class CommandArgumentParser:
|
|||||||
self._register_argument(argument)
|
self._register_argument(argument)
|
||||||
|
|
||||||
def get_argument(self, dest: str) -> Argument | None:
|
def get_argument(self, dest: str) -> Argument | None:
|
||||||
"""
|
"""Return the Argument object for a given destination name.
|
||||||
Return the Argument object for a given destination name.
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dest (str): Destination key of the argument.
|
dest (str): Destination key of the argument.
|
||||||
@@ -830,8 +828,7 @@ class CommandArgumentParser:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def to_definition_list(self) -> list[dict[str, Any]]:
|
def to_definition_list(self) -> list[dict[str, Any]]:
|
||||||
"""
|
"""Convert argument metadata into a serializable list of dicts.
|
||||||
Convert argument metadata into a serializable list of dicts.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
List of definitions for use in config introspection, documentation, or export.
|
List of definitions for use in config introspection, documentation, or export.
|
||||||
@@ -844,12 +841,13 @@ class CommandArgumentParser:
|
|||||||
"dest": arg.dest,
|
"dest": arg.dest,
|
||||||
"action": arg.action,
|
"action": arg.action,
|
||||||
"type": arg.type,
|
"type": arg.type,
|
||||||
|
"default": arg.default,
|
||||||
"choices": arg.choices,
|
"choices": arg.choices,
|
||||||
"required": arg.required,
|
"required": arg.required,
|
||||||
|
"help": arg.help,
|
||||||
"nargs": arg.nargs,
|
"nargs": arg.nargs,
|
||||||
"positional": arg.positional,
|
"positional": arg.positional,
|
||||||
"default": arg.default,
|
"suggestions": arg.suggestions,
|
||||||
"help": arg.help,
|
|
||||||
"group": arg.group,
|
"group": arg.group,
|
||||||
"mutex_group": arg.mutex_group,
|
"mutex_group": arg.mutex_group,
|
||||||
}
|
}
|
||||||
@@ -1995,8 +1993,7 @@ class CommandArgumentParser:
|
|||||||
return sorted(set(suggestions))
|
return sorted(set(suggestions))
|
||||||
|
|
||||||
def get_options_text(self) -> str:
|
def get_options_text(self) -> str:
|
||||||
"""
|
"""Render all defined arguments as a help-style string.
|
||||||
Render all defined arguments as a help-style string.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: A visual description of argument flags and structure.
|
str: A visual description of argument flags and structure.
|
||||||
|
|||||||
@@ -1,8 +1,39 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
|
"""Root parsing models and helpers for the Falyx CLI runtime.
|
||||||
|
|
||||||
|
This module defines the minimal parsing layer used before namespace routing and
|
||||||
|
command-local argument parsing begin.
|
||||||
|
|
||||||
|
It provides:
|
||||||
|
|
||||||
|
- `RootOptions`, a lightweight container for session-scoped flags such as
|
||||||
|
verbose logging, help, TLDR, and prompt suppression.
|
||||||
|
- `FalyxParser`, a small root parser that consumes only leading global options
|
||||||
|
from argv and leaves the remaining tokens untouched for downstream routing.
|
||||||
|
|
||||||
|
Unlike `CommandArgumentParser`, this module does not parse command-specific
|
||||||
|
arguments or attempt to resolve leaf-command inputs. Its responsibility is
|
||||||
|
intentionally narrow: identify root-level flags, determine the initial
|
||||||
|
application mode, and normalize the result into a `RootParseResult`.
|
||||||
|
|
||||||
|
Parsing behavior is prefix-based. Root flags are consumed only from the start of
|
||||||
|
argv, and parsing stops at the first non-root token or an explicit `--`
|
||||||
|
separator. This allows the remaining arguments to be preserved exactly for later
|
||||||
|
namespace resolution and command-local parsing.
|
||||||
|
|
||||||
|
Typical flow:
|
||||||
|
1. Raw argv is passed to `FalyxParser.parse()`.
|
||||||
|
2. Leading root/session flags are extracted into `RootOptions`.
|
||||||
|
3. A `RootParseResult` is returned with either:
|
||||||
|
- `FalyxMode.HELP` when root help or TLDR was requested, or
|
||||||
|
- `FalyxMode.COMMAND` when normal routed execution should continue.
|
||||||
|
4. Remaining argv is forwarded unchanged to the main Falyx routing layer.
|
||||||
|
|
||||||
|
This module serves as the root-entry parsing boundary for Falyx applications.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from falyx.mode import FalyxMode
|
from falyx.mode import FalyxMode
|
||||||
from falyx.parser.parse_result import RootParseResult
|
from falyx.parser.parse_result import RootParseResult
|
||||||
@@ -10,6 +41,26 @@ from falyx.parser.parse_result import RootParseResult
|
|||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class RootOptions:
|
class RootOptions:
|
||||||
|
"""Container for root-level Falyx session flags.
|
||||||
|
|
||||||
|
`RootOptions` stores the boolean flags recognized at the application
|
||||||
|
boundary before namespace routing and command-local parsing begin. These
|
||||||
|
values represent session-scoped behavior that applies to the overall Falyx
|
||||||
|
runtime rather than to any individual command.
|
||||||
|
|
||||||
|
The model is intentionally small and lightweight. It is produced by
|
||||||
|
`FalyxParser._parse_root_options()` and then translated into a
|
||||||
|
`RootParseResult` that drives the initial execution mode and runtime
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
verbose: Whether verbose logging should be enabled for the session.
|
||||||
|
debug_hooks: Whether hook execution should be logged in detail.
|
||||||
|
never_prompt: Whether prompts should be suppressed for the session.
|
||||||
|
help: Whether root help output was requested.
|
||||||
|
tldr: Whether root TLDR output was requested.
|
||||||
|
"""
|
||||||
|
|
||||||
verbose: bool = False
|
verbose: bool = False
|
||||||
debug_hooks: bool = False
|
debug_hooks: bool = False
|
||||||
never_prompt: bool = False
|
never_prompt: bool = False
|
||||||
@@ -18,13 +69,38 @@ class RootOptions:
|
|||||||
|
|
||||||
|
|
||||||
class FalyxParser:
|
class FalyxParser:
|
||||||
"""Root parser and command router for Falyx.
|
"""Parse root-level Falyx CLI flags into an initial runtime result.
|
||||||
|
|
||||||
|
`FalyxParser` is the narrow, top-level parser used before namespace routing
|
||||||
|
and command-local argument parsing begin. Its job is to inspect only the
|
||||||
|
leading session-scoped flags in argv, determine the initial application
|
||||||
|
mode, and return a normalized `RootParseResult`.
|
||||||
|
|
||||||
Responsibilities:
|
Responsibilities:
|
||||||
- parse global/root flags
|
- Parse only root/session flags such as verbose logging, help, TLDR,
|
||||||
- resolve built-ins vs registered commands
|
and prompt suppression.
|
||||||
- normalize CLI input into ParseResult
|
- Stop parsing at the first non-root token or explicit `--` separator.
|
||||||
- delegate command-specific parsing to CommandArgumentParser
|
- Preserve the remaining argv exactly for downstream routing.
|
||||||
|
- Translate root help or TLDR requests into `FalyxMode.HELP`.
|
||||||
|
- Translate normal execution into `FalyxMode.COMMAND`.
|
||||||
|
|
||||||
|
Design Notes:
|
||||||
|
- This parser does not resolve commands or namespaces.
|
||||||
|
- This parser does not parse command-specific arguments.
|
||||||
|
- Command-local parsing is delegated later to `CommandArgumentParser`
|
||||||
|
after Falyx routing has identified a leaf command.
|
||||||
|
- Root parsing is intentionally prefix-only so session flags apply at
|
||||||
|
the application boundary without mutating command-local argv.
|
||||||
|
|
||||||
|
Typical Usage:
|
||||||
|
`Falyx.run()` or another top-level entrypoint passes raw argv into
|
||||||
|
`FalyxParser.parse()`, applies the returned session options, and then
|
||||||
|
forwards the untouched remaining argv into the routed Falyx execution
|
||||||
|
flow.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
ROOT_FLAG_ALIASES: Mapping of recognized root CLI flags to
|
||||||
|
`RootOptions` attribute names.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
ROOT_FLAG_ALIASES: dict[str, str] = {
|
ROOT_FLAG_ALIASES: dict[str, str] = {
|
||||||
|
|||||||
@@ -1,4 +1,26 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
|
"""Argument grouping models for the Falyx command argument parser.
|
||||||
|
|
||||||
|
This module defines lightweight dataclasses used by
|
||||||
|
`CommandArgumentParser` to organize arguments into named help sections and
|
||||||
|
mutually exclusive sets.
|
||||||
|
|
||||||
|
It provides:
|
||||||
|
|
||||||
|
- `ArgumentGroup`, which represents a logical collection of related argument
|
||||||
|
destinations for grouped help rendering.
|
||||||
|
- `MutuallyExclusiveGroup`, which represents a set of argument destinations
|
||||||
|
where only one member may be selected, with optional group-level
|
||||||
|
requiredness.
|
||||||
|
|
||||||
|
These models are metadata containers only. They do not perform parsing or
|
||||||
|
validation themselves. Instead, they are populated and enforced by
|
||||||
|
`CommandArgumentParser` during argument registration, parsing, and help
|
||||||
|
generation.
|
||||||
|
|
||||||
|
This module exists to keep argument-group state explicit, structured, and easy
|
||||||
|
to introspect.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
@@ -6,6 +28,22 @@ from dataclasses import dataclass, field
|
|||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class ArgumentGroup:
|
class ArgumentGroup:
|
||||||
|
"""Represents a named group of related command argument destinations.
|
||||||
|
|
||||||
|
`ArgumentGroup` is used by `CommandArgumentParser` to collect arguments that
|
||||||
|
belong together conceptually so they can be rendered under a shared section
|
||||||
|
in help output and tracked as a unit in parser metadata.
|
||||||
|
|
||||||
|
This class stores only grouping metadata and does not implement any parsing
|
||||||
|
behavior on its own.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name: User-facing name of the argument group.
|
||||||
|
description: Optional descriptive text for the group, typically used in
|
||||||
|
help rendering.
|
||||||
|
dests: Destination names of arguments assigned to this group.
|
||||||
|
"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
description: str = ""
|
description: str = ""
|
||||||
dests: list[str] = field(default_factory=list)
|
dests: list[str] = field(default_factory=list)
|
||||||
@@ -13,6 +51,25 @@ class ArgumentGroup:
|
|||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class MutuallyExclusiveGroup:
|
class MutuallyExclusiveGroup:
|
||||||
|
"""Represents a mutually exclusive set of argument destinations.
|
||||||
|
|
||||||
|
`MutuallyExclusiveGroup` is used by `CommandArgumentParser` to model groups
|
||||||
|
of arguments where only one member may be provided at a time. It can also
|
||||||
|
mark the group as required, meaning that exactly one of the grouped
|
||||||
|
arguments must be present.
|
||||||
|
|
||||||
|
This class stores group metadata only. Validation and enforcement are
|
||||||
|
performed by the parser.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name: User-facing name of the mutually exclusive group.
|
||||||
|
required: Whether at least one argument in the group must be supplied.
|
||||||
|
description: Optional descriptive text for the group, typically used in
|
||||||
|
help rendering.
|
||||||
|
dests: Destination names of arguments assigned to this mutually
|
||||||
|
exclusive group.
|
||||||
|
"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
required: bool = False
|
required: bool = False
|
||||||
description: str = ""
|
description: str = ""
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
|
"""Root parse result model for the Falyx CLI runtime.
|
||||||
|
|
||||||
|
This module defines `RootParseResult`, the normalized output produced by the
|
||||||
|
root-level Falyx parsing stage.
|
||||||
|
|
||||||
|
`RootParseResult` captures the session-scoped state derived from the initial
|
||||||
|
CLI parse before namespace routing or command-local argument parsing begins. It
|
||||||
|
records the selected top-level mode, the original argv, root option flags, and
|
||||||
|
any remaining argv that should be forwarded into the routed execution layer.
|
||||||
|
|
||||||
|
This model is typically produced by `FalyxParser.parse()` and then consumed by
|
||||||
|
higher-level Falyx runtime entrypoints such as `Falyx.run()` to configure
|
||||||
|
logging, prompt behavior, help rendering, and routed command dispatch.
|
||||||
|
|
||||||
|
The dataclass is intentionally lightweight and focused on root parsing only. It
|
||||||
|
does not perform parsing, validation, or execution itself.
|
||||||
|
"""
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from falyx.mode import FalyxMode
|
from falyx.mode import FalyxMode
|
||||||
@@ -6,6 +23,28 @@ from falyx.mode import FalyxMode
|
|||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class RootParseResult:
|
class RootParseResult:
|
||||||
|
"""Represents the normalized result of root-level Falyx argument parsing.
|
||||||
|
|
||||||
|
`RootParseResult` stores the outcome of the initial CLI parse that occurs at
|
||||||
|
the application boundary. It separates session-level runtime settings from
|
||||||
|
the remaining argv that should continue into namespace routing and
|
||||||
|
command-local parsing.
|
||||||
|
|
||||||
|
This model is used to communicate root parsing decisions cleanly to the
|
||||||
|
rest of the Falyx runtime, including whether the application should enter
|
||||||
|
help mode or continue with normal command execution.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
mode: Top-level runtime mode selected from the root parse.
|
||||||
|
raw_argv: Original argv passed into the root parser.
|
||||||
|
verbose: Whether verbose logging should be enabled for the session.
|
||||||
|
debug_hooks: Whether hook execution should be logged in detail.
|
||||||
|
never_prompt: Whether prompts should be suppressed for the session.
|
||||||
|
remaining_argv: Unconsumed argv that should be forwarded to routed
|
||||||
|
command resolution.
|
||||||
|
tldr_requested: Whether root TLDR output was requested.
|
||||||
|
"""
|
||||||
|
|
||||||
mode: FalyxMode
|
mode: FalyxMode
|
||||||
raw_argv: list[str] = field(default_factory=list)
|
raw_argv: list[str] = field(default_factory=list)
|
||||||
verbose: bool = False
|
verbose: bool = False
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Type utilities and argument state models for Falyx's custom CLI argument parser.
|
||||||
Type utilities and argument state models for Falyx's custom CLI argument parser.
|
|
||||||
|
|
||||||
This module provides specialized helpers and data structures used by
|
This module provides specialized helpers and data structures used by
|
||||||
the `CommandArgumentParser` to handle non-standard parsing behavior.
|
the `CommandArgumentParser` to handle non-standard parsing behavior.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Provides utilities for introspecting Python callables and extracting argument
|
||||||
Provides utilities for introspecting Python callables and extracting argument
|
|
||||||
metadata compatible with Falyx's `CommandArgumentParser`.
|
metadata compatible with Falyx's `CommandArgumentParser`.
|
||||||
|
|
||||||
This module is primarily used to auto-generate command argument definitions from
|
This module is primarily used to auto-generate command argument definitions from
|
||||||
@@ -20,8 +19,7 @@ def infer_args_from_func(
|
|||||||
func: Callable[[Any], Any] | None,
|
func: Callable[[Any], Any] | None,
|
||||||
arg_metadata: dict[str, str | dict[str, Any]] | None = None,
|
arg_metadata: dict[str, str | dict[str, Any]] | None = None,
|
||||||
) -> list[dict[str, Any]]:
|
) -> list[dict[str, Any]]:
|
||||||
"""
|
"""Infer CLI-style argument definitions from a function signature.
|
||||||
Infer CLI-style argument definitions from a function signature.
|
|
||||||
|
|
||||||
This utility inspects the parameters of a function and returns a list of dictionaries,
|
This utility inspects the parameters of a function and returns a list of dictionaries,
|
||||||
each of which can be passed to `CommandArgumentParser.add_argument()`.
|
each of which can be passed to `CommandArgumentParser.add_argument()`.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Contains value coercion and signature comparison utilities for Falyx argument parsing.
|
||||||
Contains value coercion and signature comparison utilities for Falyx argument parsing.
|
|
||||||
|
|
||||||
This module provides type coercion functions for converting string input into expected
|
This module provides type coercion functions for converting string input into expected
|
||||||
Python types, including `Enum`, `bool`, `datetime`, and `Literal`. It also supports
|
Python types, including `Enum`, `bool`, `datetime`, and `Literal`. It also supports
|
||||||
@@ -25,8 +24,7 @@ from falyx.parser.signature import infer_args_from_func
|
|||||||
|
|
||||||
|
|
||||||
def coerce_bool(value: str) -> bool:
|
def coerce_bool(value: str) -> bool:
|
||||||
"""
|
"""Convert a string to a boolean.
|
||||||
Convert a string to a boolean.
|
|
||||||
|
|
||||||
Accepts various truthy and falsy representations such as 'true', 'yes', '0', 'off', etc.
|
Accepts various truthy and falsy representations such as 'true', 'yes', '0', 'off', etc.
|
||||||
|
|
||||||
@@ -47,8 +45,7 @@ def coerce_bool(value: str) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def coerce_enum(value: Any, enum_type: EnumMeta) -> Any:
|
def coerce_enum(value: Any, enum_type: EnumMeta) -> Any:
|
||||||
"""
|
"""Convert a raw value or string to an Enum instance.
|
||||||
Convert a raw value or string to an Enum instance.
|
|
||||||
|
|
||||||
Tries to resolve by name, value, or coerced base type.
|
Tries to resolve by name, value, or coerced base type.
|
||||||
|
|
||||||
@@ -81,8 +78,7 @@ def coerce_enum(value: Any, enum_type: EnumMeta) -> Any:
|
|||||||
|
|
||||||
|
|
||||||
def coerce_value(value: str, target_type: type) -> Any:
|
def coerce_value(value: str, target_type: type) -> Any:
|
||||||
"""
|
"""Attempt to convert a string to the given target type.
|
||||||
Attempt to convert a string to the given target type.
|
|
||||||
|
|
||||||
Handles complex typing constructs such as Union, Literal, Enum, and datetime.
|
Handles complex typing constructs such as Union, Literal, Enum, and datetime.
|
||||||
|
|
||||||
@@ -133,8 +129,7 @@ def same_argument_definitions(
|
|||||||
actions: list[Any],
|
actions: list[Any],
|
||||||
arg_metadata: dict[str, str | dict[str, Any]] | None = None,
|
arg_metadata: dict[str, str | dict[str, Any]] | None = None,
|
||||||
) -> list[dict[str, Any]] | None:
|
) -> list[dict[str, Any]] | None:
|
||||||
"""
|
"""Determine if multiple callables resolve to the same argument definitions.
|
||||||
Determine if multiple callables resolve to the same argument definitions.
|
|
||||||
|
|
||||||
This is used to infer whether actions in an ActionGroup or ProcessPool can share
|
This is used to infer whether actions in an ActionGroup or ProcessPool can share
|
||||||
a unified argument parser.
|
a unified argument parser.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Utilities for user interaction prompts in the Falyx CLI framework.
|
||||||
Utilities for user interaction prompts in the Falyx CLI framework.
|
|
||||||
|
|
||||||
Provides asynchronous confirmation dialogs and helper logic to determine
|
Provides asynchronous confirmation dialogs and helper logic to determine
|
||||||
whether a user should be prompted based on command-line options.
|
whether a user should be prompted based on command-line options.
|
||||||
@@ -38,6 +37,15 @@ def should_prompt_user(
|
|||||||
flags that may override the need for confirmation, such as `--never-prompt`,
|
flags that may override the need for confirmation, such as `--never-prompt`,
|
||||||
`--force-confirm`, or `--skip-confirm`. The `override_namespace` is checked
|
`--force-confirm`, or `--skip-confirm`. The `override_namespace` is checked
|
||||||
first for any explicit overrides, followed by the main `namespace` for defaults.
|
first for any explicit overrides, followed by the main `namespace` for defaults.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
confirm (bool): The initial confirmation flag (e.g., from a command argument).
|
||||||
|
options (OptionsManager): The options manager to check for override flags.
|
||||||
|
namespace (str): The primary namespace to check for options (default: "default").
|
||||||
|
override_namespace (str): The secondary namespace for overrides (default: "execution").
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if the user should be prompted, False if confirmation can be bypassed.
|
||||||
"""
|
"""
|
||||||
never_prompt = options.get("never_prompt", None, override_namespace)
|
never_prompt = options.get("never_prompt", None, override_namespace)
|
||||||
if never_prompt is None:
|
if never_prompt is None:
|
||||||
@@ -74,9 +82,16 @@ async def confirm_async(
|
|||||||
|
|
||||||
|
|
||||||
def rich_text_to_prompt_text(text: Text | str | StyleAndTextTuples) -> StyleAndTextTuples:
|
def rich_text_to_prompt_text(text: Text | str | StyleAndTextTuples) -> StyleAndTextTuples:
|
||||||
"""
|
"""Convert a Rich Text object to prompt_toolkit formatted text.
|
||||||
Convert a Rich Text object to a list of (style, text) tuples
|
|
||||||
compatible with prompt_toolkit.
|
This function takes a Rich `Text` object (or a string or already formatted text)
|
||||||
|
and converts it in to a list of (style, text) tuples compatible with prompt_toolkit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
text (Text | str | StyleAndTextTuples): The input text to convert.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
StyleAndTextTuples: A list of (style, text) tuples for prompt_toolkit.
|
||||||
"""
|
"""
|
||||||
if isinstance(text, list):
|
if isinstance(text, list):
|
||||||
if all(isinstance(pair, tuple) and len(pair) == 2 for pair in text):
|
if all(isinstance(pair, tuple) and len(pair) == 2 for pair in text):
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines structural protocols for advanced Falyx features.
|
||||||
Defines structural protocols for advanced Falyx features.
|
|
||||||
|
|
||||||
These runtime-checkable `Protocol` classes specify the expected interfaces for:
|
These runtime-checkable `Protocol` classes specify the expected interfaces for:
|
||||||
- Factories that asynchronously return actions
|
- Factories that asynchronously return actions
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Implements retry logic for Falyx Actions using configurable retry policies.
|
||||||
Implements retry logic for Falyx Actions using configurable retry policies.
|
|
||||||
|
|
||||||
This module defines:
|
This module defines:
|
||||||
- `RetryPolicy`: A configurable model controlling retry behavior (delay, backoff, jitter).
|
- `RetryPolicy`: A configurable model controlling retry behavior (delay, backoff, jitter).
|
||||||
@@ -30,8 +29,7 @@ from falyx.logger import logger
|
|||||||
|
|
||||||
|
|
||||||
class RetryPolicy(BaseModel):
|
class RetryPolicy(BaseModel):
|
||||||
"""
|
"""Defines a retry strategy for Falyx `Action` objects.
|
||||||
Defines a retry strategy for Falyx `Action` objects.
|
|
||||||
|
|
||||||
This model controls whether an action should be retried on failure, and how:
|
This model controls whether an action should be retried on failure, and how:
|
||||||
- `max_retries`: Maximum number of retry attempts.
|
- `max_retries`: Maximum number of retry attempts.
|
||||||
@@ -60,23 +58,16 @@ class RetryPolicy(BaseModel):
|
|||||||
enabled: bool = False
|
enabled: bool = False
|
||||||
|
|
||||||
def enable_policy(self) -> None:
|
def enable_policy(self) -> None:
|
||||||
"""
|
"""Enable the retry policy."""
|
||||||
Enable the retry policy.
|
|
||||||
:return: None
|
|
||||||
"""
|
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
|
||||||
def is_active(self) -> bool:
|
def is_active(self) -> bool:
|
||||||
"""
|
"""Check if the retry policy is active."""
|
||||||
Check if the retry policy is active.
|
|
||||||
:return: True if the retry policy is active, False otherwise.
|
|
||||||
"""
|
|
||||||
return self.max_retries > 0 and self.enabled
|
return self.max_retries > 0 and self.enabled
|
||||||
|
|
||||||
|
|
||||||
class RetryHandler:
|
class RetryHandler:
|
||||||
"""
|
"""Executes retry logic for Falyx actions using a provided `RetryPolicy`.
|
||||||
Executes retry logic for Falyx actions using a provided `RetryPolicy`.
|
|
||||||
|
|
||||||
This class is intended to be registered as an `on_error` hook. It will
|
This class is intended to be registered as an `on_error` hook. It will
|
||||||
re-attempt the failed `Action`'s `action` method using the args/kwargs from
|
re-attempt the failed `Action`'s `action` method using the args/kwargs from
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Utilities for enabling retry behavior across Falyx actions.
|
||||||
Utilities for enabling retry behavior across Falyx actions.
|
|
||||||
|
|
||||||
This module provides a helper to recursively apply a `RetryPolicy` to an action and its
|
This module provides a helper to recursively apply a `RetryPolicy` to an action and its
|
||||||
nested children (e.g. `ChainedAction`, `ActionGroup`), and register the appropriate
|
nested children (e.g. `ChainedAction`, `ActionGroup`), and register the appropriate
|
||||||
|
|||||||
@@ -1,3 +1,24 @@
|
|||||||
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
|
"""Routing result models for the Falyx CLI framework.
|
||||||
|
|
||||||
|
This module defines the core types used to describe the outcome of namespace
|
||||||
|
routing in a `Falyx` application.
|
||||||
|
|
||||||
|
It provides:
|
||||||
|
|
||||||
|
- `RouteKind`, an enum describing the kind of routed target that was reached,
|
||||||
|
such as a leaf command, namespace help, namespace TLDR, namespace menu, or
|
||||||
|
an unknown entry.
|
||||||
|
- `RouteResult`, a structured value object that captures the resolved routing
|
||||||
|
state, including the active namespace, invocation context, optional leaf
|
||||||
|
command, remaining argv for command-local parsing, and any suggestions for
|
||||||
|
unresolved input.
|
||||||
|
|
||||||
|
These types sit at the boundary between routing and execution. They do not
|
||||||
|
perform routing themselves. Instead, they are produced by Falyx routing logic
|
||||||
|
and then consumed by help rendering, completion, validation, preview, and
|
||||||
|
command dispatch flows.
|
||||||
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
@@ -13,6 +34,21 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class RouteKind(Enum):
|
class RouteKind(Enum):
|
||||||
|
"""Enumerates the possible outcomes of Falyx namespace routing.
|
||||||
|
|
||||||
|
`RouteKind` identifies what the routing layer resolved the current input
|
||||||
|
to, allowing downstream code to decide whether it should execute a command,
|
||||||
|
render namespace help, show TLDR output, display a namespace menu, or
|
||||||
|
surface an unknown-entry message.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
COMMAND: Routing reached a leaf command that may be parsed and executed.
|
||||||
|
NAMESPACE_MENU: Routing stopped at a namespace menu target.
|
||||||
|
NAMESPACE_HELP: Routing resolved to namespace help output.
|
||||||
|
NAMESPACE_TLDR: Routing resolved to namespace TLDR output.
|
||||||
|
UNKNOWN: Routing failed to resolve the requested entry.
|
||||||
|
"""
|
||||||
|
|
||||||
COMMAND = "command"
|
COMMAND = "command"
|
||||||
NAMESPACE_MENU = "namespace_menu"
|
NAMESPACE_MENU = "namespace_menu"
|
||||||
NAMESPACE_HELP = "namespace_help"
|
NAMESPACE_HELP = "namespace_help"
|
||||||
@@ -22,6 +58,30 @@ class RouteKind(Enum):
|
|||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class RouteResult:
|
class RouteResult:
|
||||||
|
"""Represents the resolved output of a Falyx routing operation.
|
||||||
|
|
||||||
|
`RouteResult` captures the full state needed after namespace resolution
|
||||||
|
completes and before command execution or help rendering begins. It records
|
||||||
|
what kind of target was reached, where routing ended, the invocation path
|
||||||
|
used to reach it, and any leaf-command metadata needed for downstream
|
||||||
|
parsing.
|
||||||
|
|
||||||
|
This model is used by Falyx execution, help, preview, completion, and
|
||||||
|
validation flows to make routing decisions explicit and easy to inspect.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
kind: The type of routed result that was resolved.
|
||||||
|
namespace: The `Falyx` namespace where routing ended.
|
||||||
|
context: Invocation context describing the routed path and current mode.
|
||||||
|
command: Resolved leaf command, if routing ended at a command.
|
||||||
|
namespace_entry: Resolved namespace entry, if the route corresponds to a
|
||||||
|
specific nested namespace.
|
||||||
|
leaf_argv: Remaining argv that should be delegated to the resolved
|
||||||
|
command's local parser.
|
||||||
|
suggestions: Suggested entry names for unresolved input.
|
||||||
|
is_preview: Whether the routed invocation is in preview mode.
|
||||||
|
"""
|
||||||
|
|
||||||
kind: RouteKind
|
kind: RouteKind
|
||||||
namespace: "Falyx"
|
namespace: "Falyx"
|
||||||
context: InvocationContext
|
context: InvocationContext
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Provides interactive selection utilities for Falyx CLI actions.
|
||||||
Provides interactive selection utilities for Falyx CLI actions.
|
|
||||||
|
|
||||||
This module defines `SelectionOption` objects, selection maps, and rich-powered
|
This module defines `SelectionOption` objects, selection maps, and rich-powered
|
||||||
rendering functions to build interactive selection prompts using `prompt_toolkit`.
|
rendering functions to build interactive selection prompts using `prompt_toolkit`.
|
||||||
@@ -46,9 +45,7 @@ class SelectionOption:
|
|||||||
|
|
||||||
|
|
||||||
class SelectionOptionMap(CaseInsensitiveDict):
|
class SelectionOptionMap(CaseInsensitiveDict):
|
||||||
"""
|
"""Manages selection options including validation and reserved key protection."""
|
||||||
Manages selection options including validation and reserved key protection.
|
|
||||||
"""
|
|
||||||
|
|
||||||
RESERVED_KEYS: set[str] = set()
|
RESERVED_KEYS: set[str] = set()
|
||||||
|
|
||||||
@@ -118,6 +115,7 @@ def render_table_base(
|
|||||||
highlight: bool = True,
|
highlight: bool = True,
|
||||||
column_names: Sequence[str] | None = None,
|
column_names: Sequence[str] | None = None,
|
||||||
) -> Table:
|
) -> Table:
|
||||||
|
"""Render the base table for selection prompts."""
|
||||||
table = Table(
|
table = Table(
|
||||||
title=title,
|
title=title,
|
||||||
caption=caption,
|
caption=caption,
|
||||||
@@ -288,6 +286,7 @@ async def prompt_for_index(
|
|||||||
allow_duplicates: bool = False,
|
allow_duplicates: bool = False,
|
||||||
cancel_key: str = "",
|
cancel_key: str = "",
|
||||||
) -> int | list[int]:
|
) -> int | list[int]:
|
||||||
|
"""Prompt the user to select an index from a table of options. Return the selected index."""
|
||||||
prompt_session = prompt_session or PromptSession()
|
prompt_session = prompt_session or PromptSession()
|
||||||
|
|
||||||
if show_table:
|
if show_table:
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Defines flow control signals used internally by the Falyx CLI framework.
|
||||||
Defines flow control signals used internally by the Falyx CLI framework.
|
|
||||||
|
|
||||||
These signals are raised to interrupt or redirect CLI execution flow
|
These signals are raised to interrupt or redirect CLI execution flow
|
||||||
(e.g., returning to a menu, quitting, or displaying help) without
|
(e.g., returning to a menu, quitting, or displaying help) without
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Centralized spinner rendering for Falyx CLI.
|
||||||
Centralized spinner rendering for Falyx CLI.
|
|
||||||
|
|
||||||
This module provides the `SpinnerManager` class, which manages a collection of
|
This module provides the `SpinnerManager` class, which manages a collection of
|
||||||
Rich spinners that can be displayed concurrently during long-running tasks.
|
Rich spinners that can be displayed concurrently during long-running tasks.
|
||||||
@@ -55,8 +54,7 @@ from falyx.themes import OneColors
|
|||||||
|
|
||||||
|
|
||||||
class SpinnerData:
|
class SpinnerData:
|
||||||
"""
|
"""Holds the configuration and Rich spinner object for a single task.
|
||||||
Holds the configuration and Rich spinner object for a single task.
|
|
||||||
|
|
||||||
This class is a lightweight container for spinner metadata, storing the
|
This class is a lightweight container for spinner metadata, storing the
|
||||||
message text, spinner type, style, and speed. It also initializes the
|
message text, spinner type, style, and speed. It also initializes the
|
||||||
@@ -92,8 +90,7 @@ class SpinnerData:
|
|||||||
|
|
||||||
|
|
||||||
class SpinnerManager:
|
class SpinnerManager:
|
||||||
"""
|
"""Manages multiple Rich spinners and handles their terminal rendering.
|
||||||
Manages multiple Rich spinners and handles their terminal rendering.
|
|
||||||
|
|
||||||
SpinnerManager maintains a registry of active spinners and a single
|
SpinnerManager maintains a registry of active spinners and a single
|
||||||
Rich `Live` display loop to render them. When the first spinner is added,
|
Rich `Live` display loop to render them. When the first spinner is added,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Generates a Rich table view of Falyx commands grouped by their tags.
|
||||||
Generates a Rich table view of Falyx commands grouped by their tags.
|
|
||||||
|
|
||||||
This module defines a utility function for rendering a custom CLI command
|
This module defines a utility function for rendering a custom CLI command
|
||||||
table that organizes commands into groups based on their first tag. It is
|
table that organizes commands into groups based on their first tag. It is
|
||||||
@@ -37,7 +36,7 @@ def build_tagged_table(flx: Falyx) -> Table:
|
|||||||
table.add_row("")
|
table.add_row("")
|
||||||
|
|
||||||
# Add bottom row
|
# Add bottom row
|
||||||
for row in flx.get_bottom_row():
|
for row in flx._get_bottom_row():
|
||||||
table.add_row(row)
|
table.add_row(row)
|
||||||
|
|
||||||
return table
|
return table
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
"""
|
"""Falyx CLI Framework
|
||||||
Falyx CLI Framework
|
|
||||||
|
|
||||||
Copyright (c) 2025 rtj.dev LLC.
|
Copyright (c) 2026 rtj.dev LLC.
|
||||||
Licensed under the MIT License. See LICENSE file for details.
|
Licensed under the MIT License. See LICENSE file for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""A Python module that integrates the Nord color palette with the Rich library.
|
||||||
A Python module that integrates the Nord color palette with the Rich library.
|
|
||||||
It defines a metaclass-based NordColors class allowing dynamic attribute lookups
|
It defines a metaclass-based NordColors class allowing dynamic attribute lookups
|
||||||
(e.g., NORD12bu -> "#D08770 bold underline") and provides a comprehensive Nord-based
|
(e.g., NORD12bu -> "#D08770 bold underline") and provides a comprehensive Nord-based
|
||||||
Theme that customizes Rich's default styles.
|
Theme that customizes Rich's default styles.
|
||||||
@@ -26,8 +25,7 @@ from rich.theme import Theme
|
|||||||
|
|
||||||
|
|
||||||
class ColorsMeta(type):
|
class ColorsMeta(type):
|
||||||
"""
|
"""A metaclass that catches attribute lookups like `NORD12buidrs` or `ORANGE_b` and returns
|
||||||
A metaclass that catches attribute lookups like `NORD12buidrs` or `ORANGE_b` and returns
|
|
||||||
a string combining the base color + bold/italic/underline/dim/reverse/strike flags.
|
a string combining the base color + bold/italic/underline/dim/reverse/strike flags.
|
||||||
|
|
||||||
The color values are required to be uppercase with optional underscores and digits,
|
The color values are required to be uppercase with optional underscores and digits,
|
||||||
@@ -152,8 +150,7 @@ class OneColors(metaclass=ColorsMeta):
|
|||||||
|
|
||||||
|
|
||||||
class NordColors(metaclass=ColorsMeta):
|
class NordColors(metaclass=ColorsMeta):
|
||||||
"""
|
"""Defines the Nord color palette as class attributes.
|
||||||
Defines the Nord color palette as class attributes.
|
|
||||||
|
|
||||||
Each color is labeled by its canonical Nord name (NORD0-NORD15)
|
Each color is labeled by its canonical Nord name (NORD0-NORD15)
|
||||||
and also has useful aliases grouped by theme:
|
and also has useful aliases grouped by theme:
|
||||||
@@ -212,8 +209,7 @@ class NordColors(metaclass=ColorsMeta):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def as_dict(cls):
|
def as_dict(cls):
|
||||||
"""
|
"""Returns a dictionary mapping every NORD* attribute
|
||||||
Returns a dictionary mapping every NORD* attribute
|
|
||||||
(e.g. 'NORD0') to its hex code.
|
(e.g. 'NORD0') to its hex code.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
@@ -224,8 +220,7 @@ class NordColors(metaclass=ColorsMeta):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def aliases(cls):
|
def aliases(cls):
|
||||||
"""
|
"""Returns a dictionary of *all* other aliases
|
||||||
Returns a dictionary of *all* other aliases
|
|
||||||
(Polar Night, Snow Storm, Frost, Aurora).
|
(Polar Night, Snow Storm, Frost, Aurora).
|
||||||
"""
|
"""
|
||||||
skip_prefixes = ("NORD", "__")
|
skip_prefixes = ("NORD", "__")
|
||||||
@@ -462,9 +457,7 @@ NORD_THEME_STYLES: dict[str, Style] = {
|
|||||||
|
|
||||||
|
|
||||||
def get_nord_theme() -> Theme:
|
def get_nord_theme() -> Theme:
|
||||||
"""
|
"""Returns a Rich Theme for the Nord color palette."""
|
||||||
Returns a Rich Theme for the Nord color palette.
|
|
||||||
"""
|
|
||||||
return Theme(NORD_THEME_STYLES)
|
return Theme(NORD_THEME_STYLES)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""General-purpose utilities and helpers for the Falyx CLI framework.
|
||||||
General-purpose utilities and helpers for the Falyx CLI framework.
|
|
||||||
|
|
||||||
This module includes asynchronous wrappers, logging setup, formatting utilities,
|
This module includes asynchronous wrappers, logging setup, formatting utilities,
|
||||||
and small type-safe enhancements such as `CaseInsensitiveDict` and coroutine enforcement.
|
and small type-safe enhancements such as `CaseInsensitiveDict` and coroutine enforcement.
|
||||||
@@ -130,8 +129,7 @@ def setup_logging(
|
|||||||
file_log_level: int = logging.DEBUG,
|
file_log_level: int = logging.DEBUG,
|
||||||
console_log_level: int = logging.WARNING,
|
console_log_level: int = logging.WARNING,
|
||||||
):
|
):
|
||||||
"""
|
"""Configure logging for Falyx with support for both CLI-friendly and structured
|
||||||
Configure logging for Falyx with support for both CLI-friendly and structured
|
|
||||||
JSON output.
|
JSON output.
|
||||||
|
|
||||||
This function sets up separate logging handlers for console and file output,
|
This function sets up separate logging handlers for console and file output,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
# Falyx CLI Framework — (c) 2026 rtj.dev LLC — MIT Licensed
|
||||||
"""
|
"""Input validators for use with Prompt Toolkit and interactive Falyx CLI workflows.
|
||||||
Input validators for use with Prompt Toolkit and interactive Falyx CLI workflows.
|
|
||||||
|
|
||||||
This module defines reusable `Validator` instances and subclasses that enforce valid
|
This module defines reusable `Validator` instances and subclasses that enforce valid
|
||||||
user input during prompts—especially for selection actions, confirmations, and
|
user input during prompts—especially for selection actions, confirmations, and
|
||||||
@@ -152,6 +151,8 @@ def word_validator(word: str) -> Validator:
|
|||||||
|
|
||||||
|
|
||||||
class MultiIndexValidator(Validator):
|
class MultiIndexValidator(Validator):
|
||||||
|
"""Validator for multiple index selections (e.g. '1,2,3')."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
minimum: int,
|
minimum: int,
|
||||||
@@ -202,6 +203,8 @@ class MultiIndexValidator(Validator):
|
|||||||
|
|
||||||
|
|
||||||
class MultiKeyValidator(Validator):
|
class MultiKeyValidator(Validator):
|
||||||
|
"""Validator for multiple key selections (e.g. 'A,B,C')."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
keys: Sequence[str] | KeysView[str],
|
keys: Sequence[str] | KeysView[str],
|
||||||
|
|||||||
Reference in New Issue
Block a user