feat(feishu): interactive card menus and session/workspace list cards

- /m (or /menu) opens a card menu; /sessionlist and /workspacelist render
  cards with bind/switch buttons; number replies stay usable as a fallback
  when the app does not subscribe card.action.trigger.
- card.action.trigger callbacks validate the operator's open_id against the
  allowed senders: group members outside the allowlist can never drive
  binding, workspace switches or other card actions.
- Session-list pagination uses page numbers everywhere (buttons carry
  sessions:<page>), fixing the previous double page-size scaling that
  skipped pages past 20 sessions.
- Bind/workspace failures map to safe user-facing messages instead of raw
  error details.
- Apps registered after this change subscribe card.action.trigger during
  the scan flow.
This commit is contained in:
liuwenbo00 2026-08-21 10:03:23 +08:00
parent 832bd539a2
commit 6366404c42
9 changed files with 642 additions and 137 deletions

View file

@ -85,7 +85,7 @@ async function selectedWorkspacePath(value) {
}
}
async function workspacePathSnapshot(harness) {
export async function workspacePathSnapshot(harness) {
const listed = await harness.listWorkspaces();
const currentValue = typeof harness?.currentWorkspace === 'function'
? harness.currentWorkspace()
@ -148,7 +148,7 @@ async function runWorkspaceListCommand(match, harness) {
}
}
async function resolveSessionListWorkspace(selector, harness) {
export async function resolveSessionListWorkspace(selector, harness) {
if (!selector) {
if (typeof harness?.currentWorkspace !== 'function') {
return { error: '当前机器人没有可用的工作区。' };