@formigio/fazemos-cli 0.10.39 → 0.10.40
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/index.js +94 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2383,8 +2383,20 @@ ws
|
|
|
2383
2383
|
.argument('<id>', 'Worksheet ID')
|
|
2384
2384
|
.action(async (id) => {
|
|
2385
2385
|
try {
|
|
2386
|
-
|
|
2386
|
+
// G4 (AC15): fetch enriched actions in parallel so we can display
|
|
2387
|
+
// linked_pipeline status chips next to bound actions.
|
|
2388
|
+
const [data, actionsResult] = await Promise.all([
|
|
2389
|
+
api('GET', `/api/worksheets/${id}`),
|
|
2390
|
+
api('GET', `/api/worksheets/${id}/actions`).catch(() => null),
|
|
2391
|
+
]);
|
|
2387
2392
|
const w = data.worksheet;
|
|
2393
|
+
// Build a lookup map from action id → linked_pipeline (from the enriched endpoint)
|
|
2394
|
+
const actionPipelineMap = new Map();
|
|
2395
|
+
if (actionsResult?.actions) {
|
|
2396
|
+
for (const a of actionsResult.actions) {
|
|
2397
|
+
actionPipelineMap.set(a.id, a.linked_pipeline ?? null);
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2388
2400
|
console.log(chalk.cyan(w.name));
|
|
2389
2401
|
console.log(` ID: ${w.id}`);
|
|
2390
2402
|
console.log(` Purpose: ${w.purpose || '(none)'}`);
|
|
@@ -2414,7 +2426,16 @@ ws
|
|
|
2414
2426
|
console.log(chalk.cyan(`\n Actions (${data.actions.length}):`));
|
|
2415
2427
|
for (const a of data.actions) {
|
|
2416
2428
|
const progress = a.target_value ? ` ${a.current_value ?? 0}/${a.target_value}` : '';
|
|
2417
|
-
|
|
2429
|
+
// G4 (AC15): show pipeline status chip when action is bound to a pipeline
|
|
2430
|
+
const linkedPipeline = actionPipelineMap.get(a.id);
|
|
2431
|
+
let pipelineChip = '';
|
|
2432
|
+
if (linkedPipeline) {
|
|
2433
|
+
const chipColor = linkedPipeline.status === 'completed' ? chalk.green :
|
|
2434
|
+
linkedPipeline.status === 'failed' ? chalk.red :
|
|
2435
|
+
chalk.yellow;
|
|
2436
|
+
pipelineChip = ` ${chipColor(`[${linkedPipeline.status}]`)}`;
|
|
2437
|
+
}
|
|
2438
|
+
console.log(` ${chalk.cyan(a.description)}${progress}${pipelineChip} — ${a.member_name || 'unassigned'} — ${a.id}`);
|
|
2418
2439
|
}
|
|
2419
2440
|
}
|
|
2420
2441
|
if (data.commitments?.length) {
|
|
@@ -4808,17 +4829,29 @@ pipelines
|
|
|
4808
4829
|
.argument('<templateId>', 'Template ID')
|
|
4809
4830
|
.requiredOption('-n, --name <name>', 'Instance name')
|
|
4810
4831
|
.option('--params <json>', 'Parameters as JSON string')
|
|
4832
|
+
.option('--action <action-id>', 'Bind to a worksheet action at creation time (UUID)')
|
|
4811
4833
|
.action(async (templateId, opts) => {
|
|
4812
4834
|
try {
|
|
4813
4835
|
const body = { templateId, name: opts.name };
|
|
4814
4836
|
if (opts.params)
|
|
4815
4837
|
body.parameters = parseJson(opts.params, '--params');
|
|
4838
|
+
// G4: optionally bind to a worksheet action at creation time (AC12)
|
|
4839
|
+
if (opts.action)
|
|
4840
|
+
body.worksheetActionId = opts.action;
|
|
4816
4841
|
const data = await api('POST', '/api/pipeline-instances', body);
|
|
4817
4842
|
const inst = data.instance;
|
|
4818
4843
|
console.log(chalk.green(`Created: ${inst.name}`));
|
|
4819
4844
|
console.log(` ID: ${inst.id}`);
|
|
4845
|
+
if (inst.worksheet_action_id) {
|
|
4846
|
+
console.log(` Bound Action: ${inst.worksheet_action_id}`);
|
|
4847
|
+
}
|
|
4820
4848
|
}
|
|
4821
4849
|
catch (err) {
|
|
4850
|
+
// G4: org-isolation guard fires when the action belongs to a different org (AC11)
|
|
4851
|
+
if (err instanceof ApiError && err.code === 'BINDING_ORG_ISOLATION_FAILED') {
|
|
4852
|
+
console.error(chalk.red('Binding failed: the action belongs to a different org than this pipeline.'));
|
|
4853
|
+
process.exit(1);
|
|
4854
|
+
}
|
|
4822
4855
|
// F16 — Role-aware Connection-unavailable error (tech spec §5.14).
|
|
4823
4856
|
// The pipeline-run path returns a structured payload when the
|
|
4824
4857
|
// Project's Connection is missing/revoked/suspended/uninstalled.
|
|
@@ -4855,6 +4888,50 @@ pipelines
|
|
|
4855
4888
|
process.exit(1);
|
|
4856
4889
|
}
|
|
4857
4890
|
});
|
|
4891
|
+
// G4 — Bind an existing pipeline instance to a worksheet action (AC13)
|
|
4892
|
+
pipelines
|
|
4893
|
+
.command('bind')
|
|
4894
|
+
.description('Bind an existing pipeline instance to a worksheet action')
|
|
4895
|
+
.argument('<instance-id>', 'Pipeline instance ID')
|
|
4896
|
+
.requiredOption('--action <action-id>', 'Worksheet action UUID to bind')
|
|
4897
|
+
.action(async (instanceId, opts) => {
|
|
4898
|
+
try {
|
|
4899
|
+
const data = await api('PATCH', `/api/pipeline-instances/${instanceId}`, {
|
|
4900
|
+
worksheetActionId: opts.action,
|
|
4901
|
+
});
|
|
4902
|
+
const inst = data.instance;
|
|
4903
|
+
console.log(chalk.green(`Bound: ${inst.name}`));
|
|
4904
|
+
console.log(` Pipeline: ${inst.id}`);
|
|
4905
|
+
console.log(` Action: ${inst.worksheet_action_id}`);
|
|
4906
|
+
}
|
|
4907
|
+
catch (err) {
|
|
4908
|
+
if (err instanceof ApiError && err.code === 'BINDING_ORG_ISOLATION_FAILED') {
|
|
4909
|
+
console.error(chalk.red('Binding failed: the action belongs to a different org than this pipeline.'));
|
|
4910
|
+
process.exit(1);
|
|
4911
|
+
}
|
|
4912
|
+
console.error(chalk.red(err.message));
|
|
4913
|
+
process.exit(1);
|
|
4914
|
+
}
|
|
4915
|
+
});
|
|
4916
|
+
// G4 — Remove binding between a pipeline instance and a worksheet action (AC14)
|
|
4917
|
+
pipelines
|
|
4918
|
+
.command('unbind')
|
|
4919
|
+
.description('Remove binding between a pipeline instance and a worksheet action')
|
|
4920
|
+
.argument('<instance-id>', 'Pipeline instance ID')
|
|
4921
|
+
.action(async (instanceId) => {
|
|
4922
|
+
try {
|
|
4923
|
+
const data = await api('PATCH', `/api/pipeline-instances/${instanceId}`, {
|
|
4924
|
+
worksheetActionId: null,
|
|
4925
|
+
});
|
|
4926
|
+
const inst = data.instance;
|
|
4927
|
+
console.log(chalk.green(`Unbound: ${inst.name}`));
|
|
4928
|
+
console.log(` Pipeline: ${inst.id}`);
|
|
4929
|
+
}
|
|
4930
|
+
catch (err) {
|
|
4931
|
+
console.error(chalk.red(err.message));
|
|
4932
|
+
process.exit(1);
|
|
4933
|
+
}
|
|
4934
|
+
});
|
|
4858
4935
|
// I30 — `pl force-cancel` removed. Replaced by the generalised
|
|
4859
4936
|
// `pl force-transition pipeline <id> --to cancelled` admin endpoint, which
|
|
4860
4937
|
// covers the same emergency cancel path plus 12 more entity/state combos
|
|
@@ -5765,10 +5842,12 @@ program
|
|
|
5765
5842
|
const executions = program.command('executions').alias('ex').description('Execution commands');
|
|
5766
5843
|
executions
|
|
5767
5844
|
.command('list')
|
|
5768
|
-
.description('List executions')
|
|
5845
|
+
.description('List executions in the active project (or all projects with --all-projects)')
|
|
5769
5846
|
.option('-s, --status <status>', 'Filter by status (pending, running, completed, failed)')
|
|
5770
5847
|
.option('-a, --agent <name>', 'Filter by agent')
|
|
5771
5848
|
.option('--source-type <type>', 'Filter by source type')
|
|
5849
|
+
.option('--project <slug>', 'Override active project for this call')
|
|
5850
|
+
.option('--all-projects', 'List executions across every project in the active org', false)
|
|
5772
5851
|
.action(async (opts) => {
|
|
5773
5852
|
try {
|
|
5774
5853
|
const params = [];
|
|
@@ -5779,7 +5858,7 @@ executions
|
|
|
5779
5858
|
if (opts.sourceType)
|
|
5780
5859
|
params.push(`source_type=${opts.sourceType}`);
|
|
5781
5860
|
const qs = params.length ? `?${params.join('&')}` : '';
|
|
5782
|
-
const data = await api('GET', `/api/executions${qs}
|
|
5861
|
+
const data = await api('GET', `/api/executions${qs}`, undefined, projectOpts(opts));
|
|
5783
5862
|
if (!data.executions?.length) {
|
|
5784
5863
|
console.log(chalk.yellow('No executions'));
|
|
5785
5864
|
return;
|
|
@@ -5790,12 +5869,20 @@ executions
|
|
|
5790
5869
|
: e.status === 'failed' ? chalk.red('✗')
|
|
5791
5870
|
: '○';
|
|
5792
5871
|
const cost = e.cost_usd ? ` $${e.cost_usd}` : '';
|
|
5793
|
-
|
|
5872
|
+
// AUTON-PORTFOLIO-VIEW — in the org-wide fleet view (--all-projects),
|
|
5873
|
+
// surface which project each execution belongs to so the list is
|
|
5874
|
+
// legible across projects. Degrades gracefully to project_id (the
|
|
5875
|
+
// executions list payload today includes project_id but not slug/name)
|
|
5876
|
+
// and is omitted entirely in the default single-project view where a
|
|
5877
|
+
// project column would be redundant.
|
|
5878
|
+
const projectCell = opts.allProjects
|
|
5879
|
+
? chalk.gray(` [${e.project_slug || e.project_name || e.project_id || '—'}]`)
|
|
5880
|
+
: '';
|
|
5881
|
+
console.log(` ${icon} ${e.agent_name} — ${e.source_type} (${e.status})${cost}${projectCell} — ${e.id}`);
|
|
5794
5882
|
}
|
|
5795
5883
|
}
|
|
5796
5884
|
catch (err) {
|
|
5797
|
-
|
|
5798
|
-
process.exit(1);
|
|
5885
|
+
handleScopedError(err);
|
|
5799
5886
|
}
|
|
5800
5887
|
});
|
|
5801
5888
|
executions
|