# Feature Spec: CLI Shell Tab Completion for `aop` Commands

> **Purpose of this document**: Define an implementation-ready plan to add shell tab completion so typing `aop <TAB>` (or equivalent double-tab listing) shows available commands and reduces CLI discovery friction.

**Version:** 1.0  
**Date:** 2026-03-05  
**Status:** Draft  
**Roadmap Mapping:** M48

---

## 0. Standards and Dependencies

### 0.1 Required Standards

All implementation MUST preserve:

- deterministic JSON success/error envelopes for regular CLI commands
- backward compatibility for existing command behavior and flags
- `npm run lint`, `npm run typecheck`, and `npm test` pass gates
- coverage thresholds: Lines >=90%, Branches >=90%, Functions >=90%, Statements >=90%

### 0.2 Required Upstream Inputs

Implementing agents MUST read:

- `apps/control-plane/src/cli/types.ts`
- `apps/control-plane/src/cli/cli-argument-parser.ts`
- `apps/control-plane/src/cli/help-command-handler.ts`
- `apps/control-plane/src/cli/aop.ts`
- `apps/control-plane/src/interfaces/cli/bootstrap.ts`
- `apps/control-plane/test/cli-helpers.spec.ts`
- `apps/control-plane/test/cli.unit.spec.ts`
- `apps/control-plane/test/aop.spec.ts`
- `README.md`
- `AGENTS.md`
- `CLAUDE.md`

### 0.3 Scope

This spec implements:

- shell completion command generation (`aop completion <bash|zsh|fish>`)
- internal completion backend command (`aop __complete ...`) used by shell scripts
- top-level command completion (`run`, `status`, `resume`, `stop`, `delete`, `cleanup`, `init`, `dashboard`, `retry`, `send`, `attach`, `help`, `completion`)
- optional flag-level completion for known subcommands in the same release scope
- documentation for installation/activation in Bash, Zsh, and Fish

Out of scope:

- PowerShell completion in M48 (can be follow-up)
- interactive fuzzy completion UIs
- completion for arbitrary filesystem paths beyond shell-native default completion

### 0.4 OOP and Architecture Guardrails (Mandatory)

Implementation MUST follow:

- **KISS**: one completion engine, one script generator per shell, no framework dependency
- **SRP**: command metadata, completion resolution, and shell script rendering are separate modules
- **SOLID-oriented design**:
  - open/closed extension for new commands/flags without rewriting shell scripts
  - interface segregation between command catalog reader and completion resolver
  - dependency inversion from bootstrap to handler interfaces
- **Hexagonal alignment**: completion logic remains in `cli/*`; no kernel/domain coupling required for static command completions
- **Composition over inheritance**: completion handler composes catalog + renderer + resolver
- **High cohesion / low coupling**: help rendering and completion share metadata, not duplicated literals

---

## 1. Problem Statement

### 1.1 Current UX Gap

Today `aop` does not expose shell completion scripts. Users must memorize commands or repeatedly run `aop --help`.

### 1.2 User Outcome Required

When a user types `aop` and presses tab in a configured shell, they must see available commands.

### 1.3 Success Definition

- discoverability improves without changing core command execution behavior
- completion remains synchronized with command/flag changes over time
- no impact to non-interactive CLI usage

---

## 2. UX Contract (Normative)

### 2.1 Public Command

Add public command:

```text
aop completion <bash|zsh|fish>
```

Behavior:

- prints shell completion script to `stdout`
- emits raw script text (not JSON envelope) so `source <(aop completion <shell>)` works directly
- unknown shell returns `invalid_cli_args` with supported shells list

### 2.2 Internal Completion Backend

Add internal command:

```text
aop __complete <shell> <cword> [tokens...]
```

Definitions:

- `shell`: `bash|zsh|fish`
- `cword`: cursor word index (0-based within `tokens` passed to backend)
- `tokens`: command tokens excluding executable path

Output contract:

- newline-delimited candidate tokens to `stdout`
- no JSON envelope for this internal command (shell parsing requires raw candidates)
- empty output is valid (no candidates)

### 2.3 Minimum Completion Behavior (M48 Required)

Required in first implementation:

