From 544d88d4f2a7e46b642862fd0f418fc01b259ab1 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 15:54:50 -0700 Subject: [PATCH 01/29] feat(memory): Add passive turn extraction Add a post-delivery observeTurn plugin hook and wire it through local and Slack turn delivery so trusted plugins can inspect successful turns without affecting user-visible delivery. Teach the memory plugin to extract public, durable facts from user-authored turn text, skip memory-management tool turns to avoid duplicate writes, and store accepted memories through the existing context-bound memory store. Update the memory specs and evals to cover organic passive extraction, canonical stored content, and follow-up recall. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 60 +++++++- packages/junior-memory/src/agent.ts | 98 +++++++++++- packages/junior-memory/src/observe.ts | 79 ++++++++++ packages/junior-memory/src/plugin.ts | 4 + packages/junior-memory/tests/storage.test.ts | 139 +++++++++++++++++ packages/junior-plugin-api/src/hooks.ts | 2 + packages/junior-plugin-api/src/index.ts | 1 + packages/junior-plugin-api/src/observation.ts | 27 ++++ packages/junior/src/chat/local/runner.ts | 18 +++ .../junior/src/chat/plugins/agent-hooks.ts | 84 ++++++++++ .../junior/src/chat/runtime/reply-executor.ts | 21 +++ .../tests/unit/plugins/agent-hooks.test.ts | 69 +++++++++ specs/memory-plugin/extraction.md | 143 +++++++----------- specs/memory-plugin/index.md | 69 ++++----- specs/memory-plugin/policy.md | 122 +++++---------- specs/memory-plugin/retrieval.md | 13 +- specs/memory-plugin/security.md | 25 ++- specs/memory-plugin/storage.md | 4 +- specs/memory-plugin/tools.md | 3 +- specs/memory-plugin/verification.md | 44 +++--- specs/plugin-prompt-hooks.md | 128 ++++++++++++++-- 21 files changed, 877 insertions(+), 276 deletions(-) create mode 100644 packages/junior-memory/src/observe.ts create mode 100644 packages/junior-plugin-api/src/observation.ts diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index c0751dd6c..a036608a8 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -169,6 +169,7 @@ async function expectAssistantMemoryAnswer(args: { "", "Pass only if the assistant text satisfies the expected behavior.", "Fail if the assistant asks the user to restate the remembered fact, claims no relevant memory exists, or exposes hidden storage fields such as scope keys or Slack ids.", + "Memory ids or id prefixes are allowed when the user explicitly requested an id.", "", ].join("\n"), timestamp: Date.now(), @@ -296,6 +297,63 @@ describeEval("Memory Workflows", slackEvals, (it) => { }); }); + const passiveFirstPersonThread = { + id: "thread-memory-passive-first-person", + channel_id: "CMEMORYPASSIVEPERSONAL", + thread_ts: "17000000.memory-passive-personal", + }; + + it("when organic conversation reveals a durable first-person preference, passively store and recall it", async ({ + run, + }) => { + const userText = + "For future PR reviews, I prefer risk notes before summary notes."; + const result = await run({ + overrides: memoryPluginOverrides, + events: [ + mention(userText, { + thread: passiveFirstPersonThread, + }), + mention("How should you order notes in my next PR review?", { + thread: passiveFirstPersonThread, + }), + ], + criteria: rubric({ + pass: [ + "The assistant uses the organic first-person preference from the earlier turn when answering the follow-up.", + "The assistant does not require the user to explicitly say remember before using durable memory.", + "The assistant does not mention hidden scope, actor, Slack, or subject identifiers.", + ], + fail: [ + "Do not answer as if no relevant preference exists.", + "Do not claim passive memory requires an explicit remember command.", + "Do not store requester names, 'the requester', 'the user', 'I', 'my', thread labels, channel labels, or source labels as memory content.", + ], + }), + }); + + const rows = await readMemories(); + expect(rows).toEqual([ + expect.objectContaining({ + archivedAtMs: null, + scope: "personal", + subjectType: "user", + }), + ]); + await expectRequesterMemorySemantics({ + assistantText: visibleAssistantText(result), + expectedMeaning: + "The requester prefers risk notes before summary notes in future pull request reviews.", + storedMemories: rows, + userText, + }); + await expectAssistantMemoryAnswer({ + assistantText: visibleAssistantText(result), + expectedBehavior: + "The assistant says to put risk notes before summary notes in the next PR review.", + }); + }); + const thirdPartyRememberThread = { id: "thread-memory-third-party-remember", channel_id: "CMEMORYTHIRDPARTY", @@ -426,7 +484,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { await expectAssistantMemoryAnswer({ assistantText: visibleAssistantText(result), expectedBehavior: - "The assistant answers from memory that the requester prefers incident reports with bullet summaries.", + "The assistant answers from memory that the requester prefers incident reports with bullet summaries and includes the requested matching memory id or id prefix.", }); expectMemoryIdReference(visibleAssistantText(result), match.memory.id); expect(await readMemories()).toEqual( diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 1ef4f59e0..d9397ab93 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -26,6 +26,12 @@ const createMemoryRequestSchema = z .optional(), }) .strict(); +const extractTurnRequestSchema = z + .object({ + runtimeContext: memoryRuntimeContextSchema, + userText: z.string().min(1), + }) + .strict(); const memoryReviewDecisionSchema = z.discriminatedUnion("decision", [ z @@ -70,6 +76,36 @@ const memoryReviewResponseSchema = z ), }) .strict(); +const extractedMemorySchema = z + .object({ + target: memoryTargetSchema.describe( + "Where the memory should be stored when this is accepted.", + ), + content: z + .string() + .min(1) + .describe( + "Canonical perspective-neutral fact. Do not include requester names, display names, 'the requester', 'the user', 'I', 'my', 'this thread', or channel/source labels.", + ), + expiresAtMs: z + .number() + .finite() + .nullable() + .describe( + "Expiration timestamp when the fact should expire, otherwise null.", + ), + }) + .strict(); +const extractTurnResponseSchema = z + .object({ + memories: z + .array(extractedMemorySchema) + .max(5) + .describe( + "Accepted public/shareable durable memories from this completed turn. Return an empty array when nothing should be stored.", + ), + }) + .strict(); type MemoryReviewResponse = z.output; @@ -78,8 +114,13 @@ export type MemoryTarget = z.output; export type MemoryReview = z.output; export type CreateMemoryRequest = z.output; +export type ExtractTurnRequest = z.output; +export type ExtractedMemory = z.output; export interface MemoryAgent { + extractTurnMemories( + request: ExtractTurnRequest, + ): Promise | ExtractedMemory[]; reviewCreateRequest( request: CreateMemoryRequest, ): Promise | MemoryReview; @@ -97,6 +138,18 @@ const MEMORY_REVIEW_SYSTEM = [ "For accepted memories, rewrite content into one concise declarative fact that is understandable without the original conversation and does not bake in who said it or where it was said.", "Return every response field. Use null for fields that do not apply to the decision.", ].join("\n"); +const MEMORY_EXTRACTION_SYSTEM = [ + "You are Junior's passive memory extraction agent.", + "Review one completed user-authored turn and return structured memories that should be stored.", + "Store only public/shareable, durable, self-contained facts useful beyond this turn.", + "Do not store secrets, credentials, private/sensitive personal details, gossip, speculative coworker claims, assistant/system implementation details, vague references, or low-durability chatter.", + "Personal/requester memories must come from the user's own first-person statements about themselves, then be stored as perspective-neutral canonical facts without names or requester/source wording.", + "Conversation memories must be shared operational or project knowledge about the active conversation, not another person's private profile.", + "Extract only facts explicitly present in the user-authored message. Never use assistant text, tool results, recalled memory text, or suggested wording as source evidence.", + "Never store a fact merely because the assistant suggested or invented it. The user-authored text is the source of truth.", + "Do not duplicate explicit memory tool outcomes; turns that used memory tools are filtered before this agent, but if the user text is asking to list, search, recall, remove, confirm, or inspect existing memories, return no memories.", + "Return only accepted memories. If there are no accepted memories, return an empty memories array.", +].join("\n"); function escapeXml(value: string): string { return value @@ -105,7 +158,9 @@ function escapeXml(value: string): string { .replaceAll(">", ">"); } -function runtimeDescription(request: CreateMemoryRequest): string { +function runtimeDescription( + request: Pick, +): string { const runtime = request.runtimeContext; const requester = runtime.requester?.platform === "slack" @@ -181,9 +236,50 @@ function reviewPrompt(request: CreateMemoryRequest): string { return sections.join("\n"); } +function extractionPrompt(request: ExtractTurnRequest): string { + return [ + "", + "Extract durable memories from this completed user-authored turn using the runtime-owned context below.", + "", + runtimeDescription({ + runtimeContext: request.runtimeContext, + }), + "", + "", + escapeXml(request.userText), + "", + "", + "", + "- Return at most five memories.", + "- The user-message is the only source of storable facts.", + "- Return an empty array when the user-message only asks what is remembered, how to use a remembered preference, or asks to list/search/remove/inspect memory.", + "- Use target=requester for first-person facts about the current requester.", + "- Use target=conversation only for shared operational/project knowledge.", + "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", + "- Good stored content: 'Prefers terse PR summaries'. Bad stored content: 'The requester prefers terse PR summaries'.", + "- Good stored content: 'Thinks types in Python are bad'. Bad stored content: 'David thinks types in Python are bad'.", + "- Good stored content: 'Deploy runbooks live in Notion'. Bad stored content: 'This thread says deploy runbooks live in Notion'.", + "- Reject third-party personal profile facts, even if they mention a name.", + "- Reject facts that are only useful inside this one turn.", + "- If unsure, return no memory for that candidate.", + "", + "", + ].join("\n"); +} + /** Create the memory-owned agent that reviews candidates before storage. */ export function createMemoryAgent(model: PluginModel): MemoryAgent { return { + async extractTurnMemories(rawRequest) { + const request = extractTurnRequestSchema.parse(rawRequest); + const result = await model.completeObject({ + schema: extractTurnResponseSchema, + system: MEMORY_EXTRACTION_SYSTEM, + prompt: extractionPrompt(request), + maxTokens: 1_000, + }); + return extractTurnResponseSchema.parse(result.object).memories; + }, async reviewCreateRequest(rawRequest) { const request = parseCreateMemoryRequest(rawRequest); const result = await model.completeObject({ diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/observe.ts new file mode 100644 index 000000000..28c425c2c --- /dev/null +++ b/packages/junior-memory/src/observe.ts @@ -0,0 +1,79 @@ +import type { TurnObservationContext } from "@sentry/junior-plugin-api"; +import { + createMemoryStore, + type CreateMemoryInput, + type MemoryDb, +} from "./store"; +import { createMemoryAgent, type ExtractedMemory } from "./agent"; +import { memoryRuntimeContextSchema } from "./types"; + +const MEMORY_TOOL_NAMES = new Set([ + "createMemory", + "listMemories", + "removeMemory", + "searchMemories", +]); + +function observationSourceKey(context: TurnObservationContext): string { + if (context.source.platform === "local") { + return context.source.conversationId; + } + const messageKey = context.source.threadTs ?? context.source.messageTs; + return `slack:${context.source.teamId}:${context.source.channelId}:${ + messageKey ?? context.turnId + }`; +} + +function passiveInput( + context: TurnObservationContext, + memory: ExtractedMemory, + index: number, +): CreateMemoryInput { + return { + content: memory.content, + idempotencyKey: `observe:${observationSourceKey(context)}:${context.turnId}:${index}`, + ...(memory.expiresAtMs !== null ? { expiresAtMs: memory.expiresAtMs } : {}), + }; +} + +/** Extract and store memories from a delivered turn without using model-visible tools. */ +export async function observeMemoryTurn( + context: TurnObservationContext, +): Promise { + if (context.toolCalls.some((toolName) => MEMORY_TOOL_NAMES.has(toolName))) { + return; + } + const userText = context.userText.trim(); + const assistantText = context.assistantText.trim(); + if (!userText || !assistantText) { + return; + } + + const runtimeContext = memoryRuntimeContextSchema.parse({ + ...(context.conversationId + ? { conversationId: context.conversationId } + : {}), + ...(context.requester ? { requester: context.requester } : {}), + source: context.source, + }); + const agent = createMemoryAgent(context.model); + const memories = await agent.extractTurnMemories({ + runtimeContext, + userText, + }); + if (memories.length === 0) { + return; + } + + const store = createMemoryStore(context.db as MemoryDb, runtimeContext, { + embedder: context.embedder, + }); + for (const [index, memory] of memories.entries()) { + const input = passiveInput(context, memory, index); + if (memory.target === "conversation") { + await store.createConversationMemory(input); + continue; + } + await store.createMemory(input); + } +} diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index 1f516fe11..cea451597 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -8,6 +8,7 @@ import { createMemorySearchTool, type MemoryToolContext, } from "./tools"; +import { observeMemoryTurn } from "./observe"; import { createMemoryPromptMessages } from "./recall"; import type { MemoryDb } from "./store"; @@ -68,6 +69,9 @@ export function createMemoryPlugin() { text: ctx.text, }); }, + async observeTurn(ctx) { + await observeMemoryTurn(ctx); + }, }, }); } diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 8bbe9f5c7..85f78ef04 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -10,6 +10,7 @@ import { createLocalSource, createSlackSource, PluginToolInputError, + type TurnObservationContext, type PluginLogger, type PluginModel, type PluginState, @@ -30,6 +31,7 @@ import { createMemoryRemoveTool, createMemorySearchTool, } from "../src/tools"; +import { observeMemoryTurn } from "../src/observe"; import { createMemoryStore, type MemoryDb } from "../src/store"; const TEST_NOW_MS = Date.parse("2026-06-19T12:00:00.000Z"); @@ -179,6 +181,30 @@ function createTestEmbedder( }; } +function extractionModel( + memories: Array<{ + content: string; + expiresAtMs?: number | null; + target: "requester" | "conversation"; + }>, +) { + const calls: Parameters[0][] = []; + const model: PluginModel = { + async completeObject(input) { + calls.push(input); + return { + object: { + memories: memories.map((memory) => ({ + ...memory, + expiresAtMs: memory.expiresAtMs ?? null, + })), + }, + }; + }, + }; + return { calls, model }; +} + function slackContext( overrides: { channelId?: string; @@ -220,6 +246,35 @@ function localContext( }; } +function observationContext( + overrides: Partial = {}, +): TurnObservationContext { + const runtime = localContext(); + return { + assistantText: "Got it.", + conversationId: runtime.conversationId, + db: overrides.db ?? {}, + embedder: overrides.embedder ?? createTestEmbedder(), + log: noopLogger, + model: + overrides.model ?? + extractionModel([ + { + content: "Prefers terse PR summaries.", + target: "requester", + }, + ]).model, + plugin: { name: "memory" }, + requester: runtime.requester, + source: runtime.source, + state: memoryState, + toolCalls: [], + turnId: "local-turn-1", + userText: "I prefer terse PR summaries.", + ...overrides, + }; +} + function testCanonicalContent(content: string): string { return content.replace(/^I prefer /, "Prefers ").replace(/^I use /, "Uses "); } @@ -311,6 +366,90 @@ describe("memory plugin storage", () => { }); }); + it("extracts and stores accepted memories from observed turns", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: "Prefers QA notes that mention database row checks.", + target: "requester", + }, + { + content: "Deploy runbooks live in Notion.", + target: "conversation", + }, + ]); + const embedder = createTestEmbedder(); + + await observeMemoryTurn( + observationContext({ + assistantText: "I will keep that in mind.", + db: memoryDb(fixture), + embedder, + model, + userText: + "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", + }), + ); + + expect(calls).toHaveLength(1); + const rows = await memoryDb(fixture) + .select() + .from(memorySqlSchema.juniorMemoryMemories) + .orderBy(memorySqlSchema.juniorMemoryMemories.createdAtMs); + expect(rows).toEqual([ + expect.objectContaining({ + content: "Prefers QA notes that mention database row checks.", + scope: "personal", + sourcePlatform: "local", + subjectType: "user", + }), + expect.objectContaining({ + content: "Deploy runbooks live in Notion.", + scope: "conversation", + sourcePlatform: "local", + subjectType: "conversation", + }), + ]); + expect(embedder.calls).toEqual([ + ["Prefers QA notes that mention database row checks."], + ["Deploy runbooks live in Notion."], + ]); + } finally { + await fixture.close(); + } + }, 15_000); + + it("skips passive extraction for memory tool turns", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: "Prefers duplicate memory avoidance.", + target: "requester", + }, + ]); + + await observeMemoryTurn( + observationContext({ + db: memoryDb(fixture), + model, + toolCalls: ["searchMemories"], + userText: "Remember that I prefer duplicate memory avoidance.", + }), + ); + + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } + }, 15_000); + it("persists, recalls, and archives visible memories", async () => { const fixture = await createMemoryFixture(); diff --git a/packages/junior-plugin-api/src/hooks.ts b/packages/junior-plugin-api/src/hooks.ts index ba8c8d60b..85e3440e9 100644 --- a/packages/junior-plugin-api/src/hooks.ts +++ b/packages/junior-plugin-api/src/hooks.ts @@ -30,6 +30,7 @@ import type { SystemPromptContext, UserPromptContext, } from "./prompt"; +import type { TurnObservationContext } from "./observation"; export interface PluginHooks { systemPrompt?( @@ -38,6 +39,7 @@ export interface PluginHooks { userPrompt?( ctx: UserPromptContext, ): Promise | PromptMessage[] | undefined; + observeTurn?(ctx: TurnObservationContext): Promise | void; beforeToolExecute?(ctx: BeforeToolExecuteHookContext): Promise | void; grantForEgress?( ctx: EgressHookContext, diff --git a/packages/junior-plugin-api/src/index.ts b/packages/junior-plugin-api/src/index.ts index b18e7b5ab..645c9eb04 100644 --- a/packages/junior-plugin-api/src/index.ts +++ b/packages/junior-plugin-api/src/index.ts @@ -8,6 +8,7 @@ export { type UserPromptContext, } from "./prompt"; export * from "./dispatch"; +export * from "./observation"; export * from "./tools"; export * from "./operations"; export * from "./credentials"; diff --git a/packages/junior-plugin-api/src/observation.ts b/packages/junior-plugin-api/src/observation.ts new file mode 100644 index 000000000..777478f0a --- /dev/null +++ b/packages/junior-plugin-api/src/observation.ts @@ -0,0 +1,27 @@ +import type { + Destination, + PluginContext, + PluginEmbedder, + PluginModel, + Requester, + Source, +} from "./context"; +import type { PluginState } from "./state"; + +/** Delivered turn text and runtime context available to post-turn plugin hooks. */ +export interface TurnObservationContext extends Pick< + PluginContext, + "db" | "log" | "plugin" +> { + assistantText: string; + conversationId?: string; + destination?: Destination; + embedder: PluginEmbedder; + model: PluginModel; + requester?: Requester; + source: Source; + state: PluginState; + toolCalls: string[]; + turnId: string; + userText: string; +} diff --git a/packages/junior/src/chat/local/runner.ts b/packages/junior/src/chat/local/runner.ts index 94a7a0069..477e60164 100644 --- a/packages/junior/src/chat/local/runner.ts +++ b/packages/junior/src/chat/local/runner.ts @@ -16,6 +16,7 @@ import { type LocalDestination, } from "@sentry/junior-plugin-api"; import { logException } from "@/chat/logging"; +import { observePluginTurn } from "@/chat/plugins/agent-hooks"; import { processPluginTask, scheduleSessionCompletedPluginTasks, @@ -376,6 +377,23 @@ export async function runLocalAgentTurn( "Local plugin session.completed task failed after reply delivery", ); } + await observePluginTurn({ + assistantText: reply.text, + toolCalls: reply.diagnostics.toolCalls, + turnId, + context: { + conversationId: input.conversationId, + destination, + requester: { + fullName: "Local CLI", + platform: "local", + userId: "local-cli", + userName: "local", + }, + source: destination, + userText: text, + }, + }); } return { diff --git a/packages/junior/src/chat/plugins/agent-hooks.ts b/packages/junior/src/chat/plugins/agent-hooks.ts index f83511f04..7e7a80a40 100644 --- a/packages/junior/src/chat/plugins/agent-hooks.ts +++ b/packages/junior/src/chat/plugins/agent-hooks.ts @@ -11,6 +11,7 @@ import type { SlackConversationLink, PluginRegistration, SlackToolRegistrationHookContext, + TurnObservationContext, UserPromptContext, } from "@sentry/junior-plugin-api"; import { getDb } from "@/chat/db"; @@ -139,6 +140,50 @@ function invocationPluginContext( }; } +function observationPluginContext( + plugin: PluginRegistration, + context: Pick< + ToolRuntimeContext, + "conversationId" | "destination" | "requester" | "source" | "userText" + > & { assistantText: string; toolCalls: string[]; turnId: string }, +): TurnObservationContext { + const base = basePluginContext(plugin); + const common = { + ...base, + assistantText: context.assistantText, + embedder: createPluginEmbedder(plugin.manifest.name), + model: createPluginModel(plugin.manifest.name), + source: context.source, + state: createPluginState(plugin.manifest.name), + toolCalls: [...context.toolCalls], + turnId: context.turnId, + userText: context.userText ?? "", + ...(context.conversationId + ? { conversationId: context.conversationId } + : {}), + }; + if (context.source.platform === "slack") { + return { + ...common, + requester: + context.requester?.platform === "slack" ? context.requester : undefined, + destination: + context.destination?.platform === "slack" + ? context.destination + : undefined, + }; + } + return { + ...common, + requester: + context.requester?.platform === "local" ? context.requester : undefined, + destination: + context.destination?.platform === "local" + ? context.destination + : undefined, + }; +} + function safeErrorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error); } @@ -441,6 +486,45 @@ export function getPluginTools( return tools; } +/** Let plugins inspect a successfully delivered turn without affecting delivery. */ +export async function observePluginTurn(args: { + assistantText: string; + toolCalls: string[]; + turnId: string; + context: Pick< + ToolRuntimeContext, + "conversationId" | "destination" | "requester" | "source" | "userText" + >; +}): Promise { + for (const plugin of getPlugins()) { + const pluginName = plugin.manifest.name; + const hook = plugin.hooks?.observeTurn; + if (!hook) { + continue; + } + try { + await hook( + observationPluginContext(plugin, { + ...args.context, + assistantText: args.assistantText, + toolCalls: args.toolCalls, + turnId: args.turnId, + }), + ); + } catch (error) { + logWarn( + "plugin_turn_observation_hook_failed", + {}, + { + "app.plugin.name": pluginName, + "exception.message": safeErrorMessage(error), + }, + "Plugin turn observation hook failed", + ); + } + } +} + /** Normalize route methods so JS plugins cannot register invalid verbs. */ function routeMethods( route: PluginRoute, diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 52fce4a58..1127dd6ff 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -9,6 +9,7 @@ import type { Message, SentMessage, Thread } from "chat"; import type { SlackAdapter } from "@chat-adapter/slack"; import { createSlackSource, type Destination } from "@sentry/junior-plugin-api"; +import { observePluginTurn } from "@/chat/plugins/agent-hooks"; import { botConfig } from "@/chat/config"; import { getSlackMessageTs } from "@/chat/slack/message"; import { @@ -1069,6 +1070,26 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { traceId: getActiveTraceId(), }); } + if (reply.diagnostics.outcome === "success") { + await observePluginTurn({ + assistantText: reply.text, + toolCalls: reply.diagnostics.toolCalls, + turnId, + context: { + ...(conversationId ? { conversationId } : {}), + destination, + requester: requesterIdentity, + source: { + platform: "slack", + teamId: destination.teamId, + channelId: destination.channelId, + ...(messageTs ? { messageTs } : {}), + ...(threadTs ? { threadTs } : {}), + }, + userText: effectiveUserText, + }, + }); + } preparedState.conversation = completedState.conversation; persistedAtLeastOnce = true; if (shouldEmitDevAgentTrace()) { diff --git a/packages/junior/tests/unit/plugins/agent-hooks.test.ts b/packages/junior/tests/unit/plugins/agent-hooks.test.ts index 11e7db73b..6c5006b7b 100644 --- a/packages/junior/tests/unit/plugins/agent-hooks.test.ts +++ b/packages/junior/tests/unit/plugins/agent-hooks.test.ts @@ -14,6 +14,7 @@ import { getPluginRoutes, getPluginSlackConversationLink, getPluginTools, + observePluginTurn, setPlugins, } from "@/chat/plugins/agent-hooks"; import { createTools } from "@/chat/tools"; @@ -333,6 +334,74 @@ describe("agent plugin hooks", () => { } }); + it("observes delivered turns with scoped plugin context", async () => { + const observed: unknown[] = []; + const previous = setPlugins([ + defineJuniorPlugin({ + manifest: { + name: "agent-demo", + displayName: "Agent Demo", + description: "Agent demo", + }, + hooks: { + observeTurn(ctx) { + observed.push({ + assistantText: ctx.assistantText, + conversationId: ctx.conversationId, + destination: ctx.destination, + hasEmbedder: typeof ctx.embedder.embedTexts === "function", + hasModel: typeof ctx.model.completeObject === "function", + requester: ctx.requester, + source: ctx.source, + toolCalls: ctx.toolCalls, + turnId: ctx.turnId, + userText: ctx.userText, + }); + }, + }, + }), + ]); + try { + await observePluginTurn({ + assistantText: "Stored.", + toolCalls: ["createMemory"], + turnId: "turn-1", + context: { + conversationId: "conversation-1", + destination: SLACK_DESTINATION, + requester: TEST_REQUESTER, + source: { + ...SLACK_DESTINATION, + messageTs: "1718800000.000000", + threadTs: "1718800000.000000", + }, + userText: "remember this", + }, + }); + + expect(observed).toEqual([ + { + assistantText: "Stored.", + conversationId: "conversation-1", + destination: SLACK_DESTINATION, + hasEmbedder: true, + hasModel: true, + requester: TEST_REQUESTER, + source: { + ...SLACK_DESTINATION, + messageTs: "1718800000.000000", + threadTs: "1718800000.000000", + }, + toolCalls: ["createMemory"], + turnId: "turn-1", + userText: "remember this", + }, + ]); + } finally { + setPlugins(previous); + } + }); + it("collects turn-scoped tools from configured plugins", () => { const previous = setPlugins([ defineJuniorPlugin({ diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 80aca5725..9507b60b1 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -3,12 +3,12 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose -Define passive memory learning through completed-session plugin background -tasks. +Define passive memory learning through completed-turn observation and the +memory-owned internal extraction agent. ## What Belongs In Memory @@ -60,76 +60,40 @@ Examples that must not be stored: ## Passive Learning -The memory plugin learns passively from its `extractMemories` -`session.completed` plugin background task. Junior core schedules registered -plugin tasks after successful completed sessions; the memory plugin owns the -memory-specific decision about whether that completed session is learnable. +The memory plugin observes completed turns through `observeTurn(ctx)`. -Core scheduling must: +The observation hook must: 1. Run only after the user-visible turn is durably committed enough that - scheduling failure cannot fail delivery. -2. Enqueue the registered `extractMemories` plugin background task for the - completed session. -3. Use a stable task id derived from the plugin, task name, and - completed-session reference. - -The task params must contain stable references and safe metadata only. They must -not contain raw private user text, raw assistant text, raw tool payloads, -credentials, or tokens. Core owns how the task is delivered through the generic -plugin background task contract. - -Core must not require plugin code to know queue topic names, queue message -shape, Vercel-specific APIs, callback routes, visibility timeouts, or -acknowledgement semantics. - -## Extraction Task Handler - -The memory plugin's `extractMemories` task handler must: - -1. Reload the bounded completed-session projection through - `ctx.session.load()`. -2. Reload current install-level memory policy. -3. Skip extraction when passive extraction is disabled, the source is not - learnable, the source is private, the source conversation is not classified - as public by Junior's existing conversation privacy/destination visibility - contracts, or the bounded session projection is unavailable, expired, - malformed, or no longer visible to the plugin. -4. Process only that completed turn. + observation failure cannot fail delivery. +2. Invoke the memory-owned extraction agent with bounded user-authored turn + text. +3. Ignore assistant-authored claims as memory sources. +4. Skip passive extraction when the completed turn already called + `createMemory`; the explicit tool path owns that memory write. 5. Extract candidate facts with a structured model output contract. -6. Ignore assistant-authored claims as memory sources. -7. Run memory agent review for extracted candidates. -8. Reject malformed, low-confidence, incoherent, semantically duplicative, - unsafe, or out-of-scope facts. -9. Reject facts disallowed by install policy, including non-public or - workplace-sensitive categories. -10. Convert relative times to absolute dates using `observed_at`. -11. Assign type, subject, scope, and optional expiration. -12. Run centralized secret detection immediately before writing memory rows. -13. Insert accepted memories transactionally. -14. Generate or queue embeddings for accepted rows when configured and allowed - by policy. -15. Archive expired, superseded, or explicitly removed memories in bounded - batches. -16. Avoid storing raw extraction prompt, raw model output, or raw turn text +6. Reject malformed, incoherent, unsafe, out-of-scope, or non-durable facts. +7. Assign requester or conversation target from memory-agent output, while + deriving all authority-bearing ids from runtime context. +8. Insert accepted memories idempotently with a stable key derived from the + source, turn id, and extracted fact position. +9. Generate embeddings for accepted rows when the host embedder is configured. +10. Avoid storing raw extraction prompt, raw model output, or raw turn text beyond the accepted memory records. -Extraction tasks must be idempotent. If the same completed turn is observed or -delivered more than once, source idempotency fields must prevent duplicate -memory writes. Semantic duplicate detection belongs in the extractor and -retrieval pipeline, not exact-content storage identity. +Observation hooks are best effort. If extraction or storage fails, Junior logs +safe metadata and the completed user-visible turn remains successful. -The task handler must be safe to run in a separate serverless invocation from -the original user turn. It must not depend on process memory, live Slack -clients, raw HTTP requests, provider tokens, or the model-visible prompt object -from the original run. +Queued extraction can be added later as a scaling option. If added, queue +payloads must contain stable references and safe metadata only; they must not +become the authority for private conversation text. ## Extraction Rules Extraction must follow these rules: 1. Extract only from user-authored text. -2. Prefer explicit "remember" requests over inferred passive learning. +2. Prefer explicit `createMemory` tool writes over inferred passive learning. 3. Store facts, not conversation summaries. 4. Make content self-contained and perspective-neutral. 5. Reject unresolved references such as "that", "it", "the thing", "someone", @@ -138,25 +102,22 @@ Extraction must follow these rules: 7. Reject assistant/system implementation details. 8. Reject low-utility facts that will not help 30 days later unless they have explicit expiration. -9. Assign `context`, `event`, `task`, or `observation` for facts that should - decay. -10. Treat extraction confidence below the configured threshold as not stored. -11. Reject workplace-sensitive categories disallowed by install policy, such as - HR/performance, protected-class, health, legal, financial, gossip, or - coworker speculation. -12. Reject private or sensitive content instead of storing it under personal +9. Reject workplace-sensitive categories, such as + HR/performance, protected-class, health, legal, financial, gossip, or + coworker speculation. +10. Reject private or sensitive content instead of storing it under personal scope. -13. In V1 passive extraction, prefer conversation-scoped operational knowledge - over personal memory. -14. Personal-scoped memories must be public/shareable first-person facts from +11. In V1 passive extraction, prefer conversation-scoped operational knowledge + over personal memory unless the user makes a clear first-person statement. +12. Personal-scoped memories must be public/shareable first-person facts from the current author/requester. -15. Assign `user` subject only for the current author/requester; do not create +13. Assign `user` subject only for the current author/requester; do not create third-party user subjects in V1. -16. Preserve provenance for third-party claims when the source matters for +14. Preserve provenance for third-party claims when the source matters for correctness. -17. Store the minimum useful assertion rather than a direct quote or broad +15. Store the minimum useful assertion rather than a direct quote or broad summary. -18. Store ownership, subject, and provenance in structured fields, not content +16. Store ownership, subject, and provenance in structured fields, not content prose. Remove requester names, display names, `the requester`, `the user`, `I`, `my`, thread labels, channel labels, and source labels from accepted content. @@ -174,32 +135,34 @@ belong to the memory agent rather than a caller-provided policy hook. The default V1 passive-extraction shape is: 1. The memory agent proposes structured candidate memories from the bounded - completed-session task projection. -2. The memory agent reviews each candidate against the installed memory policy - and workplace guidance. + observation payload. +2. The memory agent accepts only candidates that satisfy public/shareable memory + guidance. 3. Deterministic validation applies only hard structural rules, such as schema shape, runtime-owned authority, source visibility, lifecycle bounds, idempotency, and storage constraints before storage. -Memory agent review should receive only the candidate memory, the minimum -source context needed to judge it, and the installed policy guidance. It should -not receive unrestricted transcript history, raw tool payloads, provider -credentials, or unrelated conversation context unless those fields are part of -the bounded extraction input. Prompt inputs should use the same structured -context-block style as Junior's turn context, with separate `` and -`` blocks. Explicit `createMemory` review uses a singular +Memory agent review should receive only the candidate memory or completed +user-authored text, the minimum source context needed to judge it, and +public/shareable memory guidance. It should not receive unrestricted transcript +history, raw tool +payloads, provider credentials, or unrelated conversation context unless those +fields are part of the bounded extraction input. Prompt inputs should use the +same structured context-block style as Junior's turn context, with separate +`` and source blocks. Explicit `createMemory` review uses a singular `` block and the current user-authored message as bounded source -context. Passive extraction may add bounded prior-thread context, such as -compacted thread context or selected user-authored messages, inside the same -`` block and batch proposed facts inside ``. +context. Passive extraction uses only the completed turn's user-authored text. -Memory agent review output must be structured. It should include: +Memory agent output must be structured. For explicit review it should include: -- candidate id - decision: `store` or `reject` - normalized rejection reason code when rejected - optional adjusted memory type, subject, scope, expiration, or content rewrite +For passive extraction it should include an array of accepted candidate +memories with target, canonical content, and optional expiration. Rejections are +represented by omitting a candidate from the array. + The structured content field is the canonical stored memory text. The memory agent must use that field to return perspective-neutral fact text. For example, `I prefer terse PR summaries` should become `Prefers terse PR summaries`, and @@ -246,7 +209,7 @@ a model-visible rejection, not storage with a special classification. Duplicate prevention is required before insertion where the relevant signal is available: -- same source observation id and same extracted fact index +- same source, turn id, and extracted fact index - high lexical or embedding similarity to an active memory in the same scope V1 storage enforces source/fact idempotency. Exact normalized-content equality diff --git a/specs/memory-plugin/index.md b/specs/memory-plugin/index.md index 6f9dc85f2..32da287d2 100644 --- a/specs/memory-plugin/index.md +++ b/specs/memory-plugin/index.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose @@ -15,8 +15,10 @@ contracts. This spec describes the intended V1 memory plugin shape. Generic plugin prompt hooks and plugin prompt session state are available through -`../plugin-prompt-hooks.md`. Passive learning runs through plugin background -tasks defined in `../plugin-tasks.md`. +`../plugin-prompt-hooks.md`. Passive learning uses the implemented +`observeTurn` hook and the memory-owned internal extraction agent. Plugin +background task handlers remain a future scaling option, not the current V1 +contract. V1 stores only public/shareable memory content. Scope controls who can see a record; it is not a content sensitivity model. Private, sensitive, secret, or @@ -35,7 +37,7 @@ Explicit tools also support user-directed memory management. - Plugin-owned SQL storage, retrieval indexes, embeddings, and model-provider boundaries. - Automatic recall through `userPrompt` when the memory plugin is enabled. -- Passive learning through a plugin background task handler. +- Passive learning through `observeTurn`. - Explicit `createMemory`, `removeMemory`, `listMemories`, and `searchMemories` tools. - Scope, attribution, lifecycle, tool, model, public-content, and secret @@ -70,7 +72,7 @@ Read these files as one canonical spec: model/tool boundaries, task payload safety, and redaction rules. - [retrieval.md](./retrieval.md): automatic recall, tool-mediated recall, hybrid ranking, automatic injection mechanics, and performance strategy. -- [extraction.md](./extraction.md): passive completed-session extraction, +- [extraction.md](./extraction.md): passive observation, extraction, storable-fact policy, semantic duplicate detection, and supersession. - [tools.md](./tools.md): model-visible memory management and recall tools. - [admin.md](./admin.md): future operator/admin CLI command shape for memory @@ -126,8 +128,8 @@ External storage and retrieval assumptions are based on primary documentation: ## Plugin Shape -The V1 memory implementation is a plugin registered through -`defineJuniorPlugin({ manifest, hooks, tasks })`. +The V1 memory implementation is a trusted host plugin registered through +`defineJuniorPlugin({ manifest, hooks })`. The plugin uses the package name and plugin name `memory`. Plugin database tables use the prefix: @@ -143,35 +145,26 @@ defineJuniorPlugin({ manifest, hooks: { userPrompt, + observeTurn, tools, }, - tasks: { - extractMemories, - }, }); ``` -Embedding generation and repair are part of the memory store/extraction path in -V1. A separately queued embedding repair task should wait until the plugin task -contract supports a real non-session trigger. - -The exact hook and task type names are owned by their generic plugin specs. The -memory plugin needs these broad V1 surfaces: automatic recall when the plugin is -enabled, completed-session background task handling, model-visible -memory tools, SQL access, and host-owned embedding-provider access. A future -admin CLI surface is specified separately in [`./admin.md`](./admin.md). +The exact hook names are owned by their generic plugin specs. The memory plugin +needs these broad V1 surfaces: automatic recall when the plugin is enabled, +completed-turn observation, model-visible memory tools, SQL access, and +host-owned model and embedding-provider access. A future admin CLI surface is +specified separately in [`./admin.md`](./admin.md). -The plugin must also receive install-level memory policy before hooks execute. -Policy controls whether passive extraction is enabled, what categories and -scopes may be stored, which providers may receive memory text, and which -retention defaults apply. Installations that do not want automatic memory recall -should disable the memory plugin rather than split recall from the plugin. +Installations that do not want memory should disable the memory plugin rather +than split recall from the plugin. Future install-level memory policy may narrow +passive extraction, stored categories, providers, and retention defaults. -V1 passive extraction targets workplace knowledge from conversations classified -as `public` by Junior's existing conversation privacy/destination visibility -contracts. Private, direct, unknown, or unsupported sources can still use -explicit memory tools for public/shareable memories when policy allows them, -but passive learning from those sources is out of scope for V1. +V1 passive extraction targets public/shareable, durable facts from supported +runtime contexts. Local CLI contexts are valid passive-learning sources for +development and QA. Private, sensitive, secret, or otherwise restricted facts +are rejected rather than stored. V1 uses the default extraction guidance in `policy.md`. Install-provided extraction guidelines are out of scope for V1. @@ -182,9 +175,8 @@ The plugin owns: - generated SQL migrations under `migrations/*.sql` - a small memory store module around `ctx.db` - extraction and retrieval policy -- install-level memory policy evaluation -- the `extractMemories` task handler and embedding repair inside the memory - store/extraction path +- memory policy guidance inside the memory agent +- passive extraction through `observeTurn` - memory tool definitions - future memory admin command definitions @@ -194,7 +186,6 @@ Core owns: - prompt rendering and size limits - database migration application - runtime identity, source, and destination context -- plugin task enqueueing, retry, redelivery, and worker execution - model and embedding provider credential custody - tool schema validation and tool execution boundaries - plugin config loading @@ -324,20 +315,18 @@ be exported as part of Junior core. The V1 contract has these implementation dependencies: -1. Core plugin surfaces needed by this spec: `userPrompt`, - plugin background tasks, `tools`, `ctx.db`, host embedding provider access, - and plugin config/policy access. The explicit memory tool path also needs - the tool-hook `ctx.model` review capability. +1. Core plugin hook surfaces needed by this spec: `userPrompt`, `observeTurn`, + `tools`, `ctx.db`, host model access, and host embedding provider access. 2. Memory plugin package with manifest, schema, migrations, store, and - install-level policy evaluator. + memory agent policy guidance. 3. Explicit `createMemory`, `listMemories`, `searchMemories`, and `removeMemory` tools with context-bound authority. `createMemory` submits a candidate memory; the memory agent uses the tool-hook model capability to own subject and scope decisions. 4. Automatic recall from stored memories through `userPrompt`, using lexical ranking before embeddings are available. -5. Embedding provider integration, vector storage, and embedding repair tasks. -6. `session.completed` task scheduling and `extractMemories` task execution. +5. Embedding provider integration and vector storage. +6. `observeTurn` passive extraction over completed turns. 7. Deduplication, TTL archival, and conservative supersession. 8. Optional vector index tuning and hybrid ranking improvements. 9. Admin CLI inspection and repair commands after redaction and access diff --git a/specs/memory-plugin/policy.md b/specs/memory-plugin/policy.md index 11607abe4..3c7f93931 100644 --- a/specs/memory-plugin/policy.md +++ b/specs/memory-plugin/policy.md @@ -3,18 +3,18 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose -Define install-level memory policy controls, with specific attention to -workplace deployments where passive memory can create privacy, trust, and -compliance risks. +Define V1 memory policy guidance, with specific attention to workplace +deployments where passive memory can create privacy, trust, and compliance +risks. ## Scope -- What must be tunable by the installing app or workspace. -- V1 passive extraction toggle and default extraction guidance. +- Current V1 default extraction guidance. +- Future install-level policy controls for the installing app or workspace. - Default workplace extraction guidance. - Public-memory eligibility and workplace-sensitive rejection categories. - How policy affects tools, passive extraction, retrieval, retention, models, @@ -29,69 +29,42 @@ compliance risks. ## Policy Model -The memory plugin must evaluate an install-level policy before writing, -recalling, embedding, or displaying memory. - -Policy should be resolved from explicit plugin configuration and runtime -context. The model may not change policy through prompt text or tool arguments. - -V1 needs only a small required policy surface: - -- passive extraction toggle - -The V1 config shape is: - -```ts -interface MemoryPolicy { - passiveExtraction: boolean; -} -``` - Plugin enablement is controlled by the normal plugin registration path. If an install does not want memory at all, it should not enable the memory plugin. -V1 uses the default workplace guidance in this spec. Configurable extraction -guidelines are a future extension. The memory agent owns semantic memory -decisions, including public/shareable eligibility and workplace-sensitive -rejection. Deterministic code enforces structural hard rules: +V1 uses the default workplace guidance in this spec. Configurable install-level +policy and extraction guidelines are future extensions. The memory agent owns +semantic memory decisions, including public/shareable eligibility and +workplace-sensitive rejection. Deterministic code enforces structural hard +rules: - runtime-derived scope only -- source visibility checks -- `public` conversation visibility for passive capture only in V1 -- policy toggle checks -- provider allowlist checks - no raw transcript storage - redaction and logging restrictions -Memory policy must be loaded before hooks run and must be available to -extraction, tools, retrieval, storage, and admin code. +The model may not change memory policy through prompt text or tool arguments. ## Conservative Defaults Workplace-safe defaults should be conservative: -1. `passiveExtraction` defaults to `false`. -2. If passive extraction is enabled in V1, it learns only allowed workplace - knowledge from conversations classified as `public`. -3. Automatic memory injection is enabled when the memory plugin is enabled. -4. Passive extraction from conversations classified as `direct`, `private`, - `unknown`, or unsupported is out of scope for V1. -5. V1 does not store private or sensitive memory content, even in personal +1. Automatic memory injection is enabled when the memory plugin is enabled. +2. Passive extraction is enabled when the memory plugin is enabled. +3. V1 does not store private or sensitive memory content, even in personal scope. -6. Third-party personal facts about coworkers should not be passively stored by +4. Third-party personal facts about coworkers should not be passively stored by default. -7. Retention should prefer shorter TTLs for `context`, `event`, `task`, and +5. Retention should prefer shorter TTLs for `context`, `event`, `task`, and `observation` memories. -8. Default admin output should be redacted. +6. Default admin output should be redacted. -An install can choose whether to enable passive extraction, but automatic recall -is part of enabling the memory plugin. V1 does not expose broader extraction -behaviors. +An install chooses whether to enable memory through plugin registration. V1 does +not expose broader extraction behaviors. ## Default Workplace Guidelines -When `passiveExtraction` is `true`, the extractor should look for clean -workplace knowledge from conversations classified as `public`. +When the memory plugin is enabled, the passive extractor should look for clean +public/shareable knowledge from supported runtime contexts. Aim to extract: @@ -124,8 +97,7 @@ canonical text such as `Prefers terse code reviews`. Future configurable extraction guidelines may narrow or redirect what the model looks for, such as "only remember repository conventions and product decisions." They are not part of V1, and when added they must not override hard -validators or allow passive extraction from non-public or otherwise disallowed -sources. +validators or public/shareable-content rules. ## Third-Party Facts @@ -200,8 +172,8 @@ memory; it does not authorize storage of non-public content. ## Passive Extraction Policy -Passive extraction must use policy as an input before model prompting and again -after structured extraction output. +Passive extraction must use this policy guidance in the memory agent prompt and +again when validating structured extraction output. The extraction prompt may describe allowed categories for quality. Policy enforcement should happen through memory agent review after extraction proposes @@ -209,18 +181,7 @@ candidate facts. Deterministic validation remains the final enforcement point for structural rules such as runtime-derived authority, strict schemas, source visibility, provider allowlists, and lifecycle bounds. -`passiveExtraction` is a boolean: - -| Value | Meaning | -| ------- | ----------------------------------------------------------------------- | -| `false` | Do not enqueue passive extraction tasks. | -| `true` | Learn allowed workplace knowledge from public conversations only in V1. | - -Explicit-only memory creation is not a passive extraction setting. It is the -normal tool path: when `passiveExtraction` is `false`, the only way to write -memory is through explicit tools such as `createMemory`. - -When `passiveExtraction` is `true`, policy allows passive extraction of: +Policy allows passive extraction of: - explicitly requested durable user preferences about Junior's behavior - durable project or repository facts @@ -239,14 +200,13 @@ Policy still disallows passive extraction by category, including: For V1, passive extraction should store conversation-scoped operational knowledge by default. Passive personal memory from public conversations requires -explicit remember language from the source user and must still be visible only -to that requester. +clear first-person source evidence from the user and must still be visible only +to that requester. Explicit `createMemory` tool calls remain the stronger write +signal and suppress passive duplicate writes for the same completed turn. ## Automatic Injection Policy -Automatic memory injection is enabled when the memory plugin is enabled. It is -independent from passive extraction: the plugin may inject stored memories even -when `passiveExtraction` is `false`. +Automatic memory injection is enabled when the memory plugin is enabled. `searchMemories` remains the explicit model-visible recall path. It applies the same visibility, policy, ranking, and redaction rules as automatic memory @@ -254,19 +214,18 @@ injection. ## Explicit Tools And Policy -Explicit memory creation requests are still subject to install policy. +Explicit memory creation requests are still subject to memory policy guidance. -For example, passive extraction is limited to public-conversation workplace -knowledge in V1, but users may still explicitly store public/shareable personal -preferences about themselves when the requested memory passes policy. -This includes ordinary technical and workplace preferences or opinions, such -as language, tool, repository, product, communication, and workflow -preferences, when they are authored by the current requester and do not include -private or sensitive content. +Users may explicitly store public/shareable personal preferences about +themselves when the requested memory passes policy. This includes ordinary +technical and workplace preferences or opinions, such as language, tool, +repository, product, communication, and workflow preferences, when they are +authored by the current requester and do not include private or sensitive +content. The explicit tool path must use the same agentic policy guidance as passive extraction. Explicit user intent can make a fact eligible for storage under -install policy, but it cannot override secret rejection, source/scope rules, +memory policy, but it cannot override secret rejection, source/scope rules, workplace-sensitive category rejection, public-content restrictions, provider and embedding policy, or retention and lifecycle policy. @@ -291,9 +250,10 @@ asks for them. ## Model And Provider Policy -Some installs may restrict which providers can receive memory-related text. +Future install policy may restrict which providers can receive memory-related +text. -Host provider configuration must support disabling: +Host provider configuration should support disabling or narrowing: - passive extraction model calls - embedding model calls diff --git a/specs/memory-plugin/retrieval.md b/specs/memory-plugin/retrieval.md index 33427c4c6..7f1e18b53 100644 --- a/specs/memory-plugin/retrieval.md +++ b/specs/memory-plugin/retrieval.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose @@ -57,7 +57,8 @@ Retrieval must filter by visibility before prompt rendering: - matching personal requester scope - matching conversation scope -- current install policy allows recall for the memory type, scope, and source +- future install policy allows recall for the memory type, scope, and source + when that policy surface exists - `archived_at is null` - `superseded_at is null` - `expires_at is null or expires_at > now()` @@ -65,10 +66,10 @@ Retrieval must filter by visibility before prompt rendering: The query planner, vector index, model, and ranker are not authorization boundaries. -If install policy changes after a memory was created, retrieval must apply the -current policy. Stricter current policy hides the memory from automatic memory -injection and normal list/search results even if the stored row is otherwise -visible. +If future install policy changes after a memory was created, retrieval must +apply the current policy. Stricter current policy hides the memory from +automatic memory injection and normal list/search results even if the stored row +is otherwise visible. ### Ranking Pipeline diff --git a/specs/memory-plugin/security.md b/specs/memory-plugin/security.md index 5b0ca762e..c0b893ccb 100644 --- a/specs/memory-plugin/security.md +++ b/specs/memory-plugin/security.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose @@ -22,8 +22,8 @@ model calls, embeddings, logging, and multi-user visibility. 6. Embeddings and lexical indexes are derived data and cannot grant visibility. 7. Provider credentials never enter plugin storage, prompt contributions, tool schemas, task payloads, logs, or model-visible content. -8. Observation/task payloads use stable references and bounded safe metadata, - not raw private transcript text. +8. Observation hooks use bounded completed-turn text and do not store raw + transcript text. 9. Every write path uses the same policy, validation, and secret rejection layer. @@ -62,12 +62,11 @@ Conversation memory is visible only in the same conversation identity. V1 does not recall conversation memory across related channels, Slack workspaces, threads, projects, or rooms. -V1 passive extraction is limited to conversations classified as `public` by -Junior's existing conversation privacy/destination visibility contracts, and it -stores conversation-scoped workplace knowledge by default. Direct, private, -unknown, local CLI, and unsupported sources may still use explicit memory tools -when policy allows them, but they must not feed passive extraction. Visibility -classification must fail closed. +V1 passive extraction stores public/shareable memories only and prefers +conversation-scoped workplace knowledge by default. Local CLI is a supported +passive-learning source for development and QA. Direct, private, unknown, or +unsupported network sources need an explicit privacy contract before passive +learning is enabled there. Personal-scoped `user` subject memories may be created only by the current author/requester and must contain public/shareable first-person content. An @@ -101,8 +100,8 @@ reported, exported, retained, or exposed under weaker rules than memory content. ## Task Payloads -Plugin background task payloads must contain stable references and bounded safe -metadata only. +Future plugin background task payloads must contain stable references and +bounded safe metadata only. They must not contain: @@ -116,8 +115,8 @@ They must not contain: - memory content unless the task exists specifically to repair a memory id that can be reloaded from storage -Completed-session tasks should reload bounded task projections through -`ctx.session.load()`. +Future observation-backed tasks should reload bounded observation payloads +through the core-provided observation helper. ## Logging And Reporting diff --git a/specs/memory-plugin/storage.md b/specs/memory-plugin/storage.md index 6ab66dd5f..b96f4d2f9 100644 --- a/specs/memory-plugin/storage.md +++ b/specs/memory-plugin/storage.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose @@ -121,7 +121,7 @@ The store must be able to filter active visible records by: - scope - plugin-derived subject type -- current install policy +- future install policy, when that policy surface exists - archive state - supersession state - expiration diff --git a/specs/memory-plugin/tools.md b/specs/memory-plugin/tools.md index 6553001b4..2b64829e1 100644 --- a/specs/memory-plugin/tools.md +++ b/specs/memory-plugin/tools.md @@ -103,7 +103,8 @@ removing multiple rows. `listMemories` lists only active memories visible in the current context. It may accept an optional limit, but it must not search across unrelated users or -conversations. Current install policy must be applied before returning results. +conversations. Future install policy must be applied before returning results +when that policy surface exists. The tool may include ids or short ids because explicit removal workflows need a handle. Normal automatic memory injection should avoid ids. diff --git a/specs/memory-plugin/verification.md b/specs/memory-plugin/verification.md index 28093e988..12af01fb8 100644 --- a/specs/memory-plugin/verification.md +++ b/specs/memory-plugin/verification.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-20 +- Last Edited: 2026-06-22 ## Purpose @@ -25,17 +25,14 @@ requirements. 6. `userPrompt` retrieval failure: omit memory contribution, log safe metadata, and continue unless the failure indicates a broken required migration. 7. Prompt message validation failure: omit the prompt message. -8. Passive task scheduling failure: log safe metadata and do not fail the +8. `observeTurn` extraction failure: log safe metadata and do not fail the completed turn. -9. Task delivery failure: core retries according to the task runner policy. -10. Task retry bound exceeded or session projection expired: mark or drop the - task with safe metadata; do not fail the completed user turn. -11. Duplicate scheduling or duplicate task delivery: task idempotency and - source idempotency suppress duplicate stored memories. -12. Secret detection match: reject the write with a model-visible tool input +9. Duplicate post-turn observation: source idempotency suppresses duplicate + stored memories. +10. Secret detection match: reject the write with a model-visible tool input error for explicit tools or drop the passive fact with safe logging. -13. Visibility mismatch: fail closed and omit the memory. -14. Malformed stored rows: ignore the row for recall/list, log safe metadata, +11. Visibility mismatch: fail closed and omit the memory. +12. Malformed stored rows: ignore the row for recall/list, log safe metadata, and leave repair to a future administrative workflow. ## Observability @@ -86,13 +83,8 @@ Use integration tests for: requester/author - explicit personal memory rejects third-party user profile facts such as storing `David is xyz` on David's behalf -- explicit memory creation is rejected when it violates install policy or - workplace-sensitive category rules -- install policy can disable passive extraction without disabling explicit - memory tools -- install policy can reject workplace-sensitive passive facts -- stricter current policy hides previously stored memories from automatic memory - injection and list/search results +- explicit memory creation is rejected when it violates workplace-sensitive + category rules - `listMemories` returns only memories visible in the current context - `searchMemories` returns only relevant memories visible in the current context @@ -106,14 +98,14 @@ Use integration tests for: - embedding failures leave memories listable and lexically recallable - private conversation memory content is absent from logs, traces, and dashboard reporting payloads -- passive session completion schedules an extraction task without failing delivery -- extraction task params contain references rather than raw private text -- extraction task handlers can run in a separate worker invocation -- memory agent review rejects extracted candidates that violate installed - workplace policy +- passive `observeTurn` extracts from organic completed turns without failing + delivery +- passive extraction skips turns where explicit `createMemory` was already + called +- memory agent review rejects extracted candidates that violate workplace + guidance - malformed or failed memory agent review fails closed for passive extraction -- duplicate scheduling or task delivery of the same turn stores accepted - memories once +- duplicate observation of the same turn stores accepted memories once When the future admin CLI is implemented, use integration tests for: @@ -125,7 +117,7 @@ When the future admin CLI is implemented, use integration tests for: Use unit tests for: - memory type, scope, and subject parsers -- install policy parser and policy evaluation predicates +- future install policy parser and policy evaluation predicates - secret detection - storable-fact validation - explicit-tool policy filtering @@ -147,7 +139,7 @@ Use evals for: - refusal to remember secrets - explicit create rejection for policy-disallowed workplace-sensitive facts - refusal or policy rejection for workplace-sensitive facts -- passive extraction quality once the extraction task is implemented +- passive extraction quality for organic conversation - model use of current user corrections over stale memories ## Related Specs diff --git a/specs/plugin-prompt-hooks.md b/specs/plugin-prompt-hooks.md index 50c29b883..eb8309ac1 100644 --- a/specs/plugin-prompt-hooks.md +++ b/specs/plugin-prompt-hooks.md @@ -3,26 +3,28 @@ ## Metadata - Created: 2026-06-12 -- Last Edited: 2026-06-19 +- Last Edited: 2026-06-22 ## Purpose Define the generic plugin hooks that let runtime hook plugins contribute prompt -text without exposing raw Junior internals or creating memory-specific plugin -APIs. +text and observe completed turns without exposing raw Junior internals or +creating memory-specific plugin APIs. ## Implementation Status Plugin prompt hooks are implemented in Junior core and -`@sentry/junior-plugin-api`. Plugin background tasks are specified separately -in [Plugin Background Tasks Spec](./plugin-tasks.md). +`@sentry/junior-plugin-api`. Turn observation hooks are implemented as +post-delivery best-effort hooks. Plugin background task handlers remain target +design for a later implementation slice. ## Scope - Plugin-provided system prompt and user prompt contributions. - Prompt hook context. +- Post-turn observation hook contract for passive extraction workflows. - Security and rendering boundaries for prompt contributions. -- V1 memory plugin prompt-recall usage of these generic hooks. +- V1 memory plugin usage of these generic hooks. ## Non-Goals @@ -38,7 +40,7 @@ in [Plugin Background Tasks Spec](./plugin-tasks.md). ### Hook Surface -Runtime hook plugins may provide prompt hooks: +Runtime hook plugins may provide prompt and observation hooks: ```ts interface PluginHooks { @@ -49,12 +51,14 @@ interface PluginHooks { userPrompt?( ctx: UserPromptContext, ): PromptMessage[] | undefined | Promise; + + observeTurn?(ctx: TurnObservationContext): void | Promise; } ``` These hooks are app-code plugin hooks registered through `defineJuniorPlugin({ manifest, hooks })`. Declarative `plugin.yaml` manifests -must not register prompt hooks. +must not register prompt or observation hooks. ### Prompt Messages @@ -83,7 +87,7 @@ Rules: ```ts interface SystemPromptContext { - db: unknown; + db: object; log: PluginLogger; platform: Platform; plugin: PluginMetadata; @@ -135,7 +139,7 @@ Rules: ```ts interface UserPromptContext { conversationId?: string; - db: unknown; + db: object; destination?: Destination; embedder: PluginEmbedder; log: PluginLogger; @@ -157,17 +161,109 @@ The context must not expose: - cross-plugin state - model messages outside the safe hook-specific context +### Turn Observation Hook + +`observeTurn(ctx)` lets plugins inspect a completed turn and perform bounded +post-turn work such as passive memory extraction. + +Core invokes observation hooks only after final turn state is committed far +enough that the hook cannot affect whether the user-visible turn succeeds. + +Observation context should include: + +- requester, source, destination, and conversation id +- bounded user-visible turn text needed by the plugin: user text and assistant + text +- safe metadata about tool use +- plugin-scoped durable state and logger +- plugin-scoped model and embedding helpers + +The bounded observation payload is a runtime-owned projection, not a raw +transcript. Core may expose the same projection directly to `observeTurn(ctx)` +and later through `PluginTaskContext.observation.load()` for +observation-backed tasks. + +Observation hooks must not receive provider credentials, raw authorization URLs, +raw Slack clients, or unrestricted transcript history. For private +conversations, observation payloads must follow the same raw-payload restrictions +as runtime code: a plugin may receive private turn text only when it is an +explicitly enabled trusted host plugin whose contract requires that payload. + +Observation hooks must be best effort. A thrown observation error must be logged +with safe metadata and must not fail the already-completed user turn. + +### Plugin Background Tasks + +Future observation hooks may enqueue plugin-owned background tasks through a +core-owned task capability: + +```ts +interface PluginTaskEnqueueOptions { + idempotencyKey: string; + name: string; + payload?: unknown; +} + +interface PluginTaskEnqueueResult { + id: string; + status: "created" | "already_exists"; +} + +interface PluginTaskQueue { + enqueue(options: PluginTaskEnqueueOptions): Promise; +} + +interface PluginTaskContext extends PluginContext { + id: string; + name: string; + payload?: unknown; + observation?: { + load(): Promise; + }; +} + +type PluginTaskHandler = (ctx: PluginTaskContext) => Promise | void; +``` + +This task surface is not implemented yet. The exact host implementation is not +part of the plugin API. Core may run +plugin tasks with the existing queue infrastructure, a signed internal callback, +a future dedicated task worker, or a local in-process test worker. Plugin code +must observe the same contract in all cases. + +Task rules: + +1. Task names are resolved only inside the owning plugin. +2. Idempotency is scoped to plugin name and task name. +3. Task payloads must be bounded JSON-serializable data. +4. Task payloads should contain stable references and safe metadata, not raw + private prompt text, raw tool payloads, credentials, or tokens. +5. Task handlers run with plugin-scoped `ctx.db`, `ctx.state`, logger, and the + runtime-owned context needed by that task type. +6. Observation-backed tasks receive an `observation.load()` helper when core can + reconstruct a bounded observation payload from durable runtime state. +7. Task handlers must be idempotent because delivery is at least once. +8. Core owns queue acknowledgement, retry, redelivery, worker leases, callback + signing, and provider-specific visibility timeouts. +9. Plugins must not depend on task execution happening in the same process or + same request as `observeTurn`. + +For future queued memory extraction, the observation hook should enqueue a task with stable +conversation/session/message references. The task worker reloads the bounded +observation payload from durable runtime state before invoking the plugin task +handler. Queue payloads must not become the authority for private conversation +text. + ### Memory Plugin V1 Usage -The memory plugin should use the generic prompt hooks as follows: +The memory plugin should use the generic hooks as follows: 1. `userPrompt(ctx)` retrieves memories visible to the current requester and source, then returns a concise memory block for the run's triggering prompt. -2. `tools(ctx)` may expose explicit memory tools such as `createMemory`, +2. `observeTurn(ctx)` runs the memory-owned structured extraction agent over the + completed turn and writes accepted facts idempotently. +3. `tools(ctx)` may expose explicit memory tools such as `createMemory`, `removeMemory`, `listMemories`, and `searchMemories`. -3. Passive extraction uses plugin background tasks; see - [Plugin Background Tasks Spec](./plugin-tasks.md) and - [Memory Plugin Spec](./memory-plugin/index.md). Memory retrieval must not depend on the model choosing a search tool for default recall. `searchMemories` remains the explicit model-visible recall path for @@ -209,6 +305,8 @@ Core owns prompt rendering: and continue unless startup validation can catch the problem earlier. 2. Oversized contribution: truncate only if the contribution contract supports deterministic truncation; otherwise omit and log safe metadata. +3. Observation hook failure: log safe metadata and do not change the completed + turn result. ## Observability From 7c470df3d2c1f7be6c610cf48825cb743cfe2945 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 16:38:00 -0700 Subject: [PATCH 02/29] fix(memory): Tighten passive extraction boundaries Keep passive memory observation scoped to supported local and public Slack contexts, wire resumed Slack success through observation, and type observation contexts with platform-coupled runtime context. Remove the telemetry mock from resume behavior tests and align memory specs with the explicit-review and passive-extraction split. Co-Authored-By: GPT-5 Codex --- packages/junior-memory/src/observe.ts | 20 +- packages/junior-memory/src/plugin.ts | 7 +- packages/junior-memory/src/tools.ts | 4 +- packages/junior-memory/tests/storage.test.ts | 71 ++++++- packages/junior-plugin-api/src/observation.ts | 29 ++- .../junior/src/chat/plugins/agent-hooks.ts | 3 +- .../junior/src/chat/runtime/reply-executor.ts | 2 +- .../junior/src/chat/runtime/slack-resume.ts | 26 +++ .../tests/unit/handlers/oauth-resume.test.ts | 191 ++++++++++++++---- specs/memory-plugin/extraction.md | 21 +- specs/memory-plugin/index.md | 7 +- specs/memory-plugin/policy.md | 15 +- specs/memory-plugin/security.md | 4 +- specs/memory-plugin/storage.md | 4 +- specs/memory-plugin/tools.md | 8 +- 15 files changed, 311 insertions(+), 101 deletions(-) diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/observe.ts index 28c425c2c..cf4651bef 100644 --- a/packages/junior-memory/src/observe.ts +++ b/packages/junior-memory/src/observe.ts @@ -14,14 +14,22 @@ const MEMORY_TOOL_NAMES = new Set([ "searchMemories", ]); +function canPassivelyLearn(context: TurnObservationContext): boolean { + if (context.source.platform === "local") { + return true; + } + return Boolean( + context.source.channelId.startsWith("C") && + (context.source.threadTs ?? context.source.messageTs), + ); +} + function observationSourceKey(context: TurnObservationContext): string { if (context.source.platform === "local") { return context.source.conversationId; } const messageKey = context.source.threadTs ?? context.source.messageTs; - return `slack:${context.source.teamId}:${context.source.channelId}:${ - messageKey ?? context.turnId - }`; + return `slack:${context.source.teamId}:${context.source.channelId}:${messageKey}`; } function passiveInput( @@ -43,9 +51,11 @@ export async function observeMemoryTurn( if (context.toolCalls.some((toolName) => MEMORY_TOOL_NAMES.has(toolName))) { return; } + if (!canPassivelyLearn(context)) { + return; + } const userText = context.userText.trim(); - const assistantText = context.assistantText.trim(); - if (!userText || !assistantText) { + if (!userText) { return; } diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index cea451597..5a7681507 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -6,6 +6,7 @@ import { createMemoryListTool, createMemoryRemoveTool, createMemorySearchTool, + type MemoryReviewer, type MemoryToolContext, } from "./tools"; import { observeMemoryTurn } from "./observe"; @@ -13,7 +14,7 @@ import { createMemoryPromptMessages } from "./recall"; import type { MemoryDb } from "./store"; function memoryToolContext(ctx: { - agent: MemoryAgent; + agent: MemoryReviewer; conversationId?: string; db: MemoryToolContext["db"]; embedder?: MemoryToolContext["embedder"]; @@ -69,9 +70,7 @@ export function createMemoryPlugin() { text: ctx.text, }); }, - async observeTurn(ctx) { - await observeMemoryTurn(ctx); - }, + observeTurn: observeMemoryTurn, }, }); } diff --git a/packages/junior-memory/src/tools.ts b/packages/junior-memory/src/tools.ts index d04656321..ea67eccac 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior-memory/src/tools.ts @@ -20,6 +20,8 @@ import { } from "./agent"; import { memoryRuntimeContextSchema, type MemoryRuntimeContext } from "./types"; +export type MemoryReviewer = Pick; + const MAX_TOOL_CONTENT_CHARS = 4_000; const DEFAULT_RESULT_LIMIT = 20; const DEFAULT_SEARCH_LIMIT = 10; @@ -38,7 +40,7 @@ const KNOWN_TOOL_INPUT_ERROR_MESSAGES = new Set([ /** Runtime-owned context used to bind memory tools to visible scopes. */ export interface MemoryToolContext { - agent: MemoryAgent; + agent: MemoryReviewer; conversationId?: string; db: MemoryDb; embedder?: MemoryEmbeddingProvider; diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 85f78ef04..6f05ac9df 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -30,6 +30,7 @@ import { createMemoryListTool, createMemoryRemoveTool, createMemorySearchTool, + type MemoryReviewer, } from "../src/tools"; import { observeMemoryTurn } from "../src/observe"; import { createMemoryStore, type MemoryDb } from "../src/store"; @@ -282,7 +283,7 @@ function testCanonicalContent(content: string): string { function allowMemory( target: "requester" | "conversation", onRequest?: (request: CreateMemoryRequest) => void, -): MemoryAgent { +): MemoryReviewer { return { reviewCreateRequest(candidate) { onRequest?.(candidate); @@ -298,7 +299,7 @@ function allowMemory( }; } -const rejectMemory: MemoryAgent = { +const rejectMemory: MemoryReviewer = { reviewCreateRequest() { return { decision: "reject", @@ -450,6 +451,72 @@ describe("memory plugin storage", () => { } }, 15_000); + it("skips passive extraction in private Slack contexts", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: "Prefers private Slack context skips.", + target: "requester", + }, + ]); + const privateContext = slackContext({ channelId: "D123" }); + + await observeMemoryTurn( + observationContext({ + ...privateContext, + db: memoryDb(fixture), + model, + userText: "I prefer private Slack context skips.", + }), + ); + + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } + }, 15_000); + + it("skips passive extraction for Slack observations without a message key", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: "Prefers Slack message key validation.", + target: "requester", + }, + ]); + const runtime = slackContext(); + + await observeMemoryTurn( + observationContext({ + conversationId: "slack:C123:missing-message-key", + db: memoryDb(fixture), + model, + requester: runtime.requester, + source: { + platform: "slack", + teamId: runtime.source.teamId, + channelId: runtime.source.channelId, + }, + userText: "I prefer Slack message key validation.", + }), + ); + + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } + }, 15_000); + it("persists, recalls, and archives visible memories", async () => { const fixture = await createMemoryFixture(); diff --git a/packages/junior-plugin-api/src/observation.ts b/packages/junior-plugin-api/src/observation.ts index 777478f0a..f06d3bc21 100644 --- a/packages/junior-plugin-api/src/observation.ts +++ b/packages/junior-plugin-api/src/observation.ts @@ -1,27 +1,22 @@ import type { - Destination, + InvocationContext, PluginContext, PluginEmbedder, PluginModel, - Requester, - Source, } from "./context"; import type { PluginState } from "./state"; /** Delivered turn text and runtime context available to post-turn plugin hooks. */ -export interface TurnObservationContext extends Pick< +export type TurnObservationContext = Pick< PluginContext, "db" | "log" | "plugin" -> { - assistantText: string; - conversationId?: string; - destination?: Destination; - embedder: PluginEmbedder; - model: PluginModel; - requester?: Requester; - source: Source; - state: PluginState; - toolCalls: string[]; - turnId: string; - userText: string; -} +> & + InvocationContext & { + assistantText: string; + embedder: PluginEmbedder; + model: PluginModel; + state: PluginState; + toolCalls: string[]; + turnId: string; + userText: string; + }; diff --git a/packages/junior/src/chat/plugins/agent-hooks.ts b/packages/junior/src/chat/plugins/agent-hooks.ts index 7e7a80a40..41e8bb35c 100644 --- a/packages/junior/src/chat/plugins/agent-hooks.ts +++ b/packages/junior/src/chat/plugins/agent-hooks.ts @@ -153,7 +153,6 @@ function observationPluginContext( assistantText: context.assistantText, embedder: createPluginEmbedder(plugin.manifest.name), model: createPluginModel(plugin.manifest.name), - source: context.source, state: createPluginState(plugin.manifest.name), toolCalls: [...context.toolCalls], turnId: context.turnId, @@ -165,6 +164,7 @@ function observationPluginContext( if (context.source.platform === "slack") { return { ...common, + source: context.source, requester: context.requester?.platform === "slack" ? context.requester : undefined, destination: @@ -175,6 +175,7 @@ function observationPluginContext( } return { ...common, + source: context.source, requester: context.requester?.platform === "local" ? context.requester : undefined, destination: diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 1127dd6ff..52c71bbf8 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -1086,7 +1086,7 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { ...(messageTs ? { messageTs } : {}), ...(threadTs ? { threadTs } : {}), }, - userText: effectiveUserText, + userText: currentText.userText, }, }); } diff --git a/packages/junior/src/chat/runtime/slack-resume.ts b/packages/junior/src/chat/runtime/slack-resume.ts index 22e19da46..ddfba53bc 100644 --- a/packages/junior/src/chat/runtime/slack-resume.ts +++ b/packages/junior/src/chat/runtime/slack-resume.ts @@ -6,6 +6,7 @@ import { type AssistantReplyRequestContext, } from "@/chat/respond"; import type { Source } from "@sentry/junior-plugin-api"; +import { observePluginTurn } from "@/chat/plugins/agent-hooks"; import { scheduleSessionCompletedPluginTasks } from "@/chat/plugins/task-runner"; import { buildTurnFailureResponse, @@ -405,6 +406,31 @@ export async function resumeSlackTurn( ); } } + if ( + reply.diagnostics.outcome === "success" && + replyContext.destination.platform === "slack" + ) { + await observePluginTurn({ + assistantText: reply.text, + toolCalls: reply.diagnostics.toolCalls, + turnId: replyContext.correlation?.turnId ?? lockKey, + context: { + conversationId: replyContext.correlation?.conversationId ?? lockKey, + destination: replyContext.destination, + ...(replyContext.requester + ? { requester: replyContext.requester } + : {}), + source: { + platform: "slack", + teamId: replyContext.destination.teamId, + channelId: replyContext.destination.channelId, + ...(runArgs.messageTs ? { messageTs: runArgs.messageTs } : {}), + threadTs: runArgs.threadTs, + }, + userText: runArgs.messageText, + }, + }); + } } catch (error) { await status.stop(); diff --git a/packages/junior/tests/unit/handlers/oauth-resume.test.ts b/packages/junior/tests/unit/handlers/oauth-resume.test.ts index 62430e946..c9ef1f6b1 100644 --- a/packages/junior/tests/unit/handlers/oauth-resume.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-resume.test.ts @@ -1,13 +1,16 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource, defineJuniorPlugin } from "@sentry/junior-plugin-api"; import { RetryableTurnError } from "@/chat/runtime/turn"; import { disconnectStateAdapter, getStateAdapter } from "@/chat/state/adapter"; -import { createSlackSource } from "@sentry/junior-plugin-api"; +import { setPlugins } from "@/chat/plugins/agent-hooks"; -const { logExceptionMock, postMessageMock, setStatusMock } = vi.hoisted(() => ({ - logExceptionMock: vi.fn(), - postMessageMock: vi.fn(), - setStatusMock: vi.fn(), -})); +const { postMessageMock, setStatusMock, uploadFilesToThreadMock } = vi.hoisted( + () => ({ + postMessageMock: vi.fn(), + setStatusMock: vi.fn(), + uploadFilesToThreadMock: vi.fn(), + }), +); vi.mock("@/chat/config", async (importOriginal) => { const original = await importOriginal(); @@ -46,13 +49,21 @@ vi.mock("@/chat/slack/client", () => ({ }), })); -vi.mock("@/chat/logging", async (importOriginal) => { - const original = await importOriginal(); - return { - ...original, - logException: logExceptionMock, - }; -}); +vi.mock("@/chat/slack/outbound", () => ({ + postSlackMessage: async (input: { + blocks?: unknown[]; + channelId: string; + text: string; + threadTs?: string; + }) => + await postMessageMock({ + channel: input.channelId, + text: input.text, + ...(input.threadTs ? { thread_ts: input.threadTs } : {}), + ...(input.blocks ? { blocks: input.blocks } : {}), + }), + uploadFilesToThread: uploadFilesToThreadMock, +})); import { resumeAuthorizedRequest, @@ -77,21 +88,22 @@ function testSlackSource(threadTs: string) { describe("resumeAuthorizedRequest", () => { beforeEach(async () => { vi.useFakeTimers(); - logExceptionMock.mockReset(); - logExceptionMock.mockReturnValue("evt_test"); postMessageMock.mockReset(); setStatusMock.mockReset(); + uploadFilesToThreadMock.mockReset(); postMessageMock.mockResolvedValue({ ts: "1700000000.100" }); setStatusMock.mockResolvedValue(undefined); + uploadFilesToThreadMock.mockResolvedValue(undefined); await disconnectStateAdapter(); }); afterEach(async () => { vi.useRealTimers(); + setPlugins([]); await disconnectStateAdapter(); }); - it("fails fast when resumed reply generation exceeds the configured timeout", async () => { + it("runs failure handling when resumed reply generation exceeds the configured timeout", async () => { const onFailure = vi.fn(async () => undefined); const resumePromise = resumeAuthorizedRequest({ @@ -116,6 +128,13 @@ describe("resumeAuthorizedRequest", () => { await resumePromise; expect(onFailure).toHaveBeenCalledTimes(1); + expect(postMessageMock).toHaveBeenCalledWith( + expect.objectContaining({ + channel: "C-test", + thread_ts: "1700000000.0001", + text: "connected", + }), + ); expect(postMessageMock).toHaveBeenLastCalledWith( expect.objectContaining({ channel: "C-test", @@ -127,35 +146,29 @@ describe("resumeAuthorizedRequest", () => { ); }); - it("persists failure state before requiring a Sentry event ID", async () => { + it("persists failure state before posting the failure reply", async () => { const onFailure = vi.fn(async () => undefined); - logExceptionMock.mockReturnValueOnce(undefined); - await expect( - resumeAuthorizedRequest({ - messageText: "tell me the saved deadline", - channelId: "C-test", - threadTs: "1700000000.0004", - connectedText: "connected", - replyContext: { - credentialContext: { - actor: { type: "user", userId: "U-test" }, - }, - destination: TEST_SLACK_DESTINATION, - source: testSlackSource("1700000000.0004"), - requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, - }, - generateReply: async () => { - throw new Error("resume failed"); + await resumeAuthorizedRequest({ + messageText: "tell me the saved deadline", + channelId: "C-test", + threadTs: "1700000000.0004", + connectedText: "connected", + replyContext: { + credentialContext: { + actor: { type: "user", userId: "U-test" }, }, - onFailure, - }), - ).rejects.toThrow( - "Sentry did not return an event ID for slack_resume_turn_failed", - ); + destination: TEST_SLACK_DESTINATION, + source: testSlackSource("1700000000.0004"), + requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, + }, + generateReply: async () => { + throw new Error("resume failed"); + }, + onFailure, + }); expect(onFailure).toHaveBeenCalledTimes(1); - expect(postMessageMock).toHaveBeenCalledTimes(1); expect(postMessageMock).toHaveBeenCalledWith( expect.objectContaining({ channel: "C-test", @@ -163,11 +176,13 @@ describe("resumeAuthorizedRequest", () => { text: "connected", }), ); - expect(postMessageMock).not.toHaveBeenCalledWith( + expect(postMessageMock).toHaveBeenLastCalledWith( expect.objectContaining({ channel: "C-test", thread_ts: "1700000000.0004", - text: expect.stringContaining("event_id=unknown"), + text: expect.stringContaining( + "I ran into an internal error while processing that. Reference: `event_id=", + ), }), ); }); @@ -266,6 +281,96 @@ describe("resumeAuthorizedRequest", () => { }); }); + it("observes successful resumed turns after persistence", async () => { + const observed: unknown[] = []; + const onSuccess = vi.fn(async () => undefined); + const previous = setPlugins([ + defineJuniorPlugin({ + manifest: { + name: "resume-observer", + displayName: "Resume Observer", + description: "Resume observer", + }, + hooks: { + observeTurn(ctx) { + observed.push({ + assistantText: ctx.assistantText, + conversationId: ctx.conversationId, + destination: ctx.destination, + requester: ctx.requester, + source: ctx.source, + toolCalls: ctx.toolCalls, + turnId: ctx.turnId, + userText: ctx.userText, + }); + }, + }, + }), + ]); + + try { + await resumeSlackTurn({ + messageText: "remember that launch notes live in Notion", + channelId: "C-test", + threadTs: "1700000000.0005", + replyContext: { + correlation: { + conversationId: "slack:C-test:1700000000.0005", + turnId: "turn-resume-1", + }, + credentialContext: { + actor: { type: "user", userId: "U-test" }, + }, + destination: TEST_SLACK_DESTINATION, + source: testSlackSource("1700000000.0005"), + requester: { + platform: "slack", + teamId: "T-test", + userId: "U-test", + }, + }, + generateReply: async () => ({ + text: "Final resumed answer", + diagnostics: { + assistantMessageCount: 1, + modelId: "fake-agent-model", + outcome: "success", + toolCalls: [], + toolErrorCount: 0, + toolResultCount: 0, + usedPrimaryText: true, + }, + }), + onSuccess, + }); + + expect(onSuccess).toHaveBeenCalledTimes(1); + expect(observed).toEqual([ + { + assistantText: "Final resumed answer", + conversationId: "slack:C-test:1700000000.0005", + destination: TEST_SLACK_DESTINATION, + requester: { + platform: "slack", + teamId: "T-test", + userId: "U-test", + }, + source: { + platform: "slack", + teamId: "T-test", + channelId: "C-test", + threadTs: "1700000000.0005", + }, + toolCalls: [], + turnId: "turn-resume-1", + userText: "remember that launch notes live in Notion", + }, + ]); + } finally { + setPlugins(previous); + } + }); + it("releases the thread lock before scheduling another timeout slice", async () => { const onTimeoutPause = vi.fn(async () => { const stateAdapter = getStateAdapter(); @@ -307,7 +412,7 @@ describe("resumeAuthorizedRequest", () => { expect(postMessageMock).not.toHaveBeenCalled(); }); - it("posts the canonical failure response when timeout pause handling throws", async () => { + it("runs failure handling when timeout pause handling throws", async () => { const onFailure = vi.fn(async () => undefined); await resumeSlackTurn({ diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 9507b60b1..27fa8b7d7 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -69,16 +69,21 @@ The observation hook must: 2. Invoke the memory-owned extraction agent with bounded user-authored turn text. 3. Ignore assistant-authored claims as memory sources. -4. Skip passive extraction when the completed turn already called - `createMemory`; the explicit tool path owns that memory write. -5. Extract candidate facts with a structured model output contract. -6. Reject malformed, incoherent, unsafe, out-of-scope, or non-durable facts. -7. Assign requester or conversation target from memory-agent output, while +4. Skip passive extraction for unsupported sources. V1 supports local CLI + observations and public Slack channel observations with a message or thread + timestamp; private Slack and timestamp-less Slack observations are ignored + before model extraction. +5. Skip passive extraction when the completed turn already called a + memory-management tool (`createMemory`, `listMemories`, `searchMemories`, or + `removeMemory`); the explicit tool path owns `createMemory` writes. +6. Extract candidate facts with a structured model output contract. +7. Reject malformed, incoherent, unsafe, out-of-scope, or non-durable facts. +8. Assign requester or conversation target from memory-agent output, while deriving all authority-bearing ids from runtime context. -8. Insert accepted memories idempotently with a stable key derived from the +9. Insert accepted memories idempotently with a stable key derived from the source, turn id, and extracted fact position. -9. Generate embeddings for accepted rows when the host embedder is configured. -10. Avoid storing raw extraction prompt, raw model output, or raw turn text +10. Generate embeddings for accepted rows when the host embedder is configured. +11. Avoid storing raw extraction prompt, raw model output, or raw turn text beyond the accepted memory records. Observation hooks are best effort. If extraction or storage fails, Junior logs diff --git a/specs/memory-plugin/index.md b/specs/memory-plugin/index.md index 32da287d2..101ba68ce 100644 --- a/specs/memory-plugin/index.md +++ b/specs/memory-plugin/index.md @@ -32,7 +32,7 @@ Explicit tools also support user-directed memory management. ## Scope - What is eligible for long-term memory. -- Install-level policy controls for workplace-safe extraction and recall. +- Default V1 policy guidance for workplace-safe extraction and recall. - Memory plugin package shape and required plugin hooks. - Plugin-owned SQL storage, retrieval indexes, embeddings, and model-provider boundaries. @@ -65,9 +65,8 @@ Read these files as one canonical spec: - [storage.md](./storage.md): SQL storage model, retrieval indexes, pgvector, embedding model provider, and operational storage rules. -- [policy.md](./policy.md): install-level controls for memory categories, - passive extraction, workplace-sensitive facts, model/provider use, and - retention. +- [policy.md](./policy.md): default V1 controls for memory categories, passive + extraction, workplace-sensitive facts, model/provider use, and retention. - [security.md](./security.md): authority boundaries, multi-user visibility, model/tool boundaries, task payload safety, and redaction rules. - [retrieval.md](./retrieval.md): automatic recall, tool-mediated recall, diff --git a/specs/memory-plugin/policy.md b/specs/memory-plugin/policy.md index 3c7f93931..72f8ae50e 100644 --- a/specs/memory-plugin/policy.md +++ b/specs/memory-plugin/policy.md @@ -201,8 +201,8 @@ Policy still disallows passive extraction by category, including: For V1, passive extraction should store conversation-scoped operational knowledge by default. Passive personal memory from public conversations requires clear first-person source evidence from the user and must still be visible only -to that requester. Explicit `createMemory` tool calls remain the stronger write -signal and suppress passive duplicate writes for the same completed turn. +to that requester. Explicit memory-management tool calls suppress passive +extraction for the same completed turn so the tool path owns its effect. ## Automatic Injection Policy @@ -232,14 +232,15 @@ and embedding policy, or retention and lifecycle policy. Tool errors should explain policy rejection at a high level without revealing hidden policy internals or sensitive content. -Explicit memory creation must use the same memory agent review as passive -extraction when the policy decision is not deterministic. If review fails for -an explicit tool request, the tool should return a retryable input error rather -than storing the memory. +Explicit memory creation must use the memory agent's explicit-create review +when the policy decision is not deterministic. If review fails for an explicit +tool request, the tool should return a retryable input error rather than +storing the memory. ## Retrieval And Policy -Retrieval must apply current policy as well as stored scope and lifecycle. +Retrieval must apply default V1 policy guidance as well as stored scope and +lifecycle. If policy changes after a memory was created, the stricter current policy wins for automatic memory injection and list/search results. The memory may remain diff --git a/specs/memory-plugin/security.md b/specs/memory-plugin/security.md index c0b893ccb..8dd43cdb1 100644 --- a/specs/memory-plugin/security.md +++ b/specs/memory-plugin/security.md @@ -13,8 +13,8 @@ model calls, embeddings, logging, and multi-user visibility. ## Security Invariants 1. Runtime context, not model text, determines memory visibility. -2. Install-level policy determines which public/shareable categories, scopes, - subjects, and model providers are allowed. +2. Default V1 policy guidance determines which public/shareable categories, + scopes, subjects, and model providers are allowed. 3. Secrets are rejected, not stored with a special classification. 4. Memory content may be model-visible only inside the stored scope and current policy. diff --git a/specs/memory-plugin/storage.md b/specs/memory-plugin/storage.md index b96f4d2f9..6275f262a 100644 --- a/specs/memory-plugin/storage.md +++ b/specs/memory-plugin/storage.md @@ -261,8 +261,8 @@ If embedding generation fails, the memory remains active and can be found through lexical/list retrieval. A later embedding repair task may repair missing or stale embeddings. -If install policy disables embeddings or a provider for a scope, the write path -must skip vector generation without failing the memory write. +If future install policy disables embeddings or a provider for a scope, the +write path must skip vector generation without failing the memory write. ### Repair And Rebuild diff --git a/specs/memory-plugin/tools.md b/specs/memory-plugin/tools.md index 2b64829e1..cdf92609d 100644 --- a/specs/memory-plugin/tools.md +++ b/specs/memory-plugin/tools.md @@ -65,10 +65,10 @@ to rephrase them as safer memory text. The memory agent owns the semantic store-or-reject decision and canonical rewrite. The explicit tool path uses runtime context for source and idempotency. It must -run through the same memory agent review path as passive extraction. The -memory agent decides store/reject, canonical perspective-neutral content, -subject, and whether the memory targets the current requester, active -conversation, or no valid V1 target. +run through the memory agent's explicit-create review path. The memory agent +decides store/reject, canonical perspective-neutral content, subject, and +whether the memory targets the current requester, active conversation, or no +valid V1 target. The model cannot provide arbitrary scope enums, subject ids, Slack user ids, display names, aliases, or subject classes. From 007721001ae8256b48bda827d51bcd8c69d4f821 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 17:27:20 -0700 Subject: [PATCH 03/29] fix(memory): Normalize plugin source context Expose normalized plugin source helpers with compact pub/priv source typing so trusted plugins can rely on shared source visibility and stable source keys instead of rebuilding platform-specific checks. Update memory passive extraction, runtime callers, tests, specs, and source-mode package exports around that contract. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 6 ++-- packages/junior-memory/package.json | 1 + packages/junior-memory/src/observe.ts | 35 +++++++------------ packages/junior-memory/tests/storage.test.ts | 6 ++-- packages/junior-plugin-api/package.json | 1 + packages/junior-plugin-api/src/context.ts | 31 ++++++++++++++++ packages/junior-scheduler/package.json | 1 + packages/junior-scheduler/src/plugin.ts | 1 + .../junior/src/chat/runtime/reply-executor.ts | 5 ++- .../junior/src/chat/runtime/slack-resume.ts | 6 ++-- .../integration/advisor/advisor-tool.test.ts | 1 + specs/memory-plugin/extraction.md | 10 +++--- specs/memory-plugin/index.md | 3 +- specs/plugin-prompt-hooks.md | 28 +++++++++++++++ 14 files changed, 95 insertions(+), 40 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index a036608a8..3aefefc81 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -3,6 +3,7 @@ import { assistantMessages, describeEval } from "vitest-evals"; import { closeDb, getDb } from "@/chat/db"; import { completeText, resolveGatewayModel } from "@/chat/pi/client"; import { createMemoryStore, type MemoryDb } from "@sentry/junior-memory"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { juniorMemoryMemories } from "../../../junior-memory/src/db/schema"; import { mention, rubric, slackEvals } from "../../src/helpers"; @@ -27,13 +28,12 @@ function memoryContext(thread: MemoryThread) { teamId: memoryTeamId, userId: requesterUserId, }, - source: { - platform: "slack" as const, + source: createSlackSource({ teamId: memoryTeamId, channelId: thread.channel_id, messageTs: thread.thread_ts, threadTs: thread.thread_ts, - }, + }), }; } diff --git a/packages/junior-memory/package.json b/packages/junior-memory/package.json index 4a736d077..5544c84b3 100644 --- a/packages/junior-memory/package.json +++ b/packages/junior-memory/package.json @@ -14,6 +14,7 @@ "exports": { ".": { "types": "./src/index.ts", + "development": "./src/index.ts", "default": "./dist/index.js" } }, diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/observe.ts index cf4651bef..6066ab923 100644 --- a/packages/junior-memory/src/observe.ts +++ b/packages/junior-memory/src/observe.ts @@ -1,4 +1,8 @@ -import type { TurnObservationContext } from "@sentry/junior-plugin-api"; +import { + getSourceKey, + isPrivateSource, + type TurnObservationContext, +} from "@sentry/junior-plugin-api"; import { createMemoryStore, type CreateMemoryInput, @@ -14,32 +18,15 @@ const MEMORY_TOOL_NAMES = new Set([ "searchMemories", ]); -function canPassivelyLearn(context: TurnObservationContext): boolean { - if (context.source.platform === "local") { - return true; - } - return Boolean( - context.source.channelId.startsWith("C") && - (context.source.threadTs ?? context.source.messageTs), - ); -} - -function observationSourceKey(context: TurnObservationContext): string { - if (context.source.platform === "local") { - return context.source.conversationId; - } - const messageKey = context.source.threadTs ?? context.source.messageTs; - return `slack:${context.source.teamId}:${context.source.channelId}:${messageKey}`; -} - function passiveInput( context: TurnObservationContext, memory: ExtractedMemory, index: number, + sourceKey: string, ): CreateMemoryInput { return { content: memory.content, - idempotencyKey: `observe:${observationSourceKey(context)}:${context.turnId}:${index}`, + idempotencyKey: `observe:${sourceKey}:${context.turnId}:${index}`, ...(memory.expiresAtMs !== null ? { expiresAtMs: memory.expiresAtMs } : {}), }; } @@ -51,7 +38,11 @@ export async function observeMemoryTurn( if (context.toolCalls.some((toolName) => MEMORY_TOOL_NAMES.has(toolName))) { return; } - if (!canPassivelyLearn(context)) { + if (context.source.platform !== "local" && isPrivateSource(context.source)) { + return; + } + const sourceKey = getSourceKey(context.source); + if (!sourceKey) { return; } const userText = context.userText.trim(); @@ -79,7 +70,7 @@ export async function observeMemoryTurn( embedder: context.embedder, }); for (const [index, memory] of memories.entries()) { - const input = passiveInput(context, memory, index); + const input = passiveInput(context, memory, index, sourceKey); if (memory.target === "conversation") { await store.createConversationMemory(input); continue; diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 6f05ac9df..7d9df4091 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -499,11 +499,10 @@ describe("memory plugin storage", () => { db: memoryDb(fixture), model, requester: runtime.requester, - source: { - platform: "slack", + source: createSlackSource({ teamId: runtime.source.teamId, channelId: runtime.source.channelId, - }, + }), userText: "I prefer Slack message key validation.", }), ); @@ -1012,6 +1011,7 @@ WHERE id = '${superseded.memory.id}' platform: "slack", type: "pub", teamId: "T123", + conversationId: "C123", channelId: "C123", messageTs: "1718800000.000000", threadTs: "1718800000.000000", diff --git a/packages/junior-plugin-api/package.json b/packages/junior-plugin-api/package.json index 075b95cb0..aed4035ae 100644 --- a/packages/junior-plugin-api/package.json +++ b/packages/junior-plugin-api/package.json @@ -14,6 +14,7 @@ "exports": { ".": { "types": "./src/index.ts", + "development": "./src/index.ts", "default": "./dist/index.js" } }, diff --git a/packages/junior-plugin-api/src/context.ts b/packages/junior-plugin-api/src/context.ts index 88e4b26e2..76b623761 100644 --- a/packages/junior-plugin-api/src/context.ts +++ b/packages/junior-plugin-api/src/context.ts @@ -137,11 +137,42 @@ export function createLocalSource(conversationId: string): LocalSource { }; } +/** Build a source from a destination when the source is the same conversation. */ +export function sourceFromDestination(destination: Destination): Source { + if (destination.platform === "local") { + return createLocalSource(destination.conversationId); + } + return createSlackSource({ + channelId: destination.channelId, + teamId: destination.teamId, + }); +} + /** Return whether a source is private to a person or restricted group. */ export function isPrivateSource(source: Source): boolean { return source.type === "priv"; } +/** Return whether a source has a stable message or conversation identity. */ +export function hasStableSourceKey(source: Source): boolean { + if (source.platform === "local") { + return true; + } + return Boolean(source.threadTs ?? source.messageTs); +} + +/** Return the stable source identity used for idempotency and attribution. */ +export function getSourceKey(source: Source): string | undefined { + if (source.platform === "local") { + return source.conversationId; + } + const messageKey = source.threadTs ?? source.messageTs; + if (!messageKey) { + return undefined; + } + return `slack:${source.teamId}:${source.channelId}:${messageKey}`; +} + /** Narrow a runtime destination to the Slack-specific address shape. */ export function isSlackDestination( destination: Destination | undefined, diff --git a/packages/junior-scheduler/package.json b/packages/junior-scheduler/package.json index d9151bdc1..10be0b23e 100644 --- a/packages/junior-scheduler/package.json +++ b/packages/junior-scheduler/package.json @@ -14,6 +14,7 @@ "exports": { ".": { "types": "./src/index.ts", + "development": "./src/index.ts", "default": "./dist/index.js" } }, diff --git a/packages/junior-scheduler/src/plugin.ts b/packages/junior-scheduler/src/plugin.ts index 3cf1a1b49..607ed9d3b 100644 --- a/packages/junior-scheduler/src/plugin.ts +++ b/packages/junior-scheduler/src/plugin.ts @@ -1,4 +1,5 @@ import { + createSlackSource, defineJuniorPlugin, createSlackSource, type Dispatch, diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 52c71bbf8..7b9d94799 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -1079,13 +1079,12 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { ...(conversationId ? { conversationId } : {}), destination, requester: requesterIdentity, - source: { - platform: "slack", + source: createSlackSource({ teamId: destination.teamId, channelId: destination.channelId, ...(messageTs ? { messageTs } : {}), ...(threadTs ? { threadTs } : {}), - }, + }), userText: currentText.userText, }, }); diff --git a/packages/junior/src/chat/runtime/slack-resume.ts b/packages/junior/src/chat/runtime/slack-resume.ts index ddfba53bc..443c9a310 100644 --- a/packages/junior/src/chat/runtime/slack-resume.ts +++ b/packages/junior/src/chat/runtime/slack-resume.ts @@ -1,4 +1,5 @@ import { botConfig } from "@/chat/config"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import type { ChannelConfigurationService } from "@/chat/configuration/types"; import { generateAssistantReply, @@ -420,13 +421,12 @@ export async function resumeSlackTurn( ...(replyContext.requester ? { requester: replyContext.requester } : {}), - source: { - platform: "slack", + source: createSlackSource({ teamId: replyContext.destination.teamId, channelId: replyContext.destination.channelId, ...(runArgs.messageTs ? { messageTs: runArgs.messageTs } : {}), threadTs: runArgs.threadTs, - }, + }), userText: runArgs.messageText, }, }); diff --git a/packages/junior/tests/integration/advisor/advisor-tool.test.ts b/packages/junior/tests/integration/advisor/advisor-tool.test.ts index 9652cc185..fc19d7828 100644 --- a/packages/junior/tests/integration/advisor/advisor-tool.test.ts +++ b/packages/junior/tests/integration/advisor/advisor-tool.test.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import type { AgentTool, StreamFn } from "@earendil-works/pi-agent-core"; import { createLocalSource } from "@sentry/junior-plugin-api"; import { Type } from "@sinclair/typebox"; +import { createLocalSource } from "@sentry/junior-plugin-api"; import type { AdvisorConfig } from "@/chat/config"; import type { PiMessage } from "@/chat/pi/messages"; import { createTools } from "@/chat/tools"; diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 27fa8b7d7..813ee65f0 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -70,9 +70,9 @@ The observation hook must: text. 3. Ignore assistant-authored claims as memory sources. 4. Skip passive extraction for unsupported sources. V1 supports local CLI - observations and public Slack channel observations with a message or thread - timestamp; private Slack and timestamp-less Slack observations are ignored - before model extraction. + observations and `pub` sources with a stable source key. Non-local `priv` + sources and sources without stable identity are ignored before model + extraction. 5. Skip passive extraction when the completed turn already called a memory-management tool (`createMemory`, `listMemories`, `searchMemories`, or `removeMemory`); the explicit tool path owns `createMemory` writes. @@ -80,8 +80,8 @@ The observation hook must: 7. Reject malformed, incoherent, unsafe, out-of-scope, or non-durable facts. 8. Assign requester or conversation target from memory-agent output, while deriving all authority-bearing ids from runtime context. -9. Insert accepted memories idempotently with a stable key derived from the - source, turn id, and extracted fact position. +9. Insert accepted memories idempotently with a stable key derived through the + runtime source helper, turn id, and extracted fact position. 10. Generate embeddings for accepted rows when the host embedder is configured. 11. Avoid storing raw extraction prompt, raw model output, or raw turn text beyond the accepted memory records. diff --git a/specs/memory-plugin/index.md b/specs/memory-plugin/index.md index 101ba68ce..915bd50d9 100644 --- a/specs/memory-plugin/index.md +++ b/specs/memory-plugin/index.md @@ -162,7 +162,8 @@ passive extraction, stored categories, providers, and retention defaults. V1 passive extraction targets public/shareable, durable facts from supported runtime contexts. Local CLI contexts are valid passive-learning sources for -development and QA. Private, sensitive, secret, or otherwise restricted facts +development and QA. Non-local sources must be `type: "pub"` and have a stable +runtime source key. Private, sensitive, secret, or otherwise restricted facts are rejected rather than stored. V1 uses the default extraction guidance in `policy.md`. Install-provided diff --git a/specs/plugin-prompt-hooks.md b/specs/plugin-prompt-hooks.md index eb8309ac1..2fd76d045 100644 --- a/specs/plugin-prompt-hooks.md +++ b/specs/plugin-prompt-hooks.md @@ -151,6 +151,34 @@ interface UserPromptContext { } ``` +`Source` is a runtime-normalized origin for the current turn. It must include +`platform`, `type`, and a platform conversation id: + +```ts +type SourceType = "pub" | "priv"; + +type Source = + | { + platform: "slack"; + type: SourceType; + teamId: string; + conversationId: string; + channelId: string; + messageTs?: string; + threadTs?: string; + } + | { + platform: "local"; + type: "priv"; + conversationId: string; + }; +``` + +Plugins should use the public source helpers from `@sentry/junior-plugin-api` +for common source decisions such as private-source checks and stable source key +derivation. Plugin implementations must not scatter Slack channel-prefix checks +or rebuild source keys from platform-specific fields. + The context must not expose: - structured completion/model-review capabilities From 70433039432b56e220811d2c16f4941f799a2614 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 18:31:56 -0700 Subject: [PATCH 04/29] fix(memory): Tighten passive extraction QA Keep memory extraction prompt examples neutral and make the model-facing output field explicitly canonical. Pass assistant responses as rejection context for passive extraction so follow-up and advice turns are less likely to create duplicate memories. Fix eval assertions to read memories for the active test thread and remove the package development export condition that made CI load TypeScript from node_modules. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 27 +++++--- packages/junior-memory/package.json | 1 - packages/junior-memory/src/agent.ts | 67 ++++++++++++++----- packages/junior-memory/src/observe.ts | 1 + packages/junior-memory/tests/storage.test.ts | 52 +++++++++++++- packages/junior-plugin-api/package.json | 1 - packages/junior-plugin-api/src/context.ts | 8 --- packages/junior-scheduler/package.json | 1 - .../junior/src/chat/runtime/reply-executor.ts | 15 +++++ policies/evals.md | 4 ++ 10 files changed, 136 insertions(+), 41 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index 3aefefc81..b64587c9c 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -58,11 +58,16 @@ function memoryDb(): MemoryDb { return getDb() as unknown as MemoryDb; } -async function readMemories() { - return await memoryDb() +function memorySourceKey(thread: MemoryThread): string { + return `slack:${memoryTeamId}:${thread.channel_id}:${thread.thread_ts}`; +} + +async function readMemories(thread: MemoryThread) { + const rows = await memoryDb() .select() .from(juniorMemoryMemories) .orderBy(juniorMemoryMemories.createdAtMs, juniorMemoryMemories.id); + return rows.filter((memory) => memory.sourceKey === memorySourceKey(thread)); } function visibleAssistantText(result: { @@ -169,7 +174,7 @@ async function expectAssistantMemoryAnswer(args: { "", "Pass only if the assistant text satisfies the expected behavior.", "Fail if the assistant asks the user to restate the remembered fact, claims no relevant memory exists, or exposes hidden storage fields such as scope keys or Slack ids.", - "Memory ids or id prefixes are allowed when the user explicitly requested an id.", + "Use expected-behavior as the authority for whether the scenario requested a memory id. Memory ids or id prefixes are allowed when expected-behavior says an id was requested.", "", ].join("\n"), timestamp: Date.now(), @@ -230,7 +235,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - const rows = await readMemories(); + const rows = await readMemories(explicitRememberThread); expect(rows).toEqual([ expect.objectContaining({ archivedAtMs: null, @@ -280,7 +285,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - const rows = await readMemories(); + const rows = await readMemories(firstPersonRewrittenThread); expect(rows).toEqual([ expect.objectContaining({ archivedAtMs: null, @@ -332,7 +337,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - const rows = await readMemories(); + const rows = await readMemories(passiveFirstPersonThread); expect(rows).toEqual([ expect.objectContaining({ archivedAtMs: null, @@ -382,7 +387,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - expect(await readMemories()).toEqual([]); + expect(await readMemories(thirdPartyRememberThread)).toEqual([]); }); const listThread = { @@ -429,7 +434,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { "The assistant lists the stored memory that the requester prefers terse PR summaries.", }); expectMemoryIdReference(visibleAssistantText(result), seeded.memory.id); - expect(await readMemories()).toEqual([ + expect(await readMemories(listThread)).toEqual([ expect.objectContaining({ archivedAtMs: null, content: "Prefers terse PR summaries.", @@ -487,7 +492,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { "The assistant answers from memory that the requester prefers incident reports with bullet summaries and includes the requested matching memory id or id prefix.", }); expectMemoryIdReference(visibleAssistantText(result), match.memory.id); - expect(await readMemories()).toEqual( + expect(await readMemories(searchThread)).toEqual( expect.arrayContaining([ expect.objectContaining({ content: "Prefers incident reports with bullet summaries.", @@ -533,7 +538,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - expect(await readMemories()).toEqual([ + expect(await readMemories(autoRecallThread)).toEqual([ expect.objectContaining({ archivedAtMs: null, content: "Prefers PR summaries with risks first.", @@ -574,7 +579,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - expect(await readMemories()).toEqual([ + expect(await readMemories(removeThread)).toEqual([ expect.objectContaining({ archivedAtMs: expect.any(Number), archiveReason: "tool_removed", diff --git a/packages/junior-memory/package.json b/packages/junior-memory/package.json index 5544c84b3..4a736d077 100644 --- a/packages/junior-memory/package.json +++ b/packages/junior-memory/package.json @@ -14,7 +14,6 @@ "exports": { ".": { "types": "./src/index.ts", - "development": "./src/index.ts", "default": "./dist/index.js" } }, diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index d9397ab93..5eaf6d73b 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -28,6 +28,7 @@ const createMemoryRequestSchema = z .strict(); const extractTurnRequestSchema = z .object({ + assistantText: z.string(), runtimeContext: memoryRuntimeContextSchema, userText: z.string().min(1), }) @@ -57,12 +58,12 @@ const memoryReviewResponseSchema = z target: memoryTargetSchema .nullable() .describe("Memory target when decision is store, otherwise null."), - content: z + canonicalFact: z .string() .min(1) .nullable() .describe( - "Canonical perspective-neutral fact when decision is store, otherwise null. Do not include requester names, display names, 'the requester', 'the user', 'I', 'my', 'this thread', or channel/source labels. Good: 'Prefers terse PR summaries'. Good: 'Favorite CLI QA snack is mango chips'. Good: 'Deploy runbooks live in Notion'. Bad: 'The requester prefers terse PR summaries'. Bad: 'David prefers terse PR summaries'. Bad: 'This thread says deploy runbooks live in Notion'.", + "Canonical perspective-neutral fact when decision is store, otherwise null. For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'. Do not include requester names, display names, 'the requester', 'the user', first-person wording like 'I', 'me', 'my', 'mine', 'we', or 'our', second-person wording like 'you' or 'your', 'this thread', or channel/source labels. Good: 'Prefers morning standup notes'. Good: 'Favorite editor theme is Solarized Light'. Good: 'Release checklist lives in Linear'. Bad: 'I prefer morning standup notes'. Bad: 'The requester prefers morning standup notes'. Bad: 'David prefers morning standup notes'. Bad: 'This thread says the release checklist lives in Linear'.", ), reason: memoryRejectReasonSchema .nullable() @@ -81,11 +82,11 @@ const extractedMemorySchema = z target: memoryTargetSchema.describe( "Where the memory should be stored when this is accepted.", ), - content: z + canonicalFact: z .string() .min(1) .describe( - "Canonical perspective-neutral fact. Do not include requester names, display names, 'the requester', 'the user', 'I', 'my', 'this thread', or channel/source labels.", + "Canonical perspective-neutral fact. For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'. Do not include requester names, display names, 'the requester', 'the user', first-person wording like 'I', 'me', 'my', 'mine', 'we', or 'our', second-person wording like 'you' or 'your', 'this thread', or channel/source labels.", ), expiresAtMs: z .number() @@ -108,6 +109,7 @@ const extractTurnResponseSchema = z .strict(); type MemoryReviewResponse = z.output; +type ExtractTurnResponse = z.output; export type MemoryTarget = z.output; @@ -115,7 +117,11 @@ export type MemoryReview = z.output; export type CreateMemoryRequest = z.output; export type ExtractTurnRequest = z.output; -export type ExtractedMemory = z.output; +export interface ExtractedMemory { + content: string; + expiresAtMs: number | null; + target: MemoryTarget; +} export interface MemoryAgent { extractTurnMemories( @@ -136,6 +142,8 @@ const MEMORY_REVIEW_SYSTEM = [ "Conversation memories must be shared operational or project knowledge about the active conversation, not another person's private profile.", "Do not accept model/caller-provided actor ids, scope ids, aliases, or arbitrary subjects.", "For accepted memories, rewrite content into one concise declarative fact that is understandable without the original conversation and does not bake in who said it or where it was said.", + "For requester memories, omit the subject and use canonical phrasing such as 'Prefers X', 'Uses Y', or 'Thinks Z'; never output 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', a requester name, 'the requester', or 'the user'.", + "Before returning store, self-check the content: if it could be read as the user's direct quote, rewrite it into omitted-subject canonical prose.", "Return every response field. Use null for fields that do not apply to the decision.", ].join("\n"); const MEMORY_EXTRACTION_SYSTEM = [ @@ -145,8 +153,12 @@ const MEMORY_EXTRACTION_SYSTEM = [ "Do not store secrets, credentials, private/sensitive personal details, gossip, speculative coworker claims, assistant/system implementation details, vague references, or low-durability chatter.", "Personal/requester memories must come from the user's own first-person statements about themselves, then be stored as perspective-neutral canonical facts without names or requester/source wording.", "Conversation memories must be shared operational or project knowledge about the active conversation, not another person's private profile.", - "Extract only facts explicitly present in the user-authored message. Never use assistant text, tool results, recalled memory text, or suggested wording as source evidence.", + "Extract only facts explicitly present in the user-authored message. Assistant text is rejection context only; never use assistant text, tool results, recalled memory text, or suggested wording as source evidence.", "Never store a fact merely because the assistant suggested or invented it. The user-authored text is the source of truth.", + "For requester memories, omit the subject and use canonical phrasing such as 'Prefers X', 'Uses Y', or 'Thinks Z'; never output 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', a requester name, 'the requester', or 'the user'.", + "Before returning a requester memory, self-check the content: if it could be read as the user's direct quote, rewrite it into omitted-subject canonical prose.", + "Return one memory per distinct fact. If a first-person requester fact mentions a workstream, project, or conversation topic, keep that context inside the requester memory instead of also creating a conversation memory for the same fact.", + "Advice, how-to, search, recall, and planning questions are not memories by themselves. Extract from those turns only when the user states a durable self-fact or shared project fact that remains true beyond the request.", "Do not duplicate explicit memory tool outcomes; turns that used memory tools are filtered before this agent, but if the user text is asking to list, search, recall, remove, confirm, or inspect existing memories, return no memories.", "Return only accepted memories. If there are no accepted memories, return an empty memories array.", ].join("\n"); @@ -219,11 +231,13 @@ function reviewPrompt(request: CreateMemoryRequest): string { "- A candidate may be badly phrased by the outer assistant. When current-user-message contains the requester's own first-person memory request, treat that as requester-authored source evidence and canonicalize the fact instead of rejecting for third-person wording.", "- Use target=conversation only for shared operational/project knowledge in the active conversation.", "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", - "- Remove phrases such as 'I', 'my', 'the requester', 'the user', user names, 'this thread', 'this channel', and Slack/source labels from stored content.", - "- Good stored content: 'Prefers terse PR summaries'. Bad stored content: 'The requester prefers terse PR summaries'.", - "- Good stored content: 'Favorite CLI QA snack is mango chips'. Bad stored content: 'My favorite CLI QA snack is mango chips'.", - "- Good stored content: 'Thinks types in Python are bad'. Bad stored content: 'David thinks types in Python are bad'.", - "- Good stored content: 'Deploy runbooks live in Notion'. Bad stored content: 'This thread says deploy runbooks live in Notion'.", + "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", + "- If the stored content would still sound like the user's direct quote, rewrite it before returning store.", + "- Remove phrases such as 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', 'the requester', 'the user', user names, 'this thread', 'this channel', and Slack/source labels from stored content.", + "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'The requester prefers morning standup notes'.", + "- Good stored content: 'Favorite editor theme is Solarized Light'. Bad stored content: 'My favorite editor theme is Solarized Light'.", + "- Good stored content: 'Thinks runtime logs should include request ids'. Bad stored content: 'David thinks runtime logs should include request ids'.", + "- Good stored content: 'Release checklist lives in Linear'. Bad stored content: 'This thread says the release checklist lives in Linear'.", "- Reject third-party personal profile facts, even if they mention a name.", "- Reject vague content such as 'remember this' unless the candidate itself contains the fact.", "- Preserve the requested expiration when one exists; otherwise set expiresAtMs to null.", @@ -249,16 +263,25 @@ function extractionPrompt(request: ExtractTurnRequest): string { escapeXml(request.userText), "", "", + "", + escapeXml(request.assistantText), + "", + "", "", "- Return at most five memories.", "- The user-message is the only source of storable facts.", + "- Use assistant-response only to identify non-memory turns, confirmations, or follow-up questions. Do not store facts from assistant-response.", + "- Return one memory per distinct fact. Do not store the same fact under both requester and conversation targets.", + "- Do not store advice, how-to, search, recall, or planning requests unless the user-message also states a durable fact independent of the request.", "- Return an empty array when the user-message only asks what is remembered, how to use a remembered preference, or asks to list/search/remove/inspect memory.", "- Use target=requester for first-person facts about the current requester.", "- Use target=conversation only for shared operational/project knowledge.", "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", - "- Good stored content: 'Prefers terse PR summaries'. Bad stored content: 'The requester prefers terse PR summaries'.", - "- Good stored content: 'Thinks types in Python are bad'. Bad stored content: 'David thinks types in Python are bad'.", - "- Good stored content: 'Deploy runbooks live in Notion'. Bad stored content: 'This thread says deploy runbooks live in Notion'.", + "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", + "- If the stored content would still sound like the user's direct quote, rewrite it before returning it.", + "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'The requester prefers morning standup notes'.", + "- Good stored content: 'Thinks runtime logs should include request ids'. Bad stored content: 'David thinks runtime logs should include request ids'.", + "- Good stored content: 'Release checklist lives in Linear'. Bad stored content: 'This thread says the release checklist lives in Linear'.", "- Reject third-party personal profile facts, even if they mention a name.", "- Reject facts that are only useful inside this one turn.", "- If unsure, return no memory for that candidate.", @@ -278,7 +301,9 @@ export function createMemoryAgent(model: PluginModel): MemoryAgent { prompt: extractionPrompt(request), maxTokens: 1_000, }); - return extractTurnResponseSchema.parse(result.object).memories; + return extractedMemoriesFromResponse( + extractTurnResponseSchema.parse(result.object), + ); }, async reviewCreateRequest(rawRequest) { const request = parseCreateMemoryRequest(rawRequest); @@ -301,7 +326,7 @@ function memoryReviewFromResponse( return parseMemoryReview({ decision: "store", target: response.target, - content: response.content, + content: response.canonicalFact, ...(response.expiresAtMs !== null ? { expiresAtMs: response.expiresAtMs } : {}), @@ -313,6 +338,16 @@ function memoryReviewFromResponse( }); } +function extractedMemoriesFromResponse( + response: ExtractTurnResponse, +): ExtractedMemory[] { + return response.memories.map((memory) => ({ + content: memory.canonicalFact, + expiresAtMs: memory.expiresAtMs, + target: memory.target, + })); +} + /** Parse the structured decision returned by the memory agent. */ export function parseMemoryReview(result: unknown): MemoryReview { return memoryReviewDecisionSchema.parse(result); diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/observe.ts index 6066ab923..b2f3c7595 100644 --- a/packages/junior-memory/src/observe.ts +++ b/packages/junior-memory/src/observe.ts @@ -59,6 +59,7 @@ export async function observeMemoryTurn( }); const agent = createMemoryAgent(context.model); const memories = await agent.extractTurnMemories({ + assistantText: context.assistantText, runtimeContext, userText, }); diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 7d9df4091..4e4bdba9d 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -196,8 +196,9 @@ function extractionModel( return { object: { memories: memories.map((memory) => ({ - ...memory, + canonicalFact: memory.content, expiresAtMs: memory.expiresAtMs ?? null, + target: memory.target, })), }, }; @@ -318,7 +319,7 @@ describe("memory plugin storage", () => { object: { decision: "store", target: "requester", - content: "Uses qa-structured-output in CLI QA.", + canonicalFact: "Uses qa-structured-output in CLI QA.", reason: null, expiresAtMs: null, }, @@ -347,7 +348,7 @@ describe("memory plugin storage", () => { object: { decision: "reject", target: null, - content: null, + canonicalFact: null, reason: "not_public_shareable", expiresAtMs: null, }, @@ -422,6 +423,51 @@ describe("memory plugin storage", () => { } }, 15_000); + it("deduplicates repeated passive observations for the same delivered turn", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: "Prefers passive observation retries to stay idempotent.", + target: "requester", + }, + ]); + const embedder = createTestEmbedder(); + const context = observationContext({ + db: memoryDb(fixture), + embedder, + model, + turnId: "local-turn-repeat", + userText: "I prefer passive observation retries to stay idempotent.", + }); + + await observeMemoryTurn(context); + await observeMemoryTurn(context); + + expect(calls).toHaveLength(2); + const rows = await memoryDb(fixture) + .select() + .from(memorySqlSchema.juniorMemoryMemories); + expect(rows).toEqual([ + expect.objectContaining({ + content: "Prefers passive observation retries to stay idempotent.", + scope: "personal", + sourcePlatform: "local", + subjectType: "user", + }), + ]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryEmbeddings), + ).resolves.toHaveLength(1); + expect(embedder.calls).toEqual([ + ["Prefers passive observation retries to stay idempotent."], + ]); + } finally { + await fixture.close(); + } + }, 15_000); + it("skips passive extraction for memory tool turns", async () => { const fixture = await createMemoryFixture(); diff --git a/packages/junior-plugin-api/package.json b/packages/junior-plugin-api/package.json index aed4035ae..075b95cb0 100644 --- a/packages/junior-plugin-api/package.json +++ b/packages/junior-plugin-api/package.json @@ -14,7 +14,6 @@ "exports": { ".": { "types": "./src/index.ts", - "development": "./src/index.ts", "default": "./dist/index.js" } }, diff --git a/packages/junior-plugin-api/src/context.ts b/packages/junior-plugin-api/src/context.ts index 76b623761..3b36ef7ab 100644 --- a/packages/junior-plugin-api/src/context.ts +++ b/packages/junior-plugin-api/src/context.ts @@ -153,14 +153,6 @@ export function isPrivateSource(source: Source): boolean { return source.type === "priv"; } -/** Return whether a source has a stable message or conversation identity. */ -export function hasStableSourceKey(source: Source): boolean { - if (source.platform === "local") { - return true; - } - return Boolean(source.threadTs ?? source.messageTs); -} - /** Return the stable source identity used for idempotency and attribution. */ export function getSourceKey(source: Source): string | undefined { if (source.platform === "local") { diff --git a/packages/junior-scheduler/package.json b/packages/junior-scheduler/package.json index 10be0b23e..d9151bdc1 100644 --- a/packages/junior-scheduler/package.json +++ b/packages/junior-scheduler/package.json @@ -14,7 +14,6 @@ "exports": { ".": { "types": "./src/index.ts", - "development": "./src/index.ts", "default": "./dist/index.js" } }, diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 7b9d94799..94256b27e 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -1070,6 +1070,21 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { traceId: getActiveTraceId(), }); } + preparedState.conversation = completedState.conversation; + persistedAtLeastOnce = true; + if (shouldEmitDevAgentTrace()) { + logInfo( + "agent_turn_completed", + turnTraceContext, + { + "app.ai.outcome": reply.diagnostics.outcome, + "app.ai.tool_call_count": reply.diagnostics.toolCalls.length, + "app.ai.tool_error_results": reply.diagnostics.toolErrorCount, + }, + "Agent turn completed", + ); + } + await options.onTurnCompleted?.(); if (reply.diagnostics.outcome === "success") { await observePluginTurn({ assistantText: reply.text, diff --git a/policies/evals.md b/policies/evals.md index 296a813fe..c1a0f8b29 100644 --- a/policies/evals.md +++ b/policies/evals.md @@ -8,6 +8,9 @@ Evals are integration tests for agent-facing behavior through the real runtime. - Keep prompts realistic; do not script the user request to make the eval pass. - Assert behavior invariants, not incidental wording or execution sequence. +- Do not patch product prompts with eval-shaped examples, fixture names, exact user messages, expected answers, or distinctive scenario phrases from eval files. +- When an eval fails, first state the general product invariant the failure exposed, then fix the product prompt or implementation at that invariant level. +- Product prompt examples must be neutral examples that are not reused from eval scenarios. - Treat the normalized `vitest-evals` session as the canonical eval surface for judges and assertions. - Use native `vitest-evals` harness support for ordered full-turn transcripts; do not add repo-local event logs or sequencing layers to simulate them. - Use `toolCalls(result.session)` or other `vitest-evals` primitives when tool/provider evidence is part of the behavior. @@ -18,3 +21,4 @@ Evals are integration tests for agent-facing behavior through the real runtime. ## Exceptions - Exact tokens, reply counts, or command details are acceptable only when they are the behavior under test. +- Shared vocabulary that is part of the product contract is allowed, but copied scenario phrases should be replaced with neutral prompt examples. From 0150ccfaa035b6698e149f35ff21713bd5c37716 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 19:30:50 -0700 Subject: [PATCH 05/29] fix(memory): Tighten passive observation inputs Pass successful tool results into post-turn observation so failed explicit memory attempts do not block passive extraction. Derive Slack memory source privacy from explicit runtime context instead of channel id prefixes, and observe the same queued text the agent answered. Also keep requester memories in canonical stored-fact form and leave deterministic listMemories behavior in storage tests rather than evals. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 53 ------------------- packages/junior-memory/src/agent.ts | 5 +- packages/junior-memory/tests/storage.test.ts | 42 ++++++++++++++- packages/junior/src/chat/local/runner.ts | 5 +- .../junior/src/chat/runtime/reply-executor.ts | 31 +++-------- .../junior/src/chat/runtime/slack-resume.ts | 19 ++++--- .../unit/misc/respond-helpers-tools.test.ts | 14 +++++ .../tests/unit/plugins/agent-hooks.test.ts | 18 +++++++ 8 files changed, 99 insertions(+), 88 deletions(-) create mode 100644 packages/junior/tests/unit/misc/respond-helpers-tools.test.ts diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index b64587c9c..a3adee6da 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -390,59 +390,6 @@ describeEval("Memory Workflows", slackEvals, (it) => { expect(await readMemories(thirdPartyRememberThread)).toEqual([]); }); - const listThread = { - id: "thread-memory-list", - channel_id: "CMEMORYLIST", - thread_ts: "17000000.memory-list", - }; - - it("listMemories reads visible memories before answering what Junior remembers", async ({ - run, - }) => { - const seeded = await seedMemory({ - content: "Prefers terse PR summaries.", - idempotencyKey: "eval-memory-list", - thread: listThread, - }); - - const result = await run({ - overrides: memoryPluginOverrides, - events: [ - mention( - "List the exact memories you have about how I like PR summaries, including the memory id.", - { - thread: listThread, - }, - ), - ], - criteria: rubric({ - pass: [ - "The assistant lists the stored memory about terse PR summaries.", - "The assistant includes a memory id or id prefix from the memory tool output.", - "The assistant does not ask the user to restate the preference.", - ], - fail: [ - "Do not answer as if no relevant memory exists.", - "Do not mention hidden storage fields, scope keys, or Slack ids.", - ], - }), - }); - - await expectAssistantMemoryAnswer({ - assistantText: visibleAssistantText(result), - expectedBehavior: - "The assistant lists the stored memory that the requester prefers terse PR summaries.", - }); - expectMemoryIdReference(visibleAssistantText(result), seeded.memory.id); - expect(await readMemories(listThread)).toEqual([ - expect.objectContaining({ - archivedAtMs: null, - content: "Prefers terse PR summaries.", - scope: "personal", - }), - ]); - }); - const searchThread = { id: "thread-memory-search", channel_id: "CMEMORYSEARCH", diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 5eaf6d73b..8737d6549 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -86,7 +86,7 @@ const extractedMemorySchema = z .string() .min(1) .describe( - "Canonical perspective-neutral fact. For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'. Do not include requester names, display names, 'the requester', 'the user', first-person wording like 'I', 'me', 'my', 'mine', 'we', or 'our', second-person wording like 'you' or 'your', 'this thread', or channel/source labels.", + "Canonical perspective-neutral fact. For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'. Do not include requester names, display names, 'the requester', 'the user', first-person wording like 'I', 'me', 'my', 'mine', 'we', or 'our', second-person wording like 'you' or 'your', 'this thread', or channel/source labels. Good: 'Prefers morning standup notes'. Bad: 'I prefer morning standup notes'. Bad: 'The requester prefers morning standup notes'.", ), expiresAtMs: z .number() @@ -156,6 +156,7 @@ const MEMORY_EXTRACTION_SYSTEM = [ "Extract only facts explicitly present in the user-authored message. Assistant text is rejection context only; never use assistant text, tool results, recalled memory text, or suggested wording as source evidence.", "Never store a fact merely because the assistant suggested or invented it. The user-authored text is the source of truth.", "For requester memories, omit the subject and use canonical phrasing such as 'Prefers X', 'Uses Y', or 'Thinks Z'; never output 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', a requester name, 'the requester', or 'the user'.", + "Requester memory content should read like a stored fact, not like a quote from the user. Convert 'I prefer X' into 'Prefers X', 'I use Y' into 'Uses Y', and 'I think Z' into 'Thinks Z'.", "Before returning a requester memory, self-check the content: if it could be read as the user's direct quote, rewrite it into omitted-subject canonical prose.", "Return one memory per distinct fact. If a first-person requester fact mentions a workstream, project, or conversation topic, keep that context inside the requester memory instead of also creating a conversation memory for the same fact.", "Advice, how-to, search, recall, and planning questions are not memories by themselves. Extract from those turns only when the user states a durable self-fact or shared project fact that remains true beyond the request.", @@ -278,7 +279,9 @@ function extractionPrompt(request: ExtractTurnRequest): string { "- Use target=conversation only for shared operational/project knowledge.", "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", + "- Requester memory content should never read like a direct user quote. Convert first-person statements into omitted-subject facts before returning them.", "- If the stored content would still sound like the user's direct quote, rewrite it before returning it.", + "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'I prefer morning standup notes'.", "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'The requester prefers morning standup notes'.", "- Good stored content: 'Thinks runtime logs should include request ids'. Bad stored content: 'David thinks runtime logs should include request ids'.", "- Good stored content: 'Release checklist lives in Linear'. Bad stored content: 'This thread says the release checklist lives in Linear'.", diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 4e4bdba9d..ac4462e91 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -210,6 +210,7 @@ function extractionModel( function slackContext( overrides: { channelId?: string; + sourceType?: "priv" | "pub"; teamId?: string; threadTs?: string; userId?: string; @@ -230,6 +231,7 @@ function slackContext( channelId, messageTs: threadTs, threadTs, + type: overrides.sourceType ?? "pub", }), }; } @@ -468,7 +470,7 @@ describe("memory plugin storage", () => { } }, 15_000); - it("skips passive extraction for memory tool turns", async () => { + it("skips passive extraction for successful memory tool turns", async () => { const fixture = await createMemoryFixture(); try { @@ -497,6 +499,39 @@ describe("memory plugin storage", () => { } }, 15_000); + it("extracts passive memories when an explicit memory tool did not succeed", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: "Prefers fallback passive extraction.", + target: "requester", + }, + ]); + + await observeMemoryTurn( + observationContext({ + db: memoryDb(fixture), + model, + toolCalls: [], + userText: "Remember that I prefer fallback passive extraction.", + }), + ); + + expect(calls).toHaveLength(1); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([ + expect.objectContaining({ + content: "Prefers fallback passive extraction.", + }), + ]); + } finally { + await fixture.close(); + } + }, 15_000); + it("skips passive extraction in private Slack contexts", async () => { const fixture = await createMemoryFixture(); @@ -507,7 +542,10 @@ describe("memory plugin storage", () => { target: "requester", }, ]); - const privateContext = slackContext({ channelId: "D123" }); + const privateContext = slackContext({ + channelId: "D123", + sourceType: "priv", + }); await observeMemoryTurn( observationContext({ diff --git a/packages/junior/src/chat/local/runner.ts b/packages/junior/src/chat/local/runner.ts index 477e60164..56df00f9f 100644 --- a/packages/junior/src/chat/local/runner.ts +++ b/packages/junior/src/chat/local/runner.ts @@ -24,6 +24,7 @@ import { import type { ToolExecutionReport } from "@/chat/tools/agent-tools"; import { THREAD_STATE_TTL_MS } from "chat"; import { + getSuccessfulToolCalls, stripRuntimeTurnContext, trimTrailingAssistantMessages, } from "@/chat/respond-helpers"; @@ -379,7 +380,9 @@ export async function runLocalAgentTurn( } await observePluginTurn({ assistantText: reply.text, - toolCalls: reply.diagnostics.toolCalls, + toolCalls: reply.piMessages + ? getSuccessfulToolCalls(reply.piMessages) + : reply.diagnostics.toolCalls, turnId, context: { conversationId: input.conversationId, diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 94256b27e..c2d822ca2 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -118,6 +118,7 @@ import { } from "@/chat/state/conversation-details"; import { loadProjection } from "@/chat/state/session-log"; import { + getSuccessfulToolCalls, stripRuntimeTurnContext, trimTrailingAssistantMessages, } from "@/chat/respond-helpers"; @@ -863,8 +864,8 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { omittedImageAttachmentCount, userAttachments, slackConversation, - destination, source, + destination, surface: "slack", turnDeadlineAtMs: getTurnRequestDeadline()?.deadlineAtMs, correlation: { @@ -1088,37 +1089,19 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { if (reply.diagnostics.outcome === "success") { await observePluginTurn({ assistantText: reply.text, - toolCalls: reply.diagnostics.toolCalls, + toolCalls: reply.piMessages + ? getSuccessfulToolCalls(reply.piMessages) + : reply.diagnostics.toolCalls, turnId, context: { ...(conversationId ? { conversationId } : {}), destination, requester: requesterIdentity, - source: createSlackSource({ - teamId: destination.teamId, - channelId: destination.channelId, - ...(messageTs ? { messageTs } : {}), - ...(threadTs ? { threadTs } : {}), - }), - userText: currentText.userText, + source, + userText: effectiveUserText, }, }); } - preparedState.conversation = completedState.conversation; - persistedAtLeastOnce = true; - if (shouldEmitDevAgentTrace()) { - logInfo( - "agent_turn_completed", - turnTraceContext, - { - "app.ai.outcome": reply.diagnostics.outcome, - "app.ai.tool_call_count": reply.diagnostics.toolCalls.length, - "app.ai.tool_error_results": reply.diagnostics.toolErrorCount, - }, - "Agent turn completed", - ); - } - await options.onTurnCompleted?.(); if (reply.diagnostics.outcome === "success" && conversationId) { try { await deps.services.scheduleSessionCompletedPluginTasks({ diff --git a/packages/junior/src/chat/runtime/slack-resume.ts b/packages/junior/src/chat/runtime/slack-resume.ts index 443c9a310..ab9aac829 100644 --- a/packages/junior/src/chat/runtime/slack-resume.ts +++ b/packages/junior/src/chat/runtime/slack-resume.ts @@ -22,6 +22,7 @@ import { finalizeFailedTurnReply, requireTurnFailureEventId, } from "@/chat/services/turn-failure-response"; +import { getSuccessfulToolCalls } from "@/chat/respond-helpers"; import { persistThreadStateById } from "@/chat/runtime/thread-state"; import { createSlackWebApiAssistantStatusSession, @@ -413,7 +414,9 @@ export async function resumeSlackTurn( ) { await observePluginTurn({ assistantText: reply.text, - toolCalls: reply.diagnostics.toolCalls, + toolCalls: reply.piMessages + ? getSuccessfulToolCalls(reply.piMessages) + : reply.diagnostics.toolCalls, turnId: replyContext.correlation?.turnId ?? lockKey, context: { conversationId: replyContext.correlation?.conversationId ?? lockKey, @@ -421,12 +424,14 @@ export async function resumeSlackTurn( ...(replyContext.requester ? { requester: replyContext.requester } : {}), - source: createSlackSource({ - teamId: replyContext.destination.teamId, - channelId: replyContext.destination.channelId, - ...(runArgs.messageTs ? { messageTs: runArgs.messageTs } : {}), - threadTs: runArgs.threadTs, - }), + source: + replyContext.source ?? + createSlackSource({ + teamId: replyContext.destination.teamId, + channelId: replyContext.destination.channelId, + ...(runArgs.messageTs ? { messageTs: runArgs.messageTs } : {}), + threadTs: runArgs.threadTs, + }), userText: runArgs.messageText, }, }); diff --git a/packages/junior/tests/unit/misc/respond-helpers-tools.test.ts b/packages/junior/tests/unit/misc/respond-helpers-tools.test.ts new file mode 100644 index 000000000..7ec9278a4 --- /dev/null +++ b/packages/junior/tests/unit/misc/respond-helpers-tools.test.ts @@ -0,0 +1,14 @@ +import { describe, expect, it } from "vitest"; +import { getSuccessfulToolCalls } from "@/chat/respond-helpers"; + +describe("getSuccessfulToolCalls", () => { + it("omits failed tool results", () => { + expect( + getSuccessfulToolCalls([ + { role: "toolResult", toolName: "createMemory", isError: true }, + { role: "toolResult", toolName: "searchMemories", isError: false }, + { role: "toolResult", name: "removeMemory" }, + ]), + ).toEqual(["searchMemories", "removeMemory"]); + }); +}); diff --git a/packages/junior/tests/unit/plugins/agent-hooks.test.ts b/packages/junior/tests/unit/plugins/agent-hooks.test.ts index 6c5006b7b..5d27affe2 100644 --- a/packages/junior/tests/unit/plugins/agent-hooks.test.ts +++ b/packages/junior/tests/unit/plugins/agent-hooks.test.ts @@ -111,6 +111,24 @@ function fakeSandbox( } describe("agent plugin hooks", () => { + it("keeps Slack sources private unless the caller marks them public", () => { + expect( + createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "1718800000.000000", + }).type, + ).toBe("priv"); + expect( + createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "1718800000.000000", + type: "pub", + }).type, + ).toBe("pub"); + }); + it("collects system prompt contributions from configured plugins", async () => { const previous = setPlugins([ defineJuniorPlugin({ From be427d7e5adb8d08ea2e9f17e20baaff32d5577c Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 23:00:11 -0700 Subject: [PATCH 06/29] fix(memory): Preserve source across resumed runs Persist the normalized run source through auth, timeout, and continuation state so resumed Slack turns reuse the original source instead of reconstructing one. Require source at Slack resume boundaries and tighten tests to prove stored sources are forwarded. Remove deterministic memory tool mechanics from eval assertions so evals stay focused on model-facing behavior. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 86 +++---------------- packages/junior/src/chat/mcp/auth-store.ts | 15 +++- packages/junior/src/chat/mcp/oauth.ts | 4 +- packages/junior/src/chat/oauth-flow.ts | 25 +++++- packages/junior/src/chat/respond.ts | 5 ++ .../src/chat/runtime/agent-continue-runner.ts | 18 ++-- .../junior/src/chat/runtime/reply-executor.ts | 1 + .../junior/src/chat/runtime/slack-resume.ts | 14 +-- .../chat/services/mcp-auth-orchestration.ts | 4 +- .../services/plugin-auth-orchestration.ts | 4 +- .../junior/src/handlers/mcp-oauth-callback.ts | 19 ++-- .../junior/src/handlers/oauth-callback.ts | 29 +++---- .../runtime/agent-continue-runner.test.ts | 2 +- .../services/turn-session-record.test.ts | 14 ++- .../integration/agent-continue-slack.test.ts | 11 ++- .../mcp-oauth-callback-slack.test.ts | 23 ++++- .../integration/oauth-callback-slack.test.ts | 25 +++++- .../integration/oauth-resume-slack.test.ts | 10 ++- .../tests/unit/handlers/oauth-resume.test.ts | 13 +-- .../services/mcp-auth-orchestration.test.ts | 15 ++++ .../plugin-auth-orchestration.test.ts | 11 +++ 21 files changed, 209 insertions(+), 139 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index a3adee6da..210643866 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -188,14 +188,6 @@ async function expectAssistantMemoryAnswer(args: { ); } -function expectMemoryIdReference(text: string, memoryId: string): void { - expect( - Array.from({ length: memoryId.length - 11 }, (_, index) => - memoryId.slice(0, index + 12), - ).some((prefix) => text.includes(prefix)), - ).toBe(true); -} - afterEach(async () => { await closeDb(); }); @@ -390,67 +382,6 @@ describeEval("Memory Workflows", slackEvals, (it) => { expect(await readMemories(thirdPartyRememberThread)).toEqual([]); }); - const searchThread = { - id: "thread-memory-search", - channel_id: "CMEMORYSEARCH", - thread_ts: "17000000.memory-search", - }; - - it("searchMemories finds the relevant stored memory for a targeted recall request", async ({ - run, - }) => { - const match = await seedMemory({ - content: "Prefers incident reports with bullet summaries.", - idempotencyKey: "eval-memory-search-match", - thread: searchThread, - }); - await seedMemory({ - content: "Prefers terse PR summaries.", - idempotencyKey: "eval-memory-search-distractor", - thread: searchThread, - }); - - const result = await run({ - overrides: memoryPluginOverrides, - events: [ - mention( - "Search memory for my incident report preference and include the matching memory id with the answer.", - { - thread: searchThread, - }, - ), - ], - criteria: rubric({ - pass: [ - "The assistant answers from memory that the user likes incident reports with bullet summaries.", - "The assistant includes the matching memory id or id prefix from the memory search result.", - "The assistant does not substitute the unrelated PR summary preference.", - ], - fail: [ - "Do not answer from the unrelated PR summary memory.", - "Do not ask the user to restate the incident report preference.", - ], - }), - }); - - await expectAssistantMemoryAnswer({ - assistantText: visibleAssistantText(result), - expectedBehavior: - "The assistant answers from memory that the requester prefers incident reports with bullet summaries and includes the requested matching memory id or id prefix.", - }); - expectMemoryIdReference(visibleAssistantText(result), match.memory.id); - expect(await readMemories(searchThread)).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - content: "Prefers incident reports with bullet summaries.", - }), - expect.objectContaining({ - content: "Prefers terse PR summaries.", - }), - ]), - ); - }); - const autoRecallThread = { id: "thread-memory-auto-recall", channel_id: "CMEMORYAUTORECALL", @@ -500,7 +431,9 @@ describeEval("Memory Workflows", slackEvals, (it) => { thread_ts: "17000000.memory-remove", }; - it("removeMemory archives the selected stored memory", async ({ run }) => { + it("when asked to forget a remembered preference, archive the matching memory", async ({ + run, + }) => { await seedMemory({ content: "Prefers terse PR summaries.", idempotencyKey: "eval-memory-remove", @@ -516,7 +449,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { ], criteria: rubric({ pass: [ - "The assistant removes the matching stored memory.", + "The assistant understands the forget request and removes the matching remembered preference.", "The assistant does not ask the user for hidden ids or scope fields.", ], fail: [ @@ -526,12 +459,19 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - expect(await readMemories(removeThread)).toEqual([ + const memories = await readMemories(removeThread); + expect(memories).toEqual([ expect.objectContaining({ archivedAtMs: expect.any(Number), - archiveReason: "tool_removed", content: "Prefers terse PR summaries.", }), ]); + expect( + memories.filter( + (memory) => + memory.content === "Prefers terse PR summaries." && + memory.archivedAtMs === null, + ), + ).toEqual([]); }); }); diff --git a/packages/junior/src/chat/mcp/auth-store.ts b/packages/junior/src/chat/mcp/auth-store.ts index 73ac74a62..3c1f4746b 100644 --- a/packages/junior/src/chat/mcp/auth-store.ts +++ b/packages/junior/src/chat/mcp/auth-store.ts @@ -3,7 +3,11 @@ import type { OAuthTokens, } from "@modelcontextprotocol/sdk/shared/auth.js"; import type { OAuthDiscoveryState } from "@modelcontextprotocol/sdk/client/auth.js"; -import type { Destination } from "@sentry/junior-plugin-api"; +import { + sourceSchema, + type Destination, + type Source, +} from "@sentry/junior-plugin-api"; import { parseDestination } from "@/chat/destination"; import type { ThreadArtifactsState } from "@/chat/state/artifacts"; import { isRecord } from "@/chat/coerce"; @@ -23,6 +27,7 @@ export interface McpAuthSessionState { userId: string; conversationId: string; destination?: Destination; + source?: Source; sessionId: string; userMessage: string; channelId?: string; @@ -112,6 +117,13 @@ function parseMcpAuthSession(value: unknown): McpAuthSessionState | undefined { if (parsed.destination !== undefined && !destination) { return undefined; } + const source = + parsed.source === undefined + ? undefined + : sourceSchema.safeParse(parsed.source); + if (parsed.source !== undefined && (!source || !source.success)) { + return undefined; + } return { authSessionId: parsed.authSessionId, @@ -119,6 +131,7 @@ function parseMcpAuthSession(value: unknown): McpAuthSessionState | undefined { userId: parsed.userId, conversationId: parsed.conversationId, ...(destination ? { destination } : {}), + ...(source?.success ? { source: source.data } : {}), sessionId: parsed.sessionId, userMessage: parsed.userMessage, createdAtMs: parsed.createdAtMs, diff --git a/packages/junior/src/chat/mcp/oauth.ts b/packages/junior/src/chat/mcp/oauth.ts index 164031735..2a83994f9 100644 --- a/packages/junior/src/chat/mcp/oauth.ts +++ b/packages/junior/src/chat/mcp/oauth.ts @@ -1,6 +1,6 @@ import { randomUUID } from "node:crypto"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; -import type { Destination } from "@sentry/junior-plugin-api"; +import type { Destination, Source } from "@sentry/junior-plugin-api"; import { resolveBaseUrl } from "@/chat/oauth-flow"; import { getPluginDefinition } from "@/chat/plugins/registry"; import type { PluginDefinition } from "@/chat/plugins/types"; @@ -29,6 +29,7 @@ export async function createMcpOAuthClientProvider(input: { provider: string; conversationId: string; destination?: Destination; + source?: Source; sessionId: string; userId: string; userMessage: string; @@ -66,6 +67,7 @@ export async function createMcpOAuthClientProvider(input: { userId: input.userId, conversationId: input.conversationId, ...(input.destination ? { destination: input.destination } : {}), + ...(input.source ? { source: input.source } : {}), sessionId: input.sessionId, userMessage: input.userMessage, ...(input.channelId ? { channelId: input.channelId } : {}), diff --git a/packages/junior/src/chat/oauth-flow.ts b/packages/junior/src/chat/oauth-flow.ts index 0d97c61b5..0aa5cbd59 100644 --- a/packages/junior/src/chat/oauth-flow.ts +++ b/packages/junior/src/chat/oauth-flow.ts @@ -1,5 +1,9 @@ import { randomBytes } from "node:crypto"; -import type { Destination } from "@sentry/junior-plugin-api"; +import { + sourceSchema, + type Destination, + type Source, +} from "@sentry/junior-plugin-api"; import type { ChannelConfigurationService } from "@/chat/configuration/types"; import { parseDestination } from "@/chat/destination"; import { logInfo, logWarn } from "@/chat/logging"; @@ -22,6 +26,7 @@ export type OAuthStatePayload = { provider: string; channelId?: string; destination?: Destination; + source?: Source; threadTs?: string; pendingMessage?: string; configuration?: Record; @@ -34,6 +39,7 @@ type OAuthFlowInput = { requesterId: string; channelId?: string; destination?: Destination; + source?: Source; threadTs?: string; userMessage?: string; channelConfiguration?: ChannelConfigurationService; @@ -63,6 +69,17 @@ export function parseOAuthStatePayload( if (value.destination !== undefined && !destination) { return undefined; } + const source = + value.source === undefined + ? undefined + : sourceSchema.safeParse(value.source); + if (value.source !== undefined && (!source || !source.success)) { + return undefined; + } + const pendingMessage = optionalString(value.pendingMessage); + if (pendingMessage && !source?.success) { + return undefined; + } return { userId: value.userId, provider: value.provider, @@ -70,12 +87,11 @@ export function parseOAuthStatePayload( ? { channelId: optionalString(value.channelId) } : {}), ...(destination ? { destination } : {}), + ...(source?.success ? { source: source.data } : {}), ...(optionalString(value.threadTs) ? { threadTs: optionalString(value.threadTs) } : {}), - ...(optionalString(value.pendingMessage) - ? { pendingMessage: optionalString(value.pendingMessage) } - : {}), + ...(pendingMessage ? { pendingMessage } : {}), ...(isRecord(value.configuration) ? { configuration: value.configuration } : {}), @@ -241,6 +257,7 @@ export async function startOAuthFlow( provider, ...(input.channelId ? { channelId: input.channelId } : {}), ...(input.destination ? { destination: input.destination } : {}), + ...(input.source ? { source: input.source } : {}), ...(input.threadTs ? { threadTs: input.threadTs } : {}), ...(input.userMessage ? { pendingMessage: input.userMessage } : {}), ...(configuration && Object.keys(configuration).length > 0 diff --git a/packages/junior/src/chat/respond.ts b/packages/junior/src/chat/respond.ts index 7ae5743ef..4c3081cc1 100644 --- a/packages/junior/src/chat/respond.ts +++ b/packages/junior/src/chat/respond.ts @@ -1014,6 +1014,7 @@ export async function generateAssistantReply( requesterId: authRequesterId, channelId: slackChannelId, destination: context.destination, + source: runSource, threadTs: context.correlation?.threadTs, toolChannelId: context.toolChannelId, userMessage: userInput, @@ -1032,6 +1033,7 @@ export async function generateAssistantReply( requesterId: authRequesterId, channelId: slackChannelId, destination: context.destination, + source: runSource, threadTs: context.correlation?.threadTs, userMessage: userInput, channelConfiguration: context.channelConfiguration, @@ -1790,6 +1792,7 @@ export async function generateAssistantReply( currentUsage: turnUsage, messages: timeoutResumeMessages, errorMessage: error.message, + source: runSource, loadedSkillNames: loadedSkillNamesForResume, logContext: sessionRecordLogContext, requester, @@ -1819,6 +1822,7 @@ export async function generateAssistantReply( currentUsage: turnUsage, messages: timeoutResumeMessages, errorMessage: error instanceof Error ? error.message : String(error), + source: runSource, loadedSkillNames: loadedSkillNamesForResume, logContext: sessionRecordLogContext, requester, @@ -1871,6 +1875,7 @@ export async function generateAssistantReply( currentUsage: turnUsage, messages: timeoutResumeMessages, errorMessage: error.message, + source: runSource, loadedSkillNames: loadedSkillNamesForResume, logContext: sessionRecordLogContext, requester, diff --git a/packages/junior/src/chat/runtime/agent-continue-runner.ts b/packages/junior/src/chat/runtime/agent-continue-runner.ts index 5d869ebea..6577b9086 100644 --- a/packages/junior/src/chat/runtime/agent-continue-runner.ts +++ b/packages/junior/src/chat/runtime/agent-continue-runner.ts @@ -273,15 +273,15 @@ export async function continueSlackAgentRun( teamId: destination.teamId, userId: userMessage.author.userId, }); - // TODO(v0.76.0): Remove once pre-source awaiting_resume Slack records have drained. - const source = - activeSessionRecord.source ?? - createSlackSource({ - channelId: destination.channelId, - messageTs: getTurnUserSlackMessageTs(userMessage), - teamId: destination.teamId, - threadTs: thread.threadTs, + if (!activeSessionRecord.source) { + await failAgentTurnSessionRecord({ + conversationId: payload.conversationId, + expectedVersion: activeSessionRecord.version, + sessionId: payload.sessionId, + errorMessage: "Stored Slack source missing for continuation", }); + return false; + } return { messageText: userMessage.text, @@ -295,7 +295,7 @@ export async function continueSlackAgentRun( }, requester, destination: payload.destination, - source, + source: activeSessionRecord.source, correlation: { conversationId: payload.conversationId, turnId: payload.sessionId, diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index c2d822ca2..3137622af 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -1261,6 +1261,7 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { state: "failed", requester, destination, + source, traceId: getActiveTraceId(), }); const sessionRecord = await getAgentTurnSessionRecord( diff --git a/packages/junior/src/chat/runtime/slack-resume.ts b/packages/junior/src/chat/runtime/slack-resume.ts index ab9aac829..96be10ee9 100644 --- a/packages/junior/src/chat/runtime/slack-resume.ts +++ b/packages/junior/src/chat/runtime/slack-resume.ts @@ -1,5 +1,4 @@ import { botConfig } from "@/chat/config"; -import { createSlackSource } from "@sentry/junior-plugin-api"; import type { ChannelConfigurationService } from "@/chat/configuration/types"; import { generateAssistantReply, @@ -117,7 +116,7 @@ interface ResumeSlackTurnArgs { channelId: string; threadTs: string; messageTs?: string; - replyContext?: AssistantReplyRequestContext; + replyContext?: ResumeReplyContext; lockKey?: string; initialText?: string; generateReply?: typeof generateAssistantReply; @@ -424,14 +423,7 @@ export async function resumeSlackTurn( ...(replyContext.requester ? { requester: replyContext.requester } : {}), - source: - replyContext.source ?? - createSlackSource({ - teamId: replyContext.destination.teamId, - channelId: replyContext.destination.channelId, - ...(runArgs.messageTs ? { messageTs: runArgs.messageTs } : {}), - threadTs: runArgs.threadTs, - }), + source: replyContext.source, userText: runArgs.messageText, }, }); @@ -543,7 +535,7 @@ export async function resumeAuthorizedRequest(args: { threadTs: string; messageTs?: string; connectedText: string; - replyContext?: AssistantReplyRequestContext; + replyContext?: ResumeReplyContext; lockKey?: string; generateReply?: typeof generateAssistantReply; onSuccess?: (reply: AssistantReply) => Promise; diff --git a/packages/junior/src/chat/services/mcp-auth-orchestration.ts b/packages/junior/src/chat/services/mcp-auth-orchestration.ts index 72c6d13df..b5ba3c8f9 100644 --- a/packages/junior/src/chat/services/mcp-auth-orchestration.ts +++ b/packages/junior/src/chat/services/mcp-auth-orchestration.ts @@ -8,7 +8,7 @@ */ import { THREAD_STATE_TTL_MS } from "chat"; import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js"; -import type { Destination } from "@sentry/junior-plugin-api"; +import type { Destination, Source } from "@sentry/junior-plugin-api"; import { createMcpOAuthClientProvider } from "@/chat/mcp/oauth"; import { deleteMcpAuthSession, @@ -44,6 +44,7 @@ export interface McpAuthOrchestrationInput { requesterId?: string; channelId?: string; destination?: Destination; + source?: Source; threadTs?: string; toolChannelId?: string; userMessage: string; @@ -99,6 +100,7 @@ export function createMcpAuthOrchestration( provider: plugin.manifest.name, conversationId: input.conversationId, destination: input.destination, + source: input.source, sessionId: input.sessionId, userId: input.requesterId, userMessage: input.userMessage, diff --git a/packages/junior/src/chat/services/plugin-auth-orchestration.ts b/packages/junior/src/chat/services/plugin-auth-orchestration.ts index 4952276ff..c66c86890 100644 --- a/packages/junior/src/chat/services/plugin-auth-orchestration.ts +++ b/packages/junior/src/chat/services/plugin-auth-orchestration.ts @@ -11,7 +11,7 @@ * stdout patterns, or exit codes. */ import { THREAD_STATE_TTL_MS } from "chat"; -import type { Destination } from "@sentry/junior-plugin-api"; +import type { Destination, Source } from "@sentry/junior-plugin-api"; import type { ChannelConfigurationService } from "@/chat/configuration/types"; import { unlinkProvider } from "@/chat/credentials/unlink-provider"; import type { UserTokenStore } from "@/chat/credentials/user-token-store"; @@ -54,6 +54,7 @@ export interface PluginAuthOrchestrationInput { requesterId?: string; channelId?: string; destination?: Destination; + source?: Source; threadTs?: string; userMessage: string; channelConfiguration?: ChannelConfigurationService; @@ -171,6 +172,7 @@ export function createPluginAuthOrchestration( requesterId: input.requesterId, channelId: input.channelId, destination: input.destination, + source: input.source, threadTs: input.threadTs, userMessage: input.userMessage, channelConfiguration: input.channelConfiguration, diff --git a/packages/junior/src/handlers/mcp-oauth-callback.ts b/packages/junior/src/handlers/mcp-oauth-callback.ts index 0915482ca..0e0380891 100644 --- a/packages/junior/src/handlers/mcp-oauth-callback.ts +++ b/packages/junior/src/handlers/mcp-oauth-callback.ts @@ -57,7 +57,6 @@ import { type Requester, } from "@/chat/requester"; import { requireSlackDestination } from "@/chat/destination"; -import { createSlackSource } from "@sentry/junior-plugin-api"; const CALLBACK_PAGES = { missing_state: { @@ -325,6 +324,15 @@ async function resumeAuthorizedMcpTurn(args: { }); return false; } + if (!lockedSessionRecord.source) { + await failAgentTurnSessionRecord({ + conversationId: authSession.conversationId, + expectedVersion: lockedSessionRecord.version, + sessionId: lockedSessionId, + errorMessage: "Stored Slack source missing for MCP OAuth resume", + }); + return false; + } await recordAuthorizationCompleted({ conversationId: authSession.conversationId, @@ -348,14 +356,7 @@ async function resumeAuthorizedMcpTurn(args: { }, requester, destination, - source: - lockedSessionRecord.source ?? - createSlackSource({ - teamId: destination.teamId, - channelId: authSession.channelId!, - threadTs: authSession.threadTs!, - ...(lockedMessageTs ? { messageTs: lockedMessageTs } : {}), - }), + source: lockedSessionRecord.source, correlation: { conversationId: authSession.conversationId, turnId: lockedSessionId, diff --git a/packages/junior/src/handlers/oauth-callback.ts b/packages/junior/src/handlers/oauth-callback.ts index dead669db..fed81a5fe 100644 --- a/packages/junior/src/handlers/oauth-callback.ts +++ b/packages/junior/src/handlers/oauth-callback.ts @@ -67,7 +67,6 @@ import type { WaitUntilFn } from "@/handlers/types"; import { scheduleAgentContinue } from "@/chat/services/agent-continue"; import type { AssistantReply, generateAssistantReply } from "@/chat/respond"; import { requireSlackDestination } from "@/chat/destination"; -import { createSlackSource } from "@sentry/junior-plugin-api"; interface OAuthCallbackOptions { generateReply?: typeof generateAssistantReply; @@ -182,6 +181,7 @@ async function resumeOAuthSessionRecordTurn( !stored.resumeSessionId || !stored.channelId || !stored.destination || + !stored.source || !stored.threadTs ) { return false; @@ -350,6 +350,15 @@ async function resumeOAuthSessionRecordTurn( }); return false; } + if (!lockedSessionRecord.source) { + await failAgentTurnSessionRecord({ + conversationId: stored.resumeConversationId!, + expectedVersion: lockedSessionRecord.version, + sessionId: lockedSessionId, + errorMessage: "Stored Slack source missing for OAuth resume", + }); + return false; + } await recordAuthorizationCompleted({ conversationId: stored.resumeConversationId!, @@ -378,14 +387,7 @@ async function resumeOAuthSessionRecordTurn( }, requester, destination, - source: - lockedSessionRecord.source ?? - createSlackSource({ - teamId: destination.teamId, - channelId: stored.channelId!, - threadTs: stored.threadTs!, - ...(lockedMessageTs ? { messageTs: lockedMessageTs } : {}), - }), + source: lockedSessionRecord.source, correlation: { conversationId: stored.resumeConversationId!, turnId: lockedSessionId, @@ -480,10 +482,12 @@ async function resumePendingOAuthMessage( stored: OAuthStatePayload, options: OAuthCallbackOptions, ): Promise { + const source = stored.source; if ( !stored.pendingMessage || !stored.channelId || !stored.destination || + !source || !stored.threadTs ) { return; @@ -521,12 +525,7 @@ async function resumePendingOAuthMessage( }, requester, destination: stored.destination, - source: createSlackSource({ - teamId: destination.teamId, - channelId: stored.channelId, - threadTs: stored.threadTs, - ...(messageTs ? { messageTs } : {}), - }), + source, correlation: { conversationId: threadId, channelId: stored.channelId, diff --git a/packages/junior/tests/component/runtime/agent-continue-runner.test.ts b/packages/junior/tests/component/runtime/agent-continue-runner.test.ts index 1c4d2a8d0..89cb43ca0 100644 --- a/packages/junior/tests/component/runtime/agent-continue-runner.test.ts +++ b/packages/junior/tests/component/runtime/agent-continue-runner.test.ts @@ -1,6 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { disconnectStateAdapter } from "@/chat/state/adapter"; import { createSlackSource } from "@sentry/junior-plugin-api"; +import { disconnectStateAdapter } from "@/chat/state/adapter"; import { persistThreadStateById } from "@/chat/runtime/thread-state"; import { getAgentTurnSessionRecord, diff --git a/packages/junior/tests/component/services/turn-session-record.test.ts b/packages/junior/tests/component/services/turn-session-record.test.ts index 7b3a2bc75..d729861cf 100644 --- a/packages/junior/tests/component/services/turn-session-record.test.ts +++ b/packages/junior/tests/component/services/turn-session-record.test.ts @@ -1,5 +1,9 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import type { Destination } from "@sentry/junior-plugin-api"; +import { + createSlackSource, + type Destination, + type Source, +} from "@sentry/junior-plugin-api"; import type { ConversationStore } from "@/chat/conversations/store"; import type { PiMessage } from "@/chat/pi/messages"; @@ -9,6 +13,12 @@ const SLACK_DESTINATION = { teamId: "T123", channelId: "C123", } as const satisfies Destination; +const SLACK_SOURCE = createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "1700000000.001", + type: "pub", +}) satisfies Source; function userMessage(text: string): PiMessage { return { @@ -89,6 +99,7 @@ describe("persistAuthPauseSessionRecord", () => { sessionId: "turn-1", sliceId: 1, state: "awaiting_resume", + source: SLACK_SOURCE, piMessages: priorMessages, resumeReason: "auth", errorMessage: "initial auth pause", @@ -117,6 +128,7 @@ describe("persistAuthPauseSessionRecord", () => { resumedFromSliceId: 1, resumeReason: "auth", errorMessage: "plugin auth pause", + source: SLACK_SOURCE, piMessages: [priorMessages[0]], }); }); diff --git a/packages/junior/tests/integration/agent-continue-slack.test.ts b/packages/junior/tests/integration/agent-continue-slack.test.ts index 090369b71..53e1bd54f 100644 --- a/packages/junior/tests/integration/agent-continue-slack.test.ts +++ b/packages/junior/tests/integration/agent-continue-slack.test.ts @@ -1,5 +1,6 @@ import { Buffer } from "node:buffer"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { SLACK_DESTINATION, createConversationWorkQueueTestAdapter, @@ -7,7 +8,6 @@ import { } from "../fixtures/conversation-work"; import { slackApiOutbox } from "../fixtures/slack-api-outbox"; import { resetSlackApiMockState } from "../msw/handlers/slack-api"; -import { createSlackSource } from "@sentry/junior-plugin-api"; const generateAssistantReplyMock = vi.fn(); @@ -104,6 +104,12 @@ describe("agent continuation Slack integration", () => { it("posts the resumed reply through the Slack MSW harness and persists completion", async () => { const conversationId = "slack:C123:1712345.0001"; const sessionId = "turn_msg_1"; + const storedSource = createSlackSource({ + teamId: "T123", + channelId: "C123", + messageTs: "1712345.continue-source", + threadTs: "1712345.0001", + }); const sessionRecord = await turnSessionStoreModule.upsertAgentTurnSessionRecord({ conversationId, @@ -111,7 +117,7 @@ describe("agent continuation Slack integration", () => { sliceId: 2, state: "awaiting_resume", destination: SLACK_DESTINATION, - source: slackSource("1712345.0001"), + source: storedSource, piMessages: [ { role: "user", @@ -195,6 +201,7 @@ describe("agent continuation Slack integration", () => { userName: "testuser", }), destination: SLACK_DESTINATION, + source: storedSource, toolChannelId: "C999", inboundAttachmentCount: 2, omittedImageAttachmentCount: 1, diff --git a/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts b/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts index 01dff157a..13947a81c 100644 --- a/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts +++ b/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts @@ -1,5 +1,6 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource, type Source } from "@sentry/junior-plugin-api"; import { EVAL_MCP_AUTH_CODE, EVAL_MCP_AUTH_PROVIDER, @@ -13,7 +14,6 @@ import { createPluginAppFixture, type PluginAppFixture, } from "../fixtures/plugin-app"; -import { createSlackSource } from "@sentry/junior-plugin-api"; const { generateAssistantReplyMock } = vi.hoisted(() => ({ generateAssistantReplyMock: vi.fn(), @@ -80,6 +80,7 @@ async function createPendingAuthSession(args: { userMessage: args.userMessage, channelId: args.channelId, threadTs: args.threadTs, + source: slackSource(args.threadTs), }); const plugin = pluginRegistryModule.getPluginDefinition( @@ -110,6 +111,7 @@ async function createAwaitingMcpTurnRecord(args: { }; includeSource?: boolean; sessionId: string; + source?: Source; text: string; threadTs: string; }) { @@ -121,7 +123,7 @@ async function createAwaitingMcpTurnRecord(args: { destination: SLACK_DESTINATION, ...(args.includeSource === false ? {} - : { source: slackSource(args.threadTs) }), + : { source: args.source ?? slackSource(args.threadTs) }), piMessages: [ { role: "user", @@ -184,6 +186,13 @@ describe("mcp oauth callback slack integration", () => { it("finalizes MCP OAuth and resumes the stored thread with persisted context", async () => { const threadId = "slack:C123:1700000000.001"; const sessionId = "turn_user-1"; + const storedSource = createSlackSource({ + teamId: "T123", + channelId: "C123", + messageTs: "1700000000.mcp-source", + threadTs: "1700000000.001", + type: "pub", + }); await stateAdapterModule.getStateAdapter().set(`thread-state:${threadId}`, { conversation: { @@ -254,6 +263,7 @@ describe("mcp oauth callback slack integration", () => { email: "stored@example.com", }, sessionId, + source: storedSource, text: "what did i say about the budget?", threadTs: "1700000000.001", }); @@ -267,6 +277,7 @@ describe("mcp oauth callback slack integration", () => { userMessage: "what did i say about the budget?", channelId: "C123", threadTs: "1700000000.001", + source: storedSource, toolChannelId: "C999", configuration: { region: "us", @@ -303,6 +314,7 @@ describe("mcp oauth callback slack integration", () => { userMessage: "what did i say about the budget?", channelId: "C123", threadTs: "1700000000.001", + source: storedSource, toolChannelId: "C999", configuration: { region: "us", @@ -352,6 +364,7 @@ describe("mcp oauth callback slack integration", () => { userName: "stored-user", }), destination: SLACK_DESTINATION, + source: storedSource, toolChannelId: "C999", inboundAttachmentCount: 1, omittedImageAttachmentCount: 1, @@ -368,6 +381,7 @@ describe("mcp oauth callback slack integration", () => { const resumeContext = generateAssistantReplyMock.mock.calls[0]?.[1] as { conversationContext?: string; configuration?: Record; + source?: unknown; }; expect(resumeContext.conversationContext).not.toContain( "what did i say about the budget?", @@ -467,6 +481,7 @@ describe("mcp oauth callback slack integration", () => { slackUserId: "U123", }, sessionId, + source: slackSource("1700000000.006"), text: "what did i say about the budget?", threadTs: "1700000000.006", }); @@ -595,6 +610,7 @@ describe("mcp oauth callback slack integration", () => { conversationId: threadId, includeSource: false, sessionId, + source: slackSource("1700000000.005"), text: "what did i say about the budget?", threadTs: "1700000000.005", }); @@ -837,6 +853,7 @@ describe("mcp oauth callback slack integration", () => { slackUserName: "wrong-user", }, sessionId, + source: slackSource("1700000000.007"), text: "list mcp data", threadTs: "1700000000.007", }); @@ -921,6 +938,7 @@ describe("mcp oauth callback slack integration", () => { await createAwaitingMcpTurnRecord({ conversationId: "conversation-2", sessionId: "turn_msg_2", + source: slackSource("1700000000.002"), text: "/demo upload", threadTs: "1700000000.002", }); @@ -1006,6 +1024,7 @@ describe("mcp oauth callback slack integration", () => { await createAwaitingMcpTurnRecord({ conversationId: "conversation-3", sessionId: "turn_msg_3", + source: slackSource("1700000000.003"), text: "/demo upload", threadTs: "1700000000.003", }); diff --git a/packages/junior/tests/integration/oauth-callback-slack.test.ts b/packages/junior/tests/integration/oauth-callback-slack.test.ts index 925f78da1..85dcd3650 100644 --- a/packages/junior/tests/integration/oauth-callback-slack.test.ts +++ b/packages/junior/tests/integration/oauth-callback-slack.test.ts @@ -1,5 +1,6 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { getCapturedSlackApiCalls, resetSlackApiMockState, @@ -8,7 +9,6 @@ import { createPluginAppFixture, type PluginAppFixture, } from "../fixtures/plugin-app"; -import { createSlackSource } from "@sentry/junior-plugin-api"; const { generateAssistantReplyMock } = vi.hoisted(() => ({ generateAssistantReplyMock: vi.fn(), @@ -108,6 +108,13 @@ describe("oauth callback slack integration", () => { }, 20_000); it("resumes a pending OAuth request with persisted thread context", async () => { + const storedSource = createSlackSource({ + teamId: "T123", + channelId: "C123", + messageTs: "1700000000.oauth-source", + threadTs: "1700000000.001", + type: "pub", + }); await stateAdapterModule .getStateAdapter() .set("oauth-state:eval-oauth-resume-state", { @@ -115,6 +122,7 @@ describe("oauth callback slack integration", () => { provider: "eval-oauth", channelId: "C123", destination: SLACK_DESTINATION, + source: storedSource, threadTs: "1700000000.001", pendingMessage: "list my sentry issues", }); @@ -158,6 +166,7 @@ describe("oauth callback slack integration", () => { "list my sentry issues", expect.objectContaining({ destination: SLACK_DESTINATION, + source: storedSource, conversationContext: expect.stringContaining( "You need the budget by Friday.", ), @@ -186,6 +195,13 @@ describe("oauth callback slack integration", () => { it("resumes a session-recorded OAuth turn with persisted thread state", async () => { const conversationId = "slack:C123:1700000000.009"; const sessionId = "turn_msg_9"; + const storedSource = createSlackSource({ + teamId: "T123", + channelId: "C123", + messageTs: "1700000000.session-source", + threadTs: "1700000000.009", + type: "pub", + }); await turnSessionStoreModule.upsertAgentTurnSessionRecord({ conversationId, @@ -193,6 +209,7 @@ describe("oauth callback slack integration", () => { sliceId: 2, state: "awaiting_resume", destination: SLACK_DESTINATION, + source: storedSource, piMessages: [ { role: "user", @@ -219,6 +236,7 @@ describe("oauth callback slack integration", () => { provider: "eval-oauth", channelId: "C123", destination: SLACK_DESTINATION, + source: slackSource("1700000000.009"), threadTs: "1700000000.009", pendingMessage: "list my sentry issues", resumeConversationId: conversationId, @@ -309,6 +327,7 @@ describe("oauth callback slack integration", () => { userName: "stored-user", }), destination: SLACK_DESTINATION, + source: storedSource, correlation: expect.objectContaining({ channelId: "C123", threadTs: "1700000000.009", @@ -411,6 +430,7 @@ describe("oauth callback slack integration", () => { provider: "eval-oauth", channelId: "C123", destination: SLACK_DESTINATION, + source: slackSource("1700000000.012"), threadTs: "1700000000.012", pendingMessage: "list my sentry issues", resumeConversationId: conversationId, @@ -572,6 +592,7 @@ describe("oauth callback slack integration", () => { provider: "eval-oauth", channelId: "C123", destination: SLACK_DESTINATION, + source: slackSource("1700000000.011"), threadTs: "1700000000.011", pendingMessage: "list my sentry issues", resumeConversationId: conversationId, @@ -671,6 +692,7 @@ describe("oauth callback slack integration", () => { provider: "eval-oauth", channelId: "C123", destination: SLACK_DESTINATION, + source: slackSource("1700000000.012"), threadTs: "1700000000.012", pendingMessage: "old request", resumeConversationId: conversationId, @@ -770,6 +792,7 @@ describe("oauth callback slack integration", () => { provider: "eval-oauth", channelId: "C123", destination: SLACK_DESTINATION, + source: slackSource("1700000000.010"), threadTs: "1700000000.010", pendingMessage: "list my sentry issues", resumeConversationId: conversationId, diff --git a/packages/junior/tests/integration/oauth-resume-slack.test.ts b/packages/junior/tests/integration/oauth-resume-slack.test.ts index a9f86b312..20a647eda 100644 --- a/packages/junior/tests/integration/oauth-resume-slack.test.ts +++ b/packages/junior/tests/integration/oauth-resume-slack.test.ts @@ -1,10 +1,10 @@ import { Buffer } from "node:buffer"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { getSlackContinuationMarker, getSlackInterruptionMarker, } from "@/chat/slack/output"; -import { createSlackSource } from "@sentry/junior-plugin-api"; import { disconnectStateAdapter } from "@/chat/state/adapter"; import { getCapturedSlackApiCalls, @@ -71,6 +71,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.001"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.001"), }, generateReply: async () => ({ @@ -154,6 +155,7 @@ describe("oauth resume slack integration", () => { cumulativeUsage: { totalTokens: 1_000, }, + source: testSlackSource("1700000000.007"), }); await resumeAuthorizedRequest({ @@ -168,6 +170,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.007"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.007"), correlation: { conversationId: "conversation-1", turnId: "turn-1", @@ -231,6 +234,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.002"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.002"), }, generateReply: async () => ({ @@ -271,6 +275,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.003"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.003"), }, generateReply: async () => ({ @@ -308,6 +313,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.006"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.006"), }, generateReply: async () => ({ @@ -346,6 +352,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.004"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.004"), }, generateReply: async () => ({ @@ -405,6 +412,7 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.005"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, + source: testSlackSource("1700000000.005"), }, generateReply: async () => ({ diff --git a/packages/junior/tests/unit/handlers/oauth-resume.test.ts b/packages/junior/tests/unit/handlers/oauth-resume.test.ts index c9ef1f6b1..371a8726b 100644 --- a/packages/junior/tests/unit/handlers/oauth-resume.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-resume.test.ts @@ -118,6 +118,7 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0001"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, + source: testSlackSource("1700000000.0001"), }, generateReply: () => new Promise(() => {}), replyTimeoutMs: 10, @@ -161,6 +162,7 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0004"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, + source: testSlackSource("1700000000.0004"), }, generateReply: async () => { throw new Error("resume failed"); @@ -202,6 +204,7 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0005"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, + source: testSlackSource("1700000000.0005"), }, generateReply: async () => ({ text: "Final resumed answer", @@ -328,6 +331,7 @@ describe("resumeAuthorizedRequest", () => { teamId: "T-test", userId: "U-test", }, + source: testSlackSource("1700000000.0005"), }, generateReply: async () => ({ text: "Final resumed answer", @@ -355,12 +359,7 @@ describe("resumeAuthorizedRequest", () => { teamId: "T-test", userId: "U-test", }, - source: { - platform: "slack", - teamId: "T-test", - channelId: "C-test", - threadTs: "1700000000.0005", - }, + source: testSlackSource("1700000000.0005"), toolCalls: [], turnId: "turn-resume-1", userText: "remember that launch notes live in Notion", @@ -396,6 +395,7 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0002"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, + source: testSlackSource("1700000000.0002"), }, generateReply: async () => { throw new RetryableTurnError("agent_continue", "timed out again", { @@ -426,6 +426,7 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0003"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, + source: testSlackSource("1700000000.0003"), }, generateReply: async () => { throw new RetryableTurnError("agent_continue", "timed out again", { diff --git a/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts b/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts index c56ed8ea3..3b9f4c8c1 100644 --- a/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts +++ b/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts @@ -1,4 +1,5 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { createMcpAuthOrchestration } from "@/chat/services/mcp-auth-orchestration"; import { AuthorizationFlowDisabledError } from "@/chat/services/auth-pause"; import type { PluginDefinition } from "@/chat/plugins/types"; @@ -47,6 +48,14 @@ function plugin(name: string): PluginDefinition { }; } +const slackSource = createSlackSource({ + teamId: "T123", + channelId: "C123", + messageTs: "1700000000.source", + threadTs: "1700000000.000000", + type: "pub", +}); + describe("createMcpAuthOrchestration", () => { beforeEach(() => { createMcpOAuthClientProvider.mockReset(); @@ -68,6 +77,7 @@ describe("createMcpAuthOrchestration", () => { sessionId: "scheduled:sched_1:1000", requesterId: "U123", channelId: "C123", + source: slackSource, threadTs: "1700000000.000000", userMessage: "", getConfiguration: () => ({}), @@ -83,6 +93,11 @@ describe("createMcpAuthOrchestration", () => { ).rejects.toBeInstanceOf(AuthorizationFlowDisabledError); expect(deleteMcpAuthSession).toHaveBeenCalledWith("auth_1"); + expect(createMcpOAuthClientProvider).toHaveBeenCalledWith( + expect.objectContaining({ + source: slackSource, + }), + ); expect(patchMcpAuthSession).not.toHaveBeenCalled(); expect(getMcpAuthSession).not.toHaveBeenCalled(); expect(deliverPrivateMessage).not.toHaveBeenCalled(); diff --git a/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts b/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts index 8f269ada0..a5d121491 100644 --- a/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts +++ b/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts @@ -1,4 +1,5 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { createPluginAuthOrchestration, PluginAuthorizationPauseError, @@ -55,6 +56,14 @@ const githubWriteSignal = { createdAtMs: Date.now(), }; +const slackSource = createSlackSource({ + teamId: "T123", + channelId: "C123", + messageTs: "1700000000.source", + threadTs: "1700000000.000000", + type: "pub", +}); + describe("createPluginAuthOrchestration", () => { beforeEach(() => { formatProviderLabel.mockClear(); @@ -90,6 +99,7 @@ describe("createPluginAuthOrchestration", () => { const orchestration = createPluginAuthOrchestration({ abortAgent: vi.fn(), requesterId: "U123", + source: slackSource, userMessage: "check Sentry", userTokenStore: tokens, }); @@ -106,6 +116,7 @@ describe("createPluginAuthOrchestration", () => { "sentry", expect.objectContaining({ requesterId: "U123", + source: slackSource, userMessage: "check Sentry", }), ); From a8f81458c174ecd22902697ed833a7ce36b9be65 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Mon, 22 Jun 2026 23:11:25 -0700 Subject: [PATCH 07/29] test(oauth): Add source to pending resume fixture Pending-message OAuth state now requires a source so resumed Slack runs can reuse the original context. Update the unit fixture to match the runtime contract. Co-Authored-By: GPT-5 Codex --- packages/junior/tests/unit/handlers/oauth-callback.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/junior/tests/unit/handlers/oauth-callback.test.ts b/packages/junior/tests/unit/handlers/oauth-callback.test.ts index 693640e10..a16ee78fb 100644 --- a/packages/junior/tests/unit/handlers/oauth-callback.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-callback.test.ts @@ -1,4 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { http, HttpResponse } from "msw"; import { mswServer } from "../../msw/server"; @@ -656,6 +657,12 @@ describe("oauth callback handler", () => { userId: "U111", provider: "sentry", channelId: "C123", + source: createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "123.789", + type: "pub", + }), threadTs: "123.789", pendingMessage: "list my sentry issues", }); From 0e397f617584571ddabc9dacb69fc868d18e55c5 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Tue, 23 Jun 2026 15:02:43 -0700 Subject: [PATCH 08/29] fix(memory): Simplify memory extraction Keep passive extraction on a single canonical memory shape while preserving DB-backed eval coverage. Tighten source context handling, memory model selection, and eval harness behavior so the memory slice follows the trusted plugin and agentic-semantics policies. Co-Authored-By: GPT-5 Codex --- .../content/docs/reference/config-and-env.md | 1 + .../src/content/docs/start-here/quickstart.md | 1 + .../evals/memory/workflows.eval.ts | 121 ++++-- packages/junior-evals/src/behavior-harness.ts | 50 ++- packages/junior-evals/src/helpers.ts | 1 + packages/junior-evals/vitest.config.ts | 16 + packages/junior-evals/vitest.evals.config.ts | 16 + packages/junior-memory/src/agent.ts | 144 ++++--- packages/junior-memory/src/index.ts | 1 + packages/junior-memory/src/observe.ts | 22 +- packages/junior-memory/src/plugin.ts | 28 +- packages/junior-memory/src/tools.ts | 2 +- packages/junior-memory/tests/storage.test.ts | 357 ++++++++++-------- packages/junior-plugin-api/src/context.ts | 21 +- packages/junior-plugin-api/src/prompt.ts | 2 +- packages/junior/src/chat/config.ts | 10 +- .../junior/src/chat/plugins/agent-hooks.ts | 118 +++--- packages/junior/src/chat/plugins/model.ts | 2 +- packages/junior/src/chat/respond.ts | 48 +-- .../junior/src/chat/tools/slack/context.ts | 17 +- packages/junior/src/chat/tools/types.ts | 8 +- packages/junior/src/cli/init.ts | 1 + .../junior/src/reporting/conversations.ts | 23 +- .../runtime/respond-error-path.test.ts | 24 +- .../integration/dashboard-reporting.test.ts | 21 ++ .../integration/plugin-prompt-hooks.test.ts | 9 +- .../runtime/respond-agent-continue.test.ts | 14 +- .../unit/runtime/respond-lazy-sandbox.test.ts | 5 +- .../respond-mcp-progressive-loading.test.ts | 32 +- .../runtime/respond-provider-retry.test.ts | 13 +- specs/memory-plugin/extraction.md | 48 ++- specs/memory-plugin/tools.md | 5 + specs/plugin-dispatch.md | 2 +- specs/plugin-prompt-hooks.md | 8 +- specs/plugin-runtime.md | 8 +- 35 files changed, 728 insertions(+), 471 deletions(-) diff --git a/packages/docs/src/content/docs/reference/config-and-env.md b/packages/docs/src/content/docs/reference/config-and-env.md index ec82dbd86..b21b79ce5 100644 --- a/packages/docs/src/content/docs/reference/config-and-env.md +++ b/packages/docs/src/content/docs/reference/config-and-env.md @@ -25,6 +25,7 @@ related: | `JUNIOR_SLASH_COMMAND` | No | Slack slash command for account-management flows. Defaults to `/jr`; the Slack app command must match this value. | | `AI_MODEL` | No | Primary model selection override for main agent runs. Defaults to `openai/gpt-5.4`; Junior chooses the reasoning effort per run automatically. | | `AI_FAST_MODEL` | No | Faster model for lightweight tasks and routing/classification passes before the main turn begins. Defaults to `openai/gpt-5.4-mini`. | +| `AI_MEMORY_MODEL` | No | Memory plugin extraction/review model override. When unset, memory uses the host structured-model default. | | `AI_EMBEDDING_MODEL` | No | Embedding model for plugin-owned vector retrieval. Defaults to `openai/text-embedding-3-small`; memory v1 stores fixed 1536-dimensional vectors. | | `AI_VISION_MODEL` | No | Dedicated image-understanding model; unset disables vision features. | | `AI_WEB_SEARCH_MODEL` | No | Override for the `webSearch` tool model. Defaults to `openai/gpt-5.4`; does not fall through to `AI_MODEL`. | diff --git a/packages/docs/src/content/docs/start-here/quickstart.md b/packages/docs/src/content/docs/start-here/quickstart.md index 5a5b19f9f..5c099dc47 100644 --- a/packages/docs/src/content/docs/start-here/quickstart.md +++ b/packages/docs/src/content/docs/start-here/quickstart.md @@ -66,6 +66,7 @@ Set these values before running real turns: | `JUNIOR_SLASH_COMMAND` | No | Slack slash command name. Defaults to `/jr`. | | `AI_MODEL` | No | Primary assistant model override. | | `AI_FAST_MODEL` | No | Lightweight routing/classification model override. | +| `AI_MEMORY_MODEL` | No | Memory plugin extraction/review model override. | | `AI_EMBEDDING_MODEL` | No | Embedding model override for plugin vector retrieval. | | `AI_VISION_MODEL` | No | Enables image understanding when set. | | `AI_WEB_SEARCH_MODEL` | No | Search model override. | diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index 210643866..bd60628e8 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -15,43 +15,42 @@ const requesterUserId = "U-test"; const memoryJudgeModelId = resolveGatewayModel("openai/gpt-5.4").id; interface MemoryThread { + channel_type?: "channel" | "group" | "im" | "mpim"; channel_id: string; id: string; thread_ts: string; } -function memoryContext(thread: MemoryThread) { - return { - conversationId: `slack:${thread.channel_id}:${thread.thread_ts}`, +async function seedMemory(args: { + content: string; + idempotencyKey: string; + scope?: "conversation" | "personal"; + thread: MemoryThread; +}) { + const store = createMemoryStore(memoryDb(), { + conversationId: `slack:${args.thread.channel_id}:${args.thread.thread_ts}`, requester: { - platform: "slack" as const, + platform: "slack", teamId: memoryTeamId, userId: requesterUserId, }, source: createSlackSource({ + channelId: args.thread.channel_id, + messageTs: args.thread.thread_ts, teamId: memoryTeamId, - channelId: thread.channel_id, - messageTs: thread.thread_ts, - threadTs: thread.thread_ts, + threadTs: args.thread.thread_ts, + type: args.thread.channel_type === "im" ? "priv" : "pub", }), - }; -} - -async function seedMemory(args: { - content: string; - idempotencyKey: string; - scope?: "conversation" | "personal"; - thread: MemoryThread; -}) { - const store = createMemoryStore(memoryDb(), memoryContext(args.thread)); + }); const input = { content: args.content, idempotencyKey: args.idempotencyKey, }; if (args.scope === "conversation") { - return await store.createConversationMemory(input); + await store.createConversationMemory(input); + return; } - return await store.createMemory(input); + await store.createMemory(input); } function memoryDb(): MemoryDb { @@ -70,6 +69,10 @@ async function readMemories(thread: MemoryThread) { return rows.filter((memory) => memory.sourceKey === memorySourceKey(thread)); } +async function clearMemories() { + await memoryDb().delete(juniorMemoryMemories); +} + function visibleAssistantText(result: { session: Parameters[0]; }): string { @@ -106,6 +109,12 @@ function parseMemoryJudgeResult(text: string): { async function expectRequesterMemorySemantics( input: MemorySemanticJudgmentInput, ): Promise { + const storedMemoryProjection = input.storedMemories.map((memory) => ({ + archivedAtMs: memory.archivedAtMs, + content: memory.content, + scope: memory.scope, + subjectType: memory.subjectType, + })); const { text } = await completeText({ modelId: memoryJudgeModelId, system: @@ -122,14 +131,7 @@ async function expectRequesterMemorySemantics( input.expectedMeaning, "", "", - JSON.stringify( - input.storedMemories.map((memory) => ({ - archivedAtMs: memory.archivedAtMs, - content: memory.content, - scope: memory.scope, - subjectType: memory.subjectType, - })), - ), + JSON.stringify(storedMemoryProjection), "", "", input.assistantText, @@ -148,9 +150,10 @@ async function expectRequesterMemorySemantics( temperature: 0, }); const judgment = parseMemoryJudgeResult(text); - expect(judgment, judgment.rationale).toEqual( - expect.objectContaining({ passed: true }), - ); + expect( + judgment, + `${judgment.rationale}\nStored memories: ${JSON.stringify(storedMemoryProjection)}`, + ).toEqual(expect.objectContaining({ passed: true })); } async function expectAssistantMemoryAnswer(args: { @@ -202,6 +205,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { it("when explicitly asked to remember a public first-person preference, store one personal memory", async ({ run, }) => { + await clearMemories(); const result = await run({ overrides: memoryPluginOverrides, events: [ @@ -252,6 +256,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { it("when the requester states a first-person opinion, store it even if candidate wording is rewritten", async ({ run, }) => { + await clearMemories(); const userText = "ok remember that i think types in python are bad"; const result = await run({ overrides: memoryPluginOverrides, @@ -295,16 +300,17 @@ describeEval("Memory Workflows", slackEvals, (it) => { }); const passiveFirstPersonThread = { + channel_type: "channel", id: "thread-memory-passive-first-person", channel_id: "CMEMORYPASSIVEPERSONAL", thread_ts: "17000000.memory-passive-personal", - }; + } satisfies MemoryThread; it("when organic conversation reveals a durable first-person preference, passively store and recall it", async ({ run, }) => { - const userText = - "For future PR reviews, I prefer risk notes before summary notes."; + await clearMemories(); + const userText = "In my PR reviews, risk notes go before summary notes."; const result = await run({ overrides: memoryPluginOverrides, events: [ @@ -324,7 +330,6 @@ describeEval("Memory Workflows", slackEvals, (it) => { fail: [ "Do not answer as if no relevant preference exists.", "Do not claim passive memory requires an explicit remember command.", - "Do not store requester names, 'the requester', 'the user', 'I', 'my', thread labels, channel labels, or source labels as memory content.", ], }), }); @@ -360,6 +365,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { it("when asked to remember another person's personal preference, store nothing", async ({ run, }) => { + await clearMemories(); await run({ overrides: memoryPluginOverrides, events: [ @@ -391,6 +397,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { it("automatically injects relevant memories without requiring a recall tool", async ({ run, }) => { + await clearMemories(); await seedMemory({ content: "Prefers PR summaries with risks first.", idempotencyKey: "eval-memory-auto-recall", @@ -425,6 +432,51 @@ describeEval("Memory Workflows", slackEvals, (it) => { ]); }); + const passiveDedupeThread = { + id: "thread-memory-passive-dedupe", + channel_id: "CMEMORYPASSIVEDEDUPE", + thread_ts: "17000000.memory-passive-dedupe", + }; + + it("does not passively duplicate an existing semantic memory", async ({ + run, + }) => { + await clearMemories(); + await seedMemory({ + content: "Prefers PR summaries with risks first.", + idempotencyKey: "eval-memory-passive-dedupe", + thread: passiveDedupeThread, + }); + + await run({ + overrides: memoryPluginOverrides, + events: [ + mention("For PR summaries, I still want risk notes first.", { + thread: passiveDedupeThread, + }), + ], + criteria: rubric({ + pass: [ + "The assistant acknowledges the preference naturally without creating a second remembered copy.", + "The assistant does not mention hidden storage fields, scope keys, or Slack ids.", + ], + fail: [ + "Do not claim a new duplicate memory was saved.", + "Do not ask the user for Slack ids, actor ids, scope names, or subject ids.", + ], + }), + }); + + const rows = await readMemories(passiveDedupeThread); + expect(rows).toEqual([ + expect.objectContaining({ + archivedAtMs: null, + content: "Prefers PR summaries with risks first.", + scope: "personal", + }), + ]); + }); + const removeThread = { id: "thread-memory-remove", channel_id: "CMEMORYREMOVE", @@ -434,6 +486,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { it("when asked to forget a remembered preference, archive the matching memory", async ({ run, }) => { + await clearMemories(); await seedMemory({ content: "Prefers terse PR summaries.", idempotencyKey: "eval-memory-remove", diff --git a/packages/junior-evals/src/behavior-harness.ts b/packages/junior-evals/src/behavior-harness.ts index ba28f4db8..30f66c515 100644 --- a/packages/junior-evals/src/behavior-harness.ts +++ b/packages/junior-evals/src/behavior-harness.ts @@ -87,6 +87,7 @@ import { createMockImageGenerateDeps } from "./fixtures/image-generate"; // --------------------------------------------------------------------------- interface EvalEventThreadFixture { + channel_type?: "channel" | "group" | "im" | "mpim"; channel_id?: string; id: string; run_id?: string; @@ -996,6 +997,9 @@ function toIncomingMessage(event: MentionEvent | SubscribedMessageEvent) { runId: event.thread.run_id, raw: { channel: event.thread.channel_id, + ...(event.thread.channel_type + ? { channel_type: event.thread.channel_type } + : {}), team_id: EVAL_SLACK_TEAM_ID, ts: messageTs, thread_ts: event.thread.thread_ts, @@ -1491,41 +1495,30 @@ function buildRuntimeServices( delete process.env.AI_GATEWAY_API_KEY; delete process.env.VERCEL_OIDC_TOKEN; } - let reply: Awaited>; try { - reply = await Promise.race([ - generateAssistantReply(text, { - ...context, - onToolInvocation: (invocation) => { - observations.toolInvocations.push( - toEvalToolInvocation(invocation), - ); - }, - ...(env.configuredSkillDirs.length > 0 - ? { skillDirs: env.configuredSkillDirs } - : {}), - toolOverrides, - }), - new Promise((_, reject) => - setTimeout( - () => - reject( - new Error( - `generateAssistantReply timed out after ${replyTimeoutMs}ms`, - ), - ), - replyTimeoutMs, - ), + const reply = await generateAssistantReply(text, { + ...context, + turnDeadlineAtMs: Math.min( + context?.turnDeadlineAtMs ?? Number.POSITIVE_INFINITY, + Date.now() + replyTimeoutMs, ), - ]); + onToolInvocation: (invocation) => { + observations.toolInvocations.push( + toEvalToolInvocation(invocation), + ); + }, + ...(env.configuredSkillDirs.length > 0 + ? { skillDirs: env.configuredSkillDirs } + : {}), + toolOverrides, + }); + replyState.successfulCount += 1; + return reply; } finally { if (scenario.overrides?.unset_gateway_api_key) { gatewaySnapshot.restore(); } } - - replyState.successfulCount += 1; - return reply; }, }, visionContext: { @@ -1548,7 +1541,6 @@ function buildRuntimeServices( }, }, }; - return services; } diff --git a/packages/junior-evals/src/helpers.ts b/packages/junior-evals/src/helpers.ts index cb587b30f..d5916d51b 100644 --- a/packages/junior-evals/src/helpers.ts +++ b/packages/junior-evals/src/helpers.ts @@ -527,6 +527,7 @@ const DEFAULT_AUTHOR = { type AuthorOverrides = Partial; interface ThreadOverrides { + channel_type?: "channel" | "group" | "im" | "mpim"; id?: string; channel_id?: string; thread_ts?: string; diff --git a/packages/junior-evals/vitest.config.ts b/packages/junior-evals/vitest.config.ts index 6003f56b6..0033e0480 100644 --- a/packages/junior-evals/vitest.config.ts +++ b/packages/junior-evals/vitest.config.ts @@ -2,11 +2,27 @@ import { defineConfig } from "vitest/config"; import path from "node:path"; const juniorPackageRoot = path.resolve(__dirname, "../junior"); +const pluginApiPackageRoot = path.resolve(__dirname, "../junior-plugin-api"); +const memoryPackageRoot = path.resolve(__dirname, "../junior-memory"); +const schedulerPackageRoot = path.resolve(__dirname, "../junior-scheduler"); export default defineConfig({ resolve: { + alias: { + "@": path.resolve(juniorPackageRoot, "src"), + "@sentry/junior-memory": path.resolve(memoryPackageRoot, "src/index.ts"), + "@sentry/junior-plugin-api": path.resolve( + pluginApiPackageRoot, + "src/index.ts", + ), + "@sentry/junior-scheduler": path.resolve( + schedulerPackageRoot, + "src/index.ts", + ), + }, // Vite 8 resolves tsconfig `paths` natively here: // https://vite.dev/config/shared-options.html#resolve-tsconfigpaths + // The aliases above keep workspace package internals on source instead of package dist. tsconfigPaths: true, }, test: { diff --git a/packages/junior-evals/vitest.evals.config.ts b/packages/junior-evals/vitest.evals.config.ts index d300c6a7b..d079c8dc2 100644 --- a/packages/junior-evals/vitest.evals.config.ts +++ b/packages/junior-evals/vitest.evals.config.ts @@ -6,6 +6,9 @@ import { loadJuniorTestEnvFiles } from "../junior/tests/fixtures/env"; const juniorPackageRoot = path.resolve(__dirname, "../junior"); const workspaceRoot = path.resolve(__dirname, "../.."); const evalsPackageRoot = __dirname; +const pluginApiPackageRoot = path.resolve(__dirname, "../junior-plugin-api"); +const memoryPackageRoot = path.resolve(__dirname, "../junior-memory"); +const schedulerPackageRoot = path.resolve(__dirname, "../junior-scheduler"); const EVAL_TEST_TIMEOUT_MS = 60_000; loadJuniorTestEnvFiles({ @@ -21,8 +24,21 @@ process.env.VITEST_EVALS_REPLAY_MODE ??= "auto"; export default defineConfig({ resolve: { + alias: { + "@": path.resolve(juniorPackageRoot, "src"), + "@sentry/junior-memory": path.resolve(memoryPackageRoot, "src/index.ts"), + "@sentry/junior-plugin-api": path.resolve( + pluginApiPackageRoot, + "src/index.ts", + ), + "@sentry/junior-scheduler": path.resolve( + schedulerPackageRoot, + "src/index.ts", + ), + }, // Vite 8 resolves tsconfig `paths` natively here: // https://vite.dev/config/shared-options.html#resolve-tsconfigpaths + // The aliases above keep workspace package internals on source instead of package dist. tsconfigPaths: true, }, test: { diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 8737d6549..833aa4193 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -29,6 +29,16 @@ const createMemoryRequestSchema = z const extractTurnRequestSchema = z .object({ assistantText: z.string(), + existingMemories: z + .array( + z + .object({ + content: z.string().min(1), + }) + .strict(), + ) + .max(10) + .default([]), runtimeContext: memoryRuntimeContextSchema, userText: z.string().min(1), }) @@ -63,7 +73,7 @@ const memoryReviewResponseSchema = z .min(1) .nullable() .describe( - "Canonical perspective-neutral fact when decision is store, otherwise null. For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'. Do not include requester names, display names, 'the requester', 'the user', first-person wording like 'I', 'me', 'my', 'mine', 'we', or 'our', second-person wording like 'you' or 'your', 'this thread', or channel/source labels. Good: 'Prefers morning standup notes'. Good: 'Favorite editor theme is Solarized Light'. Good: 'Release checklist lives in Linear'. Bad: 'I prefer morning standup notes'. Bad: 'The requester prefers morning standup notes'. Bad: 'David prefers morning standup notes'. Bad: 'This thread says the release checklist lives in Linear'.", + "Stored memory text when decision is store. It must be self-contained and must not include requester names, requester/user labels, source labels, or first- or second-person wording. Otherwise null.", ), reason: memoryRejectReasonSchema .nullable() @@ -77,24 +87,25 @@ const memoryReviewResponseSchema = z ), }) .strict(); +const expiresAtMsSchema = z + .number() + .finite() + .nullable() + .describe( + "Expiration timestamp when the fact should expire, otherwise null.", + ); const extractedMemorySchema = z .object({ target: memoryTargetSchema.describe( - "Where the memory should be stored when this is accepted.", + "Store requester facts as personal memory for the current requester; store shared operational/project facts as conversation memory.", ), canonicalFact: z .string() .min(1) .describe( - "Canonical perspective-neutral fact. For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'. Do not include requester names, display names, 'the requester', 'the user', first-person wording like 'I', 'me', 'my', 'mine', 'we', or 'our', second-person wording like 'you' or 'your', 'this thread', or channel/source labels. Good: 'Prefers morning standup notes'. Bad: 'I prefer morning standup notes'. Bad: 'The requester prefers morning standup notes'.", - ), - expiresAtMs: z - .number() - .finite() - .nullable() - .describe( - "Expiration timestamp when the fact should expire, otherwise null.", + "Stored memory text as one self-contained fact. It must not include requester names, requester/user labels, source labels, or first- or second-person wording.", ), + expiresAtMs: expiresAtMsSchema, }) .strict(); const extractTurnResponseSchema = z @@ -132,37 +143,31 @@ export interface MemoryAgent { ): Promise | MemoryReview; } +export interface MemoryAgentOptions { + modelId?: string; +} + const MEMORY_REVIEW_SYSTEM = [ "You are Junior's memory review agent.", - "Review one explicit createMemory candidate and return one structured review decision.", + "Review one memory candidate and return one structured review decision.", "Store only public/shareable, self-contained facts that are useful beyond this turn.", - "Reject secrets, credentials, private/sensitive personal details, gossip, speculative coworker claims, assistant/system implementation details, vague references, and low-durability chatter.", - "Personal/requester memories must be authored by the current requester as first-person facts about themselves, then stored as perspective-neutral canonical facts without names or requester/source wording.", - "The current user-authored text is source evidence. If it states a first-person fact about the requester, do not reject merely because the candidate rewrites it with the requester's name, 'the requester', or third-person wording.", - "Conversation memories must be shared operational or project knowledge about the active conversation, not another person's private profile.", - "Do not accept model/caller-provided actor ids, scope ids, aliases, or arbitrary subjects.", - "For accepted memories, rewrite content into one concise declarative fact that is understandable without the original conversation and does not bake in who said it or where it was said.", - "For requester memories, omit the subject and use canonical phrasing such as 'Prefers X', 'Uses Y', or 'Thinks Z'; never output 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', a requester name, 'the requester', or 'the user'.", - "Before returning store, self-check the content: if it could be read as the user's direct quote, rewrite it into omitted-subject canonical prose.", + "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.", + "Use the runtime context only for authority and scope; do not accept model-provided actor ids, scope ids, aliases, or arbitrary subjects.", "Return every response field. Use null for fields that do not apply to the decision.", ].join("\n"); const MEMORY_EXTRACTION_SYSTEM = [ - "You are Junior's passive memory extraction agent.", - "Review one completed user-authored turn and return structured memories that should be stored.", - "Store only public/shareable, durable, self-contained facts useful beyond this turn.", - "Do not store secrets, credentials, private/sensitive personal details, gossip, speculative coworker claims, assistant/system implementation details, vague references, or low-durability chatter.", - "Personal/requester memories must come from the user's own first-person statements about themselves, then be stored as perspective-neutral canonical facts without names or requester/source wording.", - "Conversation memories must be shared operational or project knowledge about the active conversation, not another person's private profile.", - "Extract only facts explicitly present in the user-authored message. Assistant text is rejection context only; never use assistant text, tool results, recalled memory text, or suggested wording as source evidence.", - "Never store a fact merely because the assistant suggested or invented it. The user-authored text is the source of truth.", - "For requester memories, omit the subject and use canonical phrasing such as 'Prefers X', 'Uses Y', or 'Thinks Z'; never output 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', a requester name, 'the requester', or 'the user'.", - "Requester memory content should read like a stored fact, not like a quote from the user. Convert 'I prefer X' into 'Prefers X', 'I use Y' into 'Uses Y', and 'I think Z' into 'Thinks Z'.", - "Before returning a requester memory, self-check the content: if it could be read as the user's direct quote, rewrite it into omitted-subject canonical prose.", - "Return one memory per distinct fact. If a first-person requester fact mentions a workstream, project, or conversation topic, keep that context inside the requester memory instead of also creating a conversation memory for the same fact.", - "Advice, how-to, search, recall, and planning questions are not memories by themselves. Extract from those turns only when the user states a durable self-fact or shared project fact that remains true beyond the request.", - "Do not duplicate explicit memory tool outcomes; turns that used memory tools are filtered before this agent, but if the user text is asking to list, search, recall, remove, confirm, or inspect existing memories, return no memories.", - "Return only accepted memories. If there are no accepted memories, return an empty memories array.", + "You are Junior's passive memory extraction agent. Return only structured memories worth storing.", + "Use only the user-authored message as source evidence. Assistant text is rejection context only.", + "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.", + "If no public, durable, self-contained memory remains after rewriting, return an empty memories array.", ].join("\n"); +const CANONICAL_CONTENT_RULES = [ + "- Stored memory text must be a rewritten fact, not copied user wording or a sentence about who said it.", + "- Put ownership in target, not prose.", + "- For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", + "- Drop perspective/provenance markers while preserving useful context.", + "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels.", +]; function escapeXml(value: string): string { return value @@ -213,6 +218,33 @@ function sourceContext(request: CreateMemoryRequest): string | undefined { ].join("\n"); } +function existingMemoriesContext(request: ExtractTurnRequest): string { + if (request.existingMemories.length === 0) { + return "[]"; + } + return [ + "", + "Use these only to skip memories that are already covered or semantically redundant. They are not source evidence for new memories.", + escapeXml(JSON.stringify(request.existingMemories)), + "", + ].join("\n"); +} + +function extractionExamples(): string { + return [ + "", + "- User says: 'I prefer short status updates.'", + " Output requester memory: canonicalFact='Prefers short status updates.'.", + "- User says: 'For incident writeups, I prefer causes before mitigations.'", + " Output requester memory: canonicalFact='Prefers causes before mitigations in incident writeups.'.", + "- User says: 'In planning docs, open risks go before goals.'", + " Output requester memory: canonicalFact='Prefers open risks before goals in planning docs.'.", + "- User says: 'This thread says deploy runbooks live in Notion.'", + " Output conversation memory: canonicalFact='Deploy runbooks live in Notion.'.", + "", + ].join("\n"); +} + function reviewPrompt(request: CreateMemoryRequest): string { const sections = [ "", @@ -229,16 +261,15 @@ function reviewPrompt(request: CreateMemoryRequest): string { "", "- Return store only when the candidate is public/shareable, durable, and self-contained.", "- Use target=requester for first-person facts about the current requester.", - "- A candidate may be badly phrased by the outer assistant. When current-user-message contains the requester's own first-person memory request, treat that as requester-authored source evidence and canonicalize the fact instead of rejecting for third-person wording.", + "- A candidate may be badly phrased by an outer assistant or extraction pass. When current-user-message contains the requester's own first-person memory fact, treat that as requester-authored source evidence and canonicalize the fact instead of rejecting for third-person wording.", "- Use target=conversation only for shared operational/project knowledge in the active conversation.", "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", - "- If the stored content would still sound like the user's direct quote, rewrite it before returning store.", - "- Remove phrases such as 'I', 'me', 'my', 'mine', 'we', 'our', 'you', 'your', 'the requester', 'the user', user names, 'this thread', 'this channel', and Slack/source labels from stored content.", - "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'The requester prefers morning standup notes'.", - "- Good stored content: 'Favorite editor theme is Solarized Light'. Bad stored content: 'My favorite editor theme is Solarized Light'.", - "- Good stored content: 'Thinks runtime logs should include request ids'. Bad stored content: 'David thinks runtime logs should include request ids'.", - "- Good stored content: 'Release checklist lives in Linear'. Bad stored content: 'This thread says the release checklist lives in Linear'.", + "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels from stored content.", + "- Good requester content: 'Prefers short status updates'. Bad requester content: 'I prefer short status updates'.", + "- Good requester content: 'Prefers short status updates'. Bad requester content: 'The requester prefers short status updates'.", + "- Good requester content: 'Prefers causes before mitigations in incident writeups'. Bad requester content: 'Prefers in my incident writeups, causes before mitigations'.", + "- Good conversation content: 'Deploy runbooks live in Notion'. Bad conversation content: 'This thread says deploy runbooks live in Notion'.", "- Reject third-party personal profile facts, even if they mention a name.", "- Reject vague content such as 'remember this' unless the candidate itself contains the fact.", "- Preserve the requested expiration when one exists; otherwise set expiresAtMs to null.", @@ -260,6 +291,10 @@ function extractionPrompt(request: ExtractTurnRequest): string { runtimeContext: request.runtimeContext, }), "", + existingMemoriesContext(request), + "", + extractionExamples(), + "", "", escapeXml(request.userText), "", @@ -270,35 +305,31 @@ function extractionPrompt(request: ExtractTurnRequest): string { "", "", "- Return at most five memories.", - "- The user-message is the only source of storable facts.", - "- Use assistant-response only to identify non-memory turns, confirmations, or follow-up questions. Do not store facts from assistant-response.", + "- Use user-message as the only source of storable facts.", + "- Use assistant-response only to reject confirmations, follow-up questions, or memory-management turns.", "- Return one memory per distinct fact. Do not store the same fact under both requester and conversation targets.", - "- Do not store advice, how-to, search, recall, or planning requests unless the user-message also states a durable fact independent of the request.", - "- Return an empty array when the user-message only asks what is remembered, how to use a remembered preference, or asks to list/search/remove/inspect memory.", + "- Ignore advice, how-to, search, recall, planning, list, inspect, and remove requests unless user-message also states a durable fact.", "- Use target=requester for first-person facts about the current requester.", "- Use target=conversation only for shared operational/project knowledge.", - "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", - "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", - "- Requester memory content should never read like a direct user quote. Convert first-person statements into omitted-subject facts before returning them.", - "- If the stored content would still sound like the user's direct quote, rewrite it before returning it.", - "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'I prefer morning standup notes'.", - "- Good stored content: 'Prefers morning standup notes'. Bad stored content: 'The requester prefers morning standup notes'.", - "- Good stored content: 'Thinks runtime logs should include request ids'. Bad stored content: 'David thinks runtime logs should include request ids'.", - "- Good stored content: 'Release checklist lives in Linear'. Bad stored content: 'This thread says the release checklist lives in Linear'.", + ...CANONICAL_CONTENT_RULES, + "- Skip a candidate when existing-memories already cover the same durable fact.", "- Reject third-party personal profile facts, even if they mention a name.", - "- Reject facts that are only useful inside this one turn.", "- If unsure, return no memory for that candidate.", "", "", ].join("\n"); } -/** Create the memory-owned agent that reviews candidates before storage. */ -export function createMemoryAgent(model: PluginModel): MemoryAgent { +/** Create the memory-owned agent that reviews and extracts memory candidates. */ +export function createMemoryAgent( + model: PluginModel, + options: MemoryAgentOptions = {}, +): MemoryAgent { return { async extractTurnMemories(rawRequest) { const request = extractTurnRequestSchema.parse(rawRequest); const result = await model.completeObject({ + ...(options.modelId ? { modelId: options.modelId } : {}), schema: extractTurnResponseSchema, system: MEMORY_EXTRACTION_SYSTEM, prompt: extractionPrompt(request), @@ -311,6 +342,7 @@ export function createMemoryAgent(model: PluginModel): MemoryAgent { async reviewCreateRequest(rawRequest) { const request = parseCreateMemoryRequest(rawRequest); const result = await model.completeObject({ + ...(options.modelId ? { modelId: options.modelId } : {}), schema: memoryReviewResponseSchema, system: MEMORY_REVIEW_SYSTEM, prompt: reviewPrompt(request), diff --git a/packages/junior-memory/src/index.ts b/packages/junior-memory/src/index.ts index 1c2edec38..6c0a7b74a 100644 --- a/packages/junior-memory/src/index.ts +++ b/packages/junior-memory/src/index.ts @@ -1,4 +1,5 @@ export { createMemoryPlugin, memoryPlugin } from "./plugin"; +export type { MemoryPluginOptions } from "./plugin"; export { createMemoryStore } from "./store"; export type { ArchiveMemoryInput, diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/observe.ts index b2f3c7595..5403624d5 100644 --- a/packages/junior-memory/src/observe.ts +++ b/packages/junior-memory/src/observe.ts @@ -8,7 +8,11 @@ import { type CreateMemoryInput, type MemoryDb, } from "./store"; -import { createMemoryAgent, type ExtractedMemory } from "./agent"; +import { + createMemoryAgent, + type ExtractedMemory, + type MemoryAgentOptions, +} from "./agent"; import { memoryRuntimeContextSchema } from "./types"; const MEMORY_TOOL_NAMES = new Set([ @@ -34,6 +38,7 @@ function passiveInput( /** Extract and store memories from a delivered turn without using model-visible tools. */ export async function observeMemoryTurn( context: TurnObservationContext, + options: MemoryAgentOptions = {}, ): Promise { if (context.toolCalls.some((toolName) => MEMORY_TOOL_NAMES.has(toolName))) { return; @@ -57,9 +62,19 @@ export async function observeMemoryTurn( ...(context.requester ? { requester: context.requester } : {}), source: context.source, }); - const agent = createMemoryAgent(context.model); + const store = createMemoryStore(context.db as MemoryDb, runtimeContext, { + embedder: context.embedder, + }); + const existingMemories = await store.searchMemories({ + limit: 10, + query: userText, + }); + const agent = createMemoryAgent(context.model, options); const memories = await agent.extractTurnMemories({ assistantText: context.assistantText, + existingMemories: existingMemories.map((memory) => ({ + content: memory.content, + })), runtimeContext, userText, }); @@ -67,9 +82,6 @@ export async function observeMemoryTurn( return; } - const store = createMemoryStore(context.db as MemoryDb, runtimeContext, { - embedder: context.embedder, - }); for (const [index, memory] of memories.entries()) { const input = passiveInput(context, memory, index, sourceKey); if (memory.target === "conversation") { diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index 5a7681507..44e0d038d 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -13,6 +13,21 @@ import { observeMemoryTurn } from "./observe"; import { createMemoryPromptMessages } from "./recall"; import type { MemoryDb } from "./store"; +const MEMORY_MODEL_ENV = "AI_MEMORY_MODEL"; + +export interface MemoryPluginOptions { + modelId?: string; +} + +function memoryModelId(options: MemoryPluginOptions): string | undefined { + const explicitModelId = options.modelId?.trim(); + if (explicitModelId) { + return explicitModelId; + } + const envModelId = process.env[MEMORY_MODEL_ENV]?.trim(); + return envModelId || undefined; +} + function memoryToolContext(ctx: { agent: MemoryReviewer; conversationId?: string; @@ -34,7 +49,8 @@ function memoryToolContext(ctx: { } /** Create Junior's long-term memory plugin registration. */ -export function createMemoryPlugin() { +export function createMemoryPlugin(options: MemoryPluginOptions = {}) { + const modelId = memoryModelId(options); return defineJuniorPlugin({ manifest: { name: "memory", @@ -49,7 +65,9 @@ export function createMemoryPlugin() { tools(ctx) { const context = memoryToolContext({ ...ctx, - agent: createMemoryAgent(ctx.model), + agent: createMemoryAgent(ctx.model, { + ...(modelId ? { modelId } : {}), + }), db: ctx.db as MemoryDb, embedder: ctx.embedder, }); @@ -70,7 +88,11 @@ export function createMemoryPlugin() { text: ctx.text, }); }, - observeTurn: observeMemoryTurn, + async observeTurn(ctx) { + await observeMemoryTurn(ctx, { + ...(modelId ? { modelId } : {}), + }); + }, }, }); } diff --git a/packages/junior-memory/src/tools.ts b/packages/junior-memory/src/tools.ts index ea67eccac..2015cb774 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior-memory/src/tools.ts @@ -329,7 +329,7 @@ function compactMemory(memory: MemoryRecord) { export function createMemoryCreateTool(context: MemoryToolContext) { return { description: - "Remember a public/shareable fact about the current requester for later. Use when the requester explicitly asks Junior to remember something about themselves, including ordinary technical, workflow, communication, tool, language, product, repository, or project preferences and opinions. Pass one self-contained memory candidate in natural language, preserving the user's memory intent as directly as possible, such as 'I prefer terse updates' or 'I think types in Python are bad'. Do not ask the requester to rephrase ordinary technical/workflow preferences; pass the candidate to this tool and let the memory agent decide store vs reject. Do not rewrite first-person requester claims into display-name or third-person phrasing. Do not pass vague references like 'remember this'. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives all actor ids, Slack ids, scope keys, source ids, and subject ids; the memory agent decides the canonical stored content, subject, and target.", + "Submit an explicit memory-management request. Call only when the requester directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact about themselves. Do not call for organic statements that merely reveal a durable preference or fact; passive memory observation handles those after the visible turn. Pass one self-contained memory candidate in natural language, preserving the user's explicit memory intent as directly as possible, such as 'I prefer terse updates' or 'I think rollback plans should mention data recovery'. Do not ask the requester to rephrase ordinary technical/workflow preferences, do not rewrite first-person claims into display-name or third-person phrasing, and do not pass vague references like 'remember this'. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives all actor ids, Slack ids, scope keys, source ids, and subject ids; the memory agent decides the canonical stored content, subject, and target.", executionMode: "sequential", inputSchema: createMemoryInputSchema, execute: async (input, options) => { diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index ac4462e91..f47a0e104 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -236,6 +236,14 @@ function slackContext( }; } +function slackDestination(context: ReturnType) { + return { + platform: "slack" as const, + teamId: context.source.teamId, + channelId: context.source.channelId, + }; +} + function localContext( overrides: { conversationId?: string; userId?: string } = {}, ) { @@ -257,6 +265,10 @@ function observationContext( return { assistantText: "Got it.", conversationId: runtime.conversationId, + destination: { + platform: "local", + conversationId: runtime.conversationId, + }, db: overrides.db ?? {}, embedder: overrides.embedder ?? createTestEmbedder(), log: noopLogger, @@ -264,8 +276,8 @@ function observationContext( overrides.model ?? extractionModel([ { - content: "Prefers terse PR summaries.", target: "requester", + content: "terse PR summaries", }, ]).model, plugin: { name: "memory" }, @@ -343,6 +355,124 @@ describe("memory plugin storage", () => { expect(calls[0]?.schema).toBeDefined(); }); + it("passes configured model id to memory agent structured calls", async () => { + const calls: Parameters[0][] = []; + let callIndex = 0; + const model: PluginModel = { + async completeObject(input) { + calls.push(input); + callIndex += 1; + if (callIndex === 1) { + return { + object: { + memories: [], + }, + }; + } + return { + object: { + decision: "reject", + target: null, + canonicalFact: null, + reason: "not_durable", + expiresAtMs: null, + }, + }; + }, + }; + const agent = createMemoryAgent(model, { + modelId: "anthropic/claude-sonnet-4.6", + }); + + await agent.extractTurnMemories({ + assistantText: "Got it.", + runtimeContext: localContext(), + userText: "I prefer terse PR summaries.", + }); + await agent.reviewCreateRequest({ + content: "I prefer terse PR summaries.", + runtimeContext: localContext(), + }); + + expect(calls.map((call) => call.modelId)).toEqual([ + "anthropic/claude-sonnet-4.6", + "anthropic/claude-sonnet-4.6", + ]); + }); + + it("parses canonical requester extraction into stored memory text", async () => { + const model: PluginModel = { + async completeObject() { + return { + object: { + memories: [ + { + canonicalFact: + "Prefers causes before mitigations in incident writeups.", + expiresAtMs: null, + target: "requester", + }, + ], + }, + }; + }, + }; + const agent = createMemoryAgent(model); + + await expect( + agent.extractTurnMemories({ + assistantText: "Got it.", + runtimeContext: localContext(), + userText: "For incident writeups, causes go before mitigations.", + }), + ).resolves.toEqual([ + { + content: "Prefers causes before mitigations in incident writeups.", + expiresAtMs: null, + target: "requester", + }, + ]); + }); + + it("uses AI_MEMORY_MODEL as the memory plugin model default", async () => { + const previousModel = process.env.AI_MEMORY_MODEL; + process.env.AI_MEMORY_MODEL = "anthropic/claude-sonnet-4.6"; + const fixture = await createMemoryFixture(); + const calls: Parameters[0][] = []; + const model: PluginModel = { + async completeObject(input) { + calls.push(input); + return { + object: { + memories: [], + }, + }; + }, + }; + + try { + const plugin = createMemoryPlugin(); + await plugin.hooks?.observeTurn?.( + observationContext({ + db: memoryDb(fixture), + model, + userText: "I prefer terse PR summaries.", + }), + ); + + expect(calls.map((call) => call.modelId)).toEqual([ + "anthropic/claude-sonnet-4.6", + ]); + } finally { + await fixture.close(); + if (previousModel === undefined) { + delete process.env.AI_MEMORY_MODEL; + } else { + process.env.AI_MEMORY_MODEL = previousModel; + } + } + }); + it("normalizes nullable structured rejection responses", async () => { const model: PluginModel = { async completeObject() { @@ -376,8 +506,8 @@ describe("memory plugin storage", () => { try { const { model, calls } = extractionModel([ { - content: "Prefers QA notes that mention database row checks.", target: "requester", + content: "Prefers QA notes that mention database row checks.", }, { content: "Deploy runbooks live in Notion.", @@ -417,6 +547,9 @@ describe("memory plugin storage", () => { }), ]); expect(embedder.calls).toEqual([ + [ + "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", + ], ["Prefers QA notes that mention database row checks."], ["Deploy runbooks live in Notion."], ]); @@ -425,180 +558,72 @@ describe("memory plugin storage", () => { } }, 15_000); - it("deduplicates repeated passive observations for the same delivered turn", async () => { - const fixture = await createMemoryFixture(); - - try { - const { model, calls } = extractionModel([ - { - content: "Prefers passive observation retries to stay idempotent.", - target: "requester", - }, - ]); - const embedder = createTestEmbedder(); - const context = observationContext({ - db: memoryDb(fixture), - embedder, - model, - turnId: "local-turn-repeat", - userText: "I prefer passive observation retries to stay idempotent.", - }); - - await observeMemoryTurn(context); - await observeMemoryTurn(context); - - expect(calls).toHaveLength(2); - const rows = await memoryDb(fixture) - .select() - .from(memorySqlSchema.juniorMemoryMemories); - expect(rows).toEqual([ - expect.objectContaining({ - content: "Prefers passive observation retries to stay idempotent.", - scope: "personal", - sourcePlatform: "local", - subjectType: "user", - }), - ]); - await expect( - memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryEmbeddings), - ).resolves.toHaveLength(1); - expect(embedder.calls).toEqual([ - ["Prefers passive observation retries to stay idempotent."], - ]); - } finally { - await fixture.close(); - } - }, 15_000); - it("skips passive extraction for successful memory tool turns", async () => { - const fixture = await createMemoryFixture(); - - try { - const { model, calls } = extractionModel([ - { - content: "Prefers duplicate memory avoidance.", - target: "requester", - }, - ]); - - await observeMemoryTurn( - observationContext({ - db: memoryDb(fixture), - model, - toolCalls: ["searchMemories"], - userText: "Remember that I prefer duplicate memory avoidance.", - }), - ); - - expect(calls).toEqual([]); - await expect( - memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), - ).resolves.toEqual([]); - } finally { - await fixture.close(); - } - }, 15_000); - - it("extracts passive memories when an explicit memory tool did not succeed", async () => { - const fixture = await createMemoryFixture(); - - try { - const { model, calls } = extractionModel([ - { - content: "Prefers fallback passive extraction.", - target: "requester", - }, - ]); + const { model, calls } = extractionModel([ + { + target: "requester", + content: "duplicate memory avoidance", + }, + ]); - await observeMemoryTurn( - observationContext({ - db: memoryDb(fixture), - model, - toolCalls: [], - userText: "Remember that I prefer fallback passive extraction.", - }), - ); + await observeMemoryTurn( + observationContext({ + model, + toolCalls: ["createMemory"], + userText: "Remember that I prefer duplicate memory avoidance.", + }), + ); - expect(calls).toHaveLength(1); - await expect( - memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), - ).resolves.toEqual([ - expect.objectContaining({ - content: "Prefers fallback passive extraction.", - }), - ]); - } finally { - await fixture.close(); - } - }, 15_000); + expect(calls).toEqual([]); + }); it("skips passive extraction in private Slack contexts", async () => { - const fixture = await createMemoryFixture(); - - try { - const { model, calls } = extractionModel([ - { - content: "Prefers private Slack context skips.", - target: "requester", - }, - ]); - const privateContext = slackContext({ - channelId: "D123", - sourceType: "priv", - }); + const { model, calls } = extractionModel([ + { + target: "requester", + content: "private Slack context skips", + }, + ]); + const privateContext = slackContext({ + channelId: "D123", + sourceType: "priv", + }); - await observeMemoryTurn( - observationContext({ - ...privateContext, - db: memoryDb(fixture), - model, - userText: "I prefer private Slack context skips.", - }), - ); + await observeMemoryTurn( + observationContext({ + ...privateContext, + model, + userText: "I prefer private Slack context skips.", + }), + ); - expect(calls).toEqual([]); - await expect( - memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), - ).resolves.toEqual([]); - } finally { - await fixture.close(); - } - }, 15_000); + expect(calls).toEqual([]); + }); it("skips passive extraction for Slack observations without a message key", async () => { - const fixture = await createMemoryFixture(); - - try { - const { model, calls } = extractionModel([ - { - content: "Prefers Slack message key validation.", - target: "requester", - }, - ]); - const runtime = slackContext(); + const { model, calls } = extractionModel([ + { + target: "requester", + content: "Slack message key validation", + }, + ]); + const runtime = slackContext(); - await observeMemoryTurn( - observationContext({ - conversationId: "slack:C123:missing-message-key", - db: memoryDb(fixture), - model, - requester: runtime.requester, - source: createSlackSource({ - teamId: runtime.source.teamId, - channelId: runtime.source.channelId, - }), - userText: "I prefer Slack message key validation.", + await observeMemoryTurn( + observationContext({ + conversationId: "slack:C123:missing-message-key", + model, + requester: runtime.requester, + source: createSlackSource({ + teamId: runtime.source.teamId, + channelId: runtime.source.channelId, }), - ); + userText: "I prefer Slack message key validation.", + }), + ); - expect(calls).toEqual([]); - await expect( - memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), - ).resolves.toEqual([]); - } finally { - await fixture.close(); - } - }, 15_000); + expect(calls).toEqual([]); + }); it("persists, recalls, and archives visible memories", async () => { const fixture = await createMemoryFixture(); @@ -1095,7 +1120,6 @@ WHERE id = '${superseded.memory.id}' platform: "slack", type: "pub", teamId: "T123", - conversationId: "C123", channelId: "C123", messageTs: "1718800000.000000", threadTs: "1718800000.000000", @@ -1322,6 +1346,7 @@ WHERE id = '${superseded.memory.id}' const plugin = createMemoryPlugin(); const result = await plugin.hooks?.userPrompt?.({ ...context, + destination: slackDestination(context), db: memoryDb(fixture), embedder: createTestEmbedder(), log: noopLogger, @@ -1360,6 +1385,7 @@ WHERE id = '${superseded.memory.id}' await expect( plugin.hooks?.userPrompt?.({ ...context, + destination: slackDestination(context), db: memoryDb(fixture), embedder: createTestEmbedder(), log: noopLogger, @@ -1396,6 +1422,7 @@ WHERE id = '${superseded.memory.id}' await expect( plugin.hooks?.userPrompt?.({ ...context, + destination: slackDestination(context), db: memoryDb(fixture), embedder, log: noopLogger, diff --git a/packages/junior-plugin-api/src/context.ts b/packages/junior-plugin-api/src/context.ts index 3b36ef7ab..d3721e2e1 100644 --- a/packages/junior-plugin-api/src/context.ts +++ b/packages/junior-plugin-api/src/context.ts @@ -40,6 +40,8 @@ export interface PluginModel { /** Run a host-owned structured model call without exposing provider credentials. */ completeObject(input: { maxTokens?: number; + /** Optional host model id override for plugin-owned structured calls. */ + modelId?: string; prompt: string; schema: TSchema; system?: string; @@ -72,16 +74,16 @@ interface BaseInvocationContext { } export interface SlackInvocationContext extends BaseInvocationContext { - /** Runtime-owned default outbound destination for this invocation, if any. */ - destination?: SlackDestination; + /** Runtime-owned default outbound destination for this invocation. */ + destination: SlackDestination; requester?: SlackRequester; /** Runtime-owned source where the invocation came from. */ source: SlackSource; } export interface LocalInvocationContext extends BaseInvocationContext { - /** Runtime-owned default outbound destination for this invocation, if any. */ - destination?: LocalDestination; + /** Runtime-owned default outbound destination for this invocation. */ + destination: LocalDestination; requester?: LocalRequester; /** Runtime-owned source where the invocation came from. */ source: LocalSource; @@ -137,17 +139,6 @@ export function createLocalSource(conversationId: string): LocalSource { }; } -/** Build a source from a destination when the source is the same conversation. */ -export function sourceFromDestination(destination: Destination): Source { - if (destination.platform === "local") { - return createLocalSource(destination.conversationId); - } - return createSlackSource({ - channelId: destination.channelId, - teamId: destination.teamId, - }); -} - /** Return whether a source is private to a person or restricted group. */ export function isPrivateSource(source: Source): boolean { return source.type === "priv"; diff --git a/packages/junior-plugin-api/src/prompt.ts b/packages/junior-plugin-api/src/prompt.ts index 254a6b85d..4dab597ed 100644 --- a/packages/junior-plugin-api/src/prompt.ts +++ b/packages/junior-plugin-api/src/prompt.ts @@ -29,7 +29,7 @@ export type SystemPromptContext = Pick< /** Runtime facts available while building plugin user prompt context. */ export type UserPromptContext = Pick & { conversationId?: string; - destination?: Destination; + destination: Destination; embedder: PluginEmbedder; requester?: Requester; source: Source; diff --git a/packages/junior/src/chat/config.ts b/packages/junior/src/chat/config.ts index 7e6e79b60..71769de20 100644 --- a/packages/junior/src/chat/config.ts +++ b/packages/junior/src/chat/config.ts @@ -234,17 +234,19 @@ function parseReactionEmoji( function readBotConfig(env: NodeJS.ProcessEnv): BotConfig { const functionMaxDurationSeconds = resolveFunctionMaxDurationSeconds(env); const maxTurnTimeoutMs = resolveMaxTurnTimeoutMs(functionMaxDurationSeconds); + const modelId = validateGatewayModelId(env.AI_MODEL) ?? DEFAULT_MODEL_ID; + const fastModelId = + validateGatewayModelId(env.AI_FAST_MODEL ?? env.AI_MODEL) ?? + DEFAULT_FAST_MODEL_ID; return { userName: toOptionalTrimmed(env.JUNIOR_BOT_NAME) ?? "junior", - modelId: validateGatewayModelId(env.AI_MODEL) ?? DEFAULT_MODEL_ID, + modelId, modelContextWindowTokens: parseOptionalPositiveInteger( "AI_MODEL_CONTEXT_WINDOW_TOKENS", env.AI_MODEL_CONTEXT_WINDOW_TOKENS, ), - fastModelId: - validateGatewayModelId(env.AI_FAST_MODEL ?? env.AI_MODEL) ?? - DEFAULT_FAST_MODEL_ID, + fastModelId, embeddingModelId: validateEmbeddingModelId(env.AI_EMBEDDING_MODEL) ?? DEFAULT_EMBEDDING_MODEL_ID, diff --git a/packages/junior/src/chat/plugins/agent-hooks.ts b/packages/junior/src/chat/plugins/agent-hooks.ts index 41e8bb35c..92e370e0c 100644 --- a/packages/junior/src/chat/plugins/agent-hooks.ts +++ b/packages/junior/src/chat/plugins/agent-hooks.ts @@ -11,6 +11,7 @@ import type { SlackConversationLink, PluginRegistration, SlackToolRegistrationHookContext, + ToolRegistrationHookContext, TurnObservationContext, UserPromptContext, } from "@sentry/junior-plugin-api"; @@ -119,24 +120,28 @@ function invocationPluginContext( state: createPluginState(plugin.manifest.name), }; if (context.source.platform === "slack") { + if (context.destination.platform !== "slack") { + throw new TypeError( + "Slack plugin prompt context requires Slack destination", + ); + } return { ...common, + destination: context.destination, requester: context.requester?.platform === "slack" ? context.requester : undefined, - destination: - context.destination?.platform === "slack" - ? context.destination - : undefined, }; } + if (context.destination.platform !== "local") { + throw new TypeError( + "Local plugin prompt context requires local destination", + ); + } return { ...common, + destination: context.destination, requester: context.requester?.platform === "local" ? context.requester : undefined, - destination: - context.destination?.platform === "local" - ? context.destination - : undefined, }; } @@ -162,26 +167,30 @@ function observationPluginContext( : {}), }; if (context.source.platform === "slack") { + if (context.destination.platform !== "slack") { + throw new TypeError( + "Slack plugin observation context requires Slack destination", + ); + } return { ...common, + destination: context.destination, source: context.source, requester: context.requester?.platform === "slack" ? context.requester : undefined, - destination: - context.destination?.platform === "slack" - ? context.destination - : undefined, }; } + if (context.destination.platform !== "local") { + throw new TypeError( + "Local plugin observation context requires local destination", + ); + } return { ...common, + destination: context.destination, source: context.source, requester: context.requester?.platform === "local" ? context.requester : undefined, - destination: - context.destination?.platform === "local" - ? context.destination - : undefined, }; } @@ -418,7 +427,6 @@ export function getPluginTools( if (!hook) { continue; } - const destination = context.destination; const slackToolContext = getSlackToolContext(context); const credentialSubject = slackToolContext ? createSlackDirectCredentialSubject({ @@ -436,39 +444,49 @@ export function getPluginTools( ...(credentialSubject ? { credentialSubject } : {}), } : undefined; - const pluginContext = - context.source.platform === "slack" - ? { - ...basePluginContext(plugin), - requester: - context.requester?.platform === "slack" - ? context.requester - : undefined, - conversationId: context.conversationId, - destination: - destination?.platform === "slack" ? destination : undefined, - slack: slackContext!, - source: context.source, - userText: context.userText, - embedder: createPluginEmbedder(pluginName), - model: createPluginModel(pluginName), - state: createPluginState(pluginName), - } - : { - ...basePluginContext(plugin), - requester: - context.requester?.platform === "local" - ? context.requester - : undefined, - conversationId: context.conversationId, - destination: - destination?.platform === "local" ? destination : undefined, - source: context.source, - userText: context.userText, - embedder: createPluginEmbedder(pluginName), - model: createPluginModel(pluginName), - state: createPluginState(pluginName), - }; + let pluginContext: ToolRegistrationHookContext; + if (context.source.platform === "slack") { + if (context.destination.platform !== "slack") { + throw new TypeError( + "Slack plugin tool context requires Slack destination", + ); + } + pluginContext = { + ...basePluginContext(plugin), + requester: + context.requester?.platform === "slack" + ? context.requester + : undefined, + conversationId: context.conversationId, + destination: context.destination, + slack: slackContext!, + source: context.source, + userText: context.userText, + embedder: createPluginEmbedder(pluginName), + model: createPluginModel(pluginName), + state: createPluginState(pluginName), + }; + } else { + if (context.destination.platform !== "local") { + throw new TypeError( + "Local plugin tool context requires local destination", + ); + } + pluginContext = { + ...basePluginContext(plugin), + requester: + context.requester?.platform === "local" + ? context.requester + : undefined, + conversationId: context.conversationId, + destination: context.destination, + source: context.source, + userText: context.userText, + embedder: createPluginEmbedder(pluginName), + model: createPluginModel(pluginName), + state: createPluginState(pluginName), + }; + } const pluginTools = hook(pluginContext); for (const [name, tool] of Object.entries(pluginTools)) { if (!PLUGIN_TOOL_NAME_RE.test(name)) { diff --git a/packages/junior/src/chat/plugins/model.ts b/packages/junior/src/chat/plugins/model.ts index c87402fea..262247a3a 100644 --- a/packages/junior/src/chat/plugins/model.ts +++ b/packages/junior/src/chat/plugins/model.ts @@ -7,7 +7,7 @@ export function createPluginModel(pluginName: string): PluginModel { return { async completeObject(input) { const result = await completeObject({ - modelId: botConfig.fastModelId, + modelId: input.modelId ?? botConfig.fastModelId, schema: input.schema, prompt: input.prompt, ...(input.system !== undefined ? { system: input.system } : {}), diff --git a/packages/junior/src/chat/respond.ts b/packages/junior/src/chat/respond.ts index 4c3081cc1..067be1c84 100644 --- a/packages/junior/src/chat/respond.ts +++ b/packages/junior/src/chat/respond.ts @@ -8,12 +8,7 @@ * should stay outside this file. */ import { Agent, type AgentTool } from "@earendil-works/pi-agent-core"; -import { - createLocalSource, - createSlackSource, - type Destination, - type Source, -} from "@sentry/junior-plugin-api"; +import type { Destination, Source } from "@sentry/junior-plugin-api"; import { THREAD_STATE_TTL_MS, type FileUpload } from "chat"; import { botConfig } from "@/chat/config"; import { @@ -213,7 +208,7 @@ export interface ReplyRequestContext { skillDirs?: string[]; credentialContext?: CredentialContext; requester?: Requester; - source?: Source; + source: Source; slackConversation?: SlackConversationContext; destination: Destination; surface?: AgentTurnSurface; @@ -399,9 +394,9 @@ function actorRequesterFromContext( return createRequester(context.requester, { platform: context.requester?.platform ?? - (context.destination?.platform === "slack" ? "slack" : undefined), + (context.destination.platform === "slack" ? "slack" : undefined), teamId: - (context.destination?.platform === "slack" + (context.destination.platform === "slack" ? context.destination.teamId : undefined) ?? context.correlation?.teamId ?? @@ -412,25 +407,6 @@ function actorRequesterFromContext( }); } -function toolInvocationSource(context: ReplyRequestContext): Source { - if (context.source) { - return context.source; - } - if (context.destination.platform !== "slack") { - return createLocalSource(context.destination.conversationId); - } - return createSlackSource({ - teamId: context.destination.teamId, - channelId: context.destination.channelId, - ...(context.correlation?.messageTs - ? { messageTs: context.correlation.messageTs } - : {}), - ...(context.correlation?.threadTs - ? { threadTs: context.correlation.threadTs } - : {}), - }); -} - function toolInvocationDestination(context: ReplyRequestContext): Destination { if (context.destination.platform !== "slack" || !context.toolChannelId) { return context.destination; @@ -647,7 +623,7 @@ export async function generateAssistantReply( const requester = requesterFromContext(context); const actorRequester = actorRequesterFromContext(context); const surface = surfaceFromContext(context); - const runSource = toolInvocationSource(context); + const runSource = context.source; const credentialActor = context.credentialContext?.actor; const credentialActorLogContext = credentialActor ? { @@ -1088,21 +1064,23 @@ export async function generateAssistantReply( const toolDestination = toolInvocationDestination(context); let toolRuntimeContext: ToolRuntimeContext; if (toolSource.platform === "slack") { + if (toolDestination.platform !== "slack") { + throw new TypeError("Slack tool runtime requires a Slack destination"); + } toolRuntimeContext = { ...commonToolRuntimeContext, - ...(toolDestination.platform === "slack" - ? { destination: toolDestination } - : {}), + destination: toolDestination, requester: actorRequester?.platform === "slack" ? actorRequester : undefined, source: toolSource, }; } else { + if (toolDestination.platform !== "local") { + throw new TypeError("Local tool runtime requires a local destination"); + } toolRuntimeContext = { ...commonToolRuntimeContext, - ...(toolDestination.platform === "local" - ? { destination: toolDestination } - : {}), + destination: toolDestination, requester: actorRequester?.platform === "local" ? actorRequester : undefined, source: toolSource, diff --git a/packages/junior/src/chat/tools/slack/context.ts b/packages/junior/src/chat/tools/slack/context.ts index 45c8983a2..d10941cef 100644 --- a/packages/junior/src/chat/tools/slack/context.ts +++ b/packages/junior/src/chat/tools/slack/context.ts @@ -4,10 +4,10 @@ import type { SlackSource } from "@sentry/junior-plugin-api"; import type { SlackRequester } from "@/chat/requester"; export interface SlackToolContext { - destination?: SlackDestination; + destination: SlackDestination; source: SlackSource; requester?: SlackRequester; - destinationChannelId?: string; + destinationChannelId: string; messageTs?: string; sourceChannelId: string; teamId: string; @@ -21,18 +21,15 @@ export function getSlackToolContext( if (context.source.platform !== "slack") { return undefined; } + if (context.destination.platform !== "slack") { + throw new TypeError("Slack source requires a Slack destination"); + } return { - destination: - context.destination?.platform === "slack" - ? context.destination - : undefined, + destination: context.destination, source: context.source, requester: context.requester?.platform === "slack" ? context.requester : undefined, - destinationChannelId: - context.destination?.platform === "slack" - ? context.destination.channelId - : undefined, + destinationChannelId: context.destination.channelId, messageTs: context.source.messageTs, sourceChannelId: context.source.channelId, teamId: context.source.teamId, diff --git a/packages/junior/src/chat/tools/types.ts b/packages/junior/src/chat/tools/types.ts index 3e7bfd82d..b6c563d52 100644 --- a/packages/junior/src/chat/tools/types.ts +++ b/packages/junior/src/chat/tools/types.ts @@ -65,8 +65,8 @@ interface BaseToolRuntimeContext { */ conversationId?: string; - /** Runtime-owned default outbound destination, if this invocation has one. */ - destination?: Destination; + /** Runtime-owned default outbound destination for this invocation. */ + destination: Destination; requester?: Requester; /** Runtime-owned source where this invocation came from. */ @@ -81,13 +81,13 @@ interface BaseToolRuntimeContext { } interface SlackToolRuntimeContext extends BaseToolRuntimeContext { - destination?: SlackDestination; + destination: SlackDestination; requester?: SlackRequester; source: SlackSource; } interface LocalToolRuntimeContext extends BaseToolRuntimeContext { - destination?: LocalDestination; + destination: LocalDestination; requester?: LocalRequester; source: LocalSource; slack?: never; diff --git a/packages/junior/src/cli/init.ts b/packages/junior/src/cli/init.ts index ea4f4ba93..797ace540 100644 --- a/packages/junior/src/cli/init.ts +++ b/packages/junior/src/cli/init.ts @@ -211,6 +211,7 @@ JUNIOR_BOT_NAME= JUNIOR_SLASH_COMMAND= AI_MODEL= AI_FAST_MODEL= +AI_MEMORY_MODEL= AI_EMBEDDING_MODEL= AI_VISION_MODEL= AI_WEB_SEARCH_MODEL= diff --git a/packages/junior/src/reporting/conversations.ts b/packages/junior/src/reporting/conversations.ts index c53f5ae8f..7828815ec 100644 --- a/packages/junior/src/reporting/conversations.ts +++ b/packages/junior/src/reporting/conversations.ts @@ -16,13 +16,8 @@ import type { PluginConversationStatus, PluginConversations, PluginConversationSummary, - Destination, Source, } from "@sentry/junior-plugin-api"; -import { - createLocalSource, - createSlackSource, -} from "@sentry/junior-plugin-api"; import { buildSentryConversationUrl, buildSentryTraceUrl, @@ -1095,28 +1090,18 @@ function countConversationMessages(transcript: TranscriptMessage[]): number { return transcript.filter(isConversationMessage).length; } -function systemPromptMessage(destination: Destination): TranscriptMessage { +function systemPromptMessage(source: Source): TranscriptMessage { return { role: "system", parts: [ { type: "text", - text: buildSystemPrompt({ source: sourceFromDestination(destination) }), + text: buildSystemPrompt({ source }), }, ], }; } -function sourceFromDestination(destination: Destination): Source { - if (destination.platform === "local") { - return createLocalSource(destination.conversationId); - } - return createSlackSource({ - teamId: destination.teamId, - channelId: destination.channelId, - }); -} - interface ScopedTurnMessages { messages: PiMessage[]; startsAtRunBoundary: boolean; @@ -1379,8 +1364,8 @@ export async function readConversationReport( ? [ ...(scopedMessages.startsAtRunBoundary && normalizedTranscript.length > 0 && - sessionRecord?.destination - ? [systemPromptMessage(sessionRecord.destination)] + sessionRecord?.source + ? [systemPromptMessage(sessionRecord.source)] : []), ...normalizedTranscript, ] diff --git a/packages/junior/tests/component/runtime/respond-error-path.test.ts b/packages/junior/tests/component/runtime/respond-error-path.test.ts index 6d5416b7a..1274d820f 100644 --- a/packages/junior/tests/component/runtime/respond-error-path.test.ts +++ b/packages/junior/tests/component/runtime/respond-error-path.test.ts @@ -1,4 +1,8 @@ import { afterAll, describe, expect, it, vi } from "vitest"; +import { + createLocalSource, + createSlackSource, +} from "@sentry/junior-plugin-api"; const originalAiModel = process.env.AI_MODEL; @@ -18,6 +22,16 @@ const LOCAL_DESTINATION = { platform: "local" as const, conversationId: "local:test:respond-error-path", }; +const LOCAL_SOURCE = createLocalSource(LOCAL_DESTINATION.conversationId); +const SLACK_DESTINATION = { + platform: "slack" as const, + teamId: "T123", + channelId: "C123", +}; +const SLACK_SOURCE = createSlackSource({ + teamId: SLACK_DESTINATION.teamId, + channelId: SLACK_DESTINATION.channelId, +}); describe("generateAssistantReply error path", () => { afterAll(() => { @@ -31,6 +45,7 @@ describe("generateAssistantReply error path", () => { it("preserves sandbox dependency hash on non-retryable failures", async () => { const reply = await generateAssistantReply("hello", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, sandbox: { sandboxId: "sb-123", sandboxDependencyProfileHash: "hash-abc", @@ -49,6 +64,7 @@ describe("generateAssistantReply error path", () => { await expect( generateAssistantReply("hello", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, onInputCommitted: async () => { throw new Error("input should not commit before startup succeeds"); }, @@ -69,6 +85,7 @@ describe("generateAssistantReply error path", () => { await expect( generateAssistantReply("hello", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, requester: { platform: "slack", teamId: "T123", @@ -83,11 +100,8 @@ describe("generateAssistantReply error path", () => { it("hard-fails Slack correlation and destination mismatches", async () => { await expect( generateAssistantReply("hello", { - destination: { - platform: "slack", - teamId: "T123", - channelId: "C123", - }, + destination: SLACK_DESTINATION, + source: SLACK_SOURCE, correlation: { channelId: "C999", teamId: "T123", diff --git a/packages/junior/tests/integration/dashboard-reporting.test.ts b/packages/junior/tests/integration/dashboard-reporting.test.ts index deb09819c..0b9b7d6dc 100644 --- a/packages/junior/tests/integration/dashboard-reporting.test.ts +++ b/packages/junior/tests/integration/dashboard-reporting.test.ts @@ -823,6 +823,13 @@ describe("dashboard reporting", () => { teamId: "T123", channelId: "C1", }, + source: { + platform: "slack", + type: "pub", + teamId: "T123", + channelId: "C1", + threadTs: "999", + }, sessionId: "target-turn", sliceId: 1, state: "completed", @@ -876,6 +883,13 @@ describe("dashboard reporting", () => { teamId: "T123", channelId: "C1", }, + source: { + platform: "slack", + type: "pub", + teamId: "T123", + channelId: "C1", + threadTs: "333", + }, sessionId: "turn-one", sliceId: 1, state: "completed", @@ -899,6 +913,13 @@ describe("dashboard reporting", () => { teamId: "T123", channelId: "C1", }, + source: { + platform: "slack", + type: "pub", + teamId: "T123", + channelId: "C1", + threadTs: "333", + }, sessionId: "turn-two", sliceId: 1, state: "completed", diff --git a/packages/junior/tests/integration/plugin-prompt-hooks.test.ts b/packages/junior/tests/integration/plugin-prompt-hooks.test.ts index 9bb8333e2..5a8f43faf 100644 --- a/packages/junior/tests/integration/plugin-prompt-hooks.test.ts +++ b/packages/junior/tests/integration/plugin-prompt-hooks.test.ts @@ -7,7 +7,7 @@ import { it, vi, } from "vitest"; -import type { Destination } from "@sentry/junior-plugin-api"; +import { createLocalSource, type Destination } from "@sentry/junior-plugin-api"; const originalStateAdapter = process.env.JUNIOR_STATE_ADAPTER; process.env.JUNIOR_STATE_ADAPTER = "memory"; @@ -110,6 +110,7 @@ const LOCAL_DESTINATION = { platform: "local", conversationId: "local:test:plugin-prompt-hooks", } satisfies Destination; +const LOCAL_SOURCE = createLocalSource(LOCAL_DESTINATION.conversationId); describe("plugin prompt hooks", () => { let previousPlugins: ReturnType; @@ -159,6 +160,7 @@ describe("plugin prompt hooks", () => { it("renders prompt messages from plugin hooks", async () => { await generateAssistantReply("hello", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, correlation: { conversationId: "conversation-plugin-prompt-hooks", turnId: "turn-plugin-prompt-hooks", @@ -174,6 +176,7 @@ describe("plugin prompt hooks", () => { it("runs user prompt hooks for non-bootstrap follow-up prompts", async () => { await generateAssistantReply("hello", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, correlation: { conversationId: "conversation-plugin-prompt-follow-up", turnId: "turn-plugin-prompt-follow-up-1", @@ -184,6 +187,7 @@ describe("plugin prompt hooks", () => { await generateAssistantReply("again", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, correlation: { conversationId: "conversation-plugin-prompt-follow-up", turnId: "turn-plugin-prompt-follow-up-2", @@ -207,6 +211,7 @@ describe("plugin prompt hooks", () => { it("does not run user prompt hooks for steering messages", async () => { await generateAssistantReply("hello", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, correlation: { conversationId: "conversation-plugin-prompt-steering", turnId: "turn-plugin-prompt-steering", @@ -236,6 +241,7 @@ describe("plugin prompt hooks", () => { await generateAssistantReply("resume me", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, correlation: { conversationId: "conversation-plugin-prompt-resume-before-prompt", turnId: "turn-plugin-prompt-resume-before-prompt", @@ -268,6 +274,7 @@ describe("plugin prompt hooks", () => { await generateAssistantReply("resume me", { destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, correlation: { conversationId: "conversation-plugin-prompt-resume-after-prompt", turnId: "turn-plugin-prompt-resume-after-prompt", diff --git a/packages/junior/tests/unit/runtime/respond-agent-continue.test.ts b/packages/junior/tests/unit/runtime/respond-agent-continue.test.ts index c828ab137..ed4664030 100644 --- a/packages/junior/tests/unit/runtime/respond-agent-continue.test.ts +++ b/packages/junior/tests/unit/runtime/respond-agent-continue.test.ts @@ -1,7 +1,7 @@ import { Buffer } from "node:buffer"; import { setTimeout as realSetTimeout } from "node:timers"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import type { Destination } from "@sentry/junior-plugin-api"; +import { createSlackSource, type Destination } from "@sentry/junior-plugin-api"; import type { PiMessage } from "@/chat/pi/messages"; const { continueCalls, promptAborted, promptCalls, promptMode, promptSettled } = @@ -265,6 +265,11 @@ const TEST_DESTINATION = { teamId: "T123", channelId: "C123", } satisfies Destination; +const TEST_SOURCE = createSlackSource({ + teamId: TEST_DESTINATION.teamId, + channelId: TEST_DESTINATION.channelId, + threadTs: "1712345.0001", +}); const TEST_REQUESTER = { platform: "slack", @@ -296,6 +301,7 @@ describe("generateAssistantReply agent continuation", () => { const error = await generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, onInputCommitted, }).catch((caught) => caught); @@ -306,6 +312,7 @@ describe("generateAssistantReply agent continuation", () => { it("stores the last safe boundary and throws a retryable timeout error", async () => { const replyPromise = generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: TEST_REQUESTER, correlation: { conversationId: "conversation-1", @@ -364,6 +371,7 @@ describe("generateAssistantReply agent continuation", () => { const replyPromise = generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: TEST_REQUESTER, correlation: { conversationId: "conversation-timeout-cap", @@ -397,6 +405,7 @@ describe("generateAssistantReply agent continuation", () => { const startedAtMs = Date.now(); const replyPromise = generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: TEST_REQUESTER, turnDeadlineAtMs: startedAtMs + 2_500, correlation: { @@ -424,6 +433,7 @@ describe("generateAssistantReply agent continuation", () => { it("persists omitted-image context in the session-recorded Pi user message", async () => { const replyPromise = generateAssistantReply("what is in this image?", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: TEST_REQUESTER, omittedImageAttachmentCount: 1, correlation: { @@ -463,6 +473,7 @@ describe("generateAssistantReply agent continuation", () => { promptMode.value = "hangsAfterAbort"; const replyPromise = generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: TEST_REQUESTER, correlation: { conversationId: "conversation-hung", @@ -507,6 +518,7 @@ describe("generateAssistantReply agent continuation", () => { promptMode.value = "providerRetryThenHangs"; const replyPromise = generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: TEST_REQUESTER, correlation: { conversationId: "conversation-retry", diff --git a/packages/junior/tests/unit/runtime/respond-lazy-sandbox.test.ts b/packages/junior/tests/unit/runtime/respond-lazy-sandbox.test.ts index 11c63e6ed..ebe54ead8 100644 --- a/packages/junior/tests/unit/runtime/respond-lazy-sandbox.test.ts +++ b/packages/junior/tests/unit/runtime/respond-lazy-sandbox.test.ts @@ -1,4 +1,5 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; +import { createLocalSource } from "@sentry/junior-plugin-api"; const { agentMode, @@ -524,14 +525,16 @@ const LOCAL_DESTINATION = { platform: "local" as const, conversationId: "local:test:respond-lazy-sandbox", }; +const LOCAL_SOURCE = createLocalSource(LOCAL_DESTINATION.conversationId); function generateLocalReply( message: string, - context: Omit = {}, + context: Omit = {}, ) { return generateAssistantReply(message, { ...context, destination: LOCAL_DESTINATION, + source: LOCAL_SOURCE, }); } diff --git a/packages/junior/tests/unit/runtime/respond-mcp-progressive-loading.test.ts b/packages/junior/tests/unit/runtime/respond-mcp-progressive-loading.test.ts index 5525562ad..c6ac04aa6 100644 --- a/packages/junior/tests/unit/runtime/respond-mcp-progressive-loading.test.ts +++ b/packages/junior/tests/unit/runtime/respond-mcp-progressive-loading.test.ts @@ -1,4 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import type { PiMessage } from "@/chat/pi/messages"; import type { ConversationPendingAuthState } from "@/chat/state/conversation"; @@ -101,15 +102,21 @@ function makeReplyContext(args: { threadTs: string; turnId: string; }) { + const destination = { + platform: "slack" as const, + teamId: "T123", + channelId: "C123", + }; return { credentialContext: { actor: { type: "user" as const, userId: "U123" }, }, - destination: { - platform: "slack" as const, - teamId: "T123", - channelId: "C123", - }, + destination, + source: createSlackSource({ + teamId: destination.teamId, + channelId: destination.channelId, + threadTs: args.threadTs, + }), requester: TEST_REQUESTER, recordPendingAuth: async (pendingAuth: ConversationPendingAuthState) => { pendingAuthRecords.push(pendingAuth); @@ -1164,6 +1171,11 @@ describe("generateAssistantReply progressive MCP loading", () => { teamId: "T123", channelId: "C123", }, + source: createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "1712345.0003", + }), requester: TEST_REQUESTER, recordPendingAuth: async (pendingAuth: ConversationPendingAuthState) => { pendingAuthRecords.push(pendingAuth); @@ -1257,6 +1269,11 @@ describe("generateAssistantReply progressive MCP loading", () => { teamId: "T123", channelId: "C123", }, + source: createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "1712345.0005", + }), requester: TEST_REQUESTER, recordPendingAuth: async (pendingAuth: ConversationPendingAuthState) => { pendingAuthRecords.push(pendingAuth); @@ -1296,6 +1313,11 @@ describe("generateAssistantReply progressive MCP loading", () => { teamId: "T123", channelId: "C123", }, + source: createSlackSource({ + teamId: "T123", + channelId: "C123", + threadTs: "1712345.0006", + }), requester: TEST_REQUESTER, recordPendingAuth: async (pendingAuth: ConversationPendingAuthState) => { pendingAuthRecords.push(pendingAuth); diff --git a/packages/junior/tests/unit/runtime/respond-provider-retry.test.ts b/packages/junior/tests/unit/runtime/respond-provider-retry.test.ts index 6707b2f2c..d6b150d8b 100644 --- a/packages/junior/tests/unit/runtime/respond-provider-retry.test.ts +++ b/packages/junior/tests/unit/runtime/respond-provider-retry.test.ts @@ -1,7 +1,7 @@ import { Buffer } from "node:buffer"; import { setTimeout as realSetTimeout } from "node:timers"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import type { Destination } from "@sentry/junior-plugin-api"; +import { createSlackSource, type Destination } from "@sentry/junior-plugin-api"; import type { PiMessage } from "@/chat/pi/messages"; const { agentMode, counters } = vi.hoisted(() => ({ @@ -270,6 +270,11 @@ const TEST_DESTINATION = { teamId: "T123", channelId: "C123", } satisfies Destination; +const TEST_SOURCE = createSlackSource({ + teamId: TEST_DESTINATION.teamId, + channelId: TEST_DESTINATION.channelId, + threadTs: "1712345.0001", +}); describe("generateAssistantReply provider retry", () => { beforeEach(async () => { @@ -291,6 +296,7 @@ describe("generateAssistantReply provider retry", () => { it("continues from the last safe boundary after a transient provider stream error", async () => { const replyPromise = generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: { platform: "slack", teamId: "T123", userId: "U123" }, correlation: { conversationId: "conversation-1", @@ -362,6 +368,7 @@ describe("generateAssistantReply provider retry", () => { const reply = await generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, piMessages: priorMessages, requester: { platform: "slack", teamId: "T123", userId: "U123" }, correlation: { @@ -420,6 +427,7 @@ describe("generateAssistantReply provider retry", () => { const error = await generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: { platform: "slack", teamId: "T123", userId: "U123" }, correlation: { conversationId: "conversation-yield", @@ -474,6 +482,7 @@ describe("generateAssistantReply provider retry", () => { threadTs: "1712345.0005", }, destination: TEST_DESTINATION, + source: TEST_SOURCE, drainSteeringMessages: async (inject) => { const messages = [ { text: "actually do the other thing", timestampMs: 2_000 }, @@ -517,6 +526,7 @@ describe("generateAssistantReply provider retry", () => { const error = await generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: { platform: "slack", teamId: "T123", userId: "U123" }, correlation: { conversationId: "conversation-yield-persist-failure", @@ -551,6 +561,7 @@ describe("generateAssistantReply provider retry", () => { await generateAssistantReply("help me", { destination: TEST_DESTINATION, + source: TEST_SOURCE, requester: { platform: "slack", teamId: "T123", userId: "U123" }, correlation: { conversationId: "conversation-steering-failure", diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 813ee65f0..7dfbd9648 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -68,22 +68,25 @@ The observation hook must: observation failure cannot fail delivery. 2. Invoke the memory-owned extraction agent with bounded user-authored turn text. -3. Ignore assistant-authored claims as memory sources. -4. Skip passive extraction for unsupported sources. V1 supports local CLI +3. Provide visible existing memories as dedupe context only, not as source + evidence for new memories. +4. Ignore assistant-authored claims as memory sources. +5. Skip passive extraction for unsupported sources. V1 supports local CLI observations and `pub` sources with a stable source key. Non-local `priv` sources and sources without stable identity are ignored before model extraction. -5. Skip passive extraction when the completed turn already called a +6. Skip passive extraction when the completed turn already called a memory-management tool (`createMemory`, `listMemories`, `searchMemories`, or `removeMemory`); the explicit tool path owns `createMemory` writes. -6. Extract candidate facts with a structured model output contract. -7. Reject malformed, incoherent, unsafe, out-of-scope, or non-durable facts. -8. Assign requester or conversation target from memory-agent output, while +7. Extract candidate facts with a structured model output contract. +8. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or + non-durable facts. +9. Assign requester or conversation target from memory-agent output, while deriving all authority-bearing ids from runtime context. -9. Insert accepted memories idempotently with a stable key derived through the - runtime source helper, turn id, and extracted fact position. -10. Generate embeddings for accepted rows when the host embedder is configured. -11. Avoid storing raw extraction prompt, raw model output, or raw turn text +10. Insert accepted memories idempotently with a stable key derived through the + runtime source helper, turn id, and extracted fact position. +11. Generate embeddings for accepted rows when the host embedder is configured. +12. Avoid storing raw extraction prompt, raw model output, or raw turn text beyond the accepted memory records. Observation hooks are best effort. If extraction or storage fails, Junior logs @@ -156,7 +159,15 @@ fields are part of the bounded extraction input. Prompt inputs should use the same structured context-block style as Junior's turn context, with separate `` and source blocks. Explicit `createMemory` review uses a singular `` block and the current user-authored message as bounded source -context. Passive extraction uses only the completed turn's user-authored text. +context. Passive extraction uses the completed turn's user-authored text plus +visible existing memories for dedupe. Existing memories must not be used as +source evidence for new facts. + +The memory agent model is host-owned but selected by the memory plugin. An +explicit `createMemoryPlugin({ modelId })` option wins, then `AI_MEMORY_MODEL`, +then the host structured-model default. Model choice is an implementation +tuning knob; runtime context, source authority, and storage validation remain +the boundary. Memory agent output must be structured. For explicit review it should include: @@ -165,14 +176,17 @@ Memory agent output must be structured. For explicit review it should include: - optional adjusted memory type, subject, scope, expiration, or content rewrite For passive extraction it should include an array of accepted candidate -memories with target, canonical content, and optional expiration. Rejections are +memories with target, canonical stored content, and optional expiration. +Requester-target passive memories in V1 focus on durable first-person +preferences, opinions, and habits. Broader public requester facts can still be +handled by the explicit reviewed `createMemory` path. Rejections are represented by omitting a candidate from the array. -The structured content field is the canonical stored memory text. The memory -agent must use that field to return perspective-neutral fact text. For example, -`I prefer terse PR summaries` should become `Prefers terse PR summaries`, and -`This thread says deploy runbooks live in Notion` should become -`Deploy runbooks live in Notion`. +The content field is canonical stored memory text. Requester memory content +must omit ownership from prose because ownership lives in structured metadata. +For example, `I prefer terse PR summaries` should become requester memory +`Prefers terse PR summaries`, and `This thread says deploy runbooks live in +Notion` should become conversation memory `Deploy runbooks live in Notion`. The memory agent may narrow, rewrite, or reject extracted candidates, but it may not override hard structural validators. If extraction and review disagree, diff --git a/specs/memory-plugin/tools.md b/specs/memory-plugin/tools.md index cdf92609d..ceab2d526 100644 --- a/specs/memory-plugin/tools.md +++ b/specs/memory-plugin/tools.md @@ -64,6 +64,11 @@ should call `createMemory` for those requests instead of asking the requester to rephrase them as safer memory text. The memory agent owns the semantic store-or-reject decision and canonical rewrite. +The outer agent should not call `createMemory` for ordinary organic statements +that merely reveal a durable preference or fact. Those are passive-learning +candidates handled by completed-turn observation, not explicit memory-tool +requests. + The explicit tool path uses runtime context for source and idempotency. It must run through the memory agent's explicit-create review path. The memory agent decides store/reject, canonical perspective-neutral content, subject, and diff --git a/specs/plugin-dispatch.md b/specs/plugin-dispatch.md index 3ee76169e..ee5797e7c 100644 --- a/specs/plugin-dispatch.md +++ b/specs/plugin-dispatch.md @@ -156,7 +156,7 @@ Stored dispatch records include: - result timestamp or error message Plugin-visible `Dispatch` is a projection, not the stored record. -Core persists dispatch records only after plugin input has parsed through the shared schema and runtime credential binding has succeeded. Every callback, recovery, and projection path must parse stored dispatch records before use; malformed records are invalid state and must not be repaired from nearby Slack channel/thread metadata during normal runtime reads. Legacy dispatch records that predate stored `source` may derive source from their stored Slack destination only; new dispatch requests must provide `source` explicitly. +Core persists dispatch records only after plugin input has parsed through the shared schema and runtime credential binding has succeeded. Every callback, recovery, and projection path must parse stored dispatch records before use; malformed records are invalid state and must not be repaired from nearby Slack channel/thread metadata during normal runtime reads. Dispatch requests and persisted records must provide `source` explicitly. Dispatch ids should be deterministic from plugin name and idempotency key. Duplicate calls return the existing dispatch id and may re-fire the callback only when the record is incomplete. diff --git a/specs/plugin-prompt-hooks.md b/specs/plugin-prompt-hooks.md index 2fd76d045..82bc79f05 100644 --- a/specs/plugin-prompt-hooks.md +++ b/specs/plugin-prompt-hooks.md @@ -140,7 +140,7 @@ Rules: interface UserPromptContext { conversationId?: string; db: object; - destination?: Destination; + destination: Destination; embedder: PluginEmbedder; log: PluginLogger; plugin: PluginMetadata; @@ -151,8 +151,9 @@ interface UserPromptContext { } ``` -`Source` is a runtime-normalized origin for the current turn. It must include -`platform`, `type`, and a platform conversation id: +`Source` is a runtime-normalized origin for the current turn. Slack sources use +the same address fields as Slack destinations plus source visibility and inbound +message metadata: ```ts type SourceType = "pub" | "priv"; @@ -162,7 +163,6 @@ type Source = platform: "slack"; type: SourceType; teamId: string; - conversationId: string; channelId: string; messageTs?: string; threadTs?: string; diff --git a/specs/plugin-runtime.md b/specs/plugin-runtime.md index 8d21bf139..b185e4323 100644 --- a/specs/plugin-runtime.md +++ b/specs/plugin-runtime.md @@ -140,9 +140,11 @@ Tool registration contexts receive `ctx.model`, a host-owned structured completion capability for plugin-owned semantic review before tool execution. `ctx.model` accepts a strict schema plus prompt text and uses Junior's configured model boundary without exposing provider credentials, SDK clients, -provider names, or model-visible tools to plugins. Tool registration contexts -also receive `ctx.embedder`, the separate host-owned embedding capability for -derived retrieval indexes. Current hook contracts are defined in +provider names, or model-visible tools to plugins. Plugins may pass a host +model id override for their own structured call; the host still owns provider +resolution and credentials. Tool registration contexts also receive +`ctx.embedder`, the separate host-owned embedding capability for derived +retrieval indexes. Current hook contracts are defined in [Plugin Database Spec](./plugin-database.md), [Plugin CLI Spec](./plugin-cli.md), [Plugin Heartbeat Spec](./plugin-heartbeat.md), [Plugin Dispatch Spec](./plugin-dispatch.md), [Plugin Background Tasks From b5faff33873625d0f1963d9bcc0d98fbbf7801ea Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 07:55:43 -0700 Subject: [PATCH 09/29] fix(memory): Allow passive learning after recall tools Only explicit memory mutation tools should suppress passive extraction. Recall tools can run during an ordinary turn and still leave durable facts for the memory agent to extract afterward. Co-Authored-By: GPT-5 Codex --- packages/junior-memory/src/observe.ts | 13 +++++----- packages/junior-memory/src/plugin.ts | 9 +++---- packages/junior-memory/tests/storage.test.ts | 27 +++++++++++++++++++- specs/memory-plugin/extraction.md | 6 ++--- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/observe.ts index 5403624d5..136d626c3 100644 --- a/packages/junior-memory/src/observe.ts +++ b/packages/junior-memory/src/observe.ts @@ -15,12 +15,7 @@ import { } from "./agent"; import { memoryRuntimeContextSchema } from "./types"; -const MEMORY_TOOL_NAMES = new Set([ - "createMemory", - "listMemories", - "removeMemory", - "searchMemories", -]); +const MEMORY_MUTATION_TOOL_NAMES = new Set(["createMemory", "removeMemory"]); function passiveInput( context: TurnObservationContext, @@ -40,7 +35,11 @@ export async function observeMemoryTurn( context: TurnObservationContext, options: MemoryAgentOptions = {}, ): Promise { - if (context.toolCalls.some((toolName) => MEMORY_TOOL_NAMES.has(toolName))) { + if ( + context.toolCalls.some((toolName) => + MEMORY_MUTATION_TOOL_NAMES.has(toolName), + ) + ) { return; } if (context.source.platform !== "local" && isPrivateSource(context.source)) { diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index 44e0d038d..adef8f3c3 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -51,6 +51,7 @@ function memoryToolContext(ctx: { /** Create Junior's long-term memory plugin registration. */ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { const modelId = memoryModelId(options); + const agentOptions = modelId ? { modelId } : {}; return defineJuniorPlugin({ manifest: { name: "memory", @@ -65,9 +66,7 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { tools(ctx) { const context = memoryToolContext({ ...ctx, - agent: createMemoryAgent(ctx.model, { - ...(modelId ? { modelId } : {}), - }), + agent: createMemoryAgent(ctx.model, agentOptions), db: ctx.db as MemoryDb, embedder: ctx.embedder, }); @@ -89,9 +88,7 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { }); }, async observeTurn(ctx) { - await observeMemoryTurn(ctx, { - ...(modelId ? { modelId } : {}), - }); + await observeMemoryTurn(ctx, agentOptions); }, }, }); diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index f47a0e104..3cd7dc3cc 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -558,7 +558,7 @@ describe("memory plugin storage", () => { } }, 15_000); - it("skips passive extraction for successful memory tool turns", async () => { + it("skips passive extraction for successful memory mutation tool turns", async () => { const { model, calls } = extractionModel([ { target: "requester", @@ -577,6 +577,31 @@ describe("memory plugin storage", () => { expect(calls).toEqual([]); }); + it("does not skip passive extraction for memory recall tool turns", async () => { + const fixture = await createMemoryFixture(); + try { + const { model, calls } = extractionModel([ + { + target: "requester", + content: "recall turns can still learn durable facts", + }, + ]); + + await observeMemoryTurn( + observationContext({ + db: memoryDb(fixture), + model, + toolCalls: ["listMemories", "searchMemories"], + userText: "I prefer recall turns to still learn durable facts.", + }), + ); + + expect(calls).toHaveLength(1); + } finally { + await fixture.close(); + } + }, 15_000); + it("skips passive extraction in private Slack contexts", async () => { const { model, calls } = extractionModel([ { diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 7dfbd9648..06789c520 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -75,9 +75,9 @@ The observation hook must: observations and `pub` sources with a stable source key. Non-local `priv` sources and sources without stable identity are ignored before model extraction. -6. Skip passive extraction when the completed turn already called a - memory-management tool (`createMemory`, `listMemories`, `searchMemories`, or - `removeMemory`); the explicit tool path owns `createMemory` writes. +6. Skip passive extraction when the completed turn already called an explicit + memory mutation tool (`createMemory` or `removeMemory`). Recall tools + (`listMemories` and `searchMemories`) must not suppress passive extraction. 7. Extract candidate facts with a structured model output contract. 8. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or non-durable facts. From 8a073f0bd79dbac8cf31888ad5deea0b7c6cde54 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 08:08:55 -0700 Subject: [PATCH 10/29] test(plugins): Align Slack source hook expectation Slack sources expose runtime-owned Slack address fields while the opaque Junior conversation id is passed separately on the plugin context. Update the hook assertion to match the strict source schema. Co-Authored-By: GPT-5 Codex --- packages/junior/tests/unit/plugins/agent-hooks.test.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/junior/tests/unit/plugins/agent-hooks.test.ts b/packages/junior/tests/unit/plugins/agent-hooks.test.ts index 5d27affe2..46564a44d 100644 --- a/packages/junior/tests/unit/plugins/agent-hooks.test.ts +++ b/packages/junior/tests/unit/plugins/agent-hooks.test.ts @@ -111,22 +111,21 @@ function fakeSandbox( } describe("agent plugin hooks", () => { - it("keeps Slack sources private unless the caller marks them public", () => { + it("infers Slack source visibility from channel identity", () => { expect( createSlackSource({ teamId: "T123", channelId: "C123", threadTs: "1718800000.000000", }).type, - ).toBe("priv"); + ).toBe("pub"); expect( createSlackSource({ teamId: "T123", - channelId: "C123", + channelId: "D123", threadTs: "1718800000.000000", - type: "pub", }).type, - ).toBe("pub"); + ).toBe("priv"); }); it("collects system prompt contributions from configured plugins", async () => { From 5e353b5afa137d6a63eb2f7efbde03e1020dfc42 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 08:53:12 -0700 Subject: [PATCH 11/29] fix(plugins): Infer Slack source visibility Derive Slack source visibility from deterministic Slack channel ID prefixes instead of accepting caller-provided type values. Public channels use C-prefixed IDs, while D-prefixed direct messages and G-prefixed private or multi-party conversations are private. Fail closed for unknown prefixes so new Slack ID forms do not silently get the wrong memory visibility. Remove the temporary fixture type arguments now that createSlackSource owns the mapping. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 1 - packages/junior-memory/tests/storage.test.ts | 1 - packages/junior-plugin-api/src/context.ts | 27 ++++--------------- .../junior/src/chat/runtime/reply-executor.ts | 1 - .../component/memory-plugin-storage.test.ts | 1 - .../runtime/agent-continue-runner.test.ts | 1 - .../services/turn-session-record.test.ts | 1 - .../integration/agent-dispatch-runner.test.ts | 4 +-- .../tests/integration/heartbeat.test.ts | 6 ++--- .../mcp-oauth-callback-slack.test.ts | 1 - .../integration/oauth-callback-slack.test.ts | 2 -- .../integration/oauth-resume-slack.test.ts | 1 - .../integration/slack-channel-tools.test.ts | 1 - .../integration/slack-schedule-tools.test.ts | 4 --- .../integration/slack-thread-read.test.ts | 1 - .../integration/slack-user-lookup.test.ts | 1 - .../integration/tool-idempotency.test.ts | 1 - .../unit/handlers/oauth-callback.test.ts | 1 - .../tests/unit/handlers/oauth-resume.test.ts | 1 - .../tests/unit/plugins/agent-hooks.test.ts | 17 +++++++++--- packages/junior/tests/unit/prompt.test.ts | 3 --- .../runtime/agent-dispatch-validation.test.ts | 1 - .../services/mcp-auth-orchestration.test.ts | 1 - .../plugin-auth-orchestration.test.ts | 1 - .../slack-message-add-reaction-tool.test.ts | 1 - .../unit/slack/tool-registration.test.ts | 1 - 26 files changed, 22 insertions(+), 60 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index bd60628e8..d540c4d4c 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -39,7 +39,6 @@ async function seedMemory(args: { messageTs: args.thread.thread_ts, teamId: memoryTeamId, threadTs: args.thread.thread_ts, - type: args.thread.channel_type === "im" ? "priv" : "pub", }), }); const input = { diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 3cd7dc3cc..715242535 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -231,7 +231,6 @@ function slackContext( channelId, messageTs: threadTs, threadTs, - type: overrides.sourceType ?? "pub", }), }; } diff --git a/packages/junior-plugin-api/src/context.ts b/packages/junior-plugin-api/src/context.ts index d3721e2e1..e78aa228d 100644 --- a/packages/junior-plugin-api/src/context.ts +++ b/packages/junior-plugin-api/src/context.ts @@ -18,7 +18,6 @@ export type Source = z.output; export type SlackSource = Extract; export type LocalSource = Extract; export type SourceType = Source["type"]; -export type SlackChannelType = "channel" | "group" | "im" | "mpim"; export type Destination = z.output; @@ -94,14 +93,13 @@ export type InvocationContext = LocalInvocationContext | SlackInvocationContext; /** Build a normalized Slack source from runtime-owned Slack coordinates. */ export function createSlackSource(input: { channelId: string; - channelType?: SlackChannelType; messageTs?: string; teamId: string; threadTs?: string; }): SlackSource { return { platform: "slack", - type: slackSourceType(input), + type: slackSourceType(input.channelId), teamId: input.teamId, channelId: input.channelId, ...(input.messageTs ? { messageTs: input.messageTs } : {}), @@ -109,25 +107,10 @@ export function createSlackSource(input: { }; } -function slackSourceType(input: { - channelId: string; - channelType?: SlackChannelType; -}): SourceType { - if (input.channelType === "channel") return "pub"; - if ( - input.channelType === "group" || - input.channelType === "im" || - input.channelType === "mpim" - ) { - return "priv"; - } - if (input.channelId.startsWith("D") || input.channelId.startsWith("G")) { - return "priv"; - } - if (input.channelId.startsWith("C")) { - return "pub"; - } - throw new Error(`Unsupported Slack channel ID prefix: ${input.channelId}`); +function slackSourceType(channelId: string): SourceType { + if (channelId.startsWith("C")) return "pub"; + if (channelId.startsWith("D") || channelId.startsWith("G")) return "priv"; + throw new Error(`Unsupported Slack channel ID prefix: ${channelId}`); } /** Build a normalized local source from a local conversation id. */ diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 3137622af..4193c7868 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -313,7 +313,6 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { const teamId = destination.teamId; const source = createSlackSource({ channelId: channelId ?? destination.channelId, - channelType: slackChannelType, messageTs, teamId, threadTs, diff --git a/packages/junior/tests/component/memory-plugin-storage.test.ts b/packages/junior/tests/component/memory-plugin-storage.test.ts index 5162c41ac..a01feb9d9 100644 --- a/packages/junior/tests/component/memory-plugin-storage.test.ts +++ b/packages/junior/tests/component/memory-plugin-storage.test.ts @@ -126,7 +126,6 @@ WHERE table_name = 'junior_memory_memories' const source = createSlackSource({ teamId: "T123", channelId: "C123", - channelType: "channel", messageTs: "1718800000.000000", threadTs: "1718800000.000000", }); diff --git a/packages/junior/tests/component/runtime/agent-continue-runner.test.ts b/packages/junior/tests/component/runtime/agent-continue-runner.test.ts index 89cb43ca0..10a54286c 100644 --- a/packages/junior/tests/component/runtime/agent-continue-runner.test.ts +++ b/packages/junior/tests/component/runtime/agent-continue-runner.test.ts @@ -11,7 +11,6 @@ import { SLACK_DESTINATION } from "../../fixtures/conversation-work"; const SLACK_SOURCE = createSlackSource({ teamId: SLACK_DESTINATION.teamId, channelId: SLACK_DESTINATION.channelId, - channelType: "channel", threadTs: "1712345.0005", }); diff --git a/packages/junior/tests/component/services/turn-session-record.test.ts b/packages/junior/tests/component/services/turn-session-record.test.ts index d729861cf..5af470e9e 100644 --- a/packages/junior/tests/component/services/turn-session-record.test.ts +++ b/packages/junior/tests/component/services/turn-session-record.test.ts @@ -17,7 +17,6 @@ const SLACK_SOURCE = createSlackSource({ teamId: "T123", channelId: "C123", threadTs: "1700000000.001", - type: "pub", }) satisfies Source; function userMessage(text: string): PiMessage { diff --git a/packages/junior/tests/integration/agent-dispatch-runner.test.ts b/packages/junior/tests/integration/agent-dispatch-runner.test.ts index 2322576aa..7cc8b9f26 100644 --- a/packages/junior/tests/integration/agent-dispatch-runner.test.ts +++ b/packages/junior/tests/integration/agent-dispatch-runner.test.ts @@ -81,9 +81,7 @@ function slackAddress(channelId = "C123") { function slackSource(channelId = "C123") { return createSlackSource({ - teamId: "T123", - channelId, - channelType: channelId.startsWith("C") ? "channel" : "im", + ...slackAddress(channelId), }); } diff --git a/packages/junior/tests/integration/heartbeat.test.ts b/packages/junior/tests/integration/heartbeat.test.ts index a8bba24f7..2e2b10842 100644 --- a/packages/junior/tests/integration/heartbeat.test.ts +++ b/packages/junior/tests/integration/heartbeat.test.ts @@ -48,16 +48,13 @@ const SLACK_DESTINATION = { channelId: "C123", } satisfies Destination; const SLACK_SOURCE = createSlackSource({ - teamId: "T123", - channelId: "C123", - channelType: "channel", + ...SLACK_DESTINATION, }) satisfies Source; function slackDmSource(channelId = "D123"): Source { return createSlackSource({ teamId: "T123", channelId, - channelType: "im", }); } @@ -72,6 +69,7 @@ function createTask(overrides: Partial = {}): ScheduledTask { const nextRunAtMs = TEST_RUN_AT_MS; return { id: "sched_plugin_1", + conversationAccess: { audience: "channel", visibility: "public" }, createdAtMs: nextRunAtMs, createdBy: { slackUserId: "U123" }, destination: SLACK_DESTINATION, diff --git a/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts b/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts index 13947a81c..13ba575ff 100644 --- a/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts +++ b/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts @@ -191,7 +191,6 @@ describe("mcp oauth callback slack integration", () => { channelId: "C123", messageTs: "1700000000.mcp-source", threadTs: "1700000000.001", - type: "pub", }); await stateAdapterModule.getStateAdapter().set(`thread-state:${threadId}`, { diff --git a/packages/junior/tests/integration/oauth-callback-slack.test.ts b/packages/junior/tests/integration/oauth-callback-slack.test.ts index 85dcd3650..10472c02b 100644 --- a/packages/junior/tests/integration/oauth-callback-slack.test.ts +++ b/packages/junior/tests/integration/oauth-callback-slack.test.ts @@ -113,7 +113,6 @@ describe("oauth callback slack integration", () => { channelId: "C123", messageTs: "1700000000.oauth-source", threadTs: "1700000000.001", - type: "pub", }); await stateAdapterModule .getStateAdapter() @@ -200,7 +199,6 @@ describe("oauth callback slack integration", () => { channelId: "C123", messageTs: "1700000000.session-source", threadTs: "1700000000.009", - type: "pub", }); await turnSessionStoreModule.upsertAgentTurnSessionRecord({ diff --git a/packages/junior/tests/integration/oauth-resume-slack.test.ts b/packages/junior/tests/integration/oauth-resume-slack.test.ts index 20a647eda..241723940 100644 --- a/packages/junior/tests/integration/oauth-resume-slack.test.ts +++ b/packages/junior/tests/integration/oauth-resume-slack.test.ts @@ -38,7 +38,6 @@ function testSlackSource(threadTs: string) { return createSlackSource({ teamId: TEST_SLACK_DESTINATION.teamId, channelId: TEST_SLACK_DESTINATION.channelId, - channelType: "channel", threadTs, }); } diff --git a/packages/junior/tests/integration/slack-channel-tools.test.ts b/packages/junior/tests/integration/slack-channel-tools.test.ts index 4bf6fa200..9cb8be655 100644 --- a/packages/junior/tests/integration/slack-channel-tools.test.ts +++ b/packages/junior/tests/integration/slack-channel-tools.test.ts @@ -51,7 +51,6 @@ function createContext( source: createSlackSource({ teamId: "T123", channelId: sourceChannelId, - channelType: sourceChannelId.startsWith("C") ? "channel" : "im", messageTs: "1700000000.321", }), destinationChannelId, diff --git a/packages/junior/tests/integration/slack-schedule-tools.test.ts b/packages/junior/tests/integration/slack-schedule-tools.test.ts index c8ad75fa4..4030c4657 100644 --- a/packages/junior/tests/integration/slack-schedule-tools.test.ts +++ b/packages/junior/tests/integration/slack-schedule-tools.test.ts @@ -71,7 +71,6 @@ function createContext( source: createSlackSource({ teamId, channelId, - channelType: channelId.startsWith("C") ? "channel" : "im", }), requester: { platform: "slack", @@ -328,7 +327,6 @@ describe("Slack schedule tools", () => { source: createSlackSource({ teamId: TEST_TEAM_ID, channelId: "C123", - channelType: "channel", threadTs: "1700000000.000", }), }), @@ -889,7 +887,6 @@ describe("Slack schedule tools", () => { ...createSlackSource({ teamId: TEST_TEAM_ID, channelId: "D123", - channelType: "im", }), teamId: TEST_TEAM_ID, channelId: "slack:D123:1700000000.000", @@ -1222,7 +1219,6 @@ describe("Slack schedule tool wiring via getPluginTools", () => { source: createSlackSource({ teamId: TEAM_ID, channelId: "DDM", - channelType: "im", }), destination: { platform: "slack", diff --git a/packages/junior/tests/integration/slack-thread-read.test.ts b/packages/junior/tests/integration/slack-thread-read.test.ts index d9e5ea898..b33776423 100644 --- a/packages/junior/tests/integration/slack-thread-read.test.ts +++ b/packages/junior/tests/integration/slack-thread-read.test.ts @@ -26,7 +26,6 @@ function createContext( createSlackSource({ teamId: "T123", channelId: sourceChannelId, - channelType: sourceChannelId.startsWith("C") ? "channel" : "im", }), destinationChannelId, sourceChannelId, diff --git a/packages/junior/tests/integration/slack-user-lookup.test.ts b/packages/junior/tests/integration/slack-user-lookup.test.ts index d7b0fca4f..ce170b6f0 100644 --- a/packages/junior/tests/integration/slack-user-lookup.test.ts +++ b/packages/junior/tests/integration/slack-user-lookup.test.ts @@ -346,7 +346,6 @@ describe("slackUserLookup", () => { source: createSlackSource({ teamId: "T_TEST", channelId: "C_TEST", - channelType: "channel", }), destination: { platform: "slack", diff --git a/packages/junior/tests/integration/tool-idempotency.test.ts b/packages/junior/tests/integration/tool-idempotency.test.ts index 42b97ea69..d3f453396 100644 --- a/packages/junior/tests/integration/tool-idempotency.test.ts +++ b/packages/junior/tests/integration/tool-idempotency.test.ts @@ -60,7 +60,6 @@ function slackContext(channelId: string): SlackToolContext { source: createSlackSource({ teamId: "T123", channelId, - channelType: channelId.startsWith("C") ? "channel" : "im", }), destinationChannelId: channelId, sourceChannelId: channelId, diff --git a/packages/junior/tests/unit/handlers/oauth-callback.test.ts b/packages/junior/tests/unit/handlers/oauth-callback.test.ts index a16ee78fb..8347c68bf 100644 --- a/packages/junior/tests/unit/handlers/oauth-callback.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-callback.test.ts @@ -661,7 +661,6 @@ describe("oauth callback handler", () => { teamId: "T123", channelId: "C123", threadTs: "123.789", - type: "pub", }), threadTs: "123.789", pendingMessage: "list my sentry issues", diff --git a/packages/junior/tests/unit/handlers/oauth-resume.test.ts b/packages/junior/tests/unit/handlers/oauth-resume.test.ts index 371a8726b..717fa6477 100644 --- a/packages/junior/tests/unit/handlers/oauth-resume.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-resume.test.ts @@ -80,7 +80,6 @@ function testSlackSource(threadTs: string) { return createSlackSource({ teamId: TEST_SLACK_DESTINATION.teamId, channelId: TEST_SLACK_DESTINATION.channelId, - channelType: "channel", threadTs, }); } diff --git a/packages/junior/tests/unit/plugins/agent-hooks.test.ts b/packages/junior/tests/unit/plugins/agent-hooks.test.ts index 46564a44d..eacf77be0 100644 --- a/packages/junior/tests/unit/plugins/agent-hooks.test.ts +++ b/packages/junior/tests/unit/plugins/agent-hooks.test.ts @@ -49,14 +49,12 @@ const SLACK_DESTINATION = { const SLACK_SOURCE = createSlackSource({ teamId: SLACK_DESTINATION.teamId, channelId: SLACK_DESTINATION.channelId, - channelType: "im", }); function slackSource(channelId: string) { return createSlackSource({ teamId: "T123", channelId, - channelType: channelId.startsWith("C") ? "channel" : "im", }); } @@ -111,7 +109,7 @@ function fakeSandbox( } describe("agent plugin hooks", () => { - it("infers Slack source visibility from channel identity", () => { + it("infers Slack source visibility from channel ID prefixes", () => { expect( createSlackSource({ teamId: "T123", @@ -126,6 +124,19 @@ describe("agent plugin hooks", () => { threadTs: "1718800000.000000", }).type, ).toBe("priv"); + expect( + createSlackSource({ + teamId: "T123", + channelId: "G123", + threadTs: "1718800000.000000", + }).type, + ).toBe("priv"); + expect(() => + createSlackSource({ + teamId: "T123", + channelId: "X123", + }), + ).toThrow("Unsupported Slack channel ID prefix"); }); it("collects system prompt contributions from configured plugins", async () => { diff --git a/packages/junior/tests/unit/prompt.test.ts b/packages/junior/tests/unit/prompt.test.ts index a2d675bc4..83f895c92 100644 --- a/packages/junior/tests/unit/prompt.test.ts +++ b/packages/junior/tests/unit/prompt.test.ts @@ -10,7 +10,6 @@ describe("prompt builders", () => { const source = createSlackSource({ teamId: "T123", channelId: "C123", - channelType: "channel", }); const systemPrompt = buildSystemPrompt({ source }); @@ -27,7 +26,6 @@ describe("prompt builders", () => { source: createSlackSource({ teamId: "T123", channelId: "C123", - channelType: "channel", }), }), ); @@ -77,7 +75,6 @@ describe("prompt builders", () => { source: createSlackSource({ teamId: "T123", channelId: "C123", - channelType: "channel", }), destination: { platform: "slack", diff --git a/packages/junior/tests/unit/runtime/agent-dispatch-validation.test.ts b/packages/junior/tests/unit/runtime/agent-dispatch-validation.test.ts index 86a18f67e..10093ff06 100644 --- a/packages/junior/tests/unit/runtime/agent-dispatch-validation.test.ts +++ b/packages/junior/tests/unit/runtime/agent-dispatch-validation.test.ts @@ -21,7 +21,6 @@ const validOptions = { source: createSlackSource({ teamId: "T123", channelId: "C123", - channelType: "channel", }), }; diff --git a/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts b/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts index 3b9f4c8c1..402582bea 100644 --- a/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts +++ b/packages/junior/tests/unit/services/mcp-auth-orchestration.test.ts @@ -53,7 +53,6 @@ const slackSource = createSlackSource({ channelId: "C123", messageTs: "1700000000.source", threadTs: "1700000000.000000", - type: "pub", }); describe("createMcpAuthOrchestration", () => { diff --git a/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts b/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts index a5d121491..71355814f 100644 --- a/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts +++ b/packages/junior/tests/unit/services/plugin-auth-orchestration.test.ts @@ -61,7 +61,6 @@ const slackSource = createSlackSource({ channelId: "C123", messageTs: "1700000000.source", threadTs: "1700000000.000000", - type: "pub", }); describe("createPluginAuthOrchestration", () => { diff --git a/packages/junior/tests/unit/slack/slack-message-add-reaction-tool.test.ts b/packages/junior/tests/unit/slack/slack-message-add-reaction-tool.test.ts index 013dcedce..2df94efd1 100644 --- a/packages/junior/tests/unit/slack/slack-message-add-reaction-tool.test.ts +++ b/packages/junior/tests/unit/slack/slack-message-add-reaction-tool.test.ts @@ -18,7 +18,6 @@ const TEST_SLACK_CONTEXT: SlackToolContext = { source: createSlackSource({ teamId: "T123", channelId: "C123", - channelType: "channel", messageTs: "1700000000.100", }), destinationChannelId: "C123", diff --git a/packages/junior/tests/unit/slack/tool-registration.test.ts b/packages/junior/tests/unit/slack/tool-registration.test.ts index bd8873b32..5c6efd8fb 100644 --- a/packages/junior/tests/unit/slack/tool-registration.test.ts +++ b/packages/junior/tests/unit/slack/tool-registration.test.ts @@ -34,7 +34,6 @@ function ctx(channelId?: string): ToolRuntimeContext { source: createSlackSource({ teamId: "T123", channelId, - channelType: channelId.startsWith("C") ? "channel" : "im", }), sandbox: noopSandbox, }; From 3812b053666117ad425c38207a5101c92e4c19b3 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 10:02:10 -0700 Subject: [PATCH 12/29] docs(memory): Specify plugin session tasks Replace the completed-turn observation contract with typed plugin background tasks triggered by completed agent-run sessions. Memory passive learning now loads bounded session projections from durable runtime storage and treats extraction as a session compaction pass. Co-Authored-By: GPT-5 Codex --- specs/memory-plugin/extraction.md | 96 ++++++------ specs/memory-plugin/index.md | 30 ++-- specs/memory-plugin/policy.md | 2 +- specs/memory-plugin/security.md | 9 +- specs/memory-plugin/tools.md | 2 +- specs/memory-plugin/verification.md | 22 +-- specs/plugin-prompt-hooks.md | 219 ++++++++++++++++------------ specs/plugin-runtime.md | 10 +- 8 files changed, 219 insertions(+), 171 deletions(-) diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 06789c520..a36955b3e 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -7,8 +7,8 @@ ## Purpose -Define passive memory learning through completed-turn observation and the -memory-owned internal extraction agent. +Define passive memory learning through completed agent-run session processing +and the memory-owned internal extraction agent. ## What Belongs In Memory @@ -21,7 +21,8 @@ A candidate may be stored only when all of these are true: 2. It is a public/shareable concrete fact, preference, relationship, durable project fact, durable workflow preference, or explicit user request to remember something. -3. It is useful beyond the current turn or has an explicit expiration. +3. It is useful beyond the current request/session or has an explicit + expiration. 4. It is understandable without unresolved pronouns or hidden conversation context. 5. It has a runtime-derived source actor and source conversation. @@ -60,45 +61,56 @@ Examples that must not be stored: ## Passive Learning -The memory plugin observes completed turns through `observeTurn(ctx)`. - -The observation hook must: - -1. Run only after the user-visible turn is durably committed enough that - observation failure cannot fail delivery. -2. Invoke the memory-owned extraction agent with bounded user-authored turn - text. -3. Provide visible existing memories as dedupe context only, not as source - evidence for new memories. -4. Ignore assistant-authored claims as memory sources. -5. Skip passive extraction for unsupported sources. V1 supports local CLI - observations and `pub` sources with a stable source key. Non-local `priv` +The memory plugin processes completed agent-run sessions through a typed +`session.completed` plugin task. Conceptually this is a memory compaction pass: +the task loads a bounded completed-session projection and asks the memory-owned +extraction agent which durable public/shareable facts, if any, should survive +as long-term memory. + +The `processSession` task must: + +1. Run only after the user-visible agent run is delivered and the completed + session record is durably committed enough that task failure cannot fail + delivery. +2. Receive task params that contain stable references only, such as + `conversationId` and `sessionId`. Params must not duplicate raw messages, + source, destination, requester, tool payloads, or model output. +3. Load a bounded core-owned session projection from transcript/session storage. + The projection may include user-authored messages, assistant reply text, and + successful tool-call names, but not raw Pi internals, full transcript + history, private tool arguments/results, provider credentials, or unrelated + conversation context. +4. Skip passive extraction for unsupported sources. V1 supports local CLI + sessions and `pub` sources with a stable source key. Non-local `priv` sources and sources without stable identity are ignored before model extraction. -6. Skip passive extraction when the completed turn already called an explicit - memory mutation tool (`createMemory` or `removeMemory`). Recall tools - (`listMemories` and `searchMemories`) must not suppress passive extraction. -7. Extract candidate facts with a structured model output contract. -8. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or +5. Skip passive extraction when the completed session already called an + explicit memory mutation tool (`createMemory` or `removeMemory`). Recall + tools (`listMemories` and `searchMemories`) must not suppress passive + extraction. +6. Provide visible existing memories as dedupe context only, not as source + evidence for new memories. +7. Ignore assistant-authored claims as memory sources. +8. Extract candidate facts with a structured model output contract. +9. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or non-durable facts. -9. Assign requester or conversation target from memory-agent output, while - deriving all authority-bearing ids from runtime context. -10. Insert accepted memories idempotently with a stable key derived through the - runtime source helper, turn id, and extracted fact position. -11. Generate embeddings for accepted rows when the host embedder is configured. -12. Avoid storing raw extraction prompt, raw model output, or raw turn text +10. Assign requester or conversation target from memory-agent output, while + deriving all authority-bearing ids from runtime context. +11. Insert accepted memories idempotently with a stable key derived through the + runtime source helper, completed session reference, and extracted fact + position. +12. Generate embeddings for accepted rows when the host embedder is configured. +13. Avoid storing raw extraction prompt, raw model output, or raw session text beyond the accepted memory records. -Observation hooks are best effort. If extraction or storage fails, Junior logs -safe metadata and the completed user-visible turn remains successful. - -Queued extraction can be added later as a scaling option. If added, queue -payloads must contain stable references and safe metadata only; they must not -become the authority for private conversation text. +Plugin tasks are best effort and at least once. If extraction or storage fails, +Junior logs safe metadata, retries according to core task policy, and the +completed user-visible run remains successful. Duplicate task delivery must not +create duplicate memories. ## Extraction Rules -Extraction must follow these rules: +Passive session extraction must follow these rules: 1. Extract only from user-authored text. 2. Prefer explicit `createMemory` tool writes over inferred passive learning. @@ -143,25 +155,25 @@ belong to the memory agent rather than a caller-provided policy hook. The default V1 passive-extraction shape is: 1. The memory agent proposes structured candidate memories from the bounded - observation payload. + completed-session projection. 2. The memory agent accepts only candidates that satisfy public/shareable memory guidance. 3. Deterministic validation applies only hard structural rules, such as schema shape, runtime-owned authority, source visibility, lifecycle bounds, idempotency, and storage constraints before storage. -Memory agent review should receive only the candidate memory or completed -user-authored text, the minimum source context needed to judge it, and +Memory agent review should receive only the candidate memory or bounded +completed-session text, the minimum source context needed to judge it, and public/shareable memory guidance. It should not receive unrestricted transcript history, raw tool payloads, provider credentials, or unrelated conversation context unless those fields are part of the bounded extraction input. Prompt inputs should use the -same structured context-block style as Junior's turn context, with separate +same structured context-block style as Junior's run context, with separate `` and source blocks. Explicit `createMemory` review uses a singular `` block and the current user-authored message as bounded source -context. Passive extraction uses the completed turn's user-authored text plus -visible existing memories for dedupe. Existing memories must not be used as -source evidence for new facts. +context. Passive extraction uses the completed session's bounded user-authored +messages plus visible existing memories for dedupe. Existing memories must not +be used as source evidence for new facts. The memory agent model is host-owned but selected by the memory plugin. An explicit `createMemoryPlugin({ modelId })` option wins, then `AI_MEMORY_MODEL`, @@ -228,7 +240,7 @@ a model-visible rejection, not storage with a special classification. Duplicate prevention is required before insertion where the relevant signal is available: -- same source, turn id, and extracted fact index +- same source, completed session reference, and extracted fact index - high lexical or embedding similarity to an active memory in the same scope V1 storage enforces source/fact idempotency. Exact normalized-content equality diff --git a/specs/memory-plugin/index.md b/specs/memory-plugin/index.md index 915bd50d9..e08b63e5f 100644 --- a/specs/memory-plugin/index.md +++ b/specs/memory-plugin/index.md @@ -15,10 +15,9 @@ contracts. This spec describes the intended V1 memory plugin shape. Generic plugin prompt hooks and plugin prompt session state are available through -`../plugin-prompt-hooks.md`. Passive learning uses the implemented -`observeTurn` hook and the memory-owned internal extraction agent. Plugin -background task handlers remain a future scaling option, not the current V1 -contract. +`../plugin-prompt-hooks.md`. Passive learning uses a typed +`session.completed` plugin task that loads a bounded completed agent-run +session projection and invokes the memory-owned internal extraction agent. V1 stores only public/shareable memory content. Scope controls who can see a record; it is not a content sensitivity model. Private, sensitive, secret, or @@ -37,7 +36,7 @@ Explicit tools also support user-directed memory management. - Plugin-owned SQL storage, retrieval indexes, embeddings, and model-provider boundaries. - Automatic recall through `userPrompt` when the memory plugin is enabled. -- Passive learning through `observeTurn`. +- Passive learning through the memory plugin's `session.completed` task. - Explicit `createMemory`, `removeMemory`, `listMemories`, and `searchMemories` tools. - Scope, attribution, lifecycle, tool, model, public-content, and secret @@ -142,9 +141,11 @@ The V1 runtime plugin interface is: ```ts defineJuniorPlugin({ manifest, + tasks: { + processSession, + }, hooks: { userPrompt, - observeTurn, tools, }, }); @@ -152,9 +153,9 @@ defineJuniorPlugin({ The exact hook names are owned by their generic plugin specs. The memory plugin needs these broad V1 surfaces: automatic recall when the plugin is enabled, -completed-turn observation, model-visible memory tools, SQL access, and -host-owned model and embedding-provider access. A future admin CLI surface is -specified separately in [`./admin.md`](./admin.md). +completed-session background processing, model-visible memory tools, SQL +access, and host-owned model and embedding-provider access. A future admin CLI +surface is specified separately in [`./admin.md`](./admin.md). Installations that do not want memory should disable the memory plugin rather than split recall from the plugin. Future install-level memory policy may narrow @@ -176,7 +177,7 @@ The plugin owns: - a small memory store module around `ctx.db` - extraction and retrieval policy - memory policy guidance inside the memory agent -- passive extraction through `observeTurn` +- passive extraction through a typed `session.completed` plugin task - memory tool definitions - future memory admin command definitions @@ -222,13 +223,14 @@ V1 supports two visibility scopes: | Scope | Stored authority | Visible to | | -------------- | ------------------------------------------------ | -------------------------------------------- | | `personal` | current requester actor | same requester in compatible runtime context | -| `conversation` | current source/destination conversation identity | later turns in the same conversation | +| `conversation` | current source/destination conversation identity | later requests in the same conversation | Rules: 1. Scope is derived from runtime context. Model-visible tool arguments never provide requester ids, team ids, channel ids, thread ids, or conversation ids. -2. Personal memory is the default for first-person facts in interactive turns. +2. Personal memory is the default for first-person facts in interactive + requests. The current author/requester must be the subject of any personal-scoped identity, preference, or relationship fact. For example, `I am on the billing team` may become a personal memory for that requester, while `David @@ -315,7 +317,7 @@ be exported as part of Junior core. The V1 contract has these implementation dependencies: -1. Core plugin hook surfaces needed by this spec: `userPrompt`, `observeTurn`, +1. Core plugin surfaces needed by this spec: `userPrompt`, typed plugin tasks, `tools`, `ctx.db`, host model access, and host embedding provider access. 2. Memory plugin package with manifest, schema, migrations, store, and memory agent policy guidance. @@ -326,7 +328,7 @@ The V1 contract has these implementation dependencies: 4. Automatic recall from stored memories through `userPrompt`, using lexical ranking before embeddings are available. 5. Embedding provider integration and vector storage. -6. `observeTurn` passive extraction over completed turns. +6. `session.completed` passive extraction over completed agent-run sessions. 7. Deduplication, TTL archival, and conservative supersession. 8. Optional vector index tuning and hybrid ranking improvements. 9. Admin CLI inspection and repair commands after redaction and access diff --git a/specs/memory-plugin/policy.md b/specs/memory-plugin/policy.md index 72f8ae50e..206bc0126 100644 --- a/specs/memory-plugin/policy.md +++ b/specs/memory-plugin/policy.md @@ -202,7 +202,7 @@ For V1, passive extraction should store conversation-scoped operational knowledge by default. Passive personal memory from public conversations requires clear first-person source evidence from the user and must still be visible only to that requester. Explicit memory-management tool calls suppress passive -extraction for the same completed turn so the tool path owns its effect. +extraction for the same completed session so the tool path owns its effect. ## Automatic Injection Policy diff --git a/specs/memory-plugin/security.md b/specs/memory-plugin/security.md index 8dd43cdb1..2b3e0e441 100644 --- a/specs/memory-plugin/security.md +++ b/specs/memory-plugin/security.md @@ -22,8 +22,8 @@ model calls, embeddings, logging, and multi-user visibility. 6. Embeddings and lexical indexes are derived data and cannot grant visibility. 7. Provider credentials never enter plugin storage, prompt contributions, tool schemas, task payloads, logs, or model-visible content. -8. Observation hooks use bounded completed-turn text and do not store raw - transcript text. +8. Passive extraction tasks use bounded completed-session projections and do + not store raw transcript text. 9. Every write path uses the same policy, validation, and secret rejection layer. @@ -115,8 +115,9 @@ They must not contain: - memory content unless the task exists specifically to repair a memory id that can be reloaded from storage -Future observation-backed tasks should reload bounded observation payloads -through the core-provided observation helper. +Passive session-processing tasks should reload bounded completed-session +projections through the core-provided session helper rather than carrying raw +messages in task params or queue payloads. ## Logging And Reporting diff --git a/specs/memory-plugin/tools.md b/specs/memory-plugin/tools.md index ceab2d526..75b4b4b35 100644 --- a/specs/memory-plugin/tools.md +++ b/specs/memory-plugin/tools.md @@ -66,7 +66,7 @@ store-or-reject decision and canonical rewrite. The outer agent should not call `createMemory` for ordinary organic statements that merely reveal a durable preference or fact. Those are passive-learning -candidates handled by completed-turn observation, not explicit memory-tool +candidates handled by completed-session processing, not explicit memory-tool requests. The explicit tool path uses runtime context for source and idempotency. It must diff --git a/specs/memory-plugin/verification.md b/specs/memory-plugin/verification.md index 12af01fb8..74610beb5 100644 --- a/specs/memory-plugin/verification.md +++ b/specs/memory-plugin/verification.md @@ -25,10 +25,10 @@ requirements. 6. `userPrompt` retrieval failure: omit memory contribution, log safe metadata, and continue unless the failure indicates a broken required migration. 7. Prompt message validation failure: omit the prompt message. -8. `observeTurn` extraction failure: log safe metadata and do not fail the - completed turn. -9. Duplicate post-turn observation: source idempotency suppresses duplicate - stored memories. +8. `session.completed` extraction task failure: log safe metadata, retry under + core plugin-task policy, and do not fail the completed visible run. +9. Duplicate session task delivery: source/session idempotency suppresses + duplicate stored memories. 10. Secret detection match: reject the write with a model-visible tool input error for explicit tools or drop the passive fact with safe logging. 11. Visibility mismatch: fail closed and omit the memory. @@ -98,14 +98,15 @@ Use integration tests for: - embedding failures leave memories listable and lexically recallable - private conversation memory content is absent from logs, traces, and dashboard reporting payloads -- passive `observeTurn` extracts from organic completed turns without failing - delivery -- passive extraction skips turns where explicit `createMemory` was already - called +- passive `session.completed` processing extracts from organic completed + sessions without failing delivery +- passive extraction skips completed sessions where explicit `createMemory` was + already called - memory agent review rejects extracted candidates that violate workplace guidance - malformed or failed memory agent review fails closed for passive extraction -- duplicate observation of the same turn stores accepted memories once +- duplicate processing of the same completed session stores accepted memories + once When the future admin CLI is implemented, use integration tests for: @@ -139,7 +140,8 @@ Use evals for: - refusal to remember secrets - explicit create rejection for policy-disallowed workplace-sensitive facts - refusal or policy rejection for workplace-sensitive facts -- passive extraction quality for organic conversation +- passive extraction quality for organic conversation after queued plugin tasks + are drained - model use of current user corrections over stale memories ## Related Specs diff --git a/specs/plugin-prompt-hooks.md b/specs/plugin-prompt-hooks.md index 82bc79f05..8b7dabbce 100644 --- a/specs/plugin-prompt-hooks.md +++ b/specs/plugin-prompt-hooks.md @@ -1,4 +1,4 @@ -# Plugin Prompt Hooks Spec +# Plugin Prompt Hooks And Tasks Spec ## Metadata @@ -7,22 +7,24 @@ ## Purpose -Define the generic plugin hooks that let runtime hook plugins contribute prompt -text and observe completed turns without exposing raw Junior internals or -creating memory-specific plugin APIs. +Define the generic plugin hooks and background tasks that let runtime hook +plugins contribute prompt text and process completed agent-run sessions without +exposing raw Junior internals or creating memory-specific plugin APIs. ## Implementation Status Plugin prompt hooks are implemented in Junior core and -`@sentry/junior-plugin-api`. Turn observation hooks are implemented as -post-delivery best-effort hooks. Plugin background task handlers remain target -design for a later implementation slice. +`@sentry/junior-plugin-api`. The typed plugin task surface described here is +the target contract for background work. The previous post-run observation hook +shape is superseded by `session.completed` plugin tasks and should be removed +when the task runner lands. ## Scope - Plugin-provided system prompt and user prompt contributions. - Prompt hook context. -- Post-turn observation hook contract for passive extraction workflows. +- Typed plugin background task registration. +- Completed agent-run session task contract for passive extraction workflows. - Security and rendering boundaries for prompt contributions. - V1 memory plugin usage of these generic hooks. @@ -38,11 +40,17 @@ design for a later implementation slice. ## Contracts -### Hook Surface +### Registration Surface -Runtime hook plugins may provide prompt and observation hooks: +Runtime hook plugins may provide prompt hooks and typed background tasks: ```ts +interface PluginRegistrationInput { + manifest: PluginManifest; + hooks?: PluginHooks; + tasks?: PluginTasks; +} + interface PluginHooks { systemPrompt?( ctx: SystemPromptContext, @@ -51,14 +59,14 @@ interface PluginHooks { userPrompt?( ctx: UserPromptContext, ): PromptMessage[] | undefined | Promise; - - observeTurn?(ctx: TurnObservationContext): void | Promise; } + +type PluginTasks = Record>; ``` These hooks are app-code plugin hooks registered through -`defineJuniorPlugin({ manifest, hooks })`. Declarative `plugin.yaml` manifests -must not register prompt or observation hooks. +`defineJuniorPlugin({ manifest, hooks, tasks })`. Declarative `plugin.yaml` +manifests must not register prompt hooks or task handlers. ### Prompt Messages @@ -151,9 +159,9 @@ interface UserPromptContext { } ``` -`Source` is a runtime-normalized origin for the current turn. Slack sources use -the same address fields as Slack destinations plus source visibility and inbound -message metadata: +`Source` is a runtime-normalized origin for the current request or completed +agent-run session. Slack sources use the same address fields as Slack +destinations plus source visibility and inbound message metadata: ```ts type SourceType = "pub" | "priv"; @@ -189,107 +197,124 @@ The context must not expose: - cross-plugin state - model messages outside the safe hook-specific context -### Turn Observation Hook - -`observeTurn(ctx)` lets plugins inspect a completed turn and perform bounded -post-turn work such as passive memory extraction. - -Core invokes observation hooks only after final turn state is committed far -enough that the hook cannot affect whether the user-visible turn succeeds. - -Observation context should include: - -- requester, source, destination, and conversation id -- bounded user-visible turn text needed by the plugin: user text and assistant - text -- safe metadata about tool use -- plugin-scoped durable state and logger -- plugin-scoped model and embedding helpers - -The bounded observation payload is a runtime-owned projection, not a raw -transcript. Core may expose the same projection directly to `observeTurn(ctx)` -and later through `PluginTaskContext.observation.load()` for -observation-backed tasks. - -Observation hooks must not receive provider credentials, raw authorization URLs, -raw Slack clients, or unrestricted transcript history. For private -conversations, observation payloads must follow the same raw-payload restrictions -as runtime code: a plugin may receive private turn text only when it is an -explicitly enabled trusted host plugin whose contract requires that payload. - -Observation hooks must be best effort. A thrown observation error must be logged -with safe metadata and must not fail the already-completed user turn. - ### Plugin Background Tasks -Future observation hooks may enqueue plugin-owned background tasks through a -core-owned task capability: +Plugin tasks let plugins perform durable post-run work without blocking visible +reply delivery. Core owns when tasks are scheduled, how they are queued, how +they are retried, and how task params are persisted. ```ts -interface PluginTaskEnqueueOptions { - idempotencyKey: string; - name: string; - payload?: unknown; +interface PluginTaskDefinition { + trigger?: PluginTaskTrigger; + paramsSchema: TSchema; + run(ctx: PluginTaskContext>): Promise | void; } -interface PluginTaskEnqueueResult { +type PluginTaskTrigger = "session.completed"; + +interface PluginTaskContext extends PluginContext { id: string; - status: "created" | "already_exists"; + name: string; + params: TParams; + embedder: PluginEmbedder; + model: PluginModel; + state: PluginState; + session: PluginSessionReader; } -interface PluginTaskQueue { - enqueue(options: PluginTaskEnqueueOptions): Promise; +interface PluginSessionReader { + load(): Promise; } -interface PluginTaskContext extends PluginContext { - id: string; - name: string; - payload?: unknown; - observation?: { - load(): Promise; - }; +interface PluginSessionContext { + completedAtMs: number; + conversationId: string; + destination: Destination; + messages: PluginSessionMessage[]; + requester?: Requester; + sessionId: string; + source: Source; + successfulToolCalls: string[]; } -type PluginTaskHandler = (ctx: PluginTaskContext) => Promise | void; +interface PluginSessionMessage { + createdAtMs?: number; + role: "user" | "assistant"; + text: string; +} + +function definePluginTask( + task: PluginTaskDefinition, +): PluginTaskDefinition; ``` -This task surface is not implemented yet. The exact host implementation is not -part of the plugin API. Core may run -plugin tasks with the existing queue infrastructure, a signed internal callback, -a future dedicated task worker, or a local in-process test worker. Plugin code -must observe the same contract in all cases. +Task params are schema-validated before persistence and again before execution. +They must contain stable references such as `conversationId`, `sessionId`, or +run/session ids. They must not contain raw conversation text, raw assistant +text, raw tool payloads, credentials, authorization URLs, OAuth tokens, Slack +tokens, or provider credentials. + +The queue payload is a core-owned delivery envelope containing only a durable +task id. The durable task record carries plugin name, task name, parsed params, +status, attempt count, lease state, and timestamps. Plugins never receive raw +queue clients, queue topics, callback routes, message metadata, or delivery +acknowledgement controls. + +`session.load()` returns a bounded core-owned projection reconstructed from the +completed session record and transcript/session-log storage. It must not expose +raw Pi internals, full transcript history, private tool arguments/results, or +provider credentials. Core applies source privacy rules before returning raw +message text to a plugin task. Unknown or private source visibility fails +closed unless a future explicit privacy contract allows that task. Task rules: 1. Task names are resolved only inside the owning plugin. -2. Idempotency is scoped to plugin name and task name. -3. Task payloads must be bounded JSON-serializable data. -4. Task payloads should contain stable references and safe metadata, not raw - private prompt text, raw tool payloads, credentials, or tokens. -5. Task handlers run with plugin-scoped `ctx.db`, `ctx.state`, logger, and the - runtime-owned context needed by that task type. -6. Observation-backed tasks receive an `observation.load()` helper when core can - reconstruct a bounded observation payload from durable runtime state. -7. Task handlers must be idempotent because delivery is at least once. -8. Core owns queue acknowledgement, retry, redelivery, worker leases, callback +2. Task params are bounded JSON-serializable data parsed by the task's + `paramsSchema`. +3. Task handlers run with plugin-scoped `ctx.db`, `ctx.state`, logger, host + model access, host embedding access, and task-specific readers. +4. Task handlers must be idempotent because delivery is at least once. +5. Core owns queue acknowledgement, retry, redelivery, worker leases, callback signing, and provider-specific visibility timeouts. -9. Plugins must not depend on task execution happening in the same process or - same request as `observeTurn`. +6. Plugins must not depend on task execution happening in the same process or + same request that completed the agent run. + +### `session.completed` Tasks + +Core schedules `session.completed` tasks after a successful user-visible agent +run has been delivered and the completed session record has been durably +committed. The task params should be the minimum stable references needed to +reload the completed run/session, such as: + +```ts +const sessionCompletedParamsSchema = z + .object({ + conversationId: z.string().min(1), + sessionId: z.string().min(1), + }) + .strict(); +``` + +If the historical session id is not the stable run identity for a path, core may +include a separate run/session record id. The params should not duplicate +`source`, `destination`, `requester`, messages, or tool-call data when those can +be loaded from completed runtime storage. -For future queued memory extraction, the observation hook should enqueue a task with stable -conversation/session/message references. The task worker reloads the bounded -observation payload from durable runtime state before invoking the plugin task -handler. Queue payloads must not become the authority for private conversation -text. +The task idempotency key is derived from plugin name, task name, trigger name, +and the completed session reference. Duplicate queue delivery or duplicate +scheduling of the same completed session must run the plugin task at most once +successfully. ### Memory Plugin V1 Usage -The memory plugin should use the generic hooks as follows: +The memory plugin should use the generic hooks and task surface as follows: 1. `userPrompt(ctx)` retrieves memories visible to the current requester and source, then returns a concise memory block for the run's triggering prompt. -2. `observeTurn(ctx)` runs the memory-owned structured extraction agent over the - completed turn and writes accepted facts idempotently. +2. `tasks.processSession` handles the `session.completed` trigger, loads the + completed session projection, runs the memory-owned structured extraction + agent, and writes accepted facts idempotently. 3. `tools(ctx)` may expose explicit memory tools such as `createMemory`, `removeMemory`, `listMemories`, and `searchMemories`. @@ -318,7 +343,7 @@ V1 memory tools are context-bound: Core owns prompt rendering: 1. Core calls plugins in deterministic plugin-name order. -2. Core wraps user prompt contributions inside the existing turn-context/user +2. Core wraps user prompt contributions inside the existing run-context/user prompt structure owned by `buildTurnContextPrompt(...)`. 3. Core applies per-contribution and total prompt extension size limits. 4. Core omits empty contributions. @@ -333,8 +358,8 @@ Core owns prompt rendering: and continue unless startup validation can catch the problem earlier. 2. Oversized contribution: truncate only if the contribution contract supports deterministic truncation; otherwise omit and log safe metadata. -3. Observation hook failure: log safe metadata and do not change the completed - turn result. +3. Plugin task failure: log safe metadata, retry according to the core task + policy, and do not change the completed visible run result. ## Observability @@ -367,10 +392,16 @@ Use integration tests for: checkpoint - private conversation prompt contribution payloads are redacted from logs, traces, and dashboard APIs +- plugin task params are schema-validated before persistence and execution +- `session.completed` plugin tasks load bounded completed-session projections + without exposing raw private payloads +- duplicate scheduling or queue delivery does not run a completed plugin task + more than once successfully Use unit tests for: - hook return-shape validation +- task schema validation and plugin-local task name validation - deterministic plugin ordering - memory tool schema rejection of model-supplied actor or destination fields diff --git a/specs/plugin-runtime.md b/specs/plugin-runtime.md index b185e4323..2e0488446 100644 --- a/specs/plugin-runtime.md +++ b/specs/plugin-runtime.md @@ -83,8 +83,8 @@ Install-wide config defaults use `createApp({ configDefaults })` and must refere ## MCP Activation - MCP tools are not sandbox dependencies and are not registered globally at startup. -- At turn setup, the runtime restores providers from durable session-log - `mcp_provider_connected` events. Fresh turns discover providers through +- At agent-run setup, the runtime restores providers from durable session-log + `mcp_provider_connected` events. Fresh runs discover providers through `searchMcpTools` and connect lazily when the model first accesses one. - Runtime must infer restored plugin skill and MCP activation state from the session log, not side metadata. Successful `loadSkill` tool results identify @@ -97,13 +97,13 @@ Install-wide config defaults use `createApp({ configDefaults })` and must refere by `searchMcpTools({ provider })`, `callMcpTool`, resume restoration, or another explicit provider-access path. - Remote MCP catalogs are authoritative only after connection and `listTools`. -- Mid-turn MCP activation updates the host-managed MCP registry, but Junior does not mutate the Pi native tool list during the turn. +- Mid-run MCP activation updates the host-managed MCP registry, but Junior does not mutate the Pi native tool list during the run. - `searchMcpTools` and `callMcpTool` search and execute active-provider tools. Both lazily connect a provider when given one that is configured but not active. - `loadSkill` may return provider guidance, but full tool descriptors come from `searchMcpTools` after provider connection. - `searchMcpTools` returns focused descriptors including canonical `tool_name`, upstream `mcp_tool_name`, schemas, and annotations. - Resumed skills recover runtime handles from the session log. They must not re-embed skill bodies or provider summaries into the prompt when those facts are already visible in Pi history. -- MCP OAuth uses `/api/oauth/callback/mcp/` and resumes the paused turn after authorization. +- MCP OAuth uses `/api/oauth/callback/mcp/` and resumes the paused agent run after authorization. - Canonical MCP tool names remain `mcp____`. ## Plugin Skills @@ -181,7 +181,7 @@ Plugins may also provide `slackConversationLink` to replace the finalized Slack - Registry load order is deterministic. - Manifest validation fails before partial registration. - Plugin-backed skill loading rejects forged plugin metadata. -- No MCP connections are made at turn start unless restoring providers from session-log connection events. +- No MCP connections are made at agent-run start unless restoring providers from session-log connection events. - `searchMcpTools` and `callMcpTool` cannot reach tools from providers that are not configured or failed activation. ## Related Specs From 79cc38bc00574aa9ef95521bc9b5d1757b1740c0 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 13:25:33 -0700 Subject: [PATCH 13/29] feat(memory): Run extraction as plugin background task Add a durable plugin background task surface and move passive memory extraction onto a session.completed task. Core now stores task records, signs queue wakeups, wires the Vercel callback/Nitro route, and recovers pending or expired work from heartbeat. Keep plugin task params reference-only, expose a bounded completed-session projection, and run local tasks through the same durable runner after visible delivery. Also preserve root env model values when example app env placeholders are empty so local QA does not erase configured models. Co-Authored-By: GPT-5 Codex --- packages/junior-memory/src/agent.ts | 72 +++-- packages/junior-memory/src/plugin.ts | 12 +- .../src/{observe.ts => process-session.ts} | 45 +-- packages/junior-memory/src/tools.ts | 2 +- packages/junior-memory/tests/storage.test.ts | 262 ++++++++++++++---- packages/junior-plugin-api/src/context.ts | 1 + packages/junior-plugin-api/src/hooks.ts | 2 - packages/junior-plugin-api/src/index.ts | 3 +- packages/junior-plugin-api/src/observation.ts | 22 -- packages/junior-plugin-api/src/tasks.ts | 4 +- packages/junior/src/chat/local/runner.ts | 21 -- .../junior/src/chat/plugins/agent-hooks.ts | 89 ------ .../junior/src/chat/plugins/task-runner.ts | 3 + .../junior/src/chat/runtime/reply-executor.ts | 18 -- .../junior/src/chat/runtime/slack-resume.ts | 23 -- packages/junior/src/handlers/heartbeat.ts | 17 +- .../integration/local-agent-runner.test.ts | 64 +++++ .../tests/unit/handlers/oauth-resume.test.ts | 88 +----- .../tests/unit/plugins/agent-hooks.test.ts | 69 ----- scripts/lib/load-env-files.mjs | 3 + specs/index.md | 3 +- specs/memory-plugin/extraction.md | 3 +- specs/memory-plugin/index.md | 16 +- specs/memory-plugin/verification.md | 2 +- specs/plugin-prompt-hooks.md | 153 +--------- specs/plugin-tasks.md | 7 +- 26 files changed, 404 insertions(+), 600 deletions(-) rename packages/junior-memory/src/{observe.ts => process-session.ts} (56%) delete mode 100644 packages/junior-plugin-api/src/observation.ts diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 833aa4193..1d913d9e3 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -26,9 +26,8 @@ const createMemoryRequestSchema = z .optional(), }) .strict(); -const extractTurnRequestSchema = z +const extractSessionRequestSchema = z .object({ - assistantText: z.string(), existingMemories: z .array( z @@ -39,8 +38,17 @@ const extractTurnRequestSchema = z ) .max(10) .default([]), + messages: z + .array( + z + .object({ + role: z.enum(["user", "assistant"]), + text: z.string().min(1), + }) + .strict(), + ) + .min(1), runtimeContext: memoryRuntimeContextSchema, - userText: z.string().min(1), }) .strict(); @@ -108,7 +116,7 @@ const extractedMemorySchema = z expiresAtMs: expiresAtMsSchema, }) .strict(); -const extractTurnResponseSchema = z +const extractMemoriesResponseSchema = z .object({ memories: z .array(extractedMemorySchema) @@ -120,14 +128,16 @@ const extractTurnResponseSchema = z .strict(); type MemoryReviewResponse = z.output; -type ExtractTurnResponse = z.output; +type ExtractMemoriesResponse = z.output; export type MemoryTarget = z.output; export type MemoryReview = z.output; export type CreateMemoryRequest = z.output; -export type ExtractTurnRequest = z.output; +export type ExtractSessionRequest = z.output< + typeof extractSessionRequestSchema +>; export interface ExtractedMemory { content: string; expiresAtMs: number | null; @@ -135,8 +145,8 @@ export interface ExtractedMemory { } export interface MemoryAgent { - extractTurnMemories( - request: ExtractTurnRequest, + extractSessionMemories( + request: ExtractSessionRequest, ): Promise | ExtractedMemory[]; reviewCreateRequest( request: CreateMemoryRequest, @@ -218,7 +228,7 @@ function sourceContext(request: CreateMemoryRequest): string | undefined { ].join("\n"); } -function existingMemoriesContext(request: ExtractTurnRequest): string { +function existingMemoriesContext(request: ExtractSessionRequest): string { if (request.existingMemories.length === 0) { return "[]"; } @@ -282,10 +292,24 @@ function reviewPrompt(request: CreateMemoryRequest): string { return sections.join("\n"); } -function extractionPrompt(request: ExtractTurnRequest): string { +function sessionMessagesContext(request: ExtractSessionRequest): string { + return [ + "", + ...request.messages.map((message, index) => + [ + ``, + escapeXml(message.text), + "", + ].join("\n"), + ), + "", + ].join("\n"); +} + +function sessionExtractionPrompt(request: ExtractSessionRequest): string { return [ "", - "Extract durable memories from this completed user-authored turn using the runtime-owned context below.", + "Extract durable memories from this completed agent-run session using the runtime-owned context below.", "", runtimeDescription({ runtimeContext: request.runtimeContext, @@ -295,20 +319,14 @@ function extractionPrompt(request: ExtractTurnRequest): string { "", extractionExamples(), "", - "", - escapeXml(request.userText), - "", - "", - "", - escapeXml(request.assistantText), - "", + sessionMessagesContext(request), "", "", "- Return at most five memories.", - "- Use user-message as the only source of storable facts.", - "- Use assistant-response only to reject confirmations, follow-up questions, or memory-management turns.", + "- Use user role messages as the only source of storable facts.", + "- Use assistant role messages only to reject confirmations, follow-up questions, or memory-management turns.", "- Return one memory per distinct fact. Do not store the same fact under both requester and conversation targets.", - "- Ignore advice, how-to, search, recall, planning, list, inspect, and remove requests unless user-message also states a durable fact.", + "- Ignore advice, how-to, search, recall, planning, list, inspect, and remove requests unless user messages also state a durable fact.", "- Use target=requester for first-person facts about the current requester.", "- Use target=conversation only for shared operational/project knowledge.", ...CANONICAL_CONTENT_RULES, @@ -326,17 +344,17 @@ export function createMemoryAgent( options: MemoryAgentOptions = {}, ): MemoryAgent { return { - async extractTurnMemories(rawRequest) { - const request = extractTurnRequestSchema.parse(rawRequest); + async extractSessionMemories(rawRequest) { + const request = extractSessionRequestSchema.parse(rawRequest); const result = await model.completeObject({ ...(options.modelId ? { modelId: options.modelId } : {}), - schema: extractTurnResponseSchema, + schema: extractMemoriesResponseSchema, system: MEMORY_EXTRACTION_SYSTEM, - prompt: extractionPrompt(request), + prompt: sessionExtractionPrompt(request), maxTokens: 1_000, }); return extractedMemoriesFromResponse( - extractTurnResponseSchema.parse(result.object), + extractMemoriesResponseSchema.parse(result.object), ); }, async reviewCreateRequest(rawRequest) { @@ -374,7 +392,7 @@ function memoryReviewFromResponse( } function extractedMemoriesFromResponse( - response: ExtractTurnResponse, + response: ExtractMemoriesResponse, ): ExtractedMemory[] { return response.memories.map((memory) => ({ content: memory.canonicalFact, diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index adef8f3c3..4603b3505 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -9,7 +9,7 @@ import { type MemoryReviewer, type MemoryToolContext, } from "./tools"; -import { observeMemoryTurn } from "./observe"; +import { processMemorySession } from "./process-session"; import { createMemoryPromptMessages } from "./recall"; import type { MemoryDb } from "./store"; @@ -62,6 +62,13 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { cli: { commands: [createMemoryCliCommand()], }, + tasks: { + processSession: { + async run(ctx) { + await processMemorySession(ctx, agentOptions); + }, + }, + }, hooks: { tools(ctx) { const context = memoryToolContext({ @@ -87,9 +94,6 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { text: ctx.text, }); }, - async observeTurn(ctx) { - await observeMemoryTurn(ctx, agentOptions); - }, }, }); } diff --git a/packages/junior-memory/src/observe.ts b/packages/junior-memory/src/process-session.ts similarity index 56% rename from packages/junior-memory/src/observe.ts rename to packages/junior-memory/src/process-session.ts index 136d626c3..a269f4fc4 100644 --- a/packages/junior-memory/src/observe.ts +++ b/packages/junior-memory/src/process-session.ts @@ -1,7 +1,7 @@ import { getSourceKey, isPrivateSource, - type TurnObservationContext, + type PluginTaskContext, } from "@sentry/junior-plugin-api"; import { createMemoryStore, @@ -18,48 +18,56 @@ import { memoryRuntimeContextSchema } from "./types"; const MEMORY_MUTATION_TOOL_NAMES = new Set(["createMemory", "removeMemory"]); function passiveInput( - context: TurnObservationContext, + sessionId: string, memory: ExtractedMemory, index: number, sourceKey: string, ): CreateMemoryInput { return { content: memory.content, - idempotencyKey: `observe:${sourceKey}:${context.turnId}:${index}`, + idempotencyKey: `session:${sourceKey}:${sessionId}:${index}`, ...(memory.expiresAtMs !== null ? { expiresAtMs: memory.expiresAtMs } : {}), }; } -/** Extract and store memories from a delivered turn without using model-visible tools. */ -export async function observeMemoryTurn( - context: TurnObservationContext, +/** Extract and store memories from a completed session plugin task. */ +export async function processMemorySession( + context: PluginTaskContext, options: MemoryAgentOptions = {}, ): Promise { + const session = await context.session.load(); + // Explicit memory mutation tools already own the user's memory-management intent. if ( - context.toolCalls.some((toolName) => + session.toolCalls.some((toolName) => MEMORY_MUTATION_TOOL_NAMES.has(toolName), ) ) { return; } - if (context.source.platform !== "local" && isPrivateSource(context.source)) { + // V1 passive learning only stores public channel facts outside local QA. + if (session.source.platform !== "local" && isPrivateSource(session.source)) { return; } - const sourceKey = getSourceKey(context.source); + const sourceKey = getSourceKey(session.source); if (!sourceKey) { return; } - const userText = context.userText.trim(); + const messages = session.messages + .filter((message) => message.text.trim()) + .map((message) => ({ role: message.role, text: message.text.trim() })); + const userText = messages + .filter((message) => message.role === "user") + .map((message) => message.text) + .join("\n\n") + .trim(); if (!userText) { return; } const runtimeContext = memoryRuntimeContextSchema.parse({ - ...(context.conversationId - ? { conversationId: context.conversationId } - : {}), - ...(context.requester ? { requester: context.requester } : {}), - source: context.source, + conversationId: session.conversationId, + ...(session.requester ? { requester: session.requester } : {}), + source: session.source, }); const store = createMemoryStore(context.db as MemoryDb, runtimeContext, { embedder: context.embedder, @@ -69,20 +77,19 @@ export async function observeMemoryTurn( query: userText, }); const agent = createMemoryAgent(context.model, options); - const memories = await agent.extractTurnMemories({ - assistantText: context.assistantText, + const memories = await agent.extractSessionMemories({ existingMemories: existingMemories.map((memory) => ({ content: memory.content, })), + messages, runtimeContext, - userText, }); if (memories.length === 0) { return; } for (const [index, memory] of memories.entries()) { - const input = passiveInput(context, memory, index, sourceKey); + const input = passiveInput(session.sessionId, memory, index, sourceKey); if (memory.target === "conversation") { await store.createConversationMemory(input); continue; diff --git a/packages/junior-memory/src/tools.ts b/packages/junior-memory/src/tools.ts index 2015cb774..1a4fc083e 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior-memory/src/tools.ts @@ -329,7 +329,7 @@ function compactMemory(memory: MemoryRecord) { export function createMemoryCreateTool(context: MemoryToolContext) { return { description: - "Submit an explicit memory-management request. Call only when the requester directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact about themselves. Do not call for organic statements that merely reveal a durable preference or fact; passive memory observation handles those after the visible turn. Pass one self-contained memory candidate in natural language, preserving the user's explicit memory intent as directly as possible, such as 'I prefer terse updates' or 'I think rollback plans should mention data recovery'. Do not ask the requester to rephrase ordinary technical/workflow preferences, do not rewrite first-person claims into display-name or third-person phrasing, and do not pass vague references like 'remember this'. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives all actor ids, Slack ids, scope keys, source ids, and subject ids; the memory agent decides the canonical stored content, subject, and target.", + "Submit an explicit memory-management request. Call only when the requester directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact about themselves. Do not call for organic statements that merely reveal a durable preference or fact; passive memory learning handles those after the visible turn. Pass one self-contained memory candidate in natural language, preserving the user's explicit memory intent as directly as possible, such as 'I prefer terse updates' or 'I think rollback plans should mention data recovery'. Do not ask the requester to rephrase ordinary technical/workflow preferences, do not rewrite first-person claims into display-name or third-person phrasing, and do not pass vague references like 'remember this'. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives all actor ids, Slack ids, scope keys, source ids, and subject ids; the memory agent decides the canonical stored content, subject, and target.", executionMode: "sequential", inputSchema: createMemoryInputSchema, execute: async (input, options) => { diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 715242535..417d84ba8 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -10,10 +10,10 @@ import { createLocalSource, createSlackSource, PluginToolInputError, - type TurnObservationContext, type PluginLogger, type PluginModel, type PluginState, + type PluginTaskContext, } from "@sentry/junior-plugin-api"; import { Command, CommanderError } from "commander"; import { describe, expect, it } from "vitest"; @@ -25,6 +25,7 @@ import { } from "../src/agent"; import { createMemoryCliCommand } from "../src/cli"; import { createMemoryPlugin } from "../src/plugin"; +import { processMemorySession } from "../src/process-session"; import { createMemoryCreateTool, createMemoryListTool, @@ -32,7 +33,6 @@ import { createMemorySearchTool, type MemoryReviewer, } from "../src/tools"; -import { observeMemoryTurn } from "../src/observe"; import { createMemoryStore, type MemoryDb } from "../src/store"; const TEST_NOW_MS = Date.parse("2026-06-19T12:00:00.000Z"); @@ -257,19 +257,54 @@ function localContext( }; } -function observationContext( - overrides: Partial = {}, -): TurnObservationContext { +type MemoryTaskContext = PluginTaskContext; + +function completedSession( + overrides: Partial< + Awaited> + > = {}, +): NonNullable>> { const runtime = localContext(); return { - assistantText: "Got it.", + completedAtMs: TEST_NOW_MS, conversationId: runtime.conversationId, destination: { platform: "local", conversationId: runtime.conversationId, }, + messages: [ + { + role: "user", + text: "I prefer terse PR summaries.", + }, + { + role: "assistant", + text: "Got it.", + }, + ], + requester: runtime.requester, + sessionId: "local-turn-1", + source: runtime.source, + toolCalls: [], + ...overrides, + }; +} + +function processSessionContext( + overrides: Partial = {}, +): MemoryTaskContext { + const runtime = localContext(); + const session = + overrides.session ?? + ({ + async load() { + return completedSession(); + }, + } satisfies MemoryTaskContext["session"]); + return { db: overrides.db ?? {}, embedder: overrides.embedder ?? createTestEmbedder(), + id: "plugin-task-memory", log: noopLogger, model: overrides.model ?? @@ -279,13 +314,10 @@ function observationContext( content: "terse PR summaries", }, ]).model, + name: "processSession", plugin: { name: "memory" }, - requester: runtime.requester, - source: runtime.source, + session, state: memoryState, - toolCalls: [], - turnId: "local-turn-1", - userText: "I prefer terse PR summaries.", ...overrides, }; } @@ -383,10 +415,18 @@ describe("memory plugin storage", () => { modelId: "anthropic/claude-sonnet-4.6", }); - await agent.extractTurnMemories({ - assistantText: "Got it.", + await agent.extractSessionMemories({ + messages: [ + { + role: "user", + text: "I prefer terse PR summaries.", + }, + { + role: "assistant", + text: "Got it.", + }, + ], runtimeContext: localContext(), - userText: "I prefer terse PR summaries.", }); await agent.reviewCreateRequest({ content: "I prefer terse PR summaries.", @@ -419,10 +459,18 @@ describe("memory plugin storage", () => { const agent = createMemoryAgent(model); await expect( - agent.extractTurnMemories({ - assistantText: "Got it.", + agent.extractSessionMemories({ + messages: [ + { + role: "user", + text: "For incident writeups, causes go before mitigations.", + }, + { + role: "assistant", + text: "Got it.", + }, + ], runtimeContext: localContext(), - userText: "For incident writeups, causes go before mitigations.", }), ).resolves.toEqual([ { @@ -451,11 +499,10 @@ describe("memory plugin storage", () => { try { const plugin = createMemoryPlugin(); - await plugin.hooks?.observeTurn?.( - observationContext({ + await plugin.tasks?.processSession?.run( + processSessionContext({ db: memoryDb(fixture), model, - userText: "I prefer terse PR summaries.", }), ); @@ -499,7 +546,7 @@ describe("memory plugin storage", () => { }); }); - it("extracts and stores accepted memories from observed turns", async () => { + it("extracts and stores accepted memories from completed sessions", async () => { const fixture = await createMemoryFixture(); try { @@ -515,14 +562,27 @@ describe("memory plugin storage", () => { ]); const embedder = createTestEmbedder(); - await observeMemoryTurn( - observationContext({ - assistantText: "I will keep that in mind.", + await processMemorySession( + processSessionContext({ db: memoryDb(fixture), embedder, model, - userText: - "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", + session: { + async load() { + return completedSession({ + messages: [ + { + role: "user", + text: "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", + }, + { + role: "assistant", + text: "I will keep that in mind.", + }, + ], + }); + }, + }, }), ); @@ -558,6 +618,7 @@ describe("memory plugin storage", () => { }, 15_000); it("skips passive extraction for successful memory mutation tool turns", async () => { + const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ { target: "requester", @@ -565,15 +626,34 @@ describe("memory plugin storage", () => { }, ]); - await observeMemoryTurn( - observationContext({ - model, - toolCalls: ["createMemory"], - userText: "Remember that I prefer duplicate memory avoidance.", - }), - ); + try { + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + session: { + async load() { + return completedSession({ + messages: [ + { + role: "user", + text: "Remember that I prefer duplicate memory avoidance.", + }, + ], + toolCalls: ["createMemory"], + }); + }, + }, + }), + ); - expect(calls).toEqual([]); + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } }); it("does not skip passive extraction for memory recall tool turns", async () => { @@ -586,22 +666,43 @@ describe("memory plugin storage", () => { }, ]); - await observeMemoryTurn( - observationContext({ + await processMemorySession( + processSessionContext({ db: memoryDb(fixture), model, - toolCalls: ["listMemories", "searchMemories"], - userText: "I prefer recall turns to still learn durable facts.", + session: { + async load() { + return completedSession({ + messages: [ + { + role: "user", + text: "I prefer recall turns to still learn durable facts.", + }, + ], + toolCalls: ["listMemories", "searchMemories"], + }); + }, + }, }), ); expect(calls).toHaveLength(1); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([ + expect.objectContaining({ + content: "recall turns can still learn durable facts", + scope: "personal", + sourcePlatform: "local", + }), + ]); } finally { await fixture.close(); } }, 15_000); it("skips passive extraction in private Slack contexts", async () => { + const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ { target: "requester", @@ -613,18 +714,41 @@ describe("memory plugin storage", () => { sourceType: "priv", }); - await observeMemoryTurn( - observationContext({ - ...privateContext, - model, - userText: "I prefer private Slack context skips.", - }), - ); + try { + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + session: { + async load() { + return completedSession({ + conversationId: "slack:D123:1718800000.000000", + destination: slackDestination(privateContext), + messages: [ + { + role: "user", + text: "I prefer private Slack context skips.", + }, + ], + requester: privateContext.requester, + source: privateContext.source, + }); + }, + }, + }), + ); - expect(calls).toEqual([]); + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } }); - it("skips passive extraction for Slack observations without a message key", async () => { + it("skips passive extraction for Slack sessions without a message key", async () => { + const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ { target: "requester", @@ -633,20 +757,40 @@ describe("memory plugin storage", () => { ]); const runtime = slackContext(); - await observeMemoryTurn( - observationContext({ - conversationId: "slack:C123:missing-message-key", - model, - requester: runtime.requester, - source: createSlackSource({ - teamId: runtime.source.teamId, - channelId: runtime.source.channelId, + try { + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + session: { + async load() { + return completedSession({ + conversationId: "slack:C123:missing-message-key", + destination: slackDestination(runtime), + messages: [ + { + role: "user", + text: "I prefer Slack message key validation.", + }, + ], + requester: runtime.requester, + source: createSlackSource({ + teamId: runtime.source.teamId, + channelId: runtime.source.channelId, + }), + }); + }, + }, }), - userText: "I prefer Slack message key validation.", - }), - ); + ); - expect(calls).toEqual([]); + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } }); it("persists, recalls, and archives visible memories", async () => { diff --git a/packages/junior-plugin-api/src/context.ts b/packages/junior-plugin-api/src/context.ts index e78aa228d..dad31c49f 100644 --- a/packages/junior-plugin-api/src/context.ts +++ b/packages/junior-plugin-api/src/context.ts @@ -107,6 +107,7 @@ export function createSlackSource(input: { }; } +/** Classify Slack's documented C/D/G channel id prefixes into source visibility. */ function slackSourceType(channelId: string): SourceType { if (channelId.startsWith("C")) return "pub"; if (channelId.startsWith("D") || channelId.startsWith("G")) return "priv"; diff --git a/packages/junior-plugin-api/src/hooks.ts b/packages/junior-plugin-api/src/hooks.ts index 85e3440e9..ba8c8d60b 100644 --- a/packages/junior-plugin-api/src/hooks.ts +++ b/packages/junior-plugin-api/src/hooks.ts @@ -30,7 +30,6 @@ import type { SystemPromptContext, UserPromptContext, } from "./prompt"; -import type { TurnObservationContext } from "./observation"; export interface PluginHooks { systemPrompt?( @@ -39,7 +38,6 @@ export interface PluginHooks { userPrompt?( ctx: UserPromptContext, ): Promise | PromptMessage[] | undefined; - observeTurn?(ctx: TurnObservationContext): Promise | void; beforeToolExecute?(ctx: BeforeToolExecuteHookContext): Promise | void; grantForEgress?( ctx: EgressHookContext, diff --git a/packages/junior-plugin-api/src/index.ts b/packages/junior-plugin-api/src/index.ts index 645c9eb04..b6f571901 100644 --- a/packages/junior-plugin-api/src/index.ts +++ b/packages/junior-plugin-api/src/index.ts @@ -8,7 +8,7 @@ export { type UserPromptContext, } from "./prompt"; export * from "./dispatch"; -export * from "./observation"; +export * from "./tasks"; export * from "./tools"; export * from "./operations"; export * from "./credentials"; @@ -16,4 +16,3 @@ export * from "./hooks"; export * from "./cli"; export * from "./manifest"; export * from "./registration"; -export * from "./tasks"; diff --git a/packages/junior-plugin-api/src/observation.ts b/packages/junior-plugin-api/src/observation.ts deleted file mode 100644 index f06d3bc21..000000000 --- a/packages/junior-plugin-api/src/observation.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { - InvocationContext, - PluginContext, - PluginEmbedder, - PluginModel, -} from "./context"; -import type { PluginState } from "./state"; - -/** Delivered turn text and runtime context available to post-turn plugin hooks. */ -export type TurnObservationContext = Pick< - PluginContext, - "db" | "log" | "plugin" -> & - InvocationContext & { - assistantText: string; - embedder: PluginEmbedder; - model: PluginModel; - state: PluginState; - toolCalls: string[]; - turnId: string; - userText: string; - }; diff --git a/packages/junior-plugin-api/src/tasks.ts b/packages/junior-plugin-api/src/tasks.ts index a9054e9d6..131fbefe5 100644 --- a/packages/junior-plugin-api/src/tasks.ts +++ b/packages/junior-plugin-api/src/tasks.ts @@ -5,7 +5,7 @@ * scheduling, queue delivery, retries, and the bounded session projection. */ import { z } from "zod"; -import type { PluginContext } from "./context"; +import type { PluginContext, PluginEmbedder, PluginModel } from "./context"; import { destinationSchema, requesterSchema, sourceSchema } from "./schemas"; import type { PluginState } from "./state"; @@ -37,7 +37,9 @@ export type PluginSessionContext = z.output; /** Runtime context passed to a plugin-owned background task. */ export interface PluginTaskContext extends PluginContext { + embedder: PluginEmbedder; id: string; + model: PluginModel; name: string; session: { load(): Promise; diff --git a/packages/junior/src/chat/local/runner.ts b/packages/junior/src/chat/local/runner.ts index 56df00f9f..94a7a0069 100644 --- a/packages/junior/src/chat/local/runner.ts +++ b/packages/junior/src/chat/local/runner.ts @@ -16,7 +16,6 @@ import { type LocalDestination, } from "@sentry/junior-plugin-api"; import { logException } from "@/chat/logging"; -import { observePluginTurn } from "@/chat/plugins/agent-hooks"; import { processPluginTask, scheduleSessionCompletedPluginTasks, @@ -24,7 +23,6 @@ import { import type { ToolExecutionReport } from "@/chat/tools/agent-tools"; import { THREAD_STATE_TTL_MS } from "chat"; import { - getSuccessfulToolCalls, stripRuntimeTurnContext, trimTrailingAssistantMessages, } from "@/chat/respond-helpers"; @@ -378,25 +376,6 @@ export async function runLocalAgentTurn( "Local plugin session.completed task failed after reply delivery", ); } - await observePluginTurn({ - assistantText: reply.text, - toolCalls: reply.piMessages - ? getSuccessfulToolCalls(reply.piMessages) - : reply.diagnostics.toolCalls, - turnId, - context: { - conversationId: input.conversationId, - destination, - requester: { - fullName: "Local CLI", - platform: "local", - userId: "local-cli", - userName: "local", - }, - source: destination, - userText: text, - }, - }); } return { diff --git a/packages/junior/src/chat/plugins/agent-hooks.ts b/packages/junior/src/chat/plugins/agent-hooks.ts index 92e370e0c..e5dae4e4b 100644 --- a/packages/junior/src/chat/plugins/agent-hooks.ts +++ b/packages/junior/src/chat/plugins/agent-hooks.ts @@ -12,7 +12,6 @@ import type { PluginRegistration, SlackToolRegistrationHookContext, ToolRegistrationHookContext, - TurnObservationContext, UserPromptContext, } from "@sentry/junior-plugin-api"; import { getDb } from "@/chat/db"; @@ -145,55 +144,6 @@ function invocationPluginContext( }; } -function observationPluginContext( - plugin: PluginRegistration, - context: Pick< - ToolRuntimeContext, - "conversationId" | "destination" | "requester" | "source" | "userText" - > & { assistantText: string; toolCalls: string[]; turnId: string }, -): TurnObservationContext { - const base = basePluginContext(plugin); - const common = { - ...base, - assistantText: context.assistantText, - embedder: createPluginEmbedder(plugin.manifest.name), - model: createPluginModel(plugin.manifest.name), - state: createPluginState(plugin.manifest.name), - toolCalls: [...context.toolCalls], - turnId: context.turnId, - userText: context.userText ?? "", - ...(context.conversationId - ? { conversationId: context.conversationId } - : {}), - }; - if (context.source.platform === "slack") { - if (context.destination.platform !== "slack") { - throw new TypeError( - "Slack plugin observation context requires Slack destination", - ); - } - return { - ...common, - destination: context.destination, - source: context.source, - requester: - context.requester?.platform === "slack" ? context.requester : undefined, - }; - } - if (context.destination.platform !== "local") { - throw new TypeError( - "Local plugin observation context requires local destination", - ); - } - return { - ...common, - destination: context.destination, - source: context.source, - requester: - context.requester?.platform === "local" ? context.requester : undefined, - }; -} - function safeErrorMessage(error: unknown): string { return error instanceof Error ? error.message : String(error); } @@ -505,45 +455,6 @@ export function getPluginTools( return tools; } -/** Let plugins inspect a successfully delivered turn without affecting delivery. */ -export async function observePluginTurn(args: { - assistantText: string; - toolCalls: string[]; - turnId: string; - context: Pick< - ToolRuntimeContext, - "conversationId" | "destination" | "requester" | "source" | "userText" - >; -}): Promise { - for (const plugin of getPlugins()) { - const pluginName = plugin.manifest.name; - const hook = plugin.hooks?.observeTurn; - if (!hook) { - continue; - } - try { - await hook( - observationPluginContext(plugin, { - ...args.context, - assistantText: args.assistantText, - toolCalls: args.toolCalls, - turnId: args.turnId, - }), - ); - } catch (error) { - logWarn( - "plugin_turn_observation_hook_failed", - {}, - { - "app.plugin.name": pluginName, - "exception.message": safeErrorMessage(error), - }, - "Plugin turn observation hook failed", - ); - } - } -} - /** Normalize route methods so JS plugins cannot register invalid verbs. */ function routeMethods( route: PluginRoute, diff --git a/packages/junior/src/chat/plugins/task-runner.ts b/packages/junior/src/chat/plugins/task-runner.ts index cc2062e2e..9367196e4 100644 --- a/packages/junior/src/chat/plugins/task-runner.ts +++ b/packages/junior/src/chat/plugins/task-runner.ts @@ -15,6 +15,7 @@ import type { import { pluginSessionContextSchema } from "@sentry/junior-plugin-api"; import { getDb } from "@/chat/db"; import { createPluginLogger } from "@/chat/plugins/logging"; +import { createPluginEmbedder, createPluginModel } from "@/chat/plugins/model"; import { createPluginState } from "@/chat/plugins/state"; import { createRequesterFromStoredSlackRequester } from "@/chat/requester"; import type { PiMessage } from "@/chat/pi/messages"; @@ -173,8 +174,10 @@ function taskPluginContext( const sessionParams = pluginTaskParamsSchema.parse(message.params); return { db: getDb(), + embedder: createPluginEmbedder(pluginName), id: pluginTaskId(message), log: createPluginLogger(pluginName), + model: createPluginModel(pluginName), name: message.name, plugin: { name: pluginName }, session: { diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 4193c7868..273c61408 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -9,7 +9,6 @@ import type { Message, SentMessage, Thread } from "chat"; import type { SlackAdapter } from "@chat-adapter/slack"; import { createSlackSource, type Destination } from "@sentry/junior-plugin-api"; -import { observePluginTurn } from "@/chat/plugins/agent-hooks"; import { botConfig } from "@/chat/config"; import { getSlackMessageTs } from "@/chat/slack/message"; import { @@ -118,7 +117,6 @@ import { } from "@/chat/state/conversation-details"; import { loadProjection } from "@/chat/state/session-log"; import { - getSuccessfulToolCalls, stripRuntimeTurnContext, trimTrailingAssistantMessages, } from "@/chat/respond-helpers"; @@ -1085,22 +1083,6 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { ); } await options.onTurnCompleted?.(); - if (reply.diagnostics.outcome === "success") { - await observePluginTurn({ - assistantText: reply.text, - toolCalls: reply.piMessages - ? getSuccessfulToolCalls(reply.piMessages) - : reply.diagnostics.toolCalls, - turnId, - context: { - ...(conversationId ? { conversationId } : {}), - destination, - requester: requesterIdentity, - source, - userText: effectiveUserText, - }, - }); - } if (reply.diagnostics.outcome === "success" && conversationId) { try { await deps.services.scheduleSessionCompletedPluginTasks({ diff --git a/packages/junior/src/chat/runtime/slack-resume.ts b/packages/junior/src/chat/runtime/slack-resume.ts index 96be10ee9..e5e62ff30 100644 --- a/packages/junior/src/chat/runtime/slack-resume.ts +++ b/packages/junior/src/chat/runtime/slack-resume.ts @@ -6,7 +6,6 @@ import { type AssistantReplyRequestContext, } from "@/chat/respond"; import type { Source } from "@sentry/junior-plugin-api"; -import { observePluginTurn } from "@/chat/plugins/agent-hooks"; import { scheduleSessionCompletedPluginTasks } from "@/chat/plugins/task-runner"; import { buildTurnFailureResponse, @@ -21,7 +20,6 @@ import { finalizeFailedTurnReply, requireTurnFailureEventId, } from "@/chat/services/turn-failure-response"; -import { getSuccessfulToolCalls } from "@/chat/respond-helpers"; import { persistThreadStateById } from "@/chat/runtime/thread-state"; import { createSlackWebApiAssistantStatusSession, @@ -407,27 +405,6 @@ export async function resumeSlackTurn( ); } } - if ( - reply.diagnostics.outcome === "success" && - replyContext.destination.platform === "slack" - ) { - await observePluginTurn({ - assistantText: reply.text, - toolCalls: reply.piMessages - ? getSuccessfulToolCalls(reply.piMessages) - : reply.diagnostics.toolCalls, - turnId: replyContext.correlation?.turnId ?? lockKey, - context: { - conversationId: replyContext.correlation?.conversationId ?? lockKey, - destination: replyContext.destination, - ...(replyContext.requester - ? { requester: replyContext.requester } - : {}), - source: replyContext.source, - userText: runArgs.messageText, - }, - }); - } } catch (error) { await status.stop(); diff --git a/packages/junior/src/handlers/heartbeat.ts b/packages/junior/src/handlers/heartbeat.ts index 84850a015..f586c029d 100644 --- a/packages/junior/src/handlers/heartbeat.ts +++ b/packages/junior/src/handlers/heartbeat.ts @@ -1,11 +1,14 @@ import { timingSafeEqual } from "node:crypto"; import { runHeartbeat } from "@/chat/agent-dispatch/heartbeat"; +import { recoverPluginTasks } from "@/chat/plugins/task-runner"; +import type { PluginTaskQueue } from "@/chat/plugins/task-queue"; import type { ConversationWorkQueue } from "@/chat/task-execution/queue"; import { logException } from "@/chat/logging"; import type { WaitUntilFn } from "@/handlers/types"; export interface HeartbeatHandlerOptions { conversationWorkQueue?: ConversationWorkQueue; + pluginTaskQueue?: PluginTaskQueue; } function getHeartbeatSecret(): string | undefined { @@ -42,10 +45,16 @@ export async function GET( const nowMs = Date.now(); waitUntil(() => - runHeartbeat({ - conversationWorkQueue: options.conversationWorkQueue, - nowMs, - }).catch((error) => { + Promise.all([ + runHeartbeat({ + conversationWorkQueue: options.conversationWorkQueue, + nowMs, + }), + recoverPluginTasks({ + nowMs, + ...(options.pluginTaskQueue ? { queue: options.pluginTaskQueue } : {}), + }), + ]).catch((error) => { logException( error, "heartbeat_failed", diff --git a/packages/junior/tests/integration/local-agent-runner.test.ts b/packages/junior/tests/integration/local-agent-runner.test.ts index 40259061e..a56bfc7f0 100644 --- a/packages/junior/tests/integration/local-agent-runner.test.ts +++ b/packages/junior/tests/integration/local-agent-runner.test.ts @@ -25,6 +25,7 @@ import { import { commitMessages, loadProjection } from "@/chat/state/session-log"; import { coerceThreadConversationState } from "@/chat/state/conversation"; import { coerceThreadArtifactsState } from "@/chat/state/artifacts"; +import { setPlugins } from "@/chat/plugins/agent-hooks"; function successReply( text: string, @@ -498,6 +499,69 @@ describe("local agent runner", () => { expect(contexts[0]?.piMessages).toEqual([generatedMessages[0]]); }); + it("keeps the delivered local reply successful when a background task fails", async () => { + const conversationId = normalizeLocalConversationId({ + alias: "background-task-failure", + cwd: "/tmp/local-agent-runner-background-task-failure", + }); + expect(conversationId).toBeDefined(); + + const generatedMessages = [ + { + role: "user", + content: [{ type: "text", text: "hello" }], + }, + { + role: "assistant", + content: [{ type: "text", text: "visible reply" }], + }, + ] as PiMessage[]; + const delivered: LocalAgentReply[] = []; + setPlugins([ + defineJuniorPlugin({ + manifest: { + name: "local-task-failure", + displayName: "Local Task Failure", + description: "Local task failure fixture", + }, + tasks: { + processSession: { + run() { + throw new Error("background task failed"); + }, + }, + }, + }), + ]); + + try { + await expect( + runLocalAgentTurn( + { + conversationId: conversationId!, + message: "hello", + }, + { + deliverReply: async (reply) => { + delivered.push(reply); + }, + generateAssistantReply: async () => + successReply("visible reply", { + piMessages: generatedMessages, + }), + }, + ), + ).resolves.toEqual({ + conversationId, + outcome: "success", + }); + } finally { + setPlugins([]); + } + + expect(delivered).toEqual([{ text: "visible reply" }]); + }); + it("uses conversation Pi history when the session projection is stale", async () => { const conversationId = normalizeLocalConversationId({ alias: "pi-history-stale-projection", diff --git a/packages/junior/tests/unit/handlers/oauth-resume.test.ts b/packages/junior/tests/unit/handlers/oauth-resume.test.ts index 717fa6477..6bd7fc5c3 100644 --- a/packages/junior/tests/unit/handlers/oauth-resume.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-resume.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { createSlackSource, defineJuniorPlugin } from "@sentry/junior-plugin-api"; +import { createSlackSource } from "@sentry/junior-plugin-api"; import { RetryableTurnError } from "@/chat/runtime/turn"; import { disconnectStateAdapter, getStateAdapter } from "@/chat/state/adapter"; import { setPlugins } from "@/chat/plugins/agent-hooks"; @@ -283,92 +283,6 @@ describe("resumeAuthorizedRequest", () => { }); }); - it("observes successful resumed turns after persistence", async () => { - const observed: unknown[] = []; - const onSuccess = vi.fn(async () => undefined); - const previous = setPlugins([ - defineJuniorPlugin({ - manifest: { - name: "resume-observer", - displayName: "Resume Observer", - description: "Resume observer", - }, - hooks: { - observeTurn(ctx) { - observed.push({ - assistantText: ctx.assistantText, - conversationId: ctx.conversationId, - destination: ctx.destination, - requester: ctx.requester, - source: ctx.source, - toolCalls: ctx.toolCalls, - turnId: ctx.turnId, - userText: ctx.userText, - }); - }, - }, - }), - ]); - - try { - await resumeSlackTurn({ - messageText: "remember that launch notes live in Notion", - channelId: "C-test", - threadTs: "1700000000.0005", - replyContext: { - correlation: { - conversationId: "slack:C-test:1700000000.0005", - turnId: "turn-resume-1", - }, - credentialContext: { - actor: { type: "user", userId: "U-test" }, - }, - destination: TEST_SLACK_DESTINATION, - source: testSlackSource("1700000000.0005"), - requester: { - platform: "slack", - teamId: "T-test", - userId: "U-test", - }, - source: testSlackSource("1700000000.0005"), - }, - generateReply: async () => ({ - text: "Final resumed answer", - diagnostics: { - assistantMessageCount: 1, - modelId: "fake-agent-model", - outcome: "success", - toolCalls: [], - toolErrorCount: 0, - toolResultCount: 0, - usedPrimaryText: true, - }, - }), - onSuccess, - }); - - expect(onSuccess).toHaveBeenCalledTimes(1); - expect(observed).toEqual([ - { - assistantText: "Final resumed answer", - conversationId: "slack:C-test:1700000000.0005", - destination: TEST_SLACK_DESTINATION, - requester: { - platform: "slack", - teamId: "T-test", - userId: "U-test", - }, - source: testSlackSource("1700000000.0005"), - toolCalls: [], - turnId: "turn-resume-1", - userText: "remember that launch notes live in Notion", - }, - ]); - } finally { - setPlugins(previous); - } - }); - it("releases the thread lock before scheduling another timeout slice", async () => { const onTimeoutPause = vi.fn(async () => { const stateAdapter = getStateAdapter(); diff --git a/packages/junior/tests/unit/plugins/agent-hooks.test.ts b/packages/junior/tests/unit/plugins/agent-hooks.test.ts index eacf77be0..b259d487e 100644 --- a/packages/junior/tests/unit/plugins/agent-hooks.test.ts +++ b/packages/junior/tests/unit/plugins/agent-hooks.test.ts @@ -14,7 +14,6 @@ import { getPluginRoutes, getPluginSlackConversationLink, getPluginTools, - observePluginTurn, setPlugins, } from "@/chat/plugins/agent-hooks"; import { createTools } from "@/chat/tools"; @@ -362,74 +361,6 @@ describe("agent plugin hooks", () => { } }); - it("observes delivered turns with scoped plugin context", async () => { - const observed: unknown[] = []; - const previous = setPlugins([ - defineJuniorPlugin({ - manifest: { - name: "agent-demo", - displayName: "Agent Demo", - description: "Agent demo", - }, - hooks: { - observeTurn(ctx) { - observed.push({ - assistantText: ctx.assistantText, - conversationId: ctx.conversationId, - destination: ctx.destination, - hasEmbedder: typeof ctx.embedder.embedTexts === "function", - hasModel: typeof ctx.model.completeObject === "function", - requester: ctx.requester, - source: ctx.source, - toolCalls: ctx.toolCalls, - turnId: ctx.turnId, - userText: ctx.userText, - }); - }, - }, - }), - ]); - try { - await observePluginTurn({ - assistantText: "Stored.", - toolCalls: ["createMemory"], - turnId: "turn-1", - context: { - conversationId: "conversation-1", - destination: SLACK_DESTINATION, - requester: TEST_REQUESTER, - source: { - ...SLACK_DESTINATION, - messageTs: "1718800000.000000", - threadTs: "1718800000.000000", - }, - userText: "remember this", - }, - }); - - expect(observed).toEqual([ - { - assistantText: "Stored.", - conversationId: "conversation-1", - destination: SLACK_DESTINATION, - hasEmbedder: true, - hasModel: true, - requester: TEST_REQUESTER, - source: { - ...SLACK_DESTINATION, - messageTs: "1718800000.000000", - threadTs: "1718800000.000000", - }, - toolCalls: ["createMemory"], - turnId: "turn-1", - userText: "remember this", - }, - ]); - } finally { - setPlugins(previous); - } - }); - it("collects turn-scoped tools from configured plugins", () => { const previous = setPlugins([ defineJuniorPlugin({ diff --git a/scripts/lib/load-env-files.mjs b/scripts/lib/load-env-files.mjs index 63f52d567..0f3ee1582 100644 --- a/scripts/lib/load-env-files.mjs +++ b/scripts/lib/load-env-files.mjs @@ -46,6 +46,9 @@ export function loadEnvFiles(roots, options = {}) { if (protectedKeys.has(name) && !loadedKeys.has(name)) { continue; } + if (value === "" && env[name]?.trim()) { + continue; + } env[name] = value; loadedKeys.add(name); } diff --git a/specs/index.md b/specs/index.md index baf2efb74..cec077e72 100644 --- a/specs/index.md +++ b/specs/index.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-03-03 -- Last Edited: 2026-06-13 +- Last Edited: 2026-06-24 ## Purpose @@ -83,6 +83,7 @@ For chat/agent/Slack execution and response behavior: - `specs/conversation-storage.md` owns SQL-backed queryable conversation record, transcript-storage exclusions, and Vercel-safe migration/backfill behavior. - `specs/plugin-tasks.md` owns plugin-owned durable background task registration, queue dispatch, and completed-session projections. - `specs/plugin-database.md` owns plugin packaged SQL migration discovery/application and the `ctx.db` hook surface. +- `specs/plugin-tasks.md` owns trusted plugin background task registration, durable task records, queue envelopes, leases, retries, and completed-session projections. - `specs/plugin-cli.md` owns future plugin-contributed host CLI command discovery, dispatch, admin context, and redaction contracts. - `specs/memory-plugin/index.md` owns the long-term memory plugin's storage, recall, passive learning, tools, visibility, and lifecycle contracts. - `specs/local-agent.md` owns local CLI/local adapter user flows, identity, state, delivery, and verification contracts. diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index a36955b3e..494b9628b 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-22 +- Last Edited: 2026-06-24 ## Purpose @@ -263,4 +263,5 @@ guess. - `./storage.md` - `./security.md` - `../plugin-prompt-hooks.md` +- `../plugin-tasks.md` - `../data-redaction-policy.md` diff --git a/specs/memory-plugin/index.md b/specs/memory-plugin/index.md index e08b63e5f..6dcae21dd 100644 --- a/specs/memory-plugin/index.md +++ b/specs/memory-plugin/index.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-22 +- Last Edited: 2026-06-24 ## Purpose @@ -15,9 +15,10 @@ contracts. This spec describes the intended V1 memory plugin shape. Generic plugin prompt hooks and plugin prompt session state are available through -`../plugin-prompt-hooks.md`. Passive learning uses a typed -`session.completed` plugin task that loads a bounded completed agent-run -session projection and invokes the memory-owned internal extraction agent. +`../plugin-prompt-hooks.md`. Passive learning uses the typed task contract in +`../plugin-tasks.md`: a `session.completed` task loads a bounded completed +agent-run session projection and invokes the memory-owned internal extraction +agent. V1 stores only public/shareable memory content. Scope controls who can see a record; it is not a content sensitivity model. Private, sensitive, secret, or @@ -70,7 +71,7 @@ Read these files as one canonical spec: model/tool boundaries, task payload safety, and redaction rules. - [retrieval.md](./retrieval.md): automatic recall, tool-mediated recall, hybrid ranking, automatic injection mechanics, and performance strategy. -- [extraction.md](./extraction.md): passive observation, extraction, +- [extraction.md](./extraction.md): passive session processing, extraction, storable-fact policy, semantic duplicate detection, and supersession. - [tools.md](./tools.md): model-visible memory management and recall tools. - [admin.md](./admin.md): future operator/admin CLI command shape for memory @@ -127,7 +128,7 @@ External storage and retrieval assumptions are based on primary documentation: ## Plugin Shape The V1 memory implementation is a trusted host plugin registered through -`defineJuniorPlugin({ manifest, hooks })`. +`defineJuniorPlugin({ manifest, hooks, tasks })`. The plugin uses the package name and plugin name `memory`. Plugin database tables use the prefix: @@ -317,7 +318,7 @@ be exported as part of Junior core. The V1 contract has these implementation dependencies: -1. Core plugin surfaces needed by this spec: `userPrompt`, typed plugin tasks, +1. Core plugin surfaces needed by this spec: `userPrompt`, `session.completed`, `tools`, `ctx.db`, host model access, and host embedding provider access. 2. Memory plugin package with manifest, schema, migrations, store, and memory agent policy guidance. @@ -340,6 +341,7 @@ The V1 contract has these implementation dependencies: - `../plugin.md` - `../plugin-runtime.md` - `../plugin-prompt-hooks.md` +- `../plugin-tasks.md` - `../plugin-database.md` - `../plugin-cli.md` - `./policy.md` diff --git a/specs/memory-plugin/verification.md b/specs/memory-plugin/verification.md index 74610beb5..d320ea817 100644 --- a/specs/memory-plugin/verification.md +++ b/specs/memory-plugin/verification.md @@ -3,7 +3,7 @@ ## Metadata - Created: 2026-06-13 -- Last Edited: 2026-06-22 +- Last Edited: 2026-06-24 ## Purpose diff --git a/specs/plugin-prompt-hooks.md b/specs/plugin-prompt-hooks.md index 8b7dabbce..b0baecb9c 100644 --- a/specs/plugin-prompt-hooks.md +++ b/specs/plugin-prompt-hooks.md @@ -1,30 +1,26 @@ -# Plugin Prompt Hooks And Tasks Spec +# Plugin Prompt Hooks Spec ## Metadata - Created: 2026-06-12 -- Last Edited: 2026-06-22 +- Last Edited: 2026-06-24 ## Purpose -Define the generic plugin hooks and background tasks that let runtime hook -plugins contribute prompt text and process completed agent-run sessions without -exposing raw Junior internals or creating memory-specific plugin APIs. +Define the generic plugin hooks that let runtime hook plugins contribute prompt +text without exposing raw Junior internals or creating memory-specific plugin +APIs. ## Implementation Status Plugin prompt hooks are implemented in Junior core and -`@sentry/junior-plugin-api`. The typed plugin task surface described here is -the target contract for background work. The previous post-run observation hook -shape is superseded by `session.completed` plugin tasks and should be removed -when the task runner lands. +`@sentry/junior-plugin-api`. The previous post-run observation hook shape is +superseded by the task surface defined in `./plugin-tasks.md`. ## Scope - Plugin-provided system prompt and user prompt contributions. - Prompt hook context. -- Typed plugin background task registration. -- Completed agent-run session task contract for passive extraction workflows. - Security and rendering boundaries for prompt contributions. - V1 memory plugin usage of these generic hooks. @@ -35,20 +31,18 @@ when the task runner lands. - A general event bus for every runtime lifecycle transition. - Model-visible memory management as the only memory path. - Storage schema for long-lived memory records. -- Exposing raw queue clients, queue topic names, callback routes, or worker - implementation details to plugins. +- Plugin background task execution; see `./plugin-tasks.md`. ## Contracts ### Registration Surface -Runtime hook plugins may provide prompt hooks and typed background tasks: +Runtime hook plugins may provide prompt hooks: ```ts interface PluginRegistrationInput { manifest: PluginManifest; hooks?: PluginHooks; - tasks?: PluginTasks; } interface PluginHooks { @@ -60,8 +54,6 @@ interface PluginHooks { ctx: UserPromptContext, ): PromptMessage[] | undefined | Promise; } - -type PluginTasks = Record>; ``` These hooks are app-code plugin hooks registered through @@ -197,127 +189,16 @@ The context must not expose: - cross-plugin state - model messages outside the safe hook-specific context -### Plugin Background Tasks - -Plugin tasks let plugins perform durable post-run work without blocking visible -reply delivery. Core owns when tasks are scheduled, how they are queued, how -they are retried, and how task params are persisted. - -```ts -interface PluginTaskDefinition { - trigger?: PluginTaskTrigger; - paramsSchema: TSchema; - run(ctx: PluginTaskContext>): Promise | void; -} - -type PluginTaskTrigger = "session.completed"; - -interface PluginTaskContext extends PluginContext { - id: string; - name: string; - params: TParams; - embedder: PluginEmbedder; - model: PluginModel; - state: PluginState; - session: PluginSessionReader; -} - -interface PluginSessionReader { - load(): Promise; -} - -interface PluginSessionContext { - completedAtMs: number; - conversationId: string; - destination: Destination; - messages: PluginSessionMessage[]; - requester?: Requester; - sessionId: string; - source: Source; - successfulToolCalls: string[]; -} - -interface PluginSessionMessage { - createdAtMs?: number; - role: "user" | "assistant"; - text: string; -} - -function definePluginTask( - task: PluginTaskDefinition, -): PluginTaskDefinition; -``` - -Task params are schema-validated before persistence and again before execution. -They must contain stable references such as `conversationId`, `sessionId`, or -run/session ids. They must not contain raw conversation text, raw assistant -text, raw tool payloads, credentials, authorization URLs, OAuth tokens, Slack -tokens, or provider credentials. - -The queue payload is a core-owned delivery envelope containing only a durable -task id. The durable task record carries plugin name, task name, parsed params, -status, attempt count, lease state, and timestamps. Plugins never receive raw -queue clients, queue topics, callback routes, message metadata, or delivery -acknowledgement controls. - -`session.load()` returns a bounded core-owned projection reconstructed from the -completed session record and transcript/session-log storage. It must not expose -raw Pi internals, full transcript history, private tool arguments/results, or -provider credentials. Core applies source privacy rules before returning raw -message text to a plugin task. Unknown or private source visibility fails -closed unless a future explicit privacy contract allows that task. - -Task rules: - -1. Task names are resolved only inside the owning plugin. -2. Task params are bounded JSON-serializable data parsed by the task's - `paramsSchema`. -3. Task handlers run with plugin-scoped `ctx.db`, `ctx.state`, logger, host - model access, host embedding access, and task-specific readers. -4. Task handlers must be idempotent because delivery is at least once. -5. Core owns queue acknowledgement, retry, redelivery, worker leases, callback - signing, and provider-specific visibility timeouts. -6. Plugins must not depend on task execution happening in the same process or - same request that completed the agent run. - -### `session.completed` Tasks - -Core schedules `session.completed` tasks after a successful user-visible agent -run has been delivered and the completed session record has been durably -committed. The task params should be the minimum stable references needed to -reload the completed run/session, such as: - -```ts -const sessionCompletedParamsSchema = z - .object({ - conversationId: z.string().min(1), - sessionId: z.string().min(1), - }) - .strict(); -``` - -If the historical session id is not the stable run identity for a path, core may -include a separate run/session record id. The params should not duplicate -`source`, `destination`, `requester`, messages, or tool-call data when those can -be loaded from completed runtime storage. - -The task idempotency key is derived from plugin name, task name, trigger name, -and the completed session reference. Duplicate queue delivery or duplicate -scheduling of the same completed session must run the plugin task at most once -successfully. - ### Memory Plugin V1 Usage -The memory plugin should use the generic hooks and task surface as follows: +The memory plugin should use the generic prompt hook surface as follows: 1. `userPrompt(ctx)` retrieves memories visible to the current requester and source, then returns a concise memory block for the run's triggering prompt. -2. `tasks.processSession` handles the `session.completed` trigger, loads the - completed session projection, runs the memory-owned structured extraction - agent, and writes accepted facts idempotently. -3. `tools(ctx)` may expose explicit memory tools such as `createMemory`, +2. `tools(ctx)` may expose explicit memory tools such as `createMemory`, `removeMemory`, `listMemories`, and `searchMemories`. +Passive memory learning uses the task surface defined in `./plugin-tasks.md`. Memory retrieval must not depend on the model choosing a search tool for default recall. `searchMemories` remains the explicit model-visible recall path for targeted recall and follow-up memory management. Other tools are for explicit @@ -358,8 +239,6 @@ Core owns prompt rendering: and continue unless startup validation can catch the problem earlier. 2. Oversized contribution: truncate only if the contribution contract supports deterministic truncation; otherwise omit and log safe metadata. -3. Plugin task failure: log safe metadata, retry according to the core task - policy, and do not change the completed visible run result. ## Observability @@ -392,16 +271,10 @@ Use integration tests for: checkpoint - private conversation prompt contribution payloads are redacted from logs, traces, and dashboard APIs -- plugin task params are schema-validated before persistence and execution -- `session.completed` plugin tasks load bounded completed-session projections - without exposing raw private payloads -- duplicate scheduling or queue delivery does not run a completed plugin task - more than once successfully Use unit tests for: - hook return-shape validation -- task schema validation and plugin-local task name validation - deterministic plugin ordering - memory tool schema rejection of model-supplied actor or destination fields @@ -418,7 +291,7 @@ Use evals for: - `./agent-prompt.md` - `./plugin.md` - `./plugin-runtime.md` -- `./task-execution.md` +- `./plugin-tasks.md` - `./memory-plugin/index.md` - `./plugin-heartbeat.md` - `./identity.md` diff --git a/specs/plugin-tasks.md b/specs/plugin-tasks.md index 846f10cd1..7465f4db9 100644 --- a/specs/plugin-tasks.md +++ b/specs/plugin-tasks.md @@ -106,7 +106,9 @@ Task handlers receive a narrow plugin task context: ```ts interface PluginTaskContext extends PluginContext { + embedder: PluginEmbedder; id: string; + model: PluginModel; name: string; state: PluginState; session: { @@ -115,8 +117,9 @@ interface PluginTaskContext extends PluginContext { } ``` -`ctx.db` and `ctx.state` are direct host capabilities. Core must not add extra -database facades or schema-hiding layers solely to restrict plugins. +`ctx.db`, `ctx.state`, `ctx.model`, and `ctx.embedder` are direct host +capabilities. Core must not add extra database facades or schema-hiding layers +solely to restrict plugins. The task context must not expose raw queue messages, queue clients, queue topics, route URLs, retry acknowledgement controls, raw HTTP requests, provider From be48b1ff5b1e7424df30714ba3c51cb760eeed85 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 17:56:58 -0700 Subject: [PATCH 14/29] fix(ai): Pass Gateway credentials to Pi Agent Use the same Gateway credential resolution for Pi Agent runs that the direct completion path already uses. This prevents local agent runs with AI_GATEWAY_API_KEY from reaching the provider without usable auth and surfacing as empty assistant responses. Only pass a getApiKey hook when Junior has an explicit Gateway credential, so Pi can keep its own default behavior otherwise. Co-Authored-By: GPT-5 Codex --- packages/junior/src/chat/respond.ts | 4 ++-- packages/junior/src/chat/tools/advisor/tool.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/junior/src/chat/respond.ts b/packages/junior/src/chat/respond.ts index 067be1c84..47078652a 100644 --- a/packages/junior/src/chat/respond.ts +++ b/packages/junior/src/chat/respond.ts @@ -1434,9 +1434,9 @@ export async function generateAssistantReply( throw cooperativeYieldError; }; - const hasGatewayCredential = Boolean(getPiGatewayApiKey()); + const apiKeyOverride = getPiGatewayApiKey(); agent = new Agent({ - ...(hasGatewayCredential ? { getApiKey: getPiGatewayApiKey } : {}), + ...(apiKeyOverride ? { getApiKey: () => apiKeyOverride } : {}), streamFn: createTracedStreamFn({ conversationPrivacy }), steeringMode: "all", prepareNextTurn: async () => { diff --git a/packages/junior/src/chat/tools/advisor/tool.ts b/packages/junior/src/chat/tools/advisor/tool.ts index e3f68de80..b81a01be3 100644 --- a/packages/junior/src/chat/tools/advisor/tool.ts +++ b/packages/junior/src/chat/tools/advisor/tool.ts @@ -227,9 +227,9 @@ export function createAdvisorTool(context: AdvisorToolRuntimeContext) { ); } - const hasGatewayCredential = Boolean(getPiGatewayApiKey()); + const apiKeyOverride = getPiGatewayApiKey(); const advisorAgent = new Agent({ - ...(hasGatewayCredential ? { getApiKey: getPiGatewayApiKey } : {}), + ...(apiKeyOverride ? { getApiKey: () => apiKeyOverride } : {}), initialState: { systemPrompt: ADVISOR_SYSTEM_PROMPT, model: resolveGatewayModel(context.config.modelId), From 0803215cd26ca1d9b8f8d76eca15a556ccd86d45 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 18:13:27 -0700 Subject: [PATCH 15/29] docs(plugins): Tighten task contract wording Remove stale future-tense and trusted-runtime phrasing from the plugin task contracts now that background tasks are implemented in this slice. Co-Authored-By: GPT-5 Codex --- specs/memory-plugin/security.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/memory-plugin/security.md b/specs/memory-plugin/security.md index 2b3e0e441..ad7edbf09 100644 --- a/specs/memory-plugin/security.md +++ b/specs/memory-plugin/security.md @@ -100,8 +100,8 @@ reported, exported, retained, or exposed under weaker rules than memory content. ## Task Payloads -Future plugin background task payloads must contain stable references and -bounded safe metadata only. +Plugin background task params and queue payloads must contain stable references +and bounded safe metadata only. They must not contain: From c5c204fa530139e11f5f052a8a7a0e84f576dcd7 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Wed, 24 Jun 2026 19:12:56 -0700 Subject: [PATCH 16/29] fix(memory): Harden background task recovery Keep plugin task durability in Redis-backed state while Vercel Queue messages remain signed wakeups. Add active recovery tracking, max-age enforcement, terminal-record enqueue skips, and retry-stable memory extraction writes. Remove the no-op task definition wrapper from the public plugin API and update docs/specs around plugin tasks, Redis state, and deployment verification. Co-Authored-By: GPT-5 Codex --- .../src/content/docs/extend/build-a-plugin.md | 17 +- .../docs/src/content/docs/extend/index.md | 4 +- .../content/docs/reference/config-and-env.md | 3 +- .../src/content/docs/start-here/quickstart.md | 4 +- packages/junior-memory/src/agent.ts | 11 +- packages/junior-memory/src/plugin.ts | 6 +- packages/junior-memory/src/process-session.ts | 76 +++++++-- packages/junior-memory/tests/storage.test.ts | 161 ++++++++++-------- packages/junior-plugin-api/src/context.ts | 2 - .../junior-plugin-api/src/registration.ts | 6 + .../junior/src/chat/plugins/agent-hooks.ts | 4 +- packages/junior/src/chat/plugins/model.ts | 7 +- .../junior/src/chat/plugins/task-runner.ts | 2 +- specs/memory-plugin/extraction.md | 2 +- specs/memory-plugin/security.md | 2 +- specs/memory-plugin/storage.md | 9 +- 16 files changed, 188 insertions(+), 128 deletions(-) diff --git a/packages/docs/src/content/docs/extend/build-a-plugin.md b/packages/docs/src/content/docs/extend/build-a-plugin.md index 796a9422c..be6aaa0f8 100644 --- a/packages/docs/src/content/docs/extend/build-a-plugin.md +++ b/packages/docs/src/content/docs/extend/build-a-plugin.md @@ -172,16 +172,17 @@ export const plugins = defineJuniorPlugins([myProviderPlugin()]); Use `ctx.decision.replaceInput(...)` only with object-shaped tool input. Junior rejects non-object replacements before the tool runs. -### Hook surfaces +### Runtime surfaces -Use the smallest hook that matches the deterministic boundary your plugin needs: +Use the smallest surface that matches the deterministic boundary your plugin needs: -| Hook | Purpose | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------ | -| `sandboxPrepare(ctx)` | Prepare files or runtime state inside a sandbox before agent tools run. | -| `beforeToolExecute(ctx)` | Deny or rewrite object-shaped tool input and set non-secret env values before a tool runs. | -| `tools(ctx)` | Return host-registered tool definitions for the current turn. Tool names must be camelCase and cannot shadow core tools. | -| `heartbeat(ctx)` | Run bounded periodic work from Junior's internal heartbeat route. | +| Surface | Purpose | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------- | +| `sandboxPrepare(ctx)` | Prepare files or runtime state inside a sandbox before agent tools run. | +| `beforeToolExecute(ctx)` | Deny or rewrite object-shaped tool input and set non-secret env values before a tool runs. | +| `tools(ctx)` | Return host-registered tool definitions for the current turn. Tool names must be camelCase and cannot shadow core tools. | +| `heartbeat(ctx)` | Run bounded periodic work from Junior's internal heartbeat route. | +| `tasks` | Register plugin-owned background tasks. V1 tasks run after completed sessions and load bounded context with `ctx.session.load()`. | `tools(ctx)` receives the active turn context, `ctx.state`, and `ctx.log`. Return tool definitions keyed by the public tool names your plugin owns: diff --git a/packages/docs/src/content/docs/extend/index.md b/packages/docs/src/content/docs/extend/index.md index 1c450481a..73bd3fd49 100644 --- a/packages/docs/src/content/docs/extend/index.md +++ b/packages/docs/src/content/docs/extend/index.md @@ -145,9 +145,9 @@ tools and heartbeat behavior, and the GitHub plugin installs a sandbox Git hook, configures global Git defaults, and injects commit attribution env before bash commands run. -Runtime hooks are explicit app code because the app imports the plugin factory +Runtime surfaces are explicit app code because the app imports the plugin factory into `plugins.ts`. A package should use either `plugin.yaml` or -`defineJuniorPlugin({ manifest, hooks })`, not both. Use +`defineJuniorPlugin({ manifest, hooks, tasks })`, not both. Use [Build a Plugin](/extend/build-a-plugin/) for the package authoring contract. ## Local skills vs plugin skills diff --git a/packages/docs/src/content/docs/reference/config-and-env.md b/packages/docs/src/content/docs/reference/config-and-env.md index b21b79ce5..ee48557b1 100644 --- a/packages/docs/src/content/docs/reference/config-and-env.md +++ b/packages/docs/src/content/docs/reference/config-and-env.md @@ -16,7 +16,7 @@ related: | ------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `SLACK_SIGNING_SECRET` | Yes | Verifies Slack request signatures. | | `SLACK_BOT_TOKEN` or `SLACK_BOT_USER_TOKEN` | Yes | Posts thread replies and calls Slack APIs. | -| `REDIS_URL` | Yes | Queue and runtime state storage. | +| `REDIS_URL` | Yes | Runtime state, locks, and durable background task records. Vercel Queues only deliver wakeups. | | `DATABASE_URL` | No | Standard Neon/Vercel Postgres URL. When set, Junior uses SQL for queryable records and reporting. | | `JUNIOR_DATABASE_URL` | No | Optional override for the Junior SQL database when it should differ from `DATABASE_URL`. | | `JUNIOR_DATABASE_DRIVER` | No | SQL client driver for Junior records: `neon` or `postgres`. Defaults to `neon`; set `postgres` for local Postgres or node-postgres deployments. | @@ -31,6 +31,7 @@ related: | `AI_WEB_SEARCH_MODEL` | No | Override for the `webSearch` tool model. Defaults to `openai/gpt-5.4`; does not fall through to `AI_MODEL`. | | `JUNIOR_BASE_URL` | No | Canonical base URL for callback/auth URL generation. | | `JUNIOR_STATE_KEY_PREFIX` | No | Optional namespace prepended to all state-adapter keys, locks, and queues. Use separate prefixes when sharing one Redis database across environments. | +| `JUNIOR_PLUGIN_TASK_QUEUE_TOPIC` | No | Vercel Queue topic for plugin background task wakeups. Defaults to `junior_plugin_tasks`. | | `CRON_SECRET` or `JUNIOR_SCHEDULER_SECRET` | Conditional | Bearer token for the internal heartbeat route; use `CRON_SECRET` with Vercel Cron, or `JUNIOR_SCHEDULER_SECRET` for a non-Vercel heartbeat caller. | | `JUNIOR_TIMEZONE` | No | Default IANA timezone for scheduler authoring when the scheduler plugin is enabled. Defaults to `America/Los_Angeles`. | | `AI_GATEWAY_API_KEY` | No | AI gateway auth if used in your setup. | diff --git a/packages/docs/src/content/docs/start-here/quickstart.md b/packages/docs/src/content/docs/start-here/quickstart.md index 5c099dc47..22d18a455 100644 --- a/packages/docs/src/content/docs/start-here/quickstart.md +++ b/packages/docs/src/content/docs/start-here/quickstart.md @@ -18,7 +18,7 @@ Use the same baseline that the scaffolded CI workflow uses: - Node.js 24 - pnpm -- A Redis URL for queue and state storage +- A Redis URL for runtime state, locks, and durable task records Slack credentials are needed before the bot can reply in Slack. You can scaffold and verify the local health route first, then finish [Slack App Setup](/start-here/slack-app-setup/). @@ -60,7 +60,7 @@ Set these values before running real turns: | ------------------------- | ---------------------- | -------------------------------------------------------------- | | `SLACK_SIGNING_SECRET` | Yes, for Slack traffic | Verifies Slack requests. | | `SLACK_BOT_TOKEN` | Yes, for Slack replies | Posts thread replies and calls Slack APIs. | -| `REDIS_URL` | Yes | Queue and runtime state storage. | +| `REDIS_URL` | Yes | Runtime state, locks, and durable background task records. | | `JUNIOR_SECRET` | Yes | Signs internal resume callbacks and sandbox requester context. | | `JUNIOR_BOT_NAME` | No | Bot display/config name. | | `JUNIOR_SLASH_COMMAND` | No | Slack slash command name. Defaults to `/jr`. | diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 1d913d9e3..807543dbd 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -153,10 +153,6 @@ export interface MemoryAgent { ): Promise | MemoryReview; } -export interface MemoryAgentOptions { - modelId?: string; -} - const MEMORY_REVIEW_SYSTEM = [ "You are Junior's memory review agent.", "Review one memory candidate and return one structured review decision.", @@ -339,15 +335,11 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { } /** Create the memory-owned agent that reviews and extracts memory candidates. */ -export function createMemoryAgent( - model: PluginModel, - options: MemoryAgentOptions = {}, -): MemoryAgent { +export function createMemoryAgent(model: PluginModel): MemoryAgent { return { async extractSessionMemories(rawRequest) { const request = extractSessionRequestSchema.parse(rawRequest); const result = await model.completeObject({ - ...(options.modelId ? { modelId: options.modelId } : {}), schema: extractMemoriesResponseSchema, system: MEMORY_EXTRACTION_SYSTEM, prompt: sessionExtractionPrompt(request), @@ -360,7 +352,6 @@ export function createMemoryAgent( async reviewCreateRequest(rawRequest) { const request = parseCreateMemoryRequest(rawRequest); const result = await model.completeObject({ - ...(options.modelId ? { modelId: options.modelId } : {}), schema: memoryReviewResponseSchema, system: MEMORY_REVIEW_SYSTEM, prompt: reviewPrompt(request), diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index 4603b3505..a2b7b5e4f 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -51,13 +51,13 @@ function memoryToolContext(ctx: { /** Create Junior's long-term memory plugin registration. */ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { const modelId = memoryModelId(options); - const agentOptions = modelId ? { modelId } : {}; return defineJuniorPlugin({ manifest: { name: "memory", displayName: "Memory", description: "Long-term Junior memory storage and recall", }, + ...(modelId ? { model: { structuredModelId: modelId } } : {}), packageName: "@sentry/junior-memory", cli: { commands: [createMemoryCliCommand()], @@ -65,7 +65,7 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { tasks: { processSession: { async run(ctx) { - await processMemorySession(ctx, agentOptions); + await processMemorySession(ctx); }, }, }, @@ -73,7 +73,7 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { tools(ctx) { const context = memoryToolContext({ ...ctx, - agent: createMemoryAgent(ctx.model, agentOptions), + agent: createMemoryAgent(ctx.model), db: ctx.db as MemoryDb, embedder: ctx.embedder, }); diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior-memory/src/process-session.ts index a269f4fc4..4af6fcac4 100644 --- a/packages/junior-memory/src/process-session.ts +++ b/packages/junior-memory/src/process-session.ts @@ -1,39 +1,77 @@ +import { createHash } from "node:crypto"; import { getSourceKey, isPrivateSource, type PluginTaskContext, } from "@sentry/junior-plugin-api"; +import { z } from "zod"; import { createMemoryStore, type CreateMemoryInput, type MemoryDb, } from "./store"; -import { - createMemoryAgent, - type ExtractedMemory, - type MemoryAgentOptions, -} from "./agent"; +import { createMemoryAgent, type ExtractedMemory } from "./agent"; import { memoryRuntimeContextSchema } from "./types"; const MEMORY_MUTATION_TOOL_NAMES = new Set(["createMemory", "removeMemory"]); +const MEMORY_TASK_STATE_TTL_MS = 7 * 24 * 60 * 60 * 1000; +const extractedMemoryCacheSchema = z.array( + z + .object({ + content: z.string().min(1), + expiresAtMs: z.number().finite().nullable(), + target: z.enum(["requester", "conversation"]), + }) + .strict(), +); + +function memoryIdempotencySuffix(memory: ExtractedMemory): string { + return createHash("sha256") + .update(memory.target) + .update("\0") + .update(memory.content) + .update("\0") + .update(memory.expiresAtMs === null ? "never" : String(memory.expiresAtMs)) + .digest("hex") + .slice(0, 32); +} function passiveInput( sessionId: string, memory: ExtractedMemory, - index: number, sourceKey: string, ): CreateMemoryInput { return { content: memory.content, - idempotencyKey: `session:${sourceKey}:${sessionId}:${index}`, + idempotencyKey: `session:${sourceKey}:${sessionId}:${memoryIdempotencySuffix(memory)}`, ...(memory.expiresAtMs !== null ? { expiresAtMs: memory.expiresAtMs } : {}), }; } -/** Extract and store memories from a completed session plugin task. */ +async function getTaskMemories( + context: PluginTaskContext, + extract: () => Promise, +): Promise { + const cacheKey = `memory-extraction:${context.id}`; + const cached = await context.state.get(cacheKey); + if (cached !== undefined) { + return extractedMemoryCacheSchema.parse(cached); + } + const memories = await extract(); + await context.state.set(cacheKey, memories, MEMORY_TASK_STATE_TTL_MS); + return memories; +} + +/** + * Extract and store memories from a completed session plugin task. + * + * Memory owns post-session extraction and consumes only the bounded plugin task + * projection. Explicit memory tools and private non-local sources remain hard + * boundaries so background retries cannot reinterpret user-directed mutations + * or private conversations. + */ export async function processMemorySession( context: PluginTaskContext, - options: MemoryAgentOptions = {}, ): Promise { const session = await context.session.load(); // Explicit memory mutation tools already own the user's memory-management intent. @@ -76,20 +114,22 @@ export async function processMemorySession( limit: 10, query: userText, }); - const agent = createMemoryAgent(context.model, options); - const memories = await agent.extractSessionMemories({ - existingMemories: existingMemories.map((memory) => ({ - content: memory.content, - })), - messages, - runtimeContext, + const memories = await getTaskMemories(context, async () => { + const agent = createMemoryAgent(context.model); + return await agent.extractSessionMemories({ + existingMemories: existingMemories.map((memory) => ({ + content: memory.content, + })), + messages, + runtimeContext, + }); }); if (memories.length === 0) { return; } - for (const [index, memory] of memories.entries()) { - const input = passiveInput(session.sessionId, memory, index, sourceKey); + for (const memory of memories) { + const input = passiveInput(session.sessionId, memory, sourceKey); if (memory.target === "conversation") { await store.createConversationMemory(input); continue; diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 417d84ba8..a36247096 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -61,6 +61,31 @@ const memoryState: PluginState = { }, }; +function createMemoryState(): PluginState { + const values = new Map(); + return { + async delete(key) { + values.delete(key); + }, + async get(key: string): Promise { + return values.get(key) as T | undefined; + }, + async set(key, value) { + values.set(key, value); + }, + async setIfNotExists(key, value) { + if (values.has(key)) { + return false; + } + values.set(key, value); + return true; + }, + async withLock(_key, _ttlMs, callback) { + return await callback(); + }, + }; +} + const defaultEmbedding = unitEmbedding(0); function memoryDb(fixture: MemoryFixture): MemoryDb { @@ -386,57 +411,14 @@ describe("memory plugin storage", () => { expect(calls[0]?.schema).toBeDefined(); }); - it("passes configured model id to memory agent structured calls", async () => { - const calls: Parameters[0][] = []; - let callIndex = 0; - const model: PluginModel = { - async completeObject(input) { - calls.push(input); - callIndex += 1; - if (callIndex === 1) { - return { - object: { - memories: [], - }, - }; - } - return { - object: { - decision: "reject", - target: null, - canonicalFact: null, - reason: "not_durable", - expiresAtMs: null, - }, - }; - }, - }; - const agent = createMemoryAgent(model, { + it("registers explicit model id as memory plugin model configuration", () => { + const plugin = createMemoryPlugin({ modelId: "anthropic/claude-sonnet-4.6", }); - await agent.extractSessionMemories({ - messages: [ - { - role: "user", - text: "I prefer terse PR summaries.", - }, - { - role: "assistant", - text: "Got it.", - }, - ], - runtimeContext: localContext(), - }); - await agent.reviewCreateRequest({ - content: "I prefer terse PR summaries.", - runtimeContext: localContext(), + expect(plugin.model).toEqual({ + structuredModelId: "anthropic/claude-sonnet-4.6", }); - - expect(calls.map((call) => call.modelId)).toEqual([ - "anthropic/claude-sonnet-4.6", - "anthropic/claude-sonnet-4.6", - ]); }); it("parses canonical requester extraction into stored memory text", async () => { @@ -484,33 +466,13 @@ describe("memory plugin storage", () => { it("uses AI_MEMORY_MODEL as the memory plugin model default", async () => { const previousModel = process.env.AI_MEMORY_MODEL; process.env.AI_MEMORY_MODEL = "anthropic/claude-sonnet-4.6"; - const fixture = await createMemoryFixture(); - const calls: Parameters[0][] = []; - const model: PluginModel = { - async completeObject(input) { - calls.push(input); - return { - object: { - memories: [], - }, - }; - }, - }; try { const plugin = createMemoryPlugin(); - await plugin.tasks?.processSession?.run( - processSessionContext({ - db: memoryDb(fixture), - model, - }), - ); - - expect(calls.map((call) => call.modelId)).toEqual([ - "anthropic/claude-sonnet-4.6", - ]); + expect(plugin.model).toEqual({ + structuredModelId: "anthropic/claude-sonnet-4.6", + }); } finally { - await fixture.close(); if (previousModel === undefined) { delete process.env.AI_MEMORY_MODEL; } else { @@ -617,6 +579,65 @@ describe("memory plugin storage", () => { } }, 15_000); + it("reuses cached extraction output across task retries", async () => { + const fixture = await createMemoryFixture(); + + try { + const state = createMemoryState(); + const { model, calls } = extractionModel([ + { + content: "Prefers retry-safe memory extraction.", + target: "requester", + }, + ]); + const session = { + async load() { + return completedSession({ + messages: [ + { + role: "user", + text: "I prefer retry-safe memory extraction.", + }, + ], + }); + }, + }; + + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + session, + state, + }), + ); + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model: { + async completeObject() { + throw new Error("model should not run on cached retry"); + }, + }, + session, + state, + }), + ); + + expect(calls).toHaveLength(1); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([ + expect.objectContaining({ + content: "Prefers retry-safe memory extraction.", + scope: "personal", + }), + ]); + } finally { + await fixture.close(); + } + }, 15_000); + it("skips passive extraction for successful memory mutation tool turns", async () => { const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ diff --git a/packages/junior-plugin-api/src/context.ts b/packages/junior-plugin-api/src/context.ts index dad31c49f..9bd4f30c0 100644 --- a/packages/junior-plugin-api/src/context.ts +++ b/packages/junior-plugin-api/src/context.ts @@ -39,8 +39,6 @@ export interface PluginModel { /** Run a host-owned structured model call without exposing provider credentials. */ completeObject(input: { maxTokens?: number; - /** Optional host model id override for plugin-owned structured calls. */ - modelId?: string; prompt: string; schema: TSchema; system?: string; diff --git a/packages/junior-plugin-api/src/registration.ts b/packages/junior-plugin-api/src/registration.ts index 9e629b848..901d497f6 100644 --- a/packages/junior-plugin-api/src/registration.ts +++ b/packages/junior-plugin-api/src/registration.ts @@ -3,10 +3,16 @@ import type { PluginHooks } from "./hooks"; import type { PluginManifest } from "./manifest"; import type { PluginTasks } from "./tasks"; +export interface PluginModelConfig { + /** Host model id used for this plugin's structured model calls. */ + structuredModelId?: string; +} + export type PluginRegistrationInput = { cli?: PluginCliDefinition; hooks?: PluginHooks; manifest: PluginManifest; + model?: PluginModelConfig; packageName?: string; tasks?: PluginTasks; }; diff --git a/packages/junior/src/chat/plugins/agent-hooks.ts b/packages/junior/src/chat/plugins/agent-hooks.ts index e5dae4e4b..0d97877d5 100644 --- a/packages/junior/src/chat/plugins/agent-hooks.ts +++ b/packages/junior/src/chat/plugins/agent-hooks.ts @@ -413,7 +413,7 @@ export function getPluginTools( source: context.source, userText: context.userText, embedder: createPluginEmbedder(pluginName), - model: createPluginModel(pluginName), + model: createPluginModel(pluginName, plugin.model), state: createPluginState(pluginName), }; } else { @@ -433,7 +433,7 @@ export function getPluginTools( source: context.source, userText: context.userText, embedder: createPluginEmbedder(pluginName), - model: createPluginModel(pluginName), + model: createPluginModel(pluginName, plugin.model), state: createPluginState(pluginName), }; } diff --git a/packages/junior/src/chat/plugins/model.ts b/packages/junior/src/chat/plugins/model.ts index 262247a3a..bed6ea49a 100644 --- a/packages/junior/src/chat/plugins/model.ts +++ b/packages/junior/src/chat/plugins/model.ts @@ -3,11 +3,14 @@ import { botConfig } from "@/chat/config"; import { completeObject, embedTexts } from "@/chat/pi/client"; /** Create the host-owned structured model capability exposed to plugins. */ -export function createPluginModel(pluginName: string): PluginModel { +export function createPluginModel( + pluginName: string, + options: { structuredModelId?: string } = {}, +): PluginModel { return { async completeObject(input) { const result = await completeObject({ - modelId: input.modelId ?? botConfig.fastModelId, + modelId: options.structuredModelId ?? botConfig.fastModelId, schema: input.schema, prompt: input.prompt, ...(input.system !== undefined ? { system: input.system } : {}), diff --git a/packages/junior/src/chat/plugins/task-runner.ts b/packages/junior/src/chat/plugins/task-runner.ts index 9367196e4..47f5079be 100644 --- a/packages/junior/src/chat/plugins/task-runner.ts +++ b/packages/junior/src/chat/plugins/task-runner.ts @@ -177,7 +177,7 @@ function taskPluginContext( embedder: createPluginEmbedder(pluginName), id: pluginTaskId(message), log: createPluginLogger(pluginName), - model: createPluginModel(pluginName), + model: createPluginModel(pluginName, plugin.model), name: message.name, plugin: { name: pluginName }, session: { diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 494b9628b..847c95e97 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -98,7 +98,7 @@ The `processSession` task must: deriving all authority-bearing ids from runtime context. 11. Insert accepted memories idempotently with a stable key derived through the runtime source helper, completed session reference, and extracted fact - position. + content. 12. Generate embeddings for accepted rows when the host embedder is configured. 13. Avoid storing raw extraction prompt, raw model output, or raw session text beyond the accepted memory records. diff --git a/specs/memory-plugin/security.md b/specs/memory-plugin/security.md index ad7edbf09..67110e1e2 100644 --- a/specs/memory-plugin/security.md +++ b/specs/memory-plugin/security.md @@ -36,7 +36,7 @@ The store must derive authority-bearing fields from Junior runtime context: - tenant/workspace/org boundary when available - destination or conversation identity - source actor -- source event or observation id +- source event or completed-session id The model may request memory operations, but it cannot choose authority fields. Tool arguments can express content, query text, limit, or expiration. They diff --git a/specs/memory-plugin/storage.md b/specs/memory-plugin/storage.md index 6275f262a..ad23f6b2a 100644 --- a/specs/memory-plugin/storage.md +++ b/specs/memory-plugin/storage.md @@ -54,7 +54,7 @@ Required conceptual fields: - subject type - runtime-derived subject key when the subject is a user or conversation - runtime-derived source attribution -- observation or tool idempotency marker +- completed-session or tool idempotency marker - observed timestamp - created timestamp - optional expiration timestamp @@ -128,10 +128,9 @@ The store must be able to filter active visible records by: ### Idempotency And Duplicates -Passive extraction must be idempotent across repeated observations, queue -redelivery, and task retry. The store needs a stable source marker for a -completed observation and the extracted fact's position or stable fact id inside -that observation. +Passive extraction must be idempotent across repeated completed-session task +scheduling, queue redelivery, and task retry. The store needs a stable source +marker for a completed session and each extracted fact. Semantic duplicate suppression needs extractor and retrieval context. It runs before insertion in memory creation paths that have memory agent review, but V1 From a63749f85c710a2e9673601fe3ef94418f2ef25d Mon Sep 17 00:00:00 2001 From: David Cramer Date: Thu, 25 Jun 2026 08:25:15 -0700 Subject: [PATCH 17/29] ref(plugins): Simplify background task queues Use signed Vercel Queue messages as the durable plugin task request instead of persisting a separate task store. Keep local development queue clients explicit and adjust task tests around the Queue SDK callback contract. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 15 ++-- packages/junior-evals/src/behavior-harness.ts | 80 +++++++++++++++++++ packages/junior-memory/src/agent.ts | 24 +++--- packages/junior-memory/src/process-session.ts | 8 +- packages/junior/src/handlers/heartbeat.ts | 17 +--- specs/index.md | 2 +- 6 files changed, 111 insertions(+), 35 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index d540c4d4c..61aa7a3a3 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -4,7 +4,10 @@ import { closeDb, getDb } from "@/chat/db"; import { completeText, resolveGatewayModel } from "@/chat/pi/client"; import { createMemoryStore, type MemoryDb } from "@sentry/junior-memory"; import { createSlackSource } from "@sentry/junior-plugin-api"; -import { juniorMemoryMemories } from "../../../junior-memory/src/db/schema"; +import { + juniorMemoryEmbeddings, + juniorMemoryMemories, +} from "../../../junior-memory/src/db/schema"; import { mention, rubric, slackEvals } from "../../src/helpers"; const memoryPluginOverrides = { @@ -69,6 +72,7 @@ async function readMemories(thread: MemoryThread) { } async function clearMemories() { + await memoryDb().delete(juniorMemoryEmbeddings); await memoryDb().delete(juniorMemoryMemories); } @@ -334,13 +338,13 @@ describeEval("Memory Workflows", slackEvals, (it) => { }); const rows = await readMemories(passiveFirstPersonThread); - expect(rows).toEqual([ + expect(rows).toContainEqual( expect.objectContaining({ archivedAtMs: null, scope: "personal", subjectType: "user", }), - ]); + ); await expectRequesterMemorySemantics({ assistantText: visibleAssistantText(result), expectedMeaning: @@ -422,13 +426,14 @@ describeEval("Memory Workflows", slackEvals, (it) => { }), }); - expect(await readMemories(autoRecallThread)).toEqual([ + const rows = await readMemories(autoRecallThread); + expect(rows).toContainEqual( expect.objectContaining({ archivedAtMs: null, content: "Prefers PR summaries with risks first.", scope: "personal", }), - ]); + ); }); const passiveDedupeThread = { diff --git a/packages/junior-evals/src/behavior-harness.ts b/packages/junior-evals/src/behavior-harness.ts index 30f66c515..7c53d804c 100644 --- a/packages/junior-evals/src/behavior-harness.ts +++ b/packages/junior-evals/src/behavior-harness.ts @@ -4,6 +4,7 @@ import { generateKeyPairSync } from "node:crypto"; import { createServer, type Server } from "node:http"; import { fileURLToPath } from "node:url"; import { vi } from "vitest"; +import type { SlackAdapter } from "@chat-adapter/slack"; import type { Message } from "chat"; import type { Destination } from "@sentry/junior-plugin-api"; import { @@ -37,7 +38,13 @@ import { getPluginOAuthConfig, setPluginCatalogConfig, } from "@/chat/plugins/registry"; +import { + processPluginTask, + scheduleSessionCompletedPluginTasks, +} from "@/chat/plugins/task-runner"; import { generateAssistantReply } from "@/chat/respond"; +import { resumeAwaitingSlackContinuation } from "@/chat/runtime/agent-continue-runner"; +import { scheduleAgentContinue } from "@/chat/services/agent-continue"; import { createSchedulerSqlStore, schedulerPlugin, @@ -64,6 +71,10 @@ import { createTestThread, type TestThread, } from "@junior-tests/fixtures/slack-harness"; +import { + createConversationWorkQueueTestAdapter, + type ConversationWorkQueueTestAdapter, +} from "@junior-tests/fixtures/conversation-work"; import { EVAL_OAUTH_CODE, EVAL_OAUTH_PROVIDER, @@ -79,6 +90,8 @@ import { type CapturedSlackApiCall, } from "@junior-tests/msw/captured-slack-api-calls"; import { createSlackDestination } from "@/chat/destination"; +import { createSlackConversationWorker } from "@/chat/task-execution/slack-work"; +import { processConversationQueueMessage } from "@/chat/task-execution/vercel-callback"; import { ALL as sandboxEgressProxyALL } from "@/handlers/sandbox-egress-proxy"; import { createMockImageGenerateDeps } from "./fixtures/image-generate"; @@ -1366,6 +1379,7 @@ function buildRuntimeServices( env: HarnessEnvironment, threadRecordsById: Map, observations: RuntimeObservations, + conversationWorkQueue: ConversationWorkQueueTestAdapter, ): JuniorRuntimeServiceOverrides { const replyResults = scenario.overrides?.reply_results ?? []; const replyTexts = scenario.overrides?.reply_texts ?? []; @@ -1520,6 +1534,20 @@ function buildRuntimeServices( } } }, + scheduleAgentContinue: async (request) => { + await scheduleAgentContinue(request, { + queue: conversationWorkQueue, + state: env.stateAdapter, + }); + }, + scheduleSessionCompletedPluginTasks: async (params) => { + const records = await scheduleSessionCompletedPluginTasks(params, { + enqueue: false, + }); + await Promise.all( + records.map((record) => processPluginTask(record.message)), + ); + }, }, visionContext: { listThreadReplies: async ({ channelId, threadTs, targetMessageTs }) => { @@ -1552,6 +1580,8 @@ async function processEvents(args: { scenario: EvalScenario; env: HarnessEnvironment; generateAssistantReply: typeof generateAssistantReply; + getSlackAdapter: () => FakeSlackAdapter; + conversationWorkQueue: ConversationWorkQueueTestAdapter; slackRuntime: ReturnType; getThreadRecord: (fixture: EvalEventThreadFixture) => EvalThreadRecord; readyQueueDeliveries: QueueDelivery[]; @@ -1560,6 +1590,8 @@ async function processEvents(args: { scenario, env, generateAssistantReply, + getSlackAdapter, + conversationWorkQueue, slackRuntime, getThreadRecord, readyQueueDeliveries, @@ -1608,6 +1640,48 @@ async function processEvents(args: { return true; }; + const drainQueuedConversationWork = async (): Promise => { + let processed = 0; + while (conversationWorkQueue.hasQueuedMessages()) { + processed += 1; + if (processed > 10) { + throw new Error("Eval conversation work queue did not drain"); + } + await processConversationQueueMessage( + conversationWorkQueue.takeMessage(), + { + queue: conversationWorkQueue, + run: createSlackConversationWorker({ + getSlackAdapter: () => getSlackAdapter() as unknown as SlackAdapter, + resumeAwaitingContinuation: async (conversationId) => + await resumeAwaitingSlackContinuation(conversationId, { + generateReply: generateAssistantReply, + scheduleAgentContinue: async (request) => { + await scheduleAgentContinue(request, { + queue: conversationWorkQueue, + state: env.stateAdapter, + }); + }, + scheduleSessionCompletedPluginTasks: async (params) => { + const records = await scheduleSessionCompletedPluginTasks( + params, + { enqueue: false }, + ); + await Promise.all( + records.map((record) => processPluginTask(record.message)), + ); + }, + }), + runtime: slackRuntime, + state: env.stateAdapter, + }), + state: env.stateAdapter, + }, + ); + await maybeAutoCompleteAuth(); + } + }; + const enqueueEvent = (event: MentionEvent | SubscribedMessageEvent): void => { const { thread, transcript } = getThreadRecord(event.thread); const message = toIncomingMessage(event) as unknown as Message; @@ -1754,6 +1828,7 @@ async function processEvents(args: { await maybeAutoCompleteAuth(); if (await processNextDelivery()) { await maybeAutoCompleteAuth(); + await drainQueuedConversationWork(); } } @@ -1763,6 +1838,7 @@ async function processEvents(args: { break; } await maybeAutoCompleteAuth(); + await drainQueuedConversationWork(); } } @@ -1884,11 +1960,13 @@ export async function runEvalScenario( return record; }; + const conversationWorkQueue = createConversationWorkQueueTestAdapter(); const services = buildRuntimeServices( scenario, env, threadRecordsById, observations, + conversationWorkQueue, ); const generateEvalAssistantReply = services.replyExecutor?.generateAssistantReply; @@ -1905,6 +1983,8 @@ export async function runEvalScenario( scenario, env, generateAssistantReply: generateEvalAssistantReply, + getSlackAdapter: () => slackAdapter, + conversationWorkQueue, slackRuntime, getThreadRecord, readyQueueDeliveries, diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 807543dbd..c5a09d9a0 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -239,14 +239,14 @@ function existingMemoriesContext(request: ExtractSessionRequest): string { function extractionExamples(): string { return [ "", - "- User says: 'I prefer short status updates.'", - " Output requester memory: canonicalFact='Prefers short status updates.'.", - "- User says: 'For incident writeups, I prefer causes before mitigations.'", - " Output requester memory: canonicalFact='Prefers causes before mitigations in incident writeups.'.", - "- User says: 'In planning docs, open risks go before goals.'", - " Output requester memory: canonicalFact='Prefers open risks before goals in planning docs.'.", - "- User says: 'This thread says deploy runbooks live in Notion.'", - " Output conversation memory: canonicalFact='Deploy runbooks live in Notion.'.", + "- User says: 'I prefer release notes with customer impact first.'", + " Output requester memory: canonicalFact='Prefers customer impact first in release notes.'.", + "- User says: 'For architecture proposals, I prefer tradeoffs before recommendations.'", + " Output requester memory: canonicalFact='Prefers tradeoffs before recommendations in architecture proposals.'.", + "- User says: 'In support handoffs, escalation owners go before timelines.'", + " Output requester memory: canonicalFact='Prefers escalation owners before timelines in support handoffs.'.", + "- User says: 'This channel says staging database refreshes run on Wednesdays.'", + " Output conversation memory: canonicalFact='Staging database refreshes run on Wednesdays.'.", "", ].join("\n"); } @@ -272,10 +272,10 @@ function reviewPrompt(request: CreateMemoryRequest): string { "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels from stored content.", - "- Good requester content: 'Prefers short status updates'. Bad requester content: 'I prefer short status updates'.", - "- Good requester content: 'Prefers short status updates'. Bad requester content: 'The requester prefers short status updates'.", - "- Good requester content: 'Prefers causes before mitigations in incident writeups'. Bad requester content: 'Prefers in my incident writeups, causes before mitigations'.", - "- Good conversation content: 'Deploy runbooks live in Notion'. Bad conversation content: 'This thread says deploy runbooks live in Notion'.", + "- Good requester content: 'Prefers customer impact first in release notes'. Bad requester content: 'I prefer customer impact first in release notes'.", + "- Good requester content: 'Prefers customer impact first in release notes'. Bad requester content: 'The requester prefers customer impact first in release notes'.", + "- Good requester content: 'Prefers tradeoffs before recommendations in architecture proposals'. Bad requester content: 'Prefers in my architecture proposals, tradeoffs before recommendations'.", + "- Good conversation content: 'Staging database refreshes run on Wednesdays'. Bad conversation content: 'This channel says staging database refreshes run on Wednesdays'.", "- Reject third-party personal profile facts, even if they mention a name.", "- Reject vague content such as 'remember this' unless the candidate itself contains the fact.", "- Preserve the requested expiration when one exists; otherwise set expiresAtMs to null.", diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior-memory/src/process-session.ts index 4af6fcac4..dbcd13c88 100644 --- a/packages/junior-memory/src/process-session.ts +++ b/packages/junior-memory/src/process-session.ts @@ -110,11 +110,11 @@ export async function processMemorySession( const store = createMemoryStore(context.db as MemoryDb, runtimeContext, { embedder: context.embedder, }); - const existingMemories = await store.searchMemories({ - limit: 10, - query: userText, - }); const memories = await getTaskMemories(context, async () => { + const existingMemories = await store.searchMemories({ + limit: 10, + query: userText, + }); const agent = createMemoryAgent(context.model); return await agent.extractSessionMemories({ existingMemories: existingMemories.map((memory) => ({ diff --git a/packages/junior/src/handlers/heartbeat.ts b/packages/junior/src/handlers/heartbeat.ts index f586c029d..84850a015 100644 --- a/packages/junior/src/handlers/heartbeat.ts +++ b/packages/junior/src/handlers/heartbeat.ts @@ -1,14 +1,11 @@ import { timingSafeEqual } from "node:crypto"; import { runHeartbeat } from "@/chat/agent-dispatch/heartbeat"; -import { recoverPluginTasks } from "@/chat/plugins/task-runner"; -import type { PluginTaskQueue } from "@/chat/plugins/task-queue"; import type { ConversationWorkQueue } from "@/chat/task-execution/queue"; import { logException } from "@/chat/logging"; import type { WaitUntilFn } from "@/handlers/types"; export interface HeartbeatHandlerOptions { conversationWorkQueue?: ConversationWorkQueue; - pluginTaskQueue?: PluginTaskQueue; } function getHeartbeatSecret(): string | undefined { @@ -45,16 +42,10 @@ export async function GET( const nowMs = Date.now(); waitUntil(() => - Promise.all([ - runHeartbeat({ - conversationWorkQueue: options.conversationWorkQueue, - nowMs, - }), - recoverPluginTasks({ - nowMs, - ...(options.pluginTaskQueue ? { queue: options.pluginTaskQueue } : {}), - }), - ]).catch((error) => { + runHeartbeat({ + conversationWorkQueue: options.conversationWorkQueue, + nowMs, + }).catch((error) => { logException( error, "heartbeat_failed", diff --git a/specs/index.md b/specs/index.md index cec077e72..b888f4dd9 100644 --- a/specs/index.md +++ b/specs/index.md @@ -83,7 +83,7 @@ For chat/agent/Slack execution and response behavior: - `specs/conversation-storage.md` owns SQL-backed queryable conversation record, transcript-storage exclusions, and Vercel-safe migration/backfill behavior. - `specs/plugin-tasks.md` owns plugin-owned durable background task registration, queue dispatch, and completed-session projections. - `specs/plugin-database.md` owns plugin packaged SQL migration discovery/application and the `ctx.db` hook surface. -- `specs/plugin-tasks.md` owns trusted plugin background task registration, durable task records, queue envelopes, leases, retries, and completed-session projections. +- `specs/plugin-tasks.md` owns trusted plugin background task registration, queue envelopes, retries, and completed-session projections. - `specs/plugin-cli.md` owns future plugin-contributed host CLI command discovery, dispatch, admin context, and redaction contracts. - `specs/memory-plugin/index.md` owns the long-term memory plugin's storage, recall, passive learning, tools, visibility, and lifecycle contracts. - `specs/local-agent.md` owns local CLI/local adapter user flows, identity, state, delivery, and verification contracts. From 0722c1c9f79bc3894d876254a1ee44f374565a6b Mon Sep 17 00:00:00 2001 From: David Cramer Date: Thu, 25 Jun 2026 11:19:53 -0700 Subject: [PATCH 18/29] ref(plugins): Rename runtime plugin registration metadata Treat hooks and background tasks as runtime plugin code when rendering Nitro virtual config. Rename the build-time registration metadata so task-only plugins do not travel through a hook-only interface. Co-Authored-By: GPT-5 Codex --- packages/junior/tests/unit/build/nitro-plugin-module.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/junior/tests/unit/build/nitro-plugin-module.test.ts b/packages/junior/tests/unit/build/nitro-plugin-module.test.ts index 01fa2a6f6..840784790 100644 --- a/packages/junior/tests/unit/build/nitro-plugin-module.test.ts +++ b/packages/junior/tests/unit/build/nitro-plugin-module.test.ts @@ -381,7 +381,7 @@ describe("juniorNitro plugin modules", () => { delete globalState.__juniorNitroPluginModuleImports; }); - it("rejects direct plugin sets with runtime registrations because they need a runtime import", () => { + it("rejects direct plugin sets with runtime code because they need a runtime import", () => { const virtual: Record Promise) | string> = {}; const nitro = { hooks: { @@ -442,7 +442,7 @@ describe("juniorNitro plugin modules", () => { }, tasks: { processSession: { - run: async () => {}, + run() {}, }, }, }), From 285c72886b26ec8807e1eb340e598cb5541f1862 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 08:43:30 -0700 Subject: [PATCH 19/29] fix(memory): Clean up rebase artifacts Remove stale shared config docs and duplicated source fields left by the rebase. Also keep plugin prompt hook snippets aligned with the current ctx.db type. Co-Authored-By: GPT-5 Codex --- packages/docs/src/content/docs/reference/config-and-env.md | 2 -- packages/docs/src/content/docs/start-here/quickstart.md | 1 - packages/junior-scheduler/src/plugin.ts | 1 - packages/junior/src/chat/respond.ts | 3 --- .../junior/tests/integration/advisor/advisor-tool.test.ts | 1 - .../junior/tests/integration/oauth-resume-slack.test.ts | 7 ------- packages/junior/tests/unit/handlers/oauth-resume.test.ts | 5 ----- specs/index.md | 1 - specs/plugin-prompt-hooks.md | 4 ++-- 9 files changed, 2 insertions(+), 23 deletions(-) diff --git a/packages/docs/src/content/docs/reference/config-and-env.md b/packages/docs/src/content/docs/reference/config-and-env.md index ee48557b1..58cf54753 100644 --- a/packages/docs/src/content/docs/reference/config-and-env.md +++ b/packages/docs/src/content/docs/reference/config-and-env.md @@ -25,13 +25,11 @@ related: | `JUNIOR_SLASH_COMMAND` | No | Slack slash command for account-management flows. Defaults to `/jr`; the Slack app command must match this value. | | `AI_MODEL` | No | Primary model selection override for main agent runs. Defaults to `openai/gpt-5.4`; Junior chooses the reasoning effort per run automatically. | | `AI_FAST_MODEL` | No | Faster model for lightweight tasks and routing/classification passes before the main turn begins. Defaults to `openai/gpt-5.4-mini`. | -| `AI_MEMORY_MODEL` | No | Memory plugin extraction/review model override. When unset, memory uses the host structured-model default. | | `AI_EMBEDDING_MODEL` | No | Embedding model for plugin-owned vector retrieval. Defaults to `openai/text-embedding-3-small`; memory v1 stores fixed 1536-dimensional vectors. | | `AI_VISION_MODEL` | No | Dedicated image-understanding model; unset disables vision features. | | `AI_WEB_SEARCH_MODEL` | No | Override for the `webSearch` tool model. Defaults to `openai/gpt-5.4`; does not fall through to `AI_MODEL`. | | `JUNIOR_BASE_URL` | No | Canonical base URL for callback/auth URL generation. | | `JUNIOR_STATE_KEY_PREFIX` | No | Optional namespace prepended to all state-adapter keys, locks, and queues. Use separate prefixes when sharing one Redis database across environments. | -| `JUNIOR_PLUGIN_TASK_QUEUE_TOPIC` | No | Vercel Queue topic for plugin background task wakeups. Defaults to `junior_plugin_tasks`. | | `CRON_SECRET` or `JUNIOR_SCHEDULER_SECRET` | Conditional | Bearer token for the internal heartbeat route; use `CRON_SECRET` with Vercel Cron, or `JUNIOR_SCHEDULER_SECRET` for a non-Vercel heartbeat caller. | | `JUNIOR_TIMEZONE` | No | Default IANA timezone for scheduler authoring when the scheduler plugin is enabled. Defaults to `America/Los_Angeles`. | | `AI_GATEWAY_API_KEY` | No | AI gateway auth if used in your setup. | diff --git a/packages/docs/src/content/docs/start-here/quickstart.md b/packages/docs/src/content/docs/start-here/quickstart.md index 22d18a455..dd529b1e8 100644 --- a/packages/docs/src/content/docs/start-here/quickstart.md +++ b/packages/docs/src/content/docs/start-here/quickstart.md @@ -66,7 +66,6 @@ Set these values before running real turns: | `JUNIOR_SLASH_COMMAND` | No | Slack slash command name. Defaults to `/jr`. | | `AI_MODEL` | No | Primary assistant model override. | | `AI_FAST_MODEL` | No | Lightweight routing/classification model override. | -| `AI_MEMORY_MODEL` | No | Memory plugin extraction/review model override. | | `AI_EMBEDDING_MODEL` | No | Embedding model override for plugin vector retrieval. | | `AI_VISION_MODEL` | No | Enables image understanding when set. | | `AI_WEB_SEARCH_MODEL` | No | Search model override. | diff --git a/packages/junior-scheduler/src/plugin.ts b/packages/junior-scheduler/src/plugin.ts index 607ed9d3b..88abbdb55 100644 --- a/packages/junior-scheduler/src/plugin.ts +++ b/packages/junior-scheduler/src/plugin.ts @@ -1,7 +1,6 @@ import { createSlackSource, defineJuniorPlugin, - createSlackSource, type Dispatch, type PluginToolDefinition, type PluginOperationalReportContent, diff --git a/packages/junior/src/chat/respond.ts b/packages/junior/src/chat/respond.ts index 47078652a..7b35ba817 100644 --- a/packages/junior/src/chat/respond.ts +++ b/packages/junior/src/chat/respond.ts @@ -1770,7 +1770,6 @@ export async function generateAssistantReply( currentUsage: turnUsage, messages: timeoutResumeMessages, errorMessage: error.message, - source: runSource, loadedSkillNames: loadedSkillNamesForResume, logContext: sessionRecordLogContext, requester, @@ -1800,7 +1799,6 @@ export async function generateAssistantReply( currentUsage: turnUsage, messages: timeoutResumeMessages, errorMessage: error instanceof Error ? error.message : String(error), - source: runSource, loadedSkillNames: loadedSkillNamesForResume, logContext: sessionRecordLogContext, requester, @@ -1853,7 +1851,6 @@ export async function generateAssistantReply( currentUsage: turnUsage, messages: timeoutResumeMessages, errorMessage: error.message, - source: runSource, loadedSkillNames: loadedSkillNamesForResume, logContext: sessionRecordLogContext, requester, diff --git a/packages/junior/tests/integration/advisor/advisor-tool.test.ts b/packages/junior/tests/integration/advisor/advisor-tool.test.ts index fc19d7828..9652cc185 100644 --- a/packages/junior/tests/integration/advisor/advisor-tool.test.ts +++ b/packages/junior/tests/integration/advisor/advisor-tool.test.ts @@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest"; import type { AgentTool, StreamFn } from "@earendil-works/pi-agent-core"; import { createLocalSource } from "@sentry/junior-plugin-api"; import { Type } from "@sinclair/typebox"; -import { createLocalSource } from "@sentry/junior-plugin-api"; import type { AdvisorConfig } from "@/chat/config"; import type { PiMessage } from "@/chat/pi/messages"; import { createTools } from "@/chat/tools"; diff --git a/packages/junior/tests/integration/oauth-resume-slack.test.ts b/packages/junior/tests/integration/oauth-resume-slack.test.ts index 241723940..aeb2ede85 100644 --- a/packages/junior/tests/integration/oauth-resume-slack.test.ts +++ b/packages/junior/tests/integration/oauth-resume-slack.test.ts @@ -70,7 +70,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.001"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.001"), }, generateReply: async () => ({ @@ -169,7 +168,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.007"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.007"), correlation: { conversationId: "conversation-1", turnId: "turn-1", @@ -233,7 +231,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.002"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.002"), }, generateReply: async () => ({ @@ -274,7 +271,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.003"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.003"), }, generateReply: async () => ({ @@ -312,7 +308,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.006"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.006"), }, generateReply: async () => ({ @@ -351,7 +346,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.004"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.004"), }, generateReply: async () => ({ @@ -411,7 +405,6 @@ describe("oauth resume slack integration", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.005"), requester: { platform: "slack", teamId: "T123", userId: "U123" }, - source: testSlackSource("1700000000.005"), }, generateReply: async () => ({ diff --git a/packages/junior/tests/unit/handlers/oauth-resume.test.ts b/packages/junior/tests/unit/handlers/oauth-resume.test.ts index 6bd7fc5c3..1449a0831 100644 --- a/packages/junior/tests/unit/handlers/oauth-resume.test.ts +++ b/packages/junior/tests/unit/handlers/oauth-resume.test.ts @@ -117,7 +117,6 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0001"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, - source: testSlackSource("1700000000.0001"), }, generateReply: () => new Promise(() => {}), replyTimeoutMs: 10, @@ -161,7 +160,6 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0004"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, - source: testSlackSource("1700000000.0004"), }, generateReply: async () => { throw new Error("resume failed"); @@ -203,7 +201,6 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0005"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, - source: testSlackSource("1700000000.0005"), }, generateReply: async () => ({ text: "Final resumed answer", @@ -308,7 +305,6 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0002"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, - source: testSlackSource("1700000000.0002"), }, generateReply: async () => { throw new RetryableTurnError("agent_continue", "timed out again", { @@ -339,7 +335,6 @@ describe("resumeAuthorizedRequest", () => { destination: TEST_SLACK_DESTINATION, source: testSlackSource("1700000000.0003"), requester: { platform: "slack", teamId: "T-test", userId: "U-test" }, - source: testSlackSource("1700000000.0003"), }, generateReply: async () => { throw new RetryableTurnError("agent_continue", "timed out again", { diff --git a/specs/index.md b/specs/index.md index b888f4dd9..92d66ef59 100644 --- a/specs/index.md +++ b/specs/index.md @@ -83,7 +83,6 @@ For chat/agent/Slack execution and response behavior: - `specs/conversation-storage.md` owns SQL-backed queryable conversation record, transcript-storage exclusions, and Vercel-safe migration/backfill behavior. - `specs/plugin-tasks.md` owns plugin-owned durable background task registration, queue dispatch, and completed-session projections. - `specs/plugin-database.md` owns plugin packaged SQL migration discovery/application and the `ctx.db` hook surface. -- `specs/plugin-tasks.md` owns trusted plugin background task registration, queue envelopes, retries, and completed-session projections. - `specs/plugin-cli.md` owns future plugin-contributed host CLI command discovery, dispatch, admin context, and redaction contracts. - `specs/memory-plugin/index.md` owns the long-term memory plugin's storage, recall, passive learning, tools, visibility, and lifecycle contracts. - `specs/local-agent.md` owns local CLI/local adapter user flows, identity, state, delivery, and verification contracts. diff --git a/specs/plugin-prompt-hooks.md b/specs/plugin-prompt-hooks.md index b0baecb9c..214535a79 100644 --- a/specs/plugin-prompt-hooks.md +++ b/specs/plugin-prompt-hooks.md @@ -87,7 +87,7 @@ Rules: ```ts interface SystemPromptContext { - db: object; + db: unknown; log: PluginLogger; platform: Platform; plugin: PluginMetadata; @@ -139,7 +139,7 @@ Rules: ```ts interface UserPromptContext { conversationId?: string; - db: object; + db: unknown; destination: Destination; embedder: PluginEmbedder; log: PluginLogger; From bb18d8a16bb458dffa442ea56cb0c23c72342f1f Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 09:50:15 -0700 Subject: [PATCH 20/29] fix(plugin): Preserve requester context for tasks Store the runtime requester on completed session records and require plugin task sessions to load that persisted context instead of reconstructing it in the task runner. Update the eval harness and generated API docs for the task context contract, and remove the obsolete stored Slack requester reconstruction path. Co-Authored-By: GPT-5 Codex --- .../reference/api/functions/juniorNitro.md | 2 +- .../api/interfaces/ConversationFeed.md | 8 +- .../api/interfaces/ConversationReport.md | 10 +- .../api/interfaces/ConversationRunReport.md | 48 +- .../api/interfaces/ConversationStatsItem.md | 18 +- .../api/interfaces/ConversationStatsReport.md | 34 +- .../interfaces/ConversationSummaryReport.md | 36 +- .../api/interfaces/ConversationUsage.md | 12 +- .../api/interfaces/PluginTaskContext.md | 34 +- .../api/interfaces/PluginTaskDefinition.md | 4 +- .../api/interfaces/RequesterIdentity.md | 10 +- .../api/interfaces/TranscriptMessage.md | 8 +- .../api/interfaces/TranscriptPart.md | 38 +- .../type-aliases/ConversationReportStatus.md | 2 +- .../api/type-aliases/ConversationSurface.md | 2 +- .../reference/api/type-aliases/PluginTasks.md | 2 +- .../api/type-aliases/TranscriptPartType.md | 2 +- .../api/type-aliases/TranscriptRole.md | 2 +- .../variables/pluginSessionContextSchema.md | 2 +- packages/junior-evals/package.json | 1 + packages/junior-evals/src/behavior-harness.ts | 21 +- packages/junior-memory/src/tools.ts | 10 +- packages/junior-memory/tests/storage.test.ts | 51 ++ packages/junior-plugin-api/src/tasks.ts | 2 +- .../junior/src/chat/plugins/task-runner.ts | 30 +- packages/junior/src/chat/requester.ts | 66 +-- packages/junior/src/chat/respond.ts | 14 +- .../src/chat/runtime/agent-continue-runner.ts | 5 +- .../junior/src/chat/runtime/reply-executor.ts | 20 +- .../src/chat/services/turn-session-record.ts | 13 +- .../junior/src/chat/state/turn-session.ts | 33 +- .../junior/src/handlers/mcp-oauth-callback.ts | 7 +- .../junior/src/handlers/oauth-callback.ts | 7 +- .../junior/src/reporting/conversations.ts | 19 +- .../component/plugins/plugin-tasks.test.ts | 24 +- .../runtime/agent-continue-runner.test.ts | 39 +- .../services/turn-session-record.test.ts | 24 +- .../integration/agent-continue-slack.test.ts | 24 +- .../integration/dashboard-reporting.test.ts | 35 +- .../mcp-oauth-callback-slack.test.ts | 40 +- .../integration/oauth-callback-slack.test.ts | 24 +- .../tests/unit/services/requester.test.ts | 81 --- pnpm-lock.yaml | 536 +----------------- specs/memory-plugin/extraction.md | 3 +- 44 files changed, 460 insertions(+), 943 deletions(-) diff --git a/packages/docs/src/content/docs/reference/api/functions/juniorNitro.md b/packages/docs/src/content/docs/reference/api/functions/juniorNitro.md index 672deed23..b791a7b0f 100644 --- a/packages/docs/src/content/docs/reference/api/functions/juniorNitro.md +++ b/packages/docs/src/content/docs/reference/api/functions/juniorNitro.md @@ -7,7 +7,7 @@ title: "juniorNitro" > **juniorNitro**(`options?`): `object` -Defined in: [junior/src/nitro.ts:213](https://github.com/getsentry/junior/blob/main/packages/junior/src/nitro.ts#L213) +Defined in: [junior/src/nitro.ts:208](https://github.com/getsentry/junior/blob/main/packages/junior/src/nitro.ts#L208) Nitro module that configures deployment wiring and copies app/plugin content into the Vercel build output. diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationFeed.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationFeed.md index 21c9988fa..04f31e4fd 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationFeed.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationFeed.md @@ -5,7 +5,7 @@ prev: false title: "ConversationFeed" --- -Defined in: [junior/src/reporting/conversations.ts:181](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L181) +Defined in: [junior/src/reporting/conversations.ts:180](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L180) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:181](https://github.com/getse > **generatedAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:184](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L184) +Defined in: [junior/src/reporting/conversations.ts:183](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L183) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:184](https://github.com/getse > **sessions**: [`ConversationSummaryReport`](/reference/api/interfaces/conversationsummaryreport/)[] -Defined in: [junior/src/reporting/conversations.ts:182](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L182) +Defined in: [junior/src/reporting/conversations.ts:181](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L181) --- @@ -29,4 +29,4 @@ Defined in: [junior/src/reporting/conversations.ts:182](https://github.com/getse > **source**: `"conversation_index"` -Defined in: [junior/src/reporting/conversations.ts:183](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L183) +Defined in: [junior/src/reporting/conversations.ts:182](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L182) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationReport.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationReport.md index a22635fb9..68b8da50b 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationReport.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationReport.md @@ -5,7 +5,7 @@ prev: false title: "ConversationReport" --- -Defined in: [junior/src/reporting/conversations.ts:173](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L173) +Defined in: [junior/src/reporting/conversations.ts:172](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L172) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:173](https://github.com/getse > **conversationId**: `string` -Defined in: [junior/src/reporting/conversations.ts:174](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L174) +Defined in: [junior/src/reporting/conversations.ts:173](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L173) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:174](https://github.com/getse > **displayTitle**: `string` -Defined in: [junior/src/reporting/conversations.ts:176](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L176) +Defined in: [junior/src/reporting/conversations.ts:175](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L175) Always-populated display title, computed the same way as per-run reports. @@ -31,7 +31,7 @@ Always-populated display title, computed the same way as per-run reports. > **generatedAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:177](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L177) +Defined in: [junior/src/reporting/conversations.ts:176](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L176) --- @@ -39,4 +39,4 @@ Defined in: [junior/src/reporting/conversations.ts:177](https://github.com/getse > **runs**: [`ConversationRunReport`](/reference/api/interfaces/conversationrunreport/)[] -Defined in: [junior/src/reporting/conversations.ts:178](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L178) +Defined in: [junior/src/reporting/conversations.ts:177](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L177) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationRunReport.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationRunReport.md index 5f6c84fe8..759fdc904 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationRunReport.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationRunReport.md @@ -5,7 +5,7 @@ prev: false title: "ConversationRunReport" --- -Defined in: [junior/src/reporting/conversations.ts:164](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L164) +Defined in: [junior/src/reporting/conversations.ts:163](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L163) ## Extends @@ -17,7 +17,7 @@ Defined in: [junior/src/reporting/conversations.ts:164](https://github.com/getse > `optional` **channel?**: `string` -Defined in: [junior/src/reporting/conversations.ts:115](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L115) +Defined in: [junior/src/reporting/conversations.ts:114](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L114) #### Inherited from @@ -29,7 +29,7 @@ Defined in: [junior/src/reporting/conversations.ts:115](https://github.com/getse > `optional` **channelName?**: `string` -Defined in: [junior/src/reporting/conversations.ts:116](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L116) +Defined in: [junior/src/reporting/conversations.ts:115](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L115) #### Inherited from @@ -41,7 +41,7 @@ Defined in: [junior/src/reporting/conversations.ts:116](https://github.com/getse > `optional` **completedAt?**: `string` -Defined in: [junior/src/reporting/conversations.ts:112](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L112) +Defined in: [junior/src/reporting/conversations.ts:111](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L111) #### Inherited from @@ -53,7 +53,7 @@ Defined in: [junior/src/reporting/conversations.ts:112](https://github.com/getse > **conversationId**: `string` -Defined in: [junior/src/reporting/conversations.ts:106](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L106) +Defined in: [junior/src/reporting/conversations.ts:105](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L105) #### Inherited from @@ -65,7 +65,7 @@ Defined in: [junior/src/reporting/conversations.ts:106](https://github.com/getse > **cumulativeDurationMs**: `number` -Defined in: [junior/src/reporting/conversations.ts:104](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L104) +Defined in: [junior/src/reporting/conversations.ts:103](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L103) #### Inherited from @@ -77,7 +77,7 @@ Defined in: [junior/src/reporting/conversations.ts:104](https://github.com/getse > `optional` **cumulativeUsage?**: [`ConversationUsage`](/reference/api/interfaces/conversationusage/) -Defined in: [junior/src/reporting/conversations.ts:105](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L105) +Defined in: [junior/src/reporting/conversations.ts:104](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L104) #### Inherited from @@ -89,7 +89,7 @@ Defined in: [junior/src/reporting/conversations.ts:105](https://github.com/getse > **displayTitle**: `string` -Defined in: [junior/src/reporting/conversations.ts:103](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L103) +Defined in: [junior/src/reporting/conversations.ts:102](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L102) Always-populated display title, with privacy redaction applied first. @@ -103,7 +103,7 @@ Always-populated display title, with privacy redaction applied first. > **id**: `string` -Defined in: [junior/src/reporting/conversations.ts:107](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L107) +Defined in: [junior/src/reporting/conversations.ts:106](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L106) #### Inherited from @@ -115,7 +115,7 @@ Defined in: [junior/src/reporting/conversations.ts:107](https://github.com/getse > **lastProgressAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:111](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L111) +Defined in: [junior/src/reporting/conversations.ts:110](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L110) #### Inherited from @@ -127,7 +127,7 @@ Defined in: [junior/src/reporting/conversations.ts:111](https://github.com/getse > **lastSeenAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:110](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L110) +Defined in: [junior/src/reporting/conversations.ts:109](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L109) #### Inherited from @@ -139,7 +139,7 @@ Defined in: [junior/src/reporting/conversations.ts:110](https://github.com/getse > `optional` **requesterIdentity?**: [`RequesterIdentity`](/reference/api/interfaces/requesteridentity/) -Defined in: [junior/src/reporting/conversations.ts:114](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L114) +Defined in: [junior/src/reporting/conversations.ts:113](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L113) #### Inherited from @@ -151,7 +151,7 @@ Defined in: [junior/src/reporting/conversations.ts:114](https://github.com/getse > `optional` **sentryConversationUrl?**: `string` -Defined in: [junior/src/reporting/conversations.ts:117](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L117) +Defined in: [junior/src/reporting/conversations.ts:116](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L116) #### Inherited from @@ -163,7 +163,7 @@ Defined in: [junior/src/reporting/conversations.ts:117](https://github.com/getse > `optional` **sentryTraceUrl?**: `string` -Defined in: [junior/src/reporting/conversations.ts:118](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L118) +Defined in: [junior/src/reporting/conversations.ts:117](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L117) #### Inherited from @@ -175,7 +175,7 @@ Defined in: [junior/src/reporting/conversations.ts:118](https://github.com/getse > **startedAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:109](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L109) +Defined in: [junior/src/reporting/conversations.ts:108](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L108) #### Inherited from @@ -187,7 +187,7 @@ Defined in: [junior/src/reporting/conversations.ts:109](https://github.com/getse > **status**: [`ConversationReportStatus`](/reference/api/type-aliases/conversationreportstatus/) -Defined in: [junior/src/reporting/conversations.ts:108](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L108) +Defined in: [junior/src/reporting/conversations.ts:107](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L107) #### Inherited from @@ -199,7 +199,7 @@ Defined in: [junior/src/reporting/conversations.ts:108](https://github.com/getse > **surface**: [`ConversationSurface`](/reference/api/type-aliases/conversationsurface/) -Defined in: [junior/src/reporting/conversations.ts:113](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L113) +Defined in: [junior/src/reporting/conversations.ts:112](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L112) #### Inherited from @@ -211,7 +211,7 @@ Defined in: [junior/src/reporting/conversations.ts:113](https://github.com/getse > `optional` **traceId?**: `string` -Defined in: [junior/src/reporting/conversations.ts:119](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L119) +Defined in: [junior/src/reporting/conversations.ts:118](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L118) #### Inherited from @@ -223,7 +223,7 @@ Defined in: [junior/src/reporting/conversations.ts:119](https://github.com/getse > **transcript**: [`TranscriptMessage`](/reference/api/interfaces/transcriptmessage/)[] -Defined in: [junior/src/reporting/conversations.ts:170](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L170) +Defined in: [junior/src/reporting/conversations.ts:169](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L169) --- @@ -231,7 +231,7 @@ Defined in: [junior/src/reporting/conversations.ts:170](https://github.com/getse > **transcriptAvailable**: `boolean` -Defined in: [junior/src/reporting/conversations.ts:165](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L165) +Defined in: [junior/src/reporting/conversations.ts:164](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L164) --- @@ -239,7 +239,7 @@ Defined in: [junior/src/reporting/conversations.ts:165](https://github.com/getse > `optional` **transcriptMessageCount?**: `number` -Defined in: [junior/src/reporting/conversations.ts:167](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L167) +Defined in: [junior/src/reporting/conversations.ts:166](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L166) --- @@ -247,7 +247,7 @@ Defined in: [junior/src/reporting/conversations.ts:167](https://github.com/getse > `optional` **transcriptMetadata?**: [`TranscriptMessage`](/reference/api/interfaces/transcriptmessage/)[] -Defined in: [junior/src/reporting/conversations.ts:166](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L166) +Defined in: [junior/src/reporting/conversations.ts:165](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L165) --- @@ -255,7 +255,7 @@ Defined in: [junior/src/reporting/conversations.ts:166](https://github.com/getse > `optional` **transcriptRedacted?**: `boolean` -Defined in: [junior/src/reporting/conversations.ts:168](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L168) +Defined in: [junior/src/reporting/conversations.ts:167](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L167) --- @@ -263,4 +263,4 @@ Defined in: [junior/src/reporting/conversations.ts:168](https://github.com/getse > `optional` **transcriptRedactionReason?**: `"non_public_conversation"` -Defined in: [junior/src/reporting/conversations.ts:169](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L169) +Defined in: [junior/src/reporting/conversations.ts:168](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L168) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsItem.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsItem.md index 590f0735c..4e75fae91 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsItem.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsItem.md @@ -5,7 +5,7 @@ prev: false title: "ConversationStatsItem" --- -Defined in: [junior/src/reporting/conversations.ts:187](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L187) +Defined in: [junior/src/reporting/conversations.ts:186](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L186) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:187](https://github.com/getse > **active**: `number` -Defined in: [junior/src/reporting/conversations.ts:188](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L188) +Defined in: [junior/src/reporting/conversations.ts:187](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L187) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:188](https://github.com/getse > **conversations**: `number` -Defined in: [junior/src/reporting/conversations.ts:189](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L189) +Defined in: [junior/src/reporting/conversations.ts:188](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L188) --- @@ -29,7 +29,7 @@ Defined in: [junior/src/reporting/conversations.ts:189](https://github.com/getse > **durationMs**: `number` -Defined in: [junior/src/reporting/conversations.ts:190](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L190) +Defined in: [junior/src/reporting/conversations.ts:189](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L189) --- @@ -37,7 +37,7 @@ Defined in: [junior/src/reporting/conversations.ts:190](https://github.com/getse > **failed**: `number` -Defined in: [junior/src/reporting/conversations.ts:191](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L191) +Defined in: [junior/src/reporting/conversations.ts:190](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L190) --- @@ -45,7 +45,7 @@ Defined in: [junior/src/reporting/conversations.ts:191](https://github.com/getse > **hung**: `number` -Defined in: [junior/src/reporting/conversations.ts:192](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L192) +Defined in: [junior/src/reporting/conversations.ts:191](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L191) --- @@ -53,7 +53,7 @@ Defined in: [junior/src/reporting/conversations.ts:192](https://github.com/getse > **label**: `string` -Defined in: [junior/src/reporting/conversations.ts:193](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L193) +Defined in: [junior/src/reporting/conversations.ts:192](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L192) --- @@ -61,7 +61,7 @@ Defined in: [junior/src/reporting/conversations.ts:193](https://github.com/getse > **runs**: `number` -Defined in: [junior/src/reporting/conversations.ts:194](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L194) +Defined in: [junior/src/reporting/conversations.ts:193](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L193) --- @@ -69,4 +69,4 @@ Defined in: [junior/src/reporting/conversations.ts:194](https://github.com/getse > `optional` **tokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:195](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L195) +Defined in: [junior/src/reporting/conversations.ts:194](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L194) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsReport.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsReport.md index 39d0c0520..13ef55cf3 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsReport.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationStatsReport.md @@ -5,7 +5,7 @@ prev: false title: "ConversationStatsReport" --- -Defined in: [junior/src/reporting/conversations.ts:198](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L198) +Defined in: [junior/src/reporting/conversations.ts:197](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L197) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:198](https://github.com/getse > **active**: `number` -Defined in: [junior/src/reporting/conversations.ts:199](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L199) +Defined in: [junior/src/reporting/conversations.ts:198](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L198) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:199](https://github.com/getse > **conversations**: `number` -Defined in: [junior/src/reporting/conversations.ts:200](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L200) +Defined in: [junior/src/reporting/conversations.ts:199](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L199) --- @@ -29,7 +29,7 @@ Defined in: [junior/src/reporting/conversations.ts:200](https://github.com/getse > **durationMs**: `number` -Defined in: [junior/src/reporting/conversations.ts:201](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L201) +Defined in: [junior/src/reporting/conversations.ts:200](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L200) --- @@ -37,7 +37,7 @@ Defined in: [junior/src/reporting/conversations.ts:201](https://github.com/getse > **failed**: `number` -Defined in: [junior/src/reporting/conversations.ts:202](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L202) +Defined in: [junior/src/reporting/conversations.ts:201](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L201) --- @@ -45,7 +45,7 @@ Defined in: [junior/src/reporting/conversations.ts:202](https://github.com/getse > **generatedAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:203](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L203) +Defined in: [junior/src/reporting/conversations.ts:202](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L202) --- @@ -53,7 +53,7 @@ Defined in: [junior/src/reporting/conversations.ts:203](https://github.com/getse > **hung**: `number` -Defined in: [junior/src/reporting/conversations.ts:204](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L204) +Defined in: [junior/src/reporting/conversations.ts:203](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L203) --- @@ -61,7 +61,7 @@ Defined in: [junior/src/reporting/conversations.ts:204](https://github.com/getse > **locations**: [`ConversationStatsItem`](/reference/api/interfaces/conversationstatsitem/)[] -Defined in: [junior/src/reporting/conversations.ts:205](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L205) +Defined in: [junior/src/reporting/conversations.ts:204](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L204) --- @@ -69,7 +69,7 @@ Defined in: [junior/src/reporting/conversations.ts:205](https://github.com/getse > **requesters**: [`ConversationStatsItem`](/reference/api/interfaces/conversationstatsitem/)[] -Defined in: [junior/src/reporting/conversations.ts:206](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L206) +Defined in: [junior/src/reporting/conversations.ts:205](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L205) --- @@ -77,7 +77,7 @@ Defined in: [junior/src/reporting/conversations.ts:206](https://github.com/getse > **runs**: `number` -Defined in: [junior/src/reporting/conversations.ts:212](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L212) +Defined in: [junior/src/reporting/conversations.ts:211](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L211) --- @@ -85,7 +85,7 @@ Defined in: [junior/src/reporting/conversations.ts:212](https://github.com/getse > **sampleLimit**: `number` -Defined in: [junior/src/reporting/conversations.ts:207](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L207) +Defined in: [junior/src/reporting/conversations.ts:206](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L206) --- @@ -93,7 +93,7 @@ Defined in: [junior/src/reporting/conversations.ts:207](https://github.com/getse > **sampleSize**: `number` -Defined in: [junior/src/reporting/conversations.ts:208](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L208) +Defined in: [junior/src/reporting/conversations.ts:207](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L207) --- @@ -101,7 +101,7 @@ Defined in: [junior/src/reporting/conversations.ts:208](https://github.com/getse > **source**: `"conversation_index"` -Defined in: [junior/src/reporting/conversations.ts:209](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L209) +Defined in: [junior/src/reporting/conversations.ts:208](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L208) --- @@ -109,7 +109,7 @@ Defined in: [junior/src/reporting/conversations.ts:209](https://github.com/getse > `optional` **tokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:210](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L210) +Defined in: [junior/src/reporting/conversations.ts:209](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L209) --- @@ -117,7 +117,7 @@ Defined in: [junior/src/reporting/conversations.ts:210](https://github.com/getse > **truncated**: `boolean` -Defined in: [junior/src/reporting/conversations.ts:211](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L211) +Defined in: [junior/src/reporting/conversations.ts:210](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L210) --- @@ -125,7 +125,7 @@ Defined in: [junior/src/reporting/conversations.ts:211](https://github.com/getse > **windowEnd**: `string` -Defined in: [junior/src/reporting/conversations.ts:213](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L213) +Defined in: [junior/src/reporting/conversations.ts:212](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L212) --- @@ -133,4 +133,4 @@ Defined in: [junior/src/reporting/conversations.ts:213](https://github.com/getse > **windowStart**: `string` -Defined in: [junior/src/reporting/conversations.ts:214](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L214) +Defined in: [junior/src/reporting/conversations.ts:213](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L213) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationSummaryReport.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationSummaryReport.md index ee2ef536f..abd008286 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationSummaryReport.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationSummaryReport.md @@ -5,7 +5,7 @@ prev: false title: "ConversationSummaryReport" --- -Defined in: [junior/src/reporting/conversations.ts:101](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L101) +Defined in: [junior/src/reporting/conversations.ts:100](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L100) ## Extended by @@ -17,7 +17,7 @@ Defined in: [junior/src/reporting/conversations.ts:101](https://github.com/getse > `optional` **channel?**: `string` -Defined in: [junior/src/reporting/conversations.ts:115](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L115) +Defined in: [junior/src/reporting/conversations.ts:114](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L114) --- @@ -25,7 +25,7 @@ Defined in: [junior/src/reporting/conversations.ts:115](https://github.com/getse > `optional` **channelName?**: `string` -Defined in: [junior/src/reporting/conversations.ts:116](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L116) +Defined in: [junior/src/reporting/conversations.ts:115](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L115) --- @@ -33,7 +33,7 @@ Defined in: [junior/src/reporting/conversations.ts:116](https://github.com/getse > `optional` **completedAt?**: `string` -Defined in: [junior/src/reporting/conversations.ts:112](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L112) +Defined in: [junior/src/reporting/conversations.ts:111](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L111) --- @@ -41,7 +41,7 @@ Defined in: [junior/src/reporting/conversations.ts:112](https://github.com/getse > **conversationId**: `string` -Defined in: [junior/src/reporting/conversations.ts:106](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L106) +Defined in: [junior/src/reporting/conversations.ts:105](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L105) --- @@ -49,7 +49,7 @@ Defined in: [junior/src/reporting/conversations.ts:106](https://github.com/getse > **cumulativeDurationMs**: `number` -Defined in: [junior/src/reporting/conversations.ts:104](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L104) +Defined in: [junior/src/reporting/conversations.ts:103](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L103) --- @@ -57,7 +57,7 @@ Defined in: [junior/src/reporting/conversations.ts:104](https://github.com/getse > `optional` **cumulativeUsage?**: [`ConversationUsage`](/reference/api/interfaces/conversationusage/) -Defined in: [junior/src/reporting/conversations.ts:105](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L105) +Defined in: [junior/src/reporting/conversations.ts:104](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L104) --- @@ -65,7 +65,7 @@ Defined in: [junior/src/reporting/conversations.ts:105](https://github.com/getse > **displayTitle**: `string` -Defined in: [junior/src/reporting/conversations.ts:103](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L103) +Defined in: [junior/src/reporting/conversations.ts:102](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L102) Always-populated display title, with privacy redaction applied first. @@ -75,7 +75,7 @@ Always-populated display title, with privacy redaction applied first. > **id**: `string` -Defined in: [junior/src/reporting/conversations.ts:107](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L107) +Defined in: [junior/src/reporting/conversations.ts:106](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L106) --- @@ -83,7 +83,7 @@ Defined in: [junior/src/reporting/conversations.ts:107](https://github.com/getse > **lastProgressAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:111](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L111) +Defined in: [junior/src/reporting/conversations.ts:110](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L110) --- @@ -91,7 +91,7 @@ Defined in: [junior/src/reporting/conversations.ts:111](https://github.com/getse > **lastSeenAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:110](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L110) +Defined in: [junior/src/reporting/conversations.ts:109](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L109) --- @@ -99,7 +99,7 @@ Defined in: [junior/src/reporting/conversations.ts:110](https://github.com/getse > `optional` **requesterIdentity?**: [`RequesterIdentity`](/reference/api/interfaces/requesteridentity/) -Defined in: [junior/src/reporting/conversations.ts:114](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L114) +Defined in: [junior/src/reporting/conversations.ts:113](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L113) --- @@ -107,7 +107,7 @@ Defined in: [junior/src/reporting/conversations.ts:114](https://github.com/getse > `optional` **sentryConversationUrl?**: `string` -Defined in: [junior/src/reporting/conversations.ts:117](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L117) +Defined in: [junior/src/reporting/conversations.ts:116](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L116) --- @@ -115,7 +115,7 @@ Defined in: [junior/src/reporting/conversations.ts:117](https://github.com/getse > `optional` **sentryTraceUrl?**: `string` -Defined in: [junior/src/reporting/conversations.ts:118](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L118) +Defined in: [junior/src/reporting/conversations.ts:117](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L117) --- @@ -123,7 +123,7 @@ Defined in: [junior/src/reporting/conversations.ts:118](https://github.com/getse > **startedAt**: `string` -Defined in: [junior/src/reporting/conversations.ts:109](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L109) +Defined in: [junior/src/reporting/conversations.ts:108](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L108) --- @@ -131,7 +131,7 @@ Defined in: [junior/src/reporting/conversations.ts:109](https://github.com/getse > **status**: [`ConversationReportStatus`](/reference/api/type-aliases/conversationreportstatus/) -Defined in: [junior/src/reporting/conversations.ts:108](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L108) +Defined in: [junior/src/reporting/conversations.ts:107](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L107) --- @@ -139,7 +139,7 @@ Defined in: [junior/src/reporting/conversations.ts:108](https://github.com/getse > **surface**: [`ConversationSurface`](/reference/api/type-aliases/conversationsurface/) -Defined in: [junior/src/reporting/conversations.ts:113](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L113) +Defined in: [junior/src/reporting/conversations.ts:112](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L112) --- @@ -147,4 +147,4 @@ Defined in: [junior/src/reporting/conversations.ts:113](https://github.com/getse > `optional` **traceId?**: `string` -Defined in: [junior/src/reporting/conversations.ts:119](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L119) +Defined in: [junior/src/reporting/conversations.ts:118](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L118) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/ConversationUsage.md b/packages/docs/src/content/docs/reference/api/interfaces/ConversationUsage.md index 677efcfa6..8a57b76ff 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/ConversationUsage.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/ConversationUsage.md @@ -5,7 +5,7 @@ prev: false title: "ConversationUsage" --- -Defined in: [junior/src/reporting/conversations.ts:86](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L86) +Defined in: [junior/src/reporting/conversations.ts:85](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L85) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:86](https://github.com/getsen > `optional` **cacheCreationTokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:90](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L90) +Defined in: [junior/src/reporting/conversations.ts:89](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L89) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:90](https://github.com/getsen > `optional` **cachedInputTokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:89](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L89) +Defined in: [junior/src/reporting/conversations.ts:88](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L88) --- @@ -29,7 +29,7 @@ Defined in: [junior/src/reporting/conversations.ts:89](https://github.com/getsen > `optional` **inputTokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:87](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L87) +Defined in: [junior/src/reporting/conversations.ts:86](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L86) --- @@ -37,7 +37,7 @@ Defined in: [junior/src/reporting/conversations.ts:87](https://github.com/getsen > `optional` **outputTokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:88](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L88) +Defined in: [junior/src/reporting/conversations.ts:87](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L87) --- @@ -45,4 +45,4 @@ Defined in: [junior/src/reporting/conversations.ts:88](https://github.com/getsen > `optional` **totalTokens?**: `number` -Defined in: [junior/src/reporting/conversations.ts:91](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L91) +Defined in: [junior/src/reporting/conversations.ts:90](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L90) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md index 290e44e34..e373774db 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md @@ -19,7 +19,7 @@ Runtime context passed to a plugin-owned background task. > **db**: `unknown` -Defined in: [junior-plugin-api/src/context.ts:61](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/context.ts#L61) +Defined in: [junior-plugin-api/src/context.ts:60](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/context.ts#L60) Shared Drizzle database connection for plugin runtime code. @@ -29,11 +29,19 @@ Shared Drizzle database connection for plugin runtime code. --- +### embedder + +> **embedder**: `PluginEmbedder` + +Defined in: [junior-plugin-api/src/tasks.ts:40](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L40) + +--- + ### id > **id**: `string` -Defined in: [junior-plugin-api/src/tasks.ts:40](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L40) +Defined in: [junior-plugin-api/src/tasks.ts:41](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L41) --- @@ -41,7 +49,7 @@ Defined in: [junior-plugin-api/src/tasks.ts:40](https://github.com/getsentry/jun > **log**: `PluginLogger` -Defined in: [junior-plugin-api/src/context.ts:62](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/context.ts#L62) +Defined in: [junior-plugin-api/src/context.ts:61](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/context.ts#L61) #### Inherited from @@ -49,11 +57,19 @@ Defined in: [junior-plugin-api/src/context.ts:62](https://github.com/getsentry/j --- +### model + +> **model**: `PluginModel` + +Defined in: [junior-plugin-api/src/tasks.ts:42](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L42) + +--- + ### name > **name**: `string` -Defined in: [junior-plugin-api/src/tasks.ts:41](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L41) +Defined in: [junior-plugin-api/src/tasks.ts:43](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L43) --- @@ -61,7 +77,7 @@ Defined in: [junior-plugin-api/src/tasks.ts:41](https://github.com/getsentry/jun > **plugin**: `PluginMetadata` -Defined in: [junior-plugin-api/src/context.ts:63](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/context.ts#L63) +Defined in: [junior-plugin-api/src/context.ts:62](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/context.ts#L62) #### Inherited from @@ -73,15 +89,15 @@ Defined in: [junior-plugin-api/src/context.ts:63](https://github.com/getsentry/j > **session**: `object` -Defined in: [junior-plugin-api/src/tasks.ts:42](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L42) +Defined in: [junior-plugin-api/src/tasks.ts:44](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L44) #### load() -> **load**(): `Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `messages`: `object`[]; `requester?`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `sessionId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `toolCalls`: `string`[]; \}\> +> **load**(): `Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `messages`: `object`[]; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `sessionId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `toolCalls`: `string`[]; \}\> ##### Returns -`Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `messages`: `object`[]; `requester?`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `sessionId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `toolCalls`: `string`[]; \}\> +`Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `messages`: `object`[]; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `sessionId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `toolCalls`: `string`[]; \}\> --- @@ -89,4 +105,4 @@ Defined in: [junior-plugin-api/src/tasks.ts:42](https://github.com/getsentry/jun > **state**: `PluginState` -Defined in: [junior-plugin-api/src/tasks.ts:45](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L45) +Defined in: [junior-plugin-api/src/tasks.ts:47](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L47) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md index a08a1bc1f..bcea23d73 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md @@ -5,7 +5,7 @@ prev: false title: "PluginTaskDefinition" --- -Defined in: [junior-plugin-api/src/tasks.ts:49](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L49) +Defined in: [junior-plugin-api/src/tasks.ts:51](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L51) Plugin task handler registered by name in a plugin manifest module. @@ -15,7 +15,7 @@ Plugin task handler registered by name in a plugin manifest module. > **run**(`ctx`): `void` \| `Promise`\<`void`\> -Defined in: [junior-plugin-api/src/tasks.ts:50](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L50) +Defined in: [junior-plugin-api/src/tasks.ts:52](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L52) #### Parameters diff --git a/packages/docs/src/content/docs/reference/api/interfaces/RequesterIdentity.md b/packages/docs/src/content/docs/reference/api/interfaces/RequesterIdentity.md index 0daf9bdb6..7ffa1b313 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/RequesterIdentity.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/RequesterIdentity.md @@ -5,7 +5,7 @@ prev: false title: "RequesterIdentity" --- -Defined in: [junior/src/reporting/conversations.ts:94](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L94) +Defined in: [junior/src/reporting/conversations.ts:93](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L93) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:94](https://github.com/getsen > `optional` **email?**: `string` -Defined in: [junior/src/reporting/conversations.ts:95](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L95) +Defined in: [junior/src/reporting/conversations.ts:94](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L94) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:95](https://github.com/getsen > `optional` **fullName?**: `string` -Defined in: [junior/src/reporting/conversations.ts:96](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L96) +Defined in: [junior/src/reporting/conversations.ts:95](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L95) --- @@ -29,7 +29,7 @@ Defined in: [junior/src/reporting/conversations.ts:96](https://github.com/getsen > `optional` **slackUserId?**: `string` -Defined in: [junior/src/reporting/conversations.ts:97](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L97) +Defined in: [junior/src/reporting/conversations.ts:96](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L96) --- @@ -37,4 +37,4 @@ Defined in: [junior/src/reporting/conversations.ts:97](https://github.com/getsen > `optional` **slackUserName?**: `string` -Defined in: [junior/src/reporting/conversations.ts:98](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L98) +Defined in: [junior/src/reporting/conversations.ts:97](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L97) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/TranscriptMessage.md b/packages/docs/src/content/docs/reference/api/interfaces/TranscriptMessage.md index 5ba00f34f..149179235 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/TranscriptMessage.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/TranscriptMessage.md @@ -5,7 +5,7 @@ prev: false title: "TranscriptMessage" --- -Defined in: [junior/src/reporting/conversations.ts:158](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L158) +Defined in: [junior/src/reporting/conversations.ts:157](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L157) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:158](https://github.com/getse > **parts**: [`TranscriptPart`](/reference/api/interfaces/transcriptpart/)[] -Defined in: [junior/src/reporting/conversations.ts:159](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L159) +Defined in: [junior/src/reporting/conversations.ts:158](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L158) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:159](https://github.com/getse > **role**: [`TranscriptRole`](/reference/api/type-aliases/transcriptrole/) -Defined in: [junior/src/reporting/conversations.ts:160](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L160) +Defined in: [junior/src/reporting/conversations.ts:159](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L159) --- @@ -29,4 +29,4 @@ Defined in: [junior/src/reporting/conversations.ts:160](https://github.com/getse > `optional` **timestamp?**: `number` -Defined in: [junior/src/reporting/conversations.ts:161](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L161) +Defined in: [junior/src/reporting/conversations.ts:160](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L160) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/TranscriptPart.md b/packages/docs/src/content/docs/reference/api/interfaces/TranscriptPart.md index 21b908463..180bba5bc 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/TranscriptPart.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/TranscriptPart.md @@ -5,7 +5,7 @@ prev: false title: "TranscriptPart" --- -Defined in: [junior/src/reporting/conversations.ts:129](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L129) +Defined in: [junior/src/reporting/conversations.ts:128](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L128) ## Properties @@ -13,7 +13,7 @@ Defined in: [junior/src/reporting/conversations.ts:129](https://github.com/getse > `optional` **bytes?**: `number` -Defined in: [junior/src/reporting/conversations.ts:130](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L130) +Defined in: [junior/src/reporting/conversations.ts:129](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L129) --- @@ -21,7 +21,7 @@ Defined in: [junior/src/reporting/conversations.ts:130](https://github.com/getse > `optional` **chars?**: `number` -Defined in: [junior/src/reporting/conversations.ts:131](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L131) +Defined in: [junior/src/reporting/conversations.ts:130](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L130) --- @@ -29,7 +29,7 @@ Defined in: [junior/src/reporting/conversations.ts:131](https://github.com/getse > `optional` **id?**: `string` -Defined in: [junior/src/reporting/conversations.ts:132](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L132) +Defined in: [junior/src/reporting/conversations.ts:131](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L131) --- @@ -37,7 +37,7 @@ Defined in: [junior/src/reporting/conversations.ts:132](https://github.com/getse > `optional` **input?**: `unknown` -Defined in: [junior/src/reporting/conversations.ts:133](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L133) +Defined in: [junior/src/reporting/conversations.ts:132](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L132) --- @@ -45,7 +45,7 @@ Defined in: [junior/src/reporting/conversations.ts:133](https://github.com/getse > `optional` **inputKeys?**: `string`[] -Defined in: [junior/src/reporting/conversations.ts:134](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L134) +Defined in: [junior/src/reporting/conversations.ts:133](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L133) --- @@ -53,7 +53,7 @@ Defined in: [junior/src/reporting/conversations.ts:134](https://github.com/getse > `optional` **inputSizeBytes?**: `number` -Defined in: [junior/src/reporting/conversations.ts:135](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L135) +Defined in: [junior/src/reporting/conversations.ts:134](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L134) --- @@ -61,7 +61,7 @@ Defined in: [junior/src/reporting/conversations.ts:135](https://github.com/getse > `optional` **inputSizeChars?**: `number` -Defined in: [junior/src/reporting/conversations.ts:136](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L136) +Defined in: [junior/src/reporting/conversations.ts:135](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L135) --- @@ -69,7 +69,7 @@ Defined in: [junior/src/reporting/conversations.ts:136](https://github.com/getse > `optional` **inputType?**: `string` -Defined in: [junior/src/reporting/conversations.ts:137](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L137) +Defined in: [junior/src/reporting/conversations.ts:136](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L136) --- @@ -77,7 +77,7 @@ Defined in: [junior/src/reporting/conversations.ts:137](https://github.com/getse > `optional` **name?**: `string` -Defined in: [junior/src/reporting/conversations.ts:138](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L138) +Defined in: [junior/src/reporting/conversations.ts:137](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L137) --- @@ -85,7 +85,7 @@ Defined in: [junior/src/reporting/conversations.ts:138](https://github.com/getse > `optional` **output?**: `unknown` -Defined in: [junior/src/reporting/conversations.ts:139](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L139) +Defined in: [junior/src/reporting/conversations.ts:138](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L138) --- @@ -93,7 +93,7 @@ Defined in: [junior/src/reporting/conversations.ts:139](https://github.com/getse > `optional` **outputKeys?**: `string`[] -Defined in: [junior/src/reporting/conversations.ts:140](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L140) +Defined in: [junior/src/reporting/conversations.ts:139](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L139) --- @@ -101,7 +101,7 @@ Defined in: [junior/src/reporting/conversations.ts:140](https://github.com/getse > `optional` **outputSizeBytes?**: `number` -Defined in: [junior/src/reporting/conversations.ts:141](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L141) +Defined in: [junior/src/reporting/conversations.ts:140](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L140) --- @@ -109,7 +109,7 @@ Defined in: [junior/src/reporting/conversations.ts:141](https://github.com/getse > `optional` **outputSizeChars?**: `number` -Defined in: [junior/src/reporting/conversations.ts:142](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L142) +Defined in: [junior/src/reporting/conversations.ts:141](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L141) --- @@ -117,7 +117,7 @@ Defined in: [junior/src/reporting/conversations.ts:142](https://github.com/getse > `optional` **outputType?**: `string` -Defined in: [junior/src/reporting/conversations.ts:143](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L143) +Defined in: [junior/src/reporting/conversations.ts:142](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L142) --- @@ -125,7 +125,7 @@ Defined in: [junior/src/reporting/conversations.ts:143](https://github.com/getse > `optional` **redacted?**: `boolean` -Defined in: [junior/src/reporting/conversations.ts:144](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L144) +Defined in: [junior/src/reporting/conversations.ts:143](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L143) --- @@ -133,7 +133,7 @@ Defined in: [junior/src/reporting/conversations.ts:144](https://github.com/getse > `optional` **sourceType?**: `string` -Defined in: [junior/src/reporting/conversations.ts:145](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L145) +Defined in: [junior/src/reporting/conversations.ts:144](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L144) --- @@ -141,7 +141,7 @@ Defined in: [junior/src/reporting/conversations.ts:145](https://github.com/getse > `optional` **text?**: `string` -Defined in: [junior/src/reporting/conversations.ts:146](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L146) +Defined in: [junior/src/reporting/conversations.ts:145](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L145) --- @@ -149,4 +149,4 @@ Defined in: [junior/src/reporting/conversations.ts:146](https://github.com/getse > **type**: [`TranscriptPartType`](/reference/api/type-aliases/transcriptparttype/) -Defined in: [junior/src/reporting/conversations.ts:147](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L147) +Defined in: [junior/src/reporting/conversations.ts:146](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L146) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/ConversationReportStatus.md b/packages/docs/src/content/docs/reference/api/type-aliases/ConversationReportStatus.md index 7f2b38140..fc3326692 100644 --- a/packages/docs/src/content/docs/reference/api/type-aliases/ConversationReportStatus.md +++ b/packages/docs/src/content/docs/reference/api/type-aliases/ConversationReportStatus.md @@ -7,4 +7,4 @@ title: "ConversationReportStatus" > **ConversationReportStatus** = `"active"` \| `"completed"` \| `"failed"` \| `"hung"` \| `"superseded"` -Defined in: [junior/src/reporting/conversations.ts:77](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L77) +Defined in: [junior/src/reporting/conversations.ts:76](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L76) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/ConversationSurface.md b/packages/docs/src/content/docs/reference/api/type-aliases/ConversationSurface.md index 9643c5f3f..873b96154 100644 --- a/packages/docs/src/content/docs/reference/api/type-aliases/ConversationSurface.md +++ b/packages/docs/src/content/docs/reference/api/type-aliases/ConversationSurface.md @@ -7,4 +7,4 @@ title: "ConversationSurface" > **ConversationSurface** = `"api"` \| `"internal"` \| `"scheduler"` \| `"slack"` -Defined in: [junior/src/reporting/conversations.ts:84](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L84) +Defined in: [junior/src/reporting/conversations.ts:83](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L83) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md b/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md index 6b43d4c79..51592a303 100644 --- a/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md +++ b/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md @@ -7,6 +7,6 @@ title: "PluginTasks" > **PluginTasks** = `Record`\<`string`, [`PluginTaskDefinition`](/reference/api/interfaces/plugintaskdefinition/)\> -Defined in: [junior-plugin-api/src/tasks.ts:54](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L54) +Defined in: [junior-plugin-api/src/tasks.ts:56](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L56) Task handlers keyed by the plugin-owned task name. diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptPartType.md b/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptPartType.md index 451aaf436..14eeee4e6 100644 --- a/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptPartType.md +++ b/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptPartType.md @@ -7,4 +7,4 @@ title: "TranscriptPartType" > **TranscriptPartType** = `"text"` \| `"thinking"` \| `"tool_call"` \| `"tool_result"` \| `"unknown"` -Defined in: [junior/src/reporting/conversations.ts:122](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L122) +Defined in: [junior/src/reporting/conversations.ts:121](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L121) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptRole.md b/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptRole.md index 44526347b..7559bbc5b 100644 --- a/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptRole.md +++ b/packages/docs/src/content/docs/reference/api/type-aliases/TranscriptRole.md @@ -7,4 +7,4 @@ title: "TranscriptRole" > **TranscriptRole** = `"assistant"` \| `"system"` \| `"tool"` \| `"toolResult"` \| `"unknown"` \| `"user"` -Defined in: [junior/src/reporting/conversations.ts:150](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L150) +Defined in: [junior/src/reporting/conversations.ts:149](https://github.com/getsentry/junior/blob/main/packages/junior/src/reporting/conversations.ts#L149) diff --git a/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md b/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md index 65d01872c..18bf18b64 100644 --- a/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md +++ b/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md @@ -5,7 +5,7 @@ prev: false title: "pluginSessionContextSchema" --- -> `const` **pluginSessionContextSchema**: `ZodObject`\<\{ `completedAtMs`: `ZodNumber`; `conversationId`: `ZodString`; `destination`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; \}, `$strict`\>\], `"platform"`\>; `messages`: `ZodArray`\<`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; \}, `$strict`\>\>; `requester`: `ZodOptional`\<`ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>, `ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"local"`\>; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>\], `"platform"`\>\>; `sessionId`: `ZodString`; `source`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `messageTs`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `threadTs`: `ZodOptional`\<`ZodString`\>; `type`: `ZodEnum`\<\{ `priv`: `"priv"`; `pub`: `"pub"`; \}\>; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; `type`: `ZodLiteral`\<`"priv"`\>; \}, `$strict`\>\], `"platform"`\>; `toolCalls`: `ZodArray`\<`ZodString`\>; \}, `$strict`\> +> `const` **pluginSessionContextSchema**: `ZodObject`\<\{ `completedAtMs`: `ZodNumber`; `conversationId`: `ZodString`; `destination`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; \}, `$strict`\>\], `"platform"`\>; `messages`: `ZodArray`\<`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; \}, `$strict`\>\>; `requester`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>, `ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"local"`\>; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>\], `"platform"`\>; `sessionId`: `ZodString`; `source`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `messageTs`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `threadTs`: `ZodOptional`\<`ZodString`\>; `type`: `ZodEnum`\<\{ `priv`: `"priv"`; `pub`: `"pub"`; \}\>; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; `type`: `ZodLiteral`\<`"priv"`\>; \}, `$strict`\>\], `"platform"`\>; `toolCalls`: `ZodArray`\<`ZodString`\>; \}, `$strict`\> Defined in: [junior-plugin-api/src/tasks.ts:21](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L21) diff --git a/packages/junior-evals/package.json b/packages/junior-evals/package.json index 47f95533d..58b6a1ec1 100644 --- a/packages/junior-evals/package.json +++ b/packages/junior-evals/package.json @@ -9,6 +9,7 @@ "evals:record": "VITEST_EVALS_REPLAY_MODE=record vitest run -c vitest.evals.config.ts" }, "devDependencies": { + "@chat-adapter/slack": "4.29.0", "@sentry/junior": "workspace:*", "@sentry/junior-github": "workspace:*", "@sentry/junior-memory": "workspace:*", diff --git a/packages/junior-evals/src/behavior-harness.ts b/packages/junior-evals/src/behavior-harness.ts index 7c53d804c..91b86675e 100644 --- a/packages/junior-evals/src/behavior-harness.ts +++ b/packages/junior-evals/src/behavior-harness.ts @@ -1541,12 +1541,11 @@ function buildRuntimeServices( }); }, scheduleSessionCompletedPluginTasks: async (params) => { - const records = await scheduleSessionCompletedPluginTasks(params, { - enqueue: false, + await scheduleSessionCompletedPluginTasks(params, { + send: async (message) => { + await processPluginTask(message); + }, }); - await Promise.all( - records.map((record) => processPluginTask(record.message)), - ); }, }, visionContext: { @@ -1663,13 +1662,11 @@ async function processEvents(args: { }); }, scheduleSessionCompletedPluginTasks: async (params) => { - const records = await scheduleSessionCompletedPluginTasks( - params, - { enqueue: false }, - ); - await Promise.all( - records.map((record) => processPluginTask(record.message)), - ); + await scheduleSessionCompletedPluginTasks(params, { + send: async (message) => { + await processPluginTask(message); + }, + }); }, }), runtime: slackRuntime, diff --git a/packages/junior-memory/src/tools.ts b/packages/junior-memory/src/tools.ts index 1a4fc083e..f63468884 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior-memory/src/tools.ts @@ -1,6 +1,7 @@ import { Type, type TSchema } from "@sinclair/typebox"; import { Value } from "@sinclair/typebox/value"; import { + getSourceKey, PluginToolInputError, type PluginToolDefinition, type Source, @@ -289,14 +290,11 @@ function parseToolInput(schema: TSchema, input: unknown): T { } function sourceIdempotencyKey(context: MemoryToolContext): string { - if (context.source.platform === "local") { - return context.source.conversationId; - } - const threadKey = context.source.threadTs ?? context.source.messageTs; - if (!threadKey) { + const sourceKey = getSourceKey(context.source); + if (!sourceKey) { throwToolInputError("Memory creation requires source message context."); } - return `slack:${context.source.teamId}:${context.source.channelId}:${threadKey}`; + return sourceKey; } function createInput( diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index a36247096..799437a68 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -814,6 +814,57 @@ describe("memory plugin storage", () => { } }); + it("stores requester memories from local completed sessions", async () => { + const fixture = await createMemoryFixture(); + const { model } = extractionModel([ + { + target: "requester", + content: "Prefers local passive memory QA.", + }, + ]); + const runtime = localContext(); + + try { + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + session: { + async load() { + return completedSession({ + conversationId: runtime.conversationId, + destination: { + platform: "local", + conversationId: runtime.conversationId, + }, + messages: [ + { + role: "user", + text: "I prefer local passive memory QA.", + }, + ], + requester: runtime.requester, + source: runtime.source, + }); + }, + }, + }), + ); + + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toMatchObject([ + { + content: "Prefers local passive memory QA.", + scope: "personal", + subjectKey: "local:local-user", + }, + ]); + } finally { + await fixture.close(); + } + }); + it("persists, recalls, and archives visible memories", async () => { const fixture = await createMemoryFixture(); diff --git a/packages/junior-plugin-api/src/tasks.ts b/packages/junior-plugin-api/src/tasks.ts index 131fbefe5..60a908924 100644 --- a/packages/junior-plugin-api/src/tasks.ts +++ b/packages/junior-plugin-api/src/tasks.ts @@ -24,7 +24,7 @@ export const pluginSessionContextSchema = z conversationId: z.string().min(1), destination: destinationSchema, messages: z.array(pluginSessionMessageSchema), - requester: requesterSchema.optional(), + requester: requesterSchema, sessionId: z.string().min(1), source: sourceSchema, toolCalls: z.array(z.string().min(1)), diff --git a/packages/junior/src/chat/plugins/task-runner.ts b/packages/junior/src/chat/plugins/task-runner.ts index 47f5079be..4d961c049 100644 --- a/packages/junior/src/chat/plugins/task-runner.ts +++ b/packages/junior/src/chat/plugins/task-runner.ts @@ -10,14 +10,12 @@ import type { PluginSessionContext, PluginSessionMessage, PluginTaskContext, - Requester, } from "@sentry/junior-plugin-api"; import { pluginSessionContextSchema } from "@sentry/junior-plugin-api"; import { getDb } from "@/chat/db"; import { createPluginLogger } from "@/chat/plugins/logging"; import { createPluginEmbedder, createPluginModel } from "@/chat/plugins/model"; import { createPluginState } from "@/chat/plugins/state"; -import { createRequesterFromStoredSlackRequester } from "@/chat/requester"; import type { PiMessage } from "@/chat/pi/messages"; import { getPiMessageRole, @@ -94,19 +92,6 @@ function sessionMessage(message: PiMessage): PluginSessionMessage | undefined { return { role, text }; } -function requesterForSession( - record: Awaited>, -): Requester | undefined { - if (!record?.requester?.teamId || !record.requester.slackUserId) { - return undefined; - } - return createRequesterFromStoredSlackRequester({ - requester: record.requester, - teamId: record.requester.teamId, - userId: record.requester.slackUserId, - }); -} - async function withPluginTaskLock( taskId: string, callback: () => Promise, @@ -147,7 +132,11 @@ async function loadPluginSession( "Completed plugin task session record is missing source or destination", ); } - const requester = requesterForSession(record); + if (!record.requester) { + throw new Error( + "Completed plugin task session record is missing requester", + ); + } const sessionMessages = stripRuntimeTurnContext( record.piMessages.slice(record.turnStartMessageIndex ?? 0), ); @@ -158,7 +147,7 @@ async function loadPluginSession( messages: sessionMessages .map(sessionMessage) .filter((message): message is PluginSessionMessage => Boolean(message)), - ...(requester ? { requester } : {}), + requester: record.requester, sessionId: record.sessionId, source: record.source, toolCalls: getSuccessfulToolCalls(sessionMessages), @@ -212,6 +201,13 @@ export async function scheduleSessionCompletedPluginTasks( if (taskRegistrations.length === 0) { return; } + const record = await getAgentTurnSessionRecord( + coreParams.conversationId, + coreParams.sessionId, + ); + if (!record || record.state !== "completed") { + throw new Error("Completed plugin task session record is not ready"); + } const send = options.send ?? sendVercelPluginTask; const messages = taskRegistrations.map(({ name, plugin }) => ({ name, diff --git a/packages/junior/src/chat/requester.ts b/packages/junior/src/chat/requester.ts index 4ce97b2cd..872258a96 100644 --- a/packages/junior/src/chat/requester.ts +++ b/packages/junior/src/chat/requester.ts @@ -2,10 +2,10 @@ * Canonical requester identity. * * Runtime requesters are platform-scoped actors. Stored Slack requester parsing - * remains explicit so legacy durable records can resume without repairing - * malformed team or user ids. + * remains explicit so durable conversation metadata is not repaired on read. */ import { z } from "zod"; +import { requesterSchema } from "@sentry/junior-plugin-api"; import { isSlackTeamId } from "@/chat/slack/ids"; const SLACK_USER_ID_PATTERN = /^[UW][A-Z0-9]{5,}$/; @@ -53,6 +53,12 @@ export interface SlackRequesterProfile { export type StoredSlackRequester = z.output; +/** Parse a serialized runtime requester that crossed a durable boundary. */ +export function parseRequester(value: unknown): Requester | undefined { + const result = requesterSchema.safeParse(value); + return result.success ? result.data : undefined; +} + interface RequesterInput { email?: string; fullName?: string; @@ -258,47 +264,29 @@ export function toStoredSlackRequester( }; } -/** Rebuild a runtime requester from durable Slack requester state. */ -export function createRequesterFromStoredSlackRequester(args: { - requester?: StoredSlackRequester; +/** Resolve a Slack resume requester from stored runtime identity and the active actor. */ +export function createSlackResumeRequester(args: { + requester?: Requester; teamId: string; userId: string; }): SlackRequester { - const actorUserId = parseActorUserId(args.userId); - const actorTeamId = parseSlackTeamId(args.teamId); - if (!actorTeamId || !actorUserId) { - throw new Error("Slack requester requires team and user ids"); + if (!args.requester) { + throw new Error("Stored Slack requester is required for resume"); } - const storedUserId = - args.requester?.slackUserId === undefined - ? undefined - : parseActorUserId(args.requester.slackUserId); - const storedTeamId = - args.requester?.teamId === undefined - ? undefined - : parseSlackTeamId(args.requester.teamId); - if (args.requester?.slackUserId !== undefined && !storedUserId) { - throw new Error("Stored Slack requester requires a user id"); - } - if (args.requester?.teamId !== undefined && !storedTeamId) { - throw new Error("Stored Slack requester requires a team id"); - } - if (storedUserId && storedUserId !== actorUserId) { - throw new Error("Stored Slack requester must match actor user id"); + if ( + args.requester.platform !== "slack" || + args.requester.teamId !== args.teamId || + args.requester.userId !== args.userId + ) { + throw new Error("Stored Slack requester did not match resume actor"); } - if (storedTeamId && storedTeamId !== actorTeamId) { - throw new Error("Stored Slack requester must match actor team id"); + const requester = createRequester(args.requester, { + platform: "slack", + teamId: args.teamId, + userId: args.userId, + }); + if (!requester || requester.platform !== "slack") { + throw new Error("Slack requester requires team and user ids"); } - const canUseStoredProfile = Boolean(storedUserId); - return createSlackRequester( - actorTeamId, - actorUserId, - canUseStoredProfile - ? { - email: args.requester?.email, - fullName: args.requester?.fullName, - userName: args.requester?.slackUserName, - } - : undefined, - ); + return requester; } diff --git a/packages/junior/src/chat/respond.ts b/packages/junior/src/chat/respond.ts index 7b35ba817..06e124377 100644 --- a/packages/junior/src/chat/respond.ts +++ b/packages/junior/src/chat/respond.ts @@ -144,12 +144,7 @@ import type { CredentialContext } from "@/chat/credentials/context"; import { parseSlackThreadId } from "@/chat/slack/context"; import { createMcpAuthOrchestration } from "@/chat/services/mcp-auth-orchestration"; import { createPluginAuthOrchestration } from "@/chat/services/plugin-auth-orchestration"; -import { - createRequester, - toStoredSlackRequester, - type Requester, - type StoredSlackRequester, -} from "@/chat/requester"; +import { createRequester, type Requester } from "@/chat/requester"; import { AuthorizationFlowDisabledError, AuthorizationPauseError, @@ -337,11 +332,8 @@ function extractSliceUsage( function requesterFromContext( context: ReplyRequestContext, -): StoredSlackRequester | undefined { - const identity = actorRequesterFromContext(context); - return identity?.platform === "slack" - ? toStoredSlackRequester(identity) - : undefined; +): Requester | undefined { + return actorRequesterFromContext(context); } /** Reject requester identities that do not belong to the active destination. */ diff --git a/packages/junior/src/chat/runtime/agent-continue-runner.ts b/packages/junior/src/chat/runtime/agent-continue-runner.ts index 6577b9086..c0e992e9c 100644 --- a/packages/junior/src/chat/runtime/agent-continue-runner.ts +++ b/packages/junior/src/chat/runtime/agent-continue-runner.ts @@ -6,7 +6,6 @@ * durably record success, failure, auth pause, or another safe pause boundary. */ import { logException, logWarn } from "@/chat/logging"; -import { createSlackSource } from "@sentry/junior-plugin-api"; import { ResumeTurnBusyError, resumeSlackTurn, @@ -44,7 +43,7 @@ import { type AgentContinueRequest, } from "@/chat/services/agent-continue"; import { parseSlackThreadId } from "@/chat/slack/context"; -import { createRequesterFromStoredSlackRequester } from "@/chat/requester"; +import { createSlackResumeRequester } from "@/chat/requester"; import type { AssistantReply, generateAssistantReply } from "@/chat/respond"; import { persistAuthPauseTurnState } from "@/chat/runtime/auth-pause-state"; import { @@ -268,7 +267,7 @@ export async function continueSlackAgentRun( payload.destination, "Slack continuation", ); - const requester = createRequesterFromStoredSlackRequester({ + const requester = createSlackResumeRequester({ requester: activeSessionRecord.requester, teamId: destination.teamId, userId: userMessage.author.userId, diff --git a/packages/junior/src/chat/runtime/reply-executor.ts b/packages/junior/src/chat/runtime/reply-executor.ts index 273c61408..8c6b5f64c 100644 --- a/packages/junior/src/chat/runtime/reply-executor.ts +++ b/packages/junior/src/chat/runtime/reply-executor.ts @@ -356,12 +356,12 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { ), ), ); - const requesterIdentity = await ensureSlackMessageActorIdentity( + const requester = await ensureSlackMessageActorIdentity( message, teamId, deps.services.lookupSlackUser, ); - const requester = turnRequester(requesterIdentity); + const storedRequester = turnRequester(requester); const preparedState = options.preparedState ?? @@ -571,7 +571,7 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { void initConversationContext(conversationId, { channelName, originSurface: "slack", - originRequester: requester, + originRequester: storedRequester, startedAtMs: turnStartedAtMs, }).catch((error) => { logException( @@ -626,16 +626,12 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { if (message.author.userId) { setSentryUser({ id: message.author.userId, - ...(requesterIdentity.userName - ? { username: requesterIdentity.userName } - : {}), - ...(requesterIdentity.email - ? { email: requesterIdentity.email } - : {}), + ...(requester.userName ? { username: requester.userName } : {}), + ...(requester.email ? { email: requester.email } : {}), }); } - if (requesterIdentity.userName) { - setTags({ slackUserName: requesterIdentity.userName }); + if (requester.userName) { + setTags({ slackUserName: requester.userName }); } const turnAttachments = collectTurnAttachments( message, @@ -850,7 +846,7 @@ export function createReplyToThread(deps: ReplyExecutorDeps) { credentialContext: { actor: { type: "user", userId: message.author.userId }, }, - requester: requesterIdentity, + requester, conversationContext: preparedState.conversationContext, artifactState: preparedState.artifacts, piMessages, diff --git a/packages/junior/src/chat/services/turn-session-record.ts b/packages/junior/src/chat/services/turn-session-record.ts index 6a41c5c38..9fb7457a6 100644 --- a/packages/junior/src/chat/services/turn-session-record.ts +++ b/packages/junior/src/chat/services/turn-session-record.ts @@ -4,8 +4,7 @@ import { type AgentTurnSessionRecord, type AgentTurnSurface, } from "@/chat/state/turn-session"; -import type { StoredSlackRequester } from "@/chat/requester"; -import type { Destination, Source } from "@sentry/junior-plugin-api"; +import type { Destination, Requester, Source } from "@sentry/junior-plugin-api"; import { getActiveTraceId, logException } from "@/chat/logging"; import type { PiMessage } from "@/chat/pi/messages"; import { @@ -135,7 +134,7 @@ export async function persistRunningSessionRecord(args: { messages: PiMessage[]; loadedSkillNames?: string[]; logContext: SessionRecordLogContext; - requester?: StoredSlackRequester; + requester?: Requester; surface?: AgentTurnSurface; turnStartMessageIndex?: number; }): Promise { @@ -214,7 +213,7 @@ export async function persistCompletedSessionRecord(args: { allMessages: PiMessage[]; loadedSkillNames?: string[]; logContext: SessionRecordLogContext; - requester?: StoredSlackRequester; + requester?: Requester; surface?: AgentTurnSurface; turnStartMessageIndex?: number; }): Promise { @@ -297,7 +296,7 @@ export async function persistAuthPauseSessionRecord(args: { loadedSkillNames?: string[]; errorMessage: string; logContext: SessionRecordLogContext; - requester?: StoredSlackRequester; + requester?: Requester; surface?: AgentTurnSurface; }): Promise { const nextSliceId = args.currentSliceId + 1; @@ -384,7 +383,7 @@ export async function persistTimeoutSessionRecord(args: { loadedSkillNames?: string[]; errorMessage: string; logContext: SessionRecordLogContext; - requester?: StoredSlackRequester; + requester?: Requester; surface?: AgentTurnSurface; }): Promise { const nextSliceId = args.currentSliceId + 1; @@ -512,7 +511,7 @@ export async function persistYieldSessionRecord(args: { loadedSkillNames?: string[]; errorMessage: string; logContext: SessionRecordLogContext; - requester?: StoredSlackRequester; + requester?: Requester; surface?: AgentTurnSurface; }): Promise { try { diff --git a/packages/junior/src/chat/state/turn-session.ts b/packages/junior/src/chat/state/turn-session.ts index 686a168a5..5290db8de 100644 --- a/packages/junior/src/chat/state/turn-session.ts +++ b/packages/junior/src/chat/state/turn-session.ts @@ -16,8 +16,9 @@ import { isRecord } from "@/chat/coerce"; import { parseDestination } from "@/chat/destination"; import type { PiMessage } from "@/chat/pi/messages"; import { - parseStoredSlackRequester, - type StoredSlackRequester, + parseRequester, + toStoredSlackRequester, + type Requester, } from "@/chat/requester"; import { commitMessages, loadMessages, loadProjection } from "./session-log"; import type { AgentTurnUsage } from "@/chat/usage"; @@ -54,7 +55,7 @@ export interface AgentTurnSessionRecord { lastProgressAtMs: number; loadedSkillNames?: string[]; piMessages: PiMessage[]; - requester?: StoredSlackRequester; + requester?: Requester; resumeReason?: AgentTurnResumeReason; resumedFromSliceId?: number; sessionId: string; @@ -178,6 +179,14 @@ function parseSource(value: unknown): Source | undefined { return result.success ? result.data : undefined; } +function sessionLogRequester( + requester: Requester | undefined, +): ReturnType | undefined { + return requester?.platform === "slack" + ? toStoredSlackRequester(requester) + : undefined; +} + function parseAgentTurnSessionFields( parsed: Record, ): ParsedAgentTurnSessionFields | undefined { @@ -201,7 +210,10 @@ function parseAgentTurnSessionFields( const lastProgressAtMs = toFiniteNonNegativeNumber(parsed.lastProgressAtMs); const logSessionId = typeof parsed.logSessionId === "string" ? parsed.logSessionId : undefined; - const requester = parseStoredSlackRequester(parsed.requester); + const requester = + parsed.requester === undefined + ? undefined + : parseRequester(parsed.requester); const startedAtMs = toFiniteNonNegativeNumber(parsed.startedAtMs); const surface = parseAgentTurnSurface(parsed.surface); const turnStartMessageIndex = toNonNegativeInteger( @@ -220,7 +232,8 @@ function parseAgentTurnSessionFields( version === undefined || updatedAtMs === undefined || (parsed.destination !== undefined && !destination) || - (parsed.source !== undefined && !source) + (parsed.source !== undefined && !source) || + (parsed.requester !== undefined && !requester) ) { return undefined; } @@ -344,7 +357,7 @@ async function recordConversationActivityMetadata(args: { conversationId: args.summary.conversationId, destination: args.summary.destination, nowMs: args.nowMs, - requester: args.summary.requester, + requester: sessionLogRequester(args.summary.requester), source, }); } catch (error) { @@ -487,7 +500,7 @@ function buildStoredRecord(args: { loadedSkillNames?: string[]; logSessionId?: string; previousVersion?: number; - requester?: StoredSlackRequester; + requester?: Requester; sessionId: string; sliceId: number; startedAtMs?: number; @@ -646,7 +659,7 @@ export async function upsertAgentTurnSessionRecord(args: { state: AgentTurnSessionStatus; surface?: AgentTurnSurface; piMessages: PiMessage[]; - requester?: StoredSlackRequester; + requester?: Requester; resumeReason?: AgentTurnResumeReason; errorMessage?: string; resumedFromSliceId?: number; @@ -662,7 +675,7 @@ export async function upsertAgentTurnSessionRecord(args: { const commit = await commitMessages({ conversationId: args.conversationId, messages: args.piMessages, - requester: args.requester ?? existingRecord?.requester, + requester: sessionLogRequester(args.requester ?? existingRecord?.requester), ttlMs, }); @@ -740,7 +753,7 @@ export async function recordAgentTurnSessionSummary(args: { lastProgressAtMs?: number; loadedSkillNames?: string[]; conversationStore?: ConversationStore; - requester?: StoredSlackRequester; + requester?: Requester; resumeReason?: AgentTurnResumeReason; sessionId: string; sliceId: number; diff --git a/packages/junior/src/handlers/mcp-oauth-callback.ts b/packages/junior/src/handlers/mcp-oauth-callback.ts index 0e0380891..83bda2bdd 100644 --- a/packages/junior/src/handlers/mcp-oauth-callback.ts +++ b/packages/junior/src/handlers/mcp-oauth-callback.ts @@ -52,10 +52,7 @@ import { isRetryableTurnError, markTurnFailed } from "@/chat/runtime/turn"; import { scheduleAgentContinue } from "@/chat/services/agent-continue"; import { htmlCallbackResponse } from "@/handlers/oauth-html"; import type { WaitUntilFn } from "@/handlers/types"; -import { - createRequesterFromStoredSlackRequester, - type Requester, -} from "@/chat/requester"; +import { createSlackResumeRequester, type Requester } from "@/chat/requester"; import { requireSlackDestination } from "@/chat/destination"; const CALLBACK_PAGES = { @@ -309,7 +306,7 @@ async function resumeAuthorizedMcpTurn(args: { ); let requester: Requester; try { - requester = createRequesterFromStoredSlackRequester({ + requester = createSlackResumeRequester({ requester: lockedSessionRecord.requester, teamId: destination.teamId, userId: authSession.userId, diff --git a/packages/junior/src/handlers/oauth-callback.ts b/packages/junior/src/handlers/oauth-callback.ts index fed81a5fe..dd2f50875 100644 --- a/packages/junior/src/handlers/oauth-callback.ts +++ b/packages/junior/src/handlers/oauth-callback.ts @@ -43,10 +43,7 @@ import { import { isRetryableTurnError, markTurnFailed } from "@/chat/runtime/turn"; import { publishAppHomeView } from "@/chat/slack/app-home"; import { getSlackClient } from "@/chat/slack/client"; -import { - createRequesterFromStoredSlackRequester, - type Requester, -} from "@/chat/requester"; +import { createSlackResumeRequester, type Requester } from "@/chat/requester"; import { lookupSlackRequester } from "@/chat/slack/user"; import { getStateAdapter } from "@/chat/state/adapter"; import { coerceThreadArtifactsState } from "@/chat/state/artifacts"; @@ -335,7 +332,7 @@ async function resumeOAuthSessionRecordTurn( ); let requester: Requester; try { - requester = createRequesterFromStoredSlackRequester({ + requester = createSlackResumeRequester({ requester: lockedSessionRecord.requester, teamId: destination.teamId, userId: lockedUserMessage.author.userId, diff --git a/packages/junior/src/reporting/conversations.ts b/packages/junior/src/reporting/conversations.ts index 7828815ec..4b1447a0b 100644 --- a/packages/junior/src/reporting/conversations.ts +++ b/packages/junior/src/reporting/conversations.ts @@ -37,7 +37,11 @@ import { listAgentTurnSessionSummariesForConversation, type AgentTurnSessionSummary, } from "@/chat/state/turn-session"; -import type { StoredSlackRequester } from "@/chat/requester"; +import { + toStoredSlackRequester, + type Requester, + type StoredSlackRequester, +} from "@/chat/requester"; import type { AgentTurnUsage } from "@/chat/usage"; import { getConversationStore } from "@/chat/db"; import type { @@ -273,6 +277,14 @@ function requesterIdentityReport( return Object.keys(identity).length > 0 ? identity : undefined; } +function sessionRequesterIdentityReport( + requester: Requester | undefined, +): RequesterIdentity | undefined { + return requester?.platform === "slack" + ? requesterIdentityReport(toStoredSlackRequester(requester)) + : undefined; +} + function usageReport( usage: AgentTurnUsage | undefined, ): ConversationUsage | undefined { @@ -329,14 +341,15 @@ function sessionReportFromSummary( channelName: effectiveChannelName, }) ?? surfaceFallbackLabel(effectiveSurface); - const effectiveRequester = details?.originRequester ?? summary.requester; + const requesterIdentity = + requesterIdentityReport(details?.originRequester) ?? + sessionRequesterIdentityReport(summary.requester); const sentryConversationUrl = buildSentryConversationUrl( summary.conversationId, ); const sentryTraceUrl = summary.traceId ? buildSentryTraceUrl(summary.traceId) : undefined; - const requesterIdentity = requesterIdentityReport(effectiveRequester); const cumulativeUsage = usageReport(summary.cumulativeUsage); return { conversationId: summary.conversationId, diff --git a/packages/junior/tests/component/plugins/plugin-tasks.test.ts b/packages/junior/tests/component/plugins/plugin-tasks.test.ts index 30f60997d..0e0d87201 100644 --- a/packages/junior/tests/component/plugins/plugin-tasks.test.ts +++ b/packages/junior/tests/component/plugins/plugin-tasks.test.ts @@ -40,6 +40,12 @@ async function recordCompletedSession(args: { ...destination, conversationId: args.conversationId, }, + requester: { + fullName: "Local CLI", + platform: "local", + userId: "local-cli", + userName: "local", + }, piMessages: [ { role: "user", @@ -143,6 +149,12 @@ describe("plugin background tasks", () => { sessionId: runSessionId, sliceId: 1, source: runSource, + requester: { + fullName: "Local CLI", + platform: "local", + userId: "local-cli", + userName: "local", + }, state: "completed", surface: "internal", turnStartMessageIndex: 2, @@ -174,12 +186,17 @@ describe("plugin background tasks", () => { text: "Understood.", }, ], + requester: { + fullName: "Local CLI", + platform: "local", + userId: "local-cli", + userName: "local", + }, sessionId: runSessionId, source: runSource, toolCalls: [], }), ]); - expect(loadedSessions[0]).not.toHaveProperty("requester"); }); it("lets task failures bubble to the queue retry boundary", async () => { @@ -251,6 +268,11 @@ describe("plugin background tasks", () => { }), ]); + await recordCompletedSession({ + conversationId: "local:test:send-failure", + sessionId: "turn-1", + }); + await expect( scheduleSessionCompletedPluginTasks( { conversationId: "local:test:send-failure", sessionId: "turn-1" }, diff --git a/packages/junior/tests/component/runtime/agent-continue-runner.test.ts b/packages/junior/tests/component/runtime/agent-continue-runner.test.ts index 10a54286c..8dfa35d21 100644 --- a/packages/junior/tests/component/runtime/agent-continue-runner.test.ts +++ b/packages/junior/tests/component/runtime/agent-continue-runner.test.ts @@ -54,8 +54,10 @@ describe("agent continuation runner callbacks", () => { source: SLACK_SOURCE, resumeReason: "timeout", requester: { - slackUserId: "U123", - slackUserName: "stored-user", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "stored-user", fullName: "Stored User", email: "stored@example.com", }, @@ -148,7 +150,7 @@ describe("agent continuation runner callbacks", () => { }); }); - it("derives Slack source for continuation records missing source", async () => { + it("fails before continuing when a continuation record is missing source", async () => { const conversationId = "slack:C123:1712345.0007"; const sessionId = "turn_msg_7"; const sessionRecord = await upsertAgentTurnSessionRecord({ @@ -159,8 +161,10 @@ describe("agent continuation runner callbacks", () => { destination: SLACK_DESTINATION, resumeReason: "timeout", requester: { - slackUserId: "U123", - slackUserName: "stored-user", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "stored-user", }, piMessages: [ { @@ -216,21 +220,20 @@ describe("agent continuation runner callbacks", () => { { resumeTurn: async (args) => { const prepared = await args.beforeStart?.(); - if (!prepared || !prepared.replyContext) { - throw new Error("Expected prepared continuation reply context"); + if (prepared !== false) { + throw new Error("Expected continuation preparation to fail"); } - expect(prepared.replyContext.source).toEqual( - createSlackSource({ - teamId: SLACK_DESTINATION.teamId, - channelId: SLACK_DESTINATION.channelId, - threadTs: "1712345.0007", - }), - ); return true; }, }, ), ).resolves.toBe(true); + await expect( + getAgentTurnSessionRecord(conversationId, sessionId), + ).resolves.toMatchObject({ + state: "failed", + errorMessage: "Stored Slack source missing for continuation", + }); }); it("fails before continuing when stored requester and message author differ", async () => { @@ -244,8 +247,10 @@ describe("agent continuation runner callbacks", () => { destination: SLACK_DESTINATION, resumeReason: "timeout", requester: { - slackUserId: "U999", - slackUserName: "wrong-user", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U999", + userName: "wrong-user", }, piMessages: [ { @@ -305,7 +310,7 @@ describe("agent continuation runner callbacks", () => { }, }, ), - ).rejects.toThrow("Stored Slack requester must match actor user id"); + ).rejects.toThrow("Stored Slack requester did not match resume actor"); await expect( getAgentTurnSessionRecord(conversationId, sessionId), ).resolves.toMatchObject({ diff --git a/packages/junior/tests/component/services/turn-session-record.test.ts b/packages/junior/tests/component/services/turn-session-record.test.ts index 5af470e9e..171ffaef4 100644 --- a/packages/junior/tests/component/services/turn-session-record.test.ts +++ b/packages/junior/tests/component/services/turn-session-record.test.ts @@ -324,8 +324,10 @@ describe("persistAuthPauseSessionRecord", () => { state: "awaiting_resume", piMessages: [userMessage], requester: { - slackUserId: "U123", - slackUserName: "alice", + platform: "slack", + teamId: "T123", + userId: "U123", + userName: "alice", fullName: "Alice Example", email: "alice@sentry.io", }, @@ -339,8 +341,10 @@ describe("persistAuthPauseSessionRecord", () => { ), ).resolves.toMatchObject({ requester: { - slackUserId: "U123", - slackUserName: "alice", + platform: "slack", + teamId: "T123", + userId: "U123", + userName: "alice", fullName: "Alice Example", email: "alice@sentry.io", }, @@ -375,8 +379,10 @@ describe("persistAuthPauseSessionRecord", () => { state: "running", piMessages: [previousQuestion, currentQuestion], requester: { - slackUserId: "U123", - slackUserName: "alice", + platform: "slack", + teamId: "T123", + userId: "U123", + userName: "alice", }, turnStartMessageIndex: 1, }); @@ -392,8 +398,10 @@ describe("persistAuthPauseSessionRecord", () => { getAgentTurnSessionRecord("conversation-turn-scope", "turn-scope"), ).resolves.toMatchObject({ requester: { - slackUserId: "U123", - slackUserName: "alice", + platform: "slack", + teamId: "T123", + userId: "U123", + userName: "alice", }, turnStartMessageIndex: 1, piMessages: [previousQuestion, currentQuestion], diff --git a/packages/junior/tests/integration/agent-continue-slack.test.ts b/packages/junior/tests/integration/agent-continue-slack.test.ts index 53e1bd54f..84624c3b5 100644 --- a/packages/junior/tests/integration/agent-continue-slack.test.ts +++ b/packages/junior/tests/integration/agent-continue-slack.test.ts @@ -129,8 +129,10 @@ describe("agent continuation Slack integration", () => { resumedFromSliceId: 1, errorMessage: "Agent turn timed out", requester: { - slackUserId: "U123", - slackUserName: "testuser", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "testuser", fullName: "Test User", email: "testuser@example.com", }, @@ -287,8 +289,10 @@ describe("agent continuation Slack integration", () => { resumedFromSliceId: 4, errorMessage: "Agent turn timed out", requester: { - slackUserId: "U123", - slackUserName: "testuser", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "testuser", fullName: "Test User", email: "testuser@example.com", }, @@ -463,8 +467,10 @@ describe("agent continuation Slack integration", () => { resumedFromSliceId: 1, errorMessage: "Agent turn timed out", requester: { - slackUserId: "U123", - slackUserName: "testuser", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "testuser", fullName: "Test User", email: "testuser@example.com", }, @@ -558,8 +564,10 @@ describe("agent continuation Slack integration", () => { resumedFromSliceId: 1, errorMessage: "Agent turn timed out", requester: { - slackUserId: "U123", - slackUserName: "testuser", + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "testuser", fullName: "Test User", email: "testuser@example.com", }, diff --git a/packages/junior/tests/integration/dashboard-reporting.test.ts b/packages/junior/tests/integration/dashboard-reporting.test.ts index 0b9b7d6dc..a10a17869 100644 --- a/packages/junior/tests/integration/dashboard-reporting.test.ts +++ b/packages/junior/tests/integration/dashboard-reporting.test.ts @@ -16,6 +16,15 @@ const SYSTEM_MESSAGE = { const ORIGINAL_ENV = { ...process.env }; const USE_POSTGRES_HARNESS = Boolean(process.env.DATABASE_URL); +function slackRequester(fullName: string, userId = "U1") { + return { + fullName, + platform: "slack" as const, + teamId: "T1", + userId, + }; +} + async function createStateReportingReader() { const { createStateConversationStore } = await import("@/chat/conversations/state"); @@ -351,7 +360,7 @@ describe("dashboard reporting", () => { channelName: "proj-alpha", conversationId: `slack:C1:${index}`, cumulativeDurationMs: index + 1, - requester: { fullName: "Avery" }, + requester: slackRequester("Avery"), sessionId: `turn-${index}`, sliceId: 1, startedAtMs: Date.now() - index * 1000, @@ -392,7 +401,7 @@ describe("dashboard reporting", () => { conversationId: "slack:C2:300", cumulativeDurationMs: 8_000, cumulativeUsage: { totalTokens: 500 }, - requester: { fullName: "Casey" }, + requester: slackRequester("Casey"), sessionId: "old-turn", sliceId: 1, startedAtMs: Date.parse("2026-05-20T10:00:00.000Z"), @@ -404,7 +413,7 @@ describe("dashboard reporting", () => { conversationId: "slack:C1:100", cumulativeDurationMs: 1_000, cumulativeUsage: { inputTokens: 10, outputTokens: 5 }, - requester: { fullName: "Avery" }, + requester: slackRequester("Avery"), sessionId: "turn-1", sliceId: 1, startedAtMs: Date.parse("2026-06-01T10:00:00.000Z"), @@ -416,7 +425,7 @@ describe("dashboard reporting", () => { conversationId: "slack:C1:100", cumulativeDurationMs: 2_000, cumulativeUsage: { totalTokens: 20 }, - requester: { fullName: "Blake" }, + requester: slackRequester("Blake"), sessionId: "turn-2", sliceId: 1, startedAtMs: Date.parse("2026-06-01T10:03:00.000Z"), @@ -426,7 +435,7 @@ describe("dashboard reporting", () => { await recordAgentTurnSessionSummary({ conversationId: "slack:D1:200", cumulativeDurationMs: 3_000, - requester: { fullName: "Avery" }, + requester: slackRequester("Avery"), sessionId: "turn-3", sliceId: 1, startedAtMs: Date.parse("2026-06-04T11:00:00.000Z"), @@ -496,7 +505,7 @@ describe("dashboard reporting", () => { await recordAgentTurnSessionSummary({ conversationId: "slack:C1:100", cumulativeDurationMs: 1_000, - requester: { fullName: "Later Requester" }, + requester: slackRequester("Later Requester"), sessionId: "turn-1", sliceId: 1, startedAtMs: Date.parse("2026-06-04T10:05:00.000Z"), @@ -531,7 +540,7 @@ describe("dashboard reporting", () => { await recordAgentTurnSessionSummary({ conversationId: "agent-dispatch:dispatch_scheduler", cumulativeDurationMs: 2_000, - requester: { fullName: "Scheduler" }, + requester: slackRequester("Scheduler"), sessionId: "dispatch:scheduler", sliceId: 1, state: "completed", @@ -540,7 +549,7 @@ describe("dashboard reporting", () => { await recordAgentTurnSessionSummary({ conversationId: "agent-dispatch:dispatch_api", cumulativeDurationMs: 1_000, - requester: { fullName: "API" }, + requester: slackRequester("API"), sessionId: "dispatch:api", sliceId: 1, state: "completed", @@ -568,7 +577,7 @@ describe("dashboard reporting", () => { conversationStore, conversationId: "slack:C1:baseline", cumulativeDurationMs: 1_000, - requester: { fullName: "Avery" }, + requester: slackRequester("Avery"), sessionId: "turn-baseline", sliceId: 1, startedAtMs, @@ -580,7 +589,7 @@ describe("dashboard reporting", () => { conversationStore, conversationId: `slack:C_FILL:${index}`, cumulativeDurationMs: 1, - requester: { fullName: "Filler" }, + requester: slackRequester("Filler"), sessionId: `turn-${index}`, sliceId: 1, state: "completed", @@ -591,7 +600,7 @@ describe("dashboard reporting", () => { conversationStore, conversationId: "slack:C1:baseline", cumulativeDurationMs: 1_500, - requester: { fullName: "Blake" }, + requester: slackRequester("Blake"), sessionId: "turn-latest", sliceId: 1, state: "completed", @@ -1006,7 +1015,9 @@ describe("dashboard reporting", () => { channelName: "secret-dm-name", requester: { email: "david@sentry.io", - slackUserId: "U1", + platform: "slack", + teamId: "T1", + userId: "U1", }, piMessages: [ { diff --git a/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts b/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts index 13ba575ff..07f46ec56 100644 --- a/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts +++ b/packages/junior/tests/integration/mcp-oauth-callback-slack.test.ts @@ -1,6 +1,10 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { createSlackSource, type Source } from "@sentry/junior-plugin-api"; +import { + createSlackSource, + type Requester, + type Source, +} from "@sentry/junior-plugin-api"; import { EVAL_MCP_AUTH_CODE, EVAL_MCP_AUTH_PROVIDER, @@ -101,14 +105,7 @@ async function createPendingAuthSession(args: { async function createAwaitingMcpTurnRecord(args: { conversationId: string; - requester?: { - email?: string; - fullName?: string; - platform?: "slack"; - slackUserId?: string; - slackUserName?: string; - teamId?: string; - }; + requester?: Requester; includeSource?: boolean; sessionId: string; source?: Source; @@ -131,7 +128,12 @@ async function createAwaitingMcpTurnRecord(args: { timestamp: 1, }, ], - ...(args.requester ? { requester: args.requester } : {}), + requester: args.requester ?? { + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "dcramer", + }, resumeReason: "auth", resumedFromSliceId: 1, }); @@ -256,8 +258,8 @@ describe("mcp oauth callback slack integration", () => { requester: { platform: "slack", teamId: "T123", - slackUserId: "U123", - slackUserName: "stored-user", + userId: "U123", + userName: "stored-user", fullName: "Stored User", email: "stored@example.com", }, @@ -477,7 +479,7 @@ describe("mcp oauth callback slack integration", () => { requester: { platform: "slack", teamId: "T999", - slackUserId: "U123", + userId: "U123", }, sessionId, source: slackSource("1700000000.006"), @@ -607,7 +609,6 @@ describe("mcp oauth callback slack integration", () => { }); await createAwaitingMcpTurnRecord({ conversationId: threadId, - includeSource: false, sessionId, source: slackSource("1700000000.005"), text: "what did i say about the budget?", @@ -655,10 +656,7 @@ describe("mcp oauth callback slack integration", () => { conversationContext?: string; source?: unknown; }; - expect(resumeContext.source).toEqual({ - ...slackSource("1700000000.005"), - messageTs: "1700000000.0052", - }); + expect(resumeContext.source).toEqual(slackSource("1700000000.005")); expect(resumeContext.conversationContext).not.toContain( "Old MCP context that should not be used.", ); @@ -848,8 +846,10 @@ describe("mcp oauth callback slack integration", () => { await createAwaitingMcpTurnRecord({ conversationId: "conversation-mismatched-requester", requester: { - slackUserId: "U999", - slackUserName: "wrong-user", + platform: "slack", + teamId: "T123", + userId: "U999", + userName: "wrong-user", }, sessionId, source: slackSource("1700000000.007"), diff --git a/packages/junior/tests/integration/oauth-callback-slack.test.ts b/packages/junior/tests/integration/oauth-callback-slack.test.ts index 10472c02b..8691cf598 100644 --- a/packages/junior/tests/integration/oauth-callback-slack.test.ts +++ b/packages/junior/tests/integration/oauth-callback-slack.test.ts @@ -220,8 +220,8 @@ describe("oauth callback slack integration", () => { requester: { platform: "slack", teamId: "T123", - slackUserId: "U123", - slackUserName: "stored-user", + userId: "U123", + userName: "stored-user", fullName: "Stored User", email: "stored@example.com", }, @@ -343,7 +343,7 @@ describe("oauth callback slack integration", () => { }; expect(resumeContext.source).toEqual({ ...slackSource("1700000000.009"), - messageTs: "1700000000.010", + messageTs: "1700000000.session-source", }); expect(resumeContext.conversationContext).not.toContain( "list my sentry issues", @@ -418,7 +418,7 @@ describe("oauth callback slack integration", () => { requester: { platform: "slack", teamId: "T999", - slackUserId: "U123", + userId: "U123", }, }); await stateAdapterModule @@ -581,7 +581,7 @@ describe("oauth callback slack integration", () => { piMessages: [], resumeReason: "auth", resumedFromSliceId: 1, - requester: { slackUserId: "U123" }, + requester: { platform: "slack", teamId: "T123", userId: "U123" }, }); await stateAdapterModule .getStateAdapter() @@ -670,6 +670,12 @@ describe("oauth callback slack integration", () => { piMessages: [], resumeReason: "auth", resumedFromSliceId: 1, + requester: { + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "dcramer", + }, }); await turnSessionStoreModule.upsertAgentTurnSessionRecord({ conversationId, @@ -681,6 +687,12 @@ describe("oauth callback slack integration", () => { piMessages: [], resumeReason: "auth", resumedFromSliceId: 1, + requester: { + platform: "slack", + teamId: SLACK_DESTINATION.teamId, + userId: "U123", + userName: "dcramer", + }, }); await stateAdapterModule @@ -780,7 +792,7 @@ describe("oauth callback slack integration", () => { piMessages: [], resumeReason: "auth", resumedFromSliceId: 1, - requester: { slackUserId: "U123" }, + requester: { platform: "slack", teamId: "T123", userId: "U123" }, }); await stateAdapterModule diff --git a/packages/junior/tests/unit/services/requester.test.ts b/packages/junior/tests/unit/services/requester.test.ts index 8bc4d6831..95b125b5e 100644 --- a/packages/junior/tests/unit/services/requester.test.ts +++ b/packages/junior/tests/unit/services/requester.test.ts @@ -1,7 +1,6 @@ import { describe, expect, it } from "vitest"; import { createRequester, - createRequesterFromStoredSlackRequester, createSlackRequester, isActorUserId, parseActorUserId, @@ -138,86 +137,6 @@ describe("requester", () => { ); }); - it("uses stored Slack requester fields only for the same Slack actor", () => { - expect( - createRequesterFromStoredSlackRequester({ - teamId: "T123", - userId: "U039RR91S", - requester: { - email: "david@example.com", - fullName: "David Cramer", - platform: "slack", - slackUserId: "U039RR91S", - slackUserName: "dcramer", - teamId: "T123", - }, - }), - ).toEqual({ - email: "david@example.com", - fullName: "David Cramer", - platform: "slack", - teamId: "T123", - userId: "U039RR91S", - userName: "dcramer", - }); - - expect(() => - createRequesterFromStoredSlackRequester({ - teamId: "T123", - userId: "U039RR91S", - requester: { - platform: "slack", - slackUserId: "U_OTHER", - teamId: "T123", - }, - }), - ).toThrow("Stored Slack requester must match actor user id"); - expect(() => - createRequesterFromStoredSlackRequester({ - teamId: "T123", - userId: "U039RR91S", - requester: { - platform: "slack", - slackUserId: " U039RR91S ", - teamId: "T123", - }, - }), - ).toThrow("Stored Slack requester requires a user id"); - expect(() => - createRequesterFromStoredSlackRequester({ - teamId: "T123", - userId: "U039RR91S", - requester: { - platform: "slack", - slackUserId: "U039RR91S", - teamId: "T999", - }, - }), - ).toThrow("Stored Slack requester must match actor team id"); - }); - - it("preserves legacy stored Slack requester profile fields without stored team id", () => { - expect( - createRequesterFromStoredSlackRequester({ - teamId: "T123", - userId: "U039RR91S", - requester: { - email: "david@example.com", - fullName: "David Cramer", - slackUserId: "U039RR91S", - slackUserName: "dcramer", - }, - }), - ).toEqual({ - email: "david@example.com", - fullName: "David Cramer", - platform: "slack", - teamId: "T123", - userId: "U039RR91S", - userName: "dcramer", - }); - }); - it("parses canonical serialized Slack requesters without repair", () => { expect( parseStoredSlackRequester({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2aa15412c..d2c5fcd0e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -361,6 +361,9 @@ importers: packages/junior-evals: devDependencies: + '@chat-adapter/slack': + specifier: 4.29.0 + version: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) '@sentry/junior': specifier: workspace:* version: file:packages/junior @@ -569,12 +572,6 @@ packages: '@apm-js-collab/tracing-hooks@0.10.0': resolution: {integrity: sha512-2/Z3NTewJTruUkmsSnBC5bJlLNUd9keuD1OLlTEpim4FyLhm6m2Rnfv+wrFdUvFfhmH8CRdiDZBqBrn+wyaGuA==} - '@ast-grep/cli-darwin-arm64@0.43.0': - resolution: {integrity: sha512-0i63gSBbgriPaRpFsbP3yETxolHPK2JAZbpcGbFOytB7QTnKAguwhlKmIOkUGKfsCzYiEq1awY0EBmvjMONXOg==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - '@ast-grep/cli-darwin-x64@0.43.0': resolution: {integrity: sha512-SPkj00HGKpYdqReUmso2ftG5Xgd+bWNFH4i9fubLxsWzn4ey2G6sotPruaOtcrzxb9xH+8kmhN7KJfm1k8Atzg==} engines: {node: '>= 10'} @@ -1007,12 +1004,6 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/android-arm64@0.18.20': resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} @@ -1037,12 +1028,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm@0.18.20': resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} @@ -1067,12 +1052,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-x64@0.18.20': resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} @@ -1097,12 +1076,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/darwin-arm64@0.18.20': resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} @@ -1127,12 +1100,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-x64@0.18.20': resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} @@ -1157,12 +1124,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/freebsd-arm64@0.18.20': resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} @@ -1187,12 +1148,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} @@ -1217,12 +1172,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/linux-arm64@0.18.20': resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} @@ -1247,12 +1196,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm@0.18.20': resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} @@ -1277,12 +1220,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-ia32@0.18.20': resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} @@ -1307,12 +1244,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-loong64@0.18.20': resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} @@ -1337,12 +1268,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-mips64el@0.18.20': resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} @@ -1367,12 +1292,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-ppc64@0.18.20': resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} @@ -1397,12 +1316,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-riscv64@0.18.20': resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} @@ -1427,12 +1340,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-s390x@0.18.20': resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} @@ -1457,12 +1364,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-x64@0.18.20': resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} @@ -1487,12 +1388,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/netbsd-arm64@0.25.12': resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} engines: {node: '>=18'} @@ -1511,12 +1406,6 @@ packages: cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-x64@0.18.20': resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} @@ -1541,12 +1430,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} engines: {node: '>=18'} @@ -1565,12 +1448,6 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-x64@0.18.20': resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} @@ -1595,12 +1472,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} engines: {node: '>=18'} @@ -1619,12 +1490,6 @@ packages: cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/sunos-x64@0.18.20': resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} @@ -1649,12 +1514,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/win32-arm64@0.18.20': resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} @@ -1679,12 +1538,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-ia32@0.18.20': resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} @@ -1709,12 +1562,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-x64@0.18.20': resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} @@ -1739,12 +1586,6 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@expressive-code/core@0.42.0': resolution: {integrity: sha512-MN11+9nfmaC7sYu2BZJXAXqwkBRt8t1xTSqP+Ti1NfTEskgl6xUnzDxoaiQkg0BMzpglA0pys4dpDKquP/cyIw==} @@ -2701,10 +2542,6 @@ packages: '@protobufjs/utf8@1.1.1': resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} - '@publint/pack@0.1.5': - resolution: {integrity: sha512-edgyN2pP07uXiP4tJs0s8KVmU8M8i60YPbbI0/WDeok1mIJHRXz+CgD8I0nelwDkoCh3EWL/G5kGfbuHjsdbvw==} - engines: {node: '>=18'} - '@redis/bloom@5.12.1': resolution: {integrity: sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==} engines: {node: '>= 18.19.0'} @@ -3822,26 +3659,14 @@ packages: ajv@8.6.3: resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} - ansi-escapes@7.3.0: - resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} - engines: {node: '>=18'} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} - engines: {node: '>=12'} - any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -4171,14 +3996,6 @@ packages: cjs-module-lexer@2.2.0: resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} - cli-cursor@5.0.0: - resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} - engines: {node: '>=18'} - - cli-truncate@5.2.0: - resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} - engines: {node: '>=20'} - cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -4622,9 +4439,6 @@ packages: emmet@2.4.11: resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} - emoji-regex@10.6.0: - resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4665,10 +4479,6 @@ packages: miniflare: optional: true - environment@1.1.0: - resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} - engines: {node: '>=18'} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -4723,11 +4533,6 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} - hasBin: true - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4964,11 +4769,6 @@ packages: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -4993,10 +4793,6 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} - get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} @@ -5320,10 +5116,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-fullwidth-code-point@5.1.0: - resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} - engines: {node: '>=18'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} @@ -5553,18 +5345,10 @@ packages: engines: {node: '>=22.22.1'} hasBin: true - listr2@10.2.1: - resolution: {integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==} - engines: {node: '>=22.13.0'} - load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - log-update@6.1.0: - resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} - engines: {node: '>=18'} - long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} @@ -5839,10 +5623,6 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - mimic-function@5.0.1: - resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} - engines: {node: '>=18'} - mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -6111,10 +5891,6 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} - onetime@7.0.0: - resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} - engines: {node: '>=18'} - oniguruma-parser@0.12.2: resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} @@ -6326,16 +6102,6 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - playwright-core@1.60.0: - resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.60.0: - resolution: {integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==} - engines: {node: '>=18'} - hasBin: true - postcss-load-config@6.0.1: resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} engines: {node: '>= 18'} @@ -6664,10 +6430,6 @@ packages: engines: {node: '>= 0.4'} hasBin: true - restore-cursor@5.1.0: - resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} - engines: {node: '>=18'} - retext-latin@4.0.0: resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} @@ -6691,9 +6453,6 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rolldown@1.0.0-rc.1: resolution: {integrity: sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6722,10 +6481,6 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - sade@1.8.1: - resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} - engines: {node: '>=6'} - safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -6861,14 +6616,6 @@ packages: engines: {node: '>=20.19.5', npm: '>=10.8.2'} hasBin: true - slice-ansi@7.1.2: - resolution: {integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==} - engines: {node: '>=18'} - - slice-ansi@8.0.0: - resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} - engines: {node: '>=20'} - smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -6968,22 +6715,10 @@ packages: strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-argv@0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} - - string-width@8.2.1: - resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} - engines: {node: '>=20'} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -6994,10 +6729,6 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} - strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -7783,18 +7514,10 @@ packages: engines: {node: '>=8'} hasBin: true - wrap-ansi@10.0.0: - resolution: {integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==} - engines: {node: '>=20'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@9.0.2: - resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} - engines: {node: '>=18'} - wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -7953,9 +7676,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@ast-grep/cli-darwin-arm64@0.43.0': - optional: true - '@ast-grep/cli-darwin-x64@0.43.0': optional: true @@ -7975,10 +7695,7 @@ snapshots: optional: true '@ast-grep/cli@0.43.0': - dependencies: - detect-libc: 2.1.2 optionalDependencies: - '@ast-grep/cli-darwin-arm64': 0.43.0 '@ast-grep/cli-darwin-x64': 0.43.0 '@ast-grep/cli-linux-arm64-gnu': 0.43.0 '@ast-grep/cli-linux-x64-gnu': 0.43.0 @@ -8592,9 +8309,6 @@ snapshots: '@esbuild/aix-ppc64@0.27.7': optional: true - '@esbuild/aix-ppc64@0.28.1': - optional: true - '@esbuild/android-arm64@0.18.20': optional: true @@ -8607,9 +8321,6 @@ snapshots: '@esbuild/android-arm64@0.27.7': optional: true - '@esbuild/android-arm64@0.28.1': - optional: true - '@esbuild/android-arm@0.18.20': optional: true @@ -8622,9 +8333,6 @@ snapshots: '@esbuild/android-arm@0.27.7': optional: true - '@esbuild/android-arm@0.28.1': - optional: true - '@esbuild/android-x64@0.18.20': optional: true @@ -8637,9 +8345,6 @@ snapshots: '@esbuild/android-x64@0.27.7': optional: true - '@esbuild/android-x64@0.28.1': - optional: true - '@esbuild/darwin-arm64@0.18.20': optional: true @@ -8652,9 +8357,6 @@ snapshots: '@esbuild/darwin-arm64@0.27.7': optional: true - '@esbuild/darwin-arm64@0.28.1': - optional: true - '@esbuild/darwin-x64@0.18.20': optional: true @@ -8667,9 +8369,6 @@ snapshots: '@esbuild/darwin-x64@0.27.7': optional: true - '@esbuild/darwin-x64@0.28.1': - optional: true - '@esbuild/freebsd-arm64@0.18.20': optional: true @@ -8682,9 +8381,6 @@ snapshots: '@esbuild/freebsd-arm64@0.27.7': optional: true - '@esbuild/freebsd-arm64@0.28.1': - optional: true - '@esbuild/freebsd-x64@0.18.20': optional: true @@ -8697,9 +8393,6 @@ snapshots: '@esbuild/freebsd-x64@0.27.7': optional: true - '@esbuild/freebsd-x64@0.28.1': - optional: true - '@esbuild/linux-arm64@0.18.20': optional: true @@ -8712,9 +8405,6 @@ snapshots: '@esbuild/linux-arm64@0.27.7': optional: true - '@esbuild/linux-arm64@0.28.1': - optional: true - '@esbuild/linux-arm@0.18.20': optional: true @@ -8727,9 +8417,6 @@ snapshots: '@esbuild/linux-arm@0.27.7': optional: true - '@esbuild/linux-arm@0.28.1': - optional: true - '@esbuild/linux-ia32@0.18.20': optional: true @@ -8742,9 +8429,6 @@ snapshots: '@esbuild/linux-ia32@0.27.7': optional: true - '@esbuild/linux-ia32@0.28.1': - optional: true - '@esbuild/linux-loong64@0.18.20': optional: true @@ -8757,9 +8441,6 @@ snapshots: '@esbuild/linux-loong64@0.27.7': optional: true - '@esbuild/linux-loong64@0.28.1': - optional: true - '@esbuild/linux-mips64el@0.18.20': optional: true @@ -8772,9 +8453,6 @@ snapshots: '@esbuild/linux-mips64el@0.27.7': optional: true - '@esbuild/linux-mips64el@0.28.1': - optional: true - '@esbuild/linux-ppc64@0.18.20': optional: true @@ -8787,9 +8465,6 @@ snapshots: '@esbuild/linux-ppc64@0.27.7': optional: true - '@esbuild/linux-ppc64@0.28.1': - optional: true - '@esbuild/linux-riscv64@0.18.20': optional: true @@ -8802,9 +8477,6 @@ snapshots: '@esbuild/linux-riscv64@0.27.7': optional: true - '@esbuild/linux-riscv64@0.28.1': - optional: true - '@esbuild/linux-s390x@0.18.20': optional: true @@ -8817,9 +8489,6 @@ snapshots: '@esbuild/linux-s390x@0.27.7': optional: true - '@esbuild/linux-s390x@0.28.1': - optional: true - '@esbuild/linux-x64@0.18.20': optional: true @@ -8832,9 +8501,6 @@ snapshots: '@esbuild/linux-x64@0.27.7': optional: true - '@esbuild/linux-x64@0.28.1': - optional: true - '@esbuild/netbsd-arm64@0.25.12': optional: true @@ -8844,9 +8510,6 @@ snapshots: '@esbuild/netbsd-arm64@0.27.7': optional: true - '@esbuild/netbsd-arm64@0.28.1': - optional: true - '@esbuild/netbsd-x64@0.18.20': optional: true @@ -8859,9 +8522,6 @@ snapshots: '@esbuild/netbsd-x64@0.27.7': optional: true - '@esbuild/netbsd-x64@0.28.1': - optional: true - '@esbuild/openbsd-arm64@0.25.12': optional: true @@ -8871,9 +8531,6 @@ snapshots: '@esbuild/openbsd-arm64@0.27.7': optional: true - '@esbuild/openbsd-arm64@0.28.1': - optional: true - '@esbuild/openbsd-x64@0.18.20': optional: true @@ -8886,9 +8543,6 @@ snapshots: '@esbuild/openbsd-x64@0.27.7': optional: true - '@esbuild/openbsd-x64@0.28.1': - optional: true - '@esbuild/openharmony-arm64@0.25.12': optional: true @@ -8898,9 +8552,6 @@ snapshots: '@esbuild/openharmony-arm64@0.27.7': optional: true - '@esbuild/openharmony-arm64@0.28.1': - optional: true - '@esbuild/sunos-x64@0.18.20': optional: true @@ -8913,9 +8564,6 @@ snapshots: '@esbuild/sunos-x64@0.27.7': optional: true - '@esbuild/sunos-x64@0.28.1': - optional: true - '@esbuild/win32-arm64@0.18.20': optional: true @@ -8928,9 +8576,6 @@ snapshots: '@esbuild/win32-arm64@0.27.7': optional: true - '@esbuild/win32-arm64@0.28.1': - optional: true - '@esbuild/win32-ia32@0.18.20': optional: true @@ -8943,9 +8588,6 @@ snapshots: '@esbuild/win32-ia32@0.27.7': optional: true - '@esbuild/win32-ia32@0.28.1': - optional: true - '@esbuild/win32-x64@0.18.20': optional: true @@ -8958,9 +8600,6 @@ snapshots: '@esbuild/win32-x64@0.27.7': optional: true - '@esbuild/win32-x64@0.28.1': - optional: true - '@expressive-code/core@0.42.0': dependencies: '@ctrl/tinycolor': 4.2.0 @@ -9766,9 +9405,7 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.6 '@parcel/watcher-win32-x64': 2.5.6 - '@playwright/test@1.60.0': - dependencies: - playwright: 1.60.0 + '@playwright/test@1.60.0': {} '@prisma/instrumentation@7.6.0(@opentelemetry/api@1.9.1)': dependencies: @@ -9799,10 +9436,6 @@ snapshots: '@protobufjs/utf8@1.1.1': {} - '@publint/pack@0.1.5': - dependencies: - tinyexec: 1.1.2 - '@redis/bloom@5.12.1(@redis/client@5.12.1)': dependencies: '@redis/client': 5.12.1 @@ -11459,20 +11092,12 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 - ansi-escapes@7.3.0: - dependencies: - environment: 1.1.0 - ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} - ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.3: {} - any-promise@1.3.0: {} anymatch@3.1.3: @@ -11856,15 +11481,6 @@ snapshots: cjs-module-lexer@2.2.0: {} - cli-cursor@5.0.0: - dependencies: - restore-cursor: 5.1.0 - - cli-truncate@5.2.0: - dependencies: - slice-ansi: 8.0.0 - string-width: 8.2.1 - cli-width@4.1.0: {} cliui@8.0.1: @@ -12196,8 +11812,6 @@ snapshots: '@emmetio/abbreviation': 2.3.3 '@emmetio/css-abbreviation': 2.1.8 - emoji-regex@10.6.0: {} - emoji-regex@8.0.0: {} encodeurl@2.0.0: {} @@ -12235,8 +11849,6 @@ snapshots: optionalDependencies: '@vercel/queue': 0.2.0 - environment@1.1.0: {} - es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -12386,35 +11998,6 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 - esbuild@0.28.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - escalade@3.2.0: {} escape-html@1.0.3: {} @@ -12711,9 +12294,6 @@ snapshots: jsonfile: 6.2.1 universalify: 2.0.1 - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true @@ -12739,8 +12319,6 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.6.0: {} - get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -13183,10 +12761,6 @@ snapshots: is-fullwidth-code-point@3.0.0: {} - is-fullwidth-code-point@5.1.0: - dependencies: - get-east-asian-width: 1.6.0 - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -13380,33 +12954,10 @@ snapshots: dependencies: uc.micro: 2.1.0 - lint-staged@17.0.5: - dependencies: - listr2: 10.2.1 - picomatch: 4.0.4 - string-argv: 0.3.2 - tinyexec: 1.1.2 - optionalDependencies: - yaml: 2.9.0 - - listr2@10.2.1: - dependencies: - cli-truncate: 5.2.0 - eventemitter3: 5.0.4 - log-update: 6.1.0 - rfdc: 1.4.1 - wrap-ansi: 10.0.0 + lint-staged@17.0.5: {} load-tsconfig@0.2.5: {} - log-update@6.1.0: - dependencies: - ansi-escapes: 7.3.0 - cli-cursor: 5.0.0 - slice-ansi: 7.1.2 - strip-ansi: 7.2.0 - wrap-ansi: 9.0.2 - long@5.3.2: {} longest-streak@3.1.0: {} @@ -13954,8 +13505,6 @@ snapshots: mimic-fn@2.1.0: {} - mimic-function@5.0.1: {} - mimic-response@3.1.0: optional: true @@ -14364,10 +13913,6 @@ snapshots: dependencies: mimic-fn: 2.1.0 - onetime@7.0.0: - dependencies: - mimic-function: 5.0.1 - oniguruma-parser@0.12.2: {} oniguruma-to-es@4.3.6: @@ -14604,14 +14149,6 @@ snapshots: mlly: 1.8.2 pathe: 2.0.3 - playwright-core@1.60.0: {} - - playwright@1.60.0: - dependencies: - playwright-core: 1.60.0 - optionalDependencies: - fsevents: 2.3.2 - postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.15)(tsx@4.22.3)(yaml@2.9.0): dependencies: lilconfig: 3.1.3 @@ -14724,12 +14261,7 @@ snapshots: proxy-from-env@2.1.0: {} - publint@0.3.21: - dependencies: - '@publint/pack': 0.1.5 - package-manager-detector: 1.6.0 - picocolors: 1.1.1 - sade: 1.8.1 + publint@0.3.21: {} pump@3.0.4: dependencies: @@ -15062,11 +14594,6 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@5.1.0: - dependencies: - onetime: 7.0.0 - signal-exit: 4.1.0 - retext-latin@4.0.0: dependencies: '@types/nlcst': 2.0.3 @@ -15098,8 +14625,6 @@ snapshots: reusify@1.1.0: {} - rfdc@1.4.1: {} - rolldown@1.0.0-rc.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): dependencies: '@oxc-project/types': 0.110.0 @@ -15192,10 +14717,6 @@ snapshots: dependencies: queue-microtask: 1.2.3 - sade@1.8.1: - dependencies: - mri: 1.2.0 - safe-buffer@5.2.1: {} safe-regex@2.1.1: @@ -15375,16 +14896,6 @@ snapshots: arg: 5.0.2 sax: 1.6.0 - slice-ansi@7.1.2: - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.1.0 - - slice-ansi@8.0.0: - dependencies: - ansi-styles: 6.2.3 - is-fullwidth-code-point: 5.1.0 - smart-buffer@4.2.0: {} smol-toml@1.5.2: {} @@ -15469,25 +14980,12 @@ snapshots: strict-event-emitter@0.5.1: {} - string-argv@0.3.2: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@7.2.0: - dependencies: - emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 - strip-ansi: 7.2.0 - - string-width@8.2.1: - dependencies: - get-east-asian-width: 1.6.0 - strip-ansi: 7.2.0 - string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -15502,10 +15000,6 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.2.0: - dependencies: - ansi-regex: 6.2.2 - strip-bom@3.0.0: {} strip-final-newline@2.0.0: {} @@ -15759,11 +15253,7 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - tsx@4.22.3: - dependencies: - esbuild: 0.28.1 - optionalDependencies: - fsevents: 2.3.3 + tsx@4.22.3: {} tunnel-agent@0.6.0: dependencies: @@ -16322,24 +15812,12 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 - wrap-ansi@10.0.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 8.2.1 - strip-ansi: 7.2.0 - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@9.0.2: - dependencies: - ansi-styles: 6.2.3 - string-width: 7.2.0 - strip-ansi: 7.2.0 - wrappy@1.0.2: {} ws@8.20.1: {} diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 847c95e97..4c992f5cd 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -240,7 +240,8 @@ a model-visible rejection, not storage with a special classification. Duplicate prevention is required before insertion where the relevant signal is available: -- same source, completed session reference, and extracted fact index +- same source, completed session reference, target, normalized content, and + expiration marker - high lexical or embedding similarity to an active memory in the same scope V1 storage enforces source/fact idempotency. Exact normalized-content equality From f3616cbb1307ea02da78a263e005fe32640864c1 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 10:01:33 -0700 Subject: [PATCH 21/29] fix(memory): Keep organic facts on passive path Clarify that createMemory is only for explicit memory-write requests and add eval coverage that organic first-person facts are not satisfied through a visible createMemory call. Co-Authored-By: GPT-5 Codex --- packages/junior-evals/evals/memory/workflows.eval.ts | 9 ++++++++- packages/junior-memory/src/tools.ts | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index 61aa7a3a3..e28525577 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -1,5 +1,5 @@ import { afterEach, expect } from "vitest"; -import { assistantMessages, describeEval } from "vitest-evals"; +import { assistantMessages, describeEval, toolCalls } from "vitest-evals"; import { closeDb, getDb } from "@/chat/db"; import { completeText, resolveGatewayModel } from "@/chat/pi/client"; import { createMemoryStore, type MemoryDb } from "@sentry/junior-memory"; @@ -338,6 +338,13 @@ describeEval("Memory Workflows", slackEvals, (it) => { }); const rows = await readMemories(passiveFirstPersonThread); + expect(toolCalls(result.session)).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: "createMemory", + }), + ]), + ); expect(rows).toContainEqual( expect.objectContaining({ archivedAtMs: null, diff --git a/packages/junior-memory/src/tools.ts b/packages/junior-memory/src/tools.ts index f63468884..89496c77d 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior-memory/src/tools.ts @@ -327,7 +327,7 @@ function compactMemory(memory: MemoryRecord) { export function createMemoryCreateTool(context: MemoryToolContext) { return { description: - "Submit an explicit memory-management request. Call only when the requester directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact about themselves. Do not call for organic statements that merely reveal a durable preference or fact; passive memory learning handles those after the visible turn. Pass one self-contained memory candidate in natural language, preserving the user's explicit memory intent as directly as possible, such as 'I prefer terse updates' or 'I think rollback plans should mention data recovery'. Do not ask the requester to rephrase ordinary technical/workflow preferences, do not rewrite first-person claims into display-name or third-person phrasing, and do not pass vague references like 'remember this'. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives all actor ids, Slack ids, scope keys, source ids, and subject ids; the memory agent decides the canonical stored content, subject, and target.", + "Explicit memory-write tool. Use only when the latest user message directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact. Do not use for ordinary statements like 'I prefer X', 'I use Y', or 'X goes before Y' unless the user also asks you to remember/store/save it; passive memory learning handles those after the visible reply. Pass one self-contained natural-language candidate preserving the user's explicit memory intent. Do not ask the user to rephrase ordinary first-person facts, and do not rewrite them into display-name or third-person wording. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives actor, scope, source, and subject ids; the memory agent decides the canonical stored content, subject, and target.", executionMode: "sequential", inputSchema: createMemoryInputSchema, execute: async (input, options) => { From 529c30013d3220d44161541293c243f14c1cf674 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 15:50:06 -0700 Subject: [PATCH 22/29] test(local): Include requester in task session fixture Persist the local requester in the fake completed-session helper so plugin task integration coverage matches the required task session contract. Repair the pnpm lockfile metadata for lint-staged so the pre-commit hook can resolve its transitive dependencies after the rebase. Co-Authored-By: GPT-5 Codex --- .../integration/local-agent-runner.test.ts | 5 + pnpm-lock.yaml | 16896 ++++++++++------ 2 files changed, 11055 insertions(+), 5846 deletions(-) diff --git a/packages/junior/tests/integration/local-agent-runner.test.ts b/packages/junior/tests/integration/local-agent-runner.test.ts index a56bfc7f0..180bcc2b9 100644 --- a/packages/junior/tests/integration/local-agent-runner.test.ts +++ b/packages/junior/tests/integration/local-agent-runner.test.ts @@ -62,6 +62,7 @@ async function persistCompletedSessionForFakeReply( await persistCompletedSessionRecord({ conversationId, destination: context.destination, + requester: context.requester, source: context.source, sessionId, sliceId: 1, @@ -294,6 +295,10 @@ describe("local agent runner", () => { }, ], sessionId: "local-turn-1", + requester: expect.objectContaining({ + platform: "local", + userId: "local-cli", + }), source: { platform: "local", type: "priv", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2c5fcd0e..4f6a442e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '9.0' +lockfileVersion: "9.0" settings: autoInstallPeers: false @@ -7,10 +7,10 @@ settings: catalogs: default: - '@sentry/node': + "@sentry/node": specifier: 10.59.0 version: 10.59.0 - '@sentry/starlight-theme': + "@sentry/starlight-theme": specifier: ^0.7.0 version: 0.7.0 drizzle-kit: @@ -25,7 +25,7 @@ catalogs: overrides: ai: 6.0.190 - '@swc/core': 1.15.33 + "@swc/core": 1.15.33 linkify-it: 5.0.0 tinyexec: 1.1.2 tldts: 7.0.30 @@ -33,13 +33,12 @@ overrides: yaml: ^2.9.0 importers: - .: devDependencies: - '@ast-grep/cli': + "@ast-grep/cli": specifier: ^0.43.0 version: 0.43.0 - '@playwright/test': + "@playwright/test": specifier: ^1.60.0 version: 1.60.0 agent-browser: @@ -66,47 +65,47 @@ importers: apps/example: dependencies: - '@sentry/junior': + "@sentry/junior": specifier: workspace:* version: file:packages/junior - '@sentry/junior-agent-browser': + "@sentry/junior-agent-browser": specifier: workspace:* version: link:../../packages/junior-agent-browser - '@sentry/junior-dashboard': + "@sentry/junior-dashboard": specifier: workspace:* version: file:packages/junior-dashboard(jiti@2.7.0) - '@sentry/junior-datadog': + "@sentry/junior-datadog": specifier: workspace:* version: link:../../packages/junior-datadog - '@sentry/junior-github': + "@sentry/junior-github": specifier: workspace:* version: link:../../packages/junior-github - '@sentry/junior-hex': + "@sentry/junior-hex": specifier: workspace:* version: link:../../packages/junior-hex - '@sentry/junior-linear': + "@sentry/junior-linear": specifier: workspace:* version: link:../../packages/junior-linear - '@sentry/junior-memory': + "@sentry/junior-memory": specifier: workspace:* version: file:packages/junior-memory - '@sentry/junior-notion': + "@sentry/junior-notion": specifier: workspace:* version: link:../../packages/junior-notion - '@sentry/junior-scheduler': + "@sentry/junior-scheduler": specifier: workspace:* version: file:packages/junior-scheduler - '@sentry/junior-sentry': + "@sentry/junior-sentry": specifier: workspace:* version: link:../../packages/junior-sentry - '@sentry/junior-vercel': + "@sentry/junior-vercel": specifier: workspace:* version: link:../../packages/junior-vercel hono: specifier: ^4.12.22 version: 4.12.22 devDependencies: - '@types/node': + "@types/node": specifier: ^25.9.1 version: 25.9.1 jiti: @@ -114,21 +113,21 @@ importers: version: 2.7.0 nitro: specifier: 3.0.260522-beta - version: 3.0.260522-beta(@vercel/blob@2.4.0)(@vercel/queue@0.2.0)(chokidar@5.0.0)(jiti@2.7.0)(lru-cache@11.5.0)(rollup@4.60.4) + version: 3.0.260522-beta(@vercel/queue@0.2.0)(jiti@2.7.0)(rollup@4.60.4) typescript: specifier: ^6.0.3 version: 6.0.3 packages/docs: dependencies: - '@astrojs/check': + "@astrojs/check": specifier: ^0.9.9 version: 0.9.9(prettier@3.8.3)(typescript@6.0.3) - '@astrojs/starlight': + "@astrojs/starlight": specifier: ^0.39.2 version: 0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3) - '@sentry/starlight-theme': - specifier: 'catalog:' + "@sentry/starlight-theme": + specifier: "catalog:" version: 0.7.0(@astrojs/starlight@0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3)) astro: specifier: ^6.3.7 @@ -148,52 +147,52 @@ importers: packages/junior: dependencies: - '@ai-sdk/gateway': + "@ai-sdk/gateway": specifier: ^3.0.119 version: 3.0.119(zod@4.4.3) - '@chat-adapter/slack': + "@chat-adapter/slack": specifier: 4.29.0 version: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@chat-adapter/state-memory': + "@chat-adapter/state-memory": specifier: 4.29.0 version: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@chat-adapter/state-redis': + "@chat-adapter/state-redis": specifier: 4.29.0 version: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@earendil-works/pi-agent-core': + "@earendil-works/pi-agent-core": specifier: 0.74.2 version: 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) - '@earendil-works/pi-ai': + "@earendil-works/pi-ai": specifier: 0.74.2 version: 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) - '@logtape/logtape': + "@logtape/logtape": specifier: ^2.1.1 version: 2.1.1 - '@modelcontextprotocol/sdk': + "@modelcontextprotocol/sdk": specifier: 1.29.0 version: 1.29.0(zod@4.4.3) - '@neondatabase/serverless': + "@neondatabase/serverless": specifier: ^1.1.0 version: 1.1.0 - '@sentry/junior-plugin-api': + "@sentry/junior-plugin-api": specifier: workspace:* version: link:../junior-plugin-api - '@sentry/node': - specifier: 'catalog:' + "@sentry/node": + specifier: "catalog:" version: 10.59.0 - '@sinclair/typebox': + "@sinclair/typebox": specifier: ^0.34.49 version: 0.34.49 - '@slack/web-api': + "@slack/web-api": specifier: ^7.16.0 version: 7.16.0 - '@vercel/functions': + "@vercel/functions": specifier: ^3.6.0 version: 3.6.0 - '@vercel/queue': + "@vercel/queue": specifier: ^0.2.0 version: 0.2.0 - '@vercel/sandbox': + "@vercel/sandbox": specifier: 2.0.0 version: 2.0.0 ai: @@ -209,7 +208,7 @@ importers: specifier: ^14.0.3 version: 14.0.3 drizzle-orm: - specifier: 'catalog:' + specifier: "catalog:" version: 0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1) hono: specifier: ^4.12.22 @@ -233,31 +232,31 @@ importers: specifier: ^2.9.0 version: 2.9.0 zod: - specifier: 'catalog:' + specifier: "catalog:" version: 4.4.3 devDependencies: - '@emnapi/core': + "@emnapi/core": specifier: ^1.10.0 version: 1.10.0 - '@emnapi/runtime': + "@emnapi/runtime": specifier: ^1.10.0 version: 1.10.0 - '@sentry/junior-memory': + "@sentry/junior-memory": specifier: workspace:* version: file:packages/junior-memory(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0) - '@sentry/junior-scheduler': + "@sentry/junior-scheduler": specifier: workspace:* version: file:packages/junior-scheduler(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0) - '@sentry/junior-testing': + "@sentry/junior-testing": specifier: workspace:* version: file:packages/junior-testing(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6) - '@types/node': + "@types/node": specifier: ^25.9.1 version: 25.9.1 - '@types/pg': + "@types/pg": specifier: ^8.15.6 version: 8.15.6 - '@vitest/coverage-v8': + "@vitest/coverage-v8": specifier: 4.1.7 version: 4.1.7(vitest@4.1.7) dependency-cruiser: @@ -289,13 +288,13 @@ importers: packages/junior-dashboard: dependencies: - '@sentry/junior': + "@sentry/junior": specifier: workspace:* version: file:packages/junior - '@sentry/junior-plugin-api': + "@sentry/junior-plugin-api": specifier: workspace:* version: link:../junior-plugin-api - '@tanstack/react-query': + "@tanstack/react-query": specifier: ^5.100.14 version: 5.100.14(react@19.2.6) better-auth: @@ -329,19 +328,19 @@ importers: specifier: 4.1.0 version: 4.1.0 devDependencies: - '@tailwindcss/cli': + "@tailwindcss/cli": specifier: ^4.3.0 version: 4.3.0 - '@types/node': + "@types/node": specifier: ^25.9.1 version: 25.9.1 - '@types/react': + "@types/react": specifier: ^19.2.15 version: 19.2.15 - '@types/react-dom': + "@types/react-dom": specifier: ^19.2.3 version: 19.2.3(@types/react@19.2.15) - '@vitest/coverage-v8': + "@vitest/coverage-v8": specifier: 4.1.7 version: 4.1.7(vitest@4.1.7) tailwindcss: @@ -361,28 +360,28 @@ importers: packages/junior-evals: devDependencies: - '@chat-adapter/slack': + "@chat-adapter/slack": specifier: 4.29.0 version: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@sentry/junior': + "@sentry/junior": specifier: workspace:* version: file:packages/junior - '@sentry/junior-github': + "@sentry/junior-github": specifier: workspace:* version: link:../junior-github - '@sentry/junior-memory': + "@sentry/junior-memory": specifier: workspace:* version: file:packages/junior-memory - '@sentry/junior-plugin-api': + "@sentry/junior-plugin-api": specifier: workspace:* version: link:../junior-plugin-api - '@sentry/junior-scheduler': + "@sentry/junior-scheduler": specifier: workspace:* version: file:packages/junior-scheduler - '@sentry/junior-sentry': + "@sentry/junior-sentry": specifier: workspace:* version: link:../junior-sentry - '@sentry/junior-testing': + "@sentry/junior-testing": specifier: workspace:* version: file:packages/junior-testing ai: @@ -404,12 +403,12 @@ importers: specifier: 0.13.1 version: 0.13.1(ai@6.0.190(zod@4.4.3))(tinyrainbow@3.1.0)(vitest@4.1.7(@types/node@25.9.1)(tsx@4.22.3))(zod@4.4.3) zod: - specifier: 'catalog:' + specifier: "catalog:" version: 4.4.3 packages/junior-github: dependencies: - '@sentry/junior-plugin-api': + "@sentry/junior-plugin-api": specifier: workspace:* version: link:../junior-plugin-api @@ -421,30 +420,30 @@ importers: packages/junior-memory: dependencies: - '@sentry/junior-plugin-api': + "@sentry/junior-plugin-api": specifier: workspace:* version: link:../junior-plugin-api - '@sinclair/typebox': + "@sinclair/typebox": specifier: ^0.34.49 version: 0.34.49 commander: specifier: ^14.0.3 version: 14.0.3 drizzle-orm: - specifier: 'catalog:' + specifier: "catalog:" version: 0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1) zod: - specifier: 'catalog:' + specifier: "catalog:" version: 4.4.3 devDependencies: - '@sentry/junior-testing': + "@sentry/junior-testing": specifier: workspace:* version: file:packages/junior-testing - '@types/node': + "@types/node": specifier: ^25.9.1 version: 25.9.1 drizzle-kit: - specifier: 'catalog:' + specifier: "catalog:" version: 0.31.10 oxlint: specifier: ^1.66.0 @@ -467,7 +466,7 @@ importers: specifier: ^14.0.3 version: 14.0.3 zod: - specifier: 'catalog:' + specifier: "catalog:" version: 4.4.3 devDependencies: oxlint: @@ -482,20 +481,20 @@ importers: packages/junior-scheduler: dependencies: - '@sentry/junior-plugin-api': + "@sentry/junior-plugin-api": specifier: workspace:* version: link:../junior-plugin-api - '@sinclair/typebox': + "@sinclair/typebox": specifier: ^0.34.49 version: 0.34.49 drizzle-orm: - specifier: 'catalog:' + specifier: "catalog:" version: 0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1) zod: - specifier: 'catalog:' + specifier: "catalog:" version: 4.4.3 devDependencies: - '@types/node': + "@types/node": specifier: ^25.9.1 version: 25.9.1 tsup: @@ -509,23 +508,23 @@ importers: packages/junior-testing: dependencies: - '@electric-sql/pglite': + "@electric-sql/pglite": specifier: ^0.4.6 version: 0.4.6 drizzle-orm: - specifier: 'catalog:' + specifier: "catalog:" version: 0.45.2(@electric-sql/pglite@0.4.6)(@types/pg@8.15.6)(pg@8.21.0) pg: specifier: ^8.16.3 version: 8.21.0 zod: - specifier: 'catalog:' + specifier: "catalog:" version: 4.4.3 devDependencies: - '@types/node': + "@types/node": specifier: ^25.9.1 version: 25.9.1 - '@types/pg': + "@types/pg": specifier: ^8.15.6 version: 8.15.6 typescript: @@ -535,25 +534,36 @@ importers: packages/junior-vercel: {} packages: - - '@ai-sdk/gateway@3.0.119': - resolution: {integrity: sha512-VAhfRWC+JexZakkVfmjaJKaTj00x7/UHdE8kMWL3NhuQAlf8oXtg9r4dfvFZrByXxchGRBvYE3biEUyibkg0xg==} - engines: {node: '>=18'} + "@ai-sdk/gateway@3.0.119": + resolution: + { + integrity: sha512-VAhfRWC+JexZakkVfmjaJKaTj00x7/UHdE8kMWL3NhuQAlf8oXtg9r4dfvFZrByXxchGRBvYE3biEUyibkg0xg==, + } + engines: { node: ">=18" } peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider-utils@4.0.27': - resolution: {integrity: sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw==} - engines: {node: '>=18'} + "@ai-sdk/provider-utils@4.0.27": + resolution: + { + integrity: sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw==, + } + engines: { node: ">=18" } peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/provider@3.0.10': - resolution: {integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==} - engines: {node: '>=18'} - - '@anthropic-ai/sdk@0.91.1': - resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==} + "@ai-sdk/provider@3.0.10": + resolution: + { + integrity: sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw==, + } + engines: { node: ">=18" } + + "@anthropic-ai/sdk@0.91.1": + resolution: + { + integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==, + } hasBin: true peerDependencies: zod: ^3.25.0 || ^4.0.0 @@ -561,2025 +571,3418 @@ packages: zod: optional: true - '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': - resolution: {integrity: sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==} - engines: {node: '>=18.0.0'} - - '@apm-js-collab/code-transformer@0.15.0': - resolution: {integrity: sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==} + "@apm-js-collab/code-transformer-bundler-plugins@0.5.0": + resolution: + { + integrity: sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==, + } + engines: { node: ">=18.0.0" } + + "@apm-js-collab/code-transformer@0.15.0": + resolution: + { + integrity: sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==, + } hasBin: true - '@apm-js-collab/tracing-hooks@0.10.0': - resolution: {integrity: sha512-2/Z3NTewJTruUkmsSnBC5bJlLNUd9keuD1OLlTEpim4FyLhm6m2Rnfv+wrFdUvFfhmH8CRdiDZBqBrn+wyaGuA==} + "@apm-js-collab/tracing-hooks@0.10.0": + resolution: + { + integrity: sha512-2/Z3NTewJTruUkmsSnBC5bJlLNUd9keuD1OLlTEpim4FyLhm6m2Rnfv+wrFdUvFfhmH8CRdiDZBqBrn+wyaGuA==, + } + + "@ast-grep/cli-darwin-arm64@0.43.0": + resolution: + { + integrity: sha512-0i63gSBbgriPaRpFsbP3yETxolHPK2JAZbpcGbFOytB7QTnKAguwhlKmIOkUGKfsCzYiEq1awY0EBmvjMONXOg==, + } + engines: { node: ">= 10" } + cpu: [arm64] + os: [darwin] - '@ast-grep/cli-darwin-x64@0.43.0': - resolution: {integrity: sha512-SPkj00HGKpYdqReUmso2ftG5Xgd+bWNFH4i9fubLxsWzn4ey2G6sotPruaOtcrzxb9xH+8kmhN7KJfm1k8Atzg==} - engines: {node: '>= 10'} + "@ast-grep/cli-darwin-x64@0.43.0": + resolution: + { + integrity: sha512-SPkj00HGKpYdqReUmso2ftG5Xgd+bWNFH4i9fubLxsWzn4ey2G6sotPruaOtcrzxb9xH+8kmhN7KJfm1k8Atzg==, + } + engines: { node: ">= 10" } cpu: [x64] os: [darwin] - '@ast-grep/cli-linux-arm64-gnu@0.43.0': - resolution: {integrity: sha512-U8+2fkcY8sBxNHHBYZ33vTa7C97GFAB+Kj6gFzVMSqK8Ve1Aw+DxhVWD4i/PBryDdmWb4/erjGSkTQtdhVa2vg==} - engines: {node: '>= 10'} + "@ast-grep/cli-linux-arm64-gnu@0.43.0": + resolution: + { + integrity: sha512-U8+2fkcY8sBxNHHBYZ33vTa7C97GFAB+Kj6gFzVMSqK8Ve1Aw+DxhVWD4i/PBryDdmWb4/erjGSkTQtdhVa2vg==, + } + engines: { node: ">= 10" } cpu: [arm64] os: [linux] libc: [glibc] - '@ast-grep/cli-linux-x64-gnu@0.43.0': - resolution: {integrity: sha512-r/o9Mag6OZmGevY9OJjatuUKDOX1rSvgo29qSfxpMbIciiH3hkzEW/2w1xTPZI8xnM7iC+k+CkGoknmoXVTYGg==} - engines: {node: '>= 10'} + "@ast-grep/cli-linux-x64-gnu@0.43.0": + resolution: + { + integrity: sha512-r/o9Mag6OZmGevY9OJjatuUKDOX1rSvgo29qSfxpMbIciiH3hkzEW/2w1xTPZI8xnM7iC+k+CkGoknmoXVTYGg==, + } + engines: { node: ">= 10" } cpu: [x64] os: [linux] libc: [glibc] - '@ast-grep/cli-win32-arm64-msvc@0.43.0': - resolution: {integrity: sha512-oHa4ruD87xccnqFuR+Pmx6F/suHV0YtibuyZ6SxUqgpNJAFZiUNAiFblzhEgQ5gp03e8B012P/Yy/7GYOvxOLg==} - engines: {node: '>= 10'} + "@ast-grep/cli-win32-arm64-msvc@0.43.0": + resolution: + { + integrity: sha512-oHa4ruD87xccnqFuR+Pmx6F/suHV0YtibuyZ6SxUqgpNJAFZiUNAiFblzhEgQ5gp03e8B012P/Yy/7GYOvxOLg==, + } + engines: { node: ">= 10" } cpu: [arm64] os: [win32] - '@ast-grep/cli-win32-ia32-msvc@0.43.0': - resolution: {integrity: sha512-RSzz9bKzSEutWgX7/g84guudEp75Q990CYpG/TBasdJP+U27zX8aA9d5p1+o/lF0hw3UoTYuFCGG8PU/QelfNQ==} - engines: {node: '>= 10'} + "@ast-grep/cli-win32-ia32-msvc@0.43.0": + resolution: + { + integrity: sha512-RSzz9bKzSEutWgX7/g84guudEp75Q990CYpG/TBasdJP+U27zX8aA9d5p1+o/lF0hw3UoTYuFCGG8PU/QelfNQ==, + } + engines: { node: ">= 10" } cpu: [ia32] os: [win32] - '@ast-grep/cli-win32-x64-msvc@0.43.0': - resolution: {integrity: sha512-/5dDD9B65vVuHCdVHN5+tIDquhE5s43S5CgEn88w1BgQaoayf+nRnUO4ZFez6SqyCGqAfa/yZdoaOQ9N2ySa1w==} - engines: {node: '>= 10'} + "@ast-grep/cli-win32-x64-msvc@0.43.0": + resolution: + { + integrity: sha512-/5dDD9B65vVuHCdVHN5+tIDquhE5s43S5CgEn88w1BgQaoayf+nRnUO4ZFez6SqyCGqAfa/yZdoaOQ9N2ySa1w==, + } + engines: { node: ">= 10" } cpu: [x64] os: [win32] - '@ast-grep/cli@0.43.0': - resolution: {integrity: sha512-DGi6xXAOBJubGg9QWqTeW8PzKSGHWEOa3uxXspEfYf532yb3lHmNJAcKMl1d+O9Xs9bTcNeDLC8se+O+tirEFQ==} - engines: {node: '>= 12.0.0'} + "@ast-grep/cli@0.43.0": + resolution: + { + integrity: sha512-DGi6xXAOBJubGg9QWqTeW8PzKSGHWEOa3uxXspEfYf532yb3lHmNJAcKMl1d+O9Xs9bTcNeDLC8se+O+tirEFQ==, + } + engines: { node: ">= 12.0.0" } hasBin: true - '@astrojs/check@0.9.9': - resolution: {integrity: sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg==} + "@astrojs/check@0.9.9": + resolution: + { + integrity: sha512-A5UW8uIuErLWEoRQvzgXpO1gTjUFtK8r7nU2Z7GewAMxUb7bPvpk11qaKKgxqXlHJWlAvaaxy+Xg28A6bmQ1Tg==, + } hasBin: true peerDependencies: typescript: ^5.0.0 || ^6.0.0 - '@astrojs/compiler@2.13.1': - resolution: {integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==} - - '@astrojs/compiler@4.0.0': - resolution: {integrity: sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==} - - '@astrojs/internal-helpers@0.9.1': - resolution: {integrity: sha512-1pWuARqYom/TzuU3+0ZugsTrKlUydWKuULmDqSMTuonY+9IRDUEGKX/8PXQ1nBxRq3w85uGtd9q9SXfqEldMIQ==} - - '@astrojs/language-server@2.16.9': - resolution: {integrity: sha512-L9kddTg+ZSO3X0Pwfx0ZPO+Z+eSSq0/39jXRyIkHzcBICzusdn2T464R4P6K0WcDZ6pMkLlFpuGS73u1pOnMSw==} + "@astrojs/compiler@2.13.1": + resolution: + { + integrity: sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==, + } + + "@astrojs/compiler@4.0.0": + resolution: + { + integrity: sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==, + } + + "@astrojs/internal-helpers@0.9.1": + resolution: + { + integrity: sha512-1pWuARqYom/TzuU3+0ZugsTrKlUydWKuULmDqSMTuonY+9IRDUEGKX/8PXQ1nBxRq3w85uGtd9q9SXfqEldMIQ==, + } + + "@astrojs/language-server@2.16.9": + resolution: + { + integrity: sha512-L9kddTg+ZSO3X0Pwfx0ZPO+Z+eSSq0/39jXRyIkHzcBICzusdn2T464R4P6K0WcDZ6pMkLlFpuGS73u1pOnMSw==, + } hasBin: true peerDependencies: prettier: ^3.0.0 - prettier-plugin-astro: '>=0.11.0' + prettier-plugin-astro: ">=0.11.0" peerDependenciesMeta: prettier: optional: true prettier-plugin-astro: optional: true - '@astrojs/markdown-remark@7.1.2': - resolution: {integrity: sha512-caXZ4Dc2St2dW8luEg22GlP0gupLdztCTQE4EzZOxW1pqWXz9mbeJEuHUkgDYcKWW8tjIHkydYDhWLVoxJ327Q==} - - '@astrojs/mdx@5.0.6': - resolution: {integrity: sha512-4dKe0ZMmqujofPNDHahzClkwinn9f8jHPcaXcgdGvPAlboD2mjzkUCofli2cBnxYAkdfhC6d50gBJ8i/cH8gHw==} - engines: {node: '>=22.12.0'} + "@astrojs/markdown-remark@7.1.2": + resolution: + { + integrity: sha512-caXZ4Dc2St2dW8luEg22GlP0gupLdztCTQE4EzZOxW1pqWXz9mbeJEuHUkgDYcKWW8tjIHkydYDhWLVoxJ327Q==, + } + + "@astrojs/mdx@5.0.6": + resolution: + { + integrity: sha512-4dKe0ZMmqujofPNDHahzClkwinn9f8jHPcaXcgdGvPAlboD2mjzkUCofli2cBnxYAkdfhC6d50gBJ8i/cH8gHw==, + } + engines: { node: ">=22.12.0" } peerDependencies: astro: ^6.0.0 - '@astrojs/prism@4.0.2': - resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==} - engines: {node: '>=22.12.0'} - - '@astrojs/sitemap@3.7.2': - resolution: {integrity: sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA==} - - '@astrojs/starlight@0.39.2': - resolution: {integrity: sha512-vlw+bwnjtf5buCTUtLU7JfV6D3knslxqnspr6LKs6hfRuFZiyr5hT44F7GyDqR9FKANUqFxnIzWM81F1k/kOUA==} + "@astrojs/prism@4.0.2": + resolution: + { + integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==, + } + engines: { node: ">=22.12.0" } + + "@astrojs/sitemap@3.7.2": + resolution: + { + integrity: sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA==, + } + + "@astrojs/starlight@0.39.2": + resolution: + { + integrity: sha512-vlw+bwnjtf5buCTUtLU7JfV6D3knslxqnspr6LKs6hfRuFZiyr5hT44F7GyDqR9FKANUqFxnIzWM81F1k/kOUA==, + } peerDependencies: astro: ^6.0.0 - '@astrojs/telemetry@3.3.2': - resolution: {integrity: sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==} - engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} - - '@astrojs/yaml2ts@0.2.4': - resolution: {integrity: sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==} - - '@aws-crypto/crc32@5.2.0': - resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} - engines: {node: '>=16.0.0'} - - '@aws-crypto/sha256-browser@5.2.0': - resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} - - '@aws-crypto/sha256-js@5.2.0': - resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} - engines: {node: '>=16.0.0'} - - '@aws-crypto/supports-web-crypto@5.2.0': - resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} - - '@aws-crypto/util@5.2.0': - resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - - '@aws-sdk/client-bedrock-runtime@3.1048.0': - resolution: {integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/core@3.974.13': - resolution: {integrity: sha512-+Y5/4tHki0uYgyx8eun146DegRVQBpdKGK5RbV0FTKJPpaKTchvqVxrrRFK6Wk0JksO4iAZKw3eqxGEIwtO98w==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-env@3.972.39': - resolution: {integrity: sha512-29wX9zpAvEt1vcj0psha+y6ygBHy2V/S72mp6e7q0KARLWXq+pwE/lR6qGkwknQvruh52lXvlqZIga8Hdxkucw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-http@3.972.41': - resolution: {integrity: sha512-IA3CQTjtJkb6u1H4mE4936c8OPBMa9Jggtwe8U2Mqw/vvb/tZ5Ebd0mcZcX0uKWQhOyYo/+qNIwkV5Xh+FeJJA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-ini@3.972.43': - resolution: {integrity: sha512-4mzII+3mZEVXXE1xzrLQrCJL7/r62A63bA6SVzZoNL5rqCJghpf+xgGltVrIBBs0n+mOZBKrQl2tRREtvZ5l6A==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-login@3.972.43': - resolution: {integrity: sha512-HG7kQCwXtbv3oBV61Ins0oNX8KKyvrMqqRkb6ZiAfQHbMuHaiNaEb2KnpKLPkNpqImSBK82UkVE/kaY6IfWikA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-node@3.972.44': - resolution: {integrity: sha512-sDaBIT0yrNNIPfvlsiTCmANm07zKju+ipWODjEXgZlsjMeIJR3LVp7RDyAOzUoAsTbDfYKDWp+i5WrFiQP6rmQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-process@3.972.39': - resolution: {integrity: sha512-2k/amBifLd75eXNwgvPw/2lKYSQ3NhvHQgkVKVjfUq13/eJ3JRtHmznuFenn74OK3sSfp4SMy1YB2w+UVXoKqA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-sso@3.972.43': - resolution: {integrity: sha512-LPc3+Y4vhH1T4x6CMqwCM6hk5+SRf/Lwmgm8INm95wxTtIRHcMwQUVkDzWu4Iw/RSncxYM2BC01OrYbxOPZvyg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/credential-provider-web-identity@3.972.43': - resolution: {integrity: sha512-wQtL34lUD/09VXjwAUo2T+I3aEXRDxMB3DKmTJL/Zj0Gi6sLDTrVhae1XVt01yzkquOWajI/sZW72JGDZ1ciTw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/eventstream-handler-node@3.972.17': - resolution: {integrity: sha512-WFwdNcjchKZr7jKYgGimUZO8sSKQF/le7GGqgeCzz/lHozInE6b0gFJ1YMr8NaIeAoWJwgtrF7RE4/qMgosAdQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-eventstream@3.972.13': - resolution: {integrity: sha512-ECfsw7mf6G/sxNbKbGE3/h1xeIArY/yRI1IjDGYkLgDIankh+aDOtDRSr40LVlIHGL9+jEH1cVuxmbJ8NLL/1A==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/middleware-websocket@3.972.21': - resolution: {integrity: sha512-yr+5+C7v9R55sAJ89A55Wrm7wIKPVn5cm6J3Hztnd5s/iwEUKxyJqCnIxJu4fVXgG9XBQD1Jc4rsWC1ozahJjA==} - engines: {node: '>= 14.0.0'} - - '@aws-sdk/nested-clients@3.997.11': - resolution: {integrity: sha512-nWXXJ1r/r8N2Gw1pWolRgED38/A9A8DHR2ETWIv220zh4PZHcybbR4hUVWWktmNXTRHzDJwRluapHn0rZxuoqA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/signature-v4-multi-region@3.996.28': - resolution: {integrity: sha512-qs9z5LqXO/CZC2Lg9SGKpoLU8Rhi+m2pFKZqfO9pytX1clc0katqtsDNupJxFy0xT9wsZSPzM2v1y+/H/zfp5Q==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/token-providers@3.1048.0': - resolution: {integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/token-providers@3.1052.0': - resolution: {integrity: sha512-QqZNB3so7UIDxZtroc85TQaLVxdZRFm0eWM1CSR2N+b06as9TOrilvrlTZuj3guYlxMs6yLOgGxnklJ5qMYtTw==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/types@3.973.9': - resolution: {integrity: sha512-kuBfgQVdcz5Bmapc4A13YbpVw/pXkesfhetcFYwbntqas8sF41OHyd4o28+/TG2ZQdHBsv90Lsu5y6oitvYCdg==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-locate-window@3.965.5': - resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/xml-builder@3.972.25': - resolution: {integrity: sha512-GH+Kjz4nPKWKHnsiQpnhP1MJdTGIcK4rAka6tzakgjjUkVgNsmPeEbbRAf09SzS1hjGu6duGHCBsxYke0BhHjQ==} - engines: {node: '>=20.0.0'} - - '@aws/lambda-invoke-store@0.2.4': - resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} - engines: {node: '>=18.0.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.29.3': - resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} - engines: {node: '>=6.0.0'} + "@astrojs/telemetry@3.3.2": + resolution: + { + integrity: sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==, + } + engines: { node: 18.20.8 || ^20.3.0 || >=22.0.0 } + + "@astrojs/yaml2ts@0.2.4": + resolution: + { + integrity: sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==, + } + + "@aws-crypto/crc32@5.2.0": + resolution: + { + integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==, + } + engines: { node: ">=16.0.0" } + + "@aws-crypto/sha256-browser@5.2.0": + resolution: + { + integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==, + } + + "@aws-crypto/sha256-js@5.2.0": + resolution: + { + integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==, + } + engines: { node: ">=16.0.0" } + + "@aws-crypto/supports-web-crypto@5.2.0": + resolution: + { + integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==, + } + + "@aws-crypto/util@5.2.0": + resolution: + { + integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==, + } + + "@aws-sdk/client-bedrock-runtime@3.1048.0": + resolution: + { + integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/core@3.974.13": + resolution: + { + integrity: sha512-+Y5/4tHki0uYgyx8eun146DegRVQBpdKGK5RbV0FTKJPpaKTchvqVxrrRFK6Wk0JksO4iAZKw3eqxGEIwtO98w==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-env@3.972.39": + resolution: + { + integrity: sha512-29wX9zpAvEt1vcj0psha+y6ygBHy2V/S72mp6e7q0KARLWXq+pwE/lR6qGkwknQvruh52lXvlqZIga8Hdxkucw==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-http@3.972.41": + resolution: + { + integrity: sha512-IA3CQTjtJkb6u1H4mE4936c8OPBMa9Jggtwe8U2Mqw/vvb/tZ5Ebd0mcZcX0uKWQhOyYo/+qNIwkV5Xh+FeJJA==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-ini@3.972.43": + resolution: + { + integrity: sha512-4mzII+3mZEVXXE1xzrLQrCJL7/r62A63bA6SVzZoNL5rqCJghpf+xgGltVrIBBs0n+mOZBKrQl2tRREtvZ5l6A==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-login@3.972.43": + resolution: + { + integrity: sha512-HG7kQCwXtbv3oBV61Ins0oNX8KKyvrMqqRkb6ZiAfQHbMuHaiNaEb2KnpKLPkNpqImSBK82UkVE/kaY6IfWikA==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-node@3.972.44": + resolution: + { + integrity: sha512-sDaBIT0yrNNIPfvlsiTCmANm07zKju+ipWODjEXgZlsjMeIJR3LVp7RDyAOzUoAsTbDfYKDWp+i5WrFiQP6rmQ==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-process@3.972.39": + resolution: + { + integrity: sha512-2k/amBifLd75eXNwgvPw/2lKYSQ3NhvHQgkVKVjfUq13/eJ3JRtHmznuFenn74OK3sSfp4SMy1YB2w+UVXoKqA==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-sso@3.972.43": + resolution: + { + integrity: sha512-LPc3+Y4vhH1T4x6CMqwCM6hk5+SRf/Lwmgm8INm95wxTtIRHcMwQUVkDzWu4Iw/RSncxYM2BC01OrYbxOPZvyg==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/credential-provider-web-identity@3.972.43": + resolution: + { + integrity: sha512-wQtL34lUD/09VXjwAUo2T+I3aEXRDxMB3DKmTJL/Zj0Gi6sLDTrVhae1XVt01yzkquOWajI/sZW72JGDZ1ciTw==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/eventstream-handler-node@3.972.17": + resolution: + { + integrity: sha512-WFwdNcjchKZr7jKYgGimUZO8sSKQF/le7GGqgeCzz/lHozInE6b0gFJ1YMr8NaIeAoWJwgtrF7RE4/qMgosAdQ==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/middleware-eventstream@3.972.13": + resolution: + { + integrity: sha512-ECfsw7mf6G/sxNbKbGE3/h1xeIArY/yRI1IjDGYkLgDIankh+aDOtDRSr40LVlIHGL9+jEH1cVuxmbJ8NLL/1A==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/middleware-websocket@3.972.21": + resolution: + { + integrity: sha512-yr+5+C7v9R55sAJ89A55Wrm7wIKPVn5cm6J3Hztnd5s/iwEUKxyJqCnIxJu4fVXgG9XBQD1Jc4rsWC1ozahJjA==, + } + engines: { node: ">= 14.0.0" } + + "@aws-sdk/nested-clients@3.997.11": + resolution: + { + integrity: sha512-nWXXJ1r/r8N2Gw1pWolRgED38/A9A8DHR2ETWIv220zh4PZHcybbR4hUVWWktmNXTRHzDJwRluapHn0rZxuoqA==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/signature-v4-multi-region@3.996.28": + resolution: + { + integrity: sha512-qs9z5LqXO/CZC2Lg9SGKpoLU8Rhi+m2pFKZqfO9pytX1clc0katqtsDNupJxFy0xT9wsZSPzM2v1y+/H/zfp5Q==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/token-providers@3.1048.0": + resolution: + { + integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/token-providers@3.1052.0": + resolution: + { + integrity: sha512-QqZNB3so7UIDxZtroc85TQaLVxdZRFm0eWM1CSR2N+b06as9TOrilvrlTZuj3guYlxMs6yLOgGxnklJ5qMYtTw==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/types@3.973.9": + resolution: + { + integrity: sha512-kuBfgQVdcz5Bmapc4A13YbpVw/pXkesfhetcFYwbntqas8sF41OHyd4o28+/TG2ZQdHBsv90Lsu5y6oitvYCdg==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/util-locate-window@3.965.5": + resolution: + { + integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==, + } + engines: { node: ">=20.0.0" } + + "@aws-sdk/xml-builder@3.972.25": + resolution: + { + integrity: sha512-GH+Kjz4nPKWKHnsiQpnhP1MJdTGIcK4rAka6tzakgjjUkVgNsmPeEbbRAf09SzS1hjGu6duGHCBsxYke0BhHjQ==, + } + engines: { node: ">=20.0.0" } + + "@aws/lambda-invoke-store@0.2.4": + resolution: + { + integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==, + } + engines: { node: ">=18.0.0" } + + "@babel/helper-string-parser@7.27.1": + resolution: + { + integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, + } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.28.5": + resolution: + { + integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==, + } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.29.3": + resolution: + { + integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==, + } + engines: { node: ">=6.0.0" } hasBin: true - '@babel/runtime@7.29.2': - resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - - '@bcoe/v8-coverage@1.0.2': - resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} - engines: {node: '>=18'} - - '@better-auth/core@1.6.11': - resolution: {integrity: sha512-LrwidLCV8azdMGjvtwp30nj9tIv1BwI3VhtC0UaGSjQkAVWw4bN42I8qwbxRziPeSQoj+zUVkOpxZzAWBDARtQ==} + "@babel/runtime@7.29.2": + resolution: + { + integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==, + } + engines: { node: ">=6.9.0" } + + "@babel/types@7.29.0": + resolution: + { + integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==, + } + engines: { node: ">=6.9.0" } + + "@bcoe/v8-coverage@1.0.2": + resolution: + { + integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==, + } + engines: { node: ">=18" } + + "@better-auth/core@1.6.11": + resolution: + { + integrity: sha512-LrwidLCV8azdMGjvtwp30nj9tIv1BwI3VhtC0UaGSjQkAVWw4bN42I8qwbxRziPeSQoj+zUVkOpxZzAWBDARtQ==, + } peerDependencies: - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 - '@cloudflare/workers-types': '>=4' - '@opentelemetry/api': ^1.9.0 + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 + "@cloudflare/workers-types": ">=4" + "@opentelemetry/api": ^1.9.0 better-call: 1.3.5 jose: ^6.1.0 kysely: ^0.28.5 nanostores: ^1.0.1 peerDependenciesMeta: - '@cloudflare/workers-types': + "@cloudflare/workers-types": optional: true - '@opentelemetry/api': + "@opentelemetry/api": optional: true - '@better-auth/drizzle-adapter@1.6.11': - resolution: {integrity: sha512-4jpkETIGZOHCf7BK4jnu22fdN6jjomH0/HhEzkaWy3+Eppi5PYlHTF/460jrTmA3Xc+Vqwp9t282ymHiEPypGw==} + "@better-auth/drizzle-adapter@1.6.11": + resolution: + { + integrity: sha512-4jpkETIGZOHCf7BK4jnu22fdN6jjomH0/HhEzkaWy3+Eppi5PYlHTF/460jrTmA3Xc+Vqwp9t282ymHiEPypGw==, + } peerDependencies: - '@better-auth/core': ^1.6.11 - '@better-auth/utils': 0.4.0 + "@better-auth/core": ^1.6.11 + "@better-auth/utils": 0.4.0 drizzle-orm: ^0.45.2 peerDependenciesMeta: drizzle-orm: optional: true - '@better-auth/kysely-adapter@1.6.11': - resolution: {integrity: sha512-/g8M9RfIjdcZDnbstSUvQiINkvdNlCeZr248zwqx2/PVksQI1MhQofbzUn3RnQnbPKp0EPwpX/dR3oudRFenUg==} + "@better-auth/kysely-adapter@1.6.11": + resolution: + { + integrity: sha512-/g8M9RfIjdcZDnbstSUvQiINkvdNlCeZr248zwqx2/PVksQI1MhQofbzUn3RnQnbPKp0EPwpX/dR3oudRFenUg==, + } peerDependencies: - '@better-auth/core': ^1.6.11 - '@better-auth/utils': 0.4.0 + "@better-auth/core": ^1.6.11 + "@better-auth/utils": 0.4.0 kysely: ^0.28.17 peerDependenciesMeta: kysely: optional: true - '@better-auth/memory-adapter@1.6.11': - resolution: {integrity: sha512-hpdfw0BBf8MuzLkIdmbcUZICbY9r/bhLO2RxSnkzT5+/O+0I0u2I8+m0YUP7vNllP/ZCKASHOYgXPLO75Z0f9Q==} + "@better-auth/memory-adapter@1.6.11": + resolution: + { + integrity: sha512-hpdfw0BBf8MuzLkIdmbcUZICbY9r/bhLO2RxSnkzT5+/O+0I0u2I8+m0YUP7vNllP/ZCKASHOYgXPLO75Z0f9Q==, + } peerDependencies: - '@better-auth/core': ^1.6.11 - '@better-auth/utils': 0.4.0 - - '@better-auth/mongo-adapter@1.6.11': - resolution: {integrity: sha512-3Tor8rSv8vSEIMEaV2PFpPEuVhqc1gNoZ6eGvoh3LwExXXuj8madew6ob+H1pH7Aphn3Ar5PQ08AguT8TbwFAA==} + "@better-auth/core": ^1.6.11 + "@better-auth/utils": 0.4.0 + + "@better-auth/mongo-adapter@1.6.11": + resolution: + { + integrity: sha512-3Tor8rSv8vSEIMEaV2PFpPEuVhqc1gNoZ6eGvoh3LwExXXuj8madew6ob+H1pH7Aphn3Ar5PQ08AguT8TbwFAA==, + } peerDependencies: - '@better-auth/core': ^1.6.11 - '@better-auth/utils': 0.4.0 + "@better-auth/core": ^1.6.11 + "@better-auth/utils": 0.4.0 mongodb: ^6.0.0 || ^7.0.0 peerDependenciesMeta: mongodb: optional: true - '@better-auth/prisma-adapter@1.6.11': - resolution: {integrity: sha512-Pw+7q7zTp+VSci1V+CYMvuxIbAeVMZLe4lRo46LJoAKMHfjFl5T/ycsyFvWs/DkWC7n9gZZzRDEbHp0I5FiKKw==} + "@better-auth/prisma-adapter@1.6.11": + resolution: + { + integrity: sha512-Pw+7q7zTp+VSci1V+CYMvuxIbAeVMZLe4lRo46LJoAKMHfjFl5T/ycsyFvWs/DkWC7n9gZZzRDEbHp0I5FiKKw==, + } peerDependencies: - '@better-auth/core': ^1.6.11 - '@better-auth/utils': 0.4.0 - '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 + "@better-auth/core": ^1.6.11 + "@better-auth/utils": 0.4.0 + "@prisma/client": ^5.0.0 || ^6.0.0 || ^7.0.0 prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: - '@prisma/client': + "@prisma/client": optional: true prisma: optional: true - '@better-auth/telemetry@1.6.11': - resolution: {integrity: sha512-hsjDHc8MZbm6/AHeNdtywrWedXevnBjmdvnHTcZub+rTVjOv+Td0roI8USKuC6uUibmrl//2rJfVCsGbopihNA==} + "@better-auth/telemetry@1.6.11": + resolution: + { + integrity: sha512-hsjDHc8MZbm6/AHeNdtywrWedXevnBjmdvnHTcZub+rTVjOv+Td0roI8USKuC6uUibmrl//2rJfVCsGbopihNA==, + } peerDependencies: - '@better-auth/core': ^1.6.11 - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 - - '@better-auth/utils@0.4.0': - resolution: {integrity: sha512-RpMtLUIQAEWMgdPLNVbIF5ON2mm+CH0U3rCdUCU1VyeAUui4m38DyK7/aXMLZov2YDjG684pS1D0MBllrmgjQA==} - - '@better-fetch/fetch@1.1.21': - resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==} - - '@borewit/text-codec@0.2.2': - resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} - - '@bytecodealliance/preview2-shim@0.17.6': - resolution: {integrity: sha512-n3cM88gTen5980UOBAD6xDcNNL3ocTK8keab21bpx1ONdA+ARj7uD1qoFxOWCyKlkpSi195FH+GeAut7Oc6zZw==} - - '@capsizecss/unpack@4.0.0': - resolution: {integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==} - engines: {node: '>=18'} - - '@chat-adapter/shared@4.29.0': - resolution: {integrity: sha512-ARqTDoHJHKN9rpytbFPJbNmqqx3fOg5xwsTZdlingQPAssOSeHDBdqrFJkgDhyCRGbmDtG09cuS0FkVzeoh2qg==} - engines: {node: '>=20'} - - '@chat-adapter/slack@4.29.0': - resolution: {integrity: sha512-s2DXAwkTpmiIKSATXgrO879s1pqFwS70Y0JPd+TRGRzDeh6nfqt5dnKt5Bug0P1zwkB6DoPurhnYS9nqhSmD/w==} - engines: {node: '>=20'} - - '@chat-adapter/state-memory@4.29.0': - resolution: {integrity: sha512-+L5LPj9VkyXFXAcfFlTvf2JihuFfQV5U9TfXDlQeG7k6NMEA8irt4a0c6MTxFP7OI5YENknVwRGzmcUubvEWSw==} - engines: {node: '>=20'} - - '@chat-adapter/state-redis@4.29.0': - resolution: {integrity: sha512-Nn/PMSrkavIwFbNt1yyIZ0VZ1b5hT8Gw0Ujcnvnv+JlfBGz44XEE0/+NRLRx07mDndov1MlUkGjBHuKPZcS1Tg==} - engines: {node: '>=20'} - - '@clack/core@1.3.1': - resolution: {integrity: sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==} - engines: {node: '>= 20.12.0'} - - '@clack/prompts@1.4.0': - resolution: {integrity: sha512-S0My7XPGIgpRWMDG8uRqalbgT+a6FmCUdOW+HaIOVVpUPHOb7RrpvjTjiODadKp06fsrVDJZlIzc6yCTp4AnxA==} - engines: {node: '>= 20.12.0'} - - '@ctrl/tinycolor@4.2.0': - resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} - engines: {node: '>=14'} - - '@drizzle-team/brocli@0.10.2': - resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} - - '@earendil-works/pi-agent-core@0.74.2': - resolution: {integrity: sha512-RPlB3bi2z+VQK0HRhBK73kXOQI1fFmRgWzzT6+ihB7JYfh29jb7eAfYvpx8rlf248gUAYaLQ8JYa+43l09rPmQ==} - engines: {node: '>=20.0.0'} - - '@earendil-works/pi-ai@0.74.2': - resolution: {integrity: sha512-ukQBHGDm20k9ZUS2cGjNN9vDJp/48r35xmvgSx3paCaC06r2N/PLuRZoJmwQ1ZM7f8T3072odv9YPWn+77w0LA==} - engines: {node: '>=20.0.0'} + "@better-auth/core": ^1.6.11 + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 + + "@better-auth/utils@0.4.0": + resolution: + { + integrity: sha512-RpMtLUIQAEWMgdPLNVbIF5ON2mm+CH0U3rCdUCU1VyeAUui4m38DyK7/aXMLZov2YDjG684pS1D0MBllrmgjQA==, + } + + "@better-fetch/fetch@1.1.21": + resolution: + { + integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==, + } + + "@borewit/text-codec@0.2.2": + resolution: + { + integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==, + } + + "@bytecodealliance/preview2-shim@0.17.6": + resolution: + { + integrity: sha512-n3cM88gTen5980UOBAD6xDcNNL3ocTK8keab21bpx1ONdA+ARj7uD1qoFxOWCyKlkpSi195FH+GeAut7Oc6zZw==, + } + + "@capsizecss/unpack@4.0.0": + resolution: + { + integrity: sha512-VERIM64vtTP1C4mxQ5thVT9fK0apjPFobqybMtA1UdUujWka24ERHbRHFGmpbbhp73MhV+KSsHQH9C6uOTdEQA==, + } + engines: { node: ">=18" } + + "@chat-adapter/shared@4.29.0": + resolution: + { + integrity: sha512-ARqTDoHJHKN9rpytbFPJbNmqqx3fOg5xwsTZdlingQPAssOSeHDBdqrFJkgDhyCRGbmDtG09cuS0FkVzeoh2qg==, + } + engines: { node: ">=20" } + + "@chat-adapter/slack@4.29.0": + resolution: + { + integrity: sha512-s2DXAwkTpmiIKSATXgrO879s1pqFwS70Y0JPd+TRGRzDeh6nfqt5dnKt5Bug0P1zwkB6DoPurhnYS9nqhSmD/w==, + } + engines: { node: ">=20" } + + "@chat-adapter/state-memory@4.29.0": + resolution: + { + integrity: sha512-+L5LPj9VkyXFXAcfFlTvf2JihuFfQV5U9TfXDlQeG7k6NMEA8irt4a0c6MTxFP7OI5YENknVwRGzmcUubvEWSw==, + } + engines: { node: ">=20" } + + "@chat-adapter/state-redis@4.29.0": + resolution: + { + integrity: sha512-Nn/PMSrkavIwFbNt1yyIZ0VZ1b5hT8Gw0Ujcnvnv+JlfBGz44XEE0/+NRLRx07mDndov1MlUkGjBHuKPZcS1Tg==, + } + engines: { node: ">=20" } + + "@clack/core@1.3.1": + resolution: + { + integrity: sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==, + } + engines: { node: ">= 20.12.0" } + + "@clack/prompts@1.4.0": + resolution: + { + integrity: sha512-S0My7XPGIgpRWMDG8uRqalbgT+a6FmCUdOW+HaIOVVpUPHOb7RrpvjTjiODadKp06fsrVDJZlIzc6yCTp4AnxA==, + } + engines: { node: ">= 20.12.0" } + + "@ctrl/tinycolor@4.2.0": + resolution: + { + integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==, + } + engines: { node: ">=14" } + + "@drizzle-team/brocli@0.10.2": + resolution: + { + integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==, + } + + "@earendil-works/pi-agent-core@0.74.2": + resolution: + { + integrity: sha512-RPlB3bi2z+VQK0HRhBK73kXOQI1fFmRgWzzT6+ihB7JYfh29jb7eAfYvpx8rlf248gUAYaLQ8JYa+43l09rPmQ==, + } + engines: { node: ">=20.0.0" } + + "@earendil-works/pi-ai@0.74.2": + resolution: + { + integrity: sha512-ukQBHGDm20k9ZUS2cGjNN9vDJp/48r35xmvgSx3paCaC06r2N/PLuRZoJmwQ1ZM7f8T3072odv9YPWn+77w0LA==, + } + engines: { node: ">=20.0.0" } hasBin: true - '@edge-runtime/format@2.2.1': - resolution: {integrity: sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==} - engines: {node: '>=16'} - - '@edge-runtime/node-utils@2.3.0': - resolution: {integrity: sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==} - engines: {node: '>=16'} - - '@edge-runtime/ponyfill@2.4.2': - resolution: {integrity: sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==} - engines: {node: '>=16'} - - '@edge-runtime/primitives@4.1.0': - resolution: {integrity: sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==} - engines: {node: '>=16'} - - '@edge-runtime/vm@3.2.0': - resolution: {integrity: sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==} - engines: {node: '>=16'} - - '@electric-sql/pglite@0.4.6': - resolution: {integrity: sha512-qmlmfN8UyKCee35qkV0r/MBp+Znl8FjBz7OpoglNvww3GJpw0/DLP0o1ZymvLNmcD5DTLOQdzKPtF8Hd3mdl1w==} - - '@emmetio/abbreviation@2.3.3': - resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==} - - '@emmetio/css-abbreviation@2.1.8': - resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==} - - '@emmetio/css-parser@0.4.1': - resolution: {integrity: sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==} - - '@emmetio/html-matcher@1.3.0': - resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==} - - '@emmetio/scanner@1.0.4': - resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==} - - '@emmetio/stream-reader-utils@0.1.0': - resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==} - - '@emmetio/stream-reader@2.2.0': - resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==} - - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - deprecated: 'Merged into tsx: https://tsx.is' - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - deprecated: 'Merged into tsx: https://tsx.is' + "@edge-runtime/format@2.2.1": + resolution: + { + integrity: sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==, + } + engines: { node: ">=16" } + + "@edge-runtime/node-utils@2.3.0": + resolution: + { + integrity: sha512-uUtx8BFoO1hNxtHjp3eqVPC/mWImGb2exOfGjMLUoipuWgjej+f4o/VP4bUI8U40gu7Teogd5VTeZUkGvJSPOQ==, + } + engines: { node: ">=16" } + + "@edge-runtime/ponyfill@2.4.2": + resolution: + { + integrity: sha512-oN17GjFr69chu6sDLvXxdhg0Qe8EZviGSuqzR9qOiKh4MhFYGdBBcqRNzdmYeAdeRzOW2mM9yil4RftUQ7sUOA==, + } + engines: { node: ">=16" } + + "@edge-runtime/primitives@4.1.0": + resolution: + { + integrity: sha512-Vw0lbJ2lvRUqc7/soqygUX216Xb8T3WBZ987oywz6aJqRxcwSVWwr9e+Nqo2m9bxobA9mdbWNNoRY6S9eko1EQ==, + } + engines: { node: ">=16" } + + "@edge-runtime/vm@3.2.0": + resolution: + { + integrity: sha512-0dEVyRLM/lG4gp1R/Ik5bfPl/1wX00xFwd5KcNH602tzBa09oF7pbTKETEhR1GjZ75K6OJnYFu8II2dyMhONMw==, + } + engines: { node: ">=16" } + + "@electric-sql/pglite@0.4.6": + resolution: + { + integrity: sha512-qmlmfN8UyKCee35qkV0r/MBp+Znl8FjBz7OpoglNvww3GJpw0/DLP0o1ZymvLNmcD5DTLOQdzKPtF8Hd3mdl1w==, + } + + "@emmetio/abbreviation@2.3.3": + resolution: + { + integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==, + } + + "@emmetio/css-abbreviation@2.1.8": + resolution: + { + integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==, + } + + "@emmetio/css-parser@0.4.1": + resolution: + { + integrity: sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==, + } + + "@emmetio/html-matcher@1.3.0": + resolution: + { + integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==, + } + + "@emmetio/scanner@1.0.4": + resolution: + { + integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==, + } + + "@emmetio/stream-reader-utils@0.1.0": + resolution: + { + integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==, + } + + "@emmetio/stream-reader@2.2.0": + resolution: + { + integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==, + } + + "@emnapi/core@1.10.0": + resolution: + { + integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==, + } + + "@emnapi/runtime@1.10.0": + resolution: + { + integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==, + } + + "@emnapi/wasi-threads@1.2.1": + resolution: + { + integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==, + } + + "@esbuild-kit/core-utils@3.3.2": + resolution: + { + integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==, + } + deprecated: "Merged into tsx: https://tsx.is" + + "@esbuild-kit/esm-loader@2.6.5": + resolution: + { + integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==, + } + deprecated: "Merged into tsx: https://tsx.is" + + "@esbuild/aix-ppc64@0.25.12": + resolution: + { + integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [aix] - '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} + "@esbuild/aix-ppc64@0.27.0": + resolution: + { + integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.0': - resolution: {integrity: sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==} - engines: {node: '>=18'} + "@esbuild/aix-ppc64@0.27.7": + resolution: + { + integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.27.7': - resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} - engines: {node: '>=18'} + "@esbuild/aix-ppc64@0.28.1": + resolution: + { + integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.18.20': - resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} - engines: {node: '>=12'} + "@esbuild/android-arm64@0.18.20": + resolution: + { + integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==, + } + engines: { node: ">=12" } + cpu: [arm64] + os: [android] + + "@esbuild/android-arm64@0.25.12": + resolution: + { + integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.27.0": + resolution: + { + integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.0': - resolution: {integrity: sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.27.7": + resolution: + { + integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.27.7': - resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} - engines: {node: '>=18'} + "@esbuild/android-arm64@0.28.1": + resolution: + { + integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [android] - '@esbuild/android-arm@0.18.20': - resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} - engines: {node: '>=12'} + "@esbuild/android-arm@0.18.20": + resolution: + { + integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==, + } + engines: { node: ">=12" } cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.25.12": + resolution: + { + integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.0': - resolution: {integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.27.0": + resolution: + { + integrity: sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-arm@0.27.7': - resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} - engines: {node: '>=18'} + "@esbuild/android-arm@0.27.7": + resolution: + { + integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==, + } + engines: { node: ">=18" } cpu: [arm] os: [android] - '@esbuild/android-x64@0.18.20': - resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} - engines: {node: '>=12'} + "@esbuild/android-arm@0.28.1": + resolution: + { + integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [android] + + "@esbuild/android-x64@0.18.20": + resolution: + { + integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [android] + + "@esbuild/android-x64@0.25.12": + resolution: + { + integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.27.0": + resolution: + { + integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.0': - resolution: {integrity: sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.27.7": + resolution: + { + integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/android-x64@0.27.7': - resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} - engines: {node: '>=18'} + "@esbuild/android-x64@0.28.1": + resolution: + { + integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==, + } + engines: { node: ">=18" } cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.18.20': - resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} - engines: {node: '>=12'} + "@esbuild/darwin-arm64@0.18.20": + resolution: + { + integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==, + } + engines: { node: ">=12" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.25.12": + resolution: + { + integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.0': - resolution: {integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.27.0": + resolution: + { + integrity: sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.27.7': - resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} - engines: {node: '>=18'} + "@esbuild/darwin-arm64@0.27.7": + resolution: + { + integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.18.20': - resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} - engines: {node: '>=12'} + "@esbuild/darwin-arm64@0.28.1": + resolution: + { + integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [darwin] + + "@esbuild/darwin-x64@0.18.20": + resolution: + { + integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [darwin] + + "@esbuild/darwin-x64@0.25.12": + resolution: + { + integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.27.0": + resolution: + { + integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.0': - resolution: {integrity: sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.27.7": + resolution: + { + integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.27.7': - resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} - engines: {node: '>=18'} + "@esbuild/darwin-x64@0.28.1": + resolution: + { + integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.18.20': - resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} - engines: {node: '>=12'} + "@esbuild/freebsd-arm64@0.18.20": + resolution: + { + integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==, + } + engines: { node: ">=12" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.25.12": + resolution: + { + integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.0': - resolution: {integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.27.0": + resolution: + { + integrity: sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.27.7': - resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} - engines: {node: '>=18'} + "@esbuild/freebsd-arm64@0.27.7": + resolution: + { + integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==, + } + engines: { node: ">=18" } cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.18.20': - resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} - engines: {node: '>=12'} + "@esbuild/freebsd-arm64@0.28.1": + resolution: + { + integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.18.20": + resolution: + { + integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [freebsd] + + "@esbuild/freebsd-x64@0.25.12": + resolution: + { + integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.27.0": + resolution: + { + integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.0': - resolution: {integrity: sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.27.7": + resolution: + { + integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.27.7': - resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} - engines: {node: '>=18'} + "@esbuild/freebsd-x64@0.28.1": + resolution: + { + integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.18.20': - resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} - engines: {node: '>=12'} + "@esbuild/linux-arm64@0.18.20": + resolution: + { + integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==, + } + engines: { node: ">=12" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.25.12": + resolution: + { + integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.0': - resolution: {integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.27.0": + resolution: + { + integrity: sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.27.7': - resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} - engines: {node: '>=18'} + "@esbuild/linux-arm64@0.27.7": + resolution: + { + integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==, + } + engines: { node: ">=18" } cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.18.20': - resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} - engines: {node: '>=12'} + "@esbuild/linux-arm64@0.28.1": + resolution: + { + integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [linux] + + "@esbuild/linux-arm@0.18.20": + resolution: + { + integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==, + } + engines: { node: ">=12" } cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.25.12": + resolution: + { + integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.0': - resolution: {integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.27.0": + resolution: + { + integrity: sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.27.7': - resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} - engines: {node: '>=18'} + "@esbuild/linux-arm@0.27.7": + resolution: + { + integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==, + } + engines: { node: ">=18" } cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.18.20': - resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} - engines: {node: '>=12'} + "@esbuild/linux-arm@0.28.1": + resolution: + { + integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==, + } + engines: { node: ">=18" } + cpu: [arm] + os: [linux] + + "@esbuild/linux-ia32@0.18.20": + resolution: + { + integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==, + } + engines: { node: ">=12" } cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.25.12": + resolution: + { + integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.0': - resolution: {integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.27.0": + resolution: + { + integrity: sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.27.7': - resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} - engines: {node: '>=18'} + "@esbuild/linux-ia32@0.27.7": + resolution: + { + integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==, + } + engines: { node: ">=18" } cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.18.20': - resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} - engines: {node: '>=12'} + "@esbuild/linux-ia32@0.28.1": + resolution: + { + integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==, + } + engines: { node: ">=18" } + cpu: [ia32] + os: [linux] + + "@esbuild/linux-loong64@0.18.20": + resolution: + { + integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==, + } + engines: { node: ">=12" } + cpu: [loong64] + os: [linux] + + "@esbuild/linux-loong64@0.25.12": + resolution: + { + integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.27.0": + resolution: + { + integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.0': - resolution: {integrity: sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.27.7": + resolution: + { + integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.27.7': - resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} - engines: {node: '>=18'} + "@esbuild/linux-loong64@0.28.1": + resolution: + { + integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==, + } + engines: { node: ">=18" } cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.18.20': - resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} - engines: {node: '>=12'} + "@esbuild/linux-mips64el@0.18.20": + resolution: + { + integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==, + } + engines: { node: ">=12" } + cpu: [mips64el] + os: [linux] + + "@esbuild/linux-mips64el@0.25.12": + resolution: + { + integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.27.0": + resolution: + { + integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.0': - resolution: {integrity: sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.27.7": + resolution: + { + integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.27.7': - resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} - engines: {node: '>=18'} + "@esbuild/linux-mips64el@0.28.1": + resolution: + { + integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==, + } + engines: { node: ">=18" } cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.18.20': - resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} - engines: {node: '>=12'} + "@esbuild/linux-ppc64@0.18.20": + resolution: + { + integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==, + } + engines: { node: ">=12" } cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.25.12": + resolution: + { + integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.0': - resolution: {integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.27.0": + resolution: + { + integrity: sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.27.7': - resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} - engines: {node: '>=18'} + "@esbuild/linux-ppc64@0.27.7": + resolution: + { + integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==, + } + engines: { node: ">=18" } cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.18.20': - resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} - engines: {node: '>=12'} + "@esbuild/linux-ppc64@0.28.1": + resolution: + { + integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==, + } + engines: { node: ">=18" } + cpu: [ppc64] + os: [linux] + + "@esbuild/linux-riscv64@0.18.20": + resolution: + { + integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==, + } + engines: { node: ">=12" } cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.25.12": + resolution: + { + integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.0': - resolution: {integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.27.0": + resolution: + { + integrity: sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.27.7': - resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} - engines: {node: '>=18'} + "@esbuild/linux-riscv64@0.27.7": + resolution: + { + integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==, + } + engines: { node: ">=18" } cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.18.20': - resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} - engines: {node: '>=12'} + "@esbuild/linux-riscv64@0.28.1": + resolution: + { + integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==, + } + engines: { node: ">=18" } + cpu: [riscv64] + os: [linux] + + "@esbuild/linux-s390x@0.18.20": + resolution: + { + integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==, + } + engines: { node: ">=12" } + cpu: [s390x] + os: [linux] + + "@esbuild/linux-s390x@0.25.12": + resolution: + { + integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.27.0": + resolution: + { + integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.0': - resolution: {integrity: sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.27.7": + resolution: + { + integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.27.7': - resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} - engines: {node: '>=18'} + "@esbuild/linux-s390x@0.28.1": + resolution: + { + integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==, + } + engines: { node: ">=18" } cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.18.20': - resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} - engines: {node: '>=12'} + "@esbuild/linux-x64@0.18.20": + resolution: + { + integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==, + } + engines: { node: ">=12" } cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.25.12": + resolution: + { + integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.0': - resolution: {integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.27.0": + resolution: + { + integrity: sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.27.7': - resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.27.7": + resolution: + { + integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==, + } + engines: { node: ">=18" } cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} + "@esbuild/linux-x64@0.28.1": + resolution: + { + integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [linux] + + "@esbuild/netbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [netbsd] + + "@esbuild/netbsd-arm64@0.27.0": + resolution: + { + integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.0': - resolution: {integrity: sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==} - engines: {node: '>=18'} + "@esbuild/netbsd-arm64@0.27.7": + resolution: + { + integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-arm64@0.27.7': - resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} - engines: {node: '>=18'} + "@esbuild/netbsd-arm64@0.28.1": + resolution: + { + integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.18.20': - resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} - engines: {node: '>=12'} + "@esbuild/netbsd-x64@0.18.20": + resolution: + { + integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [netbsd] + + "@esbuild/netbsd-x64@0.25.12": + resolution: + { + integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.27.0": + resolution: + { + integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.0': - resolution: {integrity: sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.27.7": + resolution: + { + integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.27.7': - resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} - engines: {node: '>=18'} + "@esbuild/netbsd-x64@0.28.1": + resolution: + { + integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==, + } + engines: { node: ">=18" } cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.25.12": + resolution: + { + integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.0': - resolution: {integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.27.0": + resolution: + { + integrity: sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.27.7': - resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} - engines: {node: '>=18'} + "@esbuild/openbsd-arm64@0.27.7": + resolution: + { + integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.18.20': - resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} - engines: {node: '>=12'} + "@esbuild/openbsd-arm64@0.28.1": + resolution: + { + integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.18.20": + resolution: + { + integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [openbsd] + + "@esbuild/openbsd-x64@0.25.12": + resolution: + { + integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.27.0": + resolution: + { + integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.0': - resolution: {integrity: sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.27.7": + resolution: + { + integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.27.7': - resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} - engines: {node: '>=18'} + "@esbuild/openbsd-x64@0.28.1": + resolution: + { + integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==, + } + engines: { node: ">=18" } cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.25.12": + resolution: + { + integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.0': - resolution: {integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.27.0": + resolution: + { + integrity: sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/openharmony-arm64@0.27.7': - resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} - engines: {node: '>=18'} + "@esbuild/openharmony-arm64@0.27.7": + resolution: + { + integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==, + } + engines: { node: ">=18" } cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.18.20': - resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} - engines: {node: '>=12'} + "@esbuild/openharmony-arm64@0.28.1": + resolution: + { + integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [openharmony] + + "@esbuild/sunos-x64@0.18.20": + resolution: + { + integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==, + } + engines: { node: ">=12" } + cpu: [x64] + os: [sunos] + + "@esbuild/sunos-x64@0.25.12": + resolution: + { + integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.27.0": + resolution: + { + integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.0': - resolution: {integrity: sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.27.7": + resolution: + { + integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.27.7': - resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} - engines: {node: '>=18'} + "@esbuild/sunos-x64@0.28.1": + resolution: + { + integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==, + } + engines: { node: ">=18" } cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.18.20': - resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} - engines: {node: '>=12'} + "@esbuild/win32-arm64@0.18.20": + resolution: + { + integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==, + } + engines: { node: ">=12" } cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.25.12": + resolution: + { + integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.0': - resolution: {integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.27.0": + resolution: + { + integrity: sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.27.7': - resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} - engines: {node: '>=18'} + "@esbuild/win32-arm64@0.27.7": + resolution: + { + integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==, + } + engines: { node: ">=18" } cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.18.20': - resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} - engines: {node: '>=12'} + "@esbuild/win32-arm64@0.28.1": + resolution: + { + integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==, + } + engines: { node: ">=18" } + cpu: [arm64] + os: [win32] + + "@esbuild/win32-ia32@0.18.20": + resolution: + { + integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==, + } + engines: { node: ">=12" } cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.25.12": + resolution: + { + integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.0': - resolution: {integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.27.0": + resolution: + { + integrity: sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.27.7': - resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} - engines: {node: '>=18'} + "@esbuild/win32-ia32@0.27.7": + resolution: + { + integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==, + } + engines: { node: ">=18" } cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.18.20': - resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} - engines: {node: '>=12'} - cpu: [x64] + "@esbuild/win32-ia32@0.28.1": + resolution: + { + integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==, + } + engines: { node: ">=18" } + cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.18.20": + resolution: + { + integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==, + } + engines: { node: ">=12" } cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.0': - resolution: {integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.25.12": + resolution: + { + integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==, + } + engines: { node: ">=18" } cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.27.7': - resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} - engines: {node: '>=18'} + "@esbuild/win32-x64@0.27.0": + resolution: + { + integrity: sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==, + } + engines: { node: ">=18" } cpu: [x64] os: [win32] - '@expressive-code/core@0.42.0': - resolution: {integrity: sha512-MN11+9nfmaC7sYu2BZJXAXqwkBRt8t1xTSqP+Ti1NfTEskgl6xUnzDxoaiQkg0BMzpglA0pys4dpDKquP/cyIw==} - - '@expressive-code/plugin-frames@0.42.0': - resolution: {integrity: sha512-XtkPm+941Uta7Y+81Acv+OA/20F1NJmJhCX6UYGKpqEIGqplNh3PTOhcURp6tcruhlzJcWcvpWy6Oigz3SrjqA==} - - '@expressive-code/plugin-shiki@0.42.0': - resolution: {integrity: sha512-PMKey/kLmewttAHQezL+Y5Fx3vVssfDi3+FJOYQQS2mXP3tQspFELtKKAfsXfmSXdToZYgwoO69HJndqfE+09g==} - - '@expressive-code/plugin-text-markers@0.42.0': - resolution: {integrity: sha512-l59lUx8fq1v5g6SpmbDjiU0+7IdfbiWnAyRmtTVSpfhyq+nZMN4UcmYyu2b9Mynhzt7Gr+O+cXyEPDNb2AVWVQ==} + "@esbuild/win32-x64@0.27.7": + resolution: + { + integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] - '@fastify/busboy@2.1.1': - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} + "@esbuild/win32-x64@0.28.1": + resolution: + { + integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==, + } + engines: { node: ">=18" } + cpu: [x64] + os: [win32] - '@fastify/otel@0.18.0': - resolution: {integrity: sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA==} + "@expressive-code/core@0.42.0": + resolution: + { + integrity: sha512-MN11+9nfmaC7sYu2BZJXAXqwkBRt8t1xTSqP+Ti1NfTEskgl6xUnzDxoaiQkg0BMzpglA0pys4dpDKquP/cyIw==, + } + + "@expressive-code/plugin-frames@0.42.0": + resolution: + { + integrity: sha512-XtkPm+941Uta7Y+81Acv+OA/20F1NJmJhCX6UYGKpqEIGqplNh3PTOhcURp6tcruhlzJcWcvpWy6Oigz3SrjqA==, + } + + "@expressive-code/plugin-shiki@0.42.0": + resolution: + { + integrity: sha512-PMKey/kLmewttAHQezL+Y5Fx3vVssfDi3+FJOYQQS2mXP3tQspFELtKKAfsXfmSXdToZYgwoO69HJndqfE+09g==, + } + + "@expressive-code/plugin-text-markers@0.42.0": + resolution: + { + integrity: sha512-l59lUx8fq1v5g6SpmbDjiU0+7IdfbiWnAyRmtTVSpfhyq+nZMN4UcmYyu2b9Mynhzt7Gr+O+cXyEPDNb2AVWVQ==, + } + + "@fastify/busboy@2.1.1": + resolution: + { + integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==, + } + engines: { node: ">=14" } + + "@fastify/otel@0.18.0": + resolution: + { + integrity: sha512-3TASCATfw+ctICSb4ymrv7iCm0qJ0N9CarB+CZ7zIJ7KqNbwI5JjyDL1/sxoC0ccTO1Zyd1iQ+oqncPg5FJXaA==, + } peerDependencies: - '@opentelemetry/api': ^1.9.0 - - '@fontsource-variable/rubik@5.2.8': - resolution: {integrity: sha512-vGDExLzB4a2Fj9mca5LqNoA2ZKcU9o+x5FEBLte/nxYkCB9hOQwZS6ZlItUv+Ssn7YMzKauGuI/Po+YueFuZbg==} - - '@fontsource/ibm-plex-mono@5.2.7': - resolution: {integrity: sha512-MKAb8qV+CaiMQn2B0dIi1OV3565NYzp3WN5b4oT6LTkk+F0jR6j0ZN+5BKJiIhffDC3rtBULsYZE65+0018z9w==} - - '@gerrit0/mini-shiki@3.23.0': - resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} - - '@google/genai@1.52.0': - resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==} - engines: {node: '>=20.0.0'} + "@opentelemetry/api": ^1.9.0 + + "@fontsource-variable/rubik@5.2.8": + resolution: + { + integrity: sha512-vGDExLzB4a2Fj9mca5LqNoA2ZKcU9o+x5FEBLte/nxYkCB9hOQwZS6ZlItUv+Ssn7YMzKauGuI/Po+YueFuZbg==, + } + + "@fontsource/ibm-plex-mono@5.2.7": + resolution: + { + integrity: sha512-MKAb8qV+CaiMQn2B0dIi1OV3565NYzp3WN5b4oT6LTkk+F0jR6j0ZN+5BKJiIhffDC3rtBULsYZE65+0018z9w==, + } + + "@gerrit0/mini-shiki@3.23.0": + resolution: + { + integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==, + } + + "@google/genai@1.52.0": + resolution: + { + integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==, + } + engines: { node: ">=20.0.0" } peerDependencies: - '@modelcontextprotocol/sdk': ^1.25.2 + "@modelcontextprotocol/sdk": ^1.25.2 peerDependenciesMeta: - '@modelcontextprotocol/sdk': + "@modelcontextprotocol/sdk": optional: true - '@hono/node-server@1.19.14': - resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} - engines: {node: '>=18.14.1'} + "@hono/node-server@1.19.14": + resolution: + { + integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==, + } + engines: { node: ">=18.14.1" } peerDependencies: hono: ^4 - '@img/colour@1.1.0': - resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} - engines: {node: '>=18'} - - '@img/sharp-darwin-arm64@0.34.5': - resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/colour@1.1.0": + resolution: + { + integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==, + } + engines: { node: ">=18" } + + "@img/sharp-darwin-arm64@0.34.5": + resolution: + { + integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.34.5': - resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-darwin-x64@0.34.5": + resolution: + { + integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.4': - resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + "@img/sharp-libvips-darwin-arm64@1.2.4": + resolution: + { + integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==, + } cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.4': - resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + "@img/sharp-libvips-darwin-x64@1.2.4": + resolution: + { + integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==, + } cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.2.4': - resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + "@img/sharp-libvips-linux-arm64@1.2.4": + resolution: + { + integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==, + } cpu: [arm64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-arm@1.2.4': - resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + "@img/sharp-libvips-linux-arm@1.2.4": + resolution: + { + integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==, + } cpu: [arm] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-ppc64@1.2.4': - resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + "@img/sharp-libvips-linux-ppc64@1.2.4": + resolution: + { + integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==, + } cpu: [ppc64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-riscv64@1.2.4': - resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + "@img/sharp-libvips-linux-riscv64@1.2.4": + resolution: + { + integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==, + } cpu: [riscv64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-s390x@1.2.4': - resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + "@img/sharp-libvips-linux-s390x@1.2.4": + resolution: + { + integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==, + } cpu: [s390x] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-x64@1.2.4': - resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + "@img/sharp-libvips-linux-x64@1.2.4": + resolution: + { + integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==, + } cpu: [x64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': - resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + "@img/sharp-libvips-linuxmusl-arm64@1.2.4": + resolution: + { + integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==, + } cpu: [arm64] os: [linux] libc: [musl] - '@img/sharp-libvips-linuxmusl-x64@1.2.4': - resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + "@img/sharp-libvips-linuxmusl-x64@1.2.4": + resolution: + { + integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==, + } cpu: [x64] os: [linux] libc: [musl] - '@img/sharp-linux-arm64@0.34.5': - resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linux-arm64@0.34.5": + resolution: + { + integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [arm64] os: [linux] libc: [glibc] - '@img/sharp-linux-arm@0.34.5': - resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linux-arm@0.34.5": + resolution: + { + integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [arm] os: [linux] libc: [glibc] - '@img/sharp-linux-ppc64@0.34.5': - resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linux-ppc64@0.34.5": + resolution: + { + integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [ppc64] os: [linux] libc: [glibc] - '@img/sharp-linux-riscv64@0.34.5': - resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linux-riscv64@0.34.5": + resolution: + { + integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [riscv64] os: [linux] libc: [glibc] - '@img/sharp-linux-s390x@0.34.5': - resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linux-s390x@0.34.5": + resolution: + { + integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [s390x] os: [linux] libc: [glibc] - '@img/sharp-linux-x64@0.34.5': - resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linux-x64@0.34.5": + resolution: + { + integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [x64] os: [linux] libc: [glibc] - '@img/sharp-linuxmusl-arm64@0.34.5': - resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linuxmusl-arm64@0.34.5": + resolution: + { + integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [arm64] os: [linux] libc: [musl] - '@img/sharp-linuxmusl-x64@0.34.5': - resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-linuxmusl-x64@0.34.5": + resolution: + { + integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [x64] os: [linux] libc: [musl] - '@img/sharp-wasm32@0.34.5': - resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-wasm32@0.34.5": + resolution: + { + integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [wasm32] - '@img/sharp-win32-arm64@0.34.5': - resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-win32-arm64@0.34.5": + resolution: + { + integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.34.5': - resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-win32-ia32@0.34.5": + resolution: + { + integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.34.5': - resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + "@img/sharp-win32-x64@0.34.5": + resolution: + { + integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } cpu: [x64] os: [win32] - '@inquirer/ansi@2.0.5': - resolution: {integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - - '@inquirer/confirm@6.0.13': - resolution: {integrity: sha512-wkGPC7yJ5WJk1DJ5SX7fzk+gfj4BM8cf5dDDi71B/551xHrdsZVRJOC0WyikXd0pEsb/9cLniuE4atbsMqmFkw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + "@inquirer/ansi@2.0.5": + resolution: + { + integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==, + } + engines: { node: ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" } + + "@inquirer/confirm@6.0.13": + resolution: + { + integrity: sha512-wkGPC7yJ5WJk1DJ5SX7fzk+gfj4BM8cf5dDDi71B/551xHrdsZVRJOC0WyikXd0pEsb/9cLniuE4atbsMqmFkw==, + } + engines: { node: ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" } peerDependencies: - '@types/node': '>=18' + "@types/node": ">=18" peerDependenciesMeta: - '@types/node': + "@types/node": optional: true - '@inquirer/core@11.1.10': - resolution: {integrity: sha512-a4Q5BXHQAHa9eO202sTaFCHFYVB3x5fauDuThEAdZ9gfn76pSxiKU7wWcEH0N1O0XmQvNfQNU6QXpiRxmYQx+A==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + "@inquirer/core@11.1.10": + resolution: + { + integrity: sha512-a4Q5BXHQAHa9eO202sTaFCHFYVB3x5fauDuThEAdZ9gfn76pSxiKU7wWcEH0N1O0XmQvNfQNU6QXpiRxmYQx+A==, + } + engines: { node: ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" } peerDependencies: - '@types/node': '>=18' + "@types/node": ">=18" peerDependenciesMeta: - '@types/node': + "@types/node": optional: true - '@inquirer/figures@2.0.5': - resolution: {integrity: sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - - '@inquirer/type@4.0.5': - resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + "@inquirer/figures@2.0.5": + resolution: + { + integrity: sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==, + } + engines: { node: ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" } + + "@inquirer/type@4.0.5": + resolution: + { + integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==, + } + engines: { node: ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" } peerDependencies: - '@types/node': '>=18' + "@types/node": ">=18" peerDependenciesMeta: - '@types/node': + "@types/node": optional: true - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.1': - resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==} - engines: {node: 20 || >=22} - - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - - '@jitl/quickjs-ffi-types@0.32.0': - resolution: {integrity: sha512-v9T+GQpmk43VDJ7d72sf0Nexhk+ArvtUihW27dy7lqAl0zBObFKtSBBIm5RBjwIhE8VwsPPm9PNuvPvNqLWUEg==} - - '@jitl/quickjs-wasmfile-debug-asyncify@0.32.0': - resolution: {integrity: sha512-EX8zbXwGqCgAE764M+qvkHtyXDi/FUoMBea0JnES7vCM3P7a2+EOZOjGv85wtZ2sJhI1oJ+nekmqpOODFDY+hw==} - - '@jitl/quickjs-wasmfile-debug-sync@0.32.0': - resolution: {integrity: sha512-LeYWrPGC1uNCTBWvibo3ZLJj0CSVNYUXvJpXMCmuQ5Sap2cCACc3uvGvYV4homHHBAzfw5akoTqMMS4YFRtw+Q==} - - '@jitl/quickjs-wasmfile-release-asyncify@0.32.0': - resolution: {integrity: sha512-3oSwPfja12ICz4aIblB58cuY8JlEq5Txt8Cut4VLo+LH47QN+mzCnSgnbB03hWzg1LBcc+VyyI9UOag7a1NF+Q==} - - '@jitl/quickjs-wasmfile-release-sync@0.32.0': - resolution: {integrity: sha512-BKNDI/TPBfGlLNGYpLrhcDGXmIk4xHm4MRAisOBnOzpXVn9HZWsfmMAc9WMBrAHjvvds6HOikKeaOBKdPdpVrg==} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - - '@logtape/logtape@2.1.1': - resolution: {integrity: sha512-aULbCqUQGerfOsZ3CMvcKtueKzmdchluXYUd3bIHKmOIS93fx1ko0+hyRQ4flloGZ8EiyRPydZXiy8n1J/eAQA==} - - '@mapbox/node-pre-gyp@2.0.3': - resolution: {integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==} - engines: {node: '>=18'} + "@isaacs/balanced-match@4.0.1": + resolution: + { + integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==, + } + engines: { node: 20 || >=22 } + + "@isaacs/brace-expansion@5.0.1": + resolution: + { + integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==, + } + engines: { node: 20 || >=22 } + + "@isaacs/fs-minipass@4.0.1": + resolution: + { + integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==, + } + engines: { node: ">=18.0.0" } + + "@jitl/quickjs-ffi-types@0.32.0": + resolution: + { + integrity: sha512-v9T+GQpmk43VDJ7d72sf0Nexhk+ArvtUihW27dy7lqAl0zBObFKtSBBIm5RBjwIhE8VwsPPm9PNuvPvNqLWUEg==, + } + + "@jitl/quickjs-wasmfile-debug-asyncify@0.32.0": + resolution: + { + integrity: sha512-EX8zbXwGqCgAE764M+qvkHtyXDi/FUoMBea0JnES7vCM3P7a2+EOZOjGv85wtZ2sJhI1oJ+nekmqpOODFDY+hw==, + } + + "@jitl/quickjs-wasmfile-debug-sync@0.32.0": + resolution: + { + integrity: sha512-LeYWrPGC1uNCTBWvibo3ZLJj0CSVNYUXvJpXMCmuQ5Sap2cCACc3uvGvYV4homHHBAzfw5akoTqMMS4YFRtw+Q==, + } + + "@jitl/quickjs-wasmfile-release-asyncify@0.32.0": + resolution: + { + integrity: sha512-3oSwPfja12ICz4aIblB58cuY8JlEq5Txt8Cut4VLo+LH47QN+mzCnSgnbB03hWzg1LBcc+VyyI9UOag7a1NF+Q==, + } + + "@jitl/quickjs-wasmfile-release-sync@0.32.0": + resolution: + { + integrity: sha512-BKNDI/TPBfGlLNGYpLrhcDGXmIk4xHm4MRAisOBnOzpXVn9HZWsfmMAc9WMBrAHjvvds6HOikKeaOBKdPdpVrg==, + } + + "@jridgewell/gen-mapping@0.3.13": + resolution: + { + integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==, + } + + "@jridgewell/remapping@2.3.5": + resolution: + { + integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==, + } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { + integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, + } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.5": + resolution: + { + integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==, + } + + "@jridgewell/trace-mapping@0.3.31": + resolution: + { + integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==, + } + + "@logtape/logtape@2.1.1": + resolution: + { + integrity: sha512-aULbCqUQGerfOsZ3CMvcKtueKzmdchluXYUd3bIHKmOIS93fx1ko0+hyRQ4flloGZ8EiyRPydZXiy8n1J/eAQA==, + } + + "@mapbox/node-pre-gyp@2.0.3": + resolution: + { + integrity: sha512-uwPAhccfFJlsfCxMYTwOdVfOz3xqyj8xYL3zJj8f0pb30tLohnnFPhLuqp4/qoEz8sNxe4SESZedcBojRefIzg==, + } + engines: { node: ">=18" } hasBin: true - '@mdx-js/mdx@3.1.1': - resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} - - '@mistralai/mistralai@2.2.1': - resolution: {integrity: sha512-uKU8CZmL2RzYKmplsU01hii4p3pe4HqJefpWNRWXm1Tcm0Sm4xXfwSLIy4k7ZCPlbETCGcp69E7hZs+WOJ5itQ==} - - '@mixmark-io/domino@2.2.0': - resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} - - '@modelcontextprotocol/sdk@1.29.0': - resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} - engines: {node: '>=18'} + "@mdx-js/mdx@3.1.1": + resolution: + { + integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==, + } + + "@mistralai/mistralai@2.2.1": + resolution: + { + integrity: sha512-uKU8CZmL2RzYKmplsU01hii4p3pe4HqJefpWNRWXm1Tcm0Sm4xXfwSLIy4k7ZCPlbETCGcp69E7hZs+WOJ5itQ==, + } + + "@mixmark-io/domino@2.2.0": + resolution: + { + integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==, + } + + "@modelcontextprotocol/sdk@1.29.0": + resolution: + { + integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==, + } + engines: { node: ">=18" } peerDependencies: - '@cfworker/json-schema': ^4.1.1 + "@cfworker/json-schema": ^4.1.1 zod: ^3.25 || ^4.0 peerDependenciesMeta: - '@cfworker/json-schema': + "@cfworker/json-schema": optional: true - '@mongodb-js/zstd@7.0.0': - resolution: {integrity: sha512-mQ2s0pYYiav+tzCDR05Zptem8Ey2v8s11lri5RKGhTtL4COVCvVCk5vtyRYNT+9L8qSfyOqqefF9UtnW8mC5jA==} - engines: {node: '>= 20.19.0'} - - '@mswjs/interceptors@0.41.9': - resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} - engines: {node: '>=18'} - - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + "@mongodb-js/zstd@7.0.0": + resolution: + { + integrity: sha512-mQ2s0pYYiav+tzCDR05Zptem8Ey2v8s11lri5RKGhTtL4COVCvVCk5vtyRYNT+9L8qSfyOqqefF9UtnW8mC5jA==, + } + engines: { node: ">= 20.19.0" } + + "@mswjs/interceptors@0.41.9": + resolution: + { + integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==, + } + engines: { node: ">=18" } + + "@napi-rs/wasm-runtime@1.1.4": + resolution: + { + integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==, + } peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - - '@neondatabase/serverless@1.1.0': - resolution: {integrity: sha512-r3ZZhRjEcfEdKIZnoB1RusNgvHuaBRqfCzV4Gi+5A9yUX0S4HTws/ASWqt13wL4y4I+0rqsWGdA2w7EQXHi3+Q==} - engines: {node: '>=19.0.0'} - - '@noble/ciphers@2.2.0': - resolution: {integrity: sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA==} - engines: {node: '>= 20.19.0'} - - '@noble/hashes@2.2.0': - resolution: {integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==} - engines: {node: '>= 20.19.0'} - - '@nodable/entities@2.1.0': - resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/deferred-promise@3.0.0': - resolution: {integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - - '@opentelemetry/api-logs@0.207.0': - resolution: {integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.212.0': - resolution: {integrity: sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api-logs@0.214.0': - resolution: {integrity: sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/api@1.9.1': - resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} - engines: {node: '>=8.0.0'} - - '@opentelemetry/core@2.6.1': - resolution: {integrity: sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==} - engines: {node: ^18.19.0 || >=20.6.0} + "@emnapi/core": ^1.7.1 + "@emnapi/runtime": ^1.7.1 + + "@neondatabase/serverless@1.1.0": + resolution: + { + integrity: sha512-r3ZZhRjEcfEdKIZnoB1RusNgvHuaBRqfCzV4Gi+5A9yUX0S4HTws/ASWqt13wL4y4I+0rqsWGdA2w7EQXHi3+Q==, + } + engines: { node: ">=19.0.0" } + + "@noble/ciphers@2.2.0": + resolution: + { + integrity: sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA==, + } + engines: { node: ">= 20.19.0" } + + "@noble/hashes@2.2.0": + resolution: + { + integrity: sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==, + } + engines: { node: ">= 20.19.0" } + + "@nodable/entities@2.1.0": + resolution: + { + integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==, + } + + "@nodelib/fs.scandir@2.1.5": + resolution: + { + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, + } + engines: { node: ">= 8" } + + "@nodelib/fs.stat@2.0.5": + resolution: + { + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, + } + engines: { node: ">= 8" } + + "@nodelib/fs.walk@1.2.8": + resolution: + { + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, + } + engines: { node: ">= 8" } + + "@open-draft/deferred-promise@2.2.0": + resolution: + { + integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==, + } + + "@open-draft/deferred-promise@3.0.0": + resolution: + { + integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==, + } + + "@open-draft/logger@0.3.0": + resolution: + { + integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==, + } + + "@open-draft/until@2.1.0": + resolution: + { + integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==, + } + + "@opentelemetry/api-logs@0.207.0": + resolution: + { + integrity: sha512-lAb0jQRVyleQQGiuuvCOTDVspc14nx6XJjP4FspJ1sNARo3Regq4ZZbrc3rN4b1TYSuUCvgH+UXUPug4SLOqEQ==, + } + engines: { node: ">=8.0.0" } + + "@opentelemetry/api-logs@0.212.0": + resolution: + { + integrity: sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==, + } + engines: { node: ">=8.0.0" } + + "@opentelemetry/api-logs@0.214.0": + resolution: + { + integrity: sha512-40lSJeqYO8Uz2Yj7u94/SJWE/wONa7rmMKjI1ZcIjgf3MHNHv1OZUCrCETGuaRF62d5pQD1wKIW+L4lmSMTzZA==, + } + engines: { node: ">=8.0.0" } + + "@opentelemetry/api@1.9.1": + resolution: + { + integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==, + } + engines: { node: ">=8.0.0" } + + "@opentelemetry/core@2.6.1": + resolution: + { + integrity: sha512-8xHSGWpJP9wBxgBpnqGL0R3PbdWQndL1Qp50qrg71+B28zK5OQmUgcDKLJgzyAAV38t4tOyLMGDD60LneR5W8g==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/core@2.7.1': - resolution: {integrity: sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ">=1.0.0 <1.10.0" + + "@opentelemetry/core@2.7.1": + resolution: + { + integrity: sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': '>=1.0.0 <1.10.0' - - '@opentelemetry/instrumentation-amqplib@0.61.0': - resolution: {integrity: sha512-mCKoyTGfRNisge4br0NpOFSy2Z1NnEW8hbCJdUDdJFHrPqVzc4IIBPA/vX0U+LUcQqrQvJX+HMIU0dbDRe0i0Q==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ">=1.0.0 <1.10.0" + + "@opentelemetry/instrumentation-amqplib@0.61.0": + resolution: + { + integrity: sha512-mCKoyTGfRNisge4br0NpOFSy2Z1NnEW8hbCJdUDdJFHrPqVzc4IIBPA/vX0U+LUcQqrQvJX+HMIU0dbDRe0i0Q==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-connect@0.57.0': - resolution: {integrity: sha512-FMEBChnI4FLN5TE9DHwfH7QpNir1JzXno1uz/TAucVdLCyrG0jTrKIcNHt/i30A0M2AunNBCkcd8Ei26dIPKdg==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-connect@0.57.0": + resolution: + { + integrity: sha512-FMEBChnI4FLN5TE9DHwfH7QpNir1JzXno1uz/TAucVdLCyrG0jTrKIcNHt/i30A0M2AunNBCkcd8Ei26dIPKdg==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-dataloader@0.31.0': - resolution: {integrity: sha512-f654tZFQXS5YeLDNb9KySrwtg7SnqZN119FauD7acBoTzuLduaiGTNz88ixcVSOOMGZ+EjJu/RFtx5klObC95g==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-dataloader@0.31.0": + resolution: + { + integrity: sha512-f654tZFQXS5YeLDNb9KySrwtg7SnqZN119FauD7acBoTzuLduaiGTNz88ixcVSOOMGZ+EjJu/RFtx5klObC95g==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-fs@0.33.0': - resolution: {integrity: sha512-sCZWXGalQ01wr3tAhSR9ucqFJ0phidpAle6/17HVjD6gN8FLmZMK/8sKxdXYHy3PbnlV1P4zeiSVFNKpbFMNLA==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-fs@0.33.0": + resolution: + { + integrity: sha512-sCZWXGalQ01wr3tAhSR9ucqFJ0phidpAle6/17HVjD6gN8FLmZMK/8sKxdXYHy3PbnlV1P4zeiSVFNKpbFMNLA==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-generic-pool@0.57.0': - resolution: {integrity: sha512-orhmlaK+ZIW9hKU+nHTbXrCSXZcH83AescTqmpamHRobRmYSQwRbD0a1odc0yAzuzOtxYiHiXAnpnIpaSSY7Ow==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-generic-pool@0.57.0": + resolution: + { + integrity: sha512-orhmlaK+ZIW9hKU+nHTbXrCSXZcH83AescTqmpamHRobRmYSQwRbD0a1odc0yAzuzOtxYiHiXAnpnIpaSSY7Ow==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-graphql@0.62.0': - resolution: {integrity: sha512-3YNuLVPUxafXkH1jBAbGsKNsP3XVzcFDhCDCE3OqBwCwShlqQbLMRMFh1T/d5jaVZiGVmSsfof+ICKD2iOV8xg==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-graphql@0.62.0": + resolution: + { + integrity: sha512-3YNuLVPUxafXkH1jBAbGsKNsP3XVzcFDhCDCE3OqBwCwShlqQbLMRMFh1T/d5jaVZiGVmSsfof+ICKD2iOV8xg==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-hapi@0.60.0': - resolution: {integrity: sha512-aNljZKYrEa7obLAxd1bCEDxF7kzCLGXTuTJZ8lMR9rIVEjmuKBXN1gfqpm/OB//Zc2zP4iIve1jBp7sr3mQV6w==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-hapi@0.60.0": + resolution: + { + integrity: sha512-aNljZKYrEa7obLAxd1bCEDxF7kzCLGXTuTJZ8lMR9rIVEjmuKBXN1gfqpm/OB//Zc2zP4iIve1jBp7sr3mQV6w==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-http@0.214.0': - resolution: {integrity: sha512-FlkDhZDRjDJDcO2LcSCtjRpkal1NJ8y0fBqBhTvfAR3JSYY2jAIj1kSS5IjmEBt4c3aWv+u/lqLuoCDrrKCSKg==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-http@0.214.0": + resolution: + { + integrity: sha512-FlkDhZDRjDJDcO2LcSCtjRpkal1NJ8y0fBqBhTvfAR3JSYY2jAIj1kSS5IjmEBt4c3aWv+u/lqLuoCDrrKCSKg==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-kafkajs@0.23.0': - resolution: {integrity: sha512-4K+nVo+zI+aDz0Z85SObwbdixIbzS9moIuKJaYsdlzcHYnKOPtB7ya8r8Ezivy/GVIBHiKJVq4tv+BEkgOMLaQ==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-kafkajs@0.23.0": + resolution: + { + integrity: sha512-4K+nVo+zI+aDz0Z85SObwbdixIbzS9moIuKJaYsdlzcHYnKOPtB7ya8r8Ezivy/GVIBHiKJVq4tv+BEkgOMLaQ==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-knex@0.58.0': - resolution: {integrity: sha512-Hc/o8fSsaWxZ8r1Yw4rNDLwTpUopTf4X32y4W6UhlHmW8Wizz8wfhgOKIelSeqFVTKBBPIDUOsQWuIMxBmu8Bw==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-knex@0.58.0": + resolution: + { + integrity: sha512-Hc/o8fSsaWxZ8r1Yw4rNDLwTpUopTf4X32y4W6UhlHmW8Wizz8wfhgOKIelSeqFVTKBBPIDUOsQWuIMxBmu8Bw==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-koa@0.62.0': - resolution: {integrity: sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-koa@0.62.0": + resolution: + { + integrity: sha512-uVip0VuGUQXZ+vFxkKxAUNq8qNl+VFlyHDh/U6IQ8COOEDfbEchdaHnpFrMYF3psZRUuoSIgb7xOeXj00RdwDA==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.9.0 - - '@opentelemetry/instrumentation-lru-memoizer@0.58.0': - resolution: {integrity: sha512-6grM3TdMyHzlGY1cUA+mwoPueB1F3dYKgKtZIH6jOFXqfHAByyLTc+6PFjGM9tKh52CFBJaDwodNlL/Td39z7Q==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.9.0 + + "@opentelemetry/instrumentation-lru-memoizer@0.58.0": + resolution: + { + integrity: sha512-6grM3TdMyHzlGY1cUA+mwoPueB1F3dYKgKtZIH6jOFXqfHAByyLTc+6PFjGM9tKh52CFBJaDwodNlL/Td39z7Q==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongodb@0.67.0': - resolution: {integrity: sha512-1WJp5N1lYfHq2IhECOTewFs5Tf2NfUOwQRqs/rZdXKTezArMlucxgzAaqcgp3A3YREXopXTpXHsxZTGHjNhMdQ==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-mongodb@0.67.0": + resolution: + { + integrity: sha512-1WJp5N1lYfHq2IhECOTewFs5Tf2NfUOwQRqs/rZdXKTezArMlucxgzAaqcgp3A3YREXopXTpXHsxZTGHjNhMdQ==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mongoose@0.60.0': - resolution: {integrity: sha512-8BahAZpKsOoc+lrZGb7Ofn4g3z8qtp5IxDfvAVpKXsEheQN7ONMH5djT5ihy6yf8yyeQJGS0gXFfpEAEeEHqQg==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-mongoose@0.60.0": + resolution: + { + integrity: sha512-8BahAZpKsOoc+lrZGb7Ofn4g3z8qtp5IxDfvAVpKXsEheQN7ONMH5djT5ihy6yf8yyeQJGS0gXFfpEAEeEHqQg==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql2@0.60.0': - resolution: {integrity: sha512-m/5d3bxQALllCzezYDk/6vajh0tj5OijMMvOZGr+qN1NMXm1dzMNwyJ0gNZW7Fo3YFRyj/jJMxIw+W7d525dlw==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-mysql2@0.60.0": + resolution: + { + integrity: sha512-m/5d3bxQALllCzezYDk/6vajh0tj5OijMMvOZGr+qN1NMXm1dzMNwyJ0gNZW7Fo3YFRyj/jJMxIw+W7d525dlw==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-mysql@0.60.0': - resolution: {integrity: sha512-08pO8GFPEIz2zquKDGteBZDNmwketdgH8hTe9rVYgW9kCJXq1Psj3wPQGx+VaX4ZJKCfPeoLMYup9+cxHvZyVQ==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-mysql@0.60.0": + resolution: + { + integrity: sha512-08pO8GFPEIz2zquKDGteBZDNmwketdgH8hTe9rVYgW9kCJXq1Psj3wPQGx+VaX4ZJKCfPeoLMYup9+cxHvZyVQ==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-pg@0.66.0': - resolution: {integrity: sha512-KxfLGXBb7k2ueaPJfq2GXBDXBly8P+SpR/4Mj410hhNgmQF3sCqwXvUBQxZQkDAmsdBAoenM+yV1LhtsMRamcA==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-pg@0.66.0": + resolution: + { + integrity: sha512-KxfLGXBb7k2ueaPJfq2GXBDXBly8P+SpR/4Mj410hhNgmQF3sCqwXvUBQxZQkDAmsdBAoenM+yV1LhtsMRamcA==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation-tedious@0.33.0': - resolution: {integrity: sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation-tedious@0.33.0": + resolution: + { + integrity: sha512-Q6WQwAD01MMTub31GlejoiFACYNw26J426wyjvU7by7fDIr2nZXNW4vhTGs7i7F0TnXBO3xN688g1tdUgYwJ5w==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.207.0': - resolution: {integrity: sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation@0.207.0": + resolution: + { + integrity: sha512-y6eeli9+TLKnznrR8AZlQMSJT7wILpXH+6EYq5Vf/4Ao+huI7EedxQHwRgVUOMLFbe7VFDvHJrX9/f4lcwnJsA==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.212.0': - resolution: {integrity: sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation@0.212.0": + resolution: + { + integrity: sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/instrumentation@0.214.0': - resolution: {integrity: sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/instrumentation@0.214.0": + resolution: + { + integrity: sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.3.0 - - '@opentelemetry/resources@2.7.1': - resolution: {integrity: sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ^1.3.0 + + "@opentelemetry/resources@2.7.1": + resolution: + { + integrity: sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - - '@opentelemetry/sdk-trace-base@2.7.1': - resolution: {integrity: sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ">=1.3.0 <1.10.0" + + "@opentelemetry/sdk-trace-base@2.7.1": + resolution: + { + integrity: sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': '>=1.3.0 <1.10.0' - - '@opentelemetry/semantic-conventions@1.41.1': - resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} - engines: {node: '>=14'} - - '@opentelemetry/sql-common@0.41.2': - resolution: {integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==} - engines: {node: ^18.19.0 || >=20.6.0} + "@opentelemetry/api": ">=1.3.0 <1.10.0" + + "@opentelemetry/semantic-conventions@1.41.1": + resolution: + { + integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==, + } + engines: { node: ">=14" } + + "@opentelemetry/sql-common@0.41.2": + resolution: + { + integrity: sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==, + } + engines: { node: ^18.19.0 || >=20.6.0 } peerDependencies: - '@opentelemetry/api': ^1.1.0 - - '@oslojs/encoding@1.1.0': - resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} - - '@oxc-project/types@0.110.0': - resolution: {integrity: sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow==} - - '@oxc-project/types@0.132.0': - resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} - - '@oxc-transform/binding-android-arm-eabi@0.111.0': - resolution: {integrity: sha512-NdFLicvorfHYu0g2ftjVJaH7+Dz27AQUNJOq8t/ofRUoWmczOodgUCHx8C1M1htCN4ZmhS/FzfSy6yd/UngJGg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@opentelemetry/api": ^1.1.0 + + "@oslojs/encoding@1.1.0": + resolution: + { + integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==, + } + + "@oxc-project/types@0.110.0": + resolution: + { + integrity: sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow==, + } + + "@oxc-project/types@0.132.0": + resolution: + { + integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==, + } + + "@oxc-transform/binding-android-arm-eabi@0.111.0": + resolution: + { + integrity: sha512-NdFLicvorfHYu0g2ftjVJaH7+Dz27AQUNJOq8t/ofRUoWmczOodgUCHx8C1M1htCN4ZmhS/FzfSy6yd/UngJGg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [android] - '@oxc-transform/binding-android-arm64@0.111.0': - resolution: {integrity: sha512-J2v9ajarD2FYlhHtjbgZUFsS2Kvi27pPxDWLGCy7i8tO60xBoozX9/ktSgbiE/QsxKaUhfv4zVKppKWUo71PmQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-android-arm64@0.111.0": + resolution: + { + integrity: sha512-J2v9ajarD2FYlhHtjbgZUFsS2Kvi27pPxDWLGCy7i8tO60xBoozX9/ktSgbiE/QsxKaUhfv4zVKppKWUo71PmQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [android] - '@oxc-transform/binding-darwin-arm64@0.111.0': - resolution: {integrity: sha512-2UYmExxpXzmiHTldhNlosWqG9Nc4US51K0GB9RLcGlTE23WO33vVo1NVAKwxPE+KYuhffwDnRYTovTMUjzwvZA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-darwin-arm64@0.111.0": + resolution: + { + integrity: sha512-2UYmExxpXzmiHTldhNlosWqG9Nc4US51K0GB9RLcGlTE23WO33vVo1NVAKwxPE+KYuhffwDnRYTovTMUjzwvZA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [darwin] - '@oxc-transform/binding-darwin-x64@0.111.0': - resolution: {integrity: sha512-c4YRwfLV8Pj/ToiTCbndZaHxM2BD4W3bltr/fjXZcGypEK+U2RZFDL7tIZYT/tyneAC9hCORZKDaKhLLNuzPtA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-darwin-x64@0.111.0": + resolution: + { + integrity: sha512-c4YRwfLV8Pj/ToiTCbndZaHxM2BD4W3bltr/fjXZcGypEK+U2RZFDL7tIZYT/tyneAC9hCORZKDaKhLLNuzPtA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [darwin] - '@oxc-transform/binding-freebsd-x64@0.111.0': - resolution: {integrity: sha512-prvf32IcEuLnLZbNVomFosBu0CaZpyj3YsZ6epbOgJy8iJjfLsXBb+PrkO/NBKzjuJoJa2+u7jFKRE0KT7gSOw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-freebsd-x64@0.111.0": + resolution: + { + integrity: sha512-prvf32IcEuLnLZbNVomFosBu0CaZpyj3YsZ6epbOgJy8iJjfLsXBb+PrkO/NBKzjuJoJa2+u7jFKRE0KT7gSOw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [freebsd] - '@oxc-transform/binding-linux-arm-gnueabihf@0.111.0': - resolution: {integrity: sha512-+se3579Wp7VOk8TnTZCpT+obTAyzOw2b/UuoM0+51LtbzCSfjKxd4A+o7zRl7GyPrPZvx57KdbMOC9rWB1xNrw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-arm-gnueabihf@0.111.0": + resolution: + { + integrity: sha512-+se3579Wp7VOk8TnTZCpT+obTAyzOw2b/UuoM0+51LtbzCSfjKxd4A+o7zRl7GyPrPZvx57KdbMOC9rWB1xNrw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] - '@oxc-transform/binding-linux-arm-musleabihf@0.111.0': - resolution: {integrity: sha512-8faC99pStqaSDPK/vBgaagAHUeL0LcIzfeSjSiDTtvPGc3AwZIeqC1tx3CP15a6tWXjdgS/IUw4IjfD5HweBlg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-arm-musleabihf@0.111.0": + resolution: + { + integrity: sha512-8faC99pStqaSDPK/vBgaagAHUeL0LcIzfeSjSiDTtvPGc3AwZIeqC1tx3CP15a6tWXjdgS/IUw4IjfD5HweBlg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] - '@oxc-transform/binding-linux-arm64-gnu@0.111.0': - resolution: {integrity: sha512-HtfQv8j796gzI5WR/RaP6IMwFpiL0vYeDrUA1hYhlPzTHKYan/B+NlhJkKOI1v24yAl/yEnFmb0pxIxLNqBqBA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-arm64-gnu@0.111.0": + resolution: + { + integrity: sha512-HtfQv8j796gzI5WR/RaP6IMwFpiL0vYeDrUA1hYhlPzTHKYan/B+NlhJkKOI1v24yAl/yEnFmb0pxIxLNqBqBA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-arm64-musl@0.111.0': - resolution: {integrity: sha512-ARyfcMCIxVLDgLf6FQ8Oo1/TFySpnquV+vuSb4SFQZfYDqgMklzwv0NYXxWD0aB6enElyMDs6pQJBzusEKCkOg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-arm64-musl@0.111.0": + resolution: + { + integrity: sha512-ARyfcMCIxVLDgLf6FQ8Oo1/TFySpnquV+vuSb4SFQZfYDqgMklzwv0NYXxWD0aB6enElyMDs6pQJBzusEKCkOg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [musl] - '@oxc-transform/binding-linux-ppc64-gnu@0.111.0': - resolution: {integrity: sha512-PKpVRrSvBNK3tv9vwxn7Fay+QWZmprPGlEqJcseBJllQc5mFMD4Q/w44chu5iR9ZLsDeSHzmNWrgMLo4J0sP2A==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-ppc64-gnu@0.111.0": + resolution: + { + integrity: sha512-PKpVRrSvBNK3tv9vwxn7Fay+QWZmprPGlEqJcseBJllQc5mFMD4Q/w44chu5iR9ZLsDeSHzmNWrgMLo4J0sP2A==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-riscv64-gnu@0.111.0': - resolution: {integrity: sha512-9bUml6rMgk+8GF5rvNMweFspkzSiCjqpV6HduwiUyexqfGKrmjq9IZOxxvnzkE2RGdQzP507NNDoVNYIoGQYuA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-riscv64-gnu@0.111.0": + resolution: + { + integrity: sha512-9bUml6rMgk+8GF5rvNMweFspkzSiCjqpV6HduwiUyexqfGKrmjq9IZOxxvnzkE2RGdQzP507NNDoVNYIoGQYuA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-riscv64-musl@0.111.0': - resolution: {integrity: sha512-tzGCohGxaeH6KRJjfYZd4mHCoGjCai6N+zZi1Oj+tSDMAAdyvs1dRzYb8PNUGnybCg3Te4M0jLPzWZaSmnKraQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-riscv64-musl@0.111.0": + resolution: + { + integrity: sha512-tzGCohGxaeH6KRJjfYZd4mHCoGjCai6N+zZi1Oj+tSDMAAdyvs1dRzYb8PNUGnybCg3Te4M0jLPzWZaSmnKraQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-transform/binding-linux-s390x-gnu@0.111.0': - resolution: {integrity: sha512-sRG1KIfZ0ML9ToEygm5aM/5GJeBA05uHlgW3M0Rx/DNWMJhuahLmqWuB02aWSmijndLfEKXLLXIWhvWupRG8lg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-s390x-gnu@0.111.0": + resolution: + { + integrity: sha512-sRG1KIfZ0ML9ToEygm5aM/5GJeBA05uHlgW3M0Rx/DNWMJhuahLmqWuB02aWSmijndLfEKXLLXIWhvWupRG8lg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-x64-gnu@0.111.0': - resolution: {integrity: sha512-T0Kmvk+OdlUdABdXlDIf3MQReMzFfC75NEI9x8jxy5pKooACEFg0k0V8gyR3gq4DzbDCfucqFQDWNvSgIopAbQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-x64-gnu@0.111.0": + resolution: + { + integrity: sha512-T0Kmvk+OdlUdABdXlDIf3MQReMzFfC75NEI9x8jxy5pKooACEFg0k0V8gyR3gq4DzbDCfucqFQDWNvSgIopAbQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [glibc] - '@oxc-transform/binding-linux-x64-musl@0.111.0': - resolution: {integrity: sha512-EgoutsP3YfqzN8a9vpc9+XLr0bmBl0dA3uOMiP77+exATCPxJBkJErGmQkqk6RtTp5XqX6q6mB45qWQyKk6+pA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-linux-x64-musl@0.111.0": + resolution: + { + integrity: sha512-EgoutsP3YfqzN8a9vpc9+XLr0bmBl0dA3uOMiP77+exATCPxJBkJErGmQkqk6RtTp5XqX6q6mB45qWQyKk6+pA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [musl] - '@oxc-transform/binding-openharmony-arm64@0.111.0': - resolution: {integrity: sha512-d8J+ejc0j5WODbVwR/QxFaI65YMwvG0W53vcVCHwa6ja1QI5lpe7sislrefG2EFYgnY47voMRzlXab5d4gEcDw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-openharmony-arm64@0.111.0": + resolution: + { + integrity: sha512-d8J+ejc0j5WODbVwR/QxFaI65YMwvG0W53vcVCHwa6ja1QI5lpe7sislrefG2EFYgnY47voMRzlXab5d4gEcDw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [openharmony] - '@oxc-transform/binding-wasm32-wasi@0.111.0': - resolution: {integrity: sha512-HtyIZO8IwuZgXkyb56rysLz1OLbfLhEu8A3BeuyJXzUseAj96yuxgGt3cu3QYX9AXb9pfRfA3c/fvlhsDugyTQ==} - engines: {node: '>=14.0.0'} + "@oxc-transform/binding-wasm32-wasi@0.111.0": + resolution: + { + integrity: sha512-HtyIZO8IwuZgXkyb56rysLz1OLbfLhEu8A3BeuyJXzUseAj96yuxgGt3cu3QYX9AXb9pfRfA3c/fvlhsDugyTQ==, + } + engines: { node: ">=14.0.0" } cpu: [wasm32] - '@oxc-transform/binding-win32-arm64-msvc@0.111.0': - resolution: {integrity: sha512-YeP80Riptc0MkVVBnzbmoFuHVLUq278+MbwNo9sTLALmzTIJxJqN029xRZbG+Bun7aLsoZhmRnm3J5JZ1NcP5w==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-win32-arm64-msvc@0.111.0": + resolution: + { + integrity: sha512-YeP80Riptc0MkVVBnzbmoFuHVLUq278+MbwNo9sTLALmzTIJxJqN029xRZbG+Bun7aLsoZhmRnm3J5JZ1NcP5w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [win32] - '@oxc-transform/binding-win32-ia32-msvc@0.111.0': - resolution: {integrity: sha512-A6ztCXpoSHt6PbvGAFqB0MLOcGG7ZJrrPXY1iB0zfOB1atLgI8oNePGxPl03XSbwpiTsFJ1oo8rj9DXcBzgT9g==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-win32-ia32-msvc@0.111.0": + resolution: + { + integrity: sha512-A6ztCXpoSHt6PbvGAFqB0MLOcGG7ZJrrPXY1iB0zfOB1atLgI8oNePGxPl03XSbwpiTsFJ1oo8rj9DXcBzgT9g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [ia32] os: [win32] - '@oxc-transform/binding-win32-x64-msvc@0.111.0': - resolution: {integrity: sha512-QddKW4kBH0Wof6Y65eYCNHM4iOGmCTWLLcNYY1FGswhzmTYOUVXajNROR+iCXAOFnOF0ldtsR79SyqgyHH1Bgg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxc-transform/binding-win32-x64-msvc@0.111.0": + resolution: + { + integrity: sha512-QddKW4kBH0Wof6Y65eYCNHM4iOGmCTWLLcNYY1FGswhzmTYOUVXajNROR+iCXAOFnOF0ldtsR79SyqgyHH1Bgg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [win32] - '@oxlint/binding-android-arm-eabi@1.66.0': - resolution: {integrity: sha512-f7kq8N51T4phpzqfBpA2qaVTI/KrkCmNwaj3t/97I/WLTDI+UhlP5GL9eER+zVxBhtlx5rKXWByJU1/zDAvyaw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-android-arm-eabi@1.66.0": + resolution: + { + integrity: sha512-f7kq8N51T4phpzqfBpA2qaVTI/KrkCmNwaj3t/97I/WLTDI+UhlP5GL9eER+zVxBhtlx5rKXWByJU1/zDAvyaw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [android] - '@oxlint/binding-android-arm64@1.66.0': - resolution: {integrity: sha512-xu6QO71tdDS9mjmLZ3AqhtaVHBvdmsOKkYnReNNDgh+XiwnsipeQOIxbiYOOO0iAXycJ+GK0wdMSZP/2j/AmSg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-android-arm64@1.66.0": + resolution: + { + integrity: sha512-xu6QO71tdDS9mjmLZ3AqhtaVHBvdmsOKkYnReNNDgh+XiwnsipeQOIxbiYOOO0iAXycJ+GK0wdMSZP/2j/AmSg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [android] - '@oxlint/binding-darwin-arm64@1.66.0': - resolution: {integrity: sha512-HZ24VimSOC7mxuEA99e0H2FS0C1yO3+iW13jPRAk+e2njsUs3QeAXsafCDyaIrV/MirdOVez+etQNQsJE43zNQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-darwin-arm64@1.66.0": + resolution: + { + integrity: sha512-HZ24VimSOC7mxuEA99e0H2FS0C1yO3+iW13jPRAk+e2njsUs3QeAXsafCDyaIrV/MirdOVez+etQNQsJE43zNQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-x64@1.66.0': - resolution: {integrity: sha512-awhj8ZvJrrRSnXj7V++rpZvTmnl99L6mi0B7gg7Cp7BN6cKpzuI481bHNLvXGA9GB1/oEgA3ponuyoAc6Md12A==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-darwin-x64@1.66.0": + resolution: + { + integrity: sha512-awhj8ZvJrrRSnXj7V++rpZvTmnl99L6mi0B7gg7Cp7BN6cKpzuI481bHNLvXGA9GB1/oEgA3ponuyoAc6Md12A==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [darwin] - '@oxlint/binding-freebsd-x64@1.66.0': - resolution: {integrity: sha512-KQF0oVV21/FjIqkRuL8Q1vh8ECsE5+ocdH5tcqTQ4ZnYuDVoYibQUNfqBjQaUsP6UIIda5Y75Wpm5p4RgQWiWw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-freebsd-x64@1.66.0": + resolution: + { + integrity: sha512-KQF0oVV21/FjIqkRuL8Q1vh8ECsE5+ocdH5tcqTQ4ZnYuDVoYibQUNfqBjQaUsP6UIIda5Y75Wpm5p4RgQWiWw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [freebsd] - '@oxlint/binding-linux-arm-gnueabihf@1.66.0': - resolution: {integrity: sha512-9u1rgwZSEXWb30vbFZzQ78HVXBo0WCKNwJ3a2InRUTNMRng+PUDIoSFmA+m4HdUfBaIqftShq8J8qHc+eE/Vig==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-arm-gnueabihf@1.66.0": + resolution: + { + integrity: sha512-9u1rgwZSEXWb30vbFZzQ78HVXBo0WCKNwJ3a2InRUTNMRng+PUDIoSFmA+m4HdUfBaIqftShq8J8qHc+eE/Vig==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.66.0': - resolution: {integrity: sha512-Ynot2HR1bHxUaNWoC280MVTDfZuaWuP3XfSMRDhyuZrVjhzoaBCVFlw8h8qeZjWKVUBhPWFIxB7AQTlK8Z2WWg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-arm-musleabihf@1.66.0": + resolution: + { + integrity: sha512-Ynot2HR1bHxUaNWoC280MVTDfZuaWuP3XfSMRDhyuZrVjhzoaBCVFlw8h8qeZjWKVUBhPWFIxB7AQTlK8Z2WWg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm64-gnu@1.66.0': - resolution: {integrity: sha512-xCbgzciGgo+A4aQZEknsNrNiIwY7sU5SfRuMmRjPIvZAgdF34cIHiKvwOsS5XRLjlTVSFwitmq6YclTtHTfU+g==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-arm64-gnu@1.66.0": + resolution: + { + integrity: sha512-xCbgzciGgo+A4aQZEknsNrNiIwY7sU5SfRuMmRjPIvZAgdF34cIHiKvwOsS5XRLjlTVSFwitmq6YclTtHTfU+g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-musl@1.66.0': - resolution: {integrity: sha512-hmo+ZB/lHkR1HdDmnziNpzSLmulnUSu10VEqX2Yex7OwvoBAbjJQLvy4gIBRV3AAwWnCvAxKp5Nv1GE6LU1QMg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-arm64-musl@1.66.0": + resolution: + { + integrity: sha512-hmo+ZB/lHkR1HdDmnziNpzSLmulnUSu10VEqX2Yex7OwvoBAbjJQLvy4gIBRV3AAwWnCvAxKp5Nv1GE6LU1QMg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [musl] - '@oxlint/binding-linux-ppc64-gnu@1.66.0': - resolution: {integrity: sha512-2Invd4Uyy81mVooQC5FBtfxSNrvcX1OxbMlVQ6M2erRrNI2awFYF26YNW2yFxdVFZ4ffNOWKghtMjhnUPsXsVA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-ppc64-gnu@1.66.0": + resolution: + { + integrity: sha512-2Invd4Uyy81mVooQC5FBtfxSNrvcX1OxbMlVQ6M2erRrNI2awFYF26YNW2yFxdVFZ4ffNOWKghtMjhnUPsXsVA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [ppc64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.66.0': - resolution: {integrity: sha512-s0iXPDQVdgayE3RGa/N2DZF7tjgg0TwEtD1sGoDxqPDGrIXgo45H0yHknT0f9A0yteASsweYZtDyTuVlM4aSag==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-riscv64-gnu@1.66.0": + resolution: + { + integrity: sha512-s0iXPDQVdgayE3RGa/N2DZF7tjgg0TwEtD1sGoDxqPDGrIXgo45H0yHknT0f9A0yteASsweYZtDyTuVlM4aSag==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [riscv64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-musl@1.66.0': - resolution: {integrity: sha512-OekL4XFiu7RPK0JIZi8VeHgtIXPREf42t8Cy/rKEsC+P3gcqDgNAAGiyuUOpdbG4wwbfue1q4CHcCO7spSve6w==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-riscv64-musl@1.66.0": + resolution: + { + integrity: sha512-OekL4XFiu7RPK0JIZi8VeHgtIXPREf42t8Cy/rKEsC+P3gcqDgNAAGiyuUOpdbG4wwbfue1q4CHcCO7spSve6w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [riscv64] os: [linux] libc: [musl] - '@oxlint/binding-linux-s390x-gnu@1.66.0': - resolution: {integrity: sha512-Ga1D0kj1SFslm34ThA/BdkUlyAYEnTsXyRC4pF0C5agZSwtGdHYWMTQWemUfBGp4RCG4QWXgdO+HmmmKqOtlBg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-s390x-gnu@1.66.0": + resolution: + { + integrity: sha512-Ga1D0kj1SFslm34ThA/BdkUlyAYEnTsXyRC4pF0C5agZSwtGdHYWMTQWemUfBGp4RCG4QWXgdO+HmmmKqOtlBg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [s390x] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.66.0': - resolution: {integrity: sha512-p5jfP1wUZe/IC3qpQO84n9DRnf9g3lKRtLBlQq23ykyrDglHcVx7sWmVTlPuU6SBw8mNnPzyOn022G3XZHnlww==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-x64-gnu@1.66.0": + resolution: + { + integrity: sha512-p5jfP1wUZe/IC3qpQO84n9DRnf9g3lKRtLBlQq23ykyrDglHcVx7sWmVTlPuU6SBw8mNnPzyOn022G3XZHnlww==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.66.0': - resolution: {integrity: sha512-vUB/sYlYZorDL1ZD+o9mRv7zbsykrrFRtmgS6R8musZqLtrPRQn1gc1eGpuX+sfdccz42STl/AqldY6XRb2upQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-linux-x64-musl@1.66.0": + resolution: + { + integrity: sha512-vUB/sYlYZorDL1ZD+o9mRv7zbsykrrFRtmgS6R8musZqLtrPRQn1gc1eGpuX+sfdccz42STl/AqldY6XRb2upQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [musl] - '@oxlint/binding-openharmony-arm64@1.66.0': - resolution: {integrity: sha512-yde+6p/F59xRkGR9H1HfngWRif1QRJjynZK349l+UI0H6w9hL3G8/AVaTHFyTtLVQ56qtNbX2/5Dc77n1ovnOg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-openharmony-arm64@1.66.0": + resolution: + { + integrity: sha512-yde+6p/F59xRkGR9H1HfngWRif1QRJjynZK349l+UI0H6w9hL3G8/AVaTHFyTtLVQ56qtNbX2/5Dc77n1ovnOg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [openharmony] - '@oxlint/binding-win32-arm64-msvc@1.66.0': - resolution: {integrity: sha512-O9GLucgoTdmOrbBX+EjzNe7o/Ze5TFOvXcib6bzUOtBOmj6cV+zw18NgB+cGKAkDw1Pdqs8vGkfHbbsLuDtXWg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-win32-arm64-msvc@1.66.0": + resolution: + { + integrity: sha512-O9GLucgoTdmOrbBX+EjzNe7o/Ze5TFOvXcib6bzUOtBOmj6cV+zw18NgB+cGKAkDw1Pdqs8vGkfHbbsLuDtXWg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.66.0': - resolution: {integrity: sha512-m3Pjwc2MfTcom4E4gOv7DyuGyt7OfGNCbmqDHd+N7EzXmP+ppHuudm2NjcA3AjV5TSeGxaguVF4SbTKHe1USYA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-win32-ia32-msvc@1.66.0": + resolution: + { + integrity: sha512-m3Pjwc2MfTcom4E4gOv7DyuGyt7OfGNCbmqDHd+N7EzXmP+ppHuudm2NjcA3AjV5TSeGxaguVF4SbTKHe1USYA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [ia32] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.66.0': - resolution: {integrity: sha512-/DbBvw8UFBhja6PqudUjV4UtfsJr0Oa7jUjWVKB0g86lj/VwnPrkngn0sFql3c9RDA0O16dh7ozsXb6GjNAzBQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@oxlint/binding-win32-x64-msvc@1.66.0": + resolution: + { + integrity: sha512-/DbBvw8UFBhja6PqudUjV4UtfsJr0Oa7jUjWVKB0g86lj/VwnPrkngn0sFql3c9RDA0O16dh7ozsXb6GjNAzBQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [win32] - '@pagefind/darwin-arm64@1.5.2': - resolution: {integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==} + "@pagefind/darwin-arm64@1.5.2": + resolution: + { + integrity: sha512-MXpI+7HsAdPkvJ0gk9xj9g541BCqBZOBbdwj9g6lB5LCj6kSV6nqDSjzcAJwvOsfu0fjwvC8hQU+ecfhp+MpiQ==, + } cpu: [arm64] os: [darwin] - '@pagefind/darwin-x64@1.5.2': - resolution: {integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==} + "@pagefind/darwin-x64@1.5.2": + resolution: + { + integrity: sha512-IojxFWMEJe0RQ7PQ3KXQsPIImNsbpPYpoZ+QUDrL8fAl/O27IX+LVLs74/UzEZy5uA2LD8Nz1AiwKr72vrkZQw==, + } cpu: [x64] os: [darwin] - '@pagefind/default-ui@1.5.2': - resolution: {integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==} - - '@pagefind/freebsd-x64@1.5.2': - resolution: {integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==} + "@pagefind/default-ui@1.5.2": + resolution: + { + integrity: sha512-pm1LMnQg8N2B3n2TnjKlhaFihpz6zTiA4HiGQ6/slKO/+8K9CAU5kcjdSSPgpuk1PMuuN4hxLipUIifnrkl3Sg==, + } + + "@pagefind/freebsd-x64@1.5.2": + resolution: + { + integrity: sha512-7EVzo9+0w+2cbe671BtMj10UlNo83I+HrLVLfRxO731svHRJKUfJ/mo05gU14pe9PCfpKNQT8FS3Xc/oDN6pOA==, + } cpu: [x64] os: [freebsd] - '@pagefind/linux-arm64@1.5.2': - resolution: {integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==} + "@pagefind/linux-arm64@1.5.2": + resolution: + { + integrity: sha512-Ovt9+K35sqzn8H3ZMXGwls4TD/wMJuvRtShHIsmUQREmaxjrDEX7gHckRCrwYJ4XE1H1p6HkLz3wukrAnsfXQw==, + } cpu: [arm64] os: [linux] - '@pagefind/linux-x64@1.5.2': - resolution: {integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==} + "@pagefind/linux-x64@1.5.2": + resolution: + { + integrity: sha512-V+tFqHKXhQKq/WqPBD67AFy7scn1/aZID00ws4fSDd+1daSi5UHR9VVlRrOUYKxn3VuFQYRD7lYXdZK1WED1YA==, + } cpu: [x64] os: [linux] - '@pagefind/windows-arm64@1.5.2': - resolution: {integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==} + "@pagefind/windows-arm64@1.5.2": + resolution: + { + integrity: sha512-hN9Nh90fNW61nNRCW9ZyQrAj/mD0eRvmJ8NlTUzkbuW8kIzGJUi3cxjFkEcMZ5h/8FsKWD/VcouZl4yo1F7B6g==, + } cpu: [arm64] os: [win32] - '@pagefind/windows-x64@1.5.2': - resolution: {integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==} + "@pagefind/windows-x64@1.5.2": + resolution: + { + integrity: sha512-Fa2Iyw7kaDRzGMfNYNUXNW2zbL5FQVDgSOcbDHdzBrDEdpqOqg8TcZ68F22ol6NJ9IGzvUdmeyZypLW5dyhqsg==, + } cpu: [x64] os: [win32] - '@parcel/watcher-android-arm64@2.5.6': - resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-android-arm64@2.5.6": + resolution: + { + integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==, + } + engines: { node: ">= 10.0.0" } cpu: [arm64] os: [android] - '@parcel/watcher-darwin-arm64@2.5.6': - resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-darwin-arm64@2.5.6": + resolution: + { + integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==, + } + engines: { node: ">= 10.0.0" } cpu: [arm64] os: [darwin] - '@parcel/watcher-darwin-x64@2.5.6': - resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-darwin-x64@2.5.6": + resolution: + { + integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==, + } + engines: { node: ">= 10.0.0" } cpu: [x64] os: [darwin] - '@parcel/watcher-freebsd-x64@2.5.6': - resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-freebsd-x64@2.5.6": + resolution: + { + integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==, + } + engines: { node: ">= 10.0.0" } cpu: [x64] os: [freebsd] - '@parcel/watcher-linux-arm-glibc@2.5.6': - resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-linux-arm-glibc@2.5.6": + resolution: + { + integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==, + } + engines: { node: ">= 10.0.0" } cpu: [arm] os: [linux] libc: [glibc] - '@parcel/watcher-linux-arm-musl@2.5.6': - resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-linux-arm-musl@2.5.6": + resolution: + { + integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==, + } + engines: { node: ">= 10.0.0" } cpu: [arm] os: [linux] libc: [musl] - '@parcel/watcher-linux-arm64-glibc@2.5.6': - resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-linux-arm64-glibc@2.5.6": + resolution: + { + integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==, + } + engines: { node: ">= 10.0.0" } cpu: [arm64] os: [linux] libc: [glibc] - '@parcel/watcher-linux-arm64-musl@2.5.6': - resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-linux-arm64-musl@2.5.6": + resolution: + { + integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==, + } + engines: { node: ">= 10.0.0" } cpu: [arm64] os: [linux] libc: [musl] - '@parcel/watcher-linux-x64-glibc@2.5.6': - resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-linux-x64-glibc@2.5.6": + resolution: + { + integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==, + } + engines: { node: ">= 10.0.0" } cpu: [x64] os: [linux] libc: [glibc] - '@parcel/watcher-linux-x64-musl@2.5.6': - resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-linux-x64-musl@2.5.6": + resolution: + { + integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==, + } + engines: { node: ">= 10.0.0" } cpu: [x64] os: [linux] libc: [musl] - '@parcel/watcher-win32-arm64@2.5.6': - resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-win32-arm64@2.5.6": + resolution: + { + integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==, + } + engines: { node: ">= 10.0.0" } cpu: [arm64] os: [win32] - '@parcel/watcher-win32-ia32@2.5.6': - resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-win32-ia32@2.5.6": + resolution: + { + integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==, + } + engines: { node: ">= 10.0.0" } cpu: [ia32] os: [win32] - '@parcel/watcher-win32-x64@2.5.6': - resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} - engines: {node: '>= 10.0.0'} + "@parcel/watcher-win32-x64@2.5.6": + resolution: + { + integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==, + } + engines: { node: ">= 10.0.0" } cpu: [x64] os: [win32] - '@parcel/watcher@2.5.6': - resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} - engines: {node: '>= 10.0.0'} - - '@playwright/test@1.60.0': - resolution: {integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==} - engines: {node: '>=18'} + "@parcel/watcher@2.5.6": + resolution: + { + integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==, + } + engines: { node: ">= 10.0.0" } + + "@playwright/test@1.60.0": + resolution: + { + integrity: sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==, + } + engines: { node: ">=18" } hasBin: true - '@prisma/instrumentation@7.6.0': - resolution: {integrity: sha512-ZPW2gRiwpPzEfgeZgaekhqXrbW+Y2RJKHVqUmlhZhKzRNCcvR6DykzylDrynpArKKRQtLxoZy36fK7U0p3pdgQ==} + "@prisma/instrumentation@7.6.0": + resolution: + { + integrity: sha512-ZPW2gRiwpPzEfgeZgaekhqXrbW+Y2RJKHVqUmlhZhKzRNCcvR6DykzylDrynpArKKRQtLxoZy36fK7U0p3pdgQ==, + } peerDependencies: - '@opentelemetry/api': ^1.8 - - '@protobufjs/aspromise@1.1.2': - resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} - - '@protobufjs/base64@1.1.2': - resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} - - '@protobufjs/codegen@2.0.5': - resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} - - '@protobufjs/eventemitter@1.1.1': - resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} - - '@protobufjs/fetch@1.1.1': - resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} - - '@protobufjs/float@1.0.2': - resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} - - '@protobufjs/inquire@1.1.2': - resolution: {integrity: sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==} - - '@protobufjs/path@1.1.2': - resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} - - '@protobufjs/pool@1.1.0': - resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} - - '@protobufjs/utf8@1.1.1': - resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} - - '@redis/bloom@5.12.1': - resolution: {integrity: sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==} - engines: {node: '>= 18.19.0'} + "@opentelemetry/api": ^1.8 + + "@protobufjs/aspromise@1.1.2": + resolution: + { + integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==, + } + + "@protobufjs/base64@1.1.2": + resolution: + { + integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==, + } + + "@protobufjs/codegen@2.0.5": + resolution: + { + integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==, + } + + "@protobufjs/eventemitter@1.1.1": + resolution: + { + integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==, + } + + "@protobufjs/fetch@1.1.1": + resolution: + { + integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==, + } + + "@protobufjs/float@1.0.2": + resolution: + { + integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==, + } + + "@protobufjs/inquire@1.1.2": + resolution: + { + integrity: sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==, + } + + "@protobufjs/path@1.1.2": + resolution: + { + integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==, + } + + "@protobufjs/pool@1.1.0": + resolution: + { + integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==, + } + + "@protobufjs/utf8@1.1.1": + resolution: + { + integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==, + } + + "@publint/pack@0.1.5": + resolution: + { + integrity: sha512-edgyN2pP07uXiP4tJs0s8KVmU8M8i60YPbbI0/WDeok1mIJHRXz+CgD8I0nelwDkoCh3EWL/G5kGfbuHjsdbvw==, + } + engines: { node: ">=18" } + + "@redis/bloom@5.12.1": + resolution: + { + integrity: sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==, + } + engines: { node: ">= 18.19.0" } peerDependencies: - '@redis/client': ^5.12.1 - - '@redis/client@5.12.1': - resolution: {integrity: sha512-7aPGWeqA3uFm43o19umzdl16CEjK/JQGtSXVPevplTaOU3VJA/rseBC1QvYUz9lLDIMBimc4SW/zrW4S89BaCA==} - engines: {node: '>= 18.19.0'} + "@redis/client": ^5.12.1 + + "@redis/client@5.12.1": + resolution: + { + integrity: sha512-7aPGWeqA3uFm43o19umzdl16CEjK/JQGtSXVPevplTaOU3VJA/rseBC1QvYUz9lLDIMBimc4SW/zrW4S89BaCA==, + } + engines: { node: ">= 18.19.0" } peerDependencies: - '@node-rs/xxhash': ^1.1.0 - '@opentelemetry/api': '>=1 <2' + "@node-rs/xxhash": ^1.1.0 + "@opentelemetry/api": ">=1 <2" peerDependenciesMeta: - '@node-rs/xxhash': + "@node-rs/xxhash": optional: true - '@opentelemetry/api': + "@opentelemetry/api": optional: true - '@redis/json@5.12.1': - resolution: {integrity: sha512-eOze75esLve4vfqDel7aMX08CNaiLLQS2fV8mpRN9NxPe1rVR4vQyYiW/OgtGUysF6QOr9ANhfxABKNOJfXdKg==} - engines: {node: '>= 18.19.0'} + "@redis/json@5.12.1": + resolution: + { + integrity: sha512-eOze75esLve4vfqDel7aMX08CNaiLLQS2fV8mpRN9NxPe1rVR4vQyYiW/OgtGUysF6QOr9ANhfxABKNOJfXdKg==, + } + engines: { node: ">= 18.19.0" } peerDependencies: - '@redis/client': ^5.12.1 - - '@redis/search@5.12.1': - resolution: {integrity: sha512-ItlxbxC9cKI6IU1TLWoczwJCRb6TdmkEpWv05UrPawqaAnWGRu3rcIqsc5vN483T2fSociuyV1UkWIL5I4//2w==} - engines: {node: '>= 18.19.0'} + "@redis/client": ^5.12.1 + + "@redis/search@5.12.1": + resolution: + { + integrity: sha512-ItlxbxC9cKI6IU1TLWoczwJCRb6TdmkEpWv05UrPawqaAnWGRu3rcIqsc5vN483T2fSociuyV1UkWIL5I4//2w==, + } + engines: { node: ">= 18.19.0" } peerDependencies: - '@redis/client': ^5.12.1 - - '@redis/time-series@5.12.1': - resolution: {integrity: sha512-c6JL6E3EcZJuNqKFz+KM+l9l5mpcQiKvTwgA3blt5glWJ8hjDk0yeHN3beE/MpqYIQ8UEX44ItQzgkE/gCBELQ==} - engines: {node: '>= 18.19.0'} + "@redis/client": ^5.12.1 + + "@redis/time-series@5.12.1": + resolution: + { + integrity: sha512-c6JL6E3EcZJuNqKFz+KM+l9l5mpcQiKvTwgA3blt5glWJ8hjDk0yeHN3beE/MpqYIQ8UEX44ItQzgkE/gCBELQ==, + } + engines: { node: ">= 18.19.0" } peerDependencies: - '@redis/client': ^5.12.1 + "@redis/client": ^5.12.1 - '@reduxjs/toolkit@2.12.0': - resolution: {integrity: sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==} + "@reduxjs/toolkit@2.12.0": + resolution: + { + integrity: sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==, + } peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 || ^19 react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0 @@ -2589,954 +3992,1563 @@ packages: react-redux: optional: true - '@renovatebot/pep440@4.2.1': - resolution: {integrity: sha512-2FK1hF93Fuf1laSdfiEmJvSJPVIDHEUTz68D3Fi9s0IZrrpaEcj6pTFBTbYvsgC5du4ogrtf5re7yMMvrKNgkw==} - engines: {node: ^20.9.0 || ^22.11.0 || ^24, pnpm: ^10.0.0} - - '@rolldown/binding-android-arm64@1.0.0-rc.1': - resolution: {integrity: sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@renovatebot/pep440@4.2.1": + resolution: + { + integrity: sha512-2FK1hF93Fuf1laSdfiEmJvSJPVIDHEUTz68D3Fi9s0IZrrpaEcj6pTFBTbYvsgC5du4ogrtf5re7yMMvrKNgkw==, + } + engines: { node: ^20.9.0 || ^22.11.0 || ^24, pnpm: ^10.0.0 } + + "@rolldown/binding-android-arm64@1.0.0-rc.1": + resolution: + { + integrity: sha512-He6ZoCfv5D7dlRbrhNBkuMVIHd0GDnjJwbICE1OWpG7G3S2gmJ+eXkcNLJjzjNDpeI2aRy56ou39AJM9AD8YFA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [android] - '@rolldown/binding-android-arm64@1.0.2': - resolution: {integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-android-arm64@1.0.2": + resolution: + { + integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.1': - resolution: {integrity: sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-darwin-arm64@1.0.0-rc.1": + resolution: + { + integrity: sha512-YzJdn08kSOXnj85ghHauH2iHpOJ6eSmstdRTLyaziDcUxe9SyQJgGyx/5jDIhDvtOcNvMm2Ju7m19+S/Rm1jFg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.0.2': - resolution: {integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-darwin-arm64@1.0.2": + resolution: + { + integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.1': - resolution: {integrity: sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-darwin-x64@1.0.0-rc.1": + resolution: + { + integrity: sha512-cIvAbqM+ZVV6lBSKSBtlNqH5iCiW933t1q8j0H66B3sjbe8AxIRetVqfGgcHcJtMzBIkIALlL9fcDrElWLJQcQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.2': - resolution: {integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-darwin-x64@1.0.2": + resolution: + { + integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.1': - resolution: {integrity: sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-freebsd-x64@1.0.0-rc.1": + resolution: + { + integrity: sha512-rVt+B1B/qmKwCl1XD02wKfgh3vQPXRXdB/TicV2w6g7RVAM1+cZcpigwhLarqiVCxDObFZ7UgXCxPC7tpDoRog==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.0.2': - resolution: {integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-freebsd-x64@1.0.2": + resolution: + { + integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1': - resolution: {integrity: sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1": + resolution: + { + integrity: sha512-69YKwJJBOFprQa1GktPgbuBOfnn+EGxu8sBJ1TjPER+zhSpYeaU4N07uqmyBiksOLGXsMegymuecLobfz03h8Q==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.0.2': - resolution: {integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-arm-gnueabihf@1.0.2": + resolution: + { + integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1': - resolution: {integrity: sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1": + resolution: + { + integrity: sha512-9JDhHUf3WcLfnViFWm+TyorqUtnSAHaCzlSNmMOq824prVuuzDOK91K0Hl8DUcEb9M5x2O+d2/jmBMsetRIn3g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.0.2': - resolution: {integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-arm64-gnu@1.0.2": + resolution: + { + integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.1': - resolution: {integrity: sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-arm64-musl@1.0.0-rc.1": + resolution: + { + integrity: sha512-UvApLEGholmxw/HIwmUnLq3CwdydbhaHHllvWiCTNbyGom7wTwOtz5OAQbAKZYyiEOeIXZNPkM7nA4Dtng7CLw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.0.2': - resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-arm64-musl@1.0.2": + resolution: + { + integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.2': - resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-ppc64-gnu@1.0.2": + resolution: + { + integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.2': - resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-s390x-gnu@1.0.2": + resolution: + { + integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.1': - resolution: {integrity: sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-x64-gnu@1.0.0-rc.1": + resolution: + { + integrity: sha512-uVctNgZHiGnJx5Fij7wHLhgw4uyZBVi6mykeWKOqE7bVy9Hcxn0fM/IuqdMwk6hXlaf9fFShDTFz2+YejP+x0A==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.2': - resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-x64-gnu@1.0.2": + resolution: + { + integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.1': - resolution: {integrity: sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-x64-musl@1.0.0-rc.1": + resolution: + { + integrity: sha512-T6Eg0xWwcxd/MzBcuv4Z37YVbUbJxy5cMNnbIt/Yr99wFwli30O4BPlY8hKeGyn6lWNtU0QioBS46lVzDN38bg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-linux-x64-musl@1.0.2': - resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-linux-x64-musl@1.0.2": + resolution: + { + integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.1': - resolution: {integrity: sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-openharmony-arm64@1.0.0-rc.1": + resolution: + { + integrity: sha512-PuGZVS2xNJyLADeh2F04b+Cz4NwvpglbtWACgrDOa5YDTEHKwmiTDjoD5eZ9/ptXtcpeFrMqD2H4Zn33KAh1Eg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.0.2': - resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-openharmony-arm64@1.0.2": + resolution: + { + integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.1': - resolution: {integrity: sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw==} - engines: {node: '>=14.0.0'} + "@rolldown/binding-wasm32-wasi@1.0.0-rc.1": + resolution: + { + integrity: sha512-2mOxY562ihHlz9lEXuaGEIDCZ1vI+zyFdtsoa3M62xsEunDXQE+DVPO4S4x5MPK9tKulG/aFcA/IH5eVN257Cw==, + } + engines: { node: ">=14.0.0" } cpu: [wasm32] - '@rolldown/binding-wasm32-wasi@1.0.2': - resolution: {integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-wasm32-wasi@1.0.2": + resolution: + { + integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1': - resolution: {integrity: sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1": + resolution: + { + integrity: sha512-oQVOP5cfAWZwRD0Q3nGn/cA9FW3KhMMuQ0NIndALAe6obqjLhqYVYDiGGRGrxvnjJsVbpLwR14gIUYnpIcHR1g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.0.2': - resolution: {integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-win32-arm64-msvc@1.0.2": + resolution: + { + integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.1': - resolution: {integrity: sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-win32-x64-msvc@1.0.0-rc.1": + resolution: + { + integrity: sha512-Ydsxxx++FNOuov3wCBPaYjZrEvKOOGq3k+BF4BPridhg2pENfitSRD2TEuQ8i33bp5VptuNdC9IzxRKU031z5A==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.2': - resolution: {integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==} - engines: {node: ^20.19.0 || >=22.12.0} + "@rolldown/binding-win32-x64-msvc@1.0.2": + resolution: + { + integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==, + } + engines: { node: ^20.19.0 || >=22.12.0 } cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.1': - resolution: {integrity: sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA==} - - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} + "@rolldown/pluginutils@1.0.0-rc.1": + resolution: + { + integrity: sha512-UTBjtTxVOhodhzFVp/ayITaTETRHPUPYZPXQe0WU0wOgxghMojXxYjOiPOauKIYNWJAWS2fd7gJgGQK8GU8vDA==, + } + + "@rolldown/pluginutils@1.0.1": + resolution: + { + integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==, + } + + "@rollup/pluginutils@5.3.0": + resolution: + { + integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==, + } + engines: { node: ">=14.0.0" } peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} + "@rollup/rollup-android-arm-eabi@4.60.4": + resolution: + { + integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==, + } cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} + "@rollup/rollup-android-arm64@4.60.4": + resolution: + { + integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==, + } cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} + "@rollup/rollup-darwin-arm64@4.60.4": + resolution: + { + integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==, + } cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} + "@rollup/rollup-darwin-x64@4.60.4": + resolution: + { + integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==, + } cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} + "@rollup/rollup-freebsd-arm64@4.60.4": + resolution: + { + integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==, + } cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} + "@rollup/rollup-freebsd-x64@4.60.4": + resolution: + { + integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==, + } cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} + "@rollup/rollup-linux-arm-gnueabihf@4.60.4": + resolution: + { + integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==, + } cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} + "@rollup/rollup-linux-arm-musleabihf@4.60.4": + resolution: + { + integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==, + } cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} + "@rollup/rollup-linux-arm64-gnu@4.60.4": + resolution: + { + integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==, + } cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} + "@rollup/rollup-linux-arm64-musl@4.60.4": + resolution: + { + integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==, + } cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} + "@rollup/rollup-linux-loong64-gnu@4.60.4": + resolution: + { + integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==, + } cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} + "@rollup/rollup-linux-loong64-musl@4.60.4": + resolution: + { + integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==, + } cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} + "@rollup/rollup-linux-ppc64-gnu@4.60.4": + resolution: + { + integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==, + } cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} + "@rollup/rollup-linux-ppc64-musl@4.60.4": + resolution: + { + integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==, + } cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} + "@rollup/rollup-linux-riscv64-gnu@4.60.4": + resolution: + { + integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==, + } cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} + "@rollup/rollup-linux-riscv64-musl@4.60.4": + resolution: + { + integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==, + } cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} + "@rollup/rollup-linux-s390x-gnu@4.60.4": + resolution: + { + integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==, + } cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} + "@rollup/rollup-linux-x64-gnu@4.60.4": + resolution: + { + integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==, + } cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} + "@rollup/rollup-linux-x64-musl@4.60.4": + resolution: + { + integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==, + } cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} + "@rollup/rollup-openbsd-x64@4.60.4": + resolution: + { + integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==, + } cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} + "@rollup/rollup-openharmony-arm64@4.60.4": + resolution: + { + integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==, + } cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} + "@rollup/rollup-win32-arm64-msvc@4.60.4": + resolution: + { + integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==, + } cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} + "@rollup/rollup-win32-ia32-msvc@4.60.4": + resolution: + { + integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==, + } cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} + "@rollup/rollup-win32-x64-gnu@4.60.4": + resolution: + { + integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==, + } cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} + "@rollup/rollup-win32-x64-msvc@4.60.4": + resolution: + { + integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==, + } cpu: [x64] os: [win32] - '@sentry/conventions@0.12.0': - resolution: {integrity: sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==} - engines: {node: '>=14'} + "@sentry/conventions@0.12.0": + resolution: + { + integrity: sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==, + } + engines: { node: ">=14" } - '@sentry/core@10.53.1': - resolution: {integrity: sha512-XG4ezlkyuAPjBC5+9kXC94rXXuqYTw9NRhfaDHssbTFaGnqBR8vQX2UUgZfY7ucbeelRDGfBu1sywoU+mB04uA==} - engines: {node: '>=18'} + "@sentry/core@10.53.1": + resolution: + { + integrity: sha512-XG4ezlkyuAPjBC5+9kXC94rXXuqYTw9NRhfaDHssbTFaGnqBR8vQX2UUgZfY7ucbeelRDGfBu1sywoU+mB04uA==, + } + engines: { node: ">=18" } - '@sentry/core@10.59.0': - resolution: {integrity: sha512-QeG7XZL5j6CkToYCE7OwCerb/r742Tjj9p1BBohBKcypYTPRuqfD+A3FeUj7pk5CGO6Vj1/gOAmdbuuNbR51dQ==} - engines: {node: '>=18'} + "@sentry/core@10.59.0": + resolution: + { + integrity: sha512-QeG7XZL5j6CkToYCE7OwCerb/r742Tjj9p1BBohBKcypYTPRuqfD+A3FeUj7pk5CGO6Vj1/gOAmdbuuNbR51dQ==, + } + engines: { node: ">=18" } - '@sentry/junior-dashboard@file:packages/junior-dashboard': - resolution: {directory: packages/junior-dashboard, type: directory} + "@sentry/junior-dashboard@file:packages/junior-dashboard": + resolution: { directory: packages/junior-dashboard, type: directory } - '@sentry/junior-memory@file:packages/junior-memory': - resolution: {directory: packages/junior-memory, type: directory} + "@sentry/junior-memory@file:packages/junior-memory": + resolution: { directory: packages/junior-memory, type: directory } - '@sentry/junior-plugin-api@file:packages/junior-plugin-api': - resolution: {directory: packages/junior-plugin-api, type: directory} + "@sentry/junior-plugin-api@file:packages/junior-plugin-api": + resolution: { directory: packages/junior-plugin-api, type: directory } - '@sentry/junior-scheduler@file:packages/junior-scheduler': - resolution: {directory: packages/junior-scheduler, type: directory} + "@sentry/junior-scheduler@file:packages/junior-scheduler": + resolution: { directory: packages/junior-scheduler, type: directory } - '@sentry/junior-testing@file:packages/junior-testing': - resolution: {directory: packages/junior-testing, type: directory} + "@sentry/junior-testing@file:packages/junior-testing": + resolution: { directory: packages/junior-testing, type: directory } - '@sentry/junior@file:packages/junior': - resolution: {directory: packages/junior, type: directory} + "@sentry/junior@file:packages/junior": + resolution: { directory: packages/junior, type: directory } hasBin: true - '@sentry/node-core@10.53.1': - resolution: {integrity: sha512-iH7SMcM/7jPbN+t7+7ussQOiIqI4BMOGt4VYWlV71/z7k0pY+YPaSvlfVkNXfISiDzFAKv0ecCY3BmsLMu1xDQ==} - engines: {node: '>=18'} + "@sentry/node-core@10.53.1": + resolution: + { + integrity: sha512-iH7SMcM/7jPbN+t7+7ussQOiIqI4BMOGt4VYWlV71/z7k0pY+YPaSvlfVkNXfISiDzFAKv0ecCY3BmsLMu1xDQ==, + } + engines: { node: ">=18" } peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/core': ^1.30.1 || ^2.1.0 - '@opentelemetry/exporter-trace-otlp-http': '>=0.57.0 <1' - '@opentelemetry/instrumentation': '>=0.57.1 <1' - '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - '@opentelemetry/semantic-conventions': ^1.39.0 + "@opentelemetry/api": ^1.9.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 + "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1" + "@opentelemetry/instrumentation": ">=0.57.1 <1" + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 + "@opentelemetry/semantic-conventions": ^1.39.0 peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@opentelemetry/core': - optional: true - '@opentelemetry/exporter-trace-otlp-http': - optional: true - '@opentelemetry/instrumentation': - optional: true - '@opentelemetry/sdk-trace-base': + "@opentelemetry/api": optional: true - '@opentelemetry/semantic-conventions': + "@opentelemetry/core": optional: true - - '@sentry/node-core@10.59.0': - resolution: {integrity: sha512-qFbepzntYhDleNG9ZCZWCSoAJK0Nsx+UJxsuiygaaAf1rJMj95RVckLyslhY86pyDLVATNMmWm2elm6etgKaJw==} - engines: {node: '>=18'} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/core': ^1.30.1 || ^2.1.0 - '@opentelemetry/exporter-trace-otlp-http': '>=0.57.0 <1' - '@opentelemetry/instrumentation': '>=0.57.1 <1' - '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@opentelemetry/core': + "@opentelemetry/exporter-trace-otlp-http": optional: true - '@opentelemetry/exporter-trace-otlp-http': + "@opentelemetry/instrumentation": optional: true - '@opentelemetry/instrumentation': + "@opentelemetry/sdk-trace-base": optional: true - '@opentelemetry/sdk-trace-base': + "@opentelemetry/semantic-conventions": optional: true - '@sentry/node@10.53.1': - resolution: {integrity: sha512-rxHVil0tJAmz+keFcZCj1LaUdgdkK66E/l0gqh2p1209PNCGoD3lnClFr6vusy1aF3zF8O9JPtuMEJzXOKhs+w==} - engines: {node: '>=18'} - - '@sentry/node@10.59.0': - resolution: {integrity: sha512-qzqbP6OVoMijlDBUxWtbvVF5j73+vyzGFi+yFIslhVvzBj97TFkIeP3TpBLsmu/0L5ZvxpQCCEmzJ677tFkq/g==} - engines: {node: '>=18'} - - '@sentry/opentelemetry@10.53.1': - resolution: {integrity: sha512-Zok6UXla0mFOjd1YnVb1TZtQNOry9v93fXUqx8jmDaygwWM2BwvP8rBQabLz0/OZXo8+35oge+Vmw+QY5aesnA==} - engines: {node: '>=18'} + "@sentry/node-core@10.59.0": + resolution: + { + integrity: sha512-qFbepzntYhDleNG9ZCZWCSoAJK0Nsx+UJxsuiygaaAf1rJMj95RVckLyslhY86pyDLVATNMmWm2elm6etgKaJw==, + } + engines: { node: ">=18" } peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/core': ^1.30.1 || ^2.1.0 - '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - '@opentelemetry/semantic-conventions': ^1.39.0 - - '@sentry/opentelemetry@10.59.0': - resolution: {integrity: sha512-wV9/HR9btrNhSkJC2S0urqsD9pE4K0f6AmdfTK3qhH505mLoyV4ekTG66hdDR9xD2zOYCm58CNzaK+336zu3Gg==} - engines: {node: '>=18'} - peerDependencies: - '@opentelemetry/api': ^1.9.0 - '@opentelemetry/core': ^1.30.1 || ^2.1.0 - '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - - '@sentry/server-utils@10.59.0': - resolution: {integrity: sha512-mR3fWaU7uGxIstRba6YO+/6V3qIa7432F7/U8EWHry+dY4C9DWAVG90E2GCzeD2MwLSP0tB25i8p1TWTGiQgVg==} - engines: {node: '>=18'} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + "@opentelemetry/api": ^1.9.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 + "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1" + "@opentelemetry/instrumentation": ">=0.57.1 <1" + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 peerDependenciesMeta: - vite: + "@opentelemetry/api": + optional: true + "@opentelemetry/core": + optional: true + "@opentelemetry/exporter-trace-otlp-http": + optional: true + "@opentelemetry/instrumentation": + optional: true + "@opentelemetry/sdk-trace-base": optional: true - '@sentry/starlight-theme@0.7.0': - resolution: {integrity: sha512-yDVa7JMKKRsH3BwTFezudPJYHoZbMPi0Kvz28Szj1GT2Q7gj3Kh9cVZrooJbWqO5aexj0MFGYe3ejbTK1VXvcg==} - engines: {node: '>=22.12.0'} - peerDependencies: - '@astrojs/starlight': '>=0.39.0' - - '@shikijs/core@4.1.0': - resolution: {integrity: sha512-jLJtSJeuFffqX6/inRE1zqU5aFv2hrszvYgq3OjbAgFRZiWv7abKMDdQzYxuSDfmUPQozZvI/kuy6VMTvnvqTQ==} - engines: {node: '>=20'} - - '@shikijs/engine-javascript@4.1.0': - resolution: {integrity: sha512-YquhawCUgaBfhsS72e2Y/dI59gCBNPHu3fEO/tvLaXrTssxZrY5ddjtNLTwndrMgPo8b3IscE+xoICDzpTmlFQ==} - engines: {node: '>=20'} - - '@shikijs/engine-oniguruma@3.23.0': - resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} - - '@shikijs/engine-oniguruma@4.1.0': - resolution: {integrity: sha512-axLpjVs45YBvvINa+dJF+NPW+KtFkNXsFr4SDw2BMj9GdeMnGxVB9PQb2xXlJYovslt/nz6giedAyOANkfc7hg==} - engines: {node: '>=20'} - - '@shikijs/langs@3.23.0': - resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} - - '@shikijs/langs@4.1.0': - resolution: {integrity: sha512-nwOMruEkbgdZfQ/b8CgpNBVOpvG1k0N5tbmgiFeqsan401+x3ILqlzZJowSla4Agmq4hG2Uf2wh5jLTEhR8VSg==} - engines: {node: '>=20'} - - '@shikijs/primitive@4.1.0': - resolution: {integrity: sha512-zx2/2Uwj2q9X3KSyYREEhXO23xBw5WUhP4orK2lE4r+t9JGITmEe0JH+wPmJhqHpOT2bRRs6lAL945+LDvOAGw==} - engines: {node: '>=20'} - - '@shikijs/themes@3.23.0': - resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} - - '@shikijs/themes@4.1.0': - resolution: {integrity: sha512-emCcTnUM7yO2wltYbaxm+yLvcCI4+h8XBKc4KmJ7EZUXoSGjcCHifkI//R4OFit9ewpg7H2/9tjOuXrT2v/Knw==} - engines: {node: '>=20'} - - '@shikijs/types@3.23.0': - resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} - - '@shikijs/types@4.1.0': - resolution: {integrity: sha512-3EQWX54fMpniOrDblzAhiwiJwpiTMW6+B9DWyUd9ska483tbayFYuw47UxwuPknI31bKnySfVQ/QW+jFL4rFdA==} - engines: {node: '>=20'} - - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - - '@sinclair/typebox@0.25.24': - resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} - - '@sinclair/typebox@0.34.49': - resolution: {integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==} - - '@slack/logger@4.0.1': - resolution: {integrity: sha512-6cmdPrV/RYfd2U0mDGiMK8S7OJqpCTm7enMLRR3edccsPX8j7zXTLnaEF4fhxxJJTAIOil6+qZrnUPTuaLvwrQ==} - engines: {node: '>= 18', npm: '>= 8.6.0'} - - '@slack/socket-mode@2.0.7': - resolution: {integrity: sha512-qYy07je71WnEHgRwmw12DlAnZLi5HXmdlI2WUzUK2LH/rYXQpP6uEg462S5CwfE8FoCKUdIigHtYnOOfzZH1lQ==} - engines: {node: '>= 18', npm: '>= 8.6.0'} - - '@slack/types@2.21.1': - resolution: {integrity: sha512-I8vmSjNYWsaxuWPx6dz4yeh0h7vRBWbgAMK14LEmblbZ404BtrPbXs6jDPx4cYgGf8msDGF4A9opLZBu21FViQ==} - engines: {node: '>= 12.13.0', npm: '>= 6.12.0'} - - '@slack/web-api@7.16.0': - resolution: {integrity: sha512-68SAV77uuGKuhyyaRytX8UijVnqSLsTSKslGXw17cjQYXn+jtNl7gbaEjHgC5x2rhCuFdahBrEC2VCLppbzReg==} - engines: {node: '>= 18', npm: '>= 8.6.0'} - - '@smithy/core@3.24.4': - resolution: {integrity: sha512-3UNRKEyQyAgVgM0LGlerCLm+ChZWZ1GPfde+jBEW6bm6bSBGU1p0EbblaUV3unbhwvidjLA5Zs3sOs7mnZwvAw==} - engines: {node: '>=18.0.0'} - - '@smithy/credential-provider-imds@4.3.4': - resolution: {integrity: sha512-vKW0MEFRU4Y3MkVZUkpJm+g9qyPGLCXhc0YLggUdSdBB4g7IaSSsCE75P9rBXyWHrXY1UYSQUl8/DwsTR7QciA==} - engines: {node: '>=18.0.0'} - - '@smithy/fetch-http-handler@5.4.4': - resolution: {integrity: sha512-qM7AUKI4G6d7lNgaZD3lA1tWSolh5r6gcixfTZAPstVURfjIbvreVTPz+994M0yC3HbX4YYhDRgr31Xy3XwWOQ==} - engines: {node: '>=18.0.0'} - - '@smithy/is-array-buffer@2.2.0': - resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} - engines: {node: '>=14.0.0'} - - '@smithy/node-http-handler@4.7.4': - resolution: {integrity: sha512-HIeF+1vrDGzPkkv39Hj2vlHSXHY3p958jd/8ZnePIY6+ZOsQX8coyEUKO5yQu4r0bQIVsbpotVIrXXwyycMStQ==} - engines: {node: '>=18.0.0'} - - '@smithy/signature-v4@5.4.4': - resolution: {integrity: sha512-e5UtkMvsatzBfbeBZjEOt0k0Z3BEsjTFL/n6fdO5vtBLe67tdy0dX7xw2DU7uZ3acwoHyeCqpU2Fzb7pxwHb6Q==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.14.2': - resolution: {integrity: sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-buffer-from@2.2.0': - resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} - engines: {node: '>=14.0.0'} - - '@smithy/util-utf8@2.3.0': - resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} - engines: {node: '>=14.0.0'} - - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} - - '@standard-schema/utils@0.3.0': - resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} - - '@tailwindcss/cli@4.3.0': - resolution: {integrity: sha512-X9kdlqyMopO9fewbgHsEeuy31YzMHbdZ9VsKt004tB+mxSg1CNbyhZYCzvhciN0AM4R4b5lvIprPjtNq7iQxpQ==} - hasBin: true - - '@tailwindcss/node@4.3.0': - resolution: {integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==} - - '@tailwindcss/oxide-android-arm64@4.3.0': - resolution: {integrity: sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [android] - - '@tailwindcss/oxide-darwin-arm64@4.3.0': - resolution: {integrity: sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [darwin] - - '@tailwindcss/oxide-darwin-x64@4.3.0': - resolution: {integrity: sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==} - engines: {node: '>= 20'} - cpu: [x64] - os: [darwin] - - '@tailwindcss/oxide-freebsd-x64@4.3.0': - resolution: {integrity: sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==} - engines: {node: '>= 20'} - cpu: [x64] - os: [freebsd] - - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': - resolution: {integrity: sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==} - engines: {node: '>= 20'} - cpu: [arm] - os: [linux] - - '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': - resolution: {integrity: sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@tailwindcss/oxide-linux-arm64-musl@4.3.0': - resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@tailwindcss/oxide-linux-x64-gnu@4.3.0': - resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@tailwindcss/oxide-linux-x64-musl@4.3.0': - resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==} - engines: {node: '>= 20'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@tailwindcss/oxide-wasm32-wasi@4.3.0': - resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] - bundledDependencies: - - '@napi-rs/wasm-runtime' - - '@emnapi/core' - - '@emnapi/runtime' - - '@tybys/wasm-util' - - '@emnapi/wasi-threads' - - tslib - - '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': - resolution: {integrity: sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==} - engines: {node: '>= 20'} - cpu: [arm64] - os: [win32] - - '@tailwindcss/oxide-win32-x64-msvc@4.3.0': - resolution: {integrity: sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==} - engines: {node: '>= 20'} - cpu: [x64] - os: [win32] - - '@tailwindcss/oxide@4.3.0': - resolution: {integrity: sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==} - engines: {node: '>= 20'} - - '@tanstack/query-core@5.100.14': - resolution: {integrity: sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==} - - '@tanstack/react-query@5.100.14': - resolution: {integrity: sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==} - peerDependencies: - react: ^18 || ^19 - - '@tokenizer/inflate@0.4.1': - resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} - engines: {node: '>=18'} - - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - - '@ts-morph/common@0.11.1': - resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} - - '@tybys/wasm-util@0.10.2': - resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} - - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/d3-array@3.2.2': - resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} - - '@types/d3-color@3.1.3': - resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} - - '@types/d3-ease@3.0.2': - resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} - - '@types/d3-interpolate@3.0.4': - resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} - - '@types/d3-path@3.1.1': - resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} - - '@types/d3-scale@4.0.9': - resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} - - '@types/d3-shape@3.1.8': - resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} - - '@types/d3-time@3.0.4': - resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} - - '@types/d3-timer@3.0.2': - resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} - - '@types/debug@4.1.13': - resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} - - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - - '@types/estree-jsx@1.0.5': - resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/mdast@4.0.4': - resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - - '@types/mdx@2.0.13': - resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - - '@types/mysql@2.15.27': - resolution: {integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==} - - '@types/nlcst@2.0.3': - resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} - - '@types/node@20.11.0': - resolution: {integrity: sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==} - - '@types/node@24.12.4': - resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} - - '@types/node@25.9.1': - resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} - - '@types/pg-pool@2.0.7': - resolution: {integrity: sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==} - - '@types/pg@8.15.6': - resolution: {integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==} - - '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} - peerDependencies: - '@types/react': ^19.2.0 - - '@types/react@19.2.15': - resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} - - '@types/retry@0.12.0': - resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} - - '@types/sax@1.2.7': - resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} - - '@types/set-cookie-parser@2.4.10': - resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==} - - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - - '@types/tedious@4.0.14': - resolution: {integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==} - - '@types/unist@2.0.11': - resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@types/use-sync-external-store@0.0.6': - resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} - - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - - '@ungap/structured-clone@1.3.1': - resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} - - '@vercel/backends@0.7.2': - resolution: {integrity: sha512-+v0H6VA3j37aSzi7CfrbcV2Xw5ySCWDhp2Boeuwy1sx7oOEwKNIumQB3D3yueDYUwiSKqKYnPIJUBIcRWFW5vQ==} - - '@vercel/blob@2.4.0': - resolution: {integrity: sha512-ncQ8CRb6XoEAYJwjOTRGpACRT6h/AeY+/33gLyeVxG5BIes27OPm1jmqreF+JHjcTmGhClTP+kBpmyLfbV0xew==} - engines: {node: '>=20.0.0'} - - '@vercel/build-utils@13.26.1': - resolution: {integrity: sha512-vMdSJ0U2YVkBWfSEHEj9WOuI8g52ozlluAiZhAGh2osGNYrD+w7IsvhLWXseFsAEr7v2rNTkY9nbrfgYiHYA+Q==} - - '@vercel/cervel@0.1.7': - resolution: {integrity: sha512-YlVc328X027b7YHU8PrTIbWPizD5rYxZTcjmexTdwkJxCZu/wQfYtJ6CXa05QnjZUukoFRiaMe+tb9kCCRxfHA==} - hasBin: true - - '@vercel/cli-config@0.1.2': - resolution: {integrity: sha512-XQOcuCM+8tKjh3sfgGRKRuNh78u2D8uGpDJIFcCtFi2tUqbGvqmJo790XX7+Bwakk08y0FCrs2JlEjvvwRhpAg==} - - '@vercel/detect-agent@1.2.3': - resolution: {integrity: sha512-VYNCgUc0nOmC4WJmWw9GkrKdfr8Zl4/rxhC5SvgacBgxiW9W/9NRttUoHHXV8xdII3MaRgkZZVX8Ikzc/Jmjag==} - engines: {node: '>=14'} - - '@vercel/elysia@0.1.80': - resolution: {integrity: sha512-H2NBFYP1hAML/3TCz9r0hTyd1dRCxKzUl7k2ShziIh/tNx5qfcOPhc2sA8s/9W8O5Yg5rQb4lyLh8qxR+96grg==} - - '@vercel/error-utils@2.1.0': - resolution: {integrity: sha512-DiJcXBOB9N6QM4d7hYPM9Ck/AUjzBl58XNQPxS74o7CuvIanjzrGgygP/70VsyEASeIJMazk1LrhwcNTR/eZGQ==} - - '@vercel/express@0.1.90': - resolution: {integrity: sha512-7x7WwnZ2mai9LZBpxEIIlllX7En//jaktwkpOE8MmpBzfcGhU8YAvCykSq5fDIglSF+lMW2/NoDBZzUvVZd7pA==} - - '@vercel/fastify@0.1.83': - resolution: {integrity: sha512-abjYa0wTlz3KEFfXD6MpS0NLTIX0sB6Z1EdEALvtdOj2LesvvZE1RB9GT8ZCrGhbvSQXNwbojPxA09rOcMx74A==} - - '@vercel/fun@1.3.0': - resolution: {integrity: sha512-8erw9uPe0dFg45THkNxmjtvMX143SkZebmjgSVbcM3XCkXu3RIiBaJMcMNG8aaS+rnTuw8+d4De9HVT0M/r3wg==} - engines: {node: '>= 18'} - - '@vercel/functions@3.6.0': - resolution: {integrity: sha512-Xj68JYqqJwtqFWJN7EWmFN7MOiUjv5whjw48UEKqQbg8r7hRkhuJhncTU0ba3jJCh/wxEuLWckrtsKcrHQraxw==} - engines: {node: '>= 20'} + "@sentry/node@10.53.1": + resolution: + { + integrity: sha512-rxHVil0tJAmz+keFcZCj1LaUdgdkK66E/l0gqh2p1209PNCGoD3lnClFr6vusy1aF3zF8O9JPtuMEJzXOKhs+w==, + } + engines: { node: ">=18" } + + "@sentry/node@10.59.0": + resolution: + { + integrity: sha512-qzqbP6OVoMijlDBUxWtbvVF5j73+vyzGFi+yFIslhVvzBj97TFkIeP3TpBLsmu/0L5ZvxpQCCEmzJ677tFkq/g==, + } + engines: { node: ">=18" } + + "@sentry/opentelemetry@10.53.1": + resolution: + { + integrity: sha512-Zok6UXla0mFOjd1YnVb1TZtQNOry9v93fXUqx8jmDaygwWM2BwvP8rBQabLz0/OZXo8+35oge+Vmw+QY5aesnA==, + } + engines: { node: ">=18" } peerDependencies: - '@aws-sdk/credential-provider-web-identity': '*' + "@opentelemetry/api": ^1.9.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 + "@opentelemetry/semantic-conventions": ^1.39.0 + + "@sentry/opentelemetry@10.59.0": + resolution: + { + integrity: sha512-wV9/HR9btrNhSkJC2S0urqsD9pE4K0f6AmdfTK3qhH505mLoyV4ekTG66hdDR9xD2zOYCm58CNzaK+336zu3Gg==, + } + engines: { node: ">=18" } + peerDependencies: + "@opentelemetry/api": ^1.9.0 + "@opentelemetry/core": ^1.30.1 || ^2.1.0 + "@opentelemetry/sdk-trace-base": ^1.30.1 || ^2.1.0 + + "@sentry/server-utils@10.59.0": + resolution: + { + integrity: sha512-mR3fWaU7uGxIstRba6YO+/6V3qIa7432F7/U8EWHry+dY4C9DWAVG90E2GCzeD2MwLSP0tB25i8p1TWTGiQgVg==, + } + engines: { node: ">=18" } + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 peerDependenciesMeta: - '@aws-sdk/credential-provider-web-identity': + vite: optional: true - '@vercel/gatsby-plugin-vercel-analytics@1.0.11': - resolution: {integrity: sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==} - - '@vercel/gatsby-plugin-vercel-builder@2.2.7': - resolution: {integrity: sha512-5W4hhjCQzvehUQZHbKmXqbI5Ojx7b2BNJwN9UOGmGckG/UUTMJjqnVh9+TLzqxkuCNfqrjPoeS/+0v/AkH3DCQ==} - - '@vercel/go@3.7.1': - resolution: {integrity: sha512-63dl9firXTcP283mPnxmAb0LyWV72hWR6r8AA5ycKAiwmrkmoOh96XKDE7arXiNQDTQK1YP0oBDD6CH7JM1I8w==} - - '@vercel/h3@0.1.89': - resolution: {integrity: sha512-OnCGGd5bOO9pNvVqgwFb7h8mDevetmUolmdOL1r6EittsY2FgDxs5MnfbA6jLlzzE0P+V1D6ZX2U3WSbX1zgaQ==} - - '@vercel/hono@0.2.83': - resolution: {integrity: sha512-5lASV9a0qref0teqvhPucr+5KTZGwnTzYzQpff8Grhr5likf47he2SH60dflyoeMTVWbIKTTuXgu5V6+nHqKvg==} - - '@vercel/hydrogen@1.3.7': - resolution: {integrity: sha512-nh8hZ76Ipf9FRmMmQGd4SjkE0zxdjt+TUpZcuCIUG7yaHEh9STQV655I8rxKCB3hEWaKB3HALGgxZ0htIjQtZQ==} - - '@vercel/koa@0.1.63': - resolution: {integrity: sha512-DL41OzNaYUZnuaUWSCKJIBiN5tvntBeN3UumE3b1I20qZDhPeTQXmSUMqJHue+UHcvdJWuIyP+7p0k9hTD3Jsw==} - - '@vercel/nestjs@0.2.84': - resolution: {integrity: sha512-l0WNAxFLbOo11E9gqOen8cl0AHN87PqIoY3eGG5z2aT/z4xw/LJ4zZPD8OKfcZXtGS+hxlMYuRz/vjfOYmpmtg==} - - '@vercel/next@4.17.3': - resolution: {integrity: sha512-RwyiyRLLbFe7FLYIFBiZQrQGbmNNiSBvagPn+uN2/JRgaJp659wU/z1O+1+i1ESzWhF1KYoiIcx04njt/XmbSQ==} - - '@vercel/nft@1.5.0': - resolution: {integrity: sha512-IWTDeIoWhQ7ZtRO/JRKH+jhmeQvZYhtGPmzw/QGDY+wDCQqfm25P9yIdoAFagu4fWsK4IwZXDFIjrmp5rRm/sA==} - engines: {node: '>=20'} + "@sentry/starlight-theme@0.7.0": + resolution: + { + integrity: sha512-yDVa7JMKKRsH3BwTFezudPJYHoZbMPi0Kvz28Szj1GT2Q7gj3Kh9cVZrooJbWqO5aexj0MFGYe3ejbTK1VXvcg==, + } + engines: { node: ">=22.12.0" } + peerDependencies: + "@astrojs/starlight": ">=0.39.0" + + "@shikijs/core@4.1.0": + resolution: + { + integrity: sha512-jLJtSJeuFffqX6/inRE1zqU5aFv2hrszvYgq3OjbAgFRZiWv7abKMDdQzYxuSDfmUPQozZvI/kuy6VMTvnvqTQ==, + } + engines: { node: ">=20" } + + "@shikijs/engine-javascript@4.1.0": + resolution: + { + integrity: sha512-YquhawCUgaBfhsS72e2Y/dI59gCBNPHu3fEO/tvLaXrTssxZrY5ddjtNLTwndrMgPo8b3IscE+xoICDzpTmlFQ==, + } + engines: { node: ">=20" } + + "@shikijs/engine-oniguruma@3.23.0": + resolution: + { + integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==, + } + + "@shikijs/engine-oniguruma@4.1.0": + resolution: + { + integrity: sha512-axLpjVs45YBvvINa+dJF+NPW+KtFkNXsFr4SDw2BMj9GdeMnGxVB9PQb2xXlJYovslt/nz6giedAyOANkfc7hg==, + } + engines: { node: ">=20" } + + "@shikijs/langs@3.23.0": + resolution: + { + integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==, + } + + "@shikijs/langs@4.1.0": + resolution: + { + integrity: sha512-nwOMruEkbgdZfQ/b8CgpNBVOpvG1k0N5tbmgiFeqsan401+x3ILqlzZJowSla4Agmq4hG2Uf2wh5jLTEhR8VSg==, + } + engines: { node: ">=20" } + + "@shikijs/primitive@4.1.0": + resolution: + { + integrity: sha512-zx2/2Uwj2q9X3KSyYREEhXO23xBw5WUhP4orK2lE4r+t9JGITmEe0JH+wPmJhqHpOT2bRRs6lAL945+LDvOAGw==, + } + engines: { node: ">=20" } + + "@shikijs/themes@3.23.0": + resolution: + { + integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==, + } + + "@shikijs/themes@4.1.0": + resolution: + { + integrity: sha512-emCcTnUM7yO2wltYbaxm+yLvcCI4+h8XBKc4KmJ7EZUXoSGjcCHifkI//R4OFit9ewpg7H2/9tjOuXrT2v/Knw==, + } + engines: { node: ">=20" } + + "@shikijs/types@3.23.0": + resolution: + { + integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==, + } + + "@shikijs/types@4.1.0": + resolution: + { + integrity: sha512-3EQWX54fMpniOrDblzAhiwiJwpiTMW6+B9DWyUd9ska483tbayFYuw47UxwuPknI31bKnySfVQ/QW+jFL4rFdA==, + } + engines: { node: ">=20" } + + "@shikijs/vscode-textmate@10.0.2": + resolution: + { + integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==, + } + + "@sinclair/typebox@0.25.24": + resolution: + { + integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==, + } + + "@sinclair/typebox@0.34.49": + resolution: + { + integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==, + } + + "@slack/logger@4.0.1": + resolution: + { + integrity: sha512-6cmdPrV/RYfd2U0mDGiMK8S7OJqpCTm7enMLRR3edccsPX8j7zXTLnaEF4fhxxJJTAIOil6+qZrnUPTuaLvwrQ==, + } + engines: { node: ">= 18", npm: ">= 8.6.0" } + + "@slack/socket-mode@2.0.7": + resolution: + { + integrity: sha512-qYy07je71WnEHgRwmw12DlAnZLi5HXmdlI2WUzUK2LH/rYXQpP6uEg462S5CwfE8FoCKUdIigHtYnOOfzZH1lQ==, + } + engines: { node: ">= 18", npm: ">= 8.6.0" } + + "@slack/types@2.21.1": + resolution: + { + integrity: sha512-I8vmSjNYWsaxuWPx6dz4yeh0h7vRBWbgAMK14LEmblbZ404BtrPbXs6jDPx4cYgGf8msDGF4A9opLZBu21FViQ==, + } + engines: { node: ">= 12.13.0", npm: ">= 6.12.0" } + + "@slack/web-api@7.16.0": + resolution: + { + integrity: sha512-68SAV77uuGKuhyyaRytX8UijVnqSLsTSKslGXw17cjQYXn+jtNl7gbaEjHgC5x2rhCuFdahBrEC2VCLppbzReg==, + } + engines: { node: ">= 18", npm: ">= 8.6.0" } + + "@smithy/core@3.24.4": + resolution: + { + integrity: sha512-3UNRKEyQyAgVgM0LGlerCLm+ChZWZ1GPfde+jBEW6bm6bSBGU1p0EbblaUV3unbhwvidjLA5Zs3sOs7mnZwvAw==, + } + engines: { node: ">=18.0.0" } + + "@smithy/credential-provider-imds@4.3.4": + resolution: + { + integrity: sha512-vKW0MEFRU4Y3MkVZUkpJm+g9qyPGLCXhc0YLggUdSdBB4g7IaSSsCE75P9rBXyWHrXY1UYSQUl8/DwsTR7QciA==, + } + engines: { node: ">=18.0.0" } + + "@smithy/fetch-http-handler@5.4.4": + resolution: + { + integrity: sha512-qM7AUKI4G6d7lNgaZD3lA1tWSolh5r6gcixfTZAPstVURfjIbvreVTPz+994M0yC3HbX4YYhDRgr31Xy3XwWOQ==, + } + engines: { node: ">=18.0.0" } + + "@smithy/is-array-buffer@2.2.0": + resolution: + { + integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==, + } + engines: { node: ">=14.0.0" } + + "@smithy/node-http-handler@4.7.4": + resolution: + { + integrity: sha512-HIeF+1vrDGzPkkv39Hj2vlHSXHY3p958jd/8ZnePIY6+ZOsQX8coyEUKO5yQu4r0bQIVsbpotVIrXXwyycMStQ==, + } + engines: { node: ">=18.0.0" } + + "@smithy/signature-v4@5.4.4": + resolution: + { + integrity: sha512-e5UtkMvsatzBfbeBZjEOt0k0Z3BEsjTFL/n6fdO5vtBLe67tdy0dX7xw2DU7uZ3acwoHyeCqpU2Fzb7pxwHb6Q==, + } + engines: { node: ">=18.0.0" } + + "@smithy/types@4.14.2": + resolution: + { + integrity: sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==, + } + engines: { node: ">=18.0.0" } + + "@smithy/util-buffer-from@2.2.0": + resolution: + { + integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==, + } + engines: { node: ">=14.0.0" } + + "@smithy/util-utf8@2.3.0": + resolution: + { + integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==, + } + engines: { node: ">=14.0.0" } + + "@standard-schema/spec@1.1.0": + resolution: + { + integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==, + } + + "@standard-schema/utils@0.3.0": + resolution: + { + integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==, + } + + "@tailwindcss/cli@4.3.0": + resolution: + { + integrity: sha512-X9kdlqyMopO9fewbgHsEeuy31YzMHbdZ9VsKt004tB+mxSg1CNbyhZYCzvhciN0AM4R4b5lvIprPjtNq7iQxpQ==, + } hasBin: true - '@vercel/node@5.8.4': - resolution: {integrity: sha512-YY1sr6Vd32PL11cwMhmt7qhcAmqxbITNNq9JPLFpI0xWlr7Aiu81fgyTCV32mJvPq//NTgMumVI1hQFnojtfNQ==} - - '@vercel/oidc@3.2.0': - resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} - engines: {node: '>= 20'} + "@tailwindcss/node@4.3.0": + resolution: + { + integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==, + } + + "@tailwindcss/oxide-android-arm64@4.3.0": + resolution: + { + integrity: sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==, + } + engines: { node: ">= 20" } + cpu: [arm64] + os: [android] - '@vercel/oidc@3.4.1': - resolution: {integrity: sha512-H6B+/ig/GoahccL3WZjiHayHw1H5KhvTJNceqYulwfK9kkz5iul2hTmYzcJ7tTCQzyd0dutuL9xYFZCyLUqsog==} - engines: {node: '>= 20'} + "@tailwindcss/oxide-darwin-arm64@4.3.0": + resolution: + { + integrity: sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==, + } + engines: { node: ">= 20" } + cpu: [arm64] + os: [darwin] - '@vercel/prepare-flags-definitions@0.2.1': - resolution: {integrity: sha512-ouXTsqn7I9xZ1KKezgvn/w3tZeQHL/tc52j9GHiOYi6kT8xgdbT8s2x8C9BQr44iceX0hfhtZwk9q7NuI2Tqbw==} + "@tailwindcss/oxide-darwin-x64@4.3.0": + resolution: + { + integrity: sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==, + } + engines: { node: ">= 20" } + cpu: [x64] + os: [darwin] - '@vercel/python-analysis@0.11.1': - resolution: {integrity: sha512-EPPLuXJQhIDUx08H9nG76AR2HSgBquwe3OAX5s2w20M923iaWeGGVkhX/4yZ89CJfXEZgE1Aj/mX7lVHOVIcYA==} + "@tailwindcss/oxide-freebsd-x64@4.3.0": + resolution: + { + integrity: sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==, + } + engines: { node: ">= 20" } + cpu: [x64] + os: [freebsd] - '@vercel/python@6.43.1': - resolution: {integrity: sha512-kAykqslePS5jRgBsIui8m4BK7/7+Iqztb7X88qeTDqg0eP/JRCxg0kxC7HkX9ZkW9lpQr6hn6CNzMAdKH8ihFg==} + "@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0": + resolution: + { + integrity: sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==, + } + engines: { node: ">= 20" } + cpu: [arm] + os: [linux] - '@vercel/queue@0.2.0': - resolution: {integrity: sha512-+iOwbz9wHWwcr8kLyB6m6seE/Kw2mn0Mxatj+6ko6HwBaCZGSYRNgII7JwrKMPSaxaqE1iZ3BZRbhLwYQATaew==} - engines: {node: '>=20.0.0'} + "@tailwindcss/oxide-linux-arm64-gnu@4.3.0": + resolution: + { + integrity: sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==, + } + engines: { node: ">= 20" } + cpu: [arm64] + os: [linux] + libc: [glibc] - '@vercel/redwood@2.4.13': - resolution: {integrity: sha512-pXWzVctZea/J7WMQstjsYUDiMc6oJF72p8J5YZnLSCJWg7m+/dLzYGfaUSEo6Q0JpiO/NOcDmG3WENpn7kHwzg==} + "@tailwindcss/oxide-linux-arm64-musl@4.3.0": + resolution: + { + integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==, + } + engines: { node: ">= 20" } + cpu: [arm64] + os: [linux] + libc: [musl] - '@vercel/remix-builder@5.8.2': - resolution: {integrity: sha512-iiL8ppHkt+tIyLUEKQQQQmqVsoyZSPGc0zqIQ9lRUQLSMzxsgh57LPBjDA8AJrdLHXyxQQwNdHEtuMFZaKOG2w==} + "@tailwindcss/oxide-linux-x64-gnu@4.3.0": + resolution: + { + integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==, + } + engines: { node: ">= 20" } + cpu: [x64] + os: [linux] + libc: [glibc] - '@vercel/ruby@2.3.2': - resolution: {integrity: sha512-okIgMmPEePyDR9TZYaKM4oftcxVHM5Dbdl7V/tIdh3lq8MGLi7HR5vvQglmZUwZOeovE6MVtezxl960EOzeIiQ==} + "@tailwindcss/oxide-linux-x64-musl@4.3.0": + resolution: + { + integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==, + } + engines: { node: ">= 20" } + cpu: [x64] + os: [linux] + libc: [musl] - '@vercel/rust@1.2.0': - resolution: {integrity: sha512-JryMtBa0sFuqxfHpjrNgMks06XDKa8DVhGljTsoo26dIKqsoqeYhJHuepEAEXT+b5N+tUmxIOUcRq5//ewvytQ==} + "@tailwindcss/oxide-wasm32-wasi@4.3.0": + resolution: + { + integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==, + } + engines: { node: ">=14.0.0" } + cpu: [wasm32] + bundledDependencies: + - "@napi-rs/wasm-runtime" + - "@emnapi/core" + - "@emnapi/runtime" + - "@tybys/wasm-util" + - "@emnapi/wasi-threads" + - tslib - '@vercel/sandbox@1.9.0': - resolution: {integrity: sha512-zgr1ad0tkT1xZn/8Vxo60wOUOLqMAVGo4WqJQ8/UDcUtWynNJsBjI2tiMdWZrAo9EKH1MIqEzJNkcclF0UT1EQ==} + "@tailwindcss/oxide-win32-arm64-msvc@4.3.0": + resolution: + { + integrity: sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==, + } + engines: { node: ">= 20" } + cpu: [arm64] + os: [win32] - '@vercel/sandbox@2.0.0': - resolution: {integrity: sha512-fmg6lNfDJdhQ43Njc0jUIXTQP2wKPY6tJszeVq5C25v1XsDK3wwnlFBQfSKzZfkMkh1N269pPgOopjTEqJJamA==} + "@tailwindcss/oxide-win32-x64-msvc@4.3.0": + resolution: + { + integrity: sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==, + } + engines: { node: ">= 20" } + cpu: [x64] + os: [win32] - '@vercel/static-build@2.9.30': - resolution: {integrity: sha512-0tJU+7cW4FEMMshmoU7bybfOHGIRe+EiQOYFVrG/lSiSeCr3laIUCYn/xa9vBCFOeHcw8o/PQtLSV9d46cz3Uw==} + "@tailwindcss/oxide@4.3.0": + resolution: + { + integrity: sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==, + } + engines: { node: ">= 20" } + + "@tanstack/query-core@5.100.14": + resolution: + { + integrity: sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==, + } + + "@tanstack/react-query@5.100.14": + resolution: + { + integrity: sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==, + } + peerDependencies: + react: ^18 || ^19 - '@vercel/static-config@3.3.0': - resolution: {integrity: sha512-GpS3tPwUeDJCkrKbMNtS2XLRFgfxTlN7YNUL+Bo23+fGolrDw6Oq79R3yvxTYgqRaJMGSEqC7iMw6mj6I5loxg==} + "@tokenizer/inflate@0.4.1": + resolution: + { + integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==, + } + engines: { node: ">=18" } + + "@tokenizer/token@0.3.0": + resolution: + { + integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==, + } + + "@tootallnate/once@2.0.0": + resolution: + { + integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==, + } + engines: { node: ">= 10" } + + "@tootallnate/quickjs-emscripten@0.23.0": + resolution: + { + integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==, + } + + "@ts-morph/common@0.11.1": + resolution: + { + integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==, + } + + "@tybys/wasm-util@0.10.2": + resolution: + { + integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==, + } + + "@types/chai@5.2.3": + resolution: + { + integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==, + } + + "@types/connect@3.4.38": + resolution: + { + integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, + } + + "@types/d3-array@3.2.2": + resolution: + { + integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==, + } + + "@types/d3-color@3.1.3": + resolution: + { + integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==, + } + + "@types/d3-ease@3.0.2": + resolution: + { + integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==, + } + + "@types/d3-interpolate@3.0.4": + resolution: + { + integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==, + } + + "@types/d3-path@3.1.1": + resolution: + { + integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==, + } + + "@types/d3-scale@4.0.9": + resolution: + { + integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==, + } + + "@types/d3-shape@3.1.8": + resolution: + { + integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==, + } + + "@types/d3-time@3.0.4": + resolution: + { + integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==, + } + + "@types/d3-timer@3.0.2": + resolution: + { + integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==, + } + + "@types/debug@4.1.13": + resolution: + { + integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==, + } + + "@types/deep-eql@4.0.2": + resolution: + { + integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==, + } + + "@types/estree-jsx@1.0.5": + resolution: + { + integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==, + } + + "@types/estree@1.0.8": + resolution: + { + integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, + } + + "@types/estree@1.0.9": + resolution: + { + integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==, + } + + "@types/hast@3.0.4": + resolution: + { + integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==, + } + + "@types/js-yaml@4.0.9": + resolution: + { + integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==, + } + + "@types/json-schema@7.0.15": + resolution: + { + integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, + } + + "@types/mdast@4.0.4": + resolution: + { + integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==, + } + + "@types/mdx@2.0.13": + resolution: + { + integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==, + } + + "@types/ms@2.1.0": + resolution: + { + integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==, + } + + "@types/mysql@2.15.27": + resolution: + { + integrity: sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==, + } + + "@types/nlcst@2.0.3": + resolution: + { + integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==, + } + + "@types/node@20.11.0": + resolution: + { + integrity: sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==, + } + + "@types/node@24.12.4": + resolution: + { + integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==, + } + + "@types/node@25.9.1": + resolution: + { + integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==, + } + + "@types/pg-pool@2.0.7": + resolution: + { + integrity: sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==, + } + + "@types/pg@8.15.6": + resolution: + { + integrity: sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==, + } + + "@types/react-dom@19.2.3": + resolution: + { + integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==, + } + peerDependencies: + "@types/react": ^19.2.0 + + "@types/react@19.2.15": + resolution: + { + integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==, + } + + "@types/retry@0.12.0": + resolution: + { + integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==, + } + + "@types/sax@1.2.7": + resolution: + { + integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==, + } + + "@types/set-cookie-parser@2.4.10": + resolution: + { + integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==, + } + + "@types/statuses@2.0.6": + resolution: + { + integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==, + } + + "@types/tedious@4.0.14": + resolution: + { + integrity: sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==, + } + + "@types/unist@2.0.11": + resolution: + { + integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==, + } + + "@types/unist@3.0.3": + resolution: + { + integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==, + } + + "@types/use-sync-external-store@0.0.6": + resolution: + { + integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==, + } + + "@types/ws@8.18.1": + resolution: + { + integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==, + } + + "@ungap/structured-clone@1.3.1": + resolution: + { + integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==, + } + + "@vercel/backends@0.7.2": + resolution: + { + integrity: sha512-+v0H6VA3j37aSzi7CfrbcV2Xw5ySCWDhp2Boeuwy1sx7oOEwKNIumQB3D3yueDYUwiSKqKYnPIJUBIcRWFW5vQ==, + } + + "@vercel/blob@2.4.0": + resolution: + { + integrity: sha512-ncQ8CRb6XoEAYJwjOTRGpACRT6h/AeY+/33gLyeVxG5BIes27OPm1jmqreF+JHjcTmGhClTP+kBpmyLfbV0xew==, + } + engines: { node: ">=20.0.0" } + + "@vercel/build-utils@13.26.1": + resolution: + { + integrity: sha512-vMdSJ0U2YVkBWfSEHEj9WOuI8g52ozlluAiZhAGh2osGNYrD+w7IsvhLWXseFsAEr7v2rNTkY9nbrfgYiHYA+Q==, + } + + "@vercel/cervel@0.1.7": + resolution: + { + integrity: sha512-YlVc328X027b7YHU8PrTIbWPizD5rYxZTcjmexTdwkJxCZu/wQfYtJ6CXa05QnjZUukoFRiaMe+tb9kCCRxfHA==, + } + hasBin: true - '@vitest-evals/core@0.13.1': - resolution: {integrity: sha512-YX5bRG+J0GCzwJiNoq7UHJVRrtqx07lF3cYUrHnvfRLrn/R5nfBkFkm9eluAYlMFbWehFw+fFIW7bPuyL+3pMg==} + "@vercel/cli-config@0.1.2": + resolution: + { + integrity: sha512-XQOcuCM+8tKjh3sfgGRKRuNh78u2D8uGpDJIFcCtFi2tUqbGvqmJo790XX7+Bwakk08y0FCrs2JlEjvvwRhpAg==, + } + + "@vercel/detect-agent@1.2.3": + resolution: + { + integrity: sha512-VYNCgUc0nOmC4WJmWw9GkrKdfr8Zl4/rxhC5SvgacBgxiW9W/9NRttUoHHXV8xdII3MaRgkZZVX8Ikzc/Jmjag==, + } + engines: { node: ">=14" } + + "@vercel/elysia@0.1.80": + resolution: + { + integrity: sha512-H2NBFYP1hAML/3TCz9r0hTyd1dRCxKzUl7k2ShziIh/tNx5qfcOPhc2sA8s/9W8O5Yg5rQb4lyLh8qxR+96grg==, + } + + "@vercel/error-utils@2.1.0": + resolution: + { + integrity: sha512-DiJcXBOB9N6QM4d7hYPM9Ck/AUjzBl58XNQPxS74o7CuvIanjzrGgygP/70VsyEASeIJMazk1LrhwcNTR/eZGQ==, + } + + "@vercel/express@0.1.90": + resolution: + { + integrity: sha512-7x7WwnZ2mai9LZBpxEIIlllX7En//jaktwkpOE8MmpBzfcGhU8YAvCykSq5fDIglSF+lMW2/NoDBZzUvVZd7pA==, + } + + "@vercel/fastify@0.1.83": + resolution: + { + integrity: sha512-abjYa0wTlz3KEFfXD6MpS0NLTIX0sB6Z1EdEALvtdOj2LesvvZE1RB9GT8ZCrGhbvSQXNwbojPxA09rOcMx74A==, + } + + "@vercel/fun@1.3.0": + resolution: + { + integrity: sha512-8erw9uPe0dFg45THkNxmjtvMX143SkZebmjgSVbcM3XCkXu3RIiBaJMcMNG8aaS+rnTuw8+d4De9HVT0M/r3wg==, + } + engines: { node: ">= 18" } + + "@vercel/functions@3.6.0": + resolution: + { + integrity: sha512-Xj68JYqqJwtqFWJN7EWmFN7MOiUjv5whjw48UEKqQbg8r7hRkhuJhncTU0ba3jJCh/wxEuLWckrtsKcrHQraxw==, + } + engines: { node: ">= 20" } + peerDependencies: + "@aws-sdk/credential-provider-web-identity": "*" + peerDependenciesMeta: + "@aws-sdk/credential-provider-web-identity": + optional: true - '@vitest-evals/report-ui@0.13.1': - resolution: {integrity: sha512-uA0OSe8UFhSP8i92hUNSFbdJ7Lwi0b06DVfvPb9lnEADgZrExv8IiHy9mkRuU+aMwo7zQI75ZZz1qx07XzPczA==} + "@vercel/gatsby-plugin-vercel-analytics@1.0.11": + resolution: + { + integrity: sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==, + } + + "@vercel/gatsby-plugin-vercel-builder@2.2.7": + resolution: + { + integrity: sha512-5W4hhjCQzvehUQZHbKmXqbI5Ojx7b2BNJwN9UOGmGckG/UUTMJjqnVh9+TLzqxkuCNfqrjPoeS/+0v/AkH3DCQ==, + } + + "@vercel/go@3.7.1": + resolution: + { + integrity: sha512-63dl9firXTcP283mPnxmAb0LyWV72hWR6r8AA5ycKAiwmrkmoOh96XKDE7arXiNQDTQK1YP0oBDD6CH7JM1I8w==, + } + + "@vercel/h3@0.1.89": + resolution: + { + integrity: sha512-OnCGGd5bOO9pNvVqgwFb7h8mDevetmUolmdOL1r6EittsY2FgDxs5MnfbA6jLlzzE0P+V1D6ZX2U3WSbX1zgaQ==, + } + + "@vercel/hono@0.2.83": + resolution: + { + integrity: sha512-5lASV9a0qref0teqvhPucr+5KTZGwnTzYzQpff8Grhr5likf47he2SH60dflyoeMTVWbIKTTuXgu5V6+nHqKvg==, + } + + "@vercel/hydrogen@1.3.7": + resolution: + { + integrity: sha512-nh8hZ76Ipf9FRmMmQGd4SjkE0zxdjt+TUpZcuCIUG7yaHEh9STQV655I8rxKCB3hEWaKB3HALGgxZ0htIjQtZQ==, + } + + "@vercel/koa@0.1.63": + resolution: + { + integrity: sha512-DL41OzNaYUZnuaUWSCKJIBiN5tvntBeN3UumE3b1I20qZDhPeTQXmSUMqJHue+UHcvdJWuIyP+7p0k9hTD3Jsw==, + } + + "@vercel/nestjs@0.2.84": + resolution: + { + integrity: sha512-l0WNAxFLbOo11E9gqOen8cl0AHN87PqIoY3eGG5z2aT/z4xw/LJ4zZPD8OKfcZXtGS+hxlMYuRz/vjfOYmpmtg==, + } + + "@vercel/next@4.17.3": + resolution: + { + integrity: sha512-RwyiyRLLbFe7FLYIFBiZQrQGbmNNiSBvagPn+uN2/JRgaJp659wU/z1O+1+i1ESzWhF1KYoiIcx04njt/XmbSQ==, + } + + "@vercel/nft@1.5.0": + resolution: + { + integrity: sha512-IWTDeIoWhQ7ZtRO/JRKH+jhmeQvZYhtGPmzw/QGDY+wDCQqfm25P9yIdoAFagu4fWsK4IwZXDFIjrmp5rRm/sA==, + } + engines: { node: ">=20" } + hasBin: true - '@vitest/coverage-v8@4.1.7': - resolution: {integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==} + "@vercel/node@5.8.4": + resolution: + { + integrity: sha512-YY1sr6Vd32PL11cwMhmt7qhcAmqxbITNNq9JPLFpI0xWlr7Aiu81fgyTCV32mJvPq//NTgMumVI1hQFnojtfNQ==, + } + + "@vercel/oidc@3.2.0": + resolution: + { + integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==, + } + engines: { node: ">= 20" } + + "@vercel/oidc@3.4.1": + resolution: + { + integrity: sha512-H6B+/ig/GoahccL3WZjiHayHw1H5KhvTJNceqYulwfK9kkz5iul2hTmYzcJ7tTCQzyd0dutuL9xYFZCyLUqsog==, + } + engines: { node: ">= 20" } + + "@vercel/prepare-flags-definitions@0.2.1": + resolution: + { + integrity: sha512-ouXTsqn7I9xZ1KKezgvn/w3tZeQHL/tc52j9GHiOYi6kT8xgdbT8s2x8C9BQr44iceX0hfhtZwk9q7NuI2Tqbw==, + } + + "@vercel/python-analysis@0.11.1": + resolution: + { + integrity: sha512-EPPLuXJQhIDUx08H9nG76AR2HSgBquwe3OAX5s2w20M923iaWeGGVkhX/4yZ89CJfXEZgE1Aj/mX7lVHOVIcYA==, + } + + "@vercel/python@6.43.1": + resolution: + { + integrity: sha512-kAykqslePS5jRgBsIui8m4BK7/7+Iqztb7X88qeTDqg0eP/JRCxg0kxC7HkX9ZkW9lpQr6hn6CNzMAdKH8ihFg==, + } + + "@vercel/queue@0.2.0": + resolution: + { + integrity: sha512-+iOwbz9wHWwcr8kLyB6m6seE/Kw2mn0Mxatj+6ko6HwBaCZGSYRNgII7JwrKMPSaxaqE1iZ3BZRbhLwYQATaew==, + } + engines: { node: ">=20.0.0" } + + "@vercel/redwood@2.4.13": + resolution: + { + integrity: sha512-pXWzVctZea/J7WMQstjsYUDiMc6oJF72p8J5YZnLSCJWg7m+/dLzYGfaUSEo6Q0JpiO/NOcDmG3WENpn7kHwzg==, + } + + "@vercel/remix-builder@5.8.2": + resolution: + { + integrity: sha512-iiL8ppHkt+tIyLUEKQQQQmqVsoyZSPGc0zqIQ9lRUQLSMzxsgh57LPBjDA8AJrdLHXyxQQwNdHEtuMFZaKOG2w==, + } + + "@vercel/ruby@2.3.2": + resolution: + { + integrity: sha512-okIgMmPEePyDR9TZYaKM4oftcxVHM5Dbdl7V/tIdh3lq8MGLi7HR5vvQglmZUwZOeovE6MVtezxl960EOzeIiQ==, + } + + "@vercel/rust@1.2.0": + resolution: + { + integrity: sha512-JryMtBa0sFuqxfHpjrNgMks06XDKa8DVhGljTsoo26dIKqsoqeYhJHuepEAEXT+b5N+tUmxIOUcRq5//ewvytQ==, + } + + "@vercel/sandbox@1.9.0": + resolution: + { + integrity: sha512-zgr1ad0tkT1xZn/8Vxo60wOUOLqMAVGo4WqJQ8/UDcUtWynNJsBjI2tiMdWZrAo9EKH1MIqEzJNkcclF0UT1EQ==, + } + + "@vercel/sandbox@2.0.0": + resolution: + { + integrity: sha512-fmg6lNfDJdhQ43Njc0jUIXTQP2wKPY6tJszeVq5C25v1XsDK3wwnlFBQfSKzZfkMkh1N269pPgOopjTEqJJamA==, + } + + "@vercel/static-build@2.9.30": + resolution: + { + integrity: sha512-0tJU+7cW4FEMMshmoU7bybfOHGIRe+EiQOYFVrG/lSiSeCr3laIUCYn/xa9vBCFOeHcw8o/PQtLSV9d46cz3Uw==, + } + + "@vercel/static-config@3.3.0": + resolution: + { + integrity: sha512-GpS3tPwUeDJCkrKbMNtS2XLRFgfxTlN7YNUL+Bo23+fGolrDw6Oq79R3yvxTYgqRaJMGSEqC7iMw6mj6I5loxg==, + } + + "@vitest-evals/core@0.13.1": + resolution: + { + integrity: sha512-YX5bRG+J0GCzwJiNoq7UHJVRrtqx07lF3cYUrHnvfRLrn/R5nfBkFkm9eluAYlMFbWehFw+fFIW7bPuyL+3pMg==, + } + + "@vitest-evals/report-ui@0.13.1": + resolution: + { + integrity: sha512-uA0OSe8UFhSP8i92hUNSFbdJ7Lwi0b06DVfvPb9lnEADgZrExv8IiHy9mkRuU+aMwo7zQI75ZZz1qx07XzPczA==, + } + + "@vitest/coverage-v8@4.1.7": + resolution: + { + integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==, + } peerDependencies: - '@vitest/browser': 4.1.7 + "@vitest/browser": 4.1.7 vitest: 4.1.7 peerDependenciesMeta: - '@vitest/browser': + "@vitest/browser": optional: true - '@vitest/expect@4.1.7': - resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} - - '@vitest/mocker@4.1.7': - resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} + "@vitest/expect@4.1.7": + resolution: + { + integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==, + } + + "@vitest/mocker@4.1.7": + resolution: + { + integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==, + } peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3546,104 +5558,185 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.7': - resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} - - '@vitest/runner@4.1.7': - resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} - - '@vitest/snapshot@4.1.7': - resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} - - '@vitest/spy@4.1.7': - resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} - - '@vitest/utils@4.1.7': - resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} - - '@volar/kit@2.4.28': - resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==} + "@vitest/pretty-format@4.1.7": + resolution: + { + integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==, + } + + "@vitest/runner@4.1.7": + resolution: + { + integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==, + } + + "@vitest/snapshot@4.1.7": + resolution: + { + integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==, + } + + "@vitest/spy@4.1.7": + resolution: + { + integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==, + } + + "@vitest/utils@4.1.7": + resolution: + { + integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==, + } + + "@volar/kit@2.4.28": + resolution: + { + integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==, + } peerDependencies: - typescript: '*' - - '@volar/language-core@2.4.28': - resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} - - '@volar/language-server@2.4.28': - resolution: {integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==} - - '@volar/language-service@2.4.28': - resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==} - - '@volar/source-map@2.4.28': - resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} - - '@volar/typescript@2.4.28': - resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - - '@vscode/emmet-helper@2.11.0': - resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==} - - '@vscode/l10n@0.0.18': - resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} - - '@workflow/serde@4.1.0-beta.2': - resolution: {integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==} + typescript: "*" + + "@volar/language-core@2.4.28": + resolution: + { + integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==, + } + + "@volar/language-server@2.4.28": + resolution: + { + integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==, + } + + "@volar/language-service@2.4.28": + resolution: + { + integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==, + } + + "@volar/source-map@2.4.28": + resolution: + { + integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==, + } + + "@volar/typescript@2.4.28": + resolution: + { + integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==, + } + + "@vscode/emmet-helper@2.11.0": + resolution: + { + integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==, + } + + "@vscode/l10n@0.0.18": + resolution: + { + integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==, + } + + "@workflow/serde@4.1.0-beta.2": + resolution: + { + integrity: sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww==, + } abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} + resolution: + { + integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==, + } + engines: { node: ^18.17.0 || >=20.5.0 } accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==, + } + engines: { node: ">= 0.6" } acorn-import-attributes@1.9.5: - resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + resolution: + { + integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==, + } peerDependencies: acorn: ^8 acorn-jsx-walk@2.0.0: - resolution: {integrity: sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==} + resolution: + { + integrity: sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==, + } acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + resolution: + { + integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, + } peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn-loose@8.5.2: - resolution: {integrity: sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==, + } + engines: { node: ">=0.4.0" } acorn-walk@8.3.5: - resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==, + } + engines: { node: ">=0.4.0" } acorn@8.16.0: - resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==, + } + engines: { node: ">=0.4.0" } hasBin: true agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + resolution: + { + integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, + } + engines: { node: ">= 6.0.0" } agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==, + } + engines: { node: ">= 14" } agent-browser@0.27.0: - resolution: {integrity: sha512-mmHzVsYFVA6nshNNGJzg83aVMgKpf4h98ytY3pvtJB1Cot0ZyA2bfnkbSngGD56Azkj+GlhVH6qx9DfKOVE0yg==} + resolution: + { + integrity: sha512-mmHzVsYFVA6nshNNGJzg83aVMgKpf4h98ytY3pvtJB1Cot0ZyA2bfnkbSngGD56Azkj+GlhVH6qx9DfKOVE0yg==, + } hasBin: true ai@6.0.190: - resolution: {integrity: sha512-T+ixHbWZ6jmHRREpVVJTkFyWJeCekCdzLPan7lp1F32jG5OUw4+odlVYjtMRXVzogU+pWzpMmXdRiHUmdL/q0w==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-T+ixHbWZ6jmHRREpVVJTkFyWJeCekCdzLPan7lp1F32jG5OUw4+odlVYjtMRXVzogU+pWzpMmXdRiHUmdL/q0w==, + } + engines: { node: ">=18" } peerDependencies: zod: ^3.25.76 || ^4.1.8 ajv-draft-04@1.0.0: - resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + resolution: + { + integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==, + } peerDependencies: ajv: ^8.5.0 peerDependenciesMeta: @@ -3651,159 +5744,291 @@ packages: optional: true ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + resolution: + { + integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==, + } ajv@8.20.0: - resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + resolution: + { + integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==, + } ajv@8.6.3: - resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} + resolution: + { + integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==, + } + + ansi-escapes@7.3.0: + resolution: + { + integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==, + } + engines: { node: ">=18" } ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, + } + engines: { node: ">=8" } + + ansi-regex@6.2.2: + resolution: + { + integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==, + } + engines: { node: ">=12" } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, + } + engines: { node: ">=8" } + + ansi-styles@6.2.3: + resolution: + { + integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==, + } + engines: { node: ">=12" } any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + resolution: + { + integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==, + } anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, + } + engines: { node: ">= 8" } arg@4.1.0: - resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} + resolution: + { + integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==, + } arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + resolution: + { + integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==, + } argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, + } aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==, + } + engines: { node: ">= 0.4" } array-iterate@2.0.1: - resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + resolution: + { + integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==, + } assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==, + } + engines: { node: ">=12" } ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==, + } + engines: { node: ">=4" } ast-v8-to-istanbul@1.0.3: - resolution: {integrity: sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==} + resolution: + { + integrity: sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==, + } astring@1.9.0: - resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + resolution: + { + integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==, + } hasBin: true astro-expressive-code@0.42.0: - resolution: {integrity: sha512-aiTePi2Cn0mJPYWZSzP1GcxCinX9mNtJyCCshVVPSg1yRwM7ADvFJOx0FnS440M9t65hp8JH//dc2qr22Bm4ag==} + resolution: + { + integrity: sha512-aiTePi2Cn0mJPYWZSzP1GcxCinX9mNtJyCCshVVPSg1yRwM7ADvFJOx0FnS440M9t65hp8JH//dc2qr22Bm4ag==, + } peerDependencies: astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta astro@6.3.7: - resolution: {integrity: sha512-zIeDRrI0qNgN1lcCjNqt6/IVCVej7VwSa326cO8uP9BOk1cg4QuffhLnOn2gCgWQr32/wxpSRFfXiLKHglu1Tw==} - engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'} + resolution: + { + integrity: sha512-zIeDRrI0qNgN1lcCjNqt6/IVCVej7VwSa326cO8uP9BOk1cg4QuffhLnOn2gCgWQr32/wxpSRFfXiLKHglu1Tw==, + } + engines: { node: ">=22.12.0", npm: ">=9.6.5", pnpm: ">=7.1.0" } hasBin: true async-listen@1.2.0: - resolution: {integrity: sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==} + resolution: + { + integrity: sha512-CcEtRh/oc9Jc4uWeUwdpG/+Mb2YUHKmdaTf0gUr7Wa+bfp4xx70HOb3RuSTJMvqKNB1TkdTfjLdrcz2X4rkkZA==, + } async-listen@3.0.0: - resolution: {integrity: sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==, + } + engines: { node: ">= 14" } async-listen@3.0.1: - resolution: {integrity: sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-cWMaNwUJnf37C/S5TfCkk/15MwbPRwVYALA2jtjkbHjCmAPiDXyNJy2q3p1KAZzDLHAWyarUWSujUoHR4pEgrA==, + } + engines: { node: ">= 14" } async-retry@1.3.3: - resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + resolution: + { + integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==, + } async-sema@3.1.1: - resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + resolution: + { + integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==, + } asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { + integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, + } axios@1.16.1: - resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} + resolution: + { + integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==, + } axobject-query@4.1.0: - resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==, + } + engines: { node: ">= 0.4" } b4a@1.8.1: - resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} + resolution: + { + integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==, + } peerDependencies: - react-native-b4a: '*' + react-native-b4a: "*" peerDependenciesMeta: react-native-b4a: optional: true bail@2.0.2: - resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + resolution: + { + integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==, + } balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { + integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, + } balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==, + } + engines: { node: 18 || 20 || >=22 } bare-events@2.8.3: - resolution: {integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==} + resolution: + { + integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==, + } peerDependencies: - bare-abort-controller: '*' + bare-abort-controller: "*" peerDependenciesMeta: bare-abort-controller: optional: true base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + resolution: + { + integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, + } bash-tool@1.3.16: - resolution: {integrity: sha512-2xuprVBzUOYw4+QCpeSwvkuXuHkjKRtMzh+nTpEidROsNnglr5xRs3mdeOmwFVkjB4JhE/uZqIXE+tabbJI7QQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-2xuprVBzUOYw4+QCpeSwvkuXuHkjKRtMzh+nTpEidROsNnglr5xRs3mdeOmwFVkjB4JhE/uZqIXE+tabbJI7QQ==, + } + engines: { node: ">=18" } peerDependencies: - '@vercel/sandbox': '*' + "@vercel/sandbox": "*" ai: 6.0.190 just-bash: ^2.9.3 peerDependenciesMeta: - '@vercel/sandbox': + "@vercel/sandbox": optional: true just-bash: optional: true basic-ftp@5.3.1: - resolution: {integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==, + } + engines: { node: ">=10.0.0" } bcp-47-match@2.0.3: - resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + resolution: + { + integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==, + } bcp-47@2.1.0: - resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + resolution: + { + integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==, + } better-auth@1.6.11: - resolution: {integrity: sha512-Wwt6+q07dwIhsp6XiM7L1qSXVUWBEtNl+eZvwM778CguFqDZFBN9Pt6LtFaHl55t8Z+Zc//5kxcbgDY8/79vFQ==} + resolution: + { + integrity: sha512-Wwt6+q07dwIhsp6XiM7L1qSXVUWBEtNl+eZvwM778CguFqDZFBN9Pt6LtFaHl55t8Z+Zc//5kxcbgDY8/79vFQ==, + } peerDependencies: - '@lynx-js/react': '*' - '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 - '@sveltejs/kit': ^2.0.0 - '@tanstack/react-start': ^1.0.0 - '@tanstack/solid-start': ^1.0.0 + "@lynx-js/react": "*" + "@prisma/client": ^5.0.0 || ^6.0.0 || ^7.0.0 + "@sveltejs/kit": ^2.0.0 + "@tanstack/react-start": ^1.0.0 + "@tanstack/solid-start": ^1.0.0 better-sqlite3: ^12.0.0 - drizzle-kit: '>=0.31.4' + drizzle-kit: ">=0.31.4" drizzle-orm: ^0.45.2 mongodb: ^6.0.0 || ^7.0.0 mysql2: ^3.0.0 @@ -3817,15 +6042,15 @@ packages: vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 vue: ^3.0.0 peerDependenciesMeta: - '@lynx-js/react': + "@lynx-js/react": optional: true - '@prisma/client': + "@prisma/client": optional: true - '@sveltejs/kit': + "@sveltejs/kit": optional: true - '@tanstack/react-start': + "@tanstack/react-start": optional: true - '@tanstack/solid-start': + "@tanstack/solid-start": optional: true better-sqlite3: optional: true @@ -3857,7 +6082,10 @@ packages: optional: true better-call@1.3.5: - resolution: {integrity: sha512-kOFJkBP7utAQLEYrobZm3vkTH8mXq5GNgvjc5/XEST1ilVHaxXUXfeDeFlqoETMtyqS4+3/h4ONX2i++ebZrvA==} + resolution: + { + integrity: sha512-kOFJkBP7utAQLEYrobZm3vkTH8mXq5GNgvjc5/XEST1ilVHaxXUXfeDeFlqoETMtyqS4+3/h4ONX2i++ebZrvA==, + } peerDependencies: zod: ^4.0.0 peerDependenciesMeta: @@ -3865,99 +6093,180 @@ packages: optional: true bignumber.js@9.3.1: - resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + resolution: + { + integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==, + } bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + resolution: + { + integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==, + } bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + resolution: + { + integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, + } body-parser@2.2.2: - resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==, + } + engines: { node: ">=18" } boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + resolution: + { + integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, + } bowser@2.14.1: - resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + resolution: + { + integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==, + } brace-expansion@1.1.14: - resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + resolution: + { + integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==, + } brace-expansion@5.0.6: - resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==, + } + engines: { node: 18 || 20 || >=22 } braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, + } + engines: { node: ">=8" } buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + resolution: + { + integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==, + } buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + resolution: + { + integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==, + } buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + resolution: + { + integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, + } buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + resolution: + { + integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, + } bundle-require@5.1.0: - resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } peerDependencies: - esbuild: '>=0.18' + esbuild: ">=0.18" bytes@3.1.0: - resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==, + } + engines: { node: ">= 0.8" } bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, + } + engines: { node: ">= 0.8" } cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, + } + engines: { node: ">=8" } call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, + } + engines: { node: ">= 0.4" } call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==, + } + engines: { node: ">= 0.4" } ccount@2.0.1: - resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + resolution: + { + integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==, + } chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==, + } + engines: { node: ">=18" } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, + } + engines: { node: ">=10" } character-entities-html4@2.1.0: - resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + resolution: + { + integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==, + } character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + resolution: + { + integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==, + } character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + resolution: + { + integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==, + } character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + resolution: + { + integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==, + } chat@4.29.0: - resolution: {integrity: sha512-KdPfzaie5ivYytyRICTERg5xT+LeCbYefokvNAqTHe92eqkFaoTMXXkSitikxJVWhZIb2YoXF1b9UZHyzSzKzw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-KdPfzaie5ivYytyRICTERg5xT+LeCbYefokvNAqTHe92eqkFaoTMXXkSitikxJVWhZIb2YoXF1b9UZHyzSzKzw==, + } + engines: { node: ">=20" } peerDependencies: ai: 6.0.190 zod: ^3.0.0 || ^4.0.0 @@ -3968,255 +6277,458 @@ packages: optional: true chokidar@4.0.0: - resolution: {integrity: sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==} - engines: {node: '>= 14.16.0'} + resolution: + { + integrity: sha512-mxIojEAQcuEvT/lyXq+jf/3cO/KoA6z4CeNDGGevTybECPOMFCnQy3OPahluUkbqgPNGw5Bi78UC7Po6Lhy+NA==, + } + engines: { node: ">= 14.16.0" } chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} + resolution: + { + integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==, + } + engines: { node: ">= 14.16.0" } chokidar@5.0.0: - resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} - engines: {node: '>= 20.19.0'} + resolution: + { + integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==, + } + engines: { node: ">= 20.19.0" } chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + resolution: + { + integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==, + } chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==, + } + engines: { node: ">=18" } ci-info@4.4.0: - resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==, + } + engines: { node: ">=8" } cjs-module-lexer@1.2.3: - resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + resolution: + { + integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==, + } cjs-module-lexer@2.2.0: - resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} + resolution: + { + integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==, + } + + cli-cursor@5.0.0: + resolution: + { + integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==, + } + engines: { node: ">=18" } + + cli-truncate@5.2.0: + resolution: + { + integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==, + } + engines: { node: ">=20" } cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} + resolution: + { + integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==, + } + engines: { node: ">= 12" } cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, + } + engines: { node: ">=12" } clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==, + } + engines: { node: ">=6" } cluster-key-slot@1.1.2: - resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==, + } + engines: { node: ">=0.10.0" } code-block-writer@10.1.1: - resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} + resolution: + { + integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==, + } collapse-white-space@2.1.0: - resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + resolution: + { + integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==, + } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { + integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, + } + engines: { node: ">=7.0.0" } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { + integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, + } combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, + } + engines: { node: ">= 0.8" } comma-separated-tokens@2.0.3: - resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + resolution: + { + integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==, + } commander@11.1.0: - resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==, + } + engines: { node: ">=16" } commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==, + } + engines: { node: ">=20" } commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==, + } + engines: { node: ">= 6" } commander@6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==, + } + engines: { node: ">= 6" } common-ancestor-path@2.0.0: - resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==, + } + engines: { node: ">= 18" } concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { + integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, + } confbox@0.1.8: - resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + resolution: + { + integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==, + } consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} + resolution: + { + integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==, + } + engines: { node: ^14.18.0 || >=16.10.0 } content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==, + } + engines: { node: ">=18" } content-type@1.0.4: - resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==, + } + engines: { node: ">= 0.6" } content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, + } + engines: { node: ">= 0.6" } content-type@2.0.0: - resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==, + } + engines: { node: ">=18" } convert-hrtime@3.0.0: - resolution: {integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==, + } + engines: { node: ">=8" } convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + resolution: + { + integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, + } cookie-es@1.2.3: - resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + resolution: + { + integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==, + } cookie-es@2.0.1: - resolution: {integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==} + resolution: + { + integrity: sha512-aVf4A4hI2w70LnF7GG+7xDQUkliwiXWXFvTjkip4+b64ygDQ2sJPRSKFDHbxn8o0xu9QzPkMuuiWIXyFSE2slA==, + } cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} + resolution: + { + integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==, + } + engines: { node: ">=6.6.0" } cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==, + } + engines: { node: ">= 0.6" } cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==, + } + engines: { node: ">=18" } cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==, + } + engines: { node: ">= 0.10" } cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, + } + engines: { node: ">= 8" } crossws@0.3.5: - resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + resolution: + { + integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==, + } crossws@0.4.5: - resolution: {integrity: sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==} + resolution: + { + integrity: sha512-wUR89x/Rw7/8t+vn0CmGDYM9TD6VtARGb0LD5jq2wjtMy1vCP4M+sm6N6TigWeTYvnA8MoW29NqqXD0ep0rfBA==, + } peerDependencies: - srvx: '>=0.11.5' + srvx: ">=0.11.5" peerDependenciesMeta: srvx: optional: true css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + resolution: + { + integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==, + } css-selector-parser@3.3.0: - resolution: {integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==} + resolution: + { + integrity: sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==, + } css-tree@2.2.1: - resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + resolution: + { + integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: ">=7.0.0" } css-tree@3.2.1: - resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + resolution: + { + integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0 } css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==, + } + engines: { node: ">= 6" } cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==, + } + engines: { node: ">=4" } hasBin: true csso@5.0.5: - resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} - engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + resolution: + { + integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==, + } + engines: { node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: ">=7.0.0" } csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + resolution: + { + integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==, + } d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==, + } + engines: { node: ">=12" } d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==, + } + engines: { node: ">=12" } d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==, + } + engines: { node: ">=12" } d3-format@3.1.2: - resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==, + } + engines: { node: ">=12" } d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==, + } + engines: { node: ">=12" } d3-path@3.1.0: - resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==, + } + engines: { node: ">=12" } d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==, + } + engines: { node: ">=12" } d3-shape@3.2.0: - resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==, + } + engines: { node: ">=12" } d3-time-format@4.1.0: - resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==, + } + engines: { node: ">=12" } d3-time@3.1.0: - resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==, + } + engines: { node: ">=12" } d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==, + } + engines: { node: ">=12" } data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} + resolution: + { + integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==, + } + engines: { node: ">= 12" } data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==, + } + engines: { node: ">= 14" } db0@0.3.4: - resolution: {integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==} - peerDependencies: - '@electric-sql/pglite': '*' - '@libsql/client': '*' - better-sqlite3: '*' - drizzle-orm: '*' - mysql2: '*' - sqlite3: '*' + resolution: + { + integrity: sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==, + } + peerDependencies: + "@electric-sql/pglite": "*" + "@libsql/client": "*" + better-sqlite3: "*" + drizzle-orm: "*" + mysql2: "*" + sqlite3: "*" peerDependenciesMeta: - '@electric-sql/pglite': + "@electric-sql/pglite": optional: true - '@libsql/client': + "@libsql/client": optional: true better-sqlite3: optional: true @@ -4228,169 +6740,244 @@ packages: optional: true debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, + } + engines: { node: ">=6.0" } peerDependencies: - supports-color: '*' + supports-color: "*" peerDependenciesMeta: supports-color: optional: true debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==, + } + engines: { node: ">=6.0" } peerDependencies: - supports-color: '*' + supports-color: "*" peerDependenciesMeta: supports-color: optional: true decimal.js-light@2.5.1: - resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + resolution: + { + integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==, + } decode-named-character-reference@1.3.0: - resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + resolution: + { + integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==, + } decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==, + } + engines: { node: ">=10" } deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} + resolution: + { + integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==, + } + engines: { node: ">=4.0.0" } defu@6.1.7: - resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + resolution: + { + integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==, + } degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==, + } + engines: { node: ">= 14" } delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { + integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, + } + engines: { node: ">=0.4.0" } depd@1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==, + } + engines: { node: ">= 0.6" } depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, + } + engines: { node: ">= 0.8" } dependency-cruiser@17.4.0: - resolution: {integrity: sha512-+WdFoOb+fT1XNC0iPqOyLpfhLd8xVh7eLXJxPAtiXCS+YmXzGrjqVTte7+L8SZIsnJj0aFhb8LxECIBJY5TTIA==} - engines: {node: ^20.12||^22||>=24} + resolution: + { + integrity: sha512-+WdFoOb+fT1XNC0iPqOyLpfhLd8xVh7eLXJxPAtiXCS+YmXzGrjqVTte7+L8SZIsnJj0aFhb8LxECIBJY5TTIA==, + } + engines: { node: ^20.12||^22||>=24 } hasBin: true dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==, + } + engines: { node: ">=6" } destr@2.0.5: - resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + resolution: + { + integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==, + } detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==, + } + engines: { node: ">=8" } devalue@5.8.1: - resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} + resolution: + { + integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==, + } devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + resolution: + { + integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==, + } diff@8.0.4: - resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} - engines: {node: '>=0.3.1'} + resolution: + { + integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==, + } + engines: { node: ">=0.3.1" } direction@2.0.1: - resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} + resolution: + { + integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==, + } hasBin: true dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + resolution: + { + integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==, + } domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + resolution: + { + integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==, + } domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==, + } + engines: { node: ">= 4" } domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + resolution: + { + integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==, + } drizzle-kit@0.31.10: - resolution: {integrity: sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==} + resolution: + { + integrity: sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==, + } hasBin: true drizzle-orm@0.45.2: - resolution: {integrity: sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=4' - '@electric-sql/pglite': '>=0.2.0' - '@libsql/client': '>=0.10.0' - '@libsql/client-wasm': '>=0.10.0' - '@neondatabase/serverless': '>=0.10.0' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1.13' - '@prisma/client': '*' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/sql.js': '*' - '@upstash/redis': '>=1.34.7' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=14.0.0' - gel: '>=2' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - prisma: '*' - sql.js: '>=1' - sqlite3: '>=5' + resolution: + { + integrity: sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==, + } + peerDependencies: + "@aws-sdk/client-rds-data": ">=3" + "@cloudflare/workers-types": ">=4" + "@electric-sql/pglite": ">=0.2.0" + "@libsql/client": ">=0.10.0" + "@libsql/client-wasm": ">=0.10.0" + "@neondatabase/serverless": ">=0.10.0" + "@op-engineering/op-sqlite": ">=2" + "@opentelemetry/api": ^1.4.1 + "@planetscale/database": ">=1.13" + "@prisma/client": "*" + "@tidbcloud/serverless": "*" + "@types/better-sqlite3": "*" + "@types/pg": "*" + "@types/sql.js": "*" + "@upstash/redis": ">=1.34.7" + "@vercel/postgres": ">=0.8.0" + "@xata.io/client": "*" + better-sqlite3: ">=7" + bun-types: "*" + expo-sqlite: ">=14.0.0" + gel: ">=2" + knex: "*" + kysely: "*" + mysql2: ">=2" + pg: ">=8" + postgres: ">=3" + prisma: "*" + sql.js: ">=1" + sqlite3: ">=5" peerDependenciesMeta: - '@aws-sdk/client-rds-data': + "@aws-sdk/client-rds-data": optional: true - '@cloudflare/workers-types': + "@cloudflare/workers-types": optional: true - '@electric-sql/pglite': + "@electric-sql/pglite": optional: true - '@libsql/client': + "@libsql/client": optional: true - '@libsql/client-wasm': + "@libsql/client-wasm": optional: true - '@neondatabase/serverless': + "@neondatabase/serverless": optional: true - '@op-engineering/op-sqlite': + "@op-engineering/op-sqlite": optional: true - '@opentelemetry/api': + "@opentelemetry/api": optional: true - '@planetscale/database': + "@planetscale/database": optional: true - '@prisma/client': + "@prisma/client": optional: true - '@tidbcloud/serverless': + "@tidbcloud/serverless": optional: true - '@types/better-sqlite3': + "@types/better-sqlite3": optional: true - '@types/pg': + "@types/pg": optional: true - '@types/sql.js': + "@types/sql.js": optional: true - '@upstash/redis': + "@upstash/redis": optional: true - '@vercel/postgres': + "@vercel/postgres": optional: true - '@xata.io/client': + "@xata.io/client": optional: true better-sqlite3: optional: true @@ -4418,279 +7005,519 @@ packages: optional: true dset@3.1.4: - resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==, + } + engines: { node: ">=4" } dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, + } + engines: { node: ">= 0.4" } ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + resolution: + { + integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==, + } edge-runtime@2.5.9: - resolution: {integrity: sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-pk+k0oK0PVXdlT4oRp4lwh+unuKB7Ng4iZ2HB+EZ7QCEQizX360Rp/F4aRpgpRgdP2ufB35N+1KppHmYjqIGSg==, + } + engines: { node: ">=16" } hasBin: true ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + resolution: + { + integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, + } emmet@2.4.11: - resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} + resolution: + { + integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==, + } + + emoji-regex@10.6.0: + resolution: + { + integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==, + } emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + resolution: + { + integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, + } encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==, + } + engines: { node: ">= 0.8" } end-of-stream@1.1.0: - resolution: {integrity: sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==} + resolution: + { + integrity: sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==, + } end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + resolution: + { + integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==, + } enhanced-resolve@5.21.0: - resolution: {integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA==, + } + engines: { node: ">=10.13.0" } entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} + resolution: + { + integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==, + } + engines: { node: ">=0.12" } entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} + resolution: + { + integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==, + } + engines: { node: ">=0.12" } env-runner@0.1.9: - resolution: {integrity: sha512-W9AiZlPx0uXtghAJiTBkeZOgyQdecVvoln3cHoOEZswPq0cVMi+WBhUQjdUn+JcZFAFgOt+i5fcO7C2zniZoCg==} + resolution: + { + integrity: sha512-W9AiZlPx0uXtghAJiTBkeZOgyQdecVvoln3cHoOEZswPq0cVMi+WBhUQjdUn+JcZFAFgOt+i5fcO7C2zniZoCg==, + } hasBin: true peerDependencies: - '@netlify/runtime': ^4.1.23 - '@vercel/queue': ^0.2.0 + "@netlify/runtime": ^4.1.23 + "@vercel/queue": ^0.2.0 miniflare: ^4.20260515.0 peerDependenciesMeta: - '@netlify/runtime': + "@netlify/runtime": optional: true - '@vercel/queue': + "@vercel/queue": optional: true miniflare: optional: true + environment@1.1.0: + resolution: + { + integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==, + } + engines: { node: ">=18" } + es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, + } + engines: { node: ">= 0.4" } es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, + } + engines: { node: ">= 0.4" } es-module-lexer@1.4.1: - resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + resolution: + { + integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==, + } es-module-lexer@1.5.0: - resolution: {integrity: sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==} + resolution: + { + integrity: sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw==, + } es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + resolution: + { + integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==, + } es-object-atoms@1.1.2: - resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==, + } + engines: { node: ">= 0.4" } es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, + } + engines: { node: ">= 0.4" } es-toolkit@1.47.0: - resolution: {integrity: sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==} + resolution: + { + integrity: sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw==, + } esast-util-from-estree@2.0.0: - resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + resolution: + { + integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==, + } esast-util-from-js@2.0.1: - resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + resolution: + { + integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==, + } esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==, + } + engines: { node: ">=12" } hasBin: true esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==, + } + engines: { node: ">=18" } hasBin: true esbuild@0.27.0: - resolution: {integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==, + } + engines: { node: ">=18" } hasBin: true esbuild@0.27.7: - resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==, + } + engines: { node: ">=18" } + hasBin: true + + esbuild@0.28.1: + resolution: + { + integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==, + } + engines: { node: ">=18" } hasBin: true escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, + } + engines: { node: ">=6" } escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + resolution: + { + integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, + } escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==, + } + engines: { node: ">=12" } escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} + resolution: + { + integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==, + } + engines: { node: ">=6.0" } hasBin: true esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, + } + engines: { node: ">=4" } hasBin: true esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} + resolution: + { + integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==, + } + engines: { node: ">=0.10" } estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, + } + engines: { node: ">=4.0" } estree-util-attach-comments@3.0.0: - resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + resolution: + { + integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==, + } estree-util-build-jsx@3.0.1: - resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + resolution: + { + integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==, + } estree-util-is-identifier-name@3.0.0: - resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + resolution: + { + integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==, + } estree-util-scope@1.0.0: - resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + resolution: + { + integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==, + } estree-util-to-js@2.0.0: - resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + resolution: + { + integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==, + } estree-util-visit@2.0.0: - resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + resolution: + { + integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==, + } estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + resolution: + { + integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, + } estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + resolution: + { + integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==, + } esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, + } + engines: { node: ">=0.10.0" } etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, + } + engines: { node: ">= 0.6" } eventemitter3@4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + resolution: + { + integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, + } eventemitter3@5.0.4: - resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + resolution: + { + integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==, + } events-intercept@2.0.0: - resolution: {integrity: sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==} + resolution: + { + integrity: sha512-blk1va0zol9QOrdZt0rFXo5KMkNPVSp92Eju/Qz8THwKWKRKeE0T8Br/1aW6+Edkyq9xHYgYxn2QtOnUKPUp+Q==, + } events-universal@1.0.1: - resolution: {integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==} + resolution: + { + integrity: sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==, + } eventsource-parser@3.0.8: - resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==, + } + engines: { node: ">=18.0.0" } eventsource@3.0.7: - resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==, + } + engines: { node: ">=18.0.0" } execa@3.2.0: - resolution: {integrity: sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==} - engines: {node: ^8.12.0 || >=9.7.0} + resolution: + { + integrity: sha512-kJJfVbI/lZE1PZYDI5VPxp8zXPO9rtxOkhpZ0jMKha56AI9y2gGVC6bkukStQf0ka5Rh15BA5m7cCCH4jmHqkw==, + } + engines: { node: ^8.12.0 || >=9.7.0 } execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, + } + engines: { node: ">=10" } expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==, + } + engines: { node: ">=6" } expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==, + } + engines: { node: ">=12.0.0" } express-rate-limit@8.5.2: - resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} - engines: {node: '>= 16'} + resolution: + { + integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==, + } + engines: { node: ">= 16" } peerDependencies: - express: '>= 4.11' + express: ">= 4.11" express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==, + } + engines: { node: ">= 18" } expressive-code@0.42.0: - resolution: {integrity: sha512-V5DtJLEKuj4wf9O6IRtPtRObkMVy2ggR+S0MdjrTw6m58krZnDioyhW1si3Y04c5YPeooP4nd85Yq9NwEVHS4g==} + resolution: + { + integrity: sha512-V5DtJLEKuj4wf9O6IRtPtRObkMVy2ggR+S0MdjrTw6m58krZnDioyhW1si3Y04c5YPeooP4nd85Yq9NwEVHS4g==, + } exsolve@1.0.8: - resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + resolution: + { + integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==, + } extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + resolution: + { + integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==, + } fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + resolution: + { + integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, + } fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + resolution: + { + integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==, + } fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + resolution: + { + integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, + } + engines: { node: ">=8.6.0" } fast-string-truncated-width@3.0.3: - resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + resolution: + { + integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==, + } fast-string-width@3.0.2: - resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + resolution: + { + integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==, + } fast-uri@3.1.2: - resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + resolution: + { + integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==, + } fast-wrap-ansi@0.2.2: - resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + resolution: + { + integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==, + } fast-xml-builder@1.2.0: - resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} + resolution: + { + integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==, + } fast-xml-parser@5.7.3: - resolution: {integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==} + resolution: + { + integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==, + } hasBin: true fast-xml-parser@5.8.0: - resolution: {integrity: sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==} + resolution: + { + integrity: sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==, + } hasBin: true fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + resolution: + { + integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==, + } fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + resolution: + { + integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==, + } fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==, + } + engines: { node: ">=12.0.0" } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -4698,171 +7525,315 @@ packages: optional: true fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} + resolution: + { + integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==, + } + engines: { node: ^12.20 || >= 14.13 } file-type@21.3.4: - resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==, + } + engines: { node: ">=20" } file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + resolution: + { + integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==, + } fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, + } + engines: { node: ">=8" } finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} + resolution: + { + integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==, + } + engines: { node: ">= 18.0.0" } fix-dts-default-cjs-exports@1.0.1: - resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==} + resolution: + { + integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==, + } flattie@1.1.1: - resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==, + } + engines: { node: ">=8" } follow-redirects@1.16.0: - resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} - engines: {node: '>=4.0'} + resolution: + { + integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==, + } + engines: { node: ">=4.0" } peerDependencies: - debug: '*' + debug: "*" peerDependenciesMeta: debug: optional: true fontace@0.4.1: - resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} + resolution: + { + integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==, + } fontkitten@1.0.3: - resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==, + } + engines: { node: ">=20" } form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==, + } + engines: { node: ">= 6" } formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} + resolution: + { + integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==, + } + engines: { node: ">=12.20.0" } forwarded-parse@2.1.2: - resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} + resolution: + { + integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==, + } forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, + } + engines: { node: ">= 0.6" } fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==, + } + engines: { node: ">= 0.8" } fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + resolution: + { + integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==, + } fs-extra@11.1.0: - resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} - engines: {node: '>=14.14'} + resolution: + { + integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==, + } + engines: { node: ">=14.14" } fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} - engines: {node: '>=14.14'} + resolution: + { + integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==, + } + engines: { node: ">=14.14" } + + fsevents@2.3.2: + resolution: + { + integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } + os: [darwin] fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { + integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, + } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { + integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, + } gaxios@7.1.4: - resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==, + } + engines: { node: ">=18" } gcp-metadata@8.1.2: - resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==, + } + engines: { node: ">=18" } generic-pool@3.4.2: - resolution: {integrity: sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag==, + } + engines: { node: ">= 4" } get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + resolution: + { + integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, + } + engines: { node: 6.* || 8.* || >= 10.* } + + get-east-asian-width@1.6.0: + resolution: + { + integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==, + } + engines: { node: ">=18" } get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, + } + engines: { node: ">= 0.4" } get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, + } + engines: { node: ">= 0.4" } get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==, + } + engines: { node: ">=8" } get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, + } + engines: { node: ">=10" } get-tsconfig@4.14.0: - resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + resolution: + { + integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==, + } get-tsconfig@5.0.0-beta.4: - resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==} - engines: {node: '>=20.20.0'} + resolution: + { + integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==, + } + engines: { node: ">=20.20.0" } get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==, + } + engines: { node: ">= 14" } github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + resolution: + { + integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==, + } github-slugger@2.0.0: - resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + resolution: + { + integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==, + } glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, + } + engines: { node: ">= 6" } glob@13.0.6: - resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==, + } + engines: { node: 18 || 20 || >=22 } global-directory@4.0.1: - resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==, + } + engines: { node: ">=18" } google-auth-library@10.6.2: - resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==, + } + engines: { node: ">=18" } google-logging-utils@1.1.3: - resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==, + } + engines: { node: ">=14" } gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, + } + engines: { node: ">= 0.4" } graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: + { + integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, + } graphql@16.14.0: - resolution: {integrity: sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + resolution: + { + integrity: sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q==, + } + engines: { node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0 } h3@1.15.11: - resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + resolution: + { + integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==, + } h3@2.0.1-rc.22: - resolution: {integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==} - engines: {node: '>=20.11.1'} + resolution: + { + integrity: sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==, + } + engines: { node: ">=20.11.1" } hasBin: true peerDependencies: crossws: ^0.4.1 @@ -4871,143 +7842,269 @@ packages: optional: true has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, + } + engines: { node: ">=8" } has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, + } + engines: { node: ">= 0.4" } has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, + } + engines: { node: ">= 0.4" } hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==, + } + engines: { node: ">= 0.4" } hast-util-embedded@3.0.0: - resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + resolution: + { + integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==, + } hast-util-format@1.1.0: - resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + resolution: + { + integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==, + } hast-util-from-html@2.0.3: - resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + resolution: + { + integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==, + } hast-util-from-parse5@8.0.3: - resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + resolution: + { + integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==, + } hast-util-has-property@3.0.0: - resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + resolution: + { + integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==, + } hast-util-is-body-ok-link@3.0.1: - resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + resolution: + { + integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==, + } hast-util-is-element@3.0.0: - resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + resolution: + { + integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==, + } hast-util-minify-whitespace@1.0.1: - resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + resolution: + { + integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==, + } hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + resolution: + { + integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==, + } hast-util-phrasing@3.0.1: - resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + resolution: + { + integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==, + } hast-util-raw@9.1.0: - resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + resolution: + { + integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==, + } hast-util-select@6.0.4: - resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + resolution: + { + integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==, + } hast-util-to-estree@3.1.3: - resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + resolution: + { + integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==, + } hast-util-to-html@9.0.5: - resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + resolution: + { + integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==, + } hast-util-to-jsx-runtime@2.3.6: - resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + resolution: + { + integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==, + } hast-util-to-parse5@8.0.1: - resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} + resolution: + { + integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==, + } hast-util-to-string@3.0.1: - resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + resolution: + { + integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==, + } hast-util-to-text@4.0.2: - resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + resolution: + { + integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==, + } hast-util-whitespace@3.0.0: - resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + resolution: + { + integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==, + } hastscript@9.0.1: - resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + resolution: + { + integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==, + } he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + resolution: + { + integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, + } hasBin: true headers-polyfill@5.0.1: - resolution: {integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==} + resolution: + { + integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==, + } hono@4.12.22: - resolution: {integrity: sha512-7fvVPbB92zNRsQke+uiRGwtTuef0tB2Dg4hWxYfFNvkQhIltWoyi0ONReM5LWA+jJWS3nfT5lTq+qbsIpX0IQw==} - engines: {node: '>=16.9.0'} + resolution: + { + integrity: sha512-7fvVPbB92zNRsQke+uiRGwtTuef0tB2Dg4hWxYfFNvkQhIltWoyi0ONReM5LWA+jJWS3nfT5lTq+qbsIpX0IQw==, + } + engines: { node: ">=16.9.0" } hookable@6.1.1: - resolution: {integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==} + resolution: + { + integrity: sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ==, + } html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + resolution: + { + integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, + } html-escaper@3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + resolution: + { + integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==, + } html-void-elements@3.0.0: - resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + resolution: + { + integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==, + } html-whitespace-sensitive-tag-names@3.0.1: - resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + resolution: + { + integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==, + } http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + resolution: + { + integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==, + } http-errors@1.7.3: - resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==, + } + engines: { node: ">= 0.6" } http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==, + } + engines: { node: ">= 0.8" } http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==, + } + engines: { node: ">= 14" } https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, + } + engines: { node: ">= 6" } https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==, + } + engines: { node: ">= 14" } httpxy@0.5.3: - resolution: {integrity: sha512-SMS9V6Sn7VWaS11lYhoAr0ceoaiolTWf4jYdJn0NJhCdKMu9R2H9Fh0LBDWBHQF6HRLI1PmaePYsjanSpE5PEw==} + resolution: + { + integrity: sha512-SMS9V6Sn7VWaS11lYhoAr0ceoaiolTWf4jYdJn0NJhCdKMu9R2H9Fh0LBDWBHQF6HRLI1PmaePYsjanSpE5PEw==, + } human-signals@1.1.1: - resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} - engines: {node: '>=8.12.0'} + resolution: + { + integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==, + } + engines: { node: ">=8.12.0" } human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} + resolution: + { + integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, + } + engines: { node: ">=10.17.0" } i18next@26.2.0: - resolution: {integrity: sha512-zwBHldHdTmwN7r6UNc7lC6GWNN+YYg3DrRSeHR5PRRBf5QnJZcYHrQc0uaU26qZeYxR7iFZD+Y315dPnKP47wA==} + resolution: + { + integrity: sha512-zwBHldHdTmwN7r6UNc7lC6GWNN+YYg3DrRSeHR5PRRBf5QnJZcYHrQc0uaU26qZeYxR7iFZD+Y315dPnKP47wA==, + } peerDependencies: typescript: ^5 || ^6 peerDependenciesMeta: @@ -5015,741 +8112,1363 @@ packages: optional: true iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, + } + engines: { node: ">=0.10.0" } iconv-lite@0.7.2: - resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==, + } + engines: { node: ">=0.10.0" } ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + resolution: + { + integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, + } ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==, + } + engines: { node: ">= 4" } immer@10.2.0: - resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} + resolution: + { + integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==, + } immer@11.1.8: - resolution: {integrity: sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==} + resolution: + { + integrity: sha512-/tbkHMW7y10Lx6i1crLjD4/OhNkRG+Fo7byZHtah0547nIeXYcpIXaUh0IAQY6gO5459qpGGYapcEOHtFXkIuA==, + } import-in-the-middle@2.0.6: - resolution: {integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==} + resolution: + { + integrity: sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==, + } import-in-the-middle@3.0.1: - resolution: {integrity: sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA==, + } + engines: { node: ">=18" } inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + resolution: + { + integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, + } ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + resolution: + { + integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, + } ini@4.1.1: - resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + resolution: + { + integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==, + } + engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } ini@6.0.0: - resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} - engines: {node: ^20.17.0 || >=22.9.0} + resolution: + { + integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==, + } + engines: { node: ^20.17.0 || >=22.9.0 } inline-style-parser@0.2.7: - resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + resolution: + { + integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==, + } internmap@2.0.3: - resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==, + } + engines: { node: ">=12" } interpret@3.1.1: - resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==, + } + engines: { node: ">=10.13.0" } ip-address@10.2.0: - resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} - engines: {node: '>= 12'} + resolution: + { + integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==, + } + engines: { node: ">= 12" } ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, + } + engines: { node: ">= 0.10" } iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + resolution: + { + integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==, + } is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + resolution: + { + integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==, + } is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + resolution: + { + integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==, + } is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==, + } + engines: { node: ">=4" } is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==, + } + engines: { node: ">= 0.4" } is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + resolution: + { + integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==, + } is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } hasBin: true is-docker@4.0.0: - resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==, + } + engines: { node: ">=20" } hasBin: true is-electron@2.2.2: - resolution: {integrity: sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==} + resolution: + { + integrity: sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==, + } is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, + } + engines: { node: ">=0.10.0" } is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, + } + engines: { node: ">=8" } + + is-fullwidth-code-point@5.1.0: + resolution: + { + integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==, + } + engines: { node: ">=18" } is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, + } + engines: { node: ">=0.10.0" } is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + resolution: + { + integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==, + } is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==, + } + engines: { node: ">=14.16" } hasBin: true is-installed-globally@1.0.0: - resolution: {integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-K55T22lfpQ63N4KEN57jZUAaAYqYHEe8veb/TycJRk9DdSCLLcovXz/mL6mOnhQaZsQGwPhuFopdQIlqGSEjiQ==, + } + engines: { node: ">=18" } is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + resolution: + { + integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==, + } is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + resolution: + { + integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, + } + engines: { node: ">=0.12.0" } is-path-inside@4.0.0: - resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==, + } + engines: { node: ">=12" } is-plain-obj@4.1.0: - resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==, + } + engines: { node: ">=12" } is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + resolution: + { + integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==, + } is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, + } + engines: { node: ">=8" } is-wsl@3.1.1: - resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==, + } + engines: { node: ">=16" } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { + integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, + } istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, + } + engines: { node: ">=8" } istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, + } + engines: { node: ">=10" } istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==, + } + engines: { node: ">=8" } jiti@2.7.0: - resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + resolution: + { + integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==, + } hasBin: true jose@5.9.6: - resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} + resolution: + { + integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==, + } jose@6.2.3: - resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} + resolution: + { + integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==, + } joycon@3.1.1: - resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==, + } + engines: { node: ">=10" } js-tokens@10.0.0: - resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + resolution: + { + integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==, + } js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + resolution: + { + integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==, + } hasBin: true json-bigint@1.0.0: - resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + resolution: + { + integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==, + } json-schema-to-ts@1.6.4: - resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==} + resolution: + { + integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==, + } json-schema-to-ts@3.1.1: - resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==, + } + engines: { node: ">=16" } json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + resolution: + { + integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, + } json-schema-typed@8.0.2: - resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + resolution: + { + integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==, + } json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + resolution: + { + integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==, + } json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, + } + engines: { node: ">=6" } hasBin: true jsonc-parser@2.3.1: - resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} + resolution: + { + integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==, + } jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + resolution: + { + integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==, + } jsonfile@6.2.1: - resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + resolution: + { + integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==, + } jsonlines@0.1.1: - resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} + resolution: + { + integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==, + } just-bash@3.0.1: - resolution: {integrity: sha512-YVyzCN08fKarUnwqy7rKOAcX+2MLYLnYInuowmUXn3mqhrtd4ieZNBuzdQG+qYV9DqnIWuv9Whiph0WRIWsBtw==} + resolution: + { + integrity: sha512-YVyzCN08fKarUnwqy7rKOAcX+2MLYLnYInuowmUXn3mqhrtd4ieZNBuzdQG+qYV9DqnIWuv9Whiph0WRIWsBtw==, + } hasBin: true jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + resolution: + { + integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==, + } jws@4.0.1: - resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + resolution: + { + integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==, + } kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, + } + engines: { node: ">=6" } kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==, + } + engines: { node: ">=6" } klona@2.0.6: - resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==, + } + engines: { node: ">= 8" } kysely@0.28.17: - resolution: {integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==} - engines: {node: '>=20.0.0'} + resolution: + { + integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==, + } + engines: { node: ">=20.0.0" } lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==, + } + engines: { node: ">= 12.0.0" } cpu: [arm64] os: [android] lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==, + } + engines: { node: ">= 12.0.0" } cpu: [arm64] os: [darwin] lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==, + } + engines: { node: ">= 12.0.0" } cpu: [x64] os: [darwin] lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==, + } + engines: { node: ">= 12.0.0" } cpu: [x64] os: [freebsd] lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==, + } + engines: { node: ">= 12.0.0" } cpu: [arm] os: [linux] lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==, + } + engines: { node: ">= 12.0.0" } cpu: [arm64] os: [linux] libc: [glibc] lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==, + } + engines: { node: ">= 12.0.0" } cpu: [arm64] os: [linux] libc: [musl] lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==, + } + engines: { node: ">= 12.0.0" } cpu: [x64] os: [linux] libc: [glibc] lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==, + } + engines: { node: ">= 12.0.0" } cpu: [x64] os: [linux] libc: [musl] lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==, + } + engines: { node: ">= 12.0.0" } cpu: [arm64] os: [win32] lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==, + } + engines: { node: ">= 12.0.0" } cpu: [x64] os: [win32] lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} + resolution: + { + integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==, + } + engines: { node: ">= 12.0.0" } lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==, + } + engines: { node: ">=14" } lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + resolution: + { + integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, + } linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + resolution: + { + integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==, + } lint-staged@17.0.5: - resolution: {integrity: sha512-d12yC+/e8RhBjZtaxZn71FyrgU/P5e+uAPifhCLwdosQZP/zamSdKRWDC30ocVIbzDKiFG1McHc/LUgB92GIPw==} - engines: {node: '>=22.22.1'} + resolution: + { + integrity: sha512-d12yC+/e8RhBjZtaxZn71FyrgU/P5e+uAPifhCLwdosQZP/zamSdKRWDC30ocVIbzDKiFG1McHc/LUgB92GIPw==, + } + engines: { node: ">=22.22.1" } hasBin: true + listr2@10.2.2: + resolution: + { + integrity: sha512-JtNtbZj8q5BnDMR7trpwvwk3RIrANtIVzEUm8w7amp6xelLgyuq+4WZoTH913XaQAoH/cNdYhaNzBPA2U3xbDw==, + } + engines: { node: ">=22.13.0" } + load-tsconfig@0.2.5: - resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + + log-update@6.1.0: + resolution: + { + integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==, + } + engines: { node: ">=18" } long@5.3.2: - resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + resolution: + { + integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==, + } longest-streak@3.1.0: - resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + resolution: + { + integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==, + } lru-cache@11.5.0: - resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==, + } + engines: { node: 20 || >=22 } lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, + } + engines: { node: ">=10" } lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==, + } + engines: { node: ">=12" } lucide-react@1.17.0: - resolution: {integrity: sha512-9FA9evdox/JQL5PT57fdA1x/yg8T7knJ98+zjTL3UfKza6pflQUUh3XtaQIHKvnsJw1lmsEyHVlt5jchYxOQ5w==} + resolution: + { + integrity: sha512-9FA9evdox/JQL5PT57fdA1x/yg8T7knJ98+zjTL3UfKza6pflQUUh3XtaQIHKvnsJw1lmsEyHVlt5jchYxOQ5w==, + } peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + resolution: + { + integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==, + } luxon@3.7.2: - resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==, + } + engines: { node: ">=12" } magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + resolution: + { + integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==, + } magicast@0.5.3: - resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} + resolution: + { + integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==, + } make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, + } + engines: { node: ">=10" } markdown-extensions@2.0.0: - resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==, + } + engines: { node: ">=16" } markdown-it@14.1.1: - resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + resolution: + { + integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==, + } hasBin: true markdown-table@3.0.4: - resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + resolution: + { + integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==, + } math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, + } + engines: { node: ">= 0.4" } mdast-util-definitions@6.0.0: - resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} + resolution: + { + integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==, + } mdast-util-directive@3.1.0: - resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + resolution: + { + integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==, + } mdast-util-find-and-replace@3.0.2: - resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + resolution: + { + integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==, + } mdast-util-from-markdown@2.0.3: - resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + resolution: + { + integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==, + } mdast-util-gfm-autolink-literal@2.0.1: - resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + resolution: + { + integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==, + } mdast-util-gfm-footnote@2.1.0: - resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + resolution: + { + integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==, + } mdast-util-gfm-strikethrough@2.0.0: - resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + resolution: + { + integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==, + } mdast-util-gfm-table@2.0.0: - resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + resolution: + { + integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==, + } mdast-util-gfm-task-list-item@2.0.0: - resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + resolution: + { + integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==, + } mdast-util-gfm@3.1.0: - resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + resolution: + { + integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==, + } mdast-util-mdx-expression@2.0.1: - resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + resolution: + { + integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==, + } mdast-util-mdx-jsx@3.2.0: - resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + resolution: + { + integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==, + } mdast-util-mdx@3.0.0: - resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + resolution: + { + integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==, + } mdast-util-mdxjs-esm@2.0.1: - resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + resolution: + { + integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==, + } mdast-util-phrasing@4.1.0: - resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + resolution: + { + integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==, + } mdast-util-to-hast@13.2.1: - resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + resolution: + { + integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==, + } mdast-util-to-markdown@2.1.2: - resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + resolution: + { + integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==, + } mdast-util-to-string@4.0.0: - resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + resolution: + { + integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==, + } mdn-data@2.0.28: - resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + resolution: + { + integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==, + } mdn-data@2.27.1: - resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + resolution: + { + integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==, + } mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + resolution: + { + integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==, + } media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==, + } + engines: { node: ">= 0.8" } merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==, + } + engines: { node: ">=18" } merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + resolution: + { + integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, + } merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, + } + engines: { node: ">= 8" } meriyah@6.1.4: - resolution: {integrity: sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==, + } + engines: { node: ">=18.0.0" } micro@9.3.5-canary.3: - resolution: {integrity: sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==} - engines: {node: '>= 8.0.0'} + resolution: + { + integrity: sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==, + } + engines: { node: ">= 8.0.0" } hasBin: true micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + resolution: + { + integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==, + } micromark-extension-directive@4.0.0: - resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + resolution: + { + integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==, + } micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + resolution: + { + integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==, + } micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + resolution: + { + integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==, + } micromark-extension-gfm-strikethrough@2.1.0: - resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + resolution: + { + integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==, + } micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + resolution: + { + integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==, + } micromark-extension-gfm-tagfilter@2.0.0: - resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + resolution: + { + integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==, + } micromark-extension-gfm-task-list-item@2.1.0: - resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + resolution: + { + integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==, + } micromark-extension-gfm@3.0.0: - resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + resolution: + { + integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==, + } micromark-extension-mdx-expression@3.0.1: - resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + resolution: + { + integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==, + } micromark-extension-mdx-jsx@3.0.2: - resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + resolution: + { + integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==, + } micromark-extension-mdx-md@2.0.0: - resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + resolution: + { + integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==, + } micromark-extension-mdxjs-esm@3.0.0: - resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + resolution: + { + integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==, + } micromark-extension-mdxjs@3.0.0: - resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + resolution: + { + integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==, + } micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + resolution: + { + integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==, + } micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + resolution: + { + integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==, + } micromark-factory-mdx-expression@2.0.3: - resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + resolution: + { + integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==, + } micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + resolution: + { + integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==, + } micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + resolution: + { + integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==, + } micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + resolution: + { + integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==, + } micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + resolution: + { + integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==, + } micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + resolution: + { + integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==, + } micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + resolution: + { + integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==, + } micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + resolution: + { + integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==, + } micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + resolution: + { + integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==, + } micromark-util-decode-string@2.0.1: - resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + resolution: + { + integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==, + } micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + resolution: + { + integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==, + } micromark-util-events-to-acorn@2.0.3: - resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + resolution: + { + integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==, + } micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + resolution: + { + integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==, + } micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + resolution: + { + integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==, + } micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + resolution: + { + integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==, + } micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + resolution: + { + integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==, + } micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + resolution: + { + integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==, + } micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + resolution: + { + integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==, + } micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + resolution: + { + integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==, + } micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + resolution: + { + integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==, + } micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, + } + engines: { node: ">=8.6" } mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, + } + engines: { node: ">= 0.6" } mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==, + } + engines: { node: ">= 0.6" } mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, + } + engines: { node: ">= 0.6" } mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==, + } + engines: { node: ">=18" } mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, + } + engines: { node: ">=6" } + + mimic-function@5.0.1: + resolution: + { + integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==, + } + engines: { node: ">=18" } mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==, + } + engines: { node: ">=10" } minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + resolution: + { + integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==, + } + engines: { node: 20 || >=22 } minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==, + } + engines: { node: 18 || 20 || >=22 } minimatch@3.1.5: - resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + resolution: + { + integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==, + } minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + resolution: + { + integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, + } minipass@7.1.3: - resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==, + } + engines: { node: ">=16 || 14 >=14.17" } minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==, + } + engines: { node: ">= 18" } mixpart@0.0.6: - resolution: {integrity: sha512-CRdXtgfQH2jARmtNmPR0Q7jL20fiESbaYk1b0KvLD0jCdUuemepREtsbd8nbiY6BHV9OGGddAZITNXklupUPUQ==} - engines: {node: '>=20.0.0'} + resolution: + { + integrity: sha512-CRdXtgfQH2jARmtNmPR0Q7jL20fiESbaYk1b0KvLD0jCdUuemepREtsbd8nbiY6BHV9OGGddAZITNXklupUPUQ==, + } + engines: { node: ">=20.0.0" } mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + resolution: + { + integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==, + } mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==, + } + engines: { node: ">=10" } hasBin: true mlly@1.8.2: - resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} + resolution: + { + integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==, + } modern-tar@0.7.6: - resolution: {integrity: sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==, + } + engines: { node: ">=18.0.0" } module-details-from-path@1.0.4: - resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + resolution: + { + integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==, + } mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, + } + engines: { node: ">=4" } mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==, + } + engines: { node: ">=10" } ms@2.1.1: - resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + resolution: + { + integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==, + } ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + resolution: + { + integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, + } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { + integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, + } msw@2.14.6: - resolution: {integrity: sha512-ALe+N10S72cyx94cMcy3Zs4HhXCj35sgeAL4c+WTvKi0zWnbd8/h0lcFqv0mb2P+aSgAdD7p9HzvA0DiUPxsyg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-ALe+N10S72cyx94cMcy3Zs4HhXCj35sgeAL4c+WTvKi0zWnbd8/h0lcFqv0mb2P+aSgAdD7p9HzvA0DiUPxsyg==, + } + engines: { node: ">=18" } hasBin: true peerDependencies: - typescript: '>= 4.8.x' + typescript: ">= 4.8.x" peerDependenciesMeta: typescript: optional: true muggle-string@0.4.1: - resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + resolution: + { + integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==, + } mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} + resolution: + { + integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==, + } + engines: { node: ^20.17.0 || >=22.9.0 } mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + resolution: + { + integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==, + } nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { + integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==, + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true nanostores@1.3.0: - resolution: {integrity: sha512-XPUa/jz+P1oJvN9VBxw4L9MtdFfaH3DAryqPssqhb2kXjmb9npz0dly6rCsgFWOPr4Yg9mTfM3MDZgZZ+7A3lA==} - engines: {node: ^20.0.0 || >=22.0.0} + resolution: + { + integrity: sha512-XPUa/jz+P1oJvN9VBxw4L9MtdFfaH3DAryqPssqhb2kXjmb9npz0dly6rCsgFWOPr4Yg9mTfM3MDZgZZ+7A3lA==, + } + engines: { node: ^20.0.0 || >=22.0.0 } napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + resolution: + { + integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==, + } negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==, + } + engines: { node: ">= 0.6" } neotraverse@0.6.18: - resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} - engines: {node: '>= 10'} + resolution: + { + integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==, + } + engines: { node: ">= 10" } netmask@2.1.1: - resolution: {integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==} - engines: {node: '>= 0.4.0'} + resolution: + { + integrity: sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==, + } + engines: { node: ">= 0.4.0" } nf3@0.3.17: - resolution: {integrity: sha512-N9zEWySuJFw+gR0lhS5863YsvNeudOdqRyFvNb+jMXbeTJOdrjDqkCpDginIZfUm0LzT1t1nCRiDeqQm/8kirQ==} + resolution: + { + integrity: sha512-N9zEWySuJFw+gR0lhS5863YsvNeudOdqRyFvNb+jMXbeTJOdrjDqkCpDginIZfUm0LzT1t1nCRiDeqQm/8kirQ==, + } nitro@3.0.260522-beta: - resolution: {integrity: sha512-L/z2eOWgkiQHc65kv+SEMgau505afSRF7NJlbooaaZEZscFrNSD7rXZzeVubQlgIzPbhOG8o73bk9soIiGTHRA==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-L/z2eOWgkiQHc65kv+SEMgau505afSRF7NJlbooaaZEZscFrNSD7rXZzeVubQlgIzPbhOG8o73bk9soIiGTHRA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: - '@vercel/queue': ^0.2.0 - dotenv: '*' - giget: '*' + "@vercel/queue": ^0.2.0 + dotenv: "*" + giget: "*" jiti: ^2.6.1 rollup: ^4.60.3 vite: ^7 || ^8 xml2js: ^0.6.2 zephyr-agent: ^0.2.0 peerDependenciesMeta: - '@vercel/queue': + "@vercel/queue": optional: true dotenv: optional: true @@ -5767,30 +9486,51 @@ packages: optional: true nlcst-to-string@4.0.0: - resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + resolution: + { + integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==, + } node-abi@3.92.0: - resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==, + } + engines: { node: ">=10" } node-addon-api@7.1.1: - resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + resolution: + { + integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==, + } node-addon-api@8.8.0: - resolution: {integrity: sha512-c5Ko1fZJIJmzhFIkhRN76WTq+fC6tWnGy9CXA0fA+XygsWZmEwG8vmbkNqxMyoaa0Tin4djul49NzdVcJJcjeA==} - engines: {node: ^18 || ^20 || >= 21} + resolution: + { + integrity: sha512-c5Ko1fZJIJmzhFIkhRN76WTq+fC6tWnGy9CXA0fA+XygsWZmEwG8vmbkNqxMyoaa0Tin4djul49NzdVcJJcjeA==, + } + engines: { node: ^18 || ^20 || >= 21 } node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} + resolution: + { + integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==, + } + engines: { node: ">=10.5.0" } deprecated: Use your platform's native DOMException instead node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + resolution: + { + integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==, + } node-fetch@2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} + resolution: + { + integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==, + } + engines: { node: 4.x || >=6.0.0 } peerDependencies: encoding: ^0.1.0 peerDependenciesMeta: @@ -5798,8 +9538,11 @@ packages: optional: true node-fetch@2.6.9: - resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} - engines: {node: 4.x || >=6.0.0} + resolution: + { + integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==, + } + engines: { node: 4.x || >=6.0.0 } peerDependencies: encoding: ^0.1.0 peerDependenciesMeta: @@ -5807,8 +9550,11 @@ packages: optional: true node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} + resolution: + { + integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==, + } + engines: { node: 4.x || >=6.0.0 } peerDependencies: encoding: ^0.1.0 peerDependenciesMeta: @@ -5816,89 +9562,168 @@ packages: optional: true node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + resolution: + { + integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==, + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } node-gyp-build@4.8.4: - resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + resolution: + { + integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==, + } hasBin: true node-html-markdown@2.0.0: - resolution: {integrity: sha512-DqUC3GGP7pwSYxS93SwHoP+qCw78xcMP6C6H2DuC8rPD2AweJRjBzQb5SdXpKtDlqAQ7hVotJcfhgU7hU5Gthw==} - engines: {node: '>=20.0.0'} + resolution: + { + integrity: sha512-DqUC3GGP7pwSYxS93SwHoP+qCw78xcMP6C6H2DuC8rPD2AweJRjBzQb5SdXpKtDlqAQ7hVotJcfhgU7hU5Gthw==, + } + engines: { node: ">=20.0.0" } node-html-parser@6.1.13: - resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} + resolution: + { + integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==, + } node-liblzma@2.2.0: - resolution: {integrity: sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g==} - engines: {node: '>=16.0.0'} + resolution: + { + integrity: sha512-s0KzNOWwOJJgPG6wxg6cKohnAl9Wk/oW1KrQaVzJBjQwVcUGPQCzpR46Ximygjqj/3KhOrtJXnYMp/xYAXp75g==, + } + engines: { node: ">=16.0.0" } hasBin: true node-mock-http@1.0.4: - resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + resolution: + { + integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==, + } nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} + resolution: + { + integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==, + } + engines: { node: ^18.17.0 || >=20.5.0 } hasBin: true normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, + } + engines: { node: ">=0.10.0" } npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, + } + engines: { node: ">=8" } nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + resolution: + { + integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, + } object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, + } + engines: { node: ">=0.10.0" } object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==, + } + engines: { node: ">= 0.4" } obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + resolution: + { + integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==, + } ocache@0.1.4: - resolution: {integrity: sha512-e7geNdWjxSnvsSgvLuPvgKgu7ubM10ZmTPOgpr7mz2BXYtvjMKTiLhjFi/gWU8chkuP6hNkZBsa9LzOusyaqkQ==} + resolution: + { + integrity: sha512-e7geNdWjxSnvsSgvLuPvgKgu7ubM10ZmTPOgpr7mz2BXYtvjMKTiLhjFi/gWU8chkuP6hNkZBsa9LzOusyaqkQ==, + } ofetch@1.5.1: - resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + resolution: + { + integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==, + } ofetch@2.0.0-alpha.3: - resolution: {integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==} + resolution: + { + integrity: sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==, + } ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + resolution: + { + integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==, + } on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, + } + engines: { node: ">= 0.8" } once@1.3.3: - resolution: {integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==} + resolution: + { + integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==, + } once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + resolution: + { + integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, + } onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, + } + engines: { node: ">=6" } + + onetime@7.0.0: + resolution: + { + integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==, + } + engines: { node: ">=18" } oniguruma-parser@0.12.2: - resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + resolution: + { + integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==, + } oniguruma-to-es@4.3.6: - resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + resolution: + { + integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==, + } openai@6.26.0: - resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==} + resolution: + { + integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==, + } hasBin: true peerDependencies: ws: 8.20.1 @@ -5910,204 +9735,376 @@ packages: optional: true os-paths@4.4.0: - resolution: {integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==} - engines: {node: '>= 6.0'} + resolution: + { + integrity: sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==, + } + engines: { node: ">= 6.0" } outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + resolution: + { + integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==, + } oxc-transform@0.111.0: - resolution: {integrity: sha512-oa5KKSDNLHZGaiqIGAbCWXeN9IJUAz9MElWcQX90epDxdKc9Hrt/BsLj3K4gDqfAYa5dwdH+ZCFJG9hR74fiGg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-oa5KKSDNLHZGaiqIGAbCWXeN9IJUAz9MElWcQX90epDxdKc9Hrt/BsLj3K4gDqfAYa5dwdH+ZCFJG9hR74fiGg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } oxlint@1.66.0: - resolution: {integrity: sha512-N4LLxYLd94KEBqXDMDM5f+2PUpItTjDLreXe2Gn5KhjhCK4Qp2YUXaBi8Yu325ryOgKwt22m45fpD7nPOn69Yw==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-N4LLxYLd94KEBqXDMDM5f+2PUpItTjDLreXe2Gn5KhjhCK4Qp2YUXaBi8Yu325ryOgKwt22m45fpD7nPOn69Yw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.22.1' + oxlint-tsgolint: ">=0.22.1" peerDependenciesMeta: oxlint-tsgolint: optional: true p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==, + } + engines: { node: ">=4" } p-finally@2.0.1: - resolution: {integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==, + } + engines: { node: ">=8" } p-limit@7.3.0: - resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==, + } + engines: { node: ">=20" } p-queue@6.6.2: - resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==, + } + engines: { node: ">=8" } p-queue@9.3.0: - resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==, + } + engines: { node: ">=20" } p-retry@4.6.2: - resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==, + } + engines: { node: ">=8" } p-timeout@3.2.0: - resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==, + } + engines: { node: ">=8" } p-timeout@7.0.1: - resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==, + } + engines: { node: ">=20" } pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==, + } + engines: { node: ">= 14" } pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==, + } + engines: { node: ">= 14" } package-manager-detector@1.6.0: - resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + resolution: + { + integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==, + } pagefind@1.5.2: - resolution: {integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==} + resolution: + { + integrity: sha512-XTUaK0hXMCu2jszWE584JGQT7y284TmMV9l/HX3rnG5uo3rHI/uHU56XTyyyPFjeWEBxECbAi0CaFDJOONtG0Q==, + } hasBin: true papaparse@5.5.3: - resolution: {integrity: sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==} + resolution: + { + integrity: sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==, + } parse-entities@4.0.2: - resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + resolution: + { + integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==, + } parse-latin@7.0.0: - resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + resolution: + { + integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==, + } parse-ms@2.1.0: - resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==, + } + engines: { node: ">=6" } parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + resolution: + { + integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==, + } parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, + } + engines: { node: ">= 0.8" } partial-json@0.1.7: - resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + resolution: + { + integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==, + } path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + resolution: + { + integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==, + } path-expression-matcher@1.5.0: - resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==, + } + engines: { node: ">=14.0.0" } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, + } + engines: { node: ">=8" } path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + resolution: + { + integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, + } path-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} + resolution: + { + integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==, + } + engines: { node: 18 || 20 || >=22 } path-to-regexp@6.1.0: - resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} + resolution: + { + integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==, + } path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + resolution: + { + integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==, + } path-to-regexp@8.2.0: - resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==, + } + engines: { node: ">=16" } path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + resolution: + { + integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==, + } path-to-regexp@8.4.2: - resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + resolution: + { + integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==, + } pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + resolution: + { + integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==, + } pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + resolution: + { + integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==, + } pg-cloudflare@1.4.0: - resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} + resolution: + { + integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==, + } pg-connection-string@2.13.0: - resolution: {integrity: sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig==} + resolution: + { + integrity: sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig==, + } pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} + resolution: + { + integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==, + } + engines: { node: ">=4.0.0" } pg-pool@3.14.0: - resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==} + resolution: + { + integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==, + } peerDependencies: - pg: '>=8.0' + pg: ">=8.0" pg-protocol@1.14.0: - resolution: {integrity: sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA==} + resolution: + { + integrity: sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA==, + } pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==, + } + engines: { node: ">=4" } pg@8.21.0: - resolution: {integrity: sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA==} - engines: {node: '>= 16.0.0'} + resolution: + { + integrity: sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA==, + } + engines: { node: ">= 16.0.0" } peerDependencies: - pg-native: '>=3.0.1' + pg-native: ">=3.0.1" peerDependenciesMeta: pg-native: optional: true pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + resolution: + { + integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==, + } piccolore@0.1.3: - resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} + resolution: + { + integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==, + } picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + resolution: + { + integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, + } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { + integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, + } picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} + resolution: + { + integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==, + } + engines: { node: ">=8.6" } picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==, + } + engines: { node: ">=12" } pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==, + } + engines: { node: ">= 6" } pkce-challenge@5.0.1: - resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} - engines: {node: '>=16.20.0'} + resolution: + { + integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==, + } + engines: { node: ">=16.20.0" } pkg-types@1.3.1: - resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} + resolution: + { + integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==, + } + + playwright-core@1.60.0: + resolution: + { + integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==, + } + engines: { node: ">=18" } + hasBin: true + + playwright@1.60.0: + resolution: + { + integrity: sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==, + } + engines: { node: ">=18" } + hasBin: true postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==, + } + engines: { node: ">= 18" } peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' + jiti: ">=1.21.0" + postcss: ">=8.0.9" tsx: ^4.8.1 yaml: ^2.9.0 peerDependenciesMeta: @@ -6121,806 +10118,1495 @@ packages: optional: true postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} + resolution: + { + integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==, + } + engines: { node: ">=12.0" } peerDependencies: postcss: ^8.2.14 postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==, + } + engines: { node: ">=4" } postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { + integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==, + } + engines: { node: ^10 || ^12 || >=14 } postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==, + } + engines: { node: ">=4" } postgres-bytea@1.0.1: - resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==, + } + engines: { node: ">=0.10.0" } postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==, + } + engines: { node: ">=0.10.0" } postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==, + } + engines: { node: ">=0.10.0" } prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==, + } + engines: { node: ">=10" } deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. hasBin: true prettier@3.8.3: - resolution: {integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==, + } + engines: { node: ">=14" } hasBin: true pretty-ms@7.0.1: - resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==, + } + engines: { node: ">=10" } prismjs@1.30.0: - resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==, + } + engines: { node: ">=6" } promisepipe@3.0.0: - resolution: {integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==} + resolution: + { + integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==, + } prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, + } + engines: { node: ">= 6" } property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + resolution: + { + integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==, + } protobufjs@7.6.1: - resolution: {integrity: sha512-4K0myLaWL5EteuSAro91EGFgcfVgxb64Jx+7oDAY6GOkXD4M69yuSEljNcInGVCA5sOPxmZ/EqDLj2x0Q0+Ygg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-4K0myLaWL5EteuSAro91EGFgcfVgxb64Jx+7oDAY6GOkXD4M69yuSEljNcInGVCA5sOPxmZ/EqDLj2x0Q0+Ygg==, + } + engines: { node: ">=12.0.0" } proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, + } + engines: { node: ">= 0.10" } proxy-agent@6.4.0: - resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==, + } + engines: { node: ">= 14" } proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + resolution: + { + integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, + } proxy-from-env@2.1.0: - resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==, + } + engines: { node: ">=10" } publint@0.3.21: - resolution: {integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==, + } + engines: { node: ">=18" } hasBin: true pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + resolution: + { + integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==, + } punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==, + } + engines: { node: ">=6" } punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, + } + engines: { node: ">=6" } qs@6.15.2: - resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==, + } + engines: { node: ">=0.6" } queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, + } quickjs-emscripten-core@0.32.0: - resolution: {integrity: sha512-QFnPfjFey8EqknSrSxe1hZrf1/8z7/6s1QzGOmKo6++02r7QRRX7ZoyNaZh7JuVjWsVW87KnQrbZqnHkOAzUyg==} + resolution: + { + integrity: sha512-QFnPfjFey8EqknSrSxe1hZrf1/8z7/6s1QzGOmKo6++02r7QRRX7ZoyNaZh7JuVjWsVW87KnQrbZqnHkOAzUyg==, + } quickjs-emscripten@0.32.0: - resolution: {integrity: sha512-So0Sqw869y/S2oE3Nuc0uT3Dhqgvsj8FSrwBdsuTosVsG8ME5/OcudU1GxsrIFdFABgy17GHnTVO9TYV/bLQcA==} - engines: {node: '>=16.0.0'} + resolution: + { + integrity: sha512-So0Sqw869y/S2oE3Nuc0uT3Dhqgvsj8FSrwBdsuTosVsG8ME5/OcudU1GxsrIFdFABgy17GHnTVO9TYV/bLQcA==, + } + engines: { node: ">=16.0.0" } radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + resolution: + { + integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==, + } range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, + } + engines: { node: ">= 0.6" } raw-body@2.4.1: - resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==, + } + engines: { node: ">= 0.8" } raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} + resolution: + { + integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==, + } + engines: { node: ">= 0.10" } rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + resolution: + { + integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==, + } hasBin: true re2js@1.3.3: - resolution: {integrity: sha512-s/I5zEAo79SUK0Qw4dpZKpiMwbQ6Gz0KU2NRr7eaO4x/p2g7Vvmn3hdeXDg8VsaUjfj/ora+e9oi27LX/C9+mw==} + resolution: + { + integrity: sha512-s/I5zEAo79SUK0Qw4dpZKpiMwbQ6Gz0KU2NRr7eaO4x/p2g7Vvmn3hdeXDg8VsaUjfj/ora+e9oi27LX/C9+mw==, + } react-dom@19.2.6: - resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + resolution: + { + integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==, + } peerDependencies: react: ^19.2.6 react-is@19.2.7: - resolution: {integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==} + resolution: + { + integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==, + } react-redux@9.3.0: - resolution: {integrity: sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==} + resolution: + { + integrity: sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==, + } peerDependencies: - '@types/react': ^18.2.25 || ^19 + "@types/react": ^18.2.25 || ^19 react: ^18.0 || ^19 redux: ^5.0.0 peerDependenciesMeta: - '@types/react': + "@types/react": optional: true redux: optional: true react-router@7.16.0: - resolution: {integrity: sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A==} - engines: {node: '>=20.0.0'} + resolution: + { + integrity: sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A==, + } + engines: { node: ">=20.0.0" } peerDependencies: - react: '>=18' - react-dom: '>=18' + react: ">=18" + react-dom: ">=18" peerDependenciesMeta: react-dom: optional: true react@19.2.6: - resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==, + } + engines: { node: ">=0.10.0" } readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + resolution: + { + integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, + } + engines: { node: ">= 6" } readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} + resolution: + { + integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==, + } + engines: { node: ">= 14.18.0" } readdirp@5.0.0: - resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} - engines: {node: '>= 20.19.0'} + resolution: + { + integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==, + } + engines: { node: ">= 20.19.0" } recharts@3.8.1: - resolution: {integrity: sha512-mwzmO1s9sFL0TduUpwndxCUNoXsBw3u3E/0+A+cLcrSfQitSG62L32N69GhqUrrT5qKcAE3pCGVINC6pqkBBQg==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-mwzmO1s9sFL0TduUpwndxCUNoXsBw3u3E/0+A+cLcrSfQitSG62L32N69GhqUrrT5qKcAE3pCGVINC6pqkBBQg==, + } + engines: { node: ">=18" } peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 rechoir@0.8.0: - resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} - engines: {node: '>= 10.13.0'} + resolution: + { + integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==, + } + engines: { node: ">= 10.13.0" } recma-build-jsx@1.0.0: - resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + resolution: + { + integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==, + } recma-jsx@1.0.1: - resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + resolution: + { + integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==, + } peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 recma-parse@1.0.0: - resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + resolution: + { + integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==, + } recma-stringify@1.0.0: - resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + resolution: + { + integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==, + } redis@5.12.1: - resolution: {integrity: sha512-LDsoVvb/CpoV9EN3FXvgvSHNJWuCIzl9MiO3ppOevuGLpSGJhwfQjpEwfFJcQvNSddHADDdZaWx0HnmMxRXG7g==} - engines: {node: '>= 18.19.0'} + resolution: + { + integrity: sha512-LDsoVvb/CpoV9EN3FXvgvSHNJWuCIzl9MiO3ppOevuGLpSGJhwfQjpEwfFJcQvNSddHADDdZaWx0HnmMxRXG7g==, + } + engines: { node: ">= 18.19.0" } redux-thunk@3.1.0: - resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==} + resolution: + { + integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==, + } peerDependencies: redux: ^5.0.0 redux@5.0.1: - resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==} + resolution: + { + integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==, + } regex-recursion@6.0.2: - resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + resolution: + { + integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==, + } regex-utilities@2.3.0: - resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + resolution: + { + integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==, + } regex@6.1.0: - resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + resolution: + { + integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==, + } regexp-tree@0.1.27: - resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + resolution: + { + integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==, + } hasBin: true rehype-expressive-code@0.42.0: - resolution: {integrity: sha512-8rp/1YMEVVSYbtz+bFBx+uSx3vA4i4T8RwRm5Q/IWbucQnnQqQ0hDqtmKOr8tv+59Cik6cu5aH3WPo0I7csuTA==} + resolution: + { + integrity: sha512-8rp/1YMEVVSYbtz+bFBx+uSx3vA4i4T8RwRm5Q/IWbucQnnQqQ0hDqtmKOr8tv+59Cik6cu5aH3WPo0I7csuTA==, + } rehype-format@5.0.1: - resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} + resolution: + { + integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==, + } rehype-parse@9.0.1: - resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} + resolution: + { + integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==, + } rehype-raw@7.0.0: - resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + resolution: + { + integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==, + } rehype-recma@1.0.0: - resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + resolution: + { + integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==, + } rehype-stringify@10.0.1: - resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} + resolution: + { + integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==, + } rehype@13.0.2: - resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} + resolution: + { + integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==, + } remark-directive@4.0.0: - resolution: {integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==} + resolution: + { + integrity: sha512-7sxn4RfF1o3izevPV1DheyGDD6X4c9hrGpfdUpm7uC++dqrnJxIZVkk7CoKqcLm0VUMAuOol7Mno3m6g8cfMuA==, + } remark-gfm@4.0.1: - resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + resolution: + { + integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==, + } remark-mdx@3.1.1: - resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + resolution: + { + integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==, + } remark-parse@11.0.0: - resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + resolution: + { + integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==, + } remark-rehype@11.1.2: - resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + resolution: + { + integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==, + } remark-smartypants@3.0.2: - resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} - engines: {node: '>=16.0.0'} + resolution: + { + integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==, + } + engines: { node: ">=16.0.0" } remark-stringify@11.0.0: - resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + resolution: + { + integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==, + } remend@1.3.0: - resolution: {integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==} + resolution: + { + integrity: sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw==, + } request-light@0.5.8: - resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} + resolution: + { + integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==, + } request-light@0.7.0: - resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==} + resolution: + { + integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==, + } require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, + } + engines: { node: ">=0.10.0" } require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, + } + engines: { node: ">=0.10.0" } require-in-the-middle@8.0.1: - resolution: {integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==} - engines: {node: '>=9.3.0 || >=8.10.0 <9.0.0'} + resolution: + { + integrity: sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==, + } + engines: { node: ">=9.3.0 || >=8.10.0 <9.0.0" } reselect@5.1.1: - resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==} + resolution: + { + integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==, + } resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, + } + engines: { node: ">=8" } resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolution: + { + integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==, + } resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==, + } + engines: { node: ">=10" } resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==, + } + engines: { node: ">= 0.4" } hasBin: true + restore-cursor@5.1.0: + resolution: + { + integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==, + } + engines: { node: ">=18" } + retext-latin@4.0.0: - resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + resolution: + { + integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==, + } retext-smartypants@6.2.0: - resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + resolution: + { + integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==, + } retext-stringify@4.0.0: - resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + resolution: + { + integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==, + } retext@9.0.0: - resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} + resolution: + { + integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==, + } retry@0.13.1: - resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} - engines: {node: '>= 4'} + resolution: + { + integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==, + } + engines: { node: ">= 4" } rettime@0.11.11: - resolution: {integrity: sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==} + resolution: + { + integrity: sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==, + } reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + resolution: + { + integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, + } + engines: { iojs: ">=1.0.0", node: ">=0.10.0" } + + rfdc@1.4.1: + resolution: + { + integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==, + } rolldown@1.0.0-rc.1: - resolution: {integrity: sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-M3AeZjYE6UclblEf531Hch0WfVC/NOL43Cc+WdF3J50kk5/fvouHhDumSGTh0oRjbZ8C4faaVr5r6Nx1xMqDGg==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true rolldown@1.0.2: - resolution: {integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolution: + { + integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==, + } + engines: { node: ">=18.0.0", npm: ">=8.0.0" } hasBin: true rou3@0.7.12: - resolution: {integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==} + resolution: + { + integrity: sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==, + } rou3@0.8.1: - resolution: {integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==} + resolution: + { + integrity: sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==, + } router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==, + } + engines: { node: ">= 18" } run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, + } + + sade@1.8.1: + resolution: + { + integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==, + } + engines: { node: ">=6" } safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + resolution: + { + integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, + } safe-regex@2.1.1: - resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + resolution: + { + integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==, + } safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + resolution: + { + integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, + } sandbox@2.5.6: - resolution: {integrity: sha512-tnFr7nyiuEhsAGb+xy60SDbij0790X+FgDljh3J/2HaRM6yQgNJkQKHbDH8ld7mR+PozXGgEfJ2Dc/5OyFnwsg==} + resolution: + { + integrity: sha512-tnFr7nyiuEhsAGb+xy60SDbij0790X+FgDljh3J/2HaRM6yQgNJkQKHbDH8ld7mR+PozXGgEfJ2Dc/5OyFnwsg==, + } hasBin: true sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} - engines: {node: '>=11.0.0'} + resolution: + { + integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==, + } + engines: { node: ">=11.0.0" } scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + resolution: + { + integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==, + } seek-bzip@2.0.0: - resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} + resolution: + { + integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==, + } hasBin: true semifies@1.0.0: - resolution: {integrity: sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==} + resolution: + { + integrity: sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==, + } semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + resolution: + { + integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, + } hasBin: true semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==, + } + engines: { node: ">=10" } hasBin: true semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==, + } + engines: { node: ">=10" } hasBin: true semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==, + } + engines: { node: ">=10" } hasBin: true send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==, + } + engines: { node: ">= 18" } sentry@0.38.0: - resolution: {integrity: sha512-jxW4P3bUqqeMo2dh8i7OpDsOwNe+GQZhE5Teazh+aTw0/nforhp3ZSBsmrm09kmRIUG2R4JrXMMS/8qYFLRCgg==} - engines: {node: '>=22.15'} + resolution: + { + integrity: sha512-jxW4P3bUqqeMo2dh8i7OpDsOwNe+GQZhE5Teazh+aTw0/nforhp3ZSBsmrm09kmRIUG2R4JrXMMS/8qYFLRCgg==, + } + engines: { node: ">=22.15" } hasBin: true serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==, + } + engines: { node: ">= 18" } set-cookie-parser@2.7.2: - resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + resolution: + { + integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==, + } set-cookie-parser@3.1.0: - resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} + resolution: + { + integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==, + } setprototypeof@1.1.1: - resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} + resolution: + { + integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==, + } setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + resolution: + { + integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, + } sharp@0.34.5: - resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + resolution: + { + integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==, + } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, + } + engines: { node: ">=8" } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, + } + engines: { node: ">=8" } shiki@4.1.0: - resolution: {integrity: sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q==, + } + engines: { node: ">=20" } side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==, + } + engines: { node: ">= 0.4" } side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==, + } + engines: { node: ">= 0.4" } side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==, + } + engines: { node: ">= 0.4" } side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==, + } + engines: { node: ">= 0.4" } siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + resolution: + { + integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, + } signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + resolution: + { + integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, + } signal-exit@4.0.2: - resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==, + } + engines: { node: ">=14" } signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + resolution: + { + integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, + } + engines: { node: ">=14" } simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + resolution: + { + integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==, + } simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + resolution: + { + integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==, + } simple-git-hooks@2.13.1: - resolution: {integrity: sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ==} + resolution: + { + integrity: sha512-WszCLXwT4h2k1ufIXAgsbiTOazqqevFCIncOuUBZJ91DdvWcC5+OFkluWRQPrcuSYd8fjq+o2y1QfWqYMoAToQ==, + } hasBin: true sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + resolution: + { + integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, + } sitemap@9.0.1: - resolution: {integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==} - engines: {node: '>=20.19.5', npm: '>=10.8.2'} + resolution: + { + integrity: sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==, + } + engines: { node: ">=20.19.5", npm: ">=10.8.2" } hasBin: true + slice-ansi@7.1.2: + resolution: + { + integrity: sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==, + } + engines: { node: ">=18" } + + slice-ansi@8.0.0: + resolution: + { + integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==, + } + engines: { node: ">=20" } + smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + resolution: + { + integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==, + } + engines: { node: ">= 6.0.0", npm: ">= 3.0.0" } smol-toml@1.5.2: - resolution: {integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-QlaZEqcAH3/RtNyet1IPIYPsEWAaYyXXv1Krsi+1L/QHppjX4Ifm8MQsBISz9vE8cHicIq3clogsheili5vhaQ==, + } + engines: { node: ">= 18" } smol-toml@1.6.1: - resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==, + } + engines: { node: ">= 18" } socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} + resolution: + { + integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==, + } + engines: { node: ">= 14" } socks@2.8.9: - resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + resolution: + { + integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==, + } + engines: { node: ">= 10.0.0", npm: ">= 3.0.0" } source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==, + } + engines: { node: ">=0.10.0" } source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + resolution: + { + integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, + } source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, + } + engines: { node: ">=0.10.0" } source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} + resolution: + { + integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==, + } + engines: { node: ">= 12" } space-separated-tokens@2.0.2: - resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + resolution: + { + integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==, + } split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} + resolution: + { + integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==, + } + engines: { node: ">= 10.x" } sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + resolution: + { + integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==, + } sql.js@1.14.1: - resolution: {integrity: sha512-gcj8zBWU5cFsi9WUP+4bFNXAyF1iRpA3LLyS/DP5xlrNzGmPIizUeBggKa8DbDwdqaKwUcTEnChtd2grWo/x/A==} + resolution: + { + integrity: sha512-gcj8zBWU5cFsi9WUP+4bFNXAyF1iRpA3LLyS/DP5xlrNzGmPIizUeBggKa8DbDwdqaKwUcTEnChtd2grWo/x/A==, + } srvx@0.11.16: - resolution: {integrity: sha512-bp07zRuycfTY43IjAvvTFnmnJi8ikW0VFiHwOhhYcVW/L4xQ1XY4PAd4Nuum1rsA17C39zL7x+CDhrn5AL32Rw==} - engines: {node: '>=20.16.0'} + resolution: + { + integrity: sha512-bp07zRuycfTY43IjAvvTFnmnJi8ikW0VFiHwOhhYcVW/L4xQ1XY4PAd4Nuum1rsA17C39zL7x+CDhrn5AL32Rw==, + } + engines: { node: ">=20.16.0" } hasBin: true srvx@0.8.9: - resolution: {integrity: sha512-wYc3VLZHRzwYrWJhkEqkhLb31TI0SOkfYZDkUhXdp3NoCnNS0FqajiQszZZjfow/VYEuc6Q5sZh9nM6kPy2NBQ==} - engines: {node: '>=20.16.0'} + resolution: + { + integrity: sha512-wYc3VLZHRzwYrWJhkEqkhLb31TI0SOkfYZDkUhXdp3NoCnNS0FqajiQszZZjfow/VYEuc6Q5sZh9nM6kPy2NBQ==, + } + engines: { node: ">=20.16.0" } hasBin: true stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + resolution: + { + integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, + } starlight-typedoc@0.23.0: - resolution: {integrity: sha512-GB0tB/15nL3l9tt1aGpkV8EixnSXbApZNZaSBRt8KfIsDAJet7pRiyItk5dxBSbDTXilF2whOMXPqqkbm8dNWA==} - engines: {node: '>=22.12.0'} + resolution: + { + integrity: sha512-GB0tB/15nL3l9tt1aGpkV8EixnSXbApZNZaSBRt8KfIsDAJet7pRiyItk5dxBSbDTXilF2whOMXPqqkbm8dNWA==, + } + engines: { node: ">=22.12.0" } peerDependencies: - '@astrojs/starlight': '>=0.39.0' - typedoc: '>=0.28.0' - typedoc-plugin-markdown: '>=4.6.0' + "@astrojs/starlight": ">=0.39.0" + typedoc: ">=0.28.0" + typedoc-plugin-markdown: ">=4.6.0" stat-mode@0.3.0: - resolution: {integrity: sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==} + resolution: + { + integrity: sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng==, + } statuses@1.5.0: - resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} - engines: {node: '>= 0.6'} + resolution: + { + integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==, + } + engines: { node: ">= 0.6" } statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==, + } + engines: { node: ">= 0.8" } std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + resolution: + { + integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==, + } stream-replace-string@2.0.0: - resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + resolution: + { + integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==, + } stream-to-array@2.3.0: - resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} + resolution: + { + integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==, + } stream-to-promise@2.2.0: - resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} + resolution: + { + integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==, + } deprecated: Deprecated. Use node:stream/promises and node:stream/consumers instead. streamx@2.25.0: - resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} + resolution: + { + integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==, + } strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + resolution: + { + integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==, + } + + string-argv@0.3.2: + resolution: + { + integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==, + } + engines: { node: ">=0.6.19" } string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, + } + engines: { node: ">=8" } + + string-width@7.2.0: + resolution: + { + integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==, + } + engines: { node: ">=18" } + + string-width@8.2.1: + resolution: + { + integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==, + } + engines: { node: ">=20" } string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + resolution: + { + integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, + } stringify-entities@4.0.4: - resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + resolution: + { + integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==, + } strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, + } + engines: { node: ">=8" } + + strip-ansi@7.2.0: + resolution: + { + integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==, + } + engines: { node: ">=12" } strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, + } + engines: { node: ">=4" } strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, + } + engines: { node: ">=6" } strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} + resolution: + { + integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==, + } + engines: { node: ">=0.10.0" } strnum@2.3.0: - resolution: {integrity: sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==} + resolution: + { + integrity: sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==, + } strtok3@10.3.5: - resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==, + } + engines: { node: ">=18" } style-to-js@1.1.21: - resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + resolution: + { + integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==, + } style-to-object@1.0.14: - resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + resolution: + { + integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==, + } sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { + integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==, + } + engines: { node: ">=16 || 14 >=14.17" } hasBin: true supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, + } + engines: { node: ">=8" } supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + resolution: + { + integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, + } + engines: { node: ">= 0.4" } svgo@4.0.1: - resolution: {integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==, + } + engines: { node: ">=16" } hasBin: true tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==, + } + engines: { node: ">=20" } tailwindcss@4.3.0: - resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==} + resolution: + { + integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==, + } tapable@2.3.3: - resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==, + } + engines: { node: ">=6" } tar-fs@2.1.4: - resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + resolution: + { + integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==, + } tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==, + } + engines: { node: ">=6" } tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + resolution: + { + integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==, + } tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==, + } + engines: { node: ">=18" } tar@7.5.7: - resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==, + } + engines: { node: ">=18" } deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me text-decoder@1.2.7: - resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} + resolution: + { + integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==, + } thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} + resolution: + { + integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==, + } + engines: { node: ">=0.8" } thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + resolution: + { + integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==, + } throttleit@2.1.0: - resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==, + } + engines: { node: ">=18" } time-span@4.0.0: - resolution: {integrity: sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==, + } + engines: { node: ">=10" } tiny-inflate@1.0.3: - resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + resolution: + { + integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==, + } tiny-invariant@1.3.3: - resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + resolution: + { + integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==, + } tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + resolution: + { + integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==, + } tinyclip@0.1.12: - resolution: {integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==} - engines: {node: ^16.14.0 || >= 17.3.0} + resolution: + { + integrity: sha512-Ae3OVUqifDw0wBriIBS7yVaW44Dp6eSHQcyq4Igc7eN2TJH/2YsicswaW+J/OuMvhpDPOKEgpAZCjkb4hpoyeA==, + } + engines: { node: ^16.14.0 || >= 17.3.0 } tinyexec@1.1.2: - resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==, + } + engines: { node: ">=18" } tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} - engines: {node: '>=12.0.0'} + resolution: + { + integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==, + } + engines: { node: ">=12.0.0" } tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==, + } + engines: { node: ">=14.0.0" } tldts-core@7.0.30: - resolution: {integrity: sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==} + resolution: + { + integrity: sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==, + } tldts@7.0.30: - resolution: {integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==} + resolution: + { + integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==, + } hasBin: true to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + resolution: + { + integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, + } + engines: { node: ">=8.0" } toidentifier@1.0.0: - resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==, + } + engines: { node: ">=0.6" } toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} + resolution: + { + integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, + } + engines: { node: ">=0.6" } token-types@6.1.2: - resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} - engines: {node: '>=14.16'} + resolution: + { + integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==, + } + engines: { node: ">=14.16" } tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} + resolution: + { + integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==, + } + engines: { node: ">=16" } tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + resolution: + { + integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, + } tree-kill@1.2.2: - resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + resolution: + { + integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==, + } hasBin: true trim-lines@3.0.1: - resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + resolution: + { + integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==, + } trough@2.2.0: - resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + resolution: + { + integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==, + } ts-algebra@2.0.0: - resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + resolution: + { + integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==, + } ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + resolution: + { + integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==, + } ts-morph@12.0.0: - resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} + resolution: + { + integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==, + } ts-toolbelt@6.15.5: - resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + resolution: + { + integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==, + } tsconfig-paths-webpack-plugin@4.2.0: - resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} - engines: {node: '>=10.13.0'} + resolution: + { + integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==, + } + engines: { node: ">=10.13.0" } tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==, + } + engines: { node: ">=6" } tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + resolution: + { + integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, + } tsup@8.5.1: - resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==, + } + engines: { node: ">=18" } hasBin: true peerDependencies: - '@microsoft/api-extractor': ^7.36.0 - '@swc/core': 1.15.33 + "@microsoft/api-extractor": ^7.36.0 + "@swc/core": 1.15.33 postcss: ^8.4.12 - typescript: '>=4.5.0' + typescript: ">=4.5.0" peerDependenciesMeta: - '@microsoft/api-extractor': + "@microsoft/api-extractor": optional: true - '@swc/core': + "@swc/core": optional: true postcss: optional: true @@ -6928,199 +11614,316 @@ packages: optional: true tsx@4.21.0: - resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==, + } + engines: { node: ">=18.0.0" } hasBin: true tsx@4.22.3: - resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} - engines: {node: '>=18.0.0'} + resolution: + { + integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==, + } + engines: { node: ">=18.0.0" } hasBin: true tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + resolution: + { + integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==, + } turndown@7.2.4: - resolution: {integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==} - engines: {node: '>=18', npm: '>=9'} + resolution: + { + integrity: sha512-I8yFsfRzmzK0WV1pNNOA4A7y4RDfFxPRxb3t+e3ui14qSGOxGtiSP6GjeX+Y6CHb7HYaFj7ECUD7VE5kQMZWGQ==, + } + engines: { node: ">=18", npm: ">=9" } type-fest@5.6.0: - resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} - engines: {node: '>=20'} + resolution: + { + integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==, + } + engines: { node: ">=20" } type-is@2.1.0: - resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==, + } + engines: { node: ">= 18" } typebox@1.1.38: - resolution: {integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==} + resolution: + { + integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==, + } typedoc-plugin-markdown@4.11.0: - resolution: {integrity: sha512-2iunh2ALyfyh204OF7h2u0kuQ84xB3jFZtFyUr01nThJkLvR8oGGSSDlyt2gyO4kXhvUxDcVbO0y43+qX+wFbw==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-2iunh2ALyfyh204OF7h2u0kuQ84xB3jFZtFyUr01nThJkLvR8oGGSSDlyt2gyO4kXhvUxDcVbO0y43+qX+wFbw==, + } + engines: { node: ">= 18" } peerDependencies: typedoc: 0.28.x typedoc@0.28.19: - resolution: {integrity: sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw==} - engines: {node: '>= 18', pnpm: '>= 10'} + resolution: + { + integrity: sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw==, + } + engines: { node: ">= 18", pnpm: ">= 10" } hasBin: true peerDependencies: typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x typesafe-path@0.2.2: - resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} + resolution: + { + integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==, + } typescript-auto-import-cache@0.3.6: - resolution: {integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==} + resolution: + { + integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==, + } typescript@5.9.3: - resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==, + } + engines: { node: ">=14.17" } hasBin: true typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} + resolution: + { + integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==, + } + engines: { node: ">=14.17" } hasBin: true uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + resolution: + { + integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==, + } ufo@1.6.4: - resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + resolution: + { + integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==, + } uid-promise@1.0.0: - resolution: {integrity: sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==} + resolution: + { + integrity: sha512-R8375j0qwXyIu/7R0tjdF06/sElHqbmdmWC9M2qQHpEVbvE4I5+38KJI7LUUmQMp7NVq4tKHiBMkT0NFM453Ig==, + } uint8array-extras@1.5.0: - resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==, + } + engines: { node: ">=18" } ultrahtml@1.6.0: - resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==} + resolution: + { + integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==, + } uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + resolution: + { + integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==, + } undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + resolution: + { + integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, + } undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - - undici-types@7.24.6: - resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + resolution: + { + integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==, + } undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} + resolution: + { + integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==, + } + engines: { node: ">=14.0" } undici@6.25.0: - resolution: {integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==} - engines: {node: '>=18.17'} + resolution: + { + integrity: sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==, + } + engines: { node: ">=18.17" } undici@7.25.0: - resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} - engines: {node: '>=20.18.1'} + resolution: + { + integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==, + } + engines: { node: ">=20.18.1" } unenv@2.0.0-rc.24: - resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + resolution: + { + integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==, + } unified@11.0.5: - resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + resolution: + { + integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==, + } unifont@0.7.4: - resolution: {integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==} + resolution: + { + integrity: sha512-oHeis4/xl42HUIeHuNZRGEvxj5AaIKR+bHPNegRq5LV1gdc3jundpONbjglKpihmJf+dswygdMJn3eftGIMemg==, + } unist-util-find-after@5.0.0: - resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + resolution: + { + integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==, + } unist-util-is@6.0.1: - resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + resolution: + { + integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==, + } unist-util-modify-children@4.0.0: - resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} + resolution: + { + integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==, + } unist-util-position-from-estree@2.0.0: - resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + resolution: + { + integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==, + } unist-util-position@5.0.0: - resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + resolution: + { + integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==, + } unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + resolution: + { + integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==, + } unist-util-stringify-position@4.0.0: - resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + resolution: + { + integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==, + } unist-util-visit-children@3.0.0: - resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} + resolution: + { + integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==, + } unist-util-visit-parents@6.0.2: - resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + resolution: + { + integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==, + } unist-util-visit@5.1.0: - resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + resolution: + { + integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==, + } universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + resolution: + { + integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, + } + engines: { node: ">= 10.0.0" } unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, + } + engines: { node: ">= 0.8" } unstorage@1.17.5: - resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} - 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 + resolution: + { + integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==, + } + 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' + db0: ">=0.2.1" idb-keyval: ^6.2.1 ioredis: ^5.4.2 uploadthing: ^7.4.4 peerDependenciesMeta: - '@azure/app-configuration': + "@azure/app-configuration": optional: true - '@azure/cosmos': + "@azure/cosmos": optional: true - '@azure/data-tables': + "@azure/data-tables": optional: true - '@azure/identity': + "@azure/identity": optional: true - '@azure/keyvault-secrets': + "@azure/keyvault-secrets": optional: true - '@azure/storage-blob': + "@azure/storage-blob": optional: true - '@capacitor/preferences': + "@capacitor/preferences": optional: true - '@deno/kv': + "@deno/kv": optional: true - '@netlify/blobs': + "@netlify/blobs": optional: true - '@planetscale/database': + "@planetscale/database": optional: true - '@upstash/redis': + "@upstash/redis": optional: true - '@vercel/blob': + "@vercel/blob": optional: true - '@vercel/functions': + "@vercel/functions": optional: true - '@vercel/kv': + "@vercel/kv": optional: true aws4fetch: optional: true @@ -7134,59 +11937,62 @@ packages: optional: true unstorage@2.0.0-alpha.7: - resolution: {integrity: sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==} - peerDependencies: - '@azure/app-configuration': ^1.11.0 - '@azure/cosmos': ^4.9.1 - '@azure/data-tables': ^13.3.2 - '@azure/identity': ^4.13.0 - '@azure/keyvault-secrets': ^4.10.0 - '@azure/storage-blob': ^12.31.0 - '@capacitor/preferences': ^6 || ^7 || ^8 - '@deno/kv': '>=0.13.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.36.2 - '@vercel/blob': '>=0.27.3' - '@vercel/functions': ^2.2.12 || ^3.0.0 - '@vercel/kv': ^1.0.1 + resolution: + { + integrity: sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==, + } + peerDependencies: + "@azure/app-configuration": ^1.11.0 + "@azure/cosmos": ^4.9.1 + "@azure/data-tables": ^13.3.2 + "@azure/identity": ^4.13.0 + "@azure/keyvault-secrets": ^4.10.0 + "@azure/storage-blob": ^12.31.0 + "@capacitor/preferences": ^6 || ^7 || ^8 + "@deno/kv": ">=0.13.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.36.2 + "@vercel/blob": ">=0.27.3" + "@vercel/functions": ^2.2.12 || ^3.0.0 + "@vercel/kv": ^1.0.1 aws4fetch: ^1.0.20 chokidar: ^4 || ^5 - db0: '>=0.3.4' + db0: ">=0.3.4" idb-keyval: ^6.2.2 ioredis: ^5.9.3 lru-cache: ^11.2.6 mongodb: ^6 || ^7 - ofetch: '*' + ofetch: "*" uploadthing: ^7.7.4 peerDependenciesMeta: - '@azure/app-configuration': + "@azure/app-configuration": optional: true - '@azure/cosmos': + "@azure/cosmos": optional: true - '@azure/data-tables': + "@azure/data-tables": optional: true - '@azure/identity': + "@azure/identity": optional: true - '@azure/keyvault-secrets': + "@azure/keyvault-secrets": optional: true - '@azure/storage-blob': + "@azure/storage-blob": optional: true - '@capacitor/preferences': + "@capacitor/preferences": optional: true - '@deno/kv': + "@deno/kv": optional: true - '@netlify/blobs': + "@netlify/blobs": optional: true - '@planetscale/database': + "@planetscale/database": optional: true - '@upstash/redis': + "@upstash/redis": optional: true - '@vercel/blob': + "@vercel/blob": optional: true - '@vercel/functions': + "@vercel/functions": optional: true - '@vercel/kv': + "@vercel/kv": optional: true aws4fetch: optional: true @@ -7208,58 +12014,91 @@ packages: optional: true until-async@3.0.2: - resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + resolution: + { + integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==, + } uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + resolution: + { + integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, + } use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + resolution: + { + integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==, + } peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + resolution: + { + integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, + } vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + resolution: + { + integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, + } + engines: { node: ">= 0.8" } vercel@54.4.0: - resolution: {integrity: sha512-9BBo/6XZYMIUe2UFcffUDSocyEf8d7iFRTF13f1RloWpTObJozOqpT3mzpZkNO24zRbGVi3ElanegMS+vkFzgQ==} - engines: {node: '>= 18'} + resolution: + { + integrity: sha512-9BBo/6XZYMIUe2UFcffUDSocyEf8d7iFRTF13f1RloWpTObJozOqpT3mzpZkNO24zRbGVi3ElanegMS+vkFzgQ==, + } + engines: { node: ">= 18" } hasBin: true vfile-location@5.0.3: - resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + resolution: + { + integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==, + } vfile-message@4.0.3: - resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + resolution: + { + integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==, + } vfile@6.0.3: - resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + resolution: + { + integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==, + } victory-vendor@37.3.6: - resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==} + resolution: + { + integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==, + } vite@7.3.3: - resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' + "@types/node": ^20.19.0 || >=22.12.0 + jiti: ">=1.21.0" less: ^4.0.0 lightningcss: ^1.21.0 sass: ^1.70.0 sass-embedded: ^1.70.0 - stylus: '>=0.54.8' + stylus: ">=0.54.8" sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.9.0 peerDependenciesMeta: - '@types/node': + "@types/node": optional: true jiti: optional: true @@ -7283,26 +12122,29 @@ packages: optional: true vite@8.0.14: - resolution: {integrity: sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==} - engines: {node: ^20.19.0 || >=22.12.0} + resolution: + { + integrity: sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==, + } + engines: { node: ^20.19.0 || >=22.12.0 } hasBin: true peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 + "@types/node": ^20.19.0 || >=22.12.0 + "@vitejs/devtools": ^0.1.18 esbuild: ^0.27.0 || ^0.28.0 - jiti: '>=1.21.0' + jiti: ">=1.21.0" less: ^4.0.0 sass: ^1.70.0 sass-embedded: ^1.70.0 - stylus: '>=0.54.8' + stylus: ">=0.54.8" sugarss: ^5.0.0 terser: ^5.16.0 tsx: ^4.8.1 yaml: ^2.9.0 peerDependenciesMeta: - '@types/node': + "@types/node": optional: true - '@vitejs/devtools': + "@vitejs/devtools": optional: true esbuild: optional: true @@ -7326,7 +12168,10 @@ packages: optional: true vitefu@1.1.3: - resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + resolution: + { + integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==, + } peerDependencies: vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: @@ -7334,13 +12179,16 @@ packages: optional: true vitest-evals@0.13.1: - resolution: {integrity: sha512-UCA3drMFVxtYB3F/0AjQEBSp7EPc2Du2Au85kLHtQg4V6p2mpifP4m5VEfwgxVXq8UfrnsMk8SJvOB/5EiDC0g==} + resolution: + { + integrity: sha512-UCA3drMFVxtYB3F/0AjQEBSp7EPc2Du2Au85kLHtQg4V6p2mpifP4m5VEfwgxVXq8UfrnsMk8SJvOB/5EiDC0g==, + } hasBin: true peerDependencies: ai: 6.0.190 - tinyrainbow: '>=2 <4' - vitest: '>=4 <5' - zod: '>=3 <5' + tinyrainbow: ">=2 <4" + vitest: ">=4 <5" + zod: ">=3 <5" peerDependenciesMeta: ai: optional: true @@ -7348,39 +12196,42 @@ packages: optional: true vitest@4.1.7: - resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + resolution: + { + integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==, + } + engines: { node: ^20.0.0 || ^22.0.0 || >=24.0.0 } hasBin: true peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.7 - '@vitest/browser-preview': 4.1.7 - '@vitest/browser-webdriverio': 4.1.7 - '@vitest/coverage-istanbul': 4.1.7 - '@vitest/coverage-v8': 4.1.7 - '@vitest/ui': 4.1.7 - happy-dom: '*' - jsdom: '*' + "@edge-runtime/vm": "*" + "@opentelemetry/api": ^1.9.0 + "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 4.1.7 + "@vitest/browser-preview": 4.1.7 + "@vitest/browser-webdriverio": 4.1.7 + "@vitest/coverage-istanbul": 4.1.7 + "@vitest/coverage-v8": 4.1.7 + "@vitest/ui": 4.1.7 + happy-dom: "*" + jsdom: "*" peerDependenciesMeta: - '@edge-runtime/vm': + "@edge-runtime/vm": optional: true - '@opentelemetry/api': + "@opentelemetry/api": optional: true - '@types/node': + "@types/node": optional: true - '@vitest/browser-playwright': + "@vitest/browser-playwright": optional: true - '@vitest/browser-preview': + "@vitest/browser-preview": optional: true - '@vitest/browser-webdriverio': + "@vitest/browser-webdriverio": optional: true - '@vitest/coverage-istanbul': + "@vitest/coverage-istanbul": optional: true - '@vitest/coverage-v8': + "@vitest/coverage-v8": optional: true - '@vitest/ui': + "@vitest/ui": optional: true happy-dom: optional: true @@ -7388,145 +12239,246 @@ packages: optional: true volar-service-css@0.0.70: - resolution: {integrity: sha512-K1qyOvBpE3rzdAv3e4/6Rv5yizrYPy5R/ne3IWCAzLBuMO4qBMV3kSqWzj6KUVe6S0AnN6wxF7cRkiaKfYMYJw==} + resolution: + { + integrity: sha512-K1qyOvBpE3rzdAv3e4/6Rv5yizrYPy5R/ne3IWCAzLBuMO4qBMV3kSqWzj6KUVe6S0AnN6wxF7cRkiaKfYMYJw==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true volar-service-emmet@0.0.70: - resolution: {integrity: sha512-xi5bC4m/VyE3zy/n2CXspKeDZs3qA41tHLTw275/7dNWM/RqE2z3BnDICQybHIVp/6G1iOQj5c1qXMgQC08TNg==} + resolution: + { + integrity: sha512-xi5bC4m/VyE3zy/n2CXspKeDZs3qA41tHLTw275/7dNWM/RqE2z3BnDICQybHIVp/6G1iOQj5c1qXMgQC08TNg==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true volar-service-html@0.0.70: - resolution: {integrity: sha512-eR6vCgMdmYAo4n+gcT7DSyBQbwB8S3HZZvSagTf0sxNaD4WppMCFfpqWnkrlGStPKMZvMiejRRVmqsX9dYcTvQ==} + resolution: + { + integrity: sha512-eR6vCgMdmYAo4n+gcT7DSyBQbwB8S3HZZvSagTf0sxNaD4WppMCFfpqWnkrlGStPKMZvMiejRRVmqsX9dYcTvQ==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true volar-service-prettier@0.0.70: - resolution: {integrity: sha512-Z6BCFSpGVCd8BPAsZ785Kce1BGlWd5ODqmqZGVuB14MJvrR4+CYz6cDy4F+igmE1gMifqfvMhdgT8Aud4M5ngg==} + resolution: + { + integrity: sha512-Z6BCFSpGVCd8BPAsZ785Kce1BGlWd5ODqmqZGVuB14MJvrR4+CYz6cDy4F+igmE1gMifqfvMhdgT8Aud4M5ngg==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 prettier: ^2.2 || ^3.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true prettier: optional: true volar-service-typescript-twoslash-queries@0.0.70: - resolution: {integrity: sha512-IdD13Z9N2Bu8EM6CM0fDV1E69olEYGHDU25X51YXmq8Y0CmJ2LNj6gOiBJgpS5JGUqFzECVhMNBW7R0sPdRTMQ==} + resolution: + { + integrity: sha512-IdD13Z9N2Bu8EM6CM0fDV1E69olEYGHDU25X51YXmq8Y0CmJ2LNj6gOiBJgpS5JGUqFzECVhMNBW7R0sPdRTMQ==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true volar-service-typescript@0.0.70: - resolution: {integrity: sha512-l46Bx4cokkUedTd74ojO5H/zqHZJ8SUuyZ0IB8JN4jfRqUM3bQFBHoOwlZCyZmOeO0A3RQNkMnFclxO4c++gsg==} + resolution: + { + integrity: sha512-l46Bx4cokkUedTd74ojO5H/zqHZJ8SUuyZ0IB8JN4jfRqUM3bQFBHoOwlZCyZmOeO0A3RQNkMnFclxO4c++gsg==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true volar-service-yaml@0.0.70: - resolution: {integrity: sha512-0c8bXDBeoATF9F6iPIlOuYTuZAC4c+yi0siQo920u7eiBJk8oQmUmg9cDUbR4+Gl++bvGP4plj3fErbJuPqdcQ==} + resolution: + { + integrity: sha512-0c8bXDBeoATF9F6iPIlOuYTuZAC4c+yi0siQo920u7eiBJk8oQmUmg9cDUbR4+Gl++bvGP4plj3fErbJuPqdcQ==, + } peerDependencies: - '@volar/language-service': ~2.4.0 + "@volar/language-service": ~2.4.0 peerDependenciesMeta: - '@volar/language-service': + "@volar/language-service": optional: true vscode-css-languageservice@6.3.10: - resolution: {integrity: sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==} + resolution: + { + integrity: sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==, + } vscode-html-languageservice@5.6.2: - resolution: {integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==} + resolution: + { + integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==, + } vscode-json-languageservice@4.1.8: - resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==} - engines: {npm: '>=7.0.0'} + resolution: + { + integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==, + } + engines: { npm: ">=7.0.0" } vscode-jsonrpc@8.2.0: - resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} - engines: {node: '>=14.0.0'} + resolution: + { + integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==, + } + engines: { node: ">=14.0.0" } vscode-languageserver-protocol@3.17.5: - resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + resolution: + { + integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==, + } vscode-languageserver-textdocument@1.0.12: - resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + resolution: + { + integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==, + } vscode-languageserver-types@3.17.5: - resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + resolution: + { + integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==, + } vscode-languageserver@9.0.1: - resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + resolution: + { + integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==, + } hasBin: true vscode-nls@5.2.0: - resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} + resolution: + { + integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==, + } vscode-uri@3.1.0: - resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + resolution: + { + integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==, + } watskeburt@5.0.3: - resolution: {integrity: sha512-g9CXukMjazlJJVQ3OHzXsnG25KFYgSgKMIyoJrD8ggr0DbS9UNF7OzIqWmmKKBMedkxj3T01uqEaGnn+y7QhMA==} - engines: {node: ^20.12||^22.13||>=24.0} + resolution: + { + integrity: sha512-g9CXukMjazlJJVQ3OHzXsnG25KFYgSgKMIyoJrD8ggr0DbS9UNF7OzIqWmmKKBMedkxj3T01uqEaGnn+y7QhMA==, + } + engines: { node: ^20.12||^22.13||>=24.0 } hasBin: true web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + resolution: + { + integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==, + } web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==, + } + engines: { node: ">= 8" } web-vitals@0.2.4: - resolution: {integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==} + resolution: + { + integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==, + } webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + resolution: + { + integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, + } whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + resolution: + { + integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, + } which-pm-runs@1.1.0: - resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} - engines: {node: '>=4'} + resolution: + { + integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==, + } + engines: { node: ">=4" } which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { + integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, + } + engines: { node: ">= 8" } hasBin: true why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} + resolution: + { + integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==, + } + engines: { node: ">=8" } hasBin: true + wrap-ansi@10.0.0: + resolution: + { + integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==, + } + engines: { node: ">=20" } + wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, + } + engines: { node: ">=10" } + + wrap-ansi@9.0.2: + resolution: + { + integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==, + } + engines: { node: ">=18" } wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + resolution: + { + integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, + } ws@8.20.1: - resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} - engines: {node: '>=10.0.0'} + resolution: + { + integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==, + } + engines: { node: ">=10.0.0" } peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' + utf-8-validate: ">=5.0.2" peerDependenciesMeta: bufferutil: optional: true @@ -7534,178 +12486,258 @@ packages: optional: true xdg-app-paths@5.1.0: - resolution: {integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-RAQ3WkPf4KTU1A8RtFx3gWywzVKe00tfOPFfl2NDGqbIFENQO4kqAJp7mhQjNj/33W5x5hiWWUdyfPq/5SU3QA==, + } + engines: { node: ">=6" } xdg-app-paths@5.5.1: - resolution: {integrity: sha512-hI3flOB4PLZIy5prbtTpirobtPE2ZtZ52szO+2mM9Efp6ErM398La+C1lIpNWDfNoQk+6Lsi6nMcCwVB7pxeMQ==} - engines: {node: '>= 6.0'} + resolution: + { + integrity: sha512-hI3flOB4PLZIy5prbtTpirobtPE2ZtZ52szO+2mM9Efp6ErM398La+C1lIpNWDfNoQk+6Lsi6nMcCwVB7pxeMQ==, + } + engines: { node: ">= 6.0" } xdg-portable@7.3.0: - resolution: {integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==} - engines: {node: '>= 6.0'} + resolution: + { + integrity: sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==, + } + engines: { node: ">= 6.0" } xml-naming@0.1.0: - resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} - engines: {node: '>=16.0.0'} + resolution: + { + integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==, + } + engines: { node: ">=16.0.0" } xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} + resolution: + { + integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==, + } + engines: { node: ">=0.4" } xxhash-wasm@1.1.0: - resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + resolution: + { + integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==, + } y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + resolution: + { + integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, + } + engines: { node: ">=10" } yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + resolution: + { + integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, + } yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} + resolution: + { + integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==, + } + engines: { node: ">=18" } yaml-language-server@1.20.0: - resolution: {integrity: sha512-qhjK/bzSRZ6HtTvgeFvjNPJGWdZ0+x5NREV/9XZWFjIGezew2b4r5JPy66IfOhd5OA7KeFwk1JfmEbnTvev0cA==} + resolution: + { + integrity: sha512-qhjK/bzSRZ6HtTvgeFvjNPJGWdZ0+x5NREV/9XZWFjIGezew2b4r5JPy66IfOhd5OA7KeFwk1JfmEbnTvev0cA==, + } hasBin: true yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} + resolution: + { + integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==, + } + engines: { node: ">= 14.6" } hasBin: true yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, + } + engines: { node: ">=12" } yargs-parser@22.0.0: - resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} - engines: {node: ^20.19.0 || ^22.12.0 || >=23} + resolution: + { + integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==, + } + engines: { node: ^20.19.0 || ^22.12.0 || >=23 } yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + resolution: + { + integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, + } + engines: { node: ">=12" } yauzl-clone@1.0.4: - resolution: {integrity: sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-igM2RRCf3k8TvZoxR2oguuw4z1xasOnA31joCqHIyLkeWrvAc2Jgay5ISQ2ZplinkoGaJ6orCz56Ey456c5ESA==, + } + engines: { node: ">=6" } yauzl-promise@2.1.3: - resolution: {integrity: sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==} - engines: {node: '>=6'} + resolution: + { + integrity: sha512-A1pf6fzh6eYkK0L4Qp7g9jzJSDrM6nN0bOn5T0IbY4Yo3w+YkWlHFkJP7mzknMXjqusHFHlKsK2N+4OLsK2MRA==, + } + engines: { node: ">=6" } yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + resolution: + { + integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==, + } yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} + resolution: + { + integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==, + } + engines: { node: ">=12.20" } zod-to-json-schema@3.25.2: - resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + resolution: + { + integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==, + } peerDependencies: zod: ^3.25.28 || ^4 zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + resolution: + { + integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==, + } zod@3.24.4: - resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} + resolution: + { + integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==, + } zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + resolution: + { + integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==, + } zod@4.1.11: - resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} + resolution: + { + integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==, + } zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + resolution: + { + integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==, + } zwitch@2.0.4: - resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + resolution: + { + integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==, + } snapshots: - - '@ai-sdk/gateway@3.0.119(zod@4.4.3)': + "@ai-sdk/gateway@3.0.119(zod@4.4.3)": dependencies: - '@ai-sdk/provider': 3.0.10 - '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) - '@vercel/oidc': 3.2.0 + "@ai-sdk/provider": 3.0.10 + "@ai-sdk/provider-utils": 4.0.27(zod@4.4.3) + "@vercel/oidc": 3.2.0 zod: 4.4.3 - '@ai-sdk/provider-utils@4.0.27(zod@4.4.3)': + "@ai-sdk/provider-utils@4.0.27(zod@4.4.3)": dependencies: - '@ai-sdk/provider': 3.0.10 - '@standard-schema/spec': 1.1.0 + "@ai-sdk/provider": 3.0.10 + "@standard-schema/spec": 1.1.0 eventsource-parser: 3.0.8 zod: 4.4.3 - '@ai-sdk/provider@3.0.10': + "@ai-sdk/provider@3.0.10": dependencies: json-schema: 0.4.0 - '@anthropic-ai/sdk@0.91.1(zod@4.4.3)': + "@anthropic-ai/sdk@0.91.1(zod@4.4.3)": dependencies: json-schema-to-ts: 3.1.1 optionalDependencies: zod: 4.4.3 - '@apm-js-collab/code-transformer-bundler-plugins@0.5.0': + "@apm-js-collab/code-transformer-bundler-plugins@0.5.0": dependencies: - '@apm-js-collab/code-transformer': 0.15.0 + "@apm-js-collab/code-transformer": 0.15.0 es-module-lexer: 2.1.0 magic-string: 0.30.21 module-details-from-path: 1.0.4 - '@apm-js-collab/code-transformer@0.15.0': + "@apm-js-collab/code-transformer@0.15.0": dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 astring: 1.9.0 esquery: 1.7.0 meriyah: 6.1.4 semifies: 1.0.0 source-map: 0.6.1 - '@apm-js-collab/tracing-hooks@0.10.0': + "@apm-js-collab/tracing-hooks@0.10.0": dependencies: - '@apm-js-collab/code-transformer': 0.15.0 + "@apm-js-collab/code-transformer": 0.15.0 debug: 4.4.3 module-details-from-path: 1.0.4 transitivePeerDependencies: - supports-color - '@ast-grep/cli-darwin-x64@0.43.0': + "@ast-grep/cli-darwin-arm64@0.43.0": + optional: true + + "@ast-grep/cli-darwin-x64@0.43.0": optional: true - '@ast-grep/cli-linux-arm64-gnu@0.43.0': + "@ast-grep/cli-linux-arm64-gnu@0.43.0": optional: true - '@ast-grep/cli-linux-x64-gnu@0.43.0': + "@ast-grep/cli-linux-x64-gnu@0.43.0": optional: true - '@ast-grep/cli-win32-arm64-msvc@0.43.0': + "@ast-grep/cli-win32-arm64-msvc@0.43.0": optional: true - '@ast-grep/cli-win32-ia32-msvc@0.43.0': + "@ast-grep/cli-win32-ia32-msvc@0.43.0": optional: true - '@ast-grep/cli-win32-x64-msvc@0.43.0': + "@ast-grep/cli-win32-x64-msvc@0.43.0": optional: true - '@ast-grep/cli@0.43.0': + "@ast-grep/cli@0.43.0": + dependencies: + detect-libc: 2.1.2 optionalDependencies: - '@ast-grep/cli-darwin-x64': 0.43.0 - '@ast-grep/cli-linux-arm64-gnu': 0.43.0 - '@ast-grep/cli-linux-x64-gnu': 0.43.0 - '@ast-grep/cli-win32-arm64-msvc': 0.43.0 - '@ast-grep/cli-win32-ia32-msvc': 0.43.0 - '@ast-grep/cli-win32-x64-msvc': 0.43.0 + "@ast-grep/cli-darwin-arm64": 0.43.0 + "@ast-grep/cli-darwin-x64": 0.43.0 + "@ast-grep/cli-linux-arm64-gnu": 0.43.0 + "@ast-grep/cli-linux-x64-gnu": 0.43.0 + "@ast-grep/cli-win32-arm64-msvc": 0.43.0 + "@ast-grep/cli-win32-ia32-msvc": 0.43.0 + "@ast-grep/cli-win32-x64-msvc": 0.43.0 - '@astrojs/check@0.9.9(prettier@3.8.3)(typescript@6.0.3)': + "@astrojs/check@0.9.9(prettier@3.8.3)(typescript@6.0.3)": dependencies: - '@astrojs/language-server': 2.16.9(prettier@3.8.3)(typescript@6.0.3) + "@astrojs/language-server": 2.16.9(prettier@3.8.3)(typescript@6.0.3) chokidar: 4.0.3 kleur: 4.1.5 typescript: 6.0.3 @@ -7714,23 +12746,23 @@ snapshots: - prettier - prettier-plugin-astro - '@astrojs/compiler@2.13.1': {} + "@astrojs/compiler@2.13.1": {} - '@astrojs/compiler@4.0.0': {} + "@astrojs/compiler@4.0.0": {} - '@astrojs/internal-helpers@0.9.1': + "@astrojs/internal-helpers@0.9.1": dependencies: picomatch: 4.0.4 - '@astrojs/language-server@2.16.9(prettier@3.8.3)(typescript@6.0.3)': + "@astrojs/language-server@2.16.9(prettier@3.8.3)(typescript@6.0.3)": dependencies: - '@astrojs/compiler': 2.13.1 - '@astrojs/yaml2ts': 0.2.4 - '@jridgewell/sourcemap-codec': 1.5.5 - '@volar/kit': 2.4.28(typescript@6.0.3) - '@volar/language-core': 2.4.28 - '@volar/language-server': 2.4.28 - '@volar/language-service': 2.4.28 + "@astrojs/compiler": 2.13.1 + "@astrojs/yaml2ts": 0.2.4 + "@jridgewell/sourcemap-codec": 1.5.5 + "@volar/kit": 2.4.28(typescript@6.0.3) + "@volar/language-core": 2.4.28 + "@volar/language-server": 2.4.28 + "@volar/language-service": 2.4.28 muggle-string: 0.4.1 tinyglobby: 0.2.16 volar-service-css: 0.0.70(@volar/language-service@2.4.28) @@ -7747,10 +12779,10 @@ snapshots: transitivePeerDependencies: - typescript - '@astrojs/markdown-remark@7.1.2': + "@astrojs/markdown-remark@7.1.2": dependencies: - '@astrojs/internal-helpers': 0.9.1 - '@astrojs/prism': 4.0.2 + "@astrojs/internal-helpers": 0.9.1 + "@astrojs/prism": 4.0.2 github-slugger: 2.0.0 hast-util-from-html: 2.0.3 hast-util-to-text: 4.0.2 @@ -7773,10 +12805,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@5.0.6(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))': + "@astrojs/mdx@5.0.6(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))": dependencies: - '@astrojs/markdown-remark': 7.1.2 - '@mdx-js/mdx': 3.1.1 + "@astrojs/markdown-remark": 7.1.2 + "@mdx-js/mdx": 3.1.1 acorn: 8.16.0 astro: 6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0) es-module-lexer: 2.1.0 @@ -7792,25 +12824,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/prism@4.0.2': + "@astrojs/prism@4.0.2": dependencies: prismjs: 1.30.0 - '@astrojs/sitemap@3.7.2': + "@astrojs/sitemap@3.7.2": dependencies: sitemap: 9.0.1 stream-replace-string: 2.0.0 zod: 4.4.3 - '@astrojs/starlight@0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3)': + "@astrojs/starlight@0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3)": dependencies: - '@astrojs/markdown-remark': 7.1.2 - '@astrojs/mdx': 5.0.6(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0)) - '@astrojs/sitemap': 3.7.2 - '@pagefind/default-ui': 1.5.2 - '@types/hast': 3.0.4 - '@types/js-yaml': 4.0.9 - '@types/mdast': 4.0.4 + "@astrojs/markdown-remark": 7.1.2 + "@astrojs/mdx": 5.0.6(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0)) + "@astrojs/sitemap": 3.7.2 + "@pagefind/default-ui": 1.5.2 + "@types/hast": 3.0.4 + "@types/js-yaml": 4.0.9 + "@types/mdast": 4.0.4 astro: 6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0) astro-expressive-code: 0.42.0(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0)) bcp-47: 2.1.0 @@ -7837,7 +12869,7 @@ snapshots: - supports-color - typescript - '@astrojs/telemetry@3.3.2': + "@astrojs/telemetry@3.3.2": dependencies: ci-info: 4.4.0 dset: 3.1.4 @@ -7845,312 +12877,312 @@ snapshots: is-wsl: 3.1.1 which-pm-runs: 1.1.0 - '@astrojs/yaml2ts@0.2.4': + "@astrojs/yaml2ts@0.2.4": dependencies: yaml: 2.9.0 - '@aws-crypto/crc32@5.2.0': + "@aws-crypto/crc32@5.2.0": dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.9 + "@aws-crypto/util": 5.2.0 + "@aws-sdk/types": 3.973.9 tslib: 2.8.1 - '@aws-crypto/sha256-browser@5.2.0': + "@aws-crypto/sha256-browser@5.2.0": dependencies: - '@aws-crypto/sha256-js': 5.2.0 - '@aws-crypto/supports-web-crypto': 5.2.0 - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.9 - '@aws-sdk/util-locate-window': 3.965.5 - '@smithy/util-utf8': 2.3.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-crypto/supports-web-crypto": 5.2.0 + "@aws-crypto/util": 5.2.0 + "@aws-sdk/types": 3.973.9 + "@aws-sdk/util-locate-window": 3.965.5 + "@smithy/util-utf8": 2.3.0 tslib: 2.8.1 - '@aws-crypto/sha256-js@5.2.0': + "@aws-crypto/sha256-js@5.2.0": dependencies: - '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.9 + "@aws-crypto/util": 5.2.0 + "@aws-sdk/types": 3.973.9 tslib: 2.8.1 - '@aws-crypto/supports-web-crypto@5.2.0': + "@aws-crypto/supports-web-crypto@5.2.0": dependencies: tslib: 2.8.1 - '@aws-crypto/util@5.2.0': + "@aws-crypto/util@5.2.0": dependencies: - '@aws-sdk/types': 3.973.9 - '@smithy/util-utf8': 2.3.0 + "@aws-sdk/types": 3.973.9 + "@smithy/util-utf8": 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-bedrock-runtime@3.1048.0': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.13 - '@aws-sdk/credential-provider-node': 3.972.44 - '@aws-sdk/eventstream-handler-node': 3.972.17 - '@aws-sdk/middleware-eventstream': 3.972.13 - '@aws-sdk/middleware-websocket': 3.972.21 - '@aws-sdk/token-providers': 3.1048.0 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/fetch-http-handler': 5.4.4 - '@smithy/node-http-handler': 4.7.4 - '@smithy/types': 4.14.2 + "@aws-sdk/client-bedrock-runtime@3.1048.0": + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/credential-provider-node": 3.972.44 + "@aws-sdk/eventstream-handler-node": 3.972.17 + "@aws-sdk/middleware-eventstream": 3.972.13 + "@aws-sdk/middleware-websocket": 3.972.21 + "@aws-sdk/token-providers": 3.1048.0 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/fetch-http-handler": 5.4.4 + "@smithy/node-http-handler": 4.7.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/core@3.974.13': + "@aws-sdk/core@3.974.13": dependencies: - '@aws-sdk/types': 3.973.9 - '@aws-sdk/xml-builder': 3.972.25 - '@aws/lambda-invoke-store': 0.2.4 - '@smithy/core': 3.24.4 - '@smithy/signature-v4': 5.4.4 - '@smithy/types': 4.14.2 + "@aws-sdk/types": 3.973.9 + "@aws-sdk/xml-builder": 3.972.25 + "@aws/lambda-invoke-store": 0.2.4 + "@smithy/core": 3.24.4 + "@smithy/signature-v4": 5.4.4 + "@smithy/types": 4.14.2 bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.39': + "@aws-sdk/credential-provider-env@3.972.39": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.41': + "@aws-sdk/credential-provider-http@3.972.41": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/fetch-http-handler': 5.4.4 - '@smithy/node-http-handler': 4.7.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/fetch-http-handler": 5.4.4 + "@smithy/node-http-handler": 4.7.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.43': - dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/credential-provider-env': 3.972.39 - '@aws-sdk/credential-provider-http': 3.972.41 - '@aws-sdk/credential-provider-login': 3.972.43 - '@aws-sdk/credential-provider-process': 3.972.39 - '@aws-sdk/credential-provider-sso': 3.972.43 - '@aws-sdk/credential-provider-web-identity': 3.972.43 - '@aws-sdk/nested-clients': 3.997.11 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/credential-provider-imds': 4.3.4 - '@smithy/types': 4.14.2 + "@aws-sdk/credential-provider-ini@3.972.43": + dependencies: + "@aws-sdk/core": 3.974.13 + "@aws-sdk/credential-provider-env": 3.972.39 + "@aws-sdk/credential-provider-http": 3.972.41 + "@aws-sdk/credential-provider-login": 3.972.43 + "@aws-sdk/credential-provider-process": 3.972.39 + "@aws-sdk/credential-provider-sso": 3.972.43 + "@aws-sdk/credential-provider-web-identity": 3.972.43 + "@aws-sdk/nested-clients": 3.997.11 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/credential-provider-imds": 4.3.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-login@3.972.43': + "@aws-sdk/credential-provider-login@3.972.43": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/nested-clients': 3.997.11 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/nested-clients": 3.997.11 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-node@3.972.44': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.39 - '@aws-sdk/credential-provider-http': 3.972.41 - '@aws-sdk/credential-provider-ini': 3.972.43 - '@aws-sdk/credential-provider-process': 3.972.39 - '@aws-sdk/credential-provider-sso': 3.972.43 - '@aws-sdk/credential-provider-web-identity': 3.972.43 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/credential-provider-imds': 4.3.4 - '@smithy/types': 4.14.2 + "@aws-sdk/credential-provider-node@3.972.44": + dependencies: + "@aws-sdk/credential-provider-env": 3.972.39 + "@aws-sdk/credential-provider-http": 3.972.41 + "@aws-sdk/credential-provider-ini": 3.972.43 + "@aws-sdk/credential-provider-process": 3.972.39 + "@aws-sdk/credential-provider-sso": 3.972.43 + "@aws-sdk/credential-provider-web-identity": 3.972.43 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/credential-provider-imds": 4.3.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-process@3.972.39': + "@aws-sdk/credential-provider-process@3.972.39": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.43': + "@aws-sdk/credential-provider-sso@3.972.43": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/nested-clients': 3.997.11 - '@aws-sdk/token-providers': 3.1052.0 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/nested-clients": 3.997.11 + "@aws-sdk/token-providers": 3.1052.0 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-web-identity@3.972.43': + "@aws-sdk/credential-provider-web-identity@3.972.43": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/nested-clients': 3.997.11 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/nested-clients": 3.997.11 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/eventstream-handler-node@3.972.17': + "@aws-sdk/eventstream-handler-node@3.972.17": dependencies: - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-eventstream@3.972.13': + "@aws-sdk/middleware-eventstream@3.972.13": dependencies: - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-websocket@3.972.21': + "@aws-sdk/middleware-websocket@3.972.21": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/fetch-http-handler': 5.4.4 - '@smithy/signature-v4': 5.4.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/fetch-http-handler": 5.4.4 + "@smithy/signature-v4": 5.4.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.11': - dependencies: - '@aws-crypto/sha256-browser': 5.2.0 - '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.13 - '@aws-sdk/signature-v4-multi-region': 3.996.28 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/fetch-http-handler': 5.4.4 - '@smithy/node-http-handler': 4.7.4 - '@smithy/types': 4.14.2 + "@aws-sdk/nested-clients@3.997.11": + dependencies: + "@aws-crypto/sha256-browser": 5.2.0 + "@aws-crypto/sha256-js": 5.2.0 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/signature-v4-multi-region": 3.996.28 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/fetch-http-handler": 5.4.4 + "@smithy/node-http-handler": 4.7.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.28': + "@aws-sdk/signature-v4-multi-region@3.996.28": dependencies: - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/signature-v4': 5.4.4 - '@smithy/types': 4.14.2 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/signature-v4": 5.4.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1048.0': + "@aws-sdk/token-providers@3.1048.0": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/nested-clients': 3.997.11 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/nested-clients": 3.997.11 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1052.0': + "@aws-sdk/token-providers@3.1052.0": dependencies: - '@aws-sdk/core': 3.974.13 - '@aws-sdk/nested-clients': 3.997.11 - '@aws-sdk/types': 3.973.9 - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@aws-sdk/core": 3.974.13 + "@aws-sdk/nested-clients": 3.997.11 + "@aws-sdk/types": 3.973.9 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/types@3.973.9': + "@aws-sdk/types@3.973.9": dependencies: - '@smithy/types': 4.14.2 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@aws-sdk/util-locate-window@3.965.5': + "@aws-sdk/util-locate-window@3.965.5": dependencies: tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.25': + "@aws-sdk/xml-builder@3.972.25": dependencies: - '@nodable/entities': 2.1.0 - '@smithy/types': 4.14.2 + "@nodable/entities": 2.1.0 + "@smithy/types": 4.14.2 fast-xml-parser: 5.7.3 tslib: 2.8.1 - '@aws/lambda-invoke-store@0.2.4': {} + "@aws/lambda-invoke-store@0.2.4": {} - '@babel/helper-string-parser@7.27.1': {} + "@babel/helper-string-parser@7.27.1": {} - '@babel/helper-validator-identifier@7.28.5': {} + "@babel/helper-validator-identifier@7.28.5": {} - '@babel/parser@7.29.3': + "@babel/parser@7.29.3": dependencies: - '@babel/types': 7.29.0 + "@babel/types": 7.29.0 - '@babel/runtime@7.29.2': {} + "@babel/runtime@7.29.2": {} - '@babel/types@7.29.0': + "@babel/types@7.29.0": dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + "@babel/helper-string-parser": 7.27.1 + "@babel/helper-validator-identifier": 7.28.5 - '@bcoe/v8-coverage@1.0.2': {} + "@bcoe/v8-coverage@1.0.2": {} - '@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)': + "@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0)": dependencies: - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 - '@opentelemetry/semantic-conventions': 1.41.1 - '@standard-schema/spec': 1.1.0 + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 + "@opentelemetry/semantic-conventions": 1.41.1 + "@standard-schema/spec": 1.1.0 better-call: 1.3.5(zod@4.4.3) jose: 6.2.3 kysely: 0.28.17 nanostores: 1.3.0 zod: 4.4.3 - '@better-auth/drizzle-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + "@better-auth/drizzle-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)": dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/utils': 0.4.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/utils": 0.4.0 - '@better-auth/kysely-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17)': + "@better-auth/kysely-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17)": dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/utils': 0.4.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/utils": 0.4.0 optionalDependencies: kysely: 0.28.17 - '@better-auth/memory-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + "@better-auth/memory-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)": dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/utils': 0.4.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/utils": 0.4.0 - '@better-auth/mongo-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + "@better-auth/mongo-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)": dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/utils': 0.4.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/utils": 0.4.0 - '@better-auth/prisma-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)': + "@better-auth/prisma-adapter@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)": dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/utils': 0.4.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/utils": 0.4.0 - '@better-auth/telemetry@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)': + "@better-auth/telemetry@1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)": dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 - '@better-auth/utils@0.4.0': + "@better-auth/utils@0.4.0": dependencies: - '@noble/hashes': 2.2.0 + "@noble/hashes": 2.2.0 - '@better-fetch/fetch@1.1.21': {} + "@better-fetch/fetch@1.1.21": {} - '@borewit/text-codec@0.2.2': {} + "@borewit/text-codec@0.2.2": {} - '@bytecodealliance/preview2-shim@0.17.6': {} + "@bytecodealliance/preview2-shim@0.17.6": {} - '@capsizecss/unpack@4.0.0': + "@capsizecss/unpack@4.0.0": dependencies: fontkitten: 1.0.3 - '@chat-adapter/shared@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)': + "@chat-adapter/shared@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)": dependencies: chat: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) transitivePeerDependencies: @@ -8158,11 +13190,11 @@ snapshots: - supports-color - zod - '@chat-adapter/slack@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)': + "@chat-adapter/slack@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)": dependencies: - '@chat-adapter/shared': 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@slack/socket-mode': 2.0.7 - '@slack/web-api': 7.16.0 + "@chat-adapter/shared": 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) + "@slack/socket-mode": 2.0.7 + "@slack/web-api": 7.16.0 chat: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) transitivePeerDependencies: - ai @@ -8172,7 +13204,7 @@ snapshots: - utf-8-validate - zod - '@chat-adapter/state-memory@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)': + "@chat-adapter/state-memory@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)": dependencies: chat: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) transitivePeerDependencies: @@ -8180,429 +13212,507 @@ snapshots: - supports-color - zod - '@chat-adapter/state-redis@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)': + "@chat-adapter/state-redis@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3)": dependencies: chat: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) redis: 5.12.1 transitivePeerDependencies: - - '@node-rs/xxhash' - - '@opentelemetry/api' + - "@node-rs/xxhash" + - "@opentelemetry/api" - ai - supports-color - zod - '@clack/core@1.3.1': + "@clack/core@1.3.1": dependencies: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@clack/prompts@1.4.0': + "@clack/prompts@1.4.0": dependencies: - '@clack/core': 1.3.1 + "@clack/core": 1.3.1 fast-string-width: 3.0.2 fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@ctrl/tinycolor@4.2.0': {} + "@ctrl/tinycolor@4.2.0": {} - '@drizzle-team/brocli@0.10.2': {} + "@drizzle-team/brocli@0.10.2": {} - '@earendil-works/pi-agent-core@0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)': + "@earendil-works/pi-agent-core@0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)": dependencies: - '@earendil-works/pi-ai': 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) + "@earendil-works/pi-ai": 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) ignore: 7.0.5 typebox: 1.1.38 yaml: 2.9.0 transitivePeerDependencies: - - '@modelcontextprotocol/sdk' + - "@modelcontextprotocol/sdk" - bufferutil - supports-color - utf-8-validate - ws - zod - '@earendil-works/pi-ai@0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)': + "@earendil-works/pi-ai@0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)": dependencies: - '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) - '@aws-sdk/client-bedrock-runtime': 3.1048.0 - '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) - '@mistralai/mistralai': 2.2.1 + "@anthropic-ai/sdk": 0.91.1(zod@4.4.3) + "@aws-sdk/client-bedrock-runtime": 3.1048.0 + "@google/genai": 1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + "@mistralai/mistralai": 2.2.1 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 openai: 6.26.0(zod@4.4.3) partial-json: 0.1.7 typebox: 1.1.38 transitivePeerDependencies: - - '@modelcontextprotocol/sdk' + - "@modelcontextprotocol/sdk" - bufferutil - supports-color - utf-8-validate - ws - zod - '@edge-runtime/format@2.2.1': {} + "@edge-runtime/format@2.2.1": {} - '@edge-runtime/node-utils@2.3.0': {} + "@edge-runtime/node-utils@2.3.0": {} - '@edge-runtime/ponyfill@2.4.2': {} + "@edge-runtime/ponyfill@2.4.2": {} - '@edge-runtime/primitives@4.1.0': {} + "@edge-runtime/primitives@4.1.0": {} - '@edge-runtime/vm@3.2.0': + "@edge-runtime/vm@3.2.0": dependencies: - '@edge-runtime/primitives': 4.1.0 + "@edge-runtime/primitives": 4.1.0 - '@electric-sql/pglite@0.4.6': {} + "@electric-sql/pglite@0.4.6": {} - '@emmetio/abbreviation@2.3.3': + "@emmetio/abbreviation@2.3.3": dependencies: - '@emmetio/scanner': 1.0.4 + "@emmetio/scanner": 1.0.4 - '@emmetio/css-abbreviation@2.1.8': + "@emmetio/css-abbreviation@2.1.8": dependencies: - '@emmetio/scanner': 1.0.4 + "@emmetio/scanner": 1.0.4 - '@emmetio/css-parser@0.4.1': + "@emmetio/css-parser@0.4.1": dependencies: - '@emmetio/stream-reader': 2.2.0 - '@emmetio/stream-reader-utils': 0.1.0 + "@emmetio/stream-reader": 2.2.0 + "@emmetio/stream-reader-utils": 0.1.0 - '@emmetio/html-matcher@1.3.0': + "@emmetio/html-matcher@1.3.0": dependencies: - '@emmetio/scanner': 1.0.4 + "@emmetio/scanner": 1.0.4 - '@emmetio/scanner@1.0.4': {} + "@emmetio/scanner@1.0.4": {} - '@emmetio/stream-reader-utils@0.1.0': {} + "@emmetio/stream-reader-utils@0.1.0": {} - '@emmetio/stream-reader@2.2.0': {} + "@emmetio/stream-reader@2.2.0": {} - '@emnapi/core@1.10.0': + "@emnapi/core@1.10.0": dependencies: - '@emnapi/wasi-threads': 1.2.1 + "@emnapi/wasi-threads": 1.2.1 tslib: 2.8.1 - '@emnapi/runtime@1.10.0': + "@emnapi/runtime@1.10.0": dependencies: tslib: 2.8.1 - '@emnapi/wasi-threads@1.2.1': + "@emnapi/wasi-threads@1.2.1": dependencies: tslib: 2.8.1 - '@esbuild-kit/core-utils@3.3.2': + "@esbuild-kit/core-utils@3.3.2": dependencies: esbuild: 0.18.20 source-map-support: 0.5.21 - '@esbuild-kit/esm-loader@2.6.5': + "@esbuild-kit/esm-loader@2.6.5": dependencies: - '@esbuild-kit/core-utils': 3.3.2 + "@esbuild-kit/core-utils": 3.3.2 get-tsconfig: 4.14.0 - '@esbuild/aix-ppc64@0.25.12': + "@esbuild/aix-ppc64@0.25.12": + optional: true + + "@esbuild/aix-ppc64@0.27.0": + optional: true + + "@esbuild/aix-ppc64@0.27.7": + optional: true + + "@esbuild/aix-ppc64@0.28.1": + optional: true + + "@esbuild/android-arm64@0.18.20": + optional: true + + "@esbuild/android-arm64@0.25.12": + optional: true + + "@esbuild/android-arm64@0.27.0": + optional: true + + "@esbuild/android-arm64@0.27.7": + optional: true + + "@esbuild/android-arm64@0.28.1": + optional: true + + "@esbuild/android-arm@0.18.20": + optional: true + + "@esbuild/android-arm@0.25.12": + optional: true + + "@esbuild/android-arm@0.27.0": + optional: true + + "@esbuild/android-arm@0.27.7": + optional: true + + "@esbuild/android-arm@0.28.1": + optional: true + + "@esbuild/android-x64@0.18.20": + optional: true + + "@esbuild/android-x64@0.25.12": + optional: true + + "@esbuild/android-x64@0.27.0": + optional: true + + "@esbuild/android-x64@0.27.7": + optional: true + + "@esbuild/android-x64@0.28.1": + optional: true + + "@esbuild/darwin-arm64@0.18.20": + optional: true + + "@esbuild/darwin-arm64@0.25.12": + optional: true + + "@esbuild/darwin-arm64@0.27.0": + optional: true + + "@esbuild/darwin-arm64@0.27.7": + optional: true + + "@esbuild/darwin-arm64@0.28.1": + optional: true + + "@esbuild/darwin-x64@0.18.20": + optional: true + + "@esbuild/darwin-x64@0.25.12": + optional: true + + "@esbuild/darwin-x64@0.27.0": optional: true - '@esbuild/aix-ppc64@0.27.0': + "@esbuild/darwin-x64@0.27.7": optional: true - '@esbuild/aix-ppc64@0.27.7': + "@esbuild/darwin-x64@0.28.1": optional: true - '@esbuild/android-arm64@0.18.20': + "@esbuild/freebsd-arm64@0.18.20": optional: true - '@esbuild/android-arm64@0.25.12': + "@esbuild/freebsd-arm64@0.25.12": optional: true - '@esbuild/android-arm64@0.27.0': + "@esbuild/freebsd-arm64@0.27.0": optional: true - '@esbuild/android-arm64@0.27.7': + "@esbuild/freebsd-arm64@0.27.7": optional: true - '@esbuild/android-arm@0.18.20': + "@esbuild/freebsd-arm64@0.28.1": optional: true - '@esbuild/android-arm@0.25.12': + "@esbuild/freebsd-x64@0.18.20": optional: true - '@esbuild/android-arm@0.27.0': + "@esbuild/freebsd-x64@0.25.12": optional: true - '@esbuild/android-arm@0.27.7': + "@esbuild/freebsd-x64@0.27.0": optional: true - '@esbuild/android-x64@0.18.20': + "@esbuild/freebsd-x64@0.27.7": optional: true - '@esbuild/android-x64@0.25.12': + "@esbuild/freebsd-x64@0.28.1": optional: true - '@esbuild/android-x64@0.27.0': + "@esbuild/linux-arm64@0.18.20": optional: true - '@esbuild/android-x64@0.27.7': + "@esbuild/linux-arm64@0.25.12": optional: true - '@esbuild/darwin-arm64@0.18.20': + "@esbuild/linux-arm64@0.27.0": optional: true - '@esbuild/darwin-arm64@0.25.12': + "@esbuild/linux-arm64@0.27.7": optional: true - '@esbuild/darwin-arm64@0.27.0': + "@esbuild/linux-arm64@0.28.1": optional: true - '@esbuild/darwin-arm64@0.27.7': + "@esbuild/linux-arm@0.18.20": optional: true - '@esbuild/darwin-x64@0.18.20': + "@esbuild/linux-arm@0.25.12": optional: true - '@esbuild/darwin-x64@0.25.12': + "@esbuild/linux-arm@0.27.0": optional: true - '@esbuild/darwin-x64@0.27.0': + "@esbuild/linux-arm@0.27.7": optional: true - '@esbuild/darwin-x64@0.27.7': + "@esbuild/linux-arm@0.28.1": optional: true - '@esbuild/freebsd-arm64@0.18.20': + "@esbuild/linux-ia32@0.18.20": optional: true - '@esbuild/freebsd-arm64@0.25.12': + "@esbuild/linux-ia32@0.25.12": optional: true - '@esbuild/freebsd-arm64@0.27.0': + "@esbuild/linux-ia32@0.27.0": optional: true - '@esbuild/freebsd-arm64@0.27.7': + "@esbuild/linux-ia32@0.27.7": optional: true - '@esbuild/freebsd-x64@0.18.20': + "@esbuild/linux-ia32@0.28.1": optional: true - '@esbuild/freebsd-x64@0.25.12': + "@esbuild/linux-loong64@0.18.20": optional: true - '@esbuild/freebsd-x64@0.27.0': + "@esbuild/linux-loong64@0.25.12": optional: true - '@esbuild/freebsd-x64@0.27.7': + "@esbuild/linux-loong64@0.27.0": optional: true - '@esbuild/linux-arm64@0.18.20': + "@esbuild/linux-loong64@0.27.7": optional: true - '@esbuild/linux-arm64@0.25.12': + "@esbuild/linux-loong64@0.28.1": optional: true - '@esbuild/linux-arm64@0.27.0': + "@esbuild/linux-mips64el@0.18.20": optional: true - '@esbuild/linux-arm64@0.27.7': + "@esbuild/linux-mips64el@0.25.12": optional: true - '@esbuild/linux-arm@0.18.20': + "@esbuild/linux-mips64el@0.27.0": optional: true - '@esbuild/linux-arm@0.25.12': + "@esbuild/linux-mips64el@0.27.7": optional: true - '@esbuild/linux-arm@0.27.0': + "@esbuild/linux-mips64el@0.28.1": optional: true - '@esbuild/linux-arm@0.27.7': + "@esbuild/linux-ppc64@0.18.20": optional: true - '@esbuild/linux-ia32@0.18.20': + "@esbuild/linux-ppc64@0.25.12": optional: true - '@esbuild/linux-ia32@0.25.12': + "@esbuild/linux-ppc64@0.27.0": optional: true - '@esbuild/linux-ia32@0.27.0': + "@esbuild/linux-ppc64@0.27.7": optional: true - '@esbuild/linux-ia32@0.27.7': + "@esbuild/linux-ppc64@0.28.1": optional: true - '@esbuild/linux-loong64@0.18.20': + "@esbuild/linux-riscv64@0.18.20": optional: true - '@esbuild/linux-loong64@0.25.12': + "@esbuild/linux-riscv64@0.25.12": optional: true - '@esbuild/linux-loong64@0.27.0': + "@esbuild/linux-riscv64@0.27.0": optional: true - '@esbuild/linux-loong64@0.27.7': + "@esbuild/linux-riscv64@0.27.7": optional: true - '@esbuild/linux-mips64el@0.18.20': + "@esbuild/linux-riscv64@0.28.1": optional: true - '@esbuild/linux-mips64el@0.25.12': + "@esbuild/linux-s390x@0.18.20": optional: true - '@esbuild/linux-mips64el@0.27.0': + "@esbuild/linux-s390x@0.25.12": optional: true - '@esbuild/linux-mips64el@0.27.7': + "@esbuild/linux-s390x@0.27.0": optional: true - '@esbuild/linux-ppc64@0.18.20': + "@esbuild/linux-s390x@0.27.7": optional: true - '@esbuild/linux-ppc64@0.25.12': + "@esbuild/linux-s390x@0.28.1": optional: true - '@esbuild/linux-ppc64@0.27.0': + "@esbuild/linux-x64@0.18.20": optional: true - '@esbuild/linux-ppc64@0.27.7': + "@esbuild/linux-x64@0.25.12": optional: true - '@esbuild/linux-riscv64@0.18.20': + "@esbuild/linux-x64@0.27.0": optional: true - '@esbuild/linux-riscv64@0.25.12': + "@esbuild/linux-x64@0.27.7": optional: true - '@esbuild/linux-riscv64@0.27.0': + "@esbuild/linux-x64@0.28.1": optional: true - '@esbuild/linux-riscv64@0.27.7': + "@esbuild/netbsd-arm64@0.25.12": optional: true - '@esbuild/linux-s390x@0.18.20': + "@esbuild/netbsd-arm64@0.27.0": optional: true - '@esbuild/linux-s390x@0.25.12': + "@esbuild/netbsd-arm64@0.27.7": optional: true - '@esbuild/linux-s390x@0.27.0': + "@esbuild/netbsd-arm64@0.28.1": optional: true - '@esbuild/linux-s390x@0.27.7': + "@esbuild/netbsd-x64@0.18.20": optional: true - '@esbuild/linux-x64@0.18.20': + "@esbuild/netbsd-x64@0.25.12": optional: true - '@esbuild/linux-x64@0.25.12': + "@esbuild/netbsd-x64@0.27.0": optional: true - '@esbuild/linux-x64@0.27.0': + "@esbuild/netbsd-x64@0.27.7": optional: true - '@esbuild/linux-x64@0.27.7': + "@esbuild/netbsd-x64@0.28.1": optional: true - '@esbuild/netbsd-arm64@0.25.12': + "@esbuild/openbsd-arm64@0.25.12": optional: true - '@esbuild/netbsd-arm64@0.27.0': + "@esbuild/openbsd-arm64@0.27.0": optional: true - '@esbuild/netbsd-arm64@0.27.7': + "@esbuild/openbsd-arm64@0.27.7": optional: true - '@esbuild/netbsd-x64@0.18.20': + "@esbuild/openbsd-arm64@0.28.1": optional: true - '@esbuild/netbsd-x64@0.25.12': + "@esbuild/openbsd-x64@0.18.20": optional: true - '@esbuild/netbsd-x64@0.27.0': + "@esbuild/openbsd-x64@0.25.12": optional: true - '@esbuild/netbsd-x64@0.27.7': + "@esbuild/openbsd-x64@0.27.0": optional: true - '@esbuild/openbsd-arm64@0.25.12': + "@esbuild/openbsd-x64@0.27.7": optional: true - '@esbuild/openbsd-arm64@0.27.0': + "@esbuild/openbsd-x64@0.28.1": optional: true - '@esbuild/openbsd-arm64@0.27.7': + "@esbuild/openharmony-arm64@0.25.12": optional: true - '@esbuild/openbsd-x64@0.18.20': + "@esbuild/openharmony-arm64@0.27.0": optional: true - '@esbuild/openbsd-x64@0.25.12': + "@esbuild/openharmony-arm64@0.27.7": optional: true - '@esbuild/openbsd-x64@0.27.0': + "@esbuild/openharmony-arm64@0.28.1": optional: true - '@esbuild/openbsd-x64@0.27.7': + "@esbuild/sunos-x64@0.18.20": optional: true - '@esbuild/openharmony-arm64@0.25.12': + "@esbuild/sunos-x64@0.25.12": optional: true - '@esbuild/openharmony-arm64@0.27.0': + "@esbuild/sunos-x64@0.27.0": optional: true - '@esbuild/openharmony-arm64@0.27.7': + "@esbuild/sunos-x64@0.27.7": optional: true - '@esbuild/sunos-x64@0.18.20': + "@esbuild/sunos-x64@0.28.1": optional: true - '@esbuild/sunos-x64@0.25.12': + "@esbuild/win32-arm64@0.18.20": optional: true - '@esbuild/sunos-x64@0.27.0': + "@esbuild/win32-arm64@0.25.12": optional: true - '@esbuild/sunos-x64@0.27.7': + "@esbuild/win32-arm64@0.27.0": optional: true - '@esbuild/win32-arm64@0.18.20': + "@esbuild/win32-arm64@0.27.7": optional: true - '@esbuild/win32-arm64@0.25.12': + "@esbuild/win32-arm64@0.28.1": optional: true - '@esbuild/win32-arm64@0.27.0': + "@esbuild/win32-ia32@0.18.20": optional: true - '@esbuild/win32-arm64@0.27.7': + "@esbuild/win32-ia32@0.25.12": optional: true - '@esbuild/win32-ia32@0.18.20': + "@esbuild/win32-ia32@0.27.0": optional: true - '@esbuild/win32-ia32@0.25.12': + "@esbuild/win32-ia32@0.27.7": optional: true - '@esbuild/win32-ia32@0.27.0': + "@esbuild/win32-ia32@0.28.1": optional: true - '@esbuild/win32-ia32@0.27.7': + "@esbuild/win32-x64@0.18.20": optional: true - '@esbuild/win32-x64@0.18.20': + "@esbuild/win32-x64@0.25.12": optional: true - '@esbuild/win32-x64@0.25.12': + "@esbuild/win32-x64@0.27.0": optional: true - '@esbuild/win32-x64@0.27.0': + "@esbuild/win32-x64@0.27.7": optional: true - '@esbuild/win32-x64@0.27.7': + "@esbuild/win32-x64@0.28.1": optional: true - '@expressive-code/core@0.42.0': + "@expressive-code/core@0.42.0": dependencies: - '@ctrl/tinycolor': 4.2.0 + "@ctrl/tinycolor": 4.2.0 hast-util-select: 6.0.4 hast-util-to-html: 9.0.5 hast-util-to-text: 4.0.2 @@ -8612,234 +13722,234 @@ snapshots: unist-util-visit: 5.1.0 unist-util-visit-parents: 6.0.2 - '@expressive-code/plugin-frames@0.42.0': + "@expressive-code/plugin-frames@0.42.0": dependencies: - '@expressive-code/core': 0.42.0 + "@expressive-code/core": 0.42.0 - '@expressive-code/plugin-shiki@0.42.0': + "@expressive-code/plugin-shiki@0.42.0": dependencies: - '@expressive-code/core': 0.42.0 + "@expressive-code/core": 0.42.0 shiki: 4.1.0 - '@expressive-code/plugin-text-markers@0.42.0': + "@expressive-code/plugin-text-markers@0.42.0": dependencies: - '@expressive-code/core': 0.42.0 + "@expressive-code/core": 0.42.0 - '@fastify/busboy@2.1.1': {} + "@fastify/busboy@2.1.1": {} - '@fastify/otel@0.18.0(@opentelemetry/api@1.9.1)': + "@fastify/otel@0.18.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.212.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.212.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 minimatch: 10.2.5 transitivePeerDependencies: - supports-color - '@fontsource-variable/rubik@5.2.8': {} + "@fontsource-variable/rubik@5.2.8": {} - '@fontsource/ibm-plex-mono@5.2.7': {} + "@fontsource/ibm-plex-mono@5.2.7": {} - '@gerrit0/mini-shiki@3.23.0': + "@gerrit0/mini-shiki@3.23.0": dependencies: - '@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 + "@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 - '@google/genai@1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + "@google/genai@1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))": dependencies: google-auth-library: 10.6.2 p-retry: 4.6.2 protobufjs: 7.6.1 ws: 8.20.1 optionalDependencies: - '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) + "@modelcontextprotocol/sdk": 1.29.0(zod@4.4.3) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - '@hono/node-server@1.19.14(hono@4.12.22)': + "@hono/node-server@1.19.14(hono@4.12.22)": dependencies: hono: 4.12.22 - '@img/colour@1.1.0': + "@img/colour@1.1.0": optional: true - '@img/sharp-darwin-arm64@0.34.5': + "@img/sharp-darwin-arm64@0.34.5": optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.2.4 + "@img/sharp-libvips-darwin-arm64": 1.2.4 optional: true - '@img/sharp-darwin-x64@0.34.5': + "@img/sharp-darwin-x64@0.34.5": optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.2.4 + "@img/sharp-libvips-darwin-x64": 1.2.4 optional: true - '@img/sharp-libvips-darwin-arm64@1.2.4': + "@img/sharp-libvips-darwin-arm64@1.2.4": optional: true - '@img/sharp-libvips-darwin-x64@1.2.4': + "@img/sharp-libvips-darwin-x64@1.2.4": optional: true - '@img/sharp-libvips-linux-arm64@1.2.4': + "@img/sharp-libvips-linux-arm64@1.2.4": optional: true - '@img/sharp-libvips-linux-arm@1.2.4': + "@img/sharp-libvips-linux-arm@1.2.4": optional: true - '@img/sharp-libvips-linux-ppc64@1.2.4': + "@img/sharp-libvips-linux-ppc64@1.2.4": optional: true - '@img/sharp-libvips-linux-riscv64@1.2.4': + "@img/sharp-libvips-linux-riscv64@1.2.4": optional: true - '@img/sharp-libvips-linux-s390x@1.2.4': + "@img/sharp-libvips-linux-s390x@1.2.4": optional: true - '@img/sharp-libvips-linux-x64@1.2.4': + "@img/sharp-libvips-linux-x64@1.2.4": optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + "@img/sharp-libvips-linuxmusl-arm64@1.2.4": optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.4': + "@img/sharp-libvips-linuxmusl-x64@1.2.4": optional: true - '@img/sharp-linux-arm64@0.34.5': + "@img/sharp-linux-arm64@0.34.5": optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.2.4 + "@img/sharp-libvips-linux-arm64": 1.2.4 optional: true - '@img/sharp-linux-arm@0.34.5': + "@img/sharp-linux-arm@0.34.5": optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.2.4 + "@img/sharp-libvips-linux-arm": 1.2.4 optional: true - '@img/sharp-linux-ppc64@0.34.5': + "@img/sharp-linux-ppc64@0.34.5": optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.2.4 + "@img/sharp-libvips-linux-ppc64": 1.2.4 optional: true - '@img/sharp-linux-riscv64@0.34.5': + "@img/sharp-linux-riscv64@0.34.5": optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.2.4 + "@img/sharp-libvips-linux-riscv64": 1.2.4 optional: true - '@img/sharp-linux-s390x@0.34.5': + "@img/sharp-linux-s390x@0.34.5": optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.2.4 + "@img/sharp-libvips-linux-s390x": 1.2.4 optional: true - '@img/sharp-linux-x64@0.34.5': + "@img/sharp-linux-x64@0.34.5": optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.2.4 + "@img/sharp-libvips-linux-x64": 1.2.4 optional: true - '@img/sharp-linuxmusl-arm64@0.34.5': + "@img/sharp-linuxmusl-arm64@0.34.5": optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + "@img/sharp-libvips-linuxmusl-arm64": 1.2.4 optional: true - '@img/sharp-linuxmusl-x64@0.34.5': + "@img/sharp-linuxmusl-x64@0.34.5": optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + "@img/sharp-libvips-linuxmusl-x64": 1.2.4 optional: true - '@img/sharp-wasm32@0.34.5': + "@img/sharp-wasm32@0.34.5": dependencies: - '@emnapi/runtime': 1.10.0 + "@emnapi/runtime": 1.10.0 optional: true - '@img/sharp-win32-arm64@0.34.5': + "@img/sharp-win32-arm64@0.34.5": optional: true - '@img/sharp-win32-ia32@0.34.5': + "@img/sharp-win32-ia32@0.34.5": optional: true - '@img/sharp-win32-x64@0.34.5': + "@img/sharp-win32-x64@0.34.5": optional: true - '@inquirer/ansi@2.0.5': {} + "@inquirer/ansi@2.0.5": {} - '@inquirer/confirm@6.0.13(@types/node@25.9.1)': + "@inquirer/confirm@6.0.13(@types/node@25.9.1)": dependencies: - '@inquirer/core': 11.1.10(@types/node@25.9.1) - '@inquirer/type': 4.0.5(@types/node@25.9.1) + "@inquirer/core": 11.1.10(@types/node@25.9.1) + "@inquirer/type": 4.0.5(@types/node@25.9.1) optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@inquirer/core@11.1.10(@types/node@25.9.1)': + "@inquirer/core@11.1.10(@types/node@25.9.1)": dependencies: - '@inquirer/ansi': 2.0.5 - '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@25.9.1) + "@inquirer/ansi": 2.0.5 + "@inquirer/figures": 2.0.5 + "@inquirer/type": 4.0.5(@types/node@25.9.1) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@inquirer/figures@2.0.5': {} + "@inquirer/figures@2.0.5": {} - '@inquirer/type@4.0.5(@types/node@25.9.1)': + "@inquirer/type@4.0.5(@types/node@25.9.1)": optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@isaacs/balanced-match@4.0.1': {} + "@isaacs/balanced-match@4.0.1": {} - '@isaacs/brace-expansion@5.0.1': + "@isaacs/brace-expansion@5.0.1": dependencies: - '@isaacs/balanced-match': 4.0.1 + "@isaacs/balanced-match": 4.0.1 - '@isaacs/fs-minipass@4.0.1': + "@isaacs/fs-minipass@4.0.1": dependencies: minipass: 7.1.3 - '@jitl/quickjs-ffi-types@0.32.0': {} + "@jitl/quickjs-ffi-types@0.32.0": {} - '@jitl/quickjs-wasmfile-debug-asyncify@0.32.0': + "@jitl/quickjs-wasmfile-debug-asyncify@0.32.0": dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 + "@jitl/quickjs-ffi-types": 0.32.0 - '@jitl/quickjs-wasmfile-debug-sync@0.32.0': + "@jitl/quickjs-wasmfile-debug-sync@0.32.0": dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 + "@jitl/quickjs-ffi-types": 0.32.0 - '@jitl/quickjs-wasmfile-release-asyncify@0.32.0': + "@jitl/quickjs-wasmfile-release-asyncify@0.32.0": dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 + "@jitl/quickjs-ffi-types": 0.32.0 - '@jitl/quickjs-wasmfile-release-sync@0.32.0': + "@jitl/quickjs-wasmfile-release-sync@0.32.0": dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 + "@jitl/quickjs-ffi-types": 0.32.0 - '@jridgewell/gen-mapping@0.3.13': + "@jridgewell/gen-mapping@0.3.13": dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + "@jridgewell/sourcemap-codec": 1.5.5 + "@jridgewell/trace-mapping": 0.3.31 - '@jridgewell/remapping@2.3.5': + "@jridgewell/remapping@2.3.5": dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + "@jridgewell/gen-mapping": 0.3.13 + "@jridgewell/trace-mapping": 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} + "@jridgewell/resolve-uri@3.1.2": {} - '@jridgewell/sourcemap-codec@1.5.5': {} + "@jridgewell/sourcemap-codec@1.5.5": {} - '@jridgewell/trace-mapping@0.3.31': + "@jridgewell/trace-mapping@0.3.31": dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.5 - '@logtape/logtape@2.1.1': {} + "@logtape/logtape@2.1.1": {} - '@mapbox/node-pre-gyp@2.0.3': + "@mapbox/node-pre-gyp@2.0.3": dependencies: consola: 3.4.2 detect-libc: 2.1.2 @@ -8852,12 +13962,12 @@ snapshots: - encoding - supports-color - '@mdx-js/mdx@3.1.1': + "@mdx-js/mdx@3.1.1": dependencies: - '@types/estree': 1.0.9 - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdx': 2.0.13 + "@types/estree": 1.0.9 + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdx": 2.0.13 acorn: 8.16.0 collapse-white-space: 2.1.0 devlop: 1.1.0 @@ -8882,7 +13992,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@mistralai/mistralai@2.2.1': + "@mistralai/mistralai@2.2.1": dependencies: ws: 8.20.1 zod: 4.4.3 @@ -8891,11 +14001,11 @@ snapshots: - bufferutil - utf-8-validate - '@mixmark-io/domino@2.2.0': {} + "@mixmark-io/domino@2.2.0": {} - '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': + "@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)": dependencies: - '@hono/node-server': 1.19.14(hono@4.12.22) + "@hono/node-server": 1.19.14(hono@4.12.22) ajv: 8.20.0 ajv-formats: 3.0.1 content-type: 1.0.5 @@ -8915,551 +14025,557 @@ snapshots: transitivePeerDependencies: - supports-color - '@mongodb-js/zstd@7.0.0': + "@mongodb-js/zstd@7.0.0": dependencies: node-addon-api: 8.8.0 prebuild-install: 7.1.3 optional: true - '@mswjs/interceptors@0.41.9': + "@mswjs/interceptors@0.41.9": dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 + "@open-draft/deferred-promise": 2.2.0 + "@open-draft/logger": 0.3.0 + "@open-draft/until": 2.1.0 is-node-process: 1.2.0 outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + "@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)": dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 + "@emnapi/core": 1.10.0 + "@emnapi/runtime": 1.10.0 + "@tybys/wasm-util": 0.10.2 optional: true - '@neondatabase/serverless@1.1.0': {} + "@neondatabase/serverless@1.1.0": {} - '@noble/ciphers@2.2.0': {} + "@noble/ciphers@2.2.0": {} - '@noble/hashes@2.2.0': {} + "@noble/hashes@2.2.0": {} - '@nodable/entities@2.1.0': {} + "@nodable/entities@2.1.0": {} - '@nodelib/fs.scandir@2.1.5': + "@nodelib/fs.scandir@2.1.5": dependencies: - '@nodelib/fs.stat': 2.0.5 + "@nodelib/fs.stat": 2.0.5 run-parallel: 1.2.0 - '@nodelib/fs.stat@2.0.5': {} + "@nodelib/fs.stat@2.0.5": {} - '@nodelib/fs.walk@1.2.8': + "@nodelib/fs.walk@1.2.8": dependencies: - '@nodelib/fs.scandir': 2.1.5 + "@nodelib/fs.scandir": 2.1.5 fastq: 1.20.1 - '@open-draft/deferred-promise@2.2.0': {} + "@open-draft/deferred-promise@2.2.0": {} - '@open-draft/deferred-promise@3.0.0': {} + "@open-draft/deferred-promise@3.0.0": {} - '@open-draft/logger@0.3.0': + "@open-draft/logger@0.3.0": dependencies: is-node-process: 1.2.0 outvariant: 1.4.3 - '@open-draft/until@2.1.0': {} + "@open-draft/until@2.1.0": {} - '@opentelemetry/api-logs@0.207.0': + "@opentelemetry/api-logs@0.207.0": dependencies: - '@opentelemetry/api': 1.9.1 + "@opentelemetry/api": 1.9.1 - '@opentelemetry/api-logs@0.212.0': + "@opentelemetry/api-logs@0.212.0": dependencies: - '@opentelemetry/api': 1.9.1 + "@opentelemetry/api": 1.9.1 - '@opentelemetry/api-logs@0.214.0': + "@opentelemetry/api-logs@0.214.0": dependencies: - '@opentelemetry/api': 1.9.1 + "@opentelemetry/api": 1.9.1 - '@opentelemetry/api@1.9.1': {} + "@opentelemetry/api@1.9.1": {} - '@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)': + "@opentelemetry/core@2.6.1(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/semantic-conventions": 1.41.1 - '@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)': + "@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/semantic-conventions": 1.41.1 - '@opentelemetry/instrumentation-amqplib@0.61.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-amqplib@0.61.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-connect@0.57.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-connect@0.57.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@types/connect': 3.4.38 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@types/connect": 3.4.38 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-dataloader@0.31.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-dataloader@0.31.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-fs@0.33.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-fs@0.33.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-generic-pool@0.57.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-generic-pool@0.57.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-graphql@0.62.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-graphql@0.62.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-hapi@0.60.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-hapi@0.60.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-http@0.214.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-http@0.214.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.6.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.6.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-kafkajs@0.23.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-kafkajs@0.23.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-knex@0.58.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-knex@0.58.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-koa@0.62.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-koa@0.62.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-lru-memoizer@0.58.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-lru-memoizer@0.58.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongodb@0.67.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-mongodb@0.67.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mongoose@0.60.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-mongoose@0.60.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql2@0.60.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-mysql2@0.60.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@opentelemetry/sql-common": 0.41.2(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-mysql@0.60.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-mysql@0.60.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@types/mysql': 2.15.27 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@types/mysql": 2.15.27 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.66.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-pg@0.66.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@opentelemetry/sql-common': 0.41.2(@opentelemetry/api@1.9.1) - '@types/pg': 8.15.6 - '@types/pg-pool': 2.0.7 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@opentelemetry/sql-common": 0.41.2(@opentelemetry/api@1.9.1) + "@types/pg": 8.15.6 + "@types/pg-pool": 2.0.7 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-tedious@0.33.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation-tedious@0.33.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@types/tedious': 4.0.14 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@types/tedious": 4.0.14 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.207.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation@0.207.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.207.0 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/api-logs": 0.207.0 import-in-the-middle: 2.0.6 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.212.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation@0.212.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.212.0 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/api-logs": 0.212.0 import-in-the-middle: 2.0.6 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1)': + "@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/api-logs': 0.214.0 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/api-logs": 0.214.0 import-in-the-middle: 3.0.1 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color - '@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)': + "@opentelemetry/resources@2.7.1(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 - '@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)': + "@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/resources': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/resources": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 - '@opentelemetry/semantic-conventions@1.41.1': {} + "@opentelemetry/semantic-conventions@1.41.1": {} - '@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.1)': + "@opentelemetry/sql-common@0.41.2(@opentelemetry/api@1.9.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) - '@oslojs/encoding@1.1.0': {} + "@oslojs/encoding@1.1.0": {} - '@oxc-project/types@0.110.0': {} + "@oxc-project/types@0.110.0": {} - '@oxc-project/types@0.132.0': {} + "@oxc-project/types@0.132.0": {} - '@oxc-transform/binding-android-arm-eabi@0.111.0': + "@oxc-transform/binding-android-arm-eabi@0.111.0": optional: true - '@oxc-transform/binding-android-arm64@0.111.0': + "@oxc-transform/binding-android-arm64@0.111.0": optional: true - '@oxc-transform/binding-darwin-arm64@0.111.0': + "@oxc-transform/binding-darwin-arm64@0.111.0": optional: true - '@oxc-transform/binding-darwin-x64@0.111.0': + "@oxc-transform/binding-darwin-x64@0.111.0": optional: true - '@oxc-transform/binding-freebsd-x64@0.111.0': + "@oxc-transform/binding-freebsd-x64@0.111.0": optional: true - '@oxc-transform/binding-linux-arm-gnueabihf@0.111.0': + "@oxc-transform/binding-linux-arm-gnueabihf@0.111.0": optional: true - '@oxc-transform/binding-linux-arm-musleabihf@0.111.0': + "@oxc-transform/binding-linux-arm-musleabihf@0.111.0": optional: true - '@oxc-transform/binding-linux-arm64-gnu@0.111.0': + "@oxc-transform/binding-linux-arm64-gnu@0.111.0": optional: true - '@oxc-transform/binding-linux-arm64-musl@0.111.0': + "@oxc-transform/binding-linux-arm64-musl@0.111.0": optional: true - '@oxc-transform/binding-linux-ppc64-gnu@0.111.0': + "@oxc-transform/binding-linux-ppc64-gnu@0.111.0": optional: true - '@oxc-transform/binding-linux-riscv64-gnu@0.111.0': + "@oxc-transform/binding-linux-riscv64-gnu@0.111.0": optional: true - '@oxc-transform/binding-linux-riscv64-musl@0.111.0': + "@oxc-transform/binding-linux-riscv64-musl@0.111.0": optional: true - '@oxc-transform/binding-linux-s390x-gnu@0.111.0': + "@oxc-transform/binding-linux-s390x-gnu@0.111.0": optional: true - '@oxc-transform/binding-linux-x64-gnu@0.111.0': + "@oxc-transform/binding-linux-x64-gnu@0.111.0": optional: true - '@oxc-transform/binding-linux-x64-musl@0.111.0': + "@oxc-transform/binding-linux-x64-musl@0.111.0": optional: true - '@oxc-transform/binding-openharmony-arm64@0.111.0': + "@oxc-transform/binding-openharmony-arm64@0.111.0": optional: true - '@oxc-transform/binding-wasm32-wasi@0.111.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + "@oxc-transform/binding-wasm32-wasi@0.111.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)": dependencies: - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@napi-rs/wasm-runtime": 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + - "@emnapi/core" + - "@emnapi/runtime" optional: true - '@oxc-transform/binding-win32-arm64-msvc@0.111.0': + "@oxc-transform/binding-win32-arm64-msvc@0.111.0": optional: true - '@oxc-transform/binding-win32-ia32-msvc@0.111.0': + "@oxc-transform/binding-win32-ia32-msvc@0.111.0": optional: true - '@oxc-transform/binding-win32-x64-msvc@0.111.0': + "@oxc-transform/binding-win32-x64-msvc@0.111.0": optional: true - '@oxlint/binding-android-arm-eabi@1.66.0': + "@oxlint/binding-android-arm-eabi@1.66.0": optional: true - '@oxlint/binding-android-arm64@1.66.0': + "@oxlint/binding-android-arm64@1.66.0": optional: true - '@oxlint/binding-darwin-arm64@1.66.0': + "@oxlint/binding-darwin-arm64@1.66.0": optional: true - '@oxlint/binding-darwin-x64@1.66.0': + "@oxlint/binding-darwin-x64@1.66.0": optional: true - '@oxlint/binding-freebsd-x64@1.66.0': + "@oxlint/binding-freebsd-x64@1.66.0": optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.66.0': + "@oxlint/binding-linux-arm-gnueabihf@1.66.0": optional: true - '@oxlint/binding-linux-arm-musleabihf@1.66.0': + "@oxlint/binding-linux-arm-musleabihf@1.66.0": optional: true - '@oxlint/binding-linux-arm64-gnu@1.66.0': + "@oxlint/binding-linux-arm64-gnu@1.66.0": optional: true - '@oxlint/binding-linux-arm64-musl@1.66.0': + "@oxlint/binding-linux-arm64-musl@1.66.0": optional: true - '@oxlint/binding-linux-ppc64-gnu@1.66.0': + "@oxlint/binding-linux-ppc64-gnu@1.66.0": optional: true - '@oxlint/binding-linux-riscv64-gnu@1.66.0': + "@oxlint/binding-linux-riscv64-gnu@1.66.0": optional: true - '@oxlint/binding-linux-riscv64-musl@1.66.0': + "@oxlint/binding-linux-riscv64-musl@1.66.0": optional: true - '@oxlint/binding-linux-s390x-gnu@1.66.0': + "@oxlint/binding-linux-s390x-gnu@1.66.0": optional: true - '@oxlint/binding-linux-x64-gnu@1.66.0': + "@oxlint/binding-linux-x64-gnu@1.66.0": optional: true - '@oxlint/binding-linux-x64-musl@1.66.0': + "@oxlint/binding-linux-x64-musl@1.66.0": optional: true - '@oxlint/binding-openharmony-arm64@1.66.0': + "@oxlint/binding-openharmony-arm64@1.66.0": optional: true - '@oxlint/binding-win32-arm64-msvc@1.66.0': + "@oxlint/binding-win32-arm64-msvc@1.66.0": optional: true - '@oxlint/binding-win32-ia32-msvc@1.66.0': + "@oxlint/binding-win32-ia32-msvc@1.66.0": optional: true - '@oxlint/binding-win32-x64-msvc@1.66.0': + "@oxlint/binding-win32-x64-msvc@1.66.0": optional: true - '@pagefind/darwin-arm64@1.5.2': + "@pagefind/darwin-arm64@1.5.2": optional: true - '@pagefind/darwin-x64@1.5.2': + "@pagefind/darwin-x64@1.5.2": optional: true - '@pagefind/default-ui@1.5.2': {} + "@pagefind/default-ui@1.5.2": {} - '@pagefind/freebsd-x64@1.5.2': + "@pagefind/freebsd-x64@1.5.2": optional: true - '@pagefind/linux-arm64@1.5.2': + "@pagefind/linux-arm64@1.5.2": optional: true - '@pagefind/linux-x64@1.5.2': + "@pagefind/linux-x64@1.5.2": optional: true - '@pagefind/windows-arm64@1.5.2': + "@pagefind/windows-arm64@1.5.2": optional: true - '@pagefind/windows-x64@1.5.2': + "@pagefind/windows-x64@1.5.2": optional: true - '@parcel/watcher-android-arm64@2.5.6': + "@parcel/watcher-android-arm64@2.5.6": optional: true - '@parcel/watcher-darwin-arm64@2.5.6': + "@parcel/watcher-darwin-arm64@2.5.6": optional: true - '@parcel/watcher-darwin-x64@2.5.6': + "@parcel/watcher-darwin-x64@2.5.6": optional: true - '@parcel/watcher-freebsd-x64@2.5.6': + "@parcel/watcher-freebsd-x64@2.5.6": optional: true - '@parcel/watcher-linux-arm-glibc@2.5.6': + "@parcel/watcher-linux-arm-glibc@2.5.6": optional: true - '@parcel/watcher-linux-arm-musl@2.5.6': + "@parcel/watcher-linux-arm-musl@2.5.6": optional: true - '@parcel/watcher-linux-arm64-glibc@2.5.6': + "@parcel/watcher-linux-arm64-glibc@2.5.6": optional: true - '@parcel/watcher-linux-arm64-musl@2.5.6': + "@parcel/watcher-linux-arm64-musl@2.5.6": optional: true - '@parcel/watcher-linux-x64-glibc@2.5.6': + "@parcel/watcher-linux-x64-glibc@2.5.6": optional: true - '@parcel/watcher-linux-x64-musl@2.5.6': + "@parcel/watcher-linux-x64-musl@2.5.6": optional: true - '@parcel/watcher-win32-arm64@2.5.6': + "@parcel/watcher-win32-arm64@2.5.6": optional: true - '@parcel/watcher-win32-ia32@2.5.6': + "@parcel/watcher-win32-ia32@2.5.6": optional: true - '@parcel/watcher-win32-x64@2.5.6': + "@parcel/watcher-win32-x64@2.5.6": optional: true - '@parcel/watcher@2.5.6': + "@parcel/watcher@2.5.6": dependencies: detect-libc: 2.1.2 is-glob: 4.0.3 node-addon-api: 7.1.1 picomatch: 4.0.4 optionalDependencies: - '@parcel/watcher-android-arm64': 2.5.6 - '@parcel/watcher-darwin-arm64': 2.5.6 - '@parcel/watcher-darwin-x64': 2.5.6 - '@parcel/watcher-freebsd-x64': 2.5.6 - '@parcel/watcher-linux-arm-glibc': 2.5.6 - '@parcel/watcher-linux-arm-musl': 2.5.6 - '@parcel/watcher-linux-arm64-glibc': 2.5.6 - '@parcel/watcher-linux-arm64-musl': 2.5.6 - '@parcel/watcher-linux-x64-glibc': 2.5.6 - '@parcel/watcher-linux-x64-musl': 2.5.6 - '@parcel/watcher-win32-arm64': 2.5.6 - '@parcel/watcher-win32-ia32': 2.5.6 - '@parcel/watcher-win32-x64': 2.5.6 - - '@playwright/test@1.60.0': {} - - '@prisma/instrumentation@7.6.0(@opentelemetry/api@1.9.1)': - dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/instrumentation': 0.207.0(@opentelemetry/api@1.9.1) + "@parcel/watcher-android-arm64": 2.5.6 + "@parcel/watcher-darwin-arm64": 2.5.6 + "@parcel/watcher-darwin-x64": 2.5.6 + "@parcel/watcher-freebsd-x64": 2.5.6 + "@parcel/watcher-linux-arm-glibc": 2.5.6 + "@parcel/watcher-linux-arm-musl": 2.5.6 + "@parcel/watcher-linux-arm64-glibc": 2.5.6 + "@parcel/watcher-linux-arm64-musl": 2.5.6 + "@parcel/watcher-linux-x64-glibc": 2.5.6 + "@parcel/watcher-linux-x64-musl": 2.5.6 + "@parcel/watcher-win32-arm64": 2.5.6 + "@parcel/watcher-win32-ia32": 2.5.6 + "@parcel/watcher-win32-x64": 2.5.6 + + "@playwright/test@1.60.0": + dependencies: + playwright: 1.60.0 + + "@prisma/instrumentation@7.6.0(@opentelemetry/api@1.9.1)": + dependencies: + "@opentelemetry/api": 1.9.1 + "@opentelemetry/instrumentation": 0.207.0(@opentelemetry/api@1.9.1) transitivePeerDependencies: - supports-color - '@protobufjs/aspromise@1.1.2': {} + "@protobufjs/aspromise@1.1.2": {} - '@protobufjs/base64@1.1.2': {} + "@protobufjs/base64@1.1.2": {} - '@protobufjs/codegen@2.0.5': {} + "@protobufjs/codegen@2.0.5": {} - '@protobufjs/eventemitter@1.1.1': {} + "@protobufjs/eventemitter@1.1.1": {} - '@protobufjs/fetch@1.1.1': + "@protobufjs/fetch@1.1.1": dependencies: - '@protobufjs/aspromise': 1.1.2 + "@protobufjs/aspromise": 1.1.2 + + "@protobufjs/float@1.0.2": {} - '@protobufjs/float@1.0.2': {} + "@protobufjs/inquire@1.1.2": {} - '@protobufjs/inquire@1.1.2': {} + "@protobufjs/path@1.1.2": {} - '@protobufjs/path@1.1.2': {} + "@protobufjs/pool@1.1.0": {} - '@protobufjs/pool@1.1.0': {} + "@protobufjs/utf8@1.1.1": {} - '@protobufjs/utf8@1.1.1': {} + "@publint/pack@0.1.5": + dependencies: + tinyexec: 1.1.2 - '@redis/bloom@5.12.1(@redis/client@5.12.1)': + "@redis/bloom@5.12.1(@redis/client@5.12.1)": dependencies: - '@redis/client': 5.12.1 + "@redis/client": 5.12.1 - '@redis/client@5.12.1': + "@redis/client@5.12.1": dependencies: cluster-key-slot: 1.1.2 - '@redis/json@5.12.1(@redis/client@5.12.1)': + "@redis/json@5.12.1(@redis/client@5.12.1)": dependencies: - '@redis/client': 5.12.1 + "@redis/client": 5.12.1 - '@redis/search@5.12.1(@redis/client@5.12.1)': + "@redis/search@5.12.1(@redis/client@5.12.1)": dependencies: - '@redis/client': 5.12.1 + "@redis/client": 5.12.1 - '@redis/time-series@5.12.1(@redis/client@5.12.1)': + "@redis/time-series@5.12.1(@redis/client@5.12.1)": dependencies: - '@redis/client': 5.12.1 + "@redis/client": 5.12.1 - '@reduxjs/toolkit@2.12.0(react-redux@9.3.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1))(react@19.2.6)': + "@reduxjs/toolkit@2.12.0(react-redux@9.3.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1))(react@19.2.6)": dependencies: - '@standard-schema/spec': 1.1.0 - '@standard-schema/utils': 0.3.0 + "@standard-schema/spec": 1.1.0 + "@standard-schema/utils": 0.3.0 immer: 11.1.8 redux: 5.0.1 redux-thunk: 3.1.0(redux@5.0.1) @@ -9468,10 +14584,10 @@ snapshots: react: 19.2.6 react-redux: 9.3.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1) - '@reduxjs/toolkit@2.12.0(react-redux@9.3.0(react@19.2.6))(react@19.2.6)': + "@reduxjs/toolkit@2.12.0(react-redux@9.3.0(react@19.2.6))(react@19.2.6)": dependencies: - '@standard-schema/spec': 1.1.0 - '@standard-schema/utils': 0.3.0 + "@standard-schema/spec": 1.1.0 + "@standard-schema/utils": 0.3.0 immer: 11.1.8 redux: 5.0.1 redux-thunk: 3.1.0(redux@5.0.1) @@ -9480,205 +14596,205 @@ snapshots: react: 19.2.6 react-redux: 9.3.0(react@19.2.6) - '@renovatebot/pep440@4.2.1': {} + "@renovatebot/pep440@4.2.1": {} - '@rolldown/binding-android-arm64@1.0.0-rc.1': + "@rolldown/binding-android-arm64@1.0.0-rc.1": optional: true - '@rolldown/binding-android-arm64@1.0.2': + "@rolldown/binding-android-arm64@1.0.2": optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.1': + "@rolldown/binding-darwin-arm64@1.0.0-rc.1": optional: true - '@rolldown/binding-darwin-arm64@1.0.2': + "@rolldown/binding-darwin-arm64@1.0.2": optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.1': + "@rolldown/binding-darwin-x64@1.0.0-rc.1": optional: true - '@rolldown/binding-darwin-x64@1.0.2': + "@rolldown/binding-darwin-x64@1.0.2": optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.1': + "@rolldown/binding-freebsd-x64@1.0.0-rc.1": optional: true - '@rolldown/binding-freebsd-x64@1.0.2': + "@rolldown/binding-freebsd-x64@1.0.2": optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1': + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.1": optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.2': + "@rolldown/binding-linux-arm-gnueabihf@1.0.2": optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1': + "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.1": optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.2': + "@rolldown/binding-linux-arm64-gnu@1.0.2": optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.1': + "@rolldown/binding-linux-arm64-musl@1.0.0-rc.1": optional: true - '@rolldown/binding-linux-arm64-musl@1.0.2': + "@rolldown/binding-linux-arm64-musl@1.0.2": optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.2': + "@rolldown/binding-linux-ppc64-gnu@1.0.2": optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.2': + "@rolldown/binding-linux-s390x-gnu@1.0.2": optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.1': + "@rolldown/binding-linux-x64-gnu@1.0.0-rc.1": optional: true - '@rolldown/binding-linux-x64-gnu@1.0.2': + "@rolldown/binding-linux-x64-gnu@1.0.2": optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.1': + "@rolldown/binding-linux-x64-musl@1.0.0-rc.1": optional: true - '@rolldown/binding-linux-x64-musl@1.0.2': + "@rolldown/binding-linux-x64-musl@1.0.2": optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.1': + "@rolldown/binding-openharmony-arm64@1.0.0-rc.1": optional: true - '@rolldown/binding-openharmony-arm64@1.0.2': + "@rolldown/binding-openharmony-arm64@1.0.2": optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + "@rolldown/binding-wasm32-wasi@1.0.0-rc.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)": dependencies: - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@napi-rs/wasm-runtime": 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + - "@emnapi/core" + - "@emnapi/runtime" optional: true - '@rolldown/binding-wasm32-wasi@1.0.2': + "@rolldown/binding-wasm32-wasi@1.0.2": dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@emnapi/core": 1.10.0 + "@emnapi/runtime": 1.10.0 + "@napi-rs/wasm-runtime": 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1': + "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.1": optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.2': + "@rolldown/binding-win32-arm64-msvc@1.0.2": optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.1': + "@rolldown/binding-win32-x64-msvc@1.0.0-rc.1": optional: true - '@rolldown/binding-win32-x64-msvc@1.0.2': + "@rolldown/binding-win32-x64-msvc@1.0.2": optional: true - '@rolldown/pluginutils@1.0.0-rc.1': {} + "@rolldown/pluginutils@1.0.0-rc.1": {} - '@rolldown/pluginutils@1.0.1': {} + "@rolldown/pluginutils@1.0.1": {} - '@rollup/pluginutils@5.3.0': + "@rollup/pluginutils@5.3.0": dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 - '@rollup/pluginutils@5.3.0(rollup@4.60.4)': + "@rollup/pluginutils@5.3.0(rollup@4.60.4)": dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: rollup: 4.60.4 - '@rollup/rollup-android-arm-eabi@4.60.4': + "@rollup/rollup-android-arm-eabi@4.60.4": optional: true - '@rollup/rollup-android-arm64@4.60.4': + "@rollup/rollup-android-arm64@4.60.4": optional: true - '@rollup/rollup-darwin-arm64@4.60.4': + "@rollup/rollup-darwin-arm64@4.60.4": optional: true - '@rollup/rollup-darwin-x64@4.60.4': + "@rollup/rollup-darwin-x64@4.60.4": optional: true - '@rollup/rollup-freebsd-arm64@4.60.4': + "@rollup/rollup-freebsd-arm64@4.60.4": optional: true - '@rollup/rollup-freebsd-x64@4.60.4': + "@rollup/rollup-freebsd-x64@4.60.4": optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + "@rollup/rollup-linux-arm-gnueabihf@4.60.4": optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.4': + "@rollup/rollup-linux-arm-musleabihf@4.60.4": optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.4': + "@rollup/rollup-linux-arm64-gnu@4.60.4": optional: true - '@rollup/rollup-linux-arm64-musl@4.60.4': + "@rollup/rollup-linux-arm64-musl@4.60.4": optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.4': + "@rollup/rollup-linux-loong64-gnu@4.60.4": optional: true - '@rollup/rollup-linux-loong64-musl@4.60.4': + "@rollup/rollup-linux-loong64-musl@4.60.4": optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.4': + "@rollup/rollup-linux-ppc64-gnu@4.60.4": optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.4': + "@rollup/rollup-linux-ppc64-musl@4.60.4": optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.4': + "@rollup/rollup-linux-riscv64-gnu@4.60.4": optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.4': + "@rollup/rollup-linux-riscv64-musl@4.60.4": optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.4': + "@rollup/rollup-linux-s390x-gnu@4.60.4": optional: true - '@rollup/rollup-linux-x64-gnu@4.60.4': + "@rollup/rollup-linux-x64-gnu@4.60.4": optional: true - '@rollup/rollup-linux-x64-musl@4.60.4': + "@rollup/rollup-linux-x64-musl@4.60.4": optional: true - '@rollup/rollup-openbsd-x64@4.60.4': + "@rollup/rollup-openbsd-x64@4.60.4": optional: true - '@rollup/rollup-openharmony-arm64@4.60.4': + "@rollup/rollup-openharmony-arm64@4.60.4": optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.4': + "@rollup/rollup-win32-arm64-msvc@4.60.4": optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.4': + "@rollup/rollup-win32-ia32-msvc@4.60.4": optional: true - '@rollup/rollup-win32-x64-gnu@4.60.4': + "@rollup/rollup-win32-x64-gnu@4.60.4": optional: true - '@rollup/rollup-win32-x64-msvc@4.60.4': + "@rollup/rollup-win32-x64-msvc@4.60.4": optional: true - '@sentry/conventions@0.12.0': {} + "@sentry/conventions@0.12.0": {} - '@sentry/core@10.53.1': {} + "@sentry/core@10.53.1": {} - '@sentry/core@10.59.0': {} + "@sentry/core@10.59.0": {} - '@sentry/junior-dashboard@file:packages/junior-dashboard(jiti@2.7.0)': + "@sentry/junior-dashboard@file:packages/junior-dashboard(jiti@2.7.0)": dependencies: - '@sentry/junior': file:packages/junior - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@tanstack/react-query': 5.100.14(react@19.2.6) + "@sentry/junior": file:packages/junior + "@sentry/junior-plugin-api": file:packages/junior-plugin-api + "@tanstack/react-query": 5.100.14(react@19.2.6) better-auth: 1.6.11(react-dom@19.2.6(react@19.2.6))(react@19.2.6) hono: 4.12.22 lucide-react: 1.17.0(react@19.2.6) @@ -9690,45 +14806,45 @@ snapshots: recharts: 3.8.1(react-dom@19.2.6(react@19.2.6))(react-is@19.2.7)(react@19.2.6) shiki: 4.1.0 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@aws-sdk/credential-provider-web-identity' - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@cfworker/json-schema' - - '@cloudflare/workers-types' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@lynx-js/react' - - '@netlify/blobs' - - '@netlify/runtime' - - '@node-rs/xxhash' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@opentelemetry/exporter-trace-otlp-http' - - '@planetscale/database' - - '@prisma/client' - - '@sveltejs/kit' - - '@tanstack/react-start' - - '@tanstack/solid-start' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/react' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - '@vercel/postgres' - - '@vercel/queue' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@aws-sdk/credential-provider-web-identity" + - "@azure/app-configuration" + - "@azure/cosmos" + - "@azure/data-tables" + - "@azure/identity" + - "@azure/keyvault-secrets" + - "@azure/storage-blob" + - "@capacitor/preferences" + - "@cfworker/json-schema" + - "@cloudflare/workers-types" + - "@deno/kv" + - "@electric-sql/pglite" + - "@libsql/client" + - "@libsql/client-wasm" + - "@lynx-js/react" + - "@netlify/blobs" + - "@netlify/runtime" + - "@node-rs/xxhash" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@opentelemetry/exporter-trace-otlp-http" + - "@planetscale/database" + - "@prisma/client" + - "@sveltejs/kit" + - "@tanstack/react-start" + - "@tanstack/solid-start" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/react" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/blob" + - "@vercel/functions" + - "@vercel/kv" + - "@vercel/postgres" + - "@vercel/queue" + - "@xata.io/client" - aws4fetch - bare-abort-controller - better-sqlite3 @@ -9773,31 +14889,31 @@ snapshots: - xml2js - zephyr-agent - '@sentry/junior-memory@file:packages/junior-memory': + "@sentry/junior-memory@file:packages/junior-memory": dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.49 + "@sentry/junior-plugin-api": file:packages/junior-plugin-api + "@sinclair/typebox": 0.34.49 commander: 14.0.3 drizzle-orm: 0.45.2 zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@cloudflare/workers-types" + - "@electric-sql/pglite" + - "@libsql/client" + - "@libsql/client-wasm" + - "@neondatabase/serverless" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - better-sqlite3 - bun-types - expo-sqlite @@ -9811,31 +14927,31 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior-memory@file:packages/junior-memory(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0)': + "@sentry/junior-memory@file:packages/junior-memory(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0)": dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.49 + "@sentry/junior-plugin-api": file:packages/junior-plugin-api + "@sinclair/typebox": 0.34.49 commander: 14.0.3 drizzle-orm: 0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0) zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@cloudflare/workers-types" + - "@electric-sql/pglite" + - "@libsql/client" + - "@libsql/client-wasm" + - "@neondatabase/serverless" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - better-sqlite3 - bun-types - expo-sqlite @@ -9849,35 +14965,35 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior-plugin-api@file:packages/junior-plugin-api': + "@sentry/junior-plugin-api@file:packages/junior-plugin-api": dependencies: commander: 14.0.3 zod: 4.4.3 - '@sentry/junior-scheduler@file:packages/junior-scheduler': + "@sentry/junior-scheduler@file:packages/junior-scheduler": dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.49 + "@sentry/junior-plugin-api": file:packages/junior-plugin-api + "@sinclair/typebox": 0.34.49 drizzle-orm: 0.45.2 zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@cloudflare/workers-types" + - "@electric-sql/pglite" + - "@libsql/client" + - "@libsql/client-wasm" + - "@neondatabase/serverless" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - better-sqlite3 - bun-types - expo-sqlite @@ -9891,30 +15007,30 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior-scheduler@file:packages/junior-scheduler(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0)': + "@sentry/junior-scheduler@file:packages/junior-scheduler(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0)": dependencies: - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sinclair/typebox': 0.34.49 + "@sentry/junior-plugin-api": file:packages/junior-plugin-api + "@sinclair/typebox": 0.34.49 drizzle-orm: 0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0) zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@cloudflare/workers-types" + - "@electric-sql/pglite" + - "@libsql/client" + - "@libsql/client-wasm" + - "@neondatabase/serverless" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - better-sqlite3 - bun-types - expo-sqlite @@ -9928,29 +15044,29 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior-testing@file:packages/junior-testing': + "@sentry/junior-testing@file:packages/junior-testing": dependencies: - '@electric-sql/pglite': 0.4.6 + "@electric-sql/pglite": 0.4.6 drizzle-orm: 0.45.2(@electric-sql/pglite@0.4.6)(pg@8.21.0) pg: 8.21.0 zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@cloudflare/workers-types" + - "@libsql/client" + - "@libsql/client-wasm" + - "@neondatabase/serverless" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - better-sqlite3 - bun-types - expo-sqlite @@ -9964,29 +15080,29 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior-testing@file:packages/junior-testing(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)': + "@sentry/junior-testing@file:packages/junior-testing(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)": dependencies: - '@electric-sql/pglite': 0.4.6 + "@electric-sql/pglite": 0.4.6 drizzle-orm: 0.45.2(@electric-sql/pglite@0.4.6)(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0) pg: 8.21.0 zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@libsql/client' - - '@libsql/client-wasm' - - '@neondatabase/serverless' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@cloudflare/workers-types" + - "@libsql/client" + - "@libsql/client-wasm" + - "@neondatabase/serverless" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - better-sqlite3 - bun-types - expo-sqlite @@ -10000,24 +15116,24 @@ snapshots: - sql.js - sqlite3 - '@sentry/junior@file:packages/junior': - dependencies: - '@ai-sdk/gateway': 3.0.119(zod@4.4.3) - '@chat-adapter/slack': 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@chat-adapter/state-memory': 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@chat-adapter/state-redis': 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) - '@earendil-works/pi-agent-core': 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) - '@earendil-works/pi-ai': 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) - '@logtape/logtape': 2.1.1 - '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) - '@neondatabase/serverless': 1.1.0 - '@sentry/junior-plugin-api': file:packages/junior-plugin-api - '@sentry/node': 10.53.1 - '@sinclair/typebox': 0.34.49 - '@slack/web-api': 7.16.0 - '@vercel/functions': 3.6.0 - '@vercel/queue': 0.2.0 - '@vercel/sandbox': 2.0.0 + "@sentry/junior@file:packages/junior": + dependencies: + "@ai-sdk/gateway": 3.0.119(zod@4.4.3) + "@chat-adapter/slack": 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) + "@chat-adapter/state-memory": 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) + "@chat-adapter/state-redis": 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) + "@earendil-works/pi-agent-core": 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) + "@earendil-works/pi-ai": 0.74.2(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) + "@logtape/logtape": 2.1.1 + "@modelcontextprotocol/sdk": 1.29.0(zod@4.4.3) + "@neondatabase/serverless": 1.1.0 + "@sentry/junior-plugin-api": file:packages/junior-plugin-api + "@sentry/node": 10.53.1 + "@sinclair/typebox": 0.34.49 + "@slack/web-api": 7.16.0 + "@vercel/functions": 3.6.0 + "@vercel/queue": 0.2.0 + "@vercel/sandbox": 2.0.0 ai: 6.0.190(zod@4.4.3) bash-tool: 1.3.16(@vercel/sandbox@2.0.0)(ai@6.0.190(zod@4.4.3))(just-bash@3.0.1) chat: 4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3) @@ -10032,26 +15148,26 @@ snapshots: yaml: 2.9.0 zod: 4.4.3 transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@aws-sdk/credential-provider-web-identity' - - '@cfworker/json-schema' - - '@cloudflare/workers-types' - - '@electric-sql/pglite' - - '@libsql/client' - - '@libsql/client-wasm' - - '@node-rs/xxhash' - - '@op-engineering/op-sqlite' - - '@opentelemetry/api' - - '@opentelemetry/exporter-trace-otlp-http' - - '@planetscale/database' - - '@prisma/client' - - '@tidbcloud/serverless' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/sql.js' - - '@upstash/redis' - - '@vercel/postgres' - - '@xata.io/client' + - "@aws-sdk/client-rds-data" + - "@aws-sdk/credential-provider-web-identity" + - "@cfworker/json-schema" + - "@cloudflare/workers-types" + - "@electric-sql/pglite" + - "@libsql/client" + - "@libsql/client-wasm" + - "@node-rs/xxhash" + - "@op-engineering/op-sqlite" + - "@opentelemetry/api" + - "@opentelemetry/exporter-trace-otlp-http" + - "@planetscale/database" + - "@prisma/client" + - "@tidbcloud/serverless" + - "@types/better-sqlite3" + - "@types/pg" + - "@types/sql.js" + - "@upstash/redis" + - "@vercel/postgres" + - "@xata.io/client" - bare-abort-controller - better-sqlite3 - bufferutil @@ -10072,188 +15188,188 @@ snapshots: - utf-8-validate - ws - '@sentry/node-core@10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1)': + "@sentry/node-core@10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1)": dependencies: - '@sentry/core': 10.53.1 - '@sentry/opentelemetry': 10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1) + "@sentry/core": 10.53.1 + "@sentry/opentelemetry": 10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1) import-in-the-middle: 3.0.1 optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/sdk-trace-base": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 - '@sentry/node-core@10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))': + "@sentry/node-core@10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))": dependencies: - '@sentry/conventions': 0.12.0 - '@sentry/core': 10.59.0 - '@sentry/opentelemetry': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)) + "@sentry/conventions": 0.12.0 + "@sentry/core": 10.59.0 + "@sentry/opentelemetry": 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)) import-in-the-middle: 3.0.1 optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - - '@sentry/node@10.53.1': - dependencies: - '@fastify/otel': 0.18.0(@opentelemetry/api@1.9.1) - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-amqplib': 0.61.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-connect': 0.57.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-dataloader': 0.31.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-fs': 0.33.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-generic-pool': 0.57.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-graphql': 0.62.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-hapi': 0.60.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-http': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-kafkajs': 0.23.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-knex': 0.58.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-koa': 0.62.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-lru-memoizer': 0.58.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-mongodb': 0.67.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-mongoose': 0.60.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-mysql': 0.60.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-mysql2': 0.60.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-pg': 0.66.0(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation-tedious': 0.33.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@prisma/instrumentation': 7.6.0(@opentelemetry/api@1.9.1) - '@sentry/core': 10.53.1 - '@sentry/node-core': 10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1) - '@sentry/opentelemetry': 10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/sdk-trace-base": 2.7.1(@opentelemetry/api@1.9.1) + + "@sentry/node@10.53.1": + dependencies: + "@fastify/otel": 0.18.0(@opentelemetry/api@1.9.1) + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-amqplib": 0.61.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-connect": 0.57.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-dataloader": 0.31.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-fs": 0.33.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-generic-pool": 0.57.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-graphql": 0.62.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-hapi": 0.60.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-http": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-kafkajs": 0.23.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-knex": 0.58.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-koa": 0.62.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-lru-memoizer": 0.58.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-mongodb": 0.67.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-mongoose": 0.60.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-mysql": 0.60.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-mysql2": 0.60.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-pg": 0.66.0(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation-tedious": 0.33.0(@opentelemetry/api@1.9.1) + "@opentelemetry/sdk-trace-base": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@prisma/instrumentation": 7.6.0(@opentelemetry/api@1.9.1) + "@sentry/core": 10.53.1 + "@sentry/node-core": 10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1) + "@sentry/opentelemetry": 10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1) import-in-the-middle: 3.0.1 transitivePeerDependencies: - - '@opentelemetry/exporter-trace-otlp-http' + - "@opentelemetry/exporter-trace-otlp-http" - supports-color - '@sentry/node@10.59.0': - dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@sentry/core': 10.59.0 - '@sentry/node-core': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)) - '@sentry/opentelemetry': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)) - '@sentry/server-utils': 10.59.0 + "@sentry/node@10.59.0": + dependencies: + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/instrumentation": 0.214.0(@opentelemetry/api@1.9.1) + "@opentelemetry/sdk-trace-base": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@sentry/core": 10.59.0 + "@sentry/node-core": 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)) + "@sentry/opentelemetry": 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1)) + "@sentry/server-utils": 10.59.0 import-in-the-middle: 3.0.1 transitivePeerDependencies: - - '@opentelemetry/exporter-trace-otlp-http' + - "@opentelemetry/exporter-trace-otlp-http" - supports-color - vite - '@sentry/opentelemetry@10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1)': + "@sentry/opentelemetry@10.53.1(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/semantic-conventions@1.41.1)": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/semantic-conventions': 1.41.1 - '@sentry/core': 10.53.1 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/sdk-trace-base": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/semantic-conventions": 1.41.1 + "@sentry/core": 10.53.1 - '@sentry/opentelemetry@10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))': + "@sentry/opentelemetry@10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.7.1(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.7.1(@opentelemetry/api@1.9.1))": dependencies: - '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.7.1(@opentelemetry/api@1.9.1) - '@opentelemetry/sdk-trace-base': 2.7.1(@opentelemetry/api@1.9.1) - '@sentry/conventions': 0.12.0 - '@sentry/core': 10.59.0 + "@opentelemetry/api": 1.9.1 + "@opentelemetry/core": 2.7.1(@opentelemetry/api@1.9.1) + "@opentelemetry/sdk-trace-base": 2.7.1(@opentelemetry/api@1.9.1) + "@sentry/conventions": 0.12.0 + "@sentry/core": 10.59.0 - '@sentry/server-utils@10.59.0': + "@sentry/server-utils@10.59.0": dependencies: - '@apm-js-collab/code-transformer': 0.15.0 - '@apm-js-collab/code-transformer-bundler-plugins': 0.5.0 - '@apm-js-collab/tracing-hooks': 0.10.0 - '@sentry/conventions': 0.12.0 - '@sentry/core': 10.59.0 + "@apm-js-collab/code-transformer": 0.15.0 + "@apm-js-collab/code-transformer-bundler-plugins": 0.5.0 + "@apm-js-collab/tracing-hooks": 0.10.0 + "@sentry/conventions": 0.12.0 + "@sentry/core": 10.59.0 magic-string: 0.30.21 transitivePeerDependencies: - supports-color - '@sentry/starlight-theme@0.7.0(@astrojs/starlight@0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3))': + "@sentry/starlight-theme@0.7.0(@astrojs/starlight@0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3))": dependencies: - '@astrojs/starlight': 0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3) - '@fontsource-variable/rubik': 5.2.8 - '@fontsource/ibm-plex-mono': 5.2.7 + "@astrojs/starlight": 0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3) + "@fontsource-variable/rubik": 5.2.8 + "@fontsource/ibm-plex-mono": 5.2.7 ultrahtml: 1.6.0 - '@shikijs/core@4.1.0': + "@shikijs/core@4.1.0": dependencies: - '@shikijs/primitive': 4.1.0 - '@shikijs/types': 4.1.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/primitive": 4.1.0 + "@shikijs/types": 4.1.0 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@4.1.0': + "@shikijs/engine-javascript@4.1.0": dependencies: - '@shikijs/types': 4.1.0 - '@shikijs/vscode-textmate': 10.0.2 + "@shikijs/types": 4.1.0 + "@shikijs/vscode-textmate": 10.0.2 oniguruma-to-es: 4.3.6 - '@shikijs/engine-oniguruma@3.23.0': + "@shikijs/engine-oniguruma@3.23.0": dependencies: - '@shikijs/types': 3.23.0 - '@shikijs/vscode-textmate': 10.0.2 + "@shikijs/types": 3.23.0 + "@shikijs/vscode-textmate": 10.0.2 - '@shikijs/engine-oniguruma@4.1.0': + "@shikijs/engine-oniguruma@4.1.0": dependencies: - '@shikijs/types': 4.1.0 - '@shikijs/vscode-textmate': 10.0.2 + "@shikijs/types": 4.1.0 + "@shikijs/vscode-textmate": 10.0.2 - '@shikijs/langs@3.23.0': + "@shikijs/langs@3.23.0": dependencies: - '@shikijs/types': 3.23.0 + "@shikijs/types": 3.23.0 - '@shikijs/langs@4.1.0': + "@shikijs/langs@4.1.0": dependencies: - '@shikijs/types': 4.1.0 + "@shikijs/types": 4.1.0 - '@shikijs/primitive@4.1.0': + "@shikijs/primitive@4.1.0": dependencies: - '@shikijs/types': 4.1.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/types": 4.1.0 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 - '@shikijs/themes@3.23.0': + "@shikijs/themes@3.23.0": dependencies: - '@shikijs/types': 3.23.0 + "@shikijs/types": 3.23.0 - '@shikijs/themes@4.1.0': + "@shikijs/themes@4.1.0": dependencies: - '@shikijs/types': 4.1.0 + "@shikijs/types": 4.1.0 - '@shikijs/types@3.23.0': + "@shikijs/types@3.23.0": dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 - '@shikijs/types@4.1.0': + "@shikijs/types@4.1.0": dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 - '@shikijs/vscode-textmate@10.0.2': {} + "@shikijs/vscode-textmate@10.0.2": {} - '@sinclair/typebox@0.25.24': {} + "@sinclair/typebox@0.25.24": {} - '@sinclair/typebox@0.34.49': {} + "@sinclair/typebox@0.34.49": {} - '@slack/logger@4.0.1': + "@slack/logger@4.0.1": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@slack/socket-mode@2.0.7': + "@slack/socket-mode@2.0.7": dependencies: - '@slack/logger': 4.0.1 - '@slack/web-api': 7.16.0 - '@types/node': 25.9.1 - '@types/ws': 8.18.1 + "@slack/logger": 4.0.1 + "@slack/web-api": 7.16.0 + "@types/node": 25.9.1 + "@types/ws": 8.18.1 eventemitter3: 5.0.4 ws: 8.20.1 transitivePeerDependencies: @@ -10262,14 +15378,14 @@ snapshots: - supports-color - utf-8-validate - '@slack/types@2.21.1': {} + "@slack/types@2.21.1": {} - '@slack/web-api@7.16.0': + "@slack/web-api@7.16.0": dependencies: - '@slack/logger': 4.0.1 - '@slack/types': 2.21.1 - '@types/node': 25.9.1 - '@types/retry': 0.12.0 + "@slack/logger": 4.0.1 + "@slack/types": 2.21.1 + "@types/node": 25.9.1 + "@types/retry": 0.12.0 axios: 1.16.1 eventemitter3: 5.0.4 form-data: 4.0.5 @@ -10282,71 +15398,71 @@ snapshots: - debug - supports-color - '@smithy/core@3.24.4': + "@smithy/core@3.24.4": dependencies: - '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.14.2 + "@aws-crypto/crc32": 5.2.0 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@smithy/credential-provider-imds@4.3.4': + "@smithy/credential-provider-imds@4.3.4": dependencies: - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.4.4': + "@smithy/fetch-http-handler@5.4.4": dependencies: - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@smithy/is-array-buffer@2.2.0': + "@smithy/is-array-buffer@2.2.0": dependencies: tslib: 2.8.1 - '@smithy/node-http-handler@4.7.4': + "@smithy/node-http-handler@4.7.4": dependencies: - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@smithy/signature-v4@5.4.4': + "@smithy/signature-v4@5.4.4": dependencies: - '@smithy/core': 3.24.4 - '@smithy/types': 4.14.2 + "@smithy/core": 3.24.4 + "@smithy/types": 4.14.2 tslib: 2.8.1 - '@smithy/types@4.14.2': + "@smithy/types@4.14.2": dependencies: tslib: 2.8.1 - '@smithy/util-buffer-from@2.2.0': + "@smithy/util-buffer-from@2.2.0": dependencies: - '@smithy/is-array-buffer': 2.2.0 + "@smithy/is-array-buffer": 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@2.3.0': + "@smithy/util-utf8@2.3.0": dependencies: - '@smithy/util-buffer-from': 2.2.0 + "@smithy/util-buffer-from": 2.2.0 tslib: 2.8.1 - '@standard-schema/spec@1.1.0': {} + "@standard-schema/spec@1.1.0": {} - '@standard-schema/utils@0.3.0': {} + "@standard-schema/utils@0.3.0": {} - '@tailwindcss/cli@4.3.0': + "@tailwindcss/cli@4.3.0": dependencies: - '@parcel/watcher': 2.5.6 - '@tailwindcss/node': 4.3.0 - '@tailwindcss/oxide': 4.3.0 + "@parcel/watcher": 2.5.6 + "@tailwindcss/node": 4.3.0 + "@tailwindcss/oxide": 4.3.0 enhanced-resolve: 5.21.0 mri: 1.2.0 picocolors: 1.1.1 tailwindcss: 4.3.0 - '@tailwindcss/node@4.3.0': + "@tailwindcss/node@4.3.0": dependencies: - '@jridgewell/remapping': 2.3.5 + "@jridgewell/remapping": 2.3.5 enhanced-resolve: 5.21.0 jiti: 2.7.0 lightningcss: 1.32.0 @@ -10354,222 +15470,216 @@ snapshots: source-map-js: 1.2.1 tailwindcss: 4.3.0 - '@tailwindcss/oxide-android-arm64@4.3.0': + "@tailwindcss/oxide-android-arm64@4.3.0": optional: true - '@tailwindcss/oxide-darwin-arm64@4.3.0': + "@tailwindcss/oxide-darwin-arm64@4.3.0": optional: true - '@tailwindcss/oxide-darwin-x64@4.3.0': + "@tailwindcss/oxide-darwin-x64@4.3.0": optional: true - '@tailwindcss/oxide-freebsd-x64@4.3.0': + "@tailwindcss/oxide-freebsd-x64@4.3.0": optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0': + "@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0": optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.3.0': + "@tailwindcss/oxide-linux-arm64-gnu@4.3.0": optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.3.0': + "@tailwindcss/oxide-linux-arm64-musl@4.3.0": optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.3.0': + "@tailwindcss/oxide-linux-x64-gnu@4.3.0": optional: true - '@tailwindcss/oxide-linux-x64-musl@4.3.0': + "@tailwindcss/oxide-linux-x64-musl@4.3.0": optional: true - '@tailwindcss/oxide-wasm32-wasi@4.3.0': + "@tailwindcss/oxide-wasm32-wasi@4.3.0": optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.3.0': + "@tailwindcss/oxide-win32-arm64-msvc@4.3.0": optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.3.0': + "@tailwindcss/oxide-win32-x64-msvc@4.3.0": optional: true - '@tailwindcss/oxide@4.3.0': + "@tailwindcss/oxide@4.3.0": optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.3.0 - '@tailwindcss/oxide-darwin-arm64': 4.3.0 - '@tailwindcss/oxide-darwin-x64': 4.3.0 - '@tailwindcss/oxide-freebsd-x64': 4.3.0 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.0 - '@tailwindcss/oxide-linux-arm64-gnu': 4.3.0 - '@tailwindcss/oxide-linux-arm64-musl': 4.3.0 - '@tailwindcss/oxide-linux-x64-gnu': 4.3.0 - '@tailwindcss/oxide-linux-x64-musl': 4.3.0 - '@tailwindcss/oxide-wasm32-wasi': 4.3.0 - '@tailwindcss/oxide-win32-arm64-msvc': 4.3.0 - '@tailwindcss/oxide-win32-x64-msvc': 4.3.0 - - '@tanstack/query-core@5.100.14': {} - - '@tanstack/react-query@5.100.14(react@19.2.6)': - dependencies: - '@tanstack/query-core': 5.100.14 + "@tailwindcss/oxide-android-arm64": 4.3.0 + "@tailwindcss/oxide-darwin-arm64": 4.3.0 + "@tailwindcss/oxide-darwin-x64": 4.3.0 + "@tailwindcss/oxide-freebsd-x64": 4.3.0 + "@tailwindcss/oxide-linux-arm-gnueabihf": 4.3.0 + "@tailwindcss/oxide-linux-arm64-gnu": 4.3.0 + "@tailwindcss/oxide-linux-arm64-musl": 4.3.0 + "@tailwindcss/oxide-linux-x64-gnu": 4.3.0 + "@tailwindcss/oxide-linux-x64-musl": 4.3.0 + "@tailwindcss/oxide-wasm32-wasi": 4.3.0 + "@tailwindcss/oxide-win32-arm64-msvc": 4.3.0 + "@tailwindcss/oxide-win32-x64-msvc": 4.3.0 + + "@tanstack/query-core@5.100.14": {} + + "@tanstack/react-query@5.100.14(react@19.2.6)": + dependencies: + "@tanstack/query-core": 5.100.14 react: 19.2.6 - '@tokenizer/inflate@0.4.1': + "@tokenizer/inflate@0.4.1": dependencies: debug: 4.4.3 token-types: 6.1.2 transitivePeerDependencies: - supports-color - '@tokenizer/token@0.3.0': {} + "@tokenizer/token@0.3.0": {} - '@tootallnate/once@2.0.0': {} + "@tootallnate/once@2.0.0": {} - '@tootallnate/quickjs-emscripten@0.23.0': {} + "@tootallnate/quickjs-emscripten@0.23.0": {} - '@ts-morph/common@0.11.1': + "@ts-morph/common@0.11.1": dependencies: fast-glob: 3.3.3 minimatch: 3.1.5 mkdirp: 1.0.4 path-browserify: 1.0.1 - '@tybys/wasm-util@0.10.2': + "@tybys/wasm-util@0.10.2": dependencies: tslib: 2.8.1 optional: true - '@types/chai@5.2.3': + "@types/chai@5.2.3": dependencies: - '@types/deep-eql': 4.0.2 + "@types/deep-eql": 4.0.2 assertion-error: 2.0.1 - '@types/connect@3.4.38': + "@types/connect@3.4.38": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@types/d3-array@3.2.2': {} + "@types/d3-array@3.2.2": {} - '@types/d3-color@3.1.3': {} + "@types/d3-color@3.1.3": {} - '@types/d3-ease@3.0.2': {} + "@types/d3-ease@3.0.2": {} - '@types/d3-interpolate@3.0.4': + "@types/d3-interpolate@3.0.4": dependencies: - '@types/d3-color': 3.1.3 + "@types/d3-color": 3.1.3 - '@types/d3-path@3.1.1': {} + "@types/d3-path@3.1.1": {} - '@types/d3-scale@4.0.9': + "@types/d3-scale@4.0.9": dependencies: - '@types/d3-time': 3.0.4 + "@types/d3-time": 3.0.4 - '@types/d3-shape@3.1.8': + "@types/d3-shape@3.1.8": dependencies: - '@types/d3-path': 3.1.1 + "@types/d3-path": 3.1.1 - '@types/d3-time@3.0.4': {} + "@types/d3-time@3.0.4": {} - '@types/d3-timer@3.0.2': {} + "@types/d3-timer@3.0.2": {} - '@types/debug@4.1.13': + "@types/debug@4.1.13": dependencies: - '@types/ms': 2.1.0 + "@types/ms": 2.1.0 - '@types/deep-eql@4.0.2': {} + "@types/deep-eql@4.0.2": {} - '@types/estree-jsx@1.0.5': + "@types/estree-jsx@1.0.5": dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 - '@types/estree@1.0.8': {} + "@types/estree@1.0.8": {} - '@types/estree@1.0.9': {} + "@types/estree@1.0.9": {} - '@types/hast@3.0.4': + "@types/hast@3.0.4": dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 - '@types/js-yaml@4.0.9': {} + "@types/js-yaml@4.0.9": {} - '@types/json-schema@7.0.15': {} + "@types/json-schema@7.0.15": {} - '@types/mdast@4.0.4': + "@types/mdast@4.0.4": dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 - '@types/mdx@2.0.13': {} + "@types/mdx@2.0.13": {} - '@types/ms@2.1.0': {} + "@types/ms@2.1.0": {} - '@types/mysql@2.15.27': + "@types/mysql@2.15.27": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@types/nlcst@2.0.3': + "@types/nlcst@2.0.3": dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 - '@types/node@20.11.0': + "@types/node@20.11.0": dependencies: undici-types: 5.26.5 - '@types/node@24.12.4': + "@types/node@24.12.4": dependencies: undici-types: 7.16.0 - '@types/node@25.9.1': - dependencies: - undici-types: 7.24.6 + "@types/node@25.9.1": {} - '@types/pg-pool@2.0.7': + "@types/pg-pool@2.0.7": dependencies: - '@types/pg': 8.15.6 + "@types/pg": 8.15.6 - '@types/pg@8.15.6': - dependencies: - '@types/node': 25.9.1 - pg-protocol: 1.14.0 - pg-types: 2.2.0 + "@types/pg@8.15.6": {} - '@types/react-dom@19.2.3(@types/react@19.2.15)': + "@types/react-dom@19.2.3(@types/react@19.2.15)": dependencies: - '@types/react': 19.2.15 + "@types/react": 19.2.15 - '@types/react@19.2.15': + "@types/react@19.2.15": dependencies: csstype: 3.2.3 - '@types/retry@0.12.0': {} + "@types/retry@0.12.0": {} - '@types/sax@1.2.7': + "@types/sax@1.2.7": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@types/set-cookie-parser@2.4.10': + "@types/set-cookie-parser@2.4.10": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@types/statuses@2.0.6': {} + "@types/statuses@2.0.6": {} - '@types/tedious@4.0.14': + "@types/tedious@4.0.14": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@types/unist@2.0.11': {} + "@types/unist@2.0.11": {} - '@types/unist@3.0.3': {} + "@types/unist@3.0.3": {} - '@types/use-sync-external-store@0.0.6': {} + "@types/use-sync-external-store@0.0.6": {} - '@types/ws@8.18.1': + "@types/ws@8.18.1": dependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 - '@ungap/structured-clone@1.3.1': {} + "@ungap/structured-clone@1.3.1": {} - '@vercel/backends@0.7.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + "@vercel/backends@0.7.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)": dependencies: - '@vercel/build-utils': 13.26.1 - '@vercel/nft': 1.5.0 + "@vercel/build-utils": 13.26.1 + "@vercel/nft": 1.5.0 execa: 3.2.0 fs-extra: 11.1.0 oxc-transform: 0.111.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) @@ -10580,13 +15690,13 @@ snapshots: tsx: 4.21.0 zod: 3.22.4 transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + - "@emnapi/core" + - "@emnapi/runtime" - encoding - rollup - supports-color - '@vercel/blob@2.4.0': + "@vercel/blob@2.4.0": dependencies: async-retry: 1.3.3 is-buffer: 2.0.5 @@ -10594,69 +15704,69 @@ snapshots: throttleit: 2.1.0 undici: 6.25.0 - '@vercel/build-utils@13.26.1': + "@vercel/build-utils@13.26.1": dependencies: - '@vercel/python-analysis': 0.11.1 + "@vercel/python-analysis": 0.11.1 cjs-module-lexer: 1.2.3 es-module-lexer: 1.5.0 - '@vercel/cervel@0.1.7(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + "@vercel/cervel@0.1.7(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)": dependencies: - '@vercel/backends': 0.7.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@vercel/backends": 0.7.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + - "@emnapi/core" + - "@emnapi/runtime" - encoding - rollup - supports-color - '@vercel/cli-config@0.1.2': + "@vercel/cli-config@0.1.2": dependencies: xdg-app-paths: 5.5.1 zod: 4.1.11 - '@vercel/detect-agent@1.2.3': {} + "@vercel/detect-agent@1.2.3": {} - '@vercel/elysia@0.1.80': + "@vercel/elysia@0.1.80": dependencies: - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 transitivePeerDependencies: - encoding - rollup - supports-color - '@vercel/error-utils@2.1.0': {} + "@vercel/error-utils@2.1.0": {} - '@vercel/express@0.1.90(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + "@vercel/express@0.1.90(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)": dependencies: - '@vercel/cervel': 0.1.7(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - '@vercel/nft': 1.5.0 - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/cervel": 0.1.7(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@vercel/nft": 1.5.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 fs-extra: 11.1.0 path-to-regexp: 8.3.0 ts-morph: 12.0.0 zod: 3.22.4 transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + - "@emnapi/core" + - "@emnapi/runtime" - encoding - rollup - supports-color - '@vercel/fastify@0.1.83': + "@vercel/fastify@0.1.83": dependencies: - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 transitivePeerDependencies: - encoding - rollup - supports-color - '@vercel/fun@1.3.0': + "@vercel/fun@1.3.0": dependencies: - '@tootallnate/once': 2.0.0 + "@tootallnate/once": 2.0.0 async-listen: 1.2.0 debug: 4.3.4 generic-pool: 3.4.2 @@ -10678,38 +15788,38 @@ snapshots: - encoding - supports-color - '@vercel/functions@3.6.0': + "@vercel/functions@3.6.0": dependencies: - '@vercel/oidc': 3.4.1 + "@vercel/oidc": 3.4.1 - '@vercel/gatsby-plugin-vercel-analytics@1.0.11': + "@vercel/gatsby-plugin-vercel-analytics@1.0.11": dependencies: web-vitals: 0.2.4 - '@vercel/gatsby-plugin-vercel-builder@2.2.7': + "@vercel/gatsby-plugin-vercel-builder@2.2.7": dependencies: - '@sinclair/typebox': 0.25.24 - '@vercel/build-utils': 13.26.1 + "@sinclair/typebox": 0.25.24 + "@vercel/build-utils": 13.26.1 esbuild: 0.27.0 etag: 1.8.1 fs-extra: 11.1.0 - '@vercel/go@3.7.1': {} + "@vercel/go@3.7.1": {} - '@vercel/h3@0.1.89': + "@vercel/h3@0.1.89": dependencies: - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 transitivePeerDependencies: - encoding - rollup - supports-color - '@vercel/hono@0.2.83': + "@vercel/hono@0.2.83": dependencies: - '@vercel/nft': 1.5.0 - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/nft": 1.5.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 fs-extra: 11.1.0 path-to-regexp: 8.3.0 ts-morph: 12.0.0 @@ -10719,41 +15829,41 @@ snapshots: - rollup - supports-color - '@vercel/hydrogen@1.3.7': + "@vercel/hydrogen@1.3.7": dependencies: - '@vercel/static-config': 3.3.0 + "@vercel/static-config": 3.3.0 ts-morph: 12.0.0 - '@vercel/koa@0.1.63': + "@vercel/koa@0.1.63": dependencies: - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 transitivePeerDependencies: - encoding - rollup - supports-color - '@vercel/nestjs@0.2.84': + "@vercel/nestjs@0.2.84": dependencies: - '@vercel/node': 5.8.4 - '@vercel/static-config': 3.3.0 + "@vercel/node": 5.8.4 + "@vercel/static-config": 3.3.0 transitivePeerDependencies: - encoding - rollup - supports-color - '@vercel/next@4.17.3': + "@vercel/next@4.17.3": dependencies: - '@vercel/nft': 1.5.0 + "@vercel/nft": 1.5.0 transitivePeerDependencies: - encoding - rollup - supports-color - '@vercel/nft@1.5.0': + "@vercel/nft@1.5.0": dependencies: - '@mapbox/node-pre-gyp': 2.0.3 - '@rollup/pluginutils': 5.3.0 + "@mapbox/node-pre-gyp": 2.0.3 + "@rollup/pluginutils": 5.3.0 acorn: 8.16.0 acorn-import-attributes: 1.9.5(acorn@8.16.0) async-sema: 3.1.1 @@ -10769,16 +15879,16 @@ snapshots: - rollup - supports-color - '@vercel/node@5.8.4': + "@vercel/node@5.8.4": dependencies: - '@edge-runtime/node-utils': 2.3.0 - '@edge-runtime/primitives': 4.1.0 - '@edge-runtime/vm': 3.2.0 - '@types/node': 20.11.0 - '@vercel/build-utils': 13.26.1 - '@vercel/error-utils': 2.1.0 - '@vercel/nft': 1.5.0 - '@vercel/static-config': 3.3.0 + "@edge-runtime/node-utils": 2.3.0 + "@edge-runtime/primitives": 4.1.0 + "@edge-runtime/vm": 3.2.0 + "@types/node": 20.11.0 + "@vercel/build-utils": 13.26.1 + "@vercel/error-utils": 2.1.0 + "@vercel/nft": 1.5.0 + "@vercel/static-config": 3.3.0 async-listen: 3.0.0 cjs-module-lexer: 1.2.3 edge-runtime: 2.5.9 @@ -10798,37 +15908,37 @@ snapshots: - rollup - supports-color - '@vercel/oidc@3.2.0': {} + "@vercel/oidc@3.2.0": {} - '@vercel/oidc@3.4.1': {} + "@vercel/oidc@3.4.1": {} - '@vercel/prepare-flags-definitions@0.2.1': {} + "@vercel/prepare-flags-definitions@0.2.1": {} - '@vercel/python-analysis@0.11.1': + "@vercel/python-analysis@0.11.1": dependencies: - '@bytecodealliance/preview2-shim': 0.17.6 - '@renovatebot/pep440': 4.2.1 + "@bytecodealliance/preview2-shim": 0.17.6 + "@renovatebot/pep440": 4.2.1 fs-extra: 11.1.1 js-yaml: 4.1.1 minimatch: 10.1.1 smol-toml: 1.5.2 zod: 3.22.4 - '@vercel/python@6.43.1': + "@vercel/python@6.43.1": dependencies: - '@vercel/python-analysis': 0.11.1 + "@vercel/python-analysis": 0.11.1 - '@vercel/queue@0.2.0': + "@vercel/queue@0.2.0": dependencies: - '@vercel/oidc': 3.4.1 + "@vercel/oidc": 3.4.1 minimatch: 10.2.5 mixpart: 0.0.6 picocolors: 1.1.1 - '@vercel/redwood@2.4.13': + "@vercel/redwood@2.4.13": dependencies: - '@vercel/nft': 1.5.0 - '@vercel/static-config': 3.3.0 + "@vercel/nft": 1.5.0 + "@vercel/static-config": 3.3.0 semver: 6.3.1 ts-morph: 12.0.0 transitivePeerDependencies: @@ -10836,11 +15946,11 @@ snapshots: - rollup - supports-color - '@vercel/remix-builder@5.8.2': + "@vercel/remix-builder@5.8.2": dependencies: - '@vercel/error-utils': 2.1.0 - '@vercel/nft': 1.5.0 - '@vercel/static-config': 3.3.0 + "@vercel/error-utils": 2.1.0 + "@vercel/nft": 1.5.0 + "@vercel/static-config": 3.3.0 path-to-regexp: 6.1.0 path-to-regexp-updated: path-to-regexp@6.3.0 ts-morph: 12.0.0 @@ -10849,16 +15959,16 @@ snapshots: - rollup - supports-color - '@vercel/ruby@2.3.2': {} + "@vercel/ruby@2.3.2": {} - '@vercel/rust@1.2.0': + "@vercel/rust@1.2.0": dependencies: execa: 5.1.1 smol-toml: 1.5.2 - '@vercel/sandbox@1.9.0': + "@vercel/sandbox@1.9.0": dependencies: - '@vercel/oidc': 3.2.0 + "@vercel/oidc": 3.2.0 async-retry: 1.3.3 jsonlines: 0.1.1 ms: 2.1.3 @@ -10871,10 +15981,10 @@ snapshots: - bare-abort-controller - react-native-b4a - '@vercel/sandbox@2.0.0': + "@vercel/sandbox@2.0.0": dependencies: - '@vercel/oidc': 3.2.0 - '@workflow/serde': 4.1.0-beta.2 + "@vercel/oidc": 3.2.0 + "@workflow/serde": 4.1.0-beta.2 async-retry: 1.3.3 jose: 6.2.3 jsonlines: 0.1.1 @@ -10888,31 +15998,31 @@ snapshots: - bare-abort-controller - react-native-b4a - '@vercel/static-build@2.9.30': + "@vercel/static-build@2.9.30": dependencies: - '@vercel/gatsby-plugin-vercel-analytics': 1.0.11 - '@vercel/gatsby-plugin-vercel-builder': 2.2.7 - '@vercel/static-config': 3.3.0 + "@vercel/gatsby-plugin-vercel-analytics": 1.0.11 + "@vercel/gatsby-plugin-vercel-builder": 2.2.7 + "@vercel/static-config": 3.3.0 ts-morph: 12.0.0 - '@vercel/static-config@3.3.0': + "@vercel/static-config@3.3.0": dependencies: ajv: 8.6.3 json-schema-to-ts: 1.6.4 ts-morph: 12.0.0 - '@vitest-evals/core@0.13.1': + "@vitest-evals/core@0.13.1": dependencies: zod: 4.4.3 - '@vitest-evals/report-ui@0.13.1': + "@vitest-evals/report-ui@0.13.1": dependencies: - '@vitest-evals/core': 0.13.1 + "@vitest-evals/core": 0.13.1 - '@vitest/coverage-v8@4.1.7(vitest@4.1.7)': + "@vitest/coverage-v8@4.1.7(vitest@4.1.7)": dependencies: - '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.7 + "@bcoe/v8-coverage": 1.0.2 + "@vitest/utils": 4.1.7 ast-v8-to-istanbul: 1.0.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -10923,74 +16033,74 @@ snapshots: tinyrainbow: 3.1.0 vitest: 4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(jiti@2.7.0)(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(tsx@4.22.3)(yaml@2.9.0) - '@vitest/expect@4.1.7': + "@vitest/expect@4.1.7": dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + "@standard-schema/spec": 1.1.0 + "@types/chai": 5.2.3 + "@vitest/spy": 4.1.7 + "@vitest/utils": 4.1.7 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.7(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(tsx@4.22.3)(yaml@2.9.0))': + "@vitest/mocker@4.1.7(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(tsx@4.22.3)(yaml@2.9.0))": dependencies: - '@vitest/spy': 4.1.7 + "@vitest/spy": 4.1.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: msw: 2.14.6(@types/node@25.9.1)(typescript@6.0.3) vite: 8.0.14(@types/node@25.9.1)(jiti@2.7.0)(tsx@4.22.3)(yaml@2.9.0) - '@vitest/mocker@4.1.7(vite@8.0.14(@types/node@25.9.1)(tsx@4.22.3))': + "@vitest/mocker@4.1.7(vite@8.0.14(@types/node@25.9.1)(tsx@4.22.3))": dependencies: - '@vitest/spy': 4.1.7 + "@vitest/spy": 4.1.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: vite: 8.0.14(@types/node@25.9.1)(tsx@4.22.3) - '@vitest/pretty-format@4.1.7': + "@vitest/pretty-format@4.1.7": dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.7': + "@vitest/runner@4.1.7": dependencies: - '@vitest/utils': 4.1.7 + "@vitest/utils": 4.1.7 pathe: 2.0.3 - '@vitest/snapshot@4.1.7': + "@vitest/snapshot@4.1.7": dependencies: - '@vitest/pretty-format': 4.1.7 - '@vitest/utils': 4.1.7 + "@vitest/pretty-format": 4.1.7 + "@vitest/utils": 4.1.7 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.7': {} + "@vitest/spy@4.1.7": {} - '@vitest/utils@4.1.7': + "@vitest/utils@4.1.7": dependencies: - '@vitest/pretty-format': 4.1.7 + "@vitest/pretty-format": 4.1.7 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@volar/kit@2.4.28(typescript@6.0.3)': + "@volar/kit@2.4.28(typescript@6.0.3)": dependencies: - '@volar/language-service': 2.4.28 - '@volar/typescript': 2.4.28 + "@volar/language-service": 2.4.28 + "@volar/typescript": 2.4.28 typesafe-path: 0.2.2 typescript: 6.0.3 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/language-core@2.4.28': + "@volar/language-core@2.4.28": dependencies: - '@volar/source-map': 2.4.28 + "@volar/source-map": 2.4.28 - '@volar/language-server@2.4.28': + "@volar/language-server@2.4.28": dependencies: - '@volar/language-core': 2.4.28 - '@volar/language-service': 2.4.28 - '@volar/typescript': 2.4.28 + "@volar/language-core": 2.4.28 + "@volar/language-service": 2.4.28 + "@volar/typescript": 2.4.28 path-browserify: 1.0.1 request-light: 0.7.0 vscode-languageserver: 9.0.1 @@ -10998,22 +16108,22 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/language-service@2.4.28': + "@volar/language-service@2.4.28": dependencies: - '@volar/language-core': 2.4.28 + "@volar/language-core": 2.4.28 vscode-languageserver-protocol: 3.17.5 vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 - '@volar/source-map@2.4.28': {} + "@volar/source-map@2.4.28": {} - '@volar/typescript@2.4.28': + "@volar/typescript@2.4.28": dependencies: - '@volar/language-core': 2.4.28 + "@volar/language-core": 2.4.28 path-browserify: 1.0.1 vscode-uri: 3.1.0 - '@vscode/emmet-helper@2.11.0': + "@vscode/emmet-helper@2.11.0": dependencies: emmet: 2.4.11 jsonc-parser: 2.3.1 @@ -11021,9 +16131,9 @@ snapshots: vscode-languageserver-types: 3.17.5 vscode-uri: 3.1.0 - '@vscode/l10n@0.0.18': {} + "@vscode/l10n@0.0.18": {} - '@workflow/serde@4.1.0-beta.2': {} + "@workflow/serde@4.1.0-beta.2": {} abbrev@3.0.1: {} @@ -11064,10 +16174,10 @@ snapshots: ai@6.0.190(zod@4.4.3): dependencies: - '@ai-sdk/gateway': 3.0.119(zod@4.4.3) - '@ai-sdk/provider': 3.0.10 - '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) - '@opentelemetry/api': 1.9.1 + "@ai-sdk/gateway": 3.0.119(zod@4.4.3) + "@ai-sdk/provider": 3.0.10 + "@ai-sdk/provider-utils": 4.0.27(zod@4.4.3) + "@opentelemetry/api": 1.9.1 zod: 4.4.3 ajv-draft-04@1.0.0(ajv@8.20.0): @@ -11092,12 +16202,20 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 + ansi-escapes@7.3.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} + ansi-regex@6.2.2: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + any-promise@1.3.0: {} anymatch@3.1.3: @@ -11123,7 +16241,7 @@ snapshots: ast-v8-to-istanbul@1.0.3: dependencies: - '@jridgewell/trace-mapping': 0.3.31 + "@jridgewell/trace-mapping": 0.3.31 estree-walker: 3.0.3 js-tokens: 10.0.0 @@ -11136,14 +16254,14 @@ snapshots: astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0): dependencies: - '@astrojs/compiler': 4.0.0 - '@astrojs/internal-helpers': 0.9.1 - '@astrojs/markdown-remark': 7.1.2 - '@astrojs/telemetry': 3.3.2 - '@capsizecss/unpack': 4.0.0 - '@clack/prompts': 1.4.0 - '@oslojs/encoding': 1.1.0 - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + "@astrojs/compiler": 4.0.0 + "@astrojs/internal-helpers": 0.9.1 + "@astrojs/markdown-remark": 7.1.2 + "@astrojs/telemetry": 3.3.2 + "@capsizecss/unpack": 4.0.0 + "@clack/prompts": 1.4.0 + "@oslojs/encoding": 1.1.0 + "@rollup/pluginutils": 5.3.0(rollup@4.60.4) aria-query: 5.3.2 axobject-query: 4.1.0 ci-info: 4.4.0 @@ -11194,21 +16312,21 @@ snapshots: optionalDependencies: sharp: 0.34.5 transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@types/node' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' + - "@azure/app-configuration" + - "@azure/cosmos" + - "@azure/data-tables" + - "@azure/identity" + - "@azure/keyvault-secrets" + - "@azure/storage-blob" + - "@capacitor/preferences" + - "@deno/kv" + - "@netlify/blobs" + - "@planetscale/database" + - "@types/node" + - "@upstash/redis" + - "@vercel/blob" + - "@vercel/functions" + - "@vercel/kv" - aws4fetch - db0 - idb-keyval @@ -11272,7 +16390,7 @@ snapshots: yaml: 2.9.0 zod: 3.25.76 optionalDependencies: - '@vercel/sandbox': 2.0.0 + "@vercel/sandbox": 2.0.0 just-bash: 3.0.1 basic-ftp@5.3.1: {} @@ -11287,17 +16405,17 @@ snapshots: better-auth@1.6.11(drizzle-kit@0.31.10)(pg@8.21.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(vitest@4.1.7): dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/drizzle-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/kysely-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17) - '@better-auth/memory-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/mongo-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/prisma-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/telemetry': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 - '@noble/ciphers': 2.2.0 - '@noble/hashes': 2.2.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/drizzle-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/kysely-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17) + "@better-auth/memory-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/mongo-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/prisma-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/telemetry": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 + "@noble/ciphers": 2.2.0 + "@noble/hashes": 2.2.0 better-call: 1.3.5(zod@4.4.3) defu: 6.1.7 jose: 6.2.3 @@ -11311,22 +16429,22 @@ snapshots: react-dom: 19.2.6(react@19.2.6) vitest: 4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(tsx@4.22.3) transitivePeerDependencies: - - '@cloudflare/workers-types' - - '@opentelemetry/api' + - "@cloudflare/workers-types" + - "@opentelemetry/api" better-auth@1.6.11(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - '@better-auth/core': 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) - '@better-auth/drizzle-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/kysely-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17) - '@better-auth/memory-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/mongo-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/prisma-adapter': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) - '@better-auth/telemetry': 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 - '@noble/ciphers': 2.2.0 - '@noble/hashes': 2.2.0 + "@better-auth/core": 1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0) + "@better-auth/drizzle-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/kysely-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(kysely@0.28.17) + "@better-auth/memory-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/mongo-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/prisma-adapter": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0) + "@better-auth/telemetry": 1.6.11(@better-auth/core@1.6.11(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21)(better-call@1.3.5(zod@4.4.3))(jose@6.2.3)(kysely@0.28.17)(nanostores@1.3.0))(@better-auth/utils@0.4.0)(@better-fetch/fetch@1.1.21) + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 + "@noble/ciphers": 2.2.0 + "@noble/hashes": 2.2.0 better-call: 1.3.5(zod@4.4.3) defu: 6.1.7 jose: 6.2.3 @@ -11337,13 +16455,13 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) transitivePeerDependencies: - - '@cloudflare/workers-types' - - '@opentelemetry/api' + - "@cloudflare/workers-types" + - "@opentelemetry/api" better-call@1.3.5(zod@4.4.3): dependencies: - '@better-auth/utils': 0.4.0 - '@better-fetch/fetch': 1.1.21 + "@better-auth/utils": 0.4.0 + "@better-fetch/fetch": 1.1.21 rou3: 0.7.12 set-cookie-parser: 3.1.0 optionalDependencies: @@ -11445,7 +16563,7 @@ snapshots: chat@4.29.0(ai@6.0.190(zod@4.4.3))(zod@4.4.3): dependencies: - '@workflow/serde': 4.1.0-beta.2 + "@workflow/serde": 4.1.0-beta.2 mdast-util-to-string: 4.0.0 remark-gfm: 4.0.1 remark-parse: 11.0.0 @@ -11481,6 +16599,15 @@ snapshots: cjs-module-lexer@2.2.0: {} + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-truncate@5.2.0: + dependencies: + slice-ansi: 8.0.0 + string-width: 8.2.1 + cli-width@4.1.0: {} cliui@8.0.1: @@ -11737,8 +16864,8 @@ snapshots: drizzle-kit@0.31.10: dependencies: - '@drizzle-team/brocli': 0.10.2 - '@esbuild-kit/esm-loader': 2.6.5 + "@drizzle-team/brocli": 0.10.2 + "@esbuild-kit/esm-loader": 2.6.5 esbuild: 0.25.12 tsx: 4.22.3 @@ -11746,39 +16873,39 @@ snapshots: drizzle-orm@0.45.2(@electric-sql/pglite@0.4.6)(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0): optionalDependencies: - '@electric-sql/pglite': 0.4.6 - '@neondatabase/serverless': 1.1.0 - '@types/pg': 8.15.6 + "@electric-sql/pglite": 0.4.6 + "@neondatabase/serverless": 1.1.0 + "@types/pg": 8.15.6 pg: 8.21.0 drizzle-orm@0.45.2(@electric-sql/pglite@0.4.6)(@types/pg@8.15.6)(pg@8.21.0): optionalDependencies: - '@electric-sql/pglite': 0.4.6 - '@types/pg': 8.15.6 + "@electric-sql/pglite": 0.4.6 + "@types/pg": 8.15.6 pg: 8.21.0 drizzle-orm@0.45.2(@electric-sql/pglite@0.4.6)(pg@8.21.0): optionalDependencies: - '@electric-sql/pglite': 0.4.6 + "@electric-sql/pglite": 0.4.6 pg: 8.21.0 drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1): optionalDependencies: - '@neondatabase/serverless': 1.1.0 - '@types/pg': 8.15.6 + "@neondatabase/serverless": 1.1.0 + "@types/pg": 8.15.6 kysely: 0.28.17 pg: 8.21.0 sql.js: 1.14.1 drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(pg@8.21.0): optionalDependencies: - '@neondatabase/serverless': 1.1.0 - '@types/pg': 8.15.6 + "@neondatabase/serverless": 1.1.0 + "@types/pg": 8.15.6 pg: 8.21.0 drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(pg@8.21.0): optionalDependencies: - '@neondatabase/serverless': 1.1.0 + "@neondatabase/serverless": 1.1.0 pg: 8.21.0 dset@3.1.4: {} @@ -11795,9 +16922,9 @@ snapshots: edge-runtime@2.5.9: dependencies: - '@edge-runtime/format': 2.2.1 - '@edge-runtime/ponyfill': 2.4.2 - '@edge-runtime/vm': 3.2.0 + "@edge-runtime/format": 2.2.1 + "@edge-runtime/ponyfill": 2.4.2 + "@edge-runtime/vm": 3.2.0 async-listen: 3.0.1 mri: 1.2.0 picocolors: 1.0.0 @@ -11809,8 +16936,10 @@ snapshots: emmet@2.4.11: dependencies: - '@emmetio/abbreviation': 2.3.3 - '@emmetio/css-abbreviation': 2.1.8 + "@emmetio/abbreviation": 2.3.3 + "@emmetio/css-abbreviation": 2.1.8 + + emoji-regex@10.6.0: {} emoji-regex@8.0.0: {} @@ -11847,7 +16976,9 @@ snapshots: httpxy: 0.5.3 srvx: 0.11.16 optionalDependencies: - '@vercel/queue': 0.2.0 + "@vercel/queue": 0.2.0 + + environment@1.1.0: {} es-define-property@1.0.1: {} @@ -11874,129 +17005,158 @@ snapshots: esast-util-from-estree@2.0.0: dependencies: - '@types/estree-jsx': 1.0.5 + "@types/estree-jsx": 1.0.5 devlop: 1.1.0 estree-util-visit: 2.0.0 unist-util-position-from-estree: 2.0.0 esast-util-from-js@2.0.1: dependencies: - '@types/estree-jsx': 1.0.5 + "@types/estree-jsx": 1.0.5 acorn: 8.16.0 esast-util-from-estree: 2.0.0 vfile-message: 4.0.3 esbuild@0.18.20: optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 + "@esbuild/android-arm": 0.18.20 + "@esbuild/android-arm64": 0.18.20 + "@esbuild/android-x64": 0.18.20 + "@esbuild/darwin-arm64": 0.18.20 + "@esbuild/darwin-x64": 0.18.20 + "@esbuild/freebsd-arm64": 0.18.20 + "@esbuild/freebsd-x64": 0.18.20 + "@esbuild/linux-arm": 0.18.20 + "@esbuild/linux-arm64": 0.18.20 + "@esbuild/linux-ia32": 0.18.20 + "@esbuild/linux-loong64": 0.18.20 + "@esbuild/linux-mips64el": 0.18.20 + "@esbuild/linux-ppc64": 0.18.20 + "@esbuild/linux-riscv64": 0.18.20 + "@esbuild/linux-s390x": 0.18.20 + "@esbuild/linux-x64": 0.18.20 + "@esbuild/netbsd-x64": 0.18.20 + "@esbuild/openbsd-x64": 0.18.20 + "@esbuild/sunos-x64": 0.18.20 + "@esbuild/win32-arm64": 0.18.20 + "@esbuild/win32-ia32": 0.18.20 + "@esbuild/win32-x64": 0.18.20 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 + "@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 esbuild@0.27.0: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.0 - '@esbuild/android-arm': 0.27.0 - '@esbuild/android-arm64': 0.27.0 - '@esbuild/android-x64': 0.27.0 - '@esbuild/darwin-arm64': 0.27.0 - '@esbuild/darwin-x64': 0.27.0 - '@esbuild/freebsd-arm64': 0.27.0 - '@esbuild/freebsd-x64': 0.27.0 - '@esbuild/linux-arm': 0.27.0 - '@esbuild/linux-arm64': 0.27.0 - '@esbuild/linux-ia32': 0.27.0 - '@esbuild/linux-loong64': 0.27.0 - '@esbuild/linux-mips64el': 0.27.0 - '@esbuild/linux-ppc64': 0.27.0 - '@esbuild/linux-riscv64': 0.27.0 - '@esbuild/linux-s390x': 0.27.0 - '@esbuild/linux-x64': 0.27.0 - '@esbuild/netbsd-arm64': 0.27.0 - '@esbuild/netbsd-x64': 0.27.0 - '@esbuild/openbsd-arm64': 0.27.0 - '@esbuild/openbsd-x64': 0.27.0 - '@esbuild/openharmony-arm64': 0.27.0 - '@esbuild/sunos-x64': 0.27.0 - '@esbuild/win32-arm64': 0.27.0 - '@esbuild/win32-ia32': 0.27.0 - '@esbuild/win32-x64': 0.27.0 + "@esbuild/aix-ppc64": 0.27.0 + "@esbuild/android-arm": 0.27.0 + "@esbuild/android-arm64": 0.27.0 + "@esbuild/android-x64": 0.27.0 + "@esbuild/darwin-arm64": 0.27.0 + "@esbuild/darwin-x64": 0.27.0 + "@esbuild/freebsd-arm64": 0.27.0 + "@esbuild/freebsd-x64": 0.27.0 + "@esbuild/linux-arm": 0.27.0 + "@esbuild/linux-arm64": 0.27.0 + "@esbuild/linux-ia32": 0.27.0 + "@esbuild/linux-loong64": 0.27.0 + "@esbuild/linux-mips64el": 0.27.0 + "@esbuild/linux-ppc64": 0.27.0 + "@esbuild/linux-riscv64": 0.27.0 + "@esbuild/linux-s390x": 0.27.0 + "@esbuild/linux-x64": 0.27.0 + "@esbuild/netbsd-arm64": 0.27.0 + "@esbuild/netbsd-x64": 0.27.0 + "@esbuild/openbsd-arm64": 0.27.0 + "@esbuild/openbsd-x64": 0.27.0 + "@esbuild/openharmony-arm64": 0.27.0 + "@esbuild/sunos-x64": 0.27.0 + "@esbuild/win32-arm64": 0.27.0 + "@esbuild/win32-ia32": 0.27.0 + "@esbuild/win32-x64": 0.27.0 esbuild@0.27.7: optionalDependencies: - '@esbuild/aix-ppc64': 0.27.7 - '@esbuild/android-arm': 0.27.7 - '@esbuild/android-arm64': 0.27.7 - '@esbuild/android-x64': 0.27.7 - '@esbuild/darwin-arm64': 0.27.7 - '@esbuild/darwin-x64': 0.27.7 - '@esbuild/freebsd-arm64': 0.27.7 - '@esbuild/freebsd-x64': 0.27.7 - '@esbuild/linux-arm': 0.27.7 - '@esbuild/linux-arm64': 0.27.7 - '@esbuild/linux-ia32': 0.27.7 - '@esbuild/linux-loong64': 0.27.7 - '@esbuild/linux-mips64el': 0.27.7 - '@esbuild/linux-ppc64': 0.27.7 - '@esbuild/linux-riscv64': 0.27.7 - '@esbuild/linux-s390x': 0.27.7 - '@esbuild/linux-x64': 0.27.7 - '@esbuild/netbsd-arm64': 0.27.7 - '@esbuild/netbsd-x64': 0.27.7 - '@esbuild/openbsd-arm64': 0.27.7 - '@esbuild/openbsd-x64': 0.27.7 - '@esbuild/openharmony-arm64': 0.27.7 - '@esbuild/sunos-x64': 0.27.7 - '@esbuild/win32-arm64': 0.27.7 - '@esbuild/win32-ia32': 0.27.7 - '@esbuild/win32-x64': 0.27.7 + "@esbuild/aix-ppc64": 0.27.7 + "@esbuild/android-arm": 0.27.7 + "@esbuild/android-arm64": 0.27.7 + "@esbuild/android-x64": 0.27.7 + "@esbuild/darwin-arm64": 0.27.7 + "@esbuild/darwin-x64": 0.27.7 + "@esbuild/freebsd-arm64": 0.27.7 + "@esbuild/freebsd-x64": 0.27.7 + "@esbuild/linux-arm": 0.27.7 + "@esbuild/linux-arm64": 0.27.7 + "@esbuild/linux-ia32": 0.27.7 + "@esbuild/linux-loong64": 0.27.7 + "@esbuild/linux-mips64el": 0.27.7 + "@esbuild/linux-ppc64": 0.27.7 + "@esbuild/linux-riscv64": 0.27.7 + "@esbuild/linux-s390x": 0.27.7 + "@esbuild/linux-x64": 0.27.7 + "@esbuild/netbsd-arm64": 0.27.7 + "@esbuild/netbsd-x64": 0.27.7 + "@esbuild/openbsd-arm64": 0.27.7 + "@esbuild/openbsd-x64": 0.27.7 + "@esbuild/openharmony-arm64": 0.27.7 + "@esbuild/sunos-x64": 0.27.7 + "@esbuild/win32-arm64": 0.27.7 + "@esbuild/win32-ia32": 0.27.7 + "@esbuild/win32-x64": 0.27.7 + + esbuild@0.28.1: + optionalDependencies: + "@esbuild/aix-ppc64": 0.28.1 + "@esbuild/android-arm": 0.28.1 + "@esbuild/android-arm64": 0.28.1 + "@esbuild/android-x64": 0.28.1 + "@esbuild/darwin-arm64": 0.28.1 + "@esbuild/darwin-x64": 0.28.1 + "@esbuild/freebsd-arm64": 0.28.1 + "@esbuild/freebsd-x64": 0.28.1 + "@esbuild/linux-arm": 0.28.1 + "@esbuild/linux-arm64": 0.28.1 + "@esbuild/linux-ia32": 0.28.1 + "@esbuild/linux-loong64": 0.28.1 + "@esbuild/linux-mips64el": 0.28.1 + "@esbuild/linux-ppc64": 0.28.1 + "@esbuild/linux-riscv64": 0.28.1 + "@esbuild/linux-s390x": 0.28.1 + "@esbuild/linux-x64": 0.28.1 + "@esbuild/netbsd-arm64": 0.28.1 + "@esbuild/netbsd-x64": 0.28.1 + "@esbuild/openbsd-arm64": 0.28.1 + "@esbuild/openbsd-x64": 0.28.1 + "@esbuild/openharmony-arm64": 0.28.1 + "@esbuild/sunos-x64": 0.28.1 + "@esbuild/win32-arm64": 0.28.1 + "@esbuild/win32-ia32": 0.28.1 + "@esbuild/win32-x64": 0.28.1 escalade@3.2.0: {} @@ -12022,11 +17182,11 @@ snapshots: estree-util-attach-comments@3.0.0: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 estree-util-build-jsx@3.0.1: dependencies: - '@types/estree-jsx': 1.0.5 + "@types/estree-jsx": 1.0.5 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 estree-walker: 3.0.3 @@ -12035,25 +17195,25 @@ snapshots: estree-util-scope@1.0.0: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 devlop: 1.1.0 estree-util-to-js@2.0.0: dependencies: - '@types/estree-jsx': 1.0.5 + "@types/estree-jsx": 1.0.5 astring: 1.9.0 source-map: 0.7.6 estree-util-visit@2.0.0: dependencies: - '@types/estree-jsx': 1.0.5 - '@types/unist': 3.0.3 + "@types/estree-jsx": 1.0.5 + "@types/unist": 3.0.3 estree-walker@2.0.2: {} estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 esutils@2.0.3: {} @@ -12147,10 +17307,10 @@ snapshots: expressive-code@0.42.0: dependencies: - '@expressive-code/core': 0.42.0 - '@expressive-code/plugin-frames': 0.42.0 - '@expressive-code/plugin-shiki': 0.42.0 - '@expressive-code/plugin-text-markers': 0.42.0 + "@expressive-code/core": 0.42.0 + "@expressive-code/plugin-frames": 0.42.0 + "@expressive-code/plugin-shiki": 0.42.0 + "@expressive-code/plugin-text-markers": 0.42.0 exsolve@1.0.8: {} @@ -12162,8 +17322,8 @@ snapshots: fast-glob@3.3.3: dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 + "@nodelib/fs.stat": 2.0.5 + "@nodelib/fs.walk": 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 micromatch: 4.0.8 @@ -12187,14 +17347,14 @@ snapshots: fast-xml-parser@5.7.3: dependencies: - '@nodable/entities': 2.1.0 + "@nodable/entities": 2.1.0 fast-xml-builder: 1.2.0 path-expression-matcher: 1.5.0 strnum: 2.3.0 fast-xml-parser@5.8.0: dependencies: - '@nodable/entities': 2.1.0 + "@nodable/entities": 2.1.0 fast-xml-builder: 1.2.0 path-expression-matcher: 1.5.0 strnum: 2.3.0 @@ -12219,7 +17379,7 @@ snapshots: file-type@21.3.4: dependencies: - '@tokenizer/inflate': 0.4.1 + "@tokenizer/inflate": 0.4.1 strtok3: 10.3.5 token-types: 6.1.2 uint8array-extras: 1.5.0 @@ -12294,6 +17454,9 @@ snapshots: jsonfile: 6.2.1 universalify: 2.0.1 + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -12319,6 +17482,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.6.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -12430,12 +17595,12 @@ snapshots: hast-util-embedded@3.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-is-element: 3.0.0 hast-util-format@1.1.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-embedded: 3.0.0 hast-util-minify-whitespace: 1.0.1 hast-util-phrasing: 3.0.1 @@ -12445,7 +17610,7 @@ snapshots: hast-util-from-html@2.0.3: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 devlop: 1.1.0 hast-util-from-parse5: 8.0.3 parse5: 7.3.0 @@ -12454,8 +17619,8 @@ snapshots: hast-util-from-parse5@8.0.3: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 devlop: 1.1.0 hastscript: 9.0.1 property-information: 7.1.0 @@ -12465,19 +17630,19 @@ snapshots: hast-util-has-property@3.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-is-body-ok-link@3.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-is-element@3.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-minify-whitespace@1.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-embedded: 3.0.0 hast-util-is-element: 3.0.0 hast-util-whitespace: 3.0.0 @@ -12485,11 +17650,11 @@ snapshots: hast-util-parse-selector@4.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-phrasing@3.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-embedded: 3.0.0 hast-util-has-property: 3.0.0 hast-util-is-body-ok-link: 3.0.1 @@ -12497,9 +17662,9 @@ snapshots: hast-util-raw@9.1.0: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.1 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 + "@ungap/structured-clone": 1.3.1 hast-util-from-parse5: 8.0.3 hast-util-to-parse5: 8.0.1 html-void-elements: 3.0.0 @@ -12513,8 +17678,8 @@ snapshots: hast-util-select@6.0.4: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 bcp-47-match: 2.0.3 comma-separated-tokens: 2.0.3 css-selector-parser: 3.3.0 @@ -12531,9 +17696,9 @@ snapshots: hast-util-to-estree@3.1.3: dependencies: - '@types/estree': 1.0.9 - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 + "@types/estree": 1.0.9 + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 comma-separated-tokens: 2.0.3 devlop: 1.1.0 estree-util-attach-comments: 3.0.0 @@ -12552,8 +17717,8 @@ snapshots: hast-util-to-html@9.0.5: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 ccount: 2.0.1 comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 @@ -12566,9 +17731,9 @@ snapshots: hast-util-to-jsx-runtime@2.3.6: dependencies: - '@types/estree': 1.0.9 - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + "@types/estree": 1.0.9 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 comma-separated-tokens: 2.0.3 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 @@ -12586,7 +17751,7 @@ snapshots: hast-util-to-parse5@8.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 comma-separated-tokens: 2.0.3 devlop: 1.1.0 property-information: 7.1.0 @@ -12596,22 +17761,22 @@ snapshots: hast-util-to-string@3.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-to-text@4.0.2: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 + "@types/hast": 3.0.4 + "@types/unist": 3.0.3 hast-util-is-element: 3.0.0 unist-util-find-after: 5.0.0 hast-util-whitespace@3.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hastscript@9.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 comma-separated-tokens: 2.0.3 hast-util-parse-selector: 4.0.0 property-information: 7.1.0 @@ -12621,7 +17786,7 @@ snapshots: headers-polyfill@5.0.1: dependencies: - '@types/set-cookie-parser': 2.4.10 + "@types/set-cookie-parser": 2.4.10 set-cookie-parser: 3.1.0 hono@4.12.22: {} @@ -12761,6 +17926,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.6.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 @@ -12827,12 +17996,12 @@ snapshots: json-schema-to-ts@1.6.4: dependencies: - '@types/json-schema': 7.0.15 + "@types/json-schema": 7.0.15 ts-toolbelt: 6.15.5 json-schema-to-ts@3.1.1: dependencies: - '@babel/runtime': 7.29.2 + "@babel/runtime": 7.29.2 ts-algebra: 2.0.0 json-schema-traverse@1.0.0: {} @@ -12873,7 +18042,7 @@ snapshots: turndown: 7.2.4 yaml: 2.9.0 optionalDependencies: - '@mongodb-js/zstd': 7.0.0 + "@mongodb-js/zstd": 7.0.0 node-liblzma: 2.2.0 transitivePeerDependencies: - supports-color @@ -12954,10 +18123,33 @@ snapshots: dependencies: uc.micro: 2.1.0 - lint-staged@17.0.5: {} + lint-staged@17.0.5: + dependencies: + listr2: 10.2.2 + picomatch: 4.0.4 + string-argv: 0.3.2 + tinyexec: 1.1.2 + optionalDependencies: + yaml: 2.9.0 + + listr2@10.2.2: + dependencies: + cli-truncate: 5.2.0 + eventemitter3: 5.0.4 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 10.0.0 load-tsconfig@0.2.5: {} + log-update@6.1.0: + dependencies: + ansi-escapes: 7.3.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.2 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + long@5.3.2: {} longest-streak@3.1.0: {} @@ -12980,12 +18172,12 @@ snapshots: magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + "@jridgewell/sourcemap-codec": 1.5.5 magicast@0.5.3: dependencies: - '@babel/parser': 7.29.3 - '@babel/types': 7.29.0 + "@babel/parser": 7.29.3 + "@babel/types": 7.29.0 source-map-js: 1.2.1 make-dir@4.0.0: @@ -13009,14 +18201,14 @@ snapshots: mdast-util-definitions@6.0.0: dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 unist-util-visit: 5.1.0 mdast-util-directive@3.1.0: dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 ccount: 2.0.1 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 @@ -13029,15 +18221,15 @@ snapshots: mdast-util-find-and-replace@3.0.2: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 escape-string-regexp: 5.0.0 unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 mdast-util-from-markdown@2.0.3: dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 decode-named-character-reference: 1.3.0 devlop: 1.1.0 mdast-util-to-string: 4.0.0 @@ -13053,7 +18245,7 @@ snapshots: mdast-util-gfm-autolink-literal@2.0.1: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 ccount: 2.0.1 devlop: 1.1.0 mdast-util-find-and-replace: 3.0.2 @@ -13061,7 +18253,7 @@ snapshots: mdast-util-gfm-footnote@2.1.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 @@ -13071,7 +18263,7 @@ snapshots: mdast-util-gfm-strikethrough@2.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 transitivePeerDependencies: @@ -13079,7 +18271,7 @@ snapshots: mdast-util-gfm-table@2.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 devlop: 1.1.0 markdown-table: 3.0.4 mdast-util-from-markdown: 2.0.3 @@ -13089,7 +18281,7 @@ snapshots: mdast-util-gfm-task-list-item@2.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 @@ -13110,9 +18302,9 @@ snapshots: mdast-util-mdx-expression@2.0.1: dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 @@ -13121,10 +18313,10 @@ snapshots: mdast-util-mdx-jsx@3.2.0: dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 ccount: 2.0.1 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 @@ -13148,9 +18340,9 @@ snapshots: mdast-util-mdxjs-esm@2.0.1: dependencies: - '@types/estree-jsx': 1.0.5 - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 + "@types/estree-jsx": 1.0.5 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 devlop: 1.1.0 mdast-util-from-markdown: 2.0.3 mdast-util-to-markdown: 2.1.2 @@ -13159,14 +18351,14 @@ snapshots: mdast-util-phrasing@4.1.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 unist-util-is: 6.0.1 mdast-util-to-hast@13.2.1: dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 - '@ungap/structured-clone': 1.3.1 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 + "@ungap/structured-clone": 1.3.1 devlop: 1.1.0 micromark-util-sanitize-uri: 2.0.1 trim-lines: 3.0.1 @@ -13176,8 +18368,8 @@ snapshots: mdast-util-to-markdown@2.1.2: dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 + "@types/mdast": 4.0.4 + "@types/unist": 3.0.3 longest-streak: 3.1.0 mdast-util-phrasing: 4.1.0 mdast-util-to-string: 4.0.0 @@ -13188,7 +18380,7 @@ snapshots: mdast-util-to-string@4.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 mdn-data@2.0.28: {} @@ -13301,7 +18493,7 @@ snapshots: micromark-extension-mdx-expression@3.0.1: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 devlop: 1.1.0 micromark-factory-mdx-expression: 2.0.3 micromark-factory-space: 2.0.1 @@ -13312,7 +18504,7 @@ snapshots: micromark-extension-mdx-jsx@3.0.2: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 micromark-factory-mdx-expression: 2.0.3 @@ -13329,7 +18521,7 @@ snapshots: micromark-extension-mdxjs-esm@3.0.0: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 micromark-util-character: 2.1.1 @@ -13365,7 +18557,7 @@ snapshots: micromark-factory-mdx-expression@2.0.3: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 devlop: 1.1.0 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 @@ -13429,8 +18621,8 @@ snapshots: micromark-util-events-to-acorn@2.0.3: dependencies: - '@types/estree': 1.0.9 - '@types/unist': 3.0.3 + "@types/estree": 1.0.9 + "@types/unist": 3.0.3 devlop: 1.1.0 estree-util-visit: 2.0.0 micromark-util-symbol: 2.0.1 @@ -13466,7 +18658,7 @@ snapshots: micromark@4.0.2: dependencies: - '@types/debug': 4.1.13 + "@types/debug": 4.1.13 debug: 4.4.3 decode-named-character-reference: 1.3.0 devlop: 1.1.0 @@ -13505,12 +18697,14 @@ snapshots: mimic-fn@2.1.0: {} + mimic-function@5.0.1: {} + mimic-response@3.1.0: optional: true minimatch@10.1.1: dependencies: - '@isaacs/brace-expansion': 5.0.1 + "@isaacs/brace-expansion": 5.0.1 minimatch@10.2.5: dependencies: @@ -13558,10 +18752,10 @@ snapshots: msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3): dependencies: - '@inquirer/confirm': 6.0.13(@types/node@25.9.1) - '@mswjs/interceptors': 0.41.9 - '@open-draft/deferred-promise': 3.0.0 - '@types/statuses': 2.0.6 + "@inquirer/confirm": 6.0.13(@types/node@25.9.1) + "@mswjs/interceptors": 0.41.9 + "@open-draft/deferred-promise": 3.0.0 + "@types/statuses": 2.0.6 cookie: 1.1.1 graphql: 16.14.0 headers-polyfill: 5.0.1 @@ -13579,7 +18773,7 @@ snapshots: optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - - '@types/node' + - "@types/node" muggle-string@0.4.1: {} @@ -13606,57 +18800,6 @@ snapshots: nf3@0.3.17: {} - nitro@3.0.260522-beta(@vercel/blob@2.4.0)(@vercel/queue@0.2.0)(chokidar@5.0.0)(jiti@2.7.0)(lru-cache@11.5.0)(rollup@4.60.4): - dependencies: - consola: 3.4.2 - crossws: 0.4.5(srvx@0.11.16) - db0: 0.3.4 - env-runner: 0.1.9(@vercel/queue@0.2.0) - h3: 2.0.1-rc.22(crossws@0.4.5(srvx@0.11.16)) - hookable: 6.1.1 - nf3: 0.3.17 - ocache: 0.1.4 - ofetch: 2.0.0-alpha.3 - ohash: 2.0.11 - rolldown: 1.0.2 - srvx: 0.11.16 - unenv: 2.0.0-rc.24 - unstorage: 2.0.0-alpha.7(@vercel/blob@2.4.0)(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3) - optionalDependencies: - '@vercel/queue': 0.2.0 - jiti: 2.7.0 - rollup: 4.60.4 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@netlify/runtime' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - chokidar - - drizzle-orm - - idb-keyval - - ioredis - - lru-cache - - miniflare - - mongodb - - mysql2 - - sqlite3 - - uploadthing - nitro@3.0.260522-beta(@vercel/functions@3.6.0)(@vercel/queue@0.2.0)(drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1))(jiti@2.7.0)(rollup@4.60.4): dependencies: consola: 3.4.2 @@ -13674,27 +18817,27 @@ snapshots: unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.7(@vercel/functions@3.6.0)(db0@0.3.4(drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1)))(ofetch@2.0.0-alpha.3) optionalDependencies: - '@vercel/queue': 0.2.0 + "@vercel/queue": 0.2.0 jiti: 2.7.0 rollup: 4.60.4 transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@netlify/runtime' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' + - "@azure/app-configuration" + - "@azure/cosmos" + - "@azure/data-tables" + - "@azure/identity" + - "@azure/keyvault-secrets" + - "@azure/storage-blob" + - "@capacitor/preferences" + - "@deno/kv" + - "@electric-sql/pglite" + - "@libsql/client" + - "@netlify/blobs" + - "@netlify/runtime" + - "@planetscale/database" + - "@upstash/redis" + - "@vercel/blob" + - "@vercel/functions" + - "@vercel/kv" - aws4fetch - better-sqlite3 - chokidar @@ -13725,27 +18868,27 @@ snapshots: unenv: 2.0.0-rc.24 unstorage: 2.0.0-alpha.7(db0@0.3.4)(ofetch@2.0.0-alpha.3) optionalDependencies: - '@vercel/queue': 0.2.0 + "@vercel/queue": 0.2.0 jiti: 2.7.0 rollup: 4.60.4 transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@netlify/runtime' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' + - "@azure/app-configuration" + - "@azure/cosmos" + - "@azure/data-tables" + - "@azure/identity" + - "@azure/keyvault-secrets" + - "@azure/storage-blob" + - "@capacitor/preferences" + - "@deno/kv" + - "@electric-sql/pglite" + - "@libsql/client" + - "@netlify/blobs" + - "@netlify/runtime" + - "@planetscale/database" + - "@upstash/redis" + - "@vercel/blob" + - "@vercel/functions" + - "@vercel/kv" - aws4fetch - better-sqlite3 - chokidar @@ -13778,23 +18921,23 @@ snapshots: optionalDependencies: jiti: 2.7.0 transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@netlify/runtime' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/functions' - - '@vercel/kv' + - "@azure/app-configuration" + - "@azure/cosmos" + - "@azure/data-tables" + - "@azure/identity" + - "@azure/keyvault-secrets" + - "@azure/storage-blob" + - "@capacitor/preferences" + - "@deno/kv" + - "@electric-sql/pglite" + - "@libsql/client" + - "@netlify/blobs" + - "@netlify/runtime" + - "@planetscale/database" + - "@upstash/redis" + - "@vercel/blob" + - "@vercel/functions" + - "@vercel/kv" - aws4fetch - better-sqlite3 - chokidar @@ -13810,7 +18953,7 @@ snapshots: nlcst-to-string@4.0.0: dependencies: - '@types/nlcst': 2.0.3 + "@types/nlcst": 2.0.3 node-abi@3.92.0: dependencies: @@ -13913,6 +19056,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + oniguruma-parser@0.12.2: {} oniguruma-to-es@4.3.6: @@ -13931,51 +19078,51 @@ snapshots: oxc-transform@0.111.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): optionalDependencies: - '@oxc-transform/binding-android-arm-eabi': 0.111.0 - '@oxc-transform/binding-android-arm64': 0.111.0 - '@oxc-transform/binding-darwin-arm64': 0.111.0 - '@oxc-transform/binding-darwin-x64': 0.111.0 - '@oxc-transform/binding-freebsd-x64': 0.111.0 - '@oxc-transform/binding-linux-arm-gnueabihf': 0.111.0 - '@oxc-transform/binding-linux-arm-musleabihf': 0.111.0 - '@oxc-transform/binding-linux-arm64-gnu': 0.111.0 - '@oxc-transform/binding-linux-arm64-musl': 0.111.0 - '@oxc-transform/binding-linux-ppc64-gnu': 0.111.0 - '@oxc-transform/binding-linux-riscv64-gnu': 0.111.0 - '@oxc-transform/binding-linux-riscv64-musl': 0.111.0 - '@oxc-transform/binding-linux-s390x-gnu': 0.111.0 - '@oxc-transform/binding-linux-x64-gnu': 0.111.0 - '@oxc-transform/binding-linux-x64-musl': 0.111.0 - '@oxc-transform/binding-openharmony-arm64': 0.111.0 - '@oxc-transform/binding-wasm32-wasi': 0.111.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - '@oxc-transform/binding-win32-arm64-msvc': 0.111.0 - '@oxc-transform/binding-win32-ia32-msvc': 0.111.0 - '@oxc-transform/binding-win32-x64-msvc': 0.111.0 - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + "@oxc-transform/binding-android-arm-eabi": 0.111.0 + "@oxc-transform/binding-android-arm64": 0.111.0 + "@oxc-transform/binding-darwin-arm64": 0.111.0 + "@oxc-transform/binding-darwin-x64": 0.111.0 + "@oxc-transform/binding-freebsd-x64": 0.111.0 + "@oxc-transform/binding-linux-arm-gnueabihf": 0.111.0 + "@oxc-transform/binding-linux-arm-musleabihf": 0.111.0 + "@oxc-transform/binding-linux-arm64-gnu": 0.111.0 + "@oxc-transform/binding-linux-arm64-musl": 0.111.0 + "@oxc-transform/binding-linux-ppc64-gnu": 0.111.0 + "@oxc-transform/binding-linux-riscv64-gnu": 0.111.0 + "@oxc-transform/binding-linux-riscv64-musl": 0.111.0 + "@oxc-transform/binding-linux-s390x-gnu": 0.111.0 + "@oxc-transform/binding-linux-x64-gnu": 0.111.0 + "@oxc-transform/binding-linux-x64-musl": 0.111.0 + "@oxc-transform/binding-openharmony-arm64": 0.111.0 + "@oxc-transform/binding-wasm32-wasi": 0.111.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@oxc-transform/binding-win32-arm64-msvc": 0.111.0 + "@oxc-transform/binding-win32-ia32-msvc": 0.111.0 + "@oxc-transform/binding-win32-x64-msvc": 0.111.0 + transitivePeerDependencies: + - "@emnapi/core" + - "@emnapi/runtime" oxlint@1.66.0: optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.66.0 - '@oxlint/binding-android-arm64': 1.66.0 - '@oxlint/binding-darwin-arm64': 1.66.0 - '@oxlint/binding-darwin-x64': 1.66.0 - '@oxlint/binding-freebsd-x64': 1.66.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.66.0 - '@oxlint/binding-linux-arm-musleabihf': 1.66.0 - '@oxlint/binding-linux-arm64-gnu': 1.66.0 - '@oxlint/binding-linux-arm64-musl': 1.66.0 - '@oxlint/binding-linux-ppc64-gnu': 1.66.0 - '@oxlint/binding-linux-riscv64-gnu': 1.66.0 - '@oxlint/binding-linux-riscv64-musl': 1.66.0 - '@oxlint/binding-linux-s390x-gnu': 1.66.0 - '@oxlint/binding-linux-x64-gnu': 1.66.0 - '@oxlint/binding-linux-x64-musl': 1.66.0 - '@oxlint/binding-openharmony-arm64': 1.66.0 - '@oxlint/binding-win32-arm64-msvc': 1.66.0 - '@oxlint/binding-win32-ia32-msvc': 1.66.0 - '@oxlint/binding-win32-x64-msvc': 1.66.0 + "@oxlint/binding-android-arm-eabi": 1.66.0 + "@oxlint/binding-android-arm64": 1.66.0 + "@oxlint/binding-darwin-arm64": 1.66.0 + "@oxlint/binding-darwin-x64": 1.66.0 + "@oxlint/binding-freebsd-x64": 1.66.0 + "@oxlint/binding-linux-arm-gnueabihf": 1.66.0 + "@oxlint/binding-linux-arm-musleabihf": 1.66.0 + "@oxlint/binding-linux-arm64-gnu": 1.66.0 + "@oxlint/binding-linux-arm64-musl": 1.66.0 + "@oxlint/binding-linux-ppc64-gnu": 1.66.0 + "@oxlint/binding-linux-riscv64-gnu": 1.66.0 + "@oxlint/binding-linux-riscv64-musl": 1.66.0 + "@oxlint/binding-linux-s390x-gnu": 1.66.0 + "@oxlint/binding-linux-x64-gnu": 1.66.0 + "@oxlint/binding-linux-x64-musl": 1.66.0 + "@oxlint/binding-openharmony-arm64": 1.66.0 + "@oxlint/binding-win32-arm64-msvc": 1.66.0 + "@oxlint/binding-win32-ia32-msvc": 1.66.0 + "@oxlint/binding-win32-x64-msvc": 1.66.0 p-finally@1.0.0: {} @@ -13997,7 +19144,7 @@ snapshots: p-retry@4.6.2: dependencies: - '@types/retry': 0.12.0 + "@types/retry": 0.12.0 retry: 0.13.1 p-timeout@3.2.0: @@ -14008,7 +19155,7 @@ snapshots: pac-proxy-agent@7.2.0: dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 + "@tootallnate/quickjs-emscripten": 0.23.0 agent-base: 7.1.4 debug: 4.4.3 get-uri: 6.0.5 @@ -14028,19 +19175,19 @@ snapshots: pagefind@1.5.2: optionalDependencies: - '@pagefind/darwin-arm64': 1.5.2 - '@pagefind/darwin-x64': 1.5.2 - '@pagefind/freebsd-x64': 1.5.2 - '@pagefind/linux-arm64': 1.5.2 - '@pagefind/linux-x64': 1.5.2 - '@pagefind/windows-arm64': 1.5.2 - '@pagefind/windows-x64': 1.5.2 + "@pagefind/darwin-arm64": 1.5.2 + "@pagefind/darwin-x64": 1.5.2 + "@pagefind/freebsd-x64": 1.5.2 + "@pagefind/linux-arm64": 1.5.2 + "@pagefind/linux-x64": 1.5.2 + "@pagefind/windows-arm64": 1.5.2 + "@pagefind/windows-x64": 1.5.2 papaparse@5.5.3: {} parse-entities@4.0.2: dependencies: - '@types/unist': 2.0.11 + "@types/unist": 2.0.11 character-entities-legacy: 3.0.0 character-reference-invalid: 2.0.1 decode-named-character-reference: 1.3.0 @@ -14050,8 +19197,8 @@ snapshots: parse-latin@7.0.0: dependencies: - '@types/nlcst': 2.0.3 - '@types/unist': 3.0.3 + "@types/nlcst": 2.0.3 + "@types/unist": 3.0.3 nlcst-to-string: 4.0.0 unist-util-modify-children: 4.0.0 unist-util-visit-children: 3.0.0 @@ -14149,6 +19296,14 @@ snapshots: mlly: 1.8.2 pathe: 2.0.3 + playwright-core@1.60.0: {} + + playwright@1.60.0: + dependencies: + playwright-core: 1.60.0 + optionalDependencies: + fsevents: 2.3.2 + postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.15)(tsx@4.22.3)(yaml@2.9.0): dependencies: lilconfig: 3.1.3 @@ -14226,17 +19381,17 @@ snapshots: protobufjs@7.6.1: dependencies: - '@protobufjs/aspromise': 1.1.2 - '@protobufjs/base64': 1.1.2 - '@protobufjs/codegen': 2.0.5 - '@protobufjs/eventemitter': 1.1.1 - '@protobufjs/fetch': 1.1.1 - '@protobufjs/float': 1.0.2 - '@protobufjs/inquire': 1.1.2 - '@protobufjs/path': 1.1.2 - '@protobufjs/pool': 1.1.0 - '@protobufjs/utf8': 1.1.1 - '@types/node': 25.9.1 + "@protobufjs/aspromise": 1.1.2 + "@protobufjs/base64": 1.1.2 + "@protobufjs/codegen": 2.0.5 + "@protobufjs/eventemitter": 1.1.1 + "@protobufjs/fetch": 1.1.1 + "@protobufjs/float": 1.0.2 + "@protobufjs/inquire": 1.1.2 + "@protobufjs/path": 1.1.2 + "@protobufjs/pool": 1.1.0 + "@protobufjs/utf8": 1.1.1 + "@types/node": 25.9.1 long: 5.3.2 proxy-addr@2.0.7: @@ -14261,7 +19416,12 @@ snapshots: proxy-from-env@2.1.0: {} - publint@0.3.21: {} + publint@0.3.21: + dependencies: + "@publint/pack": 0.1.5 + package-manager-detector: 1.6.0 + picocolors: 1.1.1 + sade: 1.8.1 pump@3.0.4: dependencies: @@ -14280,14 +19440,14 @@ snapshots: quickjs-emscripten-core@0.32.0: dependencies: - '@jitl/quickjs-ffi-types': 0.32.0 + "@jitl/quickjs-ffi-types": 0.32.0 quickjs-emscripten@0.32.0: dependencies: - '@jitl/quickjs-wasmfile-debug-asyncify': 0.32.0 - '@jitl/quickjs-wasmfile-debug-sync': 0.32.0 - '@jitl/quickjs-wasmfile-release-asyncify': 0.32.0 - '@jitl/quickjs-wasmfile-release-sync': 0.32.0 + "@jitl/quickjs-wasmfile-debug-asyncify": 0.32.0 + "@jitl/quickjs-wasmfile-debug-sync": 0.32.0 + "@jitl/quickjs-wasmfile-release-asyncify": 0.32.0 + "@jitl/quickjs-wasmfile-release-sync": 0.32.0 quickjs-emscripten-core: 0.32.0 radix3@1.1.2: {} @@ -14327,16 +19487,16 @@ snapshots: react-redux@9.3.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1): dependencies: - '@types/use-sync-external-store': 0.0.6 + "@types/use-sync-external-store": 0.0.6 react: 19.2.6 use-sync-external-store: 1.6.0(react@19.2.6) optionalDependencies: - '@types/react': 19.2.15 + "@types/react": 19.2.15 redux: 5.0.1 react-redux@9.3.0(react@19.2.6): dependencies: - '@types/use-sync-external-store': 0.0.6 + "@types/use-sync-external-store": 0.0.6 react: 19.2.6 use-sync-external-store: 1.6.0(react@19.2.6) @@ -14363,7 +19523,7 @@ snapshots: recharts@3.8.1(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react-is@19.2.7)(react@19.2.6)(redux@5.0.1): dependencies: - '@reduxjs/toolkit': 2.12.0(react-redux@9.3.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1))(react@19.2.6) + "@reduxjs/toolkit": 2.12.0(react-redux@9.3.0(@types/react@19.2.15)(react@19.2.6)(redux@5.0.1))(react@19.2.6) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.47.0 @@ -14378,12 +19538,12 @@ snapshots: use-sync-external-store: 1.6.0(react@19.2.6) victory-vendor: 37.3.6 transitivePeerDependencies: - - '@types/react' + - "@types/react" - redux recharts@3.8.1(react-dom@19.2.6(react@19.2.6))(react-is@19.2.7)(react@19.2.6): dependencies: - '@reduxjs/toolkit': 2.12.0(react-redux@9.3.0(react@19.2.6))(react@19.2.6) + "@reduxjs/toolkit": 2.12.0(react-redux@9.3.0(react@19.2.6))(react@19.2.6) clsx: 2.1.1 decimal.js-light: 2.5.1 es-toolkit: 1.47.0 @@ -14398,7 +19558,7 @@ snapshots: use-sync-external-store: 1.6.0(react@19.2.6) victory-vendor: 37.3.6 transitivePeerDependencies: - - '@types/react' + - "@types/react" - redux rechoir@0.8.0: @@ -14407,7 +19567,7 @@ snapshots: recma-build-jsx@1.0.0: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 estree-util-build-jsx: 3.0.1 vfile: 6.0.3 @@ -14422,28 +19582,28 @@ snapshots: recma-parse@1.0.0: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 esast-util-from-js: 2.0.1 unified: 11.0.5 vfile: 6.0.3 recma-stringify@1.0.0: dependencies: - '@types/estree': 1.0.9 + "@types/estree": 1.0.9 estree-util-to-js: 2.0.0 unified: 11.0.5 vfile: 6.0.3 redis@5.12.1: dependencies: - '@redis/bloom': 5.12.1(@redis/client@5.12.1) - '@redis/client': 5.12.1 - '@redis/json': 5.12.1(@redis/client@5.12.1) - '@redis/search': 5.12.1(@redis/client@5.12.1) - '@redis/time-series': 5.12.1(@redis/client@5.12.1) + "@redis/bloom": 5.12.1(@redis/client@5.12.1) + "@redis/client": 5.12.1 + "@redis/json": 5.12.1(@redis/client@5.12.1) + "@redis/search": 5.12.1(@redis/client@5.12.1) + "@redis/time-series": 5.12.1(@redis/client@5.12.1) transitivePeerDependencies: - - '@node-rs/xxhash' - - '@opentelemetry/api' + - "@node-rs/xxhash" + - "@opentelemetry/api" redux-thunk@3.1.0(redux@5.0.1): dependencies: @@ -14469,45 +19629,45 @@ snapshots: rehype-format@5.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-format: 1.1.0 rehype-parse@9.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-from-html: 2.0.3 unified: 11.0.5 rehype-raw@7.0.0: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-raw: 9.1.0 vfile: 6.0.3 rehype-recma@1.0.0: dependencies: - '@types/estree': 1.0.9 - '@types/hast': 3.0.4 + "@types/estree": 1.0.9 + "@types/hast": 3.0.4 hast-util-to-estree: 3.1.3 transitivePeerDependencies: - supports-color rehype-stringify@10.0.1: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 hast-util-to-html: 9.0.5 unified: 11.0.5 rehype@13.0.2: dependencies: - '@types/hast': 3.0.4 + "@types/hast": 3.0.4 rehype-parse: 9.0.1 rehype-stringify: 10.0.1 unified: 11.0.5 remark-directive@4.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 mdast-util-directive: 3.1.0 micromark-extension-directive: 4.0.0 unified: 11.0.5 @@ -14516,7 +19676,7 @@ snapshots: remark-gfm@4.0.1: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 mdast-util-gfm: 3.1.0 micromark-extension-gfm: 3.0.0 remark-parse: 11.0.0 @@ -14534,7 +19694,7 @@ snapshots: remark-parse@11.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 mdast-util-from-markdown: 2.0.3 micromark-util-types: 2.0.2 unified: 11.0.5 @@ -14543,8 +19703,8 @@ snapshots: remark-rehype@11.1.2: dependencies: - '@types/hast': 3.0.4 - '@types/mdast': 4.0.4 + "@types/hast": 3.0.4 + "@types/mdast": 4.0.4 mdast-util-to-hast: 13.2.1 unified: 11.0.5 vfile: 6.0.3 @@ -14558,7 +19718,7 @@ snapshots: remark-stringify@11.0.0: dependencies: - '@types/mdast': 4.0.4 + "@types/mdast": 4.0.4 mdast-util-to-markdown: 2.1.2 unified: 11.0.5 @@ -14594,27 +19754,32 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + retext-latin@4.0.0: dependencies: - '@types/nlcst': 2.0.3 + "@types/nlcst": 2.0.3 parse-latin: 7.0.0 unified: 11.0.5 retext-smartypants@6.2.0: dependencies: - '@types/nlcst': 2.0.3 + "@types/nlcst": 2.0.3 nlcst-to-string: 4.0.0 unist-util-visit: 5.1.0 retext-stringify@4.0.0: dependencies: - '@types/nlcst': 2.0.3 + "@types/nlcst": 2.0.3 nlcst-to-string: 4.0.0 unified: 11.0.5 retext@9.0.0: dependencies: - '@types/nlcst': 2.0.3 + "@types/nlcst": 2.0.3 retext-latin: 4.0.0 retext-stringify: 4.0.0 unified: 11.0.5 @@ -14625,78 +19790,80 @@ snapshots: reusify@1.1.0: {} + rfdc@1.4.1: {} + rolldown@1.0.0-rc.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): dependencies: - '@oxc-project/types': 0.110.0 - '@rolldown/pluginutils': 1.0.0-rc.1 + "@oxc-project/types": 0.110.0 + "@rolldown/pluginutils": 1.0.0-rc.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.1 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.1 - '@rolldown/binding-darwin-x64': 1.0.0-rc.1 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.1 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.1 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.1 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.1 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.1 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.1 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.1 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.1 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.1 - transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + "@rolldown/binding-android-arm64": 1.0.0-rc.1 + "@rolldown/binding-darwin-arm64": 1.0.0-rc.1 + "@rolldown/binding-darwin-x64": 1.0.0-rc.1 + "@rolldown/binding-freebsd-x64": 1.0.0-rc.1 + "@rolldown/binding-linux-arm-gnueabihf": 1.0.0-rc.1 + "@rolldown/binding-linux-arm64-gnu": 1.0.0-rc.1 + "@rolldown/binding-linux-arm64-musl": 1.0.0-rc.1 + "@rolldown/binding-linux-x64-gnu": 1.0.0-rc.1 + "@rolldown/binding-linux-x64-musl": 1.0.0-rc.1 + "@rolldown/binding-openharmony-arm64": 1.0.0-rc.1 + "@rolldown/binding-wasm32-wasi": 1.0.0-rc.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@rolldown/binding-win32-arm64-msvc": 1.0.0-rc.1 + "@rolldown/binding-win32-x64-msvc": 1.0.0-rc.1 + transitivePeerDependencies: + - "@emnapi/core" + - "@emnapi/runtime" rolldown@1.0.2: dependencies: - '@oxc-project/types': 0.132.0 - '@rolldown/pluginutils': 1.0.1 + "@oxc-project/types": 0.132.0 + "@rolldown/pluginutils": 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.2 - '@rolldown/binding-darwin-arm64': 1.0.2 - '@rolldown/binding-darwin-x64': 1.0.2 - '@rolldown/binding-freebsd-x64': 1.0.2 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.2 - '@rolldown/binding-linux-arm64-gnu': 1.0.2 - '@rolldown/binding-linux-arm64-musl': 1.0.2 - '@rolldown/binding-linux-ppc64-gnu': 1.0.2 - '@rolldown/binding-linux-s390x-gnu': 1.0.2 - '@rolldown/binding-linux-x64-gnu': 1.0.2 - '@rolldown/binding-linux-x64-musl': 1.0.2 - '@rolldown/binding-openharmony-arm64': 1.0.2 - '@rolldown/binding-wasm32-wasi': 1.0.2 - '@rolldown/binding-win32-arm64-msvc': 1.0.2 - '@rolldown/binding-win32-x64-msvc': 1.0.2 + "@rolldown/binding-android-arm64": 1.0.2 + "@rolldown/binding-darwin-arm64": 1.0.2 + "@rolldown/binding-darwin-x64": 1.0.2 + "@rolldown/binding-freebsd-x64": 1.0.2 + "@rolldown/binding-linux-arm-gnueabihf": 1.0.2 + "@rolldown/binding-linux-arm64-gnu": 1.0.2 + "@rolldown/binding-linux-arm64-musl": 1.0.2 + "@rolldown/binding-linux-ppc64-gnu": 1.0.2 + "@rolldown/binding-linux-s390x-gnu": 1.0.2 + "@rolldown/binding-linux-x64-gnu": 1.0.2 + "@rolldown/binding-linux-x64-musl": 1.0.2 + "@rolldown/binding-openharmony-arm64": 1.0.2 + "@rolldown/binding-wasm32-wasi": 1.0.2 + "@rolldown/binding-win32-arm64-msvc": 1.0.2 + "@rolldown/binding-win32-x64-msvc": 1.0.2 rollup@4.60.4: dependencies: - '@types/estree': 1.0.8 + "@types/estree": 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 + "@rollup/rollup-android-arm-eabi": 4.60.4 + "@rollup/rollup-android-arm64": 4.60.4 + "@rollup/rollup-darwin-arm64": 4.60.4 + "@rollup/rollup-darwin-x64": 4.60.4 + "@rollup/rollup-freebsd-arm64": 4.60.4 + "@rollup/rollup-freebsd-x64": 4.60.4 + "@rollup/rollup-linux-arm-gnueabihf": 4.60.4 + "@rollup/rollup-linux-arm-musleabihf": 4.60.4 + "@rollup/rollup-linux-arm64-gnu": 4.60.4 + "@rollup/rollup-linux-arm64-musl": 4.60.4 + "@rollup/rollup-linux-loong64-gnu": 4.60.4 + "@rollup/rollup-linux-loong64-musl": 4.60.4 + "@rollup/rollup-linux-ppc64-gnu": 4.60.4 + "@rollup/rollup-linux-ppc64-musl": 4.60.4 + "@rollup/rollup-linux-riscv64-gnu": 4.60.4 + "@rollup/rollup-linux-riscv64-musl": 4.60.4 + "@rollup/rollup-linux-s390x-gnu": 4.60.4 + "@rollup/rollup-linux-x64-gnu": 4.60.4 + "@rollup/rollup-linux-x64-musl": 4.60.4 + "@rollup/rollup-openbsd-x64": 4.60.4 + "@rollup/rollup-openharmony-arm64": 4.60.4 + "@rollup/rollup-win32-arm64-msvc": 4.60.4 + "@rollup/rollup-win32-ia32-msvc": 4.60.4 + "@rollup/rollup-win32-x64-gnu": 4.60.4 + "@rollup/rollup-win32-x64-msvc": 4.60.4 fsevents: 2.3.3 rou3@0.7.12: {} @@ -14717,6 +19884,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + sade@1.8.1: + dependencies: + mri: 1.2.0 + safe-buffer@5.2.1: {} safe-regex@2.1.1: @@ -14727,7 +19898,7 @@ snapshots: sandbox@2.5.6: dependencies: - '@vercel/sandbox': 1.9.0 + "@vercel/sandbox": 1.9.0 debug: 4.4.3 zod: 4.4.3 transitivePeerDependencies: @@ -14792,34 +19963,34 @@ snapshots: sharp@0.34.5: dependencies: - '@img/colour': 1.1.0 + "@img/colour": 1.1.0 detect-libc: 2.1.2 semver: 7.8.1 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 + "@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 optional: true shebang-command@2.0.0: @@ -14830,14 +20001,14 @@ snapshots: shiki@4.1.0: dependencies: - '@shikijs/core': 4.1.0 - '@shikijs/engine-javascript': 4.1.0 - '@shikijs/engine-oniguruma': 4.1.0 - '@shikijs/langs': 4.1.0 - '@shikijs/themes': 4.1.0 - '@shikijs/types': 4.1.0 - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 + "@shikijs/core": 4.1.0 + "@shikijs/engine-javascript": 4.1.0 + "@shikijs/engine-oniguruma": 4.1.0 + "@shikijs/langs": 4.1.0 + "@shikijs/themes": 4.1.0 + "@shikijs/types": 4.1.0 + "@shikijs/vscode-textmate": 10.0.2 + "@types/hast": 3.0.4 side-channel-list@1.0.1: dependencies: @@ -14891,11 +20062,21 @@ snapshots: sitemap@9.0.1: dependencies: - '@types/node': 24.12.4 - '@types/sax': 1.2.7 + "@types/node": 24.12.4 + "@types/sax": 1.2.7 arg: 5.0.2 sax: 1.6.0 + slice-ansi@7.1.2: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + smart-buffer@4.2.0: {} smol-toml@1.5.2: {} @@ -14944,7 +20125,7 @@ snapshots: starlight-typedoc@0.23.0(@astrojs/starlight@0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3))(typedoc-plugin-markdown@4.11.0(typedoc@0.28.19(typescript@6.0.3)))(typedoc@0.28.19(typescript@6.0.3)): dependencies: - '@astrojs/starlight': 0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3) + "@astrojs/starlight": 0.39.2(astro@6.3.7(@types/node@25.9.1)(@vercel/blob@2.4.0)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.4)(tsx@4.22.3)(yaml@2.9.0))(typescript@6.0.3) github-slugger: 2.0.0 typedoc: 0.28.19(typescript@6.0.3) typedoc-plugin-markdown: 4.11.0(typedoc@0.28.19(typescript@6.0.3)) @@ -14980,12 +20161,25 @@ snapshots: strict-event-emitter@0.5.1: {} + string-argv@0.3.2: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string-width@8.2.1: + dependencies: + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -15000,6 +20194,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + strip-bom@3.0.0: {} strip-final-newline@2.0.0: {} @@ -15011,7 +20209,7 @@ snapshots: strtok3@10.3.5: dependencies: - '@tokenizer/token': 0.3.0 + "@tokenizer/token": 0.3.0 style-to-js@1.1.21: dependencies: @@ -15023,7 +20221,7 @@ snapshots: sucrase@3.35.1: dependencies: - '@jridgewell/gen-mapping': 0.3.13 + "@jridgewell/gen-mapping": 0.3.13 commander: 4.1.1 lines-and-columns: 1.2.4 mz: 2.7.0 @@ -15081,7 +20279,7 @@ snapshots: tar@7.5.15: dependencies: - '@isaacs/fs-minipass': 4.0.1 + "@isaacs/fs-minipass": 4.0.1 chownr: 3.0.0 minipass: 7.1.3 minizlib: 3.1.0 @@ -15089,7 +20287,7 @@ snapshots: tar@7.5.7: dependencies: - '@isaacs/fs-minipass': 4.0.1 + "@isaacs/fs-minipass": 4.0.1 chownr: 3.0.0 minipass: 7.1.3 minizlib: 3.1.0 @@ -15148,8 +20346,8 @@ snapshots: token-types@6.1.2: dependencies: - '@borewit/text-codec': 0.2.2 - '@tokenizer/token': 0.3.0 + "@borewit/text-codec": 0.2.2 + "@tokenizer/token": 0.3.0 ieee754: 1.2.1 tough-cookie@6.0.1: @@ -15170,7 +20368,7 @@ snapshots: ts-morph@12.0.0: dependencies: - '@ts-morph/common': 0.11.1 + "@ts-morph/common": 0.11.1 code-block-writer: 10.1.1 ts-toolbelt@6.15.5: {} @@ -15253,7 +20451,11 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - tsx@4.22.3: {} + tsx@4.22.3: + dependencies: + esbuild: 0.28.1 + optionalDependencies: + fsevents: 2.3.3 tunnel-agent@0.6.0: dependencies: @@ -15262,7 +20464,7 @@ snapshots: turndown@7.2.4: dependencies: - '@mixmark-io/domino': 2.2.0 + "@mixmark-io/domino": 2.2.0 type-fest@5.6.0: dependencies: @@ -15282,7 +20484,7 @@ snapshots: typedoc@0.28.19(typescript@6.0.3): dependencies: - '@gerrit0/mini-shiki': 3.23.0 + "@gerrit0/mini-shiki": 3.23.0 lunr: 2.3.9 markdown-it: 14.1.1 minimatch: 10.2.5 @@ -15315,11 +20517,9 @@ snapshots: undici-types@7.16.0: {} - undici-types@7.24.6: {} - undici@5.28.4: dependencies: - '@fastify/busboy': 2.1.1 + "@fastify/busboy": 2.1.1 undici@6.25.0: {} @@ -15331,7 +20531,7 @@ snapshots: unified@11.0.5: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 bail: 2.0.2 devlop: 1.1.0 extend: 3.0.2 @@ -15347,47 +20547,47 @@ snapshots: unist-util-find-after@5.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-is: 6.0.1 unist-util-is@6.0.1: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-modify-children@4.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 array-iterate: 2.0.1 unist-util-position-from-estree@2.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-position@5.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-remove-position@5.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-visit: 5.1.0 unist-util-stringify-position@4.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-visit-children@3.0.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-visit-parents@6.0.2: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-is: 6.0.1 unist-util-visit@5.1.0: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 @@ -15406,19 +20606,11 @@ snapshots: ofetch: 1.5.1 ufo: 1.6.4 optionalDependencies: - '@vercel/blob': 2.4.0 - - unstorage@2.0.0-alpha.7(@vercel/blob@2.4.0)(chokidar@5.0.0)(db0@0.3.4)(lru-cache@11.5.0)(ofetch@2.0.0-alpha.3): - optionalDependencies: - '@vercel/blob': 2.4.0 - chokidar: 5.0.0 - db0: 0.3.4 - lru-cache: 11.5.0 - ofetch: 2.0.0-alpha.3 + "@vercel/blob": 2.4.0 unstorage@2.0.0-alpha.7(@vercel/functions@3.6.0)(db0@0.3.4(drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1)))(ofetch@2.0.0-alpha.3): optionalDependencies: - '@vercel/functions': 3.6.0 + "@vercel/functions": 3.6.0 db0: 0.3.4(drizzle-orm@0.45.2(@neondatabase/serverless@1.1.0)(@types/pg@8.15.6)(kysely@0.28.17)(pg@8.21.0)(sql.js@1.14.1)) ofetch: 2.0.0-alpha.3 @@ -15443,30 +20635,30 @@ snapshots: vercel@54.4.0(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): dependencies: - '@vercel/backends': 0.7.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - '@vercel/blob': 2.4.0 - '@vercel/build-utils': 13.26.1 - '@vercel/cli-config': 0.1.2 - '@vercel/detect-agent': 1.2.3 - '@vercel/elysia': 0.1.80 - '@vercel/express': 0.1.90(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) - '@vercel/fastify': 0.1.83 - '@vercel/fun': 1.3.0 - '@vercel/go': 3.7.1 - '@vercel/h3': 0.1.89 - '@vercel/hono': 0.2.83 - '@vercel/hydrogen': 1.3.7 - '@vercel/koa': 0.1.63 - '@vercel/nestjs': 0.2.84 - '@vercel/next': 4.17.3 - '@vercel/node': 5.8.4 - '@vercel/prepare-flags-definitions': 0.2.1 - '@vercel/python': 6.43.1 - '@vercel/redwood': 2.4.13 - '@vercel/remix-builder': 5.8.2 - '@vercel/ruby': 2.3.2 - '@vercel/rust': 1.2.0 - '@vercel/static-build': 2.9.30 + "@vercel/backends": 0.7.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@vercel/blob": 2.4.0 + "@vercel/build-utils": 13.26.1 + "@vercel/cli-config": 0.1.2 + "@vercel/detect-agent": 1.2.3 + "@vercel/elysia": 0.1.80 + "@vercel/express": 0.1.90(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + "@vercel/fastify": 0.1.83 + "@vercel/fun": 1.3.0 + "@vercel/go": 3.7.1 + "@vercel/h3": 0.1.89 + "@vercel/hono": 0.2.83 + "@vercel/hydrogen": 1.3.7 + "@vercel/koa": 0.1.63 + "@vercel/nestjs": 0.2.84 + "@vercel/next": 4.17.3 + "@vercel/node": 5.8.4 + "@vercel/prepare-flags-definitions": 0.2.1 + "@vercel/python": 6.43.1 + "@vercel/redwood": 2.4.13 + "@vercel/remix-builder": 5.8.2 + "@vercel/ruby": 2.3.2 + "@vercel/rust": 1.2.0 + "@vercel/static-build": 2.9.30 chokidar: 4.0.0 esbuild: 0.27.0 form-data: 4.0.5 @@ -15477,8 +20669,8 @@ snapshots: smol-toml: 1.5.2 zod: 4.1.11 transitivePeerDependencies: - - '@emnapi/core' - - '@emnapi/runtime' + - "@emnapi/core" + - "@emnapi/runtime" - bare-abort-controller - encoding - react-native-b4a @@ -15487,28 +20679,28 @@ snapshots: vfile-location@5.0.3: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 vfile: 6.0.3 vfile-message@4.0.3: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 unist-util-stringify-position: 4.0.0 vfile@6.0.3: dependencies: - '@types/unist': 3.0.3 + "@types/unist": 3.0.3 vfile-message: 4.0.3 victory-vendor@37.3.6: dependencies: - '@types/d3-array': 3.2.2 - '@types/d3-ease': 3.0.2 - '@types/d3-interpolate': 3.0.4 - '@types/d3-scale': 4.0.9 - '@types/d3-shape': 3.1.8 - '@types/d3-time': 3.0.4 - '@types/d3-timer': 3.0.2 + "@types/d3-array": 3.2.2 + "@types/d3-ease": 3.0.2 + "@types/d3-interpolate": 3.0.4 + "@types/d3-scale": 4.0.9 + "@types/d3-shape": 3.1.8 + "@types/d3-time": 3.0.4 + "@types/d3-timer": 3.0.2 d3-array: 3.2.4 d3-ease: 3.0.1 d3-interpolate: 3.0.1 @@ -15526,7 +20718,7 @@ snapshots: rollup: 4.60.4 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 fsevents: 2.3.3 jiti: 2.7.0 lightningcss: 1.32.0 @@ -15541,7 +20733,7 @@ snapshots: rolldown: 1.0.2 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 fsevents: 2.3.3 jiti: 2.7.0 tsx: 4.22.3 @@ -15555,7 +20747,7 @@ snapshots: rolldown: 1.0.2 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 fsevents: 2.3.3 tsx: 4.22.3 @@ -15565,8 +20757,8 @@ snapshots: vitest-evals@0.13.1(ai@6.0.190(zod@4.4.3))(tinyrainbow@3.1.0)(vitest@4.1.7(@types/node@25.9.1)(tsx@4.22.3))(zod@4.4.3): dependencies: - '@vitest-evals/core': 0.13.1 - '@vitest-evals/report-ui': 0.13.1 + "@vitest-evals/core": 0.13.1 + "@vitest-evals/report-ui": 0.13.1 tinyrainbow: 3.1.0 vitest: 4.1.7(@types/node@25.9.1)(tsx@4.22.3) optionalDependencies: @@ -15575,13 +20767,13 @@ snapshots: vitest@4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(jiti@2.7.0)(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(tsx@4.22.3)(yaml@2.9.0): dependencies: - '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(tsx@4.22.3)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.7 - '@vitest/runner': 4.1.7 - '@vitest/snapshot': 4.1.7 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + "@vitest/expect": 4.1.7 + "@vitest/mocker": 4.1.7(msw@2.14.6(@types/node@25.9.1)(typescript@6.0.3))(vite@8.0.14(@types/node@25.9.1)(jiti@2.7.0)(tsx@4.22.3)(yaml@2.9.0)) + "@vitest/pretty-format": 4.1.7 + "@vitest/runner": 4.1.7 + "@vitest/snapshot": 4.1.7 + "@vitest/spy": 4.1.7 + "@vitest/utils": 4.1.7 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -15596,10 +20788,10 @@ snapshots: vite: 8.0.14(@types/node@25.9.1)(jiti@2.7.0)(tsx@4.22.3)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.9.1 - '@vitest/coverage-v8': 4.1.7(vitest@4.1.7) + "@types/node": 25.9.1 + "@vitest/coverage-v8": 4.1.7(vitest@4.1.7) transitivePeerDependencies: - - '@vitejs/devtools' + - "@vitejs/devtools" - esbuild - jiti - less @@ -15614,13 +20806,13 @@ snapshots: vitest@4.1.7(@types/node@25.9.1)(@vitest/coverage-v8@4.1.7)(tsx@4.22.3): dependencies: - '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@25.9.1)(tsx@4.22.3)) - '@vitest/pretty-format': 4.1.7 - '@vitest/runner': 4.1.7 - '@vitest/snapshot': 4.1.7 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + "@vitest/expect": 4.1.7 + "@vitest/mocker": 4.1.7(vite@8.0.14(@types/node@25.9.1)(tsx@4.22.3)) + "@vitest/pretty-format": 4.1.7 + "@vitest/runner": 4.1.7 + "@vitest/snapshot": 4.1.7 + "@vitest/spy": 4.1.7 + "@vitest/utils": 4.1.7 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -15635,10 +20827,10 @@ snapshots: vite: 8.0.14(@types/node@25.9.1)(tsx@4.22.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.9.1 - '@vitest/coverage-v8': 4.1.7(vitest@4.1.7) + "@types/node": 25.9.1 + "@vitest/coverage-v8": 4.1.7(vitest@4.1.7) transitivePeerDependencies: - - '@vitejs/devtools' + - "@vitejs/devtools" - esbuild - jiti - less @@ -15653,13 +20845,13 @@ snapshots: vitest@4.1.7(@types/node@25.9.1)(tsx@4.22.3): dependencies: - '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@25.9.1)(tsx@4.22.3)) - '@vitest/pretty-format': 4.1.7 - '@vitest/runner': 4.1.7 - '@vitest/snapshot': 4.1.7 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + "@vitest/expect": 4.1.7 + "@vitest/mocker": 4.1.7(vite@8.0.14(@types/node@25.9.1)(tsx@4.22.3)) + "@vitest/pretty-format": 4.1.7 + "@vitest/runner": 4.1.7 + "@vitest/snapshot": 4.1.7 + "@vitest/spy": 4.1.7 + "@vitest/utils": 4.1.7 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -15674,9 +20866,9 @@ snapshots: vite: 8.0.14(@types/node@25.9.1)(tsx@4.22.3) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 25.9.1 + "@types/node": 25.9.1 transitivePeerDependencies: - - '@vitejs/devtools' + - "@vitejs/devtools" - esbuild - jiti - less @@ -15695,16 +20887,16 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 volar-service-emmet@0.0.70(@volar/language-service@2.4.28): dependencies: - '@emmetio/css-parser': 0.4.1 - '@emmetio/html-matcher': 1.3.0 - '@vscode/emmet-helper': 2.11.0 + "@emmetio/css-parser": 0.4.1 + "@emmetio/html-matcher": 1.3.0 + "@vscode/emmet-helper": 2.11.0 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 volar-service-html@0.0.70(@volar/language-service@2.4.28): dependencies: @@ -15712,20 +20904,20 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 volar-service-prettier@0.0.70(@volar/language-service@2.4.28)(prettier@3.8.3): dependencies: vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 prettier: 3.8.3 volar-service-typescript-twoslash-queries@0.0.70(@volar/language-service@2.4.28): dependencies: vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 volar-service-typescript@0.0.70(@volar/language-service@2.4.28): dependencies: @@ -15736,25 +20928,25 @@ snapshots: vscode-nls: 5.2.0 vscode-uri: 3.1.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 volar-service-yaml@0.0.70(@volar/language-service@2.4.28): dependencies: vscode-uri: 3.1.0 yaml-language-server: 1.20.0 optionalDependencies: - '@volar/language-service': 2.4.28 + "@volar/language-service": 2.4.28 vscode-css-languageservice@6.3.10: dependencies: - '@vscode/l10n': 0.0.18 + "@vscode/l10n": 0.0.18 vscode-languageserver-textdocument: 1.0.12 vscode-languageserver-types: 3.17.5 vscode-uri: 3.1.0 vscode-html-languageservice@5.6.2: dependencies: - '@vscode/l10n': 0.0.18 + "@vscode/l10n": 0.0.18 vscode-languageserver-textdocument: 1.0.12 vscode-languageserver-types: 3.17.5 vscode-uri: 3.1.0 @@ -15812,12 +21004,24 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + wrap-ansi@10.0.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 8.2.1 + strip-ansi: 7.2.0 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrappy@1.0.2: {} ws@8.20.1: {} @@ -15849,7 +21053,7 @@ snapshots: yaml-language-server@1.20.0: dependencies: - '@vscode/l10n': 0.0.18 + "@vscode/l10n": 0.0.18 ajv: 8.20.0 ajv-draft-04: 1.0.0(ajv@8.20.0) prettier: 3.8.3 From 1064c1deaf8ec50a1987e33454046cca0446592c Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 18:53:45 -0700 Subject: [PATCH 23/29] fix(memory): Save passive extraction prompt iteration Preserve the current passive extraction experiment before trying a structural extraction contract change. The patch adjusts memory prompts, specs, and eval coverage around shared task and operational knowledge so the next iteration can be compared cleanly. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 224 ++++++++++++++++-- packages/junior-memory/src/agent.ts | 29 ++- specs/memory-plugin/extraction.md | 23 +- specs/memory-plugin/storage.md | 4 +- specs/memory-plugin/tools.md | 8 +- 5 files changed, 242 insertions(+), 46 deletions(-) diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index e28525577..3e031904d 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -1,5 +1,5 @@ import { afterEach, expect } from "vitest"; -import { assistantMessages, describeEval, toolCalls } from "vitest-evals"; +import { assistantMessages, describeEval } from "vitest-evals"; import { closeDb, getDb } from "@/chat/db"; import { completeText, resolveGatewayModel } from "@/chat/pi/client"; import { createMemoryStore, type MemoryDb } from "@sentry/junior-memory"; @@ -159,6 +159,55 @@ async function expectRequesterMemorySemantics( ).toEqual(expect.objectContaining({ passed: true })); } +async function expectConversationMemorySemantics( + input: MemorySemanticJudgmentInput, +): Promise { + const storedMemoryProjection = input.storedMemories.map((memory) => ({ + archivedAtMs: memory.archivedAtMs, + content: memory.content, + scope: memory.scope, + subjectType: memory.subjectType, + })); + const { text } = await completeText({ + modelId: memoryJudgeModelId, + system: + 'You judge Junior memory eval results. Return only raw JSON matching {"passed":boolean,"rationale":"..."}.', + messages: [ + { + role: "user", + content: [ + "", + "", + input.userText, + "", + "", + input.expectedMeaning, + "", + "", + JSON.stringify(storedMemoryProjection), + "", + "", + input.assistantText, + "", + "", + "Pass only if exactly one active conversation memory is stored and its content is semantically equivalent to the expected meaning.", + "The stored content must be canonical memory text: no requester display name, no 'the requester', no 'the user', no first-person wording, and no thread/channel/source wording.", + "Fail if the memory is stored as personal/user memory, if no memory was stored, if the content is a vague paraphrase, or if the content preserves source/user labels.", + "", + "", + ].join("\n"), + timestamp: Date.now(), + }, + ], + temperature: 0, + }); + const judgment = parseMemoryJudgeResult(text); + expect( + judgment, + `${judgment.rationale}\nStored memories: ${JSON.stringify(storedMemoryProjection)}`, + ).toEqual(expect.objectContaining({ passed: true })); +} + async function expectAssistantMemoryAnswer(args: { assistantText: string; expectedBehavior: string; @@ -302,67 +351,198 @@ describeEval("Memory Workflows", slackEvals, (it) => { }); }); - const passiveFirstPersonThread = { + const explicitTaskProcedureThread = { channel_type: "channel", - id: "thread-memory-passive-first-person", - channel_id: "CMEMORYPASSIVEPERSONAL", - thread_ts: "17000000.memory-passive-personal", + id: "thread-memory-explicit-task-procedure", + channel_id: "CMEMORYEXPLICITTASK", + thread_ts: "17000000.memory-explicit-task", } satisfies MemoryThread; - it("when organic conversation reveals a durable first-person preference, passively store and recall it", async ({ + it("when explicitly asked to remember a shared task procedure, store it as conversation memory", async ({ run, }) => { await clearMemories(); - const userText = "In my PR reviews, risk notes go before summary notes."; + const userText = + "Please remember that for flaky webhook triage, inspect delivery headers before retrying the job."; const result = await run({ overrides: memoryPluginOverrides, events: [ mention(userText, { - thread: passiveFirstPersonThread, + thread: explicitTaskProcedureThread, }), - mention("How should you order notes in my next PR review?", { - thread: passiveFirstPersonThread, + mention("How should flaky webhook triage be done?", { + thread: explicitTaskProcedureThread, }), ], criteria: rubric({ pass: [ - "The assistant uses the organic first-person preference from the earlier turn when answering the follow-up.", + "The assistant stores and uses the shared task procedure from the user's explicit memory request.", + "The assistant treats the procedure as shared process knowledge, not as the requester's personal preference.", + "The assistant does not mention hidden scope, actor, Slack, or subject identifiers.", + ], + fail: [ + "Do not answer as if no relevant webhook triage procedure exists.", + "Do not describe the stored fact as a requester preference.", + ], + }), + }); + + const rows = await readMemories(explicitTaskProcedureThread); + expect(rows).toContainEqual( + expect.objectContaining({ + archivedAtMs: null, + scope: "conversation", + subjectType: "conversation", + }), + ); + expect(rows).not.toContainEqual( + expect.objectContaining({ + archivedAtMs: null, + scope: "personal", + subjectType: "user", + }), + ); + await expectConversationMemorySemantics({ + assistantText: visibleAssistantText(result), + expectedMeaning: + "Flaky webhook triage inspects delivery headers before retrying the job.", + storedMemories: rows, + userText, + }); + await expectAssistantMemoryAnswer({ + assistantText: visibleAssistantText(result), + expectedBehavior: + "The assistant says flaky webhook triage should inspect delivery headers before retrying the job.", + }); + }); + + const passiveTaskProcedureThread = { + channel_type: "channel", + id: "thread-memory-passive-task-procedure", + channel_id: "CMEMORYPASSIVETASK", + thread_ts: "17000000.memory-passive-task", + } satisfies MemoryThread; + + it("when organic conversation teaches a task procedure, store and recall it as conversation memory", async ({ + run, + }) => { + await clearMemories(); + const userText = + "For sandbox timeout triage, inspect heartbeat gaps before increasing the timeout."; + const result = await run({ + overrides: memoryPluginOverrides, + events: [ + mention(userText, { + thread: passiveTaskProcedureThread, + }), + mention("How should sandbox timeout triage be done?", { + thread: passiveTaskProcedureThread, + }), + ], + criteria: rubric({ + pass: [ + "The assistant uses the organic task procedure from the earlier turn when answering the follow-up.", "The assistant does not require the user to explicitly say remember before using durable memory.", "The assistant does not mention hidden scope, actor, Slack, or subject identifiers.", ], fail: [ - "Do not answer as if no relevant preference exists.", + "Do not answer as if no relevant sandbox timeout triage procedure exists.", "Do not claim passive memory requires an explicit remember command.", ], }), }); - const rows = await readMemories(passiveFirstPersonThread); - expect(toolCalls(result.session)).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ - name: "createMemory", - }), - ]), + const rows = await readMemories(passiveTaskProcedureThread); + expect(rows).toContainEqual( + expect.objectContaining({ + archivedAtMs: null, + scope: "conversation", + subjectType: "conversation", + }), ); + expect(rows).not.toContainEqual( + expect.objectContaining({ + archivedAtMs: null, + scope: "personal", + subjectType: "user", + }), + ); + await expectConversationMemorySemantics({ + assistantText: visibleAssistantText(result), + expectedMeaning: + "Sandbox timeout triage inspects heartbeat gaps before increasing the timeout.", + storedMemories: rows, + userText, + }); + await expectAssistantMemoryAnswer({ + assistantText: visibleAssistantText(result), + expectedBehavior: + "The assistant says sandbox timeout triage should inspect heartbeat gaps before increasing the timeout.", + }); + }); + + const passiveConversationThread = { + channel_type: "channel", + id: "thread-memory-passive-conversation", + channel_id: "CMEMORYPASSIVECONVERSATION", + thread_ts: "17000000.memory-passive-conversation", + } satisfies MemoryThread; + + it("when organic conversation reveals operational knowledge, store and recall it as conversation memory", async ({ + run, + }) => { + await clearMemories(); + const userText = + "Branch QA runbooks require risk notes before summary notes."; + const result = await run({ + overrides: memoryPluginOverrides, + events: [ + mention(userText, { + thread: passiveConversationThread, + }), + mention("What do branch QA runbooks require?", { + thread: passiveConversationThread, + }), + ], + criteria: rubric({ + pass: [ + "The assistant uses the organic operational knowledge from the earlier turn when answering the follow-up.", + "The assistant does not require an explicit remember command before using durable memory.", + "The assistant does not mention hidden scope, actor, Slack, or subject identifiers.", + ], + fail: [ + "Do not answer as if no relevant runbook memory exists.", + "Do not claim passive memory requires an explicit remember command.", + ], + }), + }); + + const rows = await readMemories(passiveConversationThread); expect(rows).toContainEqual( + expect.objectContaining({ + archivedAtMs: null, + scope: "conversation", + subjectType: "conversation", + }), + ); + expect(rows).not.toContainEqual( expect.objectContaining({ archivedAtMs: null, scope: "personal", subjectType: "user", }), ); - await expectRequesterMemorySemantics({ + await expectConversationMemorySemantics({ assistantText: visibleAssistantText(result), expectedMeaning: - "The requester prefers risk notes before summary notes in future pull request reviews.", + "Branch QA runbooks require risk notes before summary notes.", storedMemories: rows, userText, }); await expectAssistantMemoryAnswer({ assistantText: visibleAssistantText(result), expectedBehavior: - "The assistant says to put risk notes before summary notes in the next PR review.", + "The assistant says branch QA runbooks require risk notes before summary notes.", }); }); diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index c5a09d9a0..0ad31035a 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -105,7 +105,7 @@ const expiresAtMsSchema = z const extractedMemorySchema = z .object({ target: memoryTargetSchema.describe( - "Store requester facts as personal memory for the current requester; store shared operational/project facts as conversation memory.", + "Use requester only for facts about the current requester. Use conversation for shared operational, project, process, runbook, channel, and procedural task knowledge, even when the requester authored the message.", ), canonicalFact: z .string() @@ -216,7 +216,7 @@ function sourceContext(request: CreateMemoryRequest): string | undefined { } return [ "", - "The current user-authored text is bounded context for judging the candidate. Do not store it directly unless the accepted memory content is self-contained.", + "The current user-authored text is source evidence for explicit memory requests. Use it to recover the concrete fact when the candidate is incomplete, vague, or over-personalized. Store only rewritten, self-contained memory content.", "", escapeXml(currentUserText), "", @@ -241,10 +241,10 @@ function extractionExamples(): string { "", "- User says: 'I prefer release notes with customer impact first.'", " Output requester memory: canonicalFact='Prefers customer impact first in release notes.'.", - "- User says: 'For architecture proposals, I prefer tradeoffs before recommendations.'", - " Output requester memory: canonicalFact='Prefers tradeoffs before recommendations in architecture proposals.'.", + "- User says: 'For failed deployments, inspect release logs before restarting workers.'", + " Output conversation memory: canonicalFact='Failed deployment triage inspects release logs before restarting workers.'.", "- User says: 'In support handoffs, escalation owners go before timelines.'", - " Output requester memory: canonicalFact='Prefers escalation owners before timelines in support handoffs.'.", + " Output conversation memory: canonicalFact='Support handoffs list escalation owners before timelines.'.", "- User says: 'This channel says staging database refreshes run on Wednesdays.'", " Output conversation memory: canonicalFact='Staging database refreshes run on Wednesdays.'.", "", @@ -266,18 +266,23 @@ function reviewPrompt(request: CreateMemoryRequest): string { "", "", "- Return store only when the candidate is public/shareable, durable, and self-contained.", - "- Use target=requester for first-person facts about the current requester.", + "- Choose target by what the fact is about, not by who said it.", + "- Use target=requester only for facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- When current-user-message contains an explicit memory request with a concrete fact or procedure, extract from current-user-message even if the candidate is vague, incomplete, or phrased as an instruction.", "- A candidate may be badly phrased by an outer assistant or extraction pass. When current-user-message contains the requester's own first-person memory fact, treat that as requester-authored source evidence and canonicalize the fact instead of rejecting for third-person wording.", - "- Use target=conversation only for shared operational/project knowledge in the active conversation.", + "- When candidate wording personalizes a shared task, process, runbook, project, channel, or operational fact, use current-user-message to recover the shared fact and target conversation.", + "- Explicit procedure requests are valid when the source text contains both task context and action. Canonicalize them as shared procedure facts instead of rejecting them as vague.", + "- Use target=conversation for shared operational/project knowledge, runbooks, process facts, and channel norms in the active conversation, even when the requester authored the message.", "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels from stored content.", "- Good requester content: 'Prefers customer impact first in release notes'. Bad requester content: 'I prefer customer impact first in release notes'.", "- Good requester content: 'Prefers customer impact first in release notes'. Bad requester content: 'The requester prefers customer impact first in release notes'.", "- Good requester content: 'Prefers tradeoffs before recommendations in architecture proposals'. Bad requester content: 'Prefers in my architecture proposals, tradeoffs before recommendations'.", + "- Good conversation content: 'Failed deployment triage inspects release logs before restarting workers'. Bad conversation content: 'Prefers inspecting release logs before restarting workers'.", "- Good conversation content: 'Staging database refreshes run on Wednesdays'. Bad conversation content: 'This channel says staging database refreshes run on Wednesdays'.", "- Reject third-party personal profile facts, even if they mention a name.", - "- Reject vague content such as 'remember this' unless the candidate itself contains the fact.", + "- Reject vague content such as 'remember this' unless the candidate or current-user-message contains the concrete fact.", "- Preserve the requested expiration when one exists; otherwise set expiresAtMs to null.", "- For store, set reason to null.", "- For reject, set target, content, and expiresAtMs to null.", @@ -323,8 +328,12 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { "- Use assistant role messages only to reject confirmations, follow-up questions, or memory-management turns.", "- Return one memory per distinct fact. Do not store the same fact under both requester and conversation targets.", "- Ignore advice, how-to, search, recall, planning, list, inspect, and remove requests unless user messages also state a durable fact.", - "- Use target=requester for first-person facts about the current requester.", - "- Use target=conversation only for shared operational/project knowledge.", + "- Prioritize shared task, process, runbook, project, channel, and operational knowledge.", + "- Choose target by what the fact is about, not by who said it.", + "- Use target=requester only for clear durable facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- Use target=conversation for runbooks, team/process/project facts, channel norms, and operational knowledge, even when the requester authored the message.", + "- Procedural statements such as 'for X, do Y', 'when X, do Y', and 'to accomplish X, do Y' are shared task knowledge unless they explicitly describe the requester's personal preference or habit.", + "- Do not rewrite shared procedures as requester preferences.", ...CANONICAL_CONTENT_RULES, "- Skip a candidate when existing-memories already cover the same durable fact.", "- Reject third-party personal profile facts, even if they mention a name.", diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 4c992f5cd..931bd5a7f 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -127,10 +127,11 @@ Passive session extraction must follow these rules: coworker speculation. 10. Reject private or sensitive content instead of storing it under personal scope. -11. In V1 passive extraction, prefer conversation-scoped operational knowledge - over personal memory unless the user makes a clear first-person statement. +11. In V1 passive extraction, prioritize conversation-scoped task, process, + runbook, project, channel, and operational knowledge. 12. Personal-scoped memories must be public/shareable first-person facts from - the current author/requester. + the current author/requester, and should be stored passively only when they + are clearly durable and useful beyond the active task. 13. Assign `user` subject only for the current author/requester; do not create third-party user subjects in V1. 14. Preserve provenance for third-party claims when the source matters for @@ -189,16 +190,20 @@ Memory agent output must be structured. For explicit review it should include: For passive extraction it should include an array of accepted candidate memories with target, canonical stored content, and optional expiration. -Requester-target passive memories in V1 focus on durable first-person -preferences, opinions, and habits. Broader public requester facts can still be -handled by the explicit reviewed `createMemory` path. Rejections are -represented by omitting a candidate from the array. +Conversation-target passive memories in V1 are the primary path for learning +how work gets done: task procedures, runbooks, project facts, channel norms, +and operational knowledge. Requester-target passive memories are secondary and +limited to clearly durable first-person preferences, opinions, and habits. +Broader public requester facts can still be handled by the explicit reviewed +`createMemory` path. Rejections are represented by omitting a candidate from the +array. The content field is canonical stored memory text. Requester memory content must omit ownership from prose because ownership lives in structured metadata. For example, `I prefer terse PR summaries` should become requester memory -`Prefers terse PR summaries`, and `This thread says deploy runbooks live in -Notion` should become conversation memory `Deploy runbooks live in Notion`. +`Prefers terse PR summaries`, and `This thread says deploy runbooks require +staging checks first` should become conversation memory `Deploy runbooks require +staging checks first`. The memory agent may narrow, rewrite, or reject extracted candidates, but it may not override hard structural validators. If extraction and review disagree, diff --git a/specs/memory-plugin/storage.md b/specs/memory-plugin/storage.md index ad23f6b2a..30aff7f3c 100644 --- a/specs/memory-plugin/storage.md +++ b/specs/memory-plugin/storage.md @@ -74,11 +74,11 @@ Examples: - Good: `Prefers terse PR summaries` - Good: `Favorite CLI QA snack is mango chips` -- Good: `Deploy runbooks live in Notion` +- Good: `Deploy runbooks require staging checks first` - Bad: `The requester prefers terse PR summaries` - Bad: `David prefers terse PR summaries` - Bad: `My favorite CLI QA snack is mango chips` -- Bad: `This thread says deploy runbooks live in Notion` +- Bad: `This thread says deploy runbooks require staging checks first` Prompt rendering may add perspective at recall time. Storage must not. diff --git a/specs/memory-plugin/tools.md b/specs/memory-plugin/tools.md index 75b4b4b35..d176964d8 100644 --- a/specs/memory-plugin/tools.md +++ b/specs/memory-plugin/tools.md @@ -65,9 +65,11 @@ to rephrase them as safer memory text. The memory agent owns the semantic store-or-reject decision and canonical rewrite. The outer agent should not call `createMemory` for ordinary organic statements -that merely reveal a durable preference or fact. Those are passive-learning -candidates handled by completed-session processing, not explicit memory-tool -requests. +that merely reveal a durable task, process, project, channel, or operational +fact. Those are passive-learning candidates handled by completed-session +processing, not explicit memory-tool requests. Organic first-person personal +facts should be stored passively only when they are clearly durable and useful +beyond the active task. The explicit tool path uses runtime context for source and idempotency. It must run through the memory agent's explicit-create review path. The memory agent From 051e70aecb987ed22c1b96349c6a9b65f7f2ebfd Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 20:08:24 -0700 Subject: [PATCH 24/29] fix(memory): Classify passive extraction by memory category Make the memory agent classify stored knowledge before deriving storage target so shared procedures do not become requester preferences. Passive extraction now returns categorized procedure, fact, and preference buckets. Memory uses the host default model unless a memory-specific override is configured, and the host plugin model API can request default or fast structured models explicitly. Co-Authored-By: GPT-5 Codex --- .../evals/memory/workflows.eval.ts | 2 +- packages/junior-memory/src/agent.ts | 157 +++++++++--------- packages/junior-memory/src/plugin.ts | 4 +- packages/junior-memory/tests/storage.test.ts | 117 ++++++++----- .../junior-plugin-api/src/registration.ts | 2 + packages/junior/src/chat/config.ts | 2 +- packages/junior/src/chat/plugins/model.ts | 15 +- .../component/config/chat-config.test.ts | 2 +- .../tests/unit/plugins/plugin-model.test.ts | 54 ++++++ specs/memory-plugin/extraction.md | 26 ++- specs/memory-plugin/tools.md | 6 +- 11 files changed, 251 insertions(+), 136 deletions(-) create mode 100644 packages/junior/tests/unit/plugins/plugin-model.test.ts diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index 3e031904d..93d28c3d5 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -479,7 +479,7 @@ describeEval("Memory Workflows", slackEvals, (it) => { expectedBehavior: "The assistant says sandbox timeout triage should inspect heartbeat gaps before increasing the timeout.", }); - }); + }, 120_000); const passiveConversationThread = { channel_type: "channel", diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 0ad31035a..87570b17e 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -3,6 +3,7 @@ import { z } from "zod"; import { memoryRuntimeContextSchema } from "./types"; const memoryTargetSchema = z.enum(["requester", "conversation"]); +const memoryKindSchema = z.enum(["preference", "procedure", "fact"]); const memoryRejectReasonSchema = z.enum([ "not_public_shareable", "secret_or_credential", @@ -52,6 +53,13 @@ const extractSessionRequestSchema = z }) .strict(); +const expiresAtMsSchema = z + .number() + .finite() + .nullable() + .describe( + "Expiration timestamp when the fact should expire, otherwise null.", + ); const memoryReviewDecisionSchema = z.discriminatedUnion("decision", [ z .object({ @@ -68,45 +76,31 @@ const memoryReviewDecisionSchema = z.discriminatedUnion("decision", [ }) .strict(), ]); -const memoryReviewResponseSchema = z - .object({ - decision: z - .enum(["store", "reject"]) - .describe("Whether this memory candidate should be stored or rejected."), - target: memoryTargetSchema - .nullable() - .describe("Memory target when decision is store, otherwise null."), - canonicalFact: z - .string() - .min(1) - .nullable() - .describe( - "Stored memory text when decision is store. It must be self-contained and must not include requester names, requester/user labels, source labels, or first- or second-person wording. Otherwise null.", - ), - reason: memoryRejectReasonSchema - .nullable() - .describe("Reject reason when decision is reject, otherwise null."), - expiresAtMs: z - .number() - .finite() - .nullable() - .describe( - "Requested expiration timestamp when decision is store and one was present, otherwise null.", +const memoryReviewResponseSchema = z.discriminatedUnion("decision", [ + z + .object({ + decision: z.literal("store"), + kind: memoryKindSchema.describe( + "Use preference only for requester-owned personal preferences, opinions, habits, or workflows. Use procedure for reusable task or process instructions. Use fact for shared project, channel, operational, or runbook knowledge.", ), - }) - .strict(); -const expiresAtMsSchema = z - .number() - .finite() - .nullable() - .describe( - "Expiration timestamp when the fact should expire, otherwise null.", - ); + canonicalFact: z + .string() + .min(1) + .describe( + "Stored memory text. It must be self-contained and must not include requester names, requester/user labels, source labels, or first- or second-person wording.", + ), + expiresAtMs: expiresAtMsSchema, + }) + .strict(), + z + .object({ + decision: z.literal("reject"), + reason: memoryRejectReasonSchema, + }) + .strict(), +]); const extractedMemorySchema = z .object({ - target: memoryTargetSchema.describe( - "Use requester only for facts about the current requester. Use conversation for shared operational, project, process, runbook, channel, and procedural task knowledge, even when the requester authored the message.", - ), canonicalFact: z .string() .min(1) @@ -118,11 +112,23 @@ const extractedMemorySchema = z .strict(); const extractMemoriesResponseSchema = z .object({ - memories: z + procedures: z .array(extractedMemorySchema) .max(5) .describe( - "Accepted public/shareable durable memories from this completed turn. Return an empty array when nothing should be stored.", + "Reusable public/shareable task, process, triage-flow, or runbook instructions from this completed turn. These are stored as conversation memory.", + ), + facts: z + .array(extractedMemorySchema) + .max(5) + .describe( + "Public/shareable shared project, channel, operational, or runbook facts from this completed turn. These are stored as conversation memory.", + ), + preferences: z + .array(extractedMemorySchema) + .max(5) + .describe( + "Durable public/shareable personal preferences, opinions, habits, or workflows explicitly owned by the current requester. These are stored as requester memory.", ), }) .strict(); @@ -131,6 +137,7 @@ type MemoryReviewResponse = z.output; type ExtractMemoriesResponse = z.output; export type MemoryTarget = z.output; +type MemoryKind = z.output; export type MemoryReview = z.output; @@ -159,7 +166,6 @@ const MEMORY_REVIEW_SYSTEM = [ "Store only public/shareable, self-contained facts that are useful beyond this turn.", "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.", "Use the runtime context only for authority and scope; do not accept model-provided actor ids, scope ids, aliases, or arbitrary subjects.", - "Return every response field. Use null for fields that do not apply to the decision.", ].join("\n"); const MEMORY_EXTRACTION_SYSTEM = [ "You are Junior's passive memory extraction agent. Return only structured memories worth storing.", @@ -169,12 +175,19 @@ const MEMORY_EXTRACTION_SYSTEM = [ ].join("\n"); const CANONICAL_CONTENT_RULES = [ "- Stored memory text must be a rewritten fact, not copied user wording or a sentence about who said it.", - "- Put ownership in target, not prose.", + "- Put ownership in structured fields, not prose.", "- For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", "- Drop perspective/provenance markers while preserving useful context.", "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels.", ]; +function targetForKind(kind: MemoryKind): MemoryTarget { + if (kind === "preference") { + return "requester"; + } + return "conversation"; +} + function escapeXml(value: string): string { return value .replaceAll("&", "&") @@ -236,18 +249,13 @@ function existingMemoriesContext(request: ExtractSessionRequest): string { ].join("\n"); } -function extractionExamples(): string { +function memoryKindsContext(): string { return [ - "", - "- User says: 'I prefer release notes with customer impact first.'", - " Output requester memory: canonicalFact='Prefers customer impact first in release notes.'.", - "- User says: 'For failed deployments, inspect release logs before restarting workers.'", - " Output conversation memory: canonicalFact='Failed deployment triage inspects release logs before restarting workers.'.", - "- User says: 'In support handoffs, escalation owners go before timelines.'", - " Output conversation memory: canonicalFact='Support handoffs list escalation owners before timelines.'.", - "- User says: 'This channel says staging database refreshes run on Wednesdays.'", - " Output conversation memory: canonicalFact='Staging database refreshes run on Wednesdays.'.", - "", + "", + "- preference: a durable personal preference, opinion, habit, or workflow owned by the current requester. Stored as requester memory.", + "- procedure: reusable instructions for how a task, process, triage flow, or runbook should be done. Stored as conversation memory.", + "- fact: shared project, channel, operational, or runbook knowledge that is not a personal requester preference. Stored as conversation memory.", + "", ].join("\n"); } @@ -266,26 +274,20 @@ function reviewPrompt(request: CreateMemoryRequest): string { "", "", "- Return store only when the candidate is public/shareable, durable, and self-contained.", - "- Choose target by what the fact is about, not by who said it.", - "- Use target=requester only for facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- First classify the memory kind: preference, procedure, or fact.", + "- Use kind=preference only for facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- Use kind=procedure for reusable task/process/runbook instructions.", + "- Use kind=fact for shared project, channel, operational, or runbook knowledge.", "- When current-user-message contains an explicit memory request with a concrete fact or procedure, extract from current-user-message even if the candidate is vague, incomplete, or phrased as an instruction.", "- A candidate may be badly phrased by an outer assistant or extraction pass. When current-user-message contains the requester's own first-person memory fact, treat that as requester-authored source evidence and canonicalize the fact instead of rejecting for third-person wording.", - "- When candidate wording personalizes a shared task, process, runbook, project, channel, or operational fact, use current-user-message to recover the shared fact and target conversation.", + "- When candidate wording personalizes a shared task, process, runbook, project, channel, or operational fact, use current-user-message to recover the shared fact and classify it as procedure or fact.", "- Explicit procedure requests are valid when the source text contains both task context and action. Canonicalize them as shared procedure facts instead of rejecting them as vague.", - "- Use target=conversation for shared operational/project knowledge, runbooks, process facts, and channel norms in the active conversation, even when the requester authored the message.", "- Store content as person-less, source-less canonical knowledge. Ownership and source live in structured metadata, not prose.", "- For requester memories, omit the subject and write the content as a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", "- Remove requester names, display names, requester/user labels, first- or second-person wording, thread labels, channel labels, and source labels from stored content.", - "- Good requester content: 'Prefers customer impact first in release notes'. Bad requester content: 'I prefer customer impact first in release notes'.", - "- Good requester content: 'Prefers customer impact first in release notes'. Bad requester content: 'The requester prefers customer impact first in release notes'.", - "- Good requester content: 'Prefers tradeoffs before recommendations in architecture proposals'. Bad requester content: 'Prefers in my architecture proposals, tradeoffs before recommendations'.", - "- Good conversation content: 'Failed deployment triage inspects release logs before restarting workers'. Bad conversation content: 'Prefers inspecting release logs before restarting workers'.", - "- Good conversation content: 'Staging database refreshes run on Wednesdays'. Bad conversation content: 'This channel says staging database refreshes run on Wednesdays'.", "- Reject third-party personal profile facts, even if they mention a name.", "- Reject vague content such as 'remember this' unless the candidate or current-user-message contains the concrete fact.", "- Preserve the requested expiration when one exists; otherwise set expiresAtMs to null.", - "- For store, set reason to null.", - "- For reject, set target, content, and expiresAtMs to null.", "- If unsure, reject.", "", "", @@ -318,7 +320,7 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { "", existingMemoriesContext(request), "", - extractionExamples(), + memoryKindsContext(), "", sessionMessagesContext(request), "", @@ -326,14 +328,13 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { "- Return at most five memories.", "- Use user role messages as the only source of storable facts.", "- Use assistant role messages only to reject confirmations, follow-up questions, or memory-management turns.", - "- Return one memory per distinct fact. Do not store the same fact under both requester and conversation targets.", + "- Return one memory per distinct fact.", "- Ignore advice, how-to, search, recall, planning, list, inspect, and remove requests unless user messages also state a durable fact.", - "- Prioritize shared task, process, runbook, project, channel, and operational knowledge.", - "- Choose target by what the fact is about, not by who said it.", - "- Use target=requester only for clear durable facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", - "- Use target=conversation for runbooks, team/process/project facts, channel norms, and operational knowledge, even when the requester authored the message.", - "- Procedural statements such as 'for X, do Y', 'when X, do Y', and 'to accomplish X, do Y' are shared task knowledge unless they explicitly describe the requester's personal preference or habit.", - "- Do not rewrite shared procedures as requester preferences.", + "- Fill procedures with reusable task/process/runbook instructions.", + "- Fill facts with shared team, project, channel, runbook, or operational knowledge.", + "- Fill preferences only with clear durable facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- User-authored task instructions are procedures, not preferences, unless they explicitly describe the requester's personal preference or habit.", + "- Procedural statements such as 'for X, do Y', 'when X, do Y', and 'to accomplish X, do Y' belong in procedures.", ...CANONICAL_CONTENT_RULES, "- Skip a candidate when existing-memories already cover the same durable fact.", "- Reject third-party personal profile facts, even if they mention a name.", @@ -378,7 +379,7 @@ function memoryReviewFromResponse( if (response.decision === "store") { return parseMemoryReview({ decision: "store", - target: response.target, + target: targetForKind(response.kind), content: response.canonicalFact, ...(response.expiresAtMs !== null ? { expiresAtMs: response.expiresAtMs } @@ -394,11 +395,19 @@ function memoryReviewFromResponse( function extractedMemoriesFromResponse( response: ExtractMemoriesResponse, ): ExtractedMemory[] { - return response.memories.map((memory) => ({ + const toMemory = ( + target: MemoryTarget, + memory: z.output, + ): ExtractedMemory => ({ content: memory.canonicalFact, expiresAtMs: memory.expiresAtMs, - target: memory.target, - })); + target, + }); + return [ + ...response.procedures.map((memory) => toMemory("conversation", memory)), + ...response.facts.map((memory) => toMemory("conversation", memory)), + ...response.preferences.map((memory) => toMemory("requester", memory)), + ]; } /** Parse the structured decision returned by the memory agent. */ diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index a2b7b5e4f..e1e9dfa14 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -57,7 +57,9 @@ export function createMemoryPlugin(options: MemoryPluginOptions = {}) { displayName: "Memory", description: "Long-term Junior memory storage and recall", }, - ...(modelId ? { model: { structuredModelId: modelId } } : {}), + model: modelId + ? { structuredModelId: modelId } + : { structuredModel: "default" }, packageName: "@sentry/junior-memory", cli: { commands: [createMemoryCliCommand()], diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 799437a68..12d5ece4c 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -211,20 +211,29 @@ function extractionModel( memories: Array<{ content: string; expiresAtMs?: number | null; - target: "requester" | "conversation"; + kind: "preference" | "procedure" | "fact"; }>, ) { const calls: Parameters[0][] = []; const model: PluginModel = { async completeObject(input) { calls.push(input); + const procedures = memories.filter( + (memory) => memory.kind === "procedure", + ); + const facts = memories.filter((memory) => memory.kind === "fact"); + const preferences = memories.filter( + (memory) => memory.kind === "preference", + ); + const toResponseMemory = (memory: (typeof memories)[number]) => ({ + canonicalFact: memory.content, + expiresAtMs: memory.expiresAtMs ?? null, + }); return { object: { - memories: memories.map((memory) => ({ - canonicalFact: memory.content, - expiresAtMs: memory.expiresAtMs ?? null, - target: memory.target, - })), + facts: facts.map(toResponseMemory), + preferences: preferences.map(toResponseMemory), + procedures: procedures.map(toResponseMemory), }, }; }, @@ -335,7 +344,7 @@ function processSessionContext( overrides.model ?? extractionModel([ { - target: "requester", + kind: "preference", content: "terse PR summaries", }, ]).model, @@ -380,7 +389,7 @@ const rejectMemory: MemoryReviewer = { }; describe("memory plugin storage", () => { - it("normalizes nullable structured review responses", async () => { + it("normalizes structured review responses", async () => { const calls: Parameters[0][] = []; const model: PluginModel = { async completeObject(input) { @@ -388,9 +397,8 @@ describe("memory plugin storage", () => { return { object: { decision: "store", - target: "requester", + kind: "preference", canonicalFact: "Uses qa-structured-output in CLI QA.", - reason: null, expiresAtMs: null, }, }; @@ -421,19 +429,38 @@ describe("memory plugin storage", () => { }); }); + it("defaults memory extraction to the host default model", () => { + const previousMemoryModel = process.env.AI_MEMORY_MODEL; + delete process.env.AI_MEMORY_MODEL; + + try { + const plugin = createMemoryPlugin(); + expect(plugin.model).toEqual({ + structuredModel: "default", + }); + } finally { + if (previousMemoryModel === undefined) { + delete process.env.AI_MEMORY_MODEL; + } else { + process.env.AI_MEMORY_MODEL = previousMemoryModel; + } + } + }); + it("parses canonical requester extraction into stored memory text", async () => { const model: PluginModel = { async completeObject() { return { object: { - memories: [ + facts: [], + preferences: [ { canonicalFact: "Prefers causes before mitigations in incident writeups.", expiresAtMs: null, - target: "requester", }, ], + procedures: [], }, }; }, @@ -481,16 +508,13 @@ describe("memory plugin storage", () => { } }); - it("normalizes nullable structured rejection responses", async () => { + it("normalizes structured rejection responses", async () => { const model: PluginModel = { async completeObject() { return { object: { decision: "reject", - target: null, - canonicalFact: null, reason: "not_public_shareable", - expiresAtMs: null, }, }; }, @@ -514,12 +538,12 @@ describe("memory plugin storage", () => { try { const { model, calls } = extractionModel([ { - target: "requester", + kind: "preference", content: "Prefers QA notes that mention database row checks.", }, { content: "Deploy runbooks live in Notion.", - target: "conversation", + kind: "fact", }, ]); const embedder = createTestEmbedder(); @@ -553,27 +577,32 @@ describe("memory plugin storage", () => { .select() .from(memorySqlSchema.juniorMemoryMemories) .orderBy(memorySqlSchema.juniorMemoryMemories.createdAtMs); - expect(rows).toEqual([ - expect.objectContaining({ - content: "Prefers QA notes that mention database row checks.", - scope: "personal", - sourcePlatform: "local", - subjectType: "user", - }), - expect.objectContaining({ - content: "Deploy runbooks live in Notion.", - scope: "conversation", - sourcePlatform: "local", - subjectType: "conversation", - }), - ]); - expect(embedder.calls).toEqual([ - [ - "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", - ], - ["Prefers QA notes that mention database row checks."], - ["Deploy runbooks live in Notion."], + expect(rows).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + content: "Prefers QA notes that mention database row checks.", + scope: "personal", + sourcePlatform: "local", + subjectType: "user", + }), + expect.objectContaining({ + content: "Deploy runbooks live in Notion.", + scope: "conversation", + sourcePlatform: "local", + subjectType: "conversation", + }), + ]), + ); + expect(rows).toHaveLength(2); + expect(embedder.calls[0]).toEqual([ + "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", ]); + expect(embedder.calls.slice(1)).toEqual( + expect.arrayContaining([ + ["Prefers QA notes that mention database row checks."], + ["Deploy runbooks live in Notion."], + ]), + ); } finally { await fixture.close(); } @@ -587,7 +616,7 @@ describe("memory plugin storage", () => { const { model, calls } = extractionModel([ { content: "Prefers retry-safe memory extraction.", - target: "requester", + kind: "preference", }, ]); const session = { @@ -642,7 +671,7 @@ describe("memory plugin storage", () => { const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ { - target: "requester", + kind: "preference", content: "duplicate memory avoidance", }, ]); @@ -682,7 +711,7 @@ describe("memory plugin storage", () => { try { const { model, calls } = extractionModel([ { - target: "requester", + kind: "preference", content: "recall turns can still learn durable facts", }, ]); @@ -726,7 +755,7 @@ describe("memory plugin storage", () => { const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ { - target: "requester", + kind: "preference", content: "private Slack context skips", }, ]); @@ -772,7 +801,7 @@ describe("memory plugin storage", () => { const fixture = await createMemoryFixture(); const { model, calls } = extractionModel([ { - target: "requester", + kind: "preference", content: "Slack message key validation", }, ]); @@ -818,7 +847,7 @@ describe("memory plugin storage", () => { const fixture = await createMemoryFixture(); const { model } = extractionModel([ { - target: "requester", + kind: "preference", content: "Prefers local passive memory QA.", }, ]); diff --git a/packages/junior-plugin-api/src/registration.ts b/packages/junior-plugin-api/src/registration.ts index 901d497f6..1800108ef 100644 --- a/packages/junior-plugin-api/src/registration.ts +++ b/packages/junior-plugin-api/src/registration.ts @@ -4,6 +4,8 @@ import type { PluginManifest } from "./manifest"; import type { PluginTasks } from "./tasks"; export interface PluginModelConfig { + /** Host model family used when no explicit structured model id is configured. */ + structuredModel?: "default" | "fast"; /** Host model id used for this plugin's structured model calls. */ structuredModelId?: string; } diff --git a/packages/junior/src/chat/config.ts b/packages/junior/src/chat/config.ts index 71769de20..1c9d9335b 100644 --- a/packages/junior/src/chat/config.ts +++ b/packages/junior/src/chat/config.ts @@ -183,7 +183,7 @@ function parseSlashCommand(rawValue: string | undefined): string { // Compile-time assertion: `getModel`'s second generic is constrained to // `keyof (typeof MODELS)[TProvider]`, so a stale default becomes a tsc error. -const DEFAULT_MODEL_ID = getModel("vercel-ai-gateway", "openai/gpt-5.4").id; +const DEFAULT_MODEL_ID = getModel("vercel-ai-gateway", "openai/gpt-5.5").id; const DEFAULT_FAST_MODEL_ID = getModel( "vercel-ai-gateway", "openai/gpt-5.4-mini", diff --git a/packages/junior/src/chat/plugins/model.ts b/packages/junior/src/chat/plugins/model.ts index bed6ea49a..502d21214 100644 --- a/packages/junior/src/chat/plugins/model.ts +++ b/packages/junior/src/chat/plugins/model.ts @@ -1,16 +1,25 @@ -import type { PluginEmbedder, PluginModel } from "@sentry/junior-plugin-api"; +import type { + PluginEmbedder, + PluginModel, + PluginModelConfig, +} from "@sentry/junior-plugin-api"; import { botConfig } from "@/chat/config"; import { completeObject, embedTexts } from "@/chat/pi/client"; /** Create the host-owned structured model capability exposed to plugins. */ export function createPluginModel( pluginName: string, - options: { structuredModelId?: string } = {}, + options: PluginModelConfig = {}, ): PluginModel { return { async completeObject(input) { + const modelId = + options.structuredModelId ?? + (options.structuredModel === "default" + ? botConfig.modelId + : botConfig.fastModelId); const result = await completeObject({ - modelId: options.structuredModelId ?? botConfig.fastModelId, + modelId, schema: input.schema, prompt: input.prompt, ...(input.system !== undefined ? { system: input.system } : {}), diff --git a/packages/junior/tests/component/config/chat-config.test.ts b/packages/junior/tests/component/config/chat-config.test.ts index a5e246b54..c6be53365 100644 --- a/packages/junior/tests/component/config/chat-config.test.ts +++ b/packages/junior/tests/component/config/chat-config.test.ts @@ -42,7 +42,7 @@ describe("chat config", () => { delete process.env.AI_MODEL; const { botConfig } = await loadConfig(); - expect(botConfig.modelId).toBe("openai/gpt-5.4"); + expect(botConfig.modelId).toBe("openai/gpt-5.5"); }); it("uses the default embedding model when AI_EMBEDDING_MODEL is unset", async () => { diff --git a/packages/junior/tests/unit/plugins/plugin-model.test.ts b/packages/junior/tests/unit/plugins/plugin-model.test.ts new file mode 100644 index 000000000..5d7585b7d --- /dev/null +++ b/packages/junior/tests/unit/plugins/plugin-model.test.ts @@ -0,0 +1,54 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +const completeObject = vi.fn(async () => ({ object: { ok: true } })); + +vi.mock("@/chat/config", () => ({ + botConfig: { + embeddingModelId: "test-embedding-model", + fastModelId: "openai/gpt-5.4-mini", + modelId: "openai/gpt-5.5", + }, +})); + +vi.mock("@/chat/pi/client", () => ({ + completeObject, + embedTexts: vi.fn(), +})); + +describe("createPluginModel", () => { + beforeEach(() => { + completeObject.mockClear(); + }); + + it("uses the fast model for structured plugin calls by default", async () => { + const { createPluginModel } = await import("@/chat/plugins/model"); + + await createPluginModel("test-plugin").completeObject({ + prompt: "classify", + schema: {} as never, + }); + + expect(completeObject).toHaveBeenCalledWith( + expect.objectContaining({ + modelId: "openai/gpt-5.4-mini", + }), + ); + }); + + it("uses the host default model when requested", async () => { + const { createPluginModel } = await import("@/chat/plugins/model"); + + await createPluginModel("test-plugin", { + structuredModel: "default", + }).completeObject({ + prompt: "extract", + schema: {} as never, + }); + + expect(completeObject).toHaveBeenCalledWith( + expect.objectContaining({ + modelId: "openai/gpt-5.5", + }), + ); + }); +}); diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 931bd5a7f..ec9c4238d 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -94,8 +94,9 @@ The `processSession` task must: 8. Extract candidate facts with a structured model output contract. 9. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or non-durable facts. -10. Assign requester or conversation target from memory-agent output, while - deriving all authority-bearing ids from runtime context. +10. Assign requester or conversation target from the memory kind returned by + the memory agent, while deriving all authority-bearing ids from runtime + context. 11. Insert accepted memories idempotently with a stable key derived through the runtime source helper, completed session reference, and extracted fact content. @@ -178,18 +179,27 @@ be used as source evidence for new facts. The memory agent model is host-owned but selected by the memory plugin. An explicit `createMemoryPlugin({ modelId })` option wins, then `AI_MEMORY_MODEL`, -then the host structured-model default. Model choice is an implementation -tuning knob; runtime context, source authority, and storage validation remain -the boundary. +then the host default model. Model choice is an implementation tuning knob; +runtime context, source authority, and storage validation remain the boundary. Memory agent output must be structured. For explicit review it should include: - decision: `store` or `reject` +- memory kind when stored: `preference`, `procedure`, or `fact` +- canonical stored content when stored +- optional expiration when stored - normalized rejection reason code when rejected -- optional adjusted memory type, subject, scope, expiration, or content rewrite -For passive extraction it should include an array of accepted candidate -memories with target, canonical stored content, and optional expiration. +For passive extraction it should include categorized arrays of accepted +candidate memories: + +- `preferences`: durable personal preferences, opinions, habits, or workflows + owned by the current requester; stored as requester memory. +- `procedures`: reusable task, process, triage-flow, or runbook instructions; + stored as conversation memory. +- `facts`: shared project, channel, operational, or runbook knowledge; stored + as conversation memory. + Conversation-target passive memories in V1 are the primary path for learning how work gets done: task procedures, runbooks, project facts, channel norms, and operational knowledge. Requester-target passive memories are secondary and diff --git a/specs/memory-plugin/tools.md b/specs/memory-plugin/tools.md index d176964d8..163dd3ebe 100644 --- a/specs/memory-plugin/tools.md +++ b/specs/memory-plugin/tools.md @@ -73,9 +73,9 @@ beyond the active task. The explicit tool path uses runtime context for source and idempotency. It must run through the memory agent's explicit-create review path. The memory agent -decides store/reject, canonical perspective-neutral content, subject, and -whether the memory targets the current requester, active conversation, or no -valid V1 target. +decides store/reject, memory kind, and canonical perspective-neutral content. +The plugin derives the storage target from the reviewed kind: requester for +`preference`, conversation for `procedure` and `fact`. The model cannot provide arbitrary scope enums, subject ids, Slack user ids, display names, aliases, or subject classes. From c25e2072f3fe337ac2dc0a178f6b4126bafed005 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 20:40:27 -0700 Subject: [PATCH 25/29] feat(memory): Extract passive memories from run transcripts Expose completed plugin task context as a run transcript so memory can evaluate user messages and bounded tool results from the completed run. Teach passive extraction to prefer durable procedure and source-of-truth knowledge while rejecting point-in-time analytics or status answers that naturally change. Co-Authored-By: GPT-5 Codex --- .../src/content/docs/extend/build-a-plugin.md | 2 +- .../src/content/docs/reference/api/README.md | 8 +- .../api/interfaces/PluginTaskContext.md | 22 +-- .../api/interfaces/PluginTaskDefinition.md | 4 +- .../api/type-aliases/PluginRunContext.md | 10 ++ .../type-aliases/PluginRunTranscriptEntry.md | 10 ++ .../api/type-aliases/PluginSessionContext.md | 10 -- .../api/type-aliases/PluginSessionMessage.md | 10 -- .../reference/api/type-aliases/PluginTasks.md | 2 +- .../api/variables/pluginRunContextSchema.md | 12 ++ .../pluginRunTranscriptEntrySchema.md | 12 ++ .../variables/pluginSessionContextSchema.md | 12 -- .../variables/pluginSessionMessageSchema.md | 12 -- .../evals/memory/workflows.eval.ts | 36 ++++ packages/junior-memory/src/agent.ts | 77 +++++--- packages/junior-memory/src/process-session.ts | 39 ++-- packages/junior-memory/tests/storage.test.ts | 167 ++++++++++++++---- packages/junior-plugin-api/src/tasks.ts | 46 +++-- packages/junior/src/api-reference.ts | 8 +- .../junior/src/chat/plugins/task-runner.ts | 86 ++++++--- .../component/plugins/plugin-tasks.test.ts | 27 ++- .../integration/local-agent-runner.test.ts | 14 +- specs/index.md | 2 +- specs/memory-plugin/extraction.md | 77 ++++---- specs/memory-plugin/index.md | 15 +- specs/memory-plugin/security.md | 8 +- specs/plugin-tasks.md | 45 ++--- specs/plugin.md | 2 +- 28 files changed, 512 insertions(+), 263 deletions(-) create mode 100644 packages/docs/src/content/docs/reference/api/type-aliases/PluginRunContext.md create mode 100644 packages/docs/src/content/docs/reference/api/type-aliases/PluginRunTranscriptEntry.md delete mode 100644 packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionContext.md delete mode 100644 packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionMessage.md create mode 100644 packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md create mode 100644 packages/docs/src/content/docs/reference/api/variables/pluginRunTranscriptEntrySchema.md delete mode 100644 packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md delete mode 100644 packages/docs/src/content/docs/reference/api/variables/pluginSessionMessageSchema.md diff --git a/packages/docs/src/content/docs/extend/build-a-plugin.md b/packages/docs/src/content/docs/extend/build-a-plugin.md index be6aaa0f8..686491c92 100644 --- a/packages/docs/src/content/docs/extend/build-a-plugin.md +++ b/packages/docs/src/content/docs/extend/build-a-plugin.md @@ -182,7 +182,7 @@ Use the smallest surface that matches the deterministic boundary your plugin nee | `beforeToolExecute(ctx)` | Deny or rewrite object-shaped tool input and set non-secret env values before a tool runs. | | `tools(ctx)` | Return host-registered tool definitions for the current turn. Tool names must be camelCase and cannot shadow core tools. | | `heartbeat(ctx)` | Run bounded periodic work from Junior's internal heartbeat route. | -| `tasks` | Register plugin-owned background tasks. V1 tasks run after completed sessions and load bounded context with `ctx.session.load()`. | +| `tasks` | Register plugin-owned background tasks. V1 tasks run after completed sessions and load bounded run context with `ctx.run.load()`. | `tools(ctx)` receives the active turn context, `ctx.state`, and `ctx.log`. Return tool definitions keyed by the public tool names your plugin owns: diff --git a/packages/docs/src/content/docs/reference/api/README.md b/packages/docs/src/content/docs/reference/api/README.md index 01adb85ac..2f22cf587 100644 --- a/packages/docs/src/content/docs/reference/api/README.md +++ b/packages/docs/src/content/docs/reference/api/README.md @@ -42,16 +42,16 @@ title: "@sentry/junior" - [ConversationSurface](/reference/api/type-aliases/conversationsurface/) - [JuniorPluginInput](/reference/api/type-aliases/juniorplugininput/) - [PluginConversationStatus](/reference/api/type-aliases/pluginconversationstatus/) -- [PluginSessionContext](/reference/api/type-aliases/pluginsessioncontext/) -- [PluginSessionMessage](/reference/api/type-aliases/pluginsessionmessage/) +- [PluginRunContext](/reference/api/type-aliases/pluginruncontext/) +- [PluginRunTranscriptEntry](/reference/api/type-aliases/pluginruntranscriptentry/) - [PluginTasks](/reference/api/type-aliases/plugintasks/) - [TranscriptPartType](/reference/api/type-aliases/transcriptparttype/) - [TranscriptRole](/reference/api/type-aliases/transcriptrole/) ## Variables -- [pluginSessionContextSchema](/reference/api/variables/pluginsessioncontextschema/) -- [pluginSessionMessageSchema](/reference/api/variables/pluginsessionmessageschema/) +- [pluginRunContextSchema](/reference/api/variables/pluginruncontextschema/) +- [pluginRunTranscriptEntrySchema](/reference/api/variables/pluginruntranscriptentryschema/) ## Functions diff --git a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md index e373774db..42ed0ef7e 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md @@ -5,7 +5,7 @@ prev: false title: "PluginTaskContext" --- -Defined in: [junior-plugin-api/src/tasks.ts:39](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L39) +Defined in: [junior-plugin-api/src/tasks.ts:51](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L51) Runtime context passed to a plugin-owned background task. @@ -33,7 +33,7 @@ Shared Drizzle database connection for plugin runtime code. > **embedder**: `PluginEmbedder` -Defined in: [junior-plugin-api/src/tasks.ts:40](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L40) +Defined in: [junior-plugin-api/src/tasks.ts:52](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L52) --- @@ -41,7 +41,7 @@ Defined in: [junior-plugin-api/src/tasks.ts:40](https://github.com/getsentry/jun > **id**: `string` -Defined in: [junior-plugin-api/src/tasks.ts:41](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L41) +Defined in: [junior-plugin-api/src/tasks.ts:53](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L53) --- @@ -61,7 +61,7 @@ Defined in: [junior-plugin-api/src/context.ts:61](https://github.com/getsentry/j > **model**: `PluginModel` -Defined in: [junior-plugin-api/src/tasks.ts:42](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L42) +Defined in: [junior-plugin-api/src/tasks.ts:54](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L54) --- @@ -69,7 +69,7 @@ Defined in: [junior-plugin-api/src/tasks.ts:42](https://github.com/getsentry/jun > **name**: `string` -Defined in: [junior-plugin-api/src/tasks.ts:43](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L43) +Defined in: [junior-plugin-api/src/tasks.ts:55](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L55) --- @@ -85,19 +85,19 @@ Defined in: [junior-plugin-api/src/context.ts:62](https://github.com/getsentry/j --- -### session +### run -> **session**: `object` +> **run**: `object` -Defined in: [junior-plugin-api/src/tasks.ts:44](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L44) +Defined in: [junior-plugin-api/src/tasks.ts:56](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L56) #### load() -> **load**(): `Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `messages`: `object`[]; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `sessionId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `toolCalls`: `string`[]; \}\> +> **load**(): `Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `runId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `transcript`: (\{ `role`: `"user"` \| `"assistant"`; `text`: `string`; `type`: `"message"`; \} \| \{ `isError`: `boolean`; `text?`: `string`; `toolName`: `string`; `type`: `"toolResult"`; \})[]; \}\> ##### Returns -`Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `messages`: `object`[]; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `sessionId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `toolCalls`: `string`[]; \}\> +`Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `runId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `transcript`: (\{ `role`: `"user"` \| `"assistant"`; `text`: `string`; `type`: `"message"`; \} \| \{ `isError`: `boolean`; `text?`: `string`; `toolName`: `string`; `type`: `"toolResult"`; \})[]; \}\> --- @@ -105,4 +105,4 @@ Defined in: [junior-plugin-api/src/tasks.ts:44](https://github.com/getsentry/jun > **state**: `PluginState` -Defined in: [junior-plugin-api/src/tasks.ts:47](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L47) +Defined in: [junior-plugin-api/src/tasks.ts:59](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L59) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md index bcea23d73..dfbfafe39 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskDefinition.md @@ -5,7 +5,7 @@ prev: false title: "PluginTaskDefinition" --- -Defined in: [junior-plugin-api/src/tasks.ts:51](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L51) +Defined in: [junior-plugin-api/src/tasks.ts:63](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L63) Plugin task handler registered by name in a plugin manifest module. @@ -15,7 +15,7 @@ Plugin task handler registered by name in a plugin manifest module. > **run**(`ctx`): `void` \| `Promise`\<`void`\> -Defined in: [junior-plugin-api/src/tasks.ts:52](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L52) +Defined in: [junior-plugin-api/src/tasks.ts:64](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L64) #### Parameters diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/PluginRunContext.md b/packages/docs/src/content/docs/reference/api/type-aliases/PluginRunContext.md new file mode 100644 index 000000000..087b67329 --- /dev/null +++ b/packages/docs/src/content/docs/reference/api/type-aliases/PluginRunContext.md @@ -0,0 +1,10 @@ +--- +editUrl: false +next: false +prev: false +title: "PluginRunContext" +--- + +> **PluginRunContext** = `z.output`\<_typeof_ [`pluginRunContextSchema`](/reference/api/variables/pluginruncontextschema/)\> + +Defined in: [junior-plugin-api/src/tasks.ts:48](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L48) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/PluginRunTranscriptEntry.md b/packages/docs/src/content/docs/reference/api/type-aliases/PluginRunTranscriptEntry.md new file mode 100644 index 000000000..1bf352e2b --- /dev/null +++ b/packages/docs/src/content/docs/reference/api/type-aliases/PluginRunTranscriptEntry.md @@ -0,0 +1,10 @@ +--- +editUrl: false +next: false +prev: false +title: "PluginRunTranscriptEntry" +--- + +> **PluginRunTranscriptEntry** = `z.output`\<_typeof_ [`pluginRunTranscriptEntrySchema`](/reference/api/variables/pluginruntranscriptentryschema/)\> + +Defined in: [junior-plugin-api/src/tasks.ts:44](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L44) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionContext.md b/packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionContext.md deleted file mode 100644 index 3da4e3e7a..000000000 --- a/packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionContext.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -editUrl: false -next: false -prev: false -title: "PluginSessionContext" ---- - -> **PluginSessionContext** = `z.output`\<_typeof_ [`pluginSessionContextSchema`](/reference/api/variables/pluginsessioncontextschema/)\> - -Defined in: [junior-plugin-api/src/tasks.ts:36](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L36) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionMessage.md b/packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionMessage.md deleted file mode 100644 index 3786c8216..000000000 --- a/packages/docs/src/content/docs/reference/api/type-aliases/PluginSessionMessage.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -editUrl: false -next: false -prev: false -title: "PluginSessionMessage" ---- - -> **PluginSessionMessage** = `z.output`\<_typeof_ [`pluginSessionMessageSchema`](/reference/api/variables/pluginsessionmessageschema/)\> - -Defined in: [junior-plugin-api/src/tasks.ts:34](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L34) diff --git a/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md b/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md index 51592a303..a73313feb 100644 --- a/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md +++ b/packages/docs/src/content/docs/reference/api/type-aliases/PluginTasks.md @@ -7,6 +7,6 @@ title: "PluginTasks" > **PluginTasks** = `Record`\<`string`, [`PluginTaskDefinition`](/reference/api/interfaces/plugintaskdefinition/)\> -Defined in: [junior-plugin-api/src/tasks.ts:56](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L56) +Defined in: [junior-plugin-api/src/tasks.ts:68](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L68) Task handlers keyed by the plugin-owned task name. diff --git a/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md b/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md new file mode 100644 index 000000000..3fb1b9082 --- /dev/null +++ b/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md @@ -0,0 +1,12 @@ +--- +editUrl: false +next: false +prev: false +title: "pluginRunContextSchema" +--- + +> `const` **pluginRunContextSchema**: `ZodObject`\<\{ `completedAtMs`: `ZodNumber`; `conversationId`: `ZodString`; `destination`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; \}, `$strict`\>\], `"platform"`\>; `requester`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>, `ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"local"`\>; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>\], `"platform"`\>; `runId`: `ZodString`; `source`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `messageTs`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `threadTs`: `ZodOptional`\<`ZodString`\>; `type`: `ZodEnum`\<\{ `priv`: `"priv"`; `pub`: `"pub"`; \}\>; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; `type`: `ZodLiteral`\<`"priv"`\>; \}, `$strict`\>\], `"platform"`\>; `transcript`: `ZodArray`\<`ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; `type`: `ZodLiteral`\<`"message"`\>; \}, `$strict`\>, `ZodObject`\<\{ `isError`: `ZodBoolean`; `text`: `ZodOptional`\<`ZodString`\>; `toolName`: `ZodString`; `type`: `ZodLiteral`\<`"toolResult"`\>; \}, `$strict`\>\], `"type"`\>\>; \}, `$strict`\> + +Defined in: [junior-plugin-api/src/tasks.ts:32](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L32) + +Runtime-owned completed-run projection exposed to plugin tasks. diff --git a/packages/docs/src/content/docs/reference/api/variables/pluginRunTranscriptEntrySchema.md b/packages/docs/src/content/docs/reference/api/variables/pluginRunTranscriptEntrySchema.md new file mode 100644 index 000000000..f4c604c90 --- /dev/null +++ b/packages/docs/src/content/docs/reference/api/variables/pluginRunTranscriptEntrySchema.md @@ -0,0 +1,12 @@ +--- +editUrl: false +next: false +prev: false +title: "pluginRunTranscriptEntrySchema" +--- + +> `const` **pluginRunTranscriptEntrySchema**: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; `type`: `ZodLiteral`\<`"message"`\>; \}, `$strict`\>, `ZodObject`\<\{ `isError`: `ZodBoolean`; `text`: `ZodOptional`\<`ZodString`\>; `toolName`: `ZodString`; `type`: `ZodLiteral`\<`"toolResult"`\>; \}, `$strict`\>\], `"type"`\> + +Defined in: [junior-plugin-api/src/tasks.ts:13](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L13) + +One normalized transcript entry from the completed run exposed to plugin tasks. diff --git a/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md b/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md deleted file mode 100644 index 18bf18b64..000000000 --- a/packages/docs/src/content/docs/reference/api/variables/pluginSessionContextSchema.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -editUrl: false -next: false -prev: false -title: "pluginSessionContextSchema" ---- - -> `const` **pluginSessionContextSchema**: `ZodObject`\<\{ `completedAtMs`: `ZodNumber`; `conversationId`: `ZodString`; `destination`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; \}, `$strict`\>\], `"platform"`\>; `messages`: `ZodArray`\<`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; \}, `$strict`\>\>; `requester`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>, `ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"local"`\>; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>\], `"platform"`\>; `sessionId`: `ZodString`; `source`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `messageTs`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `threadTs`: `ZodOptional`\<`ZodString`\>; `type`: `ZodEnum`\<\{ `priv`: `"priv"`; `pub`: `"pub"`; \}\>; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; `type`: `ZodLiteral`\<`"priv"`\>; \}, `$strict`\>\], `"platform"`\>; `toolCalls`: `ZodArray`\<`ZodString`\>; \}, `$strict`\> - -Defined in: [junior-plugin-api/src/tasks.ts:21](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L21) - -Runtime-owned completed-session projection exposed to plugin tasks. diff --git a/packages/docs/src/content/docs/reference/api/variables/pluginSessionMessageSchema.md b/packages/docs/src/content/docs/reference/api/variables/pluginSessionMessageSchema.md deleted file mode 100644 index d3b1ff873..000000000 --- a/packages/docs/src/content/docs/reference/api/variables/pluginSessionMessageSchema.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -editUrl: false -next: false -prev: false -title: "pluginSessionMessageSchema" ---- - -> `const` **pluginSessionMessageSchema**: `ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; \}, `$strict`\> - -Defined in: [junior-plugin-api/src/tasks.ts:13](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L13) - -Bounded message projection exposed by completed-session plugin tasks. diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index 93d28c3d5..05340c30a 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -546,6 +546,42 @@ describeEval("Memory Workflows", slackEvals, (it) => { }); }); + const passiveVolatileAnswerThread = { + channel_type: "channel", + id: "thread-memory-passive-volatile-answer", + channel_id: "CMEMORYVOLATILE", + thread_ts: "17000000.memory-volatile-answer", + } satisfies MemoryThread; + + it("when organic conversation reports a point-in-time analytics answer, store no memory", async ({ + run, + }) => { + await clearMemories(); + await run({ + overrides: memoryPluginOverrides, + events: [ + mention( + "The analytics query says today's signup conversion rate is 8.4%.", + { + thread: passiveVolatileAnswerThread, + }, + ), + ], + criteria: rubric({ + pass: [ + "The assistant treats the analytics value as a point-in-time answer, not durable memory.", + "The assistant does not claim it saved the conversion rate as memory.", + ], + fail: [ + "Do not store the current conversion-rate value as memory.", + "Do not describe point-in-time analytics answers as durable operational knowledge.", + ], + }), + }); + + expect(await readMemories(passiveVolatileAnswerThread)).toEqual([]); + }, 120_000); + const thirdPartyRememberThread = { id: "thread-memory-third-party-remember", channel_id: "CMEMORYTHIRDPARTY", diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 87570b17e..4c128aaf1 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -39,17 +39,28 @@ const extractSessionRequestSchema = z ) .max(10) .default([]), - messages: z + runtimeContext: memoryRuntimeContextSchema, + transcript: z .array( - z - .object({ - role: z.enum(["user", "assistant"]), - text: z.string().min(1), - }) - .strict(), + z.discriminatedUnion("type", [ + z + .object({ + type: z.literal("message"), + role: z.enum(["user", "assistant"]), + text: z.string().min(1), + }) + .strict(), + z + .object({ + type: z.literal("toolResult"), + toolName: z.string().min(1), + isError: z.boolean(), + text: z.string().min(1), + }) + .strict(), + ]), ) .min(1), - runtimeContext: memoryRuntimeContextSchema, }) .strict(); @@ -116,13 +127,13 @@ const extractMemoriesResponseSchema = z .array(extractedMemorySchema) .max(5) .describe( - "Reusable public/shareable task, process, triage-flow, or runbook instructions from this completed turn. These are stored as conversation memory.", + "Reusable public/shareable task, process, triage-flow, source-of-truth, lookup, or runbook instructions learned from this completed run. These are stored as conversation memory.", ), facts: z .array(extractedMemorySchema) .max(5) .describe( - "Public/shareable shared project, channel, operational, or runbook facts from this completed turn. These are stored as conversation memory.", + "Public/shareable stable project, channel, operational, or runbook facts from this completed run. These are stored as conversation memory. Exclude point-in-time query answers whose values can change.", ), preferences: z .array(extractedMemorySchema) @@ -169,7 +180,8 @@ const MEMORY_REVIEW_SYSTEM = [ ].join("\n"); const MEMORY_EXTRACTION_SYSTEM = [ "You are Junior's passive memory extraction agent. Return only structured memories worth storing.", - "Use only the user-authored message as source evidence. Assistant text is rejection context only.", + "Use the completed run transcript as source evidence, including user-authored messages and tool results.", + "Assistant text is context for interpreting the run, not independent evidence for new facts.", "Reject secrets, credentials, private or sensitive personal details, gossip, speculative claims about other people, assistant/system implementation details, vague references, and low-durability chatter.", "If no public, durable, self-contained memory remains after rewriting, return an empty memories array.", ].join("\n"); @@ -253,8 +265,8 @@ function memoryKindsContext(): string { return [ "", "- preference: a durable personal preference, opinion, habit, or workflow owned by the current requester. Stored as requester memory.", - "- procedure: reusable instructions for how a task, process, triage flow, or runbook should be done. Stored as conversation memory.", - "- fact: shared project, channel, operational, or runbook knowledge that is not a personal requester preference. Stored as conversation memory.", + "- procedure: reusable instructions for how a task, lookup, investigation, process, triage flow, or runbook should be done. Store the method, source-of-truth, prerequisite, or decision path when it took effort to discover. Stored as conversation memory.", + "- fact: stable shared project, channel, operational, or runbook knowledge that is not a personal requester preference. Direct answers to user inquiries qualify only when they are durable beyond this run. Stored as conversation memory.", "", ].join("\n"); } @@ -295,24 +307,31 @@ function reviewPrompt(request: CreateMemoryRequest): string { return sections.join("\n"); } -function sessionMessagesContext(request: ExtractSessionRequest): string { +function runTranscriptContext(request: ExtractSessionRequest): string { return [ - "", - ...request.messages.map((message, index) => - [ - ``, - escapeXml(message.text), + "", + ...request.transcript.map((entry, index) => { + if (entry.type === "toolResult") { + return [ + ``, + escapeXml(entry.text), + "", + ].join("\n"); + } + return [ + ``, + escapeXml(entry.text), "", - ].join("\n"), - ), - "", + ].join("\n"); + }), + "", ].join("\n"); } function sessionExtractionPrompt(request: ExtractSessionRequest): string { return [ "", - "Extract durable memories from this completed agent-run session using the runtime-owned context below.", + "Extract durable memories from this completed agent run using the runtime-owned context below.", "", runtimeDescription({ runtimeContext: request.runtimeContext, @@ -322,14 +341,18 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { "", memoryKindsContext(), "", - sessionMessagesContext(request), + runTranscriptContext(request), "", "", "- Return at most five memories.", - "- Use user role messages as the only source of storable facts.", - "- Use assistant role messages only to reject confirmations, follow-up questions, or memory-management turns.", + "- Use user messages and successful tool results as source evidence for storable facts.", + "- Use failed tool results only when the failure reveals durable process knowledge, not transient errors.", + "- Use assistant messages only as context; do not store the assistant's claims unless supported by user messages or tool results.", "- Return one memory per distinct fact.", - "- Ignore advice, how-to, search, recall, planning, list, inspect, and remove requests unless user messages also state a durable fact.", + "- Prefer storing how to achieve a result: stable source-of-truth, query location, workflow, prerequisite, caveat, or reusable decision path that took effort to discover.", + "- Store direct answers to user inquiries only when they are stable operational/project knowledge, not values that naturally change over time.", + "- Do not store point-in-time analytics, search, issue, metric, incident, availability, or status answers just because a tool produced them.", + "- Do not store the fact that the user asked for advice, search, recall, planning, listing, inspection, or removal. Store only stable knowledge discovered in response, such as a reusable method or source-of-truth.", "- Fill procedures with reusable task/process/runbook instructions.", "- Fill facts with shared team, project, channel, runbook, or operational knowledge.", "- Fill preferences only with clear durable facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior-memory/src/process-session.ts index dbcd13c88..5cee96403 100644 --- a/packages/junior-memory/src/process-session.ts +++ b/packages/junior-memory/src/process-session.ts @@ -73,39 +73,42 @@ async function getTaskMemories( export async function processMemorySession( context: PluginTaskContext, ): Promise { - const session = await context.session.load(); + const run = await context.run.load(); // Explicit memory mutation tools already own the user's memory-management intent. if ( - session.toolCalls.some((toolName) => - MEMORY_MUTATION_TOOL_NAMES.has(toolName), + run.transcript.some( + (entry) => + entry.type === "toolResult" && + !entry.isError && + MEMORY_MUTATION_TOOL_NAMES.has(entry.toolName), ) ) { return; } // V1 passive learning only stores public channel facts outside local QA. - if (session.source.platform !== "local" && isPrivateSource(session.source)) { + if (run.source.platform !== "local" && isPrivateSource(run.source)) { return; } - const sourceKey = getSourceKey(session.source); + const sourceKey = getSourceKey(run.source); if (!sourceKey) { return; } - const messages = session.messages - .filter((message) => message.text.trim()) - .map((message) => ({ role: message.role, text: message.text.trim() })); - const userText = messages - .filter((message) => message.role === "user") - .map((message) => message.text) + const transcript = run.transcript + .filter((entry) => entry.text?.trim()) + .map((entry) => ({ ...entry, text: entry.text!.trim() })); + const evidenceText = transcript + .filter((entry) => entry.type === "toolResult" || entry.role === "user") + .map((entry) => entry.text) .join("\n\n") .trim(); - if (!userText) { + if (!evidenceText) { return; } const runtimeContext = memoryRuntimeContextSchema.parse({ - conversationId: session.conversationId, - ...(session.requester ? { requester: session.requester } : {}), - source: session.source, + conversationId: run.conversationId, + ...(run.requester ? { requester: run.requester } : {}), + source: run.source, }); const store = createMemoryStore(context.db as MemoryDb, runtimeContext, { embedder: context.embedder, @@ -113,14 +116,14 @@ export async function processMemorySession( const memories = await getTaskMemories(context, async () => { const existingMemories = await store.searchMemories({ limit: 10, - query: userText, + query: evidenceText, }); const agent = createMemoryAgent(context.model); return await agent.extractSessionMemories({ existingMemories: existingMemories.map((memory) => ({ content: memory.content, })), - messages, + transcript, runtimeContext, }); }); @@ -129,7 +132,7 @@ export async function processMemorySession( } for (const memory of memories) { - const input = passiveInput(session.sessionId, memory, sourceKey); + const input = passiveInput(run.runId, memory, sourceKey); if (memory.target === "conversation") { await store.createConversationMemory(input); continue; diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 12d5ece4c..c898b7302 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -293,11 +293,11 @@ function localContext( type MemoryTaskContext = PluginTaskContext; -function completedSession( +function completedRun( overrides: Partial< - Awaited> + Awaited> > = {}, -): NonNullable>> { +): NonNullable>> { const runtime = localContext(); return { completedAtMs: TEST_NOW_MS, @@ -306,20 +306,21 @@ function completedSession( platform: "local", conversationId: runtime.conversationId, }, - messages: [ + transcript: [ { + type: "message", role: "user", text: "I prefer terse PR summaries.", }, { + type: "message", role: "assistant", text: "Got it.", }, ], requester: runtime.requester, - sessionId: "local-turn-1", + runId: "local-turn-1", source: runtime.source, - toolCalls: [], ...overrides, }; } @@ -328,13 +329,13 @@ function processSessionContext( overrides: Partial = {}, ): MemoryTaskContext { const runtime = localContext(); - const session = - overrides.session ?? + const run = + overrides.run ?? ({ async load() { - return completedSession(); + return completedRun(); }, - } satisfies MemoryTaskContext["session"]); + } satisfies MemoryTaskContext["run"]); return { db: overrides.db ?? {}, embedder: overrides.embedder ?? createTestEmbedder(), @@ -350,7 +351,7 @@ function processSessionContext( ]).model, name: "processSession", plugin: { name: "memory" }, - session, + run, state: memoryState, ...overrides, }; @@ -469,12 +470,14 @@ describe("memory plugin storage", () => { await expect( agent.extractSessionMemories({ - messages: [ + transcript: [ { + type: "message", role: "user", text: "For incident writeups, causes go before mitigations.", }, { + type: "message", role: "assistant", text: "Got it.", }, @@ -553,15 +556,17 @@ describe("memory plugin storage", () => { db: memoryDb(fixture), embedder, model, - session: { + run: { async load() { - return completedSession({ - messages: [ + return completedRun({ + transcript: [ { + type: "message", role: "user", text: "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", }, { + type: "message", role: "assistant", text: "I will keep that in mind.", }, @@ -608,6 +613,78 @@ describe("memory plugin storage", () => { } }, 15_000); + it("passes tool result evidence to passive extraction", async () => { + const fixture = await createMemoryFixture(); + + try { + const { model, calls } = extractionModel([ + { + content: + "Signup funnel analysis should use the modeled warehouse cohort table.", + kind: "procedure", + }, + ]); + const embedder = createTestEmbedder(); + + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + embedder, + model, + run: { + async load() { + return completedRun({ + transcript: [ + { + type: "message", + role: "user", + text: "Where should signup funnel analysis come from?", + }, + { + type: "toolResult", + toolName: "queryAnalyticsCatalog", + isError: false, + text: "The modeled warehouse cohort table is the source of truth for signup funnel analysis.", + }, + { + type: "message", + role: "assistant", + text: "Use the modeled warehouse cohort table.", + }, + ], + }); + }, + }, + }), + ); + + expect(calls[0]?.prompt).toContain(" { const fixture = await createMemoryFixture(); @@ -619,11 +696,12 @@ describe("memory plugin storage", () => { kind: "preference", }, ]); - const session = { + const run = { async load() { - return completedSession({ - messages: [ + return completedRun({ + transcript: [ { + type: "message", role: "user", text: "I prefer retry-safe memory extraction.", }, @@ -636,7 +714,7 @@ describe("memory plugin storage", () => { processSessionContext({ db: memoryDb(fixture), model, - session, + run, state, }), ); @@ -648,7 +726,7 @@ describe("memory plugin storage", () => { throw new Error("model should not run on cached retry"); }, }, - session, + run, state, }), ); @@ -681,16 +759,22 @@ describe("memory plugin storage", () => { processSessionContext({ db: memoryDb(fixture), model, - session: { + run: { async load() { - return completedSession({ - messages: [ + return completedRun({ + transcript: [ { + type: "message", role: "user", text: "Remember that I prefer duplicate memory avoidance.", }, + { + type: "toolResult", + toolName: "createMemory", + isError: false, + text: "Memory saved.", + }, ], - toolCalls: ["createMemory"], }); }, }, @@ -720,16 +804,22 @@ describe("memory plugin storage", () => { processSessionContext({ db: memoryDb(fixture), model, - session: { + run: { async load() { - return completedSession({ - messages: [ + return completedRun({ + transcript: [ { + type: "message", role: "user", text: "I prefer recall turns to still learn durable facts.", }, + { + type: "toolResult", + toolName: "searchMemories", + isError: false, + text: "No matching memories found.", + }, ], - toolCalls: ["listMemories", "searchMemories"], }); }, }, @@ -769,13 +859,14 @@ describe("memory plugin storage", () => { processSessionContext({ db: memoryDb(fixture), model, - session: { + run: { async load() { - return completedSession({ + return completedRun({ conversationId: "slack:D123:1718800000.000000", destination: slackDestination(privateContext), - messages: [ + transcript: [ { + type: "message", role: "user", text: "I prefer private Slack context skips.", }, @@ -812,13 +903,14 @@ describe("memory plugin storage", () => { processSessionContext({ db: memoryDb(fixture), model, - session: { + run: { async load() { - return completedSession({ + return completedRun({ conversationId: "slack:C123:missing-message-key", destination: slackDestination(runtime), - messages: [ + transcript: [ { + type: "message", role: "user", text: "I prefer Slack message key validation.", }, @@ -858,16 +950,17 @@ describe("memory plugin storage", () => { processSessionContext({ db: memoryDb(fixture), model, - session: { + run: { async load() { - return completedSession({ + return completedRun({ conversationId: runtime.conversationId, destination: { platform: "local", conversationId: runtime.conversationId, }, - messages: [ + transcript: [ { + type: "message", role: "user", text: "I prefer local passive memory QA.", }, diff --git a/packages/junior-plugin-api/src/tasks.ts b/packages/junior-plugin-api/src/tasks.ts index 60a908924..651acd870 100644 --- a/packages/junior-plugin-api/src/tasks.ts +++ b/packages/junior-plugin-api/src/tasks.ts @@ -2,38 +2,50 @@ * Public plugin background-task contracts. * * Plugins register small task handlers, while Junior core owns durable - * scheduling, queue delivery, retries, and the bounded session projection. + * scheduling, queue delivery, retries, and the bounded run projection. */ import { z } from "zod"; import type { PluginContext, PluginEmbedder, PluginModel } from "./context"; import { destinationSchema, requesterSchema, sourceSchema } from "./schemas"; import type { PluginState } from "./state"; -/** Bounded message projection exposed by completed-session plugin tasks. */ -export const pluginSessionMessageSchema = z - .object({ - role: z.enum(["user", "assistant"]), - text: z.string().min(1), - }) - .strict(); +/** One normalized transcript entry from the completed run exposed to plugin tasks. */ +export const pluginRunTranscriptEntrySchema = z.discriminatedUnion("type", [ + z + .object({ + type: z.literal("message"), + role: z.enum(["user", "assistant"]), + text: z.string().min(1), + }) + .strict(), + z + .object({ + type: z.literal("toolResult"), + toolName: z.string().min(1), + isError: z.boolean(), + text: z.string().min(1).optional(), + }) + .strict(), +]); -/** Runtime-owned completed-session projection exposed to plugin tasks. */ -export const pluginSessionContextSchema = z +/** Runtime-owned completed-run projection exposed to plugin tasks. */ +export const pluginRunContextSchema = z .object({ completedAtMs: z.number().finite(), conversationId: z.string().min(1), destination: destinationSchema, - messages: z.array(pluginSessionMessageSchema), requester: requesterSchema, - sessionId: z.string().min(1), + runId: z.string().min(1), source: sourceSchema, - toolCalls: z.array(z.string().min(1)), + transcript: z.array(pluginRunTranscriptEntrySchema), }) .strict(); -export type PluginSessionMessage = z.output; +export type PluginRunTranscriptEntry = z.output< + typeof pluginRunTranscriptEntrySchema +>; -export type PluginSessionContext = z.output; +export type PluginRunContext = z.output; /** Runtime context passed to a plugin-owned background task. */ export interface PluginTaskContext extends PluginContext { @@ -41,8 +53,8 @@ export interface PluginTaskContext extends PluginContext { id: string; model: PluginModel; name: string; - session: { - load(): Promise; + run: { + load(): Promise; }; state: PluginState; } diff --git a/packages/junior/src/api-reference.ts b/packages/junior/src/api-reference.ts index 94bc48728..6af3efc7e 100644 --- a/packages/junior/src/api-reference.ts +++ b/packages/junior/src/api-reference.ts @@ -10,15 +10,15 @@ export type { JuniorPluginSetOptions, } from "./plugins"; export type { - PluginSessionContext, - PluginSessionMessage, + PluginRunContext, + PluginRunTranscriptEntry, PluginTaskContext, PluginTaskDefinition, PluginTasks, } from "@sentry/junior-plugin-api"; export { - pluginSessionContextSchema, - pluginSessionMessageSchema, + pluginRunContextSchema, + pluginRunTranscriptEntrySchema, } from "@sentry/junior-plugin-api"; export { createJuniorReporting } from "./reporting"; export type { diff --git a/packages/junior/src/chat/plugins/task-runner.ts b/packages/junior/src/chat/plugins/task-runner.ts index 4d961c049..5c3440b49 100644 --- a/packages/junior/src/chat/plugins/task-runner.ts +++ b/packages/junior/src/chat/plugins/task-runner.ts @@ -2,16 +2,16 @@ * Plugin background-task orchestration. * * Core schedules tasks from completed sessions and exposes plugins only a - * bounded session projection rather than live runtime internals or queue + * bounded run projection rather than live runtime internals or queue * payloads. */ import type { PluginRegistration, - PluginSessionContext, - PluginSessionMessage, + PluginRunContext, + PluginRunTranscriptEntry, PluginTaskContext, } from "@sentry/junior-plugin-api"; -import { pluginSessionContextSchema } from "@sentry/junior-plugin-api"; +import { pluginRunContextSchema } from "@sentry/junior-plugin-api"; import { getDb } from "@/chat/db"; import { createPluginLogger } from "@/chat/plugins/logging"; import { createPluginEmbedder, createPluginModel } from "@/chat/plugins/model"; @@ -19,7 +19,9 @@ import { createPluginState } from "@/chat/plugins/state"; import type { PiMessage } from "@/chat/pi/messages"; import { getPiMessageRole, - getSuccessfulToolCalls, + isToolResultError, + isToolResultMessage, + normalizeToolNameFromResult, stripRuntimeTurnContext, } from "@/chat/respond-helpers"; import { getAgentTurnSessionRecord } from "@/chat/state/turn-session"; @@ -55,6 +57,20 @@ function textPart(value: unknown): string | undefined { return undefined; } +function serializeResultValue(value: unknown): string { + if (typeof value === "string") { + return value; + } + if (value === undefined || value === null) { + return ""; + } + try { + return JSON.stringify(value, null, 2); + } catch { + return ""; + } +} + function messageText(message: PiMessage): string { const content = (message as { content?: unknown }).content; if (typeof content === "string") { @@ -66,6 +82,19 @@ function messageText(message: PiMessage): string { return sanitizeText(content.map(textPart).filter(Boolean).join("\n")); } +function toolResultText(message: PiMessage): string { + const record = message as unknown as Record; + const parts = [ + messageText(message), + serializeResultValue(record.stdout), + serializeResultValue(record.stderr), + serializeResultValue(record.output), + serializeResultValue(record.result), + serializeResultValue(record.toolResult), + ].filter(Boolean); + return sanitizeText(parts.join("\n")); +} + function sanitizeText(text: string): string { return text .replace( @@ -80,16 +109,32 @@ function sanitizeText(text: string): string { .trim(); } -function sessionMessage(message: PiMessage): PluginSessionMessage | undefined { +function runTranscriptEntry( + message: PiMessage, +): PluginRunTranscriptEntry | undefined { const role = getPiMessageRole(message); - if (role !== "user" && role !== "assistant") { + if (role === "user" || role === "assistant") { + const text = messageText(message); + if (!text) { + return undefined; + } + return { type: "message", role, text }; + } + + if (!isToolResultMessage(message)) { return undefined; } - const text = messageText(message); - if (!text) { + const toolName = normalizeToolNameFromResult(message); + if (!toolName) { return undefined; } - return { role, text }; + const text = toolResultText(message); + return { + type: "toolResult", + toolName, + isError: isToolResultError(message), + ...(text ? { text } : {}), + }; } async function withPluginTaskLock( @@ -113,10 +158,10 @@ async function withPluginTaskLock( } } -/** Load the bounded completed-session projection exposed to plugin tasks. */ -async function loadPluginSession( +/** Load the bounded completed-run projection exposed to plugin tasks. */ +async function loadPluginRun( params: PluginTaskParams, -): Promise { +): Promise { const record = await getAgentTurnSessionRecord( params.conversationId, params.sessionId, @@ -140,17 +185,16 @@ async function loadPluginSession( const sessionMessages = stripRuntimeTurnContext( record.piMessages.slice(record.turnStartMessageIndex ?? 0), ); - return pluginSessionContextSchema.parse({ + return pluginRunContextSchema.parse({ completedAtMs: record.updatedAtMs, conversationId: record.conversationId, destination: record.destination, - messages: sessionMessages - .map(sessionMessage) - .filter((message): message is PluginSessionMessage => Boolean(message)), requester: record.requester, - sessionId: record.sessionId, + runId: record.sessionId, source: record.source, - toolCalls: getSuccessfulToolCalls(sessionMessages), + transcript: sessionMessages + .map(runTranscriptEntry) + .filter((entry): entry is PluginRunTranscriptEntry => Boolean(entry)), }); } @@ -169,9 +213,9 @@ function taskPluginContext( model: createPluginModel(pluginName, plugin.model), name: message.name, plugin: { name: pluginName }, - session: { + run: { async load() { - return await loadPluginSession(sessionParams); + return await loadPluginRun(sessionParams); }, }, state: createPluginState(pluginName), diff --git a/packages/junior/tests/component/plugins/plugin-tasks.test.ts b/packages/junior/tests/component/plugins/plugin-tasks.test.ts index 0e0d87201..8d40861f5 100644 --- a/packages/junior/tests/component/plugins/plugin-tasks.test.ts +++ b/packages/junior/tests/component/plugins/plugin-tasks.test.ts @@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto"; import { createLocalSource, defineJuniorPlugin, - type PluginSessionContext, + type PluginRunContext, } from "@sentry/junior-plugin-api"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { PiMessage } from "@/chat/pi/messages"; @@ -92,7 +92,7 @@ describe("plugin background tasks", () => { }; const runSource = createLocalSource(runConversationId); const queue = new PluginTaskQueueTestAdapter(); - const loadedSessions: PluginSessionContext[] = []; + const loadedRuns: PluginRunContext[] = []; const { setPlugins } = await import("@/chat/plugins/agent-hooks"); const { processPluginTask, scheduleSessionCompletedPluginTasks } = await import("@/chat/plugins/task-runner"); @@ -108,7 +108,7 @@ describe("plugin background tasks", () => { tasks: { processSession: { async run(ctx) { - loadedSessions.push(await ctx.session.load()); + loadedRuns.push(await ctx.run.load()); }, }, }, @@ -141,6 +141,12 @@ describe("plugin background tasks", () => { }, ], }, + { + role: "toolResult", + toolName: "searchDocs", + isError: false, + content: "Incident runbooks live in Notion.", + }, { role: "assistant", content: "Understood.", @@ -172,16 +178,25 @@ describe("plugin background tasks", () => { await processPluginTask(messages[0]!); - expect(loadedSessions).toEqual([ + expect(loadedRuns).toEqual([ expect.objectContaining({ conversationId: runConversationId, destination: runDestination, - messages: [ + runId: runSessionId, + transcript: [ { + type: "message", role: "user", text: "I prefer pull request summaries with test evidence.", }, { + type: "toolResult", + toolName: "searchDocs", + isError: false, + text: "Incident runbooks live in Notion.", + }, + { + type: "message", role: "assistant", text: "Understood.", }, @@ -192,9 +207,7 @@ describe("plugin background tasks", () => { userId: "local-cli", userName: "local", }, - sessionId: runSessionId, source: runSource, - toolCalls: [], }), ]); }); diff --git a/packages/junior/tests/integration/local-agent-runner.test.ts b/packages/junior/tests/integration/local-agent-runner.test.ts index 180bcc2b9..e3c05afc9 100644 --- a/packages/junior/tests/integration/local-agent-runner.test.ts +++ b/packages/junior/tests/integration/local-agent-runner.test.ts @@ -6,7 +6,7 @@ import type { } from "@/chat/respond"; import { defineJuniorPlugin, - type PluginSessionContext, + type PluginRunContext, } from "@sentry/junior-plugin-api"; import { normalizeLocalConversationId } from "@/chat/local/conversation"; import { @@ -228,7 +228,7 @@ describe("local agent runner", () => { }); expect(conversationId).toBeDefined(); - const loadedSessions: PluginSessionContext[] = []; + const loadedRuns: PluginRunContext[] = []; const { setPlugins } = await import("@/chat/plugins/agent-hooks"); setPlugins([ defineJuniorPlugin({ @@ -240,7 +240,7 @@ describe("local agent runner", () => { tasks: { captureSession: { async run(ctx) { - loadedSessions.push(await ctx.session.load()); + loadedRuns.push(await ctx.run.load()); }, }, }, @@ -277,24 +277,26 @@ describe("local agent runner", () => { setPlugins([]); } - expect(loadedSessions).toEqual([ + expect(loadedRuns).toEqual([ expect.objectContaining({ conversationId, destination: { platform: "local", conversationId, }, - messages: [ + runId: "local-turn-1", + transcript: [ { + type: "message", role: "user", text: "capture this local turn", }, { + type: "message", role: "assistant", text: "captured", }, ], - sessionId: "local-turn-1", requester: expect.objectContaining({ platform: "local", userId: "local-cli", diff --git a/specs/index.md b/specs/index.md index 92d66ef59..14cfad24b 100644 --- a/specs/index.md +++ b/specs/index.md @@ -81,7 +81,7 @@ For chat/agent/Slack execution and response behavior: - `specs/chat-architecture.md` owns the end-to-end platform-event-to-agent-run data flow, platform adapter boundary, data authority map, and module boundaries. - `specs/task-execution.md` owns durable conversation mailbox execution, queue wake-up semantics, conversation leases, cooperative yield, and heartbeat repair. - `specs/conversation-storage.md` owns SQL-backed queryable conversation record, transcript-storage exclusions, and Vercel-safe migration/backfill behavior. -- `specs/plugin-tasks.md` owns plugin-owned durable background task registration, queue dispatch, and completed-session projections. +- `specs/plugin-tasks.md` owns plugin-owned durable background task registration, queue dispatch, and completed-run projections. - `specs/plugin-database.md` owns plugin packaged SQL migration discovery/application and the `ctx.db` hook surface. - `specs/plugin-cli.md` owns future plugin-contributed host CLI command discovery, dispatch, admin context, and redaction contracts. - `specs/memory-plugin/index.md` owns the long-term memory plugin's storage, recall, passive learning, tools, visibility, and lifecycle contracts. diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index ec9c4238d..45fa76876 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -7,7 +7,7 @@ ## Purpose -Define passive memory learning through completed agent-run session processing +Define passive memory learning through completed agent-run processing and the memory-owned internal extraction agent. ## What Belongs In Memory @@ -29,8 +29,9 @@ A candidate may be stored only when all of these are true: 6. It has a runtime-derived visibility scope. 7. It contains no credential, token, private key, password, recovery code, connection string with credentials, payment card number, or similar secret. -8. It is not merely an assistant claim, assistant action, tool result summary, - system capability, implementation detail, or prompt/routing rule. +8. It is not merely an assistant claim, assistant action, assistant summary of + a tool result, system capability, implementation detail, or prompt/routing + rule. 9. Personal-scoped identity, preference, or relationship facts are first-person facts authored by the current requester, not third-person profile facts about someone else. @@ -43,6 +44,7 @@ Examples that can be stored: - `Prefers concise technical answers.` - `Production deploy window is Mondays from 10:00 to 12:00 UTC.` - `Incident follow-up lives in Linear.` +- `Revenue cohort analysis should use the finance-modeled warehouse tables.` - `The Acme migration is paused.` Examples that must not be stored: @@ -58,12 +60,14 @@ Examples that must not be stored: - `The user is somewhere next week.` - `The user has not decided what to do.` - `Junior can use the scheduler plugin.` +- `Today's signup conversion rate is 8.4%.` +- `There are 17 open incidents right now.` ## Passive Learning -The memory plugin processes completed agent-run sessions through a typed +The memory plugin processes completed agent runs through a typed `session.completed` plugin task. Conceptually this is a memory compaction pass: -the task loads a bounded completed-session projection and asks the memory-owned +the task loads a bounded completed-run projection and asks the memory-owned extraction agent which durable public/shareable facts, if any, should survive as long-term memory. @@ -75,11 +79,11 @@ The `processSession` task must: 2. Receive task params that contain stable references only, such as `conversationId` and `sessionId`. Params must not duplicate raw messages, source, destination, requester, tool payloads, or model output. -3. Load a bounded core-owned session projection from transcript/session storage. - The projection may include user-authored messages, assistant reply text, and - successful tool-call names, but not raw Pi internals, full transcript - history, private tool arguments/results, provider credentials, or unrelated - conversation context. +3. Load a bounded core-owned run projection from transcript/session storage. + The projection may include normalized user-authored messages, assistant + reply text, and bounded tool-result text, but not raw Pi internals, raw tool + arguments, full transcript history, private tool payloads, provider + credentials, or unrelated conversation context. 4. Skip passive extraction for unsupported sources. V1 supports local CLI sessions and `pub` sources with a stable source key. Non-local `priv` sources and sources without stable identity are ignored before model @@ -90,7 +94,8 @@ The `processSession` task must: extraction. 6. Provide visible existing memories as dedupe context only, not as source evidence for new memories. -7. Ignore assistant-authored claims as memory sources. +7. Use assistant-authored text only as context for interpreting the completed + run; assistant claims are not independent source evidence. 8. Extract candidate facts with a structured model output contract. 9. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or non-durable facts. @@ -101,7 +106,7 @@ The `processSession` task must: runtime source helper, completed session reference, and extracted fact content. 12. Generate embeddings for accepted rows when the host embedder is configured. -13. Avoid storing raw extraction prompt, raw model output, or raw session text +13. Avoid storing raw extraction prompt, raw model output, or raw run text beyond the accepted memory records. Plugin tasks are best effort and at least once. If extraction or storage fails, @@ -111,9 +116,9 @@ create duplicate memories. ## Extraction Rules -Passive session extraction must follow these rules: +Passive run extraction must follow these rules: -1. Extract only from user-authored text. +1. Extract only from user-authored text and bounded tool-result text. 2. Prefer explicit `createMemory` tool writes over inferred passive learning. 3. Store facts, not conversation summaries. 4. Make content self-contained and perspective-neutral. @@ -130,16 +135,23 @@ Passive session extraction must follow these rules: scope. 11. In V1 passive extraction, prioritize conversation-scoped task, process, runbook, project, channel, and operational knowledge. -12. Personal-scoped memories must be public/shareable first-person facts from +12. Prefer reusable "how to achieve the result" knowledge when it took effort + to discover: stable source-of-truth, query location, workflow, + prerequisite, caveat, or decision path. +13. Direct answers to user inquiries may be stored only when they are durable + operational/project knowledge. Do not store point-in-time analytics, + search, issue, metric, incident, availability, or status answers whose + values naturally change. +14. Personal-scoped memories must be public/shareable first-person facts from the current author/requester, and should be stored passively only when they are clearly durable and useful beyond the active task. -13. Assign `user` subject only for the current author/requester; do not create +15. Assign `user` subject only for the current author/requester; do not create third-party user subjects in V1. -14. Preserve provenance for third-party claims when the source matters for +16. Preserve provenance for third-party claims when the source matters for correctness. -15. Store the minimum useful assertion rather than a direct quote or broad +17. Store the minimum useful assertion rather than a direct quote or broad summary. -16. Store ownership, subject, and provenance in structured fields, not content +18. Store ownership, subject, and provenance in structured fields, not content prose. Remove requester names, display names, `the requester`, `the user`, `I`, `my`, thread labels, channel labels, and source labels from accepted content. @@ -157,7 +169,7 @@ belong to the memory agent rather than a caller-provided policy hook. The default V1 passive-extraction shape is: 1. The memory agent proposes structured candidate memories from the bounded - completed-session projection. + completed-run projection. 2. The memory agent accepts only candidates that satisfy public/shareable memory guidance. 3. Deterministic validation applies only hard structural rules, such as schema @@ -165,17 +177,16 @@ The default V1 passive-extraction shape is: idempotency, and storage constraints before storage. Memory agent review should receive only the candidate memory or bounded -completed-session text, the minimum source context needed to judge it, and +completed-run transcript, the minimum source context needed to judge it, and public/shareable memory guidance. It should not receive unrestricted transcript -history, raw tool -payloads, provider credentials, or unrelated conversation context unless those -fields are part of the bounded extraction input. Prompt inputs should use the -same structured context-block style as Junior's run context, with separate -`` and source blocks. Explicit `createMemory` review uses a singular -`` block and the current user-authored message as bounded source -context. Passive extraction uses the completed session's bounded user-authored -messages plus visible existing memories for dedupe. Existing memories must not -be used as source evidence for new facts. +history, raw tool arguments, private tool payloads, provider credentials, or +unrelated conversation context unless those fields are part of the bounded +extraction input. Prompt inputs should use the same structured context-block +style as Junior's run context, with separate `` and source blocks. +Explicit `createMemory` review uses a singular `` block and the +current user-authored message as bounded source context. Passive extraction +uses the completed run's bounded transcript plus visible existing memories for +dedupe. Existing memories must not be used as source evidence for new facts. The memory agent model is host-owned but selected by the memory plugin. An explicit `createMemoryPlugin({ modelId })` option wins, then `AI_MEMORY_MODEL`, @@ -196,9 +207,11 @@ candidate memories: - `preferences`: durable personal preferences, opinions, habits, or workflows owned by the current requester; stored as requester memory. - `procedures`: reusable task, process, triage-flow, or runbook instructions; - stored as conversation memory. + source-of-truth, lookup, or decision-path knowledge; stored as conversation + memory. - `facts`: shared project, channel, operational, or runbook knowledge; stored - as conversation memory. + as conversation memory. Point-in-time query answers are excluded unless they + are stable beyond the run. Conversation-target passive memories in V1 are the primary path for learning how work gets done: task procedures, runbooks, project facts, channel norms, diff --git a/specs/memory-plugin/index.md b/specs/memory-plugin/index.md index 6dcae21dd..dabb106d7 100644 --- a/specs/memory-plugin/index.md +++ b/specs/memory-plugin/index.md @@ -16,9 +16,8 @@ contracts. This spec describes the intended V1 memory plugin shape. Generic plugin prompt hooks and plugin prompt session state are available through `../plugin-prompt-hooks.md`. Passive learning uses the typed task contract in -`../plugin-tasks.md`: a `session.completed` task loads a bounded completed -agent-run session projection and invokes the memory-owned internal extraction -agent. +`../plugin-tasks.md`: a `session.completed` task loads a bounded completed-run +projection and invokes the memory-owned internal extraction agent. V1 stores only public/shareable memory content. Scope controls who can see a record; it is not a content sensitivity model. Private, sensitive, secret, or @@ -162,8 +161,14 @@ Installations that do not want memory should disable the memory plugin rather than split recall from the plugin. Future install-level memory policy may narrow passive extraction, stored categories, providers, and retention defaults. -V1 passive extraction targets public/shareable, durable facts from supported -runtime contexts. Local CLI contexts are valid passive-learning sources for +V1 passive extraction targets public/shareable, durable facts from the +completed run transcript for supported runtime contexts, including +user-authored messages and tool results. Extraction should prefer reusable +knowledge about how to achieve a result, such as stable source-of-truth, +workflow, query location, prerequisite, caveat, or decision-path knowledge. +Point-in-time answers from analytics, search, issue, metric, incident, +availability, or status queries are not memory unless the answer is stable +beyond the run. Local CLI contexts are valid passive-learning sources for development and QA. Non-local sources must be `type: "pub"` and have a stable runtime source key. Private, sensitive, secret, or otherwise restricted facts are rejected rather than stored. diff --git a/specs/memory-plugin/security.md b/specs/memory-plugin/security.md index 67110e1e2..8594fefaa 100644 --- a/specs/memory-plugin/security.md +++ b/specs/memory-plugin/security.md @@ -22,7 +22,7 @@ model calls, embeddings, logging, and multi-user visibility. 6. Embeddings and lexical indexes are derived data and cannot grant visibility. 7. Provider credentials never enter plugin storage, prompt contributions, tool schemas, task payloads, logs, or model-visible content. -8. Passive extraction tasks use bounded completed-session projections and do +8. Passive extraction tasks use bounded completed-run projections and do not store raw transcript text. 9. Every write path uses the same policy, validation, and secret rejection layer. @@ -115,9 +115,9 @@ They must not contain: - memory content unless the task exists specifically to repair a memory id that can be reloaded from storage -Passive session-processing tasks should reload bounded completed-session -projections through the core-provided session helper rather than carrying raw -messages in task params or queue payloads. +Passive processing tasks should reload bounded completed-run projections +through the core-provided run helper rather than carrying raw messages in task +params or queue payloads. ## Logging And Reporting diff --git a/specs/plugin-tasks.md b/specs/plugin-tasks.md index 7465f4db9..05830250c 100644 --- a/specs/plugin-tasks.md +++ b/specs/plugin-tasks.md @@ -20,7 +20,7 @@ an in-process background worker surviving a serverless request. `@sentry/junior-plugin-api`. - Core-owned queue payloads, Vercel Queue dispatch, retries, and callback routing. -- Completed-session scheduling and the completed-session projection. +- Completed-session scheduling and the completed-run projection. - Local development execution for plugin tasks. - Verification requirements for task scheduling, execution, and idempotency. @@ -111,8 +111,8 @@ interface PluginTaskContext extends PluginContext { model: PluginModel; name: string; state: PluginState; - session: { - load(): Promise; + run: { + load(): Promise; }; } ``` @@ -139,7 +139,7 @@ interface PluginTaskQueueMessage { Core owns parsing, routing, queue topic selection, and callback registration. Queue messages must not include raw transcript text, raw tool payloads, -credentials, tokens, or unbounded session data. +credentials, tokens, or unbounded run data. The task id is derived from the plugin name, task name, and parsed params. When sending to Vercel Queues, core must use that id as the queue `idempotencyKey` so @@ -179,35 +179,40 @@ For local CLI development, core may process scheduled tasks inline after visible delivery, but the inline path must still use the same task message and task runner used by queued execution. -### Completed Session Projection +### Completed Run Projection -`ctx.session.load()` returns a bounded core-owned projection: +`ctx.run.load()` returns a bounded core-owned projection of the completed agent +run. The queue params still use `sessionId` because that is the historical +persisted session-record key. ```ts -interface PluginSessionContext { +interface PluginRunContext { completedAtMs: number; conversationId: string; destination: Destination; - messages: PluginSessionMessage[]; requester?: Requester; - sessionId: string; + runId: string; source: Source; - toolCalls: string[]; + transcript: PluginRunTranscriptEntry[]; } -interface PluginSessionMessage { - role: "user" | "assistant"; - text: string; -} +type PluginRunTranscriptEntry = + | { type: "message"; role: "user" | "assistant"; text: string } + | { + type: "toolResult"; + toolName: string; + isError: boolean; + text?: string; + }; ``` -The projection may include user-authored text, assistant reply text, source, -destination, requester, and successful tool-call names. It must not expose raw -Pi internals, raw tool args/results, full unbounded transcript history, -provider credentials, OAuth tokens, Slack tokens, or private binary payloads. +The projection may include normalized user-authored text, assistant reply text, +tool-result text, source, destination, and requester. It must not expose raw Pi +internals, raw tool arguments, full unbounded transcript history, provider +credentials, OAuth tokens, Slack tokens, or private binary payloads. If the session record is unavailable, incomplete, missing source/destination, -or not completed, `session.load()` throws so the task follows the normal retry +or not completed, `run.load()` throws so the task follows the normal retry and terminal failure policy. Source privacy is evaluated by the plugin using the normalized `Source` helpers @@ -256,7 +261,7 @@ Use component or integration tests for: - params parsed before queue dispatch and again before execution - `session.completed` scheduling sends one queue message per plugin task - duplicate scheduling derives the same idempotency id -- task execution loads a bounded completed-session projection from durable +- task execution loads a bounded completed-run projection from durable session storage - failed task attempts bubble to the queue retry boundary - queue callback parsing rejects malformed payloads diff --git a/specs/plugin.md b/specs/plugin.md index 835eeb970..6360e5e3d 100644 --- a/specs/plugin.md +++ b/specs/plugin.md @@ -59,7 +59,7 @@ plugins/sentry/ - [OAuth Flows Spec](./oauth-flows.md): OAuth challenge, callback, and agent continuation behavior. - [Sandbox Snapshots Spec](./sandbox-snapshots.md): runtime dependency snapshot build/reuse. - [Plugin Prompt Hooks Spec](./plugin-prompt-hooks.md): implemented prompt hook contributions. -- [Plugin Background Tasks Spec](./plugin-tasks.md): plugin-owned durable background task registration, queue dispatch, and session projection. +- [Plugin Background Tasks Spec](./plugin-tasks.md): plugin-owned durable background task registration, queue dispatch, and completed-run projection. - [Plugin Database Spec](./plugin-database.md): packaged SQL migrations and `ctx.db` access for plugin hooks. - [Plugin CLI Spec](./plugin-cli.md): future plugin-contributed host CLI commands for operator/admin workflows. - [Memory Plugin Spec](./memory-plugin/index.md): long-term memory implemented through prompt, background task, database, and tool hooks. From 1d742d9ce089c0af7fe2994e6e0e51b16e376d8e Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 21:01:37 -0700 Subject: [PATCH 26/29] fix(memory): Tighten passive extraction boundaries Limit post-session extraction to the documented five-memory cap and skip requester-scoped writes when completed run context has no requester. Keep plugin run requester optional in the public schema, project only bounded string tool-result evidence into plugin task transcripts, and validate signed plugin task callbacks with a composed runtime schema. Co-Authored-By: GPT-5 Codex --- .../api/interfaces/PluginTaskContext.md | 4 +- .../api/variables/pluginRunContextSchema.md | 2 +- packages/junior-memory/src/agent.ts | 2 +- packages/junior-memory/src/process-session.ts | 4 +- packages/junior-memory/tests/storage.test.ts | 144 +++++++++++++++++- packages/junior-plugin-api/src/tasks.ts | 2 +- .../junior/src/chat/plugins/task-message.ts | 2 +- .../junior/src/chat/plugins/task-runner.ts | 35 ++--- .../junior/src/chat/plugins/task-signing.ts | 46 +++--- .../component/plugins/plugin-tasks.test.ts | 2 +- .../tests/component/vercel-queue-dev.test.ts | 5 + 11 files changed, 181 insertions(+), 67 deletions(-) diff --git a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md index 42ed0ef7e..cefd0bd1e 100644 --- a/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md +++ b/packages/docs/src/content/docs/reference/api/interfaces/PluginTaskContext.md @@ -93,11 +93,11 @@ Defined in: [junior-plugin-api/src/tasks.ts:56](https://github.com/getsentry/jun #### load() -> **load**(): `Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `runId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `transcript`: (\{ `role`: `"user"` \| `"assistant"`; `text`: `string`; `type`: `"message"`; \} \| \{ `isError`: `boolean`; `text?`: `string`; `toolName`: `string`; `type`: `"toolResult"`; \})[]; \}\> +> **load**(): `Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `requester?`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `runId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `transcript`: (\{ `role`: `"user"` \| `"assistant"`; `text`: `string`; `type`: `"message"`; \} \| \{ `isError`: `boolean`; `text?`: `string`; `toolName`: `string`; `type`: `"toolResult"`; \})[]; \}\> ##### Returns -`Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `requester`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `runId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `transcript`: (\{ `role`: `"user"` \| `"assistant"`; `text`: `string`; `type`: `"message"`; \} \| \{ `isError`: `boolean`; `text?`: `string`; `toolName`: `string`; `type`: `"toolResult"`; \})[]; \}\> +`Promise`\<\{ `completedAtMs`: `number`; `conversationId`: `string`; `destination`: \{ `channelId`: `string`; `platform`: `"slack"`; `teamId`: `string`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; \}; `requester?`: \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `userId`: `string`; `userName?`: `string`; \} \| \{ `email?`: `string`; `fullName?`: `string`; `platform`: `"local"`; `userId`: `string`; `userName?`: `string`; \}; `runId`: `string`; `source`: \{ `channelId`: `string`; `messageTs?`: `string`; `platform`: `"slack"`; `teamId`: `string`; `threadTs?`: `string`; `type`: `"pub"` \| `"priv"`; \} \| \{ `conversationId`: `string`; `platform`: `"local"`; `type`: `"priv"`; \}; `transcript`: (\{ `role`: `"user"` \| `"assistant"`; `text`: `string`; `type`: `"message"`; \} \| \{ `isError`: `boolean`; `text?`: `string`; `toolName`: `string`; `type`: `"toolResult"`; \})[]; \}\> --- diff --git a/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md b/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md index 3fb1b9082..a819897de 100644 --- a/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md +++ b/packages/docs/src/content/docs/reference/api/variables/pluginRunContextSchema.md @@ -5,7 +5,7 @@ prev: false title: "pluginRunContextSchema" --- -> `const` **pluginRunContextSchema**: `ZodObject`\<\{ `completedAtMs`: `ZodNumber`; `conversationId`: `ZodString`; `destination`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; \}, `$strict`\>\], `"platform"`\>; `requester`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>, `ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"local"`\>; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>\], `"platform"`\>; `runId`: `ZodString`; `source`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `messageTs`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `threadTs`: `ZodOptional`\<`ZodString`\>; `type`: `ZodEnum`\<\{ `priv`: `"priv"`; `pub`: `"pub"`; \}\>; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; `type`: `ZodLiteral`\<`"priv"`\>; \}, `$strict`\>\], `"platform"`\>; `transcript`: `ZodArray`\<`ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; `type`: `ZodLiteral`\<`"message"`\>; \}, `$strict`\>, `ZodObject`\<\{ `isError`: `ZodBoolean`; `text`: `ZodOptional`\<`ZodString`\>; `toolName`: `ZodString`; `type`: `ZodLiteral`\<`"toolResult"`\>; \}, `$strict`\>\], `"type"`\>\>; \}, `$strict`\> +> `const` **pluginRunContextSchema**: `ZodObject`\<\{ `completedAtMs`: `ZodNumber`; `conversationId`: `ZodString`; `destination`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; \}, `$strict`\>\], `"platform"`\>; `requester`: `ZodOptional`\<`ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>, `ZodObject`\<\{ `email`: `ZodOptional`\<`ZodString`\>; `fullName`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"local"`\>; `userId`: `ZodString`; `userName`: `ZodOptional`\<`ZodString`\>; \}, `$strict`\>\], `"platform"`\>\>; `runId`: `ZodString`; `source`: `ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `channelId`: `ZodString`; `messageTs`: `ZodOptional`\<`ZodString`\>; `platform`: `ZodLiteral`\<`"slack"`\>; `teamId`: `ZodString`; `threadTs`: `ZodOptional`\<`ZodString`\>; `type`: `ZodEnum`\<\{ `priv`: `"priv"`; `pub`: `"pub"`; \}\>; \}, `$strict`\>, `ZodObject`\<\{ `conversationId`: `ZodString`; `platform`: `ZodLiteral`\<`"local"`\>; `type`: `ZodLiteral`\<`"priv"`\>; \}, `$strict`\>\], `"platform"`\>; `transcript`: `ZodArray`\<`ZodDiscriminatedUnion`\<\[`ZodObject`\<\{ `role`: `ZodEnum`\<\{ `assistant`: `"assistant"`; `user`: `"user"`; \}\>; `text`: `ZodString`; `type`: `ZodLiteral`\<`"message"`\>; \}, `$strict`\>, `ZodObject`\<\{ `isError`: `ZodBoolean`; `text`: `ZodOptional`\<`ZodString`\>; `toolName`: `ZodString`; `type`: `ZodLiteral`\<`"toolResult"`\>; \}, `$strict`\>\], `"type"`\>\>; \}, `$strict`\> Defined in: [junior-plugin-api/src/tasks.ts:32](https://github.com/getsentry/junior/blob/main/packages/junior-plugin-api/src/tasks.ts#L32) diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 4c128aaf1..2a3143cfd 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -430,7 +430,7 @@ function extractedMemoriesFromResponse( ...response.procedures.map((memory) => toMemory("conversation", memory)), ...response.facts.map((memory) => toMemory("conversation", memory)), ...response.preferences.map((memory) => toMemory("requester", memory)), - ]; + ].slice(0, 5); } /** Parse the structured decision returned by the memory agent. */ diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior-memory/src/process-session.ts index 5cee96403..afb48e4bb 100644 --- a/packages/junior-memory/src/process-session.ts +++ b/packages/junior-memory/src/process-session.ts @@ -79,7 +79,6 @@ export async function processMemorySession( run.transcript.some( (entry) => entry.type === "toolResult" && - !entry.isError && MEMORY_MUTATION_TOOL_NAMES.has(entry.toolName), ) ) { @@ -137,6 +136,9 @@ export async function processMemorySession( await store.createConversationMemory(input); continue; } + if (!run.requester) { + continue; + } await store.createMemory(input); } } diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index c898b7302..e003aa9b5 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -244,7 +244,6 @@ function extractionModel( function slackContext( overrides: { channelId?: string; - sourceType?: "priv" | "pub"; teamId?: string; threadTs?: string; userId?: string; @@ -493,6 +492,43 @@ describe("memory plugin storage", () => { ]); }); + it("caps passive extraction at five memories across categories", async () => { + const model: PluginModel = { + async completeObject() { + return { + object: { + facts: [ + { canonicalFact: "Fact one.", expiresAtMs: null }, + { canonicalFact: "Fact two.", expiresAtMs: null }, + ], + preferences: [ + { canonicalFact: "Prefers one.", expiresAtMs: null }, + { canonicalFact: "Prefers two.", expiresAtMs: null }, + ], + procedures: [ + { canonicalFact: "Procedure one.", expiresAtMs: null }, + { canonicalFact: "Procedure two.", expiresAtMs: null }, + ], + }, + }; + }, + }; + const agent = createMemoryAgent(model); + + await expect( + agent.extractSessionMemories({ + transcript: [ + { + type: "message", + role: "user", + text: "Store several durable facts.", + }, + ], + runtimeContext: localContext(), + }), + ).resolves.toHaveLength(5); + }); + it("uses AI_MEMORY_MODEL as the memory plugin model default", async () => { const previousModel = process.env.AI_MEMORY_MODEL; process.env.AI_MEMORY_MODEL = "anthropic/claude-sonnet-4.6"; @@ -790,6 +826,51 @@ describe("memory plugin storage", () => { } }); + it("skips passive extraction for failed memory mutation tool turns", async () => { + const fixture = await createMemoryFixture(); + const { model, calls } = extractionModel([ + { + kind: "preference", + content: "failed memory mutation should not be reinterpreted", + }, + ]); + + try { + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + run: { + async load() { + return completedRun({ + transcript: [ + { + type: "message", + role: "user", + text: "Remember that I prefer failed mutation shielding.", + }, + { + type: "toolResult", + toolName: "createMemory", + isError: true, + text: "Memory rejected.", + }, + ], + }); + }, + }, + }), + ); + + expect(calls).toEqual([]); + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([]); + } finally { + await fixture.close(); + } + }); + it("does not skip passive extraction for memory recall tool turns", async () => { const fixture = await createMemoryFixture(); try { @@ -849,10 +930,7 @@ describe("memory plugin storage", () => { content: "private Slack context skips", }, ]); - const privateContext = slackContext({ - channelId: "D123", - sourceType: "priv", - }); + const privateContext = slackContext({ channelId: "D123" }); try { await processMemorySession( @@ -987,6 +1065,62 @@ describe("memory plugin storage", () => { } }); + it("stores conversation memories without requester context", async () => { + const fixture = await createMemoryFixture(); + const { model } = extractionModel([ + { + kind: "procedure", + content: "Release triage checks deployment markers first.", + }, + { + kind: "preference", + content: "Prefers requester-only memory.", + }, + ]); + const runtime = localContext(); + + try { + await processMemorySession( + processSessionContext({ + db: memoryDb(fixture), + model, + run: { + async load() { + return completedRun({ + conversationId: runtime.conversationId, + destination: { + platform: "local", + conversationId: runtime.conversationId, + }, + requester: undefined, + transcript: [ + { + type: "message", + role: "user", + text: "For release triage, check deployment markers first.", + }, + ], + source: runtime.source, + }); + }, + }, + }), + ); + + await expect( + memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), + ).resolves.toEqual([ + expect.objectContaining({ + content: "Release triage checks deployment markers first.", + scope: "conversation", + subjectType: "conversation", + }), + ]); + } finally { + await fixture.close(); + } + }); + it("persists, recalls, and archives visible memories", async () => { const fixture = await createMemoryFixture(); diff --git a/packages/junior-plugin-api/src/tasks.ts b/packages/junior-plugin-api/src/tasks.ts index 651acd870..793ba658f 100644 --- a/packages/junior-plugin-api/src/tasks.ts +++ b/packages/junior-plugin-api/src/tasks.ts @@ -34,7 +34,7 @@ export const pluginRunContextSchema = z completedAtMs: z.number().finite(), conversationId: z.string().min(1), destination: destinationSchema, - requester: requesterSchema, + requester: requesterSchema.optional(), runId: z.string().min(1), source: sourceSchema, transcript: z.array(pluginRunTranscriptEntrySchema), diff --git a/packages/junior/src/chat/plugins/task-message.ts b/packages/junior/src/chat/plugins/task-message.ts index 58ae18670..3df70ea14 100644 --- a/packages/junior/src/chat/plugins/task-message.ts +++ b/packages/junior/src/chat/plugins/task-message.ts @@ -10,7 +10,7 @@ export const pluginTaskParamsSchema = z export type PluginTaskParams = z.output; -const pluginTaskQueueMessageSchema = z +export const pluginTaskQueueMessageSchema = z .object({ name: z.string().min(1), params: pluginTaskParamsSchema, diff --git a/packages/junior/src/chat/plugins/task-runner.ts b/packages/junior/src/chat/plugins/task-runner.ts index 5c3440b49..a5da43231 100644 --- a/packages/junior/src/chat/plugins/task-runner.ts +++ b/packages/junior/src/chat/plugins/task-runner.ts @@ -57,20 +57,6 @@ function textPart(value: unknown): string | undefined { return undefined; } -function serializeResultValue(value: unknown): string { - if (typeof value === "string") { - return value; - } - if (value === undefined || value === null) { - return ""; - } - try { - return JSON.stringify(value, null, 2); - } catch { - return ""; - } -} - function messageText(message: PiMessage): string { const content = (message as { content?: unknown }).content; if (typeof content === "string") { @@ -86,12 +72,14 @@ function toolResultText(message: PiMessage): string { const record = message as unknown as Record; const parts = [ messageText(message), - serializeResultValue(record.stdout), - serializeResultValue(record.stderr), - serializeResultValue(record.output), - serializeResultValue(record.result), - serializeResultValue(record.toolResult), - ].filter(Boolean); + record.output, + record.result, + record.stdout, + record.stderr, + record.toolResult, + ].filter( + (value): value is string => typeof value === "string" && value.length > 0, + ); return sanitizeText(parts.join("\n")); } @@ -177,11 +165,6 @@ async function loadPluginRun( "Completed plugin task session record is missing source or destination", ); } - if (!record.requester) { - throw new Error( - "Completed plugin task session record is missing requester", - ); - } const sessionMessages = stripRuntimeTurnContext( record.piMessages.slice(record.turnStartMessageIndex ?? 0), ); @@ -189,7 +172,7 @@ async function loadPluginRun( completedAtMs: record.updatedAtMs, conversationId: record.conversationId, destination: record.destination, - requester: record.requester, + ...(record.requester ? { requester: record.requester } : {}), runId: record.sessionId, source: record.source, transcript: sessionMessages diff --git a/packages/junior/src/chat/plugins/task-signing.ts b/packages/junior/src/chat/plugins/task-signing.ts index 7e94d7b02..ae1f92da2 100644 --- a/packages/junior/src/chat/plugins/task-signing.ts +++ b/packages/junior/src/chat/plugins/task-signing.ts @@ -1,6 +1,7 @@ import { createHmac, timingSafeEqual } from "node:crypto"; +import { z } from "zod"; import { - parsePluginTaskQueueMessage, + pluginTaskQueueMessageSchema, type PluginTaskQueueMessage, } from "./task-message"; @@ -18,11 +19,20 @@ type VerificationResult = | { reason: PluginTaskQueueRejectReason; status: "rejected" } | { reason: "invalid_clock" | "missing_secret"; status: "unavailable" }; -type SignedPluginTaskQueueMessage = PluginTaskQueueMessage & { - signature: string; - signatureVersion: typeof SIGNATURE_VERSION; - signedAtMs: number; -}; +const signedPluginTaskQueueMessageSchema = pluginTaskQueueMessageSchema + .extend({ + signature: z + .string() + .min(1) + .refine((value) => value.trim().length > 0), + signatureVersion: z.literal(SIGNATURE_VERSION), + signedAtMs: z.number().finite(), + }) + .strict(); + +type SignedPluginTaskQueueMessage = z.output< + typeof signedPluginTaskQueueMessageSchema +>; function queueSecret(): string | undefined { return process.env.JUNIOR_SECRET?.trim() || undefined; @@ -55,28 +65,8 @@ function hmac( function parseSignedMessage( value: unknown, ): SignedPluginTaskQueueMessage | undefined { - if (!value || typeof value !== "object") { - return undefined; - } - const record = value as Record; - const { signature, signatureVersion, signedAtMs, ...rawMessage } = record; - const message = parsePluginTaskQueueMessage(rawMessage); - if ( - !message || - signatureVersion !== SIGNATURE_VERSION || - typeof signedAtMs !== "number" || - !Number.isFinite(signedAtMs) || - typeof signature !== "string" || - !signature.trim() - ) { - return undefined; - } - return { - ...message, - signature, - signatureVersion: SIGNATURE_VERSION, - signedAtMs, - }; + const parsed = signedPluginTaskQueueMessageSchema.safeParse(value); + return parsed.success ? parsed.data : undefined; } /** Sign a plugin task payload before it crosses the public queue callback. */ diff --git a/packages/junior/tests/component/plugins/plugin-tasks.test.ts b/packages/junior/tests/component/plugins/plugin-tasks.test.ts index 8d40861f5..447259d2c 100644 --- a/packages/junior/tests/component/plugins/plugin-tasks.test.ts +++ b/packages/junior/tests/component/plugins/plugin-tasks.test.ts @@ -145,7 +145,7 @@ describe("plugin background tasks", () => { role: "toolResult", toolName: "searchDocs", isError: false, - content: "Incident runbooks live in Notion.", + output: "Incident runbooks live in Notion.", }, { role: "assistant", diff --git a/packages/junior/tests/component/vercel-queue-dev.test.ts b/packages/junior/tests/component/vercel-queue-dev.test.ts index 3b9fe6f8e..9570db1b8 100644 --- a/packages/junior/tests/component/vercel-queue-dev.test.ts +++ b/packages/junior/tests/component/vercel-queue-dev.test.ts @@ -100,6 +100,11 @@ describe("plugin task Vercel queue integration", () => { await expect(handler(signedMessage, metadata)).resolves.toBeUndefined(); expect(processPluginTask).toHaveBeenCalledWith(message); + await expect( + handler({ ...signedMessage, unexpected: true }, metadata), + ).resolves.toBeUndefined(); + expect(processPluginTask).toHaveBeenCalledTimes(1); + processPluginTask.mockRejectedValueOnce(new Error("task failed")); await expect(handler(signedMessage, metadata)).rejects.toThrow( "task failed", From d039a891b3d361f8c468275f28c020420cfcbe0c Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 21:24:59 -0700 Subject: [PATCH 27/29] fix(memory): Tighten passive memory test coverage Make passive extraction tests assert durable outcomes instead of prompt prose, and ensure the local runner task-failure test reaches the background task path. Clarify memory extraction ownership and source-evidence rules so third-party personal facts are rejected and follow-up questions do not become source evidence for duplicate memories. Co-Authored-By: GPT-5 Codex --- packages/junior-memory/src/agent.ts | 9 ++-- packages/junior-memory/src/tools.ts | 2 +- packages/junior-memory/tests/storage.test.ts | 45 ++++++++++--------- .../integration/local-agent-runner.test.ts | 14 ++++-- specs/memory-plugin/extraction.md | 13 +++--- 5 files changed, 51 insertions(+), 32 deletions(-) diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index 2a3143cfd..b128c6280 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -264,7 +264,7 @@ function existingMemoriesContext(request: ExtractSessionRequest): string { function memoryKindsContext(): string { return [ "", - "- preference: a durable personal preference, opinion, habit, or workflow owned by the current requester. Stored as requester memory.", + "- preference: a durable first-person personal preference, opinion, habit, or workflow owned by the current requester. Stored as requester memory.", "- procedure: reusable instructions for how a task, lookup, investigation, process, triage flow, or runbook should be done. Store the method, source-of-truth, prerequisite, or decision path when it took effort to discover. Stored as conversation memory.", "- fact: stable shared project, channel, operational, or runbook knowledge that is not a personal requester preference. Direct answers to user inquiries qualify only when they are durable beyond this run. Stored as conversation memory.", "", @@ -287,7 +287,8 @@ function reviewPrompt(request: CreateMemoryRequest): string { "", "- Return store only when the candidate is public/shareable, durable, and self-contained.", "- First classify the memory kind: preference, procedure, or fact.", - "- Use kind=preference only for facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- Use kind=preference only for first-person facts authored by the current requester about their own preference, opinion, habit, identity, or workflow.", + "- Reject named third-person personal facts such as another person's preference, opinion, habit, identity, relationship, or workflow. Do not assume a named person is the current requester.", "- Use kind=procedure for reusable task/process/runbook instructions.", "- Use kind=fact for shared project, channel, operational, or runbook knowledge.", "- When current-user-message contains an explicit memory request with a concrete fact or procedure, extract from current-user-message even if the candidate is vague, incomplete, or phrased as an instruction.", @@ -353,9 +354,11 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { "- Store direct answers to user inquiries only when they are stable operational/project knowledge, not values that naturally change over time.", "- Do not store point-in-time analytics, search, issue, metric, incident, availability, or status answers just because a tool produced them.", "- Do not store the fact that the user asked for advice, search, recall, planning, listing, inspection, or removal. Store only stable knowledge discovered in response, such as a reusable method or source-of-truth.", + "- A user question asking how, what, where, or whether to do something is not source evidence for the answer. Store the answer only when supported by a user-authored factual statement or a tool result.", "- Fill procedures with reusable task/process/runbook instructions.", "- Fill facts with shared team, project, channel, runbook, or operational knowledge.", - "- Fill preferences only with clear durable facts about the current requester as a person/user, such as their own preference, opinion, habit, identity, or workflow.", + "- Fill preferences only with clear durable first-person facts authored by the current requester about their own preference, opinion, habit, identity, or workflow.", + "- Reject named third-person personal facts such as another person's preference, opinion, habit, identity, relationship, or workflow. Do not assume a named person is the current requester.", "- User-authored task instructions are procedures, not preferences, unless they explicitly describe the requester's personal preference or habit.", "- Procedural statements such as 'for X, do Y', 'when X, do Y', and 'to accomplish X, do Y' belong in procedures.", ...CANONICAL_CONTENT_RULES, diff --git a/packages/junior-memory/src/tools.ts b/packages/junior-memory/src/tools.ts index 89496c77d..9ac02ea86 100644 --- a/packages/junior-memory/src/tools.ts +++ b/packages/junior-memory/src/tools.ts @@ -327,7 +327,7 @@ function compactMemory(memory: MemoryRecord) { export function createMemoryCreateTool(context: MemoryToolContext) { return { description: - "Explicit memory-write tool. Use only when the latest user message directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact. Do not use for ordinary statements like 'I prefer X', 'I use Y', or 'X goes before Y' unless the user also asks you to remember/store/save it; passive memory learning handles those after the visible reply. Pass one self-contained natural-language candidate preserving the user's explicit memory intent. Do not ask the user to rephrase ordinary first-person facts, and do not rewrite them into display-name or third-person wording. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or facts about another person's private life. Runtime context derives actor, scope, source, and subject ids; the memory agent decides the canonical stored content, subject, and target.", + "Explicit memory-write tool. Use only when the latest user message directly asks Junior to remember, store, save, or forget-and-replace a public/shareable fact. Do not use for ordinary statements like 'I prefer X', 'I use Y', or 'X goes before Y' unless the user also asks you to remember/store/save it; passive memory learning handles those after the visible reply. Pass one self-contained natural-language candidate preserving the user's explicit memory intent. Do not ask the user to rephrase ordinary first-person facts, and do not rewrite them into display-name or third-person wording. Do not include secrets, private personal details, medical/legal/financial/sensitive facts, or another person's personal preference, opinion, habit, identity, relationship, workflow, or private life. Runtime context derives actor, scope, source, and subject ids; the memory agent decides the canonical stored content, subject, and target.", executionMode: "sequential", inputSchema: createMemoryInputSchema, execute: async (input, options) => { diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index e003aa9b5..59012fcb1 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -653,19 +653,36 @@ describe("memory plugin storage", () => { const fixture = await createMemoryFixture(); try { - const { model, calls } = extractionModel([ - { - content: - "Signup funnel analysis should use the modeled warehouse cohort table.", - kind: "procedure", + const model: PluginModel = { + async completeObject(input) { + const prompt = input.prompt; + const includesToolEvidence = + typeof prompt === "string" && + prompt.includes("queryAnalyticsCatalog") && + prompt.includes( + "The modeled warehouse cohort table is the source of truth for signup funnel analysis.", + ); + return { + object: { + facts: [], + preferences: [], + procedures: includesToolEvidence + ? [ + { + canonicalFact: + "Signup funnel analysis should use the modeled warehouse cohort table.", + expiresAtMs: null, + }, + ] + : [], + }, + }; }, - ]); - const embedder = createTestEmbedder(); + }; await processMemorySession( processSessionContext({ db: memoryDb(fixture), - embedder, model, run: { async load() { @@ -694,18 +711,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls[0]?.prompt).toContain(" { }, ] as PiMessage[]; const delivered: LocalAgentReply[] = []; + let taskRuns = 0; setPlugins([ defineJuniorPlugin({ manifest: { @@ -534,6 +535,7 @@ describe("local agent runner", () => { tasks: { processSession: { run() { + taskRuns += 1; throw new Error("background task failed"); }, }, @@ -552,10 +554,15 @@ describe("local agent runner", () => { deliverReply: async (reply) => { delivered.push(reply); }, - generateAssistantReply: async () => - successReply("visible reply", { + generateAssistantReply: async (_text, context) => { + await persistCompletedSessionForFakeReply( + context, + generatedMessages, + ); + return successReply("visible reply", { piMessages: generatedMessages, - }), + }); + }, }, ), ).resolves.toEqual({ @@ -567,6 +574,7 @@ describe("local agent runner", () => { } expect(delivered).toEqual([{ text: "visible reply" }]); + expect(taskRuns).toBe(1); }); it("uses conversation Pi history when the session projection is stale", async () => { diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 45fa76876..8ddb844a1 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -142,16 +142,19 @@ Passive run extraction must follow these rules: operational/project knowledge. Do not store point-in-time analytics, search, issue, metric, incident, availability, or status answers whose values naturally change. -14. Personal-scoped memories must be public/shareable first-person facts from +14. A user question is not source evidence for the answer; passive extraction + may store the answer only when user-authored factual text or a tool result + supports it. +15. Personal-scoped memories must be public/shareable first-person facts from the current author/requester, and should be stored passively only when they are clearly durable and useful beyond the active task. -15. Assign `user` subject only for the current author/requester; do not create +16. Assign `user` subject only for the current author/requester; do not create third-party user subjects in V1. -16. Preserve provenance for third-party claims when the source matters for +17. Preserve provenance for third-party claims when the source matters for correctness. -17. Store the minimum useful assertion rather than a direct quote or broad +18. Store the minimum useful assertion rather than a direct quote or broad summary. -18. Store ownership, subject, and provenance in structured fields, not content +19. Store ownership, subject, and provenance in structured fields, not content prose. Remove requester names, display names, `the requester`, `the user`, `I`, `my`, thread labels, channel labels, and source labels from accepted content. From ea3317e1d29bcc01e9ccc0b1c5fe63cdb48b1200 Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 21:27:36 -0700 Subject: [PATCH 28/29] fix(memory): Avoid caching empty extraction results Only persist passive extraction task cache entries when the extractor produced memories that may need retry-safe writes. Co-Authored-By: GPT-5 Codex --- packages/junior-memory/src/process-session.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior-memory/src/process-session.ts index afb48e4bb..8ee976995 100644 --- a/packages/junior-memory/src/process-session.ts +++ b/packages/junior-memory/src/process-session.ts @@ -58,7 +58,9 @@ async function getTaskMemories( return extractedMemoryCacheSchema.parse(cached); } const memories = await extract(); - await context.state.set(cacheKey, memories, MEMORY_TASK_STATE_TTL_MS); + if (memories.length > 0) { + await context.state.set(cacheKey, memories, MEMORY_TASK_STATE_TTL_MS); + } return memories; } From 0e183ae1fe3d924dfc61bcac8e40b3177d053e1b Mon Sep 17 00:00:00 2001 From: David Cramer Date: Fri, 26 Jun 2026 22:56:24 -0700 Subject: [PATCH 29/29] fix(memory): Tighten passive extraction Use a single structured passive extraction output with kind-derived targets and skip passive learning on memory tool runs so recalled memory is not treated as fresh evidence. Centralize eval cleanup for plugin tasks and propagate host cancellation through task-owned model and embedding calls to avoid leaked work after timed-out evals. Co-Authored-By: GPT-5 --- .../evals/memory/workflows.eval.ts | 8 +- packages/junior-evals/src/behavior-harness.ts | 64 +++++- packages/junior-evals/src/setup.ts | 8 + packages/junior-evals/vitest.evals.config.ts | 1 + packages/junior-memory/src/agent.ts | 36 +-- packages/junior-memory/src/plugin.ts | 2 +- packages/junior-memory/src/process-session.ts | 13 +- packages/junior-memory/tests/storage.test.ts | 215 +++++++++--------- packages/junior/src/chat/plugins/model.ts | 8 +- .../junior/src/chat/plugins/task-runner.ts | 18 +- .../tests/unit/plugins/plugin-model.test.ts | 24 +- specs/memory-plugin/extraction.md | 55 ++--- specs/memory-plugin/verification.md | 4 +- 13 files changed, 275 insertions(+), 181 deletions(-) create mode 100644 packages/junior-evals/src/setup.ts diff --git a/packages/junior-evals/evals/memory/workflows.eval.ts b/packages/junior-evals/evals/memory/workflows.eval.ts index 05340c30a..ef7bb0ae0 100644 --- a/packages/junior-evals/evals/memory/workflows.eval.ts +++ b/packages/junior-evals/evals/memory/workflows.eval.ts @@ -1,6 +1,6 @@ -import { afterEach, expect } from "vitest"; +import { expect } from "vitest"; import { assistantMessages, describeEval } from "vitest-evals"; -import { closeDb, getDb } from "@/chat/db"; +import { getDb } from "@/chat/db"; import { completeText, resolveGatewayModel } from "@/chat/pi/client"; import { createMemoryStore, type MemoryDb } from "@sentry/junior-memory"; import { createSlackSource } from "@sentry/junior-plugin-api"; @@ -243,10 +243,6 @@ async function expectAssistantMemoryAnswer(args: { ); } -afterEach(async () => { - await closeDb(); -}); - describeEval("Memory Workflows", slackEvals, (it) => { const explicitRememberThread = { id: "thread-memory-explicit-remember", diff --git a/packages/junior-evals/src/behavior-harness.ts b/packages/junior-evals/src/behavior-harness.ts index 91b86675e..6caf7026a 100644 --- a/packages/junior-evals/src/behavior-harness.ts +++ b/packages/junior-evals/src/behavior-harness.ts @@ -42,6 +42,7 @@ import { processPluginTask, scheduleSessionCompletedPluginTasks, } from "@/chat/plugins/task-runner"; +import type { PluginTaskQueueMessage } from "@/chat/plugins/task-message"; import { generateAssistantReply } from "@/chat/respond"; import { resumeAwaitingSlackContinuation } from "@/chat/runtime/agent-continue-runner"; import { scheduleAgentContinue } from "@/chat/services/agent-continue"; @@ -95,6 +96,65 @@ import { processConversationQueueMessage } from "@/chat/task-execution/vercel-ca import { ALL as sandboxEgressProxyALL } from "@/handlers/sandbox-egress-proxy"; import { createMockImageGenerateDeps } from "./fixtures/image-generate"; +const EVAL_PLUGIN_TASK_DRAIN_TIMEOUT_MS = 5_000; + +interface PendingEvalPluginTask { + abort(): void; + promise: Promise; +} + +const pendingEvalPluginTasks = new Set(); + +async function processEvalPluginTask( + message: PluginTaskQueueMessage, +): Promise { + const controller = new AbortController(); + let task!: PendingEvalPluginTask; + const promise = processPluginTask(message, { + signal: controller.signal, + }).finally(() => { + pendingEvalPluginTasks.delete(task); + }); + task = { + abort() { + controller.abort(new Error("Eval plugin task cleanup aborted task")); + }, + promise, + }; + pendingEvalPluginTasks.add(task); + await promise; +} + +/** Drain plugin tasks started by the eval harness before shared state cleanup. */ +export async function drainPendingEvalPluginTasks(): Promise { + if (pendingEvalPluginTasks.size === 0) { + return; + } + const tasks = [...pendingEvalPluginTasks]; + for (const task of tasks) { + task.abort(); + } + let timeout: ReturnType | undefined; + try { + await Promise.race([ + Promise.allSettled(tasks.map((task) => task.promise)), + new Promise((_, reject) => { + timeout = setTimeout(() => { + reject( + new Error( + `Timed out waiting for ${tasks.length} eval plugin task(s) to settle`, + ), + ); + }, EVAL_PLUGIN_TASK_DRAIN_TIMEOUT_MS); + }), + ]); + } finally { + if (timeout) { + clearTimeout(timeout); + } + } +} + // --------------------------------------------------------------------------- // Public types // --------------------------------------------------------------------------- @@ -1543,7 +1603,7 @@ function buildRuntimeServices( scheduleSessionCompletedPluginTasks: async (params) => { await scheduleSessionCompletedPluginTasks(params, { send: async (message) => { - await processPluginTask(message); + await processEvalPluginTask(message); }, }); }, @@ -1664,7 +1724,7 @@ async function processEvents(args: { scheduleSessionCompletedPluginTasks: async (params) => { await scheduleSessionCompletedPluginTasks(params, { send: async (message) => { - await processPluginTask(message); + await processEvalPluginTask(message); }, }); }, diff --git a/packages/junior-evals/src/setup.ts b/packages/junior-evals/src/setup.ts new file mode 100644 index 000000000..160028510 --- /dev/null +++ b/packages/junior-evals/src/setup.ts @@ -0,0 +1,8 @@ +import { afterEach } from "vitest"; +import { closeDb } from "@/chat/db"; +import { drainPendingEvalPluginTasks } from "./behavior-harness"; + +afterEach(async () => { + await drainPendingEvalPluginTasks(); + await closeDb(); +}); diff --git a/packages/junior-evals/vitest.evals.config.ts b/packages/junior-evals/vitest.evals.config.ts index d079c8dc2..9f976eb47 100644 --- a/packages/junior-evals/vitest.evals.config.ts +++ b/packages/junior-evals/vitest.evals.config.ts @@ -50,6 +50,7 @@ export default defineConfig({ setupFiles: [ path.resolve(juniorPackageRoot, "tests/msw/setup.ts"), path.resolve(juniorPackageRoot, "tests/fixtures/postgres/setup.ts"), + path.resolve(__dirname, "src/setup.ts"), ], reporters: [new DefaultEvalReporter()], testTimeout: EVAL_TEST_TIMEOUT_MS, diff --git a/packages/junior-memory/src/agent.ts b/packages/junior-memory/src/agent.ts index b128c6280..534076899 100644 --- a/packages/junior-memory/src/agent.ts +++ b/packages/junior-memory/src/agent.ts @@ -112,6 +112,9 @@ const memoryReviewResponseSchema = z.discriminatedUnion("decision", [ ]); const extractedMemorySchema = z .object({ + kind: memoryKindSchema.describe( + "Use preference only for requester-owned personal preferences, opinions, habits, or workflows. Use procedure for reusable task or process instructions. Use fact for shared project, channel, operational, or runbook knowledge.", + ), canonicalFact: z .string() .min(1) @@ -123,23 +126,11 @@ const extractedMemorySchema = z .strict(); const extractMemoriesResponseSchema = z .object({ - procedures: z + memories: z .array(extractedMemorySchema) .max(5) .describe( - "Reusable public/shareable task, process, triage-flow, source-of-truth, lookup, or runbook instructions learned from this completed run. These are stored as conversation memory.", - ), - facts: z - .array(extractedMemorySchema) - .max(5) - .describe( - "Public/shareable stable project, channel, operational, or runbook facts from this completed run. These are stored as conversation memory. Exclude point-in-time query answers whose values can change.", - ), - preferences: z - .array(extractedMemorySchema) - .max(5) - .describe( - "Durable public/shareable personal preferences, opinions, habits, or workflows explicitly owned by the current requester. These are stored as requester memory.", + "Accepted public/shareable durable memories from the completed run. Return one object per distinct source assertion and classify it with kind.", ), }) .strict(); @@ -187,6 +178,8 @@ const MEMORY_EXTRACTION_SYSTEM = [ ].join("\n"); const CANONICAL_CONTENT_RULES = [ "- Stored memory text must be a rewritten fact, not copied user wording or a sentence about who said it.", + "- Store the minimum useful assertion supported by source evidence; do not add adjacent steps, caveats, or generalized advice.", + "- Do not return both concise and expanded variants of the same source assertion; keep the shortest self-contained canonical memory.", "- Put ownership in structured fields, not prose.", "- For requester memories, omit the subject and write a stable fact such as 'Prefers X', 'Uses Y', or 'Thinks Z'.", "- Drop perspective/provenance markers while preserving useful context.", @@ -355,9 +348,9 @@ function sessionExtractionPrompt(request: ExtractSessionRequest): string { "- Do not store point-in-time analytics, search, issue, metric, incident, availability, or status answers just because a tool produced them.", "- Do not store the fact that the user asked for advice, search, recall, planning, listing, inspection, or removal. Store only stable knowledge discovered in response, such as a reusable method or source-of-truth.", "- A user question asking how, what, where, or whether to do something is not source evidence for the answer. Store the answer only when supported by a user-authored factual statement or a tool result.", - "- Fill procedures with reusable task/process/runbook instructions.", - "- Fill facts with shared team, project, channel, runbook, or operational knowledge.", - "- Fill preferences only with clear durable first-person facts authored by the current requester about their own preference, opinion, habit, identity, or workflow.", + "- Set kind=procedure for reusable task/process/runbook instructions.", + "- Set kind=fact for shared team, project, channel, runbook, or operational knowledge.", + "- Set kind=preference only for clear durable first-person facts authored by the current requester about their own preference, opinion, habit, identity, or workflow.", "- Reject named third-person personal facts such as another person's preference, opinion, habit, identity, relationship, or workflow. Do not assume a named person is the current requester.", "- User-authored task instructions are procedures, not preferences, unless they explicitly describe the requester's personal preference or habit.", "- Procedural statements such as 'for X, do Y', 'when X, do Y', and 'to accomplish X, do Y' belong in procedures.", @@ -422,18 +415,13 @@ function extractedMemoriesFromResponse( response: ExtractMemoriesResponse, ): ExtractedMemory[] { const toMemory = ( - target: MemoryTarget, memory: z.output, ): ExtractedMemory => ({ content: memory.canonicalFact, expiresAtMs: memory.expiresAtMs, - target, + target: targetForKind(memory.kind), }); - return [ - ...response.procedures.map((memory) => toMemory("conversation", memory)), - ...response.facts.map((memory) => toMemory("conversation", memory)), - ...response.preferences.map((memory) => toMemory("requester", memory)), - ].slice(0, 5); + return response.memories.map(toMemory); } /** Parse the structured decision returned by the memory agent. */ diff --git a/packages/junior-memory/src/plugin.ts b/packages/junior-memory/src/plugin.ts index e1e9dfa14..4bf4bd5e6 100644 --- a/packages/junior-memory/src/plugin.ts +++ b/packages/junior-memory/src/plugin.ts @@ -1,5 +1,5 @@ import { defineJuniorPlugin } from "@sentry/junior-plugin-api"; -import { createMemoryAgent, type MemoryAgent } from "./agent"; +import { createMemoryAgent } from "./agent"; import { createMemoryCliCommand } from "./cli"; import { createMemoryCreateTool, diff --git a/packages/junior-memory/src/process-session.ts b/packages/junior-memory/src/process-session.ts index 8ee976995..31dfb19c2 100644 --- a/packages/junior-memory/src/process-session.ts +++ b/packages/junior-memory/src/process-session.ts @@ -13,7 +13,12 @@ import { import { createMemoryAgent, type ExtractedMemory } from "./agent"; import { memoryRuntimeContextSchema } from "./types"; -const MEMORY_MUTATION_TOOL_NAMES = new Set(["createMemory", "removeMemory"]); +const MEMORY_TOOL_NAMES = new Set([ + "createMemory", + "listMemories", + "removeMemory", + "searchMemories", +]); const MEMORY_TASK_STATE_TTL_MS = 7 * 24 * 60 * 60 * 1000; const extractedMemoryCacheSchema = z.array( z @@ -76,12 +81,12 @@ export async function processMemorySession( context: PluginTaskContext, ): Promise { const run = await context.run.load(); - // Explicit memory mutation tools already own the user's memory-management intent. + // Memory tool turns already own memory management or recall; do not reinterpret + // recalled memory output as fresh passive-learning evidence. if ( run.transcript.some( (entry) => - entry.type === "toolResult" && - MEMORY_MUTATION_TOOL_NAMES.has(entry.toolName), + entry.type === "toolResult" && MEMORY_TOOL_NAMES.has(entry.toolName), ) ) { return; diff --git a/packages/junior-memory/tests/storage.test.ts b/packages/junior-memory/tests/storage.test.ts index 59012fcb1..b04e5442e 100644 --- a/packages/junior-memory/tests/storage.test.ts +++ b/packages/junior-memory/tests/storage.test.ts @@ -18,11 +18,7 @@ import { import { Command, CommanderError } from "commander"; import { describe, expect, it } from "vitest"; import * as memorySqlSchema from "../src/db/schema"; -import { - createMemoryAgent, - type CreateMemoryRequest, - type MemoryAgent, -} from "../src/agent"; +import { createMemoryAgent, type CreateMemoryRequest } from "../src/agent"; import { createMemoryCliCommand } from "../src/cli"; import { createMemoryPlugin } from "../src/plugin"; import { processMemorySession } from "../src/process-session"; @@ -218,22 +214,14 @@ function extractionModel( const model: PluginModel = { async completeObject(input) { calls.push(input); - const procedures = memories.filter( - (memory) => memory.kind === "procedure", - ); - const facts = memories.filter((memory) => memory.kind === "fact"); - const preferences = memories.filter( - (memory) => memory.kind === "preference", - ); const toResponseMemory = (memory: (typeof memories)[number]) => ({ canonicalFact: memory.content, expiresAtMs: memory.expiresAtMs ?? null, + kind: memory.kind, }); return { object: { - facts: facts.map(toResponseMemory), - preferences: preferences.map(toResponseMemory), - procedures: procedures.map(toResponseMemory), + memories: memories.map(toResponseMemory), }, }; }, @@ -241,6 +229,12 @@ function extractionModel( return { calls, model }; } +const throwingExtractionModel: PluginModel = { + async completeObject() { + throw new Error("memory extraction should not run"); + }, +}; + function slackContext( overrides: { channelId?: string; @@ -327,7 +321,6 @@ function completedRun( function processSessionContext( overrides: Partial = {}, ): MemoryTaskContext { - const runtime = localContext(); const run = overrides.run ?? ({ @@ -452,15 +445,14 @@ describe("memory plugin storage", () => { async completeObject() { return { object: { - facts: [], - preferences: [ + memories: [ { canonicalFact: "Prefers causes before mitigations in incident writeups.", expiresAtMs: null, + kind: "preference", }, ], - procedures: [], }, }; }, @@ -492,22 +484,29 @@ describe("memory plugin storage", () => { ]); }); - it("caps passive extraction at five memories across categories", async () => { + it("accepts up to five passive extraction memories", async () => { const model: PluginModel = { async completeObject() { return { object: { - facts: [ - { canonicalFact: "Fact one.", expiresAtMs: null }, - { canonicalFact: "Fact two.", expiresAtMs: null }, - ], - preferences: [ - { canonicalFact: "Prefers one.", expiresAtMs: null }, - { canonicalFact: "Prefers two.", expiresAtMs: null }, - ], - procedures: [ - { canonicalFact: "Procedure one.", expiresAtMs: null }, - { canonicalFact: "Procedure two.", expiresAtMs: null }, + memories: [ + { canonicalFact: "Fact one.", expiresAtMs: null, kind: "fact" }, + { canonicalFact: "Fact two.", expiresAtMs: null, kind: "fact" }, + { + canonicalFact: "Prefers one.", + expiresAtMs: null, + kind: "preference", + }, + { + canonicalFact: "Prefers two.", + expiresAtMs: null, + kind: "preference", + }, + { + canonicalFact: "Procedure one.", + expiresAtMs: null, + kind: "procedure", + }, ], }, }; @@ -529,6 +528,36 @@ describe("memory plugin storage", () => { ).resolves.toHaveLength(5); }); + it("rejects passive extraction responses with more than five memories", async () => { + const model: PluginModel = { + async completeObject() { + return { + object: { + memories: Array.from({ length: 6 }, (_, index) => ({ + canonicalFact: `Fact ${index + 1}.`, + expiresAtMs: null, + kind: "fact", + })), + }, + }; + }, + }; + const agent = createMemoryAgent(model); + + await expect( + agent.extractSessionMemories({ + transcript: [ + { + type: "message", + role: "user", + text: "Store several durable facts.", + }, + ], + runtimeContext: localContext(), + }), + ).rejects.toThrow("Too big"); + }); + it("uses AI_MEMORY_MODEL as the memory plugin model default", async () => { const previousModel = process.env.AI_MEMORY_MODEL; process.env.AI_MEMORY_MODEL = "anthropic/claude-sonnet-4.6"; @@ -575,7 +604,7 @@ describe("memory plugin storage", () => { const fixture = await createMemoryFixture(); try { - const { model, calls } = extractionModel([ + const { model } = extractionModel([ { kind: "preference", content: "Prefers QA notes that mention database row checks.", @@ -613,7 +642,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toHaveLength(1); const rows = await memoryDb(fixture) .select() .from(memorySqlSchema.juniorMemoryMemories) @@ -635,46 +663,54 @@ describe("memory plugin storage", () => { ]), ); expect(rows).toHaveLength(2); - expect(embedder.calls[0]).toEqual([ - "I prefer QA notes that mention database row checks. Deploy runbooks live in Notion.", - ]); - expect(embedder.calls.slice(1)).toEqual( - expect.arrayContaining([ - ["Prefers QA notes that mention database row checks."], - ["Deploy runbooks live in Notion."], - ]), + await expect( + memoryDb(fixture) + .select() + .from(memorySqlSchema.juniorMemoryEmbeddings) + .orderBy(memorySqlSchema.juniorMemoryEmbeddings.memoryId), + ).resolves.toEqual( + expect.arrayContaining( + rows.map((row) => + expect.objectContaining({ + dimensions: TEST_EMBEDDING_DIMENSIONS, + memoryId: row.id, + metric: "cosine", + model: "test-embedding-model", + provider: "test-embedding-provider", + }), + ), + ), ); } finally { await fixture.close(); } }, 15_000); - it("passes tool result evidence to passive extraction", async () => { + it("stores extracted conversation memories from completed sessions with tool results", async () => { const fixture = await createMemoryFixture(); try { const model: PluginModel = { async completeObject(input) { - const prompt = input.prompt; - const includesToolEvidence = - typeof prompt === "string" && - prompt.includes("queryAnalyticsCatalog") && - prompt.includes( + if ( + typeof input.prompt !== "string" || + !input.prompt.includes("queryAnalyticsCatalog") || + !input.prompt.includes( "The modeled warehouse cohort table is the source of truth for signup funnel analysis.", - ); + ) + ) { + return { object: { memories: [] } }; + } return { object: { - facts: [], - preferences: [], - procedures: includesToolEvidence - ? [ - { - canonicalFact: - "Signup funnel analysis should use the modeled warehouse cohort table.", - expiresAtMs: null, - }, - ] - : [], + memories: [ + { + canonicalFact: + "Signup funnel analysis should use the modeled warehouse cohort table.", + expiresAtMs: null, + kind: "procedure", + }, + ], }, }; }, @@ -731,7 +767,7 @@ describe("memory plugin storage", () => { try { const state = createMemoryState(); - const { model, calls } = extractionModel([ + const { model } = extractionModel([ { content: "Prefers retry-safe memory extraction.", kind: "preference", @@ -772,7 +808,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toHaveLength(1); await expect( memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), ).resolves.toEqual([ @@ -788,18 +823,12 @@ describe("memory plugin storage", () => { it("skips passive extraction for successful memory mutation tool turns", async () => { const fixture = await createMemoryFixture(); - const { model, calls } = extractionModel([ - { - kind: "preference", - content: "duplicate memory avoidance", - }, - ]); try { await processMemorySession( processSessionContext({ db: memoryDb(fixture), - model, + model: throwingExtractionModel, run: { async load() { return completedRun({ @@ -822,7 +851,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toEqual([]); await expect( memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), ).resolves.toEqual([]); @@ -833,18 +861,12 @@ describe("memory plugin storage", () => { it("skips passive extraction for failed memory mutation tool turns", async () => { const fixture = await createMemoryFixture(); - const { model, calls } = extractionModel([ - { - kind: "preference", - content: "failed memory mutation should not be reinterpreted", - }, - ]); try { await processMemorySession( processSessionContext({ db: memoryDb(fixture), - model, + model: throwingExtractionModel, run: { async load() { return completedRun({ @@ -867,7 +889,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toEqual([]); await expect( memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), ).resolves.toEqual([]); @@ -876,20 +897,13 @@ describe("memory plugin storage", () => { } }); - it("does not skip passive extraction for memory recall tool turns", async () => { + it("skips passive extraction for memory recall tool turns", async () => { const fixture = await createMemoryFixture(); try { - const { model, calls } = extractionModel([ - { - kind: "preference", - content: "recall turns can still learn durable facts", - }, - ]); - await processMemorySession( processSessionContext({ db: memoryDb(fixture), - model, + model: throwingExtractionModel, run: { async load() { return completedRun({ @@ -912,36 +926,23 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toHaveLength(1); await expect( memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), - ).resolves.toEqual([ - expect.objectContaining({ - content: "recall turns can still learn durable facts", - scope: "personal", - sourcePlatform: "local", - }), - ]); + ).resolves.toEqual([]); } finally { await fixture.close(); } - }, 15_000); + }); it("skips passive extraction in private Slack contexts", async () => { const fixture = await createMemoryFixture(); - const { model, calls } = extractionModel([ - { - kind: "preference", - content: "private Slack context skips", - }, - ]); const privateContext = slackContext({ channelId: "D123" }); try { await processMemorySession( processSessionContext({ db: memoryDb(fixture), - model, + model: throwingExtractionModel, run: { async load() { return completedRun({ @@ -962,7 +963,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toEqual([]); await expect( memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), ).resolves.toEqual([]); @@ -973,19 +973,13 @@ describe("memory plugin storage", () => { it("skips passive extraction for Slack sessions without a message key", async () => { const fixture = await createMemoryFixture(); - const { model, calls } = extractionModel([ - { - kind: "preference", - content: "Slack message key validation", - }, - ]); const runtime = slackContext(); try { await processMemorySession( processSessionContext({ db: memoryDb(fixture), - model, + model: throwingExtractionModel, run: { async load() { return completedRun({ @@ -1009,7 +1003,6 @@ describe("memory plugin storage", () => { }), ); - expect(calls).toEqual([]); await expect( memoryDb(fixture).select().from(memorySqlSchema.juniorMemoryMemories), ).resolves.toEqual([]); diff --git a/packages/junior/src/chat/plugins/model.ts b/packages/junior/src/chat/plugins/model.ts index 502d21214..b4658f591 100644 --- a/packages/junior/src/chat/plugins/model.ts +++ b/packages/junior/src/chat/plugins/model.ts @@ -10,6 +10,7 @@ import { completeObject, embedTexts } from "@/chat/pi/client"; export function createPluginModel( pluginName: string, options: PluginModelConfig = {}, + runtime: { signal?: AbortSignal } = {}, ): PluginModel { return { async completeObject(input) { @@ -26,6 +27,7 @@ export function createPluginModel( ...(input.maxTokens !== undefined ? { maxTokens: input.maxTokens } : {}), + signal: runtime.signal, metadata: { pluginName, pluginModelRole: "structured", @@ -37,12 +39,16 @@ export function createPluginModel( } /** Create the host-owned embedding capability exposed to prompt hooks. */ -export function createPluginEmbedder(pluginName: string): PluginEmbedder { +export function createPluginEmbedder( + pluginName: string, + runtime: { signal?: AbortSignal } = {}, +): PluginEmbedder { return { async embedTexts(input) { return await embedTexts({ modelId: botConfig.embeddingModelId, texts: input.texts, + signal: runtime.signal, metadata: { pluginName, pluginModelRole: "embedding", diff --git a/packages/junior/src/chat/plugins/task-runner.ts b/packages/junior/src/chat/plugins/task-runner.ts index a5da43231..b9deb95db 100644 --- a/packages/junior/src/chat/plugins/task-runner.ts +++ b/packages/junior/src/chat/plugins/task-runner.ts @@ -42,6 +42,10 @@ export interface ScheduleSessionCompletedPluginTasksOptions { send?: (message: PluginTaskQueueMessage) => Promise; } +interface ProcessPluginTaskOptions { + signal?: AbortSignal; +} + function isRecord(value: unknown): value is Record { return Boolean(value && typeof value === "object" && !Array.isArray(value)); } @@ -185,15 +189,20 @@ async function loadPluginRun( function taskPluginContext( plugin: PluginRegistration, message: PluginTaskQueueMessage, + options: ProcessPluginTaskOptions = {}, ): PluginTaskContext { const pluginName = plugin.manifest.name; const sessionParams = pluginTaskParamsSchema.parse(message.params); return { db: getDb(), - embedder: createPluginEmbedder(pluginName), + embedder: createPluginEmbedder(pluginName, { + signal: options.signal, + }), id: pluginTaskId(message), log: createPluginLogger(pluginName), - model: createPluginModel(pluginName, plugin.model), + model: createPluginModel(pluginName, plugin.model, { + signal: options.signal, + }), name: message.name, plugin: { name: pluginName }, run: { @@ -251,6 +260,7 @@ export async function scheduleSessionCompletedPluginTasks( /** Execute one parsed plugin task request. */ export async function processPluginTask( message: PluginTaskQueueMessage, + options: ProcessPluginTaskOptions = {}, ): Promise { await withPluginTaskLock(pluginTaskId(message), async () => { const resolved = findPluginTask(message); @@ -259,6 +269,8 @@ export async function processPluginTask( `Plugin task "${message.plugin}.${message.name}" is not registered`, ); } - await resolved.task.run(taskPluginContext(resolved.plugin, message)); + await resolved.task.run( + taskPluginContext(resolved.plugin, message, options), + ); }); } diff --git a/packages/junior/tests/unit/plugins/plugin-model.test.ts b/packages/junior/tests/unit/plugins/plugin-model.test.ts index 5d7585b7d..f5e0f6f3e 100644 --- a/packages/junior/tests/unit/plugins/plugin-model.test.ts +++ b/packages/junior/tests/unit/plugins/plugin-model.test.ts @@ -1,6 +1,12 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const completeObject = vi.fn(async () => ({ object: { ok: true } })); +const embedTexts = vi.fn(async () => ({ + dimensions: 1, + model: "test-embedding-model", + provider: "test-provider", + vectors: [[1]], +})); vi.mock("@/chat/config", () => ({ botConfig: { @@ -12,12 +18,13 @@ vi.mock("@/chat/config", () => ({ vi.mock("@/chat/pi/client", () => ({ completeObject, - embedTexts: vi.fn(), + embedTexts, })); describe("createPluginModel", () => { beforeEach(() => { completeObject.mockClear(); + embedTexts.mockClear(); }); it("uses the fast model for structured plugin calls by default", async () => { @@ -51,4 +58,19 @@ describe("createPluginModel", () => { }), ); }); + + it("passes host cancellation to plugin embedding calls", async () => { + const { createPluginEmbedder } = await import("@/chat/plugins/model"); + const controller = new AbortController(); + + await createPluginEmbedder("test-plugin", { + signal: controller.signal, + }).embedTexts({ texts: ["remember this"] }); + + expect(embedTexts).toHaveBeenCalledWith( + expect.objectContaining({ + signal: controller.signal, + }), + ); + }); }); diff --git a/specs/memory-plugin/extraction.md b/specs/memory-plugin/extraction.md index 8ddb844a1..f69091d11 100644 --- a/specs/memory-plugin/extraction.md +++ b/specs/memory-plugin/extraction.md @@ -88,25 +88,28 @@ The `processSession` task must: sessions and `pub` sources with a stable source key. Non-local `priv` sources and sources without stable identity are ignored before model extraction. -5. Skip passive extraction when the completed session already called an - explicit memory mutation tool (`createMemory` or `removeMemory`). Recall - tools (`listMemories` and `searchMemories`) must not suppress passive - extraction. -6. Provide visible existing memories as dedupe context only, not as source +5. Skip passive extraction when the completed session called a memory tool + (`createMemory`, `removeMemory`, `listMemories`, or `searchMemories`). + Memory tool turns already operate on memory-aware context; passive + extraction must not reinterpret recalled or listed memories as fresh source + evidence. +6. Recalled or listed memories are context for the visible answer and dedupe, + not source evidence for creating new memories. +7. Provide visible existing memories as dedupe context only, not as source evidence for new memories. -7. Use assistant-authored text only as context for interpreting the completed +8. Use assistant-authored text only as context for interpreting the completed run; assistant claims are not independent source evidence. -8. Extract candidate facts with a structured model output contract. -9. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or - non-durable facts. -10. Assign requester or conversation target from the memory kind returned by +9. Extract candidate facts with a structured model output contract. +10. Reject malformed, incoherent, unsafe, out-of-scope, redundant, or + non-durable facts. +11. Assign requester or conversation target from the memory kind returned by the memory agent, while deriving all authority-bearing ids from runtime context. -11. Insert accepted memories idempotently with a stable key derived through the +12. Insert accepted memories idempotently with a stable key derived through the runtime source helper, completed session reference, and extracted fact content. -12. Generate embeddings for accepted rows when the host embedder is configured. -13. Avoid storing raw extraction prompt, raw model output, or raw run text +13. Generate embeddings for accepted rows when the host embedder is configured. +14. Avoid storing raw extraction prompt, raw model output, or raw run text beyond the accepted memory records. Plugin tasks are best effort and at least once. If extraction or storage fails, @@ -143,8 +146,8 @@ Passive run extraction must follow these rules: search, issue, metric, incident, availability, or status answers whose values naturally change. 14. A user question is not source evidence for the answer; passive extraction - may store the answer only when user-authored factual text or a tool result - supports it. + may store the answer only when user-authored factual text or a non-memory + tool result supports it. 15. Personal-scoped memories must be public/shareable first-person facts from the current author/requester, and should be stored passively only when they are clearly durable and useful beyond the active task. @@ -204,17 +207,17 @@ Memory agent output must be structured. For explicit review it should include: - optional expiration when stored - normalized rejection reason code when rejected -For passive extraction it should include categorized arrays of accepted -candidate memories: - -- `preferences`: durable personal preferences, opinions, habits, or workflows - owned by the current requester; stored as requester memory. -- `procedures`: reusable task, process, triage-flow, or runbook instructions; - source-of-truth, lookup, or decision-path knowledge; stored as conversation - memory. -- `facts`: shared project, channel, operational, or runbook knowledge; stored - as conversation memory. Point-in-time query answers are excluded unless they - are stable beyond the run. +For passive extraction it should include one `memories` array of accepted +candidate memories. Each candidate includes: + +- `kind`: `preference`, `procedure`, or `fact` +- canonical stored content +- optional expiration + +The memory agent should return one object per distinct source assertion rather +than separate categorized arrays. The runtime derives storage target from +`kind`: requester memory for `preference`, conversation memory for `procedure` +and `fact`. Conversation-target passive memories in V1 are the primary path for learning how work gets done: task procedures, runbooks, project facts, channel norms, diff --git a/specs/memory-plugin/verification.md b/specs/memory-plugin/verification.md index d320ea817..255f943e2 100644 --- a/specs/memory-plugin/verification.md +++ b/specs/memory-plugin/verification.md @@ -100,8 +100,8 @@ Use integration tests for: dashboard reporting payloads - passive `session.completed` processing extracts from organic completed sessions without failing delivery -- passive extraction skips completed sessions where explicit `createMemory` was - already called +- passive extraction skips completed sessions where a memory tool was already + called - memory agent review rejects extracted candidates that violate workplace guidance - malformed or failed memory agent review fails closed for passive extraction