Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Implement an Output SDK workflow from a plan document. Use when the user asks to build, implement, or code a workflow from an existing plan, or after output-plan-workflow has produced a plan and the user is ready to build.
.claude/skills/growthxai-output-build-workflow/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 74% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 69% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 52% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 66% | 0% |
Your task is to implement an Output.ai workflow based on a provided plan document.
The workflow directory is provided as an argument (the workflow directory path). The workflow skeleton should already have been created there; if it has not, create it first.
Please read the plan file and implement the workflow according to its specifications.
Use the todo tool to track your progress through the implementation process.
Implement the workflow described in the plan document, following Output SDK patterns and best practices.
<pre_flight_check> EXECUTE: Claude Skill: output-meta-pre-flight </pre_flight_check>
<process_flow>
<step number="1" name="plan_analysis" subagent="workflow-context-fetcher">
Read and understand the plan document.
</step>
<step number="2" name="workflow_implementation" subagent="workflow-quality">
Update workflow.ts in the workflow directory with the workflow definition.
<implementation_checklist>
hasErrorType(error, ErrorClass) instead of instanceof (see output-error-try-catch)</implementation_checklist>
<workflow_template>
typescriptimport { workflow, z } from '@outputai/core'; import { stepName } from './steps.js'; const inputSchema = z.object( { // Define based on plan } ); const outputSchema = z.object( { // Define based on plan } ); export default workflow( { name: 'workflow-name-from-plan', description: 'Description from plan', inputSchema, outputSchema, fn: async input => { // Implement orchestration logic from plan const result = await stepName( input ); return { result }; } } );
</workflow_template>
</step>
<step number="3" name="steps_implementation" subagent="workflow-quality">
Update steps.ts in the workflow directory with all step definitions from the plan.
<implementation_checklist>
</implementation_checklist>
<step_template>
typescriptimport { step, z } from '@outputai/core'; export const stepName = step( { name: 'stepName', description: 'Description from plan', inputSchema: z.object( { // Define based on plan } ), outputSchema: z.object( { // Define based on plan } ), fn: async input => { // Implement step logic from plan return output; } } );
</step_template>
</step>
<step number="3.5" name="evaluators_implementation" subagent="workflow-quality">
If the plan includes evaluator functions, implement them in evaluators.ts in the workflow directory.
<decision_tree> IF plan_includes_evaluators: CREATE evaluators.ts IMPLEMENT evaluator functions per plan ELSE: SKIP to step 4 </decision_tree>
<implementation_checklist>
output-dev-eval-testing skill)</implementation_checklist>
<evaluator_template>
typescriptimport { evaluator, z, EvaluationBooleanResult } from '@outputai/core'; export const evaluateName = evaluator( { name: 'evaluate_name', description: 'Description from plan', inputSchema: z.object( { // Define based on plan } ), fn: async input => { // Implement evaluation logic from plan return new EvaluationBooleanResult( { value: true, confidence: 0.95, reasoning: 'Explanation of evaluation' } ); } } );
</evaluator_template>
</step>
<step number="4" name="prompt_templates" subagent="workflow-prompt-writer">
If the plan includes LLM-based steps, create prompt templates in the prompts/ subdirectory of the workflow directory.
<decision_tree> IF plan_includes_llm_steps: CREATE prompt_templates UPDATE steps.ts to use loadPrompt and generateText ELSE: SKIP to step 6 </decision_tree>
<llm_step_template>
typescriptimport { step, z } from '@outputai/core'; import { generateText } from '@outputai/llm'; export const llmStep = step( { name: 'llmStep', description: 'LLM-based step', inputSchema: z.object( { param: z.string() } ), outputSchema: z.string(), fn: async ( { param } ) => { const { result } = await generateText( { prompt: 'prompt_name@v1', variables: { param } } ); return result; } } );
</llm_step_template>
<prompt_file_template>
---
provider: anthropic
# current as of 2026-05-04 — run output-dev-model-selection for the latest
model: claude-sonnet-4-6
temperature: 0.7
---
<assistant>
You are a helpful assistant.
</assistant>
<user>
</user></prompt_file_template>
</step>
<step number="5" name="readme_update">
Update README.md in the workflow directory with workflow-specific documentation.
<documentation_requirements>
</documentation_requirements>
</step>
<step number="6" name="scenario_creation">
Create at least one scenario file in the scenarios/ subdirectory of the workflow directory for testing the workflow.
<scenario_requirements>
scenarios/ directory if it doesn't existtest_input.json with valid example input matching the inputSchema</scenario_requirements>
<scenario_template>
json{ // Populate with example values matching inputSchema // Use realistic test data that demonstrates the workflow }
</scenario_template>
<example> For a workflow with inputSchema:
typescriptz.object( { topic: z.string(), maxLength: z.number().optional() } )
Create scenarios/test_input.json:
json{ "topic": "The history of artificial intelligence", "maxLength": 500 }
</example>
</step>
<step number="7" name="validation" subagent="workflow-quality">
Verify the implementation is complete and correct.
<validation_checklist>
</validation_checklist>
</step>
<step number="8" name="post_flight_check">
Verify the implementation is ready for use.
<post_flight_check> EXECUTE: Claude Skill: output-meta-post-flight </post_flight_check>
</step>
</process_flow>
---- START ----
Use the workflow name, workflow directory, and plan file path provided as arguments, along with any additional instructions the user provided.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-11 | fail→fail | 12,114 | 7,996 | -34% | 1 | 1 | 0% | 2,050 | 3,592 | +75% | 0 | 0 | — |
case-05 | fail→pass | 12,776 | 8,859 | -31% | 1 | 1 | 0% | 2,177 | 3,796 | +74% | 0 | 0 | — |
case-01 | fail→fail | 5,225 | 6,347 | +21% | 1 | 1 | 0% | 302 | 2,624 | +769% | 0 | 0 | — |
case-02 | fail→fail | 4,441 | 7,697 | +73% | 1 | 1 | 0% | 238 | 2,632 | +1006% | 0 | 0 | — |
case-03 | fail→fail | 22,411 | 33,979 | +52% | 1 | 1 | 0% | 4,673 | 2,550 | -45% | 0 | 0 | — |
case-04 | pass→pass | 9,921 | 6,521 | -34% | 1 | 1 | 0% | 1,547 | 2,756 | +78% | 0 | 0 | — |
case-06 | fail→pass | 12,051 | 3,817 | -68% | 1 | 1 | 0% | 1,928 | 2,794 | +45% | 0 | 0 | — |
case-07 | fail→pass | 11,540 | 4,588 | -60% | 1 | 1 | 0% | 1,781 | 3,009 | +69% | 0 | 0 | — |
case-08 | fail→pass | 13,016 | 6,400 | -51% | 1 | 1 | 0% | 2,237 | 3,407 | +52% | 0 | 0 | — |
case-09 | fail→pass | 10,023 | 3,220 | -68% | 1 | 1 | 0% | 1,669 | 2,766 | +66% | 0 | 0 | — |
case-10 | fail→pass | 9,880 | 2,590 | -74% | 1 | 1 | 0% | 1,487 | 2,517 | +69% | 0 | 0 | — |
case-12 | pass→pass | 12,276 | 2,509 | -80% | 1 | 1 | 0% | 1,967 | 2,636 | +34% | 0 | 0 | — |
case-13 | fail→fail | 7,505 | 1,399 | -81% | 1 | 1 | 0% | 1,003 | 2,413 | +141% | 0 | 0 | — |
case-14 | fail→fail | 6,908 | 2,325 | -66% | 1 | 1 | 0% | 1,044 | 2,618 | +151% | 0 | 0 | — |
case-15 | fail→pass | 9,472 | 1,914 | -80% | 1 | 1 | 0% | 1,510 | 2,510 | +66% | 0 | 0 | — |
case-16 | fail→pass | 13,026 | 1,777 | -86% | 1 | 1 | 0% | 2,228 | 2,460 | +10% | 0 | 0 | — |
case-17 | fail→pass | 13,806 | 7,150 | -48% | 1 | 1 | 0% | 2,223 | 3,438 | +55% | 0 | 0 | — |
case-18 | fail→fail | 8,776 | 1,765 | -80% | 1 | 1 | 0% | 1,438 | 2,464 | +71% | 0 | 0 | — |
case-19 | fail→pass | 8,744 | 1,671 | -81% | 1 | 1 | 0% | 1,345 | 2,511 | +87% | 0 | 0 | — |
case-20 | pass→fail | 6,373 | 4,024 | -37% | 1 | 1 | 0% | 1,027 | 2,521 | +145% | 0 | 0 | — |
case-21 | pass→pass | 14,749 | 11,732 | -20% | 1 | 1 | 0% | 2,208 | 4,005 | +81% | 0 | 0 | — |
case-22 | pass→fail | 18,479 | 5,956 | -68% | 1 | 1 | 0% | 3,430 | 2,601 | -24% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 17 counted toward the lift figure. The other 5 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +36 percentage points is the difference between those two pass rates over the 17 comparable cases. 3 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.