How Detection Works
Every keystroke in Auto mode passes through a single function: lacy_shell_classify_input(). It returns shell, agent, or neutral. All routing and visual feedback flows from this one source of truth.
The six-rule cascade
Rules are evaluated in order. The first match wins.
| # | Condition | Route | Example |
|---|---|---|---|
| 1 | First word is an agent word | Agent | what files are here |
| 2 | First word is a shell reserved word | Agent | do we have auth? |
| 3 | First word is a valid command | Shell | git status |
| 4 | Single word, not a command | Shell | cd.. (typo) |
| 5 | Multiple words, first not a command | Agent | fix the bug |
| 6 | Valid command fails with NL-style args | Shell → Agent | kill the process on :3000 |
Agent words (Rule 1)
About 150 common conversational words that trigger agent routing regardless of whether they're valid shell commands. These are defined in LACY_AGENT_WORDS inlib/core/constants.sh.
Examples: what, why, how, fix, explain,help, show, list, find, yes, no,thanks, perfect, can, could, should,would, is, are, does.
Agent words match even as single-word inputs. Typing thanks alone routes to agent.
Shell reserved words (Rule 2)
Shell reserved words (do, done, then, else,elif, fi, in, select, etc.) passcommand -v but are never valid as the first token of a standalone invocation.
When a user types do we have X or in the codebase where is auth?, that's natural language, not a shell command.
Post-execution reroute (Rule 6)
When a valid command receives natural-language-style arguments and fails (exit code 1–127), Lacy analyzes the error output. If it matches a known error pattern AND the input has NL markers, the command silently rerouts to the agent.
Both criteria must match for reroute: an error pattern from LACY_SHELL_ERROR_PATTERNSAND an NL signal (second word in LACY_NL_MARKERS, or 5+ words with a parse/syntax error).
Only active in Auto mode. The reroute is silent — no user-facing hint.
Mode-aware behavior
The cascade only applies in Auto mode. In Shell mode, everything routes to shell. In Agent mode, everything routes to agent. The visual indicator always reflects the current routing decision.
Implementation
# Single source of truth: lib/core/detection.sh
lacy_shell_classify_input "$input"
# Returns: "shell" | "agent" | "neutral"All consumers — the real-time indicator, execute routing, and first-word syntax highlighting — call this single function. Never create parallel detection logic.