@aifabrix/builder 2.45.0 → 2.45.5

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 (180) hide show
  1. package/.cursor/rules/docs-rules.mdc +3 -1
  2. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  3. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  4. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  5. package/jest.projects.js +44 -1
  6. package/lib/api/agent-metadata-validation.api.js +93 -0
  7. package/lib/api/audit-api-helpers.js +68 -0
  8. package/lib/api/audit.api.js +119 -0
  9. package/lib/api/auth-cache.api.js +44 -0
  10. package/lib/api/certificates.api.js +4 -4
  11. package/lib/api/credential.api.js +2 -2
  12. package/lib/api/dataplane-health.api.js +137 -0
  13. package/lib/api/dataplane-sync.api.js +27 -0
  14. package/lib/api/datasources-core.api.js +21 -18
  15. package/lib/api/datasources-extended.api.js +22 -22
  16. package/lib/api/dimensions.api.js +3 -0
  17. package/lib/api/external-systems.api.js +13 -13
  18. package/lib/api/governance-scenarios.api.js +39 -0
  19. package/lib/api/groups.api.js +79 -0
  20. package/lib/api/index.js +45 -2
  21. package/lib/api/pipeline.api.js +4 -4
  22. package/lib/api/protection.api.js +157 -0
  23. package/lib/api/records-bulk.api.js +30 -0
  24. package/lib/api/records-search-parse.js +49 -0
  25. package/lib/api/records-search.api.js +29 -0
  26. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  27. package/lib/api/types/audit.types.js +72 -0
  28. package/lib/api/types/dataplane-health.types.js +27 -0
  29. package/lib/api/types/dimensions.types.js +2 -0
  30. package/lib/api/types/governance-scenarios.types.js +39 -0
  31. package/lib/api/types/protection.types.js +69 -0
  32. package/lib/api/types/records-bulk.types.js +35 -0
  33. package/lib/api/types/records-search.types.js +28 -0
  34. package/lib/api/user-groups.api.js +50 -0
  35. package/lib/api/users.api.js +95 -0
  36. package/lib/api/validation-run.api.js +3 -3
  37. package/lib/api/validation-runner.js +3 -3
  38. package/lib/api/wizard-platform.api.js +3 -3
  39. package/lib/api/wizard.api.js +21 -21
  40. package/lib/app/deploy.js +34 -19
  41. package/lib/cli/index.js +4 -2
  42. package/lib/cli/infra-guided.js +22 -3
  43. package/lib/cli/setup-app.help.js +50 -2
  44. package/lib/cli/setup-app.js +33 -24
  45. package/lib/cli/setup-app.test-commands.js +80 -21
  46. package/lib/cli/setup-auth.js +30 -3
  47. package/lib/cli/setup-external-system.js +37 -3
  48. package/lib/cli/setup-utility-help-after.js +45 -0
  49. package/lib/cli/setup-utility-resolve.js +2 -2
  50. package/lib/cli/setup-utility.js +99 -81
  51. package/lib/commands/auth-status-dataplane-version.js +231 -0
  52. package/lib/commands/auth-status-display.js +94 -0
  53. package/lib/commands/auth-status.js +70 -6
  54. package/lib/commands/credential-push.js +10 -5
  55. package/lib/commands/datasource-load-export-cli.js +178 -0
  56. package/lib/commands/datasource-test-trust-cli.js +114 -0
  57. package/lib/commands/datasource-unified-test-cli.js +25 -17
  58. package/lib/commands/datasource-unified-test-cli.options.js +18 -3
  59. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  60. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  61. package/lib/commands/datasource.js +68 -1
  62. package/lib/commands/dimension-value.js +43 -13
  63. package/lib/commands/dimension.js +38 -7
  64. package/lib/commands/identity-apply-sync.js +131 -0
  65. package/lib/commands/identity-group-cli.js +146 -0
  66. package/lib/commands/identity-membership-role-cache.js +175 -0
  67. package/lib/commands/identity-shared.js +94 -0
  68. package/lib/commands/identity-user-cli.js +158 -0
  69. package/lib/commands/identity.js +43 -0
  70. package/lib/commands/login.js +46 -16
  71. package/lib/commands/protection-cli-leaves.js +286 -0
  72. package/lib/commands/protection.js +50 -0
  73. package/lib/commands/repair.js +13 -3
  74. package/lib/commands/test-e2e-external.js +40 -9
  75. package/lib/commands/test-governance-cli-options.js +47 -0
  76. package/lib/commands/test-governance-command-action.js +55 -0
  77. package/lib/commands/test-governance-external.js +88 -0
  78. package/lib/commands/test-trust-cli-options.js +32 -0
  79. package/lib/commands/test-trust-command-action.js +118 -0
  80. package/lib/commands/test-trust-external.js +127 -0
  81. package/lib/commands/upload.js +34 -13
  82. package/lib/commands/wizard-core.js +3 -0
  83. package/lib/core/config-device-dataplane.js +185 -0
  84. package/lib/datasource/agent-trust-debug-log.js +45 -0
  85. package/lib/datasource/agent-trust-fetch.js +115 -0
  86. package/lib/datasource/agent-trust-map.js +101 -0
  87. package/lib/datasource/agent-trust-mock.js +44 -0
  88. package/lib/datasource/agent-trust-run.js +93 -0
  89. package/lib/datasource/agent-trust-timeout.js +25 -0
  90. package/lib/datasource/audit-evidence-display.js +80 -0
  91. package/lib/datasource/audit-evidence-extract-debug.js +103 -0
  92. package/lib/datasource/audit-evidence-extract.js +177 -0
  93. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  94. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  95. package/lib/datasource/audit-evidence-poll.js +109 -0
  96. package/lib/datasource/audit-evidence-run.js +177 -0
  97. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  98. package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
  99. package/lib/datasource/audit-evidence-verify.js +108 -0
  100. package/lib/datasource/bulk-loader-run-batches.js +88 -0
  101. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  102. package/lib/datasource/bulk-loader-service.js +127 -0
  103. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  104. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  105. package/lib/datasource/datasource-exporter-service.js +144 -0
  106. package/lib/datasource/datasource-identifier.js +148 -0
  107. package/lib/datasource/datasource-load-export-context.js +92 -0
  108. package/lib/datasource/integration-context.js +6 -4
  109. package/lib/datasource/local-data-paths.js +145 -0
  110. package/lib/datasource/log-cleaner.js +241 -0
  111. package/lib/datasource/log-viewer.js +111 -6
  112. package/lib/datasource/record-file-parser.js +85 -0
  113. package/lib/datasource/record-mapper.js +129 -0
  114. package/lib/datasource/resolve-app.js +74 -55
  115. package/lib/datasource/test-e2e.js +26 -2
  116. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  117. package/lib/datasource/unified-validation-run.js +43 -17
  118. package/lib/datasource/validate.js +37 -20
  119. package/lib/external-system/test-system-level.js +25 -4
  120. package/lib/external-system/test.js +3 -1
  121. package/lib/governance/governance-pack-loader.js +70 -0
  122. package/lib/governance/governance-run-display.js +119 -0
  123. package/lib/identity/identity-apply-core.js +108 -0
  124. package/lib/identity/identity-apply-phases.js +244 -0
  125. package/lib/identity/identity-apply-service.js +77 -0
  126. package/lib/identity/identity-csv-parser.js +114 -0
  127. package/lib/internal/fs-real-sync.js +29 -1
  128. package/lib/protection/auth-context.js +45 -0
  129. package/lib/protection/convert-batch.js +90 -0
  130. package/lib/protection/load.js +41 -0
  131. package/lib/protection/paths.js +158 -0
  132. package/lib/protection/preflight-datasource-ready.js +46 -0
  133. package/lib/protection/protection-create-probe-lines.js +142 -0
  134. package/lib/protection/protection-create-probes.js +95 -0
  135. package/lib/protection/protection-create-scaffold.js +281 -0
  136. package/lib/protection/protection-display-helpers.js +445 -0
  137. package/lib/protection/protection-display.js +215 -0
  138. package/lib/protection/protection-preset-registry.js +97 -0
  139. package/lib/protection/report-exit.js +62 -0
  140. package/lib/protection/resolve.js +202 -0
  141. package/lib/protection/run-commands-validate.js +130 -0
  142. package/lib/protection/run-commands.js +216 -0
  143. package/lib/protection/run-protection-create-helpers.js +134 -0
  144. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  145. package/lib/protection/run-protection-create.js +191 -0
  146. package/lib/protection/scope.js +22 -0
  147. package/lib/protection/sync-after-upload.js +64 -0
  148. package/lib/protection/upload-batch.js +127 -0
  149. package/lib/protection/validate-batch.js +113 -0
  150. package/lib/protection/validate-local.js +65 -0
  151. package/lib/resolvers/dimension-file.js +29 -4
  152. package/lib/schema/external-datasource.schema.json +47 -13
  153. package/lib/schema/flag-map-validation-run.json +2 -2
  154. package/lib/schema/protection.schema.json +374 -0
  155. package/lib/schema/type/credential-field-registry.json +636 -0
  156. package/lib/schema/wizard-config.schema.json +1 -1
  157. package/lib/utils/agent-trust-run-display.js +231 -0
  158. package/lib/utils/agent-trust-run-exit.js +59 -0
  159. package/lib/utils/agent-trust-wait-ui.js +94 -0
  160. package/lib/utils/cli-exit-codes.js +30 -0
  161. package/lib/utils/cli-sync-options.js +33 -0
  162. package/lib/utils/credential-push-ui.js +90 -0
  163. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  164. package/lib/utils/dataplane-cli-version-help.js +74 -0
  165. package/lib/utils/datasource-export-display.js +137 -0
  166. package/lib/utils/datasource-load-display.js +174 -0
  167. package/lib/utils/datasource-load-export-ui.js +120 -0
  168. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  169. package/lib/utils/datasource-test-run-display.js +3 -3
  170. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  171. package/lib/utils/help-builder.js +30 -24
  172. package/lib/utils/manifest-source-emit.js +22 -0
  173. package/lib/utils/semver-compare.js +127 -0
  174. package/lib/utils/upload-pipeline-ui.js +91 -0
  175. package/lib/utils/validation-poll-ui.js +14 -7
  176. package/lib/validation/wizard-config-validator.js +58 -19
  177. package/package.json +1 -1
  178. package/templates/applications/dataplane/env.template +13 -1
  179. package/templates/applications/dataplane/rbac.yaml +4 -0
  180. package/templates/external-system/README.md.hbs +56 -8
