@osolmaz/pi-workflows 0.15.3 → 0.16.1

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 (207) hide show
  1. package/README.md +24 -8
  2. package/dist/channels/adapter-entry.d.ts +3 -0
  3. package/dist/channels/adapter-entry.js +203 -0
  4. package/dist/channels/adapter-entry.js.map +1 -0
  5. package/dist/channels/config.d.ts +43 -0
  6. package/dist/channels/config.js +234 -0
  7. package/dist/channels/config.js.map +1 -0
  8. package/dist/channels/protocol.d.ts +94 -0
  9. package/dist/channels/protocol.js +219 -0
  10. package/dist/channels/protocol.js.map +1 -0
  11. package/dist/channels/telegram.d.ts +46 -0
  12. package/dist/channels/telegram.js +285 -0
  13. package/dist/channels/telegram.js.map +1 -0
  14. package/dist/client/activity.d.ts +2 -0
  15. package/dist/client/activity.js +6 -0
  16. package/dist/client/activity.js.map +1 -0
  17. package/dist/client/client.d.ts +102 -0
  18. package/dist/client/client.js +737 -0
  19. package/dist/client/client.js.map +1 -0
  20. package/dist/client/index.d.ts +3 -0
  21. package/dist/client/index.js +3 -0
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/client/materialize.d.ts +7 -0
  24. package/dist/client/materialize.js +177 -0
  25. package/dist/client/materialize.js.map +1 -0
  26. package/dist/client/protocol.d.ts +60 -0
  27. package/dist/client/protocol.js +275 -0
  28. package/dist/client/protocol.js.map +1 -0
  29. package/dist/client/resolver.d.ts +23 -0
  30. package/dist/client/resolver.js +2 -0
  31. package/dist/client/resolver.js.map +1 -0
  32. package/dist/client/view.d.ts +144 -0
  33. package/dist/client/view.js +3 -0
  34. package/dist/client/view.js.map +1 -0
  35. package/dist/controllers/index.d.ts +1 -1
  36. package/dist/controllers/index.js.map +1 -1
  37. package/dist/controllers/sqlite.d.ts +47 -157
  38. package/dist/controllers/sqlite.js +230 -406
  39. package/dist/controllers/sqlite.js.map +1 -1
  40. package/dist/extension/index.d.ts +23 -1
  41. package/dist/extension/index.js +734 -555
  42. package/dist/extension/index.js.map +1 -1
  43. package/dist/extension/recorder.d.ts +95 -0
  44. package/dist/extension/recorder.js +530 -0
  45. package/dist/extension/recorder.js.map +1 -0
  46. package/dist/extension/remote-recorder-store.d.ts +25 -0
  47. package/dist/extension/remote-recorder-store.js +81 -0
  48. package/dist/extension/remote-recorder-store.js.map +1 -0
  49. package/dist/extension/session-events.d.ts +134 -0
  50. package/dist/extension/session-events.js +60 -0
  51. package/dist/extension/session-events.js.map +1 -0
  52. package/dist/extension/session-view.d.ts +9 -2
  53. package/dist/extension/session-view.js +117 -51
  54. package/dist/extension/session-view.js.map +1 -1
  55. package/dist/extension/step-message.d.ts +6 -4
  56. package/dist/extension/step-message.js +12 -6
  57. package/dist/extension/step-message.js.map +1 -1
  58. package/dist/extension/widget.d.ts +3 -2
  59. package/dist/extension/widget.js +41 -24
  60. package/dist/extension/widget.js.map +1 -1
  61. package/dist/extension/workflow-message-coordinator.d.ts +27 -0
  62. package/dist/extension/workflow-message-coordinator.js +294 -0
  63. package/dist/extension/workflow-message-coordinator.js.map +1 -0
  64. package/dist/host/channel-effects.d.ts +72 -0
  65. package/dist/host/channel-effects.js +271 -0
  66. package/dist/host/channel-effects.js.map +1 -0
  67. package/dist/host/channel-supervisor.d.ts +21 -0
  68. package/dist/host/channel-supervisor.js +54 -0
  69. package/dist/host/channel-supervisor.js.map +1 -0
  70. package/dist/host/child-worker-supervisor.js +1 -1
  71. package/dist/host/child-worker-supervisor.js.map +1 -1
  72. package/dist/host/resolver-entry.d.ts +2 -23
  73. package/dist/host/resolver-entry.js +1 -1
  74. package/dist/host/resolver-entry.js.map +1 -1
  75. package/dist/host/runner.d.ts +54 -8
  76. package/dist/host/runner.js +1997 -305
  77. package/dist/host/runner.js.map +1 -1
  78. package/dist/host/state.d.ts +25 -19
  79. package/dist/host/state.js +303 -89
  80. package/dist/host/state.js.map +1 -1
  81. package/dist/host/view.d.ts +83 -0
  82. package/dist/host/view.js +975 -0
  83. package/dist/host/view.js.map +1 -0
  84. package/dist/host/worker-protocol.js +1 -1
  85. package/dist/host/worker-protocol.js.map +1 -1
  86. package/dist/state/database.d.ts +1 -0
  87. package/dist/state/database.js +15 -0
  88. package/dist/state/database.js.map +1 -1
  89. package/dist/state/prune.d.ts +3 -1
  90. package/dist/state/prune.js +9 -33
  91. package/dist/state/prune.js.map +1 -1
  92. package/dist/state/schema.js +88 -98
  93. package/dist/state/schema.js.map +1 -1
  94. package/dist/state/workflow-messages.d.ts +96 -0
  95. package/dist/state/workflow-messages.js +335 -0
  96. package/dist/state/workflow-messages.js.map +1 -0
  97. package/dist/viewer/backup.d.ts +2 -0
  98. package/dist/viewer/backup.js +28 -0
  99. package/dist/viewer/backup.js.map +1 -0
  100. package/dist/viewer/cli.d.ts +4 -0
  101. package/dist/viewer/cli.js +150 -170
  102. package/dist/viewer/cli.js.map +1 -1
  103. package/dist/viewer/render.js +1 -1
  104. package/dist/viewer/render.js.map +1 -1
  105. package/dist/viewer/tui.d.ts +5 -7
  106. package/dist/viewer/tui.js +245 -108
  107. package/dist/viewer/tui.js.map +1 -1
  108. package/dist/workflows/human-decision.d.ts +2 -0
  109. package/dist/workflows/human-decision.js +8 -2
  110. package/dist/workflows/human-decision.js.map +1 -1
  111. package/dist/workflows/index.d.ts +1 -1
  112. package/dist/workflows/index.js.map +1 -1
  113. package/dist/workflows/settings.d.ts +1 -8
  114. package/dist/workflows/settings.js.map +1 -1
  115. package/dist/workflows/store.d.ts +67 -20
  116. package/dist/workflows/store.js +451 -378
  117. package/dist/workflows/store.js.map +1 -1
  118. package/dist/workflows/tool-input.d.ts +21 -0
  119. package/dist/workflows/tool-input.js +23 -1
  120. package/dist/workflows/tool-input.js.map +1 -1
  121. package/dist/workflows/types.d.ts +5 -5
  122. package/dist/workflows/workflow-message-content.d.ts +38 -0
  123. package/dist/workflows/workflow-message-content.js +157 -0
  124. package/dist/workflows/workflow-message-content.js.map +1 -0
  125. package/docs/2026-08-18-herdr-piw-plan.md +2 -1
  126. package/docs/2026-08-20-durable-workflow-launch-plan.md +1 -1
  127. package/docs/2026-08-25-workflow-follow-ups.md +26 -50
  128. package/docs/2026-08-30-out-of-process-workflow-host-plan.md +3 -3
  129. package/docs/2026-09-01-restore-session-delivery-controls-plan.md +4 -0
  130. package/docs/2026-09-01-unified-workflow-client-plan.md +385 -0
  131. package/docs/2026-09-02-installed-live-e2e-plan.md +239 -0
  132. package/docs/2026-09-02-unify-workflow-messages-plan.md +562 -0
  133. package/docs/DEFERRED_TURNS.md +66 -294
  134. package/docs/HUMAN_DECISIONS.md +29 -30
  135. package/docs/HUMAN_DECISION_PRESENTATIONS.md +4 -11
  136. package/docs/SQLITE_STATE.md +31 -25
  137. package/docs/WORKFLOW_HOST.md +155 -77
  138. package/docs/WORKFLOW_STEP_MESSAGES.md +166 -75
  139. package/docs/development.md +2 -1
  140. package/docs/live-replay-protocol.md +74 -132
  141. package/docs/tui-viewer.md +12 -14
  142. package/docs/workflows.md +78 -28
  143. package/herdr-plugin.toml +1 -1
  144. package/package.json +9 -3
  145. package/plugins/herdr/viewer.mjs +14 -5
  146. package/protocol/client.v1.schema.json +137 -0
  147. package/protocol/fixtures/client-v1.json +23 -0
  148. package/src/channels/adapter-entry.ts +220 -0
  149. package/src/channels/config.ts +296 -0
  150. package/src/channels/protocol.ts +333 -0
  151. package/src/channels/telegram.ts +335 -0
  152. package/src/client/activity.ts +6 -0
  153. package/src/client/client.ts +939 -0
  154. package/src/client/index.ts +25 -0
  155. package/src/client/materialize.ts +228 -0
  156. package/src/client/protocol.ts +333 -0
  157. package/src/client/resolver.ts +26 -0
  158. package/src/client/view.ts +163 -0
  159. package/src/controllers/index.ts +0 -1
  160. package/src/controllers/sqlite.ts +339 -808
  161. package/src/extension/index.ts +853 -665
  162. package/src/extension/recorder.ts +687 -0
  163. package/src/extension/remote-recorder-store.ts +126 -0
  164. package/src/extension/session-events.ts +119 -0
  165. package/src/extension/session-view.ts +157 -51
  166. package/src/extension/step-message.ts +19 -9
  167. package/src/extension/widget.ts +53 -25
  168. package/src/extension/workflow-message-coordinator.ts +334 -0
  169. package/src/host/channel-effects.ts +465 -0
  170. package/src/host/channel-supervisor.ts +73 -0
  171. package/src/host/child-worker-supervisor.ts +1 -1
  172. package/src/host/resolver-entry.ts +11 -26
  173. package/src/host/runner.ts +2639 -450
  174. package/src/host/state.ts +404 -137
  175. package/src/host/view.ts +1212 -0
  176. package/src/host/worker-protocol.ts +1 -1
  177. package/src/state/database.ts +13 -0
  178. package/src/state/prune.ts +14 -42
  179. package/src/state/schema.ts +88 -98
  180. package/src/state/workflow-messages.ts +548 -0
  181. package/src/viewer/backup.ts +29 -0
  182. package/src/viewer/cli.ts +171 -185
  183. package/src/viewer/render.ts +1 -5
  184. package/src/viewer/tui.ts +261 -124
  185. package/src/workflows/human-decision.ts +18 -2
  186. package/src/workflows/index.ts +0 -1
  187. package/src/workflows/settings.ts +1 -20
  188. package/src/workflows/store.ts +650 -511
  189. package/src/workflows/tool-input.ts +36 -1
  190. package/src/workflows/types.ts +5 -5
  191. package/src/workflows/workflow-message-content.ts +197 -0
  192. package/dist/extension/decision-channels.d.ts +0 -134
  193. package/dist/extension/decision-channels.js +0 -1307
  194. package/dist/extension/decision-channels.js.map +0 -1
  195. package/dist/host/client.d.ts +0 -48
  196. package/dist/host/client.js +0 -216
  197. package/dist/host/client.js.map +0 -1
  198. package/dist/host/protocol.d.ts +0 -38
  199. package/dist/host/protocol.js +0 -156
  200. package/dist/host/protocol.js.map +0 -1
  201. package/dist/viewer/watch.d.ts +0 -6
  202. package/dist/viewer/watch.js +0 -46
  203. package/dist/viewer/watch.js.map +0 -1
  204. package/src/extension/decision-channels.ts +0 -1826
  205. package/src/host/client.ts +0 -293
  206. package/src/host/protocol.ts +0 -196
  207. package/src/viewer/watch.ts +0 -51
