@outputai/cli 0.1.13-dev.98dfd72.0 → 0.1.13-dev.af42b51.0

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 (43) hide show
  1. package/bin/run.js +0 -2
  2. package/dist/api/generated/api.d.ts +319 -85
  3. package/dist/api/generated/api.js +66 -8
  4. package/dist/assets/docker/docker-compose-dev.yml +1 -1
  5. package/dist/commands/fix.js +1 -1
  6. package/dist/commands/fix.spec.js +2 -2
  7. package/dist/commands/update.js +1 -1
  8. package/dist/commands/update.spec.js +2 -2
  9. package/dist/commands/workflow/plan.js +1 -5
  10. package/dist/commands/workflow/plan.spec.js +2 -3
  11. package/dist/commands/workflow/run.js +1 -2
  12. package/dist/commands/workflow/run.spec.js +0 -1
  13. package/dist/commands/workflow/start.js +1 -2
  14. package/dist/commands/workflow/start.spec.js +0 -1
  15. package/dist/generated/framework_version.json +1 -1
  16. package/dist/hooks/init.js +0 -4
  17. package/dist/services/coding_agents.js +1 -1
  18. package/dist/services/coding_agents.spec.js +6 -6
  19. package/dist/services/credentials_configurator.js +1 -1
  20. package/dist/services/env_configurator.js +1 -1
  21. package/dist/services/env_configurator.spec.js +12 -12
  22. package/dist/services/project_scaffold.js +2 -2
  23. package/dist/services/project_scaffold.spec.js +6 -6
  24. package/dist/services/workflow_builder.js +1 -5
  25. package/dist/services/workflow_builder.spec.js +2 -3
  26. package/dist/utils/format_workflow_result.d.ts +3 -3
  27. package/package.json +4 -5
  28. package/dist/commands/credentials/set.d.ts +0 -14
  29. package/dist/commands/credentials/set.js +0 -57
  30. package/dist/commands/credentials/set.spec.d.ts +0 -1
  31. package/dist/commands/credentials/set.spec.js +0 -95
  32. package/dist/utils/interactive.d.ts +0 -2
  33. package/dist/utils/interactive.js +0 -5
  34. package/dist/utils/interactive.spec.d.ts +0 -1
  35. package/dist/utils/interactive.spec.js +0 -40
  36. package/dist/utils/prompt.d.ts +0 -17
  37. package/dist/utils/prompt.js +0 -20
  38. package/dist/utils/prompt.spec.d.ts +0 -1
  39. package/dist/utils/prompt.spec.js +0 -74
  40. package/dist/utils/proxy.d.ts +0 -1
  41. package/dist/utils/proxy.js +0 -9
  42. package/dist/utils/proxy.spec.d.ts +0 -1
  43. package/dist/utils/proxy.spec.js +0 -39
@@ -24,11 +24,7 @@ export const WorkflowRunInfoStatus = {
24
24
  timed_out: 'timed_out',
25
25
  continued: 'continued',
26
26
  };
