@osolmaz/pi-workflows 0.2.0 → 0.3.0

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 (133) hide show
  1. package/README.md +71 -5
  2. package/dist/builtins/monitor.workflow.d.ts +71 -0
  3. package/dist/builtins/monitor.workflow.js +234 -0
  4. package/dist/builtins/monitor.workflow.js.map +1 -0
  5. package/dist/controllers/conditions.d.ts +6 -0
  6. package/dist/controllers/conditions.js +68 -0
  7. package/dist/controllers/conditions.js.map +1 -0
  8. package/dist/controllers/definition.d.ts +6 -0
  9. package/dist/controllers/definition.js +45 -0
  10. package/dist/controllers/definition.js.map +1 -0
  11. package/dist/controllers/effects.d.ts +14 -0
  12. package/dist/controllers/effects.js +104 -0
  13. package/dist/controllers/effects.js.map +1 -0
  14. package/dist/controllers/errors.d.ts +12 -0
  15. package/dist/controllers/errors.js +25 -0
  16. package/dist/controllers/errors.js.map +1 -0
  17. package/dist/controllers/index.d.ts +13 -0
  18. package/dist/controllers/index.js +13 -0
  19. package/dist/controllers/index.js.map +1 -0
  20. package/dist/controllers/json.d.ts +5 -0
  21. package/dist/controllers/json.js +57 -0
  22. package/dist/controllers/json.js.map +1 -0
  23. package/dist/controllers/loader.d.ts +23 -0
  24. package/dist/controllers/loader.js +74 -0
  25. package/dist/controllers/loader.js.map +1 -0
  26. package/dist/controllers/manager.d.ts +58 -0
  27. package/dist/controllers/manager.js +399 -0
  28. package/dist/controllers/manager.js.map +1 -0
  29. package/dist/controllers/results.d.ts +5 -0
  30. package/dist/controllers/results.js +32 -0
  31. package/dist/controllers/results.js.map +1 -0
  32. package/dist/controllers/sqlite.d.ts +212 -0
  33. package/dist/controllers/sqlite.js +1009 -0
  34. package/dist/controllers/sqlite.js.map +1 -0
  35. package/dist/controllers/store.d.ts +112 -0
  36. package/dist/controllers/store.js +32 -0
  37. package/dist/controllers/store.js.map +1 -0
  38. package/dist/controllers/types.d.ts +159 -0
  39. package/dist/controllers/types.js +2 -0
  40. package/dist/controllers/types.js.map +1 -0
  41. package/dist/controllers/workflow-engine-scheduler.d.ts +25 -0
  42. package/dist/controllers/workflow-engine-scheduler.js +93 -0
  43. package/dist/controllers/workflow-engine-scheduler.js.map +1 -0
  44. package/dist/controllers/workflows.d.ts +27 -0
  45. package/dist/controllers/workflows.js +109 -0
  46. package/dist/controllers/workflows.js.map +1 -0
  47. package/dist/extension/controller-host.d.ts +47 -0
  48. package/dist/extension/controller-host.js +110 -0
  49. package/dist/extension/controller-host.js.map +1 -0
  50. package/dist/extension/executor.js +1 -1
  51. package/dist/extension/executor.js.map +1 -1
  52. package/dist/extension/index.d.ts +7 -0
  53. package/dist/extension/index.js +1053 -96
  54. package/dist/extension/index.js.map +1 -1
  55. package/dist/extension/recorder.d.ts +6 -0
  56. package/dist/extension/recorder.js +20 -8
  57. package/dist/extension/recorder.js.map +1 -1
  58. package/dist/extension/workflow-tool.d.ts +28 -0
  59. package/dist/extension/workflow-tool.js +33 -0
  60. package/dist/extension/workflow-tool.js.map +1 -0
  61. package/dist/host/processes.d.ts +24 -0
  62. package/dist/host/processes.js +114 -0
  63. package/dist/host/processes.js.map +1 -0
  64. package/dist/host/rpc-bridge.d.ts +9 -0
  65. package/dist/host/rpc-bridge.js +39 -0
  66. package/dist/host/rpc-bridge.js.map +1 -0
  67. package/dist/host/rpc-executor.d.ts +38 -0
  68. package/dist/host/rpc-executor.js +254 -0
  69. package/dist/host/rpc-executor.js.map +1 -0
  70. package/dist/host/runner.d.ts +49 -0
  71. package/dist/host/runner.js +350 -0
  72. package/dist/host/runner.js.map +1 -0
  73. package/dist/viewer/cli.d.ts +7 -3
  74. package/dist/viewer/cli.js +150 -19
  75. package/dist/viewer/cli.js.map +1 -1
  76. package/dist/workflows/engine.d.ts +36 -0
  77. package/dist/workflows/engine.js +244 -14
  78. package/dist/workflows/engine.js.map +1 -1
  79. package/dist/workflows/errors.d.ts +23 -0
  80. package/dist/workflows/errors.js +38 -0
  81. package/dist/workflows/errors.js.map +1 -1
  82. package/dist/workflows/graph.js +0 -5
  83. package/dist/workflows/graph.js.map +1 -1
  84. package/dist/workflows/loader.d.ts +5 -3
  85. package/dist/workflows/loader.js +10 -1
  86. package/dist/workflows/loader.js.map +1 -1
  87. package/dist/workflows/schema.js +1 -1
  88. package/dist/workflows/schema.js.map +1 -1
  89. package/dist/workflows/store.d.ts +50 -6
  90. package/dist/workflows/store.js +446 -51
  91. package/dist/workflows/store.js.map +1 -1
  92. package/dist/workflows/types.d.ts +10 -0
  93. package/docs/CONTROLLERS.md +215 -0
  94. package/docs/development.md +12 -9
  95. package/docs/plans/2026-08-04-controller-runtime-plan.md +169 -0
  96. package/docs/plans/2026-08-05-always-on-workflows-plan.md +125 -0
  97. package/docs/plans/2026-08-10-agent-managed-monitor-workflows-plan.md +184 -0
  98. package/docs/run-bundles.md +66 -27
  99. package/docs/workflows.md +131 -11
  100. package/examples/controllers/pull-request.controller.ts +215 -0
  101. package/package.json +10 -2
  102. package/src/builtins/monitor.workflow.ts +278 -0
  103. package/src/controllers/conditions.ts +110 -0
  104. package/src/controllers/definition.ts +65 -0
  105. package/src/controllers/effects.ts +123 -0
  106. package/src/controllers/errors.ts +27 -0
  107. package/src/controllers/index.ts +90 -0
  108. package/src/controllers/json.ts +62 -0
  109. package/src/controllers/loader.ts +104 -0
  110. package/src/controllers/manager.ts +533 -0
  111. package/src/controllers/results.ts +46 -0
  112. package/src/controllers/sqlite.ts +1427 -0
  113. package/src/controllers/store.ts +160 -0
  114. package/src/controllers/types.ts +183 -0
  115. package/src/controllers/workflow-engine-scheduler.ts +145 -0
  116. package/src/controllers/workflows.ts +152 -0
  117. package/src/extension/controller-host.ts +163 -0
  118. package/src/extension/executor.ts +1 -1
  119. package/src/extension/index.ts +1243 -117
  120. package/src/extension/recorder.ts +65 -36
  121. package/src/extension/workflow-tool.ts +59 -0
  122. package/src/host/processes.ts +119 -0
  123. package/src/host/rpc-bridge.ts +44 -0
  124. package/src/host/rpc-executor.ts +299 -0
  125. package/src/host/runner.ts +406 -0
  126. package/src/viewer/cli.ts +167 -21
  127. package/src/workflows/engine.ts +327 -13
  128. package/src/workflows/errors.ts +45 -0
  129. package/src/workflows/graph.ts +0 -5
  130. package/src/workflows/loader.ts +13 -3
  131. package/src/workflows/schema.ts +1 -1
  132. package/src/workflows/store.ts +555 -46
  133. package/src/workflows/types.ts +10 -0
