@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.
- package/.cursor/rules/docs-rules.mdc +3 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
- package/jest.projects.js +44 -1
- package/lib/api/agent-metadata-validation.api.js +93 -0
- package/lib/api/audit-api-helpers.js +68 -0
- package/lib/api/audit.api.js +119 -0
- package/lib/api/auth-cache.api.js +44 -0
- package/lib/api/certificates.api.js +4 -4
- package/lib/api/credential.api.js +2 -2
- package/lib/api/dataplane-health.api.js +137 -0
- package/lib/api/dataplane-sync.api.js +27 -0
- package/lib/api/datasources-core.api.js +21 -18
- package/lib/api/datasources-extended.api.js +22 -22
- package/lib/api/dimensions.api.js +3 -0
- package/lib/api/external-systems.api.js +13 -13
- package/lib/api/governance-scenarios.api.js +39 -0
- package/lib/api/groups.api.js +79 -0
- package/lib/api/index.js +45 -2
- package/lib/api/pipeline.api.js +4 -4
- package/lib/api/protection.api.js +157 -0
- package/lib/api/records-bulk.api.js +30 -0
- package/lib/api/records-search-parse.js +49 -0
- package/lib/api/records-search.api.js +29 -0
- package/lib/api/types/agent-metadata-validation.types.js +67 -0
- package/lib/api/types/audit.types.js +72 -0
- package/lib/api/types/dataplane-health.types.js +27 -0
- package/lib/api/types/dimensions.types.js +2 -0
- package/lib/api/types/governance-scenarios.types.js +39 -0
- package/lib/api/types/protection.types.js +69 -0
- package/lib/api/types/records-bulk.types.js +35 -0
- package/lib/api/types/records-search.types.js +28 -0
- package/lib/api/user-groups.api.js +50 -0
- package/lib/api/users.api.js +95 -0
- package/lib/api/validation-run.api.js +3 -3
- package/lib/api/validation-runner.js +3 -3
- package/lib/api/wizard-platform.api.js +3 -3
- package/lib/api/wizard.api.js +21 -21
- package/lib/app/deploy.js +34 -19
- package/lib/cli/index.js +4 -2
- package/lib/cli/infra-guided.js +22 -3
- package/lib/cli/setup-app.help.js +50 -2
- package/lib/cli/setup-app.js +33 -24
- package/lib/cli/setup-app.test-commands.js +80 -21
- package/lib/cli/setup-auth.js +30 -3
- package/lib/cli/setup-external-system.js +37 -3
- package/lib/cli/setup-utility-help-after.js +45 -0
- package/lib/cli/setup-utility-resolve.js +2 -2
- package/lib/cli/setup-utility.js +99 -81
- package/lib/commands/auth-status-dataplane-version.js +231 -0
- package/lib/commands/auth-status-display.js +94 -0
- package/lib/commands/auth-status.js +70 -6
- package/lib/commands/credential-push.js +10 -5
- package/lib/commands/datasource-load-export-cli.js +178 -0
- package/lib/commands/datasource-test-trust-cli.js +114 -0
- package/lib/commands/datasource-unified-test-cli.js +25 -17
- package/lib/commands/datasource-unified-test-cli.options.js +18 -3
- package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
- package/lib/commands/datasource-verify-audit-cli.js +96 -0
- package/lib/commands/datasource.js +68 -1
- package/lib/commands/dimension-value.js +43 -13
- package/lib/commands/dimension.js +38 -7
- package/lib/commands/identity-apply-sync.js +131 -0
- package/lib/commands/identity-group-cli.js +146 -0
- package/lib/commands/identity-membership-role-cache.js +175 -0
- package/lib/commands/identity-shared.js +94 -0
- package/lib/commands/identity-user-cli.js +158 -0
- package/lib/commands/identity.js +43 -0
- package/lib/commands/login.js +46 -16
- package/lib/commands/protection-cli-leaves.js +286 -0
- package/lib/commands/protection.js +50 -0
- package/lib/commands/repair.js +13 -3
- package/lib/commands/test-e2e-external.js +40 -9
- package/lib/commands/test-governance-cli-options.js +47 -0
- package/lib/commands/test-governance-command-action.js +55 -0
- package/lib/commands/test-governance-external.js +88 -0
- package/lib/commands/test-trust-cli-options.js +32 -0
- package/lib/commands/test-trust-command-action.js +118 -0
- package/lib/commands/test-trust-external.js +127 -0
- package/lib/commands/upload.js +34 -13
- package/lib/commands/wizard-core.js +3 -0
- package/lib/core/config-device-dataplane.js +185 -0
- package/lib/datasource/agent-trust-debug-log.js +45 -0
- package/lib/datasource/agent-trust-fetch.js +115 -0
- package/lib/datasource/agent-trust-map.js +101 -0
- package/lib/datasource/agent-trust-mock.js +44 -0
- package/lib/datasource/agent-trust-run.js +93 -0
- package/lib/datasource/agent-trust-timeout.js +25 -0
- package/lib/datasource/audit-evidence-display.js +80 -0
- package/lib/datasource/audit-evidence-extract-debug.js +103 -0
- package/lib/datasource/audit-evidence-extract.js +177 -0
- package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
- package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
- package/lib/datasource/audit-evidence-poll.js +109 -0
- package/lib/datasource/audit-evidence-run.js +177 -0
- package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
- package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
- package/lib/datasource/audit-evidence-verify.js +108 -0
- package/lib/datasource/bulk-loader-run-batches.js +88 -0
- package/lib/datasource/bulk-loader-service-retry.js +52 -0
- package/lib/datasource/bulk-loader-service.js +127 -0
- package/lib/datasource/capability/run-capability-dimension.js +2 -1
- package/lib/datasource/datasource-exporter-resolve.js +82 -0
- package/lib/datasource/datasource-exporter-service.js +144 -0
- package/lib/datasource/datasource-identifier.js +148 -0
- package/lib/datasource/datasource-load-export-context.js +92 -0
- package/lib/datasource/integration-context.js +6 -4
- package/lib/datasource/local-data-paths.js +145 -0
- package/lib/datasource/log-cleaner.js +241 -0
- package/lib/datasource/log-viewer.js +111 -6
- package/lib/datasource/record-file-parser.js +85 -0
- package/lib/datasource/record-mapper.js +129 -0
- package/lib/datasource/resolve-app.js +74 -55
- package/lib/datasource/test-e2e.js +26 -2
- package/lib/datasource/unified-validation-run-resolve.js +45 -12
- package/lib/datasource/unified-validation-run.js +43 -17
- package/lib/datasource/validate.js +37 -20
- package/lib/external-system/test-system-level.js +25 -4
- package/lib/external-system/test.js +3 -1
- package/lib/governance/governance-pack-loader.js +70 -0
- package/lib/governance/governance-run-display.js +119 -0
- package/lib/identity/identity-apply-core.js +108 -0
- package/lib/identity/identity-apply-phases.js +244 -0
- package/lib/identity/identity-apply-service.js +77 -0
- package/lib/identity/identity-csv-parser.js +114 -0
- package/lib/internal/fs-real-sync.js +29 -1
- package/lib/protection/auth-context.js +45 -0
- package/lib/protection/convert-batch.js +90 -0
- package/lib/protection/load.js +41 -0
- package/lib/protection/paths.js +158 -0
- package/lib/protection/preflight-datasource-ready.js +46 -0
- package/lib/protection/protection-create-probe-lines.js +142 -0
- package/lib/protection/protection-create-probes.js +95 -0
- package/lib/protection/protection-create-scaffold.js +281 -0
- package/lib/protection/protection-display-helpers.js +445 -0
- package/lib/protection/protection-display.js +215 -0
- package/lib/protection/protection-preset-registry.js +97 -0
- package/lib/protection/report-exit.js +62 -0
- package/lib/protection/resolve.js +202 -0
- package/lib/protection/run-commands-validate.js +130 -0
- package/lib/protection/run-commands.js +216 -0
- package/lib/protection/run-protection-create-helpers.js +134 -0
- package/lib/protection/run-protection-create-probes-flow.js +43 -0
- package/lib/protection/run-protection-create.js +191 -0
- package/lib/protection/scope.js +22 -0
- package/lib/protection/sync-after-upload.js +64 -0
- package/lib/protection/upload-batch.js +127 -0
- package/lib/protection/validate-batch.js +113 -0
- package/lib/protection/validate-local.js +65 -0
- package/lib/resolvers/dimension-file.js +29 -4
- package/lib/schema/external-datasource.schema.json +47 -13
- package/lib/schema/flag-map-validation-run.json +2 -2
- package/lib/schema/protection.schema.json +374 -0
- package/lib/schema/type/credential-field-registry.json +636 -0
- package/lib/schema/wizard-config.schema.json +1 -1
- package/lib/utils/agent-trust-run-display.js +231 -0
- package/lib/utils/agent-trust-run-exit.js +59 -0
- package/lib/utils/agent-trust-wait-ui.js +94 -0
- package/lib/utils/cli-exit-codes.js +30 -0
- package/lib/utils/cli-sync-options.js +33 -0
- package/lib/utils/credential-push-ui.js +90 -0
- package/lib/utils/dataplane-cli-version-gate.js +202 -0
- package/lib/utils/dataplane-cli-version-help.js +74 -0
- package/lib/utils/datasource-export-display.js +137 -0
- package/lib/utils/datasource-load-display.js +174 -0
- package/lib/utils/datasource-load-export-ui.js +120 -0
- package/lib/utils/datasource-test-run-capability-scope.js +3 -3
- package/lib/utils/datasource-test-run-display.js +3 -3
- package/lib/utils/datasource-test-run-tty-log.js +5 -1
- package/lib/utils/help-builder.js +30 -24
- package/lib/utils/manifest-source-emit.js +22 -0
- package/lib/utils/semver-compare.js +127 -0
- package/lib/utils/upload-pipeline-ui.js +91 -0
- package/lib/utils/validation-poll-ui.js +14 -7
- package/lib/validation/wizard-config-validator.js +58 -19
- package/package.json +1 -1
- package/templates/applications/dataplane/env.template +13 -1
- package/templates/applications/dataplane/rbac.yaml +4 -0
- 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
|
+
};
|