@output.ai/cli 0.8.3 → 0.8.5

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.
@@ -117,30 +117,17 @@ services:
117
117
  sh -c "
118
118
  npm run output:worker:install &&
119
119
  echo 'Installed dependencies' &&
120
- npm run output:worker:build &&
121
- echo 'Built worker' &&
122
- npm run output:worker:start &&
123
- echo 'Started worker'
120
+ npx nodemon --watch src --watch package.json --ext ts,js,json,prompt --ignore 'dist/**' --ignore '**/*.test.ts' --ignore '**/*.spec.ts' --exec 'npm run output:worker:install && npm run output:worker:build && npm run output:worker:start'
124
121
  "
125
122
  working_dir: /app
126
123
  volumes:
127
124
  - ./:/app
128
- develop:
129
- watch:
130
- - path: ./src
131
- target: /app/src
132
- action: restart
133
- ignore:
134
- - node_modules/
135
- - '**/*.test.ts'
136
- - '**/*.spec.ts'
137
- - path: ./package.json
138
- target: /app/package.json
139
- action: restart
125
+ - worker_node_modules:/app/node_modules
140
126
 
141
127
  volumes:
142
128
  postgres:
143
129
  redis:
130
+ worker_node_modules:
144
131
 
145
132
  networks:
146
133
  main:
