@aifabrix/builder 2.49.2 → 2.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/plans/157.1-security-quality-violations-by-type.csv +374 -0
- package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
- package/.cursor/skills/README.md +1 -0
- package/.dockerignore +52 -0
- package/.eslintignore +22 -0
- package/README.md +2 -0
- package/bin/builder-api-cleanup.js +26 -0
- package/bin/builder-api-nest.js +10 -0
- package/bin/builder-api-spike.js +19 -0
- package/enterprise-knowledge/README.md +50 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
- package/integration/README.md +81 -0
- package/integration/github/README.md +53 -0
- package/integration/github/application.json +21 -0
- package/integration/github/deploy.js +72 -0
- package/integration/github/env.template +11 -0
- package/integration/github/github-datasource-issue-comments.json +239 -0
- package/integration/github/github-datasource-issues.json +399 -0
- package/integration/github/github-datasource-repository.json +354 -0
- package/integration/github/github-deploy.json +1202 -0
- package/integration/github/github-system.json +82 -0
- package/integration/hubspot-test/README.md +1 -1
- package/integration/hubspot-test/create-hubspot.js +1 -16
- package/jest.isolated-projects.js +31 -1
- package/jest.projects.js +87 -1
- package/lib/api/dev-server-https.js +1 -1
- package/lib/api/enterprise-knowledge.api.js +63 -0
- package/lib/api/evidence-kinds.api.js +128 -0
- package/lib/api/evidence.api.js +172 -0
- package/lib/api/external-systems.api.js +8 -2
- package/lib/api/pipeline.api.js +5 -1
- package/lib/api/resource-types.api.js +5 -4
- package/lib/api/roles.api.js +121 -0
- package/lib/api/types/enterprise-knowledge.types.js +46 -0
- package/lib/api/types/evidence-kinds.types.js +42 -0
- package/lib/api/types/evidence.types.js +67 -0
- package/lib/api/types/resource-types.types.js +2 -0
- package/lib/api/types/roles.types.js +36 -0
- package/lib/app/certification-verify-rows.js +1 -1
- package/lib/app/controller-application-filter.js +36 -0
- package/lib/app/deploy.js +1 -1
- package/lib/app/list-external-systems.js +130 -0
- package/lib/app/list.js +20 -8
- package/lib/app/run.js +3 -1
- package/lib/app/show-display.js +8 -3
- package/lib/app/show-online.js +178 -0
- package/lib/app/show.js +39 -90
- package/lib/build/builder-api-docker-staging.js +47 -0
- package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
- package/lib/build/standard-docker-build.js +2 -0
- package/lib/certification/merge-certification-from-artifact.js +1 -1
- package/lib/certification/post-unified-cert-sync.js +4 -31
- package/lib/certification/sync-after-external-command.js +0 -1
- package/lib/certification/sync-system-certification.js +0 -3
- package/lib/channels/add-channel.js +40 -34
- package/lib/channels/approval-guides/chatgpt.js +33 -0
- package/lib/channels/approval-guides/credential-portal.js +38 -0
- package/lib/channels/approval-guides/index.js +110 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
- package/lib/channels/approval-guides/slack.js +34 -0
- package/lib/channels/approval-guides/teams-bot.js +35 -0
- package/lib/channels/approval-guides/web-embed.js +32 -0
- package/lib/channels/channel-approval-guide.js +11 -0
- package/lib/channels/channel-artifact-generator.js +18 -5
- package/lib/channels/channel-audit.js +3 -0
- package/lib/channels/channel-auth-context.js +1 -1
- package/lib/channels/channel-description.js +59 -0
- package/lib/channels/channel-integration-generator.js +13 -230
- package/lib/channels/channel-integration-template.js +94 -0
- package/lib/channels/channel-runtime-resolver.js +43 -3
- package/lib/channels/channel-status-display.js +66 -26
- package/lib/channels/channel-targets.js +3 -3
- package/lib/cli/index.js +31 -3
- package/lib/cli/infra-guided.js +5 -1
- package/lib/cli/setup-app-external-create.js +111 -0
- package/lib/cli/setup-app.help.js +1 -1
- package/lib/cli/setup-app.js +60 -130
- package/lib/cli/setup-app.test-commands.js +26 -52
- package/lib/cli/setup-certification-commands.js +4 -4
- package/lib/cli/setup-certification.help.js +9 -9
- package/lib/cli/setup-dev.js +30 -9
- package/lib/cli/setup-external-system-help.js +4 -6
- package/lib/cli/setup-external-system.js +58 -52
- package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
- package/lib/cli/setup-infra-up-platform-action.js +3 -1
- package/lib/cli/setup-infra.js +15 -0
- package/lib/cli/setup-list.js +43 -0
- package/lib/cli/setup-utility-help-after.js +12 -0
- package/lib/cli/setup-utility-repair.js +26 -7
- package/lib/cli/setup-utility-validate.js +41 -2
- package/lib/cli/setup-utility.js +5 -3
- package/lib/commands/app.js +15 -43
- package/lib/commands/channel-add-setup.js +110 -0
- package/lib/commands/channel.js +42 -8
- package/lib/commands/datasource-sync-display.js +96 -0
- package/lib/commands/datasource-sync-policy.js +210 -0
- package/lib/commands/datasource-test-trust-cli.js +6 -6
- package/lib/commands/datasource-unified-test-cli.js +2 -1
- package/lib/commands/datasource-unified-test-cli.options.js +33 -23
- package/lib/commands/deploy-gate-failure-details.js +184 -0
- package/lib/commands/deploy-gate-orchestrator.js +368 -0
- package/lib/commands/dev-cli-handlers.js +7 -62
- package/lib/commands/dev-host-ops-params.js +91 -0
- package/lib/commands/dev-host-ops-poll.js +111 -0
- package/lib/commands/dev-host-ops.js +107 -94
- package/lib/commands/dev-init.js +6 -106
- package/lib/commands/dev-refresh.js +197 -0
- package/lib/commands/enterprise-knowledge.js +284 -0
- package/lib/commands/evidence-cli-leaves.js +250 -0
- package/lib/commands/evidence-kind.js +428 -0
- package/lib/commands/evidence.js +51 -0
- package/lib/commands/governance-cli-shared.js +2 -2
- package/lib/commands/governance-command-action.js +5 -3
- package/lib/commands/governance-fixture-subjects.js +85 -0
- package/lib/commands/governance.js +1 -1
- package/lib/commands/lifecycle-command-action.js +2 -2
- package/lib/commands/lifecycle-external.js +3 -3
- package/lib/commands/manifest-cli-auth.js +29 -0
- package/lib/commands/manifest-cli-commands.js +170 -0
- package/lib/commands/manifest-cli-integration-path.js +63 -0
- package/lib/commands/manifest.js +21 -0
- package/lib/commands/protection-cli-leaves.js +3 -3
- package/lib/commands/repair-auth-apply.js +15 -1
- package/lib/commands/repair-authentications-454.js +169 -0
- package/lib/commands/repair-capability-openapi-warnings.js +126 -0
- package/lib/commands/repair-datasource-apply.js +135 -0
- package/lib/commands/repair-datasource-auto-rbac.js +62 -1
- package/lib/commands/repair-datasource-http-service-contract.js +239 -0
- package/lib/commands/repair-datasource-operation-security.js +180 -0
- package/lib/commands/repair-datasource-run.js +7 -2
- package/lib/commands/repair-datasource-sync-operations.js +177 -0
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
- package/lib/commands/repair-datasource.js +12 -68
- package/lib/commands/repair-env-template.js +11 -1
- package/lib/commands/repair-external-run.js +121 -31
- package/lib/commands/repair-internal.js +1 -1
- package/lib/commands/repair-openapi-export.js +156 -0
- package/lib/commands/repair-openapi-sync.js +33 -8
- package/lib/commands/repair-orchestration-datasource-split.js +259 -0
- package/lib/commands/repair-persist.js +22 -1
- package/lib/commands/repair-rbac-platform-preset.js +204 -0
- package/lib/commands/repair-rbac-reader-roles.js +191 -0
- package/lib/commands/repair-rbac.js +163 -86
- package/lib/commands/repair-steps.js +83 -18
- package/lib/commands/repair-system-permissions.js +1 -0
- package/lib/commands/repair.js +1 -1
- package/lib/commands/resource-type.js +166 -44
- package/lib/commands/role.js +452 -0
- package/lib/commands/run-post-publish-data-sync.js +68 -0
- package/lib/commands/setup-modes.js +1 -1
- package/lib/commands/setup.js +1 -1
- package/lib/commands/test-e2e-external.js +21 -8
- package/lib/commands/test-governance-cli-options.js +2 -2
- package/lib/commands/test-trust-cli-options.js +2 -2
- package/lib/commands/up-builder-api-bootstrap.js +71 -0
- package/lib/commands/up-builder-api-provision.js +241 -0
- package/lib/commands/up-builder-api.js +88 -0
- package/lib/commands/up-common.js +25 -1
- package/lib/commands/upload-credential-push-log.js +117 -0
- package/lib/commands/upload-data-sync-finalize.js +60 -0
- package/lib/commands/upload-probe.js +66 -0
- package/lib/commands/upload-publish-context.js +4 -1
- package/lib/commands/upload-sidecar-followups.js +55 -27
- package/lib/commands/upload.js +116 -157
- package/lib/commands/validate-json.js +230 -0
- package/lib/commands/verify-governance-combined-external.js +1 -1
- package/lib/commands/verify-governance-db.js +2 -2
- package/lib/commands/verify-operations-command-action.js +2 -2
- package/lib/commands/verify-operations-step-plan.js +79 -41
- package/lib/commands/verify-operations-steps.js +2 -2
- package/lib/commands/verify-trust-command-action.js +1 -1
- package/lib/commands/wizard-core.js +1 -1
- package/lib/commands/wizard-headless.js +2 -1
- package/lib/core/admin-secrets.js +2 -6
- package/lib/core/audit-logger.js +1 -1
- package/lib/core/secrets-env-content.js +10 -4
- package/lib/core/secrets-env-write.js +2 -13
- package/lib/core/secrets-load.js +1 -3
- package/lib/datasource/agent-trust-run.js +3 -3
- package/lib/datasource/capability/relate-operations.js +1 -1
- package/lib/datasource/deploy.js +3 -1
- package/lib/datasource/test-e2e.js +6 -1
- package/lib/datasource/unified-validation-run-body.js +4 -1
- package/lib/datasource/unified-validation-run.js +1 -1
- package/lib/deployment/deploy-poll-ui.js +73 -12
- package/lib/deployment/deployer-poll-run.js +113 -0
- package/lib/deployment/deployer.js +17 -87
- package/lib/evidence/dataplane-context.js +21 -0
- package/lib/evidence/evidence-display.js +78 -0
- package/lib/evidence/evidence-service.js +392 -0
- package/lib/external-system/deploy.js +290 -112
- package/lib/external-system/download.js +7 -3
- package/lib/external-system/test-execution.js +1 -1
- package/lib/external-system/test-system-level.js +8 -10
- package/lib/external-system/test.js +12 -6
- package/lib/generator/deploy-script.js +73 -0
- package/lib/generator/external.js +2 -1
- package/lib/generator/helpers.js +13 -5
- package/lib/generator/index.js +17 -2
- package/lib/generator/split-variables.js +9 -3
- package/lib/generator/wizard.js +3 -36
- package/lib/infrastructure/helpers-docker-check.js +6 -0
- package/lib/infrastructure/helpers.js +1 -1
- package/lib/internal/fs-real-sync.js +22 -1
- package/lib/internal/node-fs.js +2 -0
- package/lib/lifecycle/lifecycle-governance-options.js +1 -1
- package/lib/lifecycle/verify-step-progress.js +1 -1
- package/lib/programmatic/access-log.js +26 -0
- package/lib/programmatic/auth-config.js +45 -0
- package/lib/programmatic/bearer-auth.js +176 -0
- package/lib/programmatic/builder-api-request.js +175 -0
- package/lib/programmatic/builder-api-route-dispatch.js +82 -0
- package/lib/programmatic/builder-api-runtime-config.js +42 -0
- package/lib/programmatic/builder-api-server.js +230 -0
- package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
- package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
- package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
- package/lib/programmatic/builder-help-envelope.js +36 -0
- package/lib/programmatic/builder-help-fixtures.js +200 -0
- package/lib/programmatic/builder-help-governance.js +172 -0
- package/lib/programmatic/builder-help-schema-catalog.js +92 -0
- package/lib/programmatic/builder-help.js +361 -0
- package/lib/programmatic/capability-registry.js +77 -0
- package/lib/programmatic/command-options.js +32 -0
- package/lib/programmatic/enterprise-mcp-client.js +114 -0
- package/lib/programmatic/http-problem-details.js +99 -0
- package/lib/programmatic/http-route-match.js +40 -0
- package/lib/programmatic/idempotency-cache.js +69 -0
- package/lib/programmatic/index.js +53 -0
- package/lib/programmatic/integration-path-scope.js +39 -0
- package/lib/programmatic/log-redaction.js +66 -0
- package/lib/programmatic/manifest-get-section.js +146 -0
- package/lib/programmatic/manifest-patch-section.js +252 -0
- package/lib/programmatic/manifest-repair.js +122 -0
- package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
- package/lib/programmatic/manifest-section-io.js +225 -0
- package/lib/programmatic/manifest-section-quality.js +171 -0
- package/lib/programmatic/manifest-section-registry-data.js +269 -0
- package/lib/programmatic/manifest-section-registry.js +222 -0
- package/lib/programmatic/nest-http-bridge.js +34 -0
- package/lib/programmatic/openapi-component-schemas.js +68 -0
- package/lib/programmatic/openapi-description-enricher.js +117 -0
- package/lib/programmatic/openapi-descriptions.js +190 -0
- package/lib/programmatic/openapi-docs-serving.js +123 -0
- package/lib/programmatic/openapi-help-schemas.js +63 -0
- package/lib/programmatic/openapi-manifest-schemas.js +141 -0
- package/lib/programmatic/openapi-operation-bindings.js +274 -0
- package/lib/programmatic/openapi-request-schemas.js +155 -0
- package/lib/programmatic/openapi-result-schemas.js +493 -0
- package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
- package/lib/programmatic/openapi-schema-descriptions-core.js +162 -0
- package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
- package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
- package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
- package/lib/programmatic/openapi-schema-helpers.js +108 -0
- package/lib/programmatic/openapi-spec.js +203 -0
- package/lib/programmatic/orchestration-openapi-meta.js +159 -0
- package/lib/programmatic/platform-rbac-catalog.js +90 -0
- package/lib/programmatic/request-timeout.js +53 -0
- package/lib/programmatic/route-handler-map.js +143 -0
- package/lib/programmatic/route-handlers-context.js +29 -0
- package/lib/programmatic/route-handlers.js +33 -0
- package/lib/programmatic/run-certify.js +57 -0
- package/lib/programmatic/run-enterprise-mcp.js +32 -0
- package/lib/programmatic/run-lifecycle.js +29 -0
- package/lib/programmatic/run-repair.js +41 -0
- package/lib/programmatic/run-repository-emcp.js +62 -0
- package/lib/programmatic/run-template-workspace.js +74 -0
- package/lib/programmatic/run-test.js +49 -0
- package/lib/programmatic/run-upload.js +63 -0
- package/lib/programmatic/run-validate.js +53 -0
- package/lib/programmatic/run-wizard.js +40 -0
- package/lib/programmatic/system-key.js +48 -0
- package/lib/programmatic/wizard-config-normalize.js +118 -0
- package/lib/programmatic/workspace-cleanup.js +128 -0
- package/lib/programmatic/workspace-context.js +145 -0
- package/lib/programmatic/workspace-lock.js +75 -0
- package/lib/programmatic/workspace-meta.js +64 -0
- package/lib/programmatic/workspace-ops.js +149 -0
- package/lib/protection/run-commands-upload-sync.js +35 -0
- package/lib/protection/run-commands.js +2 -20
- package/lib/protection/upload-batch.js +11 -7
- package/lib/resolvers/evidence-kind-file.js +230 -0
- package/lib/resolvers/resource-type-file.js +58 -1
- package/lib/resolvers/role-file.js +227 -0
- package/lib/schema/application-schema.json +22 -2
- package/lib/schema/external-datasource.schema.json +245 -2
- package/lib/schema/external-system.schema.json +259 -119
- package/lib/schema/flag-map-validation-run.json +3 -0
- package/lib/schema/infra.parameter.yaml +25 -1
- package/lib/schema/type/credential-field-registry.json +21 -5
- package/lib/schema/type/document-storage.json +9 -0
- package/lib/utils/agent-trust-run-display.js +1 -1
- package/lib/utils/api.js +8 -2
- package/lib/utils/app-path-resolve.js +168 -0
- package/lib/utils/app-register-config.js +4 -3
- package/lib/utils/authentication-env-template.js +222 -0
- package/lib/utils/cli-sync-options.js +62 -10
- package/lib/utils/cli-utils.js +15 -3
- package/lib/utils/cli-workspace-options.js +29 -0
- package/lib/utils/compose-generate-docker-compose.js +102 -0
- package/lib/utils/configuration-env-resolver.js +203 -27
- package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
- package/lib/utils/datasource-test-run-certification-debug.js +130 -0
- package/lib/utils/datasource-test-run-debug-display.js +2 -0
- package/lib/utils/datasource-test-run-debug-slice.js +7 -0
- package/lib/utils/datasource-test-run-display.js +2 -1
- package/lib/utils/dev-ca-install.js +5 -6
- package/lib/utils/dev-config.js +2 -2
- package/lib/utils/dev-init-ssh-merge.js +165 -23
- package/lib/utils/dev-list-sort.js +145 -0
- package/lib/utils/dev-pin-share-instructions.js +110 -0
- package/lib/utils/dev-platform-tls.js +0 -63
- package/lib/utils/dev-ssh-config-helper.js +177 -33
- package/lib/utils/docker-build.js +46 -27
- package/lib/utils/docker-daemon-tls-ca.js +1 -1
- package/lib/utils/docker-exec.js +91 -6
- package/lib/utils/enterprise-knowledge-paths.js +142 -0
- package/lib/utils/env-copy.js +3 -4
- package/lib/utils/env-dotenv-format.js +103 -0
- package/lib/utils/error-formatters/error-parser.js +0 -3
- package/lib/utils/external-env-template.js +5 -2
- package/lib/utils/external-system-display.js +5 -1
- package/lib/utils/external-system-readiness-compact-blocks.js +248 -0
- package/lib/utils/external-system-readiness-compact-display.js +324 -0
- package/lib/utils/external-system-readiness-core.js +16 -0
- package/lib/utils/external-system-readiness-deploy-display.js +29 -11
- package/lib/utils/external-system-readiness-display-internals.js +3 -1
- package/lib/utils/external-system-readiness-display.js +20 -30
- package/lib/utils/external-system-system-test-tty-certification.js +135 -0
- package/lib/utils/external-system-system-test-tty.js +5 -41
- package/lib/utils/health-check-request.js +2 -3
- package/lib/utils/help-builder.js +9 -1
- package/lib/utils/host-ops-job-labels.js +236 -0
- package/lib/utils/host-ops-job-result.js +61 -0
- package/lib/utils/host-ops-poll-ui.js +163 -0
- package/lib/utils/image-name.js +22 -4
- package/lib/utils/integration-path-resolve.js +112 -0
- package/lib/utils/logger.js +37 -4
- package/lib/utils/manifest-source-emit.js +1 -1
- package/lib/utils/paths-reload-source.js +148 -0
- package/lib/utils/paths-system-builder-keys.js +25 -0
- package/lib/utils/paths.js +183 -30
- package/lib/utils/pipeline-upload-auth-retry.js +4 -0
- package/lib/utils/postgres-platform-bootstrap.js +24 -17
- package/lib/utils/postgres-wipe.js +5 -2
- package/lib/utils/remote-dev-auth.js +39 -4
- package/lib/utils/resolve-docker-image-ref.js +36 -6
- package/lib/utils/runtime-configuration-values.js +64 -2
- package/lib/utils/secrets-helpers.js +5 -1
- package/lib/utils/ssh-known-hosts.js +130 -0
- package/lib/utils/test-target-cli-options.js +75 -0
- package/lib/utils/token-manager.js +16 -0
- package/lib/utils/upload-sync-options.js +20 -2
- package/lib/utils/validation-run-request.js +11 -2
- package/lib/validation/external-manifest-validator.js +11 -1
- package/lib/validation/openapi-contract-surface-validator.js +430 -0
- package/lib/validation/openapi-contract-vendor-validation.js +238 -0
- package/lib/validation/validate-external-file.js +160 -0
- package/lib/validation/validate.js +6 -117
- package/lib/validation/validator.js +6 -5
- package/package.json +76 -37
- package/packages/builder-api/README.md +120 -0
- package/packages/builder-api/package.json +30 -0
- package/packages/builder-api/src/app.module.ts +7 -0
- package/packages/builder-api/src/auth/auth.module.ts +5 -0
- package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
- package/packages/builder-api/src/main.ts +16 -0
- package/packages/builder-api/tsconfig.json +15 -0
- package/scripts/check-builder-api-architecture-grep.js +79 -0
- package/scripts/docker_image_content_gate.js +47 -0
- package/scripts/docker_image_content_gate.sh +5 -0
- package/scripts/export-builder-api-evidence.js +262 -0
- package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
- package/scripts/lib/builder-api-docker-staging-core.js +183 -0
- package/scripts/lib/docker-image-content-gate-core.js +166 -0
- package/scripts/lib/plan-actor.js +109 -0
- package/scripts/lib/plan-config.js +20 -0
- package/scripts/lib/plan-gates.js +154 -0
- package/scripts/lib/plan-meta.js +104 -0
- package/scripts/lib/plan-parse.js +162 -0
- package/scripts/lib/plan-prevalidate-gates.js +337 -0
- package/scripts/lib/plan-run-core.js +125 -0
- package/scripts/lib/plan-run-report.js +119 -0
- package/scripts/plan-approve.js +24 -0
- package/scripts/plan-archive.js +49 -0
- package/scripts/plan-run.js +13 -0
- package/scripts/plan-set-actor.js +21 -0
- package/scripts/plan-validate.js +80 -0
- package/scripts/pnpm/af.mjs +110 -0
- package/scripts/pnpm/check-quiet.mjs +32 -0
- package/scripts/pnpm/dev-install.mjs +29 -0
- package/scripts/pnpm/dev-reload.mjs +18 -0
- package/scripts/pnpm/help.mjs +55 -0
- package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
- package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
- package/scripts/pnpm/lib/spinner.mjs +42 -0
- package/scripts/stage_builder_api_for_docker.js +65 -0
- package/scripts/sync-builder-api-template.js +44 -0
- package/templates/README.md +3 -0
- package/templates/applications/builder-api/Dockerfile +38 -0
- package/templates/applications/builder-api/application.yaml +75 -0
- package/templates/applications/builder-api/env.template +48 -0
- package/templates/applications/dataplane/application.yaml +27 -5
- package/templates/applications/dataplane/env.template +38 -15
- package/templates/applications/dataplane/rbac.yaml +85 -3
- package/templates/applications/miso-controller/application.yaml +10 -1
- package/templates/applications/miso-controller/env.template +11 -10
- package/templates/applications/miso-controller/rbac.yaml +72 -0
- package/templates/channels/README.md +18 -0
- package/templates/channels/ai-fabrix-icon.jpg +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +21 -24
- package/templates/channels/chatgpt/integration/README.md +11 -0
- package/templates/channels/chatgpt/integration/application.json +15 -0
- package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
- package/templates/channels/chatgpt/integration/env.template +4 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
- package/templates/channels/microsoft-copilot/integration/README.md +11 -0
- package/templates/channels/microsoft-copilot/integration/application.json +15 -0
- package/templates/channels/microsoft-copilot/integration/env.template +6 -0
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
- package/templates/channels/slack/install.template.md.hbs +48 -18
- package/templates/channels/slack/integration/README.md +38 -0
- package/templates/channels/slack/integration/application.json +18 -0
- package/templates/channels/slack/integration/env.template +29 -0
- package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
- package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
- package/templates/channels/slack/integration/slack-system.json +144 -0
- package/templates/channels/slack/manifest.template.json.hbs +20 -10
- package/templates/channels/teams-bot/install.template.md.hbs +31 -17
- package/templates/channels/teams-bot/integration/README.md +18 -0
- package/templates/channels/teams-bot/integration/application.json +17 -0
- package/templates/channels/teams-bot/integration/env.template +5 -0
- package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
- package/templates/channels/web-embed/install.template.md.hbs +16 -26
- package/templates/channels/web-embed/integration/README.md +11 -0
- package/templates/channels/web-embed/integration/application.json +15 -0
- package/templates/channels/web-embed/integration/env.template +4 -0
- package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
- package/templates/openapi/redoc_page.html +86 -0
- package/templates/python/docker-compose.hbs +11 -0
- package/templates/python/requirements.txt +2 -2
- package/templates/typescript/docker-compose.hbs +11 -0
- package/lib/certification/cli-cert-sync-skip.js +0 -21
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence kind catalog file helpers for create/import/export.
|
|
3
|
+
*
|
|
4
|
+
* File JSON uses `domain`; Controller API uses `domainKey`.
|
|
5
|
+
*
|
|
6
|
+
* @fileoverview Evidence kind catalog file parsing and API mapping
|
|
7
|
+
* @author AI Fabrix Team
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const { existsSync, readFileSync, writeFileSync } = require('../internal/fs-real-sync');
|
|
15
|
+
|
|
16
|
+
const DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
17
|
+
const SEVERITIES = new Set(['low', 'medium', 'high', 'critical']);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} filePath
|
|
21
|
+
* @returns {object|Array}
|
|
22
|
+
*/
|
|
23
|
+
function loadEvidenceKindJson(filePath) {
|
|
24
|
+
const p = path.resolve(String(filePath || '').trim());
|
|
25
|
+
if (!p) {
|
|
26
|
+
throw new Error('--file is required');
|
|
27
|
+
}
|
|
28
|
+
if (!existsSync(p)) {
|
|
29
|
+
throw new Error(`File not found: ${p}`);
|
|
30
|
+
}
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = JSON.parse(readFileSync(p, 'utf8'));
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new Error(`Invalid JSON in ${p}: ${e.message}`);
|
|
36
|
+
}
|
|
37
|
+
if (parsed === null || typeof parsed !== 'object') {
|
|
38
|
+
throw new Error(`Evidence kind file must be a JSON object or array: ${p}`);
|
|
39
|
+
}
|
|
40
|
+
return parsed;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {object} entry
|
|
45
|
+
* @param {number} index
|
|
46
|
+
* @returns {string}
|
|
47
|
+
*/
|
|
48
|
+
function requireDomainValue(entry, index) {
|
|
49
|
+
const raw = entry.domain !== undefined ? entry.domain : entry.domainKey;
|
|
50
|
+
const value = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
|
|
51
|
+
if (!value) {
|
|
52
|
+
throw new Error(`evidenceKinds[${index}].domain is required`);
|
|
53
|
+
}
|
|
54
|
+
if (!DOMAIN_KEY_PATTERN.test(value)) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens'
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Map baseline/file evidence kind row to Controller create payload (domain → domainKey).
|
|
64
|
+
* @param {object} row
|
|
65
|
+
* @param {number} [index]
|
|
66
|
+
* @returns {Object}
|
|
67
|
+
*/
|
|
68
|
+
function mapEvidenceKindFileToApiPayload(row, index = 0) {
|
|
69
|
+
if (!row || typeof row !== 'object') {
|
|
70
|
+
throw new Error(`evidenceKinds[${index}] must be a JSON object`);
|
|
71
|
+
}
|
|
72
|
+
const key = String(row.key || '').trim();
|
|
73
|
+
if (!key) {
|
|
74
|
+
throw new Error(`evidenceKinds[${index}].key is required`);
|
|
75
|
+
}
|
|
76
|
+
const displayName = String(row.displayName || '').trim();
|
|
77
|
+
if (!displayName) {
|
|
78
|
+
throw new Error(`evidenceKinds[${index}].displayName is required`);
|
|
79
|
+
}
|
|
80
|
+
const purpose = String(row.purpose || '').trim();
|
|
81
|
+
if (!purpose) {
|
|
82
|
+
throw new Error(`evidenceKinds[${index}].purpose is required`);
|
|
83
|
+
}
|
|
84
|
+
const domainKey = requireDomainValue(row, index);
|
|
85
|
+
const payload = { key, displayName, purpose, domainKey };
|
|
86
|
+
copyOptionalFields(payload, row, [
|
|
87
|
+
'description',
|
|
88
|
+
'expectedUse',
|
|
89
|
+
'requiresApproval',
|
|
90
|
+
'isActive',
|
|
91
|
+
'sortOrder',
|
|
92
|
+
'source'
|
|
93
|
+
]);
|
|
94
|
+
assignOptionalSeverity(payload, row, index);
|
|
95
|
+
if (row.metadata && typeof row.metadata === 'object') {
|
|
96
|
+
payload.metadata = row.metadata;
|
|
97
|
+
}
|
|
98
|
+
return payload;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @param {Object} payload
|
|
103
|
+
* @param {object} row
|
|
104
|
+
* @param {number} index
|
|
105
|
+
* @returns {void}
|
|
106
|
+
*/
|
|
107
|
+
function assignOptionalSeverity(payload, row, index) {
|
|
108
|
+
if (row.defaultSeverity === undefined) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const severity = String(row.defaultSeverity).trim();
|
|
112
|
+
if (!SEVERITIES.has(severity)) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`evidenceKinds[${index}].defaultSeverity must be one of: ${[...SEVERITIES].join(', ')}`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
payload.defaultSeverity = severity;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {Object} target
|
|
122
|
+
* @param {object} source
|
|
123
|
+
* @param {string[]} fields
|
|
124
|
+
* @returns {void}
|
|
125
|
+
*/
|
|
126
|
+
function copyOptionalFields(target, source, fields) {
|
|
127
|
+
for (const field of fields) {
|
|
128
|
+
if (source[field] !== undefined) {
|
|
129
|
+
target[field] = source[field];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Map Controller evidence kind record to baseline-shaped JSON (domainKey → domain).
|
|
136
|
+
* @param {object} record
|
|
137
|
+
* @returns {Object}
|
|
138
|
+
*/
|
|
139
|
+
function mapEvidenceKindApiToFileRow(record) {
|
|
140
|
+
const row = {
|
|
141
|
+
key: record.key,
|
|
142
|
+
displayName: record.displayName,
|
|
143
|
+
domain: record.domainKey || record.domain,
|
|
144
|
+
purpose: record.purpose
|
|
145
|
+
};
|
|
146
|
+
if (record.description) row.description = record.description;
|
|
147
|
+
if (record.expectedUse) row.expectedUse = record.expectedUse;
|
|
148
|
+
if (record.defaultSeverity) row.defaultSeverity = record.defaultSeverity;
|
|
149
|
+
if (record.requiresApproval !== undefined) row.requiresApproval = record.requiresApproval;
|
|
150
|
+
if (record.sortOrder !== undefined) row.sortOrder = record.sortOrder;
|
|
151
|
+
if (record.metadata && typeof record.metadata === 'object') {
|
|
152
|
+
row.metadata = record.metadata;
|
|
153
|
+
}
|
|
154
|
+
return row;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @param {object} parsed
|
|
159
|
+
* @returns {void}
|
|
160
|
+
*/
|
|
161
|
+
function rejectBaselineCatalogShape(parsed) {
|
|
162
|
+
if (
|
|
163
|
+
parsed &&
|
|
164
|
+
typeof parsed === 'object' &&
|
|
165
|
+
Array.isArray(parsed.evidenceKinds) &&
|
|
166
|
+
!parsed.key
|
|
167
|
+
) {
|
|
168
|
+
throw new Error(
|
|
169
|
+
'File is a baseline catalog (evidenceKinds[]). ' +
|
|
170
|
+
'Use `aifabrix evidence-kind import --file <path>` to seed all entries, ' +
|
|
171
|
+
'or pass a single evidence kind object with key and displayName.'
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @param {string} filePath
|
|
178
|
+
* @returns {Object}
|
|
179
|
+
*/
|
|
180
|
+
function readEvidenceKindCreateFile(filePath) {
|
|
181
|
+
const parsed = loadEvidenceKindJson(filePath);
|
|
182
|
+
rejectBaselineCatalogShape(parsed);
|
|
183
|
+
return mapEvidenceKindFileToApiPayload(parsed, 0);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} filePath
|
|
188
|
+
* @returns {Object[]}
|
|
189
|
+
*/
|
|
190
|
+
function readEvidenceKindCatalogFile(filePath) {
|
|
191
|
+
const parsed = loadEvidenceKindJson(filePath);
|
|
192
|
+
let rows;
|
|
193
|
+
if (Array.isArray(parsed)) {
|
|
194
|
+
rows = parsed;
|
|
195
|
+
} else if (Array.isArray(parsed.evidenceKinds)) {
|
|
196
|
+
rows = parsed.evidenceKinds;
|
|
197
|
+
} else {
|
|
198
|
+
throw new Error(
|
|
199
|
+
'Import file must be a baseline catalog with evidenceKinds[] or a JSON array of evidence kinds.'
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
if (rows.length === 0) {
|
|
203
|
+
throw new Error('Import file contains no evidence kinds');
|
|
204
|
+
}
|
|
205
|
+
return rows.map((row, index) => mapEvidenceKindFileToApiPayload(row, index));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @param {string} filePath
|
|
210
|
+
* @param {Object[]} rows
|
|
211
|
+
* @param {string} [version]
|
|
212
|
+
* @returns {void}
|
|
213
|
+
*/
|
|
214
|
+
function writeEvidenceKindCatalogFile(filePath, rows, version = '1.0.0') {
|
|
215
|
+
const p = path.resolve(String(filePath || '').trim());
|
|
216
|
+
if (!p) {
|
|
217
|
+
throw new Error('--file is required');
|
|
218
|
+
}
|
|
219
|
+
const catalog = { version, evidenceKinds: rows };
|
|
220
|
+
writeFileSync(p, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
module.exports = {
|
|
224
|
+
mapEvidenceKindFileToApiPayload,
|
|
225
|
+
mapEvidenceKindApiToFileRow,
|
|
226
|
+
readEvidenceKindCreateFile,
|
|
227
|
+
readEvidenceKindCatalogFile,
|
|
228
|
+
writeEvidenceKindCatalogFile,
|
|
229
|
+
SEVERITIES
|
|
230
|
+
};
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
11
|
const path = require('path');
|
|
12
|
-
const { existsSync, readFileSync } = require('../internal/fs-real-sync');
|
|
12
|
+
const { existsSync, readFileSync, writeFileSync } = require('../internal/fs-real-sync');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @typedef {Object} ResourceTypeCreateInput
|
|
@@ -19,6 +19,7 @@ const { existsSync, readFileSync } = require('../internal/fs-real-sync');
|
|
|
19
19
|
* @property {string} [category]
|
|
20
20
|
* @property {string} [defaultRiskLevel]
|
|
21
21
|
* @property {string} [status]
|
|
22
|
+
* @property {string} domain
|
|
22
23
|
*/
|
|
23
24
|
|
|
24
25
|
const CATEGORIES = new Set([
|
|
@@ -32,6 +33,7 @@ const CATEGORIES = new Set([
|
|
|
32
33
|
|
|
33
34
|
const RISK_LEVELS = new Set(['low', 'medium', 'high', 'critical']);
|
|
34
35
|
const STATUSES = new Set(['draft', 'active', 'deprecated', 'retired']);
|
|
36
|
+
const DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
35
37
|
|
|
36
38
|
/**
|
|
37
39
|
* @param {string} filePath
|
|
@@ -75,6 +77,25 @@ function applyOptionalEnumField(parsed, field, allowedValues, label) {
|
|
|
75
77
|
parsed[field] = value;
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
/**
|
|
81
|
+
* @param {object} entry
|
|
82
|
+
* @param {number} index
|
|
83
|
+
* @returns {void}
|
|
84
|
+
*/
|
|
85
|
+
function applyRequiredDomainField(entry, index) {
|
|
86
|
+
const raw = entry.domain;
|
|
87
|
+
const value = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
|
|
88
|
+
if (!value) {
|
|
89
|
+
throw new Error(`resourceTypes[${index}].domain is required`);
|
|
90
|
+
}
|
|
91
|
+
if (!DOMAIN_KEY_PATTERN.test(value)) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens'
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
entry.domain = value;
|
|
97
|
+
}
|
|
98
|
+
|
|
78
99
|
/**
|
|
79
100
|
* @param {object} parsed
|
|
80
101
|
* @returns {void}
|
|
@@ -102,6 +123,7 @@ function normalizeResourceTypeCreateRow(row, index) {
|
|
|
102
123
|
applyOptionalEnumField(entry, 'category', CATEGORIES, 'category');
|
|
103
124
|
applyOptionalEnumField(entry, 'defaultRiskLevel', RISK_LEVELS, 'defaultRiskLevel');
|
|
104
125
|
applyOptionalEnumField(entry, 'status', STATUSES, 'status');
|
|
126
|
+
applyRequiredDomainField(entry, index);
|
|
105
127
|
const key = String(entry.key || '').trim();
|
|
106
128
|
if (!key) {
|
|
107
129
|
throw new Error(`resourceTypes[${index}].key is required`);
|
|
@@ -150,9 +172,44 @@ function readResourceTypeCatalogFile(filePath) {
|
|
|
150
172
|
return rows.map((row, index) => normalizeResourceTypeCreateRow(row, index));
|
|
151
173
|
}
|
|
152
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Map Controller resource type record to baseline-shaped JSON.
|
|
177
|
+
* @param {object} record
|
|
178
|
+
* @returns {Object}
|
|
179
|
+
*/
|
|
180
|
+
function mapResourceTypeApiToFileRow(record) {
|
|
181
|
+
const row = {
|
|
182
|
+
key: record.key,
|
|
183
|
+
displayName: record.displayName,
|
|
184
|
+
domain: record.domain
|
|
185
|
+
};
|
|
186
|
+
if (record.description) row.description = record.description;
|
|
187
|
+
if (record.category) row.category = record.category;
|
|
188
|
+
if (record.defaultRiskLevel) row.defaultRiskLevel = record.defaultRiskLevel;
|
|
189
|
+
if (record.status) row.status = record.status;
|
|
190
|
+
return row;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @param {string} filePath
|
|
195
|
+
* @param {Object[]} rows - baseline-shaped resource type rows
|
|
196
|
+
* @param {string} [version]
|
|
197
|
+
* @returns {void}
|
|
198
|
+
*/
|
|
199
|
+
function writeResourceTypeCatalogFile(filePath, rows, version = '1.0.0') {
|
|
200
|
+
const p = path.resolve(String(filePath || '').trim());
|
|
201
|
+
if (!p) {
|
|
202
|
+
throw new Error('--file is required');
|
|
203
|
+
}
|
|
204
|
+
const catalog = { version, resourceTypes: rows };
|
|
205
|
+
writeFileSync(p, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
|
|
206
|
+
}
|
|
207
|
+
|
|
153
208
|
module.exports = {
|
|
154
209
|
readResourceTypeCreateFile,
|
|
155
210
|
readResourceTypeCatalogFile,
|
|
211
|
+
mapResourceTypeApiToFileRow,
|
|
212
|
+
writeResourceTypeCatalogFile,
|
|
156
213
|
CATEGORIES,
|
|
157
214
|
RISK_LEVELS,
|
|
158
215
|
STATUSES
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role catalog file helpers for create/import/export.
|
|
3
|
+
*
|
|
4
|
+
* File JSON uses `domain`; Controller API uses `domainKey`.
|
|
5
|
+
* Compiler fields nest under `metadata` on the API payload.
|
|
6
|
+
*
|
|
7
|
+
* @fileoverview Role catalog file parsing and API mapping
|
|
8
|
+
* @author AI Fabrix Team
|
|
9
|
+
* @version 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { existsSync, readFileSync, writeFileSync } = require('../internal/fs-real-sync');
|
|
16
|
+
|
|
17
|
+
/** Compiler fields that live top-level in baseline JSON and under metadata in the API. */
|
|
18
|
+
const ROLE_COMPILER_FIELDS = [
|
|
19
|
+
'defaultResourceType',
|
|
20
|
+
'primaryResourceTypes',
|
|
21
|
+
'defaultCapability',
|
|
22
|
+
'defaultCapabilities',
|
|
23
|
+
'defaultKnowledgeProfiles',
|
|
24
|
+
'defaultEvidenceKinds',
|
|
25
|
+
'defaultKnowledgeKeys',
|
|
26
|
+
'defaultKnowledgeGenerationProfiles'
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
const DOMAIN_KEY_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {string} filePath
|
|
33
|
+
* @returns {object|Array}
|
|
34
|
+
*/
|
|
35
|
+
function loadRoleJson(filePath) {
|
|
36
|
+
const p = path.resolve(String(filePath || '').trim());
|
|
37
|
+
if (!p) {
|
|
38
|
+
throw new Error('--file is required');
|
|
39
|
+
}
|
|
40
|
+
if (!existsSync(p)) {
|
|
41
|
+
throw new Error(`File not found: ${p}`);
|
|
42
|
+
}
|
|
43
|
+
let parsed;
|
|
44
|
+
try {
|
|
45
|
+
parsed = JSON.parse(readFileSync(p, 'utf8'));
|
|
46
|
+
} catch (e) {
|
|
47
|
+
throw new Error(`Invalid JSON in ${p}: ${e.message}`);
|
|
48
|
+
}
|
|
49
|
+
if (parsed === null || typeof parsed !== 'object') {
|
|
50
|
+
throw new Error(`Role file must be a JSON object or array: ${p}`);
|
|
51
|
+
}
|
|
52
|
+
return parsed;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {object} entry
|
|
57
|
+
* @param {number} index
|
|
58
|
+
* @returns {string}
|
|
59
|
+
*/
|
|
60
|
+
function requireDomainValue(entry, index) {
|
|
61
|
+
const raw = entry.domain !== undefined ? entry.domain : entry.domainKey;
|
|
62
|
+
const value = typeof raw === 'string' ? raw.trim().toLowerCase() : '';
|
|
63
|
+
if (!value) {
|
|
64
|
+
throw new Error(`roles[${index}].domain is required`);
|
|
65
|
+
}
|
|
66
|
+
if (!DOMAIN_KEY_PATTERN.test(value)) {
|
|
67
|
+
throw new Error(
|
|
68
|
+
'domain must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens'
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Map baseline/file role row to Controller create payload (domain → domainKey; compiler → metadata).
|
|
76
|
+
* @param {object} row
|
|
77
|
+
* @param {number} [index]
|
|
78
|
+
* @returns {Object}
|
|
79
|
+
*/
|
|
80
|
+
function mapRoleFileToApiPayload(row, index = 0) {
|
|
81
|
+
if (!row || typeof row !== 'object') {
|
|
82
|
+
throw new Error(`roles[${index}] must be a JSON object`);
|
|
83
|
+
}
|
|
84
|
+
const key = String(row.key || '').trim();
|
|
85
|
+
if (!key) {
|
|
86
|
+
throw new Error(`roles[${index}].key is required`);
|
|
87
|
+
}
|
|
88
|
+
const displayName = String(row.displayName || '').trim();
|
|
89
|
+
if (!displayName) {
|
|
90
|
+
throw new Error(`roles[${index}].displayName is required`);
|
|
91
|
+
}
|
|
92
|
+
const domainKey = requireDomainValue(row, index);
|
|
93
|
+
const metadata = collectRoleCompilerMetadata(row);
|
|
94
|
+
const payload = { key, displayName, domainKey };
|
|
95
|
+
copyOptionalFields(payload, row, ['description', 'purpose', 'businessOutcome', 'isActive', 'source']);
|
|
96
|
+
if (Object.keys(metadata).length > 0) {
|
|
97
|
+
payload.metadata = metadata;
|
|
98
|
+
}
|
|
99
|
+
return payload;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {object} row
|
|
104
|
+
* @returns {Object}
|
|
105
|
+
*/
|
|
106
|
+
function collectRoleCompilerMetadata(row) {
|
|
107
|
+
const metadata = {
|
|
108
|
+
...(row.metadata && typeof row.metadata === 'object' ? row.metadata : {})
|
|
109
|
+
};
|
|
110
|
+
for (const field of ROLE_COMPILER_FIELDS) {
|
|
111
|
+
if (row[field] !== undefined) {
|
|
112
|
+
metadata[field] = row[field];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return metadata;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {Object} target
|
|
120
|
+
* @param {object} source
|
|
121
|
+
* @param {string[]} fields
|
|
122
|
+
* @returns {void}
|
|
123
|
+
*/
|
|
124
|
+
function copyOptionalFields(target, source, fields) {
|
|
125
|
+
for (const field of fields) {
|
|
126
|
+
if (source[field] !== undefined) {
|
|
127
|
+
target[field] = source[field];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Map Controller role record to baseline-shaped JSON (domainKey → domain; flatten compiler metadata).
|
|
134
|
+
* @param {object} record
|
|
135
|
+
* @returns {Object}
|
|
136
|
+
*/
|
|
137
|
+
function mapRoleApiToFileRow(record) {
|
|
138
|
+
const row = {
|
|
139
|
+
key: record.key,
|
|
140
|
+
displayName: record.displayName,
|
|
141
|
+
domain: record.domainKey || record.domain
|
|
142
|
+
};
|
|
143
|
+
if (record.description) row.description = record.description;
|
|
144
|
+
if (record.purpose) row.purpose = record.purpose;
|
|
145
|
+
if (record.businessOutcome) row.businessOutcome = record.businessOutcome;
|
|
146
|
+
const meta = record.metadata && typeof record.metadata === 'object' ? { ...record.metadata } : {};
|
|
147
|
+
for (const field of ROLE_COMPILER_FIELDS) {
|
|
148
|
+
if (meta[field] !== undefined) {
|
|
149
|
+
row[field] = meta[field];
|
|
150
|
+
delete meta[field];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (Object.keys(meta).length > 0) {
|
|
154
|
+
row.metadata = meta;
|
|
155
|
+
}
|
|
156
|
+
return row;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @param {object} parsed
|
|
161
|
+
* @returns {void}
|
|
162
|
+
*/
|
|
163
|
+
function rejectBaselineCatalogShape(parsed) {
|
|
164
|
+
if (parsed && typeof parsed === 'object' && Array.isArray(parsed.roles) && !parsed.key) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
'File is a baseline catalog (roles[]). ' +
|
|
167
|
+
'Use `aifabrix role import --file <path>` to seed all entries, ' +
|
|
168
|
+
'or pass a single role object with key and displayName.'
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @param {string} filePath
|
|
175
|
+
* @returns {Object}
|
|
176
|
+
*/
|
|
177
|
+
function readRoleCreateFile(filePath) {
|
|
178
|
+
const parsed = loadRoleJson(filePath);
|
|
179
|
+
rejectBaselineCatalogShape(parsed);
|
|
180
|
+
return mapRoleFileToApiPayload(parsed, 0);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* @param {string} filePath
|
|
185
|
+
* @returns {Object[]}
|
|
186
|
+
*/
|
|
187
|
+
function readRoleCatalogFile(filePath) {
|
|
188
|
+
const parsed = loadRoleJson(filePath);
|
|
189
|
+
let rows;
|
|
190
|
+
if (Array.isArray(parsed)) {
|
|
191
|
+
rows = parsed;
|
|
192
|
+
} else if (Array.isArray(parsed.roles)) {
|
|
193
|
+
rows = parsed.roles;
|
|
194
|
+
} else {
|
|
195
|
+
throw new Error(
|
|
196
|
+
'Import file must be a baseline catalog with roles[] or a JSON array of roles.'
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
if (rows.length === 0) {
|
|
200
|
+
throw new Error('Import file contains no roles');
|
|
201
|
+
}
|
|
202
|
+
return rows.map((row, index) => mapRoleFileToApiPayload(row, index));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* @param {string} filePath
|
|
207
|
+
* @param {Object[]} rows - baseline-shaped role rows
|
|
208
|
+
* @param {string} [version]
|
|
209
|
+
* @returns {void}
|
|
210
|
+
*/
|
|
211
|
+
function writeRoleCatalogFile(filePath, rows, version = '1.0.0') {
|
|
212
|
+
const p = path.resolve(String(filePath || '').trim());
|
|
213
|
+
if (!p) {
|
|
214
|
+
throw new Error('--file is required');
|
|
215
|
+
}
|
|
216
|
+
const catalog = { version, roles: rows };
|
|
217
|
+
writeFileSync(p, `${JSON.stringify(catalog, null, 2)}\n`, 'utf8');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
module.exports = {
|
|
221
|
+
ROLE_COMPILER_FIELDS,
|
|
222
|
+
mapRoleFileToApiPayload,
|
|
223
|
+
mapRoleApiToFileRow,
|
|
224
|
+
readRoleCreateFile,
|
|
225
|
+
readRoleCatalogFile,
|
|
226
|
+
writeRoleCatalogFile
|
|
227
|
+
};
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"key": "application-schema",
|
|
8
8
|
"name": "Application Configuration Schema",
|
|
9
9
|
"description": "JSON schema for validating AI Fabrix application configuration files",
|
|
10
|
-
"version": "1.
|
|
10
|
+
"version": "1.5.0",
|
|
11
11
|
"type": "schema",
|
|
12
12
|
"category": "infrastructure",
|
|
13
13
|
"author": "AI Fabrix Team",
|
|
14
14
|
"createdAt": "2024-01-01T00:00:00Z",
|
|
15
|
-
"updatedAt": "2026-
|
|
15
|
+
"updatedAt": "2026-07-21T00:00:00Z",
|
|
16
16
|
"compatibility": {
|
|
17
17
|
"minVersion": "1.0.0",
|
|
18
18
|
"maxVersion": "2.0.0",
|
|
@@ -30,6 +30,14 @@
|
|
|
30
30
|
"external-datasource.schema.json"
|
|
31
31
|
],
|
|
32
32
|
"changelog": [
|
|
33
|
+
{
|
|
34
|
+
"version": "1.5.0",
|
|
35
|
+
"date": "2026-07-21T00:00:00Z",
|
|
36
|
+
"changes": [
|
|
37
|
+
"Added optional configuration[].category (and conditionalConfiguration item category) for portal UI grouping labels in Miso Configuration tab."
|
|
38
|
+
],
|
|
39
|
+
"breaking": false
|
|
40
|
+
},
|
|
33
41
|
{
|
|
34
42
|
"version": "1.4.0",
|
|
35
43
|
"date": "2026-04-06T00:00:00Z",
|
|
@@ -203,6 +211,12 @@
|
|
|
203
211
|
"type": "boolean",
|
|
204
212
|
"description": "Whether this configuration is required"
|
|
205
213
|
},
|
|
214
|
+
"category": {
|
|
215
|
+
"type": "string",
|
|
216
|
+
"description": "Optional UI grouping label for portal/deployment wizard Configuration tab",
|
|
217
|
+
"minLength": 1,
|
|
218
|
+
"maxLength": 100
|
|
219
|
+
},
|
|
206
220
|
"portalInput": {
|
|
207
221
|
"type": "object",
|
|
208
222
|
"description": "Portal input configuration for user-provided values",
|
|
@@ -315,6 +329,12 @@
|
|
|
315
329
|
"type": "boolean",
|
|
316
330
|
"description": "Whether this configuration is required"
|
|
317
331
|
},
|
|
332
|
+
"category": {
|
|
333
|
+
"type": "string",
|
|
334
|
+
"description": "Optional UI grouping label for portal/deployment wizard Configuration tab",
|
|
335
|
+
"minLength": 1,
|
|
336
|
+
"maxLength": 100
|
|
337
|
+
},
|
|
318
338
|
"portalInput": {
|
|
319
339
|
"type": "object",
|
|
320
340
|
"description": "Portal input configuration for user-provided values",
|