docs/designs/commands.md
You are an expert javascript and Node.js engineer implementing a backwards-compatible command subsystem for Hubot.
IMPORTANT: Use TDD. Start by writing tests that describe the behavior, then implement the code to make the tests pass. Do not begin implementation until you have written the tests. Keep changes small and incremental.
High-level goal: Add a new deterministic command bus to Hubot via robot.commands while preserving full backwards compatibility with existing robot.respond() and robot.hear() scripts. This must be safe-by-default and must not introduce broad “catch-all” behavior.
Constraints:
Behavioral requirements (what must be true):
A command is registered as:
{ args, context } (required)Parse messages like:
The command subsystem integrates with Hubot's receive middleware to intercept and handle commands:
These middleware handlers are implemented in Robot.setupCommandListeners() and must not interfere with normal chat or legacy hear/respond listeners. The middleware only acts on addressed messages (those directed at the robot) and commands that have been explicitly registered.
Allow register(spec, { bridge: “respond” | “hear” | “none” }) such that when bridge is enabled, a legacy listener is registered that delegates into the command system (but still does not swallow normal chat).
Emit events through an EventEmitter on robot.commands:
Logging Strategy: Fire-and-forget async logging to NDJSON file (default: .data/commands-events.ndjson). Each event is written individually and asynchronously. Set disableLogging: true during testing to prevent file I/O.
A) Write tests first. Include at least these test scenarios:
B) Only after tests exist, implement the smallest code to pass them.
C) Refactor as needed to keep code clean, depulication, software design that provides affordances.
Environment for tests:
Output format: