diff --git a/.agents/backlog-policy.md b/.agents/backlog-policy.md new file mode 100644 index 00000000..3ff7f6f0 --- /dev/null +++ b/.agents/backlog-policy.md @@ -0,0 +1,19 @@ +# Backlog Policy + +GitHub Project: https://github.com/users/espetro/projects/6 + +## Refined task fields + +- **Milestone** — maps to iteration/quarter (e.g. `2026 Q3`). Create the milestone in the repo if it doesn't exist yet. +- **Size** — effort estimate: `XS`/`S`/`M`/`L`/`XL`. Include testing + bug potential per contact surface. +- **Start date** / **Target date** — scheduled window for the task. +- **Label** — classification, drives client positioning: `feature`, `bug`, `cosmetic`, `infra`. Create the label in the repo if it doesn't exist yet. + +## Workflow + +1. Create a GitHub issue in `espetro/calca` with title, body, classification label, milestone. +2. Add it to project 6: `gh project item-add 6 --owner espetro --url `. +3. Set Size/Start date/Target date via `gh project item-edit --project-id --id --field-id ...`. +4. Reference the issue number in the PR description and in the corresponding `.agents/plans/` doc. + +No orphan work: every plan/implementation must link back to a refined task here. diff --git a/apps/server/package.json b/apps/server/package.json index f5ea421d..11fe78f5 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -23,9 +23,10 @@ "@app/core": "workspace:*", "@app/logger": "workspace:*", "@app/shared": "workspace:*", + "@calca/pipeline": "workspace:*", "@hono/node-server": "^1.19.14", "@openfeature/server-sdk": "^1.20.2", - "ai": "^6.0.156", + "ai": "^7.0.0", "hono": "^4.12.14", "zod": "^4.3.6" }, diff --git a/apps/server/src/routes/__tests__/workflow.test.ts b/apps/server/src/routes/__tests__/workflow.test.ts index 1329f7dd..cdfb9a2c 100644 --- a/apps/server/src/routes/__tests__/workflow.test.ts +++ b/apps/server/src/routes/__tests__/workflow.test.ts @@ -1,21 +1,18 @@ +import type { GenerateOptions } from "@app/core/ai/client"; import type { Context } from "hono"; import { beforeEach, describe, expect, it, vi } from "vitest"; -// Mock dependencies before importing the handler -vi.mock("@mastra/ai-sdk", () => ({ - handleWorkflowStream: vi.fn(), +vi.mock("@app/core/ai/client", () => ({ + generateWithFallback: vi.fn(), + streamAnthropic: vi.fn(), })); -vi.mock("ai", () => ({ - createUIMessageStreamResponse: vi.fn(), +vi.mock("@app/core/pipeline/images", () => ({ + generateImages: vi.fn(), })); -vi.mock("../../workflows/mastra", () => ({ - mastra: { _mock: true }, -})); - -import { handleWorkflowStream } from "@mastra/ai-sdk"; -import { createUIMessageStreamResponse } from "ai"; +import { generateWithFallback, streamAnthropic } from "@app/core/ai/client"; +import { generateImages } from "@app/core/pipeline/images"; import { handleWorkflow } from "../workflow"; @@ -27,59 +24,189 @@ function createMockContext(body: unknown): Context { } as unknown as Context; } +async function readStream( + response: Response, +): Promise> { + const reader = response.body!.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + const parts: Array<{ type: string; [key: string]: unknown }> = []; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split("\n"); + buffer = lines.pop() ?? ""; + for (const line of lines) { + const colonIdx = line.indexOf(":"); + if (colonIdx === -1) continue; + try { + parts.push( + JSON.parse(line.slice(colonIdx + 1)) as { type: string; [key: string]: unknown }, + ); + } catch { + // ignore malformed lines + } + } + } + if (buffer.trim()) { + const colonIdx = buffer.indexOf(":"); + if (colonIdx !== -1) { + try { + parts.push( + JSON.parse(buffer.slice(colonIdx + 1)) as { type: string; [key: string]: unknown }, + ); + } catch { + // ignore + } + } + } + return parts; +} + +function buildInput(overrides?: Record): Record { + return { + prompt: "a pricing card", + mode: "sequential", + model: "claude-model", + ...overrides, + }; +} + +function mockGenerateWithFallback() { + (generateWithFallback as ReturnType).mockImplementation( + async (options: GenerateOptions) => { + const functionId = options.functionId ?? ""; + + if (functionId === "plan") { + return { + result: { + text: JSON.stringify([{ name: "Minimal", direction: "Clean" }]), + } as Awaited>["result"], + usedModel: options.model ?? "model", + }; + } + + if (functionId.startsWith("review")) { + return { + result: { text: "
reviewed
" } as Awaited< + ReturnType + >["result"], + usedModel: options.model ?? "model", + }; + } + + if (functionId.startsWith("critique")) { + return { + result: { text: "Looks good" } as Awaited< + ReturnType + >["result"], + usedModel: options.model ?? "model", + }; + } + + if (functionId === "summary") { + return { + result: { text: JSON.stringify({ rationale: "nice" }) } as Awaited< + ReturnType + >["result"], + usedModel: options.model ?? "model", + }; + } + + return { + result: { text: "" } as Awaited>["result"], + usedModel: options.model ?? "model", + }; + }, + ); +} + +function mockStreamAnthropic() { + (streamAnthropic as ReturnType).mockResolvedValue({ + text: Promise.resolve(`\n
hello
`), + }); +} + +function mockGenerateImages() { + (generateImages as ReturnType).mockImplementation(async () => ({ + html: `
hello
`, + imageCount: 0, + skipped: true, + reason: "no keys", + })); +} + describe("handleWorkflow", () => { beforeEach(() => { vi.clearAllMocks(); + mockGenerateWithFallback(); + mockStreamAnthropic(); + mockGenerateImages(); }); - it("returns a UI message stream response on success", async () => { - const mockStream = { [Symbol.asyncIterator]: vi.fn() }; - const mockResponse = new Response(null, { status: 200 }); + it("returns an SSE response with correct headers", async () => { + const ctx = createMockContext(buildInput()); + const response = await handleWorkflow(ctx); - (handleWorkflowStream as ReturnType).mockResolvedValue(mockStream); - (createUIMessageStreamResponse as ReturnType).mockReturnValue(mockResponse); - - const ctx = createMockContext({ prompt: "a pricing card" }); - const result = await handleWorkflow(ctx); + expect(response.headers.get("Content-Type")).toBe("text/event-stream; charset=utf-8"); + expect(response.headers.get("Cache-Control")).toBe("no-cache, no-transform"); + expect(response.headers.get("X-Accel-Buffering")).toBe("no"); + }); - expect(ctx.req.json).toHaveBeenCalledOnce(); - expect(handleWorkflowStream).toHaveBeenCalledOnce(); - expect(handleWorkflowStream).toHaveBeenCalledWith({ - mastra: expect.anything(), - params: { inputData: { prompt: "a pricing card" } }, - version: "v6", - workflowId: "designPipeline", + it("streams data-workflow parts through the pipeline", async () => { + const ctx = createMockContext(buildInput()); + const response = await handleWorkflow(ctx); + const parts = await readStream(response); + + const workflowParts = parts.filter((p) => p.type === "data-workflow"); + expect(workflowParts.length).toBeGreaterThan(0); + + const first = workflowParts[0] as unknown as { + data: { name: string; status: string; steps: Record }; + }; + expect(first.data.name).toBe("designPipeline"); + expect(first.data.status).toBe("running"); + expect(first.data.steps.plan).toMatchObject({ name: "plan", status: "running" }); + + const last = workflowParts[workflowParts.length - 1] as unknown as { + data: { + status: string; + steps: Record; + }; + }; + expect(last.data.status).toBe("success"); + expect(last.data.steps.collectResults?.output).toMatchObject({ + frames: [ + expect.objectContaining({ + html: "
reviewed
", + label: "Variation 1", + }), + ], + summary: expect.stringContaining("rationale"), }); - expect(createUIMessageStreamResponse).toHaveBeenCalledWith({ stream: mockStream }); - expect(result).toBe(mockResponse); }); - it("propagates errors from handleWorkflowStream", async () => { - (handleWorkflowStream as ReturnType).mockRejectedValue( - new Error("workflow exploded"), - ); - - const ctx = createMockContext({ prompt: "fail" }); + it("passes the full request body to the pipeline", async () => { + const body = { conceptCount: 4, mode: "quick", prompt: "hero section", model: "claude-model" }; + const ctx = createMockContext(body); + const response = await handleWorkflow(ctx); + await readStream(response); - await expect(handleWorkflow(ctx)).rejects.toThrow("workflow exploded"); - expect(createUIMessageStreamResponse).not.toHaveBeenCalled(); + expect(ctx.req.json).toHaveBeenCalledOnce(); + expect(streamAnthropic).toHaveBeenCalledWith(expect.objectContaining({ model: body.model })); }); - it("passes the full request body as inputData", async () => { - const body = { conceptCount: 4, preset: "marketing", prompt: "hero section" }; - const mockStream = {}; - const mockResponse = new Response(null, { status: 200 }); + it("emits an error part when the pipeline throws", async () => { + (streamAnthropic as ReturnType).mockRejectedValue(new Error("layout exploded")); - (handleWorkflowStream as ReturnType).mockResolvedValue(mockStream); - (createUIMessageStreamResponse as ReturnType).mockReturnValue(mockResponse); - - const ctx = createMockContext(body); - await handleWorkflow(ctx); + const ctx = createMockContext(buildInput()); + const response = await handleWorkflow(ctx); + const parts = await readStream(response); - expect(handleWorkflowStream).toHaveBeenCalledWith( - expect.objectContaining({ - params: { inputData: body }, - }), - ); + const errorParts = parts.filter((p) => p.type === "error"); + expect(errorParts.length).toBeGreaterThan(0); + expect(errorParts[0]).toMatchObject({ type: "error", errorText: "layout exploded" }); }); }); diff --git a/apps/server/src/routes/workflow.ts b/apps/server/src/routes/workflow.ts index 98d9f288..bef9c617 100644 --- a/apps/server/src/routes/workflow.ts +++ b/apps/server/src/routes/workflow.ts @@ -1,24 +1,18 @@ -import { handleWorkflowStream } from "@mastra/ai-sdk"; -import { createUIMessageStreamResponse } from "ai"; +import { designPipelineStream } from "@calca/pipeline"; import { type Context, Hono } from "hono"; -import { mastra } from "../workflows/mastra"; - export async function handleWorkflow(c: Context) { const body = await c.req.json(); - - const stream = await handleWorkflowStream({ - mastra, - params: { inputData: body }, - version: "v6", - workflowId: "designPipeline", + const stream = designPipelineStream(body); + return new Response(stream, { + headers: { + "Content-Type": "text/event-stream; charset=utf-8", + "Cache-Control": "no-cache, no-transform", + "X-Accel-Buffering": "no", + }, }); - - return createUIMessageStreamResponse({ stream }); } -const route = new Hono() - // - .post("/", handleWorkflow); +const route = new Hono().post("/", handleWorkflow); export default route; diff --git a/apps/server/src/workflows/design-pipeline.workflow.ts b/apps/server/src/workflows/design-pipeline.workflow.ts deleted file mode 100644 index 2b030f77..00000000 --- a/apps/server/src/workflows/design-pipeline.workflow.ts +++ /dev/null @@ -1,498 +0,0 @@ -import { getLogger } from "@app/logger"; -import { createStep, createWorkflow } from "@mastra/core/workflows"; -import { z } from "zod"; - -import type { CritiqueOutput } from "./schemas/critique.schema"; -import type { ImagesOutput } from "./schemas/images.schema"; -import type { LayoutOutput } from "./schemas/layout.schema"; -import { PlanOutputSchema } from "./schemas/plan.schema"; -import type { ReviewOutput } from "./schemas/review.schema"; -import { critiqueStep } from "./steps/critique.step"; -import { imagesStep } from "./steps/images.step"; -import { layoutStep } from "./steps/layout.step"; -import { planStep } from "./steps/plan.step"; -import { reviewStep } from "./steps/review.step"; -import { summaryStep } from "./steps/summary.step"; - -const logger = getLogger(["calca", "server", "workflow"]); - -// ── Workflow-level schemas ──────────────────────────────────────────────────── - -const WorkflowInputSchema = z.object({ - prompt: z.string(), - mode: z.enum(["quick", "sequential"]), - conceptCount: z.number().optional(), - model: z.string().optional(), - apiKey: z.string().optional(), - baseURL: z.string().optional(), - providerType: z.string().optional(), - geminiKey: z.string().optional(), - unsplashKey: z.string().optional(), - openaiKey: z.string().optional(), - systemPrompt: z.string().optional(), - contextImages: z.array(z.string()).optional(), - revision: z.string().optional(), - existingHtml: z.string().optional(), -}); - -const FrameResultSchema = z.object({ - html: z.string(), - width: z.number().optional(), - height: z.number().optional(), - label: z.string(), - comment: z.string().optional(), - critique: z.string().optional(), -}); - -const FrameOrchestratorOutputSchema = z.object({ - frames: z.array(FrameResultSchema), - html: z.string(), - prompt: z.string(), - labels: z.array(z.string()), - model: z.string().optional(), - apiKey: z.string().optional(), - baseURL: z.string().optional(), - providerType: z.string().optional(), -}); - -const WorkflowOutputSchema = z.object({ - frames: z.array(FrameResultSchema), - summary: z.string().optional(), -}); - -type WorkflowInput = z.infer; -type FrameResult = z.infer; - -// Mastra step.execute() returns `TOutput | InnerOutput` where InnerOutput -// is the return of suspend(). Since our steps never suspend, we safely -// narrow via this helper. -const unwrap = (result: unknown): T => result as T; - -// ── Frame orchestrator step ─────────────────────────────────────────────────── -// -// Receives plan output (concepts) and the full workflow input via getInitData(). -// Runs the per-frame pipeline (layout → images → review → critique) with -// branching for quick vs sequential mode. - -const frameOrchestratorStep = createStep({ - id: "frameOrchestrator", - description: - "Runs the per-frame pipeline for each concept. Quick mode = parallel. Sequential mode = sequential with critique loop.", - inputSchema: PlanOutputSchema, - outputSchema: FrameOrchestratorOutputSchema, - execute: async ({ inputData, getInitData, writer, abortSignal }) => { - const start = performance.now(); - const { concepts } = inputData; - const init = getInitData(); - const { - mode, - prompt, - model, - apiKey, - baseURL, - providerType, - geminiKey, - unsplashKey, - openaiKey, - systemPrompt, - contextImages, - revision, - existingHtml, - } = init; - - const isQuickMode = mode === "quick"; - const total = concepts.length; - - logger.info("Pipeline step starting", { step: "frameOrchestrator", model }); - - const runFramePipeline = async ( - concept: { name: string; direction: string }, - index: number, - previousCritique?: string, - ): Promise => { - const conceptStr = concept.direction ? `${concept.name}: ${concept.direction}` : concept.name; - let html: string; - let width: number | undefined; - let height: number | undefined; - let comment: string | undefined; - - writer.write({ - type: "workflow-step", - step: "layout", - frameIndex: index, - progress: 0.2 + (index / total) * 0.6, - }); - - { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "layout", frameIndex: index, model }); - const layoutResult = unwrap( - await layoutStep.execute({ - inputData: { - prompt, - concept: conceptStr, - critique: previousCritique, - systemPrompt, - model, - apiKey, - baseURL, - providerType, - contextImages, - revision, - existingHtml, - frameIndex: index, - }, - writer, - abortSignal, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "layout", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - html = layoutResult.html; - width = layoutResult.width; - height = layoutResult.height; - comment = layoutResult.comment; - } - - writer.write({ - type: "workflow-step", - step: "images", - frameIndex: index, - progress: 0.4 + (index / total) * 0.6, - }); - - { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "images", frameIndex: index }); - const imagesResult = unwrap( - await imagesStep.execute({ - inputData: { - html, - geminiKey, - unsplashKey, - openaiKey, - viewport: width && height ? { width, height } : undefined, - }, - writer, - abortSignal, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "images", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - html = imagesResult.html; - } - - if (!isQuickMode) { - writer.write({ - type: "workflow-step", - step: "review", - frameIndex: index, - progress: 0.7 + (index / total) * 0.3, - }); - - { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "review", frameIndex: index, model }); - const reviewResult = unwrap( - await reviewStep.execute({ - inputData: { - html, - prompt, - width, - height, - model, - apiKey, - baseURL, - providerType, - frameIndex: index, - }, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "review", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - html = reviewResult.html; - } - } - - let critiqueText: string | undefined; - - if (!isQuickMode) { - writer.write({ - type: "workflow-step", - step: "critique", - frameIndex: index, - progress: 0.9 + (index / total) * 0.1, - }); - - try { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "critique", frameIndex: index, model }); - const critiqueResult = unwrap( - await critiqueStep.execute({ - inputData: { - html, - prompt, - model, - apiKey, - baseURL, - providerType, - frameIndex: index, - }, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "critique", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - critiqueText = critiqueResult.critique; - } catch { - // critique is optional — continue without it - } - } - - writer.write({ - type: "workflow-step", - step: "images", - frameIndex: index, - progress: 0.4 + (index / total) * 0.6, - }); - - { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "images", frameIndex: index }); - const imagesResult = unwrap( - await imagesStep.execute({ - inputData: { - html: html!, - geminiKey, - unsplashKey, - openaiKey, - viewport: width! && height! ? { width: width!, height: height! } : undefined, - }, - writer, - abortSignal, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "images", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - html = imagesResult.html; - } - - if (!isQuickMode) { - writer.write({ - type: "workflow-step", - step: "review", - frameIndex: index, - progress: 0.7 + (index / total) * 0.3, - }); - - { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "review", frameIndex: index, model }); - const reviewResult = unwrap( - await reviewStep.execute({ - inputData: { - html, - prompt, - width, - height, - model, - apiKey, - baseURL, - providerType, - frameIndex: index, - }, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "review", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - html = reviewResult.html; - } - } - - if (!isQuickMode) { - writer.write({ - type: "workflow-step", - step: "critique", - frameIndex: index, - progress: 0.9 + (index / total) * 0.1, - }); - - try { - const start = performance.now(); - logger.info("Pipeline step starting", { step: "critique", frameIndex: index, model }); - const critiqueResult = unwrap( - await critiqueStep.execute({ - inputData: { - html, - prompt, - model, - apiKey, - baseURL, - providerType, - frameIndex: index, - }, - } as Parameters[0]), - ); - logger.info("Pipeline step completed", { - step: "critique", - frameIndex: index, - durationMs: Math.round(performance.now() - start), - }); - critiqueText = critiqueResult.critique; - } catch { - // critique is optional — continue without it - } - } - - writer.write({ - type: "workflow-step", - step: "frameComplete", - frameIndex: index, - progress: (index + 1) / total, - }); - - return { - html, - width, - height, - label: `Variation ${index + 1}`, - comment, - critique: critiqueText, - }; - }; - - // ── Execute frames ───────────────────────────────────────────────────── - - let frames: FrameResult[]; - - if (isQuickMode) { - writer.write({ - type: "workflow-step", - step: "frameOrchestrator", - progress: 0.1, - message: `Running ${total} frames in parallel`, - }); - - const results = await Promise.allSettled( - concepts.map((concept, i) => runFramePipeline(concept, i)), - ); - - frames = results.map((r, i) => { - if (r.status === "fulfilled") return r.value; - logger.warn(`Frame ${i + 1} failed:`, r.reason); - return { - html: `

⚠ Frame ${i + 1} failed

`, - label: `Variation ${i + 1}`, - }; - }); - } else { - // Sequential mode: iterate one at a time, passing previous critique - frames = []; - let previousCritique: string | undefined; - - for (let i = 0; i < concepts.length; i++) { - if (abortSignal.aborted) break; - - writer.write({ - type: "workflow-step", - step: "frameOrchestrator", - frameIndex: i, - progress: i / total, - message: `Designing ${i + 1} of ${total}…`, - }); - - try { - // oxlint-disable-next-line no-await-in-loop - const result = await runFramePipeline(concepts[i]!, i, previousCritique); - frames.push(result); - previousCritique = result.critique; - } catch (error) { - if (error instanceof Error && error.name === "AbortError") throw error; - logger.warn(`Frame ${i + 1} failed:`, { error }); - frames.push({ - html: `

⚠ Frame ${i + 1} failed

`, - label: `Variation ${i + 1}`, - }); - } - } - } - - // ── Build output ─────────────────────────────────────────────────────── - const lastFrame = frames[frames.length - 1]; - const labels = frames.map((f) => f.label).filter(Boolean); - logger.info("Pipeline step completed", { - step: "frameOrchestrator", - durationMs: Math.round(performance.now() - start), - }); - - return { - frames, - html: lastFrame?.html ?? "", - prompt, - labels, - model, - apiKey, - baseURL, - providerType, - }; - }, -}); - -// ── Collect results step ────────────────────────────────────────────────────── -// -// Combines frame results (from frameOrchestratorStep) with the summary -// (from summaryStep) into the final workflow output. - -const collectResultsStep = createStep({ - id: "collectResults", - inputSchema: z.object({ summary: z.string() }), - outputSchema: WorkflowOutputSchema, - execute: async ({ inputData, getStepResult }) => { - const frameData = getStepResult(frameOrchestratorStep); - return { - frames: frameData.frames, - summary: inputData.summary, - }; - }, -}); - -// ── Workflow definition ─────────────────────────────────────────────────────── -// -// Plan → Frame orchestrator (quick/sequential branching) → Summary → Collect - -export const designPipeline = createWorkflow({ - id: "designPipeline", - inputSchema: WorkflowInputSchema, - outputSchema: WorkflowOutputSchema, -}) - .then(planStep) - .then(frameOrchestratorStep) - .then(summaryStep) - .then(collectResultsStep) - .commit(); - -export { - WorkflowInputSchema, - WorkflowOutputSchema, - FrameOrchestratorOutputSchema, - FrameResultSchema, - frameOrchestratorStep, - collectResultsStep, -}; diff --git a/apps/server/src/workflows/mastra.ts b/apps/server/src/workflows/mastra.ts deleted file mode 100644 index 17fecfd0..00000000 --- a/apps/server/src/workflows/mastra.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Mastra } from "@mastra/core"; - -import { designPipeline } from "./design-pipeline.workflow"; - -export const mastra = new Mastra({ - workflows: { - designPipeline, - }, -}); diff --git a/apps/server/src/workflows/schemas/critique.schema.ts b/apps/server/src/workflows/schemas/critique.schema.ts deleted file mode 100644 index aed5476e..00000000 --- a/apps/server/src/workflows/schemas/critique.schema.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { z } from "zod"; - -export const CritiqueInputSchema = z.object({ - apiKey: z.string().optional(), - baseURL: z.string().optional(), - html: z.string(), - model: z.string().optional(), - prompt: z.string(), - providerType: z.string().optional(), - frameIndex: z.number().optional(), -}); - -export const CritiqueOutputSchema = z.object({ - critique: z.string(), -}); - -export type CritiqueInput = z.infer; -export type CritiqueOutput = z.infer; diff --git a/apps/server/src/workflows/schemas/images.schema.ts b/apps/server/src/workflows/schemas/images.schema.ts deleted file mode 100644 index 37cf03f5..00000000 --- a/apps/server/src/workflows/schemas/images.schema.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { z } from "zod"; - -export const ImagesInputSchema = z.object({ - geminiKey: z.string().optional(), - html: z.string(), - openaiKey: z.string().optional(), - unsplashKey: z.string().optional(), - viewport: z.object({ height: z.number(), width: z.number() }).optional(), -}); - -export const ImagesOutputSchema = z.object({ - html: z.string(), -}); - -export type ImagesInput = z.infer; -export type ImagesOutput = z.infer; diff --git a/apps/server/src/workflows/schemas/index.ts b/apps/server/src/workflows/schemas/index.ts deleted file mode 100644 index f3213036..00000000 --- a/apps/server/src/workflows/schemas/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./plan.schema"; -export * from "./layout.schema"; -export * from "./images.schema"; -export * from "./review.schema"; -export * from "./critique.schema"; -export * from "./summary.schema"; diff --git a/apps/server/src/workflows/schemas/layout.schema.ts b/apps/server/src/workflows/schemas/layout.schema.ts deleted file mode 100644 index 89f08900..00000000 --- a/apps/server/src/workflows/schemas/layout.schema.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { z } from "zod"; - -export const LayoutInputSchema = z.object({ - prompt: z.string(), - concept: z.string().optional(), - contextImages: z.array(z.string()).optional(), - critique: z.string().optional(), - revision: z.boolean().optional(), - existingHtml: z.string().optional(), - systemPrompt: z.string().optional(), - model: z.string().optional(), - apiKey: z.string().optional(), - baseURL: z.string().optional(), - providerType: z.string().optional(), - frameIndex: z.number().optional(), -}); - -export const LayoutOutputSchema = z.object({ - html: z.string(), - width: z.number().optional(), - height: z.number().optional(), - comment: z.string().optional(), -}); - -export type LayoutInput = z.infer; -export type LayoutOutput = z.infer; diff --git a/apps/server/src/workflows/schemas/plan.schema.ts b/apps/server/src/workflows/schemas/plan.schema.ts deleted file mode 100644 index e6da7a2e..00000000 --- a/apps/server/src/workflows/schemas/plan.schema.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from "zod"; - -export const PlanInputSchema = z.object({ - apiKey: z.string().optional(), - baseURL: z.string().optional(), - model: z.string().optional(), - prompt: z.string(), - providerType: z.string().optional(), -}); - -export const ConceptSchema = z.object({ - direction: z.string(), - name: z.string(), -}); - -export const PlanOutputSchema = z.object({ - concepts: z.array(ConceptSchema), - count: z.number(), -}); - -export type PlanInput = z.infer; -export type Concept = z.infer; -export type PlanOutput = z.infer; diff --git a/apps/server/src/workflows/schemas/review.schema.ts b/apps/server/src/workflows/schemas/review.schema.ts deleted file mode 100644 index 1dc0443c..00000000 --- a/apps/server/src/workflows/schemas/review.schema.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { z } from "zod"; - -export const ReviewInputSchema = z.object({ - html: z.string(), - prompt: z.string(), - width: z.number().optional(), - height: z.number().optional(), - model: z.string().optional(), - apiKey: z.string().optional(), - baseURL: z.string().optional(), - providerType: z.string().optional(), - frameIndex: z.number().optional(), -}); - -export const ReviewOutputSchema = z.object({ - html: z.string(), - width: z.number().optional(), - height: z.number().optional(), -}); - -export type ReviewInput = z.infer; -export type ReviewOutput = z.infer; diff --git a/apps/server/src/workflows/schemas/summary.schema.ts b/apps/server/src/workflows/schemas/summary.schema.ts deleted file mode 100644 index 7abfa223..00000000 --- a/apps/server/src/workflows/schemas/summary.schema.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { z } from "zod"; - -export const SummaryInputSchema = z.object({ - apiKey: z.string().optional(), - baseURL: z.string().optional(), - html: z.string(), - labels: z.array(z.string()).optional(), - model: z.string().optional(), - prompt: z.string(), - providerType: z.string().optional(), -}); - -export const SummaryOutputSchema = z.object({ - summary: z.string(), -}); - -export type SummaryInput = z.infer; -export type SummaryOutput = z.infer; diff --git a/apps/server/src/workflows/steps/critique.step.ts b/apps/server/src/workflows/steps/critique.step.ts deleted file mode 100644 index 0e349462..00000000 --- a/apps/server/src/workflows/steps/critique.step.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { generateWithFallback } from "@app/core/ai/client"; -import type { ProviderType } from "@app/core/ai/providers"; -import { buildCritiquePrompt } from "@app/core/prompts/critique"; -import { createStep } from "@mastra/core/workflows"; -import type { ModelMessage } from "ai"; - -import { stripBase64Images } from "../../lib/strip-base64"; -import { CritiqueInputSchema, CritiqueOutputSchema } from "../schemas/critique.schema"; - -export const critiqueStep = createStep({ - id: "critique", - inputSchema: CritiqueInputSchema, - outputSchema: CritiqueOutputSchema, - execute: async ({ inputData }) => { - const { html, prompt, model, apiKey, baseURL, providerType, frameIndex } = inputData; - const frameIdx = frameIndex ?? 0; - - // Strip base64 images to reduce token usage - const { stripped } = stripBase64Images(html); - - const messages: ModelMessage[] = [ - { - role: "user", - content: buildCritiquePrompt(prompt || "", stripped), - }, - ]; - - const { result } = await generateWithFallback({ - apiKey, - model: model, - messages, - maxTokens: 1024, - providerType: providerType as ProviderType | undefined, - baseURL, - functionId: `critique:${frameIdx + 1}`, - frameIndex: frameIdx, - }); - - return { - critique: result.text, - }; - }, -}); diff --git a/apps/server/src/workflows/steps/images.step.ts b/apps/server/src/workflows/steps/images.step.ts deleted file mode 100644 index 480251a0..00000000 --- a/apps/server/src/workflows/steps/images.step.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { generateImages } from "@app/core/pipeline/images"; -import { getLogger } from "@app/logger"; -import { createStep } from "@mastra/core/workflows"; - -import { ImagesInputSchema, ImagesOutputSchema } from "../schemas/images.schema"; - -const logger = getLogger(["calca", "server", "workflow", "images"]); - -export const imagesStep = createStep({ - execute: async ({ inputData, writer, abortSignal }) => { - const { html, geminiKey, unsplashKey, openaiKey, viewport } = inputData; - - if (!geminiKey && !unsplashKey && !openaiKey) { - writer.write({ - message: "No image API keys provided - skipping image generation", - stage: "images", - type: "progress", - }); - return { html }; - } - - writer.write({ - message: "Starting image generation...", - stage: "images", - type: "progress", - }); - - try { - const result = await generateImages({ - geminiKey, - html, - openaiKey, - unsplashKey, - viewport, - }); - - if (result.imageCount > 0) { - writer.write({ - current: result.imageCount, - message: `Generated ${result.imageCount} image(s)`, - stage: "images", - total: result.imageCount, - type: "progress", - }); - } - - if (result.skipped) { - writer.write({ - message: result.reason || "Image generation skipped", - stage: "images", - type: "progress", - }); - } - - return { html: result.html }; - } catch (error) { - if (error instanceof Error) { - logger.error(`[Images Step] Generation failed:\n${error.message}`); - } else { - logger.error(`[Images Step] Generation failed:`, { error }); - } - - writer.write({ - message: "Image generation failed - returning HTML unchanged", - stage: "images", - type: "progress", - }); - - return { html }; - } - }, - id: "images", - inputSchema: ImagesInputSchema, - outputSchema: ImagesOutputSchema, -}); diff --git a/apps/server/src/workflows/steps/layout.step.ts b/apps/server/src/workflows/steps/layout.step.ts deleted file mode 100644 index 0fbbaf20..00000000 --- a/apps/server/src/workflows/steps/layout.step.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { streamAnthropic } from "@app/core/ai/client"; -import type { ProviderType } from "@app/core/ai/providers"; -import { buildNewPrompt, buildRevisionUserContent } from "@app/core/prompts/layout"; -import { validateLayout } from "@app/shared"; -import { createStep } from "@mastra/core/workflows"; -import { type ImagePart, type ModelMessage, type TextPart } from "ai"; - -import { parseHtmlWithSize } from "../../lib/parse-html"; -import { stripBase64Images } from "../../lib/strip-base64"; -import { LayoutInputSchema, LayoutOutputSchema } from "../schemas/layout.schema"; - -const HEARTBEAT_INTERVAL_MS = 5_000; - -export const layoutStep = createStep({ - id: "layout", - description: "Generate HTML/CSS layout from a design prompt using AI streaming", - inputSchema: LayoutInputSchema, - outputSchema: LayoutOutputSchema, - execute: async ({ inputData, abortSignal, writer }) => { - const { - prompt, - contextImages = [], - critique, - revision, - existingHtml, - systemPrompt, - model, - apiKey, - baseURL, - providerType, - frameIndex, - } = inputData; - - const useModel = model; - const isRevision = !!(revision && existingHtml); - const frameIdx = frameIndex ?? 0; - const functionId = `layout:${frameIdx + 1}`; - - // ── Build user content ────────────────────────────────────────── - let userContent: string; - let restoreFn: ((s: string) => string) | null = null; - - if (isRevision && existingHtml) { - const { stripped, restore } = stripBase64Images(existingHtml); - restoreFn = restore; - userContent = buildRevisionUserContent(systemPrompt, stripped, prompt, String(revision)); - } else { - userContent = buildNewPrompt(systemPrompt, critique, prompt, "", []); - } - - // ── Build message parts (text + optional context images) ──────── - const userParts: (TextPart | ImagePart)[] = []; - const imageTokenMap: Record = {}; - - if (contextImages.length > 0) { - const validTypes = new Set(["image/jpeg", "image/png", "image/gif", "image/webp"]); - const imageRefs: string[] = []; - - for (let i = 0; i < contextImages.length; i++) { - const dataUrl = contextImages[i]!; - const match = dataUrl.match(/^data:(image\/[^;]+);base64,(.+)$/); - if (match && validTypes.has(match[1])) { - const token = `[USER_IMAGE_${i + 1}]`; - imageTokenMap[token] = dataUrl; - - userParts.push({ type: "image", image: dataUrl }); - imageRefs.push(`- Image ${i + 1}: Use src="${token}" to place this image`); - } - } - - if (imageRefs.length > 0) { - userParts.push({ - type: "text", - text: `USER-PROVIDED IMAGES — USE THESE IN THE DESIGN: -The ${imageRefs.length} image${imageRefs.length > 1 ? "s" : "is"} provided by the user to include IN the design. - -${imageRefs.join("\n")} - -RULES FOR USER IMAGES: -- Place them as tags using the token as the src attribute (e.g., ) -- Position them where they fit best in the design layout -- You can use each image once or multiple times -- Style them with CSS (border-radius, object-fit, shadows, etc.) -- Do NOT use placeholder divs for content these images cover -- You can STILL use data-placeholder divs for ADDITIONAL images beyond what the user provided - -`, - }); - } - } - - userParts.push({ type: "text", text: userContent }); - - // ── Build messages array ──────────────────────────────────────── - const messages: ModelMessage[] = [ - { - role: "user", - content: - userParts.length === 1 && userParts[0]!.type === "text" ? userParts[0]!.text : userParts, - }, - ]; - - // ── Stream with heartbeat ─────────────────────────────────────── - const stream = streamAnthropic({ - model: useModel, - apiKey, - providerType: providerType as ProviderType | undefined, - baseURL, - messages, - maxTokens: 16384, - enableCaching: true, - systemPrompt: systemPrompt || "", - functionId, - frameIndex: frameIdx, - }); - - const heartbeatInterval = setInterval(() => { - writer - .write({ - type: "heartbeat", - stage: "layout", - timestamp: Date.now(), - }) - .catch(() => {}); - }, HEARTBEAT_INTERVAL_MS); - - try { - const fullText = await Promise.race([ - stream.text, - new Promise((_, reject) => { - if (abortSignal.aborted) { - reject(new DOMException("Aborted", "AbortError")); - return; - } - abortSignal.addEventListener( - "abort", - () => { - reject(new DOMException("Aborted", "AbortError")); - }, - { once: true }, - ); - }), - ]); - - clearInterval(heartbeatInterval); - - // ── Validate / parse result ────────────────────────────────── - let result: { html: string; width?: number; height?: number; comment?: string }; - try { - result = validateLayout(fullText); - } catch { - result = parseHtmlWithSize(fullText, { extractComments: true }); - } - - // ── Restore base64 images (revision mode) ──────────────────── - if (restoreFn) { - result = { ...result, html: restoreFn(result.html) }; - } - - // ── Replace user image tokens with actual data URLs ────────── - for (const [token, dataUrl] of Object.entries(imageTokenMap)) { - result.html = result.html.replaceAll(token, dataUrl); - } - - return { - html: result.html, - width: result.width, - height: result.height, - comment: result.comment, - }; - } finally { - clearInterval(heartbeatInterval); - } - }, -}); diff --git a/apps/server/src/workflows/steps/plan.step.ts b/apps/server/src/workflows/steps/plan.step.ts deleted file mode 100644 index 1e3e84e6..00000000 --- a/apps/server/src/workflows/steps/plan.step.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { generateWithFallback } from "@app/core/ai/client"; -import type { ProviderType } from "@app/core/ai/providers"; -import { buildPlanPrompt } from "@app/core/prompts/plan"; -import { getLogger } from "@app/logger"; -import { createStep } from "@mastra/core/workflows"; -import type { ModelMessage } from "ai"; - -import { PlanInputSchema, PlanOutputSchema } from "../schemas/plan.schema"; - -const logger = getLogger(["calca", "server", "workflow", "plan"]); - -const VARIATION_STYLES = [ - { name: "Minimal", direction: "Clean lines, generous whitespace, restrained color palette" }, - { name: "Bold", direction: "High contrast, striking typography, confident composition" }, - { name: "Organic", direction: "Soft shapes, warm tones, natural textures" }, -]; - -export const planStep = createStep({ - id: "plan", - inputSchema: PlanInputSchema, - outputSchema: PlanOutputSchema, - execute: async ({ inputData }) => { - const { prompt, model, apiKey, baseURL, providerType } = inputData; - const useModel = model; - - const messages: ModelMessage[] = [ - { - role: "user", - content: buildPlanPrompt(prompt), - }, - ]; - - try { - const { result } = await generateWithFallback({ - apiKey, - model: useModel, - messages, - maxTokens: 2048, - providerType: providerType as ProviderType | undefined, - baseURL, - functionId: "plan", - }); - - const raw = result.text; - - // Try to parse as JSON array of concepts - let concepts: Array<{ name: string; direction: string }>; - try { - const parsed = JSON.parse(raw); - if (Array.isArray(parsed)) { - concepts = parsed.map((c: { name?: string; direction?: string }) => ({ - name: c.name || "Variation", - direction: c.direction || "", - })); - } else if (parsed.concepts && Array.isArray(parsed.concepts)) { - concepts = parsed.concepts.map((c: { name?: string; direction?: string }) => ({ - name: c.name || "Variation", - direction: c.direction || "", - })); - } else { - throw new Error("Unexpected plan response format"); - } - } catch { - // Fallback: try to extract concepts from text - const lines = raw.split("\n").filter((l) => l.trim()); - concepts = lines.slice(0, 3).map((line, i) => ({ - name: line.split(":")[0]?.trim() || `Variation ${i + 1}`, - direction: line.split(":")[1]?.trim() || line.trim(), - })); - } - - if (concepts.length === 0) { - throw new Error("No concepts generated"); - } - - return { - count: concepts.length, - concepts, - }; - } catch (error) { - logger.warn("Plan generation failed, using fallback:", { error }); - return { - count: VARIATION_STYLES.length, - concepts: VARIATION_STYLES, - }; - } - }, -}); diff --git a/apps/server/src/workflows/steps/review.step.ts b/apps/server/src/workflows/steps/review.step.ts deleted file mode 100644 index 4ff90e1f..00000000 --- a/apps/server/src/workflows/steps/review.step.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { generateWithFallback } from "@app/core/ai/client"; -import type { ProviderType } from "@app/core/ai/providers"; -import { buildReviewPrompt } from "@app/core/prompts/review"; -import { getLogger } from "@app/logger"; -import { validateReview } from "@app/shared"; -import { createStep } from "@mastra/core/workflows"; -import type { ModelMessage } from "ai"; - -import { parseHtmlWithSize } from "../../lib/parse-html"; -import { stripBase64Images } from "../../lib/strip-base64"; -import { ReviewInputSchema, ReviewOutputSchema } from "../schemas/review.schema"; - -const logger = getLogger(["calca", "server", "workflow", "review"]); - -export const reviewStep = createStep({ - id: "review", - inputSchema: ReviewInputSchema, - outputSchema: ReviewOutputSchema, - execute: async ({ inputData }) => { - const { html, prompt, width, height, model, apiKey, baseURL, providerType, frameIndex } = - inputData; - const useModel = model; - const frameIdx = frameIndex ?? 0; - - const { stripped, restore } = stripBase64Images(html); - - const messages: ModelMessage[] = [ - { - role: "user", - content: buildReviewPrompt(prompt || "", width, height, stripped), - }, - ]; - - const { result } = await generateWithFallback({ - apiKey, - model: useModel, - messages, - maxTokens: 16384, - providerType: providerType as ProviderType | undefined, - baseURL, - functionId: `review:${frameIdx + 1}`, - frameIndex: frameIdx, - }); - - const raw = result.text; - - try { - const validated = validateReview(raw); - return { - html: restore(validated.html), - width: validated.width || width, - height: validated.height || height, - }; - } catch (error) { - logger.warn("Review validation failed, returning parsed output:", { error }); - const parsed = parseHtmlWithSize(raw); - return { - html: restore(parsed.html), - width: parsed.width || width, - height: parsed.height || height, - }; - } - }, -}); diff --git a/apps/server/src/workflows/steps/summary.step.ts b/apps/server/src/workflows/steps/summary.step.ts deleted file mode 100644 index 4edcc14d..00000000 --- a/apps/server/src/workflows/steps/summary.step.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { generateWithFallback } from "@app/core/ai/client"; -import type { ProviderType } from "@app/core/ai/providers"; -import { buildSummaryPrompt } from "@app/core/prompts/summary"; -import { getLogger } from "@app/logger"; -import { validateSummary } from "@app/shared"; -import { createStep } from "@mastra/core/workflows"; -import type { ModelMessage } from "ai"; - -import { stripBase64Images } from "../../lib/strip-base64"; -import { SummaryInputSchema, SummaryOutputSchema } from "../schemas/summary.schema"; - -const logger = getLogger(["calca", "server", "workflow", "summary"]); - -export const summaryStep = createStep({ - id: "summary", - inputSchema: SummaryInputSchema, - outputSchema: SummaryOutputSchema, - execute: async ({ inputData }) => { - const { html, prompt, labels, model, apiKey, baseURL, providerType } = inputData; - - const { stripped } = stripBase64Images(html); - - const messages: ModelMessage[] = [ - { - role: "user", - content: buildSummaryPrompt(prompt, stripped, labels ?? []), - }, - ]; - - const { result } = await generateWithFallback({ - apiKey, - model: model, - messages, - maxTokens: 512, - providerType: providerType as ProviderType | undefined, - baseURL, - functionId: "summary", - }); - - const raw = result.text; - try { - const parsed = JSON.parse(raw); - const validated = validateSummary(parsed); - return { summary: JSON.stringify(validated) }; - } catch (error) { - logger.warn("Summary validation failed:", { error }); - return { summary: raw }; - } - }, -}); diff --git a/bun.lock b/bun.lock index 072f4e8f..4fd6d1aa 100644 --- a/bun.lock +++ b/bun.lock @@ -7,8 +7,6 @@ "dependencies": { "@ai-sdk/provider-utils": "^4.0.23", "@inlang/paraglide-js-adapter-vite": "^1.2.40", - "@mastra/ai-sdk": "^1.4.0", - "@mastra/core": "^1.25.0", "type-fest": "^5.6.0", }, "devDependencies": { @@ -72,9 +70,10 @@ "@app/core": "workspace:*", "@app/logger": "workspace:*", "@app/shared": "workspace:*", + "@calca/pipeline": "workspace:*", "@hono/node-server": "^1.19.14", "@openfeature/server-sdk": "^1.20.2", - "ai": "^6.0.156", + "ai": "^7.0.0", "hono": "^4.12.14", "zod": "^4.3.6", }, @@ -160,13 +159,13 @@ "name": "@app/core", "version": "0.6.1", "dependencies": { - "@ai-sdk/anthropic": "^3.0.68", - "@ai-sdk/google": "^3.0.61", - "@ai-sdk/openai-compatible": "^2.0.41", - "@ai-sdk/provider": "3.0.8", - "@ai-sdk/provider-utils": "4.0.23", + "@ai-sdk/anthropic": "^4.0.0", + "@ai-sdk/google": "^4.0.0", + "@ai-sdk/openai-compatible": "^3.0.0", + "@ai-sdk/provider": "^4.0.0", + "@ai-sdk/provider-utils": "^4.0.0", "@app/logger": "workspace:*", - "ai": "^6.0.156", + "ai": "^7.0.0", "zod": "^4.3.6", }, "devDependencies": { @@ -187,6 +186,26 @@ "vitest": "^4.1.1", }, }, + "packages/pipeline": { + "name": "@calca/pipeline", + "version": "0.6.1", + "dependencies": { + "@ai-sdk/anthropic": "^4.0.0", + "@ai-sdk/openai": "^4.0.0", + "@opentelemetry/api": "^1.9.0", + "ai": "^7.0.0", + "zod": "^4.3.6", + }, + "devDependencies": { + "typescript": "^6.0.3", + "vitest": "^4.1.4", + }, + "peerDependencies": { + "@app/core": "workspace:*", + "@app/logger": "workspace:*", + "@app/shared": "workspace:*", + }, + }, "packages/pro": { "name": "@app/pro", "version": "0.6.1", @@ -223,31 +242,21 @@ }, }, "packages": { - "@a2a-js/sdk": ["@a2a-js/sdk@0.3.13", "", { "dependencies": { "uuid": "^11.1.0" }, "peerDependencies": { "@bufbuild/protobuf": "^2.10.2", "@grpc/grpc-js": "^1.11.0", "express": "^4.21.2 || ^5.1.0" }, "optionalPeers": ["@bufbuild/protobuf", "@grpc/grpc-js", "express"] }, "sha512-BZr0f9JVNQs3GKOM9xINWCh6OKIJWZFPyqqVqTym5mxO2Eemc6I/0zL7zWnljHzGdaf5aZQyQN5xa6PSH62q+A=="], - "@adobe/css-tools": ["@adobe/css-tools@4.4.4", "", {}, "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg=="], - "@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.75", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-5AV3CKwaOJFdGXhihVgvRLNrjwRn2Xmy71YygT8DYOA+5zTx93Seg2QSIS8b3tJxzZ7X4H84pEtrE8VZKBCZGA=="], - - "@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.110", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-sbv8+1L9/BRKydn8dMNwoMQKupA4iLJ9N+yvxgW6wMQ/94UepDf3FeYWMj/dLdzolAHZ6izRUP4s5WqQkmJ2Zg=="], - - "@ai-sdk/google": ["@ai-sdk/google@3.0.67", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Qeq+SidYtzMrcf0fdw3L0QLmtXK+ErwdBzbxS4+0Q/2UP85Ges8RJJcbAj7SO8e2JbeJoM35BLqkeNy1o3wJvQ=="], + "@ai-sdk/anthropic": ["@ai-sdk/anthropic@4.0.40", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@ai-sdk/provider-utils": "5.0.28" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-cFlCZspCUC1LGDipARsKx3+4A8c9qI+vFuG0/04Phs0deKwifNsl8wDmcU2HO31aiNR9AJgEBcvg5S00zUS70g=="], - "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.46", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-23ExGdy3p0Grfz3BAjCbIOc74TjQc5nHu72e0+kx3hshvScp32a4nnQlzzG4VT1bDZxa9yPNNUNyb5nN6vJHcQ=="], + "@ai-sdk/gateway": ["@ai-sdk/gateway@4.0.56", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@ai-sdk/provider-utils": "5.0.28", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-fc7tq+v7WrzCV+aXegbq/EOs68tFDJYLEwnCOnVYcB/Y5ZTjUIHzyJlrqdoJUlMTkc/qmKsXb1ovVvdUYPmxIA=="], - "@ai-sdk/provider": ["@ai-sdk/provider@3.0.8", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ=="], + "@ai-sdk/google": ["@ai-sdk/google@4.0.47", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@ai-sdk/provider-utils": "5.0.28" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Aj/VRSDpNmxjC0mU1qWNI9BydRoRI3INVHv1KZcFj3lI7rdxmXuenhUfXw8KnfZlREWX3J3rM9JNF1khuxGfnw=="], - "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.26", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CsKNLKsOpvPujRlIYvoz+Ybw+kGn7J4/fIZa/58+R7iWLLfwn6ifE2G6Yq8K9XvH/I/3bzaDAJ3NhRwEMsLBKQ=="], - - "@ai-sdk/provider-utils-v5": ["@ai-sdk/provider-utils@3.0.23", "", { "dependencies": { "@ai-sdk/provider": "2.0.1", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-60GYsRj5wIJQRcq5YwYJq4KhwLeStceXEJiZdecP1miiH+6FMmrnc7lZDOJoQ6m9lrudEb+uI4LEwddLz5+rPQ=="], - - "@ai-sdk/provider-utils-v6": ["@ai-sdk/provider-utils@4.0.23", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-z8GlDaCmRSDlqkMF2f4/RFgWxdarvIbyuk+m6WXT1LYgsnGiXRJGTD2Z1+SDl3LqtFuRtGX1aghYvQLoHL/9pg=="], + "@ai-sdk/openai": ["@ai-sdk/openai@4.0.44", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@ai-sdk/provider-utils": "5.0.28" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-x3XjhKu5r7DKELWwE5WzCAKePkAqZXlgvat4eIiSm37MaQHk+n3qeJxmVcfqJWlQ2kkAld8+f7G3E3yjG+4ShQ=="], - "@ai-sdk/provider-v5": ["@ai-sdk/provider@2.0.1", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng=="], + "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@3.0.32", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@ai-sdk/provider-utils": "5.0.28" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-G4zNrIHW965LuyVJz7KJrmqO6y7xgwVJZ2RmYo8TA3cPhpKSmbjw7fLF6Z9iZbqiz+oBvHHbSXl4HH8xlro8AQ=="], - "@ai-sdk/provider-v6": ["@ai-sdk/provider@3.0.8", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ=="], + "@ai-sdk/provider": ["@ai-sdk/provider@4.0.7", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6or44XprPzKbr8zkmzosowSE0pxkvJcoojBL+mCZvPUt3kvXp3XSNqeVun9golb1acEfSo6yaEBRT18h2VU+1Q=="], - "@ai-sdk/ui-utils-v5": ["@ai-sdk/ui-utils@1.2.11", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w=="], + "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.26", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CsKNLKsOpvPujRlIYvoz+Ybw+kGn7J4/fIZa/58+R7iWLLfwn6ifE2G6Yq8K9XvH/I/3bzaDAJ3NhRwEMsLBKQ=="], "@app/analytics": ["@app/analytics@workspace:packages/analytics"], @@ -345,6 +354,8 @@ "@bramus/specificity": ["@bramus/specificity@2.4.2", "", { "dependencies": { "css-tree": "^3.0.0" }, "bin": { "specificity": "bin/cli.js" } }, "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw=="], + "@calca/pipeline": ["@calca/pipeline@workspace:packages/pipeline"], + "@capsizecss/unpack": ["@capsizecss/unpack@4.0.0", "", { "dependencies": { "fontkitten": "^1.0.0" } }, "sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA=="], "@changesets/apply-release-plan": ["@changesets/apply-release-plan@7.1.1", "", { "dependencies": { "@changesets/config": "^3.1.4", "@changesets/get-version-range-type": "^0.4.0", "@changesets/git": "^3.0.4", "@changesets/should-skip-package": "^0.1.2", "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", "lodash.startcase": "^4.4.0", "outdent": "^0.5.0", "prettier": "^2.7.1", "resolve-from": "^5.0.0", "semver": "^7.5.3" } }, "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA=="], @@ -637,8 +648,6 @@ "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], - "@isaacs/ttlcache": ["@isaacs/ttlcache@2.1.4", "", {}, "sha512-7kMz0BJpMvgAMkyglums7B2vtrn5g0a0am77JY0GjkZZNetOBCFn7AG7gKCwT0QPiXyxW7YIQSgtARknUEOcxQ=="], - "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], @@ -661,10 +670,6 @@ "@logtape/pretty": ["@logtape/pretty@2.0.7", "", { "peerDependencies": { "@logtape/logtape": "^2.0.7" } }, "sha512-FluT3vEBsZcK4cIuPAUTK6+RiAGQgnvFU1J76WJ0NJMReoDb4wbd2R/vO/n9SxND676hELgdP4X/RC82w9ieeg=="], - "@lukeed/csprng": ["@lukeed/csprng@1.1.0", "", {}, "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA=="], - - "@lukeed/uuid": ["@lukeed/uuid@2.0.1", "", { "dependencies": { "@lukeed/csprng": "^1.1.0" } }, "sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w=="], - "@malept/cross-spawn-promise": ["@malept/cross-spawn-promise@1.1.1", "", { "dependencies": { "cross-spawn": "^7.0.1" } }, "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ=="], "@mantine/hooks": ["@mantine/hooks@9.1.1", "", { "peerDependencies": { "react": "^19.2.0" } }, "sha512-tTJK73nGFyy1v214TLdvBq0be7QCoc6osfbXVuJgOH3YG85lWk9Mvvor6k+w6hC6HXSqKMqLKePyiGm83xGcMg=="], @@ -673,14 +678,6 @@ "@manypkg/get-packages": ["@manypkg/get-packages@1.1.3", "", { "dependencies": { "@babel/runtime": "^7.5.5", "@changesets/types": "^4.0.1", "@manypkg/find-root": "^1.1.0", "fs-extra": "^8.1.0", "globby": "^11.0.0", "read-yaml-file": "^1.1.0" } }, "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A=="], - "@mastra/ai-sdk": ["@mastra/ai-sdk@1.4.1", "", { "peerDependencies": { "@mastra/core": ">=1.5.0-0 <2.0.0-0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-IwLu9ePbNmSqkPbv2ixrz/DPGlWJA/WCWrs7Lp7bCH76XzwF/JD/OHiQ5Cmm/+uXfgC3uxfejusFT3IKFOSZJA=="], - - "@mastra/core": ["@mastra/core@1.32.1", "", { "dependencies": { "@a2a-js/sdk": "~0.3.13", "@ai-sdk/provider-utils-v5": "npm:@ai-sdk/provider-utils@3.0.23", "@ai-sdk/provider-utils-v6": "npm:@ai-sdk/provider-utils@4.0.23", "@ai-sdk/provider-v5": "npm:@ai-sdk/provider@2.0.1", "@ai-sdk/provider-v6": "npm:@ai-sdk/provider@3.0.8", "@ai-sdk/ui-utils-v5": "npm:@ai-sdk/ui-utils@1.2.11", "@isaacs/ttlcache": "^2.1.4", "@lukeed/uuid": "^2.0.1", "@mastra/schema-compat": "1.2.9", "@modelcontextprotocol/sdk": "^1.29.0", "@sindresorhus/slugify": "^2.2.1", "@standard-schema/spec": "^1.1.0", "ajv": "^8.18.0", "chat": "^4.24.0", "croner": "^10.0.1", "dotenv": "^17.3.1", "execa": "^9.6.1", "gray-matter": "^4.0.3", "hono": "^4.12.8", "hono-openapi": "^1.3.0", "ignore": "^7.0.5", "js-tiktoken": "^1.0.21", "json-schema": "^0.4.0", "lru-cache": "^11.2.7", "p-map": "^7.0.4", "p-retry": "^7.1.1", "picomatch": "^4.0.3", "radash": "^12.1.1", "tokenx": "^1.3.0", "ws": "^8.20.0", "xxhash-wasm": "^1.1.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-6ynJNZ9GMkLs11c9D4Ui9Z0eOP8GsAqPeMVhlnxExcdTls0ufFQSXFgwzBqtS97fot9IOA/fxDLvvW83fnsP0A=="], - - "@mastra/schema-compat": ["@mastra/schema-compat@1.2.9", "", { "dependencies": { "json-schema-to-zod": "^2.7.0", "zod-from-json-schema": "^0.5.2", "zod-from-json-schema-v3": "npm:zod-from-json-schema@^0.0.5", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-1/RgazXqi1Wdyx8aR81CVS+sRyzlTGUL1YhhHkSULoEY8aXs58bvWkH/6iixlYsY0xGvn+0OPLCeSRkBCtDx4Q=="], - - "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.29.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ=="], - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], @@ -971,8 +968,6 @@ "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.3", "", { "os": "win32", "cpu": "x64" }, "sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA=="], - "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], - "@shikijs/core": ["@shikijs/core@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-NSWQz0riNb67xthdm5br6lAkvpDJRTgB36fxlo37ZzM2yq0PQFFzbd8psqC2XMPgCzo1fW6cVi18+ArJ44wqgA=="], "@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.23.0", "", { "dependencies": { "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.4" } }, "sha512-aHt9eiGFobmWR5uqJUViySI1bHMqrAgamWE1TYSUoftkAeCCAiGawPMwM+VCadylQtF4V3VNOZ5LmfItH5f3yA=="], @@ -995,18 +990,8 @@ "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], - "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], - - "@sindresorhus/slugify": ["@sindresorhus/slugify@2.2.1", "", { "dependencies": { "@sindresorhus/transliterate": "^1.0.0", "escape-string-regexp": "^5.0.0" } }, "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw=="], - - "@sindresorhus/transliterate": ["@sindresorhus/transliterate@1.6.0", "", { "dependencies": { "escape-string-regexp": "^5.0.0" } }, "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ=="], - "@speed-highlight/core": ["@speed-highlight/core@1.2.15", "", {}, "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw=="], - "@standard-community/standard-json": ["@standard-community/standard-json@0.3.5", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "@types/json-schema": "^7.0.15", "@valibot/to-json-schema": "^1.3.0", "arktype": "^2.1.20", "effect": "^3.16.8", "quansync": "^0.2.11", "sury": "^10.0.0", "typebox": "^1.0.17", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-to-json-schema": "^3.24.5" }, "optionalPeers": ["@valibot/to-json-schema", "arktype", "effect", "sury", "typebox", "valibot", "zod", "zod-to-json-schema"] }, "sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA=="], - - "@standard-community/standard-openapi": ["@standard-community/standard-openapi@0.2.9", "", { "peerDependencies": { "@standard-community/standard-json": "^0.3.5", "@standard-schema/spec": "^1.0.0", "arktype": "^2.1.20", "effect": "^3.17.14", "openapi-types": "^12.1.3", "sury": "^10.0.0", "typebox": "^1.0.0", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-openapi": "^4" }, "optionalPeers": ["arktype", "effect", "sury", "typebox", "valibot", "zod", "zod-openapi"] }, "sha512-htj+yldvN1XncyZi4rehbf9kLbu8os2Ke/rfqoZHCMHuw34kiF3LP/yQPdA0tQ940y8nDq3Iou8R3wG+AGGyvg=="], - "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], "@tailwindcss/browser": ["@tailwindcss/browser@4.2.4", "", {}, "sha512-yd+3CxxuF1KDt9Q+405JR3/vyotvS5eMIsZPEynEak/JybvFVn8mVmLjVUxgNmrFB6EGCc89lXBECzIZA+YeXQ=="], @@ -1211,9 +1196,7 @@ "@vscode/l10n": ["@vscode/l10n@0.0.18", "", {}, "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ=="], - "@workflow/serde": ["@workflow/serde@4.1.0-beta.2", "", {}, "sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww=="], - - "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], + "@workflow/serde": ["@workflow/serde@4.1.0", "", {}, "sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ=="], "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], @@ -1225,14 +1208,12 @@ "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - "ai": ["ai@6.0.175", "", { "dependencies": { "@ai-sdk/gateway": "3.0.110", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-6fFFHzbh6FIZnYc31V6osOxq25ABJYCShfG0O6ajHiA4FB/DgnPi1mP8cO5aAU3HNSbQHiMazdlh9bIsp97mVA=="], + "ai": ["ai@7.0.70", "", { "dependencies": { "@ai-sdk/gateway": "4.0.56", "@ai-sdk/provider": "4.0.7", "@ai-sdk/provider-utils": "5.0.28" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-r7Y0alVQqairf0WvT3puyjz5wPMjRV5zYSHiGz87K3uoqkCeK1EaN6O8lLqduSszLcfqC6XVJAIdy3/RkPwPHg=="], - "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + "ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "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@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], - "ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="], "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], @@ -1285,8 +1266,6 @@ "base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="], - "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.10.27", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA=="], "basic-ftp": ["basic-ftp@5.3.1", "", {}, "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw=="], @@ -1301,8 +1280,6 @@ "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], - "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], - "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], @@ -1321,8 +1298,6 @@ "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="], - "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], - "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], "call-bind": ["call-bind@1.0.9", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" } }, "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ=="], @@ -1351,8 +1326,6 @@ "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], - "chat": ["chat@4.27.0", "", { "dependencies": { "@workflow/serde": "4.1.0-beta.2", "mdast-util-to-string": "^4.0.0", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "remend": "^1.2.1", "unified": "^11.0.5" } }, "sha512-PrL4k263DSIlckhX8eHLT84RdTSznOBxCCfaDc5JVJtWaS0lJkCNctm/g3gIrI41AcDHcpc/3WDoUHVrbh0W4w=="], - "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], @@ -1387,10 +1360,6 @@ "consola": ["consola@3.2.3", "", {}, "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ=="], - "content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], - - "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], - "conventional-changelog-angular": ["conventional-changelog-angular@8.3.1", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-6gfI3otXK5Ph5DfCOI1dblr+kN3FAm5a97hYoQkqNZxOaYa5WKfXH+AnpsmS+iUH2mgVC2Cg2Qw9m5OKcmNrIg=="], "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@9.3.1", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-dTYtpIacRpcZgrvBYvBfArMmK2xvIpv2TaxM0/ZI5CBtNUzvF2x0t15HsbRABWprS6UPmvj+PzHVjSx4qAVKyw=="], @@ -1403,12 +1372,8 @@ "cookie-es": ["cookie-es@1.2.3", "", {}, "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw=="], - "cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="], - "core-js": ["core-js@3.49.0", "", {}, "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg=="], - "cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="], - "cosmiconfig": ["cosmiconfig@9.0.1", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ=="], "cosmiconfig-typescript-loader": ["cosmiconfig-typescript-loader@6.3.0", "", { "dependencies": { "jiti": "2.6.1" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA=="], @@ -1417,8 +1382,6 @@ "create-require": ["create-require@1.1.1", "", {}, "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="], - "croner": ["croner@10.0.1", "", {}, "sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g=="], - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "cross-spawn-windows-exe": ["cross-spawn-windows-exe@1.2.0", "", { "dependencies": { "@malept/cross-spawn-promise": "^1.1.0", "is-wsl": "^2.2.0", "which": "^2.0.2" } }, "sha512-mkLtJJcYbDCxEG7Js6eUnUNndWjyUZwJ3H7bErmmtOYU/Zb99DyUkpamuIZE0b3bhmJyZ7D90uS6f+CGxRRjOw=="], @@ -1467,8 +1430,6 @@ "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], - "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], - "deprecation": ["deprecation@2.3.1", "", {}, "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], @@ -1517,8 +1478,6 @@ "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], - "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "electrobun": ["electrobun@1.18.1", "", { "dependencies": { "@babylonjs/core": "^7.45.0", "@types/bun": "^1.3.8", "png-to-ico": "^2.1.8", "proxy-agent": "^6.5.0", "rcedit": "^4.0.1", "three": "^0.165.0" }, "bin": { "electrobun": "bin/electrobun.cjs" } }, "sha512-tgZ+WKGskn/1/Y5i1mpVCCkgRa1O31Tz7MIArBTK44GfPzT43uOq9c/HvxdQGrLeZV8ZvjK1lQrwqSXCgh6tvA=="], "electron-to-chromium": ["electron-to-chromium@1.5.351", "", {}, "sha512-9D7Iqx8RImSvCnOsj86rCH6eQjZFQoM04Jn6HnZVM0Nu/G58/gmKYQ1d12MZTbjQbQSTGI8nwEy07ErsA2slLA=="], @@ -1527,8 +1486,6 @@ "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], - "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], - "enhanced-resolve": ["enhanced-resolve@5.21.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA=="], "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="], @@ -1557,9 +1514,7 @@ "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@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], "escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="], @@ -1583,26 +1538,14 @@ "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], - "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], - "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], - "eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="], - "eventsource-parser": ["eventsource-parser@3.0.8", "", {}, "sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ=="], - "execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="], - "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], - "express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="], - - "express-rate-limit": ["express-rate-limit@8.5.0", "", { "dependencies": { "ip-address": "10.1.0" }, "peerDependencies": { "express": ">= 4.11" } }, "sha512-XKhFohWaSBdVJNTi5TaHziqnPkv04I9UQV6q1Wy7Ui6GGQZVW12ojDFwqer14EvCXxjvPG0CyWXx7cAXpALB4Q=="], - "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], - "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], - "extendable-error": ["extendable-error@0.1.7", "", {}, "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg=="], "fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="], @@ -1623,14 +1566,10 @@ "fflate": ["fflate@0.4.8", "", {}, "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="], - "figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="], - "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], - "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], - "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], @@ -1649,10 +1588,6 @@ "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.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], - "forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="], - - "fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="], - "fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -1673,8 +1608,6 @@ "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], - "get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], - "get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="], "git-raw-commits": ["git-raw-commits@5.0.1", "", { "dependencies": { "@conventional-changelog/git-client": "^2.6.0", "meow": "^13.0.0" }, "bin": { "git-raw-commits": "src/cli.js" } }, "sha512-Y+csSm2GD/PCSh6Isd/WiMjNAydu0VBiG9J7EdQsNA5P9uXvLayqjmTsNlK5Gs9IhblFZqOU0yid5Il5JPoLiQ=="], @@ -1693,8 +1626,6 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], - "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="], - "guess-json-indent": ["guess-json-indent@2.0.0", "", {}, "sha512-3Tm6R43KhtZWEVSHZnFmYMV9+gf3Vu0HXNNYtPVk2s7o8eGwYlJPHrjLtYw/7HBc10YxV+bfzKMuOf24z5qFng=="], "h3": ["h3@1.15.11", "", { "dependencies": { "cookie-es": "^1.2.3", "crossws": "^0.3.5", "defu": "^6.1.6", "destr": "^2.0.5", "iron-webcrypto": "^1.2.1", "node-mock-http": "^1.0.4", "radix3": "^1.1.2", "ufo": "^1.6.3", "uncrypto": "^0.1.3" } }, "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg=="], @@ -1729,8 +1660,6 @@ "hono": ["hono@4.12.17", "", {}, "sha512-FbJJNb/XgX7YW0hX/V8w5oYLztKEsRLykCMZWt1WdLtsfjzMvmoqWBA4H4t5norinq8/rh20oiZYr+WSl4UzAQ=="], - "hono-openapi": ["hono-openapi@1.3.0", "", { "peerDependencies": { "@hono/standard-validator": "^0.2.0", "@standard-community/standard-json": "^0.3.5", "@standard-community/standard-openapi": "^0.2.9", "@types/json-schema": "^7.0.15", "hono": "^4.8.3", "openapi-types": "^12.1.3" }, "optionalPeers": ["@hono/standard-validator", "hono"] }, "sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig=="], - "html-encoding-sniffer": ["html-encoding-sniffer@6.0.0", "", { "dependencies": { "@exodus/bytes": "^1.6.0" } }, "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg=="], "html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="], @@ -1743,16 +1672,12 @@ "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.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], "human-id": ["human-id@4.1.3", "", { "bin": { "human-id": "dist/cli.js" } }, "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q=="], - "human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], - "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], "ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -1769,9 +1694,7 @@ "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], - "ip-address": ["ip-address@10.1.0", "", {}, "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q=="], - - "ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], + "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], "iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="], @@ -1783,8 +1706,6 @@ "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="], - "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], - "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=="], @@ -1793,8 +1714,6 @@ "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-network-error": ["is-network-error@1.3.1", "", {}, "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw=="], - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], @@ -1803,16 +1722,10 @@ "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], - "is-promise": ["is-promise@4.0.0", "", {}, "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ=="], - - "is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], - "is-subdir": ["is-subdir@1.2.0", "", { "dependencies": { "better-path-resolve": "1.0.0" } }, "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw=="], "is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="], - "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], - "is-windows": ["is-windows@1.0.2", "", {}, "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="], "is-wsl": ["is-wsl@3.1.1", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw=="], @@ -1825,12 +1738,8 @@ "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - "jose": ["jose@6.2.3", "", {}, "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw=="], - "jotai": ["jotai@2.20.0", "", { "peerDependencies": { "@babel/core": ">=7.0.0", "@babel/template": ">=7.0.0", "@types/react": ">=17.0.0", "react": ">=17.0.0" }, "optionalPeers": ["@babel/core", "@babel/template", "@types/react", "react"] }, "sha512-b5GAqgmXmXzB4WPaTH26ppk9Sl7AA9WSQX7yfdM+gJ1rFROiWcVbi97gFuN/yVCojOcbcvop2sfLL+fjxW0JVg=="], - "js-tiktoken": ["js-tiktoken@1.0.21", "", { "dependencies": { "base64-js": "^1.5.1" } }, "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g=="], - "js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], @@ -1847,11 +1756,7 @@ "json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="], - "json-schema-to-zod": ["json-schema-to-zod@2.8.1", "", { "bin": { "json-schema-to-zod": "dist/cjs/cli.js" } }, "sha512-fRr1mHgZ7hboLKBUdR428gd9dIHUFGivUqOeiDcSmyXkNZCtB1uGaZLvsjZ4GaN5pwBIs+TGIOf6s+Rp5/R/zA=="], - - "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - - "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="], + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], @@ -1869,8 +1774,6 @@ "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], - "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], - "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], @@ -1975,12 +1878,8 @@ "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], - "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], - "meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], - "merge-descriptors": ["merge-descriptors@2.0.0", "", {}, "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g=="], - "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], @@ -2041,9 +1940,9 @@ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], - "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], "min-indent": ["min-indent@1.0.1", "", {}, "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="], @@ -2067,8 +1966,6 @@ "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], - "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], - "neotraverse": ["neotraverse@0.6.18", "", {}, "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA=="], "netmask": ["netmask@2.1.1", "", {}, "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA=="], @@ -2085,14 +1982,8 @@ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - "npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], - "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], - "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], - - "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], - "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], "octokit": ["octokit@4.1.4", "", { "dependencies": { "@octokit/app": "^15.1.6", "@octokit/core": "^6.1.5", "@octokit/oauth-app": "^7.1.6", "@octokit/plugin-paginate-graphql": "^5.2.4", "@octokit/plugin-paginate-rest": "^12.0.0", "@octokit/plugin-rest-endpoint-methods": "^14.0.0", "@octokit/plugin-retry": "^7.2.1", "@octokit/plugin-throttling": "^10.0.0", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "@octokit/webhooks": "^13.8.3" } }, "sha512-cRvxRte6FU3vAHRC9+PMSY3D+mRAs2Rd9emMoqp70UGRvJRM3sbAoim2IXRZNNsf8wVfn4sGxVBHRAP+JBVX/g=="], @@ -2101,16 +1992,12 @@ "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=="], - "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], "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=="], - "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], - "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "outdent": ["outdent@0.5.0", "", {}, "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q=="], @@ -2121,12 +2008,10 @@ "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], - "p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="], + "p-map": ["p-map@2.1.0", "", {}, "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="], "p-queue": ["p-queue@8.1.1", "", { "dependencies": { "eventemitter3": "^5.0.1", "p-timeout": "^6.1.2" } }, "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ=="], - "p-retry": ["p-retry@7.1.1", "", { "dependencies": { "is-network-error": "^1.1.0" } }, "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w=="], - "p-timeout": ["p-timeout@6.1.4", "", {}, "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg=="], "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], @@ -2145,12 +2030,8 @@ "parse-latin": ["parse-latin@7.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="], - "parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="], - "parse5": ["parse5@8.0.1", "", { "dependencies": { "entities": "^8.0.0" } }, "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw=="], - "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], - "path-browserify": ["path-browserify@1.0.1", "", {}, "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], @@ -2173,8 +2054,6 @@ "pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="], - "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], - "png-to-ico": ["png-to-ico@2.1.8", "", { "dependencies": { "@types/node": "^17.0.36", "minimist": "^1.2.6", "pngjs": "^6.0.0" }, "bin": { "png-to-ico": "bin/cli.js" } }, "sha512-Nf+IIn/cZ/DIZVdGveJp86NG5uNib1ZXMiDd/8x32HCTeKSvgpyg6D/6tUBn1QO/zybzoMK0/mc3QRgAyXdv9w=="], "pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], @@ -2197,8 +2076,6 @@ "pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], - "pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="], - "prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="], "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], @@ -2207,32 +2084,22 @@ "protobufjs": ["protobufjs@7.5.6", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.1", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-M71sTMB146U3u0di3yup8iM+zv8yPRNQVr1KK4tyBitl3qFvEGucq/rGDRShD2rsJhtN02RJaJ7j5X5hmy8SJg=="], - "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=="], - "proxy-agent": ["proxy-agent@6.5.0", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.5" } }, "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A=="], "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - "qs": ["qs@6.15.1", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg=="], - "quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="], "query-selector-shadow-dom": ["query-selector-shadow-dom@1.0.1", "", {}, "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw=="], "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], - "radash": ["radash@12.1.1", "", {}, "sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA=="], - "radix-ui": ["radix-ui@1.4.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-accessible-icon": "1.1.7", "@radix-ui/react-accordion": "1.2.12", "@radix-ui/react-alert-dialog": "1.1.15", "@radix-ui/react-arrow": "1.1.7", "@radix-ui/react-aspect-ratio": "1.1.7", "@radix-ui/react-avatar": "1.1.10", "@radix-ui/react-checkbox": "1.3.3", "@radix-ui/react-collapsible": "1.1.12", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-context-menu": "2.2.16", "@radix-ui/react-dialog": "1.1.15", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-form": "0.1.8", "@radix-ui/react-hover-card": "1.1.15", "@radix-ui/react-label": "2.1.7", "@radix-ui/react-menu": "2.1.16", "@radix-ui/react-menubar": "1.1.16", "@radix-ui/react-navigation-menu": "1.2.14", "@radix-ui/react-one-time-password-field": "0.1.8", "@radix-ui/react-password-toggle-field": "0.1.3", "@radix-ui/react-popover": "1.1.15", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-progress": "1.1.7", "@radix-ui/react-radio-group": "1.3.8", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", "@radix-ui/react-separator": "1.1.7", "@radix-ui/react-slider": "1.3.6", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-tabs": "1.1.13", "@radix-ui/react-toast": "1.2.15", "@radix-ui/react-toggle": "1.1.10", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-toolbar": "1.1.11", "@radix-ui/react-tooltip": "1.2.8", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-effect-event": "0.0.2", "@radix-ui/react-use-escape-keydown": "1.1.1", "@radix-ui/react-use-is-hydrated": "0.1.0", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-size": "1.1.1", "@radix-ui/react-visually-hidden": "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-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA=="], "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.0", "unpipe": "~1.0.0" } }, "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA=="], - "rcedit": ["rcedit@4.0.1", "", { "dependencies": { "cross-spawn-windows-exe": "^1.1.0" } }, "sha512-bZdaQi34krFWhrDn+O53ccBDw0MkAT2Vhu75SqhtvhQu4OPyFM4RoVheyYiVQYdjhUi6EJMVWQ0tR6bCIYVkUg=="], "react": ["react@19.2.5", "", {}, "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA=="], @@ -2281,8 +2148,6 @@ "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], - "remend": ["remend@1.3.0", "", {}, "sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw=="], - "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=="], @@ -2303,8 +2168,6 @@ "rollup": ["rollup@4.60.3", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.3", "@rollup/rollup-android-arm64": "4.60.3", "@rollup/rollup-darwin-arm64": "4.60.3", "@rollup/rollup-darwin-x64": "4.60.3", "@rollup/rollup-freebsd-arm64": "4.60.3", "@rollup/rollup-freebsd-x64": "4.60.3", "@rollup/rollup-linux-arm-gnueabihf": "4.60.3", "@rollup/rollup-linux-arm-musleabihf": "4.60.3", "@rollup/rollup-linux-arm64-gnu": "4.60.3", "@rollup/rollup-linux-arm64-musl": "4.60.3", "@rollup/rollup-linux-loong64-gnu": "4.60.3", "@rollup/rollup-linux-loong64-musl": "4.60.3", "@rollup/rollup-linux-ppc64-gnu": "4.60.3", "@rollup/rollup-linux-ppc64-musl": "4.60.3", "@rollup/rollup-linux-riscv64-gnu": "4.60.3", "@rollup/rollup-linux-riscv64-musl": "4.60.3", "@rollup/rollup-linux-s390x-gnu": "4.60.3", "@rollup/rollup-linux-x64-gnu": "4.60.3", "@rollup/rollup-linux-x64-musl": "4.60.3", "@rollup/rollup-openbsd-x64": "4.60.3", "@rollup/rollup-openharmony-arm64": "4.60.3", "@rollup/rollup-win32-arm64-msvc": "4.60.3", "@rollup/rollup-win32-ia32-msvc": "4.60.3", "@rollup/rollup-win32-x64-gnu": "4.60.3", "@rollup/rollup-win32-x64-msvc": "4.60.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A=="], - "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], "rusha": ["rusha@0.8.14", "", {}, "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA=="], @@ -2319,24 +2182,14 @@ "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], - "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], - - "secure-json-parse": ["secure-json-parse@2.7.0", "", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="], - "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - "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=="], - "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@2.2.1", "", { "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", "send": "^1.2.0" } }, "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw=="], - "set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="], - "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], - "sha.js": ["sha.js@2.4.12", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" } }, "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w=="], "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "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=="], @@ -2347,14 +2200,6 @@ "shiki": ["shiki@3.23.0", "", { "dependencies": { "@shikijs/core": "3.23.0", "@shikijs/engine-javascript": "3.23.0", "@shikijs/engine-oniguruma": "3.23.0", "@shikijs/langs": "3.23.0", "@shikijs/themes": "3.23.0", "@shikijs/types": "3.23.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA=="], - "side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="], - - "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.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="], - - "side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="], - "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], @@ -2389,8 +2234,6 @@ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], - "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], - "std-env": ["std-env@4.1.0", "", {}, "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ=="], "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=="], @@ -2401,10 +2244,6 @@ "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], - "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], - - "strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], - "strip-indent": ["strip-indent@3.0.0", "", { "dependencies": { "min-indent": "^1.0.0" } }, "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ=="], "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], @@ -2457,10 +2296,6 @@ "toad-cache": ["toad-cache@3.7.0", "", {}, "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw=="], - "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], - - "tokenx": ["tokenx@1.3.0", "", {}, "sha512-NLdXTEZkKiO0gZuLtMoZKjCXTREXeZZt8nnnNeyoXtNZAfG/GKGSbQtLU5STspc0rMSwcA+UJfWZkbNU01iKmQ=="], - "tough-cookie": ["tough-cookie@6.0.1", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw=="], "tr46": ["tr46@6.0.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw=="], @@ -2485,8 +2320,6 @@ "type-fest": ["type-fest@5.6.0", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA=="], - "type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="], - "typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="], "typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="], @@ -2509,8 +2342,6 @@ "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], - "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], - "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], "unifont": ["unifont@0.7.4", "", { "dependencies": { "css-tree": "^3.1.0", "ofetch": "^1.5.1", "ohash": "^2.0.11" } }, "sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg=="], @@ -2539,8 +2370,6 @@ "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], - "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], - "unplugin": ["unplugin@3.0.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "picomatch": "^4.0.3", "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.10", "lru-cache": "^11.2.7", "node-fetch-native": "^1.6.7", "ofetch": "^1.5.1", "ufo": "^1.6.3" }, "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=="], @@ -2563,8 +2392,6 @@ "v8-compile-cache-lib": ["v8-compile-cache-lib@3.0.1", "", {}, "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="], - "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], - "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], "vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="], @@ -2649,7 +2476,7 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "ws": ["ws@8.20.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="], + "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], "xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="], @@ -2683,44 +2510,36 @@ "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], - "zod-from-json-schema": ["zod-from-json-schema@0.5.2", "", { "dependencies": { "zod": "^4.0.17" } }, "sha512-/dNaicfdhJTOuUd4RImbLUE2g5yrSzzDjI/S6C2vO2ecAGZzn9UcRVgtyLSnENSmAOBRiSpUdzDS6fDWX3Z35g=="], - - "zod-from-json-schema-v3": ["zod-from-json-schema@0.0.5", "", { "dependencies": { "zod": "^3.24.2" } }, "sha512-zYEoo86M1qpA1Pq6329oSyHLS785z/mTwfr9V1Xf/ZLhuuBGaMlDGu/pDVGVUe4H4oa1EFgWZT53DP0U3oT9CQ=="], - "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], "zod-to-ts": ["zod-to-ts@1.2.0", "", { "peerDependencies": { "typescript": "^4.9.4 || ^5.0.2", "zod": "^3" } }, "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@a2a-js/sdk/uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="], + "@ai-sdk/anthropic/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8", "undici": "^7.28.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TnHUyd/rCYQqHg5RuiOaz/hUql6U+kbUaBW0Rp+0N5UhnAInA9CzzV0HXvuAAPwppDsK6fAx9Rd+tRawpJ/3pg=="], - "@ai-sdk/anthropic/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + "@ai-sdk/gateway/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8", "undici": "^7.28.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TnHUyd/rCYQqHg5RuiOaz/hUql6U+kbUaBW0Rp+0N5UhnAInA9CzzV0HXvuAAPwppDsK6fAx9Rd+tRawpJ/3pg=="], - "@ai-sdk/gateway/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + "@ai-sdk/google/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8", "undici": "^7.28.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TnHUyd/rCYQqHg5RuiOaz/hUql6U+kbUaBW0Rp+0N5UhnAInA9CzzV0HXvuAAPwppDsK6fAx9Rd+tRawpJ/3pg=="], - "@ai-sdk/google/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + "@ai-sdk/openai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8", "undici": "^7.28.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TnHUyd/rCYQqHg5RuiOaz/hUql6U+kbUaBW0Rp+0N5UhnAInA9CzzV0HXvuAAPwppDsK6fAx9Rd+tRawpJ/3pg=="], - "@ai-sdk/openai-compatible/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + "@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8", "undici": "^7.28.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TnHUyd/rCYQqHg5RuiOaz/hUql6U+kbUaBW0Rp+0N5UhnAInA9CzzV0HXvuAAPwppDsK6fAx9Rd+tRawpJ/3pg=="], "@ai-sdk/provider-utils/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], - "@ai-sdk/provider-utils-v5/@ai-sdk/provider": ["@ai-sdk/provider@2.0.1", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-KCUwswvsC5VsW2PWFqF8eJgSCu5Ysj7m1TxiHTVA6g7k360bk0RNQENT8KTMAYEs+8fWPD3Uu4dEmzGHc+jGng=="], - - "@ai-sdk/ui-utils-v5/@ai-sdk/provider": ["@ai-sdk/provider@1.1.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg=="], - - "@ai-sdk/ui-utils-v5/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.2.8", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA=="], - - "@ai-sdk/ui-utils-v5/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@app/core/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.23", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-z8GlDaCmRSDlqkMF2f4/RFgWxdarvIbyuk+m6WXT1LYgsnGiXRJGTD2Z1+SDl3LqtFuRtGX1aghYvQLoHL/9pg=="], - "@app/core/vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], "@app/shared/vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="], "@app/shared/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@app/web/@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.75", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-5AV3CKwaOJFdGXhihVgvRLNrjwRn2Xmy71YygT8DYOA+5zTx93Seg2QSIS8b3tJxzZ7X4H84pEtrE8VZKBCZGA=="], + + "@app/web/@ai-sdk/google": ["@ai-sdk/google@3.0.67", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Qeq+SidYtzMrcf0fdw3L0QLmtXK+ErwdBzbxS4+0Q/2UP85Ges8RJJcbAj7SO8e2JbeJoM35BLqkeNy1o3wJvQ=="], + + "@app/web/ai": ["ai@6.0.175", "", { "dependencies": { "@ai-sdk/gateway": "3.0.110", "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26", "@opentelemetry/api": "1.9.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-6fFFHzbh6FIZnYc31V6osOxq25ABJYCShfG0O6ajHiA4FB/DgnPi1mP8cO5aAU3HNSbQHiMazdlh9bIsp97mVA=="], + "@astrojs/check/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "@babel/code-frame/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -2745,6 +2564,8 @@ "@changesets/write/fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="], + "@commitlint/config-validator/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@inlang/paraglide-js-adapter-unplugin/unplugin": ["unplugin@1.5.1", "", { "dependencies": { "acorn": "^8.11.2", "chokidar": "^3.5.3", "webpack-sources": "^3.2.3", "webpack-virtual-modules": "^0.6.0" } }, "sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew=="], @@ -2773,8 +2594,6 @@ "@manypkg/get-packages/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], - "@mastra/core/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], - "@opentelemetry/otlp-transformer/@opentelemetry/resources": ["@opentelemetry/resources@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A=="], "@opentelemetry/resources/@opentelemetry/core": ["@opentelemetry/core@2.7.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw=="], @@ -2831,9 +2650,9 @@ "@vitest/expect/chai": ["chai@6.2.2", "", {}, "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg=="], - "ai/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + "ai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@5.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.7", "@standard-schema/spec": "^1.1.0", "@workflow/serde": "4.1.0", "eventsource-parser": "^3.0.8", "undici": "^7.28.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-TnHUyd/rCYQqHg5RuiOaz/hUql6U+kbUaBW0Rp+0N5UhnAInA9CzzV0HXvuAAPwppDsK6fAx9Rd+tRawpJ/3pg=="], - "ai/@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], + "ajv-draft-04/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], "anymatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], @@ -2859,40 +2678,26 @@ "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "eslint/ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], - - "eslint/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], - "eslint/glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], "eslint/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], - "express/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="], - - "form-data/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "gauge-ts/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "globby/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], - "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], - "hast-util-from-html/parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], "hast-util-raw/parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], "miniflare/undici": ["undici@7.24.8", "", {}, "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ=="], - "miniflare/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], - - "npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], - - "p-filter/p-map": ["p-map@2.1.0", "", {}, "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="], - "p-locate/p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "png-to-ico/@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="], @@ -2907,10 +2712,6 @@ "read-yaml-file/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], - "router/path-to-regexp": ["path-to-regexp@8.4.2", "", {}, "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA=="], - - "socks/ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="], - "ts-node/diff": ["diff@4.0.4", "", {}, "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ=="], "vite/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=="], @@ -2925,18 +2726,28 @@ "wrap-ansi/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + "yaml-language-server/ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + "yaml-language-server/prettier": ["prettier@3.8.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw=="], "yaml-language-server/request-light": ["request-light@0.5.8", "", {}, "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg=="], "yaml-language-server/yaml": ["yaml@2.7.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ=="], - "zod-from-json-schema-v3/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "zod-to-ts/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "zod-to-ts/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], + "@ai-sdk/anthropic/@ai-sdk/provider-utils/undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], + + "@ai-sdk/gateway/@ai-sdk/provider-utils/undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], + + "@ai-sdk/google/@ai-sdk/provider-utils/undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], + + "@ai-sdk/openai-compatible/@ai-sdk/provider-utils/undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], + + "@ai-sdk/openai/@ai-sdk/provider-utils/undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], + "@app/core/vitest/@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="], "@app/core/vitest/@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="], @@ -2977,6 +2788,16 @@ "@app/shared/vitest/tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], + "@app/web/@ai-sdk/anthropic/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + + "@app/web/@ai-sdk/google/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + + "@app/web/ai/@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.110", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.26", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-sbv8+1L9/BRKydn8dMNwoMQKupA4iLJ9N+yvxgW6wMQ/94UepDf3FeYWMj/dLdzolAHZ6izRUP4s5WqQkmJ2Zg=="], + + "@app/web/ai/@ai-sdk/provider": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="], + + "@app/web/ai/@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="], + "@astrojs/check/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "@changesets/apply-release-plan/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="], @@ -3003,6 +2824,8 @@ "@changesets/write/fs-extra/universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], + "@commitlint/config-validator/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "@inlang/paraglide-js-adapter-unplugin/unplugin/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "@lix-js/client/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@19.1.0", "", {}, "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw=="], @@ -3039,6 +2862,10 @@ "@tanstack/router-plugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], + "ai/@ai-sdk/provider-utils/undici": ["undici@7.29.0", "", {}, "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw=="], + + "ajv-draft-04/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "boxen/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], "boxen/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], @@ -3049,12 +2876,6 @@ "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="], - "eslint/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - - "form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - - "gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], - "hast-util-from-html/parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "hast-util-raw/parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], @@ -3123,6 +2944,8 @@ "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "yaml-language-server/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], + "@inlang/paraglide-js-adapter-unplugin/unplugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], "@lix-js/client/octokit/@octokit/app/@octokit/auth-app": ["@octokit/auth-app@6.1.4", "", { "dependencies": { "@octokit/auth-oauth-app": "^7.1.0", "@octokit/auth-oauth-user": "^4.1.0", "@octokit/request": "^8.3.1", "@octokit/request-error": "^5.1.0", "@octokit/types": "^13.1.0", "deprecation": "^2.3.1", "lru-cache": "npm:@wolfy1339/lru-cache@^11.0.2-patch.1", "universal-github-app-jwt": "^1.1.2", "universal-user-agent": "^6.0.0" } }, "sha512-QkXkSOHZK4dA5oUqY5Dk3S+5pN2s1igPjEASNQV8/vgJgW034fQWR16u7VsNOK/EljA00eyjYF5mWNxWKWhHRQ=="], diff --git a/package.json b/package.json index 70ae9358..f94068a7 100644 --- a/package.json +++ b/package.json @@ -49,8 +49,6 @@ "dependencies": { "@ai-sdk/provider-utils": "^4.0.23", "@inlang/paraglide-js-adapter-vite": "^1.2.40", - "@mastra/ai-sdk": "^1.4.0", - "@mastra/core": "^1.25.0", "type-fest": "^5.6.0" } } \ No newline at end of file diff --git a/packages/core/package.json b/packages/core/package.json index 4411a5c7..1dbefcea 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -30,13 +30,13 @@ "validate": "bun ../../scripts/validate.ts --cwd $INIT_CWD" }, "dependencies": { - "@ai-sdk/anthropic": "^3.0.68", - "@ai-sdk/google": "^3.0.61", - "@ai-sdk/openai-compatible": "^2.0.41", - "@ai-sdk/provider": "3.0.8", - "@ai-sdk/provider-utils": "4.0.23", + "@ai-sdk/anthropic": "^4.0.0", + "@ai-sdk/google": "^4.0.0", + "@ai-sdk/openai-compatible": "^3.0.0", + "@ai-sdk/provider": "^4.0.0", + "@ai-sdk/provider-utils": "^4.0.0", "@app/logger": "workspace:*", - "ai": "^6.0.156", + "ai": "^7.0.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/packages/core/src/ai/client.ts b/packages/core/src/ai/client.ts index c1786f46..b922537f 100644 --- a/packages/core/src/ai/client.ts +++ b/packages/core/src/ai/client.ts @@ -1,12 +1,9 @@ -import { createHash } from "crypto"; - import { getLogger } from "@app/logger"; import { generateText, type ModelMessage, streamText } from "ai"; import type { FinishReason, LanguageModelUsage } from "ai"; import { buildModelFallbackChain, getAIProvider, getClaudeModel } from "./providers"; import type { ProviderType } from "./providers"; -import { createTelemetryCallbacks } from "./telemetry"; const CACHE_MAX_ENTRIES = 100; const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes @@ -41,18 +38,23 @@ function isExpired(entry: CacheEntry): boolean { return Date.now() - entry.timestamp > CACHE_TTL_MS; } +async function sha256hex(data: string): Promise { + const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(data)); + return [...new Uint8Array(buf)] + .map((b) => b.toString(16).padStart(2, "0")) + .join("") + .slice(0, 16); +} + // Generate cache key from system prompt + provider type + model + user messages hash -function generateCacheKey( +async function generateCacheKey( systemPrompt: string | undefined, providerType: ProviderType, model: string, userMessages: string, -): string { - const systemHash = createHash("sha256") - .update(systemPrompt || "") - .digest("hex") - .substring(0, 16); - const messagesHash = createHash("sha256").update(userMessages).digest("hex").substring(0, 16); +): Promise { + const systemHash = await sha256hex(systemPrompt || ""); + const messagesHash = await sha256hex(userMessages); return `${systemHash}:${providerType}:${model}:${messagesHash}`; } @@ -70,6 +72,7 @@ export interface GenerateOptions { systemPrompt?: string; functionId?: string; frameIndex?: number; + onFinish?: (event: { usage: LanguageModelUsage; text?: string; finishReason?: string }) => void; } function buildHeaders( @@ -170,7 +173,7 @@ export async function generateWithFallback( // Check cache if enabled if (options.enableCaching && options.systemPrompt !== undefined) { const userContent = messagesToText(options.messages); - const cacheKey = generateCacheKey( + const cacheKey = await generateCacheKey( options.systemPrompt, providerType, preferredModel, @@ -180,6 +183,11 @@ export async function generateWithFallback( if (cached && !isExpired(cached)) { cacheLogger.info(`[Cache] HIT for key: ${cacheKey.substring(0, 24)}...`); + options.onFinish?.({ + usage: cached.result.usage, + text: cached.result.text, + finishReason: cached.result.finishReason, + }); return { result: { text: cached.result.text, @@ -202,11 +210,6 @@ export async function generateWithFallback( const cachedMessages = addCacheControlToMessages(options.messages, options.enableCaching); let lastError: unknown; - const telemetry = createTelemetryCallbacks(["calca", "core", "ai", "generateWithFallback"], { - functionId: options.functionId ?? "generateWithFallback", - frameIndex: options.frameIndex, - }); - for (let i = 0; i < fallbacks.length; i++) { const modelId = fallbacks[i]; @@ -224,44 +227,13 @@ export async function generateWithFallback( maxOutputTokens: options.maxTokens, temperature: options.temperature, ...(providerType === "anthropic" ? { headers: cacheHeaders } : {}), - experimental_onStart: ({ model: m }) => { - try { - telemetry.onStart({ modelId: m.modelId, prompt: cachedMessages }); - } catch { - /* ignore telemetry errors */ - } - }, - onStepFinish: (event) => { - try { - telemetry.onFinish({ - modelId, - usage: event.usage, - finishReason: event.finishReason, - durationMs: Date.now(), - }); - } catch { - /* ignore telemetry errors */ - } - }, - onFinish: (event) => { - try { - telemetry.onFinish({ - modelId, - usage: event.totalUsage, - finishReason: event.finishReason ?? "unknown", - durationMs: Date.now(), - }); - } catch { - /* ignore telemetry errors */ - } - }, }); // Store in cache on successful response if (options.enableCaching && options.systemPrompt !== undefined) { evictIfNeeded(); const userContent = messagesToText(options.messages); - const cacheKey = generateCacheKey( + const cacheKey = await generateCacheKey( options.systemPrompt, providerType, preferredModel, @@ -277,18 +249,16 @@ export async function generateWithFallback( }); } + options.onFinish?.({ + usage: result.usage, + text: result.text, + finishReason: result.finishReason ?? "unknown", + }); + return { result, usedModel: modelId }; } catch (err: unknown) { if (isModelNotFoundError(err)) { lastError = err; - try { - telemetry.onError({ - modelId, - error: err instanceof Error ? err : new Error(String(err)), - }); - } catch { - /* ignore telemetry errors */ - } continue; } throw err; @@ -310,7 +280,9 @@ function messagesToText(messages: ModelMessage[]): string { .join("|"); } -export function streamAnthropic(options: GenerateOptions): ReturnType { +export async function streamAnthropic( + options: GenerateOptions, +): Promise> { if (!options.model) { throw new Error("No model specified. Configure a model in Settings."); } @@ -325,7 +297,12 @@ export function streamAnthropic(options: GenerateOptions): ReturnType { - try { - telemetry.onStart({ modelId: m.modelId, prompt: cachedMessages }); - } catch { - /* ignore telemetry errors */ - } - }, - onStepFinish: (event) => { - try { - telemetry.onFinish({ - modelId, - usage: event.usage, - finishReason: event.finishReason, - durationMs: Date.now(), - }); - } catch { - /* ignore telemetry errors */ - } - }, - onFinish: (event) => { - try { - telemetry.onFinish({ - modelId, - usage: event.totalUsage, - finishReason: event.finishReason ?? "unknown", - durationMs: Date.now(), - }); - } catch { - /* ignore telemetry errors */ - } - }, + onFinish: options.onFinish ? (event) => options.onFinish!({ usage: event.usage }) : undefined, }); } diff --git a/packages/core/src/ai/probe.ts b/packages/core/src/ai/probe.ts index a006520a..1c0c1f4d 100644 --- a/packages/core/src/ai/probe.ts +++ b/packages/core/src/ai/probe.ts @@ -1,5 +1,5 @@ import { getLogger } from "@app/logger"; -import { CallSettings, generateText, LanguageModel } from "ai"; +import { LanguageModelCallOptions, generateText, LanguageModel, type RequestOptions } from "ai"; import { getClaudeModel } from "./providers"; import type { ProviderType } from "./providers"; @@ -11,7 +11,10 @@ export interface ModelInfo { available: boolean; } -const probeModel = async (model: LanguageModel, settings: CallSettings) => +const probeModel = async ( + model: LanguageModel, + settings: LanguageModelCallOptions & Omit, +) => await generateText({ ...settings, model, diff --git a/packages/core/src/ai/providers.ts b/packages/core/src/ai/providers.ts index 750fb413..8e4c26cf 100644 --- a/packages/core/src/ai/providers.ts +++ b/packages/core/src/ai/providers.ts @@ -1,12 +1,12 @@ import { anthropic } from "@ai-sdk/anthropic"; -import { createGoogleGenerativeAI, google } from "@ai-sdk/google"; +import { createGoogle, google } from "@ai-sdk/google"; import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; -import type { ImageModelV3, LanguageModelV3 } from "@ai-sdk/provider"; +import type { ImageModelV4, LanguageModelV4 } from "@ai-sdk/provider"; export type ProviderType = "anthropic" | "openai-compatible"; type CallableProvider = { - (modelId: string): LanguageModelV3; + (modelId: string): LanguageModelV4; }; export function getAIProvider( @@ -48,7 +48,7 @@ export function buildModelFallbackChain(preferredModel: string, fallbackModel?: const GEMINI_IMAGE_MODEL = "gemini-2.5-flash-image"; /** @deprecated fetch models from cache otherwise API (use API base url + key). Keep single 'getModel' method. This is currently in apps/web, we must migrate it to apps/server */ -export function getGeminiImageModel(apiKey?: string): ImageModelV3 { - const provider = apiKey ? createGoogleGenerativeAI({ apiKey }) : google; +export function getGeminiImageModel(apiKey?: string): ImageModelV4 { + const provider = apiKey ? createGoogle({ apiKey }) : google; return provider.image(GEMINI_IMAGE_MODEL); } diff --git a/packages/core/src/ai/telemetry.ts b/packages/core/src/ai/telemetry.ts deleted file mode 100644 index 827e0b53..00000000 --- a/packages/core/src/ai/telemetry.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { getLogger } from "@app/logger"; -import type { ModelMessage } from "ai"; -import type { FinishReason, LanguageModelUsage } from "ai"; - -export interface TelemetryCallbacks { - onStart(params: { - modelId: string; - prompt: ModelMessage[]; - settings?: Record; - }): void; - onFinish(params: { - modelId: string; - usage: LanguageModelUsage; - finishReason: FinishReason; - durationMs: number; - }): void; - onError(params: { modelId: string; error: Error }): void; -} - -export interface TelemetryCallbacksOptions { - functionId: string; - frameIndex?: number; - isEnabled?: boolean; -} - -export function createTelemetryCallbacks( - category: string[] = ["calca", "core", "ai", "telemetry"], - options: TelemetryCallbacksOptions, -): TelemetryCallbacks { - const logger = getLogger(category); - const functionId = options.functionId; - const frameIndex = options.frameIndex; - const isEnabled = options.isEnabled ?? true; - - const startTimes = new Map(); - - return { - onStart({ modelId, prompt, settings }) { - if (!isEnabled) return; - const key = functionId; - startTimes.set(key, Date.now()); - logger.debug("AI call started", { - functionId, - frameIndex, - modelId, - promptLength: prompt.length, - settings, - }); - }, - - onFinish({ modelId, usage, finishReason, durationMs }) { - if (!isEnabled) return; - const key = functionId; - startTimes.delete(key); - logger.info("AI call completed", { - functionId, - frameIndex, - modelId, - usage, - finishReason, - durationMs, - }); - }, - - onError({ modelId, error }) { - if (!isEnabled) return; - const key = functionId; - startTimes.delete(key); - logger.error("AI call failed", { - functionId, - frameIndex, - modelId, - error: error.message, - }); - }, - }; -} diff --git a/packages/pipeline/package.json b/packages/pipeline/package.json new file mode 100644 index 00000000..dd067311 --- /dev/null +++ b/packages/pipeline/package.json @@ -0,0 +1,35 @@ +{ + "name": "@calca/pipeline", + "version": "0.6.1", + "private": true, + "license": "AGPL-3.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, + "scripts": { + "build": "echo 'build: not yet implemented'", + "typecheck": "bunx tsc --noEmit", + "test": "vitest run", + "lint": "oxlint --fix .", + "format": "oxfmt --write .", + "clean": "rm -rf dist", + "validate": "bun ../../scripts/validate.ts --cwd $INIT_CWD" + }, + "dependencies": { + "@ai-sdk/anthropic": "^4.0.0", + "@ai-sdk/openai": "^4.0.0", + "@opentelemetry/api": "^1.9.0", + "ai": "^7.0.0", + "zod": "^4.3.6" + }, + "devDependencies": { + "typescript": "^6.0.3", + "vitest": "^4.1.4" + }, + "peerDependencies": { + "@app/core": "workspace:*", + "@app/logger": "workspace:*", + "@app/shared": "workspace:*" + } +} diff --git a/packages/pipeline/src/index.ts b/packages/pipeline/src/index.ts new file mode 100644 index 00000000..1a58cec0 --- /dev/null +++ b/packages/pipeline/src/index.ts @@ -0,0 +1,44 @@ +export { designPipeline } from "./pipeline"; +export { designPipelineStream } from "./stream"; +export type { + FrameResult, + PipelineEvent, + PipelineContext, + Step, + StepContext, + WorkflowInput, + WorkflowOutput, +} from "./types"; +export { + WorkflowInputSchema, + WorkflowOutputSchema, + FrameResultSchema, + PlanInputSchema, + PlanOutputSchema, + LayoutInputSchema, + LayoutOutputSchema, + ImagesInputSchema, + ImagesOutputSchema, + ReviewInputSchema, + ReviewOutputSchema, + CritiqueInputSchema, + CritiqueOutputSchema, + SummaryInputSchema, + SummaryOutputSchema, +} from "./types"; +export { planStep } from "./steps/plan.step"; +export { layoutStep } from "./steps/layout.step"; +export { imagesStep } from "./steps/images.step"; +export { reviewStep } from "./steps/review.step"; +export { critiqueStep } from "./steps/critique.step"; +export { summaryStep } from "./steps/summary.step"; +export { createTelemetryCallbacks } from "./telemetry"; +export { + tokenAggregator, + TokenAggregator, + wrapStep, + createFrameSpan, + withActiveFrameSpan, + getPipelineTracer, +} from "./telemetry"; +export type { TokenUsage } from "./telemetry"; diff --git a/apps/server/src/lib/parse-html.ts b/packages/pipeline/src/lib/parse-html.ts similarity index 100% rename from apps/server/src/lib/parse-html.ts rename to packages/pipeline/src/lib/parse-html.ts diff --git a/apps/server/src/lib/strip-base64.ts b/packages/pipeline/src/lib/strip-base64.ts similarity index 100% rename from apps/server/src/lib/strip-base64.ts rename to packages/pipeline/src/lib/strip-base64.ts diff --git a/packages/pipeline/src/pipeline.ts b/packages/pipeline/src/pipeline.ts new file mode 100644 index 00000000..eea77b19 --- /dev/null +++ b/packages/pipeline/src/pipeline.ts @@ -0,0 +1,232 @@ +import { critiqueStep } from "./steps/critique.step"; +import { imagesStep } from "./steps/images.step"; +import { layoutStep } from "./steps/layout.step"; +import { planStep } from "./steps/plan.step"; +import { reviewStep } from "./steps/review.step"; +import { summaryStep } from "./steps/summary.step"; +import { getPipelineTracer, tokenAggregator, withActiveFrameSpan, wrapStep } from "./telemetry"; +import type { + FrameResult, + Logger, + PipelineContext, + PipelineEvent, + PlanOutput, + StepContext, + WorkflowInput, + WorkflowOutput, +} from "./types"; + +export type { PipelineEvent }; + +function makeContext( + signal: AbortSignal, + emit: (event: PipelineEvent) => void, + logger: Logger, +): StepContext { + return { + signal, + emit, + logger, + tracer: getPipelineTracer(), + tokenUsage: tokenAggregator, + }; +} + +export async function designPipeline( + input: WorkflowInput, + ctx: PipelineContext, +): Promise { + const stepCtx = makeContext(ctx.signal, ctx.emit, ctx.logger); + + stepCtx.emit({ type: "step", step: "plan", status: "running" }); + const plan = await wrapStep("plan", async (ctx) => planStep(input, ctx), stepCtx); + stepCtx.emit({ type: "step", step: "plan", status: "success", output: plan }); + + const frames: FrameResult[] = []; + if (input.mode === "quick") { + const results = await Promise.allSettled( + plan.concepts.map((concept, i) => runFrame(concept, i, undefined, input, stepCtx)), + ); + frames.push(...results.map((r, i) => (r.status === "fulfilled" ? r.value : errorFrame(i)))); + } else { + let prev: string | undefined; + for (let i = 0; i < plan.concepts.length; i++) { + if (ctx.signal.aborted) break; + const f = await runFrame(plan.concepts[i]!, i, prev, input, stepCtx); + frames.push(f); + prev = f.critique; + } + } + + stepCtx.emit({ type: "step", step: "frameOrchestrator", status: "success", output: { frames } }); + + const lastFrame = frames[frames.length - 1]; + const summaryInput = { + ...input, + html: lastFrame?.html ?? "", + labels: frames.map((f) => f.label), + }; + + stepCtx.emit({ type: "step", step: "summary", status: "running" }); + const summary = await wrapStep("summary", async (ctx) => summaryStep(summaryInput, ctx), stepCtx); + stepCtx.emit({ type: "step", step: "summary", status: "success", output: summary }); + + const output: WorkflowOutput = { frames, summary: summary.summary }; + stepCtx.emit({ + type: "step", + step: "collectResults", + status: "success", + output, + }); + stepCtx.emit({ type: "done", output }); + return output; +} + +async function runFrame( + concept: { name: string; direction: string }, + i: number, + prevCritique: string | undefined, + input: WorkflowInput, + ctx: StepContext, +): Promise { + return withActiveFrameSpan(i, concept.name, async () => { + const conceptStr = concept.direction ? `${concept.name}: ${concept.direction}` : concept.name; + + ctx.emit({ type: "step", step: "layout", status: "running", frameIndex: i }); + const { html, width, height, comment } = await wrapStep( + "layout", + async (stepCtx) => + layoutStep( + { + ...input, + concept: conceptStr, + critique: prevCritique, + frameIndex: i, + }, + stepCtx, + ), + ctx, + ); + ctx.emit({ + type: "step", + step: "layout", + status: "success", + frameIndex: i, + output: { html, width, height, comment }, + }); + + ctx.emit({ type: "step", step: "images", status: "running", frameIndex: i }); + const { html: imaged } = await wrapStep( + "images", + async (stepCtx) => + imagesStep( + { + html, + geminiKey: input.geminiKey, + unsplashKey: input.unsplashKey, + openaiKey: input.openaiKey, + viewport: width && height ? { width, height } : undefined, + }, + stepCtx, + ), + ctx, + ); + ctx.emit({ + type: "step", + step: "images", + status: "success", + frameIndex: i, + output: { html: imaged }, + }); + + let final = imaged; + let critique: string | undefined; + if (input.mode !== "quick") { + ctx.emit({ type: "step", step: "review", status: "running", frameIndex: i }); + const reviewed = await wrapStep( + "review", + async (stepCtx) => + reviewStep( + { + html: final, + prompt: input.prompt, + width, + height, + model: input.model, + apiKey: input.apiKey, + baseURL: input.baseURL, + providerType: input.providerType, + frameIndex: i, + }, + stepCtx, + ), + ctx, + ); + final = reviewed.html; + ctx.emit({ + type: "step", + step: "review", + status: "success", + frameIndex: i, + output: reviewed, + }); + + ctx.emit({ type: "step", step: "critique", status: "running", frameIndex: i }); + try { + critique = ( + await wrapStep( + "critique", + async (stepCtx) => + critiqueStep( + { + html: final, + prompt: input.prompt, + model: input.model, + apiKey: input.apiKey, + baseURL: input.baseURL, + providerType: input.providerType, + frameIndex: i, + }, + stepCtx, + ), + ctx, + ) + ).critique; + ctx.emit({ + type: "step", + step: "critique", + status: "success", + frameIndex: i, + output: { critique }, + }); + } catch { + ctx.emit({ type: "step", step: "critique", status: "failed", frameIndex: i }); + } + } + + const frame: FrameResult = { + html: final, + width, + height, + label: `Variation ${i + 1}`, + comment, + critique, + }; + ctx.emit({ type: "frame", frameIndex: i, frame }); + ctx.emit({ + type: "step", + step: "frameComplete", + status: "success", + frameIndex: i, + output: frame, + }); + return frame; + }); +} + +function errorFrame(index: number): FrameResult { + return { + html: `

