molecule-core/workspace-server/internal/channels
rabbitblood 00265d7028 feat(channels): first-class Lark/Feishu support via schema-driven config
Lark adapter was already implemented in Go (lark.go — outbound Custom Bot
webhook + inbound Event Subscriptions with constant-time token verify),
but the Canvas connect-form hardcoded a Telegram-shaped pair of inputs
(bot_token + chat_id). Selecting "Lark / Feishu" from the dropdown
silently sent the wrong field names — there was no way to enter a
webhook URL.

Fix: move form shape to the server.

- Add `ConfigField` struct + `ConfigSchema()` method to the
  `ChannelAdapter` interface. Each adapter declares its own fields with
  label/type/required/sensitive/placeholder/help.
- Implement per-adapter schemas:
  - Lark: webhook_url (required+sensitive) + verify_token (optional+sensitive)
  - Slack: bot_token/channel_id/webhook_url/username/icon_emoji
  - Discord: webhook_url + optional public_key
  - Telegram: bot_token + chat_id (unchanged UX, keeps Detect Chats)
- Change `ListAdapters()` to return `[]AdapterInfo` with config_schema
  inline. Sorted deterministically by display name so UI ordering is
  stable across Go's random map iteration.
- Update the 3 existing `ListAdapters` test sites to struct access.

Canvas (`ChannelsTab.tsx`):
- Replace the two hardcoded bot_token/chat_id inputs with a single
  schema-driven `SchemaField` component. Renders one input per field in
  the order the adapter returns them.
- Form state becomes `formValues: Record<string,string>` keyed by
  `ConfigField.key`. Values reset on platform-switch so stale
  Telegram credentials can't leak into a new Lark channel.
- "Detect Chats" stays but only renders for platforms in
  `SUPPORTS_DETECT_CHATS` (Telegram only — the only provider with
  getUpdates).
- Only schema-known keys are posted in `config`, scrubbing any stale
  values from previous platform selections.

Regression tests:
- `TestLark_ConfigSchema` locks in the 2-field Lark contract with the
  required/sensitive flags correctly set.
- `TestListAdapters_IncludesLark` confirms registry wiring + schema
  survives round-trip through ListAdapters.

Known pre-existing `TestStripPluginMarkers_AwkScript` failure in
internal/handlers is unrelated to this change (verified via stash+test
on clean staging).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:51:15 -07:00
..
adapter.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
channels_test.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
discord_test.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
discord.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
lark_test.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
lark.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
manager.go test(handlers): add CWE-22 regression suite + KI-005 terminal access fix + tests (#1574) 2026-04-22 15:30:11 +00:00
registry.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
secret_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
secret.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
slack_test.go chore: open-source restructure — rename dirs, remove internal files, scrub secrets 2026-04-18 00:24:44 -07:00
slack.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00
telegram.go feat(channels): first-class Lark/Feishu support via schema-driven config 2026-04-24 11:51:15 -07:00