# Enhanced Existing Agent Wizard Flow

## Problem

When choosing "existing agent" in the wizard, the current flow:
1. Asks for nsec
2. Recovers kind 10002 relay list from Nostr
3. Immediately boots the agent

This is insufficient when installing an existing agent on a **new server** because:
- You cannot review or change the admin pubkey
- You cannot review or change the LLM provider/model/API key
- You cannot install a systemd service with a dedicated user
- You cannot see what config was recovered from Nostr
- The agent name is not recovered from the kind 0 profile

## Current Code

- [`existing_agent_flow()`](src/setup_wizard.c:1795) — 22 lines, minimal recovery
- [`recover_existing_config_from_nostr()`](src/setup_wizard.c:792) — only recovers kind 10002 relays
- Returns `SETUP_WIZARD_RC_EXISTING` (2) which does NOT set `bootstrap_mode`
- In `main.c`, existing agents skip `reconcile_startup_events()` unless `first_run` is detected

## Data Available on Nostr for an Existing Agent

| Data | Kind | Storage | Recovery Method |
|------|------|---------|-----------------|
| Relay list | 10002 | Public tags | `query_and_extract_kind10002_relays()` |
| Agent profile/name | 0 | Public JSON content | Query kind 0 by agent pubkey |
| LLM config | 30078 d=llm_config | NIP-44 encrypted to self | `fetch_self_config_plaintext()` |
| Agent config - admin pubkey, DM protocol | 30078 d=agent_config | NIP-44 encrypted to self | `fetch_self_config_plaintext()` |
| Default skill | 31124 d=didactyl-default | Public content | Query kind 31124 by agent pubkey |
| Adoption list | 10123 | Public tags | Query kind 10123 by agent pubkey |

## Proposed Enhanced Flow

```mermaid
flowchart TD
    A[Enter nsec] --> B[Connect to default relays]
    B --> C[Recover kind 10002 relay list]
    C --> D{Relay list found?}
    D -->|No| E{Offer to create new agent with this nsec}
    E -->|Yes| E2[Jump to new_agent_flow with nsec pre-loaded]
    E -->|No| E3[Return to main menu]
    D -->|Yes| F[Reconnect with recovered relays]
    F --> G[Recover all config from Nostr]
    G --> H[Display recovered config summary]
    H --> I{Review each setting}
    I -->|Keep all| J[Review summary + launch options]
    I -->|Change admin| K[Prompt new admin pubkey]
    I -->|Change LLM| L[Prompt LLM config]
    I -->|Change relays| M[Prompt relay config]
    K --> I
    L --> I
    M --> I
    J --> N{Launch option}
    N -->|Boot now| O[Return EXISTING]
    N -->|Install systemd| P[Install dedicated-user service]
    N -->|Quit| Q[Exit]
```

### Step-by-step

#### Step 1: Identity — Enter nsec
Same as current. Derive keys from nsec.

#### Step 2: Recovery — Connect and fetch config from Nostr
1. Init nostr handler with default relays
2. Wait for relay connections
3. Query kind 10002 for relay list — if not found, offer to create a new agent with this nsec (jump to `new_agent_flow` with keys pre-loaded, skipping identity step)
4. Cleanup and re-init with recovered relays
5. Wait for relay connections on recovered relays
6. Query kind 0 for agent profile — extract display_name/name
7. Query kind 30078 d=llm_config — decrypt and parse LLM settings
8. Query kind 30078 d=agent_config — decrypt and parse admin pubkey + DM protocol
9. Cleanup nostr handler

#### Step 3: Review — Present recovered config
Display all recovered values:
```
  ┌─────────────────────────────────────────────┐
  │  Existing Agent -- Recovered Configuration  │
  ├─────────────────────────────────────────────┤
  │  Agent name:    Simon                       │
  │  Identity:      b27072b7fc2edf45...         │
  │  Admin:         a1b2c3d4e5f6...             │
  │  LLM Provider:  ppq                         │
  │  LLM Model:     claude-haiku-4.5            │
  │  LLM Base URL:  https://api.ppq.ai          │
  │  LLM API Key:   sk-...****                  │
  │  DM Protocol:   nip04                       │
  │  Relays:        5 configured                │
  └─────────────────────────────────────────────┘
```

Then offer a menu:
```
  [a] change Admin pubkey
  [l] change LLM provider/model/key
  [r] change Relay configuration
  [c] continue with these settings
  [q] quit
```

Each change option reuses the existing prompt functions (`prompt_admin_pubkey`, `prompt_llm_config`, `prompt_relay_configuration`) but with context-appropriate headers.

After any change, redisplay the summary and menu.

#### Step 4: Launch — Boot or install systemd
Same as the new-agent flow's final step:
```
  [b] boot the agent now
  [i] install dedicated-user systemd service and boot
  [q] quit
```

The systemd install reuses `install_system_service_with_dedicated_user()`.

### Return Codes

- If user chooses "boot now": return `SETUP_WIZARD_RC_EXISTING` (2) — same as current
- If user chooses "install systemd": return `SETUP_WIZARD_RC_EXIT` (1) — agent runs as systemd service
- If user changed config values: the `main()` flow should still work because `recover_missing_runtime_config_from_nostr()` at line 1108 will fill in any gaps, and the existing agent path at line 1163 loads system context from adopted skills

### Key Consideration: bootstrap_mode for changed configs

If the user changes LLM or admin config in the wizard, those changes need to be persisted back to Nostr. Currently, `persist_runtime_config_to_nostr()` is only called when `bootstrap_mode || first_run`. 

**Solution**: When the existing-agent wizard detects that config was changed, return `SETUP_WIZARD_RC_BOOTSTRAP` (0) instead of `SETUP_WIZARD_RC_EXISTING` (2). This triggers the full reconcile path which persists the updated config.

## Files to Modify

1. **`src/setup_wizard.c`**:
   - Add `recover_full_config_from_nostr()` — fetches kind 0, kind 30078 llm_config, kind 30078 agent_config
   - Add `query_self_kind0_name()` — queries agent's own kind 0 profile for name
   - Add `fetch_and_decrypt_self_config()` — replicates `fetch_self_config_plaintext()` logic from main.c for use in wizard context
   - Rewrite `existing_agent_flow()` with the enhanced multi-step flow
   - Make `prompt_admin_pubkey()`, `prompt_llm_config()`, `prompt_relay_configuration()` accept a context string parameter for the page header, or add wrapper versions for the existing-agent context

2. **`src/main.c`**:
   - Potentially expose `fetch_self_config_plaintext()`, `apply_recalled_llm_config()`, `apply_recalled_agent_config()` as non-static, OR duplicate the logic in setup_wizard.c
   - Better approach: move these to a shared location or make them accessible via a header

## Implementation Notes

- The wizard already calls `nostr_handler_init()` / `nostr_handler_cleanup()` for validation queries. The enhanced flow will do the same but with two init/cleanup cycles: first with default relays to get kind 10002, then with recovered relays to get everything else.
- The `prompt_admin_pubkey()` and `prompt_llm_config()` functions currently have hardcoded step headers like "Step 3 of 7". These should be parameterized or have existing-agent variants.
- The `fetch_self_config_plaintext()` function in main.c requires an active nostr handler. The wizard will need to have the handler initialized when calling it.
- API key display should be masked — show only first 4 and last 4 characters.