@@ -5,7 +5,6 @@ export default class Dev extends Command {
5
5
  static args: {};
6
6
  static flags: {
7
7
  'compose-file': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
- 'no-watch': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
8
  'image-pull-policy': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
9
  };
11
10
  private dockerProcess;
@@ -73,7 +73,6 @@ export default class Dev extends Command {
73
73
  static description = 'Start Output development services (auto-restarts worker on file changes)';
74
74
  static examples = [
75
75
  '<%= config.bin %> <%= command.id %>',
76
- '<%= config.bin %> <%= command.id %> --no-watch',
77
76
  '<%= config.bin %> <%= command.id %> --compose-file ./custom-docker-compose.yml',
78
77
  '<%= config.bin %> <%= command.id %> --image-pull-policy missing'
79
78
  ];
@@ -84,10 +83,6 @@ export default class Dev extends Command {
84
83
  required: false,
85
84
  char: 'f'
86
85
  }),
87
- 'no-watch': Flags.boolean({
88
- description: 'Disable automatic container restart on file changes',
89
- default: false
90
- }),
91
86
  'image-pull-policy': Flags.string({
92
87
  description: 'Image pull policy for docker compose (always, missing, never)',
93
88
  options: ['always', 'missing', 'never'],
@@ -113,12 +108,7 @@ export default class Dev extends Command {
113
108
  if (flags['compose-file']) {
114
109
  this.log(`Using custom docker-compose file: ${flags['compose-file']}\n`);
115
110
  }
116
- if (!flags['no-watch']) {
117
- this.log('👀 File watching enabled - worker will restart automatically on changes\n');
118
- }
119
- else {
120
- this.log('â„šī¸ File watching disabled (--no-watch flag used)\n');
121
- }
111
+ this.log('File watching enabled - worker will restart automatically on changes\n');
122
112
  const cleanup = async () => {
123
113
  this.log('\n');
124
114
  if (this.dockerProcess) {
@@ -131,7 +121,7 @@ export default class Dev extends Command {
131
121
  process.on('SIGTERM', cleanup);
132
122
  const pullPolicy = flags['image-pull-policy'];
133
123
  try {
134
- const { process: dockerProc, waitForHealthy } = await startDockerCompose(dockerComposePath, !flags['no-watch'], pullPolicy);
124
+ const { process: dockerProc, waitForHealthy } = await startDockerCompose(dockerComposePath, pullPolicy);
135
125
  this.dockerProcess = dockerProc;
136
126
  dockerProc.on('error', error => {
137
127
  this.error(`Docker process error: ${getErrorMessage(error)}`, { exit: 1 });
@@ -72,11 +72,6 @@ describe('dev command', () => {
72
72
  expect(Dev.args).toBeDefined();
73
73
  expect(Object.keys(Dev.args)).toHaveLength(0);
74
74
  });
75
- it('should have no-watch flag defined', () => {
76
- expect(Dev.flags).toBeDefined();
77
- expect(Dev.flags['no-watch']).toBeDefined();
78
- expect(Dev.flags['no-watch'].description).toContain('Disable automatic container restart');
79
- });
80
75
  it('should have compose-file flag defined', () => {
81
76
  expect(Dev.flags).toBeDefined();
82
77
  expect(Dev.flags['compose-file']).toBeDefined();
@@ -110,7 +105,7 @@ describe('dev command', () => {
110
105
  cmd.log = vi.fn();
111
106
  // Mock parse to return flags
112
107
  Object.defineProperty(cmd, 'parse', {
113
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined }, args: {} }),
108
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined }, args: {} }),
114
109
  configurable: true
115
110
  });
116
111
  const validationError = new Error('Docker is not installed');
@@ -140,7 +135,7 @@ describe('dev command', () => {
140
135
  cmd.log = vi.fn();
141
136
  cmd.error = vi.fn();
142
137
  Object.defineProperty(cmd, 'parse', {
143
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
138
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
144
139
  configurable: true
145
140
  });
146
141
  const runPromise = cmd.run();
@@ -154,7 +149,7 @@ describe('dev command', () => {
154
149
  cmd.log = vi.fn();
155
150
  cmd.error = vi.fn();
156
151
  Object.defineProperty(cmd, 'parse', {
157
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
152
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
158
153
  configurable: true
159
154
  });
160
155
  const runPromise = cmd.run();
@@ -165,46 +160,25 @@ describe('dev command', () => {
165
160
  });
166
161
  });
167
162
  describe('watch functionality', () => {
168
- it('should enable watch by default', async () => {
163
+ it('should start docker compose', async () => {
169
164
  const cmd = new Dev([], {});
170
165
  cmd.log = vi.fn();
171
166
  cmd.error = vi.fn();
172
167
  // Mock parse to return flags
173
168
  Object.defineProperty(cmd, 'parse', {
174
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
169
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
175
170
  configurable: true
176
171
  });
177
172
  // Run the command but don't await it since it waits forever after startup
178
173
  const runPromise = cmd.run();
179
174
  // Wait a tick for startDockerCompose to be called
180
175
  await new Promise(resolve => setImmediate(resolve));
181
- expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', true, // enableWatch should be true
182
- 'always' // default pull policy
176
+ expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', 'always' // default pull policy
183
177
  );
184
178
  expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('File watching enabled'));
185
179
  // Cancel the promise (it will be rejected but we don't care)
186
180
  runPromise.catch(() => { });
187
181
  });
188
- it('should disable watch with --no-watch flag', async () => {
189
- const cmd = new Dev(['--no-watch'], {});
190
- cmd.log = vi.fn();
191
- cmd.error = vi.fn();
192
- // Mock parse to return flags
193
- Object.defineProperty(cmd, 'parse', {
194
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': true, 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
195
- configurable: true
196
- });
197
- // Run the command but don't await it since it waits forever after startup
198
- const runPromise = cmd.run();
199
- // Wait a tick for startDockerCompose to be called
200
- await new Promise(resolve => setImmediate(resolve));
201
- expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', false, // enableWatch should be false
202
- 'always' // default pull policy
203
- );
204
- expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('File watching disabled'));
205
- // Cancel the promise (it will be rejected but we don't care)
206
- runPromise.catch(() => { });
207
- });
208
182
  it('should handle docker compose configuration not found', async () => {
209
183
  vi.mocked(fs).access.mockRejectedValue(new Error('File not found'));
210
184
  const cmd = new Dev([], {});
@@ -219,7 +193,7 @@ describe('dev command', () => {
219
193
  cmd.error = vi.fn();
220
194
  // Mock parse to return flags
221
195
  Object.defineProperty(cmd, 'parse', {
222
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
196
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
223
197
  configurable: true
224
198
  });
225
199
  await cmd.run();
@@ -233,14 +207,14 @@ describe('dev command', () => {
233
207
  cmd.error = vi.fn();
234
208
  // Mock parse to return flags with missing pull policy
235
209
  Object.defineProperty(cmd, 'parse', {
236
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined, 'image-pull-policy': 'missing' }, args: {} }),
210
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'missing' }, args: {} }),
237
211
  configurable: true
238
212
  });
239
213
  // Run the command but don't await it since it waits forever after startup
240
214
  const runPromise = cmd.run();
241
215
  // Wait a tick for startDockerCompose to be called
242
216
  await new Promise(resolve => setImmediate(resolve));
243
- expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', true, 'missing');
217
+ expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', 'missing');
244
218
  // Cancel the promise (it will be rejected but we don't care)
245
219
  runPromise.catch(() => { });
246
220
  });
@@ -250,14 +224,14 @@ describe('dev command', () => {
250
224
  cmd.error = vi.fn();
251
225
  // Mock parse to return flags with never pull policy
252
226
  Object.defineProperty(cmd, 'parse', {
253
- value: vi.fn().mockResolvedValue({ flags: { 'no-watch': false, 'compose-file': undefined, 'image-pull-policy': 'never' }, args: {} }),
227
+ value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'never' }, args: {} }),
254
228
  configurable: true
255
229
  });
256
230
  // Run the command but don't await it since it waits forever after startup
257
231
  const runPromise = cmd.run();
258
232
  // Wait a tick for startDockerCompose to be called
259
233
  await new Promise(resolve => setImmediate(resolve));
260
- expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', true, 'never');
234
+ expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', 'never');
261
235
  // Cancel the promise (it will be rejected but we don't care)
262
236
  runPromise.catch(() => { });
263
237
  });
@@ -33,6 +33,6 @@ export interface DockerComposeProcess {
33
33
  waitForHealthy: () => Promise<void>;
34
34
  }
35
35
  export type PullPolicy = 'always' | 'missing' | 'never';
36
- export declare function startDockerCompose(dockerComposePath: string, enableWatch?: boolean, pullPolicy?: PullPolicy): Promise<DockerComposeProcess>;
36
+ export declare function startDockerCompose(dockerComposePath: string, pullPolicy?: PullPolicy): Promise<DockerComposeProcess>;
37
37
  export declare function stopDockerCompose(dockerComposePath: string): Promise<void>;
38
38
  export { isDockerInstalled, isDockerComposeAvailable, isDockerDaemonRunning, DockerValidationError };
@@ -121,7 +121,7 @@ export async function waitForServicesHealthy(dockerComposePath, timeoutMs = 1200
121
121
  logUpdate.done();
122
122
  throw new Error('Timeout waiting for services to become healthy');
123
123
  }
124
- export async function startDockerCompose(dockerComposePath, enableWatch = false, pullPolicy) {
124
+ export async function startDockerCompose(dockerComposePath, pullPolicy) {
125
125
  const args = [
126
126
  'compose',
127
127
  '-f', dockerComposePath,
@@ -131,9 +131,6 @@ export async function startDockerCompose(dockerComposePath, enableWatch = false,
131
131
  if (pullPolicy) {
132
132
  args.push('--pull', pullPolicy);
133
133
  }
134
- if (enableWatch) {
135
- args.push('--watch');
136
- }
137
134
  ux.stdout('đŸŗ Starting Docker services...\n');
138
135
  const dockerProcess = spawn('docker', args, {
139
136
  cwd: process.cwd(),
@@ -254,8 +254,8 @@ export const getWorkflowGenerateSuccessMessage = (workflowName, targetDir, files
254
254
  },
255
255
  {
256
256
  step: 'Test with example scenario',
257
- command: `output workflow run ${workflowName} --input ${targetDir}/scenarios/test_input.json`,
258
- note: 'Run after starting services with "output dev"'
257
+ command: 'npx output workflow run blog_evaluator paulgraham_hwh',
258
+ note: 'Run after starting services with "npx output dev"'
259
259
  }
260
260
  ];
261
261
  const formattedSteps = steps.map((item, index) => {
@@ -16,6 +16,7 @@
16
16
  "devDependencies": {
17
17
  "@types/node": "^22.0.0",
18
18
  "copyfiles": "^1.0.0",
19
+ "nodemon": "3.1.0",
19
20
  "typescript": "^5.7.0"
20
21
  },
21
22
  "engines": {
@@ -225,7 +225,7 @@ To test your workflow:
225
225
 
226
226
  Example execution:
227
227
  ```bash
228
- npx output workflow run {{workflowName}} --input '{"prompt": "Hello"}'
228
+ npx output workflow run blog_evaluator paulgraham_hwh
229
229
  ```
230
230
 
231
231
  ## Resources
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@output.ai/cli",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",