Skip to content

workflow-console: follow the system theme, and say when MCode CLI is missing - #75

Open
stevenjj33 wants to merge 5 commits into
MiniMax-AI:mainfrom
stevenjj33:fix/workflow-console-theme-and-mcode
Open

stevenjj33 wants to merge 5 commits into
MiniMax-AI:mainfrom
stevenjj33:fix/workflow-console-theme-and-mcode

Conversation

@stevenjj33

@stevenjj33 stevenjj33 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

两个独立的修复,都来自同一位用户的实际使用反馈。

1. 主题「跟随系统」不生效

根因

miniapp/client/style.css 里从来就没有 @media (prefers-color-scheme: dark),而 app.js 的 applyTheme('system') 做的是 document.documentElement.removeAttribute('data-theme') —— 于是 :root 的浅色变量照常生效。

宿主没有主题桥接(docs/client.md 里只有 miniapp.message.append / miniapp.agent / miniapp.window),页面拿不到宿主主题,所以「跟随系统」实际上恒等于浅色。

表现:macOS 切到系统深色后,控制台仍是白底黑字,只有手动点「主题:深色」才变。

修法

用 matchMedia('(prefers-color-scheme: dark)') 把「跟随系统」解析成具体的 light/dark 再写进 data-theme,CSS 只认这两个值 —— 深色变量仍然只有一份,不会出现两套样式漂移。这与仓库里已合并的 plugins/zch0227/disk-insight 的做法一致。

顺带修了两处:

  • 监听 media query 的 change:用户选的是「跟随系统」时,系统在运行中换配色,页面会跟着换,不必再手动点一下。
  • color-scheme 三条规则([data-theme='light'] / [data-theme='dark'] / @media (prefers-color-scheme: dark) { :root:not([data-theme]) }):原生控件(输入框、下拉、滚动条)跟着页面走,否则深色页面配浅色输入框很割裂。

验证

本机 macOS 深色系统模式下实机打开控制台:修复前面板是白底黑字;修复后面板为深色,且主题按钮仍然显示「主题:跟随系统」—— 说明走的确实是「跟随系统」这条分支,而不是被强制成了深色。

2. MCode CLI 是真实执行器的硬前置

结论

读上游引擎实现(miniapp/node/vendor/dynamic-workflows/dist/main.mjs 的 resolveMcode())后确认:

  • 引擎启动不需要 MCode CLI;
  • 演示执行器(demo)不需要 MCode CLI;
  • 只有真实执行器(mcode)需要 —— 引擎在批准运行的路径上直接 check(await resolveMcode(...), "找不到 MCode CLI,请安装并登录后开始。")。

引擎查找 CLI 的顺序是三处:

  1. PATH 里的 mcode;
  2. 官方用户安装位置:根目录是 $MCODE_INSTALL_DIR,没设时是 ~/.minimax-code;macOS/Linux 找其下的 bin/mcode,Windows 找 mcode.cmd;
  3. 工作流托管的工具链 ~/.mcode-dynamic-workflows/toolchain/lib/node_modules/@minimax-ai/code/cli.js(Windows 少一层 lib)—— 只在该目录已就位时命中,引擎只检查文件是否存在,不负责安装。

/api/config 返回的 mcodeAvailable 只代表找到了可执行文件,不代表已登录、也不代表还有额度。

改动

  • app.js:引擎已起来但 mcodeAvailable === false 时,页面顶部显示横幅说明「演示执行器不受影响,真实执行器需要先安装并登录 MCode CLI」;在「开始执行」这一步,真实执行器 + CLI 缺失时直接拒绝并提示,不再让它跑到一半才失败。
  • 两份 README 新增「前置条件 / Prerequisites」章节:哪些环节需要 CLI、上述查找顺序、mcodeAvailable 的确切语义、引擎的原始报错文案。
  • SKILL.md 补一条:CLI 找不到时控制台会拒绝启动真实执行,别反复重试。

顺带修的 UX 缺陷

引擎还在启动时,横幅原来会误报「内置引擎未能启动」。现在区分成「内置引擎正在启动…」,并把「请确认 MCode CLI 可用」从该文案里移除(CLI 缺失有自己独立的横幅)。

