@swirls/looms 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/actor/host.js +4 -6
  3. package/dist/actor/index.d.ts +1 -1
  4. package/dist/actor/index.js +1 -1
  5. package/dist/actor/routing.d.ts +5 -0
  6. package/dist/actor/routing.js +14 -0
  7. package/dist/agent/agent-session.js +1 -0
  8. package/dist/agent/debugger/agent-chat.js +45 -11
  9. package/dist/agent/debugger/summarize.js +2 -0
  10. package/dist/agent/effects.d.ts +30 -0
  11. package/dist/agent/events.d.ts +2 -0
  12. package/dist/agent/events.js +2 -0
  13. package/dist/agent/llm.js +1 -8
  14. package/dist/agent/module.d.ts +604 -534
  15. package/dist/agent/module.js +11 -7
  16. package/dist/agent/projections.d.ts +5 -0
  17. package/dist/agent/projections.js +43 -2
  18. package/dist/agent/scope.d.ts +2 -0
  19. package/dist/agent/signals.d.ts +5 -0
  20. package/dist/agent/signals.js +7 -0
  21. package/dist/agent/threads.js +35 -21
  22. package/dist/agent/transcript.d.ts +7 -0
  23. package/dist/agent/transcript.js +19 -0
  24. package/dist/agent/types.d.ts +10 -0
  25. package/dist/agent/types.js +4 -0
  26. package/dist/approval/debugger/approvals-view.js +5 -3
  27. package/dist/approval/effects.d.ts +12 -0
  28. package/dist/approval/module.d.ts +24 -0
  29. package/dist/client/client.d.ts +292 -0
  30. package/dist/client/client.js +17 -1
  31. package/dist/cloudflare/router.d.ts +1 -1
  32. package/dist/cloudflare/router.js +6 -8
  33. package/dist/core/effects.d.ts +7 -0
  34. package/dist/core/effects.js +1 -0
  35. package/dist/core/fold.js +12 -6
  36. package/dist/core/fork.d.ts +35 -0
  37. package/dist/core/fork.js +129 -0
  38. package/dist/core/index.d.ts +1 -0
  39. package/dist/core/index.js +1 -0
  40. package/dist/core/module-scope.d.ts +1 -0
  41. package/dist/core/module.d.ts +2 -2
  42. package/dist/core/projection.js +1 -0
  43. package/dist/core/protocol.d.ts +10 -1
  44. package/dist/core/protocol.js +11 -0
  45. package/dist/core/replay.d.ts +8 -0
  46. package/dist/core/snapshots.js +3 -17
  47. package/dist/core/state.d.ts +14 -0
  48. package/dist/core/state.js +25 -2
  49. package/dist/core/store.d.ts +1 -0
  50. package/dist/debugger/app/assets/{index-Qb371t_O.js → index-BevQYa-U.js} +2 -2
  51. package/dist/debugger/app/assets/index-CgDzWJg7.css +2 -0
  52. package/dist/debugger/app/assets/routes-B17Om93i.js +47 -0
  53. package/dist/debugger/app/index.html +2 -2
  54. package/dist/debugger/components/composer.d.ts +5 -2
  55. package/dist/debugger/components/composer.js +5 -4
  56. package/dist/debugger/components/run-tree.js +2 -5
  57. package/dist/debugger/events/catalog.js +1 -3
  58. package/dist/debugger/events/protocol-summarize.js +7 -0
  59. package/dist/debugger/lib/event-counts.d.ts +2 -2
  60. package/dist/debugger/lib/event-counts.js +5 -9
  61. package/dist/debugger/shell/debugger-shell.js +1 -1
  62. package/dist/debugger/shell/run-controls.d.ts +2 -1
  63. package/dist/debugger/shell/run-controls.js +40 -13
  64. package/dist/debugger/shell/run-search.js +1 -3
  65. package/dist/evaluator/effects.d.ts +12 -0
  66. package/dist/evaluator/module.d.ts +24 -0
  67. package/dist/projectors/index-model.d.ts +13 -7
  68. package/dist/projectors/index-model.js +21 -26
  69. package/dist/projectors/memory.js +19 -11
  70. package/dist/projectors/postgres.js +20 -19
  71. package/dist/projectors/schema.js +20 -18
  72. package/dist/projectors/sqlite.js +32 -27
  73. package/dist/react/materialize.js +16 -11
  74. package/dist/react/react.d.ts +6 -2
  75. package/dist/react/react.js +5 -2
  76. package/dist/react/tables.d.ts +3 -2
  77. package/dist/runtime/cancellation.js +14 -27
  78. package/dist/runtime/errors.d.ts +39 -0
  79. package/dist/runtime/errors.js +32 -0
  80. package/dist/runtime/helpers.d.ts +2 -0
  81. package/dist/runtime/helpers.js +23 -1
  82. package/dist/runtime/index.d.ts +1 -1
  83. package/dist/runtime/index.js +1 -1
  84. package/dist/runtime/looms.d.ts +4 -0
  85. package/dist/runtime/looms.js +1 -0
  86. package/dist/runtime/run-start.js +1 -3
  87. package/dist/runtime/runtime.d.ts +1 -1
  88. package/dist/runtime/runtime.js +45 -18
  89. package/dist/runtime/server/http.d.ts +2 -0
  90. package/dist/runtime/server/http.js +17 -2
  91. package/dist/runtime/server/routes/runs.js +35 -2
  92. package/dist/runtime/types.d.ts +8 -0
  93. package/dist/runtime/wake-engine.js +5 -2
  94. package/dist/s2/snapshot-store.js +2 -6
  95. package/dist/workflow/effects.d.ts +24 -0
  96. package/dist/workflow/effects.js +1 -0
  97. package/dist/workflow/module.d.ts +48 -0
  98. package/package.json +1 -1
  99. package/dist/debugger/app/assets/index-B3Ah8WAE.css +0 -2
  100. package/dist/debugger/app/assets/routes-CjtEHgPQ.js +0 -47
@@ -1,8 +1,8 @@
1
1
  import { Clock, Effect, ManagedRuntime, Predicate } from 'effect';
