satay 0.1.0a1__py3-none-any.whl

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 (51) hide show
  1. satay/__init__.py +57 -0
  2. satay/_studio_assets/assets/index-BEr3SCNe.css +1 -0
  3. satay/_studio_assets/assets/index-By_8Sh9l.js +10 -0
  4. satay/_studio_assets/index.html +13 -0
  5. satay/api/__init__.py +38 -0
  6. satay/api/context.py +88 -0
  7. satay/api/decorators.py +82 -0
  8. satay/api/primitives.py +250 -0
  9. satay/api/registry.py +89 -0
  10. satay/api/run_handle.py +75 -0
  11. satay/api/runner.py +251 -0
  12. satay/blobs/__init__.py +173 -0
  13. satay/cli/__init__.py +13 -0
  14. satay/cli/main.py +117 -0
  15. satay/config.py +102 -0
  16. satay/control/__init__.py +114 -0
  17. satay/control/api.py +116 -0
  18. satay/control/commands.py +382 -0
  19. satay/control/redaction.py +82 -0
  20. satay/control/security.py +128 -0
  21. satay/control/server.py +207 -0
  22. satay/control/views.py +491 -0
  23. satay/demo.py +489 -0
  24. satay/devstack/__init__.py +27 -0
  25. satay/devstack/cli.py +41 -0
  26. satay/devstack/lock.py +128 -0
  27. satay/devstack/orchestrator.py +224 -0
  28. satay/executor/__init__.py +247 -0
  29. satay/journal/__init__.py +121 -0
  30. satay/journal/codec.py +217 -0
  31. satay/journal/events.py +175 -0
  32. satay/journal/store.py +450 -0
  33. satay/journal/timeline.py +96 -0
  34. satay/py.typed +0 -0
  35. satay/replay/__init__.py +31 -0
  36. satay/replay/driver.py +73 -0
  37. satay/replay/engine.py +792 -0
  38. satay/replay/identity.py +132 -0
  39. satay/replay/nondeterminism.py +51 -0
  40. satay/testing/__init__.py +32 -0
  41. satay/testing/clock.py +104 -0
  42. satay/testing/faults.py +81 -0
  43. satay/testing/fixtures.py +67 -0
  44. satay/testing/rng.py +60 -0
  45. satay/timers/__init__.py +287 -0
  46. satay/versioning/__init__.py +152 -0
  47. satay-0.1.0a1.dist-info/METADATA +161 -0
  48. satay-0.1.0a1.dist-info/RECORD +51 -0
  49. satay-0.1.0a1.dist-info/WHEEL +4 -0
  50. satay-0.1.0a1.dist-info/entry_points.txt +2 -0
  51. satay-0.1.0a1.dist-info/licenses/LICENSE +202 -0
