@formigio/fazemos-cli 0.10.44 → 0.10.46
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/dist/approvals.d.ts +35 -0
- package/dist/approvals.js +279 -0
- package/dist/approvals.js.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/schedule.d.ts +64 -0
- package/dist/schedule.js +528 -0
- package/dist/schedule.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FC-B — Founder Console: Close the Loop
|
|
3
|
+
*
|
|
4
|
+
* Exports `registerApprovalsCommands(program)` which wires two sub-commands
|
|
5
|
+
* into the root Commander program (mirrors src/governance.ts:518
|
|
6
|
+
* registerGovernanceCommands pattern):
|
|
7
|
+
*
|
|
8
|
+
* fazemos approvals list [--project <slug>] [--json]
|
|
9
|
+
* → GET /api/control-plane/approvals
|
|
10
|
+
* Returns pending approval gates for the active org.
|
|
11
|
+
*
|
|
12
|
+
* fazemos approvals resolve <id> --decision approve|reject --reason <text> [--json]
|
|
13
|
+
* → POST /api/control-plane/approvals/:id/resolve
|
|
14
|
+
* Resolves an approval gate; sends surface='cli' for audit trail.
|
|
15
|
+
* --reason is mandatory (min 4 chars) — this is the CLI typed-token
|
|
16
|
+
* equivalent (OBD #1 / rul_cli_resolve_terminal_explicit_is_typed_token_equivalent).
|
|
17
|
+
*
|
|
18
|
+
* Auth: requireAuth + org membership (X-Org-Id via api() helper).
|
|
19
|
+
* Both commands are org-scoped (noProjectHeader: true on resolve;
|
|
20
|
+
* list passes project_id as query param when --project provided).
|
|
21
|
+
*
|
|
22
|
+
* Rule: Server enforces reject + missing reason → 422 REJECT_REQUIRES_REASON.
|
|
23
|
+
* CLI also validates locally so the error is surfaced before any HTTP call.
|
|
24
|
+
*
|
|
25
|
+
* Spec: FC-B-founder-console-close-the-loop-manifest.yaml §cli
|
|
26
|
+
* Tech: FC-B-founder-console-close-the-loop-tech-spec.md §cli
|
|
27
|
+
*/
|
|
28
|
+
import type { Command } from 'commander';
|
|
29
|
+
/**
|
|
30
|
+
* Register `approvals list` and `approvals resolve` into the root Commander program.
|
|
31
|
+
* Called from index.ts alongside registerGovernanceCommands.
|
|
32
|
+
*
|
|
33
|
+
* Pattern: mirrors registerGovernanceCommands at fazemos-cli/src/governance.ts:518.
|
|
34
|
+
*/
|
|
35
|
+
export declare function registerApprovalsCommands(program: Command): void;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FC-B — Founder Console: Close the Loop
|
|
3
|
+
*
|
|
4
|
+
* Exports `registerApprovalsCommands(program)` which wires two sub-commands
|
|
5
|
+
* into the root Commander program (mirrors src/governance.ts:518
|
|
6
|
+
* registerGovernanceCommands pattern):
|
|
7
|
+
*
|
|
8
|
+
* fazemos approvals list [--project <slug>] [--json]
|
|
9
|
+
* → GET /api/control-plane/approvals
|
|
10
|
+
* Returns pending approval gates for the active org.
|
|
11
|
+
*
|
|
12
|
+
* fazemos approvals resolve <id> --decision approve|reject --reason <text> [--json]
|
|
13
|
+
* → POST /api/control-plane/approvals/:id/resolve
|
|
14
|
+
* Resolves an approval gate; sends surface='cli' for audit trail.
|
|
15
|
+
* --reason is mandatory (min 4 chars) — this is the CLI typed-token
|
|
16
|
+
* equivalent (OBD #1 / rul_cli_resolve_terminal_explicit_is_typed_token_equivalent).
|
|
17
|
+
*
|
|
18
|
+
* Auth: requireAuth + org membership (X-Org-Id via api() helper).
|
|
19
|
+
* Both commands are org-scoped (noProjectHeader: true on resolve;
|
|
20
|
+
* list passes project_id as query param when --project provided).
|
|
21
|
+
*
|
|
22
|
+
* Rule: Server enforces reject + missing reason → 422 REJECT_REQUIRES_REASON.
|
|
23
|
+
* CLI also validates locally so the error is surfaced before any HTTP call.
|
|
24
|
+
*
|
|
25
|
+
* Spec: FC-B-founder-console-close-the-loop-manifest.yaml §cli
|
|
26
|
+
* Tech: FC-B-founder-console-close-the-loop-tech-spec.md §cli
|
|
27
|
+
*/
|
|
28
|
+
import chalk from 'chalk';
|
|
29
|
+
import { api, ApiError, resolveProjectIdBySlug } from './api.js';
|
|
30
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* Validate that the --decision flag is one of the allowed values.
|
|
33
|
+
* Throws a user-facing error otherwise.
|
|
34
|
+
*/
|
|
35
|
+
function validateDecision(value) {
|
|
36
|
+
if (value !== 'approve' && value !== 'reject') {
|
|
37
|
+
throw new Error(`--decision must be 'approve' or 'reject', got: ${value}`);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Validate that --reason meets the minimum length requirement (4 chars).
|
|
43
|
+
* Throws a user-facing error otherwise.
|
|
44
|
+
* This is the CLI side of rul_cli_resolve_terminal_explicit_is_typed_token_equivalent.
|
|
45
|
+
*/
|
|
46
|
+
function validateReason(value) {
|
|
47
|
+
const trimmed = value.trim();
|
|
48
|
+
if (trimmed.length < 4) {
|
|
49
|
+
throw new Error(`--reason must be at least 4 characters (got ${trimmed.length}). ` +
|
|
50
|
+
`Provide a meaningful reason — it lands in the audit trail.`);
|
|
51
|
+
}
|
|
52
|
+
return trimmed;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract the approval gates array from the API response envelope.
|
|
56
|
+
* The API may return the array under different keys depending on version.
|
|
57
|
+
*/
|
|
58
|
+
function extractGates(data) {
|
|
59
|
+
if (Array.isArray(data.approvalRequests))
|
|
60
|
+
return data.approvalRequests;
|
|
61
|
+
if (Array.isArray(data.approval_requests))
|
|
62
|
+
return data.approval_requests;
|
|
63
|
+
if (Array.isArray(data.gates))
|
|
64
|
+
return data.gates;
|
|
65
|
+
// Some responses may return the array directly at a named key — scan.
|
|
66
|
+
for (const val of Object.values(data)) {
|
|
67
|
+
if (Array.isArray(val) && val.length > 0 && typeof val[0] === 'object' && 'id' in val[0]) {
|
|
68
|
+
return val;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Render a human-readable table for approval gates.
|
|
75
|
+
* Format mirrors the governance waiting_on_me approval block (F34 pattern).
|
|
76
|
+
*/
|
|
77
|
+
function renderGatesList(gates) {
|
|
78
|
+
if (gates.length === 0) {
|
|
79
|
+
console.log(chalk.dim(' No pending approval requests.'));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
console.log(chalk.bold(`Pending Approvals (${gates.length}):`));
|
|
83
|
+
console.log();
|
|
84
|
+
for (const gate of gates) {
|
|
85
|
+
console.log(` ${chalk.bold(gate.description || chalk.dim('(no description)'))}`);
|
|
86
|
+
console.log(` id: ${chalk.dim(gate.id)}`);
|
|
87
|
+
console.log(` status: ${chalk.yellow(gate.status)}`);
|
|
88
|
+
if (gate.pipeline_name) {
|
|
89
|
+
console.log(` pipeline: ${chalk.cyan(gate.pipeline_name)}`);
|
|
90
|
+
}
|
|
91
|
+
if (gate.step_name) {
|
|
92
|
+
console.log(` step: ${chalk.cyan(gate.step_name)}`);
|
|
93
|
+
}
|
|
94
|
+
if (gate.deadline_at) {
|
|
95
|
+
console.log(` deadline: ${new Date(gate.deadline_at).toLocaleString()}`);
|
|
96
|
+
}
|
|
97
|
+
console.log(` created: ${new Date(gate.created_at).toLocaleString()}`);
|
|
98
|
+
if (gate.project_id) {
|
|
99
|
+
console.log(` project: ${chalk.dim(gate.project_id)}`);
|
|
100
|
+
}
|
|
101
|
+
console.log();
|
|
102
|
+
}
|
|
103
|
+
console.log(chalk.dim(`To resolve: fazemos approvals resolve <id> --decision approve|reject --reason "<text>"`));
|
|
104
|
+
}
|
|
105
|
+
// ── Command registration ───────────────────────────────────────────────────────
|
|
106
|
+
/**
|
|
107
|
+
* Register `approvals list` and `approvals resolve` into the root Commander program.
|
|
108
|
+
* Called from index.ts alongside registerGovernanceCommands.
|
|
109
|
+
*
|
|
110
|
+
* Pattern: mirrors registerGovernanceCommands at fazemos-cli/src/governance.ts:518.
|
|
111
|
+
*/
|
|
112
|
+
export function registerApprovalsCommands(program) {
|
|
113
|
+
// ── `fazemos approvals` ───────────────────────────────────────────────────
|
|
114
|
+
//
|
|
115
|
+
// Parent command hosting list + resolve sub-commands.
|
|
116
|
+
// Org-scoped (X-Org-Id sent by api() helper; no X-Fazemos-Project-Id).
|
|
117
|
+
// Auth: requireAuth + org membership (server-side, F37 shipped).
|
|
118
|
+
const approvalsCmd = program
|
|
119
|
+
.command('approvals')
|
|
120
|
+
.description('Approval gate management — list pending gates and resolve them from the CLI.\n\n' +
|
|
121
|
+
'Sub-commands:\n' +
|
|
122
|
+
' list List pending approval gates for your org\n' +
|
|
123
|
+
' resolve Approve or reject an approval gate\n\n' +
|
|
124
|
+
'Auth: your org is resolved via X-Org-Id (your active org); ' +
|
|
125
|
+
'only gate approvers (per F37) may resolve.\n\n' +
|
|
126
|
+
'Rule (OBD #1): --reason is mandatory for resolve — it is the CLI equivalent\n' +
|
|
127
|
+
'of the typed-token ceremony (fully auditable via via=\'cli\' in audit trail).');
|
|
128
|
+
// ── `fazemos approvals list` ──────────────────────────────────────────────
|
|
129
|
+
//
|
|
130
|
+
// GET /api/control-plane/approvals
|
|
131
|
+
//
|
|
132
|
+
// Returns pending approval gates. Optional --project <slug> restricts to
|
|
133
|
+
// gates belonging to a specific project. No X-Fazemos-Project-Id header
|
|
134
|
+
// (control-plane endpoint); project_id passed as query param when provided.
|
|
135
|
+
//
|
|
136
|
+
// Usage:
|
|
137
|
+
// fazemos approvals list
|
|
138
|
+
// fazemos approvals list --project my-project
|
|
139
|
+
// fazemos approvals list --json
|
|
140
|
+
approvalsCmd
|
|
141
|
+
.command('list')
|
|
142
|
+
.description('List pending approval gates for your org.\n\n' +
|
|
143
|
+
'Calls GET /api/control-plane/approvals (listOpenApprovals — F37 shipped).\n\n' +
|
|
144
|
+
'Use --project to restrict results to a specific project.\n' +
|
|
145
|
+
'Use --json for machine-readable output (raw API response).\n\n' +
|
|
146
|
+
'To resolve a gate: fazemos approvals resolve <id> --decision approve|reject --reason "<text>"')
|
|
147
|
+
.option('--project <slug>', 'filter to a specific project (slug or id)')
|
|
148
|
+
.option('--json', 'output machine-readable JSON (raw API response)')
|
|
149
|
+
.action(async (opts) => {
|
|
150
|
+
try {
|
|
151
|
+
// Build the query string. project_id is passed as a query param
|
|
152
|
+
// (not via X-Fazemos-Project-Id header — this is a control-plane call).
|
|
153
|
+
let path = '/api/control-plane/approvals';
|
|
154
|
+
if (opts.project) {
|
|
155
|
+
// Resolve slug → id (handles UUID pass-through transparently).
|
|
156
|
+
// resolveProjectIdBySlug uses cached /auth/me; refreshes on miss.
|
|
157
|
+
const projectId = await resolveProjectIdBySlug(opts.project);
|
|
158
|
+
if (projectId) {
|
|
159
|
+
path += `?project_id=${encodeURIComponent(projectId)}`;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const data = await api('GET', path, undefined, { noProjectHeader: true });
|
|
163
|
+
if (opts.json) {
|
|
164
|
+
console.log(JSON.stringify(data, null, 2));
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const gates = extractGates(data);
|
|
168
|
+
renderGatesList(gates);
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
if (err instanceof ApiError) {
|
|
172
|
+
console.error(chalk.red(`Error (${err.status}): ${err.message}`));
|
|
173
|
+
if (err.code) {
|
|
174
|
+
console.error(chalk.dim(` code: ${err.code}`));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
179
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
180
|
+
}
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// ── `fazemos approvals resolve <id>` ─────────────────────────────────────
|
|
185
|
+
//
|
|
186
|
+
// POST /api/control-plane/approvals/:id/resolve
|
|
187
|
+
//
|
|
188
|
+
// Resolves an approval gate (approve or reject). Sends surface='cli' so the
|
|
189
|
+
// audit trail records via='cli' (rul_via_cli_landed_in_audit_trail).
|
|
190
|
+
//
|
|
191
|
+
// --decision and --reason are both required. --reason must be ≥ 4 chars.
|
|
192
|
+
// This constitutes the CLI typed-token equivalent (OBD #1):
|
|
193
|
+
// "Terminal-explicit command + mandatory --reason IS the CLI equivalent
|
|
194
|
+
// of typed-token ceremony. No hidden state. Fully auditable via='cli'."
|
|
195
|
+
//
|
|
196
|
+
// Server additionally enforces: reject + missing/empty reason_note → 422
|
|
197
|
+
// REJECT_REQUIRES_REASON (rul_cli_terminal_explicit_mandatory_reason).
|
|
198
|
+
//
|
|
199
|
+
// Usage:
|
|
200
|
+
// fazemos approvals resolve <id> --decision approve --reason "Looks good, ship it"
|
|
201
|
+
// fazemos approvals resolve <id> --decision reject --reason "Missing QA sign-off"
|
|
202
|
+
// fazemos approvals resolve <id> --decision approve --reason "ok" --json
|
|
203
|
+
approvalsCmd
|
|
204
|
+
.command('resolve')
|
|
205
|
+
.description('Approve or reject an approval gate.\n\n' +
|
|
206
|
+
'Calls POST /api/control-plane/approvals/:id/resolve with surface=\'cli\'.\n' +
|
|
207
|
+
'Sends via=\'cli\' to the audit trail (rul_via_cli_landed_in_audit_trail).\n\n' +
|
|
208
|
+
'Both --decision and --reason are required.\n' +
|
|
209
|
+
'--reason must be at least 4 characters and is recorded in the audit trail.\n' +
|
|
210
|
+
'This is the CLI equivalent of the typed-token ceremony (OBD #1).\n\n' +
|
|
211
|
+
'Exit codes:\n' +
|
|
212
|
+
' 0 — resolved successfully\n' +
|
|
213
|
+
' 1 — API error (see error message)\n' +
|
|
214
|
+
' 2 — validation error (missing/invalid flag)')
|
|
215
|
+
.argument('<id>', 'Approval gate ID (UUID)')
|
|
216
|
+
.requiredOption('--decision <approve|reject>', 'Decision: approve or reject')
|
|
217
|
+
.requiredOption('--reason <text>', 'Reason for the decision (min 4 chars; recorded in audit trail)')
|
|
218
|
+
.option('--json', 'output machine-readable JSON (raw API response)')
|
|
219
|
+
.action(async (id, opts) => {
|
|
220
|
+
try {
|
|
221
|
+
// ── Client-side validation ─────────────────────────────────────────
|
|
222
|
+
// Validate before making any HTTP call (fast fail, clear messages).
|
|
223
|
+
// Server-side re-validates as well (defense-in-depth).
|
|
224
|
+
const decision = validateDecision(opts.decision);
|
|
225
|
+
const reason = validateReason(opts.reason);
|
|
226
|
+
// ── POST /api/control-plane/approvals/:id/resolve ──────────────────
|
|
227
|
+
// Body matches the FC-B modified contract:
|
|
228
|
+
// { decision, reason_note, surface: 'cli' }
|
|
229
|
+
// surface='cli' propagates to via='cli' in the audit trail.
|
|
230
|
+
const body = {
|
|
231
|
+
decision,
|
|
232
|
+
reason_note: reason,
|
|
233
|
+
surface: 'cli',
|
|
234
|
+
};
|
|
235
|
+
const data = await api('POST', `/api/control-plane/approvals/${encodeURIComponent(id)}/resolve`, body, { noProjectHeader: true });
|
|
236
|
+
if (opts.json) {
|
|
237
|
+
console.log(JSON.stringify(data, null, 2));
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// ── Human output ───────────────────────────────────────────────────
|
|
241
|
+
const decisionLabel = decision === 'approve'
|
|
242
|
+
? chalk.green('approved')
|
|
243
|
+
: chalk.red('rejected');
|
|
244
|
+
console.log(chalk.bold(`Approval ${decisionLabel}`));
|
|
245
|
+
console.log();
|
|
246
|
+
console.log(` id: ${chalk.dim(data.id)}`);
|
|
247
|
+
console.log(` decision: ${decisionLabel}`);
|
|
248
|
+
console.log(` via: ${chalk.dim(data.via)}`);
|
|
249
|
+
console.log(` resolved_at: ${new Date(data.resolved_at).toLocaleString()}`);
|
|
250
|
+
if (data.downstream_queued) {
|
|
251
|
+
console.log();
|
|
252
|
+
console.log(` ${chalk.cyan('→ downstream step queued:')} ${chalk.dim(data.downstream_queued)}`);
|
|
253
|
+
}
|
|
254
|
+
console.log();
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
if (err instanceof ApiError) {
|
|
258
|
+
// Surface server-enforced errors clearly (e.g., 422 REJECT_REQUIRES_REASON,
|
|
259
|
+
// 409 APPROVAL_ALREADY_RESOLVED, 404 APPROVAL_GATE_NOT_FOUND).
|
|
260
|
+
console.error(chalk.red(`Error (${err.status}): ${err.message}`));
|
|
261
|
+
if (err.code) {
|
|
262
|
+
console.error(chalk.dim(` code: ${err.code}`));
|
|
263
|
+
}
|
|
264
|
+
if (err.code === 'APPROVAL_ALREADY_RESOLVED') {
|
|
265
|
+
console.error(chalk.dim(' This gate was already resolved — nothing changed.'));
|
|
266
|
+
}
|
|
267
|
+
else if (err.code === 'REJECT_REQUIRES_REASON') {
|
|
268
|
+
console.error(chalk.dim(' Server requires a reason for rejection. Pass --reason "<text>" (min 4 chars).'));
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
273
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
274
|
+
}
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,8 @@ import { registerWakeCommands } from './wake.js';
|
|
|
23
23
|
import { registerGovernanceCommands } from './governance.js';
|
|
24
24
|
import { registerAutoStartCommands } from './autostart.js';
|
|
25
25
|
import { registerFtrCommand } from './ftr.js';
|
|
26
|
+
import { registerScheduleCommands } from './schedule.js';
|
|
27
|
+
import { registerApprovalsCommands } from './approvals.js';
|
|
26
28
|
import { parseExecutionsJson, resolveWaitOptions, waitForPipelines, buildAwsCommand, validateExecutionEntry, } from './wait-for-pipeline.js';
|
|
27
29
|
import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync, statSync } from 'fs';
|
|
28
30
|
import { fileURLToPath } from 'url';
|
|
@@ -9613,6 +9615,19 @@ registerAutoStartCommands(program);
|
|
|
9613
9615
|
// AC11: human-readable output per UX §7 (ratio/breakdown/contextual/footnotes).
|
|
9614
9616
|
// AC12: --json output equals endpoint response verbatim (LOCKED passthrough).
|
|
9615
9617
|
registerFtrCommand(program);
|
|
9618
|
+
// ── F35-FU-CRON-TZ-SCHEDULE — Per-project wake schedules: schedule list/set/unset/disable/enable/tz ──
|
|
9619
|
+
// Registers `schedule` top-level command with list, set, unset, disable, enable,
|
|
9620
|
+
// and `tz set <IANA>` sub-commands. All calls use the X-Fazemos-Project-Id header
|
|
9621
|
+
// (does NOT pass noProjectHeader: true — greenfield fix per binding_decision.cli_header_scoping).
|
|
9622
|
+
// admin/owner required for set/unset/disable/enable/tz; any active member for list.
|
|
9623
|
+
registerScheduleCommands(program);
|
|
9624
|
+
// ── FC-B — Approval Gate CLI: approvals list / approvals resolve ──────────────
|
|
9625
|
+
// Registers `approvals` top-level command with `list` and `resolve` sub-commands.
|
|
9626
|
+
// Both calls are org-scoped (noProjectHeader: true); resolve sends surface='cli'
|
|
9627
|
+
// so the audit trail records via='cli' (rul_via_cli_landed_in_audit_trail).
|
|
9628
|
+
// --reason is mandatory for resolve — CLI typed-token equivalent (OBD #1).
|
|
9629
|
+
// Auth: requireAuth + org membership (server-side, F37 shipped).
|
|
9630
|
+
registerApprovalsCommands(program);
|
|
9616
9631
|
// Skip auto-parse only when running under Vitest (which sets process.env.VITEST).
|
|
9617
9632
|
// Tests import `program` and drive it via `program.parseAsync(...)` after mocking
|
|
9618
9633
|
// `./api.js`. In every other context — direct invocation, npx tsx, OR the bin
|