验证

  • 仓库根 npm run check:69/69,0 errors
  • 插件测试 node --test "tests/*.test.mjs":16/16
  • 引擎侧可复现:用隔离环境(HOME 指向空目录、PATH 里没有 mcode、MCODE_INSTALL_DIR 指向空目录)单独拉起上游引擎,/api/config 返回 "mcodeAvailable": false;本机正常环境返回 true。说明这个信号真实可达,不是理论上的分支。
  • 接线逐段核对:引擎 /api/config → server.mjs 的 record.mcodeAvailable(启动与刷新两处)→ publicService() → /api/bootstrap 的 services[] → 客户端 activeEngine()?.mcodeAvailable。
  • 实机:宿主 Mini App 面板跟随系统深色、引擎 live、mcodeAvailable: true(本机 ~/.minimax-code/bin/mcode,0.6.13),引擎 CLI 正常时不出现缺失横幅。

说明

  • 没有引入 light-dark():老浏览器不认会让自定义属性整块失效,失败面太大。
  • 没有把主题初始化挪进 <head> 内联脚本:app.js 在 boot() 里于第一个 await 之前同步调用 applyTheme,与 disk-insight 同级。
  • 客户端逻辑目前没有单元测试覆盖(现有测试都在 node 侧),主题与横幅分支是靠实机验证的。

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

…missing

Two things a user hit on macOS with the system in dark mode.

**The theme never followed the system.** The CSS only ever had
`[data-theme='dark']`, and the script set `data-theme` to a concrete value
only when a theme was picked explicitly — "follow the system" removed the
attribute, so the page fell back to `:root` and stayed light. Map the
system preference onto `data-theme` with `matchMedia('(prefers-color-scheme:
dark)')`, the way the host's own Mini App visual spec asks for and the way
`plugins/zch0227/disk-insight` already does it here, and re-apply when the
system changes while the choice is "follow the system". Also declare
`color-scheme` per theme so the native controls (the working-directory
input, scrollbars) stop looking out of place.

**MCode CLI is a prerequisite, and the page never said so.** The engine
drives agents through the `mcode` CLI, so a real run needs it installed,
logged in, and able to call a model; the demo executor needs none of it.
The console showed "MCode CLI 可用/不可用" in the status line, but that flag
only means the executable was found, and nothing stopped a real run from
starting without it. Say it in a banner, refuse to start a real run while
the CLI is missing, and write the lookup order down in both READMEs
(`PATH`, then `~/.minimax-code/bin/mcode`, then `$MCODE_INSTALL_DIR`).

While in there: the banner said "内置引擎未能启动" while the engine was
still starting, which is not what was happening. It now says so.

Verified on macOS in dark mode: the page follows the system, and the
engine reports `mcodeAvailable: true` against the official install.
The upstream engine resolves the CLI in three places, not two-and-a-half:

1. `mcode` on PATH;
2. the official user install, rooted at `$MCODE_INSTALL_DIR` when set and at
   `~/.minimax-code` otherwise — the engine appends `bin/mcode` (macOS/Linux)
   or `mcode.cmd` (Windows) to that root;
3. a workflow-managed toolchain, which is only used when that directory has
   already been populated — the engine checks for the file, it does not
   provision it.

The previous wording described `MCODE_INSTALL_DIR` as a third location in
its own right, which is not how the lookup works: it replaces the root of
the official install. Spell out all three so the section actually tells
someone where to put the CLI when the banner says it is missing.
@stevenjj33

Copy link
Copy Markdown
Contributor Author

@MyPrototypeWhat 这条 PR 是两个独立修复(主题「跟随系统」+ MCode CLI 前置条件说明),麻烦复审一下,当前 head 是 938d0c1。

一、主题「跟随系统」不生效

  • 根因:style.css 里从来没有 @media (prefers-color-scheme: dark),而 app.js 的
    applyTheme('system') 做的是 removeAttribute('data-theme'),于是 :root 的浅色变量照常生效。
    宿主没有主题桥接(docs/client.md 只有 miniapp.message.append / miniapp.agent /
    miniapp.window),页面拿不到宿主主题,所以「跟随系统」恒等于浅色。
  • 修法:用 matchMedia('(prefers-color-scheme: dark)') 把「跟随系统」解析成具体的
    light/dark 再写进 data-theme,CSS 只认这两个值,深色变量仍只有一份。
    写法对齐本仓库已合并的 plugins/zch0227/disk-insight。
  • 附带两处:监听 media query 的 change(系统运行中换配色,页面跟着换);
    color-scheme 三条规则让原生输入框/滚动条跟随页面。

