@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.
Files changed (210) hide show
  1. package/README.md +8 -0
  2. package/lib/agent-kit/apply-ops.js +82 -0
  3. package/lib/agent-kit/checksums.js +28 -0
  4. package/lib/agent-kit/classify.js +113 -0
  5. package/lib/agent-kit/claude-shim.js +61 -0
  6. package/lib/agent-kit/constants.js +55 -0
  7. package/lib/agent-kit/file-list.js +103 -0
  8. package/lib/agent-kit/host-approve.js +130 -0
  9. package/lib/agent-kit/hosting/github.js +63 -0
  10. package/lib/agent-kit/hosts.js +71 -0
  11. package/lib/agent-kit/init.js +319 -0
  12. package/lib/agent-kit/kit-root.js +17 -0
  13. package/lib/agent-kit/managed-section.js +79 -0
  14. package/lib/agent-kit/package-load.js +45 -0
  15. package/lib/agent-kit/plan-ops.js +69 -0
  16. package/lib/agent-kit/remote-prompts.js +239 -0
  17. package/lib/agent-kit/render-host-markdown.js +40 -0
  18. package/lib/agent-kit/repo-guard.js +47 -0
  19. package/lib/agent-kit/report.js +107 -0
  20. package/lib/agent-kit/run.js +82 -0
  21. package/lib/agent-kit/scm/git.js +122 -0
  22. package/lib/agent-kit/state-file.js +83 -0
  23. package/lib/agent-kit/status.js +50 -0
  24. package/lib/agent-kit/v1-detect.js +81 -0
  25. package/lib/agent-kit/validate-kit.js +87 -0
  26. package/lib/agent-kit/workspace-name.js +40 -0
  27. package/lib/agent-kit/workspace-skeleton.js +103 -0
  28. package/lib/api/role-assistant-test-pack.api.js +86 -0
  29. package/lib/api/work-search.api.js +31 -4
  30. package/lib/api/work.api.js +19 -12
  31. package/lib/app/list-external-systems.js +2 -1
  32. package/lib/app/show-display.js +33 -6
  33. package/lib/app/show.js +25 -2
  34. package/lib/channels/add-channel.js +1 -0
  35. package/lib/channels/approval-guides/claude.js +2 -2
  36. package/lib/channels/channel-add-failure.js +1 -0
  37. package/lib/channels/channel-add-remaining.js +15 -9
  38. package/lib/channels/channel-definition-status.js +115 -0
  39. package/lib/channels/channel-description.js +2 -1
  40. package/lib/channels/channel-install-envelope.js +4 -2
  41. package/lib/channels/channel-integration-generator.js +2 -0
  42. package/lib/channels/channel-runtime-resolver.js +14 -0
  43. package/lib/channels/channel-targets.js +31 -5
  44. package/lib/channels/claude-setup-values.js +4 -1
  45. package/lib/channels/slack-channel-add.js +59 -6
  46. package/lib/channels/slack-mcp-callback.js +51 -0
  47. package/lib/channels/slack-mcp-runtime.js +156 -0
  48. package/lib/channels/slack-provisioning/install-cli.js +14 -2
  49. package/lib/channels/slack-provisioning/with-curl-on-path.js +6 -1
  50. package/lib/cli/index.js +4 -0
  51. package/lib/cli/setup-certification-commands.js +2 -2
  52. package/lib/cli/setup-certification.help.js +3 -1
  53. package/lib/commands/agent-kit-help.js +79 -0
  54. package/lib/commands/agent-kit.js +346 -0
  55. package/lib/commands/channel-add-help.js +5 -5
  56. package/lib/commands/datasource-capability-relate-cli.js +5 -4
  57. package/lib/commands/repair-auth-apply.js +1 -1
  58. package/lib/commands/repair-datasource-key-skip.js +39 -0
  59. package/lib/commands/repair-datasource-keys.js +24 -12
  60. package/lib/commands/repair-rbac.js +16 -10
  61. package/lib/commands/role-assistant-copy-output.js +61 -0
  62. package/lib/commands/role-assistant-copy.js +155 -0
  63. package/lib/commands/role-assistant-test-output.js +8 -9
  64. package/lib/commands/role-assistant-test-result-rows.js +42 -0
  65. package/lib/commands/role-assistant.js +117 -48
  66. package/lib/commands/search.js +143 -0
  67. package/lib/commands/test-trust-external.js +7 -5
  68. package/lib/commands/upload-sidecar-followups.js +4 -1
  69. package/lib/commands/verify-operations-skip-e2e.js +131 -0
  70. package/lib/commands/verify-operations-step-plan.js +6 -33
  71. package/lib/commands/verify-operations-steps.js +3 -1
  72. package/lib/datasource/capability/relate-operations.js +28 -10
  73. package/lib/datasource/capability/run-capability-relate.js +48 -25
  74. package/lib/datasource/datasource-identifier.js +13 -5
  75. package/lib/deployment/deployer-poll-run.js +117 -35
  76. package/lib/external-system/deploy-dataplane-published.js +70 -0
  77. package/lib/external-system/deploy.js +12 -2
  78. package/lib/external-system/download-role-assistant.js +41 -15
  79. package/lib/external-system/download.js +7 -1
  80. package/lib/generator/wizard-datasource-key.js +54 -0
  81. package/lib/generator/wizard.js +55 -54
  82. package/lib/integration-definition/apply-datasource-keys.js +75 -0
  83. package/lib/integration-definition/apply-relationships.js +195 -0
  84. package/lib/integration-definition/apply-static-enterprise.js +229 -0
  85. package/lib/integration-definition/apply-system-file.js +71 -0
  86. package/lib/integration-definition/apply-test-endpoint.js +89 -0
  87. package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
  88. package/lib/integration-definition/apply.js +78 -59
  89. package/lib/integration-definition/enrich-openapi-operations.js +36 -10
  90. package/lib/integration-definition/enrich-openapi-pick.js +87 -0
  91. package/lib/lifecycle/role-assistant-governance.js +56 -21
  92. package/lib/programmatic/capability-registry.js +1 -0
  93. package/lib/programmatic/index.js +2 -0
  94. package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
  95. package/lib/programmatic/openapi-channel-install-schemas.js +4 -1
  96. package/lib/programmatic/openapi-component-schemas.js +1 -0
  97. package/lib/programmatic/openapi-descriptions.js +9 -3
  98. package/lib/programmatic/openapi-envelope-examples.js +7 -0
  99. package/lib/programmatic/openapi-operation-bindings.js +5 -0
  100. package/lib/programmatic/openapi-request-schemas.js +5 -0
  101. package/lib/programmatic/openapi-schema-descriptions-channel.js +8 -5
  102. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  103. package/lib/programmatic/openapi-spec.js +1 -0
  104. package/lib/programmatic/request-timeout.js +3 -0
  105. package/lib/programmatic/route-handler-map.js +7 -0
  106. package/lib/programmatic/run-channel-catalog.js +50 -8
  107. package/lib/programmatic/run-channel-install-options.js +5 -1
  108. package/lib/programmatic/run-download.js +41 -0
  109. package/lib/protection/auth-context.js +3 -1
  110. package/lib/protection/protection-display.js +3 -2
  111. package/lib/protection/report-exit.js +50 -0
  112. package/lib/protection/run-commands.js +2 -0
  113. package/lib/role-assistant/package-validate.js +175 -0
  114. package/lib/role-assistant/test-case-assertion-row.js +36 -0
  115. package/lib/role-assistant/test-case-copy-bind.js +77 -0
  116. package/lib/role-assistant/test-case-copy-expected.js +127 -0
  117. package/lib/role-assistant/test-case-copy-from-work.js +90 -0
  118. package/lib/role-assistant/test-case-copy-interactions.js +67 -0
  119. package/lib/role-assistant/test-case-copy.js +119 -0
  120. package/lib/role-assistant/test-case-expected-catalog.js +135 -0
  121. package/lib/role-assistant/test-case-validate.js +88 -0
  122. package/lib/role-assistant/test-cases-bid.js +117 -4
  123. package/lib/role-assistant/test-cases-evaluate.js +137 -30
  124. package/lib/role-assistant/test-cases-honesty.js +155 -6
  125. package/lib/role-assistant/test-cases-lifecycle.js +291 -0
  126. package/lib/role-assistant/test-cases-search-graph.js +122 -0
  127. package/lib/role-assistant/test-cases-search.js +20 -2
  128. package/lib/role-assistant/test-cases.js +34 -168
  129. package/lib/role-assistant/test-pack-map.js +180 -0
  130. package/lib/role-assistant/test-pack-sync.js +187 -0
  131. package/lib/role-assistant/test-runner-debug.js +54 -0
  132. package/lib/role-assistant/test-runner-respond-body.js +36 -0
  133. package/lib/role-assistant/test-runner-search.js +20 -5
  134. package/lib/role-assistant/test-runner-start-payload.js +63 -10
  135. package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
  136. package/lib/role-assistant/test-runner-workhub.js +45 -21
  137. package/lib/role-assistant/test-runner.js +50 -10
  138. package/lib/schema/external-datasource.schema.json +36 -5
  139. package/lib/schema/external-system.schema.json +20 -2
  140. package/lib/schema/role-assistant-test-case.schema.json +408 -0
  141. package/lib/search/dataplane-context.js +23 -0
  142. package/lib/search/search-args.js +211 -0
  143. package/lib/search/search-display.js +238 -0
  144. package/lib/search/search-errors.js +50 -0
  145. package/lib/search/search-prompts.js +119 -0
  146. package/lib/search/search-roles.js +85 -0
  147. package/lib/search/search-run.js +241 -0
  148. package/lib/search/search-skills.js +198 -0
  149. package/lib/utils/authentication-slot-show.js +153 -0
  150. package/lib/utils/credential-display.js +43 -1
  151. package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
  152. package/lib/utils/external-system-readiness-compact-display.js +30 -1
  153. package/lib/utils/external-system-validators.js +2 -1
  154. package/lib/utils/help-builder.js +3 -1
  155. package/lib/utils/schema-loader.js +37 -0
  156. package/lib/validation/validate-external-file.js +5 -1
  157. package/lib/validation/validate.js +3 -2
  158. package/package.json +1 -1
  159. package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
  160. package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
  161. package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
  162. package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
  163. package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
  164. package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
  165. package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
  166. package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
  167. package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
  168. package/templates/agent-kit/agent-kit.yaml +45 -0
  169. package/templates/agent-kit/instructions/AGENTKIT.md +83 -0
  170. package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
  171. package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
  172. package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
  173. package/templates/agent-kit/parity-inventory.yaml +188 -0
  174. package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +58 -0
  175. package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
  176. package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
  177. package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
  178. package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
  179. package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +51 -0
  180. package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
  181. package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
  182. package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
  183. package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +50 -0
  184. package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
  185. package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
  186. package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
  187. package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +42 -0
  188. package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
  189. package/templates/agent-kit/skills/shared/hosts.md +78 -0
  190. package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
  191. package/templates/agent-kit/workspace/LICENSE.mit +21 -0
  192. package/templates/agent-kit/workspace/README.md +89 -0
  193. package/templates/applications/builder-api/Dockerfile +3 -1
  194. package/templates/applications/dataplane/application.yaml +2 -2
  195. package/templates/applications/dataplane/env.template +1 -1
  196. package/templates/applications/dataplane/rbac.yaml +28 -0
  197. package/templates/applications/keycloak/env.template +3 -3
  198. package/templates/applications/miso-controller/application.yaml +1 -1
  199. package/templates/applications/miso-controller/env.template +8 -9
  200. package/templates/channels/claude/TROUBLESHOOTING.md +3 -0
  201. package/templates/channels/claude/channel.json +1 -1
  202. package/templates/channels/claude/install.template.md.hbs +1 -0
  203. package/templates/channels/claude/integration/claude-system.json +1 -1
  204. package/templates/channels/slack/channel.json +11 -0
  205. package/templates/channels/slack/install.template.md.hbs +9 -0
  206. package/templates/channels/slack/integration/slack-system.json +11 -0
  207. package/templates/channels/slack/manifest.template.json.hbs +6 -3
  208. package/templates/channels/teams-bot/channel.json +1 -0
  209. package/templates/python/docker-compose.hbs +14 -0
  210. 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 maybeProvisionSlackChannel(params) {
227
- if (!params || params.channelTarget !== 'slack') {
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 (params.options && params.options.dryRun === true) {
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
- return await provisionAndPublish(params, options, deps, ctx, projectRoot);
284
+ const result = await provisionAndPublish(params, options, deps, ctx, projectRoot);
285
+ return attachSlackMcpRemaining(result, mcpCallback);
249
286
  } catch (error) {
250
- return recoverOrRefreshAuth(error, params, options, deps, ctx, projectRoot);
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
- const lines = fromChild.split('\n').map((line) => line.trim()).filter(Boolean);
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 runtime = path.join(__dirname, 'curl-shim.js');
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 publishing local integration files before dataplane steps')
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 publishing local integration files before validate')
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
- - Local integration files are published before run unless --no-publish.
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
+ };