Skip to content

atebites-hub/open-dynamic-workflows

v0.4.3MIT

ODW for Cursor, Grok Bot (via Cursor CLI), Grok Build, ZCode, Antigravity and Copilot, with safe worktree isolation. Claude and Codex hosts use native ultracode/ultra instead.

Open Dynamic Workflows

中文文档

Dynamic workflow orchestration for Cursor, Grok Bot (via Cursor CLI), Grok Build, ZCode, Antigravity, and Copilot — fan a deterministic JavaScript script out across many CLI subagents through a native workflow tool and authoring skill.

A dynamic workflow is a plain-JS script that orchestrates subagents at scale. The model writes the script for the task; the plugin's bundled runtime executes it, fanning each agent() call out to a real cursor-agent, grok, claude, codex, or zcode subprocess.

Harness policy (2026-09-11)

Claude harnesses use native ultracode; Codex/ChatGPT harnesses use native ultra mode. Advise the mode without changing the selected model; do not activate ODW on those hosts.

Cursor and Grok Bot use ODW with Cursor CLI workers, not Cursor multitask or persistent Bot-to-Bot delegation. Set ODW_HOST=grok-bot explicitly in the Bot VM; omitted executor then selects cursor, not Grok Build. Grok Build, ZCode, Antigravity and Copilot retain their corresponding ODW executors. Installation and live-run gaps remain explicit. Legacy Claude/Codex executors remain available to standalone SDK callers, not their native-only host packages.

Worktree safety

Use isolation: 'worktree' for workers that mutate files concurrently, not for every read-only task. The first isolated worker pins the caller HEAD for the whole run, including nested workflows. Staged/unstaged caller edits are not copied or discarded; commit required shared inputs before an isolated run. A caller inside a repository subdirectory stays in that subdirectory inside each worker checkout.

Only successful pristine worktrees at their original commit are removed, without force. New commits, changed/untracked/ignored files, failed or cancelled workers, and uncertain cleanup retain the checkout. Use worktreeNotes and the agent trace cwd to inspect and integrate the result; no changes are auto-merged into the caller. Retained commits remain reachable through their worktree. Worktrees are Git isolation, not a security sandbox: native permission checks remain in force.

Install (Cursor CLI)

Cursor CLI (agent, from cursor.com/install) does not yet install plugins from a marketplace the way Grok/Codex do. Use the repo installer — one copy-paste, then a new agent session has the workflow tool and the authoring skill. Omitted executor is cursor.

git clone --depth 1 https://github.com/atebites-hub/open-dynamic-workflows-plugin.git
node open-dynamic-workflows-plugin/scripts/install-cursor-cli.mjs

That writes an absolute MCP command into ~/.cursor/mcp.json (CLI user/project mcp.json does not expand ${PLUGIN_ROOT}), links the plugin into ~/.cursor/plugins/local/open-dynamic-workflows, and copies the skill to ~/.cursor/skills/open-dynamic-workflows. Then:

agent mcp enable open-dynamic-workflows
agent mcp list

Headless check: agent -p --force --trust --workspace . --output-format json --approve-mcps. Developers iterating on a checkout can skip the home install and load the dual-format plugin (Cursor Plugin + Agent Plugin) with agent --plugin-dir /path/to/open-dynamic-workflows-plugin.

Cursor IDE

cursor-agent plugin marketplace add atebites-hub/open-dynamic-workflows-plugin only registers the marketplace. Install open-dynamic-workflows from Customize, or copy/symlink the plugin into ~/.cursor/plugins/local. Plugin mcp.json still uses ${PLUGIN_ROOT} for that loader.

Omitted executor runs on cursor (agent / cursor-agent / CURSOR_BIN). Nested Cursor leaves set ODW_CURSOR_LEAF=1 and must not reload this plugin's workflow tool.

Cursor team marketplace

This repository is the team marketplace catalog (.cursor-plugin/marketplace.json, name atebites-cursor-plugins). In Dashboard → Plugins → Import from Repo, import:

https://github.com/atebites-hub/open-dynamic-workflows-plugin

Then in Customize, install:

Remote source values are GitHub URLs, which the official marketplace schema allows. Plugin entries only use name, source, and description. If Import from Repo only indexes in-repo paths, add the ponytail and sol-advisor GitHub repos as additional marketplaces — this catalog does not vendor those trees.

CLI install for open-dynamic-workflows is still node scripts/install-cursor-cli.mjs above.

Install (Grok Build)

