@aifabrix/builder 2.51.1 → 2.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/jest.isolated-projects.js +25 -2
  2. package/jest.projects.js +4 -1
  3. package/lib/api/datasources-extended.api.js +8 -8
  4. package/lib/api/keycloak.api.js +92 -0
  5. package/lib/api/token-providers.api.js +77 -0
  6. package/lib/api/types/keycloak.types.js +23 -0
  7. package/lib/api/types/token-providers.types.js +65 -0
  8. package/lib/app/down.js +16 -1
  9. package/lib/app/run-container-start.js +4 -0
  10. package/lib/app/run-deploy-job.js +135 -27
  11. package/lib/app/run-env-compose.js +32 -0
  12. package/lib/app/run-env-recovery.js +35 -0
  13. package/lib/app/run-helpers.js +5 -6
  14. package/lib/app/run.js +11 -3
  15. package/lib/channels/add-channel.js +126 -19
  16. package/lib/channels/approval-guides/chatgpt.js +12 -9
  17. package/lib/channels/approval-guides/microsoft-copilot.js +16 -12
  18. package/lib/channels/channel-add-ensure.js +128 -0
  19. package/lib/channels/channel-artifact-generator.js +11 -1
  20. package/lib/channels/channel-branding.js +94 -0
  21. package/lib/channels/channel-credential.js +8 -0
  22. package/lib/channels/channel-discovery.js +330 -0
  23. package/lib/channels/channel-external-system.js +1 -1
  24. package/lib/channels/channel-runtime-resolver.js +103 -14
  25. package/lib/channels/channel-status-display.js +7 -1
  26. package/lib/channels/channel-targets.js +18 -1
  27. package/lib/channels/chatgpt-runtime-contract.js +1 -1
  28. package/lib/channels/microsoft-copilot-channel-add.js +138 -0
  29. package/lib/channels/microsoft-copilot-entra-sso-form.js +180 -0
  30. package/lib/channels/microsoft-copilot-entra-sso.js +264 -0
  31. package/lib/channels/microsoft-copilot-icons.js +74 -0
  32. package/lib/channels/microsoft-copilot-limits.js +84 -0
  33. package/lib/channels/microsoft-copilot-package.js +130 -49
  34. package/lib/channels/microsoft-copilot-validate.js +197 -0
  35. package/lib/cli/index.js +2 -0
  36. package/lib/cli/infra-guided-footers.js +1 -1
  37. package/lib/cli/infra-guided-public-url-warn.js +55 -0
  38. package/lib/cli/infra-guided.js +78 -62
  39. package/lib/cli/setup-app.help.js +4 -0
  40. package/lib/cli/setup-app.test-commands.js +59 -28
  41. package/lib/cli/setup-external-system.js +50 -12
  42. package/lib/cli/setup-infra.js +31 -4
  43. package/lib/commands/channel-add-setup.js +35 -10
  44. package/lib/commands/channel.js +27 -12
  45. package/lib/commands/deploy-gate-orchestrator.js +3 -2
  46. package/lib/commands/governance-verify-external.js +2 -5
  47. package/lib/commands/integration-definition.js +158 -0
  48. package/lib/commands/lifecycle-external.js +14 -7
  49. package/lib/commands/repair-auth-apply.js +19 -5
  50. package/lib/commands/repair-datasource-sync-operations.js +4 -1
  51. package/lib/commands/role-assistant-test-output.js +200 -0
  52. package/lib/commands/role-assistant.js +131 -114
  53. package/lib/commands/test-governance-external.js +2 -5
  54. package/lib/commands/up-miso.js +61 -24
  55. package/lib/commands/upload-data-sync-finalize.js +20 -3
  56. package/lib/commands/verify-governance-external.js +2 -5
  57. package/lib/commands/verify-operations-external.js +2 -5
  58. package/lib/commands/verify-operations-step-plan.js +31 -0
  59. package/lib/commands/verify-trust-command-action.js +2 -5
  60. package/lib/datasource/capability/capability-resolve.js +15 -5
  61. package/lib/datasource/capability/copy-operations.js +14 -4
  62. package/lib/datasource/datasource-identifier.js +4 -3
  63. package/lib/datasource/integration-context.js +3 -3
  64. package/lib/datasource/resolve-app.js +90 -8
  65. package/lib/datasource/test-e2e.js +2 -2
  66. package/lib/datasource/unified-validation-run-body.js +15 -1
  67. package/lib/datasource/unified-validation-run-resolve.js +2 -2
  68. package/lib/external-system/deploy-helpers.js +9 -5
  69. package/lib/external-system/deploy.js +2 -1
  70. package/lib/external-system/test-system-level.js +21 -3
  71. package/lib/external-system/test.js +4 -4
  72. package/lib/generator/builders.js +9 -15
  73. package/lib/infrastructure/index.js +19 -4
  74. package/lib/integration-definition/apply.js +478 -0
  75. package/lib/integration-definition/canonical-json.js +51 -0
  76. package/lib/integration-definition/emit-suite-bid.js +94 -0
  77. package/lib/integration-definition/enrich-crm-field-mappings.js +240 -0
  78. package/lib/integration-definition/enrich-openapi-operations.js +434 -0
  79. package/lib/integration-definition/from-discovery.js +339 -0
  80. package/lib/integration-definition/hash.js +37 -0
  81. package/lib/integration-definition/index.js +37 -0
  82. package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +205 -0
  83. package/lib/integration-definition/resource-type-catalog.js +59 -0
  84. package/lib/integration-definition/system-kind-enum.js +40 -0
  85. package/lib/integration-definition/validate.js +148 -0
  86. package/lib/programmatic/builder-api-request.js +5 -1
  87. package/lib/programmatic/builder-help-governance.js +3 -2
  88. package/lib/programmatic/capability-registry.js +19 -0
  89. package/lib/programmatic/openapi-component-schemas.js +6 -1
  90. package/lib/programmatic/openapi-descriptions.js +40 -0
  91. package/lib/programmatic/openapi-envelope-examples.js +269 -0
  92. package/lib/programmatic/openapi-operation-bindings.js +45 -0
  93. package/lib/programmatic/openapi-request-schemas.js +14 -0
  94. package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
  95. package/lib/programmatic/openapi-result-schemas.js +46 -99
  96. package/lib/programmatic/openapi-schema-descriptions-core.js +7 -4
  97. package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
  98. package/lib/programmatic/openapi-schema-descriptions-operations.js +24 -0
  99. package/lib/programmatic/openapi-schema-helpers.js +9 -9
  100. package/lib/programmatic/openapi-spec.js +11 -1
  101. package/lib/programmatic/orchestration-openapi-meta.js +10 -0
  102. package/lib/programmatic/route-handler-map.js +29 -1
  103. package/lib/programmatic/run-channel-package.js +236 -0
  104. package/lib/programmatic/run-integration-definition.js +69 -0
  105. package/lib/role-assistant/knowledge-markdown-frontmatter.js +75 -0
  106. package/lib/role-assistant/knowledge-sync-logging.js +58 -0
  107. package/lib/role-assistant/knowledge-sync.js +104 -89
  108. package/lib/role-assistant/test-cases-bid.js +155 -0
  109. package/lib/role-assistant/test-cases-evaluate.js +9 -1
  110. package/lib/role-assistant/test-cases-honesty.js +24 -10
  111. package/lib/role-assistant/test-cases.js +28 -0
  112. package/lib/role-assistant/test-runner-bid-apply.js +122 -0
  113. package/lib/role-assistant/test-runner-bid-document.js +278 -0
  114. package/lib/role-assistant/test-runner-workhub-answers.js +289 -46
  115. package/lib/role-assistant/test-runner-workhub.js +121 -25
  116. package/lib/role-assistant/test-suite.js +119 -0
  117. package/lib/schema/application-schema.json +64 -32
  118. package/lib/schema/external-datasource.schema.json +103 -17
  119. package/lib/schema/external-system.schema.json +54 -3
  120. package/lib/schema/infra.parameter.yaml +0 -20
  121. package/lib/schema/integration-definition.schema.json +195 -0
  122. package/lib/utils/authentication-shape.js +6 -0
  123. package/lib/utils/certify-external-workspace.js +40 -0
  124. package/lib/utils/docker-build.js +3 -3
  125. package/lib/utils/docker-run-ephemeral.js +77 -17
  126. package/lib/utils/health-check-public-warn.js +31 -13
  127. package/lib/utils/health-check.js +11 -1
  128. package/lib/utils/help-builder.js +1 -0
  129. package/lib/utils/paths.js +13 -15
  130. package/lib/utils/promote-dev-docker-image.js +97 -18
  131. package/lib/utils/role-assistant-paths.js +76 -14
  132. package/lib/utils/transient-developer-id.js +28 -0
  133. package/lib/utils/upload-sync-options.js +7 -4
  134. package/lib/validation/reserved-system-key-prefixes.js +56 -0
  135. package/lib/validation/validate.js +54 -19
  136. package/package.json +1 -1
  137. package/scripts/pnpm/af.mjs +24 -9
  138. package/scripts/pnpm/help.mjs +1 -1
  139. package/templates/applications/builder-api/application.yaml +3 -3
  140. package/templates/applications/dataplane/application.yaml +5 -5
  141. package/templates/applications/dataplane/env.template +8 -7
  142. package/templates/applications/dataplane/rbac.yaml +10 -10
  143. package/templates/applications/keycloak/application.yaml +2 -2
  144. package/templates/applications/keycloak/env.template +5 -2
  145. package/templates/applications/miso-controller/application.yaml +25 -11
  146. package/templates/applications/miso-controller/env.template +24 -5
  147. package/templates/channels/README.md +11 -1
  148. package/templates/channels/brand/color-192.png +0 -0
  149. package/templates/channels/brand/dark/128.png +0 -0
  150. package/templates/channels/brand/dark/192.png +0 -0
  151. package/templates/channels/brand/dark/256.png +0 -0
  152. package/templates/channels/brand/dark/32.png +0 -0
  153. package/templates/channels/brand/dark/512.png +0 -0
  154. package/templates/channels/brand/dark/64.png +0 -0
  155. package/templates/channels/brand/light/128.png +0 -0
  156. package/templates/channels/brand/light/192.png +0 -0
  157. package/templates/channels/brand/light/256.png +0 -0
  158. package/templates/channels/brand/light/32.png +0 -0
  159. package/templates/channels/brand/light/512.png +0 -0
  160. package/templates/channels/brand/light/64.png +0 -0
  161. package/templates/channels/brand/mono-white/128.png +0 -0
  162. package/templates/channels/brand/mono-white/192.png +0 -0
  163. package/templates/channels/brand/mono-white/256.png +0 -0
  164. package/templates/channels/brand/mono-white/32.png +0 -0
  165. package/templates/channels/brand/mono-white/512.png +0 -0
  166. package/templates/channels/brand/mono-white/64.png +0 -0
  167. package/templates/channels/brand/outline-32.png +0 -0
  168. package/templates/channels/chatgpt/install.template.md.hbs +76 -36
  169. package/templates/channels/chatgpt/integration/README.md +4 -4
  170. package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
  171. package/templates/channels/chatgpt/manifest.template.json.hbs +3 -3
  172. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +10 -16
  173. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
  174. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +27 -0
  175. package/templates/channels/microsoft-copilot/install.template.md.hbs +39 -20
  176. package/templates/channels/microsoft-copilot/integration/README.md +2 -3
  177. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +1 -22
  178. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +7 -7
  179. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +11 -0
  180. package/templates/channels/slack/install.template.md.hbs +6 -1
  181. package/templates/channels/slack/integration/README.md +2 -4
  182. package/templates/channels/teams-bot/install.template.md.hbs +4 -0
  183. package/templates/channels/teams-bot/integration/README.md +3 -5
  184. package/templates/channels/web-embed/integration/web-embed-system.json +1 -16
  185. package/templates/python/docker-compose.hbs +10 -0
  186. package/templates/typescript/docker-compose.hbs +10 -0
  187. /package/.cursor/plans/{Done → Archive}/157.1-security-quality-violations-by-type.csv +0 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Enterprise systemKind enum shared with external-system.schema.json.
