---
adr_number: 46
title: TUI Reference and Command System
status_history:
- - '2026-03-10'
  - Proposed
  - Jeffrey Phillips Freeman
- - '2026-03-10'
  - Accepted
  - Jeffrey Phillips Freeman
tier: 4
authors:
- Jeffrey Phillips Freeman
superseded_by: null
related_adrs:
- number: 2
  title: Namespace System
  relationship: The @ reference notation extends the namespace naming convention with resource path addressing
- number: 8
  title: Resource System
  relationship: Resource references in the @ notation resolve through the Resource Registry
- number: 9
  title: Project Model
  relationship: Project references in the @ notation resolve through the Project Registry
- number: 6
  title: Plan Lifecycle
  relationship: Plan references in the @ notation resolve through plan IDs
- number: 14
  title: Context Management (ACMS)
  relationship: Resolved @ references become priority items in the CRP for context assembly
- number: 44
  title: TUI Architecture and Framework
  relationship: The reference and command systems are input mechanisms within the TUI architecture
- number: 45
  title: TUI Persona System
  relationship: Persona scoped projects/plans interact with @ reference resolution
acceptance:
  votes_for:
  - voter: Jeffrey Phillips Freeman <Jeffrey.Freeman@CleverThis.com>
    comment: The unified @ reference notation with fuzzy search, combined with / command and ! shell prefixes, provides an ergonomic input system that bridges the multi-project domain model with natural typing patterns
  votes_against: []
  abstentions: []
---
## Context

CleverAgents manages multiple projects, plans, and resources simultaneously. In the CLI, users reference these entities by their full namespaced names or ULIDs in command arguments. In the TUI's conversational interface, users need a way to reference specific projects, plans, and resources inline within their natural-language prompts — without switching to a different screen or memorizing full identifiers.

Additionally, the TUI needs a command system for operations that are not natural-language prompts (session management, persona switching, configuration changes) and a shell mode for direct OS command execution. These three input modes — prompt with references, commands, and shell — must coexist in the same prompt input area with clear, unambiguous activation patterns.

The challenge is designing a reference notation that is:

1. **Ergonomic** — short enough for quick typing, with fuzzy search for discovery
2. **Unambiguous** — parseable without context-dependent grammar rules
3. **Hierarchical** — able to address resources within projects and decisions within plans
4. **Integrated** — resolved references become priority items in the ACMS context assembly pipeline, not just display tokens

## Decision Drivers

- Users should be able to reference any project, plan, or resource by typing `@` followed by a partial name, with intelligent fuzzy search narrowing results as they type
- The canonical reference format must be parseable, unique, and human-readable — it appears in the prompt text after selection and must be interpretable by both humans and the system
- Resolved references must integrate with the ACMS Context Request Protocol (CRP) to prioritize referenced resources in context assembly — this is not merely a UI feature but a semantic operation that affects plan behavior
- The `/` command prefix must provide a discoverable, extensible command system with tab completion — commands cover session management, persona operations, scope manipulation, and TUI configuration
- The `!` shell prefix must provide direct OS command execution with shell history and output display in the conversation stream
- All three input modes must be activatable and dismissable without mode confusion — the user must always know which mode they are in

## Decision

CleverAgents introduces three prompt input modes, each activated by a distinct prefix character at position 0:

1. **Normal mode** (default) — Natural-language prompts to the actor, with `@` inline references that trigger the Reference Picker overlay. The prompt symbol is `❯`.

2. **Command mode** (`/` at position 0) — TUI commands with tab completion via the Slash Command overlay. Not sent to the actor. The prompt symbol changes to `/`.

3. **Shell mode** (`!` at position 0) — Direct OS shell command execution. Output displayed as `ShellResult` blocks in the conversation. The prompt symbol changes to `$`.

Additionally, the `@` **Reference Picker** is a fuzzy-search overlay that activates when `@` is typed anywhere in a normal-mode prompt. It resolves partial input to fully qualified references using a defined notation grammar.

