# IUV-M03 Design: Provider-first intelligent flow + drill-down main menu **Issue:** #438 **Branch:** `feat/install-ux-intent` **Date:** 2026-04-05 ## 1. New first-run state machine The linear 12-stage interrogation is replaced with a menu-driven architecture. ### Flow overview ``` Welcome banner | v Detect existing install (auto) | v Main Menu (loop) |-- Quick Start -> provider key + admin creds -> finalize |-- Providers -> LLM API key config |-- Agent Identity -> intent intake + naming (deterministic) |-- Skills -> recommended / custom selection |-- Gateway -> port, storage tier, hostname, CORS |-- Advanced -> SOUL.md, USER.md, TOOLS.md, runtimes, hooks |-- Finish & Apply -> finalize + gateway bootstrap v Done ``` ### Menu navigation - Main menu is a `select` prompt. Each option drills into a sub-flow. - Completing a section returns to the main menu. - Menu items show completion state: `[done]` hint after configuration. - `Finish & Apply` is always last and requires at minimum a provider key (or explicit skip). - The menu tracks configured sections in `WizardState.completedSections`. ### Headless bypass When `MOSAIC_ASSUME_YES=1` or `!process.stdin.isTTY`, the entire menu is skipped. The wizard runs: defaults + env var overrides -> finalize -> gateway config -> bootstrap. This preserves full backward compatibility with `tools/install.sh --yes`. ## 2. Quick Start path Target: 3-5 questions max. Under 90 seconds for a returning user. ### Questions asked 1. **Provider API key** (Anthropic/OpenAI) - `text` prompt with paste support 2. **Admin email** - `text` prompt 3. **Admin password** - masked + confirmed ### Questions skipped (with defaults) | Setting | Default | Rationale | | ---------------------------- | ------------------------------- | ---------------------- | | Agent name | "Mosaic" | Generic but branded | | Port | 14242 | Standard default | | Storage tier | local | No external deps | | Hostname | localhost | Dev-first | | CORS origin | http://localhost:3000 | Standard web UI port | | Skills | recommended set | Curated by maintainers | | Runtimes | auto-detected | No user input needed | | Communication style | direct | Most popular choice | | SOUL.md / USER.md / TOOLS.md | template defaults | Can customize later | | Hooks | auto-install if Claude detected | Safe default | ### Flow ``` Quick Start selected -> "Paste your LLM API key (Anthropic recommended):" -> [auto-detect provider from key prefix: sk-ant-* = Anthropic, sk-* = OpenAI] -> Apply all defaults -> Run finalize (sync framework, write configs, link assets, sync skills) -> Run gateway config (headless-style with defaults + provided key) -> "Admin email:" -> "Admin password:" (masked + confirm) -> Run gateway bootstrap -> Done ``` ## 3. Provider-first flow Provider configuration (currently buried in gateway-config stage as "ANTHROPIC_API_KEY") moves to a dedicated top-level menu item and is the first question in Quick Start. ### Provider detection The API key prefix determines the provider: - `sk-ant-api03-*` -> Anthropic (Claude) - `sk-*` -> OpenAI - Empty/skipped -> no provider (gateway starts without LLM access) ### Storage The provider key is stored in the gateway `.env` as `ANTHROPIC_API_KEY` or `OPENAI_API_KEY`. For Quick Start, this replaces the old interactive prompt in `collectAndWriteConfig`. ### Menu section: "Providers" In the drill-down menu, "Providers" lets users: 1. Enter/change their API key 2. See which provider was detected 3. Optionally configure a second provider For v0.0.27, we support Anthropic and OpenAI keys only. The key is stored in `WizardState` and written during finalize. ## 4. Intent intake + naming (deterministic fallback - Option B) ### Rationale At install time, the LLM provider may not be configured yet (chicken-and-egg). We use **Option B: deterministic advisor** for the install wizard. ### Flow (Agent Identity menu section) ``` 1. "What will this agent primarily help you with?" -> Select from presets: - General purpose assistant - Software development - DevOps & infrastructure - Research & analysis - Content & writing - Custom (free text description) 2. System proposes a thematic name based on selection: - General purpose -> "Mosaic" - Software development -> "Forge" - DevOps & infrastructure -> "Sentinel" - Research & analysis -> "Atlas" - Content & writing -> "Muse" - Custom -> "Mosaic" (default) 3. "Your agent will be named 'Forge'. Press Enter to accept or type a new name:" -> User confirms or overrides ``` ### Storage - Agent name -> `WizardState.soul.agentName` -> written to SOUL.md - Intent category -> `WizardState.agentIntent` (new field) -> written to `~/.config/mosaic/agent.json` ### Post-install LLM-powered intake (future) A future `mosaic configure identity` command can use the configured LLM to: - Accept free-text intent description - Generate an expounded persona - Propose a contextual name This is explicitly out of scope for the install wizard. ## 5. Headless backward-compat ### Supported env vars (unchanged) | Variable | Used by | | -------------------------- | ---------------------------------------------- | | `MOSAIC_ASSUME_YES=1` | Skip all prompts, use defaults + env overrides | | `MOSAIC_ADMIN_NAME` | Gateway bootstrap | | `MOSAIC_ADMIN_EMAIL` | Gateway bootstrap | | `MOSAIC_ADMIN_PASSWORD` | Gateway bootstrap | | `MOSAIC_GATEWAY_PORT` | Gateway config | | `MOSAIC_HOSTNAME` | Gateway config (CORS derivation) | | `MOSAIC_CORS_ORIGIN` | Gateway config (full override) | | `MOSAIC_STORAGE_TIER` | Gateway config (local/team) | | `MOSAIC_DATABASE_URL` | Gateway config (team tier) | | `MOSAIC_VALKEY_URL` | Gateway config (team tier) | | `MOSAIC_ANTHROPIC_API_KEY` | Provider config | ### New env vars | Variable | Purpose | | --------------------- | ----------------------------------------- | | `MOSAIC_AGENT_NAME` | Override agent name in headless mode | | `MOSAIC_AGENT_INTENT` | Override intent category in headless mode | ### `tools/install.sh --yes` The install script sets `MOSAIC_ASSUME_YES=1` and passes through env vars. No changes needed to the script itself. The new wizard detects headless mode at the top of `runWizard` and runs a linear path identical to the old flow. ## 6. Explicit non-goals - **No GUI** — this is a terminal wizard only - **No multi-user install** — single-user, single-machine - **No registry changes** — npm publish flow is unchanged - **No LLM calls during install** — deterministic fallback only - **No new dependencies** — uses existing @clack/prompts and picocolors - **No changes to gateway API** — only the wizard orchestration changes - **No changes to tools/install.sh** — headless compat maintained via env vars ## 7. Implementation plan ### Files to modify 1. `packages/mosaic/src/types.ts` — add `MenuSection`, `AgentIntent`, `completedSections`, `agentIntent`, `providerKey`, `providerType` to WizardState 2. `packages/mosaic/src/wizard.ts` — replace linear flow with menu loop 3. `packages/mosaic/src/stages/mode-select.ts` — becomes the main menu 4. `packages/mosaic/src/stages/provider-setup.ts` — new: provider key collection 5. `packages/mosaic/src/stages/agent-intent.ts` — new: intent intake + naming 6. `packages/mosaic/src/stages/menu-gateway.ts` — new: gateway sub-menu wrapper 7. `packages/mosaic/src/stages/quick-start.ts` — new: quick start linear path 8. `packages/mosaic/src/constants.ts` — add intent presets and name mappings 9. `packages/mosaic/package.json` — version bump 0.0.26 -> 0.0.27 ### Files to add (tests) 1. `packages/mosaic/src/stages/wizard-menu.spec.ts` — menu navigation tests 2. `packages/mosaic/src/stages/quick-start.spec.ts` — quick start path tests 3. `packages/mosaic/src/stages/agent-intent.spec.ts` — intent + naming tests 4. `packages/mosaic/src/stages/provider-setup.spec.ts` — provider detection tests ### Migration strategy The existing stage functions remain intact. The menu system wraps them — each menu item calls the appropriate stage function(s). The linear headless path calls them in the same order as before.