@wichayutdew/pi-workflows 0.2.2 → 0.2.3

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.
@@ -51,11 +51,25 @@ export function pauseRun(
51
51
  status: 'paused',
52
52
  pausedFrom: run.status,
53
53
  pauseReason: reason || `Paused during step "${run.currentStepId}"`,
54
+ failedStepId: undefined,
54
55
  },
55
56
  now,
56
57
  );
57
58
  }
58
59
 
60
+ export function failRun(
61
+ run: WorkflowRun,
62
+ reason: string,
63
+ now: number,
64
+ ): WorkflowRun {
65
+ const paused = pauseRun(run, reason, now);
66
+ if (paused.status !== 'paused') return paused;
67
+ return {
68
+ ...paused,
69
+ failedStepId: paused.currentStepId,
70
+ };
71
+ }
72
+
59
73
  export function resumeRun(run: WorkflowRun, now: number): WorkflowRun {
60
74
  if (run.status !== 'paused') return run;
61
75
  return withUpdate(
@@ -64,6 +78,7 @@ export function resumeRun(run: WorkflowRun, now: number): WorkflowRun {
64
78
  status: run.pausedFrom ?? (run.pendingGate ? 'awaiting-gate' : 'running'),
65
79
  pauseReason: undefined,
66
80
  pausedFrom: undefined,
81
+ failedStepId: undefined,
67
82
  },
68
83
  now,
69
84
  );
@@ -80,6 +95,7 @@ export function abortRun(
80
95
  status: 'aborted',
81
96
  pauseReason: reason || 'Aborted by user',
82
97
  pausedFrom: undefined,
98
+ failedStepId: undefined,
83
99
  pendingGate: undefined,
84
100
  },
85
101
  now,
@@ -166,6 +182,7 @@ export function advanceRun(
166
182
  stepHandoff: summary,
167
183
  lastSummary: summary,
168
184
  gateFeedback: '',
185
+ ...(nextStep.gate ? { reviewedArtifact: '' } : {}),
169
186
  ...(overVisitLimit
170
187
  ? {
171
188
  pausedFrom: 'running' as const,
@@ -334,6 +351,31 @@ function retainedReviewedArtifact(
334
351
  return sourceRetained ? reviewedArtifact : '';
335
352
  }
336
353
 
354
+ function refreshApprovedGateHistory(
355
+ run: WorkflowRun,
356
+ workflow: LoadedWorkflow,
357
+ ): WorkflowRun {
358
+ const reviewedArtifact = run.reviewedArtifact ?? '';
359
+ if (!reviewedArtifact) return run;
360
+ let changed = false;
361
+ const history = run.history.map((entry) => {
362
+ const gate = workflow.definition.steps[entry.stepId]?.gate;
363
+ const currentDigest = workflow.stepDigests[entry.stepId];
364
+ if (
365
+ gate &&
366
+ currentDigest &&
367
+ entry.outcome === gate.approvedOutcome &&
368
+ entry.summary === reviewedArtifact &&
369
+ entry.stepDigest !== currentDigest
370
+ ) {
371
+ changed = true;
372
+ return { ...entry, stepDigest: currentDigest };
373
+ }
374
+ return entry;
375
+ });
376
+ return changed ? { ...run, history } : run;
377
+ }
378
+
337
379
  export function reconcileRun(
338
380
  run: WorkflowRun,
339
381
  workflow: LoadedWorkflow,
@@ -354,12 +396,13 @@ export function reconcileRun(
354
396
  error: `current step "${run.currentStepId}" was removed; abort or restore the configuration`,
355
397
  };
356
398
  }
399
+ const reconciledRun = refreshApprovedGateHistory(run, workflow);
357
400
 
358
- const changedHistoryIndex = run.history.findIndex(
401
+ const changedHistoryIndex = reconciledRun.history.findIndex(
359
402
  (entry) => workflow.stepDigests[entry.stepId] !== entry.stepDigest,
360
403
  );
361
404
  if (changedHistoryIndex >= 0) {
362
- const changedEntry = run.history[changedHistoryIndex];
405
+ const changedEntry = reconciledRun.history[changedHistoryIndex];
363
406
  if (!changedEntry || !workflow.definition.steps[changedEntry.stepId]) {
364
407
  return {
365
408
  changed: true,
@@ -367,19 +410,19 @@ export function reconcileRun(
367
410
  'a completed step was removed; abort or restore the configuration',
368
411
  };
369
412
  }
370
- const retainedHistory = run.history.slice(0, changedHistoryIndex);
413
+ const retainedHistory = reconciledRun.history.slice(0, changedHistoryIndex);
371
414
  const restartedStep = changedEntry.stepId;
372
415
  const stepHandoff = retainedHistory.at(-1)?.summary ?? '';
373
416
  const reviewedArtifact = retainedReviewedArtifact(
374
417
  workflow,
375
- run,
418
+ reconciledRun,
376
419
  retainedHistory,
377
420
  );
378
421
  return {
379
422
  changed: true,
380
423
  restartedStep,
381
424
  run: withUpdate(
382
- run,
425
+ reconciledRun,
383
426
  {
384
427
  workflowDigest: workflow.digest,
385
428
  status: 'paused',
@@ -392,6 +435,7 @@ export function reconcileRun(
392
435
  lastSummary: stepHandoff,
393
436
  pendingGate: undefined,
394
437
  pausedFrom: 'running',
438
+ failedStepId: undefined,
395
439
  pauseReason: `Configuration changed; restarted step "${restartedStep}"`,
396
440
  gateFeedback: '',
397
441
  },
@@ -401,12 +445,12 @@ export function reconcileRun(
401
445
  }
402
446
 
403
447
  const currentDigest = workflow.stepDigests[run.currentStepId] ?? '';
404
- const currentChanged = currentDigest !== run.currentStepDigest;
448
+ const currentChanged = currentDigest !== reconciledRun.currentStepDigest;
405
449
  return {
406
450
  changed: true,
407
451
  ...(currentChanged ? { restartedStep: run.currentStepId } : {}),
408
452
  run: withUpdate(
409
- run,
453
+ reconciledRun,
410
454
  {
411
455
  workflowDigest: workflow.digest,
412
456
  currentStepDigest: currentDigest,
@@ -415,6 +459,7 @@ export function reconcileRun(
415
459
  status: 'paused' as const,
416
460
  pendingGate: undefined,
417
461
  pausedFrom: 'running' as const,
462
+ failedStepId: undefined,
418
463
  pauseReason: `Configuration changed; restarted step "${run.currentStepId}"`,
419
464
  gateFeedback: '',
420
465
  }