## Design

### Reference Notation Grammar

```
reference      ::= "@" qualified_ref
                  | "@" fuzzy_text

qualified_ref  ::= ref_type ":" identifier ( ":" resource_path )?
ref_type       ::= "project" | "plan"
identifier     ::= namespace_name | ulid
namespace_name ::= ( ( server ":" )? namespace "/" )? name
resource_path  ::= resource_name ( "/" path_segment )*
path_segment   ::= <any non-whitespace character except "/">+
resource_name  ::= <registered resource name within the project>
fuzzy_text     ::= <any non-whitespace characters triggering fuzzy search>
```

#### Reference Examples

| User Types | Canonical Expansion | What It References |
|-----------|--------------------|--------------------|
| `@project:cleveragents` | `@project:local/cleveragents` | The entire CleverAgents project |
| `@project:cleveragents:git_dir/src/foo.py` | `@project:local/cleveragents:git_dir/src/foo.py` | A specific file in the project's git resource |
| `@plan:01HXM8C2` | `@plan:01HXM8C2` | A specific plan by ULID |
| `@plan:01HXM8C2:decision/D3` | `@plan:01HXM8C2:decision/D3` | A specific decision within a plan |
| `@foo.py` | `@project:local/cleveragents:git_dir/src/foo.py` | Fuzzy match → expands to canonical form |
| `@api-service` | `@project:local/api-service` | Fuzzy match → expands to project reference |
| `@handler.py` | *(popup shows multiple matches)* | Fuzzy match with multiple candidates |

### Reference Picker Overlay

The Reference Picker is a floating panel that appears above the prompt when `@` is typed. It provides real-time fuzzy search across all registered projects, plans, and resources.

#### Activation and Lifecycle

1. User types `@` anywhere in the prompt → overlay appears with all items (most recent first)
2. User continues typing after `@` → overlay filters results in real-time
3. User navigates with `up`/`down` arrows → highlight moves through results
4. User presses `enter` → selected item's canonical reference replaces the `@...` text in the prompt
5. User presses `escape` → overlay dismisses, `@` text remains as typed (treated as literal text)
6. User presses `tab` → switches from search mode to tree browser mode (hierarchical navigation)

#### Fuzzy Search Algorithm

The search operates across three entity types simultaneously:

1. **Projects**: searched by name, namespace, and description
2. **Plans**: searched by name, ULID prefix, action name, and description
3. **Resources**: searched by name, type, and file paths within the resource DAG

Matching uses a weighted fuzzy algorithm:

- **Exact prefix match**: weight 1.0 (e.g., `foo` matches `foo.py` at 1.0)
- **Substring match**: weight 0.7 (e.g., `handler` matches `auth_handler.py` at 0.7)
- **Path component match**: weight 0.8 (e.g., `auth/handler` matches `src/auth/handler.py` at 0.8)
- **Fuzzy character match**: weight 0.4 (e.g., `ahp` matches `auth_handler.py` at 0.4)

Results are sorted by: (1) match weight descending, (2) recency of access descending, (3) alphabetical name ascending.

#### Result Display Format

Each result shows its type, canonical reference, and contextual information:

```
┌─ Reference Picker ───────────────────────────────────────────┐
│ @hand                                                        │
│ ──────────────────────────────────────────────────────────── │
│  PROJECT  api-service:src/auth/handler.py                    │
│           local/api-service • Python • 245 lines             │
│                                                              │
│  PROJECT  cleveragents:git_dir/src/cli/commands/handler.py   │
│           local/cleveragents • Python • 189 lines            │
│                                                              │
│  PROJECT  api-service:src/auth/middleware/handler_base.py    │
│           local/api-service • Python • 67 lines              │
│                                                              │
│  PLAN     fix-auth-handler (01HXM8C2...)                     │
│           Phase: Execute • Actor: claude-4-sonnet            │
│                                                              │
│ ──────────────────────────────────────────────────────────── │
│ enter Select │ tab Tree │ ctrl+p Projects │ ctrl+l Plans     │
└──────────────────────────────────────────────────────────────┘
```

