@output.ai/cli 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +44 -12
  2. package/dist/api/generated/api.d.ts +13 -13
  3. package/dist/api/generated/api.js +1 -1
  4. package/dist/commands/agents/init.d.ts +18 -0
  5. package/dist/commands/agents/init.js +175 -0
  6. package/dist/commands/agents/init.spec.d.ts +1 -0
  7. package/dist/commands/agents/init.spec.js +227 -0
  8. package/dist/commands/workflow/generate.js +1 -2
  9. package/dist/commands/workflow/generate.spec.js +0 -6
  10. package/dist/commands/workflow/list.d.ts +1 -1
  11. package/dist/commands/workflow/list.js +26 -42
  12. package/dist/commands/workflow/output.d.ts +13 -0
  13. package/dist/commands/workflow/output.js +49 -0
  14. package/dist/commands/workflow/output.test.d.ts +1 -0
  15. package/dist/commands/workflow/output.test.js +23 -0
  16. package/dist/commands/workflow/run.d.ts +15 -0
  17. package/dist/commands/workflow/run.js +66 -0
  18. package/dist/commands/workflow/run.test.d.ts +1 -0
  19. package/dist/commands/workflow/run.test.js +26 -0
  20. package/dist/commands/workflow/start.d.ts +14 -0
  21. package/dist/commands/workflow/start.js +57 -0
  22. package/dist/commands/workflow/start.test.d.ts +1 -0
  23. package/dist/commands/workflow/start.test.js +23 -0
  24. package/dist/commands/workflow/status.d.ts +13 -0
  25. package/dist/commands/workflow/status.js +56 -0
  26. package/dist/commands/workflow/status.test.d.ts +1 -0
  27. package/dist/commands/workflow/status.test.js +33 -0
  28. package/dist/commands/workflow/stop.d.ts +10 -0
  29. package/dist/commands/workflow/stop.js +31 -0
  30. package/dist/commands/workflow/stop.test.d.ts +1 -0
  31. package/dist/commands/workflow/stop.test.js +17 -0
  32. package/dist/templates/agent_instructions/AGENTS.md.template +30 -0
  33. package/dist/templates/agent_instructions/agents/workflow_planner.md.template +104 -0
  34. package/dist/templates/agent_instructions/commands/plan_workflow.md.template +466 -0
  35. package/dist/templates/agent_instructions/meta/post_flight.md.template +94 -0
  36. package/dist/templates/agent_instructions/meta/pre_flight.md.template +60 -0
  37. package/dist/templates/workflow/README.md.template +5 -5
  38. package/dist/utils/constants.d.ts +5 -0
  39. package/dist/utils/constants.js +4 -0
  40. package/dist/utils/error_handler.d.ts +8 -0
  41. package/dist/utils/error_handler.js +25 -0
  42. package/dist/utils/input_parser.d.ts +1 -0
  43. package/dist/utils/input_parser.js +19 -0
  44. package/dist/utils/output_formatter.d.ts +2 -0
  45. package/dist/utils/output_formatter.js +11 -0
  46. package/dist/utils/paths.d.ts +5 -0
  47. package/dist/utils/paths.js +8 -1
  48. package/package.json +28 -30
@@ -16,6 +16,6 @@ export default class WorkflowList extends Command {
16
16
  filter: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
17
17
  };
18
18
  run(): Promise<void>;
19
- private handleError;
19
+ catch(error: Error): Promise<void>;
20
20
  }
21
21
  export {};
@@ -2,7 +2,7 @@ import { Command, Flags } from '@oclif/core';
2
2
  import Table from 'cli-table3';
3
3
  import { getWorkflowCatalog } from '../../api/generated/api.js';
4
4
  import { parseWorkflowDefinition, formatParameters } from '../../api/parser.js';
