mioku 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["BOT_CWD: { value: string }","root: string","pkg: BotConfigJson","input: unknown","config: MiokuConfig","DEFAULT_CONFIG: RuntimeMiokuConfig","botConfig: RuntimeMiokuConfig","value: boolean","draft: (config: RuntimeMiokuConfig) => void | Promise<void>","id: string","url: string","timeout: number","message: string","status: number","response: Response","headers: Record<string, string>","body: HttpRequestOptions['body']","state: DriverState","options: HttpRequestOptions","ws: WebSocket","url: string","#ws","#dispatchMessage","#dispatchClose","#dispatchError","event: MessageEvent","#messageHandlers","event: CloseEvent","#closing","#closeHandlers","event: Event","#errorHandlers","data: string | Uint8Array","code?: number","reason?: string","handler: (data: string | Uint8Array) => void","handler: (event: { code: number; reason: string }) => void","handler: (err: Error) => void","options: WebSocketConnectOptions","timer: ReturnType<typeof setTimeout> | null","rejectConnect: ((err: Error) => void) | null","options: CreateDriverOptions","driver: Driver","closes: Promise<unknown>[]","value: PlatformId","type: string","data: Record<string, unknown>","attachment?: Attachment","segments: readonly MessageSegment[] | number","rawMessage?: string","segments: readonly MessageSegment[]","file: string | Buffer","options: { local?: boolean }","text: string","target: PlatformId","options: { local?: boolean } & Attachment","messageId: PlatformId","options?: { local?: boolean }","options: { local?: boolean; name?: string }","id: string | number","id: string","options: {\n user_id: PlatformId;\n nickname: string;\n content: MessageInput;\n }","data: Record<string, unknown> | string","content: string","options: ButtonOptions","value: unknown","message: Message","input: MessageInput","e: Event","adapter: string","routes: string[]","name: string","version: number","version","capability: string","bot: Bot","group_id: PlatformId","group_name?: string","bot: Bot","user_id: PlatformId","nickname?: string","bot: B","name: string","value: unknown","registry: CapabilityRegistry","target: CapabilityTarget","capability: Capability<I, O>","input: I","group_id: PlatformId","message: MessageInput","user_id: PlatformId","message_id: PlatformId","t: MessageTarget","nodes: readonly ForwardSendNode[]","options?: ForwardSendOptions","duration: number","reject_add_request?: boolean","card: string","enable: boolean","title: string","group_name: string","file: string","is_dismiss?: boolean","profile: ProfileSetRequest","before?: string","limit?: number","extra?: Record<string, unknown>","definition: AdapterDefinition<TConfig>","capability: Capability<I, O>","target: CapabilityTarget","handler: (input: I) => Promise<O>","#handlers","entry: CapabilityHandler<unknown, unknown>","input: I","plugin: T","key: string","#state","#bots","#bus","#driver","#capabilities","#logger","#emit","#pendingStarts","#crossDedup","options: {\n state: RuntimeAdapterState\n bots: BotRegistry\n bus: EventBus\n driver: Driver\n capabilities: CapabilityRegistry\n logger: Logger\n emit: (event: BotLifecycleEvent) => Promise<void>\n crossDedup?: CrossAdapterMessageDeduplicator | null\n }","bot: Bot","bot_id: string","capability: Capability<I, O>","target: CapabilityTarget","handler: (input: I) => Promise<O>","finalTarget: CapabilityTarget","gateway: AdapterGateway","err: unknown","resource: AdapterResource","event: Event","route: string","handler: (event: Event) => void | Promise<void>","event: BotLifecycleEvent","store","key: string","factory: () => T","connectedBots: Map<string, Bot>","adapter: string","bot_id: string","bot: Bot","#bots","#disposers","key: string","bot_id: string","adapter: string","bot_id: string | number","pattern: string","route: string","logger: ((level: 'error' | 'warn' | 'info', message: string, detail?: unknown) => void) | null","#logger","handler: EventHandler<E>","options: { source?: string; priority?: number }","#nextId","#nextOrder","reg: Registration","#registrations","#unregister","id: number","event: Event","matched: Registration[]","#matching","#dispatched","cmdStr: string","options: CreateCmdOptions","filename: string","options: { defaultData?: T; compress?: boolean }","data: T","defaultData: T","options: {\n __dirname?: string\n importMeta?: ImportMeta\n compress?: boolean\n filename?: string\n }","path","text: BinaryLike","encoding: BinaryToTextEncoding | 'buffer'","text","array: T[]","value: T | T[]","ms: number","ts: number | string | Date","options: { locale?: string; timeZone?: string }","options: { locale?: string; timeZone?: string; seconds?: boolean }","min: number","max: number","array: readonly T[]","count: number","selected: number[]","isString","v: unknown","n: number","val: T | null | undefined","val?: T","val: unknown","num: number","str: string | number | Buffer","str: string","type: 'buffer' | BufferEncoding","obj: Record<number | string, unknown>","error: unknown","pskey: string","event: T","pattern: Record<string, MatchHandler<T> | MatchValue>","quote: boolean","matches: RegExpMatchArray | null","source: HasMessage | Message","options: { trim?: boolean | 'whole' | 'each' }","type: string","LEVEL_MAP: Readonly<Record<number, { name: string; color: 'red' | 'yellow' | 'white' | 'green' | 'blue' | 'gray' }>>","cachedRoot: ConsolaInstance | null","cachedRootLevel: LogLevel","level: LogLevel","file: string","args: unknown[]","level: number","tag: string | undefined","#parent","#tag","#scope","#file","#threshold","options: {\n parent: ConsolaInstance | null\n tag: string | undefined\n scope: Record<string, unknown>\n file: string\n threshold: number\n }","#tagWithScope","#log","tag: string","scope: Record<string, unknown>","options: { tag?: string; level?: LogLevel; scope?: Record<string, unknown> }","rootLogger: Logger","bot: Bot","target: MessageTarget","message: MessageInput","bots: readonly Bot[]","targets: readonly MessageTarget[]","options: NoticeOptions","groupIds: readonly (string | number)[]","userIds: readonly (string | number)[]","owners: readonly string[]","admins: readonly string[]","name: string","value: T","cover: boolean","filePath: string","p: string","dir: string","results: DiscoveredModule[]","entries: import(\"fs\").Dirent[]","prefix: string","SERVICE_PREFIX","miokuConfig: MiokuRuntimeConfig","name: string","servicePath: string","packageJson: PackageJsonLike","ctx?: MiokuContext","metadata: ServiceMetadata","service: MiokuService","serviceName: string","configName: string","defaults: Record<string, unknown>","value: Record<string, unknown>","result: Record<string, Record<string, unknown>>","id: string","ctx: MiokuContext","ref: ServiceRef<T>","isObject","value: unknown","event: unknown","#options","#cleanup","options: ContextOptions","fn: PluginCleanup","bot_id: string | number","event: { quote_id?: string | null; bot?: Bot; self_id?: string }","name: string","route: R","handler: (event: RouteEvent<R>) => void | Promise<void>","event: Event","dispose","#addCleanup","expression: string","handler: CronHandler","taskContext: TaskContext","type: K","handler: (event: K extends 'connected' ? { bot: Bot } : BotLifecycleEvent) => void | Promise<void>","updater: (config: MiokuConfig) => void | Promise<void>","value: T","cover?: boolean","event: T","pattern: Parameters<typeof matchMessage>[1]","quote?: boolean","cmdStr: string","options: CreateCmdOptions","defaultData: T","options: { __dirname?: string; importMeta?: ImportMeta; compress?: boolean; filename?: string }","filename: string","options: { defaultData?: T; compress?: boolean }","source: HasMessage | Message","options?: { trim?: boolean | 'whole' | 'each' }","groupIds: readonly string[]","message: MessageInput","options?: import('../actions').NoticeOptions","userIds: readonly string[]","store","meta: PluginMetadata","name: string","name: string","initial: T","next: T","state: T","SystemMap: Record<string, string>","ArchMap: Record<string, string>","start","options: BuildStatusOptions","status: MiokuStatus","statsLine","adapter: string","bot_id?: string","target: StatusProviderTarget","provider: StatusProvider","bot: Bot","value: unknown","data: Record<string, unknown>","stats: AdapterStatusStats | undefined","status: AdapterStatus | null","options: BuildAdapterReportOptions","report: AdapterReport","STAT_GROUPS: ReadonlyArray<\n readonly [\n icon: string,\n fields: ReadonlyArray<readonly [keyof AdapterStatusStats, string]>,\n ]\n>","stats: AdapterStatusStats","segments: string[]","instance: AdapterInstanceStatus","entry: AdapterReportEntry","CORE_DEFAULT_CONFIG: CorePluginConfig","input: unknown","input: any","value: T","config: CorePluginConfig | any","merged: CorePluginConfig","ACCESS_DEFAULT_CONFIG: AccessControlConfig","config: Partial<AccessControlConfig> | any","filePath: string","data: unknown","text: string","hook: AccessHook","text","plugins: PluginMetadata[]","out: MessageCommandMatch[]","ctx: MiokuContext","getConfig: () => CorePluginConfig","text","userId: string | number | undefined","ctx: MiokuContext","getConfig: () => CorePluginConfig","LINES_PER_NODE","chunk","arr: T[]","size: number","result: T[][]","event: any","text: string","text","options: {\n ctx: MiokuContext;\n event: any;\n text: string;\n source: string;\n summary?: string;\n}","name: string","args: string[]","cwd?: string","chunk","readPackageJson","dir: string","pkgName: string","result: InstalledPackage[]","url: string","version","updates: UpdateAvailable[]","names: string[]","before: Map<string, string>","type: \"plugin\" | \"service\"","raw: unknown","meta: NpmPackageMeta | null","official: boolean","pluginName: string","serviceName: string","isInPm2: boolean","ensureDataDir","marker: RestartMarker","value: string","scriptPath","content","ms: number","ctx: MiokuContext | undefined","segment","event: any","typeLabel","type: string","items: UpdateAvailable[]","text: string","total: number","indices: number[]","num","ctx: MiokuContext","names: string[]","marker: RestartMarker","text","ev: any","text: string","head: string","type: \"plugin\" | \"service\"","ctx: MiokuContext","text","parsed","kind: \"plugin\" | \"service\"","items: Awaited<ReturnType<typeof getMarketItems>>","ctx: MiokuContext","text","kind: \"plugin\" | \"service\" | null","ctx: MiokuContext","text","marker: RestartMarker","latest: { path: string; mtime: number } | null","filePath: string","count: number","arr: T[]","size: number","result: T[][]","ctx: MiokuContext","text","lines: string[]","ctx: MiokuContext","getConfig: () => CorePluginConfig","autoUpdateTimer: ReturnType<typeof setInterval> | null","enabled: boolean","time: string","frequency: \"daily\" | \"weekly\" | \"monthly\"","marker: RestartMarker","value: string","CORE_HELP_ENTRIES: ReadonlyArray<readonly [cmd: string, desc: string]>","width: number","displayPrefix: string","ctx: MiokuContext","likeKeyword: string","cmd: string","desc: string","help: PluginHelp","accessHooks: AccessHook[]","core: MiokuPlugin","disposers: Array<() => void>","baseConfig: CorePluginConfig","accessRules: AccessControlConfig","text: string","text","name: string","adapter?: Adapter","event: MessageEvent","str: string","BUILTIN_PLUGINS: readonly MiokuPlugin[]","core","prefix: string","obj: Record<string, unknown>","allowed: Set<string>","value: unknown","pluginName: string","commands: PluginHelp[\"commands\"]","hooks: AccessHook[]","raw: unknown","config: PluginPackageConfig","services","name: string","resolvedPath: string","packageJson: PackageJsonLike","dir: string","cwd: string","name: string","pkg: PackageJson","override?: string","candidates: string[]","appPackageJson: PackageJson","candidates: AdapterCandidate[]","candidates: PluginCandidate[]","pluginsDir: string","value: unknown","cwd: string","aliases: Record<string, string>","jiti: Jiti","candidate: AdapterCandidate","value: unknown","jiti: Jiti","entry: string","name: string","candidate: PluginCandidate","resolvedPath: string","event: MessageEvent","parts: string[]","text","content: string","#entries","#dropped","event: Event","#inserts","#prune","now: number","BUILTIN_PLUGINS: MiokuPlugin[]","DEFAULT_BUILTIN_PLUGINS","plugins: readonly MiokuPlugin[]","BUILTIN_PLUGINS","#cwd","#logger","#bus","#bots","#capabilities","#driver","#adapterStates","#enabledAdapters","#enabledPlugins","#driverFactory","#builtinPlugins","#crossDedup","options: CreateRuntimeOptions","name: string","bot_id: string | number","#readAppPackageJson","#loadPlugin","#emitLifecycle","event: BotLifecycleEvent","lifecycleEvent: Event","state: RuntimeAdapterState","plugin: MiokuPlugin","type: \"builtin\" | \"external\"","cleanupTasks: PluginCleanup[]","cleanup: PluginCleanup | null","wrappedCleanup: PluginCleanup","#setupBuiltinPlugins","#discoverAdapters","#setupPlugins","#logPluginSummary","failed: Array<{ name: string; error: string }>","tasks: Array<{\n name: string;\n priority: number;\n run: () => Promise<void>;\n }>","startTime: bigint","#startAdapter","config: unknown","#createContext","instance: Adapter","#started","failed: string[]","reason?: string","#stopped","ctx?: MiokuContext","options: StartOptions","reason?: string","role: unknown","AI_THINKING_LEVELS: AIThinkingLevel[]","AI_GEMINI_THINKING_LEVELS: AIThinkingLevel[]","value: unknown","protocol?: AIProtocol","options: MiokuStartOptions","miokuConfig: import(\"./types\").MiokuRuntimeConfig","signal: string","version: string"],"sources":["../src/config.ts","../src/driver/types.ts","../src/driver/default.ts","../src/adapter/message.ts","../src/adapter/event.ts","../src/adapter/capability.ts","../src/capabilities/message.ts","../src/capabilities/member.ts","../src/capabilities/group.ts","../src/capabilities/friend.ts","../src/capabilities/conversation.ts","../src/capabilities/profile.ts","../src/capabilities/system.ts","../src/adapter/bot.ts","../src/adapter/types.ts","../src/adapter/registry.ts","../src/plugin/plugin.ts","../src/runtime/context.ts","../src/internal/registry.ts","../src/compat/connected-bots.ts","../src/runtime/bots.ts","../src/runtime/bus.ts","../src/utils.ts","../src/logger/index.ts","../src/actions.ts","../src/services/registry.ts","../src/internal/module-scanner.ts","../src/services/manager.ts","../src/services/config.ts","../src/services/define.ts","../src/services/builtin.ts","../src/runtime/mioku-context.ts","../src/runtime/plugin-metadata.ts","../src/runtime/plugin-state.ts","../src/builtin/core/status.ts","../src/builtin/core/adapters.ts","../src/builtin/core/config.ts","../src/builtin/core/access/access-config.ts","../src/builtin/core/access/access-store.ts","../src/builtin/core/access/matcher.ts","../src/builtin/core/commands/like.ts","../src/builtin/core/access/privileged.ts","../src/builtin/core/commands/min-member.ts","../src/builtin/core/commands/notify.ts","../src/builtin/core/commands/prefix.ts","../src/builtin/core/system/package-manager.ts","../src/internal/data-paths.ts","../src/builtin/core/system/restart.ts","../src/builtin/core/commands/update.ts","../src/builtin/core/commands/install.ts","../src/builtin/core/commands/market.ts","../src/builtin/core/commands/restart.ts","../src/builtin/core/commands/log.ts","../src/builtin/core/commands/auto-approve.ts","../src/builtin/core/system/auto-update.ts","../src/builtin/core/index.ts","../src/builtin/index.ts","../src/loader/manifest.ts","../src/loader/package.ts","../src/loader/adapter.ts","../src/loader/plugin.ts","../src/runtime/cross-adapter-dedup.ts","../src/runtime/runtime.ts","../src/runtime/plugin-artifacts.ts","../src/start.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { LogLevel } from \"./logger\";\n\n/** package.json 中 mioku 字段的结构 */\nexport interface MiokuConfig {\n /** 指令前缀,缺省为 \".\" */\n prefix?: string;\n owners: string[];\n admins: string[];\n plugins: string[];\n plugins_dir?: string;\n log_level?: LogLevel;\n /** 启动完成后是否私聊通知第一位 owner */\n online_push?: boolean;\n /** 出错时是否推送给 owner */\n error_push?: boolean;\n /** 谁可以查询运行状态:所有人或仅管理员 */\n status_permission?: \"all\" | \"admin-only\";\n /** 去重选项 */\n dedup?: {\n /** 跨适配器指纹去重 */\n cross_adapter?: boolean;\n };\n adapters?: Record<string, unknown>;\n napcat?: unknown;\n}\n\n/** package.json 的宽松形状,只约定 mioku 字段 */\nexport interface BotConfigJson {\n mioku?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/** 当前机器人根目录,包一层对象以便整体重定向 */\nexport const BOT_CWD: { value: string } = { value: process.cwd() };\n\n/** 重设机器人根目录,之后 package.json 的读写都基于它 */\nexport const setBotCwd = (root: string): void => {\n BOT_CWD.value = path.resolve(root);\n};\n\n/** 读取机器人根目录的 package.json */\nexport const readPackageJson = (): BotConfigJson => {\n const file = path.join(BOT_CWD.value, \"package.json\");\n if (!fs.existsSync(file)) {\n throw new Error(\n `无法在 ${BOT_CWD.value} 下找到 package.json 文件,请确认当前目录是否为机器人根目录`,\n );\n }\n const raw = fs.readFileSync(file, \"utf-8\");\n try {\n return JSON.parse(raw) as BotConfigJson;\n } catch {\n throw new Error(`package.json 解析失败,请检查 JSON 格式`);\n }\n};\n\n/** 写回机器人根目录的 package.json */\nexport const writePackageJson = (pkg: BotConfigJson): void => {\n const file = path.join(BOT_CWD.value, \"package.json\");\n fs.writeFileSync(file, JSON.stringify(pkg, null, 2), \"utf-8\");\n};\n\n/** 把 owners 配置规整为字符串数组,非数组时返回空 */\nexport const normalizeOwners = (input: unknown): string[] => {\n if (!Array.isArray(input)) return [];\n return input.map((v) => String(v) as string);\n};\n\n/** 同 normalizeOwners,规整管理员名单 */\nexport const normalizeAdmins = (input: unknown): string[] => {\n if (!Array.isArray(input)) return [];\n return input.map((v) => String(v) as string);\n};\n\n/** 同 normalizeOwners,规整插件列表 */\nexport const normalizePlugins = (input: unknown): string[] => {\n if (!Array.isArray(input)) return [];\n return input.map((v) => String(v) as string);\n};\n\n/** 从 package.json 读取 mioku 配置并补全默认值 */\nexport const readMiokuConfig = (): MiokuConfig => {\n const raw = readPackageJson();\n const rawMioku = raw.mioku;\n if (!rawMioku || typeof rawMioku !== \"object\") {\n throw new Error(\n `无法在 package.json 中找到 mioku 配置,请确认 package.json 文件中是否包含 mioku 字段`,\n );\n }\n const config: MiokuConfig = {\n ...(rawMioku as Partial<MiokuConfig>),\n owners: normalizeOwners((rawMioku as { owners?: unknown }).owners),\n admins: normalizeAdmins((rawMioku as { admins?: unknown }).admins),\n plugins: normalizePlugins((rawMioku as { plugins?: unknown }).plugins),\n prefix:\n typeof (rawMioku as { prefix?: unknown }).prefix === \"string\"\n ? (rawMioku as { prefix: string }).prefix\n : \".\",\n plugins_dir:\n typeof (rawMioku as { plugins_dir?: unknown }).plugins_dir === \"string\"\n ? (rawMioku as { plugins_dir: string }).plugins_dir\n : \"plugins\",\n };\n if ((rawMioku as { log_level?: unknown }).log_level) {\n config.log_level = (rawMioku as { log_level: LogLevel }).log_level;\n }\n if ((rawMioku as { status_permission?: unknown }).status_permission) {\n config.status_permission = (\n rawMioku as { status_permission: \"all\" | \"admin-only\" }\n ).status_permission;\n }\n config.online_push = Boolean(\n (rawMioku as { online_push?: unknown }).online_push,\n );\n config.error_push = Boolean(\n (rawMioku as { error_push?: unknown }).error_push,\n );\n if ((rawMioku as { adapters?: unknown }).adapters) {\n config.adapters = (\n rawMioku as { adapters: Record<string, unknown> }\n ).adapters;\n }\n return config;\n};\n\n/** 运行时使用的配置,字段与 MiokuConfig 相同 */\nexport interface RuntimeMiokuConfig extends MiokuConfig {}\n\nconst DEFAULT_CONFIG: RuntimeMiokuConfig = {\n owners: [],\n admins: [],\n plugins: [],\n plugins_dir: \"plugins\",\n prefix: \".\",\n};\n\nconst loadInitialConfig = (): RuntimeMiokuConfig => {\n try {\n return readMiokuConfig();\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n};\n\n/** 全局运行时配置,模块加载时初始化 */\nexport let botConfig: RuntimeMiokuConfig = loadInitialConfig();\n\n/** 重新读取 package.json 并替换全局配置 */\nexport const reloadMiokuConfig = (): RuntimeMiokuConfig => {\n botConfig = readMiokuConfig();\n return botConfig;\n};\n\nlet writable = false;\n\n/** 控制是否允许把配置改动写回 package.json */\nexport const setWritableConfig = (value: boolean): void => {\n writable = value;\n};\n\n/** 在 draft 里直接修改配置;writable 开启时改动会落盘到 package.json */\nexport const updateMiokuConfig = (\n draft: (config: RuntimeMiokuConfig) => void | Promise<void>,\n): Promise<void> => {\n return Promise.resolve(draft(botConfig)).then(() => {\n if (!writable) return;\n const pkg = readPackageJson();\n pkg.mioku = {\n ...(pkg.mioku as Record<string, unknown> | undefined),\n ...botConfig,\n };\n writePackageJson(pkg);\n });\n};\n\n/** 判断是否为 owner */\nexport const isOwner = (id: string): boolean => {\n const target = typeof id === \"string\" ? id : id;\n return botConfig.owners.includes(target as string);\n};\n\n/** 判断是否为管理员 */\nexport const isAdmin = (id: string): boolean => {\n const target = typeof id === \"string\" ? id : id;\n return botConfig.admins.includes(target as string);\n};\n\n/** 判断是否为 owner 或管理员 */\nexport const isOwnerOrAdmin = (id: string): boolean => {\n return isOwner(id) || isAdmin(id);\n};\n\n/** isOwnerOrAdmin 的别名 */\nexport const hasRight = (id: string): boolean => isOwnerOrAdmin(id);\n","/** 一条已建立的 WebSocket 连接 */\nexport interface WebSocketConnection {\n readonly id: string\n readonly url: string\n readonly readyState: 'connecting' | 'open' | 'closing' | 'closed'\n\n send(data: string | Uint8Array): Promise<void>\n close(code?: number, reason?: string): Promise<void>\n\n /** 监听消息,返回取消监听的函数 */\n onMessage(handler: (data: string | Uint8Array) => void): () => void\n /** 监听连接关闭,返回取消监听的函数 */\n onClose(handler: (event: { code: number; reason: string }) => void): () => void\n /** 监听连接错误,返回取消监听的函数 */\n onError(handler: (err: Error) => void): () => void\n}\n\n/** 建立 WebSocket 连接的选项 */\nexport interface WebSocketConnectOptions {\n readonly headers?: Readonly<Record<string, string>>\n readonly protocols?: readonly string[]\n readonly signal?: AbortSignal\n /** 连接超时时间(毫秒) */\n readonly connectTimeout?: number\n}\n\n/** WebSocket 客户端 */\nexport interface WebSocketClient {\n connect(url: string, options?: WebSocketConnectOptions): Promise<WebSocketConnection>\n}\n\n/** HTTP 请求参数 */\nexport interface HttpRequestOptions {\n readonly method: string\n readonly url: string\n readonly headers?: Readonly<Record<string, string>>\n /** 请求体:字符串、二进制或对象(对象按 JSON 发送) */\n readonly body?: string | Uint8Array | Readonly<Record<string, unknown>>\n /** 超时时间(毫秒) */\n readonly timeout?: number\n readonly signal?: AbortSignal\n}\n\n/** HTTP 响应 */\nexport interface HttpResponse {\n readonly status: number\n readonly headers: Readonly<Record<string, string>>\n readonly body: Uint8Array\n text(): string\n json<T = unknown>(): T\n arrayBuffer(): ArrayBuffer\n}\n\n/** HTTP 客户端 */\nexport interface HttpClient {\n request(options: HttpRequestOptions): Promise<HttpResponse>\n}\n\n/** 驱动:为适配器提供统一的 HTTP 与 WebSocket 能力 */\nexport interface Driver {\n readonly name: string\n readonly http: HttpClient\n readonly websocket: WebSocketClient\n /** 关闭驱动:中止进行中的请求并断开所有连接 */\n shutdown(): Promise<void>\n}\n\n/** 驱动已关闭后发起请求时抛出的错误 */\nexport class DriverShutdownError extends Error {\n constructor(message = 'Driver has been shut down') {\n super(message)\n this.name = 'DriverShutdownError'\n }\n}\n\n/** WebSocket 连接超时时抛出的错误 */\nexport class WebSocketConnectTimeoutError extends Error {\n constructor(url: string, timeout: number) {\n super(`WebSocket connect timed out after ${timeout}ms: ${url}`)\n this.name = 'WebSocketConnectTimeoutError'\n }\n}\n\n/** HTTP 请求失败时抛出的错误 */\nexport class HttpRequestError extends Error {\n /** HTTP 状态码,网络错误或超时时为 0 */\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'HttpRequestError'\n this.status = status\n }\n}","import { randomUUID } from 'node:crypto'\n\nimport type {\n Driver,\n HttpClient,\n HttpRequestOptions,\n HttpResponse,\n WebSocketClient,\n WebSocketConnection,\n WebSocketConnectOptions,\n} from './types'\nimport { DriverShutdownError, HttpRequestError, WebSocketConnectTimeoutError } from './types'\n\nconst RAW_TEXT_DECODER = new TextDecoder()\n\nconst decodeBody = async (response: Response): Promise<{ body: Uint8Array; headers: Record<string, string> }> => {\n const arrayBuffer = await response.arrayBuffer()\n const headers: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value\n })\n return { body: new Uint8Array(arrayBuffer), headers }\n}\n\nconst buildResponse = async (response: Response): Promise<HttpResponse> => {\n const { body, headers } = await decodeBody(response)\n return {\n status: response.status,\n headers,\n body,\n text() {\n return RAW_TEXT_DECODER.decode(body)\n },\n json<T = unknown>(): T {\n return JSON.parse(RAW_TEXT_DECODER.decode(body)) as T\n },\n arrayBuffer(): ArrayBuffer {\n return body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength) as ArrayBuffer\n },\n }\n}\n\nconst serializeBody = (\n body: HttpRequestOptions['body'],\n): { body: string | Buffer | undefined; contentType: string | undefined } => {\n if (body == null) return { body: undefined, contentType: undefined }\n if (typeof body === 'string') return { body, contentType: 'text/plain;charset=utf-8' }\n if (body instanceof Uint8Array) return { body: Buffer.from(body), contentType: 'application/octet-stream' }\n return { body: JSON.stringify(body), contentType: 'application/json' }\n}\n\nconst createHttpClient = (state: DriverState): HttpClient => {\n return {\n async request(options: HttpRequestOptions): Promise<HttpResponse> {\n if (state.shutdownStarted) throw new DriverShutdownError()\n const { body, contentType } = serializeBody(options.body)\n const headers = new Headers()\n for (const [k, v] of Object.entries(options.headers ?? {})) {\n headers.set(k, v)\n }\n if (contentType && !headers.has('content-type')) {\n headers.set('content-type', contentType)\n }\n const signal = options.signal ?? state.rootController.signal\n const timeout = options.timeout ?? state.requestTimeout\n const controller = new AbortController()\n const timer =\n timeout > 0\n ? setTimeout(() => {\n controller.abort(new Error(`HttpRequest timeout after ${timeout}ms`))\n }, timeout)\n : null\n const compositeSignal = AbortSignal.any([signal, controller.signal])\n try {\n const response = await fetch(options.url, {\n method: options.method,\n headers,\n body: body as BodyInit | undefined,\n signal: compositeSignal,\n })\n return await buildResponse(response)\n } catch (err) {\n if (controller.signal.aborted) {\n throw new HttpRequestError(`Request aborted or timed out: ${options.url}`, 0)\n }\n throw new HttpRequestError(err instanceof Error ? err.message : String(err), 0)\n } finally {\n if (timer) clearTimeout(timer)\n }\n },\n }\n}\n\nclass NodeWebSocketConnection implements WebSocketConnection {\n readonly id: string\n readonly url: string\n #ws: WebSocket\n #messageHandlers = new Set<(data: string | Uint8Array) => void>()\n #closeHandlers = new Set<(event: { code: number; reason: string }) => void>()\n #errorHandlers = new Set<(err: Error) => void>()\n #closing: 'idle' | 'closing' | 'closed' = 'idle'\n\n constructor(ws: WebSocket, url: string) {\n this.#ws = ws\n this.url = url\n this.id = randomUUID()\n ws.binaryType = 'arraybuffer'\n ws.addEventListener('message', this.#dispatchMessage)\n ws.addEventListener('close', this.#dispatchClose)\n ws.addEventListener('error', this.#dispatchError)\n }\n\n get readyState(): 'connecting' | 'open' | 'closing' | 'closed' {\n switch (this.#ws.readyState) {\n case WebSocket.CONNECTING:\n return 'connecting'\n case WebSocket.OPEN:\n return 'open'\n case WebSocket.CLOSING:\n return 'closing'\n case WebSocket.CLOSED:\n return 'closed'\n default:\n return 'closed'\n }\n }\n\n #dispatchMessage = (event: MessageEvent): void => {\n if (this.#messageHandlers.size === 0) return\n const data = typeof event.data === 'string' ? event.data : new Uint8Array(event.data as ArrayBuffer)\n for (const handler of this.#messageHandlers) {\n try {\n handler(data)\n } catch {\n // swallow handler errors; transport-level concerns only.\n }\n }\n }\n\n #dispatchClose = (event: CloseEvent): void => {\n this.#closing = 'closed'\n const payload = { code: event.code, reason: event.reason }\n for (const handler of this.#closeHandlers) {\n try {\n handler(payload)\n } catch {\n // ignore\n }\n }\n }\n\n #dispatchError = (event: Event): void => {\n const err = event instanceof ErrorEvent ? new Error(event.message) : new Error('WebSocket error')\n for (const handler of this.#errorHandlers) {\n try {\n handler(err)\n } catch {\n // ignore\n }\n }\n }\n\n async send(data: string | Uint8Array): Promise<void> {\n if (this.#ws.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket is not open')\n }\n if (typeof data === 'string') {\n this.#ws.send(data)\n return\n }\n this.#ws.send(Buffer.from(data))\n }\n\n async close(code?: number, reason?: string): Promise<void> {\n if (this.#closing !== 'idle') return\n this.#closing = 'closing'\n if (this.#ws.readyState === WebSocket.OPEN || this.#ws.readyState === WebSocket.CONNECTING) {\n this.#ws.close(code ?? 1000, reason ?? '')\n }\n }\n\n onMessage(handler: (data: string | Uint8Array) => void): () => void {\n this.#messageHandlers.add(handler)\n return () => this.#messageHandlers.delete(handler)\n }\n\n onClose(handler: (event: { code: number; reason: string }) => void): () => void {\n this.#closeHandlers.add(handler)\n return () => this.#closeHandlers.delete(handler)\n }\n\n onError(handler: (err: Error) => void): () => void {\n this.#errorHandlers.add(handler)\n return () => this.#errorHandlers.delete(handler)\n }\n}\n\nconst createWebSocketClient = (state: DriverState): WebSocketClient => {\n return {\n async connect(url: string, options: WebSocketConnectOptions = {}): Promise<WebSocketConnection> {\n if (state.shutdownStarted) throw new DriverShutdownError()\n const headers = options.headers ?? {}\n const protocols = options.protocols ? Array.from(options.protocols) : undefined\n const socket = new WebSocket(url, protocols)\n const signal = options.signal\n let externalAbort = false\n const abortFromExternal = (): void => {\n externalAbort = true\n socket.close(1000, 'aborted')\n }\n if (signal) {\n if (signal.aborted) abortFromExternal()\n else signal.addEventListener('abort', abortFromExternal, { once: true })\n }\n const timeout = options.connectTimeout ?? state.connectTimeout\n let timer: ReturnType<typeof setTimeout> | null = null\n let rejectConnect: ((err: Error) => void) | null = null\n if (timeout > 0) {\n timer = setTimeout(() => {\n externalAbort = true\n try {\n socket.close(1001, 'connect timeout')\n } catch {\n // ignore\n }\n rejectConnect?.(new WebSocketConnectTimeoutError(url, timeout))\n }, timeout)\n }\n try {\n await new Promise<void>((resolve, reject) => {\n rejectConnect = reject\n socket.addEventListener('open', () => resolve(), { once: true })\n socket.addEventListener(\n 'error',\n (event) => {\n if (externalAbort) return\n const err = event instanceof ErrorEvent ? new Error(event.message) : new Error('WebSocket connect failed')\n reject(err)\n },\n { once: true },\n )\n })\n } catch (err) {\n try {\n socket.close()\n } catch {\n // ignore\n }\n throw err instanceof Error ? err : new Error('WebSocket connect failed')\n } finally {\n if (timer) clearTimeout(timer)\n rejectConnect = null\n }\n const conn = new NodeWebSocketConnection(socket, url)\n state.connections.add(conn)\n const remove = (): void => {\n state.connections.delete(conn)\n }\n conn.onClose(remove)\n return conn\n },\n }\n}\n\ninterface DriverState {\n shutdownStarted: boolean\n connections: Set<WebSocketConnection>\n rootController: AbortController\n requestTimeout: number\n connectTimeout: number\n}\n\n/** 创建默认驱动的选项 */\nexport interface CreateDriverOptions {\n /** HTTP 请求的默认超时(毫秒) */\n readonly requestTimeout?: number\n /** WebSocket 连接的默认超时(毫秒) */\n readonly connectTimeout?: number\n}\n\n/** 创建内置默认驱动:基于全局 fetch 与 WebSocket 实现 */\nexport const createDefaultDriver = (options: CreateDriverOptions = {}): Driver => {\n const state: DriverState = {\n shutdownStarted: false,\n connections: new Set(),\n rootController: new AbortController(),\n requestTimeout: options.requestTimeout ?? 30_000,\n connectTimeout: options.connectTimeout ?? 15_000,\n }\n const http = createHttpClient(state)\n const websocket = createWebSocketClient(state)\n\n const driver: Driver = {\n name: 'mioku.default',\n http,\n websocket,\n async shutdown(): Promise<void> {\n if (state.shutdownStarted) return\n state.shutdownStarted = true\n state.rootController.abort()\n const closes: Promise<unknown>[] = []\n for (const conn of state.connections) {\n closes.push(conn.close(1000, 'driver shutdown'))\n }\n await Promise.allSettled(closes)\n },\n }\n return driver\n}\n","/** 消息段的附件:图片/文件/音视频的资源引用 */\nexport interface Attachment {\n readonly id?: string;\n readonly url?: string;\n readonly file?: string;\n readonly data?: Uint8Array;\n readonly mime?: string;\n readonly size?: number;\n readonly name?: string;\n}\n\n/** 消息段:一段消息的最小单元,如文本、@、图片 */\nexport interface MessageSegment {\n readonly type: string;\n readonly data: Readonly<Record<string, unknown>>;\n readonly attachment?: Attachment;\n isText(): boolean;\n toString(): string;\n}\n\nexport interface SerializedMessageSegment {\n readonly type: string;\n readonly data: Readonly<Record<string, unknown>>;\n readonly attachment?: Attachment;\n}\n\n/** 消息:消息段的只读数组,带文本提取与按类型过滤的便捷方法 */\nexport interface Message extends ReadonlyArray<MessageSegment> {\n readonly raw_message?: string;\n toString(): string;\n text(): string;\n filterByType<T extends MessageSegment = MessageSegment>(type: string): T[];\n toJSON(): SerializedMessageSegment[];\n}\n\n/** 发送消息的入参:字符串、单段或段的数组都可以 */\nexport type MessageInput =\n | string\n | Message\n | MessageSegment\n | readonly (string | MessageSegment)[];\n\nexport type PlatformId = string | number;\n\nexport const toId = (value: PlatformId): string => String(value);\n\n/** 消息发送目标:群或私聊等会话的定位信息 */\nexport interface MessageTarget {\n readonly type: string;\n readonly id?: PlatformId;\n readonly parent_id?: PlatformId;\n readonly user_id?: PlatformId;\n readonly group_id?: PlatformId;\n}\n\nexport interface SentMessage {\n readonly message_id?: string;\n readonly sent_at?: number;\n}\n\nexport interface ReplyOptions {\n readonly quote?: boolean;\n}\n\nexport type ReplyArg = boolean | ReplyOptions;\n\n/** 交互按钮*/\nexport interface ButtonOptions {\n id?: string;\n label: string;\n /** 点击后按钮文字 */\n visitedLabel?: string;\n /** 0 灰色线框 1 蓝色线框 2 白字 3 蓝底白字 */\n style?: 0 | 1 | 2 | 3;\n /** callback 回调(默认) / command 指令(输入框插入) / link 跳转 */\n action?: \"callback\" | \"command\" | \"link\";\n /** callback / command 的数据 */\n data?: string;\n /** link 的跳转地址 */\n url?: string;\n /** \"all\" 所有人 / \"admin\" 仅管理员 / 用户 id 列表 */\n permission?: \"all\" | \"admin\" | readonly string[];\n /** command 点击后是否直接发送 */\n enter?: boolean;\n /** command 是否引用本消息 */\n reply?: boolean;\n /** 客户端版本过低时的提示文案 */\n unsupportedTips?: string;\n}\n\n/** 会话引用:用于定位一段会话(含父会话) */\nexport interface ConversationRef {\n readonly type: string;\n readonly id: string;\n readonly parent_id?: string;\n}\n\nexport class MessageSegmentImpl implements MessageSegment {\n readonly type: string;\n readonly data: Readonly<Record<string, unknown>>;\n readonly attachment: Attachment | undefined;\n constructor(\n type: string,\n data: Record<string, unknown>,\n attachment?: Attachment,\n ) {\n this.type = type;\n this.data = Object.freeze({ ...data });\n this.attachment = attachment;\n }\n\n isText(): boolean {\n return this.type === \"text\";\n }\n\n toString(): string {\n if (this.type === \"text\" && typeof this.data.text === \"string\")\n return this.data.text;\n return JSON.stringify({ type: this.type, data: this.data });\n }\n}\n\nclass MessageImpl extends Array<MessageSegment> implements Message {\n readonly raw_message: string | undefined;\n constructor(\n segments: readonly MessageSegment[] | number,\n rawMessage?: string,\n ) {\n super();\n this.raw_message = rawMessage;\n if (typeof segments === \"number\") {\n this.length = segments;\n return;\n }\n for (const seg of segments) this.push(seg);\n }\n\n toString(): string {\n return this.map((seg) => seg.toString()).join(\"\");\n }\n\n text(): string {\n return (\n this.raw_message ??\n this.filterByType(\"text\")\n .map((seg) => String(seg.data.text ?? \"\"))\n .join(\"\")\n );\n }\n\n filterByType<T extends MessageSegment = MessageSegment>(type: string): T[] {\n return this.filter((seg): seg is T => seg.type === type);\n }\n\n toJSON(): SerializedMessageSegment[] {\n return this.map((seg) => ({\n type: seg.type,\n data: seg.data,\n attachment: seg.attachment,\n }));\n }\n}\n\nexport const createMessage = (\n segments: readonly MessageSegment[],\n rawMessage?: string,\n): Message => new MessageImpl(segments, rawMessage);\n\nconst fileData = (\n file: string | Buffer,\n options: { local?: boolean } = {},\n): Record<string, unknown> => {\n if (Buffer.isBuffer(file))\n return { file: `base64://${file.toString(\"base64\")}` };\n if (options.local)\n return { file: `file:///${file.replace(/^\\s*(file:\\/\\/\\/)+/, \"\")}` };\n return { file };\n};\n\n/** 消息段构造器:按类型快速生成消息段 */\nexport const segment = {\n text(text: string): MessageSegment {\n return new MessageSegmentImpl(\"text\", { text });\n },\n at(target: PlatformId): MessageSegment {\n return new MessageSegmentImpl(\"at\", { target: toId(target) });\n },\n /** `file` 为 URL 或本地路径;传 Buffer 会转成 base64 发送 */\n image(\n file: string | Buffer,\n options: { local?: boolean } & Attachment = {},\n ): MessageSegment {\n const { local = false, ...attachment } = options;\n const data: Record<string, unknown> = {};\n if (Buffer.isBuffer(file)) {\n data.file = `base64://${file.toString(\"base64\")}`;\n } else if (local) {\n data.file = `file:///${file.replace(/^\\s*(file:\\/\\/\\/)+/, \"\")}`;\n } else {\n data.url = file;\n }\n const attrs = Object.keys(attachment).length > 0 ? attachment : undefined;\n if (attrs) data.attachment = attrs;\n return new MessageSegmentImpl(\"image\", data, attrs);\n },\n reply(messageId: PlatformId): MessageSegment {\n return new MessageSegmentImpl(\"reply\", { message_id: toId(messageId) });\n },\n video(file: string | Buffer, options?: { local?: boolean }): MessageSegment {\n return new MessageSegmentImpl(\"video\", fileData(file, options));\n },\n record(file: string | Buffer, options?: { local?: boolean }): MessageSegment {\n return new MessageSegmentImpl(\"record\", fileData(file, options));\n },\n file(\n file: string | Buffer,\n options: { local?: boolean; name?: string } = {},\n ): MessageSegment {\n const data = fileData(file, options);\n if (options.name) data.name = options.name;\n return new MessageSegmentImpl(\"file\", data);\n },\n face(id: string | number): MessageSegment {\n return new MessageSegmentImpl(\"face\", { id: String(id) });\n },\n forward(id: string): MessageSegment {\n return new MessageSegmentImpl(\"forward\", { id });\n },\n node(options: {\n user_id: PlatformId;\n nickname: string;\n content: MessageInput;\n }): MessageSegment {\n return new MessageSegmentImpl(\"node\", {\n user_id: toId(options.user_id),\n nickname: options.nickname,\n content: Array.isArray(options.content)\n ? Array.from(options.content)\n : options.content,\n });\n },\n json(data: Record<string, unknown> | string): MessageSegment {\n return new MessageSegmentImpl(\"json\", {\n data: typeof data === \"string\" ? data : JSON.stringify(data),\n });\n },\n markdown(content: string): MessageSegment {\n return new MessageSegmentImpl(\"markdown\", { content });\n },\n button(options: ButtonOptions): MessageSegment {\n return new MessageSegmentImpl(\"button\", { ...options });\n },\n raw(\n type: string,\n data: Record<string, unknown>,\n attachment?: Attachment,\n ): MessageSegment {\n return new MessageSegmentImpl(type, data, attachment);\n },\n} as const;\n\nexport const isMessage = (value: unknown): value is Message =>\n value instanceof MessageImpl;\n\n/** 取消息中的第一个 @ 目标 */\nexport const atOf = (message: Message): string | undefined => {\n const at = message.filterByType(\"at\")[0];\n if (!at) return undefined;\n const raw = at.data?.qq ?? at.data?.target;\n return raw == null ? undefined : String(raw);\n};\n\nexport const isSegment = (value: unknown): value is MessageSegment =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as { type?: unknown }).type === \"string\";\n\n/** 把任意 `MessageInput` 规范化为 `Message` */\nexport const asMessage = (input: MessageInput): Message => {\n if (isMessage(input)) return input;\n if (typeof input === \"string\")\n return new MessageImpl([new MessageSegmentImpl(\"text\", { text: input })]);\n if (isSegment(input)) return new MessageImpl([input]);\n return new MessageImpl(\n (input as readonly (string | MessageSegment)[]).map((item) =>\n typeof item === \"string\"\n ? new MessageSegmentImpl(\"text\", { text: item })\n : item,\n ),\n );\n};\n","import type {\n Attachment,\n ConversationRef,\n Message,\n MessageInput,\n MessageTarget,\n ReplyOptions,\n SentMessage,\n} from './message'\n\n/** 事件的全局标识:来自哪个适配器、哪个 bot、哪类事件 */\nexport interface EventIdentity {\n readonly adapter: string\n readonly bot_id?: string\n readonly source_id?: string\n readonly event_type: string\n readonly message_id?: string\n readonly timestamp?: number\n readonly native_event_id?: string\n readonly fingerprint?: string\n}\n\n/** 所有事件的公共基础结构 */\nexport interface EventBase {\n /** 事件大类:message / notice / request / meta_event / adapter */\n readonly kind: string\n /** 事件类型,如 `message`、`notice.group.poke` */\n readonly type: string\n /** 该事件可匹配的路由列表,由 `buildRoutes` 生成 */\n readonly routes: readonly string[]\n readonly identity: EventIdentity\n readonly self_id?: string\n readonly bot?: import('./bot').Bot\n readonly time?: number\n readonly raw?: unknown\n}\n\n/** 与具体 bot 绑定的事件(含 message / notice / request / meta_event) */\nexport interface BotEventBase extends EventBase {\n readonly self_id: string\n readonly bot: import('./bot').Bot\n}\n\nexport interface SenderInfo {\n readonly user_id?: string\n readonly nickname?: string\n readonly card?: string\n readonly role?: 'owner' | 'admin' | 'member' | (string & {})\n}\n\n/** 消息事件:私聊与群聊消息 */\nexport interface MessageEvent extends BotEventBase {\n readonly kind: 'message'\n readonly message_type: 'private' | 'group' | 'channel' | 'thread' | 'direct' | (string & {})\n readonly sub_type?: string\n readonly user_id?: string\n readonly group_id?: string\n readonly group_name?: string\n readonly message_id?: string\n readonly raw_message?: string\n readonly quote_id?: string\n readonly sender?: SenderInfo\n readonly group?: import('../capabilities/group').Group\n readonly friend?: import('../capabilities/friend').Friend\n readonly conversation?: ConversationRef\n readonly message: Message\n readonly is_to_me?: boolean\n readonly at?: string\n /** 回复这条消息 */\n reply(message: MessageInput, options?: boolean | ReplyOptions): Promise<SentMessage>\n recall(): Promise<void>\n}\n\n/** 通知事件:群成员变动、戳一戳等 */\nexport interface NoticeEvent extends BotEventBase {\n readonly kind: 'notice'\n readonly notice_type?: string\n readonly sub_type?: string\n readonly user_id?: string\n readonly group_id?: string\n readonly operator_id?: string\n}\n\n/** 请求事件:加群/好友申请,可 approve 或 reject */\nexport interface RequestEvent extends BotEventBase {\n readonly kind: 'request'\n readonly request_type?: string\n readonly sub_type?: string\n readonly user_id?: string\n readonly group_id?: string\n readonly flag?: string\n readonly comment?: string\n approve(): Promise<void>\n reject(reason?: string): Promise<void>\n}\n\n/** 生命周期元事件 */\nexport interface MetaEvent extends BotEventBase {\n readonly kind: 'meta_event'\n readonly meta_event_type?: string\n readonly sub_type?: string\n}\n\n/** 适配器自定义事件:不归属以上四类时使用 */\nexport interface AdapterEvent extends EventBase {\n readonly kind: 'adapter'\n readonly payload: unknown\n}\n\nexport type Event = MessageEvent | NoticeEvent | RequestEvent | MetaEvent | AdapterEvent\n\nexport type BotEvent = MessageEvent | NoticeEvent | RequestEvent | MetaEvent\n\nexport const isMessageEvent = (e: Event): e is MessageEvent => e.kind === 'message'\nexport const isNoticeEvent = (e: Event): e is NoticeEvent => e.kind === 'notice'\nexport const isRequestEvent = (e: Event): e is RequestEvent => e.kind === 'request'\nexport const isMetaEvent = (e: Event): e is MetaEvent => e.kind === 'meta_event'\nexport const isAdapterEvent = (e: Event): e is AdapterEvent => e.kind === 'adapter'\nexport const isBotEvent = (e: Event): e is BotEvent =>\n e.kind === 'message' || e.kind === 'notice' || e.kind === 'request' || e.kind === 'meta_event'\n\nexport interface EventFactoryOptions<T extends MessageEvent | NoticeEvent | RequestEvent | MetaEvent | AdapterEvent> {\n readonly routes: readonly string[]\n readonly identity: EventIdentity\n readonly bot?: import('./bot').Bot\n readonly self_id?: string\n readonly time?: number\n readonly raw?: unknown\n}\n\n/**\n * 根据平台信息生成层级路由列表。\n * 例如 `buildRoutes(\"onebotv11\", \"message\", \"group\")` 会生成\n * `onebotv11:message.group`、`onebotv11:message`、`onebotv11`、`message.group`、`message` 等,\n * 监听任意一层都能收到该事件。\n */\nexport const buildRoutes = (adapter: string, ...parts: (string | undefined | null)[]): string[] => {\n const cleaned = parts.filter((p): p is string => typeof p === 'string' && p.length > 0)\n const routes: string[] = []\n const platformParts = [adapter, ...cleaned]\n for (let length = platformParts.length; length > 0; length--) {\n const [head, ...rest] = platformParts.slice(0, length)\n routes.push(rest.length > 0 ? `${head}:${rest.join('.')}` : head)\n }\n for (let length = cleaned.length; length > 0; length--) {\n routes.push(cleaned.slice(0, length).join('.'))\n }\n return Array.from(new Set(routes))\n}\n\nexport type { Attachment, ConversationRef, Message, MessageInput, MessageTarget, ReplyOptions, SentMessage }","/** 能力:一个可被适配器实现、被插件调用的操作契约(如 `message.send`) */\nexport interface Capability<I, O> {\n readonly name: string\n readonly version: number\n /** 能力唯一标识,同名同版本的实现只能注册一份 */\n readonly token: symbol\n}\n\n/** 定义一个能力,`I` 为请求类型,`O` 为返回类型 */\nexport const defineCapability = <I, O>(name: string, version: number = 1): Capability<I, O> => {\n if (name.length === 0) {\n throw new Error('defineCapability: name must be a non-empty string')\n }\n if (!Number.isInteger(version) || version < 1) {\n throw new Error('defineCapability: version must be a positive integer')\n }\n return { name, version, token: Symbol(name) }\n}\n\n/** 目标上没有注册该能力时抛出的错误 */\nexport class UnsupportedCapabilityError extends Error {\n readonly capability: string\n constructor(capability: string) {\n super(`Capability \"${capability}\" is not supported on this target`)\n this.name = 'UnsupportedCapabilityError'\n this.capability = capability\n }\n}\n","import { defineCapability } from '../adapter/capability'\nimport type { Message, MessageInput, MessageTarget, PlatformId, SentMessage } from '../adapter'\n\n/** 发送消息的请求参数 */\nexport interface MessageSendRequest {\n readonly target: MessageTarget\n readonly message: MessageInput\n}\n\n/** 撤回消息的请求参数 */\nexport interface MessageRecallRequest {\n readonly message_id: PlatformId\n}\n\n/** 获取单条消息的请求参数 */\nexport interface MessageGetRequest {\n readonly message_id: PlatformId\n}\n\n/** 获取到的消息详情 */\nexport interface MessageGetResult {\n readonly message_id: string\n readonly message: Message\n readonly raw_message?: string\n readonly time?: number\n readonly user_id?: string\n readonly [key: string]: unknown\n}\n\n/** 合并转发消息里的一条子消息 */\nexport interface ForwardNode {\n readonly user_id?: string\n readonly nickname?: string\n readonly time?: number\n readonly message: Message\n}\n\n/** 获取合并转发消息内容的请求参数 */\nexport interface MessageGetForwardRequest {\n readonly message_id: PlatformId\n}\n\n/** 构造合并转发消息的单个节点 */\nexport interface ForwardSendNode {\n readonly user_id: PlatformId\n readonly nickname: string\n readonly content: MessageInput\n}\n\n/** 合并转发消息的外显样式 */\nexport interface ForwardSendOptions {\n /** 卡片来源显示文本 */\n readonly source?: string\n /** 卡片外显的摘要条目 */\n readonly news?: ReadonlyArray<{ text: string }>\n /** 卡片底部的总摘要 */\n readonly summary?: string\n}\n\n/** 发送合并转发消息的请求参数 */\nexport interface ForwardSendRequest extends ForwardSendOptions {\n readonly target: MessageTarget\n readonly nodes: readonly ForwardSendNode[]\n}\n\n/** 发送消息 */\nexport const messageSend = defineCapability<MessageSendRequest, SentMessage>('message.send', 1)\n/** 撤回消息 */\nexport const messageRecall = defineCapability<MessageRecallRequest, void>('message.recall', 1)\n/** 获取单条消息 */\nexport const messageGet = defineCapability<MessageGetRequest, MessageGetResult>('message.get', 1)\n/** 获取合并转发消息的内容 */\nexport const messageGetForward = defineCapability<MessageGetForwardRequest, ForwardNode[]>('message.getforward', 1)\n/** 发送合并转发消息 */\nexport const forwardSend = defineCapability<ForwardSendRequest, SentMessage>('message.forwardsend', 1)","import { defineCapability } from '../adapter/capability'\nimport type { PlatformId } from '../adapter'\n\n/** 群成员信息 */\nexport interface MemberInfo {\n readonly user_id: string\n readonly nickname?: string\n /** 群名片 */\n readonly card?: string\n readonly role?: 'owner' | 'admin' | 'member' | (string & {})\n /** 入群时间 */\n readonly join_time?: number\n /** 最后一次发言时间 */\n readonly last_sent_time?: number\n readonly [key: string]: unknown\n}\n\n/** 禁言成员的请求参数 */\nexport interface MemberBanRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n /** 禁言时长(秒),0 = 解除禁言 */\n readonly duration: number\n}\n\n/** 将成员移出群聊的请求参数 */\nexport interface MemberKickRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n /** 是否拒绝该成员后续的加群申请 */\n readonly reject_add_request?: boolean\n}\n\n/** 设置成员群名片的请求参数 */\nexport interface MemberSetCardRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n readonly card: string\n}\n\n/** 设置或取消群管理员的请求参数 */\nexport interface MemberSetAdminRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n readonly enable: boolean\n}\n\n/** 查询群成员信息的请求参数 */\nexport interface MemberGetInfoRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n}\n\n/** 戳一戳群成员的请求参数 */\nexport interface MemberPokeRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n}\n\n/** 设置成员专属头衔的请求参数 */\nexport interface MemberSetTitleRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n readonly title: string\n}\n\n/** 禁言群成员 */\nexport const memberBan = defineCapability<MemberBanRequest, void>('member.ban', 1)\n/** 将成员移出群聊 */\nexport const memberKick = defineCapability<MemberKickRequest, void>('member.kick', 1)\n/** 设置成员群名片 */\nexport const memberSetCard = defineCapability<MemberSetCardRequest, void>('member.setcard', 1)\n/** 设置或取消管理员 */\nexport const memberSetAdmin = defineCapability<MemberSetAdminRequest, void>('member.setadmin', 1)\n/** 获取群成员信息 */\nexport const memberGetInfo = defineCapability<MemberGetInfoRequest, MemberInfo>('member.getinfo', 1)\n/** 戳一戳群成员 */\nexport const memberPoke = defineCapability<MemberPokeRequest, void>('member.poke', 1)\n/** 设置成员专属头衔 */\nexport const memberSetTitle = defineCapability<MemberSetTitleRequest, void>('member.settitle', 1)\n","import { defineCapability } from '../adapter/capability'\nimport { toId } from '../adapter'\n\nimport type { PlatformId, Bot, MessageInput, SentMessage } from '../adapter'\nimport type { MemberInfo } from './member'\n\n/** 群信息 */\nexport interface GroupInfo {\n readonly group_id: string\n readonly group_name?: string\n readonly member_count?: number\n readonly max_member_count?: number\n readonly [key: string]: unknown\n}\n\n/** 获取群信息的请求参数 */\nexport interface GroupGetInfoRequest {\n readonly group_id: PlatformId\n}\n\n/** 获取群成员列表的请求参数 */\nexport interface GroupGetMembersRequest {\n readonly group_id: PlatformId\n}\n\n/** 退出群聊的请求参数 */\nexport interface GroupLeaveRequest {\n readonly group_id: PlatformId\n /** 是否解散群 */\n readonly is_dismiss?: boolean\n}\n\n/** 修改群名的请求参数 */\nexport interface GroupSetNameRequest {\n readonly group_id: PlatformId\n readonly group_name: string\n}\n\n/** 设置群头像的请求参数 */\nexport interface GroupSetPortraitRequest {\n readonly group_id: PlatformId\n /** 图片 URL 或本地路径 */\n readonly file: string\n}\n\n/** 全员禁言的请求参数 */\nexport interface GroupSetWholeBanRequest {\n readonly group_id: PlatformId\n readonly enable: boolean\n}\n\n/** 获取群列表的请求参数 */\nexport interface GroupGetListRequest {}\n\n/** 获取群信息 */\nexport const groupGetInfo = defineCapability<GroupGetInfoRequest, GroupInfo>('group.getinfo', 1)\n/** 获取群成员列表 */\nexport const groupGetMembers = defineCapability<GroupGetMembersRequest, MemberInfo[]>('group.getmembers', 1)\n/** 退出群聊 */\nexport const groupLeave = defineCapability<GroupLeaveRequest, void>('group.leave', 1)\n/** 修改群名 */\nexport const groupSetName = defineCapability<GroupSetNameRequest, void>('group.setname', 1)\n/** 全员禁言 */\nexport const groupSetWholeBan = defineCapability<GroupSetWholeBanRequest, void>('group.setwholeban', 1)\n/** 设置群头像 */\nexport const groupSetPortrait = defineCapability<GroupSetPortraitRequest, void>('group.setportrait', 1)\n/** 获取群列表 */\nexport const groupGetList = defineCapability<GroupGetListRequest, GroupInfo[]>('group.getlist', 1)\n\n/** 群操作句柄:绑定某个群的快捷操作 */\nexport interface Group {\n readonly group_id: string\n readonly group_name?: string\n sendMsg(message: MessageInput): Promise<SentMessage>\n getInfo(): Promise<GroupInfo | null>\n getList(): Promise<GroupInfo[]>\n getMemberList(): Promise<MemberInfo[]>\n getMemberInfo(userId: PlatformId): Promise<MemberInfo | null>\n /** 禁言成员,duration 单位为秒,0 表示解除 */\n ban(userId: PlatformId, duration: number): Promise<void>\n kick(userId: PlatformId, rejectAddRequest?: boolean): Promise<void>\n setCard(userId: PlatformId, card: string): Promise<void>\n setAdmin(userId: PlatformId, enable: boolean): Promise<void>\n recall(messageId: PlatformId): Promise<void>\n /** 退出群聊,isDismiss 为 true 时解散群 */\n leave(isDismiss?: boolean): Promise<void>\n setName(groupName: string): Promise<void>\n setPortrait(file: string): Promise<void>\n}\n\n/** 为指定群创建操作句柄 */\nexport const createGroupRef = (bot: Bot, group_id: PlatformId, group_name?: string): Group => {\n const gid = toId(group_id)\n return {\n group_id: gid,\n group_name,\n sendMsg: (message) => bot.sendGroupMsg(gid, message),\n getInfo: () => bot.getGroupInfo(gid),\n getList: () => bot.getGroupList(),\n getMemberList: () => bot.getGroupMembers(gid),\n getMemberInfo: (userId) => bot.getMemberInfo(gid, userId),\n ban: (userId, duration) => bot.banMember(gid, userId, duration),\n kick: (userId, rejectAddRequest) => bot.kickMember(gid, userId, rejectAddRequest),\n setCard: (userId, card) => bot.setMemberCard(gid, userId, card),\n setAdmin: (userId, enable) => bot.setMemberAdmin(gid, userId, enable),\n recall: (messageId) => bot.recallMessage(messageId),\n leave: (isDismiss) => bot.leaveGroup(gid, isDismiss),\n setName: (groupName) => bot.setGroupName(gid, groupName),\n setPortrait: (file) => bot.setGroupPortrait(gid, file),\n }\n}\n","import { defineCapability } from '../adapter/capability'\nimport { toId } from '../adapter'\n\nimport type { Bot, MessageInput, PlatformId, SentMessage } from '../adapter'\n\n/** 好友信息 */\nexport interface FriendInfo {\n readonly user_id: string\n readonly nickname?: string\n readonly remark?: string\n readonly [key: string]: unknown\n}\n\n/** 获取好友信息的请求参数 */\nexport interface FriendGetInfoRequest {\n readonly user_id: PlatformId\n}\n\n/** 删除好友的请求参数 */\nexport interface FriendDeleteRequest {\n readonly user_id: PlatformId\n}\n\n/** 获取好友列表的请求参数 */\nexport interface FriendGetListRequest {}\n\n/** 获取好友信息 */\nexport const friendGetInfo = defineCapability<FriendGetInfoRequest, FriendInfo>('friend.getinfo', 1)\n/** 删除好友 */\nexport const friendDelete = defineCapability<FriendDeleteRequest, void>('friend.delete', 1)\n/** 获取好友列表 */\nexport const friendGetList = defineCapability<FriendGetListRequest, FriendInfo[]>('friend.getlist', 1)\n\n/** 好友操作句柄:绑定某个好友的快捷操作 */\nexport interface Friend {\n readonly user_id: string\n readonly nickname?: string\n sendMsg(message: MessageInput): Promise<SentMessage>\n getInfo(): Promise<FriendInfo | null>\n getList(): Promise<FriendInfo[]>\n delete(): Promise<void>\n}\n\n/** 为指定好友创建操作句柄 */\nexport const createFriendRef = (bot: Bot, user_id: PlatformId, nickname?: string): Friend => {\n const uid = toId(user_id)\n return {\n user_id: uid,\n nickname,\n sendMsg: (message) => bot.sendPrivateMsg(uid, message),\n getInfo: () => bot.getFriendInfo(uid),\n getList: () => bot.getFriendList(),\n delete: () => bot.deleteFriend(uid),\n }\n}\n","import { defineCapability } from \"../adapter/capability\";\nimport type { MessageTarget, PlatformId } from \"../adapter\";\n\n/** 历史消息记录 */\nexport interface HistoryMessage {\n readonly message_id: string;\n readonly time?: number;\n readonly user_id?: string;\n readonly nickname?: string;\n readonly message: import(\"../adapter\").Message;\n readonly source?: unknown;\n}\n\n/** 拉取会话历史消息的请求参数 */\nexport interface ConversationGetHistoryRequest {\n readonly target: MessageTarget;\n /** 从这个消息 id 之前开始取(不含该条) */\n readonly before?: PlatformId;\n readonly limit?: number;\n /** 适配器私有扩展参数透传 */\n readonly extra?: Record<string, unknown>;\n}\n\n/** 拉取会话的历史消息 */\nexport const conversationGetHistory = defineCapability<\n ConversationGetHistoryRequest,\n HistoryMessage[]\n>(\"conversation.gethistory\", 1);\n","import { defineCapability } from '../adapter/capability'\n\n/** 修改 bot 自身资料的请求参数 */\nexport interface ProfileSetRequest {\n readonly nickname?: string\n /** 个性签名 */\n readonly personal_note?: string\n /** 性别编码,具体取值由适配器定义 */\n readonly sex?: number\n readonly [key: string]: unknown\n}\n\n/** 设置 bot 头像的请求参数 */\nexport interface AvatarSetRequest {\n /** 图片 URL 或本地路径 */\n readonly file: string\n}\n\n/** 修改 bot 自身资料 */\nexport const profileSet = defineCapability<ProfileSetRequest, void>('profile.set', 1)\n/** 设置 bot 头像 */\nexport const avatarSet = defineCapability<AvatarSetRequest, void>('profile.setavatar', 1)","import { defineCapability } from '../adapter/capability'\n\n/** bot 登录状态信息 */\nexport interface BotStatusResult {\n readonly online: boolean\n readonly app_name?: string\n readonly app_version?: string\n readonly protocol_version?: string\n readonly [key: string]: unknown\n}\n\n/** 查询 bot 登录状态 */\nexport const botStatus = defineCapability<Record<string, never>, BotStatusResult>('bot.status', 1)","import type { CapabilityRegistry } from \"./registry\";\nimport type { CapabilityTarget } from \"./types\";\nimport type { Capability } from \"./capability\";\nimport type {\n MessageInput,\n MessageTarget,\n PlatformId,\n SentMessage,\n} from \"./message\";\nimport { toId } from \"./message\";\n\nimport {\n messageRecall,\n messageGet,\n messageGetForward,\n forwardSend,\n memberBan,\n memberKick,\n memberSetCard,\n memberSetAdmin,\n memberGetInfo,\n memberPoke,\n memberSetTitle,\n groupGetInfo,\n groupGetMembers,\n groupGetList,\n groupLeave,\n groupSetName,\n groupSetWholeBan,\n groupSetPortrait,\n friendGetInfo,\n friendGetList,\n friendDelete,\n profileSet,\n avatarSet,\n conversationGetHistory,\n botStatus,\n ForwardNode,\n ForwardSendNode,\n ForwardSendOptions,\n MessageGetResult,\n MemberInfo,\n GroupInfo,\n FriendInfo,\n HistoryMessage,\n ProfileSetRequest,\n BotStatusResult,\n} from \"../capabilities\";\n\n/**\n * Bot 接口:所有平台 bot 的统一操作面。\n * 除 `bot_id` / `adapter` / `sendMessage` / `sendApi` / `as` 外,\n * 其余方法由框架按能力自动绑定(见 `bindCapabilities`)。\n */\nexport interface BotBase {\n readonly bot_id: string;\n readonly adapter: string;\n readonly nickname?: string;\n readonly online: boolean;\n readonly connected_at?: number;\n\n // —— 消息 ——\n sendMessage(\n target: MessageTarget,\n message: MessageInput,\n ): Promise<SentMessage>;\n sendGroupMsg(\n group_id: PlatformId,\n message: MessageInput,\n ): Promise<SentMessage>;\n sendPrivateMsg(\n user_id: PlatformId,\n message: MessageInput,\n ): Promise<SentMessage>;\n recallMessage(message_id: PlatformId): Promise<void>;\n getMessage(message_id: PlatformId): Promise<MessageGetResult | null>;\n getForwardMessage(message_id: PlatformId): Promise<ForwardNode[]>;\n sendForward(\n target: MessageTarget,\n nodes: readonly ForwardSendNode[],\n options?: ForwardSendOptions,\n ): Promise<SentMessage>;\n\n // —— 群 / 成员 ——\n getGroupInfo(group_id: PlatformId): Promise<GroupInfo | null>;\n getGroupList(): Promise<GroupInfo[]>;\n getGroupMembers(group_id: PlatformId): Promise<MemberInfo[]>;\n getMemberInfo(\n group_id: PlatformId,\n user_id: PlatformId,\n ): Promise<MemberInfo | null>;\n /** duration 单位为秒,0 = 解除禁言 */\n banMember(\n group_id: PlatformId,\n user_id: PlatformId,\n duration: number,\n ): Promise<void>;\n /** reject_add_request 为 true 时同时拒绝该成员后续的加群申请 */\n kickMember(\n group_id: PlatformId,\n user_id: PlatformId,\n reject_add_request?: boolean,\n ): Promise<void>;\n setMemberCard(\n group_id: PlatformId,\n user_id: PlatformId,\n card: string,\n ): Promise<void>;\n setMemberAdmin(\n group_id: PlatformId,\n user_id: PlatformId,\n enable: boolean,\n ): Promise<void>;\n setMemberTitle(\n group_id: PlatformId,\n user_id: PlatformId,\n title: string,\n ): Promise<void>;\n pokeMember(group_id: PlatformId, user_id: PlatformId): Promise<void>;\n setGroupName(group_id: PlatformId, group_name: string): Promise<void>;\n setGroupWholeBan(group_id: PlatformId, enable: boolean): Promise<void>;\n setGroupPortrait(group_id: PlatformId, file: string): Promise<void>;\n /** is_dismiss 为 true 时解散群(仅群主可用) */\n leaveGroup(group_id: PlatformId, is_dismiss?: boolean): Promise<void>;\n\n // —— 好友 ——\n getFriendInfo(user_id: PlatformId): Promise<FriendInfo | null>;\n getFriendList(): Promise<FriendInfo[]>;\n deleteFriend(user_id: PlatformId): Promise<void>;\n\n // —— 资料 / 会话 / 状态 ——\n setProfile(profile: ProfileSetRequest): Promise<void>;\n /** file 为本地路径或 URL */\n setAvatar(file: string): Promise<void>;\n /** 拉取会话历史,`before` 为上一页的消息 id */\n getHistory(\n target: MessageTarget,\n before?: string,\n limit?: number,\n extra?: Record<string, unknown>,\n ): Promise<HistoryMessage[]>;\n getStatus(): Promise<BotStatusResult>;\n /** 直接调用平台原生 API(action 为平台动作名) */\n sendApi<T = unknown>(\n action: string,\n params?: Record<string, unknown>,\n ): Promise<T>;\n /** 按目标类型断言 bot,用于访问平台特有方法 */\n as<T extends object = Record<string, unknown>>(): T;\n}\n\nexport type BotProvidedKeys =\n | \"bot_id\"\n | \"adapter\"\n | \"nickname\"\n | \"online\"\n | \"connected_at\"\n | \"sendMessage\"\n | \"sendApi\"\n | \"as\";\n\nexport type BotAutoFilled = Exclude<keyof BotBase, BotProvidedKeys>;\n\nexport type AdapterBotBase<B extends BotBase> = Omit<B, BotAutoFilled> &\n Partial<Pick<B, BotAutoFilled>>;\n\nexport interface AdapterBotMap {}\n\nexport type Bot = AdapterBotMap[keyof AdapterBotMap] extends never\n ? BotBase\n : AdapterBotMap[keyof AdapterBotMap];\n\nexport interface BotContext {\n readonly bot: Bot;\n unregister(): void;\n}\n\nconst bindDefault = <B extends object>(\n bot: B,\n name: string,\n value: unknown,\n): void => {\n if (!(name in bot)) {\n Object.defineProperty(bot, name, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n};\n\n/**\n * 把能力注册表中的实现绑定为 bot 的方法。\n * 适配器在 `start()` 里对自己创建的 bot 调用一次,\n * 插件拿到的 bot 就带上了完整操作面。\n */\nexport const bindCapabilities = <B extends object>(\n bot: B,\n registry: CapabilityRegistry,\n): B & BotBase => {\n const target: CapabilityTarget = {\n adapter: (bot as BotBase).adapter,\n bot_id: (bot as BotBase).bot_id,\n };\n const call = async <I, O>(\n capability: Capability<I, O>,\n input: I,\n ): Promise<O> => registry.invoke(target, capability, input);\n\n bindDefault(\n bot,\n \"as\",\n <T extends object = Record<string, unknown>>() => bot as unknown as T,\n );\n bindDefault(\n bot,\n \"sendGroupMsg\",\n (group_id: PlatformId, message: MessageInput) =>\n (bot as BotBase).sendMessage(\n { type: \"group\", group_id: toId(group_id) },\n message,\n ),\n );\n bindDefault(\n bot,\n \"sendPrivateMsg\",\n (user_id: PlatformId, message: MessageInput) =>\n (bot as BotBase).sendMessage(\n { type: \"private\", user_id: toId(user_id) },\n message,\n ),\n );\n bindDefault(bot, \"recallMessage\", async (message_id: PlatformId) => {\n await call(messageRecall, { message_id: toId(message_id) });\n });\n bindDefault(bot, \"getMessage\", (message_id: PlatformId) =>\n call(messageGet, { message_id: toId(message_id) }),\n );\n bindDefault(bot, \"getForwardMessage\", (message_id: PlatformId) =>\n call(messageGetForward, { message_id: toId(message_id) }),\n );\n bindDefault(\n bot,\n \"sendForward\",\n (\n t: MessageTarget,\n nodes: readonly ForwardSendNode[],\n options?: ForwardSendOptions,\n ) =>\n call(forwardSend, {\n target: t,\n nodes,\n source: options?.source,\n news: options?.news,\n summary: options?.summary,\n }),\n );\n bindDefault(bot, \"getGroupInfo\", (group_id: PlatformId) =>\n call(groupGetInfo, { group_id: toId(group_id) }),\n );\n bindDefault(bot, \"getGroupList\", () => call(groupGetList, {}));\n bindDefault(bot, \"getGroupMembers\", (group_id: PlatformId) =>\n call(groupGetMembers, { group_id: toId(group_id) }),\n );\n bindDefault(\n bot,\n \"getMemberInfo\",\n (group_id: PlatformId, user_id: PlatformId) =>\n call(memberGetInfo, { group_id: toId(group_id), user_id: toId(user_id) }),\n );\n bindDefault(\n bot,\n \"banMember\",\n (group_id: PlatformId, user_id: PlatformId, duration: number) =>\n call(memberBan, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n duration,\n }),\n );\n bindDefault(\n bot,\n \"kickMember\",\n (group_id: PlatformId, user_id: PlatformId, reject_add_request?: boolean) =>\n call(memberKick, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n reject_add_request: reject_add_request,\n }),\n );\n bindDefault(\n bot,\n \"setMemberCard\",\n (group_id: PlatformId, user_id: PlatformId, card: string) =>\n call(memberSetCard, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n card,\n }),\n );\n bindDefault(\n bot,\n \"setMemberAdmin\",\n (group_id: PlatformId, user_id: PlatformId, enable: boolean) =>\n call(memberSetAdmin, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n enable,\n }),\n );\n bindDefault(\n bot,\n \"setMemberTitle\",\n (group_id: PlatformId, user_id: PlatformId, title: string) =>\n call(memberSetTitle, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n title,\n }),\n );\n bindDefault(bot, \"pokeMember\", (group_id: PlatformId, user_id: PlatformId) =>\n call(memberPoke, { group_id: toId(group_id), user_id: toId(user_id) }),\n );\n bindDefault(bot, \"setGroupName\", (group_id: PlatformId, group_name: string) =>\n call(groupSetName, { group_id: toId(group_id), group_name }),\n );\n bindDefault(\n bot,\n \"setGroupWholeBan\",\n (group_id: PlatformId, enable: boolean) =>\n call(groupSetWholeBan, { group_id: toId(group_id), enable }),\n );\n bindDefault(bot, \"setGroupPortrait\", (group_id: PlatformId, file: string) =>\n call(groupSetPortrait, { group_id: toId(group_id), file }),\n );\n bindDefault(bot, \"leaveGroup\", (group_id: PlatformId, is_dismiss?: boolean) =>\n call(groupLeave, { group_id: toId(group_id), is_dismiss }),\n );\n bindDefault(bot, \"getFriendInfo\", (user_id: PlatformId) =>\n call(friendGetInfo, { user_id: toId(user_id) }),\n );\n bindDefault(bot, \"getFriendList\", () => call(friendGetList, {}));\n bindDefault(bot, \"deleteFriend\", (user_id: PlatformId) =>\n call(friendDelete, { user_id: toId(user_id) }),\n );\n bindDefault(bot, \"setProfile\", (profile: ProfileSetRequest) =>\n call(profileSet, profile),\n );\n bindDefault(bot, \"setAvatar\", (file: string) => call(avatarSet, { file }));\n bindDefault(\n bot,\n \"getHistory\",\n (\n t: MessageTarget,\n before?: string,\n limit?: number,\n extra?: Record<string, unknown>,\n ) => call(conversationGetHistory, { target: t, before, limit, extra }),\n );\n bindDefault(bot, \"getStatus\", () => call(botStatus, {}));\n\n return bot as B & BotBase;\n};\n","import type { Capability } from \"./capability\";\nimport type { CapabilityRegistry } from \"./registry\";\nimport type { Driver } from \"../driver\";\nimport type { Event } from \"./event\";\n\n/** 能力的作用目标:按适配器 / bot / 具体资源定位能力实现 */\nexport interface CapabilityTarget {\n readonly adapter: string;\n readonly bot_id?: string;\n readonly resource_id?: string;\n}\n\n/** 适配器定义:适配器包导出的核心对象,`defineAdapter()` 的返回值 */\nexport interface AdapterDefinition<TConfig = unknown> {\n readonly name: string;\n readonly version: string;\n /** 框架与适配器的 API 约定版本,不匹配会拒绝加载 */\n readonly apiVersion: number;\n readonly create: (\n options: AdapterFactoryOptions<TConfig>,\n ) => Adapter | Promise<Adapter>;\n readonly validateConfig?: (config: unknown) => TConfig;\n}\n\nexport interface AdapterFactoryOptions<TConfig = unknown> {\n readonly config: TConfig;\n readonly logger: import(\"../logger\").Logger;\n}\n\n/** 适配器启动后拿到的上下文:注册 bot、能力、网关与资源,派发事件 */\nexport interface AdapterContext {\n registerBot(bot: import(\"./bot\").Bot): import(\"./bot\").BotContext;\n unregisterBot(bot_id: string): void;\n getDriver(): Driver;\n registerCapability<I, O>(\n capability: Capability<I, O>,\n target: CapabilityTarget,\n handler: (input: I) => Promise<O>,\n ): () => void;\n getCapabilityRegistry(): CapabilityRegistry;\n registerGateway(gateway: AdapterGateway): () => void;\n registerResource(resource: AdapterResource): () => void;\n dispatch(event: Event): Promise<void>;\n emitLifecycle(event: BotLifecycleEvent): Promise<void>;\n /**\n * 订阅框架事件总线上的事件\n * 返回取消订阅函数\n */\n listen(\n route: string,\n handler: (event: Event) => void | Promise<void>,\n ): () => void;\n}\n\n/** 适配器实例:start 时建立连接并注册资源,stop 时释放 */\nexport interface Adapter {\n readonly name: string;\n readonly version: string;\n /** 底层实现库 */\n readonly impl?: { readonly name: string; readonly version?: string };\n\n start(context: AdapterContext): Promise<void> | void;\n stop(reason?: string): Promise<void> | void;\n}\n\n/** 网关:适配器内部的一个独立连接单元(如一条 WebSocket 连接) */\nexport interface AdapterGateway {\n readonly name: string;\n start(): Promise<void> | void;\n stop(reason?: string): Promise<void> | void;\n}\n\n/** 资源的归属范围:适配器级 / 网关级 / bot 级 */\nexport type AdapterResourceScope = \"adapter\" | \"gateway\" | \"bot\";\n\n/** 适配器声明的可释放资源,随适配器关闭一并清理 */\nexport interface AdapterResource {\n readonly name: string;\n readonly scope: AdapterResourceScope;\n readonly gateway?: string;\n readonly bot_id?: string;\n dispose(reason?: string): void | Promise<void>;\n}\n\nexport interface BotLifecycleEvent {\n readonly type: \"bot:connected\" | \"bot:disconnected\";\n readonly bot: import(\"./bot\").Bot;\n readonly reason?: string;\n}\n\nexport const defineAdapter = <TConfig>(\n definition: AdapterDefinition<TConfig>,\n): AdapterDefinition<TConfig> => definition;\n","import { UnsupportedCapabilityError, type Capability } from './capability'\nimport type { CapabilityTarget } from './types'\n\nexport interface CapabilityHandler<I, O> {\n readonly capability: Capability<I, O>\n readonly target: CapabilityTarget\n readonly handler: (input: I) => Promise<O>\n}\n\n/** 能力注册表:按目标(适配器/bot/资源)登记能力的实现,供调用方查找 */\nexport class CapabilityRegistry {\n #handlers: CapabilityHandler<unknown, unknown>[] = []\n\n /** 注册一个能力的实现,返回取消注册函数 */\n register<I, O>(\n capability: Capability<I, O>,\n target: CapabilityTarget,\n handler: (input: I) => Promise<O>,\n ): () => void {\n const existing = this.#handlers.find(\n (h) =>\n h.capability.token === capability.token &&\n h.capability.version === capability.version &&\n h.target.adapter === target.adapter &&\n (h.target.bot_id ?? null) === (target.bot_id ?? null) &&\n (h.target.resource_id ?? null) === (target.resource_id ?? null),\n )\n if (existing) {\n throw new Error(\n `Capability \"${capability.name}\" is already registered for ${target.adapter}${\n target.bot_id ? `:${target.bot_id}` : ''\n }${target.resource_id ? `/${target.resource_id}` : ''}`,\n )\n }\n const entry: CapabilityHandler<unknown, unknown> = {\n capability,\n target,\n handler: handler as (input: unknown) => Promise<unknown>,\n }\n this.#handlers.push(entry)\n return () => {\n const idx = this.#handlers.indexOf(entry)\n if (idx >= 0) this.#handlers.splice(idx, 1)\n }\n }\n\n /** 目标是否支持该能力 */\n supports<I, O>(target: CapabilityTarget, capability: Capability<I, O>): boolean {\n return this.#handlers.some(\n (h) =>\n h.capability.token === capability.token &&\n h.capability.version === capability.version &&\n h.target.adapter === target.adapter &&\n (h.target.bot_id ?? null) === (target.bot_id ?? null) &&\n (h.target.resource_id ?? null) === (target.resource_id ?? null),\n )\n }\n\n /** 在目标上调用能力,未注册时抛 `UnsupportedCapabilityError` */\n async invoke<I, O>(target: CapabilityTarget, capability: Capability<I, O>, input: I): Promise<O> {\n const handler = this.#handlers.find(\n (h) =>\n h.capability.token === capability.token &&\n h.capability.version === capability.version &&\n h.target.adapter === target.adapter &&\n (h.target.bot_id ?? null) === (target.bot_id ?? null) &&\n (h.target.resource_id ?? null) === (target.resource_id ?? null),\n )\n if (!handler) {\n throw new UnsupportedCapabilityError(capability.name)\n }\n return (handler.handler as (input: I) => Promise<O>)(input)\n }\n\n clear(): void {\n this.#handlers.length = 0\n }\n}\n","import type { MiokuContext } from '../runtime/mioku-context'\nimport type { TaskContext } from 'node-cron'\n\nexport type { MiokuContext }\n\n/** 插件卸载时执行的清理函数 */\nexport type PluginCleanup = () => void | Promise<void>\n\n/** bot 上线 / 下线时的回调 */\nexport type BotHandler = (event: import('../adapter/types').BotLifecycleEvent) => void | Promise<void>\n/** 定时任务回调 */\nexport type CronHandler = (ctx: MiokuContext, task: TaskContext) => void | Promise<void>\n/** 定时任务实例,来自 node-cron */\nexport type ScheduledTask = import('node-cron').ScheduledTask\n\n/** 插件定义 */\nexport interface MiokuPlugin {\n name: string\n version?: string\n /** 加载顺序,数值越小越先加载 */\n priority?: number\n description?: string\n /** 依赖的其他插件名 */\n dependencies?: string[]\n /** 插件入口,可返回清理函数供卸载时调用 */\n setup?(ctx: MiokuContext): void | Promise<void | PluginCleanup> | PluginCleanup\n}\n\n/** 定义一个插件,仅提供类型约束 */\nexport const definePlugin = <T extends MiokuPlugin>(plugin: T): T => plugin\n","import type { Bot, BotContext } from '../adapter'\nimport type { Capability } from '../adapter'\nimport type { AdapterContext, AdapterGateway, AdapterResource, BotLifecycleEvent, CapabilityTarget } from '../adapter'\nimport type { Driver } from '../driver'\nimport type { Event } from '../adapter'\nimport type { CapabilityRegistry } from '../adapter'\nimport type { EventBus } from './bus'\nimport type { CrossAdapterMessageDeduplicator } from './cross-adapter-dedup'\nimport type { Logger } from '../logger'\nimport type { BotRegistry } from './bots'\nimport type { Adapter } from '../adapter'\n\nexport class AdapterRegistrationConflictError extends Error {\n constructor(key: string) {\n super(`Bot already registered for ${key}`)\n this.name = 'AdapterRegistrationConflictError'\n }\n}\n\nexport interface RuntimeAdapterState {\n readonly definition: import('../adapter/types').AdapterDefinition<unknown>\n instance: Adapter | null\n context: AdapterContextImpl | null\n gateways: AdapterGateway[] | null\n resources: AdapterResource[] | null\n started: boolean\n}\n\nexport class AdapterContextImpl implements AdapterContext {\n readonly #state: RuntimeAdapterState\n readonly #bots: BotRegistry\n readonly #bus: EventBus\n readonly #driver: Driver\n readonly #capabilities: CapabilityRegistry\n readonly #logger: Logger\n readonly #emit: (event: BotLifecycleEvent) => Promise<void>\n readonly #pendingStarts = new Set<Promise<void>>()\n readonly #crossDedup: CrossAdapterMessageDeduplicator | null\n\n constructor(options: {\n state: RuntimeAdapterState\n bots: BotRegistry\n bus: EventBus\n driver: Driver\n capabilities: CapabilityRegistry\n logger: Logger\n emit: (event: BotLifecycleEvent) => Promise<void>\n crossDedup?: CrossAdapterMessageDeduplicator | null\n }) {\n this.#state = options.state\n this.#bots = options.bots\n this.#bus = options.bus\n this.#driver = options.driver\n this.#capabilities = options.capabilities\n this.#logger = options.logger\n this.#emit = options.emit\n this.#crossDedup = options.crossDedup ?? null\n }\n\n registerBot(bot: Bot): BotContext {\n return this.#bots.register(bot)\n }\n\n unregisterBot(bot_id: string): void {\n this.#bots.unregister(bot_id, this.#state.definition.name)\n }\n\n getDriver(): Driver {\n return this.#driver\n }\n\n registerCapability<I, O>(\n capability: Capability<I, O>,\n target: CapabilityTarget,\n handler: (input: I) => Promise<O>,\n ): () => void {\n const finalTarget: CapabilityTarget = {\n ...target,\n adapter: target.adapter ?? this.#state.definition.name,\n }\n return this.#capabilities.register(capability, finalTarget, handler)\n }\n\n getCapabilityRegistry(): CapabilityRegistry {\n return this.#capabilities\n }\n\n registerGateway(gateway: AdapterGateway): () => void {\n if (!this.#state.gateways) {\n throw new Error('registerGateway called outside of adapter start()')\n }\n if (this.#state.gateways.find((g) => g.name === gateway.name)) {\n throw new Error(`Gateway \"${gateway.name}\" already registered for adapter \"${this.#state.definition.name}\"`)\n }\n this.#state.gateways.push(gateway)\n const startPromise = Promise.resolve(gateway.start()).then(\n () => undefined,\n (err: unknown) => {\n this.#logger.error(`Gateway \"${gateway.name}\" failed to start`, err)\n throw err\n },\n )\n this.#pendingStarts.add(startPromise)\n void startPromise.then(\n () => this.#pendingStarts.delete(startPromise),\n () => this.#pendingStarts.delete(startPromise),\n )\n return () => {\n const idx = this.#state.gateways?.indexOf(gateway) ?? -1\n if (idx >= 0 && this.#state.gateways) {\n this.#state.gateways.splice(idx, 1)\n void Promise.resolve(gateway.stop('unregistered')).catch(() => undefined)\n }\n }\n }\n\n async waitForStarts(): Promise<void> {\n await Promise.all(this.#pendingStarts)\n }\n\n registerResource(resource: AdapterResource): () => void {\n if (!this.#state.resources) {\n throw new Error('registerResource called outside of adapter start()')\n }\n if (resource.scope === 'gateway' && !resource.gateway) {\n throw new Error('Resource with scope \"gateway\" requires gateway name')\n }\n if (resource.scope === 'bot' && !resource.bot_id) {\n throw new Error('Resource with scope \"bot\" requires bot_id')\n }\n if (resource.scope === 'gateway') {\n const gateway = this.#state.gateways?.find((g) => g.name === resource.gateway)\n if (!gateway) {\n throw new Error(`Resource references unknown gateway \"${resource.gateway}\"`)\n }\n }\n if (resource.scope === 'bot') {\n const key = `${this.#state.definition.name}:${resource.bot_id}`\n if (!this.#bots.has(key)) {\n throw new Error(`Resource references unknown bot \"${resource.bot_id}\"`)\n }\n }\n this.#state.resources.push(resource)\n return () => {\n const idx = this.#state.resources?.indexOf(resource) ?? -1\n if (idx >= 0 && this.#state.resources) {\n this.#state.resources.splice(idx, 1)\n void Promise.resolve(resource.dispose('unregistered')).catch(() => undefined)\n }\n }\n }\n\n async dispatch(event: Event): Promise<void> {\n if (event.kind === 'message') {\n // 发送者是本运行时里另一台已连接 bot(如同群的其它 bot 实例)时,\n // 不进入任何 handler,切断 bot 互相触发导致的循环。\n // 发送者恰为接收 bot 自身 id 的消息(自身回显、stdin 控制台用户)保持原行为,\n // 由插件层的 self 过滤与 owner 体系处理。\n const senderId = event.user_id\n if (senderId != null) {\n const senderBot = this.#bots.pick(senderId)\n if (senderBot && senderBot.bot_id !== event.self_id) {\n this.#logger.debug(\n `拦截来自其他已连接 bot 的消息: sender=${senderId} self=${event.self_id}`,\n )\n return\n }\n }\n if (this.#crossDedup?.isDuplicate(event)) {\n this.#logger.debug(\n `丢弃跨适配器重复消息: adapter=${event.identity?.adapter ?? ''} sender=${event.user_id ?? ''}`,\n )\n return\n }\n }\n await this.#bus.dispatch(event)\n }\n\n listen(route: string, handler: (event: Event) => void | Promise<void>): () => void {\n return this.#bus.register(route, handler, {\n source: `adapter:${this.adapterName}`,\n priority: 0,\n })\n }\n\n emitLifecycle(event: BotLifecycleEvent): Promise<void> {\n return this.#emit(event)\n }\n\n get adapterName(): string {\n return this.#state.definition.name\n }\n}\n","// Framework singletons are stashed on globalThis so they survive jiti's\n// moduleCache-off re-evaluation (mioku loads plugins via jiti). Callers that\n// live in the normally-cached `mioku` dist could use a plain module-level\n// const, but the global indirection keeps things stable if a plugin ever\n// re-imports the framework through jiti.\n\nconst STORE_SYMBOL = Symbol.for(\"mioku.globalStore\");\ntype GlobalStore = Record<string, unknown>;\n\nfunction store(): GlobalStore {\n const g = globalThis as unknown as Record<symbol, GlobalStore>;\n if (!g[STORE_SYMBOL]) g[STORE_SYMBOL] = {};\n return g[STORE_SYMBOL]!;\n}\n\nexport function getOrCreate<T>(key: string, factory: () => T): T {\n const s = store();\n if (s[key] === undefined) s[key] = factory();\n return s[key] as T;\n}\n","import { getOrCreate } from '../internal/registry'\n\nimport type { Bot } from '../adapter'\n\n/** 当前已连接的全部 bot,按 `adapter:bot_id` 索引 */\nexport const connectedBots: Map<string, Bot> = getOrCreate('connected-bots', () => new Map())\n\n/** 生成 bot 在连接表中的键:`adapter:bot_id` */\nexport const connectedBotKey = (adapter: string, bot_id: string): string => `${adapter}:${bot_id}`\n\n/** 兼容旧版 API 的别名:过去的 NapCat 扩展类型现在就是通用 Bot */\nexport type ExtendedNapCat = Bot","import { AdapterRegistrationConflictError } from './context'\nimport { connectedBotKey, connectedBots } from '../compat/connected-bots'\n\nimport type { Bot, BotContext } from '../adapter'\n\n/** Bot 注册表:登记已连接的 bot,按 bot_id 查询 */\nexport class BotRegistry {\n #bots = new Map<string, { adapter: string; bot_id: string; bot: Bot }>()\n #disposers = new Map<string, () => void>()\n\n /** 登记一个 bot,返回可注销的上下文 */\n register(bot: Bot): BotContext {\n const key = connectedBotKey(bot.adapter, bot.bot_id)\n if (this.#bots.has(key)) {\n throw new AdapterRegistrationConflictError(key)\n }\n this.#bots.set(key, { adapter: bot.adapter, bot_id: bot.bot_id, bot })\n connectedBots.set(key, bot)\n const dispose = (): void => {\n this.unregister(bot.bot_id, bot.adapter)\n }\n this.#disposers.set(key, dispose)\n return {\n bot,\n unregister: dispose,\n }\n }\n\n has(key: string): boolean {\n return this.#bots.has(key)\n }\n\n unregister(bot_id: string, adapter: string): boolean {\n const key = connectedBotKey(adapter, bot_id)\n const removed = this.#bots.delete(key)\n this.#disposers.delete(key)\n connectedBots.delete(key)\n return removed\n }\n\n /** 按 bot_id 取 bot(只按 id 匹配,不限适配器) */\n pick<T extends Bot = Bot>(bot_id: string | number): T | undefined {\n const key = String(bot_id)\n for (const entry of this.#bots.values()) {\n if (entry.bot_id === key) return entry.bot as T\n }\n return undefined\n }\n\n all<T extends Bot = Bot>(): readonly T[] {\n return Array.from(this.#bots.values()).map((entry) => entry.bot as T)\n }\n\n size(): number {\n return this.#bots.size\n }\n\n clear(): void {\n this.#bots.clear()\n this.#disposers.clear()\n connectedBots.clear()\n }\n}","import type { Event } from '../adapter'\n\nexport type EventHandler<E extends Event = Event> = (event: E) => void | Promise<void>\n\nexport interface Registration {\n readonly id: number\n readonly route: string\n readonly source: string\n readonly handler: EventHandler<Event>\n readonly priority: number\n readonly order: number\n disposed: boolean\n}\n\nexport interface BusStats {\n readonly registered: number\n readonly dispatched: number\n}\n\nconst WILDCARD = '*'\n\nconst isWildcardMatch = (pattern: string, route: string): boolean => {\n if (pattern === route) return true\n if (!pattern.includes(WILDCARD)) return false\n if (pattern === WILDCARD) return true\n const prefix = pattern.slice(0, -1)\n if (!prefix.endsWith('.')) return false\n return route === prefix.slice(0, -1) || route.startsWith(prefix)\n}\n\n/**\n * 事件总线:按路由把事件分发给所有匹配的监听器。\n * 支持 `*` 通配符,同一优先级按注册顺序执行,不同优先级按数值升序。\n */\nexport class EventBus {\n #registrations: Registration[] = []\n #nextId = 1\n #nextOrder = 0\n #dispatched = 0\n #logger: ((level: 'error' | 'warn' | 'info', message: string, detail?: unknown) => void) | null = null\n\n setLogger(logger: ((level: 'error' | 'warn' | 'info', message: string, detail?: unknown) => void) | null): void {\n this.#logger = logger\n }\n\n /** 注册事件监听,返回取消注册函数 */\n register<E extends Event = Event>(\n route: string,\n handler: EventHandler<E>,\n options: { source?: string; priority?: number } = {},\n ): () => void {\n if (!route) {\n throw new Error('EventBus.register: route must be a non-empty string')\n }\n if (typeof handler !== 'function') {\n throw new Error('EventBus.register: handler must be a function')\n }\n const id = this.#nextId++\n const order = this.#nextOrder++\n const reg: Registration = {\n id,\n route,\n source: options.source ?? 'anonymous',\n handler: handler as EventHandler<Event>,\n priority: options.priority ?? 0,\n order,\n disposed: false,\n }\n this.#registrations.push(reg)\n return () => this.#unregister(id)\n }\n\n #unregister(id: number): void {\n const idx = this.#registrations.findIndex((r) => r.id === id)\n if (idx >= 0) {\n this.#registrations[idx].disposed = true\n this.#registrations.splice(idx, 1)\n }\n }\n\n clear(): void {\n for (const reg of this.#registrations) reg.disposed = true\n this.#registrations = []\n }\n\n #matching(event: Event): Registration[] {\n const matched: Registration[] = []\n for (const reg of this.#registrations) {\n if (reg.disposed) continue\n if (isWildcardMatch(reg.route, event.type)) {\n matched.push(reg)\n continue\n }\n for (const route of event.routes) {\n if (isWildcardMatch(reg.route, route)) {\n matched.push(reg)\n break\n }\n }\n }\n return matched\n }\n\n /** 派发一个事件给所有匹配的监听器,单个监听器出错不影响其他监听器 */\n async dispatch(event: Event): Promise<void> {\n const matched = this.#matching(event)\n if (matched.length === 0) return\n this.#dispatched++\n\n const priorityGroups = new Map<number, Registration[]>()\n for (const reg of matched) {\n const list = priorityGroups.get(reg.priority)\n if (list) list.push(reg)\n else priorityGroups.set(reg.priority, [reg])\n }\n const sortedPriorities = Array.from(priorityGroups.entries()).sort(([a], [b]) => a - b)\n\n for (const [, regs] of sortedPriorities) {\n regs.sort((a, b) => a.order - b.order)\n await Promise.allSettled(\n regs.map((reg) =>\n Promise.resolve()\n .then(() => reg.handler(event))\n .catch((err) => {\n this.#logger?.(\n 'error',\n `Event handler \"${reg.source}\" for route \"${reg.route}\" failed`,\n err,\n )\n }),\n ),\n )\n }\n }\n\n stats(): BusStats {\n return {\n registered: this.#registrations.length,\n dispatched: this.#dispatched,\n }\n }\n}\n","// 常用工具函数集,均从 `mioku` 顶层导出,插件可直接 import 使用。\n\nimport crypto from 'node:crypto'\nimport mriLib from 'mri'\nimport { Low } from 'lowdb'\nimport { DataFile } from 'lowdb/node'\nimport { string2argv } from 'string2argv'\n\nimport type { Message, MessageSegment } from './adapter'\nimport type { BinaryLike, BinaryToTextEncoding } from 'node:crypto'\nimport type { ConsolaInstance } from 'consola/core'\n\nexport { default as prettyMs } from 'pretty-ms'\nexport { filesize } from 'filesize'\nexport { string2argv } from 'string2argv'\nexport { default as fs } from 'node:fs'\nexport { default as path } from 'node:path'\nexport { default as dayjs } from 'dayjs'\nexport { default as dedent } from 'dedent'\nexport { mriLib as mri }\nexport { colors, stripAnsi, box, colorize } from 'consola/utils'\n\nexport const ChromeUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0.0.0'\n\nexport type Noop = () => void\nexport type AnyFunc = (...args: any[]) => any\nexport type PureObject<T = unknown> = Record<PropertyKey, T>\nexport type Arrayable<T> = T | T[]\nexport type Awaitable<T> = T | Promise<T>\nexport type Gettable<T> = T | (() => T)\n\nexport interface HasMessage {\n readonly message: Message\n}\n\nexport interface CreateCmdOptions {\n prefix?: string\n onPrefix?(): void\n}\n\n/** 解析命令行字符串:返回命令、位置参数与 `--xxx` 选项 */\nexport const createCmd = (\n cmdStr: string,\n options: CreateCmdOptions = {},\n): { cmd: string | undefined; params: string[]; options: Record<string, unknown> } => {\n const { prefix = '', onPrefix = () => undefined } = options\n const { _, ...cmdOptions } = mriLib(string2argv(cmdStr))\n const [cmd, ...params] = _ as string[]\n if (prefix) {\n if (cmd !== prefix) return { cmd: undefined, params: [], options: cmdOptions }\n if (params.length === 0) onPrefix()\n const prefixedCmd = params.shift()\n return { cmd: prefixedCmd, params, options: cmdOptions }\n }\n return { cmd, params, options: cmdOptions }\n}\n\n/** 在指定路径创建并读取一个 lowdb JSON 数据库 */\nexport const createDB = async <T extends object = object>(\n filename: string,\n options: { defaultData?: T; compress?: boolean } = {},\n): Promise<Low<T>> => {\n const { defaultData = {} as T, compress = false } = options\n const database = new Low<T>(\n new DataFile<T>(filename, {\n parse: JSON.parse,\n stringify: (data: T) => JSON.stringify(data, null, compress ? 0 : 2),\n }),\n defaultData,\n )\n await database.read()\n return database\n}\n\n/** 在插件目录下创建并读取一个 JSON 数据存储(默认 `data.json`) */\nexport const createStore = async <T extends object = object>(\n defaultData: T,\n options: {\n __dirname?: string\n importMeta?: ImportMeta\n compress?: boolean\n filename?: string\n } = {},\n): Promise<Low<T>> => {\n const { compress = false, __dirname, importMeta: meta, filename = 'data.json' } = options\n const path = await import('node:path')\n const { fileURLToPath } = await import('node:url')\n const dirname = __dirname || meta?.dirname || (meta?.url ? path.dirname(fileURLToPath(meta.url)) : '')\n if (!dirname) throw new Error('createStore: options.__dirname or options.meta must be provided')\n const filePath = path.join(dirname, filename)\n const database = new Low<T>(\n new DataFile<T>(filePath, {\n parse: JSON.parse,\n stringify: (data: T) => JSON.stringify(data, null, compress ? 0 : 2),\n }),\n defaultData,\n )\n await database.read()\n await database.write()\n return database\n}\n\nexport const md5 = (text: BinaryLike, encoding: BinaryToTextEncoding | 'buffer' = 'hex'): string | Buffer => {\n const hash = crypto.createHash('md5').update(text)\n if (encoding === 'buffer') return hash.digest()\n return hash.digest(encoding)\n}\n\nexport const unique = <T>(array: T[]): T[] => Array.from(new Set(array))\n\nexport const toArray = <T>(value: T | T[]): T[] => (Array.isArray(value) ? value : [value])\n\nexport const wait = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms))\n\nexport const localeDate = (ts: number | string | Date = Date.now(), options: { locale?: string; timeZone?: string } = {}): string => {\n const { locale = 'zh-CN', timeZone = 'Asia/Shanghai' } = options\n const today = ts instanceof Date ? ts : new Date(ts)\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n timeZone,\n }).format(today)\n}\n\nexport const localeTime = (\n ts: number | string | Date = Date.now(),\n options: { locale?: string; timeZone?: string; seconds?: boolean } = {},\n): string => {\n const { locale = 'zh-CN', timeZone = 'Asia/Shanghai', seconds = true } = options\n const now = ts instanceof Date ? ts : new Date(ts)\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: '2-digit',\n day: '2-digit',\n hour: '2-digit',\n hourCycle: 'h23',\n minute: '2-digit',\n second: seconds ? '2-digit' : undefined,\n timeZone,\n }).format(now)\n}\n\nexport const randomInt = (min: number, max: number, ...hashArgs: unknown[]): number => {\n if (min > max) throw new Error('min must be less than or equal to max')\n if (hashArgs.length === 0) return Math.floor(Math.random() * (max - min + 1)) + min\n const sortedArgs = hashArgs.slice().sort((a, b) => {\n if (typeof a === 'number' && typeof b === 'number') return a - b\n return JSON.stringify(a).localeCompare(JSON.stringify(b))\n })\n const hash = md5(JSON.stringify(sortedArgs))\n const hashText = typeof hash === 'string' ? hash : hash.toString('hex')\n const hashValue = Number.parseInt(hashText.slice(0, 8), 16)\n const range = max - min + 1\n return (((hashValue % range) + range) % range) + min\n}\n\nexport const randomItem = <T>(array: readonly T[], ...hashArgs: unknown[]): T => {\n if (!Array.isArray(array) || !array.length) throw new Error('randomItem: 参数必须是数组,且不能为空')\n return array[randomInt(0, array.length - 1, ...hashArgs)]\n}\n\nexport const randomItems = <T>(array: readonly T[], count: number, ...hashArgs: unknown[]): T[] => {\n if (!Array.isArray(array) || !array.length) throw new Error('randomItems: 参数必须是数组,且不能为空')\n if (count < 0) throw new Error('randomItems: count 必须为非负整数')\n if (count === 0) return []\n if (count > array.length) throw new Error(`randomItems: 要选择的数量 (${count}) 超过了数组长度 (${array.length})`)\n if (count === array.length) return [...array]\n const indices = Array.from({ length: array.length }, (_, i) => i)\n const selected: number[] = []\n for (let i = 0; i < count; i++) {\n const remainingCount = indices.length - i\n const randomIdx = randomInt(0, remainingCount - 1, ...hashArgs, `select_${i}`)\n selected.push(indices[randomIdx])\n const lastIdx = indices.length - 1 - i\n ;[indices[randomIdx], indices[lastIdx]] = [indices[lastIdx], indices[randomIdx]]\n }\n const isString = (v: unknown): v is string => typeof v === 'string'\n const hasString = array.some(isString)\n const items = selected.map((idx) => array[idx])\n return hasString ? items.sort((p, n) => (isString(p) && isString(n) ? p.localeCompare(n) : 0)) : items\n}\n\nexport const randomId = (): string => Math.random().toString(16).slice(2, 8).toUpperCase()\n\nexport const uuid = (): string => {\n const rand = (length = 4): string => Math.random().toString(16).substring(2, length + 2)\n return `${rand(8)}-${rand(4)}-${rand(4)}-${rand(4)}-${rand(12)}`\n}\n\nexport const clamp = (n: number, min: number, max: number): number => Math.min(max, Math.max(min, n))\n\nexport const noNullish = <T>(val: T | null | undefined): val is T => val !== null && val !== undefined\n\nexport const isDefined = <T = unknown>(val?: T): val is T => typeof val !== 'undefined'\n\nexport const isFunction = <T extends AnyFunc = AnyFunc>(val: unknown): val is T => typeof val === 'function'\n\nexport const isNumber = (val: unknown): val is number => typeof val === 'number'\n\nexport const isBoolean = (val: unknown): val is boolean => typeof val === 'boolean'\n\nexport const isString = (val: unknown): val is string => typeof val === 'string'\n\nexport const isObject = (val: unknown): val is Record<string, unknown> =>\n Object.prototype.toString.call(val) === '[object Object]'\n\nexport const localNum = (num: number, locale = 'zh-CN'): string => num.toLocaleString(locale)\n\nexport const base64Encode = (str: string | number | Buffer): string => Buffer.from(str.toString()).toString('base64')\n\nexport const base64Decode = (str: string, type: 'buffer' | BufferEncoding = 'utf8'): string | Buffer => {\n if (type === 'buffer') return Buffer.from(str, 'base64')\n return Buffer.from(str, 'base64').toString(type)\n}\n\nexport const qs = (obj: Record<number | string, unknown>): string => new URLSearchParams(obj as Record<string, string>).toString()\n\nexport const stringifyError = (error: unknown): string => {\n if (typeof error === 'object' && error !== null) {\n const e = error as { constructor?: { name?: string }; message?: string; stack?: string }\n const errorType = e.constructor?.name ?? '未知错误'\n const errorMessage = e.message ?? '[无报错信息]'\n if (e.stack) return `${errorType}: ${errorMessage}\\n${e.stack}`\n return `${errorType}: ${errorMessage}`\n }\n return String(error)\n}\n\nexport const formatDuration = (ms: number): string => {\n const seconds = Math.floor(ms / 1000)\n const minutes = Math.floor(seconds / 60)\n const hours = Math.floor(minutes / 60)\n const days = Math.floor(hours / 24)\n if (days > 0) return `${days}天${hours % 24}小时`\n if (hours > 0) return `${hours}小时${minutes % 60}分钟`\n if (minutes > 0) return `${minutes}分钟${seconds % 60}秒`\n return `${seconds}秒`\n}\n\nexport const getTerminalInput = (inputTip = '请输入'): Promise<string> =>\n new Promise((resolve) => {\n if (inputTip) console.log(inputTip)\n const getInput = (): void => {\n process.stdin.once('data', (e) => {\n const input = e.toString().trim()\n if (input) {\n resolve(input)\n return\n }\n getInput()\n })\n }\n getInput()\n })\n\nexport const getGTk = (pskey: string): number => {\n let gkt = 5381\n for (let i = 0, len = pskey.length; i < len; ++i) {\n gkt += (gkt << 5) + pskey.charCodeAt(i)\n }\n return gkt & 0x7fffffff\n}\n\nexport type MatchHandler<T extends HasMessage> = (matches: RegExpMatchArray, event: T) => unknown | Promise<unknown>\n\nexport type MatchValue = string | number | boolean | Message | MessageSegment | readonly (string | MessageSegment)[]\n\n/**\n * 关键词匹配路由:pattern 的键支持正则(`/.../`)、通配符(`*`)与纯文本,\n * 命中后执行对应的处理函数或直接回复静态内容。\n */\nexport const match = async <T extends HasMessage>(\n event: T,\n pattern: Record<string, MatchHandler<T> | MatchValue>,\n quote: boolean = true,\n): Promise<{ message_id: string } | null> => {\n const inputText = event.message.text()\n for (const [key, value] of Object.entries(pattern)) {\n let isMatched = false\n let matches: RegExpMatchArray | null = null\n const isRegExp = key.startsWith('/') && key.endsWith('/')\n const hasWildcard = key.includes('*')\n if (isRegExp) {\n try {\n const regex = new RegExp(key.slice(1, -1))\n matches = inputText.match(regex)\n if (matches) isMatched = true\n } catch (err) {\n throw new Error(`无效的正则表达式: ${key}`, { cause: err })\n }\n } else if (hasWildcard) {\n const regex = new RegExp(`^${key.replace(/\\./g, '\\\\.').replace(/\\*/g, '.*')}$`)\n matches = inputText.match(regex)\n if (matches) isMatched = true\n } else if (key === inputText) {\n isMatched = true\n }\n if (!isMatched) continue\n const result = typeof value === 'function' ? await value(matches as RegExpMatchArray, event) : value\n if (result) {\n const reply = (event as unknown as { reply?: (content: unknown, quote?: boolean) => Promise<{ message_id: string }> }).reply\n if (reply) return await reply(result, quote)\n }\n }\n return null\n}\n\nexport const text = (source: HasMessage | Message, options: { trim?: boolean | 'whole' | 'each' } = {}): string => {\n const { trim = true } = options\n const message = getMessage(source)\n const texts = message\n .filterByType('text')\n .map((seg) => (typeof seg.data.text === 'string' ? seg.data.text : ''))\n if (trim === 'whole') return texts.join('').trim()\n if (trim === 'each') return texts.map((t) => t.trim()).join('')\n if (trim === true) return texts.map((t) => t.trim()).join('')\n return texts.join('')\n}\n\nexport const find = <T extends Message['length'] extends 0 ? never : Message[number]>(\n source: HasMessage | Message,\n type: string,\n): T | undefined => {\n const message = getMessage(source)\n return message.find((seg) => seg.type === type) as T | undefined\n}\n\nexport const filter = <T extends Message['length'] extends 0 ? never : Message[number]>(\n source: HasMessage | Message,\n type: string,\n): T[] => {\n const message = getMessage(source)\n return message.filter((seg) => seg.type === type) as T[]\n}\n\nexport { type ConsolaInstance }\n\nconst getMessage = (source: HasMessage | Message): Message => {\n if (Array.isArray(source) && typeof (source as Message).text === 'function') return source as Message\n return (source as HasMessage).message\n}\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport util from 'node:util'\nimport { colors } from 'consola/utils'\nimport { createConsola, LogLevels } from 'consola/core'\nimport { BOT_CWD, readMiokuConfig, updateMiokuConfig } from '../config'\n\nimport type { Logger, LogLevel } from './types'\nimport type { ConsolaInstance } from 'consola/core'\n\n/** consola 数字级别对应的名称与颜色 */\nconst LEVEL_MAP: Readonly<Record<number, { name: string; color: 'red' | 'yellow' | 'white' | 'green' | 'blue' | 'gray' }>> = {\n 0: { name: 'ERROR', color: 'red' },\n 1: { name: 'WARN', color: 'yellow' },\n 2: { name: 'LOG', color: 'white' },\n 3: { name: 'INFO', color: 'green' },\n 4: { name: 'DEBUG', color: 'blue' },\n 5: { name: 'TRACE', color: 'gray' },\n}\n\nlet cachedRoot: ConsolaInstance | null = null\nlet cachedRootLevel: LogLevel = 'info'\n\n/** 惰性创建根 logger,日志级别取自 mioku 配置 */\nconst resolveRoot = (): ConsolaInstance => {\n if (cachedRoot) return cachedRoot\n let level: LogLevel = 'info'\n try {\n level = readMiokuConfig().log_level ?? 'info'\n } catch {\n level = 'info'\n }\n cachedRootLevel = level\n cachedRoot = createConsola({\n level: LogLevels[level] ?? LogLevels.info,\n defaults: { tag: 'mioku' },\n formatOptions: { colors: true, compact: true, date: true },\n })\n return cachedRoot\n}\n\n/** 本次运行的日志文件路径:logs/ 下按启动时间命名 */\nconst getLogFile = (): string => {\n const cwd = BOT_CWD.value\n const dir = path.join(cwd, 'logs')\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)\n return path.join(dir, `${stamp}.log`)\n}\n\nconst ensureFile = (file: string): void => {\n if (!fs.existsSync(file)) {\n fs.mkdirSync(path.dirname(file), { recursive: true })\n fs.writeFileSync(file, '')\n }\n}\n\nconst renderMessage = (args: unknown[]): string =>\n args\n .map((arg) => (typeof arg === 'string' ? arg : util.inspect(arg, { colors: false, depth: 4 })))\n .join(' ')\n\n/** 渲染控制台输出的彩色日志行 */\nconst renderColored = (level: number, tag: string | undefined, args: unknown[]): string => {\n const time = colors.gray(`[${new Date().toLocaleTimeString('zh-CN')}]`)\n const meta = LEVEL_MAP[level] ?? LEVEL_MAP[3]\n const levelText = colors.bold(colors[meta.color](meta.name))\n const tagText = tag ? colors.dim(`[${tag}]`) : ''\n const message = renderMessage(args)\n return `${time} ${levelText} ${tagText} ${message}`\n}\n\n/** 把日志行追加写入文件,失败时静默忽略 */\nconst writeFile = (level: number, tag: string | undefined, args: unknown[], file: string): void => {\n try {\n ensureFile(file)\n const iso = new Date().toISOString()\n const meta = LEVEL_MAP[level] ?? LEVEL_MAP[3]\n const prefix = `[${iso}] [${meta.name}]${tag ? ` [${tag}]` : ''}`\n fs.appendFileSync(file, `${prefix} ${renderMessage(args)}\\n`)\n } catch {\n // best-effort logging, swallow file errors\n }\n}\n\n/** 写入文件并按级别输出到对应的标准流 */\nconst dispatch = (\n level: number,\n tag: string | undefined,\n args: unknown[],\n file: string,\n): void => {\n writeFile(level, tag, args, file)\n const line = renderColored(level, tag, args)\n if (level === LogLevels.error) console.error(line)\n else if (level === LogLevels.warn) console.warn(line)\n else if (level === LogLevels.log) console.log(line)\n else if (level === LogLevels.info) console.info(line)\n else console.debug(line)\n}\n\n/** 带标签与作用域的 logger 实现 */\nclass ScopedLogger implements Logger {\n readonly #parent: ConsolaInstance | null\n readonly #tag: string | undefined\n readonly #scope: Readonly<Record<string, unknown>>\n readonly #file: string\n readonly #threshold: number\n\n constructor(options: {\n parent: ConsolaInstance | null\n tag: string | undefined\n scope: Record<string, unknown>\n file: string\n threshold: number\n }) {\n this.#parent = options.parent\n this.#tag = options.tag\n this.#scope = options.scope\n this.#file = options.file\n this.#threshold = options.threshold\n }\n\n get level(): LogLevel {\n if (!this.#parent) return 'info'\n const lv = this.#parent.level\n for (const [k, v] of Object.entries(LogLevels)) {\n if (v === lv) return k as LogLevel\n }\n return 'info'\n }\n\n #tagWithScope(): string {\n const tags = [this.#tag, ...Object.entries(this.#scope).map(([k, v]) => `${k}:${String(v)}`)].filter(Boolean)\n return tags.join(':')\n }\n\n #log(level: number, args: unknown[]): void {\n if (level > this.#threshold) return\n if (this.#parent && level > this.#parent.level) return\n dispatch(level, this.#tagWithScope(), args, this.#file)\n }\n\n error(...args: unknown[]): void {\n this.#log(LogLevels.error, args)\n }\n\n warn(...args: unknown[]): void {\n this.#log(LogLevels.warn, args)\n }\n\n log(...args: unknown[]): void {\n this.#log(LogLevels.log, args)\n }\n\n info(...args: unknown[]): void {\n this.#log(LogLevels.info, args)\n }\n\n debug(...args: unknown[]): void {\n this.#log(LogLevels.debug, args)\n }\n\n trace(...args: unknown[]): void {\n this.#log(LogLevels.trace, args)\n }\n\n withTag(tag: string): Logger {\n const merged = this.#tag ? `${this.#tag}:${tag}` : tag\n return new ScopedLogger({\n parent: this.#parent,\n tag: merged,\n scope: this.#scope,\n file: this.#file,\n threshold: this.#threshold,\n })\n }\n\n child(scope: Record<string, unknown>): Logger {\n return new ScopedLogger({\n parent: this.#parent,\n tag: this.#tag,\n scope: { ...this.#scope, ...scope },\n file: this.#file,\n threshold: this.#threshold,\n })\n }\n}\n\n/** 创建挂在根 logger 下的日志器,输出统一落盘到本次运行的日志文件 */\nexport const createMiokuLogger = (options: { tag?: string; level?: LogLevel; scope?: Record<string, unknown> } = {}): Logger => {\n const root = resolveRoot()\n const file = getLogFile()\n const threshold = LogLevels[(options.level ?? cachedRootLevel) as LogLevel] ?? LogLevels.info\n return new ScopedLogger({\n parent: root,\n tag: options.tag,\n scope: options.scope ?? {},\n file,\n threshold,\n })\n}\n\n/** 全局根 logger */\nexport const rootLogger: Logger = createMiokuLogger()\n\n/** 运行时调整日志级别,并写回 mioku 配置 */\nexport const applyLogLevel = (level: LogLevel): void => {\n cachedRootLevel = level\n if (cachedRoot) {\n cachedRoot.level = LogLevels[level] ?? LogLevels.info\n }\n try {\n updateMiokuConfig((config) => {\n config.log_level = level\n }).then()\n } catch {\n // config update may fail in non-mutating contexts; ignore.\n }\n}\n\nexport type { Logger, LogLevel }","import { wait } from './utils'\nimport { rootLogger } from './logger'\n\nimport type { Bot } from './adapter'\nimport type { MessageInput } from './adapter'\nimport type { MessageTarget } from './adapter'\n\n/** 群发通知的选项 */\nexport interface NoticeOptions {\n /** 相邻两个目标之间的发送间隔(毫秒),默认 1000 */\n readonly delay?: number\n /** 统一覆盖发送目标,默认按名单逐个生成 */\n readonly target?: MessageTarget\n}\n\n/** 通过指定 bot 发送一条消息 */\nexport const sendMessage = async (bot: Bot, target: MessageTarget, message: MessageInput): Promise<unknown> => {\n return await bot.sendMessage(target, message)\n}\n\n/** 逐目标群发:每个目标依次尝试各 bot 直到成功,目标之间间隔 delay 毫秒 */\nconst notifyAll = async (\n bots: readonly Bot[],\n targets: readonly MessageTarget[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n const delay = options.delay ?? 1000\n for (const target of targets) {\n let sent = false\n for (const bot of bots) {\n try {\n await bot.sendMessage(target, message)\n sent = true\n break\n } catch {\n // 跳过失败的 bot,尝试下一个\n }\n }\n if (!sent) {\n rootLogger.warn(`通知目标 ${JSON.stringify(target)} 失败`)\n }\n await wait(delay)\n }\n}\n\n/** 向多个群发送同一条消息 */\nexport const noticeGroups = async (\n bots: readonly Bot[],\n groupIds: readonly (string | number)[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n await notifyAll(\n bots,\n groupIds.map((group_id) => ({ type: 'group', group_id })),\n message,\n options,\n )\n}\n\n/** 向多个好友私聊发送同一条消息 */\nexport const noticeFriends = async (\n bots: readonly Bot[],\n userIds: readonly (string | number)[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n await notifyAll(\n bots,\n userIds.map((user_id) => ({ type: 'private', user_id })),\n message,\n options,\n )\n}\n\n/** 通知所有 owner,可通过 options.target 统一改发到别的目标 */\nexport const noticeOwners = async (\n bots: readonly Bot[],\n owners: readonly string[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n await notifyAll(\n bots,\n owners.map((user_id) => options.target ?? ({ type: 'private', user_id } as MessageTarget)),\n message,\n options,\n )\n}\n\n/** 通知所有管理员,行为与 noticeOwners 一致 */\nexport const noticeAdmins = async (\n bots: readonly Bot[],\n admins: readonly string[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n return noticeOwners(bots, admins, message, options)\n}","import { getOrCreate } from '../internal/registry'\n\nconst services = getOrCreate<Record<string, unknown>>('services-registry', () => ({}))\n\n/** 按名称索引的服务注册表 */\nexport interface MiokuServices {\n [key: string]: unknown\n}\n\n/** 全局服务注册表实例,已加载的服务都注册在这里 */\nexport const servicesRegistry = services\n\n/** 按名称取服务,不存在时返回 undefined */\nexport const getService = <T = unknown>(name: string): T | undefined => services[name] as T | undefined\n\n/**\n * 注册服务并返回移除该服务的函数。\n * cover 为 false 且同名服务已存在时跳过注册。\n */\nexport const setService = <T = unknown>(name: string, value: T, cover: boolean = true): () => void => {\n if (cover || !services[name]) {\n services[name] = value\n }\n return () => {\n delete services[name]\n }\n}\n\n/** setService 的别名 */\nexport const addService = <T = unknown>(name: string, value: T, cover: boolean = true): (() => void) => {\n return setService(name, value, cover)\n}\n\n/** 惰性创建服务的工厂函数 */\nexport type ServiceFactory<T> = () => T","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { pathToFileURL } from \"node:url\";\n\nexport interface DiscoveredModule {\n name: string;\n path: string;\n}\n\nexport async function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function resolveRealpath(p: string): Promise<string> {\n try {\n return await fs.realpath(p);\n } catch {\n return p;\n }\n}\n\nexport function toImportPath(filePath: string): string {\n if (process.platform === \"win32\") {\n return pathToFileURL(filePath).href;\n }\n return filePath;\n}\n\nexport async function scanLocalDir(dir: string): Promise<DiscoveredModule[]> {\n const results: DiscoveredModule[] = [];\n if (!(await pathExists(dir))) return results;\n\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const entryPath = path.join(dir, entry.name);\n try {\n const stat = await fs.stat(entryPath);\n if (!stat.isDirectory()) continue;\n } catch {\n continue;\n }\n results.push({ name: entry.name, path: await resolveRealpath(entryPath) });\n }\n return results;\n}\n\nexport async function scanNodeModules(prefix: string): Promise<DiscoveredModule[]> {\n const results: DiscoveredModule[] = [];\n const nodeModulesPath = path.resolve(process.cwd(), \"node_modules\");\n if (!(await pathExists(nodeModulesPath))) return results;\n\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(nodeModulesPath, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n if (!entry.name.startsWith(prefix)) continue;\n const name = entry.name.slice(prefix.length);\n const fullPath = path.join(nodeModulesPath, entry.name);\n results.push({ name, path: await resolveRealpath(fullPath) });\n }\n return results;\n}","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport type { MiokuContext } from \"../runtime/mioku-context\";\nimport type {\n MiokuRuntimeConfig,\n PackageJsonLike,\n ServiceMetadata,\n MiokuService,\n} from \"../types\";\nimport { rootLogger as logger } from \"../logger\";\nimport {\n scanLocalDir,\n scanNodeModules,\n pathExists,\n toImportPath,\n} from \"../internal/module-scanner\";\nimport { getOrCreate } from \"../internal/registry\";\nimport { servicesRegistry } from \"./registry\";\n\nconst SERVICE_PREFIX = \"mioku-service-\";\n\n/** 服务管理器:扫描、加载本地与 npm 服务,并把服务 API 暴露到注册表 */\nexport class ServiceManager {\n private serviceMetadata = new Map<string, ServiceMetadata>();\n private loaded = new Map<string, MiokuService>();\n\n static getInstance(): ServiceManager {\n return getOrCreate(\"service-manager\", () => new ServiceManager());\n }\n\n /** 扫描本地 services/ 目录与 node_modules 下的 mioku-service-* 包,返回全部服务元数据 */\n async discoverServices(miokuConfig: MiokuRuntimeConfig = {}): Promise<ServiceMetadata[]> {\n const servicesDir = miokuConfig.services_dir\n ? path.resolve(process.cwd(), miokuConfig.services_dir)\n : path.resolve(process.cwd(), \"services\");\n\n this.serviceMetadata.clear();\n\n if (existsSync(servicesDir)) {\n const local = await scanLocalDir(servicesDir);\n for (const { name, path: p } of local) {\n const metadata = await this.loadServiceMetadata(name, p);\n if (metadata) this.serviceMetadata.set(name, metadata);\n }\n } else {\n mkdirSync(servicesDir, { recursive: true });\n }\n\n const external = await scanNodeModules(SERVICE_PREFIX);\n for (const { name, path: p } of external) {\n const metadata = await this.loadServiceMetadata(name, p);\n if (metadata) this.serviceMetadata.set(name, metadata);\n }\n\n logger.info(`o.O 发现了 ${this.serviceMetadata.size} 个服务`);\n return [...this.serviceMetadata.values()];\n }\n\n private async loadServiceMetadata(\n name: string,\n servicePath: string,\n ): Promise<ServiceMetadata | null> {\n const packageJsonPath = path.join(servicePath, \"package.json\");\n if (!(await pathExists(packageJsonPath))) return null;\n\n try {\n const packageJson: PackageJsonLike = JSON.parse(\n await fs.readFile(packageJsonPath, \"utf-8\"),\n );\n return {\n name,\n version: packageJson.version ?? \"0.0.0\",\n description: packageJson.description,\n path: servicePath,\n packageJson,\n };\n } catch (error) {\n logger.warn(`[service-manager] 解析服务 ${name} 失败: ${error}`);\n return null;\n }\n }\n\n getMetadata(name: string): ServiceMetadata | undefined {\n return this.serviceMetadata.get(name);\n }\n\n getAllMetadata(): ServiceMetadata[] {\n return [...this.serviceMetadata.values()];\n }\n\n /** 依次加载所有已发现的服务,成功的会注册进服务注册表 */\n async loadAllServices(ctx?: MiokuContext): Promise<void> {\n const all = [...this.serviceMetadata.values()];\n logger.info(`O.o 准备加载 ${all.length} 个服务...`);\n let loadedCount = 0;\n for (const metadata of all) {\n if (await this.loadService(metadata, ctx)) loadedCount++;\n }\n logger.info(`O.o 服务加载完成: ${loadedCount}/${all.length} 个就绪`);\n }\n\n private async loadService(metadata: ServiceMetadata, ctx?: MiokuContext): Promise<boolean> {\n try {\n const tsEntry = path.join(metadata.path, \"index.ts\");\n const jsEntry = path.join(metadata.path, \"index.js\");\n const entry = (await pathExists(tsEntry))\n ? tsEntry\n : (await pathExists(jsEntry))\n ? jsEntry\n : null;\n if (!entry) {\n logger.error(`[service-manager] 服务 ${metadata.name} 入口丢失`);\n return false;\n }\n\n const serviceModule = await import(toImportPath(entry));\n const service: MiokuService = serviceModule.default ?? serviceModule;\n if (!service || typeof service.init !== \"function\") {\n logger.warn(`[service-manager] 服务 ${metadata.name} 无效:缺少 init()`);\n return false;\n }\n\n await service.init();\n servicesRegistry[metadata.name] = service.api;\n this.loaded.set(metadata.name, service);\n return true;\n } catch (error) {\n logger.error(`[service-manager] 加载服务 ${metadata.name} 失败: ${error}`);\n return false;\n }\n }\n\n /** 按加载的相反顺序卸载全部服务,并从注册表移除 */\n async disposeAll(): Promise<void> {\n const entries = Array.from(this.loaded.entries()).reverse();\n this.loaded.clear();\n for (const [name, service] of entries) {\n try {\n await service.dispose?.();\n } catch (error) {\n logger.warn(`[service-manager] 服务 ${name} 卸载失败: ${error}`);\n }\n delete servicesRegistry[name];\n }\n }\n\n async reset(): Promise<void> {\n await this.disposeAll();\n this.serviceMetadata.clear();\n }\n}\n\nexport default ServiceManager.getInstance();","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport { rootLogger as logger } from \"../logger\";\n\nconst SERVICE_CONFIG_ROOT = \"service\";\n\n/** 服务配置目录:`config/service/<serviceName>/` */\nfunction resolveConfigDir(serviceName: string): string {\n return path.join(process.cwd(), \"config\", SERVICE_CONFIG_ROOT, serviceName);\n}\n\nfunction resolveConfigPath(serviceName: string, configName: string): string {\n return path.join(resolveConfigDir(serviceName), `${configName}.json`);\n}\n\nfunction ensureDir(serviceName: string): void {\n const dir = resolveConfigDir(serviceName);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\n/** 注册服务配置:文件不存在时把 defaults 写入磁盘 */\nexport async function registerServiceConfig(\n serviceName: string,\n configName: string,\n defaults: Record<string, unknown>,\n): Promise<void> {\n ensureDir(serviceName);\n const configPath = resolveConfigPath(serviceName, configName);\n if (!existsSync(configPath)) {\n await fs.writeFile(configPath, JSON.stringify(defaults, null, 2), \"utf-8\");\n }\n}\n\n/** 读取服务配置,文件不存在或解析失败时返回空对象 */\nexport async function getServiceConfig(\n serviceName: string,\n configName: string,\n): Promise<Record<string, unknown>> {\n const configPath = resolveConfigPath(serviceName, configName);\n try {\n return JSON.parse(await fs.readFile(configPath, \"utf-8\"));\n } catch (error) {\n if (!existsSync(configPath)) return {};\n logger.warn(`[service-config] 读取 ${serviceName}/${configName} 失败: ${error}`);\n return {};\n }\n}\n\n/** 覆盖写入服务配置 */\nexport async function updateServiceConfig(\n serviceName: string,\n configName: string,\n value: Record<string, unknown>,\n): Promise<void> {\n ensureDir(serviceName);\n await fs.writeFile(\n resolveConfigPath(serviceName, configName),\n JSON.stringify(value, null, 2),\n \"utf-8\",\n );\n}\n\n/** 读取服务的全部配置文件,按配置名索引 */\nexport async function getServiceConfigs(\n serviceName: string,\n): Promise<Record<string, Record<string, unknown>>> {\n const dir = resolveConfigDir(serviceName);\n if (!existsSync(dir)) return {};\n\n const result: Record<string, Record<string, unknown>> = {};\n const files = (await fs.readdir(dir)).filter((name) => name.endsWith(\".json\"));\n for (const file of files) {\n try {\n result[path.basename(file, \".json\")] = JSON.parse(\n await fs.readFile(path.join(dir, file), \"utf-8\"),\n );\n } catch (error) {\n logger.warn(`[service-config] 读取 ${serviceName}/${file} 失败: ${error}`);\n }\n }\n return result;\n}\n\n/** 删除服务配置,文件不存在时返回 false */\nexport async function deleteServiceConfig(\n serviceName: string,\n configName: string,\n): Promise<boolean> {\n const configPath = resolveConfigPath(serviceName, configName);\n if (!existsSync(configPath)) return false;\n await fs.unlink(configPath);\n return true;\n}\n","import type { MiokuContext } from \"../runtime/mioku-context\";\n\n/** 服务引用的类型安全句柄,泛型参数对应该服务的实际类型 */\nexport interface ServiceRef<T> {\n readonly id: string;\n}\n\n/** 声明一个服务引用,只记录 id,不查询注册表 */\nexport function defineService<T>(id: string): ServiceRef<T> {\n return { id };\n}\n\n/** 从上下文取服务,未注册时返回 undefined */\nexport function getService<T>(\n ctx: MiokuContext,\n ref: ServiceRef<T>,\n): T | undefined {\n return ctx.services[ref.id] as T | undefined;\n}\n\n/** 从上下文取服务,未注册时抛错 */\nexport function requireService<T>(\n ctx: MiokuContext,\n ref: ServiceRef<T>,\n): T {\n const svc = ctx.services[ref.id] as T | undefined;\n if (svc === undefined) {\n throw new Error(\n `[mioku] required service \"${ref.id}\" is not available`,\n );\n }\n return svc;\n}\n\n/** 判断服务是否已注册 */\nexport function hasService<T>(\n ctx: MiokuContext,\n ref: ServiceRef<T>,\n): boolean {\n return ctx.services[ref.id] !== undefined;\n}","import type {\n AIService,\n ConfigService,\n ScreenshotService,\n HelpService,\n} from \"../types\";\nimport { defineService } from \"./define\";\n\n/** 框架内置服务的引用集合 */\nexport const Services = {\n AI: defineService<AIService>(\"ai\"),\n Config: defineService<ConfigService>(\"config\"),\n Screenshot: defineService<ScreenshotService>(\"screenshot\"),\n Help: defineService<HelpService>(\"help\"),\n} as const;\n\n/** 全部内置服务引用的联合类型 */\nexport type BuiltinServiceRef =\n | typeof Services.AI\n | typeof Services.Config\n | typeof Services.Screenshot\n | typeof Services.Help;","import { isAdmin as isConfiguredAdmin, isOwner as isConfiguredOwner } from '../config'\nimport nodeCron from 'node-cron'\nimport {\n createCmd as createCmdUtil,\n createDB as createDBUtil,\n createStore as createStoreUtil,\n match as matchMessage,\n text as extractText,\n type CreateCmdOptions,\n type HasMessage,\n} from '../utils'\nimport * as utilsExports from '../utils'\nimport { segment } from '../adapter'\nimport {\n noticeAdmins as noticeAdminsAction,\n noticeFriends as noticeFriendsAction,\n noticeGroups as noticeGroupsAction,\n noticeOwners as noticeOwnersAction,\n} from '../actions'\nimport { addService as registerService, servicesRegistry } from '../services'\n\nimport type { Adapter, AdapterBotMap } from '../adapter'\nimport type { Bot } from '../adapter'\nimport type { Driver } from '../driver'\nimport type { Event, MessageEvent, MetaEvent, NoticeEvent, RequestEvent } from '../adapter'\nimport type { BotLifecycleEvent } from '../adapter'\nimport type { Logger } from '../logger'\nimport type { MiokuConfig } from '../config'\nimport type { EventBus } from './bus'\nimport type { CronHandler, PluginCleanup, ScheduledTask } from '../plugin'\nimport type { TaskContext } from 'node-cron'\nimport type { CapabilityRegistry } from '../adapter'\nimport type { BotRegistry } from './bots'\nimport type { Message, MessageInput } from '../adapter'\n\n/** 插件管理器:插件列表查询与运行时启停 */\nexport interface PluginManager {\n list(): Array<{ name: string; type: 'builtin' | 'external'; version?: string }>\n localPlugins(): string[]\n enable(name: string): Promise<void>\n disable(name: string): Promise<void>\n reload(name: string): Promise<void>\n}\n\nexport interface ContextOptions {\n readonly pluginName: string\n readonly bus: EventBus\n readonly bots: BotRegistry\n readonly driver: Driver\n readonly capabilities: CapabilityRegistry\n readonly config: MiokuConfig\n readonly logger: Logger\n readonly priority: number\n readonly getAdapter: <T extends Adapter = Adapter>(name: string) => T | undefined\n readonly listAdapters: () => readonly Adapter[]\n readonly onUpdateConfig: (updater: (config: MiokuConfig) => void | Promise<void>) => Promise<void>\n readonly pluginManager: PluginManager\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/** 从事件对象中提取发送者 id(支持裸 id / user_id / sender.user_id) */\nexport const toUserId = (value: unknown): string | undefined => {\n if (typeof value === 'number' || typeof value === 'string' || typeof value === 'bigint') {\n return String(value)\n }\n if (isObject(value)) {\n if ('user_id' in value) return toUserId((value as { user_id: unknown }).user_id)\n if ('sender' in value) {\n const sender = (value as { sender: unknown }).sender\n if (isObject(sender) && 'user_id' in sender) return toUserId((sender as { user_id: unknown }).user_id)\n }\n }\n return undefined\n}\n\nexport const isEventOwner = (event: unknown): boolean => {\n const id = toUserId(event)\n if (!id) return false\n return isConfiguredOwner(id)\n}\n\nexport const isEventAdmin = (event: unknown): boolean => {\n const id = toUserId(event)\n if (!id) return false\n return isConfiguredAdmin(id)\n}\n\nexport const isEventOwnerOrAdmin = (event: unknown): boolean => isEventOwner(event) || isEventAdmin(event)\nexport const hasEventRight = (event: unknown): boolean => isEventOwnerOrAdmin(event)\n\ntype SemanticRoute<R extends string> = R extends `${string}:${infer Rest}` ? Rest : R\n\ntype EventKindOfSemanticRoute<R extends string> = R extends `message${string}`\n ? MessageEvent\n : R extends `notice${string}`\n ? NoticeEvent\n : R extends `request${string}`\n ? RequestEvent\n : R extends `meta_event${string}`\n ? MetaEvent\n : Event\n\nexport type EventKindOfRoute<R extends string> = EventKindOfSemanticRoute<SemanticRoute<R>>\n\ntype AdapterBotOf<Name extends string> = Name extends keyof AdapterBotMap\n ? AdapterBotMap[Name] extends Bot\n ? AdapterBotMap[Name]\n : Bot\n : Bot\n\ntype BotOfRoute<R extends string> = R extends `${infer Adapter}:${string}` ? AdapterBotOf<Adapter> : Bot\n\ntype BindRouteBot<E, B extends Bot> = E extends { bot: Bot; self_id: string }\n ? Omit<E, 'bot' | 'self_id'> & { bot: B; self_id: B['bot_id'] }\n : E\n\ntype RouteEventOf<R extends string> = BindRouteBot<EventKindOfRoute<R>, BotOfRoute<R>>\n\nexport type RouteEvent<R extends string | readonly string[]> = R extends readonly string[]\n ? RouteEventOf<R[number]>\n : RouteEventOf<Extract<R, string>>\n\nconst CTX_UTILS = {\n localeDate: utilsExports.localeDate,\n localeTime: utilsExports.localeTime,\n randomInt: utilsExports.randomInt,\n randomItem: utilsExports.randomItem,\n randomItems: utilsExports.randomItems,\n randomId: utilsExports.randomId,\n uuid: utilsExports.uuid,\n wait: utilsExports.wait,\n toArray: utilsExports.toArray,\n unique: utilsExports.unique,\n clamp: utilsExports.clamp,\n noNullish: utilsExports.noNullish,\n isDefined: utilsExports.isDefined,\n isFunction: utilsExports.isFunction,\n isNumber: utilsExports.isNumber,\n isBoolean: utilsExports.isBoolean,\n isString: utilsExports.isString,\n isObject: utilsExports.isObject,\n localNum: utilsExports.localNum,\n formatDuration: utilsExports.formatDuration,\n md5: utilsExports.md5,\n base64Encode: utilsExports.base64Encode,\n base64Decode: utilsExports.base64Decode,\n qs: utilsExports.qs,\n stringifyError: utilsExports.stringifyError,\n getTerminalInput: utilsExports.getTerminalInput,\n find: utilsExports.find,\n filter: utilsExports.filter,\n prettyMs: utilsExports.prettyMs,\n filesize: utilsExports.filesize,\n dayjs: utilsExports.dayjs,\n path: utilsExports.path,\n fs: utilsExports.fs,\n colors: utilsExports.colors,\n} as const\n\ntype CtxUtils = typeof CTX_UTILS\n\n/**\n * 插件上下文:插件 `setup(ctx)` 收到的对象。\n * 事件监听、定时任务、配置、日志、Bot 操作与工具函数都挂在上面,\n * 同时混入了 `utils` 中的常用工具(dayjs、fs、path、randomInt 等)。\n */\nexport class MiokuContext {\n readonly #options: ContextOptions\n readonly #cleanup: Set<PluginCleanup> = new Set()\n\n constructor(options: ContextOptions) {\n this.#options = options\n Object.assign(this, CTX_UTILS)\n }\n\n #addCleanup(fn: PluginCleanup): void {\n this.#cleanup.add(fn)\n }\n\n get pluginName(): string {\n return this.#options.pluginName\n }\n\n /** 第一个已连接的 bot(多数单 bot 场景直接用这个) */\n get bot(): Bot | undefined {\n return this.#options.bots.all()[0]\n }\n\n /** 所有已连接的 bot */\n get bots(): readonly Bot[] {\n return this.#options.bots.all()\n }\n\n get self_id(): string | undefined {\n return this.bot?.bot_id\n }\n\n /** 按 bot_id 取指定 bot */\n pickBot<T extends Bot = Bot>(bot_id: string | number): T | undefined {\n return this.#options.bots.pick<T>(bot_id)\n }\n\n /**\n * 获取事件引用回复的消息内容。\n * 返回 null 表示没有引用、拿不到对应 bot 或消息已失效。\n */\n async getQuoteMsg(\n event: { quote_id?: string | null; bot?: Bot; self_id?: string },\n ): Promise<import('../capabilities/message').MessageGetResult | null> {\n const quoteId = event?.quote_id\n if (quoteId == null || quoteId === '') return null\n const bot = event.bot ?? (event.self_id != null ? this.pickBot(event.self_id) : undefined)\n if (!bot) return null\n try {\n return (await bot.getMessage(quoteId)) ?? null\n } catch {\n return null\n }\n }\n\n /** 按名称取适配器实例 */\n getAdapter<T extends Adapter = Adapter>(name: string): T | undefined {\n return this.#options.getAdapter<T>(name)\n }\n\n /** 所有已加载的适配器实例(含当前没有 bot 连接的) */\n get adapters(): readonly Adapter[] {\n return this.#options.listAdapters()\n }\n\n /**\n * 注册事件监听。route 支持层级路由,如 `message`、`message.group`、\n * `onebotv11:message`;返回取消监听函数。\n */\n handle<R extends string | readonly string[]>(\n route: R,\n handler: (event: RouteEvent<R>) => void | Promise<void>,\n ): () => void {\n const routes = Array.isArray(route) ? route : [route]\n const source = `plugin:${this.#options.pluginName}`\n const handledEvents = new WeakSet<Event>()\n const wrappedHandler = async (event: Event): Promise<void> => {\n if (handledEvents.has(event)) return\n handledEvents.add(event)\n await handler(event as RouteEvent<R>)\n }\n const disposers = routes.map((r) =>\n this.#options.bus.register(r, wrappedHandler, { source, priority: this.#options.priority }),\n )\n let disposed = false\n const dispose = (): void => {\n if (disposed) return\n disposed = true\n for (const dispose of disposers) dispose()\n }\n this.#addCleanup(dispose)\n return dispose\n }\n\n /** 注册 cron 定时任务,插件卸载时自动停止 */\n cron(expression: string, handler: CronHandler): ScheduledTask {\n const task = nodeCron.schedule(expression, async (taskContext: TaskContext) => {\n try {\n await handler(this, taskContext)\n } catch (err) {\n this.#options.logger.error(`Plugin \"${this.#options.pluginName}\" cron task failed`, err)\n }\n })\n let disposed = false\n const dispose = async (): Promise<void> => {\n if (disposed) return\n disposed = true\n await task.stop()\n await task.destroy()\n }\n this.#addCleanup(dispose)\n return task\n }\n\n /** 监听 bot 连接 / 断开 */\n onBot<K extends 'connected' | 'disconnected'>(\n type: K,\n handler: (event: K extends 'connected' ? { bot: Bot } : BotLifecycleEvent) => void | Promise<void>,\n ): () => void {\n const route = type === 'connected' ? 'bot:connected' : 'bot:disconnected'\n return this.handle(route, handler as (event: Event) => void | Promise<void>)\n }\n\n getDriver(): Driver {\n return this.#options.driver\n }\n\n /** 当前框架配置(只读) */\n get config(): Readonly<MiokuConfig> {\n return this.#options.config\n }\n\n /** 修改框架配置(owners、admins、plugins 等) */\n updateConfig(updater: (config: MiokuConfig) => void | Promise<void>): Promise<void> {\n return this.#options.onUpdateConfig(updater)\n }\n\n get logger(): Logger {\n return this.#options.logger\n }\n\n get plugins(): PluginManager {\n return this.#options.pluginManager\n }\n\n get services(): import('../services').MiokuServices {\n return servicesRegistry as import('../services').MiokuServices\n }\n\n /** 注册一个运行时服务供其他插件取用,返回注销函数 */\n addService<T = unknown>(name: string, value: T, cover?: boolean): () => void {\n const remove = registerService<T>(name, value, cover)\n this.#addCleanup(remove)\n return remove\n }\n\n get capabilities(): CapabilityRegistry {\n return this.#options.capabilities\n }\n\n get buses(): EventBus {\n return this.#options.bus\n }\n\n get segment(): typeof segment {\n return segment\n }\n\n /** 按模式匹配消息文本(支持正则/字符串/关键词数组) */\n match<T extends HasMessage>(\n event: T,\n pattern: Parameters<typeof matchMessage>[1],\n quote?: boolean,\n ): ReturnType<typeof matchMessage> {\n return matchMessage(event, pattern, quote)\n }\n\n /** 解析命令行字符串为 命令 + 参数 + 选项 */\n createCmd(cmdStr: string, options: CreateCmdOptions = {}): ReturnType<typeof createCmdUtil> {\n return createCmdUtil(cmdStr, options)\n }\n\n /** 在插件目录下创建一个 JSON 数据存储 */\n createStore<T extends object = object>(\n defaultData: T,\n options: { __dirname?: string; importMeta?: ImportMeta; compress?: boolean; filename?: string } = {},\n ): ReturnType<typeof createStoreUtil<T>> {\n return createStoreUtil<T>(defaultData, options)\n }\n\n /** 在指定路径创建一个 lowdb 数据库文件 */\n createDB<T extends object = object>(\n filename: string,\n options: { defaultData?: T; compress?: boolean } = {},\n ): ReturnType<typeof createDBUtil<T>> {\n return createDBUtil<T>(filename, options)\n }\n\n /** 提取事件消息的纯文本 */\n text(source: HasMessage | Message, options?: { trim?: boolean | 'whole' | 'each' }): string {\n return extractText(source, options)\n }\n\n /** 向多个群发送消息 */\n noticeGroups(groupIds: readonly string[], message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeGroupsAction(this.#options.bots.all(), groupIds, message, options)\n }\n\n /** 向多个好友发送消息 */\n noticeFriends(userIds: readonly string[], message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeFriendsAction(this.#options.bots.all(), userIds, message, options)\n }\n\n /** 向所有主人发送消息 */\n noticeOwners(message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeOwnersAction(this.#options.bots.all(), this.#options.config.owners, message, options)\n }\n\n /** 向所有管理员发送消息 */\n noticeAdmins(message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeAdminsAction(this.#options.bots.all(), this.#options.config.admins, message, options)\n }\n\n isGroupMsg(event: unknown): boolean {\n return isObject(event) && (event as { kind?: unknown }).kind === 'message' &&\n (event as { message_type?: unknown }).message_type === 'group'\n }\n\n isPrivateMsg(event: unknown): boolean {\n return isObject(event) && (event as { kind?: unknown }).kind === 'message' &&\n (event as { message_type?: unknown }).message_type === 'private'\n }\n\n /** 事件发送者是否为主人 */\n isOwner(event: unknown): boolean {\n return isEventOwner(event)\n }\n\n /** 事件发送者是否为管理员 */\n isAdmin(event: unknown): boolean {\n return isEventAdmin(event)\n }\n\n isOwnerOrAdmin(event: unknown): boolean {\n return isEventOwnerOrAdmin(event)\n }\n\n hasRight(event: unknown): boolean {\n return hasEventRight(event)\n }\n\n async dispose(): Promise<void> {\n const all = Array.from(this.#cleanup)\n this.#cleanup.clear()\n for (const fn of all) {\n try {\n await fn()\n } catch {\n // swallow individual cleanup errors so other plugins can still clean up\n }\n }\n }\n}\n\nexport interface MiokuContext extends CtxUtils {}\n","import { getOrCreate } from '../internal/registry'\n\nimport type { PluginMetadata } from '../types'\n\nconst store = getOrCreate<Map<string, PluginMetadata>>('plugin-metadata', () => new Map())\n\nexport const setPluginMetadata = (meta: PluginMetadata): void => {\n store.set(meta.name, meta)\n}\n\nexport const removePluginMetadata = (name: string): void => {\n store.delete(name)\n}\n\nexport const getPluginMetadata = (name: string): PluginMetadata | undefined => store.get(name)\n\nexport const getPluginMetadataList = (): PluginMetadata[] => [...store.values()]\n\nexport const resetPluginMetadata = (): void => {\n store.clear()\n}","import { getOrCreate } from \"../internal/registry\";\n\nconst store = getOrCreate<Record<string, unknown>>(\n \"plugin-runtime-state\",\n () => ({}),\n);\n\n/** 插件运行时状态引用:跨重载安全的读写句柄 */\nexport interface PluginStateRef<T> {\n readonly name: string;\n get(): T;\n set(next: T): void;\n reset(): void;\n}\n\n/** 定义一个具名状态引用,插件重载后仍能读回旧值 */\nexport function defineState<T>(name: string, initial: T): PluginStateRef<T> {\n return {\n name,\n get(): T {\n const current = store[name];\n return (current === undefined ? initial : current) as T;\n },\n set(next: T): void {\n store[name] = next;\n },\n reset(): void {\n delete store[name];\n },\n };\n}\n\nexport function hasPluginState(name: string): boolean {\n return store[name] !== undefined;\n}\n\n/** 取插件的运行时状态对象,不存在时自动创建空对象 */\nexport function getPluginRuntimeState<T = Record<string, any>>(\n name: string,\n): T {\n if (!store[name]) store[name] = {};\n return store[name] as T;\n}\n\n/** 合并写入插件运行时状态 */\nexport function setPluginRuntimeState<T>(name: string, state: T): void {\n store[name] = state;\n}\n\nexport function resetPluginRuntimeState(name: string): void {\n delete store[name];\n}\n\nexport function getAllPluginRuntimeStates(): Record<string, unknown> {\n return { ...store };\n}","import os from 'node:os'\nimport cp from 'node:child_process'\nimport { version } from '../../../package.json' with { type: 'json' }\n\nimport { filesize, localNum, prettyMs } from '../../utils'\n\nimport type { Bot } from '../../adapter'\nimport type { AdapterReport, AdapterStatusStats } from './adapters'\n\nexport const SystemMap: Record<string, string> = {\n Linux: 'Linux',\n Darwin: 'macOS',\n Windows_NT: 'Win',\n}\n\nexport const ArchMap: Record<string, string> = {\n ia32: 'x86',\n arm: 'arm',\n arm64: 'arm64',\n x64: 'x64',\n}\n\nexport interface BotStatus {\n bot_id: string\n nickname: string\n online: boolean\n adapter: string\n friends?: number\n groups?: number\n send?: number\n receive?: number\n}\n\nexport interface MiokuStatus {\n bots: readonly BotStatus[]\n plugins: {\n enabled: number\n total: number\n }\n stats: {\n uptime: number\n }\n versions: {\n node: string\n mioku: string\n }\n system: {\n name: string\n version: string\n arch: string\n }\n memory: {\n used: number\n total: number\n percent: number\n rss: {\n used: number\n percent: number\n }\n }\n disk: {\n total: number\n used: number\n free: number\n percent: number\n }\n cpu: {\n name: string\n count: number\n percent: number\n }\n}\n\nexport interface MiokuCoreServiceContrib {\n getMiokuStatus(): Promise<MiokuStatus>\n formatMiokuStatus(status: MiokuStatus): Promise<string>\n getAdapterReport(): Promise<AdapterReport>\n}\n\nconst getSystemInfo = (): { name: string; version: string; arch: string } => {\n const osType = os.type()\n const arch = ArchMap[os.type()] ?? os.arch()\n return { name: SystemMap[osType] ?? osType, version: '-', arch }\n}\n\nconst getCpuTimes = (): { idle: number; total: number } => {\n const cpus = os.cpus()\n let idle = 0\n let total = 0\n for (const cpu of cpus) {\n for (const type in cpu.times) total += (cpu.times as Record<string, number>)[type] ?? 0\n idle += cpu.times.idle ?? 0\n }\n return { idle, total }\n}\n\nconst measureCpuUsage = async (interval = 600): Promise<number> => {\n const start = getCpuTimes()\n await new Promise((resolve) => setTimeout(resolve, interval))\n const end = getCpuTimes()\n const idleDiff = end.idle - start.idle\n const totalDiff = end.total - start.total\n if (totalDiff <= 0) return 0\n const usage = 1 - idleDiff / totalDiff\n return usage * 100\n}\n\nconst getDiskUsage = (): Promise<{ total: number; used: number; free: number; percent: number }> =>\n new Promise((resolve) => {\n if (!['Linux', 'Darwin'].includes(os.type())) {\n resolve({ total: 0, used: 0, free: 0, percent: 0 })\n return\n }\n cp.exec(`df -k / | tail -1 | awk '{print $2,$4}'`, (err, stdout) => {\n if (err) {\n resolve({ total: 0, used: 0, free: 0, percent: 0 })\n return\n }\n const [totalStr, freeStr] = stdout.trim().split(' ')\n const total = Number(totalStr) * 1024\n const free = Number(freeStr) * 1024\n const used = total - free\n resolve({ total, free, used, percent: total > 0 ? Number(((used / total) * 100).toFixed(1)) : 0 })\n })\n })\n\nexport interface BuildStatusOptions {\n readonly bots: readonly Bot[]\n /** 各 bot 的计数,由 core 从适配器上报里取好后传入,键为 `adapter:bot_id` */\n readonly botStats?: ReadonlyMap<string, AdapterStatusStats>\n readonly enabledPlugins: number\n readonly totalPlugins: number\n readonly systemInfoProvider?: () => Promise<{ distro: string; release: string }>\n}\n\nexport const buildMiokuStatus = async (options: BuildStatusOptions): Promise<MiokuStatus> => {\n const sysInfo = options.systemInfoProvider ? await options.systemInfoProvider() : null\n const defaultSystem = getSystemInfo()\n const system = sysInfo ? { name: sysInfo.distro, version: sysInfo.release, arch: defaultSystem.arch } : defaultSystem\n const cpu = (() => {\n const cpus = os.cpus()\n return { name: cpus[0]?.model ?? '[未知CPU]', count: cpus.length }\n })()\n const totalMem = os.totalmem()\n const usedMem = totalMem - os.freemem()\n const rssMem = process.memoryUsage.rss()\n const [disk, cpuPercent] = await Promise.all([getDiskUsage(), measureCpuUsage()])\n return {\n bots: options.bots.map((bot) => {\n const stats = options.botStats?.get(`${bot.adapter}:${bot.bot_id}`)\n return {\n bot_id: bot.bot_id,\n nickname: bot.nickname ?? '',\n online: bot.online,\n adapter: bot.adapter,\n friends: stats?.friends,\n groups: stats?.groups,\n send: stats?.sent,\n receive: stats?.received,\n }\n }),\n plugins: { enabled: options.enabledPlugins, total: options.totalPlugins },\n stats: { uptime: process.uptime() * 1000 },\n versions: { node: process.versions.node, mioku: version },\n system,\n memory: {\n used: usedMem,\n total: totalMem,\n percent: totalMem > 0 ? Number(((usedMem / totalMem) * 100).toFixed(1)) : 0,\n rss: {\n used: rssMem,\n percent: totalMem > 0 ? Number(((rssMem / totalMem) * 100).toFixed(1)) : 0,\n },\n },\n disk,\n cpu: { name: cpu.name.trim(), count: cpu.count, percent: Number(cpuPercent.toFixed(1)) },\n }\n}\n\nexport const formatMiokuStatus = async (status: MiokuStatus): Promise<string> => {\n const { bots, plugins, system, disk, cpu, memory, versions } = status\n\n const diskValid = disk.total > 0 && disk.free >= 0\n const diskDesc = diskValid\n ? `${disk.percent}%-${filesize(disk.used, { round: 1 })}/${filesize(disk.total, { round: 1 })}`\n : ''\n\n const botLines = bots\n .map((bot) => {\n const hasStats = bot.friends != null || bot.groups != null || bot.send != null || bot.receive != null\n const statsLine = hasStats\n ? `\\n📋 ${localNum(bot.friends ?? 0)} 好友 / ${localNum(bot.groups ?? 0)} 群 / 📮 收 ${localNum(bot.receive ?? 0)} 发 ${localNum(bot.send ?? 0)}`\n : ''\n return `👤 ${bot.nickname || '(未命名)'} (${bot.bot_id})${statsLine}`\n })\n .join('\\n')\n\n const totalSend = bots.reduce((sum, bot) => sum + (bot.send ?? 0), 0)\n const totalReceive = bots.reduce((sum, bot) => sum + (bot.receive ?? 0), 0)\n const statsLine = bots.length > 1 ? `\\n📮 总计: 收 ${localNum(totalReceive)} 条,发 ${localNum(totalSend)} 条` : ''\n\n return `\n〓 🟢 mioku 状态 〓\n${botLines || '(无在线 Bot)'}\n🧩 启用了 ${localNum(plugins.enabled)} 个插件,共 ${localNum(plugins.total)} 个${statsLine}\n🚀 ${filesize(memory.rss.used, { round: 1 })}/${memory.percent}%\n⏳ 已运行 ${prettyMs(status.stats.uptime, { hideYear: true, secondsDecimalDigits: 0 })}\n🤖 mioku/${versions.mioku}-node/${versions.node.split('.')[0]}\n🖥️ ${system.name.split(' ')[0]}/${system.version.split('.')[0]}-${system.name}-node/${versions.node.split('.')[0]}\n📊 ${memory.percent}%-${filesize(memory.used, { base: 2, round: 1 })}/${filesize(memory.total, { base: 2, round: 1 })}\n🧮 ${cpu.percent}%-${cpu.name}-${cpu.count}核\n${diskValid ? `💾 ${diskDesc}` : ''}\n `.trim()\n}\n","import { getOrCreate } from \"../../internal/registry\";\nimport { localNum, prettyMs } from \"../../utils\";\n\nimport type { Bot } from \"../../adapter\";\nimport type { AdapterStatus, AdapterStatusStats } from \"../../runtime/types\";\n\nexport type { AdapterStatus, AdapterStatusStats } from \"../../runtime/types\";\n\nexport interface StatusProviderContext {\n readonly bot: Bot;\n}\n\nexport type StatusProvider = (\n context: StatusProviderContext,\n) => Promise<AdapterStatus> | AdapterStatus;\n\n/** 注册目标*/\nexport type StatusProviderTarget =\n | string\n | { readonly adapter: string; readonly bot_id?: string };\n\nconst statusProviders = getOrCreate<Map<string, StatusProvider>>(\n \"status-providers\",\n () => new Map(),\n);\n\nconst providerKey = (adapter: string, bot_id?: string): string =>\n bot_id == null || bot_id === \"\" ? adapter : `${adapter}:${bot_id}`;\n\n/**\n * 注册适配器状态上报\n */\nexport const registerStatusProvider = (\n target: StatusProviderTarget,\n provider: StatusProvider,\n): (() => void) => {\n const { adapter, bot_id } =\n typeof target === \"string\"\n ? { adapter: target, bot_id: undefined }\n : target;\n const key = providerKey(adapter, bot_id);\n statusProviders.set(key, provider);\n return () => {\n if (statusProviders.get(key) === provider) statusProviders.delete(key);\n };\n};\n\nconst resolveProvider = (bot: Bot): StatusProvider | undefined =>\n statusProviders.get(providerKey(bot.adapter, bot.bot_id)) ??\n statusProviders.get(providerKey(bot.adapter));\n\n/** 单个已连接实例 */\nexport interface AdapterInstanceStatus {\n readonly bot_id: string;\n readonly nickname: string;\n readonly online: boolean;\n readonly connected_at?: number;\n readonly impl?: string;\n readonly version?: string;\n readonly protocol?: string;\n readonly platform?: string;\n readonly platformVersion?: string;\n readonly stats: AdapterStatusStats;\n readonly data: Readonly<Record<string, unknown>>;\n}\n\n/** 单个适配器及其实例 */\nexport interface AdapterReportEntry {\n readonly name: string;\n /** 适配器包版本 */\n readonly version?: string;\n /** 底层实现库,如 icqq 的 ICQQ 1.11.4 */\n readonly impl?: { readonly name: string; readonly version?: string };\n readonly loaded: boolean;\n readonly instances: readonly AdapterInstanceStatus[];\n}\n\nexport interface AdapterReport {\n readonly adapters: readonly AdapterReportEntry[];\n readonly totalInstances: number;\n}\n\nexport interface BuildAdapterReportOptions {\n readonly bots: readonly Bot[];\n readonly adapters: readonly {\n readonly name: string;\n readonly version?: string;\n readonly impl?: { readonly name: string; readonly version?: string };\n }[];\n}\n\nconst num = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\n/** v1.0 的适配器把计数塞在 data 里 */\nconst legacyStats = (data: Record<string, unknown>): AdapterStatusStats => ({\n friends: num(data.friends),\n groups: num(data.groups),\n sent: num(data.send),\n received: num(data.receive),\n});\n\nconst normalizeStats = (\n stats: AdapterStatusStats | undefined,\n data: Record<string, unknown>,\n): AdapterStatusStats => {\n const fallback = legacyStats(data);\n return {\n friends: num(stats?.friends) ?? fallback.friends,\n groups: num(stats?.groups) ?? fallback.groups,\n sent: num(stats?.sent) ?? fallback.sent,\n received: num(stats?.received) ?? fallback.received,\n };\n};\n\nconst toInstance = (\n bot: Bot,\n status: AdapterStatus | null,\n): AdapterInstanceStatus => {\n const data = (status?.data ?? {}) as Record<string, unknown>;\n return {\n bot_id: bot.bot_id,\n nickname: bot.nickname ?? \"\",\n online: bot.online,\n connected_at: bot.connected_at,\n impl: status?.impl,\n version: status?.version,\n protocol: status?.protocol,\n platform: status?.platform,\n platformVersion: status?.platform_version,\n stats: normalizeStats(status?.stats, data),\n data,\n };\n};\n\n/** 逐个 bot 查询状态 */\nexport const buildAdapterReport = async (\n options: BuildAdapterReportOptions,\n): Promise<AdapterReport> => {\n const names = options.adapters.map((adapter) => adapter.name);\n for (const bot of options.bots)\n if (!names.includes(bot.adapter)) names.push(bot.adapter);\n\n const instances = await Promise.all(\n options.bots.map(async (bot) => {\n const provider = resolveProvider(bot);\n if (!provider) return toInstance(bot, null);\n try {\n return toInstance(bot, await provider({ bot }));\n } catch {\n return toInstance(bot, null);\n }\n }),\n );\n\n const paired = options.bots.map((bot, index) => ({\n adapter: bot.adapter,\n instance: instances[index]!,\n }));\n const adapters = names.map((name) => {\n const known = options.adapters.find((adapter) => adapter.name === name);\n return {\n name,\n version: known?.version,\n impl: known?.impl,\n loaded: known != null,\n instances: paired\n .filter((entry) => entry.adapter === name)\n .map((entry) => entry.instance),\n };\n });\n\n return { adapters, totalInstances: instances.length };\n};\n\nexport const collectBotStats = (\n report: AdapterReport,\n): Map<string, AdapterStatusStats> => {\n const map = new Map<string, AdapterStatusStats>();\n for (const entry of report.adapters)\n for (const instance of entry.instances)\n map.set(`${entry.name}:${instance.bot_id}`, instance.stats);\n return map;\n};\n\nconst STAT_GROUPS: ReadonlyArray<\n readonly [\n icon: string,\n fields: ReadonlyArray<readonly [keyof AdapterStatusStats, string]>,\n ]\n> = [\n [\n \"📋\",\n [\n [\"friends\", \"好友\"],\n [\"groups\", \"群\"],\n ],\n ],\n [\n \"📮\",\n [\n [\"received\", \"收\"],\n [\"sent\", \"发\"],\n ],\n ],\n];\n\nconst formatStats = (stats: AdapterStatusStats): string => {\n const segments: string[] = [];\n for (const [icon, fields] of STAT_GROUPS) {\n const parts = fields\n .filter(([key]) => stats[key] != null)\n .map(([key, label]) => `${label} ${localNum(stats[key]!)}`);\n if (parts.length) segments.push(`${icon} ${parts.join(\" / \")}`);\n }\n return segments.join(\" · \");\n};\n\nconst formatInstance = (instance: AdapterInstanceStatus): string[] => {\n const tags = [\n [instance.impl, instance.version].filter(Boolean).join(\"/\"),\n instance.platform\n ? `${instance.platform}${instance.platformVersion ? ` v${instance.platformVersion}` : \"\"}`\n : \"\",\n instance.online ? \"\" : \"🔴 离线\",\n ].filter(Boolean);\n const lines = [\n `👤 ${instance.nickname || \"(未命名)\"} (${instance.bot_id})${tags.length ? ` · ${tags.join(\" · \")}` : \"\"}`,\n ];\n const uptime =\n instance.online && instance.connected_at != null\n ? `⏳ 已连接 ${prettyMs(Date.now() - instance.connected_at, { hideYear: true, secondsDecimalDigits: 0 })}`\n : \"\";\n const detail = [formatStats(instance.stats), uptime]\n .filter(Boolean)\n .join(\" · \");\n if (detail) lines.push(detail);\n return lines;\n};\n\nconst summarize = (entry: AdapterReportEntry): string => {\n const total = entry.instances.length;\n if (total === 0) return entry.loaded ? \"🔴 未连接\" : \"⚪ 未加载\";\n const online = entry.instances.filter((instance) => instance.online).length;\n if (online === total) return `🟢 ${localNum(total)} 实例`;\n return `${online === 0 ? \"🔴\" : \"🟡\"} ${localNum(online)}/${localNum(total)} 实例在线`;\n};\n\n/** `名称@包版本[/实现库 v版本]` */\nconst formatAdapterName = (entry: AdapterReportEntry): string => {\n const base = `${entry.name}${entry.version ? `@${entry.version}` : \"\"}`;\n if (!entry.impl) return base;\n const impl = `${entry.impl.name}${entry.impl.version ? ` v${entry.impl.version}` : \"\"}`;\n return `${base}/${impl}`;\n};\n\nexport const formatAdapterReport = (report: AdapterReport): string => {\n if (!report.adapters.length)\n return \"〓 🔌 mioku 适配器 〓\\n(未加载任何适配器)\";\n\n const lines = report.adapters.flatMap((entry) => [\n `🔌 ${formatAdapterName(entry)} · ${summarize(entry)}`,\n ...entry.instances.flatMap(formatInstance),\n ]);\n\n return [\"〓 🔌 mioku 适配器 〓\", ...lines].join(\"\\n\");\n};\n","export interface MessageFilterRule {\n whitelist: number[];\n blacklist: number[];\n}\n\nexport interface MessageFilterConfig {\n user: MessageFilterRule;\n group: MessageFilterRule;\n}\n\nexport interface AutoUpdateConfig {\n enabled: boolean;\n time: string;\n frequency: \"daily\" | \"weekly\" | \"monthly\";\n}\n\nexport interface CorePluginConfig {\n likeCommand: {\n enabled: boolean;\n keyword: string;\n likeTimes: number;\n reactionEmojiId: number;\n };\n friend: {\n autoApprove: boolean;\n };\n group: {\n minMemberCount: number;\n };\n messageFilter: MessageFilterConfig;\n autoUpdate: AutoUpdateConfig;\n}\n\nexport const CORE_DEFAULT_CONFIG: CorePluginConfig = {\n likeCommand: {\n enabled: true,\n keyword: \"赞我\",\n likeTimes: 10,\n reactionEmojiId: 201,\n },\n friend: {\n autoApprove: true,\n },\n group: {\n minMemberCount: 0,\n },\n messageFilter: {\n user: { whitelist: [], blacklist: [] },\n group: { whitelist: [], blacklist: [] },\n },\n autoUpdate: {\n enabled: true,\n time: \"03:00\",\n frequency: \"daily\",\n },\n};\n\nfunction normalizeIdList(input: unknown): number[] {\n if (!Array.isArray(input)) return [];\n return Array.from(\n new Set(\n input\n .map((v) => Math.floor(Number(v)))\n .filter((n) => Number.isFinite(n) && n > 0),\n ),\n );\n}\n\nfunction normalizeFilterRule(input: any): MessageFilterRule {\n return {\n whitelist: normalizeIdList(input?.whitelist),\n blacklist: normalizeIdList(input?.blacklist),\n };\n}\n\nexport function cloneConfig<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function normalizeCoreConfig(config: CorePluginConfig | any): CorePluginConfig {\n const merged: CorePluginConfig = {\n ...cloneConfig(CORE_DEFAULT_CONFIG),\n ...(config || {}),\n likeCommand: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.likeCommand),\n ...(config?.likeCommand || {}),\n },\n friend: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.friend),\n ...(config?.friend || {}),\n },\n group: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.group),\n ...(config?.group || {}),\n minMemberCount:\n Number(config?.group?.minMemberCount) ||\n CORE_DEFAULT_CONFIG.group.minMemberCount,\n },\n messageFilter: {\n user: normalizeFilterRule(config?.messageFilter?.user),\n group: normalizeFilterRule(config?.messageFilter?.group),\n },\n autoUpdate: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.autoUpdate),\n ...(config?.autoUpdate || {}),\n time: config?.autoUpdate?.time || CORE_DEFAULT_CONFIG.autoUpdate.time,\n frequency: [\"daily\", \"weekly\", \"monthly\"].includes(config?.autoUpdate?.frequency)\n ? config.autoUpdate.frequency\n : CORE_DEFAULT_CONFIG.autoUpdate.frequency,\n },\n };\n return merged;\n}\n","import type { AccessControlConfig } from \"../../../types\";\n\nexport const ACCESS_DEFAULT_CONFIG: AccessControlConfig = {\n version: 1,\n global: { plugins: {}, commands: {} },\n groups: {},\n users: {},\n};\n\nexport function normalizeAccessConfig(\n config: Partial<AccessControlConfig> | any,\n): AccessControlConfig {\n return {\n version: 1,\n global: {\n plugins: config?.global?.plugins ?? {},\n commands: config?.global?.commands ?? {},\n },\n groups: config?.groups ?? {},\n users: config?.users ?? {},\n };\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { rootLogger as logger } from \"../../../logger\";\nimport type { AccessControlConfig } from \"../../../types\";\nimport {\n ACCESS_DEFAULT_CONFIG,\n normalizeAccessConfig,\n} from \"./access-config\";\n\nconst ACCESS_CONFIG_PATH = path.resolve(\n process.cwd(),\n \"config/core/access-control.json\",\n);\n\nconst BOOT_ACCESS_CONFIG_PATH = path.resolve(\n process.cwd(),\n \"config/boot/access-control.json\",\n);\n\nconst LEGACY_ACCESS_CONFIG_PATH = path.resolve(\n process.cwd(),\n \"config/access-control/base.json\",\n);\n\ninterface LegacyMessageFilter {\n user?: { whitelist?: Array<string | number>; blacklist?: Array<string | number> };\n group?: { whitelist?: Array<string | number>; blacklist?: Array<string | number> };\n}\n\nfunction readJsonSafe<T>(filePath: string): T | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as T;\n } catch {\n return null;\n }\n}\n\nfunction writeJsonSafe(filePath: string, data: unknown): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf-8\");\n}\n\nfunction copyFromLegacyLocation(): boolean {\n if (fs.existsSync(ACCESS_CONFIG_PATH)) return false;\n const legacy = readJsonSafe<AccessControlConfig>(BOOT_ACCESS_CONFIG_PATH)\n ?? readJsonSafe<AccessControlConfig>(LEGACY_ACCESS_CONFIG_PATH);\n if (!legacy) return false;\n writeJsonSafe(ACCESS_CONFIG_PATH, normalizeAccessConfig(legacy));\n logger.info(\n `已从旧位置迁移 access-control 配置到 ${path.relative(process.cwd(), ACCESS_CONFIG_PATH)}`,\n );\n return true;\n}\n\nfunction migrateFromBootMessageFilter(): AccessControlConfig | null {\n if (fs.existsSync(ACCESS_CONFIG_PATH)) return null;\n\n const bootConfigPath = path.resolve(process.cwd(), \"config/boot/base.json\");\n const bootConfig = readJsonSafe<{ messageFilter?: LegacyMessageFilter }>(\n bootConfigPath,\n );\n if (!bootConfig?.messageFilter) return null;\n\n writeJsonSafe(ACCESS_CONFIG_PATH, ACCESS_DEFAULT_CONFIG);\n logger.info(\"已从旧 boot.messageFilter 迁移到 config/core/access-control.json\");\n\n const stripped = { ...bootConfig };\n delete (stripped as any).messageFilter;\n writeJsonSafe(bootConfigPath, stripped);\n logger.info(\"已从 config/boot/base.json 中移除 messageFilter 字段\");\n\n return ACCESS_DEFAULT_CONFIG;\n}\n\nexport function ensureAccessControlConfig(): AccessControlConfig {\n copyFromLegacyLocation();\n\n const existing = readJsonSafe<AccessControlConfig>(ACCESS_CONFIG_PATH);\n if (existing) return normalizeAccessConfig(existing);\n\n const migrated = migrateFromBootMessageFilter();\n if (migrated) return migrated;\n\n writeJsonSafe(ACCESS_CONFIG_PATH, ACCESS_DEFAULT_CONFIG);\n return ACCESS_DEFAULT_CONFIG;\n}\n","import type { AccessHook, PluginMetadata } from \"../../../types\";\n\nexport interface MessageCommandMatch {\n plugin: string;\n command: string;\n}\n\nfunction matchTextHook(text: string, hook: AccessHook): boolean {\n const m = String(hook.match || \"\").trim();\n if (!m) return false;\n if (m.startsWith(\"/\") && m.endsWith(\"/\") && m.length >= 3) {\n try {\n const re = new RegExp(m.slice(1, -1));\n return re.test(text);\n } catch {\n return false;\n }\n }\n return text === m || text.startsWith(m);\n}\n\nexport function matchMessageCommands(\n plugins: PluginMetadata[],\n text: string,\n): MessageCommandMatch[] {\n const trimmed = String(text || \"\").trim();\n if (!trimmed) return [];\n const out: MessageCommandMatch[] = [];\n for (const p of plugins) {\n const hooks = p.config?.accessHooks;\n if (!hooks || hooks.length === 0) continue;\n for (const hook of hooks) {\n if (!hook.match) continue;\n if (matchTextHook(trimmed, hook)) {\n out.push({ plugin: p.name, command: hook.id });\n }\n }\n }\n return out;\n}\n","import type { BotBase } from \"../../../adapter/bot\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport type { CorePluginConfig } from \"../config\";\n\nexport function registerLikeCommand(\n ctx: MiokuContext,\n getConfig: () => CorePluginConfig,\n): () => void {\n return ctx.handle(\"message\", async (event) => {\n const cfg = getConfig();\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) {\n return;\n }\n\n if (!cfg.likeCommand.enabled) {\n return;\n }\n\n const keyword = String(cfg.likeCommand.keyword || \"\").trim();\n if (!keyword || text !== keyword) {\n return;\n }\n\n const userId = event?.user_id || event?.sender?.user_id || \"\";\n if (!userId) {\n return;\n }\n\n const bot = event.bot;\n if (!bot) {\n return;\n }\n const likeTimes = Math.max(1, Number(cfg.likeCommand.likeTimes) || 10);\n const reactionEmojiId = Math.max(\n 0,\n Number(cfg.likeCommand.reactionEmojiId) || 66,\n );\n const messageId = event?.message_id;\n\n const adapter = bot.adapter as string;\n\n if (adapter === \"onebotv11\") {\n try {\n await bot.sendApi<boolean>(\"send_like\", {\n user_id: userId,\n times: likeTimes,\n });\n } catch (error) {\n ctx.logger.warn(`core send_like 失败: ${error}`);\n }\n\n if (messageId != null) {\n try {\n await bot.sendApi(\"set_msg_emoji_like\", {\n message_id: messageId,\n emoji_id: reactionEmojiId,\n set: true,\n });\n } catch (error) {\n ctx.logger.warn(`core set_msg_emoji_like 失败: ${error}`);\n }\n }\n } else if (adapter === \"icqq\") {\n const icqqBot = bot as BotBase & {\n sendLike(userId: string | number, times?: number): Promise<boolean>;\n };\n try {\n await icqqBot.sendLike(userId, likeTimes);\n } catch (error) {\n ctx.logger.warn(`core sendLike 失败: ${error}`);\n }\n }\n });\n}\n","import { botConfig } from \"../../../config\";\n\nexport function isPrivilegedUser(userId: string | number | undefined): boolean {\n const normalizedUserId = String(userId ?? \"\").trim();\n if (!normalizedUserId) return false;\n const owners = Array.isArray(botConfig?.owners) ? botConfig.owners : [];\n const admins = Array.isArray(botConfig?.admins) ? botConfig.admins : [];\n return [...owners, ...admins].some(\n (value) => String(value).trim() === normalizedUserId,\n );\n}\n","import { wait } from \"../../../utils\";\nimport { createGroupRef } from \"../../../capabilities\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport type { CorePluginConfig } from \"../config\";\nimport { isPrivilegedUser } from \"../access/privileged\";\n\nexport function registerMinMemberCheck(\n ctx: MiokuContext,\n getConfig: () => CorePluginConfig,\n): () => void {\n return ctx.handle(\"notice.group.increase\", async (event) => {\n const cfg = getConfig();\n const selfId = String(event?.self_id || ctx.self_id || \"\");\n const groupId = event?.group_id ?? \"\";\n const userId = event?.user_id ?? \"\";\n if (!groupId || !userId) return;\n if (userId !== selfId) return;\n\n if (\n (event?.raw as { action_type?: string } | undefined)?.action_type === \"invite\" &&\n isPrivilegedUser(event?.operator_id)\n ) {\n ctx.logger.info(`群 ${groupId} 由主人/管理员邀请加入,跳过入群限制检查`);\n return;\n }\n\n const minMemberCount = Math.max(0, Number(cfg.group.minMemberCount) || 0);\n if (minMemberCount <= 0) return;\n\n const bot = event.bot;\n if (!bot) return;\n\n try {\n await wait(1000);\n const groupRef = createGroupRef(bot, groupId);\n const groupInfo = await groupRef.getInfo();\n const memberCount = Number(groupInfo?.member_count || 0);\n if (memberCount > 0 && memberCount < minMemberCount) {\n await groupRef.leave(false);\n ctx.logger.info(\n `群 ${groupId} 人数 ${memberCount} 低于限制 ${minMemberCount},已自动退群`,\n );\n }\n } catch (error) {\n ctx.logger.warn(`入群人数检查失败: ${error}`);\n }\n });\n}\n","import type { MiokuContext } from \"../../../runtime/mioku-context\";\n\nconst FORWARD_LINE_LIMIT = 50;\nconst LINES_PER_NODE = 20;\n\nfunction chunk<T>(arr: T[], size: number): T[][] {\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n result.push(arr.slice(i, i + size));\n }\n return result;\n}\n\nexport function replyText(event: any, text: string): Promise<void> {\n return event.reply(text, true);\n}\n\nexport async function sendTextOrForward(options: {\n ctx: MiokuContext;\n event: any;\n text: string;\n source: string;\n summary?: string;\n}): Promise<void> {\n const { ctx, event, text, source, summary } = options;\n const lines = text.split(/\\r?\\n/).filter((line) => line.length > 0);\n if (lines.length <= FORWARD_LINE_LIMIT) {\n await replyText(event, text);\n return;\n }\n\n const selfId = String(event?.self_id || \"\");\n const bot = event.bot;\n if (!bot) {\n await replyText(event, text);\n return;\n }\n\n const nodes = chunk(lines, LINES_PER_NODE).map((chunkLines, idx) => ({\n user_id: selfId,\n nickname: `第${idx + 1}条`,\n content: [ctx.segment.text(chunkLines.join(\"\\n\"))],\n }));\n\n try {\n const target =\n event?.message_type === \"group\" && event?.group_id\n ? { type: \"group\" as const, group_id: event.group_id }\n : event?.user_id\n ? { type: \"private\" as const, user_id: event.user_id }\n : undefined;\n if (target) {\n await bot.sendForward(target, nodes, { source, summary });\n }\n } catch (error) {\n ctx.logger.error(`[core] 发送转发消息失败: ${error}`);\n await replyText(event, text);\n }\n}\n","import { botConfig } from \"../../../config\";\n\nexport function getCommandPrefix(): string {\n return botConfig.prefix ?? \".\";\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { rootLogger as logger } from \"../../../logger\";\n\nconst NPM_REGISTRY = \"https://registry.npmjs.org\";\nconst OFFICIAL_REGISTRY_URL =\n \"https://raw.githubusercontent.com/mioku-lab/mioku/main/official-registry.json\";\nconst PLUGIN_PREFIX = \"mioku-plugin-\";\nconst SERVICE_PREFIX = \"mioku-service-\";\nconst FRAMEWORK_NAME = \"mioku\";\n\nexport type PackageType = \"plugin\" | \"service\" | \"framework\";\n\nexport interface InstalledPackage {\n name: string;\n type: PackageType;\n shortName: string;\n version: string;\n path: string;\n}\n\nexport interface UpdateAvailable {\n name: string;\n type: PackageType;\n shortName: string;\n current: string;\n latest: string;\n}\n\nexport interface MarketItem {\n name: string;\n npm: string;\n type: PackageType;\n description: string;\n latest: string;\n installed: boolean;\n installedVersion: string;\n hasUpdate: boolean;\n tags: string[];\n official: boolean;\n homepage: string;\n repo: string;\n}\n\ninterface OfficialRegistryEntry {\n npm?: string;\n builtin?: boolean;\n}\n\ninterface OfficialRegistry {\n plugins?: Record<string, OfficialRegistryEntry>;\n services?: Record<string, OfficialRegistryEntry>;\n}\n\ninterface NpmSearchObject {\n package: {\n name: string;\n description?: string;\n version?: string;\n keywords?: string[];\n date?: string;\n links?: {\n npm?: string;\n repository?: string;\n homepage?: string;\n };\n };\n searchScore?: number;\n score?: { final?: number };\n}\n\nexport interface BunRunResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\nfunction projectRoot(): string {\n return process.cwd();\n}\n\nfunction detectType(name: string): PackageType | null {\n if (name === FRAMEWORK_NAME) return \"framework\";\n if (name.startsWith(PLUGIN_PREFIX)) return \"plugin\";\n if (name.startsWith(SERVICE_PREFIX)) return \"service\";\n return null;\n}\n\nfunction shortNameOf(name: string): string {\n if (name === FRAMEWORK_NAME) return FRAMEWORK_NAME;\n if (name.startsWith(PLUGIN_PREFIX)) return name.slice(PLUGIN_PREFIX.length);\n if (name.startsWith(SERVICE_PREFIX)) return name.slice(SERVICE_PREFIX.length);\n return name;\n}\n\nexport async function runBun(args: string[], cwd?: string): Promise<BunRunResult> {\n const runCwd = cwd ?? projectRoot();\n logger.info(`[core] 执行: bun ${args.join(\" \")} (cwd: ${runCwd})`);\n const startedAt = Date.now();\n return new Promise((resolve) => {\n const child = spawn(\"bun\", args, {\n cwd: runCwd,\n shell: process.platform === \"win32\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", (err) => {\n logger.error(`[core] bun 进程异常: ${err}`);\n resolve({ code: -1, stdout, stderr: stderr + String(err) });\n });\n child.on(\"close\", (code) => {\n const elapsed = ((Date.now() - startedAt) / 1000).toFixed(1);\n const exitCode = code ?? -1;\n if (exitCode === 0) {\n logger.info(`[core] bun 完成 (耗时 ${elapsed}s)`);\n } else {\n logger.error(\n `[core] bun 退出码 ${exitCode} (耗时 ${elapsed}s)\\n${stderr || stdout}`,\n );\n }\n resolve({ code: exitCode, stdout, stderr });\n });\n });\n}\n\nfunction readPackageJson(dir: string): any | null {\n const pkgPath = path.join(dir, \"package.json\");\n if (!fs.existsSync(pkgPath)) return null;\n try {\n return JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nexport function getInstalledVersion(pkgName: string): string {\n const pkg = readPackageJson(path.join(projectRoot(), \"node_modules\", pkgName));\n return String(pkg?.version || \"0.0.0\");\n}\n\nexport function listInstalledPackages(): InstalledPackage[] {\n const modulesPath = path.join(projectRoot(), \"node_modules\");\n const result: InstalledPackage[] = [];\n if (!fs.existsSync(modulesPath)) return result;\n\n const entries = fs.readdirSync(modulesPath, { withFileTypes: true });\n for (const entry of entries) {\n const type = detectType(entry.name);\n if (!type) continue;\n const fullPath = path.join(modulesPath, entry.name);\n const stat = fs.lstatSync(fullPath);\n if (!stat.isDirectory() && !stat.isSymbolicLink()) continue;\n const pkg = readPackageJson(fullPath);\n result.push({\n name: entry.name,\n type,\n shortName: shortNameOf(entry.name),\n version: String(pkg?.version || \"0.0.0\"),\n path: fullPath,\n });\n }\n return result.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nasync function fetchJson(url: string): Promise<any> {\n const res = await fetch(url, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-core\" },\n });\n if (!res.ok) throw new Error(`HTTP_${res.status}`);\n return res.json();\n}\n\ninterface NpmPackageMeta {\n latest: string;\n description: string;\n keywords: string[];\n homepage: string;\n repository: string;\n readme: string;\n license: string;\n}\n\nasync function fetchNpmMeta(pkgName: string): Promise<NpmPackageMeta | null> {\n try {\n const data = await fetchJson(\n `${NPM_REGISTRY}/${encodeURIComponent(pkgName)}`,\n );\n const latest = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const version = latest ? data?.versions?.[latest] || {} : {};\n const repository = version?.repository || data?.repository;\n let repoUrl = \"\";\n if (typeof repository === \"string\") repoUrl = repository;\n else if (repository?.url) repoUrl = repository.url;\n repoUrl = repoUrl.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n return {\n latest,\n description: String(version?.description || data?.description || \"\").trim(),\n keywords: Array.isArray(version?.keywords) ? version.keywords : [],\n homepage: String(version?.homepage || data?.homepage || \"\").trim(),\n repository: repoUrl,\n readme: String(data?.readme || \"\").trim(),\n license: String(version?.license || data?.license || \"\").trim(),\n };\n } catch {\n return null;\n }\n}\n\nexport async function checkUpdates(): Promise<UpdateAvailable[]> {\n const installed = listInstalledPackages();\n const metas = await Promise.all(\n installed.map(async (pkg) => {\n const meta = await fetchNpmMeta(pkg.name);\n return { pkg, meta };\n }),\n );\n\n const updates: UpdateAvailable[] = [];\n for (const { pkg, meta } of metas) {\n if (!meta || !meta.latest) continue;\n if (meta.latest === pkg.version) continue;\n updates.push({\n name: pkg.name,\n type: pkg.type,\n shortName: pkg.shortName,\n current: pkg.version,\n latest: meta.latest,\n });\n }\n return updates;\n}\n\nexport interface UpdatedPackageResult {\n name: string;\n before: string;\n after: string;\n changed: boolean;\n}\n\nfunction snapshotVersions(names: string[]): Map<string, string> {\n const map = new Map<string, string>();\n for (const name of names) {\n map.set(name, getInstalledVersion(name));\n }\n return map;\n}\n\nexport async function updatePackages(names: string[]): Promise<BunRunResult> {\n if (names.length === 0) return { code: 0, stdout: \"\", stderr: \"\" };\n return runBun([\"update\", ...names, \"--latest\"]);\n}\n\nexport async function updateAllManaged(): Promise<{\n result: BunRunResult;\n names: string[];\n}> {\n const managed = listInstalledPackages()\n .filter((pkg) => pkg.type !== \"framework\")\n .map((pkg) => pkg.name);\n if (managed.length === 0) {\n return { result: { code: 0, stdout: \"\", stderr: \"\" }, names: [] };\n }\n return { result: await updatePackages(managed), names: managed };\n}\n\nexport function diffVersions(\n names: string[],\n before: Map<string, string>,\n): UpdatedPackageResult[] {\n return names.map((name) => {\n const after = getInstalledVersion(name);\n const prev = before.get(name) || \"0.0.0\";\n return { name, before: prev, after, changed: prev !== after };\n });\n}\n\nexport function snapshotAll(names: string[]): Map<string, string> {\n return snapshotVersions(names);\n}\n\nfunction appendToMiokuPlugins(pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n const packageJsonPath = path.join(projectRoot(), \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n const pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (plugins.includes(shortName)) return false;\n plugins.push(shortName);\n pkg.mioku = { ...mioku, plugins };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nfunction removeFromMiokuPlugins(pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n const packageJsonPath = path.join(projectRoot(), \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n const pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (!plugins.includes(shortName)) return false;\n pkg.mioku = {\n ...mioku,\n plugins: plugins.filter((name: string) => name !== shortName),\n };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nfunction normalizeTargetName(type: \"plugin\" | \"service\", name: string): string {\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n return name.startsWith(prefix) ? name : `${prefix}${name}`;\n}\n\nexport interface InstallResult {\n ok: boolean;\n packageName: string;\n enabled: boolean;\n output: string;\n error?: string;\n}\n\nexport async function installPackage(\n type: \"plugin\" | \"service\",\n name: string,\n): Promise<InstallResult> {\n const packageName = normalizeTargetName(type, name);\n logger.info(`[core] 开始安装 ${type} 包: ${packageName}`);\n const result = await runBun([\"add\", packageName]);\n if (result.code !== 0) {\n logger.error(`[core] 安装 ${packageName} 失败: ${result.stderr || result.stdout}`);\n return {\n ok: false,\n packageName,\n enabled: false,\n output: result.stdout || result.stderr,\n error: result.stderr || result.stdout || \"安装失败\",\n };\n }\n let enabled = false;\n if (type === \"plugin\") {\n enabled = appendToMiokuPlugins(packageName);\n }\n const installedVersion = getInstalledVersion(packageName);\n logger.info(\n `[core] 安装成功 ${packageName}@${installedVersion}${enabled ? \"(已启用)\" : \"\"}`,\n );\n return {\n ok: true,\n packageName,\n enabled,\n output: result.stdout || result.stderr,\n };\n}\n\nexport interface UninstallResult {\n ok: boolean;\n packageName: string;\n removedFromConfig: boolean;\n output: string;\n error?: string;\n}\n\nexport async function uninstallPackage(\n type: \"plugin\" | \"service\",\n name: string,\n): Promise<UninstallResult> {\n const packageName = normalizeTargetName(type, name);\n logger.info(`[core] 开始卸载 ${type} 包: ${packageName}`);\n const result = await runBun([\"remove\", packageName]);\n if (result.code !== 0) {\n logger.error(`[core] 卸载 ${packageName} 失败: ${result.stderr || result.stdout}`);\n return {\n ok: false,\n packageName,\n removedFromConfig: false,\n output: result.stdout || result.stderr,\n error: result.stderr || result.stdout || \"卸载失败\",\n };\n }\n let removedFromConfig = false;\n if (type === \"plugin\") {\n removedFromConfig = removeFromMiokuPlugins(packageName);\n }\n logger.info(\n `[core] 卸载成功 ${packageName}${removedFromConfig ? \"(已从配置移除)\" : \"\"}`,\n );\n return {\n ok: true,\n packageName,\n removedFromConfig,\n output: result.stdout || result.stderr,\n };\n}\n\nexport async function fetchOfficialRegistry(): Promise<OfficialRegistry> {\n return fetchJson(OFFICIAL_REGISTRY_URL);\n}\n\nasync function searchNpmPackages(): Promise<NpmSearchObject[]> {\n const url = `${NPM_REGISTRY}/-/v1/search?text=mioku&size=250`;\n const data = (await fetchJson(url)) as { objects?: NpmSearchObject[] };\n return data.objects || [];\n}\n\nfunction extractKeywords(raw: unknown): string[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .map((item) => String(item || \"\").trim())\n .filter((item) => item && item !== \"mioku\");\n}\n\nfunction buildMarketItem(\n pkgName: string,\n meta: NpmPackageMeta | null,\n official: boolean,\n): MarketItem {\n const type = detectType(pkgName) as \"plugin\" | \"service\";\n const installedVersion = getInstalledVersion(pkgName);\n const installed =\n installedVersion !== \"0.0.0\" && installedVersion !== \"\";\n const latest = String(meta?.latest || \"\");\n return {\n name: shortNameOf(pkgName),\n npm: pkgName,\n type,\n description: meta?.description || \"暂无介绍\",\n latest,\n installed,\n installedVersion: installed ? installedVersion : \"\",\n hasUpdate: installed && latest !== \"\" && latest !== installedVersion,\n tags: extractKeywords(meta?.keywords).slice(0, 4),\n official,\n homepage: meta?.homepage || \"\",\n repo: meta?.repository || \"\",\n };\n}\n\nexport async function getMarketItems(\n type: \"plugin\" | \"service\",\n): Promise<MarketItem[]> {\n const registry = await fetchOfficialRegistry();\n const officialEntries =\n type === \"plugin\" ? registry.plugins || {} : registry.services || {};\n const officialNpmNames = new Set(\n Object.values(officialEntries)\n .map((entry) => String(entry?.npm || \"\"))\n .filter(Boolean),\n );\n\n const searchObjects = await searchNpmPackages().catch(() => [] as NpmSearchObject[]);\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n\n const candidateNames = new Set<string>();\n for (const obj of searchObjects) {\n const name = String(obj?.package?.name || \"\");\n if (name.startsWith(prefix)) candidateNames.add(name);\n }\n for (const name of officialNpmNames) {\n if (name.startsWith(prefix)) candidateNames.add(name);\n }\n\n const metas = await Promise.all(\n Array.from(candidateNames).map(async (pkgName) => {\n const meta = await fetchNpmMeta(pkgName);\n return { pkgName, meta, official: officialNpmNames.has(pkgName) };\n }),\n );\n\n const items = metas\n .filter((entry) => entry.meta !== null)\n .filter((entry) => (entry.meta?.keywords ?? []).includes(\"mioku\"))\n .map((entry) =>\n buildMarketItem(entry.pkgName, entry.meta, entry.official),\n );\n\n return items.sort((a, b) => {\n if (a.installed !== b.installed) return a.installed ? -1 : 1;\n if (a.official !== b.official) return a.official ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n}\n","import * as path from \"path\";\nimport { existsSync, mkdirSync } from \"fs\";\n\n/** 插件数据目录:`data/<pluginName>/` */\nexport function getPluginDataDir(pluginName: string): string {\n return path.join(process.cwd(), \"data\", pluginName);\n}\n\n/** 服务数据目录:`data/<serviceName>/` */\nexport function getServiceDataDir(serviceName: string): string {\n return path.join(process.cwd(), \"data\", serviceName);\n}\n\n/** 全局数据目录:`data/` */\nexport function getDataDir(): string {\n return path.join(process.cwd(), \"data\");\n}\n\n/** 插件配置目录:`config/<pluginName>/` */\nexport function getPluginConfigDir(pluginName: string): string {\n return path.join(process.cwd(), \"config\", pluginName);\n}\n\n/** 服务配置目录:`config/service/<serviceName>/` */\nexport function getServiceConfigDir(serviceName: string): string {\n return path.join(process.cwd(), \"config\", \"service\", serviceName);\n}\n\n/** 全局配置目录:`config/` */\nexport function getConfigDir(): string {\n return path.join(process.cwd(), \"config\");\n}\n\n/** 确保插件数据目录存在,返回目录路径 */\nexport function ensureDataDir(pluginName: string): string {\n const dir = getPluginDataDir(pluginName);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n return dir;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { formatDuration } from \"../../../utils\";\nimport { rootLogger as logger } from \"../../../logger\";\nimport { connectedBots } from \"../../../compat\";\nimport { getPluginDataDir } from \"../../../internal/data-paths\";\n\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\n\nconst isInPm2: boolean = Boolean(\n typeof process !== \"undefined\" && (process.env.PM2_HOME || process.env.PM2 || process.env.pm_id),\n);\n\nconst RESTART_MARKER_PATH = path.join(getPluginDataDir(\"core\"), \"restart.json\");\n\nexport interface RestartMarker {\n initiatedAt: number;\n selfId: number;\n groupId: number | null;\n userId: number;\n}\n\nfunction ensureDataDir(): void {\n const dir = path.dirname(RESTART_MARKER_PATH);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n\nexport function writeRestartMarker(marker: RestartMarker): void {\n ensureDataDir();\n fs.writeFileSync(\n RESTART_MARKER_PATH,\n JSON.stringify(marker, null, 2),\n \"utf-8\",\n );\n}\n\nexport function consumeRestartMarker(): RestartMarker | null {\n if (!fs.existsSync(RESTART_MARKER_PATH)) return null;\n try {\n const raw = fs.readFileSync(RESTART_MARKER_PATH, \"utf-8\");\n const parsed = JSON.parse(raw) as RestartMarker;\n fs.rmSync(RESTART_MARKER_PATH, { force: true });\n return parsed;\n } catch {\n fs.rmSync(RESTART_MARKER_PATH, { force: true });\n return null;\n }\n}\n\nfunction tempDir(): string {\n const dir = path.join(process.cwd(), \"temp\");\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nfunction shellQuote(value: string): string {\n return `'${String(value).replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction writeRestartScript(): string {\n const cwd = process.cwd();\n const bun = process.execPath;\n const args = process.argv.slice(1);\n\n if (process.platform === \"win32\") {\n const scriptPath = path.join(tempDir(), \"mioku-restart.bat\");\n const quotedArgs = [bun, ...args].map((a) => `\"${a}\"`).join(\" \");\n const content = [\n \"@echo off\",\n \"ping -n 3 127.0.0.1 >nul\",\n `cd /d \"${cwd}\"`,\n `start \"mioku\" ${quotedArgs}`,\n \"del %~f0\",\n ].join(\"\\r\\n\");\n fs.writeFileSync(scriptPath, content, \"utf-8\");\n return scriptPath;\n }\n\n const scriptPath = path.join(tempDir(), \"mioku-restart.sh\");\n const execLine = [shellQuote(bun), ...args.map(shellQuote)].join(\" \");\n const content = [\n \"#!/usr/bin/env sh\",\n \"sleep 2\",\n `cd ${shellQuote(cwd)} || exit 1`,\n `exec ${execLine}`,\n ].join(\"\\n\");\n fs.writeFileSync(scriptPath, content, \"utf-8\");\n fs.chmodSync(scriptPath, 0o755);\n return scriptPath;\n}\n\nexport function cleanupStaleRestartScripts(): void {\n const dir = tempDir();\n for (const name of [\"mioku-restart.sh\", \"mioku-restart.bat\"]) {\n const file = path.join(dir, name);\n if (fs.existsSync(file)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n // ignore\n }\n }\n }\n}\n\nexport function triggerRestart(marker: RestartMarker): void {\n writeRestartMarker(marker);\n\n if (isInPm2) {\n logger.info(\"[core] 检测到 PM2 环境,退出进程后将由 PM2 自动重启\");\n setTimeout(() => process.exit(0), 300);\n return;\n }\n\n const scriptPath = writeRestartScript();\n try {\n const child = spawn(\n process.platform === \"win32\" ? \"cmd.exe\" : \"sh\",\n process.platform === \"win32\" ? [\"/c\", scriptPath] : [scriptPath],\n { detached: true, stdio: \"ignore\" },\n );\n child.unref();\n logger.info(`[core] 重启脚本已启动: ${scriptPath}`);\n } catch (error) {\n logger.error(`[core] 启动重启脚本失败: ${error}`);\n }\n\n setTimeout(() => process.exit(0), 500);\n}\n\nexport function formatUptime(ms: number): string {\n return formatDuration(ms);\n}\n\nasync function waitForBot(timeoutMs = 60000): Promise<any | null> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const bots = Array.from(connectedBots.values());\n if (bots.length > 0) return bots[0];\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n return null;\n}\n\nexport async function notifyRestartComplete(\n ctx: MiokuContext | undefined,\n marker: RestartMarker,\n): Promise<void> {\n const bot = await waitForBot();\n if (!bot) {\n logger.warn(\"[core] 重启完成但未等到 bot 上线,跳过通知\");\n return;\n }\n\n const duration = Date.now() - marker.initiatedAt;\n const message = `Bot重启成功!用时${formatDuration(duration)}`;\n const segment = ctx?.segment;\n\n try {\n const payload = segment ? [segment.text(message)] : [];\n if (marker.groupId) {\n await bot.sendMessage({ type: \"group\", group_id: marker.groupId}, payload);\n } else if (marker.userId) {\n await bot.sendMessage({ type: \"private\", user_id: marker.userId}, payload);\n }\n } catch (error) {\n ctx?.logger?.error?.(`[core] 发送重启完成通知失败: ${error}`);\n }\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { getPluginRuntimeState } from \"../../../runtime/plugin-state\";\nimport { replyText } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport {\n checkUpdates,\n diffVersions,\n snapshotAll,\n updateAllManaged,\n updatePackages,\n type UpdateAvailable,\n} from \"../system/package-manager\";\nimport { triggerRestart, type RestartMarker } from \"../system/restart\";\n\nconst SELECT_TIMEOUT_MS = 60000;\n\ninterface PendingSelection {\n disposer: () => void;\n timer: ReturnType<typeof setTimeout>;\n items: UpdateAvailable[];\n}\n\nconst RUNTIME_KEY = \"updateSelections\";\n\nfunction getPendingMap(): Map<string, PendingSelection> {\n const state = getPluginRuntimeState(\"core\");\n if (!state[RUNTIME_KEY]) {\n state[RUNTIME_KEY] = new Map<string, PendingSelection>();\n }\n return state[RUNTIME_KEY] as Map<string, PendingSelection>;\n}\n\nfunction conversationKey(event: any): string {\n const selfId = Number(event?.self_id || 0);\n if (event?.message_type === \"group\" && event?.group_id) {\n return `${selfId}:g:${event.group_id}`;\n }\n return `${selfId}:p:${event?.user_id || 0}`;\n}\n\nfunction typeLabel(type: string): string {\n if (type === \"plugin\") return \"plugin\";\n if (type === \"service\") return \"service\";\n return \"框架\";\n}\n\nfunction renderUpdateList(items: UpdateAvailable[]): string {\n const lines = items.map((item, idx) => {\n const label = typeLabel(item.type);\n return `${idx + 1}. [${label}] ${item.shortName} ${item.current} → ${item.latest}`;\n });\n return [\n \"以下包存在可用更新\",\n ...lines,\n \"\",\n \"用空格隔开需要更新的包编号,回复 all 更新全部\",\n ].join(\"\\n\");\n}\n\nfunction parseSelection(\n text: string,\n total: number,\n): { all: boolean; indices: number[] } {\n const normalized = text.trim().toLowerCase();\n if (normalized === \"all\" || normalized === \"全部\") {\n return { all: true, indices: [] };\n }\n const indices: number[] = [];\n for (const token of normalized.split(/\\s+/)) {\n if (!token) continue;\n const num = Number(token);\n if (Number.isInteger(num) && num >= 1 && num <= total) {\n indices.push(num - 1);\n }\n }\n return { all: false, indices: Array.from(new Set(indices)) };\n}\n\nasync function performUpdateAndReport(\n ctx: MiokuContext,\n event: any,\n names: string[],\n): Promise<void> {\n if (names.length === 0) {\n await replyText(event, \"没有需要更新的项。\");\n return;\n }\n const before = snapshotAll(names);\n await replyText(event, `正在更新 ${names.length} 个包,请稍候...`);\n const result = await updatePackages(names);\n if (result.code !== 0) {\n ctx.logger.error(`[core] 更新失败: ${result.stderr || result.stdout}`);\n await replyText(event, `更新失败:${result.stderr || result.stdout}`);\n return;\n }\n const diffs = diffVersions(names, before);\n const changed = diffs.filter((d) => d.changed);\n const unchanged = diffs.filter((d) => !d.changed);\n\n if (changed.length === 0) {\n await replyText(event, \"更新完成,所有包均已是最新版本\");\n return;\n }\n\n const lines = changed.map((d) => `• ${d.name}: ${d.before} → ${d.after}`);\n const parts = [`更新完成,共 ${changed.length} 个包已升级:`, ...lines];\n if (unchanged.length > 0) {\n parts.push(\"\", `另有 ${unchanged.length} 个包已是最新`);\n }\n parts.push(\"\", \"即将重启...\");\n await replyText(event, parts.join(\"\\n\"));\n\n const selfId = Number(event?.self_id || 0);\n const groupId =\n event?.message_type === \"group\" && event?.group_id\n ? Number(event.group_id)\n : null;\n const userId = Number(event?.user_id || 0);\n const marker: RestartMarker = {\n initiatedAt: Date.now(),\n selfId,\n groupId,\n userId,\n };\n triggerRestart(marker);\n}\n\nexport function registerUpdateCommands(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n if (!text.startsWith(`${prefix}update`)) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] update 指令仅主人可用\");\n return;\n }\n\n const arg = text.slice(prefix.length + \"update\".length).trim();\n const selfId = String(event?.self_id || \"\");\n const bot = event.bot;\n if (!bot) return;\n\n if (arg === \"all\") {\n const managed = await updateAllManaged();\n if (managed.names.length === 0) {\n await replyText(event, \"未找到可更新的 mioku 包\");\n return;\n }\n await performUpdateAndReport(ctx, event, managed.names);\n return;\n }\n\n if (arg === \"mioku\" || arg === \"self\") {\n await performUpdateAndReport(ctx, event, [\"mioku\"]);\n return;\n }\n\n if (arg.startsWith(\"plugin \") || arg.startsWith(\"service \")) {\n const [typeRaw, ...rest] = arg.split(/\\s+/);\n const name = rest.join(\" \").trim();\n const type = typeRaw === \"plugin\" ? \"plugin\" : \"service\";\n if (!name) {\n await replyText(event, `用法:${prefix}update ${type} <名称>`);\n return;\n }\n const pkgPrefix = type === \"plugin\" ? \"mioku-plugin-\" : \"mioku-service-\";\n const fullName = name.startsWith(pkgPrefix) ? name : `${pkgPrefix}${name}`;\n await performUpdateAndReport(ctx, event, [fullName]);\n return;\n }\n\n if (arg === \"check\" || arg === \"检查\") {\n const pending = getPendingMap();\n const key = conversationKey(event);\n const existing = pending.get(key);\n if (existing) {\n existing.disposer();\n clearTimeout(existing.timer);\n pending.delete(key);\n }\n\n let items: UpdateAvailable[];\n try {\n items = await checkUpdates();\n } catch (error) {\n ctx.logger.error(`[core] 检查更新失败: ${error}`);\n await replyText(event, `检查更新失败:${String(error)}`);\n return;\n }\n\n if (items.length === 0) {\n await replyText(event, \"所有插件与服务均已是最新版本\");\n return;\n }\n\n await replyText(event, renderUpdateList(items));\n\n const timeoutMs = SELECT_TIMEOUT_MS;\n const listenerDispose = ctx.handle(\"message\", async (ev: any) => {\n if (String(ev?.self_id || \"\") !== selfId) return;\n if (conversationKey(ev) !== key) return;\n if (!isEventOwner(ev)) return;\n\n const evText = ctx.text(ev)?.trim() || \"\";\n if (evText.startsWith(`${prefix}update`)) return;\n\n const sel = pending.get(key);\n if (!sel) return;\n\n clearTimeout(sel.timer);\n sel.disposer();\n pending.delete(key);\n\n const parsed = parseSelection(evText, sel.items.length);\n const chosen = parsed.all\n ? sel.items\n : parsed.indices.map((i) => sel.items[i]).filter(Boolean);\n\n if (chosen.length === 0) {\n await replyText(event, \"未选择任何有效项,已取消\");\n return;\n }\n await performUpdateAndReport(\n ctx,\n event,\n chosen.map((i) => i.name),\n );\n });\n\n const timer = setTimeout(async () => {\n const sel = pending.get(key);\n if (!sel) return;\n sel.disposer();\n pending.delete(key);\n await replyText(event, \"操作超时,已取消更新\");\n }, timeoutMs);\n\n pending.set(key, { disposer: listenerDispose, timer, items });\n return;\n }\n\n await replyText(\n event,\n `用法:\\n${prefix}update check 检查并选择更新\\n${prefix}update all 更新全部\\n${prefix}update mioku 更新框架\\n${prefix}update plugin <名称>\\n${prefix}update service <名称>`,\n );\n });\n\n return () => {\n dispose();\n const pending = getPendingMap();\n for (const sel of pending.values()) {\n clearTimeout(sel.timer);\n sel.disposer();\n }\n pending.clear();\n };\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { replyText } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport { installPackage, uninstallPackage } from \"../system/package-manager\";\n\nfunction parseTargetArgs(\n text: string,\n head: string,\n): { type: \"plugin\" | \"service\"; name: string } | null {\n if (!text.startsWith(head)) return null;\n const rest = text.slice(head.length).trim();\n const matched = rest.match(/^(plugin|service)\\s+([\\s\\S]+)$/);\n if (!matched) return null;\n const name = matched[2].trim();\n if (!name) return null;\n return { type: matched[1] as \"plugin\" | \"service\", name };\n}\n\nfunction typeLabel(type: \"plugin\" | \"service\"): string {\n return type === \"plugin\" ? \"插件\" : \"服务\";\n}\n\nexport function registerInstallCommands(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n const installHead = `${prefix}install`;\n const uninstallHead = `${prefix}uninstall`;\n if (!text.startsWith(installHead) && !text.startsWith(uninstallHead))\n return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] install/uninstall 指令仅主人可用\");\n return;\n }\n\n if (text.startsWith(installHead)) {\n const parsed = parseTargetArgs(text, installHead);\n if (!parsed) {\n await replyText(\n event,\n `用法:${prefix}install plugin <名称> 或 ${prefix}install service <名称>`,\n );\n return;\n }\n await replyText(\n event,\n `正在从 npm 安装${typeLabel(parsed.type)} ${parsed.name}...`,\n );\n try {\n const result = await installPackage(parsed.type, parsed.name);\n if (!result.ok) {\n ctx.logger.error(`[core] 安装失败: ${result.error || result.output}`);\n await replyText(event, `安装失败:${result.error || result.output}`);\n return;\n }\n const lines = [\n `已安装 ${result.packageName}`,\n result.enabled ? \"已在 plugins 中启用\" : \"\",\n \"重启后生效\",\n ].filter(Boolean);\n await replyText(event, lines.join(\"\\n\"));\n } catch (error) {\n ctx.logger.error(`[core] 安装失败: ${error}`);\n await replyText(event, `安装失败:${String(error)}`);\n }\n return;\n }\n\n const parsed = parseTargetArgs(text, uninstallHead);\n if (!parsed) {\n await replyText(\n event,\n `用法:${prefix}uninstall plugin <名称> 或 ${prefix}uninstall service <名称>`,\n );\n return;\n }\n await replyText(\n event,\n `正在卸载${typeLabel(parsed.type)} ${parsed.name}...`,\n );\n try {\n const result = await uninstallPackage(parsed.type, parsed.name);\n if (!result.ok) {\n ctx.logger.error(`[core] 卸载失败: ${result.error || result.output}`);\n await replyText(event, `卸载失败:${result.error || result.output}`);\n return;\n }\n const lines = [\n `已卸载 ${result.packageName}`,\n result.removedFromConfig ? \"已从 plugins 中移除\" : \"\",\n \"重启后生效\",\n ].filter(Boolean);\n await replyText(event, lines.join(\"\\n\"));\n } catch (error) {\n ctx.logger.error(`[core] 卸载失败: ${error}`);\n await replyText(event, `卸载失败:${String(error)}`);\n }\n });\n\n return dispose;\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { replyText, sendTextOrForward } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport { getMarketItems } from \"../system/package-manager\";\n\nfunction renderMarketText(\n kind: \"plugin\" | \"service\",\n items: Awaited<ReturnType<typeof getMarketItems>>,\n): string {\n const label = kind === \"plugin\" ? \"插件\" : \"服务\";\n const lines = items.map((item) => {\n const status = item.installed\n ? item.hasUpdate\n ? `可更新 ${item.installedVersion}→${item.latest}`\n : `已安装 ${item.installedVersion}`\n : `未安装${item.latest ? `(最新 ${item.latest})` : \"\"}`;\n return `• ${item.name} [${status}]\\n ${item.description}`;\n });\n return [`Mioku ${label}市场(共 ${items.length} 个)`, ...lines].join(\"\\n\");\n}\n\nexport function registerMarketCommands(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n\n const prefix = getCommandPrefix();\n const kind: \"plugin\" | \"service\" | null =\n text === `${prefix}plugin-market` || text === `${prefix}插件市场`\n ? \"plugin\"\n : text === `${prefix}service-market` || text === `${prefix}服务市场`\n ? \"service\"\n : null;\n if (!kind) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] market 指令仅主人可用\");\n return;\n }\n\n let items;\n try {\n items = await getMarketItems(kind);\n } catch (error) {\n ctx.logger.error(`[core] 获取市场信息失败: ${error}`);\n await replyText(event, `获取市场失败:${String(error)}`);\n return;\n }\n\n await sendTextOrForward({\n ctx,\n event,\n text: renderMarketText(kind, items),\n source: `Mioku ${kind === \"plugin\" ? \"插件\" : \"服务\"}市场`,\n summary: `共 ${items.length} 个`,\n });\n });\n\n return dispose;\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { replyText } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport {\n formatUptime,\n triggerRestart,\n type RestartMarker,\n} from \"../system/restart\";\n\nexport function registerRestartCommand(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n if (text !== `${prefix}restart` && text !== `${prefix}重启`) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] restart 指令仅主人可用\");\n return;\n }\n\n const uptimeMs = process.uptime() * 1000;\n const selfId = Number(event?.self_id || 0);\n const groupId =\n event?.message_type === \"group\" && event?.group_id\n ? Number(event.group_id)\n : null;\n const userId = Number(event?.user_id || 0);\n\n const marker: RestartMarker = {\n initiatedAt: Date.now(),\n selfId,\n groupId,\n userId,\n };\n\n try {\n await replyText(event, `Bot已运行${formatUptime(uptimeMs)},正在重启...`);\n } catch (error) {\n ctx.logger.warn(`[core] 发送重启提示失败: ${error}`);\n }\n\n ctx.logger.info(`[core] 正在执行重启命令 ${formatUptime(uptimeMs)}`);\n triggerRestart(marker);\n });\n\n return dispose;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { getCommandPrefix } from \"./prefix\";\nimport { replyText } from \"./notify\";\n\nconst LOG_LINE_COUNT = 100;\nconst LINES_PER_NODE = 20;\n\nfunction getLogDir(): string {\n return path.join(process.cwd(), \"logs\");\n}\n\nfunction getActiveLogFile(): string | null {\n const dir = getLogDir();\n if (!fs.existsSync(dir)) return null;\n let latest: { path: string; mtime: number } | null = null;\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isFile() || !entry.name.endsWith(\".log\")) continue;\n const full = path.join(dir, entry.name);\n const mtime = fs.statSync(full).mtimeMs;\n if (!latest || mtime > latest.mtime) {\n latest = { path: full, mtime };\n }\n }\n return latest?.path ?? null;\n}\n\nfunction readLastLines(filePath: string, count: number): string[] {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const lines = content.split(/\\r?\\n/).filter((line) => line.length > 0);\n return lines.slice(-count);\n}\n\nfunction chunk<T>(arr: T[], size: number): T[][] {\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n result.push(arr.slice(i, i + size));\n }\n return result;\n}\n\nexport function registerLogCommand(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n if (text !== `${prefix}log` && text !== `${prefix}日志`) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] 日志指令仅主人可用\");\n return;\n }\n\n const selfId = String(event?.self_id || \"\");\n const bot = event.bot;\n if (!bot) return;\n\n const logFile = getActiveLogFile();\n if (!logFile) {\n await replyText(event, \"未找到日志文件。\");\n return;\n }\n\n let lines: string[];\n try {\n lines = readLastLines(logFile, LOG_LINE_COUNT);\n } catch (error) {\n ctx.logger.error(`[core] 读取日志失败: ${error}`);\n await replyText(event, `读取日志失败:${String(error)}`);\n return;\n }\n if (lines.length === 0) {\n await replyText(event, \"日志为空。\");\n return;\n }\n\n let infoCount = 0;\n let warnCount = 0;\n let errorCount = 0;\n for (const line of lines) {\n if (/\\bERROR\\b|\\berror\\b/i.test(line)) {\n errorCount++;\n } else if (/\\bWARN\\b|\\bwarn\\b/i.test(line)) {\n warnCount++;\n } else if (/\\bINFO\\b|\\binfo\\b/i.test(line)) {\n infoCount++;\n }\n }\n const summary = `info ${infoCount} warn ${warnCount} error ${errorCount}`;\n\n const chunks = chunk(lines, LINES_PER_NODE);\n\n const nodes = chunks.map((chunkLines, idx) => ({\n user_id: selfId,\n nickname: `第${idx + 1}条日志`,\n content: [ctx.segment.text(chunkLines.join(\"\\n\"))],\n }));\n\n try {\n const target =\n event?.message_type === \"group\" && event?.group_id\n ? { type: \"group\" as const, group_id: event.group_id }\n : event?.user_id\n ? { type: \"private\" as const, user_id: event.user_id }\n : undefined;\n if (target) {\n await bot.sendForward(target, nodes, {\n source: \"最近100条运行日志\",\n summary,\n });\n }\n } catch (error) {\n ctx.logger.error(`[core] 发送日志转发失败: ${error}`);\n await replyText(event, `发送日志失败:${String(error)}`);\n }\n });\n return dispose;\n}\n","import type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport type { CorePluginConfig } from \"../config\";\nimport { isPrivilegedUser } from \"../access/privileged\";\n\nexport function registerAutoApprove(\n ctx: MiokuContext,\n getConfig: () => CorePluginConfig,\n): () => void {\n const offFriend = ctx.handle(\"request.friend\", async (event) => {\n if (!getConfig().friend.autoApprove) {\n return;\n }\n\n try {\n await event.approve();\n ctx.logger.info(`已自动通过好友申请: ${event.user_id}`);\n } catch (error) {\n ctx.logger.warn(`自动通过好友申请失败: ${error}`);\n }\n });\n\n const offGroup = ctx.handle(\"request.group.invite\", async (event) => {\n if (!isPrivilegedUser(event?.user_id)) {\n return;\n }\n\n try {\n await event.approve();\n ctx.logger.info(`已自动通过主人/管理员拉群邀请: ${event.user_id}`);\n } catch (error) {\n ctx.logger.warn(`自动通过主人/管理员拉群邀请失败: ${error}`);\n }\n });\n\n return () => {\n offFriend();\n offGroup();\n };\n}\n","import { rootLogger as logger } from \"../../../logger\";\nimport { triggerRestart, type RestartMarker } from \"./restart\";\nimport { listInstalledPackages, updatePackages } from \"./package-manager\";\n\nlet autoUpdateTimer: ReturnType<typeof setInterval> | null = null;\nlet running = false;\n\nexport function startAutoUpdateScheduler(\n enabled: boolean,\n time: string,\n frequency: \"daily\" | \"weekly\" | \"monthly\",\n): () => void {\n if (autoUpdateTimer) {\n clearInterval(autoUpdateTimer);\n autoUpdateTimer = null;\n }\n\n if (!enabled) return () => {};\n\n const [hour, minute] = time.split(\":\").map(Number);\n if (isNaN(hour) || isNaN(minute)) {\n logger.warn(`[core] 自动更新时间格式无效: ${time},调度器未启动`);\n return () => {};\n }\n\n logger.info(\n `[core] 自动更新调度器已启动: 频率=${frequency}, 时间=${time}`,\n );\n\n autoUpdateTimer = setInterval(async () => {\n if (running) return;\n const now = new Date();\n\n if (now.getHours() !== hour || now.getMinutes() !== minute) return;\n\n if (frequency === \"weekly\" && now.getDay() !== 1) return;\n if (frequency === \"monthly\" && now.getDate() !== 1) return;\n\n running = true;\n try {\n logger.info(\"[core] 自动更新开始...\");\n const allInstalled = listInstalledPackages();\n const names = allInstalled.map((pkg) => pkg.name);\n if (names.length === 0) {\n logger.info(\"[core] 未找到需要更新的包\");\n return;\n }\n\n const result = await updatePackages(names);\n if (result.code !== 0) {\n logger.error(\n `[core] 自动更新失败: ${result.stderr || result.stdout}`,\n );\n return;\n }\n\n logger.info(\"[core] 自动更新成功,准备重启...\");\n const marker: RestartMarker = {\n initiatedAt: Date.now(),\n selfId: 0,\n groupId: null,\n userId: 0,\n };\n triggerRestart(marker);\n } catch (error) {\n logger.error(`[core] 自动更新异常: ${error}`);\n } finally {\n running = false;\n }\n }, 60000);\n\n return () => {\n if (autoUpdateTimer) {\n clearInterval(autoUpdateTimer);\n autoUpdateTimer = null;\n }\n };\n}\n","import { version } from '../../../package.json' with { type: 'json' }\nimport { definePlugin } from '../../plugin'\nimport { createCmd, dedent, unique } from '../../utils'\nimport { isEventOwner, isEventOwnerOrAdmin } from '../../runtime/mioku-context'\nimport { getService } from '../../services/define'\nimport { Services } from '../../services/builtin'\nimport { rootLogger as logger } from '../../logger'\nimport {\n getPluginMetadataList,\n setPluginMetadata,\n} from '../../runtime/plugin-metadata'\nimport { getPluginRuntimeState, setPluginRuntimeState } from '../../runtime/plugin-state'\nimport { buildMiokuStatus, formatMiokuStatus } from './status'\nimport { buildAdapterReport, collectBotStats, formatAdapterReport } from './adapters'\nimport {\n CORE_DEFAULT_CONFIG,\n cloneConfig,\n normalizeCoreConfig,\n type CorePluginConfig,\n} from './config'\nimport { ensureAccessControlConfig } from './access/access-store'\nimport { normalizeAccessConfig } from './access/access-config'\nimport { matchMessageCommands } from './access/matcher'\nimport { registerLikeCommand } from './commands/like'\nimport { registerMinMemberCheck } from './commands/min-member'\nimport { registerUpdateCommands } from './commands/update'\nimport { registerInstallCommands } from './commands/install'\nimport { registerMarketCommands } from './commands/market'\nimport { registerRestartCommand } from './commands/restart'\nimport { registerLogCommand } from './commands/log'\nimport { registerAutoApprove } from './commands/auto-approve'\nimport {\n cleanupStaleRestartScripts,\n consumeRestartMarker,\n notifyRestartComplete,\n} from './system/restart'\nimport { startAutoUpdateScheduler } from './system/auto-update'\n\nimport type { Adapter, MessageSegment } from '../../adapter'\nimport type { MessageEvent } from '../../adapter'\nimport type { AccessHook, AccessControlConfig, PluginHelp, PluginMetadata } from '../../types'\nimport type { MiokuStatus } from './status'\nimport type { StatusProvider } from './adapters'\nimport type { MiokuPlugin } from '../../plugin'\nimport type { MiokuContext } from '../../runtime/mioku-context'\n\nexport type { MiokuStatus } from './status'\nexport type { StatusProvider } from './adapters'\n\nexport const CORE_PLUGINS = ['mioku-core']\n\ntype AdapterEntry = {\n name: string\n version?: string\n impl?: { name: string; version?: string }\n}\n\nexport const formatMiokuStatusFn = formatMiokuStatus\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[-_.^$?[\\]{}()|\\\\]/g, '\\\\$&')\n}\n\nconst CORE_HELP_ENTRIES: ReadonlyArray<readonly [cmd: string, desc: string]> = [\n ['help', '显示帮助信息'],\n ['status', '显示框架状态'],\n ['adapter', '显示适配器与连接实例'],\n ['plugin', '插件管理'],\n ['settings', '框架设置管理'],\n ['update', '检查并选择插件/服务更新'],\n ['install', '从 npm 安装插件/服务'],\n ['uninstall', '卸载插件/服务'],\n ['plugin-market', '查看插件市场'],\n ['service-market', '查看服务市场'],\n ['restart', '重启机器人进程'],\n ['log', '查看最近100条日志'],\n ['exit', '退出框架进程'],\n]\n\nfunction displayWidth(value: string): number {\n let width = 0\n for (const ch of value) {\n width += /[\\u1100-\\u115F\\u2E80-\\uA4CF\\uAC00-\\uD7A3\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFF60\\uFFE0-\\uFFE6]/.test(ch) ? 2 : 1\n }\n return width\n}\n\nfunction padColumn(value: string, width: number): string {\n const gap = width - displayWidth(value)\n if (gap <= 0) return value\n // 只用全角空格(固定 2 格宽);半角空格在 QQ 字体里几乎不占宽,会导致错位\n return value + ' '.repeat(Math.ceil(gap / 2))\n}\n\nfunction buildCoreHelpText(displayPrefix: string): string {\n const cmds = CORE_HELP_ENTRIES.map(([cmd]) => `${displayPrefix}${cmd}`)\n const cmdWidth = Math.max(...cmds.map(displayWidth))\n const lines = CORE_HELP_ENTRIES.map(\n ([cmd, desc], i) => `${padColumn(cmds[i], cmdWidth)} ${desc}`,\n )\n return ['〓 💡 Mioku 帮助 〓', ...lines].join('\\n')\n}\n\nfunction buildCoreMetadata(\n ctx: MiokuContext,\n displayPrefix: string,\n likeKeyword: string,\n): PluginMetadata {\n const esc = escapeRegExp(displayPrefix)\n const ownerHelp = (cmd: string, desc: string): PluginHelp['commands'][number] => ({\n cmd: `${displayPrefix}${cmd}`,\n desc,\n role: 'master',\n })\n\n const help: PluginHelp = {\n title: '系统',\n description: 'Mioku 内置核心插件:系统命令与管理功能',\n commands: CORE_HELP_ENTRIES.map(([cmd, desc]) => ownerHelp(cmd, desc)),\n }\n\n const accessHooks: AccessHook[] = [\n { id: 'like', match: likeKeyword, description: '匹配赞我指令关键字' },\n { id: 'help', match: `/^${esc}(help|帮助)$/`, description: '匹配帮助指令' },\n { id: 'status', match: `/^${esc}(status|状态)$/`, description: '匹配状态指令' },\n { id: 'adapter', match: `/^${esc}(adapter|适配器)$/`, description: '匹配适配器指令' },\n { id: 'plugin', match: `/^${esc}(plugin|插件)/`, description: '匹配插件管理指令' },\n { id: 'settings', match: `/^${esc}(settings|设置)/`, description: '匹配设置管理指令' },\n { id: 'update', match: `/^${esc}(update|更新)/`, description: '匹配更新指令' },\n { id: 'install', match: `/^${esc}(install|安装)/`, description: '匹配安装指令' },\n { id: 'uninstall', match: `/^${esc}(uninstall|卸载)/`, description: '匹配卸载指令' },\n {\n id: 'market',\n match: `/^${esc}(plugin-market|service-market|插件市场|服务市场)$/`,\n description: '匹配插件/服务市场指令',\n },\n { id: 'restart', match: `/^${esc}(restart|重启)$/`, description: '匹配重启指令' },\n { id: 'log', match: `/^${esc}(log|日志)$/`, description: '匹配日志指令' },\n { id: 'exit', match: `/^${esc}(exit|退出)$/`, description: '匹配退出指令' },\n ]\n\n return {\n name: 'core',\n version,\n description: 'mioku 内置核心插件',\n path: '',\n packageJson: {},\n config: { help, accessHooks },\n }\n}\n\nconst core: MiokuPlugin = definePlugin({\n name: 'mioku-core',\n version,\n priority: -Infinity,\n description: 'mioku 内置核心插件',\n async setup(ctx: MiokuContext) {\n const rawPrefix = ctx.config.prefix ?? '.'\n const cmdPrefix = new RegExp(`^${escapeRegExp(rawPrefix)}`)\n const displayPrefix = rawPrefix\n const statusAdminOnly = ctx.config.status_permission === 'admin-only'\n\n logger.info('========================================')\n logger.info(' Mioku 正在引导服务...')\n logger.info('========================================')\n\n const disposers: Array<() => void> = []\n const configService = getService(ctx, Services.Config)\n\n let baseConfig: CorePluginConfig = cloneConfig(CORE_DEFAULT_CONFIG)\n if (configService) {\n await configService.registerConfig('core', 'base', baseConfig)\n const nextConfig = await configService.getConfig('core', 'base')\n if (nextConfig) {\n baseConfig = normalizeCoreConfig(nextConfig)\n }\n disposers.push(\n configService.onConfigChange('core', 'base', (next) => {\n baseConfig = normalizeCoreConfig(next)\n }),\n )\n } else {\n ctx.logger.warn('config-service 未加载,core 插件将使用默认配置')\n }\n\n let accessRules: AccessControlConfig = ensureAccessControlConfig()\n if (configService) {\n await configService.registerConfig('core', 'access-control', accessRules)\n const persisted = await configService.getConfig('core', 'access-control')\n if (persisted) {\n accessRules = normalizeAccessConfig(persisted)\n }\n disposers.push(\n configService.onConfigChange('core', 'access-control', (next) => {\n accessRules = normalizeAccessConfig(next)\n }),\n )\n }\n logger.info(`访问控制已挂载: ${ctx.bots.length} 个 bot`)\n\n setPluginMetadata(\n buildCoreMetadata(ctx, displayPrefix, String(baseConfig.likeCommand.keyword || '赞我')),\n )\n\n const coreState = getPluginRuntimeState('core')\n coreState.matchMessageCommands = (text: string) =>\n matchMessageCommands(getPluginMetadataList(), text)\n setPluginRuntimeState('core', coreState)\n\n cleanupStaleRestartScripts()\n const restartMarker = consumeRestartMarker()\n if (restartMarker) {\n notifyRestartComplete(ctx, restartMarker).catch((err) => {\n ctx.logger.error(`[core] 重启完成通知失败: ${err}`)\n })\n }\n\n disposers.push(registerLikeCommand(ctx, () => baseConfig))\n disposers.push(registerAutoApprove(ctx, () => baseConfig))\n disposers.push(registerMinMemberCheck(ctx, () => baseConfig))\n disposers.push(registerUpdateCommands(ctx))\n disposers.push(registerInstallCommands(ctx))\n disposers.push(registerMarketCommands(ctx))\n disposers.push(registerRestartCommand(ctx))\n disposers.push(registerLogCommand(ctx))\n disposers.push(\n startAutoUpdateScheduler(\n baseConfig.autoUpdate.enabled,\n baseConfig.autoUpdate.time,\n baseConfig.autoUpdate.frequency,\n ),\n )\n\n const collectBots = (): typeof ctx.bots => ctx.bots\n /** 已加载的适配器优先,再补上只在 bot 上出现过的适配器名 */\n const collectAdapters = (): AdapterEntry[] => {\n const describe = (name: string, adapter?: Adapter): AdapterEntry => ({\n name,\n version: adapter?.version,\n impl: adapter?.impl ? { name: adapter.impl.name, version: adapter.impl.version } : undefined,\n })\n const list = ctx.adapters.map((adapter) => describe(adapter.name, adapter))\n const seen = new Set(list.map((adapter) => adapter.name))\n for (const bot of ctx.bots) {\n const name = String(bot.adapter)\n if (seen.has(name)) continue\n seen.add(name)\n list.push(describe(name, ctx.getAdapter(name)))\n }\n return list\n }\n\n const getStatus = async (): Promise<MiokuStatus> => {\n const enabled = ctx.plugins.list().length\n const total = ctx.plugins.list().length + ctx.plugins.localPlugins().length\n const bots = collectBots()\n const botStats = bots.length\n ? collectBotStats(await buildAdapterReport({ bots, adapters: collectAdapters() }))\n : undefined\n return await buildMiokuStatus({\n bots,\n botStats,\n enabledPlugins: enabled,\n totalPlugins: total,\n })\n }\n\n const getAdapterText = async (): Promise<string> =>\n formatAdapterReport(await buildAdapterReport({ bots: collectBots(), adapters: collectAdapters() }))\n\n const atTarget = (event: MessageEvent): string | undefined => {\n const at = event.message.find((seg): seg is MessageSegment & { data: Record<string, unknown> } => seg.type === 'at')\n const qq = at?.data?.qq ?? at?.data?.target\n return qq != null ? String(qq) : undefined\n }\n\n disposers.push(\n ctx.handle('message', async (event) => {\n const ev = event as MessageEvent\n const text = ev.message.text()\n\n if (!cmdPrefix.test(text)) return\n\n if (statusAdminOnly && !isEventOwnerOrAdmin(ev)) return\n\n const bare = text.replace(cmdPrefix, '').trim()\n\n if (bare === '状态' || bare === 'status') {\n await ev.reply(await formatMiokuStatus(await getStatus()))\n return\n }\n\n if (bare === '适配器' || bare === 'adapter') {\n await ev.reply(await getAdapterText())\n return\n }\n\n if (!isEventOwner(ev)) return\n\n const { cmd, params } = createCmd(text)\n if (!cmd) return\n\n const subCmd = cmd.replace(cmdPrefix, '').replace(/\\s+/g, '')\n const target = params[0]\n\n switch (subCmd) {\n case 'help':\n case '帮助': {\n await ev.reply(buildCoreHelpText(displayPrefix))\n break\n }\n\n case 'plugin':\n case '插件': {\n if (CORE_PLUGINS.includes(target)) {\n await ev.reply('内置插件无法操作')\n return\n }\n\n switch (target) {\n case 'list':\n case '列表': {\n const enabled = ctx.plugins.list()\n const plugins = unique([...ctx.plugins.localPlugins(), ...enabled.map((e) => e.name)])\n .map((name) => {\n const entry = enabled.find((e) => e.name === name)\n const tag = entry ? '🟢' : '🔴'\n const type = entry?.type === 'builtin' ? '[内置]' : '[用户]'\n return `${tag} ${type} ${name}`\n })\n .sort((pre, next) => {\n const weight = (str: string): number => {\n let w = 0\n if (str.includes('🟢')) w += 10\n if (str.includes('[内置]')) w += 1\n return w\n }\n return weight(next) - weight(pre) || pre.localeCompare(next)\n })\n\n await ev.reply(\n dedent(`\n 〓 插件列表 〓\n ${plugins.join('\\n')}\n 共 ${plugins.length} 个,启用 ${enabled.length} 个\n `).trim(),\n )\n break\n }\n\n case 'enable':\n case '启用': {\n const pluginName = params[1]\n if (!pluginName) {\n await ev.reply('请指定插件 ID')\n return\n }\n try {\n await ctx.plugins.enable(pluginName)\n } catch (err) {\n await ev.reply(`插件 ${pluginName} 启用失败:${err instanceof Error ? err.message : '未知错误'}`)\n return\n }\n await ctx.updateConfig((c) => {\n c.plugins = [...c.plugins, pluginName]\n })\n await ev.reply(`插件 ${pluginName} 启用成功`)\n break\n }\n\n case 'disable':\n case '禁用': {\n const pluginName = params[1]\n if (!pluginName) {\n await ev.reply('请指定插件 ID')\n return\n }\n try {\n await ctx.plugins.disable(pluginName)\n } catch (err) {\n await ev.reply(err instanceof Error ? err.message : String(err))\n return\n }\n await ctx.updateConfig((c) => {\n c.plugins = c.plugins.filter((name) => name !== pluginName)\n })\n await ev.reply(`插件 ${pluginName} 已禁用`)\n break\n }\n\n case 'reload':\n case '重载': {\n const pluginName = params[1]\n if (!pluginName) {\n await ev.reply('请指定插件 ID')\n return\n }\n try {\n await ctx.plugins.reload(pluginName)\n } catch (err) {\n await ev.reply(err instanceof Error ? err.message : String(err))\n return\n }\n await ctx.updateConfig((c) => {\n c.plugins = [...c.plugins, pluginName]\n })\n await ev.reply(`插件 ${pluginName} 已重载`)\n break\n }\n\n default: {\n await ev.reply(\n dedent(`\n 〓 🧩 mioku 插件 〓\n ${displayPrefix}plugin list\n ${displayPrefix}plugin enable <ID>\n ${displayPrefix}plugin disable <ID>\n ${displayPrefix}plugin reload <ID>\n `).trim(),\n )\n break\n }\n }\n break\n }\n\n case 'settings':\n case '设置': {\n const action = target\n switch (action) {\n case 'detail':\n case '详情': {\n await ev.reply(\n dedent(`\n 〓 设置详情 〓\n 主人: ${ctx.config.owners.join(', ') || '(无)'}\n 管理: ${ctx.config.admins.join(', ') || '(无)'}\n 启用插件: ${ctx.config.plugins.join(', ') || '(无)'}\n `).trim(),\n )\n break\n }\n\n case 'add-owner':\n case '加主人':\n case '添加主人': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定主人 QQ/AT')\n return\n }\n const userId = String(uid)\n if (ctx.config.owners.includes(userId)) {\n await ev.reply(`主人 ${uid} 已存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.owners = [...c.owners, userId]\n })\n await ev.reply(`已添加主人 ${uid}`)\n break\n }\n\n case 'remove-owner':\n case '删主人':\n case '删除主人': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定主人 QQ/AT')\n return\n }\n const userId = String(uid)\n if (userId === ctx.config.owners[0]) {\n await ev.reply('不能删除第一主人')\n return\n }\n if (!ctx.config.owners.includes(userId)) {\n await ev.reply(`主人 ${uid} 不存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.owners = c.owners.filter((id) => id !== userId)\n })\n await ev.reply(`已删除主人 ${uid}`)\n break\n }\n\n case 'add-admin':\n case '加管理':\n case '添加管理': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定管理 QQ/AT')\n return\n }\n const userId = String(uid)\n if (ctx.config.admins.includes(userId)) {\n await ev.reply(`管理 ${uid} 已存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.admins = [...c.admins, userId]\n })\n await ev.reply(`已添加管理 ${uid}`)\n break\n }\n\n case 'remove-admin':\n case '删管理':\n case '删除管理': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定管理 QQ/AT')\n return\n }\n const userId = String(uid)\n if (!ctx.config.admins.includes(userId)) {\n await ev.reply(`管理 ${uid} 不存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.admins = c.admins.filter((id) => id !== userId)\n })\n await ev.reply(`已删除管理 ${uid}`)\n break\n }\n\n default: {\n await ev.reply(\n dedent(`\n 〓 ⚙️ mioku 设置 〓\n ${displayPrefix}settings detail\n ${displayPrefix}settings [add-owner|remove-owner] <QQ/AT>\n ${displayPrefix}settings [add-admin|remove-admin] <QQ/AT>\n `).trim(),\n )\n break\n }\n }\n break\n }\n\n case 'exit':\n case '退出': {\n await ev.reply('またね~')\n ctx.logger.info('接收到退出指令,即将退出... 如需自动重启,请使用 pm2 部署。')\n process.exit(0)\n }\n }\n }),\n )\n\n logger.info('========================================')\n logger.info(' Mioku 服务初始化完成')\n logger.info('========================================')\n\n return async () => {\n for (const dispose of disposers) {\n dispose()\n }\n\n logger.info('正在关闭 Mioku...')\n }\n },\n})\n\nexport default core\nexport { buildMiokuStatus, formatMiokuStatus } from './status'\nexport { buildAdapterReport, collectBotStats, formatAdapterReport, registerStatusProvider } from './adapters'\n","import core from './core'\n\nimport type { MiokuPlugin } from '../plugin'\n\nexport const BUILTIN_PLUGINS: readonly MiokuPlugin[] = [core]\n\nexport * from './core'\n","import { rootLogger as logger } from \"../logger\";\nimport type {\n AccessHook,\n PluginHelp,\n PluginMetadata,\n PluginPackageConfig,\n} from \"../types\";\nimport type { PackageJsonLike } from \"../types\";\n\nconst PLUGIN_CONFIG_KEYS = new Set([\n \"services\",\n \"help\",\n \"accessHooks\",\n]);\n\nconst ACCESS_HOOK_KEYS = new Set([\n \"id\",\n \"match\",\n \"event\",\n \"description\",\n]);\n\nconst HELP_KEYS = new Set([\"title\", \"description\", \"commands\"]);\n\nconst HELP_COMMAND_KEYS = new Set([\"cmd\", \"desc\", \"usage\", \"role\"]);\n\nfunction warnUnknownFields(\n prefix: string,\n obj: Record<string, unknown>,\n allowed: Set<string>,\n): void {\n for (const key of Object.keys(obj)) {\n if (!allowed.has(key)) {\n logger.warn(`[plugin-manifest] ${prefix} 含未知字段 \"${key}\"(将被忽略)`);\n }\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction validateHelp(value: unknown, pluginName: string): PluginHelp | undefined {\n if (value === undefined) return undefined;\n if (!isPlainObject(value)) {\n logger.warn(`[plugin-manifest] ${pluginName}.help 必须是对象,已忽略`);\n return undefined;\n }\n warnUnknownFields(`${pluginName}.help`, value, HELP_KEYS);\n\n const title = String(value.title ?? \"\").trim();\n const description = String(value.description ?? \"\").trim();\n const rawCommands = value.commands;\n\n if (!title) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.title 缺失或为空`);\n }\n if (!description) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.description 缺失或为空`);\n }\n if (!Array.isArray(rawCommands)) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.commands 必须是数组`);\n return { title, description, commands: [] };\n }\n\n const commands: PluginHelp[\"commands\"] = [];\n for (const cmd of rawCommands) {\n if (!isPlainObject(cmd)) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.commands 项不是对象`);\n continue;\n }\n warnUnknownFields(\n `${pluginName}.help.commands[]`,\n cmd,\n HELP_COMMAND_KEYS,\n );\n const cmdName = String(cmd.cmd ?? \"\").trim();\n const desc = String(cmd.desc ?? \"\").trim();\n if (!cmdName || !desc) {\n logger.warn(\n `[plugin-manifest] ${pluginName}.help.commands 项缺少 cmd 或 desc`,\n );\n continue;\n }\n commands.push({\n cmd: cmdName,\n desc,\n usage: typeof cmd.usage === \"string\" ? cmd.usage : undefined,\n role: typeof cmd.role === \"string\" ? (cmd.role as never) : undefined,\n });\n }\n\n return { title, description, commands };\n}\n\nfunction validateAccessHooks(\n value: unknown,\n pluginName: string,\n): AccessHook[] | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n logger.warn(`[plugin-manifest] ${pluginName}.accessHooks 必须是数组`);\n return undefined;\n }\n\n const hooks: AccessHook[] = [];\n for (const hook of value) {\n if (!isPlainObject(hook)) {\n logger.warn(`[plugin-manifest] ${pluginName}.accessHooks 项不是对象`);\n continue;\n }\n warnUnknownFields(\n `${pluginName}.accessHooks[]`,\n hook,\n ACCESS_HOOK_KEYS,\n );\n const id = String(hook.id ?? \"\").trim();\n if (!id) {\n logger.warn(\n `[plugin-manifest] ${pluginName}.accessHooks 项缺少 id,已忽略`,\n );\n continue;\n }\n hooks.push({\n id,\n match: typeof hook.match === \"string\" ? hook.match : undefined,\n event: typeof hook.event === \"string\" ? hook.event : undefined,\n description:\n typeof hook.description === \"string\" ? hook.description : undefined,\n });\n }\n return hooks;\n}\n\nexport function validatePluginPackageConfig(\n raw: unknown,\n pluginName: string,\n): PluginPackageConfig {\n const config: PluginPackageConfig = {};\n\n if (raw === undefined || raw === null) {\n return config;\n }\n if (!isPlainObject(raw)) {\n logger.warn(\n `[plugin-manifest] ${pluginName} 的 mioku 字段必须是对象,已使用空配置`,\n );\n return config;\n }\n\n warnUnknownFields(`${pluginName}.mioku`, raw, PLUGIN_CONFIG_KEYS);\n\n if (raw.services !== undefined) {\n if (Array.isArray(raw.services)) {\n const services = raw.services.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n const dropped = raw.services.length - services.length;\n if (dropped > 0) {\n logger.warn(\n `[plugin-manifest] ${pluginName}.services 丢弃 ${dropped} 个非字符串项`,\n );\n }\n config.services = services;\n } else {\n logger.warn(`[plugin-manifest] ${pluginName}.services 必须是字符串数组`);\n }\n }\n\n const help = validateHelp(raw.help, pluginName);\n if (help) config.help = help;\n\n const hooks = validateAccessHooks(raw.accessHooks, pluginName);\n if (hooks) config.accessHooks = hooks;\n\n return config;\n}\n\nexport const buildPluginMetadata = (\n name: string,\n resolvedPath: string,\n packageJson: PackageJsonLike,\n): PluginMetadata => ({\n name,\n version: packageJson.version ?? \"0.0.0\",\n description: packageJson.description,\n path: resolvedPath,\n packageJson,\n config: validatePluginPackageConfig(packageJson.mioku, name),\n});","import fs from 'node:fs'\nimport path from 'node:path'\nimport { createRequire } from 'node:module'\nimport { pathToFileURL } from 'node:url'\n\nimport type { AdapterDefinition } from '../adapter'\nimport { validatePluginPackageConfig } from './manifest'\n\nimport type { PluginPackageConfig } from '../types'\n\nexport interface PackageJson {\n readonly name?: string\n readonly version?: string\n readonly description?: string\n readonly main?: string\n readonly module?: string\n readonly exports?: unknown\n readonly dependencies?: Readonly<Record<string, string>>\n readonly devDependencies?: Readonly<Record<string, string>>\n readonly optionalDependencies?: Readonly<Record<string, string>>\n readonly peerDependencies?: Readonly<Record<string, string>>\n readonly keywords?: readonly string[]\n readonly mioku?: unknown\n}\n\nexport interface PackageCandidate {\n readonly name: string\n readonly resolvedPath: string\n readonly packageJson: PackageJson\n}\n\nexport interface AdapterCandidate {\n readonly name: string\n readonly packageName: string\n readonly resolvedPath: string\n readonly packageJson: PackageJson\n readonly apiVersion: number\n readonly entry?: string\n readonly description?: string\n}\n\nexport interface PluginCandidate {\n readonly name: string\n readonly packageName: string\n readonly resolvedPath: string\n readonly packageJson: PackageJson\n readonly apiVersion: number\n readonly priority?: number\n readonly entry?: string\n readonly description?: string\n readonly config: PluginPackageConfig\n}\n\nconst ADAPTER_PACKAGE_PREFIX = 'mioku-adapter-'\nconst PLUGIN_PACKAGE_PREFIX = 'mioku-plugin-'\nconst KNOWN_ENTRY_FALLBACKS = ['dist/index.mjs', 'dist/index.js', 'dist/index.cjs', 'index.mjs', 'index.js']\n\nexport const readPackageJsonSafe = (dir: string): PackageJson | null => {\n const file = path.join(dir, 'package.json')\n if (!fs.existsSync(file)) return null\n try {\n return JSON.parse(fs.readFileSync(file, 'utf-8')) as PackageJson\n } catch {\n return null\n }\n}\n\nconst resolveFromCwd = (cwd: string, name: string): string | null => {\n const require = createRequire(pathToFileURL(path.join(cwd, 'package.json')).href)\n try {\n const entry = require.resolve(`${name}/package.json`)\n return path.dirname(entry)\n } catch {\n return null\n }\n}\n\nconst collectDirectDependencyNames = (pkg: PackageJson): readonly string[] => {\n const set = new Set<string>()\n for (const map of [pkg.dependencies, pkg.devDependencies, pkg.optionalDependencies]) {\n if (!map) continue\n for (const key of Object.keys(map)) set.add(key)\n }\n return Array.from(set)\n}\n\nexport const resolveEntry = (dir: string, pkg: PackageJson, override?: string): string | null => {\n if (override) {\n const abs = path.resolve(dir, override)\n if (fs.existsSync(abs)) return abs\n }\n const candidates: string[] = []\n if (typeof pkg.main === 'string') candidates.push(pkg.main)\n if (typeof pkg.module === 'string' && !candidates.includes(pkg.module)) candidates.push(pkg.module)\n if (typeof pkg.exports === 'string') candidates.push(pkg.exports)\n if (typeof pkg.exports === 'object' && pkg.exports) {\n const exportMap = pkg.exports as Record<string, unknown>\n const mainExport = exportMap['.']\n if (typeof mainExport === 'string') candidates.push(mainExport)\n if (typeof mainExport === 'object' && mainExport) {\n const nodeExport = (mainExport as Record<string, unknown>)['import'] ?? (mainExport as Record<string, unknown>)['default']\n if (typeof nodeExport === 'string') candidates.push(nodeExport)\n }\n }\n for (const candidate of candidates) {\n const abs = path.resolve(dir, candidate)\n if (fs.existsSync(abs)) return abs\n }\n for (const fallback of KNOWN_ENTRY_FALLBACKS) {\n const abs = path.join(dir, fallback)\n if (fs.existsSync(abs)) return abs\n }\n return null\n}\n\nexport const discoverAdapterCandidates = (cwd: string, appPackageJson: PackageJson): readonly AdapterCandidate[] => {\n const deps = collectDirectDependencyNames(appPackageJson)\n const seen = new Set<string>()\n const candidates: AdapterCandidate[] = []\n for (const dep of deps) {\n if (!dep.startsWith(ADAPTER_PACKAGE_PREFIX)) continue\n const dir = resolveFromCwd(cwd, dep)\n if (!dir) continue\n const pkg = readPackageJsonSafe(dir)\n if (!pkg) continue\n const adapterName = dep.slice(ADAPTER_PACKAGE_PREFIX.length)\n if (seen.has(adapterName)) {\n throw new Error(`Adapter name conflict: \"${adapterName}\" appears in multiple direct dependencies`)\n }\n seen.add(adapterName)\n candidates.push({\n name: adapterName,\n packageName: dep,\n resolvedPath: dir,\n packageJson: pkg,\n apiVersion: 1,\n description: pkg.description,\n })\n }\n return candidates\n}\n\nexport const discoverPluginCandidates = (cwd: string, appPackageJson: PackageJson): readonly PluginCandidate[] => {\n const deps = collectDirectDependencyNames(appPackageJson)\n const seen = new Set<string>()\n const candidates: PluginCandidate[] = []\n for (const dep of deps) {\n if (!dep.startsWith(PLUGIN_PACKAGE_PREFIX)) continue\n const dir = resolveFromCwd(cwd, dep)\n if (!dir) continue\n const pkg = readPackageJsonSafe(dir)\n if (!pkg) continue\n const pluginName = dep.slice(PLUGIN_PACKAGE_PREFIX.length)\n if (seen.has(pluginName)) {\n throw new Error(`Plugin canonical ID conflict: \"${pluginName}\" appears in multiple direct dependencies`)\n }\n seen.add(pluginName)\n candidates.push({\n name: pluginName,\n packageName: dep,\n resolvedPath: dir,\n packageJson: pkg,\n apiVersion: 1,\n description: pkg.description,\n config: validatePluginPackageConfig(pkg.mioku, pluginName),\n })\n }\n return candidates\n}\n\nexport const resolveLocalPluginPath = (cwd: string, pluginsDir: string, name: string): string | null => {\n const root = path.resolve(cwd, pluginsDir)\n if (!fs.existsSync(root)) return null\n const candidate = path.join(root, name)\n if (!fs.existsSync(candidate)) return null\n return candidate\n}\n\nexport const resolveLocalPluginEntry = (dir: string): string | null => {\n const pkg = readPackageJsonSafe(dir)\n const indexTs = path.join(dir, 'index.ts')\n if (fs.existsSync(indexTs)) return indexTs\n const candidates: string[] = []\n if (pkg?.main) candidates.push(pkg.main)\n if (pkg?.module && !candidates.includes(pkg.module)) candidates.push(pkg.module)\n candidates.push('index.js', 'index.cjs', 'index.mjs')\n for (const candidate of candidates) {\n const abs = path.resolve(dir, candidate)\n if (fs.existsSync(abs)) return abs\n }\n return null\n}\n\nexport const findLocalPlugins = (cwd: string, pluginsDir: string): readonly { name: string; absPath: string }[] => {\n const root = path.resolve(cwd, pluginsDir)\n if (!fs.existsSync(root)) return []\n return fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && !!entry.name && !entry.name.startsWith('_'))\n .map((entry) => ({\n name: entry.name,\n absPath: path.join(root, entry.name),\n }))\n}\n\nexport interface LoadedAdapterDefinition {\n readonly candidate: AdapterCandidate\n readonly definition: AdapterDefinition<unknown>\n}\n\nexport interface LoadedPluginDefinition {\n readonly candidate: PluginCandidate | { name: string; resolvedPath: string; entry: string; packageJson: PackageJson }\n readonly module: unknown\n}\n","import { pathToFileURL } from 'node:url'\nimport { createRequire } from 'node:module'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { createJiti, type Jiti } from 'jiti'\n\nimport type { AdapterDefinition } from '../adapter'\nimport type { AdapterCandidate, LoadedAdapterDefinition, PackageJson } from './package'\nimport { resolveEntry } from './package'\n\nconst isAdapterDefinition = (value: unknown): value is AdapterDefinition<unknown> => {\n if (!value || typeof value !== 'object') return false\n const v = value as Partial<AdapterDefinition<unknown>>\n return typeof v.name === 'string' && typeof v.version === 'string' && typeof v.apiVersion === 'number' && typeof v.create === 'function'\n}\n\nconst readDependencyNames = (cwd: string): string[] => {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8')) as PackageJson\n return [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ...Object.keys(pkg.optionalDependencies ?? {}),\n ]\n } catch {\n return []\n }\n}\n\nconst resolveAliases = (cwd: string): Record<string, string> => {\n const require = createRequire(path.join(cwd, 'package.json'))\n const aliases: Record<string, string> = {}\n for (const name of readDependencyNames(cwd)) {\n try {\n aliases[name] = require.resolve(name)\n } catch {\n // 忽略无法解析的依赖\n }\n }\n return aliases\n}\n\nexport const createImportContext = (cwd: string): Jiti => {\n return createJiti(cwd, {\n extensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs', '.jsx'],\n cache: false,\n fsCache: false,\n moduleCache: false,\n requireCache: false,\n sourceMaps: false,\n interopDefault: true,\n jsx: { importSource: 'react', runtime: 'automatic' },\n alias: resolveAliases(cwd),\n })\n}\n\nexport const loadAdapterDefinition = async (\n jiti: Jiti,\n candidate: AdapterCandidate,\n): Promise<LoadedAdapterDefinition> => {\n const entry = resolveEntry(candidate.resolvedPath, candidate.packageJson as PackageJson, candidate.entry)\n if (!entry) {\n throw new Error(`Adapter \"${candidate.name}\" has no resolvable entry point`)\n }\n const mod = await jiti.import(pathToFileURL(entry).href)\n const exported = (mod as { default?: unknown }).default ?? mod\n if (!isAdapterDefinition(exported)) {\n throw new Error(`Adapter \"${candidate.name}\" does not export a valid AdapterDefinition`)\n }\n if (exported.name !== candidate.name) {\n throw new Error(`Adapter name mismatch: manifest=\"${candidate.name}\" export=\"${exported.name}\"`)\n }\n if (exported.apiVersion !== candidate.apiVersion) {\n throw new Error(\n `Adapter \"${candidate.name}\" apiVersion mismatch: manifest=${candidate.apiVersion} export=${exported.apiVersion}`,\n )\n }\n return { candidate, definition: exported }\n}","import { pathToFileURL } from 'node:url'\nimport type { Jiti } from 'jiti'\n\nimport type { MiokuPlugin } from '../plugin'\nimport type { PluginCandidate } from './package'\nimport { resolveEntry, resolveLocalPluginEntry } from './package'\n\nexport const isMiokuPlugin = (value: unknown): value is MiokuPlugin => {\n if (!value || typeof value !== 'object') return false\n const v = value as Partial<MiokuPlugin>\n return typeof v.name === 'string' && (v.setup === undefined || typeof v.setup === 'function')\n}\n\nconst loadFromEntry = async (jiti: Jiti, entry: string, name: string): Promise<MiokuPlugin> => {\n const mod = await jiti.import(pathToFileURL(entry).href)\n const exported = (mod as { default?: unknown }).default ?? mod\n if (!isMiokuPlugin(exported)) {\n throw new Error(`Plugin \"${name}\" does not export a valid MiokuPlugin (need \"name\" and optional \"setup\")`)\n }\n if (exported.name !== name) {\n throw new Error(\n `Plugin canonical ID mismatch: manifest=\"${name}\" export=\"${exported.name}\". Ensure plugin.name matches the manifest`,\n )\n }\n return exported\n}\n\nexport const loadNpmPlugin = async (\n jiti: Jiti,\n candidate: PluginCandidate,\n): Promise<MiokuPlugin> => {\n const entry = resolveEntry(candidate.resolvedPath, candidate.packageJson, candidate.entry)\n if (!entry) {\n throw new Error(`Plugin \"${candidate.name}\" has no resolvable entry point`)\n }\n return await loadFromEntry(jiti, entry, candidate.name)\n}\n\nexport const loadLocalPlugin = async (\n jiti: Jiti,\n name: string,\n resolvedPath: string,\n): Promise<MiokuPlugin> => {\n const entry = resolveLocalPluginEntry(resolvedPath)\n if (!entry) {\n throw new Error(`Local plugin \"${name}\" has no entry point`)\n }\n return await loadFromEntry(jiti, entry, name)\n}","import type { Event, MessageEvent } from \"../adapter\";\n\ninterface Entry {\n adapter: string;\n bucket: number;\n at: number;\n}\n\nconst BUCKET_SLACK = 1;\nconst PRUNE_INTERVAL = 128;\nconst TTL_MS = 15_000;\nconst MAX_SIZE = 4096;\nconst MAX_SEGMENTS = 16;\nconst MAX_TEXT = 256;\n\n/**\n * 把消息段序列化为跨适配器稳定的内容指纹:\n * 文本/@/表情取内容,媒体段只取类型(url/文件名跨协议不稳定)\n */\nconst contentFingerprintOf = (event: MessageEvent): string => {\n const parts: string[] = [];\n for (const seg of event.message) {\n if (parts.length >= MAX_SEGMENTS) break;\n if (seg.type === \"reply\") continue;\n const data = seg.data ?? {};\n if (seg.type === \"text\") {\n const text = typeof data.text === \"string\" ? data.text : \"\";\n parts.push(`t:${text.slice(0, MAX_TEXT)}`);\n } else if (seg.type === \"at\") {\n const target = data.qq ?? data.target;\n parts.push(`a:${target == null ? \"\" : String(target)}`);\n } else if (seg.type === \"face\") {\n parts.push(`f:${data.id == null ? \"\" : String(data.id)}`);\n } else {\n parts.push(seg.type);\n }\n }\n return parts.join(\"|\");\n};\n\nconst scopeKeyOf = (event: MessageEvent, content: string): string =>\n [\n event.self_id ?? \"\",\n event.message_type ?? \"\",\n event.group_id ?? event.user_id ?? \"\",\n event.user_id ?? \"\",\n content,\n ].join(\"|\");\n\n/**\n * 跨适配器消息去重(L2)\n */\nexport class CrossAdapterMessageDeduplicator {\n readonly #entries = new Map<string, Entry>();\n #inserts = 0;\n #dropped = 0;\n\n /** 本次运行以来被丢弃的跨适配器重复消息数 */\n get dropped(): number {\n return this.#dropped;\n }\n\n isDuplicate(event: Event): boolean {\n if (event.kind !== \"message\") return false;\n const messageEvent = event as MessageEvent;\n const adapter = messageEvent.identity?.adapter ?? \"\";\n const now = Date.now();\n const bucket = Math.floor((messageEvent.time ?? now) / 1000);\n const key = scopeKeyOf(messageEvent, contentFingerprintOf(messageEvent));\n\n const existing = this.#entries.get(key);\n if (existing) {\n if (Math.abs(existing.bucket - bucket) <= BUCKET_SLACK) {\n if (existing.adapter !== adapter) {\n this.#dropped++;\n return true;\n }\n existing.bucket = bucket;\n existing.at = now;\n return false;\n }\n existing.bucket = bucket;\n existing.at = now;\n existing.adapter = adapter;\n return false;\n }\n\n this.#entries.set(key, { adapter, bucket, at: now });\n this.#inserts++;\n if (this.#inserts >= PRUNE_INTERVAL || this.#entries.size > MAX_SIZE) {\n this.#inserts = 0;\n this.#prune(now);\n }\n return false;\n }\n\n #prune(now: number): void {\n for (const [key, entry] of this.#entries) {\n if (now - entry.at > TTL_MS) this.#entries.delete(key);\n }\n }\n\n clear(): void {\n this.#entries.clear();\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { hrtime } from \"node:process\";\n\nimport { colors } from \"consola/utils\";\n\nimport {\n botConfig,\n reloadMiokuConfig,\n setBotCwd,\n updateMiokuConfig,\n} from \"../config\";\nimport { createDefaultDriver, DriverShutdownError } from \"../driver\";\nimport type { Driver } from \"../driver\";\nimport { CapabilityRegistry } from \"../adapter\";\nimport { definePlugin } from \"../plugin\";\nimport type { MiokuPlugin, PluginCleanup } from \"../plugin\";\nimport { BotRegistry } from \"./bots\";\nimport { EventBus } from \"./bus\";\nimport { AdapterContextImpl } from \"./context\";\nimport type { RuntimeAdapterState } from \"./context\";\nimport { MiokuContext } from \"./mioku-context\";\nimport { BUILTIN_PLUGINS as DEFAULT_BUILTIN_PLUGINS } from \"../builtin\";\nimport {\n createImportContext,\n discoverAdapterCandidates,\n discoverPluginCandidates,\n findLocalPlugins,\n loadAdapterDefinition,\n loadLocalPlugin,\n loadNpmPlugin,\n} from \"../loader\";\nimport { buildPluginMetadata } from \"../loader/manifest\";\nimport { readPackageJsonSafe } from \"../loader\";\nimport {\n setPluginMetadata,\n removePluginMetadata,\n resetPluginMetadata,\n} from \"./plugin-metadata\";\n\nimport type { Logger } from \"../logger\";\nimport type { Adapter, AdapterDefinition, BotLifecycleEvent } from \"../adapter\";\nimport type { PluginCandidate } from \"../loader\";\nimport type { Event } from \"../adapter\";\nimport type { Bot } from \"../adapter\";\nimport { CrossAdapterMessageDeduplicator } from \"./cross-adapter-dedup\";\n\nexport interface CreateRuntimeOptions {\n readonly cwd: string;\n readonly logger: Logger;\n readonly builtinPlugins?: readonly MiokuPlugin[];\n readonly driverFactory?: () => Driver;\n /** 去重选项;缺省全部开启 */\n readonly dedup?: {\n /** 跨适配器指纹去重 */\n readonly crossAdapter?: boolean;\n };\n}\n\nexport interface AdapterStartResult {\n readonly name: string;\n readonly adapter: Adapter;\n}\n\nconst BUILTIN_PLUGINS: MiokuPlugin[] = [...DEFAULT_BUILTIN_PLUGINS];\n\nexport const setBuiltinPlugins = (plugins: readonly MiokuPlugin[]): void => {\n BUILTIN_PLUGINS.length = 0;\n BUILTIN_PLUGINS.push(...plugins);\n};\n\nexport const getBuiltinPlugins = (): readonly MiokuPlugin[] => BUILTIN_PLUGINS;\n\nexport class MiokuRuntime {\n readonly #cwd: string;\n readonly #logger: Logger;\n readonly #bus: EventBus;\n readonly #bots: BotRegistry;\n readonly #capabilities: CapabilityRegistry;\n readonly #driver: Driver;\n readonly #adapterStates = new Map<string, RuntimeAdapterState>();\n readonly #enabledAdapters = new Map<string, AdapterDefinition<unknown>>();\n readonly #enabledPlugins = new Map<\n string,\n { cleanup: PluginCleanup | null; plugin: MiokuPlugin }\n >();\n readonly #driverFactory: () => Driver;\n readonly #builtinPlugins: readonly MiokuPlugin[];\n readonly #crossDedup: CrossAdapterMessageDeduplicator | null;\n #started = false;\n #stopped = false;\n\n constructor(options: CreateRuntimeOptions) {\n this.#cwd = path.resolve(options.cwd);\n this.#logger = options.logger;\n this.#driverFactory =\n options.driverFactory ?? (() => createDefaultDriver());\n this.#builtinPlugins = options.builtinPlugins ?? BUILTIN_PLUGINS;\n this.#driver = this.#driverFactory();\n this.#bus = new EventBus();\n this.#bus.setLogger((level, message, detail) => {\n const fn = this.#logger[level] ?? this.#logger.error;\n if (detail === undefined) fn(message);\n else fn(message, detail);\n });\n this.#bots = new BotRegistry();\n this.#capabilities = new CapabilityRegistry();\n this.#crossDedup =\n options.dedup?.crossAdapter === false\n ? null\n : new CrossAdapterMessageDeduplicator();\n }\n\n get cwd(): string {\n return this.#cwd;\n }\n\n get logger(): Logger {\n return this.#logger;\n }\n\n get driver(): Driver {\n return this.#driver;\n }\n\n get bus(): EventBus {\n return this.#bus;\n }\n\n get bots(): readonly Bot[] {\n return this.#bots.all();\n }\n\n get adapters(): readonly Adapter[] {\n return Array.from(this.#adapterStates.values())\n .map((state) => state.instance)\n .filter((a): a is Adapter => a != null);\n }\n\n getAdapter<T extends Adapter = Adapter>(name: string): T | undefined {\n const state = this.#adapterStates.get(name);\n return state?.instance as T | undefined;\n }\n\n pickBot<T extends Bot = Bot>(bot_id: string | number): T | undefined {\n return this.#bots.pick<T>(bot_id);\n }\n\n listPlugins(): Array<{\n name: string;\n type: \"builtin\" | \"external\";\n version?: string;\n }> {\n return Array.from(this.#enabledPlugins.entries()).map(([key, entry]) => {\n const colon = key.indexOf(\":\");\n const type = key.slice(0, colon);\n const name = key.slice(colon + 1);\n return {\n name,\n type: type === \"builtin\" ? \"builtin\" : \"external\",\n version: entry.plugin.version,\n };\n });\n }\n\n async enablePlugin(name: string): Promise<void> {\n const isEnabled =\n this.#enabledPlugins.has(`external:${name}`) ||\n this.#enabledPlugins.has(`builtin:${name}`);\n if (isEnabled) throw new Error(`插件 ${name} 已经是启用状态`);\n const appPkg = this.#readAppPackageJson();\n const jiti = createImportContext(this.#cwd);\n const local = findLocalPlugins(\n this.#cwd,\n botConfig.plugins_dir ?? \"plugins\",\n ).find((p) => p.name === name);\n if (local) {\n const pkg = readPackageJsonSafe(local.absPath) ?? {};\n const plugin = await loadLocalPlugin(jiti, name, local.absPath);\n await this.#loadPlugin(plugin, \"external\");\n setPluginMetadata(buildPluginMetadata(name, local.absPath, pkg));\n return;\n }\n const candidates = discoverPluginCandidates(this.#cwd, appPkg);\n const candidate = candidates.find((c) => c.name === name);\n if (candidate) {\n const plugin = await loadNpmPlugin(jiti, candidate);\n await this.#loadPlugin(plugin, \"external\");\n setPluginMetadata(\n buildPluginMetadata(\n candidate.name,\n candidate.resolvedPath,\n candidate.packageJson,\n ),\n );\n return;\n }\n throw new Error(`插件 ${name} 不存在`);\n }\n\n async disablePlugin(name: string): Promise<void> {\n const key = `external:${name}`;\n const entry = this.#enabledPlugins.get(key);\n if (!entry) {\n if (this.#enabledPlugins.has(`builtin:${name}`))\n throw new Error(`内置插件 ${name} 无法禁用`);\n throw new Error(`插件 ${name} 不存在或未启用`);\n }\n try {\n await entry.cleanup?.();\n } finally {\n this.#enabledPlugins.delete(key);\n removePluginMetadata(name);\n }\n this.#logger.info(`禁用插件 => ${name}`);\n }\n\n async reloadPlugin(name: string): Promise<void> {\n const wasExternal = this.#enabledPlugins.has(`external:${name}`);\n const wasBuiltin = this.#enabledPlugins.has(`builtin:${name}`);\n if (!wasExternal && !wasBuiltin) {\n await this.enablePlugin(name);\n return;\n }\n if (wasBuiltin) {\n const plugin = this.#builtinPlugins.find((p) => p.name === name);\n if (!plugin) throw new Error(`内置插件 ${name} 不存在`);\n await this.#enabledPlugins.get(`builtin:${name}`)?.cleanup?.();\n this.#enabledPlugins.delete(`builtin:${name}`);\n await this.#loadPlugin(plugin, \"builtin\");\n return;\n }\n await this.disablePlugin(name);\n await this.enablePlugin(name);\n }\n\n async #emitLifecycle(event: BotLifecycleEvent): Promise<void> {\n const lifecycleEvent: Event = {\n kind: \"adapter\",\n type: event.type,\n routes: [event.type],\n identity: {\n adapter: event.bot.adapter,\n bot_id: event.bot.bot_id,\n event_type: event.type,\n },\n bot: event.bot,\n self_id: event.bot.bot_id,\n time: Date.now(),\n raw: event,\n payload: event,\n };\n await this.#bus.dispatch(lifecycleEvent);\n }\n\n #createContext(state: RuntimeAdapterState): AdapterContextImpl {\n return new AdapterContextImpl({\n state,\n bots: this.#bots,\n bus: this.#bus,\n driver: this.#driver,\n capabilities: this.#capabilities,\n logger: this.#logger.child({ adapter: state.definition.name }),\n emit: (event) => this.#emitLifecycle(event),\n crossDedup: this.#crossDedup,\n });\n }\n\n async #loadPlugin(\n plugin: MiokuPlugin,\n type: \"builtin\" | \"external\",\n ): Promise<void> {\n const cleanupTasks: PluginCleanup[] = [];\n const ctx = new MiokuContext({\n pluginName: `${type}:${plugin.name}`,\n bus: this.#bus,\n bots: this.#bots,\n driver: this.#driver,\n capabilities: this.#capabilities,\n config: botConfig,\n logger: this.#logger.child({ plugin: plugin.name }),\n priority: plugin.priority ?? 100,\n getAdapter: <T extends Adapter = Adapter>(name: string) =>\n this.getAdapter<T>(name),\n listAdapters: () => this.adapters,\n onUpdateConfig: async (updater) => {\n await updateMiokuConfig(updater);\n },\n pluginManager: {\n list: () => this.listPlugins(),\n localPlugins: () =>\n findLocalPlugins(this.#cwd, botConfig.plugins_dir ?? \"plugins\").map(\n (p) => p.name,\n ),\n enable: (name) => this.enablePlugin(name),\n disable: (name) => this.disablePlugin(name),\n reload: (name) => this.reloadPlugin(name),\n },\n });\n cleanupTasks.push(() => ctx.dispose());\n\n let cleanup: PluginCleanup | null = null;\n try {\n const result = await plugin.setup?.(ctx);\n cleanup = typeof result === \"function\" ? result : null;\n } catch (err) {\n await ctx.dispose();\n throw new Error(\n `Plugin \"${plugin.name}\" setup failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (typeof cleanup === \"function\") cleanupTasks.push(cleanup);\n const wrappedCleanup: PluginCleanup = async () => {\n for (const fn of cleanupTasks) {\n try {\n await fn();\n } catch (err) {\n this.#logger.warn(\n `Plugin \"${plugin.name}\" cleanup error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n };\n this.#enabledPlugins.set(`${type}:${plugin.name}`, {\n cleanup: wrappedCleanup,\n plugin,\n });\n }\n\n async #setupBuiltinPlugins(): Promise<void> {\n this.#logger.info(\n `>>> 加载内置插件: ${this.#builtinPlugins.map((p) => colors.cyan(p.name)).join(\", \")}`,\n );\n for (const plugin of this.#builtinPlugins) {\n try {\n await this.#loadPlugin(plugin, \"builtin\");\n } catch (err) {\n this.#logger.error(err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n async #discoverAdapters(): Promise<void> {\n const appPkg = this.#readAppPackageJson();\n const candidates = discoverAdapterCandidates(this.#cwd, appPkg);\n const enabledNames = Object.keys(botConfig.adapters ?? {}) as string[];\n const candidateByName = new Map(\n candidates.map((candidate) => [candidate.name, candidate]),\n );\n const jiti = createImportContext(this.#cwd);\n for (const name of enabledNames) {\n const candidate = candidateByName.get(name);\n if (!candidate) {\n this.#logger.error(\n `适配器 \"${name}\" 已配置但未安装或不在项目直接依赖中,已跳过`,\n );\n continue;\n }\n try {\n const loaded = await loadAdapterDefinition(jiti, candidate);\n this.#enabledAdapters.set(name, loaded.definition);\n } catch (err) {\n this.#logger.error(\n `适配器 \"${name}\" 加载失败,已跳过: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n #readAppPackageJson(): import(\"../loader/package\").PackageJson {\n const file = `${this.#cwd}/package.json`;\n if (!fs.existsSync(file)) {\n throw new Error(`无法在 ${this.#cwd} 下找到 package.json`);\n }\n return JSON.parse(\n fs.readFileSync(file, \"utf-8\"),\n ) as import(\"../loader/package\").PackageJson;\n }\n\n async #setupPlugins(): Promise<void> {\n const startTime = hrtime.bigint();\n await this.#setupBuiltinPlugins();\n\n const appPkg = this.#readAppPackageJson();\n const enabledIds = new Set<string>(botConfig.plugins.map(String));\n if (enabledIds.size === 0) {\n await this.#logPluginSummary(startTime);\n return;\n }\n\n const candidates = discoverPluginCandidates(this.#cwd, appPkg);\n const candidateByName = new Map<string, PluginCandidate>(\n candidates.map((c) => [c.name, c]),\n );\n\n const localDir = botConfig.plugins_dir ?? \"plugins\";\n const localPlugins = findLocalPlugins(this.#cwd, localDir);\n\n const failed: Array<{ name: string; error: string }> = [];\n const jiti = createImportContext(this.#cwd);\n const tasks: Array<{\n name: string;\n priority: number;\n run: () => Promise<void>;\n }> = [];\n\n for (const id of enabledIds) {\n const npmCandidate = candidateByName.get(id);\n if (npmCandidate) {\n setPluginMetadata(\n buildPluginMetadata(\n npmCandidate.name,\n npmCandidate.resolvedPath,\n npmCandidate.packageJson,\n ),\n );\n try {\n const plugin = await loadNpmPlugin(jiti, npmCandidate);\n tasks.push({\n name: id,\n priority: plugin.priority ?? npmCandidate.priority ?? 100,\n run: async () => {\n await this.#loadPlugin(plugin, \"external\");\n },\n });\n } catch (err) {\n failed.push({\n name: id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n continue;\n }\n const local = localPlugins.find((p) => p.name === id);\n if (!local) {\n failed.push({\n name: id,\n error: `插件 \"${id}\" 未找到(既不在依赖中,也不在本地插件目录中)`,\n });\n continue;\n }\n setPluginMetadata(\n buildPluginMetadata(\n id,\n local.absPath,\n readPackageJsonSafe(local.absPath) ?? {},\n ),\n );\n try {\n const plugin = await loadLocalPlugin(jiti, id, local.absPath);\n tasks.push({\n name: id,\n priority: plugin.priority ?? 100,\n run: async () => {\n await this.#loadPlugin(plugin, \"external\");\n },\n });\n } catch (err) {\n failed.push({\n name: id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const priorityGroups = new Map<number, typeof tasks>();\n for (const task of tasks) {\n const group = priorityGroups.get(task.priority) ?? [];\n group.push(task);\n priorityGroups.set(task.priority, group);\n }\n const priorities = Array.from(priorityGroups.keys()).sort((a, b) => a - b);\n if (priorities.length > 0) {\n this.#logger.info(\n `>>> 加载用户插件: ${priorities\n .map(\n (priority) =>\n `优先级 ${colors.yellow(priority)} (${(priorityGroups.get(priority) ?? []).map((t) => colors.cyan(t.name)).join(\", \")})`,\n )\n .join(\",\")}`,\n );\n }\n for (const priority of priorities) {\n const group = priorityGroups.get(priority) ?? [];\n await Promise.allSettled(group.map((t) => t.run()));\n }\n\n if (failed.length > 0) {\n const summary = failed.map((f) => ` - ${f.name}: ${f.error}`).join(\"\\n\");\n this.#logger.warn(`以下插件加载失败:\\n${summary}`);\n for (const f of failed) removePluginMetadata(f.name);\n }\n\n await this.#logPluginSummary(startTime);\n }\n\n async #logPluginSummary(startTime: bigint): Promise<void> {\n const end = hrtime.bigint();\n const cost = Math.round(Number(end - startTime)) / 1_000_000;\n const enabledCount = this.#enabledPlugins.size;\n this.#logger.info(\n `成功加载了 ${colors.green(enabledCount)} 个插件,总耗时 ${colors.green(cost.toFixed(2))} 毫秒`,\n );\n }\n\n async #startAdapter(name: string): Promise<Adapter> {\n const definition = this.#enabledAdapters.get(name);\n if (!definition) {\n throw new Error(`Adapter \"${name}\" is not enabled`);\n }\n const rawConfig = (botConfig.adapters ?? {})[name];\n let config: unknown = rawConfig;\n if (definition.validateConfig) {\n try {\n config = definition.validateConfig(rawConfig);\n } catch (err) {\n throw new Error(\n `Adapter \"${name}\" config validation failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n const state: RuntimeAdapterState = {\n definition,\n instance: null,\n context: null,\n gateways: [],\n resources: [],\n started: false,\n };\n this.#adapterStates.set(name, state);\n const context = this.#createContext(state);\n state.context = context;\n const adapterLogger = this.#logger.child({ adapter: name });\n let instance: Adapter;\n try {\n const result = definition.create({ config, logger: adapterLogger });\n instance = result instanceof Promise ? await result : result;\n } catch (err) {\n this.#adapterStates.delete(name);\n throw new Error(\n `Adapter \"${name}\" failed to construct: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n state.instance = instance;\n try {\n await instance.start(context);\n await context.waitForStarts();\n state.started = true;\n } catch (err) {\n state.started = false;\n this.#adapterStates.delete(name);\n try {\n await instance.stop(\"startup failed\");\n } catch {\n // ignore\n }\n throw new Error(\n `Adapter \"${name}\" failed to start: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return instance;\n }\n\n async start(): Promise<void> {\n if (this.#started) {\n throw new Error(\"Runtime already started\");\n }\n this.#started = true;\n await this.#discoverAdapters();\n await this.#setupPlugins();\n const adapterNames = Array.from(this.#enabledAdapters.keys());\n const failed: string[] = [];\n for (const name of adapterNames) {\n try {\n const adapter = await this.#startAdapter(name);\n await this.#bus.dispatch({\n kind: \"adapter\",\n type: \"adapter:started\",\n routes: [\"adapter:started\"],\n identity: { adapter: name, event_type: \"adapter:started\" },\n time: Date.now(),\n payload: { name },\n });\n } catch (err) {\n this.#logger.error(\n `适配器 \"${name}\" 启动失败: ${err instanceof Error ? err.message : String(err)}`,\n );\n failed.push(name);\n }\n }\n if (failed.length > 0) {\n this.#logger.warn(\n `以下适配器启动失败,框架将继续运行: ${failed.join(\", \")}`,\n );\n }\n await this.#bus.dispatch({\n kind: \"adapter\",\n type: \"runtime:ready\",\n routes: [\"runtime:ready\"],\n identity: { adapter: \"\" as string, event_type: \"runtime:ready\" },\n time: Date.now(),\n payload: undefined,\n });\n }\n\n async shutdown(reason?: string): Promise<void> {\n if (this.#stopped) return;\n this.#stopped = true;\n await this.#bus.dispatch({\n kind: \"adapter\",\n type: \"runtime:shutdown\",\n routes: [\"runtime:shutdown\"],\n identity: { adapter: \"\" as string, event_type: \"runtime:shutdown\" },\n time: Date.now(),\n payload: reason ? { reason } : undefined,\n });\n const adapters = Array.from(this.#adapterStates.values());\n for (let i = adapters.length - 1; i >= 0; i--) {\n const state = adapters[i];\n if (!state.instance) continue;\n try {\n await state.instance.stop(reason ?? \"shutdown\");\n } catch (err) {\n this.#logger.warn(\n `Adapter \"${state.definition.name}\" stop failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (state.resources) {\n for (let r = state.resources.length - 1; r >= 0; r--) {\n try {\n await state.resources[r].dispose(reason ?? \"shutdown\");\n } catch (err) {\n this.#logger.warn(\n `Resource \"${state.resources[r].name}\" dispose failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n state.resources.length = 0;\n }\n if (state.gateways) {\n for (let g = state.gateways.length - 1; g >= 0; g--) {\n try {\n await state.gateways[g].stop(reason ?? \"shutdown\");\n } catch (err) {\n this.#logger.warn(\n `Gateway \"${state.gateways[g].name}\" stop failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n state.gateways.length = 0;\n }\n }\n for (const [, entry] of this.#enabledPlugins) {\n try {\n await entry.cleanup?.();\n } catch (err) {\n this.#logger.warn(\n `Plugin cleanup failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n this.#enabledPlugins.clear();\n this.#capabilities.clear();\n this.#bots.clear();\n resetPluginMetadata();\n try {\n await this.#driver.shutdown();\n } catch (err) {\n if (!(err instanceof DriverShutdownError)) {\n this.#logger.warn(\n `Driver shutdown error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n}\n\nexport const createRuntime = (options: CreateRuntimeOptions): MiokuRuntime => {\n setBotCwd(options.cwd);\n reloadMiokuConfig();\n return new MiokuRuntime(options);\n};\n\nexport { definePlugin };\n","import type { MiokuContext } from \"./mioku-context\";\nimport { getService } from \"../services/define\";\nimport { Services } from \"../services\";\nimport { servicesRegistry } from \"../services\";\nimport { rootLogger as logger } from \"../logger\";\nimport { getPluginMetadataList } from \"./plugin-metadata\";\nimport type { HelpService } from \"../types\";\n\nexport async function registerPluginArtifacts(\n ctx?: MiokuContext,\n): Promise<void> {\n const helpService = ctx\n ? getService(ctx, Services.Help)\n : (servicesRegistry[\"help\"] as HelpService | undefined);\n const plugins = getPluginMetadataList();\n\n let helpCount = 0;\n for (const meta of plugins) {\n if (meta.config?.help) {\n if (helpService) {\n helpService.registerHelp(meta.name, meta.config.help);\n helpCount++;\n } else {\n logger.warn(\n `[plugin-artifacts] 帮助服务未加载,跳过插件 \"${meta.name}\" 的帮助注册`,\n );\n }\n }\n const required = meta.config?.services;\n if (required && required.length > 0) {\n const missing = required.filter((name) => !servicesRegistry[name]);\n if (missing.length > 0) {\n logger.warn(\n `插件 \"${meta.name}\" 声明依赖服务 [${missing.join(\", \")}],但它们未加载`,\n );\n }\n }\n }\n\n logger.info(\n `[plugin-artifacts] 已处理 ${plugins.length} 个插件的元数据,注册帮助 ${helpCount} 个`,\n );\n}\n","import path from \"node:path\";\nimport { createRuntime, setBuiltinPlugins } from \"./runtime/runtime\";\nimport { createMiokuLogger, rootLogger } from \"./logger\";\nimport { setWritableConfig, botConfig, setBotCwd } from \"./config\";\nimport { version } from \"../package.json\";\nimport { getBuiltinPlugins } from \"./runtime/runtime\";\nimport { unique } from \"./utils\";\nimport { BUILTIN_PLUGINS } from \"./builtin\";\nimport serviceManager from \"./services/manager\";\nimport { registerPluginArtifacts } from \"./runtime/plugin-artifacts\";\nimport { colors } from \"consola/utils\";\n\nimport type { MiokuPlugin } from \"./plugin\";\nimport type { Logger } from \"./logger\";\n\n/** startRuntime 的启动选项 */\nexport interface StartOptions {\n cwd?: string;\n logger?: Logger;\n builtinPlugins?: readonly MiokuPlugin[];\n}\n\n/** 启动 mioku 运行时:加载服务、拉起适配器与插件,返回用于优雅停机的 stop */\nexport const startRuntime = async (\n options: StartOptions = {},\n): Promise<{ stop: (reason?: string) => Promise<void> }> => {\n const cwd = options.cwd ?? process.cwd();\n setBotCwd(cwd);\n setWritableConfig(true);\n\n const builtinPlugins = options.builtinPlugins ?? BUILTIN_PLUGINS;\n setBuiltinPlugins(builtinPlugins);\n const logger = options.logger ?? rootLogger;\n\n process.title = `mioku v${version}`;\n\n const runtime = createRuntime({\n cwd,\n logger,\n builtinPlugins: getBuiltinPlugins(),\n dedup: { crossAdapter: botConfig.dedup?.cross_adapter ?? true },\n });\n\n const pluginDir = path.resolve(cwd, botConfig.plugins_dir ?? \"plugins\");\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(\n `欢迎使用 ${colors.bold(colors.redBright(\"mioku\"))} 💓 ${colors.bold(colors.cyan(`v${version}`))}`,\n );\n logger.info(colors.yellow(colors.underline(\"一个跨平台的插件式机器人框架\")));\n logger.info(colors.cyan(\"轻量 * 跨平台 * 插件式 * 热重载 * 注重开发体验\"));\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(colors.dim(colors.italic(\"作者: Viki & Jerryplusy\")));\n logger.info(\n colors.dim(colors.italic(\"仓库: https://github.com/mioku-lab/mioku\")),\n );\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(`${colors.dim(\"工作目录: \")}${colors.blue(cwd)}`);\n logger.info(`${colors.dim(\"插件目录: \")}${colors.blue(pluginDir)}`);\n logger.info(\n `${colors.dim(\"配置文件: \")}${colors.blue(path.resolve(cwd, \"package.json\"))}`,\n );\n logger.info(\n `${colors.dim(\"启用插件: \")}${colors.blue(unique(botConfig.plugins).join(\", \") || \"(空)\")}`,\n );\n logger.info(\n `${colors.dim(\"适配器: \")}${colors.blue(Object.keys(botConfig.adapters ?? {}).join(\", \") || \"(无, zero-adapter 模式)\")}`,\n );\n logger.info(colors.dim(\"=\".repeat(40)));\n\n await serviceManager.loadAllServices();\n await runtime.start();\n await registerPluginArtifacts();\n\n const bots = runtime.bots;\n if (bots.length > 0) {\n logger.info(\n `成功连接 ${bots.length} 个实例: ${bots.map((b) => b.bot_id).join(\", \")}`,\n );\n }\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(\n `mioku v${version} 启动完成,向机器人发送「${colors.magentaBright(`${botConfig.prefix}help`)}」查看消息指令`,\n );\n\n if (botConfig.online_push && botConfig.owners[0]) {\n const bot = runtime.bots[0];\n if (bot) {\n try {\n await bot.sendMessage(\n { type: \"private\", user_id: botConfig.owners[0] },\n `✅ mioku v${version} 已就绪`,\n );\n } catch (err) {\n logger.warn(\"发送就绪通知失败\", err);\n }\n }\n }\n return {\n stop: async (reason?: string) => {\n await runtime.shutdown(reason);\n await serviceManager.disposeAll();\n },\n };\n};\n","// Mioku framework types — single source of truth for the public API surface.\n\n// ---------- framework ----------\n\n/** 框架服务的最小形态:init 负责初始化,api 是对外暴露的接口对象 */\nexport interface MiokuService {\n name: string;\n version: string;\n description?: string;\n init(): Promise<void>;\n api: Record<string, any>;\n dispose?(): Promise<void>;\n}\n\n/** package.json 的 `mioku` 字段中控制框架行为的运行时配置 */\nexport interface MiokuRuntimeConfig {\n plugins?: string[];\n plugins_dir?: string;\n services_dir?: string;\n [key: string]: unknown;\n}\n\n/** 宽松的 package.json 结构,用于读取插件的元信息 */\nexport interface PackageJsonLike {\n name?: string;\n version?: string;\n description?: string;\n keywords?: readonly string[];\n mioku?: unknown;\n dependencies?: Record<string, string>;\n}\n\n/** 已加载插件的元信息,供内置 core 插件与帮助系统使用 */\nexport interface PluginMetadata {\n name: string;\n version: string;\n description?: string;\n path: string;\n packageJson: PackageJsonLike;\n config: PluginPackageConfig;\n}\n\n/** 已发现服务的元信息 */\nexport interface ServiceMetadata {\n name: string;\n version: string;\n description?: string;\n path: string;\n packageJson: PackageJsonLike;\n}\n\n// ---------- plugin package config ----------\n\n/** 插件 package.json 中 `mioku` 字段的解析结果 */\nexport interface PluginPackageConfig {\n /** 插件依赖的服务名,如 `ai`、`config` */\n services?: string[];\n help?: PluginHelp;\n accessHooks?: AccessHook[];\n}\n\n/** 插件的帮助信息,框架会自动收集并注册到帮助服务 */\nexport interface PluginHelp {\n title: string;\n description: string;\n commands: Array<{\n cmd: string;\n desc: string;\n usage?: string;\n role?: CommandRole;\n }>;\n}\n\nexport type CommandRole = \"master\" | \"admin\" | \"owner\" | \"member\";\n\n/**\n * - `\"master\"`:仅 bot 主人可触发\n * - `\"owner\"`:legacy alias\n * - `\"admin\"`:bot 主人或管理员\n * - `\"member\"`:群内任意成员\n *\n */\nexport type SkillPermissionRole = \"master\" | \"owner\" | \"admin\" | \"member\";\n\nexport function normalizeSkillPermissionRole(\n role: unknown,\n): SkillPermissionRole {\n const normalized = String(role ?? \"\")\n .trim()\n .toLowerCase();\n if (\n normalized === \"master\" ||\n normalized === \"owner\" ||\n normalized === \"admin\" ||\n normalized === \"member\"\n ) {\n return normalized as SkillPermissionRole;\n }\n return \"member\";\n}\n\nexport interface AccessHook {\n id: string;\n /** 匹配文本的正则(字符串形式,如 `/^\\.help$/`),用于在事件层面拦截/放行 */\n match?: string;\n /** 命中的事件路由,如 `notice.group.poke` */\n event?: string;\n description?: string;\n}\n\nexport type AccessAction = \"allow\" | \"block\";\n\nexport interface AccessRuleEntry {\n action: AccessAction;\n}\n\nexport interface AccessScopeConfig {\n plugins?: Record<string, AccessRuleEntry>;\n commands?: Record<string, Record<string, AccessRuleEntry>>;\n}\n\n/** 访问控制配置:按全局 / 群 / 用户三级对插件与指令放行或拦截 */\nexport interface AccessControlConfig {\n version: 1;\n global: AccessScopeConfig;\n groups: Record<string, AccessScopeConfig>;\n users: Record<string, AccessScopeConfig>;\n}\n\n// ---------- built-in service contracts ----------\n\n/** 配置服务:插件的配置文件统一注册、读取与热更新 */\nexport interface ConfigService {\n registerConfig(\n pluginName: string,\n configName: string,\n initialConfig: any,\n ): Promise<boolean>;\n updateConfig(\n pluginName: string,\n configName: string,\n updates: any,\n ): Promise<boolean>;\n getConfig(pluginName: string, configName: string): Promise<any>;\n getPluginConfigs(pluginName: string): Promise<Record<string, any>>;\n /** 订阅配置变化,返回取消订阅函数 */\n onConfigChange(\n pluginName: string,\n configName: string,\n callback: (newConfig: any) => void,\n ): () => void;\n}\n\n/** 截图服务:把 HTML / Markdown / URL 渲染成图片 */\nexport interface ScreenshotService {\n screenshot(html: string, options?: any): Promise<string>;\n screenshotMarkdown(markdownContent: string, options?: any): Promise<string>;\n screenshotFromUrl(url: string, options?: any): Promise<string>;\n cleanupTemp(olderThanMs?: number): Promise<number>;\n}\n\n/** 帮助服务:插件的帮助信息注册与查询 */\nexport interface HelpService {\n registerHelp(pluginName: string, help: PluginHelp): void;\n getHelp(pluginName: string): PluginHelp | undefined;\n getAllHelp(): Map<string, PluginHelp>;\n unregisterHelp(pluginName: string): boolean;\n}\n\nexport interface WebUIService {\n getSettings(): { port: number; host: string; packageManager: string };\n}\n\n// ---------- AI service ----------\n\n/** AI 工具:暴露给模型的函数,供模型在对话中调用 */\nexport interface AITool {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n handler: (args: any, event?: any) => Promise<any> | any;\n}\n\n/** AI 技能:一组工具的组合,可按权限开放给不同角色的用户 */\nexport interface AISkill {\n name: string;\n description: string;\n permission?: SkillPermissionRole;\n tools: AITool[];\n}\n\nexport interface TextMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\n/** 多模态消息内容:文本或图片 URL */\nexport interface MultimodalContentItem {\n type: \"text\" | \"image_url\";\n text?: string;\n image_url?: {\n url: string;\n detail?: \"auto\" | \"low\" | \"high\";\n };\n}\n\nexport interface MultimodalMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string | MultimodalContentItem[];\n}\n\n/** 一次工具调用的记录(名称、参数与结果) */\nexport interface ToolCallRecord {\n name: string;\n arguments: any;\n result: any;\n}\n\nexport interface SessionToolDefinition {\n name: string;\n tool: AITool;\n}\n\n/** 模型补全请求的完整选项 */\nexport interface CompleteOptions {\n model?: string;\n messages: any[];\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n tools?: any[];\n /** 会话内可执行的工具(自动进入工具循环) */\n executableTools?: SessionToolDefinition[];\n executableToolsProvider?: () => SessionToolDefinition[];\n maxIterations?: number;\n onTextDelta?: (delta: string) => void | Promise<void>;\n usageContext?: AIUsageContext;\n usageContextTokens?: number;\n usageBreakdown?: AIUsageFinalization[\"breakdown\"];\n}\n\nexport interface CompleteResponse {\n content: string | null;\n reasoning: string | null;\n toolCalls: Array<{ id: string; name: string; arguments: string }>;\n raw: any;\n turnMessages: any[];\n iterations?: number;\n allToolCalls?: ToolCallRecord[];\n}\n\nexport type AIProtocol =\n | \"openai-chat\"\n | \"openai-response\"\n | \"anthropic\"\n | \"gemini\";\n\n/** 模型能力标记:文本 / 视觉 / 工具调用 / 推理 */\nexport type AIModelCapability = \"text\" | \"vision\" | \"tool-use\" | \"reasoning\";\n\n/** 思考等级,部分推理模型支持从 off 到 max 逐级调节 */\nexport type AIThinkingLevel =\n | \"off\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"xhigh\"\n | \"max\";\n\nexport const AI_THINKING_LEVELS: AIThinkingLevel[] = [\n \"off\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n];\n\nexport const AI_GEMINI_THINKING_LEVELS: AIThinkingLevel[] = [\n \"off\",\n \"low\",\n \"medium\",\n \"high\",\n];\n\nexport function normalizeAIThinkingLevel(\n value: unknown,\n protocol?: AIProtocol,\n): AIThinkingLevel | undefined {\n const raw = String(value ?? \"\")\n .trim()\n .toLowerCase() as AIThinkingLevel;\n if (!raw) return undefined;\n if (protocol === \"gemini\") {\n return AI_GEMINI_THINKING_LEVELS.includes(raw) ? raw : undefined;\n }\n return AI_THINKING_LEVELS.includes(raw) ? raw : undefined;\n}\n\n/** 模型角色:主对话 / 干活 / 看图 */\nexport type AIModelRole = \"main\" | \"working\" | \"vision\";\n\n/** 一个模型提供商的连接配置 */\nexport interface AIProviderConfig {\n id: string;\n name: string;\n protocol: AIProtocol;\n apiUrl: string;\n apiKey: string;\n enabled: boolean;\n headers?: Record<string, string>;\n}\n\n/** 模型描述:归属于某个提供商,带能力与上下文窗口信息 */\nexport interface AIModelDescriptor {\n id: string;\n providerId: string;\n modelId: string;\n name: string;\n capabilities: AIModelCapability[];\n contextWindow?: number;\n maxOutputTokens?: number;\n isCustom?: boolean;\n thinkingLevel?: AIThinkingLevel;\n}\n\nexport interface AIInstanceInfo {\n name: string;\n providerId: string;\n modelId: string;\n role?: AIModelRole;\n}\n\n/** AI 实例:一个绑定到具体提供商与模型的调用句柄 */\nexport interface AIInstance {\n generateText(options: {\n prompt?: string;\n messages: TextMessage[];\n model?: string;\n temperature?: number;\n max_tokens?: number;\n }): Promise<string>;\n generateMultimodal(options: {\n prompt?: string;\n messages: MultimodalMessage[];\n model?: string;\n temperature?: number;\n max_tokens?: number;\n }): Promise<string>;\n complete(options: CompleteOptions): Promise<CompleteResponse>;\n generateWithTools(options: {\n prompt?: string;\n messages: TextMessage[] | MultimodalMessage[];\n model?: string;\n temperature?: number;\n maxIterations?: number;\n }): Promise<any>;\n setUsageContext?(context: AIUsageContext | undefined): void;\n withUsageContext?<T>(\n context: AIUsageContext | undefined,\n fn: () => Promise<T>,\n ): Promise<T>;\n registerPrompt(name: string, prompt: string): boolean;\n getPrompt(name: string): string | undefined;\n getAllPrompts(): Record<string, string>;\n removePrompt(name: string): boolean;\n}\n\n/** AI 服务:实例 / 提供商 / 模型 / 技能的统一管理入口 */\nexport interface AIService {\n create(options: {\n name: string;\n apiUrl: string;\n apiKey: string;\n modelType: \"text\" | \"multimodal\";\n model?: string;\n }): Promise<AIInstance>;\n createInstance?(options: {\n name: string;\n providerId: string;\n modelId: string;\n role?: AIModelRole;\n }): Promise<AIInstance>;\n get(name: string): AIInstance | undefined;\n list(): string[];\n listInstances?(): AIInstanceInfo[];\n remove(name: string): boolean;\n setDefault(name: string): boolean;\n getDefault(): AIInstance | undefined;\n listProviders?(): AIProviderConfig[];\n getProvider?(id: string): AIProviderConfig | undefined;\n createProvider?(\n input: Omit<AIProviderConfig, \"id\"> & { id?: string },\n ): Promise<AIProviderConfig>;\n updateProvider?(\n id: string,\n input: Partial<AIProviderConfig>,\n ): Promise<AIProviderConfig>;\n removeProvider?(id: string): boolean;\n testProvider?(\n id: string,\n ): Promise<{ ok: boolean; error?: string; models?: AIModelDescriptor[] }>;\n listModels?(providerId?: string): AIModelDescriptor[];\n refreshModels?(providerId: string): Promise<AIModelDescriptor[]>;\n registerCustomModel?(input: {\n providerId: string;\n modelId: string;\n name?: string;\n capabilities?: AIModelCapability[];\n }): AIModelDescriptor;\n removeCustomModel?(modelFullId: string): boolean;\n removeModel?(modelFullId: string): boolean;\n setModelThinkingLevel?(\n modelFullId: string,\n level: AIThinkingLevel | undefined,\n ): boolean;\n getRoleBindings?(): Record<AIModelRole, string | undefined>;\n setRoleBinding?(role: AIModelRole, modelFullId: string | undefined): boolean;\n getInstanceByRole?(role: AIModelRole): AIInstance | undefined;\n setMainFallbackChain?(modelFullIds: string[]): void;\n getMainFallbackChain?(): string[];\n registerChatRuntime(runtime: any): boolean;\n getChatRuntime(): any;\n removeChatRuntime(): boolean;\n registerSkill(skill: AISkill): boolean;\n getSkill(skillName: string): AISkill | undefined;\n getAllSkills(): Map<string, AISkill>;\n removeSkill(skillName: string): boolean;\n getTool(toolName: string): AITool | undefined;\n getAllTools(): Map<string, AITool>;\n getUsageSummary?(options: {\n range: AIUsageRange;\n botId?: number;\n }): AIUsageSummary;\n cleanupUsageStats?(retentionMs?: number): number;\n finalizeUsage?(usageId: string, finalization: AIUsageFinalization): boolean;\n}\n\n// ---------- chat runtime ----------\n\n/** 聊天运行时:让插件复用 chat 插件的\"发通知 / 收集信息\"能力 */\nexport interface ChatRuntime {\n generateNotice(options: ChatRuntimeNoticeOptions): Promise<ChatRuntimeResult>;\n requestInformation(\n options: ChatRuntimeInformationRequestOptions,\n ): Promise<ChatRuntimeResult>;\n}\n\nexport const TOOL_RESULT_FOLLOWUP_KEY = \"__miokuFollowup\";\n\n/** 工具结果附带的内容:文本与图片/视频引用 */\nexport interface ToolResultFollowup {\n text: string;\n images?: Array<{ url: string; detail?: \"auto\" | \"low\" | \"high\" }>;\n videos?: Array<{ url: string; detail?: \"auto\" | \"low\" | \"high\" }>;\n}\n\nexport interface ChatRuntimePromptInjection {\n content: string;\n title?: string;\n}\n\nexport interface ChatRuntimeGroupTarget {\n selfId: number;\n groupId: number;\n}\n\nexport interface ChatRuntimePrivateTarget {\n selfId: number;\n userId: number;\n}\n\nexport type ChatRuntimeSource =\n | { event: any }\n | ChatRuntimeGroupTarget\n | ChatRuntimePrivateTarget;\n\nexport type ChatRuntimeBaseOptions = ChatRuntimeSource & {\n targetMessage?: string;\n promptInjections?: ChatRuntimePromptInjection[];\n send?: boolean;\n};\n\nexport type ChatRuntimeNoticeOptions = ChatRuntimeBaseOptions & {\n instruction: string;\n};\n\n/** 让 AI 按给定 JSON Schema 收集并返回结构化信息 */\nexport type ChatRuntimeInformationRequestOptions = ChatRuntimeBaseOptions & {\n task: string;\n schema: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n toolName?: string;\n toolDescription?: string;\n};\n\nexport interface ChatRuntimeCollectedInfo {\n data: any;\n isComplete?: boolean;\n confidence?: number;\n notes?: string;\n}\n\nexport interface ChatRuntimeResult {\n messages: string[];\n toolCalls: ToolCallRecord[];\n collectedInfo: ChatRuntimeCollectedInfo | null;\n pendingAt?: number[];\n pendingPoke?: number[];\n pendingQuote?: number;\n emojiPath?: string | null;\n protocolMessages?: any[];\n}\n\n// ---------- usage tracking ----------\n\nexport type AIUsageRange = \"today\" | \"7d\" | \"30d\";\n\nexport type AIUsageScope = \"all\" | \"bot\";\n\nexport interface AIUsageContext {\n usageId?: string;\n source?: string;\n botId?: number;\n groupId?: number;\n groupName?: string;\n userId?: number;\n userName?: string;\n sessionId?: string;\n fallbackUsed?: boolean;\n fallbackFrom?: string;\n}\n\nexport interface AIUsageBreakdown {\n systemPromptTokens?: number;\n chatHistoryTokens?: number;\n toolDefinitionTokens?: number;\n toolUseTokens?: number;\n otherContextTokens?: number;\n}\n\nexport interface AIUsageFinalization {\n sentUserMessages?: number;\n sentAssistantMessages?: number;\n breakdown?: AIUsageBreakdown;\n}\n\nexport interface AIUsageBotOption {\n botId: number;\n label: string;\n}\n\nexport interface AIUsageSummary {\n generatedAt: number;\n range: AIUsageRange;\n scope: AIUsageScope;\n botId?: number;\n bots: AIUsageBotOption[];\n totals: {\n requests: number;\n successfulRequests: number;\n failedRequests: number;\n userMessages: number;\n assistantMessages: number;\n systemMessages: number;\n toolMessages: number;\n sentUserMessages: number;\n sentAssistantMessages: number;\n inputTokens: number;\n outputTokens: number;\n systemPromptTokens: number;\n totalTokens: number;\n cacheWriteTokens: number;\n cacheReadTokens: number;\n toolDefinitionTokens: number;\n toolUseTokens: number;\n chatHistoryTokens: number;\n otherContextTokens: number;\n durationMs: number;\n toolCalls: number;\n };\n rates: {\n throughputTokPerMin: number;\n averageTokensPerUserMessage: number;\n averageTokensPerSentMessage: number;\n errorRate: number;\n cacheHitRate: number;\n };\n toolRanking: Array<{ name: string; count: number }>;\n groupRanking: Array<{\n groupId: number;\n groupName: string;\n requests: number;\n totalTokens: number;\n userMessages: number;\n assistantMessages: number;\n errorRate: number;\n }>;\n tokenFlow: Array<{\n name: \"输入\" | \"输出\" | \"缓存写入\" | \"缓存读取\";\n value: number;\n }>;\n tokenCategories: Array<{\n name: \"系统提示词\" | \"工具定义\" | \"工具使用\" | \"聊天上下文\" | \"其他上下文\";\n value: number;\n }>;\n dailyActivity: Array<{\n day: string;\n requests: number;\n userMessages: number;\n assistantMessages: number;\n totalTokens: number;\n inputTokens: number;\n cacheReadTokens: number;\n throughputTokPerMin: number;\n averageTokensPerUserMessage: number;\n averageTokensPerSentMessage: number;\n errorRate: number;\n cacheHitRate: number;\n }>;\n hourlyActivity: Array<{\n hour: string;\n requests: number;\n userMessages: number;\n assistantMessages: number;\n totalTokens: number;\n inputTokens: number;\n cacheReadTokens: number;\n throughputTokPerMin: number;\n averageTokensPerUserMessage: number;\n averageTokensPerSentMessage: number;\n errorRate: number;\n cacheHitRate: number;\n }>;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { startRuntime as startMiokuRuntime } from \"./start\";\nimport { rootLogger } from \"./logger\";\nimport serviceManager from \"./services/manager\";\nimport { readMiokuConfig } from \"./config\";\n\nimport type { Logger } from \"./logger\";\nimport type { MiokuPlugin } from \"./plugin/plugin\";\n\nexport type { MiokuPlugin, MiokuContext } from \"./plugin/plugin\";\nexport type { EventMap } from \"napcat-sdk\";\n\nexport { definePlugin } from \"./plugin/plugin\";\n\nexport * from \"./logger\";\nexport { rootLogger as logger } from \"./logger\";\nexport * from \"./driver\";\nexport * from \"./adapter\";\nexport * from \"./capabilities\";\nexport * from \"./runtime/bus\";\nexport * from \"./runtime/bots\";\nexport * from \"./runtime/context\";\nexport * from \"./runtime/lifecycle\";\nexport * from \"./runtime/mioku-context\";\nexport * from \"./runtime/runtime\";\nexport * from \"./runtime/types\";\nexport * from \"./loader\";\nexport * from \"./plugin/plugin\";\nexport * from \"./utils\";\nexport * from \"./actions\";\nexport * from \"./services/registry\";\nexport * from \"./services/define\";\nexport * from \"./services/builtin\";\nexport * from \"./services/manager\";\nexport * from \"./services/config\";\nexport * from \"./config\";\nexport * from \"./start\";\nexport * from \"./builtin\";\nexport * from \"./builtin/core/status\";\nexport * from \"./builtin/core/adapters\";\nexport * from \"./compat\";\n\nexport { default as serviceManager } from \"./services/manager\";\nexport { registerPluginArtifacts } from \"./runtime/plugin-artifacts\";\nexport * from \"./runtime/plugin-metadata\";\n\nexport {\n registerServiceConfig,\n getServiceConfig,\n updateServiceConfig,\n getServiceConfigs,\n deleteServiceConfig,\n} from \"./services/config\";\n\nexport type {\n MiokuService,\n MiokuRuntimeConfig,\n PackageJsonLike,\n PluginMetadata,\n ServiceMetadata,\n PluginPackageConfig,\n PluginHelp,\n CommandRole,\n AccessHook,\n AccessAction,\n AccessRuleEntry,\n AccessScopeConfig,\n AccessControlConfig,\n ConfigService,\n ScreenshotService,\n HelpService,\n WebUIService,\n AITool,\n AISkill,\n AIInstance,\n AIService,\n AIProtocol,\n AIModelCapability,\n AIThinkingLevel,\n AIModelRole,\n AIProviderConfig,\n AIModelDescriptor,\n AIInstanceInfo,\n ChatRuntime,\n TextMessage,\n MultimodalMessage,\n ToolCallRecord,\n CompleteOptions,\n CompleteResponse,\n SessionToolDefinition,\n SkillPermissionRole,\n MultimodalContentItem,\n ToolResultFollowup,\n ChatRuntimePromptInjection,\n ChatRuntimeGroupTarget,\n ChatRuntimePrivateTarget,\n ChatRuntimeSource,\n ChatRuntimeBaseOptions,\n ChatRuntimeNoticeOptions,\n ChatRuntimeInformationRequestOptions,\n ChatRuntimeCollectedInfo,\n ChatRuntimeResult,\n AIUsageRange,\n AIUsageScope,\n AIUsageBotOption,\n AIUsageContext,\n AIUsageBreakdown,\n AIUsageFinalization,\n AIUsageSummary,\n} from \"./types\";\n\nexport {\n TOOL_RESULT_FOLLOWUP_KEY,\n normalizeSkillPermissionRole,\n AI_THINKING_LEVELS,\n AI_GEMINI_THINKING_LEVELS,\n normalizeAIThinkingLevel,\n} from \"./types\";\n\nexport {\n defineService,\n getService,\n requireService,\n hasService,\n} from \"./services/define\";\nexport type { ServiceRef } from \"./services/define\";\nexport { Services } from \"./services/builtin\";\nexport type { BuiltinServiceRef } from \"./services/builtin\";\n\nexport interface MiokuStartOptions {\n cwd?: string;\n logger?: Logger;\n builtinPlugins?: readonly MiokuPlugin[];\n}\n\nexport async function start(\n options: MiokuStartOptions = {},\n): Promise<{ stop: (reason?: string) => Promise<void> }> {\n const { cwd = process.cwd() } = options;\n if (cwd) process.chdir(cwd);\n\n rootLogger.info(\"こんにちは..\");\n rootLogger.info(\"---------------------------------------\");\n rootLogger.info(\"---------- Mioku 正在启动 ------------\");\n rootLogger.info(\"---------------------------------------\");\n\n let miokuConfig: import(\"./types\").MiokuRuntimeConfig = {};\n try {\n const cfg = readMiokuConfig();\n miokuConfig = cfg as unknown as import(\"./types\").MiokuRuntimeConfig;\n } catch {\n miokuConfig = {};\n }\n rootLogger.info(\"o.O Miku 正在翻找服务..\");\n await serviceManager.discoverServices(miokuConfig);\n\n const { stop: stopRuntime } = await startMiokuRuntime({\n cwd,\n logger: options.logger,\n builtinPlugins: options.builtinPlugins,\n });\n\n let shuttingDown = false;\n const shutdown = async (signal: string): Promise<void> => {\n if (shuttingDown) return;\n shuttingDown = true;\n rootLogger.info(`收到 ${signal} 信号,正在关闭服务...`);\n const timer = setTimeout(() => {\n rootLogger.error(\"服务关闭超时,强制退出\");\n process.exit(1);\n }, 15_000);\n timer.unref();\n try {\n await stopRuntime(signal);\n } finally {\n clearTimeout(timer);\n }\n rootLogger.info(\"Mioku 服务已完全关闭\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => void shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"));\n\n return {\n stop: (reason) => stopRuntime(reason),\n };\n}\n\nfunction readVersion(): string {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const pkgPath = path.join(here, \"..\", \"package.json\");\n return JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")).version ?? \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nexport const version: string = readVersion();\n\nexport {\n getDataDir,\n getPluginDataDir,\n getServiceDataDir,\n getConfigDir,\n getPluginConfigDir,\n getServiceConfigDir,\n ensureDataDir,\n} from \"./internal/data-paths\";\n\nexport {\n defineState,\n hasPluginState,\n getPluginRuntimeState,\n setPluginRuntimeState,\n resetPluginRuntimeState,\n getAllPluginRuntimeStates,\n} from \"./runtime/plugin-state\";\nexport type { PluginStateRef } from \"./runtime/plugin-state\";\n\nexport {\n resolveCommand,\n commandExists,\n buildSpawnPlan,\n runCommand,\n runCommandInherit,\n} from \"./internal/exec\";\nexport type { RunCommandResult, SpawnPlan } from \"./internal/exec\";"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["BOT_CWD: { value: string }","root: string","pkg: BotConfigJson","input: unknown","config: MiokuConfig","DEFAULT_CONFIG: RuntimeMiokuConfig","botConfig: RuntimeMiokuConfig","value: boolean","draft: (config: RuntimeMiokuConfig) => void | Promise<void>","id: string","url: string","timeout: number","message: string","status: number","response: Response","headers: Record<string, string>","body: HttpRequestOptions['body']","state: DriverState","options: HttpRequestOptions","ws: WebSocket","url: string","#ws","#dispatchMessage","#dispatchClose","#dispatchError","event: MessageEvent","#messageHandlers","event: CloseEvent","#closing","#closeHandlers","event: Event","#errorHandlers","data: string | Uint8Array","code?: number","reason?: string","handler: (data: string | Uint8Array) => void","handler: (event: { code: number; reason: string }) => void","handler: (err: Error) => void","options: WebSocketConnectOptions","timer: ReturnType<typeof setTimeout> | null","rejectConnect: ((err: Error) => void) | null","options: CreateDriverOptions","driver: Driver","closes: Promise<unknown>[]","value: PlatformId","type: string","data: Record<string, unknown>","attachment?: Attachment","segments: readonly MessageSegment[] | number","rawMessage?: string","segments: readonly MessageSegment[]","file: string | Buffer","options: { local?: boolean }","text: string","target: PlatformId","options: { local?: boolean } & Attachment","messageId: PlatformId","options?: { local?: boolean }","options: { local?: boolean; name?: string }","id: string | number","id: string","options: {\n user_id: PlatformId;\n nickname: string;\n content: MessageInput;\n }","data: Record<string, unknown> | string","content: string","options: ButtonOptions","value: unknown","message: Message","input: MessageInput","e: Event","adapter: string","routes: string[]","name: string","version: number","version","capability: string","bot: Bot","group_id: PlatformId","group_name?: string","bot: Bot","user_id: PlatformId","nickname?: string","bot: B","name: string","value: unknown","registry: CapabilityRegistry","target: CapabilityTarget","capability: Capability<I, O>","input: I","group_id: PlatformId","message: MessageInput","user_id: PlatformId","message_id: PlatformId","t: MessageTarget","nodes: readonly ForwardSendNode[]","options?: ForwardSendOptions","duration: number","reject_add_request?: boolean","card: string","enable: boolean","title: string","group_name: string","file: string","is_dismiss?: boolean","profile: ProfileSetRequest","before?: string","limit?: number","extra?: Record<string, unknown>","definition: AdapterDefinition<TConfig>","capability: Capability<I, O>","target: CapabilityTarget","handler: (input: I) => Promise<O>","#handlers","entry: CapabilityHandler<unknown, unknown>","input: I","plugin: T","key: string","#state","#bots","#bus","#driver","#capabilities","#logger","#emit","#pendingStarts","#crossDedup","options: {\n state: RuntimeAdapterState\n bots: BotRegistry\n bus: EventBus\n driver: Driver\n capabilities: CapabilityRegistry\n logger: Logger\n emit: (event: BotLifecycleEvent) => Promise<void>\n crossDedup?: CrossAdapterMessageDeduplicator | null\n }","bot: Bot","bot_id: string","capability: Capability<I, O>","target: CapabilityTarget","handler: (input: I) => Promise<O>","finalTarget: CapabilityTarget","gateway: AdapterGateway","err: unknown","resource: AdapterResource","event: Event","route: string","handler: (event: Event) => void | Promise<void>","event: BotLifecycleEvent","store","key: string","factory: () => T","connectedBots: Map<string, Bot>","adapter: string","bot_id: string","bot: Bot","#bots","#disposers","key: string","bot_id: string","adapter: string","bot_id: string | number","pattern: string","route: string","logger: ((level: 'error' | 'warn' | 'info', message: string, detail?: unknown) => void) | null","#logger","handler: EventHandler<E>","options: { source?: string; priority?: number }","#nextId","#nextOrder","reg: Registration","#registrations","#unregister","id: number","event: Event","matched: Registration[]","#matching","#dispatched","cmdStr: string","options: CreateCmdOptions","filename: string","options: { defaultData?: T; compress?: boolean }","data: T","defaultData: T","options: {\n __dirname?: string;\n importMeta?: ImportMeta;\n compress?: boolean;\n filename?: string;\n }","path","text: BinaryLike","encoding: BinaryToTextEncoding | \"buffer\"","text","array: T[]","value: T | T[]","ms: number","ts: number | string | Date","options: { locale?: string; timeZone?: string }","options: { locale?: string; timeZone?: string; seconds?: boolean }","min: number","max: number","array: readonly T[]","count: number","selected: number[]","isString","v: unknown","n: number","val: T | null | undefined","val?: T","val: unknown","num: number","str: string | number | Buffer","str: string","type: \"buffer\" | BufferEncoding","obj: Record<number | string, unknown>","error: unknown","pskey: string","event: T","pattern: Record<string, MatchHandler<T> | MatchValue>","quote: boolean","matches: RegExpMatchArray | null","source: HasMessage | Message","options: { trim?: boolean | \"whole\" | \"each\" }","type: string","ADAPTER_DISPLAY_NAMES: Readonly<Record<string, string>>","id: string | number | null | undefined","LEVEL_MAP: Readonly<Record<number, { name: string; color: 'red' | 'yellow' | 'white' | 'green' | 'blue' | 'gray' }>>","cachedRoot: ConsolaInstance | null","cachedRootLevel: LogLevel","level: LogLevel","file: string","args: unknown[]","level: number","tag: string | undefined","#parent","#tag","#scope","#file","#threshold","options: {\n parent: ConsolaInstance | null\n tag: string | undefined\n scope: Record<string, unknown>\n file: string\n threshold: number\n }","#tagWithScope","#log","tag: string","scope: Record<string, unknown>","options: { tag?: string; level?: LogLevel; scope?: Record<string, unknown> }","rootLogger: Logger","bot: Bot","target: MessageTarget","message: MessageInput","bots: readonly Bot[]","targets: readonly MessageTarget[]","options: NoticeOptions","groupIds: readonly (string | number)[]","userIds: readonly (string | number)[]","owners: readonly string[]","admins: readonly string[]","name: string","value: T","cover: boolean","filePath: string","p: string","dir: string","results: DiscoveredModule[]","entries: import(\"fs\").Dirent[]","prefix: string","SERVICE_PREFIX","miokuConfig: MiokuRuntimeConfig","name: string","servicePath: string","packageJson: PackageJsonLike","ctx?: MiokuContext","metadata: ServiceMetadata","service: MiokuService","serviceName: string","configName: string","defaults: Record<string, unknown>","value: Record<string, unknown>","result: Record<string, Record<string, unknown>>","id: string","ctx: MiokuContext","ref: ServiceRef<T>","isObject","value: unknown","event: unknown","#options","#cleanup","options: ContextOptions","fn: PluginCleanup","bot_id: string | number","event: { quote_id?: string | null; bot?: Bot; self_id?: string }","name: string","route: R","handler: (event: RouteEvent<R>) => void | Promise<void>","event: Event","dispose","#addCleanup","expression: string","handler: CronHandler","taskContext: TaskContext","type: K","handler: (event: K extends 'connected' ? { bot: Bot } : BotLifecycleEvent) => void | Promise<void>","updater: (config: MiokuConfig) => void | Promise<void>","value: T","cover?: boolean","event: T","pattern: Parameters<typeof matchMessage>[1]","quote?: boolean","cmdStr: string","options: CreateCmdOptions","defaultData: T","options: { __dirname?: string; importMeta?: ImportMeta; compress?: boolean; filename?: string }","filename: string","options: { defaultData?: T; compress?: boolean }","source: HasMessage | Message","options?: { trim?: boolean | 'whole' | 'each' }","groupIds: readonly string[]","message: MessageInput","options?: import('../actions').NoticeOptions","userIds: readonly string[]","store","meta: PluginMetadata","name: string","name: string","initial: T","next: T","state: T","SystemMap: Record<string, string>","ArchMap: Record<string, string>","start","options: BuildStatusOptions","status: MiokuStatus","statsLine","adapter: string","bot_id?: string","target: StatusProviderTarget","provider: StatusProvider","bot: Bot","value: unknown","data: Record<string, unknown>","stats: AdapterStatusStats | undefined","status: AdapterStatus | null","options: BuildAdapterReportOptions","report: AdapterReport","STAT_GROUPS: ReadonlyArray<\n readonly [\n icon: string,\n fields: ReadonlyArray<readonly [keyof AdapterStatusStats, string]>,\n ]\n>","stats: AdapterStatusStats","segments: string[]","instance: AdapterInstanceStatus","entry: AdapterReportEntry","CORE_DEFAULT_CONFIG: CorePluginConfig","input: unknown","input: any","value: T","config: CorePluginConfig | any","merged: CorePluginConfig","ACCESS_DEFAULT_CONFIG: AccessControlConfig","config: Partial<AccessControlConfig> | any","filePath: string","data: unknown","text: string","hook: AccessHook","text","plugins: PluginMetadata[]","out: MessageCommandMatch[]","ctx: MiokuContext","getConfig: () => CorePluginConfig","text","userId: string | number | undefined","ctx: MiokuContext","getConfig: () => CorePluginConfig","LINES_PER_NODE","chunk","arr: T[]","size: number","result: T[][]","event: any","text: string","text","options: {\n ctx: MiokuContext;\n event: any;\n text: string;\n source: string;\n summary?: string;\n}","name: string","args: string[]","cwd?: string","chunk","readPackageJson","dir: string","pkgName: string","result: InstalledPackage[]","url: string","version","updates: UpdateAvailable[]","names: string[]","before: Map<string, string>","type: \"plugin\" | \"service\"","raw: unknown","meta: NpmPackageMeta | null","official: boolean","pluginName: string","serviceName: string","isInPm2: boolean","ensureDataDir","marker: RestartMarker","value: string","scriptPath","content","ms: number","ctx: MiokuContext | undefined","segment","event: any","typeLabel","type: string","items: UpdateAvailable[]","text: string","total: number","indices: number[]","num","ctx: MiokuContext","names: string[]","marker: RestartMarker","text","ev: any","text: string","head: string","type: \"plugin\" | \"service\"","ctx: MiokuContext","text","parsed","kind: \"plugin\" | \"service\"","items: Awaited<ReturnType<typeof getMarketItems>>","ctx: MiokuContext","text","kind: \"plugin\" | \"service\" | null","ctx: MiokuContext","text","marker: RestartMarker","latest: { path: string; mtime: number } | null","filePath: string","count: number","arr: T[]","size: number","result: T[][]","ctx: MiokuContext","text","lines: string[]","ctx: MiokuContext","getConfig: () => CorePluginConfig","autoUpdateTimer: ReturnType<typeof setInterval> | null","enabled: boolean","time: string","frequency: \"daily\" | \"weekly\" | \"monthly\"","marker: RestartMarker","value: string","CORE_HELP_ENTRIES: ReadonlyArray<readonly [cmd: string, desc: string]>","width: number","displayPrefix: string","ctx: MiokuContext","likeKeyword: string","cmd: string","desc: string","help: PluginHelp","accessHooks: AccessHook[]","core: MiokuPlugin","disposers: Array<() => void>","baseConfig: CorePluginConfig","accessRules: AccessControlConfig","text: string","text","name: string","adapter?: Adapter","event: MessageEvent","str: string","BUILTIN_PLUGINS: readonly MiokuPlugin[]","core","prefix: string","obj: Record<string, unknown>","allowed: Set<string>","value: unknown","pluginName: string","commands: PluginHelp[\"commands\"]","hooks: AccessHook[]","raw: unknown","config: PluginPackageConfig","services","name: string","resolvedPath: string","packageJson: PackageJsonLike","dir: string","cwd: string","name: string","pkg: PackageJson","override?: string","candidates: string[]","appPackageJson: PackageJson","candidates: AdapterCandidate[]","candidates: PluginCandidate[]","pluginsDir: string","value: unknown","cwd: string","aliases: Record<string, string>","jiti: Jiti","candidate: AdapterCandidate","value: unknown","jiti: Jiti","entry: string","name: string","candidate: PluginCandidate","resolvedPath: string","event: MessageEvent","parts: string[]","text","content: string","#entries","#dropped","event: Event","#inserts","#prune","now: number","BUILTIN_PLUGINS: MiokuPlugin[]","DEFAULT_BUILTIN_PLUGINS","plugins: readonly MiokuPlugin[]","BUILTIN_PLUGINS","#cwd","#logger","#bus","#bots","#capabilities","#driver","#adapterStates","#enabledAdapters","#enabledPlugins","#driverFactory","#builtinPlugins","#crossDedup","options: CreateRuntimeOptions","name: string","bot_id: string | number","#readAppPackageJson","#loadPlugin","#emitLifecycle","event: BotLifecycleEvent","lifecycleEvent: Event","state: RuntimeAdapterState","plugin: MiokuPlugin","type: \"builtin\" | \"external\"","cleanupTasks: PluginCleanup[]","cleanup: PluginCleanup | null","wrappedCleanup: PluginCleanup","#setupBuiltinPlugins","#discoverAdapters","#setupPlugins","#logPluginSummary","failed: Array<{ name: string; error: string }>","tasks: Array<{\n name: string;\n priority: number;\n run: () => Promise<void>;\n }>","startTime: bigint","#startAdapter","config: unknown","#createContext","instance: Adapter","#started","failed: string[]","reason?: string","#stopped","ctx?: MiokuContext","options: StartOptions","reason?: string","role: unknown","AI_THINKING_LEVELS: AIThinkingLevel[]","AI_GEMINI_THINKING_LEVELS: AIThinkingLevel[]","value: unknown","protocol?: AIProtocol","options: MiokuStartOptions","miokuConfig: import(\"./types\").MiokuRuntimeConfig","signal: string","version: string"],"sources":["../src/config.ts","../src/driver/types.ts","../src/driver/default.ts","../src/adapter/message.ts","../src/adapter/event.ts","../src/adapter/capability.ts","../src/capabilities/message.ts","../src/capabilities/member.ts","../src/capabilities/group.ts","../src/capabilities/friend.ts","../src/capabilities/conversation.ts","../src/capabilities/profile.ts","../src/capabilities/system.ts","../src/adapter/bot.ts","../src/adapter/types.ts","../src/adapter/registry.ts","../src/plugin/plugin.ts","../src/runtime/context.ts","../src/internal/registry.ts","../src/compat/connected-bots.ts","../src/runtime/bots.ts","../src/runtime/bus.ts","../src/utils.ts","../src/logger/index.ts","../src/actions.ts","../src/services/registry.ts","../src/internal/module-scanner.ts","../src/services/manager.ts","../src/services/config.ts","../src/services/define.ts","../src/services/builtin.ts","../src/runtime/mioku-context.ts","../src/runtime/plugin-metadata.ts","../src/runtime/plugin-state.ts","../src/builtin/core/status.ts","../src/builtin/core/adapters.ts","../src/builtin/core/config.ts","../src/builtin/core/access/access-config.ts","../src/builtin/core/access/access-store.ts","../src/builtin/core/access/matcher.ts","../src/builtin/core/commands/like.ts","../src/builtin/core/access/privileged.ts","../src/builtin/core/commands/min-member.ts","../src/builtin/core/commands/notify.ts","../src/builtin/core/commands/prefix.ts","../src/builtin/core/system/package-manager.ts","../src/internal/data-paths.ts","../src/builtin/core/system/restart.ts","../src/builtin/core/commands/update.ts","../src/builtin/core/commands/install.ts","../src/builtin/core/commands/market.ts","../src/builtin/core/commands/restart.ts","../src/builtin/core/commands/log.ts","../src/builtin/core/commands/auto-approve.ts","../src/builtin/core/system/auto-update.ts","../src/builtin/core/index.ts","../src/builtin/index.ts","../src/loader/manifest.ts","../src/loader/package.ts","../src/loader/adapter.ts","../src/loader/plugin.ts","../src/runtime/cross-adapter-dedup.ts","../src/runtime/runtime.ts","../src/runtime/plugin-artifacts.ts","../src/start.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { LogLevel } from \"./logger\";\n\n/** package.json 中 mioku 字段的结构 */\nexport interface MiokuConfig {\n /** 指令前缀,缺省为 \".\" */\n prefix?: string;\n owners: string[];\n admins: string[];\n plugins: string[];\n plugins_dir?: string;\n log_level?: LogLevel;\n /** 启动完成后是否私聊通知第一位 owner */\n online_push?: boolean;\n /** 出错时是否推送给 owner */\n error_push?: boolean;\n /** 谁可以查询运行状态:所有人或仅管理员 */\n status_permission?: \"all\" | \"admin-only\";\n /** 去重选项 */\n dedup?: {\n /** 跨适配器指纹去重 */\n cross_adapter?: boolean;\n };\n adapters?: Record<string, unknown>;\n napcat?: unknown;\n}\n\n/** package.json 的宽松形状,只约定 mioku 字段 */\nexport interface BotConfigJson {\n mioku?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/** 当前机器人根目录,包一层对象以便整体重定向 */\nexport const BOT_CWD: { value: string } = { value: process.cwd() };\n\n/** 重设机器人根目录,之后 package.json 的读写都基于它 */\nexport const setBotCwd = (root: string): void => {\n BOT_CWD.value = path.resolve(root);\n};\n\n/** 读取机器人根目录的 package.json */\nexport const readPackageJson = (): BotConfigJson => {\n const file = path.join(BOT_CWD.value, \"package.json\");\n if (!fs.existsSync(file)) {\n throw new Error(\n `无法在 ${BOT_CWD.value} 下找到 package.json 文件,请确认当前目录是否为机器人根目录`,\n );\n }\n const raw = fs.readFileSync(file, \"utf-8\");\n try {\n return JSON.parse(raw) as BotConfigJson;\n } catch {\n throw new Error(`package.json 解析失败,请检查 JSON 格式`);\n }\n};\n\n/** 写回机器人根目录的 package.json */\nexport const writePackageJson = (pkg: BotConfigJson): void => {\n const file = path.join(BOT_CWD.value, \"package.json\");\n fs.writeFileSync(file, JSON.stringify(pkg, null, 2), \"utf-8\");\n};\n\n/** 把 owners 配置规整为字符串数组,非数组时返回空 */\nexport const normalizeOwners = (input: unknown): string[] => {\n if (!Array.isArray(input)) return [];\n return input.map((v) => String(v) as string);\n};\n\n/** 同 normalizeOwners,规整管理员名单 */\nexport const normalizeAdmins = (input: unknown): string[] => {\n if (!Array.isArray(input)) return [];\n return input.map((v) => String(v) as string);\n};\n\n/** 同 normalizeOwners,规整插件列表 */\nexport const normalizePlugins = (input: unknown): string[] => {\n if (!Array.isArray(input)) return [];\n return input.map((v) => String(v) as string);\n};\n\n/** 从 package.json 读取 mioku 配置并补全默认值 */\nexport const readMiokuConfig = (): MiokuConfig => {\n const raw = readPackageJson();\n const rawMioku = raw.mioku;\n if (!rawMioku || typeof rawMioku !== \"object\") {\n throw new Error(\n `无法在 package.json 中找到 mioku 配置,请确认 package.json 文件中是否包含 mioku 字段`,\n );\n }\n const config: MiokuConfig = {\n ...(rawMioku as Partial<MiokuConfig>),\n owners: normalizeOwners((rawMioku as { owners?: unknown }).owners),\n admins: normalizeAdmins((rawMioku as { admins?: unknown }).admins),\n plugins: normalizePlugins((rawMioku as { plugins?: unknown }).plugins),\n prefix:\n typeof (rawMioku as { prefix?: unknown }).prefix === \"string\"\n ? (rawMioku as { prefix: string }).prefix\n : \".\",\n plugins_dir:\n typeof (rawMioku as { plugins_dir?: unknown }).plugins_dir === \"string\"\n ? (rawMioku as { plugins_dir: string }).plugins_dir\n : \"plugins\",\n };\n if ((rawMioku as { log_level?: unknown }).log_level) {\n config.log_level = (rawMioku as { log_level: LogLevel }).log_level;\n }\n if ((rawMioku as { status_permission?: unknown }).status_permission) {\n config.status_permission = (\n rawMioku as { status_permission: \"all\" | \"admin-only\" }\n ).status_permission;\n }\n config.online_push = Boolean(\n (rawMioku as { online_push?: unknown }).online_push,\n );\n config.error_push = Boolean(\n (rawMioku as { error_push?: unknown }).error_push,\n );\n if ((rawMioku as { adapters?: unknown }).adapters) {\n config.adapters = (\n rawMioku as { adapters: Record<string, unknown> }\n ).adapters;\n }\n return config;\n};\n\n/** 运行时使用的配置,字段与 MiokuConfig 相同 */\nexport interface RuntimeMiokuConfig extends MiokuConfig {}\n\nconst DEFAULT_CONFIG: RuntimeMiokuConfig = {\n owners: [],\n admins: [],\n plugins: [],\n plugins_dir: \"plugins\",\n prefix: \".\",\n};\n\nconst loadInitialConfig = (): RuntimeMiokuConfig => {\n try {\n return readMiokuConfig();\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n};\n\n/** 全局运行时配置,模块加载时初始化 */\nexport let botConfig: RuntimeMiokuConfig = loadInitialConfig();\n\n/** 重新读取 package.json 并替换全局配置 */\nexport const reloadMiokuConfig = (): RuntimeMiokuConfig => {\n botConfig = readMiokuConfig();\n return botConfig;\n};\n\nlet writable = false;\n\n/** 控制是否允许把配置改动写回 package.json */\nexport const setWritableConfig = (value: boolean): void => {\n writable = value;\n};\n\n/** 在 draft 里直接修改配置;writable 开启时改动会落盘到 package.json */\nexport const updateMiokuConfig = (\n draft: (config: RuntimeMiokuConfig) => void | Promise<void>,\n): Promise<void> => {\n return Promise.resolve(draft(botConfig)).then(() => {\n if (!writable) return;\n const pkg = readPackageJson();\n pkg.mioku = {\n ...(pkg.mioku as Record<string, unknown> | undefined),\n ...botConfig,\n };\n writePackageJson(pkg);\n });\n};\n\n/** 判断是否为 owner */\nexport const isOwner = (id: string): boolean => {\n const target = typeof id === \"string\" ? id : id;\n return botConfig.owners.includes(target as string);\n};\n\n/** 判断是否为管理员 */\nexport const isAdmin = (id: string): boolean => {\n const target = typeof id === \"string\" ? id : id;\n return botConfig.admins.includes(target as string);\n};\n\n/** 判断是否为 owner 或管理员 */\nexport const isOwnerOrAdmin = (id: string): boolean => {\n return isOwner(id) || isAdmin(id);\n};\n\n/** isOwnerOrAdmin 的别名 */\nexport const hasRight = (id: string): boolean => isOwnerOrAdmin(id);\n","/** 一条已建立的 WebSocket 连接 */\nexport interface WebSocketConnection {\n readonly id: string\n readonly url: string\n readonly readyState: 'connecting' | 'open' | 'closing' | 'closed'\n\n send(data: string | Uint8Array): Promise<void>\n close(code?: number, reason?: string): Promise<void>\n\n /** 监听消息,返回取消监听的函数 */\n onMessage(handler: (data: string | Uint8Array) => void): () => void\n /** 监听连接关闭,返回取消监听的函数 */\n onClose(handler: (event: { code: number; reason: string }) => void): () => void\n /** 监听连接错误,返回取消监听的函数 */\n onError(handler: (err: Error) => void): () => void\n}\n\n/** 建立 WebSocket 连接的选项 */\nexport interface WebSocketConnectOptions {\n readonly headers?: Readonly<Record<string, string>>\n readonly protocols?: readonly string[]\n readonly signal?: AbortSignal\n /** 连接超时时间(毫秒) */\n readonly connectTimeout?: number\n}\n\n/** WebSocket 客户端 */\nexport interface WebSocketClient {\n connect(url: string, options?: WebSocketConnectOptions): Promise<WebSocketConnection>\n}\n\n/** HTTP 请求参数 */\nexport interface HttpRequestOptions {\n readonly method: string\n readonly url: string\n readonly headers?: Readonly<Record<string, string>>\n /** 请求体:字符串、二进制或对象(对象按 JSON 发送) */\n readonly body?: string | Uint8Array | Readonly<Record<string, unknown>>\n /** 超时时间(毫秒) */\n readonly timeout?: number\n readonly signal?: AbortSignal\n}\n\n/** HTTP 响应 */\nexport interface HttpResponse {\n readonly status: number\n readonly headers: Readonly<Record<string, string>>\n readonly body: Uint8Array\n text(): string\n json<T = unknown>(): T\n arrayBuffer(): ArrayBuffer\n}\n\n/** HTTP 客户端 */\nexport interface HttpClient {\n request(options: HttpRequestOptions): Promise<HttpResponse>\n}\n\n/** 驱动:为适配器提供统一的 HTTP 与 WebSocket 能力 */\nexport interface Driver {\n readonly name: string\n readonly http: HttpClient\n readonly websocket: WebSocketClient\n /** 关闭驱动:中止进行中的请求并断开所有连接 */\n shutdown(): Promise<void>\n}\n\n/** 驱动已关闭后发起请求时抛出的错误 */\nexport class DriverShutdownError extends Error {\n constructor(message = 'Driver has been shut down') {\n super(message)\n this.name = 'DriverShutdownError'\n }\n}\n\n/** WebSocket 连接超时时抛出的错误 */\nexport class WebSocketConnectTimeoutError extends Error {\n constructor(url: string, timeout: number) {\n super(`WebSocket connect timed out after ${timeout}ms: ${url}`)\n this.name = 'WebSocketConnectTimeoutError'\n }\n}\n\n/** HTTP 请求失败时抛出的错误 */\nexport class HttpRequestError extends Error {\n /** HTTP 状态码,网络错误或超时时为 0 */\n readonly status: number\n constructor(message: string, status: number) {\n super(message)\n this.name = 'HttpRequestError'\n this.status = status\n }\n}","import { randomUUID } from 'node:crypto'\n\nimport type {\n Driver,\n HttpClient,\n HttpRequestOptions,\n HttpResponse,\n WebSocketClient,\n WebSocketConnection,\n WebSocketConnectOptions,\n} from './types'\nimport { DriverShutdownError, HttpRequestError, WebSocketConnectTimeoutError } from './types'\n\nconst RAW_TEXT_DECODER = new TextDecoder()\n\nconst decodeBody = async (response: Response): Promise<{ body: Uint8Array; headers: Record<string, string> }> => {\n const arrayBuffer = await response.arrayBuffer()\n const headers: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n headers[key.toLowerCase()] = value\n })\n return { body: new Uint8Array(arrayBuffer), headers }\n}\n\nconst buildResponse = async (response: Response): Promise<HttpResponse> => {\n const { body, headers } = await decodeBody(response)\n return {\n status: response.status,\n headers,\n body,\n text() {\n return RAW_TEXT_DECODER.decode(body)\n },\n json<T = unknown>(): T {\n return JSON.parse(RAW_TEXT_DECODER.decode(body)) as T\n },\n arrayBuffer(): ArrayBuffer {\n return body.buffer.slice(body.byteOffset, body.byteOffset + body.byteLength) as ArrayBuffer\n },\n }\n}\n\nconst serializeBody = (\n body: HttpRequestOptions['body'],\n): { body: string | Buffer | undefined; contentType: string | undefined } => {\n if (body == null) return { body: undefined, contentType: undefined }\n if (typeof body === 'string') return { body, contentType: 'text/plain;charset=utf-8' }\n if (body instanceof Uint8Array) return { body: Buffer.from(body), contentType: 'application/octet-stream' }\n return { body: JSON.stringify(body), contentType: 'application/json' }\n}\n\nconst createHttpClient = (state: DriverState): HttpClient => {\n return {\n async request(options: HttpRequestOptions): Promise<HttpResponse> {\n if (state.shutdownStarted) throw new DriverShutdownError()\n const { body, contentType } = serializeBody(options.body)\n const headers = new Headers()\n for (const [k, v] of Object.entries(options.headers ?? {})) {\n headers.set(k, v)\n }\n if (contentType && !headers.has('content-type')) {\n headers.set('content-type', contentType)\n }\n const signal = options.signal ?? state.rootController.signal\n const timeout = options.timeout ?? state.requestTimeout\n const controller = new AbortController()\n const timer =\n timeout > 0\n ? setTimeout(() => {\n controller.abort(new Error(`HttpRequest timeout after ${timeout}ms`))\n }, timeout)\n : null\n const compositeSignal = AbortSignal.any([signal, controller.signal])\n try {\n const response = await fetch(options.url, {\n method: options.method,\n headers,\n body: body as BodyInit | undefined,\n signal: compositeSignal,\n })\n return await buildResponse(response)\n } catch (err) {\n if (controller.signal.aborted) {\n throw new HttpRequestError(`Request aborted or timed out: ${options.url}`, 0)\n }\n throw new HttpRequestError(err instanceof Error ? err.message : String(err), 0)\n } finally {\n if (timer) clearTimeout(timer)\n }\n },\n }\n}\n\nclass NodeWebSocketConnection implements WebSocketConnection {\n readonly id: string\n readonly url: string\n #ws: WebSocket\n #messageHandlers = new Set<(data: string | Uint8Array) => void>()\n #closeHandlers = new Set<(event: { code: number; reason: string }) => void>()\n #errorHandlers = new Set<(err: Error) => void>()\n #closing: 'idle' | 'closing' | 'closed' = 'idle'\n\n constructor(ws: WebSocket, url: string) {\n this.#ws = ws\n this.url = url\n this.id = randomUUID()\n ws.binaryType = 'arraybuffer'\n ws.addEventListener('message', this.#dispatchMessage)\n ws.addEventListener('close', this.#dispatchClose)\n ws.addEventListener('error', this.#dispatchError)\n }\n\n get readyState(): 'connecting' | 'open' | 'closing' | 'closed' {\n switch (this.#ws.readyState) {\n case WebSocket.CONNECTING:\n return 'connecting'\n case WebSocket.OPEN:\n return 'open'\n case WebSocket.CLOSING:\n return 'closing'\n case WebSocket.CLOSED:\n return 'closed'\n default:\n return 'closed'\n }\n }\n\n #dispatchMessage = (event: MessageEvent): void => {\n if (this.#messageHandlers.size === 0) return\n const data = typeof event.data === 'string' ? event.data : new Uint8Array(event.data as ArrayBuffer)\n for (const handler of this.#messageHandlers) {\n try {\n handler(data)\n } catch {\n // swallow handler errors; transport-level concerns only.\n }\n }\n }\n\n #dispatchClose = (event: CloseEvent): void => {\n this.#closing = 'closed'\n const payload = { code: event.code, reason: event.reason }\n for (const handler of this.#closeHandlers) {\n try {\n handler(payload)\n } catch {\n // ignore\n }\n }\n }\n\n #dispatchError = (event: Event): void => {\n const err = event instanceof ErrorEvent ? new Error(event.message) : new Error('WebSocket error')\n for (const handler of this.#errorHandlers) {\n try {\n handler(err)\n } catch {\n // ignore\n }\n }\n }\n\n async send(data: string | Uint8Array): Promise<void> {\n if (this.#ws.readyState !== WebSocket.OPEN) {\n throw new Error('WebSocket is not open')\n }\n if (typeof data === 'string') {\n this.#ws.send(data)\n return\n }\n this.#ws.send(Buffer.from(data))\n }\n\n async close(code?: number, reason?: string): Promise<void> {\n if (this.#closing !== 'idle') return\n this.#closing = 'closing'\n if (this.#ws.readyState === WebSocket.OPEN || this.#ws.readyState === WebSocket.CONNECTING) {\n this.#ws.close(code ?? 1000, reason ?? '')\n }\n }\n\n onMessage(handler: (data: string | Uint8Array) => void): () => void {\n this.#messageHandlers.add(handler)\n return () => this.#messageHandlers.delete(handler)\n }\n\n onClose(handler: (event: { code: number; reason: string }) => void): () => void {\n this.#closeHandlers.add(handler)\n return () => this.#closeHandlers.delete(handler)\n }\n\n onError(handler: (err: Error) => void): () => void {\n this.#errorHandlers.add(handler)\n return () => this.#errorHandlers.delete(handler)\n }\n}\n\nconst createWebSocketClient = (state: DriverState): WebSocketClient => {\n return {\n async connect(url: string, options: WebSocketConnectOptions = {}): Promise<WebSocketConnection> {\n if (state.shutdownStarted) throw new DriverShutdownError()\n const headers = options.headers ?? {}\n const protocols = options.protocols ? Array.from(options.protocols) : undefined\n const socket = new WebSocket(url, protocols)\n const signal = options.signal\n let externalAbort = false\n const abortFromExternal = (): void => {\n externalAbort = true\n socket.close(1000, 'aborted')\n }\n if (signal) {\n if (signal.aborted) abortFromExternal()\n else signal.addEventListener('abort', abortFromExternal, { once: true })\n }\n const timeout = options.connectTimeout ?? state.connectTimeout\n let timer: ReturnType<typeof setTimeout> | null = null\n let rejectConnect: ((err: Error) => void) | null = null\n if (timeout > 0) {\n timer = setTimeout(() => {\n externalAbort = true\n try {\n socket.close(1001, 'connect timeout')\n } catch {\n // ignore\n }\n rejectConnect?.(new WebSocketConnectTimeoutError(url, timeout))\n }, timeout)\n }\n try {\n await new Promise<void>((resolve, reject) => {\n rejectConnect = reject\n socket.addEventListener('open', () => resolve(), { once: true })\n socket.addEventListener(\n 'error',\n (event) => {\n if (externalAbort) return\n const err = event instanceof ErrorEvent ? new Error(event.message) : new Error('WebSocket connect failed')\n reject(err)\n },\n { once: true },\n )\n })\n } catch (err) {\n try {\n socket.close()\n } catch {\n // ignore\n }\n throw err instanceof Error ? err : new Error('WebSocket connect failed')\n } finally {\n if (timer) clearTimeout(timer)\n rejectConnect = null\n }\n const conn = new NodeWebSocketConnection(socket, url)\n state.connections.add(conn)\n const remove = (): void => {\n state.connections.delete(conn)\n }\n conn.onClose(remove)\n return conn\n },\n }\n}\n\ninterface DriverState {\n shutdownStarted: boolean\n connections: Set<WebSocketConnection>\n rootController: AbortController\n requestTimeout: number\n connectTimeout: number\n}\n\n/** 创建默认驱动的选项 */\nexport interface CreateDriverOptions {\n /** HTTP 请求的默认超时(毫秒) */\n readonly requestTimeout?: number\n /** WebSocket 连接的默认超时(毫秒) */\n readonly connectTimeout?: number\n}\n\n/** 创建内置默认驱动:基于全局 fetch 与 WebSocket 实现 */\nexport const createDefaultDriver = (options: CreateDriverOptions = {}): Driver => {\n const state: DriverState = {\n shutdownStarted: false,\n connections: new Set(),\n rootController: new AbortController(),\n requestTimeout: options.requestTimeout ?? 30_000,\n connectTimeout: options.connectTimeout ?? 15_000,\n }\n const http = createHttpClient(state)\n const websocket = createWebSocketClient(state)\n\n const driver: Driver = {\n name: 'mioku.default',\n http,\n websocket,\n async shutdown(): Promise<void> {\n if (state.shutdownStarted) return\n state.shutdownStarted = true\n state.rootController.abort()\n const closes: Promise<unknown>[] = []\n for (const conn of state.connections) {\n closes.push(conn.close(1000, 'driver shutdown'))\n }\n await Promise.allSettled(closes)\n },\n }\n return driver\n}\n","/** 消息段的附件:图片/文件/音视频的资源引用 */\nexport interface Attachment {\n readonly id?: string;\n readonly url?: string;\n readonly file?: string;\n readonly data?: Uint8Array;\n readonly mime?: string;\n readonly size?: number;\n readonly name?: string;\n}\n\n/** 消息段:一段消息的最小单元,如文本、@、图片 */\nexport interface MessageSegment {\n readonly type: string;\n readonly data: Readonly<Record<string, unknown>>;\n readonly attachment?: Attachment;\n isText(): boolean;\n toString(): string;\n}\n\nexport interface SerializedMessageSegment {\n readonly type: string;\n readonly data: Readonly<Record<string, unknown>>;\n readonly attachment?: Attachment;\n}\n\n/** 消息:消息段的只读数组,带文本提取与按类型过滤的便捷方法 */\nexport interface Message extends ReadonlyArray<MessageSegment> {\n readonly raw_message?: string;\n toString(): string;\n text(): string;\n filterByType<T extends MessageSegment = MessageSegment>(type: string): T[];\n toJSON(): SerializedMessageSegment[];\n}\n\n/** 发送消息的入参:字符串、单段或段的数组都可以 */\nexport type MessageInput =\n | string\n | Message\n | MessageSegment\n | readonly (string | MessageSegment)[];\n\nexport type PlatformId = string | number;\n\nexport const toId = (value: PlatformId): string => String(value);\n\n/** 消息发送目标:群或私聊等会话的定位信息 */\nexport interface MessageTarget {\n readonly type: string;\n readonly id?: PlatformId;\n readonly parent_id?: PlatformId;\n readonly user_id?: PlatformId;\n readonly group_id?: PlatformId;\n}\n\nexport interface SentMessage {\n readonly message_id?: string;\n readonly sent_at?: number;\n}\n\nexport interface ReplyOptions {\n readonly quote?: boolean;\n}\n\nexport type ReplyArg = boolean | ReplyOptions;\n\n/** 交互按钮*/\nexport interface ButtonOptions {\n id?: string;\n label: string;\n /** 点击后按钮文字 */\n visitedLabel?: string;\n /** 0 灰色线框 1 蓝色线框 2 白字 3 蓝底白字 */\n style?: 0 | 1 | 2 | 3;\n /** callback 回调(默认) / command 指令(输入框插入) / link 跳转 */\n action?: \"callback\" | \"command\" | \"link\";\n /** callback / command 的数据 */\n data?: string;\n /** link 的跳转地址 */\n url?: string;\n /** \"all\" 所有人 / \"admin\" 仅管理员 / 用户 id 列表 */\n permission?: \"all\" | \"admin\" | readonly string[];\n /** command 点击后是否直接发送 */\n enter?: boolean;\n /** command 是否引用本消息 */\n reply?: boolean;\n /** 客户端版本过低时的提示文案 */\n unsupportedTips?: string;\n}\n\n/** 会话引用:用于定位一段会话(含父会话) */\nexport interface ConversationRef {\n readonly type: string;\n readonly id: string;\n readonly parent_id?: string;\n}\n\nexport class MessageSegmentImpl implements MessageSegment {\n readonly type: string;\n readonly data: Readonly<Record<string, unknown>>;\n readonly attachment: Attachment | undefined;\n constructor(\n type: string,\n data: Record<string, unknown>,\n attachment?: Attachment,\n ) {\n this.type = type;\n this.data = Object.freeze({ ...data });\n this.attachment = attachment;\n }\n\n isText(): boolean {\n return this.type === \"text\";\n }\n\n toString(): string {\n if (this.type === \"text\" && typeof this.data.text === \"string\")\n return this.data.text;\n return JSON.stringify({ type: this.type, data: this.data });\n }\n}\n\nclass MessageImpl extends Array<MessageSegment> implements Message {\n readonly raw_message: string | undefined;\n constructor(\n segments: readonly MessageSegment[] | number,\n rawMessage?: string,\n ) {\n super();\n this.raw_message = rawMessage;\n if (typeof segments === \"number\") {\n this.length = segments;\n return;\n }\n for (const seg of segments) this.push(seg);\n }\n\n toString(): string {\n return this.map((seg) => seg.toString()).join(\"\");\n }\n\n text(): string {\n return (\n this.raw_message ??\n this.filterByType(\"text\")\n .map((seg) => String(seg.data.text ?? \"\"))\n .join(\"\")\n );\n }\n\n filterByType<T extends MessageSegment = MessageSegment>(type: string): T[] {\n return this.filter((seg): seg is T => seg.type === type);\n }\n\n toJSON(): SerializedMessageSegment[] {\n return this.map((seg) => ({\n type: seg.type,\n data: seg.data,\n attachment: seg.attachment,\n }));\n }\n}\n\nexport const createMessage = (\n segments: readonly MessageSegment[],\n rawMessage?: string,\n): Message => new MessageImpl(segments, rawMessage);\n\nconst fileData = (\n file: string | Buffer,\n options: { local?: boolean } = {},\n): Record<string, unknown> => {\n if (Buffer.isBuffer(file))\n return { file: `base64://${file.toString(\"base64\")}` };\n if (options.local)\n return { file: `file:///${file.replace(/^\\s*(file:\\/\\/\\/)+/, \"\")}` };\n return { file };\n};\n\n/** 消息段构造器:按类型快速生成消息段 */\nexport const segment = {\n text(text: string): MessageSegment {\n return new MessageSegmentImpl(\"text\", { text });\n },\n at(target: PlatformId): MessageSegment {\n return new MessageSegmentImpl(\"at\", { target: toId(target) });\n },\n /** `file` 为 URL 或本地路径;传 Buffer 会转成 base64 发送 */\n image(\n file: string | Buffer,\n options: { local?: boolean } & Attachment = {},\n ): MessageSegment {\n const { local = false, ...attachment } = options;\n const data: Record<string, unknown> = {};\n if (Buffer.isBuffer(file)) {\n data.file = `base64://${file.toString(\"base64\")}`;\n } else if (local) {\n data.file = `file:///${file.replace(/^\\s*(file:\\/\\/\\/)+/, \"\")}`;\n } else {\n data.url = file;\n }\n const attrs = Object.keys(attachment).length > 0 ? attachment : undefined;\n if (attrs) data.attachment = attrs;\n return new MessageSegmentImpl(\"image\", data, attrs);\n },\n reply(messageId: PlatformId): MessageSegment {\n return new MessageSegmentImpl(\"reply\", { message_id: toId(messageId) });\n },\n video(file: string | Buffer, options?: { local?: boolean }): MessageSegment {\n return new MessageSegmentImpl(\"video\", fileData(file, options));\n },\n record(file: string | Buffer, options?: { local?: boolean }): MessageSegment {\n return new MessageSegmentImpl(\"record\", fileData(file, options));\n },\n file(\n file: string | Buffer,\n options: { local?: boolean; name?: string } = {},\n ): MessageSegment {\n const data = fileData(file, options);\n if (options.name) data.name = options.name;\n return new MessageSegmentImpl(\"file\", data);\n },\n face(id: string | number): MessageSegment {\n return new MessageSegmentImpl(\"face\", { id: String(id) });\n },\n forward(id: string): MessageSegment {\n return new MessageSegmentImpl(\"forward\", { id });\n },\n node(options: {\n user_id: PlatformId;\n nickname: string;\n content: MessageInput;\n }): MessageSegment {\n return new MessageSegmentImpl(\"node\", {\n user_id: toId(options.user_id),\n nickname: options.nickname,\n content: Array.isArray(options.content)\n ? Array.from(options.content)\n : options.content,\n });\n },\n json(data: Record<string, unknown> | string): MessageSegment {\n return new MessageSegmentImpl(\"json\", {\n data: typeof data === \"string\" ? data : JSON.stringify(data),\n });\n },\n markdown(content: string): MessageSegment {\n return new MessageSegmentImpl(\"markdown\", { content });\n },\n button(options: ButtonOptions): MessageSegment {\n return new MessageSegmentImpl(\"button\", { ...options });\n },\n raw(\n type: string,\n data: Record<string, unknown>,\n attachment?: Attachment,\n ): MessageSegment {\n return new MessageSegmentImpl(type, data, attachment);\n },\n} as const;\n\nexport const isMessage = (value: unknown): value is Message =>\n value instanceof MessageImpl;\n\n/** 取消息中的第一个 @ 目标 */\nexport const atOf = (message: Message): string | undefined => {\n const at = message.filterByType(\"at\")[0];\n if (!at) return undefined;\n const raw = at.data?.qq ?? at.data?.target;\n return raw == null ? undefined : String(raw);\n};\n\nexport const isSegment = (value: unknown): value is MessageSegment =>\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as { type?: unknown }).type === \"string\";\n\n/** 把任意 `MessageInput` 规范化为 `Message` */\nexport const asMessage = (input: MessageInput): Message => {\n if (isMessage(input)) return input;\n if (typeof input === \"string\")\n return new MessageImpl([new MessageSegmentImpl(\"text\", { text: input })]);\n if (isSegment(input)) return new MessageImpl([input]);\n return new MessageImpl(\n (input as readonly (string | MessageSegment)[]).map((item) =>\n typeof item === \"string\"\n ? new MessageSegmentImpl(\"text\", { text: item })\n : item,\n ),\n );\n};\n","import type {\n Attachment,\n ConversationRef,\n Message,\n MessageInput,\n MessageTarget,\n ReplyOptions,\n SentMessage,\n} from './message'\n\n/** 事件的全局标识:来自哪个适配器、哪个 bot、哪类事件 */\nexport interface EventIdentity {\n readonly adapter: string\n readonly bot_id?: string\n readonly source_id?: string\n readonly event_type: string\n readonly message_id?: string\n readonly timestamp?: number\n readonly native_event_id?: string\n readonly fingerprint?: string\n}\n\n/** 所有事件的公共基础结构 */\nexport interface EventBase {\n /** 事件大类:message / notice / request / meta_event / adapter */\n readonly kind: string\n /** 事件类型,如 `message`、`notice.group.poke` */\n readonly type: string\n /** 该事件可匹配的路由列表,由 `buildRoutes` 生成 */\n readonly routes: readonly string[]\n readonly identity: EventIdentity\n readonly self_id?: string\n readonly bot?: import('./bot').Bot\n readonly time?: number\n readonly raw?: unknown\n}\n\n/** 与具体 bot 绑定的事件(含 message / notice / request / meta_event) */\nexport interface BotEventBase extends EventBase {\n readonly self_id: string\n readonly bot: import('./bot').Bot\n}\n\nexport interface SenderInfo {\n readonly user_id?: string\n readonly nickname?: string\n readonly card?: string\n readonly role?: 'owner' | 'admin' | 'member' | (string & {})\n}\n\n/** 消息事件:私聊与群聊消息 */\nexport interface MessageEvent extends BotEventBase {\n readonly kind: 'message'\n readonly message_type: 'private' | 'group' | 'channel' | 'thread' | 'direct' | (string & {})\n readonly sub_type?: string\n readonly user_id?: string\n readonly group_id?: string\n readonly group_name?: string\n readonly message_id?: string\n readonly raw_message?: string\n readonly quote_id?: string\n readonly sender?: SenderInfo\n readonly group?: import('../capabilities/group').Group\n readonly friend?: import('../capabilities/friend').Friend\n readonly conversation?: ConversationRef\n readonly message: Message\n readonly is_to_me?: boolean\n readonly at?: string\n /** 回复这条消息 */\n reply(message: MessageInput, options?: boolean | ReplyOptions): Promise<SentMessage>\n recall(): Promise<void>\n}\n\n/** 通知事件:群成员变动、戳一戳等 */\nexport interface NoticeEvent extends BotEventBase {\n readonly kind: 'notice'\n readonly notice_type?: string\n readonly sub_type?: string\n readonly user_id?: string\n readonly group_id?: string\n readonly operator_id?: string\n}\n\n/** 请求事件:加群/好友申请,可 approve 或 reject */\nexport interface RequestEvent extends BotEventBase {\n readonly kind: 'request'\n readonly request_type?: string\n readonly sub_type?: string\n readonly user_id?: string\n readonly group_id?: string\n readonly flag?: string\n readonly comment?: string\n approve(): Promise<void>\n reject(reason?: string): Promise<void>\n}\n\n/** 生命周期元事件 */\nexport interface MetaEvent extends BotEventBase {\n readonly kind: 'meta_event'\n readonly meta_event_type?: string\n readonly sub_type?: string\n}\n\n/** 适配器自定义事件:不归属以上四类时使用 */\nexport interface AdapterEvent extends EventBase {\n readonly kind: 'adapter'\n readonly payload: unknown\n}\n\nexport type Event = MessageEvent | NoticeEvent | RequestEvent | MetaEvent | AdapterEvent\n\nexport type BotEvent = MessageEvent | NoticeEvent | RequestEvent | MetaEvent\n\nexport const isMessageEvent = (e: Event): e is MessageEvent => e.kind === 'message'\nexport const isNoticeEvent = (e: Event): e is NoticeEvent => e.kind === 'notice'\nexport const isRequestEvent = (e: Event): e is RequestEvent => e.kind === 'request'\nexport const isMetaEvent = (e: Event): e is MetaEvent => e.kind === 'meta_event'\nexport const isAdapterEvent = (e: Event): e is AdapterEvent => e.kind === 'adapter'\nexport const isBotEvent = (e: Event): e is BotEvent =>\n e.kind === 'message' || e.kind === 'notice' || e.kind === 'request' || e.kind === 'meta_event'\n\nexport interface EventFactoryOptions<T extends MessageEvent | NoticeEvent | RequestEvent | MetaEvent | AdapterEvent> {\n readonly routes: readonly string[]\n readonly identity: EventIdentity\n readonly bot?: import('./bot').Bot\n readonly self_id?: string\n readonly time?: number\n readonly raw?: unknown\n}\n\n/**\n * 根据平台信息生成层级路由列表。\n * 例如 `buildRoutes(\"onebotv11\", \"message\", \"group\")` 会生成\n * `onebotv11:message.group`、`onebotv11:message`、`onebotv11`、`message.group`、`message` 等,\n * 监听任意一层都能收到该事件。\n */\nexport const buildRoutes = (adapter: string, ...parts: (string | undefined | null)[]): string[] => {\n const cleaned = parts.filter((p): p is string => typeof p === 'string' && p.length > 0)\n const routes: string[] = []\n const platformParts = [adapter, ...cleaned]\n for (let length = platformParts.length; length > 0; length--) {\n const [head, ...rest] = platformParts.slice(0, length)\n routes.push(rest.length > 0 ? `${head}:${rest.join('.')}` : head)\n }\n for (let length = cleaned.length; length > 0; length--) {\n routes.push(cleaned.slice(0, length).join('.'))\n }\n return Array.from(new Set(routes))\n}\n\nexport type { Attachment, ConversationRef, Message, MessageInput, MessageTarget, ReplyOptions, SentMessage }","/** 能力:一个可被适配器实现、被插件调用的操作契约(如 `message.send`) */\nexport interface Capability<I, O> {\n readonly name: string\n readonly version: number\n /** 能力唯一标识,同名同版本的实现只能注册一份 */\n readonly token: symbol\n}\n\n/** 定义一个能力,`I` 为请求类型,`O` 为返回类型 */\nexport const defineCapability = <I, O>(name: string, version: number = 1): Capability<I, O> => {\n if (name.length === 0) {\n throw new Error('defineCapability: name must be a non-empty string')\n }\n if (!Number.isInteger(version) || version < 1) {\n throw new Error('defineCapability: version must be a positive integer')\n }\n return { name, version, token: Symbol(name) }\n}\n\n/** 目标上没有注册该能力时抛出的错误 */\nexport class UnsupportedCapabilityError extends Error {\n readonly capability: string\n constructor(capability: string) {\n super(`Capability \"${capability}\" is not supported on this target`)\n this.name = 'UnsupportedCapabilityError'\n this.capability = capability\n }\n}\n","import { defineCapability } from '../adapter/capability'\nimport type { Message, MessageInput, MessageTarget, PlatformId, SentMessage } from '../adapter'\n\n/** 发送消息的请求参数 */\nexport interface MessageSendRequest {\n readonly target: MessageTarget\n readonly message: MessageInput\n}\n\n/** 撤回消息的请求参数 */\nexport interface MessageRecallRequest {\n readonly message_id: PlatformId\n}\n\n/** 获取单条消息的请求参数 */\nexport interface MessageGetRequest {\n readonly message_id: PlatformId\n}\n\n/** 获取到的消息详情 */\nexport interface MessageGetResult {\n readonly message_id: string\n readonly message: Message\n readonly raw_message?: string\n readonly time?: number\n readonly user_id?: string\n readonly [key: string]: unknown\n}\n\n/** 合并转发消息里的一条子消息 */\nexport interface ForwardNode {\n readonly user_id?: string\n readonly nickname?: string\n readonly time?: number\n readonly message: Message\n}\n\n/** 获取合并转发消息内容的请求参数 */\nexport interface MessageGetForwardRequest {\n readonly message_id: PlatformId\n}\n\n/** 构造合并转发消息的单个节点 */\nexport interface ForwardSendNode {\n readonly user_id: PlatformId\n readonly nickname: string\n readonly content: MessageInput\n}\n\n/** 合并转发消息的外显样式 */\nexport interface ForwardSendOptions {\n /** 卡片来源显示文本 */\n readonly source?: string\n /** 卡片外显的摘要条目 */\n readonly news?: ReadonlyArray<{ text: string }>\n /** 卡片底部的总摘要 */\n readonly summary?: string\n}\n\n/** 发送合并转发消息的请求参数 */\nexport interface ForwardSendRequest extends ForwardSendOptions {\n readonly target: MessageTarget\n readonly nodes: readonly ForwardSendNode[]\n}\n\n/** 发送消息 */\nexport const messageSend = defineCapability<MessageSendRequest, SentMessage>('message.send', 1)\n/** 撤回消息 */\nexport const messageRecall = defineCapability<MessageRecallRequest, void>('message.recall', 1)\n/** 获取单条消息 */\nexport const messageGet = defineCapability<MessageGetRequest, MessageGetResult>('message.get', 1)\n/** 获取合并转发消息的内容 */\nexport const messageGetForward = defineCapability<MessageGetForwardRequest, ForwardNode[]>('message.getforward', 1)\n/** 发送合并转发消息 */\nexport const forwardSend = defineCapability<ForwardSendRequest, SentMessage>('message.forwardsend', 1)","import { defineCapability } from '../adapter/capability'\nimport type { PlatformId } from '../adapter'\n\n/** 群成员信息 */\nexport interface MemberInfo {\n readonly user_id: string\n readonly nickname?: string\n /** 群名片 */\n readonly card?: string\n readonly role?: 'owner' | 'admin' | 'member' | (string & {})\n /** 入群时间 */\n readonly join_time?: number\n /** 最后一次发言时间 */\n readonly last_sent_time?: number\n readonly [key: string]: unknown\n}\n\n/** 禁言成员的请求参数 */\nexport interface MemberBanRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n /** 禁言时长(秒),0 = 解除禁言 */\n readonly duration: number\n}\n\n/** 将成员移出群聊的请求参数 */\nexport interface MemberKickRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n /** 是否拒绝该成员后续的加群申请 */\n readonly reject_add_request?: boolean\n}\n\n/** 设置成员群名片的请求参数 */\nexport interface MemberSetCardRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n readonly card: string\n}\n\n/** 设置或取消群管理员的请求参数 */\nexport interface MemberSetAdminRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n readonly enable: boolean\n}\n\n/** 查询群成员信息的请求参数 */\nexport interface MemberGetInfoRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n}\n\n/** 戳一戳群成员的请求参数 */\nexport interface MemberPokeRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n}\n\n/** 设置成员专属头衔的请求参数 */\nexport interface MemberSetTitleRequest {\n readonly group_id: PlatformId\n readonly user_id: PlatformId\n readonly title: string\n}\n\n/** 禁言群成员 */\nexport const memberBan = defineCapability<MemberBanRequest, void>('member.ban', 1)\n/** 将成员移出群聊 */\nexport const memberKick = defineCapability<MemberKickRequest, void>('member.kick', 1)\n/** 设置成员群名片 */\nexport const memberSetCard = defineCapability<MemberSetCardRequest, void>('member.setcard', 1)\n/** 设置或取消管理员 */\nexport const memberSetAdmin = defineCapability<MemberSetAdminRequest, void>('member.setadmin', 1)\n/** 获取群成员信息 */\nexport const memberGetInfo = defineCapability<MemberGetInfoRequest, MemberInfo>('member.getinfo', 1)\n/** 戳一戳群成员 */\nexport const memberPoke = defineCapability<MemberPokeRequest, void>('member.poke', 1)\n/** 设置成员专属头衔 */\nexport const memberSetTitle = defineCapability<MemberSetTitleRequest, void>('member.settitle', 1)\n","import { defineCapability } from '../adapter/capability'\nimport { toId } from '../adapter'\n\nimport type { PlatformId, Bot, MessageInput, SentMessage } from '../adapter'\nimport type { MemberInfo } from './member'\n\n/** 群信息 */\nexport interface GroupInfo {\n readonly group_id: string\n readonly group_name?: string\n readonly member_count?: number\n readonly max_member_count?: number\n readonly [key: string]: unknown\n}\n\n/** 获取群信息的请求参数 */\nexport interface GroupGetInfoRequest {\n readonly group_id: PlatformId\n}\n\n/** 获取群成员列表的请求参数 */\nexport interface GroupGetMembersRequest {\n readonly group_id: PlatformId\n}\n\n/** 退出群聊的请求参数 */\nexport interface GroupLeaveRequest {\n readonly group_id: PlatformId\n /** 是否解散群 */\n readonly is_dismiss?: boolean\n}\n\n/** 修改群名的请求参数 */\nexport interface GroupSetNameRequest {\n readonly group_id: PlatformId\n readonly group_name: string\n}\n\n/** 设置群头像的请求参数 */\nexport interface GroupSetPortraitRequest {\n readonly group_id: PlatformId\n /** 图片 URL 或本地路径 */\n readonly file: string\n}\n\n/** 全员禁言的请求参数 */\nexport interface GroupSetWholeBanRequest {\n readonly group_id: PlatformId\n readonly enable: boolean\n}\n\n/** 获取群列表的请求参数 */\nexport interface GroupGetListRequest {}\n\n/** 获取群信息 */\nexport const groupGetInfo = defineCapability<GroupGetInfoRequest, GroupInfo>('group.getinfo', 1)\n/** 获取群成员列表 */\nexport const groupGetMembers = defineCapability<GroupGetMembersRequest, MemberInfo[]>('group.getmembers', 1)\n/** 退出群聊 */\nexport const groupLeave = defineCapability<GroupLeaveRequest, void>('group.leave', 1)\n/** 修改群名 */\nexport const groupSetName = defineCapability<GroupSetNameRequest, void>('group.setname', 1)\n/** 全员禁言 */\nexport const groupSetWholeBan = defineCapability<GroupSetWholeBanRequest, void>('group.setwholeban', 1)\n/** 设置群头像 */\nexport const groupSetPortrait = defineCapability<GroupSetPortraitRequest, void>('group.setportrait', 1)\n/** 获取群列表 */\nexport const groupGetList = defineCapability<GroupGetListRequest, GroupInfo[]>('group.getlist', 1)\n\n/** 群操作句柄:绑定某个群的快捷操作 */\nexport interface Group {\n readonly group_id: string\n readonly group_name?: string\n sendMsg(message: MessageInput): Promise<SentMessage>\n getInfo(): Promise<GroupInfo | null>\n getList(): Promise<GroupInfo[]>\n getMemberList(): Promise<MemberInfo[]>\n getMemberInfo(userId: PlatformId): Promise<MemberInfo | null>\n /** 禁言成员,duration 单位为秒,0 表示解除 */\n ban(userId: PlatformId, duration: number): Promise<void>\n kick(userId: PlatformId, rejectAddRequest?: boolean): Promise<void>\n setCard(userId: PlatformId, card: string): Promise<void>\n setAdmin(userId: PlatformId, enable: boolean): Promise<void>\n recall(messageId: PlatformId): Promise<void>\n /** 退出群聊,isDismiss 为 true 时解散群 */\n leave(isDismiss?: boolean): Promise<void>\n setName(groupName: string): Promise<void>\n setPortrait(file: string): Promise<void>\n}\n\n/** 为指定群创建操作句柄 */\nexport const createGroupRef = (bot: Bot, group_id: PlatformId, group_name?: string): Group => {\n const gid = toId(group_id)\n return {\n group_id: gid,\n group_name,\n sendMsg: (message) => bot.sendGroupMsg(gid, message),\n getInfo: () => bot.getGroupInfo(gid),\n getList: () => bot.getGroupList(),\n getMemberList: () => bot.getGroupMembers(gid),\n getMemberInfo: (userId) => bot.getMemberInfo(gid, userId),\n ban: (userId, duration) => bot.banMember(gid, userId, duration),\n kick: (userId, rejectAddRequest) => bot.kickMember(gid, userId, rejectAddRequest),\n setCard: (userId, card) => bot.setMemberCard(gid, userId, card),\n setAdmin: (userId, enable) => bot.setMemberAdmin(gid, userId, enable),\n recall: (messageId) => bot.recallMessage(messageId),\n leave: (isDismiss) => bot.leaveGroup(gid, isDismiss),\n setName: (groupName) => bot.setGroupName(gid, groupName),\n setPortrait: (file) => bot.setGroupPortrait(gid, file),\n }\n}\n","import { defineCapability } from '../adapter/capability'\nimport { toId } from '../adapter'\n\nimport type { Bot, MessageInput, PlatformId, SentMessage } from '../adapter'\n\n/** 好友信息 */\nexport interface FriendInfo {\n readonly user_id: string\n readonly nickname?: string\n readonly remark?: string\n readonly [key: string]: unknown\n}\n\n/** 获取好友信息的请求参数 */\nexport interface FriendGetInfoRequest {\n readonly user_id: PlatformId\n}\n\n/** 删除好友的请求参数 */\nexport interface FriendDeleteRequest {\n readonly user_id: PlatformId\n}\n\n/** 获取好友列表的请求参数 */\nexport interface FriendGetListRequest {}\n\n/** 获取好友信息 */\nexport const friendGetInfo = defineCapability<FriendGetInfoRequest, FriendInfo>('friend.getinfo', 1)\n/** 删除好友 */\nexport const friendDelete = defineCapability<FriendDeleteRequest, void>('friend.delete', 1)\n/** 获取好友列表 */\nexport const friendGetList = defineCapability<FriendGetListRequest, FriendInfo[]>('friend.getlist', 1)\n\n/** 好友操作句柄:绑定某个好友的快捷操作 */\nexport interface Friend {\n readonly user_id: string\n readonly nickname?: string\n sendMsg(message: MessageInput): Promise<SentMessage>\n getInfo(): Promise<FriendInfo | null>\n getList(): Promise<FriendInfo[]>\n delete(): Promise<void>\n}\n\n/** 为指定好友创建操作句柄 */\nexport const createFriendRef = (bot: Bot, user_id: PlatformId, nickname?: string): Friend => {\n const uid = toId(user_id)\n return {\n user_id: uid,\n nickname,\n sendMsg: (message) => bot.sendPrivateMsg(uid, message),\n getInfo: () => bot.getFriendInfo(uid),\n getList: () => bot.getFriendList(),\n delete: () => bot.deleteFriend(uid),\n }\n}\n","import { defineCapability } from \"../adapter/capability\";\nimport type { MessageTarget, PlatformId } from \"../adapter\";\n\n/** 历史消息记录 */\nexport interface HistoryMessage {\n readonly message_id: string;\n readonly time?: number;\n readonly user_id?: string;\n readonly nickname?: string;\n readonly message: import(\"../adapter\").Message;\n readonly source?: unknown;\n}\n\n/** 拉取会话历史消息的请求参数 */\nexport interface ConversationGetHistoryRequest {\n readonly target: MessageTarget;\n /** 从这个消息 id 之前开始取(不含该条) */\n readonly before?: PlatformId;\n readonly limit?: number;\n /** 适配器私有扩展参数透传 */\n readonly extra?: Record<string, unknown>;\n}\n\n/** 拉取会话的历史消息 */\nexport const conversationGetHistory = defineCapability<\n ConversationGetHistoryRequest,\n HistoryMessage[]\n>(\"conversation.gethistory\", 1);\n","import { defineCapability } from '../adapter/capability'\n\n/** 修改 bot 自身资料的请求参数 */\nexport interface ProfileSetRequest {\n readonly nickname?: string\n /** 个性签名 */\n readonly personal_note?: string\n /** 性别编码,具体取值由适配器定义 */\n readonly sex?: number\n readonly [key: string]: unknown\n}\n\n/** 设置 bot 头像的请求参数 */\nexport interface AvatarSetRequest {\n /** 图片 URL 或本地路径 */\n readonly file: string\n}\n\n/** 修改 bot 自身资料 */\nexport const profileSet = defineCapability<ProfileSetRequest, void>('profile.set', 1)\n/** 设置 bot 头像 */\nexport const avatarSet = defineCapability<AvatarSetRequest, void>('profile.setavatar', 1)","import { defineCapability } from '../adapter/capability'\n\n/** bot 登录状态信息 */\nexport interface BotStatusResult {\n readonly online: boolean\n readonly app_name?: string\n readonly app_version?: string\n readonly protocol_version?: string\n readonly [key: string]: unknown\n}\n\n/** 查询 bot 登录状态 */\nexport const botStatus = defineCapability<Record<string, never>, BotStatusResult>('bot.status', 1)","import type { CapabilityRegistry } from \"./registry\";\nimport type { CapabilityTarget } from \"./types\";\nimport type { Capability } from \"./capability\";\nimport type {\n MessageInput,\n MessageTarget,\n PlatformId,\n SentMessage,\n} from \"./message\";\nimport { toId } from \"./message\";\n\nimport {\n messageRecall,\n messageGet,\n messageGetForward,\n forwardSend,\n memberBan,\n memberKick,\n memberSetCard,\n memberSetAdmin,\n memberGetInfo,\n memberPoke,\n memberSetTitle,\n groupGetInfo,\n groupGetMembers,\n groupGetList,\n groupLeave,\n groupSetName,\n groupSetWholeBan,\n groupSetPortrait,\n friendGetInfo,\n friendGetList,\n friendDelete,\n profileSet,\n avatarSet,\n conversationGetHistory,\n botStatus,\n ForwardNode,\n ForwardSendNode,\n ForwardSendOptions,\n MessageGetResult,\n MemberInfo,\n GroupInfo,\n FriendInfo,\n HistoryMessage,\n ProfileSetRequest,\n BotStatusResult,\n} from \"../capabilities\";\n\n/**\n * Bot 接口:所有平台 bot 的统一操作面。\n * 除 `bot_id` / `adapter` / `sendMessage` / `sendApi` / `as` 外,\n * 其余方法由框架按能力自动绑定(见 `bindCapabilities`)。\n */\nexport interface BotBase {\n readonly bot_id: string;\n readonly adapter: string;\n readonly nickname?: string;\n readonly online: boolean;\n readonly connected_at?: number;\n\n // —— 消息 ——\n sendMessage(\n target: MessageTarget,\n message: MessageInput,\n ): Promise<SentMessage>;\n sendGroupMsg(\n group_id: PlatformId,\n message: MessageInput,\n ): Promise<SentMessage>;\n sendPrivateMsg(\n user_id: PlatformId,\n message: MessageInput,\n ): Promise<SentMessage>;\n recallMessage(message_id: PlatformId): Promise<void>;\n getMessage(message_id: PlatformId): Promise<MessageGetResult | null>;\n getForwardMessage(message_id: PlatformId): Promise<ForwardNode[]>;\n sendForward(\n target: MessageTarget,\n nodes: readonly ForwardSendNode[],\n options?: ForwardSendOptions,\n ): Promise<SentMessage>;\n\n // —— 群 / 成员 ——\n getGroupInfo(group_id: PlatformId): Promise<GroupInfo | null>;\n getGroupList(): Promise<GroupInfo[]>;\n getGroupMembers(group_id: PlatformId): Promise<MemberInfo[]>;\n getMemberInfo(\n group_id: PlatformId,\n user_id: PlatformId,\n ): Promise<MemberInfo | null>;\n /** duration 单位为秒,0 = 解除禁言 */\n banMember(\n group_id: PlatformId,\n user_id: PlatformId,\n duration: number,\n ): Promise<void>;\n /** reject_add_request 为 true 时同时拒绝该成员后续的加群申请 */\n kickMember(\n group_id: PlatformId,\n user_id: PlatformId,\n reject_add_request?: boolean,\n ): Promise<void>;\n setMemberCard(\n group_id: PlatformId,\n user_id: PlatformId,\n card: string,\n ): Promise<void>;\n setMemberAdmin(\n group_id: PlatformId,\n user_id: PlatformId,\n enable: boolean,\n ): Promise<void>;\n setMemberTitle(\n group_id: PlatformId,\n user_id: PlatformId,\n title: string,\n ): Promise<void>;\n pokeMember(group_id: PlatformId, user_id: PlatformId): Promise<void>;\n setGroupName(group_id: PlatformId, group_name: string): Promise<void>;\n setGroupWholeBan(group_id: PlatformId, enable: boolean): Promise<void>;\n setGroupPortrait(group_id: PlatformId, file: string): Promise<void>;\n /** is_dismiss 为 true 时解散群(仅群主可用) */\n leaveGroup(group_id: PlatformId, is_dismiss?: boolean): Promise<void>;\n\n // —— 好友 ——\n getFriendInfo(user_id: PlatformId): Promise<FriendInfo | null>;\n getFriendList(): Promise<FriendInfo[]>;\n deleteFriend(user_id: PlatformId): Promise<void>;\n\n // —— 资料 / 会话 / 状态 ——\n setProfile(profile: ProfileSetRequest): Promise<void>;\n /** file 为本地路径或 URL */\n setAvatar(file: string): Promise<void>;\n /** 拉取会话历史,`before` 为上一页的消息 id */\n getHistory(\n target: MessageTarget,\n before?: string,\n limit?: number,\n extra?: Record<string, unknown>,\n ): Promise<HistoryMessage[]>;\n getStatus(): Promise<BotStatusResult>;\n /** 直接调用平台原生 API(action 为平台动作名) */\n sendApi<T = unknown>(\n action: string,\n params?: Record<string, unknown>,\n ): Promise<T>;\n /** 按目标类型断言 bot,用于访问平台特有方法 */\n as<T extends object = Record<string, unknown>>(): T;\n}\n\nexport type BotProvidedKeys =\n | \"bot_id\"\n | \"adapter\"\n | \"nickname\"\n | \"online\"\n | \"connected_at\"\n | \"sendMessage\"\n | \"sendApi\"\n | \"as\";\n\nexport type BotAutoFilled = Exclude<keyof BotBase, BotProvidedKeys>;\n\nexport type AdapterBotBase<B extends BotBase> = Omit<B, BotAutoFilled> &\n Partial<Pick<B, BotAutoFilled>>;\n\nexport interface AdapterBotMap {}\n\nexport type Bot = AdapterBotMap[keyof AdapterBotMap] extends never\n ? BotBase\n : AdapterBotMap[keyof AdapterBotMap];\n\nexport interface BotContext {\n readonly bot: Bot;\n unregister(): void;\n}\n\nconst bindDefault = <B extends object>(\n bot: B,\n name: string,\n value: unknown,\n): void => {\n if (!(name in bot)) {\n Object.defineProperty(bot, name, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n};\n\n/**\n * 把能力注册表中的实现绑定为 bot 的方法。\n * 适配器在 `start()` 里对自己创建的 bot 调用一次,\n * 插件拿到的 bot 就带上了完整操作面。\n */\nexport const bindCapabilities = <B extends object>(\n bot: B,\n registry: CapabilityRegistry,\n): B & BotBase => {\n const target: CapabilityTarget = {\n adapter: (bot as BotBase).adapter,\n bot_id: (bot as BotBase).bot_id,\n };\n const call = async <I, O>(\n capability: Capability<I, O>,\n input: I,\n ): Promise<O> => registry.invoke(target, capability, input);\n\n bindDefault(\n bot,\n \"as\",\n <T extends object = Record<string, unknown>>() => bot as unknown as T,\n );\n bindDefault(\n bot,\n \"sendGroupMsg\",\n (group_id: PlatformId, message: MessageInput) =>\n (bot as BotBase).sendMessage(\n { type: \"group\", group_id: toId(group_id) },\n message,\n ),\n );\n bindDefault(\n bot,\n \"sendPrivateMsg\",\n (user_id: PlatformId, message: MessageInput) =>\n (bot as BotBase).sendMessage(\n { type: \"private\", user_id: toId(user_id) },\n message,\n ),\n );\n bindDefault(bot, \"recallMessage\", async (message_id: PlatformId) => {\n await call(messageRecall, { message_id: toId(message_id) });\n });\n bindDefault(bot, \"getMessage\", (message_id: PlatformId) =>\n call(messageGet, { message_id: toId(message_id) }),\n );\n bindDefault(bot, \"getForwardMessage\", (message_id: PlatformId) =>\n call(messageGetForward, { message_id: toId(message_id) }),\n );\n bindDefault(\n bot,\n \"sendForward\",\n (\n t: MessageTarget,\n nodes: readonly ForwardSendNode[],\n options?: ForwardSendOptions,\n ) =>\n call(forwardSend, {\n target: t,\n nodes,\n source: options?.source,\n news: options?.news,\n summary: options?.summary,\n }),\n );\n bindDefault(bot, \"getGroupInfo\", (group_id: PlatformId) =>\n call(groupGetInfo, { group_id: toId(group_id) }),\n );\n bindDefault(bot, \"getGroupList\", () => call(groupGetList, {}));\n bindDefault(bot, \"getGroupMembers\", (group_id: PlatformId) =>\n call(groupGetMembers, { group_id: toId(group_id) }),\n );\n bindDefault(\n bot,\n \"getMemberInfo\",\n (group_id: PlatformId, user_id: PlatformId) =>\n call(memberGetInfo, { group_id: toId(group_id), user_id: toId(user_id) }),\n );\n bindDefault(\n bot,\n \"banMember\",\n (group_id: PlatformId, user_id: PlatformId, duration: number) =>\n call(memberBan, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n duration,\n }),\n );\n bindDefault(\n bot,\n \"kickMember\",\n (group_id: PlatformId, user_id: PlatformId, reject_add_request?: boolean) =>\n call(memberKick, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n reject_add_request: reject_add_request,\n }),\n );\n bindDefault(\n bot,\n \"setMemberCard\",\n (group_id: PlatformId, user_id: PlatformId, card: string) =>\n call(memberSetCard, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n card,\n }),\n );\n bindDefault(\n bot,\n \"setMemberAdmin\",\n (group_id: PlatformId, user_id: PlatformId, enable: boolean) =>\n call(memberSetAdmin, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n enable,\n }),\n );\n bindDefault(\n bot,\n \"setMemberTitle\",\n (group_id: PlatformId, user_id: PlatformId, title: string) =>\n call(memberSetTitle, {\n group_id: toId(group_id),\n user_id: toId(user_id),\n title,\n }),\n );\n bindDefault(bot, \"pokeMember\", (group_id: PlatformId, user_id: PlatformId) =>\n call(memberPoke, { group_id: toId(group_id), user_id: toId(user_id) }),\n );\n bindDefault(bot, \"setGroupName\", (group_id: PlatformId, group_name: string) =>\n call(groupSetName, { group_id: toId(group_id), group_name }),\n );\n bindDefault(\n bot,\n \"setGroupWholeBan\",\n (group_id: PlatformId, enable: boolean) =>\n call(groupSetWholeBan, { group_id: toId(group_id), enable }),\n );\n bindDefault(bot, \"setGroupPortrait\", (group_id: PlatformId, file: string) =>\n call(groupSetPortrait, { group_id: toId(group_id), file }),\n );\n bindDefault(bot, \"leaveGroup\", (group_id: PlatformId, is_dismiss?: boolean) =>\n call(groupLeave, { group_id: toId(group_id), is_dismiss }),\n );\n bindDefault(bot, \"getFriendInfo\", (user_id: PlatformId) =>\n call(friendGetInfo, { user_id: toId(user_id) }),\n );\n bindDefault(bot, \"getFriendList\", () => call(friendGetList, {}));\n bindDefault(bot, \"deleteFriend\", (user_id: PlatformId) =>\n call(friendDelete, { user_id: toId(user_id) }),\n );\n bindDefault(bot, \"setProfile\", (profile: ProfileSetRequest) =>\n call(profileSet, profile),\n );\n bindDefault(bot, \"setAvatar\", (file: string) => call(avatarSet, { file }));\n bindDefault(\n bot,\n \"getHistory\",\n (\n t: MessageTarget,\n before?: string,\n limit?: number,\n extra?: Record<string, unknown>,\n ) => call(conversationGetHistory, { target: t, before, limit, extra }),\n );\n bindDefault(bot, \"getStatus\", () => call(botStatus, {}));\n\n return bot as B & BotBase;\n};\n","import type { Capability } from \"./capability\";\nimport type { CapabilityRegistry } from \"./registry\";\nimport type { Driver } from \"../driver\";\nimport type { Event } from \"./event\";\n\n/** 能力的作用目标:按适配器 / bot / 具体资源定位能力实现 */\nexport interface CapabilityTarget {\n readonly adapter: string;\n readonly bot_id?: string;\n readonly resource_id?: string;\n}\n\n/** 适配器定义:适配器包导出的核心对象,`defineAdapter()` 的返回值 */\nexport interface AdapterDefinition<TConfig = unknown> {\n readonly name: string;\n readonly version: string;\n /** 框架与适配器的 API 约定版本,不匹配会拒绝加载 */\n readonly apiVersion: number;\n readonly create: (\n options: AdapterFactoryOptions<TConfig>,\n ) => Adapter | Promise<Adapter>;\n readonly validateConfig?: (config: unknown) => TConfig;\n}\n\nexport interface AdapterFactoryOptions<TConfig = unknown> {\n readonly config: TConfig;\n readonly logger: import(\"../logger\").Logger;\n}\n\n/** 适配器启动后拿到的上下文:注册 bot、能力、网关与资源,派发事件 */\nexport interface AdapterContext {\n registerBot(bot: import(\"./bot\").Bot): import(\"./bot\").BotContext;\n unregisterBot(bot_id: string): void;\n getDriver(): Driver;\n registerCapability<I, O>(\n capability: Capability<I, O>,\n target: CapabilityTarget,\n handler: (input: I) => Promise<O>,\n ): () => void;\n getCapabilityRegistry(): CapabilityRegistry;\n registerGateway(gateway: AdapterGateway): () => void;\n registerResource(resource: AdapterResource): () => void;\n dispatch(event: Event): Promise<void>;\n emitLifecycle(event: BotLifecycleEvent): Promise<void>;\n /**\n * 订阅框架事件总线上的事件\n * 返回取消订阅函数\n */\n listen(\n route: string,\n handler: (event: Event) => void | Promise<void>,\n ): () => void;\n}\n\n/** 适配器实例:start 时建立连接并注册资源,stop 时释放 */\nexport interface Adapter {\n readonly name: string;\n readonly version: string;\n /** 底层实现库 */\n readonly impl?: { readonly name: string; readonly version?: string };\n\n start(context: AdapterContext): Promise<void> | void;\n stop(reason?: string): Promise<void> | void;\n}\n\n/** 网关:适配器内部的一个独立连接单元(如一条 WebSocket 连接) */\nexport interface AdapterGateway {\n readonly name: string;\n start(): Promise<void> | void;\n stop(reason?: string): Promise<void> | void;\n}\n\n/** 资源的归属范围:适配器级 / 网关级 / bot 级 */\nexport type AdapterResourceScope = \"adapter\" | \"gateway\" | \"bot\";\n\n/** 适配器声明的可释放资源,随适配器关闭一并清理 */\nexport interface AdapterResource {\n readonly name: string;\n readonly scope: AdapterResourceScope;\n readonly gateway?: string;\n readonly bot_id?: string;\n dispose(reason?: string): void | Promise<void>;\n}\n\nexport interface BotLifecycleEvent {\n readonly type: \"bot:connected\" | \"bot:disconnected\";\n readonly bot: import(\"./bot\").Bot;\n readonly reason?: string;\n}\n\nexport const defineAdapter = <TConfig>(\n definition: AdapterDefinition<TConfig>,\n): AdapterDefinition<TConfig> => definition;\n","import { UnsupportedCapabilityError, type Capability } from './capability'\nimport type { CapabilityTarget } from './types'\n\nexport interface CapabilityHandler<I, O> {\n readonly capability: Capability<I, O>\n readonly target: CapabilityTarget\n readonly handler: (input: I) => Promise<O>\n}\n\n/** 能力注册表:按目标(适配器/bot/资源)登记能力的实现,供调用方查找 */\nexport class CapabilityRegistry {\n #handlers: CapabilityHandler<unknown, unknown>[] = []\n\n /** 注册一个能力的实现,返回取消注册函数 */\n register<I, O>(\n capability: Capability<I, O>,\n target: CapabilityTarget,\n handler: (input: I) => Promise<O>,\n ): () => void {\n const existing = this.#handlers.find(\n (h) =>\n h.capability.token === capability.token &&\n h.capability.version === capability.version &&\n h.target.adapter === target.adapter &&\n (h.target.bot_id ?? null) === (target.bot_id ?? null) &&\n (h.target.resource_id ?? null) === (target.resource_id ?? null),\n )\n if (existing) {\n throw new Error(\n `Capability \"${capability.name}\" is already registered for ${target.adapter}${\n target.bot_id ? `:${target.bot_id}` : ''\n }${target.resource_id ? `/${target.resource_id}` : ''}`,\n )\n }\n const entry: CapabilityHandler<unknown, unknown> = {\n capability,\n target,\n handler: handler as (input: unknown) => Promise<unknown>,\n }\n this.#handlers.push(entry)\n return () => {\n const idx = this.#handlers.indexOf(entry)\n if (idx >= 0) this.#handlers.splice(idx, 1)\n }\n }\n\n /** 目标是否支持该能力 */\n supports<I, O>(target: CapabilityTarget, capability: Capability<I, O>): boolean {\n return this.#handlers.some(\n (h) =>\n h.capability.token === capability.token &&\n h.capability.version === capability.version &&\n h.target.adapter === target.adapter &&\n (h.target.bot_id ?? null) === (target.bot_id ?? null) &&\n (h.target.resource_id ?? null) === (target.resource_id ?? null),\n )\n }\n\n /** 在目标上调用能力,未注册时抛 `UnsupportedCapabilityError` */\n async invoke<I, O>(target: CapabilityTarget, capability: Capability<I, O>, input: I): Promise<O> {\n const handler = this.#handlers.find(\n (h) =>\n h.capability.token === capability.token &&\n h.capability.version === capability.version &&\n h.target.adapter === target.adapter &&\n (h.target.bot_id ?? null) === (target.bot_id ?? null) &&\n (h.target.resource_id ?? null) === (target.resource_id ?? null),\n )\n if (!handler) {\n throw new UnsupportedCapabilityError(capability.name)\n }\n return (handler.handler as (input: I) => Promise<O>)(input)\n }\n\n clear(): void {\n this.#handlers.length = 0\n }\n}\n","import type { MiokuContext } from '../runtime/mioku-context'\nimport type { TaskContext } from 'node-cron'\n\nexport type { MiokuContext }\n\n/** 插件卸载时执行的清理函数 */\nexport type PluginCleanup = () => void | Promise<void>\n\n/** bot 上线 / 下线时的回调 */\nexport type BotHandler = (event: import('../adapter/types').BotLifecycleEvent) => void | Promise<void>\n/** 定时任务回调 */\nexport type CronHandler = (ctx: MiokuContext, task: TaskContext) => void | Promise<void>\n/** 定时任务实例,来自 node-cron */\nexport type ScheduledTask = import('node-cron').ScheduledTask\n\n/** 插件定义 */\nexport interface MiokuPlugin {\n name: string\n version?: string\n /** 加载顺序,数值越小越先加载 */\n priority?: number\n description?: string\n /** 依赖的其他插件名 */\n dependencies?: string[]\n /** 插件入口,可返回清理函数供卸载时调用 */\n setup?(ctx: MiokuContext): void | Promise<void | PluginCleanup> | PluginCleanup\n}\n\n/** 定义一个插件,仅提供类型约束 */\nexport const definePlugin = <T extends MiokuPlugin>(plugin: T): T => plugin\n","import type { Bot, BotContext } from '../adapter'\nimport type { Capability } from '../adapter'\nimport type { AdapterContext, AdapterGateway, AdapterResource, BotLifecycleEvent, CapabilityTarget } from '../adapter'\nimport type { Driver } from '../driver'\nimport type { Event } from '../adapter'\nimport type { CapabilityRegistry } from '../adapter'\nimport type { EventBus } from './bus'\nimport type { CrossAdapterMessageDeduplicator } from './cross-adapter-dedup'\nimport type { Logger } from '../logger'\nimport type { BotRegistry } from './bots'\nimport type { Adapter } from '../adapter'\n\nexport class AdapterRegistrationConflictError extends Error {\n constructor(key: string) {\n super(`Bot already registered for ${key}`)\n this.name = 'AdapterRegistrationConflictError'\n }\n}\n\nexport interface RuntimeAdapterState {\n readonly definition: import('../adapter/types').AdapterDefinition<unknown>\n instance: Adapter | null\n context: AdapterContextImpl | null\n gateways: AdapterGateway[] | null\n resources: AdapterResource[] | null\n started: boolean\n}\n\nexport class AdapterContextImpl implements AdapterContext {\n readonly #state: RuntimeAdapterState\n readonly #bots: BotRegistry\n readonly #bus: EventBus\n readonly #driver: Driver\n readonly #capabilities: CapabilityRegistry\n readonly #logger: Logger\n readonly #emit: (event: BotLifecycleEvent) => Promise<void>\n readonly #pendingStarts = new Set<Promise<void>>()\n readonly #crossDedup: CrossAdapterMessageDeduplicator | null\n\n constructor(options: {\n state: RuntimeAdapterState\n bots: BotRegistry\n bus: EventBus\n driver: Driver\n capabilities: CapabilityRegistry\n logger: Logger\n emit: (event: BotLifecycleEvent) => Promise<void>\n crossDedup?: CrossAdapterMessageDeduplicator | null\n }) {\n this.#state = options.state\n this.#bots = options.bots\n this.#bus = options.bus\n this.#driver = options.driver\n this.#capabilities = options.capabilities\n this.#logger = options.logger\n this.#emit = options.emit\n this.#crossDedup = options.crossDedup ?? null\n }\n\n registerBot(bot: Bot): BotContext {\n return this.#bots.register(bot)\n }\n\n unregisterBot(bot_id: string): void {\n this.#bots.unregister(bot_id, this.#state.definition.name)\n }\n\n getDriver(): Driver {\n return this.#driver\n }\n\n registerCapability<I, O>(\n capability: Capability<I, O>,\n target: CapabilityTarget,\n handler: (input: I) => Promise<O>,\n ): () => void {\n const finalTarget: CapabilityTarget = {\n ...target,\n adapter: target.adapter ?? this.#state.definition.name,\n }\n return this.#capabilities.register(capability, finalTarget, handler)\n }\n\n getCapabilityRegistry(): CapabilityRegistry {\n return this.#capabilities\n }\n\n registerGateway(gateway: AdapterGateway): () => void {\n if (!this.#state.gateways) {\n throw new Error('registerGateway called outside of adapter start()')\n }\n if (this.#state.gateways.find((g) => g.name === gateway.name)) {\n throw new Error(`Gateway \"${gateway.name}\" already registered for adapter \"${this.#state.definition.name}\"`)\n }\n this.#state.gateways.push(gateway)\n const startPromise = Promise.resolve(gateway.start()).then(\n () => undefined,\n (err: unknown) => {\n this.#logger.error(`Gateway \"${gateway.name}\" failed to start`, err)\n throw err\n },\n )\n this.#pendingStarts.add(startPromise)\n void startPromise.then(\n () => this.#pendingStarts.delete(startPromise),\n () => this.#pendingStarts.delete(startPromise),\n )\n return () => {\n const idx = this.#state.gateways?.indexOf(gateway) ?? -1\n if (idx >= 0 && this.#state.gateways) {\n this.#state.gateways.splice(idx, 1)\n void Promise.resolve(gateway.stop('unregistered')).catch(() => undefined)\n }\n }\n }\n\n async waitForStarts(): Promise<void> {\n await Promise.all(this.#pendingStarts)\n }\n\n registerResource(resource: AdapterResource): () => void {\n if (!this.#state.resources) {\n throw new Error('registerResource called outside of adapter start()')\n }\n if (resource.scope === 'gateway' && !resource.gateway) {\n throw new Error('Resource with scope \"gateway\" requires gateway name')\n }\n if (resource.scope === 'bot' && !resource.bot_id) {\n throw new Error('Resource with scope \"bot\" requires bot_id')\n }\n if (resource.scope === 'gateway') {\n const gateway = this.#state.gateways?.find((g) => g.name === resource.gateway)\n if (!gateway) {\n throw new Error(`Resource references unknown gateway \"${resource.gateway}\"`)\n }\n }\n if (resource.scope === 'bot') {\n const key = `${this.#state.definition.name}:${resource.bot_id}`\n if (!this.#bots.has(key)) {\n throw new Error(`Resource references unknown bot \"${resource.bot_id}\"`)\n }\n }\n this.#state.resources.push(resource)\n return () => {\n const idx = this.#state.resources?.indexOf(resource) ?? -1\n if (idx >= 0 && this.#state.resources) {\n this.#state.resources.splice(idx, 1)\n void Promise.resolve(resource.dispose('unregistered')).catch(() => undefined)\n }\n }\n }\n\n async dispatch(event: Event): Promise<void> {\n if (event.kind === 'message') {\n // 发送者是本运行时里另一台已连接 bot(如同群的其它 bot 实例)时,\n // 不进入任何 handler,切断 bot 互相触发导致的循环。\n // 发送者恰为接收 bot 自身 id 的消息(自身回显、stdin 控制台用户)保持原行为,\n // 由插件层的 self 过滤与 owner 体系处理。\n const senderId = event.user_id\n if (senderId != null) {\n const senderBot = this.#bots.pick(senderId)\n if (senderBot && senderBot.bot_id !== event.self_id) {\n this.#logger.debug(\n `拦截来自其他已连接 bot 的消息: sender=${senderId} self=${event.self_id}`,\n )\n return\n }\n }\n if (this.#crossDedup?.isDuplicate(event)) {\n this.#logger.debug(\n `丢弃跨适配器重复消息: adapter=${event.identity?.adapter ?? ''} sender=${event.user_id ?? ''}`,\n )\n return\n }\n }\n await this.#bus.dispatch(event)\n }\n\n listen(route: string, handler: (event: Event) => void | Promise<void>): () => void {\n return this.#bus.register(route, handler, {\n source: `adapter:${this.adapterName}`,\n priority: 0,\n })\n }\n\n emitLifecycle(event: BotLifecycleEvent): Promise<void> {\n return this.#emit(event)\n }\n\n get adapterName(): string {\n return this.#state.definition.name\n }\n}\n","// Framework singletons are stashed on globalThis so they survive jiti's\n// moduleCache-off re-evaluation (mioku loads plugins via jiti). Callers that\n// live in the normally-cached `mioku` dist could use a plain module-level\n// const, but the global indirection keeps things stable if a plugin ever\n// re-imports the framework through jiti.\n\nconst STORE_SYMBOL = Symbol.for(\"mioku.globalStore\");\ntype GlobalStore = Record<string, unknown>;\n\nfunction store(): GlobalStore {\n const g = globalThis as unknown as Record<symbol, GlobalStore>;\n if (!g[STORE_SYMBOL]) g[STORE_SYMBOL] = {};\n return g[STORE_SYMBOL]!;\n}\n\nexport function getOrCreate<T>(key: string, factory: () => T): T {\n const s = store();\n if (s[key] === undefined) s[key] = factory();\n return s[key] as T;\n}\n","import { getOrCreate } from '../internal/registry'\n\nimport type { Bot } from '../adapter'\n\n/** 当前已连接的全部 bot,按 `adapter:bot_id` 索引 */\nexport const connectedBots: Map<string, Bot> = getOrCreate('connected-bots', () => new Map())\n\n/** 生成 bot 在连接表中的键:`adapter:bot_id` */\nexport const connectedBotKey = (adapter: string, bot_id: string): string => `${adapter}:${bot_id}`\n\n/** 兼容旧版 API 的别名:过去的 NapCat 扩展类型现在就是通用 Bot */\nexport type ExtendedNapCat = Bot","import { AdapterRegistrationConflictError } from './context'\nimport { connectedBotKey, connectedBots } from '../compat/connected-bots'\n\nimport type { Bot, BotContext } from '../adapter'\n\n/** Bot 注册表:登记已连接的 bot,按 bot_id 查询 */\nexport class BotRegistry {\n #bots = new Map<string, { adapter: string; bot_id: string; bot: Bot }>()\n #disposers = new Map<string, () => void>()\n\n /** 登记一个 bot,返回可注销的上下文 */\n register(bot: Bot): BotContext {\n const key = connectedBotKey(bot.adapter, bot.bot_id)\n if (this.#bots.has(key)) {\n throw new AdapterRegistrationConflictError(key)\n }\n this.#bots.set(key, { adapter: bot.adapter, bot_id: bot.bot_id, bot })\n connectedBots.set(key, bot)\n const dispose = (): void => {\n this.unregister(bot.bot_id, bot.adapter)\n }\n this.#disposers.set(key, dispose)\n return {\n bot,\n unregister: dispose,\n }\n }\n\n has(key: string): boolean {\n return this.#bots.has(key)\n }\n\n unregister(bot_id: string, adapter: string): boolean {\n const key = connectedBotKey(adapter, bot_id)\n const removed = this.#bots.delete(key)\n this.#disposers.delete(key)\n connectedBots.delete(key)\n return removed\n }\n\n /** 按 bot_id 取 bot(只按 id 匹配,不限适配器) */\n pick<T extends Bot = Bot>(bot_id: string | number): T | undefined {\n const key = String(bot_id)\n for (const entry of this.#bots.values()) {\n if (entry.bot_id === key) return entry.bot as T\n }\n return undefined\n }\n\n all<T extends Bot = Bot>(): readonly T[] {\n return Array.from(this.#bots.values()).map((entry) => entry.bot as T)\n }\n\n size(): number {\n return this.#bots.size\n }\n\n clear(): void {\n this.#bots.clear()\n this.#disposers.clear()\n connectedBots.clear()\n }\n}","import type { Event } from '../adapter'\n\nexport type EventHandler<E extends Event = Event> = (event: E) => void | Promise<void>\n\nexport interface Registration {\n readonly id: number\n readonly route: string\n readonly source: string\n readonly handler: EventHandler<Event>\n readonly priority: number\n readonly order: number\n disposed: boolean\n}\n\nexport interface BusStats {\n readonly registered: number\n readonly dispatched: number\n}\n\nconst WILDCARD = '*'\n\nconst isWildcardMatch = (pattern: string, route: string): boolean => {\n if (pattern === route) return true\n if (!pattern.includes(WILDCARD)) return false\n if (pattern === WILDCARD) return true\n const prefix = pattern.slice(0, -1)\n if (!prefix.endsWith('.')) return false\n return route === prefix.slice(0, -1) || route.startsWith(prefix)\n}\n\n/**\n * 事件总线:按路由把事件分发给所有匹配的监听器。\n * 支持 `*` 通配符,同一优先级按注册顺序执行,不同优先级按数值升序。\n */\nexport class EventBus {\n #registrations: Registration[] = []\n #nextId = 1\n #nextOrder = 0\n #dispatched = 0\n #logger: ((level: 'error' | 'warn' | 'info', message: string, detail?: unknown) => void) | null = null\n\n setLogger(logger: ((level: 'error' | 'warn' | 'info', message: string, detail?: unknown) => void) | null): void {\n this.#logger = logger\n }\n\n /** 注册事件监听,返回取消注册函数 */\n register<E extends Event = Event>(\n route: string,\n handler: EventHandler<E>,\n options: { source?: string; priority?: number } = {},\n ): () => void {\n if (!route) {\n throw new Error('EventBus.register: route must be a non-empty string')\n }\n if (typeof handler !== 'function') {\n throw new Error('EventBus.register: handler must be a function')\n }\n const id = this.#nextId++\n const order = this.#nextOrder++\n const reg: Registration = {\n id,\n route,\n source: options.source ?? 'anonymous',\n handler: handler as EventHandler<Event>,\n priority: options.priority ?? 0,\n order,\n disposed: false,\n }\n this.#registrations.push(reg)\n return () => this.#unregister(id)\n }\n\n #unregister(id: number): void {\n const idx = this.#registrations.findIndex((r) => r.id === id)\n if (idx >= 0) {\n this.#registrations[idx].disposed = true\n this.#registrations.splice(idx, 1)\n }\n }\n\n clear(): void {\n for (const reg of this.#registrations) reg.disposed = true\n this.#registrations = []\n }\n\n #matching(event: Event): Registration[] {\n const matched: Registration[] = []\n for (const reg of this.#registrations) {\n if (reg.disposed) continue\n if (isWildcardMatch(reg.route, event.type)) {\n matched.push(reg)\n continue\n }\n for (const route of event.routes) {\n if (isWildcardMatch(reg.route, route)) {\n matched.push(reg)\n break\n }\n }\n }\n return matched\n }\n\n /** 派发一个事件给所有匹配的监听器,单个监听器出错不影响其他监听器 */\n async dispatch(event: Event): Promise<void> {\n const matched = this.#matching(event)\n if (matched.length === 0) return\n this.#dispatched++\n\n const priorityGroups = new Map<number, Registration[]>()\n for (const reg of matched) {\n const list = priorityGroups.get(reg.priority)\n if (list) list.push(reg)\n else priorityGroups.set(reg.priority, [reg])\n }\n const sortedPriorities = Array.from(priorityGroups.entries()).sort(([a], [b]) => a - b)\n\n for (const [, regs] of sortedPriorities) {\n regs.sort((a, b) => a.order - b.order)\n await Promise.allSettled(\n regs.map((reg) =>\n Promise.resolve()\n .then(() => reg.handler(event))\n .catch((err) => {\n this.#logger?.(\n 'error',\n `Event handler \"${reg.source}\" for route \"${reg.route}\" failed`,\n err,\n )\n }),\n ),\n )\n }\n }\n\n stats(): BusStats {\n return {\n registered: this.#registrations.length,\n dispatched: this.#dispatched,\n }\n }\n}\n","// 常用工具函数集,均从 `mioku` 顶层导出,插件可直接 import 使用。\n\nimport crypto from \"node:crypto\";\nimport mriLib from \"mri\";\nimport { Low } from \"lowdb\";\nimport { DataFile } from \"lowdb/node\";\nimport { string2argv } from \"string2argv\";\n\nimport type { Message, MessageSegment } from \"./adapter\";\nimport type { BinaryLike, BinaryToTextEncoding } from \"node:crypto\";\nimport type { ConsolaInstance } from \"consola/core\";\n\nexport { default as prettyMs } from \"pretty-ms\";\nexport { filesize } from \"filesize\";\nexport { string2argv } from \"string2argv\";\nexport { default as fs } from \"node:fs\";\nexport { default as path } from \"node:path\";\nexport { default as dayjs } from \"dayjs\";\nexport { default as dedent } from \"dedent\";\nexport { mriLib as mri };\nexport { colors, stripAnsi, box, colorize } from \"consola/utils\";\n\nexport const ChromeUA =\n \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0.0.0\";\n\nexport type Noop = () => void;\nexport type AnyFunc = (...args: any[]) => any;\nexport type PureObject<T = unknown> = Record<PropertyKey, T>;\nexport type Arrayable<T> = T | T[];\nexport type Awaitable<T> = T | Promise<T>;\nexport type Gettable<T> = T | (() => T);\n\nexport interface HasMessage {\n readonly message: Message;\n}\n\nexport interface CreateCmdOptions {\n prefix?: string;\n onPrefix?(): void;\n}\n\n/** 解析命令行字符串:返回命令、位置参数与 `--xxx` 选项 */\nexport const createCmd = (\n cmdStr: string,\n options: CreateCmdOptions = {},\n): {\n cmd: string | undefined;\n params: string[];\n options: Record<string, unknown>;\n} => {\n const { prefix = \"\", onPrefix = () => undefined } = options;\n const { _, ...cmdOptions } = mriLib(string2argv(cmdStr));\n const [cmd, ...params] = _ as string[];\n if (prefix) {\n if (cmd !== prefix)\n return { cmd: undefined, params: [], options: cmdOptions };\n if (params.length === 0) onPrefix();\n const prefixedCmd = params.shift();\n return { cmd: prefixedCmd, params, options: cmdOptions };\n }\n return { cmd, params, options: cmdOptions };\n};\n\n/** 在指定路径创建并读取一个 lowdb JSON 数据库 */\nexport const createDB = async <T extends object = object>(\n filename: string,\n options: { defaultData?: T; compress?: boolean } = {},\n): Promise<Low<T>> => {\n const { defaultData = {} as T, compress = false } = options;\n const database = new Low<T>(\n new DataFile<T>(filename, {\n parse: JSON.parse,\n stringify: (data: T) => JSON.stringify(data, null, compress ? 0 : 2),\n }),\n defaultData,\n );\n await database.read();\n return database;\n};\n\n/** 在插件目录下创建并读取一个 JSON 数据存储(默认 `data.json`) */\nexport const createStore = async <T extends object = object>(\n defaultData: T,\n options: {\n __dirname?: string;\n importMeta?: ImportMeta;\n compress?: boolean;\n filename?: string;\n } = {},\n): Promise<Low<T>> => {\n const {\n compress = false,\n __dirname,\n importMeta: meta,\n filename = \"data.json\",\n } = options;\n const path = await import(\"node:path\");\n const { fileURLToPath } = await import(\"node:url\");\n const dirname =\n __dirname ||\n meta?.dirname ||\n (meta?.url ? path.dirname(fileURLToPath(meta.url)) : \"\");\n if (!dirname)\n throw new Error(\n \"createStore: options.__dirname or options.meta must be provided\",\n );\n const filePath = path.join(dirname, filename);\n const database = new Low<T>(\n new DataFile<T>(filePath, {\n parse: JSON.parse,\n stringify: (data: T) => JSON.stringify(data, null, compress ? 0 : 2),\n }),\n defaultData,\n );\n await database.read();\n await database.write();\n return database;\n};\n\nexport const md5 = (\n text: BinaryLike,\n encoding: BinaryToTextEncoding | \"buffer\" = \"hex\",\n): string | Buffer => {\n const hash = crypto.createHash(\"md5\").update(text);\n if (encoding === \"buffer\") return hash.digest();\n return hash.digest(encoding);\n};\n\nexport const unique = <T>(array: T[]): T[] => Array.from(new Set(array));\n\nexport const toArray = <T>(value: T | T[]): T[] =>\n Array.isArray(value) ? value : [value];\n\nexport const wait = (ms: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\nexport const localeDate = (\n ts: number | string | Date = Date.now(),\n options: { locale?: string; timeZone?: string } = {},\n): string => {\n const { locale = \"zh-CN\", timeZone = \"Asia/Shanghai\" } = options;\n const today = ts instanceof Date ? ts : new Date(ts);\n return new Intl.DateTimeFormat(locale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n timeZone,\n }).format(today);\n};\n\nexport const localeTime = (\n ts: number | string | Date = Date.now(),\n options: { locale?: string; timeZone?: string; seconds?: boolean } = {},\n): string => {\n const {\n locale = \"zh-CN\",\n timeZone = \"Asia/Shanghai\",\n seconds = true,\n } = options;\n const now = ts instanceof Date ? ts : new Date(ts);\n return new Intl.DateTimeFormat(locale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n hourCycle: \"h23\",\n minute: \"2-digit\",\n second: seconds ? \"2-digit\" : undefined,\n timeZone,\n }).format(now);\n};\n\nexport const randomInt = (\n min: number,\n max: number,\n ...hashArgs: unknown[]\n): number => {\n if (min > max) throw new Error(\"min must be less than or equal to max\");\n if (hashArgs.length === 0)\n return Math.floor(Math.random() * (max - min + 1)) + min;\n const sortedArgs = hashArgs.slice().sort((a, b) => {\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n return JSON.stringify(a).localeCompare(JSON.stringify(b));\n });\n const hash = md5(JSON.stringify(sortedArgs));\n const hashText = typeof hash === \"string\" ? hash : hash.toString(\"hex\");\n const hashValue = Number.parseInt(hashText.slice(0, 8), 16);\n const range = max - min + 1;\n return (((hashValue % range) + range) % range) + min;\n};\n\nexport const randomItem = <T>(\n array: readonly T[],\n ...hashArgs: unknown[]\n): T => {\n if (!Array.isArray(array) || !array.length)\n throw new Error(\"randomItem: 参数必须是数组,且不能为空\");\n return array[randomInt(0, array.length - 1, ...hashArgs)];\n};\n\nexport const randomItems = <T>(\n array: readonly T[],\n count: number,\n ...hashArgs: unknown[]\n): T[] => {\n if (!Array.isArray(array) || !array.length)\n throw new Error(\"randomItems: 参数必须是数组,且不能为空\");\n if (count < 0) throw new Error(\"randomItems: count 必须为非负整数\");\n if (count === 0) return [];\n if (count > array.length)\n throw new Error(\n `randomItems: 要选择的数量 (${count}) 超过了数组长度 (${array.length})`,\n );\n if (count === array.length) return [...array];\n const indices = Array.from({ length: array.length }, (_, i) => i);\n const selected: number[] = [];\n for (let i = 0; i < count; i++) {\n const remainingCount = indices.length - i;\n const randomIdx = randomInt(\n 0,\n remainingCount - 1,\n ...hashArgs,\n `select_${i}`,\n );\n selected.push(indices[randomIdx]);\n const lastIdx = indices.length - 1 - i;\n [indices[randomIdx], indices[lastIdx]] = [\n indices[lastIdx],\n indices[randomIdx],\n ];\n }\n const isString = (v: unknown): v is string => typeof v === \"string\";\n const hasString = array.some(isString);\n const items = selected.map((idx) => array[idx]);\n return hasString\n ? items.sort((p, n) =>\n isString(p) && isString(n) ? p.localeCompare(n) : 0,\n )\n : items;\n};\n\nexport const randomId = (): string =>\n Math.random().toString(16).slice(2, 8).toUpperCase();\n\nexport const uuid = (): string => {\n const rand = (length = 4): string =>\n Math.random()\n .toString(16)\n .substring(2, length + 2);\n return `${rand(8)}-${rand(4)}-${rand(4)}-${rand(4)}-${rand(12)}`;\n};\n\nexport const clamp = (n: number, min: number, max: number): number =>\n Math.min(max, Math.max(min, n));\n\nexport const noNullish = <T>(val: T | null | undefined): val is T =>\n val !== null && val !== undefined;\n\nexport const isDefined = <T = unknown>(val?: T): val is T =>\n typeof val !== \"undefined\";\n\nexport const isFunction = <T extends AnyFunc = AnyFunc>(\n val: unknown,\n): val is T => typeof val === \"function\";\n\nexport const isNumber = (val: unknown): val is number =>\n typeof val === \"number\";\n\nexport const isBoolean = (val: unknown): val is boolean =>\n typeof val === \"boolean\";\n\nexport const isString = (val: unknown): val is string =>\n typeof val === \"string\";\n\nexport const isObject = (val: unknown): val is Record<string, unknown> =>\n Object.prototype.toString.call(val) === \"[object Object]\";\n\nexport const localNum = (num: number, locale = \"zh-CN\"): string =>\n num.toLocaleString(locale);\n\nexport const base64Encode = (str: string | number | Buffer): string =>\n Buffer.from(str.toString()).toString(\"base64\");\n\nexport const base64Decode = (\n str: string,\n type: \"buffer\" | BufferEncoding = \"utf8\",\n): string | Buffer => {\n if (type === \"buffer\") return Buffer.from(str, \"base64\");\n return Buffer.from(str, \"base64\").toString(type);\n};\n\nexport const qs = (obj: Record<number | string, unknown>): string =>\n new URLSearchParams(obj as Record<string, string>).toString();\n\nexport const stringifyError = (error: unknown): string => {\n if (typeof error === \"object\" && error !== null) {\n const e = error as {\n constructor?: { name?: string };\n message?: string;\n stack?: string;\n };\n const errorType = e.constructor?.name ?? \"未知错误\";\n const errorMessage = e.message ?? \"[无报错信息]\";\n if (e.stack) return `${errorType}: ${errorMessage}\\n${e.stack}`;\n return `${errorType}: ${errorMessage}`;\n }\n return String(error);\n};\n\nexport const formatDuration = (ms: number): string => {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n if (days > 0) return `${days}天${hours % 24}小时`;\n if (hours > 0) return `${hours}小时${minutes % 60}分钟`;\n if (minutes > 0) return `${minutes}分钟${seconds % 60}秒`;\n return `${seconds}秒`;\n};\n\nexport const getTerminalInput = (inputTip = \"请输入\"): Promise<string> =>\n new Promise((resolve) => {\n if (inputTip) console.log(inputTip);\n const getInput = (): void => {\n process.stdin.once(\"data\", (e) => {\n const input = e.toString().trim();\n if (input) {\n resolve(input);\n return;\n }\n getInput();\n });\n };\n getInput();\n });\n\nexport const getGTk = (pskey: string): number => {\n let gkt = 5381;\n for (let i = 0, len = pskey.length; i < len; ++i) {\n gkt += (gkt << 5) + pskey.charCodeAt(i);\n }\n return gkt & 0x7fffffff;\n};\n\nexport type MatchHandler<T extends HasMessage> = (\n matches: RegExpMatchArray,\n event: T,\n) => unknown | Promise<unknown>;\n\nexport type MatchValue =\n | string\n | number\n | boolean\n | Message\n | MessageSegment\n | readonly (string | MessageSegment)[];\n\n/**\n * 关键词匹配路由:pattern 的键支持正则(`/.../`)、通配符(`*`)与纯文本,\n * 命中后执行对应的处理函数或直接回复静态内容。\n */\nexport const match = async <T extends HasMessage>(\n event: T,\n pattern: Record<string, MatchHandler<T> | MatchValue>,\n quote: boolean = true,\n): Promise<{ message_id: string } | null> => {\n const inputText = event.message.text();\n for (const [key, value] of Object.entries(pattern)) {\n let isMatched = false;\n let matches: RegExpMatchArray | null = null;\n const isRegExp = key.startsWith(\"/\") && key.endsWith(\"/\");\n const hasWildcard = key.includes(\"*\");\n if (isRegExp) {\n try {\n const regex = new RegExp(key.slice(1, -1));\n matches = inputText.match(regex);\n if (matches) isMatched = true;\n } catch (err) {\n throw new Error(`无效的正则表达式: ${key}`, { cause: err });\n }\n } else if (hasWildcard) {\n const regex = new RegExp(\n `^${key.replace(/\\./g, \"\\\\.\").replace(/\\*/g, \".*\")}$`,\n );\n matches = inputText.match(regex);\n if (matches) isMatched = true;\n } else if (key === inputText) {\n isMatched = true;\n }\n if (!isMatched) continue;\n const result =\n typeof value === \"function\"\n ? await value(matches as RegExpMatchArray, event)\n : value;\n if (result) {\n const reply = (\n event as unknown as {\n reply?: (\n content: unknown,\n quote?: boolean,\n ) => Promise<{ message_id: string }>;\n }\n ).reply;\n if (reply) return await reply(result, quote);\n }\n }\n return null;\n};\n\nexport const text = (\n source: HasMessage | Message,\n options: { trim?: boolean | \"whole\" | \"each\" } = {},\n): string => {\n const { trim = true } = options;\n const message = getMessage(source);\n const texts = message\n .filterByType(\"text\")\n .map((seg) => (typeof seg.data.text === \"string\" ? seg.data.text : \"\"));\n if (trim === \"whole\") return texts.join(\"\").trim();\n if (trim === \"each\") return texts.map((t) => t.trim()).join(\"\");\n if (trim === true) return texts.map((t) => t.trim()).join(\"\");\n return texts.join(\"\");\n};\n\nexport const find = <\n T extends Message[\"length\"] extends 0 ? never : Message[number],\n>(\n source: HasMessage | Message,\n type: string,\n): T | undefined => {\n const message = getMessage(source);\n return message.find((seg) => seg.type === type) as T | undefined;\n};\n\nexport const filter = <\n T extends Message[\"length\"] extends 0 ? never : Message[number],\n>(\n source: HasMessage | Message,\n type: string,\n): T[] => {\n const message = getMessage(source);\n return message.filter((seg) => seg.type === type) as T[];\n};\n\nconst ADAPTER_DISPLAY_NAMES: Readonly<Record<string, string>> = {\n stdin: \"标准输入\",\n onebotv11: \"OneBot v11\",\n icqq: \"ICQQ\",\n};\n\nexport const displayAdapterId = (\n id: string | number | null | undefined,\n): string => {\n if (id == null) return \"\";\n return ADAPTER_DISPLAY_NAMES[String(id)] ?? String(id);\n};\n\nexport { type ConsolaInstance };\n\nconst getMessage = (source: HasMessage | Message): Message => {\n if (Array.isArray(source) && typeof (source as Message).text === \"function\")\n return source as Message;\n return (source as HasMessage).message;\n};\n","import fs from 'node:fs'\nimport path from 'node:path'\nimport util from 'node:util'\nimport { colors } from 'consola/utils'\nimport { createConsola, LogLevels } from 'consola/core'\nimport { BOT_CWD, readMiokuConfig, updateMiokuConfig } from '../config'\n\nimport type { Logger, LogLevel } from './types'\nimport type { ConsolaInstance } from 'consola/core'\n\n/** consola 数字级别对应的名称与颜色 */\nconst LEVEL_MAP: Readonly<Record<number, { name: string; color: 'red' | 'yellow' | 'white' | 'green' | 'blue' | 'gray' }>> = {\n 0: { name: 'ERROR', color: 'red' },\n 1: { name: 'WARN', color: 'yellow' },\n 2: { name: 'LOG', color: 'white' },\n 3: { name: 'INFO', color: 'green' },\n 4: { name: 'DEBUG', color: 'blue' },\n 5: { name: 'TRACE', color: 'gray' },\n}\n\nlet cachedRoot: ConsolaInstance | null = null\nlet cachedRootLevel: LogLevel = 'info'\n\n/** 惰性创建根 logger,日志级别取自 mioku 配置 */\nconst resolveRoot = (): ConsolaInstance => {\n if (cachedRoot) return cachedRoot\n let level: LogLevel = 'info'\n try {\n level = readMiokuConfig().log_level ?? 'info'\n } catch {\n level = 'info'\n }\n cachedRootLevel = level\n cachedRoot = createConsola({\n level: LogLevels[level] ?? LogLevels.info,\n defaults: { tag: 'mioku' },\n formatOptions: { colors: true, compact: true, date: true },\n })\n return cachedRoot\n}\n\n/** 本次运行的日志文件路径:logs/ 下按启动时间命名 */\nconst getLogFile = (): string => {\n const cwd = BOT_CWD.value\n const dir = path.join(cwd, 'logs')\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true })\n const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19)\n return path.join(dir, `${stamp}.log`)\n}\n\nconst ensureFile = (file: string): void => {\n if (!fs.existsSync(file)) {\n fs.mkdirSync(path.dirname(file), { recursive: true })\n fs.writeFileSync(file, '')\n }\n}\n\nconst renderMessage = (args: unknown[]): string =>\n args\n .map((arg) => (typeof arg === 'string' ? arg : util.inspect(arg, { colors: false, depth: 4 })))\n .join(' ')\n\n/** 渲染控制台输出的彩色日志行 */\nconst renderColored = (level: number, tag: string | undefined, args: unknown[]): string => {\n const time = colors.gray(`[${new Date().toLocaleTimeString('zh-CN')}]`)\n const meta = LEVEL_MAP[level] ?? LEVEL_MAP[3]\n const levelText = colors.bold(colors[meta.color](meta.name))\n const tagText = tag ? colors.dim(`[${tag}]`) : ''\n const message = renderMessage(args)\n return `${time} ${levelText} ${tagText} ${message}`\n}\n\n/** 把日志行追加写入文件,失败时静默忽略 */\nconst writeFile = (level: number, tag: string | undefined, args: unknown[], file: string): void => {\n try {\n ensureFile(file)\n const iso = new Date().toISOString()\n const meta = LEVEL_MAP[level] ?? LEVEL_MAP[3]\n const prefix = `[${iso}] [${meta.name}]${tag ? ` [${tag}]` : ''}`\n fs.appendFileSync(file, `${prefix} ${renderMessage(args)}\\n`)\n } catch {\n // best-effort logging, swallow file errors\n }\n}\n\n/** 写入文件并按级别输出到对应的标准流 */\nconst dispatch = (\n level: number,\n tag: string | undefined,\n args: unknown[],\n file: string,\n): void => {\n writeFile(level, tag, args, file)\n const line = renderColored(level, tag, args)\n if (level === LogLevels.error) console.error(line)\n else if (level === LogLevels.warn) console.warn(line)\n else if (level === LogLevels.log) console.log(line)\n else if (level === LogLevels.info) console.info(line)\n else console.debug(line)\n}\n\n/** 带标签与作用域的 logger 实现 */\nclass ScopedLogger implements Logger {\n readonly #parent: ConsolaInstance | null\n readonly #tag: string | undefined\n readonly #scope: Readonly<Record<string, unknown>>\n readonly #file: string\n readonly #threshold: number\n\n constructor(options: {\n parent: ConsolaInstance | null\n tag: string | undefined\n scope: Record<string, unknown>\n file: string\n threshold: number\n }) {\n this.#parent = options.parent\n this.#tag = options.tag\n this.#scope = options.scope\n this.#file = options.file\n this.#threshold = options.threshold\n }\n\n get level(): LogLevel {\n if (!this.#parent) return 'info'\n const lv = this.#parent.level\n for (const [k, v] of Object.entries(LogLevels)) {\n if (v === lv) return k as LogLevel\n }\n return 'info'\n }\n\n #tagWithScope(): string {\n const tags = [this.#tag, ...Object.entries(this.#scope).map(([k, v]) => `${k}:${String(v)}`)].filter(Boolean)\n return tags.join(':')\n }\n\n #log(level: number, args: unknown[]): void {\n if (level > this.#threshold) return\n if (this.#parent && level > this.#parent.level) return\n dispatch(level, this.#tagWithScope(), args, this.#file)\n }\n\n error(...args: unknown[]): void {\n this.#log(LogLevels.error, args)\n }\n\n warn(...args: unknown[]): void {\n this.#log(LogLevels.warn, args)\n }\n\n log(...args: unknown[]): void {\n this.#log(LogLevels.log, args)\n }\n\n info(...args: unknown[]): void {\n this.#log(LogLevels.info, args)\n }\n\n debug(...args: unknown[]): void {\n this.#log(LogLevels.debug, args)\n }\n\n trace(...args: unknown[]): void {\n this.#log(LogLevels.trace, args)\n }\n\n withTag(tag: string): Logger {\n const merged = this.#tag ? `${this.#tag}:${tag}` : tag\n return new ScopedLogger({\n parent: this.#parent,\n tag: merged,\n scope: this.#scope,\n file: this.#file,\n threshold: this.#threshold,\n })\n }\n\n child(scope: Record<string, unknown>): Logger {\n return new ScopedLogger({\n parent: this.#parent,\n tag: this.#tag,\n scope: { ...this.#scope, ...scope },\n file: this.#file,\n threshold: this.#threshold,\n })\n }\n}\n\n/** 创建挂在根 logger 下的日志器,输出统一落盘到本次运行的日志文件 */\nexport const createMiokuLogger = (options: { tag?: string; level?: LogLevel; scope?: Record<string, unknown> } = {}): Logger => {\n const root = resolveRoot()\n const file = getLogFile()\n const threshold = LogLevels[(options.level ?? cachedRootLevel) as LogLevel] ?? LogLevels.info\n return new ScopedLogger({\n parent: root,\n tag: options.tag,\n scope: options.scope ?? {},\n file,\n threshold,\n })\n}\n\n/** 全局根 logger */\nexport const rootLogger: Logger = createMiokuLogger()\n\n/** 运行时调整日志级别,并写回 mioku 配置 */\nexport const applyLogLevel = (level: LogLevel): void => {\n cachedRootLevel = level\n if (cachedRoot) {\n cachedRoot.level = LogLevels[level] ?? LogLevels.info\n }\n try {\n updateMiokuConfig((config) => {\n config.log_level = level\n }).then()\n } catch {\n // config update may fail in non-mutating contexts; ignore.\n }\n}\n\nexport type { Logger, LogLevel }","import { wait } from './utils'\nimport { rootLogger } from './logger'\n\nimport type { Bot } from './adapter'\nimport type { MessageInput } from './adapter'\nimport type { MessageTarget } from './adapter'\n\n/** 群发通知的选项 */\nexport interface NoticeOptions {\n /** 相邻两个目标之间的发送间隔(毫秒),默认 1000 */\n readonly delay?: number\n /** 统一覆盖发送目标,默认按名单逐个生成 */\n readonly target?: MessageTarget\n}\n\n/** 通过指定 bot 发送一条消息 */\nexport const sendMessage = async (bot: Bot, target: MessageTarget, message: MessageInput): Promise<unknown> => {\n return await bot.sendMessage(target, message)\n}\n\n/** 逐目标群发:每个目标依次尝试各 bot 直到成功,目标之间间隔 delay 毫秒 */\nconst notifyAll = async (\n bots: readonly Bot[],\n targets: readonly MessageTarget[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n const delay = options.delay ?? 1000\n for (const target of targets) {\n let sent = false\n for (const bot of bots) {\n try {\n await bot.sendMessage(target, message)\n sent = true\n break\n } catch {\n // 跳过失败的 bot,尝试下一个\n }\n }\n if (!sent) {\n rootLogger.warn(`通知目标 ${JSON.stringify(target)} 失败`)\n }\n await wait(delay)\n }\n}\n\n/** 向多个群发送同一条消息 */\nexport const noticeGroups = async (\n bots: readonly Bot[],\n groupIds: readonly (string | number)[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n await notifyAll(\n bots,\n groupIds.map((group_id) => ({ type: 'group', group_id })),\n message,\n options,\n )\n}\n\n/** 向多个好友私聊发送同一条消息 */\nexport const noticeFriends = async (\n bots: readonly Bot[],\n userIds: readonly (string | number)[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n await notifyAll(\n bots,\n userIds.map((user_id) => ({ type: 'private', user_id })),\n message,\n options,\n )\n}\n\n/** 通知所有 owner,可通过 options.target 统一改发到别的目标 */\nexport const noticeOwners = async (\n bots: readonly Bot[],\n owners: readonly string[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n await notifyAll(\n bots,\n owners.map((user_id) => options.target ?? ({ type: 'private', user_id } as MessageTarget)),\n message,\n options,\n )\n}\n\n/** 通知所有管理员,行为与 noticeOwners 一致 */\nexport const noticeAdmins = async (\n bots: readonly Bot[],\n admins: readonly string[],\n message: MessageInput,\n options: NoticeOptions = {},\n): Promise<void> => {\n return noticeOwners(bots, admins, message, options)\n}","import { getOrCreate } from '../internal/registry'\n\nconst services = getOrCreate<Record<string, unknown>>('services-registry', () => ({}))\n\n/** 按名称索引的服务注册表 */\nexport interface MiokuServices {\n [key: string]: unknown\n}\n\n/** 全局服务注册表实例,已加载的服务都注册在这里 */\nexport const servicesRegistry = services\n\n/** 按名称取服务,不存在时返回 undefined */\nexport const getService = <T = unknown>(name: string): T | undefined => services[name] as T | undefined\n\n/**\n * 注册服务并返回移除该服务的函数。\n * cover 为 false 且同名服务已存在时跳过注册。\n */\nexport const setService = <T = unknown>(name: string, value: T, cover: boolean = true): () => void => {\n if (cover || !services[name]) {\n services[name] = value\n }\n return () => {\n delete services[name]\n }\n}\n\n/** setService 的别名 */\nexport const addService = <T = unknown>(name: string, value: T, cover: boolean = true): (() => void) => {\n return setService(name, value, cover)\n}\n\n/** 惰性创建服务的工厂函数 */\nexport type ServiceFactory<T> = () => T","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { pathToFileURL } from \"node:url\";\n\nexport interface DiscoveredModule {\n name: string;\n path: string;\n}\n\nexport async function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function resolveRealpath(p: string): Promise<string> {\n try {\n return await fs.realpath(p);\n } catch {\n return p;\n }\n}\n\nexport function toImportPath(filePath: string): string {\n if (process.platform === \"win32\") {\n return pathToFileURL(filePath).href;\n }\n return filePath;\n}\n\nexport async function scanLocalDir(dir: string): Promise<DiscoveredModule[]> {\n const results: DiscoveredModule[] = [];\n if (!(await pathExists(dir))) return results;\n\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n const entryPath = path.join(dir, entry.name);\n try {\n const stat = await fs.stat(entryPath);\n if (!stat.isDirectory()) continue;\n } catch {\n continue;\n }\n results.push({ name: entry.name, path: await resolveRealpath(entryPath) });\n }\n return results;\n}\n\nexport async function scanNodeModules(prefix: string): Promise<DiscoveredModule[]> {\n const results: DiscoveredModule[] = [];\n const nodeModulesPath = path.resolve(process.cwd(), \"node_modules\");\n if (!(await pathExists(nodeModulesPath))) return results;\n\n let entries: import(\"fs\").Dirent[];\n try {\n entries = await fs.readdir(nodeModulesPath, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n if (!entry.name.startsWith(prefix)) continue;\n const name = entry.name.slice(prefix.length);\n const fullPath = path.join(nodeModulesPath, entry.name);\n results.push({ name, path: await resolveRealpath(fullPath) });\n }\n return results;\n}","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport type { MiokuContext } from \"../runtime/mioku-context\";\nimport type {\n MiokuRuntimeConfig,\n PackageJsonLike,\n ServiceMetadata,\n MiokuService,\n} from \"../types\";\nimport { rootLogger as logger } from \"../logger\";\nimport {\n scanLocalDir,\n scanNodeModules,\n pathExists,\n toImportPath,\n} from \"../internal/module-scanner\";\nimport { getOrCreate } from \"../internal/registry\";\nimport { servicesRegistry } from \"./registry\";\n\nconst SERVICE_PREFIX = \"mioku-service-\";\n\n/** 服务管理器:扫描、加载本地与 npm 服务,并把服务 API 暴露到注册表 */\nexport class ServiceManager {\n private serviceMetadata = new Map<string, ServiceMetadata>();\n private loaded = new Map<string, MiokuService>();\n\n static getInstance(): ServiceManager {\n return getOrCreate(\"service-manager\", () => new ServiceManager());\n }\n\n /** 扫描本地 services/ 目录与 node_modules 下的 mioku-service-* 包,返回全部服务元数据 */\n async discoverServices(miokuConfig: MiokuRuntimeConfig = {}): Promise<ServiceMetadata[]> {\n const servicesDir = miokuConfig.services_dir\n ? path.resolve(process.cwd(), miokuConfig.services_dir)\n : path.resolve(process.cwd(), \"services\");\n\n this.serviceMetadata.clear();\n\n if (existsSync(servicesDir)) {\n const local = await scanLocalDir(servicesDir);\n for (const { name, path: p } of local) {\n const metadata = await this.loadServiceMetadata(name, p);\n if (metadata) this.serviceMetadata.set(name, metadata);\n }\n } else {\n mkdirSync(servicesDir, { recursive: true });\n }\n\n const external = await scanNodeModules(SERVICE_PREFIX);\n for (const { name, path: p } of external) {\n const metadata = await this.loadServiceMetadata(name, p);\n if (metadata) this.serviceMetadata.set(name, metadata);\n }\n\n logger.info(`o.O 发现了 ${this.serviceMetadata.size} 个服务`);\n return [...this.serviceMetadata.values()];\n }\n\n private async loadServiceMetadata(\n name: string,\n servicePath: string,\n ): Promise<ServiceMetadata | null> {\n const packageJsonPath = path.join(servicePath, \"package.json\");\n if (!(await pathExists(packageJsonPath))) return null;\n\n try {\n const packageJson: PackageJsonLike = JSON.parse(\n await fs.readFile(packageJsonPath, \"utf-8\"),\n );\n return {\n name,\n version: packageJson.version ?? \"0.0.0\",\n description: packageJson.description,\n path: servicePath,\n packageJson,\n };\n } catch (error) {\n logger.warn(`[service-manager] 解析服务 ${name} 失败: ${error}`);\n return null;\n }\n }\n\n getMetadata(name: string): ServiceMetadata | undefined {\n return this.serviceMetadata.get(name);\n }\n\n getAllMetadata(): ServiceMetadata[] {\n return [...this.serviceMetadata.values()];\n }\n\n /** 依次加载所有已发现的服务,成功的会注册进服务注册表 */\n async loadAllServices(ctx?: MiokuContext): Promise<void> {\n const all = [...this.serviceMetadata.values()];\n logger.info(`O.o 准备加载 ${all.length} 个服务...`);\n let loadedCount = 0;\n for (const metadata of all) {\n if (await this.loadService(metadata, ctx)) loadedCount++;\n }\n logger.info(`O.o 服务加载完成: ${loadedCount}/${all.length} 个就绪`);\n }\n\n private async loadService(metadata: ServiceMetadata, ctx?: MiokuContext): Promise<boolean> {\n try {\n const tsEntry = path.join(metadata.path, \"index.ts\");\n const jsEntry = path.join(metadata.path, \"index.js\");\n const entry = (await pathExists(tsEntry))\n ? tsEntry\n : (await pathExists(jsEntry))\n ? jsEntry\n : null;\n if (!entry) {\n logger.error(`[service-manager] 服务 ${metadata.name} 入口丢失`);\n return false;\n }\n\n const serviceModule = await import(toImportPath(entry));\n const service: MiokuService = serviceModule.default ?? serviceModule;\n if (!service || typeof service.init !== \"function\") {\n logger.warn(`[service-manager] 服务 ${metadata.name} 无效:缺少 init()`);\n return false;\n }\n\n await service.init();\n servicesRegistry[metadata.name] = service.api;\n this.loaded.set(metadata.name, service);\n return true;\n } catch (error) {\n logger.error(`[service-manager] 加载服务 ${metadata.name} 失败: ${error}`);\n return false;\n }\n }\n\n /** 按加载的相反顺序卸载全部服务,并从注册表移除 */\n async disposeAll(): Promise<void> {\n const entries = Array.from(this.loaded.entries()).reverse();\n this.loaded.clear();\n for (const [name, service] of entries) {\n try {\n await service.dispose?.();\n } catch (error) {\n logger.warn(`[service-manager] 服务 ${name} 卸载失败: ${error}`);\n }\n delete servicesRegistry[name];\n }\n }\n\n async reset(): Promise<void> {\n await this.disposeAll();\n this.serviceMetadata.clear();\n }\n}\n\nexport default ServiceManager.getInstance();","import * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport { rootLogger as logger } from \"../logger\";\n\nconst SERVICE_CONFIG_ROOT = \"service\";\n\n/** 服务配置目录:`config/service/<serviceName>/` */\nfunction resolveConfigDir(serviceName: string): string {\n return path.join(process.cwd(), \"config\", SERVICE_CONFIG_ROOT, serviceName);\n}\n\nfunction resolveConfigPath(serviceName: string, configName: string): string {\n return path.join(resolveConfigDir(serviceName), `${configName}.json`);\n}\n\nfunction ensureDir(serviceName: string): void {\n const dir = resolveConfigDir(serviceName);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\n/** 注册服务配置:文件不存在时把 defaults 写入磁盘 */\nexport async function registerServiceConfig(\n serviceName: string,\n configName: string,\n defaults: Record<string, unknown>,\n): Promise<void> {\n ensureDir(serviceName);\n const configPath = resolveConfigPath(serviceName, configName);\n if (!existsSync(configPath)) {\n await fs.writeFile(configPath, JSON.stringify(defaults, null, 2), \"utf-8\");\n }\n}\n\n/** 读取服务配置,文件不存在或解析失败时返回空对象 */\nexport async function getServiceConfig(\n serviceName: string,\n configName: string,\n): Promise<Record<string, unknown>> {\n const configPath = resolveConfigPath(serviceName, configName);\n try {\n return JSON.parse(await fs.readFile(configPath, \"utf-8\"));\n } catch (error) {\n if (!existsSync(configPath)) return {};\n logger.warn(`[service-config] 读取 ${serviceName}/${configName} 失败: ${error}`);\n return {};\n }\n}\n\n/** 覆盖写入服务配置 */\nexport async function updateServiceConfig(\n serviceName: string,\n configName: string,\n value: Record<string, unknown>,\n): Promise<void> {\n ensureDir(serviceName);\n await fs.writeFile(\n resolveConfigPath(serviceName, configName),\n JSON.stringify(value, null, 2),\n \"utf-8\",\n );\n}\n\n/** 读取服务的全部配置文件,按配置名索引 */\nexport async function getServiceConfigs(\n serviceName: string,\n): Promise<Record<string, Record<string, unknown>>> {\n const dir = resolveConfigDir(serviceName);\n if (!existsSync(dir)) return {};\n\n const result: Record<string, Record<string, unknown>> = {};\n const files = (await fs.readdir(dir)).filter((name) => name.endsWith(\".json\"));\n for (const file of files) {\n try {\n result[path.basename(file, \".json\")] = JSON.parse(\n await fs.readFile(path.join(dir, file), \"utf-8\"),\n );\n } catch (error) {\n logger.warn(`[service-config] 读取 ${serviceName}/${file} 失败: ${error}`);\n }\n }\n return result;\n}\n\n/** 删除服务配置,文件不存在时返回 false */\nexport async function deleteServiceConfig(\n serviceName: string,\n configName: string,\n): Promise<boolean> {\n const configPath = resolveConfigPath(serviceName, configName);\n if (!existsSync(configPath)) return false;\n await fs.unlink(configPath);\n return true;\n}\n","import type { MiokuContext } from \"../runtime/mioku-context\";\n\n/** 服务引用的类型安全句柄,泛型参数对应该服务的实际类型 */\nexport interface ServiceRef<T> {\n readonly id: string;\n}\n\n/** 声明一个服务引用,只记录 id,不查询注册表 */\nexport function defineService<T>(id: string): ServiceRef<T> {\n return { id };\n}\n\n/** 从上下文取服务,未注册时返回 undefined */\nexport function getService<T>(\n ctx: MiokuContext,\n ref: ServiceRef<T>,\n): T | undefined {\n return ctx.services[ref.id] as T | undefined;\n}\n\n/** 从上下文取服务,未注册时抛错 */\nexport function requireService<T>(\n ctx: MiokuContext,\n ref: ServiceRef<T>,\n): T {\n const svc = ctx.services[ref.id] as T | undefined;\n if (svc === undefined) {\n throw new Error(\n `[mioku] required service \"${ref.id}\" is not available`,\n );\n }\n return svc;\n}\n\n/** 判断服务是否已注册 */\nexport function hasService<T>(\n ctx: MiokuContext,\n ref: ServiceRef<T>,\n): boolean {\n return ctx.services[ref.id] !== undefined;\n}","import type {\n AIService,\n ConfigService,\n ScreenshotService,\n HelpService,\n} from \"../types\";\nimport { defineService } from \"./define\";\n\n/** 框架内置服务的引用集合 */\nexport const Services = {\n AI: defineService<AIService>(\"ai\"),\n Config: defineService<ConfigService>(\"config\"),\n Screenshot: defineService<ScreenshotService>(\"screenshot\"),\n Help: defineService<HelpService>(\"help\"),\n} as const;\n\n/** 全部内置服务引用的联合类型 */\nexport type BuiltinServiceRef =\n | typeof Services.AI\n | typeof Services.Config\n | typeof Services.Screenshot\n | typeof Services.Help;","import { isAdmin as isConfiguredAdmin, isOwner as isConfiguredOwner } from '../config'\nimport nodeCron from 'node-cron'\nimport {\n createCmd as createCmdUtil,\n createDB as createDBUtil,\n createStore as createStoreUtil,\n match as matchMessage,\n text as extractText,\n type CreateCmdOptions,\n type HasMessage,\n} from '../utils'\nimport * as utilsExports from '../utils'\nimport { segment } from '../adapter'\nimport {\n noticeAdmins as noticeAdminsAction,\n noticeFriends as noticeFriendsAction,\n noticeGroups as noticeGroupsAction,\n noticeOwners as noticeOwnersAction,\n} from '../actions'\nimport { addService as registerService, servicesRegistry } from '../services'\n\nimport type { Adapter, AdapterBotMap } from '../adapter'\nimport type { Bot } from '../adapter'\nimport type { Driver } from '../driver'\nimport type { Event, MessageEvent, MetaEvent, NoticeEvent, RequestEvent } from '../adapter'\nimport type { BotLifecycleEvent } from '../adapter'\nimport type { Logger } from '../logger'\nimport type { MiokuConfig } from '../config'\nimport type { EventBus } from './bus'\nimport type { CronHandler, PluginCleanup, ScheduledTask } from '../plugin'\nimport type { TaskContext } from 'node-cron'\nimport type { CapabilityRegistry } from '../adapter'\nimport type { BotRegistry } from './bots'\nimport type { Message, MessageInput } from '../adapter'\n\n/** 插件管理器:插件列表查询与运行时启停 */\nexport interface PluginManager {\n list(): Array<{ name: string; type: 'builtin' | 'external'; version?: string }>\n localPlugins(): string[]\n enable(name: string): Promise<void>\n disable(name: string): Promise<void>\n reload(name: string): Promise<void>\n}\n\nexport interface ContextOptions {\n readonly pluginName: string\n readonly bus: EventBus\n readonly bots: BotRegistry\n readonly driver: Driver\n readonly capabilities: CapabilityRegistry\n readonly config: MiokuConfig\n readonly logger: Logger\n readonly priority: number\n readonly getAdapter: <T extends Adapter = Adapter>(name: string) => T | undefined\n readonly listAdapters: () => readonly Adapter[]\n readonly onUpdateConfig: (updater: (config: MiokuConfig) => void | Promise<void>) => Promise<void>\n readonly pluginManager: PluginManager\n}\n\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\n/** 从事件对象中提取发送者 id(支持裸 id / user_id / sender.user_id) */\nexport const toUserId = (value: unknown): string | undefined => {\n if (typeof value === 'number' || typeof value === 'string' || typeof value === 'bigint') {\n return String(value)\n }\n if (isObject(value)) {\n if ('user_id' in value) return toUserId((value as { user_id: unknown }).user_id)\n if ('sender' in value) {\n const sender = (value as { sender: unknown }).sender\n if (isObject(sender) && 'user_id' in sender) return toUserId((sender as { user_id: unknown }).user_id)\n }\n }\n return undefined\n}\n\nexport const isEventOwner = (event: unknown): boolean => {\n const id = toUserId(event)\n if (!id) return false\n return isConfiguredOwner(id)\n}\n\nexport const isEventAdmin = (event: unknown): boolean => {\n const id = toUserId(event)\n if (!id) return false\n return isConfiguredAdmin(id)\n}\n\nexport const isEventOwnerOrAdmin = (event: unknown): boolean => isEventOwner(event) || isEventAdmin(event)\nexport const hasEventRight = (event: unknown): boolean => isEventOwnerOrAdmin(event)\n\ntype SemanticRoute<R extends string> = R extends `${string}:${infer Rest}` ? Rest : R\n\ntype EventKindOfSemanticRoute<R extends string> = R extends `message${string}`\n ? MessageEvent\n : R extends `notice${string}`\n ? NoticeEvent\n : R extends `request${string}`\n ? RequestEvent\n : R extends `meta_event${string}`\n ? MetaEvent\n : Event\n\nexport type EventKindOfRoute<R extends string> = EventKindOfSemanticRoute<SemanticRoute<R>>\n\ntype AdapterBotOf<Name extends string> = Name extends keyof AdapterBotMap\n ? AdapterBotMap[Name] extends Bot\n ? AdapterBotMap[Name]\n : Bot\n : Bot\n\ntype BotOfRoute<R extends string> = R extends `${infer Adapter}:${string}` ? AdapterBotOf<Adapter> : Bot\n\ntype BindRouteBot<E, B extends Bot> = E extends { bot: Bot; self_id: string }\n ? Omit<E, 'bot' | 'self_id'> & { bot: B; self_id: B['bot_id'] }\n : E\n\ntype RouteEventOf<R extends string> = BindRouteBot<EventKindOfRoute<R>, BotOfRoute<R>>\n\nexport type RouteEvent<R extends string | readonly string[]> = R extends readonly string[]\n ? RouteEventOf<R[number]>\n : RouteEventOf<Extract<R, string>>\n\nconst CTX_UTILS = {\n localeDate: utilsExports.localeDate,\n localeTime: utilsExports.localeTime,\n randomInt: utilsExports.randomInt,\n randomItem: utilsExports.randomItem,\n randomItems: utilsExports.randomItems,\n randomId: utilsExports.randomId,\n uuid: utilsExports.uuid,\n wait: utilsExports.wait,\n toArray: utilsExports.toArray,\n unique: utilsExports.unique,\n clamp: utilsExports.clamp,\n noNullish: utilsExports.noNullish,\n isDefined: utilsExports.isDefined,\n isFunction: utilsExports.isFunction,\n isNumber: utilsExports.isNumber,\n isBoolean: utilsExports.isBoolean,\n isString: utilsExports.isString,\n isObject: utilsExports.isObject,\n localNum: utilsExports.localNum,\n formatDuration: utilsExports.formatDuration,\n md5: utilsExports.md5,\n base64Encode: utilsExports.base64Encode,\n base64Decode: utilsExports.base64Decode,\n qs: utilsExports.qs,\n stringifyError: utilsExports.stringifyError,\n getTerminalInput: utilsExports.getTerminalInput,\n find: utilsExports.find,\n filter: utilsExports.filter,\n prettyMs: utilsExports.prettyMs,\n filesize: utilsExports.filesize,\n dayjs: utilsExports.dayjs,\n path: utilsExports.path,\n fs: utilsExports.fs,\n colors: utilsExports.colors,\n} as const\n\ntype CtxUtils = typeof CTX_UTILS\n\n/**\n * 插件上下文:插件 `setup(ctx)` 收到的对象。\n * 事件监听、定时任务、配置、日志、Bot 操作与工具函数都挂在上面,\n * 同时混入了 `utils` 中的常用工具(dayjs、fs、path、randomInt 等)。\n */\nexport class MiokuContext {\n readonly #options: ContextOptions\n readonly #cleanup: Set<PluginCleanup> = new Set()\n\n constructor(options: ContextOptions) {\n this.#options = options\n Object.assign(this, CTX_UTILS)\n }\n\n #addCleanup(fn: PluginCleanup): void {\n this.#cleanup.add(fn)\n }\n\n get pluginName(): string {\n return this.#options.pluginName\n }\n\n /** 第一个已连接的 bot(多数单 bot 场景直接用这个) */\n get bot(): Bot | undefined {\n return this.#options.bots.all()[0]\n }\n\n /** 所有已连接的 bot */\n get bots(): readonly Bot[] {\n return this.#options.bots.all()\n }\n\n get self_id(): string | undefined {\n return this.bot?.bot_id\n }\n\n /** 按 bot_id 取指定 bot */\n pickBot<T extends Bot = Bot>(bot_id: string | number): T | undefined {\n return this.#options.bots.pick<T>(bot_id)\n }\n\n /**\n * 获取事件引用回复的消息内容。\n * 返回 null 表示没有引用、拿不到对应 bot 或消息已失效。\n */\n async getQuoteMsg(\n event: { quote_id?: string | null; bot?: Bot; self_id?: string },\n ): Promise<import('../capabilities/message').MessageGetResult | null> {\n const quoteId = event?.quote_id\n if (quoteId == null || quoteId === '') return null\n const bot = event.bot ?? (event.self_id != null ? this.pickBot(event.self_id) : undefined)\n if (!bot) return null\n try {\n return (await bot.getMessage(quoteId)) ?? null\n } catch {\n return null\n }\n }\n\n /** 按名称取适配器实例 */\n getAdapter<T extends Adapter = Adapter>(name: string): T | undefined {\n return this.#options.getAdapter<T>(name)\n }\n\n /** 所有已加载的适配器实例(含当前没有 bot 连接的) */\n get adapters(): readonly Adapter[] {\n return this.#options.listAdapters()\n }\n\n /**\n * 注册事件监听。route 支持层级路由,如 `message`、`message.group`、\n * `onebotv11:message`;返回取消监听函数。\n */\n handle<R extends string | readonly string[]>(\n route: R,\n handler: (event: RouteEvent<R>) => void | Promise<void>,\n ): () => void {\n const routes = Array.isArray(route) ? route : [route]\n const source = `plugin:${this.#options.pluginName}`\n const handledEvents = new WeakSet<Event>()\n const wrappedHandler = async (event: Event): Promise<void> => {\n if (handledEvents.has(event)) return\n handledEvents.add(event)\n await handler(event as RouteEvent<R>)\n }\n const disposers = routes.map((r) =>\n this.#options.bus.register(r, wrappedHandler, { source, priority: this.#options.priority }),\n )\n let disposed = false\n const dispose = (): void => {\n if (disposed) return\n disposed = true\n for (const dispose of disposers) dispose()\n }\n this.#addCleanup(dispose)\n return dispose\n }\n\n /** 注册 cron 定时任务,插件卸载时自动停止 */\n cron(expression: string, handler: CronHandler): ScheduledTask {\n const task = nodeCron.schedule(expression, async (taskContext: TaskContext) => {\n try {\n await handler(this, taskContext)\n } catch (err) {\n this.#options.logger.error(`Plugin \"${this.#options.pluginName}\" cron task failed`, err)\n }\n })\n let disposed = false\n const dispose = async (): Promise<void> => {\n if (disposed) return\n disposed = true\n await task.stop()\n await task.destroy()\n }\n this.#addCleanup(dispose)\n return task\n }\n\n /** 监听 bot 连接 / 断开 */\n onBot<K extends 'connected' | 'disconnected'>(\n type: K,\n handler: (event: K extends 'connected' ? { bot: Bot } : BotLifecycleEvent) => void | Promise<void>,\n ): () => void {\n const route = type === 'connected' ? 'bot:connected' : 'bot:disconnected'\n return this.handle(route, handler as (event: Event) => void | Promise<void>)\n }\n\n getDriver(): Driver {\n return this.#options.driver\n }\n\n /** 当前框架配置(只读) */\n get config(): Readonly<MiokuConfig> {\n return this.#options.config\n }\n\n /** 修改框架配置(owners、admins、plugins 等) */\n updateConfig(updater: (config: MiokuConfig) => void | Promise<void>): Promise<void> {\n return this.#options.onUpdateConfig(updater)\n }\n\n get logger(): Logger {\n return this.#options.logger\n }\n\n get plugins(): PluginManager {\n return this.#options.pluginManager\n }\n\n get services(): import('../services').MiokuServices {\n return servicesRegistry as import('../services').MiokuServices\n }\n\n /** 注册一个运行时服务供其他插件取用,返回注销函数 */\n addService<T = unknown>(name: string, value: T, cover?: boolean): () => void {\n const remove = registerService<T>(name, value, cover)\n this.#addCleanup(remove)\n return remove\n }\n\n get capabilities(): CapabilityRegistry {\n return this.#options.capabilities\n }\n\n get buses(): EventBus {\n return this.#options.bus\n }\n\n get segment(): typeof segment {\n return segment\n }\n\n /** 按模式匹配消息文本(支持正则/字符串/关键词数组) */\n match<T extends HasMessage>(\n event: T,\n pattern: Parameters<typeof matchMessage>[1],\n quote?: boolean,\n ): ReturnType<typeof matchMessage> {\n return matchMessage(event, pattern, quote)\n }\n\n /** 解析命令行字符串为 命令 + 参数 + 选项 */\n createCmd(cmdStr: string, options: CreateCmdOptions = {}): ReturnType<typeof createCmdUtil> {\n return createCmdUtil(cmdStr, options)\n }\n\n /** 在插件目录下创建一个 JSON 数据存储 */\n createStore<T extends object = object>(\n defaultData: T,\n options: { __dirname?: string; importMeta?: ImportMeta; compress?: boolean; filename?: string } = {},\n ): ReturnType<typeof createStoreUtil<T>> {\n return createStoreUtil<T>(defaultData, options)\n }\n\n /** 在指定路径创建一个 lowdb 数据库文件 */\n createDB<T extends object = object>(\n filename: string,\n options: { defaultData?: T; compress?: boolean } = {},\n ): ReturnType<typeof createDBUtil<T>> {\n return createDBUtil<T>(filename, options)\n }\n\n /** 提取事件消息的纯文本 */\n text(source: HasMessage | Message, options?: { trim?: boolean | 'whole' | 'each' }): string {\n return extractText(source, options)\n }\n\n /** 向多个群发送消息 */\n noticeGroups(groupIds: readonly string[], message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeGroupsAction(this.#options.bots.all(), groupIds, message, options)\n }\n\n /** 向多个好友发送消息 */\n noticeFriends(userIds: readonly string[], message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeFriendsAction(this.#options.bots.all(), userIds, message, options)\n }\n\n /** 向所有主人发送消息 */\n noticeOwners(message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeOwnersAction(this.#options.bots.all(), this.#options.config.owners, message, options)\n }\n\n /** 向所有管理员发送消息 */\n noticeAdmins(message: MessageInput, options?: import('../actions').NoticeOptions): Promise<void> {\n return noticeAdminsAction(this.#options.bots.all(), this.#options.config.admins, message, options)\n }\n\n isGroupMsg(event: unknown): boolean {\n return isObject(event) && (event as { kind?: unknown }).kind === 'message' &&\n (event as { message_type?: unknown }).message_type === 'group'\n }\n\n isPrivateMsg(event: unknown): boolean {\n return isObject(event) && (event as { kind?: unknown }).kind === 'message' &&\n (event as { message_type?: unknown }).message_type === 'private'\n }\n\n /** 事件发送者是否为主人 */\n isOwner(event: unknown): boolean {\n return isEventOwner(event)\n }\n\n /** 事件发送者是否为管理员 */\n isAdmin(event: unknown): boolean {\n return isEventAdmin(event)\n }\n\n isOwnerOrAdmin(event: unknown): boolean {\n return isEventOwnerOrAdmin(event)\n }\n\n hasRight(event: unknown): boolean {\n return hasEventRight(event)\n }\n\n async dispose(): Promise<void> {\n const all = Array.from(this.#cleanup)\n this.#cleanup.clear()\n for (const fn of all) {\n try {\n await fn()\n } catch {\n // swallow individual cleanup errors so other plugins can still clean up\n }\n }\n }\n}\n\nexport interface MiokuContext extends CtxUtils {}\n","import { getOrCreate } from '../internal/registry'\n\nimport type { PluginMetadata } from '../types'\n\nconst store = getOrCreate<Map<string, PluginMetadata>>('plugin-metadata', () => new Map())\n\nexport const setPluginMetadata = (meta: PluginMetadata): void => {\n store.set(meta.name, meta)\n}\n\nexport const removePluginMetadata = (name: string): void => {\n store.delete(name)\n}\n\nexport const getPluginMetadata = (name: string): PluginMetadata | undefined => store.get(name)\n\nexport const getPluginMetadataList = (): PluginMetadata[] => [...store.values()]\n\nexport const resetPluginMetadata = (): void => {\n store.clear()\n}","import { getOrCreate } from \"../internal/registry\";\n\nconst store = getOrCreate<Record<string, unknown>>(\n \"plugin-runtime-state\",\n () => ({}),\n);\n\n/** 插件运行时状态引用:跨重载安全的读写句柄 */\nexport interface PluginStateRef<T> {\n readonly name: string;\n get(): T;\n set(next: T): void;\n reset(): void;\n}\n\n/** 定义一个具名状态引用,插件重载后仍能读回旧值 */\nexport function defineState<T>(name: string, initial: T): PluginStateRef<T> {\n return {\n name,\n get(): T {\n const current = store[name];\n return (current === undefined ? initial : current) as T;\n },\n set(next: T): void {\n store[name] = next;\n },\n reset(): void {\n delete store[name];\n },\n };\n}\n\nexport function hasPluginState(name: string): boolean {\n return store[name] !== undefined;\n}\n\n/** 取插件的运行时状态对象,不存在时自动创建空对象 */\nexport function getPluginRuntimeState<T = Record<string, any>>(\n name: string,\n): T {\n if (!store[name]) store[name] = {};\n return store[name] as T;\n}\n\n/** 合并写入插件运行时状态 */\nexport function setPluginRuntimeState<T>(name: string, state: T): void {\n store[name] = state;\n}\n\nexport function resetPluginRuntimeState(name: string): void {\n delete store[name];\n}\n\nexport function getAllPluginRuntimeStates(): Record<string, unknown> {\n return { ...store };\n}","import os from 'node:os'\nimport cp from 'node:child_process'\nimport { version } from '../../../package.json' with { type: 'json' }\n\nimport { filesize, localNum, prettyMs, displayAdapterId } from '../../utils'\n\nimport type { Bot } from '../../adapter'\nimport type { AdapterReport, AdapterStatusStats } from './adapters'\n\nexport const SystemMap: Record<string, string> = {\n Linux: 'Linux',\n Darwin: 'macOS',\n Windows_NT: 'Win',\n}\n\nexport const ArchMap: Record<string, string> = {\n ia32: 'x86',\n arm: 'arm',\n arm64: 'arm64',\n x64: 'x64',\n}\n\nexport interface BotStatus {\n bot_id: string\n nickname: string\n online: boolean\n adapter: string\n friends?: number\n groups?: number\n send?: number\n receive?: number\n}\n\nexport interface MiokuStatus {\n bots: readonly BotStatus[]\n plugins: {\n enabled: number\n total: number\n }\n stats: {\n uptime: number\n }\n versions: {\n node: string\n mioku: string\n }\n system: {\n name: string\n version: string\n arch: string\n }\n memory: {\n used: number\n total: number\n percent: number\n rss: {\n used: number\n percent: number\n }\n }\n disk: {\n total: number\n used: number\n free: number\n percent: number\n }\n cpu: {\n name: string\n count: number\n percent: number\n }\n}\n\nexport interface MiokuCoreServiceContrib {\n getMiokuStatus(): Promise<MiokuStatus>\n formatMiokuStatus(status: MiokuStatus): Promise<string>\n getAdapterReport(): Promise<AdapterReport>\n}\n\nconst getSystemInfo = (): { name: string; version: string; arch: string } => {\n const osType = os.type()\n const arch = ArchMap[os.type()] ?? os.arch()\n return { name: SystemMap[osType] ?? osType, version: '-', arch }\n}\n\nconst getCpuTimes = (): { idle: number; total: number } => {\n const cpus = os.cpus()\n let idle = 0\n let total = 0\n for (const cpu of cpus) {\n for (const type in cpu.times) total += (cpu.times as Record<string, number>)[type] ?? 0\n idle += cpu.times.idle ?? 0\n }\n return { idle, total }\n}\n\nconst measureCpuUsage = async (interval = 600): Promise<number> => {\n const start = getCpuTimes()\n await new Promise((resolve) => setTimeout(resolve, interval))\n const end = getCpuTimes()\n const idleDiff = end.idle - start.idle\n const totalDiff = end.total - start.total\n if (totalDiff <= 0) return 0\n const usage = 1 - idleDiff / totalDiff\n return usage * 100\n}\n\nconst getDiskUsage = (): Promise<{ total: number; used: number; free: number; percent: number }> =>\n new Promise((resolve) => {\n if (!['Linux', 'Darwin'].includes(os.type())) {\n resolve({ total: 0, used: 0, free: 0, percent: 0 })\n return\n }\n cp.exec(`df -k / | tail -1 | awk '{print $2,$4}'`, (err, stdout) => {\n if (err) {\n resolve({ total: 0, used: 0, free: 0, percent: 0 })\n return\n }\n const [totalStr, freeStr] = stdout.trim().split(' ')\n const total = Number(totalStr) * 1024\n const free = Number(freeStr) * 1024\n const used = total - free\n resolve({ total, free, used, percent: total > 0 ? Number(((used / total) * 100).toFixed(1)) : 0 })\n })\n })\n\nexport interface BuildStatusOptions {\n readonly bots: readonly Bot[]\n /** 各 bot 的计数,由 core 从适配器上报里取好后传入,键为 `adapter:bot_id` */\n readonly botStats?: ReadonlyMap<string, AdapterStatusStats>\n readonly enabledPlugins: number\n readonly totalPlugins: number\n readonly systemInfoProvider?: () => Promise<{ distro: string; release: string }>\n}\n\nexport const buildMiokuStatus = async (options: BuildStatusOptions): Promise<MiokuStatus> => {\n const sysInfo = options.systemInfoProvider ? await options.systemInfoProvider() : null\n const defaultSystem = getSystemInfo()\n const system = sysInfo ? { name: sysInfo.distro, version: sysInfo.release, arch: defaultSystem.arch } : defaultSystem\n const cpu = (() => {\n const cpus = os.cpus()\n return { name: cpus[0]?.model ?? '[未知CPU]', count: cpus.length }\n })()\n const totalMem = os.totalmem()\n const usedMem = totalMem - os.freemem()\n const rssMem = process.memoryUsage.rss()\n const [disk, cpuPercent] = await Promise.all([getDiskUsage(), measureCpuUsage()])\n return {\n bots: options.bots.map((bot) => {\n const stats = options.botStats?.get(`${bot.adapter}:${bot.bot_id}`)\n return {\n bot_id: bot.bot_id,\n nickname: bot.nickname ?? '',\n online: bot.online,\n adapter: bot.adapter,\n friends: stats?.friends,\n groups: stats?.groups,\n send: stats?.sent,\n receive: stats?.received,\n }\n }),\n plugins: { enabled: options.enabledPlugins, total: options.totalPlugins },\n stats: { uptime: process.uptime() * 1000 },\n versions: { node: process.versions.node, mioku: version },\n system,\n memory: {\n used: usedMem,\n total: totalMem,\n percent: totalMem > 0 ? Number(((usedMem / totalMem) * 100).toFixed(1)) : 0,\n rss: {\n used: rssMem,\n percent: totalMem > 0 ? Number(((rssMem / totalMem) * 100).toFixed(1)) : 0,\n },\n },\n disk,\n cpu: { name: cpu.name.trim(), count: cpu.count, percent: Number(cpuPercent.toFixed(1)) },\n }\n}\n\nexport const formatMiokuStatus = async (status: MiokuStatus): Promise<string> => {\n const { bots, plugins, system, disk, cpu, memory, versions } = status\n\n const diskValid = disk.total > 0 && disk.free >= 0\n const diskDesc = diskValid\n ? `${disk.percent}%-${filesize(disk.used, { round: 1 })}/${filesize(disk.total, { round: 1 })}`\n : ''\n\n const botLines = bots\n .map((bot) => {\n const hasStats = bot.friends != null || bot.groups != null || bot.send != null || bot.receive != null\n const statsLine = hasStats\n ? `\\n📋 ${localNum(bot.friends ?? 0)} 好友 / ${localNum(bot.groups ?? 0)} 群 / 📮 收 ${localNum(bot.receive ?? 0)} 发 ${localNum(bot.send ?? 0)}`\n : ''\n return `👤 ${bot.nickname || '(未命名)'} (${displayAdapterId(bot.bot_id)})${statsLine}`\n })\n .join('\\n')\n\n const totalSend = bots.reduce((sum, bot) => sum + (bot.send ?? 0), 0)\n const totalReceive = bots.reduce((sum, bot) => sum + (bot.receive ?? 0), 0)\n const statsLine = bots.length > 1 ? `\\n📮 总计: 收 ${localNum(totalReceive)} 条,发 ${localNum(totalSend)} 条` : ''\n\n return `\n〓 🟢 mioku 状态 〓\n${botLines || '(无在线 Bot)'}\n🧩 启用了 ${localNum(plugins.enabled)} 个插件,共 ${localNum(plugins.total)} 个${statsLine}\n🚀 ${filesize(memory.rss.used, { round: 1 })}/${memory.percent}%\n⏳ 已运行 ${prettyMs(status.stats.uptime, { hideYear: true, secondsDecimalDigits: 0 })}\n🤖 mioku/${versions.mioku}-node/${versions.node.split('.')[0]}\n🖥️ ${system.name.split(' ')[0]}/${system.version.split('.')[0]}-${system.name}-node/${versions.node.split('.')[0]}\n📊 ${memory.percent}%-${filesize(memory.used, { base: 2, round: 1 })}/${filesize(memory.total, { base: 2, round: 1 })}\n🧮 ${cpu.percent}%-${cpu.name}-${cpu.count}核\n${diskValid ? `💾 ${diskDesc}` : ''}\n `.trim()\n}\n","import { getOrCreate } from \"../../internal/registry\";\nimport { localNum, prettyMs, displayAdapterId } from \"../../utils\";\n\nimport type { Bot } from \"../../adapter\";\nimport type { AdapterStatus, AdapterStatusStats } from \"../../runtime/types\";\n\nexport type { AdapterStatus, AdapterStatusStats } from \"../../runtime/types\";\n\nexport interface StatusProviderContext {\n readonly bot: Bot;\n}\n\nexport type StatusProvider = (\n context: StatusProviderContext,\n) => Promise<AdapterStatus> | AdapterStatus;\n\n/** 注册目标*/\nexport type StatusProviderTarget =\n | string\n | { readonly adapter: string; readonly bot_id?: string };\n\nconst statusProviders = getOrCreate<Map<string, StatusProvider>>(\n \"status-providers\",\n () => new Map(),\n);\n\nconst providerKey = (adapter: string, bot_id?: string): string =>\n bot_id == null || bot_id === \"\" ? adapter : `${adapter}:${bot_id}`;\n\n/**\n * 注册适配器状态上报\n */\nexport const registerStatusProvider = (\n target: StatusProviderTarget,\n provider: StatusProvider,\n): (() => void) => {\n const { adapter, bot_id } =\n typeof target === \"string\"\n ? { adapter: target, bot_id: undefined }\n : target;\n const key = providerKey(adapter, bot_id);\n statusProviders.set(key, provider);\n return () => {\n if (statusProviders.get(key) === provider) statusProviders.delete(key);\n };\n};\n\nconst resolveProvider = (bot: Bot): StatusProvider | undefined =>\n statusProviders.get(providerKey(bot.adapter, bot.bot_id)) ??\n statusProviders.get(providerKey(bot.adapter));\n\n/** 单个已连接实例 */\nexport interface AdapterInstanceStatus {\n readonly bot_id: string;\n readonly nickname: string;\n readonly online: boolean;\n readonly connected_at?: number;\n readonly impl?: string;\n readonly version?: string;\n readonly protocol?: string;\n readonly platform?: string;\n readonly platformVersion?: string;\n readonly stats: AdapterStatusStats;\n readonly data: Readonly<Record<string, unknown>>;\n}\n\n/** 单个适配器及其实例 */\nexport interface AdapterReportEntry {\n readonly name: string;\n /** 适配器包版本 */\n readonly version?: string;\n /** 底层实现库,如 icqq 的 ICQQ 1.11.4 */\n readonly impl?: { readonly name: string; readonly version?: string };\n readonly loaded: boolean;\n readonly instances: readonly AdapterInstanceStatus[];\n}\n\nexport interface AdapterReport {\n readonly adapters: readonly AdapterReportEntry[];\n readonly totalInstances: number;\n}\n\nexport interface BuildAdapterReportOptions {\n readonly bots: readonly Bot[];\n readonly adapters: readonly {\n readonly name: string;\n readonly version?: string;\n readonly impl?: { readonly name: string; readonly version?: string };\n }[];\n}\n\nconst num = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n\n/** v1.0 的适配器把计数塞在 data 里 */\nconst legacyStats = (data: Record<string, unknown>): AdapterStatusStats => ({\n friends: num(data.friends),\n groups: num(data.groups),\n sent: num(data.send),\n received: num(data.receive),\n});\n\nconst normalizeStats = (\n stats: AdapterStatusStats | undefined,\n data: Record<string, unknown>,\n): AdapterStatusStats => {\n const fallback = legacyStats(data);\n return {\n friends: num(stats?.friends) ?? fallback.friends,\n groups: num(stats?.groups) ?? fallback.groups,\n sent: num(stats?.sent) ?? fallback.sent,\n received: num(stats?.received) ?? fallback.received,\n };\n};\n\nconst toInstance = (\n bot: Bot,\n status: AdapterStatus | null,\n): AdapterInstanceStatus => {\n const data = (status?.data ?? {}) as Record<string, unknown>;\n return {\n bot_id: bot.bot_id,\n nickname: bot.nickname ?? \"\",\n online: bot.online,\n connected_at: bot.connected_at,\n impl: status?.impl,\n version: status?.version,\n protocol: status?.protocol,\n platform: status?.platform,\n platformVersion: status?.platform_version,\n stats: normalizeStats(status?.stats, data),\n data,\n };\n};\n\n/** 逐个 bot 查询状态 */\nexport const buildAdapterReport = async (\n options: BuildAdapterReportOptions,\n): Promise<AdapterReport> => {\n const names = options.adapters.map((adapter) => adapter.name);\n for (const bot of options.bots)\n if (!names.includes(bot.adapter)) names.push(bot.adapter);\n\n const instances = await Promise.all(\n options.bots.map(async (bot) => {\n const provider = resolveProvider(bot);\n if (!provider) return toInstance(bot, null);\n try {\n return toInstance(bot, await provider({ bot }));\n } catch {\n return toInstance(bot, null);\n }\n }),\n );\n\n const paired = options.bots.map((bot, index) => ({\n adapter: bot.adapter,\n instance: instances[index]!,\n }));\n const adapters = names.map((name) => {\n const known = options.adapters.find((adapter) => adapter.name === name);\n return {\n name,\n version: known?.version,\n impl: known?.impl,\n loaded: known != null,\n instances: paired\n .filter((entry) => entry.adapter === name)\n .map((entry) => entry.instance),\n };\n });\n\n return { adapters, totalInstances: instances.length };\n};\n\nexport const collectBotStats = (\n report: AdapterReport,\n): Map<string, AdapterStatusStats> => {\n const map = new Map<string, AdapterStatusStats>();\n for (const entry of report.adapters)\n for (const instance of entry.instances)\n map.set(`${entry.name}:${instance.bot_id}`, instance.stats);\n return map;\n};\n\nconst STAT_GROUPS: ReadonlyArray<\n readonly [\n icon: string,\n fields: ReadonlyArray<readonly [keyof AdapterStatusStats, string]>,\n ]\n> = [\n [\n \"📋\",\n [\n [\"friends\", \"好友\"],\n [\"groups\", \"群\"],\n ],\n ],\n [\n \"📮\",\n [\n [\"received\", \"收\"],\n [\"sent\", \"发\"],\n ],\n ],\n];\n\nconst formatStats = (stats: AdapterStatusStats): string => {\n const segments: string[] = [];\n for (const [icon, fields] of STAT_GROUPS) {\n const parts = fields\n .filter(([key]) => stats[key] != null)\n .map(([key, label]) => `${label} ${localNum(stats[key]!)}`);\n if (parts.length) segments.push(`${icon} ${parts.join(\" / \")}`);\n }\n return segments.join(\" · \");\n};\n\nconst formatInstance = (instance: AdapterInstanceStatus): string[] => {\n const tags = [\n [instance.impl, instance.version].filter(Boolean).join(\"/\"),\n instance.platform\n ? `${instance.platform}${instance.platformVersion ? ` v${instance.platformVersion}` : \"\"}`\n : \"\",\n instance.online ? \"\" : \"🔴 离线\",\n ].filter(Boolean);\n const lines = [\n `👤 ${instance.nickname || \"(未命名)\"} (${displayAdapterId(instance.bot_id)})${tags.length ? ` · ${tags.join(\" · \")}` : \"\"}`,\n ];\n const uptime =\n instance.online && instance.connected_at != null\n ? `⏳ 已连接 ${prettyMs(Date.now() - instance.connected_at, { hideYear: true, secondsDecimalDigits: 0 })}`\n : \"\";\n const detail = [formatStats(instance.stats), uptime]\n .filter(Boolean)\n .join(\" · \");\n if (detail) lines.push(detail);\n return lines;\n};\n\nconst summarize = (entry: AdapterReportEntry): string => {\n const total = entry.instances.length;\n if (total === 0) return entry.loaded ? \"🔴 未连接\" : \"⚪ 未加载\";\n const online = entry.instances.filter((instance) => instance.online).length;\n if (online === total) return `🟢 ${localNum(total)} 实例`;\n return `${online === 0 ? \"🔴\" : \"🟡\"} ${localNum(online)}/${localNum(total)} 实例在线`;\n};\n\n/** `名称@包版本[/实现库 v版本]`,名称走人类可读映射 */\nconst formatAdapterName = (entry: AdapterReportEntry): string => {\n const base = `${displayAdapterId(entry.name)}${entry.version ? `@${entry.version}` : \"\"}`;\n if (!entry.impl) return base;\n const impl = `${entry.impl.name}${entry.impl.version ? ` v${entry.impl.version}` : \"\"}`;\n return `${base}/${impl}`;\n};\n\nexport const formatAdapterReport = (report: AdapterReport): string => {\n if (!report.adapters.length)\n return \"〓 🔌 mioku 适配器 〓\\n(未加载任何适配器)\";\n\n const lines = report.adapters.flatMap((entry) => [\n `🔌 ${formatAdapterName(entry)} · ${summarize(entry)}`,\n ...entry.instances.flatMap(formatInstance),\n ]);\n\n return [\"〓 🔌 mioku 适配器 〓\", ...lines].join(\"\\n\");\n};\n","export interface MessageFilterRule {\n whitelist: number[];\n blacklist: number[];\n}\n\nexport interface MessageFilterConfig {\n user: MessageFilterRule;\n group: MessageFilterRule;\n}\n\nexport interface AutoUpdateConfig {\n enabled: boolean;\n time: string;\n frequency: \"daily\" | \"weekly\" | \"monthly\";\n}\n\nexport interface CorePluginConfig {\n likeCommand: {\n enabled: boolean;\n keyword: string;\n likeTimes: number;\n reactionEmojiId: number;\n };\n friend: {\n autoApprove: boolean;\n };\n group: {\n minMemberCount: number;\n };\n messageFilter: MessageFilterConfig;\n autoUpdate: AutoUpdateConfig;\n}\n\nexport const CORE_DEFAULT_CONFIG: CorePluginConfig = {\n likeCommand: {\n enabled: true,\n keyword: \"赞我\",\n likeTimes: 10,\n reactionEmojiId: 201,\n },\n friend: {\n autoApprove: true,\n },\n group: {\n minMemberCount: 0,\n },\n messageFilter: {\n user: { whitelist: [], blacklist: [] },\n group: { whitelist: [], blacklist: [] },\n },\n autoUpdate: {\n enabled: true,\n time: \"03:00\",\n frequency: \"daily\",\n },\n};\n\nfunction normalizeIdList(input: unknown): number[] {\n if (!Array.isArray(input)) return [];\n return Array.from(\n new Set(\n input\n .map((v) => Math.floor(Number(v)))\n .filter((n) => Number.isFinite(n) && n > 0),\n ),\n );\n}\n\nfunction normalizeFilterRule(input: any): MessageFilterRule {\n return {\n whitelist: normalizeIdList(input?.whitelist),\n blacklist: normalizeIdList(input?.blacklist),\n };\n}\n\nexport function cloneConfig<T>(value: T): T {\n return JSON.parse(JSON.stringify(value)) as T;\n}\n\nexport function normalizeCoreConfig(config: CorePluginConfig | any): CorePluginConfig {\n const merged: CorePluginConfig = {\n ...cloneConfig(CORE_DEFAULT_CONFIG),\n ...(config || {}),\n likeCommand: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.likeCommand),\n ...(config?.likeCommand || {}),\n },\n friend: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.friend),\n ...(config?.friend || {}),\n },\n group: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.group),\n ...(config?.group || {}),\n minMemberCount:\n Number(config?.group?.minMemberCount) ||\n CORE_DEFAULT_CONFIG.group.minMemberCount,\n },\n messageFilter: {\n user: normalizeFilterRule(config?.messageFilter?.user),\n group: normalizeFilterRule(config?.messageFilter?.group),\n },\n autoUpdate: {\n ...cloneConfig(CORE_DEFAULT_CONFIG.autoUpdate),\n ...(config?.autoUpdate || {}),\n time: config?.autoUpdate?.time || CORE_DEFAULT_CONFIG.autoUpdate.time,\n frequency: [\"daily\", \"weekly\", \"monthly\"].includes(config?.autoUpdate?.frequency)\n ? config.autoUpdate.frequency\n : CORE_DEFAULT_CONFIG.autoUpdate.frequency,\n },\n };\n return merged;\n}\n","import type { AccessControlConfig } from \"../../../types\";\n\nexport const ACCESS_DEFAULT_CONFIG: AccessControlConfig = {\n version: 1,\n global: { plugins: {}, commands: {} },\n groups: {},\n users: {},\n};\n\nexport function normalizeAccessConfig(\n config: Partial<AccessControlConfig> | any,\n): AccessControlConfig {\n return {\n version: 1,\n global: {\n plugins: config?.global?.plugins ?? {},\n commands: config?.global?.commands ?? {},\n },\n groups: config?.groups ?? {},\n users: config?.users ?? {},\n };\n}\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { rootLogger as logger } from \"../../../logger\";\nimport type { AccessControlConfig } from \"../../../types\";\nimport {\n ACCESS_DEFAULT_CONFIG,\n normalizeAccessConfig,\n} from \"./access-config\";\n\nconst ACCESS_CONFIG_PATH = path.resolve(\n process.cwd(),\n \"config/core/access-control.json\",\n);\n\nconst BOOT_ACCESS_CONFIG_PATH = path.resolve(\n process.cwd(),\n \"config/boot/access-control.json\",\n);\n\nconst LEGACY_ACCESS_CONFIG_PATH = path.resolve(\n process.cwd(),\n \"config/access-control/base.json\",\n);\n\ninterface LegacyMessageFilter {\n user?: { whitelist?: Array<string | number>; blacklist?: Array<string | number> };\n group?: { whitelist?: Array<string | number>; blacklist?: Array<string | number> };\n}\n\nfunction readJsonSafe<T>(filePath: string): T | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n return JSON.parse(fs.readFileSync(filePath, \"utf-8\")) as T;\n } catch {\n return null;\n }\n}\n\nfunction writeJsonSafe(filePath: string, data: unknown): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf-8\");\n}\n\nfunction copyFromLegacyLocation(): boolean {\n if (fs.existsSync(ACCESS_CONFIG_PATH)) return false;\n const legacy = readJsonSafe<AccessControlConfig>(BOOT_ACCESS_CONFIG_PATH)\n ?? readJsonSafe<AccessControlConfig>(LEGACY_ACCESS_CONFIG_PATH);\n if (!legacy) return false;\n writeJsonSafe(ACCESS_CONFIG_PATH, normalizeAccessConfig(legacy));\n logger.info(\n `已从旧位置迁移 access-control 配置到 ${path.relative(process.cwd(), ACCESS_CONFIG_PATH)}`,\n );\n return true;\n}\n\nfunction migrateFromBootMessageFilter(): AccessControlConfig | null {\n if (fs.existsSync(ACCESS_CONFIG_PATH)) return null;\n\n const bootConfigPath = path.resolve(process.cwd(), \"config/boot/base.json\");\n const bootConfig = readJsonSafe<{ messageFilter?: LegacyMessageFilter }>(\n bootConfigPath,\n );\n if (!bootConfig?.messageFilter) return null;\n\n writeJsonSafe(ACCESS_CONFIG_PATH, ACCESS_DEFAULT_CONFIG);\n logger.info(\"已从旧 boot.messageFilter 迁移到 config/core/access-control.json\");\n\n const stripped = { ...bootConfig };\n delete (stripped as any).messageFilter;\n writeJsonSafe(bootConfigPath, stripped);\n logger.info(\"已从 config/boot/base.json 中移除 messageFilter 字段\");\n\n return ACCESS_DEFAULT_CONFIG;\n}\n\nexport function ensureAccessControlConfig(): AccessControlConfig {\n copyFromLegacyLocation();\n\n const existing = readJsonSafe<AccessControlConfig>(ACCESS_CONFIG_PATH);\n if (existing) return normalizeAccessConfig(existing);\n\n const migrated = migrateFromBootMessageFilter();\n if (migrated) return migrated;\n\n writeJsonSafe(ACCESS_CONFIG_PATH, ACCESS_DEFAULT_CONFIG);\n return ACCESS_DEFAULT_CONFIG;\n}\n","import type { AccessHook, PluginMetadata } from \"../../../types\";\n\nexport interface MessageCommandMatch {\n plugin: string;\n command: string;\n}\n\nfunction matchTextHook(text: string, hook: AccessHook): boolean {\n const m = String(hook.match || \"\").trim();\n if (!m) return false;\n if (m.startsWith(\"/\") && m.endsWith(\"/\") && m.length >= 3) {\n try {\n const re = new RegExp(m.slice(1, -1));\n return re.test(text);\n } catch {\n return false;\n }\n }\n return text === m || text.startsWith(m);\n}\n\nexport function matchMessageCommands(\n plugins: PluginMetadata[],\n text: string,\n): MessageCommandMatch[] {\n const trimmed = String(text || \"\").trim();\n if (!trimmed) return [];\n const out: MessageCommandMatch[] = [];\n for (const p of plugins) {\n const hooks = p.config?.accessHooks;\n if (!hooks || hooks.length === 0) continue;\n for (const hook of hooks) {\n if (!hook.match) continue;\n if (matchTextHook(trimmed, hook)) {\n out.push({ plugin: p.name, command: hook.id });\n }\n }\n }\n return out;\n}\n","import type { BotBase } from \"../../../adapter/bot\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport type { CorePluginConfig } from \"../config\";\n\nexport function registerLikeCommand(\n ctx: MiokuContext,\n getConfig: () => CorePluginConfig,\n): () => void {\n return ctx.handle(\"message\", async (event) => {\n const cfg = getConfig();\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) {\n return;\n }\n\n if (!cfg.likeCommand.enabled) {\n return;\n }\n\n const keyword = String(cfg.likeCommand.keyword || \"\").trim();\n if (!keyword || text !== keyword) {\n return;\n }\n\n const userId = event?.user_id || event?.sender?.user_id || \"\";\n if (!userId) {\n return;\n }\n\n const bot = event.bot;\n if (!bot) {\n return;\n }\n const likeTimes = Math.max(1, Number(cfg.likeCommand.likeTimes) || 10);\n const reactionEmojiId = Math.max(\n 0,\n Number(cfg.likeCommand.reactionEmojiId) || 66,\n );\n const messageId = event?.message_id;\n\n const adapter = bot.adapter as string;\n\n if (adapter === \"onebotv11\") {\n try {\n await bot.sendApi<boolean>(\"send_like\", {\n user_id: userId,\n times: likeTimes,\n });\n } catch (error) {\n ctx.logger.warn(`core send_like 失败: ${error}`);\n }\n\n if (messageId != null) {\n try {\n await bot.sendApi(\"set_msg_emoji_like\", {\n message_id: messageId,\n emoji_id: reactionEmojiId,\n set: true,\n });\n } catch (error) {\n ctx.logger.warn(`core set_msg_emoji_like 失败: ${error}`);\n }\n }\n } else if (adapter === \"icqq\") {\n const icqqBot = bot as BotBase & {\n sendLike(userId: string | number, times?: number): Promise<boolean>;\n };\n try {\n await icqqBot.sendLike(userId, likeTimes);\n } catch (error) {\n ctx.logger.warn(`core sendLike 失败: ${error}`);\n }\n }\n });\n}\n","import { botConfig } from \"../../../config\";\n\nexport function isPrivilegedUser(userId: string | number | undefined): boolean {\n const normalizedUserId = String(userId ?? \"\").trim();\n if (!normalizedUserId) return false;\n const owners = Array.isArray(botConfig?.owners) ? botConfig.owners : [];\n const admins = Array.isArray(botConfig?.admins) ? botConfig.admins : [];\n return [...owners, ...admins].some(\n (value) => String(value).trim() === normalizedUserId,\n );\n}\n","import { wait } from \"../../../utils\";\nimport { createGroupRef } from \"../../../capabilities\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport type { CorePluginConfig } from \"../config\";\nimport { isPrivilegedUser } from \"../access/privileged\";\n\nexport function registerMinMemberCheck(\n ctx: MiokuContext,\n getConfig: () => CorePluginConfig,\n): () => void {\n return ctx.handle(\"notice.group.increase\", async (event) => {\n const cfg = getConfig();\n const selfId = String(event?.self_id || ctx.self_id || \"\");\n const groupId = event?.group_id ?? \"\";\n const userId = event?.user_id ?? \"\";\n if (!groupId || !userId) return;\n if (userId !== selfId) return;\n\n if (\n (event?.raw as { action_type?: string } | undefined)?.action_type === \"invite\" &&\n isPrivilegedUser(event?.operator_id)\n ) {\n ctx.logger.info(`群 ${groupId} 由主人/管理员邀请加入,跳过入群限制检查`);\n return;\n }\n\n const minMemberCount = Math.max(0, Number(cfg.group.minMemberCount) || 0);\n if (minMemberCount <= 0) return;\n\n const bot = event.bot;\n if (!bot) return;\n\n try {\n await wait(1000);\n const groupRef = createGroupRef(bot, groupId);\n const groupInfo = await groupRef.getInfo();\n const memberCount = Number(groupInfo?.member_count || 0);\n if (memberCount > 0 && memberCount < minMemberCount) {\n await groupRef.leave(false);\n ctx.logger.info(\n `群 ${groupId} 人数 ${memberCount} 低于限制 ${minMemberCount},已自动退群`,\n );\n }\n } catch (error) {\n ctx.logger.warn(`入群人数检查失败: ${error}`);\n }\n });\n}\n","import type { MiokuContext } from \"../../../runtime/mioku-context\";\n\nconst FORWARD_LINE_LIMIT = 50;\nconst LINES_PER_NODE = 20;\n\nfunction chunk<T>(arr: T[], size: number): T[][] {\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n result.push(arr.slice(i, i + size));\n }\n return result;\n}\n\nexport function replyText(event: any, text: string): Promise<void> {\n return event.reply(text, true);\n}\n\nexport async function sendTextOrForward(options: {\n ctx: MiokuContext;\n event: any;\n text: string;\n source: string;\n summary?: string;\n}): Promise<void> {\n const { ctx, event, text, source, summary } = options;\n const lines = text.split(/\\r?\\n/).filter((line) => line.length > 0);\n if (lines.length <= FORWARD_LINE_LIMIT) {\n await replyText(event, text);\n return;\n }\n\n const selfId = String(event?.self_id || \"\");\n const bot = event.bot;\n if (!bot) {\n await replyText(event, text);\n return;\n }\n\n const nodes = chunk(lines, LINES_PER_NODE).map((chunkLines, idx) => ({\n user_id: selfId,\n nickname: `第${idx + 1}条`,\n content: [ctx.segment.text(chunkLines.join(\"\\n\"))],\n }));\n\n try {\n const target =\n event?.message_type === \"group\" && event?.group_id\n ? { type: \"group\" as const, group_id: event.group_id }\n : event?.user_id\n ? { type: \"private\" as const, user_id: event.user_id }\n : undefined;\n if (target) {\n await bot.sendForward(target, nodes, { source, summary });\n }\n } catch (error) {\n ctx.logger.error(`[core] 发送转发消息失败: ${error}`);\n await replyText(event, text);\n }\n}\n","import { botConfig } from \"../../../config\";\n\nexport function getCommandPrefix(): string {\n return botConfig.prefix ?? \".\";\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { rootLogger as logger } from \"../../../logger\";\n\nconst NPM_REGISTRY = \"https://registry.npmjs.org\";\nconst OFFICIAL_REGISTRY_URL =\n \"https://raw.githubusercontent.com/mioku-lab/mioku/main/official-registry.json\";\nconst PLUGIN_PREFIX = \"mioku-plugin-\";\nconst SERVICE_PREFIX = \"mioku-service-\";\nconst FRAMEWORK_NAME = \"mioku\";\n\nexport type PackageType = \"plugin\" | \"service\" | \"framework\";\n\nexport interface InstalledPackage {\n name: string;\n type: PackageType;\n shortName: string;\n version: string;\n path: string;\n}\n\nexport interface UpdateAvailable {\n name: string;\n type: PackageType;\n shortName: string;\n current: string;\n latest: string;\n}\n\nexport interface MarketItem {\n name: string;\n npm: string;\n type: PackageType;\n description: string;\n latest: string;\n installed: boolean;\n installedVersion: string;\n hasUpdate: boolean;\n tags: string[];\n official: boolean;\n homepage: string;\n repo: string;\n}\n\ninterface OfficialRegistryEntry {\n npm?: string;\n builtin?: boolean;\n}\n\ninterface OfficialRegistry {\n plugins?: Record<string, OfficialRegistryEntry>;\n services?: Record<string, OfficialRegistryEntry>;\n}\n\ninterface NpmSearchObject {\n package: {\n name: string;\n description?: string;\n version?: string;\n keywords?: string[];\n date?: string;\n links?: {\n npm?: string;\n repository?: string;\n homepage?: string;\n };\n };\n searchScore?: number;\n score?: { final?: number };\n}\n\nexport interface BunRunResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\nfunction projectRoot(): string {\n return process.cwd();\n}\n\nfunction detectType(name: string): PackageType | null {\n if (name === FRAMEWORK_NAME) return \"framework\";\n if (name.startsWith(PLUGIN_PREFIX)) return \"plugin\";\n if (name.startsWith(SERVICE_PREFIX)) return \"service\";\n return null;\n}\n\nfunction shortNameOf(name: string): string {\n if (name === FRAMEWORK_NAME) return FRAMEWORK_NAME;\n if (name.startsWith(PLUGIN_PREFIX)) return name.slice(PLUGIN_PREFIX.length);\n if (name.startsWith(SERVICE_PREFIX)) return name.slice(SERVICE_PREFIX.length);\n return name;\n}\n\nexport async function runBun(args: string[], cwd?: string): Promise<BunRunResult> {\n const runCwd = cwd ?? projectRoot();\n logger.info(`[core] 执行: bun ${args.join(\" \")} (cwd: ${runCwd})`);\n const startedAt = Date.now();\n return new Promise((resolve) => {\n const child = spawn(\"bun\", args, {\n cwd: runCwd,\n shell: process.platform === \"win32\",\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.on(\"data\", (chunk) => {\n stdout += String(chunk);\n });\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", (err) => {\n logger.error(`[core] bun 进程异常: ${err}`);\n resolve({ code: -1, stdout, stderr: stderr + String(err) });\n });\n child.on(\"close\", (code) => {\n const elapsed = ((Date.now() - startedAt) / 1000).toFixed(1);\n const exitCode = code ?? -1;\n if (exitCode === 0) {\n logger.info(`[core] bun 完成 (耗时 ${elapsed}s)`);\n } else {\n logger.error(\n `[core] bun 退出码 ${exitCode} (耗时 ${elapsed}s)\\n${stderr || stdout}`,\n );\n }\n resolve({ code: exitCode, stdout, stderr });\n });\n });\n}\n\nfunction readPackageJson(dir: string): any | null {\n const pkgPath = path.join(dir, \"package.json\");\n if (!fs.existsSync(pkgPath)) return null;\n try {\n return JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n } catch {\n return null;\n }\n}\n\nexport function getInstalledVersion(pkgName: string): string {\n const pkg = readPackageJson(path.join(projectRoot(), \"node_modules\", pkgName));\n return String(pkg?.version || \"0.0.0\");\n}\n\nexport function listInstalledPackages(): InstalledPackage[] {\n const modulesPath = path.join(projectRoot(), \"node_modules\");\n const result: InstalledPackage[] = [];\n if (!fs.existsSync(modulesPath)) return result;\n\n const entries = fs.readdirSync(modulesPath, { withFileTypes: true });\n for (const entry of entries) {\n const type = detectType(entry.name);\n if (!type) continue;\n const fullPath = path.join(modulesPath, entry.name);\n const stat = fs.lstatSync(fullPath);\n if (!stat.isDirectory() && !stat.isSymbolicLink()) continue;\n const pkg = readPackageJson(fullPath);\n result.push({\n name: entry.name,\n type,\n shortName: shortNameOf(entry.name),\n version: String(pkg?.version || \"0.0.0\"),\n path: fullPath,\n });\n }\n return result.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nasync function fetchJson(url: string): Promise<any> {\n const res = await fetch(url, {\n headers: { Accept: \"application/json\", \"User-Agent\": \"mioku-core\" },\n });\n if (!res.ok) throw new Error(`HTTP_${res.status}`);\n return res.json();\n}\n\ninterface NpmPackageMeta {\n latest: string;\n description: string;\n keywords: string[];\n homepage: string;\n repository: string;\n readme: string;\n license: string;\n}\n\nasync function fetchNpmMeta(pkgName: string): Promise<NpmPackageMeta | null> {\n try {\n const data = await fetchJson(\n `${NPM_REGISTRY}/${encodeURIComponent(pkgName)}`,\n );\n const latest = String(data?.[\"dist-tags\"]?.latest || \"\").trim();\n const version = latest ? data?.versions?.[latest] || {} : {};\n const repository = version?.repository || data?.repository;\n let repoUrl = \"\";\n if (typeof repository === \"string\") repoUrl = repository;\n else if (repository?.url) repoUrl = repository.url;\n repoUrl = repoUrl.replace(/^git\\+/, \"\").replace(/\\.git$/, \"\");\n return {\n latest,\n description: String(version?.description || data?.description || \"\").trim(),\n keywords: Array.isArray(version?.keywords) ? version.keywords : [],\n homepage: String(version?.homepage || data?.homepage || \"\").trim(),\n repository: repoUrl,\n readme: String(data?.readme || \"\").trim(),\n license: String(version?.license || data?.license || \"\").trim(),\n };\n } catch {\n return null;\n }\n}\n\nexport async function checkUpdates(): Promise<UpdateAvailable[]> {\n const installed = listInstalledPackages();\n const metas = await Promise.all(\n installed.map(async (pkg) => {\n const meta = await fetchNpmMeta(pkg.name);\n return { pkg, meta };\n }),\n );\n\n const updates: UpdateAvailable[] = [];\n for (const { pkg, meta } of metas) {\n if (!meta || !meta.latest) continue;\n if (meta.latest === pkg.version) continue;\n updates.push({\n name: pkg.name,\n type: pkg.type,\n shortName: pkg.shortName,\n current: pkg.version,\n latest: meta.latest,\n });\n }\n return updates;\n}\n\nexport interface UpdatedPackageResult {\n name: string;\n before: string;\n after: string;\n changed: boolean;\n}\n\nfunction snapshotVersions(names: string[]): Map<string, string> {\n const map = new Map<string, string>();\n for (const name of names) {\n map.set(name, getInstalledVersion(name));\n }\n return map;\n}\n\nexport async function updatePackages(names: string[]): Promise<BunRunResult> {\n if (names.length === 0) return { code: 0, stdout: \"\", stderr: \"\" };\n return runBun([\"update\", ...names, \"--latest\"]);\n}\n\nexport async function updateAllManaged(): Promise<{\n result: BunRunResult;\n names: string[];\n}> {\n const managed = listInstalledPackages()\n .filter((pkg) => pkg.type !== \"framework\")\n .map((pkg) => pkg.name);\n if (managed.length === 0) {\n return { result: { code: 0, stdout: \"\", stderr: \"\" }, names: [] };\n }\n return { result: await updatePackages(managed), names: managed };\n}\n\nexport function diffVersions(\n names: string[],\n before: Map<string, string>,\n): UpdatedPackageResult[] {\n return names.map((name) => {\n const after = getInstalledVersion(name);\n const prev = before.get(name) || \"0.0.0\";\n return { name, before: prev, after, changed: prev !== after };\n });\n}\n\nexport function snapshotAll(names: string[]): Map<string, string> {\n return snapshotVersions(names);\n}\n\nfunction appendToMiokuPlugins(pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n const packageJsonPath = path.join(projectRoot(), \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n const pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (plugins.includes(shortName)) return false;\n plugins.push(shortName);\n pkg.mioku = { ...mioku, plugins };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nfunction removeFromMiokuPlugins(pkgName: string): boolean {\n if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;\n const shortName = pkgName.slice(PLUGIN_PREFIX.length);\n const packageJsonPath = path.join(projectRoot(), \"package.json\");\n if (!fs.existsSync(packageJsonPath)) return false;\n const pkg = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n const mioku = pkg.mioku ?? {};\n const plugins = Array.isArray(mioku.plugins) ? [...mioku.plugins] : [];\n if (!plugins.includes(shortName)) return false;\n pkg.mioku = {\n ...mioku,\n plugins: plugins.filter((name: string) => name !== shortName),\n };\n fs.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n return true;\n}\n\nfunction normalizeTargetName(type: \"plugin\" | \"service\", name: string): string {\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n return name.startsWith(prefix) ? name : `${prefix}${name}`;\n}\n\nexport interface InstallResult {\n ok: boolean;\n packageName: string;\n enabled: boolean;\n output: string;\n error?: string;\n}\n\nexport async function installPackage(\n type: \"plugin\" | \"service\",\n name: string,\n): Promise<InstallResult> {\n const packageName = normalizeTargetName(type, name);\n logger.info(`[core] 开始安装 ${type} 包: ${packageName}`);\n const result = await runBun([\"add\", packageName]);\n if (result.code !== 0) {\n logger.error(`[core] 安装 ${packageName} 失败: ${result.stderr || result.stdout}`);\n return {\n ok: false,\n packageName,\n enabled: false,\n output: result.stdout || result.stderr,\n error: result.stderr || result.stdout || \"安装失败\",\n };\n }\n let enabled = false;\n if (type === \"plugin\") {\n enabled = appendToMiokuPlugins(packageName);\n }\n const installedVersion = getInstalledVersion(packageName);\n logger.info(\n `[core] 安装成功 ${packageName}@${installedVersion}${enabled ? \"(已启用)\" : \"\"}`,\n );\n return {\n ok: true,\n packageName,\n enabled,\n output: result.stdout || result.stderr,\n };\n}\n\nexport interface UninstallResult {\n ok: boolean;\n packageName: string;\n removedFromConfig: boolean;\n output: string;\n error?: string;\n}\n\nexport async function uninstallPackage(\n type: \"plugin\" | \"service\",\n name: string,\n): Promise<UninstallResult> {\n const packageName = normalizeTargetName(type, name);\n logger.info(`[core] 开始卸载 ${type} 包: ${packageName}`);\n const result = await runBun([\"remove\", packageName]);\n if (result.code !== 0) {\n logger.error(`[core] 卸载 ${packageName} 失败: ${result.stderr || result.stdout}`);\n return {\n ok: false,\n packageName,\n removedFromConfig: false,\n output: result.stdout || result.stderr,\n error: result.stderr || result.stdout || \"卸载失败\",\n };\n }\n let removedFromConfig = false;\n if (type === \"plugin\") {\n removedFromConfig = removeFromMiokuPlugins(packageName);\n }\n logger.info(\n `[core] 卸载成功 ${packageName}${removedFromConfig ? \"(已从配置移除)\" : \"\"}`,\n );\n return {\n ok: true,\n packageName,\n removedFromConfig,\n output: result.stdout || result.stderr,\n };\n}\n\nexport async function fetchOfficialRegistry(): Promise<OfficialRegistry> {\n return fetchJson(OFFICIAL_REGISTRY_URL);\n}\n\nasync function searchNpmPackages(): Promise<NpmSearchObject[]> {\n const url = `${NPM_REGISTRY}/-/v1/search?text=mioku&size=250`;\n const data = (await fetchJson(url)) as { objects?: NpmSearchObject[] };\n return data.objects || [];\n}\n\nfunction extractKeywords(raw: unknown): string[] {\n if (!Array.isArray(raw)) return [];\n return raw\n .map((item) => String(item || \"\").trim())\n .filter((item) => item && item !== \"mioku\");\n}\n\nfunction buildMarketItem(\n pkgName: string,\n meta: NpmPackageMeta | null,\n official: boolean,\n): MarketItem {\n const type = detectType(pkgName) as \"plugin\" | \"service\";\n const installedVersion = getInstalledVersion(pkgName);\n const installed =\n installedVersion !== \"0.0.0\" && installedVersion !== \"\";\n const latest = String(meta?.latest || \"\");\n return {\n name: shortNameOf(pkgName),\n npm: pkgName,\n type,\n description: meta?.description || \"暂无介绍\",\n latest,\n installed,\n installedVersion: installed ? installedVersion : \"\",\n hasUpdate: installed && latest !== \"\" && latest !== installedVersion,\n tags: extractKeywords(meta?.keywords).slice(0, 4),\n official,\n homepage: meta?.homepage || \"\",\n repo: meta?.repository || \"\",\n };\n}\n\nexport async function getMarketItems(\n type: \"plugin\" | \"service\",\n): Promise<MarketItem[]> {\n const registry = await fetchOfficialRegistry();\n const officialEntries =\n type === \"plugin\" ? registry.plugins || {} : registry.services || {};\n const officialNpmNames = new Set(\n Object.values(officialEntries)\n .map((entry) => String(entry?.npm || \"\"))\n .filter(Boolean),\n );\n\n const searchObjects = await searchNpmPackages().catch(() => [] as NpmSearchObject[]);\n const prefix = type === \"plugin\" ? PLUGIN_PREFIX : SERVICE_PREFIX;\n\n const candidateNames = new Set<string>();\n for (const obj of searchObjects) {\n const name = String(obj?.package?.name || \"\");\n if (name.startsWith(prefix)) candidateNames.add(name);\n }\n for (const name of officialNpmNames) {\n if (name.startsWith(prefix)) candidateNames.add(name);\n }\n\n const metas = await Promise.all(\n Array.from(candidateNames).map(async (pkgName) => {\n const meta = await fetchNpmMeta(pkgName);\n return { pkgName, meta, official: officialNpmNames.has(pkgName) };\n }),\n );\n\n const items = metas\n .filter((entry) => entry.meta !== null)\n .filter((entry) => (entry.meta?.keywords ?? []).includes(\"mioku\"))\n .map((entry) =>\n buildMarketItem(entry.pkgName, entry.meta, entry.official),\n );\n\n return items.sort((a, b) => {\n if (a.installed !== b.installed) return a.installed ? -1 : 1;\n if (a.official !== b.official) return a.official ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n}\n","import * as path from \"path\";\nimport { existsSync, mkdirSync } from \"fs\";\n\n/** 插件数据目录:`data/<pluginName>/` */\nexport function getPluginDataDir(pluginName: string): string {\n return path.join(process.cwd(), \"data\", pluginName);\n}\n\n/** 服务数据目录:`data/<serviceName>/` */\nexport function getServiceDataDir(serviceName: string): string {\n return path.join(process.cwd(), \"data\", serviceName);\n}\n\n/** 全局数据目录:`data/` */\nexport function getDataDir(): string {\n return path.join(process.cwd(), \"data\");\n}\n\n/** 插件配置目录:`config/<pluginName>/` */\nexport function getPluginConfigDir(pluginName: string): string {\n return path.join(process.cwd(), \"config\", pluginName);\n}\n\n/** 服务配置目录:`config/service/<serviceName>/` */\nexport function getServiceConfigDir(serviceName: string): string {\n return path.join(process.cwd(), \"config\", \"service\", serviceName);\n}\n\n/** 全局配置目录:`config/` */\nexport function getConfigDir(): string {\n return path.join(process.cwd(), \"config\");\n}\n\n/** 确保插件数据目录存在,返回目录路径 */\nexport function ensureDataDir(pluginName: string): string {\n const dir = getPluginDataDir(pluginName);\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n return dir;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { formatDuration } from \"../../../utils\";\nimport { rootLogger as logger } from \"../../../logger\";\nimport { connectedBots } from \"../../../compat\";\nimport { getPluginDataDir } from \"../../../internal/data-paths\";\n\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\n\nconst isInPm2: boolean = Boolean(\n typeof process !== \"undefined\" && (process.env.PM2_HOME || process.env.PM2 || process.env.pm_id),\n);\n\nconst RESTART_MARKER_PATH = path.join(getPluginDataDir(\"core\"), \"restart.json\");\n\nexport interface RestartMarker {\n initiatedAt: number;\n selfId: number;\n groupId: number | null;\n userId: number;\n}\n\nfunction ensureDataDir(): void {\n const dir = path.dirname(RESTART_MARKER_PATH);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n\nexport function writeRestartMarker(marker: RestartMarker): void {\n ensureDataDir();\n fs.writeFileSync(\n RESTART_MARKER_PATH,\n JSON.stringify(marker, null, 2),\n \"utf-8\",\n );\n}\n\nexport function consumeRestartMarker(): RestartMarker | null {\n if (!fs.existsSync(RESTART_MARKER_PATH)) return null;\n try {\n const raw = fs.readFileSync(RESTART_MARKER_PATH, \"utf-8\");\n const parsed = JSON.parse(raw) as RestartMarker;\n fs.rmSync(RESTART_MARKER_PATH, { force: true });\n return parsed;\n } catch {\n fs.rmSync(RESTART_MARKER_PATH, { force: true });\n return null;\n }\n}\n\nfunction tempDir(): string {\n const dir = path.join(process.cwd(), \"temp\");\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n return dir;\n}\n\nfunction shellQuote(value: string): string {\n return `'${String(value).replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction writeRestartScript(): string {\n const cwd = process.cwd();\n const bun = process.execPath;\n const args = process.argv.slice(1);\n\n if (process.platform === \"win32\") {\n const scriptPath = path.join(tempDir(), \"mioku-restart.bat\");\n const quotedArgs = [bun, ...args].map((a) => `\"${a}\"`).join(\" \");\n const content = [\n \"@echo off\",\n \"ping -n 3 127.0.0.1 >nul\",\n `cd /d \"${cwd}\"`,\n `start \"mioku\" ${quotedArgs}`,\n \"del %~f0\",\n ].join(\"\\r\\n\");\n fs.writeFileSync(scriptPath, content, \"utf-8\");\n return scriptPath;\n }\n\n const scriptPath = path.join(tempDir(), \"mioku-restart.sh\");\n const execLine = [shellQuote(bun), ...args.map(shellQuote)].join(\" \");\n const content = [\n \"#!/usr/bin/env sh\",\n \"sleep 2\",\n `cd ${shellQuote(cwd)} || exit 1`,\n `exec ${execLine}`,\n ].join(\"\\n\");\n fs.writeFileSync(scriptPath, content, \"utf-8\");\n fs.chmodSync(scriptPath, 0o755);\n return scriptPath;\n}\n\nexport function cleanupStaleRestartScripts(): void {\n const dir = tempDir();\n for (const name of [\"mioku-restart.sh\", \"mioku-restart.bat\"]) {\n const file = path.join(dir, name);\n if (fs.existsSync(file)) {\n try {\n fs.rmSync(file, { force: true });\n } catch {\n // ignore\n }\n }\n }\n}\n\nexport function triggerRestart(marker: RestartMarker): void {\n writeRestartMarker(marker);\n\n if (isInPm2) {\n logger.info(\"[core] 检测到 PM2 环境,退出进程后将由 PM2 自动重启\");\n setTimeout(() => process.exit(0), 300);\n return;\n }\n\n const scriptPath = writeRestartScript();\n try {\n const child = spawn(\n process.platform === \"win32\" ? \"cmd.exe\" : \"sh\",\n process.platform === \"win32\" ? [\"/c\", scriptPath] : [scriptPath],\n { detached: true, stdio: \"ignore\" },\n );\n child.unref();\n logger.info(`[core] 重启脚本已启动: ${scriptPath}`);\n } catch (error) {\n logger.error(`[core] 启动重启脚本失败: ${error}`);\n }\n\n setTimeout(() => process.exit(0), 500);\n}\n\nexport function formatUptime(ms: number): string {\n return formatDuration(ms);\n}\n\nasync function waitForBot(timeoutMs = 60000): Promise<any | null> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n const bots = Array.from(connectedBots.values());\n if (bots.length > 0) return bots[0];\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n return null;\n}\n\nexport async function notifyRestartComplete(\n ctx: MiokuContext | undefined,\n marker: RestartMarker,\n): Promise<void> {\n const bot = await waitForBot();\n if (!bot) {\n logger.warn(\"[core] 重启完成但未等到 bot 上线,跳过通知\");\n return;\n }\n\n const duration = Date.now() - marker.initiatedAt;\n const message = `Bot重启成功!用时${formatDuration(duration)}`;\n const segment = ctx?.segment;\n\n try {\n const payload = segment ? [segment.text(message)] : [];\n if (marker.groupId) {\n await bot.sendMessage({ type: \"group\", group_id: marker.groupId}, payload);\n } else if (marker.userId) {\n await bot.sendMessage({ type: \"private\", user_id: marker.userId}, payload);\n }\n } catch (error) {\n ctx?.logger?.error?.(`[core] 发送重启完成通知失败: ${error}`);\n }\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { getPluginRuntimeState } from \"../../../runtime/plugin-state\";\nimport { replyText } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport {\n checkUpdates,\n diffVersions,\n snapshotAll,\n updateAllManaged,\n updatePackages,\n type UpdateAvailable,\n} from \"../system/package-manager\";\nimport { triggerRestart, type RestartMarker } from \"../system/restart\";\n\nconst SELECT_TIMEOUT_MS = 60000;\n\ninterface PendingSelection {\n disposer: () => void;\n timer: ReturnType<typeof setTimeout>;\n items: UpdateAvailable[];\n}\n\nconst RUNTIME_KEY = \"updateSelections\";\n\nfunction getPendingMap(): Map<string, PendingSelection> {\n const state = getPluginRuntimeState(\"core\");\n if (!state[RUNTIME_KEY]) {\n state[RUNTIME_KEY] = new Map<string, PendingSelection>();\n }\n return state[RUNTIME_KEY] as Map<string, PendingSelection>;\n}\n\nfunction conversationKey(event: any): string {\n const selfId = Number(event?.self_id || 0);\n if (event?.message_type === \"group\" && event?.group_id) {\n return `${selfId}:g:${event.group_id}`;\n }\n return `${selfId}:p:${event?.user_id || 0}`;\n}\n\nfunction typeLabel(type: string): string {\n if (type === \"plugin\") return \"plugin\";\n if (type === \"service\") return \"service\";\n return \"框架\";\n}\n\nfunction renderUpdateList(items: UpdateAvailable[]): string {\n const lines = items.map((item, idx) => {\n const label = typeLabel(item.type);\n return `${idx + 1}. [${label}] ${item.shortName} ${item.current} → ${item.latest}`;\n });\n return [\n \"以下包存在可用更新\",\n ...lines,\n \"\",\n \"用空格隔开需要更新的包编号,回复 all 更新全部\",\n ].join(\"\\n\");\n}\n\nfunction parseSelection(\n text: string,\n total: number,\n): { all: boolean; indices: number[] } {\n const normalized = text.trim().toLowerCase();\n if (normalized === \"all\" || normalized === \"全部\") {\n return { all: true, indices: [] };\n }\n const indices: number[] = [];\n for (const token of normalized.split(/\\s+/)) {\n if (!token) continue;\n const num = Number(token);\n if (Number.isInteger(num) && num >= 1 && num <= total) {\n indices.push(num - 1);\n }\n }\n return { all: false, indices: Array.from(new Set(indices)) };\n}\n\nasync function performUpdateAndReport(\n ctx: MiokuContext,\n event: any,\n names: string[],\n): Promise<void> {\n if (names.length === 0) {\n await replyText(event, \"没有需要更新的项。\");\n return;\n }\n const before = snapshotAll(names);\n await replyText(event, `正在更新 ${names.length} 个包,请稍候...`);\n const result = await updatePackages(names);\n if (result.code !== 0) {\n ctx.logger.error(`[core] 更新失败: ${result.stderr || result.stdout}`);\n await replyText(event, `更新失败:${result.stderr || result.stdout}`);\n return;\n }\n const diffs = diffVersions(names, before);\n const changed = diffs.filter((d) => d.changed);\n const unchanged = diffs.filter((d) => !d.changed);\n\n if (changed.length === 0) {\n await replyText(event, \"更新完成,所有包均已是最新版本\");\n return;\n }\n\n const lines = changed.map((d) => `• ${d.name}: ${d.before} → ${d.after}`);\n const parts = [`更新完成,共 ${changed.length} 个包已升级:`, ...lines];\n if (unchanged.length > 0) {\n parts.push(\"\", `另有 ${unchanged.length} 个包已是最新`);\n }\n parts.push(\"\", \"即将重启...\");\n await replyText(event, parts.join(\"\\n\"));\n\n const selfId = Number(event?.self_id || 0);\n const groupId =\n event?.message_type === \"group\" && event?.group_id\n ? Number(event.group_id)\n : null;\n const userId = Number(event?.user_id || 0);\n const marker: RestartMarker = {\n initiatedAt: Date.now(),\n selfId,\n groupId,\n userId,\n };\n triggerRestart(marker);\n}\n\nexport function registerUpdateCommands(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n if (!text.startsWith(`${prefix}update`)) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] update 指令仅主人可用\");\n return;\n }\n\n const arg = text.slice(prefix.length + \"update\".length).trim();\n const selfId = String(event?.self_id || \"\");\n const bot = event.bot;\n if (!bot) return;\n\n if (arg === \"all\") {\n const managed = await updateAllManaged();\n if (managed.names.length === 0) {\n await replyText(event, \"未找到可更新的 mioku 包\");\n return;\n }\n await performUpdateAndReport(ctx, event, managed.names);\n return;\n }\n\n if (arg === \"mioku\" || arg === \"self\") {\n await performUpdateAndReport(ctx, event, [\"mioku\"]);\n return;\n }\n\n if (arg.startsWith(\"plugin \") || arg.startsWith(\"service \")) {\n const [typeRaw, ...rest] = arg.split(/\\s+/);\n const name = rest.join(\" \").trim();\n const type = typeRaw === \"plugin\" ? \"plugin\" : \"service\";\n if (!name) {\n await replyText(event, `用法:${prefix}update ${type} <名称>`);\n return;\n }\n const pkgPrefix = type === \"plugin\" ? \"mioku-plugin-\" : \"mioku-service-\";\n const fullName = name.startsWith(pkgPrefix) ? name : `${pkgPrefix}${name}`;\n await performUpdateAndReport(ctx, event, [fullName]);\n return;\n }\n\n if (arg === \"check\" || arg === \"检查\") {\n const pending = getPendingMap();\n const key = conversationKey(event);\n const existing = pending.get(key);\n if (existing) {\n existing.disposer();\n clearTimeout(existing.timer);\n pending.delete(key);\n }\n\n let items: UpdateAvailable[];\n try {\n items = await checkUpdates();\n } catch (error) {\n ctx.logger.error(`[core] 检查更新失败: ${error}`);\n await replyText(event, `检查更新失败:${String(error)}`);\n return;\n }\n\n if (items.length === 0) {\n await replyText(event, \"所有插件与服务均已是最新版本\");\n return;\n }\n\n await replyText(event, renderUpdateList(items));\n\n const timeoutMs = SELECT_TIMEOUT_MS;\n const listenerDispose = ctx.handle(\"message\", async (ev: any) => {\n if (String(ev?.self_id || \"\") !== selfId) return;\n if (conversationKey(ev) !== key) return;\n if (!isEventOwner(ev)) return;\n\n const evText = ctx.text(ev)?.trim() || \"\";\n if (evText.startsWith(`${prefix}update`)) return;\n\n const sel = pending.get(key);\n if (!sel) return;\n\n clearTimeout(sel.timer);\n sel.disposer();\n pending.delete(key);\n\n const parsed = parseSelection(evText, sel.items.length);\n const chosen = parsed.all\n ? sel.items\n : parsed.indices.map((i) => sel.items[i]).filter(Boolean);\n\n if (chosen.length === 0) {\n await replyText(event, \"未选择任何有效项,已取消\");\n return;\n }\n await performUpdateAndReport(\n ctx,\n event,\n chosen.map((i) => i.name),\n );\n });\n\n const timer = setTimeout(async () => {\n const sel = pending.get(key);\n if (!sel) return;\n sel.disposer();\n pending.delete(key);\n await replyText(event, \"操作超时,已取消更新\");\n }, timeoutMs);\n\n pending.set(key, { disposer: listenerDispose, timer, items });\n return;\n }\n\n await replyText(\n event,\n `用法:\\n${prefix}update check 检查并选择更新\\n${prefix}update all 更新全部\\n${prefix}update mioku 更新框架\\n${prefix}update plugin <名称>\\n${prefix}update service <名称>`,\n );\n });\n\n return () => {\n dispose();\n const pending = getPendingMap();\n for (const sel of pending.values()) {\n clearTimeout(sel.timer);\n sel.disposer();\n }\n pending.clear();\n };\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { replyText } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport { installPackage, uninstallPackage } from \"../system/package-manager\";\n\nfunction parseTargetArgs(\n text: string,\n head: string,\n): { type: \"plugin\" | \"service\"; name: string } | null {\n if (!text.startsWith(head)) return null;\n const rest = text.slice(head.length).trim();\n const matched = rest.match(/^(plugin|service)\\s+([\\s\\S]+)$/);\n if (!matched) return null;\n const name = matched[2].trim();\n if (!name) return null;\n return { type: matched[1] as \"plugin\" | \"service\", name };\n}\n\nfunction typeLabel(type: \"plugin\" | \"service\"): string {\n return type === \"plugin\" ? \"插件\" : \"服务\";\n}\n\nexport function registerInstallCommands(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n const installHead = `${prefix}install`;\n const uninstallHead = `${prefix}uninstall`;\n if (!text.startsWith(installHead) && !text.startsWith(uninstallHead))\n return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] install/uninstall 指令仅主人可用\");\n return;\n }\n\n if (text.startsWith(installHead)) {\n const parsed = parseTargetArgs(text, installHead);\n if (!parsed) {\n await replyText(\n event,\n `用法:${prefix}install plugin <名称> 或 ${prefix}install service <名称>`,\n );\n return;\n }\n await replyText(\n event,\n `正在从 npm 安装${typeLabel(parsed.type)} ${parsed.name}...`,\n );\n try {\n const result = await installPackage(parsed.type, parsed.name);\n if (!result.ok) {\n ctx.logger.error(`[core] 安装失败: ${result.error || result.output}`);\n await replyText(event, `安装失败:${result.error || result.output}`);\n return;\n }\n const lines = [\n `已安装 ${result.packageName}`,\n result.enabled ? \"已在 plugins 中启用\" : \"\",\n \"重启后生效\",\n ].filter(Boolean);\n await replyText(event, lines.join(\"\\n\"));\n } catch (error) {\n ctx.logger.error(`[core] 安装失败: ${error}`);\n await replyText(event, `安装失败:${String(error)}`);\n }\n return;\n }\n\n const parsed = parseTargetArgs(text, uninstallHead);\n if (!parsed) {\n await replyText(\n event,\n `用法:${prefix}uninstall plugin <名称> 或 ${prefix}uninstall service <名称>`,\n );\n return;\n }\n await replyText(\n event,\n `正在卸载${typeLabel(parsed.type)} ${parsed.name}...`,\n );\n try {\n const result = await uninstallPackage(parsed.type, parsed.name);\n if (!result.ok) {\n ctx.logger.error(`[core] 卸载失败: ${result.error || result.output}`);\n await replyText(event, `卸载失败:${result.error || result.output}`);\n return;\n }\n const lines = [\n `已卸载 ${result.packageName}`,\n result.removedFromConfig ? \"已从 plugins 中移除\" : \"\",\n \"重启后生效\",\n ].filter(Boolean);\n await replyText(event, lines.join(\"\\n\"));\n } catch (error) {\n ctx.logger.error(`[core] 卸载失败: ${error}`);\n await replyText(event, `卸载失败:${String(error)}`);\n }\n });\n\n return dispose;\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { replyText, sendTextOrForward } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport { getMarketItems } from \"../system/package-manager\";\n\nfunction renderMarketText(\n kind: \"plugin\" | \"service\",\n items: Awaited<ReturnType<typeof getMarketItems>>,\n): string {\n const label = kind === \"plugin\" ? \"插件\" : \"服务\";\n const lines = items.map((item) => {\n const status = item.installed\n ? item.hasUpdate\n ? `可更新 ${item.installedVersion}→${item.latest}`\n : `已安装 ${item.installedVersion}`\n : `未安装${item.latest ? `(最新 ${item.latest})` : \"\"}`;\n return `• ${item.name} [${status}]\\n ${item.description}`;\n });\n return [`Mioku ${label}市场(共 ${items.length} 个)`, ...lines].join(\"\\n\");\n}\n\nexport function registerMarketCommands(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n\n const prefix = getCommandPrefix();\n const kind: \"plugin\" | \"service\" | null =\n text === `${prefix}plugin-market` || text === `${prefix}插件市场`\n ? \"plugin\"\n : text === `${prefix}service-market` || text === `${prefix}服务市场`\n ? \"service\"\n : null;\n if (!kind) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] market 指令仅主人可用\");\n return;\n }\n\n let items;\n try {\n items = await getMarketItems(kind);\n } catch (error) {\n ctx.logger.error(`[core] 获取市场信息失败: ${error}`);\n await replyText(event, `获取市场失败:${String(error)}`);\n return;\n }\n\n await sendTextOrForward({\n ctx,\n event,\n text: renderMarketText(kind, items),\n source: `Mioku ${kind === \"plugin\" ? \"插件\" : \"服务\"}市场`,\n summary: `共 ${items.length} 个`,\n });\n });\n\n return dispose;\n}\n","import { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { replyText } from \"./notify\";\nimport { getCommandPrefix } from \"./prefix\";\nimport {\n formatUptime,\n triggerRestart,\n type RestartMarker,\n} from \"../system/restart\";\n\nexport function registerRestartCommand(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n if (text !== `${prefix}restart` && text !== `${prefix}重启`) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] restart 指令仅主人可用\");\n return;\n }\n\n const uptimeMs = process.uptime() * 1000;\n const selfId = Number(event?.self_id || 0);\n const groupId =\n event?.message_type === \"group\" && event?.group_id\n ? Number(event.group_id)\n : null;\n const userId = Number(event?.user_id || 0);\n\n const marker: RestartMarker = {\n initiatedAt: Date.now(),\n selfId,\n groupId,\n userId,\n };\n\n try {\n await replyText(event, `Bot已运行${formatUptime(uptimeMs)},正在重启...`);\n } catch (error) {\n ctx.logger.warn(`[core] 发送重启提示失败: ${error}`);\n }\n\n ctx.logger.info(`[core] 正在执行重启命令 ${formatUptime(uptimeMs)}`);\n triggerRestart(marker);\n });\n\n return dispose;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { isEventOwner } from \"../../../runtime/mioku-context\";\nimport type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport { getCommandPrefix } from \"./prefix\";\nimport { replyText } from \"./notify\";\n\nconst LOG_LINE_COUNT = 100;\nconst LINES_PER_NODE = 20;\n\nfunction getLogDir(): string {\n return path.join(process.cwd(), \"logs\");\n}\n\nfunction getActiveLogFile(): string | null {\n const dir = getLogDir();\n if (!fs.existsSync(dir)) return null;\n let latest: { path: string; mtime: number } | null = null;\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (!entry.isFile() || !entry.name.endsWith(\".log\")) continue;\n const full = path.join(dir, entry.name);\n const mtime = fs.statSync(full).mtimeMs;\n if (!latest || mtime > latest.mtime) {\n latest = { path: full, mtime };\n }\n }\n return latest?.path ?? null;\n}\n\nfunction readLastLines(filePath: string, count: number): string[] {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const lines = content.split(/\\r?\\n/).filter((line) => line.length > 0);\n return lines.slice(-count);\n}\n\nfunction chunk<T>(arr: T[], size: number): T[][] {\n const result: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n result.push(arr.slice(i, i + size));\n }\n return result;\n}\n\nexport function registerLogCommand(ctx: MiokuContext): () => void {\n const dispose = ctx.handle(\"message\", async (event) => {\n const text = ctx.text(event)?.trim();\n if (!text || event?.user_id === event?.self_id) return;\n const prefix = getCommandPrefix();\n if (text !== `${prefix}log` && text !== `${prefix}日志`) return;\n\n if (!isEventOwner(event)) {\n ctx.logger.warn(\"[core] 日志指令仅主人可用\");\n return;\n }\n\n const selfId = String(event?.self_id || \"\");\n const bot = event.bot;\n if (!bot) return;\n\n const logFile = getActiveLogFile();\n if (!logFile) {\n await replyText(event, \"未找到日志文件。\");\n return;\n }\n\n let lines: string[];\n try {\n lines = readLastLines(logFile, LOG_LINE_COUNT);\n } catch (error) {\n ctx.logger.error(`[core] 读取日志失败: ${error}`);\n await replyText(event, `读取日志失败:${String(error)}`);\n return;\n }\n if (lines.length === 0) {\n await replyText(event, \"日志为空。\");\n return;\n }\n\n let infoCount = 0;\n let warnCount = 0;\n let errorCount = 0;\n for (const line of lines) {\n if (/\\bERROR\\b|\\berror\\b/i.test(line)) {\n errorCount++;\n } else if (/\\bWARN\\b|\\bwarn\\b/i.test(line)) {\n warnCount++;\n } else if (/\\bINFO\\b|\\binfo\\b/i.test(line)) {\n infoCount++;\n }\n }\n const summary = `info ${infoCount} warn ${warnCount} error ${errorCount}`;\n\n const chunks = chunk(lines, LINES_PER_NODE);\n\n const nodes = chunks.map((chunkLines, idx) => ({\n user_id: selfId,\n nickname: `第${idx + 1}条日志`,\n content: [ctx.segment.text(chunkLines.join(\"\\n\"))],\n }));\n\n try {\n const target =\n event?.message_type === \"group\" && event?.group_id\n ? { type: \"group\" as const, group_id: event.group_id }\n : event?.user_id\n ? { type: \"private\" as const, user_id: event.user_id }\n : undefined;\n if (target) {\n await bot.sendForward(target, nodes, {\n source: \"最近100条运行日志\",\n summary,\n });\n }\n } catch (error) {\n ctx.logger.error(`[core] 发送日志转发失败: ${error}`);\n await replyText(event, `发送日志失败:${String(error)}`);\n }\n });\n return dispose;\n}\n","import type { MiokuContext } from \"../../../runtime/mioku-context\";\nimport type { CorePluginConfig } from \"../config\";\nimport { isPrivilegedUser } from \"../access/privileged\";\n\nexport function registerAutoApprove(\n ctx: MiokuContext,\n getConfig: () => CorePluginConfig,\n): () => void {\n const offFriend = ctx.handle(\"request.friend\", async (event) => {\n if (!getConfig().friend.autoApprove) {\n return;\n }\n\n try {\n await event.approve();\n ctx.logger.info(`已自动通过好友申请: ${event.user_id}`);\n } catch (error) {\n ctx.logger.warn(`自动通过好友申请失败: ${error}`);\n }\n });\n\n const offGroup = ctx.handle(\"request.group.invite\", async (event) => {\n if (!isPrivilegedUser(event?.user_id)) {\n return;\n }\n\n try {\n await event.approve();\n ctx.logger.info(`已自动通过主人/管理员拉群邀请: ${event.user_id}`);\n } catch (error) {\n ctx.logger.warn(`自动通过主人/管理员拉群邀请失败: ${error}`);\n }\n });\n\n return () => {\n offFriend();\n offGroup();\n };\n}\n","import { rootLogger as logger } from \"../../../logger\";\nimport { triggerRestart, type RestartMarker } from \"./restart\";\nimport { listInstalledPackages, updatePackages } from \"./package-manager\";\n\nlet autoUpdateTimer: ReturnType<typeof setInterval> | null = null;\nlet running = false;\n\nexport function startAutoUpdateScheduler(\n enabled: boolean,\n time: string,\n frequency: \"daily\" | \"weekly\" | \"monthly\",\n): () => void {\n if (autoUpdateTimer) {\n clearInterval(autoUpdateTimer);\n autoUpdateTimer = null;\n }\n\n if (!enabled) return () => {};\n\n const [hour, minute] = time.split(\":\").map(Number);\n if (isNaN(hour) || isNaN(minute)) {\n logger.warn(`[core] 自动更新时间格式无效: ${time},调度器未启动`);\n return () => {};\n }\n\n logger.info(\n `[core] 自动更新调度器已启动: 频率=${frequency}, 时间=${time}`,\n );\n\n autoUpdateTimer = setInterval(async () => {\n if (running) return;\n const now = new Date();\n\n if (now.getHours() !== hour || now.getMinutes() !== minute) return;\n\n if (frequency === \"weekly\" && now.getDay() !== 1) return;\n if (frequency === \"monthly\" && now.getDate() !== 1) return;\n\n running = true;\n try {\n logger.info(\"[core] 自动更新开始...\");\n const allInstalled = listInstalledPackages();\n const names = allInstalled.map((pkg) => pkg.name);\n if (names.length === 0) {\n logger.info(\"[core] 未找到需要更新的包\");\n return;\n }\n\n const result = await updatePackages(names);\n if (result.code !== 0) {\n logger.error(\n `[core] 自动更新失败: ${result.stderr || result.stdout}`,\n );\n return;\n }\n\n logger.info(\"[core] 自动更新成功,准备重启...\");\n const marker: RestartMarker = {\n initiatedAt: Date.now(),\n selfId: 0,\n groupId: null,\n userId: 0,\n };\n triggerRestart(marker);\n } catch (error) {\n logger.error(`[core] 自动更新异常: ${error}`);\n } finally {\n running = false;\n }\n }, 60000);\n\n return () => {\n if (autoUpdateTimer) {\n clearInterval(autoUpdateTimer);\n autoUpdateTimer = null;\n }\n };\n}\n","import { version } from '../../../package.json' with { type: 'json' }\nimport { definePlugin } from '../../plugin'\nimport { createCmd, dedent, unique } from '../../utils'\nimport { isEventOwner, isEventOwnerOrAdmin } from '../../runtime/mioku-context'\nimport { getService } from '../../services/define'\nimport { Services } from '../../services/builtin'\nimport { rootLogger as logger } from '../../logger'\nimport {\n getPluginMetadataList,\n setPluginMetadata,\n} from '../../runtime/plugin-metadata'\nimport { getPluginRuntimeState, setPluginRuntimeState } from '../../runtime/plugin-state'\nimport { buildMiokuStatus, formatMiokuStatus } from './status'\nimport { buildAdapterReport, collectBotStats, formatAdapterReport } from './adapters'\nimport {\n CORE_DEFAULT_CONFIG,\n cloneConfig,\n normalizeCoreConfig,\n type CorePluginConfig,\n} from './config'\nimport { ensureAccessControlConfig } from './access/access-store'\nimport { normalizeAccessConfig } from './access/access-config'\nimport { matchMessageCommands } from './access/matcher'\nimport { registerLikeCommand } from './commands/like'\nimport { registerMinMemberCheck } from './commands/min-member'\nimport { registerUpdateCommands } from './commands/update'\nimport { registerInstallCommands } from './commands/install'\nimport { registerMarketCommands } from './commands/market'\nimport { registerRestartCommand } from './commands/restart'\nimport { registerLogCommand } from './commands/log'\nimport { registerAutoApprove } from './commands/auto-approve'\nimport {\n cleanupStaleRestartScripts,\n consumeRestartMarker,\n notifyRestartComplete,\n} from './system/restart'\nimport { startAutoUpdateScheduler } from './system/auto-update'\n\nimport type { Adapter, MessageSegment } from '../../adapter'\nimport type { MessageEvent } from '../../adapter'\nimport type { AccessHook, AccessControlConfig, PluginHelp, PluginMetadata } from '../../types'\nimport type { MiokuStatus } from './status'\nimport type { StatusProvider } from './adapters'\nimport type { MiokuPlugin } from '../../plugin'\nimport type { MiokuContext } from '../../runtime/mioku-context'\n\nexport type { MiokuStatus } from './status'\nexport type { StatusProvider } from './adapters'\n\nexport const CORE_PLUGINS = ['mioku-core']\n\ntype AdapterEntry = {\n name: string\n version?: string\n impl?: { name: string; version?: string }\n}\n\nexport const formatMiokuStatusFn = formatMiokuStatus\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[-_.^$?[\\]{}()|\\\\]/g, '\\\\$&')\n}\n\nconst CORE_HELP_ENTRIES: ReadonlyArray<readonly [cmd: string, desc: string]> = [\n ['help', '显示帮助信息'],\n ['status', '显示框架状态'],\n ['adapter', '显示适配器与连接实例'],\n ['plugin', '插件管理'],\n ['settings', '框架设置管理'],\n ['update', '检查并选择插件/服务更新'],\n ['install', '从 npm 安装插件/服务'],\n ['uninstall', '卸载插件/服务'],\n ['plugin-market', '查看插件市场'],\n ['service-market', '查看服务市场'],\n ['restart', '重启机器人进程'],\n ['log', '查看最近100条日志'],\n ['exit', '退出框架进程'],\n]\n\nfunction displayWidth(value: string): number {\n let width = 0\n for (const ch of value) {\n width += /[\\u1100-\\u115F\\u2E80-\\uA4CF\\uAC00-\\uD7A3\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFF60\\uFFE0-\\uFFE6]/.test(ch) ? 2 : 1\n }\n return width\n}\n\nfunction padColumn(value: string, width: number): string {\n const gap = width - displayWidth(value)\n if (gap <= 0) return value\n // 只用全角空格(固定 2 格宽);半角空格在 QQ 字体里几乎不占宽,会导致错位\n return value + ' '.repeat(Math.ceil(gap / 2))\n}\n\nfunction buildCoreHelpText(displayPrefix: string): string {\n const cmds = CORE_HELP_ENTRIES.map(([cmd]) => `${displayPrefix}${cmd}`)\n const cmdWidth = Math.max(...cmds.map(displayWidth))\n const lines = CORE_HELP_ENTRIES.map(\n ([cmd, desc], i) => `${padColumn(cmds[i], cmdWidth)} ${desc}`,\n )\n return ['〓 💡 Mioku 帮助 〓', ...lines].join('\\n')\n}\n\nfunction buildCoreMetadata(\n ctx: MiokuContext,\n displayPrefix: string,\n likeKeyword: string,\n): PluginMetadata {\n const esc = escapeRegExp(displayPrefix)\n const ownerHelp = (cmd: string, desc: string): PluginHelp['commands'][number] => ({\n cmd: `${displayPrefix}${cmd}`,\n desc,\n role: 'master',\n })\n\n const help: PluginHelp = {\n title: '系统',\n description: 'Mioku 内置核心插件:系统命令与管理功能',\n commands: CORE_HELP_ENTRIES.map(([cmd, desc]) => ownerHelp(cmd, desc)),\n }\n\n const accessHooks: AccessHook[] = [\n { id: 'like', match: likeKeyword, description: '匹配赞我指令关键字' },\n { id: 'help', match: `/^${esc}(help|帮助)$/`, description: '匹配帮助指令' },\n { id: 'status', match: `/^${esc}(status|状态)$/`, description: '匹配状态指令' },\n { id: 'adapter', match: `/^${esc}(adapter|适配器)$/`, description: '匹配适配器指令' },\n { id: 'plugin', match: `/^${esc}(plugin|插件)/`, description: '匹配插件管理指令' },\n { id: 'settings', match: `/^${esc}(settings|设置)/`, description: '匹配设置管理指令' },\n { id: 'update', match: `/^${esc}(update|更新)/`, description: '匹配更新指令' },\n { id: 'install', match: `/^${esc}(install|安装)/`, description: '匹配安装指令' },\n { id: 'uninstall', match: `/^${esc}(uninstall|卸载)/`, description: '匹配卸载指令' },\n {\n id: 'market',\n match: `/^${esc}(plugin-market|service-market|插件市场|服务市场)$/`,\n description: '匹配插件/服务市场指令',\n },\n { id: 'restart', match: `/^${esc}(restart|重启)$/`, description: '匹配重启指令' },\n { id: 'log', match: `/^${esc}(log|日志)$/`, description: '匹配日志指令' },\n { id: 'exit', match: `/^${esc}(exit|退出)$/`, description: '匹配退出指令' },\n ]\n\n return {\n name: 'core',\n version,\n description: 'mioku 内置核心插件',\n path: '',\n packageJson: {},\n config: { help, accessHooks },\n }\n}\n\nconst core: MiokuPlugin = definePlugin({\n name: 'mioku-core',\n version,\n priority: -Infinity,\n description: 'mioku 内置核心插件',\n async setup(ctx: MiokuContext) {\n const rawPrefix = ctx.config.prefix ?? '.'\n const cmdPrefix = new RegExp(`^${escapeRegExp(rawPrefix)}`)\n const displayPrefix = rawPrefix\n const statusAdminOnly = ctx.config.status_permission === 'admin-only'\n\n logger.info('========================================')\n logger.info(' Mioku 正在引导服务...')\n logger.info('========================================')\n\n const disposers: Array<() => void> = []\n const configService = getService(ctx, Services.Config)\n\n let baseConfig: CorePluginConfig = cloneConfig(CORE_DEFAULT_CONFIG)\n if (configService) {\n await configService.registerConfig('core', 'base', baseConfig)\n const nextConfig = await configService.getConfig('core', 'base')\n if (nextConfig) {\n baseConfig = normalizeCoreConfig(nextConfig)\n }\n disposers.push(\n configService.onConfigChange('core', 'base', (next) => {\n baseConfig = normalizeCoreConfig(next)\n }),\n )\n } else {\n ctx.logger.warn('config-service 未加载,core 插件将使用默认配置')\n }\n\n let accessRules: AccessControlConfig = ensureAccessControlConfig()\n if (configService) {\n await configService.registerConfig('core', 'access-control', accessRules)\n const persisted = await configService.getConfig('core', 'access-control')\n if (persisted) {\n accessRules = normalizeAccessConfig(persisted)\n }\n disposers.push(\n configService.onConfigChange('core', 'access-control', (next) => {\n accessRules = normalizeAccessConfig(next)\n }),\n )\n }\n logger.info(`访问控制已挂载: ${ctx.bots.length} 个 bot`)\n\n setPluginMetadata(\n buildCoreMetadata(ctx, displayPrefix, String(baseConfig.likeCommand.keyword || '赞我')),\n )\n\n const coreState = getPluginRuntimeState('core')\n coreState.matchMessageCommands = (text: string) =>\n matchMessageCommands(getPluginMetadataList(), text)\n setPluginRuntimeState('core', coreState)\n\n cleanupStaleRestartScripts()\n const restartMarker = consumeRestartMarker()\n if (restartMarker) {\n notifyRestartComplete(ctx, restartMarker).catch((err) => {\n ctx.logger.error(`[core] 重启完成通知失败: ${err}`)\n })\n }\n\n disposers.push(registerLikeCommand(ctx, () => baseConfig))\n disposers.push(registerAutoApprove(ctx, () => baseConfig))\n disposers.push(registerMinMemberCheck(ctx, () => baseConfig))\n disposers.push(registerUpdateCommands(ctx))\n disposers.push(registerInstallCommands(ctx))\n disposers.push(registerMarketCommands(ctx))\n disposers.push(registerRestartCommand(ctx))\n disposers.push(registerLogCommand(ctx))\n disposers.push(\n startAutoUpdateScheduler(\n baseConfig.autoUpdate.enabled,\n baseConfig.autoUpdate.time,\n baseConfig.autoUpdate.frequency,\n ),\n )\n\n const collectBots = (): typeof ctx.bots => ctx.bots\n /** 已加载的适配器优先,再补上只在 bot 上出现过的适配器名 */\n const collectAdapters = (): AdapterEntry[] => {\n const describe = (name: string, adapter?: Adapter): AdapterEntry => ({\n name,\n version: adapter?.version,\n impl: adapter?.impl ? { name: adapter.impl.name, version: adapter.impl.version } : undefined,\n })\n const list = ctx.adapters.map((adapter) => describe(adapter.name, adapter))\n const seen = new Set(list.map((adapter) => adapter.name))\n for (const bot of ctx.bots) {\n const name = String(bot.adapter)\n if (seen.has(name)) continue\n seen.add(name)\n list.push(describe(name, ctx.getAdapter(name)))\n }\n return list\n }\n\n const getStatus = async (): Promise<MiokuStatus> => {\n const enabled = ctx.plugins.list().length\n const total = ctx.plugins.list().length + ctx.plugins.localPlugins().length\n const bots = collectBots()\n const botStats = bots.length\n ? collectBotStats(await buildAdapterReport({ bots, adapters: collectAdapters() }))\n : undefined\n return await buildMiokuStatus({\n bots,\n botStats,\n enabledPlugins: enabled,\n totalPlugins: total,\n })\n }\n\n const getAdapterText = async (): Promise<string> =>\n formatAdapterReport(await buildAdapterReport({ bots: collectBots(), adapters: collectAdapters() }))\n\n const atTarget = (event: MessageEvent): string | undefined => {\n const at = event.message.find((seg): seg is MessageSegment & { data: Record<string, unknown> } => seg.type === 'at')\n const qq = at?.data?.qq ?? at?.data?.target\n return qq != null ? String(qq) : undefined\n }\n\n disposers.push(\n ctx.handle('message', async (event) => {\n const ev = event as MessageEvent\n const text = ev.message.text()\n\n if (!cmdPrefix.test(text)) return\n\n if (statusAdminOnly && !isEventOwnerOrAdmin(ev)) return\n\n const bare = text.replace(cmdPrefix, '').trim()\n\n if (bare === '状态' || bare === 'status') {\n await ev.reply(await formatMiokuStatus(await getStatus()))\n return\n }\n\n if (bare === '适配器' || bare === 'adapter') {\n await ev.reply(await getAdapterText())\n return\n }\n\n if (!isEventOwner(ev)) return\n\n const { cmd, params } = createCmd(text)\n if (!cmd) return\n\n const subCmd = cmd.replace(cmdPrefix, '').replace(/\\s+/g, '')\n const target = params[0]\n\n switch (subCmd) {\n case 'help':\n case '帮助': {\n await ev.reply(buildCoreHelpText(displayPrefix))\n break\n }\n\n case 'plugin':\n case '插件': {\n if (CORE_PLUGINS.includes(target)) {\n await ev.reply('内置插件无法操作')\n return\n }\n\n switch (target) {\n case 'list':\n case '列表': {\n const enabled = ctx.plugins.list()\n const plugins = unique([...ctx.plugins.localPlugins(), ...enabled.map((e) => e.name)])\n .map((name) => {\n const entry = enabled.find((e) => e.name === name)\n const tag = entry ? '🟢' : '🔴'\n const type = entry?.type === 'builtin' ? '[内置]' : '[用户]'\n return `${tag} ${type} ${name}`\n })\n .sort((pre, next) => {\n const weight = (str: string): number => {\n let w = 0\n if (str.includes('🟢')) w += 10\n if (str.includes('[内置]')) w += 1\n return w\n }\n return weight(next) - weight(pre) || pre.localeCompare(next)\n })\n\n await ev.reply(\n dedent(`\n 〓 插件列表 〓\n ${plugins.join('\\n')}\n 共 ${plugins.length} 个,启用 ${enabled.length} 个\n `).trim(),\n )\n break\n }\n\n case 'enable':\n case '启用': {\n const pluginName = params[1]\n if (!pluginName) {\n await ev.reply('请指定插件 ID')\n return\n }\n try {\n await ctx.plugins.enable(pluginName)\n } catch (err) {\n await ev.reply(`插件 ${pluginName} 启用失败:${err instanceof Error ? err.message : '未知错误'}`)\n return\n }\n await ctx.updateConfig((c) => {\n c.plugins = [...c.plugins, pluginName]\n })\n await ev.reply(`插件 ${pluginName} 启用成功`)\n break\n }\n\n case 'disable':\n case '禁用': {\n const pluginName = params[1]\n if (!pluginName) {\n await ev.reply('请指定插件 ID')\n return\n }\n try {\n await ctx.plugins.disable(pluginName)\n } catch (err) {\n await ev.reply(err instanceof Error ? err.message : String(err))\n return\n }\n await ctx.updateConfig((c) => {\n c.plugins = c.plugins.filter((name) => name !== pluginName)\n })\n await ev.reply(`插件 ${pluginName} 已禁用`)\n break\n }\n\n case 'reload':\n case '重载': {\n const pluginName = params[1]\n if (!pluginName) {\n await ev.reply('请指定插件 ID')\n return\n }\n try {\n await ctx.plugins.reload(pluginName)\n } catch (err) {\n await ev.reply(err instanceof Error ? err.message : String(err))\n return\n }\n await ctx.updateConfig((c) => {\n c.plugins = [...c.plugins, pluginName]\n })\n await ev.reply(`插件 ${pluginName} 已重载`)\n break\n }\n\n default: {\n await ev.reply(\n dedent(`\n 〓 🧩 mioku 插件 〓\n ${displayPrefix}plugin list\n ${displayPrefix}plugin enable <ID>\n ${displayPrefix}plugin disable <ID>\n ${displayPrefix}plugin reload <ID>\n `).trim(),\n )\n break\n }\n }\n break\n }\n\n case 'settings':\n case '设置': {\n const action = target\n switch (action) {\n case 'detail':\n case '详情': {\n await ev.reply(\n dedent(`\n 〓 设置详情 〓\n 主人: ${ctx.config.owners.join(', ') || '(无)'}\n 管理: ${ctx.config.admins.join(', ') || '(无)'}\n 启用插件: ${ctx.config.plugins.join(', ') || '(无)'}\n `).trim(),\n )\n break\n }\n\n case 'add-owner':\n case '加主人':\n case '添加主人': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定主人 QQ/AT')\n return\n }\n const userId = String(uid)\n if (ctx.config.owners.includes(userId)) {\n await ev.reply(`主人 ${uid} 已存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.owners = [...c.owners, userId]\n })\n await ev.reply(`已添加主人 ${uid}`)\n break\n }\n\n case 'remove-owner':\n case '删主人':\n case '删除主人': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定主人 QQ/AT')\n return\n }\n const userId = String(uid)\n if (userId === ctx.config.owners[0]) {\n await ev.reply('不能删除第一主人')\n return\n }\n if (!ctx.config.owners.includes(userId)) {\n await ev.reply(`主人 ${uid} 不存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.owners = c.owners.filter((id) => id !== userId)\n })\n await ev.reply(`已删除主人 ${uid}`)\n break\n }\n\n case 'add-admin':\n case '加管理':\n case '添加管理': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定管理 QQ/AT')\n return\n }\n const userId = String(uid)\n if (ctx.config.admins.includes(userId)) {\n await ev.reply(`管理 ${uid} 已存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.admins = [...c.admins, userId]\n })\n await ev.reply(`已添加管理 ${uid}`)\n break\n }\n\n case 'remove-admin':\n case '删管理':\n case '删除管理': {\n const uid = params[1] ?? atTarget(ev)\n if (!uid) {\n await ev.reply('请指定管理 QQ/AT')\n return\n }\n const userId = String(uid)\n if (!ctx.config.admins.includes(userId)) {\n await ev.reply(`管理 ${uid} 不存在`)\n return\n }\n await ctx.updateConfig((c) => {\n c.admins = c.admins.filter((id) => id !== userId)\n })\n await ev.reply(`已删除管理 ${uid}`)\n break\n }\n\n default: {\n await ev.reply(\n dedent(`\n 〓 ⚙️ mioku 设置 〓\n ${displayPrefix}settings detail\n ${displayPrefix}settings [add-owner|remove-owner] <QQ/AT>\n ${displayPrefix}settings [add-admin|remove-admin] <QQ/AT>\n `).trim(),\n )\n break\n }\n }\n break\n }\n\n case 'exit':\n case '退出': {\n await ev.reply('またね~')\n ctx.logger.info('接收到退出指令,即将退出... 如需自动重启,请使用 pm2 部署。')\n process.exit(0)\n }\n }\n }),\n )\n\n logger.info('========================================')\n logger.info(' Mioku 服务初始化完成')\n logger.info('========================================')\n\n return async () => {\n for (const dispose of disposers) {\n dispose()\n }\n\n logger.info('正在关闭 Mioku...')\n }\n },\n})\n\nexport default core\nexport { buildMiokuStatus, formatMiokuStatus } from './status'\nexport { buildAdapterReport, collectBotStats, formatAdapterReport, registerStatusProvider } from './adapters'\n","import core from './core'\n\nimport type { MiokuPlugin } from '../plugin'\n\nexport const BUILTIN_PLUGINS: readonly MiokuPlugin[] = [core]\n\nexport * from './core'\n","import { rootLogger as logger } from \"../logger\";\nimport type {\n AccessHook,\n PluginHelp,\n PluginMetadata,\n PluginPackageConfig,\n} from \"../types\";\nimport type { PackageJsonLike } from \"../types\";\n\nconst PLUGIN_CONFIG_KEYS = new Set([\n \"services\",\n \"help\",\n \"accessHooks\",\n]);\n\nconst ACCESS_HOOK_KEYS = new Set([\n \"id\",\n \"match\",\n \"event\",\n \"description\",\n]);\n\nconst HELP_KEYS = new Set([\"title\", \"description\", \"commands\"]);\n\nconst HELP_COMMAND_KEYS = new Set([\"cmd\", \"desc\", \"usage\", \"role\"]);\n\nfunction warnUnknownFields(\n prefix: string,\n obj: Record<string, unknown>,\n allowed: Set<string>,\n): void {\n for (const key of Object.keys(obj)) {\n if (!allowed.has(key)) {\n logger.warn(`[plugin-manifest] ${prefix} 含未知字段 \"${key}\"(将被忽略)`);\n }\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction validateHelp(value: unknown, pluginName: string): PluginHelp | undefined {\n if (value === undefined) return undefined;\n if (!isPlainObject(value)) {\n logger.warn(`[plugin-manifest] ${pluginName}.help 必须是对象,已忽略`);\n return undefined;\n }\n warnUnknownFields(`${pluginName}.help`, value, HELP_KEYS);\n\n const title = String(value.title ?? \"\").trim();\n const description = String(value.description ?? \"\").trim();\n const rawCommands = value.commands;\n\n if (!title) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.title 缺失或为空`);\n }\n if (!description) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.description 缺失或为空`);\n }\n if (!Array.isArray(rawCommands)) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.commands 必须是数组`);\n return { title, description, commands: [] };\n }\n\n const commands: PluginHelp[\"commands\"] = [];\n for (const cmd of rawCommands) {\n if (!isPlainObject(cmd)) {\n logger.warn(`[plugin-manifest] ${pluginName}.help.commands 项不是对象`);\n continue;\n }\n warnUnknownFields(\n `${pluginName}.help.commands[]`,\n cmd,\n HELP_COMMAND_KEYS,\n );\n const cmdName = String(cmd.cmd ?? \"\").trim();\n const desc = String(cmd.desc ?? \"\").trim();\n if (!cmdName || !desc) {\n logger.warn(\n `[plugin-manifest] ${pluginName}.help.commands 项缺少 cmd 或 desc`,\n );\n continue;\n }\n commands.push({\n cmd: cmdName,\n desc,\n usage: typeof cmd.usage === \"string\" ? cmd.usage : undefined,\n role: typeof cmd.role === \"string\" ? (cmd.role as never) : undefined,\n });\n }\n\n return { title, description, commands };\n}\n\nfunction validateAccessHooks(\n value: unknown,\n pluginName: string,\n): AccessHook[] | undefined {\n if (value === undefined) return undefined;\n if (!Array.isArray(value)) {\n logger.warn(`[plugin-manifest] ${pluginName}.accessHooks 必须是数组`);\n return undefined;\n }\n\n const hooks: AccessHook[] = [];\n for (const hook of value) {\n if (!isPlainObject(hook)) {\n logger.warn(`[plugin-manifest] ${pluginName}.accessHooks 项不是对象`);\n continue;\n }\n warnUnknownFields(\n `${pluginName}.accessHooks[]`,\n hook,\n ACCESS_HOOK_KEYS,\n );\n const id = String(hook.id ?? \"\").trim();\n if (!id) {\n logger.warn(\n `[plugin-manifest] ${pluginName}.accessHooks 项缺少 id,已忽略`,\n );\n continue;\n }\n hooks.push({\n id,\n match: typeof hook.match === \"string\" ? hook.match : undefined,\n event: typeof hook.event === \"string\" ? hook.event : undefined,\n description:\n typeof hook.description === \"string\" ? hook.description : undefined,\n });\n }\n return hooks;\n}\n\nexport function validatePluginPackageConfig(\n raw: unknown,\n pluginName: string,\n): PluginPackageConfig {\n const config: PluginPackageConfig = {};\n\n if (raw === undefined || raw === null) {\n return config;\n }\n if (!isPlainObject(raw)) {\n logger.warn(\n `[plugin-manifest] ${pluginName} 的 mioku 字段必须是对象,已使用空配置`,\n );\n return config;\n }\n\n warnUnknownFields(`${pluginName}.mioku`, raw, PLUGIN_CONFIG_KEYS);\n\n if (raw.services !== undefined) {\n if (Array.isArray(raw.services)) {\n const services = raw.services.filter(\n (s): s is string => typeof s === \"string\" && s.length > 0,\n );\n const dropped = raw.services.length - services.length;\n if (dropped > 0) {\n logger.warn(\n `[plugin-manifest] ${pluginName}.services 丢弃 ${dropped} 个非字符串项`,\n );\n }\n config.services = services;\n } else {\n logger.warn(`[plugin-manifest] ${pluginName}.services 必须是字符串数组`);\n }\n }\n\n const help = validateHelp(raw.help, pluginName);\n if (help) config.help = help;\n\n const hooks = validateAccessHooks(raw.accessHooks, pluginName);\n if (hooks) config.accessHooks = hooks;\n\n return config;\n}\n\nexport const buildPluginMetadata = (\n name: string,\n resolvedPath: string,\n packageJson: PackageJsonLike,\n): PluginMetadata => ({\n name,\n version: packageJson.version ?? \"0.0.0\",\n description: packageJson.description,\n path: resolvedPath,\n packageJson,\n config: validatePluginPackageConfig(packageJson.mioku, name),\n});","import fs from 'node:fs'\nimport path from 'node:path'\nimport { createRequire } from 'node:module'\nimport { pathToFileURL } from 'node:url'\n\nimport type { AdapterDefinition } from '../adapter'\nimport { validatePluginPackageConfig } from './manifest'\n\nimport type { PluginPackageConfig } from '../types'\n\nexport interface PackageJson {\n readonly name?: string\n readonly version?: string\n readonly description?: string\n readonly main?: string\n readonly module?: string\n readonly exports?: unknown\n readonly dependencies?: Readonly<Record<string, string>>\n readonly devDependencies?: Readonly<Record<string, string>>\n readonly optionalDependencies?: Readonly<Record<string, string>>\n readonly peerDependencies?: Readonly<Record<string, string>>\n readonly keywords?: readonly string[]\n readonly mioku?: unknown\n}\n\nexport interface PackageCandidate {\n readonly name: string\n readonly resolvedPath: string\n readonly packageJson: PackageJson\n}\n\nexport interface AdapterCandidate {\n readonly name: string\n readonly packageName: string\n readonly resolvedPath: string\n readonly packageJson: PackageJson\n readonly apiVersion: number\n readonly entry?: string\n readonly description?: string\n}\n\nexport interface PluginCandidate {\n readonly name: string\n readonly packageName: string\n readonly resolvedPath: string\n readonly packageJson: PackageJson\n readonly apiVersion: number\n readonly priority?: number\n readonly entry?: string\n readonly description?: string\n readonly config: PluginPackageConfig\n}\n\nconst ADAPTER_PACKAGE_PREFIX = 'mioku-adapter-'\nconst PLUGIN_PACKAGE_PREFIX = 'mioku-plugin-'\nconst KNOWN_ENTRY_FALLBACKS = ['dist/index.mjs', 'dist/index.js', 'dist/index.cjs', 'index.mjs', 'index.js']\n\nexport const readPackageJsonSafe = (dir: string): PackageJson | null => {\n const file = path.join(dir, 'package.json')\n if (!fs.existsSync(file)) return null\n try {\n return JSON.parse(fs.readFileSync(file, 'utf-8')) as PackageJson\n } catch {\n return null\n }\n}\n\nconst resolveFromCwd = (cwd: string, name: string): string | null => {\n const require = createRequire(pathToFileURL(path.join(cwd, 'package.json')).href)\n try {\n const entry = require.resolve(`${name}/package.json`)\n return path.dirname(entry)\n } catch {\n return null\n }\n}\n\nconst collectDirectDependencyNames = (pkg: PackageJson): readonly string[] => {\n const set = new Set<string>()\n for (const map of [pkg.dependencies, pkg.devDependencies, pkg.optionalDependencies]) {\n if (!map) continue\n for (const key of Object.keys(map)) set.add(key)\n }\n return Array.from(set)\n}\n\nexport const resolveEntry = (dir: string, pkg: PackageJson, override?: string): string | null => {\n if (override) {\n const abs = path.resolve(dir, override)\n if (fs.existsSync(abs)) return abs\n }\n const candidates: string[] = []\n if (typeof pkg.main === 'string') candidates.push(pkg.main)\n if (typeof pkg.module === 'string' && !candidates.includes(pkg.module)) candidates.push(pkg.module)\n if (typeof pkg.exports === 'string') candidates.push(pkg.exports)\n if (typeof pkg.exports === 'object' && pkg.exports) {\n const exportMap = pkg.exports as Record<string, unknown>\n const mainExport = exportMap['.']\n if (typeof mainExport === 'string') candidates.push(mainExport)\n if (typeof mainExport === 'object' && mainExport) {\n const nodeExport = (mainExport as Record<string, unknown>)['import'] ?? (mainExport as Record<string, unknown>)['default']\n if (typeof nodeExport === 'string') candidates.push(nodeExport)\n }\n }\n for (const candidate of candidates) {\n const abs = path.resolve(dir, candidate)\n if (fs.existsSync(abs)) return abs\n }\n for (const fallback of KNOWN_ENTRY_FALLBACKS) {\n const abs = path.join(dir, fallback)\n if (fs.existsSync(abs)) return abs\n }\n return null\n}\n\nexport const discoverAdapterCandidates = (cwd: string, appPackageJson: PackageJson): readonly AdapterCandidate[] => {\n const deps = collectDirectDependencyNames(appPackageJson)\n const seen = new Set<string>()\n const candidates: AdapterCandidate[] = []\n for (const dep of deps) {\n if (!dep.startsWith(ADAPTER_PACKAGE_PREFIX)) continue\n const dir = resolveFromCwd(cwd, dep)\n if (!dir) continue\n const pkg = readPackageJsonSafe(dir)\n if (!pkg) continue\n const adapterName = dep.slice(ADAPTER_PACKAGE_PREFIX.length)\n if (seen.has(adapterName)) {\n throw new Error(`Adapter name conflict: \"${adapterName}\" appears in multiple direct dependencies`)\n }\n seen.add(adapterName)\n candidates.push({\n name: adapterName,\n packageName: dep,\n resolvedPath: dir,\n packageJson: pkg,\n apiVersion: 1,\n description: pkg.description,\n })\n }\n return candidates\n}\n\nexport const discoverPluginCandidates = (cwd: string, appPackageJson: PackageJson): readonly PluginCandidate[] => {\n const deps = collectDirectDependencyNames(appPackageJson)\n const seen = new Set<string>()\n const candidates: PluginCandidate[] = []\n for (const dep of deps) {\n if (!dep.startsWith(PLUGIN_PACKAGE_PREFIX)) continue\n const dir = resolveFromCwd(cwd, dep)\n if (!dir) continue\n const pkg = readPackageJsonSafe(dir)\n if (!pkg) continue\n const pluginName = dep.slice(PLUGIN_PACKAGE_PREFIX.length)\n if (seen.has(pluginName)) {\n throw new Error(`Plugin canonical ID conflict: \"${pluginName}\" appears in multiple direct dependencies`)\n }\n seen.add(pluginName)\n candidates.push({\n name: pluginName,\n packageName: dep,\n resolvedPath: dir,\n packageJson: pkg,\n apiVersion: 1,\n description: pkg.description,\n config: validatePluginPackageConfig(pkg.mioku, pluginName),\n })\n }\n return candidates\n}\n\nexport const resolveLocalPluginPath = (cwd: string, pluginsDir: string, name: string): string | null => {\n const root = path.resolve(cwd, pluginsDir)\n if (!fs.existsSync(root)) return null\n const candidate = path.join(root, name)\n if (!fs.existsSync(candidate)) return null\n return candidate\n}\n\nexport const resolveLocalPluginEntry = (dir: string): string | null => {\n const pkg = readPackageJsonSafe(dir)\n const indexTs = path.join(dir, 'index.ts')\n if (fs.existsSync(indexTs)) return indexTs\n const candidates: string[] = []\n if (pkg?.main) candidates.push(pkg.main)\n if (pkg?.module && !candidates.includes(pkg.module)) candidates.push(pkg.module)\n candidates.push('index.js', 'index.cjs', 'index.mjs')\n for (const candidate of candidates) {\n const abs = path.resolve(dir, candidate)\n if (fs.existsSync(abs)) return abs\n }\n return null\n}\n\nexport const findLocalPlugins = (cwd: string, pluginsDir: string): readonly { name: string; absPath: string }[] => {\n const root = path.resolve(cwd, pluginsDir)\n if (!fs.existsSync(root)) return []\n return fs\n .readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() && !!entry.name && !entry.name.startsWith('_'))\n .map((entry) => ({\n name: entry.name,\n absPath: path.join(root, entry.name),\n }))\n}\n\nexport interface LoadedAdapterDefinition {\n readonly candidate: AdapterCandidate\n readonly definition: AdapterDefinition<unknown>\n}\n\nexport interface LoadedPluginDefinition {\n readonly candidate: PluginCandidate | { name: string; resolvedPath: string; entry: string; packageJson: PackageJson }\n readonly module: unknown\n}\n","import { pathToFileURL } from 'node:url'\nimport { createRequire } from 'node:module'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { createJiti, type Jiti } from 'jiti'\n\nimport type { AdapterDefinition } from '../adapter'\nimport type { AdapterCandidate, LoadedAdapterDefinition, PackageJson } from './package'\nimport { resolveEntry } from './package'\n\nconst isAdapterDefinition = (value: unknown): value is AdapterDefinition<unknown> => {\n if (!value || typeof value !== 'object') return false\n const v = value as Partial<AdapterDefinition<unknown>>\n return typeof v.name === 'string' && typeof v.version === 'string' && typeof v.apiVersion === 'number' && typeof v.create === 'function'\n}\n\nconst readDependencyNames = (cwd: string): string[] => {\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(cwd, 'package.json'), 'utf-8')) as PackageJson\n return [\n ...Object.keys(pkg.dependencies ?? {}),\n ...Object.keys(pkg.devDependencies ?? {}),\n ...Object.keys(pkg.optionalDependencies ?? {}),\n ]\n } catch {\n return []\n }\n}\n\nconst resolveAliases = (cwd: string): Record<string, string> => {\n const require = createRequire(path.join(cwd, 'package.json'))\n const aliases: Record<string, string> = {}\n for (const name of readDependencyNames(cwd)) {\n try {\n aliases[name] = require.resolve(name)\n } catch {\n // 忽略无法解析的依赖\n }\n }\n return aliases\n}\n\nexport const createImportContext = (cwd: string): Jiti => {\n return createJiti(cwd, {\n extensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.mjs', '.cjs', '.jsx'],\n cache: false,\n fsCache: false,\n moduleCache: false,\n requireCache: false,\n sourceMaps: false,\n interopDefault: true,\n jsx: { importSource: 'react', runtime: 'automatic' },\n alias: resolveAliases(cwd),\n })\n}\n\nexport const loadAdapterDefinition = async (\n jiti: Jiti,\n candidate: AdapterCandidate,\n): Promise<LoadedAdapterDefinition> => {\n const entry = resolveEntry(candidate.resolvedPath, candidate.packageJson as PackageJson, candidate.entry)\n if (!entry) {\n throw new Error(`Adapter \"${candidate.name}\" has no resolvable entry point`)\n }\n const mod = await jiti.import(pathToFileURL(entry).href)\n const exported = (mod as { default?: unknown }).default ?? mod\n if (!isAdapterDefinition(exported)) {\n throw new Error(`Adapter \"${candidate.name}\" does not export a valid AdapterDefinition`)\n }\n if (exported.name !== candidate.name) {\n throw new Error(`Adapter name mismatch: manifest=\"${candidate.name}\" export=\"${exported.name}\"`)\n }\n if (exported.apiVersion !== candidate.apiVersion) {\n throw new Error(\n `Adapter \"${candidate.name}\" apiVersion mismatch: manifest=${candidate.apiVersion} export=${exported.apiVersion}`,\n )\n }\n return { candidate, definition: exported }\n}","import { pathToFileURL } from 'node:url'\nimport type { Jiti } from 'jiti'\n\nimport type { MiokuPlugin } from '../plugin'\nimport type { PluginCandidate } from './package'\nimport { resolveEntry, resolveLocalPluginEntry } from './package'\n\nexport const isMiokuPlugin = (value: unknown): value is MiokuPlugin => {\n if (!value || typeof value !== 'object') return false\n const v = value as Partial<MiokuPlugin>\n return typeof v.name === 'string' && (v.setup === undefined || typeof v.setup === 'function')\n}\n\nconst loadFromEntry = async (jiti: Jiti, entry: string, name: string): Promise<MiokuPlugin> => {\n const mod = await jiti.import(pathToFileURL(entry).href)\n const exported = (mod as { default?: unknown }).default ?? mod\n if (!isMiokuPlugin(exported)) {\n throw new Error(`Plugin \"${name}\" does not export a valid MiokuPlugin (need \"name\" and optional \"setup\")`)\n }\n if (exported.name !== name) {\n throw new Error(\n `Plugin canonical ID mismatch: manifest=\"${name}\" export=\"${exported.name}\". Ensure plugin.name matches the manifest`,\n )\n }\n return exported\n}\n\nexport const loadNpmPlugin = async (\n jiti: Jiti,\n candidate: PluginCandidate,\n): Promise<MiokuPlugin> => {\n const entry = resolveEntry(candidate.resolvedPath, candidate.packageJson, candidate.entry)\n if (!entry) {\n throw new Error(`Plugin \"${candidate.name}\" has no resolvable entry point`)\n }\n return await loadFromEntry(jiti, entry, candidate.name)\n}\n\nexport const loadLocalPlugin = async (\n jiti: Jiti,\n name: string,\n resolvedPath: string,\n): Promise<MiokuPlugin> => {\n const entry = resolveLocalPluginEntry(resolvedPath)\n if (!entry) {\n throw new Error(`Local plugin \"${name}\" has no entry point`)\n }\n return await loadFromEntry(jiti, entry, name)\n}","import type { Event, MessageEvent } from \"../adapter\";\n\ninterface Entry {\n adapter: string;\n bucket: number;\n at: number;\n}\n\nconst BUCKET_SLACK = 1;\nconst PRUNE_INTERVAL = 128;\nconst TTL_MS = 15_000;\nconst MAX_SIZE = 4096;\nconst MAX_SEGMENTS = 16;\nconst MAX_TEXT = 256;\n\n/**\n * 把消息段序列化为跨适配器稳定的内容指纹:\n * 文本/@/表情取内容,媒体段只取类型(url/文件名跨协议不稳定)\n */\nconst contentFingerprintOf = (event: MessageEvent): string => {\n const parts: string[] = [];\n for (const seg of event.message) {\n if (parts.length >= MAX_SEGMENTS) break;\n if (seg.type === \"reply\") continue;\n const data = seg.data ?? {};\n if (seg.type === \"text\") {\n const text = typeof data.text === \"string\" ? data.text : \"\";\n parts.push(`t:${text.slice(0, MAX_TEXT)}`);\n } else if (seg.type === \"at\") {\n const target = data.qq ?? data.target;\n parts.push(`a:${target == null ? \"\" : String(target)}`);\n } else if (seg.type === \"face\") {\n parts.push(`f:${data.id == null ? \"\" : String(data.id)}`);\n } else {\n parts.push(seg.type);\n }\n }\n return parts.join(\"|\");\n};\n\nconst scopeKeyOf = (event: MessageEvent, content: string): string =>\n [\n event.self_id ?? \"\",\n event.message_type ?? \"\",\n event.group_id ?? event.user_id ?? \"\",\n event.user_id ?? \"\",\n content,\n ].join(\"|\");\n\n/**\n * 跨适配器消息去重(L2)\n */\nexport class CrossAdapterMessageDeduplicator {\n readonly #entries = new Map<string, Entry>();\n #inserts = 0;\n #dropped = 0;\n\n /** 本次运行以来被丢弃的跨适配器重复消息数 */\n get dropped(): number {\n return this.#dropped;\n }\n\n isDuplicate(event: Event): boolean {\n if (event.kind !== \"message\") return false;\n const messageEvent = event as MessageEvent;\n const adapter = messageEvent.identity?.adapter ?? \"\";\n const now = Date.now();\n const bucket = Math.floor((messageEvent.time ?? now) / 1000);\n const key = scopeKeyOf(messageEvent, contentFingerprintOf(messageEvent));\n\n const existing = this.#entries.get(key);\n if (existing) {\n if (Math.abs(existing.bucket - bucket) <= BUCKET_SLACK) {\n if (existing.adapter !== adapter) {\n this.#dropped++;\n return true;\n }\n existing.bucket = bucket;\n existing.at = now;\n return false;\n }\n existing.bucket = bucket;\n existing.at = now;\n existing.adapter = adapter;\n return false;\n }\n\n this.#entries.set(key, { adapter, bucket, at: now });\n this.#inserts++;\n if (this.#inserts >= PRUNE_INTERVAL || this.#entries.size > MAX_SIZE) {\n this.#inserts = 0;\n this.#prune(now);\n }\n return false;\n }\n\n #prune(now: number): void {\n for (const [key, entry] of this.#entries) {\n if (now - entry.at > TTL_MS) this.#entries.delete(key);\n }\n }\n\n clear(): void {\n this.#entries.clear();\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { hrtime } from \"node:process\";\n\nimport { colors } from \"consola/utils\";\n\nimport {\n botConfig,\n reloadMiokuConfig,\n setBotCwd,\n updateMiokuConfig,\n} from \"../config\";\nimport { createDefaultDriver, DriverShutdownError } from \"../driver\";\nimport type { Driver } from \"../driver\";\nimport { CapabilityRegistry } from \"../adapter\";\nimport { definePlugin } from \"../plugin\";\nimport type { MiokuPlugin, PluginCleanup } from \"../plugin\";\nimport { BotRegistry } from \"./bots\";\nimport { EventBus } from \"./bus\";\nimport { AdapterContextImpl } from \"./context\";\nimport type { RuntimeAdapterState } from \"./context\";\nimport { MiokuContext } from \"./mioku-context\";\nimport { BUILTIN_PLUGINS as DEFAULT_BUILTIN_PLUGINS } from \"../builtin\";\nimport {\n createImportContext,\n discoverAdapterCandidates,\n discoverPluginCandidates,\n findLocalPlugins,\n loadAdapterDefinition,\n loadLocalPlugin,\n loadNpmPlugin,\n} from \"../loader\";\nimport { buildPluginMetadata } from \"../loader/manifest\";\nimport { readPackageJsonSafe } from \"../loader\";\nimport {\n setPluginMetadata,\n removePluginMetadata,\n resetPluginMetadata,\n} from \"./plugin-metadata\";\n\nimport type { Logger } from \"../logger\";\nimport type { Adapter, AdapterDefinition, BotLifecycleEvent } from \"../adapter\";\nimport type { PluginCandidate } from \"../loader\";\nimport type { Event } from \"../adapter\";\nimport type { Bot } from \"../adapter\";\nimport { CrossAdapterMessageDeduplicator } from \"./cross-adapter-dedup\";\n\nexport interface CreateRuntimeOptions {\n readonly cwd: string;\n readonly logger: Logger;\n readonly builtinPlugins?: readonly MiokuPlugin[];\n readonly driverFactory?: () => Driver;\n /** 去重选项;缺省全部开启 */\n readonly dedup?: {\n /** 跨适配器指纹去重 */\n readonly crossAdapter?: boolean;\n };\n}\n\nexport interface AdapterStartResult {\n readonly name: string;\n readonly adapter: Adapter;\n}\n\nconst BUILTIN_PLUGINS: MiokuPlugin[] = [...DEFAULT_BUILTIN_PLUGINS];\n\nexport const setBuiltinPlugins = (plugins: readonly MiokuPlugin[]): void => {\n BUILTIN_PLUGINS.length = 0;\n BUILTIN_PLUGINS.push(...plugins);\n};\n\nexport const getBuiltinPlugins = (): readonly MiokuPlugin[] => BUILTIN_PLUGINS;\n\nexport class MiokuRuntime {\n readonly #cwd: string;\n readonly #logger: Logger;\n readonly #bus: EventBus;\n readonly #bots: BotRegistry;\n readonly #capabilities: CapabilityRegistry;\n readonly #driver: Driver;\n readonly #adapterStates = new Map<string, RuntimeAdapterState>();\n readonly #enabledAdapters = new Map<string, AdapterDefinition<unknown>>();\n readonly #enabledPlugins = new Map<\n string,\n { cleanup: PluginCleanup | null; plugin: MiokuPlugin }\n >();\n readonly #driverFactory: () => Driver;\n readonly #builtinPlugins: readonly MiokuPlugin[];\n readonly #crossDedup: CrossAdapterMessageDeduplicator | null;\n #started = false;\n #stopped = false;\n\n constructor(options: CreateRuntimeOptions) {\n this.#cwd = path.resolve(options.cwd);\n this.#logger = options.logger;\n this.#driverFactory =\n options.driverFactory ?? (() => createDefaultDriver());\n this.#builtinPlugins = options.builtinPlugins ?? BUILTIN_PLUGINS;\n this.#driver = this.#driverFactory();\n this.#bus = new EventBus();\n this.#bus.setLogger((level, message, detail) => {\n const fn = this.#logger[level] ?? this.#logger.error;\n if (detail === undefined) fn(message);\n else fn(message, detail);\n });\n this.#bots = new BotRegistry();\n this.#capabilities = new CapabilityRegistry();\n this.#crossDedup =\n options.dedup?.crossAdapter === false\n ? null\n : new CrossAdapterMessageDeduplicator();\n }\n\n get cwd(): string {\n return this.#cwd;\n }\n\n get logger(): Logger {\n return this.#logger;\n }\n\n get driver(): Driver {\n return this.#driver;\n }\n\n get bus(): EventBus {\n return this.#bus;\n }\n\n get bots(): readonly Bot[] {\n return this.#bots.all();\n }\n\n get adapters(): readonly Adapter[] {\n return Array.from(this.#adapterStates.values())\n .map((state) => state.instance)\n .filter((a): a is Adapter => a != null);\n }\n\n getAdapter<T extends Adapter = Adapter>(name: string): T | undefined {\n const state = this.#adapterStates.get(name);\n return state?.instance as T | undefined;\n }\n\n pickBot<T extends Bot = Bot>(bot_id: string | number): T | undefined {\n return this.#bots.pick<T>(bot_id);\n }\n\n listPlugins(): Array<{\n name: string;\n type: \"builtin\" | \"external\";\n version?: string;\n }> {\n return Array.from(this.#enabledPlugins.entries()).map(([key, entry]) => {\n const colon = key.indexOf(\":\");\n const type = key.slice(0, colon);\n const name = key.slice(colon + 1);\n return {\n name,\n type: type === \"builtin\" ? \"builtin\" : \"external\",\n version: entry.plugin.version,\n };\n });\n }\n\n async enablePlugin(name: string): Promise<void> {\n const isEnabled =\n this.#enabledPlugins.has(`external:${name}`) ||\n this.#enabledPlugins.has(`builtin:${name}`);\n if (isEnabled) throw new Error(`插件 ${name} 已经是启用状态`);\n const appPkg = this.#readAppPackageJson();\n const jiti = createImportContext(this.#cwd);\n const local = findLocalPlugins(\n this.#cwd,\n botConfig.plugins_dir ?? \"plugins\",\n ).find((p) => p.name === name);\n if (local) {\n const pkg = readPackageJsonSafe(local.absPath) ?? {};\n const plugin = await loadLocalPlugin(jiti, name, local.absPath);\n await this.#loadPlugin(plugin, \"external\");\n setPluginMetadata(buildPluginMetadata(name, local.absPath, pkg));\n return;\n }\n const candidates = discoverPluginCandidates(this.#cwd, appPkg);\n const candidate = candidates.find((c) => c.name === name);\n if (candidate) {\n const plugin = await loadNpmPlugin(jiti, candidate);\n await this.#loadPlugin(plugin, \"external\");\n setPluginMetadata(\n buildPluginMetadata(\n candidate.name,\n candidate.resolvedPath,\n candidate.packageJson,\n ),\n );\n return;\n }\n throw new Error(`插件 ${name} 不存在`);\n }\n\n async disablePlugin(name: string): Promise<void> {\n const key = `external:${name}`;\n const entry = this.#enabledPlugins.get(key);\n if (!entry) {\n if (this.#enabledPlugins.has(`builtin:${name}`))\n throw new Error(`内置插件 ${name} 无法禁用`);\n throw new Error(`插件 ${name} 不存在或未启用`);\n }\n try {\n await entry.cleanup?.();\n } finally {\n this.#enabledPlugins.delete(key);\n removePluginMetadata(name);\n }\n this.#logger.info(`禁用插件 => ${name}`);\n }\n\n async reloadPlugin(name: string): Promise<void> {\n const wasExternal = this.#enabledPlugins.has(`external:${name}`);\n const wasBuiltin = this.#enabledPlugins.has(`builtin:${name}`);\n if (!wasExternal && !wasBuiltin) {\n await this.enablePlugin(name);\n return;\n }\n if (wasBuiltin) {\n const plugin = this.#builtinPlugins.find((p) => p.name === name);\n if (!plugin) throw new Error(`内置插件 ${name} 不存在`);\n await this.#enabledPlugins.get(`builtin:${name}`)?.cleanup?.();\n this.#enabledPlugins.delete(`builtin:${name}`);\n await this.#loadPlugin(plugin, \"builtin\");\n return;\n }\n await this.disablePlugin(name);\n await this.enablePlugin(name);\n }\n\n async #emitLifecycle(event: BotLifecycleEvent): Promise<void> {\n const lifecycleEvent: Event = {\n kind: \"adapter\",\n type: event.type,\n routes: [event.type],\n identity: {\n adapter: event.bot.adapter,\n bot_id: event.bot.bot_id,\n event_type: event.type,\n },\n bot: event.bot,\n self_id: event.bot.bot_id,\n time: Date.now(),\n raw: event,\n payload: event,\n };\n await this.#bus.dispatch(lifecycleEvent);\n }\n\n #createContext(state: RuntimeAdapterState): AdapterContextImpl {\n return new AdapterContextImpl({\n state,\n bots: this.#bots,\n bus: this.#bus,\n driver: this.#driver,\n capabilities: this.#capabilities,\n logger: this.#logger.child({ adapter: state.definition.name }),\n emit: (event) => this.#emitLifecycle(event),\n crossDedup: this.#crossDedup,\n });\n }\n\n async #loadPlugin(\n plugin: MiokuPlugin,\n type: \"builtin\" | \"external\",\n ): Promise<void> {\n const cleanupTasks: PluginCleanup[] = [];\n const ctx = new MiokuContext({\n pluginName: `${type}:${plugin.name}`,\n bus: this.#bus,\n bots: this.#bots,\n driver: this.#driver,\n capabilities: this.#capabilities,\n config: botConfig,\n logger: this.#logger.child({ plugin: plugin.name }),\n priority: plugin.priority ?? 100,\n getAdapter: <T extends Adapter = Adapter>(name: string) =>\n this.getAdapter<T>(name),\n listAdapters: () => this.adapters,\n onUpdateConfig: async (updater) => {\n await updateMiokuConfig(updater);\n },\n pluginManager: {\n list: () => this.listPlugins(),\n localPlugins: () =>\n findLocalPlugins(this.#cwd, botConfig.plugins_dir ?? \"plugins\").map(\n (p) => p.name,\n ),\n enable: (name) => this.enablePlugin(name),\n disable: (name) => this.disablePlugin(name),\n reload: (name) => this.reloadPlugin(name),\n },\n });\n cleanupTasks.push(() => ctx.dispose());\n\n let cleanup: PluginCleanup | null = null;\n try {\n const result = await plugin.setup?.(ctx);\n cleanup = typeof result === \"function\" ? result : null;\n } catch (err) {\n await ctx.dispose();\n throw new Error(\n `Plugin \"${plugin.name}\" setup failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (typeof cleanup === \"function\") cleanupTasks.push(cleanup);\n const wrappedCleanup: PluginCleanup = async () => {\n for (const fn of cleanupTasks) {\n try {\n await fn();\n } catch (err) {\n this.#logger.warn(\n `Plugin \"${plugin.name}\" cleanup error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n };\n this.#enabledPlugins.set(`${type}:${plugin.name}`, {\n cleanup: wrappedCleanup,\n plugin,\n });\n }\n\n async #setupBuiltinPlugins(): Promise<void> {\n this.#logger.info(\n `>>> 加载内置插件: ${this.#builtinPlugins.map((p) => colors.cyan(p.name)).join(\", \")}`,\n );\n for (const plugin of this.#builtinPlugins) {\n try {\n await this.#loadPlugin(plugin, \"builtin\");\n } catch (err) {\n this.#logger.error(err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n async #discoverAdapters(): Promise<void> {\n const appPkg = this.#readAppPackageJson();\n const candidates = discoverAdapterCandidates(this.#cwd, appPkg);\n const enabledNames = Object.keys(botConfig.adapters ?? {}) as string[];\n const candidateByName = new Map(\n candidates.map((candidate) => [candidate.name, candidate]),\n );\n const jiti = createImportContext(this.#cwd);\n for (const name of enabledNames) {\n const candidate = candidateByName.get(name);\n if (!candidate) {\n this.#logger.error(\n `适配器 \"${name}\" 已配置但未安装或不在项目直接依赖中,已跳过`,\n );\n continue;\n }\n try {\n const loaded = await loadAdapterDefinition(jiti, candidate);\n this.#enabledAdapters.set(name, loaded.definition);\n } catch (err) {\n this.#logger.error(\n `适配器 \"${name}\" 加载失败,已跳过: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n #readAppPackageJson(): import(\"../loader/package\").PackageJson {\n const file = `${this.#cwd}/package.json`;\n if (!fs.existsSync(file)) {\n throw new Error(`无法在 ${this.#cwd} 下找到 package.json`);\n }\n return JSON.parse(\n fs.readFileSync(file, \"utf-8\"),\n ) as import(\"../loader/package\").PackageJson;\n }\n\n async #setupPlugins(): Promise<void> {\n const startTime = hrtime.bigint();\n await this.#setupBuiltinPlugins();\n\n const appPkg = this.#readAppPackageJson();\n const enabledIds = new Set<string>(botConfig.plugins.map(String));\n if (enabledIds.size === 0) {\n await this.#logPluginSummary(startTime);\n return;\n }\n\n const candidates = discoverPluginCandidates(this.#cwd, appPkg);\n const candidateByName = new Map<string, PluginCandidate>(\n candidates.map((c) => [c.name, c]),\n );\n\n const localDir = botConfig.plugins_dir ?? \"plugins\";\n const localPlugins = findLocalPlugins(this.#cwd, localDir);\n\n const failed: Array<{ name: string; error: string }> = [];\n const jiti = createImportContext(this.#cwd);\n const tasks: Array<{\n name: string;\n priority: number;\n run: () => Promise<void>;\n }> = [];\n\n for (const id of enabledIds) {\n const npmCandidate = candidateByName.get(id);\n if (npmCandidate) {\n setPluginMetadata(\n buildPluginMetadata(\n npmCandidate.name,\n npmCandidate.resolvedPath,\n npmCandidate.packageJson,\n ),\n );\n try {\n const plugin = await loadNpmPlugin(jiti, npmCandidate);\n tasks.push({\n name: id,\n priority: plugin.priority ?? npmCandidate.priority ?? 100,\n run: async () => {\n await this.#loadPlugin(plugin, \"external\");\n },\n });\n } catch (err) {\n failed.push({\n name: id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n continue;\n }\n const local = localPlugins.find((p) => p.name === id);\n if (!local) {\n failed.push({\n name: id,\n error: `插件 \"${id}\" 未找到(既不在依赖中,也不在本地插件目录中)`,\n });\n continue;\n }\n setPluginMetadata(\n buildPluginMetadata(\n id,\n local.absPath,\n readPackageJsonSafe(local.absPath) ?? {},\n ),\n );\n try {\n const plugin = await loadLocalPlugin(jiti, id, local.absPath);\n tasks.push({\n name: id,\n priority: plugin.priority ?? 100,\n run: async () => {\n await this.#loadPlugin(plugin, \"external\");\n },\n });\n } catch (err) {\n failed.push({\n name: id,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n const priorityGroups = new Map<number, typeof tasks>();\n for (const task of tasks) {\n const group = priorityGroups.get(task.priority) ?? [];\n group.push(task);\n priorityGroups.set(task.priority, group);\n }\n const priorities = Array.from(priorityGroups.keys()).sort((a, b) => a - b);\n if (priorities.length > 0) {\n this.#logger.info(\n `>>> 加载用户插件: ${priorities\n .map(\n (priority) =>\n `优先级 ${colors.yellow(priority)} (${(priorityGroups.get(priority) ?? []).map((t) => colors.cyan(t.name)).join(\", \")})`,\n )\n .join(\",\")}`,\n );\n }\n for (const priority of priorities) {\n const group = priorityGroups.get(priority) ?? [];\n await Promise.allSettled(group.map((t) => t.run()));\n }\n\n if (failed.length > 0) {\n const summary = failed.map((f) => ` - ${f.name}: ${f.error}`).join(\"\\n\");\n this.#logger.warn(`以下插件加载失败:\\n${summary}`);\n for (const f of failed) removePluginMetadata(f.name);\n }\n\n await this.#logPluginSummary(startTime);\n }\n\n async #logPluginSummary(startTime: bigint): Promise<void> {\n const end = hrtime.bigint();\n const cost = Math.round(Number(end - startTime)) / 1_000_000;\n const enabledCount = this.#enabledPlugins.size;\n this.#logger.info(\n `成功加载了 ${colors.green(enabledCount)} 个插件,总耗时 ${colors.green(cost.toFixed(2))} 毫秒`,\n );\n }\n\n async #startAdapter(name: string): Promise<Adapter> {\n const definition = this.#enabledAdapters.get(name);\n if (!definition) {\n throw new Error(`Adapter \"${name}\" is not enabled`);\n }\n const rawConfig = (botConfig.adapters ?? {})[name];\n let config: unknown = rawConfig;\n if (definition.validateConfig) {\n try {\n config = definition.validateConfig(rawConfig);\n } catch (err) {\n throw new Error(\n `Adapter \"${name}\" config validation failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n const state: RuntimeAdapterState = {\n definition,\n instance: null,\n context: null,\n gateways: [],\n resources: [],\n started: false,\n };\n this.#adapterStates.set(name, state);\n const context = this.#createContext(state);\n state.context = context;\n const adapterLogger = this.#logger.child({ adapter: name });\n let instance: Adapter;\n try {\n const result = definition.create({ config, logger: adapterLogger });\n instance = result instanceof Promise ? await result : result;\n } catch (err) {\n this.#adapterStates.delete(name);\n throw new Error(\n `Adapter \"${name}\" failed to construct: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n state.instance = instance;\n try {\n await instance.start(context);\n await context.waitForStarts();\n state.started = true;\n } catch (err) {\n state.started = false;\n this.#adapterStates.delete(name);\n try {\n await instance.stop(\"startup failed\");\n } catch {\n // ignore\n }\n throw new Error(\n `Adapter \"${name}\" failed to start: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return instance;\n }\n\n async start(): Promise<void> {\n if (this.#started) {\n throw new Error(\"Runtime already started\");\n }\n this.#started = true;\n await this.#discoverAdapters();\n await this.#setupPlugins();\n const adapterNames = Array.from(this.#enabledAdapters.keys());\n const failed: string[] = [];\n for (const name of adapterNames) {\n try {\n const adapter = await this.#startAdapter(name);\n await this.#bus.dispatch({\n kind: \"adapter\",\n type: \"adapter:started\",\n routes: [\"adapter:started\"],\n identity: { adapter: name, event_type: \"adapter:started\" },\n time: Date.now(),\n payload: { name },\n });\n } catch (err) {\n this.#logger.error(\n `适配器 \"${name}\" 启动失败: ${err instanceof Error ? err.message : String(err)}`,\n );\n failed.push(name);\n }\n }\n if (failed.length > 0) {\n this.#logger.warn(\n `以下适配器启动失败,框架将继续运行: ${failed.join(\", \")}`,\n );\n }\n await this.#bus.dispatch({\n kind: \"adapter\",\n type: \"runtime:ready\",\n routes: [\"runtime:ready\"],\n identity: { adapter: \"\" as string, event_type: \"runtime:ready\" },\n time: Date.now(),\n payload: undefined,\n });\n }\n\n async shutdown(reason?: string): Promise<void> {\n if (this.#stopped) return;\n this.#stopped = true;\n await this.#bus.dispatch({\n kind: \"adapter\",\n type: \"runtime:shutdown\",\n routes: [\"runtime:shutdown\"],\n identity: { adapter: \"\" as string, event_type: \"runtime:shutdown\" },\n time: Date.now(),\n payload: reason ? { reason } : undefined,\n });\n const adapters = Array.from(this.#adapterStates.values());\n for (let i = adapters.length - 1; i >= 0; i--) {\n const state = adapters[i];\n if (!state.instance) continue;\n try {\n await state.instance.stop(reason ?? \"shutdown\");\n } catch (err) {\n this.#logger.warn(\n `Adapter \"${state.definition.name}\" stop failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (state.resources) {\n for (let r = state.resources.length - 1; r >= 0; r--) {\n try {\n await state.resources[r].dispose(reason ?? \"shutdown\");\n } catch (err) {\n this.#logger.warn(\n `Resource \"${state.resources[r].name}\" dispose failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n state.resources.length = 0;\n }\n if (state.gateways) {\n for (let g = state.gateways.length - 1; g >= 0; g--) {\n try {\n await state.gateways[g].stop(reason ?? \"shutdown\");\n } catch (err) {\n this.#logger.warn(\n `Gateway \"${state.gateways[g].name}\" stop failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n state.gateways.length = 0;\n }\n }\n for (const [, entry] of this.#enabledPlugins) {\n try {\n await entry.cleanup?.();\n } catch (err) {\n this.#logger.warn(\n `Plugin cleanup failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n this.#enabledPlugins.clear();\n this.#capabilities.clear();\n this.#bots.clear();\n resetPluginMetadata();\n try {\n await this.#driver.shutdown();\n } catch (err) {\n if (!(err instanceof DriverShutdownError)) {\n this.#logger.warn(\n `Driver shutdown error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n}\n\nexport const createRuntime = (options: CreateRuntimeOptions): MiokuRuntime => {\n setBotCwd(options.cwd);\n reloadMiokuConfig();\n return new MiokuRuntime(options);\n};\n\nexport { definePlugin };\n","import type { MiokuContext } from \"./mioku-context\";\nimport { getService } from \"../services/define\";\nimport { Services } from \"../services\";\nimport { servicesRegistry } from \"../services\";\nimport { rootLogger as logger } from \"../logger\";\nimport { getPluginMetadataList } from \"./plugin-metadata\";\nimport type { HelpService } from \"../types\";\n\nexport async function registerPluginArtifacts(\n ctx?: MiokuContext,\n): Promise<void> {\n const helpService = ctx\n ? getService(ctx, Services.Help)\n : (servicesRegistry[\"help\"] as HelpService | undefined);\n const plugins = getPluginMetadataList();\n\n let helpCount = 0;\n for (const meta of plugins) {\n if (meta.config?.help) {\n if (helpService) {\n helpService.registerHelp(meta.name, meta.config.help);\n helpCount++;\n } else {\n logger.warn(\n `[plugin-artifacts] 帮助服务未加载,跳过插件 \"${meta.name}\" 的帮助注册`,\n );\n }\n }\n const required = meta.config?.services;\n if (required && required.length > 0) {\n const missing = required.filter((name) => !servicesRegistry[name]);\n if (missing.length > 0) {\n logger.warn(\n `插件 \"${meta.name}\" 声明依赖服务 [${missing.join(\", \")}],但它们未加载`,\n );\n }\n }\n }\n\n logger.info(\n `[plugin-artifacts] 已处理 ${plugins.length} 个插件的元数据,注册帮助 ${helpCount} 个`,\n );\n}\n","import path from \"node:path\";\nimport { createRuntime, setBuiltinPlugins } from \"./runtime/runtime\";\nimport { createMiokuLogger, rootLogger } from \"./logger\";\nimport { setWritableConfig, botConfig, setBotCwd } from \"./config\";\nimport { version } from \"../package.json\";\nimport { getBuiltinPlugins } from \"./runtime/runtime\";\nimport { unique } from \"./utils\";\nimport { BUILTIN_PLUGINS } from \"./builtin\";\nimport serviceManager from \"./services/manager\";\nimport { registerPluginArtifacts } from \"./runtime/plugin-artifacts\";\nimport { colors } from \"consola/utils\";\n\nimport type { MiokuPlugin } from \"./plugin\";\nimport type { Logger } from \"./logger\";\n\n/** startRuntime 的启动选项 */\nexport interface StartOptions {\n cwd?: string;\n logger?: Logger;\n builtinPlugins?: readonly MiokuPlugin[];\n}\n\n/** 启动 mioku 运行时:加载服务、拉起适配器与插件,返回用于优雅停机的 stop */\nexport const startRuntime = async (\n options: StartOptions = {},\n): Promise<{ stop: (reason?: string) => Promise<void> }> => {\n const cwd = options.cwd ?? process.cwd();\n setBotCwd(cwd);\n setWritableConfig(true);\n\n const builtinPlugins = options.builtinPlugins ?? BUILTIN_PLUGINS;\n setBuiltinPlugins(builtinPlugins);\n const logger = options.logger ?? rootLogger;\n\n process.title = `mioku v${version}`;\n\n const runtime = createRuntime({\n cwd,\n logger,\n builtinPlugins: getBuiltinPlugins(),\n dedup: { crossAdapter: botConfig.dedup?.cross_adapter ?? true },\n });\n\n const pluginDir = path.resolve(cwd, botConfig.plugins_dir ?? \"plugins\");\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(\n `欢迎使用 ${colors.bold(colors.redBright(\"mioku\"))} 💓 ${colors.bold(colors.cyan(`v${version}`))}`,\n );\n logger.info(colors.yellow(colors.underline(\"一个跨平台的插件式机器人框架\")));\n logger.info(colors.cyan(\"轻量 * 跨平台 * 插件式 * 热重载 * 注重开发体验\"));\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(colors.dim(colors.italic(\"作者: Viki & Jerryplusy\")));\n logger.info(\n colors.dim(colors.italic(\"仓库: https://github.com/mioku-lab/mioku\")),\n );\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(`${colors.dim(\"工作目录: \")}${colors.blue(cwd)}`);\n logger.info(`${colors.dim(\"插件目录: \")}${colors.blue(pluginDir)}`);\n logger.info(\n `${colors.dim(\"配置文件: \")}${colors.blue(path.resolve(cwd, \"package.json\"))}`,\n );\n logger.info(\n `${colors.dim(\"启用插件: \")}${colors.blue(unique(botConfig.plugins).join(\", \") || \"(空)\")}`,\n );\n logger.info(\n `${colors.dim(\"适配器: \")}${colors.blue(Object.keys(botConfig.adapters ?? {}).join(\", \") || \"(无, zero-adapter 模式)\")}`,\n );\n logger.info(colors.dim(\"=\".repeat(40)));\n\n await serviceManager.loadAllServices();\n await runtime.start();\n await registerPluginArtifacts();\n\n const bots = runtime.bots;\n if (bots.length > 0) {\n logger.info(\n `成功连接 ${bots.length} 个实例: ${bots.map((b) => b.bot_id).join(\", \")}`,\n );\n }\n logger.info(colors.dim(\"=\".repeat(40)));\n logger.info(\n `mioku v${version} 启动完成,向机器人发送「${colors.magentaBright(`${botConfig.prefix}help`)}」查看消息指令`,\n );\n\n if (botConfig.online_push && botConfig.owners[0]) {\n const bot = runtime.bots[0];\n if (bot) {\n try {\n await bot.sendMessage(\n { type: \"private\", user_id: botConfig.owners[0] },\n `✅ mioku v${version} 已就绪`,\n );\n } catch (err) {\n logger.warn(\"发送就绪通知失败\", err);\n }\n }\n }\n return {\n stop: async (reason?: string) => {\n await runtime.shutdown(reason);\n await serviceManager.disposeAll();\n },\n };\n};\n","// Mioku framework types — single source of truth for the public API surface.\n\n// ---------- framework ----------\n\n/** 框架服务的最小形态:init 负责初始化,api 是对外暴露的接口对象 */\nexport interface MiokuService {\n name: string;\n version: string;\n description?: string;\n init(): Promise<void>;\n api: Record<string, any>;\n dispose?(): Promise<void>;\n}\n\n/** package.json 的 `mioku` 字段中控制框架行为的运行时配置 */\nexport interface MiokuRuntimeConfig {\n plugins?: string[];\n plugins_dir?: string;\n services_dir?: string;\n [key: string]: unknown;\n}\n\n/** 宽松的 package.json 结构,用于读取插件的元信息 */\nexport interface PackageJsonLike {\n name?: string;\n version?: string;\n description?: string;\n keywords?: readonly string[];\n mioku?: unknown;\n dependencies?: Record<string, string>;\n}\n\n/** 已加载插件的元信息,供内置 core 插件与帮助系统使用 */\nexport interface PluginMetadata {\n name: string;\n version: string;\n description?: string;\n path: string;\n packageJson: PackageJsonLike;\n config: PluginPackageConfig;\n}\n\n/** 已发现服务的元信息 */\nexport interface ServiceMetadata {\n name: string;\n version: string;\n description?: string;\n path: string;\n packageJson: PackageJsonLike;\n}\n\n// ---------- plugin package config ----------\n\n/** 插件 package.json 中 `mioku` 字段的解析结果 */\nexport interface PluginPackageConfig {\n /** 插件依赖的服务名,如 `ai`、`config` */\n services?: string[];\n help?: PluginHelp;\n accessHooks?: AccessHook[];\n}\n\n/** 插件的帮助信息,框架会自动收集并注册到帮助服务 */\nexport interface PluginHelp {\n title: string;\n description: string;\n commands: Array<{\n cmd: string;\n desc: string;\n usage?: string;\n role?: CommandRole;\n }>;\n}\n\nexport type CommandRole = \"master\" | \"admin\" | \"owner\" | \"member\";\n\n/**\n * - `\"master\"`:仅 bot 主人可触发\n * - `\"owner\"`:legacy alias\n * - `\"admin\"`:bot 主人或管理员\n * - `\"member\"`:群内任意成员\n *\n */\nexport type SkillPermissionRole = \"master\" | \"owner\" | \"admin\" | \"member\";\n\nexport function normalizeSkillPermissionRole(\n role: unknown,\n): SkillPermissionRole {\n const normalized = String(role ?? \"\")\n .trim()\n .toLowerCase();\n if (\n normalized === \"master\" ||\n normalized === \"owner\" ||\n normalized === \"admin\" ||\n normalized === \"member\"\n ) {\n return normalized as SkillPermissionRole;\n }\n return \"member\";\n}\n\nexport interface AccessHook {\n id: string;\n /** 匹配文本的正则(字符串形式,如 `/^\\.help$/`),用于在事件层面拦截/放行 */\n match?: string;\n /** 命中的事件路由,如 `notice.group.poke` */\n event?: string;\n description?: string;\n}\n\nexport type AccessAction = \"allow\" | \"block\";\n\nexport interface AccessRuleEntry {\n action: AccessAction;\n}\n\nexport interface AccessScopeConfig {\n plugins?: Record<string, AccessRuleEntry>;\n commands?: Record<string, Record<string, AccessRuleEntry>>;\n}\n\n/** 访问控制配置:按全局 / 群 / 用户三级对插件与指令放行或拦截 */\nexport interface AccessControlConfig {\n version: 1;\n global: AccessScopeConfig;\n groups: Record<string, AccessScopeConfig>;\n users: Record<string, AccessScopeConfig>;\n}\n\n// ---------- built-in service contracts ----------\n\n/** 配置服务:插件的配置文件统一注册、读取与热更新 */\nexport interface ConfigService {\n registerConfig(\n pluginName: string,\n configName: string,\n initialConfig: any,\n ): Promise<boolean>;\n updateConfig(\n pluginName: string,\n configName: string,\n updates: any,\n ): Promise<boolean>;\n getConfig(pluginName: string, configName: string): Promise<any>;\n getPluginConfigs(pluginName: string): Promise<Record<string, any>>;\n /** 订阅配置变化,返回取消订阅函数 */\n onConfigChange(\n pluginName: string,\n configName: string,\n callback: (newConfig: any) => void,\n ): () => void;\n}\n\n/** 截图服务:把 HTML / Markdown / URL 渲染成图片 */\nexport interface ScreenshotService {\n screenshot(html: string, options?: any): Promise<string>;\n screenshotMarkdown(markdownContent: string, options?: any): Promise<string>;\n screenshotFromUrl(url: string, options?: any): Promise<string>;\n cleanupTemp(olderThanMs?: number): Promise<number>;\n}\n\n/** 帮助服务:插件的帮助信息注册与查询 */\nexport interface HelpService {\n registerHelp(pluginName: string, help: PluginHelp): void;\n getHelp(pluginName: string): PluginHelp | undefined;\n getAllHelp(): Map<string, PluginHelp>;\n unregisterHelp(pluginName: string): boolean;\n}\n\nexport interface WebUIService {\n getSettings(): { port: number; host: string; packageManager: string };\n}\n\n// ---------- AI service ----------\n\n/** AI 工具:暴露给模型的函数,供模型在对话中调用 */\nexport interface AITool {\n name: string;\n description: string;\n parameters: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n handler: (args: any, event?: any) => Promise<any> | any;\n}\n\n/** AI 技能:一组工具的组合,可按权限开放给不同角色的用户 */\nexport interface AISkill {\n name: string;\n description: string;\n permission?: SkillPermissionRole;\n tools: AITool[];\n}\n\nexport interface TextMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string;\n}\n\n/** 多模态消息内容:文本或图片 URL */\nexport interface MultimodalContentItem {\n type: \"text\" | \"image_url\";\n text?: string;\n image_url?: {\n url: string;\n detail?: \"auto\" | \"low\" | \"high\";\n };\n}\n\nexport interface MultimodalMessage {\n role: \"system\" | \"user\" | \"assistant\";\n content: string | MultimodalContentItem[];\n}\n\n/** 一次工具调用的记录(名称、参数与结果) */\nexport interface ToolCallRecord {\n name: string;\n arguments: any;\n result: any;\n}\n\nexport interface SessionToolDefinition {\n name: string;\n tool: AITool;\n}\n\n/** 模型补全请求的完整选项 */\nexport interface CompleteOptions {\n model?: string;\n messages: any[];\n temperature?: number;\n max_tokens?: number;\n stream?: boolean;\n tools?: any[];\n /** 会话内可执行的工具(自动进入工具循环) */\n executableTools?: SessionToolDefinition[];\n executableToolsProvider?: () => SessionToolDefinition[];\n maxIterations?: number;\n onTextDelta?: (delta: string) => void | Promise<void>;\n usageContext?: AIUsageContext;\n usageContextTokens?: number;\n usageBreakdown?: AIUsageFinalization[\"breakdown\"];\n}\n\nexport interface CompleteResponse {\n content: string | null;\n reasoning: string | null;\n toolCalls: Array<{ id: string; name: string; arguments: string }>;\n raw: any;\n turnMessages: any[];\n iterations?: number;\n allToolCalls?: ToolCallRecord[];\n}\n\nexport type AIProtocol =\n | \"openai-chat\"\n | \"openai-response\"\n | \"anthropic\"\n | \"gemini\";\n\n/** 模型能力标记:文本 / 视觉 / 工具调用 / 推理 */\nexport type AIModelCapability = \"text\" | \"vision\" | \"tool-use\" | \"reasoning\";\n\n/** 思考等级,部分推理模型支持从 off 到 max 逐级调节 */\nexport type AIThinkingLevel =\n | \"off\"\n | \"low\"\n | \"medium\"\n | \"high\"\n | \"xhigh\"\n | \"max\";\n\nexport const AI_THINKING_LEVELS: AIThinkingLevel[] = [\n \"off\",\n \"low\",\n \"medium\",\n \"high\",\n \"xhigh\",\n \"max\",\n];\n\nexport const AI_GEMINI_THINKING_LEVELS: AIThinkingLevel[] = [\n \"off\",\n \"low\",\n \"medium\",\n \"high\",\n];\n\nexport function normalizeAIThinkingLevel(\n value: unknown,\n protocol?: AIProtocol,\n): AIThinkingLevel | undefined {\n const raw = String(value ?? \"\")\n .trim()\n .toLowerCase() as AIThinkingLevel;\n if (!raw) return undefined;\n if (protocol === \"gemini\") {\n return AI_GEMINI_THINKING_LEVELS.includes(raw) ? raw : undefined;\n }\n return AI_THINKING_LEVELS.includes(raw) ? raw : undefined;\n}\n\n/** 模型角色:主对话 / 干活 / 看图 */\nexport type AIModelRole = \"main\" | \"working\" | \"vision\";\n\n/** 一个模型提供商的连接配置 */\nexport interface AIProviderConfig {\n id: string;\n name: string;\n protocol: AIProtocol;\n apiUrl: string;\n apiKey: string;\n enabled: boolean;\n headers?: Record<string, string>;\n}\n\n/** 模型描述:归属于某个提供商,带能力与上下文窗口信息 */\nexport interface AIModelDescriptor {\n id: string;\n providerId: string;\n modelId: string;\n name: string;\n capabilities: AIModelCapability[];\n contextWindow?: number;\n maxOutputTokens?: number;\n isCustom?: boolean;\n thinkingLevel?: AIThinkingLevel;\n}\n\nexport interface AIInstanceInfo {\n name: string;\n providerId: string;\n modelId: string;\n role?: AIModelRole;\n}\n\n/** AI 实例:一个绑定到具体提供商与模型的调用句柄 */\nexport interface AIInstance {\n generateText(options: {\n prompt?: string;\n messages: TextMessage[];\n model?: string;\n temperature?: number;\n max_tokens?: number;\n }): Promise<string>;\n generateMultimodal(options: {\n prompt?: string;\n messages: MultimodalMessage[];\n model?: string;\n temperature?: number;\n max_tokens?: number;\n }): Promise<string>;\n complete(options: CompleteOptions): Promise<CompleteResponse>;\n generateWithTools(options: {\n prompt?: string;\n messages: TextMessage[] | MultimodalMessage[];\n model?: string;\n temperature?: number;\n maxIterations?: number;\n }): Promise<any>;\n setUsageContext?(context: AIUsageContext | undefined): void;\n withUsageContext?<T>(\n context: AIUsageContext | undefined,\n fn: () => Promise<T>,\n ): Promise<T>;\n registerPrompt(name: string, prompt: string): boolean;\n getPrompt(name: string): string | undefined;\n getAllPrompts(): Record<string, string>;\n removePrompt(name: string): boolean;\n}\n\n/** AI 服务:实例 / 提供商 / 模型 / 技能的统一管理入口 */\nexport interface AIService {\n create(options: {\n name: string;\n apiUrl: string;\n apiKey: string;\n modelType: \"text\" | \"multimodal\";\n model?: string;\n }): Promise<AIInstance>;\n createInstance?(options: {\n name: string;\n providerId: string;\n modelId: string;\n role?: AIModelRole;\n }): Promise<AIInstance>;\n get(name: string): AIInstance | undefined;\n list(): string[];\n listInstances?(): AIInstanceInfo[];\n remove(name: string): boolean;\n setDefault(name: string): boolean;\n getDefault(): AIInstance | undefined;\n listProviders?(): AIProviderConfig[];\n getProvider?(id: string): AIProviderConfig | undefined;\n createProvider?(\n input: Omit<AIProviderConfig, \"id\"> & { id?: string },\n ): Promise<AIProviderConfig>;\n updateProvider?(\n id: string,\n input: Partial<AIProviderConfig>,\n ): Promise<AIProviderConfig>;\n removeProvider?(id: string): boolean;\n testProvider?(\n id: string,\n ): Promise<{ ok: boolean; error?: string; models?: AIModelDescriptor[] }>;\n listModels?(providerId?: string): AIModelDescriptor[];\n refreshModels?(providerId: string): Promise<AIModelDescriptor[]>;\n registerCustomModel?(input: {\n providerId: string;\n modelId: string;\n name?: string;\n capabilities?: AIModelCapability[];\n }): AIModelDescriptor;\n removeCustomModel?(modelFullId: string): boolean;\n removeModel?(modelFullId: string): boolean;\n setModelThinkingLevel?(\n modelFullId: string,\n level: AIThinkingLevel | undefined,\n ): boolean;\n getRoleBindings?(): Record<AIModelRole, string | undefined>;\n setRoleBinding?(role: AIModelRole, modelFullId: string | undefined): boolean;\n getInstanceByRole?(role: AIModelRole): AIInstance | undefined;\n setMainFallbackChain?(modelFullIds: string[]): void;\n getMainFallbackChain?(): string[];\n registerChatRuntime(runtime: any): boolean;\n getChatRuntime(): any;\n removeChatRuntime(): boolean;\n registerSkill(skill: AISkill): boolean;\n getSkill(skillName: string): AISkill | undefined;\n getAllSkills(): Map<string, AISkill>;\n removeSkill(skillName: string): boolean;\n getTool(toolName: string): AITool | undefined;\n getAllTools(): Map<string, AITool>;\n getUsageSummary?(options: {\n range: AIUsageRange;\n botId?: number;\n }): AIUsageSummary;\n cleanupUsageStats?(retentionMs?: number): number;\n finalizeUsage?(usageId: string, finalization: AIUsageFinalization): boolean;\n}\n\n// ---------- chat runtime ----------\n\n/** 聊天运行时:让插件复用 chat 插件的\"发通知 / 收集信息\"能力 */\nexport interface ChatRuntime {\n generateNotice(options: ChatRuntimeNoticeOptions): Promise<ChatRuntimeResult>;\n requestInformation(\n options: ChatRuntimeInformationRequestOptions,\n ): Promise<ChatRuntimeResult>;\n}\n\nexport const TOOL_RESULT_FOLLOWUP_KEY = \"__miokuFollowup\";\n\n/** 工具结果附带的内容:文本与图片/视频引用 */\nexport interface ToolResultFollowup {\n text: string;\n images?: Array<{ url: string; detail?: \"auto\" | \"low\" | \"high\" }>;\n videos?: Array<{ url: string; detail?: \"auto\" | \"low\" | \"high\" }>;\n}\n\nexport interface ChatRuntimePromptInjection {\n content: string;\n title?: string;\n}\n\nexport interface ChatRuntimeGroupTarget {\n selfId: number;\n groupId: number;\n}\n\nexport interface ChatRuntimePrivateTarget {\n selfId: number;\n userId: number;\n}\n\nexport type ChatRuntimeSource =\n | { event: any }\n | ChatRuntimeGroupTarget\n | ChatRuntimePrivateTarget;\n\nexport type ChatRuntimeBaseOptions = ChatRuntimeSource & {\n targetMessage?: string;\n promptInjections?: ChatRuntimePromptInjection[];\n send?: boolean;\n};\n\nexport type ChatRuntimeNoticeOptions = ChatRuntimeBaseOptions & {\n instruction: string;\n};\n\n/** 让 AI 按给定 JSON Schema 收集并返回结构化信息 */\nexport type ChatRuntimeInformationRequestOptions = ChatRuntimeBaseOptions & {\n task: string;\n schema: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n toolName?: string;\n toolDescription?: string;\n};\n\nexport interface ChatRuntimeCollectedInfo {\n data: any;\n isComplete?: boolean;\n confidence?: number;\n notes?: string;\n}\n\nexport interface ChatRuntimeResult {\n messages: string[];\n toolCalls: ToolCallRecord[];\n collectedInfo: ChatRuntimeCollectedInfo | null;\n pendingAt?: number[];\n pendingPoke?: number[];\n pendingQuote?: number;\n emojiPath?: string | null;\n protocolMessages?: any[];\n}\n\n// ---------- usage tracking ----------\n\nexport type AIUsageRange = \"today\" | \"7d\" | \"30d\";\n\nexport type AIUsageScope = \"all\" | \"bot\";\n\nexport interface AIUsageContext {\n usageId?: string;\n source?: string;\n botId?: number;\n groupId?: number;\n groupName?: string;\n userId?: number;\n userName?: string;\n sessionId?: string;\n fallbackUsed?: boolean;\n fallbackFrom?: string;\n}\n\nexport interface AIUsageBreakdown {\n systemPromptTokens?: number;\n chatHistoryTokens?: number;\n toolDefinitionTokens?: number;\n toolUseTokens?: number;\n otherContextTokens?: number;\n}\n\nexport interface AIUsageFinalization {\n sentUserMessages?: number;\n sentAssistantMessages?: number;\n breakdown?: AIUsageBreakdown;\n}\n\nexport interface AIUsageBotOption {\n botId: number;\n label: string;\n}\n\nexport interface AIUsageSummary {\n generatedAt: number;\n range: AIUsageRange;\n scope: AIUsageScope;\n botId?: number;\n bots: AIUsageBotOption[];\n totals: {\n requests: number;\n successfulRequests: number;\n failedRequests: number;\n userMessages: number;\n assistantMessages: number;\n systemMessages: number;\n toolMessages: number;\n sentUserMessages: number;\n sentAssistantMessages: number;\n inputTokens: number;\n outputTokens: number;\n systemPromptTokens: number;\n totalTokens: number;\n cacheWriteTokens: number;\n cacheReadTokens: number;\n toolDefinitionTokens: number;\n toolUseTokens: number;\n chatHistoryTokens: number;\n otherContextTokens: number;\n durationMs: number;\n toolCalls: number;\n };\n rates: {\n throughputTokPerMin: number;\n averageTokensPerUserMessage: number;\n averageTokensPerSentMessage: number;\n errorRate: number;\n cacheHitRate: number;\n };\n toolRanking: Array<{ name: string; count: number }>;\n groupRanking: Array<{\n groupId: number;\n groupName: string;\n requests: number;\n totalTokens: number;\n userMessages: number;\n assistantMessages: number;\n errorRate: number;\n }>;\n tokenFlow: Array<{\n name: \"输入\" | \"输出\" | \"缓存写入\" | \"缓存读取\";\n value: number;\n }>;\n tokenCategories: Array<{\n name: \"系统提示词\" | \"工具定义\" | \"工具使用\" | \"聊天上下文\" | \"其他上下文\";\n value: number;\n }>;\n dailyActivity: Array<{\n day: string;\n requests: number;\n userMessages: number;\n assistantMessages: number;\n totalTokens: number;\n inputTokens: number;\n cacheReadTokens: number;\n throughputTokPerMin: number;\n averageTokensPerUserMessage: number;\n averageTokensPerSentMessage: number;\n errorRate: number;\n cacheHitRate: number;\n }>;\n hourlyActivity: Array<{\n hour: string;\n requests: number;\n userMessages: number;\n assistantMessages: number;\n totalTokens: number;\n inputTokens: number;\n cacheReadTokens: number;\n throughputTokPerMin: number;\n averageTokensPerUserMessage: number;\n averageTokensPerSentMessage: number;\n errorRate: number;\n cacheHitRate: number;\n }>;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { startRuntime as startMiokuRuntime } from \"./start\";\nimport { rootLogger } from \"./logger\";\nimport serviceManager from \"./services/manager\";\nimport { readMiokuConfig } from \"./config\";\n\nimport type { Logger } from \"./logger\";\nimport type { MiokuPlugin } from \"./plugin/plugin\";\n\nexport type { MiokuPlugin, MiokuContext } from \"./plugin/plugin\";\nexport type { EventMap } from \"napcat-sdk\";\n\nexport { definePlugin } from \"./plugin/plugin\";\n\nexport * from \"./logger\";\nexport { rootLogger as logger } from \"./logger\";\nexport * from \"./driver\";\nexport * from \"./adapter\";\nexport * from \"./capabilities\";\nexport * from \"./runtime/bus\";\nexport * from \"./runtime/bots\";\nexport * from \"./runtime/context\";\nexport * from \"./runtime/lifecycle\";\nexport * from \"./runtime/mioku-context\";\nexport * from \"./runtime/runtime\";\nexport * from \"./runtime/types\";\nexport * from \"./loader\";\nexport * from \"./plugin/plugin\";\nexport * from \"./utils\";\nexport * from \"./actions\";\nexport * from \"./services/registry\";\nexport * from \"./services/define\";\nexport * from \"./services/builtin\";\nexport * from \"./services/manager\";\nexport * from \"./services/config\";\nexport * from \"./config\";\nexport * from \"./start\";\nexport * from \"./builtin\";\nexport * from \"./builtin/core/status\";\nexport * from \"./builtin/core/adapters\";\nexport * from \"./compat\";\n\nexport { default as serviceManager } from \"./services/manager\";\nexport { registerPluginArtifacts } from \"./runtime/plugin-artifacts\";\nexport * from \"./runtime/plugin-metadata\";\n\nexport {\n registerServiceConfig,\n getServiceConfig,\n updateServiceConfig,\n getServiceConfigs,\n deleteServiceConfig,\n} from \"./services/config\";\n\nexport type {\n MiokuService,\n MiokuRuntimeConfig,\n PackageJsonLike,\n PluginMetadata,\n ServiceMetadata,\n PluginPackageConfig,\n PluginHelp,\n CommandRole,\n AccessHook,\n AccessAction,\n AccessRuleEntry,\n AccessScopeConfig,\n AccessControlConfig,\n ConfigService,\n ScreenshotService,\n HelpService,\n WebUIService,\n AITool,\n AISkill,\n AIInstance,\n AIService,\n AIProtocol,\n AIModelCapability,\n AIThinkingLevel,\n AIModelRole,\n AIProviderConfig,\n AIModelDescriptor,\n AIInstanceInfo,\n ChatRuntime,\n TextMessage,\n MultimodalMessage,\n ToolCallRecord,\n CompleteOptions,\n CompleteResponse,\n SessionToolDefinition,\n SkillPermissionRole,\n MultimodalContentItem,\n ToolResultFollowup,\n ChatRuntimePromptInjection,\n ChatRuntimeGroupTarget,\n ChatRuntimePrivateTarget,\n ChatRuntimeSource,\n ChatRuntimeBaseOptions,\n ChatRuntimeNoticeOptions,\n ChatRuntimeInformationRequestOptions,\n ChatRuntimeCollectedInfo,\n ChatRuntimeResult,\n AIUsageRange,\n AIUsageScope,\n AIUsageBotOption,\n AIUsageContext,\n AIUsageBreakdown,\n AIUsageFinalization,\n AIUsageSummary,\n} from \"./types\";\n\nexport {\n TOOL_RESULT_FOLLOWUP_KEY,\n normalizeSkillPermissionRole,\n AI_THINKING_LEVELS,\n AI_GEMINI_THINKING_LEVELS,\n normalizeAIThinkingLevel,\n} from \"./types\";\n\nexport {\n defineService,\n getService,\n requireService,\n hasService,\n} from \"./services/define\";\nexport type { ServiceRef } from \"./services/define\";\nexport { Services } from \"./services/builtin\";\nexport type { BuiltinServiceRef } from \"./services/builtin\";\n\nexport interface MiokuStartOptions {\n cwd?: string;\n logger?: Logger;\n builtinPlugins?: readonly MiokuPlugin[];\n}\n\nexport async function start(\n options: MiokuStartOptions = {},\n): Promise<{ stop: (reason?: string) => Promise<void> }> {\n const { cwd = process.cwd() } = options;\n if (cwd) process.chdir(cwd);\n\n rootLogger.info(\"こんにちは..\");\n rootLogger.info(\"---------------------------------------\");\n rootLogger.info(\"---------- Mioku 正在启动 ------------\");\n rootLogger.info(\"---------------------------------------\");\n\n let miokuConfig: import(\"./types\").MiokuRuntimeConfig = {};\n try {\n const cfg = readMiokuConfig();\n miokuConfig = cfg as unknown as import(\"./types\").MiokuRuntimeConfig;\n } catch {\n miokuConfig = {};\n }\n rootLogger.info(\"o.O Miku 正在翻找服务..\");\n await serviceManager.discoverServices(miokuConfig);\n\n const { stop: stopRuntime } = await startMiokuRuntime({\n cwd,\n logger: options.logger,\n builtinPlugins: options.builtinPlugins,\n });\n\n let shuttingDown = false;\n const shutdown = async (signal: string): Promise<void> => {\n if (shuttingDown) return;\n shuttingDown = true;\n rootLogger.info(`收到 ${signal} 信号,正在关闭服务...`);\n const timer = setTimeout(() => {\n rootLogger.error(\"服务关闭超时,强制退出\");\n process.exit(1);\n }, 15_000);\n timer.unref();\n try {\n await stopRuntime(signal);\n } finally {\n clearTimeout(timer);\n }\n rootLogger.info(\"Mioku 服务已完全关闭\");\n process.exit(0);\n };\n\n process.on(\"SIGINT\", () => void shutdown(\"SIGINT\"));\n process.on(\"SIGTERM\", () => void shutdown(\"SIGTERM\"));\n\n return {\n stop: (reason) => stopRuntime(reason),\n };\n}\n\nfunction readVersion(): string {\n try {\n const here = path.dirname(fileURLToPath(import.meta.url));\n const pkgPath = path.join(here, \"..\", \"package.json\");\n return JSON.parse(fs.readFileSync(pkgPath, \"utf-8\")).version ?? \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nexport const version: string = readVersion();\n\nexport {\n getDataDir,\n getPluginDataDir,\n getServiceDataDir,\n getConfigDir,\n getPluginConfigDir,\n getServiceConfigDir,\n ensureDataDir,\n} from \"./internal/data-paths\";\n\nexport {\n defineState,\n hasPluginState,\n getPluginRuntimeState,\n setPluginRuntimeState,\n resetPluginRuntimeState,\n getAllPluginRuntimeStates,\n} from \"./runtime/plugin-state\";\nexport type { PluginStateRef } from \"./runtime/plugin-state\";\n\nexport {\n resolveCommand,\n commandExists,\n buildSpawnPlan,\n runCommand,\n runCommandInherit,\n} from \"./internal/exec\";\nexport type { RunCommandResult, SpawnPlan } from \"./internal/exec\";"],"mappings":"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"}