#### Filter Shortcuts

While the Reference Picker is open:

| Key | Action |
|-----|--------|
| `ctrl+p` | Filter to projects only |
| `ctrl+l` | Filter to plans only |
| `ctrl+r` | Filter to resources only (across all projects) |
| `ctrl+a` | Clear filter (show all types) |
| `tab` | Switch to tree browser mode |
| `escape` | Dismiss overlay |

#### Tree Browser Mode

When the user presses `tab` in the Reference Picker, it switches from search mode to tree browser mode. This shows a navigable tree:

```
┌─ Reference Picker (Tree) ────────────────────────────────────┐
│                                                              │
│  ▼ Projects                                                  │
│    ▼ local/cleveragents                                      │
│      ▼ git_dir (git-checkout)                                │
│        ▸ src/                                                │
│        ▸ tests/                                              │
│        ▸ docs/                                               │
│        ─ pyproject.toml                                      │
│        ─ README.md                                           │
│      ▸ database (sqlite-db)                                  │
│    ▸ local/api-service                                       │
│    ▸ local/frontend-app                                      │
│  ▼ Plans                                                     │
│    ▸ fix-auth-bug (01HXM8C2)                                 │
│    ▸ refactor-models (01HXM9D3)                              │
│                                                              │
│ enter Select │ tab Search │ space Expand │ / Filter          │
└──────────────────────────────────────────────────────────────┘
```

Navigation uses standard tree controls: `up`/`down` to move, `space` or `right` to expand, `left` to collapse, `enter` to select.

### ACMS Integration

When a prompt contains resolved `@` references, those references are translated into CRP (Context Request Protocol) directives before the prompt is sent to the actor:

1. **Project references** (`@project:local/api-service`) → the project is added to the plan's project scope, and all its resources receive elevated priority in context assembly
2. **Resource path references** (`@project:local/api-service:src/auth/handler.py`) → the specific resource and path are marked as `focus` items in the CRP, receiving the highest priority tier in the context budget
3. **Plan references** (`@plan:01HXM8C2`) → the plan's decision tree and current state are included as context, enabling cross-plan awareness
4. **Decision references** (`@plan:01HXM8C2:decision/D3`) → the specific decision's context snapshot, rationale, and downstream impact are included as focus items

This integration means that `@` references are not merely display annotations — they semantically direct the ACMS to prioritize specific information when assembling the actor's context window.

#### Priority Interaction with Persona Scope

The effective scope for context assembly is the union of:

1. **Persona scoped projects/plans** (always present, baseline priority)
2. **Prompt @ references** (additive, elevated priority)

When a resource is both persona-scoped and explicitly `@`-referenced, the explicit reference takes precedence for priority elevation. This means `@`-referencing a file in an already-scoped project still has the effect of focusing the context on that specific file.

### Command System (/ Prefix)

Commands are TUI operations that execute immediately without being sent to the actor. They are activated by typing `/` as the first character of the prompt.

#### Slash Command Overlay

When `/` is typed at position 0, the Slash Command overlay appears with filterable command list:

```
┌─ Commands ───────────────────────────────────────────────────┐
│ /se                                                          │
│ ──────────────────────────────────────────────────────────── │
│  /session:create       Create a new session tab              │
│  /session:list         Show all sessions                     │
│  /session:show         Show session details                  │
│  /session:switch       Switch to session by ID               │
│  /session:close        Close current session                 │
│  /session:delete       Delete a saved session                │
│  /session:rename       Rename current session                │
│  /session:export       Export session to file                │
│  /session:import       Import session from file              │
│  /settings             Open settings screen                  │
│                                                              │
│ enter Execute │ tab Complete │ escape Dismiss                │
└──────────────────────────────────────────────────────────────┘
```

#### Complete Command Reference