- `aop <TAB>` lists all public commands
- `aop he<TAB>` completes/suggests `help`
- `aop completion <TAB>` suggests `bash`, `zsh`, `fish`

Required when `cword` resolves to subcommand flag position:

- suggest supported flags for that subcommand
- do not suggest flags already present unless flag is repeatable (none are repeatable in current contract)

Optional but in-scope if low risk:

- `--project` value suggestions from `multi-project.yaml`
- `--feature-id` suggestions from `.aop/features/index.json` active/blocked/merged ids

If optional dynamic completions are implemented, they MUST degrade gracefully (empty suggestions, no hard failure) when files are missing.

---

## 3. Architecture Design

### 3.1 Single Source of Truth for CLI Metadata

Create shared command catalog module:

```text
apps/control-plane/src/cli/command-catalog.ts
```

Required contents:

- public command list
- per-command usage + description
- per-command flags (name, takesValue, valueHint)
- subcommand visibility (`hidden` for `__complete`)

`help-command-handler.ts` MUST render from this catalog (eliminate duplicated literals).

Completion resolver MUST also read from this catalog.

### 3.2 New CLI Modules

Create:

- `apps/control-plane/src/cli/completion-command-handler.ts`
- `apps/control-plane/src/cli/complete-command-handler.ts`
- `apps/control-plane/src/cli/completion-shell-renderer.ts`
- `apps/control-plane/src/cli/completion-resolver.ts`

Responsibilities:

- `CompletionCommandHandler`: validates shell argument and prints shell script
- `CompleteCommandHandler`: resolves completion candidates from `cword + tokens`
- `completion-shell-renderer`: emits shell-specific wrapper that calls `aop __complete`
- `completion-resolver`: pure candidate selection logic using catalog + optional context providers

### 3.3 Command Wiring

Update:

- `apps/control-plane/src/cli/types.ts`
  - add `CliCommand.Completion = 'completion'`
  - add `CliCommand.InternalComplete = '__complete'`
- `apps/control-plane/src/cli/cli-argument-parser.ts`
  - parse new command tokens without regressing default `run` behavior
  - parse `completion` shell arg and `__complete` raw args
- `apps/control-plane/src/interfaces/cli/bootstrap.ts`
  - dispatch both commands before kernel-heavy initialization paths
  - ensure `__complete` returns raw text output path

### 3.4 Shell Script Generation Contract

`aop completion bash` output MUST:

- define completion function `_aop_completion`
- call `aop __complete bash "$COMP_CWORD" "${COMP_WORDS[@]:1}"`
- assign candidates into `COMPREPLY`
- register with `complete -F _aop_completion aop`

`aop completion zsh` output MUST:

- define `_aop_completion`
- call `aop __complete zsh "$CURRENT" "${words[@]:2}"`
- split newline output into array
- register via `compdef _aop_completion aop`

`aop completion fish` output MUST:

- define helper function for invoking `aop __complete fish`
- register via `complete -c aop -f -a "(__aop_complete)"`

Scripts MUST avoid external dependencies (no requirement on `bash-completion` package helpers).

### 3.5 Error and Exit Semantics

- `aop completion <shell>`
  - success: exit `0`
  - invalid shell/missing arg: exit `1` with `invalid_cli_args`
- `aop __complete ...`
  - success or no candidates: exit `0`
  - malformed backend args: exit `0` and emit no candidates (shell-safe)

Rationale: completions should never spam terminal with errors during tab presses.

---

## 4. Detailed Implementation Plan

### M48.1 — Shared Catalog Extraction

Goal: remove divergence risk between help text and completion candidates.

Changes:

- create `command-catalog.ts`
- migrate `COMMAND_HELP` source into catalog-backed structure
- keep existing help output text unchanged for current tests

### M48.2 — Completion Command Surface

Goal: add `aop completion` and hidden `aop __complete` command routing.

Changes:

- update `types.ts`, `cli-argument-parser.ts`, `bootstrap.ts`
- add new handlers and resolver modules
- add hidden command exclusion from main help command list

### M48.3 — Shell Renderers

Goal: support Bash/Zsh/Fish script emission.

Changes:

