@output.ai/cli 0.5.6 → 0.6.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 (52) hide show
  1. package/dist/commands/agents/init.d.ts +0 -1
  2. package/dist/commands/agents/init.js +9 -16
  3. package/dist/commands/agents/init.spec.js +49 -224
  4. package/dist/commands/workflow/generate.js +2 -2
  5. package/dist/commands/workflow/plan.js +3 -3
  6. package/dist/commands/workflow/plan.spec.js +13 -13
  7. package/dist/services/claude_client.d.ts +4 -4
  8. package/dist/services/claude_client.integration.test.js +2 -2
  9. package/dist/services/claude_client.js +7 -7
  10. package/dist/services/claude_client.spec.js +3 -3
  11. package/dist/services/coding_agents.d.ts +10 -24
  12. package/dist/services/coding_agents.js +112 -368
  13. package/dist/services/coding_agents.spec.js +101 -290
  14. package/dist/services/project_scaffold.js +3 -3
  15. package/dist/services/workflow_builder.d.ts +1 -1
  16. package/dist/services/workflow_builder.js +1 -1
  17. package/dist/services/workflow_planner.js +1 -2
  18. package/dist/services/workflow_planner.spec.js +4 -5
  19. package/dist/templates/agent_instructions/dotclaude/settings.json.template +29 -0
  20. package/dist/templates/agent_instructions/{AGENTS.md.template → dotoutputai/AGENTS.md.template} +12 -10
  21. package/dist/utils/claude.d.ts +5 -0
  22. package/dist/utils/claude.js +19 -0
  23. package/dist/utils/claude.spec.d.ts +1 -0
  24. package/dist/utils/claude.spec.js +119 -0
  25. package/dist/utils/paths.d.ts +0 -4
  26. package/dist/utils/paths.js +0 -6
  27. package/package.json +3 -3
  28. package/dist/templates/agent_instructions/agents/workflow_context_fetcher.md.template +0 -82
  29. package/dist/templates/agent_instructions/agents/workflow_debugger.md.template +0 -98
  30. package/dist/templates/agent_instructions/agents/workflow_planner.md.template +0 -113
  31. package/dist/templates/agent_instructions/agents/workflow_prompt_writer.md.template +0 -595
  32. package/dist/templates/agent_instructions/agents/workflow_quality.md.template +0 -244
  33. package/dist/templates/agent_instructions/commands/build_workflow.md.template +0 -290
  34. package/dist/templates/agent_instructions/commands/debug_workflow.md.template +0 -198
  35. package/dist/templates/agent_instructions/commands/plan_workflow.md.template +0 -261
  36. package/dist/templates/agent_instructions/meta/post_flight.md.template +0 -94
  37. package/dist/templates/agent_instructions/meta/pre_flight.md.template +0 -60
  38. package/dist/templates/agent_instructions/skills/output-error-direct-io/SKILL.md.template +0 -249
  39. package/dist/templates/agent_instructions/skills/output-error-http-client/SKILL.md.template +0 -298
  40. package/dist/templates/agent_instructions/skills/output-error-missing-schemas/SKILL.md.template +0 -265
  41. package/dist/templates/agent_instructions/skills/output-error-nondeterminism/SKILL.md.template +0 -252
  42. package/dist/templates/agent_instructions/skills/output-error-try-catch/SKILL.md.template +0 -226
  43. package/dist/templates/agent_instructions/skills/output-error-zod-import/SKILL.md.template +0 -209
  44. package/dist/templates/agent_instructions/skills/output-services-check/SKILL.md.template +0 -128
  45. package/dist/templates/agent_instructions/skills/output-workflow-list/SKILL.md.template +0 -117
  46. package/dist/templates/agent_instructions/skills/output-workflow-result/SKILL.md.template +0 -199
  47. package/dist/templates/agent_instructions/skills/output-workflow-run/SKILL.md.template +0 -228
  48. package/dist/templates/agent_instructions/skills/output-workflow-runs-list/SKILL.md.template +0 -141
  49. package/dist/templates/agent_instructions/skills/output-workflow-start/SKILL.md.template +0 -201
  50. package/dist/templates/agent_instructions/skills/output-workflow-status/SKILL.md.template +0 -151
  51. package/dist/templates/agent_instructions/skills/output-workflow-stop/SKILL.md.template +0 -164
  52. package/dist/templates/agent_instructions/skills/output-workflow-trace/SKILL.md.template +0 -134
