@aifabrix/builder 2.52.1 → 2.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/lib/app/deploy-config.js +3 -2
  2. package/lib/channels/add-channel.js +11 -41
  3. package/lib/channels/approval-guides/index.js +3 -0
  4. package/lib/channels/approval-guides/microsoft-copilot.js +26 -17
  5. package/lib/channels/channel-add-existing.js +72 -0
  6. package/lib/channels/channel-runtime-resolver.js +5 -1
  7. package/lib/channels/channel-status-display.js +30 -3
  8. package/lib/channels/microsoft-copilot-entra-sso-form.js +73 -2
  9. package/lib/channels/microsoft-copilot-entra-sso.js +26 -5
  10. package/lib/channels/microsoft-copilot-limits.js +22 -3
  11. package/lib/channels/microsoft-copilot-package.js +59 -14
  12. package/lib/channels/microsoft-copilot-validate.js +40 -10
  13. package/lib/cli/attach-default-help-examples.js +102 -0
  14. package/lib/cli/index.js +2 -0
  15. package/lib/cli/setup-credential-deployment.js +7 -5
  16. package/lib/cli/setup-utility-validate.js +1 -0
  17. package/lib/commands/credential-push.js +37 -5
  18. package/lib/commands/package-score.js +72 -0
  19. package/lib/commands/role-assistant.js +46 -8
  20. package/lib/deployment/deployer-poll-run.js +2 -2
  21. package/lib/deployment/deployer.js +1 -1
  22. package/lib/deployment/environment.js +2 -2
  23. package/lib/external-system/deploy.js +11 -21
  24. package/lib/integration-definition/apply.js +12 -14
  25. package/lib/integration-definition/enrich-openapi-operations.js +9 -10
  26. package/lib/lab/package-parity-score.js +417 -0
  27. package/lib/programmatic/capability-registry.js +1 -0
  28. package/lib/programmatic/help-content/channel-onboarding.md +35 -0
  29. package/lib/programmatic/help-content/cip-overview.md +27 -0
  30. package/lib/programmatic/help-content/connected-system-ui.md +70 -0
  31. package/lib/programmatic/help-content/dimensions-guide.md +23 -0
  32. package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
  33. package/lib/programmatic/help-content/overview.md +25 -0
  34. package/lib/programmatic/help-content/subscription-guide.md +27 -0
  35. package/lib/programmatic/help-content/workflow.md +50 -0
  36. package/lib/programmatic/openapi-component-schemas.js +1 -0
  37. package/lib/programmatic/openapi-descriptions.js +6 -0
  38. package/lib/programmatic/openapi-envelope-examples.js +11 -0
  39. package/lib/programmatic/openapi-operation-bindings.js +5 -0
  40. package/lib/programmatic/openapi-request-schemas.js +39 -13
  41. package/lib/programmatic/openapi-result-schemas.js +30 -0
  42. package/lib/programmatic/openapi-schema-descriptions-core.js +18 -0
  43. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  44. package/lib/programmatic/persist-supplied-openapi.js +180 -0
  45. package/lib/programmatic/route-handler-map.js +6 -0
  46. package/lib/programmatic/run-integration-definition.js +13 -5
  47. package/lib/role-assistant/evidence-sync.js +55 -7
  48. package/lib/role-assistant/test-runner-attachments.js +118 -0
  49. package/lib/role-assistant/test-runner-bid-apply.js +100 -21
  50. package/lib/role-assistant/test-runner-bid-document.js +1 -1
  51. package/lib/role-assistant/test-runner-start-payload.js +96 -0
  52. package/lib/role-assistant/test-runner-workhub-answers.js +11 -7
  53. package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
  54. package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
  55. package/lib/role-assistant/test-runner-workhub.js +68 -105
  56. package/lib/role-assistant/test-runner.js +5 -63
  57. package/lib/role-assistant/test-suite.js +33 -40
  58. package/lib/utils/compose-generator.js +10 -1
  59. package/lib/utils/compose-traefik-extra-routes.js +107 -0
  60. package/lib/utils/docker-build.js +2 -2
  61. package/lib/utils/help-builder.js +2 -1
  62. package/lib/utils/promote-dev-docker-image.js +15 -10
  63. package/package.json +14 -16
  64. package/templates/README.md +12 -1
  65. package/templates/applications/dataplane/application.yaml +8 -1
  66. package/templates/applications/dataplane/env.template +1 -1
  67. package/templates/applications/miso-controller/application.yaml +2 -1
  68. package/templates/applications/miso-controller/rbac.yaml +1 -0
  69. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +6 -2
  70. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +8 -5
  71. package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
  72. package/templates/channels/microsoft-copilot/install.template.md.hbs +74 -22
  73. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +29 -14
  74. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +6 -2
  75. package/templates/python/docker-compose.hbs +36 -0
  76. package/templates/typescript/docker-compose.hbs +36 -0
  77. package/.cursor/plans/Archive/157.1-security-quality-violations-by-type.csv +0 -374
  78. package/.cursor/process/README.md +0 -9
  79. package/.cursor/rules/anchor-docs.mdc +0 -15
  80. package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
  81. package/.cursor/rules/cli-layout.mdc +0 -81
  82. package/.cursor/rules/cli-product-neutral.mdc +0 -43
  83. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
  84. package/.cursor/rules/docs-rules.mdc +0 -32
  85. package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
  86. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
  87. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
  88. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
  89. package/.cursor/rules/project-rules.mdc +0 -913
  90. package/.cursor/skills/README.md +0 -15
  91. package/.dockerignore +0 -52
  92. package/.eslintignore +0 -22
  93. package/.markdownlint.json +0 -14
  94. package/anchor-docs/README.md +0 -10
  95. package/anchor-docs/_TEMPLATE +0 -24
  96. package/babel.config.js +0 -6
  97. package/bin/builder-api-cleanup.js +0 -26
  98. package/bin/builder-api-nest.js +0 -10
  99. package/bin/builder-api-spike.js +0 -19
  100. package/enterprise-knowledge/README.md +0 -50
  101. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
  102. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
  103. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
  104. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
  105. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
  106. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
  107. package/integration/README.md +0 -81
  108. package/integration/github/README.md +0 -53
  109. package/integration/github/application.json +0 -21
  110. package/integration/github/deploy.js +0 -72
  111. package/integration/github/env.template +0 -11
  112. package/integration/github/github-datasource-issue-comments.json +0 -239
  113. package/integration/github/github-datasource-issues.json +0 -399
  114. package/integration/github/github-datasource-repository.json +0 -354
  115. package/integration/github/github-deploy.json +0 -1202
  116. package/integration/github/github-system.json +0 -82
  117. package/integration/hubspot-test/README.md +0 -159
  118. package/integration/hubspot-test/application.json +0 -54
  119. package/integration/hubspot-test/companies.json +0 -2048
  120. package/integration/hubspot-test/create-hubspot.js +0 -523
  121. package/integration/hubspot-test/env.template +0 -4
  122. package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
  123. package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
  124. package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
  125. package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
  126. package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
  127. package/integration/hubspot-test/hubspot-test-system.json +0 -74
  128. package/integration/hubspot-test/rbac.json +0 -166
  129. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
  130. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
  131. package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
  132. package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
  133. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
  134. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
  135. package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
  136. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
  137. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  138. package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
  139. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
  140. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
  141. package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
  142. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
  143. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  144. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  145. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
  146. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
  147. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
  148. package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
  149. package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
  150. package/integration/hubspot-test/test-dataplane-down.js +0 -209
  151. package/integration/hubspot-test/test.js +0 -1588
  152. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
  153. package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
  154. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
  155. package/integration/roundtrip-test-local/README.md +0 -143
  156. package/integration/roundtrip-test-local/application.yaml +0 -13
  157. package/integration/roundtrip-test-local/env.template +0 -15
  158. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
  159. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
  160. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
  161. package/integration/roundtrip-test-local2/README.md +0 -143
  162. package/integration/roundtrip-test-local2/application.yaml +0 -13
  163. package/integration/roundtrip-test-local2/env.template +0 -15
  164. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
  165. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
  166. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
  167. package/integration/test/wizard.yaml +0 -8
  168. package/jest.config.coverage.js +0 -37
  169. package/jest.config.default.js +0 -11
  170. package/jest.config.integration.fixtures.js +0 -22
  171. package/jest.config.integration.js +0 -33
  172. package/jest.config.isolated.js +0 -11
  173. package/jest.config.manual.js +0 -30
  174. package/jest.global-live-fabrix-hooks.js +0 -36
  175. package/jest.isolated-projects.js +0 -283
  176. package/jest.projects.js +0 -79
  177. package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +0 -205
  178. package/packages/builder-api/README.md +0 -120
  179. package/packages/builder-api/package.json +0 -30
  180. package/packages/builder-api/src/app.module.ts +0 -7
  181. package/packages/builder-api/src/auth/auth.module.ts +0 -5
  182. package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
  183. package/packages/builder-api/src/main.ts +0 -16
  184. package/packages/builder-api/tsconfig.json +0 -15
  185. package/scripts/check-builder-api-architecture-grep.js +0 -79
  186. package/scripts/check-datasource-test-run-schema-sync.js +0 -34
  187. package/scripts/ci-fix.sh +0 -19
  188. package/scripts/ci-simulate.sh +0 -19
  189. package/scripts/diagnose-cli.js +0 -150
  190. package/scripts/docker_image_content_gate.js +0 -47
  191. package/scripts/docker_image_content_gate.sh +0 -5
  192. package/scripts/export-builder-api-evidence.js +0 -262
  193. package/scripts/install-local.js +0 -490
  194. package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
  195. package/scripts/lib/builder-api-docker-staging-core.js +0 -183
  196. package/scripts/lib/docker-image-content-gate-core.js +0 -166
  197. package/scripts/lib/plan-actor.js +0 -109
  198. package/scripts/lib/plan-config.js +0 -20
  199. package/scripts/lib/plan-gates.js +0 -154
  200. package/scripts/lib/plan-meta.js +0 -104
  201. package/scripts/lib/plan-parse.js +0 -162
  202. package/scripts/lib/plan-prevalidate-gates.js +0 -337
  203. package/scripts/lib/plan-run-core.js +0 -125
  204. package/scripts/lib/plan-run-report.js +0 -119
  205. package/scripts/plan-approve.js +0 -24
  206. package/scripts/plan-archive.js +0 -49
  207. package/scripts/plan-run.js +0 -13
  208. package/scripts/plan-set-actor.js +0 -21
  209. package/scripts/plan-validate.js +0 -80
  210. package/scripts/pnpm/af.mjs +0 -125
  211. package/scripts/pnpm/check-quiet.mjs +0 -32
  212. package/scripts/pnpm/dev-install.mjs +0 -29
  213. package/scripts/pnpm/dev-reload.mjs +0 -18
  214. package/scripts/pnpm/help.mjs +0 -55
  215. package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
  216. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
  217. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
  218. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
  219. package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
  220. package/scripts/pnpm/lib/spinner.mjs +0 -42
  221. package/scripts/pnpm-global-remove.js +0 -48
  222. package/scripts/stage_builder_api_for_docker.js +0 -65
  223. package/scripts/sync-builder-api-template.js +0 -44
  224. package/scripts/test-dataplane-bootstrap.js +0 -331