grok plugin marketplace add atebites-hub/open-dynamic-workflows-plugin
grok plugin install open-dynamic-workflows --trust

Open a new Grok session (or press r in the Plugins tab). Omitted executor runs on grok. The plugin is self-contained; no project-local ODW checkout or build is needed.

Claude and Codex: native mode only

Use Claude ultracode or Codex/ChatGPT ultra mode. These plugin manifests now provide only native-mode guidance, not an ODW MCP server. The server also rejects stale Claude/Codex host configurations with an actionable mode recommendation.

Install (Antigravity CLI)

After cloning/building this repository:

node scripts/install-antigravity-cli.mjs

The native CLI registers an absolute MCP command and imports the authoring skill. No undocumented plugin-root substitution is used. Keep the checkout in place and start a fresh session. Desktop/IDE seating requires its own live verification. Use ANTIGRAVITY_BIN (or AGY_BIN) for an explicit CLI path. New worker sessions use --new-project at their worktree cwd. Headless write permission must be authorized for those paths; SUCCESS with denied_actions is treated as failure.

Install (Copilot)

copilot plugin install atebites-hub/open-dynamic-workflows-plugin:plugins/copilot/open-dynamic-workflows

Restart the session after install. COPILOT_BIN selects an explicit CLI binary. The adapter requires the JSONL interface present in Copilot CLI 1.0.83. It keeps path verification enabled, does not enable all paths/URLs, and reports quota or permission errors instead of claiming an empty successful run. Model and effort remain per-worker selections; unavailable billing quota is not an adapter pass.

Install (ZCode users)

/plugins marketplace add atebites-hub/open-dynamic-workflows-plugin
/plugins install open-dynamic-workflows

Then restart ZCode (or open a new session). That's it — no build step, no node_modules. The plugin ships a self-contained dist/mcp/server.js.

After install, a session gets:

  • a workflow tool — the model authors a script and calls workflow({ cwd, script }); it runs to completion and returns the script's value.
  • the $open-dynamic-workflows skill — the authoring guide (when to reach for a workflow, the meta/agent()/pipeline()/parallel() contract, proven shapes).
  • the /open-dynamic-workflows:workflows slash command — list and resume runs in the current project.

How it works

model writes a JS workflow script
  └─ calls workflow({ cwd, script })
      └─ plugin's MCP server (dist/mcp/server.js)
          └─ ODW runtime: runWorkflow({ executors: { cursor, zcode, grok, claude, codex } })
              ├─ agent({executor:'cursor'}) (or omitted on Cursor) spawns `cursor-agent -p …`
              ├─ agent({executor:'zcode'}) (or omitted on ZCode) spawns `zcode --prompt …`
              ├─ agent({executor:'grok'}) (or omitted on Grok Build) spawns `grok -p …`
              ├─ agent({executor:'claude'}) spawns `claude --print …`
              ├─ agent({executor:'codex'}) spawns `codex exec --json …`
              ├─ parallel()/pipeline() orchestrate, journal persists results
              └─ returns the script's `return` value + run metadata

Each executor uses the user's installed CLI from PATH (GROK_BIN / ZCODE_BIN / CURSOR_BIN override the binary). Cursor runs headless agent/cursor-agent -p with --output-format json or stream-json, --force, and --workspace. Nested cursor leaves do not reload this plugin's MCP (ODW_CURSOR_LEAF=1). Grok runs headless grok -p with --output-format json or streaming-json, --always-approve, and --sandbox workspace — never the broken --tools allowlist. Nested grok leaves do not reload this plugin's MCP. Codex verifies cwd against the active workspace metadata supplied by the host, then runs with JSONL output and a workspace-write sandbox. ZCode uses ZCODE_ODW_PROTOCOL=1. Each agent is one real model turn. A Codex model override defaults to medium reasoning unless the node supplies reasoningEffort. Completed agents replay from the journal with zero token spend.

A minimal workflow

export const meta = { name: 'demo', description: 'two parallel grok agents' }

const results = await parallel([
  () => agent('What is 2+2? Reply with just the number.', { executor: 'grok', label: 'math' }),
  () => agent('Name a red planet. One word.', { executor: 'grok', label: 'trivia' }),
])
return { results }

Call workflow({ cwd: "/absolute/project/path", script: "<the above>" }); the tool returns { value: { results: [...] }, runId, ok, ... }.

See the $open-dynamic-workflows skill for the full authoring contract (phases, schemas, the pipeline-vs-parallel decision, adversarial-verify / judge-panel / loop-until-dry shapes).