satay/__init__.py ADDED
@@ -0,0 +1,57 @@
1
+ """Satay Runtime — local-first durable execution for async Python.
2
+
3
+ The public surface below is implemented and exercised end-to-end: durable calls are
4
+ recorded to a SQLite journal and workflows replay from the top on resume, reusing
5
+ recorded results. Async workflows and tasks only. See ``CLAUDE.md`` for the shipped
6
+ feature set and the deliberate MVP gaps, and ``docs/`` for the specs.
7
+
8
+ The public surface (ARCHITECTURE §1):
9
+
10
+ - ``@workflow`` / ``@task`` — author decorators
11
+ - ``start`` — create/look up a run, returns a ``RunHandle``
12
+ - ``sleep`` / ``wait_for_event`` / ``send_event`` — event & time primitives
13
+ - ``map`` / ``gather`` / ``start_child`` — composition primitives
14
+ - ``TaskContext`` — the task-body context
15
+ - ``RunHandle`` — the run handle
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ from satay.api import (
21
+ EffectSafetyError,
22
+ NondeterminismError,
23
+ RunHandle,
24
+ TaskContext,
25
+ gather,
26
+ map,
27
+ send_event,
28
+ sleep,
29
+ start,
30
+ start_child,
31
+ task,
32
+ task_context,
33
+ wait_for_event,
34
+ workflow,
35
+ )
36
+ from satay.versioning import VersionMismatchError
37
+
38
+ __version__ = "0.0.0"
39
+
40
+ __all__ = [
41
+ "EffectSafetyError",
42
+ "NondeterminismError",
43
+ "RunHandle",
44
+ "TaskContext",
45
+ "VersionMismatchError",
46
+ "__version__",
47
+ "gather",
48
+ "map",
49
+ "send_event",
50
+ "sleep",
51
+ "start",
52
+ "start_child",
53
+ "task",
54
+ "task_context",
55
+ "wait_for_event",
56
+ "workflow",
57
+ ]
@@ -0,0 +1 @@
1
+ :root{--bg: #f4f5f7;--surface: #ffffff;--surface-2: #eef0f3;--surface-3: #e6e9ee;--border: #dee1e7;--border-strong: #c7ccd6;--text: #16171d;--text-dim: #565b66;--text-faint: #8b909c;--accent: #b60fb6;--accent-bright: #d946ef;--accent-soft: rgba(182, 15, 182, .1);--accent-ring: rgba(182, 15, 182, .28);--running: #2563eb;--running-soft: rgba(37, 99, 235, .12);--completed: #17914e;--completed-soft: rgba(23, 145, 78, .13);--failed: #d63030;--failed-soft: rgba(214, 48, 48, .12);--cancelled: #6b7280;--cancelled-soft: rgba(107, 114, 128, .14);--waiting: #c47606;--waiting-soft: rgba(196, 118, 6, .14);--font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-mono: ui-monospace, "SF Mono", "Cascadia Code", "JetBrains Mono", Menlo, Consolas, monospace;--shadow: 0 1px 2px rgba(20, 22, 28, .06), 0 4px 16px rgba(20, 22, 28, .05);--radius: 6px;--rail: 2px;color-scheme:light}:root[data-theme=dark]{--bg: #0e0f13;--surface: #16181e;--surface-2: #1c1f27;--surface-3: #232732;--border: #292d38;--border-strong: #3a404e;--text: #e8eaf0;--text-dim: #9aa0ad;--text-faint: #656b78;--accent: #e879f9;--accent-bright: #f0abfc;--accent-soft: rgba(232, 121, 249, .12);--accent-ring: rgba(232, 121, 249, .3);--running: #5b93f6;--running-soft: rgba(91, 147, 246, .15);--completed: #45c07e;--completed-soft: rgba(69, 192, 126, .15);--failed: #f0736e;--failed-soft: rgba(240, 115, 110, .15);--cancelled: #8b93a3;--cancelled-soft: rgba(139, 147, 163, .16);--waiting: #f0ad3c;--waiting-soft: rgba(240, 173, 60, .15);--shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 24px rgba(0, 0, 0, .35);color-scheme:dark}@media(prefers-color-scheme:dark){:root:not([data-theme]){color-scheme:dark}}*{box-sizing:border-box}html,body{height:100%}body{margin:0;background:var(--bg);color:var(--text);font-family:var(--font-sans);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased;overflow:hidden}.chip{display:inline-flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:10.5px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;padding:3px 8px 3px 7px;border-radius:20px;white-space:nowrap}.chip .pip{width:6px;height:6px;border-radius:50%;background:currentColor}.chip.running{color:var(--running);background:var(--running-soft)}.chip.completed{color:var(--completed);background:var(--completed-soft)}.chip.failed{color:var(--failed);background:var(--failed-soft)}.chip.cancelled{color:var(--cancelled);background:var(--cancelled-soft)}.chip.waiting{color:var(--waiting);background:var(--waiting-soft)}.chip.accent{color:var(--accent);background:var(--accent-soft)}.chip.running .pip{animation:pulse 1.6s ease-in-out infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.35}}pre.json{margin:0;font-family:var(--font-mono);font-size:11.5px;line-height:1.65;color:var(--text-dim);overflow-x:auto;white-space:pre}.jk{color:var(--text)}.js{color:var(--completed)}.jn{color:var(--running)}.jb{color:var(--accent)}.redacted{display:inline-flex;align-items:center;gap:4px;font-family:var(--font-mono);font-size:10.5px;color:var(--failed);background:var(--failed-soft);padding:0 6px;border-radius:4px;border:1px dashed var(--failed)}.view-title{font-size:20px;font-weight:640;letter-spacing:-.3px;margin:0 0 3px}.view-sub{color:var(--text-dim);font-size:13px;margin:0 0 22px;max-width:72ch}.view-sub code{font-family:var(--font-mono);font-size:11.5px;background:var(--surface-2);padding:1px 5px;border-radius:4px;color:var(--text)}.empty-state{text-align:center;padding:80px 20px;color:var(--text-faint);font-family:var(--font-mono);font-size:13px}.error-state{color:var(--failed)}::-webkit-scrollbar{width:11px;height:11px}::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:6px;border:3px solid var(--bg)}::-webkit-scrollbar-thumb:hover{background:var(--text-faint)}@media(prefers-reduced-motion:reduce){*{animation:none!important;scroll-behavior:auto}}.runs-table.svelte-vdllgp{width:100%;border-collapse:collapse;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;box-shadow:var(--shadow)}.runs-table.svelte-vdllgp thead:where(.svelte-vdllgp) th:where(.svelte-vdllgp){text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);font-weight:600;padding:11px 16px;border-bottom:1px solid var(--border);background:var(--surface-2)}.runs-table.svelte-vdllgp tbody:where(.svelte-vdllgp) tr:where(.svelte-vdllgp){cursor:pointer;border-bottom:1px solid var(--border);transition:background .1s}.runs-table.svelte-vdllgp tbody:where(.svelte-vdllgp) tr:where(.svelte-vdllgp):last-child{border-bottom:none}.runs-table.svelte-vdllgp tbody:where(.svelte-vdllgp) tr:where(.svelte-vdllgp):hover{background:var(--surface-2)}.runs-table.svelte-vdllgp td:where(.svelte-vdllgp){padding:13px 16px;vertical-align:middle}.c-id.svelte-vdllgp{font-family:var(--font-mono);font-weight:600;font-size:13px}.c-id.svelte-vdllgp .bolt:where(.svelte-vdllgp){color:var(--accent);margin-left:7px;font-size:12px}.c-wf.svelte-vdllgp{color:var(--text-dim)}.c-ver.svelte-vdllgp{font-family:var(--font-mono);font-size:12px;color:var(--text-dim)}.c-ver.svelte-vdllgp .tag:where(.svelte-vdllgp){background:var(--surface-2);border:1px solid var(--border);padding:2px 7px;border-radius:5px}.c-time.svelte-vdllgp{font-family:var(--font-mono);font-size:12px;color:var(--text-dim);white-space:nowrap}.c-time.svelte-vdllgp .abs:where(.svelte-vdllgp){color:var(--text-faint);font-size:11px}.c-key.svelte-vdllgp{font-family:var(--font-mono);font-size:11.5px;color:var(--text-faint)}.runs-count.svelte-vdllgp{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);margin:14px 2px 0}.legend.svelte-cfijfh{display:flex;flex-wrap:wrap;gap:6px 16px;margin-bottom:20px;padding:12px 16px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius)}.li.svelte-cfijfh{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--text-dim)}.nd.svelte-cfijfh{width:11px;height:11px;border-radius:50%;flex:none}.tl.svelte-cfijfh{position:relative;margin-left:4px;padding-left:30px}.tl.svelte-cfijfh:before{content:"";position:absolute;left:6px;top:6px;bottom:10px;width:var(--rail);background:var(--border-strong);border-radius:2px}.ev.svelte-cfijfh{position:relative;margin-bottom:3px}.ev-head.svelte-cfijfh{display:grid;grid-template-columns:46px 1fr auto;align-items:center;gap:12px;width:100%;padding:9px 12px;border-radius:var(--radius);cursor:pointer;border:1px solid transparent;background:none;text-align:left;font:inherit;color:inherit;transition:background .1s,border-color .1s}.ev-head.svelte-cfijfh:hover{background:var(--surface);border-color:var(--border)}.ev-node.svelte-cfijfh{position:absolute;left:0;top:15px;width:13px;height:13px;border-radius:50%;background:var(--surface);border:2.5px solid var(--cancelled);z-index:2}.k-lifecycle.svelte-cfijfh{border-color:var(--text-faint);background:var(--text-faint)}.k-sched.svelte-cfijfh{border-color:var(--running)}.k-run.svelte-cfijfh{border-color:var(--running);background:var(--running)}.k-done.svelte-cfijfh{border-color:var(--completed);background:var(--completed)}.k-fail.svelte-cfijfh{border-color:var(--failed);background:var(--failed)}.k-wait.svelte-cfijfh{border-color:var(--waiting);background:var(--surface)}.k-timer.svelte-cfijfh{border-color:var(--waiting);background:var(--waiting)}.k-event.svelte-cfijfh{border-color:var(--waiting);background:var(--waiting);transform:rotate(45deg);border-radius:2px}.ev-seq.svelte-cfijfh{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);text-align:right}.ev-main.svelte-cfijfh{display:flex;align-items:center;gap:10px;min-width:0;flex-wrap:wrap}.ev-type.svelte-cfijfh{font-family:var(--font-mono);font-size:12.5px;font-weight:600;letter-spacing:-.1px}.ev-type.k-fail.svelte-cfijfh{color:var(--failed)}.ev-type.k-done.svelte-cfijfh{color:var(--completed)}.ev-type.k-resume.svelte-cfijfh{color:var(--accent)}.ev-summary.svelte-cfijfh{font-family:var(--font-mono);font-size:11.5px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ev-summary.svelte-cfijfh .strong:where(.svelte-cfijfh){color:var(--text);font-weight:600}.ev-summary.svelte-cfijfh .danger:where(.svelte-cfijfh){color:var(--failed)}.ev-ts.svelte-cfijfh{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);white-space:nowrap}.ev-caret.svelte-cfijfh{color:var(--text-faint);font-size:10px;transition:transform .15s;display:inline-block}.ev.is-open.svelte-cfijfh .ev-caret:where(.svelte-cfijfh){transform:rotate(90deg)}.ev-fork.svelte-cfijfh{position:absolute;right:8px;top:8px;z-index:3;display:none;align-items:center;gap:5px;font-family:var(--font-mono);font-size:10px;letter-spacing:.3px;padding:4px 9px;border-radius:var(--radius);cursor:pointer;background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-ring)}.ev-fork.svelte-cfijfh:hover{background:var(--accent);color:#fff}.ev.svelte-cfijfh:hover .ev-fork:where(.svelte-cfijfh){display:inline-flex}.ev-payload.svelte-cfijfh{margin:2px 0 8px}.payload-box.svelte-cfijfh{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.pb-label.svelte-cfijfh{font-family:var(--font-mono);font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);padding:8px 14px 0}.pb-json.svelte-cfijfh{padding:6px 14px 14px}.ev.is-resume.svelte-cfijfh .ev-node:where(.svelte-cfijfh){border-color:var(--accent);background:var(--accent);box-shadow:0 0 0 4px var(--accent-ring)}.seam.svelte-cfijfh{position:relative;margin:6px 0;padding:12px 16px 12px 0}.seam.svelte-cfijfh:before{content:"";position:absolute;left:6px;top:0;bottom:0;width:var(--rail);background:repeating-linear-gradient(var(--accent) 0 5px,transparent 5px 10px)}.seam-card.svelte-cfijfh{display:flex;align-items:center;gap:14px;margin-left:24px;background:linear-gradient(90deg,var(--accent-soft),transparent 85%);border:1px solid var(--accent-ring);border-left:3px solid var(--accent);border-radius:var(--radius);padding:11px 15px}.seam-bolt.svelte-cfijfh{width:30px;height:30px;flex:none;border-radius:8px;display:grid;place-items:center;background:var(--accent);color:#fff;font-size:16px;box-shadow:0 0 0 4px var(--accent-ring);animation:svelte-cfijfh-sparks 2.2s ease-in-out infinite}@keyframes svelte-cfijfh-sparks{0%,to{box-shadow:0 0 0 4px var(--accent-ring),0 0 8px 0 var(--accent-soft)}50%{box-shadow:0 0 0 6px transparent,0 0 18px 4px var(--accent-ring)}}.seam-txt.svelte-cfijfh{min-width:0}.seam-txt.svelte-cfijfh .t1:where(.svelte-cfijfh){font-family:var(--font-mono);font-size:12px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--accent)}.seam-txt.svelte-cfijfh .t2:where(.svelte-cfijfh){font-size:12px;color:var(--text-dim)}.seam-txt.svelte-cfijfh .t2:where(.svelte-cfijfh) b:where(.svelte-cfijfh){color:var(--text);font-family:var(--font-mono)}.tnode.svelte-7ey46k{margin-bottom:8px}.trow.svelte-7ey46k{display:flex;align-items:center;gap:11px;width:100%;padding:11px 14px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;text-align:left;font:inherit;color:inherit;transition:border-color .12s,background .1s}.trow.static.svelte-7ey46k{cursor:default}.trow.svelte-7ey46k:not(.static):hover{border-color:var(--border-strong);background:var(--surface-2)}.glyph.svelte-7ey46k{width:22px;height:22px;flex:none;border-radius:5px;display:grid;place-items:center;font-family:var(--font-mono);font-size:10px;font-weight:700}.glyph.task.svelte-7ey46k{background:var(--running-soft);color:var(--running)}.glyph.map.svelte-7ey46k{background:var(--accent-soft);color:var(--accent)}.glyph.child.svelte-7ey46k{background:var(--completed-soft);color:var(--completed)}.tname.svelte-7ey46k{font-family:var(--font-mono);font-size:13px;font-weight:600}.tident.svelte-7ey46k{font-family:var(--font-mono);font-size:11px;color:var(--text-faint)}.tmeta.svelte-7ey46k{margin-left:auto;display:flex;align-items:center;gap:12px}.attempts.svelte-7ey46k{font-family:var(--font-mono);font-size:11px;color:var(--text-dim)}.attempts.retried.svelte-7ey46k{color:var(--waiting)}.child-wrap.svelte-7ey46k{margin:8px 0 4px 26px;border-left:2px dashed var(--border-strong);padding-left:18px}.child-head.svelte-7ey46k{display:flex;align-items:center;gap:10px;margin-bottom:8px}.clabel.svelte-7ey46k{font-family:var(--font-mono);font-size:9.5px;letter-spacing:1px;text-transform:uppercase;color:var(--completed)}.crun.svelte-7ey46k{font-family:var(--font-mono);font-size:11px;color:var(--text-faint)}.map-wrap.svelte-7ey46k{margin:4px 0 4px 26px;padding-left:18px;border-left:2px solid var(--accent-ring)}.map-note.svelte-7ey46k{font-family:var(--font-mono);font-size:10.5px;color:var(--text-dim);margin:4px 0 9px}.map-note.svelte-7ey46k b:where(.svelte-7ey46k){color:var(--accent)}.map-grid.svelte-7ey46k{display:grid;grid-template-columns:repeat(auto-fill,minmax(148px,1fr));gap:7px}.map-item.svelte-7ey46k{display:flex;align-items:center;gap:8px;padding:8px 10px;cursor:pointer;background:var(--surface);border:1px solid var(--border);border-radius:5px;font:inherit;color:inherit;transition:border-color .1s}.map-item.svelte-7ey46k:hover{border-color:var(--border-strong)}.mk.svelte-7ey46k{font-family:var(--font-mono);font-size:11.5px;font-weight:600}.mretry.svelte-7ey46k{font-family:var(--font-mono);font-size:10px;color:var(--waiting)}.mdot.svelte-7ey46k{width:8px;height:8px;border-radius:50%;flex:none;margin-left:auto}.mdot.completed.svelte-7ey46k{background:var(--completed)}.mdot.running.svelte-7ey46k{background:var(--running)}.mdot.failed.svelte-7ey46k{background:var(--failed)}.logical.svelte-u9er0g{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:18px 20px;box-shadow:var(--shadow);margin-bottom:6px;position:relative}.logical.svelte-u9er0g:after{content:"LOGICAL TASK";position:absolute;top:14px;right:18px;font-family:var(--font-mono);font-size:9px;letter-spacing:1.5px;color:var(--text-faint)}.lt-name.svelte-u9er0g{font-family:var(--font-mono);font-size:18px;font-weight:650;letter-spacing:-.3px;display:flex;align-items:center;gap:12px}.lt-ident.svelte-u9er0g{font-family:var(--font-mono);font-size:11.5px;color:var(--text-faint);margin-top:3px}.io-grid.svelte-u9er0g{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:18px}@media(max-width:720px){.io-grid.svelte-u9er0g{grid-template-columns:1fr}}.io-label.svelte-u9er0g{font-family:var(--font-mono);font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);margin-bottom:5px}.io-box.svelte-u9er0g pre.json{background:var(--surface-2);border:1px solid var(--border);border-radius:5px;padding:12px 14px}.io-empty.svelte-u9er0g{font-family:var(--font-mono);font-size:12px;color:var(--text-faint);background:var(--surface-2);border:1px solid var(--border);border-radius:5px;padding:12px 14px}.usage.svelte-u9er0g{margin-top:18px}.u-label.svelte-u9er0g{font-family:var(--font-mono);font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);margin-bottom:7px}.usage-table.svelte-u9er0g{width:100%;border-collapse:collapse;font-family:var(--font-mono);font-size:12px;border:1px solid var(--border);border-radius:5px;overflow:hidden}.usage-table.svelte-u9er0g th:where(.svelte-u9er0g){text-align:left;font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);font-weight:600;padding:8px 12px;background:var(--surface-2);border-bottom:1px solid var(--border)}.usage-table.svelte-u9er0g th.r:where(.svelte-u9er0g){text-align:right}.usage-table.svelte-u9er0g td:where(.svelte-u9er0g){padding:9px 12px;border-bottom:1px solid var(--border);color:var(--text-dim)}.usage-table.svelte-u9er0g tr:where(.svelte-u9er0g):last-child td:where(.svelte-u9er0g){border-bottom:none}.usage-table.svelte-u9er0g td.num:where(.svelte-u9er0g){color:var(--text);text-align:right}.usage-none.svelte-u9er0g{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--text-dim);background:var(--surface-2);border:1px dashed var(--border-strong);border-radius:5px;padding:11px 14px}.usage-none.svelte-u9er0g code:where(.svelte-u9er0g){font-family:var(--font-mono);font-size:11px;color:var(--text)}.usage-none.svelte-u9er0g .dim:where(.svelte-u9er0g){color:var(--text-faint)}.attempts-label.svelte-u9er0g{font-family:var(--font-mono);font-size:9.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--text-faint);margin:26px 0 12px}.att-list.svelte-u9er0g{position:relative;padding-left:30px}.att-list.svelte-u9er0g:before{content:"";position:absolute;left:6px;top:12px;bottom:12px;width:var(--rail);background:var(--border-strong)}.att.svelte-u9er0g{position:relative;margin-bottom:12px}.att-node.svelte-u9er0g{position:absolute;left:-30px;top:16px;width:15px;height:15px;border-radius:50%;background:var(--surface);border:3px solid var(--completed);z-index:2}.att-node.failed.svelte-u9er0g{border-color:var(--failed);background:var(--failed)}.att-node.completed.svelte-u9er0g{border-color:var(--completed);background:var(--completed)}.att-node.running.svelte-u9er0g{border-color:var(--running);background:var(--surface)}.att-card.svelte-u9er0g{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:13px 16px}.att-card.failed.svelte-u9er0g{border-color:var(--failed-soft)}.att-top.svelte-u9er0g{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.att-n.svelte-u9er0g{font-family:var(--font-mono);font-size:13px;font-weight:700}.att-dur.svelte-u9er0g{font-family:var(--font-mono);font-size:11.5px;color:var(--text-dim);margin-left:auto}.att-times.svelte-u9er0g{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);margin-top:6px}.att-error.svelte-u9er0g{margin-top:11px;background:var(--failed-soft);border:1px solid var(--failed);border-radius:5px;padding:10px 13px}.att-error.svelte-u9er0g .et:where(.svelte-u9er0g){font-family:var(--font-mono);font-size:12px;font-weight:700;color:var(--failed)}.att-error.svelte-u9er0g .em:where(.svelte-u9er0g){font-family:var(--font-mono);font-size:11.5px;color:var(--text-dim);margin-top:3px}.att-retry.svelte-u9er0g{margin-top:10px;display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11.5px;color:var(--waiting)}.att-note.svelte-u9er0g{margin-top:10px;display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11.5px;color:var(--accent)}.rico.svelte-u9er0g{font-size:13px}.att-exhausted.svelte-u9er0g{margin-top:10px;display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11.5px;color:var(--failed)}.trace.svelte-u9er0g{margin-top:24px}.tr-label.svelte-u9er0g{display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:9.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--failed);margin-bottom:10px}pre.traceback.svelte-u9er0g{margin:0;background:var(--surface);border:1px solid var(--failed);border-left:3px solid var(--failed);border-radius:var(--radius);padding:14px 16px;font-family:var(--font-mono);font-size:11.5px;line-height:1.7;color:var(--text-dim);overflow-x:auto;white-space:pre}pre.traceback.svelte-u9er0g .tb-file{color:var(--text)}pre.traceback.svelte-u9er0g .tb-exc{color:var(--failed);font-weight:700}.picker.svelte-uzstyf{display:flex;align-items:center;gap:14px;margin-bottom:16px;padding:12px 16px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);flex-wrap:wrap}.pk-a.svelte-uzstyf,.pk-b.svelte-uzstyf{font-family:var(--font-mono);font-size:12.5px;color:var(--text-dim)}.pk-a.svelte-uzstyf b:where(.svelte-uzstyf){color:var(--text)}.pk-vs.svelte-uzstyf{font-family:var(--font-mono);font-size:11px;color:var(--text-faint);text-transform:uppercase;letter-spacing:1px}.pk-b.svelte-uzstyf select:where(.svelte-uzstyf){font-family:var(--font-mono);font-size:12px;padding:5px 8px;margin-left:4px;background:var(--surface-2);color:var(--text);border:1px solid var(--border);border-radius:var(--radius)}.summary.svelte-uzstyf{font-size:13px;color:var(--text-dim);margin-bottom:14px}.summary.svelte-uzstyf .tag:where(.svelte-uzstyf){font-family:var(--font-mono);font-size:11.5px;background:var(--surface-2);border:1px solid var(--border);padding:1px 6px;border-radius:5px}.cmp.svelte-uzstyf{width:100%;border-collapse:collapse;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.cmp.svelte-uzstyf thead:where(.svelte-uzstyf) th:where(.svelte-uzstyf){text-align:left;font-family:var(--font-mono);font-size:9.5px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint);font-weight:600;padding:11px 16px;border-bottom:1px solid var(--border);background:var(--surface-2);width:40%}.cmp.svelte-uzstyf thead:where(.svelte-uzstyf) th:where(.svelte-uzstyf):first-child{width:20%}.cmp.svelte-uzstyf tbody:where(.svelte-uzstyf) tr:where(.svelte-uzstyf){border-bottom:1px solid var(--border)}.cmp.svelte-uzstyf tbody:where(.svelte-uzstyf) tr:where(.svelte-uzstyf):last-child{border-bottom:none}.cmp.svelte-uzstyf tbody:where(.svelte-uzstyf) tr.changed:where(.svelte-uzstyf){background:var(--accent-soft)}.cmp.svelte-uzstyf td:where(.svelte-uzstyf){padding:12px 16px;vertical-align:top}.c-ident.svelte-uzstyf .ident:where(.svelte-uzstyf){font-family:var(--font-mono);font-weight:600;font-size:12.5px}.badge.svelte-uzstyf{display:inline-block;margin-left:7px;font-family:var(--font-mono);font-size:9px;letter-spacing:.5px;text-transform:uppercase;padding:1px 6px;border-radius:4px;background:var(--accent);color:#fff}.badge.only.svelte-uzstyf{background:var(--waiting)}.cell-line.svelte-uzstyf{font-family:var(--font-mono);font-size:11.5px;color:var(--text-dim);margin:2px 0}.cell-line.svelte-uzstyf .k:where(.svelte-uzstyf){display:inline-block;min-width:58px;color:var(--text-faint);font-size:9.5px;letter-spacing:.6px;text-transform:uppercase}.cell-line.svelte-uzstyf code:where(.svelte-uzstyf){color:var(--text)}.cell-line.time.svelte-uzstyf{color:var(--text-faint)}.cell-line.diff.svelte-uzstyf{color:var(--text);font-weight:600}.cell-line.diff.svelte-uzstyf code:where(.svelte-uzstyf){color:var(--accent-bright, var(--accent))}.absent.svelte-uzstyf{font-family:var(--font-mono);font-size:11.5px;color:var(--text-faint);font-style:italic}.app.svelte-1n46o8q{display:grid;grid-template-columns:232px 1fr;height:100vh}.sidebar.svelte-1n46o8q{background:var(--surface);border-right:1px solid var(--border);display:flex;flex-direction:column;padding:18px 14px;gap:4px;min-width:0}.brand.svelte-1n46o8q{display:flex;align-items:center;gap:9px;padding:4px 8px 14px}.mark.svelte-1n46o8q{width:26px;height:26px;border-radius:7px;flex:none;background:linear-gradient(150deg,var(--accent),var(--accent-bright));display:grid;place-items:center;box-shadow:0 0 0 1px var(--accent-ring),0 4px 12px var(--accent-soft)}.mark.svelte-1n46o8q svg:where(.svelte-1n46o8q){width:15px;height:15px}.word.svelte-1n46o8q{font-weight:650;letter-spacing:-.2px}.word.svelte-1n46o8q b:where(.svelte-1n46o8q){color:var(--accent);font-weight:650}.word.svelte-1n46o8q span:where(.svelte-1n46o8q){display:block;font-family:var(--font-mono);font-size:9.5px;letter-spacing:1.5px;color:var(--text-faint);text-transform:uppercase}.nav-label.svelte-1n46o8q{font-family:var(--font-mono);font-size:9.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--text-faint);padding:12px 8px 5px}.nav-item.svelte-1n46o8q{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--radius);color:var(--text-dim);font-weight:500;cursor:pointer;border:none;background:none;width:100%;text-align:left;font-family:inherit;font-size:13.5px;position:relative;transition:background .12s,color .12s}.nav-item.svelte-1n46o8q:hover:not(.is-disabled){background:var(--surface-2);color:var(--text)}.nav-item.is-active.svelte-1n46o8q{background:var(--accent-soft);color:var(--text)}.nav-item.is-active.svelte-1n46o8q:before{content:"";position:absolute;left:-14px;top:8px;bottom:8px;width:3px;background:var(--accent);border-radius:0 3px 3px 0}.nav-item.is-disabled.svelte-1n46o8q{opacity:.38;cursor:default}.sidebar-foot.svelte-1n46o8q{margin-top:auto;padding-top:14px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:10px}.conn.svelte-1n46o8q{display:flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11px;color:var(--text-dim);padding:0 8px}.conn.svelte-1n46o8q .dot:where(.svelte-1n46o8q){width:7px;height:7px;border-radius:50%;background:var(--completed);box-shadow:0 0 0 3px var(--completed-soft)}.theme-btn.svelte-1n46o8q{display:flex;align-items:center;gap:8px;justify-content:center;font-family:var(--font-mono);font-size:11px;letter-spacing:.4px;padding:7px;border-radius:var(--radius);cursor:pointer;background:var(--surface-2);color:var(--text-dim);border:1px solid var(--border);transition:background .12s}.theme-btn.svelte-1n46o8q:hover{background:var(--surface-3);color:var(--text)}.main.svelte-1n46o8q{min-width:0;display:flex;flex-direction:column;overflow:hidden}.runbar.svelte-1n46o8q{display:flex;align-items:center;gap:16px;padding:12px 26px;border-bottom:1px solid var(--border);background:var(--surface);min-height:56px;flex-wrap:wrap}.back.svelte-1n46o8q{display:flex;align-items:center;gap:6px;cursor:pointer;border:1px solid var(--border);background:none;color:var(--text-dim);font-family:var(--font-mono);font-size:11.5px;padding:5px 9px;border-radius:var(--radius)}.back.svelte-1n46o8q:hover{color:var(--text);background:var(--surface-2)}.rid.svelte-1n46o8q{font-family:var(--font-mono);font-size:15px;font-weight:600;letter-spacing:-.2px}.wf.svelte-1n46o8q{color:var(--text-dim);font-size:13px}.meta.svelte-1n46o8q{display:flex;gap:18px;margin-left:auto;align-items:center}.kv.svelte-1n46o8q{display:flex;flex-direction:column;gap:1px}.kv.svelte-1n46o8q .k:where(.svelte-1n46o8q){font-family:var(--font-mono);font-size:9px;letter-spacing:1px;text-transform:uppercase;color:var(--text-faint)}.kv.svelte-1n46o8q .v:where(.svelte-1n46o8q){font-family:var(--font-mono);font-size:12px;color:var(--text-dim)}.fork-chip.svelte-1n46o8q{cursor:pointer;border:1px solid var(--accent-ring);background:var(--accent-soft);color:var(--accent);font-family:var(--font-mono);font-size:10.5px;padding:3px 9px;border-radius:999px}.fork-chip.svelte-1n46o8q:hover{background:var(--accent);color:#fff}.mismatch-banner.svelte-1n46o8q{display:flex;align-items:center;gap:14px;margin:14px 26px 0;padding:12px 16px;background:linear-gradient(90deg,var(--accent-soft),transparent 90%);border:1px solid var(--accent-ring);border-left:3px solid var(--accent);border-radius:var(--radius)}.mb-bolt.svelte-1n46o8q{width:30px;height:30px;flex:none;border-radius:8px;display:grid;place-items:center;background:var(--accent);color:#fff;font-size:16px}.mb-txt.svelte-1n46o8q{min-width:0;flex:1}.mb-t1.svelte-1n46o8q{font-family:var(--font-mono);font-size:12px;font-weight:700;letter-spacing:.6px;text-transform:uppercase;color:var(--accent)}.mb-t2.svelte-1n46o8q{font-size:12.5px;color:var(--text-dim)}.mb-t2.svelte-1n46o8q b:where(.svelte-1n46o8q){color:var(--text);font-family:var(--font-mono)}.mb-act.svelte-1n46o8q{flex:none;display:flex;align-items:center;gap:6px;cursor:pointer;border:1px solid var(--accent);background:var(--accent);color:#fff;font-family:var(--font-mono);font-size:11.5px;padding:7px 12px;border-radius:var(--radius)}.mb-act.svelte-1n46o8q:hover{filter:brightness(1.08)}.view.svelte-1n46o8q{flex:1;overflow-y:auto;overflow-x:hidden;padding:26px}.view-wrap.svelte-1n46o8q{max-width:1080px;margin:0 auto}@media(max-width:640px){.app.svelte-1n46o8q{grid-template-columns:1fr}.sidebar.svelte-1n46o8q{display:none}}
@@ -0,0 +1,10 @@
1
+ var ea=Object.defineProperty;var Pr=e=>{throw TypeError(e)};var ta=(e,t,n)=>t in e?ea(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Ce=(e,t,n)=>ta(e,typeof t!="symbol"?t+"":t,n),vr=(e,t,n)=>t.has(e)||Pr("Cannot "+n);var f=(e,t,n)=>(vr(e,t,"read from private field"),n?n.call(e):t.get(e)),O=(e,t,n)=>t.has(e)?Pr("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),N=(e,t,n,r)=>(vr(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),H=(e,t,n)=>(vr(e,t,"access private method"),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const a of s)if(a.type==="childList")for(const o of a.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&r(o)}).observe(document,{childList:!0,subtree:!0});function n(s){const a={};return s.integrity&&(a.integrity=s.integrity),s.referrerPolicy&&(a.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?a.credentials="include":s.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(s){if(s.ep)return;s.ep=!0;const a=n(s);fetch(s.href,a)}})();const rs=!1;var ss=Array.isArray,na=Array.prototype.indexOf,Yn=Array.prototype.includes,nr=Array.from,ra=Object.defineProperty,Tn=Object.getOwnPropertyDescriptor,sa=Object.prototype,aa=Array.prototype,ia=Object.getPrototypeOf,Lr=Object.isExtensible;const la=()=>{};function oa(e){for(var t=0;t<e.length;t++)e[t]()}function as(){var e,t,n=new Promise((r,s)=>{e=r,t=s});return{promise:n,resolve:e,reject:t}}const de=2,Cn=4,rr=8,is=1<<24,Qe=16,Ue=32,vt=64,gr=128,We=512,ce=1024,ue=2048,$e=4096,ke=8192,Be=16384,cn=32768,Wr=1<<25,on=65536,Kn=1<<17,ua=1<<18,dn=1<<19,fa=1<<20,st=1<<25,Wt=65536,Jn=1<<21,$t=1<<22,yt=1<<23,cr=Symbol("$state"),va=Symbol("attributes"),yr=Symbol("class"),ca=Symbol("style"),kn=Symbol("text"),Fn=new class extends Error{constructor(){super(...arguments);Ce(this,"name","StaleReactionError");Ce(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};function da(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function ha(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function _a(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function pa(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function ma(e){throw new Error("https://svelte.dev/e/effect_orphan")}function ga(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function ya(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function ka(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function wa(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function ba(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const Ea=1,xa=2,ls=4,Ta=8,Sa=16,Aa=1,Ca=2,ve=Symbol("uninitialized"),qa="http://www.w3.org/1999/xhtml",ja="http://www.w3.org/2000/svg",Ra="http://www.w3.org/1998/Math/MathML";function Na(){console.warn("https://svelte.dev/e/derived_inert")}function Ma(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function os(e){return e===this.v}function Da(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function us(e){return!Da(e,this.v)}let Oa=!1,xe=null;function un(e){xe=e}function ct(e,t=!1,n){xe={p:xe,i:!1,c:null,e:null,s:e,x:null,r:W,l:null}}function dt(e){var t=xe,n=t.e;if(n!==null){t.e=null;for(var r of n)qs(r)}return t.i=!0,xe=t.p,{}}function fs(){return!0}let Jt=[];function Fa(){var e=Jt;Jt=[],oa(e)}function It(e){if(Jt.length===0){var t=Jt;queueMicrotask(()=>{t===Jt&&Fa()})}Jt.push(e)}function vs(e){var t=W;if(t===null)return L.f|=yt,e;if((t.f&cn)===0&&(t.f&Cn)===0)throw e;mt(e,t)}function mt(e,t){if(!(t!==null&&(t.f&Be)!==0)){for(;t!==null;){if((t.f&gr)!==0){if((t.f&cn)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}}const Ia=-7169;function se(e,t){e.f=e.f&Ia|t}function jr(e){(e.f&We)!==0||e.deps===null?se(e,ce):se(e,$e)}function cs(e){if(e!==null)for(const t of e)(t.f&de)===0||(t.f&Wt)===0||(t.f^=Wt,cs(t.deps))}function ds(e,t,n){(e.f&ue)!==0?t.add(e):(e.f&$e)!==0&&n.add(e),cs(e.deps),se(e,ce)}function sr(e){var t=L,n=W;Ve(null),it(null);try{return e()}finally{Ve(t),it(n)}}function za(e){let t=0,n=Ht(0),r;return()=>{Or()&&(l(n),ui(()=>(t===0&&(r=di(()=>e(()=>An(n)))),t+=1,()=>{It(()=>{t-=1,t===0&&(r==null||r(),r=void 0,An(n))})})))}}var Pa=on|dn;function La(e,t,n,r){new Wa(e,t,n,r)}var Oe,qr,Fe,Nt,we,Ie,ge,je,lt,Mt,_t,en,Rn,Nn,ot,$n,ae,Ba,Ha,Ua,kr,Hn,Un,wr,br;class Wa{constructor(t,n,r,s){O(this,ae);Ce(this,"parent");Ce(this,"is_pending",!1);Ce(this,"transform_error");O(this,Oe);O(this,qr,null);O(this,Fe);O(this,Nt);O(this,we);O(this,Ie,null);O(this,ge,null);O(this,je,null);O(this,lt,null);O(this,Mt,0);O(this,_t,0);O(this,en,!1);O(this,Rn,new Set);O(this,Nn,new Set);O(this,ot,null);O(this,$n,za(()=>(N(this,ot,Ht(f(this,Mt))),()=>{N(this,ot,null)})));var a;N(this,Oe,t),N(this,Fe,n),N(this,Nt,o=>{var v=W;v.b=this,v.f|=gr,r(o)}),this.parent=W.b,this.transform_error=s??((a=this.parent)==null?void 0:a.transform_error)??(o=>o),N(this,we,Fr(()=>{H(this,ae,kr).call(this)},Pa))}defer_effect(t){ds(t,f(this,Rn),f(this,Nn))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!f(this,Fe).pending}update_pending_count(t,n){H(this,ae,wr).call(this,t,n),N(this,Mt,f(this,Mt)+t),!(!f(this,ot)||f(this,en))&&(N(this,en,!0),It(()=>{N(this,en,!1),f(this,ot)&&fn(f(this,ot),f(this,Mt))}))}get_effect_pending(){return f(this,$n).call(this),l(f(this,ot))}error(t){if(!f(this,Fe).onerror&&!f(this,Fe).failed)throw t;M!=null&&M.is_fork?(f(this,Ie)&&M.skip_effect(f(this,Ie)),f(this,ge)&&M.skip_effect(f(this,ge)),f(this,je)&&M.skip_effect(f(this,je)),M.oncommit(()=>{H(this,ae,br).call(this,t)})):H(this,ae,br).call(this,t)}}Oe=new WeakMap,qr=new WeakMap,Fe=new WeakMap,Nt=new WeakMap,we=new WeakMap,Ie=new WeakMap,ge=new WeakMap,je=new WeakMap,lt=new WeakMap,Mt=new WeakMap,_t=new WeakMap,en=new WeakMap,Rn=new WeakMap,Nn=new WeakMap,ot=new WeakMap,$n=new WeakMap,ae=new WeakSet,Ba=function(){try{N(this,Ie,ze(()=>f(this,Nt).call(this,f(this,Oe))))}catch(t){this.error(t)}},Ha=function(t){const n=f(this,Fe).failed;n&&N(this,je,ze(()=>{n(f(this,Oe),()=>t,()=>()=>{})}))},Ua=function(){const t=f(this,Fe).pending;t&&(this.is_pending=!0,N(this,ge,ze(()=>t(f(this,Oe)))),It(()=>{var n=N(this,lt,document.createDocumentFragment()),r=kt();n.append(r),N(this,Ie,H(this,ae,Un).call(this,()=>ze(()=>f(this,Nt).call(this,r)))),f(this,_t)===0&&(f(this,Oe).before(n),N(this,lt,null),Pt(f(this,ge),()=>{N(this,ge,null)}),H(this,ae,Hn).call(this,M))}))},kr=function(){try{if(this.is_pending=this.has_pending_snippet(),N(this,_t,0),N(this,Mt,0),N(this,Ie,ze(()=>{f(this,Nt).call(this,f(this,Oe))})),f(this,_t)>0){var t=N(this,lt,document.createDocumentFragment());zr(f(this,Ie),t);const n=f(this,Fe).pending;N(this,ge,ze(()=>n(f(this,Oe))))}else H(this,ae,Hn).call(this,M)}catch(n){this.error(n)}},Hn=function(t){this.is_pending=!1,t.transfer_effects(f(this,Rn),f(this,Nn))},Un=function(t){var n=W,r=L,s=xe;it(f(this,we)),Ve(f(this,we)),un(f(this,we).ctx);try{return Bt.ensure(),t()}catch(a){return vs(a),null}finally{it(n),Ve(r),un(s)}},wr=function(t,n){var r;if(!this.has_pending_snippet()){this.parent&&H(r=this.parent,ae,wr).call(r,t,n);return}N(this,_t,f(this,_t)+t),f(this,_t)===0&&(H(this,ae,Hn).call(this,n),f(this,ge)&&Pt(f(this,ge),()=>{N(this,ge,null)}),f(this,lt)&&(f(this,Oe).before(f(this,lt)),N(this,lt,null)))},br=function(t){f(this,Ie)&&(Te(f(this,Ie)),N(this,Ie,null)),f(this,ge)&&(Te(f(this,ge)),N(this,ge,null)),f(this,je)&&(Te(f(this,je)),N(this,je,null));var n=f(this,Fe).onerror;let r=f(this,Fe).failed;var s=!1,a=!1;const o=()=>{if(s){Ma();return}s=!0,a&&ba(),f(this,je)!==null&&Pt(f(this,je),()=>{N(this,je,null)}),H(this,ae,Un).call(this,()=>{H(this,ae,kr).call(this)})},v=u=>{try{a=!0,n==null||n(u,o),a=!1}catch(i){mt(i,f(this,we)&&f(this,we).parent)}r&&N(this,je,H(this,ae,Un).call(this,()=>{try{return ze(()=>{var i=W;i.b=this,i.f|=gr,r(f(this,Oe),()=>u,()=>o)})}catch(i){return mt(i,f(this,we).parent),null}}))};It(()=>{var u;try{u=this.transform_error(t)}catch(i){mt(i,f(this,we)&&f(this,we).parent);return}u!==null&&typeof u=="object"&&typeof u.then=="function"?u.then(v,i=>mt(i,f(this,we)&&f(this,we).parent)):v(u)})};function Va(e,t,n,r){const s=Rr;var a=e.filter(p=>!p.settled),o=t.map(s);if(n.length===0&&a.length===0){r(o);return}var v=W,u=Ga(),i=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(p=>p.promise)):null;function h(p){if((v.f&Be)===0){u();try{r([...o,...p])}catch(y){mt(y,v)}Zn()}}var m=hs();if(n.length===0){i.then(()=>h([])).finally(m);return}function c(){Promise.all(n.map(p=>Ya(p))).then(h).catch(p=>mt(p,v)).finally(m)}i?i.then(()=>{u(),c(),Zn()}):c()}function Ga(){var e=W,t=L,n=xe,r=M;return function(a=!0){it(e),Ve(t),un(n),a&&(e.f&Be)===0&&(r==null||r.activate(),r==null||r.apply())}}function Zn(e=!0){it(null),Ve(null),un(null),e&&(M==null||M.deactivate())}function hs(){var e=W,t=e.b,n=M,r=!!(t!=null&&t.is_rendered());return t==null||t.update_pending_count(1,n),n.increment(r,e),()=>{t==null||t.update_pending_count(-1,n),n.decrement(r,e)}}function Rr(e){var t=de|ue;return W!==null&&(W.f|=dn),{ctx:xe,deps:null,effects:null,equals:os,f:t,fn:e,reactions:null,rv:0,v:ve,wv:0,parent:W,ac:null}}const wn=Symbol("obsolete");function Ya(e,t,n){let r=W;r===null&&da();var s=void 0,a=Ht(ve),o=!L,v=new Set;return oi(()=>{var p,y;var u=W,i=as();s=i.promise;try{Promise.resolve(e()).then(i.resolve,k=>{k!==Fn&&i.reject(k)}).finally(Zn)}catch(k){i.reject(k),Zn()}var h=M;if(o){if((u.f&cn)!==0)var m=hs();if((p=r.b)!=null&&p.is_rendered())(y=h.async_deriveds.get(u))==null||y.reject(wn);else for(const k of v.values())k.reject(wn);v.add(i),h.async_deriveds.set(u,i)}const c=(k,g=void 0)=>{m==null||m(),v.delete(i),g!==wn&&(h.activate(),g?(a.f|=yt,fn(a,g)):((a.f&yt)!==0&&(a.f^=yt),fn(a,k)),h.deactivate())};i.promise.then(c,k=>c(null,k||"unknown"))}),ii(()=>{for(const u of v)u.reject(wn)}),new Promise(u=>{function i(h){function m(){h===s?u(a):i(s)}h.then(m,m)}i(s)})}function Le(e){const t=Rr(e);return Os(t),t}function Ka(e){const t=Rr(e);return t.equals=us,t}function Ja(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)Te(t[n])}}function Nr(e){var t,n=W,r=e.parent;if(!bt&&r!==null&&e.v!==ve&&(r.f&(Be|ke))!==0)return Na(),e.v;it(r);try{e.f&=~Wt,Ja(e),t=Ps(e)}finally{it(n)}return t}function _s(e){var t=Nr(e);if(!e.equals(t)&&(e.wv=Is(),(!(M!=null&&M.is_fork)||e.deps===null)&&(M!==null?(M.capture(e,t,!0),Sn==null||Sn.capture(e,t,!0)):e.v=t,e.deps===null))){se(e,ce);return}bt||(_e!==null?(Or()||M!=null&&M.is_fork)&&_e.set(e,t):jr(e))}function Za(e){var t;if(e.effects!==null)for(const n of e.effects)(n.teardown||n.ac)&&((t=n.teardown)==null||t.call(n),n.ac!==null&&sr(()=>{n.ac.abort(Fn),n.ac=null}),n.fn!==null&&(n.teardown=la),qn(n,0),Ir(n))}function ps(e){if(e.effects!==null)for(const t of e.effects)t.teardown&&t.fn!==null&&vn(t)}let dr=null,Yt=null,M=null,Sn=null,_e=null,Er=null,hr=!1,Zt=null,Vn=null;var Br=0;let Qa=1;var tn,pt,Dt,nn,rn,sn,ut,an,be,Mn,ft,Je,nt,ln,Ot,Z,xr,bn,Tr,ms,gs,Kt,Xa,En;const er=class er{constructor(){O(this,Z);Ce(this,"id",Qa++);O(this,tn,!1);Ce(this,"linked",!0);O(this,pt,null);O(this,Dt,null);Ce(this,"async_deriveds",new Map);Ce(this,"current",new Map);Ce(this,"previous",new Map);O(this,nn,new Set);O(this,rn,new Set);O(this,sn,0);O(this,ut,new Map);O(this,an,null);O(this,be,[]);O(this,Mn,[]);O(this,ft,new Set);O(this,Je,new Set);O(this,nt,new Map);O(this,ln,new Set);Ce(this,"is_fork",!1);O(this,Ot,!1);Yt===null?dr=Yt=this:(N(Yt,Dt,this),N(this,pt,Yt)),Yt=this}skip_effect(t){f(this,nt).has(t)||f(this,nt).set(t,{d:[],m:[]}),f(this,ln).delete(t)}unskip_effect(t,n=r=>this.schedule(r)){var r=f(this,nt).get(t);if(r){f(this,nt).delete(t);for(var s of r.d)se(s,ue),n(s);for(s of r.m)se(s,$e),n(s)}f(this,ln).add(t)}capture(t,n,r=!1){t.v!==ve&&!this.previous.has(t)&&this.previous.set(t,t.v),(t.f&yt)===0&&(this.current.set(t,[n,r]),_e==null||_e.set(t,n)),this.is_fork||(t.v=n)}activate(){M=this}deactivate(){M=null,_e=null}flush(){try{hr=!0,M=this,H(this,Z,bn).call(this)}finally{Br=0,Er=null,Zt=null,Vn=null,hr=!1,M=null,_e=null,zt.clear()}}discard(){var t;for(const n of f(this,rn))n(this);f(this,rn).clear();for(const n of this.async_deriveds.values())n.reject(wn);H(this,Z,En).call(this),(t=f(this,an))==null||t.resolve()}register_created_effect(t){f(this,Mn).push(t)}increment(t,n){if(N(this,sn,f(this,sn)+1),t){let r=f(this,ut).get(n)??0;f(this,ut).set(n,r+1)}}decrement(t,n){if(N(this,sn,f(this,sn)-1),t){let r=f(this,ut).get(n)??0;r===1?f(this,ut).delete(n):f(this,ut).set(n,r-1)}f(this,Ot)||(N(this,Ot,!0),It(()=>{N(this,Ot,!1),this.linked&&this.flush()}))}transfer_effects(t,n){for(const r of t)f(this,ft).add(r);for(const r of n)f(this,Je).add(r);t.clear(),n.clear()}oncommit(t){f(this,nn).add(t)}ondiscard(t){f(this,rn).add(t)}settled(){return(f(this,an)??N(this,an,as())).promise}static ensure(){if(M===null){const t=M=new er;hr||It(()=>{f(t,tn)||t.flush()})}return M}apply(){{_e=null;return}}schedule(t){var s;if(Er=t,(s=t.b)!=null&&s.is_pending&&(t.f&(Cn|rr|is))!==0&&(t.f&cn)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var r=n.f;if(Zt!==null&&n===W&&(L===null||(L.f&de)===0))return;if((r&(vt|Ue))!==0){if((r&ce)===0)return;n.f^=ce}}f(this,be).push(n)}};tn=new WeakMap,pt=new WeakMap,Dt=new WeakMap,nn=new WeakMap,rn=new WeakMap,sn=new WeakMap,ut=new WeakMap,an=new WeakMap,be=new WeakMap,Mn=new WeakMap,ft=new WeakMap,Je=new WeakMap,nt=new WeakMap,ln=new WeakMap,Ot=new WeakMap,Z=new WeakSet,xr=function(){if(this.is_fork)return!0;for(const r of f(this,ut).keys()){for(var t=r,n=!1;t.parent!==null;){if(f(this,nt).has(t)){n=!0;break}t=t.parent}if(!n)return!0}return!1},bn=function(){var u,i,h,m;N(this,tn,!0),Br++>1e3&&(H(this,Z,En).call(this),$a());for(const c of f(this,ft))f(this,Je).delete(c),se(c,ue),this.schedule(c);for(const c of f(this,Je))se(c,$e),this.schedule(c);const t=f(this,be);N(this,be,[]),this.apply();var n=Zt=[],r=[],s=Vn=[];for(const c of t)try{H(this,Z,Tr).call(this,c,n,r)}catch(p){throw ws(c),H(this,Z,xr).call(this)||this.discard(),p}if(M=null,s.length>0){var a=er.ensure();for(const c of s)a.schedule(c)}if(Zt=null,Vn=null,H(this,Z,xr).call(this)){H(this,Z,Kt).call(this,r),H(this,Z,Kt).call(this,n);for(const[c,p]of f(this,nt))ks(c,p);s.length>0&&H(u=M,Z,bn).call(u);return}const o=H(this,Z,ms).call(this);if(o){H(this,Z,Kt).call(this,r),H(this,Z,Kt).call(this,n),H(i=o,Z,gs).call(i,this);return}f(this,ft).clear(),f(this,Je).clear();for(const c of f(this,nn))c(this);f(this,nn).clear(),Sn=this,Hr(r),Hr(n),Sn=null,(h=f(this,an))==null||h.resolve();var v=M;if(f(this,sn)===0&&(f(this,be).length===0||v!==null)&&H(this,Z,En).call(this),f(this,be).length>0)if(v!==null){const c=v;f(c,be).push(...f(this,be).filter(p=>!f(c,be).includes(p)))}else v=this;v!==null&&H(m=v,Z,bn).call(m)},Tr=function(t,n,r){t.f^=ce;for(var s=t.first;s!==null;){var a=s.f,o=(a&(Ue|vt))!==0,v=o&&(a&ce)!==0,u=v||(a&ke)!==0||f(this,nt).has(s);if(!u&&s.fn!==null){o?s.f^=ce:(a&Cn)!==0?n.push(s):zn(s)&&((a&Qe)!==0&&f(this,Je).add(s),vn(s));var i=s.first;if(i!==null){s=i;continue}}for(;s!==null;){var h=s.next;if(h!==null){s=h;break}s=s.parent}}},ms=function(){for(var t=f(this,pt);t!==null;){if(!t.is_fork){for(const[n,[,r]]of this.current)if(t.current.has(n)&&!r)return t}t=f(t,pt)}return null},gs=function(t){var r;for(const[s,a]of t.current)!this.previous.has(s)&&t.previous.has(s)&&this.previous.set(s,t.previous.get(s)),this.current.set(s,a);for(const[s,a]of t.async_deriveds){const o=this.async_deriveds.get(s);o&&a.promise.then(o.resolve).catch(o.reject)}t.async_deriveds.clear(),this.transfer_effects(f(t,ft),f(t,Je));const n=s=>{var a=s.reactions;if(a!==null&&!((s.f&de)!==0&&(s.f&(ue|$e))===0))for(const u of a){var o=u.f;if((o&de)!==0)n(u);else{var v=u;o&($t|Qe)&&!this.async_deriveds.has(v)&&(f(this,Je).delete(v),se(v,ue),this.schedule(v))}}};for(const s of this.current.keys())n(s);this.oncommit(()=>t.discard()),H(r=t,Z,En).call(r),M=this,H(this,Z,bn).call(this)},Kt=function(t){for(var n=0;n<t.length;n+=1)ds(t[n],f(this,ft),f(this,Je))},Xa=function(){var m;for(let c=dr;c!==null;c=f(c,Dt)){var t=c.id<this.id,n=[];for(const[p,[y,k]]of this.current){if(c.current.has(p)){var r=c.current.get(p)[0];if(t&&y!==r)c.current.set(p,[y,k]);else continue}n.push(p)}if(t)for(const[p,y]of this.async_deriveds){const k=c.async_deriveds.get(p);k&&y.promise.then(k.resolve).catch(k.reject)}var s=[...c.current.keys()].filter(p=>!c.current.get(p)[1]);if(!(!f(c,tn)||s.length===0)){var a=s.filter(p=>!this.current.has(p));if(a.length===0)t&&c.discard();else if(n.length>0){if(t)for(const p of f(this,ln))c.unskip_effect(p,y=>{var k;(y.f&(Qe|$t))!==0?c.schedule(y):H(k=c,Z,Kt).call(k,[y])});c.activate();var o=new Set,v=new Map;for(var u of n)ys(u,a,o,v);v=new Map;var i=[...c.current].filter(([p,y])=>{const k=this.current.get(p);return k?k[0]!==y[0]||k[1]!==y[1]:!0}).map(([p])=>p);if(i.length>0)for(const p of f(this,Mn))(p.f&(Be|ke|Kn))===0&&Mr(p,i,v)&&((p.f&($t|Qe))!==0?(se(p,ue),c.schedule(p)):f(c,ft).add(p));if(f(c,be).length>0&&!f(c,Ot)){c.apply();for(var h of f(c,be))H(m=c,Z,Tr).call(m,h,[],[]);N(c,be,[])}c.deactivate()}}}},En=function(){if(this.linked){var t=f(this,pt),n=f(this,Dt);t===null?dr=n:N(t,Dt,n),n===null?Yt=t:N(n,pt,t),this.linked=!1}};let Bt=er;function $a(){try{ga()}catch(e){mt(e,Er)}}let Ke=null;function Hr(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if((r.f&(Be|ke))===0&&zn(r)&&(Ke=new Set,vn(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&Ns(r),(Ke==null?void 0:Ke.size)>0)){zt.clear();for(const s of Ke){if((s.f&(Be|ke))!==0)continue;const a=[s];let o=s.parent;for(;o!==null;)Ke.has(o)&&(Ke.delete(o),a.push(o)),o=o.parent;for(let v=a.length-1;v>=0;v--){const u=a[v];(u.f&(Be|ke))===0&&vn(u)}}Ke.clear()}}Ke=null}}function ys(e,t,n,r){if(!n.has(e)&&(n.add(e),e.reactions!==null))for(const s of e.reactions){const a=s.f;(a&de)!==0?ys(s,t,n,r):(a&($t|Qe))!==0&&(a&ue)===0&&Mr(s,t,r)&&(se(s,ue),Dr(s))}}function Mr(e,t,n){const r=n.get(e);if(r!==void 0)return r;if(e.deps!==null)for(const s of e.deps){if(Yn.call(t,s))return!0;if((s.f&de)!==0&&Mr(s,t,n))return n.set(s,!0),!0}return n.set(e,!1),!1}function Dr(e){M.schedule(e)}function ks(e,t){if(!((e.f&Ue)!==0&&(e.f&ce)!==0)){(e.f&ue)!==0?t.d.push(e):(e.f&$e)!==0&&t.m.push(e),se(e,ce);for(var n=e.first;n!==null;)ks(n,t),n=n.next}}function ws(e){se(e,ce);for(var t=e.first;t!==null;)ws(t),t=t.next}let Qn=new Set;const zt=new Map;let bs=!1;function Ht(e,t){var n={f:0,v:e,reactions:null,equals:os,rv:0,wv:0};return n}function oe(e,t){const n=Ht(e);return Os(n),n}function ei(e,t=!1,n=!0){const r=Ht(e);return t||(r.equals=us),r}function z(e,t,n=!1){L!==null&&(!Xe||(L.f&Kn)!==0)&&fs()&&(L.f&(de|Qe|$t|Kn))!==0&&(at===null||!at.has(e))&&wa();let r=n?qt(t):t;return fn(e,r,Vn)}function fn(e,t,n=null){if(!e.equals(t)){zt.set(e,bt?t:e.v);var r=Bt.ensure();if(r.capture(e,t),(e.f&de)!==0){const s=e;(e.f&ue)!==0&&Nr(s),_e===null&&jr(s)}e.wv=Is(),Es(e,ue,n),W!==null&&(W.f&ce)!==0&&(W.f&(Ue|vt))===0&&(De===null?vi([e]):De.push(e)),!r.is_fork&&Qn.size>0&&!bs&&ti()}return t}function ti(){bs=!1;for(const e of Qn){(e.f&ce)!==0&&se(e,$e);let t;try{t=zn(e)}catch{t=!0}t&&vn(e)}Qn.clear()}function An(e){z(e,e.v+1)}function Es(e,t,n){var r=e.reactions;if(r!==null)for(var s=r.length,a=0;a<s;a++){var o=r[a],v=o.f,u=(v&ue)===0;if(u&&se(o,t),(v&Kn)!==0)Qn.add(o);else if((v&de)!==0){var i=o;_e==null||_e.delete(i),(v&Wt)===0&&(v&We&&(W===null||(W.f&Jn)===0)&&(o.f|=Wt),Es(i,$e,n))}else if(u){var h=o;(v&Qe)!==0&&Ke!==null&&Ke.add(h),n!==null?n.push(h):Dr(h)}}}function qt(e){if(typeof e!="object"||e===null||cr in e)return e;const t=ia(e);if(t!==sa&&t!==aa)return e;var n=new Map,r=ss(e),s=oe(0),a=Lt,o=v=>{if(Lt===a)return v();var u=L,i=Lt;Ve(null),Gr(a);var h=v();return Ve(u),Gr(i),h};return r&&n.set("length",oe(e.length)),new Proxy(e,{defineProperty(v,u,i){(!("value"in i)||i.configurable===!1||i.enumerable===!1||i.writable===!1)&&ya();var h=n.get(u);return h===void 0?o(()=>{var m=oe(i.value);return n.set(u,m),m}):z(h,i.value,!0),!0},deleteProperty(v,u){var i=n.get(u);if(i===void 0){if(u in v){const h=o(()=>oe(ve));n.set(u,h),An(s)}}else z(i,ve),An(s);return!0},get(v,u,i){var p;if(u===cr)return e;var h=n.get(u),m=u in v;if(h===void 0&&(!m||(p=Tn(v,u))!=null&&p.writable)&&(h=o(()=>{var y=qt(m?v[u]:ve),k=oe(y);return k}),n.set(u,h)),h!==void 0){var c=l(h);return c===ve?void 0:c}return Reflect.get(v,u,i)},getOwnPropertyDescriptor(v,u){var i=Reflect.getOwnPropertyDescriptor(v,u);if(i&&"value"in i){var h=n.get(u);h&&(i.value=l(h))}else if(i===void 0){var m=n.get(u),c=m==null?void 0:m.v;if(m!==void 0&&c!==ve)return{enumerable:!0,configurable:!0,value:c,writable:!0}}return i},has(v,u){var c;if(u===cr)return!0;var i=n.get(u),h=i!==void 0&&i.v!==ve||Reflect.has(v,u);if(i!==void 0||W!==null&&(!h||(c=Tn(v,u))!=null&&c.writable)){i===void 0&&(i=o(()=>{var p=h?qt(v[u]):ve,y=oe(p);return y}),n.set(u,i));var m=l(i);if(m===ve)return!1}return h},set(v,u,i,h){var D;var m=n.get(u),c=u in v;if(r&&u==="length")for(var p=i;p<m.v;p+=1){var y=n.get(p+"");y!==void 0?z(y,ve):p in v&&(y=o(()=>oe(ve)),n.set(p+"",y))}if(m===void 0)(!c||(D=Tn(v,u))!=null&&D.writable)&&(m=o(()=>oe(void 0)),z(m,qt(i)),n.set(u,m));else{c=m.v!==ve;var k=o(()=>qt(i));z(m,k)}var g=Reflect.getOwnPropertyDescriptor(v,u);if(g!=null&&g.set&&g.set.call(h,i),!c){if(r&&typeof u=="string"){var x=n.get("length"),I=Number(u);Number.isInteger(I)&&I>=x.v&&z(x,I+1)}An(s)}return!0},ownKeys(v){l(s);var u=Reflect.ownKeys(v).filter(m=>{var c=n.get(m);return c===void 0||c.v!==ve});for(var[i,h]of n)h.v!==ve&&!(i in v)&&u.push(i);return u},setPrototypeOf(){ka()}})}var Ur,xs,Ts,Ss;function ni(){if(Ur===void 0){Ur=window,xs=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Ts=Tn(t,"firstChild").get,Ss=Tn(t,"nextSibling").get,Lr(e)&&(e[yr]=void 0,e[va]=null,e[ca]=void 0,e.__e=void 0),Lr(n)&&(n[kn]=void 0)}}function kt(e=""){return document.createTextNode(e)}function gt(e){return Ts.call(e)}function In(e){return Ss.call(e)}function d(e,t){return gt(e)}function ye(e,t=!1){{var n=gt(e);return n instanceof Comment&&n.data===""?In(n):n}}function _(e,t=1,n=!1){let r=e;for(;t--;)r=In(r);return r}function ri(e){e.textContent=""}function As(){return!1}function Cs(e,t,n){return t==null||t===qa?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function si(e){W===null&&(L===null&&ma(),pa()),bt&&_a()}function ai(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Et(e,t){var n=W;n!==null&&(n.f&ke)!==0&&(e|=ke);var r={ctx:xe,deps:null,nodes:null,f:e|ue|We,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};M==null||M.register_created_effect(r);var s=r;if((e&Cn)!==0)Zt!==null?Zt.push(r):Bt.ensure().schedule(r);else if(t!==null){try{vn(r)}catch(o){throw Te(r),o}s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&dn)===0&&(s=s.first,(e&Qe)!==0&&(e&on)!==0&&s!==null&&(s.f|=on))}if(s!==null&&(s.parent=n,n!==null&&ai(s,n),L!==null&&(L.f&de)!==0&&(e&vt)===0)){var a=L;(a.effects??(a.effects=[])).push(s)}return r}function Or(){return L!==null&&!Xe}function ii(e){const t=Et(rr,null);return se(t,ce),t.teardown=e,t}function _r(e){si();var t=W.f,n=!L&&(t&Ue)!==0&&xe!==null&&!xe.i;if(n){var r=xe;(r.e??(r.e=[])).push(e)}else return qs(e)}function qs(e){return Et(Cn|fa,e)}function li(e){Bt.ensure();const t=Et(vt|dn,e);return(n={})=>new Promise(r=>{n.outro?Pt(t,()=>{Te(t),r(void 0)}):(Te(t),r(void 0))})}function oi(e){return Et($t|dn,e)}function ui(e,t=0){return Et(rr|t,e)}function V(e,t=[],n=[],r=[]){Va(r,t,n,s=>{Et(rr,()=>{e(...s.map(l))})})}function Fr(e,t=0){var n=Et(Qe|t,e);return n}function ze(e){return Et(Ue|dn,e)}function js(e){var t=e.teardown;if(t!==null){const n=bt,r=L;Vr(!0),Ve(null);try{t.call(null)}finally{Vr(n),Ve(r)}}}function Ir(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const s=n.ac;s!==null&&sr(()=>{s.abort(Fn)});var r=n.next;(n.f&vt)!==0?n.parent=null:Te(n,t),n=r}}function fi(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&Ue)===0&&Te(t),t=n}}function Te(e,t=!0){var n=!1;(t||(e.f&ua)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(Rs(e.nodes.start,e.nodes.end),n=!0),e.f|=Wr,Ir(e,t&&!n),qn(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const a of r)a.stop();js(e),e.f^=Wr,e.f|=Be;var s=e.parent;s!==null&&s.first!==null&&Ns(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Rs(e,t){for(;e!==null;){var n=e===t?null:In(e);e.remove(),e=n}}function Ns(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function Pt(e,t,n=!0){var r=[];Ms(e,r,!0);var s=()=>{n&&Te(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||s();for(var v of r)v.out(o)}else s()}function Ms(e,t,n){if((e.f&ke)===0){e.f^=ke;var r=e.nodes&&e.nodes.t;if(r!==null)for(const v of r)(v.is_global||n)&&t.push(v);for(var s=e.first;s!==null;){var a=s.next;if((s.f&vt)===0){var o=(s.f&on)!==0||(s.f&Ue)!==0&&(e.f&Qe)!==0;Ms(s,t,o?n:!1)}s=a}}}function Xn(e){Ds(e,!0)}function Ds(e,t){if((e.f&ke)!==0){e.f^=ke,(e.f&ce)===0&&(se(e,ue),Bt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,s=(n.f&on)!==0||(n.f&Ue)!==0;Ds(n,s?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(const o of a)(o.is_global||t)&&o.in()}}function zr(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var s=n===r?null:In(n);t.append(n),n=s}}let Gn=!1,bt=!1;function Vr(e){bt=e}let L=null,Xe=!1;function Ve(e){L=e}let W=null;function it(e){W=e}let at=null;function Os(e){L!==null&&(at??(at=new Set)).add(e)}let Ee=null,qe=0,De=null;function vi(e){De=e}let Fs=1,jt=0,Lt=jt;function Gr(e){Lt=e}function Is(){return++Fs}function zn(e){var t=e.f;if((t&ue)!==0)return!0;if(t&de&&(e.f&=~Wt),(t&$e)!==0){for(var n=e.deps,r=n.length,s=0;s<r;s++){var a=n[s];if(zn(a)&&_s(a),a.wv>e.wv)return!0}(t&We)!==0&&_e===null&&se(e,ce)}return!1}function zs(e,t,n=!0){var r=e.reactions;if(r!==null&&!(at!==null&&at.has(e)))for(var s=0;s<r.length;s++){var a=r[s];(a.f&de)!==0?zs(a,t,!1):t===a&&(n?se(a,ue):(a.f&ce)!==0&&se(a,$e),Dr(a))}}function Ps(e){var k;var t=Ee,n=qe,r=De,s=L,a=at,o=xe,v=Xe,u=Lt,i=e.f;Ee=null,qe=0,De=null,L=(i&(Ue|vt))===0?e:null,at=null,un(e.ctx),Xe=!1,Lt=++jt,e.ac!==null&&(sr(()=>{e.ac.abort(Fn)}),e.ac=null);try{e.f|=Jn;var h=e.fn,m=h();e.f|=cn;var c=e.deps,p=M==null?void 0:M.is_fork;if(Ee!==null){var y;if(p||qn(e,qe),c!==null&&qe>0)for(c.length=qe+Ee.length,y=0;y<Ee.length;y++)c[qe+y]=Ee[y];else e.deps=c=Ee;if(Or()&&(e.f&We)!==0)for(y=qe;y<c.length;y++)((k=c[y]).reactions??(k.reactions=[])).push(e)}else!p&&c!==null&&qe<c.length&&(qn(e,qe),c.length=qe);if(fs()&&De!==null&&!Xe&&c!==null&&(e.f&(de|$e|ue))===0)for(y=0;y<De.length;y++)zs(De[y],e);if(s!==null&&s!==e){if(jt++,s.deps!==null)for(let g=0;g<n;g+=1)s.deps[g].rv=jt;if(t!==null)for(const g of t)g.rv=jt;De!==null&&(r===null?r=De:r.push(...De))}return(e.f&yt)!==0&&(e.f^=yt),m}catch(g){return vs(g)}finally{e.f^=Jn,Ee=t,qe=n,De=r,L=s,at=a,un(o),Xe=v,Lt=u}}function ci(e,t){let n=t.reactions;if(n!==null){var r=na.call(n,e);if(r!==-1){var s=n.length-1;s===0?n=t.reactions=null:(n[r]=n[s],n.pop())}}if(n===null&&(t.f&de)!==0&&(Ee===null||!Yn.call(Ee,t))){var a=t;(a.f&We)!==0&&(a.f^=We,a.f&=~Wt),a.v!==ve&&jr(a),a.ac!==null&&sr(()=>{a.ac.abort(Fn),a.ac=null,se(a,ue)}),Za(a),qn(a,0)}}function qn(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)ci(e,n[r])}function vn(e){var t=e.f;if((t&Be)===0){se(e,ce);var n=W,r=Gn;W=e,Gn=(t&(Ue|vt))===0;try{(t&(Qe|is))!==0?fi(e):Ir(e),js(e);var s=Ps(e);e.teardown=typeof s=="function"?s:null,e.wv=Fs;var a;rs&&Oa&&(e.f&ue)!==0&&e.deps}finally{Gn=r,W=n}}}function l(e){var t=e.f,n=(t&de)!==0;if(L!==null&&!Xe){var r=W!==null&&(W.f&Be)!==0;if(!r&&(at===null||!at.has(e))){var s=L.deps;if((L.f&Jn)!==0)e.rv<jt&&(e.rv=jt,Ee===null&&s!==null&&s[qe]===e?qe++:Ee===null?Ee=[e]:Ee.push(e));else{L.deps??(L.deps=[]),Yn.call(L.deps,e)||L.deps.push(e);var a=e.reactions;a===null?e.reactions=[L]:Yn.call(a,L)||a.push(L)}}}if(bt&&zt.has(e))return zt.get(e);if(n){var o=e;if(bt){var v=o.v;return((o.f&ce)===0&&o.reactions!==null||Ws(o))&&(v=Nr(o)),zt.set(o,v),v}var u=(o.f&We)===0&&!Xe&&L!==null&&(Gn||(L.f&We)!==0),i=(o.f&cn)===0;zn(o)&&(u&&(o.f|=We),_s(o)),u&&!i&&(ps(o),Ls(o))}if(_e!=null&&_e.has(e))return _e.get(e);if((e.f&yt)!==0)throw e.v;return e.v}function Ls(e){if(e.f|=We,e.deps!==null)for(const t of e.deps)(t.reactions??(t.reactions=[])).push(e),(t.f&de)!==0&&(t.f&We)===0&&(ps(t),Ls(t))}function Ws(e){if(e.v===ve)return!0;if(e.deps===null)return!1;for(const t of e.deps)if(zt.has(t)||(t.f&de)!==0&&Ws(t))return!0;return!1}function di(e){var t=Xe;try{return Xe=!0,e()}finally{Xe=t}}const hi=["touchstart","touchmove"];function _i(e){return hi.includes(e)}const Rt=Symbol("events"),Bs=new Set,Sr=new Set;function Pe(e,t,n){(t[Rt]??(t[Rt]={}))[e]=n}function Pn(e){for(var t=0;t<e.length;t++)Bs.add(e[t]);for(var n of Sr)n(e)}let Yr=null;function Kr(e){var k,g;var t=this,n=t.ownerDocument,r=e.type,s=((k=e.composedPath)==null?void 0:k.call(e))||[],a=s[0]||e.target;Yr=e;var o=0,v=Yr===e&&e[Rt];if(v){var u=s.indexOf(v);if(u!==-1&&(t===document||t===window)){e[Rt]=t;return}var i=s.indexOf(t);if(i===-1)return;u<=i&&(o=u)}if(a=s[o]||e.target,a!==t){ra(e,"currentTarget",{configurable:!0,get(){return a||n}});var h=L,m=W;Ve(null),it(null);try{for(var c,p=[];a!==null&&a!==t;){try{var y=(g=a[Rt])==null?void 0:g[r];y!=null&&(!a.disabled||e.target===a)&&y.call(a,e)}catch(x){c?p.push(x):c=x}if(e.cancelBubble)break;o++,a=o<s.length?s[o]:null}if(c){for(let x of p)queueMicrotask(()=>{throw x});throw c}}finally{e[Rt]=t,delete e.currentTarget,Ve(h),it(m)}}}var es;const pr=((es=globalThis==null?void 0:globalThis.window)==null?void 0:es.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function pi(e){return(pr==null?void 0:pr.createHTML(e))??e}function mi(e){var t=Cs("template");return t.innerHTML=pi(e.replaceAll("<!>","<!---->")),t.content}function jn(e,t){var n=W;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function T(e,t){var n=(t&Aa)!==0,r=(t&Ca)!==0,s,a=!e.startsWith("<!>");return()=>{s===void 0&&(s=mi(a?e:"<!>"+e),n||(s=gt(s)));var o=r||xs?document.importNode(s,!0):s.cloneNode(!0);if(n){var v=gt(o),u=o.lastChild;jn(v,u)}else jn(o,o);return o}}function Qt(){var e=document.createDocumentFragment(),t=document.createComment(""),n=kt();return e.append(t,n),jn(t,n),e}function E(e,t){e!==null&&e.before(t)}function b(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e[kn]??(e[kn]=e.nodeValue))&&(e[kn]=n,e.nodeValue=`${n}`)}function gi(e,t){return yi(e,t)}const Bn=new Map;function yi(e,{target:t,anchor:n,props:r={},events:s,context:a,intro:o=!0,transformError:v}){ni();var u=void 0,i=li(()=>{var h=n??t.appendChild(kt());La(h,{pending:()=>{}},p=>{ct({});var y=xe;a&&(y.c=a),s&&(r.$$events=s),u=e(p,r)||{},dt()},v);var m=new Set,c=p=>{for(var y=0;y<p.length;y++){var k=p[y];if(!m.has(k)){m.add(k);var g=_i(k);for(const D of[t,document]){var x=Bn.get(D);x===void 0&&(x=new Map,Bn.set(D,x));var I=x.get(k);I===void 0?(D.addEventListener(k,Kr,{passive:g}),x.set(k,1)):x.set(k,I+1)}}}};return c(nr(Bs)),Sr.add(c),()=>{var g;for(var p of m)for(const x of[t,document]){var y=Bn.get(x),k=y.get(p);--k==0?(x.removeEventListener(p,Kr),y.delete(p),y.size===0&&Bn.delete(x)):y.set(p,k)}Sr.delete(c),h!==n&&((g=h.parentNode)==null||g.removeChild(h))}});return ki.set(u,i),u}let ki=new WeakMap;var Ze,rt,Re,Ft,Dn,On,tr;class wi{constructor(t,n=!0){Ce(this,"anchor");O(this,Ze,new Map);O(this,rt,new Map);O(this,Re,new Map);O(this,Ft,new Set);O(this,Dn,!0);O(this,On,t=>{if(f(this,Ze).has(t)){var n=f(this,Ze).get(t),r=f(this,rt).get(n);if(r)Xn(r),f(this,Ft).delete(n);else{var s=f(this,Re).get(n);s&&(Xn(s.effect),f(this,rt).set(n,s.effect),f(this,Re).delete(n),s.fragment.lastChild.remove(),this.anchor.before(s.fragment),r=s.effect)}for(const[a,o]of f(this,Ze)){if(f(this,Ze).delete(a),a===t)break;const v=f(this,Re).get(o);v&&(Te(v.effect),f(this,Re).delete(o))}for(const[a,o]of f(this,rt)){if(a===n||f(this,Ft).has(a))continue;const v=()=>{if(Array.from(f(this,Ze).values()).includes(a)){var i=document.createDocumentFragment();zr(o,i),i.append(kt()),f(this,Re).set(a,{effect:o,fragment:i})}else Te(o);f(this,Ft).delete(a),f(this,rt).delete(a)};f(this,Dn)||!r?(f(this,Ft).add(a),Pt(o,v,!1)):v()}}});O(this,tr,t=>{f(this,Ze).delete(t);const n=Array.from(f(this,Ze).values());for(const[r,s]of f(this,Re))n.includes(r)||(Te(s.effect),f(this,Re).delete(r))});this.anchor=t,N(this,Dn,n)}ensure(t,n){var r=M,s=As();if(n&&!f(this,rt).has(t)&&!f(this,Re).has(t))if(s){var a=document.createDocumentFragment(),o=kt();a.append(o),f(this,Re).set(t,{effect:ze(()=>n(o)),fragment:a})}else f(this,rt).set(t,ze(()=>n(this.anchor)));if(f(this,Ze).set(r,t),s){for(const[v,u]of f(this,rt))v===t?r.unskip_effect(u):r.skip_effect(u);for(const[v,u]of f(this,Re))v===t?r.unskip_effect(u.effect):r.skip_effect(u.effect);r.oncommit(f(this,On)),r.ondiscard(f(this,tr))}else f(this,On).call(this,r)}}Ze=new WeakMap,rt=new WeakMap,Re=new WeakMap,Ft=new WeakMap,Dn=new WeakMap,On=new WeakMap,tr=new WeakMap;function J(e,t,n=!1){var r=new wi(e),s=n?on:0;function a(o,v){r.ensure(o,v)}Fr(()=>{var o=!1;t((v,u=0)=>{o=!0,a(u,v)}),o||a(-1,null)},s)}function ar(e,t){return t}function bi(e,t,n){for(var r=[],s=t.length,a,o=t.length,v=0;v<s;v++){let m=t[v];Pt(m,()=>{if(a){if(a.pending.delete(m),a.done.add(m),a.pending.size===0){var c=e.outrogroups;Ar(e,nr(a.done)),c.delete(a),c.size===0&&(e.outrogroups=null)}}else o-=1},!1)}if(o===0){var u=r.length===0&&n!==null;if(u){var i=n,h=i.parentNode;ri(h),h.append(i),e.items.clear()}Ar(e,t,!u)}else a={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(a)}function Ar(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(const o of e.pending.values())for(const v of o)r.add(e.items.get(v).e)}for(var s=0;s<t.length;s++){var a=t[s];if(r!=null&&r.has(a)){a.f|=st;const o=document.createDocumentFragment();zr(a,o)}else Te(t[s],n)}}var Jr;function He(e,t,n,r,s,a=null){var o=e,v=new Map,u=(t&ls)!==0;if(u){var i=e;o=i.appendChild(kt())}var h=null,m=Ka(()=>{var D=n();return ss(D)?D:D==null?[]:nr(D)}),c,p=new Map,y=!0;function k(D){(I.effect.f&Be)===0&&(I.pending.delete(D),I.fallback=h,Ei(I,c,o,t,r),h!==null&&(c.length===0?(h.f&st)===0?Xn(h):(h.f^=st,xn(h,null,o)):Pt(h,()=>{h=null})))}function g(D){I.pending.delete(D)}var x=Fr(()=>{c=l(m);for(var D=c.length,C=new Set,j=M,G=As(),Y=0;Y<D;Y+=1){var K=c[Y],X=r(K,Y),U=y?null:v.get(X);U?(U.v&&fn(U.v,K),U.i&&fn(U.i,Y),G&&j.unskip_effect(U.e)):(U=xi(v,y?o:Jr??(Jr=kt()),K,X,Y,s,t,n),y||(U.e.f|=st),v.set(X,U)),C.add(X)}if(D===0&&a&&!h&&(y?h=ze(()=>a(o)):(h=ze(()=>a(Jr??(Jr=kt()))),h.f|=st)),D>C.size&&ha(),!y)if(p.set(j,C),G){for(const[q,S]of v)C.has(q)||j.skip_effect(S.e);j.oncommit(k),j.ondiscard(g)}else k(j);l(m)}),I={effect:x,items:v,pending:p,outrogroups:null,fallback:h};y=!1}function gn(e){for(;e!==null&&(e.f&Ue)===0;)e=e.next;return e}function Ei(e,t,n,r,s){var U,q,S,ne,he,le,B,Q,te;var a=(r&Ta)!==0,o=t.length,v=e.items,u=gn(e.effect.first),i,h=null,m,c=[],p=[],y,k,g,x;if(a)for(x=0;x<o;x+=1)y=t[x],k=s(y,x),g=v.get(k).e,(g.f&st)===0&&((q=(U=g.nodes)==null?void 0:U.a)==null||q.measure(),(m??(m=new Set)).add(g));for(x=0;x<o;x+=1){if(y=t[x],k=s(y,x),g=v.get(k).e,e.outrogroups!==null)for(const $ of e.outrogroups)$.pending.delete(g),$.done.delete(g);if((g.f&ke)!==0&&(Xn(g),a&&((ne=(S=g.nodes)==null?void 0:S.a)==null||ne.unfix(),(m??(m=new Set)).delete(g))),(g.f&st)!==0)if(g.f^=st,g===u)xn(g,null,n);else{var I=h?h.next:u;g===e.effect.last&&(e.effect.last=g.prev),g.prev&&(g.prev.next=g.next),g.next&&(g.next.prev=g.prev),ht(e,h,g),ht(e,g,I),xn(g,I,n),h=g,c=[],p=[],u=gn(h.next);continue}if(g!==u){if(i!==void 0&&i.has(g)){if(c.length<p.length){var D=p[0],C;h=D.prev;var j=c[0],G=c[c.length-1];for(C=0;C<c.length;C+=1)xn(c[C],D,n);for(C=0;C<p.length;C+=1)i.delete(p[C]);ht(e,j.prev,G.next),ht(e,h,j),ht(e,G,D),u=D,h=G,x-=1,c=[],p=[]}else i.delete(g),xn(g,u,n),ht(e,g.prev,g.next),ht(e,g,h===null?e.effect.first:h.next),ht(e,h,g),h=g;continue}for(c=[],p=[];u!==null&&u!==g;)(i??(i=new Set)).add(u),p.push(u),u=gn(u.next);if(u===null)continue}(g.f&st)===0&&c.push(g),h=g,u=gn(g.next)}if(e.outrogroups!==null){for(const $ of e.outrogroups)$.pending.size===0&&(Ar(e,nr($.done)),(he=e.outrogroups)==null||he.delete($));e.outrogroups.size===0&&(e.outrogroups=null)}if(u!==null||i!==void 0){var Y=[];if(i!==void 0)for(g of i)(g.f&ke)===0&&Y.push(g);for(;u!==null;)(u.f&ke)===0&&u!==e.fallback&&Y.push(u),u=gn(u.next);var K=Y.length;if(K>0){var X=(r&ls)!==0&&o===0?n:null;if(a){for(x=0;x<K;x+=1)(B=(le=Y[x].nodes)==null?void 0:le.a)==null||B.measure();for(x=0;x<K;x+=1)(te=(Q=Y[x].nodes)==null?void 0:Q.a)==null||te.fix()}bi(e,Y,X)}}a&&It(()=>{var $,fe;if(m!==void 0)for(g of m)(fe=($=g.nodes)==null?void 0:$.a)==null||fe.apply()})}function xi(e,t,n,r,s,a,o,v){var u=(o&Ea)!==0?(o&Sa)===0?ei(n,!1,!1):Ht(n):null,i=(o&xa)!==0?Ht(s):null;return{v:u,i,e:ze(()=>(a(t,u??n,i??s,v),()=>{e.delete(r)}))}}function xn(e,t,n){if(e.nodes)for(var r=e.nodes.start,s=e.nodes.end,a=t&&(t.f&st)===0?t.nodes.start:n;r!==null;){var o=In(r);if(a.before(r),r===s)return;r=o}}function ht(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Hs(e,t,n=!1,r=!1,s=!1,a=!1){var o=e,v="";if(n)var u=e;V(()=>{var i=W;if(v!==(v=t()??"")){if(n){i.nodes=null,u.innerHTML=v,v!==""&&jn(gt(u),u.lastChild);return}if(i.nodes!==null&&(Rs(i.nodes.start,i.nodes.end),i.nodes=null),v!==""){var h=r?ja:s?Ra:void 0,m=Cs(r?"svg":s?"math":"template",h);m.innerHTML=v;var c=r||s?m:m.content;if(jn(gt(c),c.lastChild),r||s)for(;gt(c);)o.before(gt(c));else o.before(c)}}})}const Zr=[...`
2
+ \r\f \v\uFEFF`];function Ti(e,t,n){var r=e==null?"":""+e;if(t&&(r=r?r+" "+t:t),n){for(var s of Object.keys(n))if(n[s])r=r?r+" "+s:s;else if(r.length)for(var a=s.length,o=0;(o=r.indexOf(s,o))>=0;){var v=o+a;(o===0||Zr.includes(r[o-1]))&&(v===r.length||Zr.includes(r[v]))?r=(o===0?"":r.substring(0,o))+r.substring(v+1):o=v}}return r===""?null:r}function me(e,t,n,r,s,a){var o=e[yr];if(o!==n||o===void 0){var v=Ti(n,r,a);v==null?e.removeAttribute("class"):e.className=v,e[yr]=n}else if(a&&s!==a)for(var u in a){var i=!!a[u];(s==null||i!==!!s[u])&&e.classList.toggle(u,i)}return a}function Qr(e,t){t?e.hasAttribute("selected")||e.setAttribute("selected",""):e.removeAttribute("selected")}const Si="5";var ts;typeof window<"u"&&((ts=window.__svelte??(window.__svelte={})).v??(ts.v=new Set)).add(Si);const Us="x-satay-token";function Vs(){const e=new URLSearchParams(window.location.search).get("token"),t=window.__SATAY_TOKEN__;return e??t??window.localStorage.getItem("satay_token")??""}async function yn(e){const t=Vs(),n={};t&&(n[Us]=t);const r=await fetch(e,{headers:n});if(!r.ok)throw new Error(`${r.status} ${r.statusText} for ${e}`);return await r.json()}async function Ai(e,t){const n=Vs(),r={"content-type":"application/json"};n&&(r[Us]=n);const s=await fetch(e,{method:"POST",headers:r,body:JSON.stringify(t)});if(!s.ok)throw new Error(`${s.status} ${s.statusText} for ${e}`);return await s.json()}const At=encodeURIComponent,Ct={runs:()=>yn("/runs"),timeline:e=>yn(`/runs/${At(e)}/timeline`),tree:e=>yn(`/runs/${At(e)}/tree`),task:(e,t)=>yn(`/runs/${At(e)}/tasks/${At(t)}`),compare:(e,t)=>yn(`/runs/${At(e)}/compare?to=${At(t)}`),fork:(e,t)=>Ai(`/runs/${At(e)}/fork`,{fork_point_seq:t})};function mr(e,t=2e3){e();const n=window.setInterval(e,t);return()=>window.clearInterval(n)}function Xt(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toISOString().slice(11,19)}function Gs(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toISOString().slice(0,16).replace("T"," ")}function Ys(e){return e==null?"—":e<1?`${Math.round(e*1e3)}ms`:e<60?`${e.toFixed(2)}s`:`${Math.floor(e/60)}m ${Math.round(e%60)}s`}function Ci(e,t){const n=Math.abs(Date.parse(t)-Date.parse(e)),r=Math.round(n/1e3),s=Math.floor(r/60);return s>0?`${s}m ${r%60}s`:`${r}s`}function qi(e,t=Date.now()){const n=Math.round((t-Date.parse(e))/6e4);return Number.isFinite(n)?n<1?"just now":n<60?`${n}m ago`:`${Math.floor(n/60)}h ${n%60}m ago`:""}function ji(e){return JSON.stringify(e,null,2)}function Ri(e){switch(e){case"WorkflowResumed":return"resume";case"TaskScheduled":return"sched";case"TaskAttemptStarted":return"run";case"TaskAttemptFailed":return"fail";case"TaskCompleted":return"done";case"TimerCreated":case"TimerFired":return"timer";case"EventWaitStarted":case"ExternalEventReceived":return"event";case"WorkflowWaiting":return"wait";default:return"lifecycle"}}function Xr(e){return e.is_interruption===!0||e.type==="WorkflowResumed"}function Ni(e){const t=e.events??[],n=t.map((r,s)=>{let a=null;if(Xr(r)&&s>0){const o=t[s-1],v=(Date.parse(r.ts)-Date.parse(o.ts))/1e3;a=Number.isFinite(v)?v:null}return{event:r,kind:Ri(r.type),downtimeSeconds:a}});return{runId:e.run_id,workflowName:e.workflow_name,status:e.status,interrupted:e.interrupted===!0||t.some(Xr),rows:n}}function Mi(e){const t=e.items??[],n=r=>t.filter(s=>s.status===r).length;return{total:t.length,completed:n("completed"),running:n("running"),failed:n("failed")}}function Di(e){return e.kind==="map"}function Oi(e){return e.kind==="child"}function Fi(e){var s;const t=(e.attempts??[]).map(a=>{const o=a.status==="failed";return{attempt:a,willRetry:o&&a.next_delay!=null,exhausted:o&&a.next_delay==null}}),n=e.usage??[],r=((s=e.error)==null?void 0:s.traceback)??null;return{detail:e,identity:e.identity,taskName:e.task_name,status:e.status,attempts:t,attemptCount:t.length,hasUsage:n.length>0,usage:n,hasTraceback:!!r,traceback:r}}function Ii(e){return e==="completed"||e==="failed"||e==="cancelled"}function zi(e){return e.seq-1}function Pi(e,t){return e.seq>1&&Ii(t)}function Ks(e){const t=e==null?void 0:e.version_mismatch;return!t||typeof t!="object"?null:{stamped:String(t.stamped??""),current:String(t.current??""),mismatch:t.mismatch===!0}}function Li(e){var t;return((t=Ks(e))==null?void 0:t.mismatch)===!0}function Wi(e){const t=e==null?void 0:e.forked_from;return!t||typeof t!="object"?null:{source_run_id:String(t.source_run_id??""),fork_point_seq:Number(t.fork_point_seq)}}function $r(e,t){return JSON.stringify(e??null)===JSON.stringify(t??null)}function Bi(e){const t=(e.rows??[]).map(n=>{const r=n.a??null,s=n.b??null,a=r!==null&&s!==null,o=a&&!$r(r.input,s.input),v=a&&!$r(r.output,s.output),u=a&&r.attempts!==s.attempts,i=a&&r.duration_seconds!==s.duration_seconds,h=n.aligned===!0&&a,m=!h||o||v||u;return{identity:n.identity,taskName:n.task_name??null,a:r,b:s,aligned:h,changed:m,diffs:{input:o,output:v,attempts:u,duration:i}}});return{a:e.a,b:e.b,rows:t,changedCount:t.filter(n=>n.changed).length}}var Hi=T('<span><span class="pip"></span> </span>');function wt(e,t){var n=Hi(),r=_(d(n),1,!0);V(()=>{me(n,1,`chip ${t.status??""}`),b(r,t.label??t.status)}),E(e,n)}var Ui=T('<span class="bolt svelte-vdllgp" title="recovered from an interruption">&#9889;</span>'),Vi=T('<tr class="svelte-vdllgp"><td class="svelte-vdllgp"><!></td><td class="c-id svelte-vdllgp"> <!></td><td class="c-wf svelte-vdllgp"> </td><td class="c-ver svelte-vdllgp"><span class="tag svelte-vdllgp"> </span></td><td class="c-time svelte-vdllgp"> <br/><span class="abs svelte-vdllgp"> </span></td><td class="c-key svelte-vdllgp"> </td></tr>'),Gi=T(`<h1 class="view-title">Runs</h1> <p class="view-sub">Every workflow run in this store, most-recent-first. Backed by <code>GET /runs</code>.
3
+ Select a run to open its timeline, execution tree, and task detail.</p> <table class="runs-table svelte-vdllgp"><thead class="svelte-vdllgp"><tr><th class="svelte-vdllgp">Status</th><th class="svelte-vdllgp">Run ID</th><th class="svelte-vdllgp">Workflow</th><th class="svelte-vdllgp">Code version</th><th class="svelte-vdllgp">Started</th><th class="svelte-vdllgp">Idempotency key</th></tr></thead><tbody class="svelte-vdllgp"></tbody></table> <div class="runs-count svelte-vdllgp"> </div>`,1);function Yi(e,t){ct(t,!0);var n=Gi(),r=_(ye(n),4),s=_(d(r));He(s,21,()=>t.runs,v=>v.run_id,(v,u)=>{var i=Vi(),h=d(i),m=d(h);wt(m,{get status(){return l(u).status}});var c=_(h),p=d(c),y=_(p);{var k=q=>{var S=Ui();E(q,S)};J(y,q=>{l(u).interrupted&&q(k)})}var g=_(c),x=d(g),I=_(g),D=d(I),C=d(D),j=_(I),G=d(j),Y=_(G,2),K=d(Y),X=_(j),U=d(X);V((q,S)=>{b(p,`${l(u).run_id??""} `),b(x,l(u).workflow_name),b(C,l(u).code_version),b(G,q),b(K,S),b(U,l(u).idempotency_key??"—")},[()=>qi(l(u).created_at),()=>Gs(l(u).created_at)]),Pe("click",i,()=>t.onselect(l(u).run_id)),E(v,i)});var a=_(r,2),o=d(a);V(()=>b(o,`${t.runs.length??""} runs · fields: run_id, workflow_name, status, code_version, created_at, idempotency_key`)),E(e,n),dt()}Pn(["click"]);const Ki="***REDACTED***";function Ji(e){return e.replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t])}function Zi(e){const t=JSON.stringify(e,null,2)??"null";let n=Ji(t).replace(/&quot;([^&]+?)&quot;(\s*:)/g,'<span class="jk">&quot;$1&quot;</span>$2').replace(/:\s&quot;(.*?)&quot;/g,': <span class="js">&quot;$1&quot;</span>').replace(/: (-?\d+\.?\d*)/g,': <span class="jn">$1</span>').replace(/: (true|false|null)/g,': <span class="jb">$1</span>');return n=n.replace(new RegExp('<span class="js">&quot;\\*\\*\\*REDACTED\\*\\*\\*&quot;</span>',"g"),'<span class="redacted">&#128274; REDACTED</span>'),t===`"${Ki}"`?'<span class="redacted">&#128274; REDACTED</span>':n}var Qi=T('<pre class="json"></pre>');function Cr(e,t){ct(t,!0);var n=Qi();Hs(n,()=>Zi(t.value),!0),E(e,n),dt()}var Xi=T('Worker died at <b class="svelte-cfijfh"> </b>, resumed at <b class="svelte-cfijfh"> </b> · ~<b class="svelte-cfijfh"> </b> down.',1),$i=T('<div class="seam svelte-cfijfh"><div class="seam-card svelte-cfijfh"><div class="seam-bolt svelte-cfijfh">&#9889;</div> <div class="seam-txt svelte-cfijfh"><div class="t1 svelte-cfijfh">Interrupted → resumed from journal</div> <div class="t2 svelte-cfijfh"><!> Completed work replays as journal hits; only the in-flight attempt re-runs.</div></div></div></div>'),el=T("<span> </span>"),tl=T('<button class="ev-fork svelte-cfijfh" title="Fork a new run from before this event — the original is left untouched (ADR-0004)">&#9887; fork from before</button>'),nl=T('<div class="ev-payload svelte-cfijfh"><div class="payload-box svelte-cfijfh"><div class="pb-label svelte-cfijfh"> </div> <div class="pb-json svelte-cfijfh"><!></div></div></div>'),rl=T('<!> <div><span></span> <button class="ev-head svelte-cfijfh"><span class="ev-seq svelte-cfijfh"> </span> <span class="ev-main svelte-cfijfh"><span> </span> <span class="ev-summary svelte-cfijfh"></span></span> <span class="ev-ts svelte-cfijfh"> <span class="ev-caret svelte-cfijfh">&#9656;</span></span></button> <!> <!></div>',1),sl=T(`<h1 class="view-title svelte-cfijfh">Timeline</h1> <p class="view-sub svelte-cfijfh">The ordered journal for this run, threaded on the skewer. A <code class="svelte-cfijfh">WorkflowResumed</code> event is the
4
+ interruption marker (⚡) — written only when the worker re-drives a crashed run, so it marks exactly where the
5
+ crash happened. Graceful <code class="svelte-cfijfh">WorkflowWaiting</code> parks carry no ⚡. Click any event for its raw payload.</p> <div class="legend svelte-cfijfh"><span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--text-faint)"></span> lifecycle</span> <span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--surface);border:2px solid var(--running)"></span> scheduled</span> <span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--running)"></span> attempt</span> <span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--completed)"></span> completed</span> <span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--failed)"></span> failed</span> <span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--waiting)"></span> timer / event</span> <span class="li svelte-cfijfh"><span class="nd svelte-cfijfh" style="background:var(--accent);box-shadow:0 0 0 3px var(--accent-ring)"></span> ⚡ interruption</span></div> <div class="tl svelte-cfijfh"></div>`,1);function al(e,t){ct(t,!0);const n=Le(()=>Ni(t.data));let r=oe(qt({}));const s={lifecycle:"k-lifecycle",resume:"k-resume",sched:"k-sched",run:"k-run",done:"k-done",fail:"k-fail",timer:"k-timer",event:"k-event",wait:"k-wait"};function a(u){var m,c,p;const i=u.payload,h=()=>i.key!=null?[{t:"key="},{t:String(i.key),strong:!0}]:[{t:`ordinal=${i.ordinal}`}];switch(u.type){case"WorkflowCreated":return[{t:"workflow="},{t:String(i.workflow_name),strong:!0},{t:` · code_version=${i.code_version}`}];case"TaskScheduled":return[{t:"task="},{t:String(i.task_name),strong:!0},{t:" "},...h()];case"TaskAttemptStarted":return[{t:"task="},{t:String(i.task_name),strong:!0},{t:` attempt=${i.attempt}`}];case"TaskAttemptFailed":return[{t:"task="},{t:String(i.task_name),strong:!0},{t:` attempt=${i.attempt} · `},{t:String((m=i.error)==null?void 0:m.type),danger:!0},{t:i.next_delay!=null?` · retry in ${i.next_delay}s`:" · exhausted"}];case"TaskCompleted":return[{t:"task="},{t:String(i.task_name),strong:!0},...i.usage?[{t:` · usage×${i.usage.length}`}]:[]];case"TimerCreated":return[{t:`kind=${i.kind} · ${i.duration_seconds}s → ${Xt(i.fire_at)}`}];case"TimerFired":return[{t:`kind=${i.kind} · identity=${i.identity}`}];case"EventWaitStarted":return[{t:"event_type="},{t:String(i.event_type),strong:!0},...i.key!=null?[{t:` key=${i.key}`}]:[]];case"ExternalEventReceived":return[{t:"event_type="},{t:String(i.event_type),strong:!0},...i.key!=null?[{t:` key=${i.key}`}]:[],{t:" · delivered"}];case"WorkflowWaiting":return[{t:"reason="},{t:String(i.reason),strong:!0},{t:" · parked (no ⚡ — graceful)"}];case"WorkflowFailed":return[{t:`${(c=i.error)==null?void 0:c.type}: ${(p=i.error)==null?void 0:p.message}`,danger:!0}];case"WorkflowResumed":return[{t:"resumed from journal"}];case"WorkflowCompleted":return[{t:"run complete"}];case"WorkflowCancelled":return[{t:String(i.reason??"cancelled")}];default:return[]}}var o=sl(),v=_(ye(o),6);He(v,23,()=>l(n).rows,u=>u.event.event_id,(u,i,h)=>{var m=rl(),c=ye(m);{var p=B=>{var Q=$i(),te=d(Q),$=_(d(te),2),fe=_(d($),2),ie=d(fe);{var Se=Ae=>{var Ge=Xi(),Ne=_(ye(Ge)),xt=d(Ne),et=_(Ne,2),Tt=d(et),St=_(et,2),w=d(St);V((F,A,R)=>{b(xt,F),b(Tt,A),b(w,R)},[()=>Xt(l(n).rows[l(h)-1].event.ts),()=>Xt(l(i).event.ts),()=>Ci(l(n).rows[l(h)-1].event.ts,l(i).event.ts)]),E(Ae,Ge)};J(ie,Ae=>{l(h)>0&&Ae(Se)})}E(B,Q)};J(c,B=>{l(i).kind==="resume"&&B(p)})}var y=_(c,2);let k;var g=d(y),x=_(g,2),I=d(x),D=d(I),C=_(I,2),j=d(C);let G;var Y=d(j),K=_(j,2);He(K,21,()=>a(l(i).event),ar,(B,Q)=>{var te=el();let $;var fe=d(te);V(()=>{$=me(te,1,"svelte-cfijfh",null,$,{strong:l(Q).strong,danger:l(Q).danger}),b(fe,l(Q).t)}),E(B,te)});var X=_(C,2),U=d(X),q=_(x,2);{var S=B=>{var Q=tl();Pe("click",Q,()=>{var te;return(te=t.onfork)==null?void 0:te.call(t,zi(l(i).event))}),E(B,Q)},ne=Le(()=>t.onfork&&Pi(l(i).event,l(n).status));J(q,B=>{l(ne)&&B(S)})}var he=_(q,2);{var le=B=>{var Q=nl(),te=d(Q),$=d(te),fe=d($),ie=_($,2),Se=d(ie);Cr(Se,{get value(){return l(i).event.payload}}),V(()=>b(fe,`event_id ${l(i).event.event_id??""} · payload`)),E(B,Q)};J(he,B=>{l(r)[l(i).event.seq]&&B(le)})}V(B=>{k=me(y,1,"ev svelte-cfijfh",null,k,{"is-resume":l(i).kind==="resume","is-open":l(r)[l(i).event.seq]}),me(g,1,`ev-node ${(l(i).kind==="resume"?"":s[l(i).kind])??""}`,"svelte-cfijfh"),b(D,`#${l(i).event.seq??""}`),G=me(j,1,"ev-type svelte-cfijfh",null,G,{"k-fail":l(i).kind==="fail","k-done":l(i).kind==="done","k-resume":l(i).kind==="resume"}),b(Y,l(i).event.type),b(U,`${B??""} `)},[()=>Xt(l(i).event.ts)]),Pe("click",x,()=>z(r,{...l(r),[l(i).event.seq]:!l(r)[l(i).event.seq]},!0)),E(u,m)}),E(e,o),dt()}Pn(["click"]);var il=T('<span class="mretry svelte-7ey46k"> </span>'),ll=T('<button class="map-item svelte-7ey46k"><span class="mk svelte-7ey46k"> </span> <!> <span></span></button>'),ol=T('<div class="tnode svelte-7ey46k"><div class="trow static svelte-7ey46k"><span class="glyph map svelte-7ey46k">&#8942;&#8942;</span> <div><div class="tname svelte-7ey46k"> </div><div class="tident svelte-7ey46k"> </div></div> <div class="tmeta svelte-7ey46k"><!></div></div> <div class="map-wrap svelte-7ey46k"><div class="map-note svelte-7ey46k"><b class="svelte-7ey46k">fan-out</b> </div> <div class="map-grid svelte-7ey46k"></div></div></div>'),ul=T('<div class="tnode svelte-7ey46k"><div class="trow static svelte-7ey46k"><span class="glyph child svelte-7ey46k">&#8618;</span> <div><div class="tname svelte-7ey46k"> </div><div class="tident svelte-7ey46k"> </div></div> <div class="tmeta svelte-7ey46k"><!></div></div> <div class="child-wrap svelte-7ey46k"><div class="child-head svelte-7ey46k"><span class="clabel svelte-7ey46k">nested run</span><span class="crun svelte-7ey46k"> </span></div> <!></div></div>'),fl=T('<div class="tnode svelte-7ey46k"><button class="trow svelte-7ey46k"><span class="glyph task svelte-7ey46k">T</span> <div><div class="tname svelte-7ey46k"> </div><div class="tident svelte-7ey46k"> </div></div> <div class="tmeta svelte-7ey46k"><span> </span> <!></div></button></div>');function Js(e,t){ct(t,!0);var n=Qt(),r=ye(n);{var s=i=>{const h=Le(()=>Mi(t.node));var m=ol(),c=d(m),p=_(d(c),2),y=d(p),k=d(y),g=_(y),x=d(g),I=_(p,2),D=d(I);wt(D,{get status(){return t.node.status}});var C=_(c,2),j=d(C),G=_(d(j)),Y=_(j,2);He(Y,21,()=>t.node.items,K=>K.identity,(K,X)=>{var U=ll(),q=d(U),S=d(q),ne=_(q,2);{var he=B=>{var Q=il(),te=d(Q);V(()=>b(te,`×${l(X).attempts??""}`)),E(B,Q)};J(ne,B=>{l(X).attempts>1&&B(he)})}var le=_(ne,2);V(()=>{b(S,l(X).key),me(le,1,`mdot ${l(X).status??""}`,"svelte-7ey46k")}),Pe("click",U,()=>t.onopentask(l(X).identity)),E(K,U)}),V(()=>{b(k,`map · ${t.node.task_name??""}`),b(x,`group=${t.node.group??""} · ${t.node.items.length??""} items`),b(G,` — ${l(h).completed??""} completed, ${l(h).running??""} running${l(h).failed?`, ${l(h).failed} failed`:""} · results rejoin in input order`)}),E(i,m)},a=Le(()=>Di(t.node)),o=i=>{var h=ul(),m=d(h),c=_(d(m),2),p=d(c),y=d(p),k=_(p),g=d(k),x=_(c,2),I=d(x);wt(I,{get status(){return t.node.status}});var D=_(m,2),C=d(D),j=_(d(C)),G=d(j),Y=_(C,2);{var K=X=>{var U=Qt(),q=ye(U);He(q,17,()=>t.node.tree.nodes,S=>S.kind+S.identity+S.group,(S,ne)=>{Js(S,{get node(){return l(ne)},get onopentask(){return t.onopentask}})}),E(X,U)};J(Y,X=>{t.node.tree&&X(K)})}V(()=>{b(y,t.node.workflow_name),b(g,`child workflow · ${t.node.identity??""}`),b(G,t.node.child_run_id)}),E(i,h)},v=Le(()=>Oi(t.node)),u=i=>{var h=fl(),m=d(h),c=_(d(m),2),p=d(c),y=d(p),k=_(p),g=d(k),x=_(c,2),I=d(x);let D;var C=d(I),j=_(I,2);wt(j,{get status(){return t.node.status}}),V(()=>{b(y,t.node.task_name),b(g,`${t.node.identity??""} · ${t.node.key!=null?`key=${t.node.key}`:`ordinal=${t.node.ordinal}`}`),D=me(I,1,"attempts svelte-7ey46k",null,D,{retried:t.node.attempts>1}),b(C,`${t.node.attempts??""} attempt${t.node.attempts>1?"s":""}`)}),Pe("click",m,()=>t.onopentask(t.node.identity)),E(i,h)};J(r,i=>{l(a)?i(s):l(v)?i(o,1):i(u,-1)})}E(e,n),dt()}Pn(["click"]);var vl=T('<div class="empty-state">This run scheduled no durable calls.</div>'),cl=T('<div class="tree"></div>'),dl=T(`<h1 class="view-title">Execution tree</h1> <p class="view-sub">Parent/child structure for this run from <code>GET /runs/&#123;id&#125;/tree</code> (V4 linkage). Standalone tasks
6
+ sit at the root; a <b style="color:var(--accent)">map</b> fan-out groups its keyed items; a <b style="color:var(--completed)">child</b> workflow nests as its own run. Click a task to open its detail.</p> <!>`,1);function hl(e,t){ct(t,!0);var n=dl(),r=_(ye(n),4);{var s=o=>{var v=vl();E(o,v)},a=o=>{var v=cl();He(v,21,()=>t.data.nodes,u=>u.kind+u.identity+u.group,(u,i)=>{Js(u,{get node(){return l(i)},get onopentask(){return t.onopentask}})}),E(o,v)};J(r,o=>{t.data.nodes.length===0?o(s):o(a,-1)})}E(e,n),dt()}var _l=T('<div class="io-empty svelte-u9er0g">null — task produced no output (failed before completing)</div>'),pl=T('<tr class="svelte-u9er0g"><td class="svelte-u9er0g"> </td><td class="num svelte-u9er0g"> </td><td class="num svelte-u9er0g"> </td><td class="num svelte-u9er0g"> </td></tr>'),ml=T('<table class="usage-table svelte-u9er0g"><thead><tr><th class="svelte-u9er0g">Model</th><th class="r svelte-u9er0g">Input tok</th><th class="r svelte-u9er0g">Output tok</th><th class="r svelte-u9er0g">Cost (USD)</th></tr></thead><tbody></tbody></table>'),gl=T('<div class="usage-none svelte-u9er0g">&#8709; No usage recorded — this task never called <code class="svelte-u9er0g">ctx.record_model_usage()</code> <span class="dim svelte-u9er0g">(expected, ADR-0008)</span></div>'),yl=T('<div class="att-error svelte-u9er0g"><div class="et svelte-u9er0g"> </div><div class="em svelte-u9er0g"> </div></div>'),kl=T('<div class="att-retry svelte-u9er0g"><span class="rico svelte-u9er0g">&#8635;</span> retried after <b> </b> </div>'),wl=T('<div class="att-exhausted svelte-u9er0g">&#9888; retries exhausted — failure propagated to the workflow</div>'),bl=T('<div class="att-note svelte-u9er0g"><span class="rico svelte-u9er0g">&#9889;</span> </div>'),El=T('<div class="att svelte-u9er0g"><span></span> <div><div class="att-top svelte-u9er0g"><span class="att-n svelte-u9er0g"> </span> <!> <span class="att-dur svelte-u9er0g"> </span></div> <div class="att-times svelte-u9er0g"> </div> <!> <!> <!></div></div>'),xl=T('<div class="trace svelte-u9er0g"><div class="tr-label svelte-u9er0g">&#9888; native stack trace · from WorkflowFailed</div> <pre class="traceback svelte-u9er0g"></pre></div>'),Tl=T(`<h1 class="view-title">Task detail</h1> <p class="view-sub">One <b>logical task</b> and its <b>physical attempts</b>, from <code>GET /runs/&#123;id&#125;/tasks/&#123;identity&#125;</code>.
7
+ Attempts are threaded on the skewer; a failed attempt shows its error and backoff. Usage is per ADR-0008 — present
8
+ only when the task self-reported it.</p> <div class="logical svelte-u9er0g"><div class="lt-name svelte-u9er0g"> <!></div> <div class="lt-ident svelte-u9er0g"> </div> <div class="io-grid svelte-u9er0g"><div class="io-box svelte-u9er0g"><div class="io-label svelte-u9er0g">input</div><!></div> <div class="io-box svelte-u9er0g"><div class="io-label svelte-u9er0g">output</div> <!></div></div> <div class="usage svelte-u9er0g"><div class="u-label svelte-u9er0g">recorded model usage</div> <!></div></div> <div class="attempts-label svelte-u9er0g"> </div> <div class="att-list svelte-u9er0g"></div> <!>`,1);function Sl(e,t){ct(t,!0);const n=Le(()=>Fi(t.data));function r(q){return(ne=>ne.replace(/[&<>]/g,he=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[he]))(q).replace(/(File &quot;.*?&quot;, line \d+, in \S+)/g,'<span class="tb-file">$1</span>').replace(/^([A-Za-z_.]*Error: .*)$/m,'<span class="tb-exc">$1</span>')}var s=Tl(),a=_(ye(s),4),o=d(a),v=d(o),u=_(v);wt(u,{get status(){return l(n).status}});var i=_(o,2),h=d(i),m=_(i,2),c=d(m),p=_(d(c));Cr(p,{get value(){return t.data.input}});var y=_(c,2),k=_(d(y),2);{var g=q=>{Cr(q,{get value(){return t.data.output}})},x=q=>{var S=_l();E(q,S)};J(k,q=>{t.data.output!=null?q(g):q(x,-1)})}var I=_(m,2),D=_(d(I),2);{var C=q=>{var S=ml(),ne=_(d(S));He(ne,21,()=>l(n).usage,ar,(he,le)=>{var B=pl(),Q=d(B),te=d(Q),$=_(Q),fe=d($),ie=_($),Se=d(ie),Ae=_(ie),Ge=d(Ae);V(Ne=>{b(te,l(le).model??"—"),b(fe,l(le).input_tokens??"—"),b(Se,l(le).output_tokens??"—"),b(Ge,Ne)},[()=>l(le).cost_usd!=null?`$${l(le).cost_usd.toFixed(4)}`:"—"]),E(he,B)}),E(q,S)},j=q=>{var S=gl();E(q,S)};J(D,q=>{l(n).hasUsage?q(C):q(j,-1)})}var G=_(a,2),Y=d(G),K=_(G,2);He(K,21,()=>l(n).attempts,q=>q.attempt.attempt,(q,S)=>{var ne=El(),he=d(ne),le=_(he,2);let B;var Q=d(le),te=d(Q),$=d(te),fe=_(te,2);wt(fe,{get status(){return l(S).attempt.status}});var ie=_(fe,2),Se=d(ie),Ae=_(Q,2),Ge=d(Ae),Ne=_(Ae,2);{var xt=A=>{var R=yl(),P=d(R),ee=d(P),re=_(P),Me=d(re);V(()=>{b(ee,l(S).attempt.error.type),b(Me,l(S).attempt.error.message)}),E(A,R)};J(Ne,A=>{l(S).attempt.error&&A(xt)})}var et=_(Ne,2);{var Tt=A=>{var R=kl(),P=_(d(R),2),ee=d(P),re=_(P);V(()=>{b(ee,`${l(S).attempt.next_delay??""}s`),b(re,` backoff → attempt ${l(S).attempt.attempt+1}`)}),E(A,R)},St=A=>{var R=wl();E(A,R)};J(et,A=>{l(S).willRetry?A(Tt):l(S).exhausted&&A(St,1)})}var w=_(et,2);{var F=A=>{var R=bl(),P=_(d(R));V(()=>b(P,` ${l(S).attempt.note??""}`)),E(A,R)};J(w,A=>{l(S).attempt.note&&A(F)})}V((A,R,P)=>{me(he,1,`att-node ${l(S).attempt.status??""}`,"svelte-u9er0g"),B=me(le,1,"att-card svelte-u9er0g",null,B,{failed:l(S).attempt.status==="failed"}),b($,`Attempt ${l(S).attempt.attempt??""}`),b(Se,A),b(Ge,`${R??""} → ${P??""}`)},[()=>Ys(l(S).attempt.duration_seconds),()=>Xt(l(S).attempt.started_at),()=>l(S).attempt.ended_at?Xt(l(S).attempt.ended_at):"—"]),E(q,ne)});var X=_(K,2);{var U=q=>{var S=xl(),ne=_(d(S),2);Hs(ne,()=>r(l(n).traceback),!0),E(q,S)};J(X,q=>{l(n).hasTraceback&&l(n).traceback&&q(U)})}V(()=>{b(v,`${l(n).taskName??""} `),b(h,`${l(n).identity??""} · ${t.data.key!=null?`key = ${t.data.key}`:`ordinal = ${t.data.ordinal}`}`),b(Y,`Physical attempts · ${l(n).attemptCount??""}`)}),E(e,s),dt()}var Al=T("<option> </option>"),Cl=T('<div class="empty-state">Pick a second run to compare against.</div>'),ql=T('<div class="empty-state">Loading comparison…</div>'),jl=T('<span class="badge svelte-uzstyf">changed</span>'),Rl=T('<span class="badge only svelte-uzstyf">one side only</span>'),Nl=T('<span class="absent svelte-uzstyf">— absent —</span>'),Ml=T('<div class="cell-line svelte-uzstyf"><!></div> <div><span class="k svelte-uzstyf">in</span> <code class="svelte-uzstyf"> </code></div> <div><span class="k svelte-uzstyf">out</span> <code class="svelte-uzstyf"> </code></div> <div><span class="k svelte-uzstyf">attempts</span> </div> <div><span class="k svelte-uzstyf">took</span> </div>',1),Dl=T('<td class="c-side svelte-uzstyf"><!></td>'),Ol=T('<tr><td class="c-ident svelte-uzstyf"><span class="ident svelte-uzstyf"> </span> <!> <!></td><!></tr>'),Fl=T('<div class="summary svelte-uzstyf"> <span class="tag svelte-uzstyf"> </span> and <span class="tag svelte-uzstyf"> </span>.</div> <table class="cmp svelte-uzstyf"><thead class="svelte-uzstyf"><tr><th class="svelte-uzstyf">Durable call</th><th class="svelte-uzstyf"> </th><th class="svelte-uzstyf"> </th></tr></thead><tbody class="svelte-uzstyf"></tbody></table>',1),Il=T(`<h1 class="view-title">Compare runs</h1> <p class="view-sub">Two runs aligned by durable-call identity (<code></code>). Each shared call is one
9
+ row; cells that changed — input, output, attempts — are highlighted, so a run and its fork answer <em>“what did my change do”</em>. Timing is shown for reference and not counted as a change.</p> <div class="picker svelte-uzstyf"><span class="pk-a svelte-uzstyf">A · <b class="svelte-uzstyf"> </b></span> <span class="pk-vs svelte-uzstyf">vs</span> <label class="pk-b svelte-uzstyf">B · <select class="svelte-uzstyf"><option>choose a run…</option><!></select></label></div> <!>`,1);function zl(e,t){ct(t,!0);const n=Le(()=>t.runs.filter(C=>C.run_id!==t.runId)),r=Le(()=>t.data?Bi(t.data):null);function s(C){const j=ji(C);return j.length>80?j.slice(0,79)+"…":j}var a=Il(),o=_(ye(a),2),v=_(d(o));v.textContent="GET /runs/{id}/compare?to=…";var u=_(o,2),i=d(u),h=_(d(i)),m=d(h),c=_(i,4),p=_(d(c)),y=d(p);y.value=y.__value="";var k=_(y);He(k,17,()=>l(n),C=>C.run_id,(C,j)=>{var G=Al(),Y=d(G),K={};V(()=>{Qr(G,l(j).run_id===t.compareTo),b(Y,`${l(j).run_id??""} · ${l(j).workflow_name??""} · ${l(j).status??""}`),K!==(K=l(j).run_id)&&(G.value=(G.__value=l(j).run_id)??"")}),E(C,G)});var g=_(u,2);{var x=C=>{var j=Cl();E(C,j)},I=C=>{var j=ql();E(C,j)},D=C=>{var j=Fl(),G=ye(j),Y=d(G),K=_(Y),X=d(K),U=_(K,2),q=d(U),S=_(G,2),ne=d(S),he=d(ne),le=_(d(he)),B=d(le),Q=_(le),te=d(Q),$=_(ne);He($,21,()=>l(r).rows,fe=>fe.identity,(fe,ie)=>{var Se=Ol();let Ae;var Ge=d(Se),Ne=d(Ge),xt=d(Ne),et=_(Ne,2);{var Tt=A=>{var R=jl();E(A,R)};J(et,A=>{l(ie).changed&&A(Tt)})}var St=_(et,2);{var w=A=>{var R=Rl();E(A,R)};J(St,A=>{l(ie).aligned||A(w)})}var F=_(Ge);He(F,17,()=>[l(ie).a,l(ie).b],ar,(A,R)=>{var P=Dl(),ee=d(P);{var re=Ye=>{var Ut=Nl();E(Ye,Ut)},Me=Ye=>{var Ut=Ml(),hn=ye(Ut),ir=d(hn);wt(ir,{get status(){return l(R).status}});var _n=_(hn,2);let pn;var lr=_(d(_n),2),or=d(lr),Vt=_(_n,2);let Ln;var ur=_(d(Vt),2),fr=d(ur),mn=_(Vt,2);let pe;var tt=_(d(mn)),Gt=_(mn,2);let Wn;var Zs=_(d(Gt));V((Qs,Xs,$s)=>{pn=me(_n,1,"cell-line svelte-uzstyf",null,pn,{diff:l(ie).diffs.input}),b(or,Qs),Ln=me(Vt,1,"cell-line svelte-uzstyf",null,Ln,{diff:l(ie).diffs.output}),b(fr,Xs),pe=me(mn,1,"cell-line svelte-uzstyf",null,pe,{diff:l(ie).diffs.attempts}),b(tt,` ${l(R).attempts??""}`),Wn=me(Gt,1,"cell-line time svelte-uzstyf",null,Wn,{diff:l(ie).diffs.duration}),b(Zs,` ${$s??""}`)},[()=>s(l(R).input),()=>s(l(R).output),()=>Ys(l(R).duration_seconds)]),E(Ye,Ut)};J(ee,Ye=>{l(R)?Ye(Me,-1):Ye(re)})}E(A,P)}),V(()=>{Ae=me(Se,1,"svelte-uzstyf",null,Ae,{changed:l(ie).changed}),b(xt,l(ie).identity)}),E(fe,Se)}),V(()=>{b(Y,`${l(r).changedCount??""} of ${l(r).rows.length??""} calls differ between `),b(X,l(r).a.run_id),b(q,l(r).b.run_id),b(B,`A · ${l(r).a.run_id??""}`),b(te,`B · ${l(r).b.run_id??""}`)}),E(C,j)};J(g,C=>{t.compareTo?l(r)?C(D,-1):C(I,1):C(x)})}V(()=>{b(m,t.runId),Qr(y,!t.compareTo)}),Pe("change",p,C=>t.onpick(C.currentTarget.value)),E(e,a),dt()}Pn(["change"]);var Pl=T("<button> </button>"),Ll=T('<span class="chip accent"><span class="pip"></span>&#9889; interrupted</span>'),Wl=T('<button class="chip fork-chip svelte-1n46o8q" title="Compare against the source run"> </button>'),Bl=T('<div class="kv svelte-1n46o8q"><span class="k svelte-1n46o8q">idempotency</span><span class="v svelte-1n46o8q"> </span></div>'),Hl=T('<div class="runbar svelte-1n46o8q"><button class="back svelte-1n46o8q">&#9664; all runs</button> <span class="rid svelte-1n46o8q"> </span> <span class="wf svelte-1n46o8q"> </span> <!> <!> <!> <div class="meta svelte-1n46o8q"><div class="kv svelte-1n46o8q"><span class="k svelte-1n46o8q">code version</span><span class="v svelte-1n46o8q"> </span></div> <div class="kv svelte-1n46o8q"><span class="k svelte-1n46o8q">started</span><span class="v svelte-1n46o8q"> </span></div> <!></div></div>'),Ul=T(`<div class="mismatch-banner svelte-1n46o8q"><span class="mb-bolt svelte-1n46o8q">&#9888;</span> <div class="mb-txt svelte-1n46o8q"><div class="mb-t1 svelte-1n46o8q">Code version mismatch</div> <div class="mb-t2 svelte-1n46o8q">This run was stamped <b class="svelte-1n46o8q"> </b> but the current code is <b class="svelte-1n46o8q"> </b>.
10
+ Resuming replays the workflow under changed code and may diverge — <b class="svelte-1n46o8q">fork</b> to continue under the new code (no automatic migration, ADR-0010).</div></div> <button class="mb-act svelte-1n46o8q">&#9887; Fork this run</button></div>`),Vl=T('<div class="empty-state error-state"> </div>'),Gl=T('<div class="empty-state">Loading timeline…</div>'),Yl=T('<div class="empty-state">Loading tree…</div>'),Kl=T('<div class="empty-state">Select a task from the execution tree.</div>'),Jl=T('<div class="empty-state">Loading task…</div>'),Zl=T('<div class="app svelte-1n46o8q"><aside class="sidebar svelte-1n46o8q"><div class="brand svelte-1n46o8q"><div class="mark svelte-1n46o8q"><svg viewBox="0 0 24 24" fill="none" class="svelte-1n46o8q"><path d="M13 2 4 14h6l-1 8 9-12h-6l1-8Z" fill="#fff"></path></svg></div> <div class="word svelte-1n46o8q">satay <b class="svelte-1n46o8q">studio</b><span class="svelte-1n46o8q">durable debugger</span></div></div> <div class="nav-label svelte-1n46o8q">Explore</div> <button>Runs</button> <div class="nav-label svelte-1n46o8q">Selected run</div> <!> <div class="sidebar-foot svelte-1n46o8q"><div class="conn svelte-1n46o8q"><span class="dot svelte-1n46o8q"></span> read API · polling</div> <button class="theme-btn svelte-1n46o8q">◐ theme</button></div></aside> <main class="main svelte-1n46o8q"><!> <!> <section class="view svelte-1n46o8q"><div class="view-wrap svelte-1n46o8q"><!></div></section></main></div>');function Ql(e,t){ct(t,!0);let n=oe("runs"),r=oe(null),s=oe(null),a=oe(null),o=oe(qt([])),v=oe(null),u=oe(null),i=oe(null),h=oe(null),m=oe(null),c=oe(!1);const p=Le(()=>l(o).find(w=>w.run_id===l(r))??null),y=Le(()=>Ks(l(p))),k=Le(()=>Wi(l(p)));function g(w){z(m,w instanceof Error?w.message:String(w),!0)}_r(()=>{if(l(n)==="runs")return mr(()=>{Ct.runs().then(w=>{z(o,w.runs,!0),z(m,null)}).catch(g)})}),_r(()=>{const w=l(r),F=l(n),A=l(s),R=l(a);if(!(!w||F==="runs"))return mr(()=>{F==="timeline"?Ct.timeline(w).then(P=>{z(v,P,!0),z(m,null)}).catch(g):F==="tree"?Ct.tree(w).then(P=>{z(u,P,!0),z(m,null)}).catch(g):F==="task"&&A?Ct.task(w,A).then(P=>{z(i,P,!0),z(m,null)}).catch(g):F==="compare"&&R&&Ct.compare(w,R).then(P=>{z(h,P,!0),z(m,null)}).catch(g)})}),_r(()=>{if(l(n)!=="runs")return mr(()=>{Ct.runs().then(w=>{z(o,w.runs,!0)}).catch(()=>{})},4e3)});function x(w){z(r,w,!0),z(s,null),z(a,null),z(v,z(u,z(i,null),!0),!0),z(h,null),z(m,null),z(n,"timeline")}function I(w){w!=="runs"&&!l(r)||z(n,w,!0)}function D(w){z(s,w,!0),z(i,null),z(n,"task")}function C(w){z(a,w||null,!0),z(h,null),z(m,null)}async function j(w){if(!(!l(r)||l(c))){z(c,!0);try{const F=await Ct.fork(l(r),w);x(F.run_id)}catch(F){g(F)}finally{z(c,!1)}}}function G(){const w=document.documentElement.getAttribute("data-theme");document.documentElement.setAttribute("data-theme",w==="dark"?"light":"dark")}const Y=[{id:"timeline",label:"Timeline"},{id:"tree",label:"Execution tree"},{id:"task",label:"Task detail"},{id:"compare",label:"Compare"}];var K=Zl(),X=d(K),U=_(d(X),4);let q;var S=_(U,4);He(S,17,()=>Y,ar,(w,F)=>{var A=Pl();let R;var P=d(A);V(()=>{R=me(A,1,"nav-item svelte-1n46o8q",null,R,{"is-active":l(n)===l(F).id,"is-disabled":!l(r)}),b(P,l(F).label)}),Pe("click",A,()=>I(l(F).id)),E(w,A)});var ne=_(S,2),he=_(d(ne),2),le=_(X,2),B=d(le);{var Q=w=>{var F=Hl(),A=d(F),R=_(A,2),P=d(R),ee=_(R,2),re=d(ee),Me=_(ee,2);wt(Me,{get status(){return l(p).status}});var Ye=_(Me,2);{var Ut=pe=>{var tt=Ll();E(pe,tt)};J(Ye,pe=>{l(p).interrupted&&pe(Ut)})}var hn=_(Ye,2);{var ir=pe=>{var tt=Wl(),Gt=d(tt);V(()=>b(Gt,`⚟ forked from ${l(k).source_run_id??""} @ #${l(k).fork_point_seq??""}`)),Pe("click",tt,()=>{C(l(k).source_run_id),I("compare")}),E(pe,tt)};J(hn,pe=>{l(k)&&pe(ir)})}var _n=_(hn,2),pn=d(_n),lr=_(d(pn)),or=d(lr),Vt=_(pn,2),Ln=_(d(Vt)),ur=d(Ln),fr=_(Vt,2);{var mn=pe=>{var tt=Bl(),Gt=_(d(tt)),Wn=d(Gt);V(()=>b(Wn,l(p).idempotency_key)),E(pe,tt)};J(fr,pe=>{l(p).idempotency_key&&pe(mn)})}V(pe=>{b(P,l(p).run_id),b(re,l(p).workflow_name),b(or,l(p).code_version),b(ur,pe)},[()=>Gs(l(p).created_at)]),Pe("click",A,()=>I("runs")),E(w,F)};J(B,w=>{l(n)!=="runs"&&l(p)&&w(Q)})}var te=_(B,2);{var $=w=>{var F=Ul(),A=_(d(F),2),R=_(d(A),2),P=_(d(R)),ee=d(P),re=_(P,2),Me=d(re),Ye=_(A,2);V(()=>{b(ee,l(y).stamped),b(Me,l(y).current)}),Pe("click",Ye,()=>I("timeline")),E(w,F)},fe=Le(()=>{var w;return l(n)!=="runs"&&l(p)&&((w=l(y))==null?void 0:w.mismatch)&&Li(l(p))});J(te,w=>{l(fe)&&w($)})}var ie=_(te,2),Se=d(ie),Ae=d(Se);{var Ge=w=>{var F=Vl(),A=d(F);V(()=>b(A,`Read API error: ${l(m)??""}`)),E(w,F)},Ne=w=>{Yi(w,{get runs(){return l(o)},onselect:x})},xt=w=>{var F=Qt(),A=ye(F);{var R=ee=>{al(ee,{get data(){return l(v)},onfork:j})},P=ee=>{var re=Gl();E(ee,re)};J(A,ee=>{l(v)?ee(R):ee(P,-1)})}E(w,F)},et=w=>{var F=Qt(),A=ye(F);{var R=ee=>{hl(ee,{get data(){return l(u)},onopentask:D})},P=ee=>{var re=Yl();E(ee,re)};J(A,ee=>{l(u)?ee(R):ee(P,-1)})}E(w,F)},Tt=w=>{var F=Qt(),A=ye(F);{var R=re=>{var Me=Kl();E(re,Me)},P=re=>{Sl(re,{get data(){return l(i)}})},ee=re=>{var Me=Jl();E(re,Me)};J(A,re=>{l(s)?l(i)?re(P,1):re(ee,-1):re(R)})}E(w,F)},St=w=>{var F=Qt(),A=ye(F);{var R=P=>{zl(P,{get runId(){return l(r)},get compareTo(){return l(a)},get runs(){return l(o)},get data(){return l(h)},onpick:C})};J(A,P=>{l(r)&&P(R)})}E(w,F)};J(Ae,w=>{l(m)?w(Ge):l(n)==="runs"?w(Ne,1):l(n)==="timeline"?w(xt,2):l(n)==="tree"?w(et,3):l(n)==="task"?w(Tt,4):l(n)==="compare"&&w(St,5)})}V(()=>q=me(U,1,"nav-item svelte-1n46o8q",null,q,{"is-active":l(n)==="runs"})),Pe("click",U,()=>I("runs")),Pe("click",he,G),E(e,K),dt()}Pn(["click"]);var ns;!document.documentElement.getAttribute("data-theme")&&((ns=window.matchMedia)!=null&&ns.call(window,"(prefers-color-scheme: light)").matches)&&document.documentElement.setAttribute("data-theme","light");gi(Ql,{target:document.getElementById("app")});
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en" data-theme="dark">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Satay Studio</title>
7
+ <script type="module" crossorigin src="./assets/index-By_8Sh9l.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-BEr3SCNe.css">
9
+ </head>
10
+ <body>
11
+ <div id="app"></div>
12
+ </body>
13
+ </html>
satay/api/__init__.py ADDED
@@ -0,0 +1,38 @@
1
+ """Author-facing API surface (A1): decorators, primitives, run handle, TaskContext.
2
+
3
+ This is the boundary the developer imports. It looks like ordinary async Python
4
+ while routing every durable call through the replay engine (ARCHITECTURE §3.1).
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from satay.api.context import TaskContext, task_context
10
+ from satay.api.decorators import task, workflow
11
+ from satay.api.primitives import (
12
+ gather,
13
+ map,
14
+ send_event,
15
+ sleep,
16
+ start,
17
+ start_child,
18
+ wait_for_event,
19
+ )
20
+ from satay.api.run_handle import RunHandle
21
+ from satay.replay.nondeterminism import EffectSafetyError, NondeterminismError
22
+
23
+ __all__ = [
24
+ "EffectSafetyError",
25
+ "NondeterminismError",
26
+ "RunHandle",
27
+ "TaskContext",
28
+ "gather",
29
+ "map",
30
+ "send_event",
31
+ "sleep",
32
+ "start",
33
+ "start_child",
34
+ "task",
35
+ "task_context",
36
+ "wait_for_event",
37
+ "workflow",
38
+ ]
satay/api/context.py ADDED
@@ -0,0 +1,88 @@
1
+ """Task-facing context (``TaskContext``, N14).
2
+
3
+ A running task reads its context with :func:`task_context`, which returns the
4
+ :class:`TaskContext` bound for the current attempt. The context carries the durable
5
+ identity of the attempt and the opt-in model-usage recording slot (ADR-0008). A task
6
+ reads ``ctx.idempotency_key`` — stable across retries, distinct across invocations
7
+ (A4.3) — to make external effects safe under at-least-once execution.
8
+
9
+ Injection is via a ``ContextVar`` (the same pattern the replay driver uses), so task
10
+ signatures stay ordinary and tasks remain independently callable. Usage is buffered on
11
+ the context and flushed by the executor into the journal's generic usage slot on
12
+ ``TaskCompleted`` (build step 1/6). The core ships no model adapters: a task that never
13
+ calls :meth:`record_model_usage` records no usage.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from contextvars import ContextVar
19
+ from typing import Any
20
+
21
+
22
+ class TaskContext:
23
+ """The context bound for one task attempt (N14)."""
24
+
25
+ def __init__(
26
+ self,
27
+ *,
28
+ run_id: str,
29
+ task_name: str,
30
+ ordinal: int,
31
+ attempt: int,
32
+ idempotency_key: str,
33
+ ) -> None:
34
+ self.run_id = run_id
35
+ self.task_name = task_name
36
+ self.ordinal = ordinal
37
+ self.attempt = attempt
38
+ self._idempotency_key = idempotency_key
39
+ self._usage: list[dict[str, Any]] = []
40
+
41
+ @property
42
+ def idempotency_key(self) -> str:
43
+ """The stable idempotency key of this logical task (read-only, A4.3)."""
44
+ return self._idempotency_key
45
+
46
+ def record_model_usage(
47
+ self,
48
+ model: str | None = None,
49
+ input_tokens: int | None = None,
50
+ output_tokens: int | None = None,
51
+ **extra: Any,
52
+ ) -> None:
53
+ """Record schemaless model usage for this attempt (opt-in self-report, ADR-0008).
54
+
55
+ Only the fields supplied are stored, plus any ``extra`` (so non-LLM cost or
56
+ provider-specific fields ride along). The executor flushes the buffer into the
57
+ journal's usage slot on ``TaskCompleted``; Studio renders it in V6.
58
+ """
59
+ entry: dict[str, Any] = dict(extra)
60
+ if model is not None:
61
+ entry["model"] = model
62
+ if input_tokens is not None:
63
+ entry["input_tokens"] = input_tokens
64
+ if output_tokens is not None:
65
+ entry["output_tokens"] = output_tokens
66
+ self._usage.append(entry)
67
+
68
+ @property
69
+ def recorded_usage(self) -> list[dict[str, Any]]:
70
+ """The usage entries recorded so far (executor-internal; empty if none)."""
71
+ return list(self._usage)
72
+
73
+
74
+ #: The context bound for the current task attempt, or ``None`` outside a task body.
75
+ CURRENT_TASK_CONTEXT: ContextVar[TaskContext | None] = ContextVar(
76
+ "satay_task_context", default=None
77
+ )
78
+
79
+
80
+ def task_context() -> TaskContext:
81
+ """Return the :class:`TaskContext` for the currently running task (N14).
82
+
83
+ Raises :class:`RuntimeError` if called outside a ``@satay.task`` body.
84
+ """
85
+ ctx = CURRENT_TASK_CONTEXT.get()
86
+ if ctx is None:
87
+ raise RuntimeError("task_context() must be called inside a running @satay.task body")
88
+ return ctx
@@ -0,0 +1,82 @@
1
+ """Author-facing decorators: ``@satay.workflow`` and ``@satay.task`` (N1/N2).
2
+
3
+ Pure Python, no third-party dependency (ARCHITECTURE §3.1). ``@satay.workflow``
4
+ registers the coroutine and returns it annotated with its definition so
5
+ :func:`satay.start` can resolve name and callable. ``@satay.task`` registers the
6
+ task and returns a wrapper whose call, *inside a running workflow*, becomes a durable
7
+ call routed to the replay engine (via the current-drive ``ContextVar``) rather than
8
+ executing inline. Called outside a drive, a task simply executes — so tasks stay
9
+ independently callable and testable.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import functools
15
+ from collections.abc import Awaitable, Callable
16
+ from typing import Any, TypeVar, cast
17
+
18
+ from satay.api.registry import REGISTRY, TaskDefinition, WorkflowDefinition
19
+ from satay.replay.driver import CURRENT_DRIVER
20
+
21
+ _AsyncFn = TypeVar("_AsyncFn", bound=Callable[..., Awaitable[Any]])
22
+
23
+ #: Attribute stamped on a decorated callable, carrying its registry definition.
24
+ WORKFLOW_ATTR = "__satay_workflow__"
25
+ TASK_ATTR = "__satay_task__"
26
+
27
+
28
+ def workflow[AsyncFnT: Callable[..., Awaitable[Any]]](fn: AsyncFnT) -> AsyncFnT:
29
+ """Register a workflow definition and return it, annotated for the runtime (N1)."""
30
+ definition = WorkflowDefinition(name=fn.__name__, fn=fn)
31
+ REGISTRY.register_workflow(definition)
32
+ setattr(fn, WORKFLOW_ATTR, definition)
33
+ return fn
34
+
35
+
36
+ def task(
37
+ *,
38
+ retries: int = 0,
39
+ timeout: float | None = None,
40
+ side_effect: bool = False,
41
+ idempotent: bool = False,
42
+ ) -> Callable[[_AsyncFn], _AsyncFn]:
43
+ """Register a task and wrap calls as durable calls (N2).
44
+
45
+ ``retries``/``timeout`` drive the retry loop with exponential backoff (N10).
46
+ ``side_effect``/``idempotent`` drive effect-safety enforcement (A10.2): a
47
+ retryable side-effecting task must set ``idempotent=True`` (a promise it keys its
48
+ effect on ``ctx.idempotency_key``), else ``effect_safety=strict`` rejects it at
49
+ schedule time.
50
+ """
51
+
52
+ def decorator(fn: _AsyncFn) -> _AsyncFn:
53
+ definition = TaskDefinition(
54
+ name=fn.__name__,
55
+ fn=fn,
56
+ retries=retries,
57
+ timeout=timeout,
58
+ side_effect=side_effect,
59
+ idempotent=idempotent,
60
+ )
61
+ REGISTRY.register_task(definition)
62
+
63
+ @functools.wraps(fn)
64
+ async def wrapper(*args: Any, **kwargs: Any) -> Any:
65
+ driver = CURRENT_DRIVER.get()
66
+ if driver is None:
67
+ # Outside a workflow drive: execute inline (tasks stay callable) with a
68
+ # detached context so ``task_context()`` still works.
69
+ from satay.api.context import CURRENT_TASK_CONTEXT
70
+ from satay.executor import detached_context
71
+
72
+ token = CURRENT_TASK_CONTEXT.set(detached_context(definition.name))
73
+ try:
74
+ return await fn(*args, **kwargs)
75
+ finally:
76
+ CURRENT_TASK_CONTEXT.reset(token)
77
+ return await driver.durable_call(definition, args, kwargs)
78
+
79
+ setattr(wrapper, TASK_ATTR, definition)
80
+ return cast("_AsyncFn", wrapper)
81
+
82
+ return decorator