@output.ai/cli 0.0.1 → 0.0.2

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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @output.ai/cli
2
2
 
3
- CLI tool for generating Output.ai workflows.
3
+ CLI tool for generating Output workflows.
4
4
 
5
5
  ## Installation
6
6
 
@@ -83,6 +83,38 @@ my-workflow/
83
83
  └── README.md # Workflow documentation
84
84
  ```
85
85
 
86
+ ### Initialize Agent Configuration
87
+
88
+ ```bash
89
+ # Initialize agent configuration for your coding agent
90
+ output-cli agents init
91
+
92
+ # Specify your agent provider (default: claude-code)
93
+ output-cli agents init --agent-provider claude-code
94
+
95
+ # Force overwrite existing configuration
96
+ output-cli agents init --force
97
+ ```
98
+
99
+ #### What It Does
100
+
101
+ Sets up your coding agent of choice with context files, sub-agents, and slash commands for working with the Output SDK effectively. It creates a `.outputai/` directory and wires up your coding agent to the context files.
102
+
103
+ **Note:** Currently this only works for [Claude Code](https://claude.ai/code), but we plan to add support for other coding agents over time.
104
+
105
+ #### Command Options
106
+
107
+ - `--agent-provider` - Specify the coding agent provider (default: `claude-code`)
108
+ - `--force, -f` - Overwrite existing agent configuration files
109
+
110
+ #### Output Agent Commands
111
+
112
+ **`/plan_workflow`** - Guides you through structured workflow planning to create comprehensive implementation blueprints before writing code.
113
+
114
+ #### Output Sub-Agents
115
+
116
+ **`workflow_planner`** - A specialized AI agent that helps with workflow architecture and planning, including requirements analysis, schema design, and testing strategy definition.
117
+
86
118
  ## About
87
119
 
88
120
  Built with [OCLIF](https://oclif.io) - see their documentation for advanced CLI features, plugins, and configuration options.
@@ -0,0 +1,18 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Init extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {};
6
+ static flags: {
7
+ 'agent-provider': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
8
+ force: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ private prepareTemplateVariables;
12
+ private processMappings;
13
+ private ensureDirectoryExists;
14
+ private fileExists;
15
+ private createFromTemplate;
16
+ private createSymlink;
17
+ private copyFile;
18
+ }
@@ -0,0 +1,175 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { getTemplateDir } from '../../utils/paths.js';
5
+ import { processTemplate } from '../../utils/template.js';
6
+ const AGENT_CONFIGS = {
7
+ outputai: {
8
+ id: 'outputai',
9
+ name: 'OutputAI Core Files',
10
+ mappings: [
11
+ {
12
+ type: 'template',
13
+ from: 'AGENTS.md.template',
14
+ to: '.outputai/AGENTS.md'
15
+ },
16
+ {
17
+ type: 'template',
18
+ from: 'agents/workflow_planner.md.template',
19
+ to: '.outputai/agents/workflow_planner.md'
20
+ },
21
+ {
22
+ type: 'template',
23
+ from: 'commands/plan_workflow.md.template',
24
+ to: '.outputai/commands/plan_workflow.md'
25
+ }
26
+ ]
27
+ },
28
+ 'claude-code': {
29
+ id: 'claude-code',
30
+ name: 'Claude Code',
31
+ mappings: [
32
+ {
33
+ type: 'symlink',
34
+ from: '.outputai/AGENTS.md',
35
+ to: 'CLAUDE.md'
36
+ },
37
+ {
38
+ type: 'symlink',
39
+ from: '.outputai/agents/workflow_planner.md',
40
+ to: '.claude/agents/workflow_planner.md'
41
+ },
42
+ {
43
+ type: 'symlink',
44
+ from: '.outputai/commands/plan_workflow.md',
45
+ to: '.claude/commands/plan_workflow.md'
46
+ }
47
+ ]
48
+ }
49
+ };
50
+ export default class Init extends Command {
51
+ static description = 'Initialize agent configuration files for AI assistant integration';
52
+ static examples = [
53
+ '<%= config.bin %> <%= command.id %>',
54
+ '<%= config.bin %> <%= command.id %> --agent-provider claude-code',
55
+ '<%= config.bin %> <%= command.id %> --force'
56
+ ];
57
+ static args = {};
58
+ static flags = {
59
+ 'agent-provider': Flags.string({
60
+ description: 'Specify the coding agent provider',
61
+ default: AGENT_CONFIGS['claude-code'].id,
62
+ options: [AGENT_CONFIGS['claude-code'].id]
63
+ }),
64
+ force: Flags.boolean({
65
+ char: 'f',
66
+ description: 'Overwrite existing files',
67
+ default: false
68
+ })
69
+ };
70
+ async run() {
71
+ const { flags } = await this.parse(Init);
72
+ this.log('Initializing agent configuration for Claude Code...');
73
+ try {
74
+ const variables = this.prepareTemplateVariables();
75
+ await this.processMappings(AGENT_CONFIGS.outputai, variables, flags.force);
76
+ await this.processMappings(AGENT_CONFIGS[flags['agent-provider']], variables, flags.force);
77
+ this.log('✅ Agent configuration initialized successfully!');
78
+ this.log('');
79
+ this.log('Created:');
80
+ this.log(' • .outputai/ directory with agent and command configurations');
81
+ this.log(' • .claude/ directory with symlinks for Claude Code integration');
82
+ this.log('');
83
+ this.log('Claude Code will automatically detect and use these configurations.');
84
+ }
85
+ catch (error) {
86
+ if (error.code === 'EACCES') {
87
+ this.error('Permission denied. Please check file permissions and try again.');
88
+ }
89
+ this.error(`Failed to initialize agent configuration: ${error.message}`);
90
+ }
91
+ }
92
+ prepareTemplateVariables() {
93
+ return {
94
+ date: new Date().toLocaleDateString('en-US', {
95
+ year: 'numeric',
96
+ month: 'long',
97
+ day: 'numeric'
98
+ })
99
+ };
100
+ }
101
+ async processMappings(config, variables, force) {
102
+ for (const mapping of config.mappings) {
103
+ const dir = path.dirname(mapping.to);
104
+ await this.ensureDirectoryExists(dir);
105
+ if (!force && await this.fileExists(mapping.to)) {
106
+ this.warn(`File already exists: ${mapping.to} (use --force to overwrite)`);
107
+ continue;
108
+ }
109
+ switch (mapping.type) {
110
+ case 'template':
111
+ await this.createFromTemplate(mapping.from, mapping.to, variables);
112
+ break;
113
+ case 'symlink':
114
+ await this.createSymlink(mapping.from, mapping.to);
115
+ break;
116
+ case 'copy':
117
+ await this.copyFile(mapping.from, mapping.to);
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ async ensureDirectoryExists(dir) {
123
+ try {
124
+ await fs.mkdir(dir, { recursive: true });
125
+ this.debug(`Created directory: ${dir}`);
126
+ }
127
+ catch (error) {
128
+ if (error.code !== 'EEXIST') {
129
+ throw error;
130
+ }
131
+ }
132
+ }
133
+ async fileExists(filePath) {
134
+ try {
135
+ await fs.stat(filePath);
136
+ return true;
137
+ }
138
+ catch {
139
+ return false;
140
+ }
141
+ }
142
+ async createFromTemplate(template, output, variables) {
143
+ const templateDir = getTemplateDir('agent_instructions');
144
+ const templatePath = path.join(templateDir, template);
145
+ const content = await fs.readFile(templatePath, 'utf-8');
146
+ const processed = processTemplate(content, variables);
147
+ await fs.writeFile(output, processed, 'utf-8');
148
+ this.debug(`Created from template: ${output}`);
149
+ }
150
+ async createSymlink(source, target) {
151
+ try {
152
+ if (await this.fileExists(target)) {
153
+ await fs.unlink(target);
154
+ }
155
+ const relativePath = path.relative(path.dirname(target), source);
156
+ await fs.symlink(relativePath, target);
157
+ this.debug(`Created symlink: ${target} -> ${source}`);
158
+ }
159
+ catch (error) {
160
+ const code = error.code;
161
+ if (code === 'ENOTSUP' || code === 'EPERM') {
162
+ this.debug(`Symlinks not supported, creating copy: ${target}`);
163
+ const content = await fs.readFile(source, 'utf-8');
164
+ await fs.writeFile(target, content, 'utf-8');
165
+ return;
166
+ }
167
+ throw error;
168
+ }
169
+ }
170
+ async copyFile(source, target) {
171
+ const content = await fs.readFile(source, 'utf-8');
172
+ await fs.writeFile(target, content, 'utf-8');
173
+ this.debug(`Copied file: ${source} -> ${target}`);
174
+ }
175
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,227 @@
1
+ /* eslint-disable no-restricted-syntax, @typescript-eslint/no-explicit-any, init-declarations */
2
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import Init from './init.js';
6
+ import { getTemplateDir } from '../../utils/paths.js';
7
+ import { processTemplate } from '../../utils/template.js';
8
+ vi.mock('node:fs/promises');
9
+ vi.mock('node:path', async () => {
10
+ const actual = await vi.importActual('node:path');
11
+ return {
12
+ ...actual,
13
+ join: vi.fn((...args) => args.join('/')),
14
+ dirname: vi.fn(p => p.split('/').slice(0, -1).join('/') || '.'),
15
+ relative: vi.fn((from, to) => {
16
+ if (to === 'CLAUDE.md' && from === '.') {
17
+ return '.outputai/AGENTS.md';
18
+ }
19
+ if (to.includes('.outputai/agents')) {
20
+ return `../../.outputai/agents/${path.basename(to)}`;
21
+ }
22
+ if (to.includes('.outputai/commands')) {
23
+ return `../../.outputai/commands/${path.basename(to)}`;
24
+ }
25
+ return to;
26
+ })
27
+ };
28
+ });
29
+ vi.mock('../../utils/paths.js');
30
+ vi.mock('../../utils/template.js');
31
+ describe('agents init', () => {
32
+ let mockGetTemplateDir;
33
+ let mockProcessTemplate;
34
+ const createTestCommand = (args = []) => {
35
+ const cmd = new Init(args, {});
36
+ cmd.log = vi.fn();
37
+ cmd.warn = vi.fn();
38
+ cmd.error = vi.fn();
39
+ cmd.debug = vi.fn();
40
+ cmd.parse = vi.fn();
41
+ return cmd;
42
+ };
43
+ beforeEach(() => {
44
+ vi.clearAllMocks();
45
+ vi.mocked(fs.mkdir).mockResolvedValue(undefined);
46
+ vi.mocked(fs.writeFile).mockResolvedValue(undefined);
47
+ vi.mocked(fs.symlink).mockResolvedValue(undefined);
48
+ vi.mocked(fs.stat).mockRejectedValue({ code: 'ENOENT' });
49
+ vi.mocked(fs.unlink).mockResolvedValue(undefined);
50
+ vi.mocked(fs.readFile).mockResolvedValue('Template content with {{date}}');
51
+ mockGetTemplateDir = vi.mocked(getTemplateDir);
52
+ mockGetTemplateDir.mockReturnValue('/templates/agent_instructions');
53
+ mockProcessTemplate = vi.mocked(processTemplate);
54
+ mockProcessTemplate.mockImplementation((content, variables) => {
55
+ return content.replace(/\{\{(\w+)\}\}/g, (_match, key) => variables[key] || _match);
56
+ });
57
+ });
58
+ afterEach(() => {
59
+ vi.restoreAllMocks();
60
+ });
61
+ describe('command structure', () => {
62
+ it('should have correct description', () => {
63
+ expect(Init.description).toBeDefined();
64
+ expect(Init.description).toContain('agent configuration');
65
+ });
66
+ it('should have correct examples', () => {
67
+ expect(Init.examples).toBeDefined();
68
+ expect(Array.isArray(Init.examples)).toBe(true);
69
+ });
70
+ it('should have no required arguments', () => {
71
+ expect(Init.args).toBeDefined();
72
+ expect(Object.keys(Init.args)).toHaveLength(0);
73
+ });
74
+ it('should have appropriate flags', () => {
75
+ expect(Init.flags).toBeDefined();
76
+ expect(Init.flags.force).toBeDefined();
77
+ });
78
+ });
79
+ describe('directory creation', () => {
80
+ it('should create .outputai directory structure', async () => {
81
+ const mockMkdir = vi.mocked(fs.mkdir);
82
+ mockMkdir.mockResolvedValue(undefined);
83
+ const cmd = createTestCommand();
84
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
85
+ await cmd.run();
86
+ expect(mockMkdir).toHaveBeenCalledWith(expect.stringContaining('.outputai'), expect.objectContaining({ recursive: true }));
87
+ expect(mockMkdir).toHaveBeenCalledWith(expect.stringContaining('.outputai/agents'), expect.objectContaining({ recursive: true }));
88
+ expect(mockMkdir).toHaveBeenCalledWith(expect.stringContaining('.outputai/commands'), expect.objectContaining({ recursive: true }));
89
+ });
90
+ it('should create .claude directory structure', async () => {
91
+ const mockMkdir = vi.mocked(fs.mkdir);
92
+ mockMkdir.mockResolvedValue(undefined);
93
+ const cmd = createTestCommand();
94
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
95
+ await cmd.run();
96
+ expect(mockMkdir).toHaveBeenCalledWith(expect.stringContaining('.claude'), expect.objectContaining({ recursive: true }));
97
+ expect(mockMkdir).toHaveBeenCalledWith(expect.stringContaining('.claude/agents'), expect.objectContaining({ recursive: true }));
98
+ expect(mockMkdir).toHaveBeenCalledWith(expect.stringContaining('.claude/commands'), expect.objectContaining({ recursive: true }));
99
+ });
100
+ });
101
+ describe('file creation from templates', () => {
102
+ it('should create AGENTS.md file from template', async () => {
103
+ const mockWriteFile = vi.mocked(fs.writeFile);
104
+ const mockReadFile = vi.mocked(fs.readFile);
105
+ mockReadFile.mockResolvedValue('Agent instructions {{date}}');
106
+ const cmd = createTestCommand();
107
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
108
+ await cmd.run();
109
+ expect(mockReadFile).toHaveBeenCalledWith(expect.stringContaining('AGENTS.md.template'), 'utf-8');
110
+ expect(mockWriteFile).toHaveBeenCalledWith('.outputai/AGENTS.md', expect.stringContaining('Agent instructions'), 'utf-8');
111
+ });
112
+ it('should create all agent configuration files', async () => {
113
+ const mockWriteFile = vi.mocked(fs.writeFile);
114
+ const cmd = createTestCommand();
115
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
116
+ await cmd.run();
117
+ const agentFiles = [
118
+ '.outputai/agents/workflow_planner.md'
119
+ ];
120
+ for (const file of agentFiles) {
121
+ expect(mockWriteFile).toHaveBeenCalledWith(file, expect.any(String), 'utf-8');
122
+ }
123
+ });
124
+ it('should create all command configuration files', async () => {
125
+ const mockWriteFile = vi.mocked(fs.writeFile);
126
+ const cmd = createTestCommand();
127
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
128
+ await cmd.run();
129
+ const commandFiles = [
130
+ '.outputai/commands/plan_workflow.md'
131
+ ];
132
+ for (const file of commandFiles) {
133
+ expect(mockWriteFile).toHaveBeenCalledWith(file, expect.any(String), 'utf-8');
134
+ }
135
+ });
136
+ });
137
+ describe('symlink creation', () => {
138
+ it('should create symlink from CLAUDE.md to .outputai/AGENTS.md', async () => {
139
+ const mockSymlink = vi.mocked(fs.symlink);
140
+ const mockStat = vi.mocked(fs.stat);
141
+ mockStat.mockImplementation(async (path) => {
142
+ if (typeof path === 'string' && path.startsWith('.outputai')) {
143
+ return { isFile: () => true };
144
+ }
145
+ throw { code: 'ENOENT' };
146
+ });
147
+ const cmd = createTestCommand();
148
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
149
+ await cmd.run();
150
+ expect(mockSymlink).toHaveBeenCalledWith('.outputai/AGENTS.md', 'CLAUDE.md');
151
+ });
152
+ it('should create symlinks for all agent files', async () => {
153
+ const mockSymlink = vi.mocked(fs.symlink);
154
+ const cmd = createTestCommand();
155
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
156
+ await cmd.run();
157
+ expect(mockSymlink).toHaveBeenCalledWith(expect.stringContaining('.outputai/agents/workflow_planner.md'), '.claude/agents/workflow_planner.md');
158
+ });
159
+ it('should create symlinks for all command files', async () => {
160
+ const mockSymlink = vi.mocked(fs.symlink);
161
+ const cmd = createTestCommand();
162
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
163
+ await cmd.run();
164
+ expect(mockSymlink).toHaveBeenCalledWith(expect.stringContaining('.outputai/commands/plan_workflow.md'), '.claude/commands/plan_workflow.md');
165
+ });
166
+ it('should handle Windows by copying files when symlinks are not supported', async () => {
167
+ const mockSymlink = vi.mocked(fs.symlink);
168
+ const mockWriteFile = vi.mocked(fs.writeFile);
169
+ const mockReadFile = vi.mocked(fs.readFile);
170
+ mockSymlink.mockRejectedValue({ code: 'ENOTSUP' });
171
+ mockReadFile.mockResolvedValue('File content');
172
+ const cmd = createTestCommand();
173
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
174
+ await cmd.run();
175
+ expect(mockReadFile).toHaveBeenCalledWith('.outputai/AGENTS.md', 'utf-8');
176
+ expect(mockWriteFile).toHaveBeenCalledWith('CLAUDE.md', 'File content', 'utf-8');
177
+ });
178
+ });
179
+ describe('error handling', () => {
180
+ it('should handle existing directory gracefully', async () => {
181
+ const mockMkdir = vi.mocked(fs.mkdir);
182
+ mockMkdir.mockRejectedValue({ code: 'EEXIST' });
183
+ const cmd = createTestCommand();
184
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
185
+ await cmd.run();
186
+ expect(cmd.error).not.toHaveBeenCalled();
187
+ });
188
+ it('should handle permission errors', async () => {
189
+ const mockMkdir = vi.mocked(fs.mkdir);
190
+ mockMkdir.mockRejectedValue({ code: 'EACCES' });
191
+ const cmd = createTestCommand();
192
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
193
+ await cmd.run();
194
+ expect(cmd.error).toHaveBeenCalledWith(expect.stringContaining('Permission denied'));
195
+ });
196
+ it('should be idempotent (safe to run multiple times)', async () => {
197
+ const mockWriteFile = vi.mocked(fs.writeFile);
198
+ mockWriteFile.mockResolvedValue(undefined);
199
+ const cmd = createTestCommand();
200
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
201
+ await cmd.run();
202
+ await cmd.run();
203
+ expect(cmd.error).not.toHaveBeenCalled();
204
+ });
205
+ });
206
+ describe('force flag', () => {
207
+ it('should overwrite existing files when force flag is set', async () => {
208
+ const mockWriteFile = vi.mocked(fs.writeFile);
209
+ const mockStat = vi.mocked(fs.stat);
210
+ mockStat.mockResolvedValue({ isFile: () => true });
211
+ mockWriteFile.mockResolvedValue(undefined);
212
+ const cmd = createTestCommand(['--force']);
213
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: true }, args: {} });
214
+ await cmd.run();
215
+ expect(mockWriteFile).toHaveBeenCalled();
216
+ expect(cmd.warn).not.toHaveBeenCalled();
217
+ });
218
+ it('should warn about existing files without force flag', async () => {
219
+ const mockStat = vi.mocked(fs.stat);
220
+ mockStat.mockResolvedValue({ isFile: () => true });
221
+ const cmd = createTestCommand();
222
+ cmd.parse.mockResolvedValue({ flags: { 'agent-provider': 'claude-code', force: false }, args: {} });
223
+ await cmd.run();
224
+ expect(cmd.warn).toHaveBeenCalledWith(expect.stringContaining('already exists'));
225
+ });
226
+ });
227
+ });
@@ -2,7 +2,7 @@ import { Args, Command, Flags } from '@oclif/core';
2
2
  import { generateWorkflow } from '../../services/workflow_generator.js';
3
3
  import { DEFAULT_OUTPUT_DIRS } from '../../utils/paths.js';
4
4
  export default class Generate extends Command {
5
- static description = 'Generate a new Flow SDK workflow';
5
+ static description = 'Generate a new Output SDK workflow';
6
6
  static examples = [
7
7
  '<%= config.bin %> <%= command.id %> my-workflow',
8
8
  '<%= config.bin %> <%= command.id %> my-workflow --skeleton',
@@ -0,0 +1,30 @@
1
+ ---
2
+ generated_by: "@output.ai/cli"
3
+ version: "{{cliVersion}}"
4
+ generated_on: "{{date}}"
5
+ ---
6
+
7
+ # Output SDK Workflow Planning Agent Configuration
8
+
9
+ This directory contains AI agent configuration for workflow planning assistance in Output SDK development. Claude Code will automatically detect and use this configuration when planning workflows in your project.
10
+
11
+ ## Available Agent
12
+
13
+ ### 🤖 workflow_planner
14
+ - **Purpose**: Assists with workflow architecture and planning
15
+ - **Capabilities**: System design, workflow structure, step organization, requirements analysis
16
+ - **Usage**: Planning new workflows, architectural decisions, creating implementation blueprints
17
+
18
+ ## Integration
19
+
20
+ This agent configuration integrates with:
21
+ - **Claude Code**: AI-powered development assistant
22
+ - **Output SDK**: Temporal-based workflow orchestration framework
23
+ - **TypeScript**: Type-safe development patterns
24
+ - **XML Process Flow**: Structured planning with validation checkpoints
25
+
26
+ ## Usage
27
+
28
+ The workflow planning agent is automatically available when using Claude Code in projects with this configuration. It provides specialized expertise for the planning and architecture phase of Output SDK workflow development.
29
+
30
+ To regenerate this configuration: `output-cli agents init --force`
@@ -0,0 +1,104 @@
1
+ ---
2
+ name: workflow-planner
3
+ description: Use this agent when you need to design new workflows for the Output SDK system, plan complex workflow orchestrations, or create comprehensive implementation blueprints before coding. This agent should be invoked at the beginning of workflow development to ensure proper architecture and complete requirements gathering.
4
+ model: opus
5
+ color: blue
6
+ ---
7
+
8
+ # Workflow Planner Agent
9
+
10
+ ## Identity
11
+ You are a Output SDK workflow planning specialist who follows structured XML-based planning processes to create comprehensive workflow implementation blueprints. You operate within a systematic framework defined by pre-flight and post-flight validation checks.
12
+
13
+ ## Core Process
14
+ Your workflow planning follows the structured process defined in `/plan_workflow` command with explicit numbered steps and validation checkpoints. You must adhere to the meta rules defined in:
15
+ - **Pre-Flight**: `@{{projectPath}}/.outputai/instructions/meta/pre_flight.md`
16
+ - **Post-Flight**: `@{{projectPath}}/.outputai/instructions/meta/post_flight.md`
17
+
18
+ ## Expertise
19
+ - **Temporal based Workflow Design**: Orchestrating complex business processes with proper activity boundaries
20
+ - **Output SDK Architecture**: Leveraging Output SDK abstractions and patterns effectively
21
+ - **System Integration**: Designing workflows that integrate with external services and APIs
22
+ - **Scalability Planning**: Architecting workflows for performance and growth
23
+ - **Error Handling Strategy**: Planning comprehensive error handling and retry policies
24
+ - **Smart Defaults**: Applying intelligent defaults to minimize user interaction
25
+
26
+ ## Smart Defaults Strategy
27
+
28
+ ### Automatic Inference
29
+ Apply these defaults unless explicitly overridden:
30
+ - **Retry Policy**: 3 attempts, exponential backoff (1s initial, 10s max)
31
+ - **Timeouts**: 30 seconds for activities, 5 minutes for workflows
32
+ - **OpenAI Model**: gpt-4o for LLM operations
33
+ - **Error Handling**: ApplicationFailure patterns with appropriate types
34
+ - **Performance**: Optimize for clarity and maintainability over speed
35
+
36
+ ### Critical Questions Only
37
+ Only request clarification for:
38
+ - Ambiguous input/output structures that cannot be inferred
39
+ - Non-standard API integrations not in the codebase
40
+ - Complex orchestration patterns requiring specific sequencing
41
+ - Unusual error handling or recovery requirements
42
+
43
+ ## Primary Responsibilities
44
+
45
+ ### 🎯 Step 1-2: Requirements & Pattern Analysis
46
+ - Analyze requirements with smart inference to minimize questions
47
+ - Search for similar workflows and reusable patterns
48
+ - Identify applicable activities and utilities
49
+ - Document requirements in structured format
50
+
51
+ ### 📋 Step 3-4: Schema & Activity Design
52
+ - Define Zod schemas with OpenAI compatibility
53
+ - Design activities with clear boundaries and responsibilities
54
+ - Plan error handling and retry strategies
55
+ - Specify workerModule service usage
56
+
57
+ ### 🏗️ Step 5-6: Prompt & Orchestration Planning
58
+ - Design LLM prompts with template variables (if applicable)
59
+ - Define workflow execution logic step-by-step
60
+ - Plan conditional logic and data flow
61
+ - Generate TypeScript code templates
62
+
63
+ ### ⚖️ Step 7-9: Documentation & Review
64
+ - Create comprehensive plan document
65
+ - Define testing strategy with specific scenarios
66
+ - Prepare implementation checklist
67
+ - Request user review and approval
68
+
69
+ ## Output SDK Conventions
70
+
71
+ ### Mandatory Rules
72
+ - All imports MUST use `.js` extension for ESM modules
73
+ - NEVER use axios directly - always use HttpClient wrapper
74
+ - Export workflow in entrypoint.ts: `export * from './path/to/workflow.js';`
75
+ - Restart worker after creating workflows: `overmind restart worker`
76
+ - All workflows must have test files with validation tests
77
+ - Run `yarn g:workflow-doc` after modifications
78
+
79
+ ### Service Access
80
+ - Use workerModule for all external services
81
+ - Available clients: OpenAI, Anthropic, Perplexity, S3, logger
82
+ - Reference: `@{{projectPath}}/docs/sdk/third-party-clients.md`
83
+
84
+ ## Context Awareness
85
+ - **Output SDK Patterns**: Deep understanding of workflow, step, and LLM abstractions
86
+ - **Temporal Best Practices**: Knowledge of workflow determinism and activity patterns
87
+ - **TypeScript Integration**: Expertise with type-safe workflow development
88
+ - **Testing Strategy**: Planning workflows for comprehensive test coverage
89
+ - **XML Process Flow**: Following structured steps with explicit subagent delegation
90
+
91
+ ## Communication Style
92
+ - **Strategic**: Focus on high-level architecture and long-term maintainability
93
+ - **Analytical**: Break down complex requirements into manageable components
94
+ - **Advisory**: Provide recommendations with clear reasoning and trade-offs
95
+ - **Forward-thinking**: Consider future extensibility and scaling needs
96
+
97
+ ## Example Interactions
98
+ - "How should I structure a workflow that processes customer orders with external payment validation?"
99
+ - "What's the best way to handle retry logic for workflows with multiple API integrations?"
100
+ - "How do I design a workflow that can be easily extended with new processing steps?"
101
+ - "What error handling strategy should I use for a workflow with both synchronous and asynchronous steps?"
102
+
103
+ ---
104
+ *This agent specializes in the planning and architecture phase of Output SDK workflow development.*
@@ -0,0 +1,466 @@
1
+ ---
2
+ description: Workflow Planning Command for Output SDK
3
+ version: 2.0
4
+ encoding: UTF-8
5
+ ---
6
+
7
+ # Plan Workflow Command
8
+
9
+ ## Overview
10
+
11
+ Generate comprehensive workflow implementation plans following Output SDK patterns and best practices.
12
+
13
+ <pre_flight_check>
14
+ EXECUTE: @{{projectPath}}/.outputai/instructions/meta/pre_flight.md
15
+ </pre_flight_check>
16
+
17
+ <process_flow>
18
+
19
+ <step number="1" subagent="workflow_planner" name="requirements_analysis">
20
+
21
+ ### Step 1: Requirements Analysis
22
+
23
+ Use the workflow_planner subagent to analyze the workflow requirements and infer smart defaults.
24
+
25
+ <smart_inference>
26
+ <approach>Infer requirements from description and apply defaults</approach>
27
+ <defaults>
28
+ - retry_policy: 3 attempts with exponential backoff
29
+ - timeout: 30s for activities, 5m for workflows
30
+ - openai_model: gpt-4o unless specified
31
+ - error_handling: ApplicationFailure patterns
32
+ - performance: clarity over speed optimization
33
+ </defaults>
34
+ </smart_inference>
35
+
36
+ <critical_questions>
37
+ ASK ONLY if cannot be inferred:
38
+ - Ambiguous input/output structures
39
+ - Non-standard API integrations
40
+ - Complex orchestration patterns
41
+ - Unusual error handling requirements
42
+ </critical_questions>
43
+
44
+ <requirements_template>
45
+ ## Requirements Analysis
46
+
47
+ **Goal**: {{workflowGoal}}
48
+ **Input**: {{inputDescription}}
49
+ **Output**: {{outputDescription}}
50
+ **External Services**: {{servicesList}}
51
+ **Constraints**: {{constraintsList}}
52
+ </requirements_template>
53
+
54
+ </step>
55
+
56
+ <step number="2" name="pattern_analysis">
57
+
58
+ ### Step 2: Pattern Analysis
59
+
60
+ <analysis_targets>
61
+ - Check the repository for similar implementations
62
+ - Identify reusable activities
63
+ - Find applicable prompt templates in workflow directories
64
+ - Locate relevant schemas and types
65
+ </analysis_targets>
66
+
67
+ <pattern_collection>
68
+ <existing_workflows>workflows with similar purpose or structure</existing_workflows>
69
+ <reusable_activities>activities that can be leveraged</reusable_activities>
70
+ <error_patterns>established error handling patterns</error_patterns>
71
+ <retry_policies>common retry configurations</retry_policies>
72
+ </pattern_collection>
73
+
74
+ </step>
75
+
76
+ <step number="3" subagent="workflow_planner" name="schema_definition">
77
+
78
+ ### Step 3: Schema Definition
79
+
80
+ Use the workflow_planner subagent to define input/output schemas with Zod validation.
81
+
82
+ <schema_requirements>
83
+ - Use simple TypeScript interfaces for basic types
84
+ - Use Zod schemas when validation is needed
85
+ - Keep field types simple: string, number, boolean, object
86
+ - Mark optional fields with ? in interfaces or .optional() in Zod
87
+ - Export types for reuse across workflow files
88
+ </schema_requirements>
89
+
90
+ <input_schema_template>
91
+ ```typescript
92
+ // For simple types (types.ts)
93
+ export interface {{WorkflowName}}Input {
94
+ {{requiredField}}: string;
95
+ {{optionalField}}?: string;
96
+ }
97
+
98
+ // Or for validation with Zod
99
+ import { z } from 'zod';
100
+
101
+ export const {{WorkflowName}}InputSchema = z.object({
102
+ {{requiredField}}: z.string(),
103
+ {{optionalField}}: z.string().optional()
104
+ });
105
+
106
+ export type {{WorkflowName}}Input = z.infer<typeof {{WorkflowName}}InputSchema>;
107
+ ```
108
+ </input_schema_template>
109
+
110
+ <output_schema_template>
111
+ ```typescript
112
+ export interface {{WorkflowName}}Output {
113
+ result: string;
114
+ // Additional fields as needed
115
+ {{additionalFields}}
116
+ }
117
+ ```
118
+ </output_schema_template>
119
+
120
+ </step>
121
+
122
+ <step number="4" subagent="workflow_planner" name="activity_design">
123
+
124
+ ### Step 4: Activity Design
125
+
126
+ Use the workflow_planner subagent to design workflow activities with clear boundaries.
127
+
128
+ <activity_template>
129
+ ### Step: `{{stepName}}`
130
+
131
+ **Purpose**: {{stepPurpose}}
132
+
133
+ **Implementation (steps.ts)**:
134
+ ```typescript
135
+ import { step } from '@output.ai/core';
136
+ import { generateText, generateObject } from '@output.ai/llm';
137
+ import { loadPrompt } from '@output.ai/prompt';
138
+ import type { Prompt } from '@output.ai/llm';
139
+
140
+ export const {{stepName}} = step({
141
+ name: '{{stepName}}',
142
+ description: '{{stepDescription}}',
143
+ inputSchema: {
144
+ type: 'object',
145
+ required: [{{requiredFields}}],
146
+ properties: {
147
+ {{fieldName}}: { type: '{{fieldType}}' }
148
+ // Add more fields as needed
149
+ }
150
+ },
151
+ outputSchema: {
152
+ type: '{{outputType}}'
153
+ },
154
+ fn: async (input) => {
155
+ // Implementation logic
156
+ {{implementationLogic}}
157
+
158
+ // For LLM operations:
159
+ // const prompt = loadPrompt('{{promptName}}', input);
160
+ // const response = await generateText(prompt as Prompt);
161
+
162
+ return {{returnValue}};
163
+ }
164
+ });
165
+ ```
166
+
167
+ **Error Handling**:
168
+ - Use `FatalError` from '@output.ai/core' for non-retryable errors
169
+ - Standard errors will be retried based on workflow configuration
170
+ </activity_template>
171
+
172
+ <decision_tree>
173
+ IF step_uses_llm:
174
+ USE generateText or generateObject from @output.ai/llm
175
+ LOAD prompts with loadPrompt from @output.ai/prompt
176
+ DEFINE error handling with FatalError
177
+ ELSE IF step_uses_external_service:
178
+ IMPORT required service libraries
179
+ HANDLE errors appropriately
180
+ ELSE:
181
+ IMPLEMENT pure logic
182
+ VALIDATE inputs/outputs
183
+ </decision_tree>
184
+
185
+ </step>
186
+
187
+ <step number="5" subagent="workflow_planner" name="prompt_engineering">
188
+
189
+ ### Step 5: Prompt Engineering (Conditional)
190
+
191
+ Use the workflow_planner subagent to design LLM prompts if the workflow uses AI services.
192
+
193
+ <decision_tree>
194
+ IF workflow_uses_llm:
195
+ EXECUTE prompt_design
196
+ ELSE:
197
+ SKIP to step 6
198
+ </decision_tree>
199
+
200
+ <prompt_template>
201
+ **Prompt File ({{promptName}}@v1.prompt)**:
202
+ ```yaml
203
+ ---
204
+ provider: {{provider}} # anthropic, openai, etc.
205
+ model: {{model}} # e.g., claude-sonnet-4-20250514, gpt-4o
206
+ temperature: {{temperature}} # e.g., 0.7
207
+ ---
208
+
209
+ <assistant>
210
+ {{systemPrompt}}
211
+ </assistant>
212
+
213
+ <user>
214
+ {{userPrompt}}
215
+
216
+ Variables to include:
217
+ {{ "{{ " }}{{variableName}}{{ " }}" }}
218
+ </user>
219
+ ```
220
+ </prompt_template>
221
+
222
+ <template_variables>
223
+ **Template Variables**:
224
+ - `{{ "{{ " }}{{variableName1}}{{ " }}" }}` - {{description1}}
225
+ - `{{ "{{ " }}{{variableName2}}{{ " }}" }}` - {{description2}}
226
+
227
+ **Loading in Step**:
228
+ ```typescript
229
+ const prompt = loadPrompt('{{promptName}}@v1', {
230
+ {{variableName1}}: input.{{field1}},
231
+ {{variableName2}}: input.{{field2}}
232
+ });
233
+ ```
234
+ </template_variables>
235
+
236
+ </step>
237
+
238
+ <step number="6" subagent="workflow_planner" name="orchestration_planning">
239
+
240
+ ### Step 6: Workflow Orchestration
241
+
242
+ Use the workflow_planner subagent to define the workflow execution logic.
243
+
244
+ <orchestration_template>
245
+ ## Workflow Logic
246
+
247
+ 1. **Input Validation**: `validateWorkflowInput(rawInput, {{WorkflowName}}InputSchema)`
248
+ 2. **{{Step2Name}}**: {{step2Description}}
249
+ 3. **{{Step3Name}}**: Call `{{activityName}}({{parameters}})`
250
+ 4. **{{Step4Name}}**: {{step4Description}}
251
+ 5. **Result Assembly**: Structure final output with metadata
252
+ 6. **Return**: Complete {{WorkflowName}}Output object
253
+
254
+ **Conditional Logic**:
255
+ {{conditionalRules}}
256
+ </orchestration_template>
257
+
258
+ <workflow_code_template>
259
+ **Workflow File (workflow.ts)**:
260
+ ```typescript
261
+ import { workflow } from '@output.ai/core';
262
+ import { {{stepImports}} } from './steps.js';
263
+ import type { {{WorkflowName}}Input, {{WorkflowName}}Output } from './types.js';
264
+
265
+ export default workflow({
266
+ name: '{{workflowName}}',
267
+ description: '{{workflowDescription}}',
268
+ inputSchema: {
269
+ type: 'object',
270
+ required: [{{requiredFields}}],
271
+ properties: {
272
+ {{fieldName}}: { type: '{{fieldType}}' }
273
+ // Define all input fields
274
+ }
275
+ },
276
+ outputSchema: {
277
+ type: 'object',
278
+ required: [{{outputRequiredFields}}],
279
+ properties: {
280
+ result: { type: 'string' }
281
+ // Define output structure
282
+ }
283
+ },
284
+ fn: async (input: {{WorkflowName}}Input): Promise<{{WorkflowName}}Output> => {
285
+ // Workflow orchestration logic
286
+ {{orchestrationSteps}}
287
+
288
+ // Example step invocation:
289
+ // const result = await {{stepName}}({ {{stepParams}} });
290
+
291
+ return {
292
+ result: {{resultValue}}
293
+ };
294
+ }
295
+ });
296
+ ```
297
+ </workflow_code_template>
298
+
299
+ </step>
300
+
301
+ <step number="7" name="plan_document_creation">
302
+
303
+ ### Step 7: Create Plan Document
304
+
305
+ <plan_structure>
306
+ # Workflow Plan: {{WorkflowName}}
307
+
308
+ ## Overview
309
+ - **Purpose**: {{purpose}}
310
+ - **Use Case**: {{useCase}}
311
+ - **Key Features**: {{features}}
312
+
313
+ ## Technical Specifications
314
+ {{schemaDefinitions}}
315
+
316
+ ## Activity Specifications
317
+ {{activityDefinitions}}
318
+
319
+ ## Prompt Specifications (if applicable)
320
+ {{promptDefinitions}}
321
+
322
+ ## Workflow Orchestration
323
+ {{orchestrationLogic}}
324
+
325
+ ## Implementation Checklist
326
+ - [ ] Create workflow directory structure
327
+ - [ ] Implement input/output schemas
328
+ - [ ] Create activity functions
329
+ - [ ] Design prompt templates (if needed)
330
+ - [ ] Implement workflow logic
331
+ - [ ] Add to entrypoint.ts
332
+ - [ ] Write unit tests
333
+ - [ ] Test with flow-cli
334
+ - [ ] Run integration tests
335
+ - [ ] Update documentation
336
+ </plan_structure>
337
+
338
+ <file_location>
339
+ workflow_plans/{{workflowName}}-plan.md
340
+ </file_location>
341
+
342
+ </step>
343
+
344
+ <step number="8" subagent="workflow_planner" name="testing_strategy">
345
+
346
+ ### Step 8: Define Testing Strategy
347
+
348
+ Use the workflow_planner subagent to create comprehensive testing requirements.
349
+
350
+ <test_scenarios>
351
+ ## Testing Plan
352
+
353
+ ### Happy Path Tests
354
+ 1. **Complete Input**: All fields provided, successful execution
355
+ 2. **Minimal Input**: Required fields only
356
+ 3. **Variations**: Different input combinations
357
+
358
+ ### Edge Cases
359
+ 1. **Boundary Values**: Min/max values, empty strings
360
+ 2. **Special Characters**: Unicode, punctuation
361
+ 3. **Optional Fields**: With/without optional data
362
+
363
+ ### Error Scenarios
364
+ 1. **Invalid Input**: Malformed data, wrong types
365
+ 2. **Service Failures**: API errors, timeouts
366
+ 3. **Schema Violations**: Invalid responses
367
+
368
+ ### Performance Tests
369
+ 1. **Response Time**: Must complete within {{timeout}}
370
+ 2. **Concurrent Execution**: Multiple workflow instances
371
+ 3. **Resource Usage**: Monitor memory and CPU
372
+ </test_scenarios>
373
+
374
+ <test_commands>
375
+ ```bash
376
+ # Build the workflow
377
+ npm run build
378
+
379
+ # Start the worker (in one terminal)
380
+ npm run start # or flow-worker
381
+
382
+ # Execute workflow (in another terminal or via API)
383
+ # Via API endpoint if configured
384
+ curl -X POST http://localhost:3000/workflows/{{workflowName}} \
385
+ -H "Content-Type: application/json" \
386
+ -d '{{testPayload}}'
387
+
388
+ # Run validation
389
+ ./run.sh validate
390
+
391
+ # Development mode with Docker
392
+ ./run.sh dev
393
+ ```
394
+ </test_commands>
395
+
396
+ </step>
397
+
398
+ <step number="9" name="review_checkpoint">
399
+
400
+ ### Step 9: Review and Approval
401
+
402
+ Request user review of the workflow plan before proceeding to implementation.
403
+
404
+ <review_template>
405
+ I've completed the workflow plan for {{workflowName}}:
406
+
407
+ 📋 **Plan Document**: `workflow_plans/{{workflowName}}-plan.md`
408
+
409
+ The plan includes:
410
+ - Complete input/output schemas with Zod validation
411
+ - {{activityCount}} activity specifications with error handling
412
+ - Workflow orchestration logic
413
+ - Comprehensive testing strategy
414
+ - Implementation checklist
415
+
416
+ Please review the plan and let me know if any modifications are needed.
417
+ </review_template>
418
+
419
+ </step>
420
+
421
+ </process_flow>
422
+
423
+ <post_flight_check>
424
+ EXECUTE: @{{projectPath}}/.outputai/instructions/meta/post_flight.md
425
+ </post_flight_check>
426
+
427
+ ## Command Usage
428
+
429
+ ### Basic Planning
430
+ ```
431
+ /plan-workflow "Process customer support tickets using AI categorization"
432
+ ```
433
+
434
+ ### With Complexity Hints
435
+ ```
436
+ /plan-workflow "Multi-step data pipeline with validation" --complexity=complex --integrations=apis,llm
437
+ ```
438
+
439
+ ### Integration-Heavy Workflow
440
+ ```
441
+ /plan-workflow "E-commerce order fulfillment" --integrations=payment,inventory,shipping
442
+ ```
443
+
444
+ ## Quality Standards
445
+
446
+ ### Plan Completeness
447
+ - All schemas defined with exact types
448
+ - Every activity specified with I/O and processing logic
449
+ - External services identified with SDK references
450
+ - Error handling complete for all scenarios
451
+ - Testing scenarios documented with commands
452
+
453
+ ### Output SDK Compliance
454
+ - ES module imports with .js extensions
455
+ - Use @output.ai/core for workflow and step functions
456
+ - Use @output.ai/llm for AI operations
457
+ - Use @output.ai/prompt for prompt loading
458
+ - Use FatalError from @output.ai/core for non-retryable errors
459
+ - Follow established workflow file structure (workflow.ts, steps.ts, types.ts, *.prompt)
460
+
461
+ ### Implementation Readiness
462
+ - Developer can implement without clarification
463
+ - All code examples compile without modification
464
+ - Testing approach is comprehensive
465
+ - Performance requirements are measurable
466
+ - Documentation is clear and actionable
@@ -0,0 +1,94 @@
1
+ ---
2
+ description: Post-Flight Validation for Output SDK Workflow Operations
3
+ version: 1.0
4
+ encoding: UTF-8
5
+ ---
6
+
7
+ # Post-Flight Rules for Output SDK Workflows
8
+
9
+ ## Execution Verification
10
+
11
+ After completing all steps in the process_flow, systematically verify:
12
+
13
+ ### Step Completion Audit
14
+ - [ ] Every numbered step has been read, executed, and delivered according to its instructions
15
+ - [ ] All steps that specified a subagent were delegated to the correct subagent
16
+ - [ ] If any subagent was not used as specified, document why and report to the user
17
+ - [ ] If any step was not executed according to instructions, explain which part was misread or skipped
18
+
19
+ ### Output SDK Convention Compliance
20
+
21
+ Verify the following conventions were followed:
22
+
23
+ #### Import Conventions
24
+ - [ ] All TypeScript/JavaScript imports use `.js` extension for ES modules
25
+ - [ ] No direct axios usage - HttpClient wrapper used throughout
26
+ - [ ] Proper import paths for Output SDK packages (@flowsdk/core, @flowsdk/llm, etc.)
27
+
28
+ #### Workflow Structure
29
+ - [ ] Workflow exported in entrypoint.ts: `export * from './path/to/workflow.js';`
30
+ - [ ] All external operations wrapped in Temporal activities (steps)
31
+ - [ ] Proper error handling with ApplicationFailure patterns
32
+ - [ ] Retry policies configured appropriately
33
+
34
+ #### Documentation & Testing
35
+ - [ ] Comprehensive plan document created with all required sections
36
+ - [ ] Testing strategy defined with specific test scenarios
37
+ - [ ] Implementation checklist provided for developers
38
+ - [ ] All code examples are complete and would compile
39
+
40
+ ## Quality Validation
41
+
42
+ ### Plan Completeness Check
43
+ Ensure the workflow plan includes:
44
+ - [ ] **Overview**: Clear purpose and use case definition
45
+ - [ ] **Technical Specifications**: Complete input/output schemas with Zod validation
46
+ - [ ] **Activity Definitions**: Each activity fully specified with purpose, I/O, and error handling
47
+ - [ ] **Prompt Engineering**: LLM prompts designed (if applicable) with template variables
48
+ - [ ] **Orchestration Logic**: Step-by-step workflow execution flow
49
+ - [ ] **Retry Policies**: Configured for each activity with appropriate timeouts
50
+ - [ ] **Testing Requirements**: Comprehensive test scenarios and commands
51
+
52
+ ### Implementation Readiness
53
+ Confirm the plan is ready for implementation:
54
+ - [ ] All schemas defined with exact field types and descriptions
55
+ - [ ] Every activity specified with input/output/processing logic
56
+ - [ ] External services identified with specific SDK client references
57
+ - [ ] Error handling complete for all failure scenarios
58
+ - [ ] Testing scenarios documented with expected outcomes
59
+ - [ ] Performance requirements clear with measurable criteria
60
+
61
+ ## Deliverable Verification
62
+
63
+ ### Required Outputs
64
+ Verify these deliverables were created or updated:
65
+ - [ ] Workflow plan document with full specifications
66
+ - [ ] Activity schemas with Zod validation
67
+ - [ ] Prompt templates (if LLM integration required)
68
+ - [ ] Testing strategy with specific commands
69
+ - [ ] Implementation checklist for developers
70
+
71
+ ### Next Steps Documentation
72
+ Ensure the following guidance is provided:
73
+ - [ ] Clear handoff to implementation phase
74
+ - [ ] Specific Output SDK CLI commands to execute
75
+ - [ ] Dependencies to install (if any)
76
+ - [ ] Configuration requirements documented
77
+ - [ ] Success criteria clearly defined
78
+
79
+ ## Error Reporting
80
+
81
+ If any issues were encountered:
82
+ 1. Document the specific issue and step where it occurred
83
+ 2. Explain any deviations from the planned process
84
+ 3. Provide recommendations for resolution
85
+ 4. Note any missing information that prevented completion
86
+
87
+ ## Final Validation
88
+
89
+ Before marking the workflow planning complete:
90
+ - [ ] Developer can implement without additional clarification
91
+ - [ ] All Output SDK patterns and conventions are followed
92
+ - [ ] Testing approach is comprehensive and executable
93
+ - [ ] Documentation is clear and complete
94
+ - [ ] Plan aligns with project's existing workflow patterns
@@ -0,0 +1,60 @@
1
+ ---
2
+ description: Pre-Flight Checks for Output SDK Workflow Operations
3
+ version: 1.0
4
+ encoding: UTF-8
5
+ ---
6
+
7
+ # Pre-Flight Rules for Output SDK Workflows
8
+
9
+ ## Execution Requirements
10
+
11
+ - **CRITICAL**: For any step that specifies a subagent in the `subagent=""` XML attribute, you MUST use the specified subagent to perform the instructions for that step
12
+ - Process all XML blocks sequentially and completely
13
+ - Execute every numbered step in the process_flow EXACTLY as specified
14
+
15
+ ## Output SDK Conventions Check
16
+
17
+ Before proceeding with any workflow operation, verify:
18
+
19
+ - **ES Modules**: All imports MUST use `.js` extension for ESM modules
20
+ - **HTTP Client**: NEVER use axios directly - always use @output.ai/http wrapper
21
+ - **LLM Client**: NEVER use a direct llm call - always use @output.ai/llm wrapper
22
+ - **Worker Restarts**: Remember to restart worker after creating workflows: `overmind restart worker`
23
+ - **Documentation**: Run `yarn g:workflow-doc` after modifications
24
+
25
+ ## Requirements Gathering Strategy
26
+
27
+ ### Smart Defaults Application
28
+ When information is not explicitly provided, apply these defaults:
29
+ - **Retry Policies**: 3 attempts with exponential backoff (1s initial, 10s max)
30
+ - **OpenAI Models**: Use `gpt-4o` unless specified otherwise
31
+ - **Error Handling**: ApplicationFailure patterns with appropriate error types
32
+ - **Performance**: Optimize for clarity and maintainability over raw speed
33
+ - **Timeouts**: 30 seconds for activities, 5 minutes for workflows
34
+
35
+ ### Critical Information Requirements
36
+ Only stop to ask for clarification on:
37
+ - Ambiguous input/output structures that cannot be inferred from context
38
+ - Specific API keys or services not commonly used in the project
39
+ - Non-standard error handling or recovery requirements
40
+ - Complex orchestration patterns requiring specific sequencing
41
+ - External dependencies not already in the project
42
+
43
+ ## Template Processing Rules
44
+
45
+ - Use exact templates as provided in each step
46
+ - Replace all template variables with actual values:
47
+ - `{{workflowName}}` - The workflow being planned
48
+ - `{{projectPath}}` - Root project directory path
49
+ - `{{requirements}}` - User-provided requirements
50
+ - `{{currentDate}}` - Current date in YYYY-MM-DD format
51
+ - `{{sdkVersion}}` - Current Output SDK version
52
+
53
+ ## Quality Gates
54
+
55
+ Before proceeding past pre-flight:
56
+ 1. Confirm all required context is available
57
+ 2. Verify understanding of the workflow's purpose
58
+ 3. Check for existing similar workflows to use as patterns
59
+ 4. Ensure Output SDK conventions are understood
60
+ 5. Validate that necessary subagents are available
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## Overview
6
6
 
7
- This workflow was generated using the Flow SDK CLI. It provides a starting point for building Temporal-based workflows with LLM integration.
7
+ This workflow was generated using the Output SDK CLI. It provides a starting point for building Temporal-based workflows with LLM integration.
8
8
 
9
9
  ## Files
10
10
 
@@ -63,7 +63,7 @@ Example:
63
63
 
64
64
  ### Workflow Structure
65
65
 
66
- The workflow follows the new Flow SDK conventions:
66
+ The workflow follows the new Output SDK conventions:
67
67
 
68
68
  ```typescript
