@aifabrix/builder 2.49.2 → 2.50.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 (409) hide show
  1. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +49 -0
  2. package/.cursor/rules/plan-rules/application-lifecycle.mdc +30 -0
  3. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +35 -0
  4. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +31 -0
  5. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +34 -0
  6. package/.cursor/skills/README.md +1 -0
  7. package/.dockerignore +52 -0
  8. package/.eslintignore +22 -0
  9. package/README.md +2 -0
  10. package/bin/builder-api-cleanup.js +26 -0
  11. package/bin/builder-api-nest.js +10 -0
  12. package/bin/builder-api-spike.js +19 -0
  13. package/enterprise-knowledge/README.md +50 -0
  14. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +22 -0
  15. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +15 -0
  16. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +69 -0
  17. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +52 -0
  18. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +29 -0
  19. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +2 -0
  20. package/integration/README.md +81 -0
  21. package/integration/github/README.md +53 -0
  22. package/integration/github/application.json +21 -0
  23. package/integration/github/deploy.js +72 -0
  24. package/integration/github/env.template +11 -0
  25. package/integration/github/github-datasource-issue-comments.json +239 -0
  26. package/integration/github/github-datasource-issues.json +399 -0
  27. package/integration/github/github-datasource-repository.json +354 -0
  28. package/integration/github/github-deploy.json +1202 -0
  29. package/integration/github/github-system.json +82 -0
  30. package/integration/hubspot-test/README.md +1 -1
  31. package/jest.isolated-projects.js +31 -1
  32. package/jest.projects.js +87 -1
  33. package/lib/api/dev-server-https.js +1 -1
  34. package/lib/api/enterprise-knowledge.api.js +63 -0
  35. package/lib/api/evidence.api.js +172 -0
  36. package/lib/api/external-systems.api.js +8 -2
  37. package/lib/api/resource-types.api.js +1 -0
  38. package/lib/api/types/enterprise-knowledge.types.js +46 -0
  39. package/lib/api/types/evidence.types.js +67 -0
  40. package/lib/api/types/resource-types.types.js +2 -0
  41. package/lib/app/controller-application-filter.js +36 -0
  42. package/lib/app/deploy.js +1 -1
  43. package/lib/app/list-external-systems.js +130 -0
  44. package/lib/app/list.js +20 -8
  45. package/lib/app/run.js +3 -1
  46. package/lib/app/show-display.js +8 -3
  47. package/lib/app/show-online.js +178 -0
  48. package/lib/app/show.js +37 -88
  49. package/lib/build/builder-api-docker-staging.js +47 -0
  50. package/lib/build/miso-controller-npm-sdk-guard.js +2 -2
  51. package/lib/build/standard-docker-build.js +2 -0
  52. package/lib/certification/post-unified-cert-sync.js +4 -31
  53. package/lib/certification/sync-after-external-command.js +0 -1
  54. package/lib/certification/sync-system-certification.js +0 -3
  55. package/lib/channels/add-channel.js +40 -34
  56. package/lib/channels/approval-guides/chatgpt.js +33 -0
  57. package/lib/channels/approval-guides/credential-portal.js +38 -0
  58. package/lib/channels/approval-guides/index.js +110 -0
  59. package/lib/channels/approval-guides/microsoft-copilot.js +34 -0
  60. package/lib/channels/approval-guides/slack.js +34 -0
  61. package/lib/channels/approval-guides/teams-bot.js +35 -0
  62. package/lib/channels/approval-guides/web-embed.js +32 -0
  63. package/lib/channels/channel-approval-guide.js +11 -0
  64. package/lib/channels/channel-artifact-generator.js +16 -4
  65. package/lib/channels/channel-audit.js +3 -0
  66. package/lib/channels/channel-auth-context.js +1 -1
  67. package/lib/channels/channel-description.js +59 -0
  68. package/lib/channels/channel-integration-generator.js +13 -230
  69. package/lib/channels/channel-integration-template.js +94 -0
  70. package/lib/channels/channel-runtime-resolver.js +43 -3
  71. package/lib/channels/channel-status-display.js +66 -26
  72. package/lib/channels/channel-targets.js +3 -3
  73. package/lib/cli/index.js +27 -3
  74. package/lib/cli/infra-guided.js +5 -1
  75. package/lib/cli/setup-app-external-create.js +111 -0
  76. package/lib/cli/setup-app.help.js +1 -1
  77. package/lib/cli/setup-app.js +38 -125
  78. package/lib/cli/setup-app.test-commands.js +26 -52
  79. package/lib/cli/setup-certification-commands.js +4 -4
  80. package/lib/cli/setup-certification.help.js +9 -9
  81. package/lib/cli/setup-dev.js +7 -2
  82. package/lib/cli/setup-external-system-help.js +4 -6
  83. package/lib/cli/setup-external-system.js +58 -52
  84. package/lib/cli/setup-infra-up-builder-api-action.js +64 -0
  85. package/lib/cli/setup-infra-up-platform-action.js +3 -1
  86. package/lib/cli/setup-infra.js +15 -0
  87. package/lib/cli/setup-list.js +43 -0
  88. package/lib/cli/setup-utility-repair.js +26 -7
  89. package/lib/cli/setup-utility.js +5 -3
  90. package/lib/commands/app.js +15 -43
  91. package/lib/commands/channel-add-setup.js +110 -0
  92. package/lib/commands/channel.js +42 -8
  93. package/lib/commands/datasource-sync-display.js +96 -0
  94. package/lib/commands/datasource-sync-policy.js +210 -0
  95. package/lib/commands/datasource-test-trust-cli.js +6 -6
  96. package/lib/commands/datasource-unified-test-cli.js +2 -1
  97. package/lib/commands/datasource-unified-test-cli.options.js +33 -23
  98. package/lib/commands/deploy-gate-failure-details.js +163 -0
  99. package/lib/commands/deploy-gate-orchestrator.js +322 -0
  100. package/lib/commands/dev-cli-handlers.js +1 -59
  101. package/lib/commands/dev-host-ops-params.js +91 -0
  102. package/lib/commands/dev-host-ops-poll.js +111 -0
  103. package/lib/commands/dev-host-ops.js +107 -94
  104. package/lib/commands/dev-init.js +3 -1
  105. package/lib/commands/enterprise-knowledge.js +284 -0
  106. package/lib/commands/evidence-cli-leaves.js +250 -0
  107. package/lib/commands/evidence.js +51 -0
  108. package/lib/commands/governance-cli-shared.js +2 -2
  109. package/lib/commands/governance-command-action.js +2 -2
  110. package/lib/commands/governance-fixture-subjects.js +85 -0
  111. package/lib/commands/governance.js +1 -1
  112. package/lib/commands/lifecycle-command-action.js +2 -2
  113. package/lib/commands/lifecycle-external.js +3 -3
  114. package/lib/commands/manifest-cli-auth.js +29 -0
  115. package/lib/commands/manifest-cli-commands.js +170 -0
  116. package/lib/commands/manifest-cli-integration-path.js +63 -0
  117. package/lib/commands/manifest.js +21 -0
  118. package/lib/commands/protection-cli-leaves.js +3 -3
  119. package/lib/commands/repair-auth-apply.js +15 -1
  120. package/lib/commands/repair-authentications-454.js +169 -0
  121. package/lib/commands/repair-capability-openapi-warnings.js +126 -0
  122. package/lib/commands/repair-datasource-apply.js +135 -0
  123. package/lib/commands/repair-datasource-auto-rbac.js +62 -1
  124. package/lib/commands/repair-datasource-http-service-contract.js +239 -0
  125. package/lib/commands/repair-datasource-operation-security.js +180 -0
  126. package/lib/commands/repair-datasource-run.js +7 -2
  127. package/lib/commands/repair-datasource-sync-operations.js +177 -0
  128. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +133 -0
  129. package/lib/commands/repair-datasource.js +12 -68
  130. package/lib/commands/repair-env-template.js +11 -1
  131. package/lib/commands/repair-external-run.js +121 -31
  132. package/lib/commands/repair-internal.js +1 -1
  133. package/lib/commands/repair-openapi-export.js +156 -0
  134. package/lib/commands/repair-openapi-sync.js +19 -2
  135. package/lib/commands/repair-orchestration-datasource-split.js +259 -0
  136. package/lib/commands/repair-persist.js +22 -1
  137. package/lib/commands/repair-rbac-platform-preset.js +204 -0
  138. package/lib/commands/repair-rbac-reader-roles.js +191 -0
  139. package/lib/commands/repair-rbac.js +163 -86
  140. package/lib/commands/repair-steps.js +83 -18
  141. package/lib/commands/repair-system-permissions.js +1 -0
  142. package/lib/commands/repair.js +1 -1
  143. package/lib/commands/resource-type.js +65 -26
  144. package/lib/commands/run-post-publish-data-sync.js +68 -0
  145. package/lib/commands/setup-modes.js +1 -1
  146. package/lib/commands/test-e2e-external.js +21 -8
  147. package/lib/commands/test-governance-cli-options.js +2 -2
  148. package/lib/commands/test-trust-cli-options.js +2 -2
  149. package/lib/commands/up-builder-api-bootstrap.js +71 -0
  150. package/lib/commands/up-builder-api-provision.js +241 -0
  151. package/lib/commands/up-builder-api.js +88 -0
  152. package/lib/commands/up-common.js +25 -1
  153. package/lib/commands/upload-credential-push-log.js +117 -0
  154. package/lib/commands/upload-data-sync-finalize.js +60 -0
  155. package/lib/commands/upload-probe.js +66 -0
  156. package/lib/commands/upload-publish-context.js +4 -1
  157. package/lib/commands/upload-sidecar-followups.js +55 -27
  158. package/lib/commands/upload.js +116 -157
  159. package/lib/commands/verify-governance-combined-external.js +1 -1
  160. package/lib/commands/verify-governance-db.js +2 -2
  161. package/lib/commands/verify-operations-command-action.js +2 -2
  162. package/lib/commands/verify-operations-step-plan.js +2 -2
  163. package/lib/commands/verify-operations-steps.js +2 -2
  164. package/lib/commands/verify-trust-command-action.js +1 -1
  165. package/lib/commands/wizard-core.js +1 -1
  166. package/lib/commands/wizard-headless.js +2 -1
  167. package/lib/core/admin-secrets.js +2 -6
  168. package/lib/core/secrets-env-content.js +10 -4
  169. package/lib/core/secrets-env-write.js +2 -13
  170. package/lib/datasource/agent-trust-run.js +3 -3
  171. package/lib/datasource/deploy.js +3 -1
  172. package/lib/datasource/test-e2e.js +6 -1
  173. package/lib/datasource/unified-validation-run-body.js +4 -1
  174. package/lib/datasource/unified-validation-run.js +1 -1
  175. package/lib/deployment/deploy-poll-ui.js +73 -12
  176. package/lib/deployment/deployer-poll-run.js +113 -0
  177. package/lib/deployment/deployer.js +17 -87
  178. package/lib/evidence/dataplane-context.js +21 -0
  179. package/lib/evidence/evidence-display.js +78 -0
  180. package/lib/evidence/evidence-service.js +392 -0
  181. package/lib/external-system/deploy.js +290 -112
  182. package/lib/external-system/download.js +7 -3
  183. package/lib/external-system/test-execution.js +1 -1
  184. package/lib/external-system/test-system-level.js +8 -10
  185. package/lib/external-system/test.js +12 -6
  186. package/lib/generator/deploy-script.js +73 -0
  187. package/lib/generator/external.js +2 -1
  188. package/lib/generator/index.js +17 -2
  189. package/lib/generator/wizard.js +3 -36
  190. package/lib/internal/fs-real-sync.js +22 -1
  191. package/lib/internal/node-fs.js +2 -0
  192. package/lib/lifecycle/lifecycle-governance-options.js +1 -1
  193. package/lib/lifecycle/verify-step-progress.js +1 -1
  194. package/lib/programmatic/access-log.js +26 -0
  195. package/lib/programmatic/auth-config.js +44 -0
  196. package/lib/programmatic/bearer-auth.js +176 -0
  197. package/lib/programmatic/builder-api-request.js +175 -0
  198. package/lib/programmatic/builder-api-route-dispatch.js +82 -0
  199. package/lib/programmatic/builder-api-runtime-config.js +42 -0
  200. package/lib/programmatic/builder-api-server.js +230 -0
  201. package/lib/programmatic/builder-help-authentication-catalog.js +282 -0
  202. package/lib/programmatic/builder-help-connected-system-ui.js +266 -0
  203. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +60 -0
  204. package/lib/programmatic/builder-help-envelope.js +36 -0
  205. package/lib/programmatic/builder-help-fixtures.js +200 -0
  206. package/lib/programmatic/builder-help-governance.js +172 -0
  207. package/lib/programmatic/builder-help-schema-catalog.js +92 -0
  208. package/lib/programmatic/builder-help.js +361 -0
  209. package/lib/programmatic/capability-registry.js +77 -0
  210. package/lib/programmatic/command-options.js +32 -0
  211. package/lib/programmatic/enterprise-mcp-client.js +98 -0
  212. package/lib/programmatic/http-problem-details.js +99 -0
  213. package/lib/programmatic/http-route-match.js +40 -0
  214. package/lib/programmatic/idempotency-cache.js +69 -0
  215. package/lib/programmatic/index.js +53 -0
  216. package/lib/programmatic/integration-path-scope.js +39 -0
  217. package/lib/programmatic/log-redaction.js +66 -0
  218. package/lib/programmatic/manifest-get-section.js +146 -0
  219. package/lib/programmatic/manifest-patch-section.js +252 -0
  220. package/lib/programmatic/manifest-repair.js +122 -0
  221. package/lib/programmatic/manifest-section-dependency-graph.js +160 -0
  222. package/lib/programmatic/manifest-section-io.js +225 -0
  223. package/lib/programmatic/manifest-section-quality.js +171 -0
  224. package/lib/programmatic/manifest-section-registry-data.js +269 -0
  225. package/lib/programmatic/manifest-section-registry.js +205 -0
  226. package/lib/programmatic/nest-http-bridge.js +34 -0
  227. package/lib/programmatic/openapi-component-schemas.js +68 -0
  228. package/lib/programmatic/openapi-description-enricher.js +117 -0
  229. package/lib/programmatic/openapi-descriptions.js +190 -0
  230. package/lib/programmatic/openapi-docs-serving.js +123 -0
  231. package/lib/programmatic/openapi-help-schemas.js +63 -0
  232. package/lib/programmatic/openapi-manifest-schemas.js +141 -0
  233. package/lib/programmatic/openapi-operation-bindings.js +274 -0
  234. package/lib/programmatic/openapi-request-schemas.js +155 -0
  235. package/lib/programmatic/openapi-result-schemas.js +476 -0
  236. package/lib/programmatic/openapi-schema-descriptions-certify.js +139 -0
  237. package/lib/programmatic/openapi-schema-descriptions-core.js +159 -0
  238. package/lib/programmatic/openapi-schema-descriptions-help.js +40 -0
  239. package/lib/programmatic/openapi-schema-descriptions-manifest.js +143 -0
  240. package/lib/programmatic/openapi-schema-descriptions-mcp.js +118 -0
  241. package/lib/programmatic/openapi-schema-descriptions-operations.js +281 -0
  242. package/lib/programmatic/openapi-schema-helpers.js +93 -0
  243. package/lib/programmatic/openapi-spec.js +203 -0
  244. package/lib/programmatic/orchestration-openapi-meta.js +159 -0
  245. package/lib/programmatic/platform-rbac-catalog.js +90 -0
  246. package/lib/programmatic/request-timeout.js +53 -0
  247. package/lib/programmatic/route-handler-map.js +143 -0
  248. package/lib/programmatic/route-handlers-context.js +29 -0
  249. package/lib/programmatic/route-handlers.js +33 -0
  250. package/lib/programmatic/run-certify.js +57 -0
  251. package/lib/programmatic/run-enterprise-mcp.js +32 -0
  252. package/lib/programmatic/run-lifecycle.js +29 -0
  253. package/lib/programmatic/run-repair.js +41 -0
  254. package/lib/programmatic/run-repository-emcp.js +54 -0
  255. package/lib/programmatic/run-template-workspace.js +61 -0
  256. package/lib/programmatic/run-test.js +49 -0
  257. package/lib/programmatic/run-upload.js +63 -0
  258. package/lib/programmatic/run-validate.js +53 -0
  259. package/lib/programmatic/run-wizard.js +40 -0
  260. package/lib/programmatic/system-key.js +48 -0
  261. package/lib/programmatic/wizard-config-normalize.js +118 -0
  262. package/lib/programmatic/workspace-cleanup.js +128 -0
  263. package/lib/programmatic/workspace-context.js +145 -0
  264. package/lib/programmatic/workspace-lock.js +75 -0
  265. package/lib/programmatic/workspace-meta.js +64 -0
  266. package/lib/programmatic/workspace-ops.js +149 -0
  267. package/lib/protection/run-commands-upload-sync.js +35 -0
  268. package/lib/protection/run-commands.js +2 -20
  269. package/lib/protection/upload-batch.js +11 -7
  270. package/lib/resolvers/resource-type-file.js +22 -0
  271. package/lib/schema/external-datasource.schema.json +161 -1
  272. package/lib/schema/external-system.schema.json +244 -118
  273. package/lib/schema/flag-map-validation-run.json +3 -0
  274. package/lib/schema/type/credential-field-registry.json +2 -2
  275. package/lib/schema/type/document-storage.json +9 -0
  276. package/lib/utils/agent-trust-run-display.js +1 -1
  277. package/lib/utils/app-path-resolve.js +168 -0
  278. package/lib/utils/authentication-env-template.js +222 -0
  279. package/lib/utils/cli-sync-options.js +7 -11
  280. package/lib/utils/cli-utils.js +4 -0
  281. package/lib/utils/cli-workspace-options.js +29 -0
  282. package/lib/utils/compose-generate-docker-compose.js +102 -0
  283. package/lib/utils/configuration-env-resolver.js +203 -27
  284. package/lib/utils/datasource-test-run-certificate-tty.js +28 -2
  285. package/lib/utils/datasource-test-run-certification-debug.js +130 -0
  286. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  287. package/lib/utils/datasource-test-run-debug-slice.js +7 -0
  288. package/lib/utils/datasource-test-run-display.js +2 -1
  289. package/lib/utils/dev-init-ssh-merge.js +165 -23
  290. package/lib/utils/dev-pin-share-instructions.js +110 -0
  291. package/lib/utils/dev-ssh-config-helper.js +177 -33
  292. package/lib/utils/enterprise-knowledge-paths.js +142 -0
  293. package/lib/utils/env-copy.js +2 -1
  294. package/lib/utils/env-dotenv-format.js +103 -0
  295. package/lib/utils/external-env-template.js +4 -1
  296. package/lib/utils/external-system-display.js +5 -1
  297. package/lib/utils/external-system-readiness-compact-blocks.js +221 -0
  298. package/lib/utils/external-system-readiness-compact-display.js +324 -0
  299. package/lib/utils/external-system-readiness-core.js +16 -0
  300. package/lib/utils/external-system-readiness-deploy-display.js +29 -11
  301. package/lib/utils/external-system-readiness-display-internals.js +3 -1
  302. package/lib/utils/external-system-readiness-display.js +20 -30
  303. package/lib/utils/external-system-system-test-tty-certification.js +135 -0
  304. package/lib/utils/external-system-system-test-tty.js +5 -41
  305. package/lib/utils/help-builder.js +6 -1
  306. package/lib/utils/host-ops-job-labels.js +236 -0
  307. package/lib/utils/host-ops-job-result.js +61 -0
  308. package/lib/utils/host-ops-poll-ui.js +163 -0
  309. package/lib/utils/integration-path-resolve.js +112 -0
  310. package/lib/utils/paths-reload-source.js +148 -0
  311. package/lib/utils/paths-system-builder-keys.js +25 -0
  312. package/lib/utils/paths.js +151 -26
  313. package/lib/utils/runtime-configuration-values.js +64 -2
  314. package/lib/utils/secrets-helpers.js +5 -1
  315. package/lib/utils/ssh-known-hosts.js +130 -0
  316. package/lib/utils/test-target-cli-options.js +75 -0
  317. package/lib/utils/upload-sync-options.js +4 -0
  318. package/lib/utils/validation-run-request.js +11 -2
  319. package/lib/validation/external-manifest-validator.js +11 -1
  320. package/lib/validation/openapi-contract-surface-validator.js +426 -0
  321. package/lib/validation/openapi-contract-vendor-validation.js +238 -0
  322. package/lib/validation/validate-external-file.js +160 -0
  323. package/lib/validation/validate.js +6 -117
  324. package/package.json +46 -29
  325. package/packages/builder-api/README.md +120 -0
  326. package/packages/builder-api/package.json +30 -0
  327. package/packages/builder-api/src/app.module.ts +7 -0
  328. package/packages/builder-api/src/auth/auth.module.ts +5 -0
  329. package/packages/builder-api/src/external-system/external-system.module.ts +5 -0
  330. package/packages/builder-api/src/main.ts +16 -0
  331. package/packages/builder-api/tsconfig.json +15 -0
  332. package/scripts/check-builder-api-architecture-grep.js +79 -0
  333. package/scripts/docker_image_content_gate.js +47 -0
  334. package/scripts/docker_image_content_gate.sh +5 -0
  335. package/scripts/export-builder-api-evidence.js +262 -0
  336. package/scripts/lib/builder-api-docker-staging-copy.js +60 -0
  337. package/scripts/lib/builder-api-docker-staging-core.js +183 -0
  338. package/scripts/lib/docker-image-content-gate-core.js +166 -0
  339. package/scripts/lib/plan-actor.js +109 -0
  340. package/scripts/lib/plan-config.js +20 -0
  341. package/scripts/lib/plan-gates.js +154 -0
  342. package/scripts/lib/plan-meta.js +104 -0
  343. package/scripts/lib/plan-parse.js +162 -0
  344. package/scripts/lib/plan-prevalidate-gates.js +326 -0
  345. package/scripts/lib/plan-run-core.js +125 -0
  346. package/scripts/lib/plan-run-report.js +108 -0
  347. package/scripts/plan-approve.js +24 -0
  348. package/scripts/plan-archive.js +49 -0
  349. package/scripts/plan-run.js +13 -0
  350. package/scripts/plan-set-actor.js +21 -0
  351. package/scripts/plan-validate.js +80 -0
  352. package/scripts/pnpm/af.mjs +110 -0
  353. package/scripts/pnpm/check-quiet.mjs +32 -0
  354. package/scripts/pnpm/dev-install.mjs +29 -0
  355. package/scripts/pnpm/dev-reload.mjs +18 -0
  356. package/scripts/pnpm/help.mjs +55 -0
  357. package/scripts/pnpm/lib/dev-reload-core.mjs +189 -0
  358. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +67 -0
  359. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +32 -0
  360. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +124 -0
  361. package/scripts/pnpm/lib/resolve-app-url.mjs +183 -0
  362. package/scripts/pnpm/lib/spinner.mjs +42 -0
  363. package/scripts/stage_builder_api_for_docker.js +65 -0
  364. package/scripts/sync-builder-api-template.js +44 -0
  365. package/templates/README.md +3 -0
  366. package/templates/applications/builder-api/Dockerfile +38 -0
  367. package/templates/applications/builder-api/application.yaml +75 -0
  368. package/templates/applications/builder-api/env.template +48 -0
  369. package/templates/applications/dataplane/application.yaml +1 -1
  370. package/templates/applications/dataplane/env.template +10 -6
  371. package/templates/applications/dataplane/rbac.yaml +21 -1
  372. package/templates/applications/miso-controller/application.yaml +1 -1
  373. package/templates/applications/miso-controller/env.template +1 -3
  374. package/templates/channels/README.md +18 -0
  375. package/templates/channels/ai-fabrix-icon.jpg +0 -0
  376. package/templates/channels/chatgpt/install.template.md.hbs +21 -24
  377. package/templates/channels/chatgpt/integration/README.md +11 -0
  378. package/templates/channels/chatgpt/integration/application.json +15 -0
  379. package/templates/channels/chatgpt/integration/chatgpt-system.json +29 -0
  380. package/templates/channels/chatgpt/integration/env.template +4 -0
  381. package/templates/channels/microsoft-copilot/install.template.md.hbs +20 -25
  382. package/templates/channels/microsoft-copilot/integration/README.md +11 -0
  383. package/templates/channels/microsoft-copilot/integration/application.json +15 -0
  384. package/templates/channels/microsoft-copilot/integration/env.template +6 -0
  385. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +34 -0
  386. package/templates/channels/slack/install.template.md.hbs +48 -18
  387. package/templates/channels/slack/integration/README.md +38 -0
  388. package/templates/channels/slack/integration/application.json +18 -0
  389. package/templates/channels/slack/integration/env.template +29 -0
  390. package/templates/channels/slack/integration/slack-datasource-conversations.json +226 -0
  391. package/templates/channels/slack/integration/slack-datasource-messages.json +269 -0
  392. package/templates/channels/slack/integration/slack-system.json +86 -0
  393. package/templates/channels/slack/manifest.template.json.hbs +20 -10
  394. package/templates/channels/teams-bot/install.template.md.hbs +31 -17
  395. package/templates/channels/teams-bot/integration/README.md +18 -0
  396. package/templates/channels/teams-bot/integration/application.json +17 -0
  397. package/templates/channels/teams-bot/integration/env.template +5 -0
  398. package/templates/channels/teams-bot/integration/teams-bot-system.json +55 -0
  399. package/templates/channels/teams-bot/manifest.template.json.hbs +27 -0
  400. package/templates/channels/web-embed/install.template.md.hbs +16 -26
  401. package/templates/channels/web-embed/integration/README.md +11 -0
  402. package/templates/channels/web-embed/integration/application.json +15 -0
  403. package/templates/channels/web-embed/integration/env.template +4 -0
  404. package/templates/channels/web-embed/integration/web-embed-system.json +29 -0
  405. package/templates/openapi/redoc_page.html +86 -0
  406. package/templates/python/docker-compose.hbs +11 -0
  407. package/templates/python/requirements.txt +1 -1
  408. package/templates/typescript/docker-compose.hbs +11 -0
  409. package/lib/certification/cli-cert-sync-skip.js +0 -21
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Runtime file discovery for builder-api Docker staging (plan 154.3).
3
+ *
4
+ * @fileoverview Require-graph walk + supplemental runtime assets
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+
14
+ const REQUIRE_RE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
15
+
16
+ /** @type {readonly string[]} */
17
+ const ENTRY_FILES = ['bin/builder-api-spike.js', 'bin/builder-api-cleanup.js'];
18
+
19
+ /** @type {readonly string[]} */
20
+ const STAGING_SKIP_FILES = ['package.json', 'package-lock.json'];
21
+
22
+ /** @type {readonly string[]} */
23
+ const SUPPLEMENTAL_DIRS = [
24
+ 'lib/schema',
25
+ 'lib/programmatic/help-content',
26
+ 'templates/openapi',
27
+ 'templates/external-system',
28
+ 'lib/datasource/capability/templates'
29
+ ];
30
+
31
+ /** @type {readonly string[]} */
32
+ const MANIFEST_FORBIDDEN_PREFIXES = [
33
+ 'templates/applications/',
34
+ 'templates/github/',
35
+ 'templates/infra/',
36
+ 'templates/python/',
37
+ 'templates/typescript/',
38
+ 'templates/channels/',
39
+ 'integration/',
40
+ 'tests/',
41
+ 'scripts/',
42
+ '.cursor/',
43
+ 'builder/',
44
+ 'packages/',
45
+ 'docs/',
46
+ 'bin/aifabrix.js',
47
+ 'lib/cli/'
48
+ ];
49
+
50
+ /**
51
+ * @param {string} repoRoot
52
+ * @param {string} fromFile
53
+ * @param {string} req
54
+ * @returns {string|null}
55
+ */
56
+ function resolveRelativeRequire(repoRoot, fromFile, req) {
57
+ if (!req.startsWith('.')) {
58
+ return null;
59
+ }
60
+ const base = path.dirname(fromFile);
61
+ let resolved = path.resolve(repoRoot, base, req);
62
+ if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
63
+ resolved = path.join(resolved, 'index.js');
64
+ }
65
+ if (!resolved.endsWith('.js') && fs.existsSync(`${resolved}.js`)) {
66
+ resolved = `${resolved}.js`;
67
+ }
68
+ if (!fs.existsSync(resolved)) {
69
+ return null;
70
+ }
71
+ return path.relative(repoRoot, resolved).split(path.sep).join('/');
72
+ }
73
+
74
+ /**
75
+ * @param {string} repoRoot
76
+ * @param {string} relFile
77
+ * @returns {string[]}
78
+ */
79
+ function collectRequiresFromFile(repoRoot, relFile) {
80
+ const abs = path.join(repoRoot, relFile);
81
+ const content = fs.readFileSync(abs, 'utf8');
82
+ const found = [];
83
+ let match;
84
+ while ((match = REQUIRE_RE.exec(content)) !== null) {
85
+ const target = resolveRelativeRequire(repoRoot, relFile, match[1]);
86
+ if (target) {
87
+ found.push(target);
88
+ }
89
+ }
90
+ return found;
91
+ }
92
+
93
+ /**
94
+ * @param {string} dir
95
+ * @param {string} repoRoot
96
+ * @param {Set<string>} out
97
+ * @returns {void}
98
+ */
99
+ function addDirectoryFiles(dir, repoRoot, out) {
100
+ const abs = path.join(repoRoot, dir);
101
+ if (!fs.existsSync(abs)) {
102
+ return;
103
+ }
104
+ for (const entry of fs.readdirSync(abs, { withFileTypes: true })) {
105
+ const rel = path.join(dir, entry.name).split(path.sep).join('/');
106
+ if (entry.isDirectory()) {
107
+ addDirectoryFiles(rel, repoRoot, out);
108
+ continue;
109
+ }
110
+ out.add(rel);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * @param {string} repoRoot
116
+ * @returns {string[]}
117
+ */
118
+ function discoverRuntimeFiles(repoRoot) {
119
+ const seen = new Set();
120
+ const queue = [...ENTRY_FILES];
121
+
122
+ while (queue.length > 0) {
123
+ const rel = queue.shift();
124
+ if (!rel || seen.has(rel)) {
125
+ continue;
126
+ }
127
+ if (!fs.existsSync(path.join(repoRoot, rel))) {
128
+ continue;
129
+ }
130
+ seen.add(rel);
131
+ for (const next of collectRequiresFromFile(repoRoot, rel)) {
132
+ if (!seen.has(next)) {
133
+ queue.push(next);
134
+ }
135
+ }
136
+ }
137
+
138
+ for (const dir of SUPPLEMENTAL_DIRS) {
139
+ addDirectoryFiles(dir, repoRoot, seen);
140
+ }
141
+
142
+ return [...seen].sort().filter((rel) => !STAGING_SKIP_FILES.includes(rel));
143
+ }
144
+
145
+ /**
146
+ * @param {string} relPath
147
+ * @returns {boolean}
148
+ */
149
+ function isForbiddenManifestPath(relPath) {
150
+ const normalized = relPath.split(path.sep).join('/');
151
+ for (const prefix of MANIFEST_FORBIDDEN_PREFIXES) {
152
+ if (normalized === prefix.replace(/\/$/, '') || normalized.startsWith(prefix)) {
153
+ return true;
154
+ }
155
+ }
156
+ if (normalized.endsWith('.md') && normalized.startsWith('lib/')) {
157
+ if (normalized.startsWith('lib/programmatic/help-content/')) {
158
+ return false;
159
+ }
160
+ return true;
161
+ }
162
+ return false;
163
+ }
164
+
165
+ /**
166
+ * @param {string[]} manifest
167
+ * @returns {string[]}
168
+ */
169
+ function findManifestViolations(manifest) {
170
+ return manifest.filter(isForbiddenManifestPath);
171
+ }
172
+
173
+ module.exports = {
174
+ ENTRY_FILES,
175
+ SUPPLEMENTAL_DIRS,
176
+ MANIFEST_FORBIDDEN_PREFIXES,
177
+ STAGING_SKIP_FILES,
178
+ discoverRuntimeFiles,
179
+ findManifestViolations,
180
+ isForbiddenManifestPath,
181
+ resolveRelativeRequire,
182
+ collectRequiresFromFile
183
+ };
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Forbidden-path profiles for Docker image content gate (plan 154.3).
3
+ *
4
+ * @fileoverview Offline path checks + docker image listing
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { spawnSync } = require('child_process');
12
+
13
+ /** @type {readonly string[]} */
14
+ const BUILDER_API_FORBIDDEN = [
15
+ '/app/.cursor',
16
+ '/app/builder',
17
+ '/app/integration',
18
+ '/app/tests',
19
+ '/app/docs',
20
+ '/app/scripts',
21
+ '/app/packages',
22
+ '/app/bin/aifabrix.js'
23
+ ];
24
+
25
+ /** @type {readonly string[]} */
26
+ const BUILDER_API_TEMPLATE_ALLOWED_PREFIXES = [
27
+ '/app/templates/openapi',
28
+ '/app/templates/external-system'
29
+ ];
30
+
31
+ /**
32
+ * @param {string} profile
33
+ * @returns {string[]}
34
+ */
35
+ function forbiddenPathsForProfile(profile) {
36
+ const normalized = String(profile || '').trim().toLowerCase();
37
+ if (normalized === 'builder-api') {
38
+ return [...BUILDER_API_FORBIDDEN];
39
+ }
40
+ throw new Error(`Unsupported profile: ${profile}`);
41
+ }
42
+
43
+ /**
44
+ * @param {string[]} pathsPresent
45
+ * @param {string[]} forbidden
46
+ * @returns {string[]}
47
+ */
48
+ function findForbiddenPrefixViolations(pathsPresent, forbidden) {
49
+ const violations = [];
50
+ for (const forbiddenPath of forbidden) {
51
+ const prefix = forbiddenPath.replace(/\/$/, '');
52
+ for (const present of pathsPresent) {
53
+ const normalized = present.replace(/\/$/, '');
54
+ if (normalized === prefix || normalized.startsWith(`${prefix}/`)) {
55
+ violations.push(forbiddenPath);
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ return violations;
61
+ }
62
+
63
+ /**
64
+ * @param {string} present
65
+ * @returns {boolean}
66
+ */
67
+ function isAllowedBuilderApiTemplatePath(present) {
68
+ const normalized = present.replace(/\/$/, '');
69
+ if (normalized === '/app/templates') {
70
+ return true;
71
+ }
72
+ if (!normalized.startsWith('/app/templates')) {
73
+ return true;
74
+ }
75
+ return BUILDER_API_TEMPLATE_ALLOWED_PREFIXES.some((prefix) => (
76
+ normalized === prefix || normalized.startsWith(`${prefix}/`)
77
+ ));
78
+ }
79
+
80
+ /**
81
+ * @param {string[]} pathsPresent
82
+ * @returns {string[]}
83
+ */
84
+ function findBuilderApiTemplateViolations(pathsPresent) {
85
+ const violations = [];
86
+ for (const present of pathsPresent) {
87
+ if (!isAllowedBuilderApiTemplatePath(present)) {
88
+ violations.push(present);
89
+ }
90
+ }
91
+ return violations;
92
+ }
93
+
94
+ /**
95
+ * @param {string[]} pathsPresent
96
+ * @returns {string[]}
97
+ */
98
+ function findBuilderApiMarkdownViolations(pathsPresent) {
99
+ const violations = [];
100
+ for (const present of pathsPresent) {
101
+ if (!present.endsWith('.md')) {
102
+ continue;
103
+ }
104
+ if (present.startsWith('/app/lib/')) {
105
+ violations.push(present);
106
+ }
107
+ }
108
+ return violations;
109
+ }
110
+
111
+ /**
112
+ * @param {string} image
113
+ * @param {string} workdir
114
+ * @param {number} maxdepth
115
+ * @returns {string[]}
116
+ */
117
+ function listImagePaths(image, workdir, maxdepth = 6) {
118
+ const proc = spawnSync(
119
+ 'docker',
120
+ [
121
+ 'run',
122
+ '--rm',
123
+ '--entrypoint',
124
+ 'sh',
125
+ image,
126
+ '-c',
127
+ `find ${workdir} -mindepth 1 -maxdepth ${maxdepth} \\( -type d -o -type f \\) 2>/dev/null`
128
+ ],
129
+ { encoding: 'utf8' }
130
+ );
131
+ if (proc.status !== 0) {
132
+ throw new Error((proc.stderr || proc.stdout || '').trim() || `docker run failed for image ${image}`);
133
+ }
134
+ return proc.stdout.split('\n').map((line) => line.trim()).filter(Boolean);
135
+ }
136
+
137
+ /**
138
+ * @param {string} image
139
+ * @param {string} profile
140
+ * @returns {string[]}
141
+ */
142
+ function checkImage(image, profile) {
143
+ const normalized = String(profile || '').trim().toLowerCase();
144
+ const paths = listImagePaths(image, '/app');
145
+ const forbidden = forbiddenPathsForProfile(profile);
146
+ const violations = findForbiddenPrefixViolations(paths, forbidden);
147
+
148
+ if (normalized === 'builder-api') {
149
+ violations.push(...findBuilderApiTemplateViolations(paths));
150
+ violations.push(...findBuilderApiMarkdownViolations(paths));
151
+ }
152
+
153
+ return [...new Set(violations)].sort();
154
+ }
155
+
156
+ module.exports = {
157
+ BUILDER_API_FORBIDDEN,
158
+ BUILDER_API_TEMPLATE_ALLOWED_PREFIXES,
159
+ forbiddenPathsForProfile,
160
+ findForbiddenPrefixViolations,
161
+ isAllowedBuilderApiTemplatePath,
162
+ findBuilderApiTemplateViolations,
163
+ findBuilderApiMarkdownViolations,
164
+ listImagePaths,
165
+ checkImage
166
+ };
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @fileoverview Plan actor display name (~/.aifabrix/plan-actor.yaml, shared across repos).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const fs = require('fs');
8
+ const os = require('os');
9
+ const path = require('path');
10
+
11
+ const REPO_ROOT = path.resolve(__dirname, '../..');
12
+ const LEGACY_REPO_ACTOR_PATH = path.join(REPO_ROOT, '.aifabrix', 'plan-actor.yaml');
13
+
14
+ /**
15
+ * @typedef {Object} PlanActor
16
+ * @property {string} displayName - Human-readable validator name for plan records
17
+ * @property {string} [email] - Optional contact email
18
+ */
19
+
20
+ /**
21
+ * @returns {string} Absolute path to the shared ~/.aifabrix config directory
22
+ */
23
+ function resolveAifabrixDir() {
24
+ if (process.env.AIFABRIX_HOME) {
25
+ return path.join(process.env.AIFABRIX_HOME, '.aifabrix');
26
+ }
27
+ return path.join(os.homedir(), '.aifabrix');
28
+ }
29
+
30
+ /**
31
+ * @returns {string} Absolute path to plan-actor.yaml (global or PLAN_ACTOR_PATH override)
32
+ */
33
+ function resolveActorPath() {
34
+ if (process.env.PLAN_ACTOR_PATH) {
35
+ return process.env.PLAN_ACTOR_PATH;
36
+ }
37
+ return path.join(resolveAifabrixDir(), 'plan-actor.yaml');
38
+ }
39
+
40
+ /**
41
+ * One-time copy from repo-local `.aifabrix/plan-actor.yaml` when global file missing.
42
+ * @returns {void}
43
+ */
44
+ function migrateLegacyActorIfNeeded() {
45
+ const actorPath = resolveActorPath();
46
+ if (fs.existsSync(actorPath) || !fs.existsSync(LEGACY_REPO_ACTOR_PATH)) {
47
+ return;
48
+ }
49
+ fs.mkdirSync(path.dirname(actorPath), { recursive: true });
50
+ fs.copyFileSync(LEGACY_REPO_ACTOR_PATH, actorPath);
51
+ }
52
+
53
+ /**
54
+ * @returns {PlanActor|null} Parsed actor from disk, or null when file or displayName is missing
55
+ */
56
+ function loadActor() {
57
+ migrateLegacyActorIfNeeded();
58
+ const actorPath = resolveActorPath();
59
+ if (!fs.existsSync(actorPath)) {
60
+ return null;
61
+ }
62
+ const raw = fs.readFileSync(actorPath, 'utf8');
63
+ const nameMatch = raw.match(/^displayName:\s*"?([^"\n]+)"?\s*$/m);
64
+ const emailMatch = raw.match(/^email:\s*"?([^"\n]+)"?\s*$/m);
65
+ if (!nameMatch) {
66
+ return null;
67
+ }
68
+ const actor = { displayName: nameMatch[1].trim() };
69
+ if (emailMatch) {
70
+ actor.email = emailMatch[1].trim();
71
+ }
72
+ return actor;
73
+ }
74
+
75
+ /**
76
+ * @param {string} displayName - Validator display name written to plan-actor.yaml
77
+ * @param {string} [email] - Optional email stored alongside the display name
78
+ * @returns {string} Absolute path to the written plan-actor.yaml file
79
+ */
80
+ function saveActor(displayName, email) {
81
+ const actorPath = resolveActorPath();
82
+ fs.mkdirSync(path.dirname(actorPath), { recursive: true });
83
+ const lines = [`displayName: "${displayName.replace(/"/g, '\\"')}"`];
84
+ if (email) {
85
+ lines.push(`email: "${email.replace(/"/g, '\\"')}"`);
86
+ }
87
+ fs.writeFileSync(actorPath, `${lines.join('\n')}\n`, 'utf8');
88
+ return actorPath;
89
+ }
90
+
91
+ /**
92
+ * @param {string} [overrideName] - CLI or env override; skips reading plan-actor.yaml when set
93
+ * @returns {PlanActor|null} Override actor, loaded actor, or null when none is configured
94
+ */
95
+ function resolveActor(overrideName) {
96
+ if (overrideName) {
97
+ return { displayName: overrideName };
98
+ }
99
+ return loadActor();
100
+ }
101
+
102
+ module.exports = {
103
+ ACTOR_PATH: resolveActorPath(),
104
+ resolveActorPath,
105
+ loadActor,
106
+ saveActor,
107
+ resolveActor,
108
+ migrateLegacyActorIfNeeded
109
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview Plan lifecycle paths and gate policy (builder).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const path = require('path');
8
+
9
+ const REPO_ROOT = path.resolve(__dirname, '../..');
10
+ const PLANS_DIR = path.join(REPO_ROOT, '.cursor/plans');
11
+
12
+ module.exports = {
13
+ REPO_ROOT,
14
+ PLANS_DIR,
15
+ DONE_DIR: path.join(PLANS_DIR, 'Done'),
16
+ REPORT_DIR: path.join(REPO_ROOT, 'temp/plan-validation'),
17
+ REQUIRED_SKILLS: ['builder-validate-implementation'],
18
+ STRICT_FRONTMATTER: false,
19
+ REQUIRE_APPROVAL_TO_ARCHIVE: true
20
+ };
@@ -0,0 +1,154 @@
1
+ /**
2
+ * @fileoverview Plan quality gates (miso / builder — config-driven).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { loadPlanFile, hasSurface } = require('./plan-parse');
10
+ const { REQUIRED_SKILLS, STRICT_FRONTMATTER, REPO_ROOT } = require('./plan-config');
11
+
12
+ const SKILLS_DIR = path.join(REPO_ROOT, '.cursor/skills');
13
+
14
+ /**
15
+ * @typedef {{ label: string, status: 'pass' | 'fail' | 'warn' | 'skip', detail?: string }} GateResult
16
+ */
17
+
18
+ /**
19
+ * @param {string} label
20
+ * @param {'pass' | 'fail' | 'warn' | 'skip'} status
21
+ * @param {string} [detail]
22
+ * @returns {GateResult}
23
+ */
24
+ function gate(label, status, detail) {
25
+ return { label, status, detail };
26
+ }
27
+
28
+ /**
29
+ * @returns {GateResult}
30
+ */
31
+ function gateSkills() {
32
+ if (!REQUIRED_SKILLS.length) {
33
+ return gate('skills', 'skip', 'none configured');
34
+ }
35
+ const missing = REQUIRED_SKILLS.filter(
36
+ (name) => !fs.existsSync(path.join(SKILLS_DIR, name, 'SKILL.md'))
37
+ );
38
+ if (missing.length) {
39
+ return gate('skills', 'fail', `missing: ${missing.join(', ')}`);
40
+ }
41
+ return gate('skills', 'pass');
42
+ }
43
+
44
+ /**
45
+ * @param {Record<string, unknown>} meta
46
+ * @returns {GateResult}
47
+ */
48
+ function gatePlanFrontmatter(meta) {
49
+ const errors = [];
50
+ const warns = [];
51
+ if (!meta.name && !meta.overview) {
52
+ errors.push('name or overview');
53
+ }
54
+ if (!Array.isArray(meta.todos) || meta.todos.length === 0) {
55
+ errors.push('todos');
56
+ }
57
+ if (STRICT_FRONTMATTER) {
58
+ if (!meta.name) {
59
+ errors.push('name');
60
+ }
61
+ if (!meta.overview) {
62
+ errors.push('overview');
63
+ }
64
+ if (!meta.status) {
65
+ errors.push('status');
66
+ }
67
+ if (!meta.planType) {
68
+ errors.push('planType');
69
+ }
70
+ if (!meta.createdBy) {
71
+ errors.push('createdBy');
72
+ }
73
+ if (meta.planType === 'code' && !Array.isArray(meta.surfaces)) {
74
+ errors.push('surfaces');
75
+ }
76
+ } else if (!meta.createdBy) {
77
+ warns.push('createdBy');
78
+ }
79
+ if (errors.length) {
80
+ return gate('plan-frontmatter', 'fail', `missing: ${errors.join(', ')}`);
81
+ }
82
+ if (warns.length) {
83
+ return gate('plan-frontmatter', 'warn', `missing: ${warns.join(', ')}`);
84
+ }
85
+ return gate('plan-frontmatter', 'pass');
86
+ }
87
+
88
+ /**
89
+ * @param {Record<string, unknown>} meta
90
+ * @returns {GateResult}
91
+ */
92
+ function gateApiTier(meta) {
93
+ if (!hasSurface(meta, 'api')) {
94
+ return gate('api-tier', 'skip', 'no api surface');
95
+ }
96
+ const tiers = meta.apiTiers;
97
+ if (!Array.isArray(tiers) || tiers.length === 0) {
98
+ return gate('api-tier', 'warn', 'api surface without apiTiers');
99
+ }
100
+ return gate('api-tier', 'pass');
101
+ }
102
+
103
+ /**
104
+ * @param {Array<{ id: string, status: string, content: string }>} todos
105
+ */
106
+ function auditTodos(todos) {
107
+ const blockingPending = todos.filter(
108
+ (t) => t.status === 'pending' || t.status === 'in_progress'
109
+ );
110
+ const manualPending = todos.filter(
111
+ (t) =>
112
+ (t.status === 'pending' || t.status === 'in_progress') &&
113
+ /manual|pilot|proof|e2e smoke|live test|business validation/i.test(t.content)
114
+ );
115
+ return { blockingPending, manualPending };
116
+ }
117
+
118
+ /**
119
+ * @param {string} planPath
120
+ */
121
+ function runAllGates(planPath) {
122
+ const loaded = loadPlanFile(planPath);
123
+ if (!loaded) {
124
+ return {
125
+ gates: [gate('plan-parse', 'fail', 'invalid frontmatter')],
126
+ todos: [],
127
+ blockingPending: [],
128
+ manualPending: []
129
+ };
130
+ }
131
+
132
+ const { meta } = loaded;
133
+ const todos = Array.isArray(meta.todos) ? meta.todos : [];
134
+ const gates = [
135
+ gateSkills(),
136
+ gatePlanFrontmatter(meta),
137
+ gateApiTier(meta),
138
+ gate('todos', todos.length ? 'pass' : 'fail', `${todos.length} todo(s)`)
139
+ ];
140
+
141
+ const { blockingPending, manualPending } = auditTodos(
142
+ todos.map((t) => ({
143
+ id: String(t.id || ''),
144
+ status: String(t.status || 'pending'),
145
+ content: String(t.content || '')
146
+ }))
147
+ );
148
+
149
+ return { gates, todos, blockingPending, manualPending };
150
+ }
151
+
152
+ module.exports = {
153
+ runAllGates
154
+ };