@aifabrix/builder 2.52.1 → 2.53.1

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 (225) 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/schema/external-datasource.schema.json +13 -4
  59. package/lib/utils/compose-generator.js +10 -1
  60. package/lib/utils/compose-traefik-extra-routes.js +107 -0
  61. package/lib/utils/docker-build.js +2 -2
  62. package/lib/utils/help-builder.js +2 -1
  63. package/lib/utils/promote-dev-docker-image.js +15 -10
  64. package/package.json +14 -16
  65. package/templates/README.md +12 -1
  66. package/templates/applications/dataplane/application.yaml +8 -1
  67. package/templates/applications/dataplane/env.template +1 -1
  68. package/templates/applications/miso-controller/application.yaml +2 -1
  69. package/templates/applications/miso-controller/rbac.yaml +1 -0
  70. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +6 -2
  71. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +8 -5
  72. package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
  73. package/templates/channels/microsoft-copilot/install.template.md.hbs +74 -22
  74. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +29 -14
  75. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +6 -2
  76. package/templates/python/docker-compose.hbs +36 -0
  77. package/templates/typescript/docker-compose.hbs +36 -0
  78. package/.cursor/plans/Archive/157.1-security-quality-violations-by-type.csv +0 -374
  79. package/.cursor/process/README.md +0 -9
  80. package/.cursor/rules/anchor-docs.mdc +0 -15
  81. package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
  82. package/.cursor/rules/cli-layout.mdc +0 -81
  83. package/.cursor/rules/cli-product-neutral.mdc +0 -43
  84. package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
  85. package/.cursor/rules/docs-rules.mdc +0 -32
  86. package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
  87. package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
  88. package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
  89. package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
  90. package/.cursor/rules/project-rules.mdc +0 -913
  91. package/.cursor/skills/README.md +0 -15
  92. package/.dockerignore +0 -52
  93. package/.eslintignore +0 -22
  94. package/.markdownlint.json +0 -14
  95. package/anchor-docs/README.md +0 -10
  96. package/anchor-docs/_TEMPLATE +0 -24
  97. package/babel.config.js +0 -6
  98. package/bin/builder-api-cleanup.js +0 -26
  99. package/bin/builder-api-nest.js +0 -10
  100. package/bin/builder-api-spike.js +0 -19
  101. package/enterprise-knowledge/README.md +0 -50
  102. package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
  103. package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
  104. package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
  105. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
  106. package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
  107. package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
  108. package/integration/README.md +0 -81
  109. package/integration/github/README.md +0 -53
  110. package/integration/github/application.json +0 -21
  111. package/integration/github/deploy.js +0 -72
  112. package/integration/github/env.template +0 -11
  113. package/integration/github/github-datasource-issue-comments.json +0 -239
  114. package/integration/github/github-datasource-issues.json +0 -399
  115. package/integration/github/github-datasource-repository.json +0 -354
  116. package/integration/github/github-deploy.json +0 -1202
  117. package/integration/github/github-system.json +0 -82
  118. package/integration/hubspot-test/README.md +0 -159
  119. package/integration/hubspot-test/application.json +0 -54
  120. package/integration/hubspot-test/companies.json +0 -2048
  121. package/integration/hubspot-test/create-hubspot.js +0 -523
  122. package/integration/hubspot-test/env.template +0 -4
  123. package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
  124. package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
  125. package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
  126. package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
  127. package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
  128. package/integration/hubspot-test/hubspot-test-system.json +0 -74
  129. package/integration/hubspot-test/rbac.json +0 -166
  130. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
  131. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
  132. package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
  133. package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
  134. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
  135. package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
  136. package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
  137. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
  138. package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
  139. package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
  140. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
  141. package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
  142. package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
  143. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
  144. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
  145. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
  146. package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
  147. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
  148. package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
  149. package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
  150. package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
  151. package/integration/hubspot-test/test-dataplane-down.js +0 -209
  152. package/integration/hubspot-test/test.js +0 -1588
  153. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
  154. package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
  155. package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
  156. package/integration/roundtrip-test-local/README.md +0 -143
  157. package/integration/roundtrip-test-local/application.yaml +0 -13
  158. package/integration/roundtrip-test-local/env.template +0 -15
  159. package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
  160. package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
  161. package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
  162. package/integration/roundtrip-test-local2/README.md +0 -143
  163. package/integration/roundtrip-test-local2/application.yaml +0 -13
  164. package/integration/roundtrip-test-local2/env.template +0 -15
  165. package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
  166. package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
  167. package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
  168. package/integration/test/wizard.yaml +0 -8
  169. package/jest.config.coverage.js +0 -37
  170. package/jest.config.default.js +0 -11
  171. package/jest.config.integration.fixtures.js +0 -22
  172. package/jest.config.integration.js +0 -33
  173. package/jest.config.isolated.js +0 -11
  174. package/jest.config.manual.js +0 -30
  175. package/jest.global-live-fabrix-hooks.js +0 -36
  176. package/jest.isolated-projects.js +0 -283
  177. package/jest.projects.js +0 -79
  178. package/lib/integration-definition/openapi-enrichment/hubspot-crm-companies.json +0 -205
  179. package/packages/builder-api/README.md +0 -120
  180. package/packages/builder-api/package.json +0 -30
  181. package/packages/builder-api/src/app.module.ts +0 -7
  182. package/packages/builder-api/src/auth/auth.module.ts +0 -5
  183. package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
  184. package/packages/builder-api/src/main.ts +0 -16
  185. package/packages/builder-api/tsconfig.json +0 -15
  186. package/scripts/check-builder-api-architecture-grep.js +0 -79
  187. package/scripts/check-datasource-test-run-schema-sync.js +0 -34
  188. package/scripts/ci-fix.sh +0 -19
  189. package/scripts/ci-simulate.sh +0 -19
  190. package/scripts/diagnose-cli.js +0 -150
  191. package/scripts/docker_image_content_gate.js +0 -47
  192. package/scripts/docker_image_content_gate.sh +0 -5
  193. package/scripts/export-builder-api-evidence.js +0 -262
  194. package/scripts/install-local.js +0 -490
  195. package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
  196. package/scripts/lib/builder-api-docker-staging-core.js +0 -183
  197. package/scripts/lib/docker-image-content-gate-core.js +0 -166
  198. package/scripts/lib/plan-actor.js +0 -109
  199. package/scripts/lib/plan-config.js +0 -20
  200. package/scripts/lib/plan-gates.js +0 -154
  201. package/scripts/lib/plan-meta.js +0 -104
  202. package/scripts/lib/plan-parse.js +0 -162
  203. package/scripts/lib/plan-prevalidate-gates.js +0 -337
  204. package/scripts/lib/plan-run-core.js +0 -125
  205. package/scripts/lib/plan-run-report.js +0 -119
  206. package/scripts/plan-approve.js +0 -24
  207. package/scripts/plan-archive.js +0 -49
  208. package/scripts/plan-run.js +0 -13
  209. package/scripts/plan-set-actor.js +0 -21
  210. package/scripts/plan-validate.js +0 -80
  211. package/scripts/pnpm/af.mjs +0 -125
  212. package/scripts/pnpm/check-quiet.mjs +0 -32
  213. package/scripts/pnpm/dev-install.mjs +0 -29
  214. package/scripts/pnpm/dev-reload.mjs +0 -18
  215. package/scripts/pnpm/help.mjs +0 -55
  216. package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
  217. package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
  218. package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
  219. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
  220. package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
  221. package/scripts/pnpm/lib/spinner.mjs +0 -42
  222. package/scripts/pnpm-global-remove.js +0 -48
  223. package/scripts/stage_builder_api_for_docker.js +0 -65
  224. package/scripts/sync-builder-api-template.js +0 -44
  225. 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
- });