27
- export const PostWorkflowRun200Status = {
28
- completed: 'completed',
29
- failed: 'failed',
30
- };
31
- export const GetWorkflowIdStatus200Status = {
27
+ export const WorkflowStatusResponseStatus = {
32
28
  canceled: 'canceled',
33
29
  completed: 'completed',
34
30
  continued_as_new: 'continued_as_new',
@@ -38,7 +34,7 @@ export const GetWorkflowIdStatus200Status = {
38
34
  timed_out: 'timed_out',
39
35
  unspecified: 'unspecified',
40
36
  };
41
- export const GetWorkflowIdResult200Status = {
37
+ export const WorkflowResultResponseStatus = {
42
38
  completed: 'completed',
43
39
  failed: 'failed',
44
40
  canceled: 'canceled',
@@ -46,6 +42,10 @@ export const GetWorkflowIdResult200Status = {
46
42
  timed_out: 'timed_out',
47
43
  continued: 'continued',
48
44
  };
45
+ export const PostWorkflowRun200Status = {
46
+ completed: 'completed',
47
+ failed: 'failed',
48
+ };
49
49
  ;
50
50
  export const getGetHealthUrl = () => {
51
51
  return `/health`;
@@ -87,6 +87,24 @@ export const getWorkflowIdStatus = async (id, options) => {
87
87
  method: 'GET'
88
88
  });
89
89
  };
90
+ export const getGetWorkflowIdRunsRidStatusUrl = (id, rid) => {
91
+ return `/workflow/${id}/runs/${rid}/status`;
92
+ };
93
+ export const getWorkflowIdRunsRidStatus = async (id, rid, options) => {
94
+ return customFetchInstance(getGetWorkflowIdRunsRidStatusUrl(id, rid), {
95
+ ...options,
96
+ method: 'GET'
97
+ });
98
+ };
99
+ export const getPatchWorkflowIdRunsRidStopUrl = (id, rid) => {
100
+ return `/workflow/${id}/runs/${rid}/stop`;
101
+ };
102
+ export const patchWorkflowIdRunsRidStop = async (id, rid, options) => {
103
+ return customFetchInstance(getPatchWorkflowIdRunsRidStopUrl(id, rid), {
104
+ ...options,
105
+ method: 'PATCH'
106
+ });
107
+ };
90
108
  export const getPatchWorkflowIdStopUrl = (id) => {
91
109
  return `/workflow/${id}/stop`;
92
110
  };
@@ -96,6 +114,17 @@ export const patchWorkflowIdStop = async (id, options) => {
96
114
  method: 'PATCH'
97
115
  });
98
116
  };
117
+ export const getPostWorkflowIdRunsRidTerminateUrl = (id, rid) => {
118
+ return `/workflow/${id}/runs/${rid}/terminate`;
119
+ };
120
+ export const postWorkflowIdRunsRidTerminate = async (id, rid, postWorkflowIdRunsRidTerminateBody, options) => {
121
+ return customFetchInstance(getPostWorkflowIdRunsRidTerminateUrl(id, rid), {
122
+ ...options,
123
+ method: 'POST',
124
+ headers: { 'Content-Type': 'application/json', ...options?.headers },
125
+ body: JSON.stringify(postWorkflowIdRunsRidTerminateBody)
126
+ });
127
+ };
99
128
  export const getPostWorkflowIdTerminateUrl = (id) => {
100
129
  return `/workflow/${id}/terminate`;
101
130
  };
@@ -107,15 +136,26 @@ export const postWorkflowIdTerminate = async (id, postWorkflowIdTerminateBody, o
107
136
  body: JSON.stringify(postWorkflowIdTerminateBody)
108
137
  });
109
138
  };
139
+ export const getPostWorkflowIdRunsRidResetUrl = (id, rid) => {
140
+ return `/workflow/${id}/runs/${rid}/reset`;
141
+ };
142
+ export const postWorkflowIdRunsRidReset = async (id, rid, resetWorkflowRequest, options) => {
143
+ return customFetchInstance(getPostWorkflowIdRunsRidResetUrl(id, rid), {
144
+ ...options,
145
+ method: 'POST',
146
+ headers: { 'Content-Type': 'application/json', ...options?.headers },
147
+ body: JSON.stringify(resetWorkflowRequest)
148
+ });
149
+ };
110
150
  export const getPostWorkflowIdResetUrl = (id) => {
111
151
  return `/workflow/${id}/reset`;
112
152
  };
113
- export const postWorkflowIdReset = async (id, postWorkflowIdResetBody, options) => {
153
+ export const postWorkflowIdReset = async (id, resetWorkflowRequest, options) => {
114
154
  return customFetchInstance(getPostWorkflowIdResetUrl(id), {
115
155
  ...options,
116
156
  method: 'POST',
117
157
  headers: { 'Content-Type': 'application/json', ...options?.headers },
118
- body: JSON.stringify(postWorkflowIdResetBody)
158
+ body: JSON.stringify(resetWorkflowRequest)
119
159
  });
120
160
  };
121
161
  export const getGetWorkflowIdResultUrl = (id) => {
@@ -127,6 +167,15 @@ export const getWorkflowIdResult = async (id, options) => {
127
167
  method: 'GET'
128
168
  });
129
169
  };
170
+ export const getGetWorkflowIdRunsRidResultUrl = (id, rid) => {
171
+ return `/workflow/${id}/runs/${rid}/result`;
172
+ };
173
+ export const getWorkflowIdRunsRidResult = async (id, rid, options) => {
174
+ return customFetchInstance(getGetWorkflowIdRunsRidResultUrl(id, rid), {
175
+ ...options,
176
+ method: 'GET'
177
+ });
178
+ };
130
179
  export const getGetWorkflowIdTraceLogUrl = (id) => {
131
180
  return `/workflow/${id}/trace-log`;
132
181
  };
@@ -136,6 +185,15 @@ export const getWorkflowIdTraceLog = async (id, options) => {
136
185
  method: 'GET'
137
186
  });
138
187
  };
