@aifabrix/builder 2.49.2 → 2.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cursor/plans/157.1-security-quality-violations-by-type.csv +374 -0
- package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
- package/.cursor/skills/README.md +1 -0
- package/.dockerignore +52 -0
- package/.eslintignore +22 -0
- package/README.md +2 -0
- package/bin/builder-api-cleanup.js +26 -0
- package/bin/builder-api-nest.js +10 -0
- package/bin/builder-api-spike.js +19 -0
- package/enterprise-knowledge/README.md +50 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
- package/integration/README.md +81 -0
- package/integration/github/README.md +53 -0
- package/integration/github/application.json +21 -0
- package/integration/github/deploy.js +72 -0
- package/integration/github/env.template +11 -0
- package/integration/github/github-datasource-issue-comments.json +239 -0
- package/integration/github/github-datasource-issues.json +399 -0
- package/integration/github/github-datasource-repository.json +354 -0
- package/integration/github/github-deploy.json +1202 -0
- package/integration/github/github-system.json +82 -0
- package/integration/hubspot-test/README.md +1 -1
- package/integration/hubspot-test/create-hubspot.js +1 -16
- package/jest.isolated-projects.js +31 -1
- package/jest.projects.js +87 -1
- package/lib/api/dev-server-https.js +1 -1
- package/lib/api/enterprise-knowledge.api.js +63 -0
- package/lib/api/evidence-kinds.api.js +128 -0
- package/lib/api/evidence.api.js +172 -0
- package/lib/api/external-systems.api.js +8 -2
- package/lib/api/pipeline.api.js +5 -1
- package/lib/api/resource-types.api.js +5 -4
- package/lib/api/roles.api.js +121 -0
- package/lib/api/types/enterprise-knowledge.types.js +46 -0
- package/lib/api/types/evidence-kinds.types.js +42 -0
- package/lib/api/types/evidence.types.js +67 -0
- package/lib/api/types/resource-types.types.js +2 -0
- package/lib/api/types/roles.types.js +36 -0
- package/lib/app/certification-verify-rows.js +1 -1
- package/lib/app/controller-application-filter.js +36 -0
- package/lib/app/deploy.js +1 -1
- package/lib/app/list-external-systems.js +130 -0
- package/lib/app/list.js +20 -8
- package/lib/app/run.js +3 -1
- package/lib/app/show-display.js +8 -3
- package/lib/app/show-online.js +178 -0
- package/lib/app/show.js +39 -90
- package/lib/build/builder-api-docker-staging.js +47 -0
- package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
- package/lib/build/standard-docker-build.js +2 -0
- package/lib/certification/merge-certification-from-artifact.js +1 -1
- package/lib/certification/post-unified-cert-sync.js +4 -31
- package/lib/certification/sync-after-external-command.js +0 -1
- package/lib/certification/sync-system-certification.js +0 -3
- package/lib/channels/add-channel.js +40 -34
- package/lib/channels/approval-guides/chatgpt.js +33 -0
- package/lib/channels/approval-guides/credential-portal.js +38 -0
- package/lib/channels/approval-guides/index.js +110 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
- package/lib/channels/approval-guides/slack.js +34 -0
- package/lib/channels/approval-guides/teams-bot.js +35 -0
- package/lib/channels/approval-guides/web-embed.js +32 -0
- package/lib/channels/channel-approval-guide.js +11 -0
- package/lib/channels/channel-artifact-generator.js +18 -5
- package/lib/channels/channel-audit.js +3 -0
- package/lib/channels/channel-auth-context.js +1 -1
- package/lib/channels/channel-description.js +59 -0
- package/lib/channels/channel-integration-generator.js +13 -230
- package/lib/channels/channel-integration-template.js +94 -0
- package/lib/channels/channel-runtime-resolver.js +43 -3
- package/lib/channels/channel-status-display.js +66 -26
- package/lib/channels/channel-targets.js +3 -3
- package/lib/cli/index.js +31 -3
- package/lib/cli/infra-guided.js +5 -1
- package/lib/cli/setup-app-external-create.js +111 -0
- package/lib/cli/setup-app.help.js +1 -1
- package/lib/cli/setup-app.js +60 -130
- package/lib/cli/setup-app.test-commands.js +26 -52
- package/lib/cli/setup-certification-commands.js +4 -4
- package/lib/cli/setup-certification.help.js +9 -9
- package/lib/cli/setup-dev.js +30 -9
- package/lib/cli/setup-external-system-help.js +4 -6
- package/lib/cli/setup-external-system.js +58 -52
- package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
- package/lib/cli/setup-infra-up-platform-action.js +3 -1
- package/lib/cli/setup-infra.js +15 -0
- package/lib/cli/setup-list.js +43 -0
- package/lib/cli/setup-utility-help-after.js +12 -0
- package/lib/cli/setup-utility-repair.js +26 -7
- package/lib/cli/setup-utility-validate.js +41 -2
- package/lib/cli/setup-utility.js +5 -3
- package/lib/commands/app.js +15 -43
- package/lib/commands/channel-add-setup.js +110 -0
- package/lib/commands/channel.js +42 -8
- package/lib/commands/datasource-sync-display.js +96 -0
- package/lib/commands/datasource-sync-policy.js +210 -0
- package/lib/commands/datasource-test-trust-cli.js +6 -6
- package/lib/commands/datasource-unified-test-cli.js +2 -1
- package/lib/commands/datasource-unified-test-cli.options.js +33 -23
- package/lib/commands/deploy-gate-failure-details.js +184 -0
- package/lib/commands/deploy-gate-orchestrator.js +368 -0
- package/lib/commands/dev-cli-handlers.js +7 -62
- package/lib/commands/dev-host-ops-params.js +91 -0
- package/lib/commands/dev-host-ops-poll.js +111 -0
- package/lib/commands/dev-host-ops.js +107 -94
- package/lib/commands/dev-init.js +6 -106
- package/lib/commands/dev-refresh.js +197 -0
- package/lib/commands/enterprise-knowledge.js +284 -0
- package/lib/commands/evidence-cli-leaves.js +250 -0
- package/lib/commands/evidence-kind.js +428 -0
- package/lib/commands/evidence.js +51 -0
- package/lib/commands/governance-cli-shared.js +2 -2
- package/lib/commands/governance-command-action.js +5 -3
- package/lib/commands/governance-fixture-subjects.js +85 -0
- package/lib/commands/governance.js +1 -1
- package/lib/commands/lifecycle-command-action.js +2 -2
- package/lib/commands/lifecycle-external.js +3 -3
- package/lib/commands/manifest-cli-auth.js +29 -0
- package/lib/commands/manifest-cli-commands.js +170 -0
- package/lib/commands/manifest-cli-integration-path.js +63 -0
- package/lib/commands/manifest.js +21 -0
- package/lib/commands/protection-cli-leaves.js +3 -3
- package/lib/commands/repair-auth-apply.js +15 -1
- package/lib/commands/repair-authentications-454.js +169 -0
- package/lib/commands/repair-capability-openapi-warnings.js +126 -0
- package/lib/commands/repair-datasource-apply.js +135 -0
- package/lib/commands/repair-datasource-auto-rbac.js +62 -1
- package/lib/commands/repair-datasource-http-service-contract.js +239 -0
- package/lib/commands/repair-datasource-operation-security.js +180 -0
- package/lib/commands/repair-datasource-run.js +7 -2
- package/lib/commands/repair-datasource-sync-operations.js +177 -0
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
- package/lib/commands/repair-datasource.js +12 -68
- package/lib/commands/repair-env-template.js +11 -1
- package/lib/commands/repair-external-run.js +121 -31
- package/lib/commands/repair-internal.js +1 -1
- package/lib/commands/repair-openapi-export.js +156 -0
- package/lib/commands/repair-openapi-sync.js +33 -8
- package/lib/commands/repair-orchestration-datasource-split.js +259 -0
- package/lib/commands/repair-persist.js +22 -1
- package/lib/commands/repair-rbac-platform-preset.js +204 -0
- package/lib/commands/repair-rbac-reader-roles.js +191 -0
- package/lib/commands/repair-rbac.js +163 -86
- package/lib/commands/repair-steps.js +83 -18
- package/lib/commands/repair-system-permissions.js +1 -0
- package/lib/commands/repair.js +1 -1
- package/lib/commands/resource-type.js +166 -44
- package/lib/commands/role.js +452 -0
- package/lib/commands/run-post-publish-data-sync.js +68 -0
- package/lib/commands/setup-modes.js +1 -1
- package/lib/commands/setup.js +1 -1
- package/lib/commands/test-e2e-external.js +21 -8
- package/lib/commands/test-governance-cli-options.js +2 -2
- package/lib/commands/test-trust-cli-options.js +2 -2
- package/lib/commands/up-builder-api-bootstrap.js +71 -0
- package/lib/commands/up-builder-api-provision.js +241 -0
- package/lib/commands/up-builder-api.js +88 -0
- package/lib/commands/up-common.js +25 -1
- package/lib/commands/upload-credential-push-log.js +117 -0
- package/lib/commands/upload-data-sync-finalize.js +60 -0
- package/lib/commands/upload-probe.js +66 -0
- package/lib/commands/upload-publish-context.js +4 -1
- package/lib/commands/upload-sidecar-followups.js +55 -27
- package/lib/commands/upload.js +116 -157
- package/lib/commands/validate-json.js +230 -0
- package/lib/commands/verify-governance-combined-external.js +1 -1
- package/lib/commands/verify-governance-db.js +2 -2
- package/lib/commands/verify-operations-command-action.js +2 -2
- package/lib/commands/verify-operations-step-plan.js +79 -41
- package/lib/commands/verify-operations-steps.js +2 -2
- package/lib/commands/verify-trust-command-action.js +1 -1
- package/lib/commands/wizard-core.js +1 -1
- package/lib/commands/wizard-headless.js +2 -1
- package/lib/core/admin-secrets.js +2 -6
- package/lib/core/audit-logger.js +1 -1
- package/lib/core/secrets-env-content.js +10 -4
- package/lib/core/secrets-env-write.js +2 -13
- package/lib/core/secrets-load.js +1 -3
- package/lib/datasource/agent-trust-run.js +3 -3
- package/lib/datasource/capability/relate-operations.js +1 -1
- package/lib/datasource/deploy.js +3 -1
- package/lib/datasource/test-e2e.js +6 -1
- package/lib/datasource/unified-validation-run-body.js +4 -1
- package/lib/datasource/unified-validation-run.js +1 -1
- package/lib/deployment/deploy-poll-ui.js +73 -12
- package/lib/deployment/deployer-poll-run.js +113 -0
- package/lib/deployment/deployer.js +17 -87
- package/lib/evidence/dataplane-context.js +21 -0
- package/lib/evidence/evidence-display.js +78 -0
- package/lib/evidence/evidence-service.js +392 -0
- package/lib/external-system/deploy.js +290 -112
- package/lib/external-system/download.js +7 -3
- package/lib/external-system/test-execution.js +1 -1
- package/lib/external-system/test-system-level.js +8 -10
- package/lib/external-system/test.js +12 -6
- package/lib/generator/deploy-script.js +73 -0
- package/lib/generator/external.js +2 -1
- package/lib/generator/helpers.js +13 -5
- package/lib/generator/index.js +17 -2
- package/lib/generator/split-variables.js +9 -3
- package/lib/generator/wizard.js +3 -36
- package/lib/infrastructure/helpers-docker-check.js +6 -0
- package/lib/infrastructure/helpers.js +1 -1
- package/lib/internal/fs-real-sync.js +22 -1
- package/lib/internal/node-fs.js +2 -0
- package/lib/lifecycle/lifecycle-governance-options.js +1 -1
- package/lib/lifecycle/verify-step-progress.js +1 -1
- package/lib/programmatic/access-log.js +26 -0
- package/lib/programmatic/auth-config.js +45 -0
- package/lib/programmatic/bearer-auth.js +176 -0
- package/lib/programmatic/builder-api-request.js +175 -0
- package/lib/programmatic/builder-api-route-dispatch.js +82 -0
- package/lib/programmatic/builder-api-runtime-config.js +42 -0
- package/lib/programmatic/builder-api-server.js +230 -0
- package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
- package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
- package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
- package/lib/programmatic/builder-help-envelope.js +36 -0
- package/lib/programmatic/builder-help-fixtures.js +200 -0
- package/lib/programmatic/builder-help-governance.js +172 -0
- package/lib/programmatic/builder-help-schema-catalog.js +92 -0
- package/lib/programmatic/builder-help.js +361 -0
- package/lib/programmatic/capability-registry.js +77 -0
- package/lib/programmatic/command-options.js +32 -0
- package/lib/programmatic/enterprise-mcp-client.js +114 -0
- package/lib/programmatic/http-problem-details.js +99 -0
- package/lib/programmatic/http-route-match.js +40 -0
- package/lib/programmatic/idempotency-cache.js +69 -0
- package/lib/programmatic/index.js +53 -0
- package/lib/programmatic/integration-path-scope.js +39 -0
- package/lib/programmatic/log-redaction.js +66 -0
- package/lib/programmatic/manifest-get-section.js +146 -0
- package/lib/programmatic/manifest-patch-section.js +252 -0
- package/lib/programmatic/manifest-repair.js +122 -0
- package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
- package/lib/programmatic/manifest-section-io.js +225 -0
- package/lib/programmatic/manifest-section-quality.js +171 -0
- package/lib/programmatic/manifest-section-registry-data.js +269 -0
- package/lib/programmatic/manifest-section-registry.js +222 -0
- package/lib/programmatic/nest-http-bridge.js +34 -0
- package/lib/programmatic/openapi-component-schemas.js +68 -0
- package/lib/programmatic/openapi-description-enricher.js +117 -0
- package/lib/programmatic/openapi-descriptions.js +190 -0
- package/lib/programmatic/openapi-docs-serving.js +123 -0
- package/lib/programmatic/openapi-help-schemas.js +63 -0
- package/lib/programmatic/openapi-manifest-schemas.js +141 -0
- package/lib/programmatic/openapi-operation-bindings.js +274 -0
- package/lib/programmatic/openapi-request-schemas.js +155 -0
- package/lib/programmatic/openapi-result-schemas.js +493 -0
- package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
- package/lib/programmatic/openapi-schema-descriptions-core.js +162 -0
- package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
- package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
- package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
- package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
- package/lib/programmatic/openapi-schema-helpers.js +108 -0
- package/lib/programmatic/openapi-spec.js +203 -0
- package/lib/programmatic/orchestration-openapi-meta.js +159 -0
- package/lib/programmatic/platform-rbac-catalog.js +90 -0
- package/lib/programmatic/request-timeout.js +53 -0
- package/lib/programmatic/route-handler-map.js +143 -0
- package/lib/programmatic/route-handlers-context.js +29 -0
- package/lib/programmatic/route-handlers.js +33 -0
- package/lib/programmatic/run-certify.js +57 -0
- package/lib/programmatic/run-enterprise-mcp.js +32 -0
- package/lib/programmatic/run-lifecycle.js +29 -0
- package/lib/programmatic/run-repair.js +41 -0
- package/lib/programmatic/run-repository-emcp.js +62 -0
- package/lib/programmatic/run-template-workspace.js +74 -0
- package/lib/programmatic/run-test.js +49 -0
- package/lib/programmatic/run-upload.js +63 -0
- package/lib/programmatic/run-validate.js +53 -0
- package/lib/programmatic/run-wizard.js +40 -0
- package/lib/programmatic/system-key.js +48 -0
- package/lib/programmatic/wizard-config-normalize.js +118 -0
- package/lib/programmatic/workspace-cleanup.js +128 -0
- package/lib/programmatic/workspace-context.js +145 -0
- package/lib/programmatic/workspace-lock.js +75 -0
- package/lib/programmatic/workspace-meta.js +64 -0
- package/lib/programmatic/workspace-ops.js +149 -0
- package/lib/protection/run-commands-upload-sync.js +35 -0
- package/lib/protection/run-commands.js +2 -20
- package/lib/protection/upload-batch.js +11 -7
- package/lib/resolvers/evidence-kind-file.js +230 -0
- package/lib/resolvers/resource-type-file.js +58 -1
- package/lib/resolvers/role-file.js +227 -0
- package/lib/schema/application-schema.json +22 -2
- package/lib/schema/external-datasource.schema.json +245 -2
- package/lib/schema/external-system.schema.json +259 -119
- package/lib/schema/flag-map-validation-run.json +3 -0
- package/lib/schema/infra.parameter.yaml +25 -1
- package/lib/schema/type/credential-field-registry.json +21 -5
- package/lib/schema/type/document-storage.json +9 -0
- package/lib/utils/agent-trust-run-display.js +1 -1
- package/lib/utils/api.js +8 -2
- package/lib/utils/app-path-resolve.js +168 -0
- package/lib/utils/app-register-config.js +4 -3
- package/lib/utils/authentication-env-template.js +222 -0
- package/lib/utils/cli-sync-options.js +62 -10
- package/lib/utils/cli-utils.js +15 -3
- package/lib/utils/cli-workspace-options.js +29 -0
- package/lib/utils/compose-generate-docker-compose.js +102 -0
- package/lib/utils/configuration-env-resolver.js +203 -27
- package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
- package/lib/utils/datasource-test-run-certification-debug.js +130 -0
- package/lib/utils/datasource-test-run-debug-display.js +2 -0
- package/lib/utils/datasource-test-run-debug-slice.js +7 -0
- package/lib/utils/datasource-test-run-display.js +2 -1
- package/lib/utils/dev-ca-install.js +5 -6
- package/lib/utils/dev-config.js +2 -2
- package/lib/utils/dev-init-ssh-merge.js +165 -23
- package/lib/utils/dev-list-sort.js +145 -0
- package/lib/utils/dev-pin-share-instructions.js +110 -0
- package/lib/utils/dev-platform-tls.js +0 -63
- package/lib/utils/dev-ssh-config-helper.js +177 -33
- package/lib/utils/docker-build.js +46 -27
- package/lib/utils/docker-daemon-tls-ca.js +1 -1
- package/lib/utils/docker-exec.js +91 -6
- package/lib/utils/enterprise-knowledge-paths.js +142 -0
- package/lib/utils/env-copy.js +3 -4
- package/lib/utils/env-dotenv-format.js +103 -0
- package/lib/utils/error-formatters/error-parser.js +0 -3
- package/lib/utils/external-env-template.js +5 -2
- package/lib/utils/external-system-display.js +5 -1
- package/lib/utils/external-system-readiness-compact-blocks.js +248 -0
- package/lib/utils/external-system-readiness-compact-display.js +324 -0
- package/lib/utils/external-system-readiness-core.js +16 -0
- package/lib/utils/external-system-readiness-deploy-display.js +29 -11
- package/lib/utils/external-system-readiness-display-internals.js +3 -1
- package/lib/utils/external-system-readiness-display.js +20 -30
- package/lib/utils/external-system-system-test-tty-certification.js +135 -0
- package/lib/utils/external-system-system-test-tty.js +5 -41
- package/lib/utils/health-check-request.js +2 -3
- package/lib/utils/help-builder.js +9 -1
- package/lib/utils/host-ops-job-labels.js +236 -0
- package/lib/utils/host-ops-job-result.js +61 -0
- package/lib/utils/host-ops-poll-ui.js +163 -0
- package/lib/utils/image-name.js +22 -4
- package/lib/utils/integration-path-resolve.js +112 -0
- package/lib/utils/logger.js +37 -4
- package/lib/utils/manifest-source-emit.js +1 -1
- package/lib/utils/paths-reload-source.js +148 -0
- package/lib/utils/paths-system-builder-keys.js +25 -0
- package/lib/utils/paths.js +183 -30
- package/lib/utils/pipeline-upload-auth-retry.js +4 -0
- package/lib/utils/postgres-platform-bootstrap.js +24 -17
- package/lib/utils/postgres-wipe.js +5 -2
- package/lib/utils/remote-dev-auth.js +39 -4
- package/lib/utils/resolve-docker-image-ref.js +36 -6
- package/lib/utils/runtime-configuration-values.js +64 -2
- package/lib/utils/secrets-helpers.js +5 -1
- package/lib/utils/ssh-known-hosts.js +130 -0
- package/lib/utils/test-target-cli-options.js +75 -0
- package/lib/utils/token-manager.js +16 -0
- package/lib/utils/upload-sync-options.js +20 -2
- package/lib/utils/validation-run-request.js +11 -2
- package/lib/validation/external-manifest-validator.js +11 -1
- package/lib/validation/openapi-contract-surface-validator.js +430 -0
- package/lib/validation/openapi-contract-vendor-validation.js +238 -0
- package/lib/validation/validate-external-file.js +160 -0
- package/lib/validation/validate.js +6 -117
- package/lib/validation/validator.js +6 -5
- package/package.json +76 -37
- package/packages/builder-api/README.md +120 -0
- package/packages/builder-api/package.json +30 -0
- package/packages/builder-api/src/app.module.ts +7 -0
- package/packages/builder-api/src/auth/auth.module.ts +5 -0
- package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
- package/packages/builder-api/src/main.ts +16 -0
- package/packages/builder-api/tsconfig.json +15 -0
- package/scripts/check-builder-api-architecture-grep.js +79 -0
- package/scripts/docker_image_content_gate.js +47 -0
- package/scripts/docker_image_content_gate.sh +5 -0
- package/scripts/export-builder-api-evidence.js +262 -0
- package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
- package/scripts/lib/builder-api-docker-staging-core.js +183 -0
- package/scripts/lib/docker-image-content-gate-core.js +166 -0
- package/scripts/lib/plan-actor.js +109 -0
- package/scripts/lib/plan-config.js +20 -0
- package/scripts/lib/plan-gates.js +154 -0
- package/scripts/lib/plan-meta.js +104 -0
- package/scripts/lib/plan-parse.js +162 -0
- package/scripts/lib/plan-prevalidate-gates.js +337 -0
- package/scripts/lib/plan-run-core.js +125 -0
- package/scripts/lib/plan-run-report.js +119 -0
- package/scripts/plan-approve.js +24 -0
- package/scripts/plan-archive.js +49 -0
- package/scripts/plan-run.js +13 -0
- package/scripts/plan-set-actor.js +21 -0
- package/scripts/plan-validate.js +80 -0
- package/scripts/pnpm/af.mjs +110 -0
- package/scripts/pnpm/check-quiet.mjs +32 -0
- package/scripts/pnpm/dev-install.mjs +29 -0
- package/scripts/pnpm/dev-reload.mjs +18 -0
- package/scripts/pnpm/help.mjs +55 -0
- package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
- package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
- package/scripts/pnpm/lib/spinner.mjs +42 -0
- package/scripts/stage_builder_api_for_docker.js +65 -0
- package/scripts/sync-builder-api-template.js +44 -0
- package/templates/README.md +3 -0
- package/templates/applications/builder-api/Dockerfile +38 -0
- package/templates/applications/builder-api/application.yaml +75 -0
- package/templates/applications/builder-api/env.template +48 -0
- package/templates/applications/dataplane/application.yaml +27 -5
- package/templates/applications/dataplane/env.template +38 -15
- package/templates/applications/dataplane/rbac.yaml +85 -3
- package/templates/applications/miso-controller/application.yaml +10 -1
- package/templates/applications/miso-controller/env.template +11 -10
- package/templates/applications/miso-controller/rbac.yaml +72 -0
- package/templates/channels/README.md +18 -0
- package/templates/channels/ai-fabrix-icon.jpg +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +21 -24
- package/templates/channels/chatgpt/integration/README.md +11 -0
- package/templates/channels/chatgpt/integration/application.json +15 -0
- package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
- package/templates/channels/chatgpt/integration/env.template +4 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
- package/templates/channels/microsoft-copilot/integration/README.md +11 -0
- package/templates/channels/microsoft-copilot/integration/application.json +15 -0
- package/templates/channels/microsoft-copilot/integration/env.template +6 -0
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
- package/templates/channels/slack/install.template.md.hbs +48 -18
- package/templates/channels/slack/integration/README.md +38 -0
- package/templates/channels/slack/integration/application.json +18 -0
- package/templates/channels/slack/integration/env.template +29 -0
- package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
- package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
- package/templates/channels/slack/integration/slack-system.json +144 -0
- package/templates/channels/slack/manifest.template.json.hbs +20 -10
- package/templates/channels/teams-bot/install.template.md.hbs +31 -17
- package/templates/channels/teams-bot/integration/README.md +18 -0
- package/templates/channels/teams-bot/integration/application.json +17 -0
- package/templates/channels/teams-bot/integration/env.template +5 -0
- package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
- package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
- package/templates/channels/web-embed/install.template.md.hbs +16 -26
- package/templates/channels/web-embed/integration/README.md +11 -0
- package/templates/channels/web-embed/integration/application.json +15 -0
- package/templates/channels/web-embed/integration/env.template +4 -0
- package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
- package/templates/openapi/redoc_page.html +86 -0
- package/templates/python/docker-compose.hbs +11 -0
- package/templates/python/requirements.txt +2 -2
- package/templates/typescript/docker-compose.hbs +11 -0
- package/lib/certification/cli-cert-sync-skip.js +0 -21
|
@@ -6,18 +6,49 @@
|
|
|
6
6
|
|
|
7
7
|
const nodeFsLib = require('../internal/node-fs');
|
|
8
8
|
const path = require('path');
|
|
9
|
-
const { ensureSshDir } = require('./ssh-key-helper');
|
|
9
|
+
const { ensureSshDir, getDefaultEd25519PrivateKeyPath } = require('./ssh-key-helper');
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
* @param {string} sshUser
|
|
14
|
-
* @param {string} sshHost
|
|
12
|
+
* Legacy SSH Host alias: sync user + builder API hostname (e.g. dev03.builder01.aifabrix.dev).
|
|
13
|
+
* @param {string} sshUser
|
|
14
|
+
* @param {string} sshHost
|
|
15
15
|
* @returns {string}
|
|
16
16
|
*/
|
|
17
17
|
function getDevSshHostAlias(sshUser, sshHost) {
|
|
18
18
|
return `${sshUser}.${sshHost}`;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* @param {string|number} developerId
|
|
23
|
+
* @returns {string}
|
|
24
|
+
*/
|
|
25
|
+
function formatDeveloperNumericId(developerId) {
|
|
26
|
+
const trimmed = String(developerId ?? '').trim();
|
|
27
|
+
if (/^\d+$/.test(trimmed)) {
|
|
28
|
+
return String(parseInt(trimmed, 10)).padStart(2, '0');
|
|
29
|
+
}
|
|
30
|
+
return trimmed.replace(/^dev/i, '');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Preferred SSH config Host alias — matches per-developer app host when developer-root-domain is set.
|
|
35
|
+
*
|
|
36
|
+
* @param {Object} p
|
|
37
|
+
* @param {string} p.syncUser
|
|
38
|
+
* @param {string} p.syncHost - sync-ssh-host (HostName for TCP connect)
|
|
39
|
+
* @param {string|number} [p.developerId]
|
|
40
|
+
* @param {string} [p.developerRootDomain] - e.g. aifabrix.dev → dev03.aifabrix.dev; dev.aifabrix → dev03.dev.aifabrix
|
|
41
|
+
* @returns {string}
|
|
42
|
+
*/
|
|
43
|
+
function resolveDevSshHostAlias(p) {
|
|
44
|
+
const root = String(p.developerRootDomain || '').trim().replace(/^\.+|\.+$/g, '');
|
|
45
|
+
const id = p.developerId !== undefined && p.developerId !== null ? String(p.developerId).trim() : '';
|
|
46
|
+
if (root && id) {
|
|
47
|
+
return `dev${formatDeveloperNumericId(id)}.${root}`;
|
|
48
|
+
}
|
|
49
|
+
return getDevSshHostAlias(p.syncUser, p.syncHost);
|
|
50
|
+
}
|
|
51
|
+
|
|
21
52
|
/**
|
|
22
53
|
* Parse ssh config into Host blocks (lines before the first Host are ignored).
|
|
23
54
|
* @param {string} content
|
|
@@ -91,6 +122,48 @@ function resolveConnectAlias(matchedBlock, canonicalAlias) {
|
|
|
91
122
|
return matchedBlock.aliases[0] || canonicalAlias;
|
|
92
123
|
}
|
|
93
124
|
|
|
125
|
+
/**
|
|
126
|
+
* @param {string[]} body
|
|
127
|
+
* @param {string} hostname
|
|
128
|
+
* @param {string} user
|
|
129
|
+
* @returns {boolean}
|
|
130
|
+
*/
|
|
131
|
+
function isSshHostBlockForUserHost(body, hostname, user) {
|
|
132
|
+
return (
|
|
133
|
+
getHostBlockDirective(body, 'HostName') === hostname &&
|
|
134
|
+
getHostBlockDirective(body, 'User') === user
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Drop Host blocks that target the same HostName + User (legacy alias migration).
|
|
140
|
+
* @param {string} content
|
|
141
|
+
* @param {string} hostname
|
|
142
|
+
* @param {string} user
|
|
143
|
+
* @returns {string}
|
|
144
|
+
*/
|
|
145
|
+
function removeSshHostBlocksForUserHost(content, hostname, user) {
|
|
146
|
+
const lines = (content || '').split(/\r?\n/);
|
|
147
|
+
const out = [];
|
|
148
|
+
for (let i = 0; i < lines.length; i++) {
|
|
149
|
+
const m = lines[i].match(/^Host\s+(.+?)\s*$/i);
|
|
150
|
+
if (!m) {
|
|
151
|
+
out.push(lines[i]);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const body = [];
|
|
155
|
+
i++;
|
|
156
|
+
while (i < lines.length && !/^Host\s/i.test(lines[i])) {
|
|
157
|
+
body.push(lines[i++]);
|
|
158
|
+
}
|
|
159
|
+
if (!isSshHostBlockForUserHost(body, hostname, user)) {
|
|
160
|
+
out.push(`Host ${m[1].trim()}`, ...body);
|
|
161
|
+
}
|
|
162
|
+
i--;
|
|
163
|
+
}
|
|
164
|
+
return out.join('\n').replace(/\s+$/, '');
|
|
165
|
+
}
|
|
166
|
+
|
|
94
167
|
/**
|
|
95
168
|
* Replace an existing Host block for hostAlias, or append a new block at EOF.
|
|
96
169
|
* @param {string} content - Existing ssh config (may be empty)
|
|
@@ -100,7 +173,8 @@ function resolveConnectAlias(matchedBlock, canonicalAlias) {
|
|
|
100
173
|
* @returns {string} Updated config
|
|
101
174
|
*/
|
|
102
175
|
function upsertSshHostBlock(content, hostAlias, hostname, user) {
|
|
103
|
-
const
|
|
176
|
+
const withoutDupes = removeSshHostBlocksForUserHost(content, hostname, user);
|
|
177
|
+
const lines = (withoutDupes || '').split(/\r?\n/);
|
|
104
178
|
const out = [];
|
|
105
179
|
let i = 0;
|
|
106
180
|
while (i < lines.length) {
|
|
@@ -123,6 +197,7 @@ function upsertSshHostBlock(content, hostAlias, hostname, user) {
|
|
|
123
197
|
`Host ${hostAlias}`,
|
|
124
198
|
` HostName ${hostname}`,
|
|
125
199
|
` User ${user}`,
|
|
200
|
+
` IdentityFile ${getDefaultEd25519PrivateKeyPath().replace(/\\/g, '/')}`,
|
|
126
201
|
' IdentitiesOnly yes'
|
|
127
202
|
].join('\n');
|
|
128
203
|
const trimmed = out.join('\n').replace(/\s+$/, '');
|
|
@@ -130,12 +205,27 @@ function upsertSshHostBlock(content, hostAlias, hostname, user) {
|
|
|
130
205
|
return `${prefix}${block}\n`;
|
|
131
206
|
}
|
|
132
207
|
|
|
208
|
+
function listHostAliasesForUserHost(content, hostname, user) {
|
|
209
|
+
const aliases = [];
|
|
210
|
+
for (const block of parseSshHostBlocks(content)) {
|
|
211
|
+
const hn = getHostBlockDirective(block.body, 'HostName');
|
|
212
|
+
const u = getHostBlockDirective(block.body, 'User');
|
|
213
|
+
if (hn === hostname && u === user) {
|
|
214
|
+
aliases.push(...block.aliases);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return aliases;
|
|
218
|
+
}
|
|
219
|
+
|
|
133
220
|
/**
|
|
134
221
|
* @param {string} sshUser
|
|
135
222
|
* @param {string} sshHost
|
|
136
|
-
* @
|
|
223
|
+
* @param {Object} [options]
|
|
224
|
+
* @param {string|number} [options.developerId]
|
|
225
|
+
* @param {string} [options.developerRootDomain]
|
|
226
|
+
* @returns {{ error: string }|{ user: string, host: string, hostAlias: string, legacyHostAlias: string }}
|
|
137
227
|
*/
|
|
138
|
-
function parseEnsureSshInputs(sshUser, sshHost) {
|
|
228
|
+
function parseEnsureSshInputs(sshUser, sshHost, options = {}) {
|
|
139
229
|
if (!sshUser || typeof sshUser !== 'string' || !sshUser.trim()) {
|
|
140
230
|
return { error: 'missing ssh user' };
|
|
141
231
|
}
|
|
@@ -144,7 +234,53 @@ function parseEnsureSshInputs(sshUser, sshHost) {
|
|
|
144
234
|
}
|
|
145
235
|
const user = sshUser.trim();
|
|
146
236
|
const host = sshHost.trim();
|
|
147
|
-
|
|
237
|
+
const hostAlias = resolveDevSshHostAlias({
|
|
238
|
+
syncUser: user,
|
|
239
|
+
syncHost: host,
|
|
240
|
+
developerId: options.developerId,
|
|
241
|
+
developerRootDomain: options.developerRootDomain
|
|
242
|
+
});
|
|
243
|
+
return {
|
|
244
|
+
user,
|
|
245
|
+
host,
|
|
246
|
+
hostAlias,
|
|
247
|
+
legacyHostAlias: getDevSshHostAlias(user, host)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @param {string} configPath
|
|
253
|
+
* @returns {Promise<{ content: string }|{ error: string }>}
|
|
254
|
+
*/
|
|
255
|
+
async function readExistingSshConfig(configPath) {
|
|
256
|
+
try {
|
|
257
|
+
const content = await nodeFsLib.nodeFs().promises.readFile(configPath, 'utf8');
|
|
258
|
+
return { content };
|
|
259
|
+
} catch (e) {
|
|
260
|
+
if (e.code === 'ENOENT') {
|
|
261
|
+
return { content: '' };
|
|
262
|
+
}
|
|
263
|
+
return { error: e.message || String(e) };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* @param {{ aliases: string[], body: string[] }|null} matched
|
|
269
|
+
* @param {string} hostAlias
|
|
270
|
+
* @param {string} rootDomain
|
|
271
|
+
* @returns {{ skip: true, hostAlias: string }|{ skip: false, matched: typeof matched }}
|
|
272
|
+
*/
|
|
273
|
+
function resolveExistingSshBlock(matched, hostAlias, rootDomain) {
|
|
274
|
+
if (!matched) {
|
|
275
|
+
return { skip: false, matched: null };
|
|
276
|
+
}
|
|
277
|
+
const matchedAlias = resolveConnectAlias(matched, hostAlias);
|
|
278
|
+
const keepExisting =
|
|
279
|
+
!rootDomain || (matched.aliases.includes(hostAlias) && matchedAlias === hostAlias);
|
|
280
|
+
if (keepExisting) {
|
|
281
|
+
return { skip: true, hostAlias: matchedAlias };
|
|
282
|
+
}
|
|
283
|
+
return { skip: false, matched };
|
|
148
284
|
}
|
|
149
285
|
|
|
150
286
|
/**
|
|
@@ -152,44 +288,52 @@ function parseEnsureSshInputs(sshUser, sshHost) {
|
|
|
152
288
|
* @param {string} sshUser - SSH user (sync-ssh-user)
|
|
153
289
|
* @param {string} sshHost - Real hostname (sync-ssh-host)
|
|
154
290
|
* @param {string} [sshDir] - SSH directory (default ~/.ssh)
|
|
155
|
-
* @
|
|
291
|
+
* @param {Object} [options]
|
|
292
|
+
* @param {string|number} [options.developerId]
|
|
293
|
+
* @param {string} [options.developerRootDomain]
|
|
294
|
+
* @returns {Promise<{ ok: boolean, configPath?: string, hostAlias?: string, error?: string, skippedDuplicate?: boolean, updated?: boolean }>}
|
|
156
295
|
*/
|
|
157
|
-
async function ensureDevSshConfigBlock(sshUser, sshHost, sshDir) {
|
|
158
|
-
const parsed = parseEnsureSshInputs(sshUser, sshHost);
|
|
296
|
+
async function ensureDevSshConfigBlock(sshUser, sshHost, sshDir, options = {}) {
|
|
297
|
+
const parsed = parseEnsureSshInputs(sshUser, sshHost, options);
|
|
159
298
|
if ('error' in parsed) {
|
|
160
299
|
return { ok: false, error: parsed.error };
|
|
161
300
|
}
|
|
162
|
-
const { user, host, hostAlias } = parsed;
|
|
163
|
-
const
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
301
|
+
const { user, host, hostAlias, legacyHostAlias } = parsed;
|
|
302
|
+
const configPath = path.join(ensureSshDir(sshDir), 'config');
|
|
303
|
+
const readResult = await readExistingSshConfig(configPath);
|
|
304
|
+
if ('error' in readResult) {
|
|
305
|
+
return { ok: false, error: readResult.error };
|
|
306
|
+
}
|
|
307
|
+
const rootDomain = String(options.developerRootDomain || '').trim();
|
|
308
|
+
const matched = findMatchingHostBlockForUserHost(readResult.content, host, user);
|
|
309
|
+
const existing = resolveExistingSshBlock(matched, hostAlias, rootDomain);
|
|
310
|
+
if (existing.skip) {
|
|
311
|
+
return { ok: true, configPath, hostAlias: existing.hostAlias, skippedDuplicate: true };
|
|
172
312
|
}
|
|
173
|
-
const
|
|
174
|
-
if (
|
|
175
|
-
return {
|
|
176
|
-
ok: true,
|
|
177
|
-
configPath,
|
|
178
|
-
hostAlias: resolveConnectAlias(matched, hostAlias),
|
|
179
|
-
skippedDuplicate: true
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
const next = upsertSshHostBlock(existing, hostAlias, host, user);
|
|
183
|
-
if (next === existing) {
|
|
313
|
+
const next = upsertSshHostBlock(readResult.content, hostAlias, host, user);
|
|
314
|
+
if (next === readResult.content) {
|
|
184
315
|
return { ok: true, configPath, hostAlias };
|
|
185
316
|
}
|
|
186
317
|
await nodeFsLib.nodeFs().promises.writeFile(configPath, next, { mode: 0o600 });
|
|
187
|
-
|
|
318
|
+
const migratedFrom = existing.matched
|
|
319
|
+
? resolveConnectAlias(existing.matched, hostAlias)
|
|
320
|
+
: legacyHostAlias;
|
|
321
|
+
return {
|
|
322
|
+
ok: true,
|
|
323
|
+
configPath,
|
|
324
|
+
hostAlias,
|
|
325
|
+
updated: true,
|
|
326
|
+
migratedFrom: migratedFrom !== hostAlias ? migratedFrom : undefined
|
|
327
|
+
};
|
|
188
328
|
}
|
|
189
329
|
|
|
190
330
|
module.exports = {
|
|
331
|
+
formatDeveloperNumericId,
|
|
191
332
|
getDevSshHostAlias,
|
|
333
|
+
resolveDevSshHostAlias,
|
|
192
334
|
findMatchingHostBlockForUserHost,
|
|
335
|
+
listHostAliasesForUserHost,
|
|
336
|
+
removeSshHostBlocksForUserHost,
|
|
193
337
|
resolveConnectAlias,
|
|
194
338
|
upsertSshHostBlock,
|
|
195
339
|
ensureDevSshConfigBlock
|
|
@@ -110,25 +110,15 @@ function buildDockerCliArgs(imageName, tag, dockerfilePath, contextPath, buildAr
|
|
|
110
110
|
return args;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
function
|
|
114
|
-
const {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
env = {},
|
|
123
|
-
buildArgs = {},
|
|
124
|
-
noCache = false
|
|
125
|
-
} = buildOpts;
|
|
126
|
-
const spawnEnv = { ...process.env, ...env };
|
|
127
|
-
const args = buildDockerCliArgs(imageName, tag, dockerfilePath, contextPath, buildArgs, noCache);
|
|
128
|
-
const dockerProcess = spawn('docker', args, {
|
|
129
|
-
shell: process.platform === 'win32',
|
|
130
|
-
env: spawnEnv
|
|
131
|
-
});
|
|
113
|
+
function createDockerSpawnParams(options) {
|
|
114
|
+
const { imageName, tag, dockerfilePath, contextPath, buildArgs, noCache, env } = options;
|
|
115
|
+
const spawnEnv = { ...process.env, ...(env || {}) };
|
|
116
|
+
const args = buildDockerCliArgs(imageName, tag, dockerfilePath, contextPath, buildArgs || {}, noCache);
|
|
117
|
+
return { spawnEnv, args };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function attachDockerBuildListeners(dockerProcess, context) {
|
|
121
|
+
const { imageName, tag, spinner, resolve, reject } = context;
|
|
132
122
|
let stdoutBuffer = '';
|
|
133
123
|
let stderrBuffer = '';
|
|
134
124
|
const lastProgressUpdateRef = { current: Date.now() };
|
|
@@ -162,6 +152,35 @@ function runDockerBuildProcess(buildOpts) {
|
|
|
162
152
|
});
|
|
163
153
|
}
|
|
164
154
|
|
|
155
|
+
function runDockerBuildProcess(buildOpts) {
|
|
156
|
+
const {
|
|
157
|
+
imageName,
|
|
158
|
+
tag,
|
|
159
|
+
dockerfilePath,
|
|
160
|
+
contextPath,
|
|
161
|
+
spinner,
|
|
162
|
+
resolve,
|
|
163
|
+
reject,
|
|
164
|
+
env = {},
|
|
165
|
+
buildArgs = {},
|
|
166
|
+
noCache = false
|
|
167
|
+
} = buildOpts;
|
|
168
|
+
const { spawnEnv, args } = createDockerSpawnParams({
|
|
169
|
+
imageName,
|
|
170
|
+
tag,
|
|
171
|
+
dockerfilePath,
|
|
172
|
+
contextPath,
|
|
173
|
+
buildArgs,
|
|
174
|
+
noCache,
|
|
175
|
+
env
|
|
176
|
+
});
|
|
177
|
+
const dockerProcess = spawn('docker', args, {
|
|
178
|
+
shell: process.platform === 'win32',
|
|
179
|
+
env: spawnEnv
|
|
180
|
+
});
|
|
181
|
+
attachDockerBuildListeners(dockerProcess, { imageName, tag, spinner, resolve, reject });
|
|
182
|
+
}
|
|
183
|
+
|
|
165
184
|
/**
|
|
166
185
|
* Executes Docker build command with progress indicator
|
|
167
186
|
* @param {string} imageName - Image name to build
|
|
@@ -236,12 +255,10 @@ async function executeBuild(imageName, dockerfilePath, contextPath, tag, options
|
|
|
236
255
|
|
|
237
256
|
// Tag image if additional tag provided
|
|
238
257
|
if (options && options.tag && options.tag !== 'latest') {
|
|
239
|
-
const {
|
|
240
|
-
const { exec } = require('child_process');
|
|
241
|
-
const run = promisify(exec);
|
|
258
|
+
const { execFileWithDockerEnv } = require('./docker-exec');
|
|
242
259
|
const { getDockerExecEnv } = require('./remote-docker-env');
|
|
243
260
|
const env = await getDockerExecEnv();
|
|
244
|
-
await
|
|
261
|
+
await execFileWithDockerEnv('docker', ['tag', `${imageName}:${tag}`, `${imageName}:latest`], { env });
|
|
245
262
|
}
|
|
246
263
|
}
|
|
247
264
|
|
|
@@ -270,12 +287,14 @@ async function executeDockerBuildWithTag(effectiveImageName, imageName, dockerfi
|
|
|
270
287
|
}
|
|
271
288
|
|
|
272
289
|
try {
|
|
273
|
-
const {
|
|
274
|
-
const { exec } = require('child_process');
|
|
275
|
-
const run = promisify(exec);
|
|
290
|
+
const { execFileWithDockerEnv } = require('./docker-exec');
|
|
276
291
|
const { getDockerExecEnv } = require('./remote-docker-env');
|
|
277
292
|
const env = await getDockerExecEnv();
|
|
278
|
-
await
|
|
293
|
+
await execFileWithDockerEnv(
|
|
294
|
+
'docker',
|
|
295
|
+
['tag', `${effectiveImageName}:${tag}`, `${imageName}:${tag}`],
|
|
296
|
+
{ env }
|
|
297
|
+
);
|
|
279
298
|
logger.log(formatSuccessLine(`Tagged image: ${imageName}:${tag}`));
|
|
280
299
|
} catch (err) {
|
|
281
300
|
logger.log(
|
package/lib/utils/docker-exec.js
CHANGED
|
@@ -9,9 +9,85 @@
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
11
|
const { promisify } = require('util');
|
|
12
|
-
const
|
|
12
|
+
const childProcess = require('child_process');
|
|
13
|
+
const execFileAsync = childProcess.execFile ? promisify(childProcess.execFile) : null;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Parse a command string into argv tokens without invoking a shell.
|
|
17
|
+
* Supports simple single/double quoted segments and escaping quotes within double quotes.
|
|
18
|
+
* @param {string} command
|
|
19
|
+
* @returns {string[]}
|
|
20
|
+
*/
|
|
21
|
+
// eslint-disable-next-line max-statements, complexity -- tokenizer intentionally handles quoted token edge-cases in one place
|
|
22
|
+
function parseCommandTokens(command) {
|
|
23
|
+
const input = String(command || '');
|
|
24
|
+
if (!input.trim()) {
|
|
25
|
+
throw new Error('Command must be a non-empty string');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @type {string[]} */
|
|
29
|
+
const tokens = [];
|
|
30
|
+
let current = '';
|
|
31
|
+
let quote = null;
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
34
|
+
const ch = input[i];
|
|
35
|
+
if (quote === null && (ch === '"' || ch === '\'')) {
|
|
36
|
+
quote = ch;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (quote !== null && ch === quote) {
|
|
40
|
+
quote = null;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
// Bash double-quote escapes: \", \\, \$, \`, and escaped newlines.
|
|
44
|
+
if (quote === '"' && ch === '\\') {
|
|
45
|
+
const next = input[i + 1];
|
|
46
|
+
if (next === '"' || next === '\\' || next === '$' || next === '`' || next === '\n') {
|
|
47
|
+
current += next;
|
|
48
|
+
i += 1;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (quote === null && /\s/.test(ch)) {
|
|
53
|
+
if (current) {
|
|
54
|
+
tokens.push(current);
|
|
55
|
+
current = '';
|
|
56
|
+
}
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
current += ch;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (quote !== null) {
|
|
63
|
+
throw new Error('Unterminated quote in command');
|
|
64
|
+
}
|
|
65
|
+
if (current) {
|
|
66
|
+
tokens.push(current);
|
|
67
|
+
}
|
|
68
|
+
if (!tokens.length) {
|
|
69
|
+
throw new Error('Command produced no executable token');
|
|
70
|
+
}
|
|
71
|
+
return tokens;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Run an executable with argv and remote Docker env settings.
|
|
76
|
+
* @param {string} file
|
|
77
|
+
* @param {string[]} [args]
|
|
78
|
+
* @param {import('child_process').ExecFileOptions} [options]
|
|
79
|
+
* @returns {Promise<{ stdout: string, stderr: string }>}
|
|
80
|
+
*/
|
|
81
|
+
async function execFileWithDockerEnv(file, args = [], options = {}) {
|
|
82
|
+
const { getDockerExecEnv } = require('./remote-docker-env');
|
|
83
|
+
const env = { ...(await getDockerExecEnv()), ...(options.env || {}) };
|
|
84
|
+
if (execFileAsync) {
|
|
85
|
+
return execFileAsync(file, args, { ...options, env });
|
|
86
|
+
}
|
|
87
|
+
const execAsync = promisify(childProcess.exec);
|
|
88
|
+
const command = [file, ...args.map((arg) => String(arg))].join(' ');
|
|
89
|
+
return execAsync(command, { ...options, env });
|
|
90
|
+
}
|
|
15
91
|
|
|
16
92
|
/**
|
|
17
93
|
* Run a shell command with process.env merged with remote Docker client settings when docker-endpoint is set.
|
|
@@ -20,9 +96,18 @@ const execAsync = promisify(exec);
|
|
|
20
96
|
* @returns {Promise<{ stdout: string, stderr: string }>}
|
|
21
97
|
*/
|
|
22
98
|
async function execWithDockerEnv(command, options = {}) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
99
|
+
if (!execFileAsync || process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined) {
|
|
100
|
+
const { getDockerExecEnv } = require('./remote-docker-env');
|
|
101
|
+
const env = { ...(await getDockerExecEnv()), ...(options.env || {}) };
|
|
102
|
+
const execAsync = promisify(childProcess.exec);
|
|
103
|
+
return execAsync(command, { ...options, env });
|
|
104
|
+
}
|
|
105
|
+
const [file, ...args] = parseCommandTokens(command);
|
|
106
|
+
return execFileWithDockerEnv(file, args, options);
|
|
26
107
|
}
|
|
27
108
|
|
|
28
|
-
module.exports = {
|
|
109
|
+
module.exports = {
|
|
110
|
+
execWithDockerEnv,
|
|
111
|
+
execFileWithDockerEnv,
|
|
112
|
+
parseCommandTokens
|
|
113
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enterprise Knowledge workspace path helpers (456.5).
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Paths under enterprise-knowledge/ for Enterprise Knowledge anchors
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const os = require('os');
|
|
13
|
+
const { nodeFs } = require('../internal/node-fs');
|
|
14
|
+
|
|
15
|
+
const WORKSPACE_ENTERPRISE_KNOWLEDGE = 'enterprise-knowledge';
|
|
16
|
+
const SYSTEM_KIND_ENTERPRISE_KNOWLEDGE = 'enterpriseKnowledge';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Materialization parent without importing paths.js (avoids circular deps in tests).
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
function getMaterializationParent() {
|
|
23
|
+
const work = process.env.AIFABRIX_WORK;
|
|
24
|
+
if (work && typeof work === 'string' && work.trim()) {
|
|
25
|
+
return path.resolve(work.trim());
|
|
26
|
+
}
|
|
27
|
+
if (process.env.AIFABRIX_HOME && typeof process.env.AIFABRIX_HOME === 'string') {
|
|
28
|
+
return path.resolve(process.env.AIFABRIX_HOME.trim());
|
|
29
|
+
}
|
|
30
|
+
return path.join(os.homedir(), '.aifabrix');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Absolute enterprise-knowledge/ next to process.cwd when present.
|
|
35
|
+
* @returns {string|null}
|
|
36
|
+
*/
|
|
37
|
+
function getCwdEnterpriseKnowledgeRoot() {
|
|
38
|
+
const p = path.join(path.resolve(process.cwd()), WORKSPACE_ENTERPRISE_KNOWLEDGE);
|
|
39
|
+
try {
|
|
40
|
+
const disk = nodeFs();
|
|
41
|
+
if (disk.existsSync(p)) {
|
|
42
|
+
const st = disk.statSync(p);
|
|
43
|
+
if (st && typeof st.isDirectory === 'function' && st.isDirectory()) {
|
|
44
|
+
return p;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch {
|
|
48
|
+
// ignore
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Default enterprise-knowledge root under materialization parent.
|
|
55
|
+
* @returns {string}
|
|
56
|
+
*/
|
|
57
|
+
function getEnterpriseKnowledgeRoot() {
|
|
58
|
+
const cwdRoot = getCwdEnterpriseKnowledgeRoot();
|
|
59
|
+
if (cwdRoot) {
|
|
60
|
+
return cwdRoot;
|
|
61
|
+
}
|
|
62
|
+
return path.join(getMaterializationParent(), WORKSPACE_ENTERPRISE_KNOWLEDGE);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Resolves enterprise-knowledge/<anchorKey> (cwd-first, then materialization parent).
|
|
67
|
+
* @param {string} anchorKey - Enterprise Knowledge anchor key
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
70
|
+
function getEnterpriseKnowledgePath(anchorKey) {
|
|
71
|
+
if (!anchorKey || typeof anchorKey !== 'string') {
|
|
72
|
+
throw new Error('Anchor key is required and must be a string');
|
|
73
|
+
}
|
|
74
|
+
const cwdHit = path.join(path.resolve(process.cwd()), WORKSPACE_ENTERPRISE_KNOWLEDGE, anchorKey);
|
|
75
|
+
try {
|
|
76
|
+
const disk = nodeFs();
|
|
77
|
+
if (disk.existsSync(cwdHit)) {
|
|
78
|
+
const st = disk.statSync(cwdHit);
|
|
79
|
+
if (st && typeof st.isDirectory === 'function' && st.isDirectory()) {
|
|
80
|
+
return cwdHit;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch {
|
|
84
|
+
// ignore
|
|
85
|
+
}
|
|
86
|
+
return path.join(getMaterializationParent(), WORKSPACE_ENTERPRISE_KNOWLEDGE, anchorKey);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function isEnterpriseKnowledgeDirectory(disk, fullPath) {
|
|
90
|
+
try {
|
|
91
|
+
const child = disk.statSync(fullPath);
|
|
92
|
+
return Boolean(child && typeof child.isDirectory === 'function' && child.isDirectory());
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function collectAnchorNamesInRoot(disk, root, names) {
|
|
99
|
+
if (!root || !disk.existsSync(root) || !isEnterpriseKnowledgeDirectory(disk, root)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
let entries;
|
|
103
|
+
try {
|
|
104
|
+
entries = disk.readdirSync(root);
|
|
105
|
+
} catch {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
for (const name of entries) {
|
|
109
|
+
const full = path.join(root, name);
|
|
110
|
+
if (isEnterpriseKnowledgeDirectory(disk, full)) {
|
|
111
|
+
names.add(name);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Lists anchor folder names under enterprise-knowledge/.
|
|
118
|
+
* @returns {string[]}
|
|
119
|
+
*/
|
|
120
|
+
function listEnterpriseKnowledgeAnchors() {
|
|
121
|
+
const disk = nodeFs();
|
|
122
|
+
const names = new Set();
|
|
123
|
+
const roots = new Set();
|
|
124
|
+
const cwdRoot = getCwdEnterpriseKnowledgeRoot();
|
|
125
|
+
if (cwdRoot) {
|
|
126
|
+
roots.add(path.resolve(cwdRoot));
|
|
127
|
+
}
|
|
128
|
+
roots.add(path.resolve(path.join(getMaterializationParent(), WORKSPACE_ENTERPRISE_KNOWLEDGE)));
|
|
129
|
+
for (const root of roots) {
|
|
130
|
+
collectAnchorNamesInRoot(disk, root, names);
|
|
131
|
+
}
|
|
132
|
+
return [...names].sort();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = {
|
|
136
|
+
WORKSPACE_ENTERPRISE_KNOWLEDGE,
|
|
137
|
+
SYSTEM_KIND_ENTERPRISE_KNOWLEDGE,
|
|
138
|
+
getCwdEnterpriseKnowledgeRoot,
|
|
139
|
+
getEnterpriseKnowledgeRoot,
|
|
140
|
+
getEnterpriseKnowledgePath,
|
|
141
|
+
listEnterpriseKnowledgeAnchors
|
|
142
|
+
};
|
package/lib/utils/env-copy.js
CHANGED
|
@@ -123,7 +123,8 @@ async function writeEnvOutputForReload(outputPath, runEnvPath, appName) {
|
|
|
123
123
|
} else {
|
|
124
124
|
baseContent = runContent;
|
|
125
125
|
}
|
|
126
|
-
|
|
126
|
+
let toWrite = mergeEnvMapIntoContent(baseContent, runMap, { appendMissingFromNewMap: false });
|
|
127
|
+
toWrite = substituteMntDataForLocal(toWrite, outputPath);
|
|
127
128
|
await fsp.writeFile(outputPath, toWrite, { mode: 0o600 });
|
|
128
129
|
logger.log(
|
|
129
130
|
formatSuccessLine(
|
|
@@ -384,9 +385,7 @@ async function processEnvVariables(envPath, variablesPath, appName, secretsPath,
|
|
|
384
385
|
}
|
|
385
386
|
|
|
386
387
|
const label = variables.build.envOutputPath;
|
|
387
|
-
const appPathForLocal =
|
|
388
|
-
(copyOptions && copyOptions.appPath) ||
|
|
389
|
-
(variablesPath ? path.dirname(variablesPath) : null);
|
|
388
|
+
const appPathForLocal = (copyOptions && copyOptions.appPath) || path.dirname(variablesPath);
|
|
390
389
|
const preferLocal =
|
|
391
390
|
copyOptions && typeof copyOptions === 'object' && copyOptions.preferLocalEnvOutputPath === true;
|
|
392
391
|
const freshEnv = copyOptions && typeof copyOptions === 'object' && copyOptions.freshEnv === true;
|