Files
nanoclaw/setup
gabi-simons e1c8876a72 feat(migrate-v1): auto-resolve missing v2 channel keys via adapter APIs
`migrate-channel-auth` now tries to derive v2-required keys that v1 never
stored by calling the channel's API with the credential v1 did have. When
the gap can be closed automatically, the keys land in v2 `.env` before
the missing-required check, and the step reports `success` instead of
`partial`. When it can't, the existing followup fires unchanged.

## Discord

v1 used raw `discord.js` (bot token only). v2's Chat SDK needs
`DISCORD_APPLICATION_ID` + `DISCORD_PUBLIC_KEY`. Both can be fetched with
the bot token via:

    GET /oauth2/applications/@me
    Authorization: Bot <DISCORD_BOT_TOKEN>
    → { id, verify_key, … }

For a stock v1 Discord user, this means `bash nanoclaw.sh` now produces
a fully working v2 Discord adapter with zero manual key-setting — just
stop v1, and v2 takes over.

## Surface

- `autoResolveV2Keys(channelType, lookup)` in `setup/migrate-v1/shared.ts`
  — pluggable per-channel resolver, returns a `{key: value}` map. Never
  throws; returns `{}` on any failure (network, auth, unexpected shape).
  Logs keys resolved, never values.
- `migrate-channel-auth` wiring: build a lookup over v1 + v2 .env, call
  the resolver, append resolved keys to v2 .env (never overwriting), sync
  to `data/env/env`, then re-check `requiredV2Keys` to compute the real
  gap. Sidecar annotation `(auto-resolved)` on `env_keys_copied` in the
  handoff so the skill can tell which came from v1 vs derived.

## Extending to other channels

Slack has `/auth.test` (bot token → team/app info), Telegram has `/getMe`,
Matrix has `/whoami`. Most don't cover the full required-key set v2 needs
(e.g. Slack's `SLACK_SIGNING_SECRET` lives only in app config and has no
API equivalent). Add resolvers case-by-case when the API supports it; the
registry's `requiredV2Keys` + followup fallback covers the rest.

## Testing

- Stripped `DISCORD_APPLICATION_ID` + `DISCORD_PUBLIC_KEY` from v2 `.env`
- Re-ran migration (wired-only, 301 groups): resolver populated both keys
  via the API; `migrate-channel-auth: success` (was `partial`);
  `overall_status: success`
- Restarted v2: Discord adapter booted clean, Gateway connected,
  `GUILD_CREATE` received
- v1 stopped, v2 handling Discord traffic
2026-04-23 13:06:14 +00:00
..