@outputai/cli 0.1.0 → 0.1.1
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 +45 -0
- package/dist/api/generated/api.js +11 -0
- package/dist/assets/docker/docker-compose-dev.yml +1 -1
- package/dist/commands/credentials/edit.js +6 -2
- package/dist/commands/dev/index.d.ts +1 -0
- package/dist/commands/dev/index.js +13 -2
- package/dist/commands/workflow/reset.d.ts +14 -0
- package/dist/commands/workflow/reset.js +51 -0
- package/dist/generated/framework_version.json +1 -1
- package/dist/services/coding_agents.js +2 -2
- package/dist/services/coding_agents.spec.js +3 -3
- package/dist/services/copy_assets.spec.js +4 -0
- package/dist/services/docker.d.ts +1 -0
- package/dist/services/docker.js +12 -0
- package/dist/services/generate_plan_name@v1.prompt +1 -1
- package/dist/templates/agent_instructions/CLAUDE.md.template +1 -1
- package/dist/templates/agent_instructions/dotclaude/settings.json.template +1 -1
- package/dist/templates/project/config/costs.yml.template +29 -0
- package/package.json +9 -9
|
@@ -277,6 +277,18 @@ export type PostWorkflowIdTerminate200 = {
|
|
|
277
277
|
terminated?: boolean;
|
|
278
278
|
workflowId?: string;
|
|
279
279
|
};
|
|
280
|
+
export type PostWorkflowIdResetBody = {
|
|
281
|
+
/** The name of the step to reset after */
|
|
282
|
+
stepName: string;
|
|
283
|
+
/** Optional reason for the reset */
|
|
284
|
+
reason?: string;
|
|
285
|
+
};
|
|
286
|
+
export type PostWorkflowIdReset200 = {
|
|
287
|
+
/** The original workflow ID */
|
|
288
|
+
workflowId?: string;
|
|
289
|
+
/** The run ID of the new execution created by the reset */
|
|
290
|
+
runId?: string;
|
|
291
|
+
};
|
|
280
292
|
/**
|
|
281
293
|
* The workflow execution status
|
|
282
294
|
*/
|
|
@@ -518,6 +530,39 @@ export type postWorkflowIdTerminateResponseError = (postWorkflowIdTerminateRespo
|
|
|
518
530
|
export type postWorkflowIdTerminateResponse = (postWorkflowIdTerminateResponseSuccess | postWorkflowIdTerminateResponseError);
|
|
519
531
|
export declare const getPostWorkflowIdTerminateUrl: (id: string) => string;
|
|
520
532
|
export declare const postWorkflowIdTerminate: (id: string, postWorkflowIdTerminateBody: PostWorkflowIdTerminateBody, options?: ApiRequestOptions) => Promise<postWorkflowIdTerminateResponse>;
|
|
533
|
+
/**
|
|
534
|
+
* Resets a workflow execution to the point after a completed step, creating a new run that replays from that point. The current execution is terminated.
|
|
535
|
+
* @summary Reset a workflow to re-run from after a specific step
|
|
536
|
+
*/
|
|
537
|
+
export type postWorkflowIdResetResponse200 = {
|
|
538
|
+
data: PostWorkflowIdReset200;
|
|
539
|
+
status: 200;
|
|
540
|
+
};
|
|
541
|
+
export type postWorkflowIdResetResponse400 = {
|
|
542
|
+
data: BadRequestResponse;
|
|
543
|
+
status: 400;
|
|
544
|
+
};
|
|
545
|
+
export type postWorkflowIdResetResponse404 = {
|
|
546
|
+
data: NotFoundResponse;
|
|
547
|
+
status: 404;
|
|
548
|
+
};
|
|
549
|
+
export type postWorkflowIdResetResponse409 = {
|
|
550
|
+
data: ErrorResponse;
|
|
551
|
+
status: 409;
|
|
552
|
+
};
|
|
553
|
+
export type postWorkflowIdResetResponse500 = {
|
|
554
|
+
data: InternalServerErrorResponse;
|
|
555
|
+
status: 500;
|
|
556
|
+
};
|
|
557
|
+
export type postWorkflowIdResetResponseSuccess = (postWorkflowIdResetResponse200) & {
|
|
558
|
+
headers: Headers;
|
|
559
|
+
};
|
|
560
|
+
export type postWorkflowIdResetResponseError = (postWorkflowIdResetResponse400 | postWorkflowIdResetResponse404 | postWorkflowIdResetResponse409 | postWorkflowIdResetResponse500) & {
|
|
561
|
+
headers: Headers;
|
|
562
|
+
};
|
|
563
|
+
export type postWorkflowIdResetResponse = (postWorkflowIdResetResponseSuccess | postWorkflowIdResetResponseError);
|
|
564
|
+
export declare const getPostWorkflowIdResetUrl: (id: string) => string;
|
|
565
|
+
export declare const postWorkflowIdReset: (id: string, postWorkflowIdResetBody: PostWorkflowIdResetBody, options?: ApiRequestOptions) => Promise<postWorkflowIdResetResponse>;
|
|
521
566
|
/**
|
|
522
567
|
* @summary Return the result of a workflow
|
|
523
568
|
*/
|
|
@@ -107,6 +107,17 @@ export const postWorkflowIdTerminate = async (id, postWorkflowIdTerminateBody, o
|
|
|
107
107
|
body: JSON.stringify(postWorkflowIdTerminateBody)
|
|
108
108
|
});
|
|
109
109
|
};
|
|
110
|
+
export const getPostWorkflowIdResetUrl = (id) => {
|
|
111
|
+
return `/workflow/${id}/reset`;
|
|
112
|
+
};
|
|
113
|
+
export const postWorkflowIdReset = async (id, postWorkflowIdResetBody, options) => {
|
|
114
|
+
return customFetchInstance(getPostWorkflowIdResetUrl(id), {
|
|
115
|
+
...options,
|
|
116
|
+
method: 'POST',
|
|
117
|
+
headers: { 'Content-Type': 'application/json', ...options?.headers },
|
|
118
|
+
body: JSON.stringify(postWorkflowIdResetBody)
|
|
119
|
+
});
|
|
120
|
+
};
|
|
110
121
|
export const getGetWorkflowIdResultUrl = (id) => {
|
|
111
122
|
return `/workflow/${id}/result`;
|
|
112
123
|
};
|
|
@@ -32,12 +32,16 @@ export default class CredentialsEdit extends Command {
|
|
|
32
32
|
if (!credentialsExist(environment, workflow)) {
|
|
33
33
|
this.error(`No credentials file found at ${resolveCredentialsPath(environment, workflow)}. Run "output credentials init" first.`);
|
|
34
34
|
}
|
|
35
|
-
const
|
|
35
|
+
const editorEnv = process.env.EDITOR || process.env.VISUAL || 'vi';
|
|
36
|
+
const [editorCmd, ...editorArgs] = editorEnv.split(/\s+/);
|
|
36
37
|
const plaintext = decryptCredentials(environment, workflow);
|
|
37
38
|
const tmpFile = path.join(os.tmpdir(), `output-credentials-${Date.now()}.yml`);
|
|
38
39
|
try {
|
|
39
40
|
fs.writeFileSync(tmpFile, plaintext, { mode: 0o600 });
|
|
40
|
-
const result = spawnSync(
|
|
41
|
+
const result = spawnSync(editorCmd, [...editorArgs, tmpFile], { stdio: 'inherit' });
|
|
42
|
+
if (result.error) {
|
|
43
|
+
this.error(`Failed to launch editor: ${result.error.message}`);
|
|
44
|
+
}
|
|
41
45
|
if (result.status !== 0) {
|
|
42
46
|
this.error(`Editor exited with non-zero status: ${result.status}`);
|
|
43
47
|
}
|
|
@@ -6,6 +6,7 @@ export default class Dev extends Command {
|
|
|
6
6
|
static flags: {
|
|
7
7
|
'compose-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
8
|
'image-pull-policy': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
detached: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
};
|
|
10
11
|
private dockerProcess;
|
|
11
12
|
run(): Promise<void>;
|
|
@@ -2,7 +2,7 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import logUpdate from 'log-update';
|
|
5
|
-
import { validateDockerEnvironment, startDockerCompose, stopDockerCompose, getServiceStatus, DockerComposeConfigNotFoundError, getDefaultDockerComposePath, SERVICE_HEALTH, SERVICE_STATE } from '#services/docker.js';
|
|
5
|
+
import { validateDockerEnvironment, startDockerCompose, startDockerComposeDetached, stopDockerCompose, getServiceStatus, DockerComposeConfigNotFoundError, getDefaultDockerComposePath, SERVICE_HEALTH, SERVICE_STATE } from '#services/docker.js';
|
|
6
6
|
import { getErrorMessage } from '#utils/error_utils.js';
|
|
7
7
|
import { getDevSuccessMessage } from '#services/messages.js';
|
|
8
8
|
import { ensureClaudePlugin } from '#services/coding_agents.js';
|
|
@@ -87,6 +87,11 @@ export default class Dev extends Command {
|
|
|
87
87
|
description: 'Image pull policy for docker compose (always, missing, never)',
|
|
88
88
|
options: ['always', 'missing', 'never'],
|
|
89
89
|
default: 'always'
|
|
90
|
+
}),
|
|
91
|
+
detached: Flags.boolean({
|
|
92
|
+
description: 'Start services in detached (background) mode and exit immediately',
|
|
93
|
+
default: false,
|
|
94
|
+
char: 'd'
|
|
90
95
|
})
|
|
91
96
|
};
|
|
92
97
|
dockerProcess = null;
|
|
@@ -108,6 +113,13 @@ export default class Dev extends Command {
|
|
|
108
113
|
if (flags['compose-file']) {
|
|
109
114
|
this.log(`Using custom docker-compose file: ${flags['compose-file']}\n`);
|
|
110
115
|
}
|
|
116
|
+
const pullPolicy = flags['image-pull-policy'];
|
|
117
|
+
if (flags.detached) {
|
|
118
|
+
this.log('🐳 Starting services in detached mode...\n');
|
|
119
|
+
startDockerComposeDetached(dockerComposePath, pullPolicy);
|
|
120
|
+
this.log('✅ Services started. Run `output dev` without --detached to monitor status.\n');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
111
123
|
this.log('File watching enabled - worker will restart automatically on changes\n');
|
|
112
124
|
const cleanup = async () => {
|
|
113
125
|
this.log('\n');
|
|
@@ -119,7 +131,6 @@ export default class Dev extends Command {
|
|
|
119
131
|
};
|
|
120
132
|
process.on('SIGINT', cleanup);
|
|
121
133
|
process.on('SIGTERM', cleanup);
|
|
122
|
-
const pullPolicy = flags['image-pull-policy'];
|
|
123
134
|
try {
|
|
124
135
|
const { process: dockerProc, waitForHealthy } = await startDockerCompose(dockerComposePath, pullPolicy);
|
|
125
136
|
this.dockerProcess = dockerProc;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class WorkflowReset extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
workflowId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
step: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
reason: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
catch(error: Error): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { postWorkflowIdReset } from '#api/generated/api.js';
|
|
3
|
+
import { handleApiError } from '#utils/error_handler.js';
|
|
4
|
+
export default class WorkflowReset extends Command {
|
|
5
|
+
static description = 'Reset a workflow to re-run from after a specific step';
|
|
6
|
+
static examples = [
|
|
7
|
+
'<%= config.bin %> <%= command.id %> wf-12345 --step generateBlogPost',
|
|
8
|
+
'<%= config.bin %> <%= command.id %> wf-12345 --step consolidateCompetitors --reason "Retry with updated prompt"'
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
workflowId: Args.string({
|
|
12
|
+
description: 'The workflow ID to reset',
|
|
13
|
+
required: true
|
|
14
|
+
})
|
|
15
|
+
};
|
|
16
|
+
static flags = {
|
|
17
|
+
step: Flags.string({
|
|
18
|
+
char: 's',
|
|
19
|
+
description: 'The step name to reset after',
|
|
20
|
+
required: true
|
|
21
|
+
}),
|
|
22
|
+
reason: Flags.string({
|
|
23
|
+
char: 'r',
|
|
24
|
+
description: 'Reason for the reset'
|
|
25
|
+
})
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
const { args, flags } = await this.parse(WorkflowReset);
|
|
29
|
+
this.log(`Resetting workflow: ${args.workflowId} to after step: ${flags.step}...`);
|
|
30
|
+
const response = await postWorkflowIdReset(args.workflowId, { stepName: flags.step, reason: flags.reason });
|
|
31
|
+
if (!response || !response.data) {
|
|
32
|
+
this.error('API returned invalid response', { exit: 1 });
|
|
33
|
+
}
|
|
34
|
+
const data = response.data;
|
|
35
|
+
const output = [
|
|
36
|
+
'Workflow reset successfully',
|
|
37
|
+
'',
|
|
38
|
+
`Workflow ID: ${args.workflowId}`,
|
|
39
|
+
`New Run ID: ${data.runId}`,
|
|
40
|
+
`Reset after step: ${flags.step}`,
|
|
41
|
+
flags.reason ? `Reason: ${flags.reason}` : ''
|
|
42
|
+
].filter(Boolean).join('\n');
|
|
43
|
+
this.log(`\n${output}`);
|
|
44
|
+
}
|
|
45
|
+
async catch(error) {
|
|
46
|
+
return handleApiError(error, (...args) => this.error(...args), {
|
|
47
|
+
404: 'Workflow or step not found. Check the workflow ID and step name.',
|
|
48
|
+
409: 'Step has not completed yet. Cannot reset to an incomplete step.'
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -14,7 +14,7 @@ import { executeClaudeCommand } from '#utils/claude.js';
|
|
|
14
14
|
import { processTemplate } from '#utils/template.js';
|
|
15
15
|
import { ClaudePluginError, UserCancelledError } from '#types/errors.js';
|
|
16
16
|
const debug = debugFactory('output-cli:agent');
|
|
17
|
-
const EXPECTED_MARKETPLACE_REPO = 'growthxai/output
|
|
17
|
+
const EXPECTED_MARKETPLACE_REPO = 'growthxai/output';
|
|
18
18
|
function createLogger(silent) {
|
|
19
19
|
return silent ? debug : (msg) => ux.stdout(ux.colorize('gray', msg));
|
|
20
20
|
}
|
|
@@ -169,7 +169,7 @@ async function registerPluginMarketplace(projectRoot, silent = false) {
|
|
|
169
169
|
const log = createLogger(silent);
|
|
170
170
|
log('Registering plugin marketplace...');
|
|
171
171
|
try {
|
|
172
|
-
await executeClaudeCommand(['plugin', 'marketplace', 'add', 'growthxai/output
|
|
172
|
+
await executeClaudeCommand(['plugin', 'marketplace', 'add', 'growthxai/output'], projectRoot, { ignoreFailure: true });
|
|
173
173
|
}
|
|
174
174
|
catch (error) {
|
|
175
175
|
await handlePluginError(error, 'plugin marketplace add', silent);
|
|
@@ -43,7 +43,7 @@ describe('coding_agents service', () => {
|
|
|
43
43
|
'team-tools': {
|
|
44
44
|
source: {
|
|
45
45
|
source: 'github',
|
|
46
|
-
repo: 'growthxai/output
|
|
46
|
+
repo: 'growthxai/output'
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
},
|
|
@@ -151,7 +151,7 @@ describe('coding_agents service', () => {
|
|
|
151
151
|
it('should call registerPluginMarketplace and installOutputAIPlugin', async () => {
|
|
152
152
|
const { executeClaudeCommand } = await import('../utils/claude.js');
|
|
153
153
|
await ensureClaudePlugin('/test/project');
|
|
154
|
-
expect(executeClaudeCommand).toHaveBeenCalledWith(['plugin', 'marketplace', 'add', 'growthxai/output
|
|
154
|
+
expect(executeClaudeCommand).toHaveBeenCalledWith(['plugin', 'marketplace', 'add', 'growthxai/output'], '/test/project', { ignoreFailure: true });
|
|
155
155
|
expect(executeClaudeCommand).toHaveBeenCalledWith(['plugin', 'marketplace', 'update', 'outputai'], '/test/project');
|
|
156
156
|
expect(executeClaudeCommand).toHaveBeenCalledWith(['plugin', 'install', 'outputai@outputai', '--scope', 'project'], '/test/project');
|
|
157
157
|
});
|
|
@@ -188,7 +188,7 @@ describe('coding_agents service', () => {
|
|
|
188
188
|
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify({
|
|
189
189
|
extraKnownMarketplaces: {
|
|
190
190
|
'team-tools': {
|
|
191
|
-
source: { source: 'github', repo: 'growthxai/output
|
|
191
|
+
source: { source: 'github', repo: 'growthxai/output' }
|
|
192
192
|
}
|
|
193
193
|
},
|
|
194
194
|
enabledPlugins: { 'outputai@outputai': true }
|
|
@@ -15,4 +15,8 @@ describe('copy-assets build output', () => {
|
|
|
15
15
|
expect(fs.existsSync(filePath), `Missing dotfile template in dist: ${dotfile}`).toBe(true);
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
|
+
it('should include config templates in dist/templates/project/', () => {
|
|
19
|
+
const configFile = path.join(distTemplatesDir, 'config', 'costs.yml.template');
|
|
20
|
+
expect(fs.existsSync(configFile), 'Missing config/costs.yml.template in dist').toBe(true);
|
|
21
|
+
});
|
|
18
22
|
});
|
|
@@ -34,5 +34,6 @@ export interface DockerComposeProcess {
|
|
|
34
34
|
}
|
|
35
35
|
export type PullPolicy = 'always' | 'missing' | 'never';
|
|
36
36
|
export declare function startDockerCompose(dockerComposePath: string, pullPolicy?: PullPolicy): Promise<DockerComposeProcess>;
|
|
37
|
+
export declare function startDockerComposeDetached(dockerComposePath: string, pullPolicy?: PullPolicy): void;
|
|
37
38
|
export declare function stopDockerCompose(dockerComposePath: string): Promise<void>;
|
|
38
39
|
export { isDockerInstalled, isDockerComposeAvailable, isDockerDaemonRunning, DockerValidationError };
|
package/dist/services/docker.js
CHANGED
|
@@ -141,6 +141,18 @@ export async function startDockerCompose(dockerComposePath, pullPolicy) {
|
|
|
141
141
|
waitForHealthy: () => waitForServicesHealthy(dockerComposePath)
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
|
+
export function startDockerComposeDetached(dockerComposePath, pullPolicy) {
|
|
145
|
+
const args = [
|
|
146
|
+
'compose',
|
|
147
|
+
'-f', dockerComposePath,
|
|
148
|
+
'--project-directory', process.cwd(),
|
|
149
|
+
'up', '-d'
|
|
150
|
+
];
|
|
151
|
+
if (pullPolicy) {
|
|
152
|
+
args.push('--pull', pullPolicy);
|
|
153
|
+
}
|
|
154
|
+
execFileSync('docker', args, { stdio: 'inherit', cwd: process.cwd() });
|
|
155
|
+
}
|
|
144
156
|
export async function stopDockerCompose(dockerComposePath) {
|
|
145
157
|
ux.stdout('⏹️ Stopping services...\n');
|
|
146
158
|
execFileSync('docker', ['compose', '-f', dockerComposePath, 'down'], { stdio: 'inherit', cwd: process.cwd() });
|
|
@@ -7,7 +7,7 @@ This is an **Output.ai** project - a framework for building reliable, production
|
|
|
7
7
|
For full framework documentation, commands, and AI-assisted workflow development, install our Claude Code plugins:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
claude plugin marketplace add growthxai/output
|
|
10
|
+
claude plugin marketplace add growthxai/output
|
|
11
11
|
claude plugin install outputai@outputai --scope project
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Token & API Pricing Configuration
|
|
2
|
+
# Prices are per million tokens, in USD
|
|
3
|
+
# Entries here are merged with built-in defaults (project values take precedence)
|
|
4
|
+
# Model names support prefix matching: 'claude-sonnet-4' matches 'claude-sonnet-4-20250514'
|
|
5
|
+
# models:
|
|
6
|
+
# # =============================================================================
|
|
7
|
+
# # Anthropic
|
|
8
|
+
# # =============================================================================
|
|
9
|
+
# claude-haiku-4-5:
|
|
10
|
+
# provider: anthropic
|
|
11
|
+
# input: 1.00
|
|
12
|
+
# output: 5.00
|
|
13
|
+
# cached_input: 0.10
|
|
14
|
+
|
|
15
|
+
# claude-sonnet-4:
|
|
16
|
+
# provider: anthropic
|
|
17
|
+
# input: 3.00
|
|
18
|
+
# output: 15.00
|
|
19
|
+
# cached_input: 0.30
|
|
20
|
+
|
|
21
|
+
# services:
|
|
22
|
+
# # =============================================================================
|
|
23
|
+
# # Jina Reader API - Token-based
|
|
24
|
+
# # =============================================================================
|
|
25
|
+
# jina:
|
|
26
|
+
# type: token
|
|
27
|
+
# url_pattern: "r.jina.ai"
|
|
28
|
+
# usage_path: "body.data.usage.tokens"
|
|
29
|
+
# per_million: 0.045
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outputai/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "CLI for Output.ai workflow generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@anthropic-ai/claude-agent-sdk": "0.1.71",
|
|
18
|
-
"@aws-sdk/client-s3": "3.
|
|
18
|
+
"@aws-sdk/client-s3": "3.1011.0",
|
|
19
19
|
"@hackylabs/deep-redact": "3.0.5",
|
|
20
|
-
"@inquirer/prompts": "8.3.
|
|
21
|
-
"@oclif/core": "4.
|
|
22
|
-
"@oclif/plugin-help": "6.2.
|
|
20
|
+
"@inquirer/prompts": "8.3.2",
|
|
21
|
+
"@oclif/core": "4.9.0",
|
|
22
|
+
"@oclif/plugin-help": "6.2.38",
|
|
23
23
|
"change-case": "5.4.4",
|
|
24
24
|
"cli-progress": "3.12.0",
|
|
25
25
|
"cli-table3": "0.6.5",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
"dotenv": "17.3.1",
|
|
29
29
|
"handlebars": "4.7.8",
|
|
30
30
|
"js-yaml": "4.1.1",
|
|
31
|
-
"json-schema-library": "11.0.
|
|
31
|
+
"json-schema-library": "11.0.5",
|
|
32
32
|
"ky": "1.14.3",
|
|
33
33
|
"log-update": "7.2.0",
|
|
34
34
|
"semver": "7.7.4",
|
|
35
35
|
"yaml": "^2.7.1",
|
|
36
|
-
"@outputai/credentials": "0.1.
|
|
37
|
-
"@outputai/
|
|
38
|
-
"@outputai/
|
|
36
|
+
"@outputai/credentials": "0.1.1",
|
|
37
|
+
"@outputai/llm": "0.1.1",
|
|
38
|
+
"@outputai/evals": "0.1.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/cli-progress": "3.11.6",
|