@aifabrix/builder 2.51.1 → 2.52.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/jest.isolated-projects.js +25 -2
- package/jest.projects.js +4 -1
- package/lib/api/datasources-extended.api.js +8 -8
- package/lib/api/keycloak.api.js +92 -0
- package/lib/api/token-providers.api.js +77 -0
- package/lib/api/types/keycloak.types.js +23 -0
- package/lib/api/types/token-providers.types.js +65 -0
- package/lib/app/down.js +16 -1
- package/lib/app/run-container-start.js +4 -0
- package/lib/app/run-deploy-job.js +135 -27
- package/lib/app/run-env-compose.js +32 -0
- package/lib/app/run-env-recovery.js +35 -0
- package/lib/app/run-helpers.js +5 -6
- package/lib/app/run.js +11 -3
- package/lib/channels/add-channel.js +126 -19
- package/lib/channels/approval-guides/chatgpt.js +12 -9
- package/lib/channels/approval-guides/microsoft-copilot.js +16 -12
- package/lib/channels/channel-add-ensure.js +128 -0
- package/lib/channels/channel-artifact-generator.js +11 -1
- package/lib/channels/channel-branding.js +94 -0
- package/lib/channels/channel-credential.js +8 -0
- package/lib/channels/channel-discovery.js +330 -0
- package/lib/channels/channel-external-system.js +1 -1
- package/lib/channels/channel-runtime-resolver.js +103 -14
- package/lib/channels/channel-status-display.js +7 -1
- package/lib/channels/channel-targets.js +18 -1
- package/lib/channels/chatgpt-runtime-contract.js +1 -1
- package/lib/channels/microsoft-copilot-channel-add.js +138 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +180 -0
- package/lib/channels/microsoft-copilot-entra-sso.js +264 -0
- package/lib/channels/microsoft-copilot-icons.js +74 -0
- package/lib/channels/microsoft-copilot-limits.js +84 -0
- package/lib/channels/microsoft-copilot-package.js +130 -49
- package/lib/channels/microsoft-copilot-validate.js +197 -0
- package/lib/cli/index.js +2 -0
- package/lib/cli/infra-guided-footers.js +1 -1
- package/lib/cli/infra-guided-public-url-warn.js +55 -0
- package/lib/cli/infra-guided.js +78 -62
- package/lib/cli/setup-app.help.js +4 -0
- package/lib/cli/setup-app.test-commands.js +59 -28
- package/lib/cli/setup-external-system.js +50 -12
- package/lib/cli/setup-infra.js +31 -4
- package/lib/commands/channel-add-setup.js +35 -10
- package/lib/commands/channel.js +27 -12
- package/lib/commands/deploy-gate-orchestrator.js +3 -2
- package/lib/commands/governance-verify-external.js +2 -5
- package/lib/commands/integration-definition.js +158 -0
- package/lib/commands/lifecycle-external.js +14 -7
- package/lib/commands/repair-auth-apply.js +19 -5
- package/lib/commands/repair-datasource-sync-operations.js +4 -1
- package/lib/commands/role-assistant-test-output.js +200 -0
- package/lib/commands/role-assistant.js +131 -114
- package/lib/commands/test-governance-external.js +2 -5
- package/lib/commands/up-miso.js +61 -24
- package/lib/commands/upload-data-sync-finalize.js +20 -3
- package/lib/commands/verify-governance-external.js +2 -5
- package/lib/commands/verify-operations-external.js +2 -5
- package/lib/commands/verify-operations-step-plan.js +31 -0
- package/lib/commands/verify-trust-command-action.js +2 -5
- package/lib/datasource/capability/capability-resolve.js +15 -5
- package/lib/datasource/capability/copy-operations.js +14 -4
- package/lib/datasource/datasource-identifier.js +4 -3
- package/lib/datasource/integration-context.js +3 -3
- package/lib/datasource/resolve-app.js +90 -8
- package/lib/datasource/test-e2e.js +2 -2
- package/lib/datasource/unified-validation-run-body.js +15 -1
- package/lib/datasource/unified-validation-run-resolve.js +2 -2
- package/lib/external-system/deploy-helpers.js +9 -5
- package/lib/external-system/deploy.js +2 -1
- package/lib/external-system/test-system-level.js +21 -3
- package/lib/external-system/test.js +4 -4
- package/lib/generator/builders.js +9 -15
- package/lib/infrastructure/index.js +19 -4
- package/lib/integration-definition/apply.js +478 -0
- package/lib/integration-definition/canonical-json.js +51 -0
- package/lib/integration-definition/emit-suite-bid.js +94 -0
- package/lib/integration-definition/enrich-crm-field-mappings.js +240 -0
- package/lib/integration-definition/enrich-openapi-operations.js +434 -0
- package/lib/integration-definition/from-discovery.js +339 -0
- package/lib/integration-definition/hash.js +37 -0
- package/lib/integration-definition/index.js +37 -0
- package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +205 -0
- package/lib/integration-definition/resource-type-catalog.js +59 -0
- package/lib/integration-definition/system-kind-enum.js +40 -0
- package/lib/integration-definition/validate.js +148 -0
- package/lib/programmatic/builder-api-request.js +5 -1
- package/lib/programmatic/builder-help-governance.js +3 -2
- package/lib/programmatic/capability-registry.js +19 -0
- package/lib/programmatic/openapi-component-schemas.js +6 -1
- package/lib/programmatic/openapi-descriptions.js +40 -0
- package/lib/programmatic/openapi-envelope-examples.js +269 -0
- package/lib/programmatic/openapi-operation-bindings.js +45 -0
- package/lib/programmatic/openapi-request-schemas.js +14 -0
- package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
- package/lib/programmatic/openapi-result-schemas.js +46 -99
- package/lib/programmatic/openapi-schema-descriptions-core.js +7 -4
- package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-operations.js +24 -0
- package/lib/programmatic/openapi-schema-helpers.js +9 -9
- package/lib/programmatic/openapi-spec.js +11 -1
- package/lib/programmatic/orchestration-openapi-meta.js +10 -0
- package/lib/programmatic/route-handler-map.js +29 -1
- package/lib/programmatic/run-channel-package.js +236 -0
- package/lib/programmatic/run-integration-definition.js +69 -0
- package/lib/role-assistant/knowledge-markdown-frontmatter.js +75 -0
- package/lib/role-assistant/knowledge-sync-logging.js +58 -0
- package/lib/role-assistant/knowledge-sync.js +104 -89
- package/lib/role-assistant/test-cases-bid.js +155 -0
- package/lib/role-assistant/test-cases-evaluate.js +9 -1
- package/lib/role-assistant/test-cases-honesty.js +24 -10
- package/lib/role-assistant/test-cases.js +28 -0
- package/lib/role-assistant/test-runner-bid-apply.js +122 -0
- package/lib/role-assistant/test-runner-bid-document.js +278 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +289 -46
- package/lib/role-assistant/test-runner-workhub.js +121 -25
- package/lib/role-assistant/test-suite.js +119 -0
- package/lib/schema/application-schema.json +64 -32
- package/lib/schema/external-datasource.schema.json +103 -17
- package/lib/schema/external-system.schema.json +54 -3
- package/lib/schema/infra.parameter.yaml +0 -20
- package/lib/schema/integration-definition.schema.json +195 -0
- package/lib/utils/authentication-shape.js +6 -0
- package/lib/utils/certify-external-workspace.js +40 -0
- package/lib/utils/docker-build.js +3 -3
- package/lib/utils/docker-run-ephemeral.js +77 -17
- package/lib/utils/health-check-public-warn.js +31 -13
- package/lib/utils/health-check.js +11 -1
- package/lib/utils/help-builder.js +1 -0
- package/lib/utils/paths.js +13 -15
- package/lib/utils/promote-dev-docker-image.js +97 -18
- package/lib/utils/role-assistant-paths.js +76 -14
- package/lib/utils/transient-developer-id.js +28 -0
- package/lib/utils/upload-sync-options.js +7 -4
- package/lib/validation/reserved-system-key-prefixes.js +56 -0
- package/lib/validation/validate.js +54 -19
- package/package.json +1 -1
- package/scripts/pnpm/af.mjs +24 -9
- package/scripts/pnpm/help.mjs +1 -1
- package/templates/applications/builder-api/application.yaml +3 -3
- package/templates/applications/dataplane/application.yaml +5 -5
- package/templates/applications/dataplane/env.template +8 -7
- package/templates/applications/dataplane/rbac.yaml +10 -10
- package/templates/applications/keycloak/application.yaml +2 -2
- package/templates/applications/keycloak/env.template +5 -2
- package/templates/applications/miso-controller/application.yaml +25 -11
- package/templates/applications/miso-controller/env.template +24 -5
- package/templates/channels/README.md +11 -1
- package/templates/channels/brand/color-192.png +0 -0
- package/templates/channels/brand/dark/128.png +0 -0
- package/templates/channels/brand/dark/192.png +0 -0
- package/templates/channels/brand/dark/256.png +0 -0
- package/templates/channels/brand/dark/32.png +0 -0
- package/templates/channels/brand/dark/512.png +0 -0
- package/templates/channels/brand/dark/64.png +0 -0
- package/templates/channels/brand/light/128.png +0 -0
- package/templates/channels/brand/light/192.png +0 -0
- package/templates/channels/brand/light/256.png +0 -0
- package/templates/channels/brand/light/32.png +0 -0
- package/templates/channels/brand/light/512.png +0 -0
- package/templates/channels/brand/light/64.png +0 -0
- package/templates/channels/brand/mono-white/128.png +0 -0
- package/templates/channels/brand/mono-white/192.png +0 -0
- package/templates/channels/brand/mono-white/256.png +0 -0
- package/templates/channels/brand/mono-white/32.png +0 -0
- package/templates/channels/brand/mono-white/512.png +0 -0
- package/templates/channels/brand/mono-white/64.png +0 -0
- package/templates/channels/brand/outline-32.png +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +76 -36
- package/templates/channels/chatgpt/integration/README.md +4 -4
- package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
- package/templates/channels/chatgpt/manifest.template.json.hbs +3 -3
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +10 -16
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +27 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +39 -20
- package/templates/channels/microsoft-copilot/integration/README.md +2 -3
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +1 -22
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +7 -7
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +11 -0
- package/templates/channels/slack/install.template.md.hbs +6 -1
- package/templates/channels/slack/integration/README.md +2 -4
- package/templates/channels/teams-bot/install.template.md.hbs +4 -0
- package/templates/channels/teams-bot/integration/README.md +3 -5
- package/templates/channels/web-embed/integration/web-embed-system.json +1 -16
- package/templates/python/docker-compose.hbs +10 -0
- package/templates/typescript/docker-compose.hbs +10 -0
- /package/.cursor/plans/{Done → Archive}/157.1-security-quality-violations-by-type.csv +0 -0
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"key": "external-system-schema",
|
|
8
8
|
"name": "External System Configuration Schema",
|
|
9
9
|
"description": "JSON schema for validating ExternalSystem configuration files",
|
|
10
|
-
"version": "1.
|
|
10
|
+
"version": "1.14.0",
|
|
11
11
|
"type": "schema",
|
|
12
12
|
"category": "integration",
|
|
13
13
|
"author": "AI Fabrix Team",
|
|
14
14
|
"createdAt": "2024-01-01T00:00:00Z",
|
|
15
|
-
"updatedAt": "2026-
|
|
15
|
+
"updatedAt": "2026-08-07T00:00:00Z",
|
|
16
16
|
"compatibility": {
|
|
17
17
|
"minVersion": "1.4.0",
|
|
18
18
|
"maxVersion": "2.0.0",
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": [],
|
|
29
29
|
"changelog": [
|
|
30
|
+
{
|
|
31
|
+
"version": "1.14.0",
|
|
32
|
+
"date": "2026-08-07T00:00:00Z",
|
|
33
|
+
"changes": [
|
|
34
|
+
"Added authentication.authType system for platform-managed downstream auth (no credential/apiProvider; ownership only — not autonomous system actor)."
|
|
35
|
+
],
|
|
36
|
+
"breaking": false
|
|
37
|
+
},
|
|
30
38
|
{
|
|
31
39
|
"version": "1.13.1",
|
|
32
40
|
"date": "2026-07-22T00:00:00Z",
|
|
@@ -806,6 +814,7 @@
|
|
|
806
814
|
"enum": [
|
|
807
815
|
"credential",
|
|
808
816
|
"apiProvider",
|
|
817
|
+
"system",
|
|
809
818
|
"none"
|
|
810
819
|
]
|
|
811
820
|
},
|
|
@@ -845,6 +854,36 @@
|
|
|
845
854
|
"apiProvider"
|
|
846
855
|
]
|
|
847
856
|
}
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
"if": {
|
|
860
|
+
"properties": {
|
|
861
|
+
"authType": {
|
|
862
|
+
"const": "system"
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
},
|
|
866
|
+
"then": {
|
|
867
|
+
"properties": {
|
|
868
|
+
"credential": false,
|
|
869
|
+
"apiProvider": false
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
"if": {
|
|
875
|
+
"properties": {
|
|
876
|
+
"authType": {
|
|
877
|
+
"const": "none"
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
},
|
|
881
|
+
"then": {
|
|
882
|
+
"properties": {
|
|
883
|
+
"credential": false,
|
|
884
|
+
"apiProvider": false
|
|
885
|
+
}
|
|
886
|
+
}
|
|
848
887
|
}
|
|
849
888
|
]
|
|
850
889
|
}
|
|
@@ -1039,7 +1078,7 @@
|
|
|
1039
1078
|
"default": false
|
|
1040
1079
|
},
|
|
1041
1080
|
"authentication": {
|
|
1042
|
-
"description": "Nested authentication: authType credential (local template), apiProvider (Miso delegated), or none. Deprecated — prefer authentications[] with usage.",
|
|
1081
|
+
"description": "Nested authentication: authType credential (local template), apiProvider (Miso delegated), system (platform-managed downstream auth ownership), or none (downstream anonymous). Deprecated — prefer authentications[] with usage.",
|
|
1043
1082
|
"oneOf": [
|
|
1044
1083
|
{
|
|
1045
1084
|
"type": "object",
|
|
@@ -1073,6 +1112,18 @@
|
|
|
1073
1112
|
},
|
|
1074
1113
|
"additionalProperties": false
|
|
1075
1114
|
},
|
|
1115
|
+
{
|
|
1116
|
+
"type": "object",
|
|
1117
|
+
"required": [
|
|
1118
|
+
"authType"
|
|
1119
|
+
],
|
|
1120
|
+
"properties": {
|
|
1121
|
+
"authType": {
|
|
1122
|
+
"const": "system"
|
|
1123
|
+
}
|
|
1124
|
+
},
|
|
1125
|
+
"additionalProperties": false
|
|
1126
|
+
},
|
|
1076
1127
|
{
|
|
1077
1128
|
"type": "object",
|
|
1078
1129
|
"required": [
|
|
@@ -340,26 +340,6 @@ parameters:
|
|
|
340
340
|
vaultSecretName: dataplane-client-secretKeyVault
|
|
341
341
|
notes: Per-app OAuth client secret for dataplane; generated on first ensure.
|
|
342
342
|
|
|
343
|
-
- key: mori-controller-client-idKeyVault
|
|
344
|
-
scope: app
|
|
345
|
-
generator:
|
|
346
|
-
type: literal
|
|
347
|
-
value: 'miso-controller-dev-mori-controller'
|
|
348
|
-
ensureOn: [upInfra, resolveApp]
|
|
349
|
-
azure:
|
|
350
|
-
notes: >-
|
|
351
|
-
Per-app OAuth client id from controller registration; literal default matches
|
|
352
|
-
{controllerId}-{environmentKey}-{applicationKey} (override per environment).
|
|
353
|
-
|
|
354
|
-
- key: mori-controller-client-secretKeyVault
|
|
355
|
-
scope: app
|
|
356
|
-
generator:
|
|
357
|
-
type: randomBytes32
|
|
358
|
-
ensureOn: [upInfra, resolveApp]
|
|
359
|
-
azure:
|
|
360
|
-
vaultSecretName: mori-controller-client-secretKeyVault
|
|
361
|
-
notes: Per-app OAuth client secret for mori-controller; generated on first ensure.
|
|
362
|
-
|
|
363
343
|
# Mori / telemetry: optional locally (LICENSE_JWT via miso-controller-jwt-licenseKeyVault=DEVELOPMENT skips Mori).
|
|
364
344
|
# MORI_AUTH_METHOD=kv://mori-controller-auth-methodKeyVault — local default apiKey.
|
|
365
345
|
- key: mori-controller-auth-methodKeyVault
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "aifabrix://schema/integration-definition.schema.json",
|
|
4
|
+
"title": "AI Fabrix Builder Integration Definition (BID)",
|
|
5
|
+
"description": "Canonical BT → Builder integration definition. Schema name aifabrix.builder.integrationDefinition v1.0.0.",
|
|
6
|
+
"metadata": {
|
|
7
|
+
"key": "integration-definition-schema",
|
|
8
|
+
"name": "Builder Integration Definition",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"schemaName": "aifabrix.builder.integrationDefinition",
|
|
11
|
+
"type": "schema",
|
|
12
|
+
"category": "integration",
|
|
13
|
+
"author": "AI Fabrix Team",
|
|
14
|
+
"createdAt": "2026-08-04T00:00:00Z",
|
|
15
|
+
"updatedAt": "2026-08-04T00:00:00Z"
|
|
16
|
+
},
|
|
17
|
+
"type": "object",
|
|
18
|
+
"additionalProperties": false,
|
|
19
|
+
"required": [
|
|
20
|
+
"schemaName",
|
|
21
|
+
"schemaVersion",
|
|
22
|
+
"definitionId",
|
|
23
|
+
"definitionHash",
|
|
24
|
+
"meta",
|
|
25
|
+
"packageIdentity",
|
|
26
|
+
"system",
|
|
27
|
+
"datasources",
|
|
28
|
+
"relationships",
|
|
29
|
+
"sync",
|
|
30
|
+
"capabilities",
|
|
31
|
+
"authority",
|
|
32
|
+
"acceptance"
|
|
33
|
+
],
|
|
34
|
+
"properties": {
|
|
35
|
+
"schemaName": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"const": "aifabrix.builder.integrationDefinition"
|
|
38
|
+
},
|
|
39
|
+
"schemaVersion": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
42
|
+
"description": "BID schema semver; implementers must accept 1.0.0."
|
|
43
|
+
},
|
|
44
|
+
"definitionId": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"format": "uuid"
|
|
47
|
+
},
|
|
48
|
+
"definitionHash": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"pattern": "^sha256:[a-f0-9]{64}$",
|
|
51
|
+
"description": "SHA-256 of canonicalized BID body excluding this field."
|
|
52
|
+
},
|
|
53
|
+
"meta": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"required": ["suiteRunId", "producedAt", "btAssistantKey"],
|
|
57
|
+
"properties": {
|
|
58
|
+
"suiteRunId": { "type": "string", "minLength": 1 },
|
|
59
|
+
"producedAt": { "type": "string", "format": "date-time" },
|
|
60
|
+
"btAssistantKey": { "type": "string", "minLength": 1 },
|
|
61
|
+
"answerFingerprint": { "type": "string" },
|
|
62
|
+
"knowledgePackRefs": {
|
|
63
|
+
"type": "array",
|
|
64
|
+
"items": { "type": "string", "minLength": 1 }
|
|
65
|
+
},
|
|
66
|
+
"humanAnswerRefs": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"items": { "type": "string", "minLength": 1 }
|
|
69
|
+
},
|
|
70
|
+
"replaceSystemKey": { "type": "boolean", "default": false }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"packageIdentity": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"additionalProperties": false,
|
|
76
|
+
"required": ["systemKey", "packageVersion", "displayName"],
|
|
77
|
+
"properties": {
|
|
78
|
+
"systemKey": { "type": "string", "pattern": "^[a-z0-9-]+$", "minLength": 3 },
|
|
79
|
+
"packageVersion": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" },
|
|
80
|
+
"displayName": { "type": "string", "minLength": 1 }
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"system": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"additionalProperties": true,
|
|
86
|
+
"required": ["key", "systemKind", "connectionRefs"],
|
|
87
|
+
"properties": {
|
|
88
|
+
"key": { "type": "string", "pattern": "^[a-z0-9-]+$" },
|
|
89
|
+
"displayName": { "type": "string" },
|
|
90
|
+
"description": { "type": "string" },
|
|
91
|
+
"systemKind": { "type": "string", "minLength": 1 },
|
|
92
|
+
"type": { "type": "string", "enum": ["openapi", "mcp", "custom"] },
|
|
93
|
+
"connectionRefs": {
|
|
94
|
+
"type": "object",
|
|
95
|
+
"description": "kv:// or credential key refs only — no plaintext secrets.",
|
|
96
|
+
"additionalProperties": { "type": "string", "minLength": 1 }
|
|
97
|
+
},
|
|
98
|
+
"openapiSourceRef": { "type": "string" }
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"datasources": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"minItems": 1,
|
|
104
|
+
"items": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"additionalProperties": true,
|
|
107
|
+
"required": ["key", "displayName", "entityType", "resourceType"],
|
|
108
|
+
"properties": {
|
|
109
|
+
"key": { "type": "string", "pattern": "^[a-z0-9-]+$", "minLength": 3 },
|
|
110
|
+
"displayName": { "type": "string", "minLength": 1 },
|
|
111
|
+
"entityType": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"enum": [
|
|
114
|
+
"documentStorage",
|
|
115
|
+
"vectorStore",
|
|
116
|
+
"recordStorage",
|
|
117
|
+
"messageService",
|
|
118
|
+
"serviceContract",
|
|
119
|
+
"none"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"resourceType": { "type": "string", "pattern": "^[a-z0-9-]+$" },
|
|
123
|
+
"capabilityKeys": {
|
|
124
|
+
"type": "array",
|
|
125
|
+
"items": { "type": "string", "pattern": "^[a-z][a-zA-Z0-9]*$" }
|
|
126
|
+
},
|
|
127
|
+
"propertyKeys": {
|
|
128
|
+
"type": "array",
|
|
129
|
+
"description": "Vendor property names to sync/index (CRM objects → CIP query.properties + fieldMappings).",
|
|
130
|
+
"items": { "type": "string", "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$", "minLength": 1 }
|
|
131
|
+
},
|
|
132
|
+
"openapiSourceRef": { "type": "string" }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"relationships": {
|
|
137
|
+
"type": "array",
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "object",
|
|
140
|
+
"additionalProperties": true,
|
|
141
|
+
"required": ["from", "to", "kind"],
|
|
142
|
+
"properties": {
|
|
143
|
+
"from": { "type": "string", "minLength": 1 },
|
|
144
|
+
"to": { "type": "string", "minLength": 1 },
|
|
145
|
+
"kind": { "type": "string", "minLength": 1 }
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"sync": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"additionalProperties": true,
|
|
152
|
+
"required": ["mode"],
|
|
153
|
+
"properties": {
|
|
154
|
+
"mode": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"enum": ["incremental"],
|
|
157
|
+
"description": "Incremental sync is mandatory for CRM profile datasources."
|
|
158
|
+
},
|
|
159
|
+
"datasources": {
|
|
160
|
+
"type": "array",
|
|
161
|
+
"items": { "type": "string", "pattern": "^[a-z0-9-]+$" }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"capabilities": {
|
|
166
|
+
"type": "object",
|
|
167
|
+
"additionalProperties": {
|
|
168
|
+
"type": "array",
|
|
169
|
+
"items": { "type": "string", "pattern": "^[a-z][a-zA-Z0-9]*$" }
|
|
170
|
+
},
|
|
171
|
+
"description": "Map of datasource key → capability keys (must include named write for company DS)."
|
|
172
|
+
},
|
|
173
|
+
"authority": {
|
|
174
|
+
"type": "object",
|
|
175
|
+
"additionalProperties": true,
|
|
176
|
+
"required": ["writeRequiresUserAuthority"],
|
|
177
|
+
"properties": {
|
|
178
|
+
"writeRequiresUserAuthority": { "type": "boolean" },
|
|
179
|
+
"notes": { "type": "string" }
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"acceptance": {
|
|
183
|
+
"type": "object",
|
|
184
|
+
"additionalProperties": true,
|
|
185
|
+
"required": ["gates"],
|
|
186
|
+
"properties": {
|
|
187
|
+
"gates": {
|
|
188
|
+
"type": "array",
|
|
189
|
+
"minItems": 1,
|
|
190
|
+
"items": { "type": "string", "minLength": 1 }
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -110,6 +110,9 @@ function buildAuthenticationFromMethod(systemKey, authType) {
|
|
|
110
110
|
if (method === 'none') {
|
|
111
111
|
return { authType: 'none' };
|
|
112
112
|
}
|
|
113
|
+
if (method === 'system') {
|
|
114
|
+
return { authType: 'system' };
|
|
115
|
+
}
|
|
113
116
|
const flat = buildFlatCredentialTemplate(systemKey, method);
|
|
114
117
|
return {
|
|
115
118
|
authType: 'credential',
|
|
@@ -174,6 +177,9 @@ function migrateAuthenticationToNestedSchema(authentication, systemKey) {
|
|
|
174
177
|
if (authentication.authType === 'none') {
|
|
175
178
|
return { authentication: { authType: 'none' }, changed: false };
|
|
176
179
|
}
|
|
180
|
+
if (authentication.authType === 'system') {
|
|
181
|
+
return { authentication: { authType: 'system' }, changed: false };
|
|
182
|
+
}
|
|
177
183
|
if (authentication.authType === 'apiProvider' && authentication.apiProvider) {
|
|
178
184
|
return { authentication, changed: false };
|
|
179
185
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Workspace roots allowed for external certify / verify CLI commands.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
const CERTIFY_EXTERNAL_BASE_DIRS = new Set([
|
|
8
|
+
'integration',
|
|
9
|
+
'role-assistant',
|
|
10
|
+
'enterprise-knowledge'
|
|
11
|
+
]);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @param {string|null|undefined} baseDir
|
|
15
|
+
* @returns {boolean}
|
|
16
|
+
*/
|
|
17
|
+
function isCertifyExternalWorkspace(baseDir) {
|
|
18
|
+
return CERTIFY_EXTERNAL_BASE_DIRS.has(baseDir);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {string|null|undefined} baseDir
|
|
23
|
+
* @param {string} commandLabel - e.g. verify-operations
|
|
24
|
+
* @returns {void}
|
|
25
|
+
* @throws {Error}
|
|
26
|
+
*/
|
|
27
|
+
function assertCertifyExternalWorkspace(baseDir, commandLabel) {
|
|
28
|
+
if (!isCertifyExternalWorkspace(baseDir)) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`${commandLabel} applies to external authoring folders only ` +
|
|
31
|
+
'(integration/<systemKey>/, role-assistant/<roleKey>/, or enterprise-knowledge/<key>/).'
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
CERTIFY_EXTERNAL_BASE_DIRS,
|
|
38
|
+
isCertifyExternalWorkspace,
|
|
39
|
+
assertCertifyExternalWorkspace
|
|
40
|
+
};
|
|
@@ -253,12 +253,12 @@ async function executeBuild(imageName, dockerfilePath, contextPath, tag, options
|
|
|
253
253
|
);
|
|
254
254
|
await executeDockerBuild(imageName, dockerfilePath, contextPath, tag, buildArgs, noCache);
|
|
255
255
|
|
|
256
|
-
//
|
|
257
|
-
if (options && options.tag && options.tag !== 'latest') {
|
|
256
|
+
// Also apply floating `main` when building a version tag (matches dev-promote dual tags).
|
|
257
|
+
if (options && options.tag && options.tag !== 'latest' && options.tag !== 'main') {
|
|
258
258
|
const { execFileWithDockerEnv } = require('./docker-exec');
|
|
259
259
|
const { getDockerExecEnv } = require('./remote-docker-env');
|
|
260
260
|
const env = await getDockerExecEnv();
|
|
261
|
-
await execFileWithDockerEnv('docker', ['tag', `${imageName}:${tag}`, `${imageName}:
|
|
261
|
+
await execFileWithDockerEnv('docker', ['tag', `${imageName}:${tag}`, `${imageName}:main`], { env });
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
|
|
@@ -16,8 +16,12 @@ const { getDockerExecEnv } = require('./remote-docker-env');
|
|
|
16
16
|
* @param {string} fullImage - Image:tag
|
|
17
17
|
* @param {string} cmd - Shell command (passed to sh -c)
|
|
18
18
|
* @param {string|null} [envFilePath] - Path for docker run --env-file
|
|
19
|
-
* @param {{
|
|
20
|
-
*
|
|
19
|
+
* @param {{
|
|
20
|
+
* network?: string|null,
|
|
21
|
+
* volumeMounts?: Array<{ host: string, container: string }>,
|
|
22
|
+
* quiet?: boolean
|
|
23
|
+
* }} [options] - quiet=true pipes stdio (installer-friendly; dump on failure)
|
|
24
|
+
* @returns {Promise<number|{ code: number, output: string }>} Exit code, or code+output when quiet
|
|
21
25
|
*/
|
|
22
26
|
async function runDockerRunEphemeral(fullImage, cmd, envFilePath = null, options = {}) {
|
|
23
27
|
const dockerEnv = await getDockerExecEnv();
|
|
@@ -26,22 +30,48 @@ async function runDockerRunEphemeral(fullImage, cmd, envFilePath = null, options
|
|
|
26
30
|
? options.network.trim()
|
|
27
31
|
: null;
|
|
28
32
|
const volumeMounts = Array.isArray(options?.volumeMounts) ? options.volumeMounts : [];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
33
|
+
const quiet = options?.quiet === true;
|
|
34
|
+
const args = _buildDockerRunArgs(fullImage, cmd, envFilePath, network, volumeMounts);
|
|
35
|
+
if (quiet) {
|
|
36
|
+
return _spawnDockerQuiet(args, dockerEnv);
|
|
37
|
+
}
|
|
38
|
+
return _spawnDockerInherit(args, dockerEnv);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {string} fullImage
|
|
43
|
+
* @param {string} cmd
|
|
44
|
+
* @param {string|null} envFilePath
|
|
45
|
+
* @param {string|null} network
|
|
46
|
+
* @param {Array<{ host: string, container: string }>} volumeMounts
|
|
47
|
+
* @returns {string[]}
|
|
48
|
+
*/
|
|
49
|
+
function _buildDockerRunArgs(fullImage, cmd, envFilePath, network, volumeMounts) {
|
|
50
|
+
const args = ['run', '--rm'];
|
|
51
|
+
if (network) {
|
|
52
|
+
args.push('--network', network);
|
|
53
|
+
}
|
|
54
|
+
if (envFilePath) {
|
|
55
|
+
args.push('--env-file', envFilePath);
|
|
56
|
+
}
|
|
57
|
+
for (const mount of volumeMounts) {
|
|
58
|
+
const host = typeof mount?.host === 'string' ? mount.host.trim() : '';
|
|
59
|
+
const container = typeof mount?.container === 'string' ? mount.container.trim() : '';
|
|
60
|
+
if (host && container) {
|
|
61
|
+
args.push('-v', `${host}:${container}`);
|
|
43
62
|
}
|
|
44
|
-
|
|
63
|
+
}
|
|
64
|
+
args.push(fullImage, 'sh', '-c', cmd);
|
|
65
|
+
return args;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* @param {string[]} args
|
|
70
|
+
* @param {NodeJS.ProcessEnv} dockerEnv
|
|
71
|
+
* @returns {Promise<number>}
|
|
72
|
+
*/
|
|
73
|
+
function _spawnDockerInherit(args, dockerEnv) {
|
|
74
|
+
return new Promise((resolve) => {
|
|
45
75
|
const proc = spawn('docker', args, {
|
|
46
76
|
stdio: 'inherit',
|
|
47
77
|
shell: false,
|
|
@@ -52,4 +82,34 @@ async function runDockerRunEphemeral(fullImage, cmd, envFilePath = null, options
|
|
|
52
82
|
});
|
|
53
83
|
}
|
|
54
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @param {string[]} args
|
|
87
|
+
* @param {NodeJS.ProcessEnv} dockerEnv
|
|
88
|
+
* @returns {Promise<{ code: number, output: string }>}
|
|
89
|
+
*/
|
|
90
|
+
function _spawnDockerQuiet(args, dockerEnv) {
|
|
91
|
+
return new Promise((resolve) => {
|
|
92
|
+
const proc = spawn('docker', args, {
|
|
93
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
94
|
+
shell: false,
|
|
95
|
+
env: dockerEnv
|
|
96
|
+
});
|
|
97
|
+
const chunks = [];
|
|
98
|
+
const push = (buf) => {
|
|
99
|
+
if (buf && buf.length) {
|
|
100
|
+
chunks.push(buf);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
proc.stdout.on('data', push);
|
|
104
|
+
proc.stderr.on('data', push);
|
|
105
|
+
proc.on('close', (code) => {
|
|
106
|
+
resolve({
|
|
107
|
+
code: code !== null ? code : 1,
|
|
108
|
+
output: Buffer.concat(chunks).toString('utf8')
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
proc.on('error', () => resolve({ code: 1, output: '' }));
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
55
115
|
module.exports = { runDockerRunEphemeral };
|
|
@@ -38,32 +38,50 @@ async function filterTraefikUrlByDns(traefikUrl, debug, isHostnameResolvableFn)
|
|
|
38
38
|
* @param {string} [p.skippedPublicHealthUrl]
|
|
39
39
|
* @param {string[]} [p.urlsToTry]
|
|
40
40
|
* @param {number} p.resolvedIndex
|
|
41
|
+
* @returns {string|null} Warning message without leading glyph, or null
|
|
41
42
|
*/
|
|
42
|
-
function
|
|
43
|
+
function buildPublicHealthUrlWarningMessage(p) {
|
|
43
44
|
const { skippedPublicHealthUrl, urlsToTry, resolvedIndex } = p;
|
|
44
|
-
if (typeof resolvedIndex !== 'number' || resolvedIndex < 0) return;
|
|
45
|
+
if (typeof resolvedIndex !== 'number' || resolvedIndex < 0) return null;
|
|
45
46
|
|
|
46
47
|
if (skippedPublicHealthUrl) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
'The application reported healthy via localhost only. Validate DNS names and Traefik routing for this host.'
|
|
51
|
-
)
|
|
48
|
+
return (
|
|
49
|
+
`Public URL was not verified (DNS): ${skippedPublicHealthUrl}. ` +
|
|
50
|
+
'The application reported healthy via localhost only. Validate DNS names and Traefik routing for this host.'
|
|
52
51
|
);
|
|
53
|
-
return;
|
|
54
52
|
}
|
|
55
53
|
if (Array.isArray(urlsToTry) && urlsToTry.length > 1 && resolvedIndex > 0) {
|
|
56
54
|
const pub = urlsToTry[0];
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'Health checks succeeded via localhost only. Validate Traefik routing, TLS, and DNS.'
|
|
61
|
-
)
|
|
55
|
+
return (
|
|
56
|
+
`Public URL was not verified: ${pub}. ` +
|
|
57
|
+
'Health checks succeeded via localhost only. Validate Traefik routing, TLS, and DNS.'
|
|
62
58
|
);
|
|
63
59
|
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @param {Object} p
|
|
65
|
+
* @param {string} [p.skippedPublicHealthUrl]
|
|
66
|
+
* @param {string[]} [p.urlsToTry]
|
|
67
|
+
* @param {number} p.resolvedIndex
|
|
68
|
+
* @param {boolean} [p.defer]
|
|
69
|
+
* @param {(message: string) => void} [p.onDeferred]
|
|
70
|
+
*/
|
|
71
|
+
function logPublicHealthUrlWarningIfNeeded(p) {
|
|
72
|
+
const message = buildPublicHealthUrlWarningMessage(p);
|
|
73
|
+
if (!message) return;
|
|
74
|
+
if (p && p.defer === true) {
|
|
75
|
+
if (typeof p.onDeferred === 'function') {
|
|
76
|
+
p.onDeferred(message);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
logger.log(chalk.yellow(`⚠ ${message}`));
|
|
64
81
|
}
|
|
65
82
|
|
|
66
83
|
module.exports = {
|
|
67
84
|
filterTraefikUrlByDns,
|
|
85
|
+
buildPublicHealthUrlWarningMessage,
|
|
68
86
|
logPublicHealthUrlWarningIfNeeded
|
|
69
87
|
};
|
|
@@ -339,6 +339,14 @@ function resolveHealthCheckPollOptions(runOptions = {}) {
|
|
|
339
339
|
if (typeof runOptions.onPollText === 'function') {
|
|
340
340
|
pollOptions.onPollText = runOptions.onPollText;
|
|
341
341
|
}
|
|
342
|
+
const defer =
|
|
343
|
+
runOptions.deferPublicUrlWarning === true || typeof runOptions.onPollText === 'function';
|
|
344
|
+
if (defer) {
|
|
345
|
+
pollOptions.deferPublicUrlWarning = true;
|
|
346
|
+
if (typeof runOptions.onDeferredPublicUrlWarning === 'function') {
|
|
347
|
+
pollOptions.onDeferredPublicUrlWarning = runOptions.onDeferredPublicUrlWarning;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
342
350
|
return pollOptions;
|
|
343
351
|
}
|
|
344
352
|
|
|
@@ -367,7 +375,9 @@ async function pollUntilHealthCheckPasses({
|
|
|
367
375
|
logPublicHealthUrlWarningIfNeeded({
|
|
368
376
|
skippedPublicHealthUrl,
|
|
369
377
|
urlsToTry,
|
|
370
|
-
resolvedIndex: attemptResult.resolvedIndex
|
|
378
|
+
resolvedIndex: attemptResult.resolvedIndex,
|
|
379
|
+
defer: pollOptions.deferPublicUrlWarning === true,
|
|
380
|
+
onDeferred: pollOptions.onDeferredPublicUrlWarning
|
|
371
381
|
});
|
|
372
382
|
return;
|
|
373
383
|
}
|
|
@@ -111,6 +111,7 @@ const CATEGORIES = [
|
|
|
111
111
|
{ name: 'delete', term: 'delete <systemKey>' },
|
|
112
112
|
{ name: 'repair', term: 'repair <systemKey>' },
|
|
113
113
|
{ name: 'manifest', term: 'manifest get-section <systemKey> <sectionKey>' },
|
|
114
|
+
{ name: 'integration-definition', term: 'integration-definition apply <file>' },
|
|
114
115
|
{ name: 'channel', term: 'channel scaffold <channelTarget>' },
|
|
115
116
|
{ name: 'datasource' },
|
|
116
117
|
{ name: 'datasource load', term: 'datasource load <datasourceKey>' },
|
package/lib/utils/paths.js
CHANGED
|
@@ -1022,23 +1022,17 @@ async function getResolveAppPath(appName, options = {}) {
|
|
|
1022
1022
|
return { appPath: result.appPath, envOnly: false };
|
|
1023
1023
|
}
|
|
1024
1024
|
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
* @param {string} cwd - Resolved process.cwd()
|
|
1028
|
-
* @param {ReturnType<typeof nodeFs>} disk
|
|
1029
|
-
* @returns {string|null}
|
|
1030
|
-
*/
|
|
1031
|
-
function tryIntegrationAppKeyAtWalkStep(walkDir, cwd, disk) {
|
|
1032
|
-
const integrationDir = path.join(walkDir, 'integration');
|
|
1025
|
+
function tryAuthoringAppKeyAtWalkStep(walkDir, cwd, disk, folderName) {
|
|
1026
|
+
const authoringDir = path.join(walkDir, folderName);
|
|
1033
1027
|
try {
|
|
1034
|
-
if (!disk.existsSync(
|
|
1028
|
+
if (!disk.existsSync(authoringDir)) {
|
|
1035
1029
|
return null;
|
|
1036
1030
|
}
|
|
1037
|
-
const
|
|
1038
|
-
if (cwd !==
|
|
1031
|
+
const rootNorm = path.resolve(authoringDir);
|
|
1032
|
+
if (cwd !== rootNorm && !cwd.startsWith(rootNorm + path.sep)) {
|
|
1039
1033
|
return null;
|
|
1040
1034
|
}
|
|
1041
|
-
const rel = path.relative(
|
|
1035
|
+
const rel = path.relative(rootNorm, cwd);
|
|
1042
1036
|
if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) {
|
|
1043
1037
|
return null;
|
|
1044
1038
|
}
|
|
@@ -1049,16 +1043,20 @@ function tryIntegrationAppKeyAtWalkStep(walkDir, cwd, disk) {
|
|
|
1049
1043
|
}
|
|
1050
1044
|
|
|
1051
1045
|
/**
|
|
1052
|
-
* Resolve app folder name when cwd is under
|
|
1046
|
+
* Resolve app folder name when cwd is under integration/, role-assistant/, or
|
|
1047
|
+
* enterprise-knowledge/<systemKey>/.
|
|
1053
1048
|
* Walks up from cwd (does not use {@link getIntegrationBuilderBaseDir}) so detection still works
|
|
1054
|
-
* when the canonical base is config/home but the shell is inside a checkout's
|
|
1049
|
+
* when the canonical base is config/home but the shell is inside a checkout's tree.
|
|
1055
1050
|
*/
|
|
1056
1051
|
function resolveIntegrationAppKeyFromCwd() {
|
|
1057
1052
|
const cwd = path.resolve(process.cwd());
|
|
1058
1053
|
const disk = nodeFs();
|
|
1059
1054
|
let p = cwd;
|
|
1060
1055
|
for (let i = 0; i < 64; i += 1) {
|
|
1061
|
-
const key =
|
|
1056
|
+
const key =
|
|
1057
|
+
tryAuthoringAppKeyAtWalkStep(p, cwd, disk, 'integration') ||
|
|
1058
|
+
tryAuthoringAppKeyAtWalkStep(p, cwd, disk, 'role-assistant') ||
|
|
1059
|
+
tryAuthoringAppKeyAtWalkStep(p, cwd, disk, 'enterprise-knowledge');
|
|
1062
1060
|
if (key) {
|
|
1063
1061
|
return key;
|
|
1064
1062
|
}
|