3
+ * @fileoverview Load allowed systemKind values for BID product rules
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const externalSystemSchema = require('../schema/external-system.schema.json');
9
+
10
+ /** @type {Set<string>|null} */
11
+ let cachedKinds = null;
12
+
13
+ /**
14
+ * @returns {Set<string>}
15
+ */
16
+ function getAllowedSystemKinds() {
17
+ if (cachedKinds) {
18
+ return cachedKinds;
19
+ }
20
+ const values = externalSystemSchema?.properties?.systemKind?.enum;
21
+ cachedKinds = new Set(Array.isArray(values) ? values.map(String) : []);
22
+ return cachedKinds;
23
+ }
24
+
25
+ /**
26
+ * @param {string} kind
27
+ * @returns {boolean}
28
+ */
29
+ function isAllowedSystemKind(kind) {
30
+ const normalized = String(kind || '').trim();
31
+ if (!normalized) {
32
+ return false;
33
+ }
34
+ return getAllowedSystemKinds().has(normalized);
35
+ }
36
+
37
+ module.exports = {
38
+ getAllowedSystemKinds,
39
+ isAllowedSystemKind
40
+ };
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Validate Builder Integration Definition (BID) v1.0.0.
3
+ * @fileoverview AJV + hash + product rules for BID
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const Ajv = require('ajv');
9
+ const addFormats = require('ajv-formats');
10
+ const schema = require('../schema/integration-definition.schema.json');
11
+ const { computeDefinitionHash } = require('./hash');
12
+ const { isActiveResourceTypeKey } = require('./resource-type-catalog');
13
+ const { isAllowedSystemKind } = require('./system-kind-enum');
14
+
15
+ const GOLD_PATH_RE = /test-e2e-hubspot|knownPlatform|builder-hp-goal/i;
16
+
17
+ let cachedValidator = null;
18
+
19
+ /**
20
+ * @returns {import('ajv').ValidateFunction}
21
+ */
22
+ function getValidator() {
23
+ if (cachedValidator) {
24
+ return cachedValidator;
25
+ }
26
+ const ajv = new Ajv({ allErrors: true, strict: false });
27
+ addFormats(ajv);
28
+ cachedValidator = ajv.compile(schema);
29
+ return cachedValidator;
30
+ }
31
+
32
+ /**
33
+ * Reset validator cache (tests).
34
+ */
35
+ function resetIntegrationDefinitionValidator() {
36
+ cachedValidator = null;
37
+ }
38
+
39
+ /**
40
+ * @param {Record<string, unknown>} doc
41
+ * @param {string[]} errors
42
+ * @returns {void}
43
+ */
44
+ function appendAjvErrors(doc, errors) {
45
+ const validate = getValidator();
46
+ if (validate(doc)) {
47
+ return;
48
+ }
49
+ for (const err of validate.errors || []) {
50
+ errors.push(`${err.instancePath || '/'} ${err.message}`);
51
+ }
52
+ }
53
+
54
+ /**
55
+ * @param {Record<string, unknown>} doc
56
+ * @param {string[]} errors
57
+ * @returns {void}
58
+ */
59
+ function appendIdentityAndHashErrors(doc, errors) {
60
+ if (doc.schemaVersion !== '1.0.0') {
61
+ errors.push(`Unsupported schemaVersion ${String(doc.schemaVersion)}; expected 1.0.0`);
62
+ }
63
+ const expectedHash = computeDefinitionHash(doc);
64
+ if (doc.definitionHash !== expectedHash) {
65
+ errors.push(`definitionHash mismatch: expected ${expectedHash}`);
66
+ }
67
+ const identity = /** @type {Record<string, unknown>} */ (doc.packageIdentity || {});
68
+ const system = /** @type {Record<string, unknown>} */ (doc.system || {});
69
+ if (identity.systemKey && system.key && identity.systemKey !== system.key) {
70
+ errors.push('packageIdentity.systemKey must match system.key');
71
+ }
72
+ }
73
+
74
+ /**
75
+ * @param {Record<string, unknown>} doc
76
+ * @param {string[]} errors
77
+ * @returns {void}
78
+ */
79
+ function appendProductRuleErrors(doc, errors) {
80
+ const blob = JSON.stringify(doc);
81
+ if (GOLD_PATH_RE.test(blob)) {
82
+ errors.push(
83
+ 'BID must not embed gold package paths or knownPlatform generation sources'
84
+ );
85
+ }
86
+ if (typeof doc.sync === 'object' && doc.sync && /** @type {any} */ (doc.sync).mode !== 'incremental') {
87
+ errors.push('sync.mode must be incremental');
88
+ }
89
+ }
90
+
91
+ /**
92
+ * @param {Record<string, unknown>} doc
93
+ * @param {string[]} errors
94
+ * @returns {void}
95
+ */
96
+ function appendCatalogAndKindErrors(doc, errors) {
97
+ const system = /** @type {Record<string, unknown>} */ (doc.system || {});
98
+ if (system.systemKind !== undefined && system.systemKind !== null && system.systemKind !== '') {
99
+ if (!isAllowedSystemKind(String(system.systemKind))) {
100
+ errors.push(
101
+ `system.systemKind '${String(system.systemKind)}' is not an enterprise catalog value (see external-system.schema.json)`
102
+ );
103
+ }
104
+ }
105
+ const datasources = Array.isArray(doc.datasources) ? doc.datasources : [];
106
+ datasources.forEach((row, index) => {
107
+ if (!row || typeof row !== 'object') {
108
+ return;
109
+ }
110
+ const resourceType = /** @type {Record<string, unknown>} */ (row).resourceType;
111
+ if (resourceType === undefined || resourceType === null || resourceType === '') {
112
+ return;
113
+ }
114
+ const key = String(resourceType);
115
+ if (!isActiveResourceTypeKey(key)) {
116
+ errors.push(
117
+ `datasources[${index}].resourceType '${key}' is not an active catalog key (GET /help?topic=resourceTypeCatalog)`
118
+ );
119
+ }
120
+ });
121
+ }
122
+
123
+ /**
124
+ * @param {unknown} bid
125
+ * @returns {{ valid: true, bid: Record<string, unknown> } | { valid: false, errors: string[] }}
126
+ */
127
+ function validateIntegrationDefinition(bid) {
128
+ const errors = [];
129
+ if (!bid || typeof bid !== 'object') {
130
+ return { valid: false, errors: ['BID must be an object'] };
131
+ }
132
+ const doc = /** @type {Record<string, unknown>} */ (bid);
133
+ appendAjvErrors(doc, errors);
134
+ appendIdentityAndHashErrors(doc, errors);
135
+ appendProductRuleErrors(doc, errors);
136
+ appendCatalogAndKindErrors(doc, errors);
137
+ if (errors.length) {
138
+ return { valid: false, errors };
139
+ }
140
+ return { valid: true, bid: doc };
141
+ }
142
+
143
+ module.exports = {
144
+ validateIntegrationDefinition,
145
+ resetIntegrationDefinitionValidator,
146
+ INTEGRATION_DEFINITION_SCHEMA_NAME: 'aifabrix.builder.integrationDefinition',
147
+ INTEGRATION_DEFINITION_SCHEMA_VERSION: '1.0.0'
148
+ };
@@ -19,7 +19,11 @@ const { withRequestTimeout } = require('./request-timeout');
19
19
  * @returns {boolean}