**Session Commands** — *mirrors CLI `agents session <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/session:create` | `[--persona <name>]` | Create a new session tab, optionally with a specific persona |
| `/session:list` | — | Display all sessions with IDs, personas, and last activity |
| `/session:show <id>` | `<id>` (required) | Show session details (persona, actor, message count, cost) |
| `/session:switch <id>` | `<id>` (required) | Switch to a session by its ID or tab index |
| `/session:close` | `[--force]` | Close the current session tab (confirms if conversation exists) |
| `/session:delete <id>` | `<id>` (required), `[--yes/-y]` | Permanently delete a saved session (with confirmation) |
| `/session:rename <name>` | `<name>` (required) | Rename the current session's display label |
| `/session:export [path]` | `[path]` (optional, defaults to `./<session-name>.json`) | Export the current session's conversation history to a JSON file |
| `/session:import <path>` | `<path>` (required) | Import a session from a previously exported JSON file |

**Persona Commands**

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/persona:list` | — | Display all personas with their actors, scopes, and cycle positions |
| `/persona:set <name>` | `<name>` (required) | Switch to a persona by name (updates actor and scope immediately) |
| `/persona:create` | — | Open the PersonaEditorModal for creating a new persona |
| `/persona:edit [name]` | `[name]` (optional, defaults to current) | Open the PersonaEditorModal for an existing persona |
| `/persona:delete <name>` | `<name>` (required) | Delete a persona (confirms before deletion) |
| `/persona:export <name>` | `<name>` (required) | Export a persona's YAML to the current directory |
| `/persona:import <path>` | `<path>` (required) | Import a persona from a YAML file |

**Scope Commands**

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/scope:add <ref>` | `<ref>` (required, e.g., `project:local/api-service`) | Add a project or plan to the current session's scope (additive to persona scope) |
| `/scope:remove <ref>` | `<ref>` (required) | Remove a project or plan from the current session's scope |
| `/scope:clear` | — | Clear all session-level scope additions (persona scope remains) |
| `/scope:show` | — | Display the effective scope (persona + session additions) |

**Plan Commands** — *mirrors CLI `agents plan <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/plan:use <action> [projects...]` | `<action>` (required), `[projects...]`, `[--arg/-a <key=value>]...` `[--automation-profile <name>]` `[--invariant <text>]...` | Start a new plan from an action |
| `/plan:list` | `[--phase <phase>]` `[--state <state>]` `[--project <name>]` `[--action <name>]` | List plans, optionally filtered |
| `/plan:status [id]` | `[id]` (optional, defaults to current plan) | Show detailed plan status in a conversation block |
| `/plan:tree <id>` | `<id>` (required), `[--show-superseded]` `[--depth <n>]` | Show the plan's decision tree in a conversation block |
| `/plan:execute [id]` | `[id]` (optional, defaults to current plan) | Execute a plan that has completed strategize phase |
| `/plan:apply [id]` | `[id]` (optional, defaults to current plan) | Apply a completed plan (confirms before apply) |
| `/plan:cancel <id>` | `<id>` (required), `[--reason/-r <text>]` | Cancel a running plan (confirms before cancellation) |
| `/plan:diff <id>` | `<id>` (required), `[--correction]` | Show the plan's diff in a DiffView block |
| `/plan:correct <did>` | `<did>` (required), `--mode/-m revert\|append` (required), `--guidance/-g <text>` (required), `[--yes/-y]` | Correct a decision in a plan |
| `/plan:resume <id>` | `<id>` (required), `[--dry-run]` | Resume a paused or failed plan |
| `/plan:revert <id>` | `<id>` (required), `[--to-phase <phase>]` `[--reason/-r <text>]` | Revert a plan to an earlier phase |
| `/plan:rollback <id> <checkpoint>` | both required, `[--yes/-y]` | Rollback plan to a specific checkpoint |
| `/plan:explain <did>` | `<did>` (required), `[--show-context]` `[--show-reasoning]` | Explain a decision's rationale and context |
| `/plan:errors <id>` | `<id>` (required) | Show plan errors in a conversation block |
| `/plan:artifacts <id>` | `<id>` (required) | Show plan artifacts in a conversation block |
| `/plan:inspect [id]` | `[id]` (optional, defaults to current plan) | Open the PlanDetailModal for a plan |

