Repository navigation
v0.5.5
MusePi 0.5.5
| Platform | 下载 |
|---|---|
| macOS (Apple Silicon) | MusePi-0.5.5-arm64.dmg |
| Windows | MusePi-0.5.5-setup.exe · MusePi-0.5.5-arm64-setup.exe |
| Linux x64 | MusePi-0.5.5-x86_64.AppImage · MusePi-0.5.5-amd64.deb |
| Linux arm64 | MusePi-0.5.5-arm64.AppImage · MusePi-0.5.5-arm64.deb |
| Android | MusePi-0.5.5-app-debug.apk (debug build, adb 安装) |
[0.5.5] - 2026-10-13
Added
-
Auth Hub 的模型选择器显示积分倍率:CodeBuddy 与 Qoder 的每个模型名后面直接标出消耗倍率(如 Deepseek-V4.1-Flash · x0.11、Sonus · x8),有促销的显示为原价→促销价,倍率为零的显示「免费」,无倍率信息的模型保持原名——选模型时消耗一目了然,不用再查文档。OpenCode 的免费模型也标出「免费」(匿名通道可用的那批)。
- EN: The Auth Hub model selector shows credit multipliers. Every CodeBuddy and Qoder model carries its rate right in the name (Deepseek-V4.1-Flash · x0.11, Sonus · x8), promotions render as base→promo, zero-rate models read 免费 (free), and models without rate info keep their plain name — the cost of a pick is visible at selection time instead of a doc lookup. OpenCode's free models are marked 免费 too (the batch the anonymous key serves).
-
Auth Hub 的九个渠道全部接入完成:ZCode(智谱)与 CodeArts(华为云)最后两家落地。ZCode 走 plan anthropic 协议(推理档位按上游配置走 output_config.effort),CodeArts 走华为云 HMAC 签名的 OpenAI 兼容端点(benefit 模型的 maas_type 头参与签名、账号无 benefit 包时自动去掉重试一次、SSE 里的业务错误会被识别为真实错误而非空回复)。两家当前回复的都是账号状态类错误(额度/并发/token 过期)——协议本身已被服务端全量接受,等账号状态恢复即可直接出对话。
- EN: All nine Auth Hub channels are now wired. ZCode (Zhipu) and CodeArts (Huawei Cloud) complete the set. ZCode runs the plan anthropic protocol (effort levels ride output_config.effort per the upstream config); CodeArts runs the Huawei HMAC-signed OpenAI-compatible endpoint (the benefit models' maas_type header participates in the signature, an account without a benefit package auto-retries once without it, and business errors inside the SSE stream surface as real errors instead of empty replies). Both currently answer with account-state errors (quota / concurrency / expired token) — the protocols themselves are fully accepted server-side, so real conversations start the moment the accounts recover.
-
退出 MusePi 前会提醒还在运行的会话:此前点退出会直接关闭——正在运行的智能体任务被静默中断,用户往往事后才发现。现在有会话在运行时退出会先弹确认(提示有几个会话正在运行、退出会中断它们),选择留在应用则什么都不会发生;没有会话在跑时退出依旧无声。
- EN: Quitting MusePi now warns about sessions that are still running. Quit used to close immediately — running agent tasks were silently interrupted and users only found out afterwards. With sessions active, quitting first asks for confirmation (how many are running, and that quitting interrupts them); choosing to stay aborts the quit entirely. With nothing running, quitting stays silent.
-
Auth Hub 的 Gemini 中国版与 WorkBuddy 渠道补全:Qoder 中国版加密推理实测通过(同一协议、中国端点与客户端标识);WorkBuddy(国际版)全链路接入——登录(登录 URL 携带版本与会话参数)、模型目录(9 个实测模型)、真实对话(要求首条消息必须是 system 提示,缺失时自动补一条;思考型模型的输出预算要给思考留出空间,实测 50 token 全被思考吃掉、500 才出正文)。模型选择器三个新渠道全部可用。
- EN: Auth Hub completes its Qoder China and WorkBuddy channels. Qoder China's encrypted inference verified live (same protocol, the China endpoint and client identity); WorkBuddy International lands end to end — sign-in (the login URL carries version and session params), a nine-model measured catalog, and real chat (the first message must be a system prompt and one is added automatically when missing; thinking models need an output budget that leaves room — at 50 tokens the thinking ate it all, 500 produced the reply). All three channels are live in the model selector.
-
Auth Hub 的 Qoder 渠道也能真正对话(含中国版):Qoder 的真实推理走加密端点——请求体由客户端自带的 WASM 模块加密(直接调用它,等同“用客户端自己的钥匙开自己的锁”),模型目录里的真名(qfmodel / dmodel 等)只有这条端点认。三个只有实测才能钉住的形状均已固化:business 字段缺失会把请求路由到故障节点(报错误导性的 Execution failed)、Authorization 头是 WASM 生成的签名令牌(用原始 token 覆盖会 403)、SSE 帧是双层包裹(外层信封的 body 字段里才是真正的 JSON 块)。Qoder 与中国版共享同一协议、各自的端点与客户端标识。
- EN: Auth Hub's Qoder channels (international and China) can now really chat. Qoder's real inference runs on an ENCRYPTED endpoint — the request body is encrypted by the client binary's own WASM module, invoked directly ("opening the client's lock with the client's own key"), because only that endpoint accepts the catalog's real model keys (qfmodel / dmodel and the rest). Three shapes only live measurement could pin are locked in: a missing business field routes the request to a broken backend node (a misleading Execution failed), the Authorization header is a WASM-minted signature token (overwriting it with the raw token is a 403), and the SSE frames are double-wrapped (the real JSON chunk lives in the envelope's body field).
-
Auth Hub 的 Gemini 渠道也能真正对话:模型选择器选 Gemini 模型发消息即走 Code Assist 真实推理(antigravity 客户端身份、字母序信封、思考预算按档位)。三处只有实测才能拿到的形状均已钉住:模型名必须带档位后缀(裸名 404)、流式请求刻意不带 Accept 头、includeThoughts 恒开(关闭思考是假关——照样思考照样计费)。
- EN: Auth Hub's Gemini channel can now really chat. Picking a Gemini model and sending a message runs real Code Assist inference (the antigravity client identity, the alphabetically-marshalled envelope, per-tier thinking budgets). Three shapes that only live-measurement could pin are locked in: the model name must carry its tier suffix (the bare name answers 404), streaming deliberately omits the Accept header, and includeThoughts is always on — "off" still thinks and still bills.
-
Auth Hub 的 MiniMax 渠道也能真正对话:模型选择器选 MiniMax 模型发消息即走真实推理(Anthropic 协议、思考块完整呈现、用量真实计数)。思考形态按模型决策表处理——M3.1 强制自适应思考(缺失会被服务端 400 拒绝),M2.7 系交由服务端默认,档位真实下发。402 余额不足原样透出,充值是唯一有效动作。
- EN: Auth Hub's MiniMax channel can now really chat. Picking a MiniMax model and sending a message runs real inference over the Anthropic protocol, with thinking blocks rendered in full and usage counted for real. The thinking shape follows the per-model decision table — M3.1 forces adaptive thinking (missing it is a server-side 400), the M2.7 family defers to the server default, and effort levels are actually sent. A 402 balance-exhausted answer surfaces verbatim; topping up is the only real action.
-
Auth Hub 的 CodeBuddy 渠道也能真正对话:模型选择器选 CodeBuddy 模型发消息即走真实推理(带完整的用量归因头族,控制台按产品正确归因)。多账号自动轮转——额度用尽的账号被透明跳过、自动换下一个账号完成本轮对话(实测:池内第一个账号 429 额度用尽,第二个账号直接接手返回正常回复),用户全程只看到一次成功的回合。
- EN: Auth Hub's CodeBuddy channel can now really chat. Picking a CodeBuddy model in the selector and sending a message runs real inference (with the complete usage-attribution header family, so the console attributes it to the product correctly). Multiple accounts rotate automatically — a quota-exhausted account is skipped transparently and the next one finishes the turn (verified live: the first pool account answered 429 with its quota spent, the second took over and returned a normal reply), and the user sees exactly one successful turn.
-
Auth Hub 的模型开始可以真正对话:OpenCode 渠道接入完整的对话传输——模型选择器里选 OpenCode 模型发消息,请求经官方 CLI 同款的客户端形状(会话标识、指纹头、代理工具)流式往返,免费模型无需任何账号即可使用。这是账号池走向可用推理的第一条通道;其余渠道(CodeBuddy / MiniMax / Qoder / Gemini)按同一网关逐家接通。
- EN: Auth Hub models can now actually chat. The OpenCode channel carries the full chat transport — picking an OpenCode model in the selector and sending a message streams through the official CLI's exact client shape (session id, fingerprint headers, stub tools), with the free models usable without any account at all. This is the first live lane from the account pool to real inference; the remaining channels (CodeBuddy / MiniMax / Qoder / Gemini) light up through the same gateway one by one.
-
Auth Hub 新增 Gemini 与 OpenCode 渠道:Gemini 走 Google 标准 OAuth(授权完成自动回跳,本地回调口随机端口,无需手动粘贴任何代码);OpenCode 免登录——匿名通道开箱即用(无需任何账号即可使用免费模型),付费 key 导入后解锁全部模型。OpenCode 的免费通道有严格的客户端形状校验(会话标识、指纹头、代理工具注入三要素缺一即被拒),已全部按官方 CLI 的真实形态实现并实测通过。
- EN: Auth Hub gains Gemini and OpenCode channels. Gemini runs Google's standard OAuth — finish the authorization in the browser and the local callback completes it (random loopback port, nothing to paste). OpenCode needs no sign-in at all: the anonymous lane works out of the box for free models, and an imported paid key unlocks the full catalog. OpenCode's free lane enforces a strict client shape (session id, fingerprint headers, and injected stub tools — any one missing is rejected), all implemented in the official CLI's exact form and verified live.
-
Auth Hub 新增 Qoder 与 Qoder 中国版渠道:面板再添两个登录入口——打开 Qoder 授权页完成登录即可(PKCE 设备流全流程,含「等待授权」与连续网络失败的容错)。两渠道各自持正确的客户端标识与端点(混用会让授权页报参数无效),登录后账号入池,模型选择器出现 Qoder 全系模型(Auto / Ultimate / Sonus / Qwen3.8 系 / Kimi-K3 / GLM-5.3 / DeepSeek-V4 等 17 个,实测目录)。
- EN: Auth Hub gains Qoder and Qoder China channels. The panel adds two more sign-in entries — finish the authorization in the browser and the account lands in the pool (the full PKCE device flow, tolerant of the waiting state and of transient network failures). Each channel carries its own client id and endpoints (mixing them fails the authorization page with invalid-parameters), and after sign-in the model selector lists the whole Qoder catalog — Auto / Ultimate / Sonus / Qwen3.8 family / Kimi-K3 / GLM-5.3 / DeepSeek-V4 and the rest, seventeen measured entries.
-
Auth Hub 新增 MiniMax 渠道:设备码登录与真实模型清单:面板新增「添加 MiniMax 账号」——打开 MiniMax 授权页并内联输入设备码即可完成登录(设备码 + PKCE 全流程,等待中与过期、取消都有明确提示)。登录或导入的 MiniMax 账号驱动真实的模型发现:模型选择器出现 MiniMax-M3.1-Flash-Preview / M3 / M2.7-highspeed / M2.7(远端目录下发顺序),令牌过期自动静默续期。
- EN: Auth Hub gains a MiniMax channel: device-code sign-in and a real model list. The panel adds "Add MiniMax account" — it opens the MiniMax authorization page with an inline device-code step (the full device-code + PKCE flow, with clear pending, expired, and denied states). Signed-in or imported MiniMax accounts drive real model discovery: the selector lists MiniMax-M3.1-Flash-Preview / M3 / M2.7-highspeed / M2.7 in the remote catalog's own order, and an expired token silently refreshes itself.
-
Auth Hub 可以一键迁移 DSH 里的现有账号:账号池界面新增「从 DSH 导入账号」——读取本机 DSH 安装的凭据库与账号索引,把 CodeBuddy、MiniMax、Qoder、ZCode、CodeArts、Gemini、OpenCode 等全部渠道的已有账号(连同刷新令牌与有效期)直接迁入账号池,无需逐个重新登录。无法迁移的账号(凭据缺失)会逐条说明原因,不会静默丢弃。
- EN: Auth Hub can migrate existing accounts from DSH in one click. The pool UI gains an "Import from DSH" entry — it reads the local DSH install's credential store and account index and brings every existing account across all channels (CodeBuddy, MiniMax, Qoder, ZCode, CodeArts, Gemini, OpenCode and the rest, with refresh tokens and expiry) straight into the pool, no per-account re-login. Accounts that cannot migrate (missing credentials) are each explained, never silently dropped.
-
Auth Hub 面板可以直接添加账号了:账号池界面新增「添加 CodeBuddy 账号」入口——点击后打开真实的 CodeBuddy 授权页,浏览器完成登录后账号与凭据自动进入账号池和宿主凭据库,模型选择器随之出现 CodeBuddy 的真实模型清单。登录中会显示授权链接、说明与取消按钮,需要输入的环节内联完成,全程不用离开面板。
- EN: The Auth Hub panel can now add accounts directly. The account pool UI gains an "Add CodeBuddy account" entry — clicking it opens the real CodeBuddy authorization page, and once you finish in the browser the account and its credentials land in both the pool and the host credential store, after which the model selector lists CodeBuddy's real models. While signing in, the panel shows the authorization link, instructions, and a cancel button; any input step completes inline, all without leaving the panel.
-
Auth Hub 可以直接登录 CodeBuddy 账号了:登录不再需要粘贴任何代码——点击登录会打开真实的 CodeBuddy 授权页,浏览器完成登录后账号(含昵称、真实凭据)自动进入多账号池,最长等待 5 分钟。模型选择器在登录后即可见到 CodeBuddy 提供的真实模型清单。
- EN: Auth Hub now signs in to CodeBuddy directly. Login no longer asks you to paste anything — clicking login opens the real CodeBuddy authorization page, and once you finish in the browser the account (with its nickname and real credentials) lands in the pool automatically, with a 5-minute wait limit. The model selector lists CodeBuddy's real model catalog after login.
-
Auth Hub 的模型清单换成真实可用模型:auth-hub 供应商的模型清单此前是单个占位条目——模型选择器里搜不到任何真实模型。现在模型的发现走活跃账号的 token 请求 CodeBuddy 的 /v3/config:craft 白名单为对话模型权威(白名单外的条目剔除——上游对它们返回 service info not found,列出来只会让人选中后报错),请求失败时回退到经真实请求验证过的内置清单并附可读原因。其余供应商(MiniMax / Qoder / ZCode 等)按同一模板逐家接入。
- EN: Auth Hub's model discovery now talks to a real upstream (CodeBuddy first). The provider's model list was previously a single placeholder entry pointing at a placeholder endpoint — no real model was searchable in the selector. Discovery now uses the active account's token to request CodeBuddy's /v3/config: the craft whitelist is the chat-model authority (entries outside it are dropped — the upstream answers service info not found for them, so listing them only lets a person pick a model that then errors), and a failed request falls back to a verified built-in list with a readable reason. The remaining providers (MiniMax / Qoder / ZCode and the rest) land one by one on the same template.
-
插件可以贡献自己的魔术关键词:新增
pi.registerMagicKeyword,扩展能注册一个输入框里的触发词(提交时向模型追加一条隐藏提示),与内置三个关键词同规则:小写散文边界匹配(不会在deepdive.ts、行内代码或deepdiving这类更长的词里误触发),开关走magicKeywords.<词>设置键,没人配置时默认停用。仓库内附完整可运行样板examples/plugin-magic-keyword(关键词 + 自带设置面板 + 后台方法一套)。- EN: Plugins can contribute their own magic keyword.
pi.registerMagicKeywordlets an extension register a composer trigger word that appends a hidden notice to the model on submit, under the same contract as the three built-in keywords: lowercase prose-delimited matching (sodeepdive.ts, inline code, and longer words likedeepdivingnever trigger it), gated by amagicKeywords.<word>setting that defaults to off when nobody configured it. A complete runnable sample ships in the repo atexamples/plugin-magic-keyword(keyword plus its own settings panel and daemon method).
- EN: Plugins can contribute their own magic keyword.
-
插件设置表单有了防覆盖与「恢复默认」能力:插件自带设置界面过去只有一个裸的读写接口,写多了会互相覆盖、也分不清某个值是用户改的还是继承清单默认值。现在提供带版本栅栏的设置表单——基于旧值发起的写入会被拒绝(界面能明确知道「这次编辑输了」而不是静默覆盖别人的改动),并区分清单默认值与用户层:键的存在即代表用户改过,因此可以逐项恢复默认。
- EN: Plugin settings forms gained lost-update protection and a per-field reset. A plugin's own settings UI previously had only a bare read/write proxy, so concurrent edits clobbered each other and there was no way to tell a user-set value from an inherited manifest default. Forms now carry a revision fence — a write issued from a stale read is refused, so an editor can say "this edit lost" instead of silently overwriting a newer one — and separate the manifest base from the user layer: a key's presence marks a user override, so any field can be reset to inherit.
-
插件组合里的条件行现在真的按条件生效:补丁里
!!js标记的表达式(例如只在某个系统启用某一行)过去一律不求值、永久显示为「未知」,组合模型对这类行等于失效。现在按参考实现的做法求值(with (ctx)),条件行会算出真实的启停;表达式算不出来时该行如实标为「未知」并给出原因,不会因为求值出错就当成启用。profile 的覆盖依旧优先于 bundle 的条件。- EN: Conditional rows in a plugin composition now actually take effect. Expressions tagged
!!jsin a patch (enabling a row only on a given platform, say) were previously never evaluated and stayed permanently "unknown", which made the composition model inert for exactly those rows. They are now evaluated the way the reference loader does (with (ctx)), so a conditional row resolves to a real enablement; when an expression cannot be computed the row is reported as unknown with the reason, and is never treated as enabled just because evaluation went wrong. A profile's override still outranks a bundle's condition.
- EN: Conditional rows in a plugin composition now actually take effect. Expressions tagged
-
插件组合升级后即可发现与使用:升级到带组合模型的版本时,若当前 profile 还没有组合清单,会在它旁边写一份可直接编辑的骨架(bundle 列表 + profile 自有 patch 的注释示例),只补缺失文件、绝不覆盖你已有的声明或 patch;组合视图因此不再是「空页面 + 不知道要填什么字段」。此外组合出的扩展入口会随行的启停重新装载,勾上即生效。
- EN: Plugin compositions are discoverable and usable right after upgrading. When an upgraded installation's profile declares no composition, a directly editable skeleton is written beside it (the bundle list plus a commented example of the profile's own patch), creating only missing files and never overwriting a declaration or patch you already have — so the composition view is no longer an empty page asking for a field nobody would know to write. Composed extension entries are also re-loaded when a row is toggled, so enabling a row takes effect immediately.
-
插件可以整包分发、逐条启停(DSH bundle/profile 组合模型):新增 profile/bundle 组合面——profile 清单声明自己叠了哪些 bundle,bundle 的
cordis.patch.yml插入若干行,profile 自己的 patch 可按行 id 覆盖某一行(配置整体替换,因此也能删掉 bundle 设的键)。行的启停写进 profile 自己的 patch 文件,与 DSH 同款写法;重新组合后回报组合的真实状态,而不是回报请求。「整包安装却什么都没贡献」的失败模式现在可见:缺失的插件、条件启停(!!js表达式本宿主不求值,明确标为未知而不是猜一个启停)、缺失的 bundle 都如实报出。- EN: Plugins can now ship as bundles and be toggled row by row (DSH's profile/bundle composition model). A profile manifest declares the bundles it stacks, a bundle's cordis.patch.yml inserts rows, and the profile's own patch can override one row by id (the config is replaced wholesale, so a profile can also remove a key the bundle set). Toggling a row writes into the profile's own patch file, the same write DSH performs, and the answer reported is the recomposed state rather than the request. The failure mode of "installed a bundle and it contributes nothing" is now visible: a missing plugin, a conditional enablement (a !!js expression this host does not evaluate, reported as unknown rather than guessed either way) and a bundle that is not installed are all reported as they are.
-
插件面板不再加载失败,官方插件也都有图标了:插件自带的设置面板原先一律报「模块加载失败」——界面在组件还在下载时就回收了它的地址;现在加载完成后才释放。同时每个插件项都画出了自己的标识(插件声明的图标、内置单元的类别图标,或按包名生成的彩色字母标),状态改为标识角上的小圆点,不再和图标挤在一起。
- EN: Plugin panels no longer fail to load, and official plugins have icons too. A plugin's own settings panel always reported "module failed to load" — the UI released its address while the download was still in flight; it now waits for the load to finish. Every plugin also draws its own mark (a declared icon, a built-in unit's kind glyph, or a colored letter tile derived from the package name), and status moved to a corner badge instead of crowding the icon.
-
插件详情弹窗补齐:点击已安装插件打开详情弹窗——大图标、版本、状态与启用开关、头部卸载按钮;插件自带的组件收进弹窗「包含的组件」逐项开关(不再与插件包重复占列表行),插件的设置界面(如账号池管理)也挂载在弹窗内。
- EN: The plugin detail dialog completes the picture. Clicking an installed plugin opens a dialog with the large icon, version, status, enable toggle and an uninstall button in the header; the plugin's own modules collapse into per-item included-component toggles (no longer duplicated as separate list rows), and its settings surface (an account pool, for example) mounts inside the dialog.
-
插件列表支持一键卸载:已安装插件卡片和列表行新增卸载按钮,确认后由守护进程移除插件目录并即时刷新列表;卸载失败时错误横幅提示且列表保持不变。
- EN: One-click uninstall in the plugin list. Installed plugin cards and rows gain an uninstall button; after a confirmation the daemon removes the plugin directory and refreshes the list immediately, and a failed uninstall shows an error banner while leaving the list untouched.
-
插件图标可自定义:插件可在清单里声明
icon(emoji、字符或图片 URL),列表立即采用;未声明时按包名生成确定的彩色字母标,同包同名同色。- EN: Customizable plugin icons. A plugin can declare
iconin its manifest (emoji, glyph, or an image URL) and the list adopts it; without one, a deterministic colored letter mark is derived from the package name — same package, same mark.
- EN: Customizable plugin icons. A plugin can declare
Fixed
-
启动等待期间也能拖动窗口:冷启动时守护进程要预热数秒,界面停在全屏的启动动画上——此前这块区域不参与窗口拖拽,想把它挪到一边只能等加载完。现在启动画面的空白处可直接拖动窗口,重试按钮照常点击不受影响。
- EN: The window can be dragged while startup is in flight. On a cold start the daemon prewarms for a few seconds and the interface sits on the full-screen splash — that area previously did not participate in window dragging, so moving it aside meant waiting for the load to finish. The splash now drags the window directly, and the retry button still clicks normally.
-
会话启动恢复到正常速度:随产品分发的内置插件包(魔术关键词三件套)此前走了为第三方插件设计的源码图装载管线——那条管线会遍历插件整个 import 图逐文件读盘分析,而内置包引用宿主自身模块,图里有几千个文件,导致每次会话装配多花约两分钟。内置包与宿主同仓库同版本、整体随版本更新,不需要逐文件快照,现在直接走原生模块加载(毫秒级)。
- EN: Session startup is back to normal speed. The bundled plugin package that ships with the product (the magic-keyword trio) went through the source-graph loading pipeline designed for third-party plugins — a file-by-file walk of the package's entire import graph, which for a package importing host modules means thousands of files read and parsed per load, adding roughly two minutes to every session assembly. Bundled packages share the host's repo and version and are replaced as a whole on upgrade, so they never needed the per-file snapshot; they now load through a plain native module import in milliseconds.
-
插件贡献的模型在扩展重载后即时出现在模型选择器:扩展注册的供应商模型此前只在会话创建时进模型目录——扩展热重载后目录已更新,但会话内的模型选择器只认 models.changed 事件,永远停在旧列表,插件新增的模型要重进会话才可见。现在扩展重载广播同时扇出 models.changed,选择器同帧刷新。
- EN: Models contributed by a plugin now appear in the model selector right after an extension reload. Extension-registered provider models only entered the catalog at session creation — after a hot reload the catalog updated, but the in-session selector listens only for models.changed and kept the stale list, so a plugin's new models required re-entering the session. The extension-reload broadcast now fans out models.changed too, and the selector refreshes in the same frame.
-
第三方插件面板真正挂载得出来(渲染端 CSP 修复):插件自带的面板此前一律报「组件加载失败 — TypeError: Failed to fetch dynamically imported module: blob:…」——页面安全策略只允许脚本来自本页与内联,而扩展组件恰恰是以 blob 模块动态导入的;第一个用
settings.extensions槽位的第三方插件(如 musepi-auth-hub 的账号池面板)首当其冲。现在script-src放行 blob:(仍然拒绝 eval),并用契约测试钉住这条安全边界。- EN: Third-party plugin panels now actually mount (renderer CSP fix). A plugin's own panel always failed with "component failed to load — TypeError: Failed to fetch dynamically imported module: blob:…" — the page's security policy only allowed page and inline scripts, while extension components are precisely blob-imported modules; the first third-party plugin using the settings.extensions slot (musepi-auth-hub's account pool, for example) hit it head-on. script-src now admits blob: (eval stays refused), with a contract test pinning that boundary.
-
插件启用开关反映真实装载结果:拨动开关此前只代表"已写入启用意图"——守护进程写完锁文件就返回成功,从不回读插件是否真的装载;装载失败的插件在界面上照样显示"已启用",什么都没跑起来。现在启用后守护进程重新装载该插件的扩展条目并回报真实结果:装载失败时开关不再翻转、错误横幅给出原因。
- EN: The plugin enable toggle now reflects the real load outcome. Toggling previously only meant "the enable intent was written" — the daemon returned success right after persisting the lockfile, never re-reading whether the plugin actually loads; a plugin whose load fails showed "enabled" in the UI while nothing registered. The daemon now re-loads the plugin's extension entries after enabling and reports the real outcome: on load failure the toggle does not flip and an error banner gives the reason.
-
第三方插件包与内置插件单元在列表里形态一致:插件包(如 musepi-auth-hub)此前渲染成只有包名、没有归属组件也进不去设置的裸行。现在插件包与内置单元共用同一套条目布局(图标 + 名称 + 来源/版本标签 + 描述 + 右侧开关,整行可点开详情),且包与其扩展模块的归属判定改用路径相对计算——不再依赖两侧拼写出同一个分隔符,也不会把只共享前缀的同级包误判成子模块。
- EN: Third-party plugin packages and built-in plugin units now share one row layout. A package (musepi-auth-hub, for example) previously rendered as a bare row carrying only its name, with no attributed components and no way into its settings. Packages and built-in units now use the same row (icon + name + source/version tag + description + trailing toggle, the whole row opening details), and package-to-module attribution compares paths relatively instead of assuming both sides spell the separator the same way — a sibling that merely shares a prefix is no longer mistaken for a child.
-
供应商列表折叠展开不再卡死:快速来回点「显示全部 / 折叠」时,上一次的展开动画还没结束新的就开始,网格会冻在半展开的高度(卡片被裁掉一截)。现在每次展开/收起都先清掉上一次动画残留的锁定,被打断的动画立即恢复正常布局。
- EN: The provider list no longer freezes mid-collapse. Clicking 显示全部/折叠 in quick succession started a new expansion before the old one settled, leaving the grid stuck at a half-open height with cards clipped. Every toggle now clears the previous animation's leftover lock first, and an interrupted animation restores natural layout immediately.
-
专注模式切换不再先跳后长:会话里切专注模式时,输入框原先先整块跳到更高的底边再开始长高——顺序是反的;同时高度动画被两套过渡同时驱动,帧数明显不够。现在动画从你切换前的真实位置出发,上下两条边一起沿曲线走到目标位置(正是"按上下边距比例放大"的观感),且整个窗口期只由一条曲线驱动;输入框聚焦时光束会在形变期间定格,不再叠加逐帧重绘。
- EN: Focus-mode toggle no longer jumps before it grows. The composer used to leap to its final position first and only then grow — the order was backwards — while two competing height transitions fought per frame and dropped the frame rate. The animation now starts from the composer's true pre-toggle position and carries both edges along one curve to the target (the proportional "grows along the margins" read), a single curve drives the whole window, and a focused beam freezes for the morph instead of repainting per frame on top of it.
-
空态输入框飞向会话态不再卡顿:输入框边缘的彩色旋转光束会在欢迎页与会话页之间的位移动画里逐帧重绘,叠在位移本身的缩放+模糊动画上就是卡顿感的来源。现在位移进行时光束定格、落地后恢复,空态发送消息的那一刻光束也立即熄灭,不再陪跑到场景淡出。
- EN: The empty-state composer no longer stutters as it flies into the session layout. The composer's rotating color beam repaints every frame, and stacked on the flight's own scale+blur animation that repaint was the stutter. The beam now freezes for the flight and resumes on landing, and sending from the empty state turns the beam off at the send itself instead of letting it run until the scene fades out.
-
登录弹窗取消后按钮不再卡死五分钟:关闭登录弹窗(点遮罩或 Esc)只取消了界面,登录中的标记还挂在供应商上——期间该供应商的登录按钮一直是禁用态,要等 5 分钟 RPC 超时才恢复(「点了添加凭证后再点不弹」)。现在取消时同步清除标记,并通知 daemon 终止登录流程。
- EN: Cancelling the login dialog no longer bricks the buttons for five minutes. Closing the dialog (backdrop or Esc) only dismissed the UI — the in-flight marker stayed on the provider, keeping its login buttons disabled until the 5-minute RPC timeout. Cancel now clears the marker immediately and asks the daemon to abort the flow.
-
首次配置引导的供应商列表合成一列:订阅登录、已配置与 API key 导入此前是三段分组——「API 密钥导入」小标题把同一件事割成两个区域,行为还不一致。现在是一个列表:每行一个供应商,行尾动作只有一种(已配置 → 凭证菜单,OAuth 供应商 → 登录,纯 API 供应商 → 导入),排序、搜索、图标一致。
- EN: The onboarding provider list is one list now. Subscription logins, configured providers, and API-key imports were three separated groups — an "API key import" subheading split one concern into two areas with inconsistent behavior. One list remains: one row per provider with a single trailing action (configured → credential menu, OAuth provider → sign in, key-only provider → import), with shared ordering, search, and icons.
-
供应商标识图标铺到设置与引导各处:供应商卡片、角色模型侧栏、引导供应商行此前都是纯文字,逐一读名才能分辨。现在与模型选择器同一套 Lobe 品牌图标,未知供应商回落到通用 AI 图标。
- EN: Provider brand icons now appear across settings and onboarding. The provider cards, the role-model sidebar, and the onboarding provider rows were text-only, forcing name-by-name reading. They now share the same Lobe brand icons as the model picker, with a generic AI fallback for unknown providers.
-
角色卡回退链可以编辑和拖拽排序了:此前每条回退只能删除重加,顺序错了只能重建整条链。现在点击条目原地换模型,拖动条目直接重排,把手悬停浮现。
- EN: Role-card fallback chains can be edited and drag-reordered. Entries were delete-and-retype only — a wrong order meant rebuilding the whole chain. Clicking an entry swaps the model in place, dragging reorders directly, and the grip appears on hover.
-
角色卡工具行按钮高度统一:思考档位下拉与旁边的按钮此前高低不齐,同一行读起来像两种组件。现在该行所有控件统一 26px 高度。
- EN: The role-card toolbar buttons share one height. The thinking-level select rendered visibly shorter than the buttons beside it, reading as two different components in one row; all controls in the row are now 26px.
-
自定义供应商表单两处对齐:引导表单此前缺「添加模型」手动行(模型列表看着像只读),两处的 Base URL 占位提示也不一致。现在两处共用同一套字段与协议感知的占位提示,表单滚动条换成应用样式(原生绿色滚动条与暗色玻璃面冲突)。
- EN: The custom-provider forms now match between onboarding and settings. The onboarding form lacked the manual "add model" row (its model list read as read-only), and the two forms showed different base-URL placeholder hints. Both now share the same fields and protocol-aware hints, and the form scrollbars use the app styling (the native green scrollbar clashed with the dark glass).
-
删除定时任务时选「同时删除会话」现在真的删得掉:此前删除后任务中心里的会话仍在——关闭会话时日志文件句柄的释放是不等待的,Windows 上紧接着的删除会因句柄未释放而失败,留下的文件让下一次扫描把会话复活。现在删除前先等句柄释放完毕,删除动作对暂时性的占用失败自动重试,不再静默留下半删的文件。
- EN: Choosing "delete its sessions" when deleting a scheduled task now actually deletes them. The journal handle released on session teardown was never awaited, so the immediately following delete failed on Windows with the handle still open, and the leftover file resurrected the session on the next scan. The delete now waits for the release first and retries transient lock failures, so no half-deleted file is left behind silently.
-
供应商卡片不再把同一个账号显示成两张:同一供应商的两种登录方式(如 ChatGPT 的浏览器回调与设备码登录)凭证存在同一处,此前按内部 id 分列成两张卡,看着像登录了两次,且每张卡的「添加另一个凭证」各自只能走到其中一种流程。现在折成一张卡,另一种登录方式收进凭证菜单,凭证、退出登录共用一份。
- EN: A provider account no longer renders as two cards. A provider's two sign-in flows (ChatGPT's browser callback and device-code login, say) share one credential store, but the cards were split by internal id — reading as logged in twice, with each card's "add another credential" reaching only one of the two flows. They now fold into one card, the other flow living in the credential menu, sharing credentials and logout.
-
「添加另一个凭证」在订阅类供应商上不再跳去 API key 输入框:有订阅登录流程的供应商(同时恰好自带模型目录)此前被误判成纯 API key 供应商,点下去打开的是粘 key 的输入框。现在按卡片实际持有的凭证种类走:订阅账号开新的登录流程,纯 API key 供应商才开 key 输入框。
- EN: "Add another credential" no longer jumps to the API-key box on subscription providers. A provider with a subscription login flow — which also happened to ship a bundled model catalog — was misread as API-key-only, so the button opened the key input. It now follows the kind of credential the card actually holds: a subscription account starts another login, and only a pure API-key provider opens the key input.
-
登录与导入 API key 改为居中弹窗:这两个流程此前渲染在设置页内部——先是在页面顶部,离触发它的供应商卡片隔着一整屏;后来嵌进卡片里,三张卡片并列时又宽到放不下,链接和按钮被截掉。现在以弹窗打开:宽度充裕、永远居中、Esc 可关,从哪张卡片发起都一样。
- EN: Login and API-key import now open in a centered dialog. Both flows used to render inside the settings page — first at the top, a full screen away from the provider card that triggered them, then embedded in the card, where two neighbouring cards left too little width and clipped the link and buttons. They now open as a dialog: roomy, always centered, closable with Esc, identical from wherever in the grid they start.
-
定时任务存储跟随数据根目录:任务列表此前固定写在用户主目录下,数据根被重定位(开发隔离、自定义数据目录)后守护进程读的是另一个位置——表现为删掉的任务一重启又回来。现在存储位置随激活的数据根解析,开发环境不再读写真实任务列表,测试也不再向生产目录落任务。
- EN: The scheduled-task store follows the active data root. The task list was hardcoded under the home directory, so a relocated data root (dev isolation, a custom data directory) made the daemon read a different location — deleted tasks reappearing after restart. The store now resolves against the active root: the dev environment no longer touches the real task list, and tests no longer seed tasks into production storage.
Added
- 插件面板不再加载失败,官方插件也都有图标了:插件自带的设置面板原先一律报「模块加载失败」——界面在组件还在下载时就回收了它的地址;现在加载完成后才释放。同时每个插件项都画出了自己的标识(插件声明的图标、内置单元的类别图标,或按包名生成的彩色字母标),状态改为标识角上的小圆点,不再和图标挤在一起。
- EN: Plugin panels no longer fail to load, and official plugins have icons too. A plugin's own settings panel always reported "module failed to load" — the UI released its address while the download was still in flight; it now waits for the load to finish. Every plugin also draws its own mark (a declared icon, a built-in unit's kind glyph, or a colored letter tile derived from the package name), and status moved to a corner badge instead of crowding the icon.
- 插件详情弹窗补齐:点击已安装插件打开详情弹窗——大图标、版本、状态与启用开关、头部卸载按钮;插件自带的组件收进弹窗「包含的组件」逐项开关(不再与插件包重复占列表行),插件的设置界面(如账号池管理)也挂载在弹窗内。
- EN: The plugin detail dialog completes the picture. Clicking an installed plugin opens a dialog with the large icon, version, status, enable toggle and an uninstall button in the header; the plugin's own modules collapse into per-item included-component toggles (no longer duplicated as separate list rows), and its settings surface (an account pool, for example) mounts inside the dialog.
- 插件列表支持一键卸载:已安装插件卡片和列表行新增卸载按钮,确认后由守护进程移除插件目录并即时刷新列表;卸载失败时错误横幅提示且列表保持不变。
- EN: One-click uninstall in the plugin list. Installed plugin cards and rows gain an uninstall button; after a confirmation the daemon removes the plugin directory and refreshes the list immediately, and a failed uninstall shows an error banner while leaving the list untouched.
- 插件图标可自定义:插件可在清单里声明
icon(emoji、字符或图片 URL),列表立即采用;未声明时按包名生成确定的彩色字母标,同包同名同色。- EN: Customizable plugin icons. A plugin can declare
iconin its manifest (emoji, glyph, or an image URL) and the list adopts it; without one, a deterministic colored letter mark is derived from the package name — same package, same mark.
- EN: Customizable plugin icons. A plugin can declare
- 插件页现在可以直接填包名、git 地址、压缩包或本机路径来安装插件:以前只有市场能装已收录的包,自己做的、还没发布的插件没法进。新的入口在插件页工具栏「安装插件」——填入内容后立即开始,边装边显示输出,可以中途取消,失败后原样重试;也可以把压缩包或插件文件夹直接拖进去,自制的插件不用先发布给别人。取消或失败都会把插件目录还原回安装前的样子,不会留下装了一半的依赖。装完会告诉你这个插件能不能在当前环境跑:依赖对得上就标为可用,缺东西或者有界面找不到落点时,把缺的是什么一并列出来,不用等到加载失败才发现。
- EN: The plugins page can now install from a package name, git address, archive, or local path. Only the marketplace could install before, so a plugin you built yourself — or one that was never published — had no way in. The new entry sits in the plugins toolbar: fill in the spec and it starts, shows output as it runs, can be cancelled mid-flight, and retries unchanged after a failure; or drop an archive or plugin folder straight onto it, so a hand-built plugin needs publishing to nobody first. A cancellation or a failure restores the plugin directory to its pre-install state, so no half-installed dependency is left behind. Once it finishes you are told whether the plugin can actually run here: matching dependencies mark it usable, and a missing runtime or a component with no mount point on this host is listed by name, instead of surfacing later as a load failure.
Full Changelog: v0.5.4...v0.5.5