@aifabrix/builder 2.46.0 → 2.47.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 (175) hide show
  1. package/.npmrc.token +1 -0
  2. package/.temp/jest-protection-convert/run-IFN2nv/.protection/hubspot-companies.json +1 -0
  3. package/.temp/jest-protection-convert/run-IvmKLO/.protection/hubspot-companies.yaml +17 -0
  4. package/.temp/jest-protection-convert/run-SdvblF/.protection/hubspot-companies.json +1 -0
  5. package/.temp/jest-protection-convert/run-b51TsW/.protection/hubspot-companies.json +1 -0
  6. package/.temp/jest-protection-convert/run-fiLmb1/.protection/hubspot-companies.json +1 -0
  7. package/.temp/jest-protection-convert/run-qYGHMU/.protection/hubspot-companies.yaml +17 -0
  8. package/.temp/jest-protection-fixtures/hubspot-Mq5re8/hubspot-companies.yaml +17 -0
  9. package/.temp/jest-protection-fixtures/hubspot-f3u4YL/hubspot-companies.yaml +17 -0
  10. package/.temp/jest-protection-fixtures/hubspot-iQtd1O/hubspot-companies.yaml +17 -0
  11. package/.temp/jest-protection-fixtures/hubspot-mdmz5M/hubspot-companies.yaml +17 -0
  12. package/.temp/jest-protection-fixtures/hubspot-qbKYxQ/hubspot-companies.yaml +17 -0
  13. package/.temp/jest-protection-fixtures/hubspot-yzlJy6/hubspot-companies.yaml +17 -0
  14. package/.temp/validation/summary.txt +5 -0
  15. package/jest.isolated-projects.js +18 -2
  16. package/jest.projects.js +24 -0
  17. package/lib/api/dataplane-health.api.js +19 -7
  18. package/lib/api/lifecycle.api.js +22 -1
  19. package/lib/api/resource-types.api.js +107 -0
  20. package/lib/api/runtime-configuration.api.js +72 -0
  21. package/lib/api/types/resource-types.types.js +45 -0
  22. package/lib/api/user-groups.api.js +9 -9
  23. package/lib/api/users.api.js +8 -8
  24. package/lib/api/wizard.api.js +10 -2
  25. package/lib/app/down.js +58 -26
  26. package/lib/app/index.js +2 -2
  27. package/lib/app/run-resolve-image.js +2 -1
  28. package/lib/app/run-stop-containers.js +113 -0
  29. package/lib/app/run.js +1 -31
  30. package/lib/app/show-display.js +35 -0
  31. package/lib/app/show.js +32 -1
  32. package/lib/build/index.js +17 -5
  33. package/lib/build/miso-controller-npm-sdk-guard.js +25 -0
  34. package/lib/channels/add-channel.js +348 -0
  35. package/lib/channels/channel-artifact-generator.js +141 -0
  36. package/lib/channels/channel-audit.js +101 -0
  37. package/lib/channels/channel-auth-context.js +37 -0
  38. package/lib/channels/channel-credential.js +200 -0
  39. package/lib/channels/channel-display-name.js +64 -0
  40. package/lib/channels/channel-external-system.js +106 -0
  41. package/lib/channels/channel-integration-generator.js +274 -0
  42. package/lib/channels/channel-probe.js +89 -0
  43. package/lib/channels/channel-runtime-resolver.js +152 -0
  44. package/lib/channels/channel-status-display.js +141 -0
  45. package/lib/channels/channel-targets.js +115 -0
  46. package/lib/cli/index.js +16 -4
  47. package/lib/cli/setup-app.js +54 -3
  48. package/lib/cli/setup-infra-up-dataplane-action.js +2 -2
  49. package/lib/cli/setup-infra-up-platform-action.js +2 -1
  50. package/lib/cli/setup-platform.js +1 -1
  51. package/lib/cli/setup-utility-help-after.js +4 -1
  52. package/lib/cli/setup-utility-resolve.js +8 -5
  53. package/lib/commands/app-logs.js +54 -26
  54. package/lib/commands/app.js +41 -0
  55. package/lib/commands/auth-status-dataplane-version.js +97 -61
  56. package/lib/commands/auth-status.js +2 -7
  57. package/lib/commands/channel.js +58 -0
  58. package/lib/commands/datasource.js +1 -1
  59. package/lib/commands/identity-apply-sync.js +49 -8
  60. package/lib/commands/identity-group-cli.js +66 -26
  61. package/lib/commands/identity-membership-role-cache.js +58 -37
  62. package/lib/commands/identity-shared.js +22 -1
  63. package/lib/commands/identity-user-cli.js +80 -34
  64. package/lib/commands/repair-auth-apply.js +30 -4
  65. package/lib/commands/repair-auth-config.js +8 -13
  66. package/lib/commands/repair-datasource-com-v2.js +15 -0
  67. package/lib/commands/repair-datasource-service-contract.js +206 -0
  68. package/lib/commands/repair-datasource.js +53 -18
  69. package/lib/commands/repair-env-template.js +12 -12
  70. package/lib/commands/repair-openapi-sync.js +26 -4
  71. package/lib/commands/repair-steps.js +28 -13
  72. package/lib/commands/repair-system-alignment.js +7 -4
  73. package/lib/commands/resource-type.js +371 -0
  74. package/lib/commands/setup-modes.js +1 -1
  75. package/lib/commands/setup-prompts-platform-mode.js +24 -21
  76. package/lib/commands/test-trust-external.js +39 -90
  77. package/lib/commands/up-common.js +33 -1
  78. package/lib/commands/up-dataplane.js +8 -4
  79. package/lib/commands/upload.js +24 -3
  80. package/lib/commands/verify-trust-command-action.js +4 -1
  81. package/lib/commands/verify-trust-external.js +12 -20
  82. package/lib/core/config-setup-platform-mode.js +3 -3
  83. package/lib/core/setup-platform-mode.js +41 -6
  84. package/lib/datasource/capability/capability-diff-slice.js +2 -2
  85. package/lib/datasource/capability/capability-manifest.js +254 -0
  86. package/lib/datasource/capability/capability-resolve.js +3 -4
  87. package/lib/datasource/capability/copy-operations.js +5 -3
  88. package/lib/datasource/capability/remove-operations.js +2 -1
  89. package/lib/datasource/capability/run-capability-copy.js +32 -4
  90. package/lib/datasource/capability/run-capability-diff.js +3 -3
  91. package/lib/datasource/capability/run-capability-dimension.js +2 -4
  92. package/lib/datasource/capability/run-capability-edit.js +4 -7
  93. package/lib/datasource/capability/run-capability-relate.js +2 -4
  94. package/lib/datasource/capability/run-capability-remove.js +2 -4
  95. package/lib/datasource/capability/validate-capability-slice.js +2 -1
  96. package/lib/datasource/datasource-identifier.js +2 -1
  97. package/lib/datasource/datasource-validate-display.js +1 -1
  98. package/lib/datasource/field-reference-validator.js +24 -3
  99. package/lib/datasource/orphan-profiles-validator.js +98 -0
  100. package/lib/datasource/validate.js +41 -23
  101. package/lib/external-system/download-helpers.js +87 -0
  102. package/lib/external-system/download.js +61 -122
  103. package/lib/external-system/generator.js +1 -59
  104. package/lib/external-system/test.js +10 -15
  105. package/lib/generator/builders.js +11 -1
  106. package/lib/generator/external-controller-manifest.js +5 -2
  107. package/lib/generator/split.js +3 -1
  108. package/lib/generator/wizard.js +1 -28
  109. package/lib/identity/fk-reference.js +65 -0
  110. package/lib/identity/identity-apply-core.js +13 -58
  111. package/lib/identity/identity-apply-phases.js +5 -1
  112. package/lib/identity/identity-display.js +243 -0
  113. package/lib/identity/identity-response-helpers.js +52 -0
  114. package/lib/identity/identity-sync-errors.js +62 -0
  115. package/lib/identity/resolve-user-id.js +129 -0
  116. package/lib/identity/username-default.js +31 -0
  117. package/lib/lifecycle/certification-progress.js +2 -2
  118. package/lib/lifecycle/report-display-trust.js +70 -0
  119. package/lib/lifecycle/report-display.js +14 -13
  120. package/lib/resolvers/datasource-resolver.js +2 -3
  121. package/lib/resolvers/resource-type-file.js +159 -0
  122. package/lib/schema/application-schema.json +16 -0
  123. package/lib/schema/deployment-rules.yaml +2 -1
  124. package/lib/schema/external-datasource.schema.json +372 -58
  125. package/lib/schema/external-system.schema.json +331 -2
  126. package/lib/schema/type/document-storage.json +9 -5
  127. package/lib/utils/app-run-containers.js +25 -2
  128. package/lib/utils/authentication-shape.js +224 -0
  129. package/lib/utils/build-copy.js +36 -5
  130. package/lib/utils/build-resolve-image.js +66 -12
  131. package/lib/utils/celery-companion-apps.js +53 -0
  132. package/lib/utils/cli-utils.js +4 -0
  133. package/lib/utils/compose-celery-worker.js +23 -0
  134. package/lib/utils/compose-generate-docker-compose.js +9 -1
  135. package/lib/utils/configuration-env-resolver.js +36 -0
  136. package/lib/utils/credential-secrets-env-kv.js +216 -0
  137. package/lib/utils/credential-secrets-env.js +52 -262
  138. package/lib/utils/dataplane-resolver.js +4 -115
  139. package/lib/utils/declarative-url-ports.js +24 -1
  140. package/lib/utils/docker-build.js +1 -4
  141. package/lib/utils/external-env-template.js +10 -3
  142. package/lib/utils/external-system-validators.js +8 -2
  143. package/lib/utils/help-builder.js +2 -0
  144. package/lib/utils/paths.js +25 -0
  145. package/lib/utils/platform-controller-url.js +2 -1
  146. package/lib/utils/platform-kv-ref.js +57 -0
  147. package/lib/utils/runtime-configuration-download.js +189 -0
  148. package/lib/utils/runtime-configuration-values.js +119 -0
  149. package/lib/utils/schema-loader.js +19 -4
  150. package/lib/utils/worker-sidecars.js +142 -0
  151. package/lib/validation/external-manifest-validator.js +2 -0
  152. package/lib/validation/runtime-configuration-rules.js +98 -0
  153. package/lib/validation/validate-display-dimensions.js +154 -0
  154. package/lib/validation/validate-display-sections.js +276 -0
  155. package/lib/validation/validate-display-steps.js +67 -0
  156. package/lib/validation/validate-display.js +24 -402
  157. package/package.json +1 -1
  158. package/templates/applications/dataplane/application.yaml +5 -0
  159. package/templates/applications/dataplane/env.template +26 -13
  160. package/templates/applications/dataplane/rbac.yaml +108 -1
  161. package/templates/applications/miso-controller/application.yaml +2 -2
  162. package/templates/applications/miso-controller/env.template +37 -122
  163. package/templates/applications/miso-controller/rbac.yaml +28 -13
  164. package/templates/channels/chatgpt/install.template.md.hbs +49 -0
  165. package/templates/channels/chatgpt/manifest.template.json.hbs +9 -0
  166. package/templates/channels/microsoft-copilot/install.template.md.hbs +49 -0
  167. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +8 -0
  168. package/templates/channels/slack/install.template.md.hbs +49 -0
  169. package/templates/channels/slack/manifest.template.json.hbs +66 -0
  170. package/templates/channels/teams-bot/install.template.md.hbs +49 -0
  171. package/templates/channels/teams-bot/manifest.template.json.hbs +13 -0
  172. package/templates/channels/web-embed/install.template.md.hbs +49 -0
  173. package/templates/channels/web-embed/manifest.template.json.hbs +8 -0
  174. package/templates/python/docker-compose.hbs +56 -0
  175. package/templates/typescript/docker-compose.hbs +52 -0