二、MCode CLI 是真实执行器的硬前置

  • 读了上游引擎 miniapp/node/vendor/dynamic-workflows/dist/main.mjs 的 resolveMcode():
    引擎启动不需要 CLI,演示执行器不需要 CLI,只有真实执行器需要
    (引擎在批准运行的路径上直接 check(await resolveMcode(...), "找不到 MCode CLI,请安装并登录后开始。"))。
  • 查找顺序三处:PATH 里的 mcode → 官方用户安装位置(根目录 $MCODE_INSTALL_DIR,
    没设时 ~/.minimax-code;macOS/Linux 找其下 bin/mcode,Windows 找 mcode.cmd)→
    工作流托管的工具链 ~/.mcode-dynamic-workflows/toolchain/lib/node_modules/@minimax-ai/code/cli.js
    (Windows 少一层 lib,只在该目录已就位时命中)。
  • 改动:引擎起来但 mcodeAvailable === false 时页面顶部显示横幅说明「演示执行器不受影响,
    真实执行器需要先安装并登录 MCode CLI」;点「开始执行」时真实执行器 + CLI 缺失直接拒绝,
    不让它跑到一半才失败。两份 README 补「前置条件 / Prerequisites」章节,SKILL.md 补一条处理提示。
  • 顺带修的 UX 缺陷:引擎还在启动时横幅原来会误报「内置引擎未能启动」,现在区分成「内置引擎正在启动…」。

验证

  • npm run check 69/69、0 errors;插件测试 16/16。
  • 引擎侧可复现:用隔离环境(HOME 指向空目录、PATH 里没有 mcode、MCODE_INSTALL_DIR
    指向空目录)单独拉起上游引擎,/api/config 返回 "mcodeAvailable": false;本机正常环境返回 true。
  • 接线逐段核对:引擎 /api/config → server.mjs 的 record.mcodeAvailable(启动与刷新两处)
    → publicService() → /api/bootstrap 的 services[] → 客户端 activeEngine()?.mcodeAvailable。
  • 实机:宿主面板跟随系统深色、引擎 live、mcodeAvailable: true(本机 ~/.minimax-code/bin/mcode,0.6.13)。

说明:客户端逻辑目前没有单元测试覆盖(现有测试都在 node 侧),主题与横幅分支是靠实机验证的;
没有引入 light-dark()(老浏览器不认会让自定义属性整块失效)。

改动 5 个文件、+148 / −17。

Verified against the bundled Workflow Studio: the create dialog's execution
picker lists demo first, `showCreate()` calls `form.reset()` and never
overrides the selection, so a new workflow runs on the demo executor unless
the user switches it to MCode.

That is the fact that decides whether the CLI is a prerequisite at all — it
is not on the default path. Say it explicitly in the prerequisites section
and in the Skill, so nobody reads "MCode CLI is required" and concludes the
console cannot be used without it.
@stevenjj33

Copy link
Copy Markdown
Contributor Author

补充一点刚核实的实现事实,已补进文档,当前 head 是 eab41df。

引擎 /api/config 里的 executor 字段是CLI 命令名(engine.options.command),不是某次运行的执行方式;真正的执行方式是每次运行时单独指定的 request.executor,取值 demo 或 mcode,引擎强制校验这个字段必须存在。

而 Studio 的「创建工作流」对话框里,执行方式下拉框的第一项就是 demo,showCreate() 只调 form.reset()、从不覆盖这个选择 —— 所以新建的工作流默认走演示执行,不调模型,也就不需要 CLI。只有用户主动切到「MCode · 真实 Agent」时,CLI 才成为硬前置。

另外 Studio 自己已经处理了 CLI 缺失的情况:读到 mcodeAvailable === false 时会把 mcode 选项的文案改成「MCode · 未检测到 CLI」(只是改文案,不禁用该选项)。本 PR 在控制台这一侧补的是横幅提示与「拒绝启动真实执行」,和 Studio 的处理不重复。