@@ -0,0 +1,231 @@
1
+ /**
2
+ * @fileoverview TTY display for agent metadata trust runs (plan 143).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const chalk = require('chalk');
10
+ const logger = require('./logger');
11
+ const { sectionTitle, headerKeyValue, metadata: metaGray } = require('./cli-test-layout-chalk');
12
+ const { statusGlyph } = require('./datasource-test-run-display');
13
+ const { trustDecisionToRowStatus } = require('../datasource/agent-trust-map');
14
+
15
+ const SEP = '────────────────────────────────';
16
+
17
+ /** @type {{ datasource: number, trust: number, conf: number, status: number, cache: number }} */
18
+ const TRUST_TABLE_COLS = {
19
+ datasource: 30,
20
+ trust: 24,
21
+ conf: 6,
22
+ status: 8,
23
+ cache: 8
24
+ };
25
+
26
+ function trustGlyph(trustDecision) {
27
+ return statusGlyph(trustDecisionToRowStatus(trustDecision));
28
+ }
29
+
30
+ function publishGateLine(trustDecision, strict) {
31
+ if (trustDecision === 'notTrusted') return chalk.red('blocked (trustDecision notTrusted)');
32
+ if (strict) {
33
+ return trustDecision === 'trusted'
34
+ ? chalk.green('allowed (strict: trusted)')
35
+ : chalk.yellow('blocked (strict requires trusted)');
36
+ }
37
+ return chalk.green('allowed (warning-only); use --strict to require trusted');
38
+ }
39
+
40
+ function logTrustHeader(run, env) {
41
+ logger.log(SEP);
42
+ logger.log(sectionTitle(`Semantic trust — ${run.datasourceKey}`));
43
+ logger.log(headerKeyValue('Environment:', env));
44
+ logger.log(headerKeyValue('System:', run.systemKey || '—'));
45
+ logger.log(SEP);
46
+ logger.log(metaGray(' Layer checked: business metadata (404.5 agent validation)'));
47
+ logger.log(metaGray(' Not checked here: vendor connectivity, sync, record counts (use test-e2e)'));
48
+ logger.log('');
49
+ }
50
+
51
+ function logTrustSummaryBlock(run) {
52
+ const confPct = Math.round((run.confidence || 0) * 100);
53
+ logger.log(
54
+ headerKeyValue(
55
+ 'Trust:',
56
+ `${trustGlyph(run.trustDecision)} ${run.trustDecision} · confidence ${confPct}% · ${run.validationStatus}`
57
+ )
58
+ );
59
+ if (!run.validatedAt) return;
60
+ const hashShort = run.inputHash ? `${String(run.inputHash).slice(0, 8)}…` : '—';
61
+ logger.log(
62
+ metaGray(
63
+ ` Validated: ${run.validatedAt} · inputHash ${hashShort} · cache: ${run.cacheHit ? 'hit' : 'miss'}`
64
+ )
65
+ );
66
+ }
67
+
68
+ function logTrustWarningsAndFindings(run, opts) {
69
+ if (run.summary) {
70
+ logger.log('');
71
+ logger.log(chalk.white(' Summary'));
72
+ logger.log(` ${run.summary}`);
73
+ }
74
+ const warnings = Array.isArray(run.highLevelWarnings) ? run.highLevelWarnings : [];
75
+ const findings = Array.isArray(run.findings) ? run.findings : [];
76
+ const showVerboseFindings = opts.verbose === true && findings.length > 0;
77
+ if (warnings.length && !showVerboseFindings) {
78
+ logger.log('');
79
+ logger.log(chalk.yellow(' Warnings (high level)'));
80
+ warnings.forEach(w => logger.log(` • ${w}`));
81
+ }
82
+ if (!showVerboseFindings) return;
83
+ logger.log('');
84
+ logger.log(chalk.white(' Findings (verbose, max 10)'));
85
+ findings.slice(0, 10).forEach(f => {
86
+ logger.log(` • [${f.severity || 'info'}] ${f.code || 'FINDING'}: ${f.message || ''}`);
87
+ });
88
+ }
89
+
90
+ function logTrustFooter(run, opts) {
91
+ logger.log('');
92
+ logger.log(metaGray(' ── Integration reality (informative) ──'));
93
+ logger.log(metaGray(` Local manifest: ${opts.noSync ? 'not uploaded (--no-sync)' : 'uploaded before run'}`));
94
+ logger.log(metaGray(` Publish gate: ${publishGateLine(run.trustDecision, opts.strict === true)}`));
95
+ logger.log(SEP);
96
+ }
97
+
98
+ function displayAgentTrustRunTTY(run, opts = {}) {
99
+ if (!run || opts.json === true) return;
100
+ const env = opts.environment ? String(opts.environment) : 'dev';
101
+ logTrustHeader(run, env);
102
+ logTrustSummaryBlock(run);
103
+ logTrustWarningsAndFindings(run, opts);
104
+ logTrustFooter(run, opts);
105
+ }
106
+
107
+ function trustCacheLabel(trustRun) {
108
+ if (!trustRun || typeof trustRun !== 'object') return '—';
109
+ if (trustRun.readLatest === true) return 'latest';
110
+ if (trustRun.cacheHit === true) return 'hit';
111
+ if (trustRun.cacheHit === false) return 'miss';
112
+ return '—';
113
+ }
114
+
115
+ /**
116
+ * @param {boolean} showCache
117
+ * @returns {number}
118
+ */
119
+ function trustTableLineWidth(showCache) {
120
+ const { datasource, trust, conf, status, cache } = TRUST_TABLE_COLS;
121
+ let w = 2 + datasource + 1 + trust + 1 + conf + 1 + status;
122
+ if (showCache) w += 1 + cache;
123
+ return w;
124
+ }
125
+
126
+ /**
127
+ * @param {string} key
128
+ * @returns {string}
129
+ */
130
+ function formatTrustTableDatasourceCol(key) {
131
+ return String(key || '').padEnd(TRUST_TABLE_COLS.datasource).slice(0, TRUST_TABLE_COLS.datasource);
132
+ }
133
+
134
+ /**
135
+ * @param {Object|null|undefined} tr
136
+ * @returns {string}
137
+ */
138
+ function formatTrustTableTrustCol(tr) {
139
+ const w = TRUST_TABLE_COLS.trust;
140
+ if (!tr || !tr.trustDecision) return '—'.padEnd(w);
141
+ const decision = String(tr.trustDecision);
142
+ const cell = `${trustGlyph(decision)} ${decision}`;
143
+ return cell.length > w ? cell.slice(0, w) : cell.padEnd(w);
144
+ }
145
+
146
+ /**
147
+ * @param {Object|null|undefined} tr
148
+ * @returns {string}
149
+ */
150
+ function formatTrustTableConfCol(tr) {
151
+ const w = TRUST_TABLE_COLS.conf;
152
+ if (!tr || typeof tr.confidence !== 'number') return '—'.padStart(w);
153
+ return `${Math.round(tr.confidence * 100)}%`.padStart(w);
154
+ }
155
+
156
+ /**
157
+ * @param {Object|null|undefined} tr
158
+ * @param {Object} row
159
+ * @returns {string}
160
+ */
161
+ function formatTrustTableStatusCol(tr, row) {
162
+ const w = TRUST_TABLE_COLS.status;
163
+ const raw = tr ? String(tr.validationStatus || '—') : row.error || 'fail';
164
+ return raw.padEnd(w).slice(0, w);
165
+ }
166
+
167
+ /**
168
+ * @param {boolean} showCache
169
+ */
170
+ function logSystemTrustTableHeader(showCache) {
171
+ const { datasource, trust, conf, status, cache } = TRUST_TABLE_COLS;
172
+ let header = ` ${'Datasource'.padEnd(datasource)} ${'Trust'.padEnd(trust)} ${'Conf.'.padStart(conf)} ${'Status'.padEnd(status)}`;
173
+ if (showCache) header += ` ${'Cache'.padEnd(cache)}`;
174
+ logger.log(chalk.white(header));
175
+ logger.log(chalk.gray(` ${'─'.repeat(trustTableLineWidth(showCache))}`));
176
+ }
177
+
178
+ /**
179
+ * @param {Object} row
180
+ * @param {boolean} showCache
181
+ * @returns {string}
182
+ */
183
+ function formatTrustTableRow(row, showCache) {
184
+ const tr = row.trustRun;
185
+ let line = ` ${formatTrustTableDatasourceCol(row.key)} ${formatTrustTableTrustCol(tr)} ${formatTrustTableConfCol(tr)} ${formatTrustTableStatusCol(tr, row)}`;
186
+ if (showCache) {
187
+ line += ` ${trustCacheLabel(tr).padEnd(TRUST_TABLE_COLS.cache).slice(0, TRUST_TABLE_COLS.cache)}`;
188
+ }
189
+ return line;
190
+ }
191
+
192
+ function logSystemTrustTable(list, opts = {}) {
193
+ const showCache = opts.showCache === true;
194
+ logSystemTrustTableHeader(showCache);
195
+ for (const row of list) {
196
+ logger.log(formatTrustTableRow(row, showCache));
197
+ }
198
+ }
199
+
200
+ function displaySystemTrustRollupTTY(systemKey, rows, opts = {}) {
201
+ if (opts.json === true) return;
202
+ const list = Array.isArray(rows) ? rows : [];
203
+ logger.log(SEP);
204
+ logger.log(sectionTitle(`Semantic trust — system ${systemKey} (${list.length} datasources)`));
205
+ const { deriveSystemStatus } = require('./external-system-system-test-tty');
206
+ const worst = deriveSystemStatus(
207
+ list.map(r => ({
208
+ success: r.success !== false,
209
+ datasourceTestRun: {
210
+ status: r.trustRun ? trustDecisionToRowStatus(r.trustRun.trustDecision) : 'fail'
211
+ }
212
+ }))
213
+ );
214
+ logger.log(
215
+ headerKeyValue('System trust:', `${statusGlyph(worst)} ${worst} (worst-of rollup)`)
216
+ );
217
+ logger.log('');
218
+ logSystemTrustTable(list, opts);
219
+ logger.log('');
220
+ logger.log(metaGray(' ── What this run proved ──'));
221
+ logger.log(metaGray(` ✔ Semantic metadata reviewed for ${list.length} datasource(s) on dataplane`));
222
+ logger.log(metaGray(' ✖ Did not call external APIs or run CIP (not E2E)'));
223
+ logger.log(SEP);
224
+ }
225
+
226
+ module.exports = {
227
+ displayAgentTrustRunTTY,
228
+ displaySystemTrustRollupTTY,
229
+ formatTrustTableRow,
230
+ TRUST_TABLE_COLS
231
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Exit codes for agent metadata trust CLI runs (plan 143).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { trustDecisionToRowStatus } = require('../datasource/agent-trust-map');
10
+ const { deriveSystemStatus } = require('./external-system-system-test-tty');
11
+ const { computeExitCodeFromDatasourceTestRun } = require('./datasource-test-run-exit');
12
+
13
+ /**
14
+ * @param {Object|null|undefined} run
15
+ * @param {Object} [opts]
16
+ * @param {boolean} [opts.warningsAsErrors]
17
+ * @param {boolean} [opts.strict]
18
+ * @returns {number}
19
+ */
20
+ function computeExitCodeFromTrustRun(run, opts = {}) {
21
+ if (!run || typeof run !== 'object') return 3;
22
+ const td = run.trustDecision;
23
+ if (run.validationStatus === 'failed' || td === 'notTrusted') return 1;
24
+ if (opts.strict === true && td !== 'trusted') return 1;
25
+ if (opts.warningsAsErrors === true && td === 'usableWithWarnings') return 1;
26
+ if (td === 'trusted' || td === 'usableWithWarnings' || td === 'pending') return 0;
27
+ return 3;
28
+ }
29
+
30
+ /**
31
+ * @param {Array<{ success?: boolean, trustRun?: Object|null }>} rows
32
+ * @param {Object} [opts]
33
+ * @returns {number}
34
+ */
35
+ function computeSystemExitCodeFromTrustRows(rows, opts = {}) {
36
+ const list = Array.isArray(rows) ? rows : [];
37
+ let worst = 0;
38
+ for (const row of list) {
39
+ const code = computeExitCodeFromTrustRun(row && row.trustRun, opts);
40
+ if (code === 3) return 3;
41
+ if (code > worst) worst = code;
42
+ }
43
+ if (worst > 0) return worst;
44
+ const synthetic = list.map(r => {
45
+ const tr = r && r.trustRun;
46
+ const st = tr ? trustDecisionToRowStatus(tr.trustDecision) : 'fail';
47
+ return { success: st !== 'fail', datasourceTestRun: { status: st } };
48
+ });
49
+ const rollup = deriveSystemStatus(synthetic);
50
+ return computeExitCodeFromDatasourceTestRun(
51
+ { status: rollup },
52
+ { warningsAsErrors: opts.warningsAsErrors === true }
53
+ );
54
+ }
55
+
56
+ module.exports = {
57
+ computeExitCodeFromTrustRun,
58
+ computeSystemExitCodeFromTrustRows
59
+ };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * TTY ora spinner for slow agent metadata validation POST (non-cached path).
3
+ *
4
+ * @fileoverview Agent trust wait presentation (aligned with validation-poll-ui)
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const chalk = require('chalk');
12
+ const logger = require('./logger');
13
+
14
+ function shouldUseAgentTrustWaitSpinner() {
15
+ return Boolean(process && process.stdout && process.stdout.isTTY);
16
+ }
17
+
18
+ /**
19
+ * @param {string} [datasourceKey]
20
+ * @param {number} deadlineMs
21
+ * @returns {string}
22
+ */
23
+ function buildAgentTrustWaitSpinnerText(datasourceKey, deadlineMs) {
24
+ const remainingSec = Math.max(0, Math.ceil((deadlineMs - Date.now()) / 1000));
25
+ const key =
26
+ datasourceKey && String(datasourceKey).trim() ? String(datasourceKey).trim() : 'datasource';
27
+ return `Waiting for semantic trust validation… ${key} (~${remainingSec}s left)`;
28
+ }
29
+
30
+ /**
31
+ * Run a blocking validate POST behind a TTY spinner (skipped when not a TTY).
32
+ *
33
+ * @async
34
+ * @param {Function} work - Zero-arg async function performing the HTTP call
35
+ * @param {Object} opts
36
+ * @param {string} [opts.datasourceKey]
37
+ * @param {number} opts.timeoutMs
38
+ * @returns {Promise<*>}
39
+ */
40
+ async function runWithAgentTrustWaitSpinner(work, opts = {}) {
41
+ const timeoutMs =
42
+ Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0 ? opts.timeoutMs : 120000;
43
+ const deadlineMs = Date.now() + timeoutMs;
44
+ const datasourceKey = opts.datasourceKey;
45
+
46
+ if (!shouldUseAgentTrustWaitSpinner()) {
47
+ return work();
48
+ }
49
+
50
+ const ora = require('ora');
51
+ const spinner = ora({
52
+ text: buildAgentTrustWaitSpinnerText(datasourceKey, deadlineMs),
53
+ spinner: 'dots'
54
+ }).start();
55
+
56
+ const tick = setInterval(() => {
57
+ spinner.text = buildAgentTrustWaitSpinnerText(datasourceKey, deadlineMs);
58
+ }, 1000);
59
+
60
+ try {
61
+ return await work();
62
+ } finally {
63
+ clearInterval(tick);
64
+ spinner.stop();
65
+ }
66
+ }
67
+
68
+ const NON_TTY_LOG_MS = 5000;
69
+
70
+ /**
71
+ * Optional one-line hint on non-TTY before a slow validate (throttled by caller usage).
72
+ *
73
+ * @param {string} [datasourceKey]
74
+ * @param {number} timeoutMs
75
+ */
76
+ function logAgentTrustWaitHintOnce(datasourceKey, timeoutMs) {
77
+ if (shouldUseAgentTrustWaitSpinner()) return;
78
+ const budgetSec = Math.max(1, Math.ceil(timeoutMs / 1000));
79
+ const key =
80
+ datasourceKey && String(datasourceKey).trim() ? String(datasourceKey).trim() : 'datasource';
81
+ logger.log(
82
+ chalk.gray(
83
+ `Waiting for semantic trust validation… ${key} (may take up to ~${budgetSec}s; not cached)`
84
+ )
85
+ );
86
+ }
87
+
88
+ module.exports = {
89
+ shouldUseAgentTrustWaitSpinner,
90
+ buildAgentTrustWaitSpinnerText,
91
+ runWithAgentTrustWaitSpinner,
92
+ logAgentTrustWaitHintOnce,
93
+ NON_TTY_LOG_MS
94
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Canonical Builder CLI exit codes for scriptable commands.
3
+ *
4
+ * Documented in `docs/commands/authentication.md`. Use in
5
+ * `aifabrix auth status --validate` and any future `--validate`-style flag.
6
+ *
7
+ * @fileoverview Exit-code constants for scriptable Builder CLI commands
8
+ * @author AI Fabrix Team
9
+ * @version 2.0.0
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ /** Success. */
15
+ const EXIT_OK = 0;
16
+
17
+ /** Not authenticated / invalid token. */
18
+ const EXIT_NOT_AUTHENTICATED = 1;
19
+
20
+ /**
21
+ * Authenticated but installed Builder CLI version is older than the dataplane
22
+ * minimum advertised by `GET /api/v1/health → minBuilderCliVersion` (plan 403.0).
23
+ */
24
+ const EXIT_CLI_VERSION_INCOMPATIBLE = 3;
25
+
26
+ module.exports = {
27
+ EXIT_OK,
28
+ EXIT_NOT_AUTHENTICATED,
29
+ EXIT_CLI_VERSION_INCOMPATIBLE
30
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @fileoverview Detect skip-sync from Commander options and raw argv (--no-sync → sync: false).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * True when the user passed `--no-sync` or Commander set `sync: false` / `noSync: true`.
11
+ * Do not use for `protection upload --no-sync` (post-upload datasource sync only).
12
+ *
13
+ * @param {Object|null|undefined} options - Commander-parsed options
14
+ * @param {import('commander').Command} [cmd] - Commander command (for rawArgs fallback)
15
+ * @returns {boolean}
16
+ */
17
+ function cliOptsSkipSync(options, cmd) {
18
+ if (!options || typeof options !== 'object') {
19
+ return false;
20
+ }
21
+ if (options.noSync === true) {
22
+ return true;
23
+ }
24
+ if (options.sync === false) {
25
+ return true;
26
+ }
27
+ const raw = cmd && Array.isArray(cmd.rawArgs) ? cmd.rawArgs : [];
28
+ return raw.includes('--no-sync');
29
+ }
30
+
31
+ module.exports = {
32
+ cliOptsSkipSync
33
+ };
@@ -0,0 +1,90 @@
1
+ /**
2
+ * @fileoverview Progress line + optional in-place spinner for credential secret push.
3
+ * @author AI Fabrix Team
4
+ * @version 1.2.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const chalk = require('chalk');
10
+ const logger = require('./logger');
11
+ const { formatProgress } = require('./cli-test-layout-chalk');
12
+
13
+ /**
14
+ * @param {Object} [options]
15
+ * @param {boolean} [options.json] - When true, skip progress line and spinner
16
+ * @returns {boolean}
17
+ */
18
+ function shouldShowCredentialPushProgress(options = {}) {
19
+ return options.json !== true;
20
+ }
21
+
22
+ /**
23
+ * @param {Object} [options]
24
+ * @returns {boolean}
25
+ */
26
+ function shouldUseCredentialPushSpinner(options = {}) {
27
+ if (!shouldShowCredentialPushProgress(options)) {
28
+ return false;
29
+ }
30
+ return Boolean(process && process.stdout && process.stdout.isTTY);
31
+ }
32
+
33
+ /**
34
+ * @param {string} systemKey
35
+ * @returns {string}
36
+ */
37
+ function buildCredentialPushSpinnerLabel(systemKey) {
38
+ const key = systemKey && String(systemKey).trim() ? String(systemKey).trim() : 'integration';
39
+ return `Pushing credential secrets for ${key}…`;
40
+ }
41
+
42
+ /**
43
+ * @param {string} systemKey
44
+ * @returns {string}
45
+ */
46
+ function buildCredentialPushSpinnerText(systemKey) {
47
+ return formatProgress(buildCredentialPushSpinnerLabel(systemKey));
48
+ }
49
+
50
+ /**
51
+ * Run credential push work with visible progress (⏳ line or ora with label on TTY).
52
+ *
53
+ * @async
54
+ * @param {Function} work - Zero-arg async function performing the push
55
+ * @param {Object} [opts]
56
+ * @param {string} [opts.systemKey]
57
+ * @param {boolean} [opts.json]
58
+ * @returns {Promise<*>}
59
+ */
60
+ async function runWithCredentialPushSpinner(work, opts = {}) {
61
+ if (!shouldShowCredentialPushProgress(opts)) {
62
+ return work();
63
+ }
64
+
65
+ if (!shouldUseCredentialPushSpinner(opts)) {
66
+ logger.log(buildCredentialPushSpinnerText(opts.systemKey));
67
+ return work();
68
+ }
69
+
70
+ const ora = require('ora');
71
+ const label = buildCredentialPushSpinnerLabel(opts.systemKey);
72
+ const spinner = ora({
73
+ text: chalk.white(label),
74
+ spinner: 'dots'
75
+ }).start();
76
+
77
+ try {
78
+ return await work();
79
+ } finally {
80
+ spinner.stop();
81
+ }
82
+ }
83
+
84
+ module.exports = {
85
+ shouldShowCredentialPushProgress,
86
+ shouldUseCredentialPushSpinner,
87
+ buildCredentialPushSpinnerLabel,
88
+ buildCredentialPushSpinnerText,
89
+ runWithCredentialPushSpinner
90
+ };