@aifabrix/builder 2.53.1 → 2.55.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 (470) hide show
  1. package/README.md +8 -0
  2. package/bin/aifabrix.js +2 -2
  3. package/lib/agent-kit/apply-ops.js +82 -0
  4. package/lib/agent-kit/checksums.js +28 -0
  5. package/lib/agent-kit/classify.js +113 -0
  6. package/lib/agent-kit/claude-shim.js +61 -0
  7. package/lib/agent-kit/constants.js +55 -0
  8. package/lib/agent-kit/file-list.js +103 -0
  9. package/lib/agent-kit/host-approve.js +130 -0
  10. package/lib/agent-kit/hosting/github.js +63 -0
  11. package/lib/agent-kit/hosts.js +71 -0
  12. package/lib/agent-kit/init.js +319 -0
  13. package/lib/agent-kit/kit-root.js +17 -0
  14. package/lib/agent-kit/managed-section.js +79 -0
  15. package/lib/agent-kit/package-load.js +45 -0
  16. package/lib/agent-kit/plan-ops.js +69 -0
  17. package/lib/agent-kit/remote-prompts.js +239 -0
  18. package/lib/agent-kit/render-host-markdown.js +40 -0
  19. package/lib/agent-kit/repo-guard.js +47 -0
  20. package/lib/agent-kit/report.js +107 -0
  21. package/lib/agent-kit/run.js +82 -0
  22. package/lib/agent-kit/scm/git.js +122 -0
  23. package/lib/agent-kit/state-file.js +83 -0
  24. package/lib/agent-kit/status.js +50 -0
  25. package/lib/agent-kit/v1-detect.js +81 -0
  26. package/lib/agent-kit/validate-kit.js +87 -0
  27. package/lib/agent-kit/workspace-name.js +40 -0
  28. package/lib/agent-kit/workspace-skeleton.js +103 -0
  29. package/lib/api/assistants.api.js +8 -5
  30. package/lib/api/channel-identity.api.js +41 -0
  31. package/lib/api/evidence-authoring.api.js +5 -1
  32. package/lib/api/evidence.api.js +2 -0
  33. package/lib/api/role-assistant-test-pack.api.js +86 -0
  34. package/lib/api/types/evidence.types.js +2 -0
  35. package/lib/api/work-search.api.js +163 -0
  36. package/lib/api/work.api.js +19 -12
  37. package/lib/app/list-external-systems.js +2 -1
  38. package/lib/app/show-display.js +33 -6
  39. package/lib/app/show.js +25 -2
  40. package/lib/channels/add-channel.js +164 -126
  41. package/lib/channels/approval-guides/chatgpt.js +14 -18
  42. package/lib/channels/approval-guides/claude.js +29 -0
  43. package/lib/channels/approval-guides/index.js +88 -22
  44. package/lib/channels/approval-guides/mcp-client.js +27 -0
  45. package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
  46. package/lib/channels/approval-guides/slack.js +10 -10
  47. package/lib/channels/approval-guides/teams-bot.js +8 -12
  48. package/lib/channels/channel-add-continuations.js +91 -0
  49. package/lib/channels/channel-add-ensure.js +124 -27
  50. package/lib/channels/channel-add-existing.js +160 -28
  51. package/lib/channels/channel-add-failure.js +61 -0
  52. package/lib/channels/channel-add-remaining.js +492 -0
  53. package/lib/channels/channel-add-tty.js +190 -0
  54. package/lib/channels/channel-add-wizard-config.js +138 -0
  55. package/lib/channels/channel-add-wizard.js +250 -0
  56. package/lib/channels/channel-artifact-generator.js +27 -13
  57. package/lib/channels/channel-cardinality.js +83 -0
  58. package/lib/channels/channel-catalog-icon.js +45 -0
  59. package/lib/channels/channel-cli-instructions.js +75 -0
  60. package/lib/channels/channel-configuration-map.js +213 -0
  61. package/lib/channels/channel-credential.js +11 -14
  62. package/lib/channels/channel-definition-project.js +101 -0
  63. package/lib/channels/channel-definition-registry.js +154 -0
  64. package/lib/channels/channel-definition-status.js +115 -0
  65. package/lib/channels/channel-description.js +60 -2
  66. package/lib/channels/channel-discovery.js +16 -2
  67. package/lib/channels/channel-external-system.js +86 -9
  68. package/lib/channels/channel-install-envelope-actions.js +88 -0
  69. package/lib/channels/channel-install-envelope-microsoft.js +155 -0
  70. package/lib/channels/channel-install-envelope.js +358 -0
  71. package/lib/channels/channel-install-help-md.js +172 -0
  72. package/lib/channels/channel-install-http-payload.js +62 -0
  73. package/lib/channels/channel-install-inventory.js +115 -0
  74. package/lib/channels/channel-install-profiles.js +90 -0
  75. package/lib/channels/channel-instance-collision.js +118 -0
  76. package/lib/channels/channel-instance-key.js +100 -0
  77. package/lib/channels/channel-instance-materialize.js +240 -0
  78. package/lib/channels/channel-integration-generator.js +18 -9
  79. package/lib/channels/channel-integration-template.js +101 -22
  80. package/lib/channels/channel-inventory-fetch.js +79 -0
  81. package/lib/channels/channel-oauth-preflight.js +104 -0
  82. package/lib/channels/channel-package-version.js +76 -0
  83. package/lib/channels/channel-predefined-client.js +154 -0
  84. package/lib/channels/channel-probe.js +7 -2
  85. package/lib/channels/channel-runtime-resolver.js +194 -72
  86. package/lib/channels/channel-status-display.js +86 -16
  87. package/lib/channels/channel-targets.js +132 -92
  88. package/lib/channels/chatgpt-callback.js +318 -0
  89. package/lib/channels/chatgpt-channel-add.js +229 -0
  90. package/lib/channels/chatgpt-preflight.js +396 -0
  91. package/lib/channels/chatgpt-runtime-contract.js +17 -0
  92. package/lib/channels/chatgpt-setup-values.js +124 -0
  93. package/lib/channels/claude-callback.js +67 -0
  94. package/lib/channels/claude-channel-add.js +254 -0
  95. package/lib/channels/claude-runtime-contract.js +40 -0
  96. package/lib/channels/claude-runtime.js +58 -0
  97. package/lib/channels/claude-setup-values.js +92 -0
  98. package/lib/channels/mcp-client/config-merge.js +148 -0
  99. package/lib/channels/mcp-client/ensure-client.js +231 -0
  100. package/lib/channels/mcp-client/paths.js +53 -0
  101. package/lib/channels/mcp-client/profiles.js +122 -0
  102. package/lib/channels/mcp-client/redirect-uris.js +99 -0
  103. package/lib/channels/mcp-client/runtime.js +59 -0
  104. package/lib/channels/mcp-client-channel-add.js +186 -0
  105. package/lib/channels/microsoft-copilot-channel-add.js +117 -7
  106. package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
  107. package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
  108. package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
  109. package/lib/channels/microsoft-copilot-package-prior.js +107 -0
  110. package/lib/channels/microsoft-copilot-package.js +29 -28
  111. package/lib/channels/microsoft-provisioning/a365.js +80 -0
  112. package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
  113. package/lib/channels/microsoft-provisioning/auth.js +179 -0
  114. package/lib/channels/microsoft-provisioning/cli.js +71 -0
  115. package/lib/channels/microsoft-provisioning/constants.js +75 -0
  116. package/lib/channels/microsoft-provisioning/errors.js +117 -0
  117. package/lib/channels/microsoft-provisioning/index.js +55 -0
  118. package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
  119. package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
  120. package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
  121. package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
  122. package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
  123. package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
  124. package/lib/channels/microsoft-provisioning/persist.js +110 -0
  125. package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
  126. package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
  127. package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
  128. package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
  129. package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
  130. package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
  131. package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
  132. package/lib/channels/runtime-tool-catalog.js +5 -2
  133. package/lib/channels/slack-channel-add-portal.js +130 -0
  134. package/lib/channels/slack-channel-add-tty-auth.js +95 -0
  135. package/lib/channels/slack-channel-add.js +311 -0
  136. package/lib/channels/slack-mcp-callback.js +51 -0
  137. package/lib/channels/slack-mcp-runtime.js +156 -0
  138. package/lib/channels/slack-provisioning/apps.js +181 -0
  139. package/lib/channels/slack-provisioning/auth-store.js +110 -0
  140. package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
  141. package/lib/channels/slack-provisioning/auth.js +115 -0
  142. package/lib/channels/slack-provisioning/callbacks.js +41 -0
  143. package/lib/channels/slack-provisioning/cli.js +226 -0
  144. package/lib/channels/slack-provisioning/constants.js +37 -0
  145. package/lib/channels/slack-provisioning/credentials.js +169 -0
  146. package/lib/channels/slack-provisioning/curl-shim.js +132 -0
  147. package/lib/channels/slack-provisioning/developer-install.js +118 -0
  148. package/lib/channels/slack-provisioning/env-file.js +120 -0
  149. package/lib/channels/slack-provisioning/errors.js +47 -0
  150. package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
  151. package/lib/channels/slack-provisioning/index.js +250 -0
  152. package/lib/channels/slack-provisioning/install-cli.js +335 -0
  153. package/lib/channels/slack-provisioning/manifest.js +89 -0
  154. package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
  155. package/lib/channels/slack-provisioning/offer-cli.js +113 -0
  156. package/lib/channels/slack-provisioning/onboard-members.js +122 -0
  157. package/lib/channels/slack-provisioning/onboard.js +89 -0
  158. package/lib/channels/slack-provisioning/persist.js +95 -0
  159. package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
  160. package/lib/channels/slack-provisioning/with-curl-on-path.js +53 -0
  161. package/lib/channels/teams-bot-channel-add.js +94 -0
  162. package/lib/channels/vendor-dataplane-url.js +249 -0
  163. package/lib/cli/index.js +4 -0
  164. package/lib/cli/setup-certification-commands.js +2 -2
  165. package/lib/cli/setup-certification.help.js +5 -1
  166. package/lib/cli/setup-external-system-help.js +2 -0
  167. package/lib/cli/setup-external-system.js +1 -1
  168. package/lib/commands/agent-kit-help.js +79 -0
  169. package/lib/commands/agent-kit.js +346 -0
  170. package/lib/commands/channel-add-help.js +366 -0
  171. package/lib/commands/channel-add-setup.js +162 -80
  172. package/lib/commands/channel-configure.js +118 -0
  173. package/lib/commands/channel.js +10 -1
  174. package/lib/commands/datasource-capability-relate-cli.js +5 -4
  175. package/lib/commands/governance-upload-external.js +6 -3
  176. package/lib/commands/lifecycle-command-action.js +2 -5
  177. package/lib/commands/lifecycle-external.js +93 -21
  178. package/lib/commands/repair-auth-apply.js +1 -1
  179. package/lib/commands/repair-datasource-key-skip.js +39 -0
  180. package/lib/commands/repair-datasource-keys.js +24 -12
  181. package/lib/commands/repair-datasource-test-payload.js +4 -2
  182. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
  183. package/lib/commands/repair-datasource.js +3 -0
  184. package/lib/commands/repair-external-run.js +59 -25
  185. package/lib/commands/repair-openapi-rest-runtime.js +127 -0
  186. package/lib/commands/repair-orchestration-tag-merge.js +339 -0
  187. package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
  188. package/lib/commands/repair-rbac-platform-preset.js +26 -15
  189. package/lib/commands/repair-rbac-reader-roles.js +8 -21
  190. package/lib/commands/repair-rbac.js +26 -44
  191. package/lib/commands/repair-system-permissions.js +24 -22
  192. package/lib/commands/role-assistant-copy-output.js +61 -0
  193. package/lib/commands/role-assistant-copy.js +155 -0
  194. package/lib/commands/role-assistant-test-output.js +22 -9
  195. package/lib/commands/role-assistant-test-result-rows.js +42 -0
  196. package/lib/commands/role-assistant.js +150 -43
  197. package/lib/commands/search.js +143 -0
  198. package/lib/commands/test-e2e-external.js +148 -21
  199. package/lib/commands/test-trust-external.js +7 -5
  200. package/lib/commands/upload-credential-push-log.js +2 -1
  201. package/lib/commands/upload-publish-context.js +1 -1
  202. package/lib/commands/upload-role-assistant-shell.js +124 -0
  203. package/lib/commands/upload-sidecar-followups.js +10 -4
  204. package/lib/commands/upload.js +18 -3
  205. package/lib/commands/verify-operations-skip-e2e.js +131 -0
  206. package/lib/commands/verify-operations-step-plan.js +6 -33
  207. package/lib/commands/verify-operations-steps.js +3 -1
  208. package/lib/core/secrets-docker-env.js +4 -1
  209. package/lib/core/secrets-env-content.js +17 -3
  210. package/lib/datasource/capability/capability-manifest.js +0 -3
  211. package/lib/datasource/capability/copy-test-payload.js +3 -0
  212. package/lib/datasource/capability/relate-operations.js +28 -10
  213. package/lib/datasource/capability/run-capability-relate.js +48 -25
  214. package/lib/datasource/datasource-identifier.js +13 -5
  215. package/lib/deployment/deployer-poll-run.js +117 -35
  216. package/lib/external-system/deploy-dataplane-published.js +70 -0
  217. package/lib/external-system/deploy-helpers.js +26 -1
  218. package/lib/external-system/deploy.js +22 -8
  219. package/lib/external-system/download-helpers.js +29 -2
  220. package/lib/external-system/download-role-assistant.js +109 -4
  221. package/lib/external-system/download.js +46 -30
  222. package/lib/external-system/sync-deploy-manifest.js +3 -2
  223. package/lib/external-system/upload-identity.js +42 -0
  224. package/lib/generator/index.js +19 -15
  225. package/lib/generator/split.js +13 -2
  226. package/lib/generator/wizard-datasource-key.js +54 -0
  227. package/lib/generator/wizard.js +55 -54
  228. package/lib/integration-definition/apply-datasource-keys.js +75 -0
  229. package/lib/integration-definition/apply-relationships.js +195 -0
  230. package/lib/integration-definition/apply-static-enterprise.js +229 -0
  231. package/lib/integration-definition/apply-system-file.js +71 -0
  232. package/lib/integration-definition/apply-test-endpoint.js +89 -0
  233. package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
  234. package/lib/integration-definition/apply.js +78 -59
  235. package/lib/integration-definition/enrich-openapi-operations.js +36 -10
  236. package/lib/integration-definition/enrich-openapi-pick.js +87 -0
  237. package/lib/lifecycle/role-assistant-governance.js +181 -0
  238. package/lib/lifecycle/scenario-upload.js +181 -30
  239. package/lib/programmatic/builder-api-cors.js +143 -0
  240. package/lib/programmatic/builder-api-request.js +6 -0
  241. package/lib/programmatic/builder-api-route-dispatch.js +56 -42
  242. package/lib/programmatic/builder-api-server.js +8 -1
  243. package/lib/programmatic/capability-registry.js +55 -0
  244. package/lib/programmatic/channel-install-help-resolve.js +359 -0
  245. package/lib/programmatic/channel-install-session.js +218 -0
  246. package/lib/programmatic/help-content/channel-onboarding.md +2 -0
  247. package/lib/programmatic/help-content/cip-overview.md +3 -1
  248. package/lib/programmatic/http-raw-response.js +62 -0
  249. package/lib/programmatic/index.js +2 -0
  250. package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
  251. package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
  252. package/lib/programmatic/openapi-channel-install-schemas.js +289 -0
  253. package/lib/programmatic/openapi-component-schemas.js +19 -1
  254. package/lib/programmatic/openapi-description-enricher.js +3 -1
  255. package/lib/programmatic/openapi-descriptions.js +80 -3
  256. package/lib/programmatic/openapi-envelope-examples.js +124 -0
  257. package/lib/programmatic/openapi-operation-bindings.js +9 -1
  258. package/lib/programmatic/openapi-request-schemas.js +5 -0
  259. package/lib/programmatic/openapi-schema-descriptions-channel.js +319 -0
  260. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  261. package/lib/programmatic/openapi-spec.js +13 -8
  262. package/lib/programmatic/platform-rbac-catalog.js +36 -18
  263. package/lib/programmatic/request-timeout.js +3 -0
  264. package/lib/programmatic/route-handler-map.js +58 -1
  265. package/lib/programmatic/route-handlers-context.js +2 -1
  266. package/lib/programmatic/run-auth-permissions.js +54 -0
  267. package/lib/programmatic/run-channel-catalog.js +238 -0
  268. package/lib/programmatic/run-channel-install-artifacts.js +137 -0
  269. package/lib/programmatic/run-channel-install-copilot.js +353 -0
  270. package/lib/programmatic/run-channel-install-options.js +236 -0
  271. package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
  272. package/lib/programmatic/run-channel-install.js +346 -0
  273. package/lib/programmatic/run-channel-package.js +87 -7
  274. package/lib/programmatic/run-download.js +41 -0
  275. package/lib/programmatic/workspace-context.js +2 -0
  276. package/lib/protection/auth-context.js +3 -1
  277. package/lib/protection/protection-display.js +3 -2
  278. package/lib/protection/report-exit.js +50 -0
  279. package/lib/protection/run-commands.js +2 -0
  280. package/lib/role-assistant/evidence-sync.js +4 -2
  281. package/lib/role-assistant/evidence-validation-issues.js +51 -0
  282. package/lib/role-assistant/knowledge-sync.js +10 -4
  283. package/lib/role-assistant/package-validate.js +175 -0
  284. package/lib/role-assistant/settings.js +49 -2
  285. package/lib/role-assistant/test-case-assertion-row.js +36 -0
  286. package/lib/role-assistant/test-case-copy-bind.js +77 -0
  287. package/lib/role-assistant/test-case-copy-expected.js +127 -0
  288. package/lib/role-assistant/test-case-copy-from-work.js +90 -0
  289. package/lib/role-assistant/test-case-copy-interactions.js +67 -0
  290. package/lib/role-assistant/test-case-copy.js +119 -0
  291. package/lib/role-assistant/test-case-expected-catalog.js +135 -0
  292. package/lib/role-assistant/test-case-validate.js +88 -0
  293. package/lib/role-assistant/test-cases-bid.js +117 -4
  294. package/lib/role-assistant/test-cases-evaluate.js +159 -24
  295. package/lib/role-assistant/test-cases-evidence.js +175 -0
  296. package/lib/role-assistant/test-cases-honesty.js +155 -6
  297. package/lib/role-assistant/test-cases-lifecycle.js +291 -0
  298. package/lib/role-assistant/test-cases-search-graph.js +122 -0
  299. package/lib/role-assistant/test-cases-search.js +247 -0
  300. package/lib/role-assistant/test-cases.js +71 -172
  301. package/lib/role-assistant/test-pack-map.js +180 -0
  302. package/lib/role-assistant/test-pack-sync.js +187 -0
  303. package/lib/role-assistant/test-runner-debug.js +54 -0
  304. package/lib/role-assistant/test-runner-respond-body.js +36 -0
  305. package/lib/role-assistant/test-runner-search.js +164 -0
  306. package/lib/role-assistant/test-runner-start-payload.js +63 -10
  307. package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
  308. package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
  309. package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
  310. package/lib/role-assistant/test-runner-workhub.js +74 -32
  311. package/lib/role-assistant/test-runner.js +66 -11
  312. package/lib/schema/external-datasource.schema.json +146 -21
  313. package/lib/schema/external-system.schema.json +177 -2
  314. package/lib/schema/mcp-client-profile.schema.json +103 -0
  315. package/lib/schema/role-assistant-test-case.schema.json +408 -0
  316. package/lib/search/dataplane-context.js +23 -0
  317. package/lib/search/search-args.js +211 -0
  318. package/lib/search/search-display.js +238 -0
  319. package/lib/search/search-errors.js +50 -0
  320. package/lib/search/search-prompts.js +119 -0
  321. package/lib/search/search-roles.js +85 -0
  322. package/lib/search/search-run.js +241 -0
  323. package/lib/search/search-skills.js +198 -0
  324. package/lib/utils/app-path-resolve.js +4 -0
  325. package/lib/utils/authentication-env-template.js +44 -6
  326. package/lib/utils/authentication-slot-show.js +153 -0
  327. package/lib/utils/credential-display.js +43 -1
  328. package/lib/utils/credential-secrets-env.js +6 -1
  329. package/lib/utils/env-copy.js +19 -7
  330. package/lib/utils/external-env-template.js +20 -2
  331. package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
  332. package/lib/utils/external-system-readiness-compact-display.js +30 -1
  333. package/lib/utils/external-system-validators.js +2 -1
  334. package/lib/utils/help-builder.js +3 -1
  335. package/lib/utils/paths.js +18 -1
  336. package/lib/utils/platform-shell-package.js +69 -0
  337. package/lib/utils/port-resolver.js +50 -1
  338. package/lib/utils/rewrite-name-flag.js +20 -0
  339. package/lib/utils/role-assistant-paths.js +13 -10
  340. package/lib/utils/schema-loader.js +37 -0
  341. package/lib/utils/schema-resolver.js +11 -1
  342. package/lib/utils/secrets-helpers.js +12 -21
  343. package/lib/utils/token-manager.js +10 -5
  344. package/lib/validation/validate-external-file.js +5 -1
  345. package/lib/validation/validate.js +41 -0
  346. package/package.json +1 -1
  347. package/templates/README.md +1 -1
  348. package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
  349. package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
  350. package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
  351. package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
  352. package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
  353. package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
  354. package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
  355. package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
  356. package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
  357. package/templates/agent-kit/agent-kit.yaml +45 -0
  358. package/templates/agent-kit/instructions/AGENTKIT.md +83 -0
  359. package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
  360. package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
  361. package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
  362. package/templates/agent-kit/parity-inventory.yaml +188 -0
  363. package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +58 -0
  364. package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
  365. package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
  366. package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
  367. package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
  368. package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +51 -0
  369. package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
  370. package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
  371. package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
  372. package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +50 -0
  373. package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
  374. package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
  375. package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
  376. package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +42 -0
  377. package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
  378. package/templates/agent-kit/skills/shared/hosts.md +78 -0
  379. package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
  380. package/templates/agent-kit/workspace/LICENSE.mit +21 -0
  381. package/templates/agent-kit/workspace/README.md +89 -0
  382. package/templates/applications/builder-api/Dockerfile +3 -1
  383. package/templates/applications/builder-api/env.template +7 -0
  384. package/templates/applications/dataplane/application.yaml +6 -5
  385. package/templates/applications/dataplane/env.template +2 -2
  386. package/templates/applications/dataplane/rbac.yaml +35 -2
  387. package/templates/applications/keycloak/Dockerfile +30 -4
  388. package/templates/applications/keycloak/application.yaml +2 -2
  389. package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
  390. package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
  391. package/templates/applications/keycloak/env.template +3 -0
  392. package/templates/applications/miso-controller/application.yaml +1 -2
  393. package/templates/applications/miso-controller/env.template +10 -9
  394. package/templates/channels/README.md +5 -5
  395. package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
  396. package/templates/channels/chatgpt/channel.json +59 -0
  397. package/templates/channels/chatgpt/icon.svg +1 -0
  398. package/templates/channels/chatgpt/install.template.md.hbs +20 -95
  399. package/templates/channels/chatgpt/integration/README.md +1 -1
  400. package/templates/channels/chatgpt/integration/application.json +2 -2
  401. package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
  402. package/templates/channels/chatgpt/integration/env.template +2 -4
  403. package/templates/channels/chatgpt/integration/rbac.json +13 -0
  404. package/templates/channels/claude/TROUBLESHOOTING.md +44 -0
  405. package/templates/channels/claude/channel.json +59 -0
  406. package/templates/channels/claude/icon.svg +1 -0
  407. package/templates/channels/claude/install.template.md.hbs +22 -0
  408. package/templates/channels/claude/integration/README.md +14 -0
  409. package/templates/channels/claude/integration/application.json +15 -0
  410. package/templates/channels/claude/integration/claude-system.json +59 -0
  411. package/templates/channels/claude/integration/env.template +2 -0
  412. package/templates/channels/claude/integration/rbac.json +13 -0
  413. package/templates/channels/claude/manifest.template.json.hbs +40 -0
  414. package/templates/channels/mcp-client/channel.json +72 -0
  415. package/templates/channels/mcp-client/icon.svg +1 -0
  416. package/templates/channels/mcp-client/install.template.md.hbs +24 -0
  417. package/templates/channels/mcp-client/integration/README.md +13 -0
  418. package/templates/channels/mcp-client/integration/application.json +15 -0
  419. package/templates/channels/mcp-client/integration/env.template +2 -0
  420. package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
  421. package/templates/channels/mcp-client/integration/rbac.json +13 -0
  422. package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
  423. package/templates/channels/mcp-client/profiles/cursor.json +26 -0
  424. package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
  425. package/templates/channels/mcp-client/profiles/vscode.json +29 -0
  426. package/templates/channels/microsoft-copilot/channel.json +73 -0
  427. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
  428. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
  429. package/templates/channels/microsoft-copilot/icon.svg +1 -0
  430. package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
  431. package/templates/channels/microsoft-copilot/integration/README.md +1 -1
  432. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  433. package/templates/channels/microsoft-copilot/integration/env.template +3 -6
  434. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
  435. package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
  436. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
  437. package/templates/channels/slack/channel.json +234 -0
  438. package/templates/channels/slack/icon.svg +1 -0
  439. package/templates/channels/slack/install.template.md.hbs +45 -28
  440. package/templates/channels/slack/integration/README.md +245 -22
  441. package/templates/channels/slack/integration/application.json +44 -7
  442. package/templates/channels/slack/integration/env.template +15 -6
  443. package/templates/channels/slack/integration/openapi/openapi.json +126 -0
  444. package/templates/channels/slack/integration/rbac.json +84 -0
  445. package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
  446. package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
  447. package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
  448. package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
  449. package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
  450. package/templates/channels/slack/integration/slack-system.json +161 -72
  451. package/templates/channels/slack/manifest.template.json.hbs +10 -4
  452. package/templates/channels/teams-bot/channel.json +162 -0
  453. package/templates/channels/teams-bot/icon.svg +1 -0
  454. package/templates/channels/teams-bot/install.template.md.hbs +12 -13
  455. package/templates/channels/teams-bot/integration/README.md +5 -4
  456. package/templates/channels/teams-bot/integration/application.json +6 -4
  457. package/templates/channels/teams-bot/integration/env.template +5 -4
  458. package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
  459. package/templates/channels/teams-bot/integration/rbac.json +21 -0
  460. package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
  461. package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
  462. package/templates/channels/web-embed/channel.json +60 -0
  463. package/templates/channels/web-embed/install.template.md.hbs +1 -1
  464. package/templates/channels/web-embed/integration/README.md +2 -2
  465. package/templates/channels/web-embed/integration/application.json +2 -2
  466. package/templates/channels/web-embed/integration/env.template +1 -1
  467. package/templates/channels/web-embed/integration/rbac.json +13 -0
  468. package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
  469. package/templates/python/docker-compose.hbs +14 -0
  470. package/templates/typescript/docker-compose.hbs +14 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Map ES configuration[] names to consumer propertyKeys and install options.
