@aifabrix/builder 2.53.1 → 2.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/bin/aifabrix.js +2 -2
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +130 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +239 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/assistants.api.js +8 -5
- package/lib/api/channel-identity.api.js +41 -0
- package/lib/api/evidence-authoring.api.js +5 -1
- package/lib/api/evidence.api.js +2 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/types/evidence.types.js +2 -0
- package/lib/api/work-search.api.js +163 -0
- package/lib/api/work.api.js +19 -12
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +164 -126
- package/lib/channels/approval-guides/chatgpt.js +14 -18
- package/lib/channels/approval-guides/claude.js +29 -0
- package/lib/channels/approval-guides/index.js +88 -22
- package/lib/channels/approval-guides/mcp-client.js +27 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
- package/lib/channels/approval-guides/slack.js +10 -10
- package/lib/channels/approval-guides/teams-bot.js +8 -12
- package/lib/channels/channel-add-continuations.js +91 -0
- package/lib/channels/channel-add-ensure.js +124 -27
- package/lib/channels/channel-add-existing.js +160 -28
- package/lib/channels/channel-add-failure.js +61 -0
- package/lib/channels/channel-add-remaining.js +492 -0
- package/lib/channels/channel-add-tty.js +190 -0
- package/lib/channels/channel-add-wizard-config.js +138 -0
- package/lib/channels/channel-add-wizard.js +250 -0
- package/lib/channels/channel-artifact-generator.js +27 -13
- package/lib/channels/channel-cardinality.js +83 -0
- package/lib/channels/channel-catalog-icon.js +45 -0
- package/lib/channels/channel-cli-instructions.js +75 -0
- package/lib/channels/channel-configuration-map.js +213 -0
- package/lib/channels/channel-credential.js +11 -14
- package/lib/channels/channel-definition-project.js +101 -0
- package/lib/channels/channel-definition-registry.js +154 -0
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +60 -2
- package/lib/channels/channel-discovery.js +16 -2
- package/lib/channels/channel-external-system.js +86 -9
- package/lib/channels/channel-install-envelope-actions.js +88 -0
- package/lib/channels/channel-install-envelope-microsoft.js +155 -0
- package/lib/channels/channel-install-envelope.js +358 -0
- package/lib/channels/channel-install-help-md.js +172 -0
- package/lib/channels/channel-install-http-payload.js +62 -0
- package/lib/channels/channel-install-inventory.js +115 -0
- package/lib/channels/channel-install-profiles.js +90 -0
- package/lib/channels/channel-instance-collision.js +118 -0
- package/lib/channels/channel-instance-key.js +100 -0
- package/lib/channels/channel-instance-materialize.js +240 -0
- package/lib/channels/channel-integration-generator.js +18 -9
- package/lib/channels/channel-integration-template.js +101 -22
- package/lib/channels/channel-inventory-fetch.js +79 -0
- package/lib/channels/channel-oauth-preflight.js +104 -0
- package/lib/channels/channel-package-version.js +76 -0
- package/lib/channels/channel-predefined-client.js +154 -0
- package/lib/channels/channel-probe.js +7 -2
- package/lib/channels/channel-runtime-resolver.js +194 -72
- package/lib/channels/channel-status-display.js +86 -16
- package/lib/channels/channel-targets.js +132 -92
- package/lib/channels/chatgpt-callback.js +318 -0
- package/lib/channels/chatgpt-channel-add.js +229 -0
- package/lib/channels/chatgpt-preflight.js +396 -0
- package/lib/channels/chatgpt-runtime-contract.js +17 -0
- package/lib/channels/chatgpt-setup-values.js +124 -0
- package/lib/channels/claude-callback.js +67 -0
- package/lib/channels/claude-channel-add.js +254 -0
- package/lib/channels/claude-runtime-contract.js +40 -0
- package/lib/channels/claude-runtime.js +58 -0
- package/lib/channels/claude-setup-values.js +92 -0
- package/lib/channels/mcp-client/config-merge.js +148 -0
- package/lib/channels/mcp-client/ensure-client.js +231 -0
- package/lib/channels/mcp-client/paths.js +53 -0
- package/lib/channels/mcp-client/profiles.js +122 -0
- package/lib/channels/mcp-client/redirect-uris.js +99 -0
- package/lib/channels/mcp-client/runtime.js +59 -0
- package/lib/channels/mcp-client-channel-add.js +186 -0
- package/lib/channels/microsoft-copilot-channel-add.js +117 -7
- package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
- package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
- package/lib/channels/microsoft-copilot-package-prior.js +107 -0
- package/lib/channels/microsoft-copilot-package.js +29 -28
- package/lib/channels/microsoft-provisioning/a365.js +80 -0
- package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
- package/lib/channels/microsoft-provisioning/auth.js +179 -0
- package/lib/channels/microsoft-provisioning/cli.js +71 -0
- package/lib/channels/microsoft-provisioning/constants.js +75 -0
- package/lib/channels/microsoft-provisioning/errors.js +117 -0
- package/lib/channels/microsoft-provisioning/index.js +55 -0
- package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
- package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
- package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
- package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
- package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
- package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
- package/lib/channels/microsoft-provisioning/persist.js +110 -0
- package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
- package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
- package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
- package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
- package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
- package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
- package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
- package/lib/channels/runtime-tool-catalog.js +5 -2
- package/lib/channels/slack-channel-add-portal.js +130 -0
- package/lib/channels/slack-channel-add-tty-auth.js +95 -0
- package/lib/channels/slack-channel-add.js +311 -0
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/apps.js +181 -0
- package/lib/channels/slack-provisioning/auth-store.js +110 -0
- package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
- package/lib/channels/slack-provisioning/auth.js +115 -0
- package/lib/channels/slack-provisioning/callbacks.js +41 -0
- package/lib/channels/slack-provisioning/cli.js +226 -0
- package/lib/channels/slack-provisioning/constants.js +37 -0
- package/lib/channels/slack-provisioning/credentials.js +169 -0
- package/lib/channels/slack-provisioning/curl-shim.js +132 -0
- package/lib/channels/slack-provisioning/developer-install.js +118 -0
- package/lib/channels/slack-provisioning/env-file.js +120 -0
- package/lib/channels/slack-provisioning/errors.js +47 -0
- package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
- package/lib/channels/slack-provisioning/index.js +250 -0
- package/lib/channels/slack-provisioning/install-cli.js +335 -0
- package/lib/channels/slack-provisioning/manifest.js +89 -0
- package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
- package/lib/channels/slack-provisioning/offer-cli.js +113 -0
- package/lib/channels/slack-provisioning/onboard-members.js +122 -0
- package/lib/channels/slack-provisioning/onboard.js +89 -0
- package/lib/channels/slack-provisioning/persist.js +95 -0
- package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
- package/lib/channels/slack-provisioning/with-curl-on-path.js +53 -0
- package/lib/channels/teams-bot-channel-add.js +94 -0
- package/lib/channels/vendor-dataplane-url.js +249 -0
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +5 -1
- package/lib/cli/setup-external-system-help.js +2 -0
- package/lib/cli/setup-external-system.js +1 -1
- package/lib/commands/agent-kit-help.js +79 -0
- package/lib/commands/agent-kit.js +346 -0
- package/lib/commands/channel-add-help.js +366 -0
- package/lib/commands/channel-add-setup.js +162 -80
- package/lib/commands/channel-configure.js +118 -0
- package/lib/commands/channel.js +10 -1
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/governance-upload-external.js +6 -3
- package/lib/commands/lifecycle-command-action.js +2 -5
- package/lib/commands/lifecycle-external.js +93 -21
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-datasource-test-payload.js +4 -2
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
- package/lib/commands/repair-datasource.js +3 -0
- package/lib/commands/repair-external-run.js +59 -25
- package/lib/commands/repair-openapi-rest-runtime.js +127 -0
- package/lib/commands/repair-orchestration-tag-merge.js +339 -0
- package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
- package/lib/commands/repair-rbac-platform-preset.js +26 -15
- package/lib/commands/repair-rbac-reader-roles.js +8 -21
- package/lib/commands/repair-rbac.js +26 -44
- package/lib/commands/repair-system-permissions.js +24 -22
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +22 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +150 -43
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-e2e-external.js +148 -21
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-credential-push-log.js +2 -1
- package/lib/commands/upload-publish-context.js +1 -1
- package/lib/commands/upload-role-assistant-shell.js +124 -0
- package/lib/commands/upload-sidecar-followups.js +10 -4
- package/lib/commands/upload.js +18 -3
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/core/secrets-docker-env.js +4 -1
- package/lib/core/secrets-env-content.js +17 -3
- package/lib/datasource/capability/capability-manifest.js +0 -3
- package/lib/datasource/capability/copy-test-payload.js +3 -0
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy-helpers.js +26 -1
- package/lib/external-system/deploy.js +22 -8
- package/lib/external-system/download-helpers.js +29 -2
- package/lib/external-system/download-role-assistant.js +109 -4
- package/lib/external-system/download.js +46 -30
- package/lib/external-system/sync-deploy-manifest.js +3 -2
- package/lib/external-system/upload-identity.js +42 -0
- package/lib/generator/index.js +19 -15
- package/lib/generator/split.js +13 -2
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +229 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +181 -0
- package/lib/lifecycle/scenario-upload.js +181 -30
- package/lib/programmatic/builder-api-cors.js +143 -0
- package/lib/programmatic/builder-api-request.js +6 -0
- package/lib/programmatic/builder-api-route-dispatch.js +56 -42
- package/lib/programmatic/builder-api-server.js +8 -1
- package/lib/programmatic/capability-registry.js +55 -0
- package/lib/programmatic/channel-install-help-resolve.js +359 -0
- package/lib/programmatic/channel-install-session.js +218 -0
- package/lib/programmatic/help-content/channel-onboarding.md +2 -0
- package/lib/programmatic/help-content/cip-overview.md +3 -1
- package/lib/programmatic/http-raw-response.js +62 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +289 -0
- package/lib/programmatic/openapi-component-schemas.js +19 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +80 -3
- package/lib/programmatic/openapi-envelope-examples.js +124 -0
- package/lib/programmatic/openapi-operation-bindings.js +9 -1
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +319 -0
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +13 -8
- package/lib/programmatic/platform-rbac-catalog.js +36 -18
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +58 -1
- package/lib/programmatic/route-handlers-context.js +2 -1
- package/lib/programmatic/run-auth-permissions.js +54 -0
- package/lib/programmatic/run-channel-catalog.js +238 -0
- package/lib/programmatic/run-channel-install-artifacts.js +137 -0
- package/lib/programmatic/run-channel-install-copilot.js +353 -0
- package/lib/programmatic/run-channel-install-options.js +236 -0
- package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
- package/lib/programmatic/run-channel-install.js +346 -0
- package/lib/programmatic/run-channel-package.js +87 -7
- package/lib/programmatic/run-download.js +41 -0
- package/lib/programmatic/workspace-context.js +2 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/evidence-sync.js +4 -2
- package/lib/role-assistant/evidence-validation-issues.js +51 -0
- package/lib/role-assistant/knowledge-sync.js +10 -4
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/settings.js +49 -2
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +159 -24
- package/lib/role-assistant/test-cases-evidence.js +175 -0
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +291 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +247 -0
- package/lib/role-assistant/test-cases.js +71 -172
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +164 -0
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
- package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
- package/lib/role-assistant/test-runner-workhub.js +74 -32
- package/lib/role-assistant/test-runner.js +66 -11
- package/lib/schema/external-datasource.schema.json +146 -21
- package/lib/schema/external-system.schema.json +177 -2
- package/lib/schema/mcp-client-profile.schema.json +103 -0
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/app-path-resolve.js +4 -0
- package/lib/utils/authentication-env-template.js +44 -6
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/credential-secrets-env.js +6 -1
- package/lib/utils/env-copy.js +19 -7
- package/lib/utils/external-env-template.js +20 -2
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/paths.js +18 -1
- package/lib/utils/platform-shell-package.js +69 -0
- package/lib/utils/port-resolver.js +50 -1
- package/lib/utils/rewrite-name-flag.js +20 -0
- package/lib/utils/role-assistant-paths.js +13 -10
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/schema-resolver.js +11 -1
- package/lib/utils/secrets-helpers.js +12 -21
- package/lib/utils/token-manager.js +10 -5
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +41 -0
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +83 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +58 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +50 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +42 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +78 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/builder-api/env.template +7 -0
- package/templates/applications/dataplane/application.yaml +6 -5
- package/templates/applications/dataplane/env.template +2 -2
- package/templates/applications/dataplane/rbac.yaml +35 -2
- package/templates/applications/keycloak/Dockerfile +30 -4
- package/templates/applications/keycloak/application.yaml +2 -2
- package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
- package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
- package/templates/applications/keycloak/env.template +3 -0
- package/templates/applications/miso-controller/application.yaml +1 -2
- package/templates/applications/miso-controller/env.template +10 -9
- package/templates/channels/README.md +5 -5
- package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
- package/templates/channels/chatgpt/channel.json +59 -0
- package/templates/channels/chatgpt/icon.svg +1 -0
- package/templates/channels/chatgpt/install.template.md.hbs +20 -95
- package/templates/channels/chatgpt/integration/README.md +1 -1
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
- package/templates/channels/chatgpt/integration/env.template +2 -4
- package/templates/channels/chatgpt/integration/rbac.json +13 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +44 -0
- package/templates/channels/claude/channel.json +59 -0
- package/templates/channels/claude/icon.svg +1 -0
- package/templates/channels/claude/install.template.md.hbs +22 -0
- package/templates/channels/claude/integration/README.md +14 -0
- package/templates/channels/claude/integration/application.json +15 -0
- package/templates/channels/claude/integration/claude-system.json +59 -0
- package/templates/channels/claude/integration/env.template +2 -0
- package/templates/channels/claude/integration/rbac.json +13 -0
- package/templates/channels/claude/manifest.template.json.hbs +40 -0
- package/templates/channels/mcp-client/channel.json +72 -0
- package/templates/channels/mcp-client/icon.svg +1 -0
- package/templates/channels/mcp-client/install.template.md.hbs +24 -0
- package/templates/channels/mcp-client/integration/README.md +13 -0
- package/templates/channels/mcp-client/integration/application.json +15 -0
- package/templates/channels/mcp-client/integration/env.template +2 -0
- package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
- package/templates/channels/mcp-client/integration/rbac.json +13 -0
- package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
- package/templates/channels/mcp-client/profiles/cursor.json +26 -0
- package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
- package/templates/channels/mcp-client/profiles/vscode.json +29 -0
- package/templates/channels/microsoft-copilot/channel.json +73 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
- package/templates/channels/microsoft-copilot/icon.svg +1 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
- package/templates/channels/microsoft-copilot/integration/README.md +1 -1
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +3 -6
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
- package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
- package/templates/channels/slack/channel.json +234 -0
- package/templates/channels/slack/icon.svg +1 -0
- package/templates/channels/slack/install.template.md.hbs +45 -28
- package/templates/channels/slack/integration/README.md +245 -22
- package/templates/channels/slack/integration/application.json +44 -7
- package/templates/channels/slack/integration/env.template +15 -6
- package/templates/channels/slack/integration/openapi/openapi.json +126 -0
- package/templates/channels/slack/integration/rbac.json +84 -0
- package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
- package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
- package/templates/channels/slack/integration/slack-system.json +161 -72
- package/templates/channels/slack/manifest.template.json.hbs +10 -4
- package/templates/channels/teams-bot/channel.json +162 -0
- package/templates/channels/teams-bot/icon.svg +1 -0
- package/templates/channels/teams-bot/install.template.md.hbs +12 -13
- package/templates/channels/teams-bot/integration/README.md +5 -4
- package/templates/channels/teams-bot/integration/application.json +6 -4
- package/templates/channels/teams-bot/integration/env.template +5 -4
- package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
- package/templates/channels/teams-bot/integration/rbac.json +21 -0
- package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
- package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
- package/templates/channels/web-embed/channel.json +60 -0
- package/templates/channels/web-embed/install.template.md.hbs +1 -1
- package/templates/channels/web-embed/integration/README.md +2 -2
- package/templates/channels/web-embed/integration/application.json +2 -2
- package/templates/channels/web-embed/integration/env.template +1 -1
- package/templates/channels/web-embed/integration/rbac.json +13 -0
- package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
|
@@ -12,6 +12,7 @@ const fs = require('../internal/fs-real-sync');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const { ensureIntegrationDirectory } = require('./workspace-context');
|
|
14
14
|
const { resolveChannelRuntimeValues } = require('../channels/channel-runtime-resolver');
|
|
15
|
+
const { vendorFacingUrlsFromCtx } = require('../channels/vendor-dataplane-url');
|
|
15
16
|
const { generateChannelArtifact } = require('../channels/channel-artifact-generator');
|
|
16
17
|
const { loadChannelPackageContext } = require('../channels/channel-discovery');
|
|
17
18
|
const {
|
|
@@ -20,6 +21,10 @@ const {
|
|
|
20
21
|
mergeChannelBranding
|
|
21
22
|
} = require('../channels/channel-branding');
|
|
22
23
|
const { isChannelTargetKey } = require('../channels/channel-targets');
|
|
24
|
+
const {
|
|
25
|
+
httpError,
|
|
26
|
+
readChannelInstallSessionForDefinition
|
|
27
|
+
} = require('./channel-install-session');
|
|
23
28
|
|
|
24
29
|
/**
|
|
25
30
|
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
@@ -43,6 +48,16 @@ function requireChannelTarget(systemKey) {
|
|
|
43
48
|
return systemKey;
|
|
44
49
|
}
|
|
45
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Catalog packaging key: instance paths (name slug) still read dist/channels/<catalog>/.
|
|
53
|
+
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
54
|
+
* @returns {string}
|
|
55
|
+
*/
|
|
56
|
+
function packagingChannelTarget(ctx) {
|
|
57
|
+
const { resolveInstallDefinitionKey } = require('./channel-install-help-resolve');
|
|
58
|
+
return requireChannelTarget(resolveInstallDefinitionKey(ctx));
|
|
59
|
+
}
|
|
60
|
+
|
|
46
61
|
/**
|
|
47
62
|
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
48
63
|
* @returns {{ type: string, token: string }}
|
|
@@ -82,8 +97,13 @@ function generatePackageArtifact(ctx, body, channelTarget, branding, dataplaneUr
|
|
|
82
97
|
branding.displayName || body.name || packageContext.displayName || channelTarget;
|
|
83
98
|
const description =
|
|
84
99
|
branding.description || body.description || packageContext.description || '';
|
|
100
|
+
const vendor = vendorFacingUrlsFromCtx({
|
|
101
|
+
...ctx,
|
|
102
|
+
dataplaneUrl
|
|
103
|
+
});
|
|
85
104
|
const runtimeValues = resolveChannelRuntimeValues({
|
|
86
|
-
dataplaneBaseUrl:
|
|
105
|
+
dataplaneBaseUrl: vendor.dataplaneBaseUrl,
|
|
106
|
+
controllerUrl: vendor.controllerUrl,
|
|
87
107
|
channelTarget,
|
|
88
108
|
appName,
|
|
89
109
|
baseName: body.baseName || appName,
|
|
@@ -91,6 +111,7 @@ function generatePackageArtifact(ctx, body, channelTarget, branding, dataplaneUr
|
|
|
91
111
|
appDescription: description,
|
|
92
112
|
layerBToolNames: packageContext.governedToolNames || [],
|
|
93
113
|
packageContext,
|
|
114
|
+
oauthPluginVaultReferenceId: body.oauthPluginVaultReferenceId,
|
|
94
115
|
iconColorPath: branding.iconColorPath,
|
|
95
116
|
iconOutlinePath: branding.iconOutlinePath
|
|
96
117
|
});
|
|
@@ -108,7 +129,7 @@ function generatePackageArtifact(ctx, body, channelTarget, branding, dataplaneUr
|
|
|
108
129
|
* @returns {Promise<Object>}
|
|
109
130
|
*/
|
|
110
131
|
async function buildChannelPackage(ctx, body = {}) {
|
|
111
|
-
const channelTarget =
|
|
132
|
+
const channelTarget = packagingChannelTarget(ctx);
|
|
112
133
|
ensureIntegrationDirectory(ctx);
|
|
113
134
|
const dir = workspaceSystemDir(ctx);
|
|
114
135
|
const branding = mergeChannelBranding(readChannelBranding(dir), body.branding || {});
|
|
@@ -151,7 +172,7 @@ async function buildChannelPackage(ctx, body = {}) {
|
|
|
151
172
|
* @returns {Object}
|
|
152
173
|
*/
|
|
153
174
|
function getChannelPackageSummary(ctx) {
|
|
154
|
-
const channelTarget =
|
|
175
|
+
const channelTarget = packagingChannelTarget(ctx);
|
|
155
176
|
const projectRoot = ctx.getUserRoot();
|
|
156
177
|
const summaryPath = path.join(
|
|
157
178
|
projectRoot,
|
|
@@ -161,7 +182,7 @@ function getChannelPackageSummary(ctx) {
|
|
|
161
182
|
`channel-${channelTarget}.json`
|
|
162
183
|
);
|
|
163
184
|
if (!fs.existsSync(summaryPath)) {
|
|
164
|
-
throw
|
|
185
|
+
throw httpError(`Channel package summary not found: ${summaryPath}`, 404);
|
|
165
186
|
}
|
|
166
187
|
const summary = JSON.parse(fs.readFileSync(summaryPath, 'utf8'));
|
|
167
188
|
return {
|
|
@@ -177,8 +198,8 @@ function getChannelPackageSummary(ctx) {
|
|
|
177
198
|
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
178
199
|
* @returns {{ fileName: string, contentType: string, byteLength: number, zipBase64: string }}
|
|
179
200
|
*/
|
|
180
|
-
function
|
|
181
|
-
const channelTarget =
|
|
201
|
+
function readChannelPackageZip(ctx) {
|
|
202
|
+
const channelTarget = packagingChannelTarget(ctx);
|
|
182
203
|
const summary = getChannelPackageSummary(ctx).summary;
|
|
183
204
|
const zipPath =
|
|
184
205
|
typeof summary?.links?.zip === 'string' && summary.links.zip
|
|
@@ -192,7 +213,7 @@ function getChannelPackageZip(ctx) {
|
|
|
192
213
|
`appPackage.${summary.environment || 'dev'}.zip`
|
|
193
214
|
);
|
|
194
215
|
if (!fs.existsSync(zipPath)) {
|
|
195
|
-
throw
|
|
216
|
+
throw httpError(`Channel package ZIP not found: ${zipPath}`, 404);
|
|
196
217
|
}
|
|
197
218
|
const buffer = fs.readFileSync(zipPath);
|
|
198
219
|
return {
|
|
@@ -203,6 +224,65 @@ function getChannelPackageZip(ctx) {
|
|
|
203
224
|
};
|
|
204
225
|
}
|
|
205
226
|
|
|
227
|
+
/**
|
|
228
|
+
* @param {Object|null} session
|
|
229
|
+
* @returns {Object}
|
|
230
|
+
*/
|
|
231
|
+
function packageBodyFromSession(session) {
|
|
232
|
+
if (!session || typeof session !== 'object') {
|
|
233
|
+
return {};
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
name: session.displayName || session.name,
|
|
237
|
+
oauthPluginVaultReferenceId: session.oauthPluginVaultReferenceId
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Portal ZIP GET must not 500 with CLI `--oauth-plugin-vault-reference-id` text.
|
|
243
|
+
* @param {unknown} err
|
|
244
|
+
* @returns {unknown}
|
|
245
|
+
*/
|
|
246
|
+
function mapCopilotPackageHttpError(err) {
|
|
247
|
+
if (err && err.statusCode) {
|
|
248
|
+
return err;
|
|
249
|
+
}
|
|
250
|
+
const msg = String((err && err.message) || '');
|
|
251
|
+
if (/oauth-plugin-vault-reference-id|OAuthPluginVault/i.test(msg)) {
|
|
252
|
+
return httpError(
|
|
253
|
+
'Copilot app package is not ready until Teams Entra SSO registration is stored on this install.',
|
|
254
|
+
409
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return err;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Rebuild the Copilot ZIP when the workspace lost dist/ after an image recreate.
|
|
262
|
+
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
263
|
+
* @returns {Promise<{ fileName: string, contentType: string, byteLength: number, zipBase64: string }>}
|
|
264
|
+
*/
|
|
265
|
+
async function getChannelPackageZip(ctx) {
|
|
266
|
+
let summaryMissing = false;
|
|
267
|
+
try {
|
|
268
|
+
getChannelPackageSummary(ctx);
|
|
269
|
+
} catch (err) {
|
|
270
|
+
if (!err || err.statusCode !== 404) {
|
|
271
|
+
throw mapCopilotPackageHttpError(err);
|
|
272
|
+
}
|
|
273
|
+
summaryMissing = true;
|
|
274
|
+
}
|
|
275
|
+
if (summaryMissing) {
|
|
276
|
+
try {
|
|
277
|
+
const session = readChannelInstallSessionForDefinition(ctx, packagingChannelTarget(ctx));
|
|
278
|
+
await buildChannelPackage(ctx, packageBodyFromSession(session));
|
|
279
|
+
} catch (err) {
|
|
280
|
+
throw mapCopilotPackageHttpError(err);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return readChannelPackageZip(ctx);
|
|
284
|
+
}
|
|
285
|
+
|
|
206
286
|
/**
|
|
207
287
|
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
208
288
|
* @param {Object} body
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Programmatic download wrapper — CLI download parity for builder-api.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview runDownload for POST /systems/:systemKey/download
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const { downloadExternalSystem } = require('../external-system/download');
|
|
12
|
+
const { runWithWorkspaceContext } = require('./workspace-context');
|
|
13
|
+
const { mergeProgrammaticOptions } = require('./command-options');
|
|
14
|
+
const { touchWorkspaceMeta } = require('./workspace-meta');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {import('./workspace-context').WorkspaceContext} ctx
|
|
18
|
+
* @param {Object} [options]
|
|
19
|
+
* @param {boolean} [options.force]
|
|
20
|
+
* @param {boolean} [options.dryRun]
|
|
21
|
+
* @param {string} [options.format]
|
|
22
|
+
* @returns {Promise<Object>}
|
|
23
|
+
*/
|
|
24
|
+
async function runDownload(ctx, options = {}) {
|
|
25
|
+
const merged = mergeProgrammaticOptions(ctx, options);
|
|
26
|
+
return runWithWorkspaceContext(ctx, async() => {
|
|
27
|
+
await downloadExternalSystem(ctx.systemKey, merged);
|
|
28
|
+
if (!options.dryRun) {
|
|
29
|
+
touchWorkspaceMeta(ctx, { lastOperation: 'download' });
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
downloaded: options.dryRun !== true,
|
|
33
|
+
dryRun: options.dryRun === true,
|
|
34
|
+
systemKey: ctx.systemKey
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
runDownload
|
|
41
|
+
};
|
|
@@ -51,6 +51,7 @@ function resolveWorkspaceRoot(segment) {
|
|
|
51
51
|
* @param {string} [params.environment]
|
|
52
52
|
* @param {string} [params.controllerUrl]
|
|
53
53
|
* @param {string} [params.dataplaneUrl]
|
|
54
|
+
* @param {string} [params.publicOrigin]
|
|
54
55
|
* @returns {WorkspaceContext}
|
|
55
56
|
*/
|
|
56
57
|
function createWorkspaceContext(params) {
|
|
@@ -88,6 +89,7 @@ function createWorkspaceContext(params) {
|
|
|
88
89
|
process.env.CONTROLLER_URL ||
|
|
89
90
|
'',
|
|
90
91
|
dataplaneUrl: params.dataplaneUrl || process.env.DATAPLANE_URL || '',
|
|
92
|
+
publicOrigin: typeof params.publicOrigin === 'string' ? params.publicOrigin.trim() : '',
|
|
91
93
|
bearerToken,
|
|
92
94
|
getUserRoot: () => userRoot,
|
|
93
95
|
getIntegrationRoot: () => integrationRoot,
|
|
@@ -67,7 +67,9 @@ async function resolveCliProtectionDataplaneContext(options) {
|
|
|
67
67
|
throw new Error('Authentication required. Run "aifabrix login" and try again.');
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig
|
|
70
|
+
const dataplaneUrl = await resolveDataplaneUrl(controllerUrl, environment, authConfig, {
|
|
71
|
+
silent: options.json === true || options.silent === true
|
|
72
|
+
});
|
|
71
73
|
return { environment, controllerUrl, dataplaneUrl, authConfig };
|
|
72
74
|
}
|
|
73
75
|
|
|
@@ -18,7 +18,7 @@ const {
|
|
|
18
18
|
formatProgress,
|
|
19
19
|
formatNextActions
|
|
20
20
|
} = require('../utils/cli-test-layout-chalk');
|
|
21
|
-
const { reportTaskRows } = require('./report-exit');
|
|
21
|
+
const { reportTaskRows, isProtectionProblemResponse } = require('./report-exit');
|
|
22
22
|
const { describeProtectionRoot } = require('./paths');
|
|
23
23
|
const {
|
|
24
24
|
appendTaskRows,
|
|
@@ -46,7 +46,8 @@ function formatProtectionValidateTTY(report, opts = {}) {
|
|
|
46
46
|
const meta = report?.metadata || {};
|
|
47
47
|
appendProtectionReportHeader(lines, meta);
|
|
48
48
|
const summary = report?.summary || {};
|
|
49
|
-
const
|
|
49
|
+
const problem = isProtectionProblemResponse(report);
|
|
50
|
+
const failCount = problem ? Math.max(1, Number(summary.fail || 0)) : Number(summary.fail || 0);
|
|
50
51
|
const warnCount = Number(summary.warn || 0);
|
|
51
52
|
const aggregate = failCount > 0 ? 'fail' : warnCount > 0 ? 'warn' : 'ok';
|
|
52
53
|
const glyph = aggregate === 'fail' ? '✖' : aggregate === 'warn' ? '⚠' : '✔';
|
|
@@ -23,6 +23,51 @@ function reportTaskRows(report) {
|
|
|
23
23
|
return [];
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* True when the payload is an RFC 7807 / API-client error, not a validate report.
|
|
28
|
+
* @param {*} report
|
|
29
|
+
* @returns {boolean}
|
|
30
|
+
*/
|
|
31
|
+
function isProtectionProblemResponse(report) {
|
|
32
|
+
if (!report || typeof report !== 'object') {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
if (report.success === false) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const status = Number(report.statusCode || report.status);
|
|
39
|
+
if (Number.isFinite(status) && status >= 400) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
const type = typeof report.type === 'string' ? report.type : '';
|
|
43
|
+
return type.includes('/Errors/') || type.includes('application/problem');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {*} uploaded
|
|
48
|
+
* @returns {string}
|
|
49
|
+
*/
|
|
50
|
+
function protectionUploadFailureMessage(uploaded) {
|
|
51
|
+
if (!uploaded || typeof uploaded !== 'object') {
|
|
52
|
+
return 'Protection upload returned empty response';
|
|
53
|
+
}
|
|
54
|
+
return (
|
|
55
|
+
uploaded.formattedError ||
|
|
56
|
+
uploaded.error ||
|
|
57
|
+
uploaded.detail ||
|
|
58
|
+
`Protection upload failed (HTTP ${uploaded.statusCode || uploaded.status || 0})`
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {*} uploaded
|
|
64
|
+
*/
|
|
65
|
+
function assertProtectionUploadSucceeded(uploaded) {
|
|
66
|
+
if (!uploaded || typeof uploaded !== 'object' || isProtectionProblemResponse(uploaded)) {
|
|
67
|
+
throw new Error(protectionUploadFailureMessage(uploaded));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
26
71
|
/**
|
|
27
72
|
* @param {Object} report
|
|
28
73
|
* @param {Object} [opts]
|
|
@@ -33,6 +78,9 @@ function exitCodeFromProtectionReport(report, opts = {}) {
|
|
|
33
78
|
if (!report || typeof report !== 'object') {
|
|
34
79
|
return 3;
|
|
35
80
|
}
|
|
81
|
+
if (isProtectionProblemResponse(report)) {
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
36
84
|
const summary = report.summary || {};
|
|
37
85
|
const failCount = Number(summary.fail || 0);
|
|
38
86
|
const warnCount = Number(summary.warn || 0);
|
|
@@ -58,5 +106,7 @@ function exitCodeFromProtectionReport(report, opts = {}) {
|
|
|
58
106
|
|
|
59
107
|
module.exports = {
|
|
60
108
|
reportTaskRows,
|
|
109
|
+
isProtectionProblemResponse,
|
|
110
|
+
assertProtectionUploadSucceeded,
|
|
61
111
|
exitCodeFromProtectionReport
|
|
62
112
|
};
|
|
@@ -18,6 +18,7 @@ const {
|
|
|
18
18
|
deleteProtection,
|
|
19
19
|
findProtectionKeyByDatasource
|
|
20
20
|
} = require('../api/protection.api');
|
|
21
|
+
const { assertProtectionUploadSucceeded } = require('./report-exit');
|
|
21
22
|
const { preflightDatasourceReady } = require('./preflight-datasource-ready');
|
|
22
23
|
const { runProtectionUploadDataSync } = require('./run-commands-upload-sync');
|
|
23
24
|
const {
|
|
@@ -63,6 +64,7 @@ async function runProtectionUpload(datasourceKey, manifest, opts, logger) {
|
|
|
63
64
|
|
|
64
65
|
logger.log(formatProgress('Uploading protection manifest...'));
|
|
65
66
|
const uploaded = await uploadProtection(ctx.dataplaneUrl, ctx.authConfig, manifest);
|
|
67
|
+
assertProtectionUploadSucceeded(uploaded);
|
|
66
68
|
logger.log(
|
|
67
69
|
formatSuccessLine(
|
|
68
70
|
`Protection for '${datasourceKey}' uploaded (deploymentId ${uploaded?.deploymentId || '—'}, revision ${uploaded?.revision ?? '—'})`
|
|
@@ -22,6 +22,7 @@ const {
|
|
|
22
22
|
} = require('../api/evidence.api');
|
|
23
23
|
const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
|
|
24
24
|
const { SYSTEM_KIND_DIGITAL_WORKER } = require('./settings');
|
|
25
|
+
const { formatEvidenceValidationIssues } = require('./evidence-validation-issues');
|
|
25
26
|
|
|
26
27
|
const EVIDENCE_DIR_NAME = 'evidence';
|
|
27
28
|
const EVIDENCE_EXPORT_FILE = 'evidence.json';
|
|
@@ -288,8 +289,9 @@ function isActivatedEvidenceRow(row) {
|
|
|
288
289
|
async function runEvidenceLifecycleForRef(dataplaneUrl, authConfig, evidenceRef) {
|
|
289
290
|
const validation = await validateEvidenceCandidate(dataplaneUrl, authConfig, evidenceRef);
|
|
290
291
|
if (validationFailed(validation)) {
|
|
291
|
-
|
|
292
|
-
|
|
292
|
+
throw new Error(
|
|
293
|
+
`Validation failed for evidence ${evidenceRef} (${formatEvidenceValidationIssues(validation?.issues)}).`
|
|
294
|
+
);
|
|
293
295
|
}
|
|
294
296
|
if (String(validation?.status || '').trim().toLowerCase() !== VALIDATION_PASSED) {
|
|
295
297
|
throw new Error(`Validation status for evidence ${evidenceRef} is "${validation?.status || 'unknown'}".`);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Evidence validate issues[] for CLI errors.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
function formatOneEvidenceIssue(issue) {
|
|
8
|
+
if (issue === undefined || issue === null) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
if (typeof issue !== 'object') {
|
|
12
|
+
return String(issue);
|
|
13
|
+
}
|
|
14
|
+
const bits = [];
|
|
15
|
+
if (issue.field) {
|
|
16
|
+
bits.push(String(issue.field));
|
|
17
|
+
}
|
|
18
|
+
if (issue.code) {
|
|
19
|
+
bits.push(String(issue.code));
|
|
20
|
+
}
|
|
21
|
+
if (issue.message) {
|
|
22
|
+
bits.push(String(issue.message));
|
|
23
|
+
}
|
|
24
|
+
if (bits.length > 0) {
|
|
25
|
+
return bits.join(' — ');
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return JSON.stringify(issue);
|
|
29
|
+
} catch {
|
|
30
|
+
return String(issue);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {unknown} issues
|
|
36
|
+
* @returns {string}
|
|
37
|
+
*/
|
|
38
|
+
function formatEvidenceValidationIssues(issues) {
|
|
39
|
+
if (!Array.isArray(issues) || issues.length === 0) {
|
|
40
|
+
return '0 issues';
|
|
41
|
+
}
|
|
42
|
+
const parts = issues.map(formatOneEvidenceIssue).filter(Boolean);
|
|
43
|
+
const noun = issues.length === 1 ? 'issue' : 'issues';
|
|
44
|
+
const detail = parts.length > 0 ? `: ${parts.join('; ')}` : '';
|
|
45
|
+
return `${issues.length} ${noun}${detail}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
formatOneEvidenceIssue,
|
|
50
|
+
formatEvidenceValidationIssues
|
|
51
|
+
};
|
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
updateAssistantSettings
|
|
20
20
|
} = require('../api/assistants.api');
|
|
21
21
|
const { resolveExternalSystemPath } = require('../utils/app-path-resolve');
|
|
22
|
+
const { bareRoleKey } = require('../utils/role-assistant-paths');
|
|
22
23
|
const {
|
|
23
24
|
SYSTEM_KIND_DIGITAL_WORKER,
|
|
24
25
|
getRoleAssistantYamlPath,
|
|
@@ -75,7 +76,11 @@ async function resolveDocumentStorageKeyFromDataplane(dataplaneUrl, authConfig,
|
|
|
75
76
|
return null;
|
|
76
77
|
}
|
|
77
78
|
try {
|
|
78
|
-
const response = await getAssistantDetails(
|
|
79
|
+
const response = await getAssistantDetails(
|
|
80
|
+
dataplaneUrl,
|
|
81
|
+
systemKey,
|
|
82
|
+
authConfig
|
|
83
|
+
);
|
|
79
84
|
return extractDocumentStorageKeyFromAssistantDetails(response);
|
|
80
85
|
} catch (_error) {
|
|
81
86
|
return null;
|
|
@@ -141,16 +146,17 @@ async function applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, s
|
|
|
141
146
|
const { documentStorageKey, debugBody, patchBody } = settingsPush;
|
|
142
147
|
const hasDocumentStorageKey = documentStorageKey !== '';
|
|
143
148
|
const hasDebugSettings = Object.keys(debugBody).length > 0;
|
|
149
|
+
const assistantKey = String(systemKey || '').trim();
|
|
144
150
|
let response = await updateAssistantSettings(
|
|
145
151
|
dataplaneUrl,
|
|
146
|
-
|
|
152
|
+
assistantKey,
|
|
147
153
|
authConfig,
|
|
148
154
|
patchBody
|
|
149
155
|
);
|
|
150
156
|
if (response && response.success === false && hasDocumentStorageKey && hasDebugSettings) {
|
|
151
157
|
response = await updateAssistantSettings(
|
|
152
158
|
dataplaneUrl,
|
|
153
|
-
|
|
159
|
+
assistantKey,
|
|
154
160
|
authConfig,
|
|
155
161
|
debugBody
|
|
156
162
|
);
|
|
@@ -352,7 +358,7 @@ function writeRoleAssistantSettingsFile(systemKey, docStorageKey, environment =
|
|
|
352
358
|
apiVersion: 'aifabrix.ai/v1',
|
|
353
359
|
version: '1.0.0',
|
|
354
360
|
kind: 'RoleAssistantSettings',
|
|
355
|
-
roleKey: systemKey,
|
|
361
|
+
roleKey: bareRoleKey(systemKey),
|
|
356
362
|
[envKey]: {
|
|
357
363
|
knowledge: docStorageKey ? { documentStorageKey: docStorageKey } : {}
|
|
358
364
|
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant package folder validation (settings, tests, evidence, knowledge).
|
|
3
|
+
* @fileoverview Walk ra-* governed files. Ignore leftover Connected System artifacts.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('../internal/fs-real-sync');
|
|
10
|
+
const { validateExternalFile, parseJsonFileContent } = require('../validation/validate-external-file');
|
|
11
|
+
const { listTestCaseFiles } = require('./test-cases');
|
|
12
|
+
const { validateTestCaseFile } = require('./test-case-validate');
|
|
13
|
+
|
|
14
|
+
const SETTINGS_TYPE = 'role-assistant-settings';
|
|
15
|
+
const EMPTY_TESTS_SKIP = 'tests/: skipped (no test cases)';
|
|
16
|
+
|
|
17
|
+
function fileRow(filePath, type, result) {
|
|
18
|
+
return {
|
|
19
|
+
file: path.basename(filePath),
|
|
20
|
+
type,
|
|
21
|
+
valid: result.valid,
|
|
22
|
+
path: filePath,
|
|
23
|
+
errors: result.errors || [],
|
|
24
|
+
warnings: result.warnings || []
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function listFilesByExt(dirPath, ext, acc) {
|
|
29
|
+
if (!fs.existsSync(dirPath)) {
|
|
30
|
+
return acc;
|
|
31
|
+
}
|
|
32
|
+
for (const name of fs.readdirSync(dirPath)) {
|
|
33
|
+
if (String(name).startsWith('.')) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const full = path.join(dirPath, name);
|
|
37
|
+
const st = fs.statSync(full);
|
|
38
|
+
if (st.isDirectory()) {
|
|
39
|
+
listFilesByExt(full, ext, acc);
|
|
40
|
+
} else if (String(name).toLowerCase().endsWith(ext)) {
|
|
41
|
+
acc.push(full);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return acc;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function evidenceRows(parsed) {
|
|
48
|
+
if (Array.isArray(parsed)) {
|
|
49
|
+
return parsed;
|
|
50
|
+
}
|
|
51
|
+
if (parsed && typeof parsed === 'object') {
|
|
52
|
+
return [parsed];
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function validateEvidenceJsonFile(filePath) {
|
|
58
|
+
const parseResult = parseJsonFileContent(filePath);
|
|
59
|
+
if (parseResult.error) {
|
|
60
|
+
return { ...parseResult.error, file: filePath, type: 'evidence' };
|
|
61
|
+
}
|
|
62
|
+
const rows = evidenceRows(parseResult.parsed);
|
|
63
|
+
const errors = [];
|
|
64
|
+
if (!rows) {
|
|
65
|
+
errors.push(`${filePath}: Evidence JSON must be an object or array of objects`);
|
|
66
|
+
} else {
|
|
67
|
+
rows.forEach((row, index) => {
|
|
68
|
+
const key = row && typeof row === 'object' && !Array.isArray(row) ? String(row.key || '').trim() : '';
|
|
69
|
+
if (!key) {
|
|
70
|
+
errors.push(`${filePath}: item ${index} is missing key`);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return { valid: errors.length === 0, errors, warnings: [], file: filePath, type: 'evidence' };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function validateKnowledgeMarkdown(filePath) {
|
|
78
|
+
const text = fs.readFileSync(filePath, 'utf8');
|
|
79
|
+
if (!String(text).trim()) {
|
|
80
|
+
return {
|
|
81
|
+
valid: false,
|
|
82
|
+
errors: [`${filePath}: knowledge markdown must not be empty`],
|
|
83
|
+
warnings: [],
|
|
84
|
+
file: filePath,
|
|
85
|
+
type: 'knowledge'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return { valid: true, errors: [], warnings: [], file: filePath, type: 'knowledge' };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function validateSettingsFile(appPath) {
|
|
92
|
+
const yamlPath = path.join(appPath, 'role-assistant.yaml');
|
|
93
|
+
try {
|
|
94
|
+
const result = await validateExternalFile(yamlPath, SETTINGS_TYPE);
|
|
95
|
+
return fileRow(yamlPath, SETTINGS_TYPE, result);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return fileRow(yamlPath, SETTINGS_TYPE, {
|
|
98
|
+
valid: false,
|
|
99
|
+
errors: [error.message],
|
|
100
|
+
warnings: []
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function collectDuplicateCaseIdErrors(caseFiles) {
|
|
106
|
+
const seen = new Map();
|
|
107
|
+
const errors = [];
|
|
108
|
+
for (const row of caseFiles) {
|
|
109
|
+
const parseResult = parseJsonFileContent(row.path);
|
|
110
|
+
const caseId = parseResult.parsed && String(parseResult.parsed.caseId || '').trim();
|
|
111
|
+
if (!caseId) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (seen.has(caseId)) {
|
|
115
|
+
errors.push(`${row.path}: duplicate caseId "${caseId}" (also ${seen.get(caseId)})`);
|
|
116
|
+
} else {
|
|
117
|
+
seen.set(caseId, row.path);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return errors;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function validateTestFiles(appPath) {
|
|
124
|
+
const testsDir = path.join(appPath, 'tests');
|
|
125
|
+
const yamlFiles = listTestCaseFiles(testsDir);
|
|
126
|
+
if (yamlFiles.length === 0) {
|
|
127
|
+
return { files: [], errors: [], warnings: [EMPTY_TESTS_SKIP] };
|
|
128
|
+
}
|
|
129
|
+
const files = yamlFiles.map((filePath) => fileRow(filePath, 'role-assistant-test-case', validateTestCaseFile(filePath)));
|
|
130
|
+
const errors = files.flatMap((row) => row.errors);
|
|
131
|
+
errors.push(...collectDuplicateCaseIdErrors(files));
|
|
132
|
+
return { files, errors, warnings: [] };
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function validateEvidenceFiles(appPath) {
|
|
136
|
+
const jsonFiles = listFilesByExt(path.join(appPath, 'evidence'), '.json', []);
|
|
137
|
+
const files = jsonFiles.map((filePath) => fileRow(filePath, 'evidence', validateEvidenceJsonFile(filePath)));
|
|
138
|
+
return { files, errors: files.flatMap((row) => row.errors), warnings: [] };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function validateKnowledgeFiles(appPath) {
|
|
142
|
+
const mdFiles = listFilesByExt(path.join(appPath, 'knowledge'), '.md', []).filter((filePath) => {
|
|
143
|
+
return path.dirname(filePath) === path.join(appPath, 'knowledge');
|
|
144
|
+
});
|
|
145
|
+
const files = mdFiles.map((filePath) => fileRow(filePath, 'knowledge', validateKnowledgeMarkdown(filePath)));
|
|
146
|
+
return { files, errors: files.flatMap((row) => row.errors), warnings: [] };
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function validateRoleAssistantPackage(appPath) {
|
|
150
|
+
const settings = await validateSettingsFile(appPath);
|
|
151
|
+
const tests = validateTestFiles(appPath);
|
|
152
|
+
const evidence = validateEvidenceFiles(appPath);
|
|
153
|
+
const knowledge = validateKnowledgeFiles(appPath);
|
|
154
|
+
const files = [settings, ...tests.files, ...evidence.files, ...knowledge.files];
|
|
155
|
+
const errors = [
|
|
156
|
+
...settings.errors,
|
|
157
|
+
...tests.errors,
|
|
158
|
+
...evidence.errors,
|
|
159
|
+
...knowledge.errors
|
|
160
|
+
];
|
|
161
|
+
const warnings = [...settings.warnings, ...tests.warnings, ...evidence.warnings, ...knowledge.warnings];
|
|
162
|
+
return {
|
|
163
|
+
valid: errors.length === 0,
|
|
164
|
+
errors,
|
|
165
|
+
warnings,
|
|
166
|
+
files
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
module.exports = {
|
|
171
|
+
EMPTY_TESTS_SKIP,
|
|
172
|
+
validateRoleAssistantPackage,
|
|
173
|
+
validateEvidenceJsonFile,
|
|
174
|
+
validateKnowledgeMarkdown
|
|
175
|
+
};
|