@@ -0,0 +1,212 @@
1
+ import { type ControllerStore, type EffectReservation, type QueueItem, type QueueRequeueOptions, type WorkflowRecordUpdate, type WorkflowReservation } from "./store.js";
2
+ import type { ChildWorkflowRecord, ControllerEvent, ControllerQueueClaim, ControllerResource, ControllerResourceRef, ControllerResourceStatus, EffectRecord, JsonObject } from "./types.js";
3
+ /** A user-started workflow run tracked by the durable run queue. */
4
+ export type WorkflowRunQueueRecord = {
5
+ runId: string;
6
+ workflowRef: string;
7
+ workflowPath: string;
8
+ input: unknown;
9
+ status: "claimed" | "parked" | "done";
10
+ runnerId: string | null;
11
+ claimToken: string | null;
12
+ claimExpiresAt: string | null;
13
+ affinityRunnerId: string | null;
14
+ parentRunId: string | null;
15
+ createdAt: string;
16
+ updatedAt: string;
17
+ };
18
+ /** One run lifecycle transition in the cross-session event feed. */
19
+ export type RunEventRecord = {
20
+ seq: number;
21
+ recordedAt: string;
22
+ runId: string;
23
+ workflowRef: string;
24
+ type: string;
25
+ runnerId: string | null;
26
+ payload: JsonObject;
27
+ };
28
+ export declare class SqliteControllerStore implements ControllerStore {
29
+ readonly filePath: string;
30
+ private readonly database;
31
+ private closed;
32
+ constructor(filePath?: string, options?: {
33
+ readOnly?: boolean;
34
+ });
35
+ close(): void;
36
+ putResource<TSpec, TStatus>(options: {
37
+ controller: string;
38
+ key: string;
39
+ spec: TSpec;
40
+ initialStatus: TStatus;
41
+ now?: string;
42
+ }): ControllerResource<TSpec, TStatus>;
43
+ getResource<TSpec = unknown, TStatus = unknown>(ref: ControllerResourceRef): ControllerResource<TSpec, TStatus> | undefined;
44
+ getResourceByUid(uid: string): ControllerResource | undefined;
45
+ listResources<TSpec = unknown, TStatus = unknown>(options?: {
46
+ controller?: string;
47
+ }): ControllerResource<TSpec, TStatus>[];
48
+ updateStatus<TStatus>(options: {
49
+ ref: ControllerResourceRef;
50
+ expectedResourceVersion: number;
51
+ status: ControllerResourceStatus<TStatus>;
52
+ finalizers?: string[];
53
+ now?: string;
54
+ }): ControllerResource<unknown, TStatus>;
55
+ requestDeletion(ref: ControllerResourceRef, now?: string): ControllerResource;
56
+ updateFinalizers(options: {
57
+ ref: ControllerResourceRef;
58
+ expectedResourceVersion: number;
59
+ finalizers: string[];
60
+ now?: string;
61
+ }): ControllerResource;
62
+ deleteResource(ref: ControllerResourceRef, expectedResourceVersion: number): boolean;
63
+ enqueue(ref: ControllerResourceRef, availableAt?: string): void;
64
+ claimNext(options: {
65
+ controllers: string[];
66
+ leaseMs: number;
67
+ now?: string;
68
+ }): ControllerQueueClaim | undefined;
69
+ renewClaim(claim: ControllerQueueClaim, leaseMs: number, now?: string): boolean;
70
+ settleClaim(claim: ControllerQueueClaim, now?: string): boolean;
71
+ requeueClaim(claim: ControllerQueueClaim, options: QueueRequeueOptions, _now?: string): boolean;
72
+ listQueue(): QueueItem[];
73
+ reserveEffect(options: {
74
+ key: string;
75
+ resourceUid: string;
76
+ generation: number;
77
+ kind: string;
78
+ requestFingerprint: string;
79
+ now?: string;
80
+ }): EffectReservation;
81
+ getEffect(resourceUid: string, key: string): EffectRecord | undefined;
82
+ updateEffect(options: {
83
+ resourceUid: string;
84
+ key: string;
85
+ state: EffectRecord["state"];
86
+ externalRef?: string;
87
+ error?: string;
88
+ now?: string;
89
+ }): EffectRecord;
90
+ listEffects(resourceUid: string): EffectRecord[];
91
+ reserveWorkflow(options: {
92
+ resourceUid: string;
93
+ requestKey: string;
94
+ workflow: string;
95
+ inputFingerprint: string;
96
+ }): WorkflowReservation;
97
+ getWorkflow(resourceUid: string, requestKey: string): ChildWorkflowRecord | undefined;
98
+ getWorkflowByRequestId(requestId: string): ChildWorkflowRecord | undefined;
99
+ updateWorkflow(requestId: string, update: WorkflowRecordUpdate): ChildWorkflowRecord;
100
+ listWorkflows(resourceUid: string): ChildWorkflowRecord[];
101
+ recordEvent(options: {
102
+ controller: string;
103
+ key: string;
104
+ type: string;
105
+ payload?: JsonObject;
106
+ now?: string;
107
+ }): ControllerEvent;
108
+ listEvents(options?: {
109
+ controller?: string;
110
+ key?: string;
111
+ limit?: number;
112
+ }): ControllerEvent[];
113
+ private configure;
114
+ private initializeSchema;
115
+ private transaction;
116
+ private resourceRow;
117
+ private requireResource;
118
+ private throwMissingOrConflict;
119
+ private enqueueRow;
120
+ private claimedRow;
121
+ private effectRow;
122
+ private requireEffect;
123
+ private workflowRow;
124
+ private requireWorkflow;
125
+ /**
126
+ * Insert a user-started run and claim it in one statement, so the
127
+ * originating runner owns the run from birth (origin affinity).
128
+ */
129
+ enqueueWorkflowRun(options: {
130
+ runId: string;
131
+ workflowRef: string;
132
+ workflowPath: string;
133
+ input: unknown;
134
+ runnerId: string;
135
+ claimToken: string;
136
+ leaseMs: number;
137
+ affinityRunnerId?: string;
138
+ parentRunId?: string;
139
+ now?: string;
140
+ }): WorkflowRunQueueRecord;
141
+ getWorkflowRun(runId: string): WorkflowRunQueueRecord | undefined;
142
+ listWorkflowRuns(options?: {
143
+ status?: WorkflowRunQueueRecord["status"];
144
+ }): WorkflowRunQueueRecord[];
145
+ /**
146
+ * Claim the oldest claimable run, preferring runs with affinity to this
147
+ * runner. Parked rows are claimable immediately; claimed rows become
148
+ * claimable once their lease expires, so a dead or stalled runner never
149
+ * strands a run. Returns undefined when nothing is claimable.
150
+ */
151
+ claimNextWorkflowRun(options: {
152
+ runnerId: string;
153
+ claimToken: string;
154
+ leaseMs: number;
155
+ excludeRunIds?: string[];
156
+ now?: string;
157
+ }): WorkflowRunQueueRecord | undefined;
158
+ /** Extend a live claim. Rejects expired or foreign claims. */
159
+ renewWorkflowRunClaim(options: {
160
+ runId: string;
161
+ claimToken: string;
162
+ leaseMs: number;
163
+ now?: string;
164
+ }): boolean;
165
+ /** The fence check: true only while this exact claim is live. */
166
+ verifyWorkflowRunClaim(options: {
167
+ runId: string;
168
+ claimToken: string;
169
+ now?: string;
170
+ }): boolean;
171
+ /** Release a claim and park the run so another runner can resume it. */
172
+ parkWorkflowRun(options: {
173
+ runId: string;
174
+ claimToken: string;
175
+ now?: string;
176
+ }): boolean;
177
+ /**
178
+ * Delete a claimed row. Used when a continuation fails before its bundle
179
+ * exists, so the parent's one-continuation slot is not consumed by a run
180
+ * that never happened.
181
+ */
182
+ deleteWorkflowRun(options: {
183
+ runId: string;
184
+ claimToken: string;
185
+ }): boolean;
186
+ /** Release a claim and mark the run terminal in the queue. */
187
+ completeWorkflowRun(options: {
188
+ runId: string;
189
+ claimToken: string;
190
+ now?: string;
191
+ }): boolean;
192
+ /** Append a run lifecycle transition to the event feed. */
193
+ recordRunEvent(options: {
194
+ runId: string;
195
+ workflowRef: string;
196
+ type: string;
197
+ runnerId?: string;
198
+ payload?: JsonObject;
199
+ now?: string;
200
+ }): number;
201
+ /** List run events after a watermark, oldest first. */
202
+ listRunEventsAfter(seq: number, options?: {
203
+ limit?: number;
204
+ }): RunEventRecord[];
205
+ /** The highest run event seq in the feed; 0 when empty. */
206
+ latestRunEventSeq(): number;
207
+ /** The last run event this session was told about; 0 before any sync. */
208
+ getSessionWatermark(sessionId: string): number;
209
+ setSessionWatermark(sessionId: string, seq: number, now?: string): void;
210
+ private requireWorkflowRun;
211
+ private requireEvent;
212
+ }