@@ -1,125 +0,0 @@
1
- /**
2
- * @fileoverview Plan run and archive core (miso / builder).
3
- */
4
-
5
- 'use strict';
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { DONE_DIR, REQUIRE_APPROVAL_TO_ARCHIVE } = require('./plan-config');
10
- const { resolvePlanPath, patchPlanMeta, die } = require('./plan-meta');
11
- const { loadPlanFile } = require('./plan-parse');
12
- const { runAllGates } = require('./plan-gates');
13
- const { buildSummaryMarkdown, writeReport } = require('./plan-run-report');
14
- const { resolveActor } = require('./plan-actor');
15
-
16
- /**
17
- * @param {import('./plan-gates').GateResult[]} gates
18
- */
19
- function gatesPassing(gates) {
20
- return gates.filter((g) => g.status === 'fail').length === 0;
21
- }
22
-
23
- /**
24
- * @param {string} planInput
25
- * @param {{ actorName?: string }} [opts]
26
- */
27
- function runPlan(planInput, opts = {}) {
28
- const planPath = resolvePlanPath(planInput);
29
- const actorInfo = resolveActor(opts.actorName);
30
- const runAt = new Date().toISOString();
31
- const planName = path.basename(planPath, '.plan.md');
32
- console.log(`Validating: ${planName}\n`);
33
-
34
- const result = runAllGates(planPath);
35
-
36
- let overallStatus = 'PASS';
37
- if (!gatesPassing(result.gates)) {
38
- overallStatus = 'FAIL';
39
- } else if (result.gates.some((g) => g.status === 'warn')) {
40
- overallStatus = 'PASS_WITH_WARNINGS';
41
- }
42
- if (result.blockingPending.length) {
43
- overallStatus = 'FAIL';
44
- }
45
-
46
- for (const g of result.gates) {
47
- const prefix =
48
- g.status === 'pass' ? '✔' : g.status === 'warn' ? '⚠' : g.status === 'skip' ? '○' : '✖';
49
- console.log(`${prefix} ${g.label}${g.detail ? ` — ${g.detail}` : ''}`);
50
- }
51
-
52
- const summary = buildSummaryMarkdown({
53
- planPath,
54
- planName,
55
- actor: actorInfo?.displayName,
56
- runAt,
57
- gates: result.gates,
58
- todos: result.todos,
59
- blockingPending: result.blockingPending,
60
- manualPending: result.manualPending,
61
- overallStatus
62
- });
63
- writeReport(summary, planName);
64
-
65
- if (!gatesPassing(result.gates) || result.blockingPending.length) {
66
- process.exit(1);
67
- }
68
-
69
- return { planPath, planName, summary, overallStatus };
70
- }
71
-
72
- /**
73
- * @param {string} planInput
74
- * @param {string} [summary]
75
- * @param {{ allowUnapproved?: boolean }} [opts]
76
- */
77
- function archivePlan(planInput, summary, opts = {}) {
78
- const planPath = resolvePlanPath(planInput);
79
- const planName = path.basename(planPath, '.plan.md');
80
- const loaded = loadPlanFile(planPath);
81
- if (
82
- REQUIRE_APPROVAL_TO_ARCHIVE &&
83
- loaded &&
84
- !loaded.meta.approvedBy &&
85
- !opts.allowUnapproved
86
- ) {
87
- die('Plan not approved — run plan-approve first or use --allow-unapproved');
88
- }
89
-
90
- fs.mkdirSync(DONE_DIR, { recursive: true });
91
- const dest = path.join(DONE_DIR, path.basename(planPath));
92
- if (fs.existsSync(dest)) {
93
- die(`Already archived: ${dest}`);
94
- }
95
- fs.renameSync(planPath, dest);
96
- if (summary) {
97
- fs.writeFileSync(path.join(DONE_DIR, `${planName}.validation.md`), summary, 'utf8');
98
- }
99
- console.log(`✔ Archived → ${dest}`);
100
- return dest;
101
- }
102
-
103
- /**
104
- * @param {string} planInput
105
- * @param {string} [actorOverride]
106
- */
107
- function approvePlan(planInput, actorOverride) {
108
- const planPath = resolvePlanPath(planInput);
109
- const actor = resolveActor(actorOverride);
110
- const name = actor?.displayName || actorOverride;
111
- if (!name) {
112
- die('Set actor first: node scripts/plan-set-actor.js "Your Name"');
113
- }
114
- const today = new Date().toISOString().slice(0, 10);
115
- patchPlanMeta(planPath, 'approvedBy', name);
116
- patchPlanMeta(planPath, 'approvedAt', today);
117
- patchPlanMeta(planPath, 'status', 'approved');
118
- console.log(`✔ Approved ${path.basename(planPath)} by ${name} on ${today}`);
119
- }
120
-
121
- module.exports = {
122
- runPlan,
123
- archivePlan,
124
- approvePlan
125
- };
@@ -1,119 +0,0 @@
1
- /**
2
- * @fileoverview Plan run report writer (shared).
3
- */
4
-
5
- 'use strict';
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { REPORT_DIR } = require('./plan-config');
10
-
11
- /**
12
- * @param {unknown} value
13
- * @returns {string}
14
- */
15
- function escapeMarkdownCell(value) {
16
- return String(value ?? '')
17
- .replace(/\r?\n+/g, ' ')
18
- .replace(/\|/g, '\\|')
19
- .trim();
20
- }
21
-
22
- /**
23
- * @param {object} params
24
- * @returns {string}
25
- */
26
- function buildSummaryMarkdown(params) {
27
- const {
28
- planPath,
29
- planName,
30
- actor,
31
- runAt,
32
- gates,
33
- todos,
34
- blockingPending,
35
- manualPending,
36
- overallStatus
37
- } = params;
38
-
39
- const lines = [
40
- '# Plan validation summary',
41
- '',
42
- '| Field | Value |',
43
- '| --- | --- |',
44
- `| **Plan** | \`${planName}\` |`,
45
- `| **Status** | **${overallStatus}** |`,
46
- `| **Run at** | ${runAt} |`,
47
- `| **Validated by** | ${actor || '_not set_'} |`,
48
- `| **Plan file** | \`${planPath}\` |`,
49
- '',
50
- '## Quality gates',
51
- '',
52
- '| Gate | Result | Detail |',
53
- '| --- | --- | --- |'
54
- ];
55
-
56
- for (const g of gates) {
57
- const icon = g.status === 'pass' ? 'pass' : g.status === 'warn' ? 'warn' : 'FAIL';
58
- lines.push(`| ${escapeMarkdownCell(g.label)} | ${icon} | ${escapeMarkdownCell(g.detail || '')} |`);
59
- }
60
-
61
- lines.push('', '## Todos', '', '| ID | Status | Content |', '| --- | --- | --- |');
62
- for (const t of todos) {
63
- lines.push(
64
- `| ${escapeMarkdownCell(t.id)} | ${escapeMarkdownCell(t.status)} | ${escapeMarkdownCell(t.content).slice(0, 100)} |`
65
- );
66
- }
67
-
68
- if (blockingPending.length) {
69
- lines.push('', '### Blocking', '');
70
- for (const t of blockingPending) {
71
- lines.push(`- **${t.id}**: ${t.content}`);
72
- }
73
- }
74
- if (manualPending.length) {
75
- lines.push('', '### Manual (non-blocking)', '');
76
- for (const t of manualPending) {
77
- lines.push(`- **${t.id}**: ${t.content}`);
78
- }
79
- }
80
-
81
- return `${lines.join('\n')}\n`;
82
- }
83
-
84
- /**
85
- * @param {string} content
86
- * @param {string} planBaseName
87
- */
88
- function writeReport(content, planBaseName) {
89
- fs.mkdirSync(REPORT_DIR, { recursive: true });
90
- const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
91
- fs.writeFileSync(path.join(REPORT_DIR, `${planBaseName}.${stamp}.md`), content, 'utf8');
92
- fs.writeFileSync(path.join(REPORT_DIR, 'LATEST.md'), content, 'utf8');
93
- console.log('Report: temp/plan-validation/LATEST.md');
94
- }
95
-
96
- /**
97
- * @param {string} planBaseName
98
- * @returns {{ summary: string, overallStatus: string } | null}
99
- */
100
- function readLatestReportForPlan(planBaseName) {
101
- const latest = path.join(REPORT_DIR, 'LATEST.md');
102
- if (!fs.existsSync(latest)) {
103
- return null;
104
- }
105
- const summary = fs.readFileSync(latest, 'utf8');
106
- const planMatch = summary.match(/\|\s*\*\*Plan\*\*\s*\|\s*`([^`]+)`\s*\|/);
107
- if (!planMatch || planMatch[1] !== planBaseName) {
108
- return null;
109
- }
110
- const statusMatch = summary.match(/\|\s*\*\*Status\*\*\s*\|\s*\*\*([^*]+)\*\*\s*\|/);
111
- const overallStatus = statusMatch ? statusMatch[1].trim() : '';
112
- return { summary, overallStatus };
113
- }
114
-
115
- module.exports = {
116
- buildSummaryMarkdown,
117
- writeReport,
118
- readLatestReportForPlan
119
- };
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- 'use strict';
4
-
5
- const { resolvePlanPath, patchPlanMeta, die } = require('./lib/plan-meta');
6
- const { resolveActor } = require('./lib/plan-actor');
7
-
8
- const planInput = process.argv[2];
9
- if (!planInput) {
10
- die('Usage: node scripts/plan-approve.js <plan-path-or-id>');
11
- }
12
-
13
- const planPath = resolvePlanPath(planInput);
14
- const actor = resolveActor(process.argv[3]);
15
- const name = actor?.displayName || process.argv[3];
16
- if (!name) {
17
- die('Set actor first via /validate-implementation (plan-set-actor)');
18
- }
19
-
20
- const today = new Date().toISOString().slice(0, 10);
21
- patchPlanMeta(planPath, 'approvedBy', name);
22
- patchPlanMeta(planPath, 'approvedAt', today);
23
- patchPlanMeta(planPath, 'status', 'approved');
24
- console.log(`✔ Approved ${planPath} by ${name} on ${today}`);
@@ -1,49 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- 'use strict';
4
-
5
- const { runPlan, archivePlan } = require('./lib/plan-run-core');
6
- const { resolvePlanPath } = require('./lib/plan-meta');
7
- const { readLatestReportForPlan } = require('./lib/plan-run-report');
8
- const path = require('path');
9
-
10
- const args = process.argv.slice(2);
11
- const planInput = args.find((a) => !a.startsWith('--'));
12
- const allowUnapproved = args.includes('--allow-unapproved');
13
- const revalidate = args.includes('--revalidate');
14
-
15
- if (!planInput) {
16
- console.error(
17
- 'Usage: node scripts/plan-archive.js <plan-path-or-id> [--allow-unapproved] [--revalidate]'
18
- );
19
- process.exit(1);
20
- }
21
-
22
- const planPath = resolvePlanPath(planInput);
23
- const planName = path.basename(planPath, '.plan.md');
24
-
25
- let summary = '';
26
- let runSummary = '';
27
-
28
- if (!revalidate) {
29
- const cached = readLatestReportForPlan(planName);
30
- if (cached) {
31
- if (cached.overallStatus !== 'PASS' && cached.overallStatus !== 'PASS_WITH_WARNINGS') {
32
- console.error(
33
- `Latest report for ${planName} is ${cached.overallStatus} — run plan-run.js or use --revalidate after fixing`
34
- );
35
- process.exit(1);
36
- }
37
- summary = cached.summary;
38
- console.log('Using cached report: temp/plan-validation/LATEST.md');
39
- }
40
- }
41
-
42
- if (!summary) {
43
- const result = runPlan(planInput);
44
- runSummary = result.summary;
45
- summary = runSummary;
46
- }
47
-
48
- archivePlan(planPath, summary, { allowUnapproved });
49
- console.log(`Plan archived: ${planName}`);
@@ -1,13 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- 'use strict';
4
-
5
- const { runPlan } = require('./lib/plan-run-core');
6
-
7
- const planInput = process.argv[2];
8
- if (!planInput) {
9
- console.error('Usage: node scripts/plan-run.js <plan-path-or-id>');
10
- process.exit(1);
11
- }
12
-
13
- runPlan(planInput);
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console */
3
- /**
4
- * Save plan validator display name to ~/.aifabrix/plan-actor.yaml (shared across repos).
5
- *
6
- * @example node scripts/plan-set-actor.js "Your Name"
7
- */
8
-
9
- 'use strict';
10
-
11
- const { saveActor } = require('./lib/plan-actor');
12
-
13
- const name = process.argv.slice(2).join(' ').trim();
14
- if (!name) {
15
- console.error('Usage: node scripts/plan-set-actor.js "Your Name"');
16
- process.exit(1);
17
- }
18
-
19
- const actorPath = saveActor(name);
20
- console.log(`✔ Saved actor: ${name}`);
21
- console.log(` ${actorPath}`);
@@ -1,80 +0,0 @@
1
- #!/usr/bin/env node
2
- /* eslint-disable no-console, require-jsdoc, valid-jsdoc, max-statements, complexity */
3
- 'use strict';
4
-
5
- const path = require('path');
6
- const { resolvePlanPath, patchPlanMeta, die } = require('./lib/plan-meta');
7
- const { resolveActor } = require('./lib/plan-actor');
8
- const {
9
- runPrevalidateGates,
10
- buildPrevalidateReport,
11
- writePrevalidateReport
12
- } = require('./lib/plan-prevalidate-gates');
13
-
14
- const args = process.argv.slice(2);
15
- const dryRun = args.includes('--dry-run');
16
- const allowNeedsUpdates = args.includes('--allow-needs-updates');
17
- const actorIdx = args.indexOf('--actor');
18
- const actorOverride = actorIdx >= 0 ? args[actorIdx + 1] : undefined;
19
- const planInput = args.find((a, i) => {
20
- if (a.startsWith('--')) {
21
- return false;
22
- }
23
- if (actorIdx >= 0 && (i === actorIdx || i === actorIdx + 1)) {
24
- return false;
25
- }
26
- return true;
27
- });
28
-
29
- if (!planInput) {
30
- die('Usage: node scripts/plan-validate.js <plan-path-or-id> [--dry-run] [--allow-needs-updates] [--actor Name]');
31
- }
32
-
33
- const planPath = resolvePlanPath(planInput);
34
- const actorInfo = resolveActor(actorOverride);
35
- if (!actorInfo && !dryRun) {
36
- die('Set actor first: node scripts/plan-set-actor.js "Your Name" (or pass --actor)');
37
- }
38
-
39
- const result = runPrevalidateGates(planPath, { allowNeedsUpdates });
40
- const planName = path.basename(planPath, '.plan.md');
41
- const runAt = new Date().toISOString();
42
- const actor = actorInfo?.displayName;
43
-
44
- for (const g of result.gates) {
45
- const prefix =
46
- g.status === 'pass' ? '✔' : g.status === 'warn' ? '⚠' : g.status === 'skip' ? '○' : '✖';
47
- console.log(`${prefix} ${g.label}${g.detail ? ` — ${g.detail}` : ''}`);
48
- }
49
-
50
- writePrevalidateReport(
51
- buildPrevalidateReport({
52
- planPath,
53
- planName,
54
- actor,
55
- runAt,
56
- gates: result.gates,
57
- planValidatedStatus: result.planValidatedStatus,
58
- reportStatus: result.reportStatus
59
- }),
60
- planName
61
- );
62
- console.log('Report: temp/plan-prevalidation/LATEST.md');
63
-
64
- const canStamp =
65
- result.planValidatedStatus === 'validated' ||
66
- (allowNeedsUpdates && result.planValidatedStatus === 'needs-updates');
67
-
68
- if (!dryRun && canStamp && actor) {
69
- const today = new Date().toISOString().slice(0, 10);
70
- patchPlanMeta(planPath, 'planValidatedStatus', result.planValidatedStatus);
71
- patchPlanMeta(planPath, 'lastValidatedBy', actor);
72
- patchPlanMeta(planPath, 'lastValidatedAt', today);
73
- console.log(`✔ Stamped ${planName}: ${result.planValidatedStatus} by ${actor} on ${today}`);
74
- } else if (!dryRun && result.planValidatedStatus === 'validated' && !actor) {
75
- die('Cannot stamp validated plan without actor');
76
- }
77
-
78
- if (result.planValidatedStatus !== 'validated') {
79
- process.exit(1);
80
- }
@@ -1,125 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * aifabrix builder passthrough for builder-api (this repo).
4
- * Usage: pnpm run af <subcommand> | npm run af -- <subcommand>
5
- */
6
- import { spawn } from 'node:child_process';
7
- import { readFileSync } from 'node:fs';
8
- import { dirname, join } from 'node:path';
9
- import { fileURLToPath } from 'node:url';
10
- import { resolveAifabrixBin } from './lib/resolve-aifabrix-bin.mjs';
11
-
12
- const AIFABRIX_BIN = resolveAifabrixBin();
13
- const REPO_ROOT = join(dirname(fileURLToPath(import.meta.url)), '../..');
14
-
15
- const USAGE = `Usage: pnpm run af <subcommand>
16
-
17
- Subcommands:
18
- ba-resolve aifabrix resolve builder-api
19
- ba-run aifabrix run builder-api
20
- ba-reload aifabrix run builder-api --reload
21
- ba-logs aifabrix logs builder-api
22
- ba-down aifabrix down-app builder-api
23
- ba-build aifabrix build builder-api
24
- dev-build ba-build then ba-run (local Docker image)
25
- dev-reload Docker live reload (spinner + URL + .temp/dev-reload.log)
26
- dev-promote build --base --from-dev + run --base (tags main + version; TAG=2.52.0 or package.json)
27
- `;
28
-
29
- const COMMANDS = {
30
- 'ba-resolve': [AIFABRIX_BIN, 'resolve', 'builder-api'],
31
- 'ba-run': [AIFABRIX_BIN, 'run', 'builder-api'],
32
- 'ba-reload': [AIFABRIX_BIN, 'run', 'builder-api', '--reload'],
33
- 'ba-logs': [AIFABRIX_BIN, 'logs', 'builder-api'],
34
- 'ba-down': [AIFABRIX_BIN, 'down-app', 'builder-api'],
35
- 'ba-build': [AIFABRIX_BIN, 'build', 'builder-api']
36
- };
37
-
38
- async function runDevBuild() {
39
- await runCommand(COMMANDS['ba-build']);
40
- await runCommand(COMMANDS['ba-run']);
41
- }
42
-
43
- function readPackageVersion() {
44
- try {
45
- const pkg = JSON.parse(readFileSync(join(REPO_ROOT, 'package.json'), 'utf8'));
46
- const version = String(pkg.version || '').trim();
47
- return version || null;
48
- } catch {
49
- return null;
50
- }
51
- }
52
-
53
- function resolvePromoteTag() {
54
- const fromArg = process.argv[3];
55
- const tag = (process.env.TAG || fromArg || readPackageVersion() || '').trim();
56
- if (!tag || tag === 'latest' || tag === 'main') {
57
- return null;
58
- }
59
- return tag;
60
- }
61
-
62
- async function runDevPromote() {
63
- const tag = resolvePromoteTag();
64
- if (!tag) {
65
- throw new Error(
66
- 'dev-promote requires a version tag. Set TAG=x.y.z or ensure package.json has "version".'
67
- );
68
- }
69
- // Promote applies both :main and :<version>; run uses the version tag.
70
- await runCommand([AIFABRIX_BIN, 'build', 'builder-api', '--base', '--from-dev', '--tag', tag]);
71
- await runCommand([AIFABRIX_BIN, 'run', 'builder-api', '--base', '--tag', tag]);
72
- }
73
-
74
- function runCommand(args) {
75
- return new Promise((resolve, reject) => {
76
- const child = spawn(args[0], args.slice(1), { stdio: 'inherit', shell: false });
77
- child.on('error', reject);
78
- child.on('close', (code) => {
79
- if (code === 0) {
80
- resolve();
81
- return;
82
- }
83
- reject(new Error(`${args.join(' ')} exited with code ${code}`));
84
- });
85
- });
86
- }
87
-
88
- async function main() {
89
- const sub = process.argv[2];
90
- if (!sub || sub === '--help' || sub === '-h') {
91
- console.error(USAGE);
92
- process.exit(sub ? 0 : 1);
93
- }
94
- if (sub === 'dev-build') {
95
- await runDevBuild();
96
- return;
97
- }
98
- if (sub === 'dev-reload') {
99
- const { runDevReload } = await import('./lib/dev-reload-core.mjs');
100
- await runDevReload({
101
- appKey: 'builder-api',
102
- displayName: 'Builder API',
103
- portBase: 3005,
104
- healthPath: '/api/v1/builder/health',
105
- apiOnly: true
106
- });
107
- return;
108
- }
109
- if (sub === 'dev-promote') {
110
- await runDevPromote();
111
- return;
112
- }
113
- const args = COMMANDS[sub];
114
- if (!args) {
115
- console.error(`Unknown af subcommand: ${sub}\n`);
116
- console.error(USAGE);
117
- process.exit(2);
118
- }
119
- await runCommand(args);
120
- }
121
-
122
- main().catch((err) => {
123
- console.error(err.message || err);
124
- process.exit(1);
125
- });
@@ -1,32 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Offline pre-commit gate — same as build:ci; logs in .temp/validation/
4
- */
5
- import { spawnSync } from 'node:child_process';
6
- import fs from 'node:fs';
7
- import path from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
-
10
- const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
11
- const logDir = path.join(repoRoot, '.temp', 'validation');
12
- const logFile = path.join(logDir, 'build-ci.log');
13
-
14
- fs.mkdirSync(logDir, { recursive: true });
15
- console.log(`[check-quiet] Running build:ci (logs → ${logFile})`);
16
-
17
- const result = spawnSync('npm', ['run', 'build:ci'], {
18
- cwd: repoRoot,
19
- env: process.env,
20
- encoding: 'utf8'
21
- });
22
-
23
- const output = `${result.stdout || ''}${result.stderr || ''}`;
24
- fs.writeFileSync(logFile, output, 'utf8');
25
-
26
- if (result.status === 0) {
27
- console.log('[check-quiet] ✓ passed');
28
- process.exit(0);
29
- }
30
-
31
- console.error(`[check-quiet] ✗ failed — see ${logFile}`);
32
- process.exit(result.status ?? 1);
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Bootstrap builder repo deps and link local aifabrix CLI from bin/aifabrix.js.
4
- */
5
- import { spawnSync } from 'node:child_process';
6
- import path from 'node:path';
7
- import { fileURLToPath } from 'node:url';
8
-
9
- const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
10
-
11
- /**
12
- * @param {string} label
13
- * @param {string} command
14
- * @param {string[]} args
15
- */
16
- function runStep(label, command, args) {
17
- console.log(`[dev-install] ${label}`);
18
- const result = spawnSync(command, args, {
19
- cwd: repoRoot,
20
- stdio: 'inherit',
21
- env: process.env
22
- });
23
- if (result.status !== 0) {
24
- process.exit(result.status ?? 1);
25
- }
26
- }
27
-
28
- runStep('npm install', 'npm', ['install']);
29
- runStep('link local CLI (install:local)', 'npm', ['run', 'install:local']);
@@ -1,18 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Docker live reload for builder-api — quiet console, logs in .temp/dev-reload.log
4
- *
5
- * Equivalent to: aifabrix resolve builder-api && aifabrix run builder-api --reload
6
- */
7
- import { runDevReload } from './lib/dev-reload-core.mjs';
8
-
9
- runDevReload({
10
- appKey: 'builder-api',
11
- displayName: 'Builder API',
12
- portBase: 3005,
13
- healthPath: '/api/v1/builder/health',
14
- apiOnly: true
15
- }).catch((err) => {
16
- console.error(`[dev-reload] ${err.message || err}`);
17
- process.exit(1);
18
- });