@swirls/looms 0.2.0 → 0.4.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.
- package/CHANGELOG.md +31 -0
- package/dist/actor/host.js +4 -6
- package/dist/actor/index.d.ts +1 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +5 -0
- package/dist/actor/routing.js +14 -0
- package/dist/agent/agent-session.js +1 -0
- package/dist/agent/debugger/agent-chat.js +45 -38
- package/dist/agent/debugger/streaming-text.d.ts +6 -0
- package/dist/agent/debugger/streaming-text.js +33 -0
- package/dist/agent/debugger/summarize.js +2 -0
- package/dist/agent/effects.d.ts +30 -0
- package/dist/agent/events.d.ts +2 -0
- package/dist/agent/events.js +2 -0
- package/dist/agent/llm.js +1 -8
- package/dist/agent/module.d.ts +230 -160
- package/dist/agent/module.js +11 -7
- package/dist/agent/projections.d.ts +5 -0
- package/dist/agent/projections.js +43 -2
- package/dist/agent/scope.d.ts +2 -0
- package/dist/agent/signals.d.ts +5 -0
- package/dist/agent/signals.js +7 -0
- package/dist/agent/threads.js +35 -21
- package/dist/agent/transcript.d.ts +7 -0
- package/dist/agent/transcript.js +19 -0
- package/dist/agent/types.d.ts +10 -0
- package/dist/agent/types.js +4 -0
- package/dist/approval/debugger/approvals-view.js +5 -3
- package/dist/approval/effects.d.ts +12 -0
- package/dist/approval/module.d.ts +24 -0
- package/dist/client/client.d.ts +292 -0
- package/dist/client/client.js +17 -1
- package/dist/cloudflare/router.d.ts +1 -1
- package/dist/cloudflare/router.js +6 -8
- package/dist/core/attempts.d.ts +8 -0
- package/dist/core/attempts.js +27 -0
- package/dist/core/effects.d.ts +7 -0
- package/dist/core/effects.js +1 -0
- package/dist/core/fold.js +12 -6
- package/dist/core/fork.d.ts +35 -0
- package/dist/core/fork.js +129 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +2 -0
- package/dist/core/module-scope.d.ts +1 -0
- package/dist/core/module.d.ts +2 -2
- package/dist/core/projection.d.ts +5 -4
- package/dist/core/projection.js +1 -0
- package/dist/core/protocol.d.ts +10 -1
- package/dist/core/protocol.js +11 -0
- package/dist/{react → core}/register.d.ts +9 -8
- package/dist/core/replay.d.ts +8 -0
- package/dist/core/snapshots.js +3 -17
- package/dist/core/state.d.ts +14 -0
- package/dist/core/state.js +25 -2
- package/dist/core/store.d.ts +1 -0
- package/dist/debugger/app/assets/index-CgDzWJg7.css +2 -0
- package/dist/debugger/app/assets/index-D--9esm9.js +22 -0
- package/dist/debugger/app/assets/routes-Dakrdusf.js +47 -0
- package/dist/debugger/app/index.html +2 -2
- package/dist/debugger/components/composer.d.ts +5 -2
- package/dist/debugger/components/composer.js +5 -4
- package/dist/debugger/components/run-tree.js +2 -5
- package/dist/debugger/events/catalog.js +1 -3
- package/dist/debugger/events/protocol-summarize.js +7 -0
- package/dist/debugger/lib/event-counts.d.ts +2 -2
- package/dist/debugger/lib/event-counts.js +5 -9
- package/dist/debugger/shell/debugger-shell.js +1 -1
- package/dist/debugger/shell/run-controls.d.ts +2 -1
- package/dist/debugger/shell/run-controls.js +40 -13
- package/dist/debugger/shell/run-search.js +1 -3
- package/dist/evaluator/effects.d.ts +45 -33
- package/dist/evaluator/module.d.ts +90 -66
- package/dist/projectors/index-model.d.ts +13 -7
- package/dist/projectors/index-model.js +21 -26
- package/dist/projectors/memory.js +19 -11
- package/dist/projectors/postgres.js +20 -19
- package/dist/projectors/schema.js +20 -18
- package/dist/projectors/sqlite.js +32 -27
- package/dist/react/derived.d.ts +26 -8
- package/dist/react/derived.js +23 -26
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +2 -2
- package/dist/react/materialize.js +16 -11
- package/dist/react/react.d.ts +12 -9
- package/dist/react/react.js +9 -6
- package/dist/react/store.d.ts +4 -5
- package/dist/react/tables.d.ts +3 -2
- package/dist/runtime/cancellation.js +14 -27
- package/dist/runtime/errors.d.ts +39 -0
- package/dist/runtime/errors.js +32 -0
- package/dist/runtime/helpers.d.ts +2 -0
- package/dist/runtime/helpers.js +23 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/looms.d.ts +4 -0
- package/dist/runtime/looms.js +1 -0
- package/dist/runtime/run-start.js +1 -3
- package/dist/runtime/runtime.d.ts +1 -1
- package/dist/runtime/runtime.js +45 -18
- package/dist/runtime/server/http.d.ts +2 -0
- package/dist/runtime/server/http.js +17 -2
- package/dist/runtime/server/routes/runs.js +35 -2
- package/dist/runtime/types.d.ts +8 -0
- package/dist/runtime/wake-engine.js +5 -2
- package/dist/s2/snapshot-store.js +2 -6
- package/dist/workflow/effects.d.ts +24 -0
- package/dist/workflow/effects.js +1 -0
- package/dist/workflow/module.d.ts +48 -0
- package/package.json +2 -2
- package/dist/debugger/app/assets/index-B3Ah8WAE.css +0 -2
- package/dist/debugger/app/assets/index-Qb371t_O.js +0 -22
- package/dist/debugger/app/assets/routes-CjtEHgPQ.js +0 -47
- /package/dist/{react → core}/register.js +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Data, Effect, Predicate } from 'effect';
|
|
2
|
+
import { isPrimitiveEffect, isWithdrawnError, } from './effects.js';
|
|
3
|
+
import { createEvent } from './envelope.js';
|
|
4
|
+
import { foldEvent, foldRun } from './fold.js';
|
|
5
|
+
import { emptyRunState, isRunTerminal } from './state.js';
|
|
6
|
+
import { isTerminalStatus } from './thread.js';
|
|
7
|
+
export class ForkSourceError extends Data.TaggedError('ForkSourceError') {
|
|
8
|
+
constructor(runId, message) {
|
|
9
|
+
super({ runId, message });
|
|
10
|
+
this.name = 'ForkSourceError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function payloadThreadId(event) {
|
|
14
|
+
const threadId = Predicate.isObject(event.payload) ? event.payload.threadId : undefined;
|
|
15
|
+
return Predicate.isString(threadId) ? threadId : event.threadId;
|
|
16
|
+
}
|
|
17
|
+
function rootTerminal(state) {
|
|
18
|
+
const root = state.rootThreadId ? state.threads[state.rootThreadId] : undefined;
|
|
19
|
+
return isRunTerminal(state) || (root !== undefined && isTerminalStatus(root.status));
|
|
20
|
+
}
|
|
21
|
+
/** Where the cancellation that wrote `event` began, when it recorded that; a seq is an index + 1. */
|
|
22
|
+
function cancellationStart(event) {
|
|
23
|
+
const resumeSeq = event.type === 'runtime.thread.cancelled' && Predicate.isObject(event.payload)
|
|
24
|
+
? event.payload.resumeSeq
|
|
25
|
+
: undefined;
|
|
26
|
+
return Predicate.isNumber(resumeSeq) ? resumeSeq : undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Fold the source until its root thread ends. Everything from that event on is how the run
|
|
30
|
+
* finished, so the fork leaves it out; a cancellation that recorded where it began is left
|
|
31
|
+
* out from there.
|
|
32
|
+
*/
|
|
33
|
+
function scanSource(events, registry) {
|
|
34
|
+
const effects = new Map();
|
|
35
|
+
const failedAt = new Map();
|
|
36
|
+
let state = emptyRunState(events[0]?.runId ?? '');
|
|
37
|
+
for (const [index, event] of events.entries()) {
|
|
38
|
+
state = foldEvent(state, event, registry);
|
|
39
|
+
for (const item of state.outstandingEffects) {
|
|
40
|
+
effects.set(item.effectId, item.effect);
|
|
41
|
+
}
|
|
42
|
+
for (const record of Object.values(state.threads)) {
|
|
43
|
+
if (record.status === 'failed' && !failedAt.has(record.threadId)) {
|
|
44
|
+
failedAt.set(record.threadId, index);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (rootTerminal(state)) {
|
|
48
|
+
const root = state.rootThreadId ? state.threads[state.rootThreadId] : undefined;
|
|
49
|
+
const rootFailed = root?.status === 'failed' || state.status === 'failed';
|
|
50
|
+
return { cut: cancellationStart(event) ?? index, effects, failedAt, rootFailed };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { cut: events.length, effects, failedAt, rootFailed: false };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Walk back from the root's failure to the effect outcome that started it, so the fork
|
|
57
|
+
* re-issues that effect instead of replaying a failure the modules already folded in.
|
|
58
|
+
*/
|
|
59
|
+
function failureOrigin(events, scan, registry) {
|
|
60
|
+
const indexById = new Map(events.map((event, index) => [event.id, index]));
|
|
61
|
+
/** A failed thread leads back to where the fold failed it, anything else to its cause. */
|
|
62
|
+
const previous = (index) => {
|
|
63
|
+
const event = events[index];
|
|
64
|
+
const threadId = event.type === 'runtime.thread.failed' ? payloadThreadId(event) : null;
|
|
65
|
+
const failedAt = threadId ? scan.failedAt.get(threadId) : undefined;
|
|
66
|
+
const cause = event.causationId ? indexById.get(event.causationId) : undefined;
|
|
67
|
+
const next = failedAt !== undefined && failedAt < index ? failedAt : cause;
|
|
68
|
+
return next !== undefined && next < index ? next : undefined;
|
|
69
|
+
};
|
|
70
|
+
for (let index = scan.cut; index !== undefined; index = previous(index)) {
|
|
71
|
+
const event = events[index];
|
|
72
|
+
const effect = event.effectId ? scan.effects.get(event.effectId) : undefined;
|
|
73
|
+
const error = Predicate.isObject(event.payload) ? event.payload.error : undefined;
|
|
74
|
+
const withdrawn = Predicate.isString(error) && isWithdrawnError(error);
|
|
75
|
+
if (effect &&
|
|
76
|
+
!isPrimitiveEffect(effect) &&
|
|
77
|
+
!registry.effects.get(effect.type)?.deterministic &&
|
|
78
|
+
!withdrawn) {
|
|
79
|
+
return index;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return scan.cut;
|
|
83
|
+
}
|
|
84
|
+
function copyEvent(event, runId, reissued) {
|
|
85
|
+
if (event.ephemeral && event.effectId && reissued.has(event.effectId)) {
|
|
86
|
+
return { ...event, runId, type: 'runtime.fork.elided', payload: { type: event.type } };
|
|
87
|
+
}
|
|
88
|
+
if (event.type === 'runtime.snapshot.taken' && Predicate.isObject(event.payload)) {
|
|
89
|
+
const { state: _state, ...pointer } = event.payload;
|
|
90
|
+
return { ...event, runId, payload: pointer };
|
|
91
|
+
}
|
|
92
|
+
if (event.type === 'runtime.run.started') {
|
|
93
|
+
return { ...event, runId, idempotencyKey: null };
|
|
94
|
+
}
|
|
95
|
+
return { ...event, runId };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Plan a new run that continues where the source run ended. The fork copies the source's
|
|
99
|
+
* history up to the point the run finished, keeping sequence numbers so effect ids still
|
|
100
|
+
* line up, and its next wake re-issues whatever effects were outstanding there.
|
|
101
|
+
*/
|
|
102
|
+
export function planFork(input) {
|
|
103
|
+
const { sourceRunId, runId, events, registry } = input;
|
|
104
|
+
if (events.length === 0) {
|
|
105
|
+
return Effect.fail(new ForkSourceError(sourceRunId, `Run "${sourceRunId}" has no events`));
|
|
106
|
+
}
|
|
107
|
+
if (events.some((event, index) => event.seq !== index + 1)) {
|
|
108
|
+
return Effect.fail(new ForkSourceError(sourceRunId, `Run "${sourceRunId}" does not have its full history from seq 1; it cannot be forked`));
|
|
109
|
+
}
|
|
110
|
+
const scan = scanSource(events, registry);
|
|
111
|
+
const cut = scan.rootFailed ? failureOrigin(events, scan, registry) : scan.cut;
|
|
112
|
+
const prefix = events.slice(0, cut);
|
|
113
|
+
const atCut = foldRun(prefix, registry, { runId });
|
|
114
|
+
if (!atCut.rootThreadId) {
|
|
115
|
+
return Effect.fail(new ForkSourceError(sourceRunId, `Run "${sourceRunId}" never started a root thread`));
|
|
116
|
+
}
|
|
117
|
+
const reissued = new Set(atCut.outstandingEffects.map((item) => item.effectId));
|
|
118
|
+
const marker = createEvent(runId, {
|
|
119
|
+
type: 'runtime.run.forked',
|
|
120
|
+
payload: { sourceRunId, sourceSeq: cut },
|
|
121
|
+
threadId: null,
|
|
122
|
+
origin: { type: 'system' },
|
|
123
|
+
}, { seq: cut + 1 });
|
|
124
|
+
return Effect.succeed({
|
|
125
|
+
events: [...prefix.map((event) => copyEvent(event, runId, reissued)), marker],
|
|
126
|
+
sourceSeq: cut,
|
|
127
|
+
rootThreadId: atCut.rootThreadId,
|
|
128
|
+
});
|
|
129
|
+
}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -13,7 +13,10 @@ export * from './state';
|
|
|
13
13
|
export * from './match';
|
|
14
14
|
export * from './fold';
|
|
15
15
|
export * from './replay';
|
|
16
|
+
export * from './fork';
|
|
16
17
|
export * from './projection';
|
|
18
|
+
export * from './attempts';
|
|
19
|
+
export type * from './register';
|
|
17
20
|
export * from './module';
|
|
18
21
|
export * from './kind';
|
|
19
22
|
export * from './module-scope';
|
package/dist/core/index.js
CHANGED
|
@@ -12,7 +12,9 @@ export * from './state.js';
|
|
|
12
12
|
export * from './match.js';
|
|
13
13
|
export * from './fold.js';
|
|
14
14
|
export * from './replay.js';
|
|
15
|
+
export * from './fork.js';
|
|
15
16
|
export * from './projection.js';
|
|
17
|
+
export * from './attempts.js';
|
|
16
18
|
export * from './module.js';
|
|
17
19
|
export * from './kind.js';
|
|
18
20
|
export * from './module-scope.js';
|
|
@@ -65,6 +65,7 @@ export interface ModuleScope<TNamespace extends string, U extends EventEnvelope<
|
|
|
65
65
|
input?: TSchema;
|
|
66
66
|
retry?: RetryPolicy;
|
|
67
67
|
execution?: EffectExecution;
|
|
68
|
+
deterministic?: boolean;
|
|
68
69
|
execute?: (input: TInput, ctx: ScopedEffectContext<EventInputOf<U>>) => EffectHandlerResult<R, EventInputOf<U>, HandlerError>;
|
|
69
70
|
}): NoInfer<EffectDefinition<TInput, R, EventInputOf<U>>>;
|
|
70
71
|
input<K extends keyof (TEvents extends EventCatalog<any, infer E> ? E : never) & string>(key: K, payload: InferPayload<(TEvents extends EventCatalog<any, infer E> ? E : never)[K]>, meta?: Omit<EventInput, 'type' | 'payload'>): Omit<EventInput, 'type' | 'payload'> & {
|
package/dist/core/module.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ export type NextEffectHandler = (effect: RuntimeEffect, ctx: EffectContext) => E
|
|
|
10
10
|
export type EffectMiddleware = (effect: RuntimeEffect, ctx: EffectContext, next: NextEffectHandler) => Effect.Effect<ReadonlyArray<EventInput>, Error>;
|
|
11
11
|
/**
|
|
12
12
|
* Names the threads whose in-process effects an admitted signal event interrupts, so a running
|
|
13
|
-
* effect (such as a model call) can stop early.
|
|
14
|
-
* nothing.
|
|
13
|
+
* effect (such as a model call) can stop early. The runtime also interrupts each named thread's
|
|
14
|
+
* descendants. Return an empty array when the event interrupts nothing.
|
|
15
15
|
*/
|
|
16
16
|
export type SignalInterruptRule = (event: EventInput) => readonly string[];
|
|
17
17
|
export interface RuntimeModuleDependency {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Schema, Stream, type Effect } from 'effect';
|
|
2
2
|
import type { EventEnvelope } from './envelope';
|
|
3
|
+
import type { AnyEventEnvelope, RegisteredEvent } from './register';
|
|
3
4
|
import type { InferSchemaOutput, SchemaInput } from './schema';
|
|
4
5
|
import type { RunState, ThreadRecord } from './state';
|
|
5
6
|
export interface ProjectionDefinition<S = unknown> {
|
|
@@ -8,17 +9,17 @@ export interface ProjectionDefinition<S = unknown> {
|
|
|
8
9
|
initialState: S;
|
|
9
10
|
reduce(state: S, event: EventEnvelope): S;
|
|
10
11
|
}
|
|
11
|
-
export declare function defineProjection<S = unknown>(def: {
|
|
12
|
+
export declare function defineProjection<S = unknown, TEvent extends AnyEventEnvelope = RegisteredEvent>(def: {
|
|
12
13
|
readonly name: string;
|
|
13
14
|
readonly shape?: undefined;
|
|
14
15
|
readonly initialState: S;
|
|
15
|
-
reduce(state: S, event:
|
|
16
|
+
reduce(state: S, event: TEvent): S;
|
|
16
17
|
}): ProjectionDefinition<S>;
|
|
17
|
-
export declare function defineProjection<TShape extends SchemaInput>(def: {
|
|
18
|
+
export declare function defineProjection<TShape extends SchemaInput, TEvent extends AnyEventEnvelope = RegisteredEvent>(def: {
|
|
18
19
|
readonly name: string;
|
|
19
20
|
readonly shape: TShape;
|
|
20
21
|
readonly initialState: InferSchemaOutput<TShape>;
|
|
21
|
-
reduce(state: NoInfer<InferSchemaOutput<TShape>>, event:
|
|
22
|
+
reduce(state: NoInfer<InferSchemaOutput<TShape>>, event: TEvent): InferSchemaOutput<TShape>;
|
|
22
23
|
}): ProjectionDefinition<InferSchemaOutput<TShape>>;
|
|
23
24
|
export declare function foldProjection<S>(projection: ProjectionDefinition<S>, events: readonly EventEnvelope[], initial?: S): S;
|
|
24
25
|
/** Fold a projection over events, skipping ephemeral ones. */
|
package/dist/core/projection.js
CHANGED
package/dist/core/protocol.d.ts
CHANGED
|
@@ -17,6 +17,13 @@ export declare const protocolCatalog: import("./catalog").EventCatalog<"runtime"
|
|
|
17
17
|
'run.cancelled': Schema.Struct<{
|
|
18
18
|
readonly reason: Schema.optional<Schema.String>;
|
|
19
19
|
}>;
|
|
20
|
+
'run.forked': Schema.Struct<{
|
|
21
|
+
readonly sourceRunId: Schema.String;
|
|
22
|
+
readonly sourceSeq: Schema.Finite;
|
|
23
|
+
}>;
|
|
24
|
+
'fork.elided': Schema.Struct<{
|
|
25
|
+
readonly type: Schema.String;
|
|
26
|
+
}>;
|
|
20
27
|
'thread.started': Schema.Struct<{
|
|
21
28
|
readonly threadId: Schema.String;
|
|
22
29
|
readonly kind: Schema.String;
|
|
@@ -36,6 +43,8 @@ export declare const protocolCatalog: import("./catalog").EventCatalog<"runtime"
|
|
|
36
43
|
'thread.cancelled': Schema.Struct<{
|
|
37
44
|
readonly threadId: Schema.String;
|
|
38
45
|
readonly reason: Schema.optional<Schema.String>;
|
|
46
|
+
/** The run's last seq before this cancellation began; a fork of the run resumes there. */
|
|
47
|
+
readonly resumeSeq: Schema.optional<Schema.Finite>;
|
|
39
48
|
}>;
|
|
40
49
|
'thread.cancel.requested': Schema.Struct<{
|
|
41
50
|
readonly threadId: Schema.String;
|
|
@@ -138,7 +147,7 @@ export declare const protocolCatalog: import("./catalog").EventCatalog<"runtime"
|
|
|
138
147
|
}>;
|
|
139
148
|
export type ProtocolEvent = EventsOfCatalog<typeof protocolCatalog>;
|
|
140
149
|
export type ProtocolEventInput = EventInputOf<typeof protocolCatalog>;
|
|
141
|
-
export declare const PROTOCOL_TYPES: readonly ['runtime.run.started', 'runtime.run.completed', 'runtime.run.cancelled', 'runtime.thread.started', 'runtime.thread.completed', 'runtime.thread.failed', 'runtime.thread.cancelled', 'runtime.thread.cancel.requested', 'runtime.wait.registered', 'runtime.wait.satisfied', 'runtime.timer.set', 'runtime.timer.fired', 'runtime.effect.failed', 'runtime.effect.attempt.started', 'runtime.effect.queued', 'runtime.effect.dispatched', 'runtime.effect.worker.started', 'runtime.effect.heartbeat', 'runtime.effect.cancel.requested', 'runtime.effect.cancelled', 'runtime.effect.completed', 'runtime.effect.timed_out', 'runtime.effect.ambiguous', 'runtime.effect.retry.scheduled', 'runtime.snapshot.taken', 'runtime.signal.received'];
|
|
150
|
+
export declare const PROTOCOL_TYPES: readonly ['runtime.run.started', 'runtime.run.completed', 'runtime.run.cancelled', 'runtime.run.forked', 'runtime.fork.elided', 'runtime.thread.started', 'runtime.thread.completed', 'runtime.thread.failed', 'runtime.thread.cancelled', 'runtime.thread.cancel.requested', 'runtime.wait.registered', 'runtime.wait.satisfied', 'runtime.timer.set', 'runtime.timer.fired', 'runtime.effect.failed', 'runtime.effect.attempt.started', 'runtime.effect.queued', 'runtime.effect.dispatched', 'runtime.effect.worker.started', 'runtime.effect.heartbeat', 'runtime.effect.cancel.requested', 'runtime.effect.cancelled', 'runtime.effect.completed', 'runtime.effect.timed_out', 'runtime.effect.ambiguous', 'runtime.effect.retry.scheduled', 'runtime.snapshot.taken', 'runtime.signal.received'];
|
|
142
151
|
export type ProtocolEventType = (typeof PROTOCOL_TYPES)[number];
|
|
143
152
|
export declare function isProtocolType(type: string): type is ProtocolEventType;
|
|
144
153
|
export type RunStartedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['run.started']>;
|
package/dist/core/protocol.js
CHANGED
|
@@ -20,6 +20,13 @@ export const protocolCatalog = defineEventCatalog('runtime', {
|
|
|
20
20
|
'run.cancelled': Schema.Struct({
|
|
21
21
|
reason: Schema.optional(Schema.String),
|
|
22
22
|
}),
|
|
23
|
+
'run.forked': Schema.Struct({
|
|
24
|
+
sourceRunId: Schema.String,
|
|
25
|
+
sourceSeq: Schema.Finite,
|
|
26
|
+
}),
|
|
27
|
+
'fork.elided': Schema.Struct({
|
|
28
|
+
type: Schema.String,
|
|
29
|
+
}),
|
|
23
30
|
'thread.started': Schema.Struct({
|
|
24
31
|
threadId: Schema.String,
|
|
25
32
|
kind: Schema.String,
|
|
@@ -39,6 +46,8 @@ export const protocolCatalog = defineEventCatalog('runtime', {
|
|
|
39
46
|
'thread.cancelled': Schema.Struct({
|
|
40
47
|
threadId: Schema.String,
|
|
41
48
|
reason: Schema.optional(Schema.String),
|
|
49
|
+
/** The run's last seq before this cancellation began; a fork of the run resumes there. */
|
|
50
|
+
resumeSeq: Schema.optional(Schema.Finite),
|
|
42
51
|
}),
|
|
43
52
|
'thread.cancel.requested': Schema.Struct({
|
|
44
53
|
threadId: Schema.String,
|
|
@@ -138,6 +147,8 @@ export const PROTOCOL_TYPES = [
|
|
|
138
147
|
'runtime.run.started',
|
|
139
148
|
'runtime.run.completed',
|
|
140
149
|
'runtime.run.cancelled',
|
|
150
|
+
'runtime.run.forked',
|
|
151
|
+
'runtime.fork.elided',
|
|
141
152
|
'runtime.thread.started',
|
|
142
153
|
'runtime.thread.completed',
|
|
143
154
|
'runtime.thread.failed',
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EventsOf } from './compose';
|
|
2
|
+
import type { EventEnvelope } from './envelope';
|
|
2
3
|
/** Looser event bound so catalog-inferred payloads (including Schema.Type) are accepted. */
|
|
3
4
|
export type AnyEventEnvelope = EventEnvelope<string, any>;
|
|
4
5
|
/**
|
|
5
|
-
* Application-level type registry for Looms
|
|
6
|
+
* Application-level type registry for Looms.
|
|
6
7
|
*
|
|
7
|
-
* Augment this interface
|
|
8
|
-
* `
|
|
8
|
+
* Augment this interface once to bind your event union. `defineProjection` reducers and the
|
|
9
|
+
* `@swirls/looms/react` hooks and stores use it as their default event type:
|
|
9
10
|
*
|
|
10
11
|
* ```ts
|
|
11
12
|
* declare module '@swirls/looms/react' {
|
|
@@ -15,7 +16,7 @@ export type AnyEventEnvelope = EventEnvelope<string, any>;
|
|
|
15
16
|
* }
|
|
16
17
|
* ```
|
|
17
18
|
*
|
|
18
|
-
* You may register either:
|
|
19
|
+
* Augmenting `@swirls/looms/core` works the same way. You may register either:
|
|
19
20
|
* - `events`: an explicit event union
|
|
20
21
|
* - `modules`: a module array / creator function (via `EventsOf`)
|
|
21
22
|
* - `catalog`: an event catalog or catalog array (via `EventsOf`)
|
|
@@ -24,8 +25,8 @@ export interface LoomsRegister {
|
|
|
24
25
|
}
|
|
25
26
|
export type RegisteredEvent = LoomsRegister extends {
|
|
26
27
|
events: infer E;
|
|
27
|
-
} ? E
|
|
28
|
+
} ? Extract<E, AnyEventEnvelope> : LoomsRegister extends {
|
|
28
29
|
modules: infer M;
|
|
29
|
-
} ? EventsOf<M
|
|
30
|
+
} ? Extract<EventsOf<M>, AnyEventEnvelope> : LoomsRegister extends {
|
|
30
31
|
catalog: infer C;
|
|
31
|
-
} ? EventsOf<C
|
|
32
|
+
} ? Extract<EventsOf<C>, AnyEventEnvelope> : EventEnvelope;
|
package/dist/core/replay.d.ts
CHANGED
|
@@ -49,6 +49,10 @@ export declare const ReplayStepSchema: Schema.Struct<{
|
|
|
49
49
|
readonly idempotencyKey: Schema.NullOr<Schema.String>;
|
|
50
50
|
readonly rootThreadId: Schema.String;
|
|
51
51
|
}>>, never>;
|
|
52
|
+
readonly forkedFrom: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
53
|
+
readonly runId: Schema.String;
|
|
54
|
+
readonly seq: Schema.Finite;
|
|
55
|
+
}>>, never>;
|
|
52
56
|
readonly threads: Schema.$Record<Schema.String, Schema.Struct<{
|
|
53
57
|
readonly threadId: Schema.String;
|
|
54
58
|
readonly kind: Schema.String;
|
|
@@ -161,6 +165,10 @@ export declare const ReplayStepSchema: Schema.Struct<{
|
|
|
161
165
|
readonly idempotencyKey: Schema.NullOr<Schema.String>;
|
|
162
166
|
readonly rootThreadId: Schema.String;
|
|
163
167
|
}>>, never>;
|
|
168
|
+
readonly forkedFrom: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
169
|
+
readonly runId: Schema.String;
|
|
170
|
+
readonly seq: Schema.Finite;
|
|
171
|
+
}>>, never>;
|
|
164
172
|
readonly threads: Schema.$Record<Schema.String, Schema.Struct<{
|
|
165
173
|
readonly threadId: Schema.String;
|
|
166
174
|
readonly kind: Schema.String;
|
package/dist/core/snapshots.js
CHANGED
|
@@ -21,14 +21,7 @@ export function shouldTakeSnapshot(events, every = DEFAULT_SNAPSHOT_EVERY) {
|
|
|
21
21
|
if (durable.length === 0) {
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
for (let i = events.length - 1; i >= 0; i--) {
|
|
26
|
-
const candidate = events[i];
|
|
27
|
-
if (candidate?.type === 'runtime.snapshot.taken') {
|
|
28
|
-
lastSnap = candidate;
|
|
29
|
-
break;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
24
|
+
const lastSnap = events.findLast((e) => e.type === 'runtime.snapshot.taken');
|
|
32
25
|
const since = lastSnap ? durable.filter((e) => e.seq > lastSnap.seq).length : durable.length;
|
|
33
26
|
return since >= every;
|
|
34
27
|
}
|
|
@@ -66,17 +59,10 @@ export function buildSnapshotMarker(runId, cursor, stateHash, options) {
|
|
|
66
59
|
}
|
|
67
60
|
export function foldFromSnapshots(events, registry, options) {
|
|
68
61
|
const runId = options?.runId ?? events[0]?.runId ?? 'unknown';
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (events[i]?.type === 'runtime.snapshot.taken') {
|
|
72
|
-
latestSnapIdx = i;
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (latestSnapIdx < 0) {
|
|
62
|
+
const snap = events.findLast((e) => e.type === 'runtime.snapshot.taken');
|
|
63
|
+
if (!snap) {
|
|
77
64
|
return foldRun(events, registry, { runId });
|
|
78
65
|
}
|
|
79
|
-
const snap = events[latestSnapIdx];
|
|
80
66
|
const decoded = Schema.decodeUnknownSync(SnapshotTakenPayloadSchema)(snap.payload);
|
|
81
67
|
if (decoded.state !== undefined) {
|
|
82
68
|
const trailing = events.filter((e) => e.seq > decoded.seq);
|
package/dist/core/state.d.ts
CHANGED
|
@@ -46,11 +46,17 @@ export interface RunStartIdentity {
|
|
|
46
46
|
idempotencyKey: string | null;
|
|
47
47
|
rootThreadId: string;
|
|
48
48
|
}
|
|
49
|
+
/** The run and last sequence a fork copied its history from. */
|
|
50
|
+
export interface RunForkSource {
|
|
51
|
+
runId: string;
|
|
52
|
+
seq: number;
|
|
53
|
+
}
|
|
49
54
|
export interface RunState {
|
|
50
55
|
runId: string;
|
|
51
56
|
status: RunStatus;
|
|
52
57
|
rootThreadId: string | null;
|
|
53
58
|
startIdentity: RunStartIdentity | null;
|
|
59
|
+
forkedFrom: RunForkSource | null;
|
|
54
60
|
threads: {
|
|
55
61
|
[threadId: string]: ThreadRecord;
|
|
56
62
|
};
|
|
@@ -77,6 +83,10 @@ export declare const RunStateSchema: Schema.Struct<{
|
|
|
77
83
|
readonly idempotencyKey: Schema.NullOr<Schema.String>;
|
|
78
84
|
readonly rootThreadId: Schema.String;
|
|
79
85
|
}>>, never>;
|
|
86
|
+
readonly forkedFrom: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
87
|
+
readonly runId: Schema.String;
|
|
88
|
+
readonly seq: Schema.Finite;
|
|
89
|
+
}>>, never>;
|
|
80
90
|
readonly threads: Schema.$Record<Schema.String, Schema.Struct<{
|
|
81
91
|
readonly threadId: Schema.String;
|
|
82
92
|
readonly kind: Schema.String;
|
|
@@ -178,4 +188,8 @@ export declare const RunStateSchema: Schema.Struct<{
|
|
|
178
188
|
}>;
|
|
179
189
|
export declare function emptyRunState(runId: string): RunState;
|
|
180
190
|
export declare function isRunTerminal(state: RunState): boolean;
|
|
191
|
+
/** Every thread below `threadId`, in the order they were started. */
|
|
192
|
+
export declare function descendantThreadIds(state: RunState, threadId: string): string[];
|
|
193
|
+
/** The status a `runtime.run.completed` payload ends the run with: an error means it failed. */
|
|
194
|
+
export declare function completedRunStatus(payload: JsonValue): 'completed' | 'failed';
|
|
181
195
|
export declare function isRunParked(state: RunState): boolean;
|
package/dist/core/state.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Effect, Schema } from 'effect';
|
|
1
|
+
import { Effect, Predicate, Schema } from 'effect';
|
|
2
2
|
import { RuntimeEffectSchema, WaitConditionSchema, } from './effects.js';
|
|
3
3
|
import { JsonValueSchema } from './envelope.js';
|
|
4
4
|
import { DEFAULT_DEFINITION_VERSION } from './module.js';
|
|
5
|
+
import { isTerminalStatus } from './thread.js';
|
|
5
6
|
export const RunStateSchema = Schema.Struct({
|
|
6
7
|
runId: Schema.String,
|
|
7
8
|
status: Schema.Union([
|
|
@@ -20,6 +21,7 @@ export const RunStateSchema = Schema.Struct({
|
|
|
20
21
|
idempotencyKey: Schema.NullOr(Schema.String),
|
|
21
22
|
rootThreadId: Schema.String,
|
|
22
23
|
})).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
24
|
+
forkedFrom: Schema.NullOr(Schema.Struct({ runId: Schema.String, seq: Schema.Finite })).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
23
25
|
threads: Schema.Record(Schema.String, Schema.Struct({
|
|
24
26
|
threadId: Schema.String,
|
|
25
27
|
kind: Schema.String,
|
|
@@ -80,6 +82,7 @@ export function emptyRunState(runId) {
|
|
|
80
82
|
status: 'running',
|
|
81
83
|
rootThreadId: null,
|
|
82
84
|
startIdentity: null,
|
|
85
|
+
forkedFrom: null,
|
|
83
86
|
threads: {},
|
|
84
87
|
waits: {},
|
|
85
88
|
outstandingEffects: [],
|
|
@@ -89,7 +92,27 @@ export function emptyRunState(runId) {
|
|
|
89
92
|
};
|
|
90
93
|
}
|
|
91
94
|
export function isRunTerminal(state) {
|
|
92
|
-
return state.status
|
|
95
|
+
return isTerminalStatus(state.status);
|
|
96
|
+
}
|
|
97
|
+
/** Every thread below `threadId`, in the order they were started. */
|
|
98
|
+
export function descendantThreadIds(state, threadId) {
|
|
99
|
+
return Object.values(state.threads)
|
|
100
|
+
.filter((record) => {
|
|
101
|
+
let parentThreadId = record.parentThreadId;
|
|
102
|
+
while (parentThreadId) {
|
|
103
|
+
if (parentThreadId === threadId) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
parentThreadId = state.threads[parentThreadId]?.parentThreadId ?? null;
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
})
|
|
110
|
+
.map((record) => record.threadId);
|
|
111
|
+
}
|
|
112
|
+
/** The status a `runtime.run.completed` payload ends the run with: an error means it failed. */
|
|
113
|
+
export function completedRunStatus(payload) {
|
|
114
|
+
const error = Predicate.isObject(payload) ? payload.error : undefined;
|
|
115
|
+
return Predicate.isString(error) && error.length > 0 ? 'failed' : 'completed';
|
|
93
116
|
}
|
|
94
117
|
export function isRunParked(state) {
|
|
95
118
|
if (isRunTerminal(state)) {
|
package/dist/core/store.d.ts
CHANGED
|
@@ -91,6 +91,7 @@ export interface StreamBounds {
|
|
|
91
91
|
readonly tail: number;
|
|
92
92
|
}
|
|
93
93
|
export interface AppendOptions {
|
|
94
|
+
/** Fail unless the stream is at this tail. The batch is numbered from `expectedTail + 1`. */
|
|
94
95
|
readonly expectedTail?: number;
|
|
95
96
|
/**
|
|
96
97
|
* Atomically claims an ingress command with the append. Reusing the key
|
|
@@ -0,0 +1,2 @@
|
|
|
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}.fill-current{fill:currentColor}.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}}
|