@formigio/fazemos-cli 0.10.39 → 0.10.41
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/autostart.d.ts +49 -0
- package/dist/autostart.js +364 -0
- package/dist/autostart.js.map +1 -0
- package/dist/index.js +102 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AUTON-AUTOSTART — Action→Pipeline Auto-Start: CLI command helpers.
|
|
3
|
+
*
|
|
4
|
+
* Exports `registerAutoStartCommands(program)` which wires the following commands
|
|
5
|
+
* into the root Commander program (mirrors the trigger/wake group pattern):
|
|
6
|
+
*
|
|
7
|
+
* fazemos autostart list
|
|
8
|
+
* → GET /api/control-plane/autostart?project_id=<id>
|
|
9
|
+
* Reads the allow-listed (action_id, template_id, enabled) bindings.
|
|
10
|
+
*
|
|
11
|
+
* fazemos autostart status [--json]
|
|
12
|
+
* → GET /api/control-plane/autostart?project_id=<id>
|
|
13
|
+
* bindings + recent action_pipeline_fires (window_key, fire_status,
|
|
14
|
+
* pipeline_instance_id, last_error).
|
|
15
|
+
*
|
|
16
|
+
* fazemos autostart disable --action <action-id> [--until <iso>] [--reason <text>]
|
|
17
|
+
* → POST /api/control-plane/autostart/disable
|
|
18
|
+
* { action: "disable", project_id, worksheet_action_id, reason, until? }
|
|
19
|
+
* Upserts an action_autostart_disables row; timed (--until) or indefinite.
|
|
20
|
+
*
|
|
21
|
+
* fazemos autostart enable --action <action-id>
|
|
22
|
+
* → POST /api/control-plane/autostart/disable
|
|
23
|
+
* { action: "enable", project_id, worksheet_action_id }
|
|
24
|
+
* Deletes the disable row (re-enables the action's auto-start).
|
|
25
|
+
*
|
|
26
|
+
* Auth: disable/enable require admin/owner (same as trigger/wake).
|
|
27
|
+
* list/status require any active org member.
|
|
28
|
+
* Scope: project-scoped reads (project_id query param); writes are org+project.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: `fire-now` is deliberately NOT offered in V1 — manual pipeline start is
|
|
31
|
+
* already `fazemos pl create`. A fire-now re-drive of a failed row is V2.
|
|
32
|
+
*
|
|
33
|
+
* Spec: AUTON-AUTOSTART-tech-spec.md §11 (R12, AC14)
|
|
34
|
+
* Manifest: cli_commands (fazemos autostart list/status/disable/enable)
|
|
35
|
+
*
|
|
36
|
+
* Key differences from trigger.ts:
|
|
37
|
+
* - No cadence dimension (action auto-start is per-action, per-window)
|
|
38
|
+
* - No fire-now command (V1 spec explicitly excludes it)
|
|
39
|
+
* - Bindings keyed by action_id + template_id (not role + cadence)
|
|
40
|
+
* - disable/enable keyed by --action <worksheet_action_id> (not --role + --cadence)
|
|
41
|
+
* - Endpoint: /api/control-plane/autostart and /api/control-plane/autostart/disable
|
|
42
|
+
*/
|
|
43
|
+
import type { Command } from 'commander';
|
|
44
|
+
/**
|
|
45
|
+
* Register `autostart list`, `autostart status`, `autostart disable`, and
|
|
46
|
+
* `autostart enable` into the root Commander program. Called from index.ts
|
|
47
|
+
* alongside registerTriggerCommands and registerWakeCommands.
|
|
48
|
+
*/
|
|
49
|
+
export declare function registerAutoStartCommands(program: Command): void;
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AUTON-AUTOSTART — Action→Pipeline Auto-Start: CLI command helpers.
|
|
3
|
+
*
|
|
4
|
+
* Exports `registerAutoStartCommands(program)` which wires the following commands
|
|
5
|
+
* into the root Commander program (mirrors the trigger/wake group pattern):
|
|
6
|
+
*
|
|
7
|
+
* fazemos autostart list
|
|
8
|
+
* → GET /api/control-plane/autostart?project_id=<id>
|
|
9
|
+
* Reads the allow-listed (action_id, template_id, enabled) bindings.
|
|
10
|
+
*
|
|
11
|
+
* fazemos autostart status [--json]
|
|
12
|
+
* → GET /api/control-plane/autostart?project_id=<id>
|
|
13
|
+
* bindings + recent action_pipeline_fires (window_key, fire_status,
|
|
14
|
+
* pipeline_instance_id, last_error).
|
|
15
|
+
*
|
|
16
|
+
* fazemos autostart disable --action <action-id> [--until <iso>] [--reason <text>]
|
|
17
|
+
* → POST /api/control-plane/autostart/disable
|
|
18
|
+
* { action: "disable", project_id, worksheet_action_id, reason, until? }
|
|
19
|
+
* Upserts an action_autostart_disables row; timed (--until) or indefinite.
|
|
20
|
+
*
|
|
21
|
+
* fazemos autostart enable --action <action-id>
|
|
22
|
+
* → POST /api/control-plane/autostart/disable
|
|
23
|
+
* { action: "enable", project_id, worksheet_action_id }
|
|
24
|
+
* Deletes the disable row (re-enables the action's auto-start).
|
|
25
|
+
*
|
|
26
|
+
* Auth: disable/enable require admin/owner (same as trigger/wake).
|
|
27
|
+
* list/status require any active org member.
|
|
28
|
+
* Scope: project-scoped reads (project_id query param); writes are org+project.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: `fire-now` is deliberately NOT offered in V1 — manual pipeline start is
|
|
31
|
+
* already `fazemos pl create`. A fire-now re-drive of a failed row is V2.
|
|
32
|
+
*
|
|
33
|
+
* Spec: AUTON-AUTOSTART-tech-spec.md §11 (R12, AC14)
|
|
34
|
+
* Manifest: cli_commands (fazemos autostart list/status/disable/enable)
|
|
35
|
+
*
|
|
36
|
+
* Key differences from trigger.ts:
|
|
37
|
+
* - No cadence dimension (action auto-start is per-action, per-window)
|
|
38
|
+
* - No fire-now command (V1 spec explicitly excludes it)
|
|
39
|
+
* - Bindings keyed by action_id + template_id (not role + cadence)
|
|
40
|
+
* - disable/enable keyed by --action <worksheet_action_id> (not --role + --cadence)
|
|
41
|
+
* - Endpoint: /api/control-plane/autostart and /api/control-plane/autostart/disable
|
|
42
|
+
*/
|
|
43
|
+
import chalk from 'chalk';
|
|
44
|
+
import { api } from './api.js';
|
|
45
|
+
import { getActiveProjectId } from './config.js';
|
|
46
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
47
|
+
/**
|
|
48
|
+
* Validate an ISO 8601 timestamp string (used for --until on disable).
|
|
49
|
+
* The API is strict — malformed timestamps produce a 400.
|
|
50
|
+
*/
|
|
51
|
+
function validateIsoTimestamp(value) {
|
|
52
|
+
const d = new Date(value);
|
|
53
|
+
if (isNaN(d.getTime())) {
|
|
54
|
+
throw new Error(`--until must be a valid ISO 8601 timestamp (e.g. 2026-12-31T23:59:59Z), got: ${value}`);
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Human-readable fire_status label with colour.
|
|
60
|
+
* Mirrors the action_pipeline_fires.fire_status CHECK values:
|
|
61
|
+
* 'claimed' → in progress; 'fired' → created + launched; 'failed' → errored.
|
|
62
|
+
*/
|
|
63
|
+
function fireStatusLabel(status) {
|
|
64
|
+
switch (status) {
|
|
65
|
+
case 'fired':
|
|
66
|
+
return chalk.green(status);
|
|
67
|
+
case 'failed':
|
|
68
|
+
return chalk.red(status);
|
|
69
|
+
case 'claimed':
|
|
70
|
+
return chalk.cyan(status);
|
|
71
|
+
default:
|
|
72
|
+
return chalk.dim(status);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// ── Command registration ───────────────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* Register `autostart list`, `autostart status`, `autostart disable`, and
|
|
78
|
+
* `autostart enable` into the root Commander program. Called from index.ts
|
|
79
|
+
* alongside registerTriggerCommands and registerWakeCommands.
|
|
80
|
+
*/
|
|
81
|
+
export function registerAutoStartCommands(program) {
|
|
82
|
+
// ── `fazemos autostart` ──────────────────────────────────────────────────────
|
|
83
|
+
//
|
|
84
|
+
// Parent command hosting sub-commands: list, status, disable, enable.
|
|
85
|
+
// The parent itself has no action (sub-commands always required).
|
|
86
|
+
const autoStartCmd = program
|
|
87
|
+
.command('autostart')
|
|
88
|
+
.description('Inspect and operate the action→pipeline auto-start control plane (AUTONOMY).\n\n' +
|
|
89
|
+
'Sub-commands:\n' +
|
|
90
|
+
' list List the allow-listed (action, template) auto-start bindings\n' +
|
|
91
|
+
' status Show bindings + recent fire history (last 50 entries)\n' +
|
|
92
|
+
' disable Disable auto-start for an action (timed or indefinite) (admin/owner)\n' +
|
|
93
|
+
' enable Re-enable a previously disabled action auto-start (admin/owner)\n\n' +
|
|
94
|
+
'list/status are readable by any active org member.\n' +
|
|
95
|
+
'disable/enable require admin or owner role.\n' +
|
|
96
|
+
'All operations are project-scoped (uses active project or --project override).\n\n' +
|
|
97
|
+
'The auto-start engine is GATED OFF by default (AUTOSTART_ALLOWLIST empty).\n' +
|
|
98
|
+
'An empty bindings list means the engine is dormant — this is the safe\n' +
|
|
99
|
+
'default state. The ENABLE flip is a separate founder step.');
|
|
100
|
+
// ── `fazemos autostart list` ──────────────────────────────────────────────────
|
|
101
|
+
//
|
|
102
|
+
// GET /api/control-plane/autostart?project_id=<id>
|
|
103
|
+
//
|
|
104
|
+
// Prints the allow-listed (action_id, template_id) bindings + enabled state.
|
|
105
|
+
// No --json flag needed (list is simple enough for human output only).
|
|
106
|
+
//
|
|
107
|
+
// Usage:
|
|
108
|
+
// fazemos autostart list
|
|
109
|
+
autoStartCmd
|
|
110
|
+
.command('list')
|
|
111
|
+
.description('List the configured auto-start bindings for the active project.\n\n' +
|
|
112
|
+
'Shows each allow-listed (action_id, template_id) pair and whether it is\n' +
|
|
113
|
+
'currently enabled. The binding list is driven by AUTOSTART_ALLOWLIST on\n' +
|
|
114
|
+
'the API; the enabled state reflects any operator disable in effect.\n\n' +
|
|
115
|
+
'An empty list means the engine is dormant (default safe state).\n\n' +
|
|
116
|
+
'Readable by any active org member.')
|
|
117
|
+
.action(async () => {
|
|
118
|
+
try {
|
|
119
|
+
const projectId = getActiveProjectId();
|
|
120
|
+
if (!projectId) {
|
|
121
|
+
throw new Error('No active project. Run `fazemos projects switch <slug>` first.');
|
|
122
|
+
}
|
|
123
|
+
const data = await api('GET', `/api/control-plane/autostart?project_id=${encodeURIComponent(projectId)}`, undefined, { noProjectHeader: true });
|
|
124
|
+
const { bindings } = data;
|
|
125
|
+
if (bindings.length === 0) {
|
|
126
|
+
console.log(chalk.yellow('No auto-start bindings configured (AUTOSTART_ALLOWLIST is empty or not set).\n' +
|
|
127
|
+
'The engine is dormant — this is the default safe state.'));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk.bold(`Auto-start bindings (${bindings.length} entries):`));
|
|
131
|
+
console.log();
|
|
132
|
+
for (const binding of bindings) {
|
|
133
|
+
const enabledLabel = binding.enabled
|
|
134
|
+
? chalk.green('enabled')
|
|
135
|
+
: chalk.red('disabled');
|
|
136
|
+
console.log(` ${chalk.cyan(binding.action_id)} ${enabledLabel}`);
|
|
137
|
+
console.log(` template: ${chalk.dim(binding.template_id)}`);
|
|
138
|
+
console.log();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
143
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
// ── `fazemos autostart status` ────────────────────────────────────────────────
|
|
148
|
+
//
|
|
149
|
+
// GET /api/control-plane/autostart?project_id=<id>
|
|
150
|
+
//
|
|
151
|
+
// bindings + recent action_pipeline_fires (window_key, fire_status,
|
|
152
|
+
// pipeline_instance_id, last_error, claimed_at, fired_at, failed_at).
|
|
153
|
+
// Fires capped at 50 most recent entries (ordered by claimed_at DESC) by the API.
|
|
154
|
+
//
|
|
155
|
+
// Usage:
|
|
156
|
+
// fazemos autostart status
|
|
157
|
+
// fazemos autostart status --json
|
|
158
|
+
autoStartCmd
|
|
159
|
+
.command('status')
|
|
160
|
+
.description('Show auto-start bindings and recent fire history for the active project.\n\n' +
|
|
161
|
+
'Prints the allow-listed (action, template) bindings alongside the last 50\n' +
|
|
162
|
+
'action_pipeline_fire records (window_key, fire_status, pipeline_instance_id).\n\n' +
|
|
163
|
+
'fire_status values:\n' +
|
|
164
|
+
' claimed — claim inserted; pipeline create + launch in progress\n' +
|
|
165
|
+
' fired — pipeline instance created and launched successfully\n' +
|
|
166
|
+
' failed — the create/launch attempt failed (see last_error)\n\n' +
|
|
167
|
+
'Note: suppressed fires do NOT appear in the ledger (the claim is deleted on\n' +
|
|
168
|
+
'suppression; `autostart_suppressed` is logged as an agent_event instead).\n\n' +
|
|
169
|
+
'Readable by any active org member. Use --json for machine-readable output.')
|
|
170
|
+
.option('--json', 'output machine-readable JSON')
|
|
171
|
+
.action(async (opts) => {
|
|
172
|
+
try {
|
|
173
|
+
const projectId = getActiveProjectId();
|
|
174
|
+
if (!projectId) {
|
|
175
|
+
throw new Error('No active project. Run `fazemos projects switch <slug>` first.');
|
|
176
|
+
}
|
|
177
|
+
const data = await api('GET', `/api/control-plane/autostart?project_id=${encodeURIComponent(projectId)}`, undefined, { noProjectHeader: true });
|
|
178
|
+
if (opts.json) {
|
|
179
|
+
console.log(JSON.stringify(data, null, 2));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const { bindings, fires } = data;
|
|
183
|
+
// ── Bindings ──────────────────────────────────────────────────────────
|
|
184
|
+
if (bindings.length === 0) {
|
|
185
|
+
console.log(chalk.yellow('No auto-start bindings configured (AUTOSTART_ALLOWLIST is empty or not set).'));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log(chalk.bold(`Auto-start bindings (${bindings.length} entries):`));
|
|
189
|
+
console.log();
|
|
190
|
+
for (const binding of bindings) {
|
|
191
|
+
const enabledLabel = binding.enabled
|
|
192
|
+
? chalk.green('enabled')
|
|
193
|
+
: chalk.red('disabled');
|
|
194
|
+
console.log(` ${chalk.cyan(binding.action_id)} ${enabledLabel}`);
|
|
195
|
+
console.log(` template: ${chalk.dim(binding.template_id)}`);
|
|
196
|
+
}
|
|
197
|
+
console.log();
|
|
198
|
+
}
|
|
199
|
+
// ── Recent fires ──────────────────────────────────────────────────────
|
|
200
|
+
if (fires.length === 0) {
|
|
201
|
+
console.log(chalk.dim('No recent auto-start fires.'));
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
console.log(chalk.bold(`Recent auto-start fires (${fires.length}):`));
|
|
205
|
+
console.log();
|
|
206
|
+
for (const fire of fires) {
|
|
207
|
+
const statusLabel = fireStatusLabel(fire.fire_status);
|
|
208
|
+
console.log(` ${chalk.cyan(fire.worksheet_action_id.slice(0, 8) + '…')} window: ${fire.window_key} ${statusLabel}`);
|
|
209
|
+
if (fire.pipeline_instance_id) {
|
|
210
|
+
console.log(` pipeline: ${chalk.dim(fire.pipeline_instance_id)}`);
|
|
211
|
+
}
|
|
212
|
+
if (fire.template_id) {
|
|
213
|
+
console.log(` template: ${chalk.dim(fire.template_id)}`);
|
|
214
|
+
}
|
|
215
|
+
if (fire.last_error) {
|
|
216
|
+
console.log(` error: ${chalk.red(fire.last_error)}`);
|
|
217
|
+
}
|
|
218
|
+
console.log(` claimed: ${new Date(fire.claimed_at).toLocaleString()}`);
|
|
219
|
+
if (fire.fired_at) {
|
|
220
|
+
console.log(` fired: ${new Date(fire.fired_at).toLocaleString()}`);
|
|
221
|
+
}
|
|
222
|
+
if (fire.failed_at) {
|
|
223
|
+
console.log(` failed: ${chalk.red(new Date(fire.failed_at).toLocaleString())}`);
|
|
224
|
+
}
|
|
225
|
+
console.log(` id: ${chalk.dim(fire.id)}`);
|
|
226
|
+
console.log();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
231
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
// ── `fazemos autostart disable` ───────────────────────────────────────────────
|
|
236
|
+
//
|
|
237
|
+
// POST /api/control-plane/autostart/disable { action: "disable", ... }
|
|
238
|
+
//
|
|
239
|
+
// Upserts an action_autostart_disables row the sweep consults before claiming.
|
|
240
|
+
// Active disable → action not eligible → no claim, no fire.
|
|
241
|
+
// --until <iso>: timed disable; omit for indefinite until `fazemos autostart enable`.
|
|
242
|
+
//
|
|
243
|
+
// Note: does NOT delete the action from the AUTOSTART_ALLOWLIST (that is an
|
|
244
|
+
// SSM / deployment-level change). The disable row is the operator kill switch.
|
|
245
|
+
//
|
|
246
|
+
// Usage:
|
|
247
|
+
// fazemos autostart disable --action <action-id> --reason "Pausing during Q2 freeze"
|
|
248
|
+
// fazemos autostart disable --action <action-id> --until 2026-12-31T23:59:59Z --reason "Q2 freeze"
|
|
249
|
+
autoStartCmd
|
|
250
|
+
.command('disable')
|
|
251
|
+
.description('Disable auto-start for an action (admin/owner only).\n\n' +
|
|
252
|
+
'Upserts a disable record for the given action. While disabled, the auto-start\n' +
|
|
253
|
+
'sweep skips this action — no claim, no fire. The action\'s readiness state\n' +
|
|
254
|
+
'(auto_start=\'ready\') is preserved; re-enabling allows the next sweep to fire.\n\n' +
|
|
255
|
+
' (no --until) Indefinite disable — remains until `fazemos autostart enable`\n' +
|
|
256
|
+
' --until <iso> Timed disable — auto-expires at the given UTC timestamp\n\n' +
|
|
257
|
+
'Requires admin or owner role. --reason is mandatory (audit trail).')
|
|
258
|
+
.requiredOption('--action <id>', 'worksheet_action_id (UUID) to disable')
|
|
259
|
+
.requiredOption('--reason <text>', 'reason for the disable (required for audit trail)')
|
|
260
|
+
.option('--until <iso>', 'ISO 8601 timestamp when the disable expires (omit for indefinite)')
|
|
261
|
+
.option('--json', 'output machine-readable JSON')
|
|
262
|
+
.action(async (opts) => {
|
|
263
|
+
try {
|
|
264
|
+
const projectId = getActiveProjectId();
|
|
265
|
+
if (!projectId) {
|
|
266
|
+
throw new Error('No active project. Run `fazemos projects switch <slug>` first.');
|
|
267
|
+
}
|
|
268
|
+
const body = {
|
|
269
|
+
action: 'disable',
|
|
270
|
+
project_id: projectId,
|
|
271
|
+
worksheet_action_id: opts.action.trim(),
|
|
272
|
+
reason: opts.reason,
|
|
273
|
+
};
|
|
274
|
+
if (opts.until !== undefined) {
|
|
275
|
+
body.until = validateIsoTimestamp(opts.until);
|
|
276
|
+
}
|
|
277
|
+
const data = await api('POST', '/api/control-plane/autostart/disable', body, {
|
|
278
|
+
noProjectHeader: true,
|
|
279
|
+
});
|
|
280
|
+
if (opts.json) {
|
|
281
|
+
console.log(JSON.stringify(data, null, 2));
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
if (data.disabled) {
|
|
285
|
+
console.log(chalk.red(`⏸ Auto-start disabled for action: ${chalk.cyan(opts.action.trim())}`));
|
|
286
|
+
if (opts.until) {
|
|
287
|
+
console.log(` Expires at: ${new Date(opts.until).toLocaleString()}`);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
console.log(` Duration: indefinite (run \`fazemos autostart enable --action ${opts.action.trim()}\` to re-enable)`);
|
|
291
|
+
}
|
|
292
|
+
console.log(` Reason: ${opts.reason}`);
|
|
293
|
+
console.log();
|
|
294
|
+
console.log(chalk.dim(' The action remains in the AUTOSTART_ALLOWLIST.'));
|
|
295
|
+
console.log(chalk.dim(' The sweep will skip it until the disable is removed or expires.'));
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
console.log(chalk.yellow(`No change — auto-start was already disabled for action ${opts.action.trim()}.`));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
303
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
304
|
+
process.exit(1);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
// ── `fazemos autostart enable` ────────────────────────────────────────────────
|
|
308
|
+
//
|
|
309
|
+
// POST /api/control-plane/autostart/disable { action: "enable", ... }
|
|
310
|
+
//
|
|
311
|
+
// Deletes the action_autostart_disables row (re-enables the action's auto-start).
|
|
312
|
+
// After enable: the next sweep tick that finds this action ready + allow-listed
|
|
313
|
+
// will claim and fire as normal (subject to windowed-claim and live-pipeline checks).
|
|
314
|
+
//
|
|
315
|
+
// Usage:
|
|
316
|
+
// fazemos autostart enable --action <action-id>
|
|
317
|
+
autoStartCmd
|
|
318
|
+
.command('enable')
|
|
319
|
+
.description('Re-enable auto-start for a previously disabled action (admin/owner only).\n\n' +
|
|
320
|
+
'Deletes the disable record for the given action, allowing the next auto-start\n' +
|
|
321
|
+
'sweep tick to evaluate and fire it (subject to the windowed-claim and\n' +
|
|
322
|
+
'live-pipeline idempotency checks — one pipeline per window maximum).\n\n' +
|
|
323
|
+
'Requires admin or owner role.')
|
|
324
|
+
.requiredOption('--action <id>', 'worksheet_action_id (UUID) to re-enable')
|
|
325
|
+
.option('--reason <text>', 'reason for re-enabling (optional; recorded in audit trail)')
|
|
326
|
+
.option('--json', 'output machine-readable JSON')
|
|
327
|
+
.action(async (opts) => {
|
|
328
|
+
try {
|
|
329
|
+
const projectId = getActiveProjectId();
|
|
330
|
+
if (!projectId) {
|
|
331
|
+
throw new Error('No active project. Run `fazemos projects switch <slug>` first.');
|
|
332
|
+
}
|
|
333
|
+
const body = {
|
|
334
|
+
action: 'enable',
|
|
335
|
+
project_id: projectId,
|
|
336
|
+
worksheet_action_id: opts.action.trim(),
|
|
337
|
+
};
|
|
338
|
+
if (opts.reason !== undefined) {
|
|
339
|
+
body.reason = opts.reason;
|
|
340
|
+
}
|
|
341
|
+
const data = await api('POST', '/api/control-plane/autostart/disable', body, {
|
|
342
|
+
noProjectHeader: true,
|
|
343
|
+
});
|
|
344
|
+
if (opts.json) {
|
|
345
|
+
console.log(JSON.stringify(data, null, 2));
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
if (data.enabled) {
|
|
349
|
+
console.log(chalk.green(`▶ Auto-start enabled for action: ${chalk.cyan(opts.action.trim())}`));
|
|
350
|
+
console.log(` The next sweep tick (≤5 min) will evaluate and fire this action`);
|
|
351
|
+
console.log(` if it is still ready, allow-listed, and has no live pipeline.`);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
console.log(chalk.dim(`No-op — auto-start was not disabled for action ${opts.action.trim()}.`));
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
359
|
+
console.error(chalk.red(`Error: ${msg}`));
|
|
360
|
+
process.exit(1);
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=autostart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autostart.js","sourceRoot":"","sources":["../src/autostart.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { registerBudgetCommands } from './budget.js';
|
|
|
21
21
|
import { registerTriggerCommands } from './trigger.js';
|
|
22
22
|
import { registerWakeCommands } from './wake.js';
|
|
23
23
|
import { registerGovernanceCommands } from './governance.js';
|
|
24
|
+
import { registerAutoStartCommands } from './autostart.js';
|
|
24
25
|
import { parseExecutionsJson, resolveWaitOptions, waitForPipelines, buildAwsCommand, validateExecutionEntry, } from './wait-for-pipeline.js';
|
|
25
26
|
import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync, statSync } from 'fs';
|
|
26
27
|
import { fileURLToPath } from 'url';
|
|
@@ -2383,8 +2384,20 @@ ws
|
|
|
2383
2384
|
.argument('<id>', 'Worksheet ID')
|
|
2384
2385
|
.action(async (id) => {
|
|
2385
2386
|
try {
|
|
2386
|
-
|
|
2387
|
+
// G4 (AC15): fetch enriched actions in parallel so we can display
|
|
2388
|
+
// linked_pipeline status chips next to bound actions.
|
|
2389
|
+
const [data, actionsResult] = await Promise.all([
|
|
2390
|
+
api('GET', `/api/worksheets/${id}`),
|
|
2391
|
+
api('GET', `/api/worksheets/${id}/actions`).catch(() => null),
|
|
2392
|
+
]);
|
|
2387
2393
|
const w = data.worksheet;
|
|
2394
|
+
// Build a lookup map from action id → linked_pipeline (from the enriched endpoint)
|
|
2395
|
+
const actionPipelineMap = new Map();
|
|
2396
|
+
if (actionsResult?.actions) {
|
|
2397
|
+
for (const a of actionsResult.actions) {
|
|
2398
|
+
actionPipelineMap.set(a.id, a.linked_pipeline ?? null);
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2388
2401
|
console.log(chalk.cyan(w.name));
|
|
2389
2402
|
console.log(` ID: ${w.id}`);
|
|
2390
2403
|
console.log(` Purpose: ${w.purpose || '(none)'}`);
|
|
@@ -2414,7 +2427,16 @@ ws
|
|
|
2414
2427
|
console.log(chalk.cyan(`\n Actions (${data.actions.length}):`));
|
|
2415
2428
|
for (const a of data.actions) {
|
|
2416
2429
|
const progress = a.target_value ? ` ${a.current_value ?? 0}/${a.target_value}` : '';
|
|
2417
|
-
|
|
2430
|
+
// G4 (AC15): show pipeline status chip when action is bound to a pipeline
|
|
2431
|
+
const linkedPipeline = actionPipelineMap.get(a.id);
|
|
2432
|
+
let pipelineChip = '';
|
|
2433
|
+
if (linkedPipeline) {
|
|
2434
|
+
const chipColor = linkedPipeline.status === 'completed' ? chalk.green :
|
|
2435
|
+
linkedPipeline.status === 'failed' ? chalk.red :
|
|
2436
|
+
chalk.yellow;
|
|
2437
|
+
pipelineChip = ` ${chipColor(`[${linkedPipeline.status}]`)}`;
|
|
2438
|
+
}
|
|
2439
|
+
console.log(` ${chalk.cyan(a.description)}${progress}${pipelineChip} — ${a.member_name || 'unassigned'} — ${a.id}`);
|
|
2418
2440
|
}
|
|
2419
2441
|
}
|
|
2420
2442
|
if (data.commitments?.length) {
|
|
@@ -4808,17 +4830,29 @@ pipelines
|
|
|
4808
4830
|
.argument('<templateId>', 'Template ID')
|
|
4809
4831
|
.requiredOption('-n, --name <name>', 'Instance name')
|
|
4810
4832
|
.option('--params <json>', 'Parameters as JSON string')
|
|
4833
|
+
.option('--action <action-id>', 'Bind to a worksheet action at creation time (UUID)')
|
|
4811
4834
|
.action(async (templateId, opts) => {
|
|
4812
4835
|
try {
|
|
4813
4836
|
const body = { templateId, name: opts.name };
|
|
4814
4837
|
if (opts.params)
|
|
4815
4838
|
body.parameters = parseJson(opts.params, '--params');
|
|
4839
|
+
// G4: optionally bind to a worksheet action at creation time (AC12)
|
|
4840
|
+
if (opts.action)
|
|
4841
|
+
body.worksheetActionId = opts.action;
|
|
4816
4842
|
const data = await api('POST', '/api/pipeline-instances', body);
|
|
4817
4843
|
const inst = data.instance;
|
|
4818
4844
|
console.log(chalk.green(`Created: ${inst.name}`));
|
|
4819
4845
|
console.log(` ID: ${inst.id}`);
|
|
4846
|
+
if (inst.worksheet_action_id) {
|
|
4847
|
+
console.log(` Bound Action: ${inst.worksheet_action_id}`);
|
|
4848
|
+
}
|
|
4820
4849
|
}
|
|
4821
4850
|
catch (err) {
|
|
4851
|
+
// G4: org-isolation guard fires when the action belongs to a different org (AC11)
|
|
4852
|
+
if (err instanceof ApiError && err.code === 'BINDING_ORG_ISOLATION_FAILED') {
|
|
4853
|
+
console.error(chalk.red('Binding failed: the action belongs to a different org than this pipeline.'));
|
|
4854
|
+
process.exit(1);
|
|
4855
|
+
}
|
|
4822
4856
|
// F16 — Role-aware Connection-unavailable error (tech spec §5.14).
|
|
4823
4857
|
// The pipeline-run path returns a structured payload when the
|
|
4824
4858
|
// Project's Connection is missing/revoked/suspended/uninstalled.
|
|
@@ -4855,6 +4889,50 @@ pipelines
|
|
|
4855
4889
|
process.exit(1);
|
|
4856
4890
|
}
|
|
4857
4891
|
});
|
|
4892
|
+
// G4 — Bind an existing pipeline instance to a worksheet action (AC13)
|
|
4893
|
+
pipelines
|
|
4894
|
+
.command('bind')
|
|
4895
|
+
.description('Bind an existing pipeline instance to a worksheet action')
|
|
4896
|
+
.argument('<instance-id>', 'Pipeline instance ID')
|
|
4897
|
+
.requiredOption('--action <action-id>', 'Worksheet action UUID to bind')
|
|
4898
|
+
.action(async (instanceId, opts) => {
|
|
4899
|
+
try {
|
|
4900
|
+
const data = await api('PATCH', `/api/pipeline-instances/${instanceId}`, {
|
|
4901
|
+
worksheetActionId: opts.action,
|
|
4902
|
+
});
|
|
4903
|
+
const inst = data.instance;
|
|
4904
|
+
console.log(chalk.green(`Bound: ${inst.name}`));
|
|
4905
|
+
console.log(` Pipeline: ${inst.id}`);
|
|
4906
|
+
console.log(` Action: ${inst.worksheet_action_id}`);
|
|
4907
|
+
}
|
|
4908
|
+
catch (err) {
|
|
4909
|
+
if (err instanceof ApiError && err.code === 'BINDING_ORG_ISOLATION_FAILED') {
|
|
4910
|
+
console.error(chalk.red('Binding failed: the action belongs to a different org than this pipeline.'));
|
|
4911
|
+
process.exit(1);
|
|
4912
|
+
}
|
|
4913
|
+
console.error(chalk.red(err.message));
|
|
4914
|
+
process.exit(1);
|
|
4915
|
+
}
|
|
4916
|
+
});
|
|
4917
|
+
// G4 — Remove binding between a pipeline instance and a worksheet action (AC14)
|
|
4918
|
+
pipelines
|
|
4919
|
+
.command('unbind')
|
|
4920
|
+
.description('Remove binding between a pipeline instance and a worksheet action')
|
|
4921
|
+
.argument('<instance-id>', 'Pipeline instance ID')
|
|
4922
|
+
.action(async (instanceId) => {
|
|
4923
|
+
try {
|
|
4924
|
+
const data = await api('PATCH', `/api/pipeline-instances/${instanceId}`, {
|
|
4925
|
+
worksheetActionId: null,
|
|
4926
|
+
});
|
|
4927
|
+
const inst = data.instance;
|
|
4928
|
+
console.log(chalk.green(`Unbound: ${inst.name}`));
|
|
4929
|
+
console.log(` Pipeline: ${inst.id}`);
|
|
4930
|
+
}
|
|
4931
|
+
catch (err) {
|
|
4932
|
+
console.error(chalk.red(err.message));
|
|
4933
|
+
process.exit(1);
|
|
4934
|
+
}
|
|
4935
|
+
});
|
|
4858
4936
|
// I30 — `pl force-cancel` removed. Replaced by the generalised
|
|
4859
4937
|
// `pl force-transition pipeline <id> --to cancelled` admin endpoint, which
|
|
4860
4938
|
// covers the same emergency cancel path plus 12 more entity/state combos
|
|
@@ -5765,10 +5843,12 @@ program
|
|
|
5765
5843
|
const executions = program.command('executions').alias('ex').description('Execution commands');
|
|
5766
5844
|
executions
|
|
5767
5845
|
.command('list')
|
|
5768
|
-
.description('List executions')
|
|
5846
|
+
.description('List executions in the active project (or all projects with --all-projects)')
|
|
5769
5847
|
.option('-s, --status <status>', 'Filter by status (pending, running, completed, failed)')
|
|
5770
5848
|
.option('-a, --agent <name>', 'Filter by agent')
|
|
5771
5849
|
.option('--source-type <type>', 'Filter by source type')
|
|
5850
|
+
.option('--project <slug>', 'Override active project for this call')
|
|
5851
|
+
.option('--all-projects', 'List executions across every project in the active org', false)
|
|
5772
5852
|
.action(async (opts) => {
|
|
5773
5853
|
try {
|
|
5774
5854
|
const params = [];
|
|
@@ -5779,7 +5859,7 @@ executions
|
|
|
5779
5859
|
if (opts.sourceType)
|
|
5780
5860
|
params.push(`source_type=${opts.sourceType}`);
|
|
5781
5861
|
const qs = params.length ? `?${params.join('&')}` : '';
|
|
5782
|
-
const data = await api('GET', `/api/executions${qs}
|
|
5862
|
+
const data = await api('GET', `/api/executions${qs}`, undefined, projectOpts(opts));
|
|
5783
5863
|
if (!data.executions?.length) {
|
|
5784
5864
|
console.log(chalk.yellow('No executions'));
|
|
5785
5865
|
return;
|
|
@@ -5790,12 +5870,20 @@ executions
|
|
|
5790
5870
|
: e.status === 'failed' ? chalk.red('✗')
|
|
5791
5871
|
: '○';
|
|
5792
5872
|
const cost = e.cost_usd ? ` $${e.cost_usd}` : '';
|
|
5793
|
-
|
|
5873
|
+
// AUTON-PORTFOLIO-VIEW — in the org-wide fleet view (--all-projects),
|
|
5874
|
+
// surface which project each execution belongs to so the list is
|
|
5875
|
+
// legible across projects. Degrades gracefully to project_id (the
|
|
5876
|
+
// executions list payload today includes project_id but not slug/name)
|
|
5877
|
+
// and is omitted entirely in the default single-project view where a
|
|
5878
|
+
// project column would be redundant.
|
|
5879
|
+
const projectCell = opts.allProjects
|
|
5880
|
+
? chalk.gray(` [${e.project_slug || e.project_name || e.project_id || '—'}]`)
|
|
5881
|
+
: '';
|
|
5882
|
+
console.log(` ${icon} ${e.agent_name} — ${e.source_type} (${e.status})${cost}${projectCell} — ${e.id}`);
|
|
5794
5883
|
}
|
|
5795
5884
|
}
|
|
5796
5885
|
catch (err) {
|
|
5797
|
-
|
|
5798
|
-
process.exit(1);
|
|
5886
|
+
handleScopedError(err);
|
|
5799
5887
|
}
|
|
5800
5888
|
});
|
|
5801
5889
|
executions
|
|
@@ -9432,6 +9520,13 @@ registerWakeCommands(program);
|
|
|
9432
9520
|
// Cross-Org read (noProjectHeader: true); server resolves orgIds[] + roleSlugs[]
|
|
9433
9521
|
// via resolveCallerContext. Read-only in v1 — no write sub-commands (AC1).
|
|
9434
9522
|
registerGovernanceCommands(program);
|
|
9523
|
+
// ── AUTON-AUTOSTART — Action→Pipeline Auto-Start: autostart list/status/disable/enable ──
|
|
9524
|
+
// Registers `autostart` top-level command with list, status, disable, and enable
|
|
9525
|
+
// sub-commands. Project-scoped reads (project_id query param);
|
|
9526
|
+
// writes are org+project level (noProjectHeader: true on all calls).
|
|
9527
|
+
// admin/owner required for disable/enable; any active member for list/status.
|
|
9528
|
+
// No fire-now in V1 (spec §11 explicitly excludes it).
|
|
9529
|
+
registerAutoStartCommands(program);
|
|
9435
9530
|
// Skip auto-parse only when running under Vitest (which sets process.env.VITEST).
|
|
9436
9531
|
// Tests import `program` and drive it via `program.parseAsync(...)` after mocking
|
|
9437
9532
|
// `./api.js`. In every other context — direct invocation, npx tsx, OR the bin
|