import type { CliId } from '../adapters/cli/types.js';
export declare const CLI_ID_CHOICES: Record<string, CliId>;
/**
 * 有序 CLI 选项 (id + 展示名), 顺序与 setup 交互菜单 (CLI_ID_CHOICES 序号
 * 1..16) 一致. dashboard "添加机器人" 的 CLI 下拉直接读这里, 避免再抄一份
 * 列表. 单一事实源: CLI_ID_CHOICES 的值序.
 */
export declare const CLI_OPTIONS: ReadonlyArray<{
    id: CliId;
    label: string;
}>;
/**
 * 把 setup 里"CLI 适配器"那一格的原始输入解析成合法的 CliId.
 *   - 空 → undefined (调用方决定 "preserve current" 还是套默认 'claude-code')
 *   - "1".."16" → CLI_ID_CHOICES 映射
 *   - 已是合法 cliId 字面值 → 原样返回
 *   - 其它 → throw (typo 不该静默落盘成 cliId)
 */
export declare function resolveCliId(input: string | undefined): CliId | undefined;
/**
 * 合法的 allowedUsers 条目：
 *   - on_xxx  union_id  — 跨应用稳定，推荐
 *   - 完整邮箱          — 人类可读，推荐
 *   - ou_xxx  open_id   — 仅对签发该 ID 的同一应用有效，不推荐跨 bot 复用
 * 裸邮箱前缀（如 "alice"）不合法：解析器只认 ou_/on_ 或完整邮箱。
 */
export declare function isValidAllowedUserEntry(entry: string): boolean;
/** 返回非法的 allowedUsers 条目（既不是 ou_ 也不是完整邮箱，典型是裸邮箱前缀）。 */
export declare function findInvalidAllowedUserEntries(entries: string[]): string[];
/**
 * 是否存在能解析成 owner 的 allowedUsers 条目（ou_ 或完整邮箱）。
 * owner = resolvedAllowedUsers 里第一个 ou_；完整邮箱会在启动时解析成 ou_，故二者都可作 owner。
 */
export declare function hasOwnerEntry(allowedUsers: string[] | undefined): boolean;
export interface BotConfigEditInput {
    name?: string;
    larkAppId?: string;
    larkAppSecret?: string;
    cliChoice?: string;
    cliPathOverride?: string;
    /**
     * 通用启动前缀（如 "aiden x claude"）。三态：
     *   - undefined → 不动
     *   - string    → 设置（空串 / "-" 视为清空）
     *   - null      → 清空（选了普通 CLI 时清掉旧的 aiden×* 前缀）
     * 调用方（setup picker / dashboard）用 resolveCliSelection 解析选择项后传入，
     * 避免 bot-config-editor 反向依赖 cli-selection（会成循环 import）。
     */
    wrapperCli?: string | null;
    /**
     * Model 字段三态语义（setup 不再交互式询问 model，此字段仅由切换 CLI 时的
     * 强制清空逻辑设 null；改 model 走 /config 卡片或手动编辑 bots.json）：
     *   - undefined → 这次编辑不动 model，保持原值
     *   - string    → 设为这个 model
     *   - null      → 清空（删字段，回到 CLI 默认）
     */
    model?: string | null;
    backendType?: string;
    workingDir?: string;
    allowedUsers?: string;
    allowedChatGroups?: string;
}
/**
 * 校验：配置了 allowedChatGroups 就必须有 owner。
 * 否则群成员只拿到 canTalk，没人在 allowedUsers 里 → canOperate 对所有人关闭（连 owner 都没有），
 * /restart、/close、获取写链接、/grant 等敏感操作全不可用。setup 写盘前调用，抛错由调用方捕获中止写盘。
 */
export declare function assertOwnerWhenChatGroups(config: {
    allowedUsers?: string[];
    allowedChatGroups?: string[];
}): void;
export interface RemoveBotConfigResult<T> {
    bots: T[];
    removed: T;
    index: number;
}
export declare function normalizeBotProcessName(input: string | undefined): string | undefined;
export declare function botProcessName(bot: {
    name?: unknown;
}, index: number, prefix?: string): string;
export declare function normalizeBotConfig<T extends Record<string, any>>(bot: T): T;
export declare function parseBotConfigsJson<T extends Record<string, any> = Record<string, any>>(content: string, filePath?: string): T[];
export declare function assertUniqueBotProcessNames(bots: Array<{
    name?: unknown;
}>, prefix?: string): void;
export declare function parseBotSelection(input: string, bots: Array<{
    larkAppId?: string;
    name?: unknown;
}>): number | undefined;
export declare function removeBotConfig<T extends {
    larkAppId?: string;
    name?: unknown;
}>(bots: T[], selection: string): RemoveBotConfigResult<T> | undefined;
export declare function applyBotConfigEdits<T extends Record<string, any>>(bot: T, input: BotConfigEditInput): T;
//# sourceMappingURL=bot-config-editor.d.ts.map