# ADR-0003: Input modes and command dispatch

## Status

Accepted

## Context

The input field accepts three logically distinct kinds of input:

1. **App DSL data commands** — simplified, space-separated forms
   like `create table Customers` or
   `add column to table Customers: Name (string)`. These are the
   primary teaching surface for beginners.
2. **App-level commands** — operations on the application itself
   rather than the data: `save`, `load`, `export`, `quit`,
   `undo`, `seed`, etc. These should always be available
   regardless of mode.
3. **Raw SQL** — for users ready to type SQL directly, including
   DDL and queries.

Beginners should not be exposed to SQL by accident, but advanced
users should not be punished for wanting to drive the app entirely
from the keyboard. Auto-detecting "is this SQL?" is unreliable
because the same first words (`create table …`) appear in both the
DSL and SQL.

## Decision

The input field has two modes, switchable by the user:

- **Simple mode** (default).
  - Accepts app DSL data commands and app-level commands.
  - Raw SQL is not executed; instead the input is recognised as
    SQL and a friendly hint suggests switching to advanced mode or
    using the one-shot escape (below).
  - The mode is indicated by a label above the input field
    (e.g. `Simple`).

- **Advanced mode**.
  - Accepts raw SQL by default.
  - App-level commands (the canonical list below) are still
    recognised without any prefix — forcing users to switch back
    to simple mode for these would be user-hostile, and advanced
    users are exactly the ones most likely to live in
    command-driven workflows.
  - Mode is indicated by a label and a distinct input border
    colour to make the elevated mode visually obvious.

- **One-shot escape with `:` in simple mode.**
  - Prefixing a single line with `:` interprets it as advanced
    input for that submission only. The prompt label changes
    (e.g. `Advanced:`) while the prefix is present.
  - This is the only sigil in the system. App-level commands
    never use a sigil.

The set of "always available" app-level commands is enumerated
explicitly; it is not heuristic. The initial canonical list is:

| Command   | Effect                                                  |
|-----------|---------------------------------------------------------|
| `save`    | Persist the project to its current location.            |
| `save as` | Persist the project to a chosen name and location.      |
| `load`    | Open the load dialog (project picker).                  |
| `new`    | Start a new auto-named temporary project.               |
| `export`  | Produce a shareable zip (ADR-0007).                     |
| `import`  | Open an exported project zip.                           |
| `seed`    | Generate sample data (rules per a future ADR).          |
| `replay`  | Replay a `history.log` or `.commands` script.           |
| `undo`    | Restore the most recent snapshot (ADR-0006).            |
| `redo`    | Re-apply an undone state (ADR-0006).                    |
| `mode`    | Switch between simple and advanced (`mode simple`/`mode advanced`). |
| `help`    | Show contextual help.                                   |
| `hint`    | Request a hint for the current input (ADR pending).     |
| `quit`    | Exit the application.                                   |

This list is **definitive** and applies in both modes. Adding,
removing, or renaming a command requires either:

- **Before code exists:** an amendment to this ADR.
- **Once code exists:** the in-code command registry becomes the
  source of truth; this ADR is updated to point at the registry,
  and any change to the registry's public surface still requires
  an ADR note explaining the change.

Commands that operate on the data (e.g. `create table`,
`add column`, `create m:n relationship`) are **not** in this list
— they are DSL data commands and behave per the simple/advanced
mode rules above.

## Consequences

- Parsing must distinguish three categories — app-level command,
  DSL data command, or SQL — and the mode determines what happens
  if the input does not match the first two.
- Mode state is per-input-session and persists across submissions
  until changed.
- Visual distinction (label, border colour) is required for safety:
  users must always know whether their next submission will be
  treated as SQL.
- The `:` escape lets advanced users in simple mode run a quick
  query without flipping modes — useful during teaching when an
  instructor wants to demonstrate SQL once.
