@output.ai/cli 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +6 -8
  2. package/dist/api/generated/api.d.ts +66 -0
  3. package/dist/api/generated/api.js +26 -0
  4. package/dist/assets/docker/docker-compose-dev.yml +9 -2
  5. package/dist/commands/workflow/runs/list.d.ts +14 -0
  6. package/dist/commands/workflow/runs/list.js +104 -0
  7. package/dist/services/coding_agents.js +180 -8
  8. package/dist/services/coding_agents.spec.js +54 -11
  9. package/dist/services/workflow_runs.d.ts +14 -0
  10. package/dist/services/workflow_runs.js +24 -0
  11. package/dist/templates/agent_instructions/AGENTS.md.template +13 -7
  12. package/dist/templates/agent_instructions/agents/{context_fetcher.md.template → workflow_context_fetcher.md.template} +1 -1
  13. package/dist/templates/agent_instructions/agents/workflow_debugger.md.template +98 -0
  14. package/dist/templates/agent_instructions/agents/workflow_planner.md.template +3 -3
  15. package/dist/templates/agent_instructions/agents/{prompt_writer.md.template → workflow_prompt_writer.md.template} +1 -1
  16. package/dist/templates/agent_instructions/agents/workflow_quality.md.template +2 -2
  17. package/dist/templates/agent_instructions/commands/build_workflow.md.template +2 -2
  18. package/dist/templates/agent_instructions/commands/debug_workflow.md.template +198 -0
  19. package/dist/templates/agent_instructions/commands/plan_workflow.md.template +2 -2
  20. package/dist/templates/agent_instructions/skills/output-error-direct-io/SKILL.md.template +249 -0
  21. package/dist/templates/agent_instructions/skills/output-error-http-client/SKILL.md.template +298 -0
  22. package/dist/templates/agent_instructions/skills/output-error-missing-schemas/SKILL.md.template +265 -0
  23. package/dist/templates/agent_instructions/skills/output-error-nondeterminism/SKILL.md.template +252 -0
  24. package/dist/templates/agent_instructions/skills/output-error-try-catch/SKILL.md.template +226 -0
  25. package/dist/templates/agent_instructions/skills/output-error-zod-import/SKILL.md.template +209 -0
  26. package/dist/templates/agent_instructions/skills/output-services-check/SKILL.md.template +128 -0
  27. package/dist/templates/agent_instructions/skills/output-workflow-list/SKILL.md.template +117 -0
  28. package/dist/templates/agent_instructions/skills/output-workflow-result/SKILL.md.template +199 -0
  29. package/dist/templates/agent_instructions/skills/output-workflow-run/SKILL.md.template +228 -0
  30. package/dist/templates/agent_instructions/skills/output-workflow-runs-list/SKILL.md.template +141 -0
  31. package/dist/templates/agent_instructions/skills/output-workflow-start/SKILL.md.template +201 -0
  32. package/dist/templates/agent_instructions/skills/output-workflow-status/SKILL.md.template +151 -0
  33. package/dist/templates/agent_instructions/skills/output-workflow-stop/SKILL.md.template +164 -0
  34. package/dist/templates/agent_instructions/skills/output-workflow-trace/SKILL.md.template +134 -0
  35. package/dist/templates/project/README.md.template +1 -1
  36. package/dist/templates/project/package.json.template +3 -2
  37. package/dist/utils/date_formatter.d.ts +15 -0
  38. package/dist/utils/date_formatter.js +31 -1
  39. package/package.json +1 -1
