@aifabrix/builder 2.49.1 → 2.50.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/process/README.md +9 -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/jest.isolated-projects.js +31 -1
- package/jest.projects.js +87 -1
- package/lib/api/dev-server-https.js +1 -1
- package/lib/api/dev.api.js +1 -0
- package/lib/api/enterprise-knowledge.api.js +63 -0
- package/lib/api/evidence.api.js +172 -0
- package/lib/api/external-systems.api.js +8 -2
- package/lib/api/host-ops.api.js +69 -0
- package/lib/api/resource-types.api.js +1 -0
- package/lib/api/types/enterprise-knowledge.types.js +46 -0
- package/lib/api/types/evidence.types.js +67 -0
- package/lib/api/types/resource-types.types.js +2 -0
- 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 +37 -88
- 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/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 +16 -4
- 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 +27 -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 +38 -125
- 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-path-commands.js +24 -0
- package/lib/cli/setup-dev.js +115 -16
- 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-repair.js +26 -7
- 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 +163 -0
- package/lib/commands/deploy-gate-orchestrator.js +322 -0
- package/lib/commands/dev-cli-handlers.js +64 -61
- 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 +252 -0
- package/lib/commands/dev-init.js +3 -1
- package/lib/commands/enterprise-knowledge.js +284 -0
- package/lib/commands/evidence-cli-leaves.js +250 -0
- package/lib/commands/evidence.js +51 -0
- package/lib/commands/governance-cli-shared.js +2 -2
- package/lib/commands/governance-command-action.js +2 -2
- 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 +19 -2
- 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 +65 -26
- package/lib/commands/run-post-publish-data-sync.js +68 -0
- package/lib/commands/setup-modes.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/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 +2 -2
- 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/secrets-env-content.js +10 -4
- package/lib/core/secrets-env-write.js +2 -13
- package/lib/datasource/agent-trust-run.js +3 -3
- 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/index.js +17 -2
- package/lib/generator/wizard.js +3 -36
- 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 +44 -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 +98 -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 +205 -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 +476 -0
- package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
- package/lib/programmatic/openapi-schema-descriptions-core.js +159 -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 +93 -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 +54 -0
- package/lib/programmatic/run-template-workspace.js +61 -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/resource-type-file.js +22 -0
- package/lib/schema/external-datasource.schema.json +161 -1
- package/lib/schema/external-system.schema.json +242 -4
- package/lib/schema/flag-map-validation-run.json +3 -0
- package/lib/schema/type/credential-field-registry.json +2 -2
- package/lib/schema/type/document-storage.json +9 -0
- package/lib/utils/agent-trust-run-display.js +1 -1
- package/lib/utils/app-path-resolve.js +168 -0
- package/lib/utils/authentication-env-template.js +222 -0
- package/lib/utils/cli-sync-options.js +7 -11
- package/lib/utils/cli-utils.js +4 -0
- 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-init-ssh-merge.js +165 -23
- package/lib/utils/dev-pin-share-instructions.js +110 -0
- package/lib/utils/dev-ssh-config-helper.js +177 -33
- package/lib/utils/enterprise-knowledge-paths.js +142 -0
- package/lib/utils/env-copy.js +2 -1
- package/lib/utils/env-dotenv-format.js +103 -0
- package/lib/utils/external-env-template.js +4 -1
- package/lib/utils/external-system-display.js +5 -1
- package/lib/utils/external-system-readiness-compact-blocks.js +221 -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/help-builder.js +6 -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/integration-path-resolve.js +112 -0
- package/lib/utils/paths-reload-source.js +148 -0
- package/lib/utils/paths-system-builder-keys.js +25 -0
- package/lib/utils/paths.js +151 -26
- 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/upload-sync-options.js +4 -0
- 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 +426 -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/package.json +46 -29
- 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 +326 -0
- package/scripts/lib/plan-run-core.js +125 -0
- package/scripts/lib/plan-run-report.js +108 -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 +1 -1
- package/templates/applications/dataplane/env.template +10 -6
- package/templates/applications/dataplane/rbac.yaml +21 -1
- package/templates/applications/miso-controller/application.yaml +1 -1
- package/templates/applications/miso-controller/env.template +1 -3
- 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 +86 -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 +1 -1
- package/templates/typescript/docker-compose.hbs +11 -0
- package/lib/certification/cli-cert-sync-skip.js +0 -21
|
@@ -27,6 +27,10 @@ const {
|
|
|
27
27
|
logCapabilitiesOverview: logCapabilitiesOverviewSection,
|
|
28
28
|
logIntegrationHealthSection: logIntegrationHealthSectionBlock
|
|
29
29
|
} = require('./external-system-system-test-tty-overview');
|
|
30
|
+
const {
|
|
31
|
+
systemCertStatus,
|
|
32
|
+
logCertificationSection
|
|
33
|
+
} = require('./external-system-system-test-tty-certification');
|
|
30
34
|
|
|
31
35
|
/**
|
|
32
36
|
* @param {'ok'|'warn'|'fail'|'skipped'|null} st
|
|
@@ -220,24 +224,6 @@ function collectKeyIssues(rows, cap) {
|
|
|
220
224
|
return out.slice(0, Math.max(0, cap));
|
|
221
225
|
}
|
|
222
226
|
|
|
223
|
-
function certificateBucket(env) {
|
|
224
|
-
const cert = env && env.certificate;
|
|
225
|
-
if (!cert || typeof cert !== 'object') return { status: null, level: null };
|
|
226
|
-
return {
|
|
227
|
-
status: cert.status ? String(cert.status) : null,
|
|
228
|
-
level: cert.level ? String(cert.level) : null
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function systemCertStatus(rows) {
|
|
233
|
-
const certs = rows
|
|
234
|
-
.map(r => (r && r.datasourceTestRun ? certificateBucket(r.datasourceTestRun) : { status: null, level: null }))
|
|
235
|
-
.filter(c => c.status !== null);
|
|
236
|
-
if (certs.length === 0) return null;
|
|
237
|
-
if (certs.some(c => c.status === 'not_passed')) return 'not_passed';
|
|
238
|
-
return 'passed';
|
|
239
|
-
}
|
|
240
|
-
|
|
241
227
|
function drillDownCommand(runType, datasourceKey) {
|
|
242
228
|
if (!datasourceKey) return null;
|
|
243
229
|
if (runType === 'e2e') return `aifabrix datasource test-e2e ${datasourceKey}`;
|
|
@@ -359,28 +345,6 @@ function logKeyIssuesSection(rows) {
|
|
|
359
345
|
return true;
|
|
360
346
|
}
|
|
361
347
|
|
|
362
|
-
function logCertificationSection(rows) {
|
|
363
|
-
const certSt = systemCertStatus(rows);
|
|
364
|
-
if (!certSt) return;
|
|
365
|
-
logger.log('');
|
|
366
|
-
logger.log(metaGray(SEP));
|
|
367
|
-
logger.log('');
|
|
368
|
-
logger.log(sectionTitle('Certification:'));
|
|
369
|
-
logger.log('');
|
|
370
|
-
logger.log(chalk.white(`System level: ${certSt === 'passed' ? '✔ Achieved' : '✖ Not achieved'}`));
|
|
371
|
-
logger.log('');
|
|
372
|
-
logger.log(chalk.white('Breakdown:'));
|
|
373
|
-
for (const r of rows) {
|
|
374
|
-
const env = r && r.datasourceTestRun;
|
|
375
|
-
if (!env) continue;
|
|
376
|
-
const cert = certificateBucket(env);
|
|
377
|
-
if (!cert.status) continue;
|
|
378
|
-
const g = cert.status === 'passed' ? '✔' : '✖';
|
|
379
|
-
const tier = cert.level ? cert.level : '(no level)';
|
|
380
|
-
logger.log(chalk.white(`- ${env.datasourceKey}: ${g} ${tier}`));
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
348
|
function logUseAndFooter(results, runType, systemStatus, blocking) {
|
|
385
349
|
logger.log('');
|
|
386
350
|
logger.log(metaGray(SEP));
|
|
@@ -422,7 +386,7 @@ function displaySystemAggregateDatasourceTestRuns(results, opts) {
|
|
|
422
386
|
const ttyIo = { log: logger.log.bind(logger), chalk, metaGray, sectionTitle, statusGlyph, SEP };
|
|
423
387
|
logCapabilitiesOverviewSection(rows, ttyIo);
|
|
424
388
|
logIntegrationHealthSectionBlock(rows, runType, ttyIo);
|
|
425
|
-
logCertificationSection(rows);
|
|
389
|
+
logCertificationSection(rows, { debug: opts.debug, verbose: opts.verbose });
|
|
426
390
|
logUseAndFooter(results, runType, systemStatus, drillDownKey);
|
|
427
391
|
}
|
|
428
392
|
|
|
@@ -26,6 +26,7 @@ const CATEGORIES = [
|
|
|
26
26
|
{ name: 'up-platform' },
|
|
27
27
|
{ name: 'up-miso' },
|
|
28
28
|
{ name: 'up-dataplane' },
|
|
29
|
+
{ name: 'up-builder-api' },
|
|
29
30
|
{ name: 'down-infra', term: 'down-infra [service|appKey]' },
|
|
30
31
|
{ name: 'doctor' },
|
|
31
32
|
{ name: 'status' },
|
|
@@ -77,8 +78,10 @@ const CATEGORIES = [
|
|
|
77
78
|
{ name: 'dimension' },
|
|
78
79
|
{ name: 'dimension value', term: 'dimension value <command>' },
|
|
79
80
|
{ name: 'resource-type' },
|
|
81
|
+
{ name: 'enterprise-knowledge' },
|
|
80
82
|
{ name: 'identity' },
|
|
81
|
-
{ name: 'protection' }
|
|
83
|
+
{ name: 'protection' },
|
|
84
|
+
{ name: 'evidence' }
|
|
82
85
|
]
|
|
83
86
|
},
|
|
84
87
|
{
|
|
@@ -97,11 +100,13 @@ const CATEGORIES = [
|
|
|
97
100
|
{
|
|
98
101
|
name: 'External Systems',
|
|
99
102
|
commands: [
|
|
103
|
+
{ name: 'list', term: 'list' },
|
|
100
104
|
{ name: 'wizard', term: 'wizard [systemKey]' },
|
|
101
105
|
{ name: 'download', term: 'download <systemKey>' },
|
|
102
106
|
{ name: 'upload', term: 'upload <systemKey>' },
|
|
103
107
|
{ name: 'delete', term: 'delete <systemKey>' },
|
|
104
108
|
{ name: 'repair', term: 'repair <systemKey>' },
|
|
109
|
+
{ name: 'manifest', term: 'manifest get-section <systemKey> <sectionKey>' },
|
|
105
110
|
{ name: 'channel', term: 'channel scaffold <channelTarget>' },
|
|
106
111
|
{ name: 'datasource' },
|
|
107
112
|
{ name: 'datasource load', term: 'datasource load <datasourceKey>' },
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable labels for host-ops job polling output.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Host-ops job type → user-facing action text
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/** @type {Record<string, { action: string, durationHint: string, pendingDetail?: string, runningDetail?: string }>} */
|
|
12
|
+
const HOST_OPS_JOB_LABELS = {
|
|
13
|
+
'remove-dev-user': {
|
|
14
|
+
action: 'Removing developer',
|
|
15
|
+
durationHint: 'usually 1–2 min',
|
|
16
|
+
pendingDetail: 'waiting for host job',
|
|
17
|
+
runningDetail: 'stopping platform, removing OS user and database'
|
|
18
|
+
},
|
|
19
|
+
'provision-dev-user': {
|
|
20
|
+
action: 'Provisioning developer',
|
|
21
|
+
durationHint: 'usually 2–3 min',
|
|
22
|
+
pendingDetail: 'waiting for host job',
|
|
23
|
+
runningDetail: 'creating OS user, installing CLI and platform'
|
|
24
|
+
},
|
|
25
|
+
'install-dev-platform': {
|
|
26
|
+
action: 'Installing platform for',
|
|
27
|
+
durationHint: 'usually 3–5 min',
|
|
28
|
+
pendingDetail: 'waiting for host job',
|
|
29
|
+
runningDetail: 'pulling images and starting containers'
|
|
30
|
+
},
|
|
31
|
+
'reinstall-dev-platform': {
|
|
32
|
+
action: 'Re-installing platform for',
|
|
33
|
+
durationHint: 'usually 3–5 min',
|
|
34
|
+
pendingDetail: 'waiting for host job',
|
|
35
|
+
runningDetail: 'replacing platform containers'
|
|
36
|
+
},
|
|
37
|
+
'update-dev-platform': {
|
|
38
|
+
action: 'Updating platform for',
|
|
39
|
+
durationHint: 'usually 2–4 min',
|
|
40
|
+
pendingDetail: 'waiting for host job',
|
|
41
|
+
runningDetail: 'refreshing platform images'
|
|
42
|
+
},
|
|
43
|
+
'install-builder-cli': {
|
|
44
|
+
action: 'Installing Builder CLI for',
|
|
45
|
+
durationHint: 'usually 1–2 min',
|
|
46
|
+
pendingDetail: 'waiting for host job',
|
|
47
|
+
runningDetail: 'installing CLI on dev host'
|
|
48
|
+
},
|
|
49
|
+
'remove-dev-platform': {
|
|
50
|
+
action: 'Removing platform for',
|
|
51
|
+
durationHint: 'usually 1–2 min',
|
|
52
|
+
pendingDetail: 'waiting for host job',
|
|
53
|
+
runningDetail: 'stopping platform containers'
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {string|number|undefined} developerId
|
|
59
|
+
* @returns {string}
|
|
60
|
+
*/
|
|
61
|
+
function formatDevLinuxUserLabel(developerId) {
|
|
62
|
+
const trimmed = String(developerId ?? '').trim();
|
|
63
|
+
if (!trimmed) {
|
|
64
|
+
return 'developer';
|
|
65
|
+
}
|
|
66
|
+
if (/^\d+$/.test(trimmed)) {
|
|
67
|
+
return `dev${String(parseInt(trimmed, 10)).padStart(2, '0')}`;
|
|
68
|
+
}
|
|
69
|
+
return trimmed.startsWith('dev') ? trimmed : `dev${trimmed}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @param {string|undefined} include
|
|
74
|
+
* @returns {string[]}
|
|
75
|
+
*/
|
|
76
|
+
function parseHostOpsIncludeList(include) {
|
|
77
|
+
return String(include ?? '')
|
|
78
|
+
.split(',')
|
|
79
|
+
.map((part) => part.trim())
|
|
80
|
+
.filter(Boolean);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Resolve human-readable target(s) from host-ops job params.
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} [params]
|
|
87
|
+
* @param {string|number} [params.developerId]
|
|
88
|
+
* @param {string} [params.include]
|
|
89
|
+
* @param {string} [params.exclude]
|
|
90
|
+
* @returns {string}
|
|
91
|
+
*/
|
|
92
|
+
function resolveHostOpsTargetLabel(params = {}) {
|
|
93
|
+
if (params.developerId) {
|
|
94
|
+
return formatDevLinuxUserLabel(params.developerId);
|
|
95
|
+
}
|
|
96
|
+
const included = parseHostOpsIncludeList(params.include);
|
|
97
|
+
if (included.length === 1) {
|
|
98
|
+
return formatDevLinuxUserLabel(included[0]);
|
|
99
|
+
}
|
|
100
|
+
if (included.length > 1) {
|
|
101
|
+
return included.map(formatDevLinuxUserLabel).join(', ');
|
|
102
|
+
}
|
|
103
|
+
if (params.exclude) {
|
|
104
|
+
return 'selected developers';
|
|
105
|
+
}
|
|
106
|
+
return 'all developers';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {Object} [params]
|
|
111
|
+
* @returns {number}
|
|
112
|
+
*/
|
|
113
|
+
function countHostOpsTargets(params = {}) {
|
|
114
|
+
if (params.developerId) {
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
const included = parseHostOpsIncludeList(params.include);
|
|
118
|
+
if (included.length > 0) {
|
|
119
|
+
return included.length;
|
|
120
|
+
}
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* @param {number} ms
|
|
126
|
+
* @returns {string}
|
|
127
|
+
*/
|
|
128
|
+
function formatHostOpsElapsed(ms) {
|
|
129
|
+
const totalSec = Math.max(0, Math.floor(ms / 1000));
|
|
130
|
+
if (totalSec < 60) {
|
|
131
|
+
return `${totalSec}s`;
|
|
132
|
+
}
|
|
133
|
+
const min = Math.floor(totalSec / 60);
|
|
134
|
+
const sec = totalSec % 60;
|
|
135
|
+
return sec > 0 ? `${min}m ${sec}s` : `${min}m`;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param {string} jobType
|
|
140
|
+
* @param {string|number|undefined} targetLabel
|
|
141
|
+
* @returns {string}
|
|
142
|
+
*/
|
|
143
|
+
function buildHostOpsActionLabel(jobType, targetLabel) {
|
|
144
|
+
const meta = HOST_OPS_JOB_LABELS[jobType];
|
|
145
|
+
const userLabel = targetLabel ? String(targetLabel) : 'developer';
|
|
146
|
+
if (!meta) {
|
|
147
|
+
return `Host job for ${userLabel}`;
|
|
148
|
+
}
|
|
149
|
+
return `${meta.action} ${userLabel}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @param {string} jobType
|
|
154
|
+
* @param {string} status
|
|
155
|
+
* @returns {string}
|
|
156
|
+
*/
|
|
157
|
+
function buildHostOpsStatusDetail(jobType, status) {
|
|
158
|
+
const meta = HOST_OPS_JOB_LABELS[jobType];
|
|
159
|
+
if (!meta) {
|
|
160
|
+
return status || 'pending';
|
|
161
|
+
}
|
|
162
|
+
if (status === 'running') {
|
|
163
|
+
return meta.runningDetail || 'running on server';
|
|
164
|
+
}
|
|
165
|
+
return meta.pendingDetail || 'queued on server';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @param {string} jobType
|
|
170
|
+
* @param {Object} [params]
|
|
171
|
+
* @returns {string}
|
|
172
|
+
*/
|
|
173
|
+
function getHostOpsDurationHint(jobType, params) {
|
|
174
|
+
const meta = HOST_OPS_JOB_LABELS[jobType];
|
|
175
|
+
const base = (meta && meta.durationHint) || 'may take several minutes';
|
|
176
|
+
const count = countHostOpsTargets(params);
|
|
177
|
+
if (count > 1) {
|
|
178
|
+
return `${base} per developer (${count} selected)`;
|
|
179
|
+
}
|
|
180
|
+
return base;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Single-line poll text (spinner or throttled log).
|
|
185
|
+
*
|
|
186
|
+
* @param {Object} ctx
|
|
187
|
+
* @param {string} ctx.jobType
|
|
188
|
+
* @param {string} [ctx.targetLabel]
|
|
189
|
+
* @param {Object} [ctx.params]
|
|
190
|
+
* @param {string} ctx.status
|
|
191
|
+
* @param {number} ctx.elapsedMs
|
|
192
|
+
* @param {string} [ctx.transientNote]
|
|
193
|
+
* @returns {string}
|
|
194
|
+
*/
|
|
195
|
+
function buildHostOpsPollLine(ctx) {
|
|
196
|
+
const targetLabel = ctx.targetLabel || resolveHostOpsTargetLabel(ctx.params);
|
|
197
|
+
const action = buildHostOpsActionLabel(ctx.jobType, targetLabel);
|
|
198
|
+
const durationHint = getHostOpsDurationHint(ctx.jobType, ctx.params);
|
|
199
|
+
const elapsed = formatHostOpsElapsed(ctx.elapsedMs);
|
|
200
|
+
if (ctx.transientNote) {
|
|
201
|
+
return `${action}: ${ctx.transientNote} (${elapsed}, ${durationHint})`;
|
|
202
|
+
}
|
|
203
|
+
const detail = buildHostOpsStatusDetail(ctx.jobType, ctx.status);
|
|
204
|
+
return `${action}: ${detail} (${elapsed}, ${durationHint})`;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Gray intro line printed once when polling starts.
|
|
209
|
+
*
|
|
210
|
+
* @param {string} jobType
|
|
211
|
+
* @param {string|Object} [targetLabelOrParams]
|
|
212
|
+
* @returns {string}
|
|
213
|
+
*/
|
|
214
|
+
function buildHostOpsPollIntroLine(jobType, targetLabelOrParams) {
|
|
215
|
+
const targetLabel =
|
|
216
|
+
typeof targetLabelOrParams === 'string'
|
|
217
|
+
? targetLabelOrParams
|
|
218
|
+
: resolveHostOpsTargetLabel(targetLabelOrParams);
|
|
219
|
+
const params = typeof targetLabelOrParams === 'object' ? targetLabelOrParams : undefined;
|
|
220
|
+
const action = buildHostOpsActionLabel(jobType, targetLabel);
|
|
221
|
+
const durationHint = getHostOpsDurationHint(jobType, params);
|
|
222
|
+
return `⏳ ${action} — ${durationHint} on the builder host`;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = {
|
|
226
|
+
HOST_OPS_JOB_LABELS,
|
|
227
|
+
formatDevLinuxUserLabel,
|
|
228
|
+
parseHostOpsIncludeList,
|
|
229
|
+
resolveHostOpsTargetLabel,
|
|
230
|
+
countHostOpsTargets,
|
|
231
|
+
formatHostOpsElapsed,
|
|
232
|
+
buildHostOpsActionLabel,
|
|
233
|
+
buildHostOpsPollLine,
|
|
234
|
+
buildHostOpsPollIntroLine,
|
|
235
|
+
getHostOpsDurationHint
|
|
236
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Host-ops job success/failure interpretation for CLI polling
|
|
3
|
+
* @author AI Fabrix Team
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Object|null|undefined} job
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/
|
|
11
|
+
function isHostOpsJobFailed(job) {
|
|
12
|
+
if (!job) return true;
|
|
13
|
+
if (job.status === 'failed') return true;
|
|
14
|
+
if (job.error) return true;
|
|
15
|
+
if (!Array.isArray(job.outcomes)) return false;
|
|
16
|
+
return job.outcomes.some((row) => {
|
|
17
|
+
if (!row || typeof row !== 'object') return false;
|
|
18
|
+
const overall = row.overall || row.status;
|
|
19
|
+
return overall === 'FAIL' || overall === 'BLOCKED';
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {Object} job
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
function formatHostOpsJobFailure(job) {
|
|
28
|
+
const parts = [];
|
|
29
|
+
if (job.error) {
|
|
30
|
+
parts.push(String(job.error));
|
|
31
|
+
}
|
|
32
|
+
if (Array.isArray(job.outcomes)) {
|
|
33
|
+
for (const row of job.outcomes) {
|
|
34
|
+
if (!row || typeof row !== 'object') continue;
|
|
35
|
+
const overall = row.overall || row.status;
|
|
36
|
+
if (overall !== 'FAIL' && overall !== 'BLOCKED') continue;
|
|
37
|
+
const label = row.linuxUser || row.developerId || 'target';
|
|
38
|
+
const detail = row.detail ? ` — ${row.detail}` : '';
|
|
39
|
+
parts.push(`${label}: ${overall}${detail}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (parts.length > 0) {
|
|
43
|
+
return parts.join('\n');
|
|
44
|
+
}
|
|
45
|
+
return `Host-ops job ${job.jobId || '(unknown)'} failed`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {Object} job
|
|
50
|
+
* @throws {Error}
|
|
51
|
+
*/
|
|
52
|
+
function assertHostOpsJobSucceeded(job) {
|
|
53
|
+
if (!isHostOpsJobFailed(job)) return;
|
|
54
|
+
throw new Error(formatHostOpsJobFailure(job));
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = {
|
|
58
|
+
isHostOpsJobFailed,
|
|
59
|
+
formatHostOpsJobFailure,
|
|
60
|
+
assertHostOpsJobSucceeded
|
|
61
|
+
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TTY ora spinner + throttled non-TTY lines for host-ops job polling.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Host-ops job poll presentation helpers
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const chalk = require('chalk');
|
|
12
|
+
const logger = require('./logger');
|
|
13
|
+
const {
|
|
14
|
+
buildHostOpsPollLine,
|
|
15
|
+
buildHostOpsPollIntroLine
|
|
16
|
+
} = require('./host-ops-job-labels');
|
|
17
|
+
|
|
18
|
+
const SILENT_POLL_HANDLERS = {
|
|
19
|
+
onPollProgress: () => {},
|
|
20
|
+
onTransientError: () => {},
|
|
21
|
+
finish: () => {}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
function shouldUseHostOpsPollSpinner() {
|
|
25
|
+
return Boolean(process && process.stdout && process.stdout.isTTY);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Use buildHostOpsPollLine via createHostOpsPollHandlers context.
|
|
30
|
+
* @param {string} jobId
|
|
31
|
+
* @param {string} status
|
|
32
|
+
* @param {number} attemptIndex
|
|
33
|
+
* @param {number} maxAttempts
|
|
34
|
+
* @returns {string}
|
|
35
|
+
*/
|
|
36
|
+
function buildHostOpsPollSpinnerText(jobId, status, attemptIndex, maxAttempts) {
|
|
37
|
+
const safeStatus = status || 'pending';
|
|
38
|
+
return `host-ops job ${jobId}: ${safeStatus} (${attemptIndex + 1}/${maxAttempts})`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const NON_TTY_THROTTLE_MS = 5000;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {Object} pollContext
|
|
45
|
+
* @returns {Function}
|
|
46
|
+
*/
|
|
47
|
+
function createPollLineBuilder(pollContext) {
|
|
48
|
+
const jobType = pollContext.jobType || 'host-ops';
|
|
49
|
+
const params = pollContext.params;
|
|
50
|
+
const targetLabel = pollContext.targetLabel;
|
|
51
|
+
return (status, elapsedMs, transientNote) =>
|
|
52
|
+
buildHostOpsPollLine({
|
|
53
|
+
jobType,
|
|
54
|
+
targetLabel,
|
|
55
|
+
params,
|
|
56
|
+
status,
|
|
57
|
+
elapsedMs,
|
|
58
|
+
transientNote
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {Object} pollContext
|
|
64
|
+
* @returns {Function}
|
|
65
|
+
*/
|
|
66
|
+
function createPollIntroLogger(pollContext) {
|
|
67
|
+
const jobType = pollContext.jobType || 'host-ops';
|
|
68
|
+
const params = pollContext.params;
|
|
69
|
+
const targetLabel = pollContext.targetLabel;
|
|
70
|
+
let introLogged = false;
|
|
71
|
+
return () => {
|
|
72
|
+
if (introLogged) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
introLogged = true;
|
|
76
|
+
logger.log(
|
|
77
|
+
chalk.gray(` ${buildHostOpsPollIntroLine(jobType, targetLabel || params || undefined)}`)
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @param {Object} pollContext
|
|
84
|
+
* @returns {{ onPollProgress: Function, onTransientError: Function, finish: () => void }}
|
|
85
|
+
*/
|
|
86
|
+
function createSpinnerHostOpsPollHandlers(pollContext) {
|
|
87
|
+
const startedAt = pollContext.startedAt || Date.now();
|
|
88
|
+
const buildLine = createPollLineBuilder(pollContext);
|
|
89
|
+
const logIntroOnce = createPollIntroLogger(pollContext);
|
|
90
|
+
const ora = require('ora');
|
|
91
|
+
logIntroOnce();
|
|
92
|
+
const spinner = ora({
|
|
93
|
+
text: buildLine('pending', 0),
|
|
94
|
+
spinner: 'dots'
|
|
95
|
+
}).start();
|
|
96
|
+
return {
|
|
97
|
+
onPollProgress: (status) => {
|
|
98
|
+
spinner.text = buildLine(status, Date.now() - startedAt);
|
|
99
|
+
},
|
|
100
|
+
onTransientError: (_err, elapsedMs) => {
|
|
101
|
+
spinner.text = buildLine('pending', elapsedMs, 'server temporarily unavailable, retrying');
|
|
102
|
+
},
|
|
103
|
+
finish: () => {
|
|
104
|
+
spinner.stop();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @param {Object} pollContext
|
|
111
|
+
* @returns {{ onPollProgress: Function, onTransientError: Function, finish: () => void }}
|
|
112
|
+
*/
|
|
113
|
+
function createNonTtyHostOpsPollHandlers(pollContext) {
|
|
114
|
+
const startedAt = pollContext.startedAt || Date.now();
|
|
115
|
+
const buildLine = createPollLineBuilder(pollContext);
|
|
116
|
+
const logIntroOnce = createPollIntroLogger(pollContext);
|
|
117
|
+
let lastNonTtyLogAt = 0;
|
|
118
|
+
return {
|
|
119
|
+
onPollProgress: (status) => {
|
|
120
|
+
logIntroOnce();
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
const elapsedMs = now - startedAt;
|
|
123
|
+
if (now - lastNonTtyLogAt < NON_TTY_THROTTLE_MS && elapsedMs > 0) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
lastNonTtyLogAt = now;
|
|
127
|
+
logger.log(chalk.gray(` ${buildLine(status, elapsedMs)}`));
|
|
128
|
+
},
|
|
129
|
+
onTransientError: (_err, elapsedMs) => {
|
|
130
|
+
logIntroOnce();
|
|
131
|
+
logger.log(
|
|
132
|
+
chalk.gray(` ${buildLine('pending', elapsedMs, 'server temporarily unavailable, retrying')}`)
|
|
133
|
+
);
|
|
134
|
+
},
|
|
135
|
+
finish: () => {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* @param {string} jobId
|
|
141
|
+
* @param {Object} [pollContext]
|
|
142
|
+
* @param {string} [pollContext.jobType]
|
|
143
|
+
* @param {string} [pollContext.targetLabel]
|
|
144
|
+
* @param {Object} [pollContext.params]
|
|
145
|
+
* @param {number} [pollContext.startedAt]
|
|
146
|
+
* @param {{ silent?: boolean }} [options]
|
|
147
|
+
* @returns {{ onPollProgress: Function, onTransientError: Function, finish: () => void }}
|
|
148
|
+
*/
|
|
149
|
+
function createHostOpsPollHandlers(jobId, pollContext = {}, options = {}) {
|
|
150
|
+
if (options && options.silent === true) {
|
|
151
|
+
return SILENT_POLL_HANDLERS;
|
|
152
|
+
}
|
|
153
|
+
if (shouldUseHostOpsPollSpinner()) {
|
|
154
|
+
return createSpinnerHostOpsPollHandlers(pollContext);
|
|
155
|
+
}
|
|
156
|
+
return createNonTtyHostOpsPollHandlers(pollContext);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
module.exports = {
|
|
160
|
+
buildHostOpsPollSpinnerText,
|
|
161
|
+
createHostOpsPollHandlers,
|
|
162
|
+
shouldUseHostOpsPollSpinner
|
|
163
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find integration/<systemKey> under aifabrix-work (sibling repos).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Worktree integration discovery for dev layouts (sibling repos under aifabrix-work)
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { getAifabrixWork } = require('./paths');
|
|
14
|
+
const { resolveApplicationConfigPath } = require('./app-config-resolver');
|
|
15
|
+
const { discoverIntegrationFiles } = require('../commands/repair-internal');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} appPath
|
|
19
|
+
* @returns {boolean}
|
|
20
|
+
*/
|
|
21
|
+
function integrationFolderHasContent(appPath) {
|
|
22
|
+
if (!fs.existsSync(appPath)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const st = fs.statSync(appPath);
|
|
27
|
+
if (!st.isDirectory()) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
const { systemFiles, datasourceFiles } = discoverIntegrationFiles(appPath);
|
|
34
|
+
if (systemFiles.length > 0 || datasourceFiles.length > 0) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
resolveApplicationConfigPath(appPath);
|
|
39
|
+
return true;
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @param {string} work
|
|
47
|
+
* @param {string} systemKey
|
|
48
|
+
* @returns {{ integrationPath: string, tier: string }[]}
|
|
49
|
+
*/
|
|
50
|
+
function collectWorkRepoIntegrationHits(work, systemKey) {
|
|
51
|
+
/** @type {{ integrationPath: string, tier: string }[]} */
|
|
52
|
+
const hits = [];
|
|
53
|
+
let entries;
|
|
54
|
+
try {
|
|
55
|
+
entries = fs.readdirSync(work, { withFileTypes: true });
|
|
56
|
+
} catch {
|
|
57
|
+
return hits;
|
|
58
|
+
}
|
|
59
|
+
for (const ent of entries) {
|
|
60
|
+
if (!ent.isDirectory() || ent.name.startsWith('.')) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const candidate = path.join(work, ent.name, 'integration', systemKey);
|
|
64
|
+
if (integrationFolderHasContent(candidate)) {
|
|
65
|
+
hits.push({ integrationPath: path.resolve(candidate), tier: 'work-repo-integration' });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return hits;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {{ integrationPath: string, tier: string }[]} hits
|
|
73
|
+
* @param {string} systemKey
|
|
74
|
+
* @returns {{ integrationPath: string, tier: string }|null}
|
|
75
|
+
*/
|
|
76
|
+
function resolveUniqueIntegrationHit(hits, systemKey) {
|
|
77
|
+
if (hits.length === 1) {
|
|
78
|
+
return hits[0];
|
|
79
|
+
}
|
|
80
|
+
if (hits.length > 1) {
|
|
81
|
+
const err = new Error(
|
|
82
|
+
`Integration "${systemKey}" found in multiple repos under aifabrix-work: ${hits.map((h) => h.integrationPath).join(', ')}. ` +
|
|
83
|
+
'Run from the target repo or narrow with cwd.'
|
|
84
|
+
);
|
|
85
|
+
err.statusCode = 409;
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {string} systemKey
|
|
93
|
+
* @returns {{ integrationPath: string, tier: string }|null}
|
|
94
|
+
*/
|
|
95
|
+
function findIntegrationPathAcrossWorkTree(systemKey) {
|
|
96
|
+
const work = getAifabrixWork();
|
|
97
|
+
if (!work) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const direct = path.join(work, 'integration', systemKey);
|
|
102
|
+
if (integrationFolderHasContent(direct)) {
|
|
103
|
+
return { integrationPath: path.resolve(direct), tier: 'work-integration' };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return resolveUniqueIntegrationHit(collectWorkRepoIntegrationHits(work, systemKey), systemKey);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = {
|
|
110
|
+
findIntegrationPathAcrossWorkTree,
|
|
111
|
+
integrationFolderHasContent
|
|
112
|
+
};
|