falyx 0.1.52__py3-none-any.whl → 0.1.53__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
falyx/action/__init__.py CHANGED
@@ -8,7 +8,7 @@ Licensed under the MIT License. See LICENSE file for details.
8
8
  from .action import Action
9
9
  from .action_factory import ActionFactoryAction
10
10
  from .action_group import ActionGroup
11
- from .base import BaseAction
11
+ from .base_action import BaseAction
12
12
  from .chained_action import ChainedAction
13
13
  from .fallback_action import FallbackAction
14
14
  from .http_action import HTTPAction
falyx/action/action.py CHANGED
@@ -6,7 +6,7 @@ from typing import Any, Callable
6
6
 
7
7
  from rich.tree import Tree
8
8
 
9
- from falyx.action.base import BaseAction
9
+ from falyx.action.base_action import BaseAction
10
10
  from falyx.context import ExecutionContext
11
11
  from falyx.execution_registry import ExecutionRegistry as er
12
12
  from falyx.hook_manager import HookManager, HookType
@@ -4,7 +4,7 @@ from typing import Any, Callable
4
4
 
5
5
  from rich.tree import Tree
6
6
 
7
- from falyx.action.base import BaseAction
7
+ from falyx.action.base_action import BaseAction
8
8
  from falyx.context import ExecutionContext
9
9
  from falyx.execution_registry import ExecutionRegistry as er
10
10
  from falyx.hook_manager import HookType
@@ -2,12 +2,12 @@
2
2
  """action_group.py"""
3
3
  import asyncio
4
4
  import random
5
- from typing import Any, Callable
5
+ from typing import Any, Callable, Sequence
6
6
 
7
7
  from rich.tree import Tree
8
8
 
9
9
  from falyx.action.action import Action
10
- from falyx.action.base import BaseAction
10
+ from falyx.action.base_action import BaseAction
11
11
  from falyx.action.mixins import ActionListMixin
12
12
  from falyx.context import ExecutionContext, SharedContext
13
13
  from falyx.execution_registry import ExecutionRegistry as er
@@ -54,7 +54,7 @@ class ActionGroup(BaseAction, ActionListMixin):
54
54
  def __init__(
55
55
  self,
56
56
  name: str,
57
- actions: list[BaseAction] | None = None,
57
+ actions: Sequence[BaseAction | Callable[..., Any]] | None = None,
58
58
  *,
59
59
  hooks: HookManager | None = None,
60
60
  inject_last_result: bool = False,
@@ -70,7 +70,7 @@ class ActionGroup(BaseAction, ActionListMixin):
70
70
  if actions:
71
71
  self.set_actions(actions)
72
72
 
73
- def _wrap_if_needed(self, action: BaseAction | Any) -> BaseAction:
73
+ def _wrap_if_needed(self, action: BaseAction | Callable[..., Any]) -> BaseAction:
74
74
  if isinstance(action, BaseAction):
75
75
  return action
76
76
  elif callable(action):
@@ -81,12 +81,18 @@ class ActionGroup(BaseAction, ActionListMixin):
81
81
  f"{type(action).__name__}"
82
82
  )
83
83
 
84
- def add_action(self, action: BaseAction | Any) -> None:
84
+ def add_action(self, action: BaseAction | Callable[..., Any]) -> None:
85
85
  action = self._wrap_if_needed(action)
86
86
  super().add_action(action)
87
87
  if hasattr(action, "register_teardown") and callable(action.register_teardown):
88
88
  action.register_teardown(self.hooks)
89
89
 
90
+ def set_actions(self, actions: Sequence[BaseAction | Callable[..., Any]]) -> None:
91
+ """Replaces the current action list with a new one."""
92
+ self.actions.clear()
93
+ for action in actions:
94
+ self.add_action(action)
95
+
90
96
  def get_infer_target(self) -> tuple[Callable[..., Any] | None, dict[str, Any] | None]:
91
97
  arg_defs = same_argument_definitions(self.actions)
92
98
  if arg_defs:
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  from enum import Enum
6
6
 
7
7
 
8
- class FileReturnType(Enum):
8
+ class FileType(Enum):
9
9
  """Enum for file return types."""
10
10
 
11
11
  TEXT = "text"
@@ -28,7 +28,7 @@ class FileReturnType(Enum):
28
28
  return aliases.get(value, value)
29
29
 
30
30
  @classmethod
31
- def _missing_(cls, value: object) -> FileReturnType:
31
+ def _missing_(cls, value: object) -> FileType:
32
32
  if isinstance(value, str):
33
33
  normalized = value.lower()
34
34
  alias = cls._get_alias(normalized)
@@ -36,7 +36,7 @@ class FileReturnType(Enum):
36
36
  if member.value == alias:
37
37
  return member
38
38
  valid = ", ".join(member.value for member in cls)
39
- raise ValueError(f"Invalid FileReturnType: '{value}'. Must be one of: {valid}")
39
+ raise ValueError(f"Invalid FileType: '{value}'. Must be one of: {valid}")
40
40
 
41
41
 
42
42
  class SelectionReturnType(Enum):
@@ -1,5 +1,5 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
- """base.py
2
+ """base_action.py
3
3
 
4
4
  Core action system for Falyx.
5
5
 
@@ -2,12 +2,12 @@
2
2
  """chained_action.py"""
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Any, Callable
5
+ from typing import Any, Callable, Sequence
6
6
 
7
7
  from rich.tree import Tree
8
8
 
9
9
  from falyx.action.action import Action
10
- from falyx.action.base import BaseAction
10
+ from falyx.action.base_action import BaseAction
11
11
  from falyx.action.fallback_action import FallbackAction