188
+ export const getGetWorkflowIdRunsRidTraceLogUrl = (id, rid) => {
189
+ return `/workflow/${id}/runs/${rid}/trace-log`;
190
+ };
191
+ export const getWorkflowIdRunsRidTraceLog = async (id, rid, options) => {
192
+ return customFetchInstance(getGetWorkflowIdRunsRidTraceLogUrl(id, rid), {
193
+ ...options,
194
+ method: 'GET'
195
+ });
196
+ };
139
197
  export const getGetWorkflowCatalogIdUrl = (id) => {
140
198
  return `/workflow/catalog/${id}`;
141
199
  };
@@ -81,7 +81,7 @@ services:
81
81
  condition: service_healthy
82
82
  worker:
83
83
  condition: service_healthy
84
- image: outputai/api:${OUTPUT_API_VERSION:-0.1.13-dev.98dfd72.0}
84
+ image: outputai/api:${OUTPUT_API_VERSION:-0.1.13-dev.af42b51.0}
85
85
  init: true
86
86
  networks:
87
87
  - main
@@ -1,5 +1,5 @@
1
1
  import { Command } from '@oclif/core';
2
- import { confirm } from '#utils/prompt.js';
2
+ import { confirm } from '@inquirer/prompts';
3
3
  import { applyFix, planFix } from '#services/fix_package.js';
4
4
  import { getErrorMessage } from '#utils/error_utils.js';