69
69
  import { workflow } from '@output.ai/core';
@@ -193,7 +193,7 @@ To test your workflow:
193
193
 
194
194
  1. Build the parent project containing this workflow
195
195
  2. Start the Flow worker
196
- 3. Execute the workflow using the Flow SDK API
196
+ 3. Execute the workflow using the Output SDK API
197
197
 
198
198
  Example execution:
199
199
  ```bash
@@ -210,6 +210,6 @@ curl -X POST http://localhost:3001/workflow \
210
210
 
211
211
  ## Resources
212
212
 
213
- - [Flow SDK Documentation](https://github.com/growthxai/flow-sdk)
213
+ - [Output SDK Documentation](https://github.com/growthxai/flow-sdk)
214
214
  - [Temporal Documentation](https://docs.temporal.io)
215
215
  - [AI SDK Documentation](https://sdk.vercel.ai/docs)
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export declare const TEMPLATE_DIRS: {
5
5
  readonly workflow: string;
6
+ readonly agent_instructions: string;
6
7
  };
7
8
  /**
8
9
  * Default output directories
@@ -22,3 +23,7 @@ export declare function createTargetDir(outputDir: string, workflowName: string)
22
23
  * Get the template directory for a specific template type
23
24
  */
24
25
  export declare function getTemplateDir(templateType: keyof typeof TEMPLATE_DIRS): string;
26
+ /**
27
+ * Get the agent instruction directory for a specific category
28
+ */
29
+ export declare function getAgentInstructionDir(category: 'agents' | 'commands'): string;
@@ -6,7 +6,8 @@ const __dirname = path.dirname(__filename);
6
6
  * Template directory paths
7
7
  */
8
8
  export const TEMPLATE_DIRS = {
9
- workflow: path.join(__dirname, '..', 'templates', 'workflow')
9
+ workflow: path.join(__dirname, '..', 'templates', 'workflow'),
10
+ agent_instructions: path.join(__dirname, '..', 'templates', 'agent_instructions')
10
11
  };
11
12
  /**
12
13
  * Default output directories
@@ -33,3 +34,9 @@ export function createTargetDir(outputDir, workflowName) {
33
34
  export function getTemplateDir(templateType) {
34
35
  return TEMPLATE_DIRS[templateType];
35
36
  }
37
+ /**
38
+ * Get the agent instruction directory for a specific category
39
+ */
40
+ export function getAgentInstructionDir(category) {
41
+ return path.join(TEMPLATE_DIRS.agent_instructions, category);
42
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@output.ai/cli",
3
3
  "description": "CLI for Output.ai workflow generation",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "author": "Ben Church",
6
6
  "bin": {
7
7
  "output-cli": "./bin/run.js"
@@ -53,6 +53,14 @@
53
53
  "topics": {
54
54
  "workflow": {
55
55
  "description": "Manage Output.ai workflows"
56
+ },
57
+ "config": {
58
+ "description": "Configure Output.ai CLI",
59
+ "subtopics": {
60
+ "agents": {
61
+ "description": "Manage AI agent configurations"
62
+ }
63
+ }
56
64
  }
57
65
  }
58
66
  },