20
20
  */
21
21
  function requiresAuth(capability) {
22
- return capability.handlerId !== 'health' && capability.handlerId !== 'ready';
22
+ return (
23
+ capability.handlerId !== 'health' &&
24
+ capability.handlerId !== 'ready' &&
25
+ capability.handlerId !== 'getBuilderHelp'
26
+ );
23
27
  }
24
28
 
25
29
  /**
@@ -8,7 +8,7 @@
8
8
 
9
9
  'use strict';
10
10
 
11
- const fs = require('fs');
11
+ const fs = require('../internal/fs-real-sync');
12
12
  const path = require('path');
13
13
  const { buildHelpEnvelope } = require('./builder-help-envelope');
14
14
  const { listPlatformRoles } = require('./platform-rbac-catalog');
@@ -168,5 +168,6 @@ module.exports = {
168
168
  buildPlatformRolesTopic,
169
169
  buildResourceTypeCatalogTopic,
170
170
  buildDimensionsGuideTopic,
171
- buildChannelOnboardingTopic
171
+ buildChannelOnboardingTopic,
172
+ loadResourceTypeCatalog
172
173
  };
@@ -15,6 +15,13 @@ const CAPABILITIES = Object.freeze([
15
15
  { method: 'GET', route: '/workspaces/me/systems/:systemKey', handlerId: 'getSystemManifest', operationType: 'workspace.read', mutating: false },
16
16
  { method: 'DELETE', route: '/workspaces/me/systems/:systemKey', handlerId: 'deleteSystem', operationType: 'workspace.write', mutating: true },
17
17
  { method: 'POST', route: '/systems/:systemKey/wizard', handlerId: 'runWizard', operationType: 'plan', mutating: true },
18
+ {
19
+ method: 'POST',
20
+ route: '/systems/:systemKey/integration-definition/apply',
21
+ handlerId: 'applyIntegrationDefinition',
22
+ operationType: 'plan',
23
+ mutating: true
24
+ },
18
25
  { method: 'POST', route: '/systems/:systemKey/repair', handlerId: 'runRepair', operationType: 'plan', mutating: true },
19
26
  { method: 'GET', route: '/systems/:systemKey/manifest/sections', handlerId: 'listManifestSections', operationType: 'workspace.read', mutating: false },
20
27
  { method: 'GET', route: '/systems/:systemKey/manifest/section/:sectionKey', handlerId: 'getManifestSection', operationType: 'workspace.read', mutating: false },
@@ -63,8 +70,20 @@ const CAPABILITIES = Object.freeze([
63
70
  { method: 'POST', route: '/systems/:systemKey/repository/create-review', handlerId: 'runRepositoryCreateReview', operationType: 'repository', mutating: true },
64
71
  { method: 'GET', route: '/systems/:systemKey/repository/status', handlerId: 'getRepositoryStatus', operationType: 'repository.read', mutating: false },
65
72
  { method: 'POST', route: '/systems/:systemKey/repository/dispatch-pipeline', handlerId: 'runRepositoryDispatchPipeline', operationType: 'repository', mutating: true },
73
+ { method: 'POST', route: '/systems/:systemKey/channels/package', handlerId: 'buildChannelPackage', operationType: 'channel', mutating: true },
74
+ { method: 'GET', route: '/systems/:systemKey/channels/package', handlerId: 'getChannelPackageSummary', operationType: 'channel.read', mutating: false },
75
+ { method: 'GET', route: '/systems/:systemKey/channels/package/zip', handlerId: 'getChannelPackageZip', operationType: 'channel.read', mutating: false },
76
+ { method: 'GET', route: '/systems/:systemKey/channels/branding', handlerId: 'getChannelBranding', operationType: 'channel.read', mutating: false },
77
+ { method: 'PATCH', route: '/systems/:systemKey/channels/branding', handlerId: 'patchChannelBranding', operationType: 'channel', mutating: true },
66
78
  { method: 'GET', route: '/health', handlerId: 'health', operationType: 'infra', mutating: false },
67
79
  { method: 'GET', route: '/health/ready', handlerId: 'ready', operationType: 'infra', mutating: false },
80
+ {
81
+ method: 'GET',
82
+ route: '/help',
83
+ handlerId: 'getBuilderHelp',
84
+ operationType: 'help.read',
85
+ mutating: false
86
+ },
68
87
  { method: 'GET', route: '/evidence/:roleKey/metadata', handlerId: 'getEvidenceMetadata', operationType: 'evidence.read', mutating: false },
69
88
  { method: 'GET', route: '/evidence/:roleKey/download', handlerId: 'downloadEvidence', operationType: 'evidence.read', mutating: false },
70
89
  { method: 'POST', route: '/evidence/:roleKey/upload', handlerId: 'uploadEvidenceCandidates', operationType: 'evidence.write', mutating: true },
@@ -21,6 +21,7 @@ const {
21
21
  OPENAPI_EVIDENCE_REQUEST_SCHEMAS,
22
22
  OPENAPI_EVIDENCE_RESULT_SCHEMAS
23
23
  } = require('./openapi-evidence-schemas');
24
+ const { OPENAPI_HELP_RESULT_SCHEMAS } = require('./openapi-help-schemas');
24
25
 
25
26
  const RESPONSE_ENVELOPES = [
26
27
  ['ListSystemsResponse', 'ListSystemsData'],
@@ -28,6 +29,7 @@ const RESPONSE_ENVELOPES = [
28
29
  ['SystemManifestResponse', 'SystemManifestData'],
29
30
  ['DeleteSystemResponse', 'DeleteSystemData'],
30
31
  ['WizardRunResponse', 'WizardRunData'],
32
+ ['IntegrationDefinitionApplyResponse', 'IntegrationDefinitionApplyData'],
31
33
  ['RepairResultResponse', 'RepairResultData'],
32
34
  ['ValidateResultResponse', 'ValidateResultData'],
33
35
  ['PreviewUploadResponse', 'PreviewUploadData'],
@@ -51,7 +53,8 @@ const RESPONSE_ENVELOPES = [
51
53
  ['EvidenceAuthoringMetadataResponse', 'EvidenceAuthoringMetadataData'],
52
54
  ['EvidenceDownloadResponse', 'EvidenceDownloadData'],
53
55
  ['EvidenceUploadResponse', 'EvidenceUploadData'],
54
- ['EvidenceActivateResponse', 'EvidenceActivateData']
56
+ ['EvidenceActivateResponse', 'EvidenceActivateData'],
57
+ ['BuilderHelpResponse', 'BuilderHelpData']
55
58
  ];
56
59
 
57
60
  /**
@@ -70,6 +73,7 @@ function buildOpenApiComponentSchemas() {
70
73
  ...OPENAPI_APPLY_RESULT_SCHEMAS,
71
74
  ...OPENAPI_MANIFEST_RESULT_SCHEMAS,
72
75
  ...OPENAPI_EVIDENCE_RESULT_SCHEMAS,
76
+ ...OPENAPI_HELP_RESULT_SCHEMAS,
73
77
  EmptyResultData: { type: 'object', properties: {}, additionalProperties: false },
74
78
  ...envelopes
75
79
  });
@@ -78,6 +82,7 @@ function buildOpenApiComponentSchemas() {
78
82
  module.exports = {
79
83
  buildOpenApiComponentSchemas,
80
84
  buildSuccessEnvelopeSchema,
85
+ RESPONSE_ENVELOPES,
81
86
  OPENAPI_REQUEST_SCHEMAS,
82
87
  OPENAPI_RESULT_SCHEMAS
83
88
  };
@@ -39,6 +39,12 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
39
39
  'Run headless wizard to materialize system and datasource JSON under the workspace. Mutating; may take up to MAX_REQUEST_TIMEOUT_MS. Retry with the same Idempotency-Key.',
40
40
  tags: ['build']
41
41
  },
42
+ applyIntegrationDefinition: {
43
+ summary: 'Apply Builder Integration Definition (BID) into workspace',
44
+ description:
45
+ 'Materialize system and datasource package files from an aifabrix.builder.integrationDefinition document. Prefer this over wizard when OpenAPI is not yet available. Mutating; retry with the same Idempotency-Key.',
46
+ tags: ['build']
47
+ },
42
48
  runRepair: {
43
49
  summary: 'Repair workspace manifest drift',
44
50
  description:
@@ -194,6 +200,12 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
194
200
  description: 'Returns ready with configured dataplaneUrl. Does not verify Dataplane connectivity in V1.',
195
201
  tags: ['infra']
196
202
  },
203
+ getBuilderHelp: {
204
+ summary: 'LLM help topics',
205
+ description:
206
+ 'Deterministic product help for agents (no tenant data). Required topic enum includes resourceTypeCatalog for BID resourceType keys. No authentication.',
207
+ tags: ['help']
208
+ },
197
209
  getEvidenceMetadata: {
198
210
  summary: 'Evidence authoring metadata',
199
211
  description:
@@ -217,6 +229,34 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
217
229
  description:
218
230
  'Activate one or many human-approved certified Evidence ids. Organizational gate after technical certification. Mutating; use Idempotency-Key.',
219
231
  tags: ['evidence']
232
+ },
233
+ buildChannelPackage: {
234
+ summary: 'Build channel package',
235
+ description:
236
+ 'Build vendor channel package from External AI Discovery plus optional workspace branding. Returns summary, README/ZIP links, and installReady. Mutating.',
237
+ tags: ['channel']
238
+ },
239
+ getChannelPackageSummary: {
240
+ summary: 'Get channel package summary',
241
+ description: 'Return last built channel package summary and README/ZIP links. Read-only.',
242
+ tags: ['channel']
243
+ },
244
+ getChannelPackageZip: {
245
+ summary: 'Download channel package ZIP',
246
+ description:
247
+ 'Return the built app package as zipBase64 (application/zip). Build package first. Read-only.',
248
+ tags: ['channel']
249
+ },
250
+ getChannelBranding: {
251
+ summary: 'Get channel branding',
252
+ description: 'Return optional workspace branding (displayName, description, icon paths). Read-only.',
253
+ tags: ['channel']
254
+ },
255
+ patchChannelBranding: {
256
+ summary: 'Patch channel branding',
257
+ description:
258
+ 'Update optional package branding overrides stored in the Builder API workspace. Mutating.',
259
+ tags: ['channel']
220
260
  }
221
261
  });
222
262
 
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Minimal valid `data` examples for builder-api success envelopes (OAPI-136).
3
+ *
4
+ * @fileoverview Envelope data examples keyed by data schema name
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const SAMPLE_SYSTEM_KEY = 'hubspot-demo';
12
+ const SAMPLE_DATASOURCE_KEY = 'hubspot-demo-companies';
13
+ const SAMPLE_UUID = '00000000-0000-4000-8000-000000000010';
14
+ const SAMPLE_ISO = '2026-01-15T12:00:00.000Z';
15
+
16
+ const SAMPLE_META = {
17
+ ownerUserId: 'user-demo',
18
+ systemKey: SAMPLE_SYSTEM_KEY,
19
+ createdAt: SAMPLE_ISO,
20
+ lastModifiedAt: SAMPLE_ISO,
21
+ lastOperation: 'validate'
22
+ };
23
+
24
+ const SAMPLE_QUALITY = {
25
+ score: 100,
26
+ blockingIssues: [],
27
+ warnings: [],
28
+ missingInputs: [],
29
+ assumptions: []
30
+ };
31
+
32
+ const SAMPLE_MCP_RESULT = {
33
+ success: true,
34
+ status: 'ok',
35
+ message: 'completed'
36
+ };
37
+
38
+ const SAMPLE_SYSTEM_MANIFEST = {
39
+ systemKey: SAMPLE_SYSTEM_KEY,
40
+ meta: SAMPLE_META,
41
+ files: [{ path: 'application.json', isDirectory: false, sizeBytes: 128, redacted: false }]
42
+ };
43
+
44
+ const SAMPLE_VALIDATION_STEP = {
45
+ valid: true,
46
+ errors: [],
47
+ warnings: []
48
+ };
49
+
50
+ /** @type {Record<string, Object>} */
51
+ const OPENAPI_ENVELOPE_DATA_EXAMPLES = {
52
+ HealthData: { status: 'ok' },
53
+ ReadyData: { status: 'ready', dataplaneUrl: 'http://localhost:3601' },
54
+ BuilderHelpData: {
55
+ version: '1.0.0',
56
+ schemaVersion: '1.0.0',
57
+ topic: 'resourceTypeCatalog',
58
+ key: 'all',
59
+ title: 'Resource type catalog',
60
+ summary: 'Taxonomy-only catalog keys for datasource.resourceType.',
61
+ data: {
62
+ schemaVersion: '1.0.0',
63
+ minimumSystemKeys: ['customer'],
64
+ resourceTypes: [
65
+ {
66
+ key: 'customer',
67
+ displayName: 'Customer',
68
+ description: 'Customer organization.',
69
+ category: 'business',
70
+ defaultRiskLevel: 'medium',
71
+ status: 'active'
72
+ }
73
+ ]
74
+ },
75
+ related: ['schemaCatalog'],
76
+ recommendedNext: ['topic=section&sectionKey=datasource.resourceType']
77
+ },
78
+ EmptyResultData: {},
79
+ ListSystemsData: { systems: [{ systemKey: SAMPLE_SYSTEM_KEY, meta: SAMPLE_META }] },
80
+ CreateSystemData: { systemKey: SAMPLE_SYSTEM_KEY, meta: SAMPLE_META },
81
+ SystemManifestData: SAMPLE_SYSTEM_MANIFEST,
82
+ DeleteSystemData: { systemKey: SAMPLE_SYSTEM_KEY, deleted: true },
83
+ WizardRunData: { systemKey: SAMPLE_SYSTEM_KEY, status: 'completed' },
84
+ IntegrationDefinitionApplyData: {
85
+ status: 'updated',
86
+ systemKey: SAMPLE_SYSTEM_KEY,
87
+ outputDir: `/workspace/integration/${SAMPLE_SYSTEM_KEY}`,
88
+ definitionId: 'bid-demo',
89
+ definitionHash: 'sha256:demo',
90
+ packageVersion: '1.0.0',
91
+ files: ['application.json']
92
+ },
93
+ RepairResultData: {
94
+ updated: true,
95
+ changes: ['synced dataSources'],
96
+ warnings: [],
97
+ changedFiles: ['application.json']
98
+ },
99
+ ValidateResultData: {
100
+ validationResult: {
101
+ valid: true,
102
+ errors: [],
103
+ warnings: [],
104
+ steps: {
105
+ application: SAMPLE_VALIDATION_STEP,
106
+ components: SAMPLE_VALIDATION_STEP,
107
+ manifest: SAMPLE_VALIDATION_STEP
108
+ }
109
+ },
110
+ pipelineValidation: null
111
+ },
112
+ PreviewUploadData: {
113
+ manifest: { key: SAMPLE_SYSTEM_KEY, version: '1.0.0', type: 'external' },
114
+ payload: {
115
+ version: '1.0.0',
116
+ application: { key: SAMPLE_SYSTEM_KEY, displayName: 'Demo', type: 'external' },
117
+ dataSources: [{ key: SAMPLE_DATASOURCE_KEY }]
118
+ }
119
+ },
120
+ UploadResultData: {
121
+ dataplaneUrl: 'http://localhost:3601',
122
+ environment: 'dev',
123
+ uploadSkipped: false
124
+ },
125
+ DeployResultData: {
126
+ deployed: true,
127
+ deploymentId: SAMPLE_UUID,
128
+ environment: 'dev',
129
+ systemKey: SAMPLE_SYSTEM_KEY
130
+ },
131
+ ProtectionUploadData: {
132
+ datasourceKey: SAMPLE_DATASOURCE_KEY,
133
+ uploaded: true,
134
+ dryRun: false
135
+ },
136
+ ProtectionCreateData: {
137
+ datasourceKey: SAMPLE_DATASOURCE_KEY,
138
+ created: true,
139
+ dryRun: false
140
+ },
141
+ TestResultData: {
142
+ runType: 'unit',
143
+ valid: true,
144
+ errors: [],
145
+ warnings: [],
146
+ systemResults: [{ file: 'hubspot-demo-system.json', valid: true, errors: [] }],
147
+ datasourceResults: [
148
+ {
149
+ key: SAMPLE_DATASOURCE_KEY,
150
+ file: 'hubspot-demo-datasource-companies.json',
151
+ valid: true,
152
+ errors: [],
153
+ warnings: []
154
+ }
155
+ ],
156
+ systemKey: SAMPLE_SYSTEM_KEY,
157
+ appName: SAMPLE_SYSTEM_KEY
158
+ },
159
+ CertifyResultData: {
160
+ command: 'verify-operations',
161
+ systemKey: SAMPLE_SYSTEM_KEY,
162
+ verdict: 'VERIFIED',
163
+ operationalReadinessPercent: 100,
164
+ certification: { level: 'SILVER', status: 'AI_READY' },
165
+ warnings: [],
166
+ details: [],
167
+ stepResults: []
168
+ },
169
+ LifecycleReportData: {
170
+ systemKey: SAMPLE_SYSTEM_KEY,
171
+ certification: { level: 'SILVER', status: 'AI_READY' },
172
+ operationalReadinessPercent: 100,
173
+ summary: true,
174
+ details: false
175
+ },
176
+ EnterpriseMcpInvocationData: {
177
+ capabilityKey: 'repository.status',
178
+ result: SAMPLE_MCP_RESULT
179
+ },
180
+ WorkspaceStatusData: {
181
+ local: SAMPLE_SYSTEM_MANIFEST,
182
+ remote: null
183
+ },
184
+ RepositoryStatusData: {
185
+ capabilityKey: 'repository.status',
186
+ result: SAMPLE_MCP_RESULT
187
+ },
188
+ ManifestSectionViewData: {
189
+ sectionKey: 'system.authentication',
190
+ target: 'system',
191
+ datasourceKey: null,
192
+ currentValue: {},
193
+ schemaFragment: {},
194
+ required: true,
195
+ mutable: true,
196
+ sourceOfTruth: true,
197
+ dependencyGraph: { downstreamFromThis: [] },
198
+ repairHooks: [],
199
+ recommendedNextActions: [],
200
+ sectionReadToken: SAMPLE_UUID,
201
+ quality: SAMPLE_QUALITY
202
+ },
203
+ ManifestPatchResultData: {
204
+ sectionKey: 'system.authentication',
205
+ datasourceKey: null,
206
+ intent: 'align auth method',
207
+ changedPaths: ['authentication.method'],
208
+ beforeHash: 'sha256:before',
209
+ afterHash: 'sha256:after',
210
+ derivedSectionsAffected: [],
211
+ repairRecommended: false,
212
+ repairHooks: [],
213
+ validationPreview: {},
214
+ riskHints: [],
215
+ nextActions: [],
216
+ dryRun: false,
217
+ quality: SAMPLE_QUALITY
218
+ },
219
+ ManifestSectionsListData: {
220
+ systemKey: SAMPLE_SYSTEM_KEY,
221
+ sections: [{ sectionKey: 'system.authentication', target: 'system' }],
222
+ datasourceKeys: [SAMPLE_DATASOURCE_KEY]
223
+ },
224
+ ManifestRepairResultData: {
225
+ hooksRun: ['sync-datasources'],
226
+ derivedSectionsUpdated: [],
227
+ repairResult: {},
228
+ dryRun: false,
229
+ quality: SAMPLE_QUALITY
230
+ },
231
+ EvidenceAuthoringMetadataData: {
232
+ roleKey: 'aifabrix-business-transformation',
233
+ evidenceKinds: [],
234
+ aspects: [],
235
+ resourceTypes: [],
236
+ assistantCapabilities: [],
237
+ writableFields: [],
238
+ requiredFields: [],
239
+ constraints: {
240
+ certification: {},
241
+ activation: { requiresCertified: true, requiresAuthority: false }
242
+ }
243
+ },
244
+ EvidenceDownloadData: {
245
+ roleKey: 'aifabrix-business-transformation',
246
+ count: 0,
247
+ data: []
248
+ },
249
+ EvidenceUploadData: {
250
+ roleKey: 'aifabrix-business-transformation',
251
+ inserted: 0,
252
+ updated: 0,
253
+ accepted: [],
254
+ rejected: [],
255
+ warnings: [],
256
+ certified: [],
257
+ readyToActivate: false
258
+ },
259
+ EvidenceActivateData: {
260
+ requested: 0,
261
+ activated: [],
262
+ failed: [],
263
+ success: true
264
+ }
265
+ };
266
+
267
+ module.exports = {
268
+ OPENAPI_ENVELOPE_DATA_EXAMPLES
269
+ };
@@ -103,6 +103,11 @@ const OPERATION_BINDINGS = Object.freeze({
103
103
  requestBody: jsonRequestBody('WizardConfigRequest', true),
104
104
  successResponse: 'WizardRunResponse'
105
105
  },
106
+ applyIntegrationDefinition: {
107
+ parameters: [SYSTEM_KEY_PARAM],
108
+ requestBody: jsonRequestBody('IntegrationDefinitionApplyRequest', true),
109
+ successResponse: 'IntegrationDefinitionApplyResponse'
110
+ },
106
111
  runRepair: {
107
112
  parameters: [SYSTEM_KEY_PARAM],
108
113
  queryParameters: [
@@ -275,6 +280,46 @@ const OPERATION_BINDINGS = Object.freeze({
275
280
  ready: {
276
281
  successResponse: 'ReadyResponse'
277
282
  },
283
+ getBuilderHelp: {
284
+ queryParameters: [
285
+ {
286
+ name: 'topic',
287
+ in: 'query',
288
+ required: true,
289
+ schema: { $ref: '#/components/schemas/BuilderHelpTopic' },
290
+ description: 'Help topic. Use resourceTypeCatalog for taxonomy keys agents may set on BID datasources.'
291
+ },
292
+ {
293
+ name: 'sectionKey',
294
+ in: 'query',
295
+ required: false,
296
+ schema: { type: 'string' },
297
+ description: 'Required when topic=section.'
298
+ },
299
+ {
300
+ name: 'exampleKey',
301
+ in: 'query',
302
+ required: false,
303
+ schema: { type: 'string' },
304
+ description: 'Required when topic=goldenExample.'
305
+ },
306
+ {
307
+ name: 'category',
308
+ in: 'query',
309
+ required: false,
310
+ schema: { type: 'string' },
311
+ description: 'Optional filter for topic=resourceTypeCatalog.'
312
+ },
313
+ {
314
+ name: 'resourceType',
315
+ in: 'query',
316
+ required: false,
317
+ schema: { type: 'string' },
318
+ description: 'Optional key filter for resourceTypeCatalog or schemaCatalog target.'
319
+ }
320
+ ],
321
+ successResponse: 'BuilderHelpResponse'
322
+ },
278
323
  getEvidenceMetadata: {
279
324
  parameters: [ROLE_KEY_PARAM],
280
325
  successResponse: 'EvidenceAuthoringMetadataResponse'