export interface TeamRosterBot { larkAppId: string; name: string; cliId: string; capability: string | null; hasTeamRole: boolean; /** Owner for grouping by person; null if unassigned. unionId is the key, name for display. */ owner: { unionId?: string; openId?: string; name?: string; } | null; /** Feishu transport capability of THIS local bot. Only populated when the * caller passes `liveBots` (the live registry knows apiOnly); false = core-only * (no Feishu transport → cannot be a group member/creator, #668). undefined = * unknown (bots-info.json fallback path, or a legacy caller) → treat as normal. */ larkTransportEnabled?: boolean; } export interface TeamRoster { team: { id: string; name: string; memberCount: number; }; bots: TeamRosterBot[]; } /** * Compute the per-bot Feishu-transport flag for a set of live bots, given the * set of apiOnly (core-only) appIds read from config. * * ⚠️ FAIL-CLOSED on config-read failure. When `apiOnlyIds` is `null` (config * couldn't be read), we cannot confirm any bot HAS transport, so every bot this * round is flagged `larkTransportEnabled: false`. This roster is federated to a * REMOTE hub/spoke that has no local config to double-check against — so * mislabeling a core-only bot as normal (fail-open) would let it be invited into * a group it can't join (#668). Mirror federation-spoke-api's spoke-side advert, * NOT the dashboard's local isNoTransportBot (which fails open only because it * has a second local config-read backstop right beside it). * * Healthy path (`apiOnlyIds` is a Set): per-bot `!apiOnlyIds.has(id)`. */ export declare function resolveLiveBotTransport(bots: T[], apiOnlyIds: Set | null): Array; /** A currently-running bot from the live daemon registry (authoritative for * "what's running" — unlike bots-info.json which is a racy, probe-lagged file). */ export interface LiveBot { larkAppId: string; botName?: string | null; cliId?: string; larkTransportEnabled?: boolean; } /** * @param configOrder optional list of larkAppIds in bots.json (config) order; * when given, the roster is sorted to match it (and the personal dashboard). * @param liveBots optional live daemon-registry bots. When given, the roster's * bot set is THESE (authoritative — fixes an empty/stale bots-info.json * showing no bots even though daemons are running), enriched with cliId from * bots-info.json by larkAppId. When omitted, falls back to bots-info.json. */ export declare function buildTeamRoster(dataDir: string, teamId?: string, configOrder?: string[], liveBots?: LiveBot[]): TeamRoster; //# sourceMappingURL=team-roster.d.ts.map