@hasna/loops 0.4.12 → 0.4.14

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 (41) hide show
  1. package/CHANGELOG.md +106 -3
  2. package/README.md +70 -17
  3. package/dist/api/index.d.ts +35 -0
  4. package/dist/api/index.js +750 -10
  5. package/dist/cli/index.js +1744 -361
  6. package/dist/cli/ui.d.ts +44 -0
  7. package/dist/daemon/index.js +948 -212
  8. package/dist/generated/storage-kit/health.d.ts +19 -0
  9. package/dist/generated/storage-kit/index.d.ts +7 -0
  10. package/dist/generated/storage-kit/migrations.d.ts +47 -0
  11. package/dist/generated/storage-kit/mode.d.ts +47 -0
  12. package/dist/generated/storage-kit/pool.d.ts +33 -0
  13. package/dist/generated/storage-kit/query.d.ts +35 -0
  14. package/dist/generated/storage-kit/tls.d.ts +25 -0
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +6513 -4840
  17. package/dist/lib/health.d.ts +83 -3
  18. package/dist/lib/mode.d.ts +27 -0
  19. package/dist/lib/mode.js +69 -2
  20. package/dist/lib/scheduler.d.ts +5 -2
  21. package/dist/lib/storage/index.d.ts +1 -0
  22. package/dist/lib/storage/index.js +1329 -211
  23. package/dist/lib/storage/pg-executor.d.ts +27 -0
  24. package/dist/lib/storage/pg-runner-claim.d.ts +40 -0
  25. package/dist/lib/storage/postgres-loop-storage.d.ts +114 -0
  26. package/dist/lib/storage/sqlite.js +336 -8
  27. package/dist/lib/store.d.ts +234 -0
  28. package/dist/lib/store.js +350 -8
  29. package/dist/mcp/index.js +1447 -479
  30. package/dist/runner/index.js +179 -25
  31. package/dist/sdk/http.d.ts +115 -0
  32. package/dist/sdk/http.js +145 -0
  33. package/dist/sdk/index.d.ts +5 -1
  34. package/dist/sdk/index.js +1106 -296
  35. package/dist/serve/index.d.ts +4 -0
  36. package/dist/serve/index.js +7619 -0
  37. package/dist/types.d.ts +3 -0
  38. package/docs/CUTOVER-RUNBOOK.md +61 -0
  39. package/docs/DEPLOYMENT_MODES.md +23 -1
  40. package/docs/USAGE.md +66 -16
  41. package/package.json +14 -2
package/dist/lib/store.js CHANGED
@@ -1,9 +1,9 @@
1
1
  // @bun
2
2
  // src/lib/store.ts
3
3
  import { Database } from "bun:sqlite";
