@output.ai/cli 0.8.1 → 0.8.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.
@@ -8,7 +8,7 @@ export declare function generatePlanName(description: string, date?: Date): Prom
8
8
  */
9
9
  export declare function writePlanFile(planName: string, content: string, projectRoot: string): Promise<string>;
10
10
  /**
11
- * Update agent templates by invoking agents init with force flag
11
+ * Update agent templates by reinitializing with force flag
12
12
  * This recreates all agent configuration files, overwriting existing ones
13
13
  * @param projectRoot - Root directory of the project
14
14
  */
@@ -36,7 +36,7 @@ export async function writePlanFile(planName, content, projectRoot) {
36
36
  return planFilePath;
37
37
  }
38
38
  /**
39
- * Update agent templates by invoking agents init with force flag
39
+ * Update agent templates by reinitializing with force flag
40
40
  * This recreates all agent configuration files, overwriting existing ones
41
41
  * @param projectRoot - Root directory of the project
42
42
  */
@@ -98,7 +98,7 @@ describe('workflow-planner service', () => {
98
98
  });
99
99
  });
100
100
  describe('updateAgentTemplates', () => {
101
- it('should invoke agents init with force flag', async () => {
101
+ it('should invoke initializeAgentConfig with force flag', async () => {
102
102
  vi.mocked(initializeAgentConfig).mockResolvedValue();
103
103
  await updateAgentTemplates('/test/project');
104
104
  expect(initializeAgentConfig).toHaveBeenCalledWith({
@@ -106,7 +106,7 @@ describe('workflow-planner service', () => {
106
106
  force: true
107
107
  });
108
108
  });
109
- it('should propagate errors from agents init', async () => {
109
+ it('should propagate errors from initializeAgentConfig', async () => {
110
110
  vi.mocked(initializeAgentConfig).mockRejectedValue(new Error('Failed to write templates'));
111
111
  await expect(updateAgentTemplates('/test/project'))
112
112
  .rejects.toThrow('Failed to write templates');
@@ -0,0 +1,19 @@
1
+ # CLAUDE.md
2
+
3
+ This is an **Output.ai** project - a framework for building reliable, production-ready LLM workflows and agents.
4
+
5
+ ## Getting Started
6
+
7
+ For full framework documentation, commands, and AI-assisted workflow development, install our Claude Code plugins:
8
+
9
+ ```bash
10
+ claude plugin marketplace add growthxai/output-claude-plugins
11
+ claude plugin install outputai@outputai --scope project
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Project-Specific Instructions
17
+
18
+ <!-- Add your project-specific instructions below -->
19
+
@@ -11,7 +11,7 @@ export declare const mockLLM: {
11
11
  generateText: import("vitest").Mock<(...args: any[]) => any>;
12
12
  };
13
13
  /**
14
- * Mock for child_process spawn (for agents init)
14
+ * Mock for child_process spawn (for agent commands)
15
15
  */
16
16
  export declare const mockSpawn: import("vitest").Mock<(...args: any[]) => any>;
17
17
  /**
@@ -24,7 +24,7 @@ export const mockLLM = {
24
24
  })
25
25
  };
26
26
  /**
27
- * Mock for child_process spawn (for agents init)
27
+ * Mock for child_process spawn (for agent commands)
28
28
  */
29
29
  export const mockSpawn = vi.fn().mockImplementation(() => {
30
30
  const mockChild = {
@@ -1,20 +1,22 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { ux } from '@oclif/core';
3
+ import debugFactory from 'debug';
3
4
  import { getErrorMessage } from './error_utils.js';
5
+ const debug = debugFactory('output-cli:process');
4
6
  export async function executeCommand(command, args, cwd) {
5
7
  const stderrLines = [];
6
8
  const proc = spawn(command, args, { cwd });
7
9
  const handleStdout = (data) => {
8
10
  const line = data.toString().trim();
9
11
  if (line) {
10
- ux.stdout(line);
12
+ debug(line);
11
13
  }
12
14
  };
13
15
  const handleStderr = (data) => {
14
16
  const line = data.toString().trim();
15
17
  if (line) {
16
18
  stderrLines.push(line);
17
- ux.stdout(line);
19
+ debug(line);
18
20
  }
19
21
  };
20
22
  proc.stdout.on('data', handleStdout);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@output.ai/cli",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,43 +0,0 @@
1
- import { Command, Flags } from '@oclif/core';
2
- import { initializeAgentConfig } from '#services/coding_agents.js';
3
- import { getErrorMessage, getErrorCode } from '#utils/error_utils.js';
4
- export default class Init extends Command {
5
- static description = 'Initialize agent configuration files for Claude Code plugin integration';
6
- static examples = [
7
- '<%= config.bin %> <%= command.id %>',
8
- '<%= config.bin %> <%= command.id %> --force'
9
- ];
10
- static args = {};
11
- static flags = {
12
- force: Flags.boolean({
13
- char: 'f',
14
- description: 'Overwrite existing files',
15
- default: false
16
- })
17
- };
18
- async run() {
19
- const { flags } = await this.parse(Init);
20
- this.log('Initializing agent configuration for Claude Code...');
21
- try {
22
- await initializeAgentConfig({
23
- projectRoot: process.cwd(),
24
- force: flags.force
25
- });
26
- this.log('Agent configuration initialized successfully!');
27
- this.log('');
28
- this.log('Configured:');
29
- this.log(' - Registered marketplace: growthxai/output-claude-plugins');
30
- this.log(' - Updated marketplace: outputai');
31
- this.log(' - Installed plugin: outputai@outputai');
32
- this.log('');
33
- this.log('Claude Code will automatically use the OutputAI plugin.');
34
- }
35
- catch (error) {
36
- if (getErrorCode(error) === 'EACCES') {
37
- this.error('Permission denied. Please check file permissions and try again.');
38
- return;
39
- }
40
- this.error(`Failed to initialize agent configuration: ${getErrorMessage(error)}`);
41
- }
42
- }
43
- }
@@ -1,109 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
3
- import Init from './init.js';
4
- import { initializeAgentConfig } from '#services/coding_agents.js';
5
- vi.mock('#services/coding_agents.js', () => ({
6
- initializeAgentConfig: vi.fn(),
7
- AGENT_CONFIGS: { 'claude-code': { id: 'claude-code' } }
8
- }));
9
- vi.mock('#config.js', () => ({
10
- AGENT_CONFIG_DIR: '.outputai'
11
- }));
12
- describe('agents init', () => {
13
- const createTestCommand = (args = []) => {
14
- const cmd = new Init(args, {});
15
- cmd.log = vi.fn();
16
- cmd.warn = vi.fn();
17
- cmd.error = vi.fn();
18
- cmd.debug = vi.fn();
19
- cmd.parse = vi.fn();
20
- return cmd;
21
- };
22
- beforeEach(() => {
23
- vi.clearAllMocks();
24
- vi.mocked(initializeAgentConfig).mockResolvedValue(undefined);
25
- });
26
- afterEach(() => {
27
- vi.restoreAllMocks();
28
- });
29
- describe('command structure', () => {
30
- it('should have correct description', () => {
31
- expect(Init.description).toBeDefined();
32
- expect(Init.description).toContain('agent configuration');
33
- });
34
- it('should have correct examples without agent-provider flag', () => {
35
- expect(Init.examples).toBeDefined();
36
- expect(Array.isArray(Init.examples)).toBe(true);
37
- const examplesStr = Init.examples.join(' ');
38
- expect(examplesStr).not.toContain('agent-provider');
39
- });
40
- it('should have no required arguments', () => {
41
- expect(Init.args).toBeDefined();
42
- expect(Object.keys(Init.args)).toHaveLength(0);
43
- });
44
- it('should only have force flag', () => {
45
- expect(Init.flags).toBeDefined();
46
- expect(Init.flags.force).toBeDefined();
47
- expect(Object.keys(Init.flags)).toHaveLength(1);
48
- });
49
- });
50
- describe('successful execution', () => {
51
- it('should call initializeAgentConfig with correct options', async () => {
52
- const cmd = createTestCommand();
53
- cmd.parse.mockResolvedValue({ flags: { force: false }, args: {} });
54
- await cmd.run();
55
- expect(initializeAgentConfig).toHaveBeenCalledWith({
56
- projectRoot: expect.any(String),
57
- force: false
58
- });
59
- });
60
- it('should pass force flag to initializeAgentConfig', async () => {
61
- const cmd = createTestCommand(['--force']);
62
- cmd.parse.mockResolvedValue({ flags: { force: true }, args: {} });
63
- await cmd.run();
64
- expect(initializeAgentConfig).toHaveBeenCalledWith({
65
- projectRoot: expect.any(String),
66
- force: true
67
- });
68
- });
69
- it('should display success messages', async () => {
70
- const cmd = createTestCommand();
71
- cmd.parse.mockResolvedValue({ flags: { force: false }, args: {} });
72
- await cmd.run();
73
- expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('initialized successfully'));
74
- expect(cmd.log).toHaveBeenCalledWith('Configured:');
75
- expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('OutputAI plugin'));
76
- });
77
- it('should display plugin configuration messages', async () => {
78
- const cmd = createTestCommand();
79
- cmd.parse.mockResolvedValue({ flags: { force: false }, args: {} });
80
- await cmd.run();
81
- expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('marketplace'));
82
- expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('plugin'));
83
- });
84
- });
85
- describe('error handling', () => {
86
- it('should handle permission errors', async () => {
87
- vi.mocked(initializeAgentConfig).mockRejectedValue({ code: 'EACCES' });
88
- const cmd = createTestCommand();
89
- cmd.parse.mockResolvedValue({ flags: { force: false }, args: {} });
90
- await cmd.run();
91
- expect(cmd.error).toHaveBeenCalledWith(expect.stringContaining('Permission denied'));
92
- });
93
- it('should handle general errors with message', async () => {
94
- vi.mocked(initializeAgentConfig).mockRejectedValue(new Error('Something went wrong'));
95
- const cmd = createTestCommand();
96
- cmd.parse.mockResolvedValue({ flags: { force: false }, args: {} });
97
- await cmd.run();
98
- expect(cmd.error).toHaveBeenCalledWith(expect.stringContaining('Failed to initialize agent configuration'));
99
- expect(cmd.error).toHaveBeenCalledWith(expect.stringContaining('Something went wrong'));
100
- });
101
- it('should handle Claude CLI not found error', async () => {
102
- vi.mocked(initializeAgentConfig).mockRejectedValue(new Error('Claude CLI not found. Please install Claude Code CLI and ensure \'claude\' is in your PATH.'));
103
- const cmd = createTestCommand();
104
- cmd.parse.mockResolvedValue({ flags: { force: false }, args: {} });
105
- await cmd.run();
106
- expect(cmd.error).toHaveBeenCalledWith(expect.stringContaining('Claude CLI not found'));
107
- });
108
- });
109
- });