@aifabrix/builder 2.50.0 → 2.51.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +374 -0
- package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
- package/integration/hubspot-test/create-hubspot.js +1 -16
- package/jest.isolated-projects.js +77 -1
- package/jest.projects.js +5 -426
- package/lib/api/assistants.api.js +67 -0
- package/lib/api/datasources-extended.api.js +6 -6
- package/lib/api/evidence-authoring-helpers.js +267 -0
- package/lib/api/evidence-authoring.api.js +337 -0
- package/lib/api/evidence-kinds.api.js +128 -0
- package/lib/api/evidence.api.js +57 -1
- package/lib/api/index.js +24 -7
- package/lib/api/pipeline.api.js +47 -3
- package/lib/api/records-bulk.api.js +28 -3
- package/lib/api/resource-types.api.js +4 -4
- package/lib/api/roles.api.js +121 -0
- package/lib/api/types/evidence-kinds.types.js +42 -0
- package/lib/api/types/evidence.types.js +156 -8
- package/lib/api/types/roles.types.js +36 -0
- package/lib/api/work.api.js +283 -0
- package/lib/app/certification-verify-rows.js +1 -1
- package/lib/app/run-deploy-job.js +108 -0
- package/lib/app/run-helpers.js +10 -3
- package/lib/app/run.js +8 -0
- package/lib/app/show.js +2 -2
- package/lib/certification/merge-certification-from-artifact.js +1 -1
- package/lib/channels/add-channel.js +54 -23
- package/lib/channels/approval-guides/chatgpt.js +8 -7
- package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
- package/lib/channels/channel-artifact-generator.js +16 -3
- package/lib/channels/channel-credential.js +3 -1
- package/lib/channels/channel-probe-evidence.js +79 -0
- package/lib/channels/channel-probe.js +265 -13
- package/lib/channels/channel-runtime-resolver.js +120 -29
- package/lib/channels/channel-status-display.js +44 -0
- package/lib/channels/channel-targets.js +7 -0
- package/lib/channels/chatgpt-runtime-contract.js +29 -0
- package/lib/channels/microsoft-copilot-package.js +280 -0
- package/lib/channels/runtime-tool-catalog.js +165 -0
- package/lib/cli/index.js +6 -0
- package/lib/cli/setup-app.js +26 -5
- package/lib/cli/setup-dev.js +23 -7
- package/lib/cli/setup-external-system-help.js +8 -2
- package/lib/cli/setup-external-system.js +12 -0
- package/lib/cli/setup-utility-help-after.js +12 -0
- package/lib/cli/setup-utility-validate.js +41 -2
- package/lib/commands/app-test.js +2 -14
- package/lib/commands/datasource-load-export-cli.js +6 -1
- package/lib/commands/deploy-gate-failure-details.js +23 -0
- package/lib/commands/deploy-gate-orchestrator.js +64 -18
- package/lib/commands/dev-cli-handlers.js +6 -3
- package/lib/commands/dev-down.js +2 -6
- package/lib/commands/dev-init.js +7 -109
- package/lib/commands/dev-refresh.js +197 -0
- package/lib/commands/evidence-kind.js +478 -0
- package/lib/commands/governance-command-action.js +4 -2
- package/lib/commands/governance-generate-external.js +56 -21
- package/lib/commands/lifecycle-external.js +10 -4
- package/lib/commands/repair-datasource-apply.js +10 -1
- package/lib/commands/repair-datasource-run.js +4 -2
- package/lib/commands/repair-datasource-test-payload.js +80 -19
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
- package/lib/commands/repair-internal.js +9 -1
- package/lib/commands/repair-openapi-export.js +1 -1
- package/lib/commands/repair-openapi-sync.js +43 -18
- package/lib/commands/resource-type.js +101 -18
- package/lib/commands/role-assistant.js +313 -0
- package/lib/commands/role.js +452 -0
- package/lib/commands/setup.js +1 -1
- package/lib/commands/upload-data-sync-finalize.js +5 -4
- package/lib/commands/upload-sidecar-followups.js +144 -47
- package/lib/commands/upload.js +43 -6
- package/lib/commands/validate-json.js +230 -0
- package/lib/commands/verify-governance-combined-external.js +73 -9
- package/lib/commands/verify-governance-db.js +80 -25
- package/lib/commands/verify-governance-external.js +29 -5
- package/lib/commands/verify-operations-step-plan.js +78 -40
- package/lib/commands/wizard-core-helpers.js +7 -3
- package/lib/commands/wizard-core.js +78 -9
- package/lib/core/audit-logger.js +1 -1
- package/lib/core/secrets-load.js +1 -3
- package/lib/datasource/bulk-loader-run-batches.js +4 -2
- package/lib/datasource/bulk-loader-service.js +5 -1
- package/lib/datasource/capability/relate-operations.js +1 -1
- package/lib/datasource/datasource-validate-summary.js +2 -2
- package/lib/datasource/validate.js +13 -6
- package/lib/external-system/deploy-helpers.js +35 -1
- package/lib/external-system/deploy.js +23 -10
- package/lib/external-system/download-helpers.js +111 -2
- package/lib/external-system/download-role-assistant.js +55 -0
- package/lib/external-system/download.js +45 -26
- package/lib/external-system/test-helpers.js +1 -1
- package/lib/external-system/test.js +39 -3
- package/lib/generator/builders.js +3 -0
- package/lib/generator/helpers.js +13 -5
- package/lib/generator/split-variables.js +9 -3
- package/lib/generator/wizard.js +51 -4
- package/lib/infrastructure/helpers-docker-check.js +6 -0
- package/lib/infrastructure/helpers.js +1 -1
- package/lib/lifecycle/access-control-abac.js +121 -0
- package/lib/lifecycle/lifecycle-governance-options.js +4 -1
- package/lib/lifecycle/product-model.js +3 -2
- package/lib/lifecycle/report-display.js +14 -2
- package/lib/programmatic/auth-config.js +3 -2
- package/lib/programmatic/bearer-auth.js +1 -1
- package/lib/programmatic/capability-registry.js +20 -1
- package/lib/programmatic/command-options.js +1 -0
- package/lib/programmatic/enterprise-mcp-client.js +18 -2
- package/lib/programmatic/index.js +4 -0
- package/lib/programmatic/manifest-patch-section.js +48 -9
- package/lib/programmatic/manifest-section-registry-data.js +3 -2
- package/lib/programmatic/manifest-section-registry.js +18 -1
- package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
- package/lib/programmatic/openapi-component-schemas.js +16 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +55 -5
- package/lib/programmatic/openapi-evidence-schemas.js +161 -0
- package/lib/programmatic/openapi-manifest-schemas.js +6 -2
- package/lib/programmatic/openapi-operation-bindings.js +99 -0
- package/lib/programmatic/openapi-request-schemas.js +36 -1
- package/lib/programmatic/openapi-result-schemas.js +29 -12
- package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
- package/lib/programmatic/openapi-schema-descriptions-core.js +6 -3
- package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
- package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
- package/lib/programmatic/openapi-schema-helpers.js +16 -1
- package/lib/programmatic/openapi-spec.js +48 -29
- package/lib/programmatic/orchestration-openapi-meta.js +5 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +89 -2
- package/lib/programmatic/run-certify.js +15 -2
- package/lib/programmatic/run-deploy.js +74 -0
- package/lib/programmatic/run-evidence-authoring.js +80 -0
- package/lib/programmatic/run-protection.js +124 -0
- package/lib/programmatic/run-repository-emcp.js +11 -3
- package/lib/programmatic/run-template-workspace.js +42 -2
- package/lib/programmatic/workspace-context.js +6 -0
- package/lib/protection/auth-context.js +48 -6
- package/lib/protection/paths.js +22 -0
- package/lib/protection/run-protection-create-helpers.js +22 -1
- package/lib/protection/run-protection-create.js +1 -1
- package/lib/protection/sync-after-upload.js +1 -1
- package/lib/resolvers/evidence-kind-file.js +230 -0
- package/lib/resolvers/resource-type-file.js +36 -1
- package/lib/resolvers/role-file.js +227 -0
- package/lib/role-assistant/evidence-sync.js +450 -0
- package/lib/role-assistant/github-workflow.js +96 -0
- package/lib/role-assistant/knowledge-sync.js +465 -0
- package/lib/role-assistant/settings.js +126 -0
- package/lib/role-assistant/test-cases-evaluate.js +170 -0
- package/lib/role-assistant/test-cases-honesty.js +184 -0
- package/lib/role-assistant/test-cases.js +364 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +203 -0
- package/lib/role-assistant/test-runner-workhub.js +385 -0
- package/lib/role-assistant/test-runner.js +500 -0
- package/lib/schema/application-schema.json +36 -2
- package/lib/schema/deployment-rules.yaml +1 -0
- package/lib/schema/external-datasource.schema.json +121 -4
- package/lib/schema/external-system.schema.json +20 -6
- package/lib/schema/infra.parameter.yaml +45 -1
- package/lib/schema/role-assistant-settings.schema.json +108 -0
- package/lib/schema/type/credential-field-registry.json +19 -3
- package/lib/utils/api.js +52 -21
- package/lib/utils/app-path-resolve.js +72 -24
- package/lib/utils/app-register-config.js +4 -3
- package/lib/utils/authentication-shape.js +3 -1
- package/lib/utils/cli-sync-options.js +59 -3
- package/lib/utils/cli-utils.js +11 -3
- package/lib/utils/deployment-validation.js +28 -3
- package/lib/utils/dev-ca-install.js +5 -6
- package/lib/utils/dev-config.js +2 -2
- package/lib/utils/dev-list-sort.js +145 -0
- package/lib/utils/dev-platform-tls.js +0 -63
- package/lib/utils/docker-build.js +46 -27
- package/lib/utils/docker-daemon-tls-ca.js +1 -1
- package/lib/utils/docker-exec.js +91 -6
- package/lib/utils/docker-run-ephemeral.js +55 -0
- package/lib/utils/enterprise-knowledge-paths.js +29 -12
- package/lib/utils/env-copy-keycloak.js +196 -0
- package/lib/utils/env-copy.js +35 -4
- package/lib/utils/error-formatters/error-parser.js +0 -3
- package/lib/utils/external-env-template.js +1 -1
- package/lib/utils/external-system-readiness-compact-blocks.js +28 -1
- package/lib/utils/external-system-readiness-compact-display.js +3 -0
- package/lib/utils/health-check-request.js +2 -3
- package/lib/utils/help-builder.js +4 -0
- package/lib/utils/image-name.js +22 -4
- package/lib/utils/logger.js +37 -4
- package/lib/utils/manifest-source-emit.js +1 -1
- package/lib/utils/paths.js +98 -26
- package/lib/utils/pipeline-upload-auth-retry.js +19 -3
- package/lib/utils/postgres-platform-bootstrap.js +24 -17
- package/lib/utils/postgres-wipe.js +5 -2
- package/lib/utils/remote-dev-auth.js +39 -4
- package/lib/utils/resolve-docker-image-ref.js +36 -6
- package/lib/utils/role-assistant-paths.js +98 -0
- package/lib/utils/schema-loader.js +41 -0
- package/lib/utils/schema-resolver.js +36 -4
- package/lib/utils/token-manager.js +47 -22
- package/lib/utils/upload-sync-options.js +17 -3
- package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
- package/lib/validation/external-manifest-validator.js +31 -8
- package/lib/validation/openapi-contract-surface-validator.js +4 -0
- package/lib/validation/validate-external-file.js +8 -1
- package/lib/validation/validator.js +6 -5
- package/package.json +35 -12
- package/scripts/export-builder-api-evidence.js +3 -3
- package/scripts/lib/plan-actor.js +2 -2
- package/scripts/lib/plan-meta.js +1 -1
- package/scripts/lib/plan-parse.js +1 -1
- package/scripts/lib/plan-prevalidate-gates.js +12 -1
- package/scripts/lib/plan-run-report.js +13 -2
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +10 -10
- package/templates/applications/dataplane/application.yaml +47 -17
- package/templates/applications/dataplane/env.template +28 -9
- package/templates/applications/dataplane/rbac.yaml +78 -2
- package/templates/applications/miso-controller/application.yaml +10 -1
- package/templates/applications/miso-controller/env.template +13 -8
- package/templates/applications/miso-controller/rbac.yaml +72 -0
- package/templates/channels/chatgpt/install.template.md.hbs +42 -24
- package/templates/channels/chatgpt/integration/README.md +10 -7
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
- package/templates/channels/chatgpt/integration/env.template +1 -1
- package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
- package/templates/channels/microsoft-copilot/integration/README.md +9 -7
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +1 -1
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
- package/templates/channels/slack/integration/slack-system.json +60 -2
- package/templates/python/requirements.txt +1 -1
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant CLI command group.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview role-assistant test command with portal deep-link output
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const logger = require('../utils/logger');
|
|
12
|
+
const { handleCommandError } = require('../utils/cli-utils');
|
|
13
|
+
const {
|
|
14
|
+
runLifecycleForExternalSystem,
|
|
15
|
+
resolveLifecycleAuth
|
|
16
|
+
} = require('./lifecycle-external');
|
|
17
|
+
const { lifecycleVerdictFromReport } = require('./lifecycle-command-action');
|
|
18
|
+
const { buildExternalSystemUiUrl } = require('../lifecycle/dataplane-ui-url');
|
|
19
|
+
const { VERDICT } = require('../lifecycle/product-model');
|
|
20
|
+
const { exitCodeFromVerdict } = require('../lifecycle/exit-codes');
|
|
21
|
+
const {
|
|
22
|
+
loadRoleAssistantTestCase,
|
|
23
|
+
evaluateRoleAssistantTestCase
|
|
24
|
+
} = require('../role-assistant/test-cases');
|
|
25
|
+
const {
|
|
26
|
+
isExecutableRoleAssistantCase,
|
|
27
|
+
runRoleAssistantCaseLifecycle,
|
|
28
|
+
mergeCaseExecutionIntoLifecycleResult,
|
|
29
|
+
lifecycleVerdictFromCaseExecution
|
|
30
|
+
} = require('../role-assistant/test-runner');
|
|
31
|
+
const { collectString } = require('./governance');
|
|
32
|
+
const {
|
|
33
|
+
sectionTitle,
|
|
34
|
+
headerKeyValue,
|
|
35
|
+
formatSuccessLine,
|
|
36
|
+
formatSuccessParagraph,
|
|
37
|
+
formatWarningLine,
|
|
38
|
+
formatBlockingError,
|
|
39
|
+
metadata
|
|
40
|
+
} = require('../utils/cli-test-layout-chalk');
|
|
41
|
+
|
|
42
|
+
function roleAssistantHelpAfter() {
|
|
43
|
+
return `
|
|
44
|
+
Examples:
|
|
45
|
+
$ aifabrix role-assistant test customer-support-bot
|
|
46
|
+
$ aifabrix role-assistant test customer-support-bot --case smoke
|
|
47
|
+
$ aifabrix role-assistant test customer-support-bot --case tests/customer-address-change.yaml
|
|
48
|
+
$ aifabrix role-assistant test customer-support-bot --subject-email ops@example.com
|
|
49
|
+
$ aifabrix role-assistant test customer-support-bot --json
|
|
50
|
+
$ aifabrix role-assistant test customer-support-bot --publish --force
|
|
51
|
+
|
|
52
|
+
Notes:
|
|
53
|
+
- Uses the public/running Role Assistant on the dataplane by default (does not publish local datasources).
|
|
54
|
+
- Use \`aifabrix upload <roleKey> --env …\` (or \`--publish\`) when you intentionally refresh the package.
|
|
55
|
+
- Runs lifecycle checks, then prints a portal deep link for full step-by-step status.
|
|
56
|
+
- Case files with input.message/input.content execute Work Hub plan→accept (or work.start when executionPath: intent).
|
|
57
|
+
- answers[] and approvals[] are matched to runtime wait payloads (questionKey/requestKey/waitReason).
|
|
58
|
+
- Use the portal URL for detailed human review while automation reads CLI/JSON output.
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function rawArgsInclude(cmd, flag) {
|
|
63
|
+
const raw = cmd && Array.isArray(cmd.rawArgs) ? cmd.rawArgs : [];
|
|
64
|
+
return raw.includes(flag);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function optionOrFlag(options, key, cmd, ...flags) {
|
|
68
|
+
if (options[key] === true) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return flags.some((flag) => rawArgsInclude(cmd, flag));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function trimOptionalString(value) {
|
|
75
|
+
return value ? String(value).trim() : '';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function normalizeRoleAssistantTestOptions(options, cmd) {
|
|
79
|
+
// Role Assistant test uses the public/running digital worker by default.
|
|
80
|
+
// Opt in to publish with --publish (optional --force).
|
|
81
|
+
const wantsPublish = optionOrFlag(options, 'publish', cmd, '--publish');
|
|
82
|
+
return {
|
|
83
|
+
env: options.env || 'dev',
|
|
84
|
+
verbose: optionOrFlag(options, 'verbose', cmd, '-v', '--verbose'),
|
|
85
|
+
debug: optionOrFlag(options, 'debug', cmd, '-d', '--debug'),
|
|
86
|
+
json: optionOrFlag(options, 'json', cmd, '--json'),
|
|
87
|
+
noPublish: !wantsPublish,
|
|
88
|
+
force: optionOrFlag(options, 'force', cmd, '--force'),
|
|
89
|
+
subjectUserId: options.subjectUserId || [],
|
|
90
|
+
subjectEmail: options.subjectEmail || [],
|
|
91
|
+
certificationProfile: options.certificationProfile || 'bronze',
|
|
92
|
+
case: trimOptionalString(options.case),
|
|
93
|
+
testsDir: trimOptionalString(options.testsDir),
|
|
94
|
+
run: true
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function buildRoleAssistantTestEnvelope(roleKey, verdict, portalUrl, result, opts, caseResult = null) {
|
|
99
|
+
const report = result.report || {};
|
|
100
|
+
const envelope = {
|
|
101
|
+
roleKey,
|
|
102
|
+
command: 'role-assistant test',
|
|
103
|
+
verdict,
|
|
104
|
+
portalUrl,
|
|
105
|
+
openApiPublished: result.openApiPublished === true,
|
|
106
|
+
certification: report.certification || null,
|
|
107
|
+
recommendations: Array.isArray(report.recommendations) ? report.recommendations : [],
|
|
108
|
+
warnings: Array.isArray(report.warnings) ? report.warnings : [],
|
|
109
|
+
stepsRun: result.stepsRun || [],
|
|
110
|
+
case: caseResult
|
|
111
|
+
? {
|
|
112
|
+
caseId: caseResult.caseId,
|
|
113
|
+
sourceFile: caseResult.sourceFile,
|
|
114
|
+
passed: caseResult.passed,
|
|
115
|
+
lifecycleState: caseResult.lifecycleState,
|
|
116
|
+
assertions: caseResult.assertions,
|
|
117
|
+
failedAssertions: caseResult.failedAssertions,
|
|
118
|
+
warnings: Array.isArray(caseResult.warnings) ? caseResult.warnings : [],
|
|
119
|
+
execution: caseResult.execution || null
|
|
120
|
+
}
|
|
121
|
+
: null
|
|
122
|
+
};
|
|
123
|
+
if (opts.verbose || opts.debug) {
|
|
124
|
+
envelope.report = report;
|
|
125
|
+
}
|
|
126
|
+
if (opts.debug) {
|
|
127
|
+
envelope.debug = {
|
|
128
|
+
observation: caseResult ? caseResult.observation : null,
|
|
129
|
+
lifecycleResult: result
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return envelope;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function displayCaseResultSummary(caseResult) {
|
|
136
|
+
if (!caseResult) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
logger.log(headerKeyValue('Case:', caseResult.caseId));
|
|
140
|
+
logger.log(headerKeyValue('Case file:', caseResult.sourceFile));
|
|
141
|
+
logger.log(headerKeyValue('Observed state:', caseResult.lifecycleState));
|
|
142
|
+
if (caseResult.execution) {
|
|
143
|
+
logger.log(headerKeyValue('Execution id:', caseResult.execution.processExecutionId || 'n/a'));
|
|
144
|
+
logger.log(headerKeyValue('Final runtime status:', caseResult.execution.finalStatus || 'n/a'));
|
|
145
|
+
}
|
|
146
|
+
if (caseResult.passed) {
|
|
147
|
+
logger.log(formatSuccessLine('Case assertions passed.'));
|
|
148
|
+
const warnings = Array.isArray(caseResult.warnings) ? caseResult.warnings : [];
|
|
149
|
+
for (const row of warnings) {
|
|
150
|
+
logger.log(formatWarningLine(row.message || String(row)));
|
|
151
|
+
}
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
logger.log(formatBlockingError('Case assertions failed.'));
|
|
155
|
+
for (const row of caseResult.failedAssertions) {
|
|
156
|
+
logger.log(formatWarningLine(row.message));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function displayRoleAssistantTestSummary(roleKey, verdict, portalUrl, result, caseResult = null) {
|
|
161
|
+
logger.log('');
|
|
162
|
+
logger.log(sectionTitle(`${String(roleKey).toUpperCase()} ROLE ASSISTANT TEST`));
|
|
163
|
+
logger.log('');
|
|
164
|
+
logger.log(headerKeyValue('Role key:', roleKey));
|
|
165
|
+
if (portalUrl) {
|
|
166
|
+
logger.log(headerKeyValue('Portal:', portalUrl));
|
|
167
|
+
} else {
|
|
168
|
+
logger.log(formatWarningLine('Portal link unavailable. Configure dataplane public URL and retry.'));
|
|
169
|
+
}
|
|
170
|
+
const verdictMessage =
|
|
171
|
+
verdict === VERDICT.VERIFIED
|
|
172
|
+
? 'Lifecycle checks passed. Open portal for full execution steps and logs.'
|
|
173
|
+
: 'Lifecycle checks are not fully verified. Open portal to inspect blocking steps.';
|
|
174
|
+
if (verdict === VERDICT.VERIFIED) {
|
|
175
|
+
logger.log(formatSuccessParagraph(verdictMessage));
|
|
176
|
+
} else {
|
|
177
|
+
logger.log(formatWarningLine(verdictMessage));
|
|
178
|
+
}
|
|
179
|
+
const steps = Array.isArray(result.stepsRun) ? result.stepsRun : [];
|
|
180
|
+
if (steps.length > 0) {
|
|
181
|
+
const labels = steps.map((row) => (row && row.pillar ? row.pillar : String(row)));
|
|
182
|
+
logger.log(metadata(`Steps run: ${labels.join(', ')}`));
|
|
183
|
+
}
|
|
184
|
+
displayCaseResultSummary(caseResult);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async function resolveRoleAssistantCaseResult(roleKey, opts, result, verdict, portalUrl) {
|
|
188
|
+
if (!opts.case) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
const roleCase = loadRoleAssistantTestCase(roleKey, opts.case, {
|
|
192
|
+
testsDir: opts.testsDir || null
|
|
193
|
+
});
|
|
194
|
+
if (!isExecutableRoleAssistantCase(roleCase)) {
|
|
195
|
+
return evaluateRoleAssistantTestCase(roleCase, result, verdict, portalUrl);
|
|
196
|
+
}
|
|
197
|
+
const authContext = await resolveLifecycleAuth(roleKey, {
|
|
198
|
+
...opts,
|
|
199
|
+
run: false,
|
|
200
|
+
noPublish: true
|
|
201
|
+
});
|
|
202
|
+
const executionResult = await runRoleAssistantCaseLifecycle(roleKey, roleCase, authContext, opts);
|
|
203
|
+
const executionVerdict = lifecycleVerdictFromCaseExecution(executionResult, verdict);
|
|
204
|
+
const evaluationInput = mergeCaseExecutionIntoLifecycleResult(result, executionResult);
|
|
205
|
+
const evaluation = evaluateRoleAssistantTestCase(
|
|
206
|
+
roleCase,
|
|
207
|
+
evaluationInput,
|
|
208
|
+
executionVerdict,
|
|
209
|
+
portalUrl
|
|
210
|
+
);
|
|
211
|
+
evaluation.execution = {
|
|
212
|
+
processExecutionId: executionResult.processExecutionId || null,
|
|
213
|
+
finalStatus: executionResult.finalStatus?.status || null,
|
|
214
|
+
waitReason: executionResult.finalStatus?.wait?.waitReason || null,
|
|
215
|
+
interactions: executionResult.interactions || [],
|
|
216
|
+
workResultError: executionResult.workResultError || null
|
|
217
|
+
};
|
|
218
|
+
return evaluation;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function computeRoleAssistantExitCode(verdict, caseResult) {
|
|
222
|
+
if (caseResult) {
|
|
223
|
+
return caseResult.passed ? 0 : 2;
|
|
224
|
+
}
|
|
225
|
+
if (verdict === VERDICT.VERIFIED) {
|
|
226
|
+
return 0;
|
|
227
|
+
}
|
|
228
|
+
return exitCodeFromVerdict(verdict, { partial: verdict === VERDICT.NOT_VERIFIED });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function runRoleAssistantTestAction(roleKey, options, cmd) {
|
|
232
|
+
const opts = normalizeRoleAssistantTestOptions(options, cmd);
|
|
233
|
+
const result = await runLifecycleForExternalSystem(roleKey, opts);
|
|
234
|
+
const verdict = lifecycleVerdictFromReport(result.report || {});
|
|
235
|
+
const portalUrl = buildExternalSystemUiUrl(result.dataplaneUiBaseUrl, roleKey);
|
|
236
|
+
const caseResult = await resolveRoleAssistantCaseResult(roleKey, opts, result, verdict, portalUrl);
|
|
237
|
+
|
|
238
|
+
if (opts.json) {
|
|
239
|
+
logger.log(
|
|
240
|
+
JSON.stringify(
|
|
241
|
+
buildRoleAssistantTestEnvelope(roleKey, verdict, portalUrl, result, opts, caseResult),
|
|
242
|
+
null,
|
|
243
|
+
2
|
|
244
|
+
)
|
|
245
|
+
);
|
|
246
|
+
} else {
|
|
247
|
+
displayRoleAssistantTestSummary(roleKey, verdict, portalUrl, result, caseResult);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const exitCode = computeRoleAssistantExitCode(verdict, caseResult);
|
|
251
|
+
if (exitCode !== 0) {
|
|
252
|
+
process.exit(exitCode);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function roleAssistantTestHandler(roleKey, options, cmd) {
|
|
257
|
+
try {
|
|
258
|
+
await runRoleAssistantTestAction(roleKey, options, cmd);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
handleCommandError(error, 'role-assistant test');
|
|
261
|
+
process.exit(3);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function setupRoleAssistantCommands(program) {
|
|
266
|
+
const roleAssistant = program
|
|
267
|
+
.command('role-assistant')
|
|
268
|
+
.description('Role Assistant lifecycle and portal workflows');
|
|
269
|
+
|
|
270
|
+
roleAssistant
|
|
271
|
+
.command('test <roleKey>')
|
|
272
|
+
.description('Run role-assistant lifecycle checks and print portal deep link')
|
|
273
|
+
.option('-e, --env <env>', 'Environment: dev, tst, or pro', 'dev')
|
|
274
|
+
.option('--case <caseIdOrPath>', 'Run and evaluate one role-assistant test case')
|
|
275
|
+
.option('--tests-dir <dir>', 'Override role-assistant test case directory')
|
|
276
|
+
.option('-v, --verbose', 'Include full lifecycle report payload in --json output')
|
|
277
|
+
.option('-d, --debug', 'Write debug logs under role-assistant/<roleKey>/logs/')
|
|
278
|
+
.option(
|
|
279
|
+
'--publish',
|
|
280
|
+
'Publish local Role Assistant package before checks (default: use public/running worker)'
|
|
281
|
+
)
|
|
282
|
+
.option('--force', 'Force upload when --publish is set')
|
|
283
|
+
.option(
|
|
284
|
+
'--subject-user-id <id>',
|
|
285
|
+
'Subject user id for governance generate (repeatable)',
|
|
286
|
+
collectString,
|
|
287
|
+
[]
|
|
288
|
+
)
|
|
289
|
+
.option(
|
|
290
|
+
'--subject-email <email>',
|
|
291
|
+
'Subject email for governance generate (repeatable)',
|
|
292
|
+
collectString,
|
|
293
|
+
[]
|
|
294
|
+
)
|
|
295
|
+
.option(
|
|
296
|
+
'--certification-profile <profile>',
|
|
297
|
+
'Certification profile for governance generate (bronze, silver, gold, ...)',
|
|
298
|
+
'bronze'
|
|
299
|
+
)
|
|
300
|
+
.option('--json', 'Machine-readable output envelope')
|
|
301
|
+
.addHelpText('after', roleAssistantHelpAfter())
|
|
302
|
+
.action((roleKey, options, cmd) => roleAssistantTestHandler(roleKey, options, cmd));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
module.exports = {
|
|
306
|
+
setupRoleAssistantCommands,
|
|
307
|
+
roleAssistantTestHandler,
|
|
308
|
+
runRoleAssistantTestAction,
|
|
309
|
+
normalizeRoleAssistantTestOptions,
|
|
310
|
+
buildRoleAssistantTestEnvelope,
|
|
311
|
+
computeRoleAssistantExitCode,
|
|
312
|
+
resolveRoleAssistantCaseResult
|
|
313
|
+
};
|