Flow: Scan library → Match or Design → Generate script → Execute → Persist
Generated scripts accumulate at ~/.maestro/workflows/dynamic/uwf-*.js,
building a reusable library over time.
Adversarial depth levels:
| Level | Decision Pattern | Agent Cost |
|---|---|---|
shallow |
Single skeptic per decision | +1 per decision |
standard |
3-vote majority per decision (default) | +4 per decision |
deep |
Cross-verify + 3-way advocacy + meta-skeptic | +8 per decision |
Parse:
--name <slug> → 指定生成脚本名(默认从 intent 自动生成)
--depth <level> → shallow | standard | deep(默认 standard)
--dry-run → 只生成脚本,不执行
--from <script> → 基于已有脚本进行修改(uwf-xxx 或 wf-xxx)
--resume <runId> → 恢复之前的运行(透传给 Workflow)
Remaining → intent
Library locations:
- Fixed scripts:
~/.maestro/workflows/swarm/wf-*.js - Dynamic scripts:
~/.maestro/workflows/dynamic/uwf-*.js
<state_machine>
S_PARSE: → S_SCAN WHEN: intent parsed DO: A_PARSE_ARGS → END WHEN: no intent
S_SCAN: → S_DECIDE WHEN: matches found DO: A_SCAN_LIBRARY → S_DESIGN WHEN: no matches DO: A_SCAN_LIBRARY
S_DECIDE: → S_EXECUTE WHEN: user picks existing script DO: — → S_DESIGN WHEN: user wants new script DO: — → S_DESIGN WHEN: --from specified DO: —
S_DESIGN: → S_GENERATE DO: A_DESIGN_WORKFLOW
S_GENERATE: → S_EXECUTE WHEN: Write + node --check pass AND NOT --dry-run DO: A_GENERATE_SCRIPT → S_PERSIST WHEN: --dry-run (file already written) DO: A_GENERATE_SCRIPT → S_GENERATE WHEN: node --check fails (retry ≤2) DO: A_GENERATE_SCRIPT (fix & retry) → END WHEN: node --check fails after 2 retries DO: report E003
S_EXECUTE: → S_PERSIST WHEN: workflow completed DO: A_EXECUTE_WORKFLOW → END WHEN: workflow failed
S_PERSIST: → END DO: A_PERSIST_SCRIPT
A_PARSE_ARGS
- Extract flags:
--name,--depth,--dry-run,--from,--resume - Remaining text as intent
- depth default
standard - If
--resume, jump to S_EXECUTE (direct resume) - If
--from, locate source script path
A_SCAN_LIBRARY
Scan two directories, read each .js file's meta block to extract name、description、whenToUse:
- Fixed scripts: expand
~/.maestro/workflows/swarm/wf-*.jsto absolute path- Glob to find all matching files
- Read the first 10 lines of each file, extract
meta.name、meta.description、meta.whenToUse
- Dynamic scripts: expand
~/.maestro/workflows/dynamic/uwf-*.js- same as above
- Match scoring: for each script, evaluate the semantic relevance of its description/whenToUse to the intent
- Output:
- List of scripts with match > 70% (max 3)
- Each lists: name, description, scriptPath, match reason
- If no match, jump directly to S_DESIGN
If there is a match, use ask_question to let the user choose:
- Options 1-3: use an existing script (with preview showing script meta)
- Last option: "Generate a brand-new script"
A_DESIGN_WORKFLOW
Analyze the task and determine the workflow structure. This is the core design step.
Step 1 — Task decomposition
Decompose the intent into:
work_items: 需要完成的具体工作单元
- { id, description, type: 'explore'|'analyze'|'create'|'verify'|'decide' }
decision_points: 需要做出判断的节点
- { id, question, type: 'go-nogo'|'pass-fail'|'select-best'|'resolve-conflict'|'assess-quality' }
data_flow: 数据在工作单元间如何流动
- { from, to, data_shape }
Step 2 — Phase orchestration
Organize work_items into execution phases:
phases: [
{ title, work_items[], parallel: true|false },
...
]
Rules:
- work_items with no dependencies go in the same phase (parallel)
- Those with dependencies go in subsequent phases
- Each decision_point is immediately followed by an adversarial decision phase
Step 3 — Adversarial mode selection
Select the adversarial mode based on decision_point.type and --depth (see ADVERSARIAL_PATTERNS):
| decision_type | shallow | standard | deep |
|---|---|---|---|
| go-nogo | 1 skeptic | 3-way advocacy + referee | cross-verify + 3-way advocacy + meta-skeptic |
| pass-fail | 1 challenger | prosecutor/defender/judge | cross-verify + prosecutor/defender + 3-vote |
| select-best | 1 critic | N proposals + judge panel | N proposals + judge + 3-critic challenge |
| resolve-conflict | 1 mediator | 3 philosophy proposals + arbitrator | 3 proposals + arbitrator + meta-skeptic |
| assess-quality | 1 skeptic | 3-vote (strict/lenient/objective) | cross-verify + 3-vote + meta-skeptic |
Step 4 — Schema design
Design a JSON Schema for each agent call:
- Work agent: task-specific schema
- Adversarial agent: use the standard adversarial schema (see ADVERSARIAL_PATTERNS)
Step 5 — Produce the blueprint
blueprint: {
name: 'uwf-{slug}',
description: string,
phases: [{ title, detail }],
agents: [{ id, prompt_outline, schema_name, agentType?, phase }],
adversarial_gates: [{ decision_id, pattern, agents[] }],
estimated_agent_count: number,
}
Show the blueprint summary to the user, including the estimated agent count.
If --dry-run then stop after S_GENERATE.
A_GENERATE_SCRIPT
Generate the complete JavaScript script based on the blueprint.Write the file first, then execute it via scriptPath(to avoid encoding/escaping issues with inline script strings).
If --from specifies a base script, first Read the source script, then modify it on that basis.
Script structure template:
export const meta = {
name: '{blueprint.name}',
description: '{English description}',
whenToUse: '{English usage scenario}',
phases: [
{ title: '{EnglishTitle}', detail: '{English detail}' },
],
}
// --- Schemas (top-level constants, never inline) ---
const WORK_SCHEMA = { type: 'object', properties: { ... }, required: [...] }
const CHALLENGE_SCHEMA = { ... }
// --- Args ---
const target = args?.target || 'default'
// --- Phase 1: {title} ---
phase('{title}')
const results = await parallel([
() => agent('prompt text', { label: 'work:1', phase: '{title}', schema: WORK_SCHEMA }),
])
// --- Phase 2: Adversarial Gate ---
phase('{adversarial_phase_title}')
// 对抗模式代码 — 从 ADVERSARIAL_PATTERNS 模板生成
return { ... }
Generation rules (all must be followed):
| # | Rule | Reason |
|---|---|---|
| 1 | Pure JavaScript — no TypeScript type annotations (: string、interface, generics) |
The parser does not support TS |
| 2 | meta block all in English — name、description、whenToUse、phases[].title/detail only ASCII characters |
Chinese triggers \uXXXX parse errors when the script string is serialized |
| 3 | Disable APIs — do not use Date.now()、Math.random(), no-arg new Date() |
breaks resume cache matching |
| 4 | Schemas declared independently — all JSON Schemas declared at the top of the file as const XXX_SCHEMA = {...}, referenced in agent calls with schema: XXX_SCHEMA references |
Inline large Schema is prone to bracket matching errors |
| 5 | Use + for string — for embedding variables in agent prompt use 'text ' + variable + ' more text',do not use template literals |
Backtick nesting and ${} escaping are the most common sources of parsing errors |
| 6 | Use function — array.filter(function(x) { return x }) for callbacks instead of arrow functions |
Arrow functions implicitly returning objects () => ({}) easily miss the outer parentheses |
| 7 | phase do not use as variable name — do not shadow the global phase() function |
After shadowing, phase('X') calls will crash |
| 8 | Use forward slashes for paths — use src/auth/ for paths in strings, do not use src\\auth\\ |
\a、\u etc., which are parsed as escape sequences |
| 9 | agentType — set only when there is a clear match (e.g., Explore、workflow-analyzer) |
Invalid agentType causes runtime errors |
| 10 | null safety — use ?.for chained access, add before array operations .filter(Boolean) |
When the agent returns null (user skips), chained calls crash |
Common error comparison:
// BAD — meta 中文导致 \uXXXX 解析错误
export const meta = { name: 'uwf-x', description: '参数审计' }
// GOOD
export const meta = { name: 'uwf-x', description: 'Parameter audit for unused/ambiguous/dead params' }
// BAD — 模板字符串嵌套
agent(`Analyze ${item.name} for ${reason}`)
// GOOD — 字符串拼接
agent('Analyze ' + item.name + ' for ' + reason)
// BAD — Schema 内联在 agent 调用中
agent('prompt', { schema: { type: 'object', properties: { a: { type: 'string' }, b: { type: 'array', items: { type: 'object', properties: { ... } } } } } })
// GOOD — Schema 顶部声明
const MY_SCHEMA = { type: 'object', properties: { a: { type: 'string' } }, required: ['a'] }
agent('prompt', { schema: MY_SCHEMA })
// BAD — 箭头函数隐式返回对象
results.map(r => ({ ...r, verified: true }))
// GOOD — function + 显式 return
results.map(function(r) { return Object.assign({}, r, { verified: true }) })
// BAD — 反斜杠路径
const path = 'C:\Users\project\src'
// GOOD
const path = 'C:/Users/project/src' // 或直接不在脚本中硬编码路径
Step 1 — Generate script content
Generate the complete JavaScript string according to the blueprint structure + the above rules. Chinese can be used inside the agent prompt (the prompt is a runtime string and does not affect parsing).
Step 2 — Write to file
write_to_file({
file_path: expandPath('~/.maestro/workflows/dynamic/uwf-{slug}.js'),
content: generatedScript
})
Step 3 — Syntax verification
run_command({ command: 'node --check "path/to/uwf-{slug}.js"' })
If verification fails:
- Read the line number and error type from the error message
- Fix accordingly (common: missing comma, bracket mismatch, reserved word conflict)
- Write again + verify (retry at most 2 times)
- If it still fails, report E003, showing the script content and error message
After verification passes, proceed to S_EXECUTE (if not --dry-run)。
A_EXECUTE_WORKFLOW
Must call with scriptPath(do not use inline script string):
Workflow({
scriptPath: expandPath('~/.maestro/workflows/dynamic/uwf-{slug}.js'),
args: taskSpecificArgs, // 从 intent 推断
resumeFromRunId: resumeId // 若有
})
Record the returned runId. The script has already been written to a file in A_GENERATE_SCRIPT; no need to persist it again.
A_PERSIST_SCRIPT
The script has already been written in A_GENERATE_SCRIPT Step 2 to ~/.maestro/workflows/dynamic/uwf-{slug}.js。
- Confirm the file exists (Glob check)
- Show the save path and usage method:
Saved: ~/.maestro/workflows/dynamic/uwf-{slug}.js Reuse: /maestro-universal-workflow --from uwf-{slug} "{new intent}" Resume: /maestro-universal-workflow --resume {runId} Via swarm: /maestro-swarm-workflow --script uwf-{slug}
</state_machine>
<adversarial_patterns>
The following is the code template library for adversarial decision modes. Select by decision_type and depth during A_GENERATE_SCRIPT.
PATTERN: Skeptic CrossVerify (shallow+)
Used for: challenging each item of parallel analysis results.
// 每个结果被 skeptic 挑战
const challenges = await pipeline(
results,
(result) => agent(
`You are an adversarial SKEPTIC. Challenge this assessment.
Original: ${JSON.stringify(result)}
Your job: find counter-evidence, check for biases, verify claims against actual code.
Default to challenge_result="weakened" if uncertain.`,
{ label: `challenge:${result.id}`, phase: '{phase}', schema: CHALLENGE_SCHEMA }
)
)
CHALLENGE_SCHEMA:
const CHALLENGE_SCHEMA = {
type: 'object',
properties: {
target: { type: 'string' },
challenge_result: { type: 'string', enum: ['confirmed', 'weakened', 'overturned'] },
adjusted_assessment: { type: 'string' },
counter_evidence: { type: 'array', items: { type: 'string' } },
confidence: { type: 'number', minimum: 0, maximum: 100 },
reasoning: { type: 'string' },
},
required: ['target', 'challenge_result', 'confidence', 'reasoning'],
}
PATTERN: 3-Way Advocacy + Referee (standard+ go-nogo)
Used for: go/no-go type decisions.
const advocacies = await parallel([
() => agent('You are the GO ADVOCATE. Argue FOR proceeding...', { label: 'advocate:go', schema: ADVOCACY_SCHEMA }),
() => agent('You are the NO-GO ADVOCATE. Argue AGAINST proceeding...', { label: 'advocate:nogo', schema: ADVOCACY_SCHEMA }),
() => agent('You are the CONDITIONAL ADVOCATE. Argue for proceeding ONLY under conditions...', { label: 'advocate:conditional', schema: ADVOCACY_SCHEMA }),
])
const decision = await agent('You are the REFEREE. Resolve the debate...', { label: 'referee', schema: DECISION_SCHEMA })
ADVOCACY_SCHEMA:
const ADVOCACY_SCHEMA = {
type: 'object',
properties: {
stance: { type: 'string' },
argument: { type: 'string' },
key_evidence: { type: 'array', items: { type: 'object', properties: { point: { type: 'string' }, strength: { type: 'string', enum: ['strong', 'moderate', 'weak'] } }, required: ['point'] } },
weaknesses_acknowledged: { type: 'array', items: { type: 'string' } },
conditions: { type: 'array', items: { type: 'string' } },
confidence: { type: 'number', minimum: 0, maximum: 100 },
},
required: ['stance', 'argument', 'confidence'],
}
PATTERN: Prosecutor/Defender/Judge (standard+ pass-fail)
Used for: pass/fail type determinations.
const debate = await parallel([
() => agent('You are the PROSECUTOR. Argue this should FAIL...', { label: 'prosecutor', schema: ARGUMENT_SCHEMA }),
() => agent('You are the DEFENDER. Argue this should PASS...', { label: 'defender', schema: ARGUMENT_SCHEMA }),
])
const verdict = await agent('You are the JUDGE. Resolve the debate...', { label: 'judge', schema: VERDICT_SCHEMA })
ARGUMENT_SCHEMA:
const ARGUMENT_SCHEMA = {
type: 'object',
properties: {
role: { type: 'string' },
stance: { type: 'string', enum: ['pass', 'fail'] },
argument: { type: 'string' },
key_points: { type: 'array', items: { type: 'object', properties: { point: { type: 'string' }, evidence: { type: 'string' }, strength: { type: 'string', enum: ['strong', 'moderate', 'weak'] } }, required: ['point', 'evidence'] } },
concessions: { type: 'array', items: { type: 'string' } },
confidence: { type: 'number', minimum: 0, maximum: 100 },
},
required: ['role', 'stance', 'argument', 'key_points', 'confidence'],
}
PATTERN: 3-Vote Majority (standard+ assess-quality)
Used for: quality assessment, status determination.
const votes = await parallel([
() => agent('You are the STRICT voter...', { label: 'vote:strict', schema: VOTE_SCHEMA }),
() => agent('You are the LENIENT voter...', { label: 'vote:lenient', schema: VOTE_SCHEMA }),
() => agent('You are the OBJECTIVE voter...', { label: 'vote:objective', schema: VOTE_SCHEMA }),
])
const majority = resolveVotes(votes) // majority wins, tie → objective
const report = await agent('Arbitrate final report from votes...', { label: 'arbitrate', schema: REPORT_SCHEMA })
VOTE_SCHEMA:
const VOTE_SCHEMA = {
type: 'object',
properties: {
perspective: { type: 'string' },
verdict: { type: 'string' },
rationale: { type: 'string' },
confidence: { type: 'number', minimum: 0, maximum: 100 },
},
required: ['perspective', 'verdict', 'rationale', 'confidence'],
}
PATTERN: Competing Proposals + Judge (standard+ select-best)
Used for: option selection.
const proposals = await parallel([
() => agent('Strategy A: ...', { label: 'proposal:A', schema: PROPOSAL_SCHEMA }),
() => agent('Strategy B: ...', { label: 'proposal:B', schema: PROPOSAL_SCHEMA }),
() => agent('Strategy C: ...', { label: 'proposal:C', schema: PROPOSAL_SCHEMA }),
])
const scores = await parallel(proposals.filter(Boolean).map(p => () =>
agent(`Score this proposal: ${p.strategy}...`, { label: `judge:${p.strategy}`, schema: SCORE_SCHEMA })
))
// select highest score
PATTERN: Meta-Skeptic (deep only)
Used for: challenging the challenger's own findings.
const metaChallenge = await agent(
`You are the META-SKEPTIC. Challenge the challengers themselves.
Findings: ${digest}
1. Which findings are OVERBLOWN? (theatrical, unlikely, missing context)
2. What did they MISS? (blind spots, interactions, real risks obscured)
3. Rate overall challenge quality (1-5).`,
{ label: 'meta-skeptic', schema: META_CHALLENGE_SCHEMA }
)
</adversarial_patterns>
Usage example
# 自动匹配或生成
/maestro-universal-workflow "评估数据库迁移方案的可行性和风险"
# 指定深度
/maestro-universal-workflow "审查 auth 模块的安全性" --depth deep
# 只生成不执行
/maestro-universal-workflow "对比 3 种缓存策略" --dry-run --name cache-eval
# 基于已有脚本修改
/maestro-universal-workflow "类似 analyze 但加入成本维度" --from wf-analyze
# 恢复之前的运行
/maestro-universal-workflow --resume wf_abc123
Generated script example
User intent: "Evaluate 3 API authentication options (JWT/OAuth2/API Key), select the best"
Generated script structure:
Phase 1: Explore — 探索代码库现有认证实现
Phase 2: Evaluate — 3 个 agent 分别深入评估每种方案
Phase 3: CrossVerify — skeptic 挑战每个评估结果
Phase 4: Compete — 3 个 advocate 各持一种方案立场辩论
Phase 5: Arbitrate — referee 根据辩论结果选出最优方案
Estimated number of agents: 1(explore) + 3(evaluate) + 3(cross-verify) + 3(advocates) + 1(referee) = 11
Relationship with swarm-workflow
| Dimension | swarm-workflow | universal-workflow |
|---|---|---|
| Script source | Fixed 8 pre-written scripts | Dynamically generated + accumulated library |
| Scope of application | Corresponds to 8 maestro commands | Any task |
| Decision mode | Hardcoded in script | Dynamically selected by depth |
| Persistence | No new script generated | Saved to dynamic/ for reuse |
| Recommended scenario | An existing matching standard command | Non-standard tasks, new domains |
When universal-workflow scans, it checks both the swarm/ and dynamic/ directories. If a swarm script has a high match score, it recommends using swarm-workflow instead.
Error Codes
| Code | Description | Recovery |
|---|---|---|
| E001 | No intent | Prompt the user for input |
| E002 | Unable to decompose the task during the design phase | Request a more specific intent |
| E003 | Generated script has syntax errors | node --check On failure: read the line number + error type → targeted fix → retry (up to 2 times) → if it still fails, show the script + error and let the user modify it manually |
| E004 | Workflow execution failed | Show the error, provide --resume |
| E005 | Persistence failed | Show the script content and let the user save it manually |