@gobing-ai/ts-dual-workflow-engine 0.3.12 → 0.3.16

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.
@@ -45,6 +45,21 @@ export class DbWorkflowPersistenceAdapter {
45
45
  await this.db.run(`INSERT INTO workflow_states (id, run_id, state, data_json, created_at, updated_at)
46
46
  VALUES (?, ?, ?, ?, ?, ?)`, `${runId}:state:${state}:${crypto.randomUUID()}`, runId, state, JSON.stringify(data), now, now);
47
47
  }
48
+ /** Insert a running action row. Returns the row id for later finalization. */
49
+ async saveActionStart(runId, node, kind) {
50
+ const id = crypto.randomUUID();
51
+ const now = Date.now();
52
+ await this.db.run(`INSERT INTO action_runs (id, run_id, node, kind, status, started_at, created_at, updated_at)
53
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, id, runId, node, kind, 'running', new Date(now).toISOString(), now, now);
54
+ return id;
55
+ }
56
+ /** Finalize an action row with duration, ok flag, and optional redacted result. */
57
+ async saveActionFinalize(actionId, status, durationMs, ok, result, _redactor) {
58
+ const now = Date.now();
59
+ await this.db.run(`UPDATE action_runs
60
+ SET status = ?, duration_ms = ?, ok = ?, result_json = ?, completed_at = ?, updated_at = ?
61
+ WHERE id = ?`, status, durationMs, ok ? 1 : 0, result !== undefined ? JSON.stringify(result) : null, new Date(now).toISOString(), now, actionId);
62
+ }
48
63
  /** Load a single run by id. */
49
64
  async loadRun(runId) {
50
65
  await applyWorkflowEngineSchema(this.db);
@@ -75,6 +90,32 @@ export class MemoryWorkflowPersistenceAdapter {
75
90
  if (run !== undefined)
76
91
  this.runs.set(runId, { ...run, status, completed_at: completedAt });
77
92
  }
93
+ actionRuns = [];
94
+ /** Insert a running action row. */
95
+ async saveActionStart(runId, node, kind) {
96
+ const id = crypto.randomUUID();
97
+ this.actionRuns.push({
98
+ id,
99
+ runId,
100
+ node,
101
+ kind,
102
+ status: 'running',
103
+ durationMs: null,
104
+ ok: null,
105
+ resultJson: null,
106
+ });
107
+ return id;
108
+ }
109
+ /** Finalize an action row. */
110
+ async saveActionFinalize(actionId, status, durationMs, ok, result, _redactor) {
111
+ const row = this.actionRuns.find((a) => a.id === actionId);
112
+ if (row === undefined)
113
+ return;
114
+ row.status = status;
115
+ row.durationMs = durationMs;
116
+ row.ok = ok ? 1 : 0;
117
+ row.resultJson = result !== undefined ? JSON.stringify(result) : null;
118
+ }
78
119
  /** Save one phase/state execution record. */
79
120
  async savePhase(runId, phase, status) {
80
121
  this.phases.push({ runId, phase, status });
@@ -52,6 +52,12 @@ export declare class RunLifecycle {
52
52
  actionDone(stateOrNodeId: string, kind: string, durationMs: number, ok: boolean): void;
53
53
  /** Log and trace a non-fatal action failure for the 'continue' error policy (ADR-013 observability seam). */
54
54
  warnActionFailed(stateOrNodeId: string, transitionsTaken: number, error?: string): void;
55
+ /** Emit a guard evaluation result (fired for every guard, including rejected). */
56
+ guardEvaluated(from: string, to: string, kind: string, passed: boolean): void;
57
+ /** Emit when an interactive HITL prompt is presented. */
58
+ hitlAsk(node: string, kind: string, message: string): void;
59
+ /** Emit when an interactive HITL prompt resolves. */
60
+ hitlResponse(node: string, ok: boolean): void;
55
61
  private result;
56
62
  private runRecord;
57
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../src/run-lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../src/run-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -62,8 +62,18 @@ export class RunLifecycle {
62
62
  return await traceAsync('workflow.run', async () => {
63
63
  await lifecycle.persistence.createRun(lifecycle.runRecord(options.metadata));
64
64
  lifecycle.logger.info('workflow run started');
65
- addSpanEvent('workflow.run.started', { workflowName, mode, runId });
66
- void lifecycle.events?.emit('workflow.run.started', { workflowName, mode, runId });
65
+ addSpanEvent('workflow.run.started', {
66
+ workflowName,
67
+ mode,
68
+ runId,
69
+ dryRun: options.dryRun ?? false,
70
+ });
71
+ void lifecycle.events?.emit('workflow.run.started', {
72
+ workflowName,
73
+ mode,
74
+ runId,
75
+ dryRun: options.dryRun ?? false,
76
+ });
67
77
  return await loop(lifecycle);
68
78
  }, { attributes: { 'workflow.name': workflowName, 'workflow.mode': mode, 'workflow.run_id': runId } });
69
79
  }
@@ -71,57 +81,101 @@ export class RunLifecycle {
71
81
  async enter(stateOrNodeId, transitionsTaken) {
72
82
  await this.persistence.saveWorkflowState(this.runId, stateOrNodeId, { transitionsTaken });
73
83
  await this.persistence.savePhase(this.runId, stateOrNodeId, 'running');
74
- addSpanEvent('workflow.node.enter', { node: stateOrNodeId, transitionsTaken });
75
- void this.events?.emit('workflow.node.enter', { node: stateOrNodeId, transitionsTaken });
84
+ addSpanEvent('workflow.node.enter', {
85
+ runId: this.runId,
86
+ node: stateOrNodeId,
87
+ transitionsTaken,
88
+ });
89
+ void this.events?.emit('workflow.node.enter', {
90
+ runId: this.runId,
91
+ node: stateOrNodeId,
92
+ transitionsTaken,
93
+ });
76
94
  }
77
95
  /** Persist a transition and emit its observability event. */
78
96
  async recordTransition(from, to, trigger) {
79
97
  await this.persistence.saveTransition(this.runId, from, to, trigger);
80
- addSpanEvent('workflow.node.transition', { from, to, ...(trigger === null ? {} : { trigger }) });
81
- void this.events?.emit('workflow.node.transition', { from, to, trigger });
98
+ addSpanEvent('workflow.node.transition', {
99
+ runId: this.runId,
100
+ from,
101
+ to,
102
+ ...(trigger === null ? {} : { trigger }),
103
+ });
104
+ void this.events?.emit('workflow.node.transition', {
105
+ runId: this.runId,
106
+ from,
107
+ to,
108
+ trigger,
109
+ });
82
110
  }
83
111
  /** Finalize the run as succeeded and return its result. */
84
112
  async done(finalState, transitionsTaken) {
85
113
  await this.persistence.savePhase(this.runId, finalState, 'done');
86
114
  await this.persistence.finalizeRun(this.runId, 'done', new Date().toISOString());
87
115
  this.logger.info('workflow run done', { finalState, transitionsTaken });
88
- addSpanEvent('workflow.run.done', { finalState, transitionsTaken });
89
- void this.events?.emit('workflow.run.done', { finalState, transitionsTaken });
116
+ addSpanEvent('workflow.run.done', { runId: this.runId, finalState, transitionsTaken });
117
+ void this.events?.emit('workflow.run.done', { runId: this.runId, finalState, transitionsTaken });
90
118
  return this.result('done', finalState, transitionsTaken);
91
119
  }
92
120
  /** Finalize the run as failed and return its result. */
93
121
  async fail(finalState, transitionsTaken, reason = 'failed') {
94
122
  await this.persistence.savePhase(this.runId, finalState, 'failed');
95
123
  await this.persistence.finalizeRun(this.runId, 'failed', new Date().toISOString());
96
- addSpanEvent('workflow.run.failed', { finalState, reason });
97
- void this.events?.emit('workflow.run.failed', { finalState, reason });
124
+ addSpanEvent('workflow.run.failed', { runId: this.runId, finalState, reason });
125
+ void this.events?.emit('workflow.run.failed', { runId: this.runId, finalState, reason });
98
126
  this.logger.warn('workflow run failed', { finalState, transitionsTaken, reason });
99
127
  return this.result('failed', finalState, transitionsTaken, reason);
100
128
  }
101
129
  /** Emit action-level observability before a host action is invoked. */
102
130
  actionStart(stateOrNodeId, kind) {
103
- addSpanEvent('workflow.action.start', { node: stateOrNodeId, kind });
104
- void this.events?.emit('workflow.action.start', { node: stateOrNodeId, kind });
131
+ addSpanEvent('workflow.action.start', { runId: this.runId, node: stateOrNodeId, kind });
132
+ void this.events?.emit('workflow.action.start', { runId: this.runId, node: stateOrNodeId, kind });
105
133
  }
106
134
  /** Emit action-level observability after a host action settles. */
107
135
  actionDone(stateOrNodeId, kind, durationMs, ok) {
108
- addSpanEvent('workflow.action.done', { node: stateOrNodeId, kind, durationMs, ok });
109
- void this.events?.emit('workflow.action.done', { node: stateOrNodeId, kind, durationMs, ok });
136
+ addSpanEvent('workflow.action.done', { runId: this.runId, node: stateOrNodeId, kind, durationMs, ok });
137
+ void this.events?.emit('workflow.action.done', {
138
+ runId: this.runId,
139
+ node: stateOrNodeId,
140
+ kind,
141
+ durationMs,
142
+ ok,
143
+ });
110
144
  }
111
145
  /** Log and trace a non-fatal action failure for the 'continue' error policy (ADR-013 observability seam). */
112
146
  warnActionFailed(stateOrNodeId, transitionsTaken, error) {
113
147
  addSpanEvent('workflow.action.failed_continue', {
148
+ runId: this.runId,
114
149
  node: stateOrNodeId,
115
150
  transitionsTaken,
116
151
  ...(error === undefined ? {} : { error }),
117
152
  });
118
153
  void this.events?.emit('workflow.action.failed_continue', {
154
+ runId: this.runId,
119
155
  node: stateOrNodeId,
120
156
  transitionsTaken,
121
157
  ...(error === undefined ? {} : { error }),
122
158
  });
123
159
  this.logger.warn('action failed (continuing)', { node: stateOrNodeId, transitionsTaken, error });
124
160
  }
161
+ /** Emit a guard evaluation result (fired for every guard, including rejected). */
162
+ guardEvaluated(from, to, kind, passed) {
163
+ void this.events?.emit('workflow.guard.evaluated', {
164
+ runId: this.runId,
165
+ from,
166
+ to,
167
+ kind,
168
+ passed,
169
+ });
170
+ }
171
+ /** Emit when an interactive HITL prompt is presented. */
172
+ hitlAsk(node, kind, message) {
173
+ void this.events?.emit('workflow.hitl.ask', { runId: this.runId, node, kind, message });
174
+ }
175
+ /** Emit when an interactive HITL prompt resolves. */
176
+ hitlResponse(node, ok) {
177
+ void this.events?.emit('workflow.hitl.response', { runId: this.runId, node, ok });
178
+ }
125
179
  result(status, finalState, transitionsTaken, reason) {
126
180
  return {
127
181
  runId: this.runId,
@@ -1,3 +1,3 @@
1
- /** SQL DDL for the dual-workflow engine's persistent schema — runs, phase_runs, transition_runs, and workflow_states tables. */
1
+ /** SQL DDL for the dual-workflow engine's persistent schema — runs, phase_runs, transition_runs, workflow_states, and action_runs tables. */
2
2
  export declare const WORKFLOW_ENGINE_SCHEMA_SQL: string;
3
3
  //# sourceMappingURL=schema-sql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-sql.d.ts","sourceRoot":"","sources":["../src/schema-sql.ts"],"names":[],"mappings":"AAAA,gIAAgI;AAChI,eAAO,MAAM,0BAA0B,QA+C/B,CAAC"}
1
+ {"version":3,"file":"schema-sql.d.ts","sourceRoot":"","sources":["../src/schema-sql.ts"],"names":[],"mappings":"AAAA,6IAA6I;AAC7I,eAAO,MAAM,0BAA0B,QA8D/B,CAAC"}
@@ -1,4 +1,4 @@
1
- /** SQL DDL for the dual-workflow engine's persistent schema — runs, phase_runs, transition_runs, and workflow_states tables. */
1
+ /** SQL DDL for the dual-workflow engine's persistent schema — runs, phase_runs, transition_runs, workflow_states, and action_runs tables. */
2
2
  export const WORKFLOW_ENGINE_SCHEMA_SQL = `
3
3
  CREATE TABLE IF NOT EXISTS runs (
4
4
  id TEXT PRIMARY KEY,
@@ -36,7 +36,6 @@ CREATE TABLE IF NOT EXISTS transition_runs (
36
36
  updated_at INTEGER NOT NULL DEFAULT 0,
37
37
  FOREIGN KEY (run_id) REFERENCES runs(id)
38
38
  );
39
-
40
39
  CREATE TABLE IF NOT EXISTS workflow_states (
41
40
  id TEXT PRIMARY KEY,
42
41
  run_id TEXT NOT NULL,
@@ -46,4 +45,20 @@ CREATE TABLE IF NOT EXISTS workflow_states (
46
45
  updated_at INTEGER NOT NULL DEFAULT 0,
47
46
  FOREIGN KEY (run_id) REFERENCES runs(id)
48
47
  );
48
+
49
+ CREATE TABLE IF NOT EXISTS action_runs (
50
+ id TEXT PRIMARY KEY,
51
+ run_id TEXT NOT NULL,
52
+ node TEXT NOT NULL,
53
+ kind TEXT NOT NULL,
54
+ status TEXT NOT NULL,
55
+ duration_ms INTEGER,
56
+ ok INTEGER,
57
+ result_json TEXT,
58
+ started_at TEXT,
59
+ completed_at TEXT,
60
+ created_at INTEGER NOT NULL DEFAULT 0,
61
+ updated_at INTEGER NOT NULL DEFAULT 0,
62
+ FOREIGN KEY (run_id) REFERENCES runs(id)
63
+ );
49
64
  `.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../src/state-machine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAIR,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAGjB,yDAAyD;AACzD,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;CACpD;AAED,wEAAwE;AACxE,qBAAa,kBAAkB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,yBAAyB;IAE/D,6DAA6D;IACvD,GAAG,CAAC,QAAQ,EAAE,uBAAuB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAU5F,IAAI;IA8FlB;;;;;OAKG;YACW,UAAU;CA+C3B"}
1
+ {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../src/state-machine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAIR,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAGjB,yDAAyD;AACzD,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;CACpD;AAED,wEAAwE;AACxE,qBAAa,kBAAkB;IACf,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,yBAAyB;IAE/D,6DAA6D;IACvD,GAAG,CAAC,QAAQ,EAAE,uBAAuB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAU5F,IAAI;IAoGlB;;;;;OAKG;YACW,UAAU;CAwD3B"}
@@ -54,7 +54,7 @@ export class StateMachineDriver {
54
54
  current: current.id,
55
55
  vars,
56
56
  lastActionResult,
57
- });
57
+ }, lifecycle);
58
58
  if (nextTransition === undefined) {
59
59
  return await lifecycle.fail(current.id, transitionsTaken, 'no-passing-transition');
60
60
  }
@@ -95,6 +95,7 @@ export class StateMachineDriver {
95
95
  env,
96
96
  builtins: runtimeBuiltins(workflowName, stateId, runId, transitionsTaken, 'state-machine'),
97
97
  });
98
+ const actionId = await this.options.persistence.saveActionStart(runId, stateId, action.kind);
98
99
  const actionStartMs = Date.now();
99
100
  lifecycle.actionStart(stateId, action.kind);
100
101
  try {
@@ -109,7 +110,9 @@ export class StateMachineDriver {
109
110
  });
110
111
  }
111
112
  finally {
112
- lifecycle.actionDone(stateId, action.kind, Date.now() - actionStartMs, last?.ok ?? false);
113
+ const durationMs = Date.now() - actionStartMs;
114
+ lifecycle.actionDone(stateId, action.kind, durationMs, last?.ok ?? false);
115
+ void this.options.persistence.saveActionFinalize(actionId, last?.ok !== false ? 'done' : 'failed', durationMs, last?.ok ?? false, last);
113
116
  }
114
117
  if (last.terminal === true)
115
118
  return { outcome: 'terminal', result: last };
@@ -123,11 +126,13 @@ export class StateMachineDriver {
123
126
  return { outcome: 'completed', result: last };
124
127
  }
125
128
  }
126
- async function firstPassingTransition(transitions, host, context) {
129
+ async function firstPassingTransition(transitions, host, context, lifecycle) {
127
130
  for (const transition of transitions) {
128
131
  if (transition.guard === undefined)
129
132
  return transition;
130
- if (await host.evaluateGuard(transition.guard.kind, transition.guard.options ?? {}, context))
133
+ const passed = await host.evaluateGuard(transition.guard.kind, transition.guard.options ?? {}, context);
134
+ lifecycle.guardEvaluated(context.current, transition.to, transition.guard.kind, passed);
135
+ if (passed)
131
136
  return transition;
132
137
  }
133
138
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"transition-flow.d.ts","sourceRoot":"","sources":["../src/transition-flow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAER,yBAAyB,EACzB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAGjB,2DAA2D;AAC3D,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;CACpD;AAED,0EAA0E;AAC1E,qBAAa,oBAAoB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAEjE,+DAA+D;IACzD,GAAG,CAAC,QAAQ,EAAE,yBAAyB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAU9F,IAAI;CAqGrB"}
1
+ {"version":3,"file":"transition-flow.d.ts","sourceRoot":"","sources":["../src/transition-flow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAEjD,OAAO,KAAK,EAER,yBAAyB,EACzB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACpB,MAAM,SAAS,CAAC;AAGjB,2DAA2D;AAC3D,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,0BAA0B,CAAC;CACpD;AAED,0EAA0E;AAC1E,qBAAa,oBAAoB;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,2BAA2B;IAEjE,+DAA+D;IACzD,GAAG,CAAC,QAAQ,EAAE,yBAAyB,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAU9F,IAAI;CA6GrB"}
@@ -30,7 +30,6 @@ export class TransitionFlowDriver {
30
30
  await lifecycle.enter(current.id, transitionsTaken);
31
31
  // 2. Execute the node action when one is configured (skipped in dry-run).
32
32
  if (options.dryRun) {
33
- // dry-run: skip action execution, continue to next node
34
33
  if (current.action !== undefined) {
35
34
  lastActionResult = undefined;
36
35
  }
@@ -41,6 +40,7 @@ export class TransitionFlowDriver {
41
40
  env,
42
41
  builtins: runtimeBuiltins(workflow.name, current.id, runId, transitionsTaken, 'transition-flow'),
43
42
  });
43
+ const actionId = await this.options.persistence.saveActionStart(runId, current.id, current.action.kind);
44
44
  const actionStartMs = Date.now();
45
45
  lifecycle.actionStart(current.id, current.action.kind);
46
46
  try {
@@ -55,7 +55,9 @@ export class TransitionFlowDriver {
55
55
  });
56
56
  }
57
57
  finally {
58
- lifecycle.actionDone(current.id, current.action.kind, Date.now() - actionStartMs, lastActionResult?.ok ?? false);
58
+ const durationMs = Date.now() - actionStartMs;
59
+ lifecycle.actionDone(current.id, current.action.kind, durationMs, lastActionResult?.ok ?? false);
60
+ void this.options.persistence.saveActionFinalize(actionId, lastActionResult?.ok !== false ? 'done' : 'failed', durationMs, lastActionResult?.ok ?? false, lastActionResult);
59
61
  }
60
62
  if (lastActionResult.setVars)
61
63
  vars = mergeSetVars(vars, lastActionResult.setVars);
@@ -81,7 +83,7 @@ export class TransitionFlowDriver {
81
83
  current: current.id,
82
84
  vars,
83
85
  lastActionResult,
84
- });
86
+ }, lifecycle);
85
87
  if (edge === undefined) {
86
88
  return await lifecycle.fail(current.id, transitionsTaken, 'no-passing-edge');
87
89
  }
@@ -100,11 +102,13 @@ export class TransitionFlowDriver {
100
102
  }
101
103
  }
102
104
  }
103
- async function firstPassingEdge(edges, host, context) {
105
+ async function firstPassingEdge(edges, host, context, lifecycle) {
104
106
  for (const edge of edges) {
105
107
  if (edge.condition === undefined)
106
108
  return edge;
107
- if (await host.evaluateGuard(edge.condition.kind, edge.condition.options ?? {}, context))
109
+ const passed = await host.evaluateGuard(edge.condition.kind, edge.condition.options ?? {}, context);
110
+ lifecycle.guardEvaluated(context.current, edge.to, edge.condition.kind, passed);
111
+ if (passed)
108
112
  return edge;
109
113
  }
110
114
  return undefined;
package/dist/types.d.ts CHANGED
@@ -164,6 +164,21 @@ export interface WorkflowRunRecord {
164
164
  readonly completed_at: string | null;
165
165
  readonly metadata_json: string;
166
166
  }
167
+ /** Persisted action run record — one row per action executed in a workflow run. */
168
+ export interface ActionRunRecord {
169
+ readonly id: string;
170
+ readonly run_id: string;
171
+ readonly node: string;
172
+ readonly kind: string;
173
+ readonly status: WorkflowStatus;
174
+ readonly duration_ms: number | null;
175
+ readonly ok: number | null;
176
+ readonly result_json: string | null;
177
+ readonly started_at: string | null;
178
+ readonly completed_at: string | null;
179
+ }
180
+ /** Optional redaction hook: given action options, return sanitized options for persistence. */
181
+ export type ActionRedactor = (kind: string, options: Record<string, unknown>) => Record<string, unknown>;
167
182
  /** Persistence adapter implemented by DB-backed and test stores. */
168
183
  export interface WorkflowPersistenceAdapter {
169
184
  createRun(record: WorkflowRunRecord): Promise<void>;
@@ -171,6 +186,10 @@ export interface WorkflowPersistenceAdapter {
171
186
  savePhase(runId: string, phase: string, status: WorkflowStatus): Promise<void>;
172
187
  saveTransition(runId: string, from: string, to: string, trigger: string | null): Promise<void>;
173
188
  saveWorkflowState(runId: string, state: string, data: Record<string, unknown>): Promise<void>;
189
+ /** Two-phase action persistence: insert a running row at action start. Returns the action row id. */
190
+ saveActionStart(runId: string, node: string, kind: string): Promise<string>;
191
+ /** Finalize an action row with duration, ok, result. */
192
+ saveActionFinalize(actionId: string, status: WorkflowStatus, durationMs: number, ok: boolean, result?: unknown, redactor?: ActionRedactor): Promise<void>;
174
193
  loadRun(runId: string): Promise<WorkflowRunRecord | undefined>;
175
194
  listRuns(): Promise<readonly WorkflowRunRecord[]>;
176
195
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErD,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3D,8EAA8E;AAC9E,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C,8DAA8D;AAC9D,MAAM,WAAW,GAAG;IAChB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,oGAAoG;IACpG,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;CACpC;AAED,8FAA8F;AAC9F,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED,6CAA6C;AAC7C,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;CAC1C;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;CAC7B;AAED,yCAAyC;AACzC,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,CAAC;CAClD;AAED,uCAAuC;AACvC,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED,uCAAuC;AACvC,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;CACjC;AAED,2CAA2C;AAC3C,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG,yBAAyB,CAAC;AAE9E,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,iHAAiH;IACjH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;CACpD;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;CAC3B;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/F;AAED,gCAAgC;AAChC,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC;CAC5C;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvF;AAED,oCAAoC;AACpC,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC;AAED,oEAAoE;AACpE,MAAM,WAAW,0BAA0B;IACvC,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvF,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9F,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC/D,QAAQ,IAAI,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;CACrD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErD,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE3D,8EAA8E;AAC9E,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C,8DAA8D;AAC9D,MAAM,WAAW,GAAG;IAChB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,mEAAmE;AACnE,MAAM,WAAW,SAAS;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,oGAAoG;IACpG,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;CACpC;AAED,8FAA8F;AAC9F,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED,6CAA6C;AAC7C,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;CAC1C;AAED,kDAAkD;AAClD,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;CAC7B;AAED,yCAAyC;AACzC,MAAM,WAAW,uBAAuB;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,QAAQ,CAAC,WAAW,EAAE,SAAS,aAAa,EAAE,CAAC;CAClD;AAED,uCAAuC;AACvC,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;IAC5D,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED,uCAAuC;AACvC,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC;CACjC;AAED,2CAA2C;AAC3C,MAAM,WAAW,yBAAyB;IACtC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;CAC1C;AAED,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG,uBAAuB,GAAG,yBAAyB,CAAC;AAE9E,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,iHAAiH;IACjH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;CACpD;AAED,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,mGAAmG;IACnG,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;CAC3B;AAED,oEAAoE;AACpE,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/F;AAED,gCAAgC;AAChC,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,YAAY,CAAC;CAC5C;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACvF;AAED,oCAAoC;AACpC,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,iBAAiB,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAClC;AAED,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,+FAA+F;AAC/F,MAAM,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzG,oEAAoE;AACpE,MAAM,WAAW,0BAA0B;IACvC,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvF,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/F,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9F,qGAAqG;IACrG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5E,wDAAwD;IACxD,kBAAkB,CACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,OAAO,EACX,MAAM,CAAC,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,cAAc,GAC1B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC/D,QAAQ,IAAI,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;CACrD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-dual-workflow-engine",
3
- "version": "0.3.12",
3
+ "version": "0.3.16",
4
4
  "description": "@gobing-ai/ts-dual-workflow-engine — State-machine and transition-flow workflow runtime.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -48,9 +48,9 @@
48
48
  "release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-dual-workflow-engine-v<version> && git push --tags' && exit 1"
49
49
  },
50
50
  "dependencies": {
51
- "@gobing-ai/ts-db": "^0.3.12",
52
- "@gobing-ai/ts-infra": "^0.3.12",
53
- "@gobing-ai/ts-runtime": "^0.3.12",
51
+ "@gobing-ai/ts-db": "^0.3.16",
52
+ "@gobing-ai/ts-infra": "^0.3.16",
53
+ "@gobing-ai/ts-runtime": "^0.3.16",
54
54
  "zod": "^4.1.0"
55
55
  },
56
56
  "devDependencies": {
package/src/events.ts CHANGED
@@ -1,23 +1,46 @@
1
1
  /** Typed event map for workflow-engine run observability. All events prefixed `workflow.`. */
2
2
  export type WorkflowEngineEvents = {
3
3
  /** Emitted when a run begins (inside the span). */
4
- 'workflow.run.started': (data: { workflowName: string; mode: string; runId: string }) => void;
4
+ 'workflow.run.started': (data: { workflowName: string; mode: string; runId: string; dryRun: boolean }) => void;
5
5
  /** Emitted when a run completes successfully. */
6
- 'workflow.run.done': (data: { finalState: string; transitionsTaken: number }) => void;
6
+ 'workflow.run.done': (data: { runId: string; finalState: string; transitionsTaken: number }) => void;
7
7
  /** Emitted when a run fails. */
8
- 'workflow.run.failed': (data: { finalState: string; reason: string }) => void;
8
+ 'workflow.run.failed': (data: { runId: string; finalState: string; reason: string }) => void;
9
9
  /** Emitted when entering a state or node. */
10
- 'workflow.node.enter': (data: { node: string; transitionsTaken: number }) => void;
10
+ 'workflow.node.enter': (data: { runId: string; node: string; transitionsTaken: number }) => void;
11
11
  /** Emitted on a state/node transition. */
12
- 'workflow.node.transition': (data: { from: string; to: string; trigger: string | null }) => void;
12
+ 'workflow.node.transition': (data: { runId: string; from: string; to: string; trigger: string | null }) => void;
13
13
  /** Emitted when an action starts executing. */
14
- 'workflow.action.start': (data: { node: string; kind: string }) => void;
14
+ 'workflow.action.start': (data: { runId: string; node: string; kind: string }) => void;
15
15
  /** Emitted when an action finishes executing (success or failure). */
16
- 'workflow.action.done': (data: { node: string; kind: string; durationMs: number; ok: boolean }) => void;
16
+ 'workflow.action.done': (data: {
17
+ runId: string;
18
+ node: string;
19
+ kind: string;
20
+ durationMs: number;
21
+ ok: boolean;
22
+ }) => void;
17
23
  /** Emitted when a non-fatal action failure is continued past (onError: 'continue'). */
18
- 'workflow.action.failed_continue': (data: { node: string; transitionsTaken: number; error?: string }) => void;
24
+ 'workflow.action.failed_continue': (data: {
25
+ runId: string;
26
+ node: string;
27
+ transitionsTaken: number;
28
+ error?: string;
29
+ }) => void;
19
30
  /** Emitted by the builtin `event.emit` action for custom user-defined events. */
20
31
  'workflow.custom': (data: { name: string; payload: Record<string, unknown> }) => void;
21
32
  /** Emitted by the builtin `note` action for workflow-visible annotations. */
22
- 'workflow.hitl.note': (data: { node: string; message: string }) => void;
33
+ 'workflow.hitl.note': (data: { runId: string; node: string; message: string }) => void;
34
+ /** Emitted when a guard condition is evaluated. Fires for every guard, including rejected ones. */
35
+ 'workflow.guard.evaluated': (data: {
36
+ runId: string;
37
+ from: string;
38
+ to: string;
39
+ kind: string;
40
+ passed: boolean;
41
+ }) => void;
42
+ /** Emitted when an interactive HITL prompt is presented and the engine waits for input. */
43
+ 'workflow.hitl.ask': (data: { runId: string; node: string; kind: string; message: string }) => void;
44
+ /** Emitted when an interactive HITL prompt receives a response. */
45
+ 'workflow.hitl.response': (data: { runId: string; node: string; ok: boolean }) => void;
23
46
  };
package/src/host.ts CHANGED
@@ -92,7 +92,11 @@ export class NoteActionRunner implements ActionRunner {
92
92
  /** Execute a no-op note action with observable event emission. */
93
93
  async execute(options: Record<string, unknown>, context?: ActionRunContext): Promise<ActionResult> {
94
94
  const message = String(options.message ?? '');
95
- void context?.events?.emit('workflow.hitl.note', { node: context.stateOrNodeId, message });
95
+ void context?.events?.emit('workflow.hitl.note', {
96
+ runId: context.runId,
97
+ node: context.stateOrNodeId,
98
+ message,
99
+ });
96
100
  return { ok: true, data: { message } };
97
101
  }
98
102
  }
package/src/index.ts CHANGED
@@ -42,9 +42,11 @@ export { StateMachineDriver, type StateMachineDriverOptions } from './state-mach
42
42
  export { TransitionFlowDriver, type TransitionFlowDriverOptions } from './transition-flow';
43
43
  export type {
44
44
  ActionDef,
45
+ ActionRedactor,
45
46
  ActionResult,
46
47
  ActionRunContext,
47
48
  ActionRunner,
49
+ ActionRunRecord,
48
50
  Env,
49
51
  FlowEdgeDef,
50
52
  FlowNodeDef,