# open-dynamic-workflows-odw **Repository Path**: zenaster/open-dynamic-workflows-odw ## Basic Information - **Project Name**: open-dynamic-workflows-odw - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-12 - **Last Updated**: 2026-08-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
Open Dynamic Workflows logo # Open Dynamic Workflows **Dynamic workflows for coding agents。** 一个开放运行时,把 Codex、Claude Code、Gemini、 Qwen、Kimi、Oh My Pi、Kilo Code、OpenCode、Cursor 编排成可调度的机群——与 Claude Code 自带 Workflow 工具同一方言,外加一个实时观测每次运行的网页看板。 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Node](https://img.shields.io/badge/Node-%E2%89%A520-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white)](tsconfig.json) [![tests](https://img.shields.io/badge/tests-275%20passing-brightgreen.svg)](tests) [![runtime deps](https://img.shields.io/badge/runtime%20deps-0-blue.svg)](package.json) [English](README.md) · [简体中文](README.zh-CN.md)
--- **Open Dynamic Workflows(ODW)** 是一个 TypeScript / Node CLI 运行时,面向可移植的 dynamic workflow:用 JavaScript 脚本在宿主 agent 上下文之外,通过 `agent()`、 `parallel()`、`pipeline()` 扇出并编排 coding agent。如果你想让 Codex、Claude Code、 Gemini、Qwen、Kimi、OMP、Kilo、OpenCode、Cursor 或自定义 CLI 都跑同一份 workflow 脚本,这就是这个项目。 **dynamic workflow** 是一段小小的 JavaScript 脚本:它把编排计划放在普通代码里,在宿主 agent 的上下文**之外**、**大规模**地调度 coding-agent CLI。你写好脚本(或拿到一个), 运行时在后台把它跑完,只把最终结果交回来。Claude Code 已经能在它自己的私有运行时里做 这件事;ODW 把**同一份脚本**做成可移植的——于是 Claude Code 生态里已经在大量产出的 workflow,就成了你在任何 agent 上都能跑的资产。
观看 ODW 产品演示 —— 把 coding agent 扇出到一个实时 workflow 上,看它跑起来 ▶ 观看 33 秒演示(带声音) —— 写一个 workflow、把 agent 扇出去,看整个运行实时点亮。
## 为什么需要编排? 让一个 agent 在自己的上下文里硬磨,很快就到天花板。下表每一行都是你大概率遇过的失败 模式;每个机制都是这个仓库里可直接运行的模式: | 单 agent 的失败模式 | dynamic workflow 的解法 | | --- | --- | | **自评偏差** —— 作者给自己的工作打分 | 跨 CLI 对抗评审:一个 adapter 实现、另一个 adapter 反驳([`adversarial-verify.js`](examples/adversarial-verify.js)、[`codex-claude-loop.js`](examples/codex-claude-loop.js)) | | **一把梭的质量彩票** | N 种思路同台竞技,两两评判选出幸存者([`tournament.js`](examples/tournament.js)) | | **串行等待** | `parallel()` 把子任务扇出到几十个 agent 进程,由有界信号量控制([`fan-out-reduce.js`](examples/fan-out-reduce.js)) | | **上下文污染** —— 长任务挤爆宿主 agent 的窗口 | 运行是 detached 后台 worker;只有最终 `return` 值回来 | | **长任务不可见** | 每次运行都是一张实时 DAG —— 浏览器看板,或 `odw logs --follow` | ## 亮点 - **可移植** —— 同一份 workflow 脚本可跑在 Codex、Claude Code、Gemini、Qwen、Kimi、 OMP、Kilo、OpenCode、Cursor 或你自己的 CLI 上;换底层 agent 只需换适配器。 - **Claude Code 方言,完整支持** —— `export const meta` + 注入的 `agent` / `parallel` / `pipeline` / `phase` / `log` / `args` / `budget` / `workflow` 全局(含嵌套 workflow),支持顶层 `await` 和 `return`。为 Claude Code 写的脚本在这里照跑,反之亦然。 - **带 Chat Host 的实时观测台** —— 在浏览器里和 Codex 正常对话;提到 ODW 或 workflow 的回合会关联到真实异步运行,CLI 发起的 job 也会以实时 DAG 展示,不会污染宿主 agent 的上下文。 - **在上下文之外、大规模** —— 计划留在代码里,中间产物不污染宿主上下文,可扇出几十个 subagent。 - **可靠的交接** —— JSON-Schema 结构化输出,自动校验与重试,让多阶段流水线稳定组合,而 不是在自由文本上碰运气。 - **后台运行、可观测** —— 每次运行都是一个 detached worker + run 目录:`status`、 `logs --follow`、`result`、`pause` / `stop`。 - **无线程、零运行时依赖** —— 引擎是异步 TypeScript(`parallel` 就是 `Promise.all`); workflow 脚本保持纯 `.js`,并附带 `.d.ts` 类型供编辑器补全。 ## 为什么不直接用 Claude Code 内置的 Workflow 工具? Claude Code 已经能跑 dynamic workflow——但只能在它自己的私有运行时里、只为 Claude Code 自己跑。ODW 把**同一份脚本**做成可移植、可独立运行的: - **任意 agent,同一份脚本** —— workflow 不止能跑 Claude Code,还能跑 Codex、Gemini、 Qwen、Kimi、OMP、Kilo、OpenCode、Cursor 或你自己的 CLI;换适配器即可。 - **带外运行** —— 每次运行都是 detached 后台 worker + run 目录,所以你能对它 `status` / `logs --follow` / `pause` / `stop`,并从浏览器观测——不依赖任何 宿主 agent 会话。 - **可移植的资产** —— Claude Code 生态已经在产出的 workflow,就此成为你可以版本化、分享、 并在任何地方运行的文件。 ## 安装 整个安装就是 **一个二进制 + 一个 skill**——无需 Node、无需 npm、不用折腾 PATH、没有 全局模块冲突。挑一种适合你的: ### 1. 让你的 AI Agent 自己装 ODW 本来就是给 coding agent 用的,最省事的就是让它自己装。把下面这段**粘给你的 agent** (Claude Code、Codex、Gemini …): > 帮我安装 Open Dynamic Workflows:运行 > `curl -fsSL https://raw.githubusercontent.com/xz1220/open-dynamic-workflows/main/scripts/install.sh | sh`, > 把 `odw` 二进制装到我的 PATH 上、把 workflow skill 装进你的 skills 目录, > 然后运行 `odw --version` 确认。从现在起,遇到大到值得扇出的任务, > 就写一个 ODW workflow 并用 `odw run` 运行它。 它会跑这个脚本、加载 [skill](skills/open-dynamic-workflows/zh-CN/SKILL.md)([English](skills/open-dynamic-workflows/SKILL.md)),然后立刻就能写并跑 workflow。 ### 2. 一键脚本 ```bash curl -fsSL https://raw.githubusercontent.com/xz1220/open-dynamic-workflows/main/scripts/install.sh | sh ``` 自动下对应平台的预编译二进制(gzip,约 35 MB)到 `~/.local/bin/odw`,并把 skill 装进 `~/.claude/skills/`(没有就退到 `~/.codex/skills/`)。无需 Node。可用环境变量 `ODW_BIN_DIR` / `ODW_VERSION` 覆盖。 ### 3. 手动安装 不想把 `curl` 管道丢给 `sh`?从 [Releases](https://github.com/xz1220/open-dynamic-workflows/releases) 下对应 OS/arch 的资产,然后: ```bash # a) 二进制 —— 放到 PATH 上 gunzip odw-darwin-arm64.gz && chmod +x odw-darwin-arm64 mv odw-darwin-arm64 ~/.local/bin/odw # b) skill —— 把 skills/open-dynamic-workflows/ 拷进 agent 的 skills 目录 git clone https://github.com/xz1220/open-dynamic-workflows.git cp -r open-dynamic-workflows/skills/open-dynamic-workflows ~/.claude/skills/open-dynamic-workflows ``` 或者,**等 `odw` 发布到 npm 之后**(目前还没有——见 [开发](#开发))、且你有 Node ≥20, `npm i -g odw` 就能把 `odw` 装到 PATH 上(skill 仍按上面第 *b* 步装)。在那之前请用上面的二进制。 > 二进制在磁盘上约 110 MB——和任何 Node→二进制 的工具一样,几乎全是内嵌的 Node 运行 > 时——但下载已 gzip 压到约 35 MB。ODW 所**驱动**的 agent(`claude`、`codex` …)仍是你 > 另行安装的独立 CLI。 ## 快速开始 只装了一个 CLI(只有 `claude` 或只有 `codex`)?零配置,直接往下看。装了好几个?安装器 已经让你选过默认了;`odw init` 随时可以重选(agent 则在问过你之后用 `odw init --adapter <名字>` 写入)。 ODW 主要是**被你的 coding agent 驱动**的,不是手动跑。装好 skill 和二进制后,你只要把一个 大任务丢给 agent——它会**自己写一个 workflow 并跑起来**,而且是在它自己的上下文之外: > **你 → 你的 agent:** *"用 Open Dynamic Workflows 深度调研 X 和 Y 的取舍,给我一份带引用 > 的报告。"* > > **你的 agent**(已经加载了 ODW skill)写一个 workflow 脚本、跑 `odw run research.js > --wait`,然后把报告交回来——几十次检索和一轮事实核查都在后台跑完,全程不碰它的上下文。 这正是重点:**agent 保持干净的上下文,把重活扇出给 ODW。** **你自己跑 `odw`**(或自己写一个 workflow)也是同一条命令。一个 workflow 就是 Claude Code 方言的纯 JavaScript,比如 `fan-out-reduce.js`: ```js export const meta = { name: 'fan-out-reduce', description: 'Draft in parallel, then synthesize the best answer.', } const drafts = await parallel( [1, 2, 3, 4].map((i) => () => agent(`Draft #${i}: ${args.question}`)), ) return await agent( 'Synthesize the single best answer from these drafts:\n\n' + drafts.filter(Boolean).join('\n\n---\n\n'), ) ``` ```bash # 在本仓库根目录下(脚本就在 examples/ 里);任意路径都行 odw run examples/fan-out-reduce.js --wait --args '{"question": "Design a rate limiter."}' ``` 旗舰示例 [`examples/deep-research.js`](examples/deep-research.js)(扇出式联网调研 → 对抗式 事实核查 → 带引用报告)正是这样一个脚本。它的实战版 [`deep-research-verified.js`](examples/deep-research-verified.js)(在 codex 适配器上以 100 个 agent、约 9 分钟端到端验证过)还配了可进 cron 的包装脚本——见 [`docs/recipes/deep-research-verified.md`](docs/recipes/deep-research-verified.md)。 ## 编程原语 一个 workflow = `export const meta = {…}` + 一段运行在 async 上下文里的脚本体。脚本体 用普通 JS 控制流(循环、`if`、去重)把这些**注入的全局**串起来——无需 import: | 原语 | 作用 | | --- | --- | | `agent(prompt, opts?)` | 让一个 coding agent 跑一个子任务。唯一真正"产出工作"的原语。返回文本;设了 `opts.schema` 则返回校验过的对象。 | | `parallel(thunks)` | 一组任务并发执行、**等全部完成**(屏障)。失败的那个变 `null`。 | | `pipeline(items, ...stages)` | 每个条目独立穿过各 stage(**无屏障**)。每个 stage 收 `(prev, item, index)`。 | | `phase(title)` / `log(msg)` | 把进度归入某阶段 / 发一行进度消息。 | | `schema`(JSON Schema) | 给 `agent` 的输出定一个类型契约;回复会被校验,不符就重试。 | | `args` | workflow 的输入,原样注入。 | | `budget` | `{ total, spent(), remaining() }`——按 token 目标动态扩缩深度。 | | `workflow(ref, args?)` | 内联调用另一个 workflow(仅一层)。子 workflow 共享本次运行的并发上限、agent 计数与预算;其 phase 以独立泳道归组。 | | `validate(source)` | 只编译不执行地校验一段候选 workflow 源码——让 workflow 能生成 workflow 的自举缝。**ODW 扩展**(不属于 Claude Code 方言)。 | 下一步需要"全量结果一次到位"(去重、计票、综合)时用 **`parallel`**;多阶段处理默认用 **`pipeline`**。归并要保持顺序无关——按"谁先跑完"分支会破坏可复现性。完整参考见 [`skills/open-dynamic-workflows/references/primitives.md`](skills/open-dynamic-workflows/references/primitives.md)。 ## 运行与观测 在交互式终端里,`odw run` 会附着一个**实时前台视图**——每个 agent 的启动、转轮、结算, 按 phase 逐步展示,结束时打印结果。Ctrl-C 只是断开观察(运行继续);`odw attach ` 可随时重新附着。 ```bash odw run wf.js [--args JSON|@file] # 终端里前台展示;运行本体仍是独立 worker # --adapter 指定这次运行的默认 agent # --budget 设置 budget.total ``` 运行本体永远在 detached 后台 worker 里执行。只要你的 shell 不是终端——`$(…)` 捕获、 管道、cron、CI、另一个 agent——同一条命令保持旧契约:立即返回并打印 run id (fire-and-poll): ```bash RUN=$(odw run wf.js) # 非 TTY:打印 run id 并立即返回 odw attach $RUN # 实时视图(被管道时为纯行输出);--timeout 超时退出码 124 odw status $RUN # 状态 + agent 计数 odw logs $RUN --follow # 流式输出原始进度事件 odw result $RUN # 最终值 odw pause|resume|stop $RUN odw list ``` `--fg` / `-d, --detach` / `--wait`(阻塞到结束并打印结果,stderr 仅一行 run id 提示)可显式指定模式;环境变量 `ODW_DETACH=1` 强制后台。 一次运行在独立的 detached worker 进程里执行,并把一切持久化到一个 run 目录——所以它能 比启动它的命令活得更久,也能从任何地方被观测。 保存好的 workflow 也可以直接按名字运行。ODW 会先找项目级、再找个人级,并同时读取自己 的目录和 Claude Code 保存 workflow 的目录: `.odw/workflows`、`.claude/workflows`、 `~/.odw/workflows`、`~/.claude/workflows`(遵循 `CLAUDE_CONFIG_DIR`)。 **喜欢用浏览器?** `odw serve` 会对同一个 run 目录开一个零依赖的实时仪表盘——阶段分栏、 每个 agent 的卡片(适配器 + 耗时)、运行状态都通过 SSE 实时更新。无需构建,不引入任何 额外依赖。 ```bash odw serve [--open] # 实时仪表盘,默认 http://127.0.0.1:4317 odw serve --port 8080 --host 0.0.0.0 # 自定义端口 / 绑定地址 ``` ![odw serve —— 一次 deep-research 运行的实时看板:阶段分栏(Search → Extract → Vote → Report)、每个 agent 的卡片(适配器 + 耗时)、实时状态](assets/odw-dashboard.png) 看板的另外两个页面 —— **Activity**(实时事件流)与 **Job detail**(以实时 DAG 展示 的运行):
Activity
Activity 页面:实时事件流、活跃运行计数和按适配器统计的 agent 负载
Job detail
Job detail 页面:按阶段展示实时 workflow 图和 agent 节点
## 看板:对话、观测、检查 看板是观测台,也带一个本地 Chat Host。普通问题就像正常 Codex 对话一样使用;当某个回合 提到 ODW 或 workflow,它会关联到真实的后台运行。CLI 发起的运行(`odw run `)和 Chat 关联的 ODW 任务都会出现在 Jobs 里,以实时 DAG、日志和最终结果展示。 ```bash odw run adversarial-verify --args '{"question":"review src/rate-limiter.js"}' odw logs --workflow adversarial-verify --follow ``` 看板可以在非 loopback 地址上查看,但本地写操作(例如 Chat 消息和停止 ODW 自己的运行) 仍由 loopback server 保护。Claude Code 自己的运行始终严格只读。 ## 配置适配器 Codex、Claude Code、Gemini、Qwen、Kimi、Oh My Pi、Kilo Code、OpenCode、Cursor 均开箱即用: | 适配器 | 本地 CLI | 非交互契约 | | --- | --- | --- | | `codex` | `codex` | stdout 文本;自带联网搜索 | | `claude` | `claude` | stdout 文本;放行 WebSearch/WebFetch | | `gemini` | `gemini` | stdout 文本 | | `qwen` | `qwen` | stdout 文本 | | `kimi` | `kimi` | stdout 文本 | | `omp` | `omp` | `--print --no-tools --no-session`;stdin 传提示词 | | `kilo` | `kilo` | `run --format json --auto`;从 JSONL 解出最终文本 | | `opencode` | `opencode` | `run --format json --auto`;从 JSONL 解出最终文本 | | `cursor` | `agent` | `--print --force --trust`;stdin 传提示词 | 内置的 `codex` 和 `claude` **自带联网能力**,调研类 workflow 零调参就能跑。 `odw init` 会列出装了哪些 CLI (带各自的权限姿态)并设置默认——在终端里是交互式选择,其他环境退化为纯报告, `odw init --adapter <名字>` 则不弹提示直接写入。要调参或加自己的 CLI,放一个 `odw.config.json`(见 [`odw.config.example.json`](odw.config.example.json))到项目根、 `~/.config/odw/config.json`,或用 `--config` 指定。ODW 只调用本地命令——绝不直接调 模型 API。 ```jsonc { "defaultAdapter": "claude", "concurrency": 8, "adapters": { "my_wrapper": { "label": "My custom CLI", "command": ["my-agent", "--cwd", "{workspace}", "--prompt-file", "{prompt_file}"] } } } ``` 自定义适配器默认把 stdout 作为文本并去掉首尾空白。JSONL 事件流需要显式声明事件 类型和最终文本路径: ```jsonc "output": { "format": "jsonl", "eventType": "text", "textPath": ["part", "text"], "select": "last" } ``` ODW 在运行诊断中保留原始 stdout/stderr,但只把解码后的最终响应交给 workflow。 Windows 下的可执行文件探测遵循 `PATHEXT`,所以 `agent.cmd`、`kilo.cmd`、`omp.exe` 这类普通 shim 无需写完整路径也能识别。 配置键全部放在**顶层**——没有 `"settings"` 包装层;odw 会对未知或放错位置的键 在 stderr 上给出警告(附 did-you-mean 提示),而不是静默忽略。没设 `defaultAdapter` 时,odw 会用唯一配置的 adapter——或在全新安装下,用 PATH 上 唯一真实存在的那个 CLI;若装了多个,报错会列出它们并告诉你如何选择。 ## 工作原理 ``` odw (CLI) ─▶ runtime(后台 worker + run 目录) └─ 加载并转换 ─▶ workflow 脚本(.js,Claude 方言) └─ 注入原语 ─▶ scheduler(async 并发上限 + agent 兜底) agent() ─▶ bridge ─▶ adapters ─▶ 真实 CLI 子进程 ├─ workspace(隔离 + diff) └─ schema(校验 / 重试) ``` 两个值得点出的设计: - **loader 是关键。** Claude 的方言既不是标准 ES module 也不是普通脚本:`export const meta` 在顶部,脚本体用了顶层 `await` **和**顶层 `return`,还引用注入的全局。loader 会(用 字符串/注释/正则感知的扫描)抽出 `meta`、去掉 `export`,再把脚本体包进一个 async 函数, 其参数**就是**那些原语——于是脚本体的 `return` 就变成 workflow 的返回值。 - **没有线程。** 引擎彻头彻尾是异步的。`agent()` 不过是一次异步子进程调用,所以 `parallel` 就是 `Promise.all`、`pipeline` 是逐条目的 async 链,并发上限只是一个小小的 异步信号量——默认 `min(16, CPU核数-2)`,外加一个单次运行总派发量的硬兜底。 | 路径 | 层 | | --- | --- | | `src/adapters/` | L1 — 统一的 CLI 调用(配置、占位符、runner、内置适配器) | | `src/bridge.ts` | L2 — 一次 `agent` 调用 → 一次 CLI 运行,含 schema 处理 | | `src/scheduler.ts` | L3 — 有界的异步并发 + agent 总量兜底 | | `src/primitives.ts`、`src/schema.ts` | L4 — 注入的原语 + 数据契约 | | `src/loader.ts` | 把 workflow 脚本转成可运行形态的转换器 | | `src/runtime/` | L5 — 后台 worker、run 目录、控制 | | `src/cli.ts` | L6 — `odw` 命令 | | `src/workspace.ts` | 横切 — 工作区隔离与 diff | workflow 脚本始终是**纯 `.js`**、从不编译;引擎用 **TypeScript** 写(编译成 ESM, **零运行时依赖**),并附带 `.d.ts` authoring 类型,让脚本作者在编辑器里对注入的全局有 自动补全。 ## 示例 [`examples/`](examples/) 里是可运行的纯 JS workflow: | Workflow | 形态 | | --- | --- | | [`deep-research.js`](examples/deep-research.js) | 扇出调研 → 对抗式事实核查 → 带引用报告 | | [`deep-research-verified.js`](examples/deep-research-verified.js) | 实战版:定界 → 搜索 → 抓取 → 三票对抗核查 → 带引用综合,配可进 cron 的包装脚本([配方](docs/recipes/deep-research-verified.md)) | | [`ultra-mode.js`](examples/ultra-mode.js) | 有纪律的深度工作循环:规划 → 并行攻坚 → 对抗评审 → 综合 | | [`fan-out-reduce.js`](examples/fan-out-reduce.js) | 并行起草 N 份 → 综合出最佳 | | [`adversarial-verify.js`](examples/adversarial-verify.js) | 产出发现 → 只保留扛住证伪的 | | [`loop-until-dry.js`](examples/loop-until-dry.js) | 循环扇出 finder,连续 K 轮无新发现才停 | | [`routing.js`](examples/routing.js) | 给请求分类 → 路由到对应专家 → 给结果打分 | | [`generate-and-filter.js`](examples/generate-and-filter.js) | 并行产出大量点子 → 去重 → 只留过 rubric 的 | | [`tournament.js`](examples/tournament.js) | N 种思路各自解题 → 两两评判晋级 → 决出唯一胜者 | | [`codex-claude-loop.js`](examples/codex-claude-loop.js) | 两个对家 CLI 回合制对弈:Claude 实现,Codex 评审,循环直到签收 | | [`agent-daily-digest.js`](examples/agent-daily-digest.js) | 发现信息源 → 并行提取 → 综合 → 核查 | ## 开发 ```bash npm run build # tsc → dist/ npm test # node:test 测试套件,由 mock 适配器驱动(无需真实账号) npm run typecheck # tsc --noEmit npm run build:binary # 打包 + Node SEA + postject → 单个自包含的 ./build/odw ``` `build:binary` 走的是标准的单二进制配方:[esbuild](https://esbuild.github.io/) 把 `dist/`(零依赖 ESM)打包成一个 CommonJS 文件,`node --experimental-sea-config` 生成 [SEA](https://nodejs.org/api/single-executable-applications.html) blob,再由 [postject](https://github.com/nodejs/postject) 把 blob 注入到一份 `node` 二进制的拷贝里 (macOS 下做 ad-hoc 签名)。esbuild 和 postject 都是**仅构建用的 devDependency**—— 二进制和 npm 包仍保持零**运行时**依赖。跨平台二进制在 CI 里按操作系统分别构建 ([`.github/workflows/release.yml`](.github/workflows/release.yml)):SEA 注入的是宿主 机的 `node`,所以每个目标平台都要在各自的 runner 上构建。 > 发布后,`npm i -g odw`(或 `npx odw …`)会把 `odw` 命令装到你的 PATH 上。 ## 状态 **最新(`main` 上,未发版):**在交互式终端里,`odw run` 现在会直接挂上**前台实时视图** ——Ctrl-C 只脱离不杀任务,`odw attach` 随时挂回,管道/CI 下仍保持先拿 run id 再轮询的 老契约。**首跑引导**落地:装了多个 CLI 时安装器会当场让你选默认,`odw init` 随时重开 这个选择,发射时会预警"裸 `agent()` 调用会失败",配置错误也改为当场失败——不再返回一个 装满 null 的"成功"运行。内置 `codex`/`claude` 适配器**开箱自带联网能力**,实战版 [`deep-research-verified.js`](examples/deep-research-verified.js) 连同可进 cron 的 包装脚本一起入库。更早合入 `main` 的:看板的本地 **Chat Host**(提到 ODW 的回合交给真实 异步运行)、桌面(Tauri)App **退役**、方言补**完整**——嵌套 `workflow()`(共享调度与预算, 仅一层)、`budget.spent()` 真实(估算)计量令 `--budget` 成为硬上限、`odw run --adapter `、随 run 留档的内联脚本运行,以及让 workflow 能生成 workflow 的 `validate()` 原语。 **v0.3.0:****Jobs** 标签页也会展示 **Claude Code 自己的 workflow 运行**——已完成的 历史与正在跑的实时任务——只读,并与 ODW 自己的 run 合并。见 [Releases](https://github.com/xz1220/open-dynamic-workflows/releases)。 **核心运行时已交付。** 完整运行时已在 `main` 上——适配层、执行桥接、工作区隔离、异步调度器、 注入原语、loader/transform、JSON-Schema 引擎、后台运行时,以及 `odw` CLI。**275 个测试 通过**,旗舰示例 [`examples/deep-research.js`](examples/deep-research.js) 端到端跑通 (plan → search → extract → vote → report)。 ### 路线图(v1.5+) `model` / `agentType` 富路由 · adapter 上报的真实 token 用量(当前预算按估算计量)· resume / journaling · 用于可重放确定性的 `Date.now`/`Math.random` 沙箱。 完整方案见 [`docs/dynamic-workflows-tech-plan.md`](docs/dynamic-workflows-tech-plan.md); ODW 所对齐的 Claude Code 方言背景见 [`docs/dynamic-workflows-research.md`](docs/dynamic-workflows-research.md)。 ## 作为 skill 使用 [`skills/open-dynamic-workflows/SKILL.md`](skills/open-dynamic-workflows/SKILL.md)(简体中文版:[`skills/open-dynamic-workflows/zh-CN/SKILL.md`](skills/open-dynamic-workflows/zh-CN/SKILL.md)) 让宿主 agent 仅凭文档就能编写并运行 workflow——把它装进你的 agent 的 skills 目录 (Codex CLI → `~/.codex/skills/`,Claude Code → 它的 skills 目录)。 ## FAQ
这和 CLAUDE.md / AGENTS.md / 一个 skill 有什么区别? 那些是在 agent 自己的上下文里教它怎么做事。dynamic workflow 把工作挪到 外面:计划在脚本里,子任务作为独立 agent 进程大规模运行,只有最终值回来。 ODW 也带一个 skill——但 skill 的职责是教你的 agent 写和跑 workflow,而不是充当编排 本身。
这和 LangGraph / n8n / Airflow 有什么区别? 那些编排的是 API 调用和自定义节点。ODW 编排的是 coding-agent CLI——你已经在付 费、已经配好的那些(Codex、Claude Code、Gemini、…)——在本次运行自己的工作目录里跑, 工作区隔离和 diff 按 agent 选入。没有 DSL、没有服务集群:一个 workflow 就是一个 Claude Code 现有方言 的纯 JavaScript 文件,引擎是零依赖的 Node CLI。
ODW 会直接调用模型 API 吗? 不会。ODW 只 shell 出到你已经登录过的本地 CLI。没有 API key、没有自己的 token 计费、 引擎不发任何网络请求。
网页能通过 odw serve 驱动我本机的 agent 吗? 不能。写端点要求 Content-Type: application/json 和同源 Origin,Host 头 有 allowlist 防 DNS rebinding,绑定到非回环地址时写操作一律拒绝(看板仍可读)。
桌面 App 去哪了? 已退役。App 本来就是 `odw serve` 所服务的同一份单文件 SPA 外面的一层薄 Tauri 壳, 所以网页看板现在是唯一的客户端——天然跨平台,除 `odw` 本身外无需安装任何东西。
## Star 趋势 Star History Chart ## 许可证 [MIT](LICENSE)