# `spt endpoint run` — interactive picker flow (M12 spec)

> Operator-specified 2026-06-14 (spt-claude-code scoping grill). The user-facing bringup
> flow for spt-hosted endpoints (create new / pick existing → start or attach). Visual
> inspiration: matt pocock's skill installer (https://github.com/mattpocock/skills) — inspect
> its source for look/feel (TUI investigation in flight). Likely Rust + ratatui.
>
> Relationship: `spt endpoint run` = the rich bringup picker. `spt rc` = connect to an
> spt-hosted PTY (cross-node attach, M12-slated). spt-claude-code's `cc`/`cc <id>` =
> thin wrapper over `spt endpoint run` defaulted to the `claude-spt` adapter.

## Layer 1 — kind
"What kind of endpoint?  [Create new | Pick existing]"

## Create-new branch
- **L2** "Choose your harness adapter for this endpoint:" → list available adapters, with
  their **profiles tree-nested** under each adapter.
- **L3** "Enter an endpoint id. Alphanumeric + hyphen + underscore only." → **start endpoint.**

## Non-interactive flags
`spt endpoint run` must support flags for fully non-interactive launch (skip the picker) so
users can bake shortcuts (e.g. a `cc-doyle` script). Flags supply adapter/profile + id +
create-vs-resume + attach/start/view so no prompt is shown. (Design the flag set to cover
every terminal action of the interactive flow.)

## Pick-existing branch
- **L2** "Available endpoints:"
  - **left/right** picks the **category**: one of `[<dir-name> project | Local node | Subnet]`.
  - **up/down** selects an endpoint within the category.
  - Grouping per category:
    - `project` endpoints → grouped by local / subnet N / subnet M / …
    - `local` endpoints → grouped by project names
    - `subnet` endpoints → grouped by `subnet:node`
  - Within a grouping, endpoints sorted **alphabetically**.
  - **Status square** behind each endpoint: online = green ■ · offline = gray hollow ▢ ·
    already-attached = blue ■.
  - **Right-half description pane** for the highlighted endpoint shows:
    1. harness `adapter:profile`
    2. project history list (newest → oldest)
    3. `spt endpoint description`
- **L3** "Confirm selection":
  ```
  <endpoint id>
  <status: online|offline|attached> • <subnet>:<node>   (or "LOCAL" if local)
  <harness adapter:profile>
  Project history: <comma-separated projects>
  <endpoint description>
  ```
  Options offered depend on status:
  - **[Attach now | Start now | View now]** per status → start endpoint
  - **Kick \<attached node name\> and attach** — EXCLUSIVE to *already-attached* endpoints
    (the session is live on another node/surface; kick that node off + attach here)
  - **Instantiate locally** (if remote) → L2@create-new → start endpoint
  - **Change harness adapter** (if offline) → L2@create-new → start endpoint
  - **Fork endpoint** → L2@create-new → L3@create-new → start endpoint
  - **Resume from history** — EXCLUSIVE to *offline* endpoints. Uses the per-endpoint
    session-id log + the adapter manifest `resume` declaration to pick from that agent's
    PRIOR sessions. Each option titled: `<project name> @ <last-log-message-timestamp>
    (...<session-id last 5 chars>)`.

  **`s` keybind (every pre-start options set):** "New `cc-<id>` shortcut" — or "Update
  `cc-<id>` shortcut" if a matching filename already exists — builds the `cc-<id>` launcher
  (e.g. `cc-doyle`) at project root with the current selection's flags BAKED IN (non-interactive).

## Implementation guidance (from TUI reference, investigated 2026-06-14)

Visual reference source = **`vercel-labs/skills`** (the `skills` npm CLI) — NOT
`mattpocock/skills` (content-only). Stack there: TS + `@clack/prompts` + `picocolors` +
a bespoke raw-ANSI `searchMultiselect` (`src/prompts/search-multiselect.ts`) with
type-to-filter, windowed cursor, a pinned **locked section**, live selected-summary.

**Rust port (recommended):** `ratatui` + `crossterm` (raw mode/keys) + `nucleo-matcher`
(fuzzy filter). ratatui's double-buffered renderer removes the manual erase/redraw +
wrapped-row-counting hazard entirely. State model to lift verbatim: `{ query, cursor,
selected:HashSet, locked:Vec }`. `List` + `ListState` = the windowed cursor/scroll.
**Copy the glyph set for the recognizable feel:** `◆ ◇ ■ ● ○ ✓ • │ ─ ❯` — green-filled `●`
/ dim-hollow `○` tri-state, cyan `❯` cursor, dim `│`/`─` gutter, inline dimmed hints.
- Their picker is **single-pane**; our **right-half description pane is our addition**
  (trivial in ratatui — a two-column layout). Map online/offline/attached squares to the
  tri-state color treatment (green ■ / gray ▢ / blue ■).
- `inquire` (Rust) is the off-the-shelf analog to clack but lacks the locked/pinned section
  + two-pane → bespoke ratatui component is the call.

## Open / suggestions (mostly resolved 2026-06-14)
- Keybinds: ←→ category · ↑↓ item · enter confirm · esc back · / filter · n new. **Phone
  caveat:** keybinds risk accidental input on a future smartphone PTY app → design the
  interaction model so a tap/non-keybind mode can layer on later (don't hard-couple to keys).
- Type-to-filter for large sets: YES (`/`). Keybind legend pinned at bottom: YES.
- "View now" = read-only attach (watch, no input); attached sessions need an explicit detach
  keybind. Empty category → "no endpoints — press n to create".
- `cc`/`cc <id>` wrapper: bare `cc` → picker scoped to claude-spt; `cc <id>` → if exists,
  attach/start directly (skip picker); else create-new with id pre-filled. Non-interactive
  flags enable `cc-<id>` shortcut scripts.
