@aifabrix/builder 2.54.1 → 2.55.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +172 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +272 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/start.js +310 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/work-search.api.js +31 -4
- package/lib/api/work.api.js +19 -12
- package/lib/app/deploy.js +7 -4
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/offer-create-from-template.js +184 -0
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +1 -0
- package/lib/channels/approval-guides/claude.js +2 -2
- package/lib/channels/channel-add-failure.js +1 -0
- package/lib/channels/channel-add-remaining.js +15 -9
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +2 -1
- package/lib/channels/channel-install-envelope.js +4 -2
- package/lib/channels/channel-integration-generator.js +2 -0
- package/lib/channels/channel-runtime-resolver.js +14 -0
- package/lib/channels/channel-targets.js +31 -5
- package/lib/channels/claude-setup-values.js +4 -1
- package/lib/channels/slack-channel-add.js +59 -6
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/install-cli.js +14 -2
- package/lib/channels/slack-provisioning/with-curl-on-path.js +6 -1
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-app.js +8 -1
- package/lib/cli/setup-auth.js +11 -2
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +3 -1
- package/lib/commands/agent-kit-help.js +149 -0
- package/lib/commands/agent-kit.js +417 -0
- package/lib/commands/auth-status-user.js +99 -0
- package/lib/commands/auth-status.js +14 -4
- package/lib/commands/channel-add-help.js +5 -5
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/datasource-load-export-cli.js +7 -2
- package/lib/commands/datasource-test-trust-cli.js +5 -1
- package/lib/commands/governance-command-action.js +5 -4
- package/lib/commands/identity-membership-role-cache.js +6 -1
- package/lib/commands/lifecycle-command-action.js +16 -15
- package/lib/commands/login-credentials.js +8 -3
- package/lib/commands/login-device.js +14 -5
- package/lib/commands/login.js +14 -1
- package/lib/commands/logout.js +50 -15
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-rbac.js +16 -10
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +8 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +140 -59
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-sidecar-followups.js +4 -1
- package/lib/commands/verify-governance-command-action.js +9 -7
- package/lib/commands/verify-operations-command-action.js +9 -8
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/commands/verify-trust-command-action.js +6 -5
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy.js +12 -2
- package/lib/external-system/download-role-assistant.js +41 -15
- package/lib/external-system/download.js +8 -3
- package/lib/generator/helpers.js +12 -1
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +232 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +56 -21
- package/lib/programmatic/capability-registry.js +1 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +4 -1
- package/lib/programmatic/openapi-component-schemas.js +1 -0
- package/lib/programmatic/openapi-descriptions.js +9 -3
- package/lib/programmatic/openapi-envelope-examples.js +7 -0
- package/lib/programmatic/openapi-operation-bindings.js +5 -0
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +8 -5
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +1 -0
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +7 -0
- package/lib/programmatic/run-channel-catalog.js +50 -8
- package/lib/programmatic/run-channel-install-options.js +5 -1
- package/lib/programmatic/run-download.js +41 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/knowledge-sync-settings-push.js +172 -0
- package/lib/role-assistant/knowledge-sync.js +9 -126
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +149 -31
- package/lib/role-assistant/test-cases-evidence.js +44 -5
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +297 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +20 -2
- package/lib/role-assistant/test-cases.js +34 -168
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +20 -5
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub.js +45 -21
- package/lib/role-assistant/test-runner.js +53 -10
- package/lib/schema/external-datasource.schema.json +36 -5
- package/lib/schema/external-system.schema.json +20 -2
- package/lib/schema/infra-parameter.schema.json +51 -3
- package/lib/schema/infra.parameter.yaml +476 -40
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/schema/type/document-storage.json +1 -1
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/api-required-permissions.js +271 -0
- package/lib/utils/api.js +16 -13
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/cli-json-exit.js +41 -0
- package/lib/utils/cli-utils.js +23 -5
- package/lib/utils/controller-url.js +78 -4
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/deployment-errors.js +15 -0
- package/lib/utils/deployment-validation-helpers.js +4 -1
- package/lib/utils/device-code.js +31 -10
- package/lib/utils/error-formatters/error-parser.js +16 -1
- package/lib/utils/error-formatters/permission-errors.js +19 -5
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/keycloak-realm-ready.js +5 -2
- package/lib/utils/logger.js +1 -0
- package/lib/utils/paths.js +26 -5
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/secrets-helpers.js +2 -2
- package/lib/utils/write-stream-and-wait.js +63 -0
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +3 -2
- package/package.json +20 -6
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +104 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +59 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +52 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +43 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +65 -0
- package/templates/agent-kit/skills/shared/login.md +16 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/dataplane/application.yaml +2 -3
- package/templates/applications/dataplane/env.template +5 -5
- package/templates/applications/dataplane/rbac.yaml +28 -0
- package/templates/applications/keycloak/env.template +3 -3
- package/templates/applications/miso-controller/application.yaml +21 -2
- package/templates/applications/miso-controller/env.template +96 -25
- package/templates/applications/miso-controller/rbac.yaml +5 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +3 -0
- package/templates/channels/claude/channel.json +1 -1
- package/templates/channels/claude/install.template.md.hbs +1 -0
- package/templates/channels/claude/integration/claude-system.json +1 -1
- package/templates/channels/slack/channel.json +11 -0
- package/templates/channels/slack/install.template.md.hbs +9 -0
- package/templates/channels/slack/integration/slack-system.json +11 -0
- package/templates/channels/slack/manifest.template.json.hbs +6 -3
- package/templates/channels/teams-bot/channel.json +1 -0
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
package/lib/app/show.js
CHANGED
|
@@ -33,6 +33,8 @@ const {
|
|
|
33
33
|
attachCertificationVerifyFromDataplane,
|
|
34
34
|
sanitizeCertificationForJson
|
|
35
35
|
} = require('./certification-show-enrich');
|
|
36
|
+
const { resolveManifestAuthMethod } = require('../utils/external-system-readiness-compact-display');
|
|
37
|
+
const { resolveAuthenticationSlots } = require('../utils/authentication-slot-show');
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
40
|
* Attach `runReloadDefault` / `runProxyDefault` from ~/.aifabrix `applications.<appKey>`.
|
|
@@ -466,6 +468,13 @@ function pickExternalVersion(res, config, system) {
|
|
|
466
468
|
return (res && res.version) ?? config.version ?? system.version ?? '—';
|
|
467
469
|
}
|
|
468
470
|
|
|
471
|
+
function pickCredentialMethod(config, system) {
|
|
472
|
+
const source = config && (config.authentication || config.authentications) ? config : system;
|
|
473
|
+
const method = resolveManifestAuthMethod(source);
|
|
474
|
+
if (!method || method === 'unknown') return undefined;
|
|
475
|
+
return method;
|
|
476
|
+
}
|
|
477
|
+
|
|
469
478
|
function resolveExternalSystemMeta(res, config, system, application, appKey) {
|
|
470
479
|
return {
|
|
471
480
|
displayName: pickExternalDisplayName(res, system, application, appKey),
|
|
@@ -501,13 +510,27 @@ function buildBaseExternalResult(configData, appKey, openapiFiles, openapiEndpoi
|
|
|
501
510
|
permissions: application.permissions
|
|
502
511
|
},
|
|
503
512
|
openapiFiles,
|
|
504
|
-
openapiEndpoints
|
|
513
|
+
openapiEndpoints,
|
|
514
|
+
credentialMethod: pickCredentialMethod(config, system),
|
|
515
|
+
authenticationSlots: resolveAuthenticationSlots(config, system)
|
|
505
516
|
};
|
|
506
517
|
}
|
|
507
518
|
|
|
519
|
+
function applyCredentialFieldsToResult(result, res) {
|
|
520
|
+
if (res.credentialId !== undefined && res.credentialId !== null) result.credentialId = res.credentialId;
|
|
521
|
+
if (res.authenticationStatus !== undefined && res.authenticationStatus !== null) {
|
|
522
|
+
result.authenticationStatus = res.authenticationStatus;
|
|
523
|
+
}
|
|
524
|
+
const resConfig = res.config && typeof res.config === 'object' ? res.config : {};
|
|
525
|
+
const fromConfig = pickCredentialMethod(resConfig, {});
|
|
526
|
+
if (fromConfig) result.credentialMethod = fromConfig;
|
|
527
|
+
const fromSlots = resolveAuthenticationSlots(resConfig, {});
|
|
528
|
+
if (fromSlots.length > 0) result.authenticationSlots = fromSlots;
|
|
529
|
+
}
|
|
530
|
+
|
|
508
531
|
function applySystemResponseToResult(result, res) {
|
|
509
532
|
result.dataplaneStatus = res.status;
|
|
510
|
-
|
|
533
|
+
applyCredentialFieldsToResult(result, res);
|
|
511
534
|
if (res.showOpenApiDocs !== undefined) result.showOpenApiDocs = res.showOpenApiDocs;
|
|
512
535
|
if (res.mcpServerUrl !== undefined && res.mcpServerUrl !== null) result.mcpServerUrl = res.mcpServerUrl;
|
|
513
536
|
if (res.apiDocumentUrl !== undefined && res.apiDocumentUrl !== null) result.apiDocumentUrl = res.apiDocumentUrl;
|
|
@@ -350,6 +350,7 @@ async function resolveInstallRuntimeValues(params, packageContext, runtimeToolNa
|
|
|
350
350
|
appDescription: description,
|
|
351
351
|
icon: options.icon,
|
|
352
352
|
commandPrefix: options.commandPrefix,
|
|
353
|
+
enableMcpServer: options.enableMcpServer,
|
|
353
354
|
layerBToolNames: runtimeToolNames,
|
|
354
355
|
packageContext,
|
|
355
356
|
entraProvider,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Claude remaining workspace steps (customer-facing).
|
|
3
3
|
*
|
|
4
|
-
* @fileoverview Short Claude connector Name
|
|
4
|
+
* @fileoverview Short Claude connector Name, Server URL, and OAuth steps — no protocol dump
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
@@ -21,7 +21,7 @@ function buildClaudeApprovalGuide(ctx) {
|
|
|
21
21
|
credentialPortalUrl: null,
|
|
22
22
|
steps: [
|
|
23
23
|
`Open ${CLAUDE_CONNECTORS_URL}`,
|
|
24
|
-
`Add a custom connector with Name: ${name}; Server URL: ${serverUrl}.`
|
|
24
|
+
`Add a custom connector with Name: ${name}; Server URL: ${serverUrl}; Authentication: OAuth.`
|
|
25
25
|
]
|
|
26
26
|
};
|
|
27
27
|
}
|
|
@@ -16,6 +16,7 @@ const BOUNDARY_MATCHERS = [
|
|
|
16
16
|
tests: [/unknown channel/i, /already configured/i, /needs a terminal/i, /--name is required/i, /needs --target/i, /unknown mcp client profile/i]
|
|
17
17
|
},
|
|
18
18
|
{ boundary: 'experimental', tests: [/is experimental/i] },
|
|
19
|
+
{ boundary: 'unavailable', tests: [/is coming soon/i, /is not available/i] },
|
|
19
20
|
{ boundary: 'preflight', tests: [/chatgpt preflight/i, /claude preflight/i, /mcp client preflight/i, /authentication required/i, /dataplanebaseurl is required/i] },
|
|
20
21
|
{ boundary: 'callback', tests: [/chatgpt callback/i, /claude callback/i, /mcp client callback/i] },
|
|
21
22
|
{ boundary: 'oauth', tests: [/oauth/i, /trustedissuer/i, /vault-reference/i] },
|
|
@@ -30,6 +30,7 @@ const { printMcpClientDryRunTty } = require('./mcp-client-channel-add');
|
|
|
30
30
|
const { printClaudeDryRunTty } = require('./claude-channel-add');
|
|
31
31
|
const { CLAUDE_REMAINING_STEPS } = require('./claude-runtime-contract');
|
|
32
32
|
const { vendorFacingUrlsFromCtx } = require('./vendor-dataplane-url');
|
|
33
|
+
const { slackMcpRemainingSteps } = require('./slack-mcp-runtime');
|
|
33
34
|
const {
|
|
34
35
|
channelDisplayLabel,
|
|
35
36
|
printValidating,
|
|
@@ -280,18 +281,23 @@ function slackRecoveryOrHandshake(ctx, custom) {
|
|
|
280
281
|
* @param {Object|null} ctx
|
|
281
282
|
* @returns {Object}
|
|
282
283
|
*/
|
|
283
|
-
function slackRemainingSpec(ctx) {
|
|
284
|
+
function slackRemainingSpec(ctx, runtimeValues) {
|
|
284
285
|
const custom = slackCustomSteps(ctx);
|
|
286
|
+
const mcpSteps = slackMcpRemainingSteps(runtimeValues);
|
|
287
|
+
let spec;
|
|
285
288
|
if (ctx && ctx.slackConnected === true) {
|
|
286
|
-
|
|
289
|
+
spec = slackConnectedRemaining(ctx, custom);
|
|
290
|
+
} else if (ctx && ctx.slackSlashCommand) {
|
|
291
|
+
spec = slackSlashRemaining(ctx, custom);
|
|
292
|
+
} else if (ctx && ctx.slackHandshakeFailed === true) {
|
|
293
|
+
spec = slackFailedRemaining(custom);
|
|
294
|
+
} else {
|
|
295
|
+
spec = slackRecoveryOrHandshake(ctx, custom);
|
|
287
296
|
}
|
|
288
|
-
if (
|
|
289
|
-
return
|
|
297
|
+
if (mcpSteps.length === 0) {
|
|
298
|
+
return spec;
|
|
290
299
|
}
|
|
291
|
-
|
|
292
|
-
return slackFailedRemaining(custom);
|
|
293
|
-
}
|
|
294
|
-
return slackRecoveryOrHandshake(ctx, custom);
|
|
300
|
+
return { ...spec, steps: [...(spec.steps || []), ...mcpSteps] };
|
|
295
301
|
}
|
|
296
302
|
|
|
297
303
|
/**
|
|
@@ -350,7 +356,7 @@ function teamsBotRemainingSpec(ctx, runtimeValues) {
|
|
|
350
356
|
*/
|
|
351
357
|
function remainingSpec(channelTarget, ctx, runtimeValues) {
|
|
352
358
|
if (channelTarget === 'slack') {
|
|
353
|
-
return slackRemainingSpec(ctx);
|
|
359
|
+
return slackRemainingSpec(ctx, runtimeValues);
|
|
354
360
|
}
|
|
355
361
|
if (channelTarget === 'microsoft-copilot') {
|
|
356
362
|
return copilotRemainingSpec(ctx, runtimeValues);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel Definition catalog/install status (visible | hide | coming-soon).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Omit or visible: listed and installable. hide: omitted and refused. coming-soon: listed read-only.
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const registry = require('./channel-definition-registry');
|
|
12
|
+
|
|
13
|
+
const CHANNEL_STATUSES = ['visible', 'hide', 'coming-soon'];
|
|
14
|
+
const COMING_SOON_REASON = 'This channel is coming soon.';
|
|
15
|
+
const HIDE_REASON = 'This channel is not available.';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {Object|null} definition
|
|
19
|
+
* @returns {'visible'|'hide'|'coming-soon'}
|
|
20
|
+
*/
|
|
21
|
+
function normalizeChannelStatus(definition) {
|
|
22
|
+
const raw = definition && definition.channel && definition.channel.status;
|
|
23
|
+
if (raw === 'hide' || raw === 'coming-soon') {
|
|
24
|
+
return raw;
|
|
25
|
+
}
|
|
26
|
+
return 'visible';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Live status from the Channel Definition registry (spy-friendly).
|
|
31
|
+
* @param {string} key
|
|
32
|
+
* @returns {'visible'|'hide'|'coming-soon'}
|
|
33
|
+
*/
|
|
34
|
+
function channelStatusOf(key) {
|
|
35
|
+
return normalizeChannelStatus(registry.getChannelDefinition(key));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param {string} status
|
|
40
|
+
* @returns {boolean}
|
|
41
|
+
*/
|
|
42
|
+
function isCatalogHiddenStatus(status) {
|
|
43
|
+
return status === 'hide';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {string} status
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
function isInstallableStatus(status) {
|
|
51
|
+
return status === 'visible';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {string} key
|
|
56
|
+
* @param {string} status
|
|
57
|
+
* @returns {Error}
|
|
58
|
+
*/
|
|
59
|
+
function statusUnavailableError(key, status) {
|
|
60
|
+
const message =
|
|
61
|
+
status === 'coming-soon'
|
|
62
|
+
? `Channel target "${key}" is coming soon.`
|
|
63
|
+
: `Channel target "${key}" is not available.`;
|
|
64
|
+
const err = new Error(message);
|
|
65
|
+
err.statusCode = 403;
|
|
66
|
+
return err;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Refuse new install for hide and coming-soon. Continue of an existing session skips.
|
|
71
|
+
* --force / allowExperimental do not override.
|
|
72
|
+
* @param {string} key
|
|
73
|
+
* @param {{ continueInstall?: boolean }} [options]
|
|
74
|
+
* @returns {void}
|
|
75
|
+
*/
|
|
76
|
+
function assertChannelStatusInstallable(key, options = {}) {
|
|
77
|
+
if (options.continueInstall === true) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const status = channelStatusOf(key);
|
|
81
|
+
if (isInstallableStatus(status)) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
throw statusUnavailableError(key, status);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Overlay coming-soon onto a catalog/detail projection (canInstall false).
|
|
89
|
+
* @param {string} status
|
|
90
|
+
* @param {Object} [projection]
|
|
91
|
+
* @returns {Object}
|
|
92
|
+
*/
|
|
93
|
+
function applyChannelStatusProjection(status, projection = {}) {
|
|
94
|
+
if (status !== 'coming-soon') {
|
|
95
|
+
return { ...projection, status };
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
...projection,
|
|
99
|
+
status,
|
|
100
|
+
canInstall: false,
|
|
101
|
+
blockedReason: COMING_SOON_REASON
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
CHANNEL_STATUSES,
|
|
107
|
+
COMING_SOON_REASON,
|
|
108
|
+
HIDE_REASON,
|
|
109
|
+
normalizeChannelStatus,
|
|
110
|
+
channelStatusOf,
|
|
111
|
+
isCatalogHiddenStatus,
|
|
112
|
+
isInstallableStatus,
|
|
113
|
+
assertChannelStatusInstallable,
|
|
114
|
+
applyChannelStatusProjection
|
|
115
|
+
};
|
|
@@ -99,7 +99,8 @@ function fillSlackManifestDescriptions(channelTarget, runtimeValues) {
|
|
|
99
99
|
return {
|
|
100
100
|
...runtimeValues,
|
|
101
101
|
appLongDescription,
|
|
102
|
-
appLongDescriptionJson: JSON.stringify(appLongDescription)
|
|
102
|
+
appLongDescriptionJson: JSON.stringify(appLongDescription),
|
|
103
|
+
enableMcpServer: runtimeValues.enableMcpServer === true
|
|
103
104
|
};
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -135,7 +135,8 @@ function claudeCopyActions(runtimeValues) {
|
|
|
135
135
|
const values = buildClaudeFormValues({ runtimeValues: runtimeValues || {} });
|
|
136
136
|
return [
|
|
137
137
|
copyValueAction('Name', values.name, 'copy-name'),
|
|
138
|
-
copyValueAction('Server URL', values.serverUrl, 'copy-server-url')
|
|
138
|
+
copyValueAction('Server URL', values.serverUrl, 'copy-server-url'),
|
|
139
|
+
copyValueAction('Authentication', values.authentication, 'copy-authentication')
|
|
139
140
|
].filter(Boolean);
|
|
140
141
|
}
|
|
141
142
|
|
|
@@ -195,7 +196,8 @@ function claudeEnvelopeParts(params) {
|
|
|
195
196
|
useValues: runtimeOk
|
|
196
197
|
? {
|
|
197
198
|
Name: values.name,
|
|
198
|
-
'Server URL': values.serverUrl
|
|
199
|
+
'Server URL': values.serverUrl,
|
|
200
|
+
Authentication: values.authentication
|
|
199
201
|
}
|
|
200
202
|
: {}
|
|
201
203
|
};
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
const path = require('path');
|
|
14
14
|
const { getChannelTarget } = require('./channel-targets');
|
|
15
|
+
const { assertChannelStatusInstallable } = require('./channel-definition-status');
|
|
15
16
|
const { getIntegrationPath } = require('../utils/paths');
|
|
16
17
|
const {
|
|
17
18
|
copyChannelIntegrationTemplate,
|
|
@@ -29,6 +30,7 @@ const { generateDeployJson } = require('../generator/index');
|
|
|
29
30
|
*/
|
|
30
31
|
async function scaffoldChannelIntegration(channelTarget, options = {}) {
|
|
31
32
|
const target = getChannelTarget(channelTarget);
|
|
33
|
+
assertChannelStatusInstallable(channelTarget, options);
|
|
32
34
|
if (target.experimental && !options.allowExperimental) {
|
|
33
35
|
throw new Error(
|
|
34
36
|
`Channel target "${channelTarget}" is experimental. Pass --allow-experimental to scaffold.`
|
|
@@ -36,6 +36,7 @@ const { applyCopilotOauthProfile, applyCopilotRuntimeDomain } = require('./chann
|
|
|
36
36
|
const { chatgptDiscoveryBlockerLabel } = require('./chatgpt-setup-values');
|
|
37
37
|
const { applyMcpClientRuntimeValues } = require('./mcp-client/runtime');
|
|
38
38
|
const { applyClaudeRuntimeValues } = require('./claude-runtime');
|
|
39
|
+
const { applySlackMcpRuntimeValues } = require('./slack-mcp-runtime');
|
|
39
40
|
|
|
40
41
|
const DEFAULT_SLACK_COMMAND_PREFIX = 'af';
|
|
41
42
|
|
|
@@ -347,6 +348,7 @@ function applySlackRuntimeValues(resolved, params) {
|
|
|
347
348
|
Object.assign(resolved, resolveSlackOAuthManifestFields());
|
|
348
349
|
delete resolved.oauthCallbackUrl;
|
|
349
350
|
resolved.commandPrefix = normalizeSlackCommandPrefix(params.commandPrefix);
|
|
351
|
+
resolved.enableMcpServer = isTrueLike(params.enableMcpServer);
|
|
350
352
|
resolved.packageVersion =
|
|
351
353
|
typeof params.packageVersion === 'string' && params.packageVersion.trim()
|
|
352
354
|
? params.packageVersion.trim()
|
|
@@ -356,6 +358,17 @@ function applySlackRuntimeValues(resolved, params) {
|
|
|
356
358
|
resolved.appLongDescriptionJson = JSON.stringify(appLongDescription);
|
|
357
359
|
}
|
|
358
360
|
|
|
361
|
+
/**
|
|
362
|
+
* @param {unknown} value
|
|
363
|
+
* @returns {boolean}
|
|
364
|
+
*/
|
|
365
|
+
function isTrueLike(value) {
|
|
366
|
+
if (value === true) {
|
|
367
|
+
return true;
|
|
368
|
+
}
|
|
369
|
+
return typeof value === 'string' && /^(true|1|yes|on)$/i.test(value.trim());
|
|
370
|
+
}
|
|
371
|
+
|
|
359
372
|
/**
|
|
360
373
|
* Slack slash alias prefix: letters then letters/digits, 1–16 chars.
|
|
361
374
|
* @param {unknown} raw
|
|
@@ -438,6 +451,7 @@ function applyChannelSpecificRuntime(resolved, params) {
|
|
|
438
451
|
if (params.channelTarget === 'slack') {
|
|
439
452
|
applySlackRuntimeValues(resolved, params);
|
|
440
453
|
applyDiscoveryPackageContext(resolved, params.packageContext);
|
|
454
|
+
applySlackMcpRuntimeValues(resolved, params);
|
|
441
455
|
}
|
|
442
456
|
if (params.channelTarget === 'microsoft-copilot') {
|
|
443
457
|
applyMicrosoftCopilotRuntimeValues(resolved, params);
|
|
@@ -14,6 +14,12 @@ const {
|
|
|
14
14
|
listChannelDefinitionKeys
|
|
15
15
|
} = require('./channel-definition-registry');
|
|
16
16
|
const { toChannelTargetProjection } = require('./channel-definition-project');
|
|
17
|
+
const {
|
|
18
|
+
assertChannelStatusInstallable,
|
|
19
|
+
channelStatusOf,
|
|
20
|
+
isCatalogHiddenStatus,
|
|
21
|
+
isInstallableStatus
|
|
22
|
+
} = require('./channel-definition-status');
|
|
17
23
|
|
|
18
24
|
function buildChannelTargets() {
|
|
19
25
|
const targets = {};
|
|
@@ -48,15 +54,21 @@ function isChannelTargetKey(channelTarget) {
|
|
|
48
54
|
*/
|
|
49
55
|
function formatSupportedChannelTargetsHelp() {
|
|
50
56
|
const targets = resolveChannelTargets();
|
|
51
|
-
const
|
|
52
|
-
const stable =
|
|
53
|
-
const experimental =
|
|
57
|
+
const installable = listInstallableChannelTargetKeys({ allowExperimental: true });
|
|
58
|
+
const stable = installable.filter((key) => !targets[key].experimental);
|
|
59
|
+
const experimental = installable.filter((key) => targets[key].experimental);
|
|
60
|
+
const comingSoon = listLiveChannelTargetKeys({ allowExperimental: true }).filter(
|
|
61
|
+
(key) => channelStatusOf(key) === 'coming-soon'
|
|
62
|
+
);
|
|
54
63
|
const lines = ['Supported channels:', ` ${stable.join(', ')}`];
|
|
55
64
|
if (experimental.length > 0) {
|
|
56
65
|
lines.push(
|
|
57
66
|
` ${experimental.join(', ')} (experimental — scaffold with --allow-experimental)`
|
|
58
67
|
);
|
|
59
68
|
}
|
|
69
|
+
if (comingSoon.length > 0) {
|
|
70
|
+
lines.push(` ${comingSoon.join(', ')} (coming soon — not installable)`);
|
|
71
|
+
}
|
|
60
72
|
return lines.join('\n');
|
|
61
73
|
}
|
|
62
74
|
|
|
@@ -81,18 +93,30 @@ function getChannelTarget(channelTarget) {
|
|
|
81
93
|
}
|
|
82
94
|
|
|
83
95
|
/**
|
|
84
|
-
* Live keys, plus experimental when `--allow-experimental` is set.
|
|
96
|
+
* Live keys (not hide), plus experimental when `--allow-experimental` is set.
|
|
85
97
|
* @param {{ allowExperimental?: boolean }} [options]
|
|
86
98
|
* @returns {string[]}
|
|
87
99
|
*/
|
|
88
100
|
function listLiveChannelTargetKeys(options = {}) {
|
|
89
101
|
const targets = resolveChannelTargets();
|
|
90
102
|
return Object.keys(targets).filter((key) => {
|
|
103
|
+
if (isCatalogHiddenStatus(channelStatusOf(key))) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
91
106
|
const target = targets[key];
|
|
92
107
|
return !target.experimental || options.allowExperimental === true;
|
|
93
108
|
});
|
|
94
109
|
}
|
|
95
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Keys that may start a new install (visible). Coming-soon is catalog-only.
|
|
113
|
+
* @param {{ allowExperimental?: boolean }} [options]
|
|
114
|
+
* @returns {string[]}
|
|
115
|
+
*/
|
|
116
|
+
function listInstallableChannelTargetKeys(options = {}) {
|
|
117
|
+
return listLiveChannelTargetKeys(options).filter((key) => isInstallableStatus(channelStatusOf(key)));
|
|
118
|
+
}
|
|
119
|
+
|
|
96
120
|
/**
|
|
97
121
|
* Inquirer list choices for `aifabrix channel add` (labels from the registry).
|
|
98
122
|
* @param {{ allowExperimental?: boolean }} [options]
|
|
@@ -100,7 +124,7 @@ function listLiveChannelTargetKeys(options = {}) {
|
|
|
100
124
|
*/
|
|
101
125
|
function listWizardChannelChoices(options = {}) {
|
|
102
126
|
const targets = resolveChannelTargets();
|
|
103
|
-
return
|
|
127
|
+
return listInstallableChannelTargetKeys(options)
|
|
104
128
|
.map((key) => targets[key])
|
|
105
129
|
.sort((a, b) => (a.wizardOrder || 100) - (b.wizardOrder || 100))
|
|
106
130
|
.map((target) => ({ name: target.displayLabel, value: target.key }));
|
|
@@ -114,6 +138,7 @@ function listWizardChannelChoices(options = {}) {
|
|
|
114
138
|
*/
|
|
115
139
|
function assertChannelTargetInstallable(channelTarget, options = {}) {
|
|
116
140
|
const target = getChannelTarget(channelTarget);
|
|
141
|
+
assertChannelStatusInstallable(channelTarget, options);
|
|
117
142
|
if (target.experimental && options.allowExperimental !== true) {
|
|
118
143
|
throw new Error(
|
|
119
144
|
`Channel target "${channelTarget}" is experimental. Pass --allow-experimental to install.`
|
|
@@ -146,6 +171,7 @@ module.exports = {
|
|
|
146
171
|
formatSupportedChannelTargetsHelp,
|
|
147
172
|
formatUnknownChannelTargetError,
|
|
148
173
|
listLiveChannelTargetKeys,
|
|
174
|
+
listInstallableChannelTargetKeys,
|
|
149
175
|
listWizardChannelChoices,
|
|
150
176
|
assertChannelTargetInstallable,
|
|
151
177
|
getChannelDefinition,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Customer-facing Claude connector form values: Name
|
|
2
|
+
* Customer-facing Claude connector form values: Name, Server URL, OAuth.
|
|
3
3
|
*
|
|
4
4
|
* @fileoverview Claude channel form values — describe, don't configure
|
|
5
5
|
*/
|
|
@@ -78,6 +78,9 @@ function formatClaudeFormValueLines(values) {
|
|
|
78
78
|
if (values.serverUrl) {
|
|
79
79
|
lines.push(`Server URL: ${values.serverUrl}`);
|
|
80
80
|
}
|
|
81
|
+
if (values.authentication) {
|
|
82
|
+
lines.push(`Authentication: ${values.authentication}`);
|
|
83
|
+
}
|
|
81
84
|
return lines;
|
|
82
85
|
}
|
|
83
86
|
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
maybeOnboardSlackUsers,
|
|
22
22
|
unmatchedRemainingStep
|
|
23
23
|
} = require('./slack-provisioning/onboard');
|
|
24
|
+
const { registerSlackMcpCallback, slackMcpProfileUrl } = require('./slack-mcp-callback');
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* @param {Error} error
|
|
@@ -223,36 +224,88 @@ async function recoverOrRefreshAuth(error, params, options, deps, ctx, projectRo
|
|
|
223
224
|
* @param {Object} params
|
|
224
225
|
* @returns {Promise<Object|null>}
|
|
225
226
|
*/
|
|
226
|
-
async function
|
|
227
|
-
|
|
227
|
+
async function maybeRegisterSlackMcpCallback(params) {
|
|
228
|
+
const runtime = params && params.runtimeValues;
|
|
229
|
+
const ctx = params && params.ctx;
|
|
230
|
+
if (!runtime || !runtime.enableMcpServer) {
|
|
228
231
|
return null;
|
|
229
232
|
}
|
|
230
|
-
if (
|
|
233
|
+
if (!ctx || !ctx.controllerUrl || !ctx.authConfig) {
|
|
234
|
+
return {
|
|
235
|
+
ok: false,
|
|
236
|
+
fallback: true,
|
|
237
|
+
remaining: ['Open the OAuth2 profile and add the Slack MCP callback URL']
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
try {
|
|
241
|
+
const result = await registerSlackMcpCallback({ ctx, ...(params.slackMcpCallbackDeps || {}) });
|
|
242
|
+
if (result && result.fallback) {
|
|
243
|
+
const profileUrl = result.profileUrl || slackMcpProfileUrl(ctx);
|
|
244
|
+
return {
|
|
245
|
+
ok: false,
|
|
246
|
+
fallback: true,
|
|
247
|
+
remaining: [`Open ${profileUrl} and add the Slack MCP callback URL`]
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
return result;
|
|
251
|
+
} catch (error) {
|
|
252
|
+
return {
|
|
253
|
+
ok: false,
|
|
254
|
+
fallback: true,
|
|
255
|
+
remaining: [error && error.message ? error.message : 'Slack MCP callback could not be registered']
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* @param {Object} params
|
|
262
|
+
* @returns {Promise<Object|null>}
|
|
263
|
+
*/
|
|
264
|
+
async function maybeProvisionSlackChannel(params) {
|
|
265
|
+
if (!params || params.channelTarget !== 'slack' || (params.options && params.options.dryRun === true)) {
|
|
231
266
|
return null;
|
|
232
267
|
}
|
|
233
268
|
const ctx = params.ctx || {};
|
|
234
269
|
const options = params.options || {};
|
|
235
270
|
const deps = slackDepsFromOptions(options);
|
|
236
271
|
const projectRoot = options.projectRoot || process.cwd();
|
|
272
|
+
const mcpCallback = await maybeRegisterSlackMcpCallback(params);
|
|
237
273
|
if (options.quiet === true) {
|
|
238
274
|
const portal = await preparePortalSlackAuth(options, deps);
|
|
239
275
|
if (portal.waiting) {
|
|
240
276
|
await publishSlackAfterSecrets({ connected: false }, options, deps);
|
|
241
|
-
return portal.result;
|
|
277
|
+
return attachSlackMcpRemaining(portal.result, mcpCallback);
|
|
242
278
|
}
|
|
243
279
|
}
|
|
244
280
|
try {
|
|
245
281
|
if (options.quiet !== true) {
|
|
246
282
|
await ensureSlackCliReady(options, deps);
|
|
247
283
|
}
|
|
248
|
-
|
|
284
|
+
const result = await provisionAndPublish(params, options, deps, ctx, projectRoot);
|
|
285
|
+
return attachSlackMcpRemaining(result, mcpCallback);
|
|
249
286
|
} catch (error) {
|
|
250
|
-
|
|
287
|
+
const recovered = await recoverOrRefreshAuth(error, params, options, deps, ctx, projectRoot);
|
|
288
|
+
return attachSlackMcpRemaining(recovered, mcpCallback);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @param {Object|null} result
|
|
294
|
+
* @param {Object|null} mcpCallback
|
|
295
|
+
* @returns {Object|null}
|
|
296
|
+
*/
|
|
297
|
+
function attachSlackMcpRemaining(result, mcpCallback) {
|
|
298
|
+
const extra = mcpCallback && Array.isArray(mcpCallback.remaining) ? mcpCallback.remaining : [];
|
|
299
|
+
if (extra.length === 0) {
|
|
300
|
+
return result;
|
|
251
301
|
}
|
|
302
|
+
const base = result && typeof result === 'object' ? result : {};
|
|
303
|
+
return { ...base, remaining: [...(base.remaining || []), ...extra] };
|
|
252
304
|
}
|
|
253
305
|
|
|
254
306
|
module.exports = {
|
|
255
307
|
maybeProvisionSlackChannel,
|
|
308
|
+
maybeRegisterSlackMcpCallback,
|
|
256
309
|
applySlackOnboardToCtx,
|
|
257
310
|
remainingFromError
|
|
258
311
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Allowlist Slack MCP OAuth callback on the existing customerOAuth client.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Reuse ChatGPT Integration Client; never rotate the secret
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
registerChatGptCallbackUrls,
|
|
11
|
+
chatgptProfileUrl
|
|
12
|
+
} = require('./chatgpt-callback');
|
|
13
|
+
const {
|
|
14
|
+
CHATGPT_INTEGRATION_CLIENT_KEY,
|
|
15
|
+
CHATGPT_OAUTH2_PROFILE_ID,
|
|
16
|
+
CHATGPT_OAUTH2_PROFILE_PATH
|
|
17
|
+
} = require('./chatgpt-runtime-contract');
|
|
18
|
+
const { SLACK_MCP_CALLBACK_URI } = require('./slack-mcp-runtime');
|
|
19
|
+
|
|
20
|
+
const SLACK_MCP_CALLBACK_CONTRACT = {
|
|
21
|
+
integrationClientKey: CHATGPT_INTEGRATION_CLIENT_KEY,
|
|
22
|
+
oauth2ProfileId: CHATGPT_OAUTH2_PROFILE_ID,
|
|
23
|
+
oauth2ProfilePath: CHATGPT_OAUTH2_PROFILE_PATH,
|
|
24
|
+
vendorLabel: 'Slack MCP'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @param {Object} ctx
|
|
29
|
+
* @returns {string}
|
|
30
|
+
*/
|
|
31
|
+
function slackMcpProfileUrl(ctx) {
|
|
32
|
+
return chatgptProfileUrl(ctx, SLACK_MCP_CALLBACK_CONTRACT);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @param {Object} params
|
|
37
|
+
* @returns {Promise<Object>}
|
|
38
|
+
*/
|
|
39
|
+
async function registerSlackMcpCallback(params) {
|
|
40
|
+
return registerChatGptCallbackUrls({
|
|
41
|
+
...params,
|
|
42
|
+
callbackUrls: [SLACK_MCP_CALLBACK_URI],
|
|
43
|
+
contract: SLACK_MCP_CALLBACK_CONTRACT
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
module.exports = {
|
|
48
|
+
SLACK_MCP_CALLBACK_CONTRACT,
|
|
49
|
+
slackMcpProfileUrl,
|
|
50
|
+
registerSlackMcpCallback
|
|
51
|
+
};
|