@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
package/scripts/diagnose-cli.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/* eslint-disable no-console */
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* List every PATH hit for aifabrix / af and each --version (find duplicate installs).
|
|
6
|
-
*
|
|
7
|
-
* @fileoverview CLI path diagnostic for @aifabrix/builder
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const { execFileSync, execSync } = require('child_process');
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
const path = require('path');
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Reads package.json `bin` field.
|
|
16
|
-
* @returns {Record<string, string>|string} Bin map or single path string
|
|
17
|
-
*/
|
|
18
|
-
function readBins() {
|
|
19
|
-
const pkgPath = path.join(__dirname, '..', 'package.json');
|
|
20
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
21
|
-
return pkg.bin || { aifabrix: 'bin/aifabrix.js' };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Resolves every PATH directory that exposes an executable named `binName`.
|
|
26
|
-
* @param {string} binName - CLI name (e.g. aifabrix)
|
|
27
|
-
* @returns {Array<{ path: string, real: string }>} Deduped hits with real paths
|
|
28
|
-
*/
|
|
29
|
-
function locationsOnPath(binName) {
|
|
30
|
-
if (process.platform === 'win32') {
|
|
31
|
-
try {
|
|
32
|
-
const out = execSync(`where ${binName}`, {
|
|
33
|
-
encoding: 'utf8',
|
|
34
|
-
stdio: ['ignore', 'pipe', 'ignore']
|
|
35
|
-
}).trim();
|
|
36
|
-
return out.split(/\r?\n/).filter(Boolean).map((p) => ({ path: p, real: p }));
|
|
37
|
-
} catch {
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const dirs = (process.env.PATH || '').split(path.delimiter).filter(Boolean);
|
|
43
|
-
const out = [];
|
|
44
|
-
const seenReal = new Set();
|
|
45
|
-
for (const dir of dirs) {
|
|
46
|
-
const candidate = path.join(dir, binName);
|
|
47
|
-
try {
|
|
48
|
-
const st = fs.lstatSync(candidate);
|
|
49
|
-
if (!st.isFile() && !st.isSymbolicLink()) continue;
|
|
50
|
-
fs.accessSync(candidate, fs.constants.X_OK);
|
|
51
|
-
const real = fs.realpathSync(candidate);
|
|
52
|
-
if (seenReal.has(real)) continue;
|
|
53
|
-
seenReal.add(real);
|
|
54
|
-
out.push({ path: candidate, real });
|
|
55
|
-
} catch {
|
|
56
|
-
// not found or not executable
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return out;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Runs `executablePath --version` and returns stdout or null on failure.
|
|
64
|
-
* @param {string} executablePath - Absolute path to the binary
|
|
65
|
-
* @returns {string|null} Trimmed version output
|
|
66
|
-
*/
|
|
67
|
-
function versionAt(executablePath) {
|
|
68
|
-
try {
|
|
69
|
-
return execFileSync(executablePath, ['--version'], {
|
|
70
|
-
encoding: 'utf8',
|
|
71
|
-
stdio: ['ignore', 'pipe', 'ignore']
|
|
72
|
-
}).trim();
|
|
73
|
-
} catch {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Prints PNPM_HOME and npm prefix for debugging PATH issues.
|
|
80
|
-
* @returns {void}
|
|
81
|
-
*/
|
|
82
|
-
function printEnvironment() {
|
|
83
|
-
console.log('Environment (relevant to global CLIs)\n');
|
|
84
|
-
console.log(` PNPM_HOME ${process.env.PNPM_HOME || '(not set)'}`);
|
|
85
|
-
try {
|
|
86
|
-
const prefix = execSync('npm config get prefix', {
|
|
87
|
-
encoding: 'utf8',
|
|
88
|
-
stdio: ['ignore', 'pipe', 'ignore']
|
|
89
|
-
}).trim();
|
|
90
|
-
console.log(` npm prefix ${prefix}`);
|
|
91
|
-
} catch {
|
|
92
|
-
console.log(' npm prefix (could not read)');
|
|
93
|
-
}
|
|
94
|
-
console.log('');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* @param {string[]} names - Bin names from package.json
|
|
99
|
-
* @returns {void}
|
|
100
|
-
*/
|
|
101
|
-
function printBinReports(names) {
|
|
102
|
-
for (const name of names) {
|
|
103
|
-
console.log(`── ${name} ──`);
|
|
104
|
-
const hits = locationsOnPath(name);
|
|
105
|
-
if (!hits.length) {
|
|
106
|
-
console.log(' (not found on PATH)\n');
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
hits.forEach((h, i) => {
|
|
110
|
-
const ver = versionAt(h.path);
|
|
111
|
-
const marker = i === 0 ? ' ← first on PATH (what your shell runs)' : '';
|
|
112
|
-
console.log(` [${i + 1}] ${h.path}`);
|
|
113
|
-
if (h.real !== h.path) console.log(` → ${h.real}`);
|
|
114
|
-
console.log(` --version: ${ver ?? '(failed to run)'}${marker}`);
|
|
115
|
-
});
|
|
116
|
-
console.log('');
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @param {string[]} names - Bin names from package.json
|
|
122
|
-
* @returns {void}
|
|
123
|
-
*/
|
|
124
|
-
function warnIfMultipleVersions(names) {
|
|
125
|
-
const uniqVersions = new Set();
|
|
126
|
-
for (const name of names) {
|
|
127
|
-
for (const h of locationsOnPath(name)) {
|
|
128
|
-
const v = versionAt(h.path);
|
|
129
|
-
if (v) uniqVersions.add(v);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (uniqVersions.size > 1) {
|
|
133
|
-
console.log('⚠ Multiple distinct --version values above: remove or reorder PATH so only one install remains.');
|
|
134
|
-
console.log(' Often: npm uninstall -g @aifabrix/builder, then ensure PNPM_HOME is before /usr/local/bin in PATH.\n');
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Entry: list PATH hits and versions for each package bin.
|
|
140
|
-
* @returns {void}
|
|
141
|
-
*/
|
|
142
|
-
function main() {
|
|
143
|
-
const binField = readBins();
|
|
144
|
-
const names = typeof binField === 'string' ? ['aifabrix'] : Object.keys(binField);
|
|
145
|
-
printEnvironment();
|
|
146
|
-
printBinReports(names);
|
|
147
|
-
warnIfMultipleVersions(names);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
main();
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Fail when a built Docker image contains dev-only paths (plan 154.3).
|
|
4
|
-
*
|
|
5
|
-
* @fileoverview builder-api image content gate
|
|
6
|
-
* @author AI Fabrix Team
|
|
7
|
-
* @version 1.0.0
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
'use strict';
|
|
11
|
-
|
|
12
|
-
const { checkImage } = require('./lib/docker-image-content-gate-core');
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @param {string[]} argv
|
|
16
|
-
* @returns {number}
|
|
17
|
-
*/
|
|
18
|
-
function main(argv) {
|
|
19
|
-
const args = argv.slice(2);
|
|
20
|
-
if (args.length < 2) {
|
|
21
|
-
console.error('Usage: docker_image_content_gate.js <image> <profile>');
|
|
22
|
-
return 1;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const [image, profile] = args;
|
|
26
|
-
try {
|
|
27
|
-
const violations = checkImage(image, profile);
|
|
28
|
-
if (violations.length > 0) {
|
|
29
|
-
console.error(`Image ${image} failed ${profile} content gate:`);
|
|
30
|
-
for (const path of violations) {
|
|
31
|
-
console.error(` - forbidden: ${path}`);
|
|
32
|
-
}
|
|
33
|
-
return 1;
|
|
34
|
-
}
|
|
35
|
-
console.log(`OK: ${image} passed ${profile} content gate`);
|
|
36
|
-
return 0;
|
|
37
|
-
} catch (error) {
|
|
38
|
-
console.error(`ERROR: ${error.message}`);
|
|
39
|
-
return 1;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (require.main === module) {
|
|
44
|
-
process.exit(main(process.argv));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
module.exports = { main };
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Export builder-api help/knowledge fixtures to Evidence Fabrix v2 bulk-load JSON.
|
|
4
|
-
*
|
|
5
|
-
* @fileoverview One-time / repeatable generator for Role Assistant evidence import
|
|
6
|
-
* @author AI Fabrix Team
|
|
7
|
-
* @version 1.0.0
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
'use strict';
|
|
11
|
-
|
|
12
|
-
const fs = require('fs');
|
|
13
|
-
const path = require('path');
|
|
14
|
-
|
|
15
|
-
const REPO_ROOT = path.join(__dirname, '..');
|
|
16
|
-
const DEFAULT_OUT = path.join(
|
|
17
|
-
REPO_ROOT,
|
|
18
|
-
'..',
|
|
19
|
-
'aifabrix-dataplane',
|
|
20
|
-
'integration',
|
|
21
|
-
'builder-api',
|
|
22
|
-
'builder-api-evidence.json'
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const EVIDENCE_PATTERNS = path.join(REPO_ROOT, 'docs', 'builder-help', 'evidence-patterns.json');
|
|
26
|
-
const GOLDEN_DIR = path.join(REPO_ROOT, 'docs', 'builder-help', 'golden-examples');
|
|
27
|
-
const PLATFORM_ROLES = path.join(REPO_ROOT, 'docs', 'builder-help', 'platform-roles.json');
|
|
28
|
-
const RESOURCE_CATALOG = path.join(REPO_ROOT, 'docs', 'builder-help', 'resource-type-catalog.json');
|
|
29
|
-
const HELP_MD_DIR = path.join(REPO_ROOT, 'lib', 'programmatic', 'help-content');
|
|
30
|
-
|
|
31
|
-
/** @type {Array<{ file: string, resourceType: string, order: number }>} */
|
|
32
|
-
const MD_TOPICS = [
|
|
33
|
-
{ file: 'overview.md', resourceType: 'workspace', order: 10 },
|
|
34
|
-
{ file: 'workflow.md', resourceType: 'workspace', order: 20 },
|
|
35
|
-
{ file: 'subscription-guide.md', resourceType: 'system', order: 30 },
|
|
36
|
-
{ file: 'cip-overview.md', resourceType: 'task', order: 40 },
|
|
37
|
-
{ file: 'dimensions-guide.md', resourceType: 'policy', order: 50 },
|
|
38
|
-
{ file: 'channel-onboarding.md', resourceType: 'channel', order: 60 },
|
|
39
|
-
{ file: 'connected-system-ui.md', resourceType: 'workspace', order: 70 }
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @param {string} text
|
|
44
|
-
* @returns {string}
|
|
45
|
-
*/
|
|
46
|
-
function stripMarkdown(text) {
|
|
47
|
-
return String(text || '')
|
|
48
|
-
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
49
|
-
.replace(/https?:\/\/[^\s)]+/gi, '')
|
|
50
|
-
.replace(/^#+\s*/gm, '')
|
|
51
|
-
.replace(/\s{2,}/g, ' ')
|
|
52
|
-
.trim();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @param {string} fileName
|
|
57
|
-
* @returns {{ title: string, summary: string, body: string }}
|
|
58
|
-
*/
|
|
59
|
-
function parseMarkdownTopic(fileName) {
|
|
60
|
-
const raw = fs.readFileSync(path.join(HELP_MD_DIR, fileName), 'utf8');
|
|
61
|
-
const lines = raw.split(/\r?\n/);
|
|
62
|
-
let title = path.basename(fileName, '.md');
|
|
63
|
-
const bodyLines = [];
|
|
64
|
-
for (const line of lines) {
|
|
65
|
-
if (line.startsWith('# ')) {
|
|
66
|
-
title = stripMarkdown(line.slice(2));
|
|
67
|
-
} else if (line.trim()) {
|
|
68
|
-
bodyLines.push(line);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const body = stripMarkdown(bodyLines.join('\n'));
|
|
72
|
-
const summary = body.slice(0, 240);
|
|
73
|
-
return { title, summary, body };
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @param {Object} row
|
|
78
|
-
* @returns {Object}
|
|
79
|
-
*/
|
|
80
|
-
function normalizeRow(row) {
|
|
81
|
-
const out = {
|
|
82
|
-
resourceType: String(row.resourceType || 'workspace').trim(),
|
|
83
|
-
title: String(row.title || '').trim(),
|
|
84
|
-
when: String(row.when || '').trim(),
|
|
85
|
-
expectedBehavior: String(row.expectedBehavior || '').trim(),
|
|
86
|
-
order: Number.isFinite(row.order) ? row.order : 100,
|
|
87
|
-
status: row.status === 'disabled' ? 'disabled' : 'active'
|
|
88
|
-
};
|
|
89
|
-
if (row.roleKey) {
|
|
90
|
-
out.roleKey = String(row.roleKey).trim();
|
|
91
|
-
}
|
|
92
|
-
if (row.description) {
|
|
93
|
-
out.description = String(row.description).trim();
|
|
94
|
-
}
|
|
95
|
-
return out;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @returns {Object[]}
|
|
100
|
-
*/
|
|
101
|
-
function rowsFromEvidencePatterns() {
|
|
102
|
-
const doc = JSON.parse(fs.readFileSync(EVIDENCE_PATTERNS, 'utf8'));
|
|
103
|
-
return (doc.patterns || []).map((p, i) =>
|
|
104
|
-
normalizeRow({
|
|
105
|
-
resourceType: p.resourceType || 'document',
|
|
106
|
-
title: p.title,
|
|
107
|
-
description: [p.summary, p.role ? `Audience: ${p.role}` : null, (p.steps || []).join(' → ')].filter(Boolean).join(' '),
|
|
108
|
-
when: p.summary || p.title,
|
|
109
|
-
expectedBehavior: (p.steps || []).join(' '),
|
|
110
|
-
order: 100 + i
|
|
111
|
-
})
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* @returns {Object[]}
|
|
117
|
-
*/
|
|
118
|
-
function rowsFromGoldenExamples() {
|
|
119
|
-
const rows = [];
|
|
120
|
-
let order = 200;
|
|
121
|
-
for (const file of fs.readdirSync(GOLDEN_DIR).sort()) {
|
|
122
|
-
if (!file.endsWith('.json')) {
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const doc = JSON.parse(fs.readFileSync(path.join(GOLDEN_DIR, file), 'utf8'));
|
|
126
|
-
const traversal = (doc.metadataTraversal || []).join(', ');
|
|
127
|
-
rows.push(
|
|
128
|
-
normalizeRow({
|
|
129
|
-
resourceType: doc.resourceType || 'document',
|
|
130
|
-
title: `Golden example: ${doc.title || doc.key}`,
|
|
131
|
-
description: [doc.summary, doc.role ? `Audience: ${doc.role}` : null].filter(Boolean).join(' '),
|
|
132
|
-
when: `Designing a ${doc.resourceType || 'document'} integration similar to ${doc.key}`,
|
|
133
|
-
expectedBehavior: [
|
|
134
|
-
doc.summary,
|
|
135
|
-
doc.subscriptionGuidance,
|
|
136
|
-
traversal ? `Traverse sections: ${traversal}` : null,
|
|
137
|
-
(doc.recommendedSectionKeys || []).length
|
|
138
|
-
? `Recommended sections: ${doc.recommendedSectionKeys.join(', ')}`
|
|
139
|
-
: null
|
|
140
|
-
]
|
|
141
|
-
.filter(Boolean)
|
|
142
|
-
.join(' '),
|
|
143
|
-
order: order++
|
|
144
|
-
})
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
return rows;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @returns {Object[]}
|
|
152
|
-
*/
|
|
153
|
-
function rowsFromMarkdownTopics() {
|
|
154
|
-
return MD_TOPICS.map((t) => {
|
|
155
|
-
const parsed = parseMarkdownTopic(t.file);
|
|
156
|
-
return normalizeRow({
|
|
157
|
-
resourceType: t.resourceType,
|
|
158
|
-
title: parsed.title,
|
|
159
|
-
description: parsed.summary,
|
|
160
|
-
when: `Agent needs builder-api guidance for ${parsed.title}`,
|
|
161
|
-
expectedBehavior: parsed.body,
|
|
162
|
-
order: t.order
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* @returns {Object[]}
|
|
169
|
-
*/
|
|
170
|
-
function rowsFromPlatformRoles() {
|
|
171
|
-
const doc = JSON.parse(fs.readFileSync(PLATFORM_ROLES, 'utf8'));
|
|
172
|
-
const roleLines = (doc.roles || [])
|
|
173
|
-
.map((r) => `${r.value}: ${r.description}`)
|
|
174
|
-
.join(' ');
|
|
175
|
-
return [
|
|
176
|
-
normalizeRow({
|
|
177
|
-
resourceType: 'policy',
|
|
178
|
-
title: 'Platform RBAC roles for facade integrations',
|
|
179
|
-
description: 'Dataplane platform roles for orchestration facade systems (not per-system admin/reader).',
|
|
180
|
-
when: 'Patching system.rolesPermissions or repair rbac on a builder-api facade system',
|
|
181
|
-
expectedBehavior: `Use rbacPreset platform. Allowed roles: ${roleLines}. Avoid {systemKey}-admin or {systemKey}-reader on facade APIs.`,
|
|
182
|
-
order: 5
|
|
183
|
-
})
|
|
184
|
-
];
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* @returns {Object[]}
|
|
189
|
-
*/
|
|
190
|
-
function rowsFromResourceCatalog() {
|
|
191
|
-
const doc = JSON.parse(fs.readFileSync(RESOURCE_CATALOG, 'utf8'));
|
|
192
|
-
const byCategory = {};
|
|
193
|
-
for (const rt of doc.resourceTypes || []) {
|
|
194
|
-
const cat = rt.category || 'other';
|
|
195
|
-
if (!byCategory[cat]) {
|
|
196
|
-
byCategory[cat] = [];
|
|
197
|
-
}
|
|
198
|
-
byCategory[cat].push(`${rt.key} (${rt.description})`);
|
|
199
|
-
}
|
|
200
|
-
const summary = Object.entries(byCategory)
|
|
201
|
-
.map(([cat, items]) => `${cat}: ${items.slice(0, 8).join('; ')}`)
|
|
202
|
-
.join(' ');
|
|
203
|
-
return [
|
|
204
|
-
normalizeRow({
|
|
205
|
-
resourceType: 'document',
|
|
206
|
-
title: 'Resource type catalog for datasource manifests',
|
|
207
|
-
description: 'Pick catalog keys that match business semantics; challenge generic placeholders.',
|
|
208
|
-
when: 'Choosing datasource.resourceType for a new or edited datasource',
|
|
209
|
-
expectedBehavior: `Compare purpose to catalog entries. Minimum system keys: ${(doc.minimumSystemKeys || []).join(', ')}. Categories: ${summary}`,
|
|
210
|
-
order: 8
|
|
211
|
-
})
|
|
212
|
-
];
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* @returns {Object[]}
|
|
217
|
-
*/
|
|
218
|
-
function rowsFromManifestGuides() {
|
|
219
|
-
return [
|
|
220
|
-
normalizeRow({
|
|
221
|
-
resourceType: 'policy',
|
|
222
|
-
title: 'Manifest section keys and dependency order',
|
|
223
|
-
when: 'Agent edits external system or datasource manifest sections',
|
|
224
|
-
expectedBehavior:
|
|
225
|
-
'Read one section at a time via manifest section APIs. After metadata or capability patches, run repair hooks for fieldMappings, expose, and rbac. Use dependency graph: downstream sections derive from upstream patches.',
|
|
226
|
-
order: 15
|
|
227
|
-
}),
|
|
228
|
-
normalizeRow({
|
|
229
|
-
resourceType: 'workspace',
|
|
230
|
-
title: 'Repair hooks and CLI flag mapping',
|
|
231
|
-
when: 'Manifest repair is required after structural edits',
|
|
232
|
-
expectedBehavior:
|
|
233
|
-
'POST manifest repair with explicit hooks (fieldMappings, expose, rbac, sync, test). Align with repair CLI flags. Validate workspace before upload or certify.',
|
|
234
|
-
order: 16
|
|
235
|
-
}),
|
|
236
|
-
normalizeRow({
|
|
237
|
-
resourceType: 'workspace',
|
|
238
|
-
title: 'Section quality and missing inputs',
|
|
239
|
-
when: 'GET manifest section returns quality.missingInputs',
|
|
240
|
-
expectedBehavior:
|
|
241
|
-
'Collect required missing inputs from the user before PATCH. Do not guess values. sectionReadToken from GET is optional on PATCH (server re-reads when omitted; stale token returns 409). Prefer GET when you need quality or missingInputs.',
|
|
242
|
-
order: 17
|
|
243
|
-
})
|
|
244
|
-
];
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function main() {
|
|
248
|
-
const outPath = path.resolve(process.argv[2] || DEFAULT_OUT);
|
|
249
|
-
const rows = [
|
|
250
|
-
...rowsFromPlatformRoles(),
|
|
251
|
-
...rowsFromResourceCatalog(),
|
|
252
|
-
...rowsFromMarkdownTopics(),
|
|
253
|
-
...rowsFromManifestGuides(),
|
|
254
|
-
...rowsFromEvidencePatterns(),
|
|
255
|
-
...rowsFromGoldenExamples()
|
|
256
|
-
];
|
|
257
|
-
fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
258
|
-
fs.writeFileSync(outPath, `${JSON.stringify(rows, null, 2)}\n`, 'utf8');
|
|
259
|
-
process.stdout.write(`Wrote ${rows.length} evidence row(s) to ${outPath}\n`);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
main();
|