@outputai/cli 0.1.1 → 0.1.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.
- package/package.json +7 -7
- package/dist/api/generated/api.d.ts +0 -820
- package/dist/api/generated/api.js +0 -226
- package/dist/api/http_client.d.ts +0 -27
- package/dist/api/http_client.js +0 -71
- package/dist/api/orval_post_process.d.ts +0 -11
- package/dist/api/orval_post_process.js +0 -46
- package/dist/api/parser.d.ts +0 -17
- package/dist/api/parser.js +0 -68
- package/dist/assets/config/costs.yml +0 -309
- package/dist/assets/docker/docker-compose-dev.yml +0 -146
- package/dist/commands/credentials/edit.d.ts +0 -10
- package/dist/commands/credentials/edit.js +0 -67
- package/dist/commands/credentials/edit.spec.d.ts +0 -1
- package/dist/commands/credentials/edit.spec.js +0 -73
- package/dist/commands/credentials/get.d.ts +0 -13
- package/dist/commands/credentials/get.js +0 -46
- package/dist/commands/credentials/get.spec.d.ts +0 -1
- package/dist/commands/credentials/get.spec.js +0 -74
- package/dist/commands/credentials/init.d.ts +0 -11
- package/dist/commands/credentials/init.js +0 -45
- package/dist/commands/credentials/init.spec.d.ts +0 -1
- package/dist/commands/credentials/init.spec.js +0 -68
- package/dist/commands/credentials/show.d.ts +0 -10
- package/dist/commands/credentials/show.js +0 -33
- package/dist/commands/credentials/show.spec.d.ts +0 -1
- package/dist/commands/credentials/show.spec.js +0 -57
- package/dist/commands/dev/eject.d.ts +0 -11
- package/dist/commands/dev/eject.js +0 -58
- package/dist/commands/dev/eject.spec.d.ts +0 -1
- package/dist/commands/dev/eject.spec.js +0 -109
- package/dist/commands/dev/index.d.ts +0 -14
- package/dist/commands/dev/index.js +0 -173
- package/dist/commands/dev/index.spec.d.ts +0 -1
- package/dist/commands/dev/index.spec.js +0 -239
- package/dist/commands/init.d.ts +0 -12
- package/dist/commands/init.js +0 -37
- package/dist/commands/init.spec.d.ts +0 -1
- package/dist/commands/init.spec.js +0 -100
- package/dist/commands/update.d.ts +0 -14
- package/dist/commands/update.js +0 -120
- package/dist/commands/update.spec.d.ts +0 -1
- package/dist/commands/update.spec.js +0 -178
- package/dist/commands/workflow/cost.d.ts +0 -16
- package/dist/commands/workflow/cost.js +0 -71
- package/dist/commands/workflow/cost.spec.d.ts +0 -1
- package/dist/commands/workflow/cost.spec.js +0 -47
- package/dist/commands/workflow/dataset/generate.d.ts +0 -22
- package/dist/commands/workflow/dataset/generate.js +0 -143
- package/dist/commands/workflow/dataset/list.d.ts +0 -12
- package/dist/commands/workflow/dataset/list.js +0 -87
- package/dist/commands/workflow/debug.d.ts +0 -16
- package/dist/commands/workflow/debug.js +0 -60
- package/dist/commands/workflow/debug.spec.d.ts +0 -1
- package/dist/commands/workflow/debug.spec.js +0 -34
- package/dist/commands/workflow/generate.d.ts +0 -17
- package/dist/commands/workflow/generate.js +0 -85
- package/dist/commands/workflow/generate.spec.d.ts +0 -1
- package/dist/commands/workflow/generate.spec.js +0 -115
- package/dist/commands/workflow/list.d.ts +0 -22
- package/dist/commands/workflow/list.js +0 -152
- package/dist/commands/workflow/list.spec.d.ts +0 -1
- package/dist/commands/workflow/list.spec.js +0 -99
- package/dist/commands/workflow/plan.d.ts +0 -12
- package/dist/commands/workflow/plan.js +0 -66
- package/dist/commands/workflow/plan.spec.d.ts +0 -1
- package/dist/commands/workflow/plan.spec.js +0 -341
- package/dist/commands/workflow/reset.d.ts +0 -14
- package/dist/commands/workflow/reset.js +0 -51
- package/dist/commands/workflow/result.d.ts +0 -13
- package/dist/commands/workflow/result.js +0 -46
- package/dist/commands/workflow/result.spec.d.ts +0 -1
- package/dist/commands/workflow/result.spec.js +0 -23
- package/dist/commands/workflow/run.d.ts +0 -16
- package/dist/commands/workflow/run.js +0 -97
- package/dist/commands/workflow/run.spec.d.ts +0 -1
- package/dist/commands/workflow/run.spec.js +0 -110
- package/dist/commands/workflow/runs/list.d.ts +0 -14
- package/dist/commands/workflow/runs/list.js +0 -104
- package/dist/commands/workflow/start.d.ts +0 -15
- package/dist/commands/workflow/start.js +0 -62
- package/dist/commands/workflow/start.spec.d.ts +0 -1
- package/dist/commands/workflow/start.spec.js +0 -28
- package/dist/commands/workflow/status.d.ts +0 -13
- package/dist/commands/workflow/status.js +0 -57
- package/dist/commands/workflow/status.spec.d.ts +0 -1
- package/dist/commands/workflow/status.spec.js +0 -33
- package/dist/commands/workflow/stop.d.ts +0 -10
- package/dist/commands/workflow/stop.js +0 -31
- package/dist/commands/workflow/stop.spec.d.ts +0 -1
- package/dist/commands/workflow/stop.spec.js +0 -17
- package/dist/commands/workflow/terminate.d.ts +0 -13
- package/dist/commands/workflow/terminate.js +0 -39
- package/dist/commands/workflow/test_eval.d.ts +0 -20
- package/dist/commands/workflow/test_eval.js +0 -151
- package/dist/config.d.ts +0 -47
- package/dist/config.js +0 -47
- package/dist/generated/framework_version.json +0 -3
- package/dist/hooks/init.d.ts +0 -3
- package/dist/hooks/init.js +0 -30
- package/dist/hooks/init.spec.d.ts +0 -1
- package/dist/hooks/init.spec.js +0 -54
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/index.spec.d.ts +0 -1
- package/dist/index.spec.js +0 -6
- package/dist/services/claude_client.d.ts +0 -30
- package/dist/services/claude_client.integration.test.d.ts +0 -1
- package/dist/services/claude_client.integration.test.js +0 -43
- package/dist/services/claude_client.js +0 -215
- package/dist/services/claude_client.spec.d.ts +0 -1
- package/dist/services/claude_client.spec.js +0 -145
- package/dist/services/coding_agents.d.ts +0 -36
- package/dist/services/coding_agents.js +0 -236
- package/dist/services/coding_agents.spec.d.ts +0 -1
- package/dist/services/coding_agents.spec.js +0 -256
- package/dist/services/copy_assets.spec.d.ts +0 -1
- package/dist/services/copy_assets.spec.js +0 -22
- package/dist/services/cost_calculator.d.ts +0 -18
- package/dist/services/cost_calculator.js +0 -359
- package/dist/services/cost_calculator.spec.d.ts +0 -1
- package/dist/services/cost_calculator.spec.js +0 -540
- package/dist/services/credentials_service.d.ts +0 -12
- package/dist/services/credentials_service.integration.test.d.ts +0 -1
- package/dist/services/credentials_service.integration.test.js +0 -66
- package/dist/services/credentials_service.js +0 -64
- package/dist/services/credentials_service.spec.d.ts +0 -1
- package/dist/services/credentials_service.spec.js +0 -106
- package/dist/services/datasets.d.ts +0 -20
- package/dist/services/datasets.js +0 -132
- package/dist/services/docker.d.ts +0 -39
- package/dist/services/docker.js +0 -160
- package/dist/services/docker.spec.d.ts +0 -1
- package/dist/services/docker.spec.js +0 -124
- package/dist/services/env_configurator.d.ts +0 -15
- package/dist/services/env_configurator.js +0 -163
- package/dist/services/env_configurator.spec.d.ts +0 -1
- package/dist/services/env_configurator.spec.js +0 -192
- package/dist/services/generate_plan_name@v1.prompt +0 -24
- package/dist/services/messages.d.ts +0 -9
- package/dist/services/messages.js +0 -338
- package/dist/services/messages.spec.d.ts +0 -1
- package/dist/services/messages.spec.js +0 -55
- package/dist/services/npm_update_service.d.ts +0 -6
- package/dist/services/npm_update_service.js +0 -87
- package/dist/services/npm_update_service.spec.d.ts +0 -1
- package/dist/services/npm_update_service.spec.js +0 -104
- package/dist/services/project_scaffold.d.ts +0 -31
- package/dist/services/project_scaffold.js +0 -212
- package/dist/services/project_scaffold.spec.d.ts +0 -1
- package/dist/services/project_scaffold.spec.js +0 -122
- package/dist/services/s3_trace_downloader.d.ts +0 -12
- package/dist/services/s3_trace_downloader.js +0 -57
- package/dist/services/template_processor.d.ts +0 -14
- package/dist/services/template_processor.js +0 -57
- package/dist/services/trace_reader.d.ts +0 -16
- package/dist/services/trace_reader.js +0 -57
- package/dist/services/trace_reader.spec.d.ts +0 -1
- package/dist/services/trace_reader.spec.js +0 -78
- package/dist/services/version_check.d.ts +0 -6
- package/dist/services/version_check.js +0 -52
- package/dist/services/version_check.spec.d.ts +0 -1
- package/dist/services/version_check.spec.js +0 -106
- package/dist/services/workflow_builder.d.ts +0 -16
- package/dist/services/workflow_builder.js +0 -86
- package/dist/services/workflow_builder.spec.d.ts +0 -1
- package/dist/services/workflow_builder.spec.js +0 -165
- package/dist/services/workflow_generator.d.ts +0 -5
- package/dist/services/workflow_generator.js +0 -40
- package/dist/services/workflow_generator.spec.d.ts +0 -1
- package/dist/services/workflow_generator.spec.js +0 -77
- package/dist/services/workflow_planner.d.ts +0 -15
- package/dist/services/workflow_planner.js +0 -48
- package/dist/services/workflow_planner.spec.d.ts +0 -1
- package/dist/services/workflow_planner.spec.js +0 -122
- package/dist/services/workflow_runs.d.ts +0 -14
- package/dist/services/workflow_runs.js +0 -25
- package/dist/templates/agent_instructions/CLAUDE.md.template +0 -19
- package/dist/templates/agent_instructions/dotclaude/settings.json.template +0 -29
- package/dist/templates/project/.env.example.template +0 -9
- package/dist/templates/project/.gitignore.template +0 -35
- package/dist/templates/project/README.md.template +0 -100
- package/dist/templates/project/config/costs.yml.template +0 -29
- package/dist/templates/project/package.json.template +0 -25
- package/dist/templates/project/src/clients/jina.ts.template +0 -30
- package/dist/templates/project/src/shared/utils/string.ts.template +0 -3
- package/dist/templates/project/src/shared/utils/url.ts.template +0 -15
- package/dist/templates/project/src/workflows/blog_evaluator/evaluators.ts.template +0 -23
- package/dist/templates/project/src/workflows/blog_evaluator/prompts/signal_noise@v1.prompt.template +0 -26
- package/dist/templates/project/src/workflows/blog_evaluator/scenarios/paulgraham_hwh.json.template +0 -3
- package/dist/templates/project/src/workflows/blog_evaluator/steps.ts.template +0 -27
- package/dist/templates/project/src/workflows/blog_evaluator/types.ts.template +0 -30
- package/dist/templates/project/src/workflows/blog_evaluator/utils.ts.template +0 -15
- package/dist/templates/project/src/workflows/blog_evaluator/workflow.ts.template +0 -27
- package/dist/templates/project/tsconfig.json.template +0 -20
- package/dist/templates/workflow/README.md.template +0 -216
- package/dist/templates/workflow/evaluators.ts.template +0 -21
- package/dist/templates/workflow/prompts/example@v1.prompt.template +0 -15
- package/dist/templates/workflow/scenarios/test_input.json.template +0 -3
- package/dist/templates/workflow/steps.ts.template +0 -20
- package/dist/templates/workflow/types.ts.template +0 -13
- package/dist/templates/workflow/workflow.ts.template +0 -23
- package/dist/test_helpers/mocks.d.ts +0 -38
- package/dist/test_helpers/mocks.js +0 -77
- package/dist/types/cost.d.ts +0 -149
- package/dist/types/cost.js +0 -6
- package/dist/types/domain.d.ts +0 -20
- package/dist/types/domain.js +0 -4
- package/dist/types/errors.d.ts +0 -68
- package/dist/types/errors.js +0 -100
- package/dist/types/errors.spec.d.ts +0 -1
- package/dist/types/errors.spec.js +0 -18
- package/dist/types/generator.d.ts +0 -26
- package/dist/types/generator.js +0 -1
- package/dist/types/trace.d.ts +0 -161
- package/dist/types/trace.js +0 -18
- package/dist/utils/claude.d.ts +0 -5
- package/dist/utils/claude.js +0 -19
- package/dist/utils/claude.spec.d.ts +0 -1
- package/dist/utils/claude.spec.js +0 -119
- package/dist/utils/constants.d.ts +0 -5
- package/dist/utils/constants.js +0 -4
- package/dist/utils/cost_formatter.d.ts +0 -5
- package/dist/utils/cost_formatter.js +0 -218
- package/dist/utils/date_formatter.d.ts +0 -23
- package/dist/utils/date_formatter.js +0 -49
- package/dist/utils/env_loader.d.ts +0 -1
- package/dist/utils/env_loader.js +0 -22
- package/dist/utils/env_loader.spec.d.ts +0 -1
- package/dist/utils/env_loader.spec.js +0 -43
- package/dist/utils/error_handler.d.ts +0 -8
- package/dist/utils/error_handler.js +0 -71
- package/dist/utils/error_utils.d.ts +0 -24
- package/dist/utils/error_utils.js +0 -87
- package/dist/utils/file_system.d.ts +0 -3
- package/dist/utils/file_system.js +0 -33
- package/dist/utils/format_workflow_result.d.ts +0 -5
- package/dist/utils/format_workflow_result.js +0 -18
- package/dist/utils/format_workflow_result.spec.d.ts +0 -1
- package/dist/utils/format_workflow_result.spec.js +0 -81
- package/dist/utils/framework_version.d.ts +0 -4
- package/dist/utils/framework_version.js +0 -4
- package/dist/utils/framework_version.spec.d.ts +0 -1
- package/dist/utils/framework_version.spec.js +0 -13
- package/dist/utils/header_utils.d.ts +0 -12
- package/dist/utils/header_utils.js +0 -29
- package/dist/utils/header_utils.spec.d.ts +0 -1
- package/dist/utils/header_utils.spec.js +0 -52
- package/dist/utils/input_parser.d.ts +0 -1
- package/dist/utils/input_parser.js +0 -19
- package/dist/utils/output_formatter.d.ts +0 -2
- package/dist/utils/output_formatter.js +0 -11
- package/dist/utils/paths.d.ts +0 -25
- package/dist/utils/paths.js +0 -36
- package/dist/utils/process.d.ts +0 -4
- package/dist/utils/process.js +0 -50
- package/dist/utils/resolve_input.d.ts +0 -1
- package/dist/utils/resolve_input.js +0 -22
- package/dist/utils/scenario_resolver.d.ts +0 -9
- package/dist/utils/scenario_resolver.js +0 -93
- package/dist/utils/scenario_resolver.spec.d.ts +0 -1
- package/dist/utils/scenario_resolver.spec.js +0 -214
- package/dist/utils/secret_sanitizer.d.ts +0 -1
- package/dist/utils/secret_sanitizer.js +0 -29
- package/dist/utils/sleep.d.ts +0 -5
- package/dist/utils/sleep.js +0 -5
- package/dist/utils/template.d.ts +0 -9
- package/dist/utils/template.js +0 -30
- package/dist/utils/template.spec.d.ts +0 -1
- package/dist/utils/template.spec.js +0 -77
- package/dist/utils/trace_extractor.d.ts +0 -27
- package/dist/utils/trace_extractor.js +0 -53
- package/dist/utils/trace_formatter.d.ts +0 -11
- package/dist/utils/trace_formatter.js +0 -402
- package/dist/utils/validation.d.ts +0 -13
- package/dist/utils/validation.js +0 -25
- package/dist/utils/validation.spec.d.ts +0 -1
- package/dist/utils/validation.spec.js +0 -140
package/dist/commands/update.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import { confirm } from '@inquirer/prompts';
|
|
3
|
-
import { fetchLatestVersion, getGlobalInstalledVersion, getLocalInstalledVersion, updateGlobal, updateLocal, isOutdated } from '#services/npm_update_service.js';
|
|
4
|
-
import { ensureClaudePlugin } from '#services/coding_agents.js';
|
|
5
|
-
import { getErrorMessage } from '#utils/error_utils.js';
|
|
6
|
-
export default class Update extends Command {
|
|
7
|
-
static description = 'Update Output CLI and agent configuration';
|
|
8
|
-
static examples = [
|
|
9
|
-
'<%= config.bin %> update',
|
|
10
|
-
'<%= config.bin %> update --cli',
|
|
11
|
-
'<%= config.bin %> update --agents'
|
|
12
|
-
];
|
|
13
|
-
static flags = {
|
|
14
|
-
cli: Flags.boolean({
|
|
15
|
-
description: 'Update CLI packages only'
|
|
16
|
-
}),
|
|
17
|
-
agents: Flags.boolean({
|
|
18
|
-
description: 'Update Claude Code agent configuration'
|
|
19
|
-
})
|
|
20
|
-
};
|
|
21
|
-
async run() {
|
|
22
|
-
const { flags } = await this.parse(Update);
|
|
23
|
-
const updateAll = !flags.cli && !flags.agents;
|
|
24
|
-
if (updateAll || flags.cli) {
|
|
25
|
-
await this.updateCli();
|
|
26
|
-
}
|
|
27
|
-
if (updateAll || flags.agents) {
|
|
28
|
-
await this.updateAgents();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async updateCli() {
|
|
32
|
-
const latest = await fetchLatestVersion();
|
|
33
|
-
if (!latest) {
|
|
34
|
-
this.error('Could not fetch the latest version from npm. Check your network connection.');
|
|
35
|
-
}
|
|
36
|
-
this.log(`\nLatest @outputai/cli version: v${latest}\n`);
|
|
37
|
-
await this.handleGlobalUpdate(latest);
|
|
38
|
-
await this.handleLocalUpdate(latest);
|
|
39
|
-
}
|
|
40
|
-
async updateAgents() {
|
|
41
|
-
this.log('\nUpdating Claude Code agent configuration...');
|
|
42
|
-
try {
|
|
43
|
-
await ensureClaudePlugin(process.cwd());
|
|
44
|
-
this.log('Claude Code agent configuration updated successfully.');
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
this.warn(`Failed to update agent configuration: ${getErrorMessage(error)}`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
async handleGlobalUpdate(latest) {
|
|
51
|
-
const globalVersion = await getGlobalInstalledVersion();
|
|
52
|
-
if (!globalVersion) {
|
|
53
|
-
this.log('Global install: not found');
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
if (!isOutdated(globalVersion, latest)) {
|
|
57
|
-
this.log(`Global install: v${globalVersion} (up to date)`);
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
this.log(`Global install: v${globalVersion} (outdated)`);
|
|
61
|
-
const shouldUpdate = await confirm({
|
|
62
|
-
message: `Update global install from v${globalVersion} to v${latest}?`
|
|
63
|
-
});
|
|
64
|
-
if (!shouldUpdate) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
await updateGlobal();
|
|
69
|
-
const newVersion = await getGlobalInstalledVersion();
|
|
70
|
-
if (newVersion) {
|
|
71
|
-
this.log(`\nGlobal install updated to v${newVersion}`);
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
this.log('\nGlobal update completed (could not verify new version)');
|
|
75
|
-
}
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
this.warn(`Failed to update global install: ${getErrorMessage(error)}`);
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
async handleLocalUpdate(latest) {
|
|
84
|
-
const cwd = process.cwd();
|
|
85
|
-
const localVersion = await getLocalInstalledVersion(cwd);
|
|
86
|
-
if (!localVersion) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
if (!isOutdated(localVersion, latest)) {
|
|
90
|
-
this.log(`\nLocal install: v${localVersion} (up to date)`);
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
this.log(`\nLocal install: v${localVersion} (outdated)`);
|
|
94
|
-
const shouldUpdate = await confirm({
|
|
95
|
-
message: `Update local install from v${localVersion} to v${latest}?`
|
|
96
|
-
});
|
|
97
|
-
if (!shouldUpdate) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
await updateLocal(cwd);
|
|
102
|
-
const newLocalVersion = await getLocalInstalledVersion(cwd);
|
|
103
|
-
if (newLocalVersion) {
|
|
104
|
-
this.log(`\nLocal install updated to v${newLocalVersion}`);
|
|
105
|
-
if (isOutdated(newLocalVersion, latest)) {
|
|
106
|
-
this.warn(`Your package.json constrains @outputai/output which limits @outputai/cli to v${newLocalVersion}. ` +
|
|
107
|
-
'Update the @outputai/output version range in package.json to get the latest CLI.');
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
this.log('\nLocal update completed (could not verify new version)');
|
|
112
|
-
}
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
this.warn(`Failed to update local install: ${getErrorMessage(error)}`);
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
3
|
-
import Update from './update.js';
|
|
4
|
-
import { fetchLatestVersion, getGlobalInstalledVersion, getLocalInstalledVersion, updateGlobal, updateLocal, isOutdated } from '#services/npm_update_service.js';
|
|
5
|
-
import { ensureClaudePlugin } from '#services/coding_agents.js';
|
|
6
|
-
import { confirm } from '@inquirer/prompts';
|
|
7
|
-
vi.mock('#services/npm_update_service.js', () => ({
|
|
8
|
-
fetchLatestVersion: vi.fn(),
|
|
9
|
-
getGlobalInstalledVersion: vi.fn(),
|
|
10
|
-
getLocalInstalledVersion: vi.fn(),
|
|
11
|
-
updateGlobal: vi.fn(),
|
|
12
|
-
updateLocal: vi.fn(),
|
|
13
|
-
isOutdated: vi.fn()
|
|
14
|
-
}));
|
|
15
|
-
vi.mock('#services/coding_agents.js', () => ({
|
|
16
|
-
ensureClaudePlugin: vi.fn()
|
|
17
|
-
}));
|
|
18
|
-
vi.mock('@inquirer/prompts', () => ({
|
|
19
|
-
confirm: vi.fn()
|
|
20
|
-
}));
|
|
21
|
-
describe('update command', () => {
|
|
22
|
-
const createTestCommand = (flags = {}) => {
|
|
23
|
-
const cmd = new Update([], {});
|
|
24
|
-
cmd.log = vi.fn();
|
|
25
|
-
cmd.warn = vi.fn();
|
|
26
|
-
cmd.error = vi.fn();
|
|
27
|
-
cmd.debug = vi.fn();
|
|
28
|
-
cmd.parse = vi.fn().mockResolvedValue({ flags, args: {} });
|
|
29
|
-
return cmd;
|
|
30
|
-
};
|
|
31
|
-
beforeEach(() => {
|
|
32
|
-
vi.clearAllMocks();
|
|
33
|
-
vi.mocked(fetchLatestVersion).mockResolvedValue('1.0.0');
|
|
34
|
-
vi.mocked(getGlobalInstalledVersion).mockResolvedValue('0.8.4');
|
|
35
|
-
vi.mocked(getLocalInstalledVersion).mockResolvedValue(null);
|
|
36
|
-
vi.mocked(isOutdated).mockReturnValue(true);
|
|
37
|
-
vi.mocked(confirm).mockResolvedValue(true);
|
|
38
|
-
vi.mocked(updateGlobal).mockResolvedValue();
|
|
39
|
-
vi.mocked(updateLocal).mockResolvedValue();
|
|
40
|
-
vi.mocked(ensureClaudePlugin).mockResolvedValue();
|
|
41
|
-
});
|
|
42
|
-
describe('command structure', () => {
|
|
43
|
-
it('should have correct description', () => {
|
|
44
|
-
expect(Update.description).toContain('Update Output CLI');
|
|
45
|
-
});
|
|
46
|
-
it('should have cli and agents flags', () => {
|
|
47
|
-
expect(Update.flags).toHaveProperty('cli');
|
|
48
|
-
expect(Update.flags).toHaveProperty('agents');
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
describe('no flags (update all)', () => {
|
|
52
|
-
it('should update cli and agents when no flags provided', async () => {
|
|
53
|
-
vi.mocked(getGlobalInstalledVersion)
|
|
54
|
-
.mockResolvedValueOnce('0.8.4')
|
|
55
|
-
.mockResolvedValueOnce('1.0.0');
|
|
56
|
-
const cmd = createTestCommand();
|
|
57
|
-
await cmd.run();
|
|
58
|
-
expect(fetchLatestVersion).toHaveBeenCalled();
|
|
59
|
-
expect(ensureClaudePlugin).toHaveBeenCalledTimes(1);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe('--cli flag', () => {
|
|
63
|
-
it('should only update cli when --cli flag is set', async () => {
|
|
64
|
-
vi.mocked(getGlobalInstalledVersion)
|
|
65
|
-
.mockResolvedValueOnce('0.8.4')
|
|
66
|
-
.mockResolvedValueOnce('1.0.0');
|
|
67
|
-
const cmd = createTestCommand({ cli: true });
|
|
68
|
-
await cmd.run();
|
|
69
|
-
expect(fetchLatestVersion).toHaveBeenCalled();
|
|
70
|
-
expect(ensureClaudePlugin).not.toHaveBeenCalled();
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
describe('--agents flag', () => {
|
|
74
|
-
it('should only update agents when --agents flag is set', async () => {
|
|
75
|
-
const cmd = createTestCommand({ agents: true });
|
|
76
|
-
await cmd.run();
|
|
77
|
-
expect(fetchLatestVersion).not.toHaveBeenCalled();
|
|
78
|
-
expect(ensureClaudePlugin).toHaveBeenCalledTimes(1);
|
|
79
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('agent configuration updated'));
|
|
80
|
-
});
|
|
81
|
-
it('should warn on agent update failure', async () => {
|
|
82
|
-
vi.mocked(ensureClaudePlugin).mockRejectedValue(new Error('agent error'));
|
|
83
|
-
const cmd = createTestCommand({ agents: true });
|
|
84
|
-
await cmd.run();
|
|
85
|
-
expect(cmd.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to update agent'));
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe('fetch failure', () => {
|
|
89
|
-
it('should error when cannot fetch latest version', async () => {
|
|
90
|
-
vi.mocked(fetchLatestVersion).mockResolvedValue(null);
|
|
91
|
-
const cmd = createTestCommand({ cli: true });
|
|
92
|
-
await cmd.run();
|
|
93
|
-
expect(cmd.error).toHaveBeenCalledWith(expect.stringContaining('Could not fetch'));
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
describe('global update', () => {
|
|
97
|
-
it('should prompt and update global install when outdated', async () => {
|
|
98
|
-
vi.mocked(getGlobalInstalledVersion)
|
|
99
|
-
.mockResolvedValueOnce('0.8.4')
|
|
100
|
-
.mockResolvedValueOnce('1.0.0');
|
|
101
|
-
const cmd = createTestCommand({ cli: true });
|
|
102
|
-
await cmd.run();
|
|
103
|
-
expect(confirm).toHaveBeenCalledWith(expect.objectContaining({ message: expect.stringContaining('v0.8.4') }));
|
|
104
|
-
expect(updateGlobal).toHaveBeenCalled();
|
|
105
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('v1.0.0'));
|
|
106
|
-
});
|
|
107
|
-
it('should skip global update when user declines', async () => {
|
|
108
|
-
vi.mocked(confirm).mockResolvedValue(false);
|
|
109
|
-
const cmd = createTestCommand({ cli: true });
|
|
110
|
-
await cmd.run();
|
|
111
|
-
expect(updateGlobal).not.toHaveBeenCalled();
|
|
112
|
-
});
|
|
113
|
-
it('should show up-to-date when global is current', async () => {
|
|
114
|
-
vi.mocked(isOutdated).mockReturnValue(false);
|
|
115
|
-
const cmd = createTestCommand({ cli: true });
|
|
116
|
-
await cmd.run();
|
|
117
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('up to date'));
|
|
118
|
-
expect(updateGlobal).not.toHaveBeenCalled();
|
|
119
|
-
});
|
|
120
|
-
it('should show not found when global is not installed', async () => {
|
|
121
|
-
vi.mocked(getGlobalInstalledVersion).mockResolvedValue(null);
|
|
122
|
-
const cmd = createTestCommand({ cli: true });
|
|
123
|
-
await cmd.run();
|
|
124
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('not found'));
|
|
125
|
-
});
|
|
126
|
-
it('should handle null version after global update', async () => {
|
|
127
|
-
vi.mocked(getGlobalInstalledVersion)
|
|
128
|
-
.mockResolvedValueOnce('0.8.4')
|
|
129
|
-
.mockResolvedValueOnce(null);
|
|
130
|
-
const cmd = createTestCommand({ cli: true });
|
|
131
|
-
await cmd.run();
|
|
132
|
-
expect(updateGlobal).toHaveBeenCalled();
|
|
133
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('could not verify'));
|
|
134
|
-
});
|
|
135
|
-
it('should warn on global update failure', async () => {
|
|
136
|
-
vi.mocked(updateGlobal).mockRejectedValue(new Error('permission denied'));
|
|
137
|
-
const cmd = createTestCommand({ cli: true });
|
|
138
|
-
await cmd.run();
|
|
139
|
-
expect(cmd.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to update global'));
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
describe('local update', () => {
|
|
143
|
-
it('should prompt and update local install when outdated', async () => {
|
|
144
|
-
vi.mocked(getLocalInstalledVersion)
|
|
145
|
-
.mockResolvedValueOnce('0.8.3')
|
|
146
|
-
.mockResolvedValueOnce('1.0.0');
|
|
147
|
-
vi.mocked(isOutdated)
|
|
148
|
-
.mockReturnValueOnce(true)
|
|
149
|
-
.mockReturnValueOnce(true)
|
|
150
|
-
.mockReturnValueOnce(false);
|
|
151
|
-
const cmd = createTestCommand({ cli: true });
|
|
152
|
-
await cmd.run();
|
|
153
|
-
expect(updateLocal).toHaveBeenCalled();
|
|
154
|
-
});
|
|
155
|
-
it('should handle null version after local update', async () => {
|
|
156
|
-
vi.mocked(getGlobalInstalledVersion).mockResolvedValue(null);
|
|
157
|
-
vi.mocked(getLocalInstalledVersion)
|
|
158
|
-
.mockResolvedValueOnce('0.8.3')
|
|
159
|
-
.mockResolvedValueOnce(null);
|
|
160
|
-
const cmd = createTestCommand({ cli: true });
|
|
161
|
-
await cmd.run();
|
|
162
|
-
expect(updateLocal).toHaveBeenCalled();
|
|
163
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('could not verify'));
|
|
164
|
-
});
|
|
165
|
-
it('should warn about package.json constraint when post-update version < latest', async () => {
|
|
166
|
-
vi.mocked(getLocalInstalledVersion)
|
|
167
|
-
.mockResolvedValueOnce('0.8.3')
|
|
168
|
-
.mockResolvedValueOnce('0.8.5');
|
|
169
|
-
vi.mocked(isOutdated)
|
|
170
|
-
.mockReturnValueOnce(true)
|
|
171
|
-
.mockReturnValueOnce(true)
|
|
172
|
-
.mockReturnValueOnce(true);
|
|
173
|
-
const cmd = createTestCommand({ cli: true });
|
|
174
|
-
await cmd.run();
|
|
175
|
-
expect(cmd.warn).toHaveBeenCalledWith(expect.stringContaining('package.json constrains'));
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class WorkflowCost 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
|
-
tracePath: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
-
};
|
|
9
|
-
static flags: {
|
|
10
|
-
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
-
};
|
|
13
|
-
run(): Promise<void>;
|
|
14
|
-
private loadLocalTrace;
|
|
15
|
-
catch(error: Error): Promise<void>;
|
|
16
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
import { readFile } from 'node:fs/promises';
|
|
3
|
-
import { calculateCost, loadPricingConfig } from '#services/cost_calculator.js';
|
|
4
|
-
import { getTrace } from '#services/trace_reader.js';
|
|
5
|
-
import { OUTPUT_FORMAT } from '#utils/constants.js';
|
|
6
|
-
import { formatCostReport } from '#utils/cost_formatter.js';
|
|
7
|
-
import { getErrorCode } from '#utils/error_utils.js';
|
|
8
|
-
import { handleApiError } from '#utils/error_handler.js';
|
|
9
|
-
import { formatOutput } from '#utils/output_formatter.js';
|
|
10
|
-
export default class WorkflowCost extends Command {
|
|
11
|
-
static description = 'Calculate the cost of a workflow execution';
|
|
12
|
-
static examples = [
|
|
13
|
-
'<%= config.bin %> <%= command.id %> my_workflow',
|
|
14
|
-
'<%= config.bin %> <%= command.id %> my_workflow --verbose',
|
|
15
|
-
'<%= config.bin %> <%= command.id %> my_workflow path/to/trace.json',
|
|
16
|
-
'<%= config.bin %> <%= command.id %> my_workflow --format json'
|
|
17
|
-
];
|
|
18
|
-
static args = {
|
|
19
|
-
workflowId: Args.string({
|
|
20
|
-
description: 'Workflow ID to calculate cost for',
|
|
21
|
-
required: true
|
|
22
|
-
}),
|
|
23
|
-
tracePath: Args.string({
|
|
24
|
-
description: 'Path to a trace JSON file (optional, fetches latest trace if omitted)',
|
|
25
|
-
required: false
|
|
26
|
-
})
|
|
27
|
-
};
|
|
28
|
-
static flags = {
|
|
29
|
-
format: Flags.string({
|
|
30
|
-
char: 'f',
|
|
31
|
-
description: 'Output format',
|
|
32
|
-
options: [OUTPUT_FORMAT.JSON, OUTPUT_FORMAT.TEXT],
|
|
33
|
-
default: OUTPUT_FORMAT.TEXT
|
|
34
|
-
}),
|
|
35
|
-
verbose: Flags.boolean({
|
|
36
|
-
description: 'Show detailed per-call breakdown',
|
|
37
|
-
default: false
|
|
38
|
-
})
|
|
39
|
-
};
|
|
40
|
-
async run() {
|
|
41
|
-
const { args, flags } = await this.parse(WorkflowCost);
|
|
42
|
-
const { traceData, traceFile } = args.tracePath ?
|
|
43
|
-
await this.loadLocalTrace(args.tracePath) :
|
|
44
|
-
{ traceData: (await getTrace(args.workflowId)).data, traceFile: undefined };
|
|
45
|
-
const config = loadPricingConfig();
|
|
46
|
-
const traceNode = traceData;
|
|
47
|
-
const report = calculateCost(traceNode, config, traceFile);
|
|
48
|
-
const formatted = formatOutput(report, flags.format, r => formatCostReport(r, { verbose: flags.verbose }));
|
|
49
|
-
this.log(formatted);
|
|
50
|
-
}
|
|
51
|
-
async loadLocalTrace(tracePath) {
|
|
52
|
-
try {
|
|
53
|
-
const content = await readFile(tracePath, 'utf-8');
|
|
54
|
-
return { traceData: JSON.parse(content), traceFile: tracePath };
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
if (getErrorCode(error) === 'ENOENT') {
|
|
58
|
-
this.error(`Trace file not found: ${tracePath}`, { exit: 1 });
|
|
59
|
-
}
|
|
60
|
-
if (error instanceof SyntaxError) {
|
|
61
|
-
this.error(`Invalid JSON in trace file: ${tracePath}`, { exit: 1 });
|
|
62
|
-
}
|
|
63
|
-
throw error;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
async catch(error) {
|
|
67
|
-
return handleApiError(error, (...args) => this.error(...args), {
|
|
68
|
-
404: 'Workflow not found. Check the workflow ID and try again.'
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
// Mock the services and utilities
|
|
3
|
-
vi.mock('../../services/trace_reader.js', () => ({
|
|
4
|
-
getTrace: vi.fn()
|
|
5
|
-
}));
|
|
6
|
-
vi.mock('../../services/cost_calculator.js', () => ({
|
|
7
|
-
calculateCost: vi.fn(),
|
|
8
|
-
loadPricingConfig: vi.fn()
|
|
9
|
-
}));
|
|
10
|
-
vi.mock('../../utils/cost_formatter.js', () => ({
|
|
11
|
-
formatCostReport: vi.fn()
|
|
12
|
-
}));
|
|
13
|
-
describe('workflow cost command', () => {
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
vi.clearAllMocks();
|
|
16
|
-
});
|
|
17
|
-
describe('command definition', () => {
|
|
18
|
-
it('should export a valid OCLIF command', async () => {
|
|
19
|
-
const WorkflowCost = (await import('./cost.js')).default;
|
|
20
|
-
expect(WorkflowCost).toBeDefined();
|
|
21
|
-
expect(WorkflowCost.description).toBeDefined();
|
|
22
|
-
expect(WorkflowCost.args).toHaveProperty('workflowId');
|
|
23
|
-
expect(WorkflowCost.flags).toHaveProperty('format');
|
|
24
|
-
expect(WorkflowCost.flags).toHaveProperty('verbose');
|
|
25
|
-
});
|
|
26
|
-
it('should have workflowId as required arg', async () => {
|
|
27
|
-
const WorkflowCost = (await import('./cost.js')).default;
|
|
28
|
-
expect(WorkflowCost.args.workflowId.required).toBe(true);
|
|
29
|
-
});
|
|
30
|
-
it('should have tracePath as optional arg', async () => {
|
|
31
|
-
const WorkflowCost = (await import('./cost.js')).default;
|
|
32
|
-
expect(WorkflowCost.args).toHaveProperty('tracePath');
|
|
33
|
-
expect(WorkflowCost.args.tracePath.required).toBeFalsy();
|
|
34
|
-
});
|
|
35
|
-
it('should have correct flag configuration', async () => {
|
|
36
|
-
const WorkflowCost = (await import('./cost.js')).default;
|
|
37
|
-
expect(WorkflowCost.flags.format.options).toEqual(['json', 'text']);
|
|
38
|
-
expect(WorkflowCost.flags.format.default).toBe('text');
|
|
39
|
-
expect(WorkflowCost.flags.verbose.default).toBe(false);
|
|
40
|
-
});
|
|
41
|
-
it('should have correct examples', async () => {
|
|
42
|
-
const WorkflowCost = (await import('./cost.js')).default;
|
|
43
|
-
expect(WorkflowCost.examples).toBeDefined();
|
|
44
|
-
expect(WorkflowCost.examples.length).toBeGreaterThan(0);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class DatasetGenerate extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
workflowName: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
-
scenario: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
8
|
-
};
|
|
9
|
-
static flags: {
|
|
10
|
-
trace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
-
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
-
download: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
-
limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
-
input: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
-
};
|
|
16
|
-
run(): Promise<void>;
|
|
17
|
-
private generateFromScenario;
|
|
18
|
-
private generateFromTrace;
|
|
19
|
-
private generateFromS3;
|
|
20
|
-
private resolveScenarioInput;
|
|
21
|
-
catch(error: Error): Promise<void>;
|
|
22
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { Args, Command, Flags, ux } from '@oclif/core';
|
|
4
|
-
import { postWorkflowRun } from '#api/generated/api.js';
|
|
5
|
-
import { writeDataset, resolveDefaultDatasetsDir, buildDataset, getExecutionTime, extractDatasetName } from '#services/datasets.js';
|
|
6
|
-
import { listRemoteTraces, downloadRemoteTrace } from '#services/s3_trace_downloader.js';
|
|
7
|
-
import { extractDatasetFromTrace } from '#utils/trace_extractor.js';
|
|
8
|
-
import { resolveScenarioPath, getScenarioNotFoundMessage } from '#utils/scenario_resolver.js';
|
|
9
|
-
import { parseInputFlag } from '#utils/input_parser.js';
|
|
10
|
-
import { handleApiError } from '#utils/error_handler.js';
|
|
11
|
-
export default class DatasetGenerate extends Command {
|
|
12
|
-
static description = 'Generate a dataset for a workflow from a scenario, trace file, or S3';
|
|
13
|
-
static examples = [
|
|
14
|
-
'<%= config.bin %> <%= command.id %> simple basic_input',
|
|
15
|
-
'<%= config.bin %> <%= command.id %> simple --trace logs/runs/simple/trace.json --name edge_case',
|
|
16
|
-
'<%= config.bin %> <%= command.id %> simple --download --limit 5'
|
|
17
|
-
];
|
|
18
|
-
static args = {
|
|
19
|
-
workflowName: Args.string({
|
|
20
|
-
description: 'Name of the workflow',
|
|
21
|
-
required: true
|
|
22
|
-
}),
|
|
23
|
-
scenario: Args.string({
|
|
24
|
-
description: 'Scenario name (resolved from the workflow\'s scenarios/ directory)',
|
|
25
|
-
required: false
|
|
26
|
-
})
|
|
27
|
-
};
|
|
28
|
-
static flags = {
|
|
29
|
-
trace: Flags.string({
|
|
30
|
-
char: 't',
|
|
31
|
-
description: 'Path to a local trace file to extract dataset from',
|
|
32
|
-
exclusive: ['download']
|
|
33
|
-
}),
|
|
34
|
-
name: Flags.string({
|
|
35
|
-
char: 'n',
|
|
36
|
-
description: 'Dataset name (defaults to scenario name or trace filename)'
|
|
37
|
-
}),
|
|
38
|
-
download: Flags.boolean({
|
|
39
|
-
char: 'd',
|
|
40
|
-
description: 'Download traces from S3 and create datasets',
|
|
41
|
-
default: false,
|
|
42
|
-
exclusive: ['trace']
|
|
43
|
-
}),
|
|
44
|
-
limit: Flags.integer({
|
|
45
|
-
char: 'l',
|
|
46
|
-
description: 'Maximum number of traces to download from S3',
|
|
47
|
-
default: 5
|
|
48
|
-
}),
|
|
49
|
-
input: Flags.string({
|
|
50
|
-
char: 'i',
|
|
51
|
-
description: 'Workflow input as JSON string or file path (overrides scenario)'
|
|
52
|
-
})
|
|
53
|
-
};
|
|
54
|
-
async run() {
|
|
55
|
-
const { args, flags } = await this.parse(DatasetGenerate);
|
|
56
|
-
if (flags.download) {
|
|
57
|
-
await this.generateFromS3(args.workflowName, flags.limit);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (flags.trace) {
|
|
61
|
-
await this.generateFromTrace(args.workflowName, flags.trace, flags.name);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
await this.generateFromScenario(args.workflowName, args.scenario, flags.input, flags.name);
|
|
65
|
-
}
|
|
66
|
-
async generateFromScenario(workflowName, scenario, inputFlag, nameOverride) {
|
|
67
|
-
const resolvedInput = await this.resolveScenarioInput(workflowName, scenario, inputFlag);
|
|
68
|
-
const datasetName = nameOverride ?? scenario ?? 'dataset';
|
|
69
|
-
this.log(`Running workflow "${workflowName}"...`);
|
|
70
|
-
const response = await postWorkflowRun({
|
|
71
|
-
workflowName,
|
|
72
|
-
input: resolvedInput
|
|
73
|
-
}, {
|
|
74
|
-
config: { timeout: 600000 }
|
|
75
|
-
});
|
|
76
|
-
if (!response?.data) {
|
|
77
|
-
this.error('API returned invalid response', { exit: 1 });
|
|
78
|
-
}
|
|
79
|
-
const { workflowId, output } = response.data;
|
|
80
|
-
const executionTimeMs = await getExecutionTime(workflowId);
|
|
81
|
-
const dataset = buildDataset(datasetName, resolvedInput, output, executionTimeMs);
|
|
82
|
-
const dir = resolveDefaultDatasetsDir(workflowName);
|
|
83
|
-
const filePath = join(dir, `${datasetName}.yml`);
|
|
84
|
-
await writeDataset(dataset, filePath);
|
|
85
|
-
this.log(`Dataset saved: ${filePath}`);
|
|
86
|
-
}
|
|
87
|
-
async generateFromTrace(workflowName, tracePath, nameOverride) {
|
|
88
|
-
this.log(`Reading trace: ${tracePath}`);
|
|
89
|
-
const content = await readFile(tracePath, 'utf-8');
|
|
90
|
-
const traceData = JSON.parse(content);
|
|
91
|
-
const extracted = extractDatasetFromTrace(traceData);
|
|
92
|
-
const datasetName = nameOverride ?? extractDatasetName(tracePath);
|
|
93
|
-
const dataset = buildDataset(datasetName, extracted.input, extracted.output, extracted.executionTimeMs);
|
|
94
|
-
const dir = resolveDefaultDatasetsDir(workflowName);
|
|
95
|
-
const filePath = join(dir, `${datasetName}.yml`);
|
|
96
|
-
await writeDataset(dataset, filePath);
|
|
97
|
-
this.log(`Dataset saved: ${filePath}`);
|
|
98
|
-
}
|
|
99
|
-
async generateFromS3(workflowName, limit) {
|
|
100
|
-
this.log(`Listing remote traces for "${workflowName}"...`);
|
|
101
|
-
const traces = await listRemoteTraces(workflowName, { limit });
|
|
102
|
-
if (traces.length === 0) {
|
|
103
|
-
this.log('No remote traces found.');
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
this.log(`Found ${traces.length} trace(s). Downloading...`);
|
|
107
|
-
const dir = resolveDefaultDatasetsDir(workflowName);
|
|
108
|
-
for (const trace of traces) {
|
|
109
|
-
const traceData = await downloadRemoteTrace(trace.key);
|
|
110
|
-
const extracted = extractDatasetFromTrace(traceData);
|
|
111
|
-
const datasetName = extractDatasetName(trace.key);
|
|
112
|
-
const dataset = buildDataset(datasetName, extracted.input, extracted.output, extracted.executionTimeMs);
|
|
113
|
-
const filePath = join(dir, `${datasetName}.yml`);
|
|
114
|
-
await writeDataset(dataset, filePath);
|
|
115
|
-
this.log(` Saved: ${filePath}`);
|
|
116
|
-
}
|
|
117
|
-
this.log(`\nGenerated ${traces.length} dataset(s)`);
|
|
118
|
-
}
|
|
119
|
-
async resolveScenarioInput(workflowName, scenario, inputFlag) {
|
|
120
|
-
if (inputFlag && scenario) {
|
|
121
|
-
return ux.error('Cannot use both scenario argument and --input flag. Choose one.', { exit: 1 });
|
|
122
|
-
}
|
|
123
|
-
if (inputFlag) {
|
|
124
|
-
return parseInputFlag(inputFlag);
|
|
125
|
-
}
|
|
126
|
-
if (scenario) {
|
|
127
|
-
const resolution = await resolveScenarioPath(workflowName, scenario);
|
|
128
|
-
if (!resolution.found) {
|
|
129
|
-
return ux.error(getScenarioNotFoundMessage(workflowName, scenario, resolution.searchedPaths), { exit: 1 });
|
|
130
|
-
}
|
|
131
|
-
return parseInputFlag(resolution.path);
|
|
132
|
-
}
|
|
133
|
-
return ux.error('Input required. Provide either:\n' +
|
|
134
|
-
' - A scenario: output workflow dataset generate <workflow> <scenario>\n' +
|
|
135
|
-
' - An input flag: output workflow dataset generate <workflow> --input <json>', { exit: 1 });
|
|
136
|
-
}
|
|
137
|
-
async catch(error) {
|
|
138
|
-
return handleApiError(error, (...args) => this.error(...args), {
|
|
139
|
-
404: 'Workflow not found. Check the workflow name.',
|
|
140
|
-
500: 'Workflow execution failed.'
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class DatasetList extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
workflowName: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
-
};
|
|
11
|
-
run(): Promise<void>;
|
|
12
|
-
}
|