@a5c-ai/babysitter-sdk 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/cli/main.d.ts +5 -0
  2. package/dist/cli/main.d.ts.map +1 -0
  3. package/dist/cli/main.js +1343 -0
  4. package/dist/cli/nodeTaskRunner.d.ts +16 -0
  5. package/dist/cli/nodeTaskRunner.d.ts.map +1 -0
  6. package/dist/cli/nodeTaskRunner.js +46 -0
  7. package/dist/index.d.ts +10 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +25 -0
  10. package/dist/runner/env.d.ts +58 -0
  11. package/dist/runner/env.d.ts.map +1 -0
  12. package/dist/runner/env.js +113 -0
  13. package/dist/runner/index.d.ts +3 -0
  14. package/dist/runner/index.d.ts.map +1 -0
  15. package/dist/runner/index.js +18 -0
  16. package/dist/runner/nodeRunner.d.ts +60 -0
  17. package/dist/runner/nodeRunner.d.ts.map +1 -0
  18. package/dist/runner/nodeRunner.js +354 -0
  19. package/dist/runtime/commitEffectResult.d.ts +3 -0
  20. package/dist/runtime/commitEffectResult.d.ts.map +1 -0
  21. package/dist/runtime/commitEffectResult.js +172 -0
  22. package/dist/runtime/constants.d.ts +2 -0
  23. package/dist/runtime/constants.d.ts.map +1 -0
  24. package/dist/runtime/constants.js +5 -0
  25. package/dist/runtime/createRun.d.ts +3 -0
  26. package/dist/runtime/createRun.d.ts.map +1 -0
  27. package/dist/runtime/createRun.js +81 -0
  28. package/dist/runtime/errorUtils.d.ts +10 -0
  29. package/dist/runtime/errorUtils.d.ts.map +1 -0
  30. package/dist/runtime/errorUtils.js +42 -0
  31. package/dist/runtime/exceptions.d.ts +45 -0
  32. package/dist/runtime/exceptions.d.ts.map +1 -0
  33. package/dist/runtime/exceptions.js +99 -0
  34. package/dist/runtime/index.d.ts +12 -0
  35. package/dist/runtime/index.d.ts.map +1 -0
  36. package/dist/runtime/index.js +34 -0
  37. package/dist/runtime/instrumentation.d.ts +6 -0
  38. package/dist/runtime/instrumentation.d.ts.map +1 -0
  39. package/dist/runtime/instrumentation.js +14 -0
  40. package/dist/runtime/intrinsics/breakpoint.d.ts +4 -0
  41. package/dist/runtime/intrinsics/breakpoint.d.ts.map +1 -0
  42. package/dist/runtime/intrinsics/breakpoint.js +42 -0
  43. package/dist/runtime/intrinsics/index.d.ts +7 -0
  44. package/dist/runtime/intrinsics/index.d.ts.map +1 -0
  45. package/dist/runtime/intrinsics/index.js +15 -0
  46. package/dist/runtime/intrinsics/orchestratorTask.d.ts +4 -0
  47. package/dist/runtime/intrinsics/orchestratorTask.d.ts.map +1 -0
  48. package/dist/runtime/intrinsics/orchestratorTask.js +28 -0
  49. package/dist/runtime/intrinsics/parallel.d.ts +5 -0
  50. package/dist/runtime/intrinsics/parallel.d.ts.map +1 -0
  51. package/dist/runtime/intrinsics/parallel.js +45 -0
  52. package/dist/runtime/intrinsics/sleep.d.ts +4 -0
  53. package/dist/runtime/intrinsics/sleep.d.ts.map +1 -0
  54. package/dist/runtime/intrinsics/sleep.js +70 -0
  55. package/dist/runtime/intrinsics/task.d.ts +20 -0
  56. package/dist/runtime/intrinsics/task.d.ts.map +1 -0
  57. package/dist/runtime/intrinsics/task.js +237 -0
  58. package/dist/runtime/invocation/hashInvocationKey.d.ts +12 -0
  59. package/dist/runtime/invocation/hashInvocationKey.d.ts.map +1 -0
  60. package/dist/runtime/invocation/hashInvocationKey.js +12 -0
  61. package/dist/runtime/invocation/index.d.ts +3 -0
  62. package/dist/runtime/invocation/index.d.ts.map +1 -0
  63. package/dist/runtime/invocation/index.js +5 -0
  64. package/dist/runtime/orchestrateIteration.d.ts +3 -0
  65. package/dist/runtime/orchestrateIteration.d.ts.map +1 -0
  66. package/dist/runtime/orchestrateIteration.js +195 -0
  67. package/dist/runtime/processContext.d.ts +19 -0
  68. package/dist/runtime/processContext.d.ts.map +1 -0
  69. package/dist/runtime/processContext.js +55 -0
  70. package/dist/runtime/replay/createReplayEngine.d.ts +31 -0
  71. package/dist/runtime/replay/createReplayEngine.d.ts.map +1 -0
  72. package/dist/runtime/replay/createReplayEngine.js +82 -0
  73. package/dist/runtime/replay/effectIndex.d.ts +34 -0
  74. package/dist/runtime/replay/effectIndex.d.ts.map +1 -0
  75. package/dist/runtime/replay/effectIndex.js +241 -0
  76. package/dist/runtime/replay/index.d.ts +7 -0
  77. package/dist/runtime/replay/index.d.ts.map +1 -0
  78. package/dist/runtime/replay/index.js +19 -0
  79. package/dist/runtime/replay/replayCursor.d.ts +7 -0
  80. package/dist/runtime/replay/replayCursor.d.ts.map +1 -0
  81. package/dist/runtime/replay/replayCursor.js +22 -0
  82. package/dist/runtime/replay/stateCache.d.ts +48 -0
  83. package/dist/runtime/replay/stateCache.d.ts.map +1 -0
  84. package/dist/runtime/replay/stateCache.js +211 -0
  85. package/dist/runtime/types.d.ts +147 -0
  86. package/dist/runtime/types.d.ts.map +1 -0
  87. package/dist/runtime/types.js +2 -0
  88. package/dist/storage/atomic.d.ts +2 -0
  89. package/dist/storage/atomic.d.ts.map +1 -0
  90. package/dist/storage/atomic.js +54 -0
  91. package/dist/storage/cleanup.d.ts +4 -0
  92. package/dist/storage/cleanup.d.ts.map +1 -0
  93. package/dist/storage/cleanup.js +96 -0
  94. package/dist/storage/clock.d.ts +6 -0
  95. package/dist/storage/clock.d.ts.map +1 -0
  96. package/dist/storage/clock.js +29 -0
  97. package/dist/storage/createRunDir.d.ts +6 -0
  98. package/dist/storage/createRunDir.d.ts.map +1 -0
  99. package/dist/storage/createRunDir.js +59 -0
  100. package/dist/storage/index.d.ts +9 -0
  101. package/dist/storage/index.d.ts.map +1 -0
  102. package/dist/storage/index.js +28 -0
  103. package/dist/storage/journal.d.ts +4 -0
  104. package/dist/storage/journal.d.ts.map +1 -0
  105. package/dist/storage/journal.js +103 -0
  106. package/dist/storage/lock.d.ts +5 -0
  107. package/dist/storage/lock.d.ts.map +1 -0
  108. package/dist/storage/lock.js +41 -0
  109. package/dist/storage/paths.d.ts +19 -0
  110. package/dist/storage/paths.d.ts.map +1 -0
  111. package/dist/storage/paths.js +46 -0
  112. package/dist/storage/runFiles.d.ts +5 -0
  113. package/dist/storage/runFiles.d.ts.map +1 -0
  114. package/dist/storage/runFiles.js +39 -0
  115. package/dist/storage/snapshotState.d.ts +10 -0
  116. package/dist/storage/snapshotState.d.ts.map +1 -0
  117. package/dist/storage/snapshotState.js +15 -0
  118. package/dist/storage/storeTaskArtifacts.d.ts +6 -0
  119. package/dist/storage/storeTaskArtifacts.d.ts.map +1 -0
  120. package/dist/storage/storeTaskArtifacts.js +58 -0
  121. package/dist/storage/tasks.d.ts +17 -0
  122. package/dist/storage/tasks.d.ts.map +1 -0
  123. package/dist/storage/tasks.js +82 -0
  124. package/dist/storage/types.d.ts +112 -0
  125. package/dist/storage/types.d.ts.map +1 -0
  126. package/dist/storage/types.js +2 -0
  127. package/dist/storage/ulids.d.ts +11 -0
  128. package/dist/storage/ulids.d.ts.map +1 -0
  129. package/dist/storage/ulids.js +25 -0
  130. package/dist/tasks/batching.d.ts +29 -0
  131. package/dist/tasks/batching.d.ts.map +1 -0
  132. package/dist/tasks/batching.js +66 -0
  133. package/dist/tasks/context.d.ts +11 -0
  134. package/dist/tasks/context.d.ts.map +1 -0
  135. package/dist/tasks/context.js +181 -0
  136. package/dist/tasks/defineTask.d.ts +9 -0
  137. package/dist/tasks/defineTask.d.ts.map +1 -0
  138. package/dist/tasks/defineTask.js +58 -0
  139. package/dist/tasks/index.d.ts +8 -0
  140. package/dist/tasks/index.d.ts.map +1 -0
  141. package/dist/tasks/index.js +23 -0
  142. package/dist/tasks/kinds/index.d.ts +7 -0
  143. package/dist/tasks/kinds/index.d.ts.map +1 -0
  144. package/dist/tasks/kinds/index.js +333 -0
  145. package/dist/tasks/registry.d.ts +53 -0
  146. package/dist/tasks/registry.d.ts.map +1 -0
  147. package/dist/tasks/registry.js +145 -0
  148. package/dist/tasks/serializer.d.ts +60 -0
  149. package/dist/tasks/serializer.d.ts.map +1 -0
  150. package/dist/tasks/serializer.js +193 -0
  151. package/dist/tasks/types.d.ts +148 -0
  152. package/dist/tasks/types.d.ts.map +1 -0
  153. package/dist/tasks/types.js +2 -0
  154. package/dist/test-fixtures/kinds/index.d.ts +56 -0
  155. package/dist/test-fixtures/kinds/index.d.ts.map +1 -0
  156. package/dist/test-fixtures/kinds/index.js +44 -0
  157. package/dist/testing/deterministic.d.ts +90 -0
  158. package/dist/testing/deterministic.d.ts.map +1 -0
  159. package/dist/testing/deterministic.js +449 -0
  160. package/dist/testing/index.d.ts +4 -0
  161. package/dist/testing/index.d.ts.map +1 -0
  162. package/dist/testing/index.js +23 -0
  163. package/dist/testing/runHarness.d.ts +64 -0
  164. package/dist/testing/runHarness.d.ts.map +1 -0
  165. package/dist/testing/runHarness.js +161 -0
  166. package/dist/testing/snapshots.d.ts +17 -0
  167. package/dist/testing/snapshots.d.ts.map +1 -0
  168. package/dist/testing/snapshots.js +24 -0
  169. package/package.json +35 -0
