Skip to content
Development
Skill

/output-dev-types-file

Create types.ts files with Zod schemas for Output SDK workflows. Use when defining input/output schemas, creating type definitions, or fixing schema-related errors.

From plugin
output
44451 skills5 agents

Claude Code

$ npx -y skills add growthxai/output --skill output-dev-types-file --agent claude-code

SKILL.md

output-dev-types-file.SKILL.md
name: output-dev-types-file
description: Create types.ts files with Zod schemas for Output SDK workflows. Use when defining input/output schemas, creating type definitions, or fixing schema-related errors.
allowed-tools: [Read, Write, Edit]

Creating types.ts Files with Zod Schemas

Overview

This skill documents how to create `types.ts` files for Output SDK workflows. These files contain Zod schemas for input/output validation and their corresponding TypeScript types.

When to Use This Skill

  • Creating a new workflow's type definitions
  • Adding new schemas for steps
  • Fixing schema validation errors
  • Refactoring existing type definitions

Critical Import Rule

**ALWAYS** import `z` from `@outputai/core`, **NEVER** from `zod` directly:

// CORRECT
import { z } from '@outputai/core';

// WRONG - will cause runtime errors
import { z } from 'zod';

**Related Skill**: `output-error-zod-import` for troubleshooting import issues

Basic Structure

import { z } from '@outputai/core';

// 1. Workflow Input Schema
export const WorkflowInputSchema = z.object( {
  // Define input fields
} );

// 2. Workflow Output Type
export type WorkflowInput = z.infer<typeof WorkflowInputSchema>;
export type WorkflowOutput = /* output type */;

// 3. Step Schemas (for each step)
export const StepNameInputSchema = z.object( {
  // Step input fields
} );

export const StepNameOutputSchema = z.object( {
  // Step output fields
} );

// 4. Type Exports
export type StepNameInput = z.infer<typeof StepNameInputSchema>;
export type StepNameOutput = z.infer<typeof StepNameOutputSchema>;

CRITICAL: Schema Constraints for LLM Output

Schemas passed to `aiSdk.Output.object()` are sent to LLM providers as tool definitions. **Anthropic rejects several JSON Schema constraints** that Zod methods produce. Getting this wrong causes runtime errors.

What Is NOT Allowed in LLM Output Schemas

  • **Numbers**: `.min()`, `.max()` on `z.number()` produce `minimum`/`maximum` -- rejected by Anthropic.
  • **Arrays**: `.min()`, `.max()`, `.length()` on `z.array()` produce `minItems`/`maxItems` -- Anthropic only supports `minItems` of `0` or `1`. Values like `.length( 3 )` or `.min( 2 )` will be rejected.

Use `.describe()` Instead

`.describe()` is the primary mechanism for guiding LLM output quality. LLM providers use field names and descriptions from the schema to understand what each field should contain. Write clear, specific descriptions that communicate your intent.

**Important**: `.describe()` replaces both unsupported constraints AND prompt-based format instructions. Do not also describe the schema in the prompt -- the schema is sent to the provider automatically, and duplicating it reduces performance and creates drift risk. See `output-dev-prompt-file` for details.

// LLM output schema (sent to provider via aiSdk.Output.object()) -- .describe() ONLY
const llmOutputSchema = z.object( {
  score: z.number().describe( 'Quality score 0-100' ),
  confidence: z.number().describe( 'Confidence 0-1' ),
  predictions: z.array( predictionSchema ).describe( 'Exactly 3 predictions' )
} );

// Workflow/step validation schema (Zod-only, NOT sent to LLM) -- .min()/.max()/.length() OK
const workflowOutputSchema = z.object( {
  score: z.number().min( 0 ).max( 100 ).describe( 'Quality score 0-100' ),
  confidence: z.number().min( 0 ).max( 1 ).describe( 'Confidence 0-1' ),
  predictions: z.array( predictionSchema ).length( 3 ).describe( 'Exactly 3 predictions' )
} );

When to Use Which

| Context | `.min()/.max()/.length()` | `.describe()` | |---------|:-:|:-:| | Schema passed to `aiSdk.Output.object()` | **No** (numbers or arrays) | Yes | | `inputSchema` / `outputSchema` on steps | OK | Optional | | `inputSchema` / `outputSchema` on workflows | OK | Optional | | `outputSchema` on evaluators | OK | Optional |

LLM Schemas Must Live in types.ts

Define all schemas used in `aiSdk.Output.object()` in `types.ts` and import them in step functions. Never define them inline -- this causes duplication and makes it harder to verify they follow the constraints above.

Common Schema Patterns

Basic Types

import { z } from '@outputai/core';

// Strings
const stringField = z.string();
const optionalString = z.string().optional();
const stringWithDefault = z.string().default( 'default value' );
const describedString = z.string().describe( 'Field description' );

// Numbers
const numberField = z.number();
const integerField = z.number().int();
const rangedNumber = z.number().min( 1 ).max( 100 ); // runtime only — NOT safe for aiSdk.Output.object() schemas

// Booleans
const booleanField = z.boolean();
const defaultBoolean = z.boolean().default( false );

// Enums
const enumField = z.enum( [ 'option1', 'option2', 'option3' ] );
const enumWithDefault = z.enum( [ 'small', 'medium', 'large' ] ).default( 'medium' );

Complex Types

import { z } from '@outputai/core';

// Arrays
const stringArray = z.array( z.string() );
const objectArray = z.array( z.object( { id: z.string(), name: z.string() } ) );

// Objects
const nestedObject = z.object( {
  user: z.object( {
    id: z.string(),
    email: z.string().email()
  } ),
  settings: z.object( {
    notifications: z.boolean()
  } )
} );

// Union Types
const flexibleInput = z.union( [
  z.string(),
  z.array( z.string() )
] );

// Records
const keyValueMap = z.record( z.string(), z.number() );

Validation Patterns

import { z } from '@outputai/core';

// String Validations
const emailField = z.string().email();
const urlField = z.string().url();
const uuidField = z.string().uuid();
const minLengthString = z.string().min( 1 );
const maxLengthString = z.string().max( 1000 );

// Number Validations
const positiveNumber = z.number().positive();
const nonNegativeNumber = z.number().nonnegative();
const percentageNumber = z.number().min( 0 ).max( 100 );

// Array Valida
Read more
@growthxai
Ships withoutput

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 in place. One framework.

44451 skills5 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
444
Star history of growthxai/output on GitHub, a chart by star-history.com

Other skills on output.

output-build-workflow

output-build-workflow

Implement an Output SDK workflow from a plan document. Use when the user asks to build, implement, or code a workflow from an…

@growthxai@growthxaiInstall Skill
output-credentials-edit

output-credentials-edi…

View, edit, and set encrypted credentials in an Output.ai project. Use when adding secrets, updating API keys, verifying…

@growthxai@growthxaiInstall Skill
output-credentials-init

output-credentials-ini…

Initialize encrypted credentials for an Output.ai project. Use when setting up credentials for the first time, adding…

@growthxai@growthxaiInstall Skill
output-debug-workflow

output-debug-workflow

Debug Output SDK workflow issues. Use when user reports a workflow failing, erroring, hanging, producing wrong results, or asks…

@growthxai@growthxaiInstall Skill
output-dev-agent-class

output-dev-agent-class

Use the Agent class for multi-step tool loops, conversation history, streaming progress, and reusable LLM agents. Use when…

@growthxai@growthxaiInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills11d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react2d252k
@facebook@facebookInstall Skill

Questions about output-dev-types-file.

Which coding agents can use output-dev-types-file?
output-dev-types-file installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.