@aifabrix/builder 2.52.0 → 2.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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/deploy-config.js +3 -2
- package/lib/app/down.js +16 -1
- package/lib/channels/add-channel.js +134 -57
- package/lib/channels/approval-guides/chatgpt.js +1 -1
- package/lib/channels/approval-guides/index.js +3 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +27 -14
- package/lib/channels/channel-add-ensure.js +128 -0
- package/lib/channels/channel-add-existing.js +72 -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 +107 -14
- package/lib/channels/channel-status-display.js +36 -3
- package/lib/channels/microsoft-copilot-channel-add.js +138 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +251 -0
- package/lib/channels/microsoft-copilot-entra-sso.js +285 -0
- package/lib/channels/microsoft-copilot-icons.js +74 -0
- package/lib/channels/microsoft-copilot-limits.js +103 -0
- package/lib/channels/microsoft-copilot-package.js +178 -52
- package/lib/channels/microsoft-copilot-validate.js +227 -0
- package/lib/cli/attach-default-help-examples.js +102 -0
- package/lib/cli/index.js +4 -0
- package/lib/cli/infra-guided.js +13 -6
- package/lib/cli/setup-credential-deployment.js +7 -5
- package/lib/cli/setup-infra.js +31 -4
- package/lib/cli/setup-utility-validate.js +1 -0
- package/lib/commands/channel-add-setup.js +28 -9
- package/lib/commands/channel.js +14 -10
- package/lib/commands/credential-push.js +37 -5
- package/lib/commands/integration-definition.js +158 -0
- package/lib/commands/package-score.js +72 -0
- 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 +163 -166
- package/lib/datasource/capability/capability-resolve.js +15 -5
- package/lib/datasource/capability/copy-operations.js +14 -4
- 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/infrastructure/index.js +19 -4
- package/lib/integration-definition/apply.js +476 -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 +433 -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/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/lab/package-parity-score.js +417 -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 +20 -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 +7 -1
- package/lib/programmatic/openapi-descriptions.js +46 -0
- package/lib/programmatic/openapi-envelope-examples.js +280 -0
- package/lib/programmatic/openapi-operation-bindings.js +50 -0
- package/lib/programmatic/openapi-request-schemas.js +40 -0
- package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
- package/lib/programmatic/openapi-result-schemas.js +76 -99
- package/lib/programmatic/openapi-schema-descriptions-core.js +25 -4
- package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-operations.js +43 -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/persist-supplied-openapi.js +180 -0
- package/lib/programmatic/route-handler-map.js +35 -1
- package/lib/programmatic/run-channel-package.js +236 -0
- package/lib/programmatic/run-integration-definition.js +77 -0
- package/lib/role-assistant/evidence-sync.js +55 -7
- package/lib/role-assistant/knowledge-sync-logging.js +58 -0
- package/lib/role-assistant/knowledge-sync.js +88 -93
- 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-attachments.js +118 -0
- package/lib/role-assistant/test-runner-bid-apply.js +201 -0
- package/lib/role-assistant/test-runner-bid-document.js +278 -0
- package/lib/role-assistant/test-runner-start-payload.js +96 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +249 -20
- 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 +152 -107
- package/lib/role-assistant/test-runner.js +5 -63
- package/lib/role-assistant/test-suite.js +112 -0
- package/lib/schema/application-schema.json +56 -6
- package/lib/schema/external-datasource.schema.json +103 -17
- package/lib/schema/external-system.schema.json +54 -3
- package/lib/schema/integration-definition.schema.json +195 -0
- package/lib/utils/authentication-shape.js +6 -0
- 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 +3 -1
- package/lib/utils/promote-dev-docker-image.js +102 -18
- package/lib/utils/transient-developer-id.js +28 -0
- package/package.json +14 -16
- package/templates/README.md +12 -1
- package/templates/applications/dataplane/application.yaml +10 -2
- package/templates/applications/dataplane/env.template +7 -6
- package/templates/applications/miso-controller/application.yaml +23 -8
- package/templates/applications/miso-controller/env.template +8 -2
- package/templates/applications/miso-controller/rbac.yaml +1 -0
- 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 +6 -4
- package/templates/channels/chatgpt/integration/README.md +4 -5
- package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +14 -16
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +30 -0
- package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +93 -22
- 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 +34 -19
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +15 -0
- 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 +36 -0
- package/templates/typescript/docker-compose.hbs +36 -0
- package/.cursor/plans/Done/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 -260
- package/jest.projects.js +0 -76
- 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 -110
- 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
|
@@ -68,7 +68,18 @@ function buildHonestyObservation(workResult) {
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
function pushHonestyAssertion(assertions, id, passed, message) {
|
|
71
|
+
function pushHonestyAssertion(assertions, id, passed, message, options = {}) {
|
|
72
|
+
const soft = options.soft === true;
|
|
73
|
+
if (soft && !passed) {
|
|
74
|
+
assertions.push({
|
|
75
|
+
id,
|
|
76
|
+
passed: true,
|
|
77
|
+
soft: true,
|
|
78
|
+
warn: true,
|
|
79
|
+
message: `${message} (soft — warning only)`
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
72
83
|
assertions.push({ id, passed, message });
|
|
73
84
|
}
|
|
74
85
|
|
|
@@ -87,7 +98,7 @@ function assertWorkResultPresent(assertions, honesty, observation) {
|
|
|
87
98
|
);
|
|
88
99
|
}
|
|
89
100
|
|
|
90
|
-
function assertSchemaVersion(assertions, honestySpec, honesty) {
|
|
101
|
+
function assertSchemaVersion(assertions, honestySpec, honesty, soft) {
|
|
91
102
|
if (!honestySpec.schemaVersion) {
|
|
92
103
|
return;
|
|
93
104
|
}
|
|
@@ -99,11 +110,12 @@ function assertSchemaVersion(assertions, honestySpec, honesty) {
|
|
|
99
110
|
passed,
|
|
100
111
|
passed
|
|
101
112
|
? `schemaVersion matched "${expected}".`
|
|
102
|
-
: `schemaVersion expected "${expected}" but got ${JSON.stringify(honesty.schemaVersion)}
|
|
113
|
+
: `schemaVersion expected "${expected}" but got ${JSON.stringify(honesty.schemaVersion)}.`,
|
|
114
|
+
{ soft }
|
|
103
115
|
);
|
|
104
116
|
}
|
|
105
117
|
|
|
106
|
-
function assertCompletion(assertions, honestySpec, honesty) {
|
|
118
|
+
function assertCompletion(assertions, honestySpec, honesty, soft) {
|
|
107
119
|
if (honestySpec.requireCompletion === false) {
|
|
108
120
|
return;
|
|
109
121
|
}
|
|
@@ -115,11 +127,12 @@ function assertCompletion(assertions, honestySpec, honesty) {
|
|
|
115
127
|
stateOk && goalOk,
|
|
116
128
|
stateOk && goalOk
|
|
117
129
|
? `completion.state/goalStatus honest (${honesty.completionState}/${honesty.goalStatus}).`
|
|
118
|
-
: `completion missing or invalid: state=${JSON.stringify(honesty.completionState)} goalStatus=${JSON.stringify(honesty.goalStatus)}
|
|
130
|
+
: `completion missing or invalid: state=${JSON.stringify(honesty.completionState)} goalStatus=${JSON.stringify(honesty.goalStatus)}.`,
|
|
131
|
+
{ soft }
|
|
119
132
|
);
|
|
120
133
|
}
|
|
121
134
|
|
|
122
|
-
function assertContribution(assertions, honestySpec, honesty) {
|
|
135
|
+
function assertContribution(assertions, honestySpec, honesty, soft) {
|
|
123
136
|
if (honestySpec.requireContributionObservation === false) {
|
|
124
137
|
return;
|
|
125
138
|
}
|
|
@@ -130,7 +143,8 @@ function assertContribution(assertions, honestySpec, honesty) {
|
|
|
130
143
|
ok,
|
|
131
144
|
ok
|
|
132
145
|
? `contributionObservation.status honest (${honesty.contributionStatus}).`
|
|
133
|
-
: `contributionObservation.status missing or invalid: ${JSON.stringify(honesty.contributionStatus)}
|
|
146
|
+
: `contributionObservation.status missing or invalid: ${JSON.stringify(honesty.contributionStatus)}.`,
|
|
147
|
+
{ soft }
|
|
134
148
|
);
|
|
135
149
|
}
|
|
136
150
|
|
|
@@ -171,9 +185,9 @@ function evaluateHonestyExpectations(honestySpec, observation, options = {}) {
|
|
|
171
185
|
// Missing Output is always a hard failure when required — soft does not waive it.
|
|
172
186
|
return assertions;
|
|
173
187
|
}
|
|
174
|
-
assertSchemaVersion(assertions, honestySpec, honesty);
|
|
175
|
-
assertCompletion(assertions, honestySpec, honesty);
|
|
176
|
-
assertContribution(assertions, honestySpec, honesty);
|
|
188
|
+
assertSchemaVersion(assertions, honestySpec, honesty, soft);
|
|
189
|
+
assertCompletion(assertions, honestySpec, honesty, soft);
|
|
190
|
+
assertContribution(assertions, honestySpec, honesty, soft);
|
|
177
191
|
assertMinResourceChanges(assertions, honestySpec, honesty, soft);
|
|
178
192
|
return assertions;
|
|
179
193
|
}
|
|
@@ -331,6 +331,32 @@ function collectCapabilitiesFromWorkSteps(out, steps) {
|
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
/**
|
|
335
|
+
* Work-result artifactIndex often carries CIP fingerprints like
|
|
336
|
+
* `capabilityKey=customer.createBasic|operationId=createbasic` when steps[] is empty.
|
|
337
|
+
* @param {Set<string>} out
|
|
338
|
+
* @param {unknown} artifacts
|
|
339
|
+
*/
|
|
340
|
+
function collectCapabilitiesFromArtifactIndex(out, artifacts) {
|
|
341
|
+
if (!Array.isArray(artifacts)) return;
|
|
342
|
+
for (const row of artifacts) {
|
|
343
|
+
if (!row || typeof row !== 'object') continue;
|
|
344
|
+
addCapabilityToken(out, row.capabilityKey);
|
|
345
|
+
addCapabilityToken(out, row.capability);
|
|
346
|
+
const fingerprint = typeof row.fingerprint === 'string' ? row.fingerprint : '';
|
|
347
|
+
const match = fingerprint.match(/(?:^|[|,])capabilityKey=([^|,]+)/);
|
|
348
|
+
if (match) {
|
|
349
|
+
addCapabilityToken(out, match[1]);
|
|
350
|
+
}
|
|
351
|
+
const artifactRef = typeof row.artifactRef === 'string' ? row.artifactRef : '';
|
|
352
|
+
// cip-log:fallback:customer.create:create:<id>
|
|
353
|
+
const refMatch = artifactRef.match(/^cip-log:[^:]+:([^:]+):/);
|
|
354
|
+
if (refMatch) {
|
|
355
|
+
addCapabilityToken(out, refMatch[1]);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
334
360
|
function collectObservedCapabilities(result) {
|
|
335
361
|
const out = new Set();
|
|
336
362
|
const steps = Array.isArray(result?.stepsRun) ? result.stepsRun : [];
|
|
@@ -341,6 +367,8 @@ function collectObservedCapabilities(result) {
|
|
|
341
367
|
}
|
|
342
368
|
collectCapabilitiesFromWorkSteps(out, result?.steps);
|
|
343
369
|
collectCapabilitiesFromWorkSteps(out, result?.workResult?.steps);
|
|
370
|
+
collectCapabilitiesFromArtifactIndex(out, result?.workResult?.artifactIndex);
|
|
371
|
+
collectCapabilitiesFromArtifactIndex(out, result?.artifactIndex);
|
|
344
372
|
addCapabilityToken(out, result?.task?.capabilityKey);
|
|
345
373
|
addCapabilityToken(out, result?.task?.capability);
|
|
346
374
|
if (result?.task?.approvalContext && typeof result.task.approvalContext === 'object') {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build work.start attachments from case YAML (paths / openapiDir).
|
|
3
|
+
* @fileoverview 517.1 — map suite OpenAPI files to ATT attachment shape
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const fs = require('../internal/fs-real-sync');
|
|
10
|
+
|
|
11
|
+
function resolveCaseDirectory(testCase) {
|
|
12
|
+
const sourceFile =
|
|
13
|
+
testCase && typeof testCase.sourceFile === 'string' ? testCase.sourceFile.trim() : '';
|
|
14
|
+
if (!sourceFile) {
|
|
15
|
+
return process.cwd();
|
|
16
|
+
}
|
|
17
|
+
return path.dirname(path.resolve(sourceFile));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function readJsonAttachmentBody(absolutePath) {
|
|
21
|
+
if (!fs.existsSync(absolutePath)) {
|
|
22
|
+
throw new Error(`Role assistant attachment file not found: ${absolutePath}`);
|
|
23
|
+
}
|
|
24
|
+
const text = fs.readFileSync(absolutePath, 'utf8');
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(text);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
throw new Error(`Role assistant attachment is not valid JSON: ${absolutePath}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function attachmentFromFile(absolutePath, meta = {}) {
|
|
33
|
+
const basename = path.basename(absolutePath);
|
|
34
|
+
const role = typeof meta.role === 'string' && meta.role.trim() ? meta.role.trim() : 'openapi';
|
|
35
|
+
return {
|
|
36
|
+
name: basename,
|
|
37
|
+
filename: basename,
|
|
38
|
+
mediaType: 'application/json',
|
|
39
|
+
role,
|
|
40
|
+
contributionPurpose: 'task',
|
|
41
|
+
body: readJsonAttachmentBody(absolutePath)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function resolveRelativeAttachmentPath(caseDir, relativePath) {
|
|
46
|
+
if (typeof relativePath !== 'string' || !relativePath.trim()) {
|
|
47
|
+
throw new Error('Role assistant attachment path must be a non-empty string');
|
|
48
|
+
}
|
|
49
|
+
const absolutePath = path.resolve(caseDir, relativePath.trim());
|
|
50
|
+
return absolutePath;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function collectExplicitAttachments(caseDir, attachments) {
|
|
54
|
+
if (!Array.isArray(attachments) || attachments.length === 0) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
return attachments.map((row) => {
|
|
58
|
+
if (!row || typeof row !== 'object' || Array.isArray(row)) {
|
|
59
|
+
throw new Error('Role assistant input.attachments entries must be objects');
|
|
60
|
+
}
|
|
61
|
+
const rel = row.path || row.file || row.filename;
|
|
62
|
+
const absolutePath = resolveRelativeAttachmentPath(caseDir, rel);
|
|
63
|
+
return attachmentFromFile(absolutePath, row);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function listOpenapiJsonFiles(absoluteDir, allowList) {
|
|
68
|
+
if (!fs.existsSync(absoluteDir)) {
|
|
69
|
+
throw new Error(`Role assistant openapiDir not found: ${absoluteDir}`);
|
|
70
|
+
}
|
|
71
|
+
const names = fs
|
|
72
|
+
.readdirSync(absoluteDir)
|
|
73
|
+
.filter((entry) => /\.json$/i.test(entry))
|
|
74
|
+
.sort();
|
|
75
|
+
if (Array.isArray(allowList) && allowList.length > 0) {
|
|
76
|
+
const wanted = new Set(allowList.map((row) => String(row).trim()).filter(Boolean));
|
|
77
|
+
return names.filter((name) => wanted.has(name));
|
|
78
|
+
}
|
|
79
|
+
return names;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function collectOpenapiDirAttachments(caseDir, input) {
|
|
83
|
+
if (typeof input.openapiDir !== 'string' || !input.openapiDir.trim()) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const absoluteDir = path.resolve(caseDir, input.openapiDir.trim());
|
|
87
|
+
const files = listOpenapiJsonFiles(absoluteDir, input.openapiFiles);
|
|
88
|
+
if (files.length === 0) {
|
|
89
|
+
throw new Error(`Role assistant openapiDir has no matching *.json files: ${absoluteDir}`);
|
|
90
|
+
}
|
|
91
|
+
return files.map((name) => attachmentFromFile(path.join(absoluteDir, name), { role: 'openapi' }));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Build ATT-shaped attachments for work.start from case input.
|
|
96
|
+
* @param {Object} testCase - Normalized case (may include sourceFile)
|
|
97
|
+
* @returns {Object[]|undefined}
|
|
98
|
+
*/
|
|
99
|
+
function buildStartAttachments(testCase) {
|
|
100
|
+
const input =
|
|
101
|
+
testCase && typeof testCase.input === 'object' && testCase.input && !Array.isArray(testCase.input)
|
|
102
|
+
? testCase.input
|
|
103
|
+
: {};
|
|
104
|
+
const caseDir = resolveCaseDirectory(testCase);
|
|
105
|
+
const fromExplicit = collectExplicitAttachments(caseDir, input.attachments);
|
|
106
|
+
const fromDir = collectOpenapiDirAttachments(caseDir, input);
|
|
107
|
+
const merged = [...fromExplicit, ...fromDir];
|
|
108
|
+
if (merged.length === 0) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
return merged;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = {
|
|
115
|
+
buildStartAttachments,
|
|
116
|
+
resolveCaseDirectory,
|
|
117
|
+
attachmentFromFile
|
|
118
|
+
};
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Soft-loop BID apply after workspace.createsystem (suite 002 / plan 512.4).
|
|
3
|
+
* @fileoverview LAB-ONLY debt helper: POST Builder-api HTTP apply when the RA
|
|
4
|
+
* soft loop needs a package materialize. Product path is Decision Engine →
|
|
5
|
+
* capability.execute(template.applyintegrationdefinition) → COM/CIP.
|
|
6
|
+
* Do not treat this module as the product apply path once Runtime COM invoke
|
|
7
|
+
* works for the suite (plan 517.5). Non-product — lab helper only.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const fs = require('../internal/fs-real-sync');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const {
|
|
15
|
+
loadCaseBidDocument,
|
|
16
|
+
resolveTargetSystemKey
|
|
17
|
+
} = require('./test-runner-bid-document');
|
|
18
|
+
const { buildStartAttachments } = require('./test-runner-attachments');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @returns {string}
|
|
22
|
+
*/
|
|
23
|
+
function resolveBuilderApiBaseUrl() {
|
|
24
|
+
const fromEnv = String(process.env.BUILDER_API_URL || process.env.BUILDER_URL || '').trim();
|
|
25
|
+
if (fromEnv) {
|
|
26
|
+
return fromEnv.replace(/\/$/, '');
|
|
27
|
+
}
|
|
28
|
+
let developerId = 0;
|
|
29
|
+
try {
|
|
30
|
+
const yaml = require('js-yaml');
|
|
31
|
+
const cfgPath = path.join(
|
|
32
|
+
process.env.HOME || '',
|
|
33
|
+
'.aifabrix',
|
|
34
|
+
'config.yaml'
|
|
35
|
+
);
|
|
36
|
+
if (fs.existsSync(cfgPath)) {
|
|
37
|
+
const cfg = yaml.load(fs.readFileSync(cfgPath, 'utf8')) || {};
|
|
38
|
+
developerId = Number(cfg['developer-id'] || cfg.developerId || 0) || 0;
|
|
39
|
+
}
|
|
40
|
+
} catch (_err) {
|
|
41
|
+
developerId = 0;
|
|
42
|
+
}
|
|
43
|
+
return `http://localhost:${3005 + developerId * 100}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {Object} authConfig
|
|
48
|
+
* @returns {string}
|
|
49
|
+
*/
|
|
50
|
+
function extractBearer(authConfig) {
|
|
51
|
+
if (!authConfig || typeof authConfig !== 'object') {
|
|
52
|
+
return '';
|
|
53
|
+
}
|
|
54
|
+
if (typeof authConfig.token === 'string' && authConfig.token.trim()) {
|
|
55
|
+
return authConfig.token.trim();
|
|
56
|
+
}
|
|
57
|
+
if (typeof authConfig.bearerToken === 'string' && authConfig.bearerToken.trim()) {
|
|
58
|
+
return authConfig.bearerToken.trim();
|
|
59
|
+
}
|
|
60
|
+
const header = authConfig.headers && authConfig.headers.Authorization;
|
|
61
|
+
const m = /^Bearer\s+(.+)$/i.exec(String(header || ''));
|
|
62
|
+
return m ? m[1].trim() : '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* True when wait is for template.applyintegrationdefinition and a case BID exists.
|
|
67
|
+
* @param {Object} testCase
|
|
68
|
+
* @param {Object} wait
|
|
69
|
+
* @returns {boolean}
|
|
70
|
+
*/
|
|
71
|
+
function shouldApplyBidAfterWait(testCase, wait) {
|
|
72
|
+
const bid = loadCaseBidDocument(testCase);
|
|
73
|
+
if (!bid) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
const capability = String(
|
|
77
|
+
wait.questionKey || wait.objectRef?.capabilityKey || wait.prompt || ''
|
|
78
|
+
).toLowerCase();
|
|
79
|
+
// Product path: DE → capability.execute(template.applyintegrationdefinition).
|
|
80
|
+
return capability.includes('applyintegrationdefinition');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Lab-only soft HTTP BID apply. Hard cases (expected.soft !== true) must rely on
|
|
85
|
+
* Runtime COM/CIP apply after respond+continue — not Builder-api HTTP (517.5 / 517.4.7).
|
|
86
|
+
* @param {Object} testCase
|
|
87
|
+
* @param {Object} wait
|
|
88
|
+
* @returns {boolean}
|
|
89
|
+
*/
|
|
90
|
+
function shouldSoftHttpBidApply(testCase, wait) {
|
|
91
|
+
if (!shouldApplyBidAfterWait(testCase, wait)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
return testCase?.expected?.soft === true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {Object} testCase
|
|
99
|
+
* @returns {Object[]|null}
|
|
100
|
+
*/
|
|
101
|
+
function collectOpenApiPersistDocuments(testCase) {
|
|
102
|
+
let attachments = [];
|
|
103
|
+
try {
|
|
104
|
+
attachments = buildStartAttachments(testCase) || [];
|
|
105
|
+
} catch (_err) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const documents = attachments
|
|
109
|
+
.filter((row) => row && (row.role === 'openapi' || !row.role) && row.body)
|
|
110
|
+
.map((row) => ({
|
|
111
|
+
filename: row.filename || row.name,
|
|
112
|
+
body: row.body
|
|
113
|
+
}))
|
|
114
|
+
.filter((row) => row.filename);
|
|
115
|
+
return documents.length > 0 ? documents : null;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @param {Response} res
|
|
120
|
+
* @param {string} label
|
|
121
|
+
* @returns {Promise<Object|null>}
|
|
122
|
+
*/
|
|
123
|
+
async function readBuilderApiJsonOrThrow(res, label) {
|
|
124
|
+
const text = await res.text();
|
|
125
|
+
let body = null;
|
|
126
|
+
try {
|
|
127
|
+
body = text ? JSON.parse(text) : null;
|
|
128
|
+
} catch (_err) {
|
|
129
|
+
body = { raw: text };
|
|
130
|
+
}
|
|
131
|
+
if (!res.ok) {
|
|
132
|
+
const err = new Error(
|
|
133
|
+
`${label} HTTP ${res.status}: ${typeof body === 'object' ? JSON.stringify(body).slice(0, 300) : text}`
|
|
134
|
+
);
|
|
135
|
+
err.status = res.status;
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
return body && body.data ? body.data : body;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Lab debt: stage suite OpenAPI into workspace via 517.2 persist API before apply.
|
|
143
|
+
* Product path is DE → capability.execute(persistsuppliedopenapi).
|
|
144
|
+
* @param {Object} authConfig
|
|
145
|
+
* @param {Object} testCase
|
|
146
|
+
* @param {string} systemKey
|
|
147
|
+
* @returns {Promise<Object|null>}
|
|
148
|
+
*/
|
|
149
|
+
async function persistCaseOpenApiViaBuilderApi(authConfig, testCase, systemKey) {
|
|
150
|
+
const token = extractBearer(authConfig);
|
|
151
|
+
if (!token || !systemKey) {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
const documents = collectOpenApiPersistDocuments(testCase);
|
|
155
|
+
if (!documents) {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const url = `${resolveBuilderApiBaseUrl()}/api/v1/builder/systems/${encodeURIComponent(systemKey)}/openapi/persist-supplied`;
|
|
159
|
+
const res = await fetch(url, {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
headers: {
|
|
162
|
+
Authorization: `Bearer ${token}`,
|
|
163
|
+
'Content-Type': 'application/json'
|
|
164
|
+
},
|
|
165
|
+
body: JSON.stringify({ documents })
|
|
166
|
+
});
|
|
167
|
+
return readBuilderApiJsonOrThrow(res, 'OpenAPI persist failed');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {Object} authConfig
|
|
172
|
+
* @param {Object} testCase
|
|
173
|
+
* @returns {Promise<Object|null>}
|
|
174
|
+
*/
|
|
175
|
+
async function applyCaseBidViaBuilderApi(authConfig, testCase) {
|
|
176
|
+
const bid = loadCaseBidDocument(testCase);
|
|
177
|
+
const systemKey = resolveTargetSystemKey(testCase);
|
|
178
|
+
const token = extractBearer(authConfig);
|
|
179
|
+
if (!bid || !systemKey || !token) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
await persistCaseOpenApiViaBuilderApi(authConfig, testCase, systemKey);
|
|
183
|
+
const url = `${resolveBuilderApiBaseUrl()}/api/v1/builder/systems/${encodeURIComponent(systemKey)}/integration-definition/apply`;
|
|
184
|
+
const res = await fetch(url, {
|
|
185
|
+
method: 'POST',
|
|
186
|
+
headers: {
|
|
187
|
+
Authorization: `Bearer ${token}`,
|
|
188
|
+
'Content-Type': 'application/json'
|
|
189
|
+
},
|
|
190
|
+
body: JSON.stringify({ integrationDefinition: bid, force: true })
|
|
191
|
+
});
|
|
192
|
+
return readBuilderApiJsonOrThrow(res, 'BID apply failed');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
module.exports = {
|
|
196
|
+
resolveBuilderApiBaseUrl,
|
|
197
|
+
shouldApplyBidAfterWait,
|
|
198
|
+
shouldSoftHttpBidApply,
|
|
199
|
+
persistCaseOpenApiViaBuilderApi,
|
|
200
|
+
applyCaseBidViaBuilderApi
|
|
201
|
+
};
|