feat: add recursive namespace routing and standalone runner polish
- introduce namespace-aware routing with RootParseResult, RouteResult, and InvocationContext - register submenus as FalyxNamespace entries and resolve them through _entry_map - refactor FalyxParser to parse only root options and leave recursive routing to Falyx - add prepare_route, resolve_route, and route dispatch flow to Falyx - update validator and completer to understand namespace entries and route results - unify help/TLDR rendering APIs and add custom_tldr support on Command - tighten Command.resolve_args error handling and parser type validation - improve CommandRunner dependency validation and argv handling - add BottomBar.has_items and improve wrapped executor error messages - add tests for execution options, resolve_args, command runner, and route-aware validation
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
# Falyx CLI Framework — (c) 2025 rtj.dev LLC — MIT Licensed
|
||||
"""
|
||||
Execution context management for Falyx CLI actions.
|
||||
"""Context management for Falyx CLI.
|
||||
|
||||
This module defines `ExecutionContext` and `SharedContext`, which are responsible for
|
||||
capturing per-action and cross-action metadata during CLI workflow execution. These
|
||||
@@ -26,6 +25,7 @@ from pydantic import BaseModel, ConfigDict, Field
|
||||
from rich.console import Console
|
||||
|
||||
from falyx.console import console
|
||||
from falyx.mode import FalyxMode
|
||||
|
||||
|
||||
class ExecutionContext(BaseModel):
|
||||
@@ -285,6 +285,30 @@ class SharedContext(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
class InvocationContext(BaseModel):
|
||||
program: str = ""
|
||||
typed_path: list[str] = Field(default_factory=list)
|
||||
mode: FalyxMode = FalyxMode.MENU
|
||||
is_preview: bool = False
|
||||
|
||||
@property
|
||||
def is_cli_mode(self) -> bool:
|
||||
return self.mode != FalyxMode.MENU
|
||||
|
||||
def child(self, token: str) -> InvocationContext:
|
||||
return InvocationContext(
|
||||
program=self.program,
|
||||
typed_path=[*self.typed_path, token],
|
||||
mode=self.mode,
|
||||
is_preview=self.is_preview,
|
||||
)
|
||||
|
||||
def display_path(self) -> str:
|
||||
if self.is_cli_mode:
|
||||
return " ".join([self.program, *self.typed_path]).strip()
|
||||
return " ".join(self.typed_path).strip()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import asyncio
|
||||
|
||||
|
||||
Reference in New Issue
Block a user