taskflow-core 0.2.6 → 0.2.8

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.
Files changed (42) hide show
  1. package/README.md +39 -5
  2. package/dist/analytics.d.ts +30 -0
  3. package/dist/analytics.d.ts.map +1 -0
  4. package/dist/analytics.js +127 -0
  5. package/dist/analytics.js.map +1 -0
  6. package/dist/build-info.json +2 -2
  7. package/dist/exec/step-kinds.d.ts +1 -1
  8. package/dist/exec/step-kinds.d.ts.map +1 -1
  9. package/dist/exec/step-kinds.js +26 -14
  10. package/dist/exec/step-kinds.js.map +1 -1
  11. package/dist/hooks.d.ts +73 -0
  12. package/dist/hooks.d.ts.map +1 -0
  13. package/dist/hooks.js +296 -0
  14. package/dist/hooks.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +4 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/preflight.d.ts +69 -0
  20. package/dist/preflight.d.ts.map +1 -0
  21. package/dist/preflight.js +389 -0
  22. package/dist/preflight.js.map +1 -0
  23. package/dist/runtime/phases/approval-wait.d.ts +33 -0
  24. package/dist/runtime/phases/approval-wait.d.ts.map +1 -0
  25. package/dist/runtime/phases/approval-wait.js +95 -0
  26. package/dist/runtime/phases/approval-wait.js.map +1 -0
  27. package/dist/runtime/phases/approval.d.ts +1 -1
  28. package/dist/runtime/phases/approval.d.ts.map +1 -1
  29. package/dist/runtime/phases/approval.js +10 -6
  30. package/dist/runtime/phases/approval.js.map +1 -1
  31. package/dist/runtime.d.ts.map +1 -1
  32. package/dist/runtime.js +40 -11
  33. package/dist/runtime.js.map +1 -1
  34. package/dist/savings.d.ts +36 -0
  35. package/dist/savings.d.ts.map +1 -0
  36. package/dist/savings.js +76 -0
  37. package/dist/savings.js.map +1 -0
  38. package/dist/schema.d.ts +31 -0
  39. package/dist/schema.d.ts.map +1 -1
  40. package/dist/schema.js +123 -0
  41. package/dist/schema.js.map +1 -1
  42. package/package.json +1 -1
package/dist/runtime.js CHANGED
@@ -2360,6 +2360,7 @@ async function executePhaseInner(phase, state, deps, prior, emitProgress, _retry
2360
2360
  // approval — HITL pause (decision → PhaseState in runtime/phases/approval.ts)
2361
2361
  if (type === "approval") {
2362
2362
  const { approvalDecisionToPhaseState } = await import("./runtime/phases/approval.js");
2363
+ const { resolveApprovalDecision } = await import("./runtime/phases/approval-wait.js");
2363
2364
  const readRefs = [];
2364
2365
  const ctx = buildInterpolationContext(state, previousOutput, undefined, (ref) => readRefs.push(ref));
2365
2366
  const message = interpolate(phase.task ?? "Approve to continue?", ctx).text;
@@ -2369,20 +2370,31 @@ async function executePhaseInner(phase, state, deps, prior, emitProgress, _retry
2369
2370
  if (cached)
2370
2371
  return cached;
2371
2372
  const reads = readRefsToReads(readRefs, state);
2372
- // Non-interactive (headless/CI/detached): auto-REJECT — safety boundary, never bypass.
2373
- if (!deps.requestApproval) {
2374
- return approvalDecisionToPhaseState(phase.id, { decision: "reject" }, {
2373
+ const resolved = await resolveApprovalDecision({
2374
+ phase,
2375
+ message,
2376
+ upstream: previousOutput,
2377
+ requestApproval: deps.requestApproval,
2378
+ signal: deps.signal,
2379
+ });
2380
+ if (resolved.kind === "fail") {
2381
+ return {
2382
+ id: phase.id,
2383
+ status: "failed",
2384
+ error: resolved.error,
2385
+ output: resolved.error,
2386
+ approval: { decision: "reject", auto: true, note: "approval-expired" },
2387
+ usage: emptyUsage(),
2375
2388
  inputHash,
2376
2389
  reads,
2377
- auto: true,
2378
- });
2390
+ endedAt: Date.now(),
2391
+ };
2379
2392
  }
2380
- const decision = await deps.requestApproval({
2381
- phaseId: phase.id,
2382
- message,
2383
- upstream: previousOutput,
2393
+ return approvalDecisionToPhaseState(phase.id, resolved.decision, {
2394
+ inputHash,
2395
+ reads,
2396
+ auto: resolved.auto,
2384
2397
  });
2385
- return approvalDecisionToPhaseState(phase.id, decision, { inputHash, reads });
2386
2398
  }
2387
2399
  if (type === "flow" || type === "expand") {
2388
2400
  const readRefs = [];
@@ -3814,7 +3826,7 @@ export async function executeTaskflow(state, deps) {
3814
3826
  if (!deps.runTask) {
3815
3827
  throw new Error("event kernel requires RuntimeDeps.runTask");
3816
3828
  }
3817
- return await runEventKernel(state, {
3829
+ const kernelResult = await runEventKernel(state, {
3818
3830
  cwd: deps.cwd,
3819
3831
  agents: deps.agents,
3820
3832
  runTask: deps.runTask,
@@ -3831,6 +3843,8 @@ export async function executeTaskflow(state, deps) {
3831
3843
  _stack: deps._stack,
3832
3844
  _dynamic: deps._dynamic,
3833
3845
  });
3846
+ await maybeDispatchTerminalHooks(kernelResult.state, deps.cwd, def);
3847
+ return kernelResult;
3834
3848
  }
3835
3849
  return await runTaskflowLayers(state, deps);
3836
3850
  }
@@ -4112,7 +4126,9 @@ async function runTaskflowLayers(state, deps) {
4112
4126
  // window where a successful detached run permanently lost its final output.
4113
4127
  state.finalOutput = finalOutput;
4114
4128
  state.outputSourcePhaseId = outputSourcePhaseId;
4129
+ state.updatedAt = Date.now();
4115
4130
  safeEmit(deps, state);
4131
+ await maybeDispatchTerminalHooks(state, deps.cwd, def);
4116
4132
  const totalUsage = aggregateUsage(Object.values(state.phases).map((p) => p.usage ?? emptyUsage()));
4117
4133
  return {
4118
4134
  state,
@@ -4123,4 +4139,17 @@ async function runTaskflowLayers(state, deps) {
4123
4139
  outputSourcePhaseId,
4124
4140
  };
4125
4141
  }
4142
+ /** Fire-and-forget terminal hooks; never throws into the runtime outcome. */
4143
+ async function maybeDispatchTerminalHooks(state, cwd, def) {
4144
+ try {
4145
+ const hooks = def.hooks;
4146
+ if (!hooks)
4147
+ return;
4148
+ const { dispatchHooks } = await import("./hooks.js");
4149
+ await dispatchHooks(state, { cwd, hooks });
4150
+ }
4151
+ catch {
4152
+ /* hooks must never replace the runtime outcome */
4153
+ }
4154
+ }
4126
4155
  //# sourceMappingURL=runtime.js.map