@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.
Files changed (310) hide show
  1. package/lib/api/datasources-extended.api.js +8 -8
  2. package/lib/api/keycloak.api.js +92 -0
  3. package/lib/api/token-providers.api.js +77 -0
  4. package/lib/api/types/keycloak.types.js +23 -0
  5. package/lib/api/types/token-providers.types.js +65 -0
  6. package/lib/app/deploy-config.js +3 -2
  7. package/lib/app/down.js +16 -1
  8. package/lib/channels/add-channel.js +134 -57
  9. package/lib/channels/approval-guides/chatgpt.js +1 -1
  10. package/lib/channels/approval-guides/index.js +3 -0
  11. package/lib/channels/approval-guides/microsoft-copilot.js +27 -14
  12. package/lib/channels/channel-add-ensure.js +128 -0
  13. package/lib/channels/channel-add-existing.js +72 -0
  14. package/lib/channels/channel-artifact-generator.js +11 -1
  15. package/lib/channels/channel-branding.js +94 -0
  16. package/lib/channels/channel-credential.js +8 -0
  17. package/lib/channels/channel-discovery.js +330 -0
  18. package/lib/channels/channel-external-system.js +1 -1
  19. package/lib/channels/channel-runtime-resolver.js +107 -14
  20. package/lib/channels/channel-status-display.js +36 -3
  21. package/lib/channels/microsoft-copilot-channel-add.js +138 -0
  22. package/lib/channels/microsoft-copilot-entra-sso-form.js +251 -0
  23. package/lib/channels/microsoft-copilot-entra-sso.js +285 -0
  24. package/lib/channels/microsoft-copilot-icons.js +74 -0
  25. package/lib/channels/microsoft-copilot-limits.js +103 -0
  26. package/lib/channels/microsoft-copilot-package.js +178 -52
  27. package/lib/channels/microsoft-copilot-validate.js +227 -0
  28. package/lib/cli/attach-default-help-examples.js +102 -0
  29. package/lib/cli/index.js +4 -0
  30. package/lib/cli/infra-guided.js +13 -6
  31. package/lib/cli/setup-credential-deployment.js +7 -5
  32. package/lib/cli/setup-infra.js +31 -4
  33. package/lib/cli/setup-utility-validate.js +1 -0
  34. package/lib/commands/channel-add-setup.js +28 -9
  35. package/lib/commands/channel.js +14 -10
  36. package/lib/commands/credential-push.js +37 -5
  37. package/lib/commands/integration-definition.js +158 -0
  38. package/lib/commands/package-score.js +72 -0
  39. package/lib/commands/repair-auth-apply.js +19 -5
  40. package/lib/commands/repair-datasource-sync-operations.js +4 -1
  41. package/lib/commands/role-assistant-test-output.js +200 -0
  42. package/lib/commands/role-assistant.js +163 -166
  43. package/lib/datasource/capability/capability-resolve.js +15 -5
  44. package/lib/datasource/capability/copy-operations.js +14 -4
  45. package/lib/deployment/deployer-poll-run.js +2 -2
  46. package/lib/deployment/deployer.js +1 -1
  47. package/lib/deployment/environment.js +2 -2
  48. package/lib/external-system/deploy.js +11 -21
  49. package/lib/infrastructure/index.js +19 -4
  50. package/lib/integration-definition/apply.js +476 -0
  51. package/lib/integration-definition/canonical-json.js +51 -0
  52. package/lib/integration-definition/emit-suite-bid.js +94 -0
  53. package/lib/integration-definition/enrich-crm-field-mappings.js +240 -0
  54. package/lib/integration-definition/enrich-openapi-operations.js +433 -0
  55. package/lib/integration-definition/from-discovery.js +339 -0
  56. package/lib/integration-definition/hash.js +37 -0
  57. package/lib/integration-definition/index.js +37 -0
  58. package/lib/integration-definition/resource-type-catalog.js +59 -0
  59. package/lib/integration-definition/system-kind-enum.js +40 -0
  60. package/lib/integration-definition/validate.js +148 -0
  61. package/lib/lab/package-parity-score.js +417 -0
  62. package/lib/programmatic/builder-api-request.js +5 -1
  63. package/lib/programmatic/builder-help-governance.js +3 -2
  64. package/lib/programmatic/capability-registry.js +20 -0
  65. package/lib/programmatic/help-content/channel-onboarding.md +35 -0
  66. package/lib/programmatic/help-content/cip-overview.md +27 -0
  67. package/lib/programmatic/help-content/connected-system-ui.md +70 -0
  68. package/lib/programmatic/help-content/dimensions-guide.md +23 -0
  69. package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
  70. package/lib/programmatic/help-content/overview.md +25 -0
  71. package/lib/programmatic/help-content/subscription-guide.md +27 -0
  72. package/lib/programmatic/help-content/workflow.md +50 -0
  73. package/lib/programmatic/openapi-component-schemas.js +7 -1
  74. package/lib/programmatic/openapi-descriptions.js +46 -0
  75. package/lib/programmatic/openapi-envelope-examples.js +280 -0
  76. package/lib/programmatic/openapi-operation-bindings.js +50 -0
  77. package/lib/programmatic/openapi-request-schemas.js +40 -0
  78. package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
  79. package/lib/programmatic/openapi-result-schemas.js +76 -99
  80. package/lib/programmatic/openapi-schema-descriptions-core.js +25 -4
  81. package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
  82. package/lib/programmatic/openapi-schema-descriptions-operations.js +43 -0
  83. package/lib/programmatic/openapi-schema-helpers.js +9 -9
  84. package/lib/programmatic/openapi-spec.js +11 -1
  85. package/lib/programmatic/orchestration-openapi-meta.js +10 -0
  86. package/lib/programmatic/persist-supplied-openapi.js +180 -0
  87. package/lib/programmatic/route-handler-map.js +35 -1
  88. package/lib/programmatic/run-channel-package.js +236 -0
  89. package/lib/programmatic/run-integration-definition.js +77 -0
  90. package/lib/role-assistant/evidence-sync.js +55 -7
  91. package/lib/role-assistant/knowledge-sync-logging.js +58 -0
  92. package/lib/role-assistant/knowledge-sync.js +88 -93
  93. package/lib/role-assistant/test-cases-bid.js +155 -0
  94. package/lib/role-assistant/test-cases-evaluate.js +9 -1
  95. package/lib/role-assistant/test-cases-honesty.js +24 -10
  96. package/lib/role-assistant/test-cases.js +28 -0
  97. package/lib/role-assistant/test-runner-attachments.js +118 -0
  98. package/lib/role-assistant/test-runner-bid-apply.js +201 -0
  99. package/lib/role-assistant/test-runner-bid-document.js +278 -0
  100. package/lib/role-assistant/test-runner-start-payload.js +96 -0
  101. package/lib/role-assistant/test-runner-workhub-answers.js +249 -20
  102. package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
  103. package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
  104. package/lib/role-assistant/test-runner-workhub.js +152 -107
  105. package/lib/role-assistant/test-runner.js +5 -63
  106. package/lib/role-assistant/test-suite.js +112 -0
  107. package/lib/schema/application-schema.json +56 -6
  108. package/lib/schema/external-datasource.schema.json +103 -17
  109. package/lib/schema/external-system.schema.json +54 -3
  110. package/lib/schema/integration-definition.schema.json +195 -0
  111. package/lib/utils/authentication-shape.js +6 -0
  112. package/lib/utils/compose-generator.js +10 -1
  113. package/lib/utils/compose-traefik-extra-routes.js +107 -0
  114. package/lib/utils/docker-build.js +2 -2
  115. package/lib/utils/help-builder.js +3 -1
  116. package/lib/utils/promote-dev-docker-image.js +102 -18
  117. package/lib/utils/transient-developer-id.js +28 -0
  118. package/package.json +14 -16
  119. package/templates/README.md +12 -1
  120. package/templates/applications/dataplane/application.yaml +10 -2
  121. package/templates/applications/dataplane/env.template +7 -6
  122. package/templates/applications/miso-controller/application.yaml +23 -8
  123. package/templates/applications/miso-controller/env.template +8 -2
  124. package/templates/applications/miso-controller/rbac.yaml +1 -0
  125. package/templates/channels/README.md +11 -1
  126. package/templates/channels/brand/color-192.png +0 -0
  127. package/templates/channels/brand/dark/128.png +0 -0
  128. package/templates/channels/brand/dark/192.png +0 -0
  129. package/templates/channels/brand/dark/256.png +0 -0
  130. package/templates/channels/brand/dark/32.png +0 -0
  131. package/templates/channels/brand/dark/512.png +0 -0
  132. package/templates/channels/brand/dark/64.png +0 -0
  133. package/templates/channels/brand/light/128.png +0 -0
  134. package/templates/channels/brand/light/192.png +0 -0
  135. package/templates/channels/brand/light/256.png +0 -0
  136. package/templates/channels/brand/light/32.png +0 -0
  137. package/templates/channels/brand/light/512.png +0 -0
  138. package/templates/channels/brand/light/64.png +0 -0
  139. package/templates/channels/brand/mono-white/128.png +0 -0
  140. package/templates/channels/brand/mono-white/192.png +0 -0
  141. package/templates/channels/brand/mono-white/256.png +0 -0
  142. package/templates/channels/brand/mono-white/32.png +0 -0
  143. package/templates/channels/brand/mono-white/512.png +0 -0
  144. package/templates/channels/brand/mono-white/64.png +0 -0
  145. package/templates/channels/brand/outline-32.png +0 -0
  146. package/templates/channels/chatgpt/install.template.md.hbs +6 -4
  147. package/templates/channels/chatgpt/integration/README.md +4 -5
  148. package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
  149. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +14 -16
  150. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
  151. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +30 -0
  152. package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
  153. package/templates/channels/microsoft-copilot/install.template.md.hbs +93 -22
  154. package/templates/channels/microsoft-copilot/integration/README.md +2 -3
  155. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +1 -22
  156. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -19
  157. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +15 -0
  158. package/templates/channels/slack/integration/README.md +2 -4
  159. package/templates/channels/teams-bot/install.template.md.hbs +4 -0
  160. package/templates/channels/teams-bot/integration/README.md +3 -5
  161. package/templates/channels/web-embed/integration/web-embed-system.json +1 -16
  162. package/templates/python/docker-compose.hbs +36 -0
  163. package/templates/typescript/docker-compose.hbs +36 -0
  164. package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +0 -374
  165. package/.cursor/process/README.md +0 -9
  166. package/.cursor/rules/anchor-docs.mdc +0 -15
  167. package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
  168. package/.cursor/rules/cli-layout.mdc +0 -81
  169. package/.cursor/rules/cli-product-neutral.mdc +0 -43
  170. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
  171. package/.cursor/rules/docs-rules.mdc +0 -32
  172. package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
  173. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
  174. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
  175. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
  176. package/.cursor/rules/project-rules.mdc +0 -913
  177. package/.cursor/skills/README.md +0 -15
  178. package/.dockerignore +0 -52
  179. package/.eslintignore +0 -22
  180. package/.markdownlint.json +0 -14
  181. package/anchor-docs/README.md +0 -10
  182. package/anchor-docs/_TEMPLATE +0 -24
  183. package/babel.config.js +0 -6
  184. package/bin/builder-api-cleanup.js +0 -26
  185. package/bin/builder-api-nest.js +0 -10
  186. package/bin/builder-api-spike.js +0 -19
  187. package/enterprise-knowledge/README.md +0 -50
  188. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
  189. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
  190. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
  191. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
  192. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
  193. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
  194. package/integration/README.md +0 -81
  195. package/integration/github/README.md +0 -53
  196. package/integration/github/application.json +0 -21
  197. package/integration/github/deploy.js +0 -72
  198. package/integration/github/env.template +0 -11
  199. package/integration/github/github-datasource-issue-comments.json +0 -239
  200. package/integration/github/github-datasource-issues.json +0 -399
  201. package/integration/github/github-datasource-repository.json +0 -354
  202. package/integration/github/github-deploy.json +0 -1202
  203. package/integration/github/github-system.json +0 -82
  204. package/integration/hubspot-test/README.md +0 -159
  205. package/integration/hubspot-test/application.json +0 -54
  206. package/integration/hubspot-test/companies.json +0 -2048
  207. package/integration/hubspot-test/create-hubspot.js +0 -523
  208. package/integration/hubspot-test/env.template +0 -4
  209. package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
  210. package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
  211. package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
  212. package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
  213. package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
  214. package/integration/hubspot-test/hubspot-test-system.json +0 -74
  215. package/integration/hubspot-test/rbac.json +0 -166
  216. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
  217. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
  218. package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
  219. package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
  220. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
  221. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
  222. package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
  223. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
  224. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  225. package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
  226. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
  227. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
  228. package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
  229. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
  230. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  231. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  232. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
  233. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
  234. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
  235. package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
  236. package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
  237. package/integration/hubspot-test/test-dataplane-down.js +0 -209
  238. package/integration/hubspot-test/test.js +0 -1588
  239. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
  240. package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
  241. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
  242. package/integration/roundtrip-test-local/README.md +0 -143
  243. package/integration/roundtrip-test-local/application.yaml +0 -13
  244. package/integration/roundtrip-test-local/env.template +0 -15
  245. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
  246. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
  247. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
  248. package/integration/roundtrip-test-local2/README.md +0 -143
  249. package/integration/roundtrip-test-local2/application.yaml +0 -13
  250. package/integration/roundtrip-test-local2/env.template +0 -15
  251. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
  252. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
  253. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
  254. package/integration/test/wizard.yaml +0 -8
  255. package/jest.config.coverage.js +0 -37
  256. package/jest.config.default.js +0 -11
  257. package/jest.config.integration.fixtures.js +0 -22
  258. package/jest.config.integration.js +0 -33
  259. package/jest.config.isolated.js +0 -11
  260. package/jest.config.manual.js +0 -30
  261. package/jest.global-live-fabrix-hooks.js +0 -36
  262. package/jest.isolated-projects.js +0 -260
  263. package/jest.projects.js +0 -76
  264. package/packages/builder-api/README.md +0 -120
  265. package/packages/builder-api/package.json +0 -30
  266. package/packages/builder-api/src/app.module.ts +0 -7
  267. package/packages/builder-api/src/auth/auth.module.ts +0 -5
  268. package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
  269. package/packages/builder-api/src/main.ts +0 -16
  270. package/packages/builder-api/tsconfig.json +0 -15
  271. package/scripts/check-builder-api-architecture-grep.js +0 -79
  272. package/scripts/check-datasource-test-run-schema-sync.js +0 -34
  273. package/scripts/ci-fix.sh +0 -19
  274. package/scripts/ci-simulate.sh +0 -19
  275. package/scripts/diagnose-cli.js +0 -150
  276. package/scripts/docker_image_content_gate.js +0 -47
  277. package/scripts/docker_image_content_gate.sh +0 -5
  278. package/scripts/export-builder-api-evidence.js +0 -262
  279. package/scripts/install-local.js +0 -490
  280. package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
  281. package/scripts/lib/builder-api-docker-staging-core.js +0 -183
  282. package/scripts/lib/docker-image-content-gate-core.js +0 -166
  283. package/scripts/lib/plan-actor.js +0 -109
  284. package/scripts/lib/plan-config.js +0 -20
  285. package/scripts/lib/plan-gates.js +0 -154
  286. package/scripts/lib/plan-meta.js +0 -104
  287. package/scripts/lib/plan-parse.js +0 -162
  288. package/scripts/lib/plan-prevalidate-gates.js +0 -337
  289. package/scripts/lib/plan-run-core.js +0 -125
  290. package/scripts/lib/plan-run-report.js +0 -119
  291. package/scripts/plan-approve.js +0 -24
  292. package/scripts/plan-archive.js +0 -49
  293. package/scripts/plan-run.js +0 -13
  294. package/scripts/plan-set-actor.js +0 -21
  295. package/scripts/plan-validate.js +0 -80
  296. package/scripts/pnpm/af.mjs +0 -110
  297. package/scripts/pnpm/check-quiet.mjs +0 -32
  298. package/scripts/pnpm/dev-install.mjs +0 -29
  299. package/scripts/pnpm/dev-reload.mjs +0 -18
  300. package/scripts/pnpm/help.mjs +0 -55
  301. package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
  302. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
  303. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
  304. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
  305. package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
  306. package/scripts/pnpm/lib/spinner.mjs +0 -42
  307. package/scripts/pnpm-global-remove.js +0 -48
  308. package/scripts/stage_builder_api_for_docker.js +0 -65
  309. package/scripts/sync-builder-api-template.js +0 -44
  310. package/scripts/test-dataplane-bootstrap.js +0 -331