Repository layout

This repo is the Cursor, Grok, Codex, and ZCode marketplace and the plugin.

├── .cursor-plugin/marketplace.json # Cursor team marketplace catalog (official schema)
├── .cursor-plugin/plugin.json      # Cursor plugin manifest
├── plugin.json                     # Agent Plugins manifest (CLI --plugin-dir)
├── mcp.json                        # Cursor MCP launch (${PLUGIN_ROOT}; IDE / plugin loader)
├── scripts/install-cursor-cli.mjs  # Cursor CLI home install (absolute MCP path)
├── .grok-plugin/marketplace.json   # Grok marketplace catalog
├── .grok-plugin/plugin.json        # Grok plugin manifest (repo-as-plugin / grok plugin install .)
├── .grok-plugin/mcp.json           # Grok MCP launch (GROK_PLUGIN_ROOT, 8h tool timeout)
├── plugins/open-dynamic-workflows/ # Grok marketplace package (catalog source; Grok rejects "./")
├── .agents/plugins/marketplace.json # Codex marketplace manifest
├── .codex-plugin/plugin.json       # Codex plugin manifest
├── .codex-mcp.json                 # Codex MCP launch config
├── marketplace.json                # ZCode marketplace manifest
├── .zcode-plugin/plugin.json       # ZCode plugin manifest
├── .mcp.json                       # ZCode stdio MCP server (${ZCODE_PLUGIN_ROOT})
├── .claude-plugin/plugin.json      # Claude Code manifest + MCP mirror
├── skills/open-dynamic-workflows/  # authoring skill (vendored from ODW)
├── commands/workflows.md           # /workflows slash command
├── src/mcp/server.ts               # MCP server source (the `workflow` tool)
├── dist/mcp/server.js              # COMMITTED self-contained bundle (what runs)
├── scripts/{build,setup,smoke}.mjs # dev build + smoke pipeline
├── open-dynamic-workflows/         # git submodule (ODW source — dev only)
└── zcode-cli/                      # git submodule (dev convenience; not bundled)

For maintainers / contributors

The dist/mcp/server.js that users run is built from the submodules and committed. Nested remotes, pin policy, and the weekday sync workflow are in UPSTREAM.md. After cloning:

npm run setup    # init submodules + locked installs + build ODW + esbuild → dist/mcp/server.js
npm run smoke    # standalone JSON-RPC smoke test of the built server
npm run build    # rebuild just the bundle (skips submodule init)
npm run verify   # rebuild and run the plugin smoke checks
node scripts/install-cursor-cli.mjs   # Cursor CLI: MCP + local plugin + skill

The build (scripts/build.mjs) uses esbuild to inline ODW + its only dep (ajv) into a single ESM file, matching the android-emulator plugin's pattern. No node_modules ship to users.

Governed routing (v0.3)

For a run that must use one exact route, pass an immutable policy:

workflow({
  cwd: "/absolute/project/path",
  routingPolicy: {
    executor: "codex",
    model: "gpt-5.4",
    reasoningEffort: "high",
  },
  script,
})

The policy is validated by ODW core before the journal or any subprocess is opened. Every omitted node route inherits it; an explicit executor, model, or reasoning-effort conflict fails before launch. Nested workflows inherit the same policy. Policy runs cannot combine with resumeFromRunId or cache replay. The MCP result exposes only the allowlisted policy tuple and its SHA-256 routingPolicyFingerprint; this is correlation evidence, not proof that a host CLI accepted the requested model. Inspect the run trace for the authoritative executor/model/effort and runtime ID when the host provides them.

Without routingPolicy, existing host defaults remain unchanged: omitted executor selects Cursor, Grok, Claude, Codex, or ZCode from the host launch environment. An explicit executor still overrides that host default.

Notes / scope (v0.4.3)

  • Host-native default worker. Omitted executor uses cursor on Cursor and Grok Bot, grok on Grok Build, zcode on ZCode, codex on Codex, claude on Claude Code. Name another worker to override.
  • Host-specific lifecycle. Grok Bot workflow() returns a durable background job handle; poll workflow_status and use workflow_cancel to stop it. Other hosts keep their synchronous workflow() behavior.
  • Local evidence. .odw/ artifacts contain workflow scripts, prompts, and agent responses; newly written run files are owner-only. Keep .odw/ gitignored.
  • No ultracode auto-decide. ODW does not auto-inject a workflow the way Claude ultracode can. The skill and tool descriptions stay passive; the model decides. Claude/Codex host exclusions and the Cursor/Grok Bot ODW route are defined by the harness policy above.
  • Telemetry. The zcode_result envelope currently reports costUsd/inputTokens/ outputTokens as null (telemetryAvailable: false). The plugin reports zeros honestly until the zcode launcher fills these in.