@@ -0,0 +1,335 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { canonicalJson } from "./json.js";
3
+ export const WORKFLOW_MESSAGE_SCHEMA = "pi-workflows.workflow-message.v1";
4
+ export const WORKFLOW_MESSAGE_CONTENT_SCHEMA = "pi-workflows.workflow-message-content.v1";
5
+ export const WORKFLOW_TURN_SCHEMA = "pi-workflows.workflow-turn.v1";
6
+ /** Durable workflow content that the host requires Pi to add to one origin session. */
7
+ export class WorkflowMessageStore {
8
+ state;
9
+ constructor(state) {
10
+ this.state = state;
11
+ }
12
+ create(options) {
13
+ validateContent(options.content, options.kind);
14
+ const now = options.now ?? Date.now();
15
+ const workflowMessageId = options.workflowMessageId ??
16
+ workflowMessageIdFor(options.kind, options.sourceId, options.idempotencyKey);
17
+ return this.state.transaction(() => {
18
+ const existing = this.get(workflowMessageId);
19
+ if (existing !== undefined) {
20
+ assertSameMessage(existing, options);
21
+ return existing;
22
+ }
23
+ const contentHash = this.state.putJson(options.content, now);
24
+ const order = (this.state.connection
25
+ .prepare(`SELECT COALESCE(MAX(order_number), 0) AS value
26
+ FROM workflow_messages WHERE target_session_id = ?`)
27
+ .get(options.targetSessionId).value ?? 0) + 1;
28
+ this.state.connection
29
+ .prepare(`INSERT INTO workflow_messages(
30
+ workflow_message_id, run_id, target_session_id, kind, source_id, content_hash,
31
+ order_number, status, pi_session_entry_id, created_at, updated_at
32
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', NULL, ?, ?)`)
33
+ .run(workflowMessageId, options.runId, options.targetSessionId, options.kind, options.sourceId, contentHash, order, now, now);
34
+ return this.require(workflowMessageId);
35
+ });
36
+ }
37
+ get(workflowMessageId) {
38
+ const row = this.state.connection
39
+ .prepare(`SELECT workflow_message_id AS workflowMessageId, run_id AS runId,
40
+ target_session_id AS targetSessionId, kind, source_id AS sourceId,
41
+ content_hash AS contentHash, order_number AS orderNumber, status,
42
+ pi_session_entry_id AS piSessionEntryId, created_at AS createdAt,
43
+ updated_at AS updatedAt
44
+ FROM workflow_messages WHERE workflow_message_id = ?`)
45
+ .get(workflowMessageId);
46
+ return isWorkflowMessageRow(row) ? this.mapMessage(row) : undefined;
47
+ }
48
+ require(workflowMessageId) {
49
+ const message = this.get(workflowMessageId);
50
+ if (message === undefined)
51
+ throw new Error(`Workflow message not found: ${workflowMessageId}`);
52
+ return message;
53
+ }
54
+ listSession(targetSessionId) {
55
+ const rows = this.state.connection
56
+ .prepare(`SELECT workflow_message_id AS workflowMessageId, run_id AS runId,
57
+ target_session_id AS targetSessionId, kind, source_id AS sourceId,
58
+ content_hash AS contentHash, order_number AS orderNumber, status,
59
+ pi_session_entry_id AS piSessionEntryId, created_at AS createdAt,
60
+ updated_at AS updatedAt
61
+ FROM workflow_messages WHERE target_session_id = ? ORDER BY order_number`)
62
+ .all(targetSessionId);
63
+ return rows.filter(isWorkflowMessageRow).map((row) => this.mapMessage(row));
64
+ }
65
+ listRun(runId) {
66
+ const rows = this.state.connection
67
+ .prepare(`SELECT workflow_message_id AS workflowMessageId, run_id AS runId,
68
+ target_session_id AS targetSessionId, kind, source_id AS sourceId,
69
+ content_hash AS contentHash, order_number AS orderNumber, status,
70
+ pi_session_entry_id AS piSessionEntryId, created_at AS createdAt,
71
+ updated_at AS updatedAt
72
+ FROM workflow_messages WHERE run_id = ? ORDER BY target_session_id, order_number`)
73
+ .all(runId);
74
+ return rows.filter(isWorkflowMessageRow).map((row) => this.mapMessage(row));
75
+ }
76
+ latestForSource(kind, sourceId) {
77
+ const row = this.state.connection
78
+ .prepare(`SELECT workflow_message_id AS workflowMessageId, run_id AS runId,
79
+ target_session_id AS targetSessionId, kind, source_id AS sourceId,
80
+ content_hash AS contentHash, order_number AS orderNumber, status,
81
+ pi_session_entry_id AS piSessionEntryId, created_at AS createdAt,
82
+ updated_at AS updatedAt
83
+ FROM workflow_messages WHERE kind = ? AND source_id = ?
84
+ ORDER BY created_at DESC, order_number DESC LIMIT 1`)
85
+ .get(kind, sourceId);
86
+ return isWorkflowMessageRow(row) ? this.mapMessage(row) : undefined;
87
+ }
88
+ cancelPendingForSource(sourceId, kind, now = Date.now()) {
89
+ return this.state.transaction(() => this.state.connection
90
+ .prepare(`UPDATE workflow_messages SET status = 'cancelled', updated_at = ?
91
+ WHERE source_id = ? AND status = 'pending'${kind === undefined ? "" : " AND kind = ?"}`)
92
+ .run(...(kind === undefined ? [now, sourceId] : [now, sourceId, kind])).changes);
93
+ }
94
+ adoptBranch(targetSessionId, entries, allowedMessageIds, now = Date.now()) {
95
+ return this.state.transaction(() => {
96
+ const adopted = [];
97
+ for (const entry of entries) {
98
+ if (!allowedMessageIds.has(entry.workflowMessageId)) {
99
+ throw new Error(`Workflow branch report contains an unknown message: ${entry.workflowMessageId}`);
100
+ }
101
+ const current = this.require(entry.workflowMessageId);
102
+ if (current.targetSessionId !== targetSessionId) {
103
+ throw new Error("Workflow branch report targets the wrong origin session");
104
+ }
105
+ if (current.status === "sent" &&
106
+ current.piSessionEntryId !== null &&
107
+ current.piSessionEntryId !== entry.piSessionEntryId) {
108
+ throw new Error("Workflow message has conflicting Pi session entry evidence");
109
+ }
110
+ if (current.status !== "sent") {
111
+ this.state.connection
112
+ .prepare(`UPDATE workflow_messages
113
+ SET status = 'sent', pi_session_entry_id = ?, updated_at = ?
114
+ WHERE workflow_message_id = ? AND status IN ('pending', 'cancelled')`)
115
+ .run(entry.piSessionEntryId, now, entry.workflowMessageId);
116
+ }
117
+ adopted.push(this.require(entry.workflowMessageId));
118
+ }
119
+ return adopted;
120
+ });
121
+ }
122
+ startTurn(options) {
123
+ const now = options.now ?? Date.now();
124
+ const workflowTurnId = options.workflowTurnId ?? `workflow-turn-${randomUUID()}`;
125
+ return this.state.transaction(() => {
126
+ const existing = this.getTurn(workflowTurnId);
127
+ if (existing !== undefined) {
128
+ assertSameTurn(existing, options);
129
+ return existing;
130
+ }
131
+ const message = this.require(options.workflowMessageId);
132
+ if (message.runId !== options.runId || message.targetSessionId !== options.targetSessionId) {
133
+ throw new Error("Workflow turn does not match its message");
134
+ }
135
+ if (message.status !== "sent")
136
+ throw new Error("Workflow turn requires a sent message");
137
+ this.state.connection
138
+ .prepare(`INSERT INTO workflow_turns(
139
+ workflow_turn_id, workflow_message_id, run_id, target_session_id, state,
140
+ stop_reason, response_session_entry_id, started_at, ended_at
141
+ ) VALUES (?, ?, ?, ?, 'started', NULL, NULL, ?, NULL)`)
142
+ .run(workflowTurnId, options.workflowMessageId, options.runId, options.targetSessionId, now);
143
+ return this.requireTurn(workflowTurnId);
144
+ });
145
+ }
146
+ endTurn(options) {
147
+ const now = options.now ?? Date.now();
148
+ return this.state.transaction(() => {
149
+ const current = this.requireTurn(options.workflowTurnId);
150
+ assertSameTurn(current, options);
151
+ if (current.state === "ended") {
152
+ if (current.stopReason !== options.stopReason ||
153
+ current.responseSessionEntryId !== (options.responseSessionEntryId ?? null)) {
154
+ throw new Error("Workflow turn end report conflicts with its saved result");
155
+ }
156
+ return current;
157
+ }
158
+ const changed = this.state.connection
159
+ .prepare(`UPDATE workflow_turns SET state = 'ended', stop_reason = ?,
160
+ response_session_entry_id = ?, ended_at = ?
161
+ WHERE workflow_turn_id = ? AND workflow_message_id = ? AND state = 'started'`)
162
+ .run(options.stopReason, options.responseSessionEntryId ?? null, now, options.workflowTurnId, options.workflowMessageId);
163
+ if (changed.changes !== 1)
164
+ throw new Error("Workflow turn changed before its end report");
165
+ return this.requireTurn(options.workflowTurnId);
166
+ });
167
+ }
168
+ getTurn(workflowTurnId) {
169
+ const row = this.state.connection
170
+ .prepare(`SELECT workflow_turn_id AS workflowTurnId, workflow_message_id AS workflowMessageId,
171
+ run_id AS runId, target_session_id AS targetSessionId, state,
172
+ stop_reason AS stopReason, response_session_entry_id AS responseSessionEntryId,
173
+ started_at AS startedAt, ended_at AS endedAt
174
+ FROM workflow_turns WHERE workflow_turn_id = ?`)
175
+ .get(workflowTurnId);
176
+ return isWorkflowTurnRow(row) ? mapTurn(row) : undefined;
177
+ }
178
+ requireTurn(workflowTurnId) {
179
+ const turn = this.getTurn(workflowTurnId);
180
+ if (turn === undefined)
181
+ throw new Error(`Workflow turn not found: ${workflowTurnId}`);
182
+ return turn;
183
+ }
184
+ openTurnForMessage(workflowMessageId) {
185
+ const row = this.state.connection
186
+ .prepare(`SELECT workflow_turn_id AS workflowTurnId, workflow_message_id AS workflowMessageId,
187
+ run_id AS runId, target_session_id AS targetSessionId, state,
188
+ stop_reason AS stopReason, response_session_entry_id AS responseSessionEntryId,
189
+ started_at AS startedAt, ended_at AS endedAt
190
+ FROM workflow_turns WHERE workflow_message_id = ? AND state = 'started'`)
191
+ .get(workflowMessageId);
192
+ return isWorkflowTurnRow(row) ? mapTurn(row) : undefined;
193
+ }
194
+ latestTurnForMessage(workflowMessageId) {
195
+ const row = this.state.connection
196
+ .prepare(`SELECT workflow_turn_id AS workflowTurnId, workflow_message_id AS workflowMessageId,
197
+ run_id AS runId, target_session_id AS targetSessionId, state,
198
+ stop_reason AS stopReason, response_session_entry_id AS responseSessionEntryId,
199
+ started_at AS startedAt, ended_at AS endedAt
200
+ FROM workflow_turns WHERE workflow_message_id = ?
201
+ ORDER BY started_at DESC LIMIT 1`)
202
+ .get(workflowMessageId);
203
+ return isWorkflowTurnRow(row) ? mapTurn(row) : undefined;
204
+ }
205
+ openTurnsForSession(targetSessionId) {
206
+ const rows = this.state.connection
207
+ .prepare(`SELECT workflow_turn_id AS workflowTurnId, workflow_message_id AS workflowMessageId,
208
+ run_id AS runId, target_session_id AS targetSessionId, state,
209
+ stop_reason AS stopReason, response_session_entry_id AS responseSessionEntryId,
210
+ started_at AS startedAt, ended_at AS endedAt
211
+ FROM workflow_turns WHERE target_session_id = ? AND state = 'started'
212
+ ORDER BY started_at`)
213
+ .all(targetSessionId);
214
+ return rows.filter(isWorkflowTurnRow).map(mapTurn);
215
+ }
216
+ mapMessage(row) {
217
+ const content = this.state.readJson(row.contentHash);
218
+ if (!isWorkflowMessageContent(content))
219
+ throw new Error("Stored workflow message content is invalid");
220
+ return {
221
+ schema: WORKFLOW_MESSAGE_SCHEMA,
222
+ workflowMessageId: row.workflowMessageId,
223
+ runId: row.runId,
224
+ targetSessionId: row.targetSessionId,
225
+ kind: row.kind,
226
+ sourceId: row.sourceId,
227
+ contentDigest: row.contentHash.toString("hex"),
228
+ content,
229
+ order: row.orderNumber,
230
+ status: row.status,
231
+ piSessionEntryId: row.piSessionEntryId,
232
+ createdAt: new Date(row.createdAt).toISOString(),
233
+ updatedAt: new Date(row.updatedAt).toISOString(),
234
+ };
235
+ }
236
+ }
237
+ export function workflowMessageIdFor(kind, sourceId, idempotencyKey) {
238
+ const digest = createHash("sha256")
239
+ .update(canonicalJson({ kind, sourceId, idempotencyKey }))
240
+ .digest("hex");
241
+ return `workflow-message-${digest}`;
242
+ }
243
+ export function isWorkflowMessageContent(value) {
244
+ return (isRecord(value) &&
245
+ value.schema === WORKFLOW_MESSAGE_CONTENT_SCHEMA &&
246
+ typeof value.customType === "string" &&
247
+ value.customType.length > 0 &&
248
+ typeof value.content === "string" &&
249
+ typeof value.display === "boolean" &&
250
+ Object.hasOwn(value, "details") &&
251
+ typeof value.triggerTurn === "boolean");
252
+ }
253
+ function validateContent(content, kind) {
254
+ if (!isWorkflowMessageContent(content))
255
+ throw new Error("Workflow message content is invalid");
256
+ const shouldTrigger = kind === "step" || kind === "terminal" || kind === "followUp";
257
+ if (content.triggerTurn !== shouldTrigger) {
258
+ throw new Error(`Workflow message kind ${kind} has invalid turn behavior`);
259
+ }
260
+ canonicalJson(content);
261
+ }
262
+ function assertSameMessage(message, options) {
263
+ const digest = createHash("sha256").update(canonicalJson(options.content)).digest("hex");
264
+ if (message.runId !== options.runId ||
265
+ message.targetSessionId !== options.targetSessionId ||
266
+ message.kind !== options.kind ||
267
+ message.sourceId !== options.sourceId ||
268
+ message.contentDigest !== digest) {
269
+ throw new Error(`Workflow message idempotency conflict: ${message.workflowMessageId}`);
270
+ }
271
+ }
272
+ function assertSameTurn(turn, options) {
273
+ if (turn.workflowMessageId !== options.workflowMessageId ||
274
+ turn.runId !== options.runId ||
275
+ turn.targetSessionId !== options.targetSessionId) {
276
+ throw new Error(`Workflow turn identity conflict: ${turn.workflowTurnId}`);
277
+ }
278
+ }
279
+ function mapTurn(row) {
280
+ return {
281
+ schema: WORKFLOW_TURN_SCHEMA,
282
+ workflowTurnId: row.workflowTurnId,
283
+ workflowMessageId: row.workflowMessageId,
284
+ runId: row.runId,
285
+ targetSessionId: row.targetSessionId,
286
+ state: row.state,
287
+ stopReason: row.stopReason,
288
+ responseSessionEntryId: row.responseSessionEntryId,
289
+ startedAt: new Date(row.startedAt).toISOString(),
290
+ endedAt: row.endedAt === null ? null : new Date(row.endedAt).toISOString(),
291
+ };
292
+ }
293
+ function isWorkflowMessageRow(value) {
294
+ return (isRecord(value) &&
295
+ typeof value.workflowMessageId === "string" &&
296
+ typeof value.runId === "string" &&
297
+ typeof value.targetSessionId === "string" &&
298
+ isWorkflowMessageKind(value.kind) &&
299
+ typeof value.sourceId === "string" &&
300
+ Buffer.isBuffer(value.contentHash) &&
301
+ typeof value.orderNumber === "number" &&
302
+ isWorkflowMessageStatus(value.status) &&
303
+ (value.piSessionEntryId === null || typeof value.piSessionEntryId === "string") &&
304
+ typeof value.createdAt === "number" &&
305
+ typeof value.updatedAt === "number");
306
+ }
307
+ function isWorkflowTurnRow(value) {
308
+ return (isRecord(value) &&
309
+ typeof value.workflowTurnId === "string" &&
310
+ typeof value.workflowMessageId === "string" &&
311
+ typeof value.runId === "string" &&
312
+ typeof value.targetSessionId === "string" &&
313
+ (value.state === "started" || value.state === "ended") &&
314
+ (value.stopReason === null || isWorkflowTurnStopReason(value.stopReason)) &&
315
+ (value.responseSessionEntryId === null || typeof value.responseSessionEntryId === "string") &&
316
+ typeof value.startedAt === "number" &&
317
+ (value.endedAt === null || typeof value.endedAt === "number"));
318
+ }
319
+ function isWorkflowMessageKind(value) {
320
+ return (value === "step" ||
321
+ value === "decision" ||
322
+ value === "notification" ||
323
+ value === "terminal" ||
324
+ value === "followUp");
325
+ }
326
+ function isWorkflowMessageStatus(value) {
327
+ return value === "pending" || value === "sent" || value === "cancelled";
328
+ }
329
+ function isWorkflowTurnStopReason(value) {
330
+ return value === "completed" || value === "aborted" || value === "error" || value === "lost";
331
+ }
332
+ function isRecord(value) {
333
+ return typeof value === "object" && value !== null && !Array.isArray(value);
334
+ }
335
+ //# sourceMappingURL=workflow-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-messages.js","sourceRoot":"","sources":["../../src/state/workflow-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErD,OAAO,EAAE,aAAa,EAAkB,MAAM,WAAW,CAAC;AAE1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,kCAA2C,CAAC;AACnF,MAAM,CAAC,MAAM,+BAA+B,GAAG,0CAAmD,CAAC;AACnG,MAAM,CAAC,MAAM,oBAAoB,GAAG,+BAAwC,CAAC;AAwF7E,uFAAuF;AACvF,MAAM,OAAO,oBAAoB;IACV,KAAK;IAA1B,YAAqB,KAAoB;qBAApB,KAAK;IAAkB,CAAC;IAE7C,MAAM,CAAC,OAAqC;QAC1C,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,iBAAiB,GACrB,OAAO,CAAC,iBAAiB;YACzB,oBAAoB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YAC7C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACrC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC7D,MAAM,KAAK,GACT,CACE,IAAI,CAAC,KAAK,CAAC,UAAU;iBAClB,OAAO,CACN;gEACkD,CACnD;iBACA,GAAG,CAAC,OAAO,CAAC,eAAe,CAC/B,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,UAAU;iBAClB,OAAO,CACN;;;iEAGuD,CACxD;iBACA,GAAG,CACF,iBAAiB,EACjB,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,eAAe,EACvB,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,QAAQ,EAChB,WAAW,EACX,KAAK,EACL,GAAG,EACH,GAAG,CACJ,CAAC;YACJ,OAAO,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,iBAAyB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC9B,OAAO,CACN;;;;;8DAKsD,CACvD;aACA,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC1B,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,CAAC;IAED,OAAO,CAAC,iBAAyB;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,iBAAiB,EAAE,CAAC,CAAC;QAC/F,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,WAAW,CAAC,eAAuB;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC/B,OAAO,CACN;;;;;kFAK0E,CAC3E;aACA,GAAG,CAAC,eAAe,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,CAAC,KAAa;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC/B,OAAO,CACN;;;;;0FAKkF,CACnF;aACA,GAAG,CAAC,KAAK,CAAC,CAAC;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,eAAe,CAAC,IAAyB,EAAE,QAAgB;QACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC9B,OAAO,CACN;;;;;;6DAMqD,CACtD;aACA,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACvB,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,CAAC;IAED,sBAAsB,CACpB,QAAgB,EAChB,IAA0B,EAC1B,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE;QAExB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAC3B,GAAG,EAAE,CACH,IAAI,CAAC,KAAK,CAAC,UAAU;aAClB,OAAO,CACN;yDAC6C,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,CACzF;aACA,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CACpF,CAAC;IACJ,CAAC;IAED,WAAW,CACT,eAAuB,EACvB,OAAuC,EACvC,iBAAsC,EACtC,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE;QAExB,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YACjC,MAAM,OAAO,GAAsB,EAAE,CAAC;YACtC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACpD,MAAM,IAAI,KAAK,CACb,uDAAuD,KAAK,CAAC,iBAAiB,EAAE,CACjF,CAAC;gBACJ,CAAC;gBACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACtD,IAAI,OAAO,CAAC,eAAe,KAAK,eAAe,EAAE,CAAC;oBAChD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;gBAC7E,CAAC;gBACD,IACE,OAAO,CAAC,MAAM,KAAK,MAAM;oBACzB,OAAO,CAAC,gBAAgB,KAAK,IAAI;oBACjC,OAAO,CAAC,gBAAgB,KAAK,KAAK,CAAC,gBAAgB,EACnD,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;gBAChF,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;oBAC9B,IAAI,CAAC,KAAK,CAAC,UAAU;yBAClB,OAAO,CACN;;oFAEsE,CACvE;yBACA,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAC/D,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;YACtD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,OAMT;QACC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,iBAAiB,UAAU,EAAE,EAAE,CAAC;QACjF,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YAC9C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAClC,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YACxD,IAAI,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC3F,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;YACxF,IAAI,CAAC,KAAK,CAAC,UAAU;iBAClB,OAAO,CACN;;;iEAGuD,CACxD;iBACA,GAAG,CACF,cAAc,EACd,OAAO,CAAC,iBAAiB,EACzB,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,eAAe,EACvB,GAAG,CACJ,CAAC;YACJ,OAAO,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,OAQP;QACC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YACjC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACzD,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACjC,IAAI,OAAO,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;gBAC9B,IACE,OAAO,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;oBACzC,OAAO,CAAC,sBAAsB,KAAK,CAAC,OAAO,CAAC,sBAAsB,IAAI,IAAI,CAAC,EAC3E,CAAC;oBACD,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;gBAC9E,CAAC;gBACD,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;iBAClC,OAAO,CACN;;wFAE8E,CAC/E;iBACA,GAAG,CACF,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,sBAAsB,IAAI,IAAI,EACtC,GAAG,EACH,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,iBAAiB,CAC1B,CAAC;YACJ,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC1F,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,CAAC,cAAsB;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC9B,OAAO,CACN;;;;wDAIgD,CACjD;aACA,GAAG,CAAC,cAAc,CAAC,CAAC;QACvB,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAED,WAAW,CAAC,cAAsB;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC1C,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,cAAc,EAAE,CAAC,CAAC;QACtF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB,CAAC,iBAAyB;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC9B,OAAO,CACN;;;;iFAIyE,CAC1E;aACA,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC1B,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAED,oBAAoB,CAAC,iBAAyB;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC9B,OAAO,CACN;;;;;0CAKkC,CACnC;aACA,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC1B,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAED,mBAAmB,CAAC,eAAuB;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU;aAC/B,OAAO,CACN;;;;;6BAKqB,CACtB;aACA,GAAG,CAAC,eAAe,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrD,CAAC;IAEO,UAAU,CAAC,GAAuB;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,OAAO;YACL,MAAM,EAAE,uBAAuB;YAC/B,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,aAAa,EAAE,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;YAC9C,OAAO;YACP,KAAK,EAAE,GAAG,CAAC,WAAW;YACtB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;YAChD,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;SACjD,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,oBAAoB,CAClC,IAAyB,EACzB,QAAgB,EAChB,cAAsB;IAEtB,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC;SAChC,MAAM,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;SACzD,MAAM,CAAC,KAAK,CAAC,CAAC;IACjB,OAAO,oBAAoB,MAAM,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,KAAK,CAAC,MAAM,KAAK,+BAA+B;QAChD,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;QACpC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;QACjC,OAAO,KAAK,CAAC,OAAO,KAAK,SAAS;QAClC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC;QAC/B,OAAO,KAAK,CAAC,WAAW,KAAK,SAAS,CACvC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,OAA+B,EAAE,IAAyB;IACjF,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC/F,MAAM,aAAa,GAAG,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,UAAU,CAAC;IACpF,IAAI,OAAO,CAAC,WAAW,KAAK,aAAa,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,4BAA4B,CAAC,CAAC;IAC7E,CAAC;IACD,aAAa,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAwB,EAAE,OAAqC;IACxF,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzF,IACE,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;QAC/B,OAAO,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe;QACnD,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI;QAC7B,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ;QACrC,OAAO,CAAC,aAAa,KAAK,MAAM,EAChC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0CAA0C,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CACrB,IAAkB,EAClB,OAA8E;IAE9E,IACE,IAAI,CAAC,iBAAiB,KAAK,OAAO,CAAC,iBAAiB;QACpD,IAAI,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;QAC5B,IAAI,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,EAChD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,GAAoB;IACnC,OAAO;QACL,MAAM,EAAE,oBAAoB;QAC5B,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;QACxC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,sBAAsB,EAAE,GAAG,CAAC,sBAAsB;QAClD,SAAS,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;QAChD,OAAO,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE;KAC3E,CAAC;AACJ,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAc;IAC1C,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,iBAAiB,KAAK,QAAQ;QAC3C,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC/B,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ;QACzC,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC;QACjC,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAClC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;QAClC,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;QACrC,uBAAuB,CAAC,KAAK,CAAC,MAAM,CAAC;QACrC,CAAC,KAAK,CAAC,gBAAgB,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,QAAQ,CAAC;QAC/E,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CACpC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,CACL,QAAQ,CAAC,KAAK,CAAC;QACf,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ;QACxC,OAAO,KAAK,CAAC,iBAAiB,KAAK,QAAQ;QAC3C,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC/B,OAAO,KAAK,CAAC,eAAe,KAAK,QAAQ;QACzC,CAAC,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;QACtD,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,wBAAwB,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACzE,CAAC,KAAK,CAAC,sBAAsB,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,sBAAsB,KAAK,QAAQ,CAAC;QAC3F,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ;QACnC,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAC9D,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAc;IAC3C,OAAO,CACL,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,cAAc;QACxB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,UAAU,CACrB,CAAC;AACJ,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc;IAC7C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,WAAW,CAAC;AAC1E,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAc;IAC9C,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,MAAM,CAAC;AAC/F,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Verify only an explicit inactive backup. Active state is verified through WorkflowClient. */
2
+ export declare function verifyInactiveBackup(databasePath: string, activeDatabasePath?: string): void;
@@ -0,0 +1,28 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { StateDatabase, workflowStatePath } from "../state/database.js";
4
+ /** Verify only an explicit inactive backup. Active state is verified through WorkflowClient. */
5
+ export function verifyInactiveBackup(databasePath, activeDatabasePath = workflowStatePath()) {
6
+ const resolved = path.resolve(databasePath);
7
+ const active = path.resolve(activeDatabasePath);
8
+ if (sameFile(resolved, active)) {
9
+ throw new Error("Active workflow state must be verified through the workflow host");
10
+ }
11
+ const state = new StateDatabase({ filePath: resolved, mode: "read-only" });
12
+ try {
13
+ state.integrityCheck();
14
+ }
15
+ finally {
16
+ state.close();
17
+ }
18
+ }
19
+ function sameFile(left, right) {
20
+ if (left === right)
21
+ return true;
22
+ if (!fs.existsSync(left) || !fs.existsSync(right))
23
+ return false;
24
+ const leftStat = fs.statSync(left);
25
+ const rightStat = fs.statSync(right);
26
+ return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
27
+ }
28
+ //# sourceMappingURL=backup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/viewer/backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAExE,gGAAgG;AAChG,MAAM,UAAU,oBAAoB,CAClC,YAAoB,EACpB,kBAAkB,GAAW,iBAAiB,EAAE;IAEhD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChD,IAAI,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3E,IAAI,CAAC;QACH,KAAK,CAAC,cAAc,EAAE,CAAC;IACzB,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,KAAa;IAC3C,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAChE,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,QAAQ,CAAC,GAAG,KAAK,SAAS,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,KAAK,SAAS,CAAC,GAAG,CAAC;AAC1E,CAAC"}
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
+ import { WorkflowClient } from "../client/client.js";
3
+ import type { JsonValue } from "../state/json.js";
2
4
  export type CliArgs = {
3
5
  command: string;
4
6
  runId?: string;
@@ -8,6 +10,7 @@ export type CliArgs = {
8
10
  hostAction?: "start" | "status" | "stop" | "run";
9
11
  stateAction?: "status" | "verify" | "backup" | "prune";
10
12
  backupDestination?: string;
13
+ verifyBackup?: string;
11
14
  pruneBefore?: string;
12
15
  pruneApply?: boolean;
13
16
  once: boolean;
@@ -16,3 +19,4 @@ export type CliArgs = {
16
19
  };
17
20
  export declare function parseCliArgs(argv: string[]): CliArgs;
18
21
  export declare function main(argv?: string[]): Promise<number>;
22
+ export declare function firstRunView(client: WorkflowClient, runId: string): Promise<JsonValue>;