@outputai/cli 0.1.7-next.ee88974.0 → 0.1.8-dev.b0ddd17.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.
- package/dist/api/generated/api.d.ts +19 -19
- package/dist/api/generated/api.js +1 -1
- package/dist/assets/docker/docker-compose-dev.yml +1 -1
- package/dist/generated/framework_version.json +1 -1
- package/dist/services/credentials_configurator.d.ts +1 -0
- package/dist/services/credentials_configurator.js +68 -0
- package/dist/services/credentials_service.d.ts +6 -0
- package/dist/services/credentials_service.js +23 -0
- package/dist/services/env_configurator.js +1 -1
- package/dist/services/env_configurator.spec.js +2 -2
- package/dist/services/messages.d.ts +1 -1
- package/dist/services/messages.js +8 -5
- package/dist/services/project_scaffold.js +18 -5
- package/dist/services/project_scaffold.spec.js +12 -2
- package/dist/templates/project/.env.example.template +2 -2
- package/dist/templates/project/package.json.template +3 -0
- package/package.json +10 -10
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generated by orval v8.
|
|
2
|
+
* Generated by orval v8.6.2 🍺
|
|
3
3
|
* Do not edit manually.
|
|
4
4
|
* Output.ai API
|
|
5
5
|
* API for managing and executing Output.ai workflows
|
|
@@ -15,9 +15,9 @@ export interface ErrorResponse {
|
|
|
15
15
|
/** Human-readable error message */
|
|
16
16
|
message?: string;
|
|
17
17
|
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
* Workflow ID when the error is tied to a specific execution (e.g. timeout)
|
|
19
|
+
* @nullable
|
|
20
|
+
*/
|
|
21
21
|
workflowId?: string | null;
|
|
22
22
|
}
|
|
23
23
|
export type ValidationErrorResponseError = typeof ValidationErrorResponseError[keyof typeof ValidationErrorResponseError];
|
|
@@ -69,14 +69,14 @@ export interface Workflow {
|
|
|
69
69
|
*/
|
|
70
70
|
export type TraceInfoDestinations = {
|
|
71
71
|
/**
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
* Absolute path to local trace file, or null if not saved locally
|
|
73
|
+
* @nullable
|
|
74
|
+
*/
|
|
75
75
|
local: string | null;
|
|
76
76
|
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
* Remote trace location (e.g., S3 URI), or null if not saved remotely
|
|
78
|
+
* @nullable
|
|
79
|
+
*/
|
|
80
80
|
remote: string | null;
|
|
81
81
|
};
|
|
82
82
|
/**
|
|
@@ -163,9 +163,9 @@ export interface WorkflowRunInfo {
|
|
|
163
163
|
/** ISO 8601 timestamp of run start */
|
|
164
164
|
startedAt?: string;
|
|
165
165
|
/**
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
* ISO 8601 timestamp of completion, or null if still running
|
|
167
|
+
* @nullable
|
|
168
|
+
*/
|
|
169
169
|
completedAt?: string | null;
|
|
170
170
|
}
|
|
171
171
|
export interface WorkflowRunsResponse {
|
|
@@ -226,9 +226,9 @@ export type PostWorkflowRun200 = {
|
|
|
226
226
|
/** The workflow execution status */
|
|
227
227
|
status?: PostWorkflowRun200Status;
|
|
228
228
|
/**
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
229
|
+
* Error message if workflow failed, null otherwise
|
|
230
|
+
* @nullable
|
|
231
|
+
*/
|
|
232
232
|
error?: string | null;
|
|
233
233
|
};
|
|
234
234
|
export type PostWorkflowStartBody = {
|
|
@@ -310,9 +310,9 @@ export type GetWorkflowIdResult200 = {
|
|
|
310
310
|
/** The workflow execution status */
|
|
311
311
|
status?: GetWorkflowIdResult200Status;
|
|
312
312
|
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
313
|
+
* Error message if workflow failed, null otherwise
|
|
314
|
+
* @nullable
|
|
315
|
+
*/
|
|
316
316
|
error?: string | null;
|
|
317
317
|
};
|
|
318
318
|
export type GetWorkflowCatalogId200 = {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function configureCredentials(projectPath: string, skipPrompt?: boolean): Promise<boolean>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { password, confirm } from '@inquirer/prompts';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { ux } from '@oclif/core';
|
|
5
|
+
import { load as parseYaml, dump as stringifyYaml } from 'js-yaml';
|
|
6
|
+
import { UserCancelledError } from '#types/errors.js';
|
|
7
|
+
import { getErrorMessage } from '#utils/error_utils.js';
|
|
8
|
+
import { writeEncryptedAtPath } from './credentials_service.js';
|
|
9
|
+
const FILL_MARKER = '<FILL_ME_OUT>';
|
|
10
|
+
const CREDENTIALS_TEMPLATE = path.join('config', 'credentials.yml.template');
|
|
11
|
+
const findSecretFields = (obj, prefix = []) => Object.entries(obj).flatMap(([key, value]) => {
|
|
12
|
+
const fieldPath = [...prefix, key];
|
|
13
|
+
if (value === FILL_MARKER) {
|
|
14
|
+
return [{ path: fieldPath, label: fieldPath.join('.') }];
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === 'object' && value !== null) {
|
|
17
|
+
return findSecretFields(value, fieldPath);
|
|
18
|
+
}
|
|
19
|
+
return [];
|
|
20
|
+
});
|
|
21
|
+
const setAtPath = (obj, [head, ...tail], value) => {
|
|
22
|
+
if (tail.length === 0) {
|
|
23
|
+
obj[head] = value;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
setAtPath(obj[head], tail, value);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
export async function configureCredentials(projectPath, skipPrompt = false) {
|
|
30
|
+
try {
|
|
31
|
+
const templatePath = path.join(projectPath, CREDENTIALS_TEMPLATE);
|
|
32
|
+
if (!fs.existsSync(templatePath)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (skipPrompt) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const shouldConfigure = await confirm({
|
|
39
|
+
message: 'Would you like to configure API credentials now?',
|
|
40
|
+
default: true
|
|
41
|
+
});
|
|
42
|
+
if (!shouldConfigure) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const templateContent = fs.readFileSync(templatePath, 'utf-8');
|
|
46
|
+
const parsed = parseYaml(templateContent);
|
|
47
|
+
const secretFields = findSecretFields(parsed);
|
|
48
|
+
if (secretFields.length === 0) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
for (const field of secretFields) {
|
|
52
|
+
const value = await password({
|
|
53
|
+
message: `${field.label} (secret):`,
|
|
54
|
+
mask: true
|
|
55
|
+
});
|
|
56
|
+
setAtPath(parsed, field.path, value || '');
|
|
57
|
+
}
|
|
58
|
+
writeEncryptedAtPath(projectPath, stringifyYaml(parsed));
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (error instanceof Error && error.name === 'ExitPromptError') {
|
|
63
|
+
throw new UserCancelledError();
|
|
64
|
+
}
|
|
65
|
+
ux.warn(`Failed to configure credentials: ${getErrorMessage(error)}`);
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -10,3 +10,9 @@ export declare const initCredentials: (environment: CredentialsEnvironment, work
|
|
|
10
10
|
keyPath: string;
|
|
11
11
|
credPath: string;
|
|
12
12
|
};
|
|
13
|
+
export declare const initCredentialsAtPath: (projectPath: string) => {
|
|
14
|
+
keyPath: string;
|
|
15
|
+
credPath: string;
|
|
16
|
+
};
|
|
17
|
+
export declare const readKeyAtPath: (projectPath: string) => string;
|
|
18
|
+
export declare const writeEncryptedAtPath: (projectPath: string, plaintext: string) => void;
|
|
@@ -62,3 +62,26 @@ export const initCredentials = (environment, workflow) => {
|
|
|
62
62
|
fs.writeFileSync(credPath, encrypt(template, key), 'utf8');
|
|
63
63
|
return { keyPath, credPath };
|
|
64
64
|
};
|
|
65
|
+
export const initCredentialsAtPath = (projectPath) => {
|
|
66
|
+
const credPath = resolveCredPath(projectPath);
|
|
67
|
+
const keyPath = resolveKPath(projectPath);
|
|
68
|
+
fs.mkdirSync(path.dirname(keyPath), { recursive: true });
|
|
69
|
+
fs.mkdirSync(path.dirname(credPath), { recursive: true });
|
|
70
|
+
const key = generateKey();
|
|
71
|
+
fs.writeFileSync(keyPath, key, { mode: 0o600 });
|
|
72
|
+
const template = stringifyYaml({
|
|
73
|
+
anthropic: { api_key: '<FILL_ME_OUT>' },
|
|
74
|
+
openai: { api_key: '<FILL_ME_OUT>' }
|
|
75
|
+
});
|
|
76
|
+
fs.writeFileSync(credPath, encrypt(template, key), 'utf8');
|
|
77
|
+
return { keyPath, credPath };
|
|
78
|
+
};
|
|
79
|
+
export const readKeyAtPath = (projectPath) => {
|
|
80
|
+
const keyPath = resolveKPath(projectPath);
|
|
81
|
+
return fs.readFileSync(keyPath, 'utf8').trim();
|
|
82
|
+
};
|
|
83
|
+
export const writeEncryptedAtPath = (projectPath, plaintext) => {
|
|
84
|
+
const key = readKeyAtPath(projectPath);
|
|
85
|
+
const credPath = resolveCredPath(projectPath);
|
|
86
|
+
fs.writeFileSync(credPath, encrypt(plaintext, key), 'utf8');
|
|
87
|
+
};
|
|
@@ -8,7 +8,7 @@ const COMMENT_LINE = /^\s*#/;
|
|
|
8
8
|
const COMMENTED_VAR = /^\s*#\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/;
|
|
9
9
|
const ACTIVE_VAR = /^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/;
|
|
10
10
|
const VAR_IN_COMMENT = /^\s*#\s*[A-Z_]+=/;
|
|
11
|
-
const SECRET_MARKER = '<
|
|
11
|
+
const SECRET_MARKER = '<FILL_ME_OUT>';
|
|
12
12
|
function extractDescription(commentLine) {
|
|
13
13
|
return commentLine.replace(/^\s*#\s*/, '').trim();
|
|
14
14
|
}
|
|
@@ -29,7 +29,7 @@ describe('configureEnvironmentVariables', () => {
|
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
it('should copy .env.example to .env when skipPrompt is true', async () => {
|
|
32
|
-
const envExampleContent = 'API_KEY=<
|
|
32
|
+
const envExampleContent = 'API_KEY=<FILL_ME_OUT>\nDATABASE_URL=localhost';
|
|
33
33
|
await fs.writeFile(testState.envExamplePath, envExampleContent);
|
|
34
34
|
const result = await configureEnvironmentVariables(testState.tempDir, true);
|
|
35
35
|
expect(result).toBe(false);
|
|
@@ -182,7 +182,7 @@ EMPTY_KEY=`);
|
|
|
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
|
|
185
|
-
ANTHROPIC_API_KEY=<
|
|
185
|
+
ANTHROPIC_API_KEY=<FILL_ME_OUT>`);
|
|
186
186
|
const result = await configureEnvironmentVariables(testState.tempDir, false);
|
|
187
187
|
expect(result).toBe(true);
|
|
188
188
|
expect(vi.mocked(password)).toHaveBeenCalledTimes(1);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Success and informational messages for project initialization
|
|
3
3
|
*/
|
|
4
4
|
export declare const getEjectSuccessMessage: (destPath: string, outputFile: string, binName: string) => string;
|
|
5
|
-
export declare const getProjectSuccessMessage: (folderName: string, installSuccess: boolean,
|
|
5
|
+
export declare const getProjectSuccessMessage: (folderName: string, installSuccess: boolean, credentialsConfigured?: boolean) => string;
|
|
6
6
|
export declare const getWorkflowGenerateSuccessMessage: (workflowName: string, targetDir: string, filesCreated: string[]) => string;
|
|
7
7
|
export declare const getDevSuccessMessage: (services: Array<{
|
|
8
8
|
name: string;
|
|
@@ -147,7 +147,7 @@ ${ux.colorize('dim', '💡 Tip: Test your changes with ')}${formatCommand('docke
|
|
|
147
147
|
${ux.colorize('green', ux.colorize('bold', 'Happy customizing! 🛠️'))}
|
|
148
148
|
`;
|
|
149
149
|
};
|
|
150
|
-
export const getProjectSuccessMessage = (folderName, installSuccess,
|
|
150
|
+
export const getProjectSuccessMessage = (folderName, installSuccess, credentialsConfigured = false) => {
|
|
151
151
|
const divider = ux.colorize('dim', '─'.repeat(80));
|
|
152
152
|
const bulletPoint = ux.colorize('green', '▸');
|
|
153
153
|
// Build the next steps array with proper formatting
|
|
@@ -164,11 +164,11 @@ export const getProjectSuccessMessage = (folderName, installSuccess, envConfigur
|
|
|
164
164
|
note: 'Required before running workflows'
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
|
-
if (!
|
|
167
|
+
if (!credentialsConfigured) {
|
|
168
168
|
steps.push({
|
|
169
|
-
step: '
|
|
170
|
-
command: '
|
|
171
|
-
note: '
|
|
169
|
+
step: 'Add your API credentials',
|
|
170
|
+
command: 'npx output credentials edit',
|
|
171
|
+
note: 'Learn more: https://docs.output.ai/packages/credentials'
|
|
172
172
|
});
|
|
173
173
|
}
|
|
174
174
|
steps.push({
|
|
@@ -229,6 +229,9 @@ ${divider}
|
|
|
229
229
|
${ux.colorize('dim', '💡 Tip: Use ')}${formatCommand('npx output workflow plan')}${ux.colorize('dim', ' to design your first custom workflow')}
|
|
230
230
|
${ux.colorize('dim', ' with AI assistance.')}
|
|
231
231
|
|
|
232
|
+
${ux.colorize('dim', '🔑 Secrets: Use ')}${formatCommand('npx output credentials show|get|edit')}
|
|
233
|
+
${ux.colorize('dim', ' to manage your project secrets.')}
|
|
234
|
+
|
|
232
235
|
${ux.colorize('green', ux.colorize('bold', 'Happy building with Output! 🚀'))}
|
|
233
236
|
`;
|
|
234
237
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { input, confirm } from '@inquirer/prompts';
|
|
2
2
|
import { ux } from '@oclif/core';
|
|
3
3
|
import { kebabCase, pascalCase } from 'change-case';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import { FolderAlreadyExistsError, UserCancelledError, DirectoryCreationError } from '#types/errors.js';
|
|
@@ -10,7 +11,8 @@ import { getFrameworkVersion } from '#utils/framework_version.js';
|
|
|
10
11
|
import { getErrorMessage, getErrorCode } from '#utils/error_utils.js';
|
|
11
12
|
import { isDockerInstalled } from '#services/docker.js';
|
|
12
13
|
import { isClaudeCliAvailable } from '#utils/claude.js';
|
|
13
|
-
import {
|
|
14
|
+
import { initCredentialsAtPath } from './credentials_service.js';
|
|
15
|
+
import { configureCredentials } from './credentials_configurator.js';
|
|
14
16
|
import { getTemplateFiles, processTemplateFile } from './template_processor.js';
|
|
15
17
|
import { initializeAgentConfig } from './coding_agents.js';
|
|
16
18
|
import { getProjectSuccessMessage } from './messages.js';
|
|
@@ -105,6 +107,12 @@ async function scaffoldProjectFiles(projectPath, projectName, description) {
|
|
|
105
107
|
await Promise.all(templateFiles.map(templateFile => processTemplateFile(templateFile, projectPath, templateVars)));
|
|
106
108
|
return templateFiles.map(f => f.outputName);
|
|
107
109
|
}
|
|
110
|
+
const CREDENTIALS_TEMPLATE_CONTENT = 'anthropic:\n api_key: "<FILL_ME_OUT>"\nopenai:\n api_key: "<FILL_ME_OUT>"\n';
|
|
111
|
+
async function createCredentialsTemplate(projectPath) {
|
|
112
|
+
const filePath = path.join(projectPath, 'config', 'credentials.yml.template');
|
|
113
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
114
|
+
await fs.writeFile(filePath, CREDENTIALS_TEMPLATE_CONTENT, 'utf-8');
|
|
115
|
+
}
|
|
108
116
|
async function executeNpmInstall(projectPath) {
|
|
109
117
|
await executeCommand('npm', ['install'], projectPath);
|
|
110
118
|
}
|
|
@@ -192,13 +200,18 @@ export async function runInit(skipEnv = false, folderName) {
|
|
|
192
200
|
ux.stdout(`Created project folder: ${config.folderName}`);
|
|
193
201
|
const filesCreated = await scaffoldProjectFiles(config.projectPath, config.projectName, config.description);
|
|
194
202
|
ux.stdout(`Created ${filesCreated.length} project files`);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
203
|
+
await createCredentialsTemplate(config.projectPath);
|
|
204
|
+
initCredentialsAtPath(config.projectPath);
|
|
205
|
+
ux.stdout('Credentials initialized');
|
|
206
|
+
const credentialsConfigured = await configureCredentials(config.projectPath, skipEnv);
|
|
207
|
+
if (credentialsConfigured) {
|
|
208
|
+
ux.stdout('API credentials configured');
|
|
198
209
|
}
|
|
210
|
+
// Copy .env.example to .env (no secrets - they live in credentials.yml.enc)
|
|
211
|
+
await fs.copyFile(path.join(config.projectPath, '.env.example'), path.join(config.projectPath, '.env'));
|
|
199
212
|
await executeCommandWithMessages(() => initializeAgents(config.projectPath), 'Initializing agent system...', 'Agent system initialized');
|
|
200
213
|
const installSuccess = await executeCommandWithMessages(() => executeNpmInstall(config.projectPath), 'Installing dependencies...', 'Dependencies installed');
|
|
201
|
-
const nextSteps = getProjectSuccessMessage(config.folderName, installSuccess,
|
|
214
|
+
const nextSteps = getProjectSuccessMessage(config.folderName, installSuccess, credentialsConfigured);
|
|
202
215
|
ux.stdout('Project created successfully!');
|
|
203
216
|
ux.stdout(nextSteps);
|
|
204
217
|
}
|
|
@@ -14,8 +14,18 @@ vi.mock('@inquirer/prompts', () => ({
|
|
|
14
14
|
}));
|
|
15
15
|
vi.mock('#utils/file_system.js');
|
|
16
16
|
vi.mock('#utils/process.js');
|
|
17
|
-
vi.mock('./
|
|
18
|
-
|
|
17
|
+
vi.mock('./credentials_service.js', () => ({
|
|
18
|
+
initCredentialsAtPath: vi.fn()
|
|
19
|
+
}));
|
|
20
|
+
vi.mock('./credentials_configurator.js', () => ({
|
|
21
|
+
configureCredentials: vi.fn().mockResolvedValue(false)
|
|
22
|
+
}));
|
|
23
|
+
vi.mock('node:fs/promises', () => ({
|
|
24
|
+
default: {
|
|
25
|
+
mkdir: vi.fn().mockResolvedValue(undefined),
|
|
26
|
+
writeFile: vi.fn().mockResolvedValue(undefined),
|
|
27
|
+
copyFile: vi.fn().mockResolvedValue(undefined)
|
|
28
|
+
}
|
|
19
29
|
}));
|
|
20
30
|
vi.mock('./template_processor.js');
|
|
21
31
|
vi.mock('./coding_agents.js');
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
DOCKER_SERVICE_NAME={{projectName}}
|
|
3
3
|
|
|
4
4
|
# Configure if you plan to use Anthropic Models in your LLM prompts
|
|
5
|
-
ANTHROPIC_API_KEY
|
|
5
|
+
ANTHROPIC_API_KEY=credential:anthropic.api_key
|
|
6
6
|
|
|
7
7
|
# Configure if you plan to use OpenAI in your LLM prompts
|
|
8
|
-
OPENAI_API_KEY
|
|
8
|
+
OPENAI_API_KEY=credential:openai.api_key
|
|
9
9
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outputai/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8-dev.b0ddd17.0",
|
|
4
4
|
"description": "CLI for Output.ai workflow generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
"output": "./bin/run.js"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@anthropic-ai/claude-agent-sdk": "0.2.
|
|
18
|
-
"@aws-sdk/client-s3": "3.
|
|
17
|
+
"@anthropic-ai/claude-agent-sdk": "0.2.81",
|
|
18
|
+
"@aws-sdk/client-s3": "3.1015.0",
|
|
19
19
|
"@hackylabs/deep-redact": "3.0.5",
|
|
20
20
|
"@inquirer/prompts": "8.3.2",
|
|
21
|
-
"@oclif/core": "4.
|
|
22
|
-
"@oclif/plugin-help": "6.2.
|
|
21
|
+
"@oclif/core": "4.10.2",
|
|
22
|
+
"@oclif/plugin-help": "6.2.40",
|
|
23
23
|
"change-case": "5.4.4",
|
|
24
24
|
"cli-progress": "3.12.0",
|
|
25
25
|
"cli-table3": "0.6.5",
|
|
@@ -32,17 +32,17 @@
|
|
|
32
32
|
"ky": "1.14.3",
|
|
33
33
|
"log-update": "7.2.0",
|
|
34
34
|
"semver": "7.7.4",
|
|
35
|
-
"yaml": "^2.
|
|
36
|
-
"@outputai/credentials": "0.1.
|
|
37
|
-
"@outputai/evals": "0.1.
|
|
38
|
-
"@outputai/llm": "0.1.
|
|
35
|
+
"yaml": "^2.8.3",
|
|
36
|
+
"@outputai/credentials": "0.1.8-dev.b0ddd17.0",
|
|
37
|
+
"@outputai/evals": "0.1.8-dev.b0ddd17.0",
|
|
38
|
+
"@outputai/llm": "0.1.8-dev.b0ddd17.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/cli-progress": "3.11.6",
|
|
42
42
|
"@types/debug": "4.1.13",
|
|
43
43
|
"@types/js-yaml": "4.0.9",
|
|
44
44
|
"@types/semver": "7.7.1",
|
|
45
|
-
"orval": "8.
|
|
45
|
+
"orval": "8.6.2"
|
|
46
46
|
},
|
|
47
47
|
"license": "Apache-2.0",
|
|
48
48
|
"publishConfig": {
|