@aifabrix/builder 2.52.1 → 2.53.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/lib/app/deploy-config.js +3 -2
- package/lib/channels/add-channel.js +11 -41
- package/lib/channels/approval-guides/index.js +3 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +26 -17
- package/lib/channels/channel-add-existing.js +72 -0
- package/lib/channels/channel-runtime-resolver.js +5 -1
- package/lib/channels/channel-status-display.js +30 -3
- package/lib/channels/microsoft-copilot-entra-sso-form.js +73 -2
- package/lib/channels/microsoft-copilot-entra-sso.js +26 -5
- package/lib/channels/microsoft-copilot-limits.js +22 -3
- package/lib/channels/microsoft-copilot-package.js +59 -14
- package/lib/channels/microsoft-copilot-validate.js +40 -10
- package/lib/cli/attach-default-help-examples.js +102 -0
- package/lib/cli/index.js +2 -0
- package/lib/cli/setup-credential-deployment.js +7 -5
- package/lib/cli/setup-utility-validate.js +1 -0
- package/lib/commands/credential-push.js +37 -5
- package/lib/commands/package-score.js +72 -0
- package/lib/commands/role-assistant.js +46 -8
- package/lib/deployment/deployer-poll-run.js +2 -2
- package/lib/deployment/deployer.js +1 -1
- package/lib/deployment/environment.js +2 -2
- package/lib/external-system/deploy.js +11 -21
- package/lib/integration-definition/apply.js +12 -14
- package/lib/integration-definition/enrich-openapi-operations.js +9 -10
- package/lib/lab/package-parity-score.js +417 -0
- package/lib/programmatic/capability-registry.js +1 -0
- package/lib/programmatic/help-content/channel-onboarding.md +35 -0
- package/lib/programmatic/help-content/cip-overview.md +27 -0
- package/lib/programmatic/help-content/connected-system-ui.md +70 -0
- package/lib/programmatic/help-content/dimensions-guide.md +23 -0
- package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
- package/lib/programmatic/help-content/overview.md +25 -0
- package/lib/programmatic/help-content/subscription-guide.md +27 -0
- package/lib/programmatic/help-content/workflow.md +50 -0
- package/lib/programmatic/openapi-component-schemas.js +1 -0
- package/lib/programmatic/openapi-descriptions.js +6 -0
- package/lib/programmatic/openapi-envelope-examples.js +11 -0
- package/lib/programmatic/openapi-operation-bindings.js +5 -0
- package/lib/programmatic/openapi-request-schemas.js +39 -13
- package/lib/programmatic/openapi-result-schemas.js +30 -0
- package/lib/programmatic/openapi-schema-descriptions-core.js +18 -0
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/persist-supplied-openapi.js +180 -0
- package/lib/programmatic/route-handler-map.js +6 -0
- package/lib/programmatic/run-integration-definition.js +13 -5
- package/lib/role-assistant/evidence-sync.js +55 -7
- package/lib/role-assistant/test-runner-attachments.js +118 -0
- package/lib/role-assistant/test-runner-bid-apply.js +100 -21
- package/lib/role-assistant/test-runner-bid-document.js +1 -1
- package/lib/role-assistant/test-runner-start-payload.js +96 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +11 -7
- package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
- package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
- package/lib/role-assistant/test-runner-workhub.js +68 -105
- package/lib/role-assistant/test-runner.js +5 -63
- package/lib/role-assistant/test-suite.js +33 -40
- package/lib/schema/external-datasource.schema.json +13 -4
- package/lib/utils/compose-generator.js +10 -1
- package/lib/utils/compose-traefik-extra-routes.js +107 -0
- package/lib/utils/docker-build.js +2 -2
- package/lib/utils/help-builder.js +2 -1
- package/lib/utils/promote-dev-docker-image.js +15 -10
- package/package.json +14 -16
- package/templates/README.md +12 -1
- package/templates/applications/dataplane/application.yaml +8 -1
- package/templates/applications/dataplane/env.template +1 -1
- package/templates/applications/miso-controller/application.yaml +2 -1
- package/templates/applications/miso-controller/rbac.yaml +1 -0
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +6 -2
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +8 -5
- package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +74 -22
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +29 -14
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +6 -2
- package/templates/python/docker-compose.hbs +36 -0
- package/templates/typescript/docker-compose.hbs +36 -0
- package/.cursor/plans/Archive/157.1-security-quality-violations-by-type.csv +0 -374
- package/.cursor/process/README.md +0 -9
- package/.cursor/rules/anchor-docs.mdc +0 -15
- package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
- package/.cursor/rules/cli-layout.mdc +0 -81
- package/.cursor/rules/cli-product-neutral.mdc +0 -43
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
- package/.cursor/rules/docs-rules.mdc +0 -32
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
- package/.cursor/rules/project-rules.mdc +0 -913
- package/.cursor/skills/README.md +0 -15
- package/.dockerignore +0 -52
- package/.eslintignore +0 -22
- package/.markdownlint.json +0 -14
- package/anchor-docs/README.md +0 -10
- package/anchor-docs/_TEMPLATE +0 -24
- package/babel.config.js +0 -6
- package/bin/builder-api-cleanup.js +0 -26
- package/bin/builder-api-nest.js +0 -10
- package/bin/builder-api-spike.js +0 -19
- package/enterprise-knowledge/README.md +0 -50
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
- package/integration/README.md +0 -81
- package/integration/github/README.md +0 -53
- package/integration/github/application.json +0 -21
- package/integration/github/deploy.js +0 -72
- package/integration/github/env.template +0 -11
- package/integration/github/github-datasource-issue-comments.json +0 -239
- package/integration/github/github-datasource-issues.json +0 -399
- package/integration/github/github-datasource-repository.json +0 -354
- package/integration/github/github-deploy.json +0 -1202
- package/integration/github/github-system.json +0 -82
- package/integration/hubspot-test/README.md +0 -159
- package/integration/hubspot-test/application.json +0 -54
- package/integration/hubspot-test/companies.json +0 -2048
- package/integration/hubspot-test/create-hubspot.js +0 -523
- package/integration/hubspot-test/env.template +0 -4
- package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
- package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
- package/integration/hubspot-test/hubspot-test-system.json +0 -74
- package/integration/hubspot-test/rbac.json +0 -166
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
- package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
- package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
- package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
- package/integration/hubspot-test/test-dataplane-down.js +0 -209
- package/integration/hubspot-test/test.js +0 -1588
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
- package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
- package/integration/roundtrip-test-local/README.md +0 -143
- package/integration/roundtrip-test-local/application.yaml +0 -13
- package/integration/roundtrip-test-local/env.template +0 -15
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
- package/integration/roundtrip-test-local2/README.md +0 -143
- package/integration/roundtrip-test-local2/application.yaml +0 -13
- package/integration/roundtrip-test-local2/env.template +0 -15
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
- package/integration/test/wizard.yaml +0 -8
- package/jest.config.coverage.js +0 -37
- package/jest.config.default.js +0 -11
- package/jest.config.integration.fixtures.js +0 -22
- package/jest.config.integration.js +0 -33
- package/jest.config.isolated.js +0 -11
- package/jest.config.manual.js +0 -30
- package/jest.global-live-fabrix-hooks.js +0 -36
- package/jest.isolated-projects.js +0 -283
- package/jest.projects.js +0 -79
- package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +0 -205
- package/packages/builder-api/README.md +0 -120
- package/packages/builder-api/package.json +0 -30
- package/packages/builder-api/src/app.module.ts +0 -7
- package/packages/builder-api/src/auth/auth.module.ts +0 -5
- package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
- package/packages/builder-api/src/main.ts +0 -16
- package/packages/builder-api/tsconfig.json +0 -15
- package/scripts/check-builder-api-architecture-grep.js +0 -79
- package/scripts/check-datasource-test-run-schema-sync.js +0 -34
- package/scripts/ci-fix.sh +0 -19
- package/scripts/ci-simulate.sh +0 -19
- package/scripts/diagnose-cli.js +0 -150
- package/scripts/docker_image_content_gate.js +0 -47
- package/scripts/docker_image_content_gate.sh +0 -5
- package/scripts/export-builder-api-evidence.js +0 -262
- package/scripts/install-local.js +0 -490
- package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
- package/scripts/lib/builder-api-docker-staging-core.js +0 -183
- package/scripts/lib/docker-image-content-gate-core.js +0 -166
- package/scripts/lib/plan-actor.js +0 -109
- package/scripts/lib/plan-config.js +0 -20
- package/scripts/lib/plan-gates.js +0 -154
- package/scripts/lib/plan-meta.js +0 -104
- package/scripts/lib/plan-parse.js +0 -162
- package/scripts/lib/plan-prevalidate-gates.js +0 -337
- package/scripts/lib/plan-run-core.js +0 -125
- package/scripts/lib/plan-run-report.js +0 -119
- package/scripts/plan-approve.js +0 -24
- package/scripts/plan-archive.js +0 -49
- package/scripts/plan-run.js +0 -13
- package/scripts/plan-set-actor.js +0 -21
- package/scripts/plan-validate.js +0 -80
- package/scripts/pnpm/af.mjs +0 -125
- package/scripts/pnpm/check-quiet.mjs +0 -32
- package/scripts/pnpm/dev-install.mjs +0 -29
- package/scripts/pnpm/dev-reload.mjs +0 -18
- package/scripts/pnpm/help.mjs +0 -55
- package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
- package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
- package/scripts/pnpm/lib/spinner.mjs +0 -42
- package/scripts/pnpm-global-remove.js +0 -48
- package/scripts/stage_builder_api_for_docker.js +0 -65
- package/scripts/sync-builder-api-template.js +0 -44
- package/scripts/test-dataplane-bootstrap.js +0 -331
|
@@ -1,41 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Role Assistant suite discovery for multi-case CLI runs.
|
|
3
|
-
* @fileoverview Discover YAML cases under tests/
|
|
3
|
+
* @fileoverview Discover YAML cases under tests/ra-* / package tests/
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const fs = require('../internal/fs-real-sync');
|
|
10
|
-
const { bareRoleKey } = require('../utils/role-assistant-paths');
|
|
10
|
+
const { bareRoleKey, roleAssistantSystemKey } = require('../utils/role-assistant-paths');
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return nodeFs.readdirSync(p, { withFileTypes: true });
|
|
30
|
-
}
|
|
31
|
-
return fs.readdirSync(p).map((name) => ({
|
|
32
|
-
name,
|
|
33
|
-
isDirectory: () => fs.statSync(path.join(p, name)).isDirectory()
|
|
34
|
-
}));
|
|
12
|
+
/**
|
|
13
|
+
* Candidate case roots (first existing wins).
|
|
14
|
+
* 1. tests/<ra-key>/<role-key>/
|
|
15
|
+
* 2. tests/role-assistant/<ra-key>/ (legacy)
|
|
16
|
+
* 3. role-assistant/<ra-key>/tests/
|
|
17
|
+
* @param {string} roleKey
|
|
18
|
+
* @param {string} cwd
|
|
19
|
+
* @returns {string[]}
|
|
20
|
+
*/
|
|
21
|
+
function listCasesRootCandidates(roleKey, cwd) {
|
|
22
|
+
const bare = bareRoleKey(roleKey);
|
|
23
|
+
const raKey = roleAssistantSystemKey(bare);
|
|
24
|
+
return [
|
|
25
|
+
path.join(cwd, 'tests', raKey, bare),
|
|
26
|
+
path.join(cwd, 'tests', 'role-assistant', raKey),
|
|
27
|
+
path.join(cwd, 'role-assistant', raKey, 'tests')
|
|
28
|
+
];
|
|
35
29
|
}
|
|
36
30
|
|
|
37
31
|
/**
|
|
38
|
-
* Resolve cases root for a role
|
|
32
|
+
* Resolve cases root for a role.
|
|
39
33
|
* @param {string} roleKey
|
|
40
34
|
* @param {{ casesRoot?: string, cwd?: string }} [options]
|
|
41
35
|
* @returns {string}
|
|
@@ -45,16 +39,14 @@ function resolveCasesRoot(roleKey, options = {}) {
|
|
|
45
39
|
return path.resolve(String(options.casesRoot));
|
|
46
40
|
}
|
|
47
41
|
const cwd = options.cwd || process.cwd();
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const packageTests = path.join(cwd, 'role-assistant', `ra-${bare}`, 'tests');
|
|
54
|
-
if (exists(packageTests)) {
|
|
55
|
-
return packageTests;
|
|
42
|
+
const candidates = listCasesRootCandidates(roleKey, cwd);
|
|
43
|
+
for (const candidate of candidates) {
|
|
44
|
+
if (fs.existsSync(candidate)) {
|
|
45
|
+
return candidate;
|
|
46
|
+
}
|
|
56
47
|
}
|
|
57
|
-
|
|
48
|
+
// Prefer package path in errors — primary authoring location when repo-root tests/ is absent.
|
|
49
|
+
return candidates[candidates.length - 1];
|
|
58
50
|
}
|
|
59
51
|
|
|
60
52
|
/**
|
|
@@ -63,12 +55,12 @@ function resolveCasesRoot(roleKey, options = {}) {
|
|
|
63
55
|
* @returns {Array<{ suite: string, file: string, absPath: string, caseIdHint: string }>}
|
|
64
56
|
*/
|
|
65
57
|
function discoverSuiteCaseFiles(casesRoot, options = {}) {
|
|
66
|
-
if (!
|
|
58
|
+
if (!fs.existsSync(casesRoot)) {
|
|
67
59
|
return [];
|
|
68
60
|
}
|
|
69
61
|
const suiteFilter = options.suite ? String(options.suite).trim() : '';
|
|
70
62
|
const rows = [];
|
|
71
|
-
for (const ent of
|
|
63
|
+
for (const ent of fs.readdirSync(casesRoot, { withFileTypes: true })) {
|
|
72
64
|
if (!ent.isDirectory() || String(ent.name).startsWith('.')) {
|
|
73
65
|
continue;
|
|
74
66
|
}
|
|
@@ -76,9 +68,9 @@ function discoverSuiteCaseFiles(casesRoot, options = {}) {
|
|
|
76
68
|
continue;
|
|
77
69
|
}
|
|
78
70
|
const suitePath = path.join(casesRoot, ent.name);
|
|
79
|
-
for (const fileEnt of
|
|
80
|
-
const name = fileEnt.name
|
|
81
|
-
if (
|
|
71
|
+
for (const fileEnt of fs.readdirSync(suitePath, { withFileTypes: true })) {
|
|
72
|
+
const name = fileEnt.name;
|
|
73
|
+
if (!fileEnt.isFile() || !/\.(ya?ml)$/i.test(name)) {
|
|
82
74
|
continue;
|
|
83
75
|
}
|
|
84
76
|
const absPath = path.join(suitePath, name);
|
|
@@ -113,6 +105,7 @@ function filterDiscoveredCases(rows, caseSel) {
|
|
|
113
105
|
}
|
|
114
106
|
|
|
115
107
|
module.exports = {
|
|
108
|
+
listCasesRootCandidates,
|
|
116
109
|
resolveCasesRoot,
|
|
117
110
|
discoverSuiteCaseFiles,
|
|
118
111
|
filterDiscoveredCases
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"key":"external-datasource-schema",
|
|
8
8
|
"name":"External Data Source Configuration Schema",
|
|
9
9
|
"description":"JSON schema for validating ExternalDataSource configuration files",
|
|
10
|
-
"version":"2.9.
|
|
10
|
+
"version":"2.9.7",
|
|
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-08-
|
|
15
|
+
"updatedAt":"2026-08-21T00:00:00Z",
|
|
16
16
|
"compatibility":{
|
|
17
17
|
"minVersion":"1.0.0",
|
|
18
18
|
"maxVersion":"3.0.0",
|
|
@@ -31,6 +31,14 @@
|
|
|
31
31
|
"external-system.schema.json"
|
|
32
32
|
],
|
|
33
33
|
"changelog":[
|
|
34
|
+
{
|
|
35
|
+
"version":"2.9.7",
|
|
36
|
+
"date":"2026-08-21T00:00:00Z",
|
|
37
|
+
"changes":[
|
|
38
|
+
"Added record to CIP fetch.source for governed local record-storage operations."
|
|
39
|
+
],
|
|
40
|
+
"breaking":false
|
|
41
|
+
},
|
|
34
42
|
{
|
|
35
43
|
"version":"2.9.5",
|
|
36
44
|
"date":"2026-07-31T00:00:00Z",
|
|
@@ -2534,9 +2542,10 @@
|
|
|
2534
2542
|
"openapi",
|
|
2535
2543
|
"http",
|
|
2536
2544
|
"datasource",
|
|
2537
|
-
"viewpoint"
|
|
2545
|
+
"viewpoint",
|
|
2546
|
+
"record"
|
|
2538
2547
|
],
|
|
2539
|
-
"description":"If 'openapi', refer to openapi.operations.*. If 'http', use explicit method/path. If 'datasource', execute another datasource operation. If 'viewpoint', execute saved SQL in fetch.query against records storage (storageType view)."
|
|
2548
|
+
"description":"If 'openapi', refer to openapi.operations.*. If 'http', use explicit method/path. If 'datasource', execute another datasource operation. If 'viewpoint', execute saved SQL in fetch.query against records storage (storageType view). If 'record', read or persist governed rows in local record storage with no vendor HTTP; read versus persist follows the CIP operation shape."
|
|
2540
2549
|
},
|
|
2541
2550
|
"openapiRef":{
|
|
2542
2551
|
"type":"string",
|
|
@@ -31,6 +31,7 @@ const {
|
|
|
31
31
|
buildTraefikIngressBase,
|
|
32
32
|
computeTraefikStripPathPrefix
|
|
33
33
|
} = require('./compose-traefik-ingress-base');
|
|
34
|
+
const { buildTraefikExtraRouters } = require('./compose-traefik-extra-routes');
|
|
34
35
|
const { parseDeveloperIdNum } = require('./declarative-url-ports');
|
|
35
36
|
|
|
36
37
|
registerComposeHelpers();
|
|
@@ -250,13 +251,20 @@ function buildTraefikConfig(config, devId, scopeOpts = null, remoteServer = null
|
|
|
250
251
|
// Traefik must only attach routers to `web` for developer-id > 0; `websecure`+tls labels without
|
|
251
252
|
// matching certs break routing on Traefik 3.6+ for HTTP traffic (404 on PathPrefix).
|
|
252
253
|
const terminateTlsAtTraefik = base.tls === true && devNum === 0;
|
|
254
|
+
const stripPathPrefix = computeTraefikStripPathPrefix(base.path, resolvedHealth);
|
|
255
|
+
const extra = buildTraefikExtraRouters(config.frontDoorRouting, base.path);
|
|
253
256
|
return {
|
|
254
257
|
enabled: true,
|
|
255
258
|
host: base.host,
|
|
256
259
|
path: base.path,
|
|
257
260
|
tls: terminateTlsAtTraefik,
|
|
258
261
|
certStore: terminateTlsAtTraefik ? base.certStore || null : null,
|
|
259
|
-
stripPathPrefix
|
|
262
|
+
stripPathPrefix,
|
|
263
|
+
passThroughRouters: extra.passThroughRouters,
|
|
264
|
+
aliasRouters: extra.aliasRouters.map((r) => ({
|
|
265
|
+
...r,
|
|
266
|
+
stripPrimary: stripPathPrefix === true && base.path !== '/'
|
|
267
|
+
}))
|
|
260
268
|
};
|
|
261
269
|
}
|
|
262
270
|
|
|
@@ -424,6 +432,7 @@ module.exports = {
|
|
|
424
432
|
getImageName,
|
|
425
433
|
derivePathFromPattern,
|
|
426
434
|
buildTraefikConfig,
|
|
435
|
+
buildTraefikExtraRouters,
|
|
427
436
|
computeAlignedHealthCheckPath,
|
|
428
437
|
resolveHealthCheckPathWithFrontDoorVdir,
|
|
429
438
|
buildDevUsername,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extra Traefik routers from frontDoorRouting.requiresRuleSet + ruleSetConditions.
|
|
3
|
+
*
|
|
4
|
+
* @fileoverview Schema-legal pass-through routes (plan 171.0). No invented keys.
|
|
5
|
+
* @author AI Fabrix Team
|
|
6
|
+
* @version 1.1.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Normalize a route pattern to a PathPrefix value (no trailing slash / wildcards).
|
|
11
|
+
* @param {unknown} pattern
|
|
12
|
+
* @returns {string|null}
|
|
13
|
+
*/
|
|
14
|
+
function normalizeRoutePrefix(pattern) {
|
|
15
|
+
if (!pattern || typeof pattern !== 'string') {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const trimmed = pattern.trim();
|
|
19
|
+
if (!trimmed.startsWith('/')) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (trimmed === '/' || trimmed === '/*') {
|
|
23
|
+
return '/';
|
|
24
|
+
}
|
|
25
|
+
const withoutWildcards = trimmed.replace(/\/\*+$/g, '').replace(/\*+$/g, '');
|
|
26
|
+
const withoutTrailing = withoutWildcards.replace(/\/+$/g, '');
|
|
27
|
+
return withoutTrailing || '/';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Safe Traefik label id fragment from a path prefix.
|
|
32
|
+
* @param {string} prefix
|
|
33
|
+
* @param {number} index
|
|
34
|
+
* @returns {string}
|
|
35
|
+
*/
|
|
36
|
+
function routeIdFromPrefix(prefix, index) {
|
|
37
|
+
const slug = String(prefix || 'x')
|
|
38
|
+
.replace(/^\//, '')
|
|
39
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
40
|
+
.replace(/^-+|-+$/g, '')
|
|
41
|
+
.slice(0, 40);
|
|
42
|
+
return `${slug || 'route'}-${index}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Collect PathPrefix values from ruleSetConditions matchValues.
|
|
47
|
+
* @param {Object} frontDoor
|
|
48
|
+
* @returns {string[]}
|
|
49
|
+
*/
|
|
50
|
+
function matchValuesFromRuleSetConditions(frontDoor) {
|
|
51
|
+
if (frontDoor.requiresRuleSet !== true) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const conditions = Array.isArray(frontDoor.ruleSetConditions)
|
|
55
|
+
? frontDoor.ruleSetConditions
|
|
56
|
+
: [];
|
|
57
|
+
const prefixes = [];
|
|
58
|
+
conditions.forEach((condition) => {
|
|
59
|
+
if (!condition || typeof condition !== 'object') {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const values = Array.isArray(condition.matchValues) ? condition.matchValues : [];
|
|
63
|
+
values.forEach((raw) => {
|
|
64
|
+
const pathPrefix = normalizeRoutePrefix(raw);
|
|
65
|
+
if (pathPrefix && pathPrefix !== '/') {
|
|
66
|
+
prefixes.push(pathPrefix);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
return prefixes;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Build Traefik extra-route descriptors from frontDoorRouting (schema fields only).
|
|
75
|
+
* @param {Object|null|undefined} frontDoor
|
|
76
|
+
* @param {string} _primaryPath - Resolved primary PathPrefix (unused; reserved for callers)
|
|
77
|
+
* @returns {{ passThroughRouters: object[], aliasRouters: object[] }}
|
|
78
|
+
*/
|
|
79
|
+
function buildTraefikExtraRouters(frontDoor, _primaryPath) {
|
|
80
|
+
const passThroughRouters = [];
|
|
81
|
+
const aliasRouters = [];
|
|
82
|
+
if (!frontDoor || typeof frontDoor !== 'object') {
|
|
83
|
+
return { passThroughRouters, aliasRouters };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const prefixes = matchValuesFromRuleSetConditions(frontDoor);
|
|
87
|
+
const seen = new Set();
|
|
88
|
+
prefixes.forEach((pathPrefix, index) => {
|
|
89
|
+
if (seen.has(pathPrefix)) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
seen.add(pathPrefix);
|
|
93
|
+
passThroughRouters.push({
|
|
94
|
+
id: routeIdFromPrefix(pathPrefix, index),
|
|
95
|
+
pathPrefix
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return { passThroughRouters, aliasRouters };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
normalizeRoutePrefix,
|
|
104
|
+
routeIdFromPrefix,
|
|
105
|
+
matchValuesFromRuleSetConditions,
|
|
106
|
+
buildTraefikExtraRouters
|
|
107
|
+
};
|
|
@@ -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
|
-
// Also apply floating `
|
|
256
|
+
// Also apply floating `latest` when building a version tag (matches dev-promote dual tags).
|
|
257
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}:latest`], { env });
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
|
|
@@ -98,7 +98,8 @@ const CATEGORIES = [
|
|
|
98
98
|
{ name: 'validate', term: 'validate [appKey|systemKey|file]' },
|
|
99
99
|
{ name: 'validate-json', term: 'validate-json [appKey|systemKey]' },
|
|
100
100
|
{ name: 'parameters', term: 'parameters validate' },
|
|
101
|
-
{ name: 'diff', term: 'diff <file1> <file2>' }
|
|
101
|
+
{ name: 'diff', term: 'diff <file1> <file2>' },
|
|
102
|
+
{ name: 'package-score', term: 'package-score --reference <dir> --candidate <dir>' }
|
|
102
103
|
]
|
|
103
104
|
},
|
|
104
105
|
{
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Promote a developer-scoped local Docker image to the manifest base repository (tag only).
|
|
3
3
|
*
|
|
4
4
|
* @fileoverview Used by `aifabrix build --base --from-dev` and dev-promote workflows.
|
|
5
|
-
* Promote always applies two base tags: `
|
|
5
|
+
* Promote always applies two base tags: `latest` (floating) and the version tag (TAG / package version).
|
|
6
6
|
* @author AI Fabrix Team
|
|
7
|
-
* @version 1.
|
|
7
|
+
* @version 1.2.0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -16,8 +16,11 @@ const { execWithDockerEnv } = require('./docker-exec');
|
|
|
16
16
|
const logger = require('./logger');
|
|
17
17
|
const { formatSuccessLine } = require('./cli-test-layout-chalk');
|
|
18
18
|
|
|
19
|
-
/** Floating base tag applied on every promote alongside the version tag. */
|
|
20
|
-
const
|
|
19
|
+
/** Floating base tag applied on every promote alongside the version tag (matches setup manifests). */
|
|
20
|
+
const PROMOTE_FLOATING_TAG = 'latest';
|
|
21
|
+
|
|
22
|
+
/** @deprecated Use {@link PROMOTE_FLOATING_TAG}. Kept for callers that imported the old name. */
|
|
23
|
+
const PROMOTE_MAIN_TAG = PROMOTE_FLOATING_TAG;
|
|
21
24
|
|
|
22
25
|
/**
|
|
23
26
|
* @param {string} value
|
|
@@ -72,22 +75,23 @@ async function dockerTagImageRef(sourceRef, targetRef) {
|
|
|
72
75
|
*/
|
|
73
76
|
function resolvePromoteVersionTag(options = {}) {
|
|
74
77
|
const raw = String(options.tag || '').trim();
|
|
75
|
-
|
|
76
|
-
|
|
78
|
+
// `main` accepted as legacy alias for the floating tag.
|
|
79
|
+
if (!raw || raw === PROMOTE_FLOATING_TAG || raw === 'main') {
|
|
80
|
+
return PROMOTE_FLOATING_TAG;
|
|
77
81
|
}
|
|
78
82
|
return raw;
|
|
79
83
|
}
|
|
80
84
|
|
|
81
85
|
/**
|
|
82
|
-
* Base tags to apply on promote: version first, then `
|
|
86
|
+
* Base tags to apply on promote: version first, then `latest` when distinct.
|
|
83
87
|
* @param {Object} options
|
|
84
88
|
* @returns {string[]}
|
|
85
89
|
*/
|
|
86
90
|
function resolvePromoteBaseTags(options = {}) {
|
|
87
91
|
const versionTag = resolvePromoteVersionTag(options);
|
|
88
92
|
const tags = [versionTag];
|
|
89
|
-
if (versionTag !==
|
|
90
|
-
tags.push(
|
|
93
|
+
if (versionTag !== PROMOTE_FLOATING_TAG) {
|
|
94
|
+
tags.push(PROMOTE_FLOATING_TAG);
|
|
91
95
|
}
|
|
92
96
|
return tags;
|
|
93
97
|
}
|
|
@@ -182,7 +186,7 @@ async function allBaseTagsMatchDev(baseName, baseTags, devId) {
|
|
|
182
186
|
|
|
183
187
|
/**
|
|
184
188
|
* Tag developer-scoped image as manifest base when present locally.
|
|
185
|
-
* Always applies the version tag and `
|
|
189
|
+
* Always applies the version tag and `latest`.
|
|
186
190
|
* @param {string} appName
|
|
187
191
|
* @param {Object} options - build options (`base`, `tag`, `registry`, `fromDev`)
|
|
188
192
|
* @returns {Promise<string|null>} primary base image ref (version) when promoted; null when missing
|
|
@@ -236,6 +240,7 @@ function shouldAttemptDevPromote(options) {
|
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
module.exports = {
|
|
243
|
+
PROMOTE_FLOATING_TAG,
|
|
239
244
|
PROMOTE_MAIN_TAG,
|
|
240
245
|
tryPromoteDevImageToBase,
|
|
241
246
|
shouldAttemptDevPromote,
|
package/package.json
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aifabrix/builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.53.1",
|
|
4
4
|
"description": "AI Fabrix Builder — CLI and developer scripts (pnpm + af)",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"aifabrix": "bin/aifabrix.js",
|
|
8
8
|
"af": "bin/aifabrix.js"
|
|
9
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/aifabrix.js",
|
|
12
|
+
"lib/",
|
|
13
|
+
"templates/",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
10
17
|
"scripts": {
|
|
11
18
|
"help": "node scripts/pnpm/help.mjs",
|
|
12
19
|
"dev-install": "node scripts/pnpm/dev-install.mjs",
|
|
@@ -21,32 +28,23 @@
|
|
|
21
28
|
"lint:fix": "eslint . --ext .js --fix",
|
|
22
29
|
"test": "node tests/scripts/test-wrapper.js",
|
|
23
30
|
"build": "npm run lint && npm run test",
|
|
24
|
-
"build:ci": "npm run lint && npm run check:schema-sync && npm run check:flags && npm run test:ci",
|
|
31
|
+
"build:ci": "npm run lint && npm run check:schema-sync && npm run check:flags && npm run check:cli-help && npm run test:ci",
|
|
25
32
|
"test:ci": "bash tests/scripts/ci-simulate.sh",
|
|
26
|
-
"install:local": "node scripts/install-local.js && which aifabrix && which af",
|
|
27
|
-
"uninstall:local": "node scripts/install-local.js uninstall && which aifabrix && which af",
|
|
28
|
-
"sync-json": "node scripts/sync-builder-api-template.js",
|
|
29
|
-
"builder-api:build": "tsc -p packages/builder-api/tsconfig.json",
|
|
30
|
-
"builder-api:nest": "node bin/builder-api-nest.js",
|
|
31
|
-
"builder-api:cleanup": "node bin/builder-api-cleanup.js",
|
|
32
|
-
"check:builder-api-arch": "node scripts/check-builder-api-architecture-grep.js",
|
|
33
33
|
"check:schema-sync": "node scripts/check-datasource-test-run-schema-sync.js",
|
|
34
34
|
"check:flags": "jest tests/lib/schema/flag-map-validation-run.test.js --runInBand --config jest.config.default.js",
|
|
35
|
-
"
|
|
36
|
-
"test:154-docker-ip": "jest --runInBand tests/scripts/stage_builder_api_for_docker.test.js tests/scripts/docker_image_content_gate.test.js",
|
|
37
|
-
"stage-builder-api-docker": "node scripts/stage_builder_api_for_docker.js",
|
|
38
|
-
"docker-image-build-builder-api": "npm run stage-builder-api-docker && docker build -f builder/builder-api/Dockerfile -t builder-api:gate .",
|
|
39
|
-
"docker-image-gate-builder-api": "npm run docker-image-build-builder-api && node scripts/docker_image_content_gate.js builder-api:gate builder-api",
|
|
35
|
+
"check:cli-help": "node scripts/check-cli-help-examples.js",
|
|
40
36
|
"test:manual": "jest --config jest.config.manual.js --runInBand",
|
|
41
37
|
"test:integration": "jest --config jest.config.integration.js --runInBand",
|
|
42
38
|
"test:integration:fixtures": "jest --config jest.config.integration.fixtures.js --runInBand",
|
|
43
39
|
"test:hubspot-wizard": "node integration/hubspot-test/test.js",
|
|
44
40
|
"test:hubspot-dataplane-down": "node integration/hubspot-test/test-dataplane-down.js",
|
|
45
41
|
"test:coverage": "cross-env RUN_COVERAGE=1 node tests/scripts/test-wrapper.js",
|
|
46
|
-
"
|
|
47
|
-
"
|
|
42
|
+
"docker-image-gate-builder-api": "node scripts/stage_builder_api_for_docker.js && docker build -f builder/builder-api/Dockerfile -t builder-api:gate . && node scripts/docker_image_content_gate.js builder-api:gate builder-api",
|
|
43
|
+
"install:local": "node scripts/install-local.js && which aifabrix && which af",
|
|
44
|
+
"uninstall:local": "node scripts/install-local.js uninstall && which aifabrix && which af",
|
|
48
45
|
"install:global": "npm install -g . --force && which aifabrix && which af && aifabrix --version",
|
|
49
46
|
"uninstall:global": "npm uninstall -g @aifabrix/builder",
|
|
47
|
+
"sync-json": "node scripts/sync-builder-api-template.js",
|
|
50
48
|
"pack": "npm run build && npm pack",
|
|
51
49
|
"validate": "npm run build",
|
|
52
50
|
"prepublishOnly": "npm run validate"
|
package/templates/README.md
CHANGED
|
@@ -15,7 +15,18 @@ Application templates are folder-based and located under `templates/applications
|
|
|
15
15
|
- `templates/applications/keycloak/` - Keycloak application template
|
|
16
16
|
- `templates/applications/builder-api/` - Builder API platform webapp (published from `builder/builder-api/` via `npm run sync-json`)
|
|
17
17
|
|
|
18
|
-
**Platform
|
|
18
|
+
**Platform template sync (`pnpm run sync-json`):** Publishes local `builder/builder-api/` (`application.yaml`, `Dockerfile`, `env.template`) and, when sibling checkouts exist, pulls the same file sets as miso/dataplane sync-json:
|
|
19
|
+
|
|
20
|
+
| SSOT | → template |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| `aifabrix-builder/builder/builder-api/` | `templates/applications/builder-api/` |
|
|
23
|
+
| `aifabrix-miso/builder/miso-controller/` (`env.template`, `rbac.yaml`, `application.yaml`) | `templates/applications/miso-controller/` |
|
|
24
|
+
| `aifabrix-miso/builder/keycloak/` (`env.template`, `application.yaml`) | `templates/applications/keycloak/` |
|
|
25
|
+
| `aifabrix-dataplane/builder/dataplane/` (`env.template`, `rbac.yaml`, `application.yaml`) | `templates/applications/dataplane/` |
|
|
26
|
+
|
|
27
|
+
**Schema master (dataplane):** Also copies dataplane `app/schemas/json/` core integration schemas + `type/*` and `configs/deployment-rules.yaml` into `lib/schema/` (same contract as dataplane `make sync-json`). Do not hand-edit those mirrors — edit dataplane SSOT, then sync. Builder-owned schemas in `lib/schema/` (wizard, infra, etc.) are left alone.
|
|
28
|
+
|
|
29
|
+
Overrides: `AIFABRIX_MISO_SRC`, `AIFABRIX_DATAPLANE_SRC` / `AIFABRIX_DATAPLANE_ROOT` (repo roots). Install with `aifabrix up-platform` / `up-builder-api` — do not hand-edit the template copies as primary.
|
|
19
30
|
|
|
20
31
|
**Template Validation:**
|
|
21
32
|
- Template folder must exist in `templates/applications/<name>/`
|
|
@@ -5,7 +5,7 @@ app:
|
|
|
5
5
|
description: "AI Fabrix Dataplane is a secure, in-tenant integration and automation layer that supplies governed, normalized, and explainable enterprise data to AI agents. Using CIP as a declarative standard, it enforces RBAC and ABAC, executes integrations, and exposes trusted data via MCP and OpenAPI."
|
|
6
6
|
type: webapp
|
|
7
7
|
language: python # Explicitly specify Python language
|
|
8
|
-
version: 2.0.
|
|
8
|
+
version: 2.0.31
|
|
9
9
|
# Image Configuration
|
|
10
10
|
# Set tag to match your build (example: aifabrix build dataplane -t 1.0.0).
|
|
11
11
|
# Registry is required so the controller can pull the image (avoids docker-not-found on the controller host).
|
|
@@ -29,6 +29,13 @@ frontDoorRouting:
|
|
|
29
29
|
internalDockerUseOriginOnly: false
|
|
30
30
|
host: ${DEV_USERNAME}.${REMOTE_HOST}
|
|
31
31
|
tls: ${TLS_ENABLED}
|
|
32
|
+
# Origin RFC 9728 PRM (outside /data PathPrefix) — Builder Traefik pass-through (plan 171.0).
|
|
33
|
+
requiresRuleSet: true
|
|
34
|
+
ruleSetConditions:
|
|
35
|
+
- type: UrlPath
|
|
36
|
+
operator: BeginsWith
|
|
37
|
+
matchValues:
|
|
38
|
+
- /.well-known/oauth-protected-resource/data
|
|
32
39
|
|
|
33
40
|
# Azure Requirements
|
|
34
41
|
requires:
|
|
@@ -44,7 +44,7 @@ API_KEY_BYPASS_ROLES=full-access
|
|
|
44
44
|
|
|
45
45
|
# API Configuration
|
|
46
46
|
API_V1_STR=/api/v1
|
|
47
|
-
VERSION=2.0.
|
|
47
|
+
VERSION=2.0.31
|
|
48
48
|
# Minimum supported aifabrix-builder CLI semver (advertised on /health and /api/v1/health; empty = no gate)
|
|
49
49
|
# MIN_BUILDER_CLI_VERSION=2.45.0
|
|
50
50
|
MIN_BUILDER_CLI_VERSION=2.45.5
|
|
@@ -4,7 +4,8 @@ app:
|
|
|
4
4
|
displayName: 'Miso Controller'
|
|
5
5
|
description: 'Miso is the AI Fabrix in-tenant controller and portal layer for securely operating enterprise AI apps inside a customer’s Azure tenant. It provides Entra ID SSO, RBAC, audit logs, environment/app configuration via schemas, and safe secret handling via Key Vault references—ensuring governance, traceability, and predictable UX across portal, SDK, and CLI.'
|
|
6
6
|
type: webapp
|
|
7
|
-
version: '2.0.
|
|
7
|
+
version: '2.0.34'
|
|
8
|
+
|
|
8
9
|
# Image Configuration
|
|
9
10
|
# Set tag to match your build (e.g. aifabrix build miso-controller -t 1.0.0 then tag: 1.0.0)
|
|
10
11
|
# Registry is required so the controller can pull the image (avoids "docker: not found" on the controller host).
|
|
@@ -3,19 +3,23 @@
|
|
|
3
3
|
"schema_version": "v2.4",
|
|
4
4
|
"name_for_human": "{{pluginNameForHuman}}",
|
|
5
5
|
"description_for_human": "{{pluginDescriptionForHuman}}",
|
|
6
|
-
"description_for_model": "Governed enterprise work tools for Role Assistants. Prefer discovery tool names only; resolve Role Assistants dynamically for the signed-in user.",
|
|
6
|
+
"description_for_model": "Governed enterprise work tools for Role Assistants. Prefer discovery tool names only; resolve Role Assistants dynamically for the signed-in user. For listing available Role Assistants use work.roles; use assistant.describe only when an assistantKey is already known.",
|
|
7
7
|
"namespace": "{{pluginNamespace}}",
|
|
8
8
|
"privacy_policy_url": "{{{dataplaneBaseUrl}}}/privacy",
|
|
9
9
|
"legal_info_url": "{{{dataplaneBaseUrl}}}/terms",
|
|
10
|
+
"functions": [],
|
|
10
11
|
"runtimes": [
|
|
11
12
|
{
|
|
12
13
|
"type": "RemoteMCPServer",
|
|
13
14
|
"spec": {
|
|
14
15
|
"url": "{{{mcpUrl}}}"
|
|
15
16
|
},
|
|
17
|
+
"run_for_functions": [
|
|
18
|
+
"*"
|
|
19
|
+
],
|
|
16
20
|
"auth": {
|
|
17
21
|
"type": "OAuthPluginVault",
|
|
18
|
-
"reference_id": "{{oauthPluginVaultReferenceId}}"
|
|
22
|
+
"reference_id": "{{{oauthPluginVaultReferenceId}}}"
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
]
|
|
@@ -6,22 +6,25 @@ Direct URL:
|
|
|
6
6
|
|
|
7
7
|
Open **Tools → Microsoft Entra SSO client ID registration → Register client ID** (or New).
|
|
8
8
|
|
|
9
|
+
Do this **before** organisation publish. The registration / auth-config ID becomes `--oauth-plugin-vault-reference-id`. It is **not** the Entra Client (application) ID.
|
|
10
|
+
|
|
9
11
|
### Values to paste into the form
|
|
10
12
|
|
|
11
13
|
| Field | Value |
|
|
12
14
|
| --- | --- |
|
|
13
15
|
| Registration name | `{{appName}}` |
|
|
14
|
-
| Base URL | {{#if entraSsoBaseUrl}}`{{{entraSsoBaseUrl}}}`{{else}}*(missing —
|
|
15
|
-
| Restrict usage by organization | My organization only
|
|
16
|
-
| Restrict usage by Teams app |
|
|
16
|
+
| Base URL | {{#if entraSsoBaseUrl}}`{{{entraSsoBaseUrl}}}`{{else}}*(missing — Remote MCP URL not resolved)*{{/if}} |
|
|
17
|
+
| Restrict usage by organization | My organization only |
|
|
18
|
+
| Restrict usage by Teams app | Stable Teams app / manifest ID `{{packageAppId}}` (known before Import — bind to this ID at registration; do not use “Any Teams app”) |
|
|
17
19
|
| Client (application) ID | {{#if entraSsoClientId}}`{{entraSsoClientId}}`{{else}}*(missing — Entra SSO enterprise app (client) id from controller Keycloak status `entraIdentityProvider.enterpriseAppId`; complete Entra onboarding if empty)*{{/if}} |
|
|
18
20
|
| Scope | {{#if entraSsoScope}}`{{entraSsoScope}}`{{else}}*(missing — set Runtime MCP delegated scopes on Trust source `microsoft-entra-id` `allowedScopes`; not openid/profile alone)*{{/if}} |
|
|
19
21
|
|
|
20
22
|
### Related (for your records)
|
|
21
23
|
|
|
22
24
|
{{#if mcpUrl}}- **Remote MCP URL (package):** `{{{mcpUrl}}}`{{/if}}
|
|
25
|
+
{{#if packageAppId}}- **Teams app / manifest ID:** `{{packageAppId}}` (preserve on Import app — do not create a new unrelated app){{/if}}
|
|
23
26
|
{{#if entraIssuer}}- **Entra issuer (Trust source):** `{{{entraIssuer}}}`{{/if}}
|
|
24
27
|
{{#if entraTenantId}}- **Tenant id:** `{{entraTenantId}}`{{/if}}
|
|
25
|
-
{{#if entraEnterpriseAppId}}- **
|
|
28
|
+
{{#if entraEnterpriseAppId}}- **Entra Client (application) ID (Keycloak enterprise app):** `{{entraEnterpriseAppId}}`{{/if}}
|
|
26
29
|
|
|
27
|
-
After Save, copy the **Microsoft Entra SSO registration ID** (auth
|
|
30
|
+
After Save, copy the **Microsoft Entra SSO registration ID** (auth-config id). Pass that value as `--oauth-plugin-vault-reference-id` and re-run `channel add` so `ai-plugin.json` embeds `OAuthPluginVault.reference_id`.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.21/MicrosoftTeams.Localization.schema.json",
|
|
3
|
+
"name.short": "{{shortName}}",
|
|
4
|
+
"name.full": "{{fullName}}",
|
|
5
|
+
"description.short": "{{fiShortDescription}}",
|
|
6
|
+
"description.full": "{{fiFullDescription}}"
|
|
7
|
+
}
|