@aifabrix/builder 2.52.1 → 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.
Files changed (224) hide show
  1. package/lib/app/deploy-config.js +3 -2
  2. package/lib/channels/add-channel.js +11 -41
  3. package/lib/channels/approval-guides/index.js +3 -0
  4. package/lib/channels/approval-guides/microsoft-copilot.js +26 -17
  5. package/lib/channels/channel-add-existing.js +72 -0
  6. package/lib/channels/channel-runtime-resolver.js +5 -1
  7. package/lib/channels/channel-status-display.js +30 -3
  8. package/lib/channels/microsoft-copilot-entra-sso-form.js +73 -2
  9. package/lib/channels/microsoft-copilot-entra-sso.js +26 -5
  10. package/lib/channels/microsoft-copilot-limits.js +22 -3
  11. package/lib/channels/microsoft-copilot-package.js +59 -14
  12. package/lib/channels/microsoft-copilot-validate.js +40 -10
  13. package/lib/cli/attach-default-help-examples.js +102 -0
  14. package/lib/cli/index.js +2 -0
  15. package/lib/cli/setup-credential-deployment.js +7 -5
  16. package/lib/cli/setup-utility-validate.js +1 -0
  17. package/lib/commands/credential-push.js +37 -5
  18. package/lib/commands/package-score.js +72 -0
  19. package/lib/commands/role-assistant.js +46 -8
  20. package/lib/deployment/deployer-poll-run.js +2 -2
  21. package/lib/deployment/deployer.js +1 -1
  22. package/lib/deployment/environment.js +2 -2
  23. package/lib/external-system/deploy.js +11 -21
  24. package/lib/integration-definition/apply.js +12 -14
  25. package/lib/integration-definition/enrich-openapi-operations.js +9 -10
  26. package/lib/lab/package-parity-score.js +417 -0
  27. package/lib/programmatic/capability-registry.js +1 -0
  28. package/lib/programmatic/help-content/channel-onboarding.md +35 -0
  29. package/lib/programmatic/help-content/cip-overview.md +27 -0
  30. package/lib/programmatic/help-content/connected-system-ui.md +70 -0
  31. package/lib/programmatic/help-content/dimensions-guide.md +23 -0
  32. package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
  33. package/lib/programmatic/help-content/overview.md +25 -0
  34. package/lib/programmatic/help-content/subscription-guide.md +27 -0
  35. package/lib/programmatic/help-content/workflow.md +50 -0
  36. package/lib/programmatic/openapi-component-schemas.js +1 -0
  37. package/lib/programmatic/openapi-descriptions.js +6 -0
  38. package/lib/programmatic/openapi-envelope-examples.js +11 -0
  39. package/lib/programmatic/openapi-operation-bindings.js +5 -0
  40. package/lib/programmatic/openapi-request-schemas.js +39 -13
  41. package/lib/programmatic/openapi-result-schemas.js +30 -0
  42. package/lib/programmatic/openapi-schema-descriptions-core.js +18 -0
  43. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  44. package/lib/programmatic/persist-supplied-openapi.js +180 -0
  45. package/lib/programmatic/route-handler-map.js +6 -0
  46. package/lib/programmatic/run-integration-definition.js +13 -5
  47. package/lib/role-assistant/evidence-sync.js +55 -7
  48. package/lib/role-assistant/test-runner-attachments.js +118 -0
  49. package/lib/role-assistant/test-runner-bid-apply.js +100 -21
  50. package/lib/role-assistant/test-runner-bid-document.js +1 -1
  51. package/lib/role-assistant/test-runner-start-payload.js +96 -0
  52. package/lib/role-assistant/test-runner-workhub-answers.js +11 -7
  53. package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
  54. package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
  55. package/lib/role-assistant/test-runner-workhub.js +68 -105
  56. package/lib/role-assistant/test-runner.js +5 -63
  57. package/lib/role-assistant/test-suite.js +33 -40
  58. package/lib/utils/compose-generator.js +10 -1
  59. package/lib/utils/compose-traefik-extra-routes.js +107 -0
  60. package/lib/utils/docker-build.js +2 -2
  61. package/lib/utils/help-builder.js +2 -1
  62. package/lib/utils/promote-dev-docker-image.js +15 -10
  63. package/package.json +14 -16
  64. package/templates/README.md +12 -1
  65. package/templates/applications/dataplane/application.yaml +8 -1
  66. package/templates/applications/dataplane/env.template +1 -1
  67. package/templates/applications/miso-controller/application.yaml +2 -1
  68. package/templates/applications/miso-controller/rbac.yaml +1 -0
  69. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +6 -2
  70. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +8 -5
  71. package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
  72. package/templates/channels/microsoft-copilot/install.template.md.hbs +74 -22
  73. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +29 -14
  74. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +6 -2
  75. package/templates/python/docker-compose.hbs +36 -0
  76. package/templates/typescript/docker-compose.hbs +36 -0
  77. package/.cursor/plans/Archive/157.1-security-quality-violations-by-type.csv +0 -374
  78. package/.cursor/process/README.md +0 -9
  79. package/.cursor/rules/anchor-docs.mdc +0 -15
  80. package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
  81. package/.cursor/rules/cli-layout.mdc +0 -81
  82. package/.cursor/rules/cli-product-neutral.mdc +0 -43
  83. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
  84. package/.cursor/rules/docs-rules.mdc +0 -32
  85. package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
  86. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
  87. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
  88. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
  89. package/.cursor/rules/project-rules.mdc +0 -913
  90. package/.cursor/skills/README.md +0 -15
  91. package/.dockerignore +0 -52
  92. package/.eslintignore +0 -22
  93. package/.markdownlint.json +0 -14
  94. package/anchor-docs/README.md +0 -10
  95. package/anchor-docs/_TEMPLATE +0 -24
  96. package/babel.config.js +0 -6
  97. package/bin/builder-api-cleanup.js +0 -26
  98. package/bin/builder-api-nest.js +0 -10
  99. package/bin/builder-api-spike.js +0 -19
  100. package/enterprise-knowledge/README.md +0 -50
  101. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
  102. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
  103. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
  104. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
  105. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
  106. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
  107. package/integration/README.md +0 -81
  108. package/integration/github/README.md +0 -53
  109. package/integration/github/application.json +0 -21
  110. package/integration/github/deploy.js +0 -72
  111. package/integration/github/env.template +0 -11
  112. package/integration/github/github-datasource-issue-comments.json +0 -239
  113. package/integration/github/github-datasource-issues.json +0 -399
  114. package/integration/github/github-datasource-repository.json +0 -354
  115. package/integration/github/github-deploy.json +0 -1202
  116. package/integration/github/github-system.json +0 -82
  117. package/integration/hubspot-test/README.md +0 -159
  118. package/integration/hubspot-test/application.json +0 -54
  119. package/integration/hubspot-test/companies.json +0 -2048
  120. package/integration/hubspot-test/create-hubspot.js +0 -523
  121. package/integration/hubspot-test/env.template +0 -4
  122. package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
  123. package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
  124. package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
  125. package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
  126. package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
  127. package/integration/hubspot-test/hubspot-test-system.json +0 -74
  128. package/integration/hubspot-test/rbac.json +0 -166
  129. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
  130. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
  131. package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
  132. package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
  133. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
  134. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
  135. package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
  136. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
  137. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  138. package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
  139. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
  140. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
  141. package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
  142. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
  143. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  144. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  145. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
  146. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
  147. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
  148. package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
  149. package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
  150. package/integration/hubspot-test/test-dataplane-down.js +0 -209
  151. package/integration/hubspot-test/test.js +0 -1588
  152. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
  153. package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
  154. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
  155. package/integration/roundtrip-test-local/README.md +0 -143
  156. package/integration/roundtrip-test-local/application.yaml +0 -13
  157. package/integration/roundtrip-test-local/env.template +0 -15
  158. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
  159. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
  160. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
  161. package/integration/roundtrip-test-local2/README.md +0 -143
  162. package/integration/roundtrip-test-local2/application.yaml +0 -13
  163. package/integration/roundtrip-test-local2/env.template +0 -15
  164. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
  165. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
  166. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
  167. package/integration/test/wizard.yaml +0 -8
  168. package/jest.config.coverage.js +0 -37
  169. package/jest.config.default.js +0 -11
  170. package/jest.config.integration.fixtures.js +0 -22
  171. package/jest.config.integration.js +0 -33
  172. package/jest.config.isolated.js +0 -11
  173. package/jest.config.manual.js +0 -30
  174. package/jest.global-live-fabrix-hooks.js +0 -36
  175. package/jest.isolated-projects.js +0 -283
  176. package/jest.projects.js +0 -79
  177. package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +0 -205
  178. package/packages/builder-api/README.md +0 -120
  179. package/packages/builder-api/package.json +0 -30
  180. package/packages/builder-api/src/app.module.ts +0 -7
  181. package/packages/builder-api/src/auth/auth.module.ts +0 -5
  182. package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
  183. package/packages/builder-api/src/main.ts +0 -16
  184. package/packages/builder-api/tsconfig.json +0 -15
  185. package/scripts/check-builder-api-architecture-grep.js +0 -79
  186. package/scripts/check-datasource-test-run-schema-sync.js +0 -34
  187. package/scripts/ci-fix.sh +0 -19
  188. package/scripts/ci-simulate.sh +0 -19
  189. package/scripts/diagnose-cli.js +0 -150
  190. package/scripts/docker_image_content_gate.js +0 -47
  191. package/scripts/docker_image_content_gate.sh +0 -5
  192. package/scripts/export-builder-api-evidence.js +0 -262
  193. package/scripts/install-local.js +0 -490
  194. package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
  195. package/scripts/lib/builder-api-docker-staging-core.js +0 -183
  196. package/scripts/lib/docker-image-content-gate-core.js +0 -166
  197. package/scripts/lib/plan-actor.js +0 -109
  198. package/scripts/lib/plan-config.js +0 -20
  199. package/scripts/lib/plan-gates.js +0 -154
  200. package/scripts/lib/plan-meta.js +0 -104
  201. package/scripts/lib/plan-parse.js +0 -162
  202. package/scripts/lib/plan-prevalidate-gates.js +0 -337
  203. package/scripts/lib/plan-run-core.js +0 -125
  204. package/scripts/lib/plan-run-report.js +0 -119
  205. package/scripts/plan-approve.js +0 -24
  206. package/scripts/plan-archive.js +0 -49
  207. package/scripts/plan-run.js +0 -13
  208. package/scripts/plan-set-actor.js +0 -21
  209. package/scripts/plan-validate.js +0 -80
  210. package/scripts/pnpm/af.mjs +0 -125
  211. package/scripts/pnpm/check-quiet.mjs +0 -32
  212. package/scripts/pnpm/dev-install.mjs +0 -29
  213. package/scripts/pnpm/dev-reload.mjs +0 -18
  214. package/scripts/pnpm/help.mjs +0 -55
  215. package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
  216. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
  217. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
  218. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
  219. package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
  220. package/scripts/pnpm/lib/spinner.mjs +0 -42
  221. package/scripts/pnpm-global-remove.js +0 -48
  222. package/scripts/stage_builder_api_for_docker.js +0 -65
  223. package/scripts/sync-builder-api-template.js +0 -44
  224. package/scripts/test-dataplane-bootstrap.js +0 -331
@@ -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,5 +0,0 @@
1
- #!/usr/bin/env sh
2
- # Plan 154.3 — verify a built builder-api image does not contain dev-only trees.
3
- set -eu
4
- ROOT="$(CDPATH= cd -- "$(dirname "$0")/.." && pwd)"
5
- exec node "$ROOT/scripts/docker_image_content_gate.js" "$@"
@@ -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();