@@ -1,125 +0,0 @@
1
- /**
2
- * @fileoverview Plan run and archive core (miso / builder).
3
- */
4
-
5
- 'use strict';
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { DONE_DIR, REQUIRE_APPROVAL_TO_ARCHIVE } = require('./plan-config');
10
- const { resolvePlanPath, patchPlanMeta, die } = require('./plan-meta');
11
- const { loadPlanFile } = require('./plan-parse');
12
- const { runAllGates } = require('./plan-gates');
13
- const { buildSummaryMarkdown, writeReport } = require('./plan-run-report');
14
- const { resolveActor } = require('./plan-actor');
15
-
16
- /**
17
- * @param {import('./plan-gates').GateResult[]} gates
18
- */
19
- function gatesPassing(gates) {
20
- return gates.filter((g) => g.status === 'fail').length === 0;
21
- }
22
-
23
- /**
24
- * @param {string} planInput
25
- * @param {{ actorName?: string }} [opts]
26
- */
27
- function runPlan(planInput, opts = {}) {
28
- const planPath = resolvePlanPath(planInput);
29
- const actorInfo = resolveActor(opts.actorName);
30
- const runAt = new Date().toISOString();
31
- const planName = path.basename(planPath, '.plan.md');
32
- console.log(`Validating: ${planName}\n`);
33
-
34
- const result = runAllGates(planPath);
35
-
36
- let overallStatus = 'PASS';
37
- if (!gatesPassing(result.gates)) {
38
- overallStatus = 'FAIL';
39
- } else if (result.gates.some((g) => g.status === 'warn')) {
40
- overallStatus = 'PASS_WITH_WARNINGS';
41
- }
42
- if (result.blockingPending.length) {
43
- overallStatus = 'FAIL';
44
- }
45
-
46
- for (const g of result.gates) {
47
- const prefix =
48
- g.status === 'pass' ? '✔' : g.status === 'warn' ? '⚠' : g.status === 'skip' ? '○' : '✖';
49
- console.log(`${prefix} ${g.label}${g.detail ? ` — ${g.detail}` : ''}`);
50
- }
51
-
52
- const summary = buildSummaryMarkdown({
53
- planPath,
54
- planName,
55
- actor: actorInfo?.displayName,
56
- runAt,
57
- gates: result.gates,
58
- todos: result.todos,
59
- blockingPending: result.blockingPending,
60
- manualPending: result.manualPending,
61
- overallStatus
62
- });
63
- writeReport(summary, planName);
64
-
65
- if (!gatesPassing(result.gates) || result.blockingPending.length) {
66
- process.exit(1);
67
- }
68
-
69
- return { planPath, planName, summary, overallStatus };
70
- }
71
-
72
- /**
73
- * @param {string} planInput
74
- * @param {string} [summary]
75
- * @param {{ allowUnapproved?: boolean }} [opts]
76
- */
77
- function archivePlan(planInput, summary, opts = {}) {
78
- const planPath = resolvePlanPath(planInput);
79
- const planName = path.basename(planPath, '.plan.md');
80
- const loaded = loadPlanFile(planPath);
81
- if (
82
- REQUIRE_APPROVAL_TO_ARCHIVE &&
83
- loaded &&
84
- !loaded.meta.approvedBy &&
85
- !opts.allowUnapproved
86
- ) {
87
- die('Plan not approved — run plan-approve first or use --allow-unapproved');
88
- }
89
-
90
- fs.mkdirSync(DONE_DIR, { recursive: true });
91
- const dest = path.join(DONE_DIR, path.basename(planPath));
92
- if (fs.existsSync(dest)) {
93
- die(`Already archived: ${dest}`);
94
- }
95
- fs.renameSync(planPath, dest);
96
- if (summary) {
97
- fs.writeFileSync(path.join(DONE_DIR, `${planName}.validation.md`), summary, 'utf8');
98
- }
99
- console.log(`✔ Archived → ${dest}`);
100
- return dest;
101
- }
102
-
103
- /**
104
- * @param {string} planInput
105
- * @param {string} [actorOverride]
106
- */
107
- function approvePlan(planInput, actorOverride) {
108
- const planPath = resolvePlanPath(planInput);
109
- const actor = resolveActor(actorOverride);
110
- const name = actor?.displayName || actorOverride;
111
- if (!name) {
112
- die('Set actor first: node scripts/plan-set-actor.js "Your Name"');
113
- }
114
- const today = new Date().toISOString().slice(0, 10);
115
- patchPlanMeta(planPath, 'approvedBy', name);
116
- patchPlanMeta(planPath, 'approvedAt', today);
117
- patchPlanMeta(planPath, 'status', 'approved');
118
- console.log(`✔ Approved ${path.basename(planPath)} by ${name} on ${today}`);
119
- }
120
-
121
- module.exports = {
122
- runPlan,
123
- archivePlan,
124
- approvePlan
125
- };
@@ -1,119 +0,0 @@
1
- /**
2
- * @fileoverview Plan run report writer (shared).
3
- */
4
-
5
- 'use strict';
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { REPORT_DIR } = require('./plan-config');
10
-
11
- /**
12
- * @param {unknown} value
13
- * @returns {string}
14
- */
15
- function escapeMarkdownCell(value) {
16
- return String(value ?? '')
17
- .replace(/\r?\n+/g, ' ')
18
- .replace(/\|/g, '\\|')
19
- .trim();
20
- }
21
-
22
- /**
23
- * @param {object} params
24
- * @returns {string}
25
- */
26
- function buildSummaryMarkdown(params) {
27
- const {
28
- planPath,
29
- planName,
30
- actor,
31
- runAt,
32
- gates,
33
- todos,
34
- blockingPending,
35
- manualPending,
36
- overallStatus
37
- } = params;
38
-
39
- const lines = [
40
- '# Plan validation summary',
41
- '',
42
- '| Field | Value |',
43
- '| --- | --- |',
44
- `| **Plan** | \`${planName}\` |`,
45
- `| **Status** | **${overallStatus}** |`,
46
- `| **Run at** | ${runAt} |`,
47
- `| **Validated by** | ${actor || '_not set_'} |`,
48
- `| **Plan file** | \`${planPath}\` |`,
49
- '',
50
- '## Quality gates',
51
- '',
52
- '| Gate | Result | Detail |',
53
- '| --- | --- | --- |'
54
- ];
55
-
56
- for (const g of gates) {
57
- const icon = g.status === 'pass' ? 'pass' : g.status === 'warn' ? 'warn' : 'FAIL';
58
- lines.push(`| ${escapeMarkdownCell(g.label)} | ${icon} | ${escapeMarkdownCell(g.detail || '')} |`);
59
- }
60
-
61
- lines.push('', '## Todos', '', '| ID | Status | Content |', '| --- | --- | --- |');
62
- for (const t of todos) {
63
- lines.push(
64
- `| ${escapeMarkdownCell(t.id)} | ${escapeMarkdownCell(t.status)} | ${escapeMarkdownCell(t.content).slice(0, 100)} |`
65
- );
66
- }
67
-
68
- if (blockingPending.length) {
69
- lines.push('', '### Blocking', '');
70
- for (const t of blockingPending) {
71
- lines.push(`- **${t.id}**: ${t.content}`);
72
- }
73
- }
74
- if (manualPending.length) {
75
- lines.push('', '### Manual (non-blocking)', '');
76
- for (const t of manualPending) {
77
- lines.push(`- **${t.id}**: ${t.content}`);
78
- }
79
- }
80
-
81
- return `${lines.join('\n')}\n`;
82
- }
83
-
84
- /**
85
- * @param {string} content
86
- * @param {string} planBaseName
87
- */
88
- function writeReport(content, planBaseName) {
89
- fs.mkdirSync(REPORT_DIR, { recursive: true });
90
- const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
91
- fs.writeFileSync(path.join(REPORT_DIR, `${planBaseName}.${stamp}.md`), content, 'utf8');
92
- fs.writeFileSync(path.join(REPORT_DIR, 'LATEST.md'), content, 'utf8');
93
- console.log('Report: temp/plan-validation/LATEST.md');
94
- }
95
-
96
- /**
97
- * @param {string} planBaseName
98
- * @returns {{ summary: string, overallStatus: string } | null}
99
- */
100
- function readLatestReportForPlan(planBaseName) {
101
- const latest = path.join(REPORT_DIR, 'LATEST.md');
102
- if (!fs.existsSync(latest)) {
103
- return null;
104
- }
105
- const summary = fs.readFileSync(latest, 'utf8');
106
- const planMatch = summary.match(/\|\s*\*\*Plan\*\*\s*\|\s*`([^`]+)`\s*\|/);
107
- if (!planMatch || planMatch[1] !== planBaseName) {
108
- return null;
109
- }
110
- const statusMatch = summary.match(/\|\s*\*\*Status\*\*\s*\|\s*\*\*([^*]+)\*\*\s*\|/);
111
- const overallStatus = statusMatch ? statusMatch[1].trim() : '';
112
- return { summary, overallStatus };
113
- }
114
-
115
- module.exports = {
116
- buildSummaryMarkdown,
117
- writeReport,
118
- readLatestReportForPlan
119
- };
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- 'use strict';
4
-
5
- const { resolvePlanPath, patchPlanMeta, die } = require('./lib/plan-meta');
6
- const { resolveActor } = require('./lib/plan-actor');
7
-
8
- const planInput = process.argv[2];
9
- if (!planInput) {
10
- die('Usage: node scripts/plan-approve.js <plan-path-or-id>');
11
- }
12
-
13
- const planPath = resolvePlanPath(planInput);
14
- const actor = resolveActor(process.argv[3]);
15
- const name = actor?.displayName || process.argv[3];
16
- if (!name) {
17
- die('Set actor first via /validate-implementation (plan-set-actor)');
18
- }
19
-
20
- const today = new Date().toISOString().slice(0, 10);
21
- patchPlanMeta(planPath, 'approvedBy', name);
22
- patchPlanMeta(planPath, 'approvedAt', today);
23
- patchPlanMeta(planPath, 'status', 'approved');
24
- console.log(`✔ Approved ${planPath} by ${name} on ${today}`);
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- 'use strict';
4
-
5
- const { runPlan, archivePlan } = require('./lib/plan-run-core');
6
- const { resolvePlanPath } = require('./lib/plan-meta');
7
- const { readLatestReportForPlan } = require('./lib/plan-run-report');
8
- const path = require('path');
9
-
10
- const args = process.argv.slice(2);
11
- const planInput = args.find((a) => !a.startsWith('--'));
12
- const allowUnapproved = args.includes('--allow-unapproved');
13
- const revalidate = args.includes('--revalidate');
14
-
15
- if (!planInput) {
16
- console.error(
17
- 'Usage: node scripts/plan-archive.js <plan-path-or-id> [--allow-unapproved] [--revalidate]'
18
- );
19
- process.exit(1);
20
- }
21
-
22
- const planPath = resolvePlanPath(planInput);
23
- const planName = path.basename(planPath, '.plan.md');
24
-
25
- let summary = '';
26
- let runSummary = '';
27
-
28
- if (!revalidate) {
29
- const cached = readLatestReportForPlan(planName);
30
- if (cached) {
31
- if (cached.overallStatus !== 'PASS' && cached.overallStatus !== 'PASS_WITH_WARNINGS') {
32
- console.error(
33
- `Latest report for ${planName} is ${cached.overallStatus} — run plan-run.js or use --revalidate after fixing`
34
- );
35
- process.exit(1);
36
- }
37
- summary = cached.summary;
38
- console.log('Using cached report: temp/plan-validation/LATEST.md');
39
- }
40
- }
41
-
42
- if (!summary) {
43
- const result = runPlan(planInput);
44
- runSummary = result.summary;
45
- summary = runSummary;
46
- }
47
-
48
- archivePlan(planPath, summary, { allowUnapproved });
49
- console.log(`Plan archived: ${planName}`);
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- 'use strict';
4
-
5
- const { runPlan } = require('./lib/plan-run-core');
6
-
7
- const planInput = process.argv[2];
8
- if (!planInput) {
9
- console.error('Usage: node scripts/plan-run.js <plan-path-or-id>');
10
- process.exit(1);
11
- }
12
-
13
- runPlan(planInput);
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- /**
4
- * Save plan validator display name to ~/.aifabrix/plan-actor.yaml (shared across repos).
5
- *
6
- * @example node scripts/plan-set-actor.js "Your Name"
7
- */
8
-
9
- 'use strict';
10
-
11
- const { saveActor } = require('./lib/plan-actor');
12
-
13
- const name = process.argv.slice(2).join(' ').trim();
14
- if (!name) {
15
- console.error('Usage: node scripts/plan-set-actor.js "Your Name"');
16
- process.exit(1);
17
- }
18
-
19
- const actorPath = saveActor(name);
20
- console.log(`✔ Saved actor: ${name}`);
21
- console.log(` ${actorPath}`);
@@ -1,80 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console, require-jsdoc, valid-jsdoc, max-statements, complexity */
3
- 'use strict';
4
-
5
- const path = require('path');
6
- const { resolvePlanPath, patchPlanMeta, die } = require('./lib/plan-meta');
7
- const { resolveActor } = require('./lib/plan-actor');
8
- const {
9
- runPrevalidateGates,
10
- buildPrevalidateReport,
11
- writePrevalidateReport
12
- } = require('./lib/plan-prevalidate-gates');
13
-
14
- const args = process.argv.slice(2);
15
- const dryRun = args.includes('--dry-run');
16
- const allowNeedsUpdates = args.includes('--allow-needs-updates');
17
- const actorIdx = args.indexOf('--actor');
18
- const actorOverride = actorIdx >= 0 ? args[actorIdx + 1] : undefined;
19
- const planInput = args.find((a, i) => {
20
- if (a.startsWith('--')) {
21
- return false;
22
- }
23
- if (actorIdx >= 0 && (i === actorIdx || i === actorIdx + 1)) {
24
- return false;
25
- }
26
- return true;
27
- });
28
-
29
- if (!planInput) {
30
- die('Usage: node scripts/plan-validate.js <plan-path-or-id> [--dry-run] [--allow-needs-updates] [--actor Name]');
31
- }
32
-
33
- const planPath = resolvePlanPath(planInput);
34
- const actorInfo = resolveActor(actorOverride);
35
- if (!actorInfo && !dryRun) {
36
- die('Set actor first: node scripts/plan-set-actor.js "Your Name" (or pass --actor)');
37
- }
38
-
39
- const result = runPrevalidateGates(planPath, { allowNeedsUpdates });
40
- const planName = path.basename(planPath, '.plan.md');
41
- const runAt = new Date().toISOString();
42
- const actor = actorInfo?.displayName;
43
-
44
- for (const g of result.gates) {
45
- const prefix =
46
- g.status === 'pass' ? '✔' : g.status === 'warn' ? '⚠' : g.status === 'skip' ? '○' : '✖';
47
- console.log(`${prefix} ${g.label}${g.detail ? ` — ${g.detail}` : ''}`);
48
- }
49
-
50
- writePrevalidateReport(
51
- buildPrevalidateReport({
52
- planPath,
53
- planName,
54
- actor,
55
- runAt,
56
- gates: result.gates,
57
- planValidatedStatus: result.planValidatedStatus,
58
- reportStatus: result.reportStatus
59
- }),
60
- planName
61
- );
62
- console.log('Report: temp/plan-prevalidation/LATEST.md');
63
-
64
- const canStamp =
65
- result.planValidatedStatus === 'validated' ||
66
- (allowNeedsUpdates && result.planValidatedStatus === 'needs-updates');
67
-
68
- if (!dryRun && canStamp && actor) {
69
- const today = new Date().toISOString().slice(0, 10);
70
- patchPlanMeta(planPath, 'planValidatedStatus', result.planValidatedStatus);
71
- patchPlanMeta(planPath, 'lastValidatedBy', actor);
72
- patchPlanMeta(planPath, 'lastValidatedAt', today);
73
- console.log(`✔ Stamped ${planName}: ${result.planValidatedStatus} by ${actor} on ${today}`);
74
- } else if (!dryRun && result.planValidatedStatus === 'validated' && !actor) {
75
- die('Cannot stamp validated plan without actor');
76
- }
77
-
78
- if (result.planValidatedStatus !== 'validated') {
79
- process.exit(1);
80
- }
@@ -1,110 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * aifabrix builder passthrough for builder-api (this repo).
4
- * Usage: pnpm run af <subcommand> | npm run af -- <subcommand>
5
- */
6
- import { spawn } from 'node:child_process';
7
- import { resolveAifabrixBin } from './lib/resolve-aifabrix-bin.mjs';
8
-
9
- const AIFABRIX_BIN = resolveAifabrixBin();
10
-
11
- const USAGE = `Usage: pnpm run af <subcommand>
12
-
13
- Subcommands:
14
- ba-resolve aifabrix resolve builder-api
15
- ba-run aifabrix run builder-api
16
- ba-reload aifabrix run builder-api --reload
17
- ba-logs aifabrix logs builder-api
18
- ba-down aifabrix down-app builder-api
19
- ba-build aifabrix build builder-api
20
- dev-build ba-build then ba-run (local Docker image)
21
- dev-reload Docker live reload (spinner + URL + .temp/dev-reload.log)
22
- dev-promote build --base --from-dev + run --base (global image; TAG=1.9.5 pnpm run dev-promote)
23
- `;
24
-
25
- const COMMANDS = {
26
- 'ba-resolve': [AIFABRIX_BIN, 'resolve', 'builder-api'],
27
- 'ba-run': [AIFABRIX_BIN, 'run', 'builder-api'],
28
- 'ba-reload': [AIFABRIX_BIN, 'run', 'builder-api', '--reload'],
29
- 'ba-logs': [AIFABRIX_BIN, 'logs', 'builder-api'],
30
- 'ba-down': [AIFABRIX_BIN, 'down-app', 'builder-api'],
31
- 'ba-build': [AIFABRIX_BIN, 'build', 'builder-api']
32
- };
33
-
34
- async function runDevBuild() {
35
- await runCommand(COMMANDS['ba-build']);
36
- await runCommand(COMMANDS['ba-run']);
37
- }
38
-
39
- function resolvePromoteTag() {
40
- const fromArg = process.argv[3];
41
- const tag = (process.env.TAG || fromArg || '').trim();
42
- if (!tag || tag === 'latest') {
43
- return null;
44
- }
45
- return tag;
46
- }
47
-
48
- async function runDevPromote() {
49
- const tag = resolvePromoteTag();
50
- if (tag) {
51
- await runCommand([AIFABRIX_BIN, 'build', 'builder-api', '--base', '--from-dev', '--tag', tag]);
52
- await runCommand([AIFABRIX_BIN, 'run', 'builder-api', '--base', '--tag', tag]);
53
- return;
54
- }
55
- await runCommand([AIFABRIX_BIN, 'build', 'builder-api', '--base', '--from-dev']);
56
- await runCommand([AIFABRIX_BIN, 'run', 'builder-api', '--base']);
57
- }
58
-
59
- function runCommand(args) {
60
- return new Promise((resolve, reject) => {
61
- const child = spawn(args[0], args.slice(1), { stdio: 'inherit', shell: false });
62
- child.on('error', reject);
63
- child.on('close', (code) => {
64
- if (code === 0) {
65
- resolve();
66
- return;
67
- }
68
- reject(new Error(`${args.join(' ')} exited with code ${code}`));
69
- });
70
- });
71
- }
72
-
73
- async function main() {
74
- const sub = process.argv[2];
75
- if (!sub || sub === '--help' || sub === '-h') {
76
- console.error(USAGE);
77
- process.exit(sub ? 0 : 1);
78
- }
79
- if (sub === 'dev-build') {
80
- await runDevBuild();
81
- return;
82
- }
83
- if (sub === 'dev-reload') {
84
- const { runDevReload } = await import('./lib/dev-reload-core.mjs');
85
- await runDevReload({
86
- appKey: 'builder-api',
87
- displayName: 'Builder API',
88
- portBase: 3005,
89
- healthPath: '/api/v1/builder/health',
90
- apiOnly: true
91
- });
92
- return;
93
- }
94
- if (sub === 'dev-promote') {
95
- await runDevPromote();
96
- return;
97
- }
98
- const args = COMMANDS[sub];
99
- if (!args) {
100
- console.error(`Unknown af subcommand: ${sub}\n`);
101
- console.error(USAGE);
102
- process.exit(2);
103
- }
104
- await runCommand(args);
105
- }
106
-
107
- main().catch((err) => {
108
- console.error(err.message || err);
109
- process.exit(1);
110
- });
@@ -1,32 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Offline pre-commit gate — same as build:ci; logs in .temp/validation/
4
- */
5
- import { spawnSync } from 'node:child_process';
6
- import fs from 'node:fs';
7
- import path from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
-
10
- const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
11
- const logDir = path.join(repoRoot, '.temp', 'validation');
12
- const logFile = path.join(logDir, 'build-ci.log');
13
-
14
- fs.mkdirSync(logDir, { recursive: true });
15
- console.log(`[check-quiet] Running build:ci (logs → ${logFile})`);
16
-
17
- const result = spawnSync('npm', ['run', 'build:ci'], {
18
- cwd: repoRoot,
19
- env: process.env,
20
- encoding: 'utf8'
21
- });
22
-
23
- const output = `${result.stdout || ''}${result.stderr || ''}`;
24
- fs.writeFileSync(logFile, output, 'utf8');
25
-
26
- if (result.status === 0) {
27
- console.log('[check-quiet] ✓ passed');
28
- process.exit(0);
29
- }
30
-
31
- console.error(`[check-quiet] ✗ failed — see ${logFile}`);
32
- process.exit(result.status ?? 1);
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Bootstrap builder repo deps and link local aifabrix CLI from bin/aifabrix.js.
4
- */
5
- import { spawnSync } from 'node:child_process';
6
- import path from 'node:path';
7
- import { fileURLToPath } from 'node:url';
8
-
9
- const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
10
-
11
- /**
12
- * @param {string} label
13
- * @param {string} command
14
- * @param {string[]} args
15
- */
16
- function runStep(label, command, args) {
17
- console.log(`[dev-install] ${label}`);
18
- const result = spawnSync(command, args, {
19
- cwd: repoRoot,
20
- stdio: 'inherit',
21
- env: process.env
22
- });
23
- if (result.status !== 0) {
24
- process.exit(result.status ?? 1);
25
- }
26
- }
27
-
28
- runStep('npm install', 'npm', ['install']);
29
- runStep('link local CLI (install:local)', 'npm', ['run', 'install:local']);
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Docker live reload for builder-api — quiet console, logs in .temp/dev-reload.log
4
- *
5
- * Equivalent to: aifabrix resolve builder-api && aifabrix run builder-api --reload
6
- */
7
- import { runDevReload } from './lib/dev-reload-core.mjs';
8
-
9
- runDevReload({
10
- appKey: 'builder-api',
11
- displayName: 'Builder API',
12
- portBase: 3005,
13
- healthPath: '/api/v1/builder/health',
14
- apiOnly: true
15
- }).catch((err) => {
16
- console.error(`[dev-reload] ${err.message || err}`);
17
- process.exit(1);
18
- });
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env node
2
- const showAll = process.argv.includes('--all');
3
-
4
- const publicSections = [
5
- {
6
- title: 'Start here (80/20)',
7
- lines: [
8
- 'aifabrix setup → once (any directory)',
9
- 'dev-install → after clone (npm install + install:local)',
10
- 'dev-reload → daily (Docker live reload)',
11
- 'check-quiet → before commit (build:ci → .temp/validation/)',
12
- 'Full guide: QUICK-START.md'
13
- ]
14
- },
15
- {
16
- title: 'Sometimes',
17
- lines: [
18
- 'dev → builder-api on host (aifabrix resolve builder-api first)',
19
- 'ui-build → N/A (no UI in this repo)',
20
- 'check → lint + test (fast, not full CI)',
21
- 'pnpm run af ba-logs | ba-down'
22
- ]
23
- }
24
- ];
25
-
26
- const advancedLines = [
27
- '--- Advanced (help -- --all) ---',
28
- 'dev-build / dev-promote / af ba-*',
29
- 'build:ci → lint + schema-sync + flags + test:ci (same as GitHub)',
30
- 'sync-json → publish builder/builder-api → templates/',
31
- 'test:154 → builder-api scoped Jest + arch grep',
32
- 'test:manual → live API tests (aifabrix login first)',
33
- 'test:integration → integration fixtures (TEST_LANGUAGE=python|typescript optional)',
34
- 'test:hubspot-wizard [-- --type negative|positive]',
35
- 'docker-image-gate-builder-api',
36
- 'builder-api:build | builder-api:nest | builder-api:cleanup',
37
- 'install:global / uninstall:global / diagnose:cli',
38
- 'Docs: docs/development/pnpm-commands.md'
39
- ];
40
-
41
- console.log('AI Fabrix Builder — pnpm commands\n');
42
- for (const section of publicSections) {
43
- console.log(section.title);
44
- for (const line of section.lines) {
45
- console.log(` ${line}`);
46
- }
47
- console.log('');
48
- }
49
- if (!showAll) {
50
- console.log('Run: pnpm run help -- --all');
51
- process.exit(0);
52
- }
53
- for (const line of advancedLines) {
54
- console.log(line);
55
- }