@aifabrix/builder 2.50.0 → 2.51.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 (236) hide show
  1. package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +374 -0
  2. package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
  3. package/integration/hubspot-test/create-hubspot.js +1 -16
  4. package/jest.isolated-projects.js +77 -1
  5. package/jest.projects.js +5 -426
  6. package/lib/api/assistants.api.js +67 -0
  7. package/lib/api/datasources-extended.api.js +6 -6
  8. package/lib/api/evidence-authoring-helpers.js +267 -0
  9. package/lib/api/evidence-authoring.api.js +337 -0
  10. package/lib/api/evidence-kinds.api.js +128 -0
  11. package/lib/api/evidence.api.js +57 -1
  12. package/lib/api/index.js +24 -7
  13. package/lib/api/pipeline.api.js +47 -3
  14. package/lib/api/records-bulk.api.js +28 -3
  15. package/lib/api/resource-types.api.js +4 -4
  16. package/lib/api/roles.api.js +121 -0
  17. package/lib/api/types/evidence-kinds.types.js +42 -0
  18. package/lib/api/types/evidence.types.js +156 -8
  19. package/lib/api/types/roles.types.js +36 -0
  20. package/lib/api/work.api.js +283 -0
  21. package/lib/app/certification-verify-rows.js +1 -1
  22. package/lib/app/run-deploy-job.js +108 -0
  23. package/lib/app/run-helpers.js +10 -3
  24. package/lib/app/run.js +8 -0
  25. package/lib/app/show.js +2 -2
  26. package/lib/certification/merge-certification-from-artifact.js +1 -1
  27. package/lib/channels/add-channel.js +54 -23
  28. package/lib/channels/approval-guides/chatgpt.js +8 -7
  29. package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
  30. package/lib/channels/channel-artifact-generator.js +16 -3
  31. package/lib/channels/channel-credential.js +3 -1
  32. package/lib/channels/channel-probe-evidence.js +79 -0
  33. package/lib/channels/channel-probe.js +265 -13
  34. package/lib/channels/channel-runtime-resolver.js +120 -29
  35. package/lib/channels/channel-status-display.js +44 -0
  36. package/lib/channels/channel-targets.js +7 -0
  37. package/lib/channels/chatgpt-runtime-contract.js +29 -0
  38. package/lib/channels/microsoft-copilot-package.js +280 -0
  39. package/lib/channels/runtime-tool-catalog.js +165 -0
  40. package/lib/cli/index.js +6 -0
  41. package/lib/cli/setup-app.js +26 -5
  42. package/lib/cli/setup-dev.js +23 -7
  43. package/lib/cli/setup-external-system-help.js +8 -2
  44. package/lib/cli/setup-external-system.js +12 -0
  45. package/lib/cli/setup-utility-help-after.js +12 -0
  46. package/lib/cli/setup-utility-validate.js +41 -2
  47. package/lib/commands/app-test.js +2 -14
  48. package/lib/commands/datasource-load-export-cli.js +6 -1
  49. package/lib/commands/deploy-gate-failure-details.js +23 -0
  50. package/lib/commands/deploy-gate-orchestrator.js +64 -18
  51. package/lib/commands/dev-cli-handlers.js +6 -3
  52. package/lib/commands/dev-down.js +2 -6
  53. package/lib/commands/dev-init.js +7 -109
  54. package/lib/commands/dev-refresh.js +197 -0
  55. package/lib/commands/evidence-kind.js +478 -0
  56. package/lib/commands/governance-command-action.js +4 -2
  57. package/lib/commands/governance-generate-external.js +56 -21
  58. package/lib/commands/lifecycle-external.js +10 -4
  59. package/lib/commands/repair-datasource-apply.js +10 -1
  60. package/lib/commands/repair-datasource-run.js +4 -2
  61. package/lib/commands/repair-datasource-test-payload.js +80 -19
  62. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
  63. package/lib/commands/repair-internal.js +9 -1
  64. package/lib/commands/repair-openapi-export.js +1 -1
  65. package/lib/commands/repair-openapi-sync.js +43 -18
  66. package/lib/commands/resource-type.js +101 -18
  67. package/lib/commands/role-assistant.js +313 -0
  68. package/lib/commands/role.js +452 -0
  69. package/lib/commands/setup.js +1 -1
  70. package/lib/commands/upload-data-sync-finalize.js +5 -4
  71. package/lib/commands/upload-sidecar-followups.js +144 -47
  72. package/lib/commands/upload.js +43 -6
  73. package/lib/commands/validate-json.js +230 -0
  74. package/lib/commands/verify-governance-combined-external.js +73 -9
  75. package/lib/commands/verify-governance-db.js +80 -25
  76. package/lib/commands/verify-governance-external.js +29 -5
  77. package/lib/commands/verify-operations-step-plan.js +78 -40
  78. package/lib/commands/wizard-core-helpers.js +7 -3
  79. package/lib/commands/wizard-core.js +78 -9
  80. package/lib/core/audit-logger.js +1 -1
  81. package/lib/core/secrets-load.js +1 -3
  82. package/lib/datasource/bulk-loader-run-batches.js +4 -2
  83. package/lib/datasource/bulk-loader-service.js +5 -1
  84. package/lib/datasource/capability/relate-operations.js +1 -1
  85. package/lib/datasource/datasource-validate-summary.js +2 -2
  86. package/lib/datasource/validate.js +13 -6
  87. package/lib/external-system/deploy-helpers.js +35 -1
  88. package/lib/external-system/deploy.js +23 -10
  89. package/lib/external-system/download-helpers.js +111 -2
  90. package/lib/external-system/download-role-assistant.js +55 -0
  91. package/lib/external-system/download.js +45 -26
  92. package/lib/external-system/test-helpers.js +1 -1
  93. package/lib/external-system/test.js +39 -3
  94. package/lib/generator/builders.js +3 -0
  95. package/lib/generator/helpers.js +13 -5
  96. package/lib/generator/split-variables.js +9 -3
  97. package/lib/generator/wizard.js +51 -4
  98. package/lib/infrastructure/helpers-docker-check.js +6 -0
  99. package/lib/infrastructure/helpers.js +1 -1
  100. package/lib/lifecycle/access-control-abac.js +121 -0
  101. package/lib/lifecycle/lifecycle-governance-options.js +4 -1
  102. package/lib/lifecycle/product-model.js +3 -2
  103. package/lib/lifecycle/report-display.js +14 -2
  104. package/lib/programmatic/auth-config.js +3 -2
  105. package/lib/programmatic/bearer-auth.js +1 -1
  106. package/lib/programmatic/capability-registry.js +20 -1
  107. package/lib/programmatic/command-options.js +1 -0
  108. package/lib/programmatic/enterprise-mcp-client.js +18 -2
  109. package/lib/programmatic/index.js +4 -0
  110. package/lib/programmatic/manifest-patch-section.js +48 -9
  111. package/lib/programmatic/manifest-section-registry-data.js +3 -2
  112. package/lib/programmatic/manifest-section-registry.js +18 -1
  113. package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
  114. package/lib/programmatic/openapi-component-schemas.js +16 -1
  115. package/lib/programmatic/openapi-description-enricher.js +3 -1
  116. package/lib/programmatic/openapi-descriptions.js +55 -5
  117. package/lib/programmatic/openapi-evidence-schemas.js +161 -0
  118. package/lib/programmatic/openapi-manifest-schemas.js +6 -2
  119. package/lib/programmatic/openapi-operation-bindings.js +99 -0
  120. package/lib/programmatic/openapi-request-schemas.js +36 -1
  121. package/lib/programmatic/openapi-result-schemas.js +29 -12
  122. package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
  123. package/lib/programmatic/openapi-schema-descriptions-core.js +6 -3
  124. package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
  125. package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
  126. package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
  127. package/lib/programmatic/openapi-schema-helpers.js +16 -1
  128. package/lib/programmatic/openapi-spec.js +48 -29
  129. package/lib/programmatic/orchestration-openapi-meta.js +5 -0
  130. package/lib/programmatic/request-timeout.js +3 -0
  131. package/lib/programmatic/route-handler-map.js +89 -2
  132. package/lib/programmatic/run-certify.js +15 -2
  133. package/lib/programmatic/run-deploy.js +74 -0
  134. package/lib/programmatic/run-evidence-authoring.js +80 -0
  135. package/lib/programmatic/run-protection.js +124 -0
  136. package/lib/programmatic/run-repository-emcp.js +11 -3
  137. package/lib/programmatic/run-template-workspace.js +42 -2
  138. package/lib/programmatic/workspace-context.js +6 -0
  139. package/lib/protection/auth-context.js +48 -6
  140. package/lib/protection/paths.js +22 -0
  141. package/lib/protection/run-protection-create-helpers.js +22 -1
  142. package/lib/protection/run-protection-create.js +1 -1
  143. package/lib/protection/sync-after-upload.js +1 -1
  144. package/lib/resolvers/evidence-kind-file.js +230 -0
  145. package/lib/resolvers/resource-type-file.js +36 -1
  146. package/lib/resolvers/role-file.js +227 -0
  147. package/lib/role-assistant/evidence-sync.js +450 -0
  148. package/lib/role-assistant/github-workflow.js +96 -0
  149. package/lib/role-assistant/knowledge-sync.js +465 -0
  150. package/lib/role-assistant/settings.js +126 -0
  151. package/lib/role-assistant/test-cases-evaluate.js +170 -0
  152. package/lib/role-assistant/test-cases-honesty.js +184 -0
  153. package/lib/role-assistant/test-cases.js +364 -0
  154. package/lib/role-assistant/test-runner-workhub-answers.js +203 -0
  155. package/lib/role-assistant/test-runner-workhub.js +385 -0
  156. package/lib/role-assistant/test-runner.js +500 -0
  157. package/lib/schema/application-schema.json +36 -2
  158. package/lib/schema/deployment-rules.yaml +1 -0
  159. package/lib/schema/external-datasource.schema.json +121 -4
  160. package/lib/schema/external-system.schema.json +20 -6
  161. package/lib/schema/infra.parameter.yaml +45 -1
  162. package/lib/schema/role-assistant-settings.schema.json +108 -0
  163. package/lib/schema/type/credential-field-registry.json +19 -3
  164. package/lib/utils/api.js +52 -21
  165. package/lib/utils/app-path-resolve.js +72 -24
  166. package/lib/utils/app-register-config.js +4 -3
  167. package/lib/utils/authentication-shape.js +3 -1
  168. package/lib/utils/cli-sync-options.js +59 -3
  169. package/lib/utils/cli-utils.js +11 -3
  170. package/lib/utils/deployment-validation.js +28 -3
  171. package/lib/utils/dev-ca-install.js +5 -6
  172. package/lib/utils/dev-config.js +2 -2
  173. package/lib/utils/dev-list-sort.js +145 -0
  174. package/lib/utils/dev-platform-tls.js +0 -63
  175. package/lib/utils/docker-build.js +46 -27
  176. package/lib/utils/docker-daemon-tls-ca.js +1 -1
  177. package/lib/utils/docker-exec.js +91 -6
  178. package/lib/utils/docker-run-ephemeral.js +55 -0
  179. package/lib/utils/enterprise-knowledge-paths.js +29 -12
  180. package/lib/utils/env-copy-keycloak.js +196 -0
  181. package/lib/utils/env-copy.js +35 -4
  182. package/lib/utils/error-formatters/error-parser.js +0 -3
  183. package/lib/utils/external-env-template.js +1 -1
  184. package/lib/utils/external-system-readiness-compact-blocks.js +28 -1
  185. package/lib/utils/external-system-readiness-compact-display.js +3 -0
  186. package/lib/utils/health-check-request.js +2 -3
  187. package/lib/utils/help-builder.js +4 -0
  188. package/lib/utils/image-name.js +22 -4
  189. package/lib/utils/logger.js +37 -4
  190. package/lib/utils/manifest-source-emit.js +1 -1
  191. package/lib/utils/paths.js +98 -26
  192. package/lib/utils/pipeline-upload-auth-retry.js +19 -3
  193. package/lib/utils/postgres-platform-bootstrap.js +24 -17
  194. package/lib/utils/postgres-wipe.js +5 -2
  195. package/lib/utils/remote-dev-auth.js +39 -4
  196. package/lib/utils/resolve-docker-image-ref.js +36 -6
  197. package/lib/utils/role-assistant-paths.js +98 -0
  198. package/lib/utils/schema-loader.js +41 -0
  199. package/lib/utils/schema-resolver.js +36 -4
  200. package/lib/utils/token-manager.js +47 -22
  201. package/lib/utils/upload-sync-options.js +17 -3
  202. package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
  203. package/lib/validation/external-manifest-validator.js +31 -8
  204. package/lib/validation/openapi-contract-surface-validator.js +4 -0
  205. package/lib/validation/validate-external-file.js +8 -1
  206. package/lib/validation/validator.js +6 -5
  207. package/package.json +35 -12
  208. package/scripts/export-builder-api-evidence.js +3 -3
  209. package/scripts/lib/plan-actor.js +2 -2
  210. package/scripts/lib/plan-meta.js +1 -1
  211. package/scripts/lib/plan-parse.js +1 -1
  212. package/scripts/lib/plan-prevalidate-gates.js +12 -1
  213. package/scripts/lib/plan-run-report.js +13 -2
  214. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +10 -10
  215. package/templates/applications/dataplane/application.yaml +47 -17
  216. package/templates/applications/dataplane/env.template +28 -9
  217. package/templates/applications/dataplane/rbac.yaml +78 -2
  218. package/templates/applications/miso-controller/application.yaml +10 -1
  219. package/templates/applications/miso-controller/env.template +13 -8
  220. package/templates/applications/miso-controller/rbac.yaml +72 -0
  221. package/templates/channels/chatgpt/install.template.md.hbs +42 -24
  222. package/templates/channels/chatgpt/integration/README.md +10 -7
  223. package/templates/channels/chatgpt/integration/application.json +2 -2
  224. package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
  225. package/templates/channels/chatgpt/integration/env.template +1 -1
  226. package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
  227. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
  228. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
  229. package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
  230. package/templates/channels/microsoft-copilot/integration/README.md +9 -7
  231. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  232. package/templates/channels/microsoft-copilot/integration/env.template +1 -1
  233. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
  234. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
  235. package/templates/channels/slack/integration/slack-system.json +60 -2
  236. package/templates/python/requirements.txt +1 -1
