diff --git a/plugins/stevenjj33/workflow-console/README.md b/plugins/stevenjj33/workflow-console/README.md index 59e22bed..076df529 100644 --- a/plugins/stevenjj33/workflow-console/README.md +++ b/plugins/stevenjj33/workflow-console/README.md @@ -85,6 +85,46 @@ engine's own database and is not affected by the change. Running real workflows still requires a working `mcode` CLI: the engine orchestrates agents through it. The demo executor works without it. +## Prerequisites + +The console itself needs nothing: no configuration step, no build step, and no other plugin +installed. It ships the Workflow Studio engine and starts it as a child process. + +**The `mcode` CLI is a prerequisite for real runs only.** The engine drives agents through the +`mcode` CLI, so a run on the real executor needs that CLI installed, logged in, and able to call a +model. Everything else works without it: + +| | needs `mcode` CLI | +| --- | --- | +| Opening the page, starting the engine, choosing a project directory | no | +| Approving a draft, pausing, cancelling, resuming | no | +| A run on the **demo** executor (placeholder results, no model call) | no | +| A run on the **real** executor (`mcode`, actual agent calls) | **yes** | + +A new workflow starts in **demo** mode: the Studio's execution-mode picker defaults to demo, so +creating and running a workflow needs no CLI at all. Switch it to "MCode · real agents" only when +you want real agents — that is the point where the CLI becomes required. + +Note that the MiniMax Code desktop app does **not** bundle the CLI. The CLI is a separate +`@minimax-ai/code` install (npm prefix `~/.minimax-code`), so having the desktop app installed is +not the same as having the CLI. + +Where the engine looks for the CLI, in the order it tries: + +1. `mcode` on `PATH`; +2. the official user install — `~/.minimax-code/bin/mcode` on macOS and Linux, + `~/.minimax-code/mcode.cmd` on Windows. `MCODE_INSTALL_DIR` replaces `~/.minimax-code` + as that root, so the engine then looks for `$MCODE_INSTALL_DIR/bin/mcode`; +3. a workflow-managed toolchain, if that directory has been populated — + `~/.mcode-dynamic-workflows/toolchain/lib/node_modules/@minimax-ai/code/cli.js` on macOS and + Linux, `~/.mcode-dynamic-workflows/toolchain/node_modules/@minimax-ai/code/cli.js` on Windows. + +The status line reports "MCode CLI 可用/不可用". That flag only means **the executable was found** — +it says nothing about whether the CLI is logged in or still has model quota, which the CLI itself +decides when a real run starts. When the CLI is missing, the console says so in a banner and +refuses to start a real run instead of failing halfway through; the engine's own error for that +case is "找不到 MCode CLI,请安装并登录后开始。" + ## Skill The package ships one Skill, `skills/workflow-console/SKILL.md`. It tells the Agent how to drive diff --git a/plugins/stevenjj33/workflow-console/README.zh-CN.md b/plugins/stevenjj33/workflow-console/README.zh-CN.md index 606b7b78..f8d348b1 100644 --- a/plugins/stevenjj33/workflow-console/README.zh-CN.md +++ b/plugins/stevenjj33/workflow-console/README.zh-CN.md @@ -68,6 +68,43 @@ Apache-2.0)。 跑真实工作流仍然需要本机 `mcode` CLI 可用:引擎通过它去编排 Agent。demo 执行器不需要。 +## 前置条件 + +控制台本身不需要任何东西:不用配置、不用构建,也不用另外装插件——它自带 Workflow Studio 引擎, +直接作为子进程拉起来。 + +**`mcode` CLI 只是「真实执行」的前置条件。** 引擎通过 `mcode` CLI 驱动 Agent,所以用真实执行器 +跑一次工作流,需要这个 CLI 已安装、已登录、且能调用模型。其余环节都不需要它: + +| 环节 | 需要 `mcode` CLI | +| --- | --- | +| 打开页面、启动引擎、选定项目目录 | 不需要 | +| 审核草稿、暂停、取消、恢复 | 不需要 | +| **演示执行器**的运行(只返回占位结果,不调模型) | 不需要 | +| **真实执行器**(`mcode`,真正调度 Agent)的运行 | **需要** | + +新建工作流默认是**演示**执行方式:Studio 的「执行方式」下拉框默认选中 demo,所以创建并运行一条 +工作流全程不需要 CLI。只有当你要用真实 Agent 时,才需要把执行方式改成「MCode · 真实执行」—— +那一步才让 CLI 变成硬前置。 + +另外注意:MiniMax Code 桌面版**不自带** CLI。CLI 是单独的 `@minimax-ai/code` 安装 +(npm prefix 是 `~/.minimax-code`),所以装了桌面版不等于装了 CLI。 + +引擎按这个顺序找 CLI: + +1. `PATH` 里的 `mcode`; +2. 官方用户安装位置——macOS 与 Linux 是 `~/.minimax-code/bin/mcode`,Windows 是 + `~/.minimax-code/mcode.cmd`;设了 `MCODE_INSTALL_DIR` 时,它顶替 `~/.minimax-code` 当根目录, + 引擎找的就是 `$MCODE_INSTALL_DIR/bin/mcode`; +3. 工作流托管的工具链(该目录已就位时才会命中)——macOS 与 Linux 是 + `~/.mcode-dynamic-workflows/toolchain/lib/node_modules/@minimax-ai/code/cli.js`,Windows 是 + `~/.mcode-dynamic-workflows/toolchain/node_modules/@minimax-ai/code/cli.js`。 + +状态栏上的「MCode CLI 可用/不可用」**只表示找到了这个可执行文件**——它不说明 CLI 有没有登录、 +还剩多少模型额度,那两件事要等 CLI 真正跑起来时自己判断。CLI 缺失时,控制台会在横幅上写明, +并且拒绝启动真实执行,而不是让它跑到一半失败;引擎那边对应的报错是 +「找不到 MCode CLI,请安装并登录后开始。」 + ## Skill 本包附带一个 Skill:`skills/workflow-console/SKILL.md`。它告诉 Agent 怎么用这个控制台—— diff --git a/plugins/stevenjj33/workflow-console/miniapp/client/app.js b/plugins/stevenjj33/workflow-console/miniapp/client/app.js index a4915350..db2e02f5 100644 --- a/plugins/stevenjj33/workflow-console/miniapp/client/app.js +++ b/plugins/stevenjj33/workflow-console/miniapp/client/app.js @@ -259,25 +259,49 @@ function toast(message, tone = 'success') { const THEMES = ['system', 'light', 'dark']; const THEME_LABEL = { system: '跟随系统', light: '浅色', dark: '深色' }; +const THEME_STORAGE_KEY = 'wf-console-theme'; +/* 系统配色偏好。跟随系统时由它决定实际是浅色还是深色;系统换配色时页面也跟着换。 */ +const systemDark = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null; +function storedTheme() { + try { + const saved = window.localStorage.getItem(THEME_STORAGE_KEY); + return THEMES.includes(saved) ? saved : 'system'; + } catch { + /* 忽略存储不可用 */ + } + return 'system'; +} + +/* 跟随系统 → 按系统偏好解析成浅色或深色;显式选择 → 用用户选的那个。 + data-theme 一律设成具体值,CSS 只认 light/dark 两种; + 早先这里是「system 就删掉 data-theme」,结果永远退回浅色。 */ function applyTheme(theme) { - if (theme === 'system') document.documentElement.removeAttribute('data-theme'); - else document.documentElement.setAttribute('data-theme', theme); + const resolved = theme === 'system' ? (systemDark && systemDark.matches ? 'dark' : 'light') : theme; + document.documentElement.setAttribute('data-theme', resolved); dom.themeToggle.textContent = `主题:${THEME_LABEL[theme]}`; dom.themeToggle.dataset.theme = theme; try { - window.localStorage.setItem('wf-console-theme', theme); + window.localStorage.setItem(THEME_STORAGE_KEY, theme); } catch { /* 忽略存储不可用 */ } } dom.themeToggle.addEventListener('click', () => { - const current = window.localStorage.getItem('wf-console-theme') || 'system'; - const next = THEMES[(THEMES.indexOf(current) + 1) % THEMES.length]; + const next = THEMES[(THEMES.indexOf(storedTheme()) + 1) % THEMES.length]; applyTheme(next); }); +/* 用户选的是「跟随系统」时,系统配色一变就跟着变。 */ +if (systemDark) { + const onSystemThemeChange = () => { + if (storedTheme() === 'system') applyTheme('system'); + }; + if (systemDark.addEventListener) systemDark.addEventListener('change', onSystemThemeChange); + else if (systemDark.addListener) systemDark.addListener(onSystemThemeChange); +} + /* ---------------- engine status ---------------- */ /* 控制台只有一个后端:它自己内置的 Workflow Studio 引擎。 @@ -286,8 +310,13 @@ dom.themeToggle.addEventListener('click', () => { let lastEngineSignature = ''; +/** 当前这台控制台唯一的后端:它自己内置的 Workflow Studio 引擎。 */ +function activeEngine() { + return state.services.find((service) => service.id === state.activeServiceId) || null; +} + function renderEngine() { - const active = state.services.find((service) => service.id === state.activeServiceId) || null; + const active = activeEngine(); const signature = active ? [ active.id, @@ -323,21 +352,38 @@ function renderEngine() { ` · 并发 ${scheduler.active ?? 0}/${scheduler.limit ?? '—'}`; } - if (live) { + if (live && active && active.mcodeAvailable === false) { + /* 引擎起来了,但真实执行器还差 MCode CLI:这时只有演示执行器能跑。 */ + dom.serviceBanner.hidden = false; + dom.serviceBanner.textContent = ''; + dom.serviceBanner.append( + node('strong', { text: '未找到 MCode CLI。' }), + node('span', { + text: ' 演示执行器(demo)不受影响,但用真实执行器跑工作流需要先安装并登录 MCode CLI,' + + '否则运行会在启动时失败。安装位置见 README 的「前置条件」。', + }), + ); + } else if (live) { dom.serviceBanner.hidden = true; } else { dom.serviceBanner.hidden = false; dom.serviceBanner.textContent = ''; + const starting = Boolean(active?.starting); dom.serviceBanner.append( node('strong', { - text: needsWorkspace ? '还没有选择项目目录。' : '内置引擎未能启动。', + text: needsWorkspace + ? '还没有选择项目目录。' + : starting + ? '内置引擎正在启动…' + : '内置引擎未能启动。', }), node('span', { text: needsWorkspace ? ' 内置引擎不会在用户主目录或系统临时目录里运行——那样一次运行就能改写整个家目录。' + '请在下方填写项目的绝对路径,保存后引擎会自动启动。' - : ' 控制台会自动重试;若持续失败,请确认 MCode CLI 可用(需要登录且模型可调用),' + - '并查看 dataDir/engine/service.log 里的引擎日志。', + : starting + ? ' 控制台会拉起内置引擎,稍等即可;期间还不能开始执行。' + : ' 控制台会自动重试;若持续失败,请查看 dataDir/engine/service.log 里的引擎日志。', }), ); } @@ -1567,6 +1613,12 @@ async function confirmStart(runId) { } const nodeCount = Array.isArray(run.topology?.nodes) ? run.topology.nodes.length : 0; const real = run.executor !== 'demo'; + /* 真实执行器要靠 MCode CLI 调度 Agent:CLI 根本不在时,运行一定起不来, + 与其让它跑到一半失败,不如在这里说清楚。演示执行器不需要 CLI。 */ + if (real && activeEngine()?.mcodeAvailable === false) { + toast('未找到 MCode CLI,真实执行无法启动;请先安装并登录 MCode CLI,或改用演示执行器。', 'danger'); + return; + } const answer = await askConfirm({ title: '开始执行该工作流', note: @@ -1985,13 +2037,7 @@ async function loadBootstrap() { } async function boot() { - let theme = 'system'; - try { - theme = window.localStorage.getItem('wf-console-theme') || 'system'; - } catch { - theme = 'system'; - } - applyTheme(THEMES.includes(theme) ? theme : 'system'); + applyTheme(storedTheme()); try { await loadBootstrap(); diff --git a/plugins/stevenjj33/workflow-console/miniapp/client/style.css b/plugins/stevenjj33/workflow-console/miniapp/client/style.css index bc0e0491..015d0fae 100644 --- a/plugins/stevenjj33/workflow-console/miniapp/client/style.css +++ b/plugins/stevenjj33/workflow-console/miniapp/client/style.css @@ -45,6 +45,23 @@ --mcode-primary-action-text: #171717; } +/* 实际配色由 data-theme 决定:脚本把「跟随系统」解析成 light/dark 落到这个属性上。 + color-scheme 决定原生控件(输入框、滚动条)用哪一套配色,别让它们跟页面脱节。 */ +[data-theme='light'] { + color-scheme: light; +} + +[data-theme='dark'] { + color-scheme: dark; +} + +/* 脚本还没跑(首屏那一瞬)时,原生控件先按系统偏好走。 */ +@media (prefers-color-scheme: dark) { + :root:not([data-theme]) { + color-scheme: dark; + } +} + * { box-sizing: border-box; } diff --git a/plugins/stevenjj33/workflow-console/miniapp/node/vendor/dynamic-workflows/VENDOR.md b/plugins/stevenjj33/workflow-console/miniapp/node/vendor/dynamic-workflows/VENDOR.md index b83fc09b..4ca42875 100644 --- a/plugins/stevenjj33/workflow-console/miniapp/node/vendor/dynamic-workflows/VENDOR.md +++ b/plugins/stevenjj33/workflow-console/miniapp/node/vendor/dynamic-workflows/VENDOR.md @@ -79,6 +79,48 @@ 需要人工确认的步骤会让那个节点直接失败,而不是停下来等人。 控制台的「开始执行」确认框和 README 都写明了这一点。 +### 上游是怎么选执行器的(升级时必看) + +引擎只有两个执行器,真实执行**没有第二条路径**: + +- `demoExecute` —— 不调模型,延时后返回占位结果; +- `mcodeExecute` —— 直接 spawn `mcode exec --input - --cwd … --output-format stream-json --permission smart …`。 + +有一处极易看错:**`/api/config` 里的 `executor` 字段是 CLI 命令名** +(`engine.options.command`,值就是 `"mcode"`),**不是某次运行用的执行方式**。 +真正的执行方式是每次运行单独指定的 `request.executor`(取值 `demo` 或 `mcode`), +引擎用 `check(["demo","mcode"].includes(request.executor), "executor 必须为 demo 或 mcode")` +强制它存在。 + +而新建工作流时**默认是 demo**:Studio 的「执行方式」下拉框第一项就是 demo, +`showCreate()` 只调 `form.reset()`、从不覆盖这个选择。 +所以「MCode CLI 是硬前置」这句话只对**真实执行**成立,默认路径并不需要它。 + +上游查找 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`, +只在该目录已就位时命中,引擎只检查文件存在,不负责安装)。 + +**升级上游时如果动了这一段**(执行器选择、`resolveMcode()` 的查找顺序), +README 的「前置条件 / Prerequisites」章节必须跟着改——两处是同一件事的两个视角, +只改一边,两份文档就会自相矛盾。 + +### 怎么自己确认「CLI 缺失」这个信号是真的 + +别只读源码就相信某个分支可达。起一个隔离环境就能复现: + +```sh +TMP=$(mktemp -d); mkdir -p "$TMP/ws" "$TMP/data" "$TMP/fakehome" "$TMP/emptyroot" +env -i HOME="$TMP/fakehome" PATH="/usr/bin:/bin" MCODE_INSTALL_DIR="$TMP/emptyroot" \ + "$(command -v node)" miniapp/node/vendor/dynamic-workflows/dist/main.mjs \ + --workspace "$TMP/ws" --data-dir "$TMP/data" +``` + +`HOME` 指向空目录 → `~/.minimax-code` 不存在;`PATH` 里没有 `mcode`; +`MCODE_INSTALL_DIR` 指向空目录。引擎照常启动,`/api/config` 返回 +`"mcodeAvailable": false`——这正是控制台横幅和「拒绝启动真实执行」所依赖的信号。 + ## 更新方式(怎么跟上上游) 副本锁定在 `6481e4ae1e0375a4ddb3d5e9b29845354ab1cead`,不会自动跟随上游升级。 diff --git a/plugins/stevenjj33/workflow-console/skills/workflow-console/SKILL.md b/plugins/stevenjj33/workflow-console/skills/workflow-console/SKILL.md index 375b484c..9c512eab 100644 --- a/plugins/stevenjj33/workflow-console/skills/workflow-console/SKILL.md +++ b/plugins/stevenjj33/workflow-console/skills/workflow-console/SKILL.md @@ -74,6 +74,13 @@ description: "运行、查看与管控 MiniMax Code 动态工作流(多 Agent 页面上 `mcodeAvailable: true` 只说明 `mcode` 可执行文件存在,**不代表它登录了或还有额度**。 真实执行失败时先查登录和额度,别直接归因给工作流本身。 +CLI 找不到时,控制台会在横幅上写明并**拒绝启动真实执行**——这时候别反复重试,让用户先装好并登录, +或改用 demo 执行器(Studio 的「执行方式」默认就是 demo,不调模型,所以没有 CLI 也能把工作流 +创建并跑起来)。引擎查找 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`)。 + ## 数据与边界 - 引擎只监听 `127.0.0.1`,控制台只代理到它:不连外网,也不连别的本地服务。