DEPRECATION NOTICE
This implementation plan has been completed. The checkboxes below were not updated during implementation and do not reflect current status. Please refer to the actual codebase for the current implementation state. Key implemented features include:
- Argument Parsing (
packages/maid-engine/src/maid_engine/commands/arguments.py)- Command Decorators (
packages/maid-engine/src/maid_engine/commands/decorators.py)- Help Generator (
packages/maid-engine/src/maid_engine/commands/help.py)- Hook System (
packages/maid-engine/src/maid_engine/commands/hooks.py)- Lock System (
packages/maid-engine/src/maid_engine/commands/locks.py)- Layered Registry (
packages/maid-engine/src/maid_engine/commands/registry.py)
Command System Enhancements - Implementation Plan¶
Summary¶
This plan implements four major enhancements to MAID's command system to achieve feature parity with Evennia:
- Advanced Argument Parsing - Declarative argument schemas with type coercion, entity resolution, and pattern matching
- Auto-Generated Help from Docstrings - Automatic help text extraction from handler docstrings and argument specs
- Pre/Post Command Hooks - Middleware pipeline for logging, cooldowns, combat checks, and cleanup
- Enhanced Lock System - Expression-based permissions with AND/OR/NOT operators and pluggable lock functions
All features are backward-compatible; existing commands continue to work without modification.
Tasks¶
Phase 1: Core Argument Parsing Infrastructure¶
Location: packages/maid-engine/src/maid_engine/commands/arguments.py
- [x] Create
ArgumentTypeenum with types: STRING, INTEGER, FLOAT, BOOLEAN, ENTITY, ENTITY_LIST, DIRECTION, PLAYER, REST - [x] Create
SearchScopeenum for entity search: ROOM, INVENTORY, EQUIPMENT, ROOM_AND_INVENTORY, ALL - [x] Create
ArgumentErrordataclass for parse errors - [x] Create
ArgumentSpecgeneric dataclass with validation logic - Supports: name, type, required, default, description, choices, pattern, search_scope, min/max values
- [x] Create
ParsedArgumentsdataclass with dict-like access and error tracking - [x] Create
EntityReferenceclass for resolved entity results withentity,found, and iteration support - [x] Create
ArgumentPatterndataclass for pattern-based parsing (e.g.,<target> = <message>) - [x] Write unit tests for all dataclasses and enums
Phase 2: Argument Parser Implementation¶
Location: packages/maid-engine/src/maid_engine/commands/arguments.py
- [x] Implement
ArgumentParserclass - [x] Implement
parse()method dispatching to positional or pattern parsing - [x] Implement
_parse_positional()for sequential argument parsing - [x] Implement
_parse_pattern()for regex-based pattern extraction - [x] Implement
_parse_value()for type coercion (STRING, INTEGER, FLOAT, BOOLEAN) - Depends on: Phase 1 dataclasses
- [x] Implement entity resolution in
_resolve_entity() - [x] Support index syntax (
2.sword) - [x] Support all syntax (
all.sword) - [x] Support special keywords (
me,here) - [x] Implement
_entity_matches_keyword()for keyword matching - Depends on: SearchScope, EntityReference
- [x] Implement
_resolve_player()for online player lookup - [x] Implement
_normalize_direction()for direction aliases (n→north, etc.) - [x] Write unit tests for ArgumentParser with all argument types
- [x] Write integration tests for entity resolution
Phase 3: Argument Decorators¶
Location: packages/maid-engine/src/maid_engine/commands/decorators.py
- [x] Implement
@arguments(*specs)decorator - Wraps handler to parse arguments before execution
- Attaches
__argument_parser__and__argument_specs__for introspection - Depends on: ArgumentParser
- [x] Implement
@pattern(pattern_string, *specs)decorator - Supports delimited patterns like
<target> = <message> - Depends on: ArgumentPattern, ArgumentParser
- [x] Write unit tests for decorators
- [x] Add usage examples to docstrings
Phase 4: Help Generator¶
Location: packages/maid-engine/src/maid_engine/commands/help.py
- [x] Create
HelpEntrydataclass with all help fields - [x] Create
ArgumentHelpdataclass for argument documentation - [x] Implement
HelpGeneratorclass - [x] Implement
generate()to create HelpEntry from CommandDefinition - [x] Implement
_parse_docstring()to extract short/long description, see_also, examples - [x] Implement
_generate_usage()from argument specs or pattern - [x] Implement
_extract_argument_help()from handler decorators - Depends on: Phase 3 decorators (for
__argument_specs__) - [x] Implement
format_terminal()for terminal-friendly output with wrapping - [x] Write unit tests for docstring parsing
- [x] Write unit tests for usage generation
- [x] Write unit tests for terminal formatting
Phase 5: Hook System Infrastructure¶
Location: packages/maid-engine/src/maid_engine/commands/hooks.py
- [x] Create
HookPriorityenum: FIRST, HIGH, NORMAL, LOW, LAST - [x] Create
HookResultenum: CONTINUE, CANCEL, SKIP - [x] Create
PreHookContextdataclass withcancel()method - [x] Create
PostHookContextdataclass with result, exception, execution_time_ms - [x] Create
RegisteredHookdataclass withmatches()method for command/category filtering - [x] Implement
HookRegistryclass - [x] Implement
register_pre_hook()with priority sorting - [x] Implement
register_post_hook()with priority sorting - [x] Implement
unregister()by name - [x] Implement
get_pre_hooks()andget_post_hooks()with filtering - [x] Write unit tests for HookRegistry
Phase 6: Command Executor with Hooks¶
Location: packages/maid-engine/src/maid_engine/commands/hooks.py
- [x] Implement
CommandExecutorclass - [x] Implement
execute()with full pre/post hook pipeline - [x] Handle pre-hook cancellation with user message
- [x] Handle SKIP result to bypass remaining pre-hooks
- [x] Ensure post-hooks run even on handler exception
- [x] Track execution time for post-hook context
- [x] Implement
_call_hook()supporting both sync and async handlers - Depends on: HookRegistry
- [x] Write unit tests for hook execution order
- [x] Write unit tests for cancellation flow
- [x] Write unit tests for exception handling
Phase 7: Built-in Hooks¶
Location: packages/maid-engine/src/maid_engine/commands/hooks.py
- [x] Implement
logging_pre_hook()- log command attempts - [x] Implement
logging_post_hook()- log command completion with timing - [x] Implement
CooldownHookclass - Tracks per-player, per-command cooldowns
- Reads
cooldownfrom command metadata - [x] Implement
CombatStateHookclass - Blocks configurable commands during combat
- [x] Implement
MetricsHookclass - Collects execution counts, times, error counts
- Provides
get_stats()method - [x] Write unit tests for each built-in hook
Phase 8: Lock Expression Parser¶
Location: packages/maid-engine/src/maid_engine/commands/locks.py
- [x] Create
LockContextdataclass with player, world, target, command context - [x] Create
LockFunctionRegistryclass for registering/evaluating lock functions - [x] Create
LockNodeABC and concrete node classes: - [x]
LockFunctionNode- function call likeperm(admin) - [x]
LockAndNode,LockOrNode,LockNotNode- operators - [x]
LockTrueNode,LockFalseNode- constants - [x] Implement
LockExpressionParserclass - [x] Implement tokenizer with TOKEN_PATTERNS
- [x] Implement
parse()with expression caching - [x] Implement recursive descent:
_parse_or_expr,_parse_and_expr,_parse_not_expr,_parse_primary - [x] Handle parentheses for grouping
- [x] Produce clear error messages for invalid expressions
- [x] Write unit tests for parser with various expressions
- [x] Write unit tests for operator precedence
Phase 9: Lock Evaluator and Built-in Functions¶
Location: packages/maid-engine/src/maid_engine/commands/locks.py
- [x] Implement
LockEvaluatorclass withcheck()method - Depends on: LockExpressionParser
- [x] Implement built-in lock functions:
- [x]
lock_all(),lock_none()- always pass/fail - [x]
lock_perm()- access level check - [x]
lock_owns()- target ownership check - [x]
lock_holds()- inventory check - [x]
lock_in_room()- room tag check - [x]
lock_has_flag()- player tag check - [x]
lock_in_guild(),lock_guild_rank()- guild checks - [x]
lock_level()- account access level check (andlock_char_level()- character level check) - [x]
lock_in_combat()- combat state check - [x]
lock_has_item()- inventory item check - [x]
lock_has_skill()- skill level check - [x] Register all built-in functions with LockFunctionRegistry
- [x] Write unit tests for each lock function
Phase 10: Registry Integration¶
Location: packages/maid-engine/src/maid_engine/commands/registry.py
- [x] Add
locks: strfield toCommandDefinitiondataclass - [x] Add
metadata: dict[str, Any]field toCommandDefinitionfor hook data (e.g., cooldowns) - [x] Initialize
HookRegistryandCommandExecutorinLayeredCommandRegistry.__init__() - [x] Initialize
LockEvaluatorinLayeredCommandRegistry.__init__() - [x] Update
execute()method to: - [x] Evaluate lock expressions before execution
- [x] Use
CommandExecutorfor hook pipeline - Depends on: Phases 6 and 9
- [x] Add
register_pre_hook()andregister_post_hook()convenience methods - [x] Write integration tests for full command flow with hooks and locks
- [x] Verify backward compatibility with existing commands
Phase 11: Update Command Decorator¶
Location: packages/maid-engine/src/maid_engine/commands/decorators.py
- [x] Update
@command()decorator to acceptlocksparameter - [x] Update
@command()decorator to acceptmetadataparameter (for cooldowns etc.) - [x] Ensure HelpGenerator can access lock expressions
- [x] Write integration tests for decorated commands with locks
Phase 12: Help Command Integration¶
- [x] Update
helpcommand to useHelpGenerator - [x] Display lock requirements in help output (P1)
- [x] Format argument help with required markers
- [x] Test help output for commands with full decorators
Phase 13: Documentation and Examples¶
- [x] Add docstrings to all public classes and methods
- [x] Create usage examples in
docs/examples/: - [x] Basic argument parsing example
- [x] Pattern-based parsing example
- [x] Hook registration example
- [x] Custom lock function example
- [x] Update CLAUDE.md with new command system features
- [x] Document migration path for existing commands
Phase 14: Testing and Performance¶
- [x] Achieve 90%+ test coverage for ArgumentParser, HookRegistry, CommandExecutor
- [x] Achieve 95%+ test coverage for LockExpressionParser
- [x] Add performance benchmarks:
- [x] Argument parsing (5 args) < 1ms
- [x] Lock expression parsing < 0.5ms
- [x] Lock evaluation (complex) < 0.1ms
- [x] Hook pipeline (5 hooks) < 2ms
- [x] Run full regression test suite
- [x] Test backward compatibility with existing commands
Dependencies Graph¶
Phase 1 (Dataclasses)
└─► Phase 2 (ArgumentParser)
└─► Phase 3 (Decorators)
└─► Phase 4 (HelpGenerator)
└─► Phase 11 (Command Decorator Updates)
Phase 5 (Hook Infrastructure)
└─► Phase 6 (CommandExecutor)
└─► Phase 7 (Built-in Hooks)
└─► Phase 10 (Registry Integration)
Phase 8 (Lock Parser)
└─► Phase 9 (Lock Functions)
└─► Phase 10 (Registry Integration)
Phase 10 (Registry Integration)
└─► Phase 11 (Command Decorator Updates)
└─► Phase 12 (Help Command)
└─► Phase 13 (Documentation)
└─► Phase 14 (Testing)
Priority Ordering¶
P0 (Must Have): - Phases 1-3: Core argument parsing - Phases 5-6: Hook infrastructure and executor - Phases 8-10: Lock system and registry integration
P1 (Should Have): - Phase 4: Help generator - Phase 7: Built-in hooks - Phase 12: Help command integration
P2 (Nice to Have): - Phase 13: Documentation and examples - Phase 14: Performance benchmarks
Estimated Effort¶
| Phase | Effort | Dependencies |
|---|---|---|
| Phase 1 | 0.5 day | None |
| Phase 2 | 1 day | Phase 1 |
| Phase 3 | 0.5 day | Phase 2 |
| Phase 4 | 1 day | Phase 3 |
| Phase 5 | 0.5 day | None |
| Phase 6 | 1 day | Phase 5 |
| Phase 7 | 0.5 day | Phase 6 |
| Phase 8 | 1 day | None |
| Phase 9 | 1 day | Phase 8 |
| Phase 10 | 1 day | Phases 6, 9 |
| Phase 11 | 0.5 day | Phase 10 |
| Phase 12 | 0.5 day | Phases 4, 11 |
| Phase 13 | 1 day | Phase 12 |
| Phase 14 | 1 day | All |
Total: ~11 days