@@ -1,249 +0,0 @@
1
- ---
2
- name: output-error-direct-io
3
- description: Fix direct I/O in Output SDK workflow functions. Use when workflow hangs, returns undefined, shows "workflow must be deterministic" errors, or when HTTP/API calls are made directly in workflow code.
4
- allowed-tools: [Bash, Read]
5
- ---
6
-
7
- # Fix Direct I/O in Workflow Functions
8
-
9
- ## Overview
10
-
11
- This skill helps diagnose and fix a critical error pattern where I/O operations (HTTP calls, database queries, file operations) are performed directly in workflow functions instead of in steps. This violates Temporal's determinism requirements.
12
-
13
- ## When to Use This Skill
14
-
15
- You're seeing:
16
- - Workflow hangs indefinitely
17
- - Undefined or empty responses
18
- - "workflow must be deterministic" errors
19
- - Network operations failing silently
20
- - Timeouts without clear cause
21
-
22
- ## Root Cause
23
-
24
- Workflow functions must be **deterministic** - they should only orchestrate steps, not perform I/O directly. When you make HTTP calls, database queries, or any external operations directly in a workflow function:
25
-
26
- 1. **Hangs**: The workflow may hang because I/O isn't properly handled
27
- 2. **Determinism violations**: Temporal replays workflows, and I/O results differ
28
- 3. **No retry logic**: Direct calls bypass Output SDK's retry mechanisms
29
- 4. **No tracing**: Operations aren't recorded in the workflow trace
30
-
31
- ## Symptoms
32
-
33
- ### Direct fetch/axios in Workflow
34
-
35
- ```typescript
36
- // WRONG: I/O directly in workflow
37
- export default workflow({
38
- fn: async (input) => {
39
- const response = await fetch('https://api.example.com/data'); // BAD!
40
- const data = await response.json();
41
- return { data };
42
- }
43
- });
44
- ```
45
-
46
- ### Direct Database Calls
47
-
48
- ```typescript
49
- // WRONG: Database I/O in workflow
50
- export default workflow({
51
- fn: async (input) => {
52
- const user = await db.users.findById(input.userId); // BAD!
53
- return { user };
54
- }
55
- });
56
- ```
57
-
58
- ### File System Operations
59
-
60
- ```typescript
61
- // WRONG: File I/O in workflow
62
- import fs from 'fs/promises';
63
-
64
- export default workflow({
65
- fn: async (input) => {
66
- const data = await fs.readFile(input.path, 'utf-8'); // BAD!
67
- return { data };
68
- }
69
- });
70
- ```
71
-
72
- ## Solution
73
-
74
- Move ALL I/O operations to step functions. Steps are designed to handle non-deterministic operations.
75
-
76
- ### Before (Wrong)
77
-
78
- ```typescript
79
- export default workflow({
80
- fn: async (input) => {
81
- const response = await fetch('https://api.example.com/data');
82
- const data = await response.json();
83
- return { data };
84
- }
85
- });
86
- ```
87
-
88
- ### After (Correct)
89
-
90
- ```typescript
91
- import { z, step, workflow } from '@output.ai/core';
92
- import { httpClient } from '@output.ai/http';
93
-
94
- // Create a step for the I/O operation
95
- export const fetchData = step({
96
- name: 'fetchData',
97
- inputSchema: z.object({
98
- endpoint: z.string(),
99
- }),
100
- outputSchema: z.object({
101
- data: z.unknown(),
102
- }),
103
- fn: async (input) => {
104
- const client = httpClient({ prefixUrl: 'https://api.example.com' });
105
- const data = await client.get(input.endpoint).json();
106
- return { data };
107
- },
108
- });
109
-
110
- // Workflow only orchestrates steps
111
- export default workflow({
112
- inputSchema: z.object({}),
113
- outputSchema: z.object({ data: z.unknown() }),
114
- fn: async (input) => {
115
- const result = await fetchData({ endpoint: 'data' });
116
- return result;
117
- },
118
- });
119
- ```
120
-
121
- ## Complete Example: Database Operation
122
-
123
- ### Before (Wrong)
124
-
125
- ```typescript
126
- export default workflow({
127
- fn: async (input) => {
128
- const user = await prisma.user.findUnique({
129
- where: { id: input.userId }
130
- });
131
- const orders = await prisma.order.findMany({
132
- where: { userId: input.userId }
133
- });
134
- return { user, orders };
135
- }
136
- });
137
- ```
138
-
139
- ### After (Correct)
140
-
141
- ```typescript
142
- import { z, step, workflow } from '@output.ai/core';
143
- import { prisma } from '../lib/db';
144
-
145
- export const fetchUser = step({
146
- name: 'fetchUser',
147
- inputSchema: z.object({ userId: z.string() }),
148
- outputSchema: z.object({
149
- user: z.object({
150
- id: z.string(),
151
- name: z.string(),
152
- email: z.string(),
153
- }).nullable(),
154
- }),
155
- fn: async (input) => {
156
- const user = await prisma.user.findUnique({
157
- where: { id: input.userId }
158
- });
159
- return { user };
160
- },
161
- });
162
-
163
- export const fetchOrders = step({
164
- name: 'fetchOrders',
165
- inputSchema: z.object({ userId: z.string() }),
166
- outputSchema: z.object({
167
- orders: z.array(z.object({
168
- id: z.string(),
169
- total: z.number(),
170
- })),
171
- }),
172
- fn: async (input) => {
173
- const orders = await prisma.order.findMany({
174
- where: { userId: input.userId }
175
- });
176
- return { orders };
177
- },
178
- });
179
-
180
- export default workflow({
181
- inputSchema: z.object({ userId: z.string() }),
182
- outputSchema: z.object({
183
- user: z.unknown(),
184
- orders: z.array(z.unknown()),
185
- }),
186
- fn: async (input) => {
187
- const { user } = await fetchUser({ userId: input.userId });
188
- const { orders } = await fetchOrders({ userId: input.userId });
189
- return { user, orders };
190
- },
191
- });
192
- ```
193
-
194
- ## Finding Direct I/O in Workflows
195
-
196
- Search for common I/O patterns in workflow files:
197
-
198
- ```bash
199
- # Find fetch calls
200
- grep -rn "await fetch" src/workflows/
201
-
202
- # Find axios calls
203
- grep -rn "axios\." src/workflows/
204
-
205
- # Find database operations
206
- grep -rn "prisma\.\|db\.\|mongoose\." src/workflows/
207
-
208
- # Find file system operations
209
- grep -rn "fs\.\|readFile\|writeFile" src/workflows/
210
- ```
211
-
212
- Then review each match to see if it's in a workflow function vs a step function.
213
-
214
- ## What CAN Be in Workflow Functions
215
-
216
- Workflow functions should contain:
217
- - **Step calls**: `await myStep(input)`
218
- - **Orchestration logic**: conditionals, loops (over step calls)
219
- - **Data transformation**: Pure functions on step results
220
- - **Constants**: Static values and configuration
221
-
222
- Workflow functions should NOT contain:
223
- - HTTP/API calls
224
- - Database operations
225
- - File system operations
226
- - External service calls
227
- - Anything that talks to the network or filesystem
228
-
229
- ## Verification
230
-
231
- After moving I/O to steps:
232
-
233
- 1. **Run the workflow**: `npx output workflow run <name> '<input>'`
234
- 2. **Check the trace**: `npx output workflow debug <id> --format json`
235
- 3. **Verify steps appear**: Look for your I/O steps in the trace
236
- 4. **Confirm no errors**: No determinism warnings or hangs
237
-
238
- ## Benefits of Steps for I/O
239
-
240
- 1. **Retry logic**: Steps can be retried on failure
241
- 2. **Tracing**: I/O operations appear in workflow traces
242
- 3. **Timeouts**: Steps can have individual timeouts
243
- 4. **Determinism**: Replays use recorded results
244
- 5. **Debugging**: Clear visibility into what happened
245
-
246
- ## Related Issues
247
-
248
- - For HTTP client best practices, see `output-error-http-client`
249
- - For non-determinism from other causes, see `output-error-nondeterminism`
@@ -1,298 +0,0 @@
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**: `npx output workflow run <name> '<input>'`
291
- 2. **Check the trace**: `npx 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`