@@ -1,389 +1,35 @@
1
- const {
2
- headerKeyValue,
3
- metadata,
4
- formatDatasourceListRow,
5
- formatBlockingError,
6
- formatSuccessLine,
7
- formatSuccessParagraph,
8
- successGlyph,
9
- failureGlyph
10
- } = require('../utils/cli-test-layout-chalk');
11
1
  /**
12
2
  * @fileoverview Validation display for `aifabrix validate` (tty-summary: cli-layout.mdc, layout.md).
13
3
  * @author AI Fabrix Team
14
4
  */
15
5
 
6
+ 'use strict';
7
+
16
8
  const path = require('path');
17
9
  const chalk = require('chalk');
18
10
  const logger = require('../utils/logger');
19
- const { loadConfigFile } = require('../utils/config-format');
20
- const { flattenRootDimensionsForDisplay } = require('./dimension-display-helpers');
21
11
  const {
22
- logSectionTitle,
23
- logOkRowRest,
24
- logWarnRow,
25
- logDimLine,
26
- logErrorDetail
27
- } = require('./validate-display-log-helpers');
28
-
29
- /**
30
- * Displays application validation results
31
- * @function displayApplicationValidation
32
- * @param {Object} application - Application validation result
33
- */
34
- function displayApplicationValidation(application) {
35
- if (!application) {
36
- return;
37
- }
38
-
39
- logSectionTitle('Application');
40
- if (application.valid) {
41
- logOkRowRest('Application configuration is valid');
42
- } else {
43
- logger.log(` ${failureGlyph()} ${chalk.red('Application configuration has errors:')}`);
44
- if (application.errors && application.errors.length > 0) {
45
- application.errors.forEach(error => {
46
- logErrorDetail(error);
47
- });
48
- }
49
- }
50
- if (application.warnings && application.warnings.length > 0) {
51
- application.warnings.forEach(warning => {
52
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
53
- });
54
- }
55
- }
56
-
57
- /**
58
- * Extracts dimensions from a datasource file for CLI display.
59
- * Local bindings become `metadata.<field>`; FK bindings become `fk:<fk>→<dimension>...` plus optional `(actor: ...)`.
60
- * @function extractDimensionsFromDatasource
61
- * @param {string} filePath - Path to datasource file
62
- * @returns {Object} Dimensions info { dimensions: Object, dimensionKeys: string[], hasDimensions: boolean }
63
- */
64
- function extractDimensionsFromDatasource(filePath) {
65
- try {
66
- const parsed = loadConfigFile(filePath);
67
-
68
- const rootFlat = flattenRootDimensionsForDisplay(parsed.dimensions);
69
- const abacDimensions = parsed.abac?.dimensions || {};
70
- const allDimensions = { ...rootFlat, ...abacDimensions };
71
- const dimensionKeys = Object.keys(allDimensions);
72
-
73
- return {
74
- dimensions: allDimensions,
75
- dimensionKeys,
76
- hasDimensions: dimensionKeys.length > 0
77
- };
78
- } catch {
79
- return { dimensions: {}, dimensionKeys: [], hasDimensions: false };
80
- }
81
- }
82
-
83
- /**
84
- * Displays external files validation results
85
- * @function displayExternalFilesValidation
86
- * @param {Array} externalFiles - External files validation results
87
- */
88
- function displayExternalFilesValidation(externalFiles) {
89
- if (!externalFiles || externalFiles.length === 0) {
90
- return;
91
- }
92
-
93
- logSectionTitle('External integration files');
94
- externalFiles.forEach(file => {
95
- if (file.valid) {
96
- logger.log(formatDatasourceListRow('ok', file.file, file.type));
97
- } else {
98
- logger.log(formatDatasourceListRow('fail', file.file, file.type));
99
- file.errors.forEach(error => {
100
- logErrorDetail(error);
101
- });
102
- }
103
- if (file.warnings && file.warnings.length > 0) {
104
- file.warnings.forEach(warning => {
105
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
106
- });
107
- }
108
- });
109
- }
110
-
111
- /**
112
- * Displays Dimensions (ABAC) validation results for datasources
113
- * @function displayDimensionsValidation
114
- * @param {Array} externalFiles - External files validation results
115
- * @returns {Array} Warnings to add to aggregated warnings
116
- */
117
- function displayDimensionsValidation(externalFiles) {
118
- if (!externalFiles || externalFiles.length === 0) {
119
- return [];
120
- }
121
-
122
- const datasourceFiles = externalFiles.filter(f =>
123
- f.type === 'datasource' || f.type === 'external-datasource'
124
- );
125
-
126
- if (datasourceFiles.length === 0) {
127
- return [];
128
- }
129
-
130
- logSectionTitle('Dimensions (ABAC)');
131
-
132
- const warnings = [];
133
- let anyDatasourceHasDimensions = false;
134
-
135
- datasourceFiles.forEach(file => {
136
- const dimensionsInfo = extractDimensionsFromDatasource(file.path);
137
-
138
- if (dimensionsInfo.hasDimensions) {
139
- anyDatasourceHasDimensions = true;
140
- logger.log(formatDatasourceListRow('ok', file.file, file.type));
141
- dimensionsInfo.dimensionKeys.forEach(key => {
142
- const mapping = dimensionsInfo.dimensions[key];
143
- logDimLine(`${key} → ${mapping}`);
144
- });
145
- } else {
146
- logWarnRow(`${file.file} — no dimensions configured`);
147
- warnings.push(`${file.file} - no dimensions configured, ABAC filtering disabled`);
148
- }
149
- });
150
-
151
- if (!anyDatasourceHasDimensions) {
152
- logWarnRow('No dimensions configured — ABAC filtering disabled for all datasources');
153
- }
154
-
155
- return warnings;
156
- }
157
-
158
- /**
159
- * Displays RBAC validation results
160
- * @function displayRbacValidation
161
- * @param {Object} rbac - RBAC validation result
162
- */
163
- function displayRbacValidation(rbac) {
164
- if (!rbac) {
165
- return;
166
- }
167
-
168
- logSectionTitle('RBAC configuration');
169
- if (rbac.valid) {
170
- logOkRowRest('RBAC configuration is valid');
171
- } else {
172
- logger.log(` ${failureGlyph()} ${chalk.red('RBAC configuration has errors:')}`);
173
- rbac.errors.forEach(error => {
174
- logErrorDetail(error);
175
- });
176
- }
177
- if (rbac.warnings && rbac.warnings.length > 0) {
178
- rbac.warnings.forEach(warning => {
179
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
180
- });
181
- }
182
- }
183
-
184
- /**
185
- * Displays file validation results (for direct file validation)
186
- * @function displayFileValidation
187
- * @param {Object} result - Validation result
188
- */
189
- function displayFileValidation(result) {
190
- if (!result.file) {
191
- return;
192
- }
193
-
194
- logSectionTitle('File');
195
- logger.log(` ${headerKeyValue('Path:', result.file)}`);
196
- logger.log(` ${headerKeyValue('Type:', String(result.type))}`);
197
- if (result.valid) {
198
- logOkRowRest('File is valid');
199
- } else {
200
- logger.log(` ${failureGlyph()} ${chalk.red('File has errors:')}`);
201
- result.errors.forEach(error => {
202
- logErrorDetail(error);
203
- });
204
- }
205
- if (result.warnings && result.warnings.length > 0) {
206
- result.warnings.forEach(warning => {
207
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
208
- });
209
- }
210
- }
211
-
212
- /**
213
- * Displays aggregated warnings
214
- * @function displayAggregatedWarnings
215
- * @param {Array} warnings - Array of warning messages
216
- */
217
- function displayAggregatedWarnings(warnings) {
218
- if (!warnings || warnings.length === 0) {
219
- return;
220
- }
221
-
222
- logSectionTitle('Warnings');
223
- warnings.forEach(warning => {
224
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
225
- });
226
- }
227
-
228
- /**
229
- * Displays application validation step
230
- * @function displayApplicationStep
231
- * @param {Object} application - Application validation result
232
- * @returns {void}
233
- */
234
- function displayApplicationStep(application) {
235
- logSectionTitle('Application');
236
- if (application.valid) {
237
- logOkRowRest('Application configuration is valid');
238
- } else {
239
- logger.log(` ${failureGlyph()} ${chalk.red('Application configuration has errors:')}`);
240
- application.errors.forEach(error => {
241
- logErrorDetail(error);
242
- });
243
- }
244
- if (application.warnings && application.warnings.length > 0) {
245
- application.warnings.forEach(warning => {
246
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
247
- });
248
- }
249
- }
250
-
251
- /**
252
- * Displays external integration files step
253
- * @function displayComponentsStep
254
- * @param {Object} components - Components validation result
255
- * @returns {void}
256
- */
257
- function displayComponentsStep(components) {
258
- const hasFiles = components.files && components.files.length > 0;
259
- const hasErrors = components.errors && components.errors.length > 0;
260
- if (!hasFiles && !hasErrors) {
261
- return;
262
- }
263
-
264
- logSectionTitle('External integration files');
265
- if (hasFiles) {
266
- components.files.forEach(file => {
267
- if (file.valid) {
268
- logger.log(formatDatasourceListRow('ok', file.file, file.type));
269
- } else {
270
- logger.log(formatDatasourceListRow('fail', file.file, file.type));
271
- }
272
- });
273
- }
274
- if (hasErrors) {
275
- components.errors.forEach(error => {
276
- logger.log(formatBlockingError(error));
277
- });
278
- }
279
- }
280
-
281
- /**
282
- * Displays dimensions validation for datasources
283
- * @function displayDimensionsStep
284
- * @param {Array} datasourceFiles - Datasource files
285
- * @returns {void}
286
- */
287
- function displayDimensionsStep(datasourceFiles) {
288
- if (datasourceFiles.length === 0) {
289
- return;
290
- }
291
-
292
- logSectionTitle('Dimensions (ABAC)');
293
- datasourceFiles.forEach(file => {
294
- try {
295
- const dimensionsInfo = extractDimensionsFromDatasource(file.path || file.file);
296
- if (dimensionsInfo.hasDimensions) {
297
- logger.log(formatDatasourceListRow('ok', file.file, file.type));
298
- dimensionsInfo.dimensionKeys.forEach(key => {
299
- const mapping = dimensionsInfo.dimensions[key];
300
- logDimLine(`${key} → ${mapping}`);
301
- });
302
- } else {
303
- logWarnRow(`${file.file} — no dimensions configured`);
304
- }
305
- } catch {
306
- // Skip if file path not available
307
- }
308
- });
309
- }
310
-
311
- /**
312
- * Displays deployment manifest step
313
- * @function displayManifestStep
314
- * @param {Object} manifest - Manifest validation result
315
- * @param {Array} componentFiles - Component files
316
- * @returns {void}
317
- */
318
- function displayManifestStep(manifest, componentFiles) {
319
- logSectionTitle('Deployment manifest');
320
- if (manifest.skipped) {
321
- logger.log(` ${chalk.gray('⏭')} ${chalk.white('Skipped (fix errors above first)')}`);
322
- } else if (manifest.valid) {
323
- logOkRowRest('Full deployment manifest is valid');
324
- if (componentFiles) {
325
- const datasourceFiles = componentFiles.filter(f => f.type === 'datasource' || f.type === 'external-datasource');
326
- logger.log(` ${successGlyph()} ${chalk.white('System configuration valid')}`);
327
- logger.log(` ${successGlyph()} ${chalk.white(`${datasourceFiles.length} datasource(s) valid`)}`);
328
- logger.log(` ${successGlyph()} ${chalk.white('Schema validation passed')}`);
329
- }
330
- } else {
331
- logger.log(` ${failureGlyph()} ${chalk.red('Full deployment manifest validation failed:')}`);
332
- const errs = manifest.errors && manifest.errors.length > 0 ? manifest.errors : [];
333
- if (errs.length > 0) {
334
- errs.forEach(error => {
335
- const msg = typeof error === 'string' ? error : String(error);
336
- logErrorDetail(msg);
337
- });
338
- } else {
339
- logErrorDetail('No error details available (check schema and manifest structure).');
340
- }
341
- }
342
- if (manifest.warnings && manifest.warnings.length > 0) {
343
- manifest.warnings.forEach(warning => {
344
- logger.log(` ${chalk.yellow('⚠')} ${chalk.white(warning)}`);
345
- });
346
- }
347
- }
348
-
349
- /**
350
- * Displays step-by-step validation results for external systems
351
- * @function displayStepByStepValidation
352
- * @param {Object} result - Validation result with steps
353
- */
354
- function displayStepByStepValidation(result) {
355
- if (result.valid) {
356
- logger.log(formatSuccessParagraph('Validation passed!'));
357
- } else {
358
- logger.log(`\n${formatBlockingError('Validation failed!')}`);
359
- }
360
-
361
- displayApplicationStep(result.steps.application);
362
-
363
- if (!result.steps.components.valid || (result.steps.components.files && result.steps.components.files.length > 0)) {
364
- displayComponentsStep(result.steps.components);
365
- }
366
-
367
- const datasourceFiles = result.steps.components.files?.filter(f =>
368
- f.type === 'datasource' || f.type === 'external-datasource'
369
- ) || [];
370
- displayDimensionsStep(datasourceFiles);
371
-
372
- if (result.rbac) {
373
- displayRbacValidation(result.rbac);
374
- }
375
-
376
- displayManifestStep(result.steps.manifest, result.steps.components.files);
377
-
378
- if (result.warnings && result.warnings.length > 0) {
379
- displayAggregatedWarnings(result.warnings);
380
- }
381
-
382
- displayOverallStatus(result);
383
- if (result.appPath) {
384
- logger.log(`\n${metadata(path.resolve(result.appPath))}`);
385
- }
386
- }
12
+ headerKeyValue,
13
+ metadata,
14
+ formatBlockingError,
15
+ formatSuccessLine,
16
+ formatSuccessParagraph,
17
+ failureGlyph
18
+ } = require('../utils/cli-test-layout-chalk');
19
+ const { logSectionTitle } = require('./validate-display-log-helpers');
20
+ const {
21
+ displayApplicationValidation,
22
+ displayExternalFilesValidation,
23
+ displayRbacValidation,
24
+ displayFileValidation,
25
+ displayAggregatedWarnings,
26
+ displayOverallStatus
27
+ } = require('./validate-display-sections');
28
+ const {
29
+ displayDimensionsValidation,
30
+ extractDimensionsFromDatasource
31
+ } = require('./validate-display-dimensions');
32
+ const { displayStepByStepValidation } = require('./validate-display-steps');
387
33
 
