@formigio/fazemos-cli 0.10.23 → 0.10.25
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/budget.d.ts +37 -0
- package/dist/budget.js +530 -0
- package/dist/budget.js.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -1
- package/dist/runbook/checks.d.ts +78 -0
- package/dist/runbook/checks.js +404 -0
- package/dist/runbook/checks.js.map +1 -0
- package/dist/runbook/schema.d.ts +153 -0
- package/dist/runbook/schema.js +136 -0
- package/dist/runbook/schema.js.map +1 -0
- package/package.json +1 -1
package/dist/budget.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* F33 — Token/Cost Budgets: CLI command helpers.
|
|
3
|
+
*
|
|
4
|
+
* Exports `registerBudgetCommands(program)` which wires the following commands
|
|
5
|
+
* into the root Commander program (mirrors the pause group pattern):
|
|
6
|
+
*
|
|
7
|
+
* fazemos budget set [--unit tokens|usd]
|
|
8
|
+
* (tokens-global) --plan-allowance <n> --window <dur> [--reserve <0..1>]
|
|
9
|
+
* (usd-global) --daily-cap <amount>
|
|
10
|
+
* (role) --role <slug> --soft <amount> [--autopause]
|
|
11
|
+
* (stream) --stream <id> --soft <amount> [--autopause]
|
|
12
|
+
* --reason <text> (required, audit trail)
|
|
13
|
+
* → POST /api/control-plane/budget
|
|
14
|
+
*
|
|
15
|
+
* fazemos budget clear [--role <slug> | --stream <id>] [--reason <text>]
|
|
16
|
+
* → DELETE /api/control-plane/budget
|
|
17
|
+
*
|
|
18
|
+
* fazemos budget show [--json]
|
|
19
|
+
* → GET /api/control-plane/budget (configured budgets)
|
|
20
|
+
*
|
|
21
|
+
* fazemos budget status [--json]
|
|
22
|
+
* → GET /api/control-plane/budget (configured budgets + in-window spend)
|
|
23
|
+
*
|
|
24
|
+
* Auth: set/clear require admin/owner. show/status require any active member.
|
|
25
|
+
* Org is derived from the auth token (budget is org-level; noProjectHeader: true
|
|
26
|
+
* on all calls).
|
|
27
|
+
*
|
|
28
|
+
* Spec: F33-token-cost-budgets-tech-spec.md §9 / §11 (denomination-aware)
|
|
29
|
+
* Manifest: cli_commands section (T17)
|
|
30
|
+
*/
|
|
31
|
+
import type { Command } from 'commander';
|
|
32
|
+
/**
|
|
33
|
+
* Register `budget set`, `budget clear`, `budget show`, and `budget status`
|
|
34
|
+
* into the root Commander program. Called from index.ts after `program` is
|
|
35
|
+
* created. Mirrors registerPauseCommands() from pause.ts.
|
|
36
|
+
*/
|
|
37
|
+
export declare function registerBudgetCommands(program: Command): void;
|
package/dist/budget.js
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* F33 — Token/Cost Budgets: CLI command helpers.
|
|
3
|
+
*
|
|
4
|
+
* Exports `registerBudgetCommands(program)` which wires the following commands
|
|
5
|
+
* into the root Commander program (mirrors the pause group pattern):
|
|
6
|
+
*
|
|
7
|
+
* fazemos budget set [--unit tokens|usd]
|
|
8
|
+
* (tokens-global) --plan-allowance <n> --window <dur> [--reserve <0..1>]
|
|
9
|
+
* (usd-global) --daily-cap <amount>
|
|
10
|
+
* (role) --role <slug> --soft <amount> [--autopause]
|
|
11
|
+
* (stream) --stream <id> --soft <amount> [--autopause]
|
|
12
|
+
* --reason <text> (required, audit trail)
|
|
13
|
+
* → POST /api/control-plane/budget
|
|
14
|
+
*
|
|
15
|
+
* fazemos budget clear [--role <slug> | --stream <id>] [--reason <text>]
|
|
16
|
+
* → DELETE /api/control-plane/budget
|
|
17
|
+
*
|
|
18
|
+
* fazemos budget show [--json]
|
|
19
|
+
* → GET /api/control-plane/budget (configured budgets)
|
|
20
|
+
*
|
|
21
|
+
* fazemos budget status [--json]
|
|
22
|
+
* → GET /api/control-plane/budget (configured budgets + in-window spend)
|
|
23
|
+
*
|
|
24
|
+
* Auth: set/clear require admin/owner. show/status require any active member.
|
|
25
|
+
* Org is derived from the auth token (budget is org-level; noProjectHeader: true
|
|
26
|
+
* on all calls).
|
|
27
|
+
*
|
|
28
|
+
* Spec: F33-token-cost-budgets-tech-spec.md §9 / §11 (denomination-aware)
|
|
29
|
+
* Manifest: cli_commands section (T17)
|
|
30
|
+
*/
|
|
31
|
+
import chalk from 'chalk';
|
|
32
|
+
import { api } from './api.js';
|
|
33
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Resolve scope + scope_key from --role / --stream flags.
|
|
36
|
+
* Rules (matching API validation):
|
|
37
|
+
* --role <slug> → scope='role', scope_key=slug
|
|
38
|
+
* --stream <id> → scope='stream', scope_key=id
|
|
39
|
+
* (neither) → scope='global', scope_key absent
|
|
40
|
+
* (both) → error: mutually exclusive
|
|
41
|
+
*/
|
|
42
|
+
function resolveScope(opts) {
|
|
43
|
+
if (opts.role && opts.stream) {
|
|
44
|
+
throw new Error('--role and --stream are mutually exclusive; specify at most one.');
|
|
45
|
+
}
|
|
46
|
+
if (opts.role) {
|
|
47
|
+
if (!opts.role.trim())
|
|
48
|
+
throw new Error('--role cannot be empty');
|
|
49
|
+
return { scope: 'role', scope_key: opts.role.trim().toLowerCase() };
|
|
50
|
+
}
|
|
51
|
+
if (opts.stream) {
|
|
52
|
+
if (!opts.stream.trim())
|
|
53
|
+
throw new Error('--stream cannot be empty');
|
|
54
|
+
return { scope: 'stream', scope_key: opts.stream.trim() };
|
|
55
|
+
}
|
|
56
|
+
return { scope: 'global' };
|
|
57
|
+
}
|
|
58
|
+
/** Human-readable scope label for terminal output. */
|
|
59
|
+
function scopeLabel(scope, scope_key) {
|
|
60
|
+
if (scope === 'global')
|
|
61
|
+
return chalk.bold('global');
|
|
62
|
+
if (scope === 'role')
|
|
63
|
+
return `role: ${chalk.cyan(scope_key ?? '?')}`;
|
|
64
|
+
return `stream: ${chalk.cyan(scope_key ?? '?')}`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse a duration string to seconds.
|
|
68
|
+
* Accepts: <n>s, <n>m, <n>h, <n>d, or a plain integer (treated as seconds).
|
|
69
|
+
* Example: "24h" → 86400, "7d" → 604800
|
|
70
|
+
*/
|
|
71
|
+
function parseDurationToSeconds(dur) {
|
|
72
|
+
const match = dur.match(/^(\d+)([smhd]?)$/i);
|
|
73
|
+
if (!match) {
|
|
74
|
+
throw new Error(`Invalid --window value "${dur}". Use <n>s, <n>m, <n>h, <n>d, or a plain integer (seconds).`);
|
|
75
|
+
}
|
|
76
|
+
const n = parseInt(match[1], 10);
|
|
77
|
+
const unit = (match[2] || 's').toLowerCase();
|
|
78
|
+
const multipliers = { s: 1, m: 60, h: 3600, d: 86400 };
|
|
79
|
+
return n * multipliers[unit];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Render a tokens-mode budget row in human-readable form.
|
|
83
|
+
*/
|
|
84
|
+
function renderTokensBudgetRow(b) {
|
|
85
|
+
const allowance = b.plan_token_allowance ? parseInt(b.plan_token_allowance, 10) : null;
|
|
86
|
+
const reservePct = parseFloat(b.reserve_pct);
|
|
87
|
+
const cap = b.token_cap ? parseInt(b.token_cap, 10) : null;
|
|
88
|
+
const softCap = b.soft_token_budget ? parseInt(b.soft_token_budget, 10) : null;
|
|
89
|
+
const effectiveCap = cap ?? (allowance != null ? Math.floor(allowance * (1 - reservePct)) : null);
|
|
90
|
+
const windowHours = b.window_seconds != null ? (b.window_seconds / 3600).toFixed(1) : null;
|
|
91
|
+
const windowKindLabel = b.window_kind === 'rolling' ? `rolling ${windowHours}h` : 'UTC day';
|
|
92
|
+
console.log(` ${chalk.bold(scopeLabel(b.scope, b.scope_key))}`);
|
|
93
|
+
if (allowance != null) {
|
|
94
|
+
console.log(` Plan allowance: ${allowance.toLocaleString()} tokens`);
|
|
95
|
+
console.log(` Reserve: ${(reservePct * 100).toFixed(1)}%`);
|
|
96
|
+
}
|
|
97
|
+
if (effectiveCap != null) {
|
|
98
|
+
console.log(` Effective cap: ${effectiveCap.toLocaleString()} tokens`);
|
|
99
|
+
}
|
|
100
|
+
if (softCap != null) {
|
|
101
|
+
console.log(` Soft cap: ${softCap.toLocaleString()} tokens${b.autopause ? ' (autopause on breach)' : ''}`);
|
|
102
|
+
}
|
|
103
|
+
if (b.autopause && softCap == null) {
|
|
104
|
+
console.log(` Autopause: yes`);
|
|
105
|
+
}
|
|
106
|
+
if (windowHours) {
|
|
107
|
+
console.log(` Window: ${windowKindLabel}`);
|
|
108
|
+
}
|
|
109
|
+
if (b.reason) {
|
|
110
|
+
console.log(` Reason: ${b.reason}`);
|
|
111
|
+
}
|
|
112
|
+
console.log(` Set by: ${b.set_by} at ${new Date(b.set_at).toLocaleString()}`);
|
|
113
|
+
console.log(` Version: ${b.version}`);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Render a USD-mode budget row in human-readable form.
|
|
117
|
+
*/
|
|
118
|
+
function renderUsdBudgetRow(b) {
|
|
119
|
+
const dailyCap = b.daily_cap_usd ? parseFloat(b.daily_cap_usd) : null;
|
|
120
|
+
const softBudget = b.soft_budget_usd ? parseFloat(b.soft_budget_usd) : null;
|
|
121
|
+
console.log(` ${chalk.bold(scopeLabel(b.scope, b.scope_key))}`);
|
|
122
|
+
if (dailyCap != null) {
|
|
123
|
+
console.log(` Daily cap (USD): $${dailyCap.toFixed(2)}`);
|
|
124
|
+
}
|
|
125
|
+
if (softBudget != null) {
|
|
126
|
+
console.log(` Soft cap (USD): $${softBudget.toFixed(2)}${b.autopause ? ' (autopause on breach)' : ''}`);
|
|
127
|
+
}
|
|
128
|
+
if (b.autopause && softBudget == null) {
|
|
129
|
+
console.log(` Autopause: yes`);
|
|
130
|
+
}
|
|
131
|
+
if (b.reason) {
|
|
132
|
+
console.log(` Reason: ${b.reason}`);
|
|
133
|
+
}
|
|
134
|
+
console.log(` Set by: ${b.set_by} at ${new Date(b.set_at).toLocaleString()}`);
|
|
135
|
+
console.log(` Version: ${b.version}`);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Render a single budget row (dispatch on unit).
|
|
139
|
+
*/
|
|
140
|
+
function renderBudgetRow(b) {
|
|
141
|
+
if (b.budget_unit === 'usd') {
|
|
142
|
+
renderUsdBudgetRow(b);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
renderTokensBudgetRow(b);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Render spend window data alongside a budget row (for `status` sub-command).
|
|
150
|
+
*/
|
|
151
|
+
function renderSpendWindow(sw) {
|
|
152
|
+
const unit = sw.unit;
|
|
153
|
+
const windowStart = new Date(sw.window_start).toLocaleString();
|
|
154
|
+
const resetsAt = sw.resets_at ? new Date(sw.resets_at).toLocaleString() : 'n/a';
|
|
155
|
+
console.log();
|
|
156
|
+
console.log(chalk.bold('In-window spend:'));
|
|
157
|
+
if (unit === 'tokens') {
|
|
158
|
+
console.log(` Org spend (weighted): ${sw.org.weighted_spend.toLocaleString()} tokens`);
|
|
159
|
+
console.log(` Org effective spend: ${sw.org.effective_spend.toLocaleString()} tokens`);
|
|
160
|
+
if (sw.org.cap != null) {
|
|
161
|
+
console.log(` Org hard cap: ${sw.org.cap.toLocaleString()} tokens`);
|
|
162
|
+
}
|
|
163
|
+
if (sw.org.soft_cap != null) {
|
|
164
|
+
console.log(` Org soft cap: ${sw.org.soft_cap.toLocaleString()} tokens`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
console.log(` Org weighted spend: $${sw.org.weighted_spend.toFixed(4)}`);
|
|
169
|
+
console.log(` Org effective spend: $${sw.org.effective_spend.toFixed(4)}`);
|
|
170
|
+
if (sw.org.cap != null) {
|
|
171
|
+
console.log(` Org daily cap: $${sw.org.cap.toFixed(2)}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
console.log(` Window start: ${windowStart}`);
|
|
175
|
+
console.log(` Resets at: ${resetsAt}`);
|
|
176
|
+
const roles = Object.entries(sw.roles);
|
|
177
|
+
if (roles.length > 0) {
|
|
178
|
+
console.log();
|
|
179
|
+
console.log(' Role spend:');
|
|
180
|
+
for (const [slug, data] of roles) {
|
|
181
|
+
const capStr = data.cap != null
|
|
182
|
+
? (unit === 'usd' ? ` / $${data.cap.toFixed(2)}` : ` / ${data.cap.toLocaleString()}`)
|
|
183
|
+
: '';
|
|
184
|
+
const spendStr = unit === 'usd' ? `$${data.spend.toFixed(4)}` : data.spend.toLocaleString();
|
|
185
|
+
console.log(` ${chalk.cyan(slug)}: ${spendStr}${capStr}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const streams = Object.entries(sw.streams);
|
|
189
|
+
if (streams.length > 0) {
|
|
190
|
+
console.log();
|
|
191
|
+
console.log(' Stream spend:');
|
|
192
|
+
for (const [id, data] of streams) {
|
|
193
|
+
const capStr = data.cap != null
|
|
194
|
+
? (unit === 'usd' ? ` / $${data.cap.toFixed(2)}` : ` / ${data.cap.toLocaleString()}`)
|
|
195
|
+
: '';
|
|
196
|
+
const spendStr = unit === 'usd' ? `$${data.spend.toFixed(4)}` : data.spend.toLocaleString();
|
|
197
|
+
console.log(` ${chalk.cyan(id)}: ${spendStr}${capStr}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// ── Command registration ───────────────────────────────────────────────────────
|
|
202
|
+
/**
|
|
203
|
+
* Register `budget set`, `budget clear`, `budget show`, and `budget status`
|
|
204
|
+
* into the root Commander program. Called from index.ts after `program` is
|
|
205
|
+
* created. Mirrors registerPauseCommands() from pause.ts.
|
|
206
|
+
*/
|
|
207
|
+
export function registerBudgetCommands(program) {
|
|
208
|
+
// ── `fazemos budget` ─────────────────────────────────────────────────────────
|
|
209
|
+
//
|
|
210
|
+
// Parent command hosting sub-commands: set, clear, show, status.
|
|
211
|
+
// The parent itself has no action (sub-commands always required).
|
|
212
|
+
const budgetCmd = program
|
|
213
|
+
.command('budget')
|
|
214
|
+
.description('Manage token/cost budgets for the org (AUTONOMY Phase 0 control plane).\n\n' +
|
|
215
|
+
'Sub-commands:\n' +
|
|
216
|
+
' set Set or update a budget (tokens or USD denomination)\n' +
|
|
217
|
+
' clear Remove/clear an active budget\n' +
|
|
218
|
+
' show List configured budgets\n' +
|
|
219
|
+
' status List configured budgets with in-window spend data\n\n' +
|
|
220
|
+
'All budget operations are org-level (project header not sent).\n' +
|
|
221
|
+
'set/clear require admin or owner role; show/status any active member.');
|
|
222
|
+
// ── `fazemos budget set` ──────────────────────────────────────────────────────
|
|
223
|
+
//
|
|
224
|
+
// POST /api/control-plane/budget
|
|
225
|
+
//
|
|
226
|
+
// Global tokens: fazemos budget set --unit tokens --plan-allowance 1000000 --window 24h --reserve 0.2 --reason "..."
|
|
227
|
+
// Global USD: fazemos budget set --unit usd --daily-cap 50.00 --reason "..."
|
|
228
|
+
// Per-role: fazemos budget set --role luca --soft 200000 [--autopause] --reason "..."
|
|
229
|
+
// Per-stream: fazemos budget set --stream <uuid> --soft 50000 [--autopause] --reason "..."
|
|
230
|
+
//
|
|
231
|
+
// Flag-set validation (denomination-aware):
|
|
232
|
+
// --daily-cap with --unit tokens → error
|
|
233
|
+
// --plan-allowance/--window/--reserve with --unit usd → error
|
|
234
|
+
// --autopause without --role/--stream → error
|
|
235
|
+
// --soft without --role/--stream → error
|
|
236
|
+
budgetCmd
|
|
237
|
+
.command('set')
|
|
238
|
+
.description('Set or update a budget for the org.\n\n' +
|
|
239
|
+
'Denomination:\n' +
|
|
240
|
+
' --unit tokens (default) Set a rolling token-based budget\n' +
|
|
241
|
+
' --unit usd Set a UTC-day USD budget\n\n' +
|
|
242
|
+
'Tokens-global flags (scope=global, unit=tokens):\n' +
|
|
243
|
+
' --plan-allowance <n> Org-level token allowance (required for global tokens)\n' +
|
|
244
|
+
' --window <dur> Rolling window (e.g. 24h, 7d, 86400); default 24h\n' +
|
|
245
|
+
' --reserve <0..1> Fraction held in reserve (default 0.2)\n\n' +
|
|
246
|
+
'USD-global flags (scope=global, unit=usd):\n' +
|
|
247
|
+
' --daily-cap <amount> Daily USD cap (required for global usd)\n\n' +
|
|
248
|
+
'Role/stream flags (scope=role|stream):\n' +
|
|
249
|
+
' --role <slug> Target a specific agent role\n' +
|
|
250
|
+
' --stream <id> Target a specific pipeline instance stream\n' +
|
|
251
|
+
' --soft <amount> Soft cap in the active unit (role/stream only)\n' +
|
|
252
|
+
' --autopause Trip global pause when soft cap is breached\n\n' +
|
|
253
|
+
'--reason <text> is required (audit trail).\n' +
|
|
254
|
+
'Org is derived from your auth token; no project header is sent.')
|
|
255
|
+
.option('--unit <tokens|usd>', 'budget denomination: tokens (default) or usd', 'tokens')
|
|
256
|
+
.option('--plan-allowance <n>', 'org-level token allowance (tokens-global)')
|
|
257
|
+
.option('--window <dur>', 'rolling window duration (tokens mode), e.g. 24h, 7d', '24h')
|
|
258
|
+
.option('--reserve <0..1>', 'fraction of allowance held in reserve (tokens-global, default 0.2)', '0.2')
|
|
259
|
+
.option('--daily-cap <amount>', 'daily USD cap (usd-global)')
|
|
260
|
+
.option('--role <slug>', 'target a specific agent role (role budget)')
|
|
261
|
+
.option('--stream <id>', 'target a specific pipeline instance stream (stream budget)')
|
|
262
|
+
.option('--soft <amount>', 'soft cap in the active unit (role/stream only)')
|
|
263
|
+
.option('--autopause', 'trip global pause when soft cap is breached (role/stream only)')
|
|
264
|
+
.requiredOption('--reason <text>', 'reason for the budget change (required for audit trail)')
|
|
265
|
+
.option('--json', 'output machine-readable JSON')
|
|
266
|
+
.action(async (opts) => {
|
|
267
|
+
try {
|
|
268
|
+
const unit = opts.unit.toLowerCase();
|
|
269
|
+
if (unit !== 'tokens' && unit !== 'usd') {
|
|
270
|
+
throw new Error(`--unit must be 'tokens' or 'usd', got: ${opts.unit}`);
|
|
271
|
+
}
|
|
272
|
+
const { scope, scope_key } = resolveScope({ role: opts.role, stream: opts.stream });
|
|
273
|
+
// ── Flag-set validation (denomination + scope aware) ───────────────────
|
|
274
|
+
if (unit === 'tokens') {
|
|
275
|
+
if (opts.dailyCap !== undefined) {
|
|
276
|
+
throw new Error('--daily-cap is only valid with --unit usd');
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (unit === 'usd') {
|
|
280
|
+
if (opts.planAllowance !== undefined) {
|
|
281
|
+
throw new Error('--plan-allowance is only valid with --unit tokens');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
if (opts.autopause && scope === 'global') {
|
|
285
|
+
throw new Error('--autopause is only supported for --role or --stream scopes');
|
|
286
|
+
}
|
|
287
|
+
if (opts.soft !== undefined && scope === 'global') {
|
|
288
|
+
throw new Error('--soft is only valid for --role or --stream scopes; use --plan-allowance or --daily-cap for global caps');
|
|
289
|
+
}
|
|
290
|
+
// ── Build request body ────────────────────────────────────────────────
|
|
291
|
+
const body = {
|
|
292
|
+
scope,
|
|
293
|
+
budget_unit: unit,
|
|
294
|
+
reason: opts.reason,
|
|
295
|
+
};
|
|
296
|
+
if (scope_key !== undefined)
|
|
297
|
+
body.scope_key = scope_key;
|
|
298
|
+
if (unit === 'tokens') {
|
|
299
|
+
const windowSeconds = parseDurationToSeconds(opts.window);
|
|
300
|
+
body.window_seconds = windowSeconds;
|
|
301
|
+
if (scope === 'global') {
|
|
302
|
+
if (opts.planAllowance === undefined) {
|
|
303
|
+
throw new Error('--plan-allowance is required for a global token budget');
|
|
304
|
+
}
|
|
305
|
+
const allowance = parseInt(opts.planAllowance, 10);
|
|
306
|
+
if (isNaN(allowance) || allowance <= 0) {
|
|
307
|
+
throw new Error('--plan-allowance must be a positive integer');
|
|
308
|
+
}
|
|
309
|
+
body.plan_token_allowance = allowance;
|
|
310
|
+
const reserve = parseFloat(opts.reserve);
|
|
311
|
+
if (isNaN(reserve) || reserve < 0 || reserve > 1) {
|
|
312
|
+
throw new Error('--reserve must be a number between 0 and 1');
|
|
313
|
+
}
|
|
314
|
+
body.reserve_pct = reserve;
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
// role or stream
|
|
318
|
+
if (opts.soft !== undefined) {
|
|
319
|
+
const softCap = parseInt(opts.soft, 10);
|
|
320
|
+
if (isNaN(softCap) || softCap <= 0) {
|
|
321
|
+
throw new Error('--soft must be a positive integer (token count)');
|
|
322
|
+
}
|
|
323
|
+
body.soft_token_budget = softCap;
|
|
324
|
+
}
|
|
325
|
+
if (opts.autopause) {
|
|
326
|
+
body.autopause = true;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
// usd
|
|
332
|
+
if (scope === 'global') {
|
|
333
|
+
if (opts.dailyCap === undefined) {
|
|
334
|
+
throw new Error('--daily-cap is required for a global USD budget');
|
|
335
|
+
}
|
|
336
|
+
const dailyCap = parseFloat(opts.dailyCap);
|
|
337
|
+
if (isNaN(dailyCap) || dailyCap <= 0) {
|
|
338
|
+
throw new Error('--daily-cap must be a positive number');
|
|
339
|
+
}
|
|
340
|
+
body.daily_cap_usd = dailyCap;
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
// role or stream
|
|
344
|
+
if (opts.soft !== undefined) {
|
|
345
|
+
const softBudget = parseFloat(opts.soft);
|
|
346
|
+
if (isNaN(softBudget) || softBudget <= 0) {
|
|
347
|
+
throw new Error('--soft must be a positive number (USD amount)');
|
|
348
|
+
}
|
|
349
|
+
body.soft_budget_usd = softBudget;
|
|
350
|
+
}
|
|
351
|
+
if (opts.autopause) {
|
|
352
|
+
body.autopause = true;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const data = await api('POST', '/api/control-plane/budget', body, {
|
|
357
|
+
noProjectHeader: true,
|
|
358
|
+
});
|
|
359
|
+
if (opts.json) {
|
|
360
|
+
console.log(JSON.stringify(data, null, 2));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const budget = data.budget;
|
|
364
|
+
console.log(chalk.green('✓ Budget set'));
|
|
365
|
+
renderBudgetRow(budget);
|
|
366
|
+
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
369
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
370
|
+
process.exit(1);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
// ── `fazemos budget clear` ────────────────────────────────────────────────────
|
|
374
|
+
//
|
|
375
|
+
// DELETE /api/control-plane/budget
|
|
376
|
+
//
|
|
377
|
+
// Usage:
|
|
378
|
+
// fazemos budget clear --reason "no longer needed"
|
|
379
|
+
// fazemos budget clear --role luca --reason "unrestricting"
|
|
380
|
+
// fazemos budget clear --stream <uuid> --reason "F33 build complete"
|
|
381
|
+
budgetCmd
|
|
382
|
+
.command('clear')
|
|
383
|
+
.description('Clear (soft-delete) an active budget for the org.\n\n' +
|
|
384
|
+
'Clears exactly one scope at a time. The API soft-clears the row and\n' +
|
|
385
|
+
'nudges suppressed pipeline steps to re-evaluate (re_driven count printed).\n' +
|
|
386
|
+
'Idempotent — clearing a non-existent budget returns success.\n\n' +
|
|
387
|
+
'Scopes:\n' +
|
|
388
|
+
' (no flag) → clear global budget\n' +
|
|
389
|
+
' --role <slug> → clear per-role budget\n' +
|
|
390
|
+
' --stream <id> → clear per-stream budget\n\n' +
|
|
391
|
+
'Requires admin or owner role. --reason maps to clear_reason in the audit log.')
|
|
392
|
+
.option('--role <slug>', 'clear the budget for a specific agent role')
|
|
393
|
+
.option('--stream <id>', 'clear the budget for a specific pipeline instance stream')
|
|
394
|
+
.option('--reason <text>', 'reason for clearing the budget (audit trail)')
|
|
395
|
+
.option('--json', 'output machine-readable JSON')
|
|
396
|
+
.action(async (opts) => {
|
|
397
|
+
try {
|
|
398
|
+
const { scope, scope_key } = resolveScope({ role: opts.role, stream: opts.stream });
|
|
399
|
+
const body = { scope };
|
|
400
|
+
if (scope_key !== undefined)
|
|
401
|
+
body.scope_key = scope_key;
|
|
402
|
+
if (opts.reason)
|
|
403
|
+
body.clear_reason = opts.reason;
|
|
404
|
+
const data = await api('DELETE', '/api/control-plane/budget', body, {
|
|
405
|
+
noProjectHeader: true,
|
|
406
|
+
});
|
|
407
|
+
if (opts.json) {
|
|
408
|
+
console.log(JSON.stringify(data, null, 2));
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (data.cleared) {
|
|
412
|
+
console.log(chalk.green('✓ Budget cleared'));
|
|
413
|
+
console.log(` Scope: ${scopeLabel(scope, scope_key)}`);
|
|
414
|
+
if (data.re_driven > 0) {
|
|
415
|
+
console.log(` Re-driven: ${chalk.cyan(String(data.re_driven))} pipeline instance(s) nudged to re-drive`);
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
console.log(` Re-driven: 0 (ops-sweep will re-drive on next tick)`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
console.log(chalk.yellow(`No active budget found for ${scopeLabel(scope, scope_key)} — nothing to clear.`));
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
catch (err) {
|
|
426
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
427
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
428
|
+
process.exit(1);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
// ── `fazemos budget show` ─────────────────────────────────────────────────────
|
|
432
|
+
//
|
|
433
|
+
// GET /api/control-plane/budget — show configured budgets only (no spend data).
|
|
434
|
+
//
|
|
435
|
+
// Usage:
|
|
436
|
+
// fazemos budget show
|
|
437
|
+
// fazemos budget show --json
|
|
438
|
+
budgetCmd
|
|
439
|
+
.command('show')
|
|
440
|
+
.description('List all configured budgets for the org.\n\n' +
|
|
441
|
+
'Shows: scope, unit, window, cap amounts, autopause flag, who/when.\n' +
|
|
442
|
+
'Does not include in-window spend data — use `fazemos budget status` for spend.\n\n' +
|
|
443
|
+
'Readable by any active org member. Use --json for machine-readable output.')
|
|
444
|
+
.option('--json', 'output machine-readable JSON')
|
|
445
|
+
.action(async (opts) => {
|
|
446
|
+
try {
|
|
447
|
+
const data = await api('GET', '/api/control-plane/budget', undefined, {
|
|
448
|
+
noProjectHeader: true,
|
|
449
|
+
});
|
|
450
|
+
if (opts.json) {
|
|
451
|
+
console.log(JSON.stringify(data, null, 2));
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
const budgets = data.budgets;
|
|
455
|
+
if (budgets.length === 0) {
|
|
456
|
+
console.log(chalk.yellow('No budgets configured.'));
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
console.log(chalk.bold(`Configured budgets (${budgets.length}):`));
|
|
460
|
+
console.log();
|
|
461
|
+
for (const b of budgets) {
|
|
462
|
+
renderBudgetRow(b);
|
|
463
|
+
console.log();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
catch (err) {
|
|
467
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
468
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
469
|
+
process.exit(1);
|
|
470
|
+
}
|
|
471
|
+
});
|
|
472
|
+
// ── `fazemos budget status` ───────────────────────────────────────────────────
|
|
473
|
+
//
|
|
474
|
+
// GET /api/control-plane/budget — configured budgets + in-window spend (AC#16).
|
|
475
|
+
//
|
|
476
|
+
// Tokens render: tokens-used / allowance (reserve N%) · effective vs cap · window resets in <Δ>
|
|
477
|
+
// USD render: recorded $spend · effective vs $cap · resets at midnight UTC
|
|
478
|
+
//
|
|
479
|
+
// Usage:
|
|
480
|
+
// fazemos budget status
|
|
481
|
+
// fazemos budget status --json
|
|
482
|
+
budgetCmd
|
|
483
|
+
.command('status')
|
|
484
|
+
.description('List configured budgets plus in-window spend data for the org.\n\n' +
|
|
485
|
+
'Shows configured caps alongside actual spend in the current window,\n' +
|
|
486
|
+
'per scope (global, each role, each stream). Requires any active org member.\n\n' +
|
|
487
|
+
'Tokens mode: tokens-used / allowance (reserve N%) · effective vs cap · window resets.\n' +
|
|
488
|
+
'USD mode: recorded $spend · in-window · resets at midnight UTC.\n\n' +
|
|
489
|
+
'Use --json for machine-readable output.')
|
|
490
|
+
.option('--json', 'output machine-readable JSON')
|
|
491
|
+
.action(async (opts) => {
|
|
492
|
+
try {
|
|
493
|
+
const data = await api('GET', '/api/control-plane/budget', undefined, {
|
|
494
|
+
noProjectHeader: true,
|
|
495
|
+
});
|
|
496
|
+
if (opts.json) {
|
|
497
|
+
console.log(JSON.stringify(data, null, 2));
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const budgets = data.budgets;
|
|
501
|
+
const spendWindow = data.spend_window;
|
|
502
|
+
if (budgets.length === 0) {
|
|
503
|
+
console.log(chalk.yellow('No budgets configured.'));
|
|
504
|
+
if (spendWindow) {
|
|
505
|
+
renderSpendWindow(spendWindow);
|
|
506
|
+
}
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
console.log(chalk.bold(`Budget status (${budgets.length} configured):`));
|
|
510
|
+
console.log();
|
|
511
|
+
for (const b of budgets) {
|
|
512
|
+
renderBudgetRow(b);
|
|
513
|
+
console.log();
|
|
514
|
+
}
|
|
515
|
+
if (spendWindow) {
|
|
516
|
+
renderSpendWindow(spendWindow);
|
|
517
|
+
console.log();
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
console.log(chalk.dim(' (No in-window spend data available — no active global budget configured)'));
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
catch (err) {
|
|
524
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
525
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
526
|
+
process.exit(1);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"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"}
|