satay 0.1.0__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 (57) hide show
  1. satay/__init__.py +112 -0
  2. satay/_studio_assets/assets/index-BhyW4Wc4.js +10 -0
  3. satay/_studio_assets/assets/index-vwLg8ReS.css +1 -0
  4. satay/_studio_assets/index.html +13 -0
  5. satay/api/__init__.py +38 -0
  6. satay/api/app.py +138 -0
  7. satay/api/context.py +138 -0
  8. satay/api/decorators.py +101 -0
  9. satay/api/fork.py +239 -0
  10. satay/api/primitives.py +281 -0
  11. satay/api/registry.py +94 -0
  12. satay/api/run_handle.py +167 -0
  13. satay/api/runner.py +268 -0
  14. satay/blobs/__init__.py +173 -0
  15. satay/cli/__init__.py +13 -0
  16. satay/cli/main.py +132 -0
  17. satay/config.py +275 -0
  18. satay/control/__init__.py +120 -0
  19. satay/control/api.py +145 -0
  20. satay/control/commands.py +559 -0
  21. satay/control/redaction.py +33 -0
  22. satay/control/security.py +128 -0
  23. satay/control/server.py +210 -0
  24. satay/control/views.py +504 -0
  25. satay/demo.py +489 -0
  26. satay/devstack/__init__.py +32 -0
  27. satay/devstack/appload.py +226 -0
  28. satay/devstack/cli.py +87 -0
  29. satay/devstack/lock.py +128 -0
  30. satay/devstack/orchestrator.py +307 -0
  31. satay/executor/__init__.py +259 -0
  32. satay/journal/__init__.py +121 -0
  33. satay/journal/codec.py +567 -0
  34. satay/journal/events.py +182 -0
  35. satay/journal/store.py +557 -0
  36. satay/journal/timeline.py +109 -0
  37. satay/py.typed +0 -0
  38. satay/redaction.py +162 -0
  39. satay/replay/__init__.py +33 -0
  40. satay/replay/driver.py +76 -0
  41. satay/replay/engine.py +1115 -0
  42. satay/replay/failures.py +53 -0
  43. satay/replay/identity.py +132 -0
  44. satay/replay/nondeterminism.py +61 -0
  45. satay/testing/__init__.py +38 -0
  46. satay/testing/clock.py +104 -0
  47. satay/testing/faults.py +81 -0
  48. satay/testing/fixtures.py +82 -0
  49. satay/testing/rng.py +60 -0
  50. satay/testing/settle.py +98 -0
  51. satay/timers/__init__.py +364 -0
  52. satay/versioning/__init__.py +160 -0
  53. satay-0.1.0.dist-info/METADATA +168 -0
  54. satay-0.1.0.dist-info/RECORD +57 -0
  55. satay-0.1.0.dist-info/WHEEL +4 -0
  56. satay-0.1.0.dist-info/entry_points.txt +2 -0
  57. satay-0.1.0.dist-info/licenses/LICENSE +202 -0
