@aifabrix/builder 2.53.0 → 2.54.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/bin/aifabrix.js +2 -2
- package/lib/api/assistants.api.js +8 -5
- package/lib/api/channel-identity.api.js +41 -0
- package/lib/api/evidence-authoring.api.js +5 -1
- package/lib/api/evidence.api.js +2 -0
- package/lib/api/types/evidence.types.js +2 -0
- package/lib/api/work-search.api.js +136 -0
- package/lib/channels/add-channel.js +163 -126
- package/lib/channels/approval-guides/chatgpt.js +14 -18
- package/lib/channels/approval-guides/claude.js +29 -0
- package/lib/channels/approval-guides/index.js +88 -22
- package/lib/channels/approval-guides/mcp-client.js +27 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
- package/lib/channels/approval-guides/slack.js +10 -10
- package/lib/channels/approval-guides/teams-bot.js +8 -12
- package/lib/channels/channel-add-continuations.js +91 -0
- package/lib/channels/channel-add-ensure.js +124 -27
- package/lib/channels/channel-add-existing.js +160 -28
- package/lib/channels/channel-add-failure.js +60 -0
- package/lib/channels/channel-add-remaining.js +486 -0
- package/lib/channels/channel-add-tty.js +190 -0
- package/lib/channels/channel-add-wizard-config.js +138 -0
- package/lib/channels/channel-add-wizard.js +250 -0
- package/lib/channels/channel-artifact-generator.js +27 -13
- package/lib/channels/channel-cardinality.js +83 -0
- package/lib/channels/channel-catalog-icon.js +45 -0
- package/lib/channels/channel-cli-instructions.js +75 -0
- package/lib/channels/channel-configuration-map.js +213 -0
- package/lib/channels/channel-credential.js +11 -14
- package/lib/channels/channel-definition-project.js +101 -0
- package/lib/channels/channel-definition-registry.js +154 -0
- package/lib/channels/channel-description.js +59 -2
- package/lib/channels/channel-discovery.js +16 -2
- package/lib/channels/channel-external-system.js +86 -9
- package/lib/channels/channel-install-envelope-actions.js +88 -0
- package/lib/channels/channel-install-envelope-microsoft.js +155 -0
- package/lib/channels/channel-install-envelope.js +356 -0
- package/lib/channels/channel-install-help-md.js +172 -0
- package/lib/channels/channel-install-http-payload.js +62 -0
- package/lib/channels/channel-install-inventory.js +115 -0
- package/lib/channels/channel-install-profiles.js +90 -0
- package/lib/channels/channel-instance-collision.js +118 -0
- package/lib/channels/channel-instance-key.js +100 -0
- package/lib/channels/channel-instance-materialize.js +240 -0
- package/lib/channels/channel-integration-generator.js +16 -9
- package/lib/channels/channel-integration-template.js +101 -22
- package/lib/channels/channel-inventory-fetch.js +79 -0
- package/lib/channels/channel-oauth-preflight.js +104 -0
- package/lib/channels/channel-package-version.js +76 -0
- package/lib/channels/channel-predefined-client.js +154 -0
- package/lib/channels/channel-probe.js +7 -2
- package/lib/channels/channel-runtime-resolver.js +180 -72
- package/lib/channels/channel-status-display.js +86 -16
- package/lib/channels/channel-targets.js +106 -92
- package/lib/channels/chatgpt-callback.js +318 -0
- package/lib/channels/chatgpt-channel-add.js +229 -0
- package/lib/channels/chatgpt-preflight.js +396 -0
- package/lib/channels/chatgpt-runtime-contract.js +17 -0
- package/lib/channels/chatgpt-setup-values.js +124 -0
- package/lib/channels/claude-callback.js +67 -0
- package/lib/channels/claude-channel-add.js +254 -0
- package/lib/channels/claude-runtime-contract.js +40 -0
- package/lib/channels/claude-runtime.js +58 -0
- package/lib/channels/claude-setup-values.js +89 -0
- package/lib/channels/mcp-client/config-merge.js +148 -0
- package/lib/channels/mcp-client/ensure-client.js +231 -0
- package/lib/channels/mcp-client/paths.js +53 -0
- package/lib/channels/mcp-client/profiles.js +122 -0
- package/lib/channels/mcp-client/redirect-uris.js +99 -0
- package/lib/channels/mcp-client/runtime.js +59 -0
- package/lib/channels/mcp-client-channel-add.js +186 -0
- package/lib/channels/microsoft-copilot-channel-add.js +117 -7
- package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
- package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
- package/lib/channels/microsoft-copilot-package-prior.js +107 -0
- package/lib/channels/microsoft-copilot-package.js +29 -28
- package/lib/channels/microsoft-provisioning/a365.js +80 -0
- package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
- package/lib/channels/microsoft-provisioning/auth.js +179 -0
- package/lib/channels/microsoft-provisioning/cli.js +71 -0
- package/lib/channels/microsoft-provisioning/constants.js +75 -0
- package/lib/channels/microsoft-provisioning/errors.js +117 -0
- package/lib/channels/microsoft-provisioning/index.js +55 -0
- package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
- package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
- package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
- package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
- package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
- package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
- package/lib/channels/microsoft-provisioning/persist.js +110 -0
- package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
- package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
- package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
- package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
- package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
- package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
- package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
- package/lib/channels/runtime-tool-catalog.js +5 -2
- package/lib/channels/slack-channel-add-portal.js +130 -0
- package/lib/channels/slack-channel-add-tty-auth.js +95 -0
- package/lib/channels/slack-channel-add.js +258 -0
- package/lib/channels/slack-provisioning/apps.js +181 -0
- package/lib/channels/slack-provisioning/auth-store.js +110 -0
- package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
- package/lib/channels/slack-provisioning/auth.js +115 -0
- package/lib/channels/slack-provisioning/callbacks.js +41 -0
- package/lib/channels/slack-provisioning/cli.js +226 -0
- package/lib/channels/slack-provisioning/constants.js +37 -0
- package/lib/channels/slack-provisioning/credentials.js +169 -0
- package/lib/channels/slack-provisioning/curl-shim.js +132 -0
- package/lib/channels/slack-provisioning/developer-install.js +118 -0
- package/lib/channels/slack-provisioning/env-file.js +120 -0
- package/lib/channels/slack-provisioning/errors.js +47 -0
- package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
- package/lib/channels/slack-provisioning/index.js +250 -0
- package/lib/channels/slack-provisioning/install-cli.js +323 -0
- package/lib/channels/slack-provisioning/manifest.js +89 -0
- package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
- package/lib/channels/slack-provisioning/offer-cli.js +113 -0
- package/lib/channels/slack-provisioning/onboard-members.js +122 -0
- package/lib/channels/slack-provisioning/onboard.js +89 -0
- package/lib/channels/slack-provisioning/persist.js +95 -0
- package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
- package/lib/channels/slack-provisioning/with-curl-on-path.js +48 -0
- package/lib/channels/teams-bot-channel-add.js +94 -0
- package/lib/channels/vendor-dataplane-url.js +249 -0
- package/lib/cli/setup-certification.help.js +2 -0
- package/lib/cli/setup-external-system-help.js +2 -0
- package/lib/cli/setup-external-system.js +1 -1
- package/lib/commands/channel-add-help.js +366 -0
- package/lib/commands/channel-add-setup.js +162 -80
- package/lib/commands/channel-configure.js +118 -0
- package/lib/commands/channel.js +10 -1
- package/lib/commands/governance-upload-external.js +6 -3
- package/lib/commands/lifecycle-command-action.js +2 -5
- package/lib/commands/lifecycle-external.js +93 -21
- package/lib/commands/repair-datasource-test-payload.js +4 -2
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
- package/lib/commands/repair-datasource.js +3 -0
- package/lib/commands/repair-external-run.js +59 -25
- package/lib/commands/repair-openapi-rest-runtime.js +127 -0
- package/lib/commands/repair-orchestration-tag-merge.js +339 -0
- package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
- package/lib/commands/repair-rbac-platform-preset.js +26 -15
- package/lib/commands/repair-rbac-reader-roles.js +8 -21
- package/lib/commands/repair-rbac.js +10 -34
- package/lib/commands/repair-system-permissions.js +24 -22
- package/lib/commands/role-assistant-test-output.js +14 -0
- package/lib/commands/role-assistant.js +59 -21
- package/lib/commands/test-e2e-external.js +148 -21
- package/lib/commands/upload-credential-push-log.js +2 -1
- package/lib/commands/upload-publish-context.js +1 -1
- package/lib/commands/upload-role-assistant-shell.js +124 -0
- package/lib/commands/upload-sidecar-followups.js +6 -3
- package/lib/commands/upload.js +18 -3
- package/lib/core/secrets-docker-env.js +4 -1
- package/lib/core/secrets-env-content.js +17 -3
- package/lib/datasource/capability/capability-manifest.js +0 -3
- package/lib/datasource/capability/copy-test-payload.js +3 -0
- package/lib/external-system/deploy-helpers.js +26 -1
- package/lib/external-system/deploy.js +10 -6
- package/lib/external-system/download-helpers.js +29 -2
- package/lib/external-system/download-role-assistant.js +83 -4
- package/lib/external-system/download.js +40 -30
- package/lib/external-system/sync-deploy-manifest.js +3 -2
- package/lib/external-system/upload-identity.js +42 -0
- package/lib/generator/index.js +19 -15
- package/lib/generator/split.js +13 -2
- package/lib/lifecycle/role-assistant-governance.js +146 -0
- package/lib/lifecycle/scenario-upload.js +181 -30
- package/lib/programmatic/builder-api-cors.js +143 -0
- package/lib/programmatic/builder-api-request.js +6 -0
- package/lib/programmatic/builder-api-route-dispatch.js +56 -42
- package/lib/programmatic/builder-api-server.js +8 -1
- package/lib/programmatic/capability-registry.js +54 -0
- package/lib/programmatic/channel-install-help-resolve.js +359 -0
- package/lib/programmatic/channel-install-session.js +218 -0
- package/lib/programmatic/help-content/channel-onboarding.md +2 -0
- package/lib/programmatic/help-content/cip-overview.md +3 -1
- package/lib/programmatic/http-raw-response.js +62 -0
- package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +286 -0
- package/lib/programmatic/openapi-component-schemas.js +18 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +74 -3
- package/lib/programmatic/openapi-envelope-examples.js +117 -0
- package/lib/programmatic/openapi-operation-bindings.js +4 -1
- package/lib/programmatic/openapi-schema-descriptions-channel.js +316 -0
- package/lib/programmatic/openapi-spec.js +12 -8
- package/lib/programmatic/platform-rbac-catalog.js +36 -18
- package/lib/programmatic/route-handler-map.js +51 -1
- package/lib/programmatic/route-handlers-context.js +2 -1
- package/lib/programmatic/run-auth-permissions.js +54 -0
- package/lib/programmatic/run-channel-catalog.js +196 -0
- package/lib/programmatic/run-channel-install-artifacts.js +137 -0
- package/lib/programmatic/run-channel-install-copilot.js +353 -0
- package/lib/programmatic/run-channel-install-options.js +232 -0
- package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
- package/lib/programmatic/run-channel-install.js +346 -0
- package/lib/programmatic/run-channel-package.js +87 -7
- package/lib/programmatic/workspace-context.js +2 -0
- package/lib/role-assistant/evidence-sync.js +4 -2
- package/lib/role-assistant/evidence-validation-issues.js +51 -0
- package/lib/role-assistant/knowledge-sync.js +10 -4
- package/lib/role-assistant/settings.js +49 -2
- package/lib/role-assistant/test-cases-evaluate.js +30 -2
- package/lib/role-assistant/test-cases-evidence.js +175 -0
- package/lib/role-assistant/test-cases-search.js +229 -0
- package/lib/role-assistant/test-cases.js +37 -4
- package/lib/role-assistant/test-runner-search.js +149 -0
- package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
- package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
- package/lib/role-assistant/test-runner-workhub.js +29 -11
- package/lib/role-assistant/test-runner.js +16 -1
- package/lib/schema/external-datasource.schema.json +119 -16
- package/lib/schema/external-system.schema.json +159 -2
- package/lib/schema/mcp-client-profile.schema.json +103 -0
- package/lib/utils/app-path-resolve.js +4 -0
- package/lib/utils/authentication-env-template.js +44 -6
- package/lib/utils/credential-secrets-env.js +6 -1
- package/lib/utils/env-copy.js +19 -7
- package/lib/utils/external-env-template.js +20 -2
- package/lib/utils/paths.js +18 -1
- package/lib/utils/platform-shell-package.js +69 -0
- package/lib/utils/port-resolver.js +50 -1
- package/lib/utils/rewrite-name-flag.js +20 -0
- package/lib/utils/role-assistant-paths.js +13 -10
- package/lib/utils/schema-resolver.js +11 -1
- package/lib/utils/secrets-helpers.js +12 -21
- package/lib/utils/token-manager.js +10 -5
- package/lib/validation/validate.js +40 -0
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/applications/builder-api/Dockerfile +1 -1
- package/templates/applications/builder-api/env.template +7 -0
- package/templates/applications/dataplane/application.yaml +6 -5
- package/templates/applications/dataplane/env.template +2 -2
- package/templates/applications/dataplane/rbac.yaml +7 -2
- package/templates/applications/keycloak/Dockerfile +30 -4
- package/templates/applications/keycloak/application.yaml +2 -2
- package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
- package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
- package/templates/applications/keycloak/env.template +3 -0
- package/templates/applications/miso-controller/application.yaml +1 -2
- package/templates/applications/miso-controller/env.template +2 -0
- package/templates/channels/README.md +5 -5
- package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
- package/templates/channels/chatgpt/channel.json +59 -0
- package/templates/channels/chatgpt/icon.svg +1 -0
- package/templates/channels/chatgpt/install.template.md.hbs +20 -95
- package/templates/channels/chatgpt/integration/README.md +1 -1
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
- package/templates/channels/chatgpt/integration/env.template +2 -4
- package/templates/channels/chatgpt/integration/rbac.json +13 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +41 -0
- package/templates/channels/claude/channel.json +59 -0
- package/templates/channels/claude/icon.svg +1 -0
- package/templates/channels/claude/install.template.md.hbs +21 -0
- package/templates/channels/claude/integration/README.md +14 -0
- package/templates/channels/claude/integration/application.json +15 -0
- package/templates/channels/claude/integration/claude-system.json +59 -0
- package/templates/channels/claude/integration/env.template +2 -0
- package/templates/channels/claude/integration/rbac.json +13 -0
- package/templates/channels/claude/manifest.template.json.hbs +40 -0
- package/templates/channels/mcp-client/channel.json +72 -0
- package/templates/channels/mcp-client/icon.svg +1 -0
- package/templates/channels/mcp-client/install.template.md.hbs +24 -0
- package/templates/channels/mcp-client/integration/README.md +13 -0
- package/templates/channels/mcp-client/integration/application.json +15 -0
- package/templates/channels/mcp-client/integration/env.template +2 -0
- package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
- package/templates/channels/mcp-client/integration/rbac.json +13 -0
- package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
- package/templates/channels/mcp-client/profiles/cursor.json +26 -0
- package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
- package/templates/channels/mcp-client/profiles/vscode.json +29 -0
- package/templates/channels/microsoft-copilot/channel.json +73 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
- package/templates/channels/microsoft-copilot/icon.svg +1 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
- package/templates/channels/microsoft-copilot/integration/README.md +1 -1
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +3 -6
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
- package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
- package/templates/channels/slack/channel.json +223 -0
- package/templates/channels/slack/icon.svg +1 -0
- package/templates/channels/slack/install.template.md.hbs +36 -28
- package/templates/channels/slack/integration/README.md +245 -22
- package/templates/channels/slack/integration/application.json +44 -7
- package/templates/channels/slack/integration/env.template +15 -6
- package/templates/channels/slack/integration/openapi/openapi.json +126 -0
- package/templates/channels/slack/integration/rbac.json +84 -0
- package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
- package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
- package/templates/channels/slack/integration/slack-system.json +155 -77
- package/templates/channels/slack/manifest.template.json.hbs +5 -2
- package/templates/channels/teams-bot/channel.json +161 -0
- package/templates/channels/teams-bot/icon.svg +1 -0
- package/templates/channels/teams-bot/install.template.md.hbs +12 -13
- package/templates/channels/teams-bot/integration/README.md +5 -4
- package/templates/channels/teams-bot/integration/application.json +6 -4
- package/templates/channels/teams-bot/integration/env.template +5 -4
- package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
- package/templates/channels/teams-bot/integration/rbac.json +21 -0
- package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
- package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
- package/templates/channels/web-embed/channel.json +60 -0
- package/templates/channels/web-embed/install.template.md.hbs +1 -1
- package/templates/channels/web-embed/integration/README.md +2 -2
- package/templates/channels/web-embed/integration/application.json +2 -2
- package/templates/channels/web-embed/integration/env.template +1 -1
- package/templates/channels/web-embed/integration/rbac.json +13 -0
- package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
|
@@ -81,6 +81,19 @@ function mapCaseEnvelopeRow(row) {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
function attachEnvelopeIsolation(envelope, opts) {
|
|
85
|
+
const emails = Array.isArray(opts.subjectEmail)
|
|
86
|
+
? opts.subjectEmail.map((value) => String(value || '').trim()).filter(Boolean)
|
|
87
|
+
: [];
|
|
88
|
+
const userIds = Array.isArray(opts.subjectUserId)
|
|
89
|
+
? opts.subjectUserId.map((value) => String(value || '').trim()).filter(Boolean)
|
|
90
|
+
: [];
|
|
91
|
+
if (emails.length === 0 && userIds.length === 0) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
envelope.isolation = { subjectEmails: emails, subjectUserIds: userIds };
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
function attachEnvelopeCases(envelope, caseResult) {
|
|
85
98
|
if (Array.isArray(caseResult)) {
|
|
86
99
|
envelope.cases = caseResult.map(mapCaseEnvelopeRow);
|
|
@@ -118,6 +131,7 @@ function buildRoleAssistantTestEnvelope(roleKey, verdict, portalUrl, result, opt
|
|
|
118
131
|
summary: null
|
|
119
132
|
};
|
|
120
133
|
attachEnvelopeCases(envelope, caseResult);
|
|
134
|
+
attachEnvelopeIsolation(envelope, opts);
|
|
121
135
|
if (opts.verbose || opts.debug) {
|
|
122
136
|
envelope.report = report;
|
|
123
137
|
}
|
|
@@ -34,6 +34,7 @@ const {
|
|
|
34
34
|
mergeCaseExecutionIntoLifecycleResult,
|
|
35
35
|
lifecycleVerdictFromCaseExecution
|
|
36
36
|
} = require('../role-assistant/test-runner');
|
|
37
|
+
const { assertRoleAssistantEvidencePreflight } = require('../role-assistant/test-cases-evidence');
|
|
37
38
|
const { collectString } = require('./governance');
|
|
38
39
|
const {
|
|
39
40
|
sectionTitle,
|
|
@@ -91,8 +92,12 @@ Notes:
|
|
|
91
92
|
- Use \`aifabrix upload <roleKey> --env …\` (or \`--publish\`) when you intentionally refresh the package.
|
|
92
93
|
- Runs lifecycle checks, then prints a portal deep link for full step-by-step status.
|
|
93
94
|
- Case files with input.message/input.content execute Work Hub plan→accept (or work.start when executionPath: intent).
|
|
95
|
+
- Cases with executionPath: search|skills (input.executionPath or case-root executionPath) run work.skills / work.search instead of Work Hub.
|
|
96
|
+
- Role Assistant packages do not need application.yaml; test uses device login and the published dataplane worker.
|
|
97
|
+
- Cases with preflight.evidence.requiredKeys read live Evidence from the dataplane before start and hard-stop if those keys are missing or not active.
|
|
94
98
|
- answers[] and approvals[] are matched to runtime wait payloads (questionKey/requestKey/waitReason).
|
|
95
99
|
- --suite runs YAML under role-assistant/ra-<roleKey>/tests/<suite>/ (preferred), or tests/ra-<roleKey>/<roleKey>/<suite>/, or legacy tests/role-assistant/ra-<roleKey>/<suite>/ (override with --cases-root).
|
|
100
|
+
- --subject-email / --subject-user-id isolate Work Hub cases (repeatable). They do not generate Connected System governance packs and do not require application.yaml.
|
|
96
101
|
- Use the portal URL for detailed human review while automation reads CLI/JSON output.
|
|
97
102
|
`;
|
|
98
103
|
}
|
|
@@ -254,38 +259,71 @@ async function runRoleAssistantTestAction(roleKey, options, cmd) {
|
|
|
254
259
|
return exitCode;
|
|
255
260
|
}
|
|
256
261
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
262
|
+
function attachCaseExecution(evaluation, executionResult, error) {
|
|
263
|
+
const errMsg = error && (error.message || String(error));
|
|
264
|
+
evaluation.execution = {
|
|
265
|
+
processExecutionId: executionResult?.processExecutionId || error?.planId || null,
|
|
266
|
+
finalStatus: executionResult?.finalStatus?.status || (error ? 'failed' : null),
|
|
267
|
+
waitReason: executionResult?.finalStatus?.wait?.waitReason || null,
|
|
268
|
+
interactions: executionResult?.interactions || [],
|
|
269
|
+
workResultError: executionResult?.workResultError || errMsg || null
|
|
270
|
+
};
|
|
271
|
+
return evaluation;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async function resolveExecutableCaseResult(roleKey, roleCase, opts, result, verdict, portalUrl) {
|
|
267
275
|
const authContext = await resolveLifecycleAuth(roleKey, {
|
|
268
276
|
...opts,
|
|
269
277
|
run: false,
|
|
270
278
|
noPublish: true
|
|
271
279
|
});
|
|
280
|
+
const evidencePreflight = await assertRoleAssistantEvidencePreflight(roleCase, authContext);
|
|
272
281
|
const executionResult = await runRoleAssistantCaseLifecycle(roleKey, roleCase, authContext, opts);
|
|
273
282
|
const executionVerdict = lifecycleVerdictFromCaseExecution(executionResult, verdict);
|
|
274
283
|
const evaluationInput = mergeCaseExecutionIntoLifecycleResult(result, executionResult);
|
|
284
|
+
evaluationInput.evidencePreflight = evidencePreflight;
|
|
275
285
|
const evaluation = evaluateRoleAssistantTestCase(
|
|
276
286
|
roleCase,
|
|
277
287
|
evaluationInput,
|
|
278
288
|
executionVerdict,
|
|
279
289
|
portalUrl
|
|
280
290
|
);
|
|
281
|
-
evaluation
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
291
|
+
return attachCaseExecution(evaluation, executionResult);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async function resolveRoleAssistantCaseResult(roleKey, opts, result, verdict, portalUrl) {
|
|
295
|
+
if (!opts.case) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
const roleCase = loadRoleAssistantTestCase(roleKey, opts.case, {
|
|
299
|
+
testsDir: opts.testsDir || null
|
|
300
|
+
});
|
|
301
|
+
if (!isExecutableRoleAssistantCase(roleCase)) {
|
|
302
|
+
return evaluateRoleAssistantTestCase(roleCase, result, verdict, portalUrl);
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
return await resolveExecutableCaseResult(
|
|
306
|
+
roleKey,
|
|
307
|
+
roleCase,
|
|
308
|
+
opts,
|
|
309
|
+
result,
|
|
310
|
+
verdict,
|
|
311
|
+
portalUrl
|
|
312
|
+
);
|
|
313
|
+
} catch (error) {
|
|
314
|
+
const failedInput = mergeCaseExecutionIntoLifecycleResult(result, {
|
|
315
|
+
finalStatus: { status: 'failed' },
|
|
316
|
+
workResult: null,
|
|
317
|
+
workResultError: error.message || String(error),
|
|
318
|
+
interactions: []
|
|
319
|
+
});
|
|
320
|
+
failedInput.workResultError = error.message || String(error);
|
|
321
|
+
return attachCaseExecution(
|
|
322
|
+
evaluateRoleAssistantTestCase(roleCase, failedInput, verdict, portalUrl),
|
|
323
|
+
null,
|
|
324
|
+
error
|
|
325
|
+
);
|
|
326
|
+
}
|
|
289
327
|
}
|
|
290
328
|
|
|
291
329
|
async function roleAssistantTestHandler(roleKey, options, cmd) {
|
|
@@ -332,19 +370,19 @@ function setupRoleAssistantCommands(program) {
|
|
|
332
370
|
.option('--force', 'Force upload when --publish is set')
|
|
333
371
|
.option(
|
|
334
372
|
'--subject-user-id <id>',
|
|
335
|
-
'
|
|
373
|
+
'Work Hub isolation user id (repeatable; not Connected System governance)',
|
|
336
374
|
collectString,
|
|
337
375
|
[]
|
|
338
376
|
)
|
|
339
377
|
.option(
|
|
340
378
|
'--subject-email <email>',
|
|
341
|
-
'
|
|
379
|
+
'Work Hub isolation email (repeatable; not Connected System governance)',
|
|
342
380
|
collectString,
|
|
343
381
|
[]
|
|
344
382
|
)
|
|
345
383
|
.option(
|
|
346
384
|
'--certification-profile <profile>',
|
|
347
|
-
'
|
|
385
|
+
'Ignored for Role Assistant packages (Connected System governance generate does not run)',
|
|
348
386
|
'bronze'
|
|
349
387
|
)
|
|
350
388
|
.option('--json', 'Machine-readable output envelope')
|
|
@@ -39,6 +39,99 @@ function deriveDatasourceKeyFromFileName(fileName, systemKey) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/* eslint-disable max-statements -- Key resolution from system or files */
|
|
42
|
+
function datasourceKeyFromParsedOrFile(parsed, fileName, systemKey) {
|
|
43
|
+
if (parsed && typeof parsed.key === 'string' && parsed.key.trim()) {
|
|
44
|
+
return parsed.key.trim();
|
|
45
|
+
}
|
|
46
|
+
return deriveDatasourceKeyFromFileName(fileName, systemKey);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function cipFetchSources(parsed) {
|
|
50
|
+
const ops = parsed && parsed.execution && parsed.execution.cip && parsed.execution.cip.operations;
|
|
51
|
+
if (!ops || typeof ops !== 'object') {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const sources = [];
|
|
55
|
+
for (const op of Object.values(ops)) {
|
|
56
|
+
if (!op || typeof op !== 'object') continue;
|
|
57
|
+
for (const step of op.steps || []) {
|
|
58
|
+
const src = step && step.fetch && step.fetch.source;
|
|
59
|
+
if (typeof src === 'string' && src.trim()) sources.push(src.trim());
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return sources;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function isExclusiveRecordFetchSource(parsed) {
|
|
66
|
+
const sources = cipFetchSources(parsed);
|
|
67
|
+
return sources.length > 0 && sources.every((src) => src === 'record');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Maps datasource keys to E2E skip reasons (`view` / `record`) or storageType.
|
|
72
|
+
* @param {string} appPath
|
|
73
|
+
* @param {string[]} datasourceFiles
|
|
74
|
+
* @param {string} systemKey
|
|
75
|
+
* @returns {Object<string, string|undefined>}
|
|
76
|
+
*/
|
|
77
|
+
function loadDatasourceStorageByKey(appPath, datasourceFiles, systemKey) {
|
|
78
|
+
const byKey = {};
|
|
79
|
+
for (const fileName of datasourceFiles) {
|
|
80
|
+
const filePath = path.join(appPath, fileName);
|
|
81
|
+
if (!fs.existsSync(filePath)) continue;
|
|
82
|
+
try {
|
|
83
|
+
const parsed = loadConfigFile(filePath);
|
|
84
|
+
const key = datasourceKeyFromParsedOrFile(parsed, fileName, systemKey);
|
|
85
|
+
if (!key) continue;
|
|
86
|
+
if (parsed && parsed.storageType === 'view') byKey[key] = 'view';
|
|
87
|
+
else if (isExclusiveRecordFetchSource(parsed)) byKey[key] = 'record';
|
|
88
|
+
else byKey[key] = parsed && parsed.storageType;
|
|
89
|
+
} catch {
|
|
90
|
+
// Unreadable files stay unknown and remain eligible for E2E.
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return byKey;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Table E2E (sync/CRUD) does not apply to viewpoint datasources.
|
|
98
|
+
* @param {string[]} keys
|
|
99
|
+
* @param {Object<string, string|undefined>} storageByKey
|
|
100
|
+
* @returns {{ runnable: string[], skipped: string[] }}
|
|
101
|
+
*/
|
|
102
|
+
function selectE2eRunnableKeys(keys, storageByKey) {
|
|
103
|
+
const runnable = [];
|
|
104
|
+
const skipped = [];
|
|
105
|
+
for (const key of keys) {
|
|
106
|
+
if (storageByKey[key] === 'view' || storageByKey[key] === 'record') skipped.push(key);
|
|
107
|
+
else runnable.push(key);
|
|
108
|
+
}
|
|
109
|
+
return { runnable, skipped };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Drops storageType view keys and logs skips. Empty runnable is success (nothing to run).
|
|
114
|
+
* @param {string} externalSystem
|
|
115
|
+
* @param {string} appPath
|
|
116
|
+
* @param {string[]} datasourceFiles
|
|
117
|
+
* @param {string} systemKey
|
|
118
|
+
* @param {string[]} keys
|
|
119
|
+
* @returns {string[]}
|
|
120
|
+
*/
|
|
121
|
+
function prepareE2eDatasourceKeys(externalSystem, appPath, datasourceFiles, systemKey, keys) {
|
|
122
|
+
const storageByKey = loadDatasourceStorageByKey(appPath, datasourceFiles, systemKey);
|
|
123
|
+
const { runnable, skipped } = selectE2eRunnableKeys(keys, storageByKey);
|
|
124
|
+
skipped.forEach((key) => {
|
|
125
|
+
const reason =
|
|
126
|
+
storageByKey[key] === 'record' ? 'fetch.source record' : 'storageType view';
|
|
127
|
+
logger.log(chalk.gray(`⏭ Skipping ${key} (${reason})`));
|
|
128
|
+
});
|
|
129
|
+
if (runnable.length === 0 && keys.length === 0) {
|
|
130
|
+
logger.log(chalk.yellow(`No datasources found for ${externalSystem}. Add datasource files and run aifabrix repair.`));
|
|
131
|
+
}
|
|
132
|
+
return runnable;
|
|
133
|
+
}
|
|
134
|
+
|
|
42
135
|
/**
|
|
43
136
|
* Resolves the list of datasource keys for an external system (from system file or discovered files).
|
|
44
137
|
* @param {string} appPath - Integration app path
|
|
@@ -117,22 +210,29 @@ async function syncLocalIfRequested(systemKey, options) {
|
|
|
117
210
|
return uploadCtx && uploadCtx.dataplaneUrl && uploadCtx.authConfig ? uploadCtx : null;
|
|
118
211
|
}
|
|
119
212
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
213
|
+
function isPlatformShellAppPath(appPath) {
|
|
214
|
+
const parent = path.basename(path.dirname(path.resolve(String(appPath || ''))));
|
|
215
|
+
return parent === 'role-assistant' || parent === 'enterprise-knowledge';
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function platformShellIntegrationContext(systemKey, appPath) {
|
|
219
|
+
return { systemKey, keys: [], appPath, datasourceFiles: [] };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function tryApplicationConfigPath(appPath) {
|
|
223
|
+
try {
|
|
224
|
+
return resolveApplicationConfigPath(appPath);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
if (isPlatformShellAppPath(appPath)) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
134
233
|
/**
|
|
135
234
|
* Resolve integration folder, system key, and datasource keys for system-level tests.
|
|
235
|
+
* Role Assistant / Enterprise Knowledge packages have no application.yaml.
|
|
136
236
|
* @param {string} externalSystem
|
|
137
237
|
* @returns {{ systemKey: string, keys: string[] }}
|
|
138
238
|
*/
|
|
@@ -144,13 +244,19 @@ function resolveExternalIntegrationContext(externalSystem, pathOptions = {}) {
|
|
|
144
244
|
if (!fs.existsSync(appPath)) {
|
|
145
245
|
throw new Error(`Integration path not found: ${appPath}`);
|
|
146
246
|
}
|
|
147
|
-
const configPath =
|
|
247
|
+
const configPath = tryApplicationConfigPath(appPath);
|
|
248
|
+
if (!configPath) {
|
|
249
|
+
return platformShellIntegrationContext(externalSystem, appPath);
|
|
250
|
+
}
|
|
148
251
|
let variables = {};
|
|
149
252
|
if (fs.existsSync(configPath)) {
|
|
150
253
|
variables = loadConfigFile(configPath);
|
|
151
254
|
}
|
|
152
255
|
const { systemFiles, datasourceFiles: discovered } = discoverIntegrationFiles(appPath);
|
|
153
256
|
if (systemFiles.length === 0) {
|
|
257
|
+
if (isPlatformShellAppPath(appPath)) {
|
|
258
|
+
return platformShellIntegrationContext(externalSystem, appPath);
|
|
259
|
+
}
|
|
154
260
|
throw new Error(`No system file found in ${appPath}. Expected *-system.yaml or *-system.json`);
|
|
155
261
|
}
|
|
156
262
|
const datasourceFiles = buildEffectiveDatasourceFiles(
|
|
@@ -171,13 +277,33 @@ function resolveExternalIntegrationContext(externalSystem, pathOptions = {}) {
|
|
|
171
277
|
systemParsed,
|
|
172
278
|
datasourceFiles
|
|
173
279
|
);
|
|
174
|
-
return { systemKey, keys };
|
|
280
|
+
return { systemKey, keys, appPath, datasourceFiles };
|
|
175
281
|
}
|
|
176
282
|
|
|
283
|
+
/* eslint-disable max-lines-per-function, max-statements -- Load context, then loop over keys */
|
|
284
|
+
/**
|
|
285
|
+
* Runs E2E for all datasources of an external system. Uses each datasource's payloadTemplate (no extra params required).
|
|
286
|
+
*
|
|
287
|
+
* @async
|
|
288
|
+
* @param {string} externalSystem - System key (e.g. hubspot-demo)
|
|
289
|
+
* @param {Object} options - Options passed to each runDatasourceTestE2E
|
|
290
|
+
* @param {string} [options.env] - Environment (dev, tst, pro)
|
|
291
|
+
* @param {boolean} [options.debug] - Include debug, write log
|
|
292
|
+
* @param {boolean} [options.verbose] - Verbose output
|
|
293
|
+
* @param {boolean} [options.async] - If false, sync mode (default true)
|
|
294
|
+
* @param {boolean} [options.noPublish] - When true, skip upload (E2E uses dataplane config already deployed)
|
|
295
|
+
* @returns {Promise<{ success: boolean, results: Array<{ key: string, success: boolean, error?: string }> }>}
|
|
296
|
+
*/
|
|
177
297
|
async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
178
|
-
const { systemKey, keys } = resolveExternalIntegrationContext(externalSystem);
|
|
179
|
-
|
|
180
|
-
|
|
298
|
+
const { systemKey, keys, appPath, datasourceFiles } = resolveExternalIntegrationContext(externalSystem);
|
|
299
|
+
const e2eKeys = prepareE2eDatasourceKeys(
|
|
300
|
+
externalSystem,
|
|
301
|
+
appPath,
|
|
302
|
+
datasourceFiles,
|
|
303
|
+
systemKey,
|
|
304
|
+
keys
|
|
305
|
+
);
|
|
306
|
+
if (e2eKeys.length === 0) {
|
|
181
307
|
return { success: true, results: [] };
|
|
182
308
|
}
|
|
183
309
|
|
|
@@ -217,12 +343,12 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
|
217
343
|
quietPollUi: options.quietPollUi === true,
|
|
218
344
|
onPollProgress: options.onPollProgress
|
|
219
345
|
};
|
|
220
|
-
for (const key of
|
|
346
|
+
for (const key of e2eKeys) {
|
|
221
347
|
if (typeof options.onDatasourceProgress === 'function') {
|
|
222
348
|
options.onDatasourceProgress({
|
|
223
349
|
key,
|
|
224
350
|
index: results.length,
|
|
225
|
-
total:
|
|
351
|
+
total: e2eKeys.length
|
|
226
352
|
});
|
|
227
353
|
}
|
|
228
354
|
try {
|
|
@@ -246,6 +372,7 @@ async function runTestE2EForExternalSystem(externalSystem, options = {}) {
|
|
|
246
372
|
module.exports = {
|
|
247
373
|
runTestE2EForExternalSystem,
|
|
248
374
|
getDatasourceKeys,
|
|
375
|
+
selectE2eRunnableKeys,
|
|
249
376
|
resolveExternalIntegrationContext,
|
|
250
377
|
syncLocalIfRequested
|
|
251
378
|
};
|
|
@@ -91,7 +91,8 @@ async function pushAndLogCredentialSecrets(dataplaneUrl, authConfig, systemKey,
|
|
|
91
91
|
pushCredentialSecrets(dataplaneUrl, authConfig, {
|
|
92
92
|
envFilePath,
|
|
93
93
|
appName: systemKey,
|
|
94
|
-
payload
|
|
94
|
+
payload,
|
|
95
|
+
excludeKeys: uiOpts.excludeSecretKeys
|
|
95
96
|
}),
|
|
96
97
|
{ systemKey, json: uiOpts.json === true }
|
|
97
98
|
);
|
|
@@ -57,7 +57,7 @@ async function resolveUploadPublishContext(
|
|
|
57
57
|
environment: options.environment
|
|
58
58
|
});
|
|
59
59
|
requireBearerForDataplanePipeline(resolved.authConfig);
|
|
60
|
-
if (options.force === true) {
|
|
60
|
+
if (options.force === true && options.suppressSummary !== true) {
|
|
61
61
|
logForcePublishWarning();
|
|
62
62
|
}
|
|
63
63
|
const controllerUrl = await resolveControllerUrl();
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant upload without Connected System files.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Settings + Evidence path for role-assistant/ packages
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
const logger = require('../utils/logger');
|
|
11
|
+
const { detectAppType } = require('../utils/paths');
|
|
12
|
+
const { isRoleAssistantWorkspace } = require('../utils/platform-shell-package');
|
|
13
|
+
const {
|
|
14
|
+
SYSTEM_KIND_DIGITAL_WORKER,
|
|
15
|
+
readRoleAssistantSettings,
|
|
16
|
+
resolveRoleAssistantSettingsVersion,
|
|
17
|
+
resolveRoleAssistantEnvironmentSettings
|
|
18
|
+
} = require('../role-assistant/settings');
|
|
19
|
+
const { validateExternalSystemComplete } = require('../validation/validate');
|
|
20
|
+
const { displayValidationResults } = require('../validation/validate-display');
|
|
21
|
+
const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
|
|
22
|
+
const { runUploadSidecarFollowups } = require('./upload-sidecar-followups');
|
|
23
|
+
const { finalizeUploadPublishResult } = require('./upload-data-sync-finalize');
|
|
24
|
+
|
|
25
|
+
async function isRoleAssistantShellPackage(systemKey, options = {}) {
|
|
26
|
+
const pathOptions = options.pathOptions || {};
|
|
27
|
+
const detected = await detectAppType(systemKey, pathOptions);
|
|
28
|
+
return isRoleAssistantWorkspace(detected.baseDir);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function buildRoleAssistantShellPayload(systemKey, options = {}) {
|
|
32
|
+
const pathOptions = options.pathOptions || {};
|
|
33
|
+
const settings = readRoleAssistantSettings(systemKey, { required: true, pathOptions });
|
|
34
|
+
resolveRoleAssistantEnvironmentSettings(settings, options.env || 'dev', { required: true });
|
|
35
|
+
const version = resolveRoleAssistantSettingsVersion(settings) || '1.0.0';
|
|
36
|
+
return {
|
|
37
|
+
version,
|
|
38
|
+
application: {
|
|
39
|
+
key: systemKey,
|
|
40
|
+
systemKind: SYSTEM_KIND_DIGITAL_WORKER
|
|
41
|
+
},
|
|
42
|
+
dataSources: [],
|
|
43
|
+
status: options.uploadStatus === 'published' ? 'published' : 'draft'
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function assertRoleAssistantShellValid(validationResult) {
|
|
48
|
+
if (validationResult && validationResult.valid) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
displayValidationResults(validationResult);
|
|
52
|
+
const errors = (validationResult && validationResult.errors) || [];
|
|
53
|
+
const summary = errors.slice(0, 3).map((item) => (typeof item === 'string' ? item : String(item))).join('; ');
|
|
54
|
+
throw new Error(
|
|
55
|
+
summary
|
|
56
|
+
? `Validation failed: ${summary}. Fix errors above and run the command again.`
|
|
57
|
+
: 'Validation failed. Fix errors before uploading.'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function validateRoleAssistantShellPackage(systemKey, options = {}) {
|
|
62
|
+
const pathOptions = options.pathOptions || {};
|
|
63
|
+
const validationResult = await validateExternalSystemComplete(systemKey, {
|
|
64
|
+
type: 'external',
|
|
65
|
+
...pathOptions
|
|
66
|
+
});
|
|
67
|
+
assertRoleAssistantShellValid(validationResult);
|
|
68
|
+
if (options.minimal !== true) {
|
|
69
|
+
logger.log(formatSuccessLine('Local validation passed'));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function logRoleAssistantShellDryRun(systemKey, payload) {
|
|
74
|
+
logger.log(
|
|
75
|
+
chalk.yellow(
|
|
76
|
+
'Dry run: would apply Role Assistant settings and Evidence (no Connected System publish).'
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
logger.log(chalk.gray(` System: ${systemKey}, version: ${payload.version}`));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function applyRoleAssistantShellSidecars(systemKey, options, payload, deps) {
|
|
83
|
+
const { dataplaneUrl, authConfig, environment } = await deps.resolveDataplaneAndAuth(
|
|
84
|
+
systemKey,
|
|
85
|
+
options
|
|
86
|
+
);
|
|
87
|
+
const sidecar = await runUploadSidecarFollowups({
|
|
88
|
+
systemKey,
|
|
89
|
+
options: { ...options, skipDataSync: true },
|
|
90
|
+
payload,
|
|
91
|
+
dataplaneUrl,
|
|
92
|
+
authConfig,
|
|
93
|
+
environment
|
|
94
|
+
});
|
|
95
|
+
if (options.suppressSummary !== true && options.minimal !== true) {
|
|
96
|
+
logger.log(
|
|
97
|
+
formatSuccessLine('Role Assistant settings and Evidence applied (no Connected System publish).')
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return finalizeUploadPublishResult(
|
|
101
|
+
{ dataplaneUrl, authConfig, environment, uploadSkipped: true, sidecar },
|
|
102
|
+
payload,
|
|
103
|
+
options
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async function uploadRoleAssistantShellPackage(systemKey, options = {}, deps = {}) {
|
|
108
|
+
if (!deps.resolveDataplaneAndAuth) {
|
|
109
|
+
throw new Error('Role Assistant upload requires dataplane auth resolution');
|
|
110
|
+
}
|
|
111
|
+
await validateRoleAssistantShellPackage(systemKey, options);
|
|
112
|
+
const payload = buildRoleAssistantShellPayload(systemKey, options);
|
|
113
|
+
if (options.dryRun === true) {
|
|
114
|
+
logRoleAssistantShellDryRun(systemKey, payload);
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
return applyRoleAssistantShellSidecars(systemKey, options, payload, deps);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
module.exports = {
|
|
121
|
+
isRoleAssistantShellPackage,
|
|
122
|
+
buildRoleAssistantShellPayload,
|
|
123
|
+
uploadRoleAssistantShellPackage
|
|
124
|
+
};
|
|
@@ -38,11 +38,14 @@ function buildRoleAssistantSyncContext(ctx, model) {
|
|
|
38
38
|
|
|
39
39
|
async function runGovernanceSidecar(ctx, sidecar, quietSidecar) {
|
|
40
40
|
try {
|
|
41
|
-
const {
|
|
42
|
-
|
|
41
|
+
const {
|
|
42
|
+
uploadGovernanceScenarioPacks,
|
|
43
|
+
normalizeGovernanceUploadResult
|
|
44
|
+
} = require('../lifecycle/scenario-upload');
|
|
45
|
+
const result = await uploadGovernanceScenarioPacks(ctx.systemKey, ctx.dataplaneUrl, ctx.authConfig, {
|
|
43
46
|
silent: quietSidecar
|
|
44
47
|
});
|
|
45
|
-
sidecar.governance =
|
|
48
|
+
sidecar.governance = normalizeGovernanceUploadResult(result);
|
|
46
49
|
} catch (err) {
|
|
47
50
|
sidecar.governance = { skipped: true, reason: err.message || String(err) };
|
|
48
51
|
if (!quietSidecar) {
|
package/lib/commands/upload.js
CHANGED
|
@@ -44,6 +44,7 @@ const { maybeSyncOpenApiFilesForMcp } = require('./repair-openapi-sync');
|
|
|
44
44
|
const { exportProgrammaticOpenApiForRepair } = require('./repair-openapi-export');
|
|
45
45
|
const { resolveUploadPublishContext } = require('./upload-publish-context');
|
|
46
46
|
const { syncDeployJsonFromSources } = require('../external-system/sync-deploy-manifest');
|
|
47
|
+
const { assertUploadPackageIdentity } = require('../external-system/upload-identity');
|
|
47
48
|
const { handlePublicationAndFollowups } = require('./upload-sidecar-followups');
|
|
48
49
|
const { finalizeUploadPublishResult, finishUnchangedUploadPublication } = require('./upload-data-sync-finalize');
|
|
49
50
|
const { pushAndLogCredentialSecrets } = require('./upload-credential-push-log');
|
|
@@ -53,6 +54,10 @@ const {
|
|
|
53
54
|
resolveRoleAssistantSettingsVersion,
|
|
54
55
|
resolveRoleAssistantEnvironmentSettings
|
|
55
56
|
} = require('../role-assistant/settings');
|
|
57
|
+
const {
|
|
58
|
+
isRoleAssistantShellPackage,
|
|
59
|
+
uploadRoleAssistantShellPackage
|
|
60
|
+
} = require('./upload-role-assistant-shell');
|
|
56
61
|
|
|
57
62
|
/**
|
|
58
63
|
* Validates system-key format (same as download).
|
|
@@ -149,7 +154,10 @@ async function runUploadValidatePublish(
|
|
|
149
154
|
{ timeoutMs: options.timeoutMs }
|
|
150
155
|
);
|
|
151
156
|
if (res?.success === false) {
|
|
152
|
-
|
|
157
|
+
const err = new Error(formatApiError(res, dataplaneUrl));
|
|
158
|
+
const status = Number(res.status || res.statusCode);
|
|
159
|
+
err.statusCode = status >= 400 && status < 600 ? status : 400;
|
|
160
|
+
throw err;
|
|
153
161
|
}
|
|
154
162
|
return res;
|
|
155
163
|
}
|
|
@@ -256,6 +264,7 @@ async function buildValidatedUploadManifestPayload(systemKey, opts = {}) {
|
|
|
256
264
|
}
|
|
257
265
|
}
|
|
258
266
|
await resolvePayloadConfiguration(systemKey, payload, pathOptions);
|
|
267
|
+
assertUploadPackageIdentity(payload, systemKey);
|
|
259
268
|
return { manifest, payload };
|
|
260
269
|
}
|
|
261
270
|
|
|
@@ -312,7 +321,8 @@ async function completeUploadAfterPublish(systemKey, options, manifest, payload,
|
|
|
312
321
|
const pushMeta = await pushAndLogCredentialSecrets(ctx.dataplaneUrl, ctx.authConfig, systemKey, payload, {
|
|
313
322
|
json: options.json === true,
|
|
314
323
|
pathOptions: options.pathOptions,
|
|
315
|
-
suppressCredentialLog: quietCompact
|
|
324
|
+
suppressCredentialLog: quietCompact,
|
|
325
|
+
excludeSecretKeys: options.excludeSecretKeys
|
|
316
326
|
});
|
|
317
327
|
await logAndSyncLocalOpenApiForUpload(systemKey, manifest, {
|
|
318
328
|
dataplaneUrl: ctx.dataplaneUrl,
|
|
@@ -417,7 +427,12 @@ async function uploadExternalSystem(systemKey, options = {}) {
|
|
|
417
427
|
: options.minimal === false
|
|
418
428
|
? false
|
|
419
429
|
: options.verbose !== true;
|
|
420
|
-
const uploadOptions = { ...options, minimal };
|
|
430
|
+
const uploadOptions = { ...options, minimal, pathOptions };
|
|
431
|
+
if (await isRoleAssistantShellPackage(systemKey, uploadOptions)) {
|
|
432
|
+
return uploadRoleAssistantShellPackage(systemKey, uploadOptions, {
|
|
433
|
+
resolveDataplaneAndAuth
|
|
434
|
+
});
|
|
435
|
+
}
|
|
421
436
|
if (!minimal) {
|
|
422
437
|
logger.log('');
|
|
423
438
|
logger.log(sectionTitle('Upload external system'));
|
|
@@ -10,7 +10,7 @@ const fs = require('fs');
|
|
|
10
10
|
const yaml = require('js-yaml');
|
|
11
11
|
const config = require('./config');
|
|
12
12
|
const { getEnvHosts } = require('../utils/env-endpoints');
|
|
13
|
-
const { getContainerPortFromPath } = require('../utils/port-resolver');
|
|
13
|
+
const { getContainerPortFromPath, isExternalAppPath } = require('../utils/port-resolver');
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Gets base docker environment config
|
|
@@ -69,6 +69,9 @@ function getContainerPortFromDockerEnv(dockerEnv) {
|
|
|
69
69
|
* @returns {Promise<string>} Updated content with PORT set
|
|
70
70
|
*/
|
|
71
71
|
async function updatePortForDocker(resolved, variablesPath) {
|
|
72
|
+
if (isExternalAppPath(variablesPath)) {
|
|
73
|
+
return resolved;
|
|
74
|
+
}
|
|
72
75
|
let dockerEnv = await getBaseDockerEnv();
|
|
73
76
|
dockerEnv = applyDockerEnvOverride(dockerEnv);
|
|
74
77
|
|