@@ -0,0 +1,333 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodeTask = nodeTask;
4
+ exports.breakpointTask = breakpointTask;
5
+ exports.orchestratorTask = orchestratorTask;
6
+ exports.sleepTask = sleepTask;
7
+ const defineTask_1 = require("../defineTask");
8
+ const DEFAULT_NODE_TIMEOUT_MS = 15 * 60 * 1000;
9
+ const DEFAULT_BREAKPOINT_LABEL = "breakpoint";
10
+ const DEFAULT_ORCHESTRATOR_LABEL = "orchestrator-task";
11
+ const DEFAULT_SLEEP_TASK_ID = "__sdk.sleep";
12
+ const REDACTION_KEYWORDS = ["SECRET", "TOKEN", "PASSWORD", "KEY"];
13
+ function nodeTask(id, options) {
14
+ if (!options || !options.entry) {
15
+ throw new Error("nodeTask requires an entry option");
16
+ }
17
+ return (0, defineTask_1.defineTask)(id, async (args, ctx) => {
18
+ const [entry, title, description, helperLabels, helperMetadata, ioOverrides, nodeArgs, envInput, cwd, timeoutOverride,] = await Promise.all([
19
+ resolveRequiredValue(options.entry, args, ctx, "entry"),
20
+ resolveOptionalValue(options.title, args, ctx),
21
+ resolveOptionalValue(options.description, args, ctx),
22
+ resolveLabelList(options.labels, args, ctx),
23
+ resolveMetadata(options.metadata, args, ctx),
24
+ resolveIoHints(options.io, args, ctx),
25
+ resolveStringArray(options.args, args, ctx),
26
+ resolveEnv(options.env, args, ctx),
27
+ resolveOptionalValue(options.cwd, args, ctx),
28
+ resolveNumber(options.timeoutMs, args, ctx),
29
+ ]);
30
+ const io = applyIoOverrides(buildDefaultNodeIo(ctx), ioOverrides);
31
+ const { env, redacted } = sanitizeEnv(envInput);
32
+ const metadata = appendRedactedEnvKeys(helperMetadata, redacted);
33
+ const labels = mergeLabels(ctx, helperLabels);
34
+ const nodeOptions = buildNodeOptions(entry, nodeArgs, env, cwd, timeoutOverride);
35
+ return {
36
+ kind: "node",
37
+ title,
38
+ description,
39
+ labels,
40
+ io,
41
+ metadata,
42
+ node: nodeOptions,
43
+ };
44
+ }, { kind: "node" });
45
+ }
46
+ function breakpointTask(id, options = {}) {
47
+ return (0, defineTask_1.defineTask)(id, async (args, ctx) => {
48
+ const [title, description, helperLabels, metadata, payload, confirmationRequired] = await Promise.all([
49
+ resolveOptionalValue(options.title, args, ctx),
50
+ resolveOptionalValue(options.description, args, ctx),
51
+ resolveLabelList(options.labels, args, ctx),
52
+ resolveMetadata(options.metadata, args, ctx),
53
+ resolveOptionalValue(options.payload, args, ctx),
54
+ resolveBoolean(options.confirmationRequired, args, ctx),
55
+ ]);
56
+ const labels = mergeLabels(ctx, helperLabels, DEFAULT_BREAKPOINT_LABEL);
57
+ const breakpoint = buildBreakpointOptions(payload ?? args, confirmationRequired);
58
+ const resolvedTitle = title ?? ctx.label ?? labels?.[0] ?? DEFAULT_BREAKPOINT_LABEL;
59
+ return {
60
+ kind: "breakpoint",
61
+ title: resolvedTitle,
62
+ description,
63
+ labels,
64
+ metadata,
65
+ breakpoint,
66
+ };
67
+ }, { kind: "breakpoint" });
68
+ }
69
+ function orchestratorTask(id, options = {}) {
70
+ return (0, defineTask_1.defineTask)(id, async (args, ctx) => {
71
+ const [title, description, helperLabels, metadata, payload, resumeCommand] = await Promise.all([
72
+ resolveOptionalValue(options.title, args, ctx),
73
+ resolveOptionalValue(options.description, args, ctx),
74
+ resolveLabelList(options.labels, args, ctx),
75
+ resolveMetadata(options.metadata, args, ctx),
76
+ resolvePayload(options.payload, args, ctx),
77
+ resolveOptionalValue(options.resumeCommand, args, ctx),
78
+ ]);
79
+ const labels = mergeLabels(ctx, helperLabels, DEFAULT_ORCHESTRATOR_LABEL);
80
+ const orchestrator = buildOrchestratorOptions(payload ?? pickJsonRecord(args), resumeCommand);
81
+ const mergedMetadata = ensureMetadata(metadata);
82
+ mergedMetadata.orchestratorTask = true;
83
+ const resolvedTitle = title ?? ctx.label ?? labels?.[0] ?? DEFAULT_ORCHESTRATOR_LABEL;
84
+ return {
85
+ kind: "orchestrator_task",
86
+ title: resolvedTitle,
87
+ description,
88
+ labels,
89
+ metadata: mergedMetadata,
90
+ orchestratorTask: orchestrator,
91
+ };
92
+ }, { kind: "orchestrator_task" });
93
+ }
94
+ function sleepTask(id = DEFAULT_SLEEP_TASK_ID, options = {}) {
95
+ return (0, defineTask_1.defineTask)(id, async (args, ctx) => {
96
+ const [title, description, helperLabels, metadata] = await Promise.all([
97
+ resolveOptionalValue(options.title, args, ctx),
98
+ resolveOptionalValue(options.description, args, ctx),
99
+ resolveLabelList(options.labels, args, ctx),
100
+ resolveMetadata(options.metadata, args, ctx),
101
+ ]);
102
+ const iso = args.iso;
103
+ const targetEpochMs = args.targetEpochMs;
104
+ if (typeof iso !== "string" || !iso.length) {
105
+ throw new Error("sleepTask requires args.iso to be a non-empty ISO string");
106
+ }
107
+ if (typeof targetEpochMs !== "number" || !Number.isFinite(targetEpochMs)) {
108
+ throw new Error("sleepTask requires args.targetEpochMs to be a finite number");
109
+ }
110
+ const labels = mergeLabels(ctx, helperLabels, `sleep:${iso}`);
111
+ const mergedMetadata = ensureMetadata(metadata);
112
+ mergedMetadata.iso = iso;
113
+ mergedMetadata.targetEpochMs = targetEpochMs;
114
+ const resolvedTitle = title ?? `sleep:${iso}`;
115
+ return {
116
+ kind: "sleep",
117
+ title: resolvedTitle,
118
+ description,
119
+ labels,
120
+ metadata: mergedMetadata,
121
+ sleep: { iso, targetEpochMs },
122
+ };
123
+ }, { kind: "sleep" });
124
+ }
125
+ async function resolveOptionalValue(source, args, ctx) {
126
+ if (source === undefined || source === null)
127
+ return undefined;
128
+ const value = isFactory(source) ? await source(args, ctx) : source;
129
+ return value === null ? undefined : value;
130
+ }
131
+ async function resolveRequiredValue(source, args, ctx, field) {
132
+ const value = await resolveOptionalValue(source, args, ctx);
133
+ if (typeof value !== "string" || !value.trim()) {
134
+ throw new Error(`nodeTask requires a non-empty ${field}`);
135
+ }
136
+ return value;
137
+ }
138
+ async function resolveLabelList(source, args, ctx) {
139
+ const values = await resolveOptionalValue(source, args, ctx);
140
+ if (!Array.isArray(values)) {
141
+ return undefined;
142
+ }
143
+ return normalizeLabels(values);
144
+ }
145
+ async function resolveMetadata(source, args, ctx) {
146
+ const value = await resolveOptionalValue(source, args, ctx);
147
+ if (!isJsonRecord(value)) {
148
+ return undefined;
149
+ }
150
+ return { ...value };
151
+ }
152
+ async function resolveIoHints(source, args, ctx) {
153
+ const value = await resolveOptionalValue(source, args, ctx);
154
+ if (!value)
155
+ return undefined;
156
+ return { ...value };
157
+ }
158
+ async function resolveStringArray(source, args, ctx) {
159
+ const values = await resolveOptionalValue(source, args, ctx);
160
+ if (!Array.isArray(values)) {
161
+ return undefined;
162
+ }
163
+ return values.slice();
164
+ }
165
+ async function resolveEnv(source, args, ctx) {
166
+ const value = await resolveOptionalValue(source, args, ctx);
167
+ if (!value || typeof value !== "object") {
168
+ return undefined;
169
+ }
170
+ return { ...value };
171
+ }
172
+ async function resolveNumber(source, args, ctx) {
173
+ const value = await resolveOptionalValue(source, args, ctx);
174
+ if (typeof value !== "number" || !Number.isFinite(value)) {
175
+ return undefined;
176
+ }
177
+ return value;
178
+ }
179
+ async function resolveBoolean(source, args, ctx) {
180
+ const value = await resolveOptionalValue(source, args, ctx);
181
+ if (typeof value !== "boolean") {
182
+ return undefined;
183
+ }
184
+ return value;
185
+ }
186
+ async function resolvePayload(source, args, ctx) {
187
+ const value = await resolveOptionalValue(source, args, ctx);
188
+ if (!isJsonRecord(value)) {
189
+ return undefined;
190
+ }
191
+ return { ...value };
192
+ }
193
+ function isFactory(value) {
194
+ return typeof value === "function";
195
+ }
196
+ function normalizeLabels(values) {
197
+ if (!Array.isArray(values)) {
198
+ return undefined;
199
+ }
200
+ const seen = new Set();
201
+ const normalized = [];
202
+ for (const label of values) {
203
+ if (typeof label !== "string")
204
+ continue;
205
+ const trimmed = label.trim();
206
+ if (!trimmed || seen.has(trimmed))
207
+ continue;
208
+ seen.add(trimmed);
209
+ normalized.push(trimmed);
210
+ }
211
+ return normalized.length ? normalized : undefined;
212
+ }
213
+ function mergeLabels(ctx, helperLabels, fallback) {
214
+ const combined = [];
215
+ combined.push(...(normalizeLabels(ctx.labels) ?? []));
216
+ combined.push(...(helperLabels ?? []));
217
+ const normalized = normalizeLabels(combined);
218
+ const fallbackLabel = typeof fallback === "string" ? fallback.trim() : undefined;
219
+ if ((!ctx.label || !ctx.label.trim()) && (!normalized || normalized.length === 0) && fallbackLabel) {
220
+ return [fallbackLabel];
221
+ }
222
+ return normalized;
223
+ }
224
+ function buildDefaultNodeIo(ctx) {
225
+ return {
226
+ inputJsonPath: ctx.toTaskRelativePath("inputs.json"),
227
+ outputJsonPath: ctx.toTaskRelativePath("result.json"),
228
+ stdoutPath: ctx.toTaskRelativePath("stdout.log"),
229
+ stderrPath: ctx.toTaskRelativePath("stderr.log"),
230
+ };
231
+ }
232
+ function applyIoOverrides(base, override) {
233
+ if (!override) {
234
+ return base;
235
+ }
236
+ return {
237
+ ...base,
238
+ ...override,
239
+ };
240
+ }
241
+ function sanitizeEnv(input) {
242
+ if (!input) {
243
+ return { redacted: [] };
244
+ }
245
+ const env = {};
246
+ const redacted = [];
247
+ for (const [rawKey, rawValue] of Object.entries(input)) {
248
+ const key = typeof rawKey === "string" ? rawKey.trim() : "";
249
+ if (!key)
250
+ continue;
251
+ if (rawValue === undefined || rawValue === null) {
252
+ continue;
253
+ }
254
+ const value = typeof rawValue === "string" ? rawValue : String(rawValue);
255
+ if (shouldRedactEnvKey(key)) {
256
+ redacted.push(key);
257
+ continue;
258
+ }
259
+ env[key] = value;
260
+ }
261
+ redacted.sort((a, b) => a.localeCompare(b));
262
+ return {
263
+ env: Object.keys(env).length ? env : undefined,
264
+ redacted,
265
+ };
266
+ }
267
+ function shouldRedactEnvKey(key) {
268
+ const upper = key.toUpperCase();
269
+ if (upper === "NODE_AUTH_TOKEN") {
270
+ return true;
271
+ }
272
+ return REDACTION_KEYWORDS.some((keyword) => upper.includes(keyword));
273
+ }
274
+ function appendRedactedEnvKeys(metadata, keys) {
275
+ if (!keys.length) {
276
+ return metadata;
277
+ }
278
+ const result = ensureMetadata(metadata);
279
+ const existing = Array.isArray(result.redactedEnvKeys) ? result.redactedEnvKeys : [];
280
+ const merged = Array.from(new Set([...existing, ...keys]));
281
+ merged.sort((a, b) => a.localeCompare(b));
282
+ result.redactedEnvKeys = merged;
283
+ return result;
284
+ }
285
+ function ensureMetadata(metadata) {
286
+ if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) {
287
+ return { ...metadata };
288
+ }
289
+ return {};
290
+ }
291
+ function buildNodeOptions(entry, args, env, cwd, timeoutOverride) {
292
+ const nodeOptions = { entry };
293
+ if (args !== undefined) {
294
+ nodeOptions.args = args;
295
+ }
296
+ if (env) {
297
+ nodeOptions.env = env;
298
+ }
299
+ if (typeof cwd === "string" && cwd.length) {
300
+ nodeOptions.cwd = cwd;
301
+ }
302
+ nodeOptions.timeoutMs = typeof timeoutOverride === "number" ? timeoutOverride : DEFAULT_NODE_TIMEOUT_MS;
303
+ return nodeOptions;
304
+ }
305
+ function buildBreakpointOptions(payload, confirmationRequired) {
306
+ const breakpoint = {};
307
+ if (payload !== undefined) {
308
+ breakpoint.payload = payload;
309
+ }
310
+ if (confirmationRequired !== undefined) {
311
+ breakpoint.confirmationRequired = confirmationRequired;
312
+ }
313
+ return breakpoint;
314
+ }
315
+ function buildOrchestratorOptions(payload, resumeCommand) {
316
+ const orchestrator = {};
317
+ if (payload) {
318
+ orchestrator.payload = payload;
319
+ }
320
+ if (resumeCommand) {
321
+ orchestrator.resumeCommand = resumeCommand;
322
+ }
323
+ return orchestrator;
324
+ }
325
+ function pickJsonRecord(value) {
326
+ if (!isJsonRecord(value)) {
327
+ return undefined;
328
+ }
329
+ return { ...value };
330
+ }
331
+ function isJsonRecord(value) {
332
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
333
+ }
@@ -0,0 +1,53 @@
1
+ import { JsonRecord } from "../storage/types";
2
+ export type TaskStatus = "pending" | "resolved_ok" | "resolved_error";
3
+ export interface RegisteredTaskDefinition {
4
+ id: string;
5
+ kind?: string;
6
+ labels: string[];
7
+ description?: string;
8
+ source?: string;
9
+ }
10
+ export interface RegistryEffectRecord {
11
+ effectId: string;
12
+ taskId: string;
13
+ invocationKey: string;
14
+ kind: string;
15
+ label?: string;
16
+ labels?: string[];
17
+ status: TaskStatus;
18
+ taskDefRef: string;
19
+ inputsRef?: string;
20
+ resultRef?: string;
21
+ stdoutRef?: string;
22
+ stderrRef?: string;
23
+ metadata?: JsonRecord;
24
+ stepId?: string;
25
+ requestedAt?: string;
26
+ resolvedAt?: string;
27
+ }
28
+ export interface PendingFilter {
29
+ kind?: string | string[];
30
+ labels?: string | string[];
31
+ }
32
+ export declare class DuplicateTaskIdError extends Error {
33
+ constructor(taskId: string);
34
+ }
35
+ export declare class TaskRegistry {
36
+ private definitions;
37
+ private effects;
38
+ registerDefinition(record: RegisteredTaskDefinition): RegisteredTaskDefinition;
39
+ recordDefinitionMetadata(taskId: string, metadata: Partial<Omit<RegisteredTaskDefinition, "id">>): void;
40
+ recordEffect(record: RegistryEffectRecord): RegistryEffectRecord;
41
+ resolveEffect(effectId: string, update: Partial<RegistryEffectRecord>): RegistryEffectRecord | undefined;
42
+ get(effectId: string): RegistryEffectRecord | undefined;
43
+ listPending(filter?: PendingFilter): RegistryEffectRecord[];
44
+ listDefinitions(): RegisteredTaskDefinition[];
45
+ hasTask(taskId: string): boolean;
46
+ clear(): void;
47
+ private matchesKind;
48
+ private matchesLabel;
49
+ private extractMetadataLabels;
50
+ }
51
+ export declare const globalTaskRegistry: TaskRegistry;
52
+ export declare function resetGlobalTaskRegistry(): void;
53
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tasks/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAEtE,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC5B;AAED,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,MAAM,EAAE,MAAM;CAI3B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,OAAO,CAA2C;IAE1D,kBAAkB,CAAC,MAAM,EAAE,wBAAwB,GAAG,wBAAwB;IAe9E,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI;IAmBvG,YAAY,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB;IAchE,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB,GAAG,SAAS;IAcxG,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAIvD,WAAW,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,oBAAoB,EAAE;IAO3D,eAAe,IAAI,wBAAwB,EAAE;IAI7C,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIhC,KAAK,IAAI,IAAI;IAKb,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,qBAAqB;CAO9B;AAED,eAAO,MAAM,kBAAkB,cAAqB,CAAC;AAErD,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.globalTaskRegistry = exports.TaskRegistry = exports.DuplicateTaskIdError = void 0;
4
+ exports.resetGlobalTaskRegistry = resetGlobalTaskRegistry;
5
+ class DuplicateTaskIdError extends Error {
6
+ constructor(taskId) {
7
+ super(`Task id "${taskId}" is already registered`);
8
+ this.name = "DuplicateTaskIdError";
9
+ }
10
+ }
11
+ exports.DuplicateTaskIdError = DuplicateTaskIdError;
12
+ class TaskRegistry {
13
+ definitions = new Map();
14
+ effects = new Map();
15
+ registerDefinition(record) {
16
+ if (this.definitions.has(record.id)) {
17
+ throw new DuplicateTaskIdError(record.id);
18
+ }
19
+ const normalized = {
20
+ id: record.id,
21
+ kind: record.kind,
22
+ labels: normalizeLabels(record.labels),
23
+ description: record.description,
24
+ source: record.source,
25
+ };
26
+ this.definitions.set(record.id, normalized);
27
+ return normalized;
28
+ }
29
+ recordDefinitionMetadata(taskId, metadata) {
30
+ const current = this.definitions.get(taskId);
31
+ if (!current) {
32
+ this.definitions.set(taskId, {
33
+ id: taskId,
34
+ labels: normalizeLabels(metadata.labels ?? []),
35
+ kind: metadata.kind,
36
+ description: metadata.description,
37
+ source: metadata.source,
38
+ });
39
+ return;
40
+ }
41
+ this.definitions.set(taskId, {
42
+ ...current,
43
+ ...metadata,
44
+ labels: normalizeLabels(metadata.labels ?? current.labels),
45
+ });
46
+ }
47
+ recordEffect(record) {
48
+ const normalizedLabels = normalizeLabels(record.labels ?? []);
49
+ const normalized = {
50
+ ...record,
51
+ label: normalizeLabelValue(record.label),
52
+ labels: normalizedLabels.length ? normalizedLabels : undefined,
53
+ kind: record.kind,
54
+ status: record.status,
55
+ inputsRef: record.inputsRef,
56
+ };
57
+ this.effects.set(record.effectId, normalized);
58
+ return normalized;
59
+ }
60
+ resolveEffect(effectId, update) {
61
+ const current = this.effects.get(effectId);
62
+ if (!current)
63
+ return undefined;
64
+ const next = {
65
+ ...current,
66
+ ...update,
67
+ };
68
+ if (update.status) {
69
+ next.status = update.status;
70
+ }
71
+ this.effects.set(effectId, next);
72
+ return next;
73
+ }
74
+ get(effectId) {
75
+ return this.effects.get(effectId);
76
+ }
77
+ listPending(filter) {
78
+ const pending = Array.from(this.effects.values()).filter((record) => record.status === "pending");
79
+ return pending
80
+ .filter((record) => this.matchesKind(record, filter?.kind) && this.matchesLabel(record, filter?.labels))
81
+ .sort((a, b) => a.effectId.localeCompare(b.effectId));
82
+ }
83
+ listDefinitions() {
84
+ return Array.from(this.definitions.values()).sort((a, b) => a.id.localeCompare(b.id));
85
+ }
86
+ hasTask(taskId) {
87
+ return this.definitions.has(taskId);
88
+ }
89
+ clear() {
90
+ this.definitions.clear();
91
+ this.effects.clear();
92
+ }
93
+ matchesKind(record, kinds) {
94
+ if (!kinds)
95
+ return true;
96
+ const asArray = Array.isArray(kinds) ? kinds : [kinds];
97
+ if (!asArray.length)
98
+ return true;
99
+ return asArray.some((kind) => kind === record.kind);
100
+ }
101
+ matchesLabel(record, labels) {
102
+ if (!labels)
103
+ return true;
104
+ const values = Array.isArray(labels) ? labels : [labels];
105
+ if (!values.length)
106
+ return true;
107
+ const metadataLabels = this.extractMetadataLabels(record.metadata);
108
+ const definitionLabels = this.definitions.get(record.taskId)?.labels ?? [];
109
+ const labelSet = new Set([record.label, ...(record.labels ?? []), ...metadataLabels, ...definitionLabels].filter((label) => typeof label === "string" && Boolean(label)));
110
+ return values.some((value) => labelSet.has(value));
111
+ }
112
+ extractMetadataLabels(metadata) {
113
+ if (!metadata)
114
+ return [];
115
+ const labels = metadata.labels;
116
+ return Array.isArray(labels)
117
+ ? labels.filter((label) => typeof label === "string" && Boolean(label))
118
+ : [];
119
+ }
120
+ }
121
+ exports.TaskRegistry = TaskRegistry;
122
+ exports.globalTaskRegistry = new TaskRegistry();
123
+ function resetGlobalTaskRegistry() {
124
+ exports.globalTaskRegistry.clear();
125
+ }
126
+ function normalizeLabels(labels) {
127
+ const seen = new Set();
128
+ const result = [];
129
+ for (const label of labels) {
130
+ if (typeof label !== "string")
131
+ continue;
132
+ const trimmed = label.trim();
133
+ if (!trimmed || seen.has(trimmed))
134
+ continue;
135
+ seen.add(trimmed);
136
+ result.push(trimmed);
137
+ }
138
+ return result;
139
+ }
140
+ function normalizeLabelValue(label) {
141
+ if (typeof label !== "string")
142
+ return undefined;
143
+ const trimmed = label.trim();
144
+ return trimmed.length ? trimmed : undefined;
145
+ }
@@ -0,0 +1,60 @@
1
+ import { JsonRecord, StoredTaskResult } from "../storage/types";
2
+ import { TaskDef, TaskSerializerContext } from "./types";
3
+ import type { SerializedEffectError } from "../runtime/types";
4
+ export declare const TASK_SCHEMA_VERSION = "2026.01.tasks-v1";
5
+ export declare const RESULT_SCHEMA_VERSION = "2026.01.results-v1";
6
+ export interface SerializeTaskDefinitionOptions extends TaskSerializerContext {
7
+ task: TaskDef;
8
+ inputs?: unknown;
9
+ }
10
+ export interface SerializeTaskResultOptions extends TaskSerializerContext {
11
+ payload: TaskResultPayload;
12
+ }
13
+ export interface TaskResultPayload {
14
+ status: "ok" | "error";
15
+ result?: unknown;
16
+ error?: SerializedErrorPayload;
17
+ stdout?: string;
18
+ stderr?: string;
19
+ stdoutRef?: string;
20
+ stderrRef?: string;
21
+ startedAt?: string;
22
+ finishedAt?: string;
23
+ metadata?: JsonRecord;
24
+ }
25
+ export type SerializedErrorPayload = SerializedEffectError | JsonRecord | undefined;
26
+ export interface SerializeTaskDefinitionResult {
27
+ taskRef: string;
28
+ inputsRef?: string;
29
+ serialized: SerializedTaskDefinition;
30
+ }
31
+ export interface SerializeTaskResultOutput {
32
+ resultRef: string;
33
+ stdoutRef?: string;
34
+ stderrRef?: string;
35
+ serialized: StoredTaskResult;
36
+ }
37
+ export interface SerializedTaskDefinition extends JsonRecord {
38
+ schemaVersion: string;
39
+ effectId: string;
40
+ taskId: string;
41
+ invocationKey: string;
42
+ stepId?: string;
43
+ kind: string;
44
+ title?: string;
45
+ description?: string;
46
+ labels?: string[];
47
+ inputs?: unknown;
48
+ inputsRef?: string;
49
+ io?: JsonRecord;
50
+ node?: JsonRecord;
51
+ breakpoint?: JsonRecord;
52
+ orchestratorTask?: JsonRecord;
53
+ sleep?: JsonRecord;
54
+ metadata?: JsonRecord;
55
+ }
56
+ export declare function serializeAndWriteTaskDefinition(options: SerializeTaskDefinitionOptions): Promise<SerializeTaskDefinitionResult>;
57
+ export declare function serializeTaskDefinition(options: SerializeTaskDefinitionOptions): Promise<SerializedTaskDefinition>;
58
+ export declare function serializeAndWriteTaskResult(options: SerializeTaskResultOptions): Promise<SerializeTaskResultOutput>;
59
+ export declare function serializeTaskResult(options: SerializeTaskResultOptions): Promise<StoredTaskResult>;
60
+ //# sourceMappingURL=serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../../src/tasks/serializer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEhE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9D,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AACtD,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAI1D,MAAM,WAAW,8BAA+B,SAAQ,qBAAqB;IAC3E,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,0BAA2B,SAAQ,qBAAqB;IACvE,OAAO,EAAE,iBAAiB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,IAAI,GAAG,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,sBAAsB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,GAAG,UAAU,GAAG,SAAS,CAAC;AAEpF,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,wBAAwB,CAAC;CACtC;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAyB,SAAQ,UAAU;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,gBAAgB,CAAC,EAAE,UAAU,CAAC;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,UAAU,CAAC;CACvB;AAED,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,6BAA6B,CAAC,CAQxC;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CAgCnC;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,yBAAyB,CAAC,CAepC;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,gBAAgB,CAAC,CAgC3B"}