@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
|
@@ -15,7 +15,10 @@ const { buildSlackApprovalGuide } = require('./slack');
|
|
|
15
15
|
const { buildTeamsBotApprovalGuide } = require('./teams-bot');
|
|
16
16
|
const { buildMicrosoftCopilotApprovalGuide } = require('./microsoft-copilot');
|
|
17
17
|
const { buildChatGptApprovalGuide } = require('./chatgpt');
|
|
18
|
+
const { buildClaudeApprovalGuide } = require('./claude');
|
|
18
19
|
const { buildWebEmbedInstallGuide } = require('./web-embed');
|
|
20
|
+
const { buildMcpClientInstallGuide } = require('./mcp-client');
|
|
21
|
+
const { vendorFacingUrlsFromCtx } = require('../vendor-dataplane-url');
|
|
19
22
|
const { buildCredentialPortalUrl } = require('./credential-portal');
|
|
20
23
|
|
|
21
24
|
/** @type {Record<string, (ctx: Object) => { portalUrl: string|null, steps: string[] }>} */
|
|
@@ -24,6 +27,8 @@ const GUIDE_BUILDERS = {
|
|
|
24
27
|
'teams-bot': buildTeamsBotApprovalGuide,
|
|
25
28
|
'microsoft-copilot': buildMicrosoftCopilotApprovalGuide,
|
|
26
29
|
chatgpt: buildChatGptApprovalGuide,
|
|
30
|
+
claude: buildClaudeApprovalGuide,
|
|
31
|
+
'mcp-client': buildMcpClientInstallGuide,
|
|
27
32
|
'web-embed': buildWebEmbedInstallGuide
|
|
28
33
|
};
|
|
29
34
|
|
|
@@ -51,50 +56,110 @@ function buildResumeCommand(channelTarget, name) {
|
|
|
51
56
|
|
|
52
57
|
/**
|
|
53
58
|
* @param {string} channelTarget
|
|
54
|
-
* @param {Object}
|
|
59
|
+
* @param {Object} context
|
|
60
|
+
* @param {Object} target
|
|
55
61
|
* @returns {Object}
|
|
56
62
|
*/
|
|
57
|
-
function
|
|
58
|
-
const target = getChannelTarget(channelTarget);
|
|
59
|
-
const builder = GUIDE_BUILDERS[channelTarget];
|
|
60
|
-
if (!builder) {
|
|
61
|
-
throw new Error(`No approval guide for channel target "${channelTarget}"`);
|
|
62
|
-
}
|
|
63
|
-
|
|
63
|
+
function approvalGuideContext(channelTarget, context, target) {
|
|
64
64
|
const projectRoot = context.projectRoot || process.cwd();
|
|
65
65
|
const name = context.name || '';
|
|
66
|
+
const baseName = context.baseName || name;
|
|
66
67
|
const artifactPath = resolveArtifactPath(projectRoot, channelTarget, context.artifactPath);
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
const credentialPortalUrl = context.dataplaneBaseUrl
|
|
70
|
-
? buildCredentialPortalUrl(context.dataplaneBaseUrl, channelTarget)
|
|
71
|
-
: null;
|
|
72
|
-
const baseCtx = {
|
|
68
|
+
const resumeName = channelTarget === 'chatgpt' || channelTarget === 'claude' ? baseName : name;
|
|
69
|
+
return {
|
|
73
70
|
channelTarget,
|
|
74
71
|
name,
|
|
75
|
-
baseName
|
|
72
|
+
baseName,
|
|
76
73
|
environment: context.environment || 'dev',
|
|
77
74
|
artifactPath,
|
|
78
|
-
|
|
75
|
+
installGuidePath: path.join(path.dirname(artifactPath), 'INSTALL.md'),
|
|
76
|
+
resumeCommand: buildResumeCommand(channelTarget, resumeName),
|
|
79
77
|
credentialKey: target.credentialKey,
|
|
80
|
-
credentialPortalUrl
|
|
78
|
+
credentialPortalUrl: context.dataplaneBaseUrl
|
|
79
|
+
? buildCredentialPortalUrl(context.dataplaneBaseUrl, channelTarget)
|
|
80
|
+
: null,
|
|
81
|
+
controllerUrl: context.controllerUrl,
|
|
82
|
+
oauth2ProfileUrl: context.oauth2ProfileUrl,
|
|
83
|
+
mcpUrl: context.mcpUrl,
|
|
84
|
+
appName: context.appName || name,
|
|
85
|
+
description: context.description,
|
|
86
|
+
authorizationUrl: context.authorizationUrl,
|
|
87
|
+
tokenUrl: context.tokenUrl,
|
|
88
|
+
clientId: context.clientId
|
|
81
89
|
};
|
|
90
|
+
}
|
|
82
91
|
|
|
83
|
-
|
|
92
|
+
/**
|
|
93
|
+
* @param {Object} context
|
|
94
|
+
* @param {Object} guide
|
|
95
|
+
* @param {string} channelTarget
|
|
96
|
+
* @returns {string|null}
|
|
97
|
+
*/
|
|
98
|
+
function approvalGuideCredentialUrl(channelTarget, context, guide) {
|
|
99
|
+
if (guide.credentialPortalUrl !== undefined) {
|
|
100
|
+
return guide.credentialPortalUrl;
|
|
101
|
+
}
|
|
102
|
+
if (!context.dataplaneBaseUrl) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return buildCredentialPortalUrl(context.dataplaneBaseUrl, channelTarget);
|
|
106
|
+
}
|
|
84
107
|
|
|
108
|
+
/**
|
|
109
|
+
* @param {string} channelTarget
|
|
110
|
+
* @param {Object} [context]
|
|
111
|
+
* @returns {Object}
|
|
112
|
+
*/
|
|
113
|
+
function buildChannelApprovalGuide(channelTarget, context = {}) {
|
|
114
|
+
const target = getChannelTarget(channelTarget);
|
|
115
|
+
const builder = GUIDE_BUILDERS[channelTarget];
|
|
116
|
+
if (!builder) {
|
|
117
|
+
throw new Error(`No approval guide for channel target "${channelTarget}"`);
|
|
118
|
+
}
|
|
119
|
+
const baseCtx = approvalGuideContext(channelTarget, context, target);
|
|
120
|
+
const guide = builder(baseCtx);
|
|
85
121
|
return {
|
|
86
122
|
channelTarget,
|
|
123
|
+
heading: guide.heading,
|
|
87
124
|
portalUrl: guide.portalUrl,
|
|
88
|
-
artifactPath,
|
|
89
|
-
installGuidePath,
|
|
90
|
-
resumeCommand,
|
|
125
|
+
artifactPath: baseCtx.artifactPath,
|
|
126
|
+
installGuidePath: baseCtx.installGuidePath,
|
|
127
|
+
resumeCommand: baseCtx.resumeCommand,
|
|
91
128
|
credentialKey: target.credentialKey,
|
|
92
|
-
credentialPortalUrl,
|
|
129
|
+
credentialPortalUrl: approvalGuideCredentialUrl(channelTarget, context, guide),
|
|
93
130
|
steps: guide.steps,
|
|
94
131
|
approvalRequired: target.approvalRequired === true
|
|
95
132
|
};
|
|
96
133
|
}
|
|
97
134
|
|
|
135
|
+
/**
|
|
136
|
+
* @param {Object} params
|
|
137
|
+
* @returns {Object|null}
|
|
138
|
+
*/
|
|
139
|
+
function buildLiveInstallApprovalGuide(params) {
|
|
140
|
+
const { channelTarget, status, artifact, name, baseName, ctx, options } = params;
|
|
141
|
+
if (status !== 'approvalRequired') {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
const runtimeValues = params.runtimeValues || {};
|
|
145
|
+
const asMetadata = params.preflight && params.preflight.asMetadata;
|
|
146
|
+
const vendor = vendorFacingUrlsFromCtx(ctx);
|
|
147
|
+
return buildChannelApprovalGuide(channelTarget, {
|
|
148
|
+
projectRoot: options.projectRoot || process.cwd(),
|
|
149
|
+
name,
|
|
150
|
+
baseName,
|
|
151
|
+
artifactPath: artifact.outputPath,
|
|
152
|
+
dataplaneBaseUrl: vendor.dataplaneBaseUrl,
|
|
153
|
+
controllerUrl: vendor.controllerUrl,
|
|
154
|
+
environment: ctx.environment || options.environment || 'dev',
|
|
155
|
+
oauth2ProfileUrl: runtimeValues.oauth2ProfileUrl,
|
|
156
|
+
mcpUrl: runtimeValues.mcpUrl,
|
|
157
|
+
description: runtimeValues.appDescription,
|
|
158
|
+
authorizationUrl: asMetadata && asMetadata.authorization_endpoint,
|
|
159
|
+
tokenUrl: asMetadata && asMetadata.token_endpoint
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
|
|
98
163
|
/**
|
|
99
164
|
* @param {string} channelTarget
|
|
100
165
|
* @param {Object} [context]
|
|
@@ -107,6 +172,7 @@ function resolveApprovalPortalUrl(channelTarget, context = {}) {
|
|
|
107
172
|
module.exports = {
|
|
108
173
|
GUIDE_BUILDERS,
|
|
109
174
|
buildChannelApprovalGuide,
|
|
175
|
+
buildLiveInstallApprovalGuide,
|
|
110
176
|
resolveApprovalPortalUrl,
|
|
111
177
|
resolveArtifactPath,
|
|
112
178
|
buildResumeCommand
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Developer MCP client go-live steps — reload the editor after mcp.json merge.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Remaining operator step for mcp-client
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {Object} ctx
|
|
11
|
+
* @returns {{ heading: string, portalUrl: null, steps: string[], credentialPortalUrl: null }}
|
|
12
|
+
*/
|
|
13
|
+
function buildMcpClientInstallGuide(ctx) {
|
|
14
|
+
const profile = ctx.mcpClientProfileKey || '<profile>';
|
|
15
|
+
return {
|
|
16
|
+
heading: 'Reload the editor',
|
|
17
|
+
portalUrl: null,
|
|
18
|
+
credentialPortalUrl: null,
|
|
19
|
+
steps: [
|
|
20
|
+
'Reload the editor so it reads the merged MCP client config.',
|
|
21
|
+
'Sign in with your user account when the editor starts OAuth.',
|
|
22
|
+
`Re-run: aifabrix channel add mcp-client --target ${profile} --name "${ctx.name || ''}"`
|
|
23
|
+
]
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = { buildMcpClientInstallGuide };
|
|
@@ -8,8 +8,53 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
+
const fs = require('../../internal/fs-real-sync');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
|
|
11
14
|
const DEVELOPER_PORTAL_URL = 'https://dev.teams.microsoft.com/';
|
|
15
|
+
const DEVELOPER_PORTAL_APPS_URL = 'https://dev.teams.microsoft.com/apps';
|
|
12
16
|
const TEAMS_ADMIN_APPS_URL = 'https://admin.teams.microsoft.com/policies/manage-apps';
|
|
17
|
+
const TEAMS_APP_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Developer Portal publish-to-org page for a packaged Teams app id.
|
|
21
|
+
* @param {string} [appId]
|
|
22
|
+
* @returns {string}
|
|
23
|
+
*/
|
|
24
|
+
function developerPortalPublishOrgUrl(appId) {
|
|
25
|
+
const id = typeof appId === 'string' ? appId.trim() : '';
|
|
26
|
+
if (!TEAMS_APP_ID.test(id)) {
|
|
27
|
+
return DEVELOPER_PORTAL_APPS_URL;
|
|
28
|
+
}
|
|
29
|
+
return `${DEVELOPER_PORTAL_APPS_URL}/${id}/publish-org`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Packaged Teams app / manifest id from runtime values or the built source manifest.
|
|
34
|
+
* @param {Object|null} ctx
|
|
35
|
+
* @param {Object|null} runtimeValues
|
|
36
|
+
* @returns {string}
|
|
37
|
+
*/
|
|
38
|
+
function copilotPackageAppId(ctx, runtimeValues) {
|
|
39
|
+
const fromRuntime =
|
|
40
|
+
runtimeValues && typeof runtimeValues.packageAppId === 'string'
|
|
41
|
+
? runtimeValues.packageAppId.trim()
|
|
42
|
+
: '';
|
|
43
|
+
if (fromRuntime) {
|
|
44
|
+
return fromRuntime;
|
|
45
|
+
}
|
|
46
|
+
const root = ctx && typeof ctx.projectRoot === 'string' ? ctx.projectRoot.trim() : '';
|
|
47
|
+
if (!root) {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const manifestPath = path.join(root, 'dist', 'channels', 'microsoft-copilot', 'source', 'manifest.json');
|
|
52
|
+
const parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
53
|
+
return typeof parsed.id === 'string' ? parsed.id.trim() : '';
|
|
54
|
+
} catch {
|
|
55
|
+
return '';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
13
58
|
|
|
14
59
|
/**
|
|
15
60
|
* @param {Object} ctx
|
|
@@ -25,14 +70,15 @@ function buildMicrosoftCopilotApprovalGuide(ctx) {
|
|
|
25
70
|
(typeof ctx.baseName === 'string' && ctx.baseName.trim()) ||
|
|
26
71
|
'your app';
|
|
27
72
|
return {
|
|
28
|
-
portalUrl:
|
|
73
|
+
portalUrl: DEVELOPER_PORTAL_APPS_URL,
|
|
74
|
+
heading: 'Organisation publish / Teams admin approval required',
|
|
29
75
|
steps: [
|
|
30
|
-
`Open Teams Developer Portal (${
|
|
76
|
+
`Open Teams Developer Portal (${DEVELOPER_PORTAL_APPS_URL}).`,
|
|
31
77
|
`Click Import an app → import ${zipName}. Preserve the generated stable manifest.json.id. Do not create an unrelated new Teams app.`,
|
|
32
78
|
'Developer Portal → selected app → Publish to your org → Distribute / submit.',
|
|
33
79
|
`Teams admin approves in ${TEAMS_ADMIN_APPS_URL} (Manage apps → search → allow). Expect Published / Unblocked per organisation policy. Allow several minutes for propagation.`,
|
|
34
80
|
`Open Teams → Apps (Built for your org), click "${appName}", Add the application, then choose Open with Copilot.`,
|
|
35
|
-
'In Copilot, click "
|
|
81
|
+
'In Copilot, click a conversation starter titled like "vX.Y.Z — Role Assistants" and run it.',
|
|
36
82
|
'Confirm Runtime MCP and governed tools using INSTALL.md, then re-run with --probe after organisation publish.',
|
|
37
83
|
`After the app is available under Built for your org, re-run: ${ctx.resumeCommand}`
|
|
38
84
|
]
|
|
@@ -41,6 +87,9 @@ function buildMicrosoftCopilotApprovalGuide(ctx) {
|
|
|
41
87
|
|
|
42
88
|
module.exports = {
|
|
43
89
|
buildMicrosoftCopilotApprovalGuide,
|
|
90
|
+
copilotPackageAppId,
|
|
91
|
+
developerPortalPublishOrgUrl,
|
|
44
92
|
DEVELOPER_PORTAL_URL,
|
|
93
|
+
DEVELOPER_PORTAL_APPS_URL,
|
|
45
94
|
TEAMS_ADMIN_APPS_URL
|
|
46
95
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Slack channel admin approval steps (plan 152).
|
|
2
|
+
* Slack channel admin approval steps (plan 152 / 176).
|
|
3
3
|
*
|
|
4
|
-
* @fileoverview Slack
|
|
4
|
+
* @fileoverview Automated Slack CLI path first; manifest paste is recovery
|
|
5
5
|
* @author AI Fabrix Team
|
|
6
|
-
* @version 1.
|
|
6
|
+
* @version 1.1.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
@@ -17,14 +17,14 @@ const { formatCredentialPortalStep } = require('./credential-portal');
|
|
|
17
17
|
function buildSlackApprovalGuide(ctx) {
|
|
18
18
|
return {
|
|
19
19
|
portalUrl: 'https://api.slack.com/apps',
|
|
20
|
+
heading: 'Slack workspace approval',
|
|
20
21
|
steps: [
|
|
21
|
-
'Open https://api.slack.com/apps
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
25
|
-
'
|
|
26
|
-
'
|
|
27
|
-
formatCredentialPortalStep(ctx, 'the Bot User OAuth Token and Signing Secret'),
|
|
22
|
+
'Open https://api.slack.com/apps only if channel add could not create the app (recovery).',
|
|
23
|
+
'Preferred: paste the slash command from Next actions in Slack, then paste the challenge code and continue.',
|
|
24
|
+
'Approve the Slack workspace install if Slack prompts.',
|
|
25
|
+
'Recovery: Create New App → From an app manifest, then paste or upload the generated Slack app manifest (path shown below).',
|
|
26
|
+
'Recovery only: copy the Bot User OAuth Token and Signing Secret from Slack app settings.',
|
|
27
|
+
formatCredentialPortalStep(ctx, 'the Bot User OAuth Token and Signing Secret (recovery only)'),
|
|
28
28
|
`When Slack shows the app as installed, re-run: ${ctx.resumeCommand}`,
|
|
29
29
|
'Optional: add --probe to verify callbacks and the assistant catalog.'
|
|
30
30
|
]
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Microsoft Teams bot channel admin approval steps
|
|
2
|
+
* Microsoft Teams bot channel admin approval steps.
|
|
3
3
|
*
|
|
4
|
-
* @fileoverview
|
|
4
|
+
* @fileoverview Tenant policy / org publish after Azure-managed bot provision
|
|
5
5
|
* @author AI Fabrix Team
|
|
6
6
|
* @version 1.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
-
const {
|
|
11
|
+
const { TEAMS_ADMIN_APPS_URL, TEAMS_OPEN_URL, TEAMS_POLICY_REMAINING } = require('../microsoft-provisioning/constants');
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @param {Object} ctx
|
|
@@ -16,16 +16,12 @@ const { formatCredentialPortalStep } = require('./credential-portal');
|
|
|
16
16
|
*/
|
|
17
17
|
function buildTeamsBotApprovalGuide(ctx) {
|
|
18
18
|
return {
|
|
19
|
-
portalUrl:
|
|
19
|
+
portalUrl: TEAMS_OPEN_URL,
|
|
20
|
+
heading: 'Tenant policy / org publish may still be required',
|
|
20
21
|
steps: [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
'In Azure Portal, register or link the Azure Bot resource and copy the Microsoft App ID.',
|
|
25
|
-
'Create a client secret (or upload certificate) for the bot app registration in Microsoft Entra.',
|
|
26
|
-
'Enable the Microsoft Teams channel on the Azure Bot resource.',
|
|
27
|
-
formatCredentialPortalStep(ctx, 'the Microsoft App ID and client secret'),
|
|
28
|
-
'Publish the app to your org (or sideload for lab) and complete tenant admin approval if prompted.',
|
|
22
|
+
`Open Teams (${TEAMS_OPEN_URL}) and install the generated package if sideloading is allowed.`,
|
|
23
|
+
TEAMS_POLICY_REMAINING,
|
|
24
|
+
`If custom app upload is restricted, approve in Teams admin centre: ${TEAMS_ADMIN_APPS_URL}`,
|
|
29
25
|
`After the bot is live in Teams, re-run: ${ctx.resumeCommand}`,
|
|
30
26
|
'Optional: add --probe to verify inbound JWT validation and the assistant catalog.'
|
|
31
27
|
]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vendor preflight and continuation dispatch for channel add.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Keep add-channel.js under the file-size limit
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
maybeAssertChatGptPreflight,
|
|
11
|
+
maybeRunChatGptContinuation
|
|
12
|
+
} = require('./chatgpt-channel-add');
|
|
13
|
+
const {
|
|
14
|
+
maybeAssertMcpClientPreflight,
|
|
15
|
+
maybeRunMcpClientContinuation
|
|
16
|
+
} = require('./mcp-client-channel-add');
|
|
17
|
+
const {
|
|
18
|
+
maybeAssertClaudePreflight,
|
|
19
|
+
maybeRunClaudeContinuation
|
|
20
|
+
} = require('./claude-channel-add');
|
|
21
|
+
const { assertIntegrationClientPermissions } = require('./channel-oauth-preflight');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Object} params
|
|
25
|
+
* @returns {Promise<void>}
|
|
26
|
+
*/
|
|
27
|
+
async function maybeAssertIntegrationClientPermissions(params) {
|
|
28
|
+
const ctx = params.ctx;
|
|
29
|
+
if (!ctx || (params.options && params.options.dryRun === true)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const token = (ctx.authConfig && ctx.authConfig.token) || ctx.bearerToken;
|
|
33
|
+
if (!token || !ctx.controllerUrl) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
await assertIntegrationClientPermissions(
|
|
37
|
+
{
|
|
38
|
+
controllerUrl: ctx.controllerUrl,
|
|
39
|
+
environment: ctx.environment,
|
|
40
|
+
bearerToken: token
|
|
41
|
+
},
|
|
42
|
+
params.channelTarget,
|
|
43
|
+
params.deps || {}
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {Object} params
|
|
49
|
+
* @returns {Promise<void>}
|
|
50
|
+
*/
|
|
51
|
+
async function runChannelAddPreflights(params) {
|
|
52
|
+
await maybeAssertIntegrationClientPermissions(params);
|
|
53
|
+
await maybeAssertChatGptPreflight(params);
|
|
54
|
+
await maybeAssertMcpClientPreflight(params);
|
|
55
|
+
await maybeAssertClaudePreflight(params);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {Object} params
|
|
60
|
+
* @returns {Promise<void>}
|
|
61
|
+
*/
|
|
62
|
+
async function runChannelAddContinuations(params) {
|
|
63
|
+
await maybeRunChatGptContinuation(params);
|
|
64
|
+
await maybeRunMcpClientContinuation(params);
|
|
65
|
+
await maybeRunClaudeContinuation(params);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Re-run remaining TTY for ChatGPT/Claude without regenerating artifacts.
|
|
70
|
+
* @param {Object} params
|
|
71
|
+
* @returns {Promise<boolean>}
|
|
72
|
+
*/
|
|
73
|
+
async function runSkippedRemoteMcpTty(params) {
|
|
74
|
+
if (params.channelTarget === 'chatgpt') {
|
|
75
|
+
await maybeAssertChatGptPreflight(params);
|
|
76
|
+
await maybeRunChatGptContinuation(params);
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
if (params.channelTarget === 'claude') {
|
|
80
|
+
await maybeAssertClaudePreflight(params);
|
|
81
|
+
await maybeRunClaudeContinuation(params);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
runChannelAddPreflights,
|
|
89
|
+
runChannelAddContinuations,
|
|
90
|
+
runSkippedRemoteMcpTty
|
|
91
|
+
};
|
|
@@ -8,28 +8,87 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
-
const fs = require('fs');
|
|
12
11
|
const path = require('path');
|
|
12
|
+
const fs = require('fs');
|
|
13
13
|
const chalk = require('chalk');
|
|
14
14
|
const logger = require('../utils/logger');
|
|
15
|
-
const {
|
|
15
|
+
const { printScaffolded, printUploaded, isChannelAddVerbose } = require('./channel-add-tty');
|
|
16
16
|
const { getIntegrationPath } = require('../utils/paths');
|
|
17
17
|
const { getExternalSystem } = require('../api/external-systems.api');
|
|
18
18
|
const { unwrapApiData } = require('../utils/external-system-readiness-core');
|
|
19
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
scaffoldChannelIntegration,
|
|
21
|
+
hasChannelIntegrationFiles
|
|
22
|
+
} = require('./channel-integration-generator');
|
|
20
23
|
const { resolveChannelAuthContext } = require('./channel-auth-context');
|
|
21
24
|
const { uploadExternalSystem } = require('../commands/upload');
|
|
25
|
+
const { materializeChannelInstanceSystem } = require('./channel-instance-materialize');
|
|
26
|
+
const { resolveChannelInstanceKey } = require('./channel-instance-key');
|
|
27
|
+
const { isNotFoundError } = require('./channel-instance-collision');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Default channel-add TTY: Publishing spinner, then one Uploaded line.
|
|
31
|
+
* Compact UPLOAD card and dataplane URL resolve stay on -v.
|
|
32
|
+
* @param {Object} options
|
|
33
|
+
* @param {Object} ctx
|
|
34
|
+
* @returns {Object}
|
|
35
|
+
*/
|
|
36
|
+
function buildChannelAddUploadOptions(options, ctx) {
|
|
37
|
+
const verbose = isChannelAddVerbose(options);
|
|
38
|
+
const shared = {
|
|
39
|
+
force: true,
|
|
40
|
+
authConfig: ctx.authConfig,
|
|
41
|
+
dataplaneUrl: ctx.dataplaneUrl,
|
|
42
|
+
environment: ctx.environment
|
|
43
|
+
};
|
|
44
|
+
if (verbose) {
|
|
45
|
+
return { ...shared, minimal: false, verbose: true };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
...shared,
|
|
49
|
+
minimal: true,
|
|
50
|
+
verbose: false,
|
|
51
|
+
silentResolve: true,
|
|
52
|
+
suppressSummary: true,
|
|
53
|
+
suppressPipelineSpinner: options.quiet === true
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function resolveInstanceKey(channelTarget, options = {}) {
|
|
58
|
+
return resolveChannelInstanceKey(channelTarget, options);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* HTTP install already has the caller JWT on options.authContext.
|
|
63
|
+
* Re-resolving via getDeploymentAuth(definitionKey) looks up
|
|
64
|
+
* `{key}-client-idKeyVault` inside builder-api and 500s.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} channelTarget
|
|
67
|
+
* @param {Object} options
|
|
68
|
+
* @returns {Promise<Object>}
|
|
69
|
+
*/
|
|
70
|
+
async function resolveEnsureAuthContext(channelTarget, options) {
|
|
71
|
+
if (options.authContext && typeof options.authContext === 'object') {
|
|
72
|
+
return options.authContext;
|
|
73
|
+
}
|
|
74
|
+
const verbose = isChannelAddVerbose(options);
|
|
75
|
+
return resolveChannelAuthContext(channelTarget, {
|
|
76
|
+
silent: options.quiet === true || !verbose
|
|
77
|
+
});
|
|
78
|
+
}
|
|
22
79
|
|
|
23
80
|
/**
|
|
24
81
|
* @param {string} channelTarget
|
|
25
82
|
* @param {string} [projectRoot]
|
|
83
|
+
* @param {string} [instanceKey]
|
|
26
84
|
* @returns {string}
|
|
27
85
|
*/
|
|
28
|
-
function resolveIntegrationDir(channelTarget, projectRoot) {
|
|
86
|
+
function resolveIntegrationDir(channelTarget, projectRoot, instanceKey) {
|
|
87
|
+
const folderKey = instanceKey || channelTarget;
|
|
29
88
|
if (projectRoot) {
|
|
30
|
-
return path.join(path.resolve(projectRoot), 'integration',
|
|
89
|
+
return path.join(path.resolve(projectRoot), 'integration', folderKey);
|
|
31
90
|
}
|
|
32
|
-
return getIntegrationPath(
|
|
91
|
+
return getIntegrationPath(folderKey);
|
|
33
92
|
}
|
|
34
93
|
|
|
35
94
|
/**
|
|
@@ -38,31 +97,65 @@ function resolveIntegrationDir(channelTarget, projectRoot) {
|
|
|
38
97
|
* @returns {Promise<boolean>}
|
|
39
98
|
*/
|
|
40
99
|
async function isCommunicationSystemUploaded(ctx, channelTarget) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
100
|
+
try {
|
|
101
|
+
const res = await getExternalSystem(ctx.dataplaneUrl, channelTarget, ctx.authConfig);
|
|
102
|
+
const system = unwrapApiData(res);
|
|
103
|
+
return !!(system && typeof system === 'object');
|
|
104
|
+
} catch (err) {
|
|
105
|
+
if (isNotFoundError(err)) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function maybeRegenerateInstanceDeployJson(integrationDir, instanceKey) {
|
|
113
|
+
const appPath = path.join(integrationDir, 'application.json');
|
|
114
|
+
if (!fs.existsSync(appPath)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const { generateDeployJson } = require('../generator');
|
|
118
|
+
await generateDeployJson(instanceKey, { appPath: integrationDir });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async function finishInstanceScaffold(integrationDir, definitionKey, instanceKey) {
|
|
122
|
+
materializeChannelInstanceSystem(integrationDir, definitionKey, instanceKey);
|
|
123
|
+
await maybeRegenerateInstanceDeployJson(integrationDir, instanceKey);
|
|
44
124
|
}
|
|
45
125
|
|
|
46
126
|
/**
|
|
47
|
-
* Scaffold integration/<target>/ when missing
|
|
127
|
+
* Scaffold integration/<target>/ when missing or incomplete.
|
|
128
|
+
* With --force, refresh files from the channel template (same as channel scaffold --force).
|
|
48
129
|
*
|
|
49
130
|
* @param {string} channelTarget
|
|
50
131
|
* @param {Object} options
|
|
51
132
|
* @returns {Promise<{ scaffolded: boolean, integrationDir: string }>}
|
|
52
133
|
*/
|
|
53
134
|
async function ensureChannelScaffold(channelTarget, options = {}) {
|
|
54
|
-
const
|
|
55
|
-
|
|
135
|
+
const instanceKey = resolveInstanceKey(channelTarget, options);
|
|
136
|
+
const integrationDir = resolveIntegrationDir(
|
|
137
|
+
channelTarget,
|
|
138
|
+
options.projectRoot,
|
|
139
|
+
instanceKey
|
|
140
|
+
);
|
|
141
|
+
const force = options.force === true;
|
|
142
|
+
if (hasChannelIntegrationFiles(integrationDir, instanceKey) && !force) {
|
|
143
|
+
await finishInstanceScaffold(integrationDir, channelTarget, instanceKey);
|
|
56
144
|
return { scaffolded: false, integrationDir };
|
|
57
145
|
}
|
|
58
146
|
const result = await scaffoldChannelIntegration(channelTarget, {
|
|
59
147
|
projectRoot: options.projectRoot,
|
|
60
|
-
|
|
148
|
+
integrationDir,
|
|
149
|
+
allowExperimental: options.allowExperimental === true,
|
|
150
|
+
force
|
|
61
151
|
});
|
|
152
|
+
await finishInstanceScaffold(result.integrationDir, channelTarget, instanceKey);
|
|
62
153
|
if (options.quiet !== true) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
154
|
+
printScaffolded(result.integrationDir);
|
|
155
|
+
if (isChannelAddVerbose(options) && Array.isArray(result.files)) {
|
|
156
|
+
for (const file of result.files) {
|
|
157
|
+
logger.log(chalk.gray(file));
|
|
158
|
+
}
|
|
66
159
|
}
|
|
67
160
|
}
|
|
68
161
|
return { scaffolded: true, integrationDir: result.integrationDir };
|
|
@@ -79,25 +172,28 @@ async function ensureChannelUploaded(channelTarget, options = {}) {
|
|
|
79
172
|
if (options.dryRun === true) {
|
|
80
173
|
return { uploaded: false, skipped: true, ctx: null };
|
|
81
174
|
}
|
|
82
|
-
const
|
|
175
|
+
const instanceKey = resolveInstanceKey(channelTarget, options);
|
|
176
|
+
const verbose = isChannelAddVerbose(options);
|
|
177
|
+
const ctx = await resolveEnsureAuthContext(channelTarget, options);
|
|
83
178
|
const force = options.force === true;
|
|
84
|
-
const alreadyUploaded = force ? false : await isCommunicationSystemUploaded(ctx,
|
|
179
|
+
const alreadyUploaded = force ? false : await isCommunicationSystemUploaded(ctx, instanceKey);
|
|
85
180
|
if (alreadyUploaded) {
|
|
86
|
-
if (options.quiet !== true) {
|
|
87
|
-
logger.log(chalk.gray(` Communication system "${
|
|
181
|
+
if (verbose && options.quiet !== true) {
|
|
182
|
+
logger.log(chalk.gray(` Communication system "${instanceKey}" already on dataplane`));
|
|
88
183
|
}
|
|
89
184
|
return { uploaded: false, skipped: true, ctx };
|
|
90
185
|
}
|
|
91
|
-
if (options.quiet !== true) {
|
|
186
|
+
if (verbose && options.quiet !== true) {
|
|
92
187
|
const reason = force ? 'force upload' : 'not found on dataplane';
|
|
93
|
-
logger.log(chalk.white(`Uploading ${
|
|
188
|
+
logger.log(chalk.white(`Uploading ${instanceKey} (${reason})…`));
|
|
94
189
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
190
|
+
const integrationDir = resolveIntegrationDir(channelTarget, options.projectRoot, instanceKey);
|
|
191
|
+
await uploadExternalSystem(instanceKey, {
|
|
192
|
+
...buildChannelAddUploadOptions(options, ctx),
|
|
193
|
+
pathOptions: { appPath: integrationDir }
|
|
98
194
|
});
|
|
99
|
-
if (options.quiet !== true) {
|
|
100
|
-
|
|
195
|
+
if (options.quiet !== true && options.suppressUploadedLine !== true) {
|
|
196
|
+
printUploaded(instanceKey);
|
|
101
197
|
}
|
|
102
198
|
return { uploaded: true, skipped: false, ctx };
|
|
103
199
|
}
|
|
@@ -122,6 +218,7 @@ async function ensureChannelReadyForAdd(channelTarget, options = {}) {
|
|
|
122
218
|
module.exports = {
|
|
123
219
|
resolveIntegrationDir,
|
|
124
220
|
isCommunicationSystemUploaded,
|
|
221
|
+
buildChannelAddUploadOptions,
|
|
125
222
|
ensureChannelScaffold,
|
|
126
223
|
ensureChannelUploaded,
|
|
127
224
|
ensureChannelReadyForAdd
|