feat(core): centralize command execution and add standalone command runner

- add CommandExecutor to unify shared command execution lifecycle
  across Falyx and standalone command execution
- add CommandRunner for running a single Command directly as a CLI
  or programmatic entrypoint
- add Command.build() factory and rename parse_args() to resolve_args()
  to clarify the parsing-to-execution boundary
- introduce ExecutionOption and wire execution-scoped flags into
  CommandArgumentParser and Command construction
- refactor Falyx to use FalyxParser/ParseResult and CommandExecutor
  instead of the older argparse-based flow and run_key path
- simplify __main__.py bootstrap by building a bootstrap Falyx instance
  directly and running flx.run()
- improve completer support for preview commands and unique-prefix
  command resolution
- default BottomBar toggle namespace to "default"
- expand module/class docstrings to reflect the new execution architecture
This commit is contained in:
2026-04-07 18:58:24 -04:00
parent 8ce0ffa18e
commit 5d8f3aa603
34 changed files with 3043 additions and 1419 deletions

View File

@@ -10,7 +10,7 @@ from falyx.validators import CommandValidator
@pytest.mark.asyncio
async def test_command_validator_validates_command():
fake_falyx = AsyncMock()
fake_falyx.get_command.return_value = (False, object(), (), {})
fake_falyx.get_command.return_value = (False, object(), (), {}, {})
validator = CommandValidator(fake_falyx, "Invalid!")
await validator.validate_async(Document("valid"))
@@ -20,7 +20,7 @@ async def test_command_validator_validates_command():
@pytest.mark.asyncio
async def test_command_validator_rejects_invalid_command():
fake_falyx = AsyncMock()
fake_falyx.get_command.return_value = (False, None, (), {})
fake_falyx.get_command.return_value = (False, None, (), {}, {})
validator = CommandValidator(fake_falyx, "Invalid!")
with pytest.raises(ValidationError):
@@ -33,7 +33,7 @@ async def test_command_validator_rejects_invalid_command():
@pytest.mark.asyncio
async def test_command_validator_is_preview():
fake_falyx = AsyncMock()
fake_falyx.get_command.return_value = (True, None, (), {})
fake_falyx.get_command.return_value = (True, None, (), {}, {})
validator = CommandValidator(fake_falyx, "Invalid!")
await validator.validate_async(Document("?preview_command"))