4
- import { chmodSync, existsSync, mkdirSync as mkdirSync3, mkdtempSync, rmSync as rmSync2 } from "fs";
5
- import { tmpdir } from "os";
6
- import { basename as basename2, dirname as dirname2, join as join3 } from "path";
4
+ import { chmodSync, existsSync, mkdirSync as mkdirSync3, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "fs";
5
+ import { tmpdir as tmpdir2 } from "os";
6
+ import { basename as basename2, dirname as dirname2, join as join4 } from "path";
7
7
 
8
8
  // src/lib/errors.ts
9
9
  class CodedError extends Error {
@@ -1202,6 +1202,196 @@ function discardWorkflowRunManifest(staged) {
1202
1202
  } catch {}
1203
1203
  }
1204
1204
 
1205
+ // src/lib/route/todos-cli.ts
1206
+ import { closeSync, mkdtempSync, openSync, readFileSync as readFileSync3, rmSync as rmSync2 } from "fs";
1207
+ import { spawnSync as spawnSync2 } from "child_process";
1208
+ import { join as join3 } from "path";
1209
+ import { homedir as homedir2, tmpdir } from "os";
1210
+
1211
+ // src/lib/format.ts
1212
+ var TEXT_OUTPUT_LIMIT = 32 * 1024;
1213
+ var SENSITIVE_PAYLOAD_KEYS = new Set(["env", "error", "prompt", "reason", "stderr", "stdout"]);
1214
+ function redact(value, visible = 0) {
1215
+ if (!value)
1216
+ return value;
1217
+ if (value.length <= visible)
1218
+ return value;
1219
+ if (visible <= 0)
1220
+ return `[redacted ${value.length} chars]`;
1221
+ return `${value.slice(0, visible)}... [redacted ${value.length - visible} chars]`;
1222
+ }
1223
+ function truncateTextOutput(value) {
1224
+ if (value.length <= TEXT_OUTPUT_LIMIT)
1225
+ return value;
1226
+ return `${value.slice(0, TEXT_OUTPUT_LIMIT)}
1227
+ [truncated ${value.length - TEXT_OUTPUT_LIMIT} chars]`;
1228
+ }
1229
+ function redactSensitivePayload(value, key) {
1230
+ if (key && SENSITIVE_PAYLOAD_KEYS.has(key)) {
1231
+ if (typeof value === "string")
1232
+ return redact(value);
1233
+ if (value === undefined || value === null)
1234
+ return value;
1235
+ return "[redacted]";
1236
+ }
1237
+ if (Array.isArray(value))
1238
+ return value.map((item) => redactSensitivePayload(item));
1239
+ if (value && typeof value === "object") {
1240
+ return Object.fromEntries(Object.entries(value).map(([entryKey, entryValue]) => [entryKey, redactSensitivePayload(entryValue, entryKey)]));
1241
+ }
1242
+ return value;
1243
+ }
1244
+ function textOutputBlocks(value, opts = {}) {
1245
+ const indent = opts.indent ?? "";
1246
+ const nested = `${indent} `;
1247
+ const blocks = [];
1248
+ for (const [label, output] of [
1249
+ ["stdout", value.stdout],
1250
+ ["stderr", value.stderr]
1251
+ ]) {
1252
+ if (!output)
1253
+ continue;
1254
+ blocks.push(`${indent}${label}:`);
1255
+ for (const line of truncateTextOutput(output).replace(/\s+$/, "").split(/\r?\n/)) {
1256
+ blocks.push(`${nested}${line}`);
1257
+ }
1258
+ }
1259
+ return blocks;
1260
+ }
1261
+ function publicLoop(loop) {
1262
+ const target = loop.target.type === "command" ? { ...loop.target, env: loop.target.env ? "[redacted]" : undefined } : loop.target.type === "agent" ? { ...loop.target, prompt: redact(loop.target.prompt) } : loop.target;
1263
+ return {
1264
+ ...loop,
1265
+ target
1266
+ };
1267
+ }
1268
+ function publicRun(run, showOutput = false, opts = {}) {
1269
+ return {
1270
+ ...run,
1271
+ stdout: showOutput ? run.stdout : run.stdout ? `[redacted ${run.stdout.length} chars]` : undefined,
1272
+ stderr: showOutput ? run.stderr : run.stderr ? `[redacted ${run.stderr.length} chars]` : undefined,
1273
+ error: opts.redactError ? redact(run.error) : run.error
1274
+ };
1275
+ }
1276
+ function publicExecutorResult(result, showOutput = false) {
1277
+ return {
1278
+ ...result,
1279
+ stdout: showOutput ? result.stdout : result.stdout ? `[redacted ${result.stdout.length} chars]` : undefined,
1280
+ stderr: showOutput ? result.stderr : result.stderr ? `[redacted ${result.stderr.length} chars]` : undefined,
1281
+ error: redact(result.error)
1282
+ };
1283
+ }
1284
+ function publicWorkflow(workflow) {
1285
+ return {
1286
+ ...workflow,
1287
+ steps: workflow.steps.map((step) => ({
1288
+ ...step,
1289
+ target: step.target.type === "agent" ? { ...step.target, prompt: redact(step.target.prompt) } : step.target.type === "command" && step.target.env ? { ...step.target, env: "[redacted]" } : step.target
1290
+ }))
1291
+ };
1292
+ }
1293
+ function publicWorkflowRun(run) {
1294
+ return { ...run, error: redact(run.error) };
1295
+ }
1296
+ function publicWorkflowInvocation(invocation) {
1297
+ return redactSensitivePayload(invocation);
1298
+ }
1299
+ function publicWorkflowWorkItem(item) {
1300
+ return { ...item, lastReason: redact(item.lastReason, 240) };
1301
+ }
1302
+ function publicWorkflowStepRun(run, showOutput = false) {
1303
+ return {
1304
+ ...run,
1305
+ stdout: showOutput ? run.stdout : run.stdout ? `[redacted ${run.stdout.length} chars]` : undefined,
1306
+ stderr: showOutput ? run.stderr : run.stderr ? `[redacted ${run.stderr.length} chars]` : undefined,
1307
+ error: redact(run.error)
1308
+ };
1309
+ }
1310
+ function publicWorkflowEvent(event) {
1311
+ return { ...event, payload: redactSensitivePayload(event.payload) };
1312
+ }
1313
+ function publicGoal(goal) {
1314
+ return {
1315
+ ...goal,
1316
+ objective: redact(goal.objective, 120)
1317
+ };
1318
+ }
1319
+ function publicGoalRun(run) {
1320
+ return {
1321
+ ...run,
1322
+ evidence: redactSensitivePayload(run.evidence),
1323
+ rawResponse: redactSensitivePayload(run.rawResponse)
1324
+ };
1325
+ }
1326
+
1327
+ // src/lib/route/todos-cli.ts
1328
+ function defaultLoopsProject() {
1329
+ return process.env.LOOPS_TASK_PROJECT || process.env.LOOPS_DATA_DIR || `${process.env.HOME || homedir2()}/.hasna/loops`;
1330
+ }
1331
+ function runLocalCommand(command, args, opts = {}) {
1332
+ const result = spawnSync2(command, args, {
1333
+ input: opts.input,
1334
+ encoding: "utf8",
1335
+ timeout: opts.timeoutMs ?? 30000,
1336
+ maxBuffer: opts.maxBuffer ?? 8 * 1024 * 1024,
1337
+ env: process.env
1338
+ });
1339
+ return {
1340
+ ok: result.status === 0,
1341
+ status: result.status,
1342
+ stdout: result.stdout || "",
1343
+ stderr: result.stderr || "",
1344
+ error: result.error ? String(result.error.message || result.error) : ""
1345
+ };
1346
+ }
1347
+ function runLocalCommandWithStdoutFile(command, args, opts = {}) {
1348
+ const tempDir = mkdtempSync(join3(tmpdir(), "loops-command-output-"));
1349
+ const stdoutPath = join3(tempDir, "stdout");
1350
+ const stdoutFd = openSync(stdoutPath, "w");
1351
+ let result;
1352
+ try {
1353
+ result = spawnSync2(command, args, {
1354
+ input: opts.input,
1355
+ encoding: "utf8",
1356
+ timeout: opts.timeoutMs ?? 30000,
1357
+ maxBuffer: opts.maxBuffer ?? 8 * 1024 * 1024,
1358
+ env: process.env,
1359
+ stdio: ["pipe", stdoutFd, "pipe"]
1360
+ });
1361
+ } finally {
1362
+ closeSync(stdoutFd);
1363
+ }
1364
+ try {
1365
+ return {
1366
+ ok: result.status === 0,
1367
+ status: result.status,
1368
+ stdout: readFileSync3(stdoutPath, "utf8"),
1369
+ stderr: typeof result.stderr === "string" ? result.stderr : result.stderr?.toString() || "",
1370
+ error: result.error ? String(result.error.message || result.error) : ""
1371
+ };
1372
+ } finally {
1373
+ rmSync2(tempDir, { recursive: true, force: true });
1374
+ }
1375
+ }
1376
+ function ensureTodosTaskList(project, slug, name, description) {
1377
+ runLocalCommand("todos", ["--project", project, "task-lists", "--add", name, "--slug", slug, "-d", description]);
1378
+ const list = runLocalCommand("todos", ["--project", project, "--json", "task-lists"]);
1379
+ if (!list.ok)
1380
+ throw new Error(list.stderr || list.error || "failed to list todos task lists");
1381
+ const values = JSON.parse(list.stdout || "[]");
1382
+ const found = values.find((entry) => entry.slug === slug);
1383
+ if (!found)
1384
+ throw new Error(`todos task list not found after ensure: ${slug}`);
1385
+ return found.id;
1386
+ }
1387
+ function todosMutationSummary(result) {
1388
+ return {
1389
+ ok: result.ok,
1390
+ status: result.status,
1391
+ error: result.ok ? undefined : redact(result.stderr || result.error || "todos mutation failed", 320)
1392
+ };
1393
+ }
1394
+
1205
1395
  // src/lib/store.ts
1206
1396
  var DEFAULT_RECOVERY_BATCH_LIMIT = 100;
1207
1397
  var DEFAULT_RECOVERY_SCAN_MULTIPLIER = 5;
@@ -1211,6 +1401,7 @@ var TERMINAL_RUN_STATUSES = ["succeeded", "failed", "timed_out", "abandoned", "s
1211
1401
  var PRUNE_BATCH_SIZE = 400;
1212
1402
  var GENERATED_ROUTE_TEMPLATE_IDS = new Set(["todos-task-worker-verifier", "task-lifecycle", "event-worker-verifier"]);
1213
1403
  var GENERATED_ROUTE_KEYS = new Set(["todos-task", "generic-event"]);
1404
+ var TASK_LIFECYCLE_TEMPLATE_ID = "task-lifecycle";
1214
1405
  function rowToLoop(row) {
1215
1406
  return {
1216
1407
  id: row.id,
@@ -1261,6 +1452,9 @@ function rowToRun(row) {
1261
1452
  updatedAt: row.updated_at
1262
1453
  };
1263
1454
  }
1455
+ function latestRunTime(row) {
1456
+ return row.finished_at ?? row.started_at ?? row.created_at;
1457
+ }
1264
1458
  function rowToWorkflow(row) {
1265
1459
  return {
1266
1460
  id: row.id,
@@ -1515,7 +1709,7 @@ class Store {
1515
1709
  const file = path ?? dbPath();
1516
1710
  if (file !== ":memory:")
1517
1711
  ensurePrivateStorePath(file);
1518
- this.rootDir = file === ":memory:" ? mkdtempSync(join3(tmpdir(), "open-loops-store-")) : dirname2(file);
1712
+ this.rootDir = file === ":memory:" ? mkdtempSync2(join4(tmpdir2(), "open-loops-store-")) : dirname2(file);
1519
1713
  if (file === ":memory:")
1520
1714
  this.memoryRootDir = this.rootDir;
1521
1715
  this.db = new Database(file);
@@ -2013,7 +2207,32 @@ class Store {
2013
2207
  } else {
2014
2208
  rows = this.db.query("SELECT * FROM loops WHERE archived_at IS NULL ORDER BY status ASC, next_run_at ASC LIMIT ?").all(limit);
2015
2209
  }
2016
- return rows.map(rowToLoop);
2210
+ return this.withLatestRunSummaries(rows.map(rowToLoop));
2211
+ }
2212
+ withLatestRunSummaries(loops) {
2213
+ if (loops.length === 0)
2214
+ return loops;
2215
+ const placeholders = loops.map(() => "?").join(",");
2216
+ const rows = this.db.query(`SELECT loop_id, id, status, started_at, finished_at, created_at
2217
+ FROM (
2218
+ SELECT loop_id, id, status, started_at, finished_at, created_at,
2219
+ ROW_NUMBER() OVER (PARTITION BY loop_id ORDER BY created_at DESC, id DESC) AS rn
2220
+ FROM loop_runs
2221
+ WHERE loop_id IN (${placeholders})
2222
+ )
2223
+ WHERE rn = 1`).all(...loops.map((loop) => loop.id));
2224
+ const latestByLoopId = new Map(rows.map((row) => [row.loop_id, row]));
2225
+ return loops.map((loop) => {
2226
+ const latest = latestByLoopId.get(loop.id);
2227
+ if (!latest)
2228
+ return loop;
2229
+ return {
2230
+ ...loop,
2231
+ latestRunId: latest.id,
2232
+ latestRunStatus: latest.status,
2233
+ lastRunAt: latestRunTime(latest)
2234
+ };
2235
+ });
2017
2236
  }
2018
2237
  dueLoops(now, limit = 500) {
2019
2238
  const rows = this.db.query(`SELECT * FROM loops
@@ -2132,6 +2351,45 @@ class Store {
2132
2351
  throw error;
2133
2352
  }
2134
2353
  }
2354
+ updateAgentLoopTimeout(idOrName, timeoutMs, opts = {}) {
2355
+ const updated = (opts.now ?? new Date).toISOString();
2356
+ this.db.exec("BEGIN IMMEDIATE");
2357
+ try {
2358
+ const current = this.requireUniqueLoop(idOrName);
2359
+ if (current.archivedAt)
2360
+ throw new LoopArchivedError(current.name || current.id);
2361
+ if (current.target.type !== "agent")
2362
+ throw new Error(`loop is not an agent loop: ${idOrName}`);
2363
+ if (this.hasRunningRun(current.id))
2364
+ throw new Error(`refusing to update running loop: ${current.id}`);
2365
+ const target = { ...current.target, timeoutMs };
2366
+ if (timeoutMs === null && target.idleTimeoutMs !== undefined)
2367
+ delete target.idleTimeoutMs;
2368
+ const res = this.db.query(`UPDATE loops SET target_json=$target, updated_at=$updated
2369
+ WHERE id=$id
2370
+ AND ($daemonLeaseId IS NULL OR EXISTS (
2371
+ SELECT 1 FROM daemon_lease WHERE id=$daemonLeaseId AND expires_at > $now
2372
+ ))`).run({
2373
+ $id: current.id,
2374
+ $target: JSON.stringify(target),
2375
+ $updated: updated,
2376
+ $daemonLeaseId: opts.daemonLeaseId ?? null,
2377
+ $now: updated
2378
+ });
2379
+ if (res.changes !== 1)
2380
+ throw new Error("daemon lease lost");
2381
+ this.db.exec("COMMIT");
2382
+ const after = this.getLoop(current.id);
2383
+ if (!after)
2384
+ throw new Error(`loop not found after timeout update: ${current.id}`);
2385
+ return after;
2386
+ } catch (error) {
2387
+ try {
2388
+ this.db.exec("ROLLBACK");
2389
+ } catch {}
2390
+ throw error;
2391
+ }
2392
+ }
2135
2393
  createAndRetargetWorkflowLoop(idOrName, workflowInput, opts = {}) {
2136
2394
  const normalized = normalizeCreateWorkflowInput(workflowInput);
2137
2395
  const updated = (opts.now ?? new Date).toISOString();
@@ -2462,6 +2720,59 @@ class Store {
2462
2720
  updated
2463
2721
  });
2464
2722
  }
2723
+ taskLifecycleTodosPointerContext(workflowRunId) {
2724
+ const run = this.getWorkflowRun(workflowRunId);
2725
+ if (!run || run.status !== "succeeded" || !run.invocationId || !run.workItemId || !run.manifestPath)
2726
+ return;
2727
+ const workItem = this.getWorkflowWorkItem(run.workItemId);
2728
+ if (!workItem || workItem.routeKey !== "todos-task")
2729
+ return;
2730
+ const invocation = this.getWorkflowInvocation(run.invocationId);
2731
+ if (!invocation || invocation.templateId !== TASK_LIFECYCLE_TEMPLATE_ID)
2732
+ return;
2733
+ const projectPath = workItem.projectKey ?? invocation.scope?.projectPath;
2734
+ const taskId = invocation.subjectRef.id ?? workItem.subjectRef;
2735
+ if (!projectPath || !taskId)
2736
+ return;
2737
+ return {
2738
+ projectPath,
2739
+ taskId,
2740
+ invocationId: invocation.id,
2741
+ workflowRunId: run.id,
2742
+ manifestPath: run.manifestPath
2743
+ };
2744
+ }
2745
+ syncSuccessfulTaskLifecycleTodosPointers(workflowRunId) {
2746
+ const context = this.taskLifecycleTodosPointerContext(workflowRunId);
2747
+ if (!context)
2748
+ return;
2749
+ const result = runLocalCommand("todos", [
2750
+ "--project",
2751
+ context.projectPath,
2752
+ "task",
2753
+ "workflow-pointers",
2754
+ context.taskId,
2755
+ "--clear",
2756
+ "--invocation",
2757
+ context.invocationId,
2758
+ "--run",
2759
+ context.workflowRunId,
2760
+ "--manifest",
2761
+ context.manifestPath,
2762
+ "--state",
2763
+ "succeeded",
2764
+ "--actor",
2765
+ "openloops:task-lifecycle"
2766
+ ]);
2767
+ this.appendWorkflowEvent(workflowRunId, result.ok ? "todos_workflow_pointers_synced" : "todos_workflow_pointers_sync_failed", undefined, {
2768
+ projectPath: context.projectPath,
2769
+ taskId: context.taskId,
2770
+ invocationId: context.invocationId,
2771
+ workflowRunId: context.workflowRunId,
2772
+ manifestPath: context.manifestPath,
2773
+ mutation: todosMutationSummary(result)
2774
+ });
2775
+ }
2465
2776
  createWorkflowInvocation(input) {
2466
2777
  const now = nowIso();
2467
2778
  const sourceDedupeKey = input.sourceRef.dedupeKey ?? undefined;
@@ -3424,6 +3735,8 @@ class Store {
3424
3735
  const run = this.getWorkflowRun(workflowRunId);
3425
3736
  if (!run)
3426
3737
  throw new Error(`workflow run not found after finalize: ${workflowRunId}`);
3738
+ if (changed && status === "succeeded")
3739
+ this.syncSuccessfulTaskLifecycleTodosPointers(workflowRunId);
3427
3740
  return run;
3428
3741
  }
3429
3742
  cancelWorkflowRun(workflowRunId, reason = "cancelled by user") {
@@ -3485,6 +3798,17 @@ class Store {
3485
3798
  const row = this.db.query("SELECT COUNT(*) AS count FROM loop_runs WHERE loop_id = ? AND scheduled_for = ? AND status = 'running'").get(loopId, scheduledFor);
3486
3799
  return (row?.count ?? 0) > 0;
3487
3800
  }
3801
+ hasBlockingRunningRunForOtherSlot(loopId, scheduledFor, nowIso2) {
3802
+ const rows = this.db.query(`SELECT * FROM loop_runs
3803
+ WHERE loop_id = ? AND scheduled_for <> ? AND status = 'running'`).all(loopId, scheduledFor);
3804
+ return rows.some((row) => {
3805
+ if (!row.lease_expires_at || row.lease_expires_at > nowIso2)
3806
+ return true;
3807
+ if (isRecordedProcessAlive(row.pid, row.process_started_at))
3808
+ return true;
3809
+ return this.hasLiveWorkflowStepProcesses(row.id);
3810
+ });
3811
+ }
3488
3812
  markRunPid(id, pid, claimedBy, opts = {}) {
3489
3813
  const now = (opts.now ?? new Date).toISOString();
3490
3814
  const startedMs = processStartTimeMs(pid);
@@ -3617,6 +3941,10 @@ class Store {
3617
3941
  loop = currentLoop;
3618
3942
  const leaseExpiresAt = new Date(now.getTime() + loop.leaseMs).toISOString();
3619
3943
  const existing = this.getRunBySlot(loop.id, scheduledFor);
3944
+ if (loop.overlap === "skip" && this.hasBlockingRunningRunForOtherSlot(loop.id, scheduledFor, startedAt)) {
3945
+ this.db.exec("COMMIT");
3946
+ return;
3947
+ }
3620
3948
  if (existing) {
3621
3949
  if (existing.status === "running") {
3622
3950
  if (existing.leaseExpiresAt && existing.leaseExpiresAt <= startedAt && isRecordedProcessAlive(existing.pid, existing.processStartedAt)) {
@@ -4188,9 +4516,9 @@ class Store {
4188
4516
  const runDir = dirname2(manifestPath);
4189
4517
  try {
4190
4518
  if (/^[0-9a-f]{12,64}$/.test(basename2(runDir))) {
4191
- rmSync2(runDir, { recursive: true, force: true });
4519
+ rmSync3(runDir, { recursive: true, force: true });
4192
4520
  } else {
4193
- rmSync2(manifestPath, { force: true });
4521
+ rmSync3(manifestPath, { force: true });
4194
4522
  }
4195
4523
  } catch {}
4196
4524
  }
@@ -4257,12 +4585,26 @@ class Store {
4257
4585
  this.db.close();
4258
4586
  if (this.memoryRootDir) {
4259
4587
  try {
4260
- rmSync2(this.memoryRootDir, { recursive: true, force: true });
4588
+ rmSync3(this.memoryRootDir, { recursive: true, force: true });
4261
4589
  } catch {}
4262
4590
  this.memoryRootDir = undefined;
4263
4591
  }
4264
4592
  }
4265
4593
  }
4266
4594
  export {
4595
+ workItemStatusForLoopRun,
4596
+ rowToWorkflowWorkItem,
4597
+ rowToWorkflowStepRun,
4598
+ rowToWorkflowRun,
4599
+ rowToWorkflowInvocation,
4600
+ rowToWorkflowEvent,
4601
+ rowToWorkflow,
4602
+ rowToRun,
4603
+ rowToLoop,
4604
+ rowToLease,
4605
+ rowToGoalRun,
4606
+ rowToGoalPlanNode,
4607
+ rowToGoal,
4608
+ persistedRunOutput,
4267
4609
  Store
4268
4610
  };