peaks-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +52 -0
- package/README.md +417 -0
- package/bin/peaks.js +2 -0
- package/dist/src/cli/cli-helpers.d.ts +25 -0
- package/dist/src/cli/cli-helpers.js +78 -0
- package/dist/src/cli/commands/capability-commands.d.ts +5 -0
- package/dist/src/cli/commands/capability-commands.js +46 -0
- package/dist/src/cli/commands/capability-worker-config-sc-commands.d.ts +3 -0
- package/dist/src/cli/commands/capability-worker-config-sc-commands.js +10 -0
- package/dist/src/cli/commands/config-commands.d.ts +3 -0
- package/dist/src/cli/commands/config-commands.js +212 -0
- package/dist/src/cli/commands/core-artifact-commands.d.ts +3 -0
- package/dist/src/cli/commands/core-artifact-commands.js +200 -0
- package/dist/src/cli/commands/sc-commands.d.ts +3 -0
- package/dist/src/cli/commands/sc-commands.js +37 -0
- package/dist/src/cli/commands/worker-commands.d.ts +3 -0
- package/dist/src/cli/commands/worker-commands.js +52 -0
- package/dist/src/cli/commands/workflow-commands.d.ts +3 -0
- package/dist/src/cli/commands/workflow-commands.js +257 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +14 -0
- package/dist/src/cli/program.d.ts +4 -0
- package/dist/src/cli/program.js +13 -0
- package/dist/src/services/artifacts/artifact-service.d.ts +43 -0
- package/dist/src/services/artifacts/artifact-service.js +97 -0
- package/dist/src/services/artifacts/workspace-service.d.ts +33 -0
- package/dist/src/services/artifacts/workspace-service.js +254 -0
- package/dist/src/services/config/config-service.d.ts +29 -0
- package/dist/src/services/config/config-service.js +501 -0
- package/dist/src/services/config/config-types.d.ts +63 -0
- package/dist/src/services/config/config-types.js +16 -0
- package/dist/src/services/config/model-routing.d.ts +4 -0
- package/dist/src/services/config/model-routing.js +15 -0
- package/dist/src/services/doctor/doctor-service.d.ts +18 -0
- package/dist/src/services/doctor/doctor-service.js +68 -0
- package/dist/src/services/memory/project-memory-service.d.ts +79 -0
- package/dist/src/services/memory/project-memory-service.js +306 -0
- package/dist/src/services/profiles/profile-service.d.ts +6 -0
- package/dist/src/services/profiles/profile-service.js +19 -0
- package/dist/src/services/providers/minimax-provider-service.d.ts +24 -0
- package/dist/src/services/providers/minimax-provider-service.js +143 -0
- package/dist/src/services/providers/minimax-worker-service.d.ts +21 -0
- package/dist/src/services/providers/minimax-worker-service.js +80 -0
- package/dist/src/services/proxy/proxy-service.d.ts +7 -0
- package/dist/src/services/proxy/proxy-service.js +31 -0
- package/dist/src/services/rd/rd-service.d.ts +88 -0
- package/dist/src/services/rd/rd-service.js +370 -0
- package/dist/src/services/recommendations/capability-availability.d.ts +5 -0
- package/dist/src/services/recommendations/capability-availability.js +40 -0
- package/dist/src/services/recommendations/capability-map-service.d.ts +7 -0
- package/dist/src/services/recommendations/capability-map-service.js +131 -0
- package/dist/src/services/recommendations/capability-seed-items.d.ts +2 -0
- package/dist/src/services/recommendations/capability-seed-items.js +131 -0
- package/dist/src/services/recommendations/capability-seed-mappings.d.ts +2 -0
- package/dist/src/services/recommendations/capability-seed-mappings.js +42 -0
- package/dist/src/services/recommendations/capability-seed-sources.d.ts +2 -0
- package/dist/src/services/recommendations/capability-seed-sources.js +35 -0
- package/dist/src/services/recommendations/recommendation-service.d.ts +8 -0
- package/dist/src/services/recommendations/recommendation-service.js +106 -0
- package/dist/src/services/recommendations/recommendation-types.d.ts +129 -0
- package/dist/src/services/recommendations/recommendation-types.js +1 -0
- package/dist/src/services/recommendations/seed-capability-catalog.d.ts +3 -0
- package/dist/src/services/recommendations/seed-capability-catalog.js +3 -0
- package/dist/src/services/refactor/refactor-service.d.ts +9 -0
- package/dist/src/services/refactor/refactor-service.js +33 -0
- package/dist/src/services/sc/index.d.ts +1 -0
- package/dist/src/services/sc/index.js +1 -0
- package/dist/src/services/sc/sc-service.d.ts +79 -0
- package/dist/src/services/sc/sc-service.js +223 -0
- package/dist/src/services/skills/skill-registry.d.ts +17 -0
- package/dist/src/services/skills/skill-registry.js +40 -0
- package/dist/src/services/standards/project-standards-service.d.ts +82 -0
- package/dist/src/services/standards/project-standards-service.js +383 -0
- package/dist/src/services/tech/tech-service.d.ts +69 -0
- package/dist/src/services/tech/tech-service.js +236 -0
- package/dist/src/services/workflow/workflow-autonomous-service.d.ts +99 -0
- package/dist/src/services/workflow/workflow-autonomous-service.js +526 -0
- package/dist/src/services/workflow/workflow-router-service.d.ts +85 -0
- package/dist/src/services/workflow/workflow-router-service.js +213 -0
- package/dist/src/shared/change-id.d.ts +15 -0
- package/dist/src/shared/change-id.js +76 -0
- package/dist/src/shared/frontmatter.d.ts +6 -0
- package/dist/src/shared/frontmatter.js +47 -0
- package/dist/src/shared/fs-utils.d.ts +4 -0
- package/dist/src/shared/fs-utils.js +16 -0
- package/dist/src/shared/fs.d.ts +4 -0
- package/dist/src/shared/fs.js +26 -0
- package/dist/src/shared/path-utils.d.ts +13 -0
- package/dist/src/shared/path-utils.js +56 -0
- package/dist/src/shared/paths.d.ts +6 -0
- package/dist/src/shared/paths.js +40 -0
- package/dist/src/shared/planner-response.d.ts +21 -0
- package/dist/src/shared/planner-response.js +26 -0
- package/dist/src/shared/platform.d.ts +6 -0
- package/dist/src/shared/platform.js +11 -0
- package/dist/src/shared/process.d.ts +5 -0
- package/dist/src/shared/process.js +12 -0
- package/dist/src/shared/result.d.ts +13 -0
- package/dist/src/shared/result.js +32 -0
- package/package.json +49 -0
- package/schemas/approval-record.schema.json +14 -0
- package/schemas/artifact-manifest.schema.json +16 -0
- package/schemas/artifact-retention-report.schema.json +17 -0
- package/schemas/artifact-workspace.schema.json +22 -0
- package/schemas/capability-availability.schema.json +36 -0
- package/schemas/capability-item.schema.json +37 -0
- package/schemas/capability-source.schema.json +30 -0
- package/schemas/change-impact.schema.json +15 -0
- package/schemas/context-capsule.schema.json +16 -0
- package/schemas/recommendation-plan.schema.json +37 -0
- package/schemas/refactor-slice-spec.schema.json +19 -0
- package/scripts/clean-dist.mjs +8 -0
- package/scripts/install-skills.mjs +76 -0
- package/scripts/watch.mjs +389 -0
- package/skills/peaks-prd/SKILL.md +42 -0
- package/skills/peaks-prd/references/artifact-contracts.md +3 -0
- package/skills/peaks-prd/references/command-migration.md +3 -0
- package/skills/peaks-prd/references/workflow.md +11 -0
- package/skills/peaks-qa/SKILL.md +45 -0
- package/skills/peaks-qa/references/artifact-contracts.md +3 -0
- package/skills/peaks-qa/references/command-migration.md +3 -0
- package/skills/peaks-qa/references/regression-gates.md +16 -0
- package/skills/peaks-rd/SKILL.md +56 -0
- package/skills/peaks-rd/references/artifact-contracts.md +3 -0
- package/skills/peaks-rd/references/command-migration.md +3 -0
- package/skills/peaks-rd/references/refactor-workflow.md +31 -0
- package/skills/peaks-sc/SKILL.md +30 -0
- package/skills/peaks-sc/references/artifact-contracts.md +3 -0
- package/skills/peaks-sc/references/artifact-retention.md +14 -0
- package/skills/peaks-sc/references/command-migration.md +3 -0
- package/skills/peaks-solo/SKILL.md +63 -0
- package/skills/peaks-solo/references/artifact-contracts.md +3 -0
- package/skills/peaks-solo/references/command-migration.md +3 -0
- package/skills/peaks-solo/references/refactor-mode.md +22 -0
- package/skills/peaks-solo/references/workflow.md +14 -0
- package/skills/peaks-txt/SKILL.md +48 -0
- package/skills/peaks-txt/references/artifact-contracts.md +3 -0
- package/skills/peaks-txt/references/command-migration.md +3 -0
- package/skills/peaks-txt/references/context-capsule.md +20 -0
- package/skills/peaks-ui/SKILL.md +35 -0
- package/skills/peaks-ui/references/artifact-contracts.md +3 -0
- package/skills/peaks-ui/references/command-migration.md +3 -0
- package/skills/peaks-ui/references/workflow.md +11 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { addWorkspace, getConfig, getMiniMaxProviderConfig, getMiniMaxProviderStatus, isSensitiveConfigPath, readConfig, redactConfigSecrets, removeWorkspace, setConfig, setCurrentWorkspace, setMiniMaxProviderConfig } from '../../services/config/config-service.js';
|
|
2
|
+
import { testMiniMaxProvider } from '../../services/providers/minimax-provider-service.js';
|
|
3
|
+
import { fail, ok } from '../../shared/result.js';
|
|
4
|
+
import { addJsonOption, getErrorMessage, isArtifactProvider, isArtifactRepoSegment, isMiniMaxHttpsUrl, parseConfigLayer, printInvalidConfigLayer, printResult, redactSensitiveErrorMessage, summarizeMiniMaxSmokeResult } from '../cli-helpers.js';
|
|
5
|
+
export function registerConfigCommands(program, io) {
|
|
6
|
+
const config = program.command('config').description('Manage Peaks configuration');
|
|
7
|
+
registerConfigGetSetCommands(config, io);
|
|
8
|
+
registerMiniMaxProviderCommands(config, io);
|
|
9
|
+
registerWorkspaceCommands(config, io);
|
|
10
|
+
}
|
|
11
|
+
function registerConfigGetSetCommands(config, io) {
|
|
12
|
+
addJsonOption(config.command('get').description('Get current config or a specific key').option('--key <path>', 'dot-notation key path').option('--layer <layer>', 'user or project')).action((options) => {
|
|
13
|
+
const layer = parseConfigLayer(options.layer);
|
|
14
|
+
if (layer === null) {
|
|
15
|
+
printInvalidConfigLayer(io, 'config.get', options.json);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const getOpts = { ...(layer !== undefined ? { layer } : {}), ...(options.key !== undefined ? { key: options.key } : {}) };
|
|
19
|
+
const value = getConfig(getOpts);
|
|
20
|
+
const isSensitiveKey = options.key !== undefined && isSensitiveConfigPath(options.key);
|
|
21
|
+
printResult(io, ok('config.get', isSensitiveKey ? '***' : redactConfigSecrets(value, options.key ?? '')), options.json);
|
|
22
|
+
});
|
|
23
|
+
addJsonOption(config.command('set').description('Set a config value').requiredOption('--key <path>', 'dot-notation key path').requiredOption('--value <json>', 'JSON value').option('--layer <layer>', 'user or project')).action((options) => {
|
|
24
|
+
const parsedLayer = parseConfigLayer(options.layer);
|
|
25
|
+
if (parsedLayer === null) {
|
|
26
|
+
printInvalidConfigLayer(io, 'config.set', options.json);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
let parsed;
|
|
30
|
+
try {
|
|
31
|
+
parsed = JSON.parse(options.value);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
printResult(io, fail('config.set', 'INVALID_JSON', 'Could not parse value as JSON', {}, ['Use valid JSON: --value \'{"key":"value"}\'']), options.json);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
setConfig({ key: options.key, value: parsed, layer: parsedLayer ?? 'user' });
|
|
40
|
+
const value = isSensitiveConfigPath(options.key) ? '***' : redactConfigSecrets(parsed);
|
|
41
|
+
printResult(io, ok('config.set', { key: options.key, value }), options.json);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
printConfigSetError(io, error, options.json);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function printConfigSetError(io, error, asJson) {
|
|
49
|
+
const message = getErrorMessage(error);
|
|
50
|
+
if (message === 'Sensitive config keys must be stored in the user config layer') {
|
|
51
|
+
printResult(io, fail('config.set', 'SECRET_CONFIG_REQUIRES_USER_LAYER', message, {}, ['Use --layer user or peaks config provider minimax set']), asJson);
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (message === 'Project config not found') {
|
|
56
|
+
printResult(io, fail('config.set', 'PROJECT_CONFIG_NOT_FOUND', message, {}, ['Create a safe .peaks/config.json in the project or use --layer user']), asJson);
|
|
57
|
+
process.exitCode = 1;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (message === 'MiniMax base URL must be the MiniMax HTTPS endpoint without embedded credentials') {
|
|
61
|
+
printResult(io, fail('config.set', 'INVALID_MINIMAX_BASE_URL', message, {}, ['Use a MiniMax Anthropic-compatible HTTPS endpoint']), asJson);
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
printResult(io, fail('config.set', 'CONFIG_SET_FAILED', message, {}, ['Check the config key and layer, then retry']), asJson);
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
}
|
|
68
|
+
function registerMiniMaxProviderCommands(config, io) {
|
|
69
|
+
const minimaxProvider = config.command('provider').description('Manage model provider settings').command('minimax').description('Manage MiniMax provider settings');
|
|
70
|
+
addJsonOption(minimaxProvider.command('set').description('Set MiniMax provider settings in user config').option('--base-url <url>', 'MiniMax Anthropic-compatible base URL')).action((options) => {
|
|
71
|
+
const baseUrl = options.baseUrl?.trim();
|
|
72
|
+
const apiKey = process.env.MINIMAX_API_KEY?.trim();
|
|
73
|
+
if (!baseUrl && !apiKey) {
|
|
74
|
+
printResult(io, fail('config.provider.minimax.set', 'MINIMAX_PROVIDER_NO_VALUES', 'Provide --base-url and set MINIMAX_API_KEY', {}, ['Export MINIMAX_API_KEY and rerun peaks config provider minimax set --base-url <url>']), options.json);
|
|
75
|
+
process.exitCode = 1;
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (baseUrl && !isMiniMaxHttpsUrl(baseUrl)) {
|
|
79
|
+
printResult(io, fail('config.provider.minimax.set', 'INVALID_MINIMAX_BASE_URL', 'MiniMax base URL must be the MiniMax HTTPS endpoint without embedded credentials', {}, ['Use a MiniMax Anthropic-compatible HTTPS endpoint']), options.json);
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const input = {};
|
|
85
|
+
if (baseUrl)
|
|
86
|
+
input.baseUrl = baseUrl;
|
|
87
|
+
if (apiKey)
|
|
88
|
+
input.apiKey = apiKey;
|
|
89
|
+
const status = setMiniMaxProviderConfig(input);
|
|
90
|
+
printResult(io, ok('config.provider.minimax.set', status), options.json);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
printMiniMaxProviderSetError(io, error, options.json);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
addJsonOption(minimaxProvider.command('get').description('Show redacted MiniMax provider settings')).action((options) => {
|
|
97
|
+
const configValue = getMiniMaxProviderConfig();
|
|
98
|
+
const status = getMiniMaxProviderStatus();
|
|
99
|
+
printResult(io, ok('config.provider.minimax.get', { ...redactConfigSecrets(configValue, 'providers.minimax'), ...status }), options.json);
|
|
100
|
+
});
|
|
101
|
+
addJsonOption(minimaxProvider.command('status').description('Show MiniMax provider configuration status')).action((options) => {
|
|
102
|
+
printResult(io, ok('config.provider.minimax.status', getMiniMaxProviderStatus()), options.json);
|
|
103
|
+
});
|
|
104
|
+
addJsonOption(minimaxProvider.command('test').description('Run a redacted MiniMax provider smoke test').option('--model <model>', 'model name for the smoke test', 'MiniMax-M2.7')).action(async (options) => {
|
|
105
|
+
try {
|
|
106
|
+
const result = await testMiniMaxProvider(getMiniMaxProviderConfig(), { model: options.model });
|
|
107
|
+
const safeResult = summarizeMiniMaxSmokeResult(result);
|
|
108
|
+
if (!result.configured) {
|
|
109
|
+
printResult(io, fail('config.provider.minimax.test', 'MINIMAX_PROVIDER_NOT_CONFIGURED', 'MiniMax provider requires baseUrl and apiKey in user config', safeResult, ['Export MINIMAX_API_KEY or set MINIMAX_API_KEY']), options.json);
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
printResult(io, result.ok ? ok('config.provider.minimax.test', safeResult) : fail('config.provider.minimax.test', 'MINIMAX_PROVIDER_TEST_FAILED', 'MiniMax provider smoke test failed', safeResult, ['Check the MiniMax base URL, API key, and model name']), options.json);
|
|
114
|
+
if (!result.ok)
|
|
115
|
+
process.exitCode = 1;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
printResult(io, fail('config.provider.minimax.test', 'MINIMAX_PROVIDER_TEST_FAILED', redactSensitiveErrorMessage(getErrorMessage(error)), {}, ['Check network connectivity and MiniMax provider settings']), options.json);
|
|
119
|
+
process.exitCode = 1;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function printMiniMaxProviderSetError(io, error, asJson) {
|
|
124
|
+
if (getErrorMessage(error) === 'MiniMax base URL must be the MiniMax HTTPS endpoint without embedded credentials') {
|
|
125
|
+
printResult(io, fail('config.provider.minimax.set', 'INVALID_MINIMAX_BASE_URL', 'MiniMax base URL must be the MiniMax HTTPS endpoint without embedded credentials', {}, ['Use a MiniMax Anthropic-compatible HTTPS endpoint']), asJson);
|
|
126
|
+
process.exitCode = 1;
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
printResult(io, fail('config.provider.minimax.set', 'MINIMAX_PROVIDER_SET_FAILED', getErrorMessage(error), {}, ['Check MiniMax provider settings and retry']), asJson);
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
}
|
|
132
|
+
function registerWorkspaceCommands(config, io) {
|
|
133
|
+
const configWorkspace = config.command('workspace').description('Manage workspaces');
|
|
134
|
+
addJsonOption(configWorkspace.command('list').description('List all workspaces')).action((options) => {
|
|
135
|
+
const cfg = readConfig();
|
|
136
|
+
printResult(io, ok('config.workspace.list', { currentWorkspace: cfg.currentWorkspace, workspaces: cfg.workspaces }), options.json);
|
|
137
|
+
});
|
|
138
|
+
addJsonOption(configWorkspace.command('add').description('Add a workspace').requiredOption('--id <id>', 'workspace identifier').requiredOption('--name <name>', 'workspace display name').requiredOption('--path <path>', 'workspace root path').option('--provider <provider>', 'artifact repo provider: github or gitlab').option('--repo-owner <owner>', 'artifact repo owner').option('--repo-name <name>', 'artifact repo name').option('--layer <layer>', 'user or project')).action((options) => {
|
|
139
|
+
const layer = parseConfigLayer(options.layer);
|
|
140
|
+
if (layer === null) {
|
|
141
|
+
printInvalidConfigLayer(io, 'config.workspace.add', options.json);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const artifactRepo = parseArtifactRepoInput(io, options, options.json);
|
|
145
|
+
if (artifactRepo === null)
|
|
146
|
+
return;
|
|
147
|
+
const workspace = { workspaceId: options.id, name: options.name, rootPath: options.path, installedCapabilityIds: [] };
|
|
148
|
+
const configLayer = layer ?? 'user';
|
|
149
|
+
if (artifactRepo) {
|
|
150
|
+
addWorkspace({ ...workspace, artifactRepo }, configLayer);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
addWorkspace(workspace, configLayer);
|
|
154
|
+
}
|
|
155
|
+
printResult(io, ok('config.workspace.add', { workspaceId: options.id, name: options.name, rootPath: options.path, artifactRepo }), options.json);
|
|
156
|
+
});
|
|
157
|
+
addJsonOption(configWorkspace.command('remove').description('Remove a workspace').requiredOption('--id <id>', 'workspace identifier').option('--layer <layer>', 'user or project')).action((options) => {
|
|
158
|
+
const layer = parseConfigLayer(options.layer);
|
|
159
|
+
if (layer === null) {
|
|
160
|
+
printInvalidConfigLayer(io, 'config.workspace.remove', options.json);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const configLayer = layer ?? 'user';
|
|
164
|
+
const removed = removeWorkspace(options.id, configLayer);
|
|
165
|
+
if (removed) {
|
|
166
|
+
printResult(io, ok('config.workspace.remove', { workspaceId: options.id }), options.json);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
printWorkspaceNotFound(io, 'config.workspace.remove', `Workspace ${options.id} not found`, options.json);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
addJsonOption(configWorkspace.command('switch').description('Switch current workspace').requiredOption('--id <id>', 'workspace identifier').option('--layer <layer>', 'user or project')).action((options) => {
|
|
173
|
+
const layer = parseConfigLayer(options.layer);
|
|
174
|
+
if (layer === null) {
|
|
175
|
+
printInvalidConfigLayer(io, 'config.workspace.switch', options.json);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const configLayer = layer ?? 'user';
|
|
179
|
+
const switched = setCurrentWorkspace(options.id, configLayer);
|
|
180
|
+
if (switched) {
|
|
181
|
+
printResult(io, ok('config.workspace.switch', { currentWorkspace: options.id }), options.json);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
printWorkspaceNotFound(io, 'config.workspace.switch', `Workspace ${options.id} not found`, options.json);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
function parseArtifactRepoInput(io, options, asJson) {
|
|
189
|
+
const hasArtifactRepoInput = options.provider !== undefined || options.repoOwner !== undefined || options.repoName !== undefined;
|
|
190
|
+
if (!hasArtifactRepoInput)
|
|
191
|
+
return undefined;
|
|
192
|
+
if (!options.provider || !options.repoOwner || !options.repoName) {
|
|
193
|
+
printResult(io, fail('config.workspace.add', 'INVALID_ARTIFACT_REPO_CONFIG', 'Artifact repo config requires --provider, --repo-owner, and --repo-name together', {}, ['Provide all three artifact repo options together, or omit them all']), asJson);
|
|
194
|
+
process.exitCode = 1;
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
if (!isArtifactProvider(options.provider)) {
|
|
198
|
+
printResult(io, fail('config.workspace.add', 'UNSUPPORTED_ARTIFACT_PROVIDER', `Unsupported provider ${options.provider}`, {}, ['Use --provider github or --provider gitlab']), asJson);
|
|
199
|
+
process.exitCode = 1;
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
if (!isArtifactRepoSegment(options.repoOwner) || !isArtifactRepoSegment(options.repoName)) {
|
|
203
|
+
printResult(io, fail('config.workspace.add', 'INVALID_ARTIFACT_REPO_CONFIG', 'Artifact repo owner and name must use safe GitHub/GitLab path segments', {}, ['Use letters, numbers, dots, underscores, or hyphens without path traversal']), asJson);
|
|
204
|
+
process.exitCode = 1;
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
return { provider: options.provider, owner: options.repoOwner, name: options.repoName };
|
|
208
|
+
}
|
|
209
|
+
function printWorkspaceNotFound(io, command, message, asJson) {
|
|
210
|
+
printResult(io, fail(command, 'WORKSPACE_NOT_FOUND', message, {}, ['List workspaces with: peaks config workspace list']), asJson);
|
|
211
|
+
process.exitCode = 1;
|
|
212
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { createArtifactInitPlan, getArtifactStatus, createGuidedArtifactSetup } from '../../services/artifacts/artifact-service.js';
|
|
2
|
+
import { getArtifactWorkspaceStatus, planArtifactSync } from '../../services/artifacts/workspace-service.js';
|
|
3
|
+
import { executeProjectMemoryBackup, executeProjectMemoryExtract, summarizeProjectMemoryBackupResult, summarizeProjectMemoryExtractResult } from '../../services/memory/project-memory-service.js';
|
|
4
|
+
import { executeProjectStandardsInit, executeProjectStandardsUpdate, summarizeProjectStandardsInitResult, summarizeProjectStandardsUpdateResult } from '../../services/standards/project-standards-service.js';
|
|
5
|
+
import { listProfiles } from '../../services/profiles/profile-service.js';
|
|
6
|
+
import { planProxyTest } from '../../services/proxy/proxy-service.js';
|
|
7
|
+
import { runDoctor } from '../../services/doctor/doctor-service.js';
|
|
8
|
+
import { listSkills } from '../../services/skills/skill-registry.js';
|
|
9
|
+
import { fail, ok } from '../../shared/result.js';
|
|
10
|
+
import { addJsonOption, failUnsupportedNonDryRun, getErrorMessage, isArtifactProvider, isArtifactSetupStep, printResult } from '../cli-helpers.js';
|
|
11
|
+
export function registerCoreAndArtifactCommands(program, io) {
|
|
12
|
+
addJsonOption(program.command('doctor').description('Run repository doctor checks')).action(async (options) => {
|
|
13
|
+
const report = await runDoctor();
|
|
14
|
+
const result = report.summary.ok
|
|
15
|
+
? ok('doctor', report)
|
|
16
|
+
: fail('doctor', 'DOCTOR_FAILED', 'One or more doctor checks failed', report, ['Fix failed checks and rerun peaks doctor']);
|
|
17
|
+
printResult(io, result, options.json);
|
|
18
|
+
if (!report.summary.ok) {
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const skill = program.command('skill').description('Manage Peaks skills');
|
|
23
|
+
addJsonOption(skill.command('list').description('List skills derived from skills/*/SKILL.md')).action(async (options) => {
|
|
24
|
+
const skills = await listSkills();
|
|
25
|
+
printResult(io, ok('skill.list', { skills }), options.json);
|
|
26
|
+
});
|
|
27
|
+
addJsonOption(skill.command('doctor').description('Run skill-related doctor checks')).action(async (options) => {
|
|
28
|
+
const report = await runDoctor();
|
|
29
|
+
const skillChecks = report.checks.filter((check) => check.id.startsWith('skill'));
|
|
30
|
+
const failed = skillChecks.filter((check) => !check.ok).length;
|
|
31
|
+
printResult(io, ok('skill.doctor', { checks: skillChecks, ok: failed === 0 }), options.json);
|
|
32
|
+
if (failed > 0) {
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
const profile = program.command('profile').description('Manage runtime profiles');
|
|
37
|
+
addJsonOption(profile.command('list').description('List available profiles')).action((options) => {
|
|
38
|
+
printResult(io, ok('profile.list', { profiles: listProfiles() }), options.json);
|
|
39
|
+
});
|
|
40
|
+
const standards = program.command('standards').description('Manage project-local coding standards');
|
|
41
|
+
addJsonOption(standards
|
|
42
|
+
.command('init')
|
|
43
|
+
.description('Initialize project-local coding standards for Peaks skill preflight')
|
|
44
|
+
.requiredOption('--project <path>', 'target project root')
|
|
45
|
+
.option('--language <language>', 'standards language pack')
|
|
46
|
+
.option('--dry-run', 'preview writes without changing files')
|
|
47
|
+
.option('--apply', 'write missing standards into the target project')).action((options) => {
|
|
48
|
+
if (options.dryRun === true && options.apply === true) {
|
|
49
|
+
printResult(io, fail('standards.init', 'INVALID_STANDARDS_INIT_FLAGS', 'Use either --dry-run or --apply, not both', {}, ['Run without --apply to preview writes, or omit --dry-run when applying standards']), options.json);
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const result = executeProjectStandardsInit({ projectRoot: options.project, ...(options.language !== undefined ? { language: options.language } : {}), apply: options.apply === true });
|
|
55
|
+
printResult(io, ok('standards.init', summarizeProjectStandardsInitResult(result)), options.json);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
printResult(io, fail('standards.init', 'STANDARDS_INIT_FAILED', getErrorMessage(error), {}, ['Check the project path and existing .claude/rules directory before retrying']), options.json);
|
|
59
|
+
process.exitCode = 1;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
addJsonOption(standards
|
|
63
|
+
.command('update')
|
|
64
|
+
.description('Append managed standards metadata to an existing CLAUDE.md without rewriting the body')
|
|
65
|
+
.requiredOption('--project <path>', 'target project root')
|
|
66
|
+
.option('--language <language>', 'standards language pack')
|
|
67
|
+
.option('--dry-run', 'preview writes without changing files')
|
|
68
|
+
.option('--apply', 'append managed metadata to the target project')).action((options) => {
|
|
69
|
+
if (options.dryRun === true && options.apply === true) {
|
|
70
|
+
printResult(io, fail('standards.update', 'INVALID_STANDARDS_UPDATE_FLAGS', 'Use either --dry-run or --apply, not both', {}, ['Run without --apply to preview writes, or omit --dry-run when applying standards updates']), options.json);
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const result = executeProjectStandardsUpdate({ projectRoot: options.project, ...(options.language !== undefined ? { language: options.language } : {}), apply: options.apply === true });
|
|
76
|
+
const summary = summarizeProjectStandardsUpdateResult(result);
|
|
77
|
+
const response = summary.reviewSuggestions.length > 0
|
|
78
|
+
? fail('standards.update', 'STANDARDS_UPDATE_REVIEW_REQUIRED', 'Standards update requires manual review', summary, summary.reviewSuggestions)
|
|
79
|
+
: ok('standards.update', summary);
|
|
80
|
+
printResult(io, response, options.json);
|
|
81
|
+
if (summary.reviewSuggestions.length > 0) {
|
|
82
|
+
process.exitCode = 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
printResult(io, fail('standards.update', 'STANDARDS_UPDATE_FAILED', getErrorMessage(error), {}, ['Check the project path, CLAUDE.md contents, and existing .claude/rules directory before retrying']), options.json);
|
|
87
|
+
process.exitCode = 1;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
const memory = program.command('memory').description('Manage project-local Peaks memory');
|
|
91
|
+
addJsonOption(memory
|
|
92
|
+
.command('extract')
|
|
93
|
+
.description('Extract stable project memory from skill artifacts into project .claude/memory')
|
|
94
|
+
.requiredOption('--project <path>', 'target project root')
|
|
95
|
+
.requiredOption('--artifact <path...>', 'skill artifact paths inside the project')
|
|
96
|
+
.option('--dry-run', 'preview writes without changing files', true)
|
|
97
|
+
.option('--apply', 'write extracted memories into project .claude/memory')).action((options) => {
|
|
98
|
+
try {
|
|
99
|
+
const result = executeProjectMemoryExtract({ projectRoot: options.project, artifactPaths: options.artifact, apply: options.apply === true });
|
|
100
|
+
printResult(io, ok('memory.extract', summarizeProjectMemoryExtractResult(result)), options.json);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
printResult(io, fail('memory.extract', 'MEMORY_EXTRACT_FAILED', getErrorMessage(error), {}, ['Check artifact paths and remove secrets before extracting memory']), options.json);
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
addJsonOption(memory
|
|
108
|
+
.command('sync')
|
|
109
|
+
.description('Back up project .claude/memory into the artifact workspace')
|
|
110
|
+
.requiredOption('--project <path>', 'target project root')
|
|
111
|
+
.requiredOption('--workspace <path>', 'artifact workspace path')
|
|
112
|
+
.option('--dry-run', 'preview copies without changing files', true)
|
|
113
|
+
.option('--apply', 'copy project .claude/memory into artifact workspace backup')).action((options) => {
|
|
114
|
+
try {
|
|
115
|
+
const result = executeProjectMemoryBackup({ projectRoot: options.project, artifactWorkspacePath: options.workspace, apply: options.apply === true });
|
|
116
|
+
printResult(io, ok('memory.sync', summarizeProjectMemoryBackupResult(result)), options.json);
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
printResult(io, fail('memory.sync', 'MEMORY_SYNC_FAILED', getErrorMessage(error), {}, ['Use an artifact workspace outside the project root']), options.json);
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
const proxy = program.command('proxy').description('Manage proxy settings');
|
|
124
|
+
addJsonOption(proxy
|
|
125
|
+
.command('test')
|
|
126
|
+
.description('Plan or run a proxy connectivity test')
|
|
127
|
+
.requiredOption('--proxy <url>', 'proxy URL')
|
|
128
|
+
.option('--target <url>', 'target URL', 'https://www.google.com')
|
|
129
|
+
.option('--dry-run', 'only print the planned command', true)
|
|
130
|
+
.option('--no-dry-run', 'unsupported: do not execute connectivity tests from this CLI')).action((options) => {
|
|
131
|
+
if (options.dryRun === false) {
|
|
132
|
+
failUnsupportedNonDryRun(io, 'proxy.test', options.json);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const plan = planProxyTest(options.proxy, options.target, true);
|
|
137
|
+
printResult(io, ok('proxy.test', plan), options.json);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
printResult(io, fail('proxy.test', 'INVALID_PROXY', getErrorMessage(error), {}, ['Use a proxy URL starting with http:// or https://']), options.json);
|
|
141
|
+
process.exitCode = 1;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
const artifacts = program.command('artifacts').description('Manage intermediate artifact repositories');
|
|
145
|
+
addJsonOption(artifacts.command('status').description('Show artifact repository status')).action((options) => {
|
|
146
|
+
printResult(io, ok('artifacts.status', getArtifactStatus()), options.json);
|
|
147
|
+
});
|
|
148
|
+
addJsonOption(artifacts
|
|
149
|
+
.command('init')
|
|
150
|
+
.description('Plan remote-first artifact repository initialization')
|
|
151
|
+
.requiredOption('--provider <provider>', 'artifact provider: github or gitlab')
|
|
152
|
+
.requiredOption('--name <name>', 'remote repository name')
|
|
153
|
+
.option('--path <path>', 'local artifact working copy path', '.peaks-artifacts')
|
|
154
|
+
.option('--dry-run', 'preview without creating repositories or files', true)
|
|
155
|
+
.option('--no-dry-run', 'unsupported: do not create repositories or files from this CLI')).action((options) => {
|
|
156
|
+
if (options.dryRun === false) {
|
|
157
|
+
failUnsupportedNonDryRun(io, 'artifacts.init', options.json);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (!isArtifactProvider(options.provider)) {
|
|
161
|
+
printResult(io, fail('artifacts.init', 'UNSUPPORTED_ARTIFACT_PROVIDER', `Unsupported provider ${options.provider}`, {}, ['Use --provider github or --provider gitlab']), options.json);
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
printResult(io, ok('artifacts.init', createArtifactInitPlan({
|
|
166
|
+
provider: options.provider,
|
|
167
|
+
name: options.name,
|
|
168
|
+
localPath: options.path,
|
|
169
|
+
dryRun: true
|
|
170
|
+
})), options.json);
|
|
171
|
+
});
|
|
172
|
+
addJsonOption(artifacts
|
|
173
|
+
.command('sync')
|
|
174
|
+
.description('Plan sync between local artifact workspace and remote repository')
|
|
175
|
+
.option('--workspace <id>', 'workspace identifier (uses current if not specified)')
|
|
176
|
+
.option('--dry-run', 'preview sync plan without executing', true)
|
|
177
|
+
.option('--no-dry-run', 'unsupported: do not sync from this CLI')).action((options) => {
|
|
178
|
+
if (options.dryRun === false) {
|
|
179
|
+
failUnsupportedNonDryRun(io, 'artifacts.sync', options.json);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
printResult(io, ok('artifacts.sync', planArtifactSync(options.workspace, true)), options.json);
|
|
183
|
+
});
|
|
184
|
+
addJsonOption(artifacts.command('workspace').description('Show artifact workspace status for current or specified workspace').option('--workspace <id>', 'workspace identifier')).action((options) => {
|
|
185
|
+
printResult(io, ok('artifacts.workspace', getArtifactWorkspaceStatus(options.workspace)), options.json);
|
|
186
|
+
});
|
|
187
|
+
addJsonOption(artifacts.command('setup').description('Interactive guided artifact repository setup').option('--step <step>', 'start from specific step: detect, configure, validate, complete')).action((options) => {
|
|
188
|
+
const requestedStep = options.step;
|
|
189
|
+
const setup = createGuidedArtifactSetup();
|
|
190
|
+
if (requestedStep) {
|
|
191
|
+
if (!isArtifactSetupStep(requestedStep)) {
|
|
192
|
+
printResult(io, fail('artifacts.setup', 'INVALID_ARTIFACT_SETUP_STEP', `Invalid artifact setup step ${requestedStep}`, {}, ['Use one of: detect, configure, validate, complete']), options.json);
|
|
193
|
+
process.exitCode = 1;
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
setup.step = requestedStep;
|
|
197
|
+
}
|
|
198
|
+
printResult(io, ok('artifacts.setup', setup), options.json);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createArtifactRetentionReport, createChangeImpact, getChangeTraceabilityStatus, getScHelpText, recordCommitBoundary, validateArtifactRetention } from '../../services/sc/sc-service.js';
|
|
2
|
+
import { ok } from '../../shared/result.js';
|
|
3
|
+
import { addJsonOption, multipleOption, printResult } from '../cli-helpers.js';
|
|
4
|
+
export function registerSCCommands(program, io) {
|
|
5
|
+
const sc = program.command('sc').description('Source control and change traceability (peaks-sc integration)');
|
|
6
|
+
registerSCStatusCommands(sc, io);
|
|
7
|
+
registerSCArtifactCommands(sc, io);
|
|
8
|
+
}
|
|
9
|
+
function registerSCStatusCommands(sc, io) {
|
|
10
|
+
addJsonOption(sc.command('status').description('Show change traceability status')).action((options) => {
|
|
11
|
+
printResult(io, ok('sc.status', getChangeTraceabilityStatus()), options.json);
|
|
12
|
+
});
|
|
13
|
+
addJsonOption(sc.command('help').description('Show peaks-sc help text')).action((options) => {
|
|
14
|
+
const helpText = getScHelpText().join('\n');
|
|
15
|
+
if (options.json) {
|
|
16
|
+
printResult(io, ok('sc.help', { helpText }), options.json);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
io.stdout(helpText);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function registerSCArtifactCommands(sc, io) {
|
|
24
|
+
addJsonOption(sc.command('impact').description('Generate change impact artifact').requiredOption('--change-id <id>', 'change identifier').option('--module <module>', 'affected module', multipleOption).option('--file <file>', 'affected file', multipleOption)).action((options) => {
|
|
25
|
+
const impactOptions = { changeId: options.changeId, ...(options.module ? { affectedModules: options.module } : {}), ...(options.file ? { affectedFiles: options.file } : {}) };
|
|
26
|
+
printResult(io, ok('sc.impact', createChangeImpact(impactOptions)), options.json);
|
|
27
|
+
});
|
|
28
|
+
addJsonOption(sc.command('retention').description('Create artifact retention report').requiredOption('--slice-id <id>', 'slice identifier').option('--prd <artifact>', 'PRD artifact path', multipleOption).option('--rd <artifact>', 'RD artifact path', multipleOption).option('--qa <artifact>', 'QA artifact path', multipleOption).option('--coverage <artifact>', 'coverage artifact path', multipleOption).option('--review <artifact>', 'review artifact path', multipleOption).option('--code <file>', 'code file path', multipleOption)).action((options) => {
|
|
29
|
+
printResult(io, ok('sc.retention', createArtifactRetentionReport({ sliceId: options.sliceId, ...(options.prd ? { prdArtifacts: options.prd } : {}), ...(options.rd ? { rdArtifacts: options.rd } : {}), ...(options.qa ? { qaArtifacts: options.qa } : {}), ...(options.coverage ? { coverageArtifacts: options.coverage } : {}), ...(options.review ? { reviewArtifacts: options.review } : {}), ...(options.code ? { codeChanges: options.code } : {}) })), options.json);
|
|
30
|
+
});
|
|
31
|
+
addJsonOption(sc.command('validate').description('Validate artifact retention for a slice').requiredOption('--slice-id <id>', 'slice identifier')).action((options) => {
|
|
32
|
+
printResult(io, ok('sc.validate', validateArtifactRetention(options.sliceId)), options.json);
|
|
33
|
+
});
|
|
34
|
+
addJsonOption(sc.command('boundary').description('Record commit boundary for a slice').requiredOption('--slice-id <id>', 'slice identifier').option('--artifact <path>', 'artifact path', multipleOption).option('--code <file>', 'code file path', multipleOption)).action((options) => {
|
|
35
|
+
printResult(io, ok('sc.boundary', recordCommitBoundary({ sliceId: options.sliceId, ...(options.artifact ? { artifacts: options.artifact } : {}), ...(options.code ? { codeFiles: options.code } : {}) })), options.json);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { getMiniMaxProviderConfig } from '../../services/config/config-service.js';
|
|
2
|
+
import { runMiniMaxWorker } from '../../services/providers/minimax-worker-service.js';
|
|
3
|
+
import { fail, ok } from '../../shared/result.js';
|
|
4
|
+
import { addJsonOption, getErrorMessage, printResult, redactSensitiveErrorMessage, summarizeMiniMaxWorkerResult } from '../cli-helpers.js';
|
|
5
|
+
function addMiniMaxWorkerOptions(command) {
|
|
6
|
+
return addJsonOption(command
|
|
7
|
+
.description('Run a single MiniMax coding and unit-test execution worker')
|
|
8
|
+
.requiredOption('--change-id <id>', 'change identifier')
|
|
9
|
+
.requiredOption('--goal <goal>', 'execution goal')
|
|
10
|
+
.requiredOption('--coding-task <task>', 'coding execution task')
|
|
11
|
+
.requiredOption('--unit-test-task <task>', 'unit-test execution task')
|
|
12
|
+
.option('--model <model>', 'model name for the worker', 'MiniMax-M2.7')
|
|
13
|
+
.option('--confirm', 'confirm that worker inputs may be sent to the external MiniMax provider once and only return a review handoff', false));
|
|
14
|
+
}
|
|
15
|
+
async function runMiniMaxWorkerCommand(io, options) {
|
|
16
|
+
if (!options.confirm) {
|
|
17
|
+
printResult(io, fail('worker.minimax', 'CONFIRMATION_REQUIRED', 'This worker only runs with explicit confirmation because inputs may be sent to the external MiniMax provider', {}, ['Rerun with --confirm after removing secrets from worker inputs']), options.json);
|
|
18
|
+
process.exitCode = 1;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const changeId = options.changeId.trim();
|
|
22
|
+
const goal = options.goal.trim();
|
|
23
|
+
const codingTask = options.codingTask.trim();
|
|
24
|
+
const unitTestTask = options.unitTestTask.trim();
|
|
25
|
+
if (!changeId || !goal || !codingTask || !unitTestTask) {
|
|
26
|
+
printResult(io, fail('worker.minimax', 'INVALID_WORKER_INPUT', 'Worker inputs must be non-empty', {}, ['Provide non-empty values for --change-id, --goal, --coding-task, and --unit-test-task']), options.json);
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const result = await runMiniMaxWorker(getMiniMaxProviderConfig(), { changeId, goal, codingTask, unitTestTask, model: options.model });
|
|
32
|
+
const safeResult = summarizeMiniMaxWorkerResult(result);
|
|
33
|
+
if (!result.provider.configured) {
|
|
34
|
+
printResult(io, fail('worker.minimax', 'MINIMAX_PROVIDER_NOT_CONFIGURED', 'MiniMax provider requires baseUrl and apiKey in user config', safeResult, ['Run peaks config provider minimax set --base-url <url> and either MINIMAX_API_KEY']), options.json);
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
printResult(io, result.provider.ok ? ok('worker.minimax', safeResult) : fail('worker.minimax', 'MINIMAX_WORKER_FAILED', 'MiniMax worker execution failed', safeResult, ['Check the MiniMax base URL, API key, and worker tasks']), options.json);
|
|
39
|
+
if (!result.provider.ok) {
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
printResult(io, fail('worker.minimax', 'MINIMAX_WORKER_FAILED', redactSensitiveErrorMessage(getErrorMessage(error)), {}, ['Check the MiniMax base URL, API key, and worker tasks']), options.json);
|
|
45
|
+
process.exitCode = 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function registerWorkerCommands(program, io) {
|
|
49
|
+
const worker = program.command('worker').description('Run controlled execution workers');
|
|
50
|
+
addMiniMaxWorkerOptions(worker.command('minimax')).action(async (options) => runMiniMaxWorkerCommand(io, options));
|
|
51
|
+
addMiniMaxWorkerOptions(program.command('minimax-worker')).action(async (options) => runMiniMaxWorkerCommand(io, options));
|
|
52
|
+
}
|