2
- import { composeModules, createEvent, createThreadId, createRunId, DEFAULT_DEFINITION_VERSION, DEFAULT_SNAPSHOT_EVERY, definitionKey, EventStoreTag, foldRun, project, replayTo, summarizeRun, } from '@swirls/looms/core';
2
+ import { composeModules, createEvent, createThreadId, createRunId, DEFAULT_DEFINITION_VERSION, DEFAULT_SNAPSHOT_EVERY, definitionKey, descendantThreadIds, EventStoreTag, foldRun, isRunTerminal, planFork, project, replayTo, summarizeRun, } from '@swirls/looms/core';
3
3
  import { createCancellation } from './cancellation.js';
4
4
  import { nextRuntimeDeadline } from './deadline-transition-planner.js';
5
- import { RuntimeExecutionError } from './errors.js';
5
+ import { ForkConflictError, RunNotFinishedError, RunNotFoundError, RunTerminalError, RuntimeExecutionError, } from './errors.js';
6
6
  import { admitExternalEvents, moduleServices, resolveSnapshotStore, RunCursorCache, threadStartedEvents, UnknownDefinitionError, validateAndCreateEvents, waitSatisfiedEvents, } from './helpers.js';
7
7
  import { createRunIngress } from './ingress.js';
8
8
  import { notifyObserver } from './observer.js';
@@ -13,26 +13,21 @@ import { createWakeEngine } from './wake-engine.js';
13
13
  import { createTimeoutScheduler } from './wake-scheduler.js';
14
14
  import { createWorkerCallbacks } from './worker-callbacks.js';
15
15
  export { createTimeoutScheduler } from './wake-scheduler.js';
16
- export { DuplicateEffectDispatchError, MaxWakeIterationsError, StartRunConflictError, } from './errors.js';
16
+ export { DuplicateEffectDispatchError, ForkConflictError, MaxWakeIterationsError, RunNotFinishedError, RunNotFoundError, RunTerminalError, StartRunConflictError, } from './errors.js';
17
17
  export { RunOverloadedError } from './ingress.js';
18
18
  function currentTimeMillis() {
19
19
  return Math.floor(performance.timeOrigin + performance.now());
20
20
  }
21
- /** Threads whose in-process effects an admitted signal interrupts. */
22
- function interruptedThreadIds(events, rules) {
23
- const threadIds = new Set();
24
- for (const event of events) {
21
+ /** Threads whose in-process effects an admitted signal interrupts: each named one and its subtree. */
22
+ function interruptedThreadIds(events, rules, state) {
23
+ const named = events.flatMap((event) => {
25
24
  const payload = Predicate.isObject(event.payload) ? event.payload : {};
26
- if (event.type === 'runtime.thread.cancel.requested' && Predicate.isString(payload.threadId)) {
27
- threadIds.add(payload.threadId);
28
- }
29
- for (const rule of rules) {
30
- for (const threadId of rule(event)) {
31
- threadIds.add(threadId);
32
- }
33
- }
34
- }
35
- return threadIds;
25
+ const cancelled = event.type === 'runtime.thread.cancel.requested' && Predicate.isString(payload.threadId)
26
+ ? [payload.threadId]
27
+ : [];
28
+ return [...cancelled, ...rules.flatMap((rule) => rule(event))];
29
+ });
30
+ return new Set(named.flatMap((threadId) => [threadId, ...descendantThreadIds(state, threadId)]));
36
31
  }
37
32
  const DEFAULT_RUN_CACHE_SIZE = 0;
38
33
  const RESCAN_CONCURRENCY = 16;
@@ -83,6 +78,9 @@ export function createRuntime(options) {
83
78
  ...input,
84
79
  idempotencyKey: input.idempotencyKey ?? signalKey,
85
80
  })), { origin: { type: 'external' } });
81
+ if (isRunTerminal(current.state)) {
82
+ return yield* new RunTerminalError(runId, current.state.status);
83
+ }
86
84
  const folded = foldRun(batch, registry, { runId, initial: current.state });
87
85
  const satisfiedEvents = waitSatisfiedEvents(folded, batch).map((input) => createEvent(runId, input));
88
86
  return {
@@ -92,7 +90,7 @@ export function createRuntime(options) {
92
90
  };
93
91
  }));
94
92
  if (committed.append) {
95
- executionContexts.abort(runId, interruptedThreadIds(events, registry.interruptRules), 'Effect interrupted');
93
+ executionContexts.abort(runId, interruptedThreadIds(events, registry.interruptRules, committed.value), 'Effect interrupted');
96
94
  }
97
95
  return committed.value;
98
96
  });
@@ -295,6 +293,35 @@ export function createRuntime(options) {
295
293
  },
296
294
  signal: (runId, events, signalOpts) => admitExternalEvents(events).pipe(Effect.flatMap((admitted) => withRunIngress(runId, signalAdmitted(runId, admitted, signalOpts))), Effect.andThen(runtime.wake(runId))),
297
295
  cancel: cancellation,
296
+ fork: (sourceRunId, forkOptions) => {
297
+ const runId = forkOptions?.runId ?? createRunId();
298
+ return withRunIngress(runId, Effect.gen(function* () {
299
+ const store = yield* EventStoreTag;
300
+ const source = yield* loadCursor(store, sourceRunId);
301
+ if (source.seq === 0) {
302
+ return yield* new RunNotFoundError(sourceRunId);
303
+ }
304
+ if (!isRunTerminal(source.state)) {
305
+ return yield* new RunNotFinishedError(sourceRunId, source.state.status);
306
+ }
307
+ const plan = yield* planFork({
308
+ sourceRunId,
309
+ runId,
310
+ events: yield* store.read(sourceRunId),
311
+ registry,
312
+ });
313
+ // Appending at tail 0 numbers the copied events 1..n, the seqs they had in the source.
314
+ yield* commit(store, runId, (existing) => {
315
+ if (existing.seq === 0) {
316
+ return Effect.succeed({ events: plan.events, value: undefined });
317
+ }
318
+ return existing.state.forkedFrom?.runId === sourceRunId
319
+ ? Effect.succeed({ events: [], value: undefined })
320
+ : Effect.fail(new ForkConflictError(runId, sourceRunId));
321
+ });
322
+ return plan.rootThreadId;
323
+ })).pipe(Effect.flatMap((threadId) => runtime.wake(runId).pipe(Effect.map((state) => ({ runId, threadId, state })))));
324
+ },
298
325
  wake: wakeEngine,