5
5
  const Ansi = {
@@ -2,12 +2,12 @@
2
2
  import { describe, it, expect, beforeEach, vi } from 'vitest';
3
3
  import Fix from './fix.js';
4
4
  import * as fixService from '#services/fix_package.js';
5
- import { confirm } from '#utils/prompt.js';
5
+ import { confirm } from '@inquirer/prompts';
6
6
  vi.mock('#services/fix_package.js', () => ({
7
7
  planFix: vi.fn(),
8
8
  applyFix: vi.fn()
9
9
  }));
10
- vi.mock('#utils/prompt.js', () => ({
10
+ vi.mock('@inquirer/prompts', () => ({
11
11
  confirm: vi.fn()
12
12
  }));
13
13
  const basePlan = () => ({
@@ -1,5 +1,5 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
- import { confirm } from '#utils/prompt.js';
2
+ import { confirm } from '@inquirer/prompts';
3
3
  import { fetchLatestVersion, getGlobalInstalledVersion, getLocalInstalledVersion, updateGlobal, updateLocal, isOutdated } from '#services/npm_update_service.js';
4
4
  import { ensureClaudePlugin } from '#services/coding_agents.js';
5
5
  import { getErrorMessage } from '#utils/error_utils.js';
@@ -3,7 +3,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest';
3
3
  import Update from './update.js';
4
4
  import { fetchLatestVersion, getGlobalInstalledVersion, getLocalInstalledVersion, updateGlobal, updateLocal, isOutdated } from '#services/npm_update_service.js';
5
5
  import { ensureClaudePlugin } from '#services/coding_agents.js';
6
- import { confirm } from '#utils/prompt.js';
6
+ import { confirm } from '@inquirer/prompts';
7
7
  vi.mock('#services/npm_update_service.js', () => ({
8
8
  fetchLatestVersion: vi.fn(),
9
9
  getGlobalInstalledVersion: vi.fn(),
@@ -15,7 +15,7 @@ vi.mock('#services/npm_update_service.js', () => ({
15
15
  vi.mock('#services/coding_agents.js', () => ({
16
16
  ensureClaudePlugin: vi.fn()
17
17
  }));
18
- vi.mock('#utils/prompt.js', () => ({
18
+ vi.mock('@inquirer/prompts', () => ({
19
19
  confirm: vi.fn()
20
20
  }));
21
21
  describe('update command', () => {
@@ -1,6 +1,5 @@
1
1
  import { Command, Flags, ux } from '@oclif/core';
2
- import { input } from '#utils/prompt.js';
3
- import { isInteractive } from '#utils/interactive.js';
2
+ import { input } from '@inquirer/prompts';
4
3
  import { generatePlanName, updateAgentTemplates, writePlanFile } from '#services/workflow_planner.js';
5
4
  import { ensureOutputAISystem } from '#services/coding_agents.js';
6
5
  import { invokePlanWorkflow, PLAN_COMMAND_OPTIONS, replyToClaude } from '#services/claude_client.js';
@@ -46,9 +45,6 @@ export default class WorkflowPlan extends Command {
46
45
  this.log('=========');
47
46
  this.log(originalPlanContent);
48
47
  this.log('=========');
49
- if (!isInteractive()) {
50
- return originalPlanContent;
51
- }
52
48
  const modifications = await input({
53
49
  message: ux.colorize('gray', `Reply or type ${acceptKey} to accept the plan as is: `),
54
50
  validate: (value) => value.length >= 10 || value === acceptKey
@@ -3,12 +3,11 @@ import WorkflowPlan from './plan.js';
3
3
  import { generatePlanName, writePlanFile, updateAgentTemplates } from '#services/workflow_planner.js';
4
4
  import { ensureOutputAISystem } from '#services/coding_agents.js';
5
5
  import { invokePlanWorkflow, replyToClaude, ClaudeInvocationError } from '#services/claude_client.js';
6
- import { input } from '#utils/prompt.js';
6
+ import { input } from '@inquirer/prompts';
7
7
  vi.mock('#services/workflow_planner.js');
8
8
  vi.mock('#services/coding_agents.js');
9
9
  vi.mock('#services/claude_client.js');
10
- vi.mock('#utils/prompt.js');
11
- vi.mock('#utils/interactive.js', () => ({ isInteractive: () => true }));
10
+ vi.mock('@inquirer/prompts');
12
11
  describe('WorkflowPlan Command', () => {
13
12
  const createCommand = () => {
14
13
  const cmd = new WorkflowPlan([], {});
@@ -55,8 +55,7 @@ export default class WorkflowRun extends Command {
55
55
  }),
56
56
  'task-queue': Flags.string({
57
57
  char: 'q',
58
- description: 'Task queue name for workflow execution (defaults to OUTPUT_CATALOG_ID)',
59
- env: 'OUTPUT_CATALOG_ID'
58
+ description: 'Task queue name for workflow execution'
60
59
  }),
61
60
  format: Flags.string({
62
61
  char: 'f',
@@ -13,7 +13,6 @@ vi.mock('#utils/sleep.js', () => ({
13
13
  describe('workflow run command', () => {
14
14
  beforeEach(async () => {
15
15
  vi.clearAllMocks();
16
- delete process.env.OUTPUT_CATALOG_ID;
17
16
  const { resolveInput } = await import('#utils/resolve_input.js');
18
17
  const { sleep } = await import('#utils/sleep.js');
19
18
  vi.mocked(resolveInput).mockResolvedValue({});
@@ -28,8 +28,7 @@ export default class WorkflowStart extends Command {
28
28
  }),
29
29
  'task-queue': Flags.string({
30
30
  char: 'q',
31
- description: 'Task queue name for workflow execution (defaults to OUTPUT_CATALOG_ID)',
32
- env: 'OUTPUT_CATALOG_ID'
31
+ description: 'Task queue name for workflow execution'
33
32
  })
34
33
  };
35
34
  async run() {
@@ -5,7 +5,6 @@ vi.mock('../../api/generated/api.js', () => ({
5
5
  describe('workflow start command', () => {
6
6
  beforeEach(() => {
7
7
  vi.clearAllMocks();
8
- delete process.env.OUTPUT_CATALOG_ID;
9
8
  });
10
9
  describe('command definition', () => {
11
10
  it('should export a valid OCLIF command', async () => {
@@ -1,3 +1,3 @@
1
1
  {
2
- "framework": "0.1.13-dev.98dfd72.0"
2
+ "framework": "0.1.13-dev.af42b51.0"
3
3
  }
@@ -1,10 +1,6 @@
1
1
  import { ux } from '@oclif/core';
2
2
  import { checkForUpdate } from '#services/version_check.js';
3
- import { setNonInteractive } from '#utils/interactive.js';
4
3
  const hook = async function () {
5
- if (process.argv.includes('--yes') || process.argv.includes('--non-interactive') || !process.stdin.isTTY) {
6
- setNonInteractive(true);
7
- }
8
4
  try {
9
5
  const result = await checkForUpdate(this.config.version, this.config.cacheDir);
10
6
  if (!result.updateAvailable) {
@@ -7,7 +7,7 @@ import { access } from 'node:fs/promises';
7
7
  import path from 'node:path';
8
8
  import { join } from 'node:path';
9
9
  import { ux } from '@oclif/core';
10
- import { confirm } from '#utils/prompt.js';
10
+ import { confirm } from '@inquirer/prompts';
11
11
  import debugFactory from 'debug';
12
12
  import { getTemplateDir } from '#utils/paths.js';
13
13
  import { executeClaudeCommand } from '#utils/claude.js';
@@ -19,7 +19,7 @@ vi.mock('@oclif/core', () => ({
19
19
  colorize: vi.fn().mockImplementation((_color, text) => text)
20
20
  }
21
21
  }));
22
- vi.mock('#utils/prompt.js', () => ({
22
+ vi.mock('@inquirer/prompts', () => ({
23
23
  confirm: vi.fn()
24
24
  }));
25
25
  describe('coding_agents service', () => {
@@ -157,7 +157,7 @@ describe('coding_agents service', () => {
157
157
  });
158
158
  it('should show error and prompt user when plugin commands fail', async () => {
159
159
  const { executeClaudeCommand } = await import('../utils/claude.js');
160
- const { confirm } = await import('#utils/prompt.js');
160
+ const { confirm } = await import('@inquirer/prompts');
161
161
  vi.mocked(executeClaudeCommand)
162
162
  .mockResolvedValueOnce(undefined) // marketplace add
163
163
  .mockRejectedValueOnce(new Error('Plugin update failed')); // marketplace update
@@ -169,7 +169,7 @@ describe('coding_agents service', () => {
169
169
  });
170
170
  it('should allow user to proceed without plugin setup if they confirm', async () => {
171
171
  const { executeClaudeCommand } = await import('../utils/claude.js');
172
- const { confirm } = await import('#utils/prompt.js');
172
+ const { confirm } = await import('@inquirer/prompts');
173
173
  vi.mocked(executeClaudeCommand)
174
174
  .mockRejectedValue(new Error('All plugin commands fail'));
175
175
  vi.mocked(confirm).mockResolvedValue(true);
@@ -219,7 +219,7 @@ describe('coding_agents service', () => {
219
219
  });
220
220
  it('should show error and prompt user when registerPluginMarketplace fails', async () => {
221
221
  const { executeClaudeCommand } = await import('../utils/claude.js');
222
- const { confirm } = await import('#utils/prompt.js');
222
+ const { confirm } = await import('@inquirer/prompts');
223
223
  vi.mocked(executeClaudeCommand)
224
224
  .mockResolvedValueOnce(undefined) // marketplace add
225
225
  .mockRejectedValueOnce(new Error('Plugin update failed')); // marketplace update
@@ -231,7 +231,7 @@ describe('coding_agents service', () => {
231
231
  });
232
232
  it('should show error and prompt user when installOutputAIPlugin fails', async () => {
233
233
  const { executeClaudeCommand } = await import('../utils/claude.js');
234
- const { confirm } = await import('#utils/prompt.js');
234
+ const { confirm } = await import('@inquirer/prompts');
235
235
  vi.mocked(executeClaudeCommand)
236
236
  .mockResolvedValueOnce(undefined) // marketplace add
237
237
  .mockResolvedValueOnce(undefined) // marketplace update
@@ -244,7 +244,7 @@ describe('coding_agents service', () => {
244
244
  });
245
245
  it('should allow user to proceed without plugin setup if they confirm', async () => {
246
246
  const { executeClaudeCommand } = await import('../utils/claude.js');
247
- const { confirm } = await import('#utils/prompt.js');
247
+ const { confirm } = await import('@inquirer/prompts');
248
248
  vi.mocked(executeClaudeCommand)
249
249
  .mockRejectedValue(new Error('All plugin commands fail'));
250
250
  vi.mocked(confirm).mockResolvedValue(true);
@@ -1,4 +1,4 @@
1
- import { password, confirm } from '#utils/prompt.js';
1
+ import { password, confirm } from '@inquirer/prompts';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { ux } from '@oclif/core';
@@ -1,4 +1,4 @@
1
- import { input, confirm, password } from '#utils/prompt.js';
1
+ import { input, confirm, password } from '@inquirer/prompts';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { ux } from '@oclif/core';
@@ -3,7 +3,7 @@ import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  import { configureEnvironmentVariables } from './env_configurator.js';
5
5
  // Mock inquirer prompts
6
- vi.mock('#utils/prompt.js', () => ({
6
+ vi.mock('@inquirer/prompts', () => ({
7
7
  input: vi.fn(),
8
8
  confirm: vi.fn(),
9
9
  password: vi.fn()
@@ -45,7 +45,7 @@ describe('configureEnvironmentVariables', () => {
45
45
  expect(result).toBe(false);
46
46
  });
47
47
  it('should return false if user declines configuration', async () => {
48
- const { confirm } = await import('#utils/prompt.js');
48
+ const { confirm } = await import('@inquirer/prompts');
49
49
  vi.mocked(confirm).mockResolvedValue(false);
50
50
  await fs.writeFile(testState.envExamplePath, '# API key\nAPIKEY=');
51
51
  const result = await configureEnvironmentVariables(testState.tempDir, false);
@@ -53,14 +53,14 @@ describe('configureEnvironmentVariables', () => {
53
53
  expect(vi.mocked(confirm)).toHaveBeenCalled();
54
54
  });
55
55
  it('should return false if no empty variables exist', async () => {
56
- const { confirm } = await import('#utils/prompt.js');
56
+ const { confirm } = await import('@inquirer/prompts');
57
57
  vi.mocked(confirm).mockResolvedValue(true);
58
58
  await fs.writeFile(testState.envExamplePath, 'APIKEY=my-secret-key');
59
59
  const result = await configureEnvironmentVariables(testState.tempDir, false);
60
60
  expect(result).toBe(false);
61
61
  });
62
62
  it('should copy .env.example to .env when user confirms configuration', async () => {
63
- const { input, confirm } = await import('#utils/prompt.js');
63
+ const { input, confirm } = await import('@inquirer/prompts');
64
64
  vi.mocked(confirm).mockResolvedValue(true);
65
65
  vi.mocked(input).mockResolvedValueOnce('sk-proj-123');
66
66
  const originalContent = `# API key
@@ -72,7 +72,7 @@ APIKEY=`;
72
72
  await expect(fs.access(testState.envPath)).resolves.toBeUndefined();
73
73
  });
74
74
  it('should write configured values to .env while leaving .env.example unchanged', async () => {
75
- const { input, confirm } = await import('#utils/prompt.js');
75
+ const { input, confirm } = await import('@inquirer/prompts');
76
76
  vi.mocked(confirm).mockResolvedValue(true);
77
77
  vi.mocked(input).mockResolvedValueOnce('sk-proj-123');
78
78
  const originalContent = `# API key
@@ -88,7 +88,7 @@ APIKEY=`;
88
88
  expect(envExampleContent).toBe(originalContent);
89
89
  });
90
90
  it('should prompt for empty variables and update .env', async () => {
91
- const { input, confirm } = await import('#utils/prompt.js');
91
+ const { input, confirm } = await import('@inquirer/prompts');
92
92
  vi.mocked(confirm).mockResolvedValue(true);
93
93
  vi.mocked(input).mockResolvedValueOnce('sk-proj-123');
94
94
  vi.mocked(input).mockResolvedValueOnce('');
@@ -105,7 +105,7 @@ OPENAI_API_KEY=`);
105
105
  expect(content).toContain('OPENAI_API_KEY=');
106
106
  });
107
107
  it('should preserve comments in .env file', async () => {
108
- const { input, confirm } = await import('#utils/prompt.js');
108
+ const { input, confirm } = await import('@inquirer/prompts');
109
109
  vi.mocked(confirm).mockResolvedValue(true);
110
110
  vi.mocked(input).mockResolvedValueOnce('test-key');
111
111
  const originalContent = `# This is a comment
@@ -123,7 +123,7 @@ OTHER=value`;
123
123
  expect(content).toContain('OTHER=value');
124
124
  });
125
125
  it('should skip placeholder values and only prompt for truly empty variables', async () => {
126
- const { input, confirm } = await import('#utils/prompt.js');
126
+ const { input, confirm } = await import('@inquirer/prompts');
127
127
  vi.mocked(confirm).mockResolvedValue(true);
128
128
  vi.mocked(input).mockResolvedValueOnce('new-key');
129
129
  await fs.writeFile(testState.envExamplePath, `APIKEY=your_api_key_here
@@ -136,7 +136,7 @@ EMPTY_KEY=`);
136
136
  }));
137
137
  });
138
138
  it('should skip variables with existing values', async () => {
139
- const { input, confirm } = await import('#utils/prompt.js');
139
+ const { input, confirm } = await import('@inquirer/prompts');
140
140
  vi.mocked(confirm).mockResolvedValue(true);
141
141
  vi.mocked(input).mockResolvedValueOnce('new-key');
142
142
  await fs.writeFile(testState.envExamplePath, `EXISTING_KEY=existing-value
@@ -147,7 +147,7 @@ EMPTY_KEY=`);
147
147
  expect(vi.mocked(input)).toHaveBeenCalledTimes(1);
148
148
  });
149
149
  it('should handle case where .env already exists (overwrite with copy)', async () => {
150
- const { input, confirm } = await import('#utils/prompt.js');
150
+ const { input, confirm } = await import('@inquirer/prompts');
151
151
  vi.mocked(confirm).mockResolvedValue(true);
152
152
  vi.mocked(input).mockResolvedValueOnce('new-configured-value');
153
153
  // Create existing .env with old content
@@ -162,7 +162,7 @@ EMPTY_KEY=`);
162
162
  expect(envContent).not.toContain('OLD_KEY');
163
163
  });
164
164
  it('should return false if an error occurs during parsing', async () => {
165
- const { confirm } = await import('#utils/prompt.js');
165
+ const { confirm } = await import('@inquirer/prompts');
166
166
  vi.mocked(confirm).mockResolvedValue(true);
167
167
  await fs.writeFile(testState.envExamplePath, 'KEY=');
168
168
  // Delete the .env.example file after access check but before parsing would happen
@@ -178,7 +178,7 @@ EMPTY_KEY=`);
178
178
  vi.mocked(fs.copyFile).mockImplementation(originalCopyFile);
179
179
  });
180
180
  it('should prompt for SECRET marker values with password input', async () => {
181
- const { password, confirm } = await import('#utils/prompt.js');
181
+ const { password, confirm } = await import('@inquirer/prompts');
182
182
  vi.mocked(confirm).mockResolvedValue(true);
183
183
  vi.mocked(password).mockResolvedValueOnce('my-secret-api-key');
184
184
  await fs.writeFile(testState.envExamplePath, `# API Key
@@ -1,4 +1,4 @@
1
- import { input, confirm } from '#utils/prompt.js';
1
+ import { input, confirm } from '@inquirer/prompts';
2
2
  import { ux } from '@oclif/core';
3
3
  import { kebabCase, pascalCase } from 'change-case';
4
4
  import fs from 'node:fs/promises';
@@ -41,7 +41,7 @@ export async function checkDependencies() {
41
41
  try {
42
42
  const shouldProceed = await confirm({
43
43
  message: 'Would you like to proceed anyway?',
44
- default: true
44
+ default: false
45
45
  });
46
46
  if (!shouldProceed) {
47
47
  throw new UserCancelledError();
@@ -8,7 +8,7 @@ vi.mock('#utils/framework_version.js', () => ({
8
8
  })
9
9
  }));
10
10
  // Mock other dependencies
11
- vi.mock('#utils/prompt.js', () => ({
11
+ vi.mock('@inquirer/prompts', () => ({
12
12
  input: vi.fn(),
13
13
  confirm: vi.fn()
14
14
  }));
@@ -47,7 +47,7 @@ describe('project_scaffold', () => {
47
47
  });
48
48
  describe('getProjectConfig', () => {
49
49
  it('should skip all prompts when folderName is provided', async () => {
50
- const { input } = await import('#utils/prompt.js');
50
+ const { input } = await import('@inquirer/prompts');
51
51
  const config = await getProjectConfig('my-project');
52
52
  expect(config.folderName).toBe('my-project');
53
53
  expect(config.projectName).toBe('my-project');
@@ -58,7 +58,7 @@ describe('project_scaffold', () => {
58
58
  expect(config.description).toBe('AI Agents & Workflows built with Output.ai for test-folder');
59
59
  });
60
60
  it('should prompt for project name and folder name when not provided', async () => {
61
- const { input } = await import('#utils/prompt.js');
61
+ const { input } = await import('@inquirer/prompts');
62
62
  vi.mocked(input)
63
63
  .mockResolvedValueOnce('Test Project')
64
64
  .mockResolvedValueOnce('test-project');
@@ -73,7 +73,7 @@ describe('project_scaffold', () => {
73
73
  it('should not prompt when all dependencies are available', async () => {
74
74
  const { isDockerInstalled } = await import('#services/docker.js');
75
75
  const { isClaudeCliAvailable } = await import('#utils/claude.js');
76
- const { confirm } = await import('#utils/prompt.js');
76
+ const { confirm } = await import('@inquirer/prompts');
77
77
  vi.mocked(isDockerInstalled).mockReturnValue(true);
78
78
  vi.mocked(isClaudeCliAvailable).mockReturnValue(true);
79
79
  await checkDependencies();
@@ -82,7 +82,7 @@ describe('project_scaffold', () => {
82
82
  it('should prompt user when docker is missing', async () => {
83
83
  const { isDockerInstalled } = await import('#services/docker.js');
84
84
  const { isClaudeCliAvailable } = await import('#utils/claude.js');
85
- const { confirm } = await import('#utils/prompt.js');
85
+ const { confirm } = await import('@inquirer/prompts');
86
86
  vi.mocked(isDockerInstalled).mockReturnValue(false);
87
87
  vi.mocked(isClaudeCliAvailable).mockReturnValue(true);
88
88
  vi.mocked(confirm).mockResolvedValue(true);
@@ -94,7 +94,7 @@ describe('project_scaffold', () => {
94
94
  it('should throw UserCancelledError when user declines to proceed', async () => {
95
95
  const { isDockerInstalled } = await import('#services/docker.js');
96
96
  const { isClaudeCliAvailable } = await import('#utils/claude.js');
97
- const { confirm } = await import('#utils/prompt.js');
97
+ const { confirm } = await import('@inquirer/prompts');
98
98
  vi.mocked(isDockerInstalled).mockReturnValue(false);
99
99
  vi.mocked(isClaudeCliAvailable).mockReturnValue(true);
100
100
  vi.mocked(confirm).mockResolvedValue(false);
@@ -2,8 +2,7 @@
2
2
  * Workflow builder service for implementing workflows from plan files
3
3
  */
4
4
  import { ADDITIONAL_INSTRUCTIONS, BUILD_COMMAND_OPTIONS, invokeBuildWorkflow as invokeBuildWorkflowFromClient, replyToClaude } from './claude_client.js';
5
- import { input } from '#utils/prompt.js';
6
- import { isInteractive } from '#utils/interactive.js';
5
+ import { input } from '@inquirer/prompts';
7
6
  import { ux } from '@oclif/core';
8
7
  import fs from 'node:fs/promises';
9
8
  import path from 'node:path';
@@ -71,9 +70,6 @@ async function processModification(modification, currentOutput) {
71
70
  }
72
71
  }
73
72
  async function interactiveRefinementLoop(currentOutput) {
74
- if (!isInteractive()) {
75
- return currentOutput;
76
- }
77
73
  const modification = await promptForModification();
78
74
  if (isAcceptCommand(modification)) {
79
75
  return currentOutput;
@@ -1,12 +1,11 @@
1
1
  import { describe, it, expect, beforeEach, vi } from 'vitest';
2
2
  import { buildWorkflow, buildWorkflowInteractiveLoop } from './workflow_builder.js';
3
3
  import { ADDITIONAL_INSTRUCTIONS, BUILD_COMMAND_OPTIONS, invokeBuildWorkflow, replyToClaude } from './claude_client.js';
4
- import { input } from '#utils/prompt.js';
4
+ import { input } from '@inquirer/prompts';
5
5
  import { ux } from '@oclif/core';
6
6
  import fs from 'node:fs/promises';
7
7
  vi.mock('./claude_client.js');
8
- vi.mock('#utils/prompt.js');
9
- vi.mock('#utils/interactive.js', () => ({ isInteractive: () => true }));
8
+ vi.mock('@inquirer/prompts');
10
9
  vi.mock('@oclif/core', () => ({
11
10
  ux: {
12
11
  stdout: vi.fn(),
@@ -1,5 +1,5 @@
1
- import type { GetWorkflowIdResult200, GetWorkflowIdResult200Status } from '../api/generated/api.js';
2
- type WorkflowResult = Pick<GetWorkflowIdResult200, 'workflowId' | 'output' | 'status' | 'error'>;
3
- export declare const ERROR_STATUSES: ReadonlySet<GetWorkflowIdResult200Status | undefined>;
1
+ import type { WorkflowResultResponse, WorkflowResultResponseStatus } from '../api/generated/api.js';
2
+ type WorkflowResult = Pick<WorkflowResultResponse, 'workflowId' | 'output' | 'status' | 'error'>;
3
+ export declare const ERROR_STATUSES: ReadonlySet<WorkflowResultResponseStatus | undefined>;
4
4
  export declare function formatWorkflowResult(result: WorkflowResult): string;
5
5
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outputai/cli",
3
- "version": "0.1.13-dev.98dfd72.0",
3
+ "version": "0.1.13-dev.af42b51.0",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -34,11 +34,10 @@
34
34
  "ky": "1.14.3",
35
35
  "react": "19.2.4",
36
36
  "semver": "7.7.4",
37
- "undici": "8.0.2",
38
37
  "yaml": "^2.8.3",
39
- "@outputai/credentials": "0.1.13-dev.98dfd72.0",
40
- "@outputai/evals": "0.1.13-dev.98dfd72.0",
41
- "@outputai/llm": "0.1.13-dev.98dfd72.0"
38
+ "@outputai/credentials": "0.1.13-dev.af42b51.0",
39
+ "@outputai/evals": "0.1.13-dev.af42b51.0",
40
+ "@outputai/llm": "0.1.13-dev.af42b51.0"
42
41
  },
43
42
  "devDependencies": {
44
43
  "@types/cli-progress": "3.11.6",
@@ -1,14 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class CredentialsSet extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static args: {
6
- path: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
- value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
8
- };
9
- static flags: {
10
- environment: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- workflow: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
- };
13
- run(): Promise<void>;
14
- }