两份 README 的「前置条件 / Prerequisites」章节因此补了一段说明默认走 demo,SKILL.md 也加了同样的提示,避免读者把「MCode CLI 是前置条件」误读成「没装 CLI 就用不了这个插件」。

The engine's real executor is the mcode CLI, so the CLI is a prerequisite for
real runs. It is easy to assume it comes with MiniMax Code, but it does not:
the CLI is a separate `@minimax-ai/code` install with npm prefix
`~/.minimax-code`, while the desktop app lives in /Applications. Say so next
to the prerequisite, not in a support answer.
@stevenjj33

Copy link
Copy Markdown
Contributor Author

再补一条实操要点,当前 head 是 11ae421。

桌面版 MiniMax Code 不自带 mcode CLI。 CLI 是单独的 npm 包 @minimax-ai/code,prefix 是 ~/.minimax-code(install.json 里 updateOwner: npm-prefix、registry 是 npmjs),而桌面 App 在 /Applications/MiniMax Code.app。所以「装了桌面版」不等于「有 CLI」,这一条容易被想当然地跳过。

上游 mcode-dynamic-workflows 自己的 VENDOR.md 里也写明了同一件事:「内置引擎调度真实 Agent 时依旧调用 MCode CLI(mcode exec --permission smart …),它需要单独安装并完成登录。本目录只替代插件,不替代 MCode CLI。」 本 PR 内置的是那 2.3 MB 运行时(让没装过上游插件的机器也能跑),替代不了执行器本身。

两份 README 的「前置条件 / Prerequisites」章节都补了这一条。

The README explains the prerequisite from the user's side. This records the
upstream side, for whoever upgrades the vendored runtime:

- the engine has exactly two executors, so a real run has no second path;
- `/api/config`'s `executor` is the CLI command name, not the execution mode
  of a run — the mode is the per-run `request.executor`;
- a new workflow defaults to demo, so the CLI is not on the default path;
- where the engine looks for the CLI, and that upgrading that logic means
  the README's prerequisites section has to change with it.

Also adds a reproducible way to confirm the missing-CLI signal is real
instead of a theoretical branch: start the engine with an empty HOME, a PATH
without mcode, and an empty MCODE_INSTALL_DIR, then read `mcodeAvailable`
off `/api/config`. The snippet in the file is the one that was run.
@stevenjj33

Copy link
Copy Markdown
Contributor Author

文档补齐了最后一块,当前 head 是 31dab97。

README 的「前置条件」是用户视角(要不要装、哪些环节要、怎么装)。这次在 miniapp/node/vendor/dynamic-workflows/VENDOR.md 里补了升级者视角——那是控制台自己写的文件(不在上游 blob 表里,改它不会破坏 vendor-integrity.test.mjs),写的是:

  • 引擎只有 demoExecute / mcodeExecute 两个执行器,真实执行没有第二条路径;
  • /api/config 的 executor 是 CLI 命令名,不是某次运行用的执行方式(同名异义,最容易看错);真正的执行方式是 per-run 的 request.executor,引擎强制它必须存在;
  • 新建工作流默认走 demo,所以 CLI 不在默认路径上;
  • 上游查找 CLI 的三处位置;
  • 升级时如果动了这段逻辑,README 的「前置条件」章节必须跟着改——两处是同一件事的两个视角,只改一边文档就自相矛盾。

另外给了一段可复现的验证命令,用来确认「CLI 缺失」这个信号真实可达,而不是只读源码就相信某个分支存在:起一个隔离环境(HOME 指向空目录、PATH 里没有 mcode、MCODE_INSTALL_DIR 指向空目录)拉起引擎,/api/config 返回 "mcodeAvailable": false。文档里那段命令是逐字跑过的,输出确认过。

改动 6 个文件、+245 / −17。npm run check 69/69,插件测试 16/16。

@stevenjj33

Copy link
Copy Markdown
Contributor Author

更正上一条的数字:改动是 6 个文件、+206 / −17(我刚才写成了 +245,以这个为准)。文件清单:README.md、README.zh-CN.md、skills/workflow-console/SKILL.md、miniapp/node/vendor/dynamic-workflows/VENDOR.md、miniapp/client/app.js、miniapp/client/style.css。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant