Agent skill

Output Dev Step Function

by growthxai in growthxai/output

Create step functions in steps.ts for Output SDK workflows. An agent skill from growthxai/output.

Apache-2.0Auto-check passed

Install Output Dev Step Function

skills CLI
$ npx skills add growthxai/output --skill output-dev-step-function -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install growthxai/output output-dev-step-function --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/growthxai/output.git skills-src && mkdir -p .claude/skills && cp -r skills-src/coding_assistants/claude/plugins/outputai/skills/output-dev-step-function .claude/skills/output-dev-step-function && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
output-dev-step-function
GitHub stars
440
Token cost
~4.3k tokens
SKILL.md length
691 words
Files
1
Skills in repo
52
Repo updated
First seen
Licence
Apache-2.0

At a glance

Create step functions in steps.ts for Output SDK workflows. An agent skill from growthxai/output.

  • Works in 3 steps: One Responsibility Per Step → Clear Error Messages → Validate Input Early
  • Implementing I/O operations
  • SKILL.md covers Overview, When to Use This Skill, File Organization and Component Location Rules, plus 6 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Output Dev Step Function is an agent skill from growthxai/output. Create step functions in steps.ts for Output SDK workflows. Use when implementing I/O operations, error handling, HTTP requests, or LLM calls.

Its SKILL.md is about 4.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

The repository describes itself as: The open-source TypeScript framework for building AI workflows and agents. Designed for Claude Code describe what you want, Claude builds it, with all the best practices already… The licence is Apache-2.0.

When your agent uses it

  • Implementing I/O operations

Example prompts

  • “/output-dev-step-function”

Requirements

  • Pre-approved tools (allowed-tools): Read, Write, Edit

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. One Responsibility Per Step
  2. Clear Error Messages
  3. Validate Input Early

What it can do on your machine

Read from SKILL.md and the folder at commit 52b51ac. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Read
    • Write
    • Edit

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Output Dev Step Function loads about 4.3k tokens when it runs. Until then it costs about 42 tokens; SKILL.md has 691 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~42
When it runs · the whole SKILL.md, loaded when a task matches
~4.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from growthxai/output at commit 52b51ac, republished under its Apache-2.0 licence (© growthxai). 691 words, ~4,257 tokens.

Download SKILL.mdSave it as .claude/skills/output-dev-step-function/SKILL.md (or your agent's skills folder).
name
output-dev-step-function
description
Create step functions in steps.ts for Output SDK workflows. Use when implementing I/O operations, error handling, HTTP requests, or LLM calls.
allowed-tools
Read, Write, Edit

Creating Step Functions

Overview

This skill documents how to create step functions in steps.ts for Output SDK workflows. Steps are where all I/O operations happen - HTTP requests, LLM calls, database operations, file system access, etc.

When to Use This Skill

  • Implementing I/O operations for a workflow
  • Adding HTTP client integrations
  • Implementing LLM-powered steps
  • Handling errors with FatalError and ValidationError
  • Creating reusable step components

File Organization

Option 1: Flat File (Default)

For smaller workflows, use a single steps.ts file:

src/workflows/{workflow-name}/
├── workflow.ts
├── steps.ts         # All steps in one file
├── types.ts
└── ...
Option 2: Folder-Based (Large workflows)

For larger workflows with many steps, use a steps/ folder:

src/workflows/{workflow-name}/
├── workflow.ts
├── steps/           # Steps split into individual files
│   ├── fetch_data.ts
│   ├── process.ts
│   └── validate.ts
├── types.ts
└── ...

Component Location Rules

Important: step() calls MUST be in files containing 'steps' in the path:

  • src/workflows/my_workflow/steps.ts ✓
  • src/workflows/my_workflow/steps/fetch_data.ts ✓
  • src/shared/steps/common_steps.ts ✓
  • src/workflows/my_workflow/helpers.ts ✗ (cannot contain step() calls)

Activity Isolation Constraints

Steps are Temporal activities with strict import rules to ensure deterministic replay.

Steps CAN import from:
  • Local workflow files: ./utils.js, ./types.js, ./helpers.js
  • Local subdirectories: ./clients/pokeapi.js, ./lib/helpers.js
  • Shared utilities: ../../shared/utils/*.js
  • Shared clients: ../../shared/clients/*.js
  • Shared services: ../../shared/services/*.js
Steps CANNOT import:
  • Other step files (even shared steps - workflows import those)
  • Evaluator files
  • Workflow files

Example of WRONG imports:

typescript
// WRONG - steps cannot import other steps
import { otherStep } from '../../shared/steps/other.js'; // ✗
import { anotherStep } from './other_steps.js'; // ✗

Critical Import Patterns

Core Imports
typescript
// CORRECT - Import from @outputai/core
import { step, z, FatalError, ValidationError } from '@outputai/core';

// WRONG - Never import z from zod
import { z } from 'zod';
HTTP Client Import
typescript
// CORRECT - Use @outputai/http wrapper
import { createKyClient } from '@outputai/http';

// WRONG - Never use axios directly
import axios from 'axios';

Related Skill: output-error-http-client

LLM Client Import
typescript
// CORRECT - Use @outputai/llm wrapper
import { generateText, aiSdk } from '@outputai/llm';

// WRONG - Never call LLM providers directly
import OpenAI from 'openai';
ES Module Imports

All imports MUST use .js extension:

typescript
// CORRECT
import { InputSchema, OutputSchema } from './types.js';
import { GeminiService } from '../../shared/clients/gemini_client.js';

// WRONG - Missing .js extension
import { InputSchema, OutputSchema } from './types';

Basic Structure

typescript
import { step, z, FatalError, ValidationError } from '@outputai/core';
import { createKyClient } from '@outputai/http';
import { generateText, aiSdk } from '@outputai/llm';

import { StepInputSchema, StepOutputSchema } from './types.js';

export const myStep = step( {
  name: 'myStep',
  description: 'Description of what this step does',
  inputSchema: StepInputSchema,
  outputSchema: StepOutputSchema,
  fn: async input => {
    // Implementation with I/O operations
    return { /* output matching outputSchema */ };
  }
} );

Required Properties

name (string)

Unique identifier for the step. Use camelCase.

typescript
name: 'generateImageIdeas'
description (string)

Human-readable description of the step's purpose.

typescript
description: 'Generate creative infographic prompt ideas using Claude'
inputSchema (Zod schema)

Schema for validating step input. Define in types.ts and import.

typescript
inputSchema: z.object( {
  content: z.string(),
  numberOfIdeas: z.number()
} )
outputSchema (Zod schema)

Schema for validating step output. Define in types.ts and import.

typescript
outputSchema: z.array( z.string() )
fn (async function)

The step execution function. This is where I/O operations happen.

typescript
fn: async input => {
  const result = await someExternalService( input );
  return result;
}

HTTP Client Usage

Creating an HTTP Client
typescript
import { createKyClient } from '@outputai/http';
import { FatalError, ValidationError } from '@outputai/core';

const RETRY_STATUS_CODES = [ 408, 429, 500, 502, 503, 504 ];
const FATAL_STATUS_CODES = [ 401, 403, 404 ];

const client = createKyClient( {
  timeout: 30000,
  retry: {
    limit: 3,
    statusCodes: RETRY_STATUS_CODES
  },
  hooks: {
    beforeError: [
      ( { error } ) => {
        const status = error.response?.status;
        const message = error.message;

        if ( status && FATAL_STATUS_CODES.includes( status ) ) {
          throw new FatalError(
            `HTTP ${status} error: ${message}. This is a permanent error.`
          );
        }

        throw new ValidationError(
          `HTTP request failed: ${message}`
        );
      }
    ]
  }
} );
Making HTTP Requests
typescript
// GET request
const response = await client.get( 'https://api.example.com/data' );
const data = await response.json();

// POST request with JSON body
const response = await client.post( 'https://api.example.com/submit', {
  json: { field: 'value' }
} );

// HEAD request (check URL accessibility)
const response = await client.head( url );
const contentType = response.headers.get( 'content-type' );

When a non-HEAD request only uses response metadata, such as response.url, response.status, or headers, cancel the unused body in a finally block. Responses read with .json(), .text(), etc. are already consumed.

typescript
const response = await client.get( url );

try {
  return response.url;
} finally {
  await response.body?.cancel();
}

Related Skill: output-dev-http-client-create for creating shared clients

LLM Operations

Important: Define LLM Schemas in types.ts

Schemas used in aiSdk.Output.object() must be defined in types.ts and imported -- never defined inline in step functions. Inline schemas lead to duplication, drift between the step's outputSchema and the LLM schema, and make it harder to maintain types.

typescript
// WRONG - inline schema in aiSdk.Output.object()
output: aiSdk.Output.object( {
  schema: z.object( {
    analysis: z.string()
  } )
} )

// CORRECT - import from types.ts
import { AnalysisLlmSchema } from './types.js';
// ...
output: aiSdk.Output.object( {
  schema: AnalysisLlmSchema
} )
Using generateText with aiSdk.Output.object()

The variables field accepts scalars, nested objects, and arrays. Use Liquid loops and dot notation in the prompt when it owns presentation; pre-format in the step when the exact rendered text is application logic.

generateText arguments: prompt, promptDir, variables, tools, output, toolChoice, stopWhen, abortSignal.

typescript
import { generateText, aiSdk } from '@outputai/llm';
import {
  AnalyzeContentInputSchema,
  AnalyzeContentOutputSchema,
  AnalysisLlmSchema
} from './types.js';

export const analyzeContent = step( {
  name: 'analyzeContent',
  description: 'Analyze content using Claude',
  inputSchema: AnalyzeContentInputSchema,
  outputSchema: AnalyzeContentOutputSchema,
  fn: async ( { content } ) => {
    const { output } = await generateText( {
      prompt: 'analyzeContent@v1',
      variables: {
        content
      },
      output: aiSdk.Output.object( {
        schema: AnalysisLlmSchema
      } )
    } );

    return { analysis: output.analysis };
  }
} );
Using generateText
typescript
import { generateText } from '@outputai/llm';
import { SummarizeInputSchema, SummarizeOutputSchema } from './types.js';

export const generateSummary = step( {
  name: 'generateSummary',
  description: 'Generate a text summary',
  inputSchema: SummarizeInputSchema,
  outputSchema: SummarizeOutputSchema,
  fn: async ( { content } ) => {
    const { result } = await generateText( {
      prompt: 'summarize@v1',
      variables: { content }
    } );

    return { summary: result };
  }
} );

Related Skill: output-dev-prompt-file for creating prompt files

Show full SKILL.md (283 more words)Show less
Streaming LLM Progress

Prefer generateTextWithStreaming() in steps when the caller needs progress callbacks and a complete result:

typescript
import { generateTextWithStreaming } from '@outputai/llm';

const reportProgress = ( chunk: string ) => process.stdout.write( chunk );

const result = await generateTextWithStreaming( {
  prompt: 'summarize@v1',
  variables: { content },
  onChunk( { chunk } ) {
    if ( chunk.type === 'text-delta' ) {
      reportProgress( chunk.text );
    }
  }
} );

return result.result;

The returned promise rejects on stream failures, allowing Temporal to retry the activity. Use streamText() only when direct stream access is required; capture onError and throw the captured error after consumption. See output-dev-llm-streaming for complete patterns.

Error Handling

FatalError (Non-Retryable)

Use FatalError for permanent failures that should not be retried:

typescript
import { FatalError } from '@outputai/core';
import { credentials } from '@outputai/core/credentials';

// Authentication failures
if ( response.status === 401 ) {
  throw new FatalError( 'Invalid API key' );
}

// Invalid input that cannot be fixed by retry
if ( !input.requiredField ) {
  throw new FatalError( 'Missing required field: requiredField' );
}

// Resource not found
if ( response.status === 404 ) {
  throw new FatalError( `Resource not found: ${resourceId}` );
}

// Configuration errors
if ( !credentials.get( 'service.api_key' ) ) {
  throw new FatalError( 'service.api_key credential not set' );
}
ValidationError (Retryable)

Use ValidationError for temporary failures that may succeed on retry:

typescript
import { ValidationError } from '@outputai/core';

// Rate limiting
if ( response.status === 429 ) {
  throw new ValidationError( 'Rate limit exceeded, will retry' );
}

// Temporary service unavailability
if ( response.status === 503 ) {
  throw new ValidationError( 'Service temporarily unavailable' );
}

// Network errors
try {
  const response = await client.get( url );
} catch ( error ) {
  throw new ValidationError( `Network error: ${error.message}` );
}

// Empty response that might be temporary
if ( results.length === 0 ) {
  throw new ValidationError( 'No results returned, will retry' );
}

Related Skill: output-error-try-catch for proper error handling patterns

Complete Example

Based on a real workflow step:

typescript
import { step, z, FatalError, ValidationError } from '@outputai/core';
import { createKyClient } from '@outputai/http';
import { generateText, aiSdk } from '@outputai/llm';

import { GeminiImageService } from '../../shared/clients/gemini_client.js';
import {
  GenerateImageIdeasInputSchema,
  GenerateImagesInputSchema,
  ImageIdeasSchema
} from './types.js';

const RETRY_STATUS_CODES = [ 408, 429, 500, 502, 503, 504 ];
const FATAL_STATUS_CODES = [ 401, 403, 404 ];

const client = createKyClient( {
  timeout: 30000,
  retry: {
    limit: 3,
    statusCodes: RETRY_STATUS_CODES
  },
  hooks: {
    beforeError: [
      ( { error } ) => {
        const status = error.response?.status;
        const message = error.message;

        if ( status && FATAL_STATUS_CODES.includes( status ) ) {
          throw new FatalError( `HTTP ${status} error: ${message}` );
        }

        throw new ValidationError( `HTTP request failed: ${message}` );
      }
    ]
  }
} );

// Step 1: Generate Ideas using LLM
export const generateImageIdeas = step( {
  name: 'generateImageIdeas',
  description: 'Generate creative infographic prompt ideas using Claude',
  inputSchema: GenerateImageIdeasInputSchema,
  outputSchema: z.array( z.string() ),
  fn: async ( { content, numberOfIdeas, colorPalette, artDirection } ) => {
    const { output } = await generateText( {
      prompt: 'generateImageIdeas@v1',
      variables: {
        content,
        numberOfIdeas,
        colorPalette: colorPalette || '',
        artDirection: artDirection || ''
      },
      output: aiSdk.Output.object( {
        schema: ImageIdeasSchema
      } )
    } );

    return output.ideas;
  }
} );

// Step 2: Generate Images using external API
export const generateImages = step( {
  name: 'generateImages',
  description: 'Generate images using Gemini API',
  inputSchema: GenerateImagesInputSchema,
  outputSchema: z.array( z.string() ),
  fn: async ( { input, prompt } ) => {
    const geminiImageService = new GeminiImageService();

    const generatedImages = await geminiImageService.generateImage( {
      prompt,
      aspectRatio: input.aspectRatio,
      resolution: input.resolution,
      numberOfImages: input.numberOfGenerations
    } );

    if ( generatedImages.length === 0 ) {
      throw new ValidationError( 'No images were generated by Gemini' );
    }

    return generatedImages;
  }
} );

// Step 3: Validate URLs using HTTP client
export const validateReferenceImages = step( {
  name: 'validateReferenceImages',
  description: 'Validates that all provided reference image URLs are accessible',
  inputSchema: z.object( {
    referenceImageUrls: z.array( z.string() ).optional()
  } ),
  outputSchema: z.boolean(),
  fn: async ( { referenceImageUrls } ) => {
    if ( !referenceImageUrls || referenceImageUrls.length === 0 ) {
      return true;
    }

    for ( const [ index, url ] of referenceImageUrls.entries() ) {
      const response = await client.head( url );
      const contentType = response.headers.get( 'content-type' );

      if ( contentType && !contentType.startsWith( 'image/' ) ) {
        throw new FatalError(
          `Reference URL ${index + 1} (${url}) is not an image file`
        );
      }
    }

    return true;
  }
} );

Best Practices

1. One Responsibility Per Step
typescript
// Good - focused step
export const fetchUserData = step( {
  name: 'fetchUserData',
  description: 'Fetch user data from the API'
  // ...
} );

// Avoid - step doing too much
export const fetchAndProcessAndSaveUserData = step( {
  name: 'fetchAndProcessAndSaveUserData'
  // ...
} );
2. Clear Error Messages
typescript
// Good - specific error message
throw new FatalError( `Invalid API key for service: ${serviceName}` );

// Avoid - generic error message
throw new FatalError( 'Error occurred' );
3. Validate Input Early
typescript
fn: async input => {
  if ( !input.url.startsWith( 'https://' ) ) {
    throw new FatalError( 'URL must use HTTPS protocol' );
  }

  const response = await client.get( input.url );
  // ...
}

Verification Checklist

  • step, z, FatalError, ValidationError imported from @outputai/core
  • createKyClient imported from @outputai/http (not axios)
  • generateText and aiSdk imported from @outputai/llm (not direct provider)
  • Structured output uses aiSdk.Output.object() with .describe() (not .min()/.max()/.length()) on number and array schemas
  • Schemas for aiSdk.Output.object() are defined in types.ts and imported, not inline
  • All imports use .js extension
  • Named exports used for each step
  • Each step has name, description, inputSchema, outputSchema, fn
  • FatalError used for non-retryable failures
  • ValidationError used for retryable failures
  • Non-HEAD HTTP responses are consumed or cancelled when only metadata is used
  • No bare try-catch blocks that swallow errors
  • Steps only import allowed dependencies (local files, shared code)
  • No imports of other steps, evaluators, or workflows
  • Code follows style conventions (see output-dev-code-style)
  • output-dev-workflow-function - Orchestrating steps in workflow.ts
  • output-dev-evaluator-function - Using steps in evaluator functions
  • output-dev-types-file - Defining step input/output schemas
  • output-dev-code-style - Code formatting and style conventions
  • output-dev-http-client-create - Creating shared HTTP clients
  • output-dev-llm-streaming - Streaming LLM progress with Temporal-safe failures
  • output-dev-prompt-file - Creating prompt files for LLM operations
  • output-error-try-catch - Proper error handling patterns
  • output-error-direct-io - Avoiding direct I/O in workflows

© growthxai, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in coding_assistants/claude/plugins/outputai/skills/output-dev-step-function of growthxai/output.

Open the folder on GitHubat commit 52b51ac

Compare with similar skills

Output Dev Step Function next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Output Dev Step Function compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Output Dev Step Function this skillgrowthxai/output440—~4.3kAutomated safety check: PassApache-2.0
Step Functions Workflowjeremylongshore/tons-of-skills-marketplace2.8k—~562Automated safety check: PassMIT
AWS Step Functionsaws/agent-toolkit-for-aws2.8k—~3.4kAutomated safety check: PassApache-2.0
Step Functionsitsmostafa/aws-agent-skills1.2k—~2.4kAutomated safety check: PassMIT
Processing S3 Uploads With Step Functionsaws/agent-toolkit-for-aws2.8k—~4kAutomated safety check: PassApache-2.0
AWS Step Functionsawslabs/agent-plugins915—~1.9kAutomated safety check: PassApache-2.0

Similar skills

  • Step Functions Workflow

    jeremylongshore/tons-of-skills-marketplace

    Manage step functions workflow operations. An agent skill from jeremylongshore/tons-of-skills-marketplace.

    2.8k GitHub stars~562 tokensUpdated today
    DevOps & CloudAuto-check passed
  • AWS Step Functions

    aws/agent-toolkit-for-aws

    Official

    Authors and edits AWS Step Functions state machines: writes Amazon States Language (ASL) in JSONata, and chooses and structures state types (Task, Choice, Map, Parallel, Pass, Wait, Succeed, Fail).

    2.8k GitHub stars~3.4k tokensUpdated today
    Backend & APIsAuto-check passed
  • Step Functions

    itsmostafa/aws-agent-skills

    AWS Step Functions workflow orchestration with state machines.

    1.2k GitHub stars~2.4k tokensUpdated 2 days ago
    DevelopmentAuto-check passed
  • Official

    Deploy an event-driven workflow that routes S3 uploads to either Lambda or Fargate via Step Functions based on file size.

    2.8k GitHub stars~4k tokensUpdated today
    Backend & APIsAuto-check passed
  • AWS Step Functions

    awslabs/agent-plugins

    Official

    Build workflows with AWS Step Functions state machines using the JSONata query language.

    915 GitHub stars~1.9k tokensUpdated 2 days ago
    Data & AnalyticsAuto-check passed
  • Os Step By Step

    kharmanskyi/open-steps

    ALWAYS invoke this skill when you need the user to act - run a command, paste a secret, click, approve - and whenever they ask how to do something or say they do not know what to do: "step by step"…

    1.2k GitHub stars~1.9k tokensUpdated 2 days ago
    Writing & ContentAuto-check passed

More from growthxai/output

All 52 skills in this repo
  • Zod schema constraints that Anthropic rejects or silently ignores when sent as structured-output tool definitions via aiSdk.Output.object().

    440 GitHub stars~597 tokensUpdated today
    Auto-check passed
  • Output Build Workflow

    growthxai/output

    Implement an Output SDK workflow from a plan document. An agent skill from growthxai/output.

    440 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Output Credentials Edit

    growthxai/output

    View, edit, and set encrypted credentials in an Output.ai project.

    440 GitHub stars~1.1k tokensUpdated today
    Auto-check: notes
  • Wire encrypted credentials to environment variables using the credential: convention.

    440 GitHub stars~930 tokensUpdated today
    Auto-check: notes
  • Output Credentials Init

    growthxai/output

    Initialize encrypted credentials for an Output.ai project. An agent skill from growthxai/output.

    440 GitHub stars~803 tokensUpdated today
    Auto-check: notes
  • Output Debug Workflow

    growthxai/output

    Debug Output SDK workflow issues. An agent skill from growthxai/output.

    440 GitHub stars~1.5k tokensUpdated today
    Auto-check passed

Questions about Output Dev Step Function

What does Output Dev Step Function do?

Create step functions in steps.ts for Output SDK workflows. An agent skill from growthxai/output. Output Dev Step Function is an agent skill from growthxai/output.ts for Output SDK workflows.

When should I use Output Dev Step Function?

Output Dev Step Function fits situations like: implementing I/O operations.

How do I install Output Dev Step Function in Claude Code?

Run `npx skills add growthxai/output --skill output-dev-step-function -a claude-code`. Or copy the skill folder (coding_assistants/claude/plugins/outputai/skills/output-dev-step-function in growthxai/output) into .claude/skills/output-dev-step-function in your project. Claude Code loads it when a task matches its description.

How do I install Output Dev Step Function in Codex?

Run `npx skills add growthxai/output --skill output-dev-step-function -a codex`. Or copy the skill folder (coding_assistants/claude/plugins/outputai/skills/output-dev-step-function in growthxai/output) into .agents/skills/output-dev-step-function in your project. Codex loads it when a task matches its description.

Can I use Output Dev Step Function in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add growthxai/output --skill output-dev-step-function -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/output-dev-step-function, .gemini/skills/output-dev-step-function, .github/skills/output-dev-step-function and .opencode/skills/output-dev-step-function in your project.

What does Output Dev Step Function need to run?

SKILL.md names no scripts, command-line tools or credentials: Output Dev Step Function is instructions for the agent only. Its frontmatter pre-approves these tools: Read, Write, Edit.

Does Output Dev Step Function access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Output Dev Step Function safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Output Dev Step Function use?

Output Dev Step Function is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Output Dev Step Function use?

About 4.3k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Output Dev Step Function?

Skills that share tags, products or a category with Output Dev Step Function: Step Functions Workflow (jeremylongshore/tons-of-skills-marketplace, 2.8k stars), AWS Step Functions (aws/agent-toolkit-for-aws, 2.8k stars), Step Functions (itsmostafa/aws-agent-skills, 1.2k stars) and Processing S3 Uploads With Step Functions (aws/agent-toolkit-for-aws, 2.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Output Dev Step Function?

growthxai (a GitHub organization) maintains it in growthxai/output, which has 440 GitHub stars. The repository holds 52 skills in this directory. The repository was last updated on October 7, 2026.

Source: growthxai/output on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.