@@ -0,0 +1,298 @@
1
+ ---
2
+ name: output-error-http-client
3
+ description: Fix HTTP client misuse in Output SDK steps. Use when seeing untraced requests, missing error details, axios-related errors, or when HTTP calls aren't being properly logged and retried.
4
+ allowed-tools: [Bash, Read]
5
+ ---
6
+
7
+ # Fix HTTP Client Misuse
8
+
9
+ ## Overview
10
+
11
+ This skill helps diagnose and fix issues caused by using axios, fetch, or other HTTP clients directly instead of Output SDK's `httpClient` from `@output.ai/http`. The Output SDK client provides tracing, automatic retries, and better error handling.
12
+
13
+ ## When to Use This Skill
14
+
15
+ You're seeing:
16
+ - Untraced HTTP requests (not appearing in workflow traces)
17
+ - Missing error details for failed requests
18
+ - axios-related errors or import issues
19
+ - Retries not working for HTTP failures
20
+ - Inconsistent timeout behavior
21
+
22
+ ## Root Cause
23
+
24
+ Using axios, fetch, or other HTTP clients directly bypasses Output SDK's:
25
+ - **Request/response tracing**: Calls aren't logged in workflow traces
26
+ - **Automatic retries**: Failed requests aren't retried
27
+ - **Error standardization**: Error formats may be inconsistent
28
+ - **Timeout handling**: Timeouts may not integrate with step timeouts
29
+
30
+ ## Symptoms
31
+
32
+ ### Using axios Directly
33
+
34
+ ```typescript
35
+ // WRONG: Using axios
36
+ import axios from 'axios';
37
+
38
+ export const fetchData = step({
39
+ name: 'fetchData',
40
+ fn: async (input) => {
41
+ const response = await axios.get('https://api.example.com/data');
42
+ return response.data;
43
+ },
44
+ });
45
+ ```
46
+
47
+ ### Using fetch Directly
48
+
49
+ ```typescript
50
+ // WRONG: Using fetch
51
+ export const fetchData = step({
52
+ name: 'fetchData',
53
+ fn: async (input) => {
54
+ const response = await fetch('https://api.example.com/data');
55
+ return response.json();
56
+ },
57
+ });
58
+ ```
59
+
60
+ ## Solution
61
+
62
+ Use `httpClient` from `@output.ai/http`:
63
+
64
+ ### Basic Usage
65
+
66
+ ```typescript
67
+ import { z, step } from '@output.ai/core';
68
+ import { httpClient } from '@output.ai/http';
69
+
70
+ export const fetchData = step({
71
+ name: 'fetchData',
72
+ inputSchema: z.object({
73
+ endpoint: z.string(),
74
+ }),
75
+ outputSchema: z.object({
76
+ data: z.unknown(),
77
+ }),
78
+ fn: async (input) => {
79
+ const client = httpClient({
80
+ prefixUrl: 'https://api.example.com',
81
+ });
82
+
83
+ const data = await client.get(input.endpoint).json();
84
+ return { data };
85
+ },
86
+ });
87
+ ```
88
+
89
+ ### With Full Configuration
90
+
91
+ ```typescript
92
+ import { httpClient } from '@output.ai/http';
93
+
94
+ const client = httpClient({
95
+ prefixUrl: 'https://api.example.com',
96
+ timeout: 30000, // 30 second timeout
97
+ retry: {
98
+ limit: 3, // Retry up to 3 times
99
+ methods: ['GET', 'POST'], // Which methods to retry
100
+ statusCodes: [408, 500, 502, 503, 504], // Which status codes trigger retry
101
+ },
102
+ headers: {
103
+ 'Authorization': `Bearer ${apiKey}`,
104
+ 'Content-Type': 'application/json',
105
+ },
106
+ });
107
+ ```
108
+
109
+ ## HTTP Methods
110
+
111
+ ### GET Request
112
+
113
+ ```typescript
114
+ const data = await client.get('users/123').json();
115
+ ```
116
+
117
+ ### POST Request
118
+
119
+ ```typescript
120
+ const result = await client.post('users', {
121
+ json: {
122
+ name: 'John',
123
+ email: 'john@example.com',
124
+ },
125
+ }).json();
126
+ ```
127
+
128
+ ### PUT Request
129
+
130
+ ```typescript
131
+ const updated = await client.put('users/123', {
132
+ json: {
133
+ name: 'John Updated',
134
+ },
135
+ }).json();
136
+ ```
137
+
138
+ ### DELETE Request
139
+
140
+ ```typescript
141
+ await client.delete('users/123');
142
+ ```
143
+
144
+ ### With Query Parameters
145
+
146
+ ```typescript
147
+ const data = await client.get('search', {
148
+ searchParams: {
149
+ q: 'query',
150
+ limit: 10,
151
+ },
152
+ }).json();
153
+ ```
154
+
155
+ ## Complete Migration Example
156
+
157
+ ### Before (Wrong - using axios)
158
+
159
+ ```typescript
160
+ import axios from 'axios';
161
+ import { step } from '@output.ai/core';
162
+
163
+ export const createUser = step({
164
+ name: 'createUser',
165
+ fn: async (input) => {
166
+ try {
167
+ const response = await axios.post(
168
+ 'https://api.example.com/users',
169
+ { name: input.name, email: input.email },
170
+ {
171
+ headers: { 'Authorization': `Bearer ${process.env.API_KEY}` },
172
+ timeout: 30000,
173
+ }
174
+ );
175
+ return response.data;
176
+ } catch (error) {
177
+ if (axios.isAxiosError(error)) {
178
+ throw new Error(`API Error: ${error.response?.data?.message}`);
179
+ }
180
+ throw error;
181
+ }
182
+ },
183
+ });
184
+ ```
185
+
186
+ ### After (Correct - using httpClient)
187
+
188
+ ```typescript
189
+ import { z, step } from '@output.ai/core';
190
+ import { httpClient } from '@output.ai/http';
191
+
192
+ export const createUser = step({
193
+ name: 'createUser',
194
+ inputSchema: z.object({
195
+ name: z.string(),
196
+ email: z.string().email(),
197
+ }),
198
+ outputSchema: z.object({
199
+ id: z.string(),
200
+ name: z.string(),
201
+ email: z.string(),
202
+ }),
203
+ fn: async (input) => {
204
+ const client = httpClient({
205
+ prefixUrl: 'https://api.example.com',
206
+ timeout: 30000,
207
+ retry: { limit: 3 },
208
+ headers: {
209
+ 'Authorization': `Bearer ${process.env.API_KEY}`,
210
+ },
211
+ });
212
+
213
+ const user = await client.post('users', {
214
+ json: {
215
+ name: input.name,
216
+ email: input.email,
217
+ },
218
+ }).json();
219
+
220
+ return user;
221
+ },
222
+ });
223
+ ```
224
+
225
+ ## Error Handling
226
+
227
+ The httpClient provides structured error handling:
228
+
229
+ ```typescript
230
+ import { httpClient, HTTPError } from '@output.ai/http';
231
+
232
+ export const fetchData = step({
233
+ name: 'fetchData',
234
+ fn: async (input) => {
235
+ const client = httpClient({ prefixUrl: 'https://api.example.com' });
236
+
237
+ try {
238
+ return await client.get('data').json();
239
+ } catch (error) {
240
+ if (error instanceof HTTPError) {
241
+ // Access response details
242
+ const status = error.response.status;
243
+ const body = await error.response.json();
244
+ throw new Error(`API returned ${status}: ${body.message}`);
245
+ }
246
+ throw error;
247
+ }
248
+ },
249
+ });
250
+ ```
251
+
252
+ ## Finding axios/fetch Usage
253
+
254
+ Search your codebase:
255
+
256
+ ```bash
257
+ # Find axios imports
258
+ grep -rn "from 'axios'\|from \"axios\"" src/
259
+
260
+ # Find fetch calls
261
+ grep -rn "await fetch(" src/
262
+
263
+ # Find other HTTP libraries
264
+ grep -rn "got\|node-fetch\|request\|superagent" src/
265
+ ```
266
+
267
+ ## Benefits of httpClient
268
+
269
+ 1. **Tracing**: Requests appear in workflow traces with timing
270
+ 2. **Automatic Retries**: Configurable retry logic for transient failures
271
+ 3. **Consistent Errors**: Standardized error format across all requests
272
+ 4. **Timeout Integration**: Works with step and workflow timeouts
273
+ 5. **Type Safety**: Full TypeScript support
274
+
275
+ ## Configuration Options
276
+
277
+ | Option | Description | Default |
278
+ |--------|-------------|---------|
279
+ | `prefixUrl` | Base URL for all requests | (required) |
280
+ | `timeout` | Request timeout in ms | 10000 |
281
+ | `retry.limit` | Max retry attempts | 2 |
282
+ | `retry.methods` | HTTP methods to retry | ['GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'] |
283
+ | `retry.statusCodes` | Status codes to retry | [408, 413, 429, 500, 502, 503, 504] |
284
+ | `headers` | Default headers | {} |
285
+
286
+ ## Verification
287
+
288
+ After migrating to httpClient:
289
+
290
+ 1. **Run the workflow**: `output workflow run <name> '<input>'`
291
+ 2. **Check the trace**: `output workflow debug <id> --format json`
292
+ 3. **Verify tracing**: HTTP requests should appear in the step trace
293
+ 4. **Test retries**: Simulate failures to verify retry behavior
294
+
295
+ ## Related Issues
296
+
297
+ - For I/O in workflow functions, see `output-error-direct-io`
298
+ - For connection issues, see `output-services-check`
@@ -0,0 +1,265 @@
1
+ ---
2
+ name: output-error-missing-schemas
3
+ description: Fix missing schema definitions in Output SDK steps. Use when seeing type errors, undefined properties at step boundaries, validation failures, or when step inputs/outputs aren't being properly typed.
4
+ allowed-tools: [Bash, Read]
5
+ ---
6
+
7
+ # Fix Missing Schema Definitions
8
+
9
+ ## Overview
10
+
11
+ This skill helps diagnose and fix issues caused by steps that lack explicit `inputSchema` or `outputSchema` definitions. Schemas are essential for type safety, validation, and proper data serialization between steps.
12
+
13
+ ## When to Use This Skill
14
+
15
+ You're seeing:
16
+ - Type errors at step boundaries
17
+ - Undefined properties in step inputs/outputs
18
+ - Validation failures when passing data between steps
19
+ - TypeScript errors about incompatible types
20
+ - Runtime errors about unexpected data shapes
21
+
22
+ ## Root Cause
23
+
24
+ Steps without explicit schemas:
25
+ - Don't validate input data at runtime
26
+ - Don't provide TypeScript type inference
27
+ - May serialize/deserialize data incorrectly
28
+ - Can pass undefined or malformed data silently
29
+
30
+ ## Symptoms
31
+
32
+ ### Missing Input Schema
33
+
34
+ ```typescript
35
+ // WRONG: No input validation
36
+ export const processData = step({
37
+ name: 'processData',
38
+ // inputSchema: missing!
39
+ outputSchema: z.object({ result: z.string() }),
40
+ fn: async (input) => {
41
+ return { result: input.value }; // input.value might be undefined!
42
+ }
43
+ });
44
+ ```
45
+
46
+ ### Missing Output Schema
47
+
48
+ ```typescript
49
+ // WRONG: No output validation
50
+ export const fetchData = step({
51
+ name: 'fetchData',
52
+ inputSchema: z.object({ id: z.string() }),
53
+ // outputSchema: missing!
54
+ fn: async (input) => {
55
+ return { data: await getFromApi(input.id) }; // Output shape not validated
56
+ }
57
+ });
58
+ ```
59
+
60
+ ### Both Schemas Missing
61
+
62
+ ```typescript
63
+ // WRONG: No validation at all
64
+ export const transformData = step({
65
+ name: 'transformData',
66
+ // No schemas!
67
+ fn: async (input) => {
68
+ return transform(input);
69
+ }
70
+ });
71
+ ```
72
+
73
+ ## Solution
74
+
75
+ Always define both `inputSchema` and `outputSchema` for every step:
76
+
77
+ ### Complete Step Definition
78
+
79
+ ```typescript
80
+ import { z, step } from '@output.ai/core';
81
+
82
+ export const processData = step({
83
+ name: 'processData',
84
+ inputSchema: z.object({
85
+ id: z.string(),
86
+ value: z.number(),
87
+ optional: z.string().optional(),
88
+ }),
89
+ outputSchema: z.object({
90
+ result: z.string(),
91
+ processedAt: z.number(),
92
+ }),
93
+ fn: async (input) => {
94
+ // input is fully typed: { id: string, value: number, optional?: string }
95
+ return {
96
+ result: `Processed ${input.id}`,
97
+ processedAt: Date.now(),
98
+ };
99
+ // output is validated against outputSchema
100
+ },
101
+ });
102
+ ```
103
+
104
+ ## Schema Definition Best Practices
105
+
106
+ ### Use Descriptive Schemas
107
+
108
+ ```typescript
109
+ // Good: Clear, descriptive schema
110
+ inputSchema: z.object({
111
+ userId: z.string().uuid(),
112
+ email: z.string().email(),
113
+ age: z.number().int().positive(),
114
+ })
115
+ ```
116
+
117
+ ### Handle Optional Fields
118
+
119
+ ```typescript
120
+ inputSchema: z.object({
121
+ required: z.string(),
122
+ optional: z.string().optional(),
123
+ withDefault: z.string().default('fallback'),
124
+ })
125
+ ```
126
+
127
+ ### Use Schema Composition
128
+
129
+ ```typescript
130
+ // Define reusable schemas
131
+ const userSchema = z.object({
132
+ id: z.string(),
133
+ name: z.string(),
134
+ });
135
+
136
+ const addressSchema = z.object({
137
+ street: z.string(),
138
+ city: z.string(),
139
+ });
140
+
141
+ // Compose in step
142
+ inputSchema: z.object({
143
+ user: userSchema,
144
+ address: addressSchema,
145
+ })
146
+ ```
147
+
148
+ ### Handle Arrays and Nested Objects
149
+
150
+ ```typescript
151
+ inputSchema: z.object({
152
+ items: z.array(z.object({
153
+ id: z.string(),
154
+ quantity: z.number(),
155
+ })),
156
+ metadata: z.record(z.string()),
157
+ })
158
+ ```
159
+
160
+ ## Finding Steps Without Schemas
161
+
162
+ Search your codebase:
163
+
164
+ ```bash
165
+ # Find step definitions
166
+ grep -rn "step({" src/workflows/
167
+
168
+ # Look for steps without inputSchema
169
+ grep -A5 "step({" src/workflows/ | grep -B2 "fn:"
170
+
171
+ # Check if schemas are present
172
+ grep -rn "inputSchema:" src/workflows/
173
+ grep -rn "outputSchema:" src/workflows/
174
+ ```
175
+
176
+ Review each step definition to ensure both schemas are present.
177
+
178
+ ## Benefits of Explicit Schemas
179
+
180
+ 1. **Runtime Validation**: Catches data errors early
181
+ 2. **Type Safety**: Full TypeScript inference in step functions
182
+ 3. **Documentation**: Schemas document expected data shapes
183
+ 4. **Serialization**: Ensures proper data serialization between steps
184
+ 5. **Error Messages**: Clear validation errors when data is wrong
185
+
186
+ ## Common Schema Patterns
187
+
188
+ ### API Response Steps
189
+
190
+ ```typescript
191
+ export const fetchUser = step({
192
+ name: 'fetchUser',
193
+ inputSchema: z.object({
194
+ userId: z.string(),
195
+ }),
196
+ outputSchema: z.object({
197
+ user: z.object({
198
+ id: z.string(),
199
+ name: z.string(),
200
+ email: z.string(),
201
+ }).nullable(), // Handle not found
202
+ found: z.boolean(),
203
+ }),
204
+ fn: async (input) => {
205
+ const user = await api.getUser(input.userId);
206
+ return { user, found: user !== null };
207
+ },
208
+ });
209
+ ```
210
+
211
+ ### Transformation Steps
212
+
213
+ ```typescript
214
+ export const transformData = step({
215
+ name: 'transformData',
216
+ inputSchema: z.object({
217
+ raw: z.array(z.unknown()),
218
+ }),
219
+ outputSchema: z.object({
220
+ processed: z.array(z.object({
221
+ id: z.string(),
222
+ value: z.number(),
223
+ })),
224
+ count: z.number(),
225
+ }),
226
+ fn: async (input) => {
227
+ const processed = input.raw.map(transformItem);
228
+ return { processed, count: processed.length };
229
+ },
230
+ });
231
+ ```
232
+
233
+ ### Void Output Steps
234
+
235
+ For steps that don't return meaningful data:
236
+
237
+ ```typescript
238
+ export const logEvent = step({
239
+ name: 'logEvent',
240
+ inputSchema: z.object({
241
+ event: z.string(),
242
+ data: z.record(z.unknown()),
243
+ }),
244
+ outputSchema: z.object({
245
+ logged: z.literal(true),
246
+ }),
247
+ fn: async (input) => {
248
+ await logger.log(input.event, input.data);
249
+ return { logged: true };
250
+ },
251
+ });
252
+ ```
253
+
254
+ ## Verification
255
+
256
+ After adding schemas:
257
+
258
+ 1. **TypeScript check**: `npm run build` should pass without type errors
259
+ 2. **Runtime test**: `output workflow run <name> '<input>'` should validate correctly
260
+ 3. **Invalid input test**: Pass invalid data and verify validation errors appear
261
+
262
+ ## Related Issues
263
+
264
+ - For Zod import issues, see `output-error-zod-import`
265
+ - For type mismatches despite schemas, verify schema matches actual data