@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 +33 -1
- package/dist/commands/agents/init.d.ts +18 -0
- package/dist/commands/agents/init.js +175 -0
- package/dist/commands/agents/init.spec.d.ts +1 -0
- package/dist/commands/agents/init.spec.js +227 -0
- package/dist/commands/workflow/generate.js +1 -1
- package/dist/templates/agent_instructions/AGENTS.md.template +30 -0
- package/dist/templates/agent_instructions/agents/workflow_planner.md.template +104 -0
- package/dist/templates/agent_instructions/commands/plan_workflow.md.template +466 -0
- package/dist/templates/agent_instructions/meta/post_flight.md.template +94 -0
- package/dist/templates/agent_instructions/meta/pre_flight.md.template +60 -0
- package/dist/templates/workflow/README.md.template +4 -4
- package/dist/utils/paths.d.ts +5 -0
- package/dist/utils/paths.js +8 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @output.ai/cli
|
|
2
2
|
|
|
3
|
-
CLI tool for generating Output
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
- [
|
|
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)
|
package/dist/utils/paths.d.ts
CHANGED
|
@@ -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;
|
package/dist/utils/paths.js
CHANGED
|
@@ -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.
|
|
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
|
},
|