@aicalas/loopy 0.1.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 (244) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +101 -0
  3. package/dist/adapters.d.ts +111 -0
  4. package/dist/adapters.d.ts.map +1 -0
  5. package/dist/adapters.js +27 -0
  6. package/dist/adapters.js.map +1 -0
  7. package/dist/attention/github.d.ts +57 -0
  8. package/dist/attention/github.d.ts.map +1 -0
  9. package/dist/attention/github.js +162 -0
  10. package/dist/attention/github.js.map +1 -0
  11. package/dist/authoring/attention-config.d.ts +16 -0
  12. package/dist/authoring/attention-config.d.ts.map +1 -0
  13. package/dist/authoring/attention-config.js +19 -0
  14. package/dist/authoring/attention-config.js.map +1 -0
  15. package/dist/authoring/channel-config.d.ts +16 -0
  16. package/dist/authoring/channel-config.d.ts.map +1 -0
  17. package/dist/authoring/channel-config.js +16 -0
  18. package/dist/authoring/channel-config.js.map +1 -0
  19. package/dist/authoring/define.d.ts +13 -0
  20. package/dist/authoring/define.d.ts.map +1 -0
  21. package/dist/authoring/define.js +13 -0
  22. package/dist/authoring/define.js.map +1 -0
  23. package/dist/authoring/effect-config.d.ts +16 -0
  24. package/dist/authoring/effect-config.d.ts.map +1 -0
  25. package/dist/authoring/effect-config.js +17 -0
  26. package/dist/authoring/effect-config.js.map +1 -0
  27. package/dist/authoring/harness-config.d.ts +30 -0
  28. package/dist/authoring/harness-config.d.ts.map +1 -0
  29. package/dist/authoring/harness-config.js +36 -0
  30. package/dist/authoring/harness-config.js.map +1 -0
  31. package/dist/authoring/index.d.ts +10 -0
  32. package/dist/authoring/index.d.ts.map +1 -0
  33. package/dist/authoring/index.js +9 -0
  34. package/dist/authoring/index.js.map +1 -0
  35. package/dist/authoring/schema.d.ts +9 -0
  36. package/dist/authoring/schema.d.ts.map +1 -0
  37. package/dist/authoring/schema.js +28 -0
  38. package/dist/authoring/schema.js.map +1 -0
  39. package/dist/authoring/types.d.ts +115 -0
  40. package/dist/authoring/types.d.ts.map +1 -0
  41. package/dist/authoring/types.js +2 -0
  42. package/dist/authoring/types.js.map +1 -0
  43. package/dist/authoring/watcher-config.d.ts +33 -0
  44. package/dist/authoring/watcher-config.d.ts.map +1 -0
  45. package/dist/authoring/watcher-config.js +61 -0
  46. package/dist/authoring/watcher-config.js.map +1 -0
  47. package/dist/build/discover.d.ts +34 -0
  48. package/dist/build/discover.d.ts.map +1 -0
  49. package/dist/build/discover.js +165 -0
  50. package/dist/build/discover.js.map +1 -0
  51. package/dist/build/identity.d.ts +9 -0
  52. package/dist/build/identity.d.ts.map +1 -0
  53. package/dist/build/identity.js +0 -0
  54. package/dist/build/identity.js.map +1 -0
  55. package/dist/channels/github.d.ts +14 -0
  56. package/dist/channels/github.d.ts.map +1 -0
  57. package/dist/channels/github.js +118 -0
  58. package/dist/channels/github.js.map +1 -0
  59. package/dist/channels/index.d.ts +2 -0
  60. package/dist/channels/index.d.ts.map +1 -0
  61. package/dist/channels/index.js +2 -0
  62. package/dist/channels/index.js.map +1 -0
  63. package/dist/cli-help.d.ts +23 -0
  64. package/dist/cli-help.d.ts.map +1 -0
  65. package/dist/cli-help.js +186 -0
  66. package/dist/cli-help.js.map +1 -0
  67. package/dist/cli.d.ts +37 -0
  68. package/dist/cli.d.ts.map +1 -0
  69. package/dist/cli.js +385 -0
  70. package/dist/cli.js.map +1 -0
  71. package/dist/config.d.ts +71 -0
  72. package/dist/config.d.ts.map +1 -0
  73. package/dist/config.js +426 -0
  74. package/dist/config.js.map +1 -0
  75. package/dist/core/calls.d.ts +67 -0
  76. package/dist/core/calls.d.ts.map +1 -0
  77. package/dist/core/calls.js +109 -0
  78. package/dist/core/calls.js.map +1 -0
  79. package/dist/core/identifiers.d.ts +24 -0
  80. package/dist/core/identifiers.d.ts.map +1 -0
  81. package/dist/core/identifiers.js +129 -0
  82. package/dist/core/identifiers.js.map +1 -0
  83. package/dist/core/prompt.d.ts +5 -0
  84. package/dist/core/prompt.d.ts.map +1 -0
  85. package/dist/core/prompt.js +47 -0
  86. package/dist/core/prompt.js.map +1 -0
  87. package/dist/core/reconcile.d.ts +27 -0
  88. package/dist/core/reconcile.d.ts.map +1 -0
  89. package/dist/core/reconcile.js +36 -0
  90. package/dist/core/reconcile.js.map +1 -0
  91. package/dist/core/wire.d.ts +332 -0
  92. package/dist/core/wire.d.ts.map +1 -0
  93. package/dist/core/wire.js +543 -0
  94. package/dist/core/wire.js.map +1 -0
  95. package/dist/emitters/github.d.ts +15 -0
  96. package/dist/emitters/github.d.ts.map +1 -0
  97. package/dist/emitters/github.js +43 -0
  98. package/dist/emitters/github.js.map +1 -0
  99. package/dist/emitters/index.d.ts +2 -0
  100. package/dist/emitters/index.d.ts.map +1 -0
  101. package/dist/emitters/index.js +2 -0
  102. package/dist/emitters/index.js.map +1 -0
  103. package/dist/git.d.ts +17 -0
  104. package/dist/git.d.ts.map +1 -0
  105. package/dist/git.js +122 -0
  106. package/dist/git.js.map +1 -0
  107. package/dist/github/client.d.ts +53 -0
  108. package/dist/github/client.d.ts.map +1 -0
  109. package/dist/github/client.js +169 -0
  110. package/dist/github/client.js.map +1 -0
  111. package/dist/github/trigger.d.ts +12 -0
  112. package/dist/github/trigger.d.ts.map +1 -0
  113. package/dist/github/trigger.js +21 -0
  114. package/dist/github/trigger.js.map +1 -0
  115. package/dist/github/writes.d.ts +4 -0
  116. package/dist/github/writes.d.ts.map +1 -0
  117. package/dist/github/writes.js +21 -0
  118. package/dist/github/writes.js.map +1 -0
  119. package/dist/harnesses/base.d.ts +41 -0
  120. package/dist/harnesses/base.d.ts.map +1 -0
  121. package/dist/harnesses/base.js +182 -0
  122. package/dist/harnesses/base.js.map +1 -0
  123. package/dist/harnesses/claude-executable.d.ts +42 -0
  124. package/dist/harnesses/claude-executable.d.ts.map +1 -0
  125. package/dist/harnesses/claude-executable.js +138 -0
  126. package/dist/harnesses/claude-executable.js.map +1 -0
  127. package/dist/harnesses/claude.d.ts +35 -0
  128. package/dist/harnesses/claude.d.ts.map +1 -0
  129. package/dist/harnesses/claude.js +160 -0
  130. package/dist/harnesses/claude.js.map +1 -0
  131. package/dist/harnesses/codex.d.ts +40 -0
  132. package/dist/harnesses/codex.d.ts.map +1 -0
  133. package/dist/harnesses/codex.js +118 -0
  134. package/dist/harnesses/codex.js.map +1 -0
  135. package/dist/harnesses/index.d.ts +2 -0
  136. package/dist/harnesses/index.d.ts.map +1 -0
  137. package/dist/harnesses/index.js +2 -0
  138. package/dist/harnesses/index.js.map +1 -0
  139. package/dist/harnesses/opencode.d.ts +33 -0
  140. package/dist/harnesses/opencode.d.ts.map +1 -0
  141. package/dist/harnesses/opencode.js +203 -0
  142. package/dist/harnesses/opencode.js.map +1 -0
  143. package/dist/identifiers.d.ts +26 -0
  144. package/dist/identifiers.d.ts.map +1 -0
  145. package/dist/identifiers.js +62 -0
  146. package/dist/identifiers.js.map +1 -0
  147. package/dist/index.d.ts +10 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +10 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/log.d.ts +10 -0
  152. package/dist/log.d.ts.map +1 -0
  153. package/dist/log.js +44 -0
  154. package/dist/log.js.map +1 -0
  155. package/dist/settings.d.ts +43 -0
  156. package/dist/settings.d.ts.map +1 -0
  157. package/dist/settings.js +128 -0
  158. package/dist/settings.js.map +1 -0
  159. package/dist/temporal/activities.d.ts +57 -0
  160. package/dist/temporal/activities.d.ts.map +1 -0
  161. package/dist/temporal/activities.js +366 -0
  162. package/dist/temporal/activities.js.map +1 -0
  163. package/dist/temporal/answers.d.ts +48 -0
  164. package/dist/temporal/answers.d.ts.map +1 -0
  165. package/dist/temporal/answers.js +78 -0
  166. package/dist/temporal/answers.js.map +1 -0
  167. package/dist/temporal/client.d.ts +13 -0
  168. package/dist/temporal/client.d.ts.map +1 -0
  169. package/dist/temporal/client.js +20 -0
  170. package/dist/temporal/client.js.map +1 -0
  171. package/dist/temporal/contracts.d.ts +19 -0
  172. package/dist/temporal/contracts.d.ts.map +1 -0
  173. package/dist/temporal/contracts.js +22 -0
  174. package/dist/temporal/contracts.js.map +1 -0
  175. package/dist/temporal/drain.d.ts +19 -0
  176. package/dist/temporal/drain.d.ts.map +1 -0
  177. package/dist/temporal/drain.js +109 -0
  178. package/dist/temporal/drain.js.map +1 -0
  179. package/dist/temporal/executions.d.ts +18 -0
  180. package/dist/temporal/executions.d.ts.map +1 -0
  181. package/dist/temporal/executions.js +15 -0
  182. package/dist/temporal/executions.js.map +1 -0
  183. package/dist/temporal/handle.d.ts +39 -0
  184. package/dist/temporal/handle.d.ts.map +1 -0
  185. package/dist/temporal/handle.js +95 -0
  186. package/dist/temporal/handle.js.map +1 -0
  187. package/dist/temporal/history.d.ts +75 -0
  188. package/dist/temporal/history.d.ts.map +1 -0
  189. package/dist/temporal/history.js +310 -0
  190. package/dist/temporal/history.js.map +1 -0
  191. package/dist/temporal/observe.d.ts +85 -0
  192. package/dist/temporal/observe.d.ts.map +1 -0
  193. package/dist/temporal/observe.js +110 -0
  194. package/dist/temporal/observe.js.map +1 -0
  195. package/dist/temporal/schedules.d.ts +26 -0
  196. package/dist/temporal/schedules.d.ts.map +1 -0
  197. package/dist/temporal/schedules.js +200 -0
  198. package/dist/temporal/schedules.js.map +1 -0
  199. package/dist/temporal/status.d.ts +63 -0
  200. package/dist/temporal/status.d.ts.map +1 -0
  201. package/dist/temporal/status.js +153 -0
  202. package/dist/temporal/status.js.map +1 -0
  203. package/dist/temporal/stuck.d.ts +58 -0
  204. package/dist/temporal/stuck.d.ts.map +1 -0
  205. package/dist/temporal/stuck.js +53 -0
  206. package/dist/temporal/stuck.js.map +1 -0
  207. package/dist/temporal/supervisor.d.ts +11 -0
  208. package/dist/temporal/supervisor.d.ts.map +1 -0
  209. package/dist/temporal/supervisor.js +506 -0
  210. package/dist/temporal/supervisor.js.map +1 -0
  211. package/dist/temporal/worker.d.ts +21 -0
  212. package/dist/temporal/worker.d.ts.map +1 -0
  213. package/dist/temporal/worker.js +82 -0
  214. package/dist/temporal/worker.js.map +1 -0
  215. package/dist/temporal/workflow-bundle.js +12742 -0
  216. package/dist/temporal/workflows.d.ts +9 -0
  217. package/dist/temporal/workflows.d.ts.map +1 -0
  218. package/dist/temporal/workflows.js +144 -0
  219. package/dist/temporal/workflows.js.map +1 -0
  220. package/dist/version.d.ts +2 -0
  221. package/dist/version.d.ts.map +1 -0
  222. package/dist/version.js +2 -0
  223. package/dist/version.js.map +1 -0
  224. package/dist/watchers/base.d.ts +4 -0
  225. package/dist/watchers/base.d.ts.map +1 -0
  226. package/dist/watchers/base.js +7 -0
  227. package/dist/watchers/base.js.map +1 -0
  228. package/dist/watchers/github/client.d.ts +52 -0
  229. package/dist/watchers/github/client.d.ts.map +1 -0
  230. package/dist/watchers/github/client.js +165 -0
  231. package/dist/watchers/github/client.js.map +1 -0
  232. package/dist/watchers/github/index.d.ts +19 -0
  233. package/dist/watchers/github/index.d.ts.map +1 -0
  234. package/dist/watchers/github/index.js +83 -0
  235. package/dist/watchers/github/index.js.map +1 -0
  236. package/dist/watchers/index.d.ts +2 -0
  237. package/dist/watchers/index.d.ts.map +1 -0
  238. package/dist/watchers/index.js +2 -0
  239. package/dist/watchers/index.js.map +1 -0
  240. package/dist/worker-lock.d.ts +11 -0
  241. package/dist/worker-lock.d.ts.map +1 -0
  242. package/dist/worker-lock.js +53 -0
  243. package/dist/worker-lock.js.map +1 -0
  244. package/package.json +92 -0