388
34
  /**
389
35
  * Displays batch validation results (per-app blocks then summary).
@@ -418,31 +64,6 @@ function displayBatchValidationResults(batchResult) {
418
64
  }
419
65
  }
420
66
 
421
- /**
422
- * Displays overall validation status
423
- * @param {Object} result - Validation result
424
- */
425
- function displayOverallStatus(result) {
426
- let hasErrors = result.errors && result.errors.length > 0;
427
- if (!hasErrors && result.steps) {
428
- const stepErrors = [result.steps.application, result.steps.components, result.steps.manifest]
429
- .filter(Boolean)
430
- .some(s => s.errors && s.errors.length > 0);
431
- if (stepErrors) {
432
- hasErrors = true;
433
- }
434
- }
435
- const hasWarnings = result.warnings && result.warnings.length > 0;
436
- logger.log('');
437
- if (hasErrors) {
438
- logger.log(headerKeyValue('Overall:', chalk.red('Failed')));
439
- } else if (hasWarnings) {
440
- logger.log(headerKeyValue('Overall:', chalk.yellow('Passed with warnings')));
441
- } else {
442
- logger.log(headerKeyValue('Overall:', chalk.green('Passed')));
443
- }
444
- }
445
-
446
67
  /**
447
68
  * Displays validation results in a user-friendly format
448
69
  *
@@ -481,6 +102,7 @@ function displayValidationResults(result) {
481
102
  logger.log(`\n${metadata(path.resolve(result.appPath))}`);
482
103
  }
483
104
  }
105
+
484
106
  module.exports = {
485
107
  displayValidationResults,
486
108
  displayBatchValidationResults,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifabrix/builder",
3
- "version": "2.46.0",
3
+ "version": "2.47.0",
4
4
  "description": "AI Fabrix Local Fabric & Deployment SDK",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -68,6 +68,11 @@ build:
68
68
  reloadStart: WATCHFILES_FORCE_POLLING=1 uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001} --reload --reload-dir /app/app
69
69
  # Pulled-image local compose (no bind-mount): drives `command` in generated docker-compose. Override for non-standard images (e.g. stub ACR tags).
70
70
  imageRun: exec python -m uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001}
71
+ # Image policy (442.0): explicit Dockerfile COPY; worker/beat via python -m app.core.*
72
+ # integration/ in image: <systemKey>-deploy.json + application.json|yaml only (no test-*, wizard-configs).
73
+ worker: true
74
+ imageRunWorker: exec python -m app.core.celery_worker_main
75
+ imageRunBeat: exec python -m app.core.celery_beat_main
71
76
 
72
77
  # =============================================================================
73
78
  # Portal Input Configuration (Deployment Wizard)
@@ -20,12 +20,21 @@ LOG_FORMAT=json
20
20
  # Docker default (no volume): use LOG_FILE_PATH=/app/logs/app.log (directory created in image).
21
21
  # Production with persistent logs: use /mnt/data/logs/app.log and mount a volume at /mnt/data.
22
22
  LOG_FILE_PATH=/mnt/data/logs/app.log
23
- # If true, run without Redis/Celery (single process)
23
+ # If true, run without Redis/Celery (single process). Set false on API/worker/beat in production.
24
24
  LOCAL_MODE=true
25
25
 
26
+ # Celery worker process tuning (dataplane-worker container; optional overrides)
27
+ # CELERY_WORKER_QUEUES=external_data,document_sync,document_processing,audit
28
+ # CELERY_WORKER_CONCURRENCY=2
29
+ # CELERY_LOG_LEVEL=info
30
+
26
31
  # When API_KEY is set, a matching Bearer token bypasses OAuth2 validation
27
32
  # Same kv:// as miso-controller API_KEY so pipeline Bearer bypass uses one secrets.local entry
28
33
  API_KEY=kv://miso-controller-secrets-apiKeyVault
34
+ # Comma-separated realm roles attached to API_KEY bypass (JWT realm_access.roles). Default: operator.
35
+ # Add integration RBAC role keys from published manifests when manual tests need selector/MCP access, e.g.:
36
+ # API_KEY_BYPASS_ROLES=operator,<role-from-manifest-rbac>
37
+ # API_KEY_BYPASS_ROLES=operator
29
38
 
30
39
  # API Configuration
31
40
  API_V1_STR=/api/v1
@@ -108,6 +117,7 @@ ABAC_POLICY_PARSE_CACHE_MAX_ENTRIES=2048
108
117
  # =============================================================================
109
118
 
110
119
  # MISO Application Client Credentials (per application)
120
+ # Backend-only: never expose MISO_CLIENTSECRET to the Vite frontend (use VITE_* in app-ui).
111
121
  MISO_CLIENTID=kv://dataplane-client-idKeyVault
112
122
  MISO_CLIENTSECRET=kv://dataplane-client-secretKeyVault
113
123
 
@@ -125,24 +135,17 @@ KEYCLOAK_REALM=aifabrix
125
135
  MISO_WEB_SERVER_URL=url://miso-controller-public
126
136
  # Internal: server-to-controller API calls (Docker: service:port; local: host:port — no front-door path).
127
137
  MISO_CONTROLLER_URL=url://miso-controller-internal
138
+ # Browser logout page on miso-controller (path relative to MISO_WEB_SERVER_URL; not dataplane /login).
139
+ MISO_LOGOUT_URL=/logout
128
140
 
129
141
  # Environment key sent to miso-controller (e.g. environmentKey on RBAC/register) when not supplied in the payload.
130
142
  # Set MISO_PIPELINE_ENV_KEY=dev when the controller installation uses dev (e.g. MISO_CLIENTID=miso-controller-dev-dataplane).
131
143
  # If unset, derived from MISO_CLIENTID (e.g. dev from miso-controller-dev-dataplane).
132
144
  MISO_PIPELINE_ENV_KEY=
133
145
 
134
- # =============================================================================
135
- # AI/LLM CONFIGURATION
136
- # =============================================================================
137
-
138
- # OpenAI Configuration
139
- OPENAI_API_KEY=kv://secrets-openaiApiKeyVault
140
-
141
- # Azure OpenAI Configuration
142
- AZURE_OPENAI_ENDPOINT=kv://azure-openaiapi-urlKeyVault
143
- AZURE_OPENAI_API_KEY=kv://secrets-azureOpenaiApiKeyVault
144
- AZURE_OPENAI_API_VERSION=2024-02-15-preview
145
- AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o
146
+ # LLM: chat/embed route through governed enterprise-llm only. Provider credentials
147
+ # live on LLM provider external systems (integration/openai, azure-openai, ollama).
148
+ AI_VALIDATION_LLM_MODEL=gpt-4o-mini
146
149
 
147
150
  # =============================================================================
148
151
  # AUDIT CONFIGURATION
@@ -179,6 +182,11 @@ AUDIT_ASYNC_SHADOW_ENQUEUE=false
179
182
  # Set true for local dev policy CRUD; pair with VITE_POLICY_MANAGEMENT_ENABLED=true in app-ui.
180
183
  POLICY_MANAGEMENT_API_ENABLED=false
181
184
 
185
+ # Developer Access tab help links (optional; empty hides banner links in UI).
186
+ # VITE_DEVELOPER_GUIDE_URL=
187
+ # VITE_API_EXAMPLES_URL=
188
+ # VITE_MCP_INTEGRATION_GUIDE_URL=
189
+
182
190
  # First-party HTTP internal SpecFile (398.2 / plan 397). When true, lifespan upserts
183
191
  # internal:dataplane-first-party-http from the live COM-merged OpenAPI schema.
184
192
  FIRST_PARTY_HTTP_INTERNAL_SPEC_SYNC_ON_STARTUP=false
@@ -199,6 +207,11 @@ OPENTELEMETRY_ENDPOINT=
199
207
  # INTEGRATION CERTIFICATE SIGNING (RS256 PEM)
200
208
  # =============================================================================
201
209
  # Read by PemRsaCertificateSigner.from_environment in app/validation/certificates/signer.py.
210
+ # Workforce execute signing (437.4). Falls back to CERTIFICATE_* keys, then ephemeral dev RSA.
211
+ DATAPLANE_PRIVATE_KEY=
212
+ DATAPLANE_PUBLIC_KEY=
213
+ DATAPLANE_PUBLIC_KEY_ID=
214
+
202
215
  # When CERTIFICATE_PRIVATE_KEY and CERTIFICATE_PUBLIC_KEY are both set (non-empty PEM), the
203
216
  # engine uses RS256. When unset and LOCAL_MODE=true, a process-local ephemeral RSA keypair is used
204
217
  # (still RS256, with publicKey + publicKeyFingerprint on issued certs). Non-local requires PEM keys.
@@ -35,6 +35,16 @@ roles:
35
35
  description: "Read-only access to monitoring, logs, and compliance reports"
36
36
  groups: ["AI-Fabrix-Observers"]
37
37
 
38
+ - name: "AI Fabrix AI Trust Operator"
39
+ value: "aifabrix-ai-trust-operator"
40
+ description: "Run AI Trust access evaluation and explain visibility for governed users"
41
+ groups: ["AI-Fabrix-AI-Trust-Operators"]
42
+
43
+ - name: "AI Fabrix External System Discoverer"
44
+ value: "aifabrix-external-system-discoverer"
45
+ description: "Discover business context for external systems via REST and MCP"
46
+ groups: ["AI-Fabrix-External-System-Discoverers"]
47
+
38
48
  permissions:
39
49
  # Credential management
40
50
  - name: "credential:create"
@@ -281,9 +291,29 @@ permissions:
281
291
  roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-deployment-admin", "aifabrix-compliance-admin", "aifabrix-developer", "aifabrix-observer"]
282
292
  description: "Search records"
283
293
 
294
+ - name: "external-system:discover"
295
+ roles:
296
+ [
297
+ "aifabrix-platform-admin",
298
+ "aifabrix-security-admin",
299
+ "aifabrix-developer",
300
+ "aifabrix-external-system-discoverer",
301
+ ]
302
+ description: "Discover business context (semantics, exposure, enabled governance, tools, validation state) for external systems"
303
+
284
304
  - name: "governance:evaluate"
285
305
  roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-developer"]
286
306
  description: "Run governance scenario acceptance (subject impersonation for ABAC proof)"
307
+
308
+ - name: "ai-trust:evaluate"
309
+ roles:
310
+ [
311
+ "aifabrix-platform-admin",
312
+ "aifabrix-security-admin",
313
+ "aifabrix-developer",
314
+ "aifabrix-ai-trust-operator",
315
+ ]
316
+ description: "Use AI Trust workspace (list systems, sessions, evaluate access, explain visibility)"
287
317
 
288
318
  # IDE simulation operations
289
319
  - name: "dataplane:abac-simulate"
@@ -292,4 +322,81 @@ permissions:
292
322
 
293
323
  - name: "dataplane:rbac-simulate"
294
324
  roles: ["aifabrix-platform-admin", "aifabrix-security-admin", "aifabrix-developer"]
295
- description: "Simulate RBAC policy evaluation in IDE"
325
+ description: "Simulate RBAC policy evaluation in IDE"
326
+
327
+ # Digital Worker activation (438.1)
328
+ - name: "worker:read"
329
+ roles:
330
+ [
331
+ "aifabrix-platform-admin",
332
+ "aifabrix-security-admin",
333
+ "aifabrix-developer",
334
+ "aifabrix-ai-trust-operator",
335
+ ]
336
+ description: "List activatable Digital Workers and user activations"
337
+
338
+ - name: "worker:activate"
339
+ roles:
340
+ [
341
+ "aifabrix-platform-admin",
342
+ "aifabrix-developer",
343
+ "aifabrix-ai-trust-operator",
344
+ ]
345
+ description: "Activate a generated Digital Worker for the current user"
346
+
347
+ - name: "worker:update"
348
+ roles:
349
+ [
350
+ "aifabrix-platform-admin",
351
+ "aifabrix-developer",
352
+ "aifabrix-ai-trust-operator",
353
+ ]
354
+ description: "Update assistantName or preferredChannel on a user activation"
355
+
356
+ - name: "worker:archive"
357
+ roles:
358
+ [
359
+ "aifabrix-platform-admin",
360
+ "aifabrix-developer",
361
+ "aifabrix-ai-trust-operator",
362
+ ]
363
+ description: "Archive a user Digital Worker activation"
364
+
365
+ - name: "worker:approve"
366
+ roles:
367
+ [
368
+ "aifabrix-platform-admin",
369
+ "aifabrix-security-admin",
370
+ "aifabrix-ai-trust-operator",
371
+ ]
372
+ description: "Approve or reject pending worker tasks"
373
+
374
+ - name: "worker:manager-read"
375
+ roles:
376
+ [
377
+ "aifabrix-platform-admin",
378
+ "aifabrix-security-admin",
379
+ "aifabrix-ai-trust-operator",
380
+ ]
381
+ description: "Read manager-scoped workforce impact aggregates (no task detail)"
382
+
383
+ # Workforce subscriptions (436.11 / 438.6)
384
+ - name: "subscription:read"
385
+ roles:
386
+ [
387
+ "aifabrix-platform-admin",
388
+ "aifabrix-security-admin",
389
+ "aifabrix-developer",
390
+ "aifabrix-deployment-admin",
391
+ "aifabrix-observer",
392
+ ]
393
+ description: "List workforce subscriptions and execution audit rows"
394
+
395
+ - name: "subscription:run"
396
+ roles:
397
+ [
398
+ "aifabrix-platform-admin",
399
+ "aifabrix-developer",
400
+ "aifabrix-deployment-admin",
401
+ ]
402
+ description: "Manually run a workforce subscription task"