12
12
  from falyx.action.literal_input_action import LiteralInputAction
13
13
  from falyx.action.mixins import ActionListMixin
@@ -47,7 +47,7 @@ class ChainedAction(BaseAction, ActionListMixin):
47
47
  def __init__(
48
48
  self,
49
49
  name: str,
50
- actions: list[BaseAction | Any] | None = None,
50
+ actions: Sequence[BaseAction | Callable[..., Any]] | None = None,
51
51
  *,
52
52
  hooks: HookManager | None = None,
53
53
  inject_last_result: bool = False,
@@ -67,7 +67,7 @@ class ChainedAction(BaseAction, ActionListMixin):
67
67
  if actions:
68
68
  self.set_actions(actions)
69
69
 
70
- def _wrap_if_needed(self, action: BaseAction | Any) -> BaseAction:
70
+ def _wrap_if_needed(self, action: BaseAction | Callable[..., Any]) -> BaseAction:
71
71
  if isinstance(action, BaseAction):
72
72
  return action
73
73
  elif callable(action):
@@ -75,7 +75,7 @@ class ChainedAction(BaseAction, ActionListMixin):
75
75
  else:
76
76
  return LiteralInputAction(action)
77
77
 
78
- def add_action(self, action: BaseAction | Any) -> None:
78
+ def add_action(self, action: BaseAction | Callable[..., Any]) -> None:
79
79
  action = self._wrap_if_needed(action)
80
80
  if self.actions and self.auto_inject and not action.inject_last_result:
81
81
  action.inject_last_result = True
@@ -83,6 +83,12 @@ class ChainedAction(BaseAction, ActionListMixin):
83
83
  if hasattr(action, "register_teardown") and callable(action.register_teardown):
84
84
  action.register_teardown(self.hooks)
85
85
 
86
+ def set_actions(self, actions: Sequence[BaseAction | Callable[..., Any]]) -> None:
87
+ """Replaces the current action list with a new one."""
88
+ self.actions.clear()
89
+ for action in actions:
90
+ self.add_action(action)
91
+
86
92
  def get_infer_target(self) -> tuple[Callable[..., Any] | None, dict[str, Any] | None]:
87
93
  if self.actions:
88
94
  return self.actions[0].get_infer_target()
falyx/action/io_action.py CHANGED
@@ -21,7 +21,7 @@ from typing import Any, Callable
21
21
 
22
22
  from rich.tree import Tree
23
23
 
24
- from falyx.action.base import BaseAction
24
+ from falyx.action.base_action import BaseAction
25
25
  from falyx.context import ExecutionContext
26
26
  from falyx.execution_registry import ExecutionRegistry as er
27
27
  from falyx.hook_manager import HookManager, HookType
@@ -0,0 +1,28 @@
1
+ # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
+ """load_file_action.py"""
3
+ from pathlib import Path
4
+
5
+ from rich.tree import Tree
6
+
7
+ from falyx.action.base_action import BaseAction
8
+
9
+
10
+ class LoadFileAction(BaseAction):
11
+ """ """
12
+
13
+ def __init__(self, name: str, file_path: str):
14
+ super().__init__(name=name)
15
+ self.file_path = file_path
16
+
17
+ def get_infer_target(self) -> tuple[None, None]:
18
+ return None, None
19
+
20
+ async def _run(self, *args, **kwargs):
21
+ raise NotImplementedError(
22
+ "LoadFileAction is not finished yet... Use primatives instead..."
23
+ )
24
+
25
+ async def preview(self, parent: Tree | None = None): ...
26
+
27
+ def __str__(self) -> str:
28
+ return f"LoadFileAction(file_path={self.file_path})"
@@ -7,7 +7,7 @@ from rich.console import Console
7
7
  from rich.table import Table
8
8
  from rich.tree import Tree
9
9
 
10
- from falyx.action.base import BaseAction
10
+ from falyx.action.base_action import BaseAction
11
11
  from falyx.context import ExecutionContext
12
12
  from falyx.execution_registry import ExecutionRegistry as er
13
13
  from falyx.hook_manager import HookType
falyx/action/mixins.py CHANGED
@@ -1,6 +1,8 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
2
  """mixins.py"""
3
- from falyx.action.base import BaseAction
3
+ from typing import Sequence
4
+
5
+ from falyx.action.base_action import BaseAction
4
6
 
5
7
 
6
8
  class ActionListMixin:
@@ -9,7 +11,7 @@ class ActionListMixin:
9
11
  def __init__(self) -> None:
10
12
  self.actions: list[BaseAction] = []
11
13
 
12
- def set_actions(self, actions: list[BaseAction]) -> None:
14
+ def set_actions(self, actions: Sequence[BaseAction]) -> None:
13
15
  """Replaces the current action list with a new one."""
14
16
  self.actions.clear()
15
17
  for action in actions:
@@ -9,7 +9,7 @@ from typing import Any, Callable
9
9
 
10
10
  from rich.tree import Tree
11
11
 
12
- from falyx.action.base import BaseAction
12
+ from falyx.action.base_action import BaseAction
13
13
  from falyx.context import ExecutionContext
14
14
  from falyx.execution_registry import ExecutionRegistry as er
15
15
  from falyx.hook_manager import HookManager, HookType
@@ -11,7 +11,7 @@ from typing import Any, Callable
11
11
 
12
12
  from rich.tree import Tree
13
13
 
14
- from falyx.action.base import BaseAction
14
+ from falyx.action.base_action import BaseAction
15
15
  from falyx.context import ExecutionContext, SharedContext
16
16
  from falyx.execution_registry import ExecutionRegistry as er
17
17
  from falyx.hook_manager import HookManager, HookType
@@ -7,7 +7,7 @@ from prompt_toolkit.formatted_text import FormattedText, merge_formatted_text
7
7
  from rich.console import Console
8
8
  from rich.tree import Tree
9
9
 
10
- from falyx.action.base import BaseAction
10
+ from falyx.action.base_action import BaseAction
11
11
  from falyx.context import ExecutionContext
12
12
  from falyx.execution_registry import ExecutionRegistry as er
13
13
  from falyx.hook_manager import HookType
@@ -0,0 +1,28 @@
1
+ # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
+ """save_file_action.py"""
3
+ from pathlib import Path
4
+
5
+ from rich.tree import Tree
6
+
7
+ from falyx.action.base_action import BaseAction
8
+
9
+
10
+ class SaveFileAction(BaseAction):
11
+ """ """
12
+
13
+ def __init__(self, name: str, file_path: str):
14
+ super().__init__(name=name)
15
+ self.file_path = file_path
16
+
17
+ def get_infer_target(self) -> tuple[None, None]:
18
+ return None, None
19
+
20
+ async def _run(self, *args, **kwargs):
21
+ raise NotImplementedError(
22
+ "SaveFileAction is not finished yet... Use primitives instead..."
23
+ )
24
+
25
+ async def preview(self, parent: Tree | None = None): ...
26
+
27
+ def __str__(self) -> str:
28
+ return f"SaveFileAction(file_path={self.file_path})"
@@ -14,8 +14,8 @@ from prompt_toolkit import PromptSession
14
14
  from rich.console import Console
15
15
  from rich.tree import Tree
16
16
 
17
- from falyx.action.base import BaseAction
18
- from falyx.action.types import FileReturnType
17
+ from falyx.action.action_types import FileType
18
+ from falyx.action.base_action import BaseAction
19
19
  from falyx.context import ExecutionContext
20
20
  from falyx.execution_registry import ExecutionRegistry as er
21
21
  from falyx.hook_manager import HookType
@@ -50,7 +50,7 @@ class SelectFileAction(BaseAction):
50
50
  prompt_message (str): Message to display when prompting for selection.
51
51
  style (str): Style for the selection options.
52
52
  suffix_filter (str | None): Restrict to certain file types.
53
- return_type (FileReturnType): What to return (path, content, parsed).
53
+ return_type (FileType): What to return (path, content, parsed).
54
54
  console (Console | None): Console instance for output.
55
55
  prompt_session (PromptSession | None): Prompt session for user input.
56
56
  """
@@ -65,7 +65,7 @@ class SelectFileAction(BaseAction):
65
65
  prompt_message: str = "Choose > ",
66
66
  style: str = OneColors.WHITE,
67
67
  suffix_filter: str | None = None,
68
- return_type: FileReturnType | str = FileReturnType.PATH,
68
+ return_type: FileType | str = FileType.PATH,
69
69
  number_selections: int | str = 1,
70
70
  separator: str = ",",
71
71
  allow_duplicates: bool = False,
@@ -104,35 +104,35 @@ class SelectFileAction(BaseAction):
104
104
  else:
105
105
  raise ValueError("number_selections must be a positive integer or one of '*'")
106
106
 
107
- def _coerce_return_type(self, return_type: FileReturnType | str) -> FileReturnType:
108
- if isinstance(return_type, FileReturnType):
107
+ def _coerce_return_type(self, return_type: FileType | str) -> FileType:
108
+ if isinstance(return_type, FileType):
109
109
  return return_type
110
- return FileReturnType(return_type)
110
+ return FileType(return_type)
111
111
 
112
112
  def get_options(self, files: list[Path]) -> dict[str, SelectionOption]:
113
113
  value: Any
114
114
  options = {}
115
115
  for index, file in enumerate(files):
116
116
  try:
117
- if self.return_type == FileReturnType.TEXT:
117
+ if self.return_type == FileType.TEXT:
118
118
  value = file.read_text(encoding="UTF-8")
119
- elif self.return_type == FileReturnType.PATH:
119
+ elif self.return_type == FileType.PATH:
120
120
  value = file
121
- elif self.return_type == FileReturnType.JSON:
121
+ elif self.return_type == FileType.JSON:
122
122
  value = json.loads(file.read_text(encoding="UTF-8"))
123
- elif self.return_type == FileReturnType.TOML:
123
+ elif self.return_type == FileType.TOML:
124
124
  value = toml.loads(file.read_text(encoding="UTF-8"))
125
- elif self.return_type == FileReturnType.YAML:
125
+ elif self.return_type == FileType.YAML:
126
126
  value = yaml.safe_load(file.read_text(encoding="UTF-8"))
127
- elif self.return_type == FileReturnType.CSV:
127
+ elif self.return_type == FileType.CSV:
128
128
  with open(file, newline="", encoding="UTF-8") as csvfile:
129
129
  reader = csv.reader(csvfile)
130
130
  value = list(reader)
131
- elif self.return_type == FileReturnType.TSV:
131
+ elif self.return_type == FileType.TSV:
132
132
  with open(file, newline="", encoding="UTF-8") as tsvfile:
133
133
  reader = csv.reader(tsvfile, delimiter="\t")
134
134
  value = list(reader)
135
- elif self.return_type == FileReturnType.XML:
135
+ elif self.return_type == FileType.XML:
136
136
  tree = ET.parse(file, parser=ET.XMLParser(encoding="UTF-8"))
137
137
  root = tree.getroot()
138
138
  value = ET.tostring(root, encoding="unicode")
@@ -6,8 +6,8 @@ from prompt_toolkit import PromptSession
6
6
  from rich.console import Console
7
7
  from rich.tree import Tree
8
8
 
9
- from falyx.action.base import BaseAction
10
- from falyx.action.types import SelectionReturnType
9
+ from falyx.action.action_types import SelectionReturnType
10
+ from falyx.action.base_action import BaseAction
11
11
  from falyx.context import ExecutionContext
12
12
  from falyx.execution_registry import ExecutionRegistry as er
13
13
  from falyx.hook_manager import HookType
@@ -5,7 +5,7 @@ from prompt_toolkit.validation import Validator
5
5
  from rich.console import Console
6
6
  from rich.tree import Tree
7
7
 
8
- from falyx.action.base import BaseAction
8
+ from falyx.action.base_action import BaseAction
9
9
  from falyx.context import ExecutionContext
10
10
  from falyx.execution_registry import ExecutionRegistry as er
11
11
  from falyx.hook_manager import HookType
falyx/command.py CHANGED
@@ -27,7 +27,7 @@ from rich.console import Console
27
27
  from rich.tree import Tree
28
28
 
29
29
  from falyx.action.action import Action
30
- from falyx.action.base import BaseAction
30
+ from falyx.action.base_action import BaseAction
31
31
  from falyx.context import ExecutionContext
32
32
  from falyx.debug import register_debug_hooks
33
33
  from falyx.execution_registry import ExecutionRegistry as er
falyx/config.py CHANGED
@@ -14,7 +14,7 @@ from pydantic import BaseModel, Field, field_validator, model_validator
14
14
  from rich.console import Console
15
15
 
16
16
  from falyx.action.action import Action
17
- from falyx.action.base import BaseAction
17
+ from falyx.action.base_action import BaseAction
18
18
  from falyx.command import Command
19
19
  from falyx.falyx import Falyx
20
20
  from falyx.logger import logger
falyx/falyx.py CHANGED
@@ -43,7 +43,7 @@ from rich.markdown import Markdown
43
43
  from rich.table import Table
44
44
 
45
45
  from falyx.action.action import Action
46
- from falyx.action.base import BaseAction
46
+ from falyx.action.base_action import BaseAction
47
47
  from falyx.bottom_bar import BottomBar
48
48
  from falyx.command import Command
49
49
  from falyx.context import ExecutionContext
@@ -346,7 +346,6 @@ class Falyx:
346
346
  aliases=["HISTORY"],
347
347
  action=Action(name="View Execution History", action=er.summary),
348
348
  style=OneColors.DARK_YELLOW,
349
- simple_help_signature=True,
350
349
  arg_parser=parser,
351
350
  help_text="View the execution history of commands.",
352
351
  )
@@ -1152,7 +1151,7 @@ class Falyx:
1152
1151
  sys.exit(0)
1153
1152
 
1154
1153
  if self.cli_args.command == "version" or self.cli_args.version:
1155
- self.console.print(f"[{self.version_style}]{self.program} v{__version__}[/]")
1154
+ self.console.print(f"[{self.version_style}]{self.program} v{self.version}[/]")
1156
1155
  sys.exit(0)
1157
1156
 
1158
1157
  if self.cli_args.command == "preview":
falyx/menu.py CHANGED
@@ -4,7 +4,7 @@ from dataclasses import dataclass
4
4
 
5
5
  from prompt_toolkit.formatted_text import FormattedText
6
6
 
7
- from falyx.action.base import BaseAction
7
+ from falyx.action.base_action import BaseAction
8
8
  from falyx.signals import BackSignal, QuitSignal
9
9
  from falyx.themes import OneColors
10
10
  from falyx.utils import CaseInsensitiveDict
falyx/parser/argument.py CHANGED
@@ -3,7 +3,7 @@
3
3
  from dataclasses import dataclass
4
4
  from typing import Any
5
5
 
6
- from falyx.action.base import BaseAction
6
+ from falyx.action.base_action import BaseAction
7
7
  from falyx.parser.argument_action import ArgumentAction
8
8
 
9
9
 
@@ -9,7 +9,7 @@ from rich.console import Console
9
9
  from rich.markup import escape
10
10
  from rich.text import Text
11
11
 
12
- from falyx.action.base import BaseAction
12
+ from falyx.action.base_action import BaseAction
13
13
  from falyx.exceptions import CommandArgumentError
14
14
  from falyx.parser.argument import Argument
15
15
  from falyx.parser.argument_action import ArgumentAction
falyx/parser/parsers.py CHANGED
@@ -76,14 +76,14 @@ def get_root_parser(
76
76
  help="Run in non-interactive mode with all prompts bypassed.",
77
77
  )
78
78
  parser.add_argument(
79
- "-v", "--verbose", action="store_true", help="Enable debug logging for Falyx."
79
+ "-v", "--verbose", action="store_true", help=f"Enable debug logging for {prog}."
80
80
  )
81
81
  parser.add_argument(
82
82
  "--debug-hooks",
83
83
  action="store_true",
84
84
  help="Enable default lifecycle debug logging",
85
85
  )
86
- parser.add_argument("--version", action="store_true", help="Show Falyx version")
86
+ parser.add_argument("--version", action="store_true", help=f"Show {prog} version")
87
87
  return parser
88
88
 
89
89
 
@@ -98,7 +98,6 @@ def get_subparsers(
98
98
  subparsers = parser.add_subparsers(
99
99
  title=title,
100
100
  description=description,
101
- metavar="COMMAND",
102
101
  dest="command",
103
102
  )
104
103
  return subparsers
@@ -124,6 +123,8 @@ def get_arg_parsers(
124
123
  subparsers: _SubParsersAction | None = None,
125
124
  ) -> FalyxParsers:
126
125
  """Returns the argument parser for the CLI."""
126
+ if epilog is None:
127
+ epilog = f"Tip: Use '{prog} run ?[COMMAND]' to preview any command from the CLI."
127
128
  if root_parser is None:
128
129
  parser = get_root_parser(
129
130
  prog=prog,
@@ -145,7 +146,14 @@ def get_arg_parsers(
145
146
  parser = root_parser
146
147
 
147
148
  if subparsers is None:
148
- subparsers = get_subparsers(parser)
149
+ if prog == "falyx":
150
+ subparsers = get_subparsers(
151
+ parser,
152
+ title="Falyx Commands",
153
+ description="Available commands for the Falyx CLI.",
154
+ )
155
+ else:
156
+ subparsers = get_subparsers(parser, title="subcommands", description=None)
149
157
  if not isinstance(subparsers, _SubParsersAction):
150
158
  raise TypeError("subparsers must be an instance of _SubParsersAction")
151
159
 
@@ -154,10 +162,10 @@ def get_arg_parsers(
154
162
  if isinstance(commands, dict):
155
163
  for command in commands.values():
156
164
  run_description.append(command.usage)
157
- command_description = command.description or command.help_text
165
+ command_description = command.help_text or command.description
158
166
  run_description.append(f"{' '*24}{command_description}")
159
167
  run_epilog = (
160
- "Tip: Use 'falyx run ?[COMMAND]' to preview commands by their key or alias."
168
+ f"Tip: Use '{prog} run ?[COMMAND]' to preview commands by their key or alias."
161
169
  )
162
170
  run_parser = subparsers.add_parser(
163
171
  "run",
@@ -259,7 +267,7 @@ def get_arg_parsers(
259
267
  "-t", "--tag", help="Filter commands by tag (case-insensitive)", default=None
260
268
  )
261
269
 
262
- version_parser = subparsers.add_parser("version", help="Show the Falyx version")
270
+ version_parser = subparsers.add_parser("version", help=f"Show {prog} version")
263
271
 
264
272
  return FalyxParsers(
265
273
  root=parser,
falyx/parser/utils.py CHANGED
@@ -6,7 +6,7 @@ from typing import Any, Literal, Union, get_args, get_origin
6
6
 
7
7
  from dateutil import parser as date_parser
8
8
 
9
- from falyx.action.base import BaseAction
9
+ from falyx.action.base_action import BaseAction
10
10
  from falyx.logger import logger
11
11
  from falyx.parser.signature import infer_args_from_func
12
12
 
falyx/protocols.py CHANGED
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Any, Awaitable, Protocol, runtime_checkable
6
6
 
7
- from falyx.action.base import BaseAction
7
+ from falyx.action.base_action import BaseAction
8
8
 
9
9
 
10
10
  @runtime_checkable
falyx/retry_utils.py CHANGED
@@ -1,7 +1,7 @@
1
1
  # Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
2
2
  """retry_utils.py"""
3
3
  from falyx.action.action import Action
4
- from falyx.action.base import BaseAction
4
+ from falyx.action.base_action import BaseAction
5
5
  from falyx.hook_manager import HookType
6
6
  from falyx.retry import RetryHandler, RetryPolicy
7
7
 
falyx/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.52"
1
+ __version__ = "0.1.53"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: falyx
3
- Version: 0.1.52
3
+ Version: 0.1.53
4
4
  Summary: Reliable and introspectable async CLI action framework.
5
5
  License: MIT
6
6
  Author: Roland Thomas Jr
@@ -0,0 +1,66 @@
1
+ falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ falyx/__init__.py,sha256=Gh88lQ5pbD7xbGWrBgslE2kSTZKY9TkvKSa53rZ3l8U,305
3
+ falyx/__main__.py,sha256=xHO4pB45rccixo-ougF84QJeB36ef8mEZXWVK_CJL9M,3420
4
+ falyx/action/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ falyx/action/__init__.py,sha256=i7rQJDJMPLONgiAgs3KU3Ay0T1rIk7ySF4JJqpzc6QM,1279
6
+ falyx/action/action.py,sha256=853-7CU9q6HmTEC7ha_snc-DM6P-AWv6vJVqmFSV54I,5760
7
+ falyx/action/action_factory.py,sha256=FKbqvEfZgxlxCXraWkBtRkUKA8wOVEmEreiiBWVNO6E,4839
8
+ falyx/action/action_group.py,sha256=daijfvLtE-YSGoS-jD8bqmkhIP_KzH3HrN3Q7pa5tkg,7239
9
+ falyx/action/action_types.py,sha256=oG8qIFObZdiU1VZQlnWzR8uBDq8rcxzkCli9A31_tMI,1460
10
+ falyx/action/base_action.py,sha256=-S-ODqetUFpcCYI9V5531-_XKXjgL1aYkOKO0rpfTS8,5873
11
+ falyx/action/chained_action.py,sha256=nFFzj-GsO6948Zo3hRIfk-4G8pm3hnK511F345QDC0g,8902
12
+ falyx/action/fallback_action.py,sha256=3FGWfoR1MIgY0ZkDNOpKu8p3JqPWzh5ON3943mfgDGs,1708
13
+ falyx/action/http_action.py,sha256=DNeSBWh58UTFGlfFyTk2GnhS54hpLAJLC0QNbq2cYic,5799
14
+ falyx/action/io_action.py,sha256=V888tQgAynqsVvkhICnEeE4wRs2vvdTcdlEpDSEbHqo,6128
15
+ falyx/action/literal_input_action.py,sha256=ShXXiUYKg01BMZRChlxEWlNcaLXV1B1LW-w5A8mOPvA,1387
16
+ falyx/action/load_file_action.py,sha256=kRFmYJI0QyBN00NX_89cI77kjYKRqCueKjru_uvXWNE,764
17
+ falyx/action/menu_action.py,sha256=ODghp2RcQhnSgVKhq3l8tH7pQ5HL5cT-Y0TuoWF8z84,6076
18
+ falyx/action/mixins.py,sha256=TDR8hPaBA_P_O9l03eW4IxN7Dj6Z08o97jYkXG9qt1A,1237
19
+ falyx/action/process_action.py,sha256=nUNcJD6Ms34vmj8njWzv1R1P9xJTyJmelnyJksHcp7M,4666
20
+ falyx/action/process_pool_action.py,sha256=i-RqgN82TndPkgFFvkh7FShIg6O9m7Etlh-4OMIXGTg,6039
21
+ falyx/action/prompt_menu_action.py,sha256=SYgSDURsyjeQbEm_lbJCEVjVGPSGN59-xtT_VDyJqVY,5293
22
+ falyx/action/save_file_action.py,sha256=Eveteiy-VejenFCZzoslQ5cIxm11IXVbEcgTI-cFbgg,764
23
+ falyx/action/select_file_action.py,sha256=5TB5YN6vcFtv4F2aUGP8akuexHdXHXwr1rq06cLHByY,9829
24
+ falyx/action/selection_action.py,sha256=f3m4sYpGVu6nwydtx76OMvp7HFMZqSEr_nL9lwaPd_A,15749
25
+ falyx/action/shell_action.py,sha256=0A_kvZLsYmeLHInMM_4Jpe8GCSnXzGBm7H9PnXPvbAs,4055
26
+ falyx/action/signal_action.py,sha256=5UMqvzy7fBnLANGwYUWoe1VRhrr7e-yOVeLdOnCBiJo,1350
27
+ falyx/action/user_input_action.py,sha256=DnIYy4Bwl3dPbNSiM4ojuv-Y3WDYgIF2cUE3YPu-xCE,3848
28
+ falyx/bottom_bar.py,sha256=KPACb9VC0I3dv_pYZLqy7e4uA_KT5dSfwnvuknyV0FI,7388
29
+ falyx/command.py,sha256=8kUz3QmPGxrMZ2e2xQG2aIUkzlcqZSLBQbiWyuiBBSA,16439
30
+ falyx/config.py,sha256=JkGLssxRYgSOFqGhLT19q4dqyLdLQj_NAtzZpcYSU2M,9665
31
+ falyx/context.py,sha256=b9PGkIfhc1BbFUmaqmr4AojzONfKG1c9WP2uixzCJGQ,10806
32
+ falyx/debug.py,sha256=pguI0XQcZ-7jte5YUPexAufa1oxxalYO1JgmO6GU3rI,1557
33
+ falyx/exceptions.py,sha256=kK9k1v7LVNjJSwYztRa9Krhr3ZOI-6Htq2ZjlYICPKg,922
34
+ falyx/execution_registry.py,sha256=7t_96-Q7R7MAJBvWwAt5IAERp0TjbGZPGeeJ1s24ey8,7628
35
+ falyx/falyx.py,sha256=IGNgkaSgrF0jydQQulJUl0hJZT56tmy2UCDmC9DSWB8,49773
36
+ falyx/hook_manager.py,sha256=TFuHQnAncS_rk6vuw-VSx8bnAppLuHfrZCrzLwqcO9o,2979
37
+ falyx/hooks.py,sha256=xMfQROib0BNsaQF4AXJpmCiGePoE1f1xpcdibgnVZWM,2913
38
+ falyx/init.py,sha256=F9jg7mLPoBWXdJnc_fyWG7zVQSnrAO8ueDiP8AJxDWE,3331
39
+ falyx/logger.py,sha256=1Mfb_vJFJ1tQwziuyU2p-cSMi2Js8N2byniFEnI6vOQ,132
40
+ falyx/menu.py,sha256=9kvLZhkC8PoSQvv1NZQsPIFSDy11dXfFgqVAuDmtfsM,3752
41
+ falyx/options_manager.py,sha256=dFAnQw543tQ6Xupvh1PwBrhiSWlSACHw8K-sHP_lUh4,2842
42
+ falyx/parser/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ falyx/parser/__init__.py,sha256=NbxAovKIY-duFTs6DAsdM_OzL7s3VIu19KMOmltX9ts,512
44
+ falyx/parser/argument.py,sha256=l1aNTkMEEgFdBu4wQALBpMlsJ3_8519S3ChAOpxJgxE,3369
45
+ falyx/parser/argument_action.py,sha256=rNVeth0eMpkZRU_eT1RPVxOGzD4pbdAMx9Kq07T4mG4,709
46
+ falyx/parser/command_argument_parser.py,sha256=tcyxRhMoBSwpjN-Z56-vglbRjPcA-BI4R8AEQvqoYsk,33899
47
+ falyx/parser/parsers.py,sha256=X3eEltxBbwRwWG5Q1A1GqSdQCJZAYN5Eub0_U6dlBN4,9159
48
+ falyx/parser/signature.py,sha256=fSltLEr8ctj1qpbU-OvTMnREjlb8OTG5t-guJFR7j4E,2529
49
+ falyx/parser/utils.py,sha256=gk-SHGPrVOrV-YCLc0bZlWRzXLw0goGUKA5fWZqT0iw,2963
50
+ falyx/prompt_utils.py,sha256=qgk0bXs7mwzflqzWyFhEOTpKQ_ZtMIqGhKeg-ocwNnE,1542
51
+ falyx/protocols.py,sha256=_e3wPDrn-6_20n8Uz80MnesEryDmkrMkPdYXUQO9YvA,500
52
+ falyx/retry.py,sha256=sGRE9QhdZK98M99G8F15WUsJ_fYLNyLlCgu3UANaSQs,3744
53
+ falyx/retry_utils.py,sha256=IqvEy_F0dXG8Yl2UoEJVLX-6OXk-dh-D72_SWv4w-p0,730
54
+ falyx/selection.py,sha256=TPSM_KKGHedJblWI0AzxTZR2haZjRF3k-gQoQeR3L28,15239
55
+ falyx/signals.py,sha256=Y_neFXpfHs7qY0syw9XcfR9WeAGRcRw1nG_2L1JJqKE,1083
56
+ falyx/tagged_table.py,sha256=4SV-SdXFrAhy1JNToeBCvyxT-iWVf6cWY7XETTys4n8,1067
57
+ falyx/themes/__init__.py,sha256=1CZhEUCin9cUk8IGYBUFkVvdHRNNJBEFXccHwpUKZCA,284
58
+ falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
59
+ falyx/utils.py,sha256=U45xnZFUdoFC4xiji_9S1jHS5V7MvxSDtufP8EgB0SM,6732
60
+ falyx/validators.py,sha256=Pbdxh5777Y03HxyArAh2ApeVSx23in4w4K38G43Vt98,5197
61
+ falyx/version.py,sha256=FdQ5_-vfyHXSNAuzQXtxxDH2WjNJ3g581mH_zvly6Xo,23
62
+ falyx-0.1.53.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
63
+ falyx-0.1.53.dist-info/METADATA,sha256=P1gyGshvU_NnFWfQHvq1J8L_VatBhNl8vpv3qXwmkbY,5561
64
+ falyx-0.1.53.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
65
+ falyx-0.1.53.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
66
+ falyx-0.1.53.dist-info/RECORD,,
@@ -1,64 +0,0 @@
1
- falyx/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- falyx/__init__.py,sha256=Gh88lQ5pbD7xbGWrBgslE2kSTZKY9TkvKSa53rZ3l8U,305
3
- falyx/__main__.py,sha256=xHO4pB45rccixo-ougF84QJeB36ef8mEZXWVK_CJL9M,3420
4
- falyx/action/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- falyx/action/__init__.py,sha256=xpsZJVtMFP9vtmg6LSS3QjZrezD2ZxGZUBAjv4axuuw,1272
6
- falyx/action/action.py,sha256=j9ANO0xRfWoiNK6z-46T04EKAJ7GhjVrzb8_U8afEAA,5753
7
- falyx/action/action_factory.py,sha256=br-P7Oip-4tZkO8qVT_ECwLe6idYjJa_GuBi5QR7vS4,4832
8
- falyx/action/action_group.py,sha256=NT2m9aLHUV2CqJxaDTAXFOH5_9F07TaCDmhybrO5dvU,6920
9
- falyx/action/base.py,sha256=B7mt66oznmhv2qpSOwOuScgMckVXrxjRMU2buzZkRD8,5866
10
- falyx/action/chained_action.py,sha256=0qSZBtL8G1Mb4S-iisBjOlsX8GDq8iB6iecf0vvp2L8,8589
11
- falyx/action/fallback_action.py,sha256=3FGWfoR1MIgY0ZkDNOpKu8p3JqPWzh5ON3943mfgDGs,1708
12
- falyx/action/http_action.py,sha256=DNeSBWh58UTFGlfFyTk2GnhS54hpLAJLC0QNbq2cYic,5799
13
- falyx/action/io_action.py,sha256=uOehF3ryqSUf0ye4cyQrHyNvf7TMnwfgt2EtZNEeHr0,6121
14
- falyx/action/literal_input_action.py,sha256=ShXXiUYKg01BMZRChlxEWlNcaLXV1B1LW-w5A8mOPvA,1387
15
- falyx/action/menu_action.py,sha256=SLqwmQ1TOt8kl_cgIWogBYfx8lYPLZa4E-Yy6M2cX_w,6069
16
- falyx/action/mixins.py,sha256=xWFyiGAcocTb9yTtHtTiAuuYdIc8vqLPreJAHPA6jBs,1197
17
- falyx/action/process_action.py,sha256=UdE6ab5fwS03iRY3Xk6fehpPZ47wo7yQT9tZmWiSTgw,4659
18
- falyx/action/process_pool_action.py,sha256=soHrecetIVN-dzgCS4jSdC0cnabDZQGwCWjPPOAFUIs,6032
19
- falyx/action/prompt_menu_action.py,sha256=corzjpPNVMYKncfueeRUWwklnlZHN-Fc61psOzbZELg,5286
20
- falyx/action/select_file_action.py,sha256=2T4I1CLvHLAAqNUD2rFBIpdi74BP5amU4yTHUOGnd64,9911
21
- falyx/action/selection_action.py,sha256=Mav39iTkVIJPDvmDek8R2bSF18f-mII56l5sSzZSPII,15735
22
- falyx/action/shell_action.py,sha256=0A_kvZLsYmeLHInMM_4Jpe8GCSnXzGBm7H9PnXPvbAs,4055
23
- falyx/action/signal_action.py,sha256=5UMqvzy7fBnLANGwYUWoe1VRhrr7e-yOVeLdOnCBiJo,1350
24
- falyx/action/types.py,sha256=ml-KMelDjYnXdUTR1n7mHEwZFpAIdtB3RTnJS0KdVCQ,1478
25
- falyx/action/user_input_action.py,sha256=ywbuHciMhXfZpLuHFBF8PBcm_bnmH3VLib66RrKFSx0,3841
26
- falyx/bottom_bar.py,sha256=KPACb9VC0I3dv_pYZLqy7e4uA_KT5dSfwnvuknyV0FI,7388
27
- falyx/command.py,sha256=v6GOVOPDmcjfKq0uR4EYXuqXSAYOVFp9Iy1hlZq4W5w,16432
28
- falyx/config.py,sha256=Cm1F9SfNSbugPALxaEz7NRqp1wrk-g2jYq35bQzN2uE,9658
29
- falyx/context.py,sha256=b9PGkIfhc1BbFUmaqmr4AojzONfKG1c9WP2uixzCJGQ,10806
30
- falyx/debug.py,sha256=pguI0XQcZ-7jte5YUPexAufa1oxxalYO1JgmO6GU3rI,1557
31
- falyx/exceptions.py,sha256=kK9k1v7LVNjJSwYztRa9Krhr3ZOI-6Htq2ZjlYICPKg,922
32
- falyx/execution_registry.py,sha256=7t_96-Q7R7MAJBvWwAt5IAERp0TjbGZPGeeJ1s24ey8,7628
33
- falyx/falyx.py,sha256=zOAah7OYHZgMRI60zwXjNgfeEHs8y87SDs3Meslood0,49805
34
- falyx/hook_manager.py,sha256=TFuHQnAncS_rk6vuw-VSx8bnAppLuHfrZCrzLwqcO9o,2979
35
- falyx/hooks.py,sha256=xMfQROib0BNsaQF4AXJpmCiGePoE1f1xpcdibgnVZWM,2913
36
- falyx/init.py,sha256=F9jg7mLPoBWXdJnc_fyWG7zVQSnrAO8ueDiP8AJxDWE,3331
37
- falyx/logger.py,sha256=1Mfb_vJFJ1tQwziuyU2p-cSMi2Js8N2byniFEnI6vOQ,132
38
- falyx/menu.py,sha256=E580qZsx08bnWcqRVjJuD2Fy8Zh_1zIexp5f0lC7L2c,3745
39
- falyx/options_manager.py,sha256=dFAnQw543tQ6Xupvh1PwBrhiSWlSACHw8K-sHP_lUh4,2842
40
- falyx/parser/.pytyped,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- falyx/parser/__init__.py,sha256=NbxAovKIY-duFTs6DAsdM_OzL7s3VIu19KMOmltX9ts,512
42
- falyx/parser/argument.py,sha256=5udUzYOgxdOz4thI0bxuRsqGFf_YuId4LP7MZ6n0dYc,3362
43
- falyx/parser/argument_action.py,sha256=rNVeth0eMpkZRU_eT1RPVxOGzD4pbdAMx9Kq07T4mG4,709
44
- falyx/parser/command_argument_parser.py,sha256=c6mHuOxAWdt5CXMnZv-ZvAf0DDdNhSWaOYu2KIJGAFA,33892
45
- falyx/parser/parsers.py,sha256=MXWC8OQ3apDaeKfY0O4J8NnkxofWVOCRnKatC00lGm0,8796
46
- falyx/parser/signature.py,sha256=fSltLEr8ctj1qpbU-OvTMnREjlb8OTG5t-guJFR7j4E,2529
47
- falyx/parser/utils.py,sha256=W3uuvzftwE7Yuiwp_YsrvkIpJp0WcFEIdrRv8SCsnds,2956
48
- falyx/prompt_utils.py,sha256=qgk0bXs7mwzflqzWyFhEOTpKQ_ZtMIqGhKeg-ocwNnE,1542
49
- falyx/protocols.py,sha256=-9GbCBUzzsEgw2_KOCYqxxzWJuez0eHmwnZp_ShY0jc,493
50
- falyx/retry.py,sha256=sGRE9QhdZK98M99G8F15WUsJ_fYLNyLlCgu3UANaSQs,3744
51
- falyx/retry_utils.py,sha256=vwoZmFVCGVqZ13BX_xi3qZZVsmSxkp-jfaf6kJtBV9c,723
52
- falyx/selection.py,sha256=TPSM_KKGHedJblWI0AzxTZR2haZjRF3k-gQoQeR3L28,15239
53
- falyx/signals.py,sha256=Y_neFXpfHs7qY0syw9XcfR9WeAGRcRw1nG_2L1JJqKE,1083
54
- falyx/tagged_table.py,sha256=4SV-SdXFrAhy1JNToeBCvyxT-iWVf6cWY7XETTys4n8,1067
55
- falyx/themes/__init__.py,sha256=1CZhEUCin9cUk8IGYBUFkVvdHRNNJBEFXccHwpUKZCA,284
56
- falyx/themes/colors.py,sha256=4aaeAHJetmeNInI0Zytg4E3YqKfPFelpf04vtjSvsS8,19776
57
- falyx/utils.py,sha256=U45xnZFUdoFC4xiji_9S1jHS5V7MvxSDtufP8EgB0SM,6732
58
- falyx/validators.py,sha256=Pbdxh5777Y03HxyArAh2ApeVSx23in4w4K38G43Vt98,5197
59
- falyx/version.py,sha256=xEFLBJ_IHewFRxpAOMcKAhQVPVf06lsExSa2472N2G8,23
60
- falyx-0.1.52.dist-info/LICENSE,sha256=B0yqgaHuSdhN7T3OBmgQSiDTy8HqT5Oe_dLypRe4Ra4,1073
61
- falyx-0.1.52.dist-info/METADATA,sha256=KEyMpUA-OEVmqKEHDTXguJV_id4mevnq9TDAAHSIcgM,5561
62
- falyx-0.1.52.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
63
- falyx-0.1.52.dist-info/entry_points.txt,sha256=j8owOSl2j1Ss8DtGMnKfgehKaolqnIPhVFHaUBLUnMs,45
64
- falyx-0.1.52.dist-info/RECORD,,
File without changes