@aifabrix/builder 2.54.1 → 2.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +130 -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 +239 -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/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/list-external-systems.js +2 -1
- 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-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +3 -1
- package/lib/commands/agent-kit-help.js +79 -0
- package/lib/commands/agent-kit.js +346 -0
- package/lib/commands/channel-add-help.js +5 -5
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- 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 +117 -48
- 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-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/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 +7 -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 +229 -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/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 +137 -30
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +291 -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 +50 -10
- package/lib/schema/external-datasource.schema.json +36 -5
- package/lib/schema/external-system.schema.json +20 -2
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- 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/authentication-slot-show.js +153 -0
- package/lib/utils/credential-display.js +43 -1
- 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/schema-loader.js +37 -0
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +3 -2
- package/package.json +1 -1
- 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 +83 -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 +58 -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 +51 -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 +50 -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 +42 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +78 -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 -2
- package/templates/applications/dataplane/env.template +1 -1
- package/templates/applications/dataplane/rbac.yaml +28 -0
- package/templates/applications/keycloak/env.template +3 -3
- package/templates/applications/miso-controller/application.yaml +1 -1
- package/templates/applications/miso-controller/env.template +8 -9
- 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
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slackbot MCP Client packaging (opt-in). Auth freeze: manual_auth.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Slack MCP manifest fields from discovery; HMAC path stays default
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const SLACK_MCP_AUTH_TYPE = 'manual_auth';
|
|
10
|
+
const SLACK_MCP_AUTH_PROVIDER_KEY = 'mcp_aifabrix';
|
|
11
|
+
const SLACK_MCP_SERVER_KEY = 'runtime-orchestration';
|
|
12
|
+
const SLACK_MCP_CALLBACK_URI = 'https://oauth2.slack.com/external/auth/callback';
|
|
13
|
+
const SLACK_MCP_OAUTH_SCOPES = ['openid', 'profile', 'email', 'offline_access'];
|
|
14
|
+
const SLACK_MCP_CAPABILITY = 'customerOAuth';
|
|
15
|
+
const SLACK_MCP_MISSING_URL = 'Runtime MCP URL is missing.';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} [controllerUrl]
|
|
19
|
+
* @param {string} [mcpUrl]
|
|
20
|
+
* @param {string} [dataplaneBaseUrl]
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
23
|
+
function authorizationServerBase(controllerUrl, mcpUrl, dataplaneBaseUrl) {
|
|
24
|
+
const candidate = controllerUrl || mcpUrl || dataplaneBaseUrl;
|
|
25
|
+
try {
|
|
26
|
+
return `${new URL(candidate).origin}/auth/realms/aifabrix`;
|
|
27
|
+
} catch {
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {string} asBase
|
|
34
|
+
* @returns {{ authorizationUrl: string, tokenUrl: string }}
|
|
35
|
+
*/
|
|
36
|
+
function keycloakEndpoints(asBase) {
|
|
37
|
+
if (!asBase) {
|
|
38
|
+
return { authorizationUrl: '', tokenUrl: '' };
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
authorizationUrl: `${asBase}/protocol/openid-connect/auth`,
|
|
42
|
+
tokenUrl: `${asBase}/protocol/openid-connect/token`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {Object} resolved
|
|
48
|
+
* @returns {void}
|
|
49
|
+
*/
|
|
50
|
+
function clearSlackMcpPackaging(resolved) {
|
|
51
|
+
resolved.slackMcpAuthType = '';
|
|
52
|
+
resolved.slackMcpAuthProviderKey = '';
|
|
53
|
+
resolved.slackMcpCallbackUri = '';
|
|
54
|
+
resolved.slackMcpCapability = '';
|
|
55
|
+
resolved.slackMcpServersJson = '';
|
|
56
|
+
resolved.slackExternalAuthJson = '';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {Object} resolved
|
|
61
|
+
* @returns {boolean}
|
|
62
|
+
*/
|
|
63
|
+
function selectsCustomerOAuth(resolved) {
|
|
64
|
+
const caps = resolved.discoveryAuthenticationCapabilities;
|
|
65
|
+
if (!Array.isArray(caps) || caps.length === 0) {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return caps.includes(SLACK_MCP_CAPABILITY);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {Object} resolved
|
|
73
|
+
* @param {Object} params
|
|
74
|
+
* @param {string} mcpUrl
|
|
75
|
+
* @returns {Object}
|
|
76
|
+
*/
|
|
77
|
+
function buildExternalAuthProviders(resolved, params, mcpUrl) {
|
|
78
|
+
const asBase = authorizationServerBase(
|
|
79
|
+
params && params.controllerUrl,
|
|
80
|
+
mcpUrl,
|
|
81
|
+
resolved.dataplaneBaseUrl
|
|
82
|
+
);
|
|
83
|
+
const endpoints = keycloakEndpoints(asBase);
|
|
84
|
+
const provider = {
|
|
85
|
+
authorization_url: endpoints.authorizationUrl,
|
|
86
|
+
token_url: endpoints.tokenUrl,
|
|
87
|
+
scope: SLACK_MCP_OAUTH_SCOPES,
|
|
88
|
+
use_pkce: true,
|
|
89
|
+
identity_config: null
|
|
90
|
+
};
|
|
91
|
+
const clientId =
|
|
92
|
+
typeof resolved.slackMcpClientId === 'string' ? resolved.slackMcpClientId.trim() : '';
|
|
93
|
+
if (clientId) {
|
|
94
|
+
provider.client_id = clientId;
|
|
95
|
+
}
|
|
96
|
+
return { oauth2: { [SLACK_MCP_AUTH_PROVIDER_KEY]: provider } };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* @param {Object} resolved
|
|
101
|
+
* @param {Object} [params]
|
|
102
|
+
* @returns {void}
|
|
103
|
+
*/
|
|
104
|
+
function applySlackMcpRuntimeValues(resolved, params) {
|
|
105
|
+
if (!resolved.enableMcpServer) {
|
|
106
|
+
clearSlackMcpPackaging(resolved);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const mcpUrl = typeof resolved.mcpUrl === 'string' ? resolved.mcpUrl.trim() : '';
|
|
110
|
+
if (!mcpUrl) {
|
|
111
|
+
throw new Error(SLACK_MCP_MISSING_URL);
|
|
112
|
+
}
|
|
113
|
+
if (!selectsCustomerOAuth(resolved)) {
|
|
114
|
+
throw new Error('Slack MCP requires customerOAuth on Runtime discovery.');
|
|
115
|
+
}
|
|
116
|
+
resolved.slackMcpAuthType = SLACK_MCP_AUTH_TYPE;
|
|
117
|
+
resolved.slackMcpAuthProviderKey = SLACK_MCP_AUTH_PROVIDER_KEY;
|
|
118
|
+
resolved.slackMcpCallbackUri = SLACK_MCP_CALLBACK_URI;
|
|
119
|
+
resolved.slackMcpCapability = SLACK_MCP_CAPABILITY;
|
|
120
|
+
resolved.slackMcpServersJson = JSON.stringify({
|
|
121
|
+
[SLACK_MCP_SERVER_KEY]: {
|
|
122
|
+
url: mcpUrl,
|
|
123
|
+
auth_type: SLACK_MCP_AUTH_TYPE,
|
|
124
|
+
auth_provider_key: SLACK_MCP_AUTH_PROVIDER_KEY
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
resolved.slackExternalAuthJson = JSON.stringify(
|
|
128
|
+
buildExternalAuthProviders(resolved, params || {}, mcpUrl)
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @param {Object} [runtimeValues]
|
|
134
|
+
* @returns {string[]}
|
|
135
|
+
*/
|
|
136
|
+
function slackMcpRemainingSteps(runtimeValues) {
|
|
137
|
+
if (!runtimeValues || !runtimeValues.enableMcpServer) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
return [
|
|
141
|
+
'Connect the AI Fabrix MCP server in Slack',
|
|
142
|
+
'Complete sign-in at AI Fabrix when Slack asks'
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = {
|
|
147
|
+
SLACK_MCP_AUTH_TYPE,
|
|
148
|
+
SLACK_MCP_AUTH_PROVIDER_KEY,
|
|
149
|
+
SLACK_MCP_SERVER_KEY,
|
|
150
|
+
SLACK_MCP_CALLBACK_URI,
|
|
151
|
+
SLACK_MCP_OAUTH_SCOPES,
|
|
152
|
+
SLACK_MCP_CAPABILITY,
|
|
153
|
+
SLACK_MCP_MISSING_URL,
|
|
154
|
+
applySlackMcpRuntimeValues,
|
|
155
|
+
slackMcpRemainingSteps
|
|
156
|
+
};
|
|
@@ -179,6 +179,19 @@ function fetchHttpsText(url, redirects = 0) {
|
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Drop Node's version footer; prefer an Error: line when present.
|
|
184
|
+
* @param {string} text
|
|
185
|
+
* @returns {string}
|
|
186
|
+
*/
|
|
187
|
+
function lastUsefulInstallLine(text) {
|
|
188
|
+
const lines = text.split('\n').map((line) => line.trim()).filter(Boolean);
|
|
189
|
+
const withoutNode = lines.filter((line) => !/^Node\.js v\d/i.test(line));
|
|
190
|
+
const pool = withoutNode.length ? withoutNode : lines;
|
|
191
|
+
const errorLine = [...pool].reverse().find((line) => /^Error:/i.test(line));
|
|
192
|
+
return errorLine || pool[pool.length - 1] || '';
|
|
193
|
+
}
|
|
194
|
+
|
|
182
195
|
/**
|
|
183
196
|
* Prefer child stderr over Node's "Command failed: bash /tmp/…" wrapper.
|
|
184
197
|
* @param {unknown} error
|
|
@@ -190,8 +203,7 @@ function slackCliInstallFailureMessage(error) {
|
|
|
190
203
|
const raw = error && error.message ? String(error.message) : '';
|
|
191
204
|
const fromChild = stderr || stdout;
|
|
192
205
|
if (fromChild) {
|
|
193
|
-
|
|
194
|
-
return lines[lines.length - 1] || fromChild;
|
|
206
|
+
return lastUsefulInstallLine(fromChild) || fromChild;
|
|
195
207
|
}
|
|
196
208
|
const stripped = raw.replace(/^Command failed: bash \S+\s*/i, '').trim();
|
|
197
209
|
return stripped || 'Slack CLI install failed.';
|
|
@@ -22,7 +22,12 @@ async function curlExists(env) {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function writeCurlShim(dir) {
|
|
25
|
-
const
|
|
25
|
+
const source = path.join(__dirname, 'curl-shim.js');
|
|
26
|
+
if (!fs.existsSync(source)) {
|
|
27
|
+
throw new Error(`Slack CLI curl shim missing: ${source}`);
|
|
28
|
+
}
|
|
29
|
+
const runtime = path.join(dir, 'curl-shim.js');
|
|
30
|
+
fs.copyFileSync(source, runtime);
|
|
26
31
|
const wrapper = `#!/bin/sh\nexec "${process.execPath}" "${runtime}" "$@"\n`;
|
|
27
32
|
fs.writeFileSync(path.join(dir, 'curl'), wrapper, { mode: 0o755 });
|
|
28
33
|
}
|
package/lib/cli/index.js
CHANGED
|
@@ -25,9 +25,11 @@ const { setupDimensionCommands } = require('../commands/dimension');
|
|
|
25
25
|
const { setupResourceTypeCommands } = require('../commands/resource-type');
|
|
26
26
|
const { setupRoleCommands } = require('../commands/role');
|
|
27
27
|
const { setupRoleAssistantCommands } = require('../commands/role-assistant');
|
|
28
|
+
const { setupSearchCommands } = require('../commands/search');
|
|
28
29
|
const { setupEvidenceKindCommands } = require('../commands/evidence-kind');
|
|
29
30
|
const { setupEnterpriseKnowledgeCommands } = require('../commands/enterprise-knowledge');
|
|
30
31
|
const { setupIdentityCommands } = require('../commands/identity');
|
|
32
|
+
const { setupAgentKitCommands } = require('../commands/agent-kit');
|
|
31
33
|
const { setupProtectionCommands } = require('../commands/protection');
|
|
32
34
|
const { setupEvidenceCommands } = require('../commands/evidence');
|
|
33
35
|
const { setupCredentialDeploymentCommands } = require('./setup-credential-deployment');
|
|
@@ -80,9 +82,11 @@ function setupExtendedCliCommands(program) {
|
|
|
80
82
|
setupResourceTypeCommands(program);
|
|
81
83
|
setupRoleCommands(program);
|
|
82
84
|
setupRoleAssistantCommands(program);
|
|
85
|
+
setupSearchCommands(program);
|
|
83
86
|
setupEvidenceKindCommands(program);
|
|
84
87
|
setupEnterpriseKnowledgeCommands(program);
|
|
85
88
|
setupIdentityCommands(program);
|
|
89
|
+
setupAgentKitCommands(program);
|
|
86
90
|
setupProtectionCommands(program);
|
|
87
91
|
setupEvidenceCommands(program);
|
|
88
92
|
setupUtilityCommands(program);
|
|
@@ -20,7 +20,7 @@ function setupVerifyOperationsCommand(program) {
|
|
|
20
20
|
.option('-e, --env <env>', 'Environment: dev, tst, or pro', 'dev')
|
|
21
21
|
.option('-v, --verbose', 'Readiness breakdown and verification step checklist')
|
|
22
22
|
.option('-d, --debug', 'Write debug logs under integration/<systemKey>/logs/')
|
|
23
|
-
.option('--no-publish', 'Skip
|
|
23
|
+
.option('--no-publish', 'Skip uploading local files (verify-operations does not upload by default)')
|
|
24
24
|
.option(
|
|
25
25
|
'--force',
|
|
26
26
|
'With default sync, pass force to upload (same as aifabrix upload --force)'
|
|
@@ -39,7 +39,7 @@ function setupVerifyTrustCommand(program) {
|
|
|
39
39
|
.option('-e, --env <env>', 'Environment: dev, tst, or pro', 'dev')
|
|
40
40
|
.option('-v, --verbose', 'Per-datasource breakdown')
|
|
41
41
|
.option('-d, --debug', 'Write debug log under integration/<systemKey>/logs/')
|
|
42
|
-
.option('--no-publish', 'Skip
|
|
42
|
+
.option('--no-publish', 'Skip uploading local files (verify-trust does not upload by default)')
|
|
43
43
|
.option(
|
|
44
44
|
'--force',
|
|
45
45
|
'With default sync, pass force to upload (same as aifabrix upload --force)'
|
|
@@ -12,6 +12,8 @@ Examples:
|
|
|
12
12
|
|
|
13
13
|
Notes:
|
|
14
14
|
- Orchestrates validate → test → test-integration → test-e2e for the system.
|
|
15
|
+
- Does not upload. Upload is not publish; run aifabrix deploy to publish.
|
|
16
|
+
- Static custom packages (syncBridge disabled) skip live E2E (not FAILED).
|
|
15
17
|
- Default output shows Operational Readiness % and OPERATIONS VERIFIED/FAILED only.
|
|
16
18
|
- -v / --verbose adds readiness breakdown and verification step checklist at the end.
|
|
17
19
|
- -v does not enable upload sidecar logs or inner E2E poll spinners (use aifabrix upload -v for upload detail).
|
|
@@ -28,7 +30,7 @@ Examples:
|
|
|
28
30
|
Notes:
|
|
29
31
|
- For one datasource: aifabrix datasource verify-trust <datasourceKey>
|
|
30
32
|
- Does not call external vendor APIs (use verify-operations / test-e2e for connectivity).
|
|
31
|
-
-
|
|
33
|
+
- Does not upload. Upload is not publish; run aifabrix deploy to publish.
|
|
32
34
|
`;
|
|
33
35
|
|
|
34
36
|
const VERIFY_GOVERNANCE_HELP_AFTER = `
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Help text for `aifabrix agent-kit` leaves.
|
|
3
|
+
* @fileoverview Per-command examples so update -h is not install-centric
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const GROUP_HELP = `
|
|
9
|
+
Examples:
|
|
10
|
+
$ aifabrix agent-kit init cust-demo --host all --approve-all --yes
|
|
11
|
+
$ aifabrix agent-kit install --host all --approve-all --yes
|
|
12
|
+
$ aifabrix agent-kit update --host all --approve-all --yes
|
|
13
|
+
$ aifabrix agent-kit status
|
|
14
|
+
$ aifabrix agent-kit validate
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
const INSTALL_HELP = `
|
|
18
|
+
Examples:
|
|
19
|
+
$ aifabrix agent-kit install
|
|
20
|
+
$ aifabrix agent-kit install --host all --approve-all --yes
|
|
21
|
+
$ aifabrix agent-kit install --host claude --approve-all --yes
|
|
22
|
+
$ aifabrix agent-kit install --skip-approve-all
|
|
23
|
+
$ aifabrix agent-kit install --dry-run
|
|
24
|
+
|
|
25
|
+
TTY asks to auto-approve Claude Code and Codex permissions (default yes). Silent: --approve-all --yes. Skip: --skip-approve-all.
|
|
26
|
+
`;
|
|
27
|
+
|
|
28
|
+
const STATUS_HELP = `
|
|
29
|
+
Examples:
|
|
30
|
+
$ aifabrix agent-kit status
|
|
31
|
+
$ aifabrix agent-kit status --json
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
const UPDATE_HELP = `
|
|
35
|
+
Examples:
|
|
36
|
+
$ aifabrix agent-kit update
|
|
37
|
+
$ aifabrix agent-kit update --host all --approve-all --yes
|
|
38
|
+
$ aifabrix agent-kit update --host claude --force
|
|
39
|
+
$ aifabrix agent-kit update --dry-run
|
|
40
|
+
|
|
41
|
+
Omit --host to keep the coding hosts already recorded. Pass --host when you add or switch Cursor, Claude Code, or Codex.
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
const VALIDATE_HELP = `
|
|
45
|
+
Examples:
|
|
46
|
+
$ aifabrix agent-kit validate
|
|
47
|
+
$ aifabrix agent-kit validate --json
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
const INIT_HELP = `
|
|
51
|
+
Examples:
|
|
52
|
+
$ aifabrix agent-kit init cust-demo
|
|
53
|
+
$ aifabrix agent-kit init cust-demo --host all --approve-all --yes
|
|
54
|
+
$ aifabrix agent-kit init cust-demo --host all --remote --org my-org --yes
|
|
55
|
+
$ aifabrix agent-kit init ./path/to/cust-demo --dry-run --json
|
|
56
|
+
|
|
57
|
+
Interactive (TTY): omit --host / --yes to be prompted.
|
|
58
|
+
Silent local: --host all --approve-all --yes
|
|
59
|
+
Silent remote: --host all --remote --org <owner> --yes
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
const REMOTE_HELP = `
|
|
63
|
+
Examples:
|
|
64
|
+
$ cd cust-demo && aifabrix agent-kit remote create
|
|
65
|
+
$ aifabrix agent-kit remote create --org my-org --yes
|
|
66
|
+
$ aifabrix agent-kit remote create --org my-org --dry-run --json
|
|
67
|
+
|
|
68
|
+
Interactive (TTY): omit flags to be prompted. Silent: --org <owner> --yes
|
|
69
|
+
`;
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
GROUP_HELP,
|
|
73
|
+
INSTALL_HELP,
|
|
74
|
+
STATUS_HELP,
|
|
75
|
+
UPDATE_HELP,
|
|
76
|
+
VALIDATE_HELP,
|
|
77
|
+
INIT_HELP,
|
|
78
|
+
REMOTE_HELP
|
|
79
|
+
};
|