3
+ *
4
+ * @fileoverview CHANNEL_COMMAND_PREFIX → commandPrefix
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const SECRET_NAME_RE = /(SECRET|PASSWORD|TOKEN|KEY|CREDENTIAL)/i;
12
+
13
+ /**
14
+ * @param {string} envName
15
+ * @returns {string}
16
+ */
17
+ function envNameToPropertyKey(envName) {
18
+ const stripped = String(envName || '').replace(/^CHANNEL_/, '');
19
+ const lower = stripped.toLowerCase();
20
+ return lower.replace(/_([a-z0-9])/g, (_, ch) => ch.toUpperCase());
21
+ }
22
+
23
+ /**
24
+ * @param {Object} definition
25
+ * @returns {Object[]}
26
+ */
27
+ function listDefinitionConfiguration(definition) {
28
+ const rows = definition && Array.isArray(definition.configuration) ? definition.configuration : [];
29
+ return rows.filter((row) => row && typeof row.name === 'string');
30
+ }
31
+
32
+ /**
33
+ * @param {Object} definition
34
+ * @returns {Map<string, Object>}
35
+ */
36
+ function configurationByPropertyKey(definition) {
37
+ const map = new Map();
38
+ for (const row of listDefinitionConfiguration(definition)) {
39
+ map.set(envNameToPropertyKey(row.name), row);
40
+ }
41
+ return map;
42
+ }
43
+
44
+ /**
45
+ * @param {unknown} value
46
+ * @returns {boolean}
47
+ */
48
+ function isSecretShapedValue(value) {
49
+ if (typeof value !== 'string') {
50
+ return false;
51
+ }
52
+ return /kv:\/\//i.test(value) || SECRET_NAME_RE.test(value);
53
+ }
54
+
55
+ /**
56
+ * Safe configuration for GET definition (no secret-shaped values).
57
+ * @param {Object} definition
58
+ * @returns {Object[]}
59
+ */
60
+ function toSafeConfiguration(definition) {
61
+ return listDefinitionConfiguration(definition).map((row) => {
62
+ const copy = { ...row };
63
+ if (isSecretShapedValue(copy.value)) {
64
+ copy.value = '';
65
+ }
66
+ copy.propertyKey = envNameToPropertyKey(row.name);
67
+ return copy;
68
+ });
69
+ }
70
+
71
+ /**
72
+ * @param {Object} row
73
+ * @returns {Object|null}
74
+ */
75
+ function toPortalField(row) {
76
+ const portal = row && row.portalInput;
77
+ if (!portal || typeof portal !== 'object') {
78
+ return null;
79
+ }
80
+ if (typeof portal.label !== 'string' || !portal.label.trim()) {
81
+ return null;
82
+ }
83
+ if (isSecretShapedValue(row.value)) {
84
+ return null;
85
+ }
86
+ const propertyKey = envNameToPropertyKey(row.name);
87
+ const field = {
88
+ propertyKey,
89
+ label: portal.label.trim(),
90
+ required: row.required === true,
91
+ envName: row.name
92
+ };
93
+ if (portal.field) {
94
+ field.inputKind = portal.field;
95
+ }
96
+ if (portal.placeholder) {
97
+ field.placeholder = portal.placeholder;
98
+ }
99
+ if (Array.isArray(portal.options) && portal.options.length > 0) {
100
+ field.options = portal.options;
101
+ }
102
+ if (
103
+ typeof row.value === 'string' &&
104
+ row.value.trim() &&
105
+ !row.value.includes('{{') &&
106
+ !/kv:\/\//i.test(row.value)
107
+ ) {
108
+ field.defaultValue = row.value.trim();
109
+ }
110
+ assignPortalConstraints(field, portal.validation);
111
+ return field;
112
+ }
113
+
114
+ /**
115
+ * @param {Object} field
116
+ * @param {unknown} validation
117
+ */
118
+ function assignPortalConstraints(field, validation) {
119
+ if (!validation || typeof validation !== 'object') {
120
+ return;
121
+ }
122
+ const rules = /** @type {Record<string, unknown>} */ (validation);
123
+ if (typeof rules.minLength === 'number' && rules.minLength > 0) {
124
+ field.minLength = rules.minLength;
125
+ }
126
+ if (typeof rules.maxLength === 'number' && rules.maxLength > 0) {
127
+ field.maxLength = rules.maxLength;
128
+ }
129
+ if (typeof rules.pattern === 'string' && rules.pattern.trim()) {
130
+ field.pattern = rules.pattern.trim();
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Portal-facing fields only. Rows without portalInput are hidden system variables.
136
+ * @param {Object} definition
137
+ * @returns {Object[]}
138
+ */
139
+ function toPortalFields(definition) {
140
+ return listDefinitionConfiguration(definition)
141
+ .map(toPortalField)
142
+ .filter(Boolean);
143
+ }
144
+
145
+ /**
146
+ * @param {Object} definition
147
+ * @param {Object} configuration
148
+ * @returns {string[]}
149
+ */
150
+ function unknownConfigurationKeys(definition, configuration) {
151
+ if (!configuration || typeof configuration !== 'object') {
152
+ return [];
153
+ }
154
+ const known = configurationByPropertyKey(definition);
155
+ return Object.keys(configuration).filter((key) => !known.has(key));
156
+ }
157
+
158
+ /**
159
+ * @param {Object} definition
160
+ * @param {Object} configuration
161
+ * @returns {string[]}
162
+ */
163
+ function missingRequiredConfigurationKeys(definition, configuration) {
164
+ const provided = configuration && typeof configuration === 'object' ? configuration : {};
165
+ const missing = [];
166
+ for (const [propertyKey, row] of configurationByPropertyKey(definition).entries()) {
167
+ if (row.required === true && (provided[propertyKey] === undefined || provided[propertyKey] === '')) {
168
+ missing.push(propertyKey);
169
+ }
170
+ }
171
+ return missing;
172
+ }
173
+
174
+ const OPTION_BY_PROPERTY_KEY = {
175
+ commandPrefix: 'commandPrefix',
176
+ packageVersion: 'packageVersion',
177
+ oauthPluginVaultReferenceId: 'oauthPluginVaultReferenceId',
178
+ appDescription: 'description'
179
+ };
180
+
181
+ /**
182
+ * @param {Object} options
183
+ * @param {Object} configuration
184
+ * @returns {Object}
185
+ */
186
+ function applyConfigurationToAddOptions(options, configuration) {
187
+ if (!configuration || typeof configuration !== 'object') {
188
+ return options;
189
+ }
190
+ const next = { ...options };
191
+ for (const [propertyKey, value] of Object.entries(configuration)) {
192
+ if (SECRET_NAME_RE.test(propertyKey) && !OPTION_BY_PROPERTY_KEY[propertyKey]) {
193
+ continue;
194
+ }
195
+ const optionKey = OPTION_BY_PROPERTY_KEY[propertyKey] || propertyKey;
196
+ if (value !== undefined) {
197
+ next[optionKey] = value;
198
+ }
199
+ }
200
+ return next;
201
+ }
202
+
203
+ module.exports = {
204
+ envNameToPropertyKey,
205
+ listDefinitionConfiguration,
206
+ configurationByPropertyKey,
207
+ toSafeConfiguration,
208
+ toPortalFields,
209
+ unknownConfigurationKeys,
210
+ missingRequiredConfigurationKeys,
211
+ applyConfigurationToAddOptions,
212
+ isSecretShapedValue
213
+ };
@@ -26,7 +26,8 @@ const CREDENTIAL_SPECS = {
26
26
  method: 'hmac',
27
27
  credentialConfig: {
28
28
  type: 'hmac',
29
- signingSecret: 'pending-channel-install',
29
+ signingSecret: 'kv://slack/signingSecret',
30
+ botToken: 'kv://slack/botToken',
30
31
  algorithm: 'sha256',
31
32
  signatureHeader: 'X-Slack-Signature',
32
33
  timestampHeader: 'X-Slack-Request-Timestamp',
@@ -57,15 +58,6 @@ const CREDENTIAL_SPECS = {
57
58
  clientSecret: 'pending-channel-install'
58
59
  }
59
60
  },
60
- chatgpt: {
61
- method: 'apiKey',
62
- credentialConfig: {
63
- type: 'apiKey',
64
- apiKey: 'pending-channel-install',
65
- headerName: 'Authorization',
66
- prefix: 'Bearer'
67
- }
68
- },
69
61
  'web-embed': {
70
62
  method: 'apiKey',
71
63
  credentialConfig: {
@@ -148,10 +140,15 @@ async function createChannelCredential(ctx, channelTarget, target) {
148
140
  * @returns {Promise<{ pushed: number }>}
149
141
  */
150
142
  async function pushIntegrationSecrets(ctx, channelTarget) {
151
- const integrationDir = getIntegrationPath(channelTarget);
152
- const envPath = path.join(integrationDir, '.env');
143
+ const folderKey =
144
+ ctx && typeof ctx.instanceSystemKey === 'string' && ctx.instanceSystemKey.trim()
145
+ ? ctx.instanceSystemKey.trim()
146
+ : channelTarget;
147
+ const integrationDir = ctx && ctx.projectRoot
148
+ ? path.join(path.resolve(ctx.projectRoot), 'integration', folderKey)
149
+ : getIntegrationPath(folderKey);
153
150
  const result = await pushCredentialSecrets(ctx.dataplaneUrl, ctx.authConfig, {
154
- envFilePath: envPath,
151
+ envFilePath: path.join(integrationDir, '.env'),
155
152
  appName: channelTarget,
156
153
  quiet: true
157
154
  });
@@ -175,7 +172,7 @@ async function ensureChannelCredential(params) {
175
172
  if (skipsChannelOauthCredential(channelTarget)) {
176
173
  return {
177
174
  skipped: true,
178
- reason: 'entraSsoTrustedIssuer',
175
+ reason: channelTarget === 'microsoft-copilot' ? 'entraSsoTrustedIssuer' : 'integrationClientOAuth',
179
176
  credentialKey: target.credentialKey
180
177
  };
181
178
  }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Project Channel Definitions into the historic CHANNEL_TARGETS row shape.
3
+ *
4
+ * @fileoverview Catalog / wizard / adapter packaging from channel.json
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { definitionRuntimeSystemKey } = require('./channel-definition-registry');
12
+
13
+ const DEFAULT_CAPABILITIES = ['chat', 'notify', 'documentApproval'];
14
+
15
+ /**
16
+ * @param {Object} definition
17
+ * @returns {Object}
18
+ */
19
+ function packagingOf(definition) {
20
+ const packing = definition && definition.channel && definition.channel.packaging;
21
+ return packing && typeof packing === 'object' ? packing : {};
22
+ }
23
+
24
+ /**
25
+ * @param {Object} definition
26
+ * @param {Object} packing
27
+ * @returns {string}
28
+ */
29
+ function credentialKeyOf(definition, packing) {
30
+ const fromAuth =
31
+ definition.authentication && definition.authentication.credential
32
+ ? definition.authentication.credential.credentialKey
33
+ : null;
34
+ return fromAuth || packing.credentialKey || `${definition.key}-channel`;
35
+ }
36
+
37
+ /**
38
+ * @param {Object} definition
39
+ * @param {Object} channel
40
+ * @returns {Object}
41
+ */
42
+ function runtimeTargetOf(definition, channel) {
43
+ return (
44
+ channel.runtimeTarget || {
45
+ defaultSystemKey: definitionRuntimeSystemKey(definition),
46
+ configurable: true
47
+ }
48
+ );
49
+ }
50
+
51
+ /**
52
+ * @param {Object} definition
53
+ * @param {Object} packing
54
+ * @returns {Object}
55
+ */
56
+ function packagingFields(definition, packing) {
57
+ return {
58
+ channelType: packing.channelType || definition.key,
59
+ templateDir: packing.templateDir || definition.key,
60
+ artifactFileName: packing.artifactFileName || `channel-${definition.key}.json`,
61
+ artifactFormat: packing.artifactFormat || 'json',
62
+ displayLabel: packing.displayLabel || definition.displayName,
63
+ category: packing.category || 'communication',
64
+ wizardOrder: Number.isInteger(packing.wizardOrder) ? packing.wizardOrder : 100,
65
+ remainingManualStep: packing.remainingManualStep || '',
66
+ docsAnchor: packing.docsAnchor || definition.key,
67
+ approvalRequired: packing.approvalRequired !== false,
68
+ vendorAuthRequired: packing.vendorAuthRequired !== false,
69
+ capabilities: Array.isArray(packing.capabilities)
70
+ ? [...packing.capabilities]
71
+ : [...DEFAULT_CAPABILITIES]
72
+ };
73
+ }
74
+
75
+ /**
76
+ * @param {Object} definition
77
+ * @returns {Object}
78
+ */
79
+ function toChannelTargetProjection(definition) {
80
+ const packing = packagingOf(definition);
81
+ const channel = definition.channel || {};
82
+ return {
83
+ key: definition.key,
84
+ ...packagingFields(definition, packing),
85
+ credentialKey: credentialKeyOf(definition, packing),
86
+ description: definition.description,
87
+ experimental: channel.experimental === true,
88
+ automatedProvisioning: Boolean(channel.provisioning && channel.provisioning.mode === 'automatic'),
89
+ provisioning: channel.provisioning || { mode: 'guided' },
90
+ runtimeTarget: runtimeTargetOf(definition, channel),
91
+ profiles: Array.isArray(channel.profiles) ? channel.profiles.map((row) => ({ ...row })) : [],
92
+ definitionKey: channel.definitionKey || definition.key,
93
+ artifacts: Array.isArray(channel.artifacts) ? [...channel.artifacts] : []
94
+ };
95
+ }
96
+
97
+ module.exports = {
98
+ packagingOf,
99
+ toChannelTargetProjection,
100
+ DEFAULT_CAPABILITIES
101
+ };
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Load Channel Definitions from templates/channels/<key>/channel.json.
3
+ *
4
+ * @fileoverview Canonical ES documents plus channel specialization
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const path = require('path');
12
+
13
+ const TEMPLATES_ROOT = path.join(__dirname, '..', '..', 'templates', 'channels');
14
+ const DEFAULT_RUNTIME = 'runtime-orchestration';
15
+
16
+ /** @type {Map<string, Object>|null} */
17
+ let cachedDefinitions = null;
18
+
19
+ /**
20
+ * Disk SSOT must ignore Jest `fs` mocks (brand/ is an icon pack, not a definition).
21
+ * @returns {typeof import('node:fs')}
22
+ */
23
+ function channelDiskFs() {
24
+ const jestApi = typeof globalThis.jest === 'object' ? globalThis.jest : null;
25
+ if (jestApi && typeof jestApi.requireActual === 'function') {
26
+ return jestApi.requireActual('node:fs');
27
+ }
28
+ const snap = global.__AIFABRIX_NODE_FS_UNMOCKED__;
29
+ if (snap && typeof snap.readdirSync === 'function' && typeof snap.readFileSync === 'function') {
30
+ return snap;
31
+ }
32
+ return require('node:fs');
33
+ }
34
+
35
+ /**
36
+ * @param {string} raw
37
+ * @param {string} filePath
38
+ * @returns {Object}
39
+ */
40
+ function parseDefinition(raw, filePath) {
41
+ const parsed = JSON.parse(raw);
42
+ if (!parsed || typeof parsed !== 'object' || typeof parsed.key !== 'string') {
43
+ throw new Error(`Invalid Channel Definition: ${filePath}`);
44
+ }
45
+ return parsed;
46
+ }
47
+
48
+ /**
49
+ * @param {object} disk
50
+ * @param {string} templatesRoot
51
+ * @param {string} name
52
+ * @param {Map<string, Object>} map
53
+ * @returns {void}
54
+ */
55
+ function loadOneDefinition(disk, templatesRoot, name, map) {
56
+ if (typeof name !== 'string' || name.startsWith('.')) {
57
+ return;
58
+ }
59
+ const filePath = path.join(templatesRoot, name, 'channel.json');
60
+ let raw;
61
+ try {
62
+ raw = disk.readFileSync(filePath, 'utf8');
63
+ } catch (err) {
64
+ if (err && (err.code === 'ENOENT' || err.code === 'EISDIR' || err.code === 'ENOTDIR')) {
65
+ return;
66
+ }
67
+ throw err;
68
+ }
69
+ if (typeof raw !== 'string' || !raw.trim()) {
70
+ return;
71
+ }
72
+ const definition = parseDefinition(raw, filePath);
73
+ map.set(definition.key, definition);
74
+ }
75
+
76
+ /**
77
+ * @param {string} [templatesRoot]
78
+ * @returns {Map<string, Object>}
79
+ */
80
+ function loadChannelDefinitions(templatesRoot = TEMPLATES_ROOT) {
81
+ const disk = channelDiskFs();
82
+ const map = new Map();
83
+ let names;
84
+ try {
85
+ names = disk.readdirSync(templatesRoot);
86
+ } catch {
87
+ return map;
88
+ }
89
+ if (!Array.isArray(names)) {
90
+ return map;
91
+ }
92
+ for (const name of names) {
93
+ loadOneDefinition(disk, templatesRoot, name, map);
94
+ }
95
+ return map;
96
+ }
97
+
98
+ /**
99
+ * @returns {Map<string, Object>}
100
+ */
101
+ function getChannelDefinitionMap() {
102
+ if (cachedDefinitions && cachedDefinitions.size > 0) {
103
+ return cachedDefinitions;
104
+ }
105
+ cachedDefinitions = loadChannelDefinitions();
106
+ return cachedDefinitions;
107
+ }
108
+
109
+ /**
110
+ * Test hook — clear cached definitions.
111
+ * @returns {void}
112
+ */
113
+ function resetChannelDefinitionCache() {
114
+ cachedDefinitions = null;
115
+ }
116
+
117
+ /**
118
+ * @param {string} key
119
+ * @returns {Object|null}
120
+ */
121
+ function getChannelDefinition(key) {
122
+ return getChannelDefinitionMap().get(key) || null;
123
+ }
124
+
125
+ /**
126
+ * @returns {string[]}
127
+ */
128
+ function listChannelDefinitionKeys() {
129
+ return [...getChannelDefinitionMap().keys()];
130
+ }
131
+
132
+ /**
133
+ * @param {Object} definition
134
+ * @returns {string}
135
+ */
136
+ function definitionRuntimeSystemKey(definition) {
137
+ const fromDoc = definition && definition.channel && definition.channel.runtimeTarget;
138
+ if (fromDoc && typeof fromDoc.defaultSystemKey === 'string' && fromDoc.defaultSystemKey) {
139
+ return fromDoc.defaultSystemKey;
140
+ }
141
+ return DEFAULT_RUNTIME;
142
+ }
143
+
144
+ module.exports = {
145
+ TEMPLATES_ROOT,
146
+ DEFAULT_RUNTIME,
147
+ channelDiskFs,
148
+ loadChannelDefinitions,
149
+ getChannelDefinitionMap,
150
+ getChannelDefinition,
151
+ listChannelDefinitionKeys,
152
+ resetChannelDefinitionCache,
153
+ definitionRuntimeSystemKey
154
+ };
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Channel Definition catalog/install status (visible | hide | coming-soon).
3
+ *
4
+ * @fileoverview Omit or visible: listed and installable. hide: omitted and refused. coming-soon: listed read-only.
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const registry = require('./channel-definition-registry');
12
+
13
+ const CHANNEL_STATUSES = ['visible', 'hide', 'coming-soon'];
14
+ const COMING_SOON_REASON = 'This channel is coming soon.';
15
+ const HIDE_REASON = 'This channel is not available.';
16
+
17
+ /**
18
+ * @param {Object|null} definition
19
+ * @returns {'visible'|'hide'|'coming-soon'}
20
+ */
21
+ function normalizeChannelStatus(definition) {
22
+ const raw = definition && definition.channel && definition.channel.status;
23
+ if (raw === 'hide' || raw === 'coming-soon') {
24
+ return raw;
25
+ }
26
+ return 'visible';
27
+ }
28
+
29
+ /**
30
+ * Live status from the Channel Definition registry (spy-friendly).
31
+ * @param {string} key
32
+ * @returns {'visible'|'hide'|'coming-soon'}
33
+ */
34
+ function channelStatusOf(key) {
35
+ return normalizeChannelStatus(registry.getChannelDefinition(key));
36
+ }
37
+
38
+ /**
39
+ * @param {string} status
40
+ * @returns {boolean}
41
+ */
42
+ function isCatalogHiddenStatus(status) {
43
+ return status === 'hide';
44
+ }
45
+
46
+ /**
47
+ * @param {string} status
48
+ * @returns {boolean}
49
+ */
50
+ function isInstallableStatus(status) {
51
+ return status === 'visible';
52
+ }
53
+
54
+ /**
55
+ * @param {string} key
56
+ * @param {string} status
57
+ * @returns {Error}
58
+ */
59
+ function statusUnavailableError(key, status) {
60
+ const message =
61
+ status === 'coming-soon'
62
+ ? `Channel target "${key}" is coming soon.`
63
+ : `Channel target "${key}" is not available.`;
64
+ const err = new Error(message);
65
+ err.statusCode = 403;
66
+ return err;
67
+ }
68
+
69
+ /**
70
+ * Refuse new install for hide and coming-soon. Continue of an existing session skips.
71
+ * --force / allowExperimental do not override.
72
+ * @param {string} key
73
+ * @param {{ continueInstall?: boolean }} [options]
74
+ * @returns {void}
75
+ */
76
+ function assertChannelStatusInstallable(key, options = {}) {
77
+ if (options.continueInstall === true) {
78
+ return;
79
+ }
80
+ const status = channelStatusOf(key);
81
+ if (isInstallableStatus(status)) {
82
+ return;
83
+ }
84
+ throw statusUnavailableError(key, status);
85
+ }
86
+
87
+ /**
88
+ * Overlay coming-soon onto a catalog/detail projection (canInstall false).
89
+ * @param {string} status
90
+ * @param {Object} [projection]
91
+ * @returns {Object}
92
+ */
93
+ function applyChannelStatusProjection(status, projection = {}) {
94
+ if (status !== 'coming-soon') {
95
+ return { ...projection, status };
96
+ }
97
+ return {
98
+ ...projection,
99
+ status,
100
+ canInstall: false,
101
+ blockedReason: COMING_SOON_REASON
102
+ };
103
+ }
104
+
105
+ module.exports = {
106
+ CHANNEL_STATUSES,
107
+ COMING_SOON_REASON,
108
+ HIDE_REASON,
109
+ normalizeChannelStatus,
110
+ channelStatusOf,
111
+ isCatalogHiddenStatus,
112
+ isInstallableStatus,
113
+ assertChannelStatusInstallable,
114
+ applyChannelStatusProjection
115
+ };