@@ -7,12 +7,12 @@
7
7
  "key":"external-datasource-schema",
8
8
  "name":"External Data Source Configuration Schema",
9
9
  "description":"JSON schema for validating ExternalDataSource configuration files",
10
- "version":"2.9.2",
10
+ "version":"2.9.5",
11
11
  "type":"schema",
12
12
  "category":"integration",
13
13
  "author":"AI Fabrix Team",
14
14
  "createdAt":"2024-01-01T00:00:00Z",
15
- "updatedAt":"2026-06-16T00:00:00Z",
15
+ "updatedAt":"2026-07-31T00:00:00Z",
16
16
  "compatibility":{
17
17
  "minVersion":"1.0.0",
18
18
  "maxVersion":"3.0.0",
@@ -31,6 +31,30 @@
31
31
  "external-system.schema.json"
32
32
  ],
33
33
  "changelog":[
34
+ {
35
+ "version":"2.9.5",
36
+ "date":"2026-07-31T00:00:00Z",
37
+ "changes":[
38
+ "Added optional root accessControl.abac with applicability (required | notApplicable) and optional rationale for governance certification (scenario packs) — distinct from CIP filter.abac.mode."
39
+ ],
40
+ "breaking":false
41
+ },
42
+ {
43
+ "version":"2.9.4",
44
+ "date":"2026-07-18T00:00:00Z",
45
+ "changes":[
46
+ "Removed root statusMaps (superseded by dimensions.*.map {dimensionValue, rawValue} only — 346 §7.1)."
47
+ ],
48
+ "breaking":true
49
+ },
50
+ {
51
+ "version":"2.9.3",
52
+ "date":"2026-07-18T00:00:00Z",
53
+ "changes":[
54
+ "Added optional dimensionBinding.map array of {dimensionValue, rawValue} for static Dimension raw→enterprise translation on normalize (346 §7.1)."
55
+ ],
56
+ "breaking":false
57
+ },
34
58
  {
35
59
  "version":"2.9.2",
36
60
  "date":"2026-07-02T00:00:00Z",
@@ -70,7 +94,7 @@
70
94
  "version":"2.8.1",
71
95
  "date":"2026-06-15T00:00:00Z",
72
96
  "changes":[
73
- "Added composition.datasources for composed enterprise and Digital Worker datasources (438.6).",
97
+ "Added composition.datasources for composed enterprise and Role Assistant datasources (438.6).",
74
98
  "Added optional subscriptionFilter (roleKeys, includeSystemKinds, excludeSystemKinds, resourceTypes, systemKeys, datasourceKeys) on datasource manifests."
75
99
  ],
76
100
  "breaking":false
@@ -387,6 +411,32 @@
387
411
  "minimum":1,
388
412
  "description":"Optional sort order of this datasource within its external system (1 = first) for agent and integrator workflows when multiple record-storage datasources exist. Does not control CIP step execution order. Published to OpenAPI governance / optional runtime meta.business.businessOrder when epic 404.2 is enabled. foreignKeys alone do not define this order."
389
413
  },
414
+ "accessControl":{
415
+ "type":"object",
416
+ "additionalProperties":false,
417
+ "description":"Datasource-level access-control declarations for certification and product surfaces. Distinct from CIP filter.abac.mode (runtime filter step).",
418
+ "properties":{
419
+ "abac":{
420
+ "type":"object",
421
+ "additionalProperties":false,
422
+ "description":"Whether record-scoped ABAC governance scenario packs apply to this datasource.",
423
+ "required":["applicability"],
424
+ "properties":{
425
+ "applicability":{
426
+ "type":"string",
427
+ "enum":["required","notApplicable"],
428
+ "description":"required (default when accessControl.abac omitted): verify-governance / scenario packs expected. notApplicable: governance pillar is NOT_APPLICABLE for this datasource; packs and subject emails not required."
429
+ },
430
+ "rationale":{
431
+ "type":"string",
432
+ "minLength":1,
433
+ "maxLength":500,
434
+ "description":"Human-readable reason shown in Overview Governance Validation and CLI when applicability is notApplicable. Recommended when notApplicable."
435
+ }
436
+ }
437
+ }
438
+ }
439
+ },
390
440
  "composition":{
391
441
  "type":"object",
392
442
  "description":"Declares upstream datasources merged into this composed datasource. Generator owns merged metadata, exposedSchema, capabilities, and REST/MCP contract.",
@@ -407,7 +457,7 @@
407
457
  },
408
458
  "subscriptionFilter":{
409
459
  "$ref":"aifabrix://schema/external-system.schema.json#/$defs/subscriptionFilter",
410
- "description":"Optional role and systemKind filters for Digital Worker generation inputs on datasource manifests."
460
+ "description":"Optional role and systemKind filters for Role Assistant generation inputs on datasource manifests."
411
461
  },
412
462
  "agentExposure":{
413
463
  "type":"object",
@@ -1514,6 +1564,10 @@
1514
1564
  "type":"boolean",
1515
1565
  "description":"Filterability hint for metadata-driven query planning."
1516
1566
  },
1567
+ "observer":{
1568
+ "type":"boolean",
1569
+ "description":"When true, a committed change to this normalized first-level scalar field is eligible for Enterprise Runtime observation wake-up."
1570
+ },
1517
1571
  "nullable":{
1518
1572
  "type":"boolean"
1519
1573
  },
@@ -1694,6 +1748,45 @@
1694
1748
  }