5
- import { config } from '../../config.js';
5
+ import { handleApiError } from '../../utils/error_handler.js';
6
6
  const OUTPUT_FORMAT = {
7
7
  LIST: 'list',
8
8
  TABLE: 'table',
@@ -119,51 +119,35 @@ export default class WorkflowList extends Command {
119
119
  };
120
120
  async run() {
121
121
  const { flags } = await this.parse(WorkflowList);
122
- try {
123
- this.log('Fetching workflow catalog...');
124
- const response = await getWorkflowCatalog();
125
- if (!response) {
126
- this.error('Failed to connect to API server. Is it running?', { exit: 1 });
127
- }
128
- if (!response.data) {
129
- this.error('API returned invalid response (missing data)', { exit: 1 });
130
- }
131
- if (!response.data.workflows) {
132
- this.error('API returned invalid response (missing workflows)', { exit: 1 });
133
- }
134
- if (response.data.workflows.length === 0) {
135
- this.log('No workflows found in catalog.');
136
- return;
137
- }
138
- const workflows = flags.filter ?
139
- response.data.workflows.filter(matchName(flags.filter)) :
140
- response.data.workflows;
141
- if (workflows.length === 0 && flags.filter) {
142
- this.log(`No workflows matching filter: ${flags.filter}`);
143
- return;
144
- }
145
- const output = formatWorkflows(workflows, flags.format, flags.detailed);
146
- this.log(output);
147
- this.log(`\nFound ${workflows.length} workflow(s)`);
122
+ this.log('Fetching workflow catalog...');
123
+ const response = await getWorkflowCatalog();
124
+ if (!response) {
125
+ this.error('Failed to connect to API server. Is it running?', { exit: 1 });
148
126
  }
149
- catch (error) {
150
- this.handleError(error);
127
+ if (!response.data) {
128
+ this.error('API returned invalid response (missing data)', { exit: 1 });
151
129
  }
152
- }
153
- handleError(error) {
154
- const apiError = error;
155
- if (apiError.code === 'ECONNREFUSED') {
156
- this.error(`Connection refused to ${config.apiUrl}`, { exit: 1 });
157
- }
158
- if (apiError.response?.status === 401) {
159
- this.error('Authentication failed.', { exit: 1 });
130
+ if (!response.data.workflows) {
131
+ this.error('API returned invalid response (missing workflows)', { exit: 1 });
160
132
  }
161
- if (apiError.response?.status === 404) {
162
- this.error('Not found.', { exit: 1 });
133
+ if (response.data.workflows.length === 0) {
134
+ this.log('No workflows found in catalog.');
135
+ return;
163
136
  }
164
- if (apiError.message) {
165
- this.error(`Failed to fetch workflow catalog: ${apiError.message}`, { exit: 1 });
137
+ const workflows = flags.filter ?
138
+ response.data.workflows.filter(matchName(flags.filter)) :
139
+ response.data.workflows;
140
+ if (workflows.length === 0 && flags.filter) {
141
+ this.log(`No workflows matching filter: ${flags.filter}`);
142
+ return;
166
143
  }
167
- this.error('Failed to fetch workflow catalog: Unknown error', { exit: 1 });
144
+ const output = formatWorkflows(workflows, flags.format, flags.detailed);
145
+ this.log(output);
146
+ this.log(`\nFound ${workflows.length} workflow(s)`);
147
+ }
148
+ async catch(error) {
149
+ return handleApiError(error, (...args) => this.error(...args), {
150
+ 404: 'Catalog not found.'
151
+ });
168
152
  }
169
153
  }
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class WorkflowOutput extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ workflowId: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ catch(error: Error): Promise<void>;
13
+ }
@@ -0,0 +1,49 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getWorkflowIdOutput } from '../../api/generated/api.js';
3
+ import { OUTPUT_FORMAT } from '../../utils/constants.js';
4
+ import { formatOutput } from '../../utils/output_formatter.js';
5
+ import { handleApiError } from '../../utils/error_handler.js';
6
+ export default class WorkflowOutput extends Command {
7
+ static description = 'Get workflow execution output';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> wf-12345',
10
+ '<%= config.bin %> <%= command.id %> wf-12345 --format json'
11
+ ];
12
+ static args = {
13
+ workflowId: Args.string({
14
+ description: 'The workflow ID to get output for',
15
+ required: true
16
+ })
17
+ };
18
+ static flags = {
19
+ format: Flags.string({
20
+ char: 'f',
21
+ description: 'Output format',
22
+ options: [OUTPUT_FORMAT.JSON, OUTPUT_FORMAT.TEXT],
23
+ default: OUTPUT_FORMAT.TEXT
24
+ })
25
+ };
26
+ async run() {
27
+ const { args, flags } = await this.parse(WorkflowOutput);
28
+ this.log(`Fetching output for workflow: ${args.workflowId}...`);
29
+ const response = await getWorkflowIdOutput(args.workflowId);
30
+ if (!response || !response.data) {
31
+ this.error('API returned invalid response', { exit: 1 });
32
+ }
33
+ const output = formatOutput(response.data, flags.format, (result) => {
34
+ const lines = [
35
+ `Workflow ID: ${result.workflowId || 'unknown'}`,
36
+ '',
37
+ 'Output:',
38
+ JSON.stringify(result.output, null, 2)
39
+ ];
40
+ return lines.join('\n');
41
+ });
42
+ this.log(`\n${output}`);
43
+ }
44
+ async catch(error) {
45
+ return handleApiError(error, (...args) => this.error(...args), {
46
+ 404: 'Workflow not found. Check the workflow ID.'
47
+ });
48
+ }
49
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('../../api/generated/api.js', () => ({
3
+ getWorkflowIdOutput: vi.fn()
4
+ }));
5
+ describe('workflow output command', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+ describe('command definition', () => {
10
+ it('should export a valid OCLIF command', async () => {
11
+ const WorkflowOutput = (await import('./output.js')).default;
12
+ expect(WorkflowOutput).toBeDefined();
13
+ expect(WorkflowOutput.description).toContain('Get workflow execution output');
14
+ expect(WorkflowOutput.args).toHaveProperty('workflowId');
15
+ expect(WorkflowOutput.flags).toHaveProperty('format');
16
+ });
17
+ it('should have correct flag configuration', async () => {
18
+ const WorkflowOutput = (await import('./output.js')).default;
19
+ expect(WorkflowOutput.flags.format.options).toEqual(['json', 'text']);
20
+ expect(WorkflowOutput.flags.format.default).toBe('text');
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,15 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class WorkflowRun extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ workflowName: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ input: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ 'task-queue': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ format: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ catch(error: Error): Promise<void>;
15
+ }
@@ -0,0 +1,66 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { postWorkflowRun } from '../../api/generated/api.js';
3
+ import { OUTPUT_FORMAT } from '../../utils/constants.js';
4
+ import { parseInputFlag } from '../../utils/input_parser.js';
5
+ import { formatOutput } from '../../utils/output_formatter.js';
6
+ import { handleApiError } from '../../utils/error_handler.js';
7
+ export default class WorkflowRun extends Command {
8
+ static description = 'Execute a workflow synchronously and wait for completion';
9
+ static examples = [
10
+ '<%= config.bin %> <%= command.id %> simple --input \'{"values":[1,2,3]}\'',
11
+ '<%= config.bin %> <%= command.id %> simple --input input.json',
12
+ '<%= config.bin %> <%= command.id %> simple --input \'{"key":"value"}\' --format json',
13
+ '<%= config.bin %> <%= command.id %> simple --input \'{"key":"value"}\' --task-queue my-queue'
14
+ ];
15
+ static args = {
16
+ workflowName: Args.string({
17
+ description: 'Name of the workflow to execute',
18
+ required: true
19
+ })
20
+ };
21
+ static flags = {
22
+ input: Flags.string({
23
+ char: 'i',
24
+ description: 'Workflow input as JSON string or file path',
25
+ required: true
26
+ }),
27
+ 'task-queue': Flags.string({
28
+ char: 'q',
29
+ description: 'Task queue name for workflow execution'
30
+ }),
31
+ format: Flags.string({
32
+ char: 'f',
33
+ description: 'Output format',
34
+ options: [OUTPUT_FORMAT.JSON, OUTPUT_FORMAT.TEXT],
35
+ default: OUTPUT_FORMAT.TEXT
36
+ })
37
+ };
38
+ async run() {
39
+ const { args, flags } = await this.parse(WorkflowRun);
40
+ const input = parseInputFlag(flags.input);
41
+ this.log(`Executing workflow: ${args.workflowName}...`);
42
+ const response = await postWorkflowRun({
43
+ workflowName: args.workflowName,
44
+ input,
45
+ taskQueue: flags['task-queue']
46
+ });
47
+ if (!response || !response.data) {
48
+ this.error('API returned invalid response', { exit: 1 });
49
+ }
50
+ const output = formatOutput(response.data, flags.format, (result) => {
51
+ const lines = [
52
+ `Workflow ID: ${result.workflowId || 'unknown'}`,
53
+ '',
54
+ 'Output:',
55
+ JSON.stringify(result.output, null, 2)
56
+ ];
57
+ return lines.join('\n');
58
+ });
59
+ this.log(`\n${output}`);
60
+ }
61
+ async catch(error) {
62
+ return handleApiError(error, (...args) => this.error(...args), {
63
+ 404: 'Workflow not found. Check the workflow name.'
64
+ });
65
+ }
66
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('../../api/generated/api.js', () => ({
3
+ postWorkflowRun: vi.fn()
4
+ }));
5
+ describe('workflow run command', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+ describe('command definition', () => {
10
+ it('should export a valid OCLIF command', async () => {
11
+ const WorkflowRun = (await import('./run.js')).default;
12
+ expect(WorkflowRun).toBeDefined();
13
+ expect(WorkflowRun.description).toContain('Execute a workflow');
14
+ expect(WorkflowRun.args).toHaveProperty('workflowName');
15
+ expect(WorkflowRun.flags).toHaveProperty('input');
16
+ expect(WorkflowRun.flags).toHaveProperty('format');
17
+ expect(WorkflowRun.flags).toHaveProperty('task-queue');
18
+ });
19
+ it('should have correct flag configuration', async () => {
20
+ const WorkflowRun = (await import('./run.js')).default;
21
+ expect(WorkflowRun.flags.format.options).toEqual(['json', 'text']);
22
+ expect(WorkflowRun.flags.format.default).toBe('text');
23
+ expect(WorkflowRun.flags.input.required).toBe(true);
24
+ });
25
+ });
26
+ });
@@ -0,0 +1,14 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class WorkflowStart extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ workflowName: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ input: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ 'task-queue': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ catch(error: Error): Promise<void>;
14
+ }
@@ -0,0 +1,57 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { postWorkflowStart } from '../../api/generated/api.js';
3
+ import { parseInputFlag } from '../../utils/input_parser.js';
4
+ import { handleApiError } from '../../utils/error_handler.js';
5
+ export default class WorkflowStart extends Command {
6
+ static description = 'Start a workflow asynchronously without waiting for completion';
7
+ static examples = [
8
+ '<%= config.bin %> <%= command.id %> simple --input \'{"values":[1,2,3]}\'',
9
+ '<%= config.bin %> <%= command.id %> simple --input input.json',
10
+ '<%= config.bin %> <%= command.id %> simple --input \'{"key":"value"}\' --task-queue my-queue'
11
+ ];
12
+ static args = {
13
+ workflowName: Args.string({
14
+ description: 'Name of the workflow to start',
15
+ required: true
16
+ })
17
+ };
18
+ static flags = {
19
+ input: Flags.string({
20
+ char: 'i',
21
+ description: 'Workflow input as JSON string or file path',
22
+ required: true
23
+ }),
24
+ 'task-queue': Flags.string({
25
+ char: 'q',
26
+ description: 'Task queue name for workflow execution'
27
+ })
28
+ };
29
+ async run() {
30
+ const { args, flags } = await this.parse(WorkflowStart);
31
+ const input = parseInputFlag(flags.input);
32
+ this.log(`Starting workflow: ${args.workflowName}...`);
33
+ const response = await postWorkflowStart({
34
+ workflowName: args.workflowName,
35
+ input,
36
+ taskQueue: flags['task-queue']
37
+ });
38
+ if (!response || !response.data) {
39
+ this.error('API returned invalid response', { exit: 1 });
40
+ }
41
+ const result = response.data;
42
+ const output = [
43
+ 'Workflow started successfully',
44
+ '',
45
+ `Workflow ID: ${result.workflowId || 'unknown'}`,
46
+ '',
47
+ `Use "workflow status ${result.workflowId || '<workflow-id>'}" to check the workflow status`,
48
+ `Use "workflow output ${result.workflowId || '<workflow-id>'}" to get the workflow output when complete`
49
+ ].join('\n');
50
+ this.log(`\n${output}`);
51
+ }
52
+ async catch(error) {
53
+ return handleApiError(error, (...args) => this.error(...args), {
54
+ 404: 'Workflow not found. Check the workflow name.'
55
+ });
56
+ }
57
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('../../api/generated/api.js', () => ({
3
+ postWorkflowStart: vi.fn()
4
+ }));
5
+ describe('workflow start command', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+ describe('command definition', () => {
10
+ it('should export a valid OCLIF command', async () => {
11
+ const WorkflowStart = (await import('./start.js')).default;
12
+ expect(WorkflowStart).toBeDefined();
13
+ expect(WorkflowStart.description).toContain('Start a workflow');
14
+ expect(WorkflowStart.args).toHaveProperty('workflowName');
15
+ expect(WorkflowStart.flags).toHaveProperty('input');
16
+ expect(WorkflowStart.flags).toHaveProperty('task-queue');
17
+ });
18
+ it('should have correct flag configuration', async () => {
19
+ const WorkflowStart = (await import('./start.js')).default;
20
+ expect(WorkflowStart.flags.input.required).toBe(true);
21
+ });
22
+ });
23
+ });
@@ -0,0 +1,13 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class WorkflowStatus extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ workflowId: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
7
+ };
8
+ static flags: {
9
+ format: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ catch(error: Error): Promise<void>;
13
+ }
@@ -0,0 +1,56 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { getWorkflowIdStatus } from '../../api/generated/api.js';
3
+ import { OUTPUT_FORMAT } from '../../utils/constants.js';
4
+ import { formatOutput } from '../../utils/output_formatter.js';
5
+ import { handleApiError } from '../../utils/error_handler.js';
6
+ export default class WorkflowStatus extends Command {
7
+ static description = 'Get workflow execution status';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %> wf-12345',
10
+ '<%= config.bin %> <%= command.id %> wf-12345 --format json'
11
+ ];
12
+ static args = {
13
+ workflowId: Args.string({
14
+ description: 'The workflow ID to check status for',
15
+ required: true
16
+ })
17
+ };
18
+ static flags = {
19
+ format: Flags.string({
20
+ char: 'f',
21
+ description: 'Output format',
22
+ options: [OUTPUT_FORMAT.JSON, OUTPUT_FORMAT.TEXT],
23
+ default: OUTPUT_FORMAT.TEXT
24
+ })
25
+ };
26
+ async run() {
27
+ const { args, flags } = await this.parse(WorkflowStatus);
28
+ this.log(`Fetching status for workflow: ${args.workflowId}...`);
29
+ const response = await getWorkflowIdStatus(args.workflowId);
30
+ if (!response || !response.data) {
31
+ this.error('API returned invalid response', { exit: 1 });
32
+ }
33
+ const output = formatOutput(response.data, flags.format, (result) => {
34
+ const lines = [
35
+ `Workflow ID: ${result.workflowId || 'unknown'}`,
36
+ `Status: ${result.status || 'unknown'}`,
37
+ ''
38
+ ];
39
+ if (result.startedAt) {
40
+ const startDate = new Date(result.startedAt);
41
+ lines.push(`Started At: ${startDate.toISOString()}`);
42
+ }
43
+ if (result.completedAt) {
44
+ const completedDate = new Date(result.completedAt);
45
+ lines.push(`Completed At: ${completedDate.toISOString()}`);
46
+ }
47
+ return lines.join('\n');
48
+ });
49
+ this.log(`\n${output}`);
50
+ }
51
+ async catch(error) {
52
+ return handleApiError(error, (...args) => this.error(...args), {
53
+ 404: 'Workflow not found. Check the workflow ID.'
54
+ });
55
+ }
56
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('../../api/generated/api.js', () => ({
3
+ getWorkflowIdStatus: vi.fn(),
4
+ GetWorkflowIdStatus200Status: {
5
+ canceled: 'canceled',
6
+ completed: 'completed',
7
+ continued_as_new: 'continued_as_new',
8
+ failed: 'failed',
9
+ running: 'running',
10
+ terminated: 'terminated',
11
+ timed_out: 'timed_out',
12
+ unspecified: 'unspecified'
13
+ }
14
+ }));
15
+ describe('workflow status command', () => {
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ });
19
+ describe('command definition', () => {
20
+ it('should export a valid OCLIF command', async () => {
21
+ const WorkflowStatus = (await import('./status.js')).default;
22
+ expect(WorkflowStatus).toBeDefined();
23
+ expect(WorkflowStatus.description).toContain('Get workflow execution status');
24
+ expect(WorkflowStatus.args).toHaveProperty('workflowId');
25
+ expect(WorkflowStatus.flags).toHaveProperty('format');
26
+ });
27
+ it('should have correct flag configuration', async () => {
28
+ const WorkflowStatus = (await import('./status.js')).default;
29
+ expect(WorkflowStatus.flags.format.options).toEqual(['json', 'text']);
30
+ expect(WorkflowStatus.flags.format.default).toBe('text');
31
+ });
32
+ });
33
+ });
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class WorkflowStop extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ workflowId: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
7
+ };
8
+ run(): Promise<void>;
9
+ catch(error: Error): Promise<void>;
10
+ }
@@ -0,0 +1,31 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import { patchWorkflowIdStop } from '../../api/generated/api.js';
3
+ import { handleApiError } from '../../utils/error_handler.js';
4
+ export default class WorkflowStop extends Command {
5
+ static description = 'Stop a workflow execution';
6
+ static examples = [
7
+ '<%= config.bin %> <%= command.id %> wf-12345'
8
+ ];
9
+ static args = {
10
+ workflowId: Args.string({
11
+ description: 'The workflow ID to stop',
12
+ required: true
13
+ })
14
+ };
15
+ async run() {
16
+ const { args } = await this.parse(WorkflowStop);
17
+ this.log(`Stopping workflow: ${args.workflowId}...`);
18
+ await patchWorkflowIdStop(args.workflowId);
19
+ const output = [
20
+ 'Workflow stopped successfully',
21
+ '',
22
+ `Workflow ID: ${args.workflowId}`
23
+ ].join('\n');
24
+ this.log(`\n${output}`);
25
+ }
26
+ async catch(error) {
27
+ return handleApiError(error, (...args) => this.error(...args), {
28
+ 404: 'Workflow not found. Check the workflow ID.'
29
+ });
30
+ }
31
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ vi.mock('../../api/generated/api.js', () => ({
3
+ patchWorkflowIdStop: vi.fn()
4
+ }));
5
+ describe('workflow stop command', () => {
6
+ beforeEach(() => {
7
+ vi.clearAllMocks();
8
+ });
9
+ describe('command definition', () => {
10
+ it('should export a valid OCLIF command', async () => {
11
+ const WorkflowStop = (await import('./stop.js')).default;
12
+ expect(WorkflowStop).toBeDefined();
13
+ expect(WorkflowStop.description).toContain('Stop a workflow execution');
14
+ expect(WorkflowStop.args).toHaveProperty('workflowId');
15
+ });
16
+ });
17
+ });
@@ -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`