# Ticket 3.3 — CLI Interface

**Phase**: 3 — Daemon & CLI
**Priority**: Critical (blocking)
**Depends on**: 3.1, 3.2

## Description

The command-line interface that users interact with. Running `npx conduit` in a project directory registers it with the daemon, displays a QR code for easy mobile connection, and shows status. Supports flags for daemon management, PIN configuration, and project operations.

## Acceptance Criteria

### AC1: Default invocation registers current directory

```gherkin
Given I am in directory /Users/me/my-app
When I run `npx conduit`
Then it connects to the daemon (starting one if needed)
And it registers /Users/me/my-app as a project
And it displays:
  - The HTTPS URL with project slug
  - A QR code pointing to the URL
  - The PIN (if set) or a prompt to set one
  - Connection instructions
```

### AC2: Status flag

```gherkin
When I run `npx conduit --status`
Then it shows:
  - Daemon uptime
  - Server URL and port
  - Number of connected clients
  - List of registered projects with their slugs
  - OpenCode server status for each project
```

### AC3: Stop flag

```gherkin
Given the daemon is running
When I run `npx conduit --stop`
Then it sends a shutdown command to the daemon
And it waits for confirmation
And it displays "Daemon stopped"
```

### AC4: PIN management

```gherkin
When I run `npx conduit --pin 1234`
Then it sets the PIN to "1234"
And it confirms "PIN updated"

When I run `npx conduit --pin` (without a value)
Then it prompts interactively for a PIN
```

### AC5: Project management flags

```gherkin
When I run `npx conduit --add /path/to/project`
Then it registers the specified directory as a project

When I run `npx conduit --remove`
Then it unregisters the current directory

When I run `npx conduit --list`
Then it lists all registered projects with slugs and directories

When I run `npx conduit --title "My Cool Project"`
Then it sets the display name for the current project
```

### AC6: Port configuration

```gherkin
When I run `npx conduit --port 8080`
Then the daemon starts on port 8080 instead of 2633

When I run `npx conduit --oc-port 4000`
Then it tells the OpenCode process manager to use port 4000
```

### AC7: QR code display

```gherkin
Given the server is running on https://192.168.1.50:2633
When the CLI displays connection info
Then it renders a terminal QR code encoding the URL
And the QR code is scannable from a phone camera
And the URL is also printed as text below the QR code
```

### AC8: Error messages are actionable

```gherkin
Given OpenCode is not installed
When I run `npx conduit`
Then it displays "OpenCode not found. Install it with: bun install -g opencode"
And it exits with code 1

Given the port is already in use
When I run `npx conduit`
Then it displays "Port 2633 is in use. Use --port to specify a different port."
```

## Testable Components

| Component | Test Type | What to Assert |
|-----------|-----------|----------------|
| `parseArgs(argv)` | Unit | Correct parsing of all flags and values |
| Default invocation | Unit | Connects to daemon, registers project |
| `--status` | Unit | Sends get_status, displays response |
| `--stop` | Unit | Sends shutdown, waits for confirmation |
| `--pin` | Unit | Sends set_pin, validates format |
| `--add/--remove/--list` | Unit | Correct IPC commands |
| `--port/--oc-port` | Unit | Passed through to daemon config |
| QR code generation | Unit | Generates valid QR code for URL |
| Error messages | Unit | Correct message for each error condition |
| Daemon auto-start | Fixture | No daemon → starts one → registers project |

## API Shape

```ts
// src/bin/cli.ts
// Entry point — parses args and communicates with daemon via IPC

// Supported flags:
// --status         Show daemon status
// --stop           Stop daemon
// --pin <PIN>      Set/update PIN
// --add <path>     Add project
// --remove         Remove current project
// --list           List projects
// --title <name>   Set project title
// --port <port>    HTTP server port (default: 2633)
// --oc-port <port> OpenCode server port (default: auto)
// --no-update      Skip version checking
// --debug          Enable debug panel in UI
```

## Reference

- Claude-relay CLI: `../claude-relay/bin/cli.js`
- QR code: `qrcode-terminal` package
- Daemon IPC: see ticket 3.2