⚠ Frame ${index + 1} failed

`, + label: `Variation ${index + 1}`, + }; +} diff --git a/packages/pipeline/src/steps/critique.step.ts b/packages/pipeline/src/steps/critique.step.ts new file mode 100644 index 00000000..4d6addce --- /dev/null +++ b/packages/pipeline/src/steps/critique.step.ts @@ -0,0 +1,40 @@ +import { generateWithFallback } from "@app/core/ai/client"; +import type { ProviderType } from "@app/core/ai/providers"; +import { buildCritiquePrompt } from "@app/core/prompts/critique"; +import type { ModelMessage } from "ai"; + +import { stripBase64Images } from "../lib/strip-base64"; +import type { CritiqueInput, CritiqueOutput, Step, StepContext } from "../types"; + +export const critiqueStep: Step = async ( + input, + ctx: StepContext, +) => { + const { html, prompt, model, apiKey, baseURL, providerType, frameIndex } = input; + const frameIdx = frameIndex ?? 0; + + const { stripped } = stripBase64Images(html); + + const messages: ModelMessage[] = [ + { + role: "user", + content: buildCritiquePrompt(prompt || "", stripped), + }, + ]; + + const { result } = await generateWithFallback({ + apiKey, + model: model, + messages, + maxTokens: 1024, + providerType: providerType as ProviderType | undefined, + baseURL, + functionId: `critique:${frameIdx + 1}`, + frameIndex: frameIdx, + onFinish: (event) => ctx.tokenUsage?.add(event.usage), + }); + + return { + critique: result.text, + }; +}; diff --git a/packages/pipeline/src/steps/images.step.ts b/packages/pipeline/src/steps/images.step.ts new file mode 100644 index 00000000..6c847b20 --- /dev/null +++ b/packages/pipeline/src/steps/images.step.ts @@ -0,0 +1,54 @@ +import { generateImages } from "@app/core/pipeline/images"; + +import type { ImagesInput, ImagesOutput, Step, StepContext } from "../types"; + +export const imagesStep: Step = async (input, ctx: StepContext) => { + const { html, geminiKey, unsplashKey, openaiKey, viewport } = input; + + if (!geminiKey && !unsplashKey && !openaiKey) { + ctx.emit({ type: "step", step: "images", status: "running", frameIndex: undefined }); + return { html }; + } + + ctx.emit({ type: "step", step: "images", status: "running", frameIndex: undefined }); + + try { + const result = await generateImages({ + geminiKey, + html, + openaiKey, + unsplashKey, + viewport, + }); + + if (result.imageCount > 0) { + ctx.emit({ + type: "step", + step: "images", + status: "success", + frameIndex: undefined, + output: { imageCount: result.imageCount }, + }); + } + + if (result.skipped) { + ctx.emit({ + type: "step", + step: "images", + status: "success", + frameIndex: undefined, + output: { skipped: true, reason: result.reason }, + }); + } + + return { html: result.html }; + } catch (error) { + if (error instanceof Error) { + ctx.logger.error(`[Images Step] Generation failed:\n${error.message}`); + } else { + ctx.logger.error(`[Images Step] Generation failed:`, { error }); + } + + return { html }; + } +}; diff --git a/packages/pipeline/src/steps/layout.step.ts b/packages/pipeline/src/steps/layout.step.ts new file mode 100644 index 00000000..3b17a1b2 --- /dev/null +++ b/packages/pipeline/src/steps/layout.step.ts @@ -0,0 +1,156 @@ +import { streamAnthropic } from "@app/core/ai/client"; +import type { ProviderType } from "@app/core/ai/providers"; +import { buildNewPrompt, buildRevisionUserContent } from "@app/core/prompts/layout"; +import { validateLayout } from "@app/shared"; +import { type ImagePart, type ModelMessage, type TextPart } from "ai"; + +import { parseHtmlWithSize } from "../lib/parse-html"; +import { stripBase64Images } from "../lib/strip-base64"; +import type { LayoutInput, LayoutOutput, Step, StepContext } from "../types"; + +const HEARTBEAT_INTERVAL_MS = 5_000; + +export const layoutStep: Step = async (input, ctx: StepContext) => { + const { + prompt, + contextImages = [], + critique, + revision, + existingHtml, + systemPrompt, + model, + apiKey, + baseURL, + providerType, + frameIndex, + } = input; + + const useModel = model; + const isRevision = !!(revision && existingHtml); + const frameIdx = frameIndex ?? 0; + const functionId = `layout:${frameIdx + 1}`; + + let userContent: string; + let restoreFn: ((s: string) => string) | null = null; + + if (isRevision && existingHtml) { + const { stripped, restore } = stripBase64Images(existingHtml); + restoreFn = restore; + userContent = buildRevisionUserContent(systemPrompt, stripped, prompt, String(revision)); + } else { + userContent = buildNewPrompt(systemPrompt, critique, prompt, "", []); + } + + const userParts: (TextPart | ImagePart)[] = []; + const imageTokenMap: Record = {}; + + if (contextImages.length > 0) { + const validTypes = new Set(["image/jpeg", "image/png", "image/gif", "image/webp"]); + const imageRefs: string[] = []; + + for (let i = 0; i < contextImages.length; i++) { + const dataUrl = contextImages[i]!; + const match = dataUrl.match(/^data:(image\/[^;]+);base64,(.+)$/); + if (match && validTypes.has(match[1])) { + const token = `[USER_IMAGE_${i + 1}]`; + imageTokenMap[token] = dataUrl; + + userParts.push({ type: "image", image: dataUrl }); + imageRefs.push(`- Image ${i + 1}: Use src="${token}" to place this image`); + } + } + + if (imageRefs.length > 0) { + userParts.push({ + type: "text", + text: `USER-PROVIDED IMAGES — USE THESE IN THE DESIGN: +The ${imageRefs.length} image${imageRefs.length > 1 ? "s" : "is"} provided by the user to include IN the design. + +${imageRefs.join("\n")} + +RULES FOR USER IMAGES: +- Place them as tags using the token as the src attribute (e.g., ) +- Position them where they fit best in the design layout +- You can use each image once or multiple times +- Style them with CSS (border-radius, object-fit, shadows, etc.) +- Do NOT use placeholder divs for content these images cover +- You can STILL use data-placeholder divs for ADDITIONAL images beyond what the user provided + +`, + }); + } + } + + userParts.push({ type: "text", text: userContent }); + + const messages: ModelMessage[] = [ + { + role: "user", + content: + userParts.length === 1 && userParts[0]!.type === "text" ? userParts[0]!.text : userParts, + }, + ]; + + const stream = await streamAnthropic({ + model: useModel, + apiKey, + providerType: providerType as ProviderType | undefined, + baseURL, + messages, + maxTokens: 16384, + enableCaching: true, + systemPrompt: systemPrompt || "", + functionId, + frameIndex: frameIdx, + onFinish: (event) => ctx.tokenUsage?.add(event.usage), + }); + + const heartbeatInterval = setInterval(() => { + ctx.emit({ type: "step", step: "layout", status: "running", frameIndex: frameIdx }); + }, HEARTBEAT_INTERVAL_MS); + + try { + const fullText = await Promise.race([ + stream.text, + new Promise((_, reject) => { + if (ctx.signal.aborted) { + reject(new DOMException("Aborted", "AbortError")); + return; + } + ctx.signal.addEventListener( + "abort", + () => { + reject(new DOMException("Aborted", "AbortError")); + }, + { once: true }, + ); + }), + ]); + + clearInterval(heartbeatInterval); + + let result: { html: string; width?: number; height?: number; comment?: string }; + try { + result = validateLayout(fullText); + } catch { + result = parseHtmlWithSize(fullText, { extractComments: true }); + } + + if (restoreFn) { + result = { ...result, html: restoreFn(result.html) }; + } + + for (const [token, dataUrl] of Object.entries(imageTokenMap)) { + result.html = result.html.replaceAll(token, dataUrl); + } + + return { + html: result.html, + width: result.width, + height: result.height, + comment: result.comment, + }; + } finally { + clearInterval(heartbeatInterval); + } +}; diff --git a/packages/pipeline/src/steps/plan.step.ts b/packages/pipeline/src/steps/plan.step.ts new file mode 100644 index 00000000..2f6f7320 --- /dev/null +++ b/packages/pipeline/src/steps/plan.step.ts @@ -0,0 +1,78 @@ +import { generateWithFallback } from "@app/core/ai/client"; +import type { ProviderType } from "@app/core/ai/providers"; +import { buildPlanPrompt } from "@app/core/prompts/plan"; +import type { ModelMessage } from "ai"; + +import type { PlanInput, PlanOutput, Step, StepContext } from "../types"; + +const VARIATION_STYLES = [ + { name: "Minimal", direction: "Clean lines, generous whitespace, restrained color palette" }, + { name: "Bold", direction: "High contrast, striking typography, confident composition" }, + { name: "Organic", direction: "Soft shapes, warm tones, natural textures" }, +]; + +export const planStep: Step = async (input, ctx: StepContext) => { + const { prompt, model, apiKey, baseURL, providerType } = input; + const useModel = model; + + const messages: ModelMessage[] = [ + { + role: "user", + content: buildPlanPrompt(prompt), + }, + ]; + + try { + const { result } = await generateWithFallback({ + apiKey, + model: useModel, + messages, + maxTokens: 2048, + providerType: providerType as ProviderType | undefined, + baseURL, + functionId: "plan", + onFinish: (event) => ctx.tokenUsage?.add(event.usage), + }); + + const raw = result.text; + + let concepts: Array<{ name: string; direction: string }>; + try { + const parsed = JSON.parse(raw); + if (Array.isArray(parsed)) { + concepts = parsed.map((c: { name?: string; direction?: string }) => ({ + name: c.name || "Variation", + direction: c.direction || "", + })); + } else if (parsed.concepts && Array.isArray(parsed.concepts)) { + concepts = parsed.concepts.map((c: { name?: string; direction?: string }) => ({ + name: c.name || "Variation", + direction: c.direction || "", + })); + } else { + throw new Error("Unexpected plan response format"); + } + } catch { + const lines = raw.split("\n").filter((l) => l.trim()); + concepts = lines.slice(0, 3).map((line, i) => ({ + name: line.split(":")[0]?.trim() || `Variation ${i + 1}`, + direction: line.split(":")[1]?.trim() || line.trim(), + })); + } + + if (concepts.length === 0) { + throw new Error("No concepts generated"); + } + + return { + count: concepts.length, + concepts, + }; + } catch (error) { + ctx.logger.warn("Plan generation failed, using fallback:", { error }); + return { + count: VARIATION_STYLES.length, + concepts: VARIATION_STYLES, + }; + } +}; diff --git a/packages/pipeline/src/steps/review.step.ts b/packages/pipeline/src/steps/review.step.ts new file mode 100644 index 00000000..b9d2cf9d --- /dev/null +++ b/packages/pipeline/src/steps/review.step.ts @@ -0,0 +1,55 @@ +import { generateWithFallback } from "@app/core/ai/client"; +import type { ProviderType } from "@app/core/ai/providers"; +import { buildReviewPrompt } from "@app/core/prompts/review"; +import { validateReview } from "@app/shared"; +import type { ModelMessage } from "ai"; + +import { parseHtmlWithSize } from "../lib/parse-html"; +import { stripBase64Images } from "../lib/strip-base64"; +import type { ReviewInput, ReviewOutput, Step, StepContext } from "../types"; + +export const reviewStep: Step = async (input, ctx: StepContext) => { + const { html, prompt, width, height, model, apiKey, baseURL, providerType, frameIndex } = input; + const useModel = model; + const frameIdx = frameIndex ?? 0; + + const { stripped, restore } = stripBase64Images(html); + + const messages: ModelMessage[] = [ + { + role: "user", + content: buildReviewPrompt(prompt || "", width, height, stripped), + }, + ]; + + const { result } = await generateWithFallback({ + apiKey, + model: useModel, + messages, + maxTokens: 16384, + providerType: providerType as ProviderType | undefined, + baseURL, + functionId: `review:${frameIdx + 1}`, + frameIndex: frameIdx, + onFinish: (event) => ctx.tokenUsage?.add(event.usage), + }); + + const raw = result.text; + + try { + const validated = validateReview(raw); + return { + html: restore(validated.html), + width: validated.width || width, + height: validated.height || height, + }; + } catch (error) { + ctx.logger.warn("Review validation failed, returning parsed output:", { error }); + const parsed = parseHtmlWithSize(raw); + return { + html: restore(parsed.html), + width: parsed.width || width, + height: parsed.height || height, + }; + } +}; diff --git a/packages/pipeline/src/steps/summary.step.ts b/packages/pipeline/src/steps/summary.step.ts new file mode 100644 index 00000000..8b4d0c24 --- /dev/null +++ b/packages/pipeline/src/steps/summary.step.ts @@ -0,0 +1,42 @@ +import { generateWithFallback } from "@app/core/ai/client"; +import type { ProviderType } from "@app/core/ai/providers"; +import { buildSummaryPrompt } from "@app/core/prompts/summary"; +import { validateSummary } from "@app/shared"; +import type { ModelMessage } from "ai"; + +import { stripBase64Images } from "../lib/strip-base64"; +import type { Step, StepContext, SummaryInput, SummaryOutput } from "../types"; + +export const summaryStep: Step = async (input, ctx: StepContext) => { + const { html, prompt, labels, model, apiKey, baseURL, providerType } = input; + + const { stripped } = stripBase64Images(html); + + const messages: ModelMessage[] = [ + { + role: "user", + content: buildSummaryPrompt(prompt, stripped, labels ?? []), + }, + ]; + + const { result } = await generateWithFallback({ + apiKey, + model: model, + messages, + maxTokens: 512, + providerType: providerType as ProviderType | undefined, + baseURL, + functionId: "summary", + onFinish: (event) => ctx.tokenUsage?.add(event.usage), + }); + + const raw = result.text; + try { + const parsed = JSON.parse(raw); + const validated = validateSummary(parsed); + return { summary: JSON.stringify(validated) }; + } catch (error) { + ctx.logger.warn("Summary validation failed:", { error }); + return { summary: raw }; + } +}; diff --git a/packages/pipeline/src/stream.test.ts b/packages/pipeline/src/stream.test.ts new file mode 100644 index 00000000..c4fecb03 --- /dev/null +++ b/packages/pipeline/src/stream.test.ts @@ -0,0 +1,126 @@ +import type { GenerateOptions } from "@app/core/ai/client"; +import { describe, expect, it, vi } from "vitest"; + +vi.mock("@app/core/ai/client", () => ({ + generateWithFallback: vi.fn(), + streamAnthropic: vi.fn(), +})); + +vi.mock("@app/core/pipeline/images", () => ({ + generateImages: vi.fn(), +})); + +import { generateWithFallback, streamAnthropic } from "@app/core/ai/client"; +import { generateImages } from "@app/core/pipeline/images"; + +import { designPipelineStream } from "./stream"; + +async function readStream( + stream: ReadableStream, +): Promise> { + const reader = stream.getReader(); + const decoder = new TextDecoder(); + let buffer = ""; + const parts: Array<{ type: string; [key: string]: unknown }> = []; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + buffer += decoder.decode(value, { stream: true }); + const lines = buffer.split("\n"); + buffer = lines.pop() ?? ""; + for (const line of lines) { + const colonIdx = line.indexOf(":"); + if (colonIdx === -1) continue; + try { + parts.push( + JSON.parse(line.slice(colonIdx + 1)) as { type: string; [key: string]: unknown }, + ); + } catch { + // ignore malformed lines + } + } + } + return parts; +} + +function setupMocks() { + vi.clearAllMocks(); + + (generateWithFallback as ReturnType).mockImplementation( + async (options: GenerateOptions) => { + const functionId = options.functionId ?? ""; + const baseResult = { text: "" } as Awaited>["result"]; + + if (functionId === "plan") { + return { + result: { text: JSON.stringify([{ name: "Minimal", direction: "Clean" }]) } as Awaited< + ReturnType + >["result"], + usedModel: options.model ?? "model", + }; + } + + if (functionId.startsWith("review")) { + return { + result: { text: "
reviewed
" } as typeof baseResult, + usedModel: options.model ?? "model", + }; + } + + if (functionId.startsWith("critique")) { + return { + result: { text: "Looks good" } as typeof baseResult, + usedModel: options.model ?? "model", + }; + } + + if (functionId === "summary") { + return { + result: { text: JSON.stringify({ rationale: "nice" }) } as typeof baseResult, + usedModel: options.model ?? "model", + }; + } + + return { result: baseResult, usedModel: options.model ?? "model" }; + }, + ); + + (streamAnthropic as ReturnType).mockResolvedValue({ + text: Promise.resolve(`\n
hello
`), + }); + + (generateImages as ReturnType).mockResolvedValue({ + html: `
hello
`, + imageCount: 0, + skipped: true, + reason: "no keys", + }); +} + +describe("designPipelineStream", () => { + it("emits an error part for invalid input", async () => { + const stream = designPipelineStream({ prompt: 123 }); + const parts = await readStream(stream); + + expect(parts[0]).toMatchObject({ type: "error", errorText: "Invalid workflow input" }); + }); + + it("streams a successful workflow to completion", async () => { + setupMocks(); + + const stream = designPipelineStream({ prompt: "a card", mode: "sequential", model: "model" }); + const parts = await readStream(stream); + + const workflowParts = parts.filter((p) => p.type === "data-workflow"); + expect(workflowParts.length).toBeGreaterThan(0); + + const last = workflowParts[workflowParts.length - 1] as unknown as { + data: { status: string; steps: Record }; + }; + expect(last.data.status).toBe("success"); + expect(last.data.steps.collectResults?.output).toMatchObject({ + frames: [expect.objectContaining({ label: "Variation 1" })], + }); + }); +}); diff --git a/packages/pipeline/src/stream.ts b/packages/pipeline/src/stream.ts new file mode 100644 index 00000000..80b01848 --- /dev/null +++ b/packages/pipeline/src/stream.ts @@ -0,0 +1,165 @@ +import { getLogger } from "@app/logger"; + +import { designPipeline } from "./pipeline"; +import type { FrameResult, PipelineEvent } from "./types"; +import { WorkflowInputSchema } from "./types"; + +interface WorkflowStepResult { + name: string; + status: string; + input: null; + output: unknown; + suspendPayload: null; + resumePayload: null; +} + +interface WorkflowData { + name: string; + status: string; + steps: Record; + output: { + usage: { inputTokens: number; outputTokens: number; totalTokens: number }; + } | null; +} + +const STEP_ORDER = ["plan", "frameOrchestrator", "summary", "collectResults"]; + +function buildInitialSteps(): Record { + return { + plan: { + name: "plan", + status: "running", + input: null, + output: null, + suspendPayload: null, + resumePayload: null, + }, + }; +} + +function buildWorkflowData(steps: Record): WorkflowData { + const orderedSteps: Record = {}; + for (const name of STEP_ORDER) { + if (steps[name]) { + orderedSteps[name] = steps[name]!; + } + } + for (const [name, result] of Object.entries(steps)) { + if (!orderedSteps[name]) { + orderedSteps[name] = result; + } + } + + const isFailed = Object.values(steps).some((s) => s.status === "failed"); + const isSuccess = steps.collectResults?.status === "success" || steps.plan?.status === "success"; + + return { + name: "designPipeline", + status: isFailed ? "failed" : isSuccess ? "success" : "running", + steps: orderedSteps, + output: { + usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 }, + }, + }; +} + +function updateSteps( + steps: Record, + event: PipelineEvent, +): Record { + switch (event.type) { + case "step": { + const existing = steps[event.step]; + steps[event.step] = { + name: event.step, + status: event.status, + input: existing?.input ?? null, + output: event.output ?? existing?.output ?? null, + suspendPayload: null, + resumePayload: null, + }; + break; + } + case "frame": { + const fo = steps.frameOrchestrator; + if (fo) { + const frames = ((fo.output as { frames?: FrameResult[] } | null)?.frames ?? + []) as FrameResult[]; + frames[event.frameIndex] = event.frame; + fo.output = { frames }; + } + break; + } + case "done": { + steps.collectResults = { + name: "collectResults", + status: "success", + input: null, + output: event.output, + suspendPayload: null, + resumePayload: null, + }; + break; + } + case "error": { + break; + } + case "abort": { + break; + } + } + return steps; +} + +function encodeSSE(index: number, part: { type: string; [key: string]: unknown }): Uint8Array { + const line = `${index}:${JSON.stringify(part)}\n`; + return new TextEncoder().encode(line); +} + +export function designPipelineStream(input: unknown): ReadableStream { + const parsed = WorkflowInputSchema.safeParse(input); + if (!parsed.success) { + return new ReadableStream({ + start(controller) { + controller.enqueue(encodeSSE(0, { type: "error", errorText: "Invalid workflow input" })); + controller.close(); + }, + }); + } + + const abortController = new AbortController(); + + return new ReadableStream({ + async start(controller) { + const steps = buildInitialSteps(); + let index = 0; + + const send = (part: { type: string; [key: string]: unknown }) => { + controller.enqueue(encodeSSE(index++, part)); + }; + + const emit = (event: PipelineEvent) => { + updateSteps(steps, event); + send({ type: "data-workflow", id: "designPipeline", data: buildWorkflowData(steps) }); + }; + + send({ type: "data-workflow", id: "designPipeline", data: buildWorkflowData(steps) }); + + try { + await designPipeline(parsed.data, { + signal: abortController.signal, + emit, + logger: getLogger(["calca", "pipeline", "stream"]), + }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + send({ type: "error", errorText: message }); + } finally { + controller.close(); + } + }, + cancel() { + abortController.abort(); + }, + }); +} diff --git a/packages/pipeline/src/telemetry.ts b/packages/pipeline/src/telemetry.ts new file mode 100644 index 00000000..effc83ce --- /dev/null +++ b/packages/pipeline/src/telemetry.ts @@ -0,0 +1,119 @@ +import { context, Span, SpanKind, SpanStatusCode, trace, Tracer } from "@opentelemetry/api"; + +import type { PipelineEvent, StepContext } from "./types"; + +const TRACER_NAME = "calca.pipeline"; + +export interface TelemetryCallbacks { + onStart(params: { modelId: string; prompt: unknown[]; settings?: Record }): void; + onFinish(params: { + modelId: string; + usage: { inputTokens?: number; outputTokens?: number; totalTokens?: number }; + finishReason: string; + durationMs: number; + }): void; + onError(params: { modelId: string; error: Error }): void; +} + +export interface TelemetryCallbacksOptions { + functionId: string; + frameIndex?: number; + isEnabled?: boolean; +} + +export function createTelemetryCallbacks( + _category: string[] = ["calca", "pipeline", "telemetry"], + _options: TelemetryCallbacksOptions, +): TelemetryCallbacks { + return { + onStart() {}, + onFinish() {}, + onError() {}, + }; +} + +export interface TokenUsage { + inputTokens: number; + outputTokens: number; + totalTokens: number; +} + +export class TokenAggregator { + private usage: TokenUsage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 }; + + add(u: Partial) { + if (u.inputTokens != null) this.usage.inputTokens += u.inputTokens; + if (u.outputTokens != null) this.usage.outputTokens += u.outputTokens; + if (u.totalTokens != null) this.usage.totalTokens += u.totalTokens; + } + + get(): TokenUsage { + return { ...this.usage }; + } + + reset() { + this.usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 }; + } +} + +export const tokenAggregator = new TokenAggregator(); + +export function getPipelineTracer(): Tracer { + return trace.getTracer(TRACER_NAME); +} + +export function wrapStep( + name: string, + fn: (ctx: StepContext) => Promise, + ctx: StepContext, +): Promise { + const tracer = trace.getTracer(TRACER_NAME); + return tracer.startActiveSpan( + `pipeline.${name}`, + { kind: SpanKind.INTERNAL }, + async (span: Span) => { + try { + const result = await fn(ctx); + span.setStatus({ code: SpanStatusCode.OK }); + return result; + } catch (err) { + span.recordException(err instanceof Error ? err : new Error(String(err))); + span.setStatus({ code: SpanStatusCode.ERROR }); + throw err; + } finally { + span.end(); + } + }, + ); +} + +export function createFrameSpan(frameIndex: number, conceptName: string): Span { + const tracer = trace.getTracer(TRACER_NAME); + const span = tracer.startSpan("pipeline.frame", { + kind: SpanKind.INTERNAL, + attributes: { + "frame.index": frameIndex, + "frame.concept": conceptName, + }, + }); + return span; +} + +export function withActiveFrameSpan( + frameIndex: number, + conceptName: string, + fn: () => Promise, +): Promise { + const span = createFrameSpan(frameIndex, conceptName); + return context.with(trace.setSpan(context.active(), span), async () => { + try { + return await fn(); + } catch (err) { + span.recordException(err instanceof Error ? err : new Error(String(err))); + span.setStatus({ code: SpanStatusCode.ERROR }); + throw err; + } finally { + span.end(); + } + }); +} diff --git a/packages/pipeline/src/types.ts b/packages/pipeline/src/types.ts new file mode 100644 index 00000000..ef3d7cc5 --- /dev/null +++ b/packages/pipeline/src/types.ts @@ -0,0 +1,219 @@ +import type { Tracer } from "@opentelemetry/api"; +import { z } from "zod"; + +import type { TokenAggregator } from "./telemetry"; + +// ── Workflow I/O ──────────────────────────────────────────────────────────── + +export const WorkflowInputSchema = z.object({ + prompt: z.string(), + mode: z.enum(["quick", "sequential"]), + conceptCount: z.number().optional(), + model: z.string().optional(), + apiKey: z.string().optional(), + baseURL: z.string().optional(), + providerType: z.string().optional(), + geminiKey: z.string().optional(), + unsplashKey: z.string().optional(), + openaiKey: z.string().optional(), + systemPrompt: z.string().optional(), + contextImages: z.array(z.string()).optional(), + revision: z.string().optional(), + existingHtml: z.string().optional(), +}); + +export const FrameResultSchema = z.object({ + html: z.string(), + width: z.number().optional(), + height: z.number().optional(), + label: z.string(), + comment: z.string().optional(), + critique: z.string().optional(), +}); + +export const WorkflowOutputSchema = z.object({ + frames: z.array(FrameResultSchema), + summary: z.string().optional(), +}); + +export type WorkflowInput = z.infer; +export type WorkflowOutput = z.infer; +export type FrameResult = z.infer; + +// ── Plan ──────────────────────────────────────────────────────────────────── + +export const PlanInputSchema = z.object({ + apiKey: z.string().optional(), + baseURL: z.string().optional(), + model: z.string().optional(), + prompt: z.string(), + providerType: z.string().optional(), +}); + +export const ConceptSchema = z.object({ + direction: z.string(), + name: z.string(), +}); + +export const PlanOutputSchema = z.object({ + concepts: z.array(ConceptSchema), + count: z.number(), +}); + +export type PlanInput = z.infer; +export type Concept = z.infer; +export type PlanOutput = z.infer; + +// ── Layout ────────────────────────────────────────────────────────────────── + +export const LayoutInputSchema = z.object({ + prompt: z.string(), + concept: z.string().optional(), + contextImages: z.array(z.string()).optional(), + critique: z.string().optional(), + revision: z.string().optional(), + existingHtml: z.string().optional(), + systemPrompt: z.string().optional(), + model: z.string().optional(), + apiKey: z.string().optional(), + baseURL: z.string().optional(), + providerType: z.string().optional(), + frameIndex: z.number().optional(), +}); + +export const LayoutOutputSchema = z.object({ + html: z.string(), + width: z.number().optional(), + height: z.number().optional(), + comment: z.string().optional(), +}); + +export type LayoutInput = z.infer; +export type LayoutOutput = z.infer; + +// ── Images ────────────────────────────────────────────────────────────────── + +export const ImagesInputSchema = z.object({ + geminiKey: z.string().optional(), + html: z.string(), + openaiKey: z.string().optional(), + unsplashKey: z.string().optional(), + viewport: z.object({ height: z.number(), width: z.number() }).optional(), +}); + +export const ImagesOutputSchema = z.object({ + html: z.string(), +}); + +export type ImagesInput = z.infer; +export type ImagesOutput = z.infer; + +// ── Review ────────────────────────────────────────────────────────────────── + +export const ReviewInputSchema = z.object({ + html: z.string(), + prompt: z.string(), + width: z.number().optional(), + height: z.number().optional(), + model: z.string().optional(), + apiKey: z.string().optional(), + baseURL: z.string().optional(), + providerType: z.string().optional(), + frameIndex: z.number().optional(), +}); + +export const ReviewOutputSchema = z.object({ + html: z.string(), + width: z.number().optional(), + height: z.number().optional(), +}); + +export type ReviewInput = z.infer; +export type ReviewOutput = z.infer; + +// ── Critique ──────────────────────────────────────────────────────────────── + +export const CritiqueInputSchema = z.object({ + apiKey: z.string().optional(), + baseURL: z.string().optional(), + html: z.string(), + model: z.string().optional(), + prompt: z.string(), + providerType: z.string().optional(), + frameIndex: z.number().optional(), +}); + +export const CritiqueOutputSchema = z.object({ + critique: z.string(), +}); + +export type CritiqueInput = z.infer; +export type CritiqueOutput = z.infer; + +// ── Summary ───────────────────────────────────────────────────────────────── + +export const SummaryInputSchema = z.object({ + apiKey: z.string().optional(), + baseURL: z.string().optional(), + html: z.string(), + labels: z.array(z.string()).optional(), + model: z.string().optional(), + prompt: z.string(), + providerType: z.string().optional(), +}); + +export const SummaryOutputSchema = z.object({ + summary: z.string(), +}); + +export type SummaryInput = z.infer; +export type SummaryOutput = z.infer; + +// ── Step interface ────────────────────────────────────────────────────────── + +export type StepName = + | "plan" + | "layout" + | "images" + | "review" + | "critique" + | "summary" + | "frameOrchestrator" + | "collectResults" + | "frameComplete"; + +export type PipelineEvent = + | { + type: "step"; + step: StepName; + status: "running" | "success" | "failed"; + frameIndex?: number; + output?: unknown; + } + | { type: "frame"; frameIndex: number; frame: FrameResult } + | { type: "done"; output: WorkflowOutput } + | { type: "error"; message: string } + | { type: "abort" }; + +export interface PipelineContext { + signal: AbortSignal; + emit: (event: PipelineEvent) => void; + logger: Logger; +} + +export interface StepContext { + signal: AbortSignal; + emit: (event: PipelineEvent) => void; + logger: Logger; + tracer?: Tracer; + tokenUsage?: TokenAggregator; +} + +export type Step = (input: I, ctx: StepContext) => Promise; + +export interface Logger { + debug: (msg: string, meta?: Record) => void; + info: (msg: string, meta?: Record) => void; + warn: (msg: string, meta?: Record) => void; + error: (msg: string, meta?: Record) => void; +} diff --git a/packages/pipeline/tsconfig.json b/packages/pipeline/tsconfig.json new file mode 100644 index 00000000..da760249 --- /dev/null +++ b/packages/pipeline/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../packages/config/tsconfig/base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "lib": ["ESNext", "DOM"], + "types": ["bun"] + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["node_modules", "dist"] +}