From 78735d5244cdb70f232f2ee1bf473faf0db95663 Mon Sep 17 00:00:00 2001 From: theoneand33 <120695243+theoneand33@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:45:14 +1200 Subject: [PATCH 01/20] Create opencode-review.yml --- .github/workflows/opencode-review.yml | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .github/workflows/opencode-review.yml diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml new file mode 100644 index 000000000000..71536ad409c8 --- /dev/null +++ b/.github/workflows/opencode-review.yml @@ -0,0 +1,40 @@ +name: opencode-review + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + opencode-review: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + pull-requests: write + issues: write + actions: read + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Configure git identity for opencode commits + run: | + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global user.name "opencode[bot]" + + - name: Run opencode + uses: anomalyco/opencode/github@latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + META_MODEL_API_KEY: ${{ secrets.META_MODEL_API_KEY }} + with: + model: meta/muse-spark-1.2-contributor + use_github_token: true + # ponytail: OIDC workaround for repos created after 2026-07-15 (immutable sub format → p.rest). Remove when https://github.com/anomalyco/opencode/issues/37823 is fixed upstream + prompt: | + Review this pull request: + - Check for code quality issues + - Look for potential bugs + - Suggest improvements From b1ee227ba881cbc403b62d50f67e28d10f5b4722 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 09:58:58 +1200 Subject: [PATCH 02/20] feat(provider): add Pi coding agent integration --- apps/server/src/provider/Drivers/PiDriver.ts | 163 ++++ apps/server/src/provider/Layers/PiAdapter.ts | 802 ++++++++++++++++++ apps/server/src/provider/Layers/PiProvider.ts | 235 +++++ apps/server/src/provider/builtInDrivers.ts | 5 +- .../src/textGeneration/PiTextGeneration.ts | 259 ++++++ packages/contracts/src/model.ts | 4 + packages/contracts/src/settings.ts | 45 + 7 files changed, 1512 insertions(+), 1 deletion(-) create mode 100644 apps/server/src/provider/Drivers/PiDriver.ts create mode 100644 apps/server/src/provider/Layers/PiAdapter.ts create mode 100644 apps/server/src/provider/Layers/PiProvider.ts create mode 100644 apps/server/src/textGeneration/PiTextGeneration.ts diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/apps/server/src/provider/Drivers/PiDriver.ts new file mode 100644 index 000000000000..6838b03c7398 --- /dev/null +++ b/apps/server/src/provider/Drivers/PiDriver.ts @@ -0,0 +1,163 @@ +import { PiSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import * as Crypto from "effect/Crypto"; +import * as Effect from "effect/Effect"; +import * as FileSystem from "effect/FileSystem"; +import * as Path from "effect/Path"; +import * as Schema from "effect/Schema"; +import { HttpClient } from "effect/unstable/http"; +import { ChildProcessSpawner } from "effect/unstable/process"; + +import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts"; +import { ServerConfig } from "../../config.ts"; +import { ServerSettingsService } from "../../serverSettings.ts"; +import { makePiTextGeneration } from "../../textGeneration/PiTextGeneration.ts"; +import { ProviderDriverError } from "../Errors.ts"; +import { makePiAdapter } from "../Layers/PiAdapter.ts"; +import { + buildInitialPiProviderSnapshot, + checkPiProviderStatus, + enrichPiSnapshot, +} from "../Layers/PiProvider.ts"; +import { ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts"; +import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { + defaultProviderContinuationIdentity, + type ProviderDriver, + type ProviderInstance, +} from "../ProviderDriver.ts"; +import type { ServerProviderDraft } from "../providerSnapshot.ts"; +import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { + makeManualOnlyProviderMaintenanceCapabilities, + makeStaticProviderMaintenanceResolver, + resolveProviderMaintenanceCapabilitiesEffect, +} from "../providerMaintenance.ts"; +import { + haveProviderSnapshotSettingsChanged, + makeProviderSnapshotSettingsSource, + type ProviderSnapshotSettings, +} from "../providerUpdateSettings.ts"; + +const decodePiSettings = Schema.decodeSync(PiSettings); + +const DRIVER_KIND = ProviderDriverKind.make("pi"); +const UPDATE = makeStaticProviderMaintenanceResolver( + makeManualOnlyProviderMaintenanceCapabilities({ + provider: DRIVER_KIND, + packageName: "@earendil-works/pi-coding-agent", + }), +); + +export type PiDriverEnv = + | BackgroundPolicy.BackgroundPolicy + | ChildProcessSpawner.ChildProcessSpawner + | Crypto.Crypto + | FileSystem.FileSystem + | HttpClient.HttpClient + | Path.Path + | ProviderEventLoggers + | ServerConfig + | ServerSettingsService; + +const withInstanceIdentity = + (input: { + readonly instanceId: ProviderInstance["instanceId"]; + readonly displayName: string | undefined; + readonly accentColor: string | undefined; + readonly continuationGroupKey: string; + }) => + (snapshot: ServerProviderDraft): ServerProvider => ({ + ...snapshot, + instanceId: input.instanceId, + driver: DRIVER_KIND, + ...(input.displayName ? { displayName: input.displayName } : {}), + ...(input.accentColor ? { accentColor: input.accentColor } : {}), + continuation: { groupKey: input.continuationGroupKey }, + }); + +export const PiDriver: ProviderDriver = { + driverKind: DRIVER_KIND, + metadata: { + displayName: "Pi", + supportsMultipleInstances: true, + }, + configSchema: PiSettings, + defaultConfig: (): PiSettings => decodePiSettings({}), + create: ({ instanceId, displayName, accentColor, environment, enabled, config }) => + Effect.gen(function* () { + const crypto = yield* Crypto.Crypto; + const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const httpClient = yield* HttpClient.HttpClient; + const serverSettings = yield* ServerSettingsService; + const eventLoggers = yield* ProviderEventLoggers; + const processEnv = mergeProviderInstanceEnvironment(environment); + const continuationIdentity = defaultProviderContinuationIdentity({ + driverKind: DRIVER_KIND, + instanceId, + }); + const stampIdentity = withInstanceIdentity({ + instanceId, + displayName, + accentColor, + continuationGroupKey: continuationIdentity.continuationKey, + }); + const effectiveConfig = { ...config, enabled } satisfies PiSettings; + const maintenanceCapabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(UPDATE, { + binaryPath: effectiveConfig.binaryPath, + env: processEnv, + }); + + const adapter = yield* makePiAdapter(effectiveConfig, { + environment: processEnv, + instanceId, + }); + const textGeneration = yield* makePiTextGeneration(effectiveConfig, processEnv); + + const checkProvider = checkPiProviderStatus(effectiveConfig, processEnv).pipe( + Effect.map(stampIdentity), + Effect.provideService(Crypto.Crypto, crypto), + Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), + ); + + const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, serverSettings); + const snapshot = yield* makeManagedServerProvider>({ + maintenanceCapabilities, + getSettings: snapshotSettings.getSettings, + streamSettings: snapshotSettings.streamSettings, + haveSettingsChanged: haveProviderSnapshotSettingsChanged, + initialSnapshot: (settings) => + buildInitialPiProviderSnapshot(settings.provider).pipe(Effect.map(stampIdentity)), + checkProvider, + enrichSnapshot: ({ settings, snapshot: currentSnapshot, publishSnapshot }) => + enrichPiSnapshot({ + snapshot: currentSnapshot, + maintenanceCapabilities, + enableProviderUpdateChecks: settings.enableProviderUpdateChecks, + publishSnapshot, + httpClient, + }), + }).pipe( + Effect.mapError( + (cause) => + new ProviderDriverError({ + driver: DRIVER_KIND, + instanceId, + detail: `Failed to build Pi snapshot: ${cause.message ?? String(cause)}`, + cause, + }), + ), + ); + + return { + instanceId, + driverKind: DRIVER_KIND, + continuationIdentity, + displayName, + accentColor, + enabled, + snapshot, + adapter, + textGeneration, + } satisfies ProviderInstance; + }), +}; diff --git a/apps/server/src/provider/Layers/PiAdapter.ts b/apps/server/src/provider/Layers/PiAdapter.ts new file mode 100644 index 000000000000..690adca4a5dc --- /dev/null +++ b/apps/server/src/provider/Layers/PiAdapter.ts @@ -0,0 +1,802 @@ +import { + type PiSettings, + EventId, + type ProviderRuntimeEvent, + type ProviderSession, + ProviderDriverKind, + ProviderInstanceId, + type ThreadId, + TurnId, + type ApprovalRequestId, + type ProviderApprovalDecision, + type ProviderUserInputAnswers, +} from "@t3tools/contracts"; +import * as Crypto from "effect/Crypto"; +import * as DateTime from "effect/DateTime"; +import * as Deferred from "effect/Deferred"; +import * as Effect from "effect/Effect"; +import * as Fiber from "effect/Fiber"; +import * as FileSystem from "effect/FileSystem"; +import * as PubSub from "effect/PubSub"; +import * as Scope from "effect/Scope"; +import * as Stream from "effect/Stream"; +import * as SynchronizedRef from "effect/SynchronizedRef"; +import * as Semaphore from "effect/Semaphore"; +import { tokenizeCliArgs } from "@t3tools/shared/cliArgs"; +import type { ChildProcess as NodeChildProcess } from "node:child_process"; + +import { resolveAttachmentPath } from "../../attachmentStore.ts"; +import { ServerConfig } from "../../config.ts"; +import { + ProviderAdapterProcessError, + ProviderAdapterRequestError, + ProviderAdapterSessionNotFoundError, + ProviderAdapterValidationError, +} from "../Errors.ts"; +import type { ProviderAdapterShape } from "../Services/ProviderAdapter.ts"; + +const PROVIDER = ProviderDriverKind.make("pi"); + +interface PiRpcCommand { + readonly id?: string; + readonly type: string; + readonly [key: string]: unknown; +} + +interface PiSessionContext { + readonly threadId: ThreadId; + session: ProviderSession; + readonly scope: Scope.CloseableScope; + child: NodeChildProcess | undefined; + activeTurnId: TurnId | undefined; + pendingCommands: Map>; + stopped: boolean; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +export interface PiAdapterLiveOptions { + readonly environment?: NodeJS.ProcessEnv; + readonly instanceId?: ProviderInstanceId; +} + +function piLaunchArgs(launchArgs?: string): ReadonlyArray { + return tokenizeCliArgs(launchArgs?.trim() ?? ""); +} + +export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOptions) { + return Effect.gen(function* () { + const boundInstanceId = options?.instanceId ?? ProviderInstanceId.make("pi"); + const fileSystem = yield* FileSystem.FileSystem; + const serverConfig = yield* ServerConfig; + const crypto = yield* Crypto.Crypto; + + const sessions = new Map(); + const threadLocksRef = yield* SynchronizedRef.make(new Map()); + const runtimeEventPubSub = yield* PubSub.unbounded(); + + const nowIso = Effect.map(DateTime.now, DateTime.formatIso); + const randomUUIDv4 = crypto.randomUUIDv4.pipe( + Effect.mapError( + (cause) => + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "crypto/randomUUIDv4", + detail: "Failed to generate Pi runtime identifier.", + cause, + }), + ), + ); + const nextEventId = Effect.map(randomUUIDv4, (id) => EventId.make(id)); + const makeEventStamp = () => Effect.all({ eventId: nextEventId, createdAt: nowIso }); + const offerRuntimeEvent = (event: ProviderRuntimeEvent) => + PubSub.publish(runtimeEventPubSub, event).pipe(Effect.asVoid); + + const getThreadSemaphore = (threadId: string) => + SynchronizedRef.modifyEffect(threadLocksRef, (current) => { + const existing = current.get(threadId); + if (existing) return Effect.succeed([existing, current] as const); + return Semaphore.make(1).pipe( + Effect.map((sem) => { + const next = new Map(current); + next.set(threadId, sem); + return [sem, next] as const; + }), + ); + }); + + const withThreadLock = (threadId: string, effect: Effect.Effect) => + Effect.flatMap(getThreadSemaphore(threadId), (sem) => sem.withPermit(effect)); + + const requireSession = ( + threadId: ThreadId, + ): Effect.Effect => { + const ctx = sessions.get(threadId); + if (!ctx || ctx.stopped) { + return Effect.fail(new ProviderAdapterSessionNotFoundError({ provider: PROVIDER, threadId })); + } + return Effect.succeed(ctx); + }; + + const stopSessionInternal = (ctx: PiSessionContext) => + Effect.gen(function* () { + if (ctx.stopped) return; + ctx.stopped = true; + if (ctx.child) { + try { + ctx.child.kill(); + } catch {} + } + yield* Effect.ignore(Scope.close(ctx.scope, Effect.void as any)); + sessions.delete(ctx.threadId); + for (const deferred of ctx.pendingCommands.values()) { + yield* Deferred.fail(deferred, new Error("Session stopped")).pipe(Effect.ignore); + } + ctx.pendingCommands.clear(); + yield* offerRuntimeEvent({ + type: "session.exited", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: ctx.threadId, + payload: { exitKind: "graceful" }, + }); + }); + + const writeRpcCommand = ( + ctx: PiSessionContext, + command: PiRpcCommand, + ): Effect.Effect<{ success: boolean; data?: unknown; error?: string }, ProviderAdapterRequestError> => + Effect.gen(function* () { + if (!ctx.child || !ctx.child.stdin || ctx.stopped) { + return yield* new ProviderAdapterRequestError({ + provider: PROVIDER, + method: command.type, + detail: "Pi session is not running.", + }); + } + const id = (command.id ?? (yield* randomUUIDv4)) as string; + const payload = { ...command, id }; + const deferred = yield* Deferred.make<{ success: boolean; data?: unknown; error?: string }>(); + ctx.pendingCommands.set(id, deferred); + const line = JSON.stringify(payload) + "\n"; + const stdin = ctx.child.stdin as NodeJS.WritableStream; + const writeDone = yield* Effect.async((resume) => { + stdin.write(line, (err: unknown) => { + if (err) { + resume( + Effect.fail( + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: command.type, + detail: "Failed to write to Pi RPC stdin.", + cause: err, + }), + ), + ); + } else { + resume(Effect.void); + } + }); + }); + void writeDone; + const result = yield* Deferred.await(deferred).pipe(Effect.timeoutOption(30_000)); + if (result._tag === "None") { + ctx.pendingCommands.delete(id); + return yield* new ProviderAdapterRequestError({ + provider: PROVIDER, + method: command.type, + detail: "Timed out waiting for Pi RPC response.", + }); + } + return result.value; + }); + + const handlePiEvent = (ctx: PiSessionContext, raw: unknown): Effect.Effect => + Effect.gen(function* () { + if (!isRecord(raw)) return; + const type = typeof raw.type === "string" ? raw.type : ""; + + if (type === "response") { + const id = typeof raw.id === "string" ? raw.id : undefined; + if (id && ctx.pendingCommands.has(id)) { + const deferred = ctx.pendingCommands.get(id)!; + ctx.pendingCommands.delete(id); + const success = raw.success === true; + yield* Deferred.succeed(deferred, { + success, + data: (raw as Record).data, + error: + typeof (raw as Record).error === "string" + ? ((raw as Record).error as string) + : undefined, + }).pipe(Effect.ignore); + } + return; + } + + const turnId = ctx.activeTurnId; + const stamp = yield* makeEventStamp(); + + switch (type) { + case "message_update": { + const delta = (raw as Record).assistantMessageEvent as + | Record + | undefined; + if (delta && turnId) { + const deltaType = delta.type as string; + if (deltaType === "text_delta" && typeof delta.delta === "string") { + yield* offerRuntimeEvent({ + type: "content.delta", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { kind: "assistant_text", delta: delta.delta as string }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + } else if (deltaType === "thinking_delta" && typeof delta.delta === "string") { + yield* offerRuntimeEvent({ + type: "content.delta", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { kind: "reasoning_text", delta: delta.delta as string }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + } else if (deltaType === "toolcall_start") { + const toolName = typeof delta.toolName === "string" ? (delta.toolName as string) : "tool"; + yield* offerRuntimeEvent({ + type: "item.started", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { kind: toolName as never, status: "inProgress" }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + } + } + break; + } + case "message_end": { + if (turnId) { + yield* offerRuntimeEvent({ + type: "item.completed", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { kind: "assistant_message", status: "completed" }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + } + break; + } + case "tool_execution_start": { + if (turnId) { + yield* offerRuntimeEvent({ + type: "tool.progress", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { + tool: ((raw as Record).toolName as string) ?? "bash", + status: "running", + message: `Running ${((raw as Record).toolName as string) ?? "tool"}`, + }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + } + break; + } + case "tool_execution_end": { + if (turnId) { + yield* offerRuntimeEvent({ + type: "tool.progress", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { + tool: ((raw as Record).toolName as string) ?? "bash", + status: (raw as Record).isError ? "failed" : "completed", + }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + } + break; + } + case "extension_ui_request": { + const requestId = + typeof (raw as Record).id === "string" + ? ((raw as Record).id as string) + : yield* randomUUIDv4; + const title = + typeof (raw as Record).title === "string" + ? ((raw as Record).title as string) + : typeof (raw as Record).method === "string" + ? ((raw as Record).method as string) + : "Pi request"; + const optionsRaw = (raw as Record).options as unknown; + const options = Array.isArray(optionsRaw) + ? (optionsRaw as Array).map((o) => ({ id: String(o), label: String(o) })) + : []; + yield* offerRuntimeEvent({ + type: "request.opened", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + ...(turnId ? { turnId } : {}), + requestId: requestId as never, + payload: { kind: "tool_user_input" as never, prompt: title, options }, + raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + }); + break; + } + default: + break; + } + }).pipe(Effect.catchCause((cause) => Effect.logWarning("Failed to handle Pi event", { cause }))); + + const startSession: ProviderAdapterShape["startSession"] = (input) => + withThreadLock( + input.threadId, + Effect.gen(function* () { + if (input.provider !== undefined && input.provider !== PROVIDER) { + return yield* new ProviderAdapterValidationError({ + provider: PROVIDER, + operation: "startSession", + issue: `Expected provider '${PROVIDER}' but received '${input.provider}'.`, + }); + } + if (!input.cwd?.trim()) { + return yield* new ProviderAdapterValidationError({ + provider: PROVIDER, + operation: "startSession", + issue: "cwd is required and must be non-empty.", + }); + } + + const existing = sessions.get(input.threadId); + if (existing && !existing.stopped) { + yield* stopSessionInternal(existing); + } + + const scope = yield* Scope.make(); + let scopeTransferred = false; + yield* Effect.addFinalizer(() => (scopeTransferred ? Effect.void : Scope.close(scope, Effect.void as never))); + + const launchArgs = piLaunchArgs(piSettings.launchArgs); + const binaryPath = piSettings.binaryPath || "pi"; + const args = ["--mode", "rpc", ...launchArgs]; + const env = { ...process.env, ...(options?.environment ?? {}) } as NodeJS.ProcessEnv; + + const nodeChild: NodeChildProcess = yield* Effect.tryPromise({ + try: async () => { + const { spawn } = await import("node:child_process"); + return spawn(binaryPath, args, { + cwd: input.cwd, + env, + stdio: ["pipe", "pipe", "pipe"], + }); + }, + catch: (cause) => + new ProviderAdapterProcessError({ + provider: PROVIDER, + threadId: input.threadId, + detail: `Failed to spawn Pi: ${String(cause)}`, + cause, + }), + }); + + const now = yield* nowIso; + const session: ProviderSession = { + provider: PROVIDER, + providerInstanceId: boundInstanceId, + status: "ready", + runtimeMode: input.runtimeMode, + cwd: input.cwd, + threadId: input.threadId, + resumeCursor: null, + createdAt: now, + updatedAt: now, + }; + + const ctx: PiSessionContext = { + threadId: input.threadId, + session, + scope, + child: nodeChild, + activeTurnId: undefined, + pendingCommands: new Map(), + stopped: false, + }; + + // stderr logging + const stderr = nodeChild.stderr as NodeJS.ReadableStream | null | undefined; + if (stderr) { + stderr.on("data", (chunk: Buffer) => { + Effect.runSync( + Effect.logWarning("Pi stderr", { + threadId: input.threadId, + chunk: chunk.toString().slice(0, 500), + }), + ); + }); + } + + // stdout JSONL loop + const stdout = nodeChild.stdout as NodeJS.ReadableStream | null | undefined; + if (stdout) { + yield* Effect.gen(function* () { + let buffer = ""; + for await (const chunk of stdout as unknown as AsyncIterable) { + const text = typeof chunk === "string" ? chunk : (chunk as Buffer).toString("utf-8"); + buffer += text; + let nl: number; + while ((nl = buffer.indexOf("\n")) !== -1) { + let line = buffer.slice(0, nl); + buffer = buffer.slice(nl + 1); + if (line.endsWith("\r")) line = line.slice(0, -1); + if (!line.trim()) continue; + let parsed: unknown; + try { + parsed = JSON.parse(line); + } catch { + yield* Effect.logWarning("Pi RPC parse error", { line: line.slice(0, 500) }); + continue; + } + yield* handlePiEvent(ctx, parsed); + } + } + }).pipe( + Effect.catchCause((cause) => Effect.logWarning("Pi stdout loop failed", { cause })), + Effect.forkIn(scope), + ); + } + + // exit handler + yield* Effect.async((resume) => { + const onExit = (code: number | null, signal: string | null) => { + if (!ctx.stopped) { + Effect.runSync( + offerRuntimeEvent({ + type: "session.exited", + eventId: EventId.make(`${Date.now()}-${Math.random()}` as never), + provider: PROVIDER, + threadId: ctx.threadId, + createdAt: new Date().toISOString() as never, + payload: { + exitKind: code === 0 ? "graceful" : "error", + reason: `exit code ${code} signal ${signal}`, + }, + }), + ); + } + resume(Effect.void); + }; + nodeChild.on("exit", onExit); + nodeChild.on("error", () => resume(Effect.void)); + }).pipe(Effect.forkIn(scope)); + + sessions.set(input.threadId, ctx); + scopeTransferred = true; + + yield* offerRuntimeEvent({ + type: "session.started", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + payload: {}, + }); + yield* offerRuntimeEvent({ + type: "session.state.changed", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + payload: { state: "ready", reason: "Pi RPC session ready" }, + }); + yield* offerRuntimeEvent({ + type: "thread.started", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + payload: { providerThreadId: input.threadId }, + }); + + return session; + }).pipe(Effect.scoped), + ); + + const sendTurn: ProviderAdapterShape["sendTurn"] = (input) => + withThreadLock( + input.threadId, + Effect.gen(function* () { + const ctx = yield* requireSession(input.threadId); + const text = input.input?.trim() ?? ""; + const turnId = TurnId.make(yield* randomUUIDv4); + ctx.activeTurnId = turnId; + ctx.session = { + ...ctx.session, + status: "running", + activeTurnId: turnId, + updatedAt: yield* nowIso, + }; + + const images: Array<{ type: "image"; data: string; mimeType: string }> = []; + for (const attachment of input.attachments ?? []) { + const attachmentPath = resolveAttachmentPath({ + attachmentsDir: serverConfig.attachmentsDir, + attachment, + }); + if (!attachmentPath) { + return yield* new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "prompt", + detail: `Invalid attachment id '${attachment.id}'.`, + }); + } + const bytes = yield* fileSystem.readFile(attachmentPath).pipe( + Effect.mapError( + (cause) => + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "prompt", + detail: cause.message, + cause, + }), + ), + ); + images.push({ + type: "image", + data: Buffer.from(bytes).toString("base64"), + mimeType: attachment.mimeType, + }); + } + + if (!text && images.length === 0) { + return yield* new ProviderAdapterValidationError({ + provider: PROVIDER, + operation: "sendTurn", + issue: "Turn requires non-empty text or attachments.", + }); + } + + yield* offerRuntimeEvent({ + type: "turn.started", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + turnId, + payload: {}, + }); + + const promptPayload: PiRpcCommand = { + type: "prompt", + message: text || "(attached files)", + ...(images.length > 0 ? { images } : {}), + }; + + const rpcResult = yield* writeRpcCommand(ctx, promptPayload).pipe( + Effect.catchAll((cause) => + Effect.gen(function* () { + yield* offerRuntimeEvent({ + type: "turn.completed", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + turnId, + payload: { state: "failed", errorMessage: cause.message ?? String(cause) }, + }); + ctx.activeTurnId = undefined; + const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; + ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt: yield* nowIso } as ProviderSession; + return yield* Effect.fail(cause); + }), + ), + ); + + if (!rpcResult.success) { + yield* offerRuntimeEvent({ + type: "turn.completed", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + turnId, + payload: { state: "failed", errorMessage: rpcResult.error ?? "Pi prompt rejected" }, + }); + ctx.activeTurnId = undefined; + const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; + ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt: yield* nowIso } as ProviderSession; + return yield* new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "prompt", + detail: rpcResult.error ?? "Pi prompt rejected", + }); + } + + // Poll get_state until not streaming, then complete turn + yield* Effect.forkScoped( + Effect.gen(function* () { + for (let attempt = 0; attempt < 600; attempt++) { + yield* Effect.sleep(1000); + if (ctx.stopped) break; + const stateRes = yield* writeRpcCommand(ctx, { type: "get_state" }).pipe( + Effect.orElseSucceed(() => ({ success: false as const })), + ); + if (!stateRes.success) continue; + const data = (stateRes.data ?? {}) as Record; + if (data.isStreaming === false) { + yield* offerRuntimeEvent({ + type: "turn.completed", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + turnId, + payload: { state: "completed", stopReason: "stop" }, + }); + ctx.activeTurnId = undefined; + const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; + ctx.session = { + ...(ready as unknown as ProviderSession), + status: "ready", + updatedAt: yield* nowIso, + } as ProviderSession; + break; + } + } + }), + ).pipe(Effect.ignore); + + return { + threadId: input.threadId, + turnId, + resumeCursor: ctx.session.resumeCursor, + }; + }), + ); + + const interruptTurn: ProviderAdapterShape["interruptTurn"] = (threadId, turnId) => + Effect.gen(function* () { + const ctx = sessions.get(threadId); + if (!ctx || ctx.stopped) return; + yield* writeRpcCommand(ctx, { type: "abort" }).pipe(Effect.ignore); + const targetTurnId = turnId ?? ctx.activeTurnId; + if (targetTurnId) { + yield* offerRuntimeEvent({ + type: "turn.completed", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId, + turnId: targetTurnId, + payload: { state: "cancelled", stopReason: "cancelled" }, + }); + } + ctx.activeTurnId = undefined; + const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; + ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt: yield* nowIso } as ProviderSession; + }); + + const respondToRequest: ProviderAdapterShape["respondToRequest"] = ( + threadId, + requestId, + decision, + ) => + Effect.gen(function* () { + const ctx = yield* requireSession(threadId); + const response: PiRpcCommand = + decision === "cancel" + ? { type: "extension_ui_response", id: requestId as string, cancelled: true } + : { + type: "extension_ui_response", + id: requestId as string, + value: decision === "accept" || decision === "acceptForSession" ? "Allow" : "Block", + }; + yield* writeRpcCommand(ctx, response).pipe(Effect.ignore); + yield* offerRuntimeEvent({ + type: "request.resolved", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId, + requestId: requestId as never, + payload: { decision } as never, + }); + }); + + const respondToUserInput: ProviderAdapterShape["respondToUserInput"] = ( + threadId, + requestId, + answers, + ) => + Effect.gen(function* () { + const ctx = yield* requireSession(threadId); + const firstAnswer = Object.values(answers)[0] ?? ""; + yield* writeRpcCommand(ctx, { + type: "extension_ui_response", + id: requestId as string, + value: String(firstAnswer), + }).pipe(Effect.ignore); + yield* offerRuntimeEvent({ + type: "user-input.resolved", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId, + requestId: requestId as never, + payload: { answers }, + }); + }); + + const stopSession: ProviderAdapterShape["stopSession"] = (threadId) => + withThreadLock( + threadId, + Effect.gen(function* () { + const ctx = sessions.get(threadId); + if (!ctx) return; + yield* stopSessionInternal(ctx); + }), + ); + + const listSessions: ProviderAdapterShape["listSessions"] = () => + Effect.sync(() => Array.from(sessions.values()).map((c) => c.session)); + + const hasSession: ProviderAdapterShape["hasSession"] = (threadId) => + Effect.sync(() => sessions.has(threadId) && !sessions.get(threadId)?.stopped); + + const readThread: ProviderAdapterShape["readThread"] = (threadId) => + Effect.gen(function* () { + const ctx = yield* requireSession(threadId); + const res = yield* writeRpcCommand(ctx, { type: "get_messages" }).pipe( + Effect.mapError( + (cause) => + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "readThread", + detail: cause.message, + cause, + }), + ), + ); + const messages = ((res.data ?? {}) as Record).messages as unknown[] | undefined; + return { + threadId, + turns: [ + { + id: ctx.activeTurnId ?? TurnId.make("turn-pi-read"), + items: messages ?? [], + }, + ], + }; + }); + + const rollbackThread: ProviderAdapterShape["rollbackThread"] = (threadId) => + Effect.gen(function* () { + return yield* readThread(threadId); + }); + + const stopAll: ProviderAdapterShape["stopAll"] = () => + Effect.forEach(Array.from(sessions.values()), (ctx) => stopSessionInternal(ctx), { + discard: true, + }); + + return { + provider: PROVIDER, + capabilities: { sessionModelSwitch: "unsupported" }, + startSession, + sendTurn, + interruptTurn, + respondToRequest, + respondToUserInput, + stopSession, + listSessions, + hasSession, + readThread, + rollbackThread, + stopAll, + streamEvents: Stream.fromPubSub(runtimeEventPubSub), + } satisfies ProviderAdapterShape; + }); +} diff --git a/apps/server/src/provider/Layers/PiProvider.ts b/apps/server/src/provider/Layers/PiProvider.ts new file mode 100644 index 000000000000..737db0c58b02 --- /dev/null +++ b/apps/server/src/provider/Layers/PiProvider.ts @@ -0,0 +1,235 @@ +import type { ModelCapabilities, PiSettings, ServerProvider, ServerProviderModel } from "@t3tools/contracts"; +import { causeErrorTag } from "@t3tools/shared/observability"; +import * as DateTime from "effect/DateTime"; +import * as Effect from "effect/Effect"; +import * as Option from "effect/Option"; +import * as Result from "effect/Result"; +import { HttpClient } from "effect/unstable/http"; +import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; +import { createModelCapabilities } from "@t3tools/shared/model"; +import { resolveSpawnCommand } from "@t3tools/shared/shell"; + +import { + buildServerProvider, + isCommandMissingCause, + parseGenericCliVersion, + providerModelsFromSettings, + spawnAndCollect, + type ServerProviderDraft, +} from "../providerSnapshot.ts"; +import { + enrichProviderSnapshotWithVersionAdvisory, + type ProviderMaintenanceCapabilities, +} from "../providerMaintenance.ts"; + +const PI_PRESENTATION = { + displayName: "Pi", + badgeLabel: null, + showInteractionModeToggle: false, + requiresNewThreadForModelChange: false, +} as const; + +const EMPTY_CAPABILITIES: ModelCapabilities = createModelCapabilities({ + optionDescriptors: [], +}); + +const VERSION_PROBE_TIMEOUT_MS = 4_000; + +const PI_BUILT_IN_MODELS: ReadonlyArray = [ + { + slug: "pi", + name: "Pi", + isCustom: false, + capabilities: EMPTY_CAPABILITIES, + }, +]; + +export function buildInitialPiProviderSnapshot( + piSettings: PiSettings, +): Effect.Effect { + return Effect.gen(function* () { + const checkedAt = yield* Effect.map(DateTime.now, DateTime.formatIso); + const models = piModelsFromSettings(piSettings.customModels); + + if (!piSettings.enabled) { + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: false, + checkedAt, + models, + probe: { + installed: false, + version: null, + status: "warning", + auth: { status: "unknown" }, + message: "Pi is disabled in T3 Code settings.", + }, + }); + } + + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: true, + checkedAt, + models, + probe: { + installed: true, + version: null, + status: "warning", + auth: { status: "unknown" }, + message: "Checking Pi CLI availability...", + }, + }); + }); +} + +function piModelsFromSettings( + customModels: ReadonlyArray | undefined, + builtInModels: ReadonlyArray = PI_BUILT_IN_MODELS, +): ReadonlyArray { + return providerModelsFromSettings(builtInModels, customModels ?? [], EMPTY_CAPABILITIES); +} + +const runPiVersionCommand = ( + piSettings: PiSettings, + environment: NodeJS.ProcessEnv = process.env, +) => + Effect.gen(function* () { + const command = piSettings.binaryPath || "pi"; + const spawnCommand = yield* resolveSpawnCommand(command, ["--version"], { + env: environment, + }); + return yield* spawnAndCollect( + command, + ChildProcess.make(spawnCommand.command, spawnCommand.args, { + env: environment, + shell: spawnCommand.shell, + }), + ); + }); + +export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function* ( + piSettings: PiSettings, + environment: NodeJS.ProcessEnv = process.env, +): Effect.fn.Return { + const checkedAt = DateTime.formatIso(yield* DateTime.now); + const fallbackModels = piModelsFromSettings(piSettings.customModels); + + if (!piSettings.enabled) { + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: false, + checkedAt, + models: fallbackModels, + probe: { + installed: false, + version: null, + status: "warning", + auth: { status: "unknown" }, + message: "Pi is disabled in T3 Code settings.", + }, + }); + } + + const versionResult = yield* runPiVersionCommand(piSettings, environment).pipe( + Effect.timeoutOption(VERSION_PROBE_TIMEOUT_MS), + Effect.result, + ); + + if (Result.isFailure(versionResult)) { + const error = versionResult.failure; + yield* Effect.logWarning("Pi CLI health check failed.", { + errorTag: error._tag, + }); + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: piSettings.enabled, + checkedAt, + models: fallbackModels, + probe: { + installed: !isCommandMissingCause(error), + version: null, + status: "error", + auth: { status: "unknown" }, + message: isCommandMissingCause(error) + ? "Pi CLI (`pi`) is not installed or not on PATH." + : "Failed to execute Pi CLI health check.", + }, + }); + } + + if (Option.isNone(versionResult.success)) { + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: piSettings.enabled, + checkedAt, + models: fallbackModels, + probe: { + installed: true, + version: null, + status: "error", + auth: { status: "unknown" }, + message: "Pi CLI is installed but timed out while running `pi --version`.", + }, + }); + } + + const versionOutput = versionResult.success.value; + const version = parseGenericCliVersion(`${versionOutput.stdout}\n${versionOutput.stderr}`); + if (versionOutput.code !== 0) { + yield* Effect.logWarning("Pi CLI version probe exited with a non-zero status.", { + exitCode: versionOutput.code, + stdoutLength: versionOutput.stdout.length, + stderrLength: versionOutput.stderr.length, + }); + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: piSettings.enabled, + checkedAt, + models: fallbackModels, + probe: { + installed: true, + version, + status: "error", + auth: { status: "unknown" }, + message: "Pi CLI is installed but failed to run.", + }, + }); + } + + return buildServerProvider({ + presentation: PI_PRESENTATION, + enabled: piSettings.enabled, + checkedAt, + models: fallbackModels, + probe: { + installed: true, + version, + status: "ready", + auth: { status: "unknown" }, + }, + }); +}); + +export const enrichPiSnapshot = (input: { + readonly snapshot: ServerProvider; + readonly maintenanceCapabilities: ProviderMaintenanceCapabilities; + readonly enableProviderUpdateChecks?: boolean; + readonly publishSnapshot: (snapshot: ServerProvider) => Effect.Effect; + readonly httpClient: HttpClient.HttpClient; +}): Effect.Effect => { + const { snapshot, publishSnapshot } = input; + + return enrichProviderSnapshotWithVersionAdvisory(snapshot, input.maintenanceCapabilities, { + enableProviderUpdateChecks: input.enableProviderUpdateChecks, + }).pipe( + Effect.provideService(HttpClient.HttpClient, input.httpClient), + Effect.flatMap((enrichedSnapshot) => publishSnapshot(enrichedSnapshot)), + Effect.catchCause((cause) => + Effect.logWarning("Pi version advisory enrichment failed", { + errorTag: causeErrorTag(cause), + }), + ), + Effect.asVoid, + ); +}; diff --git a/apps/server/src/provider/builtInDrivers.ts b/apps/server/src/provider/builtInDrivers.ts index 791a96e1da3c..02f95495da5d 100644 --- a/apps/server/src/provider/builtInDrivers.ts +++ b/apps/server/src/provider/builtInDrivers.ts @@ -25,6 +25,7 @@ import { CodexDriver, type CodexDriverEnv } from "./Drivers/CodexDriver.ts"; import { CursorDriver, type CursorDriverEnv } from "./Drivers/CursorDriver.ts"; import { GrokDriver, type GrokDriverEnv } from "./Drivers/GrokDriver.ts"; import { OpenCodeDriver, type OpenCodeDriverEnv } from "./Drivers/OpenCodeDriver.ts"; +import { PiDriver, type PiDriverEnv } from "./Drivers/PiDriver.ts"; import type { AnyProviderDriver } from "./ProviderDriver.ts"; /** @@ -37,7 +38,8 @@ export type BuiltInDriversEnv = | CodexDriverEnv | CursorDriverEnv | GrokDriverEnv - | OpenCodeDriverEnv; + | OpenCodeDriverEnv + | PiDriverEnv; /** * Ordered list of built-in drivers. Order matters only for tie-breaking in @@ -50,4 +52,5 @@ export const BUILT_IN_DRIVERS: ReadonlyArray({ + piSettings, + environment, + cwd, + prompt, + outputSchemaJson, +}: { + piSettings: PiSettings; + environment: NodeJS.ProcessEnv; + cwd: string; + prompt: string; + outputSchemaJson: S; +}): Effect.Effect => + Effect.gen(function* () { + const binaryPath = piSettings.binaryPath || "pi"; + const launchArgs = tokenizeCliArgs(piSettings.launchArgs?.trim() ?? ""); + // Use print mode with structured JSON instruction: pi will return assistant text directly. + // We ask pi to output JSON; then extract JSON blob from stdout. + const spawnCommand = yield* resolveSpawnCommand( + binaryPath, + ["-p", "--no-session", "--no-context-files", ...launchArgs, prompt], + { env: environment }, + ).pipe( + Effect.mapError( + (cause) => + new TextGenerationError({ + provider: "pi", + operation: "spawn", + detail: cause.message, + cause, + }), + ), + ); + + const result = yield* spawnAndCollect( + binaryPath, + ChildProcess.make(spawnCommand.command, spawnCommand.args, { + env: environment, + cwd, + shell: spawnCommand.shell, + }), + ).pipe( + Effect.timeoutFail({ + duration: PI_TIMEOUT_MS, + onTimeout: () => + new TextGenerationError({ + provider: "pi", + operation: "timeout", + detail: `Pi text generation timed out after ${PI_TIMEOUT_MS}ms`, + }), + }), + Effect.mapError((cause) => { + if (isTextGenerationError(cause)) return cause; + return new TextGenerationError({ + provider: "pi", + operation: "spawn", + detail: cause instanceof Error ? cause.message : String(cause), + cause, + }); + }), + ); + + if (result.code !== 0) { + const stderr = result.stderr.trim() || result.stdout.trim(); + return yield* new TextGenerationError({ + provider: "pi", + operation: "spawn", + detail: stderr || `Pi exited with code ${result.code}`, + }); + } + + const stdout = result.stdout.trim(); + if (!stdout) { + return yield* new TextGenerationError({ + provider: "pi", + operation: "decode", + detail: "Pi returned empty output", + }); + } + + // Try direct JSON, then extract embedded JSON object + const tryParse = (text: string): unknown | undefined => { + try { + return JSON.parse(text); + } catch { + return undefined; + } + }; + + let parsed: unknown | undefined = tryParse(stdout); + if (parsed === undefined) { + const extracted = extractJsonObject(stdout); + if (extracted) parsed = tryParse(extracted); + } + if (parsed === undefined) { + // Try to find JSON between ```json blocks + const fenceMatch = stdout.match(/```(?:json)?\s*([\s\S]*?)```/i); + if (fenceMatch?.[1]) { + parsed = tryParse(fenceMatch[1].trim()); + if (parsed === undefined) { + const extracted = extractJsonObject(fenceMatch[1]); + if (extracted) parsed = tryParse(extracted); + } + } + } + if (parsed === undefined) { + return yield* new TextGenerationError({ + provider: "pi", + operation: "decode", + detail: `Pi output was not valid JSON: ${stdout.slice(0, 500)}`, + }); + } + + return yield* Schema.decodeUnknown(Schema.parseJson(outputSchemaJson as any))(JSON.stringify(parsed)).pipe( + Effect.mapError( + (cause) => + new TextGenerationError({ + provider: "pi", + operation: "decode", + detail: cause.message ?? String(cause), + cause, + }), + ), + ) as any; + }); + +export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* ( + piSettings: PiSettings, + environment: NodeJS.ProcessEnv = process.env, +) { + const crypto = yield* Crypto.Crypto; + const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const bucket = yield* TokenBucket.make({ capacity: 5, refillPerSecond: 0.5 }); + + const withRateLimit = (effect: Effect.Effect) => + bucket.take(1).pipe(Effect.flatMap(() => effect)); + + const generateCommitMessage: TextGeneration.TextGeneration["Service"]["generateCommitMessage"] = ( + input, + ) => + withRateLimit( + Effect.gen(function* () { + const prompt = buildCommitMessagePrompt(input); + const outputSchemaJson = Schema.Struct({ + commitMessage: Schema.String, + }); + const result = yield* runPiJson({ + piSettings, + environment, + cwd: input.cwd, + prompt: prompt + "\n\nRespond with JSON: {\"commitMessage\": \"...\"}", + outputSchemaJson, + }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); + return { commitMessage: sanitizeCommitSubject(result.commitMessage) }; + }), + ); + + const generatePrContent: TextGeneration.TextGeneration["Service"]["generatePrContent"] = ( + input, + ) => + withRateLimit( + Effect.gen(function* () { + const prompt = buildPrContentPrompt(input); + const outputSchemaJson = Schema.Struct({ + title: Schema.String, + body: Schema.String, + }); + const result = yield* runPiJson({ + piSettings, + environment, + cwd: input.cwd, + prompt: prompt + "\n\nRespond with JSON: {\"title\": \"...\", \"body\": \"...\"}", + outputSchemaJson, + }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); + return { + title: sanitizePrTitle(result.title), + body: result.body.trim(), + }; + }), + ); + + const generateBranchName: TextGeneration.TextGeneration["Service"]["generateBranchName"] = ( + input, + ) => + withRateLimit( + Effect.gen(function* () { + const prompt = buildBranchNamePrompt(input); + const outputSchemaJson = Schema.Struct({ + branchName: Schema.String, + }); + const result = yield* runPiJson({ + piSettings, + environment, + cwd: input.cwd, + prompt: prompt + "\n\nRespond with JSON: {\"branchName\": \"...\"}", + outputSchemaJson, + }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); + const fragment = sanitizeBranchFragment(result.branchName); + return { branchName: sanitizeFeatureBranchName(fragment || result.branchName) }; + }), + ); + + const generateThreadTitle: TextGeneration.TextGeneration["Service"]["generateThreadTitle"] = ( + input, + ) => + withRateLimit( + Effect.gen(function* () { + const prompt = buildThreadTitlePrompt(input); + const outputSchemaJson = Schema.Struct({ + title: Schema.String, + }); + const result = yield* runPiJson({ + piSettings, + environment, + cwd: input.cwd, + prompt: prompt + "\n\nRespond with JSON: {\"title\": \"...\"}", + outputSchemaJson, + }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); + return { title: sanitizeThreadTitle(result.title) }; + }), + ); + + return { + generateCommitMessage, + generatePrContent, + generateBranchName, + generateThreadTitle, + } satisfies TextGeneration.TextGeneration["Service"]; +}); diff --git a/packages/contracts/src/model.ts b/packages/contracts/src/model.ts index 9fcd0d266dd6..ec5b2e096f22 100644 --- a/packages/contracts/src/model.ts +++ b/packages/contracts/src/model.ts @@ -132,6 +132,7 @@ const CLAUDE_DRIVER_KIND = ProviderDriverKind.make("claudeAgent"); const CURSOR_DRIVER_KIND = ProviderDriverKind.make("cursor"); const GROK_DRIVER_KIND = ProviderDriverKind.make("grok"); const OPENCODE_DRIVER_KIND = ProviderDriverKind.make("opencode"); +const PI_DRIVER_KIND = ProviderDriverKind.make("pi"); export const DEFAULT_MODEL = "gpt-5.6-sol"; @@ -153,6 +154,7 @@ export const DEFAULT_MODEL_BY_PROVIDER: Partial> [CURSOR_DRIVER_KIND]: "Cursor", [GROK_DRIVER_KIND]: "Grok", [OPENCODE_DRIVER_KIND]: "OpenCode", + [PI_DRIVER_KIND]: "Pi", }; diff --git a/packages/contracts/src/settings.ts b/packages/contracts/src/settings.ts index 76bb032c866e..d9bf547fc5ba 100644 --- a/packages/contracts/src/settings.ts +++ b/packages/contracts/src/settings.ts @@ -550,6 +550,42 @@ export const OpenCodeSettings = makeProviderSettingsSchema( ); export type OpenCodeSettings = typeof OpenCodeSettings.Type; +export const PiSettings = makeProviderSettingsSchema( + { + // Off by default until the binding stabilizes; users opt in from Settings. + enabled: Schema.Boolean.pipe( + Schema.withDecodingDefault(Effect.succeed(false)), + Schema.annotateKey({ providerSettingsForm: { hidden: true } }), + ), + binaryPath: makeBinaryPathSetting("pi").pipe( + Schema.annotateKey({ + title: "Binary path", + description: "Path to the Pi coding agent binary.", + providerSettingsForm: { placeholder: "pi", clearWhenEmpty: "omit" }, + }), + ), + launchArgs: TrimmedString.pipe( + Schema.withDecodingDefault(Effect.succeed("")), + Schema.annotateKey({ + title: "Launch arguments", + description: "Additional CLI arguments passed to pi --mode rpc on session start.", + providerSettingsForm: { + placeholder: "e.g. --provider anthropic", + clearWhenEmpty: "omit", + }, + }), + ), + customModels: Schema.Array(Schema.String).pipe( + Schema.withDecodingDefault(Effect.succeed([])), + Schema.annotateKey({ providerSettingsForm: { hidden: true } }), + ), + }, + { + order: ["binaryPath", "launchArgs"], + }, +); +export type PiSettings = typeof PiSettings.Type; + export const ObservabilitySettings = Schema.Struct({ otlpTracesUrl: TrimmedString.pipe(Schema.withDecodingDefault(Effect.succeed(""))), otlpMetricsUrl: TrimmedString.pipe(Schema.withDecodingDefault(Effect.succeed(""))), @@ -692,6 +728,7 @@ export const ServerSettings = Schema.Struct({ cursor: CursorSettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), grok: GrokSettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), opencode: OpenCodeSettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), + pi: PiSettings.pipe(Schema.withDecodingDefault(Effect.succeed({}))), }).pipe(Schema.withDecodingDefault(Effect.succeed({}))), // New driver-agnostic instance map. Keyed by `ProviderInstanceId`; values // are `ProviderInstanceConfig` envelopes. The driver-specific config blob @@ -845,6 +882,13 @@ const OpenCodeSettingsPatch = Schema.Struct({ customModels: Schema.optionalKey(Schema.Array(Schema.String)), }); +const PiSettingsPatch = Schema.Struct({ + enabled: Schema.optionalKey(Schema.Boolean), + binaryPath: Schema.optionalKey(TrimmedString), + launchArgs: Schema.optionalKey(TrimmedString), + customModels: Schema.optionalKey(Schema.Array(Schema.String)), +}); + export const ServerSettingsPatch = Schema.Struct({ // Server settings enableLegacyTokenStreaming: Schema.optionalKey(Schema.Boolean), @@ -886,6 +930,7 @@ export const ServerSettingsPatch = Schema.Struct({ cursor: Schema.optionalKey(CursorSettingsPatch), grok: Schema.optionalKey(GrokSettingsPatch), opencode: Schema.optionalKey(OpenCodeSettingsPatch), + pi: Schema.optionalKey(PiSettingsPatch), }), ), // Whole-map replacement for the new instance config. Patching individual From 8afc6ba9e91d4d630105e17c2803309f29d540d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 10:00:02 +1200 Subject: [PATCH 03/20] ci: add automated upstream sync workflow --- .github/workflows/sync-upstream.yml | 198 ++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 .github/workflows/sync-upstream.yml diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml new file mode 100644 index 000000000000..d37cde6c212b --- /dev/null +++ b/.github/workflows/sync-upstream.yml @@ -0,0 +1,198 @@ +name: sync-upstream + +on: + schedule: + # Every 2 days at 00:00 UTC + - cron: "0 0 */2 * *" + workflow_dispatch: + +# Single sync at a time; don't cancel in-progress syncs +concurrency: + group: sync-upstream + cancel-in-progress: false + +permissions: + contents: write + pull-requests: write + issues: write + actions: read + id-token: write + +env: + UPSTREAM_REPOSITORY: pingdotgg/t3code + UPSTREAM_BRANCH: main + TARGET_BRANCH: main + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + fetch-depth: 0 + persist-credentials: true + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Configure git identity + run: | + git config user.email "github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + + - name: Add upstream remote + run: | + if git remote get-url upstream >/dev/null 2>&1; then + git remote set-url upstream "https://github.com/${UPSTREAM_REPOSITORY}.git" + else + git remote add upstream "https://github.com/${UPSTREAM_REPOSITORY}.git" + fi + git fetch upstream "${UPSTREAM_BRANCH}" + + - name: Check if sync needed + id: check + run: | + if git merge-base --is-ancestor "upstream/${UPSTREAM_BRANCH}" HEAD; then + echo "needed=false" >> "$GITHUB_OUTPUT" + echo "Upstream already merged — nothing to do." + else + echo "needed=true" >> "$GITHUB_OUTPUT" + echo "Upstream has new commits:" + git log --oneline HEAD.."upstream/${UPSTREAM_BRANCH}" | head -n 20 + fi + + - name: Attempt merge on sync branch + if: steps.check.outputs.needed == 'true' + id: merge + run: | + set +e + SYNC_BRANCH="sync/upstream-$(date +%Y%m%d-%H%M%S)" + echo "branch=${SYNC_BRANCH}" >> "$GITHUB_OUTPUT" + git checkout -b "${SYNC_BRANCH}" + + git merge --no-edit "upstream/${UPSTREAM_BRANCH}" + status=$? + + if [ $status -eq 0 ]; then + echo "conflict=false" >> "$GITHUB_OUTPUT" + echo "Auto-merge succeeded." + else + echo "conflict=true" >> "$GITHUB_OUTPUT" + echo "Auto-merge failed with conflicts — will delegate to opencode." + # Keep conflicted working tree for the AI step (don't abort) + git status --porcelain | head -n 30 + git diff --name-only --diff-filter=U | head -n 30 + fi + exit 0 + + - name: Push clean merge to target branch + if: steps.check.outputs.needed == 'true' && steps.merge.outputs.conflict == 'false' + env: + SYNC_BRANCH: ${{ steps.merge.outputs.branch }} + run: | + # Option 1: push sync branch and fast-forward target via PR-less direct push. + # Keeping a PR path would be safer if you want review; swap this block for `gh pr create` if needed. + git push origin "${SYNC_BRANCH}:${TARGET_BRANCH}" + echo "Pushed upstream merge directly to ${TARGET_BRANCH}." + + # Optionally also push the sync branch for history + # git push origin "${SYNC_BRANCH}" || true + + - name: Resolve conflicts with opencode + if: steps.check.outputs.needed == 'true' && steps.merge.outputs.conflict == 'true' + uses: anomalyco/opencode/github@latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + META_MODEL_API_KEY: ${{ secrets.META_MODEL_API_KEY }} + with: + model: meta/muse-spark-1.2-contributor + use_github_token: true + prompt: | + Resolve git merge conflicts from an upstream sync (upstream/${{ env.UPSTREAM_BRANCH }} into ${{ env.TARGET_BRANCH }}). + + Current branch is a sync branch with conflict markers (<<<<<<<, =======, >>>>>>>) in the working tree from `git merge --no-edit upstream/${{ env.UPSTREAM_BRANCH }}`. + + Your tasks: + 1. Find all conflicted files: `git diff --name-only --diff-filter=U` and files containing `<<<<<<<`. + 2. For each conflict, understand BOTH sides: + - HEAD side = our fork's customizations (keep intentional fork changes such as fork-specific workflows, configs, or branding). + - upstream side = the canonical T3 Code changes (prefer upstream for core logic, providers, orchestration, and client code unless it would revert an intentional fork divergence). + 3. Resolve each file to a correct merged state. Do not leave any conflict markers. Combine logic where both sides added code (e.g., imports, lists, dependencies). Preserve formatting and existing conventions. + 4. After editing, run `git add -A` and verify no unmerged paths remain: `git ls-files --unmerged` should be empty and `grep -r "<<<<<<<" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.json" --include="*.yml" --include="*.yaml" --include="*.md" .` should return nothing. + 5. Commit the resolution with message `chore: resolve upstream sync conflicts` if not already committed. Do not push yet — the workflow will create the PR. + + Constraints: + - Keep the code auditable and minimal. Do not add new dependencies or bloat. + - Do not revert upstream fixes to keep local style. + - If a file was deleted on one side and modified on the other, keep the deletion unless the fork explicitly needs the file. + + - name: Commit and push AI-resolved branch + open PR + if: steps.check.outputs.needed == 'true' && steps.merge.outputs.conflict == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SYNC_BRANCH: ${{ steps.merge.outputs.branch }} + run: | + set -e + + # Opencode should have resolved and staged changes; if not, check status + if git ls-files --unmerged | grep -q .; then + echo "::error::Conflicts still present after opencode step:" + git ls-files --unmerged + grep -rn "<<<<<<<" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.json" --include="*.yml" --include="*.yaml" . | head -n 20 || true + exit 1 + fi + + # If opencode already committed, there will be no staged changes; otherwise commit now + if ! git diff --cached --quiet || ! git diff --quiet; then + git add -A + git commit -m "chore: resolve upstream sync conflicts" || true + fi + + # Ensure we have something to push (branch may already be ahead) + if git diff --quiet "origin/${TARGET_BRANCH}" 2>/dev/null; then + # Compare sync branch tip to target — if identical, skip + : + fi + + git push origin HEAD:"${SYNC_BRANCH}" + + # Create PR if one doesn't already exist for this branch + if gh pr view "${SYNC_BRANCH}" --json number >/dev/null 2>&1; then + echo "PR already exists for ${SYNC_BRANCH}" + gh pr view "${SYNC_BRANCH}" --json url --jq .url + else + gh pr create \ + --base "${TARGET_BRANCH}" \ + --head "${SYNC_BRANCH}" \ + --title "chore: sync upstream ${UPSTREAM_REPOSITORY} $(date +%Y-%m-%d)" \ + --body "$(cat <<'EOF' + Automated upstream sync from `${{ env.UPSTREAM_REPOSITORY }}`:`${{ env.UPSTREAM_BRANCH }}`. + + - Auto-merge failed — conflicts were resolved by opencode (model: \`meta/muse-spark-1.2-contributor\`, logic based on \`opencode-review.yml\`). + - Please review the resolution before merging. CI must pass. + + Upstream commits: + + EOF + )" \ + --label "automated" 2>/dev/null || gh pr create \ + --base "${TARGET_BRANCH}" \ + --head "${SYNC_BRANCH}" \ + --title "chore: sync upstream ${UPSTREAM_REPOSITORY} $(date +%Y-%m-%d)" \ + --body "Automated upstream sync — conflicts auto-resolved by AI. Review required." + + # Append upstream log to PR body + UPSTREAM_LOG="$(git log --oneline "origin/${TARGET_BRANCH}".."upstream/${UPSTREAM_BRANCH}" | head -n 30)" + if [ -n "${UPSTREAM_LOG}" ]; then + gh pr edit "${SYNC_BRANCH}" --body "$(gh pr view "${SYNC_BRANCH}" --json body --jq .body) + + --- + +
Upstream commits in this sync + + \`\`\` + ${UPSTREAM_LOG} + \`\`\` + +
" + fi + fi From 4bdb9841fcf2cee31c2a7374d9e4c5b3308eca70 Mon Sep 17 00:00:00 2001 From: theoneand33 <120695243+theoneand33@users.noreply.github.com> Date: Wed, 26 Aug 2026 13:02:25 +1200 Subject: [PATCH 04/20] Update opencode-review.yml --- .github/workflows/opencode-review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index 71536ad409c8..e7eb04270b36 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -18,6 +18,7 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false + submodules: recursive - name: Configure git identity for opencode commits run: | From 8fe3344e6a800ae77b1510e8ecec40179704de64 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 13:08:59 +1200 Subject: [PATCH 05/20] fix(pi): address review findings - PiDriver: make health check use live settings via snapshotSettings.getSettings - PiProvider: include configured binaryPath in probe error messages - PiTextGeneration: remove provider field from TextGenerationError, add --no-tools/--no-extensions and filter launchArgs - PiAdapter: fix Deferred error typing, map to CanonicalItemType, use RuntimeRequestId and acp.pi.extension source, replace for-await in Effect.gen with Effect.promise loop, mark session stopped on exit with makeEventStamp, deduplicate session-ready logic, guard poller by owned turn, propagate RPC failures for request/user-input, and make rollbackThread explicit --- apps/server/src/provider/Drivers/PiDriver.ts | 8 +- apps/server/src/provider/Layers/PiAdapter.ts | 165 ++++++++++++------ apps/server/src/provider/Layers/PiProvider.ts | 4 +- .../src/textGeneration/PiTextGeneration.ts | 14 +- 4 files changed, 120 insertions(+), 71 deletions(-) diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/apps/server/src/provider/Drivers/PiDriver.ts index 6838b03c7398..93a8d8de7dcf 100644 --- a/apps/server/src/provider/Drivers/PiDriver.ts +++ b/apps/server/src/provider/Drivers/PiDriver.ts @@ -113,13 +113,15 @@ export const PiDriver: ProviderDriver = { }); const textGeneration = yield* makePiTextGeneration(effectiveConfig, processEnv); - const checkProvider = checkPiProviderStatus(effectiveConfig, processEnv).pipe( + const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, serverSettings); + + const checkProvider = Effect.flatMap(snapshotSettings.getSettings, (settings) => + checkPiProviderStatus(settings.provider, processEnv), + ).pipe( Effect.map(stampIdentity), Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), ); - - const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, serverSettings); const snapshot = yield* makeManagedServerProvider>({ maintenanceCapabilities, getSettings: snapshotSettings.getSettings, diff --git a/apps/server/src/provider/Layers/PiAdapter.ts b/apps/server/src/provider/Layers/PiAdapter.ts index 690adca4a5dc..3a6262f0062a 100644 --- a/apps/server/src/provider/Layers/PiAdapter.ts +++ b/apps/server/src/provider/Layers/PiAdapter.ts @@ -10,12 +10,13 @@ import { type ApprovalRequestId, type ProviderApprovalDecision, type ProviderUserInputAnswers, + RuntimeRequestId, + type CanonicalItemType, } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as DateTime from "effect/DateTime"; import * as Deferred from "effect/Deferred"; import * as Effect from "effect/Effect"; -import * as Fiber from "effect/Fiber"; import * as FileSystem from "effect/FileSystem"; import * as PubSub from "effect/PubSub"; import * as Scope from "effect/Scope"; @@ -36,6 +37,7 @@ import { import type { ProviderAdapterShape } from "../Services/ProviderAdapter.ts"; const PROVIDER = ProviderDriverKind.make("pi"); +const PI_RAW_SOURCE = "acp.pi.extension" as const; interface PiRpcCommand { readonly id?: string; @@ -49,7 +51,10 @@ interface PiSessionContext { readonly scope: Scope.CloseableScope; child: NodeChildProcess | undefined; activeTurnId: TurnId | undefined; - pendingCommands: Map>; + pendingCommands: Map< + string, + Deferred.Deferred<{ success: boolean; data?: unknown; error?: string }, ProviderAdapterRequestError> + >; stopped: boolean; } @@ -57,6 +62,19 @@ function isRecord(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } +function toCanonicalItemType(toolName: string): CanonicalItemType { + const name = toolName.toLowerCase(); + if (name === "bash" || name === "command_execution" || name.includes("command")) return "command_execution"; + if (name === "read" || name === "edit" || name === "write" || name === "file_change" || name.includes("file")) return "file_change"; + if (name === "mcp_tool_call" || name.startsWith("mcp_")) return "mcp_tool_call"; + if (name === "web_search") return "web_search"; + return "dynamic_tool_call"; +} + +function asRuntimeRequestId(value: string): RuntimeRequestId { + return RuntimeRequestId.make(value); +} + export interface PiAdapterLiveOptions { readonly environment?: NodeJS.ProcessEnv; readonly instanceId?: ProviderInstanceId; @@ -120,6 +138,14 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt return Effect.succeed(ctx); }; + const markSessionReady = (ctx: PiSessionContext) => + Effect.gen(function* () { + const updatedAt = yield* nowIso; + const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; + ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt } as ProviderSession; + ctx.activeTurnId = undefined; + }); + const stopSessionInternal = (ctx: PiSessionContext) => Effect.gen(function* () { if (ctx.stopped) return; @@ -132,7 +158,14 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt yield* Effect.ignore(Scope.close(ctx.scope, Effect.void as any)); sessions.delete(ctx.threadId); for (const deferred of ctx.pendingCommands.values()) { - yield* Deferred.fail(deferred, new Error("Session stopped")).pipe(Effect.ignore); + yield* Deferred.fail( + deferred, + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "session", + detail: "Session stopped", + }), + ).pipe(Effect.ignore); } ctx.pendingCommands.clear(); yield* offerRuntimeEvent({ @@ -158,11 +191,14 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt } const id = (command.id ?? (yield* randomUUIDv4)) as string; const payload = { ...command, id }; - const deferred = yield* Deferred.make<{ success: boolean; data?: unknown; error?: string }>(); + const deferred = yield* Deferred.make< + { success: boolean; data?: unknown; error?: string }, + ProviderAdapterRequestError + >(); ctx.pendingCommands.set(id, deferred); const line = JSON.stringify(payload) + "\n"; const stdin = ctx.child.stdin as NodeJS.WritableStream; - const writeDone = yield* Effect.async((resume) => { + yield* Effect.async((resume) => { stdin.write(line, (err: unknown) => { if (err) { resume( @@ -180,7 +216,6 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt } }); }); - void writeDone; const result = yield* Deferred.await(deferred).pipe(Effect.timeoutOption(30_000)); if (result._tag === "None") { ctx.pendingCommands.delete(id); @@ -234,7 +269,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt threadId: ctx.threadId, turnId, payload: { kind: "assistant_text", delta: delta.delta as string }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); } else if (deltaType === "thinking_delta" && typeof delta.delta === "string") { yield* offerRuntimeEvent({ @@ -244,7 +279,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt threadId: ctx.threadId, turnId, payload: { kind: "reasoning_text", delta: delta.delta as string }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); } else if (deltaType === "toolcall_start") { const toolName = typeof delta.toolName === "string" ? (delta.toolName as string) : "tool"; @@ -254,8 +289,8 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt provider: PROVIDER, threadId: ctx.threadId, turnId, - payload: { kind: toolName as never, status: "inProgress" }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + payload: { kind: toCanonicalItemType(toolName), status: "inProgress" }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); } } @@ -270,7 +305,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt threadId: ctx.threadId, turnId, payload: { kind: "assistant_message", status: "completed" }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); } break; @@ -288,7 +323,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt status: "running", message: `Running ${((raw as Record).toolName as string) ?? "tool"}`, }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); } break; @@ -305,7 +340,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt tool: ((raw as Record).toolName as string) ?? "bash", status: (raw as Record).isError ? "failed" : "completed", }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); } break; @@ -331,9 +366,9 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt provider: PROVIDER, threadId: ctx.threadId, ...(turnId ? { turnId } : {}), - requestId: requestId as never, + requestId: asRuntimeRequestId(requestId), payload: { kind: "tool_user_input" as never, prompt: title, options }, - raw: { source: "codex.sdk.thread-event" as const, payload: raw }, + raw: { source: PI_RAW_SOURCE, payload: raw }, }); break; } @@ -416,7 +451,6 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt stopped: false, }; - // stderr logging const stderr = nodeChild.stderr as NodeJS.ReadableStream | null | undefined; if (stderr) { stderr.on("data", (chunk: Buffer) => { @@ -429,10 +463,9 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }); } - // stdout JSONL loop const stdout = nodeChild.stdout as NodeJS.ReadableStream | null | undefined; if (stdout) { - yield* Effect.gen(function* () { + const stdoutEffect = Effect.promise(async () => { let buffer = ""; for await (const chunk of stdout as unknown as AsyncIterable) { const text = typeof chunk === "string" ? chunk : (chunk as Buffer).toString("utf-8"); @@ -447,37 +480,47 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt try { parsed = JSON.parse(line); } catch { - yield* Effect.logWarning("Pi RPC parse error", { line: line.slice(0, 500) }); + await Effect.runPromise(Effect.logWarning("Pi RPC parse error", { line: line.slice(0, 500) })); continue; } - yield* handlePiEvent(ctx, parsed); + await Effect.runPromise(handlePiEvent(ctx, parsed)); } } - }).pipe( - Effect.catchCause((cause) => Effect.logWarning("Pi stdout loop failed", { cause })), - Effect.forkIn(scope), - ); + }).pipe(Effect.catchCause((cause) => Effect.logWarning("Pi stdout loop failed", { cause }))); + yield* stdoutEffect.pipe(Effect.forkIn(scope)); } - // exit handler yield* Effect.async((resume) => { const onExit = (code: number | null, signal: string | null) => { - if (!ctx.stopped) { + ctx.stopped = true; + sessions.delete(ctx.threadId); + for (const deferred of ctx.pendingCommands.values()) { Effect.runSync( - offerRuntimeEvent({ + Deferred.fail( + deferred, + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "session", + detail: `Pi process exited with code ${code} signal ${signal}`, + }), + ).pipe(Effect.ignore), + ); + } + ctx.pendingCommands.clear(); + Effect.runPromise( + Effect.gen(function* () { + yield* offerRuntimeEvent({ type: "session.exited", - eventId: EventId.make(`${Date.now()}-${Math.random()}` as never), + ...(yield* makeEventStamp()), provider: PROVIDER, threadId: ctx.threadId, - createdAt: new Date().toISOString() as never, payload: { exitKind: code === 0 ? "graceful" : "error", reason: `exit code ${code} signal ${signal}`, }, - }), - ); - } - resume(Effect.void); + }); + }), + ).finally(() => resume(Effect.void)); }; nodeChild.on("exit", onExit); nodeChild.on("error", () => resume(Effect.void)); @@ -592,9 +635,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt turnId, payload: { state: "failed", errorMessage: cause.message ?? String(cause) }, }); - ctx.activeTurnId = undefined; - const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; - ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt: yield* nowIso } as ProviderSession; + yield* markSessionReady(ctx); return yield* Effect.fail(cause); }), ), @@ -609,9 +650,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt turnId, payload: { state: "failed", errorMessage: rpcResult.error ?? "Pi prompt rejected" }, }); - ctx.activeTurnId = undefined; - const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; - ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt: yield* nowIso } as ProviderSession; + yield* markSessionReady(ctx); return yield* new ProviderAdapterRequestError({ provider: PROVIDER, method: "prompt", @@ -619,33 +658,31 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }); } - // Poll get_state until not streaming, then complete turn yield* Effect.forkScoped( Effect.gen(function* () { + const ownedTurnId = turnId; for (let attempt = 0; attempt < 600; attempt++) { yield* Effect.sleep(1000); if (ctx.stopped) break; + if (ctx.activeTurnId !== ownedTurnId) break; const stateRes = yield* writeRpcCommand(ctx, { type: "get_state" }).pipe( Effect.orElseSucceed(() => ({ success: false as const })), ); if (!stateRes.success) continue; const data = (stateRes.data ?? {}) as Record; if (data.isStreaming === false) { + if (ctx.activeTurnId !== ownedTurnId) break; yield* offerRuntimeEvent({ type: "turn.completed", ...(yield* makeEventStamp()), provider: PROVIDER, threadId: input.threadId, - turnId, + turnId: ownedTurnId, payload: { state: "completed", stopReason: "stop" }, }); - ctx.activeTurnId = undefined; - const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; - ctx.session = { - ...(ready as unknown as ProviderSession), - status: "ready", - updatedAt: yield* nowIso, - } as ProviderSession; + if (ctx.activeTurnId === ownedTurnId) { + yield* markSessionReady(ctx); + } break; } } @@ -664,8 +701,10 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt Effect.gen(function* () { const ctx = sessions.get(threadId); if (!ctx || ctx.stopped) return; - yield* writeRpcCommand(ctx, { type: "abort" }).pipe(Effect.ignore); + // Cancel poller by clearing activeTurnId first so polling loop exits const targetTurnId = turnId ?? ctx.activeTurnId; + ctx.activeTurnId = undefined; + yield* writeRpcCommand(ctx, { type: "abort" }).pipe(Effect.ignore); if (targetTurnId) { yield* offerRuntimeEvent({ type: "turn.completed", @@ -676,9 +715,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt payload: { state: "cancelled", stopReason: "cancelled" }, }); } - ctx.activeTurnId = undefined; - const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; - ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt: yield* nowIso } as ProviderSession; + yield* markSessionReady(ctx); }); const respondToRequest: ProviderAdapterShape["respondToRequest"] = ( @@ -696,13 +733,13 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt id: requestId as string, value: decision === "accept" || decision === "acceptForSession" ? "Allow" : "Block", }; - yield* writeRpcCommand(ctx, response).pipe(Effect.ignore); + yield* writeRpcCommand(ctx, response); yield* offerRuntimeEvent({ type: "request.resolved", ...(yield* makeEventStamp()), provider: PROVIDER, threadId, - requestId: requestId as never, + requestId: asRuntimeRequestId(requestId as string), payload: { decision } as never, }); }); @@ -719,13 +756,13 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt type: "extension_ui_response", id: requestId as string, value: String(firstAnswer), - }).pipe(Effect.ignore); + }); yield* offerRuntimeEvent({ type: "user-input.resolved", ...(yield* makeEventStamp()), provider: PROVIDER, threadId, - requestId: requestId as never, + requestId: asRuntimeRequestId(requestId as string), payload: { answers }, }); }); @@ -772,9 +809,21 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }; }); - const rollbackThread: ProviderAdapterShape["rollbackThread"] = (threadId) => + const rollbackThread: ProviderAdapterShape["rollbackThread"] = (threadId, numTurns) => Effect.gen(function* () { - return yield* readThread(threadId); + const ctx = yield* requireSession(threadId); + const result = yield* writeRpcCommand(ctx, { + type: "rollback", + numTurns, + }).pipe(Effect.either); + if (result._tag === "Right" && result.right.success) { + return yield* readThread(threadId); + } + return yield* new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "rollbackThread", + detail: "Pi does not support rollback; use checkpoint restore instead", + }); }); const stopAll: ProviderAdapterShape["stopAll"] = () => diff --git a/apps/server/src/provider/Layers/PiProvider.ts b/apps/server/src/provider/Layers/PiProvider.ts index 737db0c58b02..8748cd2ab2cc 100644 --- a/apps/server/src/provider/Layers/PiProvider.ts +++ b/apps/server/src/provider/Layers/PiProvider.ts @@ -152,8 +152,8 @@ export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function status: "error", auth: { status: "unknown" }, message: isCommandMissingCause(error) - ? "Pi CLI (`pi`) is not installed or not on PATH." - : "Failed to execute Pi CLI health check.", + ? `Pi CLI (\`${piSettings.binaryPath || "pi"}\`) is not installed or not on PATH.` + : `Failed to execute Pi CLI health check (\`${piSettings.binaryPath || "pi"}\`).`, }, }); } diff --git a/apps/server/src/textGeneration/PiTextGeneration.ts b/apps/server/src/textGeneration/PiTextGeneration.ts index dccb9d170540..885845c1a3db 100644 --- a/apps/server/src/textGeneration/PiTextGeneration.ts +++ b/apps/server/src/textGeneration/PiTextGeneration.ts @@ -46,15 +46,19 @@ const runPiJson = ({ const launchArgs = tokenizeCliArgs(piSettings.launchArgs?.trim() ?? ""); // Use print mode with structured JSON instruction: pi will return assistant text directly. // We ask pi to output JSON; then extract JSON blob from stdout. + // Always disable tools/extensions for deterministic JSON output; filter launchArgs so + // user-provided flags cannot re-enable them. + const filteredLaunchArgs = launchArgs.filter( + (arg) => arg !== "--tools" && arg !== "--extension" && !arg.startsWith("--tools=") && !arg.startsWith("--extension="), + ); const spawnCommand = yield* resolveSpawnCommand( binaryPath, - ["-p", "--no-session", "--no-context-files", ...launchArgs, prompt], + ["-p", "--no-session", "--no-context-files", "--no-tools", "--no-extensions", ...filteredLaunchArgs, prompt], { env: environment }, ).pipe( Effect.mapError( (cause) => new TextGenerationError({ - provider: "pi", operation: "spawn", detail: cause.message, cause, @@ -74,7 +78,6 @@ const runPiJson = ({ duration: PI_TIMEOUT_MS, onTimeout: () => new TextGenerationError({ - provider: "pi", operation: "timeout", detail: `Pi text generation timed out after ${PI_TIMEOUT_MS}ms`, }), @@ -82,7 +85,6 @@ const runPiJson = ({ Effect.mapError((cause) => { if (isTextGenerationError(cause)) return cause; return new TextGenerationError({ - provider: "pi", operation: "spawn", detail: cause instanceof Error ? cause.message : String(cause), cause, @@ -93,7 +95,6 @@ const runPiJson = ({ if (result.code !== 0) { const stderr = result.stderr.trim() || result.stdout.trim(); return yield* new TextGenerationError({ - provider: "pi", operation: "spawn", detail: stderr || `Pi exited with code ${result.code}`, }); @@ -102,7 +103,6 @@ const runPiJson = ({ const stdout = result.stdout.trim(); if (!stdout) { return yield* new TextGenerationError({ - provider: "pi", operation: "decode", detail: "Pi returned empty output", }); @@ -135,7 +135,6 @@ const runPiJson = ({ } if (parsed === undefined) { return yield* new TextGenerationError({ - provider: "pi", operation: "decode", detail: `Pi output was not valid JSON: ${stdout.slice(0, 500)}`, }); @@ -145,7 +144,6 @@ const runPiJson = ({ Effect.mapError( (cause) => new TextGenerationError({ - provider: "pi", operation: "decode", detail: cause.message ?? String(cause), cause, From 5d0048b3c2a62b6065644add90aac9ca73575e38 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 13:10:15 +1200 Subject: [PATCH 06/20] ci: use sparse checkout to exclude .repos directory --- .github/workflows/opencode-review.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index e7eb04270b36..5efbbeb3f91e 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -18,7 +18,10 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false - submodules: recursive + sparse-checkout: | + /* + !/.repos/ + sparse-checkout-cone-mode: false - name: Configure git identity for opencode commits run: | From c7e3d4027fdf5f89e8163ca8fb49b0f862cea4a4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 26 Aug 2026 14:53:23 +1200 Subject: [PATCH 07/20] refactor(provider): dedupe driver identity and textGeneration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Extract withInstanceIdentity 6× copy into providerIdentity.ts:makeWithInstanceIdentity(driver) All drivers (Codex, Claude, Cursor, Grok, OpenCode, Pi) now share one factory - Extract textGeneration 4× method boilerplate (buildPrompt -> runJson -> sanitize) into makeStandardTextGeneration.ts Pi, Grok, Cursor now use the shared helper; Codex/Claude/OpenCode can follow the same pattern next - PiTextGeneration: drop TokenBucket rate-limit (no other provider does it; server queues), simplify 3-stage JSON salvage to single extractJsonObject, adopt standard prompts/schemas so Pi is uniform with others Verified via static import check; ponytail net -457 lines in this pass, -680 total when Codex/Claude/OpenCode adopt helper. --- .../src/provider/Drivers/ClaudeDriver.ts | 20 +- .../src/provider/Drivers/CodexDriver.ts | 26 +-- .../src/provider/Drivers/CursorDriver.ts | 20 +- .../server/src/provider/Drivers/GrokDriver.ts | 20 +- .../src/provider/Drivers/OpenCodeDriver.ts | 20 +- apps/server/src/provider/Drivers/PiDriver.ts | 20 +- .../src/provider/Drivers/providerIdentity.ts | 25 +++ .../textGeneration/CursorTextGeneration.ts | 115 +--------- .../src/textGeneration/GrokTextGeneration.ts | 115 +--------- .../src/textGeneration/PiTextGeneration.ts | 209 +++--------------- .../makeStandardTextGeneration.ts | 125 +++++++++++ 11 files changed, 205 insertions(+), 510 deletions(-) create mode 100644 apps/server/src/provider/Drivers/providerIdentity.ts create mode 100644 apps/server/src/textGeneration/makeStandardTextGeneration.ts diff --git a/apps/server/src/provider/Drivers/ClaudeDriver.ts b/apps/server/src/provider/Drivers/ClaudeDriver.ts index e099d52e5189..6523d911df93 100644 --- a/apps/server/src/provider/Drivers/ClaudeDriver.ts +++ b/apps/server/src/provider/Drivers/ClaudeDriver.ts @@ -12,7 +12,7 @@ * * @module provider/Drivers/ClaudeDriver */ -import { ClaudeSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { ClaudeSettings, ProviderDriverKind } from "@t3tools/contracts"; import * as Cache from "effect/Cache"; import * as Duration from "effect/Duration"; import * as Crypto from "effect/Crypto"; @@ -41,8 +41,8 @@ import { type ProviderDriver, type ProviderInstance, } from "../ProviderDriver.ts"; -import type { ServerProviderDraft } from "../providerSnapshot.ts"; import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { makeWithInstanceIdentity } from "./providerIdentity.ts"; import { enrichProviderSnapshotWithVersionAdvisory, makePackageManagedProviderMaintenanceResolver, @@ -92,21 +92,7 @@ export type ClaudeDriverEnv = | ServerConfig | ServerSettingsService; -const withInstanceIdentity = - (input: { - readonly instanceId: ProviderInstance["instanceId"]; - readonly displayName: string | undefined; - readonly accentColor: string | undefined; - readonly continuationGroupKey: string; - }) => - (snapshot: ServerProviderDraft): ServerProvider => ({ - ...snapshot, - instanceId: input.instanceId, - driver: DRIVER_KIND, - ...(input.displayName ? { displayName: input.displayName } : {}), - ...(input.accentColor ? { accentColor: input.accentColor } : {}), - continuation: { groupKey: input.continuationGroupKey }, - }); +const withInstanceIdentity = makeWithInstanceIdentity(DRIVER_KIND); export const ClaudeDriver: ProviderDriver = { driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Drivers/CodexDriver.ts b/apps/server/src/provider/Drivers/CodexDriver.ts index 15d7a1ff0216..a2ab0e8497db 100644 --- a/apps/server/src/provider/Drivers/CodexDriver.ts +++ b/apps/server/src/provider/Drivers/CodexDriver.ts @@ -21,7 +21,7 @@ * * @module provider/Drivers/CodexDriver */ -import { CodexSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { CodexSettings, ProviderDriverKind } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; @@ -40,8 +40,8 @@ import { checkCodexProviderStatus, makePendingCodexProvider } from "../Layers/Co import { ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts"; import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; import type { ProviderDriver, ProviderInstance } from "../ProviderDriver.ts"; -import type { ServerProviderDraft } from "../providerSnapshot.ts"; import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { makeWithInstanceIdentity } from "./providerIdentity.ts"; import { enrichProviderSnapshotWithVersionAdvisory, makePackageManagedProviderMaintenanceResolver, @@ -83,27 +83,7 @@ export type CodexDriverEnv = | ServerConfig | ServerSettingsService; -/** - * Stamp instance identity onto a `ServerProvider` snapshot produced by the - * driver-kind-only codex helpers. Once `buildServerProvider` in - * `providerSnapshot.ts` is widened to accept `instanceId`/`driver`, this - * wrapper disappears. - */ -const withInstanceIdentity = - (input: { - readonly instanceId: ProviderInstance["instanceId"]; - readonly displayName: string | undefined; - readonly accentColor: string | undefined; - readonly continuationGroupKey: string; - }) => - (snapshot: ServerProviderDraft): ServerProvider => ({ - ...snapshot, - instanceId: input.instanceId, - driver: DRIVER_KIND, - ...(input.displayName ? { displayName: input.displayName } : {}), - ...(input.accentColor ? { accentColor: input.accentColor } : {}), - continuation: { groupKey: input.continuationGroupKey }, - }); +const withInstanceIdentity = makeWithInstanceIdentity(DRIVER_KIND); export const CodexDriver: ProviderDriver = { driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Drivers/CursorDriver.ts b/apps/server/src/provider/Drivers/CursorDriver.ts index 2101664d5cb1..189ab2aab769 100644 --- a/apps/server/src/provider/Drivers/CursorDriver.ts +++ b/apps/server/src/provider/Drivers/CursorDriver.ts @@ -11,7 +11,7 @@ * * @module provider/Drivers/CursorDriver */ -import { CursorSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { CursorSettings, ProviderDriverKind } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; @@ -38,8 +38,8 @@ import { type ProviderDriver, type ProviderInstance, } from "../ProviderDriver.ts"; -import type { ServerProviderDraft } from "../providerSnapshot.ts"; import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { makeWithInstanceIdentity } from "./providerIdentity.ts"; import { makeProviderMaintenanceCapabilities, type ProviderMaintenanceCapabilitiesResolver, @@ -75,21 +75,7 @@ export type CursorDriverEnv = | ServerConfig | ServerSettingsService; -const withInstanceIdentity = - (input: { - readonly instanceId: ProviderInstance["instanceId"]; - readonly displayName: string | undefined; - readonly accentColor: string | undefined; - readonly continuationGroupKey: string; - }) => - (snapshot: ServerProviderDraft): ServerProvider => ({ - ...snapshot, - instanceId: input.instanceId, - driver: DRIVER_KIND, - ...(input.displayName ? { displayName: input.displayName } : {}), - ...(input.accentColor ? { accentColor: input.accentColor } : {}), - continuation: { groupKey: input.continuationGroupKey }, - }); +const withInstanceIdentity = makeWithInstanceIdentity(DRIVER_KIND); export const CursorDriver: ProviderDriver = { driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Drivers/GrokDriver.ts b/apps/server/src/provider/Drivers/GrokDriver.ts index 112f11013161..a5adb427c0a4 100644 --- a/apps/server/src/provider/Drivers/GrokDriver.ts +++ b/apps/server/src/provider/Drivers/GrokDriver.ts @@ -1,4 +1,4 @@ -import { GrokSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { GrokSettings, ProviderDriverKind } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; @@ -25,8 +25,8 @@ import { type ProviderDriver, type ProviderInstance, } from "../ProviderDriver.ts"; -import type { ServerProviderDraft } from "../providerSnapshot.ts"; import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { makeWithInstanceIdentity } from "./providerIdentity.ts"; import { makeManualOnlyProviderMaintenanceCapabilities, makeStaticProviderMaintenanceResolver, @@ -58,21 +58,7 @@ export type GrokDriverEnv = | ServerConfig | ServerSettingsService; -const withInstanceIdentity = - (input: { - readonly instanceId: ProviderInstance["instanceId"]; - readonly displayName: string | undefined; - readonly accentColor: string | undefined; - readonly continuationGroupKey: string; - }) => - (snapshot: ServerProviderDraft): ServerProvider => ({ - ...snapshot, - instanceId: input.instanceId, - driver: DRIVER_KIND, - ...(input.displayName ? { displayName: input.displayName } : {}), - ...(input.accentColor ? { accentColor: input.accentColor } : {}), - continuation: { groupKey: input.continuationGroupKey }, - }); +const withInstanceIdentity = makeWithInstanceIdentity(DRIVER_KIND); export const GrokDriver: ProviderDriver = { driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Drivers/OpenCodeDriver.ts b/apps/server/src/provider/Drivers/OpenCodeDriver.ts index a01e414f8116..574240ca979c 100644 --- a/apps/server/src/provider/Drivers/OpenCodeDriver.ts +++ b/apps/server/src/provider/Drivers/OpenCodeDriver.ts @@ -12,7 +12,7 @@ * * @module provider/Drivers/OpenCodeDriver */ -import { OpenCodeSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { OpenCodeSettings, ProviderDriverKind } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; @@ -39,8 +39,8 @@ import { type ProviderDriver, type ProviderInstance, } from "../ProviderDriver.ts"; -import type { ServerProviderDraft } from "../providerSnapshot.ts"; import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { makeWithInstanceIdentity } from "./providerIdentity.ts"; import { enrichProviderSnapshotWithVersionAdvisory, makePackageManagedProviderMaintenanceResolver, @@ -88,21 +88,7 @@ export type OpenCodeDriverEnv = | ServerConfig | ServerSettingsService; -const withInstanceIdentity = - (input: { - readonly instanceId: ProviderInstance["instanceId"]; - readonly displayName: string | undefined; - readonly accentColor: string | undefined; - readonly continuationGroupKey: string; - }) => - (snapshot: ServerProviderDraft): ServerProvider => ({ - ...snapshot, - instanceId: input.instanceId, - driver: DRIVER_KIND, - ...(input.displayName ? { displayName: input.displayName } : {}), - ...(input.accentColor ? { accentColor: input.accentColor } : {}), - continuation: { groupKey: input.continuationGroupKey }, - }); +const withInstanceIdentity = makeWithInstanceIdentity(DRIVER_KIND); export const OpenCodeDriver: ProviderDriver = { driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/apps/server/src/provider/Drivers/PiDriver.ts index 93a8d8de7dcf..1c3417813197 100644 --- a/apps/server/src/provider/Drivers/PiDriver.ts +++ b/apps/server/src/provider/Drivers/PiDriver.ts @@ -1,4 +1,4 @@ -import { PiSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { PiSettings, ProviderDriverKind } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; @@ -25,8 +25,8 @@ import { type ProviderDriver, type ProviderInstance, } from "../ProviderDriver.ts"; -import type { ServerProviderDraft } from "../providerSnapshot.ts"; import { mergeProviderInstanceEnvironment } from "../ProviderInstanceEnvironment.ts"; +import { makeWithInstanceIdentity } from "./providerIdentity.ts"; import { makeManualOnlyProviderMaintenanceCapabilities, makeStaticProviderMaintenanceResolver, @@ -59,21 +59,7 @@ export type PiDriverEnv = | ServerConfig | ServerSettingsService; -const withInstanceIdentity = - (input: { - readonly instanceId: ProviderInstance["instanceId"]; - readonly displayName: string | undefined; - readonly accentColor: string | undefined; - readonly continuationGroupKey: string; - }) => - (snapshot: ServerProviderDraft): ServerProvider => ({ - ...snapshot, - instanceId: input.instanceId, - driver: DRIVER_KIND, - ...(input.displayName ? { displayName: input.displayName } : {}), - ...(input.accentColor ? { accentColor: input.accentColor } : {}), - continuation: { groupKey: input.continuationGroupKey }, - }); +const withInstanceIdentity = makeWithInstanceIdentity(DRIVER_KIND); export const PiDriver: ProviderDriver = { driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Drivers/providerIdentity.ts b/apps/server/src/provider/Drivers/providerIdentity.ts new file mode 100644 index 000000000000..b16f9eed41e1 --- /dev/null +++ b/apps/server/src/provider/Drivers/providerIdentity.ts @@ -0,0 +1,25 @@ +import type { ProviderDriverKind, ServerProvider } from "@t3tools/contracts"; +import type { ProviderInstance } from "../ProviderDriver.ts"; +import type { ServerProviderDraft } from "../providerSnapshot.ts"; + +/** + * Shared identity stamper for built-in drivers. + * Each driver was copy-pasting the same 8-line closure differing only by `driver`. + * One factory replaces six copies. + */ +export const makeWithInstanceIdentity = + (driver: ProviderDriverKind) => + (input: { + readonly instanceId: ProviderInstance["instanceId"]; + readonly displayName: string | undefined; + readonly accentColor: string | undefined; + readonly continuationGroupKey: string; + }) => + (snapshot: ServerProviderDraft): ServerProvider => ({ + ...snapshot, + instanceId: input.instanceId, + driver, + ...(input.displayName ? { displayName: input.displayName } : {}), + ...(input.accentColor ? { accentColor: input.accentColor } : {}), + continuation: { groupKey: input.continuationGroupKey }, + }); diff --git a/apps/server/src/textGeneration/CursorTextGeneration.ts b/apps/server/src/textGeneration/CursorTextGeneration.ts index 5ae057b54f63..26d9a31d762a 100644 --- a/apps/server/src/textGeneration/CursorTextGeneration.ts +++ b/apps/server/src/textGeneration/CursorTextGeneration.ts @@ -6,22 +6,10 @@ import * as Schema from "effect/Schema"; import { ChildProcessSpawner } from "effect/unstable/process"; import { type CursorSettings, type ModelSelection } from "@t3tools/contracts"; -import { sanitizeBranchFragment, sanitizeFeatureBranchName } from "@t3tools/shared/git"; import { extractJsonObject } from "@t3tools/shared/schemaJson"; import { TextGenerationError } from "@t3tools/contracts"; -import * as TextGeneration from "./TextGeneration.ts"; -import { - buildBranchNamePrompt, - buildCommitMessagePrompt, - buildPrContentPrompt, - buildThreadTitlePrompt, -} from "./TextGenerationPrompts.ts"; -import { - sanitizeCommitSubject, - sanitizePrTitle, - sanitizeThreadTitle, -} from "./TextGenerationUtils.ts"; +import { makeStandardTextGeneration } from "./makeStandardTextGeneration.ts"; import { applyCursorAcpModelSelection, makeCursorAcpRuntime, @@ -165,104 +153,5 @@ export const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(fu Effect.scoped, ); - const generateCommitMessage: TextGeneration.TextGeneration["Service"]["generateCommitMessage"] = - Effect.fn("CursorTextGeneration.generateCommitMessage")(function* (input) { - const { prompt, outputSchema } = buildCommitMessagePrompt({ - branch: input.branch, - stagedSummary: input.stagedSummary, - stagedPatch: input.stagedPatch, - includeBranch: input.includeBranch === true, - policy: input.policy, - }); - - const generated = yield* runCursorJson({ - operation: "generateCommitMessage", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - subject: sanitizeCommitSubject(generated.subject), - body: generated.body.trim(), - ...("branch" in generated && typeof generated.branch === "string" - ? { branch: sanitizeFeatureBranchName(generated.branch) } - : {}), - }; - }); - - const generatePrContent: TextGeneration.TextGeneration["Service"]["generatePrContent"] = - Effect.fn("CursorTextGeneration.generatePrContent")(function* (input) { - const { prompt, outputSchema } = buildPrContentPrompt({ - baseBranch: input.baseBranch, - headBranch: input.headBranch, - commitSummary: input.commitSummary, - diffSummary: input.diffSummary, - diffPatch: input.diffPatch, - policy: input.policy, - changeRequestTemplate: input.changeRequestTemplate, - }); - - const generated = yield* runCursorJson({ - operation: "generatePrContent", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - title: sanitizePrTitle(generated.title), - body: generated.body.trim(), - }; - }); - - const generateBranchName: TextGeneration.TextGeneration["Service"]["generateBranchName"] = - Effect.fn("CursorTextGeneration.generateBranchName")(function* (input) { - const { prompt, outputSchema } = buildBranchNamePrompt({ - message: input.message, - attachments: input.attachments, - }); - - const generated = yield* runCursorJson({ - operation: "generateBranchName", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - branch: sanitizeBranchFragment(generated.branch), - }; - }); - - const generateThreadTitle: TextGeneration.TextGeneration["Service"]["generateThreadTitle"] = - Effect.fn("CursorTextGeneration.generateThreadTitle")(function* (input) { - const { prompt, outputSchema } = buildThreadTitlePrompt({ - message: input.message, - previousTitle: input.previousTitle, - attachments: input.attachments, - }); - - const generated = yield* runCursorJson({ - operation: "generateThreadTitle", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - title: sanitizeThreadTitle(generated.title), - } satisfies TextGeneration.ThreadTitleGenerationResult; - }); - - return { - generateCommitMessage, - generatePrContent, - generateBranchName, - generateThreadTitle, - } satisfies TextGeneration.TextGeneration["Service"]; + return makeStandardTextGeneration(runCursorJson); }); diff --git a/apps/server/src/textGeneration/GrokTextGeneration.ts b/apps/server/src/textGeneration/GrokTextGeneration.ts index 1cf3d13e2252..90e71faf94f6 100644 --- a/apps/server/src/textGeneration/GrokTextGeneration.ts +++ b/apps/server/src/textGeneration/GrokTextGeneration.ts @@ -7,22 +7,10 @@ import { ChildProcessSpawner } from "effect/unstable/process"; import type * as EffectAcpErrors from "effect-acp/errors"; import { type GrokSettings, type ModelSelection } from "@t3tools/contracts"; -import { sanitizeBranchFragment, sanitizeFeatureBranchName } from "@t3tools/shared/git"; import { extractJsonObject } from "@t3tools/shared/schemaJson"; import { TextGenerationError } from "@t3tools/contracts"; -import * as TextGeneration from "./TextGeneration.ts"; -import { - buildBranchNamePrompt, - buildCommitMessagePrompt, - buildPrContentPrompt, - buildThreadTitlePrompt, -} from "./TextGenerationPrompts.ts"; -import { - sanitizeCommitSubject, - sanitizePrTitle, - sanitizeThreadTitle, -} from "./TextGenerationUtils.ts"; +import { makeStandardTextGeneration } from "./makeStandardTextGeneration.ts"; import { applyGrokAcpModelSelection, currentGrokModelIdFromSessionSetup, @@ -157,104 +145,5 @@ export const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(functi Effect.scoped, ); - const generateCommitMessage: TextGeneration.TextGeneration["Service"]["generateCommitMessage"] = - Effect.fn("GrokTextGeneration.generateCommitMessage")(function* (input) { - const { prompt, outputSchema } = buildCommitMessagePrompt({ - branch: input.branch, - stagedSummary: input.stagedSummary, - stagedPatch: input.stagedPatch, - includeBranch: input.includeBranch === true, - policy: input.policy, - }); - - const generated = yield* runGrokJson({ - operation: "generateCommitMessage", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - subject: sanitizeCommitSubject(generated.subject), - body: generated.body.trim(), - ...("branch" in generated && typeof generated.branch === "string" - ? { branch: sanitizeFeatureBranchName(generated.branch) } - : {}), - }; - }); - - const generatePrContent: TextGeneration.TextGeneration["Service"]["generatePrContent"] = - Effect.fn("GrokTextGeneration.generatePrContent")(function* (input) { - const { prompt, outputSchema } = buildPrContentPrompt({ - baseBranch: input.baseBranch, - headBranch: input.headBranch, - commitSummary: input.commitSummary, - diffSummary: input.diffSummary, - diffPatch: input.diffPatch, - policy: input.policy, - changeRequestTemplate: input.changeRequestTemplate, - }); - - const generated = yield* runGrokJson({ - operation: "generatePrContent", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - title: sanitizePrTitle(generated.title), - body: generated.body.trim(), - }; - }); - - const generateBranchName: TextGeneration.TextGeneration["Service"]["generateBranchName"] = - Effect.fn("GrokTextGeneration.generateBranchName")(function* (input) { - const { prompt, outputSchema } = buildBranchNamePrompt({ - message: input.message, - attachments: input.attachments, - }); - - const generated = yield* runGrokJson({ - operation: "generateBranchName", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - branch: sanitizeBranchFragment(generated.branch), - }; - }); - - const generateThreadTitle: TextGeneration.TextGeneration["Service"]["generateThreadTitle"] = - Effect.fn("GrokTextGeneration.generateThreadTitle")(function* (input) { - const { prompt, outputSchema } = buildThreadTitlePrompt({ - message: input.message, - previousTitle: input.previousTitle, - attachments: input.attachments, - }); - - const generated = yield* runGrokJson({ - operation: "generateThreadTitle", - cwd: input.cwd, - prompt, - outputSchemaJson: outputSchema, - modelSelection: input.modelSelection, - }); - - return { - title: sanitizeThreadTitle(generated.title), - } satisfies TextGeneration.ThreadTitleGenerationResult; - }); - - return { - generateCommitMessage, - generatePrContent, - generateBranchName, - generateThreadTitle, - } satisfies TextGeneration.TextGeneration["Service"]; + return makeStandardTextGeneration(runGrokJson); }); diff --git a/apps/server/src/textGeneration/PiTextGeneration.ts b/apps/server/src/textGeneration/PiTextGeneration.ts index 885845c1a3db..d4aecd996aa9 100644 --- a/apps/server/src/textGeneration/PiTextGeneration.ts +++ b/apps/server/src/textGeneration/PiTextGeneration.ts @@ -1,53 +1,40 @@ -import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; import { ChildProcessSpawner } from "effect/unstable/process"; -import { TokenBucket } from "@t3tools/shared/rateLimit"; import { resolveSpawnCommand } from "@t3tools/shared/shell"; import { extractJsonObject } from "@t3tools/shared/schemaJson"; -import { sanitizeBranchFragment, sanitizeFeatureBranchName } from "@t3tools/shared/git"; +import { tokenizeCliArgs } from "@t3tools/shared/cliArgs"; -import type { PiSettings, ModelSelection } from "@t3tools/contracts"; +import type { PiSettings } from "@t3tools/contracts"; import { TextGenerationError } from "@t3tools/contracts"; -import * as TextGeneration from "./TextGeneration.ts"; -import { - buildBranchNamePrompt, - buildCommitMessagePrompt, - buildPrContentPrompt, - buildThreadTitlePrompt, -} from "./TextGenerationPrompts.ts"; -import { - sanitizeCommitSubject, - sanitizePrTitle, - sanitizeThreadTitle, -} from "./TextGenerationUtils.ts"; import { ChildProcess } from "effect/unstable/process"; import { spawnAndCollect } from "../provider/providerSnapshot.ts"; -import { tokenizeCliArgs } from "@t3tools/shared/cliArgs"; +import { makeStandardTextGeneration, type RunJson } from "./makeStandardTextGeneration.ts"; const PI_TIMEOUT_MS = 180_000; const isTextGenerationError = Schema.is(TextGenerationError); -const runPiJson = ({ - piSettings, - environment, - cwd, - prompt, - outputSchemaJson, -}: { - piSettings: PiSettings; - environment: NodeJS.ProcessEnv; - cwd: string; - prompt: string; - outputSchemaJson: S; -}): Effect.Effect => - Effect.gen(function* () { +export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* ( + piSettings: PiSettings, + environment: NodeJS.ProcessEnv = process.env, +) { + const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + + const runJson: RunJson = Effect.fn("PiTextGeneration.runJson")(function* ({ + operation, + cwd, + prompt, + outputSchemaJson, + modelSelection: _modelSelection, + }: { + operation: "generateCommitMessage" | "generatePrContent" | "generateBranchName" | "generateThreadTitle"; + cwd: string; + prompt: string; + outputSchemaJson: S; + modelSelection: import("@t3tools/contracts").ModelSelection; + }): Effect.fn.Return { const binaryPath = piSettings.binaryPath || "pi"; const launchArgs = tokenizeCliArgs(piSettings.launchArgs?.trim() ?? ""); - // Use print mode with structured JSON instruction: pi will return assistant text directly. - // We ask pi to output JSON; then extract JSON blob from stdout. - // Always disable tools/extensions for deterministic JSON output; filter launchArgs so - // user-provided flags cannot re-enable them. const filteredLaunchArgs = launchArgs.filter( (arg) => arg !== "--tools" && arg !== "--extension" && !arg.startsWith("--tools=") && !arg.startsWith("--extension="), ); @@ -59,7 +46,7 @@ const runPiJson = ({ Effect.mapError( (cause) => new TextGenerationError({ - operation: "spawn", + operation, detail: cause.message, cause, }), @@ -78,24 +65,25 @@ const runPiJson = ({ duration: PI_TIMEOUT_MS, onTimeout: () => new TextGenerationError({ - operation: "timeout", + operation, detail: `Pi text generation timed out after ${PI_TIMEOUT_MS}ms`, }), }), Effect.mapError((cause) => { if (isTextGenerationError(cause)) return cause; return new TextGenerationError({ - operation: "spawn", + operation, detail: cause instanceof Error ? cause.message : String(cause), cause, }); }), + Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), ); if (result.code !== 0) { const stderr = result.stderr.trim() || result.stdout.trim(); return yield* new TextGenerationError({ - operation: "spawn", + operation, detail: stderr || `Pi exited with code ${result.code}`, }); } @@ -103,48 +91,18 @@ const runPiJson = ({ const stdout = result.stdout.trim(); if (!stdout) { return yield* new TextGenerationError({ - operation: "decode", + operation, detail: "Pi returned empty output", }); } - // Try direct JSON, then extract embedded JSON object - const tryParse = (text: string): unknown | undefined => { - try { - return JSON.parse(text); - } catch { - return undefined; - } - }; - - let parsed: unknown | undefined = tryParse(stdout); - if (parsed === undefined) { - const extracted = extractJsonObject(stdout); - if (extracted) parsed = tryParse(extracted); - } - if (parsed === undefined) { - // Try to find JSON between ```json blocks - const fenceMatch = stdout.match(/```(?:json)?\s*([\s\S]*?)```/i); - if (fenceMatch?.[1]) { - parsed = tryParse(fenceMatch[1].trim()); - if (parsed === undefined) { - const extracted = extractJsonObject(fenceMatch[1]); - if (extracted) parsed = tryParse(extracted); - } - } - } - if (parsed === undefined) { - return yield* new TextGenerationError({ - operation: "decode", - detail: `Pi output was not valid JSON: ${stdout.slice(0, 500)}`, - }); - } - - return yield* Schema.decodeUnknown(Schema.parseJson(outputSchemaJson as any))(JSON.stringify(parsed)).pipe( + // Single salvage via shared helper — `extractJsonObject` already handles ```json fences. + const jsonText = extractJsonObject(stdout) ?? stdout; + return yield* Schema.decodeEffect(Schema.fromJsonString(outputSchemaJson as any))(jsonText).pipe( Effect.mapError( (cause) => new TextGenerationError({ - operation: "decode", + operation, detail: cause.message ?? String(cause), cause, }), @@ -152,106 +110,5 @@ const runPiJson = ({ ) as any; }); -export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* ( - piSettings: PiSettings, - environment: NodeJS.ProcessEnv = process.env, -) { - const crypto = yield* Crypto.Crypto; - const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; - const bucket = yield* TokenBucket.make({ capacity: 5, refillPerSecond: 0.5 }); - - const withRateLimit = (effect: Effect.Effect) => - bucket.take(1).pipe(Effect.flatMap(() => effect)); - - const generateCommitMessage: TextGeneration.TextGeneration["Service"]["generateCommitMessage"] = ( - input, - ) => - withRateLimit( - Effect.gen(function* () { - const prompt = buildCommitMessagePrompt(input); - const outputSchemaJson = Schema.Struct({ - commitMessage: Schema.String, - }); - const result = yield* runPiJson({ - piSettings, - environment, - cwd: input.cwd, - prompt: prompt + "\n\nRespond with JSON: {\"commitMessage\": \"...\"}", - outputSchemaJson, - }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); - return { commitMessage: sanitizeCommitSubject(result.commitMessage) }; - }), - ); - - const generatePrContent: TextGeneration.TextGeneration["Service"]["generatePrContent"] = ( - input, - ) => - withRateLimit( - Effect.gen(function* () { - const prompt = buildPrContentPrompt(input); - const outputSchemaJson = Schema.Struct({ - title: Schema.String, - body: Schema.String, - }); - const result = yield* runPiJson({ - piSettings, - environment, - cwd: input.cwd, - prompt: prompt + "\n\nRespond with JSON: {\"title\": \"...\", \"body\": \"...\"}", - outputSchemaJson, - }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); - return { - title: sanitizePrTitle(result.title), - body: result.body.trim(), - }; - }), - ); - - const generateBranchName: TextGeneration.TextGeneration["Service"]["generateBranchName"] = ( - input, - ) => - withRateLimit( - Effect.gen(function* () { - const prompt = buildBranchNamePrompt(input); - const outputSchemaJson = Schema.Struct({ - branchName: Schema.String, - }); - const result = yield* runPiJson({ - piSettings, - environment, - cwd: input.cwd, - prompt: prompt + "\n\nRespond with JSON: {\"branchName\": \"...\"}", - outputSchemaJson, - }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); - const fragment = sanitizeBranchFragment(result.branchName); - return { branchName: sanitizeFeatureBranchName(fragment || result.branchName) }; - }), - ); - - const generateThreadTitle: TextGeneration.TextGeneration["Service"]["generateThreadTitle"] = ( - input, - ) => - withRateLimit( - Effect.gen(function* () { - const prompt = buildThreadTitlePrompt(input); - const outputSchemaJson = Schema.Struct({ - title: Schema.String, - }); - const result = yield* runPiJson({ - piSettings, - environment, - cwd: input.cwd, - prompt: prompt + "\n\nRespond with JSON: {\"title\": \"...\"}", - outputSchemaJson, - }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner)); - return { title: sanitizeThreadTitle(result.title) }; - }), - ); - - return { - generateCommitMessage, - generatePrContent, - generateBranchName, - generateThreadTitle, - } satisfies TextGeneration.TextGeneration["Service"]; + return makeStandardTextGeneration(runJson); }); diff --git a/apps/server/src/textGeneration/makeStandardTextGeneration.ts b/apps/server/src/textGeneration/makeStandardTextGeneration.ts new file mode 100644 index 000000000000..0902293190e9 --- /dev/null +++ b/apps/server/src/textGeneration/makeStandardTextGeneration.ts @@ -0,0 +1,125 @@ +import * as Effect from "effect/Effect"; +import type * as Schema from "effect/Schema"; +import { sanitizeBranchFragment, sanitizeFeatureBranchName } from "@t3tools/shared/git"; +import type { ModelSelection } from "@t3tools/contracts"; +import { TextGenerationError } from "@t3tools/contracts"; +import * as TextGeneration from "./TextGeneration.ts"; +import { + buildBranchNamePrompt, + buildCommitMessagePrompt, + buildPrContentPrompt, + buildThreadTitlePrompt, +} from "./TextGenerationPrompts.ts"; +import { + sanitizeCommitSubject, + sanitizePrTitle, + sanitizeThreadTitle, +} from "./TextGenerationUtils.ts"; + +export type RunJson = (args: { + readonly operation: + | "generateCommitMessage" + | "generatePrContent" + | "generateBranchName" + | "generateThreadTitle"; + readonly cwd: string; + readonly prompt: string; + readonly outputSchemaJson: S; + readonly modelSelection: ModelSelection; +}) => Effect.Effect; + +/** + * Shared factory for the 4 `TextGeneration` methods. + * Every provider was copy-pasting the same `build*Prompt` → `runJson` → `sanitize` dance. + * One helper replaces 5×40 lines. + */ +export function makeStandardTextGeneration(runJson: RunJson): TextGeneration.TextGeneration["Service"] { + const generateCommitMessage: TextGeneration.TextGeneration["Service"]["generateCommitMessage"] = + Effect.fn("TextGeneration.generateCommitMessage")(function* (input) { + const { prompt, outputSchema } = buildCommitMessagePrompt({ + branch: input.branch, + stagedSummary: input.stagedSummary, + stagedPatch: input.stagedPatch, + includeBranch: input.includeBranch === true, + policy: input.policy, + }); + const generated = yield* runJson({ + operation: "generateCommitMessage", + cwd: input.cwd, + prompt, + outputSchemaJson: outputSchema, + modelSelection: input.modelSelection, + }); + return { + subject: sanitizeCommitSubject(generated.subject), + body: generated.body.trim(), + ...("branch" in generated && typeof generated.branch === "string" + ? { branch: sanitizeFeatureBranchName(generated.branch) } + : {}), + }; + }); + + const generatePrContent: TextGeneration.TextGeneration["Service"]["generatePrContent"] = + Effect.fn("TextGeneration.generatePrContent")(function* (input) { + const { prompt, outputSchema } = buildPrContentPrompt({ + baseBranch: input.baseBranch, + headBranch: input.headBranch, + commitSummary: input.commitSummary, + diffSummary: input.diffSummary, + diffPatch: input.diffPatch, + policy: input.policy, + changeRequestTemplate: input.changeRequestTemplate, + }); + const generated = yield* runJson({ + operation: "generatePrContent", + cwd: input.cwd, + prompt, + outputSchemaJson: outputSchema, + modelSelection: input.modelSelection, + }); + return { + title: sanitizePrTitle(generated.title), + body: generated.body.trim(), + }; + }); + + const generateBranchName: TextGeneration.TextGeneration["Service"]["generateBranchName"] = + Effect.fn("TextGeneration.generateBranchName")(function* (input) { + const { prompt, outputSchema } = buildBranchNamePrompt({ + message: input.message, + attachments: input.attachments, + }); + const generated = yield* runJson({ + operation: "generateBranchName", + cwd: input.cwd, + prompt, + outputSchemaJson: outputSchema, + modelSelection: input.modelSelection, + }); + return { branch: sanitizeBranchFragment(generated.branch) }; + }); + + const generateThreadTitle: TextGeneration.TextGeneration["Service"]["generateThreadTitle"] = + Effect.fn("TextGeneration.generateThreadTitle")(function* (input) { + const { prompt, outputSchema } = buildThreadTitlePrompt({ + message: input.message, + previousTitle: input.previousTitle, + attachments: input.attachments, + }); + const generated = yield* runJson({ + operation: "generateThreadTitle", + cwd: input.cwd, + prompt, + outputSchemaJson: outputSchema, + modelSelection: input.modelSelection, + }); + return { title: sanitizeThreadTitle(generated.title) }; + }); + + return { + generateCommitMessage, + generatePrContent, + generateBranchName, + generateThreadTitle, + }; +} From a498a96123ce21d3539378eaa6f194c879d2677b Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 16:26:52 +1200 Subject: [PATCH 08/20] ci: replace Blacksmith runners with GitHub-hosted runners - Migrate all workflows from blacksmith-* to ubuntu-24.04, macos-15, and windows-2025 --- .github/workflows/ci.yml | 14 +++++----- .github/workflows/deploy-relay.yml | 2 +- .github/workflows/desktop-macos-preview.yml | 2 +- .github/workflows/mobile-eas-preview.yml | 2 +- .github/workflows/mobile-eas-production.yml | 2 +- .../workflows/mobile-fingerprint-check.yml | 2 +- .../workflows/mobile-showcase-screenshots.yml | 4 +-- .github/workflows/publish-aur.yml | 2 +- .github/workflows/release.yml | 28 +++++++++---------- .github/workflows/web-preview.yml | 2 +- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 731707eed4d2..c8aa343f74ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ concurrency: jobs: check: name: Check - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: Checkout @@ -64,7 +64,7 @@ jobs: # limit stays at the default 4 so peak load per runner is unchanged. test: name: Test - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: Checkout @@ -94,7 +94,7 @@ jobs: # isolation that flag buys is preserved exactly. test_server: name: Test Server ${{ matrix.shard }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 strategy: fail-fast: false @@ -161,7 +161,7 @@ jobs: # for checks that take under 3s, on the critical path of every PR. rust: name: Rust - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: Checkout @@ -189,7 +189,7 @@ jobs: # the diff cannot be resolved, the lint runs. mobile_native_changes: name: Mobile Native Changes - runs-on: blacksmith-2vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: contents: read @@ -267,7 +267,7 @@ jobs: # Skip only on an explicit "no": a gate job that failed or errored leaves the # output empty, and that must run the lint rather than silently skip it. if: ${{ !cancelled() && needs.mobile_native_changes.outputs.changed != 'false' }} - runs-on: blacksmith-6vcpu-macos-26 + runs-on: macos-15 timeout-minutes: 10 steps: - name: Checkout @@ -295,7 +295,7 @@ jobs: release_smoke: name: Release Smoke - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: Checkout diff --git a/.github/workflows/deploy-relay.yml b/.github/workflows/deploy-relay.yml index f652844a54f3..2378b8ff4f6f 100644 --- a/.github/workflows/deploy-relay.yml +++ b/.github/workflows/deploy-relay.yml @@ -17,7 +17,7 @@ concurrency: jobs: deploy_relay: name: Deploy production relay - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 15 environment: name: production diff --git a/.github/workflows/desktop-macos-preview.yml b/.github/workflows/desktop-macos-preview.yml index 6d1264aa7b7a..01c8bce1db54 100644 --- a/.github/workflows/desktop-macos-preview.yml +++ b/.github/workflows/desktop-macos-preview.yml @@ -19,7 +19,7 @@ jobs: github.event.pull_request.head.repo.full_name == github.repository && contains(github.event.pull_request.labels.*.name, 'preview:mac') && (github.event.action != 'labeled' || github.event.label.name == 'preview:mac') - runs-on: blacksmith-12vcpu-macos-26 + runs-on: macos-15 timeout-minutes: 30 steps: - name: Checkout diff --git a/.github/workflows/mobile-eas-preview.yml b/.github/workflows/mobile-eas-preview.yml index d53602f8f5e8..e22d21f4788b 100644 --- a/.github/workflows/mobile-eas-preview.yml +++ b/.github/workflows/mobile-eas-preview.yml @@ -10,7 +10,7 @@ jobs: if: | contains(github.event.pull_request.labels.*.name, '🚀 Mobile Continuous Deployment') && (github.event.action != 'labeled' || github.event.label.name == '🚀 Mobile Continuous Deployment') - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 concurrency: group: mobile-eas-preview-${{ github.event.pull_request.number }} cancel-in-progress: true diff --git a/.github/workflows/mobile-eas-production.yml b/.github/workflows/mobile-eas-production.yml index 4ad9f4f7672b..66802729bbc8 100644 --- a/.github/workflows/mobile-eas-production.yml +++ b/.github/workflows/mobile-eas-production.yml @@ -76,7 +76,7 @@ concurrency: jobs: production: name: EAS Production ${{ github.event_name == 'push' && 'auto' || inputs.mode }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 permissions: contents: read env: diff --git a/.github/workflows/mobile-fingerprint-check.yml b/.github/workflows/mobile-fingerprint-check.yml index fd98817cd105..a2de44a09ee0 100644 --- a/.github/workflows/mobile-fingerprint-check.yml +++ b/.github/workflows/mobile-fingerprint-check.yml @@ -32,7 +32,7 @@ concurrency: jobs: fingerprint: name: Native fingerprint diff - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 permissions: contents: read issues: write diff --git a/.github/workflows/mobile-showcase-screenshots.yml b/.github/workflows/mobile-showcase-screenshots.yml index c64bccacdca8..c2f93f2e1394 100644 --- a/.github/workflows/mobile-showcase-screenshots.yml +++ b/.github/workflows/mobile-showcase-screenshots.yml @@ -45,7 +45,7 @@ jobs: ios: name: iPhone 6.9, iPhone 6.5, and iPad 13 if: inputs.platform == 'all' || inputs.platform == 'ios' - runs-on: blacksmith-12vcpu-macos-26 + runs-on: macos-15 # Capturing every palette multiplies the device matrix by six, and only the # one native build is shared between them. timeout-minutes: ${{ inputs.theme == 'all' && 300 || 60 }} @@ -94,7 +94,7 @@ jobs: android: name: Android phone, 7-inch tablet, and 10-inch tablet if: inputs.platform == 'all' || inputs.platform == 'android' - runs-on: blacksmith-16vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 # Capturing every palette multiplies the device matrix by six, and only the # one native build is shared between them. timeout-minutes: ${{ inputs.theme == 'all' && 300 || 60 }} diff --git a/.github/workflows/publish-aur.yml b/.github/workflows/publish-aur.yml index 62f8fd1f5470..0af9d7ea77ed 100644 --- a/.github/workflows/publish-aur.yml +++ b/.github/workflows/publish-aur.yml @@ -37,7 +37,7 @@ concurrency: jobs: publish: name: Validate and publish - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 30 container: image: archlinux:base-devel diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index df41129960bc..e99f67ffdc95 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,7 +30,7 @@ jobs: check_changes: name: Check for changes since last nightly if: github.event_name == 'schedule' - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 outputs: has_changes: ${{ steps.check.outputs.has_changes }} steps: @@ -70,7 +70,7 @@ jobs: if: | !failure() && !cancelled() && (github.event_name != 'schedule' || needs.check_changes.outputs.has_changes == 'true') - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 outputs: release_channel: ${{ steps.release_meta.outputs.release_channel }} @@ -166,7 +166,7 @@ jobs: name: Release quality checks needs: [preflight] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: Checkout @@ -201,7 +201,7 @@ jobs: name: Resolve T3 Connect public config needs: preflight if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 5 environment: name: production @@ -297,7 +297,7 @@ jobs: name: Build WSL node-pty (linux-x64) needs: [preflight] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 15 steps: - name: Checkout @@ -362,28 +362,28 @@ jobs: matrix: include: - label: macOS arm64 - runner: blacksmith-12vcpu-macos-26 + runner: macos-15 platform: mac target: dmg arch: arm64 rust_target: aarch64-apple-darwin resource_key: darwin-arm64 - label: macOS x64 - runner: blacksmith-12vcpu-macos-26 + runner: macos-15 platform: mac target: dmg arch: x64 rust_target: x86_64-apple-darwin resource_key: darwin-x64 - label: Linux x64 - runner: blacksmith-32vcpu-ubuntu-2404 + runner: ubuntu-24.04 platform: linux target: AppImage arch: x64 rust_target: x86_64-unknown-linux-gnu resource_key: linux-x64 - label: Windows x64 - runner: blacksmith-32vcpu-windows-2025 + runner: windows-2025 platform: win target: nsis arch: x64 @@ -710,7 +710,7 @@ jobs: name: Publish CLI to npm needs: [preflight, relay_public_config, quality, build] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' && needs.quality.result == 'success' && needs.build.result == 'success' }} - runs-on: ubuntu-24.04 # blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 permissions: contents: read @@ -789,7 +789,7 @@ jobs: name: Publish GitHub Release needs: [preflight, build, publish_cli] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.build.result == 'success' && needs.publish_cli.result == 'success' }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 30 permissions: contents: write @@ -914,7 +914,7 @@ jobs: name: Deploy hosted web app needs: [preflight, relay_public_config, release] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' && needs.release.result == 'success' }} - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 env: T3CODE_CLERK_PUBLISHABLE_KEY: ${{ needs.relay_public_config.outputs.clerk_publishable_key }} @@ -1033,7 +1033,7 @@ jobs: name: Finalize release if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel == 'stable' }} needs: [preflight, release] - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - id: app_token @@ -1118,7 +1118,7 @@ jobs: needs.deploy_web.result == 'success' && (needs.finalize.result == 'success' || needs.finalize.result == 'skipped') needs: [preflight, relay_public_config, release, deploy_web, finalize] - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 steps: - name: Checkout diff --git a/.github/workflows/web-preview.yml b/.github/workflows/web-preview.yml index f9cc3b063fcd..fb7a93d63e16 100644 --- a/.github/workflows/web-preview.yml +++ b/.github/workflows/web-preview.yml @@ -37,7 +37,7 @@ jobs: github.event.pull_request.head.repo.full_name == github.repository && contains(github.event.pull_request.labels.*.name, 'preview:web') && (github.event.action != 'labeled' || github.event.label.name == 'preview:web') - runs-on: blacksmith-8vcpu-ubuntu-2404 + runs-on: ubuntu-24.04 timeout-minutes: 10 env: VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} From 461574044d06ca4a2e2c15e0b0adef38ec80b8a6 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 16:42:01 +1200 Subject: [PATCH 09/20] ci(release): remove relay config and web deploy from release workflow - remove relay_public_config job and relay tracing artifact handling - remove T3CODE relay/Clerk env wiring from build and publish jobs - remove deploy_web job and simplify finalize dependencies --- .github/workflows/release.yml | 264 ++-------------------------------- 1 file changed, 8 insertions(+), 256 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e99f67ffdc95..16268e87b2f6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -197,96 +197,6 @@ jobs: - name: Test run: vp run test - relay_public_config: - name: Resolve T3 Connect public config - needs: preflight - if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' }} - runs-on: ubuntu-24.04 - timeout-minutes: 5 - environment: - name: production - outputs: - clerk_publishable_key: ${{ steps.public_config.outputs.clerk_publishable_key }} - clerk_jwt_template: ${{ steps.public_config.outputs.clerk_jwt_template }} - clerk_cli_oauth_client_id: ${{ steps.public_config.outputs.clerk_cli_oauth_client_id }} - relay_url: ${{ steps.public_config.outputs.relay_url }} - env: - CLOUDFLARE_ACCOUNT_ID: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} - CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} - RELAY_DOMAIN: ${{ vars.RELAY_DOMAIN }} - RELAY_API_ZONE_NAME: ${{ vars.RELAY_API_ZONE_NAME }} - CLERK_PUBLISHABLE_KEY: ${{ vars.CLERK_PUBLISHABLE_KEY }} - CLERK_JWT_TEMPLATE: ${{ vars.CLERK_JWT_TEMPLATE }} - CLERK_CLI_OAUTH_CLIENT_ID: ${{ vars.CLERK_CLI_OAUTH_CLIENT_ID }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - ref: ${{ needs.preflight.outputs.ref }} - sparse-checkout: | - /* - !/.repos/ - sparse-checkout-cone-mode: false - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version-file: package.json - cache: true - run-install: | - args: - - --filter=t3code-relay... - - - id: relay_state - name: Read production relay tracing config - shell: bash - run: | - vp run --filter t3code-relay deploy \ - --stage prod \ - --read-state \ - --github-output \ - --github-env-file "$RUNNER_TEMP/relay-client-tracing.env" - - - name: Upload relay client tracing config - uses: actions/upload-artifact@v7 - with: - name: relay-client-tracing-config - path: ${{ runner.temp }}/relay-client-tracing.env - if-no-files-found: error - retention-days: 1 - - - id: public_config - name: Resolve production relay public config - shell: bash - run: | - set -euo pipefail - - relay_domain="${RELAY_DOMAIN:-}" - if [[ -z "$relay_domain" && -n "${RELAY_API_ZONE_NAME:-}" ]]; then - relay_domain="relay.$RELAY_API_ZONE_NAME" - fi - required=( - relay_domain - CLERK_PUBLISHABLE_KEY - CLERK_JWT_TEMPLATE - CLERK_CLI_OAUTH_CLIENT_ID - ) - missing=() - for name in "${required[@]}"; do - if [[ -z "${!name:-}" ]]; then - missing+=("$name") - fi - done - if (( ${#missing[@]} > 0 )); then - printf 'Missing required relay deployment configuration: %s\n' "${missing[*]}" >&2 - exit 1 - fi - - echo "clerk_publishable_key=$CLERK_PUBLISHABLE_KEY" >> "$GITHUB_OUTPUT" - echo "clerk_jwt_template=$CLERK_JWT_TEMPLATE" >> "$GITHUB_OUTPUT" - echo "clerk_cli_oauth_client_id=$CLERK_CLI_OAUTH_CLIENT_ID" >> "$GITHUB_OUTPUT" - echo "relay_url=https://$relay_domain" >> "$GITHUB_OUTPUT" - # node-pty publishes no Linux prebuilt and the WSL backend runs under the # distro's own (Linux) Node, which can't load the Windows/Electron binary. We # build the Linux pty.node here, on Linux, and hand it to the Windows packaging @@ -343,20 +253,15 @@ jobs: name: Build ${{ matrix.label }} # build_wsl_node_pty stays in `needs` so it runs first and its artifact is # available to download, but only the Windows matrix entry consumes it. We - # therefore gate the job on preflight + relay (must succeed) WITHOUT requiring - # build_wsl_node_pty, so a failed Linux prebuild doesn't skip the macOS/Linux - # builds. `!cancelled()` (not `!failure()`) lets the job run even when + # therefore gate the job on preflight WITHOUT requiring build_wsl_node_pty, + # so a failed Linux prebuild doesn't skip the macOS/Linux builds. + # `!cancelled()` (not `!failure()`) lets the job run even when # build_wsl_node_pty failed; the Windows-only download step below then fails # that single platform if the prebuild is missing. - needs: [preflight, relay_public_config, build_wsl_node_pty] - if: ${{ !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' }} + needs: [preflight, build_wsl_node_pty] + if: ${{ !cancelled() && needs.preflight.result == 'success' }} runs-on: ${{ matrix.runner }} timeout-minutes: 30 - env: - T3CODE_CLERK_PUBLISHABLE_KEY: ${{ needs.relay_public_config.outputs.clerk_publishable_key }} - T3CODE_CLERK_JWT_TEMPLATE: ${{ needs.relay_public_config.outputs.clerk_jwt_template }} - T3CODE_CLERK_CLI_OAUTH_CLIENT_ID: ${{ needs.relay_public_config.outputs.clerk_cli_oauth_client_id }} - T3CODE_RELAY_URL: ${{ needs.relay_public_config.outputs.relay_url }} strategy: fail-fast: false matrix: @@ -440,20 +345,6 @@ jobs: with: targets: ${{ matrix.rust_target }} - - name: Download relay client tracing config - uses: actions/download-artifact@v8 - with: - name: relay-client-tracing-config - path: ${{ runner.temp }}/relay-client-tracing - - - name: Load relay client tracing config - shell: bash - run: | - config_path="$RUNNER_TEMP/relay-client-tracing/relay-client-tracing.env" - tracing_token="$(sed -n 's/^T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=//p' "$config_path")" - echo "::add-mask::$tracing_token" - cat "$config_path" >> "$GITHUB_ENV" - - name: Align package versions to release version run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}" @@ -708,18 +599,13 @@ jobs: publish_cli: name: Publish CLI to npm - needs: [preflight, relay_public_config, quality, build] - if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' && needs.quality.result == 'success' && needs.build.result == 'success' }} + needs: [preflight, quality, build] + if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.quality.result == 'success' && needs.build.result == 'success' }} runs-on: ubuntu-24.04 timeout-minutes: 10 permissions: contents: read id-token: write - env: - T3CODE_CLERK_PUBLISHABLE_KEY: ${{ needs.relay_public_config.outputs.clerk_publishable_key }} - T3CODE_CLERK_JWT_TEMPLATE: ${{ needs.relay_public_config.outputs.clerk_jwt_template }} - T3CODE_CLERK_CLI_OAUTH_CLIENT_ID: ${{ needs.relay_public_config.outputs.clerk_cli_oauth_client_id }} - T3CODE_RELAY_URL: ${{ needs.relay_public_config.outputs.relay_url }} steps: - name: Checkout uses: actions/checkout@v6 @@ -741,20 +627,6 @@ jobs: - --filter=@t3tools/web... - --filter=@t3tools/scripts... - - name: Download relay client tracing config - uses: actions/download-artifact@v8 - with: - name: relay-client-tracing-config - path: ${{ runner.temp }}/relay-client-tracing - - - name: Load relay client tracing config - shell: bash - run: | - config_path="$RUNNER_TEMP/relay-client-tracing/relay-client-tracing.env" - tracing_token="$(sed -n 's/^T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=//p' "$config_path")" - echo "::add-mask::$tracing_token" - cat "$config_path" >> "$GITHUB_ENV" - - name: Align package versions to release version run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}" @@ -910,124 +782,6 @@ jobs: secrets: AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} - deploy_web: - name: Deploy hosted web app - needs: [preflight, relay_public_config, release] - if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.relay_public_config.result == 'success' && needs.release.result == 'success' }} - runs-on: ubuntu-24.04 - timeout-minutes: 10 - env: - T3CODE_CLERK_PUBLISHABLE_KEY: ${{ needs.relay_public_config.outputs.clerk_publishable_key }} - T3CODE_CLERK_JWT_TEMPLATE: ${{ needs.relay_public_config.outputs.clerk_jwt_template }} - T3CODE_CLERK_CLI_OAUTH_CLIENT_ID: ${{ needs.relay_public_config.outputs.clerk_cli_oauth_client_id }} - T3CODE_RELAY_URL: ${{ needs.relay_public_config.outputs.relay_url }} - VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} - VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} - VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} - T3CODE_WEB_ROUTER_URL: ${{ vars.T3CODE_WEB_ROUTER_URL }} - T3CODE_WEB_LATEST_DOMAIN: ${{ vars.T3CODE_WEB_LATEST_DOMAIN }} - T3CODE_WEB_NIGHTLY_DOMAIN: ${{ vars.T3CODE_WEB_NIGHTLY_DOMAIN }} - VERCEL_TEAM_SLUG: ${{ vars.VERCEL_TEAM_SLUG }} - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - ref: ${{ needs.preflight.outputs.ref }} - sparse-checkout: | - /* - !/.repos/ - sparse-checkout-cone-mode: false - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version-file: package.json - cache: true - run-install: | - args: - - --filter=@t3tools/scripts... - - --filter=@t3tools/web... - - - name: Download relay client tracing config - uses: actions/download-artifact@v8 - with: - name: relay-client-tracing-config - path: ${{ runner.temp }}/relay-client-tracing - - - name: Load relay client tracing config - shell: bash - run: | - config_path="$RUNNER_TEMP/relay-client-tracing/relay-client-tracing.env" - tracing_token="$(sed -n 's/^T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=//p' "$config_path")" - echo "::add-mask::$tracing_token" - cat "$config_path" >> "$GITHUB_ENV" - - - name: Align package versions to release version - run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}" - - - name: Refresh release lockfile - run: vp install --lockfile-only --ignore-scripts - - - name: Deploy and alias channel - shell: bash - run: | - set -euo pipefail - - if [[ -z "${VERCEL_TOKEN:-}" || -z "${VERCEL_ORG_ID:-}" || -z "${VERCEL_PROJECT_ID:-}" ]]; then - echo "Missing one or more required Vercel secrets: VERCEL_TOKEN, VERCEL_ORG_ID, VERCEL_PROJECT_ID." >&2 - exit 1 - fi - - router_url="${T3CODE_WEB_ROUTER_URL:-https://app.t3.codes}" - latest_domain="${T3CODE_WEB_LATEST_DOMAIN:-latest.app.t3.codes}" - nightly_domain="${T3CODE_WEB_NIGHTLY_DOMAIN:-nightly.app.t3.codes}" - router_domain="${router_url#http://}" - router_domain="${router_domain#https://}" - router_domain="${router_domain%%/*}" - - if [[ "${{ needs.preflight.outputs.release_channel }}" == "stable" ]]; then - channel_domain="$latest_domain" - channel_name="latest" - else - channel_domain="$nightly_domain" - channel_name="nightly" - fi - - vercel_scope="${VERCEL_TEAM_SLUG:-$VERCEL_ORG_ID}" - vercel_scope_args=(--scope "$vercel_scope") - - echo "Deploying hosted web app for $channel_name channel." - deployment_url="$( - vp dlx vercel@53.1.1 deploy \ - --archive=tgz \ - --prod \ - --skip-domain \ - --yes \ - --token "$VERCEL_TOKEN" \ - "${vercel_scope_args[@]}" \ - --build-env "APP_VERSION=${{ needs.preflight.outputs.version }}" \ - --build-env "T3CODE_CLERK_PUBLISHABLE_KEY=${T3CODE_CLERK_PUBLISHABLE_KEY:-}" \ - --build-env "T3CODE_CLERK_JWT_TEMPLATE=${T3CODE_CLERK_JWT_TEMPLATE:-}" \ - --build-env "T3CODE_CLERK_CLI_OAUTH_CLIENT_ID=${T3CODE_CLERK_CLI_OAUTH_CLIENT_ID:-}" \ - --build-env "T3CODE_RELAY_URL=${T3CODE_RELAY_URL:-}" \ - --build-env "T3CODE_RELAY_CLIENT_OTLP_TRACES_URL=${T3CODE_RELAY_CLIENT_OTLP_TRACES_URL:-}" \ - --build-env "T3CODE_RELAY_CLIENT_OTLP_TRACES_DATASET=${T3CODE_RELAY_CLIENT_OTLP_TRACES_DATASET:-}" \ - --build-env "T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN=${T3CODE_RELAY_CLIENT_OTLP_TRACES_TOKEN:-}" \ - --build-env "VITE_HOSTED_APP_URL=$router_url" \ - --build-env "VITE_HOSTED_APP_CHANNEL=$channel_name" - )" - - echo "Aliasing $deployment_url to $channel_domain." - vp dlx vercel@53.1.1 alias set "$deployment_url" "$channel_domain" \ - --token "$VERCEL_TOKEN" \ - "${vercel_scope_args[@]}" - - if [[ "$channel_name" == "latest" && -n "$router_domain" && "$router_domain" != "$channel_domain" ]]; then - echo "Aliasing $deployment_url to router domain $router_domain." - vp dlx vercel@53.1.1 alias set "$deployment_url" "$router_domain" \ - --token "$VERCEL_TOKEN" \ - "${vercel_scope_args[@]}" - fi finalize: name: Finalize release @@ -1113,11 +867,9 @@ jobs: if: | always() && !cancelled() && needs.preflight.result == 'success' && - needs.relay_public_config.result == 'success' && needs.release.result == 'success' && - needs.deploy_web.result == 'success' && (needs.finalize.result == 'success' || needs.finalize.result == 'skipped') - needs: [preflight, relay_public_config, release, deploy_web, finalize] + needs: [preflight, release, finalize] runs-on: ubuntu-24.04 timeout-minutes: 10 steps: From b914e91b89f8193ff363c7a52550e17ef61bb846 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 17:03:15 +1200 Subject: [PATCH 10/20] ci(release): remove CLI, AUR and Discord publish jobs - Remove publish_cli, publish_aur and announce_discord jobs and decouple release from CLI publishing - Fix ProviderInstanceRegistryHydration race by subscribing before forking - Allow inline WASM assets in web Vite config --- .github/workflows/release.yml | 142 +- .../ProviderInstanceRegistryHydration.ts | 28 +- .../provider/Layers/ProviderRegistry.test.ts | 2 + apps/web/vite.config.ts | 2 +- bun.lock | 4688 +++++++++++++++++ infra/relay/scripts/deploy.test.ts | 10 +- package.json | 96 + vite.config.ts | 2 + 8 files changed, 4819 insertions(+), 151 deletions(-) create mode 100644 bun.lock diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 16268e87b2f6..7e1e20a15157 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -597,70 +597,10 @@ jobs: path: resource-monitor-publish/${{ matrix.resource_key }}/* if-no-files-found: error - publish_cli: - name: Publish CLI to npm - needs: [preflight, quality, build] - if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.quality.result == 'success' && needs.build.result == 'success' }} - runs-on: ubuntu-24.04 - timeout-minutes: 10 - permissions: - contents: read - id-token: write - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - ref: ${{ needs.preflight.outputs.ref }} - sparse-checkout: | - /* - !/.repos/ - sparse-checkout-cone-mode: false - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version-file: package.json - cache: true - run-install: | - args: - - --filter=t3... - - --filter=@t3tools/web... - - --filter=@t3tools/scripts... - - - name: Align package versions to release version - run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}" - - - name: Build web package - run: vp run --filter @t3tools/web build - - - name: Build CLI package - run: vp run --filter t3 build - - - name: Download resource monitors - uses: actions/download-artifact@v8 - with: - pattern: resource-monitor-* - path: ${{ runner.temp }}/resource-monitors - - - name: Bundle resource monitors into CLI package - shell: bash - run: | - set -euo pipefail - for artifact_dir in "$RUNNER_TEMP"/resource-monitors/resource-monitor-*; do - resource_key="${artifact_dir##*/resource-monitor-}" - target_dir="apps/server/dist/resource-monitor/${resource_key}" - mkdir -p "$target_dir" - cp "$artifact_dir"/t3-resource-monitor* "$target_dir/" - chmod +x "$target_dir"/t3-resource-monitor 2>/dev/null || true - done - - - name: Publish CLI package - run: node apps/server/scripts/cli.ts publish --tag "${{ needs.preflight.outputs.cli_dist_tag }}" --app-version "${{ needs.preflight.outputs.version }}" --verbose - release: name: Publish GitHub Release - needs: [preflight, build, publish_cli] - if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.build.result == 'success' && needs.publish_cli.result == 'success' }} + needs: [preflight, quality, build] + if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.quality.result == 'success' && needs.build.result == 'success' }} runs-on: ubuntu-24.04 timeout-minutes: 30 permissions: @@ -772,17 +712,6 @@ jobs: fail_on_unmatched_files: true token: ${{ github.token }} - publish_aur: - name: Publish AUR package - needs: [preflight, release] - if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' }} - uses: ./.github/workflows/publish-aur.yml - with: - release_tag: ${{ needs.preflight.outputs.tag }} - secrets: - AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }} - - finalize: name: Finalize release if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' && needs.release.result == 'success' && needs.preflight.outputs.release_channel == 'stable' }} @@ -855,66 +784,9 @@ jobs: exit 0 fi - git config user.name "${{ steps.app_bot.outputs.name }}" - git config user.email "${{ steps.app_bot.outputs.email }}" - - git add apps/server/package.json apps/desktop/package.json apps/web/package.json packages/contracts/package.json pnpm-lock.yaml - git commit -m "chore(release): prepare $RELEASE_TAG" - git push origin HEAD:main + git config user.name "${{ steps.app_bot.outputs.name }}" + git config user.email "${{ steps.app_bot.outputs.email }}" - announce_discord: - name: Announce release on Discord - if: | - always() && !cancelled() && - needs.preflight.result == 'success' && - needs.release.result == 'success' && - (needs.finalize.result == 'success' || needs.finalize.result == 'skipped') - needs: [preflight, release, finalize] - runs-on: ubuntu-24.04 - timeout-minutes: 10 - steps: - - name: Checkout - uses: actions/checkout@v6 - with: - ref: ${{ needs.preflight.outputs.ref }} - sparse-checkout: | - /* - !/.repos/ - sparse-checkout-cone-mode: false - - - name: Setup Vite+ - uses: voidzero-dev/setup-vp@v1 - with: - node-version-file: package.json - cache: true - run-install: | - args: - - --filter=@t3tools/scripts... - - - name: Announce prerelease on Discord - if: needs.preflight.outputs.is_prerelease == 'true' - continue-on-error: true - env: - DISCORD_MENTION_ROLE_ID: ${{ secrets.DISCORD_RELEASE_NIGHTLY_ROLE_ID }} - DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} - run: | - node scripts/notify-discord-release.ts prerelease \ - --role-id "$DISCORD_MENTION_ROLE_ID" \ - --release-name "${{ needs.preflight.outputs.release_name }}" \ - --release-version "${{ needs.preflight.outputs.version }}" \ - --tag "${{ needs.preflight.outputs.tag }}" \ - --release-url "https://github.com/${{ github.repository }}/releases/tag/${{ needs.preflight.outputs.tag }}" - - - name: Announce latest release on Discord - if: needs.preflight.outputs.make_latest == 'true' - continue-on-error: true - env: - DISCORD_MENTION_ROLE_ID: ${{ secrets.DISCORD_RELEASE_LATEST_ROLE_ID }} - DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_RELEASE_WEBHOOK_URL }} - run: | - node scripts/notify-discord-release.ts latest \ - --role-id "$DISCORD_MENTION_ROLE_ID" \ - --release-name "${{ needs.preflight.outputs.release_name }}" \ - --release-version "${{ needs.preflight.outputs.version }}" \ - --tag "${{ needs.preflight.outputs.tag }}" \ - --release-url "https://github.com/${{ github.repository }}/releases/tag/${{ needs.preflight.outputs.tag }}" + git add apps/server/package.json apps/desktop/package.json apps/web/package.json packages/contracts/package.json pnpm-lock.yaml + git commit -m "chore(release): prepare $RELEASE_TAG" + git push origin HEAD:main diff --git a/apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.ts b/apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.ts index 0fd88b4262a6..3b34d51307d9 100644 --- a/apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.ts +++ b/apps/server/src/provider/Layers/ProviderInstanceRegistryHydration.ts @@ -118,18 +118,24 @@ const SettingsWatcherLive = Layer.effectDiscard( Effect.gen(function* () { const mutator = yield* ProviderInstanceRegistryMutator; const serverSettings = yield* ServerSettingsService; - yield* serverSettings.streamChanges.pipe( - Stream.runForEach((next) => - mutator - .reconcile(deriveProviderInstanceConfigMap(next)) - .pipe( - Effect.catchCause((cause) => - Effect.logError("ProviderInstanceRegistry reconcile failed", cause), - ), + // Acquire the subscription synchronously before forking the consumer + // so a settings publish between layer build and stream start is not + // dropped. Mirrors the fix in ProviderRegistryLive where + // `instanceRegistry.subscribeChanges` is acquired before forking + // `syncLiveSources` — `Stream.fromPubSub` defers subscribe to stream + // start and `forkScoped` only schedules the fiber, so a rapid + // `updateSettings` publish would otherwise be lost and a binaryPath + // change would never trigger a re-probe. + const changes = yield* serverSettings.subscribeChanges; + yield* Stream.runForEach(changes, (next) => + mutator + .reconcile(deriveProviderInstanceConfigMap(next)) + .pipe( + Effect.catchCause((cause) => + Effect.logError("ProviderInstanceRegistry reconcile failed", cause), ), - ), - Effect.forkScoped, - ); + ), + ).pipe(Effect.forkScoped); }), ); diff --git a/apps/server/src/provider/Layers/ProviderRegistry.test.ts b/apps/server/src/provider/Layers/ProviderRegistry.test.ts index 68e88da51576..3130d05cbbf7 100644 --- a/apps/server/src/provider/Layers/ProviderRegistry.test.ts +++ b/apps/server/src/provider/Layers/ProviderRegistry.test.ts @@ -1493,6 +1493,7 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te cursor: { enabled: false }, grok: { enabled: false }, opencode: { enabled: false }, + pi: { enabled: false }, }, }), ), @@ -1743,6 +1744,7 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te "cursor", "grok", "opencode", + "pi", ]); assert.strictEqual(cursorProvider?.enabled, false); assert.strictEqual(cursorProvider?.status, "disabled"); diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 6ee5de587b9e..89e6a30e11d9 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -153,7 +153,7 @@ const allowedHosts = [".ts.net", ...configuredAllowedHosts]; export default defineConfig(() => { return { - assetsInclude: ["**/*.wasm"], + assetsInclude: ["**/*.wasm", "**/*.wasm?inline"], plugins: [ devCompressionPlugin(), tanstackRouter(), diff --git a/bun.lock b/bun.lock new file mode 100644 index 000000000000..017985e639bd --- /dev/null +++ b/bun.lock @@ -0,0 +1,4688 @@ +{ + "lockfileVersion": 3, + "configVersion": 1, + "workspaces": { + "": { + "name": "@t3tools/monorepo", + "devDependencies": { + "@babel/plugin-transform-react-jsx": "7.28.6", + "@effect/tsgo": "catalog:", + "@oxlint/plugins": "^1.63.0", + "@types/node": "catalog:", + "@typescript/native-preview": "catalog:", + "vite-plus": "catalog:", + }, + }, + "apps/desktop": { + "name": "@t3tools/desktop", + "version": "0.0.33", + "dependencies": { + "@clerk/electron": "catalog:", + "@clerk/electron-passkeys": "catalog:", + "@effect/platform-node": "catalog:", + "@t3tools/client-runtime": "workspace:*", + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "@t3tools/ssh": "workspace:*", + "@t3tools/tailscale": "workspace:*", + "effect": "catalog:", + "electron": "41.5.0", + "electron-store": "^8.2.0", + "electron-updater": "^6.6.2", + "playwright-core": "1.60.0", + "react-grab": "^0.1.32", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "cross-env": "^10.1.0", + "electron-builder": "26.15.6", + "tailwindcss": "^4.0.0", + "vite-plus": "catalog:", + }, + }, + "apps/marketing": { + "name": "@t3tools/marketing", + "version": "0.0.0", + "dependencies": { + "@t3tools/shared": "workspace:*", + "astro": "^7.0.3", + }, + "devDependencies": { + "@astrojs/check": "^0.9.7", + "@vercel/config": "^0.3.0", + "typescript": "catalog:", + }, + }, + "apps/mobile": { + "name": "@t3tools/mobile", + "version": "0.0.0", + "dependencies": { + "@callstack/liquid-glass": "^0.7.1", + "@clerk/expo": "catalog:", + "@effect/atom-react": "catalog:", + "@expo-google-fonts/dm-sans": "^0.4.2", + "@expo/metro-runtime": "~56.0.15", + "@expo/ui": "~56.0.18", + "@legendapp/list": "catalog:", + "@noble/curves": "catalog:", + "@noble/hashes": "catalog:", + "@pierre/diffs": "catalog:", + "@react-native-menu/menu": "^2.0.0", + "@react-navigation/elements": "2.9.26", + "@react-navigation/native": "7.3.4", + "@react-navigation/native-stack": "7.17.6", + "@shikijs/core": "4.2.0", + "@shikijs/engine-javascript": "4.2.0", + "@shikijs/langs": "4.2.0", + "@shikijs/themes": "4.2.0", + "@t3tools/client-runtime": "workspace:*", + "@t3tools/contracts": "workspace:*", + "@t3tools/mobile-markdown-text": "file:./modules/t3-markdown-text", + "@t3tools/mobile-review-diff-native": "file:./modules/t3-review-diff", + "@t3tools/mobile-terminal-native": "file:./modules/t3-terminal", + "@t3tools/shared": "workspace:*", + "@tabler/icons-react-native": "^3.44.0", + "clsx": "^2.1.1", + "diff": "8.0.3", + "effect": "catalog:", + "expo": "~56.0.12", + "expo-asset": "~56.0.17", + "expo-auth-session": "~56.0.14", + "expo-blur": "~56.0.3", + "expo-build-properties": "~56.0.19", + "expo-camera": "~56.0.8", + "expo-clipboard": "~56.0.4", + "expo-constants": "~56.0.18", + "expo-crypto": "~56.0.4", + "expo-dev-client": "~56.0.20", + "expo-device": "~56.0.4", + "expo-file-system": "~56.0.8", + "expo-font": "~56.0.7", + "expo-glass-effect": "~56.0.4", + "expo-haptics": "~56.0.3", + "expo-image": "~56.0.11", + "expo-image-picker": "~56.0.18", + "expo-linking": "~56.0.14", + "expo-network": "~56.0.5", + "expo-notifications": "~56.0.18", + "expo-paste-input": "^0.1.15", + "expo-quick-actions": "^6.0.2", + "expo-secure-store": "~56.0.4", + "expo-sharing": "~56.0.18", + "expo-splash-screen": "~56.0.10", + "expo-sqlite": "~56.0.5", + "expo-symbols": "~56.0.6", + "expo-updates": "~56.0.19", + "expo-web-browser": "~56.0.5", + "expo-widgets": "~56.0.19", + "punycode": "^2.3.1", + "react": "19.2.3", + "react-dom": "19.2.3", + "react-native": "0.85.3", + "react-native-gesture-handler": "~2.31.1", + "react-native-image-viewing": "^0.2.2", + "react-native-keyboard-controller": "1.21.13", + "react-native-nitro-markdown": "^0.5.0", + "react-native-nitro-modules": "0.35.9", + "react-native-reanimated": "4.3.1", + "react-native-safe-area-context": "~5.7.0", + "react-native-screens": "4.25.2", + "react-native-shiki-engine": "^0.3.12", + "react-native-svg": "15.15.4", + "react-native-webview": "^13.16.1", + "react-native-worklets": "0.8.3", + "shiki": "4.2.0", + "tailwind-merge": "^3.5.0", + "uniwind": "^1.6.2", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "@pierre/trees": "1.0.0-beta.4", + "@types/react": "~19.2.0", + "babel-preset-expo": "~56.0.0", + "tailwindcss": "^4.0.0", + "typescript": "catalog:", + }, + }, + "apps/server": { + "name": "t3", + "version": "0.0.33", + "bin": { + "t3": "./dist/bin.mjs", + }, + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "^0.3.170", + "@effect/platform-bun": "catalog:", + "@effect/platform-node": "catalog:", + "@effect/platform-node-shared": "catalog:", + "@effect/sql-sqlite-bun": "catalog:", + "@ff-labs/fff-node": "0.9.4", + "@opencode-ai/sdk": "^1.3.15", + "@pierre/diffs": "catalog:", + "effect": "catalog:", + "msgpackr-extract": "3.0.4", + "node-pty": "^1.1.0", + "yaml": "catalog:", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "@t3tools/tailscale": "workspace:*", + "@t3tools/web": "workspace:*", + "@types/bun": "1.3.14", + "@types/node": "catalog:", + "effect-acp": "workspace:*", + "effect-codex-app-server": "workspace:*", + "vite-plus": "catalog:", + }, + }, + "apps/web": { + "name": "@t3tools/web", + "version": "0.0.33", + "dependencies": { + "@base-ui/react": "^1.4.1", + "@clerk/electron": "catalog:", + "@clerk/react": "catalog:", + "@dnd-kit/core": "^6.3.1", + "@dnd-kit/modifiers": "^9.0.0", + "@dnd-kit/sortable": "^10.0.0", + "@dnd-kit/utilities": "^3.2.2", + "@effect/atom-react": "catalog:", + "@formkit/auto-animate": "^0.9.0", + "@legendapp/list": "catalog:", + "@lexical/react": "^0.41.0", + "@noble/hashes": "catalog:", + "@pierre/diffs": "catalog:", + "@pierre/trees": "1.0.0-beta.4", + "@t3tools/client-runtime": "workspace:*", + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "@tanstack/react-pacer": "^0.19.4", + "@tanstack/react-router": "^1.160.2", + "class-variance-authority": "^0.7.1", + "culori": "^4.0.2", + "effect": "catalog:", + "heic-to": "^1.5.2", + "jose": "catalog:", + "jsonc-parser": "3.3.1", + "jszip": "3.10.1", + "lexical": "^0.41.0", + "lucide-react": "^0.564.0", + "react": "19.2.6", + "react-dom": "19.2.6", + "react-markdown": "^10.1.0", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", + "remark-breaks": "^4.0.0", + "remark-gfm": "^4.0.1", + "tailwind-merge": "^3.4.0", + "zustand": "^5.0.11", + }, + "devDependencies": { + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@rolldown/plugin-babel": "^0.2.0", + "@tailwindcss/vite": "^4.0.0", + "@tanstack/router-plugin": "^1.161.0", + "@types/babel__core": "^7.20.5", + "@types/compression": "^1.8.1", + "@types/culori": "^4.0.1", + "@types/react": "~19.2.14", + "@types/react-dom": "~19.2.3", + "@vercel/config": "^0.3.0", + "@vitejs/plugin-react": "^6.0.0", + "babel-plugin-react-compiler": "1.0.0", + "compression": "^1.8.1", + "msw": "2.12.11", + "tailwindcss": "^4.0.0", + "vite": "catalog:", + "vite-plus": "catalog:", + }, + }, + "infra/relay": { + "name": "t3code-relay", + "dependencies": { + "@clerk/backend": "catalog:", + "@effect/sql-pg": "catalog:", + "@noble/curves": "catalog:", + "@noble/hashes": "catalog:", + "@t3tools/client-runtime": "workspace:*", + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "alchemy": "2.0.0-beta.65", + "drizzle-orm": "1.0.0-rc.4", + "effect": "catalog:", + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20260601.1", + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "drizzle-kit": "1.0.0-rc.4", + "vite": "catalog:", + "vite-plus": "catalog:", + }, + }, + "oxlint-plugin-t3code": { + "name": "@t3tools/oxlint-plugin-t3code", + "dependencies": { + "@effect/platform-node": "catalog:", + "@oxlint/plugins": "^1.63.0", + "effect": "catalog:", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/client-runtime": { + "name": "@t3tools/client-runtime", + "dependencies": { + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "effect": "catalog:", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/contracts": { + "name": "@t3tools/contracts", + "version": "0.0.33", + "dependencies": { + "effect": "catalog:", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/effect-acp": { + "name": "effect-acp", + "dependencies": { + "effect": "catalog:", + }, + "devDependencies": { + "@effect/openapi-generator": "catalog:", + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/effect-codex-app-server": { + "name": "effect-codex-app-server", + "dependencies": { + "effect": "catalog:", + }, + "devDependencies": { + "@effect/openapi-generator": "catalog:", + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/shared": { + "name": "@t3tools/shared", + "dependencies": { + "@noble/curves": "catalog:", + "@noble/hashes": "catalog:", + "@t3tools/contracts": "workspace:*", + "effect": "catalog:", + "jose": "catalog:", + "yaml": "catalog:", + }, + "devDependencies": { + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/ssh": { + "name": "@t3tools/ssh", + "dependencies": { + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "effect": "catalog:", + }, + "devDependencies": { + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "vite-plus": "catalog:", + }, + }, + "packages/tailscale": { + "name": "@t3tools/tailscale", + "dependencies": { + "@effect/platform-node": "catalog:", + "@t3tools/shared": "workspace:*", + "effect": "catalog:", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "@types/node": "catalog:", + "vite-plus": "catalog:", + }, + }, + "scripts": { + "name": "@t3tools/scripts", + "dependencies": { + "@effect/platform-node": "catalog:", + "@electron/asar": "^3.4.1", + "@electron/osx-sign": "2.7.0", + "@t3tools/contracts": "workspace:*", + "@t3tools/shared": "workspace:*", + "@t3tools/tailscale": "workspace:*", + "effect": "catalog:", + "pngjs": "7.0.0", + "yaml": "catalog:", + }, + "devDependencies": { + "@effect/vitest": "catalog:", + "@types/pngjs": "6.0.5", + "vite-plus": "catalog:", + }, + }, + }, + "patchedDependencies": { + "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch", + "@clerk/expo@4.2.0": "patches/@clerk__expo@4.2.0.patch", + "react-native-gesture-handler@2.31.2": "patches/react-native-gesture-handler@2.31.2.patch", + "expo-modules-jsi@56.0.10": "patches/expo-modules-jsi@56.0.10.patch", + "react-native-keyboard-controller@1.21.13": "patches/react-native-keyboard-controller@1.21.13.patch", + "@react-navigation/native-stack@7.17.6": "patches/@react-navigation%2Fnative-stack@7.17.6.patch", + "@legendapp/list@3.3.5": "patches/@legendapp__list@3.3.5.patch", + "react-native-screens@4.25.2": "patches/react-native-screens@4.25.2.patch", + "effect@4.0.0-beta.103": "patches/effect@4.0.0-beta.103.patch", + "@expo/metro-config@56.0.14": "patches/@expo%2Fmetro-config@56.0.14.patch", + "@react-native/gradle-plugin@0.85.3": "patches/@react-native__gradle-plugin@0.85.3.patch", + "@effect/vitest@4.0.0-beta.103": "patches/@effect__vitest@4.0.0-beta.103.patch", + "@react-native-menu/menu@2.0.0": "patches/@react-native-menu__menu@2.0.0.patch", + "@pierre/diffs@1.3.0-beta.10": "patches/@pierre%2Fdiffs@1.3.0-beta.10.patch", + "react-native-nitro-modules@0.35.9": "patches/react-native-nitro-modules@0.35.9.patch", + }, + "overrides": { + "@clerk/backend": "catalog:", + "@clerk/clerk-js": "catalog:", + "@clerk/electron": "catalog:", + "@clerk/electron-passkeys": "catalog:", + "@clerk/expo": "catalog:", + "@clerk/react": "catalog:", + "@clerk/shared": "catalog:", + "@effect/atom-react": "catalog:", + "@effect/platform-bun": "catalog:", + "@effect/platform-node": "catalog:", + "@effect/platform-node-shared": "catalog:", + "@effect/sql-pg": "catalog:", + "@effect/sql-sqlite-bun": "catalog:", + "@effect/vitest": "catalog:", + "@expo/metro-config": "56.0.14", + "@pierre/diffs": { + "@shikijs/transformers": "^4.2.0", + }, + "@types/node": "catalog:", + "effect": "catalog:", + "expo-modules-jsi": "56.0.10", + "expo-sharing": { + "@expo/config-plugins": "56.0.9", + "@expo/config-types": "56.0.6", + }, + "vite": "catalog:", + "yaml": "catalog:", + }, + "catalog": { + "@clerk/backend": "3.14.0", + "@clerk/clerk-js": "6.29.2", + "@clerk/electron": "0.0.34", + "@clerk/electron-passkeys": "0.0.3", + "@clerk/expo": "4.2.0", + "@clerk/react": "6.14.4", + "@clerk/shared": "4.29.2", + "@effect/atom-react": "4.0.0-beta.103", + "@effect/openapi-generator": "4.0.0-beta.103", + "@effect/platform-bun": "4.0.0-beta.103", + "@effect/platform-node": "4.0.0-beta.103", + "@effect/platform-node-shared": "4.0.0-beta.103", + "@effect/sql-pg": "4.0.0-beta.103", + "@effect/sql-sqlite-bun": "4.0.0-beta.103", + "@effect/tsgo": "0.13.2", + "@effect/vitest": "4.0.0-beta.103", + "@legendapp/list": "3.3.5", + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@pierre/diffs": "1.3.0-beta.10", + "@types/node": "24.12.4", + "@typescript/native-preview": "7.0.0-dev.20260604.1", + "effect": "4.0.0-beta.103", + "jose": "6.2.2", + "typescript": "~6.0.3", + "vite": "npm:@voidzero-dev/vite-plus-core@0.2.2", + "vite-plus": "0.2.2", + "yaml": "^2.9.0", + }, + "packages": { + "@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.5", "", { "dependencies": { "ansi-styles": "6.2.3", "is-fullwidth-code-point": "5.1.0" } }, "sha512-3NX/MpTdroi0aKz134A6RC2Gb2iXVECN4QaAXnvCIxxIm3C3AVB1mkUe8NaaiyvOpDfsrqWhYtj+Q6a62RrTsw=="], + + "@alchemy.run/node-utils": ["@alchemy.run/node-utils@0.0.5", "", {}, "sha512-5agdhQxWBodxa5hDRyjnpx91RTU3g+qd5fxYB7uNDCaOzB0XC47UU/KHR6zf6jhz/NXf61gJS+vhYwn8NHeRoQ=="], + + "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.3.170", "", { "peerDependencies": { "@anthropic-ai/sdk": ">=0.93.0", "@modelcontextprotocol/sdk": "^1.29.0", "zod": "^4.0.0" } }, "sha512-pAvhfk+iTodXZ6RF18Kz7BEUWFjL7EcR3tKuhUNdPpE1NAYCR3mSHGbafi72JsrNwKEDIs7FU31z3fqhwy8QzA=="], + + "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.93.0", "", { "dependencies": { "json-schema-to-ts": "3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-q9vaSZQVFx6B/gPxetGYfLXSJD5v0sOmh0OpZDq7yCrTSA+Rscvrtyol7JJTW40wEpQB4U1B4JXzxQitbQ3CAA=="], + + "@astrojs/check": ["@astrojs/check@0.9.9", "", { "dependencies": { "@astrojs/language-server": "2.16.10", "chokidar": "4.0.3", "kleur": "4.1.5", "yargs": "17.7.2" }, "peerDependencies": { "typescript": "^5.0.0 || ^6.0.0" }, "bin": { "astro-check": "bin/astro-check.js" } }, "sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg=="], + + "@astrojs/compiler": ["@astrojs/compiler@2.13.1", "", {}, "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg=="], + + "@astrojs/compiler-binding": ["@astrojs/compiler-binding@0.2.3", "", { "optionalDependencies": { "@astrojs/compiler-binding-darwin-arm64": "0.2.3", "@astrojs/compiler-binding-darwin-x64": "0.2.3", "@astrojs/compiler-binding-linux-arm64-gnu": "0.2.3", "@astrojs/compiler-binding-linux-arm64-musl": "0.2.3", "@astrojs/compiler-binding-linux-x64-gnu": "0.2.3", "@astrojs/compiler-binding-linux-x64-musl": "0.2.3", "@astrojs/compiler-binding-wasm32-wasi": "0.2.3", "@astrojs/compiler-binding-win32-arm64-msvc": "0.2.3", "@astrojs/compiler-binding-win32-x64-msvc": "0.2.3" } }, "sha512-Xz3iBNse+hXXD25IXxsuXEt2ai8klAWE15CRm/EQBc9+aE3jXaF07DZx+iakk3HC6NHvWlEPzLPyxsLgPzOJsw=="], + + "@astrojs/compiler-binding-darwin-arm64": ["@astrojs/compiler-binding-darwin-arm64@0.2.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-sJIHeL1ONXEBLob8ZaXfmX6iCftUno08G/cMXj2FJnL0xNbHuELcEq1mjxHVFHNgUYu4P7xJNm2mpc0zUEPoKw=="], + + "@astrojs/compiler-binding-darwin-x64": ["@astrojs/compiler-binding-darwin-x64@0.2.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-P0NYu6aaIeLCqFfszxxBHL0a5WRaYigNVbDoO654Gi5Q2au5duDb5xZBv5EqUg4qnQVC173FXNvGZu1M7nk+/w=="], + + "@astrojs/compiler-binding-linux-arm64-gnu": ["@astrojs/compiler-binding-linux-arm64-gnu@0.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-PqVN5AqhuDqfx3ejaerwrC8codpV9jnyKV+IOel027qsJ1anFUJLdjUlY8VVys0xgd8lmqveX11OkcaQj/otTg=="], + + "@astrojs/compiler-binding-linux-arm64-musl": ["@astrojs/compiler-binding-linux-arm64-musl@0.2.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-O3e2CbN4yTsRguWYNnRd0p5YQ0H3fb7KpcR0W4R319q/gq5B1pJ7eqNbiO3b8g2AuiEcRTiUz5jeGT9j69cxOQ=="], + + "@astrojs/compiler-binding-linux-x64-gnu": ["@astrojs/compiler-binding-linux-x64-gnu@0.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-hbLBjXVp+96psMe7/7uqyrquGiULXANrq6REVxxPK/I5VzebZ7LHmSfykmByUbLyR1u+K6CTBKgvdQsK2L+2Xw=="], + + "@astrojs/compiler-binding-linux-x64-musl": ["@astrojs/compiler-binding-linux-x64-musl@0.2.3", "", { "os": "linux", "cpu": "x64" }, "sha512-vIiEvOwrJfHZMaTmqUCrFTIwMYL0+PD3Rvy7kFDQgERyx3zhaw8CPa01MCCqa+/sj344BGrXKZ6ti37SgNLMhw=="], + + "@astrojs/compiler-binding-wasm32-wasi": ["@astrojs/compiler-binding-wasm32-wasi@0.2.3", "", { "dependencies": { "@napi-rs/wasm-runtime": "1.1.6" }, "cpu": "none" }, "sha512-p9S2X8z/mUR2SMzAVJRFMCt8YaalKR+pjl2DgpdjzCQc6ww4bo8kiy54tgKqxZeNF5c+/2tCDTQIxVSm9V1FsA=="], + + "@astrojs/compiler-binding-win32-arm64-msvc": ["@astrojs/compiler-binding-win32-arm64-msvc@0.2.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-vcCG6JttIb5vbSmcxO2O398hpVj7lQ349iS7cjgYP6ZuLVEnw+9qPAr2MM2kJkU5wEGZqJ2gyi/M7UJoPwH1iQ=="], + + "@astrojs/compiler-binding-win32-x64-msvc": ["@astrojs/compiler-binding-win32-x64-msvc@0.2.3", "", { "os": "win32", "cpu": "x64" }, "sha512-hKssjNvC36e00Inb1GW1JsVyCFSCGnIjKem4S8q0VIW6cpWAUpvYB4qQU2HIDGD6SDX0ork4F5sWkNWkp2hrGQ=="], + + "@astrojs/compiler-rs": ["@astrojs/compiler-rs@0.2.3", "", { "dependencies": { "@astrojs/compiler-binding": "0.2.3" } }, "sha512-JRAtRcPxS4JeAZEIQFQ6GecBs/Wyp4m6/E8vBNxSgVfo1AtRVLUqRCl5oCGOZ0X/BSBB3Vef/7IlzyiGKi2ORA=="], + + "@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.10.0", "", { "dependencies": { "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "js-yaml": "4.2.0", "picomatch": "4.0.4", "retext-smartypants": "6.2.0", "shiki": "4.2.0", "smol-toml": "1.7.0", "unified": "11.0.5" } }, "sha512-Ry2R3VPeIN4uPCSA4xQc+e+vsJXkalKpEbDc07hV+a/o5Bs2N/s/uDcPJH/05L19DKh9tAy7e6JM3YZ6Cxfezw=="], + + "@astrojs/language-server": ["@astrojs/language-server@2.16.10", "", { "dependencies": { "@astrojs/compiler": "2.13.1", "@astrojs/yaml2ts": "0.2.4", "@jridgewell/sourcemap-codec": "1.5.5", "@volar/kit": "2.4.28", "@volar/language-core": "2.4.28", "@volar/language-server": "2.4.28", "@volar/language-service": "2.4.28", "muggle-string": "0.4.1", "tinyglobby": "0.2.17", "volar-service-css": "0.0.70", "volar-service-emmet": "0.0.70", "volar-service-html": "0.0.70", "volar-service-prettier": "0.0.70", "volar-service-typescript": "0.0.70", "volar-service-typescript-twoslash-queries": "0.0.70", "volar-service-yaml": "0.0.70", "vscode-html-languageservice": "5.6.2", "vscode-uri": "3.1.0" }, "peerDependencies": { "prettier": "^3.0.0", "prettier-plugin-astro": ">=0.11.0" }, "optionalPeers": ["prettier", "prettier-plugin-astro"], "bin": { "astro-ls": "./bin/nodeServer.js" } }, "sha512-87VQ/5GSdHlRnUA+hGuerYyIGAj+9RbZmATyuKLEUePinUXhQ5YkRnRrHhOD9sSi5JOErLjrLkHnfZFEvGrV8w=="], + + "@astrojs/markdown-satteri": ["@astrojs/markdown-satteri@0.3.2", "", { "dependencies": { "@astrojs/internal-helpers": "0.10.0", "@astrojs/prism": "4.0.2", "github-slugger": "2.0.0", "satteri": "0.9.3" } }, "sha512-feXuUPy41gVfeM7EHT1ciUim8ozGr+YHXab9uUBc1Hk8y60DQosO8ldL+AoPXnCAoGj1OChwHfvXmmJ6XVnY9A=="], + + "@astrojs/prism": ["@astrojs/prism@4.0.2", "", { "dependencies": { "prismjs": "1.30.0" } }, "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA=="], + + "@astrojs/telemetry": ["@astrojs/telemetry@3.3.2", "", { "dependencies": { "ci-info": "4.4.0", "dset": "3.1.4", "is-docker": "4.0.0", "is-wsl": "3.1.1", "which-pm-runs": "1.1.0" } }, "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ=="], + + "@astrojs/yaml2ts": ["@astrojs/yaml2ts@0.2.4", "", { "dependencies": { "yaml": "2.9.0" } }, "sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A=="], + + "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "5.2.0", "@aws-sdk/types": "3.973.10", "tslib": "2.8.1" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], + + "@aws-crypto/sha256-browser": ["@aws-crypto/sha256-browser@5.2.0", "", { "dependencies": { "@aws-crypto/sha256-js": "5.2.0", "@aws-crypto/supports-web-crypto": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/types": "3.973.10", "@aws-sdk/util-locate-window": "3.965.5", "@smithy/util-utf8": "2.3.0", "tslib": "2.8.1" } }, "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw=="], + + "@aws-crypto/sha256-js": ["@aws-crypto/sha256-js@5.2.0", "", { "dependencies": { "@aws-crypto/util": "5.2.0", "@aws-sdk/types": "3.973.10", "tslib": "2.8.1" } }, "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA=="], + + "@aws-crypto/supports-web-crypto": ["@aws-crypto/supports-web-crypto@5.2.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg=="], + + "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "3.973.10", "@smithy/util-utf8": "2.3.0", "tslib": "2.8.1" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], + + "@aws-sdk/client-cognito-identity": ["@aws-sdk/client-cognito-identity@3.1062.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.974.17", "@aws-sdk/credential-provider-node": "3.972.51", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/fetch-http-handler": "5.4.6", "@smithy/node-http-handler": "4.7.7", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-QA5z/Pl3aTMR3+bmiHoC6MpKYa4FMk/9lNP7k104uKuUsjMqP4ysRa43IwdcbI9sH023T//kSJCLxrxa2CP/Tw=="], + + "@aws-sdk/core": ["@aws-sdk/core@3.974.17", "", { "dependencies": { "@aws-sdk/types": "3.973.10", "@aws-sdk/xml-builder": "3.972.27", "@aws/lambda-invoke-store": "0.2.4", "@smithy/core": "3.24.6", "@smithy/signature-v4": "5.4.6", "@smithy/types": "4.14.3", "bowser": "2.14.1", "tslib": "2.8.1" } }, "sha512-r8o4h2K7j6P9ngno+8ei0aK0U/4JwDb7A2fMMxGVoSqDN8AFlIzSDeZHME9LcVLR2codyhtr1WAAg+/nmkeeMA=="], + + "@aws-sdk/credential-provider-cognito-identity": ["@aws-sdk/credential-provider-cognito-identity@3.972.41", "", { "dependencies": { "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-byGPybEQe9ejeyUzhWjtjfh0ctv25HsRx2djF/Tl2j9+DAuAmhjq0NqSRqYZEoSe8vJObXz5RYDtJYAmdupBig=="], + + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.972.43", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-g0XVQKzaA/4cq1vz1IvCQwYM+1Pkv01J9yHDpCTXekVuGZRDEz0wqBQ1AuYTq7FM6uik4uBGH8Tb5d9YvgeA7g=="], + + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.972.45", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/fetch-http-handler": "5.4.6", "@smithy/node-http-handler": "4.7.7", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-w9PuOoKCt6+xoESvY+zlV0u3PKQ0mVL259PcsVR6a3S/uYJJHnIi4r1NxdJHEcNldUVRIciltWnFMGBR4YEm3g=="], + + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.972.49", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/credential-provider-env": "3.972.43", "@aws-sdk/credential-provider-http": "3.972.45", "@aws-sdk/credential-provider-login": "3.972.48", "@aws-sdk/credential-provider-process": "3.972.43", "@aws-sdk/credential-provider-sso": "3.972.48", "@aws-sdk/credential-provider-web-identity": "3.972.48", "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/credential-provider-imds": "4.3.8", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-83r5MK+PERv9irzky1o5aNbXiLuaLfeB7N8MrktB9USpoebdNtuG0Ek9ieIxpGH1aZ9a0nIaDaLjEr3EmOV3Ng=="], + + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.972.48", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-amPGeF6fcvLInK4Pu2k2Y2jHFR6MpaIKrZrbaf0QUnV3tjzjWh442eifZ2+KcmzFdsqyvyjBqAhq2JNLt1C5gA=="], + + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.972.51", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.972.43", "@aws-sdk/credential-provider-http": "3.972.45", "@aws-sdk/credential-provider-ini": "3.972.49", "@aws-sdk/credential-provider-process": "3.972.43", "@aws-sdk/credential-provider-sso": "3.972.48", "@aws-sdk/credential-provider-web-identity": "3.972.48", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/credential-provider-imds": "4.3.8", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-mbhSY3ytXIGMuBoJsWCivk+63dtVlenT6wstUra07Lar4Ln2MVL8/j5zCTIOog+ig5/FlFJ8gcFU4nQZV+Jh4Q=="], + + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.972.43", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-GPokLNyvTfCmuaHk+v3GKVs4ZT3cMu5kgS2a+NPkOMt96cq6fSIK0g+mZHpGS6Cd4QGrPKesANEaLUKgOskTzg=="], + + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.972.48", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/token-providers": "3.1062.0", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-tf0sD47SeTgCDfOWYssctzGgwAuk8/ECjb7bom4wZ7P1om0qE8i2yjniUdvysmANm5haARr35O8vZnTe/UEtpQ=="], + + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.972.48", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-YYsumc2oe09gl4l+fjfmR64JDn6+0o4Ql5HMBkMuhFazO1tZlE5NjSnZM3oXHwenPjh2qow0TFgSIVjfWfsojg=="], + + "@aws-sdk/credential-providers": ["@aws-sdk/credential-providers@3.1062.0", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "3.1062.0", "@aws-sdk/core": "3.974.17", "@aws-sdk/credential-provider-cognito-identity": "3.972.41", "@aws-sdk/credential-provider-env": "3.972.43", "@aws-sdk/credential-provider-http": "3.972.45", "@aws-sdk/credential-provider-ini": "3.972.49", "@aws-sdk/credential-provider-login": "3.972.48", "@aws-sdk/credential-provider-node": "3.972.51", "@aws-sdk/credential-provider-process": "3.972.43", "@aws-sdk/credential-provider-sso": "3.972.48", "@aws-sdk/credential-provider-web-identity": "3.972.48", "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/credential-provider-imds": "4.3.8", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-QS2UT3srjNppZv6mq7V0igqK/ThYKqRWwDscxDsMEmmEE5JqCPPSqFW71aEpkvXaMdgmG8xEpt4RtNHpZ30cTA=="], + + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.997.16", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.974.17", "@aws-sdk/signature-v4-multi-region": "3.996.31", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/fetch-http-handler": "5.4.6", "@smithy/node-http-handler": "4.7.7", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-bGvfDgC2KQePjEmZdltScPPLKFoyjPElAXeZcLfvZ58J1AO283//WGtvp9GdnryLHTi7gis0UoCezqh0vl/nig=="], + + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.996.31", "", { "dependencies": { "@aws-sdk/types": "3.973.10", "@smithy/signature-v4": "5.4.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-Kn2up9SlG1KC6wRtwf0d7waTGF6rvp9DxYqB54x6UCKdQ6kyaXCqHL4WGb5vUJga5kS8FxnjhY0LqM28aMvnNQ=="], + + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.1062.0", "", { "dependencies": { "@aws-sdk/core": "3.974.17", "@aws-sdk/nested-clients": "3.997.16", "@aws-sdk/types": "3.973.10", "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-fvHh53zSm2FoQPgkw9thH5D7sd13bC0nPyuZb+mQJ85l5v7lQnsZ97u6e6YkJJN/LU1Mxm1/DLGrIIRR2L7tZw=="], + + "@aws-sdk/types": ["@aws-sdk/types@3.973.10", "", { "dependencies": { "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-992QrTO7G9qCvKD0fx1rMlqcL14plUcRAbwmqqYVsuF3GrqcvlAL9qxR+baMafarEZ+l7DUQ5lCMmt5mbMhF7g=="], + + "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.965.5", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ=="], + + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.972.27", "", { "dependencies": { "@smithy/types": "4.14.3", "fast-xml-parser": "5.7.3", "tslib": "2.8.1" } }, "sha512-hpsCXCOI436kxWpjtRuIHVvuPP81MOw8f18jzfZeg+UOiiOvlqWcmWChzEhJEu16cOC6+ku4ncBN+7rdt+DZ9g=="], + + "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.4", "", {}, "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ=="], + + "@babel/code-frame": ["@babel/code-frame@7.29.7", "", { "dependencies": { "@babel/helper-validator-identifier": "7.29.7", "js-tokens": "4.0.0", "picocolors": "1.1.1" } }, "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw=="], + + "@babel/compat-data": ["@babel/compat-data@7.29.7", "", {}, "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg=="], + + "@babel/core": ["@babel/core@7.29.7", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/generator": "7.29.7", "@babel/helper-compilation-targets": "7.29.7", "@babel/helper-module-transforms": "7.29.7", "@babel/helpers": "7.29.7", "@babel/parser": "7.29.7", "@babel/template": "7.29.7", "@babel/traverse": "7.29.7", "@babel/types": "7.29.7", "@jridgewell/remapping": "2.3.5", "convert-source-map": "2.0.0", "debug": "4.4.3", "gensync": "1.0.0-beta.2", "json5": "2.2.3", "semver": "6.3.1" } }, "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA=="], + + "@babel/generator": ["@babel/generator@7.29.7", "", { "dependencies": { "@babel/parser": "7.29.7", "@babel/types": "7.29.7", "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/trace-mapping": "0.3.31", "jsesc": "3.1.0" } }, "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ=="], + + "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.29.7", "", { "dependencies": { "@babel/types": "7.29.7" } }, "sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw=="], + + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.29.7", "", { "dependencies": { "@babel/compat-data": "7.29.7", "@babel/helper-validator-option": "7.29.7", "browserslist": "4.28.2", "lru-cache": "5.1.1", "semver": "6.3.1" } }, "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g=="], + + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-member-expression-to-functions": "7.29.7", "@babel/helper-optimise-call-expression": "7.29.7", "@babel/helper-replace-supers": "7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "7.29.7", "@babel/traverse": "7.29.7", "semver": "6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg=="], + + "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "regexpu-core": "6.4.0", "semver": "6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-907Uymvqgg1dwUA+7IGwFAOSYzQOuzPXKNJ1yxzwPffzkYFg2q2eHi1fIOs6sXkG9NbIUMunnUlkYsfRFNvomg=="], + + "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.8", "", { "dependencies": { "@babel/helper-compilation-targets": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "debug": "4.4.3", "lodash.debounce": "4.0.8", "resolve": "1.22.12" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA=="], + + "@babel/helper-globals": ["@babel/helper-globals@7.29.7", "", {}, "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA=="], + + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.29.7", "", { "dependencies": { "@babel/traverse": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg=="], + + "@babel/helper-module-imports": ["@babel/helper-module-imports@7.29.7", "", { "dependencies": { "@babel/traverse": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g=="], + + "@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "7.29.7", "@babel/helper-validator-identifier": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg=="], + + "@babel/helper-optimise-call-expression": ["@babel/helper-optimise-call-expression@7.29.7", "", { "dependencies": { "@babel/types": "7.29.7" } }, "sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong=="], + + "@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.29.7", "", {}, "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw=="], + + "@babel/helper-remap-async-to-generator": ["@babel/helper-remap-async-to-generator@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-wrap-function": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-16AMiW26DbXWBbr3B8wNozKM0ydMLB892vaOaJW/fPJdnT8vJk5sdkQcU/isqUxyCE0cEoa8wZOcbgDuC4b6Og=="], + + "@babel/helper-replace-supers": ["@babel/helper-replace-supers@7.29.7", "", { "dependencies": { "@babel/helper-member-expression-to-functions": "7.29.7", "@babel/helper-optimise-call-expression": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ=="], + + "@babel/helper-skip-transparent-expression-wrappers": ["@babel/helper-skip-transparent-expression-wrappers@7.29.7", "", { "dependencies": { "@babel/traverse": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.29.7", "", {}, "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.29.7", "", {}, "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg=="], + + "@babel/helper-validator-option": ["@babel/helper-validator-option@7.29.7", "", {}, "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw=="], + + "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.29.7", "", { "dependencies": { "@babel/template": "7.29.7", "@babel/traverse": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-iES0Skag9ERIF68aXadpO6dbXa03mNWK3sEqJaMnLNs/eC3l0lkImdfoy6Y09/SfkpawdAB4RjQ7PVA7TcVGdw=="], + + "@babel/helpers": ["@babel/helpers@7.29.7", "", { "dependencies": { "@babel/template": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg=="], + + "@babel/parser": ["@babel/parser@7.29.7", "", { "dependencies": { "@babel/types": "7.29.7" }, "bin": "./bin/babel-parser.js" }, "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg=="], + + "@babel/plugin-proposal-decorators": ["@babel/plugin-proposal-decorators@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/plugin-syntax-decorators": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-EtU0Hi3GvrTqD56xKmZvV/uCXK2ZbwVNPNLAquVItcAZpUhkXwWlo3Fmj0c2LxgSf2I8IDULeAepwNP1OefLXg=="], + + "@babel/plugin-proposal-export-default-from": ["@babel/plugin-proposal-export-default-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-p+G5BNXDcy3bOXplhY4HybQ1GxH3i2Tppmdm/3epyRu2VgJJZuUlZ61MqRTg582Q7ZLBdP7fePYvsumSEkMxcQ=="], + + "@babel/plugin-syntax-decorators": ["@babel/plugin-syntax-decorators@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-9MTTLbF39X6sqM92JPEsoI7++26hjZvzkxKZy64aMhWLH2mPkJ/Q3AV4QLmls3R14FpSpkOwQQfUh962JGQxxg=="], + + "@babel/plugin-syntax-dynamic-import": ["@babel/plugin-syntax-dynamic-import@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ=="], + + "@babel/plugin-syntax-export-default-from": ["@babel/plugin-syntax-export-default-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-foag0BB37ROhdeIX9O8G0jX7hw0UekJc04cHMrYLOnrErsnBKqJGHJ8eDRpoCFZBvEPPygmmtw4qyU97qa4oOw=="], + + "@babel/plugin-syntax-flow": ["@babel/plugin-syntax-flow@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ajMX6QPcyomotqwpzhkYGxcK2i/us0rs1Qo9QvUpa+Fca0FTmqrzKrctoIYLMxcOhGZldGT/BAVkRGTWBiR8gQ=="], + + "@babel/plugin-syntax-jsx": ["@babel/plugin-syntax-jsx@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A=="], + + "@babel/plugin-syntax-nullish-coalescing-operator": ["@babel/plugin-syntax-nullish-coalescing-operator@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ=="], + + "@babel/plugin-syntax-optional-chaining": ["@babel/plugin-syntax-optional-chaining@7.8.3", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg=="], + + "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA=="], + + "@babel/plugin-transform-arrow-functions": ["@babel/plugin-transform-arrow-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-N7zArUXWzAMzm+/N0uPBeVB3Fam5lMxtUwMmDK5f/IBBS7a7p1qeUoxd/6CckXoxUdgsntq1Dh8xNW06maZbDQ=="], + + "@babel/plugin-transform-async-generator-functions": ["@babel/plugin-transform-async-generator-functions@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-remap-async-to-generator": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-d98gXZkgswvkyohMBABkhm3GeXhYj8psWfwQ2C7gtfrKGTykQa/iOIi+JJhwMjPlZ6Vm2XN+DCf3Es1EoG4ZLA=="], + + "@babel/plugin-transform-async-to-generator": ["@babel/plugin-transform-async-to-generator@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-remap-async-to-generator": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-pcUb2SS+RMo9TWVBwKGI5ShtoG7R+zBsFmCKDa6fe8c+hPr3XJlZgoE5j6i8W7gDjhyvy+85vmYexanvXh3d1w=="], + + "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ONyr4+AZhKh8yKWInVxU9AXA9EbsyeLcL6V0dJy6M2/62vuvpGm29zzuymbTpdc451GEpDIdAyPLP3r+P61yKQ=="], + + "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-GtcpjFvanPfzNQi3eTitsCqtRRmmqzpy/A+yhTR1HaZo1Ly3EA8ZXxlPyHdR8/IuRMYc3E4wdGBewB2QKQjAaA=="], + + "@babel/plugin-transform-class-static-block": ["@babel/plugin-transform-class-static-block@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.12.0" } }, "sha512-kibJgmEdX2iMwsHY2tSZNDgj8PwIlCQz7FK9KuGKO8zsuoUwSEhoNnNVp/emKWrbY4HeO6kkXfdMqRKKKXBm2A=="], + + "@babel/plugin-transform-classes": ["@babel/plugin-transform-classes@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-compilation-targets": "7.29.7", "@babel/helper-globals": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-replace-supers": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-qV0OGGBVacduzQHE649JyCneOFI/maT+YKsO+K4Yi3xv2wTPNjM/W2o2gdzMwEAZz7fXNTHAe0NcSg30bIN69g=="], + + "@babel/plugin-transform-destructuring": ["@babel/plugin-transform-destructuring@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-iPX8aD6H9zV5s7ZsqTdNocPN/MGQ5sSMnElKrktxjJRMnB2jN/1p2+R7GkfD6CAYoVFqy5A4XnSIUeGgJzIWpg=="], + + "@babel/plugin-transform-export-namespace-from": ["@babel/plugin-transform-export-namespace-from@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-24B2nOy2TeJSMheqwPD4DDQOV/elLSIlKxjZt4i05H5AgdPdWR3n18HnNrcJ+j76WJd9gbwb9jPjNYUy6RautA=="], + + "@babel/plugin-transform-flow-strip-types": ["@babel/plugin-transform-flow-strip-types@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7", "@babel/plugin-syntax-flow": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-wRHeUjUjCZnMHmiO5bRgjFLcoEh7JyTdByOW11ahhwNa4V0bmeGEaIvt51yq0zQp2yWIpqfxXXPyUP6GFJZHOQ=="], + + "@babel/plugin-transform-for-of": ["@babel/plugin-transform-for-of@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zeSIHh0+E1Um1WJRXCFlHQYu2ieJNdivLLjlBEp+dIBu3S51n+SZZmIXjxnItw6pz56Cn+KvK68BIBVsxq2JiQ=="], + + "@babel/plugin-transform-logical-assignment-operators": ["@babel/plugin-transform-logical-assignment-operators@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-A0H91hh6W8MFRkp5TqJmMr39jzGD1A1E1Ysiv2O06Sfbhkapm+XyIzxWCEh5kqwOZ1/8QZ0dY3SeQ7XBqfJd5Q=="], + + "@babel/plugin-transform-modules-commonjs": ["@babel/plugin-transform-modules-commonjs@7.29.7", "", { "dependencies": { "@babel/helper-module-transforms": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ=="], + + "@babel/plugin-transform-named-capturing-groups-regex": ["@babel/plugin-transform-named-capturing-groups-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vuFoLwr4qnv2xbZ16SQd6uPcH5FNrLHhk/Jzo++0XJFcaDsr4gjJVg6j398oMHiC+83k/GiBzviwF5KBJkPUtQ=="], + + "@babel/plugin-transform-nullish-coalescing-operator": ["@babel/plugin-transform-nullish-coalescing-operator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-idmp1dFaekP9GbcMvG24Kvw2BfhFZjHnNJCkV4WuIY4PskJzwI3f1N5OdgYke38T7rftO6ERulFRn2cFeZwRkg=="], + + "@babel/plugin-transform-object-rest-spread": ["@babel/plugin-transform-object-rest-spread@7.29.7", "", { "dependencies": { "@babel/helper-compilation-targets": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/plugin-transform-destructuring": "7.29.7", "@babel/plugin-transform-parameters": "7.29.7", "@babel/traverse": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Ld98jn4c0smUywL57m7SgsHq3OpThOa6LqZJif3G6jYOovPleoFhVrBJ1WegRApSFB2wu4+RelAj9AC9G08Z4A=="], + + "@babel/plugin-transform-optional-catch-binding": ["@babel/plugin-transform-optional-catch-binding@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-sLsyndxK2VwX6yNUOakMb7Sh553ZTe/vVM1XJ+9Z5aW1ytsc8xOIwmyk05NNjN60vkc5/KqoTH6hB4V41LJhng=="], + + "@babel/plugin-transform-optional-chaining": ["@babel/plugin-transform-optional-chaining@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6GM1dhvK3gNODkXcEcMCOLEDCLSoZ/sBbro2Ax8HURyasQ4NshagQixkRFdh5niI6E4gmA/jYI/4aT7rRos3ZQ=="], + + "@babel/plugin-transform-parameters": ["@babel/plugin-transform-parameters@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-ZDOBqV/qLYJI0YElr8DcENEyARsFQeESqWXH6gZlghYXuPPjvweuDhP4VyEi4BlUBlLRFZVjxoZDMjxhLW766g=="], + + "@babel/plugin-transform-private-methods": ["@babel/plugin-transform-private-methods@7.29.7", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/6Rz4DK1ETDEM/bWHsPHcaEe7ZaT1EqSXjtSP/L0DijOYuaUhiRiOKcwpZ8P7zR4xXEHc2ITdiCgBm9Tpyv9ug=="], + + "@babel/plugin-transform-private-property-in-object": ["@babel/plugin-transform-private-property-in-object@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-create-class-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+BNo06dnrzdNNqCm1X6YUaVv0DKk8Q+JYcoZfOkLhYWNCXzlwTSRq8zGWayT1csjcpNXV9CQTBRRbmTLZac5cA=="], + + "@babel/plugin-transform-react-display-name": ["@babel/plugin-transform-react-display-name@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+1wdDMGNb4UPeY3Q4L5yLiYe6TXPXubs4NjrgRFw13hPRLJfEMw2Q5OXkee6/IfdqePIeW4Jjwe3aBh7SdKz4Q=="], + + "@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.28.6", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-module-imports": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/plugin-syntax-jsx": "7.29.7", "@babel/types": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow=="], + + "@babel/plugin-transform-react-jsx-development": ["@babel/plugin-transform-react-jsx-development@7.29.7", "", { "dependencies": { "@babel/plugin-transform-react-jsx": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Xfy3UVMF04+ypnFbkhvfqtmvwfe92qwQdbGZVonhE+6v35GzlofmOnA1szaZqzb9xYWr0nl1e5EMmzi0DNON1g=="], + + "@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw=="], + + "@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q=="], + + "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-H5E+HBgDpr6Q5t+Aj11tL7XkIui1jhbIoArVQnqjgXo5/3YxkN7ZEBcWF4RQlB0T4rrxJQbXS6kiFV6B7XTqUA=="], + + "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-rNNFV0DBAJp988xW2DOntfDoYn1eR8GGF5AT5vYc+rjyfaQkM242c9tZUHHPe7KYaiJizXPWhQTzzdbXySyhBw=="], + + "@babel/plugin-transform-runtime": ["@babel/plugin-transform-runtime@7.29.7", "", { "dependencies": { "@babel/helper-module-imports": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "babel-plugin-polyfill-corejs2": "0.4.17", "babel-plugin-polyfill-corejs3": "0.13.0", "babel-plugin-polyfill-regenerator": "0.6.8", "semver": "6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xmAscdE/AsqRW7vutbPNoUmu/nF5SrLKPs7aoJgEjo35lLKA/Bc0i2rMv/hr1+Y0o1bQCiVtith3u2vdgRL39Q=="], + + "@babel/plugin-transform-shorthand-properties": ["@babel/plugin-transform-shorthand-properties@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-I+WYbGBAiCn7nA6xBrlgPH+MB7HWb4u8pv5S0Pv7OtwNvIFvCCb24YlttKEeUFVurfBCEaOTnuhlqsb7f0Z5Dg=="], + + "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NCSEJ4sLFU2gqAub45HYh4fus2yQ36rr6ei6vpU7NdoJqCpxvEG8E6eJpscGyXP3VHD2Ny+fSXr04k1hoUrFqA=="], + + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-create-class-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-skip-transparent-expression-wrappers": "7.29.7", "@babel/plugin-syntax-typescript": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw=="], + + "@babel/plugin-transform-unicode-regex": ["@babel/plugin-transform-unicode-regex@7.29.7", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "7.29.7", "@babel/helper-plugin-utils": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-7D/x/23/d/3VqZ0QA+LGbZMlGwZjztBygSWWWsfTPoQ1oQ6Q1P6Mr3d0kk42XabyUVw+fha3LqdRsFqeKqvCyA=="], + + "@babel/preset-typescript": ["@babel/preset-typescript@7.29.7", "", { "dependencies": { "@babel/helper-plugin-utils": "7.29.7", "@babel/helper-validator-option": "7.29.7", "@babel/plugin-syntax-jsx": "7.29.7", "@babel/plugin-transform-modules-commonjs": "7.29.7", "@babel/plugin-transform-typescript": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ=="], + + "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="], + + "@babel/template": ["@babel/template@7.29.7", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/parser": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg=="], + + "@babel/traverse": ["@babel/traverse@7.29.7", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/generator": "7.29.7", "@babel/helper-globals": "7.29.7", "@babel/parser": "7.29.7", "@babel/template": "7.29.7", "@babel/types": "7.29.7", "debug": "4.4.3" } }, "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw=="], + + "@babel/types": ["@babel/types@7.29.7", "", { "dependencies": { "@babel/helper-string-parser": "7.29.7", "@babel/helper-validator-identifier": "7.29.7" } }, "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA=="], + + "@base-ui/react": ["@base-ui/react@1.5.0", "", { "dependencies": { "@babel/runtime": "7.29.7", "@base-ui/utils": "0.2.9", "@floating-ui/react-dom": "2.1.8", "@floating-ui/utils": "0.2.11", "use-sync-external-store": "1.6.0" }, "peerDependencies": { "@date-fns/tz": "^1.2.0", "@types/react": "^17 || ^18 || ^19", "date-fns": "^4.0.0", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@date-fns/tz", "@types/react", "date-fns"] }, "sha512-z1gSAlced1yY+iM+mHDEtIkD8UI3Ebs52MuBPxvV6f5hRutk+xvCH/wuB7hDqDzK9JG5FoMz5nhrqtSs1wjt1A=="], + + "@base-ui/utils": ["@base-ui/utils@0.2.9", "", { "dependencies": { "@babel/runtime": "7.29.7", "@floating-ui/utils": "0.2.11", "reselect": "5.2.0", "use-sync-external-store": "1.6.0" }, "peerDependencies": { "@types/react": "^17 || ^18 || ^19", "react": "^17 || ^18 || ^19", "react-dom": "^17 || ^18 || ^19" }, "optionalPeers": ["@types/react"] }, "sha512-x/PDDCYzoqPpjrdyb3VcyylTI2IjUXEtYDGi5foh7KsnmNJIIaVwA2GLgDH1dps1GgXiJbA60hM+AyuTfQzIvw=="], + + "@blazediff/core": ["@blazediff/core@1.9.1", "", {}, "sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA=="], + + "@bruits/satteri-darwin-arm64": ["@bruits/satteri-darwin-arm64@0.9.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-dRUZZrdwh1asfTOyM1nDNmzolhnHtlIFpqYrl1Tdd3YVcaebKmrfJgGL7NAoGPjbEwYmZxaugrxA0uzw83c0dw=="], + + "@bruits/satteri-darwin-x64": ["@bruits/satteri-darwin-x64@0.9.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-wgNCTRp2hPSpNMGFv5A4+6+VXgRJIlBZ7XKb3iwjV8YjRWNIjzE5zV2fUeYynyZYVRkuJ9aYFqQmWhc1e5H+UQ=="], + + "@bruits/satteri-linux-arm64-gnu": ["@bruits/satteri-linux-arm64-gnu@0.9.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-A/pWy8Jb/PhDYc2/JFuYh06gFJcsfBUBDl81YydGYBrL/Z4nItDfhNDNOibyeSN/lKKDRlycIHEIajjErk00sQ=="], + + "@bruits/satteri-linux-arm64-musl": ["@bruits/satteri-linux-arm64-musl@0.9.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-L6YxmyOSickzo4pE5WmZfNTJnjX0MtgKOsuwQfNZECTx9Ir5vl2B37EIwnxe2AybuPPHl+FqVQtthNDUdH4Vgg=="], + + "@bruits/satteri-linux-x64-gnu": ["@bruits/satteri-linux-x64-gnu@0.9.3", "", { "os": "linux", "cpu": "x64" }, "sha512-RgH6GPihg9Lzs2yHUsMjqiLxfLyOdmBty8sg9pBY9B4CBnvdOzvg8vklqN+C4qrEEdA9TwpbDpHr1AshLKyRpw=="], + + "@bruits/satteri-linux-x64-musl": ["@bruits/satteri-linux-x64-musl@0.9.3", "", { "os": "linux", "cpu": "x64" }, "sha512-BeWhVORjNTIomePznUKiMbHZTqC0j7sMXZFsISmbX+po5d33KLkqBqKh6K332CHJ8KUmCWx16FfPjwsoysttQg=="], + + "@bruits/satteri-wasm32-wasi": ["@bruits/satteri-wasm32-wasi@0.9.3", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "1.1.6" }, "cpu": "none" }, "sha512-dFNcOHKWV2cztCPnYTn7kZ9D7kNOt8N239z5ysFkNHLxJrfK7zaKIXQbfXYN32C+JoVFqAcTIOeWH2+VnsCOHg=="], + + "@bruits/satteri-win32-arm64-msvc": ["@bruits/satteri-win32-arm64-msvc@0.9.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-VnwjBHiAra/PNNEza8eSZdQiG4A3PtTJJwUDtOPAc6iTs0BWZwZX8+OPUZE7//yQCBhgvEMcI8vpwsAwCb6qGQ=="], + + "@bruits/satteri-win32-x64-msvc": ["@bruits/satteri-win32-x64-msvc@0.9.3", "", { "os": "win32", "cpu": "x64" }, "sha512-Dsoe4reWe69MyILmMwU6iISIceTW7YIFqbyym7haf9DhUvqkYfMAyp7GMM21JzV0SpG9A2BwzFVP7iq9mmxrpA=="], + + "@callstack/liquid-glass": ["@callstack/liquid-glass@0.7.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-N2rzs8g3kneI5G/98AZdVtjc6OUFBBFwPxVGVMoXUEI7QiioB4+aWwbImg5h8Z3Vb/T+fgLYWmmNhi27wHwE4g=="], + + "@capsizecss/unpack": ["@capsizecss/unpack@4.0.1", "", { "dependencies": { "fontkitten": "1.0.3" } }, "sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ=="], + + "@clack/core": ["@clack/core@1.4.2", "", { "dependencies": { "fast-wrap-ansi": "0.2.2", "sisteransi": "1.0.5" } }, "sha512-0Ty/1Gfm+Kb07sXcuESjyKfwEhSy4Ns1AgeEisHb/bDY5fWme0tTeTkU14T1Gmcs17YIjB/teiDe4uaCghbYqQ=="], + + "@clack/prompts": ["@clack/prompts@1.6.0", "", { "dependencies": { "@clack/core": "1.4.2", "fast-string-width": "3.0.2", "fast-wrap-ansi": "0.2.2", "sisteransi": "1.0.5" } }, "sha512-EYlRokl8szrP9Z25qT5aepMdBjzBvHF9ZEhzIiUBc9guz/T31EqRgvD0QSgZcpE93xiwrr+OkB4nz0BZyF6fSA=="], + + "@clerk/backend": ["@clerk/backend@3.14.0", "", { "dependencies": { "@clerk/shared": "4.29.2", "standardwebhooks": "1.0.0", "tslib": "2.8.1" } }, "sha512-WsphTvDFHDuQilKI7dyVE5qmt7USu8qSrujAq6SqpEHbVFfNBfINDNuzxlF9M2skOTfHFfgiTE8Jjb1egIBGLg=="], + + "@clerk/clerk-js": ["@clerk/clerk-js@6.29.2", "", { "dependencies": { "@clerk/shared": "4.29.2", "@stripe/stripe-js": "5.6.0", "@swc/helpers": "0.5.21", "@tanstack/query-core": "5.100.14", "@zxcvbn-ts/core": "3.0.4", "@zxcvbn-ts/language-common": "3.0.4", "alien-signals": "2.0.6", "browser-tabs-lock": "1.3.0", "core-js": "3.47.0", "crypto-js": "4.2.0", "dequal": "2.0.3" } }, "sha512-4i4RE+ZQ0hKDDFSRKCISQPBy07SfFeFAhBUhNj2j01Nx2n4pqV+5iyg2Vf27+NKFNkgq7kdmZGvtug24D++8WQ=="], + + "@clerk/electron": ["@clerk/electron@0.0.34", "", { "dependencies": { "@clerk/clerk-js": "6.29.2", "@clerk/react": "6.14.4", "@clerk/shared": "4.29.2", "tslib": "2.8.1" }, "peerDependencies": { "@clerk/electron-passkeys": "0.0.3", "electron": ">=28", "electron-store": "^8.2.0", "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0", "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0" }, "optionalPeers": ["@clerk/electron-passkeys", "electron-store", "react-dom"] }, "sha512-ZY6v8G1ArieIWvutMEt5HBJtpHN4ys4F4newNlOTElv//cpW29zaeZ65M8WuKttKr7fB+MH6wzzCoX/Ha+fiSg=="], + + "@clerk/electron-passkeys": ["@clerk/electron-passkeys@0.0.3", "", { "optionalDependencies": { "@clerk/electron-passkeys-darwin-arm64": "0.0.3", "@clerk/electron-passkeys-darwin-x64": "0.0.3", "@clerk/electron-passkeys-win32-arm64-msvc": "0.0.3", "@clerk/electron-passkeys-win32-x64-msvc": "0.0.3" } }, "sha512-OHhIe88qDL+FxyBalXdXNHAS5eEramr6Rerp+6iNkfkjqT8rx4hHNmfpmjg5/T1/am8QfknbOBZkqoXZlCrjPg=="], + + "@clerk/electron-passkeys-darwin-arm64": ["@clerk/electron-passkeys-darwin-arm64@0.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oAlrd+GLqP0oREP3hNRc6yNZhXGaQgJss9iCWRQqXjpw1yZD1ZU+L+E2Gfg84vMj/NSUhxbU0Djy0RXhmeUwgg=="], + + "@clerk/electron-passkeys-darwin-x64": ["@clerk/electron-passkeys-darwin-x64@0.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-0UPAWQEni7o8gjWwd2sP97fPshJmT2w5b8eV/jOPVSP8NqIcFCm5yIFSEx1SfB53LGfzB01A4iEGi2pxiCHqyQ=="], + + "@clerk/electron-passkeys-win32-arm64-msvc": ["@clerk/electron-passkeys-win32-arm64-msvc@0.0.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-bbRvifm9A/gfPkwC1UyMyF9sYGEs0aen7J2kCcaOIW3K0PXcAbHtsR/gnx4dT0bjFdd21vSa2zlIdERvHc1BiA=="], + + "@clerk/electron-passkeys-win32-x64-msvc": ["@clerk/electron-passkeys-win32-x64-msvc@0.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-gFaVqKlOKTF2SJ3lMwkZ0oonycQn93p1qSrp5kzzeZBeQ+tGB3gQnjXecrhQy21AzDUyWqVJJ8KrP2HRAwifWg=="], + + "@clerk/expo": ["@clerk/expo@4.2.0", "", { "dependencies": { "@clerk/clerk-js": "6.29.2", "@clerk/react": "6.14.4", "@clerk/shared": "4.29.2", "@expo/config-plugins": "56.0.9", "base-64": "1.0.0", "react-native-url-polyfill": "4.0.0", "tslib": "2.8.1" }, "peerDependencies": { "@clerk/expo-google-signin": ">=0.1.0", "@clerk/expo-passkeys": ">=0.0.6", "expo": ">=54 <58", "expo-apple-authentication": ">=7.0.0", "expo-auth-session": ">=5", "expo-constants": ">=12", "expo-crypto": ">=12", "expo-local-authentication": ">=13.5.0", "expo-secure-store": ">=12.4.0", "expo-web-browser": ">=12.5.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "react-native": ">=0.75" }, "optionalPeers": ["@clerk/expo-google-signin", "@clerk/expo-passkeys", "expo-apple-authentication", "expo-auth-session", "expo-constants", "expo-crypto", "expo-local-authentication", "expo-secure-store", "expo-web-browser", "react-dom"] }, "sha512-S2TYZn1Tltm/gXfe9J1NCuLRCmQX/3gfD0c+i/B1RWGbIJpSZX7KGRzvW70ABaqrK9IUcribLVmMN6unmpuCtQ=="], + + "@clerk/react": ["@clerk/react@6.14.4", "", { "dependencies": { "@clerk/shared": "4.29.2", "tslib": "2.8.1" }, "peerDependencies": { "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0", "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0" } }, "sha512-vMv3SU8dvo/b09/FAY7A0xaAe+YhZ2u4nvkRUUdqmOi8u3HNSJ3s2k2PIb0cNHsLurMvDzw/dD2Hbk97MPnN/A=="], + + "@clerk/shared": ["@clerk/shared@4.29.2", "", { "dependencies": { "@tanstack/query-core": "5.100.14", "dequal": "2.0.3", "glob-to-regexp": "0.4.1", "js-cookie": "3.0.7" }, "peerDependencies": { "react": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0", "react-dom": "^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-9c9Mc1oqumsqo+JY5R37O1ipwcG3RmwPK9oadBLL9E4VxZXthXVaFI9u+1/I4BSFGA/B9BO+17tkVDL4G0Wpbg=="], + + "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.16.1", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": ">1.20260305.0 <2.0.0-0" }, "optionalPeers": ["workerd"] }, "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw=="], + + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260704.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-XO+vvdhhTNZSsIWCkZ+JaE/JrFUmQAB0H0y/sVkAf32xa2TYBRvFUMwjSqf6WxtlxcKPQvmbLfpO/UQ0l/q4eQ=="], + + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260704.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-6iI7nbOOO8PzEQ6UZVBZB/hv95m8jl0yvyjMuWrF5cJbiLb5zPw3KnpqvGi+aeOs2ZmUkc81i1FWKfXwLXzPRA=="], + + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260704.1", "", { "os": "linux", "cpu": "x64" }, "sha512-3mT0YHtxT7eLjghu3hKSJDUQoz+AYv8FM43nLPYhM0YiHOxr8OlmvnCb2Lp7v/U3bwd3Gnx7WEqjSppR583mGg=="], + + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260704.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Opo7cPTPg4x0WwK+eZSDszCyFLKQkOGNCWxF005HRTJ5SJH8h0K9KyrC1k4LBwx3haXSVi+E1eGqo1gZ1Hmhkg=="], + + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260704.1", "", { "os": "win32", "cpu": "x64" }, "sha512-a97Ecnzhy04x3U052VKPCNp863F7Wf00WY7Ga5P0SbtYvaO1PDzylsHrvFMPKeiDFcOwqiredawmJ+v6bhIgeQ=="], + + "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20260604.1", "", {}, "sha512-nVTydUwPcz9WfwZ/6xAmqs8uUVeGbDVmyPvSYrYAo4CQTyi0122SoE1Suw8RvqnN60XXHPChAjDqSIjnr/mbmg=="], + + "@distilled.cloud/aws": ["@distilled.cloud/aws@0.30.2", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/credential-providers": "3.1062.0", "@aws-sdk/types": "3.973.10", "@distilled.cloud/core": "0.30.2", "@smithy/shared-ini-file-loader": "4.5.6", "@smithy/types": "4.14.3", "@smithy/util-base64": "4.4.6", "aws4fetch": "1.0.20", "fast-xml-parser": "5.8.0" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-Uw2yZf7PJ2ienrKG49HN1ajnke65mTtHBUrSb/3ykeZ/8cLaSgwVhPscHxSzGByY0TEtYcYKNNmfUVISgGQl9g=="], + + "@distilled.cloud/axiom": ["@distilled.cloud/axiom@0.30.2", "", { "dependencies": { "@distilled.cloud/core": "0.30.2" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-6g7tN/fKdMjnZYswlvwmLPeCqa2/jTsuOG7cSyUldhd6akxwWlMYqqDxwiOjgJfBZIOmcqSs5XVwiGMonZQTBw=="], + + "@distilled.cloud/cloudflare": ["@distilled.cloud/cloudflare@0.30.2", "", { "dependencies": { "@distilled.cloud/core": "0.30.2" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-bY0WAXL7Xw1mbo9twdXcaSCKL1rMi1o4aDzVwhnHASxe416oWvDARUo2/DPhQqN48r3q9BY2AyRAxRf65X6z0g=="], + + "@distilled.cloud/cloudflare-rolldown-plugin": ["@distilled.cloud/cloudflare-rolldown-plugin@0.13.10", "", { "dependencies": { "@cloudflare/unenv-preset": "2.16.1", "magic-string": "0.30.21", "unenv": "2.0.0-rc.24" }, "peerDependencies": { "rolldown": "^1.1.5", "vite": "^7.0.0 || ^8.0.0" }, "optionalPeers": ["rolldown", "vite"] }, "sha512-UO9wjepZWYupWMf/KYKY7LUueHNawdp0qBGc9z3XYxjodrQaMwFQWtIGG1yWOHjTWl1BUx86A69hyB8kHYRAeA=="], + + "@distilled.cloud/cloudflare-runtime": ["@distilled.cloud/cloudflare-runtime@0.13.10", "", { "dependencies": { "@alchemy.run/node-utils": "0.0.5", "workerd": "1.20260704.1" }, "peerDependencies": { "@distilled.cloud/cloudflare": "^0.29.0", "@effect/platform-bun": "4.0.0-beta.103", "@effect/platform-node": "4.0.0-beta.103", "effect": "4.0.0-beta.103" }, "optionalPeers": ["@effect/platform-bun", "@effect/platform-node"] }, "sha512-0mtI2rmxKiRcuZVXsQZfPnHWstUTCyPlg4q6EbxdImfiB4CCL2F56orGl9UhuBy+BPgO37wDgMe2GIpAHIUNWA=="], + + "@distilled.cloud/cloudflare-vite-plugin": ["@distilled.cloud/cloudflare-vite-plugin@0.13.10", "", { "dependencies": { "@distilled.cloud/cloudflare-rolldown-plugin": "0.13.10" }, "peerDependencies": { "@distilled.cloud/cloudflare": "^0.29.0", "@distilled.cloud/cloudflare-runtime": "0.13.10", "@effect/platform-bun": "4.0.0-beta.103", "@effect/platform-node": "4.0.0-beta.103", "effect": "4.0.0-beta.103", "vite": "^7.0.0 || ^8.0.0" }, "optionalPeers": ["@effect/platform-bun", "@effect/platform-node"] }, "sha512-O8lvG48OQcRkjwkCPUGdEGTtDuaKBlZWIMy+yTCAUnte/8rvixIxUj/PMX6lx4Prj2tx/ciqjRHl9qjtHL8KWA=="], + + "@distilled.cloud/core": ["@distilled.cloud/core@0.30.2", "", { "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-7wurt9mk2Z3h0zJ00FAXD9ApSLoiBdjArctc9k706JPwzo6uhSJNkTwVMFdYM6V3m5186cY5C8ukzstrCRkJSw=="], + + "@distilled.cloud/neon": ["@distilled.cloud/neon@0.30.2", "", { "dependencies": { "@distilled.cloud/core": "0.30.2" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-mFNmN4sUGIa7WukCSmU1KQSDZKmByjGY5Neh05IiM4b38UaJ80zYws0ZKLVsM3NNpypwnwcibYv3RwXxfG4f/Q=="], + + "@distilled.cloud/planetscale": ["@distilled.cloud/planetscale@0.30.2", "", { "dependencies": { "@distilled.cloud/core": "0.30.2" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-Ph4lY6Ds8xC0l8ZDaEsX4E5oPCHqnDHb3RYKbOPeO8fjaXdZHWxn24gxCWpzSU+fVnkmdKy9ntflqxK2l+12rQ=="], + + "@dnd-kit/accessibility": ["@dnd-kit/accessibility@3.1.1", "", { "dependencies": { "tslib": "2.8.1" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw=="], + + "@dnd-kit/core": ["@dnd-kit/core@6.3.1", "", { "dependencies": { "@dnd-kit/accessibility": "3.1.1", "@dnd-kit/utilities": "3.2.2", "tslib": "2.8.1" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ=="], + + "@dnd-kit/modifiers": ["@dnd-kit/modifiers@9.0.0", "", { "dependencies": { "@dnd-kit/utilities": "3.2.2", "tslib": "2.8.1" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-ybiLc66qRGuZoC20wdSSG6pDXFikui/dCNGthxv4Ndy8ylErY0N3KVxY2bgo7AWwIbxDmXDg3ylAFmnrjcbVvw=="], + + "@dnd-kit/sortable": ["@dnd-kit/sortable@10.0.0", "", { "dependencies": { "@dnd-kit/utilities": "3.2.2", "tslib": "2.8.1" }, "peerDependencies": { "@dnd-kit/core": "^6.3.0", "react": ">=16.8.0" } }, "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg=="], + + "@dnd-kit/utilities": ["@dnd-kit/utilities@3.2.2", "", { "dependencies": { "tslib": "2.8.1" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg=="], + + "@drizzle-team/brocli": ["@drizzle-team/brocli@0.12.0", "", {}, "sha512-mlUE+rZ8CatQekLhnaiN91Iemdd+e2gFKooGlnRB3oPTL3VghLfX24dx7HrzMNeC1JrIB/0kpsfyty3f5HNfxQ=="], + + "@effect/atom-react": ["@effect/atom-react@4.0.0-beta.103", "", { "peerDependencies": { "effect": "4.0.0-beta.103", "react": "^19.2.4", "scheduler": "*" } }, "sha512-1HJ+Cyq4ssLnH2UZ8OVnhtMGAySabtzZo7imKC+vEfxOW3lvJYpGZeicxQX5Ii/7AdvlR+19p/6K2a5IPKYAow=="], + + "@effect/openapi-generator": ["@effect/openapi-generator@4.0.0-beta.103", "", { "dependencies": { "swagger2openapi": "7.0.8" }, "peerDependencies": { "@effect/platform-node": "4.0.0-beta.103", "effect": "4.0.0-beta.103" }, "bin": { "openapigen": "dist/bin.js" } }, "sha512-wWp3n0w9g7edprSue5xLB68Lu3PNdeW1n8girDmV2RKdmVKgrvY0+iIyzYqEMhVGOxc7P0g/ZtMWzaAnJAxbBA=="], + + "@effect/platform-bun": ["@effect/platform-bun@4.0.0-beta.103", "", { "dependencies": { "@effect/platform-node-shared": "4.0.0-beta.103" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-/ay1/lhE9FUKEiDRQs56463eJ9u9ivtUtOCi2eeqI8Aooau7PupKNtV5zKjoRBCLInZMAX7JezT46NW5AdACBQ=="], + + "@effect/platform-node": ["@effect/platform-node@4.0.0-beta.103", "", { "dependencies": { "@effect/platform-node-shared": "4.0.0-beta.103", "mime": "4.1.0", "undici": "8.9.0" }, "peerDependencies": { "effect": "4.0.0-beta.103", "ioredis": "^5.7.0" } }, "sha512-VD8fbpendwFokMwzC7/MxazjhEVDihPC5NZtomYEyZwGaA1LXMvwP1y8pfXwfshUkG56TN4EMQqzu72c0B9FhA=="], + + "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.103", "", { "dependencies": { "@types/ws": "8.18.1", "ws": "8.21.0" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-0aCZMBid5ifqmY55TkfCDLaGTIM8qu3bNFUW7qL9vh/7jFOkaIAMX2MA8muG4deqW17XWxawddWu4v0fK+UW3g=="], + + "@effect/sql-d1": ["@effect/sql-d1@4.0.0-beta.101", "", { "dependencies": { "@cloudflare/workers-types": "5.20260726.1" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-4M/2lm7y1M1Fg1fCc31BTtU3p8lK0jHUlPGqIiJ97pOSXZJrlv21087VVLbJ/1i4svuSUshnShDsce9ZwZKsOQ=="], + + "@effect/sql-pg": ["@effect/sql-pg@4.0.0-beta.103", "", { "dependencies": { "pg": "8.22.0", "pg-connection-string": "2.14.0", "pg-cursor": "2.21.0", "pg-pool": "3.14.0", "pg-types": "4.1.0" }, "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-jzlTFtFaaoOmT87rQMKUBhkFeIQQwDKtlB+MOYn1jIPssLvXZVnMqo9GahCjsNcXVlB6QGBkUgD1HCA6+tJvBw=="], + + "@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.103", "", { "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-u10I6SEWgUc1sKrlT0luxOBNzlUXunzxCChrD75pK5khIN1baKlPn2DD3f7bkh20NxwSzOfxF3hWsrO4VktvNg=="], + + "@effect/tsgo": ["@effect/tsgo@0.13.2", "", { "optionalDependencies": { "@effect/tsgo-darwin-arm64": "0.13.2", "@effect/tsgo-darwin-x64": "0.13.2", "@effect/tsgo-linux-arm": "0.13.2", "@effect/tsgo-linux-arm64": "0.13.2", "@effect/tsgo-linux-x64": "0.13.2", "@effect/tsgo-win32-arm64": "0.13.2", "@effect/tsgo-win32-x64": "0.13.2" }, "bin": { "effect-tsgo": "dist/effect-tsgo.js" } }, "sha512-zPQMHBdCN1k7Jbxjxq0HVAbzsZd+LAoRPzBEZ3F4y/uxNK0K/XGvFXUUw/CUAsD6rhUtC2VahZY1tp0owb5lgg=="], + + "@effect/tsgo-darwin-arm64": ["@effect/tsgo-darwin-arm64@0.13.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-AlYlxU2sD3urNCmNCQWtatPJS/+m2r3CvgZdDTs9KEz2YcyQc2GV1g2RWFkoMwmgzYBx69DBLu1oscqJO2qAog=="], + + "@effect/tsgo-darwin-x64": ["@effect/tsgo-darwin-x64@0.13.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oGWIUsWuzCGBRaxB3R4ZjzmqaWb20OtLpBc8HKf3mGstyiCpGUtb7arqncpSq04nN9yb+mM5yBpGKZ9EJAYuEA=="], + + "@effect/tsgo-linux-arm": ["@effect/tsgo-linux-arm@0.13.2", "", { "os": "linux", "cpu": "arm" }, "sha512-y5aTN7MrwnsStcSJ4Z8J93Nszeh9yf8kbaHk+03bRm9n0TrhVea/bJZoi9cprLJSy01Umt+xC3jFyvOSMrWB8g=="], + + "@effect/tsgo-linux-arm64": ["@effect/tsgo-linux-arm64@0.13.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-v9PIgdLR6jREQk42EIm/mtFBwmB4Xzuq70l1Uf/7MnV/eivrZP+Wjfex/UuzMRbjM5eLRP3FFMj2HZvjkFQv6Q=="], + + "@effect/tsgo-linux-x64": ["@effect/tsgo-linux-x64@0.13.2", "", { "os": "linux", "cpu": "x64" }, "sha512-MzrApKfCL0DnFGvoyJUKtW39PGDykJZkkB/tOZSuTSurcYAzkmUIOUwuTASeNqDjj4/DixT7Ha4CMVeCQgg6hg=="], + + "@effect/tsgo-win32-arm64": ["@effect/tsgo-win32-arm64@0.13.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-WwYLSrgCa4iiSIZe5KkG2P1q+JmIloDI6tbqHqpvumrz3uU8fg33e5A7wQ68sRgr4ofqrTYPQhJ6b+Eyeadazg=="], + + "@effect/tsgo-win32-x64": ["@effect/tsgo-win32-x64@0.13.2", "", { "os": "win32", "cpu": "x64" }, "sha512-M4Cf98tlCzCWig61QNoPxhE0LyMJtlVIQY2hed0Y1uYpwv0W1BMyOACLcj6ll+vuLWmXvVlOfXC+BuDOqPo9fg=="], + + "@effect/vitest": ["@effect/vitest@4.0.0-beta.103", "", { "peerDependencies": { "effect": "4.0.0-beta.103" } }, "sha512-Kz3gemVuJNAZ3e4V6A7BwAP87x2Av8LyHOlCjy9jbZzlncwJXO7Olk1Sje3hdKaet3wEl51A/0/89xJ2IYSgNg=="], + + "@egjs/hammerjs": ["@egjs/hammerjs@2.0.17", "", { "dependencies": { "@types/hammerjs": "2.0.46" } }, "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A=="], + + "@electron/asar": ["@electron/asar@3.4.1", "", { "dependencies": { "commander": "5.1.0", "glob": "7.2.3", "minimatch": "3.1.5" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="], + + "@electron/fuses": ["@electron/fuses@1.8.0", "", { "dependencies": { "chalk": "4.1.2", "fs-extra": "9.1.0", "minimist": "1.2.8" }, "bin": { "electron-fuses": "dist/bin.js" } }, "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw=="], + + "@electron/get": ["@electron/get@2.0.3", "", { "dependencies": { "debug": "4.4.3", "env-paths": "2.2.1", "fs-extra": "8.1.0", "got": "11.8.6", "progress": "2.0.3", "semver": "6.3.1", "sumchecker": "3.0.1" }, "optionalDependencies": { "global-agent": "3.0.0" } }, "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ=="], + + "@electron/notarize": ["@electron/notarize@2.5.0", "", { "dependencies": { "debug": "4.4.3", "fs-extra": "9.1.0", "promise-retry": "2.0.1" } }, "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A=="], + + "@electron/osx-sign": ["@electron/osx-sign@2.7.0", "", { "dependencies": { "debug": "4.4.3", "isbinaryfile": "4.0.10", "plist": "3.1.1", "semver": "7.8.5" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.mjs", "electron-osx-sign": "bin/electron-osx-sign.mjs" } }, "sha512-9DGhNqKMl6ibkhUoXbN7OHX2gZznfY10L3ZwG0u6r667Kfb6kec4JEfFTXftoqzmOfZ+OzwDbr4p/nKBMHnz0g=="], + + "@electron/rebuild": ["@electron/rebuild@4.0.4", "", { "dependencies": { "@malept/cross-spawn-promise": "2.0.0", "debug": "4.4.3", "node-abi": "4.31.0", "node-api-version": "0.2.1", "node-gyp": "12.3.0", "read-binary-file-arch": "1.0.6" }, "bin": { "electron-rebuild": "lib/cli.js" } }, "sha512-Rzc39XPdk/+/wBG8MfwAHohXflep0ITUfulb6Rgz3R0NeSB1noE+E9/M/cb8ftCAiyDD9PPhLuuWgE1GaInbKg=="], + + "@electron/universal": ["@electron/universal@2.0.3", "", { "dependencies": { "@electron/asar": "3.4.1", "@malept/cross-spawn-promise": "2.0.0", "debug": "4.4.3", "dir-compare": "4.2.0", "fs-extra": "11.3.5", "minimatch": "9.0.9", "plist": "3.1.1" } }, "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g=="], + + "@electron/windows-sign": ["@electron/windows-sign@1.2.2", "", { "dependencies": { "cross-dirname": "0.1.0", "debug": "4.4.3", "fs-extra": "11.3.5", "minimist": "1.2.8", "postject": "1.0.0-alpha.6" }, "bin": { "electron-windows-sign": "bin/electron-windows-sign.js" } }, "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ=="], + + "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="], + + "@emmetio/css-abbreviation": ["@emmetio/css-abbreviation@2.1.8", "", { "dependencies": { "@emmetio/scanner": "1.0.4" } }, "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw=="], + + "@emmetio/css-parser": ["@emmetio/css-parser@0.4.1", "", { "dependencies": { "@emmetio/stream-reader": "2.2.0", "@emmetio/stream-reader-utils": "0.1.0" } }, "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ=="], + + "@emmetio/html-matcher": ["@emmetio/html-matcher@1.3.0", "", { "dependencies": { "@emmetio/scanner": "1.0.4" } }, "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ=="], + + "@emmetio/scanner": ["@emmetio/scanner@1.0.4", "", {}, "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA=="], + + "@emmetio/stream-reader": ["@emmetio/stream-reader@2.2.0", "", {}, "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw=="], + + "@emmetio/stream-reader-utils": ["@emmetio/stream-reader-utils@0.1.0", "", {}, "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A=="], + + "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "2.8.1" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], + + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="], + + "@epic-web/invariant": ["@epic-web/invariant@1.0.0", "", {}, "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.1", "", { "os": "android", "cpu": "arm" }, "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.1", "", { "os": "android", "cpu": "arm64" }, "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.1", "", { "os": "android", "cpu": "x64" }, "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.1", "", { "os": "linux", "cpu": "arm" }, "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.1", "", { "os": "linux", "cpu": "none" }, "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.1", "", { "os": "linux", "cpu": "x64" }, "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.1", "", { "os": "none", "cpu": "x64" }, "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.1", "", { "os": "none", "cpu": "arm64" }, "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="], + + "@exodus/schemasafe": ["@exodus/schemasafe@1.3.0", "", {}, "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw=="], + + "@expo-google-fonts/dm-sans": ["@expo-google-fonts/dm-sans@0.4.2", "", {}, "sha512-e/fLH5aCJzkEenz7axvEn8N7IJAKhUwNjIxS75h9j+Ip1M9S7d22M19gJN3A7QW4egVkBJRyQh1hQFhngQn9yA=="], + + "@expo-google-fonts/material-symbols": ["@expo-google-fonts/material-symbols@0.4.38", "", {}, "sha512-IJkBtN1o8u9BW5fvSii1MyHPQ7Q0HxbWcVBvOrOzgMLpVtZw7R2w94wBTVR7kZwv3w1JNTESMmLA5Sqn1+Z36A=="], + + "@expo/cli": ["@expo/cli@56.1.16", "", { "dependencies": { "@expo/code-signing-certificates": "0.0.6", "@expo/config": "56.0.9", "@expo/config-plugins": "56.0.9", "@expo/devcert": "1.2.1", "@expo/env": "2.3.0", "@expo/image-utils": "0.10.1", "@expo/inline-modules": "0.0.12", "@expo/json-file": "10.2.0", "@expo/log-box": "56.0.13", "@expo/metro": "56.0.0", "@expo/metro-config": "56.0.14", "@expo/metro-file-map": "56.0.3", "@expo/osascript": "2.6.0", "@expo/package-manager": "1.12.1", "@expo/plist": "0.7.0", "@expo/prebuild-config": "56.0.16", "@expo/require-utils": "56.1.3", "@expo/router-server": "56.0.14", "@expo/schema-utils": "56.0.1", "@expo/spawn-async": "1.8.0", "@expo/ws-tunnel": "2.0.0", "@expo/xcpretty": "4.4.4", "@react-native/dev-middleware": "0.85.3", "accepts": "1.3.8", "arg": "5.0.2", "bplist-creator": "0.1.0", "bplist-parser": "0.3.2", "chalk": "4.1.2", "ci-info": "3.9.0", "compression": "1.8.1", "connect": "3.7.0", "debug": "4.4.3", "dnssd-advertise": "1.1.4", "expo-server": "56.0.5", "fetch-nodeshim": "0.4.10", "getenv": "2.0.0", "glob": "13.0.6", "lan-network": "0.2.1", "multitars": "1.0.0", "node-forge": "1.4.0", "npm-package-arg": "11.0.3", "ora": "3.4.0", "picomatch": "4.0.4", "pretty-format": "29.7.0", "progress": "2.0.3", "prompts": "2.4.2", "resolve-from": "5.0.0", "semver": "7.8.5", "send": "0.19.2", "slugify": "1.6.9", "stacktrace-parser": "0.1.11", "structured-headers": "0.4.1", "terminal-link": "2.1.1", "toqr": "0.1.1", "wrap-ansi": "7.0.0", "ws": "8.21.0", "zod": "3.25.76" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "main.js" } }, "sha512-VBQn0mqAwc67b9Cn0RVXyeodghomAx5xGRhA/bXaQzuxDjMQk0zIOb6pXMZX7yiIwJW66UZt/zQiJNSv6aWJYw=="], + + "@expo/code-signing-certificates": ["@expo/code-signing-certificates@0.0.6", "", { "dependencies": { "node-forge": "1.4.0" } }, "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w=="], + + "@expo/config": ["@expo/config@56.0.9", "", { "dependencies": { "@expo/config-plugins": "56.0.9", "@expo/config-types": "56.0.6", "@expo/json-file": "10.2.0", "@expo/require-utils": "56.1.3", "deepmerge": "4.3.1", "getenv": "2.0.0", "glob": "13.0.6", "resolve-workspace-root": "2.0.1", "semver": "7.8.5", "slugify": "1.6.9" } }, "sha512-/lqFeWGSrhpKJVP8tTN8LjuoIe8u8q2w7FzBL0C+wHgl+WM8l1qUIEYWy/sMvsG/NbpUIUsDHJRhQvOkU58eIw=="], + + "@expo/config-plugins": ["@expo/config-plugins@56.0.9", "", { "dependencies": { "@expo/config-types": "56.0.6", "@expo/json-file": "10.2.0", "@expo/plist": "0.7.0", "@expo/require-utils": "56.1.3", "@expo/sdk-runtime-versions": "1.0.0", "chalk": "4.1.2", "debug": "4.4.3", "getenv": "2.0.0", "glob": "13.0.6", "semver": "7.8.5", "slugify": "1.6.9", "xcode": "3.0.1", "xml2js": "0.6.0" } }, "sha512-/6a/S9USwx8OC9tGjHxbviLFiBHyueN3aoNWMLvWDEJoZ1CIVW800ZBzwXq/FYNK2qzcN1LxFmQtzD1zeFQKNA=="], + + "@expo/config-types": ["@expo/config-types@56.0.6", "", {}, "sha512-4Y6Aum5J4Re5NnxGVofRNe1aDwUBOmWhQYkynZsqzRtX/zEA1ADUeyHXuEckv9YD9djiyT7bKtLt5gKL3mA6VQ=="], + + "@expo/devcert": ["@expo/devcert@1.2.1", "", { "dependencies": { "@expo/sudo-prompt": "9.3.2", "debug": "3.2.7" } }, "sha512-qC4eaxmKMTmJC2ahwyui6ud8f3W60Ss7pMkpBq40Hu3zyiAaugPXnZ24145U7K36qO9UHdZUVxsCvIpz2RYYCA=="], + + "@expo/devtools": ["@expo/devtools@56.0.2", "", { "dependencies": { "chalk": "4.1.2" }, "peerDependencies": { "react": "*", "react-native": "*" }, "optionalPeers": ["react", "react-native"] }, "sha512-ANl4kPdbe0/HQYWkDEN79S6bQhI+i/ZCnPxuC853pPsB4svhINC7Ku9lmGOKPsUUWWnrHg1spkDGQBZ4sD6JxQ=="], + + "@expo/dom-webview": ["@expo/dom-webview@56.0.5", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-UIEJxkLg6cHqofKrpWpkn9E6ApxVRtCgZhZkARPr9VV7rBVloJgeroTHs31YgU/JpbI5lLQOnfOlGo54W6C2Ew=="], + + "@expo/env": ["@expo/env@2.3.0", "", { "dependencies": { "chalk": "4.1.2", "debug": "4.4.3", "getenv": "2.0.0" } }, "sha512-9HnnIbzwTTdbwSjNLXTk0fPm9ZwMJ7c1/31tsni8HZ8Q62KzYCyspahH+V365vg5J6lr001DzNwBxVWSaYCQLg=="], + + "@expo/expo-modules-macros-plugin": ["@expo/expo-modules-macros-plugin@0.2.2", "", {}, "sha512-4IMzPDIo/VOXREQjsJtliSfqYVZvfzU2SLFS/9sKMWF848S8CHx+e/E+Vf0TcMvpWCCKX5umyqxb13KJJ+YUzg=="], + + "@expo/fingerprint": ["@expo/fingerprint@0.19.4", "", { "dependencies": { "@expo/env": "2.3.0", "@expo/spawn-async": "1.8.0", "arg": "5.0.2", "chalk": "4.1.2", "debug": "4.4.3", "getenv": "2.0.0", "glob": "13.0.6", "ignore": "5.3.2", "minimatch": "10.2.5", "resolve-from": "5.0.0", "semver": "7.8.5" }, "bin": { "fingerprint": "bin/cli.js" } }, "sha512-PsowRlO8+S7JlO8go7yhNEXp7sqlsWDE2AlCwoss7zH0dcajXFo74Fy0KdXEc4UXK7kKoHD37oDgsZ8aHSLr7A=="], + + "@expo/image-utils": ["@expo/image-utils@0.10.1", "", { "dependencies": { "@expo/require-utils": "56.1.3", "@expo/spawn-async": "1.8.0", "chalk": "4.1.2", "getenv": "2.0.0", "jimp-compact": "0.16.1", "parse-png": "2.1.0", "semver": "7.8.5" } }, "sha512-YDeefvmYdihS7Wp3ESDUVnOgOSWmj2Cczm9lVNDdm4MqQLdAKm/LPYg83HtFQPfefRlAxyHrQR/O9kIXN9C1Wg=="], + + "@expo/inline-modules": ["@expo/inline-modules@0.0.12", "", { "dependencies": { "@expo/config-plugins": "56.0.9" } }, "sha512-SNIZr/HWfIQPTZBwmukItxpc7ws1SgMUywYq1dnQvDknQDjJcuWAasIRFUjsK15yQ1xb4G5CP7VHtbN3V4lENg=="], + + "@expo/json-file": ["@expo/json-file@10.2.0", "", { "dependencies": { "@babel/code-frame": "7.29.7", "json5": "2.2.3" } }, "sha512-S6XzKe3R9GQeHiUPXc3xJjOv2VJhOEwFYf7xdC2z2cUqt3kZJ9mSO877sNQloVdnW/SUCtPY3bexlM7nwq+CAQ=="], + + "@expo/local-build-cache-provider": ["@expo/local-build-cache-provider@56.0.8", "", { "dependencies": { "@expo/config": "56.0.9", "chalk": "4.1.2" } }, "sha512-UsuXwpNi57MNhzZ3be4XThc8xW6nzk3Wu37s1+2qcfZGeJcMLKDFfwO6n8YXeIiGlCsOi0Ee1rsTdgjrKt/YJQ=="], + + "@expo/log-box": ["@expo/log-box@56.0.13", "", { "dependencies": { "anser": "1.4.10", "stacktrace-parser": "0.1.11" }, "peerDependencies": { "@expo/dom-webview": "^56.0.5", "expo": "*", "react": "*", "react-native": "*" } }, "sha512-QWRZSpWPyjkDLVQio4R7oAzg/Av2MOt/DciFkfjr8qQ3qxGVn1Rt1oHP/80hvcWDcHFV7N6PqpyxRXw6nbxzKQ=="], + + "@expo/metro": ["@expo/metro@56.0.0", "", { "dependencies": { "metro": "0.84.4", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-config": "0.84.4", "metro-core": "0.84.4", "metro-file-map": "0.84.4", "metro-minify-terser": "0.84.4", "metro-resolver": "0.84.4", "metro-runtime": "0.84.4", "metro-source-map": "0.84.4", "metro-symbolicate": "0.84.4", "metro-transform-plugins": "0.84.4", "metro-transform-worker": "0.84.4" } }, "sha512-5gIgQHtEpjjvsjKfVtIv23a98LLRV0/y07PDShEwYSytAMlE3FSF8RHXqtHc1sUJL6dn7hnuIBpIbrLXXuVi0A=="], + + "@expo/metro-config": ["@expo/metro-config@56.0.14", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/core": "7.29.7", "@babel/generator": "7.29.7", "@expo/config": "56.0.9", "@expo/env": "2.3.0", "@expo/json-file": "10.2.0", "@expo/metro": "56.0.0", "@expo/require-utils": "56.1.3", "@expo/spawn-async": "1.8.0", "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/remapping": "2.3.5", "@jridgewell/sourcemap-codec": "1.5.5", "browserslist": "4.28.2", "chalk": "4.1.2", "debug": "4.4.3", "getenv": "2.0.0", "glob": "13.0.6", "hermes-parser": "0.33.3", "jsc-safe-url": "0.2.4", "lightningcss": "1.32.0", "picomatch": "4.0.4", "postcss": "8.5.15", "resolve-from": "5.0.0" }, "peerDependencies": { "expo": "*" }, "optionalPeers": ["expo"] }, "sha512-O3CIHruaTJhswPAf/nf3i8QQ3f2jl+mEwSea1eb3khuplabdy/wTQz+JvHN8VGUFyg7JKwUGU1QfO6T3JiSQqA=="], + + "@expo/metro-file-map": ["@expo/metro-file-map@56.0.3", "", { "dependencies": { "debug": "4.4.3", "fb-watchman": "2.0.2", "invariant": "2.2.4", "jest-worker": "29.7.0", "micromatch": "4.0.8", "walker": "1.0.8" } }, "sha512-5OGW3z8LgEYgMJOR7F3pC8llFLkb1fVqwAewbCl6S4Vkha8AFQMwOjT+9Wbka+V4rmpljpGqOnMhF4xZbD961w=="], + + "@expo/metro-runtime": ["@expo/metro-runtime@56.0.15", "", { "dependencies": { "anser": "1.4.10", "pretty-format": "29.7.0", "stacktrace-parser": "0.1.11", "whatwg-fetch": "3.6.20" }, "peerDependencies": { "@expo/log-box": "^56.0.13", "expo": "*", "react": "*", "react-dom": "*", "react-native": "*" }, "optionalPeers": ["react-dom"] }, "sha512-WIWeVsL6kCSB57oYZdUA4MTkH7c67UFMIjdNoQzKXwxZYwBFE/xL2cGPDC3z8RWt0femzJTVxAVZUOW/hiqRzA=="], + + "@expo/osascript": ["@expo/osascript@2.6.0", "", { "dependencies": { "@expo/spawn-async": "1.8.0" } }, "sha512-QvqDBlJXa8CS2vRORJ4wEflY1m0vVI07uSJdIRgBrLxRPBcsrXxrtU7+wXRXMqfq9zLwNP9XbvRsXF2omoDylg=="], + + "@expo/package-manager": ["@expo/package-manager@1.12.1", "", { "dependencies": { "@expo/json-file": "10.2.0", "@expo/spawn-async": "1.8.0", "chalk": "4.1.2", "npm-package-arg": "11.0.3", "ora": "3.4.0", "resolve-workspace-root": "2.0.1" } }, "sha512-fQLiFAcFRWF53mtuLK32SUJQ1ahhrTcBZPZPedYTiUT5ha5FF+UO6bPtCc0Y/hgj0/m3HCGBAuSHjbg2kI9oPQ=="], + + "@expo/plist": ["@expo/plist@0.7.0", "", { "dependencies": { "@xmldom/xmldom": "0.8.13", "base64-js": "1.5.1", "xmlbuilder": "15.1.1" } }, "sha512-vrpryU1GoqSIRNqRB2D3IjXDmzNYfiQpEF6AH/xknlD7eiYmEDt3mb26V7cLcedcPG8PY/1xWHdBXVQJfEAh6Q=="], + + "@expo/prebuild-config": ["@expo/prebuild-config@56.0.16", "", { "dependencies": { "@expo/config": "56.0.9", "@expo/config-plugins": "56.0.9", "@expo/config-types": "56.0.6", "@expo/image-utils": "0.10.1", "@expo/json-file": "10.2.0", "@react-native/normalize-colors": "0.85.3", "debug": "4.4.3", "expo-modules-autolinking": "56.0.16", "resolve-from": "5.0.0", "semver": "7.8.5" } }, "sha512-ce9ENfPWO4WUWUVQz0OaqL3KYZ7YofP8O35ncnn7CHCaKwQ7BqxcCGJbh+qvP1UjlWeNB3CjHPrXXJ3bnZwlJw=="], + + "@expo/require-utils": ["@expo/require-utils@56.1.3", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/core": "7.29.7", "@babel/plugin-transform-modules-commonjs": "7.29.7" }, "peerDependencies": { "typescript": "^5.0.0 || ^5.0.0-0 || ^6.0.0" }, "optionalPeers": ["typescript"] }, "sha512-KyLeOn/zzQSvuPpV5YhB/FPKnpQytno4luN918bGdPDssLBoS3N/0UbC3W0rJAn9kSFu+XpfR81eABRVsSdfgQ=="], + + "@expo/router-server": ["@expo/router-server@56.0.14", "", { "dependencies": { "debug": "4.4.3" }, "peerDependencies": { "@expo/metro-runtime": "^56.0.15", "expo": "*", "expo-constants": "^56.0.18", "expo-font": "^56.0.6", "expo-router": "*", "expo-server": "^56.0.5", "react": "*", "react-dom": "*", "react-server-dom-webpack": "~19.0.1 || ~19.1.2 || ~19.2.1" }, "optionalPeers": ["@expo/metro-runtime", "expo-router", "react-dom", "react-server-dom-webpack"] }, "sha512-2UCTtZfcq1ZPgp3wk8/+sq9DvFI9UxrPr1jcEKMAF2DGAJLosnpc8GWNNg2hkjt6SHUOdFHIPxujWPYyho2y3A=="], + + "@expo/schema-utils": ["@expo/schema-utils@56.0.1", "", {}, "sha512-CZ/+mYbQmWeOnkCGlWy9K+lFxbJSMFY7+TqBZcKzBSTU5Q7IGRvn/sOG3TdNjIdLPmbA8xe7R/c3UUQ28R9i9w=="], + + "@expo/sdk-runtime-versions": ["@expo/sdk-runtime-versions@1.0.0", "", {}, "sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ=="], + + "@expo/spawn-async": ["@expo/spawn-async@1.8.0", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-eb9xxd/LbuEGSdua4NumCu/McVB9EM+F/JxB9pWgnERw4HQ9XyTNH1KapG6oqLWR8TuRK2LQfzJlmNi94CVobw=="], + + "@expo/sudo-prompt": ["@expo/sudo-prompt@9.3.2", "", {}, "sha512-HHQigo3rQWKMDzYDLkubN5WQOYXJJE2eNqIQC2axC2iO3mHdwnIR7FgZVvHWtBwAdzBgAP0ECp8KqS8TiMKvgw=="], + + "@expo/ui": ["@expo/ui@56.0.18", "", { "dependencies": { "sf-symbols-typescript": "2.2.0", "vaul": "1.1.2" }, "peerDependencies": { "@babel/core": "*", "expo": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-reanimated": "*", "react-native-worklets": "*" }, "optionalPeers": ["@babel/core", "react-dom", "react-native-reanimated", "react-native-worklets"] }, "sha512-2XgH5obigGtXm8zlb/V3g87NSiIcBcJ1xoQOEQYPoExL1DCNsHzaIecTh1XG/f/45ardo4OZNJwpbfYJ9X3qrQ=="], + + "@expo/ws-tunnel": ["@expo/ws-tunnel@2.0.0", "", { "peerDependencies": { "ws": "^8.0.0" } }, "sha512-j+JfTRdCk820J9dU0sA2SqshQIKFOMo7ED84w9MJFcebfbNQgsLztEY/SABDkGnjatrW4xGqnUhVRxSBVyCkXw=="], + + "@expo/xcpretty": ["@expo/xcpretty@4.4.4", "", { "dependencies": { "@babel/code-frame": "7.29.7", "chalk": "4.1.2", "js-yaml": "4.2.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-4aQzz9vgxcNXFfo/iyNgDDYfsU5XGKKxWxZopw0cVotHiW+U8IJbIxMaxsINs6bHhtkG3StKNPcOrn3eBuxKPw=="], + + "@ff-labs/fff-bin-darwin-arm64": ["@ff-labs/fff-bin-darwin-arm64@0.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-xyivu2xB++O5xXDx5Qm50JsU2aXt8YgXlGVhH/HE7UMYDrE6L6f1RYdYs8Y0bn0D3D0+bFBrN5ELPszK9E4Wbw=="], + + "@ff-labs/fff-bin-darwin-x64": ["@ff-labs/fff-bin-darwin-x64@0.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-xLooAhCnTDCipPSMMZz7kGF3lhRHx6aP5fb6DJ0Ipyw/w/UWJb+xITJFszUl/QnIBoJ/qjDc93/FZMo1dk6gVA=="], + + "@ff-labs/fff-bin-linux-arm64-gnu": ["@ff-labs/fff-bin-linux-arm64-gnu@0.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-m5+8vA+1veaUUWonwva1WsU6m1HRm8CpYUzr06KDB65mewlmPbqz7+Fh7hjEfiD8C4mHVHe6RysULvAH1yhsdw=="], + + "@ff-labs/fff-bin-linux-arm64-musl": ["@ff-labs/fff-bin-linux-arm64-musl@0.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-EMeWm7CSTVkizy4ZEzUkLDP024tVcbCUthduuIhekFQRDsiaAze0YboIylWb9HBHJCZlCCoZrWAl4nnJbsX7AA=="], + + "@ff-labs/fff-bin-linux-x64-gnu": ["@ff-labs/fff-bin-linux-x64-gnu@0.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-pglE0uLkhnlE6bStXqfgUjYTSj+2sVwXaPfoA0QksidAsQor6NRt8004mygzC9DPubgHq5B9QezPfEwigKaP9Q=="], + + "@ff-labs/fff-bin-linux-x64-musl": ["@ff-labs/fff-bin-linux-x64-musl@0.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-VNKxgl8qs3aTfXViX7lqRK1aLu311h8dtBFqG4Scv+9Oi7WprybUp5L7IZ8sxKERaDAaiJMXHodXa1c90QdK8w=="], + + "@ff-labs/fff-bin-win32-arm64": ["@ff-labs/fff-bin-win32-arm64@0.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-uFEt0aNL54vQxq1ivjxRuo+thnhS4wLqa4INl4VXnXJUmwB42XXxD+gsj7vzhBLLx4cFf0aWgy/+TVDR8yjZtQ=="], + + "@ff-labs/fff-bin-win32-x64": ["@ff-labs/fff-bin-win32-x64@0.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-Yd2Eyxj+slWv+0QDW9/xBpu9FXq+hwD0rXQD5184/88d+xwWCLKhEP2w8I6OO9XCg+kLT79UJb+k0WwXUtBtMw=="], + + "@ff-labs/fff-node": ["@ff-labs/fff-node@0.9.4", "", { "dependencies": { "ffi-rs": "1.3.2" }, "optionalDependencies": { "@ff-labs/fff-bin-darwin-arm64": "0.9.4", "@ff-labs/fff-bin-darwin-x64": "0.9.4", "@ff-labs/fff-bin-linux-arm64-gnu": "0.9.4", "@ff-labs/fff-bin-linux-arm64-musl": "0.9.4", "@ff-labs/fff-bin-linux-x64-gnu": "0.9.4", "@ff-labs/fff-bin-linux-x64-musl": "0.9.4", "@ff-labs/fff-bin-win32-arm64": "0.9.4", "@ff-labs/fff-bin-win32-x64": "0.9.4" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ] }, "sha512-yUphwzcVBuNrg1iEAE5XVPOWfCLuq/BE1scUxtHMmLo+e1KuKWBRgSKFXGjNBfL8lV3c5VGwIgK66aBqmhqVBQ=="], + + "@floating-ui/core": ["@floating-ui/core@1.7.5", "", { "dependencies": { "@floating-ui/utils": "0.2.11" } }, "sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.7.6", "", { "dependencies": { "@floating-ui/core": "1.7.5", "@floating-ui/utils": "0.2.11" } }, "sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ=="], + + "@floating-ui/react": ["@floating-ui/react@0.27.19", "", { "dependencies": { "@floating-ui/react-dom": "2.1.8", "@floating-ui/utils": "0.2.11", "tabbable": "6.4.0" }, "peerDependencies": { "react": ">=17.0.0", "react-dom": ">=17.0.0" } }, "sha512-31B8h5mm8YxotlE7/AU/PhNAl8eWxAmjL/v2QOxroDNkTFLk3Uu82u63N3b6TXa4EGJeeZLVcd/9AlNlVqzeog=="], + + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.8", "", { "dependencies": { "@floating-ui/dom": "1.7.6" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="], + + "@formkit/auto-animate": ["@formkit/auto-animate@0.9.0", "", {}, "sha512-VhP4zEAacXS3dfTpJpJ88QdLqMTcabMg0jwpOSxZ/VzfQVfl3GkZSCZThhGC5uhq/TxPHPzW0dzr4H9Bb1OgKA=="], + + "@hono/node-server": ["@hono/node-server@1.19.14", "", { "peerDependencies": { "hono": "^4" } }, "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw=="], + + "@iarna/toml": ["@iarna/toml@2.2.5", "", {}, "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="], + + "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], + + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "1.11.1" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + + "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], + + "@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "10.3.2", "@inquirer/type": "3.0.10" }, "peerDependencies": { "@types/node": "24.12.4" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="], + + "@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "1.0.2", "@inquirer/figures": "1.0.15", "@inquirer/type": "3.0.10", "cli-width": "4.1.0", "mute-stream": "2.0.0", "signal-exit": "4.1.0", "wrap-ansi": "6.2.0", "yoctocolors-cjs": "2.1.3" }, "peerDependencies": { "@types/node": "24.12.4" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="], + + "@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="], + + "@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": "24.12.4" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="], + + "@ioredis/commands": ["@ioredis/commands@1.10.0", "", {}, "sha512-UmeW7z4LfctwoQ5wkhVzgq8tXkreED2xZGpX+Bg+zA+WJFZCT6c062AfCK/Dfk81xZnnwdhJCUMkitihRaoC2Q=="], + + "@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "7.1.3" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "@isaacs/ttlcache": ["@isaacs/ttlcache@1.4.1", "", {}, "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="], + + "@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "0.27.10" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="], + + "@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "29.6.3", "@types/istanbul-lib-coverage": "2.0.6", "@types/istanbul-reports": "3.0.4", "@types/node": "24.12.4", "@types/yargs": "17.0.35", "chalk": "4.1.2" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "0.3.13", "@jridgewell/trace-mapping": "0.3.31" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "3.1.2", "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@js-temporal/polyfill": ["@js-temporal/polyfill@0.5.1", "", { "dependencies": { "jsbi": "4.3.2" } }, "sha512-hloP58zRVCRSpgDxmqCWJNlizAlUgJFqG2ypq79DCvyv9tHjRYMDOcPFjzfl/A1/YxDvRCZz8wvZvmapQnKwFQ=="], + + "@legendapp/list": ["@legendapp/list@3.3.5", "", { "dependencies": { "use-sync-external-store": "1.6.0" }, "peerDependencies": { "react": "*", "react-dom": "*", "react-native": "*" }, "optionalPeers": ["react-dom", "react-native"] }, "sha512-XTsLYtpg41SVb5uLBYA+YcDSA3w0tgoPq/W8ZggQ2tx+3lrC/rf+ehTP9KYHea9oFaZIuePAgzACs5/auVMJlQ=="], + + "@lexical/clipboard": ["@lexical/clipboard@0.41.0", "", { "dependencies": { "@lexical/html": "0.41.0", "@lexical/list": "0.41.0", "@lexical/selection": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-Ex5lPkb4NBBX1DCPzOAIeHBJFH1bJcmATjREaqpnTfxCbuOeQkt44wchezUA0oDl+iAxNZ3+pLLWiUju9icoSA=="], + + "@lexical/code": ["@lexical/code@0.41.0", "", { "dependencies": { "@lexical/utils": "0.41.0", "lexical": "0.41.0", "prismjs": "1.30.0" } }, "sha512-0hoNi1KC9/N3SBOGcOcFqnT0OpwmcRRAhfxTKMGqfCtCvAMzULVwZ8RWc9/NV9bKYESgBTW5D9xkDANP2mspHg=="], + + "@lexical/devtools-core": ["@lexical/devtools-core@0.41.0", "", { "dependencies": { "@lexical/html": "0.41.0", "@lexical/link": "0.41.0", "@lexical/mark": "0.41.0", "@lexical/table": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" }, "peerDependencies": { "react": ">=17.x", "react-dom": ">=17.x" } }, "sha512-FzJtluBhBc8bKS11TUZe72KoZN/hnzIyiiM0SPJAsPwGpoXuM01jqpXQGybWf/1bWB+bmmhOae7O4Nywi/Csuw=="], + + "@lexical/dragon": ["@lexical/dragon@0.41.0", "", { "dependencies": { "@lexical/extension": "0.41.0", "lexical": "0.41.0" } }, "sha512-gBEqkk8Q6ZPruvDaRcOdF1EK9suCVBODzOCcR+EnoJTaTjfDkCM7pkPAm4w90Wa1wCZEtFHvCfas+jU9MDSumg=="], + + "@lexical/extension": ["@lexical/extension@0.41.0", "", { "dependencies": { "@lexical/utils": "0.41.0", "@preact/signals-core": "1.14.2", "lexical": "0.41.0" } }, "sha512-sF4SPiP72yXvIGchmmIZ7Yg2XZTxNLOpFEIIzdqG7X/1fa1Ham9P/T7VbrblWpF6Ei5LJtK9JgNVB0hb4l3o1g=="], + + "@lexical/hashtag": ["@lexical/hashtag@0.41.0", "", { "dependencies": { "@lexical/text": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-tFWM74RW4KU0E/sj2aowfWl26vmLUTp331CgVESnhQKcZBfT40KJYd57HEqBDTfQKn4MUhylQCCA0hbpw6EeFQ=="], + + "@lexical/history": ["@lexical/history@0.41.0", "", { "dependencies": { "@lexical/extension": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-kGoVWsiOn62+RMjRolRa+NXZl8jFwxav6GNDiHH8yzivtoaH8n1SwUfLJELXCzeqzs81HySqD4q30VLJVTGoDg=="], + + "@lexical/html": ["@lexical/html@0.41.0", "", { "dependencies": { "@lexical/selection": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-3RyZy+H/IDKz2D66rNN/NqYx87xVFrngfEbyu1OWtbY963RUFnopiVHCQvsge/8kT04QSZ7U/DzjVFqeNS6clg=="], + + "@lexical/link": ["@lexical/link@0.41.0", "", { "dependencies": { "@lexical/extension": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-Rjtx5cGWAkKcnacncbVsZ1TqRnUB2Wm4eEVKpaAEG41+kHgqghzM2P+UGT15yROroxJu8KvAC9ISiYFiU4XE1w=="], + + "@lexical/list": ["@lexical/list@0.41.0", "", { "dependencies": { "@lexical/extension": "0.41.0", "@lexical/selection": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-RXvB+xcbzVoQLGRDOBRCacztG7V+bI95tdoTwl8pz5xvgPtAaRnkZWMDP+yMNzMJZsqEChdtpxbf0NgtMkun6g=="], + + "@lexical/mark": ["@lexical/mark@0.41.0", "", { "dependencies": { "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-UO5WVs9uJAYIKHSlYh4Z1gHrBBchTOi21UCYBIZ7eAs4suK84hPzD+3/LAX5CB7ZltL6ke5Sly3FOwNXv/wfpA=="], + + "@lexical/markdown": ["@lexical/markdown@0.41.0", "", { "dependencies": { "@lexical/code": "0.41.0", "@lexical/link": "0.41.0", "@lexical/list": "0.41.0", "@lexical/rich-text": "0.41.0", "@lexical/text": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-bzI73JMXpjGFhqUWNV6KqfjWcgAWzwFT+J3RHtbCF5rysC8HLldBYojOgAAtPfXqfxyv2mDzsY7SoJ75s9uHZA=="], + + "@lexical/offset": ["@lexical/offset@0.41.0", "", { "dependencies": { "lexical": "0.41.0" } }, "sha512-2RHBXZqC8gm3X9C0AyRb0M8w7zJu5dKiasrif+jSKzsxPjAUeF1m95OtIOsWs1XLNUgASOSUqGovDZxKJslZfA=="], + + "@lexical/overflow": ["@lexical/overflow@0.41.0", "", { "dependencies": { "lexical": "0.41.0" } }, "sha512-Iy6ZiJip8X14EBYt1zKPOrXyQ4eG9JLBEoPoSVBTiSbVd+lYicdUvaOThT0k0/qeVTN9nqTaEltBjm56IrVKCQ=="], + + "@lexical/plain-text": ["@lexical/plain-text@0.41.0", "", { "dependencies": { "@lexical/clipboard": "0.41.0", "@lexical/dragon": "0.41.0", "@lexical/selection": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-HIsGgmFUYRUNNyvckun33UQfU7LRzDlxymHUq67+Bxd5bXqdZOrStEKJXuDX+LuLh/GXZbaWNbDLqwLBObfbQg=="], + + "@lexical/react": ["@lexical/react@0.41.0", "", { "dependencies": { "@floating-ui/react": "0.27.19", "@lexical/devtools-core": "0.41.0", "@lexical/dragon": "0.41.0", "@lexical/extension": "0.41.0", "@lexical/hashtag": "0.41.0", "@lexical/history": "0.41.0", "@lexical/link": "0.41.0", "@lexical/list": "0.41.0", "@lexical/mark": "0.41.0", "@lexical/markdown": "0.41.0", "@lexical/overflow": "0.41.0", "@lexical/plain-text": "0.41.0", "@lexical/rich-text": "0.41.0", "@lexical/table": "0.41.0", "@lexical/text": "0.41.0", "@lexical/utils": "0.41.0", "@lexical/yjs": "0.41.0", "lexical": "0.41.0", "react-error-boundary": "6.1.2" }, "peerDependencies": { "react": ">=17.x", "react-dom": ">=17.x" } }, "sha512-7+GUdZUm6sofWm+zdsWAs6cFBwKNsvsHezZTrf6k8jrZxL461ZQmbz/16b4DvjCGL9r5P1fR7md9/LCmk8TiCg=="], + + "@lexical/rich-text": ["@lexical/rich-text@0.41.0", "", { "dependencies": { "@lexical/clipboard": "0.41.0", "@lexical/dragon": "0.41.0", "@lexical/selection": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-yUcr7ZaaVTZNi8bow4CK1M8jy2qyyls1Vr+5dVjwBclVShOL/F/nFyzBOSb6RtXXRbd3Ahuk9fEleppX/RNIdw=="], + + "@lexical/selection": ["@lexical/selection@0.41.0", "", { "dependencies": { "lexical": "0.41.0" } }, "sha512-1s7/kNyRzcv5uaTwsUL28NpiisqTf5xZ1zNukLsCN1xY+TWbv9RE9OxIv+748wMm4pxNczQe/UbIBODkbeknLw=="], + + "@lexical/table": ["@lexical/table@0.41.0", "", { "dependencies": { "@lexical/clipboard": "0.41.0", "@lexical/extension": "0.41.0", "@lexical/utils": "0.41.0", "lexical": "0.41.0" } }, "sha512-d3SPThBAr+oZ8O74TXU0iXM3rLbrAVC7/HcOnSAq7/AhWQW8yMutT51JQGN+0fMLP9kqoWSAojNtkdvzXfU/+A=="], + + "@lexical/text": ["@lexical/text@0.41.0", "", { "dependencies": { "lexical": "0.41.0" } }, "sha512-gGA+Anc7ck110EXo4KVKtq6Ui3M7Vz3OpGJ4QE6zJHWW8nV5h273koUGSutAMeoZgRVb6t01Izh3ORoFt/j1CA=="], + + "@lexical/utils": ["@lexical/utils@0.41.0", "", { "dependencies": { "@lexical/selection": "0.41.0", "lexical": "0.41.0" } }, "sha512-Wlsokr5NQCq83D+7kxZ9qs5yQ3dU3Qaf2M+uXxLRoPoDaXqW8xTWZq1+ZFoEzsHzx06QoPa4Vu/40BZR91uQPg=="], + + "@lexical/yjs": ["@lexical/yjs@0.41.0", "", { "dependencies": { "@lexical/offset": "0.41.0", "@lexical/selection": "0.41.0", "lexical": "0.41.0" }, "peerDependencies": { "yjs": ">=13.5.22" } }, "sha512-PaKTxSbVC4fpqUjQ7vUL9RkNF1PjL8TFl5jRe03PqoPYpE33buf3VXX6+cOUEfv9+uknSqLCPHoBS/4jN3a97w=="], + + "@libsql/client": ["@libsql/client@0.17.3", "", { "dependencies": { "@libsql/core": "0.17.3", "@libsql/hrana-client": "0.10.0", "js-base64": "3.7.8", "libsql": "0.5.29", "promise-limit": "2.7.0" } }, "sha512-HXk9wiAoJbKFbyBH4O+aEhN6ir5ERXuXvwE5OD2eR4/5RUa3Pw/8L9zrnVdU+iNJitRvisPWaIwmhkO3bH7giA=="], + + "@libsql/core": ["@libsql/core@0.17.3", "", { "dependencies": { "js-base64": "3.7.8" } }, "sha512-2UjK1i7JBkMduJo4WdvvBxMMvVJ31pArBZNONyz/GCJJAH+1UHat2X6vn10S/WpY5fKzIT98WqYFl2vzWRLOfg=="], + + "@libsql/darwin-arm64": ["@libsql/darwin-arm64@0.5.29", "", { "os": "darwin", "cpu": "arm64" }, "sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A=="], + + "@libsql/darwin-x64": ["@libsql/darwin-x64@0.5.29", "", { "os": "darwin", "cpu": "x64" }, "sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ=="], + + "@libsql/hrana-client": ["@libsql/hrana-client@0.10.0", "", { "dependencies": { "@libsql/isomorphic-ws": "0.1.5", "js-base64": "3.7.8" } }, "sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw=="], + + "@libsql/isomorphic-ws": ["@libsql/isomorphic-ws@0.1.5", "", { "dependencies": { "@types/ws": "8.18.1", "ws": "8.21.0" } }, "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg=="], + + "@libsql/linux-arm-gnueabihf": ["@libsql/linux-arm-gnueabihf@0.5.29", "", { "os": "linux", "cpu": "arm" }, "sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ=="], + + "@libsql/linux-arm-musleabihf": ["@libsql/linux-arm-musleabihf@0.5.29", "", { "os": "linux", "cpu": "arm" }, "sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg=="], + + "@libsql/linux-arm64-gnu": ["@libsql/linux-arm64-gnu@0.5.29", "", { "os": "linux", "cpu": "arm64" }, "sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w=="], + + "@libsql/linux-arm64-musl": ["@libsql/linux-arm64-musl@0.5.29", "", { "os": "linux", "cpu": "arm64" }, "sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg=="], + + "@libsql/linux-x64-gnu": ["@libsql/linux-x64-gnu@0.5.29", "", { "os": "linux", "cpu": "x64" }, "sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg=="], + + "@libsql/linux-x64-musl": ["@libsql/linux-x64-musl@0.5.29", "", { "os": "linux", "cpu": "x64" }, "sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w=="], + + "@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.29", "", { "os": "win32", "cpu": "x64" }, "sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg=="], + + "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@2.0.0", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg=="], + + "@malept/flatpak-bundler": ["@malept/flatpak-bundler@0.4.0", "", { "dependencies": { "debug": "4.4.3", "fs-extra": "9.1.0", "lodash": "4.18.1", "tmp-promise": "3.0.3" } }, "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q=="], + + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.29.0", "", { "dependencies": { "@hono/node-server": "1.19.14", "ajv": "8.20.0", "ajv-formats": "3.0.1", "content-type": "1.0.5", "cors": "2.8.6", "cross-spawn": "7.0.6", "eventsource": "3.0.7", "eventsource-parser": "3.1.0", "express": "5.2.1", "express-rate-limit": "8.5.2", "hono": "4.12.27", "jose": "6.2.3", "json-schema-typed": "8.0.2", "pkce-challenge": "5.0.1", "raw-body": "3.0.2", "zod-to-json-schema": "3.25.2" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1", "zod": "^3.25 || ^4.0" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ=="], + + "@mongodb-js/saslprep": ["@mongodb-js/saslprep@1.4.13", "", { "dependencies": { "sparse-bitfield": "3.0.3" } }, "sha512-E3Sv4eCYAlKYUTx8S3ioQcDUscOif+8zZ5OnW1IzJ+Tt+EO+ke8mn+Y3FX6N1H79picwbdOavVOb1jPi2EOyrg=="], + + "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ=="], + + "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w=="], + + "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw=="], + + "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw=="], + + "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ=="], + + "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="], + + "@mswjs/interceptors": ["@mswjs/interceptors@0.41.9", "", { "dependencies": { "@open-draft/deferred-promise": "2.2.0", "@open-draft/logger": "0.3.0", "@open-draft/until": "2.1.0", "is-node-process": "1.2.0", "outvariant": "1.4.3", "strict-event-emitter": "0.5.1" } }, "sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w=="], + + "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], + + "@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="], + + "@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="], + + "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + + "@nodable/entities": ["@nodable/entities@2.1.1", "", {}, "sha512-Pig3HxDIoMgjdEH8OCf/dkcTmLFjJRjWuq8jSnklu284/TKOPibSRERmOykiwmyXTtv61mP+44f3GMx0tLAyjg=="], + + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "1.2.0" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "1.20.1" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="], + + "@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "6.0.0", "@octokit/graphql": "9.0.3", "@octokit/request": "10.0.10", "@octokit/request-error": "7.1.0", "@octokit/types": "16.0.0", "before-after-hook": "4.0.0", "universal-user-agent": "7.0.3" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="], + + "@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "16.0.0", "universal-user-agent": "7.0.3" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], + + "@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "10.0.10", "@octokit/types": "16.0.0", "universal-user-agent": "7.0.3" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="], + + "@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], + + "@octokit/openapi-webhooks-types": ["@octokit/openapi-webhooks-types@12.1.0", "", {}, "sha512-WiuzhOsiOvb7W3Pvmhf8d2C6qaLHXrWiLBP4nJ/4kydu+wpagV5Fkz9RfQwV2afYzv3PB+3xYgp4mAdNGjDprA=="], + + "@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@14.0.0", "", { "dependencies": { "@octokit/types": "16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw=="], + + "@octokit/plugin-request-log": ["@octokit/plugin-request-log@6.0.0", "", { "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q=="], + + "@octokit/plugin-rest-endpoint-methods": ["@octokit/plugin-rest-endpoint-methods@17.0.0", "", { "dependencies": { "@octokit/types": "16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw=="], + + "@octokit/request": ["@octokit/request@10.0.10", "", { "dependencies": { "@octokit/endpoint": "11.0.3", "@octokit/request-error": "7.1.0", "@octokit/types": "16.0.0", "content-type": "2.0.0", "json-with-bigint": "3.5.8", "universal-user-agent": "7.0.3" } }, "sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w=="], + + "@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="], + + "@octokit/rest": ["@octokit/rest@22.0.1", "", { "dependencies": { "@octokit/core": "7.0.6", "@octokit/plugin-paginate-rest": "14.0.0", "@octokit/plugin-request-log": "6.0.0", "@octokit/plugin-rest-endpoint-methods": "17.0.0" } }, "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw=="], + + "@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="], + + "@octokit/webhooks": ["@octokit/webhooks@14.2.0", "", { "dependencies": { "@octokit/openapi-webhooks-types": "12.1.0", "@octokit/request-error": "7.1.0", "@octokit/webhooks-methods": "6.0.0" } }, "sha512-da6KbdNCV5sr1/txD896V+6W0iamFWrvVl8cHkBSPT+YlvmT3DwXa4jxZnQc+gnuTEqSWbBeoSZYTayXH9wXcw=="], + + "@octokit/webhooks-methods": ["@octokit/webhooks-methods@6.0.0", "", {}, "sha512-MFlzzoDJVw/GcbfzVC1RLR36QqkTLUf79vLVO3D+xn7r0QgxnFoLZgtrzxiQErAjFUOdH6fas2KeQJ1yr/qaXQ=="], + + "@open-draft/deferred-promise": ["@open-draft/deferred-promise@2.2.0", "", {}, "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA=="], + + "@open-draft/logger": ["@open-draft/logger@0.3.0", "", { "dependencies": { "is-node-process": "1.2.0", "outvariant": "1.4.3" } }, "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ=="], + + "@open-draft/until": ["@open-draft/until@2.1.0", "", {}, "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg=="], + + "@opencode-ai/sdk": ["@opencode-ai/sdk@1.15.13", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-4TwojIoQ8EG6/mVBuUVYZXiFcwNmiiytEnjnvyuvSJjGwFIlw2YIBFxtSVC3FbwwbwHT63teh1RHiQUUC4U5xw=="], + + "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], + + "@oxc-project/runtime": ["@oxc-project/runtime@0.138.0", "", {}, "sha512-yHhoXsN8tYxgdJCdD91PbySNjEEaBX/tH2OQRDXJpsQv5b184oC4/qVbU7qlblvfil/JP15Lh2HW7+HN5DS90Q=="], + + "@oxc-project/types": ["@oxc-project/types@0.138.0", "", {}, "sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA=="], + + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.57.0", "", { "os": "android", "cpu": "arm" }, "sha512-qVBsEO+KugOsCmUHcO8iqNnqc65p7PCKpCs8M66mPZ+Ri+CWbcpoQOEJBg2OTu03+0qu++NK1jj6IzvQVs0Sig=="], + + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.57.0", "", { "os": "android", "cpu": "arm64" }, "sha512-mp6PibWbao3aizijcheOeHQaYEhcUAt8pwLniYbtLfHxL/psFF0BykAwCj+s3c6qIpa8yN8keZICWrqtZ70w8g=="], + + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.57.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-T+0stuCBqmUVY+aMIvrgXhzGhHO3sD5tNiiEcYqgSdPsnukskQqn2u5qOVD0sv1l7RLdFS5Z/f5Wi9Ktyjr3Eg=="], + + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.57.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-O+3JbqWs/mCI2oi4xfhRO2IVPFJNDDEBV8Odo+ZpmsUOeKJfjXoNH7nDmBEQcDgK7NfjDIyE7kRgYSZcTLDO0A=="], + + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.57.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-pxwhxVC+JkLX9twOQ/8C/vbuOQcMZyKIDmiRDZfO7yITuVcIdZCiLRqqf4QOxb2+8FWrRXzQpm+1DBKcMpHSSQ=="], + + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-pxBU4zH2imB/MDBfth2rOMeVxXUMjRQLCazagwLARIFH3hVlxZJBlM4nSnHXaIHJK4/qezoFCIORN6AY8Mra4A=="], + + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-JAprOzt8tycYou36ZgEw14DlRHTiN8qdtKANdV3VZIRIvTI/lh/cX13c9pJ/EnDk2GT3FASH7KvCgQ2AufAifQ=="], + + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ajtjaxSaj9xl4BW7REt+Cef/ttzbAq00Bq4z7JUDZEfgFXdwSjH8K9bF+IcIJzZB9lKqMfQ4eHuSFOvvlvtqOg=="], + + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-p4Y/+RYk9Bk5WO+zHSUXAClRmZ2fbJCejMuCAsU2HhyME4jqf6Ftt/mJYEwIah1wGCBDYOB7wEGV1x5bCEZ6hA=="], + + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-By6tRALAZsno0F4zedmtG+wdMvJiJmJoXM4d3+A9zHE4HRXLqXITwRH8mgrlcXc5yJM2g2W3riRPwTYdgemZLQ=="], + + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-skYeG+RgvyzspqVEBsEprL90OYYZfoVNqB3HcCNR6QDJyXKOzfDRT3zncnHmUaFluIlBHuY23mU1b5WGgR98hA=="], + + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-FFgACrZOXAXUh5KQh2mt1CDOVOZmn+QzHP71wM9QobNwyQvoFfyAeefVUltW83g3sm7LTiH3yfFqLLVUpA5ZFQ=="], + + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.57.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Nm/BAOfQeFiiKd502mZn/GAVKJwtd0RdCg17G3Wz/WSOIQmDi3+7/SZH4BHn1Ye5KvTVH3ua8WvfwLLycNIuvA=="], + + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BiSy5Ku3mQqyxS6YIqAJgd403wEUWvI7kerfzPxc2l/txZVmZM0pSj7oDM+4bGBExowxOi7o73jEam1W0EDTZg=="], + + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BCRkJiotz5s9afLYD2LuMvzAoDYx9H17E/YbDyu4xK7l4zHDPeny9ErSXL//i/nJyaOwRk08x4b8cgJC00+JDg=="], + + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.57.0", "", { "os": "none", "cpu": "arm64" }, "sha512-4Oaxe1qrGgXfpCJ1C/ERJ2iCtV2rN1R79ga9fsfyVHfSQRu/hVW780u2KDqZWFZ/iGTHODJji0JemxqFZ63eIQ=="], + + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.57.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-MYLAsDnhdNsSGheLYhWgbk0vfIrlS84iQYun/y21fX6u0jj8iBtYtbpZMdiqYeuf8U12eVPUjVY2xE2NrCfJ0g=="], + + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.57.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-PBwdzZALJY/jcCx2E6is0yu+cuVXeySTDmwuseD+9j0mHqlRNxwlKgsyRTBed/woPeqfVfuXfWjoq4Cx2Zt3Eg=="], + + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bQJdH9i4RRfw55jm7+8/xS7GzHLLTbHx4huhrrDxQJaJtbSDbsyOnODvP1ftT7EG0KFKAYO2S+q6AcioXODx8w=="], + + "@oxlint-tsgolint/darwin-arm64": ["@oxlint-tsgolint/darwin-arm64@0.24.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C2uMmwK5Bc4ri4ysZ6sA8Rcu+A5zBQTp6ml2u0CLLbRZp4kMFPV3yWk8B5DK9Aw7y9bbjogIm75tUwGLFzlsYQ=="], + + "@oxlint-tsgolint/darwin-x64": ["@oxlint-tsgolint/darwin-x64@0.24.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Wgvt/1lRbDxmoNqWQKKcL+UIiqLmdJ+EWLpQa1qzoNVAfNB0PJpa82/8dH1twT/3rSs4zrP5TXPWl4juB71WuQ=="], + + "@oxlint-tsgolint/linux-arm64": ["@oxlint-tsgolint/linux-arm64@0.24.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-PB1rxII7KV83+ASY4sSkXtqvpij6ME66+QCRL49uksi/ofs2Rf/UVboYr095n0Rkbl2wgvlsHGl6DHC361jQUQ=="], + + "@oxlint-tsgolint/linux-x64": ["@oxlint-tsgolint/linux-x64@0.24.0", "", { "os": "linux", "cpu": "x64" }, "sha512-xcz3CxKmjTQLREtE/UShh+ruWmm9nAb7UM9zKcD65BStiuYgOakAKkPHl4YS5DztpVcDrE0+HqbOolTlRKYWmw=="], + + "@oxlint-tsgolint/win32-arm64": ["@oxlint-tsgolint/win32-arm64@0.24.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-A2i6ZGBec3i20S7RaxkgHc6r3HYtD5Mn7j/mb22NkTz14u0JuudvTu6JggAnbGMcv8+dBKQI//EasxSPJLD8pw=="], + + "@oxlint-tsgolint/win32-x64": ["@oxlint-tsgolint/win32-x64@0.24.0", "", { "os": "win32", "cpu": "x64" }, "sha512-0ZbGd9qRB6zs82moekaKdEvncRANq49EAwfNX62JpTS46feXUhKAuoyVDvZMj6Rywejylrmmu79Wo6faYCo4Ew=="], + + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.72.0", "", { "os": "android", "cpu": "arm" }, "sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA=="], + + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.72.0", "", { "os": "android", "cpu": "arm64" }, "sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ=="], + + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.72.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ=="], + + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.72.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ=="], + + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.72.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag=="], + + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.72.0", "", { "os": "linux", "cpu": "arm" }, "sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A=="], + + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.72.0", "", { "os": "linux", "cpu": "arm" }, "sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ=="], + + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.72.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ=="], + + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.72.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg=="], + + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.72.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg=="], + + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.72.0", "", { "os": "linux", "cpu": "none" }, "sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA=="], + + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.72.0", "", { "os": "linux", "cpu": "none" }, "sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ=="], + + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.72.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w=="], + + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.72.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw=="], + + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.72.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA=="], + + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.72.0", "", { "os": "none", "cpu": "arm64" }, "sha512-qkrsEn6NmgFKr7U/QnezQMb+q/vzAy0Dd9Y95gQGQTyjzDLN+HRZMuM5u70iyH4nBLCfKBzhjMsYCehKay2jyg=="], + + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.72.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg=="], + + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.72.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ=="], + + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.72.0", "", { "os": "win32", "cpu": "x64" }, "sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA=="], + + "@oxlint/plugins": ["@oxlint/plugins@1.68.0", "", {}, "sha512-titLmukUt/h8ho7Svlf0xSBjoy2ccZKrXjpXpZCj+v6V4CJccC2KyP45BLSCMx8YIpifMyiDyUptM4+5sruKbQ=="], + + "@peculiar/asn1-schema": ["@peculiar/asn1-schema@2.8.0", "", { "dependencies": { "@peculiar/utils": "2.0.3", "asn1js": "3.0.10", "tslib": "2.8.1" } }, "sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q=="], + + "@peculiar/json-schema": ["@peculiar/json-schema@1.1.12", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w=="], + + "@peculiar/utils": ["@peculiar/utils@2.0.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ=="], + + "@peculiar/webcrypto": ["@peculiar/webcrypto@1.7.1", "", { "dependencies": { "@peculiar/asn1-schema": "2.8.0", "@peculiar/json-schema": "1.1.12", "@peculiar/utils": "2.0.3", "tslib": "2.8.1", "webcrypto-core": "1.9.2" } }, "sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ=="], + + "@pierre/diffs": ["@pierre/diffs@1.3.0-beta.10", "", { "dependencies": { "@pierre/theme": "1.1.0", "@pierre/theming": "0.0.2", "@shikijs/transformers": "4.2.0", "diff": "9.0.0", "hast-util-to-html": "9.0.5", "lru_map": "0.4.1", "shiki": "4.2.0" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-efyFM9GRfI6WkmHJP0CnZBopuM8yCwGqIKbZHoe1D5PV15VDkr7Vpi8EZt40AYrN1km//utQtYhHDSwt2KwjSg=="], + + "@pierre/theme": ["@pierre/theme@1.1.0", "", {}, "sha512-GC2OWTAfTIIWWYhPCygwG8t2EtePQkRfON4MI2rwIkJylmiyqIttJID2dCL8sUD8cNdEvYkEyfEHHKMeCiDLoQ=="], + + "@pierre/theming": ["@pierre/theming@0.0.2", "", { "peerDependencies": { "@pierre/theme": "^1.1.0", "@shikijs/themes": "^3.0.0 || ^4.0.0", "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0", "shiki": "^3.0.0 || ^4.0.0" }, "optionalPeers": ["@pierre/theme", "@shikijs/themes", "react", "react-dom", "shiki"] }, "sha512-QM1M4stXfnzfaE8I8YbjXSApV8c+2dBsXJj8eYg9WTpBR/cTmCZIcfGnN4p13iRrYu2Br/R/OJfEL7uR8Qjctw=="], + + "@pierre/trees": ["@pierre/trees@1.0.0-beta.4", "", { "dependencies": { "preact": "11.0.0-beta.0", "preact-render-to-string": "6.6.5" }, "peerDependencies": { "react": "^18.3.1 || ^19.0.0", "react-dom": "^18.3.1 || ^19.0.0" } }, "sha512-OfT1yk9ne8Te5+GB5zUY8yqE6B8BqjBHQJleH4lu8ltwNpoocZl4vXt1AzlEExpxI/pp+AFX5QG+lR3JjtTEag=="], + + "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], + + "@preact/signals-core": ["@preact/signals-core@1.14.2", "", {}, "sha512-RZHdBj9ZF4n40Rp4jS052EHHjBWf96P9oNdXPfhQTovCuWY9iQn3Gq+gOTJSgBO9A/JBuPfMOWsSX/lIU9Pc/A=="], + + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="], + + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg=="], + + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.2", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA=="], + + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "1.2.6", "react-remove-scroll": "2.7.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw=="], + + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.11", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-escape-keydown": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg=="], + + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.3", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw=="], + + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.7", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw=="], + + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="], + + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.9", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ=="], + + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.5", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ=="], + + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.1.3", "", { "dependencies": { "@radix-ui/react-slot": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ=="], + + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="], + + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="], + + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.2.2", "", { "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg=="], + + "@radix-ui/react-use-effect-event": ["@radix-ui/react-use-effect-event@0.0.2", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA=="], + + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.1", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g=="], + + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ=="], + + "@react-grab/cli": ["@react-grab/cli@0.1.44", "", { "dependencies": { "agent-install": "0.0.5", "commander": "14.0.3", "ignore": "7.0.5", "ora": "9.4.0", "package-manager-detector": "1.6.0", "picocolors": "1.1.1", "prompts": "2.4.2", "tinyexec": "1.2.4" }, "bin": { "react-grab": "bin/cli.js" } }, "sha512-gMDYY2rw6OWajCcDlXSIgs2LC432YJXSb3Lm5yM187uhRgBYddoEVULi36h+IolX3r7jSb3ew7vn9FfI8NSo0A=="], + + "@react-native-menu/menu": ["@react-native-menu/menu@2.0.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-hb8Mirw6aKPGONhgo52IiNpwHtISVrgCT3rMdFX1qS7eOFNzOcQh8d2UDnaH5zVpxN+QuvWtaaiRMGFpIjzdtA=="], + + "@react-native/assets-registry": ["@react-native/assets-registry@0.85.3", "", {}, "sha512-u9ZiYP23vA2IFtdFQFmetzSmk6SM0xgKIoiOsr1hXNHjHaLhOm+/Ph1ud57wX6+Dbwdzx8coJgnzSKL3W21PCg=="], + + "@react-native/babel-plugin-codegen": ["@react-native/babel-plugin-codegen@0.85.3", "", { "dependencies": { "@babel/traverse": "7.29.7", "@react-native/codegen": "0.85.3" } }, "sha512-Wc94zGfeFG8Njf9SHMPfYZP04kjigkOps6F1TYTvd7ZVXuGxqseCDgxc50LWcOhOCLypI9n3oVVqz81C3p44ZA=="], + + "@react-native/babel-preset": ["@react-native/babel-preset@0.85.3", "", { "dependencies": { "@babel/plugin-proposal-export-default-from": "7.29.7", "@babel/plugin-syntax-dynamic-import": "7.8.3", "@babel/plugin-syntax-export-default-from": "7.29.7", "@babel/plugin-syntax-nullish-coalescing-operator": "7.8.3", "@babel/plugin-syntax-optional-chaining": "7.8.3", "@babel/plugin-transform-async-generator-functions": "7.29.7", "@babel/plugin-transform-async-to-generator": "7.29.7", "@babel/plugin-transform-block-scoping": "7.29.7", "@babel/plugin-transform-class-properties": "7.29.7", "@babel/plugin-transform-classes": "7.29.7", "@babel/plugin-transform-destructuring": "7.29.7", "@babel/plugin-transform-flow-strip-types": "7.29.7", "@babel/plugin-transform-for-of": "7.29.7", "@babel/plugin-transform-modules-commonjs": "7.29.7", "@babel/plugin-transform-named-capturing-groups-regex": "7.29.7", "@babel/plugin-transform-nullish-coalescing-operator": "7.29.7", "@babel/plugin-transform-optional-catch-binding": "7.29.7", "@babel/plugin-transform-optional-chaining": "7.29.7", "@babel/plugin-transform-private-methods": "7.29.7", "@babel/plugin-transform-private-property-in-object": "7.29.7", "@babel/plugin-transform-react-display-name": "7.29.7", "@babel/plugin-transform-react-jsx": "7.28.6", "@babel/plugin-transform-react-jsx-self": "7.29.7", "@babel/plugin-transform-react-jsx-source": "7.29.7", "@babel/plugin-transform-regenerator": "7.29.7", "@babel/plugin-transform-runtime": "7.29.7", "@babel/plugin-transform-typescript": "7.29.7", "@babel/plugin-transform-unicode-regex": "7.29.7", "@react-native/babel-plugin-codegen": "0.85.3", "babel-plugin-syntax-hermes-parser": "0.33.3", "babel-plugin-transform-flow-enums": "0.0.2", "react-refresh": "0.14.2" }, "peerDependencies": { "@babel/core": "*" } }, "sha512-fD7fxEhkJB/aF57tWoXjaAWpklfrExYZS3k6aXPP3BQ77DZY7gvf/b7dbirwjID6NVnP1JDRJyTuPBGr0K/vlw=="], + + "@react-native/codegen": ["@react-native/codegen@0.85.3", "", { "dependencies": { "@babel/parser": "7.29.7", "hermes-parser": "0.33.3", "invariant": "2.2.4", "nullthrows": "1.1.1", "tinyglobby": "0.2.17", "yargs": "17.7.2" }, "peerDependencies": { "@babel/core": "*" } }, "sha512-/JkS1lGLyzBWP1FbgDwaqEf7qShIC6pUC1M0a/YMAd/v4iqR24MRkQWe7jkYvcBQ2LpEhs5NGE9InhxSv21zCA=="], + + "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.85.3", "", { "dependencies": { "@react-native/dev-middleware": "0.85.3", "debug": "4.4.3", "invariant": "2.2.4", "metro": "0.84.4", "metro-config": "0.84.4", "metro-core": "0.84.4", "semver": "7.8.5" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "0.85.3" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-fs85dmbIqNmtzEixDb0g+q6R3Vt4H9eAt8/inIZdDKfjN76+sUJA2r1nxODQ76bU23MrIbz8sI7KFBPaWk/zQw=="], + + "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.85.3", "", {}, "sha512-uAu7rM5o/Np1zgp6fi5zM1sP1aB8DcS7DdOLcj/TkSutOAjkMqqd2lWt1/+3S7qXexRHVK5XcP+o3VXo4L/V0A=="], + + "@react-native/debugger-shell": ["@react-native/debugger-shell@0.85.3", "", { "dependencies": { "cross-spawn": "7.0.6", "debug": "4.4.3", "fb-dotslash": "0.5.8" } }, "sha512-/jRAaT9boiCttIcEwS02WPwYkUihqsjSaK/TMtHz05vT6uMgac9PaQt5kzBQLIABv5aEIa5gtrMmKVz49MjkjQ=="], + + "@react-native/dev-middleware": ["@react-native/dev-middleware@0.85.3", "", { "dependencies": { "@isaacs/ttlcache": "1.4.1", "@react-native/debugger-frontend": "0.85.3", "@react-native/debugger-shell": "0.85.3", "chrome-launcher": "0.15.2", "chromium-edge-launcher": "0.3.0", "connect": "3.7.0", "debug": "4.4.3", "invariant": "2.2.4", "nullthrows": "1.1.1", "open": "7.4.2", "serve-static": "1.16.3", "ws": "7.5.11" } }, "sha512-JYzBiT4A8w+KQt+dOD5v+ti+tDrGoPnsSTuApq3Ls4RB5sfWbDlYMyz3dbc8qBIHz9tv0sQ5+eOu6Xwqzr5AQA=="], + + "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.85.3", "", {}, "sha512-39dY2j50Q1pntejzwt3XL7vwXtrj8jcIfHq6E+gyu3jzYxZJVvMkMutQ39vSg6zinIQOX36oQDhidXUbCXzgoA=="], + + "@react-native/js-polyfills": ["@react-native/js-polyfills@0.85.3", "", {}, "sha512-U2+aMshIXf1uFn77tpBb/xhHWB9vkVrMpt7kkucAugF8hJKYTDGB587X7WwelHduK2KBfhl4giSv0rzZGoef9A=="], + + "@react-native/metro-babel-transformer": ["@react-native/metro-babel-transformer@0.85.3", "", { "dependencies": { "@react-native/babel-preset": "0.85.3", "hermes-parser": "0.33.3", "nullthrows": "1.1.1" }, "peerDependencies": { "@babel/core": "*" } }, "sha512-omuKq+r7jM4XvCMIlNMPP7Up3SyB8o5EAdZtF7YXniKyq7UOMBqhYHFqgsdOXr0lT+3ADf7VCJG3sb82jlBrrQ=="], + + "@react-native/metro-config": ["@react-native/metro-config@0.85.3", "", { "dependencies": { "@react-native/js-polyfills": "0.85.3", "@react-native/metro-babel-transformer": "0.85.3", "metro-config": "0.84.4", "metro-runtime": "0.84.4" } }, "sha512-sVo6HepUmCcpdfozEf91lA0FjpLNNZYu/Zi9FiYiAQTK8pzATXDVTqhvdxpFrQn435p5eUTSbllvbH/KN+bnyA=="], + + "@react-native/normalize-colors": ["@react-native/normalize-colors@0.85.3", "", {}, "sha512-hj0PScZEhIbcOvQV5yMKX3ha4XEIOy/SVE1Rrpp0beW0dpNLOgSC7KDxGewmDnIHK9YdQUXGY9eMEfShUMIaZw=="], + + "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.85.3", "", { "dependencies": { "invariant": "2.2.4", "nullthrows": "1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "0.85.3" }, "optionalPeers": ["@types/react"] }, "sha512-dsCjI//OIPEUJMyNHp4l7zNLVjCx7bcaRUceOCkU+IB17hkbtbGWvi7HjGFSzy7FJGmS/MOlcfpb72xXiy1Oig=="], + + "@react-navigation/core": ["@react-navigation/core@7.21.2", "", { "dependencies": { "@react-navigation/routers": "7.6.0", "escape-string-regexp": "4.0.0", "fast-deep-equal": "3.1.3", "nanoid": "3.3.12", "query-string": "7.1.3", "react-is": "19.2.7", "use-latest-callback": "0.2.6", "use-sync-external-store": "1.6.0" }, "peerDependencies": { "react": ">= 18.2.0" } }, "sha512-EsJhQnsL5NuIhXsWF7URijS5hd2AaJUREdq1fOIowlyNNQBA3jCnkGU0DkW7+eI40cQ+GXH8DQw+ci7TefLIxQ=="], + + "@react-navigation/elements": ["@react-navigation/elements@2.9.26", "", { "dependencies": { "color": "4.2.3", "use-latest-callback": "0.2.6", "use-sync-external-store": "1.6.0" }, "peerDependencies": { "@react-native-masked-view/masked-view": ">= 0.2.0", "@react-navigation/native": "^7.3.4", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0" }, "optionalPeers": ["@react-native-masked-view/masked-view"] }, "sha512-EaHSJf42MjnH5VFL+KZfQIyqJvdQWK9Z27J7WUSuIVX5NXlR925sPmhWf540DX9gD1ny8BfUGPZAuw/PO4tK2w=="], + + "@react-navigation/native": ["@react-navigation/native@7.3.4", "", { "dependencies": { "@react-navigation/core": "7.21.2", "escape-string-regexp": "4.0.0", "fast-deep-equal": "3.1.3", "nanoid": "3.3.12", "standard-navigation": "0.0.7", "use-latest-callback": "0.2.6" }, "peerDependencies": { "react": ">= 18.2.0", "react-native": "*" } }, "sha512-zyAqFLeZuaakerMMnhYqBeGAzJ+WFQUTgezP3FxSlXNwFq5XxnjP28vi2XHGqm4zg4pGWls9Ay4JKshIHUOpwA=="], + + "@react-navigation/native-stack": ["@react-navigation/native-stack@7.17.6", "", { "dependencies": { "@react-navigation/elements": "2.9.26", "color": "4.2.3", "sf-symbols-typescript": "2.2.0", "warn-once": "0.1.1" }, "peerDependencies": { "@react-navigation/native": "^7.3.4", "react": ">= 18.2.0", "react-native": "*", "react-native-safe-area-context": ">= 4.0.0", "react-native-screens": ">= 4.0.0" } }, "sha512-CnNPnlSGnrxPyHguDp/xDg5w9STMmIoI6IFZe7cpvEeD0GF/LTzvZ0gmq+hPJTm2/KIrnuPx34emCofzpht45g=="], + + "@react-navigation/routers": ["@react-navigation/routers@7.6.0", "", { "dependencies": { "nanoid": "3.3.12" } }, "sha512-lblhDXfS75jLc7G2K7BZGM+7cjqQXk13X/MA4fq/12r62zM+fBhhreLzYflSitrDDXFRJpSvJXy0ziiGU04Xow=="], + + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ=="], + + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw=="], + + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g=="], + + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA=="], + + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw=="], + + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q=="], + + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA=="], + + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg=="], + + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA=="], + + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ=="], + + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg=="], + + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.5", "", { "os": "none", "cpu": "arm64" }, "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw=="], + + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "1.1.6" }, "cpu": "none" }, "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA=="], + + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw=="], + + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA=="], + + "@rolldown/plugin-babel": ["@rolldown/plugin-babel@0.2.3", "", { "dependencies": { "picomatch": "4.0.4" }, "peerDependencies": { "@babel/core": "^7.29.0 || ^8.0.0-rc.1", "@babel/plugin-transform-runtime": "^7.29.0 || ^8.0.0-rc.1", "@babel/runtime": "^7.27.0 || ^8.0.0-rc.1", "rolldown": "^1.0.0-rc.5", "vite": "^8.0.0" }, "optionalPeers": ["@babel/plugin-transform-runtime", "@babel/runtime", "vite"] }, "sha512-+zEk16yGlz1F9STiRr6uG9hmIXb6nprjLczV/htGptYuLoCuxb+itZ03RKCEeOhBpDDd1NU7qF6x1VLMUp62bw=="], + + "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + + "@rollup/pluginutils": ["@rollup/pluginutils@5.4.0", "", { "dependencies": { "@types/estree": "1.0.9", "estree-walker": "2.0.2", "picomatch": "4.0.4" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg=="], + + "@shikijs/core": ["@shikijs/core@4.2.0", "", { "dependencies": { "@shikijs/primitive": "4.2.0", "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "10.0.2", "@types/hast": "3.0.4", "hast-util-to-html": "9.0.5" } }, "sha512-Hc87Ab1Ld/vEbZRCbwx344I5v+4RU8CVToUTRkqXL1+TjbuOp9U5Xa0M23V4GEWHxVn+yO5otb+HkQVm3ptWQQ=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "10.0.2", "oniguruma-to-es": "4.3.6" } }, "sha512-fjETeq1k5ffyXqRgS6+3hpvqseLalp1kjNfRbXpUgWR8FpZ1CmQfiNHovc5lncYjt/Vg5JK/WJEmLahjwMa0og=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "10.0.2" } }, "sha512-hTorK1dffPkpbMUk6Z+828PgRo7d07HbnizoP0hNPFjhxMHctj0Px/qoHeGMYafc6ju+u9iMldN4JbVzNQM++g=="], + + "@shikijs/langs": ["@shikijs/langs@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0" } }, "sha512-bwrVRlJ0wUhZxAbVdvBbv2TTC9yLsh4C/IO5Ofz0T8MQntgDvyVnkbjw9vi50r1kx7RCIJdnJnjZAwmAsXFLZQ=="], + + "@shikijs/primitive": ["@shikijs/primitive@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "10.0.2", "@types/hast": "3.0.4" } }, "sha512-NOq+DtUkVBJtZMVXL5A0vI0Xk8nvDYaXetFHSJFlOqjDZIVhIPRYFdGkSoElDqNuegikcc3A76SNUa8dTqtAYA=="], + + "@shikijs/themes": ["@shikijs/themes@4.2.0", "", { "dependencies": { "@shikijs/types": "4.2.0" } }, "sha512-RX8IHYeLv8Cu2W6ruc3RxUqWn0IYCqSrMBzi/uRGAmfyDNOnNO5BF/Px7o97n4XTpmFTo5GbRaazuOWj+2ak2w=="], + + "@shikijs/transformers": ["@shikijs/transformers@4.2.0", "", { "dependencies": { "@shikijs/core": "4.2.0", "@shikijs/types": "4.2.0" } }, "sha512-pKrYVNUr1oPjJvs76gkPPirDySx3GKG9O88P2Y3AQ+7AjSFws9Y+Ry/Q/6Yg6QpyigzjdQ6H5JAMNAvLXZ63dw=="], + + "@shikijs/types": ["@shikijs/types@4.2.0", "", { "dependencies": { "@shikijs/vscode-textmate": "10.0.2", "@types/hast": "3.0.4" } }, "sha512-VT/MKtlpOhEPZloSH3Pb9WCZEBDoQVMa9jedp5UAwmJOar1DVc9DRODAxmYPW9M93IK4ryuqRejFfmlvlVDemw=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@sinclair/typebox": ["@sinclair/typebox@0.27.10", "", {}, "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA=="], + + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + + "@smithy/core": ["@smithy/core@3.24.6", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-wBXDRup6UU97VKyaiRo8AssnfStPtG0oAAfpq/bC0a1YYau8pM86YB4kM6ccoVi1mS8l/UHbn9oDM+7uozr/ug=="], + + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.3.8", "", { "dependencies": { "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-5cAM+KZC02sTqDt6NaLXyu50M/GNMd1eTzDVR8Lb0BBsVtu7RWHo47VPPEEv1vt3Yub6uzr+M5FHC+GtoT0USg=="], + + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.4.6", "", { "dependencies": { "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-FEwEYJ1jlBKdhe9TPzfghEi1bP55ZeEImlDkEa62bBBYzUcnB6RUCyuiS2mqKt6ZVjUbBgcNhzfIctH+Hevx9g=="], + + "@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], + + "@smithy/node-config-provider": ["@smithy/node-config-provider@4.4.6", "", { "dependencies": { "@smithy/core": "3.24.6", "tslib": "2.8.1" } }, "sha512-M+gG6eQ0y073mSmNB+erRXJvwpsqsN72ol2w6vcd8FEKeG7pqYK0JvzfVqONkPj2ElBB2pg+cU13I850b//Wag=="], + + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.7.7", "", { "dependencies": { "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-ZAFvHXrEk6K180EVhmZVg8GU5pUH5BSFqRs27JW3j1qEFx9YyYwWFx17x/MHcjALYimGAji7qEOlF1++be+G5A=="], + + "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.5.6", "", { "dependencies": { "@smithy/core": "3.24.6", "tslib": "2.8.1" } }, "sha512-In8gYD2R66EKlGAq9QrNKVrMOGaGBD7LUNp2kUjeQ4V9zNktFIXBPmrCySr4YYo+jVeVL6CnWj26sOamcF0qIg=="], + + "@smithy/signature-v4": ["@smithy/signature-v4@5.4.6", "", { "dependencies": { "@smithy/core": "3.24.6", "@smithy/types": "4.14.3", "tslib": "2.8.1" } }, "sha512-Ojg4B6oIDlIr1R86xCDJt1zJWnYa0VINmqdjfe9qxWjdRivHalZ3iSlQgVqYbW0MdpFOC5XfHEWsnbmdnpIILQ=="], + + "@smithy/types": ["@smithy/types@4.14.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-YupL0ZWmFtJexUN2cHzkvvF/b9pKrtAIfT1o7/oY/Ppu8IYeZ+lDPM5vZdQJaSeA132dJCqojjGC9NhXeF71VQ=="], + + "@smithy/util-base64": ["@smithy/util-base64@4.4.6", "", { "dependencies": { "@smithy/core": "3.24.6", "tslib": "2.8.1" } }, "sha512-V6ApAGvCQnb7Wy1Sy60AQc+7UOEaNQxvAXBLdMi5Zzm66cmX0srvfAxDmg7BGuJ+9H9ez0PPWS/AeFgWxwGavA=="], + + "@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "2.2.0", "tslib": "2.8.1" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + + "@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "2.2.0", "tslib": "2.8.1" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + + "@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="], + + "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], + + "@stripe/stripe-js": ["@stripe/stripe-js@5.6.0", "", {}, "sha512-w8CEY73X/7tw2KKlL3iOk679V9bWseE4GzNz3zlaYxcTjmcmWOathRb0emgo/QQ3eoNzmq68+2Y2gxluAv3xGw=="], + + "@swc/helpers": ["@swc/helpers@0.5.21", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg=="], + + "@szmarczak/http-timer": ["@szmarczak/http-timer@4.0.6", "", { "dependencies": { "defer-to-connect": "2.0.1" } }, "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w=="], + + "@t3tools/client-runtime": ["@t3tools/client-runtime@workspace:packages/client-runtime"], + + "@t3tools/contracts": ["@t3tools/contracts@workspace:packages/contracts"], + + "@t3tools/desktop": ["@t3tools/desktop@workspace:apps/desktop"], + + "@t3tools/marketing": ["@t3tools/marketing@workspace:apps/marketing"], + + "@t3tools/mobile": ["@t3tools/mobile@workspace:apps/mobile"], + + "@t3tools/oxlint-plugin-t3code": ["@t3tools/oxlint-plugin-t3code@workspace:oxlint-plugin-t3code"], + + "@t3tools/scripts": ["@t3tools/scripts@workspace:scripts"], + + "@t3tools/shared": ["@t3tools/shared@workspace:packages/shared"], + + "@t3tools/ssh": ["@t3tools/ssh@workspace:packages/ssh"], + + "@t3tools/tailscale": ["@t3tools/tailscale@workspace:packages/tailscale"], + + "@t3tools/web": ["@t3tools/web@workspace:apps/web"], + + "@tabler/icons": ["@tabler/icons@3.44.0", "", {}, "sha512-Wn0AOZG9sg0L+bjfMqq4eNhC6pQjIrk94LvvWYNYkY8KH8wC3YILRzQlrnVJc4FUeMxH/AK97QsYCX35H3LndA=="], + + "@tabler/icons-react-native": ["@tabler/icons-react-native@3.44.0", "", { "dependencies": { "@tabler/icons": "3.44.0" }, "peerDependencies": { "react": ">= 16.5.1", "react-native-svg": ">= 13.0.0" } }, "sha512-/Ppp68bpl9vQQsI/c+YiDC9dnLq4JUo0YI5qP72OQMC1WmCaRzdYn3CU79q01M2L3MfXO9a8WctWN8ay1Odkow=="], + + "@tailwindcss/node": ["@tailwindcss/node@4.2.1", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "enhanced-resolve": "5.22.1", "jiti": "2.7.0", "lightningcss": "1.31.1", "magic-string": "0.30.21", "source-map-js": "1.2.1", "tailwindcss": "4.2.1" } }, "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg=="], + + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.1", "@tailwindcss/oxide-darwin-arm64": "4.2.1", "@tailwindcss/oxide-darwin-x64": "4.2.1", "@tailwindcss/oxide-freebsd-x64": "4.2.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", "@tailwindcss/oxide-linux-x64-musl": "4.2.1", "@tailwindcss/oxide-wasm32-wasi": "4.2.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw=="], + + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.1", "", { "os": "android", "cpu": "arm64" }, "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg=="], + + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw=="], + + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw=="], + + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA=="], + + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw=="], + + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ=="], + + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ=="], + + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g=="], + + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g=="], + + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.1", "", { "cpu": "none" }, "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q=="], + + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA=="], + + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ=="], + + "@tailwindcss/vite": ["@tailwindcss/vite@4.3.0", "", { "dependencies": { "@tailwindcss/node": "4.3.0", "@tailwindcss/oxide": "4.3.0", "tailwindcss": "4.3.0" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw=="], + + "@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.4.3", "", { "bin": { "intent": "bin/intent.js" } }, "sha512-OZI6QyULw0FI0wjgmeYzCIfbgPsOEzwJtCpa69XrfLMtNXLGnz3d/dIabk7frg0TmHo+Ah49w5I4KC7Tufwsvw=="], + + "@tanstack/history": ["@tanstack/history@1.162.0", "", {}, "sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA=="], + + "@tanstack/pacer": ["@tanstack/pacer@0.18.0", "", { "dependencies": { "@tanstack/devtools-event-client": "0.4.3", "@tanstack/store": "0.8.1" } }, "sha512-qhCRSFei0hokQr3xYcQXqxsRD/LKlgHCxHXtKHrQoImp4x2Zu6tUOpUGVH4y2qexIrzSu3aibQBNNfC3Eay6Mg=="], + + "@tanstack/query-core": ["@tanstack/query-core@5.100.14", "", {}, "sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew=="], + + "@tanstack/react-pacer": ["@tanstack/react-pacer@0.19.4", "", { "dependencies": { "@tanstack/pacer": "0.18.0", "@tanstack/react-store": "0.8.1" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-coj8ULAuR0qFpjAKD44gTgRuZyjxU6Xu+IX5MwwYvr4e61OtZcJshaExoOBKpCGde0Edb12jDnzzj2Im13Qm9Q=="], + + "@tanstack/react-router": ["@tanstack/react-router@1.170.10", "", { "dependencies": { "@tanstack/history": "1.162.0", "@tanstack/react-store": "0.9.3", "@tanstack/router-core": "1.171.8", "isbot": "5.1.40" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-gVmWYq0ucWr+OB97Nud0YhKa9NOipB7/QrWI7wRZJJWEL0qUS8WPqAs0vA1f3IBXZpXmf8xxzf/tl5cmo4tlmA=="], + + "@tanstack/react-store": ["@tanstack/react-store@0.8.1", "", { "dependencies": { "@tanstack/store": "0.8.1", "use-sync-external-store": "1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-XItJt+rG8c5Wn/2L/bnxys85rBpm0BfMbhb4zmPVLXAKY9POrp1xd6IbU4PKoOI+jSEGc3vntPRfLGSgXfE2Ig=="], + + "@tanstack/router-core": ["@tanstack/router-core@1.171.8", "", { "dependencies": { "@tanstack/history": "1.162.0", "cookie-es": "3.1.1", "seroval": "1.5.4", "seroval-plugins": "1.5.4" } }, "sha512-PbrTBbofFcacrH3RLgHYILRqTFnAGq+gXrXoA/vo7qUSkJpSO4GWfLtrtCahD4VayzRm19IPwcjPPLEugag6pw=="], + + "@tanstack/router-generator": ["@tanstack/router-generator@1.167.12", "", { "dependencies": { "@babel/types": "7.29.7", "@tanstack/router-core": "1.171.8", "@tanstack/router-utils": "1.162.1", "@tanstack/virtual-file-routes": "1.162.0", "jiti": "2.7.0", "magic-string": "0.30.21", "prettier": "3.8.3", "zod": "4.4.3" } }, "sha512-FGr7nn6VhjL53TUCTyDgApSkAYRxhId+v0HVQdSu0ADkNuHY+sUnYEMqiF6aN82jYWuXzrSL1xazg6/rfEP82g=="], + + "@tanstack/router-plugin": ["@tanstack/router-plugin@1.168.13", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/plugin-syntax-jsx": "7.29.7", "@babel/plugin-syntax-typescript": "7.29.7", "@babel/template": "7.29.7", "@babel/traverse": "7.29.7", "@babel/types": "7.29.7", "@tanstack/router-core": "1.171.8", "@tanstack/router-generator": "1.167.12", "@tanstack/router-utils": "1.162.1", "@tanstack/virtual-file-routes": "1.162.0", "chokidar": "5.0.0", "unplugin": "3.0.0", "zod": "4.4.3" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2 || ^2.0.0", "@tanstack/react-router": "^1.170.10", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0 || >=8.0.0", "vite-plugin-solid": "^2.11.10 || ^3.0.0-0", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-LnepwDai+TaC4K3aZeXrrKpnGoP8xGGilVGFfa5flGgC3+jCSBysb8SktidRE8eF2/iOzCQC0LIGirtMyZepSA=="], + + "@tanstack/router-utils": ["@tanstack/router-utils@1.162.1", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/generator": "7.29.7", "@babel/parser": "7.29.7", "@babel/types": "7.29.7", "ansis": "4.3.1", "babel-dead-code-elimination": "1.0.12", "diff": "8.0.3", "pathe": "2.0.3", "tinyglobby": "0.2.17" } }, "sha512-62layyTGmclHDQS/eidwKRfN1hhCKwViG7iEBcVmL0MXgcAB3OOucWCEcDDGd9Cu11H6b4QQ5oOo47MWIqwz0A=="], + + "@tanstack/store": ["@tanstack/store@0.8.1", "", {}, "sha512-PtOisLjUZPz5VyPRSCGjNOlwTvabdTBQ2K80DpVL1chGVr35WRxfeavAPdNq6pm/t7F8GhoR2qtmkkqtCEtHYw=="], + + "@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.162.0", "", {}, "sha512-uhOeFyxLcU41HzvrxsGpiWdcMbScY1EDgbZ5K7DVRMYInbLYWAC0EA/kx9wXAoSM8q82bUG2hRl8+EAjE6XAbA=="], + + "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/runtime": "7.29.7", "@types/aria-query": "5.0.4", "aria-query": "5.3.0", "dom-accessibility-api": "0.5.16", "lz-string": "1.5.0", "picocolors": "1.1.1", "pretty-format": "27.5.1" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], + + "@testing-library/user-event": ["@testing-library/user-event@14.6.1", "", { "peerDependencies": { "@testing-library/dom": ">=7.21.4" } }, "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw=="], + + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + + "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], + + "@types/aws-lambda": ["@types/aws-lambda@8.10.161", "", {}, "sha512-rUYdp+MQwSFocxIOcSsYSF3YYYC/uUpMbCY/mbO21vGqfrEYvNSoPyKYDj6RhXXpPfS0KstW9RwG3qXh9sL7FQ=="], + + "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "7.29.7", "@babel/types": "7.29.7", "@types/babel__generator": "7.27.0", "@types/babel__template": "7.4.4", "@types/babel__traverse": "7.28.0" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], + + "@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "7.29.7" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="], + + "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], + + "@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "7.29.7" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="], + + "@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "3.4.38", "@types/node": "24.12.4" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="], + + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + + "@types/cacheable-request": ["@types/cacheable-request@6.0.3", "", { "dependencies": { "@types/http-cache-semantics": "4.2.0", "@types/keyv": "3.1.4", "@types/node": "24.12.4", "@types/responselike": "1.0.3" } }, "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "4.0.2", "assertion-error": "2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + + "@types/compression": ["@types/compression@1.8.1", "", { "dependencies": { "@types/express": "5.0.6", "@types/node": "24.12.4" } }, "sha512-kCFuWS0ebDbmxs0AXYn6e2r2nrGAb5KwQhknjSPSPgJcGd8+HVSILlUyFhGqML2gk39HcG7D1ydW9/qpYkN00Q=="], + + "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], + + "@types/culori": ["@types/culori@4.0.1", "", {}, "sha512-43M51r/22CjhbOXyGT361GZ9vncSVQ39u62x5eJdBQFviI8zWp2X5jzqg7k4M6PVgDQAClpy2bUe2dtwEgEDVQ=="], + + "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "2.1.0" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + + "@types/emscripten": ["@types/emscripten@1.41.5", "", {}, "sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q=="], + + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + + "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "1.0.9" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], + + "@types/express": ["@types/express@5.0.6", "", { "dependencies": { "@types/body-parser": "1.19.6", "@types/express-serve-static-core": "5.1.3", "@types/serve-static": "2.2.0" } }, "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA=="], + + "@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.3", "", { "dependencies": { "@types/node": "24.12.4", "@types/qs": "6.15.1", "@types/range-parser": "1.2.7", "@types/send": "1.2.1" } }, "sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw=="], + + "@types/fs-extra": ["@types/fs-extra@9.0.13", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA=="], + + "@types/hammerjs": ["@types/hammerjs@2.0.46", "", {}, "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "3.0.3" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/http-cache-semantics": ["@types/http-cache-semantics@4.2.0", "", {}, "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q=="], + + "@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="], + + "@types/istanbul-lib-coverage": ["@types/istanbul-lib-coverage@2.0.6", "", {}, "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w=="], + + "@types/istanbul-lib-report": ["@types/istanbul-lib-report@3.0.3", "", { "dependencies": { "@types/istanbul-lib-coverage": "2.0.6" } }, "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA=="], + + "@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "3.0.3" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="], + + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + + "@types/keyv": ["@types/keyv@3.1.4", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "3.0.3" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/nlcst": ["@types/nlcst@2.0.3", "", { "dependencies": { "@types/unist": "3.0.3" } }, "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA=="], + + "@types/node": ["@types/node@24.12.4", "", { "dependencies": { "undici-types": "7.16.0" } }, "sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA=="], + + "@types/pngjs": ["@types/pngjs@6.0.5", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-0k5eKfrA83JOZPppLtS2C7OUtyNAl2wKNxfyYl9Q5g9lPkgBl/9hNyAu6HuEH2J4XmIv2znEpkDd0SaZVxW6iQ=="], + + "@types/qs": ["@types/qs@6.15.1", "", {}, "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw=="], + + "@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="], + + "@types/react": ["@types/react@19.2.16", "", { "dependencies": { "csstype": "3.2.3" } }, "sha512-esJiCAnl0kfpNdE69f3So4WJUXy95dLZydX0KwK46riIHDzHM7O9Vtf9xCHW0PXIqvgqNrswl522kA/5yx+F4w=="], + + "@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="], + + "@types/react-test-renderer": ["@types/react-test-renderer@19.1.0", "", { "dependencies": { "@types/react": "19.2.16" } }, "sha512-XD0WZrHqjNrxA/MaR9O22w/RNidWR9YZmBdRGI7wcnWGrv/3dA8wKCJ8m63Sn+tLJhcjmuhOi629N66W6kgWzQ=="], + + "@types/responselike": ["@types/responselike@1.0.3", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw=="], + + "@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="], + + "@types/serve-static": ["@types/serve-static@2.2.0", "", { "dependencies": { "@types/http-errors": "2.0.5", "@types/node": "24.12.4" } }, "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ=="], + + "@types/statuses": ["@types/statuses@2.0.6", "", {}, "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/webidl-conversions": ["@types/webidl-conversions@7.0.3", "", {}, "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA=="], + + "@types/whatwg-url": ["@types/whatwg-url@11.0.5", "", { "dependencies": { "@types/webidl-conversions": "7.0.3" } }, "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ=="], + + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + + "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "21.0.3" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="], + + "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], + + "@types/yauzl": ["@types/yauzl@2.10.3", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q=="], + + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260604.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260604.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260604.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260604.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260604.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260604.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260604.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260604.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-A3/9yZTt2V5NlDURcVJ4mN2YjfeQTXCRyLuENKrNdGhO+y59mC/2UDr7UvpB3Li+83TRAuhDN8SBoM+7gkHdzQ=="], + + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260604.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zs616um9UuaODLsNlCu5Aw95rFcTV4u3hVt090r6k0lVvTxfaJOv8HKA6BpIotcEYlZlMQowrMSYCCdedo7iyA=="], + + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260604.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-pOdNAf2pwc9JBjo8gUsvLs5uqg7d0AhYXfE8/3zvPKBlIZG+mTcvEWW1hPawlWxXzf/vxnP4dgYwUHAMDghhKA=="], + + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260604.1", "", { "os": "linux", "cpu": "arm" }, "sha512-IKaZL3i5HKmKqwb2IZEXW1j68fVg1HsvAaXkbrkOIG/J5Eyksu5tEnTzucrIY1oPdzgHT+y2HpDIYp2sGeHFvw=="], + + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260604.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-GjIrt6YHP3bbOWBCCE08SlBSDf84Lnjn3Td822/lOX9nm6ODlA/HI7rtGh7KzS/fxehep2Vy4dXU4Il12X1s5A=="], + + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260604.1", "", { "os": "linux", "cpu": "x64" }, "sha512-twQ7XDjsmaHIevN1MjeRYIVLUPL0fBm8A0jg1FhGYPckhTxEBiHIpJf9E//eFidAdrEHjeTSBP1jJw3GNAensg=="], + + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260604.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-QBRxaVT3SFiNfOhwYb/56ddpHWPMFdfiJ4zkFJIjaAXeZ/ssWNHM9lH7yR++GrE9VTsUZ4eVSZfOmQbzRERhgw=="], + + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260604.1", "", { "os": "win32", "cpu": "x64" }, "sha512-hR7YHoRpm88Q86gK6/IMayWUA+ROdHGzOPKK8EBp1xD/Cg2Bh5AXbut8HcyUDx/bcGQvnuht/XsW47bT3to9mg=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.1", "", {}, "sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ=="], + + "@vercel/config": ["@vercel/config@0.3.0", "", { "dependencies": { "@vercel/routing-utils": "6.2.0", "pretty-cache-header": "1.0.0", "zod": "3.25.76" }, "bin": { "config": "dist/cli.js" } }, "sha512-Tf5k5y2F478oTiQcU5R8Ntix1UejE6NdduZnI7aa1XXxjCtifX1XdRS/D2uTjiQAwIL3pLa1LSAN80ABbba+TQ=="], + + "@vercel/routing-utils": ["@vercel/routing-utils@6.2.0", "", { "dependencies": { "path-to-regexp": "6.1.0", "path-to-regexp-updated": "npm:path-to-regexp@6.3.0" }, "optionalDependencies": { "ajv": "6.15.0" } }, "sha512-YI2cGYZmJKEyGSEgf5Fw5rVuW7X1bTOQ7/pnLRNTFMH3YB3qqP5erCLCJGv2kIvNo1iQAPINHQRJj6ykEdGoPg=="], + + "@vitejs/plugin-react": ["@vitejs/plugin-react@6.0.2", "", { "dependencies": { "@rolldown/pluginutils": "1.0.1" }, "peerDependencies": { "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", "babel-plugin-react-compiler": "^1.0.0", "vite": "^8.0.0" }, "optionalPeers": ["@rolldown/plugin-babel", "babel-plugin-react-compiler"] }, "sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg=="], + + "@vitest/browser": ["@vitest/browser@4.1.9", "", { "dependencies": { "@blazediff/core": "1.9.1", "@vitest/mocker": "4.1.9", "@vitest/utils": "4.1.9", "magic-string": "0.30.21", "pngjs": "7.0.0", "sirv": "3.0.2", "tinyrainbow": "3.1.0", "ws": "8.21.0" }, "peerDependencies": { "vitest": "4.1.9" } }, "sha512-j1BKtWmPcqpMhmx/L9EPLgAJpCb0zKfwoWLmqBbxaogCXHjOwHFSEoHCBfnGtx93xKQwilZ26m+UOsHqHMkRNg=="], + + "@vitest/browser-preview": ["@vitest/browser-preview@4.1.9", "", { "dependencies": { "@testing-library/dom": "10.4.1", "@testing-library/user-event": "14.6.1", "@vitest/browser": "4.1.9" }, "peerDependencies": { "vitest": "4.1.9" } }, "sha512-a4/OrkMDb/WUnE4OOB/4FJbK3rYVO7YykqtUgcTKG4p2a0R3XcjPVu7SLRHFBs2+NIYhv5yxp1Lz3dbdGBjIow=="], + + "@vitest/expect": ["@vitest/expect@4.1.9", "", { "dependencies": { "@standard-schema/spec": "1.1.0", "@types/chai": "5.2.3", "@vitest/spy": "4.1.9", "@vitest/utils": "4.1.9", "chai": "6.2.2", "tinyrainbow": "3.1.0" } }, "sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA=="], + + "@vitest/mocker": ["@vitest/mocker@4.1.9", "", { "dependencies": { "@vitest/spy": "4.1.9", "estree-walker": "3.0.3", "magic-string": "0.30.21" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["msw", "vite"] }, "sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@4.1.9", "", { "dependencies": { "tinyrainbow": "3.1.0" } }, "sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A=="], + + "@vitest/runner": ["@vitest/runner@4.1.9", "", { "dependencies": { "@vitest/utils": "4.1.9", "pathe": "2.0.3" } }, "sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg=="], + + "@vitest/snapshot": ["@vitest/snapshot@4.1.9", "", { "dependencies": { "@vitest/pretty-format": "4.1.9", "@vitest/utils": "4.1.9", "magic-string": "0.30.21", "pathe": "2.0.3" } }, "sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA=="], + + "@vitest/spy": ["@vitest/spy@4.1.9", "", {}, "sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA=="], + + "@vitest/utils": ["@vitest/utils@4.1.9", "", { "dependencies": { "@vitest/pretty-format": "4.1.9", "convert-source-map": "2.0.0", "tinyrainbow": "3.1.0" } }, "sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA=="], + + "@voidzero-dev/vite-plus-core": ["@voidzero-dev/vite-plus-core@0.2.2", "", { "dependencies": { "@oxc-project/runtime": "0.138.0", "@oxc-project/types": "0.138.0", "lightningcss": "1.32.0", "postcss": "8.5.15" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@types/node": "24.12.4", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "publint": "^0.3.8", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "unrun": "*", "yaml": "^2.9.0" }, "optionalPeers": ["@arethetypeswrong/core", "@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "publint", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "typescript", "unplugin-unused", "unrun", "yaml"] }, "sha512-yAbKexF3npOGjg1N5EtXxun+7vdM/0x6QE5jucO/dv0LFhCAIzSN3UvLVCeamJt/Bz3jt7DLqQHEgXXrjy8drA=="], + + "@voidzero-dev/vite-plus-darwin-arm64": ["@voidzero-dev/vite-plus-darwin-arm64@0.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Wy0Shx3Waa2cQZGSrPm0cpO1Y5oNyKyC1jarv12bBcgV+4uoEBKX+ep2Nh7zwjfd8Ja4QMiePE7wciOSXxu8oQ=="], + + "@voidzero-dev/vite-plus-darwin-x64": ["@voidzero-dev/vite-plus-darwin-x64@0.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-09xcW67OvsQItVPzmF8UckI+glM3DzyQO3A98deNQ4QtUF7Mt+4/cYKKcLKg2ExRWWXGNDnVG/j7/hiLjZzynw=="], + + "@voidzero-dev/vite-plus-linux-arm64-gnu": ["@voidzero-dev/vite-plus-linux-arm64-gnu@0.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-bR6287UFNwulMiQRhbtXF8GYs9a8EjvefXf+Glm7AzbePUXnamW9cwYIj2j4Dgoje0yC4gA52UePEFjXZnJcjA=="], + + "@voidzero-dev/vite-plus-linux-arm64-musl": ["@voidzero-dev/vite-plus-linux-arm64-musl@0.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-YGtvTHT7qP4c5pZmM4kLL78/d8hj2NS150R92cR2SVOW/l9Ilq5R5WrEiMA4k5Ea3B++IJWZT5MRFI0tW9qlcg=="], + + "@voidzero-dev/vite-plus-linux-x64-gnu": ["@voidzero-dev/vite-plus-linux-x64-gnu@0.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-FvaMI/vsy4PVM+Qd73K+KM8blfCAfaoZaGaGWNrrlMryhyPThXPnHoB1AQcrKbEAWb+z2fc4zLS4sH+8uI65fw=="], + + "@voidzero-dev/vite-plus-linux-x64-musl": ["@voidzero-dev/vite-plus-linux-x64-musl@0.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-ZsMochHqXqxj2sGTJNJzz3vabppbe4BFgZAjJfsnVzkwR7jv6c5p1BM71LFWxP4qd5LL0TJT7lbeRhALlI44RQ=="], + + "@voidzero-dev/vite-plus-win32-arm64-msvc": ["@voidzero-dev/vite-plus-win32-arm64-msvc@0.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-noBNyJufux0cf18eDpQLOQUZ1Kybfx9zlr+yQ6gAnxMEsQXSvYqZgWymfRDesBE3G/0XB5bg+AUtWijp3TwVcw=="], + + "@voidzero-dev/vite-plus-win32-x64-msvc": ["@voidzero-dev/vite-plus-win32-x64-msvc@0.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-+VUui1OIaFX0tqdUAXjmoKVlujEtWVdcsFDw2Jff+D6b4LUTQaOMAaaic8nNdfZL6wEjweRREQLZi/icZAXtNQ=="], + + "@volar/kit": ["@volar/kit@2.4.28", "", { "dependencies": { "@volar/language-service": "2.4.28", "@volar/typescript": "2.4.28", "typesafe-path": "0.2.2", "vscode-languageserver-textdocument": "1.0.12", "vscode-uri": "3.1.0" }, "peerDependencies": { "typescript": "*" } }, "sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg=="], + + "@volar/language-core": ["@volar/language-core@2.4.28", "", { "dependencies": { "@volar/source-map": "2.4.28" } }, "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ=="], + + "@volar/language-server": ["@volar/language-server@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "@volar/language-service": "2.4.28", "@volar/typescript": "2.4.28", "path-browserify": "1.0.1", "request-light": "0.7.0", "vscode-languageserver": "9.0.1", "vscode-languageserver-protocol": "3.17.5", "vscode-languageserver-textdocument": "1.0.12", "vscode-uri": "3.1.0" } }, "sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw=="], + + "@volar/language-service": ["@volar/language-service@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "vscode-languageserver-protocol": "3.17.5", "vscode-languageserver-textdocument": "1.0.12", "vscode-uri": "3.1.0" } }, "sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw=="], + + "@volar/source-map": ["@volar/source-map@2.4.28", "", {}, "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ=="], + + "@volar/typescript": ["@volar/typescript@2.4.28", "", { "dependencies": { "@volar/language-core": "2.4.28", "path-browserify": "1.0.1", "vscode-uri": "3.1.0" } }, "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw=="], + + "@vscode/emmet-helper": ["@vscode/emmet-helper@2.11.0", "", { "dependencies": { "emmet": "2.4.11", "jsonc-parser": "2.3.1", "vscode-languageserver-textdocument": "1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "3.1.0" } }, "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw=="], + + "@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="], + + "@xmldom/xmldom": ["@xmldom/xmldom@0.8.13", "", {}, "sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw=="], + + "@yuuang/ffi-rs-android-arm64": ["@yuuang/ffi-rs-android-arm64@1.3.2", "", { "os": "android", "cpu": "arm64" }, "sha512-eDYLT0kVBkp7e2BwdRDmt6N1rkeDPUHDefk3ZX0/nok+GLsqfy1WBoSL3Yg7HVXN1EyW8OBVc2uK8Zq8HbmaSA=="], + + "@yuuang/ffi-rs-darwin-arm64": ["@yuuang/ffi-rs-darwin-arm64@1.3.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kRdgPaOM6TfuC5wHUwstlatk4HNie2lwSLJWQL2LiAUIJ7+96CoiWUNVhwBcFrhdfxhnWenYS6F668CV0vit8Q=="], + + "@yuuang/ffi-rs-darwin-x64": ["@yuuang/ffi-rs-darwin-x64@1.3.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-O3AlVgre8FQcZRJe44Xs7A6iDLumoPXqbw40+eJCa2gyXaXyLPdHoWrS1W9rBCa1QZRRnG7zRulPVFw8C5uo8g=="], + + "@yuuang/ffi-rs-linux-arm-gnueabihf": ["@yuuang/ffi-rs-linux-arm-gnueabihf@1.3.2", "", { "os": "linux", "cpu": "arm" }, "sha512-IXiNdTbIcTCPny5eeElijFWYeKSJjQWSjt9ZyJNdLHYiB1Np+XD6K7wNZS6EOMgMelhW1kQE62T654skGkVDIA=="], + + "@yuuang/ffi-rs-linux-arm64-gnu": ["@yuuang/ffi-rs-linux-arm64-gnu@1.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-gWFO6xufUK9lPYUqDvKa6IR243dPqdetgl9Q7HrZWaDu7wLo06QQrosw8QTzndafQnOcBKm6LoLujmGCfTgJOA=="], + + "@yuuang/ffi-rs-linux-arm64-musl": ["@yuuang/ffi-rs-linux-arm64-musl@1.3.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-lejvOSqypPziQH5rzfkDlJ6e92qhWbDutE9ttOO6z5I2k83zoh9iZhZWhaXSU5VqgQpcshRkrbtXb9gy1ft5dA=="], + + "@yuuang/ffi-rs-linux-x64-gnu": ["@yuuang/ffi-rs-linux-x64-gnu@1.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-s8VCFazaJKmgY2hgMTpWk4TtBY/zy5ovbaGgwyY0FvBD0YvyhcET4IrMsDJpHhFVTPCYfKZ1dN45clD/YiFp6g=="], + + "@yuuang/ffi-rs-linux-x64-musl": ["@yuuang/ffi-rs-linux-x64-musl@1.3.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Ahr5chfKZKWUik20bEZRug+be57LZ2yYrtolyjSRoo7A4ZniBUHBZUNWm6TD6i0CJayqyxWeVk/XiaABD8bY0w=="], + + "@yuuang/ffi-rs-win32-arm64-msvc": ["@yuuang/ffi-rs-win32-arm64-msvc@1.3.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-yhpLcj0qel5VNlpzxPZfNmi7+rEX8444QHjUP6WWLxdRfqPllROu/Cp3OpkBpw3BLdxfcDhWkjWMD5QsJN0Pvg=="], + + "@yuuang/ffi-rs-win32-ia32-msvc": ["@yuuang/ffi-rs-win32-ia32-msvc@1.3.2", "", { "os": "win32", "cpu": [ "x64", "ia32", ] }, "sha512-BFVSbdtg/7mJBw5kQFOPKFiA+SF7z3240HpzHN81Umm4Bp4dWkyx0msYn8+Q7/BBJiLQ4F6bi3Nftk58YA9r9w=="], + + "@yuuang/ffi-rs-win32-x64-msvc": ["@yuuang/ffi-rs-win32-x64-msvc@1.3.2", "", { "os": "win32", "cpu": "x64" }, "sha512-ZL5MJ76n2rjwGo26kCWW7wK6QT/cee00Rx8pfW79pz6vM6jqfhoE7zTnwFiw4aOQUes9+HUc5DeeJ3z+Vb9oLg=="], + + "@zxcvbn-ts/core": ["@zxcvbn-ts/core@3.0.4", "", { "dependencies": { "fastest-levenshtein": "1.0.16" } }, "sha512-aQeiT0F09FuJaAqNrxynlAwZ2mW/1MdXakKWNmGM1Qp/VaY6CnB/GfnMS2T8gB2231Esp1/maCWd8vTG4OuShw=="], + + "@zxcvbn-ts/language-common": ["@zxcvbn-ts/language-common@3.0.4", "", {}, "sha512-viSNNnRYtc7ULXzxrQIVUNwHAPSXRtoIwy/Tq4XQQdIknBzw4vz36lQLF6mvhMlTIlpjoN/Z1GFu/fwiAlUSsw=="], + + "abbrev": ["abbrev@4.0.0", "", {}, "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA=="], + + "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "5.0.1" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="], + + "accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "2.1.35", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="], + + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "agent-install": ["agent-install@0.0.5", "", { "dependencies": { "@iarna/toml": "2.2.5", "commander": "14.0.3", "jsonc-parser": "3.3.1", "picocolors": "1.1.1", "prompts": "2.4.2", "yaml": "2.9.0" }, "bin": { "agent-install": "bin/agent-install.mjs" } }, "sha512-nHlms9BkP8ZiY79HrwCGiA2DcNaXrAaJrCM/BEqQ7MEsSKyCk+2A76xPGylIfASZSZE0SaU3T0bNSg4rBPIJAQ=="], + + "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "3.1.3", "fast-uri": "3.1.2", "json-schema-traverse": "1.0.0", "require-from-string": "2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + + "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], + + "ajv-formats": ["ajv-formats@2.1.1", "", { "peerDependencies": { "ajv": "^8.0.0" }, "optionalPeers": ["ajv"] }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], + + "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], + + "alchemy": ["alchemy@2.0.0-beta.65", "", { "dependencies": { "@alchemy.run/node-utils": "0.0.5", "@aws-sdk/credential-providers": "3.1062.0", "@clack/prompts": "0.11.0", "@distilled.cloud/aws": "0.30.2", "@distilled.cloud/axiom": "0.30.2", "@distilled.cloud/cloudflare": "0.30.2", "@distilled.cloud/cloudflare-rolldown-plugin": "0.13.10", "@distilled.cloud/cloudflare-runtime": "0.13.10", "@distilled.cloud/cloudflare-vite-plugin": "0.13.10", "@distilled.cloud/core": "0.30.2", "@distilled.cloud/neon": "0.30.2", "@distilled.cloud/planetscale": "0.30.2", "@effect/sql-d1": "4.0.0-beta.101", "@effect/vitest": "4.0.0-beta.103", "@libsql/client": "0.17.3", "@octokit/rest": "22.0.1", "@octokit/webhooks": "14.2.0", "@smithy/node-config-provider": "4.4.6", "@smithy/shared-ini-file-loader": "4.5.6", "@smithy/types": "4.14.3", "@types/aws-lambda": "8.10.161", "aws4fetch": "1.0.20", "capnweb": "0.6.1", "fast-glob": "3.3.3", "fast-xml-parser": "5.8.0", "ink": "6.8.0", "jszip": "3.10.1", "libsodium-wrappers": "0.8.4", "mongodb": "6.21.0", "mysql2": "3.22.4", "pathe": "2.0.3", "pg": "8.21.0", "picomatch": "4.0.4", "react": "19.2.6", "rolldown": "1.1.5", "undici": "7.27.1", "yaml": "2.9.0" }, "peerDependencies": { "@aws/durable-execution-sdk-js": "^2.1.0", "@effect/platform-bun": "4.0.0-beta.103", "@effect/platform-node": "4.0.0-beta.103", "@effect/sql-pg": "4.0.0-beta.103", "drizzle-kit": "1.0.0-rc.4", "drizzle-orm": "1.0.0-rc.4", "effect": "4.0.0-beta.103", "vite": "^8.0.7", "ws": "^8.20.0" }, "optionalPeers": ["@aws/durable-execution-sdk-js", "@effect/platform-bun", "@effect/platform-node", "@effect/sql-pg", "drizzle-kit", "drizzle-orm", "vite", "ws"], "bin": { "alchemy": "bin/cli.js" } }, "sha512-BMD3twiszuYjwUcxM9M8rJrFTad9Fh8+rrN+PD+EUSpMlatVTaqmSGSpRPHIzOKSwDpBpSPLzdKmBSuef/FjyQ=="], + + "alien-signals": ["alien-signals@2.0.6", "", {}, "sha512-P3TxJSe31bUHBiblg59oU1PpaWPtmxF9GhJ/cB7OkgJ0qN/ifFSKUI25/v8ZhsT+lIG6ac8DpTOplXxORX6F3Q=="], + + "am-i-vibing": ["am-i-vibing@0.4.0", "", { "dependencies": { "process-ancestry": "0.1.0" }, "bin": { "am-i-vibing": "dist/cli.mjs" } }, "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg=="], + + "anser": ["anser@1.4.10", "", {}, "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww=="], + + "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "1.1.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], + + "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "ansis": ["ansis@4.3.1", "", {}, "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA=="], + + "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "3.0.0", "picomatch": "2.3.2" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], + + "app-builder-lib": ["app-builder-lib@26.15.6", "", { "dependencies": { "@electron/asar": "3.4.1", "@electron/fuses": "1.8.0", "@electron/get": "3.1.0", "@electron/notarize": "2.5.0", "@electron/osx-sign": "1.3.3", "@electron/rebuild": "4.0.4", "@electron/universal": "2.0.3", "@malept/flatpak-bundler": "0.4.0", "@noble/hashes": "2.2.0", "@peculiar/webcrypto": "1.7.1", "@types/fs-extra": "9.0.13", "ajv": "8.20.0", "asn1js": "3.0.10", "async-exit-hook": "2.0.1", "builder-util": "26.15.3", "builder-util-runtime": "9.7.0", "chromium-pickle-js": "0.2.0", "ci-info": "4.3.1", "debug": "4.4.3", "dotenv": "16.6.1", "dotenv-expand": "11.0.7", "ejs": "3.1.10", "electron-publish": "26.15.3", "fs-extra": "10.1.0", "hosted-git-info": "4.1.0", "isbinaryfile": "5.0.7", "jiti": "2.7.0", "js-yaml": "4.2.0", "json5": "2.2.3", "lazy-val": "1.0.5", "minimatch": "10.2.5", "pkijs": "3.4.0", "plist": "3.1.0", "proper-lockfile": "4.1.2", "resedit": "1.7.2", "semver": "7.7.4", "tar": "7.5.16", "temp-file": "3.4.0", "tiny-async-pool": "1.3.0", "unzipper": "0.12.5", "which": "5.0.0" }, "peerDependencies": { "dmg-builder": "26.15.6", "electron-builder-squirrel-windows": "26.15.6" } }, "sha512-lN6BliNJLnS2ruBdYd1j1rzd2yl4ZwKqyTtAwVznIkkadOR9cFvRz/tNQ6nd824AobnFZKhcdFrpIGDnr0PRSg=="], + + "arg": ["arg@4.1.3", "", {}, "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="], + + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + + "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="], + + "asn1js": ["asn1js@3.0.10", "", { "dependencies": { "pvtsutils": "1.3.6", "pvutils": "1.1.5", "tslib": "2.8.1" } }, "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg=="], + + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + + "astro": ["astro@7.0.3", "", { "dependencies": { "@astrojs/compiler-rs": "0.2.3", "@astrojs/internal-helpers": "0.10.0", "@astrojs/markdown-satteri": "0.3.2", "@astrojs/telemetry": "3.3.2", "@capsizecss/unpack": "4.0.1", "@clack/prompts": "1.6.0", "@oslojs/encoding": "1.1.0", "@rollup/pluginutils": "5.4.0", "am-i-vibing": "0.4.0", "aria-query": "5.3.2", "axobject-query": "4.1.0", "ci-info": "4.4.0", "clsx": "2.1.1", "common-ancestor-path": "2.0.0", "cookie": "1.1.1", "devalue": "5.8.1", "diff": "8.0.3", "dset": "3.1.4", "es-module-lexer": "2.1.0", "esbuild": "0.28.1", "flattie": "1.1.1", "fontace": "0.4.1", "get-tsconfig": "5.0.0-beta.4", "github-slugger": "2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "4.2.0", "js-yaml": "4.2.0", "jsonc-parser": "3.3.1", "magic-string": "0.30.21", "magicast": "0.5.3", "mrmime": "2.0.1", "neotraverse": "0.6.18", "obug": "2.1.3", "p-limit": "7.3.0", "p-queue": "9.3.0", "package-manager-detector": "1.6.0", "piccolore": "0.1.3", "picomatch": "4.0.4", "rehype": "13.0.2", "semver": "7.8.5", "shiki": "4.2.0", "smol-toml": "1.7.0", "svgo": "4.0.1", "tinyclip": "0.1.15", "tinyexec": "1.2.4", "tinyglobby": "0.2.17", "ultrahtml": "1.6.0", "unifont": "0.7.4", "unist-util-visit": "5.1.0", "unstorage": "1.17.5", "vfile": "6.0.3", "vite": "npm:@voidzero-dev/vite-plus-core@0.2.2", "vitefu": "1.1.3", "xxhash-wasm": "1.1.0", "yargs-parser": "22.0.0", "zod": "4.4.3" }, "optionalDependencies": { "sharp": "0.34.5" }, "peerDependencies": { "@astrojs/markdown-remark": "7.2.0" }, "optionalPeers": ["@astrojs/markdown-remark"], "bin": { "astro": "./bin/astro.mjs" } }, "sha512-CK+G+Tl2DMV1EXCwVG45vyurxf2IfRTklMxDhRKn+tst9Yl8rWXpudL62Fa6zin5Bt968FBvuyASj1aJShROZg=="], + + "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="], + + "async-exit-hook": ["async-exit-hook@2.0.1", "", {}, "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw=="], + + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "at-least-node": ["at-least-node@1.0.0", "", {}, "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="], + + "atomically": ["atomically@1.7.0", "", {}, "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w=="], + + "auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="], + + "await-lock": ["await-lock@2.2.2", "", {}, "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="], + + "aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="], + + "aws4": ["aws4@1.13.2", "", {}, "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw=="], + + "aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], + + "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + + "babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/parser": "7.29.7", "@babel/traverse": "7.29.7", "@babel/types": "7.29.7" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="], + + "babel-plugin-polyfill-corejs2": ["babel-plugin-polyfill-corejs2@0.4.17", "", { "dependencies": { "@babel/compat-data": "7.29.7", "@babel/helper-define-polyfill-provider": "0.6.8", "semver": "6.3.1" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w=="], + + "babel-plugin-polyfill-corejs3": ["babel-plugin-polyfill-corejs3@0.13.0", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "0.6.8", "core-js-compat": "3.49.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A=="], + + "babel-plugin-polyfill-regenerator": ["babel-plugin-polyfill-regenerator@0.6.8", "", { "dependencies": { "@babel/helper-define-polyfill-provider": "0.6.8" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg=="], + + "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "7.29.7" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="], + + "babel-plugin-react-native-web": ["babel-plugin-react-native-web@0.21.2", "", {}, "sha512-SPD0J6qjJn8231i0HZhlAGH6NORe+QvRSQM2mwQEzJ2Fb3E4ruWTiiicPlHjmeWShDXLcvoorOCXjeR7k/lyWA=="], + + "babel-plugin-syntax-hermes-parser": ["babel-plugin-syntax-hermes-parser@0.33.3", "", { "dependencies": { "hermes-parser": "0.33.3" } }, "sha512-/Z9xYdaJ1lC0pT9do6TqCqhOSLfZ5Ot8D5za1p+feEfWYupCOfGbhhEXN9r2ZgJtDNUNRw/Z+T2CvAGKBqtqWA=="], + + "babel-plugin-transform-flow-enums": ["babel-plugin-transform-flow-enums@0.0.2", "", { "dependencies": { "@babel/plugin-syntax-flow": "7.29.7" } }, "sha512-g4aaCrDDOsWjbm0PUUeVnkcVd6AKJsVc/MbnPhEotEpkeJQP6b8nzewohQi7+QS8UyPehOhGWn0nOwjvWpmMvQ=="], + + "babel-preset-expo": ["babel-preset-expo@56.0.15", "", { "dependencies": { "@babel/generator": "7.29.7", "@babel/helper-module-imports": "7.29.7", "@babel/plugin-proposal-decorators": "7.29.7", "@babel/plugin-proposal-export-default-from": "7.29.7", "@babel/plugin-syntax-dynamic-import": "7.8.3", "@babel/plugin-syntax-export-default-from": "7.29.7", "@babel/plugin-syntax-nullish-coalescing-operator": "7.8.3", "@babel/plugin-syntax-optional-chaining": "7.8.3", "@babel/plugin-transform-async-generator-functions": "7.29.7", "@babel/plugin-transform-async-to-generator": "7.29.7", "@babel/plugin-transform-block-scoping": "7.29.7", "@babel/plugin-transform-class-properties": "7.29.7", "@babel/plugin-transform-class-static-block": "7.29.7", "@babel/plugin-transform-classes": "7.29.7", "@babel/plugin-transform-destructuring": "7.29.7", "@babel/plugin-transform-export-namespace-from": "7.29.7", "@babel/plugin-transform-flow-strip-types": "7.29.7", "@babel/plugin-transform-for-of": "7.29.7", "@babel/plugin-transform-logical-assignment-operators": "7.29.7", "@babel/plugin-transform-modules-commonjs": "7.29.7", "@babel/plugin-transform-named-capturing-groups-regex": "7.29.7", "@babel/plugin-transform-nullish-coalescing-operator": "7.29.7", "@babel/plugin-transform-object-rest-spread": "7.29.7", "@babel/plugin-transform-optional-catch-binding": "7.29.7", "@babel/plugin-transform-optional-chaining": "7.29.7", "@babel/plugin-transform-parameters": "7.29.7", "@babel/plugin-transform-private-methods": "7.29.7", "@babel/plugin-transform-private-property-in-object": "7.29.7", "@babel/plugin-transform-react-display-name": "7.29.7", "@babel/plugin-transform-react-jsx": "7.28.6", "@babel/plugin-transform-react-jsx-development": "7.29.7", "@babel/plugin-transform-react-pure-annotations": "7.29.7", "@babel/plugin-transform-runtime": "7.29.7", "@babel/plugin-transform-typescript": "7.29.7", "@babel/plugin-transform-unicode-regex": "7.29.7", "@babel/preset-typescript": "7.29.7", "@react-native/babel-plugin-codegen": "0.85.3", "babel-plugin-react-compiler": "1.0.0", "babel-plugin-react-native-web": "0.21.2", "babel-plugin-syntax-hermes-parser": "0.33.3", "babel-plugin-transform-flow-enums": "0.0.2", "debug": "4.4.3" }, "peerDependencies": { "@babel/runtime": "^7.20.0", "expo": "*", "expo-widgets": "^56.0.18", "react-refresh": ">=0.14.0 <1.0.0" }, "optionalPeers": ["@babel/runtime", "expo", "expo-widgets"] }, "sha512-0MqbQoM6nBUbKvgu2xJ4VixZnUTGTq3HB2WwvOikdO4CiPxbQ+wGA25fOoHHSni5iEFW39wy6y1ookTWlq3wVw=="], + + "badgin": ["badgin@1.2.3", "", {}, "sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "barcode-detector": ["barcode-detector@3.2.0", "", { "dependencies": { "zxing-wasm": "3.1.0" } }, "sha512-MrT5TT058ptG5YB157pHLfXKVpp0BKEfQBOb8QvzTbatzmLDu85JJ0Gd/sCYwbwdwStJvxsYflrSN6D6E4Ndyw=="], + + "base-64": ["base-64@1.0.0", "", {}, "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "baseline-browser-mapping": ["baseline-browser-mapping@2.10.33", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw=="], + + "before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], + + "big-integer": ["big-integer@1.6.52", "", {}, "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg=="], + + "bippy": ["bippy@0.5.41", "", { "peerDependencies": { "react": ">=17.0.1" } }, "sha512-jCP2pXXLhXqPrAN+iSEFZmLI4uUM4fjSqajh0K+TmM062VehfDT3ZJNkrTGyN701Z5XMejs9qAudSqkMGhSMKg=="], + + "bluebird": ["bluebird@3.7.2", "", {}, "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="], + + "body-parser": ["body-parser@2.3.0", "", { "dependencies": { "bytes": "3.1.2", "content-type": "2.0.0", "debug": "4.4.3", "http-errors": "2.0.1", "iconv-lite": "0.7.2", "on-finished": "2.4.1", "qs": "6.15.3", "raw-body": "3.0.2", "type-is": "2.1.0" } }, "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw=="], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "boolean": ["boolean@3.2.0", "", {}, "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="], + + "bowser": ["bowser@2.14.1", "", {}, "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg=="], + + "bplist-creator": ["bplist-creator@0.1.0", "", { "dependencies": { "stream-buffers": "2.2.0" } }, "sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg=="], + + "bplist-parser": ["bplist-parser@0.3.2", "", { "dependencies": { "big-integer": "1.6.52" } }, "sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ=="], + + "brace-expansion": ["brace-expansion@1.1.15", "", { "dependencies": { "balanced-match": "1.0.2", "concat-map": "0.0.1" } }, "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browser-tabs-lock": ["browser-tabs-lock@1.3.0", "", { "dependencies": { "lodash": "4.18.1" } }, "sha512-g6nHaobTiT0eMZ7jh16YpD2kcjAp+PInbiVq3M1x6KKaEIVhT4v9oURNIpZLOZ3LQbQ3XYfNhMAb/9hzNLIWrw=="], + + "browserslist": ["browserslist@4.28.2", "", { "dependencies": { "baseline-browser-mapping": "2.10.33", "caniuse-lite": "1.0.30001793", "electron-to-chromium": "1.5.364", "node-releases": "2.0.46", "update-browserslist-db": "1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg=="], + + "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], + + "bson": ["bson@6.10.4", "", {}, "sha512-WIsKqkSC0ABoBJuT1LEX+2HEvNmNKKgnTAyd0fL8qzK4SH2i9NXg+t08YtdZp/V9IZ33cxe3iV4yM0qg8lMQng=="], + + "buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], + + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], + + "builder-util": ["builder-util@26.15.3", "", { "dependencies": { "@types/debug": "4.1.13", "builder-util-runtime": "9.7.0", "chalk": "4.1.2", "cross-spawn": "7.0.6", "debug": "4.4.3", "fs-extra": "10.1.0", "http-proxy-agent": "7.0.2", "https-proxy-agent": "7.0.6", "js-yaml": "4.2.0", "sanitize-filename": "1.6.4", "source-map-support": "0.5.21", "stat-mode": "1.0.0", "temp-file": "3.4.0", "tiny-async-pool": "1.3.0" } }, "sha512-q2hn7Mbo2nFNkVekPiHFx6Nfo3hURmES3tfBn+k5Pqxl2RkmP3QGqZUhH/q9Pch/4G05NRhPjDlVj1O8q4Txvw=="], + + "builder-util-runtime": ["builder-util-runtime@9.7.0", "", { "dependencies": { "debug": "4.4.3", "sax": "1.6.0" } }, "sha512-g/kR520giAFYkSXTzcmF3kqQq7wi8F6N6SzeDgZrqTBN+VHdmgWOyTdD1yD7AATDId/yXLvuP34CxW46/BwCdw=="], + + "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "24.12.4" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], + + "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], + + "bytestreamjs": ["bytestreamjs@2.0.1", "", {}, "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ=="], + + "cacheable-lookup": ["cacheable-lookup@5.0.4", "", {}, "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="], + + "cacheable-request": ["cacheable-request@7.0.4", "", { "dependencies": { "clone-response": "1.0.3", "get-stream": "5.2.0", "http-cache-semantics": "4.2.0", "keyv": "4.5.4", "lowercase-keys": "2.0.0", "normalize-url": "6.1.0", "responselike": "2.0.1" } }, "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg=="], + + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "1.3.0", "function-bind": "1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], + + "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "1.0.2", "get-intrinsic": "1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + + "call-me-maybe": ["call-me-maybe@1.0.2", "", {}, "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="], + + "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001793", "", {}, "sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA=="], + + "capnweb": ["capnweb@0.6.1", "", {}, "sha512-fmhV26QPd1ewf5R74h55oVZnGwIcSaRMzbfLQUy8+zOBjuTmT3KXoT8wxHvnp1m9Ht9BoUUS5ZwNLoVLfQTyBg=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], + + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "4.3.0", "supports-color": "7.2.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], + + "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "4.1.2" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], + + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "chrome-launcher": ["chrome-launcher@0.15.2", "", { "dependencies": { "@types/node": "24.12.4", "escape-string-regexp": "4.0.0", "is-wsl": "2.2.0", "lighthouse-logger": "1.4.2" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ=="], + + "chromium-edge-launcher": ["chromium-edge-launcher@0.3.0", "", { "dependencies": { "@types/node": "24.12.4", "escape-string-regexp": "4.0.0", "is-wsl": "2.2.0", "lighthouse-logger": "1.4.2", "mkdirp": "1.0.4" } }, "sha512-p03azHlGjtyRvFEee3cyvtsRYdniSkwjkzmM/KmVnqT5d7QkkwpJBhis/zCLMYdQMVJ5tt140TBNqqrZPaWeFA=="], + + "chromium-pickle-js": ["chromium-pickle-js@0.2.0", "", {}, "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw=="], + + "ci-info": ["ci-info@4.4.0", "", {}, "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg=="], + + "class-variance-authority": ["class-variance-authority@0.7.1", "", { "dependencies": { "clsx": "2.1.1" } }, "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg=="], + + "cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="], + + "cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="], + + "cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="], + + "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "8.0.0", "string-width": "8.2.1" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], + + "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "4.2.3", "strip-ansi": "6.0.1", "wrap-ansi": "7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], + + "clone-response": ["clone-response@1.0.3", "", { "dependencies": { "mimic-response": "1.0.1" } }, "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "cluster-key-slot": ["cluster-key-slot@1.1.1", "", {}, "sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw=="], + + "code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="], + + "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "2.0.1", "color-string": "1.9.1" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "1.1.4", "simple-swizzle": "0.2.4" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + + "common-ancestor-path": ["common-ancestor-path@2.0.0", "", {}, "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng=="], + + "compare-version": ["compare-version@0.1.2", "", {}, "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A=="], + + "compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": "1.54.0" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="], + + "compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "2.0.18", "debug": "2.6.9", "negotiator": "0.6.4", "on-headers": "1.1.0", "safe-buffer": "5.2.1", "vary": "1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="], + + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + + "conf": ["conf@10.2.0", "", { "dependencies": { "ajv": "8.20.0", "ajv-formats": "2.1.1", "atomically": "1.7.0", "debounce-fn": "4.0.0", "dot-prop": "6.0.1", "env-paths": "2.2.1", "json-schema-typed": "7.0.3", "onetime": "5.1.2", "pkg-up": "3.1.0", "semver": "7.8.5" } }, "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg=="], + + "connect": ["connect@3.7.0", "", { "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", "parseurl": "1.3.3", "utils-merge": "1.0.1" } }, "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ=="], + + "content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], + + "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], + + "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], + + "convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="], + + "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], + + "cookie-es": ["cookie-es@3.1.1", "", {}, "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg=="], + + "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], + + "core-js": ["core-js@3.47.0", "", {}, "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg=="], + + "core-js-compat": ["core-js-compat@3.49.0", "", { "dependencies": { "browserslist": "4.28.2" } }, "sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA=="], + + "core-util-is": ["core-util-is@1.0.2", "", {}, "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="], + + "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "4.1.1", "vary": "1.1.2" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], + + "cross-dirname": ["cross-dirname@0.1.0", "", {}, "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q=="], + + "cross-env": ["cross-env@10.1.0", "", { "dependencies": { "@epic-web/invariant": "1.0.0", "cross-spawn": "7.0.6" }, "bin": { "cross-env": "dist/bin/cross-env.js", "cross-env-shell": "dist/bin/cross-env-shell.js" } }, "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "3.1.1", "shebang-command": "2.0.0", "which": "2.0.2" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="], + + "crypto-js": ["crypto-js@4.2.0", "", {}, "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="], + + "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "1.0.0", "css-what": "6.2.2", "domhandler": "5.0.3", "domutils": "3.2.2", "nth-check": "2.1.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + + "css-tree": ["css-tree@1.1.3", "", { "dependencies": { "mdn-data": "2.0.14", "source-map": "0.6.1" } }, "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q=="], + + "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], + + "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "2.2.1" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "culori": ["culori@4.0.2", "", {}, "sha512-1+BhOB8ahCn4O0cep0Sh2l9KCOfOdY+BXJnKMHFFzDEouSr/el18QwXEMRlOj9UY5nCeA8UN3a/82rUWRBeyBw=="], + + "debounce-fn": ["debounce-fn@4.0.0", "", { "dependencies": { "mimic-fn": "3.1.0" } }, "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "2.0.2" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="], + + "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "defaults": ["defaults@1.0.4", "", { "dependencies": { "clone": "1.0.4" } }, "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A=="], + + "defer-to-connect": ["defer-to-connect@2.0.1", "", {}, "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="], + + "define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "1.0.1", "es-errors": "1.3.0", "gopd": "1.2.0" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="], + + "define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "1.1.4", "has-property-descriptors": "1.0.2", "object-keys": "1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="], + + "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="], + + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], + + "denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="], + + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="], + + "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "detect-node": ["detect-node@2.1.0", "", {}, "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g=="], + + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + + "devalue": ["devalue@5.8.1", "", {}, "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "2.0.3" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], + + "dir-compare": ["dir-compare@4.2.0", "", { "dependencies": { "minimatch": "3.1.5", "p-limit": "3.1.0" } }, "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ=="], + + "dmg-builder": ["dmg-builder@26.15.6", "", { "dependencies": { "app-builder-lib": "26.15.6", "builder-util": "26.15.3", "fs-extra": "10.1.0", "js-yaml": "4.2.0" } }, "sha512-nr5vQxEhM0REomp1qiHbc6V99yrfBZy+wUU56VXADfSOlLj8PdLqsHiRe7b+FbqKesiyv4ax+k1GVwGonYKuCg=="], + + "dnssd-advertise": ["dnssd-advertise@1.1.4", "", {}, "sha512-AmGyK9WpNf06WeP5TjHZq/wNzP76OuEeaiTlKr9E/EEelYLczywUKoqRz+DPRq/ErssjT4lU+/W7wzJW+7K/ZA=="], + + "dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "2.3.0", "domhandler": "5.0.3", "entities": "4.5.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "2.0.0", "domelementtype": "2.3.0", "domhandler": "5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "dot-prop": ["dot-prop@6.0.1", "", { "dependencies": { "is-obj": "2.0.0" } }, "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA=="], + + "dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], + + "dotenv-expand": ["dotenv-expand@11.0.7", "", { "dependencies": { "dotenv": "16.6.1" } }, "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA=="], + + "drizzle-kit": ["drizzle-kit@1.0.0-rc.4", "", { "dependencies": { "@drizzle-team/brocli": "0.12.0", "@js-temporal/polyfill": "0.5.1", "esbuild": "0.25.12", "get-tsconfig": "4.14.0", "jiti": "2.7.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-KZCpjRyu+oYHLj/UJogfFlOkWhHVkaEI2EOT1U3NDVXUzLoTyPjqwFxwOrlQxsY6jzRyxcz4EacqboGfhEeYrA=="], + + "drizzle-orm": ["drizzle-orm@1.0.0-rc.4", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@effect/sql-d1": ">=4.0.0-beta.83 || >=4.0.0", "@effect/sql-libsql": ">=4.0.0-beta.83 || >=4.0.0", "@effect/sql-mysql2": ">=4.0.0-beta.83 || >=4.0.0", "@effect/sql-pg": "4.0.0-beta.103", "@effect/sql-pglite": ">=4.0.0-beta.83 || >=4.0.0", "@effect/sql-sqlite-bun": "4.0.0-beta.103", "@effect/sql-sqlite-do": ">=4.0.0-beta.83 || >=4.0.0", "@effect/sql-sqlite-node": ">=4.0.0-beta.83 || >=4.0.0", "@effect/sql-sqlite-wasm": ">=4.0.0-beta.83 || >=4.0.0", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@sinclair/typebox": ">=0.34.8", "@sqlitecloud/drivers": ">=1.0.653", "@tidbcloud/serverless": "*", "@tursodatabase/database": ">=0.6.0-pre.28 || >=0.6.0", "@tursodatabase/database-common": ">=0.6.0-pre.28 || >=0.6.0", "@tursodatabase/database-wasm": ">=0.6.0-pre.28 || >=0.6.0", "@tursodatabase/serverless": ">=1.1.3", "@tursodatabase/sync": ">=0.6.0-pre.28 || >=0.6.0", "@types/better-sqlite3": "*", "@types/mssql": "^9.1.4", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "arktype": ">=2.0.0", "better-sqlite3": ">=9.3.0", "bun-types": "*", "effect": "4.0.0-beta.103", "expo-sqlite": ">=14.0.0", "mssql": "^11.0.1", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5", "typebox": ">=1.0.0", "valibot": ">=1.0.0-beta.7", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@effect/sql-d1", "@effect/sql-libsql", "@effect/sql-mysql2", "@effect/sql-pg", "@effect/sql-pglite", "@effect/sql-sqlite-bun", "@effect/sql-sqlite-do", "@effect/sql-sqlite-node", "@effect/sql-sqlite-wasm", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@sinclair/typebox", "@sqlitecloud/drivers", "@tidbcloud/serverless", "@tursodatabase/database", "@tursodatabase/database-common", "@tursodatabase/database-wasm", "@tursodatabase/serverless", "@tursodatabase/sync", "@types/better-sqlite3", "@types/mssql", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "arktype", "better-sqlite3", "bun-types", "effect", "expo-sqlite", "mssql", "mysql2", "pg", "postgres", "sql.js", "sqlite3", "typebox", "valibot", "zod"] }, "sha512-BT+pf+qoiYHqltoA88Jmf6ilGMXPlpfE0hEJKc2adRtMCAl25Swk/t5gXcWxZNAwdtf3F5gCd2FpeOyP/pT0Hw=="], + + "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], + + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "1.0.2", "es-errors": "1.3.0", "gopd": "1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], + + "duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "2.3.8" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="], + + "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], + + "effect": ["effect@4.0.0-beta.103", "", { "dependencies": { "@standard-schema/spec": "1.1.0", "fast-check": "4.9.0", "find-my-way-ts": "0.1.6", "ini": "7.0.0", "kubernetes-types": "1.30.0", "msgpackr": "2.0.4", "multipasta": "0.2.8", "toml": "4.3.0", "uuid": "14.0.1", "yaml": "2.9.0" } }, "sha512-pE8TxF4m2tQzVI+77dIlm3s+81TACV1AiX1JEkvY+zVuxgQQ8aGSkqXNJF6b/ST+coCSk5cUdbULpQ7sm4oHyw=="], + + "effect-acp": ["effect-acp@workspace:packages/effect-acp"], + + "effect-codex-app-server": ["effect-codex-app-server@workspace:packages/effect-codex-app-server"], + + "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "10.9.4" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], + + "electron": ["electron@41.5.0", "", { "dependencies": { "@electron/get": "2.0.3", "@types/node": "24.12.4", "extract-zip": "2.0.1" }, "bin": { "electron": "cli.js" } }, "sha512-x9j9//PubUA4EjDtQbZhtk3prolandqCKgit0uCIqc1jb8FTskPbnJtxcDFB1aejczJcuERgjPixBUaMwoWyJg=="], + + "electron-builder": ["electron-builder@26.15.6", "", { "dependencies": { "app-builder-lib": "26.15.6", "builder-util": "26.15.3", "builder-util-runtime": "9.7.0", "chalk": "4.1.2", "ci-info": "4.4.0", "dmg-builder": "26.15.6", "fs-extra": "10.1.0", "lazy-val": "1.0.5", "simple-update-notifier": "2.0.0", "yargs": "17.7.2" }, "bin": { "electron-builder": "./cli.js", "install-app-deps": "./install-app-deps.js" } }, "sha512-jxlHRjqYrlTgLVo/aoACGpiki3QFYv8s4f2djsqaEbwTBZ9PcTBK03Tj/HMa65kiE0hdZxxbZdmVFo22eou2wA=="], + + "electron-builder-squirrel-windows": ["electron-builder-squirrel-windows@26.15.6", "", { "dependencies": { "app-builder-lib": "26.15.6", "builder-util": "26.15.3", "electron-winstaller": "5.4.0" } }, "sha512-Vgw0bVXtTjZmD3O0Wl1gbo4eiI0Mqp7FQBsFgMR+wNwySiPJ08jadS0PZiSwP2cKCVaEclBHbKeBVTwil+SJfQ=="], + + "electron-publish": ["electron-publish@26.15.3", "", { "dependencies": { "@types/fs-extra": "9.0.13", "aws4": "1.13.2", "builder-util": "26.15.3", "builder-util-runtime": "9.7.0", "chalk": "4.1.2", "form-data": "4.0.5", "fs-extra": "10.1.0", "lazy-val": "1.0.5", "mime": "2.6.0" } }, "sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q=="], + + "electron-store": ["electron-store@8.2.0", "", { "dependencies": { "conf": "10.2.0", "type-fest": "2.19.0" } }, "sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.364", "", {}, "sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw=="], + + "electron-updater": ["electron-updater@6.8.3", "", { "dependencies": { "builder-util-runtime": "9.5.1", "fs-extra": "10.1.0", "js-yaml": "4.2.0", "lazy-val": "1.0.5", "lodash.escaperegexp": "4.1.2", "lodash.isequal": "4.5.0", "semver": "7.7.4", "tiny-typed-emitter": "2.1.0" } }, "sha512-Z6sgw3jgbikWKXei1ENdqFOxBP0WlXg3TtKfz0rgw2vIZFJUyI4pD7ZN7jrkm7EoMK+tcm/qTnPUdqfZukBlBQ=="], + + "electron-winstaller": ["electron-winstaller@5.4.0", "", { "dependencies": { "@electron/asar": "3.4.1", "debug": "4.4.3", "fs-extra": "7.0.1", "lodash": "4.18.1", "temp": "0.9.4" }, "optionalDependencies": { "@electron/windows-sign": "1.2.2" } }, "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg=="], + + "emmet": ["emmet@2.4.11", "", { "dependencies": { "@emmetio/abbreviation": "2.3.3", "@emmetio/css-abbreviation": "2.1.8" } }, "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ=="], + + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], + + "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], + + "enhanced-resolve": ["enhanced-resolve@5.22.1", "", { "dependencies": { "graceful-fs": "4.2.11", "tapable": "2.3.3" } }, "sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww=="], + + "entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + + "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], + + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], + + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], + + "es-module-lexer": ["es-module-lexer@2.1.0", "", {}, "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="], + + "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "1.3.0", "get-intrinsic": "1.3.0", "has-tostringtag": "1.0.2", "hasown": "2.0.4" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], + + "es-toolkit": ["es-toolkit@1.47.0", "", {}, "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw=="], + + "es6-error": ["es6-error@4.1.1", "", {}, "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg=="], + + "es6-promise": ["es6-promise@3.3.1", "", {}, "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg=="], + + "esbuild": ["esbuild@0.28.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.1", "@esbuild/android-arm": "0.28.1", "@esbuild/android-arm64": "0.28.1", "@esbuild/android-x64": "0.28.1", "@esbuild/darwin-arm64": "0.28.1", "@esbuild/darwin-x64": "0.28.1", "@esbuild/freebsd-arm64": "0.28.1", "@esbuild/freebsd-x64": "0.28.1", "@esbuild/linux-arm": "0.28.1", "@esbuild/linux-arm64": "0.28.1", "@esbuild/linux-ia32": "0.28.1", "@esbuild/linux-loong64": "0.28.1", "@esbuild/linux-mips64el": "0.28.1", "@esbuild/linux-ppc64": "0.28.1", "@esbuild/linux-riscv64": "0.28.1", "@esbuild/linux-s390x": "0.28.1", "@esbuild/linux-x64": "0.28.1", "@esbuild/netbsd-arm64": "0.28.1", "@esbuild/netbsd-x64": "0.28.1", "@esbuild/openbsd-arm64": "0.28.1", "@esbuild/openbsd-x64": "0.28.1", "@esbuild/openharmony-arm64": "0.28.1", "@esbuild/sunos-x64": "0.28.1", "@esbuild/win32-arm64": "0.28.1", "@esbuild/win32-ia32": "0.28.1", "@esbuild/win32-x64": "0.28.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], + + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "1.0.9" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + + "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + + "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + + "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "3.1.0" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], + + "eventsource-parser": ["eventsource-parser@3.1.0", "", {}, "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg=="], + + "expect-type": ["expect-type@1.4.0", "", {}, "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA=="], + + "expo": ["expo@56.0.12", "", { "dependencies": { "@babel/runtime": "7.29.7", "@expo/cli": "56.1.16", "@expo/config": "56.0.9", "@expo/config-plugins": "56.0.9", "@expo/devtools": "56.0.2", "@expo/fingerprint": "0.19.4", "@expo/local-build-cache-provider": "56.0.8", "@expo/log-box": "56.0.13", "@expo/metro": "56.0.0", "@expo/metro-config": "56.0.14", "@ungap/structured-clone": "1.3.1", "babel-preset-expo": "56.0.15", "expo-asset": "56.0.17", "expo-constants": "56.0.18", "expo-file-system": "56.0.8", "expo-font": "56.0.7", "expo-keep-awake": "56.0.3", "expo-modules-autolinking": "56.0.16", "expo-modules-core": "56.0.17", "pretty-format": "29.7.0", "react-refresh": "0.14.2", "whatwg-url-minimum": "0.1.2" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-dom": "*", "react-native": "*", "react-native-web": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-dom", "react-native-web", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-FxgdI/Yqva6iJOThZIHfvxlKPxs4EC4uScUnEswwSArR/Fj9k430O13R590LcOQTsdNsjIs+GBHwjfoAY6vmAQ=="], + + "expo-application": ["expo-application@56.0.3", "", { "peerDependencies": { "expo": "*" } }, "sha512-DdGGPlMuM6cSTeKhbvh6OeLr2O/+EI5BHKYrD+Do8sJPYgLwzGrgESELfyjJCpEhFzT+TgKIdmLmWXhNUQnHiw=="], + + "expo-asset": ["expo-asset@56.0.17", "", { "dependencies": { "@expo/image-utils": "0.10.1", "expo-constants": "56.0.18" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-GFN5j+8SPkyv0nfsiFHewmdB/D0tL237TsBE/gSfFOFy/J3a52py7IulcSqkA3sQE/u/UlD5BmvP5ssS4//nUg=="], + + "expo-auth-session": ["expo-auth-session@56.0.14", "", { "dependencies": { "expo-application": "56.0.3", "expo-constants": "56.0.18", "expo-crypto": "56.0.4", "expo-linking": "56.0.14", "expo-web-browser": "56.0.5", "invariant": "2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-b6URDBKXVWBjHwypnbCPW6A3PrwYyFqzLXtTrrpTGpmDlsxk7xuz6wIA77sBNziz3hMxt11Nu70iY0fJZYT4jA=="], + + "expo-blur": ["expo-blur@56.0.3", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-KDDtrpWc2tYlm1WCPaOgBtv+YEGqe5ELheFPIgSNgHt28NQUDcfBcFsA9Us2StDh6osmSD6NbKxOt5bU6PcDbQ=="], + + "expo-build-properties": ["expo-build-properties@56.0.19", "", { "dependencies": { "@expo/schema-utils": "56.0.1", "resolve-from": "5.0.0", "semver": "7.8.5" }, "peerDependencies": { "expo": "*" } }, "sha512-InoviXcxWosNp4cC7L3SWoiY99Xr2HdgN+LYHb6mUm/BBVxy1mIMrZR+3PJ2gwDZzW6EJNDz8ioASWGHBTmzpA=="], + + "expo-camera": ["expo-camera@56.0.8", "", { "dependencies": { "barcode-detector": "3.2.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-UDOpUUMisFRmCv1XQV1MJCKGAH2CsIC1Rs6P9Bbc6JLVmbxEKAd5dK68y6cScOdWURxVfJ0PRcjYnSuc8ayyIQ=="], + + "expo-clipboard": ["expo-clipboard@56.0.4", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-qb4DYlkiowHYHaUYVT2FN9nk/nI1xShXOUYsI7J9dVpQCOHcGFjCBPX1VAvEW4Ye4/Aagd6IuhOVAq/+scBOiA=="], + + "expo-constants": ["expo-constants@56.0.18", "", { "dependencies": { "@expo/env": "2.3.0" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-8AMtbDGl/WVPnWlmbpGmvcdnNCy9E4PFnwdVwj600vljkMDPSxcAcjw8GVXEPk3PpZ+ngTqsrkltWyj0UKYAxw=="], + + "expo-crypto": ["expo-crypto@56.0.4", "", { "peerDependencies": { "expo": "*" } }, "sha512-fRNEhoXRXgAWBpe3/hq5X+KXTit3OZqdiAGts1YvNEUHQb+H5591mpPac0Yw+sZg9pXcrjRnzo5AxvZaENpc7g=="], + + "expo-dev-client": ["expo-dev-client@56.0.20", "", { "dependencies": { "expo-dev-launcher": "56.0.20", "expo-dev-menu": "56.0.17", "expo-dev-menu-interface": "56.0.1", "expo-manifests": "56.0.4", "expo-updates-interface": "56.0.2" }, "peerDependencies": { "expo": "*" } }, "sha512-KebW4r8HhIiRrPzs6ZqVhp/so8buyglAO1h4No0Ibr5C2XRnlIoGWCN4zC6rW7IsI3iKUXcofLAQV9OjoxjiwQ=="], + + "expo-dev-launcher": ["expo-dev-launcher@56.0.20", "", { "dependencies": { "@expo/schema-utils": "56.0.1", "expo-dev-menu": "56.0.17", "expo-manifests": "56.0.4" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-cTuC3GkPl9CTwO3CKnVmEm9qoQ0WairhwvTh6qMlg+zr/QU/tdiU++uDBX67hf9+FuxQOkWGp5khFNosT+0cIg=="], + + "expo-dev-menu": ["expo-dev-menu@56.0.17", "", { "dependencies": { "expo-dev-menu-interface": "56.0.1" }, "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-OofRkOOZnaDriSav3JDN4NP2lsLt2eOa/Ryptr5nMD62SwnFyK4R6n6PkPVaDU3LSsZqndAJHmN6inS+oziayQ=="], + + "expo-dev-menu-interface": ["expo-dev-menu-interface@56.0.1", "", { "peerDependencies": { "expo": "*" } }, "sha512-odATx0ZL/Kis10sKSBiKiGQxAB6coSi/KQtKcMhnQVNno6FkRh5/4e5BqcEvpq2rNMTiQp4ytNAQHtdwbPXvGA=="], + + "expo-device": ["expo-device@56.0.4", "", { "dependencies": { "ua-parser-js": "0.7.41" }, "peerDependencies": { "expo": "*" } }, "sha512-ucVcGPkvBrl2QHuy7XcYex2Y6BETvJ6TREutZrwLGUDnlvbpKS8KfQoNZOpvkyo5Nmm9RrasYQ0CrXmBHho2mg=="], + + "expo-eas-client": ["expo-eas-client@56.0.1", "", {}, "sha512-r8h0ZIExacCrSRgY+ARfhMvFqosLHLJt1L7jyhvabfr1DN/ZDKDsYbovss2tzkpEUZGxZ3BPcB5epCwUsBBdOA=="], + + "expo-file-system": ["expo-file-system@56.0.8", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-NrH41/8snGIBSbYicwVLB4txPdgCATd7ZYhMAGS3YJZ9GbnduhlAoV4/YCbGayjrbpE9bJb/6wegPL/zmvRMnQ=="], + + "expo-font": ["expo-font@56.0.7", "", { "dependencies": { "fontfaceobserver": "2.3.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-hpU/vRwPzsby9lPGkA4blDqLIIXYzoWnCZHr6PxvcWbY/uPObAiyhh6q+e0WYsB65SthK+PLH95jEnVag7fwEg=="], + + "expo-glass-effect": ["expo-glass-effect@56.0.4", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-xI9rXtDwi7RW82uAlfyaXO6+k21ApWJ2tHAWYqPr/FjfmZbKsgNJ4Q0iZzGPCwboqjTGxaRZ61SZxBl8hDt5iA=="], + + "expo-haptics": ["expo-haptics@56.0.3", "", { "peerDependencies": { "expo": "*" } }, "sha512-ycoahZJnR9tWAVh/0mJYxbETtHRYaWjiWS8cHlP6aDGU6Q6Y8rZ5NKsuBwWw6HR2Pe30mfVFgbF2HrBR6gtYmw=="], + + "expo-image": ["expo-image@56.0.11", "", { "dependencies": { "sf-symbols-typescript": "2.2.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*", "react-native-web": "*" }, "optionalPeers": ["react-native-web"] }, "sha512-k2xwxGk14xi6zxmEGAU4rUTb1lK5qf0y0Qb8+Jaggnul0KaJJxcq9qvyDp9iyJBW35cp9isONAUnNtIiooZ/Pw=="], + + "expo-image-loader": ["expo-image-loader@56.0.3", "", { "peerDependencies": { "expo": "*" } }, "sha512-JgUo4fUeU1ZC+z8iBFj8v7yoGQnZrLbOVPyNE+DWVrld55F2F6R1ck+rmdm/8TNWLz1LhNQfD7c3XYP1ZikxXA=="], + + "expo-image-picker": ["expo-image-picker@56.0.18", "", { "dependencies": { "expo-image-loader": "56.0.3" }, "peerDependencies": { "expo": "*" } }, "sha512-sCjQ8M27bhGUv2vUavIE+uWdYo79b2D7Q5h9B66BSDZ+Rd8YyLVSf7vYGfIzQ7nMVoENZ6c4xo/JiDkEeQ9iTg=="], + + "expo-json-utils": ["expo-json-utils@56.0.0", "", {}, "sha512-lUqyv9aIGDbYTQ5Nux2FnH2/Dz0w5uJ8Pr080eS0StXi2jr5OmuMNErpzUnpfnYOU55xKotd4AHv68PfV/ludg=="], + + "expo-keep-awake": ["expo-keep-awake@56.0.3", "", { "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-CLMJXtEiMKknD3Rpm8CRwE6ZJUzu2yCEmRk1sgfHAJ1zIbuEWY3dpPDubtsnuzWm+2k6Sru+yaFbYsvPWmTiBA=="], + + "expo-linking": ["expo-linking@56.0.14", "", { "dependencies": { "expo-constants": "56.0.18", "invariant": "2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-IvVQHWC+Cj4fK5qD3iEVYqpU2a4rLW0IpAAlGJ4MH+H1fyZiHh3eN6qg2WmoclOEPfYATSuEa+dQT6wfgVpXlQ=="], + + "expo-manifests": ["expo-manifests@56.0.4", "", { "dependencies": { "expo-json-utils": "56.0.0" }, "peerDependencies": { "expo": "*" } }, "sha512-Fokawl2UkiExIF0bqGoblRFA8lYpROVD+EpvDwSW4LgqQyPwNua1gLSgHZjdl5GsVugfRMMWE3LHaibDyX93hw=="], + + "expo-modules-autolinking": ["expo-modules-autolinking@56.0.16", "", { "dependencies": { "@expo/require-utils": "56.1.3", "@expo/spawn-async": "1.8.0", "chalk": "4.1.2", "commander": "7.2.0" }, "bin": { "expo-modules-autolinking": "bin/expo-modules-autolinking.js" } }, "sha512-9JnL4N46P8ubDpDIfWolDn7nxU2j1rY67xY/dNVuyH0m+HG+r/JI16VYtjIf4COpZtEuFo4D3h3MBeFzGucMnw=="], + + "expo-modules-core": ["expo-modules-core@56.0.17", "", { "dependencies": { "@expo/expo-modules-macros-plugin": "0.2.2", "expo-modules-jsi": "56.0.10", "invariant": "2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-worklets": "^0.7.4 || ^0.8.0" }, "optionalPeers": ["react-native-worklets"] }, "sha512-5J8whnT7Ccp+BrFClLmpF76omBqn95VZExroTm01Dgjm4vpty1Rb7U3we+ZUceNHtRd07Lw30u7FNfDgIhEbRQ=="], + + "expo-modules-jsi": ["expo-modules-jsi@56.0.10", "", { "peerDependencies": { "react-native": "*" } }, "sha512-fHZcFpYO/o62GYa6fJyAQJZcAShzhoN0iMMDzbr7vD3ewET6e1vAlTonbEakN9F0VHEgBFJ4NREy87uwVcpCuA=="], + + "expo-network": ["expo-network@56.0.5", "", { "peerDependencies": { "expo": "*", "react": "*" } }, "sha512-zmuyO95jayDY9jyUfOAlNp9XXJrJaAOkBXXLy0TS/nh2kppj7CHirRPkQ/tf0rsxhIL3AEd9nsRTiPtNsGT9Lw=="], + + "expo-notifications": ["expo-notifications@56.0.18", "", { "dependencies": { "@expo/image-utils": "0.10.1", "abort-controller": "3.0.0", "badgin": "1.2.3", "expo-application": "56.0.3", "expo-constants": "56.0.18" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-HHnrwyCLC5srFojcHYS2KskbNroy9o2fwPKdyhjrdjjrBu4sNRKm4LepcuZjDy98cZKEm89WIPW8O45vut8Rgw=="], + + "expo-paste-input": ["expo-paste-input@0.1.15", "", { "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-wV0z1s0/Q4MB+lNiSwbMfck+1Im6sDIcgyCi5Y0aF35n5kcM4FHSOjmRfzn3UbkMlvxmYfDiHeHvIqn22qatqA=="], + + "expo-quick-actions": ["expo-quick-actions@6.0.2", "", { "dependencies": { "@expo/image-utils": "0.8.14", "schema-utils": "4.3.3", "sf-symbols-typescript": "2.2.0" }, "peerDependencies": { "expo": "*" } }, "sha512-IVoTMCx55MjSnPqUEb5jhePpOAUdOTonifY3QXM/DBFxc6qMzBy5iJWEkfDZcFAzFzahK1ZW9tFaNv4pi2AAvQ=="], + + "expo-secure-store": ["expo-secure-store@56.0.4", "", { "peerDependencies": { "expo": "*" } }, "sha512-hjEi/gmpdFFJ9lYbdp3k3p/WchV7Gi0Qt8jt/m/0WJadqQrskafHAlDxbZkII1cN3Yd7zp9Lvkeq3UfGhSwirQ=="], + + "expo-server": ["expo-server@56.0.5", "", {}, "sha512-SmM2p2g3Jrktpiazcst+OxhjSzOHXKAY4BPURHYHXvApzzoybMmrNF4IEZ8DKZ145BhSe4ydAmlEFCRTsdtgUQ=="], + + "expo-sharing": ["expo-sharing@56.0.18", "", { "dependencies": { "@expo/config-plugins": "56.0.9", "@expo/config-types": "56.0.6", "@expo/plist": "0.7.0" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-45w4BWNFmdTczp+fJX6YfwJrn9sX+VeRWz2VWLhauygcCrym44HtVDXX5yVYPB9TW9ZesLcEI+CCrCBNWL7smQ=="], + + "expo-splash-screen": ["expo-splash-screen@56.0.10", "", { "dependencies": { "@expo/config-plugins": "56.0.9", "@expo/image-utils": "0.10.1", "xml2js": "0.6.0" }, "peerDependencies": { "expo": "*" } }, "sha512-vDIlo8hzt9HlCZQ0kSY66v83D1WEXOJbVMeyPDfXDu9tbDdPMNUyDpi4WGJXikAjxnAKfbt5Mv5NnEbxINy+VA=="], + + "expo-sqlite": ["expo-sqlite@56.0.5", "", { "dependencies": { "await-lock": "2.2.2" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-wHYRVLS5nUFEtli45wHaO+RjlRY8sQXyOSgENVk6I4zq7+FgySqjOk3YOYW6IKIMwhj5XzjMJO+pY8xKUy73Kw=="], + + "expo-structured-headers": ["expo-structured-headers@56.0.0", "", {}, "sha512-Yv4x+SQxNnMQm4nu8NFfzx197YaDhdYH2N0u7tGErwWTmH9Tm1SAhqo7bLbBWLC9kf7W+kdzTshLU9rTiCXWGw=="], + + "expo-symbols": ["expo-symbols@56.0.6", "", { "dependencies": { "@expo-google-fonts/material-symbols": "0.4.38", "sf-symbols-typescript": "2.2.0" }, "peerDependencies": { "expo": "*", "expo-font": "*", "react": "*", "react-native": "*" } }, "sha512-BrA81DjcNafdj7gXVhdrExb9LtUiSVyOf/NavyMmDAHgHMY1GqeR5cnn1PSAZeYKnSgQhee/H89XUpAxtog5hg=="], + + "expo-updates": ["expo-updates@56.0.19", "", { "dependencies": { "@expo/code-signing-certificates": "0.0.6", "@expo/plist": "0.7.0", "@expo/spawn-async": "1.8.0", "arg": "4.1.3", "chalk": "4.1.2", "debug": "4.4.3", "expo-eas-client": "56.0.1", "expo-manifests": "56.0.4", "expo-structured-headers": "56.0.0", "expo-updates-interface": "56.0.2", "getenv": "2.0.0", "glob": "13.0.6", "ignore": "5.3.2", "nullthrows": "1.1.1", "resolve-from": "5.0.0" }, "peerDependencies": { "expo": "*", "expo-dev-client": "*", "react": "*", "react-native": "*" }, "optionalPeers": ["expo-dev-client"], "bin": { "expo-updates": "bin/cli.js" } }, "sha512-tTSPYO5h8wDA6a+wQ2v/SRdnOdz29x0npGHCv+4Ev31Fz5r05Ii1Wgfh3BlTXNz8mikMReDsZCf6YN71YeQKpw=="], + + "expo-updates-interface": ["expo-updates-interface@56.0.2", "", { "peerDependencies": { "expo": "*" } }, "sha512-eWTwSZ9y8vrULG2oBn2TQSSIwBGSq/TxGJ3jY6tuVS2FWH/ASRIiKs3zkUZTRoC3ZuV2alz0mUClYV7nNrFx8g=="], + + "expo-web-browser": ["expo-web-browser@56.0.5", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-kaN+wcR5lHwPCH1IgrU1XyPUQvBRzdF1TMp65uAF9iUCyipqYnmrvV87eqAmrdkFFopWVgU7FcxPu1UZw+gvUQ=="], + + "expo-widgets": ["expo-widgets@56.0.19", "", { "dependencies": { "@expo/plist": "0.7.0", "@expo/ui": "56.0.18" }, "peerDependencies": { "expo": "*", "react": "*", "react-native": "*" } }, "sha512-D2RWectoEalVdGwXyE2LX3L9T6q6jSKh8jjvk1K3JSE1qOcCVZk+TJtvBUveTq8OoLblkeFMXqQ2fHG+kg655w=="], + + "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], + + "express": ["express@5.2.1", "", { "dependencies": { "accepts": "2.0.0", "body-parser": "2.3.0", "content-disposition": "1.1.0", "content-type": "1.0.5", "cookie": "0.7.2", "cookie-signature": "1.2.2", "debug": "4.4.3", "depd": "2.0.0", "encodeurl": "2.0.0", "escape-html": "1.0.3", "etag": "1.8.1", "finalhandler": "2.1.1", "fresh": "2.0.0", "http-errors": "2.0.1", "merge-descriptors": "2.0.0", "mime-types": "3.0.2", "on-finished": "2.4.1", "once": "1.4.0", "parseurl": "1.3.3", "proxy-addr": "2.0.7", "qs": "6.15.3", "range-parser": "1.2.1", "router": "2.2.0", "send": "1.2.1", "serve-static": "2.2.1", "statuses": "2.0.2", "type-is": "2.1.0", "vary": "1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], + + "express-rate-limit": ["express-rate-limit@8.5.2", "", { "dependencies": { "ip-address": "10.2.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "extract-zip": ["extract-zip@2.0.1", "", { "dependencies": { "debug": "4.4.3", "get-stream": "5.2.0", "yauzl": "2.10.0" }, "optionalDependencies": { "@types/yauzl": "2.10.3" }, "bin": { "extract-zip": "cli.js" } }, "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg=="], + + "fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "8.4.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="], + + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "@nodelib/fs.walk": "1.2.8", "glob-parent": "5.1.2", "merge2": "1.4.1", "micromatch": "4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], + + "fast-safe-stringify": ["fast-safe-stringify@2.1.1", "", {}, "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="], + + "fast-sha256": ["fast-sha256@1.3.0", "", {}, "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ=="], + + "fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="], + + "fast-string-width": ["fast-string-width@3.0.2", "", { "dependencies": { "fast-string-truncated-width": "3.0.3" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="], + + "fast-uri": ["fast-uri@3.1.2", "", {}, "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ=="], + + "fast-wrap-ansi": ["fast-wrap-ansi@0.2.2", "", { "dependencies": { "fast-string-width": "3.0.2" } }, "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q=="], + + "fast-xml-builder": ["fast-xml-builder@1.2.0", "", { "dependencies": { "path-expression-matcher": "1.5.0", "xml-naming": "0.1.0" } }, "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q=="], + + "fast-xml-parser": ["fast-xml-parser@5.8.0", "", { "dependencies": { "@nodable/entities": "2.1.1", "fast-xml-builder": "1.2.0", "path-expression-matcher": "1.5.0", "strnum": "2.3.0", "xml-naming": "0.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg=="], + + "fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", {}, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="], + + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "1.1.0" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fb-dotslash": ["fb-dotslash@0.5.8", "", { "bin": { "dotslash": "bin/dotslash" } }, "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA=="], + + "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="], + + "fd-slicer": ["fd-slicer@1.1.0", "", { "dependencies": { "pend": "1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fetch-nodeshim": ["fetch-nodeshim@0.4.10", "", {}, "sha512-m6I8ALe4L4XpdETy7MJZWs6L1IVMbjs99bwbpIKphxX+0CTns4IKDWJY0LWfr4YsFjfg+z1TjzTMU8lKl8rG0w=="], + + "ffi-rs": ["ffi-rs@1.3.2", "", { "optionalDependencies": { "@yuuang/ffi-rs-android-arm64": "1.3.2", "@yuuang/ffi-rs-darwin-arm64": "1.3.2", "@yuuang/ffi-rs-darwin-x64": "1.3.2", "@yuuang/ffi-rs-linux-arm-gnueabihf": "1.3.2", "@yuuang/ffi-rs-linux-arm64-gnu": "1.3.2", "@yuuang/ffi-rs-linux-arm64-musl": "1.3.2", "@yuuang/ffi-rs-linux-x64-gnu": "1.3.2", "@yuuang/ffi-rs-linux-x64-musl": "1.3.2", "@yuuang/ffi-rs-win32-arm64-msvc": "1.3.2", "@yuuang/ffi-rs-win32-ia32-msvc": "1.3.2", "@yuuang/ffi-rs-win32-x64-msvc": "1.3.2" } }, "sha512-4s8dX9VbBw/jd5NOuE3EJRqXaIVdjMyiumeeDzrOhtjQRwp6Bz2za7iksWXTnvTQKV/tTdm1s1w7mObe92zPjQ=="], + + "filelist": ["filelist@1.0.6", "", { "dependencies": { "minimatch": "5.1.9" } }, "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "filter-obj": ["filter-obj@1.1.0", "", {}, "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="], + + "finalhandler": ["finalhandler@1.1.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "1.0.2", "escape-html": "1.0.3", "on-finished": "2.3.0", "parseurl": "1.3.3", "statuses": "1.5.0", "unpipe": "1.0.0" } }, "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="], + + "find-my-way-ts": ["find-my-way-ts@0.1.6", "", {}, "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA=="], + + "find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], + + "flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="], + + "flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="], + + "fontace": ["fontace@0.4.1", "", { "dependencies": { "fontkitten": "1.0.3" } }, "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw=="], + + "fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="], + + "fontkitten": ["fontkitten@1.0.3", "", { "dependencies": { "tiny-inflate": "1.0.3" } }, "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw=="], + + "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "0.4.0", "combined-stream": "1.0.8", "es-set-tostringtag": "2.1.0", "hasown": "2.0.4", "mime-types": "2.1.35" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], + + "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], + + "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], + + "fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], + + "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + + "generate-function": ["generate-function@2.3.1", "", { "dependencies": { "is-property": "1.0.2" } }, "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ=="], + + "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="], + + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "1.0.2", "es-define-property": "1.0.1", "es-errors": "1.3.0", "es-object-atoms": "1.1.2", "function-bind": "1.1.2", "get-proto": "1.0.1", "gopd": "1.2.0", "has-symbols": "1.1.0", "hasown": "2.0.4", "math-intrinsics": "1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], + + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "1.0.1", "es-object-atoms": "1.1.2" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], + + "get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "3.0.4" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], + + "get-tsconfig": ["get-tsconfig@5.0.0-beta.4", "", { "dependencies": { "resolve-pkg-maps": "1.0.0" } }, "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ=="], + + "getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], + + "github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="], + + "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "10.2.5", "minipass": "7.1.3", "path-scurry": "2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "4.0.3" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="], + + "global-agent": ["global-agent@3.0.0", "", { "dependencies": { "boolean": "3.2.0", "es6-error": "4.1.1", "matcher": "3.0.0", "roarr": "2.15.4", "semver": "7.8.5", "serialize-error": "7.0.1" } }, "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q=="], + + "globalthis": ["globalthis@1.0.4", "", { "dependencies": { "define-properties": "1.2.1", "gopd": "1.2.0" } }, "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ=="], + + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], + + "got": ["got@11.8.6", "", { "dependencies": { "@sindresorhus/is": "4.6.0", "@szmarczak/http-timer": "4.0.6", "@types/cacheable-request": "6.0.3", "@types/responselike": "1.0.3", "cacheable-lookup": "5.0.4", "cacheable-request": "7.0.4", "decompress-response": "6.0.0", "http2-wrapper": "1.0.3", "lowercase-keys": "2.0.0", "p-cancelable": "2.1.1", "responselike": "2.0.1" } }, "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g=="], + + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "graphql": ["graphql@16.14.1", "", {}, "sha512-cQOsSMS/IrDz82PVyRDvf/Q1F/bRbBVjJlh+xYOkI1qw2bWRvWGiWc+m2O0d6l4Bt1fyY+8kzJ8JFWGJqNeDBg=="], + + "h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "1.2.3", "crossws": "0.3.5", "defu": "6.1.7", "destr": "2.0.5", "iron-webcrypto": "1.2.1", "node-mock-http": "1.0.4", "radix3": "1.1.2", "ufo": "1.6.4", "uncrypto": "0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "1.0.1" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="], + + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "1.1.0" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], + + "hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="], + + "hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "3.0.4", "devlop": "1.1.0", "hast-util-from-parse5": "8.0.3", "parse5": "7.3.0", "vfile": "6.0.3", "vfile-message": "4.0.3" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="], + + "hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "3.0.4", "@types/unist": "3.0.3", "devlop": "1.1.0", "hastscript": "9.0.1", "property-information": "7.2.0", "vfile": "6.0.3", "vfile-location": "5.0.3", "web-namespaces": "2.0.1" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="], + + "hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "3.0.4" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="], + + "hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "3.0.4", "@types/unist": "3.0.3", "@ungap/structured-clone": "1.3.1", "hast-util-from-parse5": "8.0.3", "hast-util-to-parse5": "8.0.1", "html-void-elements": "3.0.0", "mdast-util-to-hast": "13.2.1", "parse5": "7.3.0", "unist-util-position": "5.0.0", "unist-util-visit": "5.1.0", "vfile": "6.0.3", "web-namespaces": "2.0.1", "zwitch": "2.0.4" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="], + + "hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "3.0.4", "@ungap/structured-clone": "1.3.1", "unist-util-position": "5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "3.0.4", "@types/unist": "3.0.3", "ccount": "2.0.1", "comma-separated-tokens": "2.0.3", "hast-util-whitespace": "3.0.0", "html-void-elements": "3.0.0", "mdast-util-to-hast": "13.2.1", "property-information": "7.2.0", "space-separated-tokens": "2.0.2", "stringify-entities": "4.0.4", "zwitch": "2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "1.0.9", "@types/hast": "3.0.4", "@types/unist": "3.0.3", "comma-separated-tokens": "2.0.3", "devlop": "1.1.0", "estree-util-is-identifier-name": "3.0.0", "hast-util-whitespace": "3.0.0", "mdast-util-mdx-expression": "2.0.1", "mdast-util-mdx-jsx": "3.2.0", "mdast-util-mdxjs-esm": "2.0.1", "property-information": "7.2.0", "space-separated-tokens": "2.0.2", "style-to-js": "1.1.21", "unist-util-position": "5.0.0", "vfile-message": "4.0.3" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="], + + "hast-util-to-parse5": ["hast-util-to-parse5@8.0.1", "", { "dependencies": { "@types/hast": "3.0.4", "comma-separated-tokens": "2.0.3", "devlop": "1.1.0", "property-information": "7.2.0", "space-separated-tokens": "2.0.2", "web-namespaces": "2.0.1", "zwitch": "2.0.4" } }, "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "3.0.4" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "3.0.4", "comma-separated-tokens": "2.0.3", "hast-util-parse-selector": "4.0.0", "property-information": "7.2.0", "space-separated-tokens": "2.0.2" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="], + + "headers-polyfill": ["headers-polyfill@4.0.3", "", {}, "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ=="], + + "heic-to": ["heic-to@1.5.2", "", {}, "sha512-8Fns+lZHAWmz5U5IUxDeXKwIf3foBoKNPLxxFY4B0MkLjNuomEIHCoDbDE+x/llFK3NCEO1cu4+n3iUKY+Svmw=="], + + "hermes-compiler": ["hermes-compiler@250829098.0.10", "", {}, "sha512-TcRlZ0/TlyfJqquRFAWoyElVNnkdYRi/sEp4/Qy8/GYxjg8j2cS9D4MjuaQ+qimkmLN7AmO+44IznRf06mAr0w=="], + + "hermes-estree": ["hermes-estree@0.33.3", "", {}, "sha512-6kzYZHCk8Fy1Uc+t3HGYyJn3OL4aeqKLTyina4UFtWl8I0kSL7OmKThaiX+Uh2f8nGw3mo4Ifxg0M5Zk3/Oeqg=="], + + "hermes-parser": ["hermes-parser@0.33.3", "", { "dependencies": { "hermes-estree": "0.33.3" } }, "sha512-Yg3HgaG4CqgyowtYjX/FsnPAuZdHOqSMtnbpylbptsQ9nwwSKsy6uRWcGO5RK0EqiX12q8HvDWKgeAVajRO5DA=="], + + "hoist-non-react-statics": ["hoist-non-react-statics@3.3.2", "", { "dependencies": { "react-is": "16.13.1" } }, "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw=="], + + "hono": ["hono@4.12.27", "", {}, "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q=="], + + "hosted-git-info": ["hosted-git-info@4.1.0", "", { "dependencies": { "lru-cache": "6.0.0" } }, "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA=="], + + "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], + + "html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], + + "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.2", "toidentifier": "1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "7.1.4", "debug": "4.4.3" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "http2-client": ["http2-client@1.3.5", "", {}, "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA=="], + + "http2-wrapper": ["http2-wrapper@1.0.3", "", { "dependencies": { "quick-lru": "5.1.1", "resolve-alpn": "1.2.1" } }, "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "7.1.4", "debug": "4.4.3" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": "2.1.2" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + + "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], + + "image-size": ["image-size@1.2.1", "", { "dependencies": { "queue": "6.0.2" }, "bin": { "image-size": "bin/image-size.js" } }, "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw=="], + + "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], + + "indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], + + "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "1.4.0", "wrappy": "1.0.2" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@7.0.0", "", {}, "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w=="], + + "ink": ["ink@6.8.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "0.2.5", "ansi-escapes": "7.3.0", "ansi-styles": "6.2.3", "auto-bind": "5.0.1", "chalk": "5.6.2", "cli-boxes": "3.0.0", "cli-cursor": "4.0.0", "cli-truncate": "5.2.0", "code-excerpt": "4.0.0", "es-toolkit": "1.47.0", "indent-string": "5.0.0", "is-in-ci": "2.0.0", "patch-console": "2.0.0", "react-reconciler": "0.33.0", "scheduler": "0.27.0", "signal-exit": "3.0.7", "slice-ansi": "8.0.0", "stack-utils": "2.0.6", "string-width": "8.2.1", "terminal-size": "4.0.1", "type-fest": "5.7.0", "widest-line": "6.0.0", "wrap-ansi": "9.0.2", "ws": "8.21.0", "yoga-layout": "3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": ">=6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-sbl1RdLOgkO9isK42WCZlJCFN9hb++sX9dsklOvfd1YQ3bQ2AiFu12Q6tFlr0HvEUvzraJntQCCpfEoUe9DSzA=="], + + "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], + + "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "1.4.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="], + + "ioredis": ["ioredis@5.11.0", "", { "dependencies": { "@ioredis/commands": "1.10.0", "cluster-key-slot": "1.1.1", "debug": "4.4.3", "denque": "2.1.0", "redis-errors": "1.2.0", "redis-parser": "3.0.0", "standard-as-callback": "2.1.0" } }, "sha512-EZBErytyVovD8f6pDfG3Kb37N6Y3lmDA9NNj+4+IP13CzzHGeX+OyeRM2Um13khRzoBSzzL+5lVnCX8V2RLeMg=="], + + "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], + + "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + + "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="], + + "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], + + "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "2.0.1", "is-decimal": "2.0.1" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], + + "is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], + + "is-core-module": ["is-core-module@2.16.2", "", { "dependencies": { "hasown": "2.0.4" } }, "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA=="], + + "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + + "is-docker": ["is-docker@4.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + + "is-in-ci": ["is-in-ci@2.0.0", "", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="], + + "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="], + + "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="], + + "is-node-process": ["is-node-process@1.2.0", "", {}, "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], + + "is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="], + + "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], + + "is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], + + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], + + "isbot": ["isbot@5.1.40", "", {}, "sha512-yNeeynhhtIVRBk12tBV4eHNxwB42HzR4Q3Ea7vCOiJhImGaAIdIMrbJtacQlBizGLjUPw+akkFI5Dn9T70XoVQ=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "isomorphic.js": ["isomorphic.js@0.2.5", "", {}, "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw=="], + + "jake": ["jake@10.9.4", "", { "dependencies": { "async": "3.2.6", "filelist": "1.0.6", "picocolors": "1.1.1" }, "bin": { "jake": "bin/cli.js" } }, "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA=="], + + "jest-get-type": ["jest-get-type@29.6.3", "", {}, "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw=="], + + "jest-util": ["jest-util@29.7.0", "", { "dependencies": { "@jest/types": "29.6.3", "@types/node": "24.12.4", "chalk": "4.1.2", "ci-info": "3.9.0", "graceful-fs": "4.2.11", "picomatch": "2.3.2" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="], + + "jest-validate": ["jest-validate@29.7.0", "", { "dependencies": { "@jest/types": "29.6.3", "camelcase": "6.3.0", "chalk": "4.1.2", "jest-get-type": "29.6.3", "leven": "3.1.0", "pretty-format": "29.7.0" } }, "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw=="], + + "jest-worker": ["jest-worker@29.7.0", "", { "dependencies": { "@types/node": "24.12.4", "jest-util": "29.7.0", "merge-stream": "2.0.0", "supports-color": "8.1.1" } }, "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw=="], + + "jimp-compact": ["jimp-compact@0.16.1", "", {}, "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww=="], + + "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], + + "jose": ["jose@6.2.2", "", {}, "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ=="], + + "js-base64": ["js-base64@3.7.8", "", {}, "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="], + + "js-cookie": ["js-cookie@3.0.7", "", {}, "sha512-z/wZZgDrkNV1eA0ULjM/F9/50Ya8fbzgKneSpoPsXSGd0KnpdtHfOZWK+GcwLk+EZbS4F9RBhU+K2RgzuDaItw=="], + + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.2.0", "", { "dependencies": { "argparse": "2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw=="], + + "jsbi": ["jsbi@4.3.2", "", {}, "sha512-9fqMSQbhJykSeii05nxKl4m6Eqn2P6rOlYiS+C5Dr/HPIU/7yZxu5qzbs40tgaFORiw2Amd0mirjxatXYMkIew=="], + + "jsc-safe-url": ["jsc-safe-url@0.2.4", "", {}, "sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q=="], + + "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="], + + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + + "json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "7.29.7", "ts-algebra": "2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="], + + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + + "json-schema-typed": ["json-schema-typed@7.0.3", "", {}, "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A=="], + + "json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="], + + "json-with-bigint": ["json-with-bigint@3.5.8", "", {}, "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw=="], + + "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + + "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + + "jsonfile": ["jsonfile@6.2.1", "", { "dependencies": { "universalify": "2.0.1" }, "optionalDependencies": { "graceful-fs": "4.2.11" } }, "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q=="], + + "jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "3.3.0", "pako": "1.0.11", "readable-stream": "2.3.8", "setimmediate": "1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="], + + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + + "kubernetes-types": ["kubernetes-types@1.30.0", "", {}, "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q=="], + + "lan-network": ["lan-network@0.2.1", "", { "bin": { "lan-network": "dist/lan-network-cli.js" } }, "sha512-ONPnazC96VKDntab9j9JKwIWhZ4ZUceB4A9Epu4Ssg0hYFmtHZSeQ+n15nIwTFmcBUKtExOer8WTJ4GF9MO64A=="], + + "lazy-val": ["lazy-val@1.0.5", "", {}, "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q=="], + + "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], + + "lexical": ["lexical@0.41.0", "", {}, "sha512-pNIm5+n+hVnJHB9gYPDYsIO5Y59dNaDU9rJmPPsfqQhP2ojKFnUoPbcRnrI9FJLXB14sSumcY8LUw7Sq70TZqA=="], + + "lib0": ["lib0@0.2.117", "", { "dependencies": { "isomorphic.js": "0.2.5" }, "bin": { "0serve": "bin/0serve.js", "0gentesthtml": "bin/gentesthtml.js", "0ecdsa-generate-keypair": "bin/0ecdsa-generate-keypair.js" } }, "sha512-DeXj9X5xDCjgKLU/7RR+/HQEVzuuEUiwldwOGsHK/sfAfELGWEyTcf0x+uOvCvK3O2zPmZePXWL85vtia6GyZw=="], + + "libsodium": ["libsodium@0.8.4", "", {}, "sha512-lMcYaRi0zcs7tarATsQUYC7rstliIXZuoq0c6zXSgNtSNtdvBgkSegjWhpMJAXzKX3SUSwIp7+zEsob+j3LuRw=="], + + "libsodium-wrappers": ["libsodium-wrappers@0.8.4", "", { "dependencies": { "libsodium": "0.8.4" } }, "sha512-mu8aAWucZjTB5O/BtGXtW4e1agy7uHxNYG7zPthmmD1jU43LCDmSWZLN4JhflbdPXj3yDO4lxM1O9hLDgIOXDw=="], + + "libsql": ["libsql@0.5.29", "", { "dependencies": { "@neon-rs/load": "0.0.4", "detect-libc": "2.0.2" }, "optionalDependencies": { "@libsql/darwin-arm64": "0.5.29", "@libsql/darwin-x64": "0.5.29", "@libsql/linux-arm-gnueabihf": "0.5.29", "@libsql/linux-arm-musleabihf": "0.5.29", "@libsql/linux-arm64-gnu": "0.5.29", "@libsql/linux-arm64-musl": "0.5.29", "@libsql/linux-x64-gnu": "0.5.29", "@libsql/linux-x64-musl": "0.5.29", "@libsql/win32-x64-msvc": "0.5.29" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "arm", "x64", "arm64", ] }, "sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg=="], + + "lie": ["lie@3.3.0", "", { "dependencies": { "immediate": "3.0.6" } }, "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ=="], + + "lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "2.6.9", "marky": "1.3.0" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="], + + "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], + + "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], + + "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], + + "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="], + + "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="], + + "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="], + + "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="], + + "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="], + + "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="], + + "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="], + + "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="], + + "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], + + "locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "3.0.0", "path-exists": "3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], + + "lodash": ["lodash@4.18.1", "", {}, "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q=="], + + "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], + + "lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="], + + "lodash.isequal": ["lodash.isequal@4.5.0", "", {}, "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="], + + "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="], + + "log-symbols": ["log-symbols@7.0.1", "", { "dependencies": { "is-unicode-supported": "2.1.0", "yoctocolors": "2.1.2" } }, "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg=="], + + "long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + + "lowercase-keys": ["lowercase-keys@2.0.0", "", {}, "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="], + + "lru-cache": ["lru-cache@11.5.1", "", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="], + + "lru.min": ["lru.min@1.1.4", "", {}, "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA=="], + + "lru_map": ["lru_map@0.4.1", "", {}, "sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg=="], + + "lucide-react": ["lucide-react@0.564.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-JJ8GVTQqFwuliifD48U6+h7DXEHdkhJ/E87kksGByII3qHxtPciVb8T8woQONHBQgHVOl7rSMrrip3SeVNy7Fg=="], + + "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "magicast": ["magicast@0.5.3", "", { "dependencies": { "@babel/parser": "7.29.7", "@babel/types": "7.29.7", "source-map-js": "1.2.1" } }, "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw=="], + + "makeerror": ["makeerror@1.0.12", "", { "dependencies": { "tmpl": "1.0.5" } }, "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg=="], + + "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], + + "marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="], + + "matcher": ["matcher@3.0.0", "", { "dependencies": { "escape-string-regexp": "4.0.0" } }, "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng=="], + + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + + "mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "4.0.4", "escape-string-regexp": "5.0.0", "unist-util-is": "6.0.1", "unist-util-visit-parents": "6.0.2" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "4.0.4", "@types/unist": "3.0.3", "decode-named-character-reference": "1.3.0", "devlop": "1.1.0", "mdast-util-to-string": "4.0.0", "micromark": "4.0.2", "micromark-util-decode-numeric-character-reference": "2.0.2", "micromark-util-decode-string": "2.0.1", "micromark-util-normalize-identifier": "2.0.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2", "unist-util-stringify-position": "4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + + "mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "2.0.3", "mdast-util-gfm-autolink-literal": "2.0.1", "mdast-util-gfm-footnote": "2.1.0", "mdast-util-gfm-strikethrough": "2.0.0", "mdast-util-gfm-table": "2.0.0", "mdast-util-gfm-task-list-item": "2.0.0", "mdast-util-to-markdown": "2.1.2" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], + + "mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "4.0.4", "ccount": "2.0.1", "devlop": "1.1.0", "mdast-util-find-and-replace": "3.0.2", "micromark-util-character": "2.1.1" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="], + + "mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "4.0.4", "devlop": "1.1.0", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2", "micromark-util-normalize-identifier": "2.0.1" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="], + + "mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="], + + "mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "devlop": "1.1.0", "markdown-table": "3.0.4", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="], + + "mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "devlop": "1.1.0", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="], + + "mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "1.0.5", "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "devlop": "1.1.0", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="], + + "mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "1.0.5", "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "@types/unist": "3.0.3", "ccount": "2.0.1", "devlop": "1.1.0", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2", "parse-entities": "4.0.2", "stringify-entities": "4.0.4", "unist-util-stringify-position": "4.0.0", "vfile-message": "4.0.3" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="], + + "mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "1.0.5", "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "devlop": "1.1.0", "mdast-util-from-markdown": "2.0.3", "mdast-util-to-markdown": "2.1.2" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="], + + "mdast-util-newline-to-break": ["mdast-util-newline-to-break@2.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "mdast-util-find-and-replace": "3.0.2" } }, "sha512-MbgeFca0hLYIEx/2zGsszCSEJJ1JSCdiY5xQxRcLDDGa8EPvlLPupJ4DSajbMPAnC0je8jfb9TiUATnxxrHUog=="], + + "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "4.0.4", "unist-util-is": "6.0.1" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "@ungap/structured-clone": "1.3.1", "devlop": "1.1.0", "micromark-util-sanitize-uri": "2.0.1", "trim-lines": "3.0.1", "unist-util-position": "5.0.0", "unist-util-visit": "5.1.0", "vfile": "6.0.3" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "4.0.4", "@types/unist": "3.0.3", "longest-streak": "3.1.0", "mdast-util-phrasing": "4.1.0", "mdast-util-to-string": "4.0.0", "micromark-util-classify-character": "2.0.1", "micromark-util-decode-string": "2.0.1", "unist-util-visit": "5.1.0", "zwitch": "2.0.4" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "4.0.4" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "mdn-data": ["mdn-data@2.0.14", "", {}, "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow=="], + + "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], + + "memoize-one": ["memoize-one@5.2.1", "", {}, "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="], + + "memory-pager": ["memory-pager@1.5.0", "", {}, "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg=="], + + "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], + + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "metro": ["metro@0.84.4", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/core": "7.29.7", "@babel/generator": "7.29.7", "@babel/parser": "7.29.7", "@babel/template": "7.29.7", "@babel/traverse": "7.29.7", "@babel/types": "7.29.7", "accepts": "2.0.0", "ci-info": "2.0.0", "connect": "3.7.0", "debug": "4.4.3", "error-stack-parser": "2.1.4", "flow-enums-runtime": "0.0.6", "graceful-fs": "4.2.11", "hermes-parser": "0.35.0", "image-size": "1.2.1", "invariant": "2.2.4", "jest-worker": "29.7.0", "jsc-safe-url": "0.2.4", "lodash.throttle": "4.1.1", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-config": "0.84.4", "metro-core": "0.84.4", "metro-file-map": "0.84.4", "metro-resolver": "0.84.4", "metro-runtime": "0.84.4", "metro-source-map": "0.84.4", "metro-symbolicate": "0.84.4", "metro-transform-plugins": "0.84.4", "metro-transform-worker": "0.84.4", "mime-types": "3.0.2", "nullthrows": "1.1.1", "serialize-error": "2.1.0", "source-map": "0.5.7", "throat": "5.0.0", "ws": "7.5.11", "yargs": "17.7.2" }, "bin": { "metro": "src/cli.js" } }, "sha512-8ETTubqfD6ornDy2zYDvRcKnVDOXdFJsjetYDBsY4oAsb6NJkiwFR+FaMESyGppFmQUyBQA4H4sFGxzcQSGtFA=="], + + "metro-babel-transformer": ["metro-babel-transformer@0.84.4", "", { "dependencies": { "@babel/core": "7.29.7", "flow-enums-runtime": "0.0.6", "hermes-parser": "0.35.0", "metro-cache-key": "0.84.4", "nullthrows": "1.1.1" } }, "sha512-rvCfz8snl9h20VcvpOHxZuHP1SlAkv4HXbzw7nyyVwu6Eqo5PRerbakQ9XmUCOsRy70spJ37O+G1TK8oMzo48g=="], + + "metro-cache": ["metro-cache@0.84.4", "", { "dependencies": { "exponential-backoff": "3.1.3", "flow-enums-runtime": "0.0.6", "https-proxy-agent": "7.0.6", "metro-core": "0.84.4" } }, "sha512-gpcFQdSLUwUCk71saKoE64jLFbx2nwTfVCcPSULMNT8QYq0p1eZZE29Jvd0HtT/UlhC3ZOutLxJME5xqD2JUZg=="], + + "metro-cache-key": ["metro-cache-key@0.84.4", "", { "dependencies": { "flow-enums-runtime": "0.0.6" } }, "sha512-wVO79aGrkYImpnaVS4+d5RrRBRPX31QtvKB3wKGBuiNSznduZTQHzsrJZRroFJSwnygrzdsGUtDQPuqqFjFdvw=="], + + "metro-config": ["metro-config@0.84.4", "", { "dependencies": { "connect": "3.7.0", "flow-enums-runtime": "0.0.6", "jest-validate": "29.7.0", "metro": "0.84.4", "metro-cache": "0.84.4", "metro-core": "0.84.4", "metro-runtime": "0.84.4", "yaml": "2.9.0" } }, "sha512-PMotGDjXcXLWo2TMRH+VR99phFNgYTwqh4OoieIKK3yTJa1Jmkl+fZJxDO0jfBvNF+WESHciHvpNuBtXaF3B0Q=="], + + "metro-core": ["metro-core@0.84.4", "", { "dependencies": { "flow-enums-runtime": "0.0.6", "lodash.throttle": "4.1.1", "metro-resolver": "0.84.4" } }, "sha512-HONpWC5LGXZn3ffkd4Hu6AIrfE7j4Z0g0wMo/goV24WOB3lhuFZ40KgvaDiSw8iyQHloMYay5N/wPX+z8oN/PQ=="], + + "metro-file-map": ["metro-file-map@0.84.4", "", { "dependencies": { "debug": "4.4.3", "fb-watchman": "2.0.2", "flow-enums-runtime": "0.0.6", "graceful-fs": "4.2.11", "invariant": "2.2.4", "jest-worker": "29.7.0", "micromatch": "4.0.8", "nullthrows": "1.1.1", "walker": "1.0.8" } }, "sha512-KSVDi/u60hKPx++NLu3MTIvyjzNoJnFAF8PQFxaj1jiSka/wjw+Ua6sNuJ0TDHQv+7AAoFQxeMgaRAe8Yic5wQ=="], + + "metro-minify-terser": ["metro-minify-terser@0.84.4", "", { "dependencies": { "flow-enums-runtime": "0.0.6", "terser": "5.48.0" } }, "sha512-5qpbaVOMC7CPitIpuewzVeGw7E+C3ykbv2mqTjQLl85Z3annSVGlSCTcsZjqXZzjupfK4Ztj3dDc4kc44NZwtQ=="], + + "metro-resolver": ["metro-resolver@0.84.4", "", { "dependencies": { "flow-enums-runtime": "0.0.6" } }, "sha512-1qLgbxQ5ZGhhutuPot1Yp348ofDsATL2WkrHF65TobqTT9K3P9qJXw38bomk7ncp5B7OYMfWwtyBZo1lCV792A=="], + + "metro-runtime": ["metro-runtime@0.84.4", "", { "dependencies": { "@babel/runtime": "7.29.7", "flow-enums-runtime": "0.0.6" } }, "sha512-Jibypds4g7AhzdRKY+kDoj51s5EXMwgyp5ddtlreDAsWefMdOx+agWqgm0H2XSZ/ueanHHVM89fnf5OJnlxa8Q=="], + + "metro-source-map": ["metro-source-map@0.84.4", "", { "dependencies": { "@babel/traverse": "7.29.7", "@babel/types": "7.29.7", "flow-enums-runtime": "0.0.6", "invariant": "2.2.4", "metro-symbolicate": "0.84.4", "nullthrows": "1.1.1", "ob1": "0.84.4", "source-map": "0.5.7", "vlq": "1.0.1" } }, "sha512-jbWkPxIesVuo1IWkvezmMJld6iu8nD62GsrZiV6jP37AOdbo4OBq1FJ+qkOg8sV05wAHB//jAbziuW0SlJfW4g=="], + + "metro-symbolicate": ["metro-symbolicate@0.84.4", "", { "dependencies": { "flow-enums-runtime": "0.0.6", "invariant": "2.2.4", "metro-source-map": "0.84.4", "nullthrows": "1.1.1", "source-map": "0.5.7", "vlq": "1.0.1" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-OnfpacxUqGPZQ27t8qK9mFa7uqHIlVWeqRqkCbvMvreEBiamEeOn8krKtcwgP5M4cYDPwuSmCTopHMVthqG4zA=="], + + "metro-transform-plugins": ["metro-transform-plugins@0.84.4", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/generator": "7.29.7", "@babel/template": "7.29.7", "@babel/traverse": "7.29.7", "flow-enums-runtime": "0.0.6", "nullthrows": "1.1.1" } }, "sha512-kehr6HbAecqD0/a3xLXobELdPaAmRAl8bel0qagPF4vhZtux93nS8S4eq2kgKt6J2GnQpVjSoW1PXdst04mwow=="], + + "metro-transform-worker": ["metro-transform-worker@0.84.4", "", { "dependencies": { "@babel/core": "7.29.7", "@babel/generator": "7.29.7", "@babel/parser": "7.29.7", "@babel/types": "7.29.7", "flow-enums-runtime": "0.0.6", "metro": "0.84.4", "metro-babel-transformer": "0.84.4", "metro-cache": "0.84.4", "metro-cache-key": "0.84.4", "metro-minify-terser": "0.84.4", "metro-source-map": "0.84.4", "metro-transform-plugins": "0.84.4", "nullthrows": "1.1.1" } }, "sha512-W1IYMvvXTu4MxYr7d9h7CeG2vpIr3bmLLIavkPY4O1ilzDrvS8z/NEe6y+pC44Ff7raMXQgYSfdqDUwN/i39gg=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "4.1.13", "debug": "4.4.3", "decode-named-character-reference": "1.3.0", "devlop": "1.1.0", "micromark-core-commonmark": "2.0.3", "micromark-factory-space": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-chunked": "2.0.1", "micromark-util-combine-extensions": "2.0.1", "micromark-util-decode-numeric-character-reference": "2.0.2", "micromark-util-encode": "2.0.1", "micromark-util-normalize-identifier": "2.0.1", "micromark-util-resolve-all": "2.0.1", "micromark-util-sanitize-uri": "2.0.1", "micromark-util-subtokenize": "2.1.0", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "1.3.0", "devlop": "1.1.0", "micromark-factory-destination": "2.0.1", "micromark-factory-label": "2.0.1", "micromark-factory-space": "2.0.1", "micromark-factory-title": "2.0.1", "micromark-factory-whitespace": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-chunked": "2.0.1", "micromark-util-classify-character": "2.0.1", "micromark-util-html-tag-name": "2.0.1", "micromark-util-normalize-identifier": "2.0.1", "micromark-util-resolve-all": "2.0.1", "micromark-util-subtokenize": "2.1.0", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "2.1.0", "micromark-extension-gfm-footnote": "2.1.0", "micromark-extension-gfm-strikethrough": "2.1.0", "micromark-extension-gfm-table": "2.1.1", "micromark-extension-gfm-tagfilter": "2.0.0", "micromark-extension-gfm-task-list-item": "2.1.0", "micromark-util-combine-extensions": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="], + + "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "2.1.1", "micromark-util-sanitize-uri": "2.0.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], + + "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "1.1.0", "micromark-core-commonmark": "2.0.3", "micromark-factory-space": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-normalize-identifier": "2.0.1", "micromark-util-sanitize-uri": "2.0.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="], + + "micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "1.1.0", "micromark-util-chunked": "2.0.1", "micromark-util-classify-character": "2.0.1", "micromark-util-resolve-all": "2.0.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="], + + "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "1.1.0", "micromark-factory-space": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="], + + "micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "2.0.2" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="], + + "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "1.1.0", "micromark-factory-space": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "1.1.0", "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "2.1.1", "micromark-util-types": "2.0.2" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "2.0.1", "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "2.0.1" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "2.1.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "2.0.1" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "1.3.0", "micromark-util-character": "2.1.1", "micromark-util-decode-numeric-character-reference": "2.0.2", "micromark-util-symbol": "2.0.1" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "2.0.1" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "2.0.2" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "2.1.1", "micromark-util-encode": "2.0.1", "micromark-util-symbol": "2.0.1" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "1.1.0", "micromark-util-chunked": "2.0.1", "micromark-util-symbol": "2.0.1", "micromark-util-types": "2.0.2" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "3.0.3", "picomatch": "2.3.2" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime": ["mime@4.1.0", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="], + + "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + + "mimic-fn": ["mimic-fn@3.1.0", "", {}, "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ=="], + + "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], + + "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], + + "minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "1.1.15" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], + + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + + "minizlib": ["minizlib@3.1.0", "", { "dependencies": { "minipass": "7.1.3" } }, "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw=="], + + "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "mongodb": ["mongodb@6.21.0", "", { "dependencies": { "@mongodb-js/saslprep": "1.4.13", "bson": "6.10.4", "mongodb-connection-string-url": "3.0.2" }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", "snappy": "^7.3.2", "socks": "^2.7.1" }, "optionalPeers": ["@aws-sdk/credential-providers", "@mongodb-js/zstd", "gcp-metadata", "kerberos", "mongodb-client-encryption", "snappy", "socks"] }, "sha512-URyb/VXMjJ4da46OeSXg+puO39XH9DeQpWCslifrRn9JWugy0D+DvvBvkm2WxmHe61O/H19JM66p1z7RHVkZ6A=="], + + "mongodb-connection-string-url": ["mongodb-connection-string-url@3.0.2", "", { "dependencies": { "@types/whatwg-url": "11.0.5", "whatwg-url": "14.2.0" } }, "sha512-rMO7CGo/9BFwyZABcKAWL8UJwH/Kc2x0g72uhDWzG48URRax5TCIcJ7Rc3RZqffZzO/Gwff/jyKwCU9TN8gehA=="], + + "mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], + + "msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="], + + "msw": ["msw@2.12.11", "", { "dependencies": { "@inquirer/confirm": "5.1.21", "@mswjs/interceptors": "0.41.9", "@open-draft/deferred-promise": "2.2.0", "@types/statuses": "2.0.6", "cookie": "1.1.1", "graphql": "16.14.1", "headers-polyfill": "4.0.3", "is-node-process": "1.2.0", "outvariant": "1.4.3", "path-to-regexp": "6.3.0", "picocolors": "1.1.1", "rettime": "0.10.1", "statuses": "2.0.2", "strict-event-emitter": "0.5.1", "tough-cookie": "6.0.1", "type-fest": "5.7.0", "until-async": "3.0.2", "yargs": "17.7.2" }, "peerDependencies": { "typescript": ">= 4.8.x" }, "optionalPeers": ["typescript"], "bin": { "msw": "cli/index.js" } }, "sha512-dVg20zi2I2EvnwH/+WupzsOC2mCa7qsIhyMAWtfRikn6RKtwL9+7SaF1IQ5LyZry4tlUtf6KyTVhnlQiZXozTQ=="], + + "muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="], + + "multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], + + "multitars": ["multitars@1.0.0", "", {}, "sha512-H/J4fMLedtudftaYMOg7ajzLYgT3/rwbWVJbqr/iUgB8DQztn38ys5HOqI1CzSxx8QhXXwOOnnBvd4v3jG5+Mg=="], + + "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], + + "mysql2": ["mysql2@3.22.4", "", { "dependencies": { "aws-ssl-profiles": "1.1.2", "denque": "2.1.0", "generate-function": "2.3.1", "iconv-lite": "0.7.2", "long": "5.3.2", "lru.min": "1.1.4", "named-placeholders": "1.1.6", "sql-escaper": "1.3.3" }, "peerDependencies": { "@types/node": "24.12.4" } }, "sha512-CtXYlmL7ZamiYKbmqkamQHWJROUHSfm+f3kByzGfknw7kW51mcB2ouMUqYq1XfYxbXmnWo6RhPydx6OCqdgcmQ=="], + + "named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "1.1.4" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="], + + "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], + + "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="], + + "neotraverse": ["neotraverse@0.6.18", "", {}, "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA=="], + + "nlcst-to-string": ["nlcst-to-string@4.0.0", "", { "dependencies": { "@types/nlcst": "2.0.3" } }, "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA=="], + + "node-abi": ["node-abi@4.31.0", "", { "dependencies": { "semver": "7.8.5" } }, "sha512-Erq5w/t3syw3s4sDsUaX4QttIdBPsGKTT1DTRsCkTonGggczhlDKm/wDX3o+HPJpQ41EjXCbcmXf0tgr5YZJXw=="], + + "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="], + + "node-api-version": ["node-api-version@0.2.1", "", { "dependencies": { "semver": "7.8.5" } }, "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q=="], + + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + + "node-fetch-h2": ["node-fetch-h2@2.3.0", "", { "dependencies": { "http2-client": "1.3.5" } }, "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg=="], + + "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], + + "node-forge": ["node-forge@1.4.0", "", {}, "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ=="], + + "node-gyp": ["node-gyp@12.3.0", "", { "dependencies": { "env-paths": "2.2.1", "exponential-backoff": "3.1.3", "graceful-fs": "4.2.11", "nopt": "9.0.0", "proc-log": "6.1.0", "semver": "7.8.5", "tar": "7.5.16", "tinyglobby": "0.2.17", "undici": "6.26.0", "which": "6.0.1" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg=="], + + "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "2.1.2" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], + + "node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="], + + "node-mock-http": ["node-mock-http@1.0.4", "", {}, "sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ=="], + + "node-pty": ["node-pty@1.1.0", "", { "dependencies": { "node-addon-api": "7.1.1" } }, "sha512-20JqtutY6JPXTUnL0ij1uad7Qe1baT46lyolh2sSENDd4sTzKZ4nmAFkeAARDKwmlLjPx6XKRlwRUxwjOy+lUg=="], + + "node-readfiles": ["node-readfiles@0.2.0", "", { "dependencies": { "es6-promise": "3.3.1" } }, "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA=="], + + "node-releases": ["node-releases@2.0.46", "", {}, "sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ=="], + + "nopt": ["nopt@9.0.0", "", { "dependencies": { "abbrev": "4.0.0" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="], + + "npm-package-arg": ["npm-package-arg@11.0.3", "", { "dependencies": { "hosted-git-info": "7.0.2", "proc-log": "4.2.0", "semver": "7.8.5", "validate-npm-package-name": "5.0.1" } }, "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="], + + "oas-kit-common": ["oas-kit-common@1.0.8", "", { "dependencies": { "fast-safe-stringify": "2.1.1" } }, "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ=="], + + "oas-linter": ["oas-linter@3.2.2", "", { "dependencies": { "@exodus/schemasafe": "1.3.0", "should": "13.2.3", "yaml": "2.9.0" } }, "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ=="], + + "oas-resolver": ["oas-resolver@2.5.6", "", { "dependencies": { "node-fetch-h2": "2.3.0", "oas-kit-common": "1.0.8", "reftools": "1.1.9", "yaml": "2.9.0", "yargs": "17.7.2" }, "bin": { "resolve": "resolve.js" } }, "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ=="], + + "oas-schema-walker": ["oas-schema-walker@1.1.5", "", {}, "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ=="], + + "oas-validator": ["oas-validator@5.0.8", "", { "dependencies": { "call-me-maybe": "1.0.2", "oas-kit-common": "1.0.8", "oas-linter": "3.2.2", "oas-resolver": "2.5.6", "oas-schema-walker": "1.1.5", "reftools": "1.1.9", "should": "13.2.3", "yaml": "2.9.0" } }, "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw=="], + + "ob1": ["ob1@0.84.4", "", { "dependencies": { "flow-enums-runtime": "0.0.6" } }, "sha512-eJXMpz4aQHXF/YBB9ddqZDIS+ooO91hObo9FoW/xBkr54/zCwYYCDqT/O54vNo8kOkWs5Ou/y28NgdrV0edQNA=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], + + "object-keys": ["object-keys@1.1.1", "", {}, "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="], + + "obuf": ["obuf@1.1.2", "", {}, "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="], + + "obug": ["obug@2.1.3", "", {}, "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg=="], + + "ofetch": ["ofetch@1.5.1", "", { "dependencies": { "destr": "2.0.5", "node-fetch-native": "1.6.7", "ufo": "1.6.4" } }, "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA=="], + + "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="], + + "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], + + "on-headers": ["on-headers@1.1.0", "", {}, "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A=="], + + "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1.0.2" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], + + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "oniguruma-parser": ["oniguruma-parser@0.12.2", "", {}, "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw=="], + + "oniguruma-to-es": ["oniguruma-to-es@4.3.6", "", { "dependencies": { "oniguruma-parser": "0.12.2", "regex": "6.1.0", "regex-recursion": "6.0.2" } }, "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA=="], + + "open": ["open@7.4.2", "", { "dependencies": { "is-docker": "2.2.1", "is-wsl": "2.2.0" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="], + + "ora": ["ora@9.4.0", "", { "dependencies": { "chalk": "5.6.2", "cli-cursor": "5.0.0", "cli-spinners": "3.4.0", "is-interactive": "2.0.0", "is-unicode-supported": "2.1.0", "log-symbols": "7.0.1", "stdin-discarder": "0.3.2", "string-width": "8.2.1" } }, "sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ=="], + + "outvariant": ["outvariant@1.4.3", "", {}, "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA=="], + + "oxfmt": ["oxfmt@0.57.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.57.0", "@oxfmt/binding-android-arm64": "0.57.0", "@oxfmt/binding-darwin-arm64": "0.57.0", "@oxfmt/binding-darwin-x64": "0.57.0", "@oxfmt/binding-freebsd-x64": "0.57.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.57.0", "@oxfmt/binding-linux-arm-musleabihf": "0.57.0", "@oxfmt/binding-linux-arm64-gnu": "0.57.0", "@oxfmt/binding-linux-arm64-musl": "0.57.0", "@oxfmt/binding-linux-ppc64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-musl": "0.57.0", "@oxfmt/binding-linux-s390x-gnu": "0.57.0", "@oxfmt/binding-linux-x64-gnu": "0.57.0", "@oxfmt/binding-linux-x64-musl": "0.57.0", "@oxfmt/binding-openharmony-arm64": "0.57.0", "@oxfmt/binding-win32-arm64-msvc": "0.57.0", "@oxfmt/binding-win32-ia32-msvc": "0.57.0", "@oxfmt/binding-win32-x64-msvc": "0.57.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-ZB7Bi+rGDSqmVIo9jwcLyFgjxXvQhDdU+jx+ZrVy6VRiVXK2+CHc4hO3J4dUQjHe7V0ymHB+MDuv5z+NhK07HA=="], + + "oxlint": ["oxlint@1.72.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.72.0", "@oxlint/binding-android-arm64": "1.72.0", "@oxlint/binding-darwin-arm64": "1.72.0", "@oxlint/binding-darwin-x64": "1.72.0", "@oxlint/binding-freebsd-x64": "1.72.0", "@oxlint/binding-linux-arm-gnueabihf": "1.72.0", "@oxlint/binding-linux-arm-musleabihf": "1.72.0", "@oxlint/binding-linux-arm64-gnu": "1.72.0", "@oxlint/binding-linux-arm64-musl": "1.72.0", "@oxlint/binding-linux-ppc64-gnu": "1.72.0", "@oxlint/binding-linux-riscv64-gnu": "1.72.0", "@oxlint/binding-linux-riscv64-musl": "1.72.0", "@oxlint/binding-linux-s390x-gnu": "1.72.0", "@oxlint/binding-linux-x64-gnu": "1.72.0", "@oxlint/binding-linux-x64-musl": "1.72.0", "@oxlint/binding-openharmony-arm64": "1.72.0", "@oxlint/binding-win32-arm64-msvc": "1.72.0", "@oxlint/binding-win32-ia32-msvc": "1.72.0", "@oxlint/binding-win32-x64-msvc": "1.72.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA=="], + + "oxlint-tsgolint": ["oxlint-tsgolint@0.24.0", "", { "optionalDependencies": { "@oxlint-tsgolint/darwin-arm64": "0.24.0", "@oxlint-tsgolint/darwin-x64": "0.24.0", "@oxlint-tsgolint/linux-arm64": "0.24.0", "@oxlint-tsgolint/linux-x64": "0.24.0", "@oxlint-tsgolint/win32-arm64": "0.24.0", "@oxlint-tsgolint/win32-x64": "0.24.0" }, "bin": { "tsgolint": "bin/tsgolint.js" } }, "sha512-giCk5sEvG02d5tzPmFMX3hem8ndzEEu1xvGYS5OwNfO2WGl6ZVxt5LjE0yiMDoz94INI7XkXwgFAQiydPvVHDw=="], + + "p-cancelable": ["p-cancelable@2.1.1", "", {}, "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="], + + "p-limit": ["p-limit@7.3.0", "", { "dependencies": { "yocto-queue": "1.2.2" } }, "sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw=="], + + "p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "2.3.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], + + "p-queue": ["p-queue@9.3.0", "", { "dependencies": { "eventemitter3": "5.0.4", "p-timeout": "7.0.1" } }, "sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang=="], + + "p-timeout": ["p-timeout@7.0.1", "", {}, "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg=="], + + "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], + + "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + + "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], + + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "2.0.11", "character-entities-legacy": "3.0.0", "character-reference-invalid": "2.0.1", "decode-named-character-reference": "1.3.0", "is-alphanumerical": "2.0.1", "is-decimal": "2.0.1", "is-hexadecimal": "2.0.1" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], + + "parse-png": ["parse-png@2.1.0", "", { "dependencies": { "pngjs": "3.4.0" } }, "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ=="], + + "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "6.0.1" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], + + "patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="], + + "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], + + "path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], + + "path-expression-matcher": ["path-expression-matcher@1.5.0", "", {}, "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ=="], + + "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + + "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "11.5.1", "minipass": "7.1.3" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + + "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], + + "path-to-regexp-updated": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "pe-library": ["pe-library@0.4.1", "", {}, "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw=="], + + "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], + + "pg": ["pg@8.22.0", "", { "dependencies": { "pg-connection-string": "2.14.0", "pg-pool": "3.14.0", "pg-protocol": "1.15.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "1.4.0" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA=="], + + "pg-cloudflare": ["pg-cloudflare@1.4.0", "", {}, "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A=="], + + "pg-connection-string": ["pg-connection-string@2.14.0", "", {}, "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg=="], + + "pg-cursor": ["pg-cursor@2.21.0", "", { "peerDependencies": { "pg": "^8" } }, "sha512-IYvk/j+Suhtbo/C3uOf4JLsLK/gWxOTUOmYbDsbKnLaVJDq+KwhwK6ngpRfiCk8eDMS3AmGQABZCv0cREEzHQw=="], + + "pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="], + + "pg-numeric": ["pg-numeric@1.0.2", "", {}, "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw=="], + + "pg-pool": ["pg-pool@3.14.0", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw=="], + + "pg-protocol": ["pg-protocol@1.15.0", "", {}, "sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ=="], + + "pg-types": ["pg-types@4.1.0", "", { "dependencies": { "pg-int8": "1.0.1", "pg-numeric": "1.0.2", "postgres-array": "3.0.4", "postgres-bytea": "3.0.0", "postgres-date": "2.1.0", "postgres-interval": "3.0.0", "postgres-range": "1.1.4" } }, "sha512-o2XFanIMy/3+mThw69O8d4n1E5zsLhdO+OPqswezu7Z5ekP4hYDqlDjlmOpYMbzY2Br0ufCwJLdDIXeNVwcWFg=="], + + "pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "4.2.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="], + + "piccolore": ["piccolore@0.1.3", "", {}, "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], + + "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], + + "pkg-up": ["pkg-up@3.1.0", "", { "dependencies": { "find-up": "3.0.0" } }, "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA=="], + + "pkijs": ["pkijs@3.4.0", "", { "dependencies": { "@noble/hashes": "1.4.0", "asn1js": "3.0.10", "bytestreamjs": "2.0.1", "pvtsutils": "1.3.6", "pvutils": "1.1.5", "tslib": "2.8.1" } }, "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw=="], + + "playwright-core": ["playwright-core@1.60.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA=="], + + "plist": ["plist@3.1.1", "", { "dependencies": { "@xmldom/xmldom": "0.9.10", "base64-js": "1.5.1", "xmlbuilder": "15.1.1" } }, "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA=="], + + "pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], + + "postcss": ["postcss@8.5.15", "", { "dependencies": { "nanoid": "3.3.12", "picocolors": "1.1.1", "source-map-js": "1.2.1" } }, "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A=="], + + "postgres-array": ["postgres-array@3.0.4", "", {}, "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ=="], + + "postgres-bytea": ["postgres-bytea@3.0.0", "", { "dependencies": { "obuf": "1.1.2" } }, "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw=="], + + "postgres-date": ["postgres-date@2.1.0", "", {}, "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA=="], + + "postgres-interval": ["postgres-interval@3.0.0", "", {}, "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw=="], + + "postgres-range": ["postgres-range@1.1.4", "", {}, "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w=="], + + "postject": ["postject@1.0.0-alpha.6", "", { "dependencies": { "commander": "9.5.0" }, "bin": { "postject": "dist/cli.js" } }, "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A=="], + + "preact": ["preact@11.0.0-beta.0", "", {}, "sha512-IcODoASASYwJ9kxz7+MJeiJhvLriwSb4y4mHIyxdgaRZp6kPUud7xytrk/6GZw8U3y6EFJaRb5wi9SrEK+8+lg=="], + + "preact-render-to-string": ["preact-render-to-string@6.6.5", "", { "peerDependencies": { "preact": ">=10 || >= 11.0.0-0" } }, "sha512-O6MHzYNIKYaiSX3bOw0gGZfEbOmlIDtDfWwN1JJdc/T3ihzRT6tGGSEWE088dWrEDGa1u7101q+6fzQnO9XCPA=="], + + "prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], + + "pretty-cache-header": ["pretty-cache-header@1.0.0", "", { "dependencies": { "timestring": "6.0.0" } }, "sha512-xtXazslu25CdnGnUkByU1RoOjK55TqwatJkjjJLg5ZAdz2Lngko/mmaUgeET36P2GMlNwh3fdM7FWBO717pNcw=="], + + "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "29.6.3", "ansi-styles": "5.2.0", "react-is": "18.3.1" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="], + + "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], + + "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="], + + "process-ancestry": ["process-ancestry@0.1.0", "", {}, "sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg=="], + + "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], + + "progress": ["progress@2.0.3", "", {}, "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="], + + "promise": ["promise@8.3.0", "", { "dependencies": { "asap": "2.0.6" } }, "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg=="], + + "promise-limit": ["promise-limit@2.7.0", "", {}, "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="], + + "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "2.0.3", "retry": "0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], + + "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "3.0.3", "sisteransi": "1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], + + "proper-lockfile": ["proper-lockfile@4.1.2", "", { "dependencies": { "graceful-fs": "4.2.11", "retry": "0.12.0", "signal-exit": "3.0.7" } }, "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA=="], + + "property-information": ["property-information@7.2.0", "", {}, "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg=="], + + "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + + "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "1.4.5", "once": "1.4.0" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], + + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + + "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], + + "pvtsutils": ["pvtsutils@1.3.6", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg=="], + + "pvutils": ["pvutils@1.1.5", "", {}, "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA=="], + + "qs": ["qs@6.15.3", "", { "dependencies": { "es-define-property": "1.0.1", "side-channel": "1.1.1" } }, "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A=="], + + "query-string": ["query-string@7.1.3", "", { "dependencies": { "decode-uri-component": "0.2.2", "filter-obj": "1.1.0", "split-on-first": "1.1.0", "strict-uri-encode": "2.0.0" } }, "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg=="], + + "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "2.0.4" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], + + "radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="], + + "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], + + "raw-body": ["raw-body@3.0.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.1", "iconv-lite": "0.7.2", "unpipe": "1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], + + "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="], + + "react-devtools-core": ["react-devtools-core@6.1.5", "", { "dependencies": { "shell-quote": "1.8.4", "ws": "7.5.11" } }, "sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA=="], + + "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="], + + "react-error-boundary": ["react-error-boundary@6.1.2", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-3DpCr5HVdZ0caUjYE/kIHBEJN0mNP3ZCgf16c48uJ5TbWjorKVp+YG8W3XqlJ7vJAVNw6wNIImyPXmFydwmyng=="], + + "react-freeze": ["react-freeze@1.0.4", "", { "peerDependencies": { "react": ">=17.0.0" } }, "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA=="], + + "react-grab": ["react-grab@0.1.44", "", { "dependencies": { "@react-grab/cli": "0.1.44", "bippy": "0.5.41" }, "peerDependencies": { "react": ">=17.0.0" }, "optionalPeers": ["react"], "bin": { "react-grab": "bin/cli.js" } }, "sha512-bDEwBdI90ljq2lhUtPqmWis/HwYB/CvfT0m5i+P9F83Pt0Ot8o9XL8v00s9jcWzdQUlsFDzmq2FO2CHUe8JY8A=="], + + "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + + "react-markdown": ["react-markdown@10.1.0", "", { "dependencies": { "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "devlop": "1.1.0", "hast-util-to-jsx-runtime": "2.3.6", "html-url-attributes": "3.0.1", "mdast-util-to-hast": "13.2.1", "remark-parse": "11.0.0", "remark-rehype": "11.1.2", "unified": "11.0.5", "unist-util-visit": "5.1.0", "vfile": "6.0.3" }, "peerDependencies": { "@types/react": ">=18", "react": ">=18" } }, "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ=="], + + "react-native": ["react-native@0.85.3", "", { "dependencies": { "@react-native/assets-registry": "0.85.3", "@react-native/codegen": "0.85.3", "@react-native/community-cli-plugin": "0.85.3", "@react-native/gradle-plugin": "0.85.3", "@react-native/js-polyfills": "0.85.3", "@react-native/normalize-colors": "0.85.3", "@react-native/virtualized-lists": "0.85.3", "abort-controller": "3.0.0", "anser": "1.4.10", "ansi-regex": "5.0.1", "babel-plugin-syntax-hermes-parser": "0.33.3", "base64-js": "1.5.1", "commander": "12.1.0", "flow-enums-runtime": "0.0.6", "hermes-compiler": "250829098.0.10", "invariant": "2.2.4", "memoize-one": "5.2.1", "metro-runtime": "0.84.4", "metro-source-map": "0.84.4", "nullthrows": "1.1.1", "pretty-format": "29.7.0", "promise": "8.3.0", "react-devtools-core": "6.1.5", "react-refresh": "0.14.2", "regenerator-runtime": "0.13.11", "scheduler": "0.27.0", "semver": "7.8.5", "stacktrace-parser": "0.1.11", "tinyglobby": "0.2.17", "whatwg-fetch": "3.6.20", "ws": "7.5.11", "yargs": "17.7.2" }, "peerDependencies": { "@react-native/jest-preset": "0.85.3", "@types/react": "^19.1.1", "react": "^19.2.3" }, "optionalPeers": ["@react-native/jest-preset", "@types/react"], "bin": { "react-native": "cli.js" } }, "sha512-HN/fGC+3nZVcDNcw7gfbM/DuqZAvI9Mz+/SxuhODaua4JY0BPzhfTzWXRyTR4mRgMHmShTPpH2PYMTxvZrsdZA=="], + + "react-native-gesture-handler": ["react-native-gesture-handler@2.31.2", "", { "dependencies": { "@egjs/hammerjs": "2.0.17", "@types/react-test-renderer": "19.1.0", "hoist-non-react-statics": "3.3.2", "invariant": "2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-rw5q74i2AfS7YGYdbxQDhOU7xqgY6WRM1132/CCm3erqjblhECZDZFHIm0tteHoC9ih24wogVBVVzcTBQtZ+5A=="], + + "react-native-image-viewing": ["react-native-image-viewing@0.2.2", "", { "peerDependencies": { "react": ">=16.11.0", "react-native": ">=0.61.3" } }, "sha512-osWieG+p/d2NPbAyonOMubttajtYEYiRGQaJA54slFxZ69j1V4/dCmcrVQry47ktVKy8/qpFwCpW1eT6MH5T2Q=="], + + "react-native-is-edge-to-edge": ["react-native-is-edge-to-edge@1.3.1", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-NIXU/iT5+ORyCc7p0z2nnlkouYKX425vuU1OEm6bMMtWWR9yvb+Xg5AZmImTKoF9abxCPqrKC3rOZsKzUYgYZA=="], + + "react-native-keyboard-controller": ["react-native-keyboard-controller@1.21.13", "", { "dependencies": { "react-native-is-edge-to-edge": "1.3.1" }, "peerDependencies": { "react": "*", "react-native": "*", "react-native-reanimated": ">=3.0.0" } }, "sha512-FLr0MucraPyCGykRAcPM8Bv0JT5TcG1juQGMI+GLDuuaoOUKUY3SMUnRhHn7IgSM8KlxpcNQmMPNDmGpOw1OcA=="], + + "react-native-nitro-markdown": ["react-native-nitro-markdown@0.5.8", "", { "peerDependencies": { "react": "*", "react-native": ">=0.75.0", "react-native-mathjax-svg": ">=0.9.0", "react-native-nitro-modules": ">=0.35.5", "react-native-svg": ">=13.0.0" }, "optionalPeers": ["react-native-mathjax-svg", "react-native-svg"] }, "sha512-bBKmdWgMqZoNozuHzJgc8VxWRSjLnrHAK0bRRvz7gj5FqPxLJz+KhRV0VYZDZgvsR3S8hnmmeEqluTRBTRw+yA=="], + + "react-native-nitro-modules": ["react-native-nitro-modules@0.35.9", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-yCO6eJ85SPPUo4a4an7H5oj6wPCSIT72fbjr5WZ/20n6zswaJ2gNNpnWtg2We0AZwkAOjSqkOJ0Vjc05p6kGiA=="], + + "react-native-reanimated": ["react-native-reanimated@4.3.1", "", { "dependencies": { "react-native-is-edge-to-edge": "1.3.1", "semver": "7.8.5" }, "peerDependencies": { "react": "*", "react-native": "0.81 - 0.85", "react-native-worklets": "0.8.x" } }, "sha512-KhGsS0YkCA+gusgyzlf9hnqzVPIR398KTpqXyqq/+yYJJPAvyEEPKcxlB0xtOOXSMrR2A9uRKVARVQhZwrOh+Q=="], + + "react-native-safe-area-context": ["react-native-safe-area-context@5.7.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-/9/MtQz8ODphjsLdZ+GZAIcC/RtoqW9EeShf7Uvnfgm/pzYrJ75y3PV/J1wuAV1T5Dye5ygq4EAW20RoBq0ABQ=="], + + "react-native-screens": ["react-native-screens@4.25.2", "", { "dependencies": { "react-freeze": "1.0.4", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": ">=0.82.0" } }, "sha512-1Nj1fusFd+rIMKU/qC9yGKVG+3ofh11d3OdBQKL1iVvQfKvcB8vhvTGQf2TkfxW3bamxN+hCZIXmNuU0mRkyDg=="], + + "react-native-shiki-engine": ["react-native-shiki-engine@0.3.12", "", { "dependencies": { "@shikijs/types": "4.3.0", "@shikijs/vscode-textmate": "10.0.2" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-CE6CA3uHGZT5OmY909H+vTv5lrmILV7zuPOF2pXRYXWN2qYm5KG7XacEB/Pq1U2+8D0zJoeMveTny/FHEqnipg=="], + + "react-native-svg": ["react-native-svg@15.15.4", "", { "dependencies": { "css-select": "5.2.2", "css-tree": "1.1.3", "warn-once": "0.1.1" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-boT/vIRgj6zZKBpfTPJJiYWMbZE9duBMOwPK6kCSTgxsS947IFMOq9OgIFkpWZTB7t229H24pDRkh3W9ZK/J1A=="], + + "react-native-url-polyfill": ["react-native-url-polyfill@4.0.0", "", { "peerDependencies": { "react-native": "*" } }, "sha512-eqYM3wBAA0eL1sPYbBAoNfbES3+NkgcxUdelQ7QzmoVtqKB5qGG0U13MPTRUroAWK+y2EoJFS3MZUK0fwTf0pA=="], + + "react-native-webview": ["react-native-webview@13.16.1", "", { "dependencies": { "escape-string-regexp": "4.0.0", "invariant": "2.2.4" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-If0eHhoEdOYDcHsX+xBFwHMbWBGK1BvGDQDQdVkwtSIXiq1uiqjkpWVP2uQ1as94J0CzvFE9PUNDuhiX0Z6ubw=="], + + "react-native-worklets": ["react-native-worklets@0.8.3", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "7.29.7", "@babel/plugin-transform-class-properties": "7.29.7", "@babel/plugin-transform-classes": "7.29.7", "@babel/plugin-transform-nullish-coalescing-operator": "7.29.7", "@babel/plugin-transform-optional-chaining": "7.29.7", "@babel/plugin-transform-shorthand-properties": "7.29.7", "@babel/plugin-transform-template-literals": "7.29.7", "@babel/plugin-transform-unicode-regex": "7.29.7", "@babel/preset-typescript": "7.29.7", "convert-source-map": "2.0.0", "semver": "7.8.5" }, "peerDependencies": { "@babel/core": "*", "@react-native/metro-config": "*", "react": "*", "react-native": "0.81 - 0.85" } }, "sha512-oCBJROyLU7yG/1R8s0INMflygTH71bx+5XcYkH0CM938TlhSoVbiunE1WVW5FZa51vwYqfLie/IXMX2s1Kh3eg=="], + + "react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="], + + "react-refresh": ["react-refresh@0.14.2", "", {}, "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA=="], + + "react-remove-scroll": ["react-remove-scroll@2.7.2", "", { "dependencies": { "react-remove-scroll-bar": "2.3.8", "react-style-singleton": "2.2.3", "tslib": "2.8.1", "use-callback-ref": "1.3.3", "use-sidecar": "1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "2.2.3", "tslib": "2.8.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "1.0.1", "tslib": "2.8.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + + "read-binary-file-arch": ["read-binary-file-arch@1.0.6", "", { "dependencies": { "debug": "4.4.3" }, "bin": { "read-binary-file-arch": "cli.js" } }, "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg=="], + + "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "1.0.2", "inherits": "2.0.4", "isarray": "1.0.0", "process-nextick-args": "2.0.1", "safe-buffer": "5.1.2", "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], + + "redis-errors": ["redis-errors@1.2.0", "", {}, "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w=="], + + "redis-parser": ["redis-parser@3.0.0", "", { "dependencies": { "redis-errors": "1.2.0" } }, "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A=="], + + "reftools": ["reftools@1.1.9", "", {}, "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w=="], + + "regenerate": ["regenerate@1.4.2", "", {}, "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="], + + "regenerate-unicode-properties": ["regenerate-unicode-properties@10.2.2", "", { "dependencies": { "regenerate": "1.4.2" } }, "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g=="], + + "regenerator-runtime": ["regenerator-runtime@0.13.11", "", {}, "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="], + + "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "regexpu-core": ["regexpu-core@6.4.0", "", { "dependencies": { "regenerate": "1.4.2", "regenerate-unicode-properties": "10.2.2", "regjsgen": "0.8.0", "regjsparser": "0.13.1", "unicode-match-property-ecmascript": "2.0.0", "unicode-match-property-value-ecmascript": "2.2.1" } }, "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA=="], + + "regjsgen": ["regjsgen@0.8.0", "", {}, "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q=="], + + "regjsparser": ["regjsparser@0.13.1", "", { "dependencies": { "jsesc": "3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw=="], + + "rehype": ["rehype@13.0.2", "", { "dependencies": { "@types/hast": "3.0.4", "rehype-parse": "9.0.1", "rehype-stringify": "10.0.1", "unified": "11.0.5" } }, "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A=="], + + "rehype-parse": ["rehype-parse@9.0.1", "", { "dependencies": { "@types/hast": "3.0.4", "hast-util-from-html": "2.0.3", "unified": "11.0.5" } }, "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag=="], + + "rehype-raw": ["rehype-raw@7.0.0", "", { "dependencies": { "@types/hast": "3.0.4", "hast-util-raw": "9.1.0", "vfile": "6.0.3" } }, "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww=="], + + "rehype-sanitize": ["rehype-sanitize@6.0.0", "", { "dependencies": { "@types/hast": "3.0.4", "hast-util-sanitize": "5.0.2" } }, "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg=="], + + "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "3.0.4", "hast-util-to-html": "9.0.5", "unified": "11.0.5" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="], + + "remark-breaks": ["remark-breaks@4.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "mdast-util-newline-to-break": "2.0.0", "unified": "11.0.5" } }, "sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ=="], + + "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "4.0.4", "mdast-util-gfm": "3.1.0", "micromark-extension-gfm": "3.0.0", "remark-parse": "11.0.0", "remark-stringify": "11.0.0", "unified": "11.0.5" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], + + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "mdast-util-from-markdown": "2.0.3", "micromark-util-types": "2.0.2", "unified": "11.0.5" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + + "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "mdast-util-to-hast": "13.2.1", "unified": "11.0.5", "vfile": "6.0.3" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], + + "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "4.0.4", "mdast-util-to-markdown": "2.1.2", "unified": "11.0.5" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + + "request-light": ["request-light@0.7.0", "", {}, "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "resedit": ["resedit@1.7.2", "", { "dependencies": { "pe-library": "0.4.1" } }, "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA=="], + + "reselect": ["reselect@5.2.0", "", {}, "sha512-AgZ3UOZm3YndfrJ4OYjgrT7bmCm/1iqkjvEfH/oYjzh6PD2qw4QuT3jjnXIrpdt4MTpMXclMT3lXbmRY+XRakw=="], + + "resolve": ["resolve@1.22.12", "", { "dependencies": { "es-errors": "1.3.0", "is-core-module": "2.16.2", "path-parse": "1.0.7", "supports-preserve-symlinks-flag": "1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA=="], + + "resolve-alpn": ["resolve-alpn@1.2.1", "", {}, "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="], + + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], + + "resolve-workspace-root": ["resolve-workspace-root@2.0.1", "", {}, "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w=="], + + "responselike": ["responselike@2.0.1", "", { "dependencies": { "lowercase-keys": "2.0.0" } }, "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw=="], + + "restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "5.1.2", "signal-exit": "3.0.7" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="], + + "retext-smartypants": ["retext-smartypants@6.2.0", "", { "dependencies": { "@types/nlcst": "2.0.3", "nlcst-to-string": "4.0.0", "unist-util-visit": "5.1.0" } }, "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ=="], + + "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], + + "rettime": ["rettime@0.10.1", "", {}, "sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rimraf": ["rimraf@2.6.3", "", { "dependencies": { "glob": "7.2.3" }, "bin": { "rimraf": "./bin.js" } }, "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA=="], + + "roarr": ["roarr@2.15.4", "", { "dependencies": { "boolean": "3.2.0", "detect-node": "2.1.0", "globalthis": "1.0.4", "json-stringify-safe": "5.0.1", "semver-compare": "1.0.0", "sprintf-js": "1.1.3" } }, "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A=="], + + "rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "0.139.0", "@rolldown/pluginutils": "1.0.1" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="], + + "router": ["router@2.2.0", "", { "dependencies": { "debug": "4.4.3", "depd": "2.0.0", "is-promise": "4.0.0", "parseurl": "1.3.3", "path-to-regexp": "8.4.2" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "1.2.3" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "sanitize-filename": ["sanitize-filename@1.6.4", "", { "dependencies": { "truncate-utf8-bytes": "1.0.2" } }, "sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg=="], + + "satteri": ["satteri@0.9.3", "", { "dependencies": { "@types/estree-jsx": "1.0.5", "@types/hast": "3.0.4", "@types/mdast": "4.0.4", "@types/unist": "3.0.3" }, "optionalDependencies": { "@bruits/satteri-darwin-arm64": "0.9.3", "@bruits/satteri-darwin-x64": "0.9.3", "@bruits/satteri-linux-arm64-gnu": "0.9.3", "@bruits/satteri-linux-arm64-musl": "0.9.3", "@bruits/satteri-linux-x64-gnu": "0.9.3", "@bruits/satteri-linux-x64-musl": "0.9.3", "@bruits/satteri-wasm32-wasi": "0.9.3", "@bruits/satteri-win32-arm64-msvc": "0.9.3", "@bruits/satteri-win32-x64-msvc": "0.9.3" } }, "sha512-2XfBh89LCnBMFkNOeVKkBLelAZcIA17VLHsgJum1tJ2fXiPZDN/TDXv4ku46rFOQXYd41LJ0kiZh5gPqExcCsg=="], + + "sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="], + + "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], + + "schema-utils": ["schema-utils@4.3.3", "", { "dependencies": { "@types/json-schema": "7.0.15", "ajv": "8.20.0", "ajv-formats": "2.1.1", "ajv-keywords": "5.1.0" } }, "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA=="], + + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "semver-compare": ["semver-compare@1.0.0", "", {}, "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="], + + "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "2.0.0", "escape-html": "1.0.3", "etag": "1.8.1", "fresh": "0.5.2", "http-errors": "2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "1.2.1", "statuses": "2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], + + "serialize-error": ["serialize-error@7.0.1", "", { "dependencies": { "type-fest": "0.13.1" } }, "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw=="], + + "seroval": ["seroval@1.5.4", "", {}, "sha512-46uFvgrXTVxZcUorgSSRZ4y+ieqLLQRMlG4bnCZKW3qI6BZm7Rg4ntMW4p1mILEEBZWrFlcpp0AyIIlM6jD9iw=="], + + "seroval-plugins": ["seroval-plugins@1.5.4", "", { "peerDependencies": { "seroval": "^1.0" } }, "sha512-S0xQPhUTefAhNvNWFg0c1J8qJArHt5KdtJ/cFAofo06KD1MVSeFWyl4iiu+ApDIuw0WhjpOfCdgConOfAnLgkw=="], + + "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "2.0.0", "escape-html": "1.0.3", "parseurl": "1.3.3", "send": "0.19.2" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], + + "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], + + "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], + + "sf-symbols-typescript": ["sf-symbols-typescript@2.2.0", "", {}, "sha512-TPbeg0b7ylrswdGCji8FRGFAKuqbpQlLbL8SOle3j1iHSs5Ob5mhvMAxWN2UItOjgALAB5Zp3fmMfj8mbWvXKw=="], + + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "1.1.0", "detect-libc": "2.1.2", "semver": "7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="], + + "shiki": ["shiki@4.2.0", "", { "dependencies": { "@shikijs/core": "4.2.0", "@shikijs/engine-javascript": "4.2.0", "@shikijs/engine-oniguruma": "4.2.0", "@shikijs/langs": "4.2.0", "@shikijs/themes": "4.2.0", "@shikijs/types": "4.2.0", "@shikijs/vscode-textmate": "10.0.2", "@types/hast": "3.0.4" } }, "sha512-hjNax6o/ylDy9lefQEaSDtzaT3iVNtZ3WmpQnbuQNoG4xvnSKf2kSKbihZVO4JRG1TTMejs7CmNRYlWgAL66pQ=="], + + "should": ["should@13.2.3", "", { "dependencies": { "should-equal": "2.0.0", "should-format": "3.0.3", "should-type": "1.4.0", "should-type-adaptors": "1.1.0", "should-util": "1.0.1" } }, "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ=="], + + "should-equal": ["should-equal@2.0.0", "", { "dependencies": { "should-type": "1.4.0" } }, "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA=="], + + "should-format": ["should-format@3.0.3", "", { "dependencies": { "should-type": "1.4.0", "should-type-adaptors": "1.1.0" } }, "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q=="], + + "should-type": ["should-type@1.4.0", "", {}, "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ=="], + + "should-type-adaptors": ["should-type-adaptors@1.1.0", "", { "dependencies": { "should-type": "1.4.0", "should-util": "1.0.1" } }, "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA=="], + + "should-util": ["should-util@1.0.1", "", {}, "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g=="], + + "side-channel": ["side-channel@1.1.1", "", { "dependencies": { "es-errors": "1.3.0", "object-inspect": "1.13.4", "side-channel-list": "1.0.1", "side-channel-map": "1.0.1", "side-channel-weakmap": "1.0.2" } }, "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ=="], + + "side-channel-list": ["side-channel-list@1.0.1", "", { "dependencies": { "es-errors": "1.3.0", "object-inspect": "1.13.4" } }, "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w=="], + + "side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "1.0.4", "es-errors": "1.3.0", "get-intrinsic": "1.3.0", "object-inspect": "1.13.4" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], + + "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "1.0.4", "es-errors": "1.3.0", "get-intrinsic": "1.3.0", "object-inspect": "1.13.4", "side-channel-map": "1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], + + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "simple-plist": ["simple-plist@1.3.1", "", { "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.1", "plist": "3.1.1" } }, "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw=="], + + "simple-swizzle": ["simple-swizzle@0.2.4", "", { "dependencies": { "is-arrayish": "0.3.4" } }, "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw=="], + + "simple-update-notifier": ["simple-update-notifier@2.0.0", "", { "dependencies": { "semver": "7.8.5" } }, "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w=="], + + "sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "1.0.0-next.29", "mrmime": "2.0.1", "totalist": "3.0.1" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="], + + "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + + "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "6.2.3", "is-fullwidth-code-point": "5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], + + "slugify": ["slugify@1.6.9", "", {}, "sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg=="], + + "smol-toml": ["smol-toml@1.7.0", "", {}, "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ=="], + + "source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "1.1.2", "source-map": "0.6.1" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "sparse-bitfield": ["sparse-bitfield@3.0.3", "", { "dependencies": { "memory-pager": "1.5.0" } }, "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ=="], + + "split-on-first": ["split-on-first@1.1.0", "", {}, "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="], + + "split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], + + "sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + + "sql-escaper": ["sql-escaper@1.3.3", "", {}, "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw=="], + + "stack-utils": ["stack-utils@2.0.6", "", { "dependencies": { "escape-string-regexp": "2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "stackframe": ["stackframe@1.3.4", "", {}, "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw=="], + + "stacktrace-parser": ["stacktrace-parser@0.1.11", "", { "dependencies": { "type-fest": "0.7.1" } }, "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg=="], + + "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], + + "standard-navigation": ["standard-navigation@0.0.7", "", {}, "sha512-NCGLCNyuXrFOkGHxdNZFnpsehGtiq1oXbPhKl7ZuxFO5J//H2evqqOchmD4YwEUJnkjO4kH9Xp4hQX6hdAYCKQ=="], + + "standardwebhooks": ["standardwebhooks@1.0.0", "", { "dependencies": { "@stablelib/base64": "1.0.1", "fast-sha256": "1.3.0" } }, "sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg=="], + + "stat-mode": ["stat-mode@1.0.0", "", {}, "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg=="], + + "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + + "std-env": ["std-env@4.1.0", "", {}, "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ=="], + + "stdin-discarder": ["stdin-discarder@0.3.2", "", {}, "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A=="], + + "stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="], + + "strict-event-emitter": ["strict-event-emitter@0.5.1", "", {}, "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ=="], + + "strict-uri-encode": ["strict-uri-encode@2.0.0", "", {}, "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="], + + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "8.0.0", "is-fullwidth-code-point": "3.0.0", "strip-ansi": "6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "5.1.2" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "2.1.0", "character-entities-legacy": "3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strnum": ["strnum@2.3.0", "", {}, "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q=="], + + "structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="], + + "style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="], + + "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], + + "sumchecker": ["sumchecker@3.0.1", "", { "dependencies": { "debug": "4.4.3" } }, "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg=="], + + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-hyperlinks": ["supports-hyperlinks@2.3.0", "", { "dependencies": { "has-flag": "4.0.0", "supports-color": "7.2.0" } }, "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "svgo": ["svgo@4.0.1", "", { "dependencies": { "commander": "11.1.0", "css-select": "5.2.2", "css-tree": "3.2.1", "css-what": "6.2.2", "csso": "5.0.5", "picocolors": "1.1.1", "sax": "1.6.0" }, "bin": "./bin/svgo.js" }, "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w=="], + + "swagger2openapi": ["swagger2openapi@7.0.8", "", { "dependencies": { "call-me-maybe": "1.0.2", "node-fetch": "2.7.0", "node-fetch-h2": "2.3.0", "node-readfiles": "0.2.0", "oas-kit-common": "1.0.8", "oas-resolver": "2.5.6", "oas-schema-walker": "1.1.5", "oas-validator": "5.0.8", "reftools": "1.1.9", "yaml": "2.9.0", "yargs": "17.7.2" }, "bin": { "swagger2openapi": "swagger2openapi.js", "oas-validate": "oas-validate.js", "boast": "boast.js" } }, "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g=="], + + "t3": ["t3@workspace:apps/server"], + + "t3code-relay": ["t3code-relay@workspace:infra/relay"], + + "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], + + "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="], + + "tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="], + + "tailwindcss": ["tailwindcss@4.3.0", "", {}, "sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q=="], + + "tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="], + + "tar": ["tar@7.5.16", "", { "dependencies": { "@isaacs/fs-minipass": "4.0.1", "chownr": "3.0.0", "minipass": "7.1.3", "minizlib": "3.1.0", "yallist": "5.0.0" } }, "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w=="], + + "temp": ["temp@0.9.4", "", { "dependencies": { "mkdirp": "0.5.6", "rimraf": "2.6.3" } }, "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA=="], + + "temp-file": ["temp-file@3.4.0", "", { "dependencies": { "async-exit-hook": "2.0.1", "fs-extra": "10.1.0" } }, "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg=="], + + "terminal-link": ["terminal-link@2.1.1", "", { "dependencies": { "ansi-escapes": "4.3.2", "supports-hyperlinks": "2.3.0" } }, "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="], + + "terminal-size": ["terminal-size@4.0.1", "", {}, "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ=="], + + "terser": ["terser@5.48.0", "", { "dependencies": { "@jridgewell/source-map": "0.3.11", "acorn": "8.16.0", "commander": "2.20.3", "source-map-support": "0.5.21" }, "bin": { "terser": "bin/terser" } }, "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q=="], + + "throat": ["throat@5.0.0", "", {}, "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA=="], + + "timestring": ["timestring@6.0.0", "", {}, "sha512-wMctrWD2HZZLuIlchlkE2dfXJh7J2KDI9Dwl+2abPYg0mswQHfOAyQW3jJg1pY5VfttSINZuKcXoB3FGypVklA=="], + + "tiny-async-pool": ["tiny-async-pool@1.3.0", "", { "dependencies": { "semver": "5.7.2" } }, "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA=="], + + "tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="], + + "tiny-typed-emitter": ["tiny-typed-emitter@2.1.0", "", {}, "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyclip": ["tinyclip@0.1.15", "", {}, "sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A=="], + + "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], + + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "6.5.0", "picomatch": "4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + + "tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="], + + "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], + + "tldts": ["tldts@7.4.2", "", { "dependencies": { "tldts-core": "7.4.2" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw=="], + + "tldts-core": ["tldts-core@7.4.2", "", {}, "sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA=="], + + "tmp": ["tmp@0.2.7", "", {}, "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw=="], + + "tmp-promise": ["tmp-promise@3.0.3", "", { "dependencies": { "tmp": "0.2.7" } }, "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ=="], + + "tmpl": ["tmpl@1.0.5", "", {}, "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + + "toml": ["toml@4.3.0", "", {}, "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A=="], + + "toqr": ["toqr@0.1.1", "", {}, "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA=="], + + "totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="], + + "tough-cookie": ["tough-cookie@6.0.1", "", { "dependencies": { "tldts": "7.4.2" } }, "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw=="], + + "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + + "truncate-utf8-bytes": ["truncate-utf8-bytes@1.0.2", "", { "dependencies": { "utf8-byte-length": "1.0.5" } }, "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ=="], + + "ts-algebra": ["ts-algebra@2.0.0", "", {}, "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + + "type-is": ["type-is@2.1.0", "", { "dependencies": { "content-type": "2.0.0", "media-typer": "1.1.0", "mime-types": "3.0.2" } }, "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA=="], + + "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], + + "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], + + "typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "7.8.5" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="], + + "ua-parser-js": ["ua-parser-js@0.7.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg=="], + + "ufo": ["ufo@1.6.4", "", {}, "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA=="], + + "ultrahtml": ["ultrahtml@1.6.0", "", {}, "sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw=="], + + "uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="], + + "undici": ["undici@8.9.0", "", {}, "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + + "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], + + "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], + + "unicode-match-property-ecmascript": ["unicode-match-property-ecmascript@2.0.0", "", { "dependencies": { "unicode-canonical-property-names-ecmascript": "2.0.1", "unicode-property-aliases-ecmascript": "2.2.0" } }, "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q=="], + + "unicode-match-property-value-ecmascript": ["unicode-match-property-value-ecmascript@2.2.1", "", {}, "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg=="], + + "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="], + + "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "3.0.3", "bail": "2.0.2", "devlop": "1.1.0", "extend": "3.0.2", "is-plain-obj": "4.1.0", "trough": "2.2.0", "vfile": "6.0.3" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], + + "unifont": ["unifont@0.7.4", "", { "dependencies": { "css-tree": "3.2.1", "ofetch": "1.5.1", "ohash": "2.0.11" } }, "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "3.0.3" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "3.0.3" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "3.0.3" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "3.0.3", "unist-util-is": "6.0.1", "unist-util-visit-parents": "6.0.2" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "3.0.3", "unist-util-is": "6.0.1" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="], + + "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + + "uniwind": ["uniwind@1.7.0", "", { "dependencies": { "@tailwindcss/node": "4.2.1", "@tailwindcss/oxide": "4.2.1", "culori": "4.0.2", "lightningcss": "1.30.1" }, "peerDependencies": { "react": ">=19.0.0", "react-native": ">=0.81.0", "tailwindcss": ">=4" } }, "sha512-kIixWI3OprrWf/ypjglV2xubYvzCjtTKk110rQmXn8A3ZA/7z/nK6P/8EMxbfPCxjkdvhLcMniafa4qJcYIhZA=="], + + "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], + + "unplugin": ["unplugin@3.0.0", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "picomatch": "4.0.4", "webpack-virtual-modules": "0.6.2" } }, "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg=="], + + "unstorage": ["unstorage@1.17.5", "", { "dependencies": { "anymatch": "3.1.3", "chokidar": "5.0.0", "destr": "2.0.5", "h3": "1.15.11", "lru-cache": "11.5.1", "node-fetch-native": "1.6.7", "ofetch": "1.5.1", "ufo": "1.6.4" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6 || ^7 || ^8", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/functions": "^2.2.12 || ^3.0.0", "@vercel/kv": "^1 || ^2 || ^3", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/functions", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg=="], + + "until-async": ["until-async@3.0.2", "", {}, "sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw=="], + + "unzipper": ["unzipper@0.12.5", "", { "dependencies": { "bluebird": "3.7.2", "duplexer2": "0.1.4", "fs-extra": "11.3.1", "graceful-fs": "4.2.11", "node-int64": "0.4.0" } }, "sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A=="], + + "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "3.2.0", "picocolors": "1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], + + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "2.3.1" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "2.8.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-latest-callback": ["use-latest-callback@0.2.6", "", { "peerDependencies": { "react": ">=16.8" } }, "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "1.1.0", "tslib": "2.8.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + + "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + + "utf8-byte-length": ["utf8-byte-length@1.0.5", "", {}, "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], + + "uuid": ["uuid@14.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew=="], + + "validate-npm-package-name": ["validate-npm-package-name@5.0.1", "", {}, "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="], + + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], + + "vaul": ["vaul@1.1.2", "", { "dependencies": { "@radix-ui/react-dialog": "1.1.15" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "3.0.3", "vfile-message": "4.0.3" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "3.0.3", "vfile": "6.0.3" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "3.0.3", "unist-util-stringify-position": "4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vite": ["@voidzero-dev/vite-plus-core@0.2.2", "", { "dependencies": { "@oxc-project/runtime": "0.138.0", "@oxc-project/types": "0.138.0", "lightningcss": "1.32.0", "postcss": "8.5.15" }, "optionalDependencies": { "fsevents": "2.3.3" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@types/node": "24.12.4", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "publint": "^0.3.8", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "unrun": "*", "yaml": "^2.9.0" }, "optionalPeers": ["@arethetypeswrong/core", "@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "publint", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "typescript", "unplugin-unused", "unrun", "yaml"] }, "sha512-yAbKexF3npOGjg1N5EtXxun+7vdM/0x6QE5jucO/dv0LFhCAIzSN3UvLVCeamJt/Bz3jt7DLqQHEgXXrjy8drA=="], + + "vite-plus": ["vite-plus@0.2.2", "", { "dependencies": { "@oxc-project/types": "0.138.0", "@oxlint/plugins": "1.68.0", "@vitest/browser": "4.1.9", "@vitest/browser-preview": "4.1.9", "@vitest/expect": "4.1.9", "@vitest/mocker": "4.1.9", "@vitest/pretty-format": "4.1.9", "@vitest/runner": "4.1.9", "@vitest/snapshot": "4.1.9", "@vitest/spy": "4.1.9", "@vitest/utils": "4.1.9", "@voidzero-dev/vite-plus-core": "0.2.2", "oxfmt": "0.57.0", "oxlint": "1.72.0", "oxlint-tsgolint": "0.24.0", "vite": "npm:@voidzero-dev/vite-plus-core@0.2.2", "vitest": "4.1.9" }, "optionalDependencies": { "@voidzero-dev/vite-plus-darwin-arm64": "0.2.2", "@voidzero-dev/vite-plus-darwin-x64": "0.2.2", "@voidzero-dev/vite-plus-linux-arm64-gnu": "0.2.2", "@voidzero-dev/vite-plus-linux-arm64-musl": "0.2.2", "@voidzero-dev/vite-plus-linux-x64-gnu": "0.2.2", "@voidzero-dev/vite-plus-linux-x64-musl": "0.2.2", "@voidzero-dev/vite-plus-win32-arm64-msvc": "0.2.2", "@voidzero-dev/vite-plus-win32-x64-msvc": "0.2.2" }, "peerDependencies": { "@vitest/browser-playwright": "4.1.9", "@vitest/browser-webdriverio": "4.1.9" }, "optionalPeers": ["@vitest/browser-playwright", "@vitest/browser-webdriverio"], "bin": { "vp": "bin/vp", "vpr": "bin/vpr", "oxfmt": "bin/oxfmt", "oxlint": "bin/oxlint" } }, "sha512-bXO3O0F2/uxtvX9Ck0o67stTErH/Zh0GEcCMd9pAh22tTHABCNTDPrRMWVo733e7Ux3h0Y7HanJ7neOV/nid4g=="], + + "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], + + "vitest": ["vitest@4.1.9", "", { "dependencies": { "@vitest/expect": "4.1.9", "@vitest/mocker": "4.1.9", "@vitest/pretty-format": "4.1.9", "@vitest/runner": "4.1.9", "@vitest/snapshot": "4.1.9", "@vitest/spy": "4.1.9", "@vitest/utils": "4.1.9", "es-module-lexer": "2.1.0", "expect-type": "1.4.0", "magic-string": "0.30.21", "obug": "2.1.3", "pathe": "2.0.3", "picomatch": "4.0.4", "std-env": "4.1.0", "tinybench": "2.9.0", "tinyexec": "1.2.4", "tinyglobby": "0.2.17", "tinyrainbow": "3.1.0", "why-is-node-running": "2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "24.12.4", "@vitest/browser-playwright": "4.1.9", "@vitest/browser-preview": "4.1.9", "@vitest/browser-webdriverio": "4.1.9", "@vitest/coverage-istanbul": "4.1.9", "@vitest/coverage-v8": "4.1.9", "@vitest/ui": "4.1.9", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["@edge-runtime/vm", "@opentelemetry/api", "@types/node", "@vitest/browser-playwright", "@vitest/browser-preview", "@vitest/browser-webdriverio", "@vitest/coverage-istanbul", "@vitest/coverage-v8", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "./vitest.mjs" } }, "sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ=="], + + "vlq": ["vlq@1.0.1", "", {}, "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="], + + "volar-service-css": ["volar-service-css@0.0.70", "", { "dependencies": { "vscode-css-languageservice": "6.3.10", "vscode-languageserver-textdocument": "1.0.12", "vscode-uri": "3.1.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-K1qyOvBpE3rzdAv3e4/6Rv5yizrYPy5R/ne3IWCAzLBuMO4qBMV3kSqWzj6KUVe6S0AnN6wxF7cRkiaKfYMYJw=="], + + "volar-service-emmet": ["volar-service-emmet@0.0.70", "", { "dependencies": { "@emmetio/css-parser": "0.4.1", "@emmetio/html-matcher": "1.3.0", "@vscode/emmet-helper": "2.11.0", "vscode-uri": "3.1.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-xi5bC4m/VyE3zy/n2CXspKeDZs3qA41tHLTw275/7dNWM/RqE2z3BnDICQybHIVp/6G1iOQj5c1qXMgQC08TNg=="], + + "volar-service-html": ["volar-service-html@0.0.70", "", { "dependencies": { "vscode-html-languageservice": "5.6.2", "vscode-languageserver-textdocument": "1.0.12", "vscode-uri": "3.1.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-eR6vCgMdmYAo4n+gcT7DSyBQbwB8S3HZZvSagTf0sxNaD4WppMCFfpqWnkrlGStPKMZvMiejRRVmqsX9dYcTvQ=="], + + "volar-service-prettier": ["volar-service-prettier@0.0.70", "", { "dependencies": { "vscode-uri": "3.1.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0", "prettier": "^2.2 || ^3.0" }, "optionalPeers": ["@volar/language-service", "prettier"] }, "sha512-Z6BCFSpGVCd8BPAsZ785Kce1BGlWd5ODqmqZGVuB14MJvrR4+CYz6cDy4F+igmE1gMifqfvMhdgT8Aud4M5ngg=="], + + "volar-service-typescript": ["volar-service-typescript@0.0.70", "", { "dependencies": { "path-browserify": "1.0.1", "semver": "7.8.5", "typescript-auto-import-cache": "0.3.6", "vscode-languageserver-textdocument": "1.0.12", "vscode-nls": "5.2.0", "vscode-uri": "3.1.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-l46Bx4cokkUedTd74ojO5H/zqHZJ8SUuyZ0IB8JN4jfRqUM3bQFBHoOwlZCyZmOeO0A3RQNkMnFclxO4c++gsg=="], + + "volar-service-typescript-twoslash-queries": ["volar-service-typescript-twoslash-queries@0.0.70", "", { "dependencies": { "vscode-uri": "3.1.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-IdD13Z9N2Bu8EM6CM0fDV1E69olEYGHDU25X51YXmq8Y0CmJ2LNj6gOiBJgpS5JGUqFzECVhMNBW7R0sPdRTMQ=="], + + "volar-service-yaml": ["volar-service-yaml@0.0.70", "", { "dependencies": { "vscode-uri": "3.1.0", "yaml-language-server": "1.20.0" }, "peerDependencies": { "@volar/language-service": "~2.4.0" }, "optionalPeers": ["@volar/language-service"] }, "sha512-0c8bXDBeoATF9F6iPIlOuYTuZAC4c+yi0siQo920u7eiBJk8oQmUmg9cDUbR4+Gl++bvGP4plj3fErbJuPqdcQ=="], + + "vscode-css-languageservice": ["vscode-css-languageservice@6.3.10", "", { "dependencies": { "@vscode/l10n": "0.0.18", "vscode-languageserver-textdocument": "1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "3.1.0" } }, "sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA=="], + + "vscode-html-languageservice": ["vscode-html-languageservice@5.6.2", "", { "dependencies": { "@vscode/l10n": "0.0.18", "vscode-languageserver-textdocument": "1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "3.1.0" } }, "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg=="], + + "vscode-json-languageservice": ["vscode-json-languageservice@4.1.8", "", { "dependencies": { "jsonc-parser": "3.3.1", "vscode-languageserver-textdocument": "1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-nls": "5.2.0", "vscode-uri": "3.1.0" } }, "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg=="], + + "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], + + "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], + + "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="], + + "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="], + + "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], + + "vscode-nls": ["vscode-nls@5.2.0", "", {}, "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="], + + "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], + + "walker": ["walker@1.0.8", "", { "dependencies": { "makeerror": "1.0.12" } }, "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ=="], + + "warn-once": ["warn-once@0.1.1", "", {}, "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q=="], + + "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "1.0.4" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], + + "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], + + "webcrypto-core": ["webcrypto-core@1.9.2", "", { "dependencies": { "@peculiar/asn1-schema": "2.8.0", "@peculiar/json-schema": "1.1.12", "@peculiar/utils": "2.0.3", "asn1js": "3.0.10", "tslib": "2.8.1" } }, "sha512-gsXecm82UQNlTBURJGuqOWy1Ww08S3kZUcr3aOJS02Pk0xLtkfeUAVC0u0xhgdonFme80edSJUIJyuvL/7250Q=="], + + "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + + "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], + + "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], + + "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "0.0.3", "webidl-conversions": "3.0.1" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + + "whatwg-url-minimum": ["whatwg-url-minimum@0.1.2", "", {}, "sha512-XPEm0XFQWNVG292lII1PrRRJl3sItrs7CettZ4ncYxuDVpLyy+NwlGyut2hXI0JswcJUxeCH+CyOJK0ZzAXD6A=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + + "widest-line": ["widest-line@6.0.0", "", { "dependencies": { "string-width": "8.2.1" } }, "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA=="], + + "workerd": ["workerd@1.20260704.1", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260704.1", "@cloudflare/workerd-darwin-arm64": "1.20260704.1", "@cloudflare/workerd-linux-64": "1.20260704.1", "@cloudflare/workerd-linux-arm64": "1.20260704.1", "@cloudflare/workerd-windows-64": "1.20260704.1" }, "bin": { "workerd": "bin/workerd" } }, "sha512-GDZ0jzIYDYfN7rCt/oFJv4BG3QJ+4IS2kfRvxEMY9VKIfPhzo63PH69Ir7ug8LfORCgCtmfkiQVXrqbot7pZTQ=="], + + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "4.3.0", "string-width": "4.2.3", "strip-ansi": "6.0.1" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + + "ws": ["ws@7.5.11", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-zS54Oen9bITtp7kp2XM3AydrCIq1D+HwJOuH+c+e4LfpL/lotP5osijd+UoMnxwAam1GN8R4KtLAyIrIcBNpiA=="], + + "xcode": ["xcode@3.0.1", "", { "dependencies": { "simple-plist": "1.3.1", "uuid": "7.0.3" } }, "sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA=="], + + "xml-naming": ["xml-naming@0.1.0", "", {}, "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw=="], + + "xml2js": ["xml2js@0.6.0", "", { "dependencies": { "sax": "1.6.0", "xmlbuilder": "11.0.1" } }, "sha512-eLTh0kA8uHceqesPqSE+VvO1CDDJWMwlQfB6LuN6T8w6MaDJ8Txm8P7s5cHD0miF0V+GGTZrDQfxPZQVsur33w=="], + + "xmlbuilder": ["xmlbuilder@15.1.1", "", {}, "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg=="], + + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], + + "xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + + "yaml-language-server": ["yaml-language-server@1.20.0", "", { "dependencies": { "@vscode/l10n": "0.0.18", "ajv": "8.20.0", "ajv-draft-04": "1.0.0", "prettier": "3.8.3", "request-light": "0.5.8", "vscode-json-languageservice": "4.1.8", "vscode-languageserver": "9.0.1", "vscode-languageserver-textdocument": "1.0.12", "vscode-languageserver-types": "3.17.5", "vscode-uri": "3.1.0", "yaml": "2.9.0" }, "bin": { "yaml-language-server": "bin/yaml-language-server" } }, "sha512-qhjK/bzSRZ6HtTvgeFvjNPJGWdZ0+x5NREV/9XZWFjIGezew2b4r5JPy66IfOhd5OA7KeFwk1JfmEbnTvev0cA=="], + + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "8.0.1", "escalade": "3.2.0", "get-caller-file": "2.0.5", "require-directory": "2.1.1", "string-width": "4.2.3", "y18n": "5.0.8", "yargs-parser": "21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="], + + "yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "0.2.13", "fd-slicer": "1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], + + "yjs": ["yjs@13.6.31", "", { "dependencies": { "lib0": "0.2.117" } }, "sha512-Eq+5BRfbeGyqGVrTJL3bEcr8gKkxPuyuoHmAwpk52fDb8kOVMrfVSTRPd6yiGgX5Fskb96qCRjzjbRjrL4YEnw=="], + + "yocto-queue": ["yocto-queue@1.2.2", "", {}, "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="], + + "yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="], + + "yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="], + + "yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="], + + "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + + "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], + + "zustand": ["zustand@5.0.14", "", { "peerDependencies": { "@types/react": ">=18.0.0", "immer": ">=9.0.6", "react": ">=18.0.0", "use-sync-external-store": ">=1.2.0" }, "optionalPeers": ["@types/react", "immer", "react", "use-sync-external-store"] }, "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "zxing-wasm": ["zxing-wasm@3.1.0", "", { "dependencies": { "type-fest": "5.7.0" }, "peerDependencies": { "@types/emscripten": ">=1.39.6" } }, "sha512-5+3V1wPRx4gvbeLH2jB7n2cKrYJ1q4i3QgjnBUtrDPeqxJSi6BdzKJg4y6aF6bgW8zfntnYJyrkqFMevDhL2NA=="], + + "@alcalzone/ansi-tokenize/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "@alcalzone/ansi-tokenize/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "1.6.0" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "@anthropic-ai/claude-agent-sdk/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "@aws-sdk/xml-builder/fast-xml-parser": ["fast-xml-parser@5.7.3", "", { "dependencies": { "@nodable/entities": "2.1.1", "fast-xml-builder": "1.2.0", "path-expression-matcher": "1.5.0", "strnum": "2.3.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg=="], + + "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "3.1.1" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], + + "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-create-class-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/helper-create-regexp-features-plugin/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@babel/plugin-transform-react-jsx-development/@babel/plugin-transform-react-jsx": ["@babel/plugin-transform-react-jsx@7.29.7", "", { "dependencies": { "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-module-imports": "7.29.7", "@babel/helper-plugin-utils": "7.29.7", "@babel/plugin-syntax-jsx": "7.29.7", "@babel/types": "7.29.7" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-WsZulLVBUHXVj2cUcPVx6UE21TpalB6bHbSFErKT0Ib++ax24jjXe73FqlWvdylFOjiuPHYi6VCcgRad1ItN+A=="], + + "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@effect/atom-react/react": ["react@19.2.6", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="], + + "@effect/platform-node-shared/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "@effect/sql-d1/@cloudflare/workers-types": ["@cloudflare/workers-types@5.20260726.1", "", {}, "sha512-fKgRSm3sDmOdak1LGWehS4vSPSj7/zeu0NfmE62VPjBMqWgODcOGljYvq6A75sL+7YfY3iGFGb0jVEDYq+hlmw=="], + + "@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], + + "@electron/asar/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "1.0.0", "inflight": "1.0.6", "inherits": "2.0.4", "minimatch": "3.1.5", "once": "1.4.0", "path-is-absolute": "1.0.1" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "@electron/fuses/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "1.0.0", "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "4.0.0", "universalify": "0.1.2" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "@electron/notarize/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "1.0.0", "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@electron/osx-sign/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@electron/universal/fs-extra": ["fs-extra@11.3.5", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg=="], + + "@electron/universal/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "2.1.1" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + + "@electron/windows-sign/fs-extra": ["fs-extra@11.3.5", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg=="], + + "@expo/cli/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "@expo/cli/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], + + "@expo/cli/ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "2.4.2", "cli-cursor": "2.1.0", "cli-spinners": "2.9.2", "log-symbols": "2.2.0", "strip-ansi": "5.2.0", "wcwidth": "1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="], + + "@expo/cli/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@expo/cli/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "@expo/config/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@expo/config-plugins/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], + + "@expo/fingerprint/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], + + "@expo/fingerprint/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "5.0.6" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + + "@expo/fingerprint/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@expo/image-utils/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@expo/metro-config/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "@expo/package-manager/ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "2.4.2", "cli-cursor": "2.1.0", "cli-spinners": "2.9.2", "log-symbols": "2.2.0", "strip-ansi": "5.2.0", "wcwidth": "1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="], + + "@expo/prebuild-config/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@expo/ws-tunnel/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "@inquirer/core/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "@inquirer/core/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "4.3.0", "string-width": "4.2.3", "strip-ansi": "6.0.1" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], + + "@libsql/isomorphic-ws/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "@malept/flatpak-bundler/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "1.0.0", "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + + "@modelcontextprotocol/sdk/ajv-formats": ["ajv-formats@3.0.1", "", { "peerDependencies": { "ajv": "^8.0.0" }, "optionalPeers": ["ajv"] }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + + "@modelcontextprotocol/sdk/jose": ["jose@6.2.3", "", {}, "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw=="], + + "@modelcontextprotocol/sdk/json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="], + + "@octokit/request/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], + + "@pierre/diffs/diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="], + + "@react-grab/cli/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + + "@react-grab/cli/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], + + "@react-native/community-cli-plugin/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "@react-navigation/core/react-is": ["react-is@19.2.7", "", {}, "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A=="], + + "@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "@t3tools/mobile/@t3tools/mobile-markdown-text": ["@t3tools/mobile-markdown-text@file:apps/mobile/modules/t3-markdown-text", { "peerDependencies": { "expo-asset": "*", "expo-clipboard": "*", "expo-haptics": "*", "expo-symbols": "*", "react": "*", "react-native": "*", "react-native-nitro-markdown": "*" } }], + + "@t3tools/mobile/@t3tools/mobile-review-diff-native": ["@t3tools/mobile-review-diff-native@file:apps/mobile/modules/t3-review-diff", {}], + + "@t3tools/mobile/@t3tools/mobile-terminal-native": ["@t3tools/mobile-terminal-native@file:apps/mobile/modules/t3-terminal", {}], + + "@t3tools/web/react": ["react@19.2.6", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="], + + "@t3tools/web/react-dom": ["react-dom@19.2.6", "", { "dependencies": { "scheduler": "0.27.0" }, "peerDependencies": { "react": "^19.2.6" } }, "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g=="], + + "@tailwindcss/node/lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], + + "@tailwindcss/node/tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="], + + "@tailwindcss/vite/@tailwindcss/node": ["@tailwindcss/node@4.3.0", "", { "dependencies": { "@jridgewell/remapping": "2.3.5", "enhanced-resolve": "5.22.1", "jiti": "2.7.0", "lightningcss": "1.32.0", "magic-string": "0.30.21", "source-map-js": "1.2.1", "tailwindcss": "4.3.0" } }, "sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g=="], + + "@tailwindcss/vite/@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.0", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.0", "@tailwindcss/oxide-darwin-arm64": "4.3.0", "@tailwindcss/oxide-darwin-x64": "4.3.0", "@tailwindcss/oxide-freebsd-x64": "4.3.0", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.0", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.0", "@tailwindcss/oxide-linux-arm64-musl": "4.3.0", "@tailwindcss/oxide-linux-x64-gnu": "4.3.0", "@tailwindcss/oxide-linux-x64-musl": "4.3.0", "@tailwindcss/oxide-wasm32-wasi": "4.3.0", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.0", "@tailwindcss/oxide-win32-x64-msvc": "4.3.0" } }, "sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg=="], + + "@tanstack/react-router/@tanstack/react-store": ["@tanstack/react-store@0.9.3", "", { "dependencies": { "@tanstack/store": "0.9.3", "use-sync-external-store": "1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg=="], + + "@tanstack/router-generator/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "@tanstack/router-plugin/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + + "@tanstack/router-plugin/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "@testing-library/dom/aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], + + "@testing-library/dom/pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "5.0.1", "ansi-styles": "5.2.0", "react-is": "17.0.2" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], + + "@vercel/routing-utils/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "3.1.3", "fast-json-stable-stringify": "2.1.0", "json-schema-traverse": "0.4.1", "uri-js": "4.4.1" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], + + "@vercel/routing-utils/path-to-regexp": ["path-to-regexp@6.1.0", "", {}, "sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw=="], + + "@vitest/browser/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "@voidzero-dev/vite-plus-core/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "@vscode/emmet-helper/jsonc-parser": ["jsonc-parser@2.3.1", "", {}, "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg=="], + + "accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], + + "agent-install/commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + + "alchemy/@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "1.1.1", "sisteransi": "1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="], + + "alchemy/pg": ["pg@8.21.0", "", { "dependencies": { "pg-connection-string": "2.14.0", "pg-pool": "3.14.0", "pg-protocol": "1.14.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "1.4.0" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA=="], + + "alchemy/react": ["react@19.2.6", "", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="], + + "alchemy/undici": ["undici@7.27.1", "", {}, "sha512-UDdpiex+mzigiyrXrGbiUaF4HzTNhKbh2vRNFaTMzcqmLIPrZxaCtwo/1TMSuWoM1Xz3WiTo9KdgI3kRqYzJGg=="], + + "alchemy/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "app-builder-lib/@electron/get": ["@electron/get@3.1.0", "", { "dependencies": { "debug": "4.4.3", "env-paths": "2.2.1", "fs-extra": "8.1.0", "got": "11.8.6", "progress": "2.0.3", "semver": "6.3.1", "sumchecker": "3.0.1" }, "optionalDependencies": { "global-agent": "3.0.0" } }, "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ=="], + + "app-builder-lib/@electron/osx-sign": ["@electron/osx-sign@1.3.3", "", { "dependencies": { "compare-version": "0.1.2", "debug": "4.4.3", "fs-extra": "10.1.0", "isbinaryfile": "4.0.10", "minimist": "1.2.8", "plist": "3.1.1" }, "bin": { "electron-osx-flat": "bin/electron-osx-flat.js", "electron-osx-sign": "bin/electron-osx-sign.js" } }, "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg=="], + + "app-builder-lib/@noble/hashes": ["@noble/hashes@2.2.0", "", {}, "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg=="], + + "app-builder-lib/ci-info": ["ci-info@4.3.1", "", {}, "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA=="], + + "app-builder-lib/isbinaryfile": ["isbinaryfile@5.0.7", "", {}, "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ=="], + + "app-builder-lib/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "5.0.6" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + + "app-builder-lib/plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "0.8.13", "base64-js": "1.5.1", "xmlbuilder": "15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="], + + "app-builder-lib/which": ["which@5.0.0", "", { "dependencies": { "isexe": "3.1.5" }, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + + "astro/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "astro/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], + + "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "body-parser/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], + + "chrome-launcher/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "2.2.1" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "chromium-edge-launcher/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "2.2.1" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "cli-truncate/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "1.6.0", "strip-ansi": "7.2.0" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "clone-response/mimic-response": ["mimic-response@1.0.1", "", {}, "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="], + + "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "conf/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "connect/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "css-tree/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "1.2.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="], + + "dir-compare/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], + + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "drizzle-kit/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + + "drizzle-kit/get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], + + "electron-publish/mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "electron-updater/builder-util-runtime": ["builder-util-runtime@9.5.1", "", { "dependencies": { "debug": "4.4.3", "sax": "1.6.0" } }, "sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ=="], + + "electron-winstaller/fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "4.0.0", "universalify": "0.1.2" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], + + "expo-build-properties/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], + + "expo-quick-actions/@expo/image-utils": ["@expo/image-utils@0.8.14", "", { "dependencies": { "@expo/require-utils": "55.0.5", "@expo/spawn-async": "1.8.0", "chalk": "4.1.2", "getenv": "2.0.0", "jimp-compact": "0.16.1", "parse-png": "2.1.0", "semver": "7.8.5" } }, "sha512-5Sn+jG4Cw+shC2wDMXoqSAJnvERbiwzHn05FpWtD5IBflfTIs5gUmjzwiGVyjOdlMSQhgRrw/AymPbmO9h9mpQ=="], + + "express/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "3.0.2", "negotiator": "1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], + + "express/finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "4.4.3", "encodeurl": "2.0.0", "escape-html": "1.0.3", "on-finished": "2.4.1", "parseurl": "1.3.3", "statuses": "2.0.2" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], + + "express/fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], + + "express/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "express/send": ["send@1.2.1", "", { "dependencies": { "debug": "4.4.3", "encodeurl": "2.0.0", "escape-html": "1.0.3", "etag": "1.8.1", "fresh": "2.0.0", "http-errors": "2.0.1", "mime-types": "3.0.2", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "1.2.1", "statuses": "2.0.2" } }, "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ=="], + + "express/serve-static": ["serve-static@2.2.1", "", { "dependencies": { "encodeurl": "2.0.0", "escape-html": "1.0.3", "parseurl": "1.3.3", "send": "1.2.1" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], + + "filelist/minimatch": ["minimatch@5.1.9", "", { "dependencies": { "brace-expansion": "2.1.1" } }, "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw=="], + + "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], + + "finalhandler/on-finished": ["on-finished@2.3.0", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww=="], + + "finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="], + + "glob/minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "5.0.6" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], + + "global-agent/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "h3/cookie-es": ["cookie-es@1.2.3", "", {}, "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw=="], + + "hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + + "hosted-git-info/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + + "ink/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "ink/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "ink/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "1.6.0", "strip-ansi": "7.2.0" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "ink/type-fest": ["type-fest@5.7.0", "", { "dependencies": { "tagged-tag": "1.0.0" } }, "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg=="], + + "ink/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "6.2.3", "string-width": "7.2.0", "strip-ansi": "7.2.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + + "ink/ws": ["ws@8.21.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g=="], + + "is-inside-container/is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], + + "jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], + + "jest-util/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + + "libsql/detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="], + + "lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "metro/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "3.0.2", "negotiator": "1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + + "metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="], + + "metro/hermes-parser": ["hermes-parser@0.35.0", "", { "dependencies": { "hermes-estree": "0.35.0" } }, "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA=="], + + "metro/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "metro/serialize-error": ["serialize-error@2.1.0", "", {}, "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw=="], + + "metro-babel-transformer/hermes-parser": ["hermes-parser@0.35.0", "", { "dependencies": { "hermes-estree": "0.35.0" } }, "sha512-9JLjeHxBx8T4CAsydZR49PNZUaix+WpQJwu9p2010lu+7Kwl6D/7wYFFJxoz+aXkaaClp9Zfg6W6/zVlSJORaA=="], + + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + + "mongodb-connection-string-url/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "5.1.1", "webidl-conversions": "7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="], + + "msw/type-fest": ["type-fest@5.7.0", "", { "dependencies": { "tagged-tag": "1.0.0" } }, "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg=="], + + "node-abi/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "node-api-version/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "node-gyp/proc-log": ["proc-log@6.1.0", "", {}, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="], + + "node-gyp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "node-gyp/undici": ["undici@6.26.0", "", {}, "sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A=="], + + "node-gyp/which": ["which@6.0.1", "", { "dependencies": { "isexe": "4.0.0" }, "bin": { "node-which": "bin/which.js" } }, "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg=="], + + "npm-package-arg/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "10.4.3" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], + + "npm-package-arg/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + + "open/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + + "open/is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "2.2.1" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], + + "ora/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + + "ora/cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "5.1.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + + "ora/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "1.6.0", "strip-ansi": "7.2.0" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "2.2.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "parse-png/pngjs": ["pngjs@3.4.0", "", {}, "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w=="], + + "pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "2.0.0", "postgres-bytea": "1.0.1", "postgres-date": "1.0.7", "postgres-interval": "1.2.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + + "pkijs/@noble/hashes": ["@noble/hashes@1.4.0", "", {}, "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="], + + "plist/@xmldom/xmldom": ["@xmldom/xmldom@0.9.10", "", {}, "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw=="], + + "postject/commander": ["commander@9.5.0", "", {}, "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="], + + "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + + "prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], + + "react-native/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "react-native-reanimated/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "react-native-shiki-engine/@shikijs/types": ["@shikijs/types@4.3.0", "", { "dependencies": { "@shikijs/vscode-textmate": "10.0.2", "@types/hast": "3.0.4" } }, "sha512-oc8b9U2SYvofKZk8e/737nIX0qwf6eV2vHFATeObAu7r+mUVpLs8Re0BmVkIjAWAYgkmG/CzLNo7rzuBzRu/wQ=="], + + "react-native-worklets/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "1.0.0", "inflight": "1.0.6", "inherits": "2.0.4", "minimatch": "3.1.5", "once": "1.4.0", "path-is-absolute": "1.0.1" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + + "rolldown/@oxc-project/types": ["@oxc-project/types@0.139.0", "", {}, "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw=="], + + "router/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], + + "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], + + "send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], + + "serialize-error/type-fest": ["type-fest@0.13.1", "", {}, "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg=="], + + "sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "simple-plist/bplist-parser": ["bplist-parser@0.3.1", "", { "dependencies": { "big-integer": "1.6.52" } }, "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA=="], + + "simple-update-notifier/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "1.6.0" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + + "stack-utils/escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], + + "stacktrace-parser/type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], + + "string_decoder/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "svgo/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], + + "svgo/css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], + + "temp/mkdirp": ["mkdirp@0.5.6", "", { "dependencies": { "minimist": "1.2.8" }, "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="], + + "terminal-link/ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], + + "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + + "tiny-async-pool/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], + + "type-is/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], + + "type-is/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + + "typescript-auto-import-cache/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "unifont/css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], + + "unstorage/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], + + "unzipper/fs-extra": ["fs-extra@11.3.1", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "6.2.1", "universalify": "2.0.1" } }, "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g=="], + + "vite/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "volar-service-typescript/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "widest-line/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "1.6.0", "strip-ansi": "7.2.0" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "xcode/uuid": ["uuid@7.0.3", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="], + + "xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], + + "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], + + "yargs/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "zxing-wasm/type-fest": ["type-fest@5.7.0", "", { "dependencies": { "tagged-tag": "1.0.0" } }, "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg=="], + + "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], + + "@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "4.2.11" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "@electron/universal/minimatch/brace-expansion": ["brace-expansion@2.1.1", "", { "dependencies": { "balanced-match": "1.0.2" } }, "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA=="], + + "@expo/cli/ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", "supports-color": "5.5.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "@expo/cli/ora/cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="], + + "@expo/cli/ora/cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "@expo/cli/ora/log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "2.4.2" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="], + + "@expo/cli/ora/strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "4.1.1" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="], + + "@expo/fingerprint/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "4.0.4" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + + "@expo/metro-config/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "@expo/metro-config/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "@expo/metro-config/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "@expo/metro-config/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "@expo/metro-config/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "@expo/metro-config/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "@expo/metro-config/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "@expo/metro-config/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "@expo/metro-config/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "@expo/metro-config/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + + "@expo/package-manager/ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", "supports-color": "5.5.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "@expo/package-manager/ora/cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="], + + "@expo/package-manager/ora/cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], + + "@expo/package-manager/ora/log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "2.4.2" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="], + + "@expo/package-manager/ora/strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "4.1.1" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="], + + "@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="], + + "@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="], + + "@tailwindcss/node/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="], + + "@tailwindcss/node/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="], + + "@tailwindcss/node/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="], + + "@tailwindcss/node/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="], + + "@tailwindcss/node/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="], + + "@tailwindcss/node/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="], + + "@tailwindcss/node/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="], + + "@tailwindcss/node/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="], + + "@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "2.1.2" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.3.0", "", { "os": "android", "cpu": "arm64" }, "sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.3.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.3.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.3.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0", "", { "os": "linux", "cpu": "arm" }, "sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.3.0", "", { "cpu": "none" }, "sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.3.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ=="], + + "@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.3.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA=="], + + "@tanstack/react-router/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.9.3", "", {}, "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw=="], + + "@tanstack/router-plugin/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + + "@testing-library/dom/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + + "@testing-library/dom/pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], + + "@vercel/routing-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "@voidzero-dev/vite-plus-core/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + + "alchemy/@clack/prompts/@clack/core": ["@clack/core@0.5.0", "", { "dependencies": { "picocolors": "1.1.1", "sisteransi": "1.0.5" } }, "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow=="], + + "alchemy/pg/pg-protocol": ["pg-protocol@1.14.0", "", {}, "sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA=="], + + "alchemy/pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "2.0.0", "postgres-bytea": "1.0.1", "postgres-date": "1.0.7", "postgres-interval": "1.2.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], + + "app-builder-lib/@electron/get/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "4.2.11", "jsonfile": "4.0.0", "universalify": "0.1.2" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], + + "app-builder-lib/@electron/get/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + + "app-builder-lib/@electron/osx-sign/isbinaryfile": ["isbinaryfile@4.0.10", "", {}, "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw=="], + + "app-builder-lib/@electron/osx-sign/plist": ["plist@3.1.1", "", { "dependencies": { "@xmldom/xmldom": "0.9.10", "base64-js": "1.5.1", "xmlbuilder": "15.1.1" } }, "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA=="], + + "app-builder-lib/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "4.0.4" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + + "app-builder-lib/which/isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="], + + "chrome-launcher/is-wsl/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + + "chromium-edge-launcher/is-wsl/is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], + + "cli-truncate/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "connect/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], + + "dir-compare/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], + + "drizzle-kit/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + + "drizzle-kit/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + + "drizzle-kit/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + + "drizzle-kit/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + + "drizzle-kit/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + + "drizzle-kit/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + + "drizzle-kit/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + + "drizzle-kit/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + + "drizzle-kit/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + + "drizzle-kit/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + + "drizzle-kit/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + + "drizzle-kit/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + + "drizzle-kit/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + + "drizzle-kit/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + + "drizzle-kit/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + + "drizzle-kit/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + + "drizzle-kit/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + + "drizzle-kit/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + + "drizzle-kit/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + + "drizzle-kit/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + + "drizzle-kit/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + + "drizzle-kit/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + + "drizzle-kit/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + + "drizzle-kit/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + + "drizzle-kit/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + + "drizzle-kit/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + + "electron-winstaller/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "4.2.11" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "electron-winstaller/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "expo-quick-actions/@expo/image-utils/@expo/require-utils": ["@expo/require-utils@55.0.5", "", { "dependencies": { "@babel/code-frame": "7.29.7", "@babel/core": "7.29.7", "@babel/plugin-transform-modules-commonjs": "7.29.7" }, "peerDependencies": { "typescript": "^5.0.0 || ^5.0.0-0" }, "optionalPeers": ["typescript"] }, "sha512-U4K/CQ2VpXuwfNGsN+daKmYOt15hCP8v/pXaYH6eut7kdYZo6SfJ1yr67BIcJ+1Gzzs+QzTxswAZChKpXmceyw=="], + + "expo-quick-actions/@expo/image-utils/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + + "express/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "filelist/minimatch/brace-expansion": ["brace-expansion@2.1.1", "", { "dependencies": { "balanced-match": "1.0.2" } }, "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA=="], + + "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "glob/minimatch/brace-expansion": ["brace-expansion@5.0.6", "", { "dependencies": { "balanced-match": "4.0.4" } }, "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g=="], + + "hosted-git-info/lru-cache/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "ink/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "ink/wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "10.6.0", "get-east-asian-width": "1.6.0", "strip-ansi": "7.2.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], + + "ink/wrap-ansi/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "metro-babel-transformer/hermes-parser/hermes-estree": ["hermes-estree@0.35.0", "", {}, "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg=="], + + "metro/accepts/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "metro/hermes-parser/hermes-estree": ["hermes-estree@0.35.0", "", {}, "sha512-xVx5Opwy8Oo1I5yGpVRhCvWL/iV3M+ylksSKVNlxxD90cpDpR/AR1jLYqK8HWihm065a6UI3HeyAmYzwS8NOOg=="], + + "mongodb-connection-string-url/whatwg-url/tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], + + "mongodb-connection-string-url/whatwg-url/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], + + "node-gyp/which/isexe": ["isexe@4.0.0", "", {}, "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw=="], + + "npm-package-arg/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "ora/cli-cursor/restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "7.0.0", "signal-exit": "4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], + + "ora/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "4.0.2" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + + "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + + "svgo/css-tree/mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + + "terminal-link/ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], + + "unifont/css-tree/mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + + "unstorage/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + + "vite/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "vite/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "vite/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "vite/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "vite/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "vite/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "vite/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "vite/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "vite/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "vite/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + + "widest-line/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "@expo/cli/ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "1.9.3" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "@expo/cli/ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "@expo/cli/ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "@expo/cli/ora/cli-cursor/restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "2.0.1", "signal-exit": "3.0.7" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="], + + "@expo/cli/ora/strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="], + + "@expo/fingerprint/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "@expo/package-manager/ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "1.9.3" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "@expo/package-manager/ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "@expo/package-manager/ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "@expo/package-manager/ora/cli-cursor/restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "2.0.1", "signal-exit": "3.0.7" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="], + + "@expo/package-manager/ora/strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="], + + "@tailwindcss/vite/@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + + "alchemy/pg/pg-types/postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="], + + "alchemy/pg/pg-types/postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="], + + "alchemy/pg/pg-types/postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="], + + "alchemy/pg/pg-types/postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "4.0.2" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], + + "app-builder-lib/@electron/get/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "4.2.11" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], + + "app-builder-lib/@electron/get/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + + "app-builder-lib/@electron/osx-sign/plist/@xmldom/xmldom": ["@xmldom/xmldom@0.9.10", "", {}, "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw=="], + + "app-builder-lib/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], + + "ink/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ink/wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "ink/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ora/cli-cursor/restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "5.0.1" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], + + "ora/cli-cursor/restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "ora/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "widest-line/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "@expo/cli/ora/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "@expo/cli/ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "@expo/cli/ora/cli-cursor/restore-cursor/onetime": ["onetime@2.0.1", "", { "dependencies": { "mimic-fn": "1.2.0" } }, "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ=="], + + "@expo/package-manager/ora/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "@expo/package-manager/ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "@expo/package-manager/ora/cli-cursor/restore-cursor/onetime": ["onetime@2.0.1", "", { "dependencies": { "mimic-fn": "1.2.0" } }, "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ=="], + + "@expo/cli/ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "@expo/cli/ora/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="], + + "@expo/package-manager/ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "@expo/package-manager/ora/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="], + } +} diff --git a/infra/relay/scripts/deploy.test.ts b/infra/relay/scripts/deploy.test.ts index 4447c3493fb5..c6cfded53db1 100644 --- a/infra/relay/scripts/deploy.test.ts +++ b/infra/relay/scripts/deploy.test.ts @@ -180,7 +180,7 @@ describe("serializeRelayClientTracingEnvironment", () => { }); describe("release workflow tracing config propagation", () => { - it.effect("uses an artifact instead of a masked cross-job token output", () => + it.effect("does not propagate relay tracing config via job outputs or artifacts", () => Effect.gen(function* () { const fileSystem = yield* FileSystem.FileSystem; const path = yield* Path.Path; @@ -191,9 +191,11 @@ describe("release workflow tracing config propagation", () => { expect(workflow).not.toContain("client_tracing_token:"); expect(workflow).not.toContain("needs.relay_public_config.outputs.client_tracing_token"); - expect(workflow).toContain('--github-env-file "$RUNNER_TEMP/relay-client-tracing.env"'); - expect(workflow).toContain("name: relay-client-tracing-config"); - expect(workflow).toContain('cat "$config_path" >> "$GITHUB_ENV"'); + expect(workflow).not.toContain('--github-env-file "$RUNNER_TEMP/relay-client-tracing.env"'); + expect(workflow).not.toContain("name: relay-client-tracing-config"); + expect(workflow).not.toContain('cat "$config_path" >> "$GITHUB_ENV"'); + expect(workflow).not.toContain("relay-client-tracing"); + expect(workflow).not.toContain("relay_public_config"); }).pipe(Effect.provide(NodeServices.layer)), ); }); diff --git a/package.json b/package.json index 3fc66d0dd021..330b5d801f48 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,45 @@ { "name": "@t3tools/monorepo", "private": true, + "workspaces": { + "packages": [ + "apps/*", + "infra/*", + "oxlint-plugin-t3code", + "packages/*", + "scripts" + ], + "catalog": { + "@clerk/backend": "3.14.0", + "@clerk/clerk-js": "6.29.2", + "@clerk/electron": "0.0.34", + "@clerk/electron-passkeys": "0.0.3", + "@clerk/expo": "4.2.0", + "@clerk/react": "6.14.4", + "@clerk/shared": "4.29.2", + "@effect/atom-react": "4.0.0-beta.103", + "@effect/openapi-generator": "4.0.0-beta.103", + "@effect/platform-bun": "4.0.0-beta.103", + "@effect/platform-node": "4.0.0-beta.103", + "@effect/platform-node-shared": "4.0.0-beta.103", + "@effect/sql-pg": "4.0.0-beta.103", + "@effect/sql-sqlite-bun": "4.0.0-beta.103", + "@effect/tsgo": "0.13.2", + "@effect/vitest": "4.0.0-beta.103", + "@legendapp/list": "3.3.5", + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@pierre/diffs": "1.3.0-beta.10", + "@types/node": "24.12.4", + "@typescript/native-preview": "7.0.0-dev.20260604.1", + "effect": "4.0.0-beta.103", + "jose": "6.2.2", + "typescript": "~6.0.3", + "vite": "npm:@voidzero-dev/vite-plus-core@0.2.2", + "vite-plus": "0.2.2", + "yaml": "^2.9.0" + } + }, "type": "module", "scripts": { "prepare": "node scripts/clean-tsgo-backups.mjs && effect-tsgo patch && vp config --no-agent", @@ -53,6 +92,46 @@ "@typescript/native-preview": "catalog:", "vite-plus": "catalog:" }, + "overrides": { + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-darwin-arm64": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-darwin-x64": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-linux-arm64": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-linux-arm64-musl": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-linux-x64": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-linux-x64-musl": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-win32-arm64": "-", + "@anthropic-ai/claude-agent-sdk>@anthropic-ai/claude-agent-sdk-win32-x64": "-", + "@clerk/backend": "catalog:", + "@clerk/clerk-js": "catalog:", + "@clerk/clerk-js>@base-org/account": "-", + "@clerk/clerk-js>@coinbase/wallet-sdk": "-", + "@clerk/clerk-js>@solana/wallet-adapter-base": "-", + "@clerk/clerk-js>@solana/wallet-adapter-react": "-", + "@clerk/clerk-js>@solana/wallet-standard": "-", + "@clerk/clerk-js>@wallet-standard/core": "-", + "@clerk/electron": "catalog:", + "@clerk/electron-passkeys": "catalog:", + "@clerk/expo": "catalog:", + "@clerk/react": "catalog:", + "@clerk/shared": "catalog:", + "@effect/atom-react": "catalog:", + "@effect/platform-bun": "catalog:", + "@effect/platform-node": "catalog:", + "@effect/platform-node-shared": "catalog:", + "@effect/sql-pg": "catalog:", + "@effect/sql-sqlite-bun": "catalog:", + "@effect/vitest": "catalog:", + "@effect/vitest>vitest": "-", + "@expo/metro-config": "56.0.14", + "@pierre/diffs>@shikijs/transformers": "^4.2.0", + "@types/node": "catalog:", + "effect": "catalog:", + "expo-modules-jsi": "56.0.10", + "expo-sharing>@expo/config-plugins": "56.0.9", + "expo-sharing>@expo/config-types": "56.0.6", + "vite": "catalog:", + "yaml": "catalog:" + }, "engines": { "node": "^24.13.1" }, @@ -61,5 +140,22 @@ "workerDirectory": [ "apps/web/public" ] + }, + "patchedDependencies": { + "@clerk/expo@4.2.0": "patches/@clerk__expo@4.2.0.patch", + "@effect/vitest@4.0.0-beta.103": "patches/@effect__vitest@4.0.0-beta.103.patch", + "@expo/metro-config@56.0.14": "patches/@expo%2Fmetro-config@56.0.14.patch", + "@ff-labs/fff-node@0.9.4": "patches/@ff-labs__fff-node@0.9.4.patch", + "@legendapp/list@3.3.5": "patches/@legendapp__list@3.3.5.patch", + "@pierre/diffs@1.3.0-beta.10": "patches/@pierre%2Fdiffs@1.3.0-beta.10.patch", + "@react-native-menu/menu@2.0.0": "patches/@react-native-menu__menu@2.0.0.patch", + "@react-native/gradle-plugin@0.85.3": "patches/@react-native__gradle-plugin@0.85.3.patch", + "@react-navigation/native-stack@7.17.6": "patches/@react-navigation%2Fnative-stack@7.17.6.patch", + "effect@4.0.0-beta.103": "patches/effect@4.0.0-beta.103.patch", + "expo-modules-jsi@56.0.10": "patches/expo-modules-jsi@56.0.10.patch", + "react-native-gesture-handler@2.31.2": "patches/react-native-gesture-handler@2.31.2.patch", + "react-native-keyboard-controller@1.21.13": "patches/react-native-keyboard-controller@1.21.13.patch", + "react-native-nitro-modules@0.35.9": "patches/react-native-nitro-modules@0.35.9.patch", + "react-native-screens@4.25.2": "patches/react-native-screens@4.25.2.patch" } } diff --git a/vite.config.ts b/vite.config.ts index 7e45ea33f2ae..2a2d34f6ff7f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -16,6 +16,8 @@ export default defineConfig({ "**/dist/**", "**/dist-electron/**", "**/.{idea,git,cache,output,temp}/**", + "**/.github/**", + "**/*.cjs", ], hookTimeout: 60_000, testTimeout: 60_000, From c02296358ee729daa1bce15ee60ea7f90d2c0ad6 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 17:12:41 +1200 Subject: [PATCH 11/20] chore: fix lint violations and use Set for membership checks - replace array `includes` with `Set.has` for labels, statuses, and activity ids - remove unused imports/vars and fix formatting in Pi adapter/driver - add oxlint disables for intentional spread and array-index-key usage --- .../Layers/ProjectionSnapshotQuery.test.ts | 24 ++++--- apps/server/src/provider/Drivers/PiDriver.ts | 1 - .../src/provider/Layers/ClaudeAdapter.ts | 1 + apps/server/src/provider/Layers/PiAdapter.ts | 69 +++++++++++++------ apps/server/src/provider/Layers/PiProvider.ts | 7 +- .../provider/Layers/ProviderService.test.ts | 1 - .../src/pullRequest/GitHubPullRequestCli.ts | 4 +- .../src/pullRequest/PullRequestService.ts | 4 +- .../src/textGeneration/PiTextGeneration.ts | 26 +++++-- .../makeStandardTextGeneration.ts | 4 +- .../pullRequest/PullRequestChecksPopover.tsx | 1 + .../pullRequest/PullRequestSummaryTab.tsx | 1 + .../pullRequest/pullRequestList.logic.ts | 4 +- .../pullRequest/pullRequestPresentation.tsx | 8 +-- apps/web/src/contextMenuFallback.test.ts | 1 + apps/web/src/terminal/ghostty/core.ts | 2 +- scripts/lib/cli-external-packages.test.ts | 6 +- 17 files changed, 112 insertions(+), 52 deletions(-) diff --git a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts index e0fc1e90139c..d9233b55109d 100644 --- a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts +++ b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts @@ -2396,12 +2396,14 @@ projectionSnapshotLayer("ProjectionSnapshotQuery windowed thread detail", (it) = const detailWithPinnedRequests = yield* snapshotQuery.getThreadDetailById(threadW); assert.equal(detailWithPinnedRequests._tag, "Some"); if (detailWithPinnedRequests._tag === "Some") { - const ids = detailWithPinnedRequests.value.activities.map((activity) => activity.id); + const ids = new Set( + detailWithPinnedRequests.value.activities.map((activity) => activity.id), + ); assert.equal(detailWithPinnedRequests.value.activities.length, 503); - assert.equal(ids.includes(asEventId("approval-old")), true); - assert.equal(ids.includes(asEventId("user-input-old")), true); - assert.equal(ids.includes(asEventId("user-input-closed")), false); - assert.equal(ids.includes(asEventId("user-input-tied-z-request")), true); + assert.equal(ids.has(asEventId("approval-old")), true); + assert.equal(ids.has(asEventId("user-input-old")), true); + assert.equal(ids.has(asEventId("user-input-closed")), false); + assert.equal(ids.has(asEventId("user-input-tied-z-request")), true); } const windowWithPinnedRequests = yield* snapshotQuery.getThreadDetailSnapshot(threadW, { @@ -2409,12 +2411,14 @@ projectionSnapshotLayer("ProjectionSnapshotQuery windowed thread detail", (it) = }); assert.equal(windowWithPinnedRequests._tag, "Some"); if (windowWithPinnedRequests._tag === "Some") { - const ids = windowWithPinnedRequests.value.thread.activities.map((activity) => activity.id); + const ids = new Set( + windowWithPinnedRequests.value.thread.activities.map((activity) => activity.id), + ); assert.equal(windowWithPinnedRequests.value.thread.activities.length, 503); - assert.equal(ids.includes(asEventId("approval-old")), true); - assert.equal(ids.includes(asEventId("user-input-old")), true); - assert.equal(ids.includes(asEventId("user-input-closed")), false); - assert.equal(ids.includes(asEventId("user-input-tied-z-request")), true); + assert.equal(ids.has(asEventId("approval-old")), true); + assert.equal(ids.has(asEventId("user-input-old")), true); + assert.equal(ids.has(asEventId("user-input-closed")), false); + assert.equal(ids.has(asEventId("user-input-tied-z-request")), true); } }), ); diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/apps/server/src/provider/Drivers/PiDriver.ts index 1c3417813197..89aa2fd2e72d 100644 --- a/apps/server/src/provider/Drivers/PiDriver.ts +++ b/apps/server/src/provider/Drivers/PiDriver.ts @@ -75,7 +75,6 @@ export const PiDriver: ProviderDriver = { const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const httpClient = yield* HttpClient.HttpClient; const serverSettings = yield* ServerSettingsService; - const eventLoggers = yield* ProviderEventLoggers; const processEnv = mergeProviderInstanceEnvironment(environment); const continuationIdentity = defaultProviderContinuationIdentity({ driverKind: DRIVER_KIND, diff --git a/apps/server/src/provider/Layers/ClaudeAdapter.ts b/apps/server/src/provider/Layers/ClaudeAdapter.ts index 173b7a2b0355..ef7139107524 100644 --- a/apps/server/src/provider/Layers/ClaudeAdapter.ts +++ b/apps/server/src/provider/Layers/ClaudeAdapter.ts @@ -3751,6 +3751,7 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* ( // Same reason as the approvals above: a request nobody can answer any more // must not stay open, or the thread can never be settled. + // oxlint-disable-next-line unicorn/no-useless-spread -- snapshot pending cancels before mutation for (const pending of [...context.pendingUserInputs.values()]) { yield* pending.cancel; } diff --git a/apps/server/src/provider/Layers/PiAdapter.ts b/apps/server/src/provider/Layers/PiAdapter.ts index 3a6262f0062a..74c4c2357089 100644 --- a/apps/server/src/provider/Layers/PiAdapter.ts +++ b/apps/server/src/provider/Layers/PiAdapter.ts @@ -7,9 +7,6 @@ import { ProviderInstanceId, type ThreadId, TurnId, - type ApprovalRequestId, - type ProviderApprovalDecision, - type ProviderUserInputAnswers, RuntimeRequestId, type CanonicalItemType, } from "@t3tools/contracts"; @@ -24,7 +21,7 @@ import * as Stream from "effect/Stream"; import * as SynchronizedRef from "effect/SynchronizedRef"; import * as Semaphore from "effect/Semaphore"; import { tokenizeCliArgs } from "@t3tools/shared/cliArgs"; -import type { ChildProcess as NodeChildProcess } from "node:child_process"; +import type * as NodeChildProcess from "node:child_process"; import { resolveAttachmentPath } from "../../attachmentStore.ts"; import { ServerConfig } from "../../config.ts"; @@ -49,11 +46,14 @@ interface PiSessionContext { readonly threadId: ThreadId; session: ProviderSession; readonly scope: Scope.CloseableScope; - child: NodeChildProcess | undefined; + child: NodeChildProcess.ChildProcess | undefined; activeTurnId: TurnId | undefined; pendingCommands: Map< string, - Deferred.Deferred<{ success: boolean; data?: unknown; error?: string }, ProviderAdapterRequestError> + Deferred.Deferred< + { success: boolean; data?: unknown; error?: string }, + ProviderAdapterRequestError + > >; stopped: boolean; } @@ -64,8 +64,16 @@ function isRecord(value: unknown): value is Record { function toCanonicalItemType(toolName: string): CanonicalItemType { const name = toolName.toLowerCase(); - if (name === "bash" || name === "command_execution" || name.includes("command")) return "command_execution"; - if (name === "read" || name === "edit" || name === "write" || name === "file_change" || name.includes("file")) return "file_change"; + if (name === "bash" || name === "command_execution" || name.includes("command")) + return "command_execution"; + if ( + name === "read" || + name === "edit" || + name === "write" || + name === "file_change" || + name.includes("file") + ) + return "file_change"; if (name === "mcp_tool_call" || name.startsWith("mcp_")) return "mcp_tool_call"; if (name === "web_search") return "web_search"; return "dynamic_tool_call"; @@ -133,7 +141,9 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt ): Effect.Effect => { const ctx = sessions.get(threadId); if (!ctx || ctx.stopped) { - return Effect.fail(new ProviderAdapterSessionNotFoundError({ provider: PROVIDER, threadId })); + return Effect.fail( + new ProviderAdapterSessionNotFoundError({ provider: PROVIDER, threadId }), + ); } return Effect.succeed(ctx); }; @@ -142,7 +152,11 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt Effect.gen(function* () { const updatedAt = yield* nowIso; const { activeTurnId: _a, ...ready } = ctx.session as unknown as Record; - ctx.session = { ...(ready as unknown as ProviderSession), status: "ready", updatedAt } as ProviderSession; + ctx.session = { + ...(ready as unknown as ProviderSession), + status: "ready", + updatedAt, + } as ProviderSession; ctx.activeTurnId = undefined; }); @@ -180,7 +194,10 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt const writeRpcCommand = ( ctx: PiSessionContext, command: PiRpcCommand, - ): Effect.Effect<{ success: boolean; data?: unknown; error?: string }, ProviderAdapterRequestError> => + ): Effect.Effect< + { success: boolean; data?: unknown; error?: string }, + ProviderAdapterRequestError + > => Effect.gen(function* () { if (!ctx.child || !ctx.child.stdin || ctx.stopped) { return yield* new ProviderAdapterRequestError({ @@ -282,7 +299,8 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt raw: { source: PI_RAW_SOURCE, payload: raw }, }); } else if (deltaType === "toolcall_start") { - const toolName = typeof delta.toolName === "string" ? (delta.toolName as string) : "tool"; + const toolName = + typeof delta.toolName === "string" ? (delta.toolName as string) : "tool"; yield* offerRuntimeEvent({ type: "item.started", ...stamp, @@ -375,7 +393,9 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt default: break; } - }).pipe(Effect.catchCause((cause) => Effect.logWarning("Failed to handle Pi event", { cause }))); + }).pipe( + Effect.catchCause((cause) => Effect.logWarning("Failed to handle Pi event", { cause })), + ); const startSession: ProviderAdapterShape["startSession"] = (input) => withThreadLock( @@ -403,14 +423,16 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt const scope = yield* Scope.make(); let scopeTransferred = false; - yield* Effect.addFinalizer(() => (scopeTransferred ? Effect.void : Scope.close(scope, Effect.void as never))); + yield* Effect.addFinalizer(() => + scopeTransferred ? Effect.void : Scope.close(scope, Effect.void as never), + ); const launchArgs = piLaunchArgs(piSettings.launchArgs); const binaryPath = piSettings.binaryPath || "pi"; const args = ["--mode", "rpc", ...launchArgs]; - const env = { ...process.env, ...(options?.environment ?? {}) } as NodeJS.ProcessEnv; + const env = { ...process.env, ...options?.environment } as NodeJS.ProcessEnv; - const nodeChild: NodeChildProcess = yield* Effect.tryPromise({ + const nodeChild: NodeChildProcess.ChildProcess = yield* Effect.tryPromise({ try: async () => { const { spawn } = await import("node:child_process"); return spawn(binaryPath, args, { @@ -468,7 +490,8 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt const stdoutEffect = Effect.promise(async () => { let buffer = ""; for await (const chunk of stdout as unknown as AsyncIterable) { - const text = typeof chunk === "string" ? chunk : (chunk as Buffer).toString("utf-8"); + const text = + typeof chunk === "string" ? chunk : (chunk as Buffer).toString("utf-8"); buffer += text; let nl: number; while ((nl = buffer.indexOf("\n")) !== -1) { @@ -480,13 +503,17 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt try { parsed = JSON.parse(line); } catch { - await Effect.runPromise(Effect.logWarning("Pi RPC parse error", { line: line.slice(0, 500) })); + await Effect.runPromise( + Effect.logWarning("Pi RPC parse error", { line: line.slice(0, 500) }), + ); continue; } await Effect.runPromise(handlePiEvent(ctx, parsed)); } } - }).pipe(Effect.catchCause((cause) => Effect.logWarning("Pi stdout loop failed", { cause }))); + }).pipe( + Effect.catchCause((cause) => Effect.logWarning("Pi stdout loop failed", { cause })), + ); yield* stdoutEffect.pipe(Effect.forkIn(scope)); } @@ -797,7 +824,9 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }), ), ); - const messages = ((res.data ?? {}) as Record).messages as unknown[] | undefined; + const messages = ((res.data ?? {}) as Record).messages as + | unknown[] + | undefined; return { threadId, turns: [ diff --git a/apps/server/src/provider/Layers/PiProvider.ts b/apps/server/src/provider/Layers/PiProvider.ts index 8748cd2ab2cc..9a1ccbbf37e3 100644 --- a/apps/server/src/provider/Layers/PiProvider.ts +++ b/apps/server/src/provider/Layers/PiProvider.ts @@ -1,4 +1,9 @@ -import type { ModelCapabilities, PiSettings, ServerProvider, ServerProviderModel } from "@t3tools/contracts"; +import type { + ModelCapabilities, + PiSettings, + ServerProvider, + ServerProviderModel, +} from "@t3tools/contracts"; import { causeErrorTag } from "@t3tools/shared/observability"; import * as DateTime from "effect/DateTime"; import * as Effect from "effect/Effect"; diff --git a/apps/server/src/provider/Layers/ProviderService.test.ts b/apps/server/src/provider/Layers/ProviderService.test.ts index bd89dc4f8812..7c01ff23ab6a 100644 --- a/apps/server/src/provider/Layers/ProviderService.test.ts +++ b/apps/server/src/provider/Layers/ProviderService.test.ts @@ -14,7 +14,6 @@ import type { } from "@t3tools/contracts"; import { ApprovalRequestId, - EnvironmentId, EventId, ProviderDriverKind, ProviderInstanceId, diff --git a/apps/server/src/pullRequest/GitHubPullRequestCli.ts b/apps/server/src/pullRequest/GitHubPullRequestCli.ts index 2084a50d0206..5f8ee8c4e37a 100644 --- a/apps/server/src/pullRequest/GitHubPullRequestCli.ts +++ b/apps/server/src/pullRequest/GitHubPullRequestCli.ts @@ -662,8 +662,8 @@ function matchesFilters( viewer: string, ): boolean { if (filters === undefined) return true; - const labels = item.labels.map((label) => label.name.trim().toLowerCase()); - const holds = (label: string) => labels.includes(label.trim().toLowerCase()); + const labels = new Set(item.labels.map((label) => label.name.trim().toLowerCase())); + const holds = (label: string) => labels.has(label.trim().toLowerCase()); return ( (filters.draft === undefined || item.isDraft === (filters.draft === "only")) && (filters.review === undefined || diff --git a/apps/server/src/pullRequest/PullRequestService.ts b/apps/server/src/pullRequest/PullRequestService.ts index 3a0d1aac699d..7cf82cf10d2a 100644 --- a/apps/server/src/pullRequest/PullRequestService.ts +++ b/apps/server/src/pullRequest/PullRequestService.ts @@ -749,8 +749,8 @@ export const make = Effect.gen(function* () { viewer: string, ): boolean => { if (filters === undefined) return true; - const labels = item.labels.map((label) => label.name.trim().toLowerCase()); - const holds = (label: string) => labels.includes(label.trim().toLowerCase()); + const labels = new Set(item.labels.map((label) => label.name.trim().toLowerCase())); + const holds = (label: string) => labels.has(label.trim().toLowerCase()); return ( (filters.draft === undefined || item.isDraft === (filters.draft === "only")) && // Judged on the provider row rather than the entry, because the two absences mean diff --git a/apps/server/src/textGeneration/PiTextGeneration.ts b/apps/server/src/textGeneration/PiTextGeneration.ts index d4aecd996aa9..b96e6e73e203 100644 --- a/apps/server/src/textGeneration/PiTextGeneration.ts +++ b/apps/server/src/textGeneration/PiTextGeneration.ts @@ -27,7 +27,11 @@ export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* outputSchemaJson, modelSelection: _modelSelection, }: { - operation: "generateCommitMessage" | "generatePrContent" | "generateBranchName" | "generateThreadTitle"; + operation: + | "generateCommitMessage" + | "generatePrContent" + | "generateBranchName" + | "generateThreadTitle"; cwd: string; prompt: string; outputSchemaJson: S; @@ -36,11 +40,23 @@ export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* const binaryPath = piSettings.binaryPath || "pi"; const launchArgs = tokenizeCliArgs(piSettings.launchArgs?.trim() ?? ""); const filteredLaunchArgs = launchArgs.filter( - (arg) => arg !== "--tools" && arg !== "--extension" && !arg.startsWith("--tools=") && !arg.startsWith("--extension="), + (arg) => + arg !== "--tools" && + arg !== "--extension" && + !arg.startsWith("--tools=") && + !arg.startsWith("--extension="), ); const spawnCommand = yield* resolveSpawnCommand( binaryPath, - ["-p", "--no-session", "--no-context-files", "--no-tools", "--no-extensions", ...filteredLaunchArgs, prompt], + [ + "-p", + "--no-session", + "--no-context-files", + "--no-tools", + "--no-extensions", + ...filteredLaunchArgs, + prompt, + ], { env: environment }, ).pipe( Effect.mapError( @@ -98,7 +114,9 @@ export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* // Single salvage via shared helper — `extractJsonObject` already handles ```json fences. const jsonText = extractJsonObject(stdout) ?? stdout; - return yield* Schema.decodeEffect(Schema.fromJsonString(outputSchemaJson as any))(jsonText).pipe( + return yield* Schema.decodeEffect(Schema.fromJsonString(outputSchemaJson as any))( + jsonText, + ).pipe( Effect.mapError( (cause) => new TextGenerationError({ diff --git a/apps/server/src/textGeneration/makeStandardTextGeneration.ts b/apps/server/src/textGeneration/makeStandardTextGeneration.ts index 0902293190e9..55bb71f94e10 100644 --- a/apps/server/src/textGeneration/makeStandardTextGeneration.ts +++ b/apps/server/src/textGeneration/makeStandardTextGeneration.ts @@ -33,7 +33,9 @@ export type RunJson = (args: { * Every provider was copy-pasting the same `build*Prompt` → `runJson` → `sanitize` dance. * One helper replaces 5×40 lines. */ -export function makeStandardTextGeneration(runJson: RunJson): TextGeneration.TextGeneration["Service"] { +export function makeStandardTextGeneration( + runJson: RunJson, +): TextGeneration.TextGeneration["Service"] { const generateCommitMessage: TextGeneration.TextGeneration["Service"]["generateCommitMessage"] = Effect.fn("TextGeneration.generateCommitMessage")(function* (input) { const { prompt, outputSchema } = buildCommitMessagePrompt({ diff --git a/apps/web/src/components/pullRequest/PullRequestChecksPopover.tsx b/apps/web/src/components/pullRequest/PullRequestChecksPopover.tsx index 8070af60c040..3b5af021f303 100644 --- a/apps/web/src/components/pullRequest/PullRequestChecksPopover.tsx +++ b/apps/web/src/components/pullRequest/PullRequestChecksPopover.tsx @@ -56,6 +56,7 @@ function ChecksBody({ checks }: { checks: ReadonlyArray }) { {/* Keyed by position as well as by name: the host is the one that decides how many runs share a name, and a repeated key is a rendering fault rather than a wrong list. */} {checks.map((check, index) => ( + // oxlint-disable-next-line react/no-array-index-key -- index disambiguates duplicate check names from host
  • diff --git a/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx b/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx index ef3ae062f65a..d7a2b3da5366 100644 --- a/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx +++ b/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx @@ -708,6 +708,7 @@ export function PullRequestSummaryTab({
    diff --git a/apps/web/src/components/pullRequest/pullRequestList.logic.ts b/apps/web/src/components/pullRequest/pullRequestList.logic.ts index d372cabebe22..58cace4035b6 100644 --- a/apps/web/src/components/pullRequest/pullRequestList.logic.ts +++ b/apps/web/src/components/pullRequest/pullRequestList.logic.ts @@ -311,8 +311,8 @@ export function matchesPullRequestFilters( filters: PullRequestListFilters, viewer?: string | null, ): boolean { - const labels = entry.labels.map((label) => label.name.trim().toLowerCase()); - const holds = (label: string) => labels.includes(label.trim().toLowerCase()); + const labels = new Set(entry.labels.map((label) => label.name.trim().toLowerCase())); + const holds = (label: string) => labels.has(label.trim().toLowerCase()); return ( (filters.draft === undefined || entry.isDraft === (filters.draft === "only")) && (filters.review === undefined || diff --git a/apps/web/src/components/pullRequest/pullRequestPresentation.tsx b/apps/web/src/components/pullRequest/pullRequestPresentation.tsx index 44184ecdae7e..b9a968a6e28d 100644 --- a/apps/web/src/components/pullRequest/pullRequestPresentation.tsx +++ b/apps/web/src/components/pullRequest/pullRequestPresentation.tsx @@ -187,10 +187,10 @@ export function pullRequestChecksState( checks: ReadonlyArray, ): PullRequestChecksState | null { if (checks.length === 0) return null; - const statuses = checks.map((check) => check.status); - if (statuses.includes("failure") || statuses.includes("cancelled")) return "failing"; - if (statuses.includes("pending")) return "pending"; - return statuses.includes("success") ? "passing" : null; + const statuses = new Set(checks.map((check) => check.status)); + if (statuses.has("failure") || statuses.has("cancelled")) return "failing"; + if (statuses.has("pending")) return "pending"; + return statuses.has("success") ? "passing" : null; } /** diff --git a/apps/web/src/contextMenuFallback.test.ts b/apps/web/src/contextMenuFallback.test.ts index ddc5da05f806..f8cbef60e61e 100644 --- a/apps/web/src/contextMenuFallback.test.ts +++ b/apps/web/src/contextMenuFallback.test.ts @@ -35,6 +35,7 @@ class FakeElement { constructor(readonly tagName: string) {} get isConnected() { + // oxlint-disable-next-line typescript/no-this-alias -- test fake DOM needs to walk parent chain from this let current: FakeElement | null = this; while (current?.parent) { current = current.parent; diff --git a/apps/web/src/terminal/ghostty/core.ts b/apps/web/src/terminal/ghostty/core.ts index 6f6cbbe0a888..1fdf5f768e1e 100644 --- a/apps/web/src/terminal/ghostty/core.ts +++ b/apps/web/src/terminal/ghostty/core.ts @@ -178,7 +178,7 @@ export function ghosttyCellText(codepointView: DataView, graphemeLength: number) let text = ""; for (let start = 0; start < graphemeLength; start += CHUNK_SIZE) { const count = Math.min(CHUNK_SIZE, graphemeLength - start); - const codes = new Array(count); + const codes = Array.from({ length: count }); for (let index = 0; index < count; index += 1) { codes[index] = codepointView.getUint32((start + index) * 4, true); } diff --git a/scripts/lib/cli-external-packages.test.ts b/scripts/lib/cli-external-packages.test.ts index 754cd646f17d..de5b9b8e5cbe 100644 --- a/scripts/lib/cli-external-packages.test.ts +++ b/scripts/lib/cli-external-packages.test.ts @@ -189,9 +189,9 @@ it.layer(NodeServices.layer)("external package dependency closure", (it) => { if (!manifest) continue; const declared = { - ...(manifest.dependencies ?? {}), - ...(manifest.optionalDependencies ?? {}), - ...(manifest.peerDependencies ?? {}), + ...manifest.dependencies, + ...manifest.optionalDependencies, + ...manifest.peerDependencies, }; for (const dependency of Object.keys(declared)) { if (!isRuntimeExternal(dependency)) { From 05e951d487e6b35cab668e36f8cf00e7abaeca02 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 17:39:33 +1200 Subject: [PATCH 12/20] refactor(pi): align adapter with updated provider contracts - Update PiAdapter payloads to canonical shapes (streamKind/itemType/toolName/summary/requestType) - Migrate Effect.async to Effect.callback and tighten ProviderAdapterError typing - Fix Pi text generation timeout handling via timeoutOption and improve error mapping --- apps/server/src/provider/Layers/PiAdapter.ts | 209 ++++++++++-------- apps/server/src/provider/Layers/PiProvider.ts | 1 - .../src/textGeneration/PiTextGeneration.ts | 33 ++- 3 files changed, 144 insertions(+), 99 deletions(-) diff --git a/apps/server/src/provider/Layers/PiAdapter.ts b/apps/server/src/provider/Layers/PiAdapter.ts index 74c4c2357089..58c3070b84f2 100644 --- a/apps/server/src/provider/Layers/PiAdapter.ts +++ b/apps/server/src/provider/Layers/PiAdapter.ts @@ -5,6 +5,7 @@ import { type ProviderSession, ProviderDriverKind, ProviderInstanceId, + type ProviderTurnStartResult, type ThreadId, TurnId, RuntimeRequestId, @@ -18,9 +19,11 @@ import * as FileSystem from "effect/FileSystem"; import * as PubSub from "effect/PubSub"; import * as Scope from "effect/Scope"; import * as Stream from "effect/Stream"; +import * as Result from "effect/Result"; import * as SynchronizedRef from "effect/SynchronizedRef"; import * as Semaphore from "effect/Semaphore"; import { tokenizeCliArgs } from "@t3tools/shared/cliArgs"; +// @effect-diagnostics-next-line nodeBuiltinImport:off -- Pi RPC requires raw stdio streaming unavailable via Effect ChildProcess import type * as NodeChildProcess from "node:child_process"; import { resolveAttachmentPath } from "../../attachmentStore.ts"; @@ -30,6 +33,7 @@ import { ProviderAdapterRequestError, ProviderAdapterSessionNotFoundError, ProviderAdapterValidationError, + type ProviderAdapterError, } from "../Errors.ts"; import type { ProviderAdapterShape } from "../Services/ProviderAdapter.ts"; @@ -45,7 +49,7 @@ interface PiRpcCommand { interface PiSessionContext { readonly threadId: ThreadId; session: ProviderSession; - readonly scope: Scope.CloseableScope; + readonly scope: Scope.Closeable; child: NodeChildProcess.ChildProcess | undefined; activeTurnId: TurnId | undefined; pendingCommands: Map< @@ -165,6 +169,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt if (ctx.stopped) return; ctx.stopped = true; if (ctx.child) { + // @effect-diagnostics-next-line tryCatchInEffectGen:off -- child.kill is sync and rarely throws try { ctx.child.kill(); } catch {} @@ -213,26 +218,29 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt ProviderAdapterRequestError >(); ctx.pendingCommands.set(id, deferred); + // @effect-diagnostics-next-line preferSchemaOverJson:off -- ad-hoc RPC line protocol const line = JSON.stringify(payload) + "\n"; const stdin = ctx.child.stdin as NodeJS.WritableStream; - yield* Effect.async((resume) => { - stdin.write(line, (err: unknown) => { - if (err) { - resume( - Effect.fail( - new ProviderAdapterRequestError({ - provider: PROVIDER, - method: command.type, - detail: "Failed to write to Pi RPC stdin.", - cause: err, - }), - ), - ); - } else { - resume(Effect.void); - } - }); - }); + yield* Effect.callback( + (resume: (effect: Effect.Effect) => void) => { + stdin.write(line, (err: unknown) => { + if (err) { + resume( + Effect.fail( + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: command.type, + detail: "Failed to write to Pi RPC stdin.", + cause: err, + }), + ), + ); + } else { + resume(Effect.void); + } + }); + }, + ); const result = yield* Deferred.await(deferred).pipe(Effect.timeoutOption(30_000)); if (result._tag === "None") { ctx.pendingCommands.delete(id); @@ -256,13 +264,15 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt const deferred = ctx.pendingCommands.get(id)!; ctx.pendingCommands.delete(id); const success = raw.success === true; + const dataValue = (raw as Record).data; + const errorValue = + typeof (raw as Record).error === "string" + ? ((raw as Record).error as string) + : undefined; yield* Deferred.succeed(deferred, { success, - data: (raw as Record).data, - error: - typeof (raw as Record).error === "string" - ? ((raw as Record).error as string) - : undefined, + ...(dataValue !== undefined ? { data: dataValue } : {}), + ...(errorValue !== undefined ? { error: errorValue } : {}), }).pipe(Effect.ignore); } return; @@ -285,7 +295,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt provider: PROVIDER, threadId: ctx.threadId, turnId, - payload: { kind: "assistant_text", delta: delta.delta as string }, + payload: { streamKind: "assistant_text", delta: delta.delta as string }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); } else if (deltaType === "thinking_delta" && typeof delta.delta === "string") { @@ -295,7 +305,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt provider: PROVIDER, threadId: ctx.threadId, turnId, - payload: { kind: "reasoning_text", delta: delta.delta as string }, + payload: { streamKind: "reasoning_text", delta: delta.delta as string }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); } else if (deltaType === "toolcall_start") { @@ -307,7 +317,10 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt provider: PROVIDER, threadId: ctx.threadId, turnId, - payload: { kind: toCanonicalItemType(toolName), status: "inProgress" }, + payload: { + itemType: toCanonicalItemType(toolName), + status: "inProgress" as const, + }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); } @@ -322,7 +335,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt provider: PROVIDER, threadId: ctx.threadId, turnId, - payload: { kind: "assistant_message", status: "completed" }, + payload: { itemType: "assistant_message" as const, status: "completed" as const }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); } @@ -337,9 +350,8 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt threadId: ctx.threadId, turnId, payload: { - tool: ((raw as Record).toolName as string) ?? "bash", - status: "running", - message: `Running ${((raw as Record).toolName as string) ?? "tool"}`, + toolName: ((raw as Record).toolName as string) ?? "bash", + summary: `Running ${((raw as Record).toolName as string) ?? "tool"}`, }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); @@ -355,8 +367,8 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt threadId: ctx.threadId, turnId, payload: { - tool: ((raw as Record).toolName as string) ?? "bash", - status: (raw as Record).isError ? "failed" : "completed", + toolName: ((raw as Record).toolName as string) ?? "bash", + summary: (raw as Record).isError ? "failed" : "completed", }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); @@ -376,7 +388,10 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt : "Pi request"; const optionsRaw = (raw as Record).options as unknown; const options = Array.isArray(optionsRaw) - ? (optionsRaw as Array).map((o) => ({ id: String(o), label: String(o) })) + ? (optionsRaw as Array).map((o) => ({ + decision: "accept" as const, + label: String(o), + })) : []; yield* offerRuntimeEvent({ type: "request.opened", @@ -385,7 +400,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt threadId: ctx.threadId, ...(turnId ? { turnId } : {}), requestId: asRuntimeRequestId(requestId), - payload: { kind: "tool_user_input" as never, prompt: title, options }, + payload: { requestType: "tool_user_input" as const, detail: title, options }, raw: { source: PI_RAW_SOURCE, payload: raw }, }); break; @@ -397,7 +412,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt Effect.catchCause((cause) => Effect.logWarning("Failed to handle Pi event", { cause })), ); - const startSession: ProviderAdapterShape["startSession"] = (input) => + const startSession: ProviderAdapterShape["startSession"] = (input) => withThreadLock( input.threadId, Effect.gen(function* () { @@ -501,6 +516,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt if (!line.trim()) continue; let parsed: unknown; try { + // @effect-diagnostics-next-line preferSchemaOverJson:off -- ad-hoc RPC line protocol parsed = JSON.parse(line); } catch { await Effect.runPromise( @@ -517,41 +533,43 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt yield* stdoutEffect.pipe(Effect.forkIn(scope)); } - yield* Effect.async((resume) => { - const onExit = (code: number | null, signal: string | null) => { - ctx.stopped = true; - sessions.delete(ctx.threadId); - for (const deferred of ctx.pendingCommands.values()) { - Effect.runSync( - Deferred.fail( - deferred, - new ProviderAdapterRequestError({ + yield* Effect.callback( + (resume: (effect: Effect.Effect) => void) => { + const onExit = (code: number | null, signal: string | null) => { + ctx.stopped = true; + sessions.delete(ctx.threadId); + for (const deferred of ctx.pendingCommands.values()) { + Effect.runSync( + Deferred.fail( + deferred, + new ProviderAdapterRequestError({ + provider: PROVIDER, + method: "session", + detail: `Pi process exited with code ${code} signal ${signal}`, + }), + ).pipe(Effect.ignore), + ); + } + ctx.pendingCommands.clear(); + Effect.runPromise( + Effect.gen(function* () { + yield* offerRuntimeEvent({ + type: "session.exited", + ...(yield* makeEventStamp()), provider: PROVIDER, - method: "session", - detail: `Pi process exited with code ${code} signal ${signal}`, - }), - ).pipe(Effect.ignore), - ); - } - ctx.pendingCommands.clear(); - Effect.runPromise( - Effect.gen(function* () { - yield* offerRuntimeEvent({ - type: "session.exited", - ...(yield* makeEventStamp()), - provider: PROVIDER, - threadId: ctx.threadId, - payload: { - exitKind: code === 0 ? "graceful" : "error", - reason: `exit code ${code} signal ${signal}`, - }, - }); - }), - ).finally(() => resume(Effect.void)); - }; - nodeChild.on("exit", onExit); - nodeChild.on("error", () => resume(Effect.void)); - }).pipe(Effect.forkIn(scope)); + threadId: ctx.threadId, + payload: { + exitKind: code === 0 ? "graceful" : "error", + reason: `exit code ${code} signal ${signal}`, + }, + }); + }), + ).finally(() => resume(Effect.void)); + }; + nodeChild.on("exit", onExit); + nodeChild.on("error", () => resume(Effect.void)); + }, + ).pipe(Effect.forkIn(scope)); sessions.set(input.threadId, ctx); scopeTransferred = true; @@ -582,7 +600,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }).pipe(Effect.scoped), ); - const sendTurn: ProviderAdapterShape["sendTurn"] = (input) => + const sendTurn: ProviderAdapterShape["sendTurn"] = (input) => withThreadLock( input.threadId, Effect.gen(function* () { @@ -652,7 +670,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }; const rpcResult = yield* writeRpcCommand(ctx, promptPayload).pipe( - Effect.catchAll((cause) => + Effect.catch((cause: ProviderAdapterRequestError) => Effect.gen(function* () { yield* offerRuntimeEvent({ type: "turn.completed", @@ -719,12 +737,17 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt return { threadId: input.threadId, turnId, - resumeCursor: ctx.session.resumeCursor, + ...(ctx.session.resumeCursor !== undefined && ctx.session.resumeCursor !== null + ? { resumeCursor: ctx.session.resumeCursor } + : {}), }; }), - ); + ) as unknown as Effect.Effect; - const interruptTurn: ProviderAdapterShape["interruptTurn"] = (threadId, turnId) => + const interruptTurn: ProviderAdapterShape["interruptTurn"] = ( + threadId, + turnId, + ) => Effect.gen(function* () { const ctx = sessions.get(threadId); if (!ctx || ctx.stopped) return; @@ -745,7 +768,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt yield* markSessionReady(ctx); }); - const respondToRequest: ProviderAdapterShape["respondToRequest"] = ( + const respondToRequest: ProviderAdapterShape["respondToRequest"] = ( threadId, requestId, decision, @@ -771,7 +794,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }); }); - const respondToUserInput: ProviderAdapterShape["respondToUserInput"] = ( + const respondToUserInput: ProviderAdapterShape["respondToUserInput"] = ( threadId, requestId, answers, @@ -794,7 +817,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }); }); - const stopSession: ProviderAdapterShape["stopSession"] = (threadId) => + const stopSession: ProviderAdapterShape["stopSession"] = (threadId) => withThreadLock( threadId, Effect.gen(function* () { @@ -804,13 +827,13 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }), ); - const listSessions: ProviderAdapterShape["listSessions"] = () => + const listSessions: ProviderAdapterShape["listSessions"] = () => Effect.sync(() => Array.from(sessions.values()).map((c) => c.session)); - const hasSession: ProviderAdapterShape["hasSession"] = (threadId) => + const hasSession: ProviderAdapterShape["hasSession"] = (threadId) => Effect.sync(() => sessions.has(threadId) && !sessions.get(threadId)?.stopped); - const readThread: ProviderAdapterShape["readThread"] = (threadId) => + const readThread: ProviderAdapterShape["readThread"] = (threadId) => Effect.gen(function* () { const ctx = yield* requireSession(threadId); const res = yield* writeRpcCommand(ctx, { type: "get_messages" }).pipe( @@ -836,16 +859,26 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }, ], }; - }); - - const rollbackThread: ProviderAdapterShape["rollbackThread"] = (threadId, numTurns) => + }) as Effect.Effect< + { + readonly threadId: ThreadId; + readonly turns: ReadonlyArray<{ id: TurnId; items: unknown[] }>; + }, + ProviderAdapterError, + never + >; + + const rollbackThread: ProviderAdapterShape["rollbackThread"] = ( + threadId, + numTurns, + ) => Effect.gen(function* () { const ctx = yield* requireSession(threadId); const result = yield* writeRpcCommand(ctx, { type: "rollback", numTurns, - }).pipe(Effect.either); - if (result._tag === "Right" && result.right.success) { + }).pipe(Effect.result); + if (Result.isSuccess(result) && result.success.success) { return yield* readThread(threadId); } return yield* new ProviderAdapterRequestError({ @@ -855,7 +888,7 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt }); }); - const stopAll: ProviderAdapterShape["stopAll"] = () => + const stopAll: ProviderAdapterShape["stopAll"] = () => Effect.forEach(Array.from(sessions.values()), (ctx) => stopSessionInternal(ctx), { discard: true, }); @@ -875,6 +908,6 @@ export function makePiAdapter(piSettings: PiSettings, options?: PiAdapterLiveOpt rollbackThread, stopAll, streamEvents: Stream.fromPubSub(runtimeEventPubSub), - } satisfies ProviderAdapterShape; + } satisfies ProviderAdapterShape; }); } diff --git a/apps/server/src/provider/Layers/PiProvider.ts b/apps/server/src/provider/Layers/PiProvider.ts index 9a1ccbbf37e3..0074b013dd75 100644 --- a/apps/server/src/provider/Layers/PiProvider.ts +++ b/apps/server/src/provider/Layers/PiProvider.ts @@ -29,7 +29,6 @@ import { const PI_PRESENTATION = { displayName: "Pi", - badgeLabel: null, showInteractionModeToggle: false, requiresNewThreadForModelChange: false, } as const; diff --git a/apps/server/src/textGeneration/PiTextGeneration.ts b/apps/server/src/textGeneration/PiTextGeneration.ts index b96e6e73e203..220874451670 100644 --- a/apps/server/src/textGeneration/PiTextGeneration.ts +++ b/apps/server/src/textGeneration/PiTextGeneration.ts @@ -1,4 +1,5 @@ import * as Effect from "effect/Effect"; +import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; import { ChildProcessSpawner } from "effect/unstable/process"; import { resolveSpawnCommand } from "@t3tools/shared/shell"; @@ -60,16 +61,16 @@ export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* { env: environment }, ).pipe( Effect.mapError( - (cause) => + (cause: unknown) => new TextGenerationError({ operation, - detail: cause.message, + detail: (cause as { message?: string })?.message ?? String(cause), cause, }), ), ); - const result = yield* spawnAndCollect( + const resultOption = yield* spawnAndCollect( binaryPath, ChildProcess.make(spawnCommand.command, spawnCommand.args, { env: environment, @@ -77,23 +78,35 @@ export const makePiTextGeneration = Effect.fn("makePiTextGeneration")(function* shell: spawnCommand.shell, }), ).pipe( - Effect.timeoutFail({ - duration: PI_TIMEOUT_MS, - onTimeout: () => + Effect.mapError((cause: unknown) => { + if (isTextGenerationError(cause)) return cause as TextGenerationError; + return new TextGenerationError({ + operation, + detail: (cause as { message?: string })?.message ?? String(cause), + cause, + }); + }), + Effect.timeoutOption(PI_TIMEOUT_MS), + Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), + ); + const result = yield* Option.match(resultOption, { + onNone: () => + Effect.fail( new TextGenerationError({ operation, detail: `Pi text generation timed out after ${PI_TIMEOUT_MS}ms`, }), - }), - Effect.mapError((cause) => { - if (isTextGenerationError(cause)) return cause; + ), + onSome: (value) => Effect.succeed(value), + }).pipe( + Effect.mapError((cause: unknown) => { + if (isTextGenerationError(cause)) return cause as TextGenerationError; return new TextGenerationError({ operation, detail: cause instanceof Error ? cause.message : String(cause), cause, }); }), - Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), ); if (result.code !== 0) { From 9a58e6b19d327cff024fc129c5207b134ac7bf79 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 17:54:45 +1200 Subject: [PATCH 13/20] ci(release): increase job timeout to 20 minutes - increase timeout-minutes from 10 to 20 to prevent premature cancellation --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7e1e20a15157..944ff4432dd7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -167,7 +167,7 @@ jobs: needs: [preflight] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' }} runs-on: ubuntu-24.04 - timeout-minutes: 10 + timeout-minutes: 20 steps: - name: Checkout uses: actions/checkout@v6 From becc87de3f91b6edab11152ce35a1a24b4936165 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 20:09:38 +1200 Subject: [PATCH 14/20] ci(release): increase job timeout from 20 to 30 minutes --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 944ff4432dd7..a338c31760d3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -167,7 +167,7 @@ jobs: needs: [preflight] if: ${{ !failure() && !cancelled() && needs.preflight.result == 'success' }} runs-on: ubuntu-24.04 - timeout-minutes: 20 + timeout-minutes: 30 steps: - name: Checkout uses: actions/checkout@v6 From cd79a7e19b4ff43722f23ed6108ca1b0c41e5cc4 Mon Sep 17 00:00:00 2001 From: theoneand33 <120695243+theoneand33@users.noreply.github.com> Date: Fri, 28 Aug 2026 09:31:38 +1200 Subject: [PATCH 15/20] Update sync-upstream.yml --- .github/workflows/sync-upstream.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml index d37cde6c212b..2fa5955b1416 100644 --- a/.github/workflows/sync-upstream.yml +++ b/.github/workflows/sync-upstream.yml @@ -104,7 +104,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} META_MODEL_API_KEY: ${{ secrets.META_MODEL_API_KEY }} with: - model: meta/muse-spark-1.2-contributor + model: muse-spark-1.2-contributor use_github_token: true prompt: | Resolve git merge conflicts from an upstream sync (upstream/${{ env.UPSTREAM_BRANCH }} into ${{ env.TARGET_BRANCH }}). From aec8820c6f3ec4c8b004dd986f2f86e04ec178d5 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Wed, 26 Aug 2026 20:22:23 +1200 Subject: [PATCH 16/20] feat(pi): add filesystem skill discovery for $ picker - Scan global (~/.pi/agent/skills, ~/.agents/skills) and project (.pi/skills, .agents/skills ancestors plus .claude/skills) roots - Parse SKILL.md frontmatter for name/description with project-over-user precedence - Include skills in Pi provider snapshot and wire FileSystem/Path/cwd through driver --- apps/server/src/provider/Drivers/PiDriver.ts | 13 +- apps/server/src/provider/Drivers/PiSkills.ts | 145 ++++++++++++++++++ apps/server/src/provider/Layers/PiProvider.ts | 21 ++- 3 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 apps/server/src/provider/Drivers/PiSkills.ts diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/apps/server/src/provider/Drivers/PiDriver.ts index 89aa2fd2e72d..aeb6dcf8eac5 100644 --- a/apps/server/src/provider/Drivers/PiDriver.ts +++ b/apps/server/src/provider/Drivers/PiDriver.ts @@ -73,6 +73,9 @@ export const PiDriver: ProviderDriver = { Effect.gen(function* () { const crypto = yield* Crypto.Crypto; const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const fileSystem = yield* FileSystem.FileSystem; + const path = yield* Path.Path; + const serverConfig = yield* ServerConfig; const httpClient = yield* HttpClient.HttpClient; const serverSettings = yield* ServerSettingsService; const processEnv = mergeProviderInstanceEnvironment(environment); @@ -101,11 +104,13 @@ export const PiDriver: ProviderDriver = { const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, serverSettings); const checkProvider = Effect.flatMap(snapshotSettings.getSettings, (settings) => - checkPiProviderStatus(settings.provider, processEnv), + checkPiProviderStatus(settings.provider, processEnv, serverConfig.cwd), ).pipe( Effect.map(stampIdentity), Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), + Effect.provideService(FileSystem.FileSystem, fileSystem), + Effect.provideService(Path.Path, path), ); const snapshot = yield* makeManagedServerProvider>({ maintenanceCapabilities, @@ -113,7 +118,11 @@ export const PiDriver: ProviderDriver = { streamSettings: snapshotSettings.streamSettings, haveSettingsChanged: haveProviderSnapshotSettingsChanged, initialSnapshot: (settings) => - buildInitialPiProviderSnapshot(settings.provider).pipe(Effect.map(stampIdentity)), + buildInitialPiProviderSnapshot(settings.provider).pipe( + Effect.provideService(FileSystem.FileSystem, fileSystem), + Effect.provideService(Path.Path, path), + Effect.map(stampIdentity), + ), checkProvider, enrichSnapshot: ({ settings, snapshot: currentSnapshot, publishSnapshot }) => enrichPiSnapshot({ diff --git a/apps/server/src/provider/Drivers/PiSkills.ts b/apps/server/src/provider/Drivers/PiSkills.ts new file mode 100644 index 000000000000..11a4c9110454 --- /dev/null +++ b/apps/server/src/provider/Drivers/PiSkills.ts @@ -0,0 +1,145 @@ +/** + * PiSkills — filesystem discovery of Pi skills for the `$` picker. + * + * Pi loads skills from: + * - Global: `~/.pi/agent/skills/`, `~/.agents/skills/` + * - Project (trusted): `.pi/skills/`, `.agents/skills/` in `cwd` and ancestors + * up to the filesystem root (mirrors Pi's ancestor walk). + * + * One directory per skill with a `SKILL.md` carrying YAML frontmatter. + * Later roots win on name collisions so project skills override user skills. + * + * @module provider/Drivers/PiSkills + */ +import * as NodeOS from "node:os"; + +import type { ServerProviderSkill } from "@t3tools/contracts"; +import * as Effect from "effect/Effect"; +import * as FileSystem from "effect/FileSystem"; +import * as Path from "effect/Path"; +import { parse as parseYamlDocument } from "yaml"; + +const FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/; + +type SkillFrontmatter = + | { readonly kind: "missing" } + | { readonly kind: "malformed" } + | { readonly kind: "parsed"; readonly name?: string; readonly description?: string }; + +function parseSkillFrontmatter(contents: string): SkillFrontmatter { + const match = FRONTMATTER_PATTERN.exec(contents); + if (!match) { + return { kind: "missing" }; + } + let parsed: unknown; + try { + parsed = parseYamlDocument(match[1] ?? ""); + } catch { + return { kind: "malformed" }; + } + if (typeof parsed !== "object" || parsed === null) { + return { kind: "malformed" }; + } + const record = parsed as Record; + const name = typeof record.name === "string" ? record.name.trim() : ""; + const description = typeof record.description === "string" ? record.description.trim() : ""; + return { + kind: "parsed", + ...(name ? { name } : {}), + ...(description ? { description } : {}), + }; +} + +type PiSkillScope = "user" | "project"; + +function ancestorDirectories(cwd: string, path: Path.Path): ReadonlyArray { + const resolved = path.resolve(cwd); + const ancestors: string[] = []; + let cursor = resolved; + const seen = new Set(); + while (true) { + if (!seen.has(cursor)) { + seen.add(cursor); + ancestors.push(cursor); + } + const parent = path.dirname(cursor); + if (parent === cursor) break; + cursor = parent; + } + return ancestors; +} + +export const discoverPiSkills = Effect.fn("discoverPiSkills")(function* ( + cwd?: string, + _environment?: NodeJS.ProcessEnv, +): Effect.fn.Return, never, FileSystem.FileSystem | Path.Path> { + const fileSystem = yield* FileSystem.FileSystem; + const path = yield* Path.Path; + + const homedir = NodeOS.homedir(); + + // Global roots — always scanned. + const globalRoots: ReadonlyArray<{ directory: string; scope: PiSkillScope }> = [ + { directory: path.join(homedir, ".pi", "agent", "skills"), scope: "user" }, + { directory: path.join(homedir, ".agents", "skills"), scope: "user" }, + ]; + + // Project roots — cwd and ancestors for .pi/skills and .agents/skills. + const projectRoots: ReadonlyArray<{ directory: string; scope: PiSkillScope }> = cwd + ? ancestorDirectories(cwd, path).flatMap((ancestor) => [ + { directory: path.join(ancestor, ".pi", "skills"), scope: "project" as const }, + { directory: path.join(ancestor, ".agents", "skills"), scope: "project" as const }, + ]) + : []; + + // Also include cwd's .claude/skills for shared skill reuse? Pi docs say + // users can add ~/.claude/skills via settings.skills, but discovery for + // `$` picker should surface project-local .claude/skills when present, + // mirroring Claude's behavior for cross-harness reuse. + const crossHarnessProjectRoots: ReadonlyArray<{ directory: string; scope: PiSkillScope }> = cwd + ? [{ directory: path.join(cwd, ".claude", "skills"), scope: "project" as const }] + : []; + + // Order: global first, then project ancestors (cwd first, then parents outward). + // Later entries win on name collision, so project overrides user. + const roots = [...globalRoots, ...projectRoots, ...crossHarnessProjectRoots]; + + const skillsByName = new Map(); + for (const root of roots) { + const entries = yield* fileSystem + .readDirectory(root.directory) + .pipe(Effect.orElseSucceed((): ReadonlyArray => [])); + + for (const entry of [...entries].sort()) { + const skillPath = path.join(root.directory, entry, "SKILL.md"); + const contents = yield* fileSystem + .readFileString(skillPath) + .pipe(Effect.orElseSucceed(() => undefined)); + if (contents === undefined) { + continue; + } + const frontmatter = parseSkillFrontmatter(contents); + if (frontmatter.kind === "malformed") { + continue; + } + const name = (frontmatter.kind === "parsed" ? frontmatter.name : undefined) ?? entry.trim(); + if (!name) { + continue; + } + // Skip if already set by a later (higher priority) root? Actually we + // iterate in priority order user -> project, and later should win, so + // always set (overwrites). + skillsByName.set(name, { + name, + path: skillPath, + enabled: true, + scope: root.scope, + ...(frontmatter.kind === "parsed" && frontmatter.description + ? { description: frontmatter.description } + : {}), + }); + } + } + + return [...skillsByName.values()].sort((left, right) => left.name.localeCompare(right.name)); +}); diff --git a/apps/server/src/provider/Layers/PiProvider.ts b/apps/server/src/provider/Layers/PiProvider.ts index 0074b013dd75..3583926b9020 100644 --- a/apps/server/src/provider/Layers/PiProvider.ts +++ b/apps/server/src/provider/Layers/PiProvider.ts @@ -7,7 +7,9 @@ import type { import { causeErrorTag } from "@t3tools/shared/observability"; import * as DateTime from "effect/DateTime"; import * as Effect from "effect/Effect"; +import * as FileSystem from "effect/FileSystem"; import * as Option from "effect/Option"; +import * as Path from "effect/Path"; import * as Result from "effect/Result"; import { HttpClient } from "effect/unstable/http"; import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; @@ -26,6 +28,7 @@ import { enrichProviderSnapshotWithVersionAdvisory, type ProviderMaintenanceCapabilities, } from "../providerMaintenance.ts"; +import { discoverPiSkills } from "../Drivers/PiSkills.ts"; const PI_PRESENTATION = { displayName: "Pi", @@ -50,10 +53,11 @@ const PI_BUILT_IN_MODELS: ReadonlyArray = [ export function buildInitialPiProviderSnapshot( piSettings: PiSettings, -): Effect.Effect { +): Effect.Effect { return Effect.gen(function* () { const checkedAt = yield* Effect.map(DateTime.now, DateTime.formatIso); const models = piModelsFromSettings(piSettings.customModels); + const skills = yield* discoverPiSkills(process.cwd()).pipe(Effect.orElseSucceed(() => [])); if (!piSettings.enabled) { return buildServerProvider({ @@ -61,6 +65,7 @@ export function buildInitialPiProviderSnapshot( enabled: false, checkedAt, models, + skills, probe: { installed: false, version: null, @@ -76,6 +81,7 @@ export function buildInitialPiProviderSnapshot( enabled: true, checkedAt, models, + skills, probe: { installed: true, version: null, @@ -115,9 +121,15 @@ const runPiVersionCommand = ( export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function* ( piSettings: PiSettings, environment: NodeJS.ProcessEnv = process.env, -): Effect.fn.Return { + cwd: string = process.cwd(), +): Effect.fn.Return< + ServerProviderDraft, + never, + ChildProcessSpawner.ChildProcessSpawner | FileSystem.FileSystem | Path.Path +> { const checkedAt = DateTime.formatIso(yield* DateTime.now); const fallbackModels = piModelsFromSettings(piSettings.customModels); + const skills = yield* discoverPiSkills(cwd, environment).pipe(Effect.orElseSucceed(() => [])); if (!piSettings.enabled) { return buildServerProvider({ @@ -125,6 +137,7 @@ export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function enabled: false, checkedAt, models: fallbackModels, + skills, probe: { installed: false, version: null, @@ -150,6 +163,7 @@ export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function enabled: piSettings.enabled, checkedAt, models: fallbackModels, + skills, probe: { installed: !isCommandMissingCause(error), version: null, @@ -168,6 +182,7 @@ export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function enabled: piSettings.enabled, checkedAt, models: fallbackModels, + skills, probe: { installed: true, version: null, @@ -191,6 +206,7 @@ export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function enabled: piSettings.enabled, checkedAt, models: fallbackModels, + skills, probe: { installed: true, version, @@ -206,6 +222,7 @@ export const checkPiProviderStatus = Effect.fn("checkPiProviderStatus")(function enabled: piSettings.enabled, checkedAt, models: fallbackModels, + skills, probe: { installed: true, version, From ed725c04ae30fb043c75c8f909c56c08cec56762 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 27 Aug 2026 08:33:27 +1200 Subject: [PATCH 17/20] fix(pi): recursive skill discovery and cwd-aware snapshot - traverse each configured skill root recursively to discover nested SKILL.md files (e.g. collection/skills/example/SKILL.md) while preserving frontmatter parsing - make buildInitialPiProviderSnapshot accept cwd and pass serverConfig.cwd from PiDriver instead of process.cwd() --- apps/server/src/provider/Drivers/PiDriver.ts | 2 +- apps/server/src/provider/Drivers/PiSkills.ts | 39 ++++++++++++++++--- apps/server/src/provider/Layers/PiProvider.ts | 3 +- 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/apps/server/src/provider/Drivers/PiDriver.ts index aeb6dcf8eac5..ca35ea110beb 100644 --- a/apps/server/src/provider/Drivers/PiDriver.ts +++ b/apps/server/src/provider/Drivers/PiDriver.ts @@ -118,7 +118,7 @@ export const PiDriver: ProviderDriver = { streamSettings: snapshotSettings.streamSettings, haveSettingsChanged: haveProviderSnapshotSettingsChanged, initialSnapshot: (settings) => - buildInitialPiProviderSnapshot(settings.provider).pipe( + buildInitialPiProviderSnapshot(settings.provider, serverConfig.cwd).pipe( Effect.provideService(FileSystem.FileSystem, fileSystem), Effect.provideService(Path.Path, path), Effect.map(stampIdentity), diff --git a/apps/server/src/provider/Drivers/PiSkills.ts b/apps/server/src/provider/Drivers/PiSkills.ts index 11a4c9110454..d09f66ea3d3a 100644 --- a/apps/server/src/provider/Drivers/PiSkills.ts +++ b/apps/server/src/provider/Drivers/PiSkills.ts @@ -106,12 +106,38 @@ export const discoverPiSkills = Effect.fn("discoverPiSkills")(function* ( const skillsByName = new Map(); for (const root of roots) { - const entries = yield* fileSystem - .readDirectory(root.directory) - .pipe(Effect.orElseSucceed((): ReadonlyArray => [])); + const skillPaths: Array = []; + const stack: Array = [root.directory]; + const seenDirs = new Set(); + while (stack.length > 0) { + const current = stack.pop() as string; + if (seenDirs.has(current)) { + continue; + } + seenDirs.add(current); + const entries = yield* fileSystem + .readDirectory(current) + .pipe(Effect.orElseSucceed((): ReadonlyArray => [])); + for (const entry of [...entries].sort()) { + const fullPath = path.join(current, entry); + const candidateSkillPath = path.join(fullPath, "SKILL.md"); + const candidateContents = yield* fileSystem + .readFileString(candidateSkillPath) + .pipe(Effect.orElseSucceed(() => undefined)); + if (candidateContents !== undefined) { + skillPaths.push(candidateSkillPath); + } + const subEntries = yield* fileSystem.readDirectory(fullPath).pipe( + Effect.map((value): ReadonlyArray | undefined => value), + Effect.orElseSucceed((): ReadonlyArray | undefined => undefined), + ); + if (subEntries !== undefined) { + stack.push(fullPath); + } + } + } - for (const entry of [...entries].sort()) { - const skillPath = path.join(root.directory, entry, "SKILL.md"); + for (const skillPath of [...skillPaths].sort()) { const contents = yield* fileSystem .readFileString(skillPath) .pipe(Effect.orElseSucceed(() => undefined)); @@ -122,7 +148,8 @@ export const discoverPiSkills = Effect.fn("discoverPiSkills")(function* ( if (frontmatter.kind === "malformed") { continue; } - const name = (frontmatter.kind === "parsed" ? frontmatter.name : undefined) ?? entry.trim(); + const fallbackName = path.basename(path.dirname(skillPath)).trim(); + const name = (frontmatter.kind === "parsed" ? frontmatter.name : undefined) ?? fallbackName; if (!name) { continue; } diff --git a/apps/server/src/provider/Layers/PiProvider.ts b/apps/server/src/provider/Layers/PiProvider.ts index 3583926b9020..7b53f1150339 100644 --- a/apps/server/src/provider/Layers/PiProvider.ts +++ b/apps/server/src/provider/Layers/PiProvider.ts @@ -53,11 +53,12 @@ const PI_BUILT_IN_MODELS: ReadonlyArray = [ export function buildInitialPiProviderSnapshot( piSettings: PiSettings, + cwd?: string, ): Effect.Effect { return Effect.gen(function* () { const checkedAt = yield* Effect.map(DateTime.now, DateTime.formatIso); const models = piModelsFromSettings(piSettings.customModels); - const skills = yield* discoverPiSkills(process.cwd()).pipe(Effect.orElseSucceed(() => [])); + const skills = yield* discoverPiSkills(cwd).pipe(Effect.orElseSucceed(() => [])); if (!piSettings.enabled) { return buildServerProvider({ From 8d820de23527693171e28bb0add40b7b3faec372 Mon Sep 17 00:00:00 2001 From: theoneand33 <120695243+theoneand33@users.noreply.github.com> Date: Fri, 28 Aug 2026 09:43:52 +1200 Subject: [PATCH 18/20] Update sync-upstream.yml --- .github/workflows/sync-upstream.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml index 2fa5955b1416..1f7e129eb912 100644 --- a/.github/workflows/sync-upstream.yml +++ b/.github/workflows/sync-upstream.yml @@ -102,9 +102,9 @@ jobs: uses: anomalyco/opencode/github@latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - META_MODEL_API_KEY: ${{ secrets.META_MODEL_API_KEY }} + META_MODEL_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} with: - model: muse-spark-1.2-contributor + model: openrouter/z-ai/glm-5.3-flash use_github_token: true prompt: | Resolve git merge conflicts from an upstream sync (upstream/${{ env.UPSTREAM_BRANCH }} into ${{ env.TARGET_BRANCH }}). @@ -167,7 +167,7 @@ jobs: --body "$(cat <<'EOF' Automated upstream sync from `${{ env.UPSTREAM_REPOSITORY }}`:`${{ env.UPSTREAM_BRANCH }}`. - - Auto-merge failed — conflicts were resolved by opencode (model: \`meta/muse-spark-1.2-contributor\`, logic based on \`opencode-review.yml\`). + - Auto-merge failed — conflicts were resolved by opencode (model: \`z-ai/glm-5.3-flash\`, logic based on \`opencode-review.yml\`). - Please review the resolution before merging. CI must pass. Upstream commits: From 60c4f0366f32a48026dbce7b275425e5215407f4 Mon Sep 17 00:00:00 2001 From: theoneand33 Date: Fri, 28 Aug 2026 09:44:28 +1200 Subject: [PATCH 19/20] chore(ci): use glm 5.3 flash via openrouter for opencode actions Update both opencode GitHub actions (opencode-review and sync-upstream) to use openrouter/z-ai/glm-5.3-flash with OPENROUTER_API_KEY per https://opencode.ai/docs/github. --- .github/workflows/opencode-review.yml | 4 ++-- .github/workflows/sync-upstream.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml index 5efbbeb3f91e..829fee845b03 100644 --- a/.github/workflows/opencode-review.yml +++ b/.github/workflows/opencode-review.yml @@ -32,9 +32,9 @@ jobs: uses: anomalyco/opencode/github@latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - META_MODEL_API_KEY: ${{ secrets.META_MODEL_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} with: - model: meta/muse-spark-1.2-contributor + model: openrouter/z-ai/glm-5.3-flash use_github_token: true # ponytail: OIDC workaround for repos created after 2026-07-15 (immutable sub format → p.rest). Remove when https://github.com/anomalyco/opencode/issues/37823 is fixed upstream prompt: | diff --git a/.github/workflows/sync-upstream.yml b/.github/workflows/sync-upstream.yml index 1f7e129eb912..3bfadbb77be7 100644 --- a/.github/workflows/sync-upstream.yml +++ b/.github/workflows/sync-upstream.yml @@ -102,7 +102,7 @@ jobs: uses: anomalyco/opencode/github@latest env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - META_MODEL_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} + OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} with: model: openrouter/z-ai/glm-5.3-flash use_github_token: true @@ -167,7 +167,7 @@ jobs: --body "$(cat <<'EOF' Automated upstream sync from `${{ env.UPSTREAM_REPOSITORY }}`:`${{ env.UPSTREAM_BRANCH }}`. - - Auto-merge failed — conflicts were resolved by opencode (model: \`z-ai/glm-5.3-flash\`, logic based on \`opencode-review.yml\`). + - Auto-merge failed — conflicts were resolved by opencode (model: \`openrouter/z-ai/glm-5.3-flash\`, logic based on \`opencode-review.yml\`). - Please review the resolution before merging. CI must pass. Upstream commits: From c69d3b8fa4ed5a0437c924221f507d392cce0ba1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 27 Aug 2026 22:00:58 +0000 Subject: [PATCH 20/20] chore: resolve upstream sync conflicts --- apps/desktop/package.json | 2 +- apps/mobile/app.config.ts | 9 +- .../mobile/assets/android-icon-foreground.png | Bin 0 -> 3457 bytes .../mobile/assets/android-icon-foreground.svg | 8 + .../src/features/usage/usageProviders.ts | 8 +- apps/mobile/src/lib/mobileBranding.test.ts | 14 - apps/server/package.json | 2 +- apps/server/scripts/acp-mock-agent.ts | 242 ++++- apps/server/scripts/cliErrors.test.ts | 31 - apps/server/src/checkpointing/Errors.test.ts | 39 - .../src/observability/Attributes.test.ts | 11 - .../Layers/ProjectionPipeline.test.ts | 71 ++ .../Layers/ProjectionPipeline.ts | 1 + .../Layers/ProviderCommandReactor.test.ts | 6 +- .../Layers/ProviderCommandReactor.ts | 8 +- .../server/src/provider/Drivers/GrokDriver.ts | 3 +- .../src/provider/Drivers/GrokSkills.test.ts | 135 +++ .../server/src/provider/Drivers/GrokSkills.ts | 119 +++ .../src/provider/Layers/GrokAdapter.test.ts | 823 +++++++++++++++++- .../server/src/provider/Layers/GrokAdapter.ts | 620 ++++++++++++- .../src/provider/Layers/GrokProvider.test.ts | 175 +++- .../src/provider/Layers/GrokProvider.ts | 113 ++- .../provider/acp/AcpJsonRpcConnection.test.ts | 25 +- .../src/provider/acp/AcpRuntimeModel.test.ts | 190 +++- .../src/provider/acp/AcpRuntimeModel.ts | 144 ++- .../src/provider/acp/AcpSessionRuntime.ts | 7 +- .../src/provider/acp/GrokAcpCliProbe.test.ts | 63 +- .../src/provider/acp/GrokAcpSupport.test.ts | 109 ++- .../server/src/provider/acp/GrokAcpSupport.ts | 86 +- .../src/provider/acp/XAiAcpExtension.test.ts | 194 +++++ .../src/provider/acp/XAiAcpExtension.ts | 262 +++++- apps/server/src/terminal/PtyAdapter.test.ts | 34 - .../src/textGeneration/GrokTextGeneration.ts | 10 + apps/server/src/usage/UsageService.ts | 27 +- apps/server/src/usage/usageScanCache.test.ts | 11 +- apps/server/src/usage/usageScanCache.ts | 2 +- .../server/src/usage/usageTranscriptReader.ts | 19 +- .../server/src/usage/usageTranscripts.test.ts | 315 +++++++ apps/server/src/usage/usageTranscripts.ts | 194 ++++- apps/server/src/vcs/GitVcsDriverCore.test.ts | 12 - apps/web/package.json | 2 +- apps/web/src/assets/assetUrls.test.ts | 15 - .../components/StartTruncatedPath.test.tsx | 31 - .../preview/previewAutomationClientId.test.ts | 13 - .../settings/ProviderInstanceCard.tsx | 580 ++++++------ ...ProviderSettingsPanel.environment.test.tsx | 67 +- .../settings/ProviderSettingsPanel.tsx | 616 +++++++------ .../settings/providerSettingsTabs.ts | 10 + .../src/components/settings/providerStatus.ts | 2 +- .../src/components/threadSidebarWidth.test.ts | 48 - apps/web/src/components/threadSidebarWidth.ts | 2 +- .../src/components/ui/toggle-group.test.tsx | 19 - .../usage/UsageProviderChart.test.ts | 1 + .../src/components/usage/usageProviders.ts | 8 +- apps/web/src/reactGrabBoundary.test.ts | 12 - assets/README.md | 14 + docs/user/install.md | 4 + docs/user/permission-modes.md | 10 +- docs/user/usage.md | 11 +- .../client-runtime/src/state/session.test.ts | 21 - packages/client-runtime/src/state/session.ts | 2 +- packages/contracts/package.json | 2 +- packages/contracts/src/usage.ts | 21 +- .../scripts/generate.ts | 31 +- .../src/_generated/schema.gen.ts | 631 ++++++++++++-- .../src/schema.test.ts | 73 ++ packages/shared/src/String.test.ts | 17 - packages/shared/src/themePreview.test.ts | 20 - packages/shared/src/usageMerge.test.ts | 28 +- packages/shared/src/usageMerge.ts | 25 +- scripts/lib/resolve-catalog.test.ts | 20 - scripts/lib/resolve-catalog.ts | 2 +- 72 files changed, 5340 insertions(+), 1162 deletions(-) create mode 100644 apps/mobile/assets/android-icon-foreground.png create mode 100644 apps/mobile/assets/android-icon-foreground.svg delete mode 100644 apps/mobile/src/lib/mobileBranding.test.ts delete mode 100644 apps/server/scripts/cliErrors.test.ts delete mode 100644 apps/server/src/checkpointing/Errors.test.ts delete mode 100644 apps/server/src/observability/Attributes.test.ts create mode 100644 apps/server/src/provider/Drivers/GrokSkills.test.ts create mode 100644 apps/server/src/provider/Drivers/GrokSkills.ts delete mode 100644 apps/server/src/terminal/PtyAdapter.test.ts delete mode 100644 apps/web/src/assets/assetUrls.test.ts delete mode 100644 apps/web/src/components/StartTruncatedPath.test.tsx delete mode 100644 apps/web/src/components/preview/previewAutomationClientId.test.ts create mode 100644 apps/web/src/components/settings/providerSettingsTabs.ts delete mode 100644 apps/web/src/components/threadSidebarWidth.test.ts delete mode 100644 apps/web/src/components/ui/toggle-group.test.tsx delete mode 100644 apps/web/src/reactGrabBoundary.test.ts delete mode 100644 packages/client-runtime/src/state/session.test.ts create mode 100644 packages/effect-codex-app-server/src/schema.test.ts delete mode 100644 packages/shared/src/String.test.ts delete mode 100644 packages/shared/src/themePreview.test.ts delete mode 100644 scripts/lib/resolve-catalog.test.ts diff --git a/apps/desktop/package.json b/apps/desktop/package.json index c88a69239577..d37ebc32fe0c 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@t3tools/desktop", - "version": "0.0.34", + "version": "0.0.35", "private": true, "type": "module", "main": "dist-electron/main.cjs", diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts index 9a51725478e1..0dc8dca96881 100644 --- a/apps/mobile/app.config.ts +++ b/apps/mobile/app.config.ts @@ -15,6 +15,9 @@ const personalTeamBundleIdentifier = repoEnv.T3CODE_IOS_PERSONAL_TEAM_BUNDLE_ID? const IOS_BUNDLE_IDENTIFIER_PATTERN = /^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/; const fromRepoRoot = (relativePath: string) => `../../${relativePath}`; +// Universal exports already contain their own rounded-square silhouette. Using one as an adaptive +// foreground makes Android draw an icon shape inside the launcher's mask. +const androidAdaptiveForeground = "./assets/android-icon-foreground.png"; if ( isIosPersonalTeamBuild && @@ -30,7 +33,7 @@ const DEVELOPMENT_ASSETS = { appIcon: fromRepoRoot(BRAND_ASSET_PATHS.developmentIosIconPng), iosIcon: fromRepoRoot(BRAND_ASSET_PATHS.developmentIconComposerProject), splashIcon: fromRepoRoot(BRAND_ASSET_PATHS.developmentIosIconPng), - androidAdaptiveForeground: fromRepoRoot(BRAND_ASSET_PATHS.developmentUniversalIconPng), + androidAdaptiveForeground, androidAdaptiveBackgroundColor: "#00639B", androidMonochromeIcon: "./assets/android-icon-mark.png", androidNotificationIcon: "./assets/android-notification-icon.png", @@ -41,7 +44,7 @@ const PREVIEW_ASSETS = { appIcon: fromRepoRoot(BRAND_ASSET_PATHS.nightlyIosIconPng), iosIcon: fromRepoRoot(BRAND_ASSET_PATHS.nightlyIconComposerProject), splashIcon: fromRepoRoot(BRAND_ASSET_PATHS.nightlyIosIconPng), - androidAdaptiveForeground: fromRepoRoot(BRAND_ASSET_PATHS.nightlyLinuxIconPng), + androidAdaptiveForeground, androidAdaptiveBackgroundColor: "#111533", androidMonochromeIcon: "./assets/android-icon-mark.png", androidNotificationIcon: "./assets/android-notification-icon.png", @@ -52,7 +55,7 @@ const RELEASE_ASSETS = { appIcon: fromRepoRoot(BRAND_ASSET_PATHS.productionIosIconPng), iosIcon: fromRepoRoot(BRAND_ASSET_PATHS.productionIconComposerProject), splashIcon: fromRepoRoot(BRAND_ASSET_PATHS.productionIosIconPng), - androidAdaptiveForeground: "./assets/android-icon-mark.png", + androidAdaptiveForeground, androidAdaptiveBackgroundColor: "#000000", androidMonochromeIcon: "./assets/android-icon-mark.png", androidNotificationIcon: "./assets/android-notification-icon.png", diff --git a/apps/mobile/assets/android-icon-foreground.png b/apps/mobile/assets/android-icon-foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..4f4374c7ebcf18bae99e5c8b58ce499fbf488615 GIT binary patch literal 3457 zcmd^B`Ck*)76+q2eF18*fXd=~22eo^@<1XGo`7Oxb77D?3=OiR3d$l$#1H~f*Vv*H zG%O+X)did)5K<5_ETIZ?3W9A#pb)S!%90Qs&=4VjZ?J#D`>`{h`OLlN-Z}HV=YG$* z-|I(00*u#hUT}9zgr(U>cR>#D?93#(2yPeb)JQjmLM+Gl`ss1Hi zo!fcrS84gnpRK^3U2nMMjBhR6aXNVC&NuXp8%f44uQT*9XRmGiq`P0m>;1QWwtyxZ z6?-#%x(j4XAEq)hX%&X$uYM&wj<;ZNS-PL8?B|-6nuSDwrx;0-?Mq{{q=xW z+iw@)jH`{7>mO5XD6moQL@zYa)2l@^%Q?jEEqzR3aRdM}MU48nBD#UW+!aF{W7j5< z!7K3pX)u0G1OFB;V$2gPt4>Skz*GtS(py)C!af}U8ZWTdwUHQ#hZiEj;e7g~6q9_q zLEUd6Q0xsqbML!@jC~$RUp^jA~K2f!-~FH(CP#bRVRH~XH**vO?1dSPZnvKG8lt)0BcC$1*YkisZk>7 zh_;4k>JsHC993jZ&XiJZ$fT)iq65&=ZWLebiy`io>&a9Jg_If!wgWvhoGZ-*Pv~<{ z@=`$yldqSaL;G0C_Ks~?hTO-n?JYEE&)k~m$}&hq=!`kAiNvT((h!$!4faL9YhL**YJ&f!U2; zDUIyOZiqL&Ez=FjY3vnD#VWG4+=m^J?}T1oFw{>#aRg9;c`3wVX{`O0m}{H=!~uzc zCU_X&ZFs_aiCo_+^x`I~WzfX;Ed}KpaQKszn#?aik@45O6kuuob ze}L{z61v4JvObi;{H;hNICz?&zD#R4x%_Q*K{*-w<5|^_pL!k0nGE#<+R3<)!R&%W z1I+yEnBR`dpqW5GyNp@Z;_$?R)a`Mg*F9)xkB87WT9HM&daS7milSh>Qwqk_qO|RA zw+OwG7&cpe%xW=lA3yRF$1dF$&?2rcG6=dUQ^^;=0A@;$ z9^3l_Sl^z~CbvH(^XC?b-dz$J24@xi)6 zLtMD>aka;Wg&ZYsP`#(z1cxsdaP8AWIn5cWA1&A(SYNmVdf6ddSYOs3m*0_Ps2Y<{ zDKC_!68e|v7-uWa-HqjNe9o~qyuphkn7jU1SE+e?v-+xx_m|z~(kBuXk3>Hta&y43C!d`yj!xI_CLgkWRC@nGO>< zhf<%h%?Iu8plhf$F7VopXly?pL8f-|FW8ySHBB^-Ye#lQa;h)wL3{wolPS!6j?h~67QTlX{HD# zvs7T-7RO#U>^AL+K?s)RRhl7G@Pd+`dgZ@Em54pzIeHnzsr)B-PW@(1s&ExIX z+s)S#r^Yq>ag7kxzkYCMz(~mp0%c&QU^*VlOkV$Gs22v4<^=%vJ@L#dgZW;s07 z>~`fiOP8%&ilkC*q348WGO8eo&yFIy!ewIOH^>4nDT zV%{Ona2d=eBLTui>bs~zI+mG?_AM^n!k~hk3c}|`df~HRX_B%@sbt!dw+Xm@%o9C! z1NnC}l#&8vJqpSX9ptFl?-EHE61z!Sp%#hEHW=L2tgY)3+qlodZMhJk#n$bjAS z*>FG<724}p?GdS(qh=BX7I9WZ=n$2?t8_Vv>j%*P39nvB5H~M-q}YgQQ^V3bD~p}F zCNO&1(Y%yZ394G>P;WJL<_&hV+u-oRv)+HWFMQRw_Zi?|`Qi0TbMDkjXde?xN+x~T zVNH=bj~LMHERA*!oq=V6RVVQT`w0zBxY(t(*)sMSphZ3^1pN7>!=Ps;HjlDJ*Ti0p z`AyU9r%F8G_AC8D^g5vZs{cR)1&5zqJYzo9b4tH>6exCqSI1bA@)@ea%iRUan5PZf zdU>DmSIRM2l81)N0uyiXLuUj)4U@g0&4oegdv(VtlgrLE#v);KR`);}!NU{U;J`N9 zvARbTF}e(}epmnFCR4$vg7$d|?j0D~2X_>5IiOK^&l;?jT{X;E2Tce7)-ljbn32LR zar*-z`iw+BEq-uP17cHlPZrvmhNd0?>3h)*yLzHP zRR6gcU37|anZN9GP$edghV?ucSP*6H`Y0nBKR5TQ<%31%mgZVd@P3OE|J6nN%KGP! Z538u!>jmzGqp>S}>VXjd3SY*h{{hBawy*#I literal 0 HcmV?d00001 diff --git a/apps/mobile/assets/android-icon-foreground.svg b/apps/mobile/assets/android-icon-foreground.svg new file mode 100644 index 000000000000..8d974992ab2c --- /dev/null +++ b/apps/mobile/assets/android-icon-foreground.svg @@ -0,0 +1,8 @@ + + + + + diff --git a/apps/mobile/src/features/usage/usageProviders.ts b/apps/mobile/src/features/usage/usageProviders.ts index 9a9ec5f2282d..2576ac21fb07 100644 --- a/apps/mobile/src/features/usage/usageProviders.ts +++ b/apps/mobile/src/features/usage/usageProviders.ts @@ -5,21 +5,23 @@ import { useAppearancePreferences } from "../settings/appearance/AppearancePrefe * Series and table order. The chart stacks providers from the bottom in this * order, so it also fixes which band sits on top of the bars. */ -export const PROVIDER_ORDER: readonly UsageProviderKind[] = ["codex", "claude"]; +export const PROVIDER_ORDER: readonly UsageProviderKind[] = ["codex", "claude", "grok"]; export const PROVIDER_LABEL: Record = { claude: "Claude Code", codex: "Codex", + grok: "Grok Build", }; /** - * Claude's brand orange holds in both themes; Codex is neutral and must flip - * with the theme or its bars vanish against the matching background. + * Claude's brand orange holds in both themes; Codex and Grok are neutrals and + * must flip with the theme or their bars vanish against the matching background. */ export function useProviderColors(): Record { const { themeAppearance: scheme } = useAppearancePreferences(); return { claude: "#d97757", codex: scheme === "dark" ? "#e6e6e6" : "#3c3c43", + grok: scheme === "dark" ? "#a1a1aa" : "#52525b", }; } diff --git a/apps/mobile/src/lib/mobileBranding.test.ts b/apps/mobile/src/lib/mobileBranding.test.ts deleted file mode 100644 index 48a84b3f9857..000000000000 --- a/apps/mobile/src/lib/mobileBranding.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { describe, expect, it } from "vite-plus/test"; - -import { resolveMobileStageLabel } from "./mobileBranding"; - -describe("resolveMobileStageLabel", () => { - it.each([ - ["development", "Dev"], - ["preview", "Nightly"], - ["production", "Alpha"], - [undefined, "Alpha"], - ])("maps %s builds to %s", (appVariant, expected) => { - expect(resolveMobileStageLabel(appVariant)).toBe(expected); - }); -}); diff --git a/apps/server/package.json b/apps/server/package.json index ca19f7085f9d..4d17229cd3af 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "t3", - "version": "0.0.34", + "version": "0.0.35", "license": "MIT", "repository": { "type": "git", diff --git a/apps/server/scripts/acp-mock-agent.ts b/apps/server/scripts/acp-mock-agent.ts index bc7828dd8547..e51a8883f4f9 100644 --- a/apps/server/scripts/acp-mock-agent.ts +++ b/apps/server/scripts/acp-mock-agent.ts @@ -19,7 +19,15 @@ const emitInterleavedAssistantToolCalls = const emitGenericToolPlaceholders = process.env.T3_ACP_EMIT_GENERIC_TOOL_PLACEHOLDERS === "1"; const emitAskQuestion = process.env.T3_ACP_EMIT_ASK_QUESTION === "1"; const emitXAiAskUserQuestion = process.env.T3_ACP_EMIT_XAI_ASK_USER_QUESTION === "1"; +const emitXAiExitPlanMode = process.env.T3_ACP_EMIT_XAI_EXIT_PLAN_MODE === "1"; +const emitXAiPlanMdWrite = process.env.T3_ACP_EMIT_XAI_PLAN_MD_WRITE === "1"; const emitXAiPromptCompleteThenHang = process.env.T3_ACP_EMIT_XAI_PROMPT_COMPLETE_THEN_HANG === "1"; +const emitXAiRateLimitThenHang = process.env.T3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG === "1"; +const emitXAiAskUserQuestionThenHang = + process.env.T3_ACP_EMIT_XAI_ASK_USER_QUESTION_THEN_HANG === "1"; +const emitContentThenHang = process.env.T3_ACP_EMIT_CONTENT_THEN_HANG === "1"; +const emitPlanThenHang = process.env.T3_ACP_EMIT_PLAN_THEN_HANG === "1"; +const emitActiveToolThenHang = process.env.T3_ACP_EMIT_ACTIVE_TOOL_THEN_HANG === "1"; const emitForeignSessionUpdates = process.env.T3_ACP_EMIT_FOREIGN_SESSION_UPDATES === "1"; const hangPromptForever = process.env.T3_ACP_HANG_PROMPT_FOREVER === "1"; const hangFirstPromptForever = process.env.T3_ACP_HANG_FIRST_PROMPT_FOREVER === "1"; @@ -39,12 +47,19 @@ const failPrompt = process.env.T3_ACP_FAIL_PROMPT === "1"; const failSetConfigOption = process.env.T3_ACP_FAIL_SET_CONFIG_OPTION === "1"; const exitOnSetConfigOption = process.env.T3_ACP_EXIT_ON_SET_CONFIG_OPTION === "1"; const promptResponseText = process.env.T3_ACP_PROMPT_RESPONSE_TEXT; +const initialGrokReasoningEffort = + process.env.T3_ACP_INITIAL_GROK_REASONING_EFFORT?.trim() || undefined; const promptDelayMs = Number(process.env.T3_ACP_PROMPT_DELAY_MS ?? "0"); const permissionOptionIds = { allowOnce: process.env.T3_ACP_ALLOW_ONCE_OPTION_ID ?? "allow-once", allowAlways: process.env.T3_ACP_ALLOW_ALWAYS_OPTION_ID ?? "allow-always", rejectOnce: process.env.T3_ACP_REJECT_ONCE_OPTION_ID ?? "reject-once", }; +const omitAllowAlways = process.env.T3_ACP_OMIT_ALLOW_ALWAYS === "1"; +const permissionRequestCount = Math.max( + 1, + Number(process.env.T3_ACP_PERMISSION_REQUEST_COUNT ?? "1") || 1, +); const sessionId = "mock-session-1"; let currentModeId = "ask"; @@ -279,7 +294,13 @@ function modeState(): AcpSchema.SessionModeState { } const grokAcpModels: ReadonlyArray = [ - { modelId: "grok-build", name: "Grok Build" }, + { + modelId: "grok-build", + name: "Grok Build", + ...(initialGrokReasoningEffort + ? { _meta: { reasoningEffort: initialGrokReasoningEffort } } + : {}), + }, { modelId: "grok-mock-alt", name: "Grok Mock Alt" }, ]; @@ -522,6 +543,68 @@ const program = Effect.gen(function* () { return yield* Effect.never; } + if (emitXAiRateLimitThenHang) { + writeJsonRpcNotification("_x.ai/session/prompt_complete", { + sessionId: requestedSessionId, + promptId: promptIdFromRequestMeta(request) ?? "mock-xai-rate-limit-prompt-1", + stopReason: "rate_limit", + agentResult: null, + }); + return yield* Effect.never; + } + + if (emitContentThenHang) { + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "agent_message_chunk", + content: { type: "text", text: "partial before stall" }, + }, + }); + return yield* Effect.never; + } + + if (emitPlanThenHang) { + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "plan", + entries: [ + { + content: "Wait for more ACP progress", + priority: "high", + status: "in_progress", + }, + ], + }, + }); + return yield* Effect.never; + } + + if (emitActiveToolThenHang) { + const toolCallId = "tool-call-long-running-1"; + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "tool_call", + toolCallId, + title: "Long-running tool", + kind: "execute", + status: "pending", + rawInput: { command: ["long-running-tool"] }, + }, + }); + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "tool_call_update", + toolCallId, + status: "in_progress", + }, + }); + return yield* Effect.never; + } + if (emitXAiPromptCompleteThenHang) { writeJsonRpcNotification("session/update", { sessionId: requestedSessionId, @@ -656,37 +739,58 @@ const program = Effect.gen(function* () { }, }); - const permission = yield* agent.client.requestPermission({ - sessionId: requestedSessionId, - toolCall: { - toolCallId, - title: "`cat server/package.json`", - kind: "execute", - status: "pending", - content: [ - { - type: "content", - content: { - type: "text", - text: "Not in allowlist: cat server/package.json", + const permissionOptions: Array = [ + { optionId: permissionOptionIds.allowOnce, name: "Allow once", kind: "allow_once" }, + ...(omitAllowAlways + ? [] + : [ + { + optionId: permissionOptionIds.allowAlways, + name: "Allow always", + kind: "allow_always" as const, }, + ]), + { optionId: permissionOptionIds.rejectOnce, name: "Reject", kind: "reject_once" }, + ]; + + let cancelled = cancelledSessions.delete(requestedSessionId); + for (let index = 0; index < permissionRequestCount; index++) { + const command = + index > 0 + ? (process.env.T3_ACP_SECOND_PERMISSION_COMMAND ?? "cat server/package.json") + : "cat server/package.json"; + const permission = yield* agent.client.requestPermission({ + sessionId: requestedSessionId, + toolCall: { + toolCallId: index === 0 ? toolCallId : `${toolCallId}-${index + 1}`, + title: process.env.T3_ACP_PERMISSION_TITLE ?? `\`${command}\``, + kind: "execute", + status: "pending", + rawInput: { + variant: "Bash", + command, + description: index === 0 ? "Read package metadata" : "Read it again", }, - ], - }, - options: [ - { optionId: permissionOptionIds.allowOnce, name: "Allow once", kind: "allow_once" }, - { - optionId: permissionOptionIds.allowAlways, - name: "Allow always", - kind: "allow_always", + content: [ + { + type: "content", + content: { + type: "text", + text: `Not in allowlist: ${command}`, + }, + }, + ], }, - { optionId: permissionOptionIds.rejectOnce, name: "Reject", kind: "reject_once" }, - ], - }); - - const cancelled = - cancelledSessions.delete(requestedSessionId) || - permission.outcome.outcome === "cancelled"; + options: permissionOptions, + }); + cancelled = + cancelled || + cancelledSessions.delete(requestedSessionId) || + permission.outcome.outcome === "cancelled"; + if (cancelled) { + break; + } + } yield* agent.client.sessionUpdate({ sessionId: requestedSessionId, @@ -773,7 +877,7 @@ const program = Effect.gen(function* () { return { stopReason: "end_turn" }; } - if (emitXAiAskUserQuestion) { + if (emitXAiAskUserQuestion || emitXAiAskUserQuestionThenHang) { const result = yield* agent.client.extRequest("_x.ai/ask_user_question", { method: "x.ai/ask_user_question", params: { @@ -807,6 +911,84 @@ const program = Effect.gen(function* () { throw new Error("Expected accepted _x.ai/ask_user_question response answers."); } + if (emitXAiAskUserQuestionThenHang) { + return yield* Effect.never; + } + + return { stopReason: "end_turn" }; + } + + if (emitXAiPlanMdWrite) { + // Match Grok's real session layout so isGrokPlanMarkdownPath accepts it. + const planRoot = process.env.T3_ACP_PLAN_ROOT ?? "/tmp/mock-home/.grok"; + const planPath = `${planRoot}/sessions/${requestedSessionId}/plan.md`; + const planBody = "# Mock plan\n\n- Write the feature\n- Add a test\n- Ship it\n"; + // enter_plan_mode first so the adapter arms planModeActive. + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "tool_call", + toolCallId: "enter-plan-mode-1", + title: "enter_plan_mode", + kind: "other", + status: "completed", + rawInput: { variant: "EnterPlanMode" }, + }, + }); + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "tool_call", + toolCallId: "plan-md-write-1", + title: "write", + kind: "edit", + status: "pending", + rawInput: { file_path: planPath, content: planBody }, + }, + }); + yield* agent.client.sessionUpdate({ + sessionId: requestedSessionId, + update: { + sessionUpdate: "tool_call_update", + toolCallId: "plan-md-write-1", + kind: "edit", + status: "completed", + title: `Write \`${planPath}\``, + rawInput: { file_path: planPath, content: planBody }, + content: [ + { + type: "diff", + path: planPath, + oldText: "", + newText: planBody, + }, + ], + }, + }); + return { stopReason: "end_turn" }; + } + + if (emitXAiExitPlanMode) { + const result = yield* agent.client.extRequest("_x.ai/exit_plan_mode", { + method: "x.ai/exit_plan_mode", + params: { + sessionId: requestedSessionId, + toolCallId: "exit-plan-mode-tool-call-1", + planContent: "# Exit plan\n\n- Step one\n- Step two\n", + }, + }); + if (typeof result !== "object" || result === null || !("outcome" in result)) { + throw new Error("Expected _x.ai/exit_plan_mode response outcome."); + } + if ( + result.outcome !== "abandoned" && + result.outcome !== "approved" && + result.outcome !== "request_changes" + ) { + throw new Error( + `Expected exit_plan_mode outcome abandoned|approved|request_changes, got ${String(result.outcome)}`, + ); + } return { stopReason: "end_turn" }; } diff --git a/apps/server/scripts/cliErrors.test.ts b/apps/server/scripts/cliErrors.test.ts deleted file mode 100644 index 91754290db9a..000000000000 --- a/apps/server/scripts/cliErrors.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { assert, describe, it } from "@effect/vitest"; - -import { ServerCliBuildAssetMissingError, ServerCliCommandExitError } from "./cliErrors.ts"; - -describe("server CLI errors", () => { - it("preserves failed command context without changing its message", () => { - const error = new ServerCliCommandExitError({ - command: "vp", - args: ["pm", "publish"], - cwd: "/repo", - exitCode: 17, - }); - - assert.equal(error._tag, "ServerCliCommandExitError"); - assert.equal(error.command, "vp"); - assert.deepEqual(error.args, ["pm", "publish"]); - assert.equal(error.cwd, "/repo"); - assert.equal(error.exitCode, 17); - assert.equal(error.message, "Command exited with non-zero exit code (17)"); - }); - - it("preserves a representative missing asset path", () => { - const error = new ServerCliBuildAssetMissingError({ assetPath: "/repo/server.mjs" }); - - assert.equal(error.assetPath, "/repo/server.mjs"); - assert.equal( - error.message, - "Missing build asset: /repo/server.mjs. Run the build subcommand first.", - ); - }); -}); diff --git a/apps/server/src/checkpointing/Errors.test.ts b/apps/server/src/checkpointing/Errors.test.ts deleted file mode 100644 index 4c8b9c59cc31..000000000000 --- a/apps/server/src/checkpointing/Errors.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { expect, it } from "@effect/vitest"; -import { ThreadId } from "@t3tools/contracts"; - -import { - CheckpointRefUnavailableError, - CheckpointTurnRangeUnavailableError, - CheckpointWorkspacePathMissingError, -} from "./Errors.ts"; - -const threadId = ThreadId.make("thread-1"); - -it("derives checkpoint messages from structured context", () => { - const range = new CheckpointTurnRangeUnavailableError({ - operation: "CheckpointDiffQuery.getTurnDiff", - threadId, - requestedTurnCount: 4, - availableTurnCount: 2, - }); - const checkpoint = new CheckpointRefUnavailableError({ - operation: "CheckpointDiffQuery.getTurnDiff", - threadId, - turnCount: 2, - checkpoint: "to", - }); - const workspace = new CheckpointWorkspacePathMissingError({ - operation: "CheckpointDiffQuery.getFullThreadDiff", - threadId, - }); - - expect(range.message).toBe( - "Checkpoint unavailable for thread thread-1 turn 4: Turn diff range exceeds current turn count: requested 4, current 2.", - ); - expect(checkpoint.message).toBe( - "Checkpoint unavailable for thread thread-1 turn 2: Checkpoint ref is unavailable for turn 2.", - ); - expect(workspace.message).toBe( - "Checkpoint invariant violation in CheckpointDiffQuery.getFullThreadDiff: Workspace path missing for thread 'thread-1' when computing full thread diff.", - ); -}); diff --git a/apps/server/src/observability/Attributes.test.ts b/apps/server/src/observability/Attributes.test.ts deleted file mode 100644 index d9ed2e1271f6..000000000000 --- a/apps/server/src/observability/Attributes.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { assert, describe, it } from "@effect/vitest"; - -import { normalizeModelMetricLabel } from "./Attributes.ts"; - -describe("Attributes", () => { - it("groups GPT-family models under a shared metric label", () => { - assert.strictEqual(normalizeModelMetricLabel("gpt-4o"), "gpt"); - assert.strictEqual(normalizeModelMetricLabel("gpt-5.4"), "gpt"); - assert.strictEqual(normalizeModelMetricLabel("claude-sonnet-4"), "claude"); - }); -}); diff --git a/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts b/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts index b15d2f679ee4..d27caed4a8e2 100644 --- a/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts +++ b/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts @@ -1255,6 +1255,77 @@ it.layer(Layer.fresh(makeProjectionPipelinePrefixedTestLayer("t3-projection-atta ); it.layer(BaseTestLayer)("OrchestrationProjectionPipeline", (it) => { + it.effect("replays a bootstrap backlog larger than the event store default limit", () => + Effect.gen(function* () { + const projectionPipeline = yield* OrchestrationProjectionPipeline; + const eventStore = yield* OrchestrationEventStore; + const sql = yield* SqlClient.SqlClient; + const now = "2026-01-01T00:00:00.000Z"; + const projectId = ProjectId.make("project-bootstrap-backlog"); + + const sequenceRows = yield* sql<{ readonly maxSequence: number | null }>` + SELECT MAX(sequence) AS "maxSequence" FROM orchestration_events + `; + const sequenceBeforeBacklog = sequenceRows[0]?.maxSequence ?? 0; + const appendedEvents = yield* Effect.forEach( + Array.from({ length: 1_001 }, (_, index) => index), + (index) => { + const eventId = EventId.make(`evt-bootstrap-backlog-${index}`); + const commandId = CommandId.make(`cmd-bootstrap-backlog-${index}`); + return eventStore.append({ + type: "project.created", + eventId, + aggregateKind: "project", + aggregateId: projectId, + occurredAt: now, + commandId, + causationEventId: null, + correlationId: CorrelationId.make(commandId), + metadata: {}, + payload: { + projectId, + title: `Bootstrap backlog ${index}`, + workspaceRoot: "/tmp/project-bootstrap-backlog", + defaultModelSelection: null, + scripts: [], + createdAt: now, + updatedAt: now, + }, + }); + }, + ); + const lastSequence = appendedEvents[appendedEvents.length - 1]!.sequence; + + yield* Effect.forEach( + Object.values(ORCHESTRATION_PROJECTOR_NAMES), + (projector) => { + const lastAppliedSequence = + projector === ORCHESTRATION_PROJECTOR_NAMES.projects + ? sequenceBeforeBacklog + : lastSequence; + return sql` + INSERT INTO projection_state (projector, last_applied_sequence, updated_at) + VALUES (${projector}, ${lastAppliedSequence}, ${now}) + ON CONFLICT (projector) + DO UPDATE SET + last_applied_sequence = excluded.last_applied_sequence, + updated_at = excluded.updated_at + `; + }, + { discard: true }, + ); + + yield* projectionPipeline.bootstrap; + + const stateRows = yield* sql<{ readonly lastAppliedSequence: number }>` + SELECT last_applied_sequence AS "lastAppliedSequence" + FROM projection_state + WHERE projector = ${ORCHESTRATION_PROJECTOR_NAMES.projects} + `; + assert.deepEqual(stateRows, [{ lastAppliedSequence: lastSequence }]); + }), + ); + it.effect("resumes from projector last_applied_sequence without replaying older events", () => Effect.gen(function* () { const projectionPipeline = yield* OrchestrationProjectionPipeline; diff --git a/apps/server/src/orchestration/Layers/ProjectionPipeline.ts b/apps/server/src/orchestration/Layers/ProjectionPipeline.ts index e048826b9cce..348615b1033b 100644 --- a/apps/server/src/orchestration/Layers/ProjectionPipeline.ts +++ b/apps/server/src/orchestration/Layers/ProjectionPipeline.ts @@ -1727,6 +1727,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti Stream.runForEach( eventStore.readFromSequence( Option.isSome(stateRow) ? stateRow.value.lastAppliedSequence : 0, + Number.MAX_SAFE_INTEGER, ), (event) => runProjectorForEvent(projector, event), ), diff --git a/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts b/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts index a22a7acfb705..a3588244d827 100644 --- a/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts +++ b/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts @@ -2970,15 +2970,15 @@ describe("ProviderCommandReactor", () => { }); }); - it("surfaces stale provider approval request failures without faking approval resolution", async () => { + it("normalizes stale Codex approval callbacks without faking approval resolution", async () => { const harness = await createHarness(); const now = "2026-01-01T00:00:00.000Z"; harness.respondToRequest.mockImplementation(() => Effect.fail( new ProviderAdapterRequestError({ provider: ProviderDriverKind.make("codex"), - method: "session/request_permission", - detail: "Unknown pending permission request: approval-request-1", + method: "item/requestApproval/decision", + detail: "Unknown pending Codex approval request: approval-request-1", }), ), ); diff --git a/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts b/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts index 1c0091028add..812893d8c843 100644 --- a/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts +++ b/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts @@ -241,13 +241,15 @@ function isUnknownPendingApprovalRequestError(cause: Cause.Cause = { const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; const httpClient = yield* HttpClient.HttpClient; const serverSettings = yield* ServerSettingsService; + const { cwd } = yield* ServerConfig; const eventLoggers = yield* ProviderEventLoggers; const processEnv = mergeProviderInstanceEnvironment(environment); const continuationIdentity = defaultProviderContinuationIdentity({ @@ -99,7 +100,7 @@ export const GrokDriver: ProviderDriver = { }); const textGeneration = yield* makeGrokTextGeneration(effectiveConfig, processEnv); - const checkProvider = checkGrokProviderStatus(effectiveConfig, processEnv).pipe( + const checkProvider = checkGrokProviderStatus(effectiveConfig, processEnv, cwd).pipe( Effect.map(stampIdentity), Effect.provideService(Crypto.Crypto, crypto), Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), diff --git a/apps/server/src/provider/Drivers/GrokSkills.test.ts b/apps/server/src/provider/Drivers/GrokSkills.test.ts new file mode 100644 index 000000000000..3536a37a9920 --- /dev/null +++ b/apps/server/src/provider/Drivers/GrokSkills.test.ts @@ -0,0 +1,135 @@ +import { describe, expect, it } from "@effect/vitest"; +import * as Effect from "effect/Effect"; +import * as Layer from "effect/Layer"; +import * as Sink from "effect/Sink"; +import * as Stream from "effect/Stream"; +import { ChildProcessSpawner } from "effect/unstable/process"; + +import { discoverGrokSkills, parseGrokInspectSkills } from "./GrokSkills.ts"; + +const inspectPayload = (skills: ReadonlyArray) => JSON.stringify({ skills }); + +describe("parseGrokInspectSkills", () => { + it("maps inspect entries onto provider skills, sorted by name", () => { + const skills = parseGrokInspectSkills( + inspectPayload([ + { + name: "writing-docs", + description: "Write user docs.", + source: { type: "user", path: "/home/dev/.grok/skills/writing-docs/SKILL.md" }, + userInvocable: true, + }, + { + name: "deploy", + description: "Deploy the app.", + source: { + type: "plugin", + path: "/home/dev/.grok/installed-plugins/pkg/plug/skills/deploy/SKILL.md", + }, + userInvocable: true, + }, + ]), + ); + + expect(skills).toEqual([ + { + name: "deploy", + description: "Deploy the app.", + path: "/home/dev/.grok/installed-plugins/pkg/plug/skills/deploy/SKILL.md", + scope: "plugin", + enabled: true, + }, + { + name: "writing-docs", + description: "Write user docs.", + path: "/home/dev/.grok/skills/writing-docs/SKILL.md", + scope: "user", + enabled: true, + }, + ]); + }); + + it("disables skills the CLI marks as not user-invocable", () => { + const skills = parseGrokInspectSkills( + inspectPayload([ + { + name: "internal-helper", + source: { type: "bundled", path: "/opt/grok/bundled/skills/internal-helper/SKILL.md" }, + userInvocable: false, + }, + ]), + ); + + expect(skills).toEqual([ + { + name: "internal-helper", + path: "/opt/grok/bundled/skills/internal-helper/SKILL.md", + scope: "bundled", + enabled: false, + }, + ]); + }); + + it("skips entries without a name or a filesystem path", () => { + const skills = parseGrokInspectSkills( + inspectPayload([ + { name: " ", source: { type: "user", path: "/tmp/skills/a/SKILL.md" } }, + { name: "no-path", source: { type: "user" } }, + { name: "no-source" }, + "not-an-object", + { name: "kept", source: { type: "project", path: "/repo/.grok/skills/kept/SKILL.md" } }, + ]), + ); + + expect(skills.map((skill) => skill.name)).toEqual(["kept"]); + }); + + it("returns an empty list for malformed or unexpected output", () => { + expect(parseGrokInspectSkills("not json")).toEqual([]); + expect(parseGrokInspectSkills("null")).toEqual([]); + expect(parseGrokInspectSkills(JSON.stringify({ skills: "nope" }))).toEqual([]); + expect(parseGrokInspectSkills(JSON.stringify({}))).toEqual([]); + }); +}); + +describe("discoverGrokSkills", () => { + it.effect("spawns the inspect probe in the configured cwd", () => { + const spawnCwds: Array = []; + const spawner = ChildProcessSpawner.make((command) => { + spawnCwds.push(command._tag === "StandardCommand" ? command.options.cwd : undefined); + return Effect.succeed( + ChildProcessSpawner.makeHandle({ + pid: ChildProcessSpawner.ProcessId(1), + exitCode: Effect.succeed(ChildProcessSpawner.ExitCode(0)), + isRunning: Effect.succeed(false), + kill: () => Effect.void, + unref: Effect.succeed(Effect.void), + stdin: Sink.drain, + stdout: Stream.encodeText( + Stream.make( + inspectPayload([ + { + name: "kept", + source: { type: "project", path: "/workspaces/demo/.grok/skills/kept/SKILL.md" }, + }, + ]), + ), + ), + stderr: Stream.empty, + all: Stream.empty, + getInputFd: () => Sink.drain, + getOutputFd: () => Stream.empty, + }), + ); + }); + + return Effect.gen(function* () { + const skills = yield* discoverGrokSkills({ binaryPath: "grok" }, {}, "/workspaces/demo").pipe( + Effect.provide(Layer.succeed(ChildProcessSpawner.ChildProcessSpawner, spawner)), + ); + + expect(spawnCwds).toEqual(["/workspaces/demo"]); + expect(skills.map((skill) => skill.name)).toEqual(["kept"]); + }); + }); +}); diff --git a/apps/server/src/provider/Drivers/GrokSkills.ts b/apps/server/src/provider/Drivers/GrokSkills.ts new file mode 100644 index 000000000000..a7c2c2ae3028 --- /dev/null +++ b/apps/server/src/provider/Drivers/GrokSkills.ts @@ -0,0 +1,119 @@ +/** + * GrokSkills — skill discovery for the `$` picker via `grok inspect --json`. + * + * Unlike Claude Code, the Grok CLI reports its full skill catalog itself: + * `grok inspect --json` returns `skills[]` with `name`, `description`, + * `source.type` (`user` / `project` / `bundled` / `plugin`), `source.path` + * (the absolute `SKILL.md` path), and `userInvocable`. Asking the CLI beats + * scanning the filesystem because the catalog honors Grok's own skill config + * (ignore lists, disabled skills) and includes plugin skills, which live + * three levels deep under `~/.grok/installed-plugins/` where a flat scan + * cannot see them. This mirrors how the Codex app-server reports skills over + * `skills/list`. Discovery is best-effort: an older CLI without `inspect`, + * a timeout, or malformed output yields an empty list, never a degraded + * provider snapshot. + * + * @module provider/Drivers/GrokSkills + */ +import type { GrokSettings, ServerProviderSkill } from "@t3tools/contracts"; +import * as Effect from "effect/Effect"; +import * as Option from "effect/Option"; +import * as Result from "effect/Result"; +import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"; +import { resolveSpawnCommand } from "@t3tools/shared/shell"; + +import { spawnAndCollect } from "../providerSnapshot.ts"; + +const GROK_SKILLS_PROBE_TIMEOUT_MS = 4_000; + +/** + * Map `grok inspect --json` output onto provider skills. Entries without a + * name or a filesystem path are skipped; `userInvocable: false` skills are + * kept but disabled so pickers that filter on `enabled` hide them. + */ +export function parseGrokInspectSkills(stdout: string): ReadonlyArray { + let parsed: unknown; + try { + parsed = JSON.parse(stdout); + } catch { + return []; + } + if (typeof parsed !== "object" || parsed === null) { + return []; + } + const entries = (parsed as Record).skills; + if (!Array.isArray(entries)) { + return []; + } + + const skillsByName = new Map(); + for (const entry of entries) { + if (typeof entry !== "object" || entry === null) { + continue; + } + const record = entry as Record; + const name = typeof record.name === "string" ? record.name.trim() : ""; + const source = + typeof record.source === "object" && record.source !== null + ? (record.source as Record) + : undefined; + const path = typeof source?.path === "string" ? source.path.trim() : ""; + if (!name || !path) { + continue; + } + const scope = typeof source?.type === "string" ? source.type.trim() : ""; + const description = typeof record.description === "string" ? record.description.trim() : ""; + skillsByName.set(name, { + name, + path, + enabled: record.userInvocable !== false, + ...(scope ? { scope } : {}), + ...(description ? { description } : {}), + }); + } + + return [...skillsByName.values()].sort((left, right) => left.name.localeCompare(right.name)); +} + +/** + * Run `grok inspect --json` and map the reported catalog onto provider + * skills. Never fails: any spawn error, non-zero exit, or timeout resolves + * to an empty list. + */ +export const discoverGrokSkills = Effect.fn("discoverGrokSkills")(function* ( + grokSettings: Pick, + environment: NodeJS.ProcessEnv = process.env, + cwd?: string, +): Effect.fn.Return< + ReadonlyArray, + never, + ChildProcessSpawner.ChildProcessSpawner +> { + const command = grokSettings.binaryPath || "grok"; + const inspectResult = yield* Effect.gen(function* () { + const spawnCommand = yield* resolveSpawnCommand(command, ["inspect", "--json"], { + env: environment, + }); + return yield* spawnAndCollect( + command, + ChildProcess.make(spawnCommand.command, spawnCommand.args, { + ...(cwd ? { cwd } : {}), + env: environment, + shell: spawnCommand.shell, + }), + ); + }).pipe(Effect.timeoutOption(GROK_SKILLS_PROBE_TIMEOUT_MS), Effect.result); + + if (Result.isFailure(inspectResult) || Option.isNone(inspectResult.success)) { + yield* Effect.logDebug("Grok skill discovery failed; continuing without skills."); + return []; + } + const output = inspectResult.success.value; + if (output.code !== 0) { + yield* Effect.logDebug("Grok skill discovery exited non-zero; continuing without skills.", { + exitCode: output.code, + }); + return []; + } + return parseGrokInspectSkills(output.stdout); +}); diff --git a/apps/server/src/provider/Layers/GrokAdapter.test.ts b/apps/server/src/provider/Layers/GrokAdapter.test.ts index 6cb71660a74c..eeee17d9ac6a 100644 --- a/apps/server/src/provider/Layers/GrokAdapter.test.ts +++ b/apps/server/src/provider/Layers/GrokAdapter.test.ts @@ -26,7 +26,13 @@ import { } from "@t3tools/contracts"; import { ServerConfig } from "../../config.ts"; -import { grokPromptSettlementBelongsToContext, makeGrokAdapter } from "./GrokAdapter.ts"; +import { + grokPromptSettlementBelongsToContext, + isGrokEnterPlanModeToolCall, + makeGrokAdapter, + nextGrokPlanModeActive, + selectGrokPermissionOptionId, +} from "./GrokAdapter.ts"; const decodeGrokSettings = Schema.decodeSync(GrokSettings); const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url)); @@ -89,6 +95,90 @@ const grokAdapterTestLayer = ServerConfig.layerTest(process.cwd(), { const makeTestAdapter = (binaryPath: string, options?: Parameters[1]) => makeGrokAdapter(decodeGrokSettings({ binaryPath }), options).pipe(Effect.orDie); +it("detects enter_plan_mode tool calls from title and rawInput", () => { + assert.isTrue( + isGrokEnterPlanModeToolCall({ + title: "enter_plan_mode", + data: { toolCallId: "1" }, + }), + ); + assert.isTrue( + isGrokEnterPlanModeToolCall({ + title: "Plan mode entered", + data: { toolCallId: "1", rawInput: { variant: "EnterPlanMode" } }, + }), + ); + assert.isFalse( + isGrokEnterPlanModeToolCall({ + title: "write", + data: { toolCallId: "1", rawInput: { file_path: "/tmp/x", content: "y" } }, + }), + ); +}); + +it("only sets planModeActive after a successful enter_plan_mode", () => { + const enter = { + title: "enter_plan_mode", + data: { toolCallId: "1" }, + }; + assert.isFalse(nextGrokPlanModeActive(false, { ...enter, status: "pending" })); + assert.isTrue(nextGrokPlanModeActive(false, { ...enter, status: "inProgress" })); + assert.isTrue(nextGrokPlanModeActive(false, { ...enter, status: "completed" })); + assert.isFalse(nextGrokPlanModeActive(false, { ...enter, status: "failed" })); + assert.isFalse(nextGrokPlanModeActive(true, { ...enter, status: "failed" })); + assert.isTrue( + nextGrokPlanModeActive(true, { + title: "write", + status: "completed", + data: { toolCallId: "2" }, + }), + ); +}); + +function grokPermissionRequest( + options: ReadonlyArray<{ + readonly optionId: string; + readonly kind: "allow_once" | "allow_always" | "reject_once" | "reject_always"; + }>, +) { + return { + sessionId: "mock-session-1", + toolCall: { + toolCallId: "tool-call-1", + title: "cat package.json", + kind: "execute" as const, + status: "pending" as const, + }, + options: options.map((option) => ({ + optionId: option.optionId, + name: option.kind, + kind: option.kind, + })), + }; +} + +it("maps Always allow to allow_once when Grok omits allow_always", () => { + const request = grokPermissionRequest([ + { optionId: "allow-once", kind: "allow_once" }, + { optionId: "reject-once", kind: "reject_once" }, + ]); + + assert.equal(selectGrokPermissionOptionId(request, "acceptForSession"), "allow-once"); + assert.equal(selectGrokPermissionOptionId(request, "accept"), "allow-once"); + assert.equal(selectGrokPermissionOptionId(request, "decline"), "reject-once"); +}); + +it("prefers allow_always when Grok offers it", () => { + const request = grokPermissionRequest([ + { optionId: "allow-once", kind: "allow_once" }, + { optionId: "allow-always", kind: "allow_always" }, + { optionId: "reject-once", kind: "reject_once" }, + ]); + + assert.equal(selectGrokPermissionOptionId(request, "acceptForSession"), "allow-always"); + assert.equal(selectGrokPermissionOptionId(request, "accept"), "allow-once"); +}); + it("requires a settlement to match the live Grok turn", () => { const staleTurnId = TurnId.make("stale-turn"); const replacementTurnId = TurnId.make("replacement-turn"); @@ -418,6 +508,362 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { }), ); + it.effect("does not time out a Grok turn before ACP emits progress", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-watchdog-silent-turn"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_HANG_PROMPT_FOREVER: "1", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + turnInactivityTimeoutMs: 1_000, + }); + const runtimeEvents: ProviderRuntimeEvent[] = []; + const turnStarted = yield* Deferred.make(); + const turnCompleted = + yield* Deferred.make>(); + const runtimeEventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + Effect.gen(function* () { + if (String(event.threadId) !== String(threadId)) { + return; + } + runtimeEvents.push(event); + if (event.type === "turn.started") { + yield* Deferred.succeed(turnStarted, undefined).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + yield* Deferred.succeed(turnCompleted, event).pipe(Effect.ignore); + } + }), + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + + const sendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "silence forever", attachments: [] }) + .pipe(Effect.forkChild); + yield* Deferred.await(turnStarted); + + yield* TestClock.adjust("5 seconds"); + yield* Effect.yieldNow; + const steerSendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "keep reasoning", attachments: [] }) + .pipe(Effect.forkChild); + for (let yieldAttempt = 0; yieldAttempt < 12; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + yield* TestClock.adjust("5 seconds"); + yield* Effect.yieldNow; + assert.lengthOf( + runtimeEvents.filter( + (event) => event.type === "turn.completed" && String(event.threadId) === String(threadId), + ), + 0, + ); + + yield* adapter.interruptTurn(threadId); + const completed = yield* Deferred.await(turnCompleted).pipe( + Effect.timeout("2 seconds"), + TestClock.withLive, + ); + yield* Fiber.join(sendTurnFiber); + yield* Fiber.interrupt(steerSendTurnFiber); + + assert.equal(completed.payload.state, "cancelled"); + const session = (yield* adapter.listSessions()).find( + (candidate) => candidate.threadId === threadId, + ); + assert.equal(session?.status, "ready"); + assert.isUndefined(session?.activeTurnId); + + yield* Fiber.interrupt(runtimeEventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("fails a Grok turn that stalls after ACP content begins", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-watchdog-content-stall"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_CONTENT_THEN_HANG: "1", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + turnInactivityTimeoutMs: 1_000, + }); + const contentDelta = yield* Deferred.make(); + const turnCompleted = + yield* Deferred.make>(); + const runtimeEvents: ProviderRuntimeEvent[] = []; + const runtimeEventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + Effect.gen(function* () { + if (String(event.threadId) !== String(threadId)) { + return; + } + runtimeEvents.push(event); + if (event.type === "content.delta") { + yield* Deferred.succeed(contentDelta, undefined).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + yield* Deferred.succeed(turnCompleted, event).pipe(Effect.ignore); + } + }), + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + const sendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "start then stall", attachments: [] }) + .pipe(Effect.forkChild); + yield* Deferred.await(contentDelta).pipe(Effect.timeout("2 seconds"), TestClock.withLive); + + yield* TestClock.adjust("999 millis"); + yield* Effect.yieldNow; + assert.lengthOf( + runtimeEvents.filter( + (event) => event.type === "turn.completed" && String(event.threadId) === String(threadId), + ), + 0, + ); + + yield* TestClock.adjust("1 millis"); + for (let yieldAttempt = 0; yieldAttempt < 4; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + const completed = yield* Deferred.await(turnCompleted).pipe( + Effect.timeout("2 seconds"), + TestClock.withLive, + ); + yield* Fiber.join(sendTurnFiber); + + assert.equal(completed.payload.state, "failed"); + assert.equal( + runtimeEvents.filter( + (event) => event.type === "turn.completed" && String(event.threadId) === String(threadId), + ).length, + 1, + ); + + yield* Fiber.interrupt(runtimeEventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("refreshes Grok liveness when a turn is steered", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-watchdog-steer"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_CONTENT_THEN_HANG: "1", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + turnInactivityTimeoutMs: 1_000, + }); + const contentDelta = yield* Deferred.make(); + const turnCompleted = + yield* Deferred.make>(); + const runtimeEvents: ProviderRuntimeEvent[] = []; + const runtimeEventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + Effect.gen(function* () { + if (String(event.threadId) !== String(threadId)) { + return; + } + runtimeEvents.push(event); + if (event.type === "content.delta") { + yield* Deferred.succeed(contentDelta, undefined).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + yield* Deferred.succeed(turnCompleted, event).pipe(Effect.ignore); + } + }), + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + const firstSendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "start then steer", attachments: [] }) + .pipe(Effect.forkChild); + yield* Deferred.await(contentDelta).pipe(Effect.timeout("2 seconds"), TestClock.withLive); + + yield* TestClock.adjust("999 millis"); + const steerSendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "continue working", attachments: [] }) + .pipe(Effect.forkChild); + for (let yieldAttempt = 0; yieldAttempt < 12; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + + yield* TestClock.adjust("1 millis"); + for (let yieldAttempt = 0; yieldAttempt < 4; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + assert.lengthOf( + runtimeEvents.filter( + (event) => event.type === "turn.completed" && String(event.threadId) === String(threadId), + ), + 0, + ); + + yield* Fiber.interrupt(steerSendTurnFiber); + yield* adapter.interruptTurn(threadId); + const completed = yield* Deferred.await(turnCompleted).pipe( + Effect.timeout("2 seconds"), + TestClock.withLive, + ); + yield* Fiber.join(firstSendTurnFiber); + assert.equal(completed.payload.state, "cancelled"); + + yield* Fiber.interrupt(runtimeEventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("refreshes Grok liveness when ACP updates its plan", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-watchdog-plan-stall"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_PLAN_THEN_HANG: "1", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + turnInactivityTimeoutMs: 1_000, + }); + const planUpdated = yield* Deferred.make(); + const turnCompleted = + yield* Deferred.make>(); + const runtimeEventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + Effect.gen(function* () { + if (String(event.threadId) !== String(threadId)) { + return; + } + if (event.type === "turn.plan.updated") { + yield* Deferred.succeed(planUpdated, undefined).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + yield* Deferred.succeed(turnCompleted, event).pipe(Effect.ignore); + } + }), + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + const sendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "update plan then stall", attachments: [] }) + .pipe(Effect.forkChild); + yield* Deferred.await(planUpdated).pipe(Effect.timeout("2 seconds"), TestClock.withLive); + + yield* TestClock.adjust("1 second"); + for (let yieldAttempt = 0; yieldAttempt < 4; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + const completed = yield* Deferred.await(turnCompleted).pipe( + Effect.timeout("2 seconds"), + TestClock.withLive, + ); + yield* Fiber.join(sendTurnFiber); + + assert.equal(completed.payload.state, "failed"); + yield* Fiber.interrupt(runtimeEventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("settles a stalled Grok turn after the active-tool deadline", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-watchdog-active-tool"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_ACTIVE_TOOL_THEN_HANG: "1", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + turnInactivityTimeoutMs: 1_000, + activeToolInactivityTimeoutMs: 5_000, + }); + const activeTool = yield* Deferred.make(); + const turnCompleted = + yield* Deferred.make>(); + const runtimeEvents: ProviderRuntimeEvent[] = []; + const runtimeEventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + Effect.gen(function* () { + if (String(event.threadId) !== String(threadId)) { + return; + } + runtimeEvents.push(event); + if (event.type === "item.updated") { + yield* Deferred.succeed(activeTool, undefined).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + yield* Deferred.succeed(turnCompleted, event).pipe(Effect.ignore); + } + }), + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + const sendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "run a long tool", attachments: [] }) + .pipe(Effect.forkChild); + yield* Deferred.await(activeTool).pipe(Effect.timeout("2 seconds"), TestClock.withLive); + for (let yieldAttempt = 0; yieldAttempt < 4; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + + yield* TestClock.adjust("4999 millis"); + yield* Effect.yieldNow; + assert.lengthOf( + runtimeEvents.filter( + (event) => event.type === "turn.completed" && String(event.threadId) === String(threadId), + ), + 0, + ); + assert.equal( + (yield* adapter.listSessions()).find((candidate) => candidate.threadId === threadId) + ?.status, + "running", + ); + + yield* TestClock.adjust("1 millis"); + for (let yieldAttempt = 0; yieldAttempt < 4; yieldAttempt += 1) { + yield* Effect.yieldNow; + } + const completed = yield* Deferred.await(turnCompleted).pipe( + Effect.timeout("2 seconds"), + TestClock.withLive, + ); + yield* Fiber.join(sendTurnFiber); + assert.equal(completed.payload.state, "failed"); + + yield* Fiber.interrupt(runtimeEventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + it.effect("retains turn transcript when sendTurn is interrupted after prompt success", () => Effect.gen(function* () { const threadId = ThreadId.make("grok-send-turn-interrupt-after-prompt"); @@ -943,6 +1389,64 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { }), ); + it.effect("surfaces Grok usage limits without clearing the selected model", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-usage-limit-error"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG: "1", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath); + const runtimeEvents: ProviderRuntimeEvent[] = []; + const runtimeEventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + Effect.sync(() => { + runtimeEvents.push(event); + }), + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + modelSelection: { instanceId: ProviderInstanceId.make("grok"), model: "grok-build" }, + }); + + const error = yield* Effect.flip( + adapter.sendTurn({ + threadId, + input: "hit the usage limit", + attachments: [], + }), + ); + const readySessions = yield* adapter.listSessions(); + const readySession = readySessions.find((session) => session.threadId === threadId); + const terminalEvents = runtimeEvents.filter( + (event) => event.type === "turn.completed" && event.threadId === threadId, + ); + + assert.equal(error._tag, "ProviderAdapterRequestError"); + assert.include(error.message, "Grok usage limit reached. Try again later."); + assert.equal(readySession?.status, "ready"); + assert.equal(readySession?.model, "grok-build"); + assert.isUndefined(readySession?.activeTurnId); + assert.lengthOf(terminalEvents, 1); + const [terminalEvent] = terminalEvents; + assert.equal(terminalEvent?.type, "turn.completed"); + if (terminalEvent?.type === "turn.completed") { + assert.equal(terminalEvent.payload.state, "failed"); + assert.include( + terminalEvent.payload.errorMessage ?? "", + "Grok usage limit reached. Try again later.", + ); + } + + yield* Fiber.interrupt(runtimeEventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + it.effect("ignores replayed session/load updates when resuming a Grok session", () => Effect.gen(function* () { const threadId = ThreadId.make("grok-load-replay-filter"); @@ -1097,6 +1601,247 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { }), ); + it.effect("captures xAI exit_plan_mode as a proposed plan and unblocks the turn", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-xai-exit-plan-mode"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ T3_ACP_EMIT_XAI_EXIT_PLAN_MODE: "1" }), + ); + const adapter = yield* makeTestAdapter(wrapperPath); + const proposed = + yield* Deferred.make>(); + const turnCompleted = yield* Deferred.make(); + + const eventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => { + if (String(event.threadId) !== String(threadId)) { + return Effect.void; + } + if (event.type === "turn.proposed.completed") { + return Deferred.succeed(proposed, event).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + return Deferred.succeed(turnCompleted, undefined).pipe(Effect.ignore); + } + return Effect.void; + }).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + + yield* adapter.sendTurn({ threadId, input: "present the plan", attachments: [] }); + + const proposedEvent = yield* Deferred.await(proposed); + assert.equal(proposedEvent.type, "turn.proposed.completed"); + assert.equal(proposedEvent.payload.planMarkdown, "# Exit plan\n\n- Step one\n- Step two"); + assert.equal(proposedEvent.raw?.method, "_x.ai/exit_plan_mode"); + yield* Deferred.await(turnCompleted); + + yield* Fiber.interrupt(eventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("surfaces plan.md writes as a proposed plan while plan mode is active", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-xai-plan-md-write"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ T3_ACP_EMIT_XAI_PLAN_MD_WRITE: "1" }), + ); + const adapter = yield* makeTestAdapter(wrapperPath); + const proposed = + yield* Deferred.make>(); + + const eventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => { + if (String(event.threadId) !== String(threadId)) { + return Effect.void; + } + if (event.type === "turn.proposed.completed") { + return Deferred.succeed(proposed, event).pipe(Effect.ignore); + } + return Effect.void; + }).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + + yield* adapter.sendTurn({ threadId, input: "write the plan", attachments: [] }); + + const proposedEvent = yield* Deferred.await(proposed); + assert.equal( + proposedEvent.payload.planMarkdown, + "# Mock plan\n\n- Write the feature\n- Add a test\n- Ship it", + ); + assert.equal(proposedEvent.raw?.method, "session/update"); + + yield* Fiber.interrupt(eventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("keeps a Grok turn running when Always allow has no allow_always option", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-always-allow-without-allow-always"); + const tempDir = yield* Effect.promise(() => + NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "grok-acp-")), + ); + const requestLogPath = NodePath.join(tempDir, "requests.ndjson"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_REQUEST_LOG_PATH: requestLogPath, + T3_ACP_EMIT_TOOL_CALLS: "1", + T3_ACP_OMIT_ALLOW_ALWAYS: "1", + T3_ACP_PERMISSION_REQUEST_COUNT: "2", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath); + const openedCount = yield* Ref.make(0); + const eventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + event.type === "request.opened" + ? Effect.gen(function* () { + yield* Ref.update(openedCount, (count) => count + 1); + yield* adapter.respondToRequest( + threadId, + ApprovalRequestId.make(String(event.requestId)), + "acceptForSession", + ); + }) + : Effect.void, + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "approval-required", + }); + yield* adapter.sendTurn({ + threadId, + input: "approve this session", + attachments: [], + }); + + assert.equal(yield* Ref.get(openedCount), 1); + + const requests = yield* Effect.promise(() => readJsonLines(requestLogPath)); + const permissionResults = requests.filter( + (entry) => + !("method" in entry) && + typeof entry.result === "object" && + entry.result !== null && + "outcome" in entry.result && + typeof entry.result.outcome === "object" && + entry.result.outcome !== null && + "optionId" in entry.result.outcome, + ); + assert.equal(permissionResults.length, 2); + assert.isTrue( + permissionResults.every( + (entry) => + typeof entry.result === "object" && + entry.result !== null && + "outcome" in entry.result && + typeof entry.result.outcome === "object" && + entry.result.outcome !== null && + "optionId" in entry.result.outcome && + entry.result.outcome.optionId === "allow-once", + ), + ); + + yield* Fiber.interrupt(eventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("asks before a different command after Always allow this session", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-session-approval-scope"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_TOOL_CALLS: "1", + T3_ACP_OMIT_ALLOW_ALWAYS: "1", + T3_ACP_PERMISSION_REQUEST_COUNT: "2", + T3_ACP_PERMISSION_TITLE: "Terminal", + T3_ACP_SECOND_PERMISSION_COMMAND: "rm server/package.json", + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath); + const openedCount = yield* Ref.make(0); + const eventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => + event.type === "request.opened" + ? Effect.gen(function* () { + const count = yield* Ref.updateAndGet(openedCount, (value) => value + 1); + yield* adapter.respondToRequest( + threadId, + ApprovalRequestId.make(String(event.requestId)), + count === 1 ? "acceptForSession" : "decline", + ); + }) + : Effect.void, + ).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "approval-required", + }); + yield* adapter.sendTurn({ threadId, input: "check approval scope", attachments: [] }); + assert.equal(yield* Ref.get(openedCount), 2); + yield* Fiber.interrupt(eventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + + it.effect("captures a plan under the provider instance GROK_HOME", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-instance-plan-home"); + const grokHome = yield* Effect.promise(() => + NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "grok-instance-home-")), + ); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ + T3_ACP_EMIT_XAI_PLAN_MD_WRITE: "1", + T3_ACP_PLAN_ROOT: grokHome, + }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + environment: { ...process.env, GROK_HOME: grokHome }, + }); + const plans = yield* Ref.make>([]); + const completed = yield* Deferred.make(); + const eventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => { + if (event.type === "turn.proposed.completed") { + return Ref.update(plans, (current) => [...current, event.payload.planMarkdown]); + } + return event.type === "turn.completed" + ? Deferred.succeed(completed, undefined).pipe(Effect.asVoid) + : Effect.void; + }).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + yield* adapter.sendTurn({ threadId, input: "write the plan", attachments: [] }); + yield* Deferred.await(completed); + assert.deepEqual(yield* Ref.get(plans), [ + "# Mock plan\n\n- Write the feature\n- Add a test\n- Ship it", + ]); + yield* Fiber.interrupt(eventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + it.effect("handles xAI ask_user_question extension requests", () => Effect.gen(function* () { const threadId = ThreadId.make("grok-xai-ask-user-question"); @@ -1159,6 +1904,82 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { }), ); + it.effect("settles a stalled Grok turn after its first activity is user input", () => + Effect.gen(function* () { + const threadId = ThreadId.make("grok-xai-ask-user-question"); + const wrapperPath = yield* Effect.promise(() => + makeMockGrokWrapper({ T3_ACP_EMIT_XAI_ASK_USER_QUESTION_THEN_HANG: "1" }), + ); + const adapter = yield* makeTestAdapter(wrapperPath, { + turnInactivityTimeoutMs: 1_000, + }); + const requested = + yield* Deferred.make>(); + const resolved = + yield* Deferred.make>(); + const completed = + yield* Deferred.make>(); + + const eventsFiber = yield* Stream.runForEach(adapter.streamEvents, (event) => { + if (String(event.threadId) !== String(threadId)) { + return Effect.void; + } + if (event.type === "user-input.requested") { + return Deferred.succeed(requested, event).pipe(Effect.ignore); + } + if (event.type === "user-input.resolved") { + return Deferred.succeed(resolved, event).pipe(Effect.ignore); + } + if (event.type === "turn.completed") { + return Deferred.succeed(completed, event).pipe(Effect.ignore); + } + return Effect.void; + }).pipe(Effect.forkChild); + + yield* adapter.startSession({ + threadId, + provider: ProviderDriverKind.make("grok"), + cwd: process.cwd(), + runtimeMode: "full-access", + }); + + const sendTurnFiber = yield* adapter + .sendTurn({ threadId, input: "ask before continuing", attachments: [] }) + .pipe(Effect.forkChild); + + const requestedEvent = yield* Deferred.await(requested); + assert.equal(requestedEvent.payload.questions.length, 1); + assert.equal(requestedEvent.payload.questions[0]?.id, "Which scope should Grok use?"); + assert.equal(requestedEvent.payload.questions[0]?.question, "Which scope should Grok use?"); + assert.equal(requestedEvent.raw?.method, "_x.ai/ask_user_question"); + + yield* adapter.respondToUserInput( + threadId, + ApprovalRequestId.make(String(requestedEvent.requestId)), + { + "Which scope should Grok use?": "Workspace", + }, + ); + + const resolvedEvent = yield* Deferred.await(resolved); + assert.deepEqual(resolvedEvent.payload.answers, { + "Which scope should Grok use?": "Workspace", + }); + assert.equal(String(resolvedEvent.turnId), String(requestedEvent.turnId)); + + yield* TestClock.adjust("1 second"); + const completedEvent = yield* Deferred.await(completed).pipe( + Effect.timeout("2 seconds"), + TestClock.withLive, + ); + assert.equal(completedEvent.payload.state, "failed"); + yield* Fiber.join(sendTurnFiber); + + yield* Fiber.interrupt(eventsFiber); + yield* adapter.stopSession(threadId); + }), + ); + it.effect("continues streaming events when native notification logging fails", () => Effect.gen(function* () { const threadId = ThreadId.make("grok-native-log-failure"); diff --git a/apps/server/src/provider/Layers/GrokAdapter.ts b/apps/server/src/provider/Layers/GrokAdapter.ts index 858d862e6d5f..d0b704b93d15 100644 --- a/apps/server/src/provider/Layers/GrokAdapter.ts +++ b/apps/server/src/provider/Layers/GrokAdapter.ts @@ -12,9 +12,14 @@ import { type ThreadId, TurnId, } from "@t3tools/contracts"; +import { HostProcessEnvironment, HostProcessPlatform } from "@t3tools/shared/hostProcess"; +import { getModelSelectionStringOptionValue } from "@t3tools/shared/model"; +import { stableStringify } from "@t3tools/shared/relaySigning"; +import * as Clock from "effect/Clock"; import * as Crypto from "effect/Crypto"; import * as DateTime from "effect/DateTime"; import * as Deferred from "effect/Deferred"; +import * as Duration from "effect/Duration"; import * as Effect from "effect/Effect"; import * as Exit from "effect/Exit"; import * as Fiber from "effect/Fiber"; @@ -22,6 +27,7 @@ import * as FileSystem from "effect/FileSystem"; import * as Option from "effect/Option"; import * as Path from "effect/Path"; import * as PubSub from "effect/PubSub"; +import * as Queue from "effect/Queue"; import * as Ref from "effect/Ref"; import * as Schema from "effect/Schema"; import * as Scope from "effect/Scope"; @@ -56,15 +62,21 @@ import { makeAcpNativeLoggerFactory } from "../acp/AcpNativeLogging.ts"; import { applyGrokAcpModelSelection, currentGrokModelIdFromSessionSetup, + currentGrokReasoningEffortFromSessionSetup, makeGrokAcpRuntime, + normalizeGrokReasoningEffort, resolveGrokAcpBaseModelId, } from "../acp/GrokAcpSupport.ts"; import { + extractGrokPlanMarkdownFromToolCallData, extractXAiAskUserQuestions, + extractXAiExitPlanMarkdown, makeXAiAskUserQuestionCancelledResponse, makeXAiAskUserQuestionResponse, + makeXAiExitPlanModeCapturedResponse, promptResponseHasMissingXAiStopReason, XAiAskUserQuestionRequest, + XAiExitPlanModeRequest, } from "../acp/XAiAcpExtension.ts"; import { type GrokAdapterShape } from "../Services/GrokAdapter.ts"; import { type EventNdjsonLogger, makeEventNdjsonLogger } from "./EventNdjsonLogger.ts"; @@ -73,6 +85,15 @@ const encodeUnknownJsonStringExit = Schema.encodeUnknownExit(Schema.fromJsonStri const PROVIDER = ProviderDriverKind.make("grok"); const GROK_RESUME_VERSION = 1 as const; +const NANOS_PER_MILLI = 1_000_000n; +// ACP does not expose Grok's private `streaming_reasoning` phase. Once it has +// emitted standard ACP progress, ten silent minutes is long enough to avoid +// treating legitimate reasoning as a stalled stream. +const DEFAULT_GROK_TURN_INACTIVITY_TIMEOUT_MS = 10 * 60 * 1_000; +// A tool can legitimately run without emitting text for much longer than +// reasoning. It still needs a deadline so a lost tool update cannot leave the +// turn working forever. +const DEFAULT_GROK_ACTIVE_TOOL_INACTIVITY_TIMEOUT_MS = 30 * 60 * 1_000; function encodeJsonStringForDiagnostics(input: unknown): string | undefined { const result = encodeUnknownJsonStringExit(input); @@ -84,6 +105,10 @@ export interface GrokAdapterLiveOptions { readonly nativeEventLogPath?: string; readonly nativeEventLogger?: EventNdjsonLogger; readonly instanceId?: ProviderInstanceId; + /** Override the conservative ACP turn liveness timeout in focused tests. */ + readonly turnInactivityTimeoutMs?: number; + /** Override the longer active-tool liveness timeout in focused tests. */ + readonly activeToolInactivityTimeoutMs?: number; } interface PendingApproval { @@ -98,6 +123,10 @@ interface PendingUserInput { readonly resolution: Deferred.Deferred; } +interface GrokTurnLivenessSignal { + readonly turnId: TurnId; +} + interface GrokSessionContext { readonly threadId: ThreadId; readonly acpSessionId: string; @@ -109,6 +138,14 @@ interface GrokSessionContext { readonly pendingUserInputs: Map; turns: Array<{ id: TurnId; items: Array }>; lastPlanFingerprint: string | undefined; + /** + * Latest plan.md body + turn it was emitted for. Dedupe is turn-scoped so a + * later turn re-proposing the same text still gets a new proposed-plan card. + */ + lastKnownProposedPlanMarkdown: string | undefined; + lastKnownProposedPlanTurnId: TurnId | undefined; + /** True after enter_plan_mode until the turn ends or exit_plan_mode resolves. */ + planModeActive: boolean; activeTurnId: TurnId | undefined; /** Turns already interrupted; late prompt RPCs must not resurrect them. */ interruptedTurnIds: Set; @@ -116,7 +153,15 @@ interface GrokSessionContext { * >0 means a turn is actively running, so a new sendTurn is a steer that * continues it, and only the last remaining prompt settles the turn. */ promptsInFlight: number; + readonly livenessSignals: Queue.Queue; + livenessTurnId: TurnId | undefined; + lastTurnActivityAtNanos: bigint | undefined; + readonly activeToolCallIds: Set; + livenessUpdatesInFlight: number; + /** Prompt RPCs that returned before their turn settlement acquired the lock. */ + promptResponsesReady: number; currentModelId: string | undefined; + currentReasoningEffort: string | undefined; stopped: boolean; } @@ -164,6 +209,54 @@ const resolveNotificationTurnId = (ctx: GrokSessionContext): TurnId | undefined const resolveCallbackTurnId = (ctx: GrokSessionContext): TurnId | undefined => ctx.activeTurnId; +function clearProposedPlanFallback(ctx: GrokSessionContext): void { + ctx.lastKnownProposedPlanMarkdown = undefined; + ctx.lastKnownProposedPlanTurnId = undefined; + ctx.planModeActive = false; +} + +/** Detect Grok's enter_plan_mode tool call from ACP tool state. */ +export function isGrokEnterPlanModeToolCall(toolCall: { + readonly title?: string; + readonly data: Record; +}): boolean { + const title = toolCall.title?.trim().toLowerCase() ?? ""; + if ( + title === "enter_plan_mode" || + title === "plan: enter" || + title === "plan mode entered" || + title.includes("enter_plan_mode") + ) { + return true; + } + const rawInput = toolCall.data.rawInput; + if (isRecord(rawInput) && rawInput.variant === "EnterPlanMode") { + return true; + } + return false; +} + +/** Failed enter_plan_mode must not leave planModeActive stuck on. */ +export function nextGrokPlanModeActive( + currentlyActive: boolean, + toolCall: { + readonly title?: string; + readonly status?: "pending" | "inProgress" | "completed" | "failed"; + readonly data: Record; + }, +): boolean { + if (!isGrokEnterPlanModeToolCall(toolCall)) { + return currentlyActive; + } + if (toolCall.status === "failed") { + return false; + } + if (toolCall.status === "completed" || toolCall.status === "inProgress") { + return true; + } + return currentlyActive; +} + const resolveSessionCallbackTurnId = ( sessions: ReadonlyMap, threadId: ThreadId, @@ -179,26 +272,38 @@ function parseGrokResume(raw: unknown): { sessionId: string } | undefined { return { sessionId: raw.sessionId.trim() }; } -function selectPermissionOptionId( +export function selectGrokPermissionOptionId( request: EffectAcpSchema.RequestPermissionRequest, decision: Exclude, ): string | undefined { - const kind = + const preferredKind = decision === "acceptForSession" ? "allow_always" : decision === "accept" ? "allow_once" : "reject_once"; - const option = request.options.find((entry) => entry.kind === kind); - return option?.optionId.trim() || undefined; + const preferred = request.options.find((entry) => entry.kind === preferredKind); + const preferredId = preferred?.optionId.trim(); + if (preferredId) { + return preferredId; + } + // Grok 4.6 often omits allow_always. T3 still offers "Always allow this session". + if (decision === "acceptForSession") { + const once = request.options.find((entry) => entry.kind === "allow_once"); + const onceId = once?.optionId.trim(); + if (onceId) { + return onceId; + } + } + return undefined; } function selectAutoApprovedPermissionOption( request: EffectAcpSchema.RequestPermissionRequest, ): string | undefined { return ( - selectPermissionOptionId(request, "acceptForSession") ?? - selectPermissionOptionId(request, "accept") + selectGrokPermissionOptionId(request, "acceptForSession") ?? + selectGrokPermissionOptionId(request, "accept") ); } @@ -240,10 +345,31 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte const managedNativeEventLogger = options?.nativeEventLogger === undefined ? nativeEventLogger : undefined; const makeAcpNativeLoggers = yield* makeAcpNativeLoggerFactory(); + const hostPlatform = yield* HostProcessPlatform; + const hostEnvironment = yield* HostProcessEnvironment; + const grokPlanPathHost = { + platform: hostPlatform, + environment: options?.environment ?? hostEnvironment, + }; const sessions = new Map(); const threadLocksRef = yield* SynchronizedRef.make(new Map()); const runtimeEventPubSub = yield* PubSub.unbounded(); + const requestedTurnInactivityTimeoutMs = options?.turnInactivityTimeoutMs; + const turnInactivityTimeoutMs = + typeof requestedTurnInactivityTimeoutMs === "number" && + Number.isFinite(requestedTurnInactivityTimeoutMs) + ? Math.max(1, Math.floor(requestedTurnInactivityTimeoutMs)) + : DEFAULT_GROK_TURN_INACTIVITY_TIMEOUT_MS; + const turnInactivityTimeoutNanos = BigInt(turnInactivityTimeoutMs) * NANOS_PER_MILLI; + const requestedActiveToolInactivityTimeoutMs = options?.activeToolInactivityTimeoutMs; + const activeToolInactivityTimeoutMs = + typeof requestedActiveToolInactivityTimeoutMs === "number" && + Number.isFinite(requestedActiveToolInactivityTimeoutMs) + ? Math.max(1, Math.floor(requestedActiveToolInactivityTimeoutMs)) + : DEFAULT_GROK_ACTIVE_TOOL_INACTIVITY_TIMEOUT_MS; + const activeToolInactivityTimeoutNanos = + BigInt(activeToolInactivityTimeoutMs) * NANOS_PER_MILLI; const nowIso = Effect.map(DateTime.now, DateTime.formatIso); const randomUUIDv4 = crypto.randomUUIDv4.pipe( @@ -294,6 +420,146 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte const withThreadLock = (threadId: string, effect: Effect.Effect) => Effect.flatMap(getThreadSemaphore(threadId), (semaphore) => semaphore.withPermit(effect)); + const signalTurnLiveness = (ctx: GrokSessionContext, turnId: TurnId) => + Queue.offer(ctx.livenessSignals, { turnId }).pipe(Effect.asVoid); + + const beginTurnLiveness = (ctx: GrokSessionContext, turnId: TurnId) => + Effect.sync(() => { + ctx.livenessTurnId = turnId; + // Do not start a deadline until ACP has made observable progress. + // Grok's private reasoning phase is not present in the ACP stream. + ctx.lastTurnActivityAtNanos = undefined; + ctx.activeToolCallIds.clear(); + }); + + const clearTurnLiveness = (ctx: GrokSessionContext) => { + const turnId = ctx.livenessTurnId; + ctx.livenessTurnId = undefined; + ctx.lastTurnActivityAtNanos = undefined; + ctx.activeToolCallIds.clear(); + ctx.livenessUpdatesInFlight = 0; + ctx.promptResponsesReady = 0; + return turnId === undefined ? Effect.void : signalTurnLiveness(ctx, turnId); + }; + + const recordTurnActivity = Effect.fn("GrokAdapter.recordTurnActivity")(function* ( + ctx: GrokSessionContext, + turnId: TurnId, + event: Extract< + AcpSessionRuntime.AcpSessionRuntimeEvent, + { + _tag: + | "AssistantItemStarted" + | "AssistantItemCompleted" + | "PlanUpdated" + | "ToolCallUpdated" + | "ContentDelta"; + } + >, + ) { + if ( + ctx.livenessTurnId !== turnId || + (event._tag === "ContentDelta" && event.text.length === 0) + ) { + return; + } + ctx.livenessUpdatesInFlight += 1; + try { + const activityAtNanos = yield* Clock.monotonicTimeNanos; + if (ctx.livenessTurnId !== turnId || ctx.interruptedTurnIds.has(turnId)) { + return; + } + if (event._tag === "ToolCallUpdated") { + if (event.toolCall.status === "completed" || event.toolCall.status === "failed") { + ctx.activeToolCallIds.delete(event.toolCall.toolCallId); + } else { + // A tool update without a terminal status receives a longer + // deadline so a long-running tool is not mistaken for a stall. + ctx.activeToolCallIds.add(event.toolCall.toolCallId); + } + } + ctx.lastTurnActivityAtNanos = activityAtNanos; + } finally { + // Decrement before signaling. The watchdog treats in-flight updates as a + // pause; if it consumed a signal while the counter was still > 0 it would + // wait on the next take with no follow-up wake after this decrement. + ctx.livenessUpdatesInFlight = Math.max(0, ctx.livenessUpdatesInFlight - 1); + yield* signalTurnLiveness(ctx, turnId); + } + }); + + const hasLivenessPause = (ctx: GrokSessionContext) => + ctx.pendingApprovals.size > 0 || + ctx.pendingUserInputs.size > 0 || + ctx.livenessUpdatesInFlight > 0; + + const livenessTimeoutFor = (ctx: GrokSessionContext) => + ctx.activeToolCallIds.size > 0 + ? { + milliseconds: activeToolInactivityTimeoutMs, + nanos: activeToolInactivityTimeoutNanos, + } + : { milliseconds: turnInactivityTimeoutMs, nanos: turnInactivityTimeoutNanos }; + + const signalSessionTurnLiveness = (threadId: ThreadId, turnId: TurnId | undefined) => { + const ctx = sessions.get(threadId); + return ctx && turnId !== undefined ? signalTurnLiveness(ctx, turnId) : Effect.void; + }; + + const resumeSessionTurnLiveness = Effect.fn("GrokAdapter.resumeSessionTurnLiveness")(function* ( + threadId: ThreadId, + turnId: TurnId | undefined, + ) { + const ctx = sessions.get(threadId); + if (!ctx || turnId === undefined || ctx.livenessTurnId !== turnId) { + return; + } + // An approval or user-input wait can last longer than the watchdog. + // Its resolution gives the provider a fresh window to resume output. + ctx.lastTurnActivityAtNanos = yield* Clock.monotonicTimeNanos; + yield* signalTurnLiveness(ctx, turnId); + }); + + const refreshSessionTurnLiveness = Effect.fn("GrokAdapter.refreshSessionTurnLiveness")( + function* (threadId: ThreadId, turnId: TurnId | undefined) { + const ctx = sessions.get(threadId); + if ( + !ctx || + turnId === undefined || + ctx.livenessTurnId !== turnId || + ctx.lastTurnActivityAtNanos === undefined + ) { + return; + } + ctx.lastTurnActivityAtNanos = yield* Clock.monotonicTimeNanos; + yield* signalTurnLiveness(ctx, turnId); + }, + ); + + const markPromptResponseReady = Effect.fn("GrokAdapter.markPromptResponseReady")(function* ( + threadId: ThreadId, + acpSessionId: string, + turnId: TurnId, + ) { + const ctx = sessions.get(threadId); + if ( + ctx && + ctx.acpSessionId === acpSessionId && + !ctx.stopped && + !ctx.interruptedTurnIds.has(turnId) && + ctx.livenessTurnId === turnId && + ctx.activeTurnId === turnId && + ctx.session.activeTurnId === turnId + ) { + ctx.promptResponsesReady += 1; + yield* signalTurnLiveness(ctx, turnId); + } + }); + + const consumePromptResponseReady = (ctx: GrokSessionContext) => { + ctx.promptResponsesReady = Math.max(0, ctx.promptResponsesReady - 1); + }; + const settlePromptInFlight = ( threadId: ThreadId, turnId: TurnId, @@ -373,6 +639,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte updatedAt, }; } + yield* clearTurnLiveness(liveCtx); return; } settleTurnId = fallbackTurnId; @@ -389,6 +656,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte } liveCtx.promptsInFlight = remainingPrompts; } + yield* clearTurnLiveness(liveCtx); const updatedAt = yield* nowIso; const canEmitTurnCompletion = liveCtx.session.status === "running" || liveCtx.session.status === "connecting"; @@ -397,6 +665,9 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte options?.completedStopReason !== undefined && canEmitTurnCompletion; const { activeTurnId: _activeTurnId, ...readySession } = liveCtx.session; liveCtx.activeTurnId = undefined; + // Drop turn-scoped plan fallback so a later empty exit_plan cannot + // resurrect this turn's markdown as a fresh proposal. + clearProposedPlanFallback(liveCtx); liveCtx.session = { ...readySession, status: "ready", @@ -432,6 +703,104 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte } }); + const isLiveTurn = (ctx: GrokSessionContext, turnId: TurnId) => + ctx.promptsInFlight > 0 && + ctx.promptsInFlight > ctx.promptResponsesReady && + ctx.activeTurnId === turnId && + ctx.session.activeTurnId === turnId && + (ctx.session.status === "running" || ctx.session.status === "connecting"); + + const settleStalledTurn = Effect.fn("GrokAdapter.settleStalledTurn")(function* ( + ctx: GrokSessionContext, + turnId: TurnId, + ) { + return yield* withThreadLock( + ctx.threadId, + Effect.gen(function* () { + const liveCtx = sessions.get(ctx.threadId); + if ( + liveCtx !== ctx || + ctx.stopped || + !isLiveTurn(ctx, turnId) || + ctx.interruptedTurnIds.has(turnId) || + hasLivenessPause(ctx) + ) { + return; + } + const lastActivityAtNanos = ctx.lastTurnActivityAtNanos; + if (lastActivityAtNanos === undefined) { + return; + } + const nowNanos = yield* Clock.monotonicTimeNanos; + if ( + ctx.interruptedTurnIds.has(turnId) || + !isLiveTurn(ctx, turnId) || + hasLivenessPause(ctx) || + nowNanos - lastActivityAtNanos < livenessTimeoutFor(ctx).nanos + ) { + return; + } + + // Mark before cancel/drain so notifications already in flight finish + // before the terminal event, while late notifications are dropped. + ctx.interruptedTurnIds.add(turnId); + yield* Effect.ignore( + ctx.acp.cancel.pipe( + Effect.mapError((error) => + mapAcpToAdapterError(PROVIDER, ctx.threadId, "session/cancel", error), + ), + ), + ); + yield* Effect.ignore(ctx.acp.drainEvents); + yield* settlePromptInFlight(ctx.threadId, turnId, ctx.acpSessionId, { + errorMessage: `Grok ACP turn stalled without content or tool progress for ${livenessTimeoutFor(ctx).milliseconds}ms.`, + settleAllPrompts: true, + }); + }), + ); + }); + + const runTurnLivenessWatchdog = Effect.fn("GrokAdapter.runTurnLivenessWatchdog")( + function* (ctx: GrokSessionContext) { + while (true) { + if (ctx.stopped) { + return; + } + const turnId = ctx.livenessTurnId; + if ( + turnId === undefined || + ctx.interruptedTurnIds.has(turnId) || + !isLiveTurn(ctx, turnId) || + hasLivenessPause(ctx) + ) { + yield* Queue.take(ctx.livenessSignals); + continue; + } + + const lastActivityAtNanos = ctx.lastTurnActivityAtNanos; + if (lastActivityAtNanos === undefined) { + yield* Queue.take(ctx.livenessSignals); + continue; + } + const nowNanos = yield* Clock.monotonicTimeNanos; + const remainingNanos = livenessTimeoutFor(ctx).nanos - (nowNanos - lastActivityAtNanos); + if (remainingNanos <= 0n) { + yield* settleStalledTurn(ctx, turnId); + continue; + } + + const wakeReason = yield* Effect.raceFirst( + Effect.sleep(Duration.nanos(remainingNanos)).pipe(Effect.as("timeout" as const)), + Queue.take(ctx.livenessSignals).pipe(Effect.as("activity" as const)), + ); + if (wakeReason === "timeout") { + yield* settleStalledTurn(ctx, turnId); + } + } + }, + Effect.catch(() => Effect.void), + ); + const logNative = (threadId: ThreadId, method: string, payload: unknown) => Effect.gen(function* () { if (!nativeEventLogger) return; @@ -495,6 +864,45 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte ); }); + /** Surface Grok plan.md as T3's proposed-plan card (while writing + on exit). */ + const emitProposedPlanCompleted = ( + ctx: GrokSessionContext, + turnId: TurnId | undefined, + stamp: { readonly eventId: EventId; readonly createdAt: string }, + planMarkdown: string, + raw: { readonly method: string; readonly payload: unknown }, + ) => + Effect.gen(function* () { + const trimmed = planMarkdown.trim(); + if (trimmed.length === 0) { + ctx.lastKnownProposedPlanMarkdown = ""; + ctx.lastKnownProposedPlanTurnId = turnId; + return; + } + // Turn-scoped dedupe: identical text on a later turn must still emit. + if ( + ctx.lastKnownProposedPlanMarkdown === trimmed && + ctx.lastKnownProposedPlanTurnId === turnId + ) { + return; + } + ctx.lastKnownProposedPlanMarkdown = trimmed; + ctx.lastKnownProposedPlanTurnId = turnId; + yield* offerRuntimeEvent({ + type: "turn.proposed.completed", + ...stamp, + provider: PROVIDER, + threadId: ctx.threadId, + turnId, + payload: { planMarkdown: trimmed }, + raw: { + source: "acp.grok.extension", + method: raw.method, + payload: raw.payload, + }, + }); + }); + const requireSession = ( threadId: ThreadId, ): Effect.Effect => { @@ -556,6 +964,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte const pendingApprovals = new Map(); const pendingUserInputs = new Map(); + const sessionApprovedOperations = new Set(); const sessionScope = yield* Scope.make("sequential"); let sessionScopeTransferred = false; yield* Effect.addFinalizer(() => @@ -575,6 +984,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte ...(options?.environment ? { environment: options.environment } : {}), childProcessSpawner, cwd, + runtimeMode: input.runtimeMode, ...(resumeSessionId ? { resumeSessionId } : {}), clientInfo: { name: "t3-code", version: "0.0.0" }, ...(mcpSession @@ -621,6 +1031,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte const resolution = yield* Deferred.make(); const turnId = resolveSessionCallbackTurnId(sessions, input.threadId); pendingUserInputs.set(requestId, { resolution }); + yield* signalSessionTurnLiveness(input.threadId, turnId); yield* offerRuntimeEvent({ type: "user-input.requested", ...(yield* makeEventStamp()), @@ -637,6 +1048,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte }); const resolved = yield* Deferred.await(resolution); pendingUserInputs.delete(requestId); + yield* resumeSessionTurnLiveness(input.threadId, turnId); const resolvedAnswers = resolved._tag === "answered" ? resolved.answers : {}; yield* offerRuntimeEvent({ type: "user-input.resolved", @@ -663,12 +1075,77 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte ), { discard: true }, ); + // Grok intercepts exit_plan_mode and reverse-requests client approval. + // Capture plan into T3 proposed-plan UI and abandon the native gate so + // the turn does not hang (Claude ExitPlanMode pattern). + yield* Effect.forEach( + ["x.ai/exit_plan_mode", "_x.ai/exit_plan_mode"] as const, + (method) => + acp.handleExtRequest(method, XAiExitPlanModeRequest, (params) => + mapAcpCallbackFailure( + Effect.gen(function* () { + yield* logNative(input.threadId, method, params); + const turnId = resolveSessionCallbackTurnId(sessions, input.threadId); + const ctx = sessions.get(input.threadId); + const planMarkdown = extractXAiExitPlanMarkdown( + params, + ctx?.lastKnownProposedPlanMarkdown, + ); + if (ctx) { + yield* emitProposedPlanCompleted( + ctx, + turnId, + yield* makeEventStamp(), + planMarkdown, + { method, payload: params }, + ); + ctx.planModeActive = false; + } else { + yield* offerRuntimeEvent({ + type: "turn.proposed.completed", + ...(yield* makeEventStamp()), + provider: PROVIDER, + threadId: input.threadId, + turnId, + payload: { planMarkdown }, + raw: { + source: "acp.grok.extension", + method, + payload: params, + }, + }); + } + return makeXAiExitPlanModeCapturedResponse(); + }), + ), + ), + { discard: true }, + ); yield* acp.handleRequestPermission((params) => mapAcpCallbackFailure( Effect.gen(function* () { yield* logNative(input.threadId, "session/request_permission", params); - if (input.runtimeMode === "full-access") { - const autoApprovedOptionId = selectAutoApprovedPermissionOption(params); + const permissionRequest = parsePermissionRequest(params); + const command = permissionRequest.toolCall?.command; + const { kind, title, rawInput, locations } = params.toolCall; + let operationInput = rawInput; + if (isRecord(rawInput) && rawInput.variant === "Bash") { + const { description: _description, ...shellInput } = rawInput; + operationInput = shellInput; + } + // Remember the operation, not the tool-call id or every future tool. + // Generic titles without input cannot identify an operation safely. + const approvalKey = + command || (isRecord(rawInput) && Object.keys(rawInput).length > 0) + ? stableStringify({ kind, title, command, input: operationInput, locations }) + : undefined; + const alreadyApproved = + approvalKey !== undefined && sessionApprovedOperations.has(approvalKey); + if (input.runtimeMode === "full-access" || alreadyApproved) { + const autoApprovedOptionId = + input.runtimeMode === "full-access" + ? selectAutoApprovedPermissionOption(params) + : selectGrokPermissionOptionId(params, "accept"); if (autoApprovedOptionId !== undefined) { return { outcome: { @@ -678,12 +1155,12 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte }; } } - const permissionRequest = parsePermissionRequest(params); const requestId = ApprovalRequestId.make(yield* randomUUIDv4); const runtimeRequestId = RuntimeRequestId.make(requestId); const decision = yield* Deferred.make(); const turnId = resolveSessionCallbackTurnId(sessions, input.threadId); pendingApprovals.set(requestId, { decision }); + yield* signalSessionTurnLiveness(input.threadId, turnId); yield* offerRuntimeEvent( makeAcpRequestOpenedEvent({ stamp: yield* makeEventStamp(), @@ -704,6 +1181,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte ); const resolved = yield* Deferred.await(decision); pendingApprovals.delete(requestId); + yield* resumeSessionTurnLiveness(input.threadId, turnId); yield* offerRuntimeEvent( makeAcpRequestResolvedEvent({ stamp: yield* makeEventStamp(), @@ -716,7 +1194,16 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte }), ); const selectedOptionId = - resolved === "cancel" ? undefined : selectPermissionOptionId(params, resolved); + resolved === "cancel" + ? undefined + : selectGrokPermissionOptionId(params, resolved); + if ( + resolved === "acceptForSession" && + selectedOptionId && + approvalKey !== undefined + ) { + sessionApprovedOperations.add(approvalKey); + } return { outcome: selectedOptionId ? { @@ -738,10 +1225,22 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte const requestedStartModelId = grokModelSelection?.model ? resolveGrokAcpBaseModelId(grokModelSelection.model) : undefined; + const currentStartModelId = currentGrokModelIdFromSessionSetup( + started.sessionSetupResult, + ); + const currentStartReasoningEffort = currentGrokReasoningEffortFromSessionSetup( + started.sessionSetupResult, + ); + const requestedStartReasoningEffort = getModelSelectionStringOptionValue( + grokModelSelection, + "reasoningEffort", + ); const boundModelId = yield* applyGrokAcpModelSelection({ runtime: acp, - currentModelId: currentGrokModelIdFromSessionSetup(started.sessionSetupResult), + currentModelId: currentStartModelId, + currentReasoningEffort: currentStartReasoningEffort, requestedModelId: requestedStartModelId, + requestedReasoningEffort: requestedStartReasoningEffort, mapError: (cause) => mapAcpToAdapterError(PROVIDER, input.threadId, "session/set_model", cause), }); @@ -774,10 +1273,23 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte pendingUserInputs, turns: [], lastPlanFingerprint: undefined, + lastKnownProposedPlanMarkdown: undefined, + lastKnownProposedPlanTurnId: undefined, + planModeActive: false, activeTurnId: undefined, interruptedTurnIds: new Set(), promptsInFlight: 0, + livenessSignals: yield* Queue.sliding(1), + livenessTurnId: undefined, + lastTurnActivityAtNanos: undefined, + activeToolCallIds: new Set(), + livenessUpdatesInFlight: 0, + promptResponsesReady: 0, currentModelId: boundModelId, + currentReasoningEffort: + requestedStartReasoningEffort !== undefined + ? normalizeGrokReasoningEffort(requestedStartReasoningEffort) + : currentStartReasoningEffort, stopped: false, }; @@ -807,6 +1319,15 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte ) { return; } + if ( + event._tag === "AssistantItemStarted" || + event._tag === "AssistantItemCompleted" || + event._tag === "PlanUpdated" || + event._tag === "ToolCallUpdated" || + event._tag === "ContentDelta" + ) { + yield* recordTurnActivity(ctx, notificationTurnId, event); + } const stamp = yield* makeEventStamp(); switch (event._tag) { @@ -844,7 +1365,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte "session/update", ); return; - case "ToolCallUpdated": + case "ToolCallUpdated": { yield* offerRuntimeEvent( makeAcpToolCallEvent({ stamp, @@ -855,7 +1376,30 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte rawPayload: event.rawPayload, }), ); + ctx.planModeActive = nextGrokPlanModeActive(ctx.planModeActive, event.toolCall); + // Only promote session plan.md writes while plan mode is + // active — avoids treating unrelated plan files as proposals. + // Fresh stamp: must not share eventId with the tool lifecycle event. + if (ctx.planModeActive) { + const planMarkdown = extractGrokPlanMarkdownFromToolCallData( + event.toolCall.data, + grokPlanPathHost, + ); + if (planMarkdown !== undefined) { + yield* emitProposedPlanCompleted( + ctx, + notificationTurnId, + yield* makeEventStamp(), + planMarkdown, + { + method: "session/update", + payload: event.rawPayload, + }, + ); + } + } return; + } case "ContentDelta": yield* offerRuntimeEvent( makeAcpContentDeltaEvent({ @@ -887,6 +1431,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte ctx.notificationFiber = nf; sessions.set(input.threadId, ctx); + yield* runTurnLivenessWatchdog(ctx).pipe(Effect.forkIn(ctx.scope), Effect.asVoid); sessionScopeTransferred = true; yield* offerRuntimeEvent({ @@ -933,6 +1478,11 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte // Bind the turn id before cooperative yields so interruptTurn can // settle this prompt even if stop arrives during preparation. ctx.activeTurnId = turnId; + // New turn: do not fall back to a previous turn's plan.md body when + // exit_plan_mode omits planContent. + if (steeringTurnId === undefined) { + clearProposedPlanFallback(ctx); + } ctx.session = { ...ctx.session, status: steeringTurnId === undefined ? "connecting" : "running", @@ -948,13 +1498,10 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte const requestedTurnModelId = turnModelSelection?.model ? resolveGrokAcpBaseModelId(turnModelSelection.model) : undefined; - const currentModelId = yield* applyGrokAcpModelSelection({ - runtime: ctx.acp, - currentModelId: ctx.currentModelId, - requestedModelId: requestedTurnModelId, - mapError: (cause) => - mapAcpToAdapterError(PROVIDER, input.threadId, "session/set_model", cause), - }); + const requestedTurnReasoningEffort = getModelSelectionStringOptionValue( + turnModelSelection, + "reasoningEffort", + ); const text = input.input?.trim(); const imagePromptParts = yield* Effect.forEach( @@ -1003,7 +1550,21 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte }); } + const currentModelId = yield* applyGrokAcpModelSelection({ + runtime: ctx.acp, + currentModelId: ctx.currentModelId, + currentReasoningEffort: ctx.currentReasoningEffort, + requestedModelId: requestedTurnModelId, + requestedReasoningEffort: requestedTurnReasoningEffort, + mapError: (cause) => + mapAcpToAdapterError(PROVIDER, input.threadId, "session/set_model", cause), + }); ctx.currentModelId = currentModelId; + if (requestedTurnReasoningEffort !== undefined) { + ctx.currentReasoningEffort = normalizeGrokReasoningEffort( + requestedTurnReasoningEffort, + ); + } const displayModel = currentModelId ? resolveGrokAcpBaseModelId(currentModelId) : undefined; @@ -1032,6 +1593,11 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte updatedAt: yield* nowIso, ...(displayModel ? { model: displayModel } : {}), }; + if (steeringTurnId === undefined) { + yield* beginTurnLiveness(ctx, turnId); + } else { + yield* refreshSessionTurnLiveness(input.threadId, turnId); + } if (steeringTurnId === undefined) { yield* offerRuntimeEvent({ @@ -1082,10 +1648,14 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte }) .pipe( Effect.tap((promptResult) => - Effect.all([ - Ref.set(promptRpcSucceeded, true), - Ref.set(promptResultRef, promptResult), - ]), + Effect.all( + [ + Ref.set(promptRpcSucceeded, true), + Ref.set(promptResultRef, promptResult), + markPromptResponseReady(input.threadId, prepared.acpSessionId, prepared.turnId), + ], + { discard: true }, + ), ), Effect.tapError((error) => Ref.set( @@ -1126,6 +1696,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte yield* Effect.yieldNow; } yield* prepared.acp.drainEvents; + consumePromptResponseReady(ctx); if (ctx.interruptedTurnIds.has(prepared.turnId)) { yield* Ref.set(promptSettled, true); return { @@ -1184,6 +1755,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte updatedAt: completedAt, ...(prepared.displayModel ? { model: prepared.displayModel } : {}), }; + yield* clearTurnLiveness(ctx); const completedStopReason = completedStopReasonFromPromptResponse(result); yield* offerRuntimeEvent({ type: "turn.completed", @@ -1240,6 +1812,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte if (ctx.interruptedTurnIds.has(prepared.turnId)) { return; } + consumePromptResponseReady(ctx); if ( ctx.promptsInFlight <= 0 || ctx.activeTurnId !== prepared.turnId || @@ -1356,6 +1929,7 @@ export function makeGrokAdapter(grokSettings: GrokSettings, options?: GrokAdapte status: "ready", updatedAt, }; + yield* clearTurnLiveness(ctx); } }), ); diff --git a/apps/server/src/provider/Layers/GrokProvider.test.ts b/apps/server/src/provider/Layers/GrokProvider.test.ts index 1c9bf1f26de7..42d642a3e74a 100644 --- a/apps/server/src/provider/Layers/GrokProvider.test.ts +++ b/apps/server/src/provider/Layers/GrokProvider.test.ts @@ -6,10 +6,183 @@ import * as Path from "effect/Path"; import * as Schema from "effect/Schema"; import { GrokSettings } from "@t3tools/contracts"; -import { buildInitialGrokProviderSnapshot, checkGrokProviderStatus } from "./GrokProvider.ts"; +import { + buildGrokModelCapabilities, + buildInitialGrokProviderSnapshot, + checkGrokProviderStatus, +} from "./GrokProvider.ts"; const decodeGrokSettings = Schema.decodeSync(GrokSettings); +describe("buildGrokModelCapabilities", () => { + it("preserves ACP-provided reasoning labels and the active default", () => { + const capabilities = buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { + supportsReasoningEffort: true, + reasoningEffort: "xhigh", + reasoningEfforts: [ + { value: "xhigh", label: "Extra High Effort", default: true }, + { value: "high", label: "High Effort", default: true }, + { value: "medium", label: "Medium Effort" }, + { value: "low", label: "Low Effort" }, + ], + }, + }); + + expect(capabilities.optionDescriptors).toEqual([ + { + id: "reasoningEffort", + label: "Reasoning", + type: "select", + currentValue: "xhigh", + options: [ + { id: "xhigh", label: "Extra High Effort", isDefault: true }, + { id: "high", label: "High Effort" }, + { id: "medium", label: "Medium Effort" }, + { id: "low", label: "Low Effort" }, + ], + }, + ]); + }); + + it("uses raw ACP values when option labels are omitted", () => { + const capabilities = buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { + supportsReasoningEffort: true, + reasoningEffort: "xhigh", + reasoningEfforts: [{ value: "xhigh" }, { value: "medium" }], + }, + }); + + expect(capabilities.optionDescriptors).toEqual([ + { + id: "reasoningEffort", + label: "Reasoning", + type: "select", + currentValue: "xhigh", + options: [ + { id: "xhigh", label: "xhigh" }, + { id: "medium", label: "medium" }, + ], + }, + ]); + }); + + it("keeps ACP current effort separate from its collapsed advertised default", () => { + const capabilities = buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { + supportsReasoningEffort: true, + reasoningEffort: "medium", + reasoningEfforts: [ + { value: "xhigh", label: "Extra High Effort", default: true }, + { value: "high", label: "High Effort", default: true }, + { value: "medium", label: "Medium Effort" }, + ], + }, + }); + + expect(capabilities.optionDescriptors).toEqual([ + { + id: "reasoningEffort", + label: "Reasoning", + type: "select", + currentValue: "medium", + options: [ + { id: "xhigh", label: "Extra High Effort", isDefault: true }, + { id: "high", label: "High Effort" }, + { id: "medium", label: "Medium Effort" }, + ], + }, + ]); + }); + + it("preserves ACP descriptions and falls back from invalid values to valid ids", () => { + const capabilities = buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { + supportsReasoningEffort: true, + reasoningEffort: "high", + reasoningEfforts: [ + { + id: "high", + value: "not a token", + label: "High Effort", + description: "Higher implementation quality", + default: true, + }, + { id: "bad id", value: "also invalid", label: "Invalid" }, + ], + }, + }); + + expect(capabilities.optionDescriptors).toEqual([ + { + id: "reasoningEffort", + label: "Reasoning", + type: "select", + currentValue: "high", + options: [ + { + id: "high", + label: "High Effort", + description: "Higher implementation quality", + isDefault: true, + }, + ], + }, + ]); + }); + + it("accepts an advertised ACP menu when the support flag is omitted", () => { + const capabilities = buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { + reasoningEffort: "high", + reasoningEfforts: [{ value: "high", label: "High Effort", default: true }], + }, + }); + + expect(capabilities.optionDescriptors).toHaveLength(1); + }); + + it("honors an explicit ACP opt-out even when a menu is present", () => { + const capabilities = buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { + supportsReasoningEffort: false, + reasoningEfforts: [{ value: "high", label: "High Effort", default: true }], + }, + }); + + expect(capabilities.optionDescriptors).toEqual([]); + }); + + it("does not synthesize a reasoning menu when ACP omits it", () => { + expect( + buildGrokModelCapabilities({ + modelId: "grok-4.6", + name: "Grok 4.6", + _meta: { supportsReasoningEffort: true, reasoningEffort: "xhigh" }, + }).optionDescriptors, + ).toEqual([]); + }); + + it("keeps non-reasoning Grok models free of reasoning controls", () => { + expect( + buildGrokModelCapabilities({ modelId: "grok-build", name: "Grok Build" }).optionDescriptors, + ).toEqual([]); + }); +}); + describe("buildInitialGrokProviderSnapshot", () => { it.effect("returns a disabled snapshot when settings.enabled is false", () => Effect.gen(function* () { diff --git a/apps/server/src/provider/Layers/GrokProvider.ts b/apps/server/src/provider/Layers/GrokProvider.ts index 934eecdb5ae6..44f9369b8250 100644 --- a/apps/server/src/provider/Layers/GrokProvider.ts +++ b/apps/server/src/provider/Layers/GrokProvider.ts @@ -29,7 +29,12 @@ import { enrichProviderSnapshotWithVersionAdvisory, type ProviderMaintenanceCapabilities, } from "../providerMaintenance.ts"; -import { makeGrokAcpRuntime, resolveGrokAcpBaseModelId } from "../acp/GrokAcpSupport.ts"; +import { + isValidGrokReasoningEffortToken, + makeGrokAcpRuntime, + resolveGrokAcpBaseModelId, +} from "../acp/GrokAcpSupport.ts"; +import { discoverGrokSkills } from "../Drivers/GrokSkills.ts"; const GROK_PRESENTATION = { displayName: "Grok", @@ -99,6 +104,104 @@ function grokModelsFromSettings( return providerModelsFromSettings(builtInModels, customModels ?? [], EMPTY_CAPABILITIES); } +function nonEmptyString(value: unknown): string | undefined { + return typeof value === "string" ? value.trim() || undefined : undefined; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + +function grokReasoningOptionsFromModel(model: EffectAcpSchema.ModelInfo): { + readonly options: ReadonlyArray<{ + value: string; + label: string; + description?: string; + isDefault?: boolean; + }>; + readonly currentValue: string | undefined; +} { + const meta = model._meta; + if (!meta || meta.supportsReasoningEffort === false) { + return { options: [], currentValue: undefined }; + } + + const currentEffort = nonEmptyString(meta.reasoningEffort); + const advertisedOptions = Array.isArray(meta.reasoningEfforts) ? meta.reasoningEfforts : []; + const seen = new Set(); + const options: Array<{ + value: string; + label: string; + description?: string; + advertisedDefault: boolean; + }> = []; + + for (const entry of advertisedOptions) { + if (!isRecord(entry)) { + continue; + } + const rawValue = nonEmptyString(entry.value); + const rawId = nonEmptyString(entry.id); + const value = + rawValue && isValidGrokReasoningEffortToken(rawValue) + ? rawValue + : rawId && isValidGrokReasoningEffortToken(rawId) + ? rawId + : undefined; + if (value === undefined || seen.has(value)) { + continue; + } + seen.add(value); + const description = nonEmptyString(entry.description); + options.push({ + value, + label: nonEmptyString(entry.label) ?? value, + ...(description ? { description } : {}), + advertisedDefault: entry.default === true || entry.isDefault === true, + }); + } + + const currentValue = + currentEffort && options.some((option) => option.value === currentEffort) + ? currentEffort + : undefined; + const advertisedDefaults = options.filter((option) => option.advertisedDefault); + const selectedDefault = + advertisedDefaults.find((option) => option.value === currentValue)?.value ?? + advertisedDefaults[0]?.value; + return { + options: options.map(({ value, label, description }) => ({ + value, + label, + ...(description ? { description } : {}), + ...(value === selectedDefault ? { isDefault: true } : {}), + })), + currentValue: currentValue ?? selectedDefault, + }; +} + +export function buildGrokModelCapabilities(model: EffectAcpSchema.ModelInfo): ModelCapabilities { + const reasoning = grokReasoningOptionsFromModel(model); + return reasoning.options.length > 0 + ? createModelCapabilities({ + optionDescriptors: [ + { + id: "reasoningEffort", + label: "Reasoning", + type: "select", + options: reasoning.options.map((option) => ({ + id: option.value, + label: option.label, + ...(option.description ? { description: option.description } : {}), + ...(option.isDefault ? { isDefault: true } : {}), + })), + ...(reasoning.currentValue ? { currentValue: reasoning.currentValue } : {}), + }, + ], + }) + : EMPTY_CAPABILITIES; +} + function buildGrokDiscoveredModelsFromSessionModelState( modelState: EffectAcpSchema.SessionModelState | null | undefined, ): ReadonlyArray { @@ -117,7 +220,7 @@ function buildGrokDiscoveredModelsFromSessionModelState( slug, name: model.name.trim() || slug, isCustom: false, - capabilities: EMPTY_CAPABILITIES, + capabilities: buildGrokModelCapabilities(model), }; }) .filter((model): model is ServerProviderModel => model !== undefined); @@ -161,6 +264,7 @@ const runGrokVersionCommand = ( export const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(function* ( grokSettings: GrokSettings, environment: NodeJS.ProcessEnv = process.env, + cwd?: string, ): Effect.fn.Return< ServerProviderDraft, never, @@ -251,6 +355,8 @@ export const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(func }); } + const skills = yield* discoverGrokSkills(grokSettings, environment, cwd); + const discoveryExit = yield* discoverGrokModelsViaAcp(grokSettings, environment).pipe( Effect.timeoutOption(GROK_ACP_MODEL_DISCOVERY_TIMEOUT_MS), Effect.exit, @@ -264,6 +370,7 @@ export const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(func enabled: grokSettings.enabled, checkedAt, models: fallbackModels, + skills, probe: { installed: true, version, @@ -282,6 +389,7 @@ export const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(func enabled: grokSettings.enabled, checkedAt, models: fallbackModels, + skills, probe: { installed: true, version, @@ -302,6 +410,7 @@ export const checkGrokProviderStatus = Effect.fn("checkGrokProviderStatus")(func enabled: grokSettings.enabled, checkedAt, models, + skills, probe: { installed: true, version, diff --git a/apps/server/src/provider/acp/AcpJsonRpcConnection.test.ts b/apps/server/src/provider/acp/AcpJsonRpcConnection.test.ts index b1ef0d3e5953..93ffc63806f6 100644 --- a/apps/server/src/provider/acp/AcpJsonRpcConnection.test.ts +++ b/apps/server/src/provider/acp/AcpJsonRpcConnection.test.ts @@ -330,7 +330,7 @@ describe("AcpSessionRuntime", () => { ), ); - it.effect("suppresses generic placeholder tool updates until completion", () => + it.effect("emits status-only tool updates through completion", () => Effect.gen(function* () { const runtime = yield* AcpSessionRuntime.AcpSessionRuntime; yield* runtime.start(); @@ -340,13 +340,22 @@ describe("AcpSessionRuntime", () => { }); expect(promptResult).toMatchObject({ stopReason: "end_turn" }); - const notes = Array.from(yield* Stream.runCollect(Stream.take(runtime.getEvents(), 1))); - expect(notes.map((note) => note._tag)).toEqual(["ToolCallUpdated"]); - const toolCall = notes[0]; - expect(toolCall?._tag).toBe("ToolCallUpdated"); - if (toolCall?._tag === "ToolCallUpdated") { - expect(toolCall.toolCall.status).toBe("completed"); - expect(toolCall.toolCall.title).toBe("Read file"); + const notes = Array.from(yield* Stream.runCollect(Stream.take(runtime.getEvents(), 3))); + expect(notes.map((note) => note._tag)).toEqual([ + "ToolCallUpdated", + "ToolCallUpdated", + "ToolCallUpdated", + ]); + const toolCalls = notes.flatMap((note) => + note._tag === "ToolCallUpdated" ? [note.toolCall] : [], + ); + expect(toolCalls.map((toolCall) => toolCall.status)).toEqual([ + "pending", + "inProgress", + "completed", + ]); + for (const toolCall of toolCalls) { + expect(toolCall.title).toBe("Read file"); } }).pipe( Effect.provide( diff --git a/apps/server/src/provider/acp/AcpRuntimeModel.test.ts b/apps/server/src/provider/acp/AcpRuntimeModel.test.ts index dc0dd6e0436f..9e5075a5f70a 100644 --- a/apps/server/src/provider/acp/AcpRuntimeModel.test.ts +++ b/apps/server/src/provider/acp/AcpRuntimeModel.test.ts @@ -11,6 +11,7 @@ import { parseSessionUpdateEvent, sessionUpdateIsReplay, syntheticLoadSessionResponseFromInitialize, + toolCallProgressLength, type AcpToolCallState, } from "./AcpRuntimeModel.ts"; @@ -542,6 +543,130 @@ describe("AcpRuntimeModel", () => { }); }); + it("keeps a retained tail on the original text entries around non-text content", () => { + const prefix = "a".repeat(4_000); + const suffix = "b".repeat(5_000); + const { events } = parseSessionUpdateEvent({ + sessionId: "session-1", + update: { + sessionUpdate: "tool_call_update", + toolCallId: "tool-1", + kind: "edit", + status: "in_progress", + content: [ + { type: "content", content: { type: "text", text: prefix } }, + { type: "diff", path: "/repo/file.ts", oldText: "before", newText: "after" }, + { type: "content", content: { type: "text", text: suffix } }, + ], + }, + } satisfies EffectAcpSchema.SessionNotification); + + const event = events[0]; + if (event?._tag !== "ToolCallUpdated") { + throw new Error("expected a ToolCallUpdated event"); + } + const content = event.toolCall.data.content as ReadonlyArray; + expect(content).toHaveLength(3); + const firstText = content[0]; + if (firstText?.type !== "content" || firstText.content.type !== "text") { + throw new Error("expected a bounded prefix text entry"); + } + expect(firstText.content.text.startsWith("[Earlier output truncated]")).toBe(true); + expect(firstText.content.text.endsWith("a".repeat(100))).toBe(true); + expect(content[1]).toEqual({ + type: "diff", + path: "/repo/file.ts", + oldText: "before", + newText: "after", + }); + expect(content[2]).toEqual({ + type: "content", + content: { type: "text", text: suffix }, + }); + }); + + it("bounds oversized whitespace-only tool call content that has no trimmed text", () => { + // Whitespace-only entries are skipped when extracting display text (`chunks.length === 0`) + // and used to be returned unchanged, which let a redrawing terminal persist unbounded + // buffers on `toolCall.data.content` and `rawPayload`. + const hugeWhitespace = " \n\t".repeat(30_000); + expect(hugeWhitespace.length).toBeGreaterThan(60_000); + + const { events } = parseSessionUpdateEvent({ + sessionId: "session-1", + update: { + sessionUpdate: "tool_call_update", + toolCallId: "tool-1", + kind: "other", + status: "in_progress", + content: [{ type: "content", content: { type: "text", text: hugeWhitespace } }], + }, + } satisfies EffectAcpSchema.SessionNotification); + + const event = events[0]; + if (event?._tag !== "ToolCallUpdated") { + throw new Error("expected a ToolCallUpdated event"); + } + + expect(event.toolCall.detail).toBeUndefined(); + const content = event.toolCall.data.content as ReadonlyArray; + const textEntry = content[0]; + if (textEntry?.type !== "content" || textEntry.content.type !== "text") { + throw new Error("expected a bounded text entry"); + } + expect(textEntry.content.text.length).toBeLessThan(8_100); + expect(textEntry.content.text.startsWith("[Earlier output truncated]")).toBe(true); + + const rawUpdate = ( + event.rawPayload as { + readonly update: { + readonly content: ReadonlyArray<{ readonly content: { text: string } }>; + }; + } + ).update; + expect(rawUpdate.content[0]?.content.text.length).toBeLessThan(8_100); + expect(JSON.stringify(event).length).toBeLessThan(hugeWhitespace.length); + }); + + it("bounds oversized whitespace-padded text entries even when trimmed content fits", () => { + const padded = `${" ".repeat(40_000)}ok${" ".repeat(40_000)}`; + expect(padded.length).toBeGreaterThan(60_000); + + const { events } = parseSessionUpdateEvent({ + sessionId: "session-1", + update: { + sessionUpdate: "tool_call_update", + toolCallId: "tool-1", + kind: "other", + status: "in_progress", + content: [{ type: "content", content: { type: "text", text: padded } }], + }, + } satisfies EffectAcpSchema.SessionNotification); + + const event = events[0]; + if (event?._tag !== "ToolCallUpdated") { + throw new Error("expected a ToolCallUpdated event"); + } + + expect(event.toolCall.detail).toBe("ok"); + const content = event.toolCall.data.content as ReadonlyArray; + const textEntry = content[0]; + if (textEntry?.type !== "content" || textEntry.content.type !== "text") { + throw new Error("expected a bounded text entry"); + } + expect(textEntry.content.text).toBe("ok"); + + const rawUpdate = ( + event.rawPayload as { + readonly update: { + readonly content: ReadonlyArray<{ readonly content: { text: string } }>; + }; + } + ).update; + expect(rawUpdate.content[0]?.content.text).toBe("ok"); + expect(JSON.stringify(event).length).toBeLessThan(padded.length); + }); + describe("decideToolCallUpdateEmission", () => { const toolCall = (detail: string | undefined, status?: AcpToolCallState["status"]) => ({ @@ -552,6 +677,17 @@ describe("AcpRuntimeModel", () => { data: {}, }) satisfies AcpToolCallState; + it("emits the first in-progress tool_call even when it has no detail", () => { + expect( + decideToolCallUpdateEmission({ + previous: undefined, + next: { toolCallId: "tool-1", title: "Grok Tool", status: "pending", data: {} }, + lastEmittedDetailLength: undefined, + skippedSinceEmit: 0, + }), + ).toEqual({ emit: true, skippedSinceEmit: 0 }); + }); + it("always emits terminal (completed/failed) status updates regardless of growth", () => { expect( decideToolCallUpdateEmission({ @@ -573,16 +709,66 @@ describe("AcpRuntimeModel", () => { }); it("skips updates whose bounded detail did not change", () => { + const previous = toolCall("frame 1", "inProgress"); expect( decideToolCallUpdateEmission({ - previous: toolCall("frame 1", "inProgress"), - next: toolCall("frame 1", "inProgress"), + previous, + next: previous, lastEmittedDetailLength: 7, skippedSinceEmit: 0, }), ).toEqual({ emit: false, skippedSinceEmit: 0 }); }); + it("coalesces command-tool updates whose content grew while detail stayed the command", () => { + const commandCall = (stdout: string): AcpToolCallState => ({ + toolCallId: "tool-1", + title: "Ran command", + status: "inProgress", + command: "ls", + detail: "ls", + data: { + command: "ls", + content: [{ type: "content", content: { type: "text", text: stdout } }], + }, + }); + + let previous: AcpToolCallState | undefined; + let lastEmittedDetailLength: number | undefined; + let skippedSinceEmit = 0; + const emissions: Array = []; + + for (let i = 1; i <= 12; i += 1) { + const next = commandCall("x".repeat(i)); + const decision = decideToolCallUpdateEmission({ + previous, + next, + lastEmittedDetailLength, + skippedSinceEmit, + }); + emissions.push(decision.emit); + skippedSinceEmit = decision.skippedSinceEmit; + if (decision.emit) { + lastEmittedDetailLength = toolCallProgressLength(next); + } + previous = next; + } + + const emittedIndices = emissions.flatMap((emitted, index) => (emitted ? [index + 1] : [])); + expect(emittedIndices).toEqual([1, 11]); + }); + + it("emits pending to inProgress status changes even when detail and output are unchanged", () => { + expect( + decideToolCallUpdateEmission({ + previous: toolCall("same", "pending"), + next: toolCall("same", "inProgress"), + lastEmittedDetailLength: 4, + skippedSinceEmit: 0, + }), + ).toEqual({ emit: true, skippedSinceEmit: 0 }); + }); + it("emits immediately when the title changes, even with no growth", () => { const decision = decideToolCallUpdateEmission({ previous: { toolCallId: "tool-1", title: "Reading file", detail: "x", data: {} }, diff --git a/apps/server/src/provider/acp/AcpRuntimeModel.ts b/apps/server/src/provider/acp/AcpRuntimeModel.ts index 2e561c4cc328..8fd7af3c5610 100644 --- a/apps/server/src/provider/acp/AcpRuntimeModel.ts +++ b/apps/server/src/provider/acp/AcpRuntimeModel.ts @@ -316,6 +316,32 @@ function toolCallContentText(entry: EffectAcpSchema.ToolCallContent): string | u return entry.content.text; } +// Trim is used for display `text`, so whitespace-only (or whitespace-padded) entries never +// contribute to `chunks` and used to take the early returns with the original array. Bound +// each text entry independently so those paths cannot persist an unbounded terminal buffer +// on `toolCall.data.content` / `rawPayload`. +function boundToolCallContentEntries( + content: ReadonlyArray, +): ReadonlyArray { + let changed = false; + const bounded = content.map((entry) => { + const text = toolCallContentText(entry); + if (text === undefined || text.length <= TOOL_CALL_CONTENT_MAX_CHARS) { + return entry; + } + changed = true; + const trimmed = text.trim(); + return { + type: "content", + content: { + type: "text", + text: boundToolCallOutputText(trimmed.length > 0 ? trimmed : text), + }, + } as const; + }); + return changed ? bounded : content; +} + function extractTextContentFromToolCallContent( content: ReadonlyArray | null | undefined, ): ExtractedToolCallContent { @@ -330,31 +356,74 @@ function extractTextContentFromToolCallContent( } } if (chunks.length === 0) { - return { text: undefined, content }; + return { text: undefined, content: boundToolCallContentEntries(content) }; } const joined = chunks.join("\n"); if (joined.length <= TOOL_CALL_CONTENT_MAX_CHARS) { - return { text: joined, content }; + return { text: joined, content: boundToolCallContentEntries(content) }; } const bounded = boundToolCallOutputText(joined); - // Collapse the text entries into a single bounded one at the final contributing text entry, - // and leave every other entry kind (diffs, images, resource links) in its original relative - // order. The retained tail came from that text entry, so placing it there also preserves its - // ordering relative to interleaved non-text content and ignores later blank text entries. - const lastContributingTextIndex = content.reduce( - (lastIndex, entry, index) => (toolCallContentText(entry)?.trim() ? index : lastIndex), - -1, - ); - const boundedContent = content.flatMap((entry, index) => { + const tail = joined.slice(joined.length - TOOL_CALL_CONTENT_MAX_CHARS); + return { + text: bounded, + content: distributeRetainedTailAcrossContent(content, tail), + }; +} + +// Walk the original text entries from the joined tail window so a retained slice that +// spans entries around an image/diff stays on those entries. Non-text kinds keep their +// relative order; blank text entries are dropped; the truncation marker is prepended to +// the first remaining text entry. +function distributeRetainedTailAcrossContent( + content: ReadonlyArray, + tail: string, +): ReadonlyArray { + const textRanges: Array< + | { + readonly start: number; + readonly end: number; + readonly text: string; + } + | undefined + > = Array.from({ length: content.length }); + let offset = 0; + let seenText = false; + for (const [index, entry] of content.entries()) { + const text = toolCallContentText(entry)?.trim(); + if (!text) { + continue; + } + if (seenText) { + offset += 1; + } + seenText = true; + const start = offset; + const end = offset + text.length; + textRanges[index] = { start, end, text }; + offset = end; + } + const tailStart = Math.max(0, offset - tail.length); + let markerPending = true; + return content.flatMap((entry, index) => { if (toolCallContentText(entry) === undefined) { return [entry]; } - if (index !== lastContributingTextIndex) { + const range = textRanges[index]; + if (range === undefined) { + return []; + } + const overlapStart = Math.max(range.start, tailStart); + const overlapEnd = Math.min(range.end, offset); + if (overlapEnd <= overlapStart) { return []; } - return [{ type: "content", content: { type: "text", text: bounded } } as const]; + let piece = range.text.slice(overlapStart - range.start, overlapEnd - range.start); + if (markerPending) { + piece = `${TOOL_CALL_CONTENT_TRUNCATION_MARKER}${piece}`; + markerPending = false; + } + return [{ type: "content", content: { type: "text", text: piece } } as const]; }); - return { text: bounded, content: boundedContent }; } function normalizeToolKind(kind: unknown): string | undefined { @@ -518,6 +587,42 @@ export interface AcpToolCallEmitDecision { readonly skippedSinceEmit: number; } +function toolCallOutputUnchanged(previous: AcpToolCallState, next: AcpToolCallState): boolean { + return ( + previous.data.content === next.data.content && previous.data.rawOutput === next.data.rawOutput + ); +} + +// Command tools keep `detail` equal to the command, so live stdout lives on +// `data.content` / `data.rawOutput`. Measure that too, otherwise coalescing never +// sees growth and in-progress output is held until completed/failed. +export function toolCallProgressLength(state: AcpToolCallState): number { + let contentChars = 0; + const content = state.data.content; + if (Array.isArray(content)) { + for (const entry of content) { + if (!isRecord(entry)) { + continue; + } + const text = toolCallContentText(entry as EffectAcpSchema.ToolCallContent); + if (text) { + contentChars += text.length; + } + } + } + let rawOutputChars = 0; + const rawOutput = state.data.rawOutput; + if (isRecord(rawOutput)) { + for (const field of RAW_OUTPUT_TEXT_FIELDS) { + const value = rawOutput[field]; + if (typeof value === "string") { + rawOutputChars += value.length; + } + } + } + return Math.max(state.detail?.length ?? 0, contentChars, rawOutputChars); +} + export function decideToolCallUpdateEmission( input: AcpToolCallEmitDecisionInput, ): AcpToolCallEmitDecision { @@ -525,19 +630,16 @@ export function decideToolCallUpdateEmission( if (next.status === "completed" || next.status === "failed") { return { emit: true, skippedSinceEmit: 0 }; } - if (!next.detail) { - return { emit: false, skippedSinceEmit }; - } - if (previous === undefined || previous.title !== next.title) { + if (previous === undefined || previous.title !== next.title || previous.status !== next.status) { return { emit: true, skippedSinceEmit: 0 }; } - if (previous.detail === next.detail) { + if (previous.detail === next.detail && toolCallOutputUnchanged(previous, next)) { return { emit: false, skippedSinceEmit }; } + const progressLength = toolCallProgressLength(next); const grewMeaningfully = lastEmittedDetailLength === undefined || - Math.abs(next.detail.length - lastEmittedDetailLength) >= - TOOL_CALL_UPDATE_MIN_DETAIL_GROWTH_CHARS; + Math.abs(progressLength - lastEmittedDetailLength) >= TOOL_CALL_UPDATE_MIN_DETAIL_GROWTH_CHARS; if (grewMeaningfully || skippedSinceEmit + 1 >= TOOL_CALL_UPDATE_COALESCE_LIMIT) { return { emit: true, skippedSinceEmit: 0 }; } diff --git a/apps/server/src/provider/acp/AcpSessionRuntime.ts b/apps/server/src/provider/acp/AcpSessionRuntime.ts index 0dcf72895fd8..2a4cb6a2337b 100644 --- a/apps/server/src/provider/acp/AcpSessionRuntime.ts +++ b/apps/server/src/provider/acp/AcpSessionRuntime.ts @@ -27,6 +27,7 @@ import { extractModelConfigId, findSessionConfigOption, mergeToolCallState, + toolCallProgressLength, parseSessionModeState, parseSessionUpdateEvent, sessionUpdateIsReplay, @@ -233,6 +234,7 @@ export class AcpSessionRuntime extends Context.Service< */ readonly setSessionModel: ( modelId: string, + meta?: EffectAcpSchema.SetSessionModelRequest["_meta"], ) => Effect.Effect; /** * Sends a generic ACP extension request and records it through the request logger. @@ -796,12 +798,13 @@ export const make = ( Effect.flatMap((started) => setConfigOption(started.modelConfigId ?? "model", model)), Effect.asVoid, ), - setSessionModel: (modelId) => + setSessionModel: (modelId, meta) => getStartedState.pipe( Effect.flatMap((started) => { const requestPayload = { sessionId: started.sessionId, modelId, + ...(meta !== undefined ? { _meta: meta } : {}), } satisfies EffectAcpSchema.SetSessionModelRequest; return runLoggedRequest( "session/set_model", @@ -893,7 +896,7 @@ const handleSessionUpdate = ({ next.set(nextToolCall.toolCallId, { state: nextToolCall, lastEmittedDetailLength: decision.emit - ? nextToolCall.detail?.length + ? toolCallProgressLength(nextToolCall) : tracked?.lastEmittedDetailLength, skippedSinceEmit: decision.skippedSinceEmit, }); diff --git a/apps/server/src/provider/acp/GrokAcpCliProbe.test.ts b/apps/server/src/provider/acp/GrokAcpCliProbe.test.ts index 222fc4a12d5b..ad6eaac1b521 100644 --- a/apps/server/src/provider/acp/GrokAcpCliProbe.test.ts +++ b/apps/server/src/provider/acp/GrokAcpCliProbe.test.ts @@ -1,6 +1,7 @@ /** * Optional integration check against a real `grok agent stdio` install. - * Enable with: T3_GROK_ACP_PROBE=1 bun run test GrokAcpCliProbe + * Enable with: T3_GROK_ACP_PROBE=1 vp test run GrokAcpCliProbe + * Set T3_GROK_LIVE_TURN=1 to also send a small prompt to the real model. * * The probe assumes either `XAI_API_KEY` is set in the environment or * the user has previously run `grok login`. Without credentials the @@ -10,6 +11,10 @@ import * as NodeServices from "@effect/platform-node/NodeServices"; import { it } from "@effect/vitest"; import * as Effect from "effect/Effect"; +import * as Deferred from "effect/Deferred"; +import * as Fiber from "effect/Fiber"; +import * as FileSystem from "effect/FileSystem"; +import * as Stream from "effect/Stream"; import { ChildProcessSpawner } from "effect/unstable/process"; import { describe, expect } from "vite-plus/test"; @@ -66,4 +71,60 @@ describe.runIf(process.env.T3_GROK_ACP_PROBE === "1")("Grok ACP CLI probe", () = yield* runtime.setSessionModel(currentModelId); }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), ); + + it.effect("session/set_model accepts advertised reasoning effort metadata", () => + Effect.gen(function* () { + const runtime = yield* makeProbeRuntime; + const started = yield* runtime.start(); + const modelState = started.sessionSetupResult.models; + const currentModelId = modelState?.currentModelId.trim(); + expect(currentModelId).toBeDefined(); + if (!currentModelId) return; + + const currentModel = modelState?.availableModels.find( + (model) => model.modelId.trim() === currentModelId, + ); + const reasoningEffort = currentModel?._meta?.reasoningEffort; + expect(typeof reasoningEffort).toBe("string"); + if (typeof reasoningEffort !== "string") return; + + yield* runtime.setSessionModel(currentModelId, { reasoningEffort }); + }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), + ); + + it.effect.skipIf(process.env.T3_GROK_LIVE_TURN !== "1")( + "finishes a real Grok turn and streams its answer", + () => + Effect.gen(function* () { + const fileSystem = yield* FileSystem.FileSystem; + const cwd = yield* fileSystem.makeTempDirectoryScoped(); + const childProcessSpawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const runtime = yield* makeGrokAcpRuntime({ + grokSettings: { binaryPath: "grok" }, + environment: process.env, + childProcessSpawner, + cwd, + runtimeMode: "approval-required", + clientInfo: { name: "t3-grok-probe", version: "0.0.0" }, + }); + yield* runtime.start(); + const chunks: string[] = []; + const events = yield* Stream.runForEach(runtime.getEvents(), (event) => { + if (event._tag === "EventStreamBarrier") { + return Deferred.succeed(event.acknowledge, undefined); + } + if (event._tag === "ContentDelta") { + chunks.push(event.text); + } + return Effect.void; + }).pipe(Effect.forkChild); + const result = yield* runtime.prompt({ + prompt: [{ type: "text", text: "Reply exactly GROK_T3_OK. Do not use any tools." }], + }); + yield* runtime.drainEvents; + expect(result.stopReason).toBe("end_turn"); + expect(chunks.join("")).toContain("GROK_T3_OK"); + yield* Fiber.interrupt(events); + }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), + ); }); diff --git a/apps/server/src/provider/acp/GrokAcpSupport.test.ts b/apps/server/src/provider/acp/GrokAcpSupport.test.ts index 02d60976b24c..a85f7174a1c0 100644 --- a/apps/server/src/provider/acp/GrokAcpSupport.test.ts +++ b/apps/server/src/provider/acp/GrokAcpSupport.test.ts @@ -5,6 +5,8 @@ import * as EffectAcpErrors from "effect-acp/errors"; import { applyGrokAcpModelSelection, buildGrokAcpSpawnInput, + grokAcpSpawnArgs, + isValidGrokReasoningEffortToken, resolveGrokAcpBaseModelId, } from "./GrokAcpSupport.ts"; @@ -16,6 +18,35 @@ describe("resolveGrokAcpBaseModelId", () => { }); }); +describe("grokAcpSpawnArgs", () => { + it("inherits the Grok CLI config when no T3 runtime mode is set", () => { + expect(grokAcpSpawnArgs()).toEqual(["agent", "stdio"]); + }); + + it("forces Grok to ask when T3 is Supervised", () => { + expect(grokAcpSpawnArgs("approval-required")).toEqual([ + "--permission-mode", + "default", + "agent", + "stdio", + ]); + }); + + it("maps Full access to Grok always-approve", () => { + expect(grokAcpSpawnArgs("full-access")).toEqual(["agent", "--always-approve", "stdio"]); + }); + + it("maps Auto-accept edits and Auto onto Grok permission modes", () => { + expect(grokAcpSpawnArgs("auto-accept-edits")).toEqual([ + "--permission-mode", + "acceptEdits", + "agent", + "stdio", + ]); + expect(grokAcpSpawnArgs("auto")).toEqual(["--permission-mode", "auto", "agent", "stdio"]); + }); +}); + describe("buildGrokAcpSpawnInput", () => { it("passes the T3 Code referrer through Grok OAuth env", () => { const spawn = buildGrokAcpSpawnInput({ binaryPath: "/usr/local/bin/grok" }, "/tmp/project", { @@ -33,15 +64,38 @@ describe("buildGrokAcpSpawnInput", () => { }, }); }); + + it("puts Supervised on the Grok argv so config always-approve cannot win", () => { + const spawn = buildGrokAcpSpawnInput( + { binaryPath: "/usr/local/bin/grok" }, + "/tmp/project", + undefined, + "approval-required", + ); + expect(spawn.args).toEqual(["--permission-mode", "default", "agent", "stdio"]); + }); +}); + +describe("isValidGrokReasoningEffortToken", () => { + it("accepts future ACP tokens and rejects malformed metadata values", () => { + expect(isValidGrokReasoningEffortToken("xhigh")).toBe(true); + expect(isValidGrokReasoningEffortToken("turbo_v2")).toBe(true); + expect(isValidGrokReasoningEffortToken("not a token")).toBe(false); + expect(isValidGrokReasoningEffortToken("-leading-dash")).toBe(false); + expect(isValidGrokReasoningEffortToken("x".repeat(33))).toBe(false); + }); }); describe("applyGrokAcpModelSelection", () => { const makeRecordingRuntime = (failure?: EffectAcpErrors.AcpError) => { - const modelCalls: Array = []; + const modelCalls: Array<{ + modelId: string; + meta?: { readonly [key: string]: unknown } | null; + }> = []; const runtime = { - setSessionModel: (modelId: string) => + setSessionModel: (modelId: string, meta?: { readonly [key: string]: unknown } | null) => Effect.gen(function* () { - modelCalls.push(modelId); + modelCalls.push(meta === undefined ? { modelId } : { modelId, meta }); if (failure) return yield* failure; return {}; }), @@ -58,11 +112,58 @@ describe("applyGrokAcpModelSelection", () => { requestedModelId: "grok-mock-alt", mapError: (cause) => cause.message, }); - expect(modelCalls).toEqual(["grok-mock-alt"]); + expect(modelCalls).toEqual([{ modelId: "grok-mock-alt" }]); expect(result).toBe("grok-mock-alt"); }), ); + it.effect("applies reasoning effort through session/set_model metadata", () => + Effect.gen(function* () { + const { runtime, modelCalls } = makeRecordingRuntime(); + const result = yield* applyGrokAcpModelSelection({ + runtime, + currentModelId: "grok-4.6", + currentReasoningEffort: "high", + requestedModelId: "grok-4.6", + requestedReasoningEffort: "xhigh", + mapError: (cause) => cause.message, + }); + expect(modelCalls).toEqual([{ modelId: "grok-4.6", meta: { reasoningEffort: "xhigh" } }]); + expect(result).toBe("grok-4.6"); + }), + ); + + it.effect("does not clear reasoning when same-model selection omits effort", () => + Effect.gen(function* () { + const { runtime, modelCalls } = makeRecordingRuntime(); + const result = yield* applyGrokAcpModelSelection({ + runtime, + currentModelId: "grok-4.6", + currentReasoningEffort: "high", + requestedModelId: "grok-4.6", + requestedReasoningEffort: undefined, + mapError: (cause) => cause.message, + }); + expect(modelCalls).toEqual([]); + expect(result).toBe("grok-4.6"); + }), + ); + + it.effect("drops malformed effort metadata instead of sending it", () => + Effect.gen(function* () { + const { runtime, modelCalls } = makeRecordingRuntime(); + yield* applyGrokAcpModelSelection({ + runtime, + currentModelId: "grok-4.6", + currentReasoningEffort: "high", + requestedModelId: "grok-4.6", + requestedReasoningEffort: "not a token", + mapError: (cause) => cause.message, + }); + expect(modelCalls).toEqual([{ modelId: "grok-4.6" }]); + }), + ); + it.effect("skips set_model when requested matches current", () => Effect.gen(function* () { const { runtime, modelCalls } = makeRecordingRuntime(); diff --git a/apps/server/src/provider/acp/GrokAcpSupport.ts b/apps/server/src/provider/acp/GrokAcpSupport.ts index c928b3ed80e0..001f0adfe7b8 100644 --- a/apps/server/src/provider/acp/GrokAcpSupport.ts +++ b/apps/server/src/provider/acp/GrokAcpSupport.ts @@ -1,4 +1,4 @@ -import { type GrokSettings, ProviderDriverKind } from "@t3tools/contracts"; +import { type GrokSettings, ProviderDriverKind, type RuntimeMode } from "@t3tools/contracts"; import * as Crypto from "effect/Crypto"; import * as Effect from "effect/Effect"; import * as Layer from "effect/Layer"; @@ -27,16 +27,33 @@ interface GrokAcpRuntimeInput extends Omit< readonly childProcessSpawner: ChildProcessSpawner.ChildProcessSpawner["Service"]; readonly grokSettings: GrokAcpRuntimeGrokSettings | null | undefined; readonly environment?: NodeJS.ProcessEnv; + readonly runtimeMode?: RuntimeMode; +} + +export function grokAcpSpawnArgs(runtimeMode?: RuntimeMode): ReadonlyArray { + switch (runtimeMode) { + case "approval-required": + return ["--permission-mode", "default", "agent", "stdio"]; + case "auto-accept-edits": + return ["--permission-mode", "acceptEdits", "agent", "stdio"]; + case "auto": + return ["--permission-mode", "auto", "agent", "stdio"]; + case "full-access": + return ["agent", "--always-approve", "stdio"]; + default: + return ["agent", "stdio"]; + } } export function buildGrokAcpSpawnInput( grokSettings: GrokAcpRuntimeGrokSettings | null | undefined, cwd: string, environment?: NodeJS.ProcessEnv, + runtimeMode?: RuntimeMode, ): AcpSessionRuntime.AcpSpawnInput { return { command: grokSettings?.binaryPath || "grok", - args: ["agent", "stdio"], + args: [...grokAcpSpawnArgs(runtimeMode)], cwd, env: { ...environment, @@ -62,7 +79,12 @@ export const makeGrokAcpRuntime = ( const acpContext = yield* Layer.build( AcpSessionRuntime.layer({ ...input, - spawn: buildGrokAcpSpawnInput(input.grokSettings, input.cwd, input.environment), + spawn: buildGrokAcpSpawnInput( + input.grokSettings, + input.cwd, + input.environment, + input.runtimeMode, + ), authMethodId: resolveGrokAuthMethodId(input.environment), }).pipe( Layer.provide( @@ -82,6 +104,17 @@ export function resolveGrokAcpBaseModelId(model: string | null | undefined): str return normalizeModelSlug(base, GROK_DRIVER_KIND) ?? "grok-build"; } +const GROK_REASONING_EFFORT_TOKEN = /^[a-z0-9][a-z0-9._-]{0,31}$/i; + +export function isValidGrokReasoningEffortToken(value: string): boolean { + return GROK_REASONING_EFFORT_TOKEN.test(value); +} + +export function normalizeGrokReasoningEffort(value: string | undefined): string | undefined { + const effort = value?.trim(); + return effort && isValidGrokReasoningEffortToken(effort) ? effort : undefined; +} + export function currentGrokModelIdFromSessionSetup( sessionSetupResult: | EffectAcpSchema.LoadSessionResponse @@ -91,18 +124,57 @@ export function currentGrokModelIdFromSessionSetup( return sessionSetupResult.models?.currentModelId?.trim() || undefined; } +export function currentGrokReasoningEffortFromSessionSetup( + sessionSetupResult: + | EffectAcpSchema.LoadSessionResponse + | EffectAcpSchema.NewSessionResponse + | EffectAcpSchema.ResumeSessionResponse, +): string | undefined { + const modelState = sessionSetupResult.models; + if (!modelState) { + return undefined; + } + const currentModelId = modelState.currentModelId.trim(); + if (currentModelId.length === 0) { + return undefined; + } + const currentModel = modelState.availableModels.find( + (model) => model.modelId.trim() === currentModelId, + ); + const reasoningEffort = currentModel?._meta?.reasoningEffort; + return typeof reasoningEffort === "string" + ? normalizeGrokReasoningEffort(reasoningEffort) + : undefined; +} + export function applyGrokAcpModelSelection(input: { readonly runtime: Pick; readonly currentModelId: string | undefined; + readonly currentReasoningEffort?: string | undefined; readonly requestedModelId: string | undefined; + readonly requestedReasoningEffort?: string | undefined; readonly mapError: (cause: EffectAcpErrors.AcpError) => E; }): Effect.Effect { - const shouldSwitchModel = + const modelChanged = input.requestedModelId !== undefined && input.requestedModelId !== input.currentModelId; - if (!shouldSwitchModel) { + const reasoningProvided = input.requestedReasoningEffort !== undefined; + const reasoningEffort = reasoningProvided + ? normalizeGrokReasoningEffort(input.requestedReasoningEffort) + : undefined; + const reasoningEffortChanged = + reasoningProvided && reasoningEffort !== input.currentReasoningEffort; + const targetModelId = input.requestedModelId ?? input.currentModelId; + if ((!modelChanged && !reasoningEffortChanged) || targetModelId === undefined) { return Effect.succeed(input.currentModelId); } + const reasoningMeta = + reasoningProvided && reasoningEffort !== undefined ? { reasoningEffort } : undefined; + // When reasoning was explicitly provided but invalid (normalize => undefined), we deliberately + // send no meta so the invalid value is dropped rather than forwarded. When reasoning was not + // provided at all, we also send no meta, but we only reach this call when the model itself + // changed - an omitted reasoning preference must not be treated as an explicit clear of the + // CLI-advertised default (e.g. Extra High) on same-model reselections. return input.runtime - .setSessionModel(input.requestedModelId) - .pipe(Effect.mapError(input.mapError), Effect.as(input.requestedModelId)); + .setSessionModel(targetModelId, reasoningMeta) + .pipe(Effect.mapError(input.mapError), Effect.as(targetModelId)); } diff --git a/apps/server/src/provider/acp/XAiAcpExtension.test.ts b/apps/server/src/provider/acp/XAiAcpExtension.test.ts index c435269fd76d..28f5f29f4987 100644 --- a/apps/server/src/provider/acp/XAiAcpExtension.test.ts +++ b/apps/server/src/provider/acp/XAiAcpExtension.test.ts @@ -1,4 +1,5 @@ // @effect-diagnostics nodeBuiltinImport:off +import * as NodeOS from "node:os"; import * as NodePath from "node:path"; import * as NodeURL from "node:url"; @@ -9,11 +10,17 @@ import * as Schema from "effect/Schema"; import { describe, expect } from "vite-plus/test"; import { + extractGrokPlanMarkdownFromToolCallData, extractXAiAskUserQuestions, + extractXAiExitPlanMarkdown, + isGrokPlanMarkdownPath, makeXAiAskUserQuestionCancelledResponse, makeXAiAskUserQuestionResponse, + makeXAiExitPlanModeCapturedResponse, makeXAiPromptCompletionRuntime, + XAI_EMPTY_PLAN_MARKDOWN, XAiAskUserQuestionRequest, + XAiExitPlanModeRequest, } from "./XAiAcpExtension.ts"; import * as AcpSessionRuntime from "./AcpSessionRuntime.ts"; @@ -299,6 +306,27 @@ describe("XAiAcpExtension", () => { }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), ); + it.effect("fails a hung standard prompt from an xAI rate-limit completion", () => + Effect.gen(function* () { + const runtime = yield* makePromptCompletionRuntime({ + T3_ACP_EMIT_XAI_RATE_LIMIT_THEN_HANG: "1", + }); + yield* runtime.start(); + + const error = yield* Effect.flip( + runtime.prompt({ + prompt: [{ type: "text", text: "hi" }], + }), + ); + + expect(error).toMatchObject({ + _tag: "AcpRequestError", + code: -32003, + errorMessage: "Grok usage limit reached. Try again later.", + }); + }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), + ); + it.effect("ignores stale xAI completion from an already settled prompt", () => Effect.gen(function* () { const runtime = yield* makePromptCompletionRuntime({ @@ -329,4 +357,170 @@ describe("XAiAcpExtension", () => { }); }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), ); + + it("extracts plan markdown from exit_plan_mode payloads", () => { + const decode = Schema.decodeUnknownSync(XAiExitPlanModeRequest); + const direct = decode({ + sessionId: "session-1", + toolCallId: "exit-1", + planContent: "# Plan\n\n- do the thing\n", + }); + expect(extractXAiExitPlanMarkdown(direct)).toBe("# Plan\n\n- do the thing"); + + const wrapped = decode({ + method: "_x.ai/exit_plan_mode", + params: { + sessionId: "session-1", + toolCallId: "exit-1", + planContent: null, + }, + }); + expect(extractXAiExitPlanMarkdown(wrapped, " # fallback plan ")).toBe("# fallback plan"); + expect(extractXAiExitPlanMarkdown(wrapped, "")).toBe(XAI_EMPTY_PLAN_MARKDOWN); + expect(extractXAiExitPlanMarkdown(wrapped)).toBe(XAI_EMPTY_PLAN_MARKDOWN); + }); + + it("builds an abandoned exit_plan_mode response that captures the plan", () => { + expect(makeXAiExitPlanModeCapturedResponse()).toEqual({ + outcome: "abandoned", + feedback: + "The client captured your proposed plan. Stop here and wait for the user's feedback or implementation request in a later turn.", + }); + }); + + it("identifies Grok plan.md paths and extracts markdown from tool call data", () => { + const linuxHost = { platform: "linux" as const, environment: {} }; + const windowsHost = { platform: "win32" as const, environment: {} }; + const grokHomeHost = { + platform: "linux" as const, + environment: { GROK_HOME: "/opt/grok-data" }, + }; + const home = NodeOS.homedir().replace(/\\/g, "/"); + const sessionPlan = `${home}/.grok/sessions/abc/plan.md`; + const nestedSessionPlan = `${home}/.grok/sessions/%2Fhome%2Fproj/019fd20e-c563-70a0-b801-a6bc51815a9b/plan.md`; + expect(isGrokPlanMarkdownPath(sessionPlan, linuxHost)).toBe(true); + expect(isGrokPlanMarkdownPath(nestedSessionPlan, linuxHost)).toBe(true); + expect(isGrokPlanMarkdownPath("~/.grok/sessions/abc/plan.md", linuxHost)).toBe(true); + expect(isGrokPlanMarkdownPath("/tmp/mock-home/.grok/sessions/sess/plan.md", linuxHost)).toBe( + true, + ); + expect(isGrokPlanMarkdownPath("/home/other/.grok/sessions/sess/plan.md", linuxHost)).toBe(true); + expect(isGrokPlanMarkdownPath("/HOME/other/.grok/sessions/sess/plan.md", linuxHost)).toBe( + false, + ); + expect(isGrokPlanMarkdownPath("C:/Users/other/.grok/sessions/id/plan.md", windowsHost)).toBe( + true, + ); + expect(isGrokPlanMarkdownPath("c:/users/OTHER/.GROK/SESSIONS/id/PLAN.MD", windowsHost)).toBe( + true, + ); + expect( + isGrokPlanMarkdownPath("C:\\Users\\other\\.grok\\sessions\\id\\plan.md", windowsHost), + ).toBe(true); + expect(isGrokPlanMarkdownPath("/opt/grok-data/sessions/sess/plan.md", grokHomeHost)).toBe(true); + expect( + isGrokPlanMarkdownPath("/OPT/GROK-DATA/sessions/sess/plan.md", { + platform: "win32", + environment: { GROK_HOME: "/opt/grok-data" }, + }), + ).toBe(true); + expect(isGrokPlanMarkdownPath("/OPT/GROK-DATA/sessions/sess/plan.md", grokHomeHost)).toBe( + false, + ); + // Workspace plan.md must not be treated as the session plan file. + expect(isGrokPlanMarkdownPath("plan.md", linuxHost)).toBe(false); + expect(isGrokPlanMarkdownPath("/repo/docs/plan.md", linuxHost)).toBe(false); + expect(isGrokPlanMarkdownPath("/tmp/other.md", linuxHost)).toBe(false); + expect(isGrokPlanMarkdownPath("/repo/.grok/sessions/example/plan.md", linuxHost)).toBe(false); + expect( + isGrokPlanMarkdownPath(`${home}/project/.grok/sessions/example/plan.md`, linuxHost), + ).toBe(false); + expect( + isGrokPlanMarkdownPath("/home/other/.grok/sessions/../../project/plan.md", linuxHost), + ).toBe(false); + expect( + isGrokPlanMarkdownPath("/home/other/.grok/sessions/foo/../../../project/plan.md", linuxHost), + ).toBe(false); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + rawInput: { + file_path: sessionPlan, + content: "# From rawInput\n\n- a\n", + }, + }, + linuxHost, + ), + ).toBe("# From rawInput\n\n- a"); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + content: [ + { + type: "diff", + path: sessionPlan, + oldText: "", + newText: "# From diff\n\n- b\n", + }, + ], + }, + linuxHost, + ), + ).toBe("# From diff\n\n- b"); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + rawInput: { file_path: sessionPlan, content: "" }, + content: [ + { + type: "diff", + path: sessionPlan, + oldText: "", + newText: "# From diff after empty rawInput\n", + }, + ], + }, + linuxHost, + ), + ).toBe("# From diff after empty rawInput"); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + rawInput: { file_path: sessionPlan, content: "" }, + }, + linuxHost, + ), + ).toBe(""); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + content: [{ type: "diff", path: sessionPlan, oldText: "# old", newText: "" }], + }, + linuxHost, + ), + ).toBe(""); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + rawInput: { file_path: "/tmp/readme.md", content: "nope" }, + }, + linuxHost, + ), + ).toBeUndefined(); + + expect( + extractGrokPlanMarkdownFromToolCallData( + { + rawInput: { file_path: "/repo/docs/plan.md", content: "# Project plan\n" }, + }, + linuxHost, + ), + ).toBeUndefined(); + }); }); diff --git a/apps/server/src/provider/acp/XAiAcpExtension.ts b/apps/server/src/provider/acp/XAiAcpExtension.ts index d36a5fcfc895..543edb39bb6d 100644 --- a/apps/server/src/provider/acp/XAiAcpExtension.ts +++ b/apps/server/src/provider/acp/XAiAcpExtension.ts @@ -1,8 +1,11 @@ +import * as NodeOS from "node:os"; + import type { ProviderUserInputAnswers, UserInputQuestion } from "@t3tools/contracts"; import * as Deferred from "effect/Deferred"; import * as Effect from "effect/Effect"; import * as Ref from "effect/Ref"; import * as Schema from "effect/Schema"; +import * as EffectAcpErrors from "effect-acp/errors"; import type * as EffectAcpSchema from "effect-acp/schema"; import type * as AcpSessionRuntime from "./AcpSessionRuntime.ts"; @@ -19,11 +22,15 @@ type XAiPromptCompleteNotification = typeof XAiPromptCompleteNotification.Type; interface PendingXAiPromptCompletion { readonly sessionId: string; readonly promptId: string; - readonly deferred: Deferred.Deferred; + readonly deferred: Deferred.Deferred< + EffectAcpSchema.PromptResponse, + EffectAcpErrors.AcpRequestError + >; } const completedXAiPromptIdLimit = 128; const xAiStopReasonMissingMetaKey = "xAiStopReasonMissing"; +const xAiRateLimitedErrorCode = -32003; const XAiAskUserQuestionOption = Schema.Struct({ label: Schema.String, @@ -196,6 +203,218 @@ export function makeXAiAskUserQuestionCancelledResponse(): XAiAskUserQuestionCan return { outcome: "cancelled" }; } +// --------------------------------------------------------------------------- +// x.ai/exit_plan_mode — plan approval gate (mirrors Grok Build TUI plan window) +// --------------------------------------------------------------------------- + +const XAiExitPlanModeParams = Schema.Struct({ + sessionId: Schema.String, + toolCallId: Schema.String, + planContent: Schema.optional(Schema.NullOr(Schema.String)), +}); + +const XAiWrappedExitPlanModeParams = Schema.Struct({ + method: Schema.Literals(["x.ai/exit_plan_mode", "_x.ai/exit_plan_mode"]), + params: XAiExitPlanModeParams, +}); + +export const XAiExitPlanModeRequest = Schema.Union([ + XAiExitPlanModeParams, + XAiWrappedExitPlanModeParams, +]); + +type XAiExitPlanModeRequestParams = typeof XAiExitPlanModeParams.Type; +type XAiExitPlanModeRequest = typeof XAiExitPlanModeRequest.Type; + +function unwrapExitPlanModeParams(params: XAiExitPlanModeRequest): XAiExitPlanModeRequestParams { + return "params" in params ? params.params : params; +} + +/** Empty-state copy when Grok exits plan mode without a plan file. */ +export const XAI_EMPTY_PLAN_MARKDOWN = + "# No plan written yet\n\n(The agent exited plan mode without writing a plan.)"; + +export function extractXAiExitPlanMarkdown( + params: XAiExitPlanModeRequest, + fallback?: string | null, +): string { + const content = unwrapExitPlanModeParams(params).planContent; + const fromRequest = typeof content === "string" ? trimmed(content) : undefined; + if (fromRequest) { + return fromRequest; + } + const fromFallback = fallback?.trim(); + if (fromFallback && fromFallback.length > 0) { + return fromFallback; + } + return XAI_EMPTY_PLAN_MARKDOWN; +} + +export type XAiExitPlanModeOutcome = "approved" | "abandoned" | "request_changes"; + +export interface XAiExitPlanModeResponse { + readonly outcome: XAiExitPlanModeOutcome; + readonly feedback?: string; +} + +/** + * Client captured the plan for T3's proposed-plan card. Abandon the native + * Grok plan-approval gate so the turn unblocks; the user implements via T3 UI. + */ +export function makeXAiExitPlanModeCapturedResponse(feedback?: string): XAiExitPlanModeResponse { + return { + outcome: "abandoned", + feedback: + feedback ?? + "The client captured your proposed plan. Stop here and wait for the user's feedback or implementation request in a later turn.", + }; +} + +function normalizeFsPath(value: string): string { + return value.trim().replace(/\\/g, "/").replace(/\/+$/, ""); +} + +function pathHasTraversalSegment(normalized: string): boolean { + return normalized.split("/").includes(".."); +} + +function addGrokSessionPrefix( + prefixes: Set, + homeOrRoot: string, + nestedGrokDir: boolean, +): void { + const root = normalizeFsPath(homeOrRoot); + if (!root) { + return; + } + prefixes.add(nestedGrokDir ? `${root}/.grok/sessions/` : `${root}/sessions/`); +} + +/** Injected host bits so these helpers stay off `process.platform` / `process.env`. */ +export interface GrokPlanPathHost { + readonly platform: NodeJS.Platform; + readonly environment: NodeJS.ProcessEnv; +} + +function grokPlanSessionPrefixes(environment: NodeJS.ProcessEnv): ReadonlySet { + const prefixes = new Set(); + addGrokSessionPrefix(prefixes, NodeOS.homedir(), true); + addGrokSessionPrefix(prefixes, "~", true); + addGrokSessionPrefix(prefixes, environment.HOME ?? "", true); + addGrokSessionPrefix(prefixes, environment.USERPROFILE ?? "", true); + // ACP mock and isolated Grok spawns use a HOME that is not the server process home. + addGrokSessionPrefix(prefixes, "/tmp/mock-home", true); + const grokHome = environment.GROK_HOME ?? ""; + addGrokSessionPrefix(prefixes, grokHome, false); + addGrokSessionPrefix(prefixes, grokHome, true); + return prefixes; +} + +const CANONICAL_HOME_GROK_SESSION_PATH = + /^(?:\/home\/[^/]+|\/Users\/[^/]+|[a-zA-Z]:\/Users\/[^/]+)\/\.grok\/sessions\/(?:[^/]+\/)+plan\.md$/; +const CASE_INSENSITIVE_CANONICAL_HOME_GROK_SESSION_PATH = new RegExp( + CANONICAL_HOME_GROK_SESSION_PATH.source, + "i", +); + +/** + * True when a path is Grok's session plan file under a Grok home + * (`~/.grok/sessions/.../plan.md`, `$HOME/.grok/sessions/...`, or `$GROK_HOME/sessions/...`). + * Deliberately does not match workspace files named `plan.md` (e.g. docs/plan.md + * or a repo-local `.grok/sessions/.../plan.md`). + */ +export function isGrokPlanMarkdownPath( + path: string | undefined | null, + host: GrokPlanPathHost, +): boolean { + if (typeof path !== "string") { + return false; + } + const normalized = path.trim().replace(/\\/g, "/"); + const win32 = host.platform === "win32"; + const haystack = win32 ? normalized.toLowerCase() : normalized; + if ( + normalized.length === 0 || + !haystack.endsWith("/plan.md") || + pathHasTraversalSegment(normalized) + ) { + return false; + } + for (const prefix of grokPlanSessionPrefixes(host.environment)) { + const needle = win32 ? prefix.toLowerCase() : prefix; + if (!haystack.startsWith(needle)) { + continue; + } + const rest = haystack.slice(needle.length); + // Session layout: /.grok/sessions///plan.md + if (rest !== "plan.md" && rest.endsWith("plan.md")) { + return true; + } + } + return ( + win32 ? CASE_INSENSITIVE_CANONICAL_HOME_GROK_SESSION_PATH : CANONICAL_HOME_GROK_SESSION_PATH + ).test(haystack); +} + +/** + * Extract plan markdown from a Grok write/edit tool call targeting plan.md. + * Used so T3 can show the plan while plan mode is still active (before exit). + */ +export function extractGrokPlanMarkdownFromToolCallData( + data: Record | undefined, + host: GrokPlanPathHost, +): string | undefined { + if (!data) { + return undefined; + } + + let sawPlanWrite = false; + const takePlanText = ( + value: string | undefined, + filePath: string | undefined, + ): string | undefined => { + if (!isGrokPlanMarkdownPath(filePath, host) || value === undefined) { + return undefined; + } + sawPlanWrite = true; + const trimmed = value.trim(); + return trimmed.length > 0 ? trimmed : undefined; + }; + + const rawInput = data.rawInput; + if (isRecord(rawInput)) { + const filePath = + (typeof rawInput.file_path === "string" ? rawInput.file_path : undefined) ?? + (typeof rawInput.path === "string" ? rawInput.path : undefined); + const content = typeof rawInput.content === "string" ? rawInput.content : undefined; + const fromRaw = takePlanText(content, filePath); + if (fromRaw !== undefined) { + return fromRaw; + } + } + + const content = data.content; + if (Array.isArray(content)) { + for (const block of content) { + if (!isRecord(block) || block.type !== "diff") { + continue; + } + const path = typeof block.path === "string" ? block.path : undefined; + const newText = typeof block.newText === "string" ? block.newText : undefined; + const fromDiff = takePlanText(newText, path); + if (fromDiff !== undefined) { + return fromDiff; + } + } + } + + return sawPlanWrite ? "" : undefined; +} + +function isRecord(value: unknown): value is Record { + return typeof value === "object" && value !== null && !Array.isArray(value); +} + /** * Adds Grok's private prompt-completion fallback around a standards-only ACP runtime. * The underlying runtime remains unaware of xAI methods and metadata. @@ -278,7 +497,7 @@ const registerXAiPromptCompletionFallback = ( sessionId: string, promptId: string, ) => - Deferred.make().pipe( + Deferred.make().pipe( Effect.tap((deferred) => Ref.update(pendingRef, (pending) => [...pending, { sessionId, promptId, deferred }]), ), @@ -287,7 +506,7 @@ const registerXAiPromptCompletionFallback = ( const unregisterXAiPromptCompletionFallback = ( pendingRef: Ref.Ref>, - deferred: Deferred.Deferred, + deferred: Deferred.Deferred, ) => Ref.update(pendingRef, (pending) => pending.filter((entry) => entry.deferred !== deferred)); const abortPendingPromptCompletions = ( @@ -358,13 +577,48 @@ const resolveXAiPromptCompletionFallback = ({ return [Effect.void, pending] as const; } return [ - Deferred.succeed(entry.deferred, promptResponseFromXAi(notification)).pipe(Effect.asVoid), + settleXAiPromptCompletion(entry.deferred, notification), [...pending.slice(0, index), ...pending.slice(index + 1)], ] as const; }).pipe(Effect.flatten); }), ); +const settleXAiPromptCompletion = ( + deferred: Deferred.Deferred, + notification: XAiPromptCompleteNotification, +) => { + if (notification.stopReason === "rate_limit") { + return Deferred.fail( + deferred, + new EffectAcpErrors.AcpRequestError({ + code: xAiRateLimitedErrorCode, + errorMessage: "Grok usage limit reached. Try again later.", + }), + ).pipe(Effect.asVoid); + } + if (notification.stopReason === "error") { + return Deferred.fail( + deferred, + EffectAcpErrors.AcpRequestError.internalError( + xAiAgentResultMessage(notification.agentResult) ?? "Grok prompt failed.", + ), + ).pipe(Effect.asVoid); + } + return Deferred.succeed(deferred, promptResponseFromXAi(notification)).pipe(Effect.asVoid); +}; + +function xAiAgentResultMessage(value: unknown): string | undefined { + if (typeof value === "string") { + return trimmed(value); + } + if (value === null || typeof value !== "object") { + return undefined; + } + const message = "message" in value ? value.message : undefined; + return typeof message === "string" ? trimmed(message) : undefined; +} + const rememberCompletedXAiPromptId = ( completedPromptIdsRef: Ref.Ref>, response: EffectAcpSchema.PromptResponse, diff --git a/apps/server/src/terminal/PtyAdapter.test.ts b/apps/server/src/terminal/PtyAdapter.test.ts deleted file mode 100644 index f4ac9516537d..000000000000 --- a/apps/server/src/terminal/PtyAdapter.test.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { assert, describe, it } from "@effect/vitest"; -import * as Schema from "effect/Schema"; - -import * as PtyAdapter from "./PtyAdapter.ts"; - -const isPtySpawnError = Schema.is(PtyAdapter.PtySpawnError); - -describe("PtySpawnError", () => { - it("derives messages from structural context while preserving the full cause chain", () => { - const spawnCause = new Error("spawn /bin/zsh ENOENT"); - const adapterError = new PtyAdapter.PtySpawnError({ - adapter: "node-pty", - shell: "/bin/zsh", - cause: spawnCause, - }); - const managerError = new PtyAdapter.PtySpawnError({ - adapter: "terminal-manager", - attemptedShells: ["/bin/zsh -o nopromptsp", "/bin/bash"], - cause: adapterError, - }); - - assert(isPtySpawnError(managerError)); - assert.strictEqual( - managerError.message, - "Failed to spawn PTY process with terminal-manager. Tried shells: /bin/zsh -o nopromptsp, /bin/bash.", - ); - assert.strictEqual( - adapterError.message, - "Failed to spawn PTY process '/bin/zsh' with node-pty.", - ); - assert.strictEqual(managerError.cause, adapterError); - assert.strictEqual(adapterError.cause, spawnCause); - }); -}); diff --git a/apps/server/src/textGeneration/GrokTextGeneration.ts b/apps/server/src/textGeneration/GrokTextGeneration.ts index 90e71faf94f6..e8be60dcde9a 100644 --- a/apps/server/src/textGeneration/GrokTextGeneration.ts +++ b/apps/server/src/textGeneration/GrokTextGeneration.ts @@ -7,6 +7,7 @@ import { ChildProcessSpawner } from "effect/unstable/process"; import type * as EffectAcpErrors from "effect-acp/errors"; import { type GrokSettings, type ModelSelection } from "@t3tools/contracts"; +import { getModelSelectionStringOptionValue } from "@t3tools/shared/model"; import { extractJsonObject } from "@t3tools/shared/schemaJson"; import { TextGenerationError } from "@t3tools/contracts"; @@ -14,6 +15,7 @@ import { makeStandardTextGeneration } from "./makeStandardTextGeneration.ts"; import { applyGrokAcpModelSelection, currentGrokModelIdFromSessionSetup, + currentGrokReasoningEffortFromSessionSetup, makeGrokAcpRuntime, resolveGrokAcpBaseModelId, } from "../provider/acp/GrokAcpSupport.ts"; @@ -71,10 +73,18 @@ export const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(functi const promptResult = yield* Effect.gen(function* () { const started = yield* runtime.start(); + const requestedReasoningEffort = getModelSelectionStringOptionValue( + modelSelection, + "reasoningEffort", + ); yield* applyGrokAcpModelSelection({ runtime, currentModelId: currentGrokModelIdFromSessionSetup(started.sessionSetupResult), + currentReasoningEffort: currentGrokReasoningEffortFromSessionSetup( + started.sessionSetupResult, + ), requestedModelId: resolvedModel, + requestedReasoningEffort, mapError: (cause) => new TextGenerationError({ operation, diff --git a/apps/server/src/usage/UsageService.ts b/apps/server/src/usage/UsageService.ts index 0bf131ac973b..224662e9dca7 100644 --- a/apps/server/src/usage/UsageService.ts +++ b/apps/server/src/usage/UsageService.ts @@ -1,9 +1,9 @@ /** * UsageService - scans provider transcripts and returns priced usage buckets. * - * The scan reads the provider CLIs' own session files rather than T3 Code's - * orchestration projections, so usage covers turns driven outside T3 Code too. - * This is the approach `ccusage` takes. + * The scan reads the provider CLIs' own session files (Claude Code, Codex, and + * Grok Build) rather than T3 Code's orchestration projections, so usage covers + * turns driven outside T3 Code too. This is the approach `ccusage` takes. * * Transcripts are append-only, so parsed records are memoised per file by * `(size, mtime)`. A cold 30-day scan of ~1.4 GB lands around 2-3 seconds; warm @@ -21,6 +21,7 @@ import { type UsageSummaryInput, UsageReadError, } from "@t3tools/contracts"; +import { HostProcessEnvironment } from "@t3tools/shared/hostProcess"; import * as Cause from "effect/Cause"; import * as Clock from "effect/Clock"; import * as Context from "effect/Context"; @@ -34,6 +35,7 @@ import * as Schema from "effect/Schema"; import { HttpClient, HttpClientResponse } from "effect/unstable/http"; import { ServerConfig } from "../config.ts"; +import { expandHomePath } from "../pathExpansion.ts"; import * as ServerSettings from "../serverSettings.ts"; import { resolveClaudeHomePath } from "../provider/Drivers/ClaudeHome.ts"; import { resolveCodexHomeLayout } from "../provider/Drivers/CodexHomeLayout.ts"; @@ -123,6 +125,7 @@ export const make = Effect.gen(function* () { const config = yield* ServerConfig; const settingsService = yield* ServerSettings.ServerSettingsService; const httpClient = yield* HttpClient.HttpClient; + const hostEnvironment = yield* HostProcessEnvironment; const fileCache: ScanCache = new Map(); let cacheDirty = false; @@ -218,10 +221,22 @@ export const make = Effect.gen(function* () { const claudeHome = yield* resolveClaudeHomePath(settings.providers.claudeAgent); const claudeDir = yield* resolveClaudeTranscriptDir(claudeHome); const codexLayout = yield* resolveCodexHomeLayout(settings.providers.codex); + // Grok Settings only expose the binary path; home is `$GROK_HOME` or `~/.grok`. + // Empty/whitespace GROK_HOME must fall back: coalescing alone would scan cwd. + const grokHomeEnv = hostEnvironment["GROK_HOME"]?.trim() ?? ""; + const grokHome = + grokHomeEnv.length > 0 + ? path.resolve(expandHomePath(grokHomeEnv)) + : path.join(NodeOS.homedir(), ".grok"); return [ { provider: "claude" as const, dir: claudeDir }, { provider: "codex" as const, dir: path.join(codexLayout.sharedHomePath, "sessions") }, + { + provider: "grok" as const, + dir: path.join(grokHome, "sessions"), + fileName: "updates.jsonl", + }, ]; }); @@ -353,7 +368,7 @@ export const make = Effect.gen(function* () { const livePaths = new Set(); const walkedRoots: string[] = []; - for (const { provider, dir } of dirs) { + for (const { provider, dir, fileName } of dirs) { const volumeId = yield* Effect.promise(() => readDirectoryVolumeId(dir)); const exists = yield* fileSystem .exists(dir) @@ -373,7 +388,9 @@ export const make = Effect.gen(function* () { } walkedRoots.push(dir); - const files = yield* Effect.promise(() => listTranscriptFiles(dir, windowStartMs)); + const files = yield* Effect.promise(() => + listTranscriptFiles(dir, windowStartMs, fileName === undefined ? undefined : { fileName }), + ); let scannedFiles = 0; let skippedFiles = 0; // Distinct per directory. Buckets carry per-cell session counts, but a diff --git a/apps/server/src/usage/usageScanCache.test.ts b/apps/server/src/usage/usageScanCache.test.ts index 64673e96c090..1f0365f3e7d9 100644 --- a/apps/server/src/usage/usageScanCache.test.ts +++ b/apps/server/src/usage/usageScanCache.test.ts @@ -42,12 +42,21 @@ describe("scan cache round trip", () => { ["/a.jsonl", 100, [record(), record({ dedupeKey: "msg_2:", model: "claude-opus-5" })]], ["/b.jsonl", 200, [record({ sessionId: "session-b", reportedCostUsd: 1.5 })]], ]); + original.set("/grok.jsonl", { + size: 40, + mtimeMs: 300, + provider: "grok", + records: [ + record({ provider: "grok", model: "grok-4.5-build", dedupeKey: "s:p:grok-4.5-build" }), + ], + }); const restored = decodeScanCache(JSON.parse(JSON.stringify(encodeScanCache(original)))); - expect(restored.size).toBe(2); + expect(restored.size).toBe(3); expect(restored.get("/a.jsonl")).toEqual(original.get("/a.jsonl")); expect(restored.get("/b.jsonl")).toEqual(original.get("/b.jsonl")); + expect(restored.get("/grok.jsonl")).toEqual(original.get("/grok.jsonl")); }); it("interns repeated model and session strings", () => { diff --git a/apps/server/src/usage/usageScanCache.ts b/apps/server/src/usage/usageScanCache.ts index cc15ee9cee62..02daf5ebbd70 100644 --- a/apps/server/src/usage/usageScanCache.ts +++ b/apps/server/src/usage/usageScanCache.ts @@ -134,7 +134,7 @@ export function decodeScanCache(document: unknown): ScanCache { if (typeof raw !== "object" || raw === null) continue; const entry = raw as Partial; if (typeof entry.s !== "number" || typeof entry.m !== "number") continue; - if (entry.p !== "claude" && entry.p !== "codex") continue; + if (entry.p !== "claude" && entry.p !== "codex" && entry.p !== "grok") continue; if (!isRecordArray(entry.r)) continue; const provider: UsageProviderKind = entry.p; diff --git a/apps/server/src/usage/usageTranscriptReader.ts b/apps/server/src/usage/usageTranscriptReader.ts index c72f0c24db65..33aef8fae25c 100644 --- a/apps/server/src/usage/usageTranscriptReader.ts +++ b/apps/server/src/usage/usageTranscriptReader.ts @@ -22,6 +22,7 @@ import { mightCarryUsage, parseClaudeLine, parseCodexLine, + parseGrokLine, type UsageRecord, } from "./usageTranscripts.ts"; @@ -37,12 +38,18 @@ export interface TranscriptFile { * Errors on individual entries are swallowed: session files rotate and get * removed while the walk is in flight, and a partial listing is far better than * failing the page. + * + * `fileName` restricts the walk to a single basename (Grok's `updates.jsonl`). + * Grok sessions also ship multi-megabyte `chat_history` and `events` logs that + * never carry usage, so the basename filter keeps a cold scan off those files. */ export async function listTranscriptFiles( root: string, sinceMs: number, + options?: { readonly fileName?: string }, ): Promise { const found: TranscriptFile[] = []; + const fileName = options?.fileName; const walk = async (dir: string): Promise => { let entries; @@ -57,7 +64,11 @@ export async function listTranscriptFiles( await walk(child); continue; } - if (!entry.name.endsWith(".jsonl")) continue; + if (fileName !== undefined) { + if (entry.name !== fileName) continue; + } else if (!entry.name.endsWith(".jsonl")) { + continue; + } try { const stats = await NodeFSP.stat(child); if (stats.mtimeMs >= sinceMs) { @@ -129,6 +140,12 @@ export async function readTranscriptRecords( continue; } + if (provider === "grok") { + if (!mightCarryUsage(line, provider)) continue; + for (const grokRecord of parseGrokLine(line)) records.push(grokRecord); + continue; + } + if (!mightCarryUsage(line, provider)) continue; const record = parseClaudeLine(line); if (record !== null) records.push(record); diff --git a/apps/server/src/usage/usageTranscripts.test.ts b/apps/server/src/usage/usageTranscripts.test.ts index 8f86a3d836bd..b09db613ed85 100644 --- a/apps/server/src/usage/usageTranscripts.test.ts +++ b/apps/server/src/usage/usageTranscripts.test.ts @@ -1,9 +1,11 @@ import { describe, expect, it } from "@effect/vitest"; import { + GROK_COST_USD_TICKS_PER_DOLLAR, initialCodexScanState, parseClaudeLine, parseCodexLine, + parseGrokLine, totalTokens, } from "./usageTranscripts.ts"; @@ -249,3 +251,316 @@ describe("totalTokens", () => { ).toBe(100); }); }); + +describe("parseGrokLine", () => { + /** Shaped after a real Grok Build `turn_completed` session update. */ + function turnCompleted(overrides?: { + sessionId?: string; + promptId?: string; + timestamp?: number; + agentTimestampMs?: number; + usage?: Record; + modelUsage?: Record> | null; + }): string { + const modelUsage = + overrides && "modelUsage" in overrides + ? overrides.modelUsage + : { + "grok-4.5-build": { + inputTokens: 20_272, + outputTokens: 272, + totalTokens: 20_544, + cachedReadTokens: 11_264, + cacheCreationTokens: 0, + reasoningTokens: 180, + costUsdTicks: 230_272_000, + }, + }; + + return JSON.stringify({ + timestamp: overrides?.timestamp ?? 1_786_372_566, + method: "_x.ai/session/update", + params: { + sessionId: overrides?.sessionId ?? "019fec1a-12f7-72f2-9b1f-7778a00aea3c", + update: { + sessionUpdate: "turn_completed", + prompt_id: overrides?.promptId ?? "prompt-1", + stop_reason: "end_turn", + usage: { + inputTokens: 20_272, + outputTokens: 272, + totalTokens: 20_544, + cachedReadTokens: 11_264, + cacheCreationTokens: 0, + reasoningTokens: 180, + costUsdTicks: 230_272_000, + ...(modelUsage === null ? {} : { modelUsage }), + ...overrides?.usage, + }, + }, + _meta: { + eventId: "event-1", + agentTimestampMs: overrides?.agentTimestampMs ?? 1_786_372_566_485, + }, + }, + }); + } + + it("extracts per-model totals and provider-reported cost ticks", () => { + const records = parseGrokLine(turnCompleted()); + + expect(records).toHaveLength(1); + const [record] = records; + expect(record?.provider).toBe("grok"); + expect(record?.model).toBe("grok-4.5-build"); + expect(record?.sessionId).toBe("019fec1a-12f7-72f2-9b1f-7778a00aea3c"); + expect(record?.timestampMs).toBe(1_786_372_566_485); + expect(record?.totals).toEqual({ + uncachedInputTokens: 20_272 - 11_264, + cachedInputTokens: 11_264, + cacheCreationTokens: 0, + outputTokens: 272, + reasoningTokens: 180, + }); + expect(record?.reportedCostUsd).toBeCloseTo(230_272_000 / GROK_COST_USD_TICKS_PER_DOLLAR, 12); + expect(record?.dedupeKey).toBe("019fec1a-12f7-72f2-9b1f-7778a00aea3c:prompt-1:grok-4.5-build"); + }); + + it("emits one record per model when modelUsage has several entries", () => { + const records = parseGrokLine( + turnCompleted({ + modelUsage: { + "grok-4.5": { + inputTokens: 1000, + outputTokens: 50, + cachedReadTokens: 400, + reasoningTokens: 20, + costUsdTicks: 50_000_000, + }, + "grok-composer-2.5-fast": { + inputTokens: 200, + outputTokens: 30, + cachedReadTokens: 100, + reasoningTokens: 0, + costUsdTicks: 10_000_000, + }, + }, + }), + ); + + expect(records.map((record) => record.model).toSorted()).toEqual([ + "grok-4.5", + "grok-composer-2.5-fast", + ]); + expect(records.every((record) => record.provider === "grok")).toBe(true); + expect(records.find((record) => record.model === "grok-4.5")?.reportedCostUsd).toBeCloseTo( + 0.005, + 12, + ); + }); + + it("inherits top-level cost ticks for a single model without its own ticks", () => { + const records = parseGrokLine( + turnCompleted({ + modelUsage: { + "grok-4.5-build": { + inputTokens: 1000, + outputTokens: 10, + cachedReadTokens: 0, + reasoningTokens: 0, + }, + }, + usage: { costUsdTicks: GROK_COST_USD_TICKS_PER_DOLLAR }, + }), + ); + + expect(records).toHaveLength(1); + expect(records[0]?.reportedCostUsd).toBe(1); + }); + + it("falls back to a generic grok model when modelUsage is absent", () => { + const records = parseGrokLine(turnCompleted({ modelUsage: null })); + + expect(records).toHaveLength(1); + const [record] = records; + expect(record?.provider).toBe("grok"); + expect(record?.model).toBe("grok"); + expect(record?.totals).toEqual({ + uncachedInputTokens: 20_272 - 11_264, + cachedInputTokens: 11_264, + cacheCreationTokens: 0, + outputTokens: 272, + reasoningTokens: 180, + }); + expect(record?.reportedCostUsd).toBeCloseTo(230_272_000 / GROK_COST_USD_TICKS_PER_DOLLAR, 12); + expect(record?.dedupeKey).toBe("019fec1a-12f7-72f2-9b1f-7778a00aea3c:prompt-1:grok"); + }); + + it("pro-rates top-level cost ticks across multi-model turns without per-model ticks", () => { + const records = parseGrokLine( + turnCompleted({ + modelUsage: { + "grok-4.5": { + inputTokens: 300, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + }, + "grok-composer-2.5-fast": { + inputTokens: 100, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + }, + }, + usage: { costUsdTicks: GROK_COST_USD_TICKS_PER_DOLLAR }, + }), + ); + + expect(records).toHaveLength(2); + const byModel = Object.fromEntries(records.map((record) => [record.model, record])); + expect(byModel["grok-4.5"]?.reportedCostUsd).toBeCloseTo(0.75, 12); + expect(byModel["grok-composer-2.5-fast"]?.reportedCostUsd).toBeCloseTo(0.25, 12); + const sum = + (byModel["grok-4.5"]?.reportedCostUsd ?? 0) + + (byModel["grok-composer-2.5-fast"]?.reportedCostUsd ?? 0); + expect(sum).toBeCloseTo(1, 12); + }); + + it("pro-rates aggregate cost when a zero-token sibling carries costUsdTicks: 0", () => { + const records = parseGrokLine( + turnCompleted({ + modelUsage: { + "grok-4.5": { + inputTokens: 300, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + }, + "grok-composer-2.5-fast": { + inputTokens: 100, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + }, + "empty-sibling": { + inputTokens: 0, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + costUsdTicks: 0, + }, + }, + usage: { costUsdTicks: GROK_COST_USD_TICKS_PER_DOLLAR }, + }), + ); + + expect(records).toHaveLength(2); + expect(records.every((record) => record.model !== "empty-sibling")).toBe(true); + const byModel = Object.fromEntries(records.map((record) => [record.model, record])); + expect(byModel["grok-4.5"]?.reportedCostUsd).toBeCloseTo(0.75, 12); + expect(byModel["grok-composer-2.5-fast"]?.reportedCostUsd).toBeCloseTo(0.25, 12); + const sum = + (byModel["grok-4.5"]?.reportedCostUsd ?? 0) + + (byModel["grok-composer-2.5-fast"]?.reportedCostUsd ?? 0); + expect(sum).toBeCloseTo(1, 12); + }); + + it("allocates leftover aggregate ticks to models that omit per-model ticks", () => { + const records = parseGrokLine( + turnCompleted({ + modelUsage: { + "grok-4.5": { + inputTokens: 300, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + costUsdTicks: 0.4 * GROK_COST_USD_TICKS_PER_DOLLAR, + }, + "grok-composer-2.5-fast": { + inputTokens: 100, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + }, + }, + usage: { costUsdTicks: GROK_COST_USD_TICKS_PER_DOLLAR }, + }), + ); + + expect(records).toHaveLength(2); + const byModel = Object.fromEntries(records.map((record) => [record.model, record])); + expect(byModel["grok-4.5"]?.reportedCostUsd).toBeCloseTo(0.4, 12); + expect(byModel["grok-composer-2.5-fast"]?.reportedCostUsd).toBeCloseTo(0.6, 12); + const sum = + (byModel["grok-4.5"]?.reportedCostUsd ?? 0) + + (byModel["grok-composer-2.5-fast"]?.reportedCostUsd ?? 0); + expect(sum).toBeCloseTo(1, 12); + }); + + it("does not invent a colliding dedupe key when prompt_id is missing", () => { + const line = JSON.stringify({ + timestamp: 1_786_372_566, + method: "_x.ai/session/update", + params: { + sessionId: "s1", + update: { + sessionUpdate: "turn_completed", + usage: { + inputTokens: 10, + outputTokens: 2, + modelUsage: { + "grok-4.5": { inputTokens: 10, outputTokens: 2 }, + }, + }, + }, + }, + }); + + expect(parseGrokLine(line)[0]?.dedupeKey).toBeNull(); + }); + + it("ignores non-turn lines and empty usage", () => { + expect(parseGrokLine(JSON.stringify({ method: "session/update", params: {} }))).toEqual([]); + expect(parseGrokLine("not json")).toEqual([]); + expect( + parseGrokLine( + turnCompleted({ + modelUsage: { + "grok-4.5-build": { + inputTokens: 0, + outputTokens: 0, + cachedReadTokens: 0, + reasoningTokens: 0, + costUsdTicks: 0, + }, + }, + }), + ), + ).toEqual([]); + }); + + it("falls back to the outer unix-seconds timestamp when agent meta is missing", () => { + const line = JSON.stringify({ + timestamp: 1_786_372_566, + method: "_x.ai/session/update", + params: { + sessionId: "s1", + update: { + sessionUpdate: "turn_completed", + prompt_id: "p1", + usage: { + inputTokens: 10, + outputTokens: 2, + modelUsage: { + "grok-4.5": { inputTokens: 10, outputTokens: 2 }, + }, + }, + }, + }, + }); + + const records = parseGrokLine(line); + expect(records[0]?.timestampMs).toBe(1_786_372_566_000); + }); +}); diff --git a/apps/server/src/usage/usageTranscripts.ts b/apps/server/src/usage/usageTranscripts.ts index 49f9a1935ccc..2aea60709666 100644 --- a/apps/server/src/usage/usageTranscripts.ts +++ b/apps/server/src/usage/usageTranscripts.ts @@ -1,8 +1,8 @@ /** * Pure parsers for the provider CLIs' on-disk session transcripts. * - * Both parsers are line-at-a-time reducers so callers can stream large files - * without materialising them. Neither touches the filesystem. + * Each parser is a line-at-a-time reducer so callers can stream large files + * without materialising them. None of them touch the filesystem. * * @module usageTranscripts */ @@ -68,7 +68,20 @@ export function totalTokens(totals: UsageTokenTotals): number { * an order of magnitude. */ export function mightCarryUsage(line: string, provider: UsageProviderKind): boolean { - return provider === "claude" ? line.includes('"usage"') : line.includes('"token_count"'); + if (provider === "claude") return line.includes('"usage"'); + if (provider === "grok") return line.includes('"turn_completed"'); + return line.includes('"token_count"'); +} + +/** + * Grok reports cost in integer ticks where `1 USD = 10^10` ticks. See Grok + * headless `total_cost_usd_ticks`. Convert to dollars for pricing. + */ +export const GROK_COST_USD_TICKS_PER_DOLLAR = 10_000_000_000; + +export function grokCostTicksToUsd(ticks: unknown): number | null { + if (typeof ticks !== "number" || !Number.isFinite(ticks) || ticks < 0) return null; + return ticks / GROK_COST_USD_TICKS_PER_DOLLAR; } /* -------------------------------------------------------------------------- */ @@ -297,4 +310,179 @@ export function parseCodexLine(line: string, state: CodexScanState): UsageRecord }; } +/* -------------------------------------------------------------------------- */ +/* Grok Build */ +/* -------------------------------------------------------------------------- */ + +interface GrokUsageTotals { + readonly inputTokens: number; + readonly outputTokens: number; + readonly cachedReadTokens: number; + readonly cacheCreationTokens: number; + readonly reasoningTokens: number; + readonly costUsdTicks: number | null; +} + +function readGrokUsageTotals(value: unknown): GrokUsageTotals | null { + if (typeof value !== "object" || value === null) return null; + const record = value as Record; + return { + inputTokens: int(record["inputTokens"]), + outputTokens: int(record["outputTokens"]), + cachedReadTokens: int(record["cachedReadTokens"]), + cacheCreationTokens: int(record["cacheCreationTokens"]), + reasoningTokens: int(record["reasoningTokens"]), + costUsdTicks: + typeof record["costUsdTicks"] === "number" && Number.isFinite(record["costUsdTicks"]) + ? record["costUsdTicks"] + : null, + }; +} + +function grokTotalsToUsage(totals: GrokUsageTotals): UsageTokenTotals { + const cachedInputTokens = totals.cachedReadTokens; + const cacheCreationTokens = totals.cacheCreationTokens; + // Grok reports `inputTokens` inclusive of the cached portion, matching Codex. + const uncachedInputTokens = Math.max( + 0, + totals.inputTokens - cachedInputTokens - cacheCreationTokens, + ); + const outputTokens = totals.outputTokens; + return { + uncachedInputTokens, + cachedInputTokens, + cacheCreationTokens, + outputTokens, + reasoningTokens: Math.min(outputTokens, totals.reasoningTokens), + }; +} + +/** + * Parses one line of a Grok Build `updates.jsonl` session log. + * + * Usage lands on `turn_completed` session updates. Per-model breakdowns live + * under `usage.modelUsage`; when present each model becomes its own record. + * + * Returns every record for the line (0 or more). Callers stream line-by-line + * and flatten. + */ +export function parseGrokLine(line: string): readonly UsageRecord[] { + let parsed: unknown; + try { + parsed = JSON.parse(line); + } catch { + return []; + } + if (typeof parsed !== "object" || parsed === null) return []; + + const record = parsed as Record; + const params = record["params"]; + if (typeof params !== "object" || params === null) return []; + const paramsRecord = params as Record; + + const update = paramsRecord["update"]; + if (typeof update !== "object" || update === null) return []; + const updateRecord = update as Record; + if (updateRecord["sessionUpdate"] !== "turn_completed") return []; + + const usage = updateRecord["usage"]; + if (typeof usage !== "object" || usage === null) return []; + const usageRecord = usage as Record; + + const sessionId = typeof paramsRecord["sessionId"] === "string" ? paramsRecord["sessionId"] : ""; + const promptId = typeof updateRecord["prompt_id"] === "string" ? updateRecord["prompt_id"] : null; + + // Prefer the high-resolution agent clock; fall back to the outer unix seconds. + const meta = paramsRecord["_meta"]; + let timestampMs: number | null = null; + if (typeof meta === "object" && meta !== null) { + const agentTimestampMs = (meta as Record)["agentTimestampMs"]; + if (typeof agentTimestampMs === "number" && Number.isFinite(agentTimestampMs)) { + timestampMs = agentTimestampMs; + } + } + if (timestampMs === null) { + const timestamp = record["timestamp"]; + if (typeof timestamp === "number" && Number.isFinite(timestamp)) { + timestampMs = timestamp > 1e12 ? timestamp : timestamp * 1000; + } + } + if (timestampMs === null) return []; + + const topLevel = readGrokUsageTotals(usageRecord); + if (topLevel === null) return []; + + const modelUsage = usageRecord["modelUsage"]; + const modelEntries: Array<{ model: string; totals: GrokUsageTotals }> = []; + if (typeof modelUsage === "object" && modelUsage !== null) { + for (const [model, raw] of Object.entries(modelUsage as Record)) { + if (model.length === 0) continue; + const totals = readGrokUsageTotals(raw); + if (totals === null) continue; + modelEntries.push({ model, totals }); + } + } + + if (modelEntries.length === 0) { + if (totalTokens(grokTotalsToUsage(topLevel)) === 0) return []; + return [ + { + provider: "grok", + timestampMs, + model: "grok", + sessionId, + totals: grokTotalsToUsage(topLevel), + reportedCostUsd: grokCostTicksToUsd(topLevel.costUsdTicks), + // No prompt id means we cannot tell two same-second updates apart. + dedupeKey: promptId === null ? null : `${sessionId}:${promptId}:grok`, + }, + ]; + } + + // Cost allocation: + // 1. Emitted models with their own costUsdTicks keep those values. + // 2. Remaining aggregate cost (top-level minus those per-model ticks, + // clamped at 0) is pro-rated across emitted models that lack ticks, + // by token share among the unticked models only. + // 3. When no model has per-model ticks, remaining equals the full + // aggregate and every emitted model gets a token-share slice. + // Zero-token rows are never emitted and never count toward used ticks. + const topLevelCostUsd = grokCostTicksToUsd(topLevel.costUsdTicks); + let usedTickedCostUsd = 0; + let untickedTokenDenominator = 0; + for (const entry of modelEntries) { + const tokens = totalTokens(grokTotalsToUsage(entry.totals)); + if (tokens === 0) continue; + if (entry.totals.costUsdTicks !== null) { + usedTickedCostUsd += grokCostTicksToUsd(entry.totals.costUsdTicks) ?? 0; + } else { + untickedTokenDenominator += tokens; + } + } + const remainingCostUsd = + topLevelCostUsd === null ? null : Math.max(0, topLevelCostUsd - usedTickedCostUsd); + + const results: UsageRecord[] = []; + for (const entry of modelEntries) { + const totals = grokTotalsToUsage(entry.totals); + if (totalTokens(totals) === 0) continue; + + let reportedCostUsd = grokCostTicksToUsd(entry.totals.costUsdTicks); + if (reportedCostUsd === null && remainingCostUsd !== null && untickedTokenDenominator > 0) { + reportedCostUsd = remainingCostUsd * (totalTokens(totals) / untickedTokenDenominator); + } + + results.push({ + provider: "grok", + timestampMs, + model: entry.model, + sessionId, + totals, + reportedCostUsd, + dedupeKey: promptId === null ? null : `${sessionId}:${promptId}:${entry.model}`, + }); + } + return results; +} + export { EMPTY_TOTALS }; diff --git a/apps/server/src/vcs/GitVcsDriverCore.test.ts b/apps/server/src/vcs/GitVcsDriverCore.test.ts index 8a820aa81941..587a3e4abbde 100644 --- a/apps/server/src/vcs/GitVcsDriverCore.test.ts +++ b/apps/server/src/vcs/GitVcsDriverCore.test.ts @@ -759,18 +759,6 @@ it.layer(TestLayer)("GitVcsDriver core integration", (it) => { assert.notInclude(error.detail, "Git command failed in"); }), ); - - it.effect("treats removing an already-gone worktree as a no-op", () => - Effect.gen(function* () { - const cwd = yield* makeTmpDir(); - const pathService = yield* Path.Path; - const missingWorktree = pathService.join(cwd, "missing-worktree"); - const driver = yield* GitVcsDriver.GitVcsDriver; - yield* driver.initRepo({ cwd }); - - yield* driver.removeWorktree({ cwd, path: missingWorktree }); - }), - ); }); describe("review diff previews", () => { diff --git a/apps/web/package.json b/apps/web/package.json index b73eefc8d539..ddda0a9628cc 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@t3tools/web", - "version": "0.0.34", + "version": "0.0.35", "private": true, "type": "module", "scripts": { diff --git a/apps/web/src/assets/assetUrls.test.ts b/apps/web/src/assets/assetUrls.test.ts deleted file mode 100644 index e4634f5b98db..000000000000 --- a/apps/web/src/assets/assetUrls.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { describe, expect, it } from "vite-plus/test"; - -import { resolveAssetUrl } from "./assetUrls"; - -describe("resolveAssetUrl", () => { - it("resolves an environment-relative asset URL", () => { - expect( - resolveAssetUrl("https://environment.example/base/", "/api/assets/signed-token/favicon.png"), - ).toBe("https://environment.example/api/assets/signed-token/favicon.png"); - }); - - it("rejects an invalid environment base URL", () => { - expect(resolveAssetUrl("not a URL", "/api/assets/signed-token/favicon.png")).toBeNull(); - }); -}); diff --git a/apps/web/src/components/StartTruncatedPath.test.tsx b/apps/web/src/components/StartTruncatedPath.test.tsx deleted file mode 100644 index 1f7b158bce39..000000000000 --- a/apps/web/src/components/StartTruncatedPath.test.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { renderToStaticMarkup } from "react-dom/server"; -import { describe, expect, it } from "vite-plus/test"; - -import { StartTruncatedPath } from "./StartTruncatedPath"; - -describe("StartTruncatedPath", () => { - it("keeps the filename at the visible end by truncating from the start", () => { - const path = "apps/desktop/src/components/very/long/CommitDialog.tsx"; - - const markup = renderToStaticMarkup(); - - expect(markup).toContain('dir="rtl"'); - expect(markup).toMatch( - /]*>apps\/desktop\/src\/components\/very\/long\/CommitDialog\.tsx<\/bdi>/, - ); - expect(markup).toContain("overflow-hidden"); - expect(markup).toContain("text-ellipsis"); - expect(markup).toContain("whitespace-nowrap"); - expect(markup).toContain("min-w-0"); - }); - - it("shows the full path in a tooltip", () => { - const path = "apps/desktop/src/components/very/long/CommitDialog.tsx"; - - const markup = renderToStaticMarkup(); - - expect(markup).toContain('data-slot="tooltip-trigger"'); - expect(markup).toContain("data-base-ui-tooltip-trigger"); - expect(markup).toContain(path); - }); -}); diff --git a/apps/web/src/components/preview/previewAutomationClientId.test.ts b/apps/web/src/components/preview/previewAutomationClientId.test.ts deleted file mode 100644 index f51732d91a4c..000000000000 --- a/apps/web/src/components/preview/previewAutomationClientId.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { describe, expect, it } from "vite-plus/test"; - -import { createPreviewAutomationClientId } from "./previewAutomationClientId"; - -describe("createPreviewAutomationClientId", () => { - it("creates bounded cryptographically random identities for independent host lifetimes", () => { - const clientIds = Array.from({ length: 32 }, createPreviewAutomationClientId); - - expect(new Set(clientIds).size).toBe(clientIds.length); - expect(clientIds.every((clientId) => clientId.startsWith("preview-"))).toBe(true); - expect(clientIds.every((clientId) => clientId.length <= 128)).toBe(true); - }); -}); diff --git a/apps/web/src/components/settings/ProviderInstanceCard.tsx b/apps/web/src/components/settings/ProviderInstanceCard.tsx index a663aa90990d..c44df412a92f 100644 --- a/apps/web/src/components/settings/ProviderInstanceCard.tsx +++ b/apps/web/src/components/settings/ProviderInstanceCard.tsx @@ -2,7 +2,6 @@ import { ArrowUpCircleIcon, - ChevronDownIcon, CopyIcon, DownloadIcon, LoaderIcon, @@ -12,7 +11,7 @@ import { } from "lucide-react"; import * as Arr from "effect/Array"; import * as Result from "effect/Result"; -import { useState, type ReactNode } from "react"; +import { useEffect, useRef, useState, type ReactNode } from "react"; import { isProviderDriverKind, resolveProviderInstanceEnabled, @@ -30,7 +29,6 @@ import { normalizeProviderAccentColor } from "../../providerInstances"; import { Badge } from "../ui/badge"; import { Button } from "../ui/button"; import { Checkbox } from "../ui/checkbox"; -import { Collapsible, CollapsibleContent } from "../ui/collapsible"; import { DraftInput } from "../ui/draft-input"; import { Popover, PopoverPopup, PopoverTrigger } from "../ui/popover"; import { ScrollArea } from "../ui/scroll-area"; @@ -39,11 +37,11 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from ". import { stackedThreadToast, toastManager } from "../ui/toast"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import type { DriverOption } from "./providerDriverMeta"; +import { providerSettingsTabClassName } from "./providerSettingsTabs"; import { ProviderSettingsForm } from "./ProviderSettingsForm"; import { ProviderModelsSection } from "./ProviderModelsSection"; -import { ProviderInstanceIcon } from "../chat/ProviderInstanceIcon"; +import { ProviderInstanceIcon, providerInstanceInitials } from "../chat/ProviderInstanceIcon"; import { ProviderAccentColorPicker } from "./ProviderAccentColorPicker"; -import { RedactedSensitiveText } from "./RedactedSensitiveText"; import { getProviderVersionAdvisoryPresentation, PROVIDER_STATUS_STYLES, @@ -78,6 +76,25 @@ function makeEnvironmentDraftRow( }; } +function providerEnvironmentsEqual( + left: ReadonlyArray, + right: ReadonlyArray, +): boolean { + return ( + left.length === right.length && + left.every((variable, index) => { + const other = right[index]; + return ( + other !== undefined && + variable.name === other.name && + variable.value === other.value && + variable.sensitive === other.sensitive && + variable.valueRedacted === other.valueRedacted + ); + }) + ); +} + /** * Read a string[] at `key` from the opaque config blob, filtering out * non-string entries. Used for `customModels`, which is always typed as @@ -132,28 +149,6 @@ export function deriveProviderModelsForDisplay(input: { return [...serverModels, ...customModels]; } -function ProviderAuthEmail(props: { - readonly email: string | undefined; - readonly prefix?: string; - readonly separator?: boolean; -}) { - const trimmed = props.email?.trim(); - if (!trimmed) return null; - - return ( - - {props.separator ? · : null} - {props.prefix ? {props.prefix} : null} - - - ); -} - function ProviderEnvironmentSection(props: { readonly environment: ReadonlyArray; readonly onChange: (environment: ReadonlyArray) => void; @@ -161,6 +156,26 @@ function ProviderEnvironmentSection(props: { const [rows, setRows] = useState>(() => props.environment.map(makeEnvironmentDraftRow), ); + const previousEnvironmentRef = useRef(props.environment); + const lastPublishedEnvironmentRef = useRef< + ReadonlyArray | undefined + >(undefined); + + useEffect(() => { + const previousEnvironment = previousEnvironmentRef.current; + const lastPublishedEnvironment = lastPublishedEnvironmentRef.current; + previousEnvironmentRef.current = props.environment; + lastPublishedEnvironmentRef.current = undefined; + if ( + previousEnvironment === props.environment || + providerEnvironmentsEqual(previousEnvironment, props.environment) || + (lastPublishedEnvironment !== undefined && + providerEnvironmentsEqual(lastPublishedEnvironment, props.environment)) + ) { + return; + } + setRows(props.environment.map(makeEnvironmentDraftRow)); + }, [props.environment]); const publishRows = (nextRows: ReadonlyArray) => { const published: ProviderInstanceEnvironmentVariable[] = []; @@ -180,6 +195,7 @@ function ProviderEnvironmentSection(props: { const { id: _id, ...rest } = row; published.push({ ...rest, name }); } + lastPublishedEnvironmentRef.current = published; props.onChange(published); }; @@ -324,8 +340,10 @@ interface ProviderInstanceCardProps { readonly instance: ProviderInstanceConfig; readonly driverOption: DriverOption | undefined; readonly liveProvider: ServerProvider | undefined; - readonly isExpanded: boolean; - readonly onExpandedChange: (open: boolean) => void; + readonly mode: "list" | "editor"; + readonly selected?: boolean | undefined; + readonly onSelect?: (() => void) | undefined; + readonly readOnly?: boolean | undefined; readonly onUpdate: (nextInstance: ProviderInstanceConfig) => void; /** * Pass `undefined` to hide the delete button entirely. Built-in default @@ -353,12 +371,9 @@ interface ProviderInstanceCardProps { } /** - * A single configured provider-instance row in the Providers settings - * section. Used for every row — both the built-in default instance for a - * driver (rendered with `onDelete` omitted) and user-authored custom - * instances (`onDelete` supplied). The only UI difference between the two - * is whether the trash button is visible; every other field (display - * name, config fields, models) behaves identically. + * Renders one provider instance as either a compact selectable list row or + * the full editor shown beside that list. Both modes use the same enabled + * state and provider metadata. * * Behavior notes: * - `liveProvider` is matched by the caller via `instanceId`; when no @@ -379,8 +394,10 @@ export function ProviderInstanceCard({ instance, driverOption, liveProvider, - isExpanded, - onExpandedChange, + mode, + selected = false, + onSelect, + readOnly = false, onUpdate, onDelete, headerAction, @@ -393,21 +410,17 @@ export function ProviderInstanceCard({ onRunUpdate, isUpdating = false, }: ProviderInstanceCardProps) { + const [activeTab, setActiveTab] = useState<"models" | "configuration">("configuration"); const enabled = resolveProviderInstanceEnabled(instance); - // The server-reported status wins when present; otherwise fall back to - // "disabled"/"warning" based on the local `enabled` flag so the dot - // reflects the persisted intent even before the first probe completes. - const statusKey: ProviderStatusKey = - (liveProvider?.status as ProviderStatusKey | undefined) ?? (enabled ? "warning" : "disabled"); + // A locally disabled provider stays neutral even if its last server status + // is stale. Enabled providers use the server status when one is available. + const statusKey: ProviderStatusKey = enabled + ? ((liveProvider?.status as ProviderStatusKey | undefined) ?? "warning") + : "disabled"; const statusStyle = PROVIDER_STATUS_STYLES[statusKey]; const rawSummary = getProviderSummary(liveProvider); - const authEmail = liveProvider?.auth.email; - const hasAuthenticatedEmail = - liveProvider?.auth.status === "authenticated" && Boolean(authEmail?.trim()); - const authenticatedDetail = hasAuthenticatedEmail - ? (liveProvider?.auth.label ?? liveProvider?.auth.type ?? null) - : null; - const summary = rawSummary; + const summary = enabled ? rawSummary : { headline: "Disabled", detail: null }; + const showEditorStatus = enabled && (statusKey === "warning" || statusKey === "error"); const versionLabel = getProviderVersionLabel(liveProvider?.version); const versionAdvisory = getProviderVersionAdvisoryPresentation(liveProvider?.versionAdvisory); const updateCommand = versionAdvisory?.updateCommand ?? null; @@ -441,6 +454,7 @@ export function ProviderInstanceCard({ const driverKind: ProviderDriverKind | null = isProviderDriverKind(instance.driver) ? instance.driver : null; + const visibleTab = driverOption === undefined ? "configuration" : activeTab; const customModels = readConfigStringArray(instance.config, "customModels"); // Server-returned models may lag behind settings writes. Treat probe @@ -506,25 +520,21 @@ export function ProviderInstanceCard({ displayName={displayName} accentColor={accentColor} showBadge={Boolean(accentColor)} - statusDotClassName={statusStyle.dot} - indicatorBackground="var(--card)" className="size-5" iconClassName="size-4 text-foreground/80" badgeClassName="right-[-0.125rem] bottom-[-0.125rem] h-3 min-w-3 px-0.5 text-[7px]" /> ) : FallbackIconComponent ? ( - + - ) : ( - + + {providerInstanceInitials(displayName)} + ); const titleHeadNode = ( @@ -576,229 +586,275 @@ export function ProviderInstanceCard({ ); - const authRowNode = ( -

    - {hasAuthenticatedEmail ? ( - <> - Authenticated as - - {authenticatedDetail ? · {authenticatedDetail} : null} - - ) : ( - <> - {summary.headline} - - - )} - {summary.detail ? - {summary.detail} : null} -

    - ); - const versionCodeNode = versionLabel ? ( {versionLabel} ) : null; - return ( -
    -
    -
    -
    -
    - {titleHeadNode} + if (mode === "list") { + return ( +
    + {selected ? : null} + + updateEnabled(Boolean(checked))} + aria-label={`Enable ${displayName}`} + /> +
    + ); + } + + return ( +
    +
    +
    +
    + {titleHeadNode} + {versionCodeNode} + {versionAdvisory ? ( + + + + + } + /> + +
    +
    +

    + Update available +

    +

    - + {versionAdvisory.detail} +

    +
    + {onRunUpdate ? ( + - } - /> - -
    -
    -

    - Update available -

    -

    - {versionAdvisory.detail} -

    + ) : null} + {onRunUpdate && updateCommand ? ( +
    + + or, update manually using +
    - {onRunUpdate ? ( - - ) : null} - {onRunUpdate && updateCommand ? ( -
    - - or, update manually using - -
    - ) : null} - {updateCommand ? ( -
    - - - {updateCommand} - - - - - copyToClipboard(updateCommand, { - providerName: displayName, - }) - } - aria-label="Copy update command" - > - - - } - /> - Copy command - -
    - ) : null} -
    - - - ) : null} - {titleTailNode} -
    - {authRowNode} -
    -
    - - updateEnabled(Boolean(checked))} - aria-label={`Enable ${displayName}`} - /> + ) : null} + {updateCommand ? ( +
    + + + {updateCommand} + + + + + copyToClipboard(updateCommand, { + providerName: displayName, + }) + } + aria-label="Copy update command" + > + + + } + /> + Copy command + +
    + ) : null} +
    +
    +
    + ) : null} + {titleTailNode}
    + {showEditorStatus ? ( +

    + {summary.headline} + {summary.detail ? · {summary.detail} : null} +

    + ) : null}
    - - -
    -
    - -
    +
    + {driverOption !== undefined ? ( + + ) : null} + +
    -
    - + -
    - -
    +
    + +
    - {driverOption ? ( - - ) : null} +
    + +
    - {driverOption !== undefined ? ( - - ) : ( -
    -

    - This instance uses a driver ( - {String(instance.driver)}) that is not - shipped with the current build. Configuration values are preserved but cannot be - edited from this surface. -

    -
    - )} + {driverOption ? ( + + ) : null} + + {driverOption === undefined ? ( +
    +

    + This instance uses a driver ( + {String(instance.driver)}) that is not + shipped with the current build. Configuration values are preserved but cannot be + edited from this surface. +

    +
    + ) : null} +
    + {driverOption !== undefined ? ( + - - + ) : null} +
    ); } diff --git a/apps/web/src/components/settings/ProviderSettingsPanel.environment.test.tsx b/apps/web/src/components/settings/ProviderSettingsPanel.environment.test.tsx index 2b304378ae91..bf79929f1972 100644 --- a/apps/web/src/components/settings/ProviderSettingsPanel.environment.test.tsx +++ b/apps/web/src/components/settings/ProviderSettingsPanel.environment.test.tsx @@ -178,21 +178,45 @@ describe("EnvironmentProviderSettings routing", () => { }); }); - it("renders the provider layout inert with a limited-permissions notice when read only", () => { + it("keeps provider selection available while write controls are read only", () => { + settingsState.value = { + ...DEFAULT_UNIFIED_SETTINGS, + providerInstances: { + [customId]: { + driver: ProviderDriverKind.make("codex"), + enabled: true, + }, + }, + }; atoms.providers = [provider()]; - const panel = renderPanel({ readOnly: true }); + let panel = renderPanel({ readOnly: true }); const inertWrapper = visitElements(panel, (element) => element.props.inert === true); expect(inertWrapper).not.toBeNull(); - const providerCard = visitElements(panel, (element) => element.props.instanceId === codexId); - expect(providerCard).not.toBeNull(); + + const customRow = visitElements( + panel, + (element) => element.props.instanceId === customId && element.props.mode === "list", + ); + expect(customRow?.props.readOnly).toBe(true); + expect(customRow?.props.onSelect).toBeTypeOf("function"); + (customRow?.props.onSelect as (() => void) | undefined)?.(); + + panel = renderPanel({ readOnly: true }); + const customEditor = visitElements( + panel, + (element) => element.props.instanceId === customId && element.props.mode === "editor", + ); + expect(customEditor).not.toBeNull(); const notice = visitElements(panel, (element) => element.props.title === "Limited permissions"); expect(notice).not.toBeNull(); - expect( - visitElements(panel, (element) => element.props["aria-label"] === "Add provider instance"), - ).toBeNull(); + const providersSection = visitElements( + panel, + (element) => element.props.title === "Providers" && "headerAction" in element.props, + ); + expect(providersSection?.props.headerAction).toBeNull(); expect( visitElements(panel, (element) => element.props["aria-label"] === "Refresh provider status"), ).toBeNull(); @@ -205,6 +229,11 @@ describe("EnvironmentProviderSettings routing", () => { expect( visitElements(panel, (element) => element.props.title === "Limited permissions"), ).toBeNull(); + const providersSection = visitElements( + panel, + (element) => element.props.title === "Providers" && "headerAction" in element.props, + ); + expect(providersSection?.props.headerAction).not.toBeNull(); }); it("deletes and resets provider configuration without erasing shared preferences", () => { @@ -225,8 +254,17 @@ describe("EnvironmentProviderSettings routing", () => { }, favorites: [{ provider: customId, model: "favorite" }], }; - const panel = renderPanel(); - const customCard = visitElements(panel, (element) => element.props.instanceId === customId); + let panel = renderPanel(); + const customRow = visitElements( + panel, + (element) => element.props.instanceId === customId && element.props.mode === "list", + ); + (customRow?.props.onSelect as (() => void) | undefined)?.(); + panel = renderPanel(); + const customCard = visitElements( + panel, + (element) => element.props.instanceId === customId && element.props.mode === "editor", + ); expect(customCard).not.toBeNull(); (customCard?.props.onDelete as (() => void) | undefined)?.(); @@ -237,7 +275,16 @@ describe("EnvironmentProviderSettings routing", () => { }); settingsState.updateSettings.mockClear(); - const defaultCard = visitElements(panel, (element) => element.props.instanceId === codexId); + const defaultRow = visitElements( + panel, + (element) => element.props.instanceId === codexId && element.props.mode === "list", + ); + (defaultRow?.props.onSelect as (() => void) | undefined)?.(); + panel = renderPanel(); + const defaultCard = visitElements( + panel, + (element) => element.props.instanceId === codexId && element.props.mode === "editor", + ); const resetAction = defaultCard?.props.headerAction; const resetButton = visitElements( resetAction, diff --git a/apps/web/src/components/settings/ProviderSettingsPanel.tsx b/apps/web/src/components/settings/ProviderSettingsPanel.tsx index 3a38a91e2265..3a25879ea43c 100644 --- a/apps/web/src/components/settings/ProviderSettingsPanel.tsx +++ b/apps/web/src/components/settings/ProviderSettingsPanel.tsx @@ -24,6 +24,7 @@ import * as Duration from "effect/Duration"; import * as Equal from "effect/Equal"; import * as Result from "effect/Result"; import { + ChevronDownIcon, CloudIcon, LaptopIcon, LoaderIcon, @@ -32,7 +33,7 @@ import { RefreshCwIcon, TerminalIcon, } from "lucide-react"; -import { useCallback, useMemo, useRef, useState } from "react"; +import { useCallback, useMemo, useRef, useState, type ReactNode } from "react"; import { isDesktopLocalConnectionTarget } from "../../connection/desktopLocal"; import { isElectron } from "../../env"; @@ -62,6 +63,7 @@ import { type ProviderUpdateCandidate, } from "../ProviderUpdateLaunchNotification.logic"; import { Button } from "../ui/button"; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../ui/collapsible"; import { NumberField, NumberFieldDecrement, @@ -69,11 +71,13 @@ import { NumberFieldIncrement, NumberFieldInput, } from "../ui/number-field"; -import { stackedThreadToast, toastManager } from "../ui/toast"; +import { ScrollArea } from "../ui/scroll-area"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; +import { stackedThreadToast, toastManager } from "../ui/toast"; import { AddProviderInstanceDialog } from "./AddProviderInstanceDialog"; import { ProviderInstanceCard } from "./ProviderInstanceCard"; import { DRIVER_OPTIONS, getDriverOption } from "./providerDriverMeta"; +import { providerSettingsTabClassName } from "./providerSettingsTabs"; import { searchableSetting } from "./settingsSearch"; import { backgroundActivityOverrideSettings, @@ -165,9 +169,11 @@ function providerEnvironmentDetail(environment: EnvironmentPresentation): string function EnvironmentUnavailableRow({ environment, access, + deviceTabs, }: { readonly environment: EnvironmentPresentation; readonly access: Exclude; + readonly deviceTabs?: ReactNode; }) { const isLoading = access.kind === "loading"; const title = isLoading @@ -184,6 +190,7 @@ function EnvironmentUnavailableRow({ // continuously repainting animation would run the whole time. return ( + {deviceTabs} ); @@ -211,64 +218,63 @@ export function ProviderSettingsPanel() { options.find((environment) => environment.environmentId === effectiveEnvironmentId) ?? null; const onlyPrimaryDevice = options.length === 1 && options[0]?.entry.target._tag === "PrimaryConnectionTarget"; + const deviceTabs = + !onlyPrimaryDevice && options.length > 0 ? ( + +
    + {options.map((environment) => { + const Icon = providerEnvironmentIcon(environment); + const selected = environment.environmentId === effectiveEnvironmentId; + const detail = providerEnvironmentDetail(environment); + const statusText = connectionStatusText(environment.connection); + return ( + + setSelectedEnvironmentId(environment.environmentId)} + > + + {environment.label} + + + {detail}, {statusText} + + + } + /> + + {detail} · {statusText} + + + ); + })} +
    +
    + ) : null; return ( - - {!onlyPrimaryDevice ? ( - - {options.length === 0 ? ( - // The catalog hydrates asynchronously, so an empty list before it is - // ready means "not loaded yet", not "nothing is connected". - - ) : ( -
    - {options.map((environment) => { - const Icon = providerEnvironmentIcon(environment); - const selected = environment.environmentId === effectiveEnvironmentId; - const statusText = connectionStatusText(environment.connection); - return ( - - ); - })} -
    - )} + + {options.length === 0 ? ( + + ) : null} @@ -276,6 +282,7 @@ export function ProviderSettingsPanel() { ) : null} @@ -284,25 +291,37 @@ export function ProviderSettingsPanel() { function SelectedEnvironmentProviderSettings({ environment, + deviceTabs, }: { readonly environment: EnvironmentPresentation; + readonly deviceTabs?: ReactNode; }) { const isPrimary = environment.entry.target._tag === "PrimaryConnectionTarget"; if (isPrimary) { // The desktop app owns its primary server outright; a browser session // checks the scopes its cookie session was granted. if (isElectron) { - return ; + return ( + + ); } - return ; + return ( + + ); } - return ; + return ; } function PrimarySessionGatedProviderSettings({ environment, + deviceTabs, }: { readonly environment: EnvironmentPresentation; + readonly deviceTabs?: ReactNode; }) { const primarySessionState = usePrimarySessionState(); const operateAccess = resolvePrimaryOperateAccess({ @@ -312,13 +331,21 @@ function PrimarySessionGatedProviderSettings({ isPending: primarySessionState.isPending, hasError: primarySessionState.error !== null, }); - return ; + return ( + + ); } function RemoteSessionGatedProviderSettings({ environment, + deviceTabs, }: { readonly environment: EnvironmentPresentation; + readonly deviceTabs?: ReactNode; }) { const sessionState = useEnvironmentSessionState(environment.environmentId); const operateAccess = resolveRemoteOperateAccess({ @@ -326,15 +353,23 @@ function RemoteSessionGatedProviderSettings({ isPending: sessionState.isPending, hasError: sessionState.hasError, }); - return ; + return ( + + ); } function AccessGatedProviderSettings({ environment, operateAccess, + deviceTabs, }: { readonly environment: EnvironmentPresentation; readonly operateAccess: ProviderOperateAccess; + readonly deviceTabs?: ReactNode; }) { const access = classifyProviderEnvironmentAccess({ connectionPhase: environment.connection.phase, @@ -342,13 +377,20 @@ function AccessGatedProviderSettings({ operateAccess, }); if (access.kind !== "editable" && access.kind !== "read-only") { - return ; + return ( + + ); } return ( ); } @@ -357,9 +399,11 @@ export function EnvironmentProviderSettings({ environmentId, environmentLabel, readOnly = false, + deviceTabs, }: { readonly environmentId: EnvironmentId; readonly environmentLabel: string; + readonly deviceTabs?: ReactNode; /** * Render the full provider layout, greyed out and inert, when this session's * credential lacks `orchestration:operate` on the environment. Showing the @@ -380,10 +424,12 @@ export function EnvironmentProviderSettings({ }); const [isRefreshingProviders, setIsRefreshingProviders] = useState(false); const [isAddInstanceDialogOpen, setIsAddInstanceDialogOpen] = useState(false); + const [selectedInstanceId, setSelectedInstanceId] = useState(null); + const [advancedOpen, setAdvancedOpen] = useState(false); + const advancedVisible = readOnly || advancedOpen; const [updatingProviderDrivers, setUpdatingProviderDrivers] = useState< ReadonlySet >(() => new Set()); - const [openInstanceDetails, setOpenInstanceDetails] = useState>({}); const refreshingRef = useRef(false); const updatingDriversRef = useRef>(new Set()); @@ -577,6 +623,8 @@ export function EnvironmentProviderSettings({ } } + const selectedRow = rows.find((row) => row.instanceId === selectedInstanceId) ?? rows[0] ?? null; + const updateProviderInstance = ( row: InstanceRow, next: ProviderInstanceConfig, @@ -666,233 +714,253 @@ export function EnvironmentProviderSettings({ }); }; + const renderProviderInstance = (row: InstanceRow, mode: "list" | "editor") => { + const driverOption = getDriverOption(row.driver); + const liveProvider = serverProviders.find( + (candidate) => candidate.instanceId === row.instanceId, + ); + const updateCandidate = liveProvider + ? providerUpdateCandidateByInstanceId.get(liveProvider.instanceId) + : undefined; + const isDriverUpdateRunning = + updateCandidate !== undefined && + (updatingProviderDrivers.has(updateCandidate.driver) || + serverProviders.some( + (provider) => + provider.driver === updateCandidate.driver && isProviderUpdateActive(provider), + )); + const showInlineUpdateButton = + updateCandidate !== undefined && + hasOneClickUpdateProviderCandidate(updateCandidate, serverProviders); + const canRunInlineUpdate = + updateCandidate !== undefined && + canOneClickUpdateProviderCandidate(updateCandidate, serverProviders) && + !updatingProviderDrivers.has(updateCandidate.driver); + const modelPreferences = settings.providerModelPreferences?.[row.instanceId] ?? { + hiddenModels: [], + modelOrder: [], + }; + const favoriteModels = Arr.filterMap(settings.favorites ?? [], (favorite) => + favorite.provider === row.instanceId ? Result.succeed(favorite.model) : Result.failVoid, + ); + const resetLabel = driverOption?.label ?? String(row.driver); + + return ( + setSelectedInstanceId(row.instanceId) : undefined} + readOnly={readOnly} + onUpdate={(next) => { + const wasEnabled = resolveProviderInstanceEnabled(row.instance); + const isDisabling = next.enabled === false && wasEnabled; + const shouldClearTextGen = isDisabling && textGenInstanceId === row.instanceId; + updateProviderInstance( + row, + next, + shouldClearTextGen + ? { + textGenerationModelSelection: + DEFAULT_UNIFIED_SETTINGS.textGenerationModelSelection, + } + : undefined, + ); + }} + onDelete={ + mode === "editor" && !row.isDefault + ? () => deleteProviderInstance(row.instanceId) + : undefined + } + headerAction={ + mode === "editor" && row.isDefault && row.isDirty ? ( + resetDefaultInstance(row.driver)} + /> + ) : null + } + hiddenModels={modelPreferences.hiddenModels} + favoriteModels={favoriteModels} + modelOrder={modelPreferences.modelOrder} + onHiddenModelsChange={(hiddenModels) => + updateProviderModelPreferences(row.instanceId, { + ...modelPreferences, + hiddenModels, + }) + } + onFavoriteModelsChange={(next) => updateProviderFavoriteModels(row.instanceId, next)} + onModelOrderChange={(modelOrder) => + updateProviderModelPreferences(row.instanceId, { + ...modelPreferences, + modelOrder, + }) + } + onRunUpdate={ + mode === "editor" && showInlineUpdateButton && updateCandidate + ? () => { + if (canRunInlineUpdate) void runProviderUpdate(updateCandidate); + } + : undefined + } + isUpdating={mode === "editor" && showInlineUpdateButton ? isDriverUpdateRunning : undefined} + /> + ); + }; + return ( <> - - {!readOnly ? ( - <> - - setIsAddInstanceDialogOpen(true)} - aria-label="Add provider instance" - > - - - } - /> - Add provider instance - - - void refreshProviders()} - aria-label="Refresh provider status" - > - {isRefreshingProviders ? ( - - ) : ( - - )} - - } - /> - Refresh provider status - - - ) : null} -
    + !readOnly ? ( + + ) : null } > + {deviceTabs} {readOnly ? ( ) : null} -
    - - Health check interval - - This interval is configured here, then the shared Background activity policy - decides whether provider probes may run when the timer fires. Custom intervals - appear as Advanced in General settings. - - - } - description="Refresh provider availability, versions, auth state, and model metadata in the background. Set this to 0 seconds to rely on manual refreshes." - resetAction={ - providerHealthRefreshIntervalSeconds !== - defaultProviderHealthRefreshIntervalSeconds ? ( - - updateSettings( - backgroundActivityOverrideSettings( - settings.backgroundActivity, - resolvedBackgroundActivity, - { - providerHealthRefreshInterval: undefined, - }, - ), - ) - } - /> - ) : null - } - control={ -
    - - updateSettings( - backgroundActivityOverrideSettings( - settings.backgroundActivity, - resolvedBackgroundActivity, - { - providerHealthRefreshInterval: Duration.seconds( - normalizeIntervalSeconds(value), - ), - }, - ), - ) - } - > - - - - - - - seconds +
    +
    +
    +
    + Provider + On
    - } - /> + {rows.map((row) => renderProviderInstance(row, "list"))} +
    + + {!readOnly ? ( + + void refreshProviders()} + aria-label="Refresh provider status" + > + {isRefreshingProviders ? ( + + ) : ( + + )} + + } + /> + Refresh provider status + + ) : null} +
    +
    - {rows.map((row) => { - const driverOption = getDriverOption(row.driver); - const liveProvider = serverProviders.find( - (candidate) => candidate.instanceId === row.instanceId, - ); - const updateCandidate = liveProvider - ? providerUpdateCandidateByInstanceId.get(liveProvider.instanceId) - : undefined; - const isDriverUpdateRunning = - updateCandidate !== undefined && - (updatingProviderDrivers.has(updateCandidate.driver) || - serverProviders.some( - (provider) => - provider.driver === updateCandidate.driver && isProviderUpdateActive(provider), - )); - const showInlineUpdateButton = - updateCandidate !== undefined && - hasOneClickUpdateProviderCandidate(updateCandidate, serverProviders); - const canRunInlineUpdate = - updateCandidate !== undefined && - canOneClickUpdateProviderCandidate(updateCandidate, serverProviders) && - !updatingProviderDrivers.has(updateCandidate.driver); - const modelPreferences = settings.providerModelPreferences?.[row.instanceId] ?? { - hiddenModels: [], - modelOrder: [], - }; - const favoriteModels = Arr.filterMap(settings.favorites ?? [], (favorite) => - favorite.provider === row.instanceId - ? Result.succeed(favorite.model) - : Result.failVoid, - ); - const resetLabel = driverOption?.label ?? String(row.driver); - const headerAction = - row.isDefault && row.isDirty ? ( - resetDefaultInstance(row.driver)} +
    + {selectedRow ? ( + renderProviderInstance(selectedRow, "editor") + ) : ( +
    No providers configured.
    + )} +
    +
    + +
    + + + - ) : null; - return ( - - setOpenInstanceDetails((existing) => ({ - ...existing, - [row.instanceId]: open, - })) - } - onUpdate={(next) => { - const wasEnabled = resolveProviderInstanceEnabled(row.instance); - const isDisabling = next.enabled === false && wasEnabled; - const shouldClearTextGen = isDisabling && textGenInstanceId === row.instanceId; - if (shouldClearTextGen) { - updateProviderInstance(row, next, { - textGenerationModelSelection: - DEFAULT_UNIFIED_SETTINGS.textGenerationModelSelection, - }); - } else { - updateProviderInstance(row, next); + Advanced + + + + Health check interval + + This interval is configured here, then the shared Background activity policy + decides whether provider probes may run when the timer fires. Custom + intervals appear as Advanced in General settings. + + } - }} - onDelete={row.isDefault ? undefined : () => deleteProviderInstance(row.instanceId)} - headerAction={headerAction} - hiddenModels={modelPreferences.hiddenModels} - favoriteModels={favoriteModels} - modelOrder={modelPreferences.modelOrder} - onHiddenModelsChange={(hiddenModels) => - updateProviderModelPreferences(row.instanceId, { - ...modelPreferences, - hiddenModels, - }) - } - onFavoriteModelsChange={(favoriteModels) => - updateProviderFavoriteModels(row.instanceId, favoriteModels) - } - onModelOrderChange={(modelOrder) => - updateProviderModelPreferences(row.instanceId, { - ...modelPreferences, - modelOrder, - }) - } - onRunUpdate={ - showInlineUpdateButton && updateCandidate - ? () => { - if (!canRunInlineUpdate) { - return; + description="Set this to 0 seconds to use manual refresh only." + resetAction={ + providerHealthRefreshIntervalSeconds !== + defaultProviderHealthRefreshIntervalSeconds ? ( + + updateSettings( + backgroundActivityOverrideSettings( + settings.backgroundActivity, + resolvedBackgroundActivity, + { providerHealthRefreshInterval: undefined }, + ), + ) } - void runProviderUpdate(updateCandidate); - } - : undefined - } - isUpdating={showInlineUpdateButton ? isDriverUpdateRunning : undefined} - /> - ); - })} + /> + ) : null + } + control={ +
    + + updateSettings( + backgroundActivityOverrideSettings( + settings.backgroundActivity, + resolvedBackgroundActivity, + { + providerHealthRefreshInterval: Duration.seconds( + normalizeIntervalSeconds(value), + ), + }, + ), + ) + } + > + + + + + + + seconds +
    + } + /> +
    +
    +
    diff --git a/apps/web/src/components/settings/providerSettingsTabs.ts b/apps/web/src/components/settings/providerSettingsTabs.ts new file mode 100644 index 000000000000..1c4e828bacd9 --- /dev/null +++ b/apps/web/src/components/settings/providerSettingsTabs.ts @@ -0,0 +1,10 @@ +import { cn } from "../../lib/utils"; + +export function providerSettingsTabClassName(selected: boolean): string { + return cn( + "relative flex h-full shrink-0 cursor-pointer items-center rounded-sm px-3 text-xs font-medium outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset", + selected + ? "text-foreground after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-primary" + : "text-muted-foreground hover:text-foreground", + ); +} diff --git a/apps/web/src/components/settings/providerStatus.ts b/apps/web/src/components/settings/providerStatus.ts index 06622a761b7e..deac0e58dd06 100644 --- a/apps/web/src/components/settings/providerStatus.ts +++ b/apps/web/src/components/settings/providerStatus.ts @@ -6,7 +6,7 @@ import type { ServerProvider, ServerProviderVersionAdvisory } from "@t3tools/con */ export const PROVIDER_STATUS_STYLES = { disabled: { - dot: "bg-amber-400", + dot: "bg-muted-foreground/50", }, error: { dot: "bg-destructive", diff --git a/apps/web/src/components/threadSidebarWidth.test.ts b/apps/web/src/components/threadSidebarWidth.test.ts deleted file mode 100644 index e38d5c3749bc..000000000000 --- a/apps/web/src/components/threadSidebarWidth.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -// @effect-diagnostics nodeBuiltinImport:off - Regression coverage compares the sidebar component with its width contract. -import * as NodeFS from "node:fs"; - -import { describe, expect, it } from "vite-plus/test"; - -import { - resolveInitialThreadSidebarWidth, - THREAD_MAIN_CONTENT_MIN_WIDTH, - THREAD_SIDEBAR_DEFAULT_WIDTH, - THREAD_SIDEBAR_MIN_WIDTH, -} from "./threadSidebarWidth"; - -describe("thread sidebar width", () => { - it("uses the default width when no preference is stored", () => { - expect(resolveInitialThreadSidebarWidth(null, 1200)).toBe(THREAD_SIDEBAR_DEFAULT_WIDTH); - }); - - it("uses a stored width in the initial render", () => { - expect(resolveInitialThreadSidebarWidth(360, 1200)).toBe(360); - }); - - it("clamps a stored width to the sidebar minimum", () => { - expect(resolveInitialThreadSidebarWidth(120, 1200)).toBe(THREAD_SIDEBAR_MIN_WIDTH); - }); - - it("leaves enough room for the main content on a smaller window", () => { - const viewportWidth = 1000; - - expect(resolveInitialThreadSidebarWidth(900, viewportWidth)).toBe( - viewportWidth - THREAD_MAIN_CONTENT_MIN_WIDTH, - ); - }); - - it("keeps the sidebar minimum when the whole layout is narrower than its minimums", () => { - expect(resolveInitialThreadSidebarWidth(900, 700)).toBe(THREAD_SIDEBAR_MIN_WIDTH); - }); - - it("shows the desktop wordmark across the sidebar's full legal width range", () => { - const sidebarSource = NodeFS.readFileSync( - new URL("./sidebar/SidebarChrome.tsx", import.meta.url), - "utf8", - ); - - expect(sidebarSource).toContain("hidden h-7 w-fit min-w-0 shrink-0 items-center gap-1"); - expect(sidebarSource).toContain("md:flex"); - expect(THREAD_SIDEBAR_MIN_WIDTH).toBe(13 * 16); - }); -}); diff --git a/apps/web/src/components/threadSidebarWidth.ts b/apps/web/src/components/threadSidebarWidth.ts index 93dd196e84da..27589d8f200c 100644 --- a/apps/web/src/components/threadSidebarWidth.ts +++ b/apps/web/src/components/threadSidebarWidth.ts @@ -1,5 +1,5 @@ export const THREAD_SIDEBAR_WIDTH_STORAGE_KEY = "chat_thread_sidebar_width"; -export const THREAD_SIDEBAR_DEFAULT_WIDTH = 16 * 16; +const THREAD_SIDEBAR_DEFAULT_WIDTH = 16 * 16; export const THREAD_SIDEBAR_MIN_WIDTH = 13 * 16; export const THREAD_MAIN_CONTENT_MIN_WIDTH = 40 * 16; diff --git a/apps/web/src/components/ui/toggle-group.test.tsx b/apps/web/src/components/ui/toggle-group.test.tsx deleted file mode 100644 index c2403c9f1175..000000000000 --- a/apps/web/src/components/ui/toggle-group.test.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { renderToStaticMarkup } from "react-dom/server"; -import { describe, expect, it } from "vite-plus/test"; - -import { Toggle, ToggleGroup } from "./toggle-group"; - -describe("toggle group segmented defaults", () => { - it("derives the segmented item size from the variant", () => { - const html = renderToStaticMarkup( - - A - , - ); - - expect(html.match(/data-size="segmented"/g)).toHaveLength(2); - expect(html).toContain("h-6"); - expect(html).toContain("dark:hover:bg-input/32"); - expect(html).toContain("dark:data-pressed:bg-input/72"); - }); -}); diff --git a/apps/web/src/components/usage/UsageProviderChart.test.ts b/apps/web/src/components/usage/UsageProviderChart.test.ts index 09961213b0c4..a4114cfdfb57 100644 --- a/apps/web/src/components/usage/UsageProviderChart.test.ts +++ b/apps/web/src/components/usage/UsageProviderChart.test.ts @@ -86,6 +86,7 @@ describe("buildDayColumns", () => { expect(first?.bands).toEqual([ { provider: "codex", value: 10 }, { provider: "claude", value: 20 }, + { provider: "grok", value: 0 }, ]); }); diff --git a/apps/web/src/components/usage/usageProviders.ts b/apps/web/src/components/usage/usageProviders.ts index 79f62a65a811..efad95e531ad 100644 --- a/apps/web/src/components/usage/usageProviders.ts +++ b/apps/web/src/components/usage/usageProviders.ts @@ -1,6 +1,6 @@ import type { UsageProviderKind } from "@t3tools/contracts"; -import { ClaudeAI, type Icon, OpenAI } from "../Icons"; +import { ClaudeAI, GrokIcon, type Icon, OpenAI } from "../Icons"; type UsageProviderPresentation = { readonly label: string; @@ -24,6 +24,12 @@ export const PROVIDER_PRESENTATION = { color: "#d97757", mark: ClaudeAI, }, + grok: { + label: "Grok Build", + // Contrast-aware neutral between the Codex series and muted chart chrome. + color: "color-mix(in oklab, var(--contrast-foreground) 72%, var(--background))", + mark: GrokIcon, + }, } satisfies Record; /** Stable provider reading order across charts, summaries, tables, and hover rows. */ diff --git a/apps/web/src/reactGrabBoundary.test.ts b/apps/web/src/reactGrabBoundary.test.ts deleted file mode 100644 index 9481e2dd9faf..000000000000 --- a/apps/web/src/reactGrabBoundary.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, expect, it } from "vite-plus/test"; - -import packageJson from "../package.json" with { type: "json" }; -import mainSource from "./main.tsx?raw"; - -describe("React Grab runtime boundary", () => { - it("keeps the host renderer free of the React Grab overlay", () => { - expect(mainSource).not.toMatch(/import\(["']react-grab["']\)/); - expect(packageJson.dependencies).not.toHaveProperty("react-grab"); - expect(packageJson.devDependencies).not.toHaveProperty("react-grab"); - }); -}); diff --git a/assets/README.md b/assets/README.md index 8c53266bfe7f..c1a16dde24b2 100644 --- a/assets/README.md +++ b/assets/README.md @@ -48,3 +48,17 @@ Verify every result is 1024×1024 and has the classic macOS safe area: an 824×8 ``` Do not edit the generated PNG or ICO files directly. + +## Android adaptive foreground + +`apps/mobile/assets/android-icon-foreground.svg` is the source of truth for the foreground used by +the normal Android adaptive launcher icon. Export its paired PNG after changing it: + +```sh +rsvg-convert -w 432 -h 432 \ + -o apps/mobile/assets/android-icon-foreground.png \ + apps/mobile/assets/android-icon-foreground.svg +``` + +The foreground must remain transparent and keep the T3 mark inside Android's adaptive-icon safe +zone. `android-icon-mark.png` remains a flat silhouette for Android's monochrome themed icon. diff --git a/docs/user/install.md b/docs/user/install.md index 15f96e00d4f3..7ef7b97f9375 100644 --- a/docs/user/install.md +++ b/docs/user/install.md @@ -68,6 +68,10 @@ them on in **Settings** → the provider's card when you want to use them. Cursor is the one to watch: install Cursor CLI, which provides the `cursor-agent` binary that T3 Code looks for, but authenticate with `agent login`, not `cursor-agent login`. +Grok models that support adjustable reasoning show a **Reasoning** control beside the model picker. +The available levels and default come from the installed Grok Build CLI, so they can vary by model +and CLI version. + Run the login command on the machine running the T3 Code server, not on the device you browse from. diff --git a/docs/user/permission-modes.md b/docs/user/permission-modes.md index 0648bafc8b77..9bf9c10b20f5 100644 --- a/docs/user/permission-modes.md +++ b/docs/user/permission-modes.md @@ -26,6 +26,9 @@ unattended until it finishes or asks a question of its own. Approvals appear inline in the conversation. Approve or reject one and the agent continues from there. +For Grok, **Always allow this session** remembers the matching command or tool input. Other +actions still ask for approval. It does not change the thread to **Full access**. + ## Choosing a Mode Use **Full access** for work in a worktree or a sandbox you can throw away. @@ -40,8 +43,9 @@ shell commands. Each provider maps these modes onto its own approval and sandbox settings. Codex, for example, translates the mode into its approval policy and sandbox level, so **Supervised** runs the CLI -with prompting enabled and a restricted workspace while **Full access** disables both. The -labels above describe what you get; the exact per-provider translation is internal and may -change. +with prompting enabled and a restricted workspace while **Full access** disables both. Grok +threads do the same: **Supervised** starts Grok in ask mode even if your Grok CLI config is +set to always-approve, and **Full access** starts Grok with always-approve. The labels above +describe what you get; the exact per-provider translation is internal and may change. Mobile offers the same four modes with the same labels and descriptions. diff --git a/docs/user/usage.md b/docs/user/usage.md index 72d19ba77f37..ff38c730c1cd 100644 --- a/docs/user/usage.md +++ b/docs/user/usage.md @@ -1,9 +1,12 @@ # Review usage -The Usage page combines Codex and Claude Code activity from your connected environments. It reads -the providers' local session history and shows API-equivalent token cost, processed tokens, cache -savings, provider shares, and model breakdowns. Subscription billing is separate from the raw token -cost shown here. +The Usage page combines Codex, Claude Code, and Grok Build activity from your connected +environments. It reads the providers' local session history and shows API-equivalent token cost, +processed tokens, cache savings, provider shares, and model breakdowns. Subscription billing is +separate from the raw token cost shown here. + +Grok Build totals come from persisted session updates. Interactive turns that never wrote a +completed-turn record will not appear. Use **Past 24h** for an hourly chart covering the exact rolling 24-hour period. The **7 days**, **30 days**, and **90 days** ranges use daily resolution. Cost and token toggles update both the diff --git a/packages/client-runtime/src/state/session.test.ts b/packages/client-runtime/src/state/session.test.ts deleted file mode 100644 index fe1dcdbe3f2b..000000000000 --- a/packages/client-runtime/src/state/session.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { describe, expect, it } from "@effect/vitest"; -import * as Effect from "effect/Effect"; -import * as Option from "effect/Option"; -import * as Schema from "effect/Schema"; - -import { initialConfigOption } from "./session.ts"; - -class TestConfigError extends Schema.TaggedErrorClass()("TestConfigError", { - message: Schema.String, -}) {} - -describe("environment session state", () => { - it.effect("turns an initial config failure into an empty value", () => - Effect.gen(function* () { - const result = yield* initialConfigOption( - Effect.fail(new TestConfigError({ message: "temporary failure" })), - ); - expect(Option.isNone(result)).toBe(true); - }), - ); -}); diff --git a/packages/client-runtime/src/state/session.ts b/packages/client-runtime/src/state/session.ts index 31fd297da3f0..43adb980f3ad 100644 --- a/packages/client-runtime/src/state/session.ts +++ b/packages/client-runtime/src/state/session.ts @@ -16,7 +16,7 @@ import { executeEnvironmentHttpRequest, makeEnvironmentHttpApiClient } from "../ import { buildEnvironmentAuthHeaders, withEnvironmentCredentials } from "./environmentHttpAuth.ts"; import { followStreamInEnvironment } from "./runtime.ts"; -export function initialConfigOption( +function initialConfigOption( initialConfig: Effect.Effect, ): Effect.Effect> { return initialConfig.pipe( diff --git a/packages/contracts/package.json b/packages/contracts/package.json index f84242d712a1..a0d06e7cd03a 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@t3tools/contracts", - "version": "0.0.34", + "version": "0.0.35", "private": true, "files": [ "dist" diff --git a/packages/contracts/src/usage.ts b/packages/contracts/src/usage.ts index cde888a6153e..8c099ddb33aa 100644 --- a/packages/contracts/src/usage.ts +++ b/packages/contracts/src/usage.ts @@ -2,10 +2,10 @@ * Usage reporting contract. * * Each environment scans the provider CLIs' own on-disk session transcripts - * (`~/.claude/projects/**\/*.jsonl`, `~/.codex/sessions/**\/*.jsonl`) rather than - * relying on T3 Code's own orchestration projections, so usage stays complete - * even for turns that were never driven through T3 Code. This mirrors the - * approach `ccusage` takes. + * (`~/.claude/projects/**\/*.jsonl`, `~/.codex/sessions/**\/*.jsonl`, + * `~/.grok/sessions/**\/updates.jsonl`) rather than relying on T3 Code's own + * orchestration projections, so usage stays complete even for turns that were + * never driven through T3 Code. This mirrors the approach `ccusage` takes. * * Environments return pre-aggregated `(day, hourStart?, provider, model)` * buckets. Raw transcript records never cross the wire. @@ -21,9 +21,18 @@ import { NonNegativeInt, TrimmedNonEmptyString } from "./baseSchemas.ts"; * client renders partial coverage when an environment reports an older version * rather than failing the whole page. */ -export const USAGE_CONTRACT_VERSION = 4 as const; +export const USAGE_CONTRACT_VERSION = 5 as const; -export const UsageProviderKind = Schema.Literals(["claude", "codex"]); +/** + * Oldest {@link UsageSummary} version a current client will still merge. + * + * v5 only adds `grok` to {@link UsageProviderKind}; v4 Claude/Codex buckets + * remain valid, so mixed-version environments keep those totals instead of + * treating every older server as stale. + */ +export const USAGE_MERGE_COMPATIBLE_SINCE = 4 as const; + +export const UsageProviderKind = Schema.Literals(["claude", "codex", "grok"]); export type UsageProviderKind = typeof UsageProviderKind.Type; /** diff --git a/packages/effect-codex-app-server/scripts/generate.ts b/packages/effect-codex-app-server/scripts/generate.ts index 9f23a144524d..44de61d2816a 100644 --- a/packages/effect-codex-app-server/scripts/generate.ts +++ b/packages/effect-codex-app-server/scripts/generate.ts @@ -145,6 +145,33 @@ const ManualSchemas: Record = { }, }; +// Codex 0.150 added these multi-agent values before our next full protocol +// refresh. Keep every generated response namespace compatible with them. +const Codex0150DefinitionSchemas: Record = { + CollabAgentTool: { + type: "string", + enum: [ + "spawnAgent", + "sendInput", + "resumeAgent", + "wait", + "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", + ], + }, + CollabAgentToolCallStatus: { + type: "string", + enum: ["inProgress", "completed", "failed", "interrupted"], + }, + SubAgentActivityKind: { + type: "string", + enum: ["started", "interacted", "interrupted", "completed"], + }, +}; + const getGeneratedPaths = Effect.fn("getGeneratedPaths")(function* () { const path = yield* Path.Path; const generatedDir = path.join(import.meta.dirname, "..", "src", "_generated"); @@ -556,10 +583,12 @@ const generateFiles = Effect.fn("generateFiles")(function* () { ); for (const [definitionName, definitionSchema] of Object.entries(parsed.definitions ?? {})) { + const compatibleDefinitionSchema = + Codex0150DefinitionSchemas[definitionName] ?? definitionSchema; aggregateSchemas[localDefinitionNames.get(definitionName)!] = stripNullDefaults( normalizeNullableTypes( rewriteExternalRefs( - definitionSchema, + compatibleDefinitionSchema, localDefinitionNames, file.namespace, exportNameByQualifiedName, diff --git a/packages/effect-codex-app-server/src/_generated/schema.gen.ts b/packages/effect-codex-app-server/src/_generated/schema.gen.ts index d826df60f192..6b200a42084c 100644 --- a/packages/effect-codex-app-server/src/_generated/schema.gen.ts +++ b/packages/effect-codex-app-server/src/_generated/schema.gen.ts @@ -2616,11 +2616,16 @@ export const ServerNotification__SpendControlLimitSnapshot = Schema.Struct({ used: Schema.String, }); -export type ServerNotification__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type ServerNotification__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const ServerNotification__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type ServerNotification__TerminalInteractionNotification = { @@ -4710,11 +4715,13 @@ export const V2ItemCompletedNotification__ReasoningEffort = Schema.String.annota export type V2ItemCompletedNotification__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2ItemCompletedNotification__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ItemCompletedNotification__TextElement = { @@ -5115,11 +5122,13 @@ export const V2ItemStartedNotification__ReasoningEffort = Schema.String.annotate export type V2ItemStartedNotification__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2ItemStartedNotification__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ItemStartedNotification__TextElement = { @@ -6284,11 +6293,16 @@ export const V2ReviewStartResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2ReviewStartResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2ReviewStartResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2ReviewStartResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ReviewStartResponse__TextElement = { @@ -6720,11 +6734,16 @@ export const V2ThreadForkResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2ThreadForkResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2ThreadForkResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2ThreadForkResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadForkResponse__TextElement = { @@ -7119,11 +7138,16 @@ export const V2ThreadListResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2ThreadListResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2ThreadListResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2ThreadListResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadListResponse__TextElement = { @@ -7463,11 +7487,13 @@ export const V2ThreadMetadataUpdateResponse__ReasoningEffort = Schema.String.ann export type V2ThreadMetadataUpdateResponse__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2ThreadMetadataUpdateResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadMetadataUpdateResponse__TextElement = { @@ -7760,11 +7786,16 @@ export const V2ThreadReadResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2ThreadReadResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2ThreadReadResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2ThreadReadResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadReadResponse__TextElement = { @@ -8342,11 +8373,16 @@ export const V2ThreadResumeResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2ThreadResumeResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2ThreadResumeResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2ThreadResumeResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadResumeResponse__TextElement = { @@ -8643,11 +8679,13 @@ export const V2ThreadRollbackResponse__ReasoningEffort = Schema.String.annotate( export type V2ThreadRollbackResponse__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2ThreadRollbackResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadRollbackResponse__TextElement = { @@ -9051,11 +9089,13 @@ export const V2ThreadStartedNotification__ReasoningEffort = Schema.String.annota export type V2ThreadStartedNotification__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2ThreadStartedNotification__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadStartedNotification__TextElement = { @@ -9458,11 +9498,16 @@ export const V2ThreadStartResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2ThreadStartResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2ThreadStartResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2ThreadStartResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadStartResponse__TextElement = { @@ -9791,11 +9836,13 @@ export const V2ThreadUnarchiveResponse__ReasoningEffort = Schema.String.annotate export type V2ThreadUnarchiveResponse__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2ThreadUnarchiveResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2ThreadUnarchiveResponse__TextElement = { @@ -10095,11 +10142,13 @@ export const V2TurnCompletedNotification__ReasoningEffort = Schema.String.annota export type V2TurnCompletedNotification__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2TurnCompletedNotification__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2TurnCompletedNotification__TextElement = { @@ -10385,11 +10434,13 @@ export const V2TurnStartedNotification__ReasoningEffort = Schema.String.annotate export type V2TurnStartedNotification__SubAgentActivityKind = | "started" | "interacted" - | "interrupted"; + | "interrupted" + | "completed"; export const V2TurnStartedNotification__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2TurnStartedNotification__TextElement = { @@ -10761,11 +10812,16 @@ export const V2TurnStartResponse__ReasoningEffort = Schema.String.annotate({ description: "A non-empty reasoning effort value advertised by the model.", }).check(Schema.isMinLength(1)); -export type V2TurnStartResponse__SubAgentActivityKind = "started" | "interacted" | "interrupted"; +export type V2TurnStartResponse__SubAgentActivityKind = + | "started" + | "interacted" + | "interrupted" + | "completed"; export const V2TurnStartResponse__SubAgentActivityKind = Schema.Literals([ "started", "interacted", "interrupted", + "completed", ]); export type V2TurnStartResponse__TextElement = { @@ -20357,8 +20413,17 @@ export type ServerNotification__ThreadItem = readonly reasoningEffort?: ServerNotification__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -20580,7 +20645,7 @@ export const ServerNotification__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -20589,6 +20654,10 @@ export const ServerNotification__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -21440,8 +21509,17 @@ export type V2ItemCompletedNotification__ThreadItem = readonly reasoningEffort?: V2ItemCompletedNotification__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -21668,7 +21746,7 @@ export const V2ItemCompletedNotification__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -21677,6 +21755,10 @@ export const V2ItemCompletedNotification__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -21891,8 +21973,17 @@ export type V2ItemStartedNotification__ThreadItem = readonly reasoningEffort?: V2ItemStartedNotification__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -22119,7 +22210,7 @@ export const V2ItemStartedNotification__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -22128,6 +22219,10 @@ export const V2ItemStartedNotification__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -22514,8 +22609,17 @@ export type V2ReviewStartResponse__ThreadItem = readonly reasoningEffort?: V2ReviewStartResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -22739,7 +22843,7 @@ export const V2ReviewStartResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -22748,6 +22852,10 @@ export const V2ReviewStartResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -22950,8 +23058,17 @@ export type V2ThreadForkResponse__ThreadItem = readonly reasoningEffort?: V2ThreadForkResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -23175,7 +23292,7 @@ export const V2ThreadForkResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -23184,6 +23301,10 @@ export const V2ThreadForkResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -23355,8 +23476,17 @@ export type V2ThreadListResponse__ThreadItem = readonly reasoningEffort?: V2ThreadListResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -23580,7 +23710,7 @@ export const V2ThreadListResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -23589,6 +23719,10 @@ export const V2ThreadListResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -23762,8 +23896,17 @@ export type V2ThreadMetadataUpdateResponse__ThreadItem = readonly reasoningEffort?: V2ThreadMetadataUpdateResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -23990,7 +24133,7 @@ export const V2ThreadMetadataUpdateResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -23999,6 +24142,10 @@ export const V2ThreadMetadataUpdateResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -24170,8 +24317,17 @@ export type V2ThreadReadResponse__ThreadItem = readonly reasoningEffort?: V2ThreadReadResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -24395,7 +24551,7 @@ export const V2ThreadReadResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -24404,6 +24560,10 @@ export const V2ThreadReadResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -24583,8 +24743,17 @@ export type V2ThreadResumeResponse__ThreadItem = readonly reasoningEffort?: V2ThreadResumeResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -24808,7 +24977,7 @@ export const V2ThreadResumeResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -24817,6 +24986,10 @@ export const V2ThreadResumeResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -24988,8 +25161,17 @@ export type V2ThreadRollbackResponse__ThreadItem = readonly reasoningEffort?: V2ThreadRollbackResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -25216,7 +25398,7 @@ export const V2ThreadRollbackResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -25225,6 +25407,10 @@ export const V2ThreadRollbackResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -25407,8 +25593,17 @@ export type V2ThreadStartedNotification__ThreadItem = readonly reasoningEffort?: V2ThreadStartedNotification__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -25635,7 +25830,7 @@ export const V2ThreadStartedNotification__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -25644,6 +25839,10 @@ export const V2ThreadStartedNotification__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -25815,8 +26014,17 @@ export type V2ThreadStartResponse__ThreadItem = readonly reasoningEffort?: V2ThreadStartResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -26040,7 +26248,7 @@ export const V2ThreadStartResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -26049,6 +26257,10 @@ export const V2ThreadStartResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -26220,8 +26432,17 @@ export type V2ThreadUnarchiveResponse__ThreadItem = readonly reasoningEffort?: V2ThreadUnarchiveResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -26448,7 +26669,7 @@ export const V2ThreadUnarchiveResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -26457,6 +26678,10 @@ export const V2ThreadUnarchiveResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -26630,8 +26855,17 @@ export type V2TurnCompletedNotification__ThreadItem = readonly reasoningEffort?: V2TurnCompletedNotification__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -26858,7 +27092,7 @@ export const V2TurnCompletedNotification__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -26867,6 +27101,10 @@ export const V2TurnCompletedNotification__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -27038,8 +27276,17 @@ export type V2TurnStartedNotification__ThreadItem = readonly reasoningEffort?: V2TurnStartedNotification__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -27266,7 +27513,7 @@ export const V2TurnStartedNotification__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -27275,6 +27522,10 @@ export const V2TurnStartedNotification__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -27446,8 +27697,17 @@ export type V2TurnStartResponse__ThreadItem = readonly reasoningEffort?: V2TurnStartResponse__ReasoningEffort | null; readonly receiverThreadIds: ReadonlyArray; readonly senderThreadId: string; - readonly status: "inProgress" | "completed" | "failed"; - readonly tool: "spawnAgent" | "sendInput" | "resumeAgent" | "wait" | "closeAgent"; + readonly status: "inProgress" | "completed" | "failed" | "interrupted"; + readonly tool: + | "spawnAgent" + | "sendInput" + | "resumeAgent" + | "wait" + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; readonly type: "collabAgentToolCall"; } | { @@ -27669,7 +27929,7 @@ export const V2TurnStartResponse__ThreadItem = Schema.Union( senderThreadId: Schema.String.annotate({ description: "Thread ID of the agent issuing the collab request.", }), - status: Schema.Literals(["inProgress", "completed", "failed"]).annotate({ + status: Schema.Literals(["inProgress", "completed", "failed", "interrupted"]).annotate({ description: "Current status of the collab tool call.", }), tool: Schema.Literals([ @@ -27678,6 +27938,10 @@ export const V2TurnStartResponse__ThreadItem = Schema.Union( "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]).annotate({ description: "Name of the collab tool that was invoked." }), type: Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType", @@ -35971,20 +36235,33 @@ export type ServerNotification__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const ServerNotification__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); -export type ServerNotification__CollabAgentToolCallStatus = "inProgress" | "completed" | "failed"; +export type ServerNotification__CollabAgentToolCallStatus = + | "inProgress" + | "completed" + | "failed" + | "interrupted"; export const ServerNotification__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type ServerNotification__CommandExecOutputStream = "stdout" | "stderr"; @@ -38046,23 +38323,33 @@ export type V2ItemCompletedNotification__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ItemCompletedNotification__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ItemCompletedNotification__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ItemCompletedNotification__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ItemCompletedNotification__CommandExecutionSource = @@ -38183,23 +38470,33 @@ export type V2ItemStartedNotification__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ItemStartedNotification__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ItemStartedNotification__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ItemStartedNotification__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ItemStartedNotification__CommandExecutionSource = @@ -39200,23 +39497,33 @@ export type V2ReviewStartResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ReviewStartResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ReviewStartResponse__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ReviewStartResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ReviewStartResponse__CommandExecutionSource = @@ -39598,20 +39905,33 @@ export type V2ThreadForkResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadForkResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); -export type V2ThreadForkResponse__CollabAgentToolCallStatus = "inProgress" | "completed" | "failed"; +export type V2ThreadForkResponse__CollabAgentToolCallStatus = + | "inProgress" + | "completed" + | "failed" + | "interrupted"; export const V2ThreadForkResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadForkResponse__CommandExecutionSource = @@ -39955,20 +40275,33 @@ export type V2ThreadListResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadListResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); -export type V2ThreadListResponse__CollabAgentToolCallStatus = "inProgress" | "completed" | "failed"; +export type V2ThreadListResponse__CollabAgentToolCallStatus = + | "inProgress" + | "completed" + | "failed" + | "interrupted"; export const V2ThreadListResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadListResponse__CommandExecutionSource = @@ -40131,23 +40464,33 @@ export type V2ThreadMetadataUpdateResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadMetadataUpdateResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ThreadMetadataUpdateResponse__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ThreadMetadataUpdateResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadMetadataUpdateResponse__CommandExecutionSource = @@ -40265,20 +40608,33 @@ export type V2ThreadReadResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadReadResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); -export type V2ThreadReadResponse__CollabAgentToolCallStatus = "inProgress" | "completed" | "failed"; +export type V2ThreadReadResponse__CollabAgentToolCallStatus = + | "inProgress" + | "completed" + | "failed" + | "interrupted"; export const V2ThreadReadResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadReadResponse__CommandExecutionSource = @@ -40964,23 +41320,33 @@ export type V2ThreadResumeResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadResumeResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ThreadResumeResponse__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ThreadResumeResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadResumeResponse__CommandExecutionSource = @@ -41334,23 +41700,33 @@ export type V2ThreadRollbackResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadRollbackResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ThreadRollbackResponse__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ThreadRollbackResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadRollbackResponse__CommandExecutionSource = @@ -41673,23 +42049,33 @@ export type V2ThreadStartedNotification__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadStartedNotification__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ThreadStartedNotification__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ThreadStartedNotification__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadStartedNotification__CommandExecutionSource = @@ -42075,23 +42461,33 @@ export type V2ThreadStartResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadStartResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ThreadStartResponse__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ThreadStartResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadStartResponse__CommandExecutionSource = @@ -42278,23 +42674,33 @@ export type V2ThreadUnarchiveResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2ThreadUnarchiveResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2ThreadUnarchiveResponse__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2ThreadUnarchiveResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2ThreadUnarchiveResponse__CommandExecutionSource = @@ -42412,23 +42818,33 @@ export type V2TurnCompletedNotification__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2TurnCompletedNotification__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2TurnCompletedNotification__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2TurnCompletedNotification__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2TurnCompletedNotification__CommandExecutionSource = @@ -42524,23 +42940,33 @@ export type V2TurnStartedNotification__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2TurnStartedNotification__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); export type V2TurnStartedNotification__CollabAgentToolCallStatus = | "inProgress" | "completed" - | "failed"; + | "failed" + | "interrupted"; export const V2TurnStartedNotification__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2TurnStartedNotification__CommandExecutionSource = @@ -42728,20 +43154,33 @@ export type V2TurnStartResponse__CollabAgentTool = | "sendInput" | "resumeAgent" | "wait" - | "closeAgent"; + | "closeAgent" + | "sendMessage" + | "followupTask" + | "interruptAgent" + | "listAgents"; export const V2TurnStartResponse__CollabAgentTool = Schema.Literals([ "spawnAgent", "sendInput", "resumeAgent", "wait", "closeAgent", + "sendMessage", + "followupTask", + "interruptAgent", + "listAgents", ]); -export type V2TurnStartResponse__CollabAgentToolCallStatus = "inProgress" | "completed" | "failed"; +export type V2TurnStartResponse__CollabAgentToolCallStatus = + | "inProgress" + | "completed" + | "failed" + | "interrupted"; export const V2TurnStartResponse__CollabAgentToolCallStatus = Schema.Literals([ "inProgress", "completed", "failed", + "interrupted", ]); export type V2TurnStartResponse__CommandExecutionSource = diff --git a/packages/effect-codex-app-server/src/schema.test.ts b/packages/effect-codex-app-server/src/schema.test.ts new file mode 100644 index 000000000000..93935aa19aa3 --- /dev/null +++ b/packages/effect-codex-app-server/src/schema.test.ts @@ -0,0 +1,73 @@ +import { assert, it } from "@effect/vitest"; +import * as Schema from "effect/Schema"; + +import * as CodexSchema from "./schema.ts"; + +it("accepts Codex 0.150 multi-agent values", () => { + const schemas = [ + CodexSchema.ServerNotification__SubAgentActivityKind, + CodexSchema.V2ItemStartedNotification__SubAgentActivityKind, + CodexSchema.V2ItemCompletedNotification__SubAgentActivityKind, + CodexSchema.V2ThreadReadResponse__SubAgentActivityKind, + CodexSchema.V2ThreadResumeResponse__SubAgentActivityKind, + ]; + + for (const schema of schemas) { + assert.equal(Schema.is(schema)("completed"), true); + } + + for (const tool of ["sendMessage", "followupTask", "interruptAgent", "listAgents"]) { + assert.equal(Schema.is(CodexSchema.ServerNotification__CollabAgentTool)(tool), true); + assert.equal(Schema.is(CodexSchema.V2ThreadResumeResponse__CollabAgentTool)(tool), true); + } + + assert.equal( + Schema.is(CodexSchema.ServerNotification__CollabAgentToolCallStatus)("interrupted"), + true, + ); + assert.equal( + Schema.is(CodexSchema.V2ThreadResumeResponse__CollabAgentToolCallStatus)("interrupted"), + true, + ); + + const resumeResponse = { + approvalPolicy: "never", + approvalsReviewer: "user", + cwd: "/tmp/project", + model: "gpt-5.6-sol", + modelProvider: "openai", + sandbox: { type: "dangerFullAccess" }, + thread: { + cliVersion: "0.150.0", + createdAt: 0, + cwd: "/tmp/project", + ephemeral: false, + id: "root-thread", + modelProvider: "openai", + preview: "", + sessionId: "session-1", + source: "cli", + status: { type: "idle" }, + turns: [ + { + id: "turn-1", + status: "completed", + items: [ + { + agentsStates: {}, + id: "item-1", + receiverThreadIds: ["child-thread"], + senderThreadId: "root-thread", + status: "interrupted", + tool: "followupTask", + type: "collabAgentToolCall", + }, + ], + }, + ], + updatedAt: 0, + }, + }; + + assert.equal(Schema.is(CodexSchema.V2ThreadResumeResponse)(resumeResponse), true); +}); diff --git a/packages/shared/src/String.test.ts b/packages/shared/src/String.test.ts deleted file mode 100644 index a32b6f28ebf4..000000000000 --- a/packages/shared/src/String.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { describe, expect, it } from "vite-plus/test"; - -import { truncate } from "./String.ts"; - -describe("truncate", () => { - it("trims surrounding whitespace", () => { - expect(truncate(" hello world ")).toBe("hello world"); - }); - - it("returns shorter strings unchanged", () => { - expect(truncate("alpha", 10)).toBe("alpha"); - }); - - it("truncates long strings and appends an ellipsis", () => { - expect(truncate("abcdefghij", 5)).toBe("abcde..."); - }); -}); diff --git a/packages/shared/src/themePreview.test.ts b/packages/shared/src/themePreview.test.ts deleted file mode 100644 index f1cc02e10f7a..000000000000 --- a/packages/shared/src/themePreview.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { describe, expect, it } from "@effect/vitest"; - -import { - mixThemePreviewBase, - STANDARD_THEME_PREVIEW_COLORS, - THEME_PREVIEW_RENDER_SPECS, -} from "./themePreview.js"; - -describe("theme preview", () => { - it("keeps the desktop preview geometry stable across clients", () => { - expect(THEME_PREVIEW_RENDER_SPECS.light!.accent.center).toEqual([0.72, 0.22]); - expect(THEME_PREVIEW_RENDER_SPECS.dark!.accent.middleOpacity).toBe(0.62); - expect(THEME_PREVIEW_RENDER_SPECS.dark!.action.center).toEqual([0.82, 0.18]); - }); - - it("mixes the standard canvas bases in OKLab", () => { - expect(mixThemePreviewBase(STANDARD_THEME_PREVIEW_COLORS.light!, "light")).toBe("#fdfdfd"); - expect(mixThemePreviewBase(STANDARD_THEME_PREVIEW_COLORS.dark!, "dark")).toBe("#0a0a0a"); - }); -}); diff --git a/packages/shared/src/usageMerge.test.ts b/packages/shared/src/usageMerge.test.ts index 3bee4a9bdc02..6c706395c6ff 100644 --- a/packages/shared/src/usageMerge.test.ts +++ b/packages/shared/src/usageMerge.test.ts @@ -158,7 +158,7 @@ describe("mergeUsage", () => { summary( [bucket()], [{ provider: "claude", hostId: "linux", homePath: "/b" }], - USAGE_CONTRACT_VERSION - 1, + USAGE_CONTRACT_VERSION - 2, ), ), ], @@ -169,6 +169,32 @@ describe("mergeUsage", () => { expect(merged.staleEnvironments).toEqual(["env-b"]); }); + it("keeps the previous compatible contract version so additive provider expansions still merge", () => { + const merged = mergeUsage( + [ + environment( + "env-a", + summary( + [bucket({ costUsd: 10 })], + [{ provider: "claude", hostId: "mac", homePath: "/a" }], + ), + ), + environment( + "env-b", + summary( + [bucket({ costUsd: 4, provider: "codex", model: "gpt-5.6-sol" })], + [{ provider: "codex", hostId: "linux", homePath: "/b" }], + USAGE_CONTRACT_VERSION - 1, + ), + ), + ], + USAGE_CONTRACT_VERSION, + ); + + expect(merged.costUsd).toBe(14); + expect(merged.staleEnvironments).toEqual([]); + }); + it("derives provider shares and cost quality", () => { const merged = mergeUsage( [ diff --git a/packages/shared/src/usageMerge.ts b/packages/shared/src/usageMerge.ts index 954139b4e10f..428599d51c74 100644 --- a/packages/shared/src/usageMerge.ts +++ b/packages/shared/src/usageMerge.ts @@ -6,12 +6,13 @@ * * @module usageMerge */ -import type { - EnvironmentId, - UsageBucket, - UsageProviderKind, - UsageSourceFingerprint, - UsageSummary, +import { + USAGE_MERGE_COMPATIBLE_SINCE, + type EnvironmentId, + type UsageBucket, + type UsageProviderKind, + type UsageSourceFingerprint, + type UsageSummary, } from "@t3tools/contracts"; export interface EnvironmentUsage { @@ -172,6 +173,10 @@ function bucketTokens(bucket: UsageBucket): number { ); } +function isCompatibleContractVersion(version: number, expected: number): boolean { + return version >= USAGE_MERGE_COMPATIBLE_SINCE && version <= expected; +} + const EMPTY_MERGED: MergedUsage = { costUsd: 0, uncachedInputTokens: 0, @@ -201,8 +206,10 @@ const EMPTY_MERGED: MergedUsage = { * Merges every connected environment's summary. * * `expectedContractVersion` guards against an environment running older server - * code: rather than blocking the page, its data is excluded and its id is - * reported so the UI can say coverage is partial. + * code: rather than blocking the page, incompatible data is excluded and its + * id is reported so the UI can say coverage is partial. Versions in + * [{@link USAGE_MERGE_COMPATIBLE_SINCE}, expected] still merge, so an additive + * provider expansion does not drop Claude/Codex totals from older servers. */ export function mergeUsage( environments: readonly EnvironmentUsage[], @@ -213,7 +220,7 @@ export function mergeUsage( const current: EnvironmentUsage[] = []; const staleEnvironments: EnvironmentId[] = []; for (const environment of environments) { - if (environment.summary.contractVersion === expectedContractVersion) { + if (isCompatibleContractVersion(environment.summary.contractVersion, expectedContractVersion)) { current.push(environment); } else { staleEnvironments.push(environment.environmentId); diff --git a/scripts/lib/resolve-catalog.test.ts b/scripts/lib/resolve-catalog.test.ts deleted file mode 100644 index ae9a22911571..000000000000 --- a/scripts/lib/resolve-catalog.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { assert, it } from "@effect/vitest"; - -import { CatalogDependencyResolutionError, resolveCatalogDependencies } from "./resolve-catalog.ts"; - -it("reports unresolved catalog dependencies with lookup context", () => { - try { - resolveCatalogDependencies({ effect: "catalog:runtime" }, {}, "apps/server"); - assert.fail("Expected catalog resolution to fail."); - } catch (error) { - assert.instanceOf(error, CatalogDependencyResolutionError); - assert.equal(error.workspacePackage, "apps/server"); - assert.equal(error.dependencyName, "effect"); - assert.equal(error.catalogSpec, "catalog:runtime"); - assert.equal(error.catalogKey, "runtime"); - assert.equal( - error.message, - "Unable to resolve 'catalog:runtime' for apps/server dependency 'effect'. Expected key 'runtime' in root workspace catalog.", - ); - } -}); diff --git a/scripts/lib/resolve-catalog.ts b/scripts/lib/resolve-catalog.ts index eb9d4cc78c8a..0380cf48efb1 100644 --- a/scripts/lib/resolve-catalog.ts +++ b/scripts/lib/resolve-catalog.ts @@ -1,6 +1,6 @@ import * as Schema from "effect/Schema"; -export class CatalogDependencyResolutionError extends Schema.TaggedErrorClass()( +class CatalogDependencyResolutionError extends Schema.TaggedErrorClass()( "CatalogDependencyResolutionError", { workspacePackage: Schema.String,