**Project Commands** — *mirrors CLI `agents project <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/project:list` | `[--namespace/-n <ns>]` | List all registered projects |
| `/project:create <name>` | `<name>` (required), `[--description/-d <text>]` `[--resource/-r <name>]...` | Create a new project |
| `/project:show <name>` | `<name>` (required) | Show project details in a conversation block |
| `/project:delete <name>` | `<name>` (required), `[--yes/-y]` | Delete a project (with confirmation) |
| `/project:inspect <name>` | `<name>` (required) | Open the ProjectDetailModal for a project |
| `/project:context:show <name>` | `<name>` (required), `[--view/-v <view>]` | Show project context configuration |

**Actor Commands** — *mirrors CLI `agents actor <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/actor:list` | — | List all registered actors |
| `/actor:show <name>` | `<name>` (required) | Show actor details (configuration, argument schema, capabilities) |
| `/actor:set-default <name>` | `<name>` (required) | Set the default actor for new sessions |

**Resource Commands** — *mirrors CLI `agents resource <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/resource:list [project]` | `[project]` (optional), `[--type/-t <type>]` | List resources, optionally scoped to a project or type |
| `/resource:show <name>` | `<name>` (required) | Show resource details (type, properties, DAG position) |
| `/resource:tree [project]` | `[project]` (optional), `[--depth/-d <n>]` | Show the resource DAG as a tree |
| `/resource:inspect <name>` | `<name>` (required) | Show detailed resource info with children and validations |

**Automation Profile Commands** — *mirrors CLI `agents automation-profile <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/profile:list` | — | List available automation profiles |
| `/profile:show <name>` | `<name>` (required) | Show automation profile details (thresholds, safety settings) |

**Invariant Commands** — *mirrors CLI `agents invariant <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/invariant:list` | `[--project <name>]` `[--plan <id>]` `[--global]` `[--effective]` | List invariant constraints |
| `/invariant:add <text>` | `<text>` (required), `[--global]` `[--project <name>]` `[--plan <id>]` | Add an invariant constraint |
| `/invariant:remove <id>` | `<id>` (required), `[--yes/-y]` | Remove an invariant constraint |

**Config Commands** — *mirrors CLI `agents config <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/config:list [pattern]` | `[pattern]` (optional glob) | List configuration keys and values |
| `/config:get <key>` | `<key>` (required) | Show a configuration value |
| `/config:set <key> <value>` | both required | Set a configuration value |

**Tool Commands** — *mirrors CLI `agents tool <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/tool:list` | `[--namespace/-n <ns>]` `[--type/-t <type>]` | List registered tools |
| `/tool:show <name>` | `<name>` (required) | Show tool details (capabilities, argument schema) |