@@ -0,0 +1,200 @@
1
+ import { ScheduleAlreadyRunning, ScheduleOverlapPolicy, } from "@temporalio/client";
2
+ import { instanceIdPrefix, ownsScheduleId, pollRunWorkflowId, pollScheduleId, scheduledRunWorkflowId, scheduledScheduleId, } from "../identifiers.js";
3
+ import { POLL_WORKFLOW_TYPE } from "./contracts.js";
4
+ export async function syncSchedules(client, options) {
5
+ const { settings } = options;
6
+ const desired = new Map(options.workflows.flatMap((workflow) => scheduleDefinitions(workflow, options)));
7
+ // Every loopy Schedule this repository owns, not just the poll prefix: a Schedule a removed
8
+ // feature left behind (the reverted workspace sweep's `loopy:sweep:<slug>`) is owned-but-not-
9
+ // desired, so the reconciliation below reaps it instead of leaving it firing forever.
10
+ const existing = new Set();
11
+ for await (const schedule of client.list()) {
12
+ if (ownsScheduleId(settings.repository, schedule.scheduleId))
13
+ existing.add(schedule.scheduleId);
14
+ }
15
+ for (const [scheduleId, definition] of desired) {
16
+ if (!existing.has(scheduleId)) {
17
+ try {
18
+ await client.create({ scheduleId, ...definition });
19
+ continue;
20
+ }
21
+ catch (error) {
22
+ if (!(error instanceof ScheduleAlreadyRunning))
23
+ throw error;
24
+ }
25
+ }
26
+ await update(client.getHandle(scheduleId), definition);
27
+ }
28
+ for (const scheduleId of existing) {
29
+ if (!desired.has(scheduleId))
30
+ await client.getHandle(scheduleId).delete();
31
+ }
32
+ }
33
+ function scheduleDefinitions(workflow, options) {
34
+ if (workflow.schedule !== undefined) {
35
+ return [
36
+ [
37
+ scheduledScheduleId(options.settings.repository, workflow.name),
38
+ scheduledWorkflowSchedule(workflow, options),
39
+ ],
40
+ [
41
+ pollScheduleId(options.settings.repository, workflow.name),
42
+ observerSchedule(workflow, options),
43
+ ],
44
+ ];
45
+ }
46
+ if (workflow.watcher === undefined || workflow.attention === undefined) {
47
+ throw new Error(`watcher workflow ${JSON.stringify(workflow.name)} is incomplete`);
48
+ }
49
+ const { settings } = options;
50
+ const input = {
51
+ workflow: workflow.name,
52
+ repository: settings.repository,
53
+ defaultBranch: settings.defaultBranch,
54
+ watcher: workflow.watcher,
55
+ attention: workflow.attention,
56
+ agentTaskQueue: settings.temporal.agentTaskQueue,
57
+ instanceIdPrefix: instanceIdPrefix(settings.repository),
58
+ };
59
+ return [
60
+ [
61
+ pollScheduleId(settings.repository, workflow.name),
62
+ intervalSchedule({
63
+ intervalSeconds: settings.pollIntervalSeconds,
64
+ workflowType: POLL_WORKFLOW_TYPE,
65
+ taskQueue: options.controlTaskQueue,
66
+ workflowId: pollRunWorkflowId(settings.repository, workflow.name),
67
+ args: [input],
68
+ }),
69
+ ],
70
+ ];
71
+ }
72
+ function scheduledWorkflowSchedule(workflow, options) {
73
+ const { settings } = options;
74
+ if (workflow.schedule === undefined)
75
+ throw new Error(`scheduled workflow ${workflow.name} has no schedule`);
76
+ const trigger = {
77
+ source: "schedule",
78
+ digest: `schedule:${workflow.name}`,
79
+ repository: settings.repository,
80
+ kind: "schedule",
81
+ id: workflow.name,
82
+ data: {},
83
+ };
84
+ const input = {
85
+ workflow: workflow.name,
86
+ repository: settings.repository,
87
+ defaultBranch: settings.defaultBranch,
88
+ trigger,
89
+ agentTaskQueue: settings.temporal.agentTaskQueue,
90
+ ...(workflow.attention === undefined ? {} : { attention: workflow.attention }),
91
+ };
92
+ return declaredSchedule({
93
+ schedule: workflow.schedule,
94
+ workflowType: workflow.name,
95
+ taskQueue: options.controlTaskQueue,
96
+ workflowId: scheduledRunWorkflowId(settings.repository, workflow.name),
97
+ args: [input],
98
+ });
99
+ }
100
+ /** The regular control tick observes scheduled instances for stuck runs and pending answers. */
101
+ function observerSchedule(workflow, options) {
102
+ const { settings } = options;
103
+ const input = {
104
+ workflow: workflow.name,
105
+ repository: settings.repository,
106
+ defaultBranch: settings.defaultBranch,
107
+ agentTaskQueue: settings.temporal.agentTaskQueue,
108
+ instanceIdPrefix: instanceIdPrefix(settings.repository),
109
+ ...(workflow.attention === undefined ? {} : { attention: workflow.attention }),
110
+ };
111
+ return intervalSchedule({
112
+ intervalSeconds: settings.pollIntervalSeconds,
113
+ workflowType: POLL_WORKFLOW_TYPE,
114
+ taskQueue: options.controlTaskQueue,
115
+ workflowId: pollRunWorkflowId(settings.repository, workflow.name),
116
+ args: [input],
117
+ });
118
+ }
119
+ /** `paused: false` is the creation default only; `update` carries the live pause through instead. */
120
+ function intervalSchedule(request) {
121
+ return {
122
+ spec: { intervals: [{ every: `${request.intervalSeconds}s` }] },
123
+ action: {
124
+ type: "startWorkflow",
125
+ workflowType: request.workflowType,
126
+ taskQueue: request.taskQueue,
127
+ workflowId: request.workflowId,
128
+ args: request.args,
129
+ },
130
+ policies: { overlap: ScheduleOverlapPolicy.SKIP },
131
+ state: { paused: false },
132
+ };
133
+ }
134
+ function declaredSchedule(request) {
135
+ const schedule = request.schedule;
136
+ return {
137
+ spec: schedule.cron === undefined
138
+ ? { intervals: [{ every: `${schedule.intervalSeconds}s` }] }
139
+ : {
140
+ cronExpressions: [schedule.cron],
141
+ ...(schedule.timezone === undefined ? {} : { timezone: schedule.timezone }),
142
+ },
143
+ action: {
144
+ type: "startWorkflow",
145
+ workflowType: request.workflowType,
146
+ taskQueue: request.taskQueue,
147
+ workflowId: request.workflowId,
148
+ args: request.args,
149
+ },
150
+ policies: { overlap: schedule.overlap ?? ScheduleOverlapPolicy.SKIP },
151
+ state: { paused: false },
152
+ };
153
+ }
154
+ /**
155
+ * Reconcile the spec and action to code, but carry the live pause through. Paused is an operator
156
+ * decision - it is how a deployment drains - and a restart is exactly when it used to be lost.
157
+ */
158
+ async function update(handle, definition) {
159
+ await handle.update((current) => ({
160
+ ...definition,
161
+ state: { paused: current.state.paused, note: current.state.note },
162
+ }));
163
+ }
164
+ /**
165
+ * Marks a pause as loopy's own, so startup can lift it without touching a pause an operator set for
166
+ * their own reasons. Without the distinction, every restart would clear a deliberate pause.
167
+ */
168
+ export const DRAIN_PAUSE_NOTE = "loopy: drained for shutdown";
169
+ /**
170
+ * Stop every Schedule this deployment owns, so nothing new starts while the drain waits on the
171
+ * Executions already running.
172
+ */
173
+ export async function pauseOwnedSchedules(client, repository, note) {
174
+ const paused = [];
175
+ for await (const handle of ownedSchedules(client, repository)) {
176
+ await handle.pause(note);
177
+ paused.push(handle.scheduleId);
178
+ }
179
+ return paused;
180
+ }
181
+ /** Lift only the pauses this deployment's own drain set; anything else stays paused. */
182
+ export async function resumeDrainedSchedules(client, repository) {
183
+ const resumed = [];
184
+ for await (const handle of ownedSchedules(client, repository)) {
185
+ const { state } = await handle.describe();
186
+ if (!state.paused || state.note !== DRAIN_PAUSE_NOTE)
187
+ continue;
188
+ await handle.unpause("loopy loop started");
189
+ resumed.push(handle.scheduleId);
190
+ }
191
+ return resumed;
192
+ }
193
+ /** Every Schedule this repository owns: a poll per workflow, plus any orphan awaiting reaping. */
194
+ async function* ownedSchedules(client, repository) {
195
+ for await (const schedule of client.list()) {
196
+ if (ownsScheduleId(repository, schedule.scheduleId))
197
+ yield client.getHandle(schedule.scheduleId);
198
+ }
199
+ }
200
+ //# sourceMappingURL=schedules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedules.js","sourceRoot":"","sources":["../../src/temporal/schedules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { type CleanupResult, type InstanceState, type JsonValue, type TriggerCandidate } from "../core/wire.js";
2
+ /** Domain status enriched with the states only status inspection can observe. */
3
+ export type ViewDomainStatus = InstanceState["domainStatus"] | "completed" | "stuck" | "unavailable";
4
+ export interface InstanceView {
5
+ workflowId: string;
6
+ runId: string;
7
+ workflowType: string;
8
+ taskQueue: string;
9
+ temporalStatus: string;
10
+ domainStatus: ViewDomainStatus;
11
+ trigger?: TriggerCandidate;
12
+ parked?: string[];
13
+ callsUsed?: number;
14
+ callLimit?: number;
15
+ reason?: string;
16
+ value?: JsonValue;
17
+ cleanup?: CleanupResult;
18
+ }
19
+ /** The subset of a Temporal `WorkflowExecutionInfo` that status inspection reads. */
20
+ export interface StatusExecutionInfo {
21
+ workflowId: string;
22
+ }
23
+ /** The subset of a Temporal `WorkflowExecutionDescription` that status inspection reads. */
24
+ export interface StatusDescription {
25
+ runId: string;
26
+ type: string;
27
+ taskQueue: string;
28
+ status: {
29
+ name: string;
30
+ };
31
+ raw?: {
32
+ pendingWorkflowTask?: {
33
+ attempt?: number | {
34
+ toNumber(): number;
35
+ } | null;
36
+ } | null;
37
+ };
38
+ }
39
+ export interface StatusWorkflowHandle {
40
+ describe(): Promise<StatusDescription>;
41
+ query(queryName: string): Promise<unknown>;
42
+ result(): Promise<unknown>;
43
+ }
44
+ export interface StatusWorkflowClient {
45
+ list(options: {
46
+ query: string;
47
+ }): AsyncIterable<StatusExecutionInfo>;
48
+ getHandle(workflowId: string): StatusWorkflowHandle;
49
+ }
50
+ export interface StatusOptions {
51
+ queryTimeoutMs?: number;
52
+ }
53
+ /**
54
+ * List every loopy instance. Each user workflow is its own Workflow Type now, so the Workflow ID
55
+ * prefix - not the type - is what selects loopy's executions, filtered server-side so the listing
56
+ * pages loopy's instances rather than every Execution retained in a shared Namespace.
57
+ */
58
+ export declare function listInstances(client: StatusWorkflowClient, options?: StatusOptions): Promise<InstanceView[]>;
59
+ /** Resolve one instance Execution to its Temporal and loopy domain state. */
60
+ export declare function describeInstance(client: StatusWorkflowClient, workflowId: string, options?: StatusOptions): Promise<InstanceView>;
61
+ /** A Running Execution whose next Workflow Task has already failed is stuck, not progressing. */
62
+ export declare function isStuck(description: StatusDescription): boolean;
63
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/temporal/status.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,aAAa,EAClB,KAAK,SAAS,EAGd,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAgBzB,iFAAiF;AACjF,MAAM,MAAM,gBAAgB,GACxB,aAAa,CAAC,cAAc,CAAC,GAC7B,WAAW,GACX,OAAO,GACP,aAAa,CAAC;AAElB,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,4FAA4F;AAC5F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzB,GAAG,CAAC,EAAE;QAAE,mBAAmB,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,MAAM,GAAG;gBAAE,QAAQ,IAAI,MAAM,CAAA;aAAE,GAAG,IAAI,CAAA;SAAE,GAAG,IAAI,CAAA;KAAE,CAAC;CAC7F;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACvC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,CAAC,mBAAmB,CAAC,CAAC;IACrE,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACrD;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,EAAE,CAAC,CAazB;AAED,6EAA6E;AAC7E,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA2CvB;AA6BD,iGAAiG;AACjG,wBAAgB,OAAO,CAAC,WAAW,EAAE,iBAAiB,GAAG,OAAO,CAI/D"}
@@ -0,0 +1,153 @@
1
+ import { QueryNotRegisteredError, QueryRejectedError, ServiceError } from "@temporalio/client";
2
+ import { WorkflowNotFoundError } from "@temporalio/common";
3
+ import { parkedCallIds } from "../core/calls.js";
4
+ import { parseInstanceResult, parseInstanceState, } from "../core/wire.js";
5
+ import { INSTANCE_ID_PREFIX, INSTANCE_STATE_QUERY } from "./contracts.js";
6
+ const DEFAULT_QUERY_TIMEOUT_MS = 5_000;
7
+ /**
8
+ * gRPC FAILED_PRECONDITION. The server answers a Query against an Execution whose Workflow Task is
9
+ * failing with this code, which is the Execution reporting that it cannot serve one - not a defect
10
+ * on this side. Transport codes are deliberately excluded: an unreachable server must stay loud
11
+ * rather than turn one outage into an "unavailable" row per Execution.
12
+ *
13
+ * The code is not unique to that refusal - `NamespaceNotActive` carries it too, so a global
14
+ * Namespace failover reads as every instance being stuck. That is a display artefact and clears
15
+ * with the failover; nothing destructive reads this.
16
+ */
17
+ const GRPC_FAILED_PRECONDITION = 9;
18
+ /**
19
+ * List every loopy instance. Each user workflow is its own Workflow Type now, so the Workflow ID
20
+ * prefix - not the type - is what selects loopy's executions, filtered server-side so the listing
21
+ * pages loopy's instances rather than every Execution retained in a shared Namespace.
22
+ */
23
+ export async function listInstances(client, options = {}) {
24
+ const views = [];
25
+ // Visibility yields one entry per Run, and a Workflow ID is reused across every re-fire of the
26
+ // same trigger. Status reports current state, so collapse to one row per Workflow ID; the handle
27
+ // resolves to the latest Run. Earlier Runs stay in Event History for anyone who needs them.
28
+ const seen = new Set();
29
+ const query = `WorkflowId STARTS_WITH ${JSON.stringify(INSTANCE_ID_PREFIX)}`;
30
+ for await (const info of client.list({ query })) {
31
+ if (seen.has(info.workflowId))
32
+ continue;
33
+ seen.add(info.workflowId);
34
+ views.push(await describeInstance(client, info.workflowId, options));
35
+ }
36
+ return views;
37
+ }
38
+ /** Resolve one instance Execution to its Temporal and loopy domain state. */
39
+ export async function describeInstance(client, workflowId, options = {}) {
40
+ const handle = client.getHandle(workflowId);
41
+ const description = await handle.describe();
42
+ const base = {
43
+ workflowId,
44
+ runId: description.runId,
45
+ workflowType: description.type,
46
+ taskQueue: description.taskQueue,
47
+ temporalStatus: description.status.name,
48
+ };
49
+ if (base.temporalStatus === "RUNNING") {
50
+ const state = await queryState(handle, options.queryTimeoutMs ?? DEFAULT_QUERY_TIMEOUT_MS);
51
+ if (state !== undefined)
52
+ return fromState(base, state);
53
+ const domainStatus = isStuck(description) ? "stuck" : "unavailable";
54
+ return domainStatus === "stuck"
55
+ ? { ...base, domainStatus, reason: "workflow-task-failing" }
56
+ : { ...base, domainStatus };
57
+ }
58
+ if (base.temporalStatus === "COMPLETED") {
59
+ let result;
60
+ try {
61
+ result = parseInstanceResult(await handle.result());
62
+ }
63
+ catch (error) {
64
+ // A closed Execution outlives the build that wrote its result, and Namespace retention keeps
65
+ // it listed for days afterwards, so a shape this build does not recognise is a version gap
66
+ // rather than a defect. Keep the row and name the gap. Query state gets no such latitude: it
67
+ // comes from the bundle running right now, so a mismatch there is this build's bug.
68
+ return {
69
+ ...base,
70
+ domainStatus: "unavailable",
71
+ reason: `result-unreadable:${message(error)}`,
72
+ };
73
+ }
74
+ const view = {
75
+ ...base,
76
+ domainStatus: result.domainStatus,
77
+ cleanup: result.cleanup,
78
+ };
79
+ if (result.domainStatus === "halted")
80
+ view.reason = result.reason;
81
+ else
82
+ view.value = result.value;
83
+ return view;
84
+ }
85
+ return { ...base, domainStatus: "unavailable" };
86
+ }
87
+ function fromState(base, state) {
88
+ const view = {
89
+ ...base,
90
+ domainStatus: state.domainStatus,
91
+ trigger: state.trigger,
92
+ parked: parkedCallIds(state.calls),
93
+ callsUsed: state.callsUsed,
94
+ callLimit: state.callLimit,
95
+ };
96
+ if (state.terminal !== undefined)
97
+ view.reason = state.terminal.reason;
98
+ return view;
99
+ }
100
+ async function queryState(handle, timeoutMs) {
101
+ let value;
102
+ try {
103
+ value = await withTimeout(handle.query(INSTANCE_STATE_QUERY), timeoutMs);
104
+ }
105
+ catch (error) {
106
+ if (isUnavailableQuery(error))
107
+ return undefined;
108
+ throw error;
109
+ }
110
+ return parseInstanceState(value);
111
+ }
112
+ /** A Running Execution whose next Workflow Task has already failed is stuck, not progressing. */
113
+ export function isStuck(description) {
114
+ const attempt = description.raw?.pendingWorkflowTask?.attempt;
115
+ const count = typeof attempt === "number" ? attempt : (attempt?.toNumber() ?? 0);
116
+ return count > 1;
117
+ }
118
+ function withTimeout(operation, timeoutMs) {
119
+ return new Promise((resolve, reject) => {
120
+ const timer = setTimeout(() => reject(new QueryTimeoutError()), timeoutMs);
121
+ timer.unref();
122
+ operation.then(resolve, reject).finally(() => clearTimeout(timer));
123
+ });
124
+ }
125
+ class QueryTimeoutError extends Error {
126
+ }
127
+ function isUnavailableQuery(error) {
128
+ return (error instanceof QueryTimeoutError ||
129
+ error instanceof QueryNotRegisteredError ||
130
+ error instanceof QueryRejectedError ||
131
+ error instanceof WorkflowNotFoundError ||
132
+ refusedQuery(error));
133
+ }
134
+ /**
135
+ * The refusal arrives as a `ServiceError` wrapping the one that carries the gRPC code, so walk the
136
+ * cause chain rather than inspecting only the error thrown to the caller.
137
+ */
138
+ function refusedQuery(error) {
139
+ for (let current = error; current instanceof Error; current = current.cause) {
140
+ if (current instanceof ServiceError && grpcCode(current) === GRPC_FAILED_PRECONDITION) {
141
+ return true;
142
+ }
143
+ }
144
+ return false;
145
+ }
146
+ function message(error) {
147
+ return error instanceof Error ? error.message : String(error);
148
+ }
149
+ function grpcCode(error) {
150
+ const code = error.code;
151
+ return typeof code === "number" ? code : undefined;
152
+ }
153
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/temporal/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { type InstanceWorkflowInput } from "../core/wire.js";
2
+ import { type StatusDescription } from "./status.js";
3
+ /**
4
+ * The client surface the stuck scan needs. A real `WorkflowClient` satisfies it — including the
5
+ * raw `workflowService` handle, which is used instead of `fetchHistory()` because a stuck
6
+ * Execution's history grows on every failed Workflow Task and the scan only ever needs event one.
7
+ */
8
+ export interface StuckScanClient {
9
+ list(options: {
10
+ query: string;
11
+ }): AsyncIterable<{
12
+ workflowId: string;
13
+ }>;
14
+ getHandle(workflowId: string): StuckScanHandle;
15
+ workflowService: {
16
+ getWorkflowExecutionHistory(request: {
17
+ namespace: string;
18
+ execution: {
19
+ workflowId: string;
20
+ runId: string;
21
+ };
22
+ maximumPageSize: number;
23
+ }): Promise<{
24
+ history?: StartHistory | null;
25
+ }>;
26
+ };
27
+ options: {
28
+ namespace: string;
29
+ };
30
+ }
31
+ export interface StuckScanHandle {
32
+ describe(): Promise<StatusDescription>;
33
+ }
34
+ /** The one slice of an Event History the scan reads: the start event's input payload. */
35
+ export interface StartHistory {
36
+ events?: readonly StartEvent[] | null;
37
+ }
38
+ interface StartEvent {
39
+ workflowExecutionStartedEventAttributes?: {
40
+ input?: {
41
+ payloads?: readonly unknown[] | null;
42
+ } | null;
43
+ } | null;
44
+ }
45
+ export interface StuckInstance {
46
+ workflowId: string;
47
+ runId: string;
48
+ input: InstanceWorkflowInput;
49
+ }
50
+ /**
51
+ * Find this workflow's open instances that are failing Workflow Tasks. A stuck instance's own code
52
+ * no longer runs, so it cannot surface itself — this control-side scan is how `stuck` reaches the
53
+ * attention port. The trigger comes from the Execution's own start input, because the trigger
54
+ * object may no longer match any watcher (its intake label was consumed before the code broke).
55
+ */
56
+ export declare function findStuckInstances(client: StuckScanClient, repository: string, workflow: string): Promise<StuckInstance[]>;
57
+ export {};
58
+ //# sourceMappingURL=stuck.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stuck.d.ts","sourceRoot":"","sources":["../../src/temporal/stuck.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,qBAAqB,EAA8B,MAAM,iBAAiB,CAAC;AAGzF,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAAC;IAC/C,eAAe,EAAE;QACf,2BAA2B,CAAC,OAAO,EAAE;YACnC,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE;gBAAE,UAAU,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAA;aAAE,CAAC;YACjD,eAAe,EAAE,MAAM,CAAC;SACzB,GAAG,OAAO,CAAC;YAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAA;SAAE,CAAC,CAAC;KAChD,CAAC;IACF,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxC;AAED,yFAAyF;AACzF,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,SAAS,UAAU,EAAE,GAAG,IAAI,CAAC;CACvC;AAED,UAAU,UAAU;IAClB,uCAAuC,CAAC,EAAE;QACxC,KAAK,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAAA;SAAE,GAAG,IAAI,CAAC;KACzD,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,EAAE,CAAC,CAsB1B"}
@@ -0,0 +1,53 @@
1
+ import { defaultPayloadConverter } from "@temporalio/common";
2
+ import { parseInstanceWorkflowInput } from "../core/wire.js";
3
+ import { instanceIdPrefix } from "../identifiers.js";
4
+ import { log } from "../log.js";
5
+ import { isStuck } from "./status.js";
6
+ /**
7
+ * Find this workflow's open instances that are failing Workflow Tasks. A stuck instance's own code
8
+ * no longer runs, so it cannot surface itself — this control-side scan is how `stuck` reaches the
9
+ * attention port. The trigger comes from the Execution's own start input, because the trigger
10
+ * object may no longer match any watcher (its intake label was consumed before the code broke).
11
+ */
12
+ export async function findStuckInstances(client, repository, workflow) {
13
+ const prefix = `${instanceIdPrefix(repository)}${workflow}:`;
14
+ const query = `ExecutionStatus="Running" AND WorkflowId STARTS_WITH ${JSON.stringify(prefix)}`;
15
+ const stuck = [];
16
+ for await (const info of client.list({ query })) {
17
+ const description = await client.getHandle(info.workflowId).describe();
18
+ // Visibility lags the live Execution, so re-check status on the authoritative Describe.
19
+ if (description.status.name !== "RUNNING" || !isStuck(description))
20
+ continue;
21
+ let input;
22
+ try {
23
+ input = parseInstanceWorkflowInput(decodeStartInput(await fetchStartHistory(client, info.workflowId, description.runId)));
24
+ }
25
+ catch (error) {
26
+ // Without the start input there is no trigger to surface the event on. A shape this build
27
+ // cannot read is a version gap; say so and leave the instance to `loopy status`.
28
+ log.warning(`stuck instance ${info.workflowId}: cannot read start input: ${message(error)}`);
29
+ continue;
30
+ }
31
+ stuck.push({ workflowId: info.workflowId, runId: description.runId, input });
32
+ }
33
+ return stuck;
34
+ }
35
+ async function fetchStartHistory(client, workflowId, runId) {
36
+ const response = await client.workflowService.getWorkflowExecutionHistory({
37
+ namespace: client.options.namespace,
38
+ execution: { workflowId, runId },
39
+ maximumPageSize: 1,
40
+ });
41
+ return response.history ?? {};
42
+ }
43
+ function decodeStartInput(history) {
44
+ const payload = history.events?.[0]?.workflowExecutionStartedEventAttributes?.input?.payloads?.[0];
45
+ if (payload === undefined || payload === null) {
46
+ throw new Error("start event carries no input payload");
47
+ }
48
+ return defaultPayloadConverter.fromPayload(payload);
49
+ }
50
+ function message(error) {
51
+ return error instanceof Error ? error.message : String(error);
52
+ }
53
+ //# sourceMappingURL=stuck.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stuck.js","sourceRoot":"","sources":["../../src/temporal/stuck.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAgB,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAA8B,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,OAAO,EAA0B,MAAM,aAAa,CAAC;AAyC9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAuB,EACvB,UAAkB,EAClB,QAAgB;IAEhB,MAAM,MAAM,GAAG,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC;IAC7D,MAAM,KAAK,GAAG,wDAAwD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/F,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAChD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvE,wFAAwF;QACxF,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;YAAE,SAAS;QAC7E,IAAI,KAA4B,CAAC;QACjC,IAAI,CAAC;YACH,KAAK,GAAG,0BAA0B,CAChC,gBAAgB,CAAC,MAAM,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CACtF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,0FAA0F;YAC1F,iFAAiF;YACjF,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,CAAC,UAAU,8BAA8B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7F,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,MAAuB,EACvB,UAAkB,EAClB,KAAa;IAEb,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,2BAA2B,CAAC;QACxE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,SAAS;QACnC,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE;QAChC,eAAe,EAAE,CAAC;KACnB,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;AAChC,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAqB;IAC7C,MAAM,OAAO,GACX,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,uCAAuC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IACrF,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,uBAAuB,CAAC,WAAW,CAAC,OAAkB,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { WorkflowDefinition } from "../authoring/types.js";
2
+ import { type InstanceResult, type InstanceState, type JsonValue } from "../core/wire.js";
3
+ /** A fixed safety bound until a real workflow demonstrates the need for configuration. */
4
+ export declare const MAX_CALLS_PER_INSTANCE = 200;
5
+ /** Reserved: the engine's own intake claim occupies this effect identifier. */
6
+ export declare const INTAKE_EFFECT_ID = "intake";
7
+ export declare const instanceStateQuery: import("@temporalio/workflow").QueryDefinition<InstanceState, [], string>;
8
+ export declare const resolveInstanceUpdate: import("@temporalio/common").UpdateDefinition<InstanceState, [unknown], string>;
9
+ export declare const answerInstanceUpdate: import("@temporalio/common").UpdateDefinition<InstanceState, [unknown], string>;
10
+ export declare function runSupervised<R extends JsonValue>(definition: WorkflowDefinition<R>, input: unknown): Promise<InstanceResult>;
11
+ //# sourceMappingURL=supervisor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/temporal/supervisor.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAc/B,OAAO,EAcL,KAAK,cAAc,EACnB,KAAK,aAAa,EAElB,KAAK,SAAS,EAcf,MAAM,iBAAiB,CAAC;AAiCzB,0FAA0F;AAC1F,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAKzC,eAAO,MAAM,kBAAkB,2EAAmD,CAAC;AACnF,eAAO,MAAM,qBAAqB,iFAEjC,CAAC;AACF,eAAO,MAAM,oBAAoB,iFAAiE,CAAC;AAsBnG,wBAAgB,aAAa,CAAC,CAAC,SAAS,SAAS,EAC/C,UAAU,EAAE,kBAAkB,CAAC,CAAC,CAAC,EACjC,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,cAAc,CAAC,CAEzB"}