1695
1749
  }
1696
1750
  },
1751
+ {
1752
+ "if":{
1753
+ "properties":{
1754
+ "observer":{
1755
+ "const":true
1756
+ }
1757
+ },
1758
+ "required":[
1759
+ "observer"
1760
+ ]
1761
+ },
1762
+ "then":{
1763
+ "properties":{
1764
+ "type":{
1765
+ "type":"string",
1766
+ "enum":[
1767
+ "string",
1768
+ "number",
1769
+ "integer",
1770
+ "boolean"
1771
+ ]
1772
+ }
1773
+ },
1774
+ "not":{
1775
+ "anyOf":[
1776
+ {
1777
+ "required":[
1778
+ "properties"
1779
+ ]
1780
+ },
1781
+ {
1782
+ "required":[
1783
+ "items"
1784
+ ]
1785
+ }
1786
+ ]
1787
+ }
1788
+ }
1789
+ },
1697
1790
  {
1698
1791
  "if":{
1699
1792
  "required":[
@@ -1845,6 +1938,30 @@
1845
1938
  "type":"boolean",
1846
1939
  "default":true,
1847
1940
  "description":"When false, this dimension binding is not used for protection/RSS dimension enforcement or governance visibility checks. Catalog binding and metadata materialization may still apply. Use object form to disable; string shorthand bindings are always enforcement-enabled."
1941
+ },
1942
+ "map":{
1943
+ "type":"array",
1944
+ "description":"Optional raw→enterprise value map for static Dimensions. Each entry has only dimensionValue and rawValue. Datasource and field are implied by this binding. CIP normalize persists dimensionValue for ABAC/MCP.",
1945
+ "items":{
1946
+ "type":"object",
1947
+ "additionalProperties":false,
1948
+ "required":[
1949
+ "dimensionValue",
1950
+ "rawValue"
1951
+ ],
1952
+ "properties":{
1953
+ "dimensionValue":{
1954
+ "type":"string",
1955
+ "minLength":1,
1956
+ "description":"Enterprise Dimension catalog value."
1957
+ },
1958
+ "rawValue":{
1959
+ "type":"string",
1960
+ "minLength":1,
1961
+ "description":"Connected-system token for this binding's field."
1962
+ }
1963
+ }
1964
+ }
1848
1965
  }
1849
1966
  },
1850
1967
  "oneOf":[
@@ -7,12 +7,12 @@
7
7
  "key": "external-system-schema",
8
8
  "name": "External System Configuration Schema",
9
9
  "description": "JSON schema for validating ExternalSystem configuration files",
10
- "version": "1.13.0",
10
+ "version": "1.13.1",
11
11
  "type": "schema",
12
12
  "category": "integration",
13
13
  "author": "AI Fabrix Team",
14
14
  "createdAt": "2024-01-01T00:00:00Z",
15
- "updatedAt": "2026-06-15T00:00:00Z",
15
+ "updatedAt": "2026-07-22T00:00:00Z",
16
16
  "compatibility": {
17
17
  "minVersion": "1.4.0",
18
18
  "maxVersion": "2.0.0",
@@ -27,6 +27,14 @@
27
27
  ],
28
28
  "dependencies": [],
29
29
  "changelog": [
30
+ {
31
+ "version": "1.13.1",
32
+ "date": "2026-07-22T00:00:00Z",
33
+ "changes": [
34
+ "Added optional configuration[].category for portal UI grouping labels (parity with application-schema)."
35
+ ],
36
+ "breaking": false
37
+ },
30
38
  {
31
39
  "version": "1.13.0",
32
40
  "date": "2026-07-02T00:00:00Z",
@@ -64,7 +72,7 @@
64
72
  "date": "2026-06-15T00:00:00Z",
65
73
  "changes": [
66
74
  "Added systemKind digitalWorker to x-systemKindCatalog (enterpriseContext group).",
67
- "Extended subscriptionFilter with roleKeys, includeSystemKinds, and excludeSystemKinds for Digital Worker generation inputs."
75
+ "Extended subscriptionFilter with roleKeys, includeSystemKinds, and excludeSystemKinds for Role Assistant generation inputs."
68
76
  ],
69
77
  "breaking": false
70
78
  },
@@ -176,7 +184,7 @@
176
184
  "$defs": {
177
185
  "subscriptionFilter": {
178
186
  "type": "object",
179
- "description": "Shared filter engine shape for subscription triggers and Digital Worker generation inputs.",
187
+ "description": "Shared filter engine shape for subscription triggers and Role Assistant generation inputs.",
180
188
  "properties": {
181
189
  "resourceTypes": {
182
190
  "type": "array",
@@ -209,7 +217,7 @@
209
217
  "minLength": 1
210
218
  },
211
219
  "minItems": 1,
212
- "description": "Role keys that scope Digital Worker or subscription generation."
220
+ "description": "Role keys that scope Role Assistant or subscription generation."
213
221
  },
214
222
  "includeSystemKinds": {
215
223
  "type": "array",
@@ -970,7 +978,7 @@
970
978
  },
971
979
  {
972
980
  "key": "digitalWorker",
973
- "displayName": "Digital Worker",
981
+ "displayName": "Role Assistant",
974
982
  "group": "enterpriseContext"
975
983
  },
976
984
  {
@@ -1163,6 +1171,12 @@
1163
1171
  "required": {
1164
1172
  "type": "boolean"
1165
1173
  },
1174
+ "category": {
1175
+ "type": "string",
1176
+ "description": "Optional UI grouping label for portal/deployment wizard Configuration tab",
1177
+ "minLength": 1,
1178
+ "maxLength": 100
1179
+ },
1166
1180
  "portalInput": {
1167
1181
  "type": "object",
1168
1182
  "required": [
@@ -204,6 +204,19 @@ parameters:
204
204
  notes: >-
205
205
  JWT signing secret; generated on first ensure. Azure Bicep typically uses `${prefix}-secrets-jwtKeyVault`.
206
206
 
207
+ # LICENSE_JWT=kv://miso-controller-jwt-licenseKeyVault — local default skips Mori/JWT license checks.
208
+ # Controller ignores DEVELOPMENT when DEPLOYMENT=azure.
209
+ - key: miso-controller-jwt-licenseKeyVault
210
+ scope: app
211
+ generator:
212
+ type: literal
213
+ value: 'DEVELOPMENT'
214
+ ensureOn: [upInfra, resolveApp]
215
+ azure:
216
+ notes: >-
217
+ Local/dev default DEVELOPMENT disables license validation (no Mori/JWT required).
218
+ Ignored when DEPLOYMENT=azure. Override with a real offline license JWT (or empty for Mori) in non-dev.
219
+
207
220
  # Exact entry so this is not caught by *KeyVault → randomBytes32 (invalid email).
208
221
  - key: miso-controller-admin-emailKeyVault
209
222
  scope: app
@@ -327,7 +340,38 @@ parameters:
327
340
  vaultSecretName: dataplane-client-secretKeyVault
328
341
  notes: Per-app OAuth client secret for dataplane; generated on first ensure.
329
342
 
330
- # Mori / telemetry: optional locally (LICENSE_JWT=DEVELOPMENT skips Mori); empty until integrated.
343
+ - key: mori-controller-client-idKeyVault
344
+ scope: app
345
+ generator:
346
+ type: literal
347
+ value: 'miso-controller-dev-mori-controller'
348
+ ensureOn: [upInfra, resolveApp]
349
+ azure:
350
+ notes: >-
351
+ Per-app OAuth client id from controller registration; literal default matches
352
+ {controllerId}-{environmentKey}-{applicationKey} (override per environment).
353
+
354
+ - key: mori-controller-client-secretKeyVault
355
+ scope: app
356
+ generator:
357
+ type: randomBytes32
358
+ ensureOn: [upInfra, resolveApp]
359
+ azure:
360
+ vaultSecretName: mori-controller-client-secretKeyVault
361
+ notes: Per-app OAuth client secret for mori-controller; generated on first ensure.
362
+
363
+ # Mori / telemetry: optional locally (LICENSE_JWT via miso-controller-jwt-licenseKeyVault=DEVELOPMENT skips Mori).
364
+ # MORI_AUTH_METHOD=kv://mori-controller-auth-methodKeyVault — local default apiKey.
365
+ - key: mori-controller-auth-methodKeyVault
366
+ scope: infra
367
+ generator:
368
+ type: literal
369
+ value: 'apiKey'
370
+ ensureOn: [upInfra, resolveApp]
371
+ azure:
372
+ notes: >-
373
+ Local/dev default apiKey. Override when using Mori basic auth or other methods.
374
+
331
375
  - key: mori-controller-api-keyKeyVault
332
376
  scope: infra
333
377
  generator:
@@ -0,0 +1,108 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "aifabrix://schema/role-assistant-settings",
4
+ "title": "Role Assistant Settings",
5
+ "description": "Schema for role-assistant.yaml used by digitalWorker packages.",
6
+ "type": "object",
7
+ "required": [
8
+ "apiVersion",
9
+ "version",
10
+ "kind",
11
+ "roleKey"
12
+ ],
13
+ "additionalProperties": false,
14
+ "properties": {
15
+ "apiVersion": {
16
+ "type": "string",
17
+ "const": "aifabrix.ai/v1"
18
+ },
19
+ "version": {
20
+ "type": "string",
21
+ "pattern": "^\\d+\\.\\d+\\.\\d+$"
22
+ },
23
+ "kind": {
24
+ "type": "string",
25
+ "const": "RoleAssistantSettings"
26
+ },
27
+ "roleKey": {
28
+ "type": "string",
29
+ "pattern": "^[a-z0-9-_]+$"
30
+ },
31
+ "dev": {
32
+ "$ref": "#/$defs/environmentSettings"
33
+ },
34
+ "tst": {
35
+ "$ref": "#/$defs/environmentSettings"
36
+ },
37
+ "pro": {
38
+ "$ref": "#/$defs/environmentSettings"
39
+ }
40
+ },
41
+ "$defs": {
42
+ "environmentSettings": {
43
+ "type": "object",
44
+ "additionalProperties": false,
45
+ "properties": {
46
+ "runtime": {
47
+ "$ref": "#/$defs/runtime"
48
+ },
49
+ "debug": {
50
+ "$ref": "#/$defs/debug"
51
+ },
52
+ "knowledge": {
53
+ "$ref": "#/$defs/knowledge"
54
+ }
55
+ }
56
+ },
57
+ "runtime": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "properties": {
61
+ "provider": {
62
+ "type": "string"
63
+ },
64
+ "model": {
65
+ "type": "string"
66
+ },
67
+ "temperature": {
68
+ "type": "number",
69
+ "minimum": 0,
70
+ "maximum": 2
71
+ },
72
+ "maxLoops": {
73
+ "type": "integer",
74
+ "minimum": 1,
75
+ "maximum": 1000
76
+ }
77
+ }
78
+ },
79
+ "debug": {
80
+ "type": "object",
81
+ "additionalProperties": false,
82
+ "properties": {
83
+ "enabled": {
84
+ "type": "boolean"
85
+ },
86
+ "includeRuntimeLog": {
87
+ "type": "boolean"
88
+ },
89
+ "includePromptTrace": {
90
+ "type": "boolean"
91
+ },
92
+ "includeCapabilityTrace": {
93
+ "type": "boolean"
94
+ }
95
+ }
96
+ },
97
+ "knowledge": {
98
+ "type": "object",
99
+ "additionalProperties": false,
100
+ "properties": {
101
+ "documentStorageKey": {
102
+ "type": "string",
103
+ "pattern": "^[a-z0-9-_]+$"
104
+ }
105
+ }
106
+ }
107
+ }
108
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": 6,
2
+ "version": 8,
3
3
  "semantics": {
4
4
  "visibility.show": "When false, the field name is omitted from default portal field lists, embedded credential form field lists, and from public API credentialConfig read models (GET/list with decrypt=false), in addition to any omission driven by encrypted. GET with decrypt=true returns the full decrypted config for authorized callers and does not apply this visibility filter.",
5
5
  "visibility.showValue": "UI-only: whether stored values may be shown versus placeholders in form flows that honor this flag. Does not control encryption at rest or public API stripping.",
@@ -114,10 +114,12 @@
114
114
  "display": {
115
115
  "label": "Tenant ID",
116
116
  "control": "text",
117
- "enabled": true
117
+ "enabled": true,
118
+ "placeholder": "Azure AD directory (tenant) ID",
119
+ "description": "Used for Microsoft identity platforms. May also appear in tokenUrl as {{tenantId}}."
118
120
  },
119
121
  "visibility": {
120
- "show": false,
122
+ "show": true,
121
123
  "showValue": true
122
124
  },
123
125
  "encrypted": false
@@ -149,6 +151,20 @@
149
151
  "showValue": false
150
152
  },
151
153
  "encrypted": true
154
+ },
155
+ {
156
+ "name": "accessTokenExpiresAt",
157
+ "required": false,
158
+ "display": {
159
+ "label": "Access Token Expires At",
160
+ "control": "text",
161
+ "enabled": false
162
+ },
163
+ "visibility": {
164
+ "show": false,
165
+ "showValue": false
166
+ },
167
+ "encrypted": false
152
168
  }
153
169
  ]
154
170
  },
package/lib/utils/api.js CHANGED
@@ -381,12 +381,11 @@ function extractControllerUrl(url) {
381
381
  return match ? match[1] : url;
382
382
  }
383
383
  }
384
-
385
384
  /**
386
- * Set auth header on headers object: Bearer for user token, x-client-token for application token.
385
+ * Set auth header on headers object: Bearer for user token, x-client-token for app token.
387
386
  * @param {Object} headers - Headers object to mutate
388
387
  * @param {string} token - Token value
389
- * @param {string} authType - 'bearer' or 'client-token'
388
+ * @param {string} authType - 'bearer' | 'client-token'
390
389
  */
391
390
  function setAuthHeader(headers, token, authType) {
392
391
  if (!token) return;
@@ -396,7 +395,6 @@ function setAuthHeader(headers, token, authType) {
396
395
  headers['Authorization'] = `Bearer ${token}`;
397
396
  }
398
397
  }
399
-
400
398
  /**
401
399
  * Make an authenticated API call with user token (Bearer) or application token (x-client-token).
402
400
  * Automatically refreshes device token on 401 when user Bearer was used.
@@ -408,7 +406,48 @@ function setAuthHeader(headers, token, authType) {
408
406
  * @param {string} [tokenOrAuthConfig.controller] - Controller URL for token refresh (if object)
409
407
  * @returns {Promise<Object>} Response object
410
408
  */
411
- // eslint-disable-next-line max-statements
409
+ /**
410
+ * Retry once after device-token refresh on 401 (Bearer only; never for client-token/preserveBearer).
411
+ * @param {Object} response
412
+ * @param {string} url
413
+ * @param {Object} options
414
+ * @param {Object} headers
415
+ * @param {string|null} authControllerUrl
416
+ * @returns {Promise<Object>}
417
+ */
418
+ async function retryApiCallAfterDeviceTokenRefresh(
419
+ response,
420
+ url,
421
+ options,
422
+ headers,
423
+ authControllerUrl
424
+ ) {
425
+ try {
426
+ const { forceRefreshDeviceToken } = require('./token-manager');
427
+ const refreshedToken = await forceRefreshDeviceToken(
428
+ authControllerUrl || extractControllerUrl(url)
429
+ );
430
+ if (refreshedToken?.token) {
431
+ headers.Authorization = `Bearer ${refreshedToken.token}`;
432
+ return await makeApiCall(url, { ...options, headers });
433
+ }
434
+ const authError =
435
+ 'Authentication failed: Token expired and refresh failed. Please login again using: aifabrix login';
436
+ return { ...response, error: authError, formattedError: authError };
437
+ } catch (refreshError) {
438
+ const authError = `Authentication failed: ${refreshError.message || String(refreshError)}. Please login again using: aifabrix login`;
439
+ return { ...response, error: authError, formattedError: authError };
440
+ }
441
+ }
442
+ function shouldRefreshBearerOn401(response, authType, tokenOrAuthConfig) {
443
+ return (
444
+ !response.success &&
445
+ response.status === 401 &&
446
+ authType !== 'client-token' &&
447
+ !(typeof tokenOrAuthConfig === 'object' && tokenOrAuthConfig?.preserveBearer)
448
+ );
449
+ }
450
+
412
451
  async function authenticatedApiCall(url, options = {}, tokenOrAuthConfig) {
413
452
  const isStringToken = typeof tokenOrAuthConfig === 'string';
414
453
  const token = isStringToken ? tokenOrAuthConfig : tokenOrAuthConfig?.token;
@@ -426,26 +465,18 @@ async function authenticatedApiCall(url, options = {}, tokenOrAuthConfig) {
426
465
  headers
427
466
  });
428
467
 
429
- // Only attempt device token refresh on 401 when user Bearer token was used (not for client-token)
430
- if (!response.success && response.status === 401 && authType !== 'client-token') {
431
- try {
432
- const { forceRefreshDeviceToken } = require('./token-manager');
433
- const refreshedToken = await forceRefreshDeviceToken(authControllerUrl || extractControllerUrl(url));
434
- if (refreshedToken?.token) {
435
- headers['Authorization'] = `Bearer ${refreshedToken.token}`;
436
- return await makeApiCall(url, { ...options, headers });
437
- }
438
- const authError = 'Authentication failed: Token expired and refresh failed. Please login again using: aifabrix login';
439
- return { ...response, error: authError, formattedError: authError };
440
- } catch (refreshError) {
441
- const authError = `Authentication failed: ${refreshError.message || String(refreshError)}. Please login again using: aifabrix login`;
442
- return { ...response, error: authError, formattedError: authError };
443
- }
468
+ if (shouldRefreshBearerOn401(response, authType, tokenOrAuthConfig)) {
469
+ return retryApiCallAfterDeviceTokenRefresh(
470
+ response,
471
+ url,
472
+ options,
473
+ headers,
474
+ authControllerUrl
475
+ );
444
476
  }
445
477
 
446
478
  return response;
447
479
  }
448
-
449
480
  const {
450
481
  initiateDeviceCodeFlow,
451
482
  pollDeviceCodeToken,