satay/__init__.py ADDED
@@ -0,0 +1,112 @@
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
+ - ``fork`` — re-cut a finished run from a chosen point, optionally under a new input
15
+ - ``run_app`` — ``async with``: the journal open and the poll loop running
16
+ - ``TaskContext`` — the task-body context
17
+ - ``RunHandle`` — the run handle
18
+ - ``PARKED`` — what ``result()`` returns for a run parked with nothing to wake it
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ from importlib.metadata import PackageNotFoundError
24
+ from importlib.metadata import version as _distribution_version
25
+ from pathlib import Path
26
+
27
+ from satay.api import (
28
+ EffectSafetyError,
29
+ NondeterminismError,
30
+ RunHandle,
31
+ TaskContext,
32
+ gather,
33
+ map,
34
+ send_event,
35
+ sleep,
36
+ start,
37
+ start_child,
38
+ task,
39
+ task_context,
40
+ wait_for_event,
41
+ workflow,
42
+ )
43
+ from satay.api.app import run_app
44
+ from satay.api.fork import fork
45
+ from satay.api.run_handle import PARKED, WorkflowFailedError
46
+ from satay.replay.failures import TaskFailedError
47
+ from satay.versioning import VersionMismatchError
48
+
49
+
50
+ def _version_from_source_tree() -> str | None:
51
+ """Read ``project.version`` out of the checkout's ``pyproject.toml``.
52
+
53
+ This is the fallback for a source tree whose distribution is not installed, so a
54
+ contributor running straight off ``src/`` still sees the real version instead of a
55
+ placeholder. Returns ``None`` when this file is not sitting in a Satay checkout —
56
+ which is the normal installed case, where the metadata above already answered.
57
+ """
58
+ import tomllib
59
+
60
+ pyproject = Path(__file__).resolve().parents[2] / "pyproject.toml"
61
+ try:
62
+ with pyproject.open("rb") as handle:
63
+ data: dict[str, object] = tomllib.load(handle)
64
+ except (OSError, tomllib.TOMLDecodeError):
65
+ return None
66
+ project = data.get("project")
67
+ if not isinstance(project, dict) or project.get("name") != "satay":
68
+ return None
69
+ declared = project.get("version")
70
+ return declared if isinstance(declared, str) else None
71
+
72
+
73
+ def _detect_version() -> str:
74
+ """Resolve the package version from metadata, never from a constant in this file.
75
+
76
+ ``pyproject.toml`` is the single source of truth: the installed distribution's
77
+ metadata is generated from it at build time, and the source-tree fallback reads it
78
+ directly. Hard-coding the version here is what shipped ``0.0.0`` in ``0.1.0a1``
79
+ (KAN-447) — the value must not be able to drift from ``pyproject.toml`` again.
80
+ """
81
+ try:
82
+ return _distribution_version("satay")
83
+ except PackageNotFoundError:
84
+ # Not installed: a bare source checkout, or an import off a path entry.
85
+ return _version_from_source_tree() or "0.0.0.dev0+unknown"
86
+
87
+
88
+ __version__: str = _detect_version()
89
+
90
+ __all__ = [
91
+ "PARKED",
92
+ "EffectSafetyError",
93
+ "NondeterminismError",
94
+ "RunHandle",
95
+ "TaskContext",
96
+ "TaskFailedError",
97
+ "VersionMismatchError",
98
+ "WorkflowFailedError",
99
+ "__version__",
100
+ "fork",
101
+ "gather",
102
+ "map",
103
+ "run_app",
104
+ "send_event",
105
+ "sleep",
106
+ "start",
107
+ "start_child",
108
+ "task",
109
+ "task_context",
110
+ "wait_for_event",
111
+ "workflow",
112
+ ]
@@ -0,0 +1,10 @@
1
+ var ta=Object.defineProperty;var Lr=e=>{throw TypeError(e)};var na=(e,t,n)=>t in e?ta(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var je=(e,t,n)=>na(e,typeof t!="symbol"?t+"":t,n),vr=(e,t,n)=>t.has(e)||Lr("Cannot "+n);var v=(e,t,n)=>(vr(e,t,"read from private field"),n?n.call(e):t.get(e)),N=(e,t,n)=>t.has(e)?Lr("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),C=(e,t,n,r)=>(vr(e,t,"write to private field"),r?r.call(e,n):t.set(e,n),n),B=(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 ss=!1;var as=Array.isArray,ra=Array.prototype.indexOf,$n=Array.prototype.includes,or=Array.from,sa=Object.defineProperty,Rn=Object.getOwnPropertyDescriptor,aa=Object.prototype,ia=Array.prototype,la=Object.getPrototypeOf,Wr=Object.isExtensible;const oa=()=>{};function ua(e){for(var t=0;t<e.length;t++)e[t]()}function is(){var e,t,n=new Promise((r,s)=>{e=r,t=s});return{promise:n,resolve:e,reject:t}}const pe=2,Dn=4,ur=8,ls=1<<24,et=16,Je=32,pt=64,gr=128,Ye=512,_e=1024,de=2048,nt=4096,Ee=8192,Ke=16384,kn=32768,Br=1<<25,_n=65536,er=1<<17,fa=1<<18,yn=1<<19,va=1<<20,ot=1<<25,Jt=65536,tr=1<<21,ln=1<<22,qt=1<<23,cr=Symbol("$state"),ca=Symbol("attributes"),kr=Symbol("class"),da=Symbol("style"),Sn=Symbol("text"),Hn=new class extends Error{constructor(){super(...arguments);je(this,"name","StaleReactionError");je(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};function ha(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function _a(e,t,n){throw new Error("https://svelte.dev/e/each_key_duplicate")}function pa(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function ma(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function ga(e){throw new Error("https://svelte.dev/e/effect_orphan")}function ka(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function ya(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function wa(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function ba(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function xa(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const Ea=1,Ta=2,os=4,Sa=8,Aa=16,Ca=1,qa=2,he=Symbol("uninitialized"),ja="http://www.w3.org/1999/xhtml",Ra="http://www.w3.org/2000/svg",Na="http://www.w3.org/1998/Math/MathML";function Ma(){console.warn("https://svelte.dev/e/derived_inert")}function Da(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function us(e){return e===this.v}function Fa(e,t){return e!=e?t==t:e!==t||e!==null&&typeof e=="object"||typeof e=="function"}function fs(e){return!Fa(e,this.v)}let Oa=!1,Ce=null;function pn(e){Ce=e}function mt(e,t=!1,n){Ce={p:Ce,i:!1,c:null,e:null,s:e,x:null,r:L,l:null}}function gt(e){var t=Ce,n=t.e;if(n!==null){t.e=null;for(var r of n)js(r)}return t.i=!0,Ce=t.p,{}}function vs(){return!0}let nn=[];function Ia(){var e=nn;nn=[],ua(e)}function St(e){if(nn.length===0){var t=nn;queueMicrotask(()=>{t===nn&&Ia()})}nn.push(e)}function cs(e){var t=L;if(t===null)return P.f|=qt,e;if((t.f&kn)===0&&(t.f&Dn)===0)throw e;At(e,t)}function At(e,t){if(!(t!==null&&(t.f&Ke)!==0)){for(;t!==null;){if((t.f&gr)!==0){if((t.f&kn)===0)throw e;try{t.b.error(e);return}catch(n){e=n}}t=t.parent}throw e}}const za=-7169;function ue(e,t){e.f=e.f&za|t}function Rr(e){(e.f&Ye)!==0||e.deps===null?ue(e,_e):ue(e,nt)}function ds(e){if(e!==null)for(const t of e)(t.f&pe)===0||(t.f&Jt)===0||(t.f^=Jt,ds(t.deps))}function hs(e,t,n){(e.f&de)!==0?t.add(e):(e.f&nt)!==0&&n.add(e),ds(e.deps),ue(e,_e)}function fr(e){var t=P,n=L;Ze(null),ft(null);try{return e()}finally{Ze(t),ft(n)}}function Pa(e){let t=0,n=Qt(0),r;return()=>{Or()&&(i(n),fi(()=>(t===0&&(r=hi(()=>e(()=>Mn(n)))),t+=1,()=>{St(()=>{t-=1,t===0&&(r==null||r(),r=void 0,Mn(n))})})))}}var La=_n|yn;function Wa(e,t,n,r){new Ba(e,t,n,r)}var We,jr,Be,Wt,Te,He,xe,Ne,ct,Bt,Et,on,zn,Pn,dt,ar,ie,Ha,Ua,yr,Va,wr,Jn,Zn,br,xr;class Ba{constructor(t,n,r,s){N(this,ie);je(this,"parent");je(this,"is_pending",!1);je(this,"transform_error");N(this,We);N(this,jr,null);N(this,Be);N(this,Wt);N(this,Te);N(this,He,null);N(this,xe,null);N(this,Ne,null);N(this,ct,null);N(this,Bt,0);N(this,Et,0);N(this,on,!1);N(this,zn,new Set);N(this,Pn,new Set);N(this,dt,null);N(this,ar,Pa(()=>(C(this,dt,Qt(v(this,Bt))),()=>{C(this,dt,null)})));var a;C(this,We,t),C(this,Be,n),C(this,Wt,o=>{var u=L;u.b=this,u.f|=gr,r(o)}),this.parent=L.b,this.transform_error=s??((a=this.parent)==null?void 0:a.transform_error)??(o=>o),C(this,Te,Ir(()=>{B(this,ie,wr).call(this)},La))}defer_effect(t){hs(t,v(this,zn),v(this,Pn))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!v(this,Be).pending}update_pending_count(t,n){B(this,ie,br).call(this,t,n),C(this,Bt,v(this,Bt)+t),!(!v(this,dt)||v(this,on))&&(C(this,on,!0),St(()=>{C(this,on,!1),v(this,dt)&&mn(v(this,dt),v(this,Bt))}))}get_effect_pending(){return v(this,ar).call(this),i(v(this,dt))}error(t){if(!v(this,Be).onerror&&!v(this,Be).failed)throw t;q!=null&&q.is_fork?(v(this,He)&&q.skip_effect(v(this,He)),v(this,xe)&&q.skip_effect(v(this,xe)),v(this,Ne)&&q.skip_effect(v(this,Ne)),q.oncommit(()=>{B(this,ie,xr).call(this,t)})):B(this,ie,xr).call(this,t)}}We=new WeakMap,jr=new WeakMap,Be=new WeakMap,Wt=new WeakMap,Te=new WeakMap,He=new WeakMap,xe=new WeakMap,Ne=new WeakMap,ct=new WeakMap,Bt=new WeakMap,Et=new WeakMap,on=new WeakMap,zn=new WeakMap,Pn=new WeakMap,dt=new WeakMap,ar=new WeakMap,ie=new WeakSet,Ha=function(){try{C(this,He,Ue(()=>v(this,Wt).call(this,v(this,We))))}catch(t){this.error(t)}},Ua=function(t){const n=v(this,Be).failed,{reset:r,invoke_onerror:s}=B(this,ie,yr).call(this,t);St(s),n&&C(this,Ne,Ue(()=>{n(v(this,We),()=>t,()=>r)}))},yr=function(t){var n=!1,r=!1;const s=()=>{if(n){Da();return}n=!0,r&&xa(),v(this,Ne)!==null&&Yt(v(this,Ne),()=>{C(this,Ne,null)}),B(this,ie,Zn).call(this,()=>{B(this,ie,wr).call(this)})};return{reset:s,invoke_onerror:()=>{var o,u;try{r=!0,(u=(o=v(this,Be)).onerror)==null||u.call(o,t,s),r=!1}catch(f){At(f,v(this,Te)&&v(this,Te).parent)}}}},Va=function(){const t=v(this,Be).pending;t&&(this.is_pending=!0,C(this,xe,Ue(()=>t(v(this,We)))),St(()=>{var n=C(this,ct,document.createDocumentFragment()),r=jt();n.append(r),C(this,He,B(this,ie,Zn).call(this,()=>Ue(()=>v(this,Wt).call(this,r)))),v(this,Et)===0&&(v(this,We).before(n),C(this,ct,null),Yt(v(this,xe),()=>{C(this,xe,null)}),B(this,ie,Jn).call(this,q))}))},wr=function(){try{if(this.is_pending=this.has_pending_snippet(),C(this,Et,0),C(this,Bt,0),C(this,He,Ue(()=>{v(this,Wt).call(this,v(this,We))})),v(this,Et)>0){var t=C(this,ct,document.createDocumentFragment());Pr(v(this,He),t);const n=v(this,Be).pending;C(this,xe,Ue(()=>n(v(this,We))))}else B(this,ie,Jn).call(this,q)}catch(n){this.error(n)}},Jn=function(t){this.is_pending=!1,t.transfer_effects(v(this,zn),v(this,Pn))},Zn=function(t){var n=L,r=P,s=Ce;ft(v(this,Te)),Ze(v(this,Te)),pn(v(this,Te).ctx);try{return Zt.ensure(),t()}catch(a){return cs(a),null}finally{ft(n),Ze(r),pn(s)}},br=function(t,n){var r;if(!this.has_pending_snippet()){this.parent&&B(r=this.parent,ie,br).call(r,t,n);return}C(this,Et,v(this,Et)+t),v(this,Et)===0&&(B(this,ie,Jn).call(this,n),v(this,xe)&&Yt(v(this,xe),()=>{C(this,xe,null)}),v(this,ct)&&(v(this,We).before(v(this,ct)),C(this,ct,null)))},xr=function(t){v(this,He)&&(qe(v(this,He)),C(this,He,null)),v(this,xe)&&(qe(v(this,xe)),C(this,xe,null)),v(this,Ne)&&(qe(v(this,Ne)),C(this,Ne,null));let n=v(this,Be).failed;const r=s=>{const{reset:a,invoke_onerror:o}=B(this,ie,yr).call(this,s);o(),n&&C(this,Ne,B(this,ie,Zn).call(this,()=>{try{return Ue(()=>{var u=L;u.b=this,u.f|=gr,n(v(this,We),()=>s,()=>a)})}catch(u){return At(u,v(this,Te).parent),null}}))};St(()=>{var s;try{s=this.transform_error(t)}catch(a){At(a,v(this,Te)&&v(this,Te).parent);return}s!==null&&typeof s=="object"&&typeof s.then=="function"?s.then(r,a=>At(a,v(this,Te)&&v(this,Te).parent)):r(s)})};function Ga(e,t,n,r){const s=Nr;var a=e.filter(p=>!p.settled),o=t.map(s);if(n.length===0&&a.length===0){r(o);return}var u=L,f=Ya(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(p=>p.promise)):null;function _(p){if((u.f&Ke)===0){f();try{r([...o,...p])}catch(k){At(k,u)}nr()}}var m=_s();if(n.length===0){l.then(()=>_([])).finally(m);return}function c(){Promise.all(n.map(p=>Ka(p))).then(_).catch(p=>At(p,u)).finally(m)}l?l.then(()=>{f(),c(),nr()}):c()}function Ya(){var e=L,t=P,n=Ce,r=q;return function(a=!0){ft(e),Ze(t),pn(n),a&&(e.f&Ke)===0&&(r==null||r.activate(),r==null||r.apply())}}function nr(e=!0){ft(null),Ze(null),pn(null),e&&(q==null||q.deactivate())}function _s(){var e=L,t=e.b,n=q,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 Nr(e){var t=pe|de;return L!==null&&(L.f|=yn),{ctx:Ce,deps:null,effects:null,equals:us,f:t,fn:e,reactions:null,rv:0,v:he,wv:0,parent:L,ac:null}}const An=Symbol("obsolete");function Ka(e,t,n){let r=L;r===null&&ha();var s=void 0,a=Qt(he),o=!P,u=new Set;return ui(()=>{var p,k;var f=L,l=is();s=l.promise;try{Promise.resolve(e()).then(l.resolve,y=>{y!==Hn&&l.reject(y)}).finally(nr)}catch(y){l.reject(y),nr()}var _=q;if(o){if((f.f&kn)!==0)var m=_s();if((p=r.b)!=null&&p.is_rendered())(k=_.async_deriveds.get(f))==null||k.reject(An);else for(const y of u.values())y.reject(An);u.add(l),_.async_deriveds.set(f,l)}const c=(y,g=void 0)=>{m==null||m(),u.delete(l),g!==An&&(_.activate(),g?(a.f|=qt,mn(a,g)):((a.f&qt)!==0&&(a.f^=qt),mn(a,y)),_.deactivate())};l.promise.then(c,y=>c(null,y||"unknown"))}),li(()=>{for(const f of u)f.reject(An)}),new Promise(f=>{function l(_){function m(){_===s?f(a):l(s)}_.then(m,m)}l(s)})}function Ge(e){const t=Nr(e);return Os(t),t}function Ja(e){const t=Nr(e);return t.equals=fs,t}function Za(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n<t.length;n+=1)qe(t[n])}}function Mr(e){var t,n=L,r=e.parent;if(!Nt&&r!==null&&e.v!==he&&(r.f&(Ke|Ee))!==0)return Ma(),e.v;ft(r);try{e.f&=~Jt,Za(e),t=Ls(e)}finally{ft(n)}return t}function ps(e){var t=Mr(e);if(!e.equals(t)&&(e.wv=zs(),(!(q!=null&&q.is_fork)||e.deps===null)&&(q!==null?(q.capture(e,t,!0),Nn==null||Nn.capture(e,t,!0)):e.v=t,e.deps===null))){ue(e,_e);return}Nt||(me!==null?(Or()||q!=null&&q.is_fork)&&me.set(e,t):Rr(e))}function Qa(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&&fr(()=>{n.ac.abort(Hn),n.ac=null}),n.fn!==null&&(n.teardown=oa),Fn(n,0),zr(n))}function ms(e){if(e.effects!==null)for(const t of e.effects)t.teardown&&t.fn!==null&&gn(t)}let dr=null,en=null,q=null,Nn=null,me=null,Er=null,hr=!1,rn=null,Qn=null;var Hr=0;let Xa=1;var un,Tt,Ht,fn,vn,cn,ht,dn,Se,Ln,_t,Xe,it,hn,Ut,X,Tr,Cn,Sr,gs,ks,tn,$a,qn;const ir=class ir{constructor(){N(this,X);je(this,"id",Xa++);N(this,un,!1);je(this,"linked",!0);N(this,Tt,null);N(this,Ht,null);je(this,"async_deriveds",new Map);je(this,"current",new Map);je(this,"previous",new Map);N(this,fn,new Set);N(this,vn,new Set);N(this,cn,0);N(this,ht,new Map);N(this,dn,null);N(this,Se,[]);N(this,Ln,[]);N(this,_t,new Set);N(this,Xe,new Set);N(this,it,new Map);N(this,hn,new Set);je(this,"is_fork",!1);N(this,Ut,!1);en===null?dr=en=this:(C(en,Ht,this),C(this,Tt,en)),en=this}skip_effect(t){v(this,it).has(t)||v(this,it).set(t,{d:[],m:[]}),v(this,hn).delete(t)}unskip_effect(t,n=r=>this.schedule(r)){var r=v(this,it).get(t);if(r){v(this,it).delete(t);for(var s of r.d)ue(s,de),n(s);for(s of r.m)ue(s,nt),n(s)}v(this,hn).add(t)}capture(t,n,r=!1){t.v!==he&&!this.previous.has(t)&&this.previous.set(t,t.v),(t.f&qt)===0&&(this.current.set(t,[n,r]),me==null||me.set(t,n)),this.is_fork||(t.v=n)}activate(){q=this}deactivate(){q=null,me=null}flush(){try{hr=!0,q=this,B(this,X,Cn).call(this)}finally{Hr=0,Er=null,rn=null,Qn=null,hr=!1,q=null,me=null,Gt.clear()}}discard(){var t;for(const n of v(this,vn))n(this);v(this,vn).clear();for(const n of this.async_deriveds.values())n.reject(An);B(this,X,qn).call(this),(t=v(this,dn))==null||t.resolve()}register_created_effect(t){v(this,Ln).push(t)}increment(t,n){if(C(this,cn,v(this,cn)+1),t){let r=v(this,ht).get(n)??0;v(this,ht).set(n,r+1)}}decrement(t,n){if(C(this,cn,v(this,cn)-1),t){let r=v(this,ht).get(n)??0;r===1?v(this,ht).delete(n):v(this,ht).set(n,r-1)}v(this,Ut)||(C(this,Ut,!0),St(()=>{C(this,Ut,!1),this.linked&&this.flush()}))}transfer_effects(t,n){for(const r of t)v(this,_t).add(r);for(const r of n)v(this,Xe).add(r);t.clear(),n.clear()}oncommit(t){v(this,fn).add(t)}ondiscard(t){v(this,vn).add(t)}settled(){return(v(this,dn)??C(this,dn,is())).promise}static ensure(){if(q===null){const t=q=new ir;hr||St(()=>{v(t,un)||t.flush()})}return q}apply(){{me=null;return}}schedule(t){var s;if(Er=t,(s=t.b)!=null&&s.is_pending&&(t.f&(Dn|ur|ls))!==0&&(t.f&kn)===0){t.b.defer_effect(t);return}for(var n=t;n.parent!==null;){n=n.parent;var r=n.f;if(rn!==null&&n===L&&(P===null||(P.f&pe)===0))return;if((r&(pt|Je))!==0){if((r&_e)===0)return;n.f^=_e}}v(this,Se).push(n)}};un=new WeakMap,Tt=new WeakMap,Ht=new WeakMap,fn=new WeakMap,vn=new WeakMap,cn=new WeakMap,ht=new WeakMap,dn=new WeakMap,Se=new WeakMap,Ln=new WeakMap,_t=new WeakMap,Xe=new WeakMap,it=new WeakMap,hn=new WeakMap,Ut=new WeakMap,X=new WeakSet,Tr=function(){if(this.is_fork)return!0;for(const r of v(this,ht).keys()){for(var t=r,n=!1;t.parent!==null;){if(v(this,it).has(t)){n=!0;break}t=t.parent}if(!n)return!0}return!1},Cn=function(){var f,l,_,m;C(this,un,!0),Hr++>1e3&&(B(this,X,qn).call(this),ei());for(const c of v(this,_t))v(this,Xe).delete(c),ue(c,de),this.schedule(c);for(const c of v(this,Xe))ue(c,nt),this.schedule(c);const t=v(this,Se);C(this,Se,[]),this.apply();var n=rn=[],r=[],s=Qn=[];for(const c of t)try{B(this,X,Sr).call(this,c,n,r)}catch(p){throw bs(c),B(this,X,Tr).call(this)||this.discard(),p}if(q=null,s.length>0){var a=ir.ensure();for(const c of s)a.schedule(c)}if(rn=null,Qn=null,B(this,X,Tr).call(this)){B(this,X,tn).call(this,r),B(this,X,tn).call(this,n);for(const[c,p]of v(this,it))ws(c,p);s.length>0&&B(f=q,X,Cn).call(f);return}const o=B(this,X,gs).call(this);if(o){B(this,X,tn).call(this,r),B(this,X,tn).call(this,n),B(l=o,X,ks).call(l,this);return}v(this,_t).clear(),v(this,Xe).clear();for(const c of v(this,fn))c(this);v(this,fn).clear(),Nn=this,Ur(r),Ur(n),Nn=null,(_=v(this,dn))==null||_.resolve();var u=q;if(v(this,cn)===0&&(v(this,Se).length===0||u!==null)&&B(this,X,qn).call(this),v(this,Se).length>0)if(u!==null){const c=u;v(c,Se).push(...v(this,Se).filter(p=>!v(c,Se).includes(p)))}else u=this;u!==null&&B(m=u,X,Cn).call(m)},Sr=function(t,n,r){t.f^=_e;for(var s=t.first;s!==null;){var a=s.f,o=(a&(Je|pt))!==0,u=o&&(a&_e)!==0,f=u||(a&Ee)!==0||v(this,it).has(s);if(!f&&s.fn!==null){o?s.f^=_e:(a&Dn)!==0?n.push(s):Vn(s)&&((a&et)!==0&&v(this,Xe).add(s),gn(s));var l=s.first;if(l!==null){s=l;continue}}for(;s!==null;){var _=s.next;if(_!==null){s=_;break}s=s.parent}}},gs=function(){for(var t=v(this,Tt);t!==null;){if(!t.is_fork){for(const[n,[,r]]of this.current)if(t.current.has(n)&&!r)return t}t=v(t,Tt)}return null},ks=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(v(t,_t),v(t,Xe));const n=s=>{var a=s.reactions;if(a!==null&&!((s.f&pe)!==0&&(s.f&(de|nt))===0))for(const f of a){var o=f.f;if((o&pe)!==0)n(f);else{var u=f;o&(ln|et)&&!this.async_deriveds.has(u)&&(v(this,Xe).delete(u),ue(u,de),this.schedule(u))}}};for(const s of this.current.keys())n(s);this.oncommit(()=>t.discard()),B(r=t,X,qn).call(r),q=this,B(this,X,Cn).call(this)},tn=function(t){for(var n=0;n<t.length;n+=1)hs(t[n],v(this,_t),v(this,Xe))},$a=function(){var m;for(let c=dr;c!==null;c=v(c,Ht)){var t=c.id<this.id,n=[];for(const[p,[k,y]]of this.current){if(c.current.has(p)){var r=c.current.get(p)[0];if(t&&k!==r)c.current.set(p,[k,y]);else continue}n.push(p)}if(t)for(const[p,k]of this.async_deriveds){const y=c.async_deriveds.get(p);y&&k.promise.then(y.resolve).catch(y.reject)}var s=[...c.current.keys()].filter(p=>!c.current.get(p)[1]);if(!(!v(c,un)||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 v(this,hn))c.unskip_effect(p,k=>{var y;(k.f&(et|ln))!==0?c.schedule(k):B(y=c,X,tn).call(y,[k])});c.activate();var o=new Set,u=new Map;for(var f of n)ys(f,a,o,u);u=new Map;var l=[...c.current].filter(([p,k])=>{const y=this.current.get(p);return y?y[0]!==k[0]||y[1]!==k[1]:!0}).map(([p])=>p);if(l.length>0)for(const p of v(this,Ln))(p.f&(Ke|Ee|er))===0&&Dr(p,l,u)&&((p.f&(ln|et))!==0?(ue(p,de),c.schedule(p)):v(c,_t).add(p));if(v(c,Se).length>0&&!v(c,Ut)){c.apply();for(var _ of v(c,Se))B(m=c,X,Sr).call(m,_,[],[]);C(c,Se,[])}c.deactivate()}}}},qn=function(){if(this.linked){var t=v(this,Tt),n=v(this,Ht);t===null?dr=n:C(t,Ht,n),n===null?en=t:C(n,Tt,t),this.linked=!1}};let Zt=ir;function ei(){try{ka()}catch(e){At(e,Er)}}let Qe=null;function Ur(e){var t=e.length;if(t!==0){for(var n=0;n<t;){var r=e[n++];if((r.f&(Ke|Ee))===0&&Vn(r)&&(Qe=new Set,gn(r),r.deps===null&&r.first===null&&r.nodes===null&&r.teardown===null&&r.ac===null&&Ms(r),(Qe==null?void 0:Qe.size)>0)){Gt.clear();for(const s of Qe){if((s.f&(Ke|Ee))!==0)continue;const a=[s];let o=s.parent;for(;o!==null;)Qe.has(o)&&(Qe.delete(o),a.push(o)),o=o.parent;for(let u=a.length-1;u>=0;u--){const f=a[u];(f.f&(Ke|Ee))===0&&gn(f)}}Qe.clear()}}Qe=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&pe)!==0?ys(s,t,n,r):(a&(ln|et))!==0&&(a&de)===0&&Dr(s,t,r)&&(ue(s,de),Fr(s))}}function Dr(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($n.call(t,s))return!0;if((s.f&pe)!==0&&Dr(s,t,n))return n.set(s,!0),!0}return n.set(e,!1),!1}function Fr(e){q.schedule(e)}function ws(e,t){if(!((e.f&Je)!==0&&(e.f&_e)!==0)){(e.f&de)!==0?t.d.push(e):(e.f&nt)!==0&&t.m.push(e),ue(e,_e);for(var n=e.first;n!==null;)ws(n,t),n=n.next}}function bs(e){ue(e,_e);for(var t=e.first;t!==null;)bs(t),t=t.next}let rr=new Set;const Gt=new Map;let xs=!1;function Qt(e,t){var n={f:0,v:e,reactions:null,equals:us,rv:0,wv:0};return n}function ce(e,t){const n=Qt(e);return Os(n),n}function ti(e,t=!1,n=!0){const r=Qt(e);return t||(r.equals=fs),r}function z(e,t,n=!1){P!==null&&(!tt||(P.f&er)!==0)&&vs()&&(P.f&(pe|et|ln|er))!==0&&(ut===null||!ut.has(e))&&ba();let r=n?zt(t):t;return mn(e,r,Qn)}function mn(e,t,n=null){if(!e.equals(t)){Gt.set(e,Nt?t:e.v);var r=Zt.ensure();if(r.capture(e,t),(e.f&pe)!==0){const s=e;(e.f&de)!==0&&Mr(s),me===null&&Rr(s)}e.wv=zs(),Es(e,de,n),L!==null&&(L.f&_e)!==0&&(L.f&(Je|pt))===0&&(Le===null?ci([e]):Le.push(e)),!r.is_fork&&rr.size>0&&!xs&&ni()}return t}function ni(){xs=!1;for(const e of rr){(e.f&_e)!==0&&ue(e,nt);let t;try{t=Vn(e)}catch{t=!0}t&&gn(e)}rr.clear()}function Mn(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],u=o.f,f=(u&de)===0;if(f&&ue(o,t),(u&er)!==0)rr.add(o);else if((u&pe)!==0){var l=o;me==null||me.delete(l),(u&Jt)===0&&(u&Ye&&(L===null||(L.f&tr)===0)&&(o.f|=Jt),Es(l,nt,n))}else if(f){var _=o;(u&et)!==0&&Qe!==null&&Qe.add(_),n!==null?n.push(_):Fr(_)}}}function zt(e){if(typeof e!="object"||e===null||cr in e)return e;const t=la(e);if(t!==aa&&t!==ia)return e;var n=new Map,r=as(e),s=ce(0),a=Kt,o=u=>{if(Kt===a)return u();var f=P,l=Kt;Ze(null),Yr(a);var _=u();return Ze(f),Yr(l),_};return r&&n.set("length",ce(e.length)),new Proxy(e,{defineProperty(u,f,l){(!("value"in l)||l.configurable===!1||l.enumerable===!1||l.writable===!1)&&ya();var _=n.get(f);return _===void 0?o(()=>{var m=ce(l.value);return n.set(f,m),m}):z(_,l.value,!0),!0},deleteProperty(u,f){var l=n.get(f);if(l===void 0){if(f in u){const _=o(()=>ce(he));n.set(f,_),Mn(s)}}else z(l,he),Mn(s);return!0},get(u,f,l){var p;if(f===cr)return e;var _=n.get(f),m=f in u;if(_===void 0&&(!m||(p=Rn(u,f))!=null&&p.writable)&&(_=o(()=>{var k=zt(m?u[f]:he),y=ce(k);return y}),n.set(f,_)),_!==void 0){var c=i(_);return c===he?void 0:c}return Reflect.get(u,f,l)},getOwnPropertyDescriptor(u,f){var l=Reflect.getOwnPropertyDescriptor(u,f);if(l&&"value"in l){var _=n.get(f);_&&(l.value=i(_))}else if(l===void 0){var m=n.get(f),c=m==null?void 0:m.v;if(m!==void 0&&c!==he)return{enumerable:!0,configurable:!0,value:c,writable:!0}}return l},has(u,f){var c;if(f===cr)return!0;var l=n.get(f),_=l!==void 0&&l.v!==he||Reflect.has(u,f);if(l!==void 0||L!==null&&(!_||(c=Rn(u,f))!=null&&c.writable)){l===void 0&&(l=o(()=>{var p=_?zt(u[f]):he,k=ce(p);return k}),n.set(f,l));var m=i(l);if(m===he)return!1}return _},set(u,f,l,_){var j;var m=n.get(f),c=f in u;if(r&&f==="length")for(var p=l;p<m.v;p+=1){var k=n.get(p+"");k!==void 0?z(k,he):p in u&&(k=o(()=>ce(he)),n.set(p+"",k))}if(m===void 0)(!c||(j=Rn(u,f))!=null&&j.writable)&&(m=o(()=>ce(void 0)),z(m,zt(l)),n.set(f,m));else{c=m.v!==he;var y=o(()=>zt(l));z(m,y)}var g=Reflect.getOwnPropertyDescriptor(u,f);if(g!=null&&g.set&&g.set.call(_,l),!c){if(r&&typeof f=="string"){var E=n.get("length"),F=Number(f);Number.isInteger(F)&&F>=E.v&&z(E,F+1)}Mn(s)}return!0},ownKeys(u){i(s);var f=Reflect.ownKeys(u).filter(m=>{var c=n.get(m);return c===void 0||c.v!==he});for(var[l,_]of n)_.v!==he&&!(l in u)&&f.push(l);return f},setPrototypeOf(){wa()}})}var Vr,Ts,Ss,As;function ri(){if(Vr===void 0){Vr=window,Ts=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;Ss=Rn(t,"firstChild").get,As=Rn(t,"nextSibling").get,Wr(e)&&(e[kr]=void 0,e[ca]=null,e[da]=void 0,e.__e=void 0),Wr(n)&&(n[Sn]=void 0)}}function jt(e=""){return document.createTextNode(e)}function Ct(e){return Ss.call(e)}function Un(e){return As.call(e)}function d(e,t){return Ct(e)}function we(e,t=!1){{var n=Ct(e);return n instanceof Comment&&n.data===""?Un(n):n}}function h(e,t=1,n=!1){let r=e;for(;t--;)r=Un(r);return r}function si(e){e.textContent=""}function Cs(){return!1}function qs(e,t,n){return t==null||t===ja?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function ai(e){L===null&&(P===null&&ga(),ma()),Nt&&pa()}function ii(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function Mt(e,t){var n=L;n!==null&&(n.f&Ee)!==0&&(e|=Ee);var r={ctx:Ce,deps:null,nodes:null,f:e|de|Ye,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};q==null||q.register_created_effect(r);var s=r;if((e&Dn)!==0)rn!==null?rn.push(r):Zt.ensure().schedule(r);else if(t!==null){try{gn(r)}catch(o){throw qe(r),o}s.deps===null&&s.teardown===null&&s.nodes===null&&s.first===s.last&&(s.f&yn)===0&&(s=s.first,(e&et)!==0&&(e&_n)!==0&&s!==null&&(s.f|=_n))}if(s!==null&&(s.parent=n,n!==null&&ii(s,n),P!==null&&(P.f&pe)!==0&&(e&pt)===0)){var a=P;(a.effects??(a.effects=[])).push(s)}return r}function Or(){return P!==null&&!tt}function li(e){const t=Mt(ur,null);return ue(t,_e),t.teardown=e,t}function _r(e){ai();var t=L.f,n=!P&&(t&Je)!==0&&Ce!==null&&!Ce.i;if(n){var r=Ce;(r.e??(r.e=[])).push(e)}else return js(e)}function js(e){return Mt(Dn|va,e)}function oi(e){Zt.ensure();const t=Mt(pt|yn,e);return(n={})=>new Promise(r=>{n.outro?Yt(t,()=>{qe(t),r(void 0)}):(qe(t),r(void 0))})}function ui(e){return Mt(ln|yn,e)}function fi(e,t=0){return Mt(ur|t,e)}function U(e,t=[],n=[],r=[]){Ga(r,t,n,s=>{Mt(ur,()=>{e(...s.map(i))})})}function Ir(e,t=0){var n=Mt(et|t,e);return n}function Ue(e){return Mt(Je|yn,e)}function Rs(e){var t=e.teardown;if(t!==null){const n=Nt,r=P;Gr(!0),Ze(null);try{t.call(null)}finally{Gr(n),Ze(r)}}}function zr(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){const s=n.ac;s!==null&&fr(()=>{s.abort(Hn)});var r=n.next;(n.f&pt)!==0?n.parent=null:qe(n,t),n=r}}function vi(e){for(var t=e.first;t!==null;){var n=t.next;(t.f&Je)===0&&qe(t),t=n}}function qe(e,t=!0){var n=!1;(t||(e.f&fa)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(Ns(e.nodes.start,e.nodes.end),n=!0),e.f|=Br,zr(e,t&&!n),Fn(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(const a of r)a.stop();Rs(e),e.f^=Br,e.f|=Ke;var s=e.parent;s!==null&&s.first!==null&&Ms(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Ns(e,t){for(;e!==null;){var n=e===t?null:Un(e);e.remove(),e=n}}function Ms(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 Yt(e,t,n=!0){var r=[];Ds(e,r,!0);var s=()=>{n&&qe(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||s();for(var u of r)u.out(o)}else s()}function Ds(e,t,n){if((e.f&Ee)===0){e.f^=Ee;var r=e.nodes&&e.nodes.t;if(r!==null)for(const u of r)(u.is_global||n)&&t.push(u);for(var s=e.first;s!==null;){var a=s.next;if((s.f&pt)===0){var o=(s.f&_n)!==0||(s.f&Je)!==0&&(e.f&et)!==0;Ds(s,t,o?n:!1)}s=a}}}function sr(e){Fs(e,!0)}function Fs(e,t){if((e.f&Ee)!==0){e.f^=Ee,(e.f&_e)===0&&(ue(e,de),Zt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,s=(n.f&_n)!==0||(n.f&Je)!==0;Fs(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 Pr(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var s=n===r?null:Un(n);t.append(n),n=s}}let Xn=!1,Nt=!1;function Gr(e){Nt=e}let P=null,tt=!1;function Ze(e){P=e}let L=null;function ft(e){L=e}let ut=null;function Os(e){P!==null&&(ut??(ut=new Set)).add(e)}let Ae=null,Re=0,Le=null;function ci(e){Le=e}let Is=1,Pt=0,Kt=Pt;function Yr(e){Kt=e}function zs(){return++Is}function Vn(e){var t=e.f;if((t&de)!==0)return!0;if(t&pe&&(e.f&=~Jt),(t&nt)!==0){for(var n=e.deps,r=n.length,s=0;s<r;s++){var a=n[s];if(Vn(a)&&ps(a),a.wv>e.wv)return!0}(t&Ye)!==0&&me===null&&ue(e,_e)}return!1}function Ps(e,t,n=!0){var r=e.reactions;if(r!==null&&!(ut!==null&&ut.has(e)))for(var s=0;s<r.length;s++){var a=r[s];(a.f&pe)!==0?Ps(a,t,!1):t===a&&(n?ue(a,de):(a.f&_e)!==0&&ue(a,nt),Fr(a))}}function Ls(e){var y;var t=Ae,n=Re,r=Le,s=P,a=ut,o=Ce,u=tt,f=Kt,l=e.f;Ae=null,Re=0,Le=null,P=(l&(Je|pt))===0?e:null,ut=null,pn(e.ctx),tt=!1,Kt=++Pt,e.ac!==null&&(fr(()=>{e.ac.abort(Hn)}),e.ac=null);try{e.f|=tr;var _=e.fn,m=_();e.f|=kn;var c=e.deps,p=q==null?void 0:q.is_fork;if(Ae!==null){var k;if(p||Fn(e,Re),c!==null&&Re>0)for(c.length=Re+Ae.length,k=0;k<Ae.length;k++)c[Re+k]=Ae[k];else e.deps=c=Ae;if(Or()&&(e.f&Ye)!==0)for(k=Re;k<c.length;k++)((y=c[k]).reactions??(y.reactions=[])).push(e)}else!p&&c!==null&&Re<c.length&&(Fn(e,Re),c.length=Re);if(vs()&&Le!==null&&!tt&&c!==null&&(e.f&(pe|nt|de))===0)for(k=0;k<Le.length;k++)Ps(Le[k],e);if(s!==null&&s!==e){if(Pt++,s.deps!==null)for(let g=0;g<n;g+=1)s.deps[g].rv=Pt;if(t!==null)for(const g of t)g.rv=Pt;Le!==null&&(r===null?r=Le:r.push(...Le))}return(e.f&qt)!==0&&(e.f^=qt),m}catch(g){return cs(g)}finally{e.f^=tr,Ae=t,Re=n,Le=r,P=s,ut=a,pn(o),tt=u,Kt=f}}function di(e,t){let n=t.reactions;if(n!==null){var r=ra.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&pe)!==0&&(Ae===null||!$n.call(Ae,t))){var a=t;(a.f&Ye)!==0&&(a.f^=Ye,a.f&=~Jt),a.v!==he&&Rr(a),a.ac!==null&&fr(()=>{a.ac.abort(Hn),a.ac=null,ue(a,de)}),Qa(a),Fn(a,0)}}function Fn(e,t){var n=e.deps;if(n!==null)for(var r=t;r<n.length;r++)di(e,n[r])}function gn(e){var t=e.f;if((t&Ke)===0){ue(e,_e);var n=L,r=Xn;L=e,Xn=(t&(Je|pt))===0;try{(t&(et|ls))!==0?vi(e):zr(e),Rs(e);var s=Ls(e);e.teardown=typeof s=="function"?s:null,e.wv=Is;var a;ss&&Oa&&(e.f&de)!==0&&e.deps}finally{Xn=r,L=n}}}function i(e){var t=e.f,n=(t&pe)!==0;if(P!==null&&!tt){var r=L!==null&&(L.f&Ke)!==0;if(!r&&(ut===null||!ut.has(e))){var s=P.deps;if((P.f&tr)!==0)e.rv<Pt&&(e.rv=Pt,Ae===null&&s!==null&&s[Re]===e?Re++:Ae===null?Ae=[e]:Ae.push(e));else{P.deps??(P.deps=[]),$n.call(P.deps,e)||P.deps.push(e);var a=e.reactions;a===null?e.reactions=[P]:$n.call(a,P)||a.push(P)}}}if(Nt&&Gt.has(e))return Gt.get(e);if(n){var o=e;if(Nt){var u=o.v;return((o.f&_e)===0&&o.reactions!==null||Bs(o))&&(u=Mr(o)),Gt.set(o,u),u}var f=(o.f&Ye)===0&&!tt&&P!==null&&(Xn||(P.f&Ye)!==0),l=(o.f&kn)===0;Vn(o)&&(f&&(o.f|=Ye),ps(o)),f&&!l&&(ms(o),Ws(o))}if(me!=null&&me.has(e))return me.get(e);if((e.f&qt)!==0)throw e.v;return e.v}function Ws(e){if(e.f|=Ye,e.deps!==null)for(const t of e.deps)(t.reactions??(t.reactions=[])).push(e),(t.f&pe)!==0&&(t.f&Ye)===0&&(ms(t),Ws(t))}function Bs(e){if(e.v===he)return!0;if(e.deps===null)return!1;for(const t of e.deps)if(Gt.has(t)||(t.f&pe)!==0&&Bs(t))return!0;return!1}function hi(e){var t=tt;try{return tt=!0,e()}finally{tt=t}}const _i=["touchstart","touchmove"];function pi(e){return _i.includes(e)}const Lt=Symbol("events"),Hs=new Set,Ar=new Set;function Ve(e,t,n){(t[Lt]??(t[Lt]={}))[e]=n}function Gn(e){for(var t=0;t<e.length;t++)Hs.add(e[t]);for(var n of Ar)n(e)}let Kr=null;function Jr(e){var y,g;var t=this,n=t.ownerDocument,r=e.type,s=((y=e.composedPath)==null?void 0:y.call(e))||[],a=s[0]||e.target;Kr=e;var o=0,u=Kr===e&&e[Lt];if(u){var f=s.indexOf(u);if(f!==-1&&(t===document||t===window)){e[Lt]=t;return}var l=s.indexOf(t);if(l===-1)return;f<=l&&(o=f)}if(a=s[o]||e.target,a!==t){sa(e,"currentTarget",{configurable:!0,get(){return a||n}});var _=P,m=L;Ze(null),ft(null);try{for(var c,p=[];a!==null&&a!==t;){try{var k=(g=a[Lt])==null?void 0:g[r];k!=null&&(!a.disabled||e.target===a)&&k.call(a,e)}catch(E){c?p.push(E):c=E}if(e.cancelBubble)break;o++,a=o<s.length?s[o]:null}if(c){for(let E of p)queueMicrotask(()=>{throw E});throw c}}finally{e[Lt]=t,delete e.currentTarget,Ze(_),ft(m)}}}var ts;const pr=((ts=globalThis==null?void 0:globalThis.window)==null?void 0:ts.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function mi(e){return(pr==null?void 0:pr.createHTML(e))??e}function gi(e){var t=qs("template");return t.innerHTML=mi(e.replaceAll("<!>","<!---->")),t.content}function On(e,t){var n=L;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function T(e,t){var n=(t&Ca)!==0,r=(t&qa)!==0,s,a=!e.startsWith("<!>");return()=>{s===void 0&&(s=gi(a?e:"<!>"+e),n||(s=Ct(s)));var o=r||Ts?document.importNode(s,!0):s.cloneNode(!0);if(n){var u=Ct(o),f=o.lastChild;On(u,f)}else On(o,o);return o}}function sn(){var e=document.createDocumentFragment(),t=document.createComment(""),n=jt();return e.append(t,n),On(t,n),e}function x(e,t){e!==null&&e.before(t)}function b(e,t){var n=t==null?"":typeof t=="object"?`${t}`:t;n!==(e[Sn]??(e[Sn]=e.nodeValue))&&(e[Sn]=n,e.nodeValue=`${n}`)}function ki(e,t){return yi(e,t)}const Kn=new Map;function yi(e,{target:t,anchor:n,props:r={},events:s,context:a,intro:o=!0,transformError:u}){ri();var f=void 0,l=oi(()=>{var _=n??t.appendChild(jt());Wa(_,{pending:()=>{}},p=>{mt({});var k=Ce;a&&(k.c=a),s&&(r.$$events=s),f=e(p,r)||{},gt()},u);var m=new Set,c=p=>{for(var k=0;k<p.length;k++){var y=p[k];if(!m.has(y)){m.add(y);var g=pi(y);for(const j of[t,document]){var E=Kn.get(j);E===void 0&&(E=new Map,Kn.set(j,E));var F=E.get(y);F===void 0?(j.addEventListener(y,Jr,{passive:g}),E.set(y,1)):E.set(y,F+1)}}}};return c(or(Hs)),Ar.add(c),()=>{var g;for(var p of m)for(const E of[t,document]){var k=Kn.get(E),y=k.get(p);--y==0?(E.removeEventListener(p,Jr),k.delete(p),k.size===0&&Kn.delete(E)):k.set(p,y)}Ar.delete(c),_!==n&&((g=_.parentNode)==null||g.removeChild(_))}});return wi.set(f,l),f}let wi=new WeakMap;var $e,lt,Me,Vt,Wn,Bn,lr;class bi{constructor(t,n=!0){je(this,"anchor");N(this,$e,new Map);N(this,lt,new Map);N(this,Me,new Map);N(this,Vt,new Set);N(this,Wn,!0);N(this,Bn,t=>{if(v(this,$e).has(t)){var n=v(this,$e).get(t),r=v(this,lt).get(n);if(r)sr(r),v(this,Vt).delete(n);else{var s=v(this,Me).get(n);s&&(sr(s.effect),v(this,lt).set(n,s.effect),v(this,Me).delete(n),s.fragment.lastChild.remove(),this.anchor.before(s.fragment),r=s.effect)}for(const[a,o]of v(this,$e)){if(v(this,$e).delete(a),a===t)break;const u=v(this,Me).get(o);u&&(qe(u.effect),v(this,Me).delete(o))}for(const[a,o]of v(this,lt)){if(a===n||v(this,Vt).has(a))continue;const u=()=>{if(Array.from(v(this,$e).values()).includes(a)){var l=document.createDocumentFragment();Pr(o,l),l.append(jt()),v(this,Me).set(a,{effect:o,fragment:l})}else qe(o);v(this,Vt).delete(a),v(this,lt).delete(a)};v(this,Wn)||!r?(v(this,Vt).add(a),Yt(o,u,!1)):u()}}});N(this,lr,t=>{v(this,$e).delete(t);const n=Array.from(v(this,$e).values());for(const[r,s]of v(this,Me))n.includes(r)||(qe(s.effect),v(this,Me).delete(r))});this.anchor=t,C(this,Wn,n)}ensure(t,n){var r=q,s=Cs();if(n&&!v(this,lt).has(t)&&!v(this,Me).has(t))if(s){var a=document.createDocumentFragment(),o=jt();a.append(o),v(this,Me).set(t,{effect:Ue(()=>n(o)),fragment:a})}else v(this,lt).set(t,Ue(()=>n(this.anchor)));if(v(this,$e).set(r,t),s){for(const[u,f]of v(this,lt))u===t?r.unskip_effect(f):r.skip_effect(f);for(const[u,f]of v(this,Me))u===t?r.unskip_effect(f.effect):r.skip_effect(f.effect);r.oncommit(v(this,Bn)),r.ondiscard(v(this,lr))}else v(this,Bn).call(this,r)}}$e=new WeakMap,lt=new WeakMap,Me=new WeakMap,Vt=new WeakMap,Wn=new WeakMap,Bn=new WeakMap,lr=new WeakMap;function G(e,t,n=!1){var r=new bi(e),s=n?_n:0;function a(o,u){r.ensure(o,u)}Ir(()=>{var o=!1;t((u,f=0)=>{o=!0,a(f,u)}),o||a(-1,null)},s)}function In(e,t){return t}function xi(e,t,n){for(var r=[],s=t.length,a,o=t.length,u=0;u<s;u++){let m=t[u];Yt(m,()=>{if(a){if(a.pending.delete(m),a.done.add(m),a.pending.size===0){var c=e.outrogroups;Cr(e,or(a.done)),c.delete(a),c.size===0&&(e.outrogroups=null)}}else o-=1},!1)}if(o===0){var f=r.length===0&&n!==null;if(f){var l=n,_=l.parentNode;si(_),_.append(l),e.items.clear()}Cr(e,t,!f)}else a={pending:new Set(t),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(a)}function Cr(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(const o of e.pending.values())for(const u of o)r.add(e.items.get(u).e)}for(var s=0;s<t.length;s++){var a=t[s];if(r!=null&&r.has(a)){a.f|=ot;const o=document.createDocumentFragment();Pr(a,o)}else qe(t[s],n)}}var Zr;function De(e,t,n,r,s,a=null){var o=e,u=new Map,f=(t&os)!==0;if(f){var l=e;o=l.appendChild(jt())}var _=null,m=Ja(()=>{var j=n();return as(j)?j:j==null?[]:or(j)}),c,p=new Map,k=!0;function y(j){(F.effect.f&Ke)===0&&(F.pending.delete(j),F.fallback=_,Ei(F,c,o,t,r),_!==null&&(c.length===0?(_.f&ot)===0?sr(_):(_.f^=ot,jn(_,null,o)):Yt(_,()=>{_=null})))}function g(j){F.pending.delete(j)}var E=Ir(()=>{c=i(m);for(var j=c.length,S=new Set,A=q,J=Cs(),Y=0;Y<j;Y+=1){var Z=c[Y],$=r(Z,Y),V=k?null:u.get($);V?(V.v&&mn(V.v,Z),V.i&&mn(V.i,Y),J&&A.unskip_effect(V.e)):(V=Ti(u,k?o:Zr??(Zr=jt()),Z,$,Y,s,t,n),k||(V.e.f|=ot),u.set($,V)),S.add($)}if(j===0&&a&&!_&&(k?_=Ue(()=>a(o)):(_=Ue(()=>a(Zr??(Zr=jt()))),_.f|=ot)),j>S.size&&_a(),!k)if(p.set(A,S),J){for(const[ne,re]of u)S.has(ne)||A.skip_effect(re.e);A.oncommit(y),A.ondiscard(g)}else y(A);i(m)}),F={effect:E,items:u,pending:p,outrogroups:null,fallback:_};k=!1}function En(e){for(;e!==null&&(e.f&Je)===0;)e=e.next;return e}function Ei(e,t,n,r,s){var V,ne,re,O,R,fe,W,ee,se;var a=(r&Sa)!==0,o=t.length,u=e.items,f=En(e.effect.first),l,_=null,m,c=[],p=[],k,y,g,E;if(a)for(E=0;E<o;E+=1)k=t[E],y=s(k,E),g=u.get(y).e,(g.f&ot)===0&&((ne=(V=g.nodes)==null?void 0:V.a)==null||ne.measure(),(m??(m=new Set)).add(g));for(E=0;E<o;E+=1){if(k=t[E],y=s(k,E),g=u.get(y).e,e.outrogroups!==null)for(const K of e.outrogroups)K.pending.delete(g),K.done.delete(g);if((g.f&Ee)!==0&&(sr(g),a&&((O=(re=g.nodes)==null?void 0:re.a)==null||O.unfix(),(m??(m=new Set)).delete(g))),(g.f&ot)!==0)if(g.f^=ot,g===f)jn(g,null,n);else{var F=_?_.next:f;g===e.effect.last&&(e.effect.last=g.prev),g.prev&&(g.prev.next=g.next),g.next&&(g.next.prev=g.prev),xt(e,_,g),xt(e,g,F),jn(g,F,n),_=g,c=[],p=[],f=En(_.next);continue}if(g!==f){if(l!==void 0&&l.has(g)){if(c.length<p.length){var j=p[0],S;_=j.prev;var A=c[0],J=c[c.length-1];for(S=0;S<c.length;S+=1)jn(c[S],j,n);for(S=0;S<p.length;S+=1)l.delete(p[S]);xt(e,A.prev,J.next),xt(e,_,A),xt(e,J,j),f=j,_=J,E-=1,c=[],p=[]}else l.delete(g),jn(g,f,n),xt(e,g.prev,g.next),xt(e,g,_===null?e.effect.first:_.next),xt(e,_,g),_=g;continue}for(c=[],p=[];f!==null&&f!==g;)(l??(l=new Set)).add(f),p.push(f),f=En(f.next);if(f===null)continue}(g.f&ot)===0&&c.push(g),_=g,f=En(g.next)}if(e.outrogroups!==null){for(const K of e.outrogroups)K.pending.size===0&&(Cr(e,or(K.done)),(R=e.outrogroups)==null||R.delete(K));e.outrogroups.size===0&&(e.outrogroups=null)}if(f!==null||l!==void 0){var Y=[];if(l!==void 0)for(g of l)(g.f&Ee)===0&&Y.push(g);for(;f!==null;)(f.f&Ee)===0&&f!==e.fallback&&Y.push(f),f=En(f.next);var Z=Y.length;if(Z>0){var $=(r&os)!==0&&o===0?n:null;if(a){for(E=0;E<Z;E+=1)(W=(fe=Y[E].nodes)==null?void 0:fe.a)==null||W.measure();for(E=0;E<Z;E+=1)(se=(ee=Y[E].nodes)==null?void 0:ee.a)==null||se.fix()}xi(e,Y,$)}}a&&St(()=>{var K,ae;if(m!==void 0)for(g of m)(ae=(K=g.nodes)==null?void 0:K.a)==null||ae.apply()})}function Ti(e,t,n,r,s,a,o,u){var f=(o&Ea)!==0?(o&Aa)===0?ti(n,!1,!1):Qt(n):null,l=(o&Ta)!==0?Qt(s):null;return{v:f,i:l,e:Ue(()=>(a(t,f??n,l??s,u),()=>{e.delete(r)}))}}function jn(e,t,n){if(e.nodes)for(var r=e.nodes.start,s=e.nodes.end,a=t&&(t.f&ot)===0?t.nodes.start:n;r!==null;){var o=Un(r);if(a.before(r),r===s)return;r=o}}function xt(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function Us(e,t,n=!1,r=!1,s=!1,a=!1){var o=e,u="";if(n)var f=e;U(()=>{var l=L;if(u!==(u=t()??"")){if(n){l.nodes=null,f.innerHTML=u,u!==""&&On(Ct(f),f.lastChild);return}if(l.nodes!==null&&(Ns(l.nodes.start,l.nodes.end),l.nodes=null),u!==""){var _=r?Ra:s?Na:void 0,m=qs(r?"svg":s?"math":"template",_);m.innerHTML=u;var c=r||s?m:m.content;if(On(Ct(c),c.lastChild),r||s)for(;Ct(c);)o.before(Ct(c));else o.before(c)}}})}const Qr=[...`
2
+ \r\f \v\uFEFF`];function Si(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 u=o+a;(o===0||Qr.includes(r[o-1]))&&(u===r.length||Qr.includes(r[u]))?r=(o===0?"":r.substring(0,o))+r.substring(u+1):o=u}}return r===""?null:r}function ye(e,t,n,r,s,a){var o=e[kr];if(o!==n||o===void 0){var u=Si(n,r,a);u==null?e.removeAttribute("class"):e.className=u,e[kr]=n}else if(a&&s!==a)for(var f in a){var l=!!a[f];(s==null||l!==!!s[f])&&e.classList.toggle(f,l)}return a}function Xr(e,t){t?e.hasAttribute("selected")||e.setAttribute("selected",""):e.removeAttribute("selected")}const Ai="5";var ns;typeof window<"u"&&((ns=window.__svelte??(window.__svelte={})).v??(ns.v=new Set)).add(Ai);const Vs="x-satay-token";function Gs(){const e=new URLSearchParams(window.location.search).get("token"),t=window.__SATAY_TOKEN__;return e??t??window.localStorage.getItem("satay_token")??""}async function Tn(e){const t=Gs(),n={};t&&(n[Vs]=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 Ci(e,t){const n=Gs(),r={"content-type":"application/json"};n&&(r[Vs]=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 Ot=encodeURIComponent,It={runs:()=>Tn("/runs"),timeline:e=>Tn(`/runs/${Ot(e)}/timeline`),tree:e=>Tn(`/runs/${Ot(e)}/tree`),task:(e,t)=>Tn(`/runs/${Ot(e)}/tasks/${Ot(t)}`),compare:(e,t)=>Tn(`/runs/${Ot(e)}/compare?to=${Ot(t)}`),fork:(e,t)=>Ci(`/runs/${Ot(e)}/fork`,{fork_point_seq:t})};function mr(e,t=2e3){e();const n=window.setInterval(e,t);return()=>window.clearInterval(n)}function an(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toISOString().slice(11,19)}function Ys(e){const t=new Date(e);return Number.isNaN(t.getTime())?e:t.toISOString().slice(0,16).replace("T"," ")}function Ks(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 qi(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 ji(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 Ri(e){return JSON.stringify(e,null,2)}function Ni(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 $r(e){return e.is_interruption===!0||e.type==="WorkflowResumed"}function Mi(e){const t=e.events??[],n=t.map((r,s)=>{let a=null;if($r(r)&&s>0){const o=t[s-1],u=(Date.parse(r.ts)-Date.parse(o.ts))/1e3;a=Number.isFinite(u)?u:null}return{event:r,kind:Ni(r.type),downtimeSeconds:a}});return{runId:e.run_id,workflowName:e.workflow_name,status:e.status,interrupted:e.interrupted===!0||t.some($r),rows:n}}function Di(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 Fi(e){return e.kind==="map"}function Oi(e){return e.kind==="child"}function Ii(e){var s;const t=(e.attempts??[]).map(a=>{const o=a.status==="failed",u=a.usage??[];return{attempt:a,willRetry:o&&a.next_delay!=null,exhausted:o&&a.next_delay==null,usage:u,hasUsage:u.length>0}}),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,billedFailedAttempts:t.some(a=>a.attempt.status==="failed"&&a.hasUsage),hasTraceback:!!r,traceback:r}}function zi(e){return e==="completed"||e==="failed"||e==="cancelled"}function Pi(e){return e.seq-1}function Li(e,t){return e.seq>1&&zi(t)}function Js(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 Wi(e){var t;return((t=Js(e))==null?void 0:t.mismatch)===!0}function Bi(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 es(e,t){return JSON.stringify(e??null)===JSON.stringify(t??null)}function Hi(e){const t=(e.rows??[]).map(n=>{const r=n.a??null,s=n.b??null,a=r!==null&&s!==null,o=a&&!es(r.input,s.input),u=a&&!es(r.output,s.output),f=a&&r.attempts!==s.attempts,l=a&&r.duration_seconds!==s.duration_seconds,_=n.aligned===!0&&a,m=!_||o||u||f;return{identity:n.identity,taskName:n.task_name??null,a:r,b:s,aligned:_,changed:m,diffs:{input:o,output:u,attempts:f,duration:l}}});return{a:e.a,b:e.b,rows:t,changedCount:t.filter(n=>n.changed).length}}var Ui=T('<span><span class="pip"></span> </span>');function Rt(e,t){var n=Ui(),r=h(d(n),1,!0);U(()=>{ye(n,1,`chip ${t.status??""}`),b(r,t.label??t.status)}),x(e,n)}var Vi=T('<span class="bolt svelte-vdllgp" title="recovered from an interruption">&#9889;</span>'),Gi=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>'),Yi=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 Ki(e,t){mt(t,!0);var n=Yi(),r=h(we(n),4),s=h(d(r));De(s,21,()=>t.runs,u=>u.run_id,(u,f)=>{var l=Gi(),_=d(l),m=d(_);Rt(m,{get status(){return i(f).status}});var c=h(_),p=d(c),k=h(p);{var y=ne=>{var re=Vi();x(ne,re)};G(k,ne=>{i(f).interrupted&&ne(y)})}var g=h(c),E=d(g),F=h(g),j=d(F),S=d(j),A=h(F),J=d(A),Y=h(J,2),Z=d(Y),$=h(A),V=d($);U((ne,re)=>{b(p,`${i(f).run_id??""} `),b(E,i(f).workflow_name),b(S,i(f).code_version),b(J,ne),b(Z,re),b(V,i(f).idempotency_key??"—")},[()=>ji(i(f).created_at),()=>Ys(i(f).created_at)]),Ve("click",l,()=>t.onselect(i(f).run_id)),x(u,l)});var a=h(r,2),o=d(a);U(()=>b(o,`${t.runs.length??""} runs · fields: run_id, workflow_name, status, code_version, created_at, idempotency_key`)),x(e,n),gt()}Gn(["click"]);const Ji="***REDACTED***";function Zi(e){return e.replace(/[&<>"]/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"})[t])}function Qi(e){const t=JSON.stringify(e,null,2)??"null";let n=Zi(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===`"${Ji}"`?'<span class="redacted">&#128274; REDACTED</span>':n}var Xi=T('<pre class="json"></pre>');function qr(e,t){mt(t,!0);var n=Xi();Us(n,()=>Qi(t.value),!0),x(e,n),gt()}var $i=T('Worker died at <b class="svelte-cfijfh"> </b>, resumed at <b class="svelte-cfijfh"> </b> · ~<b class="svelte-cfijfh"> </b> down.',1),el=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>'),tl=T("<span> </span>"),nl=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>'),rl=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>'),sl=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),al=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 il(e,t){mt(t,!0);const n=Ge(()=>Mi(t.data));let r=ce(zt({}));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(f){var m,c,p;const l=f.payload,_=()=>l.key!=null?[{t:"key="},{t:String(l.key),strong:!0}]:[{t:`ordinal=${l.ordinal}`}];switch(f.type){case"WorkflowCreated":return[{t:"workflow="},{t:String(l.workflow_name),strong:!0},{t:` · code_version=${l.code_version}`}];case"TaskScheduled":return[{t:"task="},{t:String(l.task_name),strong:!0},{t:" "},..._()];case"TaskAttemptStarted":return[{t:"task="},{t:String(l.task_name),strong:!0},{t:` attempt=${l.attempt}`}];case"TaskAttemptFailed":return[{t:"task="},{t:String(l.task_name),strong:!0},{t:` attempt=${l.attempt} · `},{t:String((m=l.error)==null?void 0:m.type),danger:!0},{t:l.next_delay!=null?` · retry in ${l.next_delay}s`:" · exhausted"},...l.usage?[{t:` · usage×${l.usage.length}`}]:[]];case"TaskCompleted":return[{t:"task="},{t:String(l.task_name),strong:!0},...l.usage?[{t:` · usage×${l.usage.length}`}]:[]];case"TimerCreated":return[{t:`kind=${l.kind} · ${l.duration_seconds}s → ${an(l.fire_at)}`}];case"TimerFired":return[{t:`kind=${l.kind} · identity=${l.identity}`}];case"EventWaitStarted":return[{t:"event_type="},{t:String(l.event_type),strong:!0},...l.key!=null?[{t:` key=${l.key}`}]:[]];case"ExternalEventReceived":return[{t:"event_type="},{t:String(l.event_type),strong:!0},...l.key!=null?[{t:` key=${l.key}`}]:[],{t:" · delivered"}];case"WorkflowWaiting":return[{t:"reason="},{t:String(l.reason),strong:!0},{t:" · parked (no ⚡ — graceful)"}];case"WorkflowFailed":return[{t:`${(c=l.error)==null?void 0:c.type}: ${(p=l.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(l.reason??"cancelled")}];default:return[]}}var o=al(),u=h(we(o),6);De(u,23,()=>i(n).rows,f=>f.event.event_id,(f,l,_)=>{var m=sl(),c=we(m);{var p=W=>{var ee=el(),se=d(ee),K=h(d(se),2),ae=h(d(K),2),ve=d(ae);{var be=Fe=>{var Oe=$i(),Ie=h(we(Oe)),rt=d(Ie),ze=h(Ie,2),vt=d(ze),st=h(ze,2),w=d(st);U((M,I,H)=>{b(rt,M),b(vt,I),b(w,H)},[()=>an(i(n).rows[i(_)-1].event.ts),()=>an(i(l).event.ts),()=>qi(i(n).rows[i(_)-1].event.ts,i(l).event.ts)]),x(Fe,Oe)};G(ve,Fe=>{i(_)>0&&Fe(be)})}x(W,ee)};G(c,W=>{i(l).kind==="resume"&&W(p)})}var k=h(c,2);let y;var g=d(k),E=h(g,2),F=d(E),j=d(F),S=h(F,2),A=d(S);let J;var Y=d(A),Z=h(A,2);De(Z,21,()=>a(i(l).event),In,(W,ee)=>{var se=tl();let K;var ae=d(se);U(()=>{K=ye(se,1,"svelte-cfijfh",null,K,{strong:i(ee).strong,danger:i(ee).danger}),b(ae,i(ee).t)}),x(W,se)});var $=h(S,2),V=d($),ne=h(E,2);{var re=W=>{var ee=nl();Ve("click",ee,()=>{var se;return(se=t.onfork)==null?void 0:se.call(t,Pi(i(l).event))}),x(W,ee)},O=Ge(()=>t.onfork&&Li(i(l).event,i(n).status));G(ne,W=>{i(O)&&W(re)})}var R=h(ne,2);{var fe=W=>{var ee=rl(),se=d(ee),K=d(se),ae=d(K),ve=h(K,2),be=d(ve);qr(be,{get value(){return i(l).event.payload}}),U(()=>b(ae,`event_id ${i(l).event.event_id??""} · payload`)),x(W,ee)};G(R,W=>{i(r)[i(l).event.seq]&&W(fe)})}U(W=>{y=ye(k,1,"ev svelte-cfijfh",null,y,{"is-resume":i(l).kind==="resume","is-open":i(r)[i(l).event.seq]}),ye(g,1,`ev-node ${(i(l).kind==="resume"?"":s[i(l).kind])??""}`,"svelte-cfijfh"),b(j,`#${i(l).event.seq??""}`),J=ye(A,1,"ev-type svelte-cfijfh",null,J,{"k-fail":i(l).kind==="fail","k-done":i(l).kind==="done","k-resume":i(l).kind==="resume"}),b(Y,i(l).event.type),b(V,`${W??""} `)},[()=>an(i(l).event.ts)]),Ve("click",E,()=>z(r,{...i(r),[i(l).event.seq]:!i(r)[i(l).event.seq]},!0)),x(f,m)}),x(e,o),gt()}Gn(["click"]);var ll=T('<span class="mretry svelte-7ey46k"> </span>'),ol=T('<button class="map-item svelte-7ey46k"><span class="mk svelte-7ey46k"> </span> <!> <span></span></button>'),ul=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>'),fl=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>'),vl=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 Zs(e,t){mt(t,!0);var n=sn(),r=we(n);{var s=l=>{const _=Ge(()=>Di(t.node));var m=ul(),c=d(m),p=h(d(c),2),k=d(p),y=d(k),g=h(k),E=d(g),F=h(p,2),j=d(F);Rt(j,{get status(){return t.node.status}});var S=h(c,2),A=d(S),J=h(d(A)),Y=h(A,2);De(Y,21,()=>t.node.items,Z=>Z.identity,(Z,$)=>{var V=ol(),ne=d(V),re=d(ne),O=h(ne,2);{var R=W=>{var ee=ll(),se=d(ee);U(()=>b(se,`×${i($).attempts??""}`)),x(W,ee)};G(O,W=>{i($).attempts>1&&W(R)})}var fe=h(O,2);U(()=>{b(re,i($).key),ye(fe,1,`mdot ${i($).status??""}`,"svelte-7ey46k")}),Ve("click",V,()=>t.onopentask(i($).identity)),x(Z,V)}),U(()=>{b(y,`map · ${t.node.task_name??""}`),b(E,`group=${t.node.group??""} · ${t.node.items.length??""} items`),b(J,` — ${i(_).completed??""} completed, ${i(_).running??""} running${i(_).failed?`, ${i(_).failed} failed`:""} · results rejoin in input order`)}),x(l,m)},a=Ge(()=>Fi(t.node)),o=l=>{var _=fl(),m=d(_),c=h(d(m),2),p=d(c),k=d(p),y=h(p),g=d(y),E=h(c,2),F=d(E);Rt(F,{get status(){return t.node.status}});var j=h(m,2),S=d(j),A=h(d(S)),J=d(A),Y=h(S,2);{var Z=$=>{var V=sn(),ne=we(V);De(ne,17,()=>t.node.tree.nodes,re=>re.kind+re.identity+re.group,(re,O)=>{Zs(re,{get node(){return i(O)},get onopentask(){return t.onopentask}})}),x($,V)};G(Y,$=>{t.node.tree&&$(Z)})}U(()=>{b(k,t.node.workflow_name),b(g,`child workflow · ${t.node.identity??""}`),b(J,t.node.child_run_id)}),x(l,_)},u=Ge(()=>Oi(t.node)),f=l=>{var _=vl(),m=d(_),c=h(d(m),2),p=d(c),k=d(p),y=h(p),g=d(y),E=h(c,2),F=d(E);let j;var S=d(F),A=h(F,2);Rt(A,{get status(){return t.node.status}}),U(()=>{b(k,t.node.task_name),b(g,`${t.node.identity??""} · ${t.node.key!=null?`key=${t.node.key}`:`ordinal=${t.node.ordinal}`}`),j=ye(F,1,"attempts svelte-7ey46k",null,j,{retried:t.node.attempts>1}),b(S,`${t.node.attempts??""} attempt${t.node.attempts>1?"s":""}`)}),Ve("click",m,()=>t.onopentask(t.node.identity)),x(l,_)};G(r,l=>{i(a)?l(s):i(u)?l(o,1):l(f,-1)})}x(e,n),gt()}Gn(["click"]);var cl=T('<div class="empty-state">This run scheduled no durable calls.</div>'),dl=T('<div class="tree"></div>'),hl=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 _l(e,t){mt(t,!0);var n=hl(),r=h(we(n),4);{var s=o=>{var u=cl();x(o,u)},a=o=>{var u=dl();De(u,21,()=>t.data.nodes,f=>f.kind+f.identity+f.group,(f,l)=>{Zs(f,{get node(){return i(l)},get onopentask(){return t.onopentask}})}),x(o,u)};G(r,o=>{t.data.nodes.length===0?o(s):o(a,-1)})}x(e,n),gt()}var pl=T('<div class="io-empty svelte-u9er0g">null — task produced no output (failed before completing)</div>'),ml=T('<div class="u-note svelte-u9er0g">&#9888; includes attempts that failed — billed, and nothing to show for it</div>'),gl=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>'),kl=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>',1),yl=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>'),wl=T('<div class="att-error svelte-u9er0g"><div class="et svelte-u9er0g"> </div><div class="em svelte-u9er0g"> </div></div>'),bl=T('<div class="att-retry svelte-u9er0g"><span class="rico svelte-u9er0g">&#8635;</span> retried after <b> </b> </div>'),xl=T('<div class="att-exhausted svelte-u9er0g">&#9888; retries exhausted — failure propagated to the workflow</div>'),El=T('<span class="au-cost svelte-u9er0g"> </span>'),Tl=T('<div class="au-row svelte-u9er0g"><span class="au-model svelte-u9er0g"> </span> <span class="au-tok"> </span> <!></div>'),Sl=T('<div class="att-usage svelte-u9er0g"></div>'),Al=T('<div class="att-note svelte-u9er0g"><span class="rico svelte-u9er0g">&#9889;</span> </div>'),Cl=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>'),ql=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>'),jl=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, its backoff, and what it cost. Usage is per
8
+ ADR-0008 — present only when the task self-reported it — and the total below is every attempt, failed ones included.</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"> </div> <!></div></div> <div class="attempts-label svelte-u9er0g"> </div> <div class="att-list svelte-u9er0g"></div> <!>`,1);function Rl(e,t){mt(t,!0);const n=Ge(()=>Ii(t.data));function r(O){return(fe=>fe.replace(/[&<>]/g,W=>({"&":"&amp;","<":"&lt;",">":"&gt;"})[W]))(O).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=jl(),a=h(we(s),4),o=d(a),u=d(o),f=h(u);Rt(f,{get status(){return i(n).status}});var l=h(o,2),_=d(l),m=h(l,2),c=d(m),p=h(d(c));qr(p,{get value(){return t.data.input}});var k=h(c,2),y=h(d(k),2);{var g=O=>{qr(O,{get value(){return t.data.output}})},E=O=>{var R=pl();x(O,R)};G(y,O=>{t.data.output!=null?O(g):O(E,-1)})}var F=h(m,2),j=d(F),S=d(j),A=h(j,2);{var J=O=>{var R=kl(),fe=we(R);{var W=K=>{var ae=ml();x(K,ae)};G(fe,K=>{i(n).billedFailedAttempts&&K(W)})}var ee=h(fe,2),se=h(d(ee));De(se,21,()=>i(n).usage,In,(K,ae)=>{var ve=gl(),be=d(ve),Fe=d(be),Oe=h(be),Ie=d(Oe),rt=h(Oe),ze=d(rt),vt=h(rt),st=d(vt);U(w=>{b(Fe,i(ae).model??"—"),b(Ie,i(ae).input_tokens??"—"),b(ze,i(ae).output_tokens??"—"),b(st,w)},[()=>i(ae).cost_usd!=null?`$${i(ae).cost_usd.toFixed(4)}`:"—"]),x(K,ve)}),x(O,R)},Y=O=>{var R=yl();x(O,R)};G(A,O=>{i(n).hasUsage?O(J):O(Y,-1)})}var Z=h(a,2),$=d(Z),V=h(Z,2);De(V,21,()=>i(n).attempts,O=>O.attempt.attempt,(O,R)=>{var fe=Cl(),W=d(fe),ee=h(W,2);let se;var K=d(ee),ae=d(K),ve=d(ae),be=h(ae,2);Rt(be,{get status(){return i(R).attempt.status}});var Fe=h(be,2),Oe=d(Fe),Ie=h(K,2),rt=d(Ie),ze=h(Ie,2);{var vt=D=>{var te=wl(),oe=d(te),ge=d(oe),Pe=h(oe),kt=d(Pe);U(()=>{b(ge,i(R).attempt.error.type),b(kt,i(R).attempt.error.message)}),x(D,te)};G(ze,D=>{i(R).attempt.error&&D(vt)})}var st=h(ze,2);{var w=D=>{var te=bl(),oe=h(d(te),2),ge=d(oe),Pe=h(oe);U(()=>{b(ge,`${i(R).attempt.next_delay??""}s`),b(Pe,` backoff → attempt ${i(R).attempt.attempt+1}`)}),x(D,te)},M=D=>{var te=xl();x(D,te)};G(st,D=>{i(R).willRetry?D(w):i(R).exhausted&&D(M,1)})}var I=h(st,2);{var H=D=>{var te=Sl();De(te,21,()=>i(R).usage,In,(oe,ge)=>{var Pe=Tl(),kt=d(Pe),Dt=d(kt),yt=h(kt,2),wn=d(yt),bn=h(yt,2);{var wt=bt=>{var Xt=El(),xn=d(Xt);U(Ft=>b(xn,`$${Ft??""}`),[()=>i(ge).cost_usd.toFixed(4)]),x(bt,Xt)};G(bn,bt=>{i(ge).cost_usd!=null&&bt(wt)})}U(()=>{b(Dt,i(ge).model??"—"),b(wn,`${i(ge).input_tokens??"—"??""} in / ${i(ge).output_tokens??"—"??""} out`)}),x(oe,Pe)}),x(D,te)};G(I,D=>{i(R).hasUsage&&D(H)})}var Q=h(I,2);{var le=D=>{var te=Al(),oe=h(d(te));U(()=>b(oe,` ${i(R).attempt.note??""}`)),x(D,te)};G(Q,D=>{i(R).attempt.note&&D(le)})}U((D,te,oe)=>{ye(W,1,`att-node ${i(R).attempt.status??""}`,"svelte-u9er0g"),se=ye(ee,1,"att-card svelte-u9er0g",null,se,{failed:i(R).attempt.status==="failed"}),b(ve,`Attempt ${i(R).attempt.attempt??""}`),b(Oe,D),b(rt,`${te??""} → ${oe??""}`)},[()=>Ks(i(R).attempt.duration_seconds),()=>an(i(R).attempt.started_at),()=>i(R).attempt.ended_at?an(i(R).attempt.ended_at):"—"]),x(O,fe)});var ne=h(V,2);{var re=O=>{var R=ql(),fe=h(d(R),2);Us(fe,()=>r(i(n).traceback),!0),x(O,R)};G(ne,O=>{i(n).hasTraceback&&i(n).traceback&&O(re)})}U(()=>{b(u,`${i(n).taskName??""} `),b(_,`${i(n).identity??""} · ${t.data.key!=null?`key = ${t.data.key}`:`ordinal = ${t.data.ordinal}`}`),b(S,`recorded model usage · all ${i(n).attemptCount??""} attempt${i(n).attemptCount===1?"":"s"}`),b($,`Physical attempts · ${i(n).attemptCount??""}`)}),x(e,s),gt()}var Nl=T("<option> </option>"),Ml=T('<div class="empty-state">Pick a second run to compare against.</div>'),Dl=T('<div class="empty-state">Loading comparison…</div>'),Fl=T('<span class="badge svelte-uzstyf">changed</span>'),Ol=T('<span class="badge only svelte-uzstyf">one side only</span>'),Il=T('<span class="absent svelte-uzstyf">— absent —</span>'),zl=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),Pl=T('<td class="c-side svelte-uzstyf"><!></td>'),Ll=T('<tr><td class="c-ident svelte-uzstyf"><span class="ident svelte-uzstyf"> </span> <!> <!></td><!></tr>'),Wl=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),Bl=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 Hl(e,t){mt(t,!0);const n=Ge(()=>t.runs.filter(S=>S.run_id!==t.runId)),r=Ge(()=>t.data?Hi(t.data):null);function s(S){const A=Ri(S);return A.length>80?A.slice(0,79)+"…":A}var a=Bl(),o=h(we(a),2),u=h(d(o));u.textContent="GET /runs/{id}/compare?to=…";var f=h(o,2),l=d(f),_=h(d(l)),m=d(_),c=h(l,4),p=h(d(c)),k=d(p);k.value=k.__value="";var y=h(k);De(y,17,()=>i(n),S=>S.run_id,(S,A)=>{var J=Nl(),Y=d(J),Z={};U(()=>{Xr(J,i(A).run_id===t.compareTo),b(Y,`${i(A).run_id??""} · ${i(A).workflow_name??""} · ${i(A).status??""}`),Z!==(Z=i(A).run_id)&&(J.value=(J.__value=i(A).run_id)??"")}),x(S,J)});var g=h(f,2);{var E=S=>{var A=Ml();x(S,A)},F=S=>{var A=Dl();x(S,A)},j=S=>{var A=Wl(),J=we(A),Y=d(J),Z=h(Y),$=d(Z),V=h(Z,2),ne=d(V),re=h(J,2),O=d(re),R=d(O),fe=h(d(R)),W=d(fe),ee=h(fe),se=d(ee),K=h(O);De(K,21,()=>i(r).rows,ae=>ae.identity,(ae,ve)=>{var be=Ll();let Fe;var Oe=d(be),Ie=d(Oe),rt=d(Ie),ze=h(Ie,2);{var vt=I=>{var H=Fl();x(I,H)};G(ze,I=>{i(ve).changed&&I(vt)})}var st=h(ze,2);{var w=I=>{var H=Ol();x(I,H)};G(st,I=>{i(ve).aligned||I(w)})}var M=h(Oe);De(M,17,()=>[i(ve).a,i(ve).b],In,(I,H)=>{var Q=Pl(),le=d(Q);{var D=oe=>{var ge=Il();x(oe,ge)},te=oe=>{var ge=zl(),Pe=we(ge),kt=d(Pe);Rt(kt,{get status(){return i(H).status}});var Dt=h(Pe,2);let yt;var wn=h(d(Dt),2),bn=d(wn),wt=h(Dt,2);let bt;var Xt=h(d(wt),2),xn=d(Xt),Ft=h(wt,2);let ke;var at=h(d(Ft)),$t=h(Ft,2);let Yn;var Qs=h(d($t));U((Xs,$s,ea)=>{yt=ye(Dt,1,"cell-line svelte-uzstyf",null,yt,{diff:i(ve).diffs.input}),b(bn,Xs),bt=ye(wt,1,"cell-line svelte-uzstyf",null,bt,{diff:i(ve).diffs.output}),b(xn,$s),ke=ye(Ft,1,"cell-line svelte-uzstyf",null,ke,{diff:i(ve).diffs.attempts}),b(at,` ${i(H).attempts??""}`),Yn=ye($t,1,"cell-line time svelte-uzstyf",null,Yn,{diff:i(ve).diffs.duration}),b(Qs,` ${ea??""}`)},[()=>s(i(H).input),()=>s(i(H).output),()=>Ks(i(H).duration_seconds)]),x(oe,ge)};G(le,oe=>{i(H)?oe(te,-1):oe(D)})}x(I,Q)}),U(()=>{Fe=ye(be,1,"svelte-uzstyf",null,Fe,{changed:i(ve).changed}),b(rt,i(ve).identity)}),x(ae,be)}),U(()=>{b(Y,`${i(r).changedCount??""} of ${i(r).rows.length??""} calls differ between `),b($,i(r).a.run_id),b(ne,i(r).b.run_id),b(W,`A · ${i(r).a.run_id??""}`),b(se,`B · ${i(r).b.run_id??""}`)}),x(S,A)};G(g,S=>{t.compareTo?i(r)?S(j,-1):S(F,1):S(E)})}U(()=>{b(m,t.runId),Xr(k,!t.compareTo)}),Ve("change",p,S=>t.onpick(S.currentTarget.value)),x(e,a),gt()}Gn(["change"]);var Ul=T("<button> </button>"),Vl=T('<span class="chip accent"><span class="pip"></span>&#9889; interrupted</span>'),Gl=T('<button class="chip fork-chip svelte-1n46o8q" title="Compare against the source run"> </button>'),Yl=T('<div class="kv svelte-1n46o8q"><span class="k svelte-1n46o8q">idempotency</span><span class="v svelte-1n46o8q"> </span></div>'),Kl=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>'),Jl=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>`),Zl=T('<div class="empty-state error-state"> </div>'),Ql=T('<div class="empty-state">Loading timeline…</div>'),Xl=T('<div class="empty-state">Loading tree…</div>'),$l=T('<div class="empty-state">Select a task from the execution tree.</div>'),eo=T('<div class="empty-state">Loading task…</div>'),to=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 no(e,t){mt(t,!0);let n=ce("runs"),r=ce(null),s=ce(null),a=ce(null),o=ce(zt([])),u=ce(null),f=ce(null),l=ce(null),_=ce(null),m=ce(null),c=ce(!1);const p=Ge(()=>i(o).find(w=>w.run_id===i(r))??null),k=Ge(()=>Js(i(p))),y=Ge(()=>Bi(i(p)));function g(w){z(m,w instanceof Error?w.message:String(w),!0)}_r(()=>{if(i(n)==="runs")return mr(()=>{It.runs().then(w=>{z(o,w.runs,!0),z(m,null)}).catch(g)})}),_r(()=>{const w=i(r),M=i(n),I=i(s),H=i(a);if(!(!w||M==="runs"))return mr(()=>{M==="timeline"?It.timeline(w).then(Q=>{z(u,Q,!0),z(m,null)}).catch(g):M==="tree"?It.tree(w).then(Q=>{z(f,Q,!0),z(m,null)}).catch(g):M==="task"&&I?It.task(w,I).then(Q=>{z(l,Q,!0),z(m,null)}).catch(g):M==="compare"&&H&&It.compare(w,H).then(Q=>{z(_,Q,!0),z(m,null)}).catch(g)})}),_r(()=>{if(i(n)!=="runs")return mr(()=>{It.runs().then(w=>{z(o,w.runs,!0)}).catch(()=>{})},4e3)});function E(w){z(r,w,!0),z(s,null),z(a,null),z(u,z(f,z(l,null),!0),!0),z(_,null),z(m,null),z(n,"timeline")}function F(w){w!=="runs"&&!i(r)||z(n,w,!0)}function j(w){z(s,w,!0),z(l,null),z(n,"task")}function S(w){z(a,w||null,!0),z(_,null),z(m,null)}async function A(w){if(!(!i(r)||i(c))){z(c,!0);try{const M=await It.fork(i(r),w);E(M.run_id)}catch(M){g(M)}finally{z(c,!1)}}}function J(){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 Z=to(),$=d(Z),V=h(d($),4);let ne;var re=h(V,4);De(re,17,()=>Y,In,(w,M)=>{var I=Ul();let H;var Q=d(I);U(()=>{H=ye(I,1,"nav-item svelte-1n46o8q",null,H,{"is-active":i(n)===i(M).id,"is-disabled":!i(r)}),b(Q,i(M).label)}),Ve("click",I,()=>F(i(M).id)),x(w,I)});var O=h(re,2),R=h(d(O),2),fe=h($,2),W=d(fe);{var ee=w=>{var M=Kl(),I=d(M),H=h(I,2),Q=d(H),le=h(H,2),D=d(le),te=h(le,2);Rt(te,{get status(){return i(p).status}});var oe=h(te,2);{var ge=ke=>{var at=Vl();x(ke,at)};G(oe,ke=>{i(p).interrupted&&ke(ge)})}var Pe=h(oe,2);{var kt=ke=>{var at=Gl(),$t=d(at);U(()=>b($t,`⚟ forked from ${i(y).source_run_id??""} @ #${i(y).fork_point_seq??""}`)),Ve("click",at,()=>{S(i(y).source_run_id),F("compare")}),x(ke,at)};G(Pe,ke=>{i(y)&&ke(kt)})}var Dt=h(Pe,2),yt=d(Dt),wn=h(d(yt)),bn=d(wn),wt=h(yt,2),bt=h(d(wt)),Xt=d(bt),xn=h(wt,2);{var Ft=ke=>{var at=Yl(),$t=h(d(at)),Yn=d($t);U(()=>b(Yn,i(p).idempotency_key)),x(ke,at)};G(xn,ke=>{i(p).idempotency_key&&ke(Ft)})}U(ke=>{b(Q,i(p).run_id),b(D,i(p).workflow_name),b(bn,i(p).code_version),b(Xt,ke)},[()=>Ys(i(p).created_at)]),Ve("click",I,()=>F("runs")),x(w,M)};G(W,w=>{i(n)!=="runs"&&i(p)&&w(ee)})}var se=h(W,2);{var K=w=>{var M=Jl(),I=h(d(M),2),H=h(d(I),2),Q=h(d(H)),le=d(Q),D=h(Q,2),te=d(D),oe=h(I,2);U(()=>{b(le,i(k).stamped),b(te,i(k).current)}),Ve("click",oe,()=>F("timeline")),x(w,M)},ae=Ge(()=>{var w;return i(n)!=="runs"&&i(p)&&((w=i(k))==null?void 0:w.mismatch)&&Wi(i(p))});G(se,w=>{i(ae)&&w(K)})}var ve=h(se,2),be=d(ve),Fe=d(be);{var Oe=w=>{var M=Zl(),I=d(M);U(()=>b(I,`Read API error: ${i(m)??""}`)),x(w,M)},Ie=w=>{Ki(w,{get runs(){return i(o)},onselect:E})},rt=w=>{var M=sn(),I=we(M);{var H=le=>{il(le,{get data(){return i(u)},onfork:A})},Q=le=>{var D=Ql();x(le,D)};G(I,le=>{i(u)?le(H):le(Q,-1)})}x(w,M)},ze=w=>{var M=sn(),I=we(M);{var H=le=>{_l(le,{get data(){return i(f)},onopentask:j})},Q=le=>{var D=Xl();x(le,D)};G(I,le=>{i(f)?le(H):le(Q,-1)})}x(w,M)},vt=w=>{var M=sn(),I=we(M);{var H=D=>{var te=$l();x(D,te)},Q=D=>{Rl(D,{get data(){return i(l)}})},le=D=>{var te=eo();x(D,te)};G(I,D=>{i(s)?i(l)?D(Q,1):D(le,-1):D(H)})}x(w,M)},st=w=>{var M=sn(),I=we(M);{var H=Q=>{Hl(Q,{get runId(){return i(r)},get compareTo(){return i(a)},get runs(){return i(o)},get data(){return i(_)},onpick:S})};G(I,Q=>{i(r)&&Q(H)})}x(w,M)};G(Fe,w=>{i(m)?w(Oe):i(n)==="runs"?w(Ie,1):i(n)==="timeline"?w(rt,2):i(n)==="tree"?w(ze,3):i(n)==="task"?w(vt,4):i(n)==="compare"&&w(st,5)})}U(()=>ne=ye(V,1,"nav-item svelte-1n46o8q",null,ne,{"is-active":i(n)==="runs"})),Ve("click",V,()=>F("runs")),Ve("click",R,J),x(e,Z),gt()}Gn(["click"]);var rs;!document.documentElement.getAttribute("data-theme")&&((rs=window.matchMedia)!=null&&rs.call(window,"(prefers-color-scheme: light)").matches)&&document.documentElement.setAttribute("data-theme","light");ki(no,{target:document.getElementById("app")});
@@ -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}.ev-node.k-lifecycle.svelte-cfijfh{border-color:var(--text-faint);background:var(--text-faint)}.ev-node.k-sched.svelte-cfijfh{border-color:var(--running)}.ev-node.k-run.svelte-cfijfh{border-color:var(--running);background:var(--running)}.ev-node.k-done.svelte-cfijfh{border-color:var(--completed);background:var(--completed)}.ev-node.k-fail.svelte-cfijfh{border-color:var(--failed);background:var(--failed)}.ev-node.k-wait.svelte-cfijfh{border-color:var(--waiting);background:var(--surface)}.ev-node.k-timer.svelte-cfijfh{border-color:var(--waiting);background:var(--waiting)}.ev-node.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)}.u-note.svelte-u9er0g{font-family:var(--font-mono);font-size:11px;color:var(--failed);margin-bottom:7px}.att-usage.svelte-u9er0g{margin-top:10px;border-top:1px dashed var(--border-strong);padding-top:8px}.au-row.svelte-u9er0g{display:flex;align-items:baseline;gap:10px;font-family:var(--font-mono);font-size:11.5px;color:var(--text-dim)}.au-model.svelte-u9er0g{color:var(--text)}.au-cost.svelte-u9er0g{margin-left:auto;color:var(--text)}.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,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-BhyW4Wc4.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-vwLg8ReS.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/app.py ADDED
@@ -0,0 +1,138 @@
1
+ """``satay.run_app`` — a journal with the poll loop already running (KAN-491, ADR-0030).
2
+
3
+ Two of the five primitives park the run: ``satay.sleep`` and ``wait_for_event`` give up
4
+ the coroutine entirely, and something has to wake it. Until this module existed, a script
5
+ that used either one had to assemble that "something" by hand — open a data dir, open a
6
+ :class:`~satay.journal.store.SQLiteStore`, build a
7
+ :class:`~satay.timers.TimerEventWorker`, start its loop as a task, and tear all three down
8
+ in a ``finally`` — four sub-module imports, none of them public surface, before you could
9
+ write the line you actually cared about. This is that block, once, in the runtime::
10
+
11
+ async with satay.run_app() as store:
12
+ print(await satay.start(trial, "u-1", store=store).result())
13
+
14
+ **An async context manager, not a ``run_app(main)`` callback.** Teardown is the whole
15
+ problem here (the hand-rolled version needed ``try``/``finally`` and still leaked a
16
+ cancelled task on the way out), and ``async with`` is Python's answer to teardown. It also
17
+ composes: the body is your code, at your indentation, inside whatever ``asyncio.run`` you
18
+ already have — a callback form would have owned the event loop and made the tutorial teach
19
+ inversion of control before it taught durability.
20
+
21
+ **Core, not ``satay[studio]``.** A reader hits ``satay.sleep`` on page two of the tutorial,
22
+ long before Studio, so this cannot need the extra (ADR-0013/0016). Nothing here imports
23
+ FastAPI, uvicorn or Typer; the store and the worker are imported lazily inside the function
24
+ so ``import satay`` stays cheap. ``satay dev`` is the other end of the same idea — a whole
25
+ process, with Studio — and the two interoperate over one journal.
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ import asyncio
31
+ import contextlib
32
+ from collections.abc import AsyncIterator
33
+ from contextlib import asynccontextmanager
34
+ from typing import TYPE_CHECKING
35
+
36
+ if TYPE_CHECKING:
37
+ import os
38
+
39
+ from satay.config import EffectSafety, NondeterminismPolicy, VersionMismatchPolicy
40
+ from satay.journal import Store
41
+ from satay.testing.clock import Clock
42
+ from satay.testing.faults import FaultInjector
43
+ from satay.testing.rng import Rng
44
+
45
+ #: Poll cadence for the worker ``run_app`` starts, in seconds. Shorter than the one
46
+ #: ``satay dev`` uses (1.0s): a script is usually waiting on the loop interactively, and
47
+ #: an idle tick over an empty timer table is a couple of indexed SQLite reads.
48
+ DEFAULT_POLL_INTERVAL = 0.2
49
+
50
+
51
+ @asynccontextmanager
52
+ async def run_app(
53
+ *,
54
+ data_dir: str | os.PathLike[str] | None = None,
55
+ store: Store | None = None,
56
+ interval: float = DEFAULT_POLL_INTERVAL,
57
+ clock: Clock | None = None,
58
+ rng: Rng | None = None,
59
+ injector: FaultInjector | None = None,
60
+ effect_safety: str | EffectSafety | None = None,
61
+ nondeterminism: str | NondeterminismPolicy | None = None,
62
+ version_mismatch: str | VersionMismatchPolicy | None = None,
63
+ ) -> AsyncIterator[Store]:
64
+ """Open the journal, run the timer + event poll loop, and yield the store (N21).
65
+
66
+ Pass the yielded store to every ``satay.start`` / ``satay.send_event`` inside the
67
+ block so the whole app shares one writer (ADR-0012)::
68
+
69
+ async with satay.run_app() as store:
70
+ handle = satay.start(trial, "u-1", store=store)
71
+ print(await handle.result())
72
+
73
+ While the block is open, ``await handle.result()`` on a run that parks **waits** for
74
+ the loop to wake it and returns the real outcome, instead of handing back
75
+ :data:`satay.PARKED` (ADR-0030) — so a workflow that sleeps or waits for an event
76
+ reads like an ordinary ``await``. A run parked on an event nobody sends waits forever,
77
+ exactly like any other ``await``; wrap it in :func:`asyncio.wait_for` if you want a
78
+ deadline.
79
+
80
+ On the way out the loop is stopped and awaited before the store is closed, in that
81
+ order, whether the block exits normally or by exception.
82
+
83
+ ``data_dir`` overrides the project-local ``./.satay`` (as ``--data-dir`` /
84
+ ``SATAY_DATA_DIR`` do). ``store`` runs the loop over a store you opened yourself, and
85
+ leaves closing it to you — an in-memory store in a test, say. ``interval`` is the poll
86
+ cadence in seconds. ``clock`` / ``rng`` / ``injector`` and the three policy settings
87
+ are the same seam ``satay.start`` takes; a :class:`~satay.testing.clock.ManualClock`
88
+ here means the loop only advances when your test advances it.
89
+ """
90
+ from satay.config import (
91
+ db_path,
92
+ resolve_data_dir,
93
+ resolve_effect_safety,
94
+ resolve_nondeterminism,
95
+ resolve_version_mismatch,
96
+ )
97
+ from satay.journal.store import SQLiteStore
98
+ from satay.timers import TimerEventWorker, register_poll_loop, unregister_poll_loop
99
+
100
+ owned: SQLiteStore | None = None
101
+ if store is None:
102
+ directory = resolve_data_dir(data_dir)
103
+ directory.mkdir(parents=True, exist_ok=True)
104
+ owned = SQLiteStore.open(db_path(directory))
105
+ resolved: Store = owned
106
+ else:
107
+ if data_dir is not None:
108
+ raise TypeError("pass either data_dir= or store= to satay.run_app(), not both")
109
+ resolved = store
110
+
111
+ worker = TimerEventWorker(
112
+ store=resolved,
113
+ clock=clock,
114
+ rng=rng,
115
+ injector=injector,
116
+ interval=interval,
117
+ effect_safety=resolve_effect_safety(effect_safety),
118
+ nondeterminism=resolve_nondeterminism(nondeterminism),
119
+ version_mismatch=resolve_version_mismatch(version_mismatch),
120
+ )
121
+ # Registered here rather than only inside ``worker.run()``: the task does not reach
122
+ # its first line until the next suspension point, and a ``result()`` awaited before
123
+ # that would otherwise see no loop and give up on a parked run.
124
+ register_poll_loop(resolved)
125
+ task = asyncio.create_task(worker.run())
126
+ try:
127
+ yield resolved
128
+ finally:
129
+ worker.stop()
130
+ task.cancel()
131
+ with contextlib.suppress(asyncio.CancelledError):
132
+ await task
133
+ unregister_poll_loop(resolved)
134
+ if owned is not None:
135
+ owned.close()
136
+
137
+
138
+ __all__ = ["DEFAULT_POLL_INTERVAL", "run_app"]