- implement shell renderer module
- validate script output consistency with snapshot/string tests
- ensure scripts use installed `aop` binary name (not `npm run run`)

### M48.4 — Optional Dynamic Value Completion (In-Scope)

Goal: improve common flag-value UX while preserving robustness.

Changes:

- add project-name provider for `--project`
- add feature-id provider for `--feature-id`
- swallow local read failures and return empty candidates

### M48.5 — Documentation and Command Guide Updates

Goal: make feature discoverable and keep assistant docs aligned.

Changes:

- update `README.md` with install snippets for Bash/Zsh/Fish
- update `AGENTS.md` and `CLAUDE.md` command listings to include `completion`
- add help text entry for `completion`

---

## 5. Test Strategy (Required)

### 5.1 Unit Tests

Add/extend in:

- `apps/control-plane/test/cli-helpers.spec.ts`
- `apps/control-plane/test/cli.unit.spec.ts`

Minimum cases:

1. parser recognizes `completion` and internal `__complete`
2. `HelpCommandHandler` includes `completion` and excludes `__complete`
3. `CompletionCommandHandler` returns scripts for each supported shell
4. unsupported shell returns `invalid_cli_args`
5. resolver returns top-level command set for cursor at command position
6. resolver returns subcommand flags for command-specific flag position
7. resolver excludes already-used one-shot flags

### 5.2 Integration-Like CLI Cases

Add in `apps/control-plane/test/cli.unit.spec.ts`:

1. `main(['completion', 'bash'])` returns exit `0` and script content includes registration command
2. `main(['completion', 'bogus'])` returns exit `1` and structured error
3. `main(['__complete', 'bash', '1', ''])` returns candidate list output and exit `0`

### 5.3 Regression Safety

- existing help tests remain green (only additive `completion` command row)
- existing command flows (`run`, `status`, `resume`, `stop`, etc.) unchanged
- completion backend must not instantiate kernel or supervisor for top-level/flag completions

---

## 6. Acceptance Criteria

Feature is complete when all are true:

1. `aop completion bash|zsh|fish` emits shell-specific scripts that register completion for `aop`.
2. After sourcing the generated script, `aop <TAB>` shows command suggestions.
3. Help output documents `completion` command and keeps existing commands unchanged.
4. Hidden `__complete` command is not displayed in public help output.
5. Lint, typecheck, and full tests pass; coverage remains >=90% for all metrics.
6. README + AGENTS + CLAUDE are updated and aligned.

---

## 7. Risks and Mitigations

1. **Risk:** command metadata drift between help and completion.
   **Mitigation:** single shared catalog module used by both paths.

2. **Risk:** shell quoting differences break scripts.
   **Mitigation:** test emitted scripts for expected invocation signatures per shell.

3. **Risk:** completion backend errors degrade shell UX.
   **Mitigation:** fail-soft backend behavior for malformed completion input.

4. **Risk:** additional command causes parser regressions.
   **Mitigation:** explicit parser regression tests for unknown/default command paths.

---

## 8. Rollout Plan

1. Merge M48.1 + M48.2 first (catalog + command wiring).
2. Merge M48.3 with shell renderers and tests.
3. Merge M48.4 (dynamic value completion) only if risk remains low and tests are stable.
4. Merge M48.5 documentation updates.

Rollback strategy:

- disable completion exposure by removing `completion` dispatch and catalog entry while leaving core commands untouched.

---

## 9. Definition of Done

- all M48 milestones completed
- all acceptance criteria satisfied
- spec gap tracker items marked complete
- no regressions in existing CLI command behavior

---

## 10. Spec Gap Tracker

| ID    | Requirement                                                       | Status      | Notes |
| ----- | ----------------------------------------------------------------- | ----------- | ----- |
| M48.1 | Shared command catalog used by help and completion                | Not Started |       |
| M48.2 | `completion` + hidden `__complete` commands wired                 | Not Started |       |
| M48.3 | Bash/Zsh/Fish script generation implemented                       | Not Started |       |
| M48.4 | Optional dynamic `--project` and `--feature-id` value suggestions | Not Started |       |
| M48.5 | README + AGENTS + CLAUDE docs updated                             | Not Started |       |
