Skip to content
Development
Skill

/mass-ulw

Drives dependency-ordered child work through the native workflow tool, one run per phase with retry/amend/send recovery. Use when the user asks for mass-ulw, a DAG of tasks, or fan-out work where some tasks must wait on others.

From plugin
code-yeongyu-oh-my-openagent
69k31 skills1 agent4 MCP
Install
$ npx -y skills add code-yeongyu/oh-my-openagent --skill mass-ulw --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/mass-ulw

Context preview

The summary Claude sees to decide when to auto-load this skill.

Drives dependency-ordered child work through the native workflow tool, one run per phase with retry/amend/send recovery. Use when the user asks for mass-ulw, a DAG of tasks, or fan-out work where some tasks must wait on others.

SKILL.md

mass-ulw.SKILL.md
name: mass-ulw
description: "Drives dependency-ordered child work through the native workflow tool, one run per phase with retry/amend/send recovery. Use when the user asks for mass-ulw, a DAG of tasks, or fan-out work where some tasks must wait on others."
metadata:
  short-description: Dependency-graph orchestration of child agents

mass-ulw

Use this skill when the user asks for `mass-ulw`, a task DAG, staged fan-out, or any multi-agent job where real dependencies exist: task C needs A and B finished first. For fully independent workers, plain parallel `task` spawns are simpler. Reach for `workflow` when the ordering itself is the point. A run covers ONE phase's dependency-ordered lanes and NEVER a whole multi-phase job; define the next phase as a NEW run (or `amend` when only the definition changed) in the cell from what the settled run proved. Under `ulw-loop` or `ulw-execute`, that contract owns the goal, criteria, evidence, and checkpoints; this skill owns only how each phase's run is defined, driven, and recovered.

Planning - MANDATORY first step

Before defining ANY graph, read `references/planning.md` (relative to this skill's own directory) IN FULL. Do not call `sdk.define`, `sdk.start`, or `tool.workflow` with `action: "start"` before reading it. It carries the working doctrine this file deliberately omits: how to decompose the request into nodes, how to route each node's `category`, how to keep parallel write scopes disjoint, the node prompt contract, the verification wave, and the failure playbook. A graph defined without it is unplanned work.

The shape

A run is a declarative definition: a stable `key` (idempotency: re-starting the same key with the same graph reuses the run), a human `name`, and `nodes`. Each node has an `id`, a self-contained English `prompt`, a `category` that routes it to the right kind of worker, and optional `dependsOn` listing node ids that must finish first. `dependsOn` is ordering ONLY: no upstream output is substituted into a downstream prompt, so write every prompt to stand alone. Optional per-node extras: `label`, `task_summary`, `description`, and `load_skills` (skill names prepended to that node's prompt).

Route every node by `category` using the routing table in `references/planning.md`; the run executes nodes in parallel waves as their dependencies clear.

Goal before start

Every run is goal-bound. In a standalone run, register the goal as written (`create_goal`, or a `# Goal` block where no goal tool exists). Under `ulw-loop` or `ulw-execute`, the loop's registered goal already covers the run, so register no second goal. The objective names the deliverable the graph produces, and the success criteria carry RESULT VERIFICATION - node and run completion claims are false until proven against captured evidence, the same contract the dag completion directive injects (TREAT AS FALSE UNTIL YOU PROVE IT). The verification wave (references/planning.md) produces the evidence those criteria name; the run ends when the criteria pass, never when the last node reports completion.

Running a dag - eval is the default

Build and run every dag INSIDE an eval cell. The eval kernel installs the `tool.workflow` proxy and the extension publishes a small JS SDK at `OMO_DAG_SDK_ROOT`; driving runs from a cell is what unlocks the orchestration patterns in `references/planning.md` (data-driven graph construction, multi-run composition, concurrent runs, adaptive retries).

JS cells import the SDK from the path the extension publishes:

const sdk = await import(`${env("OMO_DAG_SDK_ROOT")}/sdk.js`)

const dag = sdk.define({ key: "docs-refresh", name: "Docs refresh" })
dag.node({ id: "audit", category: "unspecified-low", prompt: "Audit docs/ for stale API references and list each stale file with the outdated claim." })
dag.node({ id: "rewrite", category: "writing", prompt: "Rewrite every stale page under docs/ against the current API surface in src/.", dependsOn: ["audit"] })
dag.node({ id: "verify", category: "quick", prompt: "Check every code sample under docs/ compiles and every internal link resolves.", dependsOn: ["rewrite"] })

const run = await sdk.start(dag)
const result = await sdk.wait(run.run_id)

`define` builds the definition and rejects duplicate node ids locally, before anything is started. `start`, `attach`, `snapshot`, `wait`, and `cancel` are the whole surface.

Python cells cannot import the ESM SDK; call `tool.workflow({...})` directly with the same payload shape the SDK produces - note the SDK passes `detach: false` on `wait`, so a blocking Python wait is `tool.workflow({"action": "wait", "run_id": run_id, "detach": False})`; without it the tool detaches against a live run and returns the current snapshot. Prefer a JS cell whenever the run involves any orchestration beyond a single `start` + `wait`.

Run lifecycle

`start` returns a `run_id` and a snapshot; keep the id. From there:

const sdk = await import(`${env("OMO_DAG_SDK_ROOT")}/sdk.js`)
const runId = "run_stub_1"
await sdk.attach(runId)
await sdk.snapshot(runId)
await sdk.cancel(runId, "superseded by a new plan")
  • `attach` re-binds to a live run you already own, for example after your own context was rebuilt.
  • `start` returns at once; node completions and settle wake the session, and each wake carries the TREAT-AS-FALSE verification directive. Do independent work between wakes.
  • `snapshot` is a one-off read of status and node counts when a midpoint decision needs it, never a polling loop.
  • `wait` blocks the cell until the run settles (the SDK passes `detach: false`; the bare tool action detaches by default against a live run). Use it only inside a detached cell or when nothing else remains.
  • `cancel` stops the run; pass a reason so the record says why.

Recovering one node - retry, send, amend

A settled run is not a dead end. Three verbs act on a SINGLE node, so one bad node never costs you the whole graph, and every node that alrea

Read more
Ships withcode-yeongyu-oh-my-openagent

You're juggling Claude Code, Codex, and random OSS models. Configuring workflows. Debugging agents. We did the work. Tested everything. Kept what actually shipped. Install oh-my-openagent. Type ultrawork. Done.

Get the whole plugin
Stats
69,112
Stars
5,688
Forks
Active
Maintenance
TypeScript
Language
23h ago
Last commit
9mo ago
Created

Repo: code-yeongyu/oh-my-openagent