Milo 0.1.1
Reducer combinators, Bubbletea-inspired effects, CLI polish, and developer experience improvements.
Patch release focused on Elm Architecture ergonomics, Bubbletea-inspired effect patterns, CLI table-stakes features, and internal code health.
Highlights
- Reducer combinators —
quit_on,with_cursor,with_confirmdecorators stack to eliminate boilerplate key/cursor/confirm handling - Cmd effects — Lightweight
Cmdthunks as a simpler alternative to sagas for one-shot side effects, withBatch(concurrent) andSequence(serial) combinators TickCmd— Self-sustaining tick pattern with per-component, dynamic tick controlViewState— Declarative terminal state management (alt_screen,cursor_visible,window_title,mouse_mode) with diff-based rendering- Message filter —
App(filter=fn)intercepts actions before dispatch to drop or transform them - Shell completions —
install_completions()generates bash, zsh, and fish completions from CLI definitions - Doctor diagnostics —
run_doctor()validates environment, dependencies, and config health with structuredCheckspecs - Version checking — automatic PyPI upgrade notices (respects
NO_UPDATE_CHECKenv var) App.from_dir()— automatic template directory discovery, no manual loader setupContext.run_app()— bridge CLI command handlers to interactive Elm Architecture apps- Built-in template macros —
selectable_list,scrollable_list,format_timeincomponents/_defs.kida
CLI polish
- Structured error handling with
MiloErrorcode + hint display - Command examples render in help output and
generate_help_all() - Did-you-mean fuzzy suggestions on unknown commands
- Before/after hooks via
HookRegistry - Confirm gates for destructive commands
- Dry-run and output-file global option flags
- Progress bars via
CLIProgress Context.log()with leveled stderr outputConfig.validate()type-checks against spec defaultsConfig.init()scaffolds starter config filesinvoke()test helper splits stdout/stderrRetrysaga effect with backoff- Saga/Cmd error recovery — unhandled exceptions dispatch
@@SAGA_ERROR/@@CMD_ERRORinstead of being swallowed
Internal improvements
- Extracted
_command_defs.py,_cli_help.py,_jsonrpc.py, and_mcp_router.pyfrom monolithic modules - Unified command registration between CLI and Group via
_make_command_def - Middleware wired into
CLI.run()andCLI.call()dispatch paths - Parallelized health checks and gateway discovery with
ThreadPoolExecutor - Lazy
walk_commandsgenerators avoid eager materialization - Pre-computed property sets in workflow detection eliminate O(n²) work
- Fixed registry N+1 file reads in doctor checks
- Cached
_list_toolsin MCP server to avoid per-request recomputation - Fixed
execution_order()set rebuild performance - Bulletproof terminal cleanup — each step in
App.run()finally block is individually guarded
Bug fixes
- HelpRenderer now wired as default formatter in
CLI.build_parser()and subparsers - Action group capture in help uses formatter lifecycle instead of parser attributes
- Docstring descriptions propagate through schema to argparse help text
components/*.kidaincluded in package data--versionrendering guards template path when no action groups are captured- Fixed unclosed backtick in
generate_help_allglobal options - uv detection for version upgrade notices
- Version string drift — all modules now use
__version__from__init__.py - ViewState merging in
combine_reducers— fields from multiple reducers are merged, not overwritten - Message filter + Ctrl+C — filtered
@@QUITno longer locks out subsequent Ctrl+C CLI.call()provides a properContextto middleware instead ofNone- Gateway child I/O enforces a 30-second read timeout to prevent deadlocks
Store.shutdown()waits for pending work; Batch uses a 60-second timeout- Failed
@@SAGA_ERROR/@@CMD_ERRORdispatches are logged instead of silently swallowed - Before/after hook errors are caught and reported instead of crashing
New examples
devtool— showcases doctor diagnostics, hooks, command examples in help, structured errors, and shell completionsspinner— showcasesCmd,Batch,TickCmd, andViewStatepatterns