A self-contained, extensible shell environment tailored for rapid Python utility management.
Flamingo was built to solve a specific frustration: managing scattered Python utility scripts on Windows. Instead of polluting the system PATH with batch files or shim scripts, Flamingo provides a single, portable executable environment where utilities exist as native plugins.
Project Status: Developed in <36 hours. Currently just a side-project in "alpha".
- Portability: The entire environment is designed to be compiled via PyInstaller into a single executable.
- State Persistence: User state, variables, and history are persisted locally via
shelve. - Aesthetics: First-class support for the Catppuccin palette and
prompt_toolkitstyling. - Strict Typing: Arguments are parsed and strictly validated against Python types before execution.
Flamingo implements a unique scoped variable system that mimics memory pointers rather than simple text expansion.
#system: System configurations (Prompt format, Plugin paths).$env: Environmental context (CWD).@user: User-defined variables and aliases.
Variables support Reference Linking. You can link @alias to point directly to @source. Updating @source immediately reflects in @alias without copying values.
Flamingo is designed to be extended. The core commands (ls, cd, set) are implemented as plugins, ensuring the plugin architecture is first-class, not an afterthought.
Plugins are loaded dynamically from the plugins/ directory.
- Clone the repository.
- Install dependencies:
pip install -r requirements.txt
- Run the kernel:
python -m flamingo.main
Flamingo is fully compatible with PyInstaller for single-file distribution:
pyinstaller --onefile flamingo/main.py --name flamingo
Adding value to the environment is straightforward. Plugins inherit from FlamingoCommand and use declarative argument parsers.
Example: A custom 'Hello / Ping' command
import flamingo
from flamingo.core.commands.command import FlamingoCommand
from flamingo.core.kernel import FlamingoKernel
from flamingo.interface.text import FmtBuilder
from flamingo.plugins.plugin import FlamingoPlugin
class PingPlugin(FlamingoPlugin):
def load(self, kernel) -> tuple[int, int]:
return 0, 0
def unload(self, kernel) -> tuple[int, int]:
return 0, 0
def __init__(self):
super().__init__("ping", "shaun", "It's a pinging plugin!", "0.1")
ping_plugin = PingPlugin()
@ping_plugin.add_command
class MyCommand(FlamingoCommand):
def __init__(self):
super().__init__("ping", "Ping", (), flamingo.core.commands.parser.ArgParser())
def execute(self, kernel: FlamingoKernel, args: list):
_ = self.arg_parser.parse(args)
kernel.out(FmtBuilder.from_kernel(kernel).surface2("pong!").build())- Kernel: acts as the central delegator, holding the
VarTableandUserstates. - Shell Interface: Powered by
prompt_toolkitfor history, auto-completion, and syntax highlighting. - Context Scope: An internal context manager tracks the execution stack for granular error logging.