@outputai/cli 0.1.2-dev.0 → 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 -13
- package/dist/commands/dev/index.js +0 -162
- 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 -38
- package/dist/services/docker.js +0 -148
- 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
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import logUpdate from 'log-update';
|
|
5
|
-
import { validateDockerEnvironment, startDockerCompose, stopDockerCompose, getServiceStatus, DockerComposeConfigNotFoundError, getDefaultDockerComposePath, SERVICE_HEALTH, SERVICE_STATE } from '#services/docker.js';
|
|
6
|
-
import { getErrorMessage } from '#utils/error_utils.js';
|
|
7
|
-
import { getDevSuccessMessage } from '#services/messages.js';
|
|
8
|
-
import { ensureClaudePlugin } from '#services/coding_agents.js';
|
|
9
|
-
const ANSI = {
|
|
10
|
-
RESET: '\x1b[0m',
|
|
11
|
-
DIM: '\x1b[2m',
|
|
12
|
-
BOLD: '\x1b[1m',
|
|
13
|
-
CYAN: '\x1b[36m',
|
|
14
|
-
RED: '\x1b[31m',
|
|
15
|
-
YELLOW: '\x1b[33m',
|
|
16
|
-
BG_RED: '\x1b[41m',
|
|
17
|
-
WHITE: '\x1b[37m'
|
|
18
|
-
};
|
|
19
|
-
const STATUS_ICONS = {
|
|
20
|
-
[SERVICE_HEALTH.HEALTHY]: '●',
|
|
21
|
-
[SERVICE_HEALTH.UNHEALTHY]: '○',
|
|
22
|
-
[SERVICE_HEALTH.STARTING]: '◐',
|
|
23
|
-
[SERVICE_HEALTH.NONE]: '●',
|
|
24
|
-
[SERVICE_STATE.RUNNING]: '●',
|
|
25
|
-
[SERVICE_STATE.EXITED]: '✗'
|
|
26
|
-
};
|
|
27
|
-
const STATUS_COLORS = {
|
|
28
|
-
[SERVICE_HEALTH.HEALTHY]: '\x1b[32m',
|
|
29
|
-
[SERVICE_HEALTH.UNHEALTHY]: '\x1b[31m',
|
|
30
|
-
[SERVICE_HEALTH.STARTING]: '\x1b[33m',
|
|
31
|
-
[SERVICE_HEALTH.NONE]: '\x1b[34m',
|
|
32
|
-
[SERVICE_STATE.RUNNING]: '\x1b[34m',
|
|
33
|
-
[SERVICE_STATE.EXITED]: '\x1b[31m'
|
|
34
|
-
};
|
|
35
|
-
const formatService = (service) => {
|
|
36
|
-
const healthKey = service.health === SERVICE_HEALTH.NONE ? service.state : service.health;
|
|
37
|
-
const icon = STATUS_ICONS[healthKey] || '?';
|
|
38
|
-
const color = STATUS_COLORS[healthKey] || '';
|
|
39
|
-
const ports = service.ports.length ? service.ports.join(', ') : '-';
|
|
40
|
-
const status = service.health === SERVICE_HEALTH.NONE ? service.state : service.health;
|
|
41
|
-
const name = service.name.padEnd(15);
|
|
42
|
-
const statusPadded = status.padEnd(10);
|
|
43
|
-
return ` ${color}${icon}${ANSI.RESET} ${name} ${ANSI.DIM}${statusPadded}${ANSI.RESET} ${ANSI.DIM}${ports}${ANSI.RESET}`;
|
|
44
|
-
};
|
|
45
|
-
const getFailedServicesWarning = (services) => {
|
|
46
|
-
const failedServices = services.filter(s => s.state === SERVICE_STATE.EXITED);
|
|
47
|
-
if (failedServices.length === 0) {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
const failedNames = failedServices.map(s => s.name);
|
|
51
|
-
const hasWorkerFailed = failedNames.some(name => name.toLowerCase().includes('worker'));
|
|
52
|
-
const warningLines = [
|
|
53
|
-
'',
|
|
54
|
-
`${ANSI.BG_RED}${ANSI.WHITE}${ANSI.BOLD} ⚠️ SERVICE FAILURE DETECTED ${ANSI.RESET}`,
|
|
55
|
-
'',
|
|
56
|
-
`${ANSI.RED}${ANSI.BOLD}Failed services:${ANSI.RESET} ${failedNames.join(', ')}`
|
|
57
|
-
];
|
|
58
|
-
if (hasWorkerFailed) {
|
|
59
|
-
warningLines.push('', `${ANSI.YELLOW}${ANSI.BOLD}⚡ The worker is not running!${ANSI.RESET}`, `${ANSI.YELLOW} Workflows will fail until the worker is restarted.${ANSI.RESET}`, '', `${ANSI.DIM}Check the logs with: docker compose logs worker${ANSI.RESET}`);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
warningLines.push('', `${ANSI.DIM}Check the logs with: docker compose logs <service-name>${ANSI.RESET}`);
|
|
63
|
-
}
|
|
64
|
-
return warningLines;
|
|
65
|
-
};
|
|
66
|
-
const poll = async (fn, intervalMs) => {
|
|
67
|
-
for (;;) {
|
|
68
|
-
await fn();
|
|
69
|
-
await new Promise(resolve => setTimeout(resolve, intervalMs));
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
export default class Dev extends Command {
|
|
73
|
-
static description = 'Start Output development services (auto-restarts worker on file changes)';
|
|
74
|
-
static examples = [
|
|
75
|
-
'<%= config.bin %> <%= command.id %>',
|
|
76
|
-
'<%= config.bin %> <%= command.id %> --compose-file ./custom-docker-compose.yml',
|
|
77
|
-
'<%= config.bin %> <%= command.id %> --image-pull-policy missing'
|
|
78
|
-
];
|
|
79
|
-
static args = {};
|
|
80
|
-
static flags = {
|
|
81
|
-
'compose-file': Flags.string({
|
|
82
|
-
description: 'Path to a custom docker-compose file',
|
|
83
|
-
required: false,
|
|
84
|
-
char: 'f'
|
|
85
|
-
}),
|
|
86
|
-
'image-pull-policy': Flags.string({
|
|
87
|
-
description: 'Image pull policy for docker compose (always, missing, never)',
|
|
88
|
-
options: ['always', 'missing', 'never'],
|
|
89
|
-
default: 'always'
|
|
90
|
-
})
|
|
91
|
-
};
|
|
92
|
-
dockerProcess = null;
|
|
93
|
-
async run() {
|
|
94
|
-
const { flags } = await this.parse(Dev);
|
|
95
|
-
// Ensure Claude plugin is configured (fire-and-forget, silent)
|
|
96
|
-
ensureClaudePlugin(process.cwd(), { silent: true }).catch(() => { });
|
|
97
|
-
validateDockerEnvironment();
|
|
98
|
-
const dockerComposePath = flags['compose-file'] ?
|
|
99
|
-
path.resolve(process.cwd(), flags['compose-file']) :
|
|
100
|
-
getDefaultDockerComposePath();
|
|
101
|
-
try {
|
|
102
|
-
await fs.access(dockerComposePath);
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
throw new DockerComposeConfigNotFoundError(dockerComposePath);
|
|
106
|
-
}
|
|
107
|
-
this.log('\n🚀 Starting Output development services...\n');
|
|
108
|
-
if (flags['compose-file']) {
|
|
109
|
-
this.log(`Using custom docker-compose file: ${flags['compose-file']}\n`);
|
|
110
|
-
}
|
|
111
|
-
this.log('File watching enabled - worker will restart automatically on changes\n');
|
|
112
|
-
const cleanup = async () => {
|
|
113
|
-
this.log('\n');
|
|
114
|
-
if (this.dockerProcess) {
|
|
115
|
-
this.dockerProcess.kill('SIGTERM');
|
|
116
|
-
}
|
|
117
|
-
await stopDockerCompose(dockerComposePath);
|
|
118
|
-
process.exit(0);
|
|
119
|
-
};
|
|
120
|
-
process.on('SIGINT', cleanup);
|
|
121
|
-
process.on('SIGTERM', cleanup);
|
|
122
|
-
const pullPolicy = flags['image-pull-policy'];
|
|
123
|
-
try {
|
|
124
|
-
const { process: dockerProc, waitForHealthy } = await startDockerCompose(dockerComposePath, pullPolicy);
|
|
125
|
-
this.dockerProcess = dockerProc;
|
|
126
|
-
dockerProc.on('error', error => {
|
|
127
|
-
this.error(`Docker process error: ${getErrorMessage(error)}`, { exit: 1 });
|
|
128
|
-
});
|
|
129
|
-
this.log('⏳ Waiting for services to become healthy...\n');
|
|
130
|
-
await waitForHealthy();
|
|
131
|
-
const services = await getServiceStatus(dockerComposePath);
|
|
132
|
-
this.log(getDevSuccessMessage(services));
|
|
133
|
-
await this.pollServiceStatus(dockerComposePath);
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
this.error(getErrorMessage(error), { exit: 1 });
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
async pollServiceStatus(dockerComposePath) {
|
|
140
|
-
const outputServiceStatus = async () => {
|
|
141
|
-
try {
|
|
142
|
-
const services = await getServiceStatus(dockerComposePath);
|
|
143
|
-
const failureWarning = getFailedServicesWarning(services);
|
|
144
|
-
const lines = [
|
|
145
|
-
`${ANSI.BOLD}📊 Service Status${ANSI.RESET}`,
|
|
146
|
-
'',
|
|
147
|
-
...services.map(formatService),
|
|
148
|
-
...failureWarning,
|
|
149
|
-
'',
|
|
150
|
-
`${ANSI.CYAN}🌐 Temporal UI:${ANSI.RESET} ${ANSI.BOLD}http://localhost:8080${ANSI.RESET}`,
|
|
151
|
-
'',
|
|
152
|
-
`${ANSI.DIM}Press Ctrl+C to stop services${ANSI.RESET}`
|
|
153
|
-
];
|
|
154
|
-
logUpdate(lines.join('\n'));
|
|
155
|
-
}
|
|
156
|
-
catch {
|
|
157
|
-
// silent retry on next poll
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
await poll(outputServiceStatus, 2000);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
3
|
-
import fs from 'node:fs/promises';
|
|
4
|
-
import * as dockerService from '#services/docker.js';
|
|
5
|
-
import * as codingAgentsService from '#services/coding_agents.js';
|
|
6
|
-
import Dev from './index.js';
|
|
7
|
-
vi.mock('#services/coding_agents.js', () => ({
|
|
8
|
-
ensureClaudePlugin: vi.fn().mockResolvedValue(undefined)
|
|
9
|
-
}));
|
|
10
|
-
vi.mock('#services/docker.js', () => ({
|
|
11
|
-
validateDockerEnvironment: vi.fn(),
|
|
12
|
-
startDockerCompose: vi.fn(),
|
|
13
|
-
stopDockerCompose: vi.fn().mockResolvedValue(undefined),
|
|
14
|
-
getServiceStatus: vi.fn().mockResolvedValue([
|
|
15
|
-
{ name: 'redis', state: 'running', health: 'healthy', ports: ['6379:6379'] },
|
|
16
|
-
{ name: 'temporal', state: 'running', health: 'healthy', ports: ['7233:7233'] }
|
|
17
|
-
]),
|
|
18
|
-
DockerComposeConfigNotFoundError: Error,
|
|
19
|
-
DockerValidationError: Error,
|
|
20
|
-
getDefaultDockerComposePath: vi.fn(() => '/path/to/docker-compose-dev.yml'),
|
|
21
|
-
SERVICE_HEALTH: {
|
|
22
|
-
HEALTHY: 'healthy',
|
|
23
|
-
UNHEALTHY: 'unhealthy',
|
|
24
|
-
STARTING: 'starting',
|
|
25
|
-
NONE: 'none'
|
|
26
|
-
},
|
|
27
|
-
SERVICE_STATE: {
|
|
28
|
-
RUNNING: 'running',
|
|
29
|
-
EXITED: 'exited'
|
|
30
|
-
}
|
|
31
|
-
}));
|
|
32
|
-
vi.mock('node:fs/promises', () => ({
|
|
33
|
-
default: {
|
|
34
|
-
access: vi.fn()
|
|
35
|
-
}
|
|
36
|
-
}));
|
|
37
|
-
const createMockDockerProcess = () => ({
|
|
38
|
-
process: {
|
|
39
|
-
on: vi.fn(),
|
|
40
|
-
kill: vi.fn(),
|
|
41
|
-
stdout: { on: vi.fn() },
|
|
42
|
-
stderr: { on: vi.fn() }
|
|
43
|
-
},
|
|
44
|
-
waitForHealthy: vi.fn().mockResolvedValue(undefined)
|
|
45
|
-
});
|
|
46
|
-
describe('dev command', () => {
|
|
47
|
-
beforeEach(() => {
|
|
48
|
-
vi.clearAllMocks();
|
|
49
|
-
// By default, docker validation succeeds
|
|
50
|
-
vi.mocked(dockerService.validateDockerEnvironment).mockResolvedValue(undefined);
|
|
51
|
-
// By default, startDockerCompose returns a mock process
|
|
52
|
-
vi.mocked(dockerService.startDockerCompose).mockResolvedValue(createMockDockerProcess());
|
|
53
|
-
// By default, fs.access succeeds (file exists)
|
|
54
|
-
vi.mocked(fs).access.mockResolvedValue(undefined);
|
|
55
|
-
// By default, ensureClaudePlugin succeeds
|
|
56
|
-
vi.mocked(codingAgentsService.ensureClaudePlugin).mockResolvedValue(undefined);
|
|
57
|
-
});
|
|
58
|
-
afterEach(() => {
|
|
59
|
-
vi.restoreAllMocks();
|
|
60
|
-
});
|
|
61
|
-
describe('command structure', () => {
|
|
62
|
-
it('should have correct description', () => {
|
|
63
|
-
expect(Dev.description).toBeDefined();
|
|
64
|
-
expect(Dev.description).toContain('development services');
|
|
65
|
-
});
|
|
66
|
-
it('should have examples', () => {
|
|
67
|
-
expect(Dev.examples).toBeDefined();
|
|
68
|
-
expect(Array.isArray(Dev.examples)).toBe(true);
|
|
69
|
-
expect(Dev.examples.length).toBeGreaterThan(0);
|
|
70
|
-
});
|
|
71
|
-
it('should have no required arguments', () => {
|
|
72
|
-
expect(Dev.args).toBeDefined();
|
|
73
|
-
expect(Object.keys(Dev.args)).toHaveLength(0);
|
|
74
|
-
});
|
|
75
|
-
it('should have compose-file flag defined', () => {
|
|
76
|
-
expect(Dev.flags).toBeDefined();
|
|
77
|
-
expect(Dev.flags['compose-file']).toBeDefined();
|
|
78
|
-
expect(Dev.flags['compose-file'].description).toContain('custom docker-compose');
|
|
79
|
-
expect(Dev.flags['compose-file'].required).toBe(false);
|
|
80
|
-
expect(Dev.flags['compose-file'].char).toBe('f');
|
|
81
|
-
});
|
|
82
|
-
it('should have image-pull-policy flag defined', () => {
|
|
83
|
-
expect(Dev.flags).toBeDefined();
|
|
84
|
-
expect(Dev.flags['image-pull-policy']).toBeDefined();
|
|
85
|
-
expect(Dev.flags['image-pull-policy'].description).toContain('pull policy');
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe('command instantiation', () => {
|
|
89
|
-
it('should be instantiable', () => {
|
|
90
|
-
const cmd = new Dev([], {});
|
|
91
|
-
expect(cmd).toBeInstanceOf(Dev);
|
|
92
|
-
});
|
|
93
|
-
it('should have a run method', () => {
|
|
94
|
-
const cmd = new Dev([], {});
|
|
95
|
-
expect(cmd.run).toBeDefined();
|
|
96
|
-
expect(typeof cmd.run).toBe('function');
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
describe('Docker validation', () => {
|
|
100
|
-
it('should error if Docker validation fails', async () => {
|
|
101
|
-
const config = {
|
|
102
|
-
runHook: vi.fn().mockResolvedValue({ failures: [], successes: [] })
|
|
103
|
-
};
|
|
104
|
-
const cmd = new Dev([], config);
|
|
105
|
-
cmd.log = vi.fn();
|
|
106
|
-
// Mock parse to return flags
|
|
107
|
-
Object.defineProperty(cmd, 'parse', {
|
|
108
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined }, args: {} }),
|
|
109
|
-
configurable: true
|
|
110
|
-
});
|
|
111
|
-
const validationError = new Error('Docker is not installed');
|
|
112
|
-
vi.mocked(dockerService.validateDockerEnvironment).mockImplementation(() => {
|
|
113
|
-
throw validationError;
|
|
114
|
-
});
|
|
115
|
-
await expect(cmd.run()).rejects.toThrow('Docker is not installed');
|
|
116
|
-
});
|
|
117
|
-
it('should call validateDockerEnvironment', async () => {
|
|
118
|
-
const cmd = new Dev([], {});
|
|
119
|
-
cmd.log = vi.fn();
|
|
120
|
-
cmd.error = vi.fn();
|
|
121
|
-
// Mock the subprocess spawn to prevent actual execution
|
|
122
|
-
vi.doMock('node:child_process', () => ({
|
|
123
|
-
spawn: vi.fn().mockReturnValue({
|
|
124
|
-
on: vi.fn(),
|
|
125
|
-
kill: vi.fn()
|
|
126
|
-
})
|
|
127
|
-
}));
|
|
128
|
-
// This test just verifies the function is called
|
|
129
|
-
expect(vi.mocked(dockerService.validateDockerEnvironment)).toBeDefined();
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe('Claude plugin update', () => {
|
|
133
|
-
it('should call ensureClaudePlugin on startup', async () => {
|
|
134
|
-
const cmd = new Dev([], {});
|
|
135
|
-
cmd.log = vi.fn();
|
|
136
|
-
cmd.error = vi.fn();
|
|
137
|
-
Object.defineProperty(cmd, 'parse', {
|
|
138
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
|
|
139
|
-
configurable: true
|
|
140
|
-
});
|
|
141
|
-
const runPromise = cmd.run();
|
|
142
|
-
await new Promise(resolve => setImmediate(resolve));
|
|
143
|
-
expect(codingAgentsService.ensureClaudePlugin).toHaveBeenCalledWith(process.cwd(), { silent: true });
|
|
144
|
-
runPromise.catch(() => { });
|
|
145
|
-
});
|
|
146
|
-
it('should not block dev if ensureClaudePlugin fails', async () => {
|
|
147
|
-
vi.mocked(codingAgentsService.ensureClaudePlugin).mockRejectedValue(new Error('Plugin update failed'));
|
|
148
|
-
const cmd = new Dev([], {});
|
|
149
|
-
cmd.log = vi.fn();
|
|
150
|
-
cmd.error = vi.fn();
|
|
151
|
-
Object.defineProperty(cmd, 'parse', {
|
|
152
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
|
|
153
|
-
configurable: true
|
|
154
|
-
});
|
|
155
|
-
const runPromise = cmd.run();
|
|
156
|
-
await new Promise(resolve => setImmediate(resolve));
|
|
157
|
-
// Docker compose should still be called even if plugin update fails
|
|
158
|
-
expect(dockerService.startDockerCompose).toHaveBeenCalled();
|
|
159
|
-
runPromise.catch(() => { });
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
describe('watch functionality', () => {
|
|
163
|
-
it('should start docker compose', async () => {
|
|
164
|
-
const cmd = new Dev([], {});
|
|
165
|
-
cmd.log = vi.fn();
|
|
166
|
-
cmd.error = vi.fn();
|
|
167
|
-
// Mock parse to return flags
|
|
168
|
-
Object.defineProperty(cmd, 'parse', {
|
|
169
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
|
|
170
|
-
configurable: true
|
|
171
|
-
});
|
|
172
|
-
// Run the command but don't await it since it waits forever after startup
|
|
173
|
-
const runPromise = cmd.run();
|
|
174
|
-
// Wait a tick for startDockerCompose to be called
|
|
175
|
-
await new Promise(resolve => setImmediate(resolve));
|
|
176
|
-
expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', 'always' // default pull policy
|
|
177
|
-
);
|
|
178
|
-
expect(cmd.log).toHaveBeenCalledWith(expect.stringContaining('File watching enabled'));
|
|
179
|
-
// Cancel the promise (it will be rejected but we don't care)
|
|
180
|
-
runPromise.catch(() => { });
|
|
181
|
-
});
|
|
182
|
-
it('should handle docker compose configuration not found', async () => {
|
|
183
|
-
vi.mocked(fs).access.mockRejectedValue(new Error('File not found'));
|
|
184
|
-
const cmd = new Dev([], {});
|
|
185
|
-
cmd.log = vi.fn();
|
|
186
|
-
cmd.error = vi.fn();
|
|
187
|
-
await expect(cmd.run()).rejects.toThrow();
|
|
188
|
-
});
|
|
189
|
-
it('should handle startDockerCompose errors', async () => {
|
|
190
|
-
vi.mocked(dockerService.startDockerCompose).mockRejectedValue(new Error('Docker error'));
|
|
191
|
-
const cmd = new Dev([], {});
|
|
192
|
-
cmd.log = vi.fn();
|
|
193
|
-
cmd.error = vi.fn();
|
|
194
|
-
// Mock parse to return flags
|
|
195
|
-
Object.defineProperty(cmd, 'parse', {
|
|
196
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'always' }, args: {} }),
|
|
197
|
-
configurable: true
|
|
198
|
-
});
|
|
199
|
-
await cmd.run();
|
|
200
|
-
expect(cmd.error).toHaveBeenCalledWith('Docker error', { exit: 1 });
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
describe('image pull policy', () => {
|
|
204
|
-
it('should pass pull policy to startDockerCompose', async () => {
|
|
205
|
-
const cmd = new Dev([], {});
|
|
206
|
-
cmd.log = vi.fn();
|
|
207
|
-
cmd.error = vi.fn();
|
|
208
|
-
// Mock parse to return flags with missing pull policy
|
|
209
|
-
Object.defineProperty(cmd, 'parse', {
|
|
210
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'missing' }, args: {} }),
|
|
211
|
-
configurable: true
|
|
212
|
-
});
|
|
213
|
-
// Run the command but don't await it since it waits forever after startup
|
|
214
|
-
const runPromise = cmd.run();
|
|
215
|
-
// Wait a tick for startDockerCompose to be called
|
|
216
|
-
await new Promise(resolve => setImmediate(resolve));
|
|
217
|
-
expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', 'missing');
|
|
218
|
-
// Cancel the promise (it will be rejected but we don't care)
|
|
219
|
-
runPromise.catch(() => { });
|
|
220
|
-
});
|
|
221
|
-
it('should use never pull policy when specified', async () => {
|
|
222
|
-
const cmd = new Dev([], {});
|
|
223
|
-
cmd.log = vi.fn();
|
|
224
|
-
cmd.error = vi.fn();
|
|
225
|
-
// Mock parse to return flags with never pull policy
|
|
226
|
-
Object.defineProperty(cmd, 'parse', {
|
|
227
|
-
value: vi.fn().mockResolvedValue({ flags: { 'compose-file': undefined, 'image-pull-policy': 'never' }, args: {} }),
|
|
228
|
-
configurable: true
|
|
229
|
-
});
|
|
230
|
-
// Run the command but don't await it since it waits forever after startup
|
|
231
|
-
const runPromise = cmd.run();
|
|
232
|
-
// Wait a tick for startDockerCompose to be called
|
|
233
|
-
await new Promise(resolve => setImmediate(resolve));
|
|
234
|
-
expect(dockerService.startDockerCompose).toHaveBeenCalledWith('/path/to/docker-compose-dev.yml', 'never');
|
|
235
|
-
// Cancel the promise (it will be rejected but we don't care)
|
|
236
|
-
runPromise.catch(() => { });
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
});
|
package/dist/commands/init.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class Init extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static args: {
|
|
6
|
-
folderName: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
7
|
-
};
|
|
8
|
-
static flags: {
|
|
9
|
-
'skip-env': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
};
|
|
11
|
-
run(): Promise<void>;
|
|
12
|
-
}
|
package/dist/commands/init.js
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
import { UserCancelledError } from '#types/errors.js';
|
|
3
|
-
import { runInit } from '#services/project_scaffold.js';
|
|
4
|
-
export default class Init extends Command {
|
|
5
|
-
static description = 'Initialize a new Output project by scaffolding the complete project structure';
|
|
6
|
-
static examples = [
|
|
7
|
-
'<%= config.bin %> <%= command.id %>',
|
|
8
|
-
'<%= config.bin %> <%= command.id %> my-workflow-project'
|
|
9
|
-
];
|
|
10
|
-
static args = {
|
|
11
|
-
folderName: Args.string({
|
|
12
|
-
description: 'Optional folder name for the project (skips folder name prompt)',
|
|
13
|
-
required: false
|
|
14
|
-
})
|
|
15
|
-
};
|
|
16
|
-
static flags = {
|
|
17
|
-
'skip-env': Flags.boolean({
|
|
18
|
-
description: 'Skip interactive environment variable configuration',
|
|
19
|
-
default: false
|
|
20
|
-
})
|
|
21
|
-
};
|
|
22
|
-
async run() {
|
|
23
|
-
try {
|
|
24
|
-
const { args, flags } = await this.parse(Init);
|
|
25
|
-
await runInit(flags['skip-env'], args.folderName);
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
if (error instanceof UserCancelledError) {
|
|
29
|
-
this.log(error.message);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
// runInit handles cleanup internally and throws Error with message
|
|
33
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
34
|
-
this.error(errorMessage);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
3
|
-
import * as projectScaffold from '#services/project_scaffold.js';
|
|
4
|
-
import { UserCancelledError } from '#types/errors.js';
|
|
5
|
-
import Init from './init.js';
|
|
6
|
-
vi.mock('#services/project_scaffold.js');
|
|
7
|
-
describe('init command', () => {
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
vi.clearAllMocks();
|
|
10
|
-
vi.mocked(projectScaffold.runInit).mockResolvedValue(undefined);
|
|
11
|
-
});
|
|
12
|
-
afterEach(() => {
|
|
13
|
-
vi.restoreAllMocks();
|
|
14
|
-
});
|
|
15
|
-
describe('command structure', () => {
|
|
16
|
-
it('should have correct description', () => {
|
|
17
|
-
expect(Init.description).toBeDefined();
|
|
18
|
-
expect(Init.description).toContain('scaffold');
|
|
19
|
-
});
|
|
20
|
-
it('should have correct examples', () => {
|
|
21
|
-
expect(Init.examples).toBeDefined();
|
|
22
|
-
expect(Array.isArray(Init.examples)).toBe(true);
|
|
23
|
-
expect(Init.examples.length).toBeGreaterThan(0);
|
|
24
|
-
});
|
|
25
|
-
it('should have an optional folderName argument', () => {
|
|
26
|
-
expect(Init.args).toBeDefined();
|
|
27
|
-
expect(Init.args.folderName).toBeDefined();
|
|
28
|
-
expect(Init.args.folderName.required).toBe(false);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('command execution', () => {
|
|
32
|
-
const createTestCommand = (args = [], flags = {}, parsedArgs = {}) => {
|
|
33
|
-
const cmd = new Init(args, {});
|
|
34
|
-
cmd.log = vi.fn();
|
|
35
|
-
cmd.warn = vi.fn();
|
|
36
|
-
cmd.error = vi.fn();
|
|
37
|
-
Object.defineProperty(cmd, 'parse', {
|
|
38
|
-
value: vi.fn().mockResolvedValue({
|
|
39
|
-
args: { folderName: undefined, ...parsedArgs },
|
|
40
|
-
flags: { 'skip-env': false, ...flags }
|
|
41
|
-
}),
|
|
42
|
-
configurable: true
|
|
43
|
-
});
|
|
44
|
-
return cmd;
|
|
45
|
-
};
|
|
46
|
-
it('should be instantiable', () => {
|
|
47
|
-
const cmd = createTestCommand();
|
|
48
|
-
expect(cmd).toBeInstanceOf(Init);
|
|
49
|
-
});
|
|
50
|
-
it('should have a run method', () => {
|
|
51
|
-
const cmd = createTestCommand();
|
|
52
|
-
expect(cmd.run).toBeDefined();
|
|
53
|
-
expect(typeof cmd.run).toBe('function');
|
|
54
|
-
});
|
|
55
|
-
it('should call runInit with skip-env flag and folder name', async () => {
|
|
56
|
-
const cmd = createTestCommand();
|
|
57
|
-
await cmd.run();
|
|
58
|
-
expect(projectScaffold.runInit).toHaveBeenCalledWith(false, undefined);
|
|
59
|
-
});
|
|
60
|
-
it('should handle UserCancelledError', async () => {
|
|
61
|
-
const error = new UserCancelledError();
|
|
62
|
-
vi.mocked(projectScaffold.runInit).mockRejectedValue(error);
|
|
63
|
-
const cmd = createTestCommand();
|
|
64
|
-
await cmd.run();
|
|
65
|
-
expect(cmd.log).toHaveBeenCalledWith('Init cancelled by user.');
|
|
66
|
-
expect(cmd.error).not.toHaveBeenCalled();
|
|
67
|
-
});
|
|
68
|
-
it('should handle other errors by passing error message', async () => {
|
|
69
|
-
// runInit now handles cleanup internally and throws Error with message
|
|
70
|
-
const testError = new Error('Failed to create project');
|
|
71
|
-
vi.mocked(projectScaffold.runInit).mockRejectedValue(testError);
|
|
72
|
-
const cmd = createTestCommand();
|
|
73
|
-
await cmd.run();
|
|
74
|
-
expect(cmd.error).toHaveBeenCalledWith('Failed to create project');
|
|
75
|
-
});
|
|
76
|
-
it('should pass error message to this.error', async () => {
|
|
77
|
-
const testError = new Error('Folder already exists');
|
|
78
|
-
vi.mocked(projectScaffold.runInit).mockRejectedValue(testError);
|
|
79
|
-
const cmd = createTestCommand();
|
|
80
|
-
await cmd.run();
|
|
81
|
-
expect(cmd.error).toHaveBeenCalledWith('Folder already exists');
|
|
82
|
-
});
|
|
83
|
-
it('should successfully complete project creation', async () => {
|
|
84
|
-
const cmd = createTestCommand();
|
|
85
|
-
await cmd.run();
|
|
86
|
-
expect(projectScaffold.runInit).toHaveBeenCalled();
|
|
87
|
-
expect(cmd.error).not.toHaveBeenCalled();
|
|
88
|
-
});
|
|
89
|
-
it('should pass skip-env flag to runInit when --skip-env is provided', async () => {
|
|
90
|
-
const cmd = createTestCommand([], { 'skip-env': true });
|
|
91
|
-
await cmd.run();
|
|
92
|
-
expect(projectScaffold.runInit).toHaveBeenCalledWith(true, undefined);
|
|
93
|
-
});
|
|
94
|
-
it('should pass folder name to runInit when provided', async () => {
|
|
95
|
-
const cmd = createTestCommand([], {}, { folderName: 'my-project' });
|
|
96
|
-
await cmd.run();
|
|
97
|
-
expect(projectScaffold.runInit).toHaveBeenCalledWith(false, 'my-project');
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class Update extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
cli: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
-
agents: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
-
};
|
|
9
|
-
run(): Promise<void>;
|
|
10
|
-
private updateCli;
|
|
11
|
-
private updateAgents;
|
|
12
|
-
private handleGlobalUpdate;
|
|
13
|
-
private handleLocalUpdate;
|
|
14
|
-
}
|