299
326
  dispose: Effect.sync(() => scheduler.dispose?.()).pipe(Effect.andThen(services.disposeEffect)),
300
327
  };
@@ -29,6 +29,8 @@ export declare const EventInputBodySchema: Schema.Struct<{
29
29
  export declare function isLoomsApiPath(path: string): boolean;
30
30
  export declare function provideStore<A, E>(effect: Effect.Effect<A, E, EventStoreTag>, store: EventStore): Effect.Effect<A, E>;
31
31
  export declare const readJson: (req: Request) => Effect.Effect<JsonValue, RequestBodyError>;
32
+ /** `readJson` for routes whose body is optional: a request without one reads as `{}`. */
33
+ export declare const readOptionalJson: (req: Request) => Effect.Effect<JsonValue, RequestBodyError>;
32
34
  export declare function extractIdempotencyKey(req: Request, bodyKey?: string): string | undefined;
33
35
  export declare function acceptsEventStream(req: Request): boolean;
34
36
  export declare function readIntegerQuery(url: URL, name: string, options: {
@@ -1,6 +1,6 @@
1
1
  import { Data, Effect, Schema } from 'effect';
2
- import { EventStoreTag, InvalidEventError, InvalidInputError, JsonValueSchema, } from '@swirls/looms/core';
3
- import { RunOverloadedError, StartRunConflictError } from '../runtime.js';
2
+ import { EventStoreTag, ForkSourceError, InvalidEventError, InvalidInputError, JsonValueSchema, } from '@swirls/looms/core';
3
+ import { ForkConflictError, RunNotFinishedError, RunNotFoundError, RunOverloadedError, RunTerminalError, StartRunConflictError, } from '../runtime.js';
4
4
  export class RequestBodyError extends Data.TaggedError('RequestBodyError') {
5
5
  constructor(cause) {
6
6
  super({ cause, message: 'Invalid JSON request body' });
@@ -25,6 +25,10 @@ export const readJson = (req) => Effect.tryPromise({
25
25
  try: () => req.json(),
26
26
  catch: (cause) => new RequestBodyError(cause),
27
27
  }).pipe(Effect.flatMap(Schema.decodeUnknownEffect(JsonValueSchema)), Effect.mapError((cause) => cause instanceof RequestBodyError ? cause : new RequestBodyError(cause)));
28
+ /** `readJson` for routes whose body is optional: a request without one reads as `{}`. */
29
+ export const readOptionalJson = (req) => req.body === null || req.headers.get('content-length') === '0'
30
+ ? Effect.succeed({})
31
+ : readJson(req);
28
32
  export function extractIdempotencyKey(req, bodyKey) {
29
33
  return (bodyKey ??
30
34
  req.headers.get('idempotency-key') ??
@@ -59,8 +63,19 @@ export function toErrorResponse(err) {
59
63
  if (err instanceof RunOverloadedError) {
60
64
  return Response.json({ error: err.message }, { status: 429 });
61
65
  }
66
+ if (err instanceof RunNotFoundError) {
67
+ return Response.json({ error: err.message }, { status: 404 });
68
+ }
69
+ if (err instanceof RunTerminalError) {
70
+ return Response.json({ error: err.message, status: err.status }, { status: 409 });
71
+ }
62
72
  if (err instanceof StartRunConflictError) {
63
73
  return Response.json({ error: err.message, mismatches: err.mismatches }, { status: 409 });
64
74
  }
75
+ if (err instanceof RunNotFinishedError ||
76
+ err instanceof ForkConflictError ||
77
+ err instanceof ForkSourceError) {
78
+ return Response.json({ error: err.message }, { status: 409 });
79
+ }
65
80
  return Response.json({ error: err.message }, { status: 500 });
66
81
  }
@@ -1,7 +1,7 @@
1
1
  import { Effect, Schema } from 'effect';
2
2
  import { createRunId, EventStoreTag, JsonValueSchema, stringifyJson, } from '@swirls/looms/core';
3
3
  import { createEventStreamResponse } from '../../sse.js';
4
- import { acceptsEventStream, EventInputBodySchema, extractIdempotencyKey, provideStore, readIntegerQuery, readJson, RequestQueryError, } from '../http.js';
4
+ import { acceptsEventStream, EventInputBodySchema, extractIdempotencyKey, provideStore, readIntegerQuery, readJson, readOptionalJson, RequestQueryError, } from '../http.js';
5
5
  import { route } from '../route-table.js';
6
6
  const StartRunBodySchema = Schema.Struct({
7
7
  kind: Schema.optional(Schema.String),
@@ -19,6 +19,12 @@ const SignalBodySchema = Schema.Struct({
19
19
  threadId: Schema.optional(Schema.NullOr(Schema.String)),
20
20
  idempotencyKey: Schema.optional(Schema.String),
21
21
  });
22
+ const CancelBodySchema = Schema.Struct({
23
+ threadId: Schema.optional(Schema.String),
24
+ });
25
+ const ForkBodySchema = Schema.Struct({
26
+ runId: Schema.optional(Schema.String),
27
+ });
22
28
  function wantsRunStream(req, url) {
23
29
  return url.searchParams.get('stream') === 'true' || acceptsEventStream(req);
24
30
  }
@@ -193,7 +199,34 @@ export function runRoutes({ runtime, store }) {
193
199
  path: '/runs/:runId/wake',
194
200
  name: 'runs.wake',
195
201
  access: 'write',
196
- handle: ({ params }) => provideStore(runtime.wake(params.runId), store).pipe(Effect.map((state) => Response.json({ runId: params.runId, state }))),
202
+ handle: ({ params }) => Effect.gen(function* () {
203
+ const before = yield* store.tail(params.runId);
204
+ const state = yield* provideStore(runtime.wake(params.runId), store);
205
+ const appended = (yield* store.tail(params.runId)) - before;
206
+ return Response.json({ runId: params.runId, state, appended });
207
+ }),
208
+ }),
209
+ route({
210
+ method: 'POST',
211
+ path: '/runs/:runId/cancel',
212
+ name: 'runs.cancel',
213
+ access: 'write',
214
+ handle: ({ req, params }) => Effect.gen(function* () {
215
+ const body = yield* readOptionalJson(req).pipe(Effect.flatMap(Schema.decodeUnknownEffect(CancelBodySchema)));
216
+ const state = yield* provideStore(runtime.cancel(params.runId, body.threadId), store);
217
+ return Response.json({ runId: params.runId, state });
218
+ }),
219
+ }),
220
+ route({
221
+ method: 'POST',
222
+ path: '/runs/:runId/fork',
223
+ name: 'runs.fork',
224
+ access: 'write',
225
+ handle: ({ req, params }) => Effect.gen(function* () {
226
+ const body = yield* readOptionalJson(req).pipe(Effect.flatMap(Schema.decodeUnknownEffect(ForkBodySchema)));
227
+ const result = yield* provideStore(runtime.fork(params.runId, { runId: body.runId }), store);
228
+ return Response.json(result);
229
+ }),
197
230
  }),
198
231
  ];
199
232
  }
@@ -105,6 +105,14 @@ export interface LoomsRuntime<TModules extends readonly AnyRuntimeModule[] = rea
105
105
  inspectRun(runId: string): Effect.Effect<RunOperationalStatus, EventStoreError | EventStoreTrimmedError | EventStoreTruncationError, EventStoreTag>;
106
106
  retryEffect(runId: string, effectId: string): Effect.Effect<RunState, Error | EventStoreAppendError | EventStoreError, EventStoreTag>;
107
107
  cancel(runId: string, threadId?: string): Effect.Effect<RunState, Error | EventStoreAppendError | EventStoreError, EventStoreTag>;
108
+ /**
109
+ * Start a new run that continues where a finished run ended. The fork copies the source's
110
+ * history up to the point it finished and re-issues the effects outstanding there. Retrying
111
+ * with the same `runId` returns the existing fork.
112
+ */
113
+ fork(sourceRunId: string, options?: {
114
+ runId?: string;
115
+ }): Effect.Effect<StartResult, Error | EventStoreAppendError | EventStoreError, EventStoreTag>;
108
116
  /** Applies a worker's report about one effect attempt; stale or foreign reports are ignored. */
109
117
  workerCallback(runId: string, input: WorkerCallbackInput): Effect.Effect<RunState, Error | EventStoreAppendError | EventStoreError, EventStoreTag>;
110
118
  readonly listRuns: Effect.Effect<string[], EventStoreError, EventStoreTag>;
@@ -2,7 +2,7 @@ import { Clock, Effect, Exit, Option } from 'effect';
2
2
  import { createEvent, EventStoreTag, foldRun, isRunTerminal, } from '@swirls/looms/core';
3
3
  import { nextRuntimeDeadline, planDeadlineTransitions, planTerminalCancellationTransitions, } from './deadline-transition-planner.js';
4
4
  import { DuplicateEffectDispatchError, MaxWakeIterationsError, RuntimeExecutionError, } from './errors.js';
5
- import { stripSeq, synthesizedThreadFailed, waitSatisfiedEvents } from './helpers.js';
5
+ import { cascadedCancellations, stripSeq, synthesizedThreadFailed, waitSatisfiedEvents, } from './helpers.js';
6
6
  import { executeLocalEffects } from './local-effect-executor.js';
7
7
  import { notifyObserver } from './observer.js';
8
8
  import { dispatchWorkerEffect, isWorkerEffect, planWorkerEffects } from './worker-effect-dispatch.js';
@@ -225,7 +225,10 @@ export function createWakeEngine(options) {
225
225
  yield* liveAppends.drain(runId);
226
226
  const beforeFold = cursor.state;
227
227
  const intermediateState = foldRun(produced, registry, { runId, initial: beforeFold });
228
- const synthesized = synthesizedThreadFailed(beforeFold, intermediateState, produced);
228
+ const synthesized = [
229
+ ...synthesizedThreadFailed(beforeFold, intermediateState, produced),
230
+ ...cascadedCancellations(intermediateState, produced),
231
+ ];
229
232
  const synthesizedEvents = synthesized.map((input) => createEvent(runId, input));
230
233
  const stateAfterSynth = synthesizedEvents.length > 0
231
234
  ? foldRun(synthesizedEvents, registry, { runId, initial: intermediateState })
@@ -44,9 +44,7 @@ export function assembleSnapshot(frames) {
44
44
  throw new SnapshotStoreError('Cannot assemble snapshot from empty frames');
45
45
  }
46
46
  const first = frames[0];
47
- // Oxlint's immutable alternative requires ES2023; sorting a fresh copy is safe on ES2022.
48
- // oxlint-disable-next-line unicorn/no-array-sort
49
- const ordered = [...frames].sort((a, b) => a.chunk - b.chunk);
47
+ const ordered = frames.toSorted((a, b) => a.chunk - b.chunk);
50
48
  for (const frame of ordered) {
51
49
  if (frame.cursor !== first.cursor ||
52
50
  frame.chunks !== first.chunks ||
@@ -163,9 +161,7 @@ function groupCompleteSnapshots(records) {
163
161
  continue;
164
162
  }
165
163
  }
166
- // `assembled` is function-local, so in-place sorting cannot mutate caller-owned data.
167
- // oxlint-disable-next-line unicorn/no-array-sort
168
- return assembled.sort((a, b) => a.cursor - b.cursor);
164
+ return assembled.toSorted((a, b) => a.cursor - b.cursor);
169
165
  }
170
166
  export function s2SnapshotStore(config) {
171
167
  const parsed = Schema.decodeSync(S2ConfigSchema)(config);
@@ -104,6 +104,11 @@ export declare const scheduleEffect: NoInfer<import("@swirls/looms/core").Effect
104
104
  readonly attempt: number;
105
105
  readonly deadlineAt: number | null;
106
106
  };
107
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
108
+ readonly type: "runtime.fork.elided";
109
+ readonly payload: {
110
+ readonly type: string;
111
+ };
107
112
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
108
113
  readonly type: "runtime.run.cancelled";
109
114
  readonly payload: {
@@ -115,6 +120,12 @@ export declare const scheduleEffect: NoInfer<import("@swirls/looms/core").Effect
115
120
  readonly output: Schema.Json;
116
121
  readonly error: string | null;
117
122
  };
123
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
124
+ readonly type: "runtime.run.forked";
125
+ readonly payload: {
126
+ readonly sourceRunId: string;
127
+ readonly sourceSeq: number;
128
+ };
118
129
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
119
130
  readonly type: "runtime.run.started";
120
131
  readonly payload: {
@@ -147,6 +158,7 @@ export declare const scheduleEffect: NoInfer<import("@swirls/looms/core").Effect
147
158
  readonly payload: {
148
159
  readonly threadId: string;
149
160
  readonly reason?: string | undefined;
161
+ readonly resumeSeq?: number | undefined;
150
162
  };
151
163
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
152
164
  readonly type: "runtime.thread.completed";
@@ -431,6 +443,11 @@ export declare const runNodeEffect: NoInfer<import("@swirls/looms/core").EffectD
431
443
  readonly attempt: number;
432
444
  readonly deadlineAt: number | null;
433
445
  };
446
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
447
+ readonly type: "runtime.fork.elided";
448
+ readonly payload: {
449
+ readonly type: string;
450
+ };
434
451
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
435
452
  readonly type: "runtime.run.cancelled";
436
453
  readonly payload: {
@@ -442,6 +459,12 @@ export declare const runNodeEffect: NoInfer<import("@swirls/looms/core").EffectD
442
459
  readonly output: Schema.Json;
443
460
  readonly error: string | null;
444
461
  };
462
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
463
+ readonly type: "runtime.run.forked";
464
+ readonly payload: {
465
+ readonly sourceRunId: string;
466
+ readonly sourceSeq: number;
467
+ };
445
468
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
446
469
  readonly type: "runtime.run.started";
447
470
  readonly payload: {
@@ -474,6 +497,7 @@ export declare const runNodeEffect: NoInfer<import("@swirls/looms/core").EffectD
474
497
  readonly payload: {
475
498
  readonly threadId: string;
476
499
  readonly reason?: string | undefined;
500
+ readonly resumeSeq?: number | undefined;
477
501
  };
478
502
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
479
503
  readonly type: "runtime.thread.completed";
@@ -46,6 +46,7 @@ function threadFailed(threadId, error) {
46
46
  export const scheduleEffect = workflowModule.effect({
47
47
  type: 'workflow.schedule',
48
48
  input: ScheduleInput,
49
+ deterministic: true,
49
50
  execute: (input, ctx) => Effect.gen(function* () {
50
51
  const workflows = yield* WorkflowDefinitionsTag;
51
52
  const definition = input.definitionName
@@ -203,6 +203,11 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
203
203
  readonly attempt: number;
204
204
  readonly deadlineAt: number | null;
205
205
  };
206
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
207
+ readonly type: "runtime.fork.elided";
208
+ readonly payload: {
209
+ readonly type: string;
210
+ };
206
211
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
207
212
  readonly type: "runtime.run.cancelled";
208
213
  readonly payload: {
@@ -214,6 +219,12 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
214
219
  readonly output: import("effect/Schema").Json;
215
220
  readonly error: string | null;
216
221
  };
222
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
223
+ readonly type: "runtime.run.forked";
224
+ readonly payload: {
225
+ readonly sourceRunId: string;
226
+ readonly sourceSeq: number;
227
+ };
217
228
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
218
229
  readonly type: "runtime.run.started";
219
230
  readonly payload: {
@@ -246,6 +257,7 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
246
257
  readonly payload: {
247
258
  readonly threadId: string;
248
259
  readonly reason?: string | undefined;
260
+ readonly resumeSeq?: number | undefined;
249
261
  };
250
262
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
251
263
  readonly type: "runtime.thread.completed";
@@ -526,6 +538,11 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
526
538
  readonly attempt: number;
527
539
  readonly deadlineAt: number | null;
528
540
  };
541
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
542
+ readonly type: "runtime.fork.elided";
543
+ readonly payload: {
544
+ readonly type: string;
545
+ };
529
546
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
530
547
  readonly type: "runtime.run.cancelled";
531
548
  readonly payload: {
@@ -537,6 +554,12 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
537
554
  readonly output: import("effect/Schema").Json;
538
555
  readonly error: string | null;
539
556
  };
557
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
558
+ readonly type: "runtime.run.forked";
559
+ readonly payload: {
560
+ readonly sourceRunId: string;
561
+ readonly sourceSeq: number;
562
+ };
540
563
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
541
564
  readonly type: "runtime.run.started";
542
565
  readonly payload: {
@@ -569,6 +592,7 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
569
592
  readonly payload: {
570
593
  readonly threadId: string;
571
594
  readonly reason?: string | undefined;
595
+ readonly resumeSeq?: number | undefined;
572
596
  };
573
597
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
574
598
  readonly type: "runtime.thread.completed";
@@ -1003,6 +1027,11 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
1003
1027
  readonly attempt: number;
1004
1028
  readonly deadlineAt: number | null;
1005
1029
  };
1030
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1031
+ readonly type: "runtime.fork.elided";
1032
+ readonly payload: {
1033
+ readonly type: string;
1034
+ };
1006
1035
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1007
1036
  readonly type: "runtime.run.cancelled";
1008
1037
  readonly payload: {
@@ -1014,6 +1043,12 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
1014
1043
  readonly output: import("effect/Schema").Json;
1015
1044
  readonly error: string | null;
1016
1045
  };
1046
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1047
+ readonly type: "runtime.run.forked";
1048
+ readonly payload: {
1049
+ readonly sourceRunId: string;
1050
+ readonly sourceSeq: number;
1051
+ };
1017
1052
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1018
1053
  readonly type: "runtime.run.started";
1019
1054
  readonly payload: {
@@ -1046,6 +1081,7 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
1046
1081
  readonly payload: {
1047
1082
  readonly threadId: string;
1048
1083
  readonly reason?: string | undefined;
1084
+ readonly resumeSeq?: number | undefined;
1049
1085
  };
1050
1086
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1051
1087
  readonly type: "runtime.thread.completed";
@@ -1326,6 +1362,11 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
1326
1362
  readonly attempt: number;
1327
1363
  readonly deadlineAt: number | null;
1328
1364
  };
1365
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1366
+ readonly type: "runtime.fork.elided";
1367
+ readonly payload: {
1368
+ readonly type: string;
1369
+ };
1329
1370
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1330
1371
  readonly type: "runtime.run.cancelled";
1331
1372
  readonly payload: {
@@ -1337,6 +1378,12 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
1337
1378
  readonly output: import("effect/Schema").Json;
1338
1379
  readonly error: string | null;
1339
1380
  };
1381
+ }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1382
+ readonly type: "runtime.run.forked";
1383
+ readonly payload: {
1384
+ readonly sourceRunId: string;
1385
+ readonly sourceSeq: number;
1386
+ };
1340
1387
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1341
1388
  readonly type: "runtime.run.started";
1342
1389
  readonly payload: {
@@ -1369,6 +1416,7 @@ export declare function workflow(options?: WorkflowModuleOptions): import("@swir
1369
1416
  readonly payload: {
1370
1417
  readonly threadId: string;
1371
1418
  readonly reason?: string | undefined;
1419
+ readonly resumeSeq?: number | undefined;
1372
1420
  };
1373
1421
  }) | (Omit<import("@swirls/looms/core").EventInput, "payload" | "type"> & {
1374
1422
  readonly type: "runtime.thread.completed";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swirls/looms",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Pluggable event-sourced runtime for durable agents and workflows",
5
5
  "homepage": "https://github.com/ByteSliceHQ/looms#readme",
6
6
  "bugs": {
@@ -1,2 +0,0 @@
1
- /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--color-black:#000;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-relaxed:1.625;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:ui-sans-serif, system-ui, -apple-system, sans-serif;--default-mono-font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--color-border:var(--border)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--background:oklch(16% .005 260);--foreground:oklch(93% .01 260);--card:oklch(19% .006 260);--card-foreground:oklch(93% .01 260);--primary:oklch(93% .01 260);--primary-foreground:oklch(20% .006 260);--secondary:oklch(24% .008 260);--secondary-foreground:oklch(93% .01 260);--muted:oklch(24% .008 260);--muted-foreground:oklch(68% .015 260);--accent:oklch(26% .01 260);--accent-foreground:oklch(95% .01 260);--destructive:oklch(65% .18 25);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.12);--ring:oklch(55% .02 260);--sidebar:oklch(18% .006 260);--sidebar-foreground:oklch(93% .01 260)}:where(.looms-debugger,.debugger-pop),:where(.looms-debugger,.debugger-pop) *,:where(.looms-debugger,.debugger-pop) :before,:where(.looms-debugger,.debugger-pop) :after{border-color:var(--color-border)}}@layer components;@layer utilities{.\@container{container-type:inline-size}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-y-0{inset-block:0}.top-0{top:0}.top-0\.5{top:calc(var(--spacing) * .5)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.right-0{right:0}.right-0\.5{right:calc(var(--spacing) * .5)}.bottom-3{bottom:calc(var(--spacing) * 3)}.left-0{left:0}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-2{margin-inline:calc(var(--spacing) * 2)}.my-1{margin-block:var(--spacing)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mr-1{margin-right:var(--spacing)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.field-sizing-content{field-sizing:content}.size-1\.5{width:calc(var(--spacing) * 1.5);height:calc(var(--spacing) * 1.5)}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-full{width:100%;height:100%}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-\[26px\]{height:26px}.h-\[45\%\]{height:45%}.h-full{height:100%}.h-px{height:1px}.max-h-\(--radix-dropdown-menu-content-available-height\){max-height:var(--radix-dropdown-menu-content-available-height)}.max-h-48{max-height:calc(var(--spacing) * 48)}.max-h-64{max-height:calc(var(--spacing) * 64)}.max-h-80{max-height:calc(var(--spacing) * 80)}.min-h-0{min-height:0}.min-h-11{min-height:calc(var(--spacing) * 11)}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-20{min-height:calc(var(--spacing) * 20)}.min-h-28{min-height:calc(var(--spacing) * 28)}.min-h-32{min-height:calc(var(--spacing) * 32)}.min-h-40{min-height:calc(var(--spacing) * 40)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-7{width:calc(var(--spacing) * 7)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-60{width:calc(var(--spacing) * 60)}.w-72{width:calc(var(--spacing) * 72)}.w-80{width:calc(var(--spacing) * 80)}.w-\[26rem\]{width:26rem}.w-\[calc\(100\%\+0\.5rem\)\]{width:calc(100% + .5rem)}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-60{max-width:calc(var(--spacing) * 60)}.max-w-64{max-width:calc(var(--spacing) * 64)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.min-w-40{min-width:calc(var(--spacing) * 40)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.touch-none{touch-action:none}.resize-none{resize:none}.scroll-py-1{scroll-padding-block:var(--spacing)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-rows-\[minmax\(0\,38\%\)_minmax\(0\,1fr\)\]{grid-template-rows:minmax(0,38%) minmax(0,1fr)}.flex-col{flex-direction:column}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0{gap:0}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overscroll-contain{overscroll-behavior:contain}.rounded{border-radius:.25rem}.rounded-\[1px\]{border-radius:1px}.rounded-\[3px\]{border-radius:3px}.rounded-\[inherit\]{border-radius:inherit}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) * .8)}.rounded-sm{border-radius:calc(var(--radius) * .6)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-border,.border-border\/70{border-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.border-border\/70{border-color:color-mix(in oklab, var(--border) 70%, transparent)}}.border-input{border-color:var(--input)}.border-t-transparent{border-top-color:#0000}.border-l-transparent{border-left-color:#0000}.bg-accent{background-color:var(--accent)}.bg-background,.bg-background\/40{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/40{background-color:color-mix(in oklab, var(--background) 40%, transparent)}}.bg-background\/60{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/60{background-color:color-mix(in oklab, var(--background) 60%, transparent)}}.bg-background\/95{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.bg-background\/95{background-color:color-mix(in oklab, var(--background) 95%, transparent)}}.bg-border{background-color:var(--border)}.bg-card,.bg-card\/60{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\/60{background-color:color-mix(in oklab, var(--card) 60%, transparent)}}.bg-card\/90{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\/90{background-color:color-mix(in oklab, var(--card) 90%, transparent)}}.bg-card\/95{background-color:var(--card)}@supports (color:color-mix(in lab, red, red)){.bg-card\/95{background-color:color-mix(in oklab, var(--card) 95%, transparent)}}.bg-current\/10{background-color:currentColor}@supports (color:color-mix(in lab, red, red)){.bg-current\/10{background-color:color-mix(in oklab, currentcolor 10%, transparent)}}.bg-foreground,.bg-foreground\/15{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.bg-foreground\/15{background-color:color-mix(in oklab, var(--foreground) 15%, transparent)}}.bg-foreground\/70{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.bg-foreground\/70{background-color:color-mix(in oklab, var(--foreground) 70%, transparent)}}.bg-primary{background-color:var(--primary)}.bg-secondary,.bg-secondary\/70{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.bg-secondary\/70{background-color:color-mix(in oklab, var(--secondary) 70%, transparent)}}.bg-sidebar{background-color:var(--sidebar)}.bg-status-cancelled{background-color:var(--status-cancelled)}.bg-status-completed{background-color:var(--status-completed)}.bg-status-failed,.bg-status-failed\/10{background-color:var(--status-failed)}@supports (color:color-mix(in lab, red, red)){.bg-status-failed\/10{background-color:color-mix(in oklab, var(--status-failed) 10%, transparent)}}.bg-status-running{background-color:var(--status-running)}.bg-status-waiting{background-color:var(--status-waiting)}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:var(--spacing)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.p-px{padding:1px}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-px{padding-block:1px}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pr-0\.5{padding-right:calc(var(--spacing) * .5)}.pr-1{padding-right:var(--spacing)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-1{padding-bottom:var(--spacing)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-0{padding-left:0}.pl-1{padding-left:var(--spacing)}.pl-1\.5{padding-left:calc(var(--spacing) * 1.5)}.pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-7{padding-left:calc(var(--spacing) * 7)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-\[-2px\]{vertical-align:-2px}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}.font-sans{font-family:ui-sans-serif,system-ui,-apple-system,sans-serif}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.leading-3\.5{--tw-leading:calc(var(--spacing) * 3.5);line-height:calc(var(--spacing) * 3.5)}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--background)}.text-border{color:var(--border)}.text-card-foreground{color:var(--card-foreground)}.text-foreground{color:var(--foreground)}.text-json-boolean{color:var(--json-boolean)}.text-json-key{color:var(--json-key)}.text-json-null{color:var(--json-null)}.text-json-number{color:var(--json-number)}.text-json-string{color:var(--json-string)}.text-muted-foreground,.text-muted-foreground\/60{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/60{color:color-mix(in oklab, var(--muted-foreground) 60%, transparent)}}.text-muted-foreground\/70{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/70{color:color-mix(in oklab, var(--muted-foreground) 70%, transparent)}}.text-muted-foreground\/80{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/80{color:color-mix(in oklab, var(--muted-foreground) 80%, transparent)}}.text-primary-foreground{color:var(--primary-foreground)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-status-cancelled{color:var(--status-cancelled)}.text-status-completed{color:var(--status-completed)}.text-status-failed{color:var(--status-failed)}.text-status-running{color:var(--status-running)}.text-status-waiting{color:var(--status-waiting)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-black\/30{--tw-shadow-color:#0000004d}@supports (color:color-mix(in lab, red, red)){.shadow-black\/30{--tw-shadow-color:color-mix(in oklab, color-mix(in oklab, var(--color-black) 30%, transparent) var(--tw-shadow-alpha), transparent)}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.backdrop-blur{--tw-backdrop-blur:blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition-\[border-color\,box-shadow\]{transition-property:border-color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[transform\,background-color\,color\,opacity\]{transition-property:transform,background-color,color,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.ease-snappy{--tw-ease:var(--debugger-ease);transition-timing-function:var(--debugger-ease)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\/branch\:text-foreground:is(:where(.group\/branch):hover *){color:var(--foreground)}.group-hover\/json\:opacity-100:is(:where(.group\/json):hover *){opacity:1}}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:inset-y-0:after{content:var(--tw-content);inset-block:0}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:w-2:after{content:var(--tw-content);width:calc(var(--spacing) * 2)}.after\:-translate-x-1\/2:after{content:var(--tw-content);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.focus-within\:border-ring\/70:focus-within{border-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-within\:border-ring\/70:focus-within{border-color:color-mix(in oklab, var(--ring) 70%, transparent)}}.focus-within\:ring-\[3px\]:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-within\:ring-ring\/25:focus-within{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-within\:ring-ring\/25:focus-within{--tw-ring-color:color-mix(in oklab, var(--ring) 25%, transparent)}}@media (hover:hover){.hover\:border-ring\/40:hover{border-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.hover\:border-ring\/40:hover{border-color:color-mix(in oklab, var(--ring) 40%, transparent)}}.hover\:bg-accent:hover,.hover\:bg-accent\/40:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/40:hover{background-color:color-mix(in oklab, var(--accent) 40%, transparent)}}.hover\:bg-accent\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/50:hover{background-color:color-mix(in oklab, var(--accent) 50%, transparent)}}.hover\:bg-accent\/60:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/60:hover{background-color:color-mix(in oklab, var(--accent) 60%, transparent)}}.hover\:bg-background\/40:hover{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-background\/40:hover{background-color:color-mix(in oklab, var(--background) 40%, transparent)}}.hover\:bg-background\/60:hover{background-color:var(--background)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-background\/60:hover{background-color:color-mix(in oklab, var(--background) 60%, transparent)}}.hover\:bg-foreground\/25:hover{background-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-foreground\/25:hover{background-color:color-mix(in oklab, var(--foreground) 25%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-status-failed\/15:hover{background-color:var(--status-failed)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-status-failed\/15:hover{background-color:color-mix(in oklab, var(--status-failed) 15%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-status-failed:hover{color:var(--status-failed)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:scale-\[0\.97\]:active{scale:.97}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.aria-pressed\:bg-accent[aria-pressed=true]{background-color:var(--accent)}.aria-pressed\:text-foreground[aria-pressed=true]{color:var(--foreground)}.aria-\[orientation\=vertical\]\:flex-col[aria-orientation=vertical]{flex-direction:column}.data-disabled\:pointer-events-none[data-disabled]{pointer-events:none}.data-disabled\:opacity-50[data-disabled]{opacity:.5}.data-\[disabled\=true\]\:pointer-events-none[data-disabled=true]{pointer-events:none}.data-\[disabled\=true\]\:opacity-50[data-disabled=true]{opacity:.5}.data-\[selected\=true\]\:bg-accent[data-selected=true]{background-color:var(--accent)}.data-\[selected\=true\]\:text-accent-foreground[data-selected=true]{color:var(--accent-foreground)}.data-\[separator\=active\]\:bg-ring[data-separator=active],.data-\[separator\=focus\]\:bg-ring[data-separator=focus],.data-\[separator\=hover\]\:bg-ring\/60[data-separator=hover]{background-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.data-\[separator\=hover\]\:bg-ring\/60[data-separator=hover]{background-color:color-mix(in oklab, var(--ring) 60%, transparent)}}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.data-\[state\=checked\]\:bg-foreground[data-state=checked]{background-color:var(--foreground)}.data-\[state\=checked\]\:text-background[data-state=checked]{color:var(--background)}.data-\[state\=hidden\]\:opacity-0[data-state=hidden]{opacity:0}.data-\[state\=open\]\:border-ring\/60[data-state=open]{border-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.data-\[state\=open\]\:border-ring\/60[data-state=open]{border-color:color-mix(in oklab, var(--ring) 60%, transparent)}}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=open\]\:text-foreground[data-state=open]{color:var(--foreground)}@media (width>=36rem){.min-\[36rem\]\:grid-cols-\[14rem_minmax\(0\,1fr\)\]{grid-template-columns:14rem minmax(0,1fr)}.min-\[36rem\]\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.min-\[36rem\]\:border-b-0{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}@container (width>=24rem){.\@sm\:ml-0{margin-left:0}.\@sm\:flex{display:flex}}@container (width>=28rem){.\@md\:flex{display:flex}.\@md\:max-w-64{max-width:calc(var(--spacing) * 64)}}@container (width>=32rem){.\@lg\:inline{display:inline}}.\[\&_\[cmdk-group-heading\]\]\:px-2 [cmdk-group-heading]{padding-inline:calc(var(--spacing) * 2)}.\[\&_\[cmdk-group-heading\]\]\:pt-2 [cmdk-group-heading]{padding-top:calc(var(--spacing) * 2)}.\[\&_\[cmdk-group-heading\]\]\:pb-1 [cmdk-group-heading]{padding-bottom:var(--spacing)}.\[\&_\[cmdk-group-heading\]\]\:text-\[11px\] [cmdk-group-heading]{font-size:11px}.\[\&_\[cmdk-group-heading\]\]\:font-medium [cmdk-group-heading]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.\[\&_\[cmdk-group-heading\]\]\:text-muted-foreground [cmdk-group-heading]{color:var(--muted-foreground)}.\[\&_svg\]\:size-3 svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\]\:size-3\.5 svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&\>div\]\:block\!>div{display:block!important}}:root{--debugger-ease:cubic-bezier(.23, 1, .32, 1);--status-running:oklch(74% .12 240);--status-waiting:oklch(80% .14 85);--status-completed:oklch(76% .13 155);--status-failed:oklch(68% .18 25);--status-cancelled:oklch(62% .01 260);--json-key:oklch(80% .06 280);--json-string:oklch(80% .1 150);--json-number:oklch(80% .1 230);--json-boolean:oklch(82% .11 70);--json-null:oklch(60% .01 260)}@keyframes debugger-pop-in{0%{opacity:0;transform:scale(.97)}}@keyframes debugger-fade-in{0%{opacity:0}}.debugger-pop{transform-origin:var(--radix-popper-transform-origin);animation:debugger-pop-in .15s var(--debugger-ease)}.debugger-pop[data-instant]{animation:none}.debugger-float-in{transition:opacity .15s var(--debugger-ease), transform .15s var(--debugger-ease), scale .15s var(--debugger-ease), background-color .15s var(--debugger-ease)}@starting-style{.debugger-float-in{opacity:0;transform:translateY(4px)}}@media (prefers-reduced-motion:reduce){.debugger-pop{animation-name:debugger-fade-in}.debugger-float-in{transition-property:opacity}}.debugger-event-stream{container-type:inline-size}.debugger-event-offset,.debugger-event-causation,.debugger-event-thread{display:none}@container (width>=24rem){.debugger-event-offset{display:inline}}@container (width>=34rem){.debugger-event-thread{display:inline}}@container (width>=44rem){.debugger-event-causation{display:inline}}:root{--radius:.375rem}html,body,#root{height:100%}html,body{overscroll-behavior:none}body{margin:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}