**Skill Commands** — *mirrors CLI `agents skill <verb>`*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/skill:list` | `[--namespace/-n <ns>]` | List registered skills |
| `/skill:show <name>` | `<name>` (required) | Show skill details and provided tools |

**TUI Commands** — *TUI-only utility commands*

| Command | Arguments | Description |
|---------|-----------|-------------|
| `/clear` | — | Clear the conversation display (does not delete session history) |
| `/theme [name]` | `[name]` (optional, shows current if omitted) | Switch the TUI color theme |
| `/settings` | — | Open the SettingsScreen |
| `/help [command]` | `[command]` (optional) | Show help for a specific command, or list all commands |
| `/about` | — | Show CleverAgents version, build info, and system status |
| `/debug` | — | Toggle debug mode (shows A2A events, widget boundaries, performance metrics) |

#### Command Extensibility

Actors can register additional slash commands via A2A. When an actor session is established, the actor may provide an `AvailableCommandsUpdate` message listing actor-specific commands. These appear in the Slash Command overlay with the actor's namespace prefix:

```
/claude:explain         Ask Claude to explain its reasoning
/claude:summarize       Summarize the conversation so far
/claude:focus <topic>   Focus subsequent responses on a topic
```

### Shell Mode (! Prefix)

Shell mode provides direct OS command execution from the TUI prompt.

#### Activation and Behavior

1. User types `!` as the first character → prompt symbol changes from `❯` to `$`, prompt background tints to indicate shell mode
2. User types a shell command (e.g., `!git status`)
3. User presses `enter` → command executes on the host OS via subprocess
4. Output appears as a `ShellResult` block in the conversation stream
5. After execution, the prompt returns to normal mode

#### Shell Mode Characteristics

| Aspect | Behavior |
|--------|----------|
| **Working directory** | The host OS current directory (where `agents` was launched), NOT a project resource directory |
| **History** | Separate history from prompt history; navigable with `up`/`down` while in shell mode |
| **Tab completion** | File/directory path completion from the host filesystem |
| **Syntax highlighting** | Bash/shell syntax highlighting in the prompt |
| **Dangerous command detection** | Commands matching destructive patterns (e.g., `rm -rf /`, `git push --force`) are highlighted in `$error` color with a confirmation prompt |
| **Long-running commands** | Output streams in real-time; `ctrl+c` sends SIGINT to the subprocess |
| **Exit** | `escape` exits shell mode back to normal prompt mode (if no command is being typed); otherwise clears the current input |

#### Shell Result Display

```
  $ git status
  ┌─────────────────────────────────────────────────────────┐
  │ On branch main                                          │
  │ Your branch is up to date with 'origin/main'.           │
  │                                                         │
  │ Changes not staged for commit:                          │
  │   modified:   src/auth/handler.py                       │
  │   modified:   src/auth/middleware.py                    │
  │                                                         │
  │ Untracked files:                                        │
  │   src/auth/limiter.py                                   │
  └─────────────────────────────────────────────────────────┘
```

Shell results have a `$primary` left border and `$foreground 4%` background, distinguishing them from actor responses and user prompts.

### Input Mode Summary

| First Character | Mode | Prompt Symbol | Sent To | Overlay |
|-----------------|------|---------------|---------|---------|
| *(any other)* | Normal | `❯` | Actor via A2A `message/send` | — |
| `@` *(inline)* | Normal + Reference | `❯` | Actor (with resolved references as CRP directives) | ReferencePickerOverlay |
| `/` | Command | `/` | TUI command processor (local) | SlashCommandOverlay |
| `!` | Shell | `$` | Host OS subprocess | — |

### Multi-line Input

In normal mode, the prompt supports multi-line input:

- `shift+enter` or `ctrl+j` inserts a newline (prompt symbol changes to `☰`)
- In multi-line mode, `shift+enter` or `ctrl+j` submits the prompt
- `escape` in multi-line mode with no overlay visible returns to single-line mode (discarding extra lines if empty)

In shell mode, multi-line input is supported via backslash continuation (`\` at end of line) following standard shell conventions.

Command mode (`/`) is always single-line.

## Constraints

- The `@` character must always trigger the Reference Picker when typed in normal mode, regardless of cursor position — it is never treated as a literal character in prompts (users who need a literal `@` can use `\@`)
- The `/` character triggers command mode only at position 0 of an empty or beginning-of-line prompt — `/` in the middle of text is literal
- The `!` character triggers shell mode only at position 0 — `!` in the middle of text is literal
- Reference resolution must complete within 200ms for interactive responsiveness; the fuzzy search index must be pre-built and incrementally updated
- All `/` commands must have consistent argument parsing: positional arguments are space-separated, named arguments use `--flag value` syntax, matching the CLI convention
- Shell mode commands execute with the same user permissions as the `agents` process — no privilege escalation is possible
- The Reference Picker must not block the main event loop — search operations run in a worker thread with debounced input (100ms)

## Consequences

### Positive

- The `@` reference system provides a natural, conversational way to direct the actor's attention to specific resources — `"review @project:api-service:src/auth/handler.py"` reads naturally and has precise semantic effect on context assembly
- Fuzzy search means users rarely need to type full canonical references — `@handler.py` is sufficient when there's a clear best match
- The `/` command system provides a discoverable, tab-completable interface for all TUI operations — users can discover available commands without memorizing hotkeys
- Shell mode (`!`) provides a convenient escape hatch for quick OS operations without leaving the TUI
- The three-mode design (normal/command/shell) provides clear separation of concerns with unambiguous activation — there is never confusion about which mode a keystroke will be interpreted in
- ACMS integration means `@` references have real semantic effect: they don't just annotate the prompt, they direct the context assembly pipeline to prioritize the referenced resources

### Negative

- The `@` character cannot be used literally in prompts without escaping (`\@`) — this may confuse users who habitually use `@` in email addresses or social media handles in their prompts
- The command namespace (`/session:*`, `/persona:*`, etc.) may become crowded as features are added — the colon-separated namespace helps, but discoverability depends on good tab completion
- Shell mode operates on the host OS, not on project resources — users expecting `!ls` to list files in a project resource will need to understand the distinction

### Risks

- Fuzzy search performance may degrade with very large resource registries (thousands of resources across many projects) — the search index should be bounded and prioritize recently-accessed resources
- Reference resolution ambiguity: when `@foo.py` matches files in multiple projects, the user must select from the popup — this is extra friction compared to single-project tools where `@foo.py` is always unambiguous
- Actor-provided commands via `AvailableCommandsUpdate` could conflict with built-in commands — the system must enforce that actor commands are always prefixed with the actor's namespace (e.g., `/claude:*`)

## Alternatives Considered

**Hashtag notation (`#`) instead of `@`** — Some systems use `#` for references. Rejected because `@` is more universally associated with "mentioning" or "referencing" entities (email, social media, IDE go-to-symbol) and `#` is commonly used for comments in code-adjacent contexts, which could cause confusion.

**Separate reference input field** — A dedicated input area for adding references, separate from the prompt. Rejected because it breaks the natural flow of typing a prompt — the user would need to switch focus, add references, switch back, and type the prompt. Inline `@` references keep everything in one place.

**IDE-style Ctrl+Space completion** — Trigger a general completion menu with `ctrl+space` that includes references, commands, and shell. Rejected because it conflates three distinct input modes into one mechanism, making the UI less predictable. The distinct prefix characters (`@`, `/`, `!`) provide clear affordances.

**SQL-like FROM clause** — Require explicit scope declaration before the prompt: `FROM project:api-service SELECT review auth module`. Rejected as overly formal for a conversational interface. The `@` inline notation is more natural.

## Compliance

- **Grammar tests**: Parser tests verify that all reference notation examples in this ADR parse correctly to their canonical form
- **Fuzzy search tests**: Search algorithm tests verify ranking correctness (exact > substring > path > fuzzy) with fixed test datasets
- **Resolution tests**: Integration tests verify that `@` references resolve through the actual Project/Plan/Resource registries via A2A
- **ACMS integration tests**: Verify that resolved references produce correct CRP directives and that referenced resources appear in assembled context with elevated priority
- **Command tests**: Every `/` command has a test that simulates input and verifies the expected TUI action (screen push, state change, conversation block)
- **Shell mode tests**: Verify that `!` commands execute via subprocess, output appears as ShellResult blocks, and `ctrl+c` interrupts running commands
- **Performance tests**: Fuzzy search benchmarks verify < 200ms response time with 10,000+ resources in the index
- **Overlay tests**: Pilot tests verify that overlays appear on trigger, filter correctly as the user types, and dismiss on escape/selection
- **Escaping tests**: Verify that `\@` produces a literal `@` in the prompt text and does not trigger the Reference Picker