See harness policy above.

License: MIT.

Native-only installation roots

Claude and Codex install the small packages under native/claude/open-dynamic-workflows and native/codex/open-dynamic-workflows. Do not install the development repository root on those hosts: native auto- discovery can otherwise load root workflow skills and the ZCode MCP config. The published advice-only roots contain one native-orchestration skill and no MCP configuration. Claude external catalogs use the documented git-subdir source with the reviewed release SHA; Codex's own catalog points at its native package directory. Other hosts retain the full workflow package.

Grok Bot through Cursor CLI

This is a configured host-to-executor mapping, not native Bot orchestration. The worker CLI runs inside the Bot VM. Do not use a Mac-side fallback or substitute the ambiguous agent binary, which may belong to Grok Build.

Before installation, check cursor-agent --version and cursor-agent status in that VM. Keep credentials out of prompts and logs. A Grok Bot login does not prove Cursor CLI authentication, model availability, or which allowance pays for its requests. No model selection or billing setting is changed by this plugin.

For the Cursor CLI MCP configuration in the Bot VM:

node scripts/install-cursor-cli.mjs --host grok-bot
cursor-agent mcp enable open-dynamic-workflows

This installer configures Cursor CLI; it does not install/authenticate that CLI or certify that the Grok Bot host loads its local MCP configuration. Register node /absolute/plugin/dist/mcp/server.js with ODW_HOST=grok-bot through the host's supported MCP mechanism. If that mechanism is unavailable, report an installation gap rather than calling an alternate host a Grok Bot pass.

Every Grok Bot workflow call must supply its absolute VM project cwd. Use isolation: 'worktree' for parallel writers. Poll the returned jobId with workflow_status; accepted/queued is not success. Inspect the final result's executionContext (configured host/default executor only), per-agent traces (actual executor), and retained branch/diff receipts. Never infer preserved files from a resumed chat ID, or runtime/model attestation from a host label.

npm run verify exercises the Grok Bot mapping, missing/relative cwd rejection, installer idempotence, and two retained writer worktrees through the packaged server. The model CLIs in those tests are fixtures; live VM qualification is still a separate requirement.

Grok Bot background jobs (0.4.2)

The host's short MCP deadline must not own a long workflow. workflow now accepts a job promptly on Grok Bot, while a detached supervisor runs the same ODW engine. workflow_status({cwd, jobId, waitSeconds: 10}) waits at most 20 seconds per call; poll until terminal. Only state: "completed", ok: true means success: all nodes must succeed and the journal must be durable.

Pass a stable optional requestId for idempotent start retries. Identical snapshotted inputs return the same job; changed inputs under that key are rejected. This is not agent-cache replay. scriptPath is snapshotted at start and resolves relative to the supplied project cwd. The core runId becomes available after execution starts and is distinct from the control jobId.

Jobs survive an MCP request ending or the MCP server process disconnecting. Use workflow_cancel({cwd, jobId}) for explicit cancellation. maxSeconds bounds the whole job: default 1800, range 1-28800, plus up to 5 seconds for cooperative abort/receipt flushing before the supervisor kills its owned runtime process group. Cancellation retains partial CLI traces and worktrees. On Linux, 0.4.3 also stops job-marked Cursor Shell sessions that detached from that group. Status exposes cleanup.method and cleanup.complete; terminal receipts are written after cleanup. Cleanup failure is interrupted, never a successful run. Non-Linux hosts retain process-group-only cleanup. The marker is lifecycle ownership, not a security sandbox or protection against hostile workers. No PID supplied by a client is ever signalled. Unknown/cross-project handles fail; a dead supervisor without a terminal receipt is interrupted, never a pass.

Private job input, status, result and runner logs live in .odw/.jobs/. Gitignore that directory as well as workflow run artifacts: they can contain prompts/results. No credentials or environment snapshot are written by the job controller. This is POSIX process supervision, not a security sandbox, VM-restart recovery, or strict Advisor attestation. A lost VM cannot be made durable by this adapter; preserve/inspect its evidence before a fresh run.

Run npm run verify:long for a packaged >60-second process/worktree fixture. It uses fake model CLIs; a real Grok Bot run is a separate release acceptance.