From 827ade0135035bd90204bd559d04833b604fc553 Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 20 Aug 2026 11:21:02 -0500 Subject: [PATCH] feat(runner): expose live activity details --- .../devtools/issue-thread/src/ThreadItems.tsx | 31 +- .../issue-thread/src/issue-thread.css | 48 +++ packages/paperclip-runner/package.json | 2 + .../src/issue-thread/live-projection.ts | 12 +- .../src/issue-thread/public-view.test.ts | 29 ++ .../src/issue-thread/public-view.ts | 1 + .../src/issue-thread/types.ts | 1 + .../src/live/evidence-redaction.ts | 66 +++- pnpm-lock.yaml | 344 ++++++------------ 9 files changed, 287 insertions(+), 247 deletions(-) diff --git a/packages/paperclip-runner/devtools/issue-thread/src/ThreadItems.tsx b/packages/paperclip-runner/devtools/issue-thread/src/ThreadItems.tsx index 9f6b1059837..75b3c9a142d 100644 --- a/packages/paperclip-runner/devtools/issue-thread/src/ThreadItems.tsx +++ b/packages/paperclip-runner/devtools/issue-thread/src/ThreadItems.tsx @@ -1,4 +1,6 @@ import { useState } from "react"; +import ReactMarkdown from "react-markdown"; +import remarkGfm from "remark-gfm"; import type { CapabilityEvidenceSectionId, @@ -13,6 +15,14 @@ const VISIBLE_STRIPS = 3; const STATUS_GLYPH = { ok: "✓", denied: "✕", running: "⏳" } as const; +function MarkdownBody({ children }: { children: string }) { + return ( +
+ {children} +
+ ); +} + export interface ThreadCallbacks { onOpenEvidence: (section: CapabilityEvidenceSectionId, recordId: string) => void; onRespond: (response: CapabilityInteractionResponse) => void; @@ -86,10 +96,19 @@ function ProgressItem({
-

- {item.eventCount} sanitized progress update{item.eventCount === 1 ? "" : "s"} observed. - Raw output, chain-of-thought, and credential values are not exposed. -

+ {Object.entries(item.details).map(([name, value]) => + name === "withheld" ? null : ( +
+ {name} +
{typeof value === "string" ? value : JSON.stringify(value, null, 2)}
+
+ ), + )} + {Array.isArray(item.details.withheld) ? ( +

+ Not available here: {item.details.withheld.join(", ")}. +

+ ) : null}
); @@ -115,7 +134,7 @@ function ThreadItemView({ {item.author} -
{item.body}
+ {item.body} ); @@ -138,7 +157,7 @@ function ThreadItemView({ ) : null} -
{item.body}
+ {item.body} ); diff --git a/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css b/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css index 0ae5e36b26a..a45947793a6 100644 --- a/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css +++ b/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css @@ -671,6 +671,38 @@ textarea { overflow-wrap: anywhere; } +.pit-markdown { + white-space: normal; +} + +.pit-markdown > :first-child { margin-top: 0; } +.pit-markdown > :last-child { margin-bottom: 0; } +.pit-markdown pre, +.pit-markdown code { + font-family: var(--pit-font-mono); +} +.pit-markdown pre { + overflow-x: auto; + padding: var(--pit-space-3); + border: 1px solid var(--pit-border); + border-radius: var(--pit-radius-sm); + background: var(--pit-background); +} +.pit-markdown :not(pre) > code { + padding: 0.08rem 0.28rem; + border-radius: var(--pit-radius-sm); + background: var(--pit-surface-sunken); +} +.pit-markdown blockquote { + margin-left: 0; + padding-left: var(--pit-space-3); + border-left: 2px solid var(--pit-accent); + color: var(--pit-muted-foreground); +} +.pit-markdown table { border-collapse: collapse; } +.pit-markdown th, +.pit-markdown td { padding: var(--pit-space-2); border: 1px solid var(--pit-border); } + .pit-durable-tag { display: inline-flex; align-items: center; @@ -840,6 +872,22 @@ textarea { margin: 0; } +.pit-activity-field { + display: grid; + gap: var(--pit-space-1); +} + +.pit-activity-field > span { + color: var(--pit-faint-foreground); + font-family: var(--pit-font-mono); + text-transform: uppercase; + letter-spacing: 0.06em; +} + +.pit-withheld-note { + color: var(--pit-faint-foreground); +} + .pit-activity-payloads { display: grid; gap: var(--pit-space-2); diff --git a/packages/paperclip-runner/package.json b/packages/paperclip-runner/package.json index c8a2041339c..99d7c87ffa5 100644 --- a/packages/paperclip-runner/package.json +++ b/packages/paperclip-runner/package.json @@ -148,6 +148,8 @@ "json-schema-to-ts": "^3.1.1", "react": "^19.2.7", "react-dom": "^19.2.7", + "react-markdown": "^10.1.0", + "remark-gfm": "^4.0.1", "typescript": "^5.7.3", "vite": "^6.1.0", "vitest": "^4.1.10" diff --git a/packages/paperclip-runner/src/issue-thread/live-projection.ts b/packages/paperclip-runner/src/issue-thread/live-projection.ts index 497068b5a06..5e31e068848 100644 --- a/packages/paperclip-runner/src/issue-thread/live-projection.ts +++ b/packages/paperclip-runner/src/issue-thread/live-projection.ts @@ -497,7 +497,10 @@ function derivedRecordItems( items.push({ kind: "interaction", id: `item-interaction-${interaction.id}`, - at: interaction.createdAt, + // Anchor the prompt to the tool call that created it. Mock timestamps can + // precede streamed provider activity, which used to hoist the card above + // the exchange instead of showing it inline where Codex asked. + at: pair.at, ...interactionCard(interaction, state), }); } @@ -772,7 +775,7 @@ export function projectCapabilityIssueThread( event: keyof typeof PROGRESS_EVENTS; at: string; count: number; - command: string; + details: Record; } >(); for (const entry of snapshot.evidence) { @@ -785,7 +788,7 @@ export function projectCapabilityIssueThread( const key = event.endsWith("_delta") ? `${entry.turnId}:${event}` : entry.id; const group = progressGroups.get(key); if (group === undefined) { - progressGroups.set(key, { id: entry.id, turnId: entry.turnId, event, at: entry.at, count: 1, command: readString(entry.data.command) }); + progressGroups.set(key, { id: entry.id, turnId: entry.turnId, event, at: entry.at, count: 1, details: entry.data }); } else { group.count += 1; } @@ -800,8 +803,9 @@ export function projectCapabilityIssueThread( activity: copy.activity, status: running ? "running" : "complete", label: copy.label, - summary: group.command || (running ? copy.running : copy.complete), + summary: running ? copy.running : copy.complete, eventCount: group.count, + details: group.details, }); } diff --git a/packages/paperclip-runner/src/issue-thread/public-view.test.ts b/packages/paperclip-runner/src/issue-thread/public-view.test.ts index f5488eb8e73..666767e501e 100644 --- a/packages/paperclip-runner/src/issue-thread/public-view.test.ts +++ b/packages/paperclip-runner/src/issue-thread/public-view.test.ts @@ -237,6 +237,35 @@ describe("Capability evidence redaction", () => { expect(redacted.command).toContain("printf ok"); expect(redacted.command).not.toContain("hidden-token"); expect(redacted.command).not.toContain("pcp_1234567890"); + expect(redacted.withheld).toEqual([ + "command output (not retained by the browser evidence boundary)", + ]); + expect(JSON.stringify(redacted)).not.toContain(CANARY); + }); + + it("retains safe Codex tool details and identifies redacted credentials", () => { + const redacted = redactCapabilityEvidenceData("provider_event", { + method: "item/completed", + params: { + item: { + type: "dynamicToolCall", + tool: "paperclip_finish", + namespace: "paperclip", + status: "completed", + arguments: { summary: "Done", apiKey: CANARY }, + result: { ok: true, note: "Recorded" }, + }, + }, + }); + + expect(redacted).toMatchObject({ + event: "tool_completed", + tool: "paperclip_finish", + namespace: "paperclip", + status: "completed", + arguments: { summary: "Done", apiKey: "[redacted]" }, + result: { ok: true, note: "Recorded" }, + }); expect(JSON.stringify(redacted)).not.toContain(CANARY); }); diff --git a/packages/paperclip-runner/src/issue-thread/public-view.ts b/packages/paperclip-runner/src/issue-thread/public-view.ts index 0aa805103c5..108eca845bd 100644 --- a/packages/paperclip-runner/src/issue-thread/public-view.ts +++ b/packages/paperclip-runner/src/issue-thread/public-view.ts @@ -296,6 +296,7 @@ function publicItem(item: CapabilityThreadItem, aliases: Aliases): CapabilityThr label: clamp(item.label), summary: clamp(item.summary), eventCount: item.eventCount, + details: item.details, }; case "interaction": return { diff --git a/packages/paperclip-runner/src/issue-thread/types.ts b/packages/paperclip-runner/src/issue-thread/types.ts index 16d7c91868f..98da740875c 100644 --- a/packages/paperclip-runner/src/issue-thread/types.ts +++ b/packages/paperclip-runner/src/issue-thread/types.ts @@ -206,6 +206,7 @@ export type CapabilityThreadItem = label: string; summary: string; eventCount: number; + details: Record; } | ({ kind: "interaction"; id: string; at: string } & CapabilityThreadInteractionCard) | { diff --git a/packages/paperclip-runner/src/live/evidence-redaction.ts b/packages/paperclip-runner/src/live/evidence-redaction.ts index 315574bebe1..203a69d47cc 100644 --- a/packages/paperclip-runner/src/live/evidence-redaction.ts +++ b/packages/paperclip-runner/src/live/evidence-redaction.ts @@ -41,7 +41,8 @@ export type CapabilityEvidenceKind = /** Disposition copy is rendered, so it is bounded rather than unbounded. */ const MAX_DISPOSITION_CHARS = 500; -const MAX_COMMAND_CHARS = 2_000; +const MAX_COMMAND_CHARS = 64_000; +const MAX_PROVIDER_VALUE_CHARS = 16_000; const MAX_FIELD_NAMES = 32; const MAX_ENTITY_REFS = 64; @@ -146,6 +147,64 @@ function commandPreview(item: Record): string | null { return command; } +const SECRET_FIELD = /(?:api[_-]?key|access[_-]?token|auth[_-]?token|password|secret|credential)/i; + +function safeProviderValue(value: unknown, key = "", depth = 0): CapabilityJsonValue { + if (SECRET_FIELD.test(key)) return "[redacted]"; + if (value === null || typeof value === "boolean" || typeof value === "number") return value; + if (typeof value === "string") { + return clamp( + value + .replace(/bearer\s+[a-z0-9._-]+/gi, "Bearer [redacted]") + .replace(/\b(?:sk|pcp)_[a-z0-9._-]{8,}\b/gi, "[redacted]"), + MAX_PROVIDER_VALUE_CHARS, + ); + } + if (depth >= 5) return "[nested value omitted]"; + if (Array.isArray(value)) { + return value.slice(0, 64).map((entry) => safeProviderValue(entry, key, depth + 1)); + } + if (typeof value === "object" && value !== null) { + return Object.fromEntries( + Object.entries(value as Record) + .slice(0, 64) + .map(([childKey, childValue]) => [childKey, safeProviderValue(childValue, childKey, depth + 1)]), + ); + } + return String(value); +} + +function providerActivityDetails( + event: string, + item: Record, +): Record { + const details: Record = {}; + const command = event.startsWith("command_") ? commandPreview(item) : null; + if (command !== null) details.command = command; + for (const name of ["status", "exitCode", "durationMs"] as const) { + const value = item[name]; + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + details[name] = value; + } + } + if (event.startsWith("tool_")) { + const tool = asString(item.tool) || asString(item.name); + const namespace = asString(item.namespace); + if (tool) details.tool = clamp(tool, 240); + if (namespace) details.namespace = clamp(namespace, 240); + if ("arguments" in item) details.arguments = safeProviderValue(item.arguments, "arguments"); + if (event === "tool_completed" && "result" in item) { + details.result = safeProviderValue(item.result, "result"); + } + } + if (Object.keys(details).length > 0) { + details.withheld = event.startsWith("command_") + ? ["command output (not retained by the browser evidence boundary)"] + : ["provider-only reasoning and hidden chain-of-thought"]; + } + return details; +} + function copyFields( data: Record, names: readonly string[], @@ -229,12 +288,9 @@ export function redactCapabilityEvidenceData( case "provider_event": { const event = capabilityProviderEventCategory(asString(data.method), asRecord(data.params)); const item = asRecord(asRecord(data.params).item); - const command = event === "command_started" || event === "command_completed" - ? commandPreview(item) - : null; return { event, - ...(command === null ? {} : { command }), + ...providerActivityDetails(event, item), }; } case "diagnostic": diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b24014d3009..0aad0d9f982 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -122,6 +122,9 @@ importers: packages/adapter-utils: dependencies: + '@paperclipai/shared': + specifier: workspace:* + version: link:../shared acpx: specifier: 0.12.0 version: 0.12.0(patch_hash=x3fethhotv43zektyl5prdwf54) @@ -430,6 +433,61 @@ importers: specifier: ^4.1.10 version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(jsdom@28.1.0(@noble/hashes@2.3.0))(vite@7.3.1(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12)) + packages/paperclip-eval-kernel: + devDependencies: + typescript: + specifier: ^5.7.3 + version: 5.9.3 + + packages/paperclip-runner: + dependencies: + ajv: + specifier: ^8.20.0 + version: 8.20.0 + devDependencies: + '@playwright/test': + specifier: ^1.61.1 + version: 1.62.1 + '@types/node': + specifier: ^22.20.1 + version: 22.20.1 + '@types/react': + specifier: ^19.2.17 + version: 19.2.17 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.17) + '@vitejs/plugin-react': + specifier: ^4.7.0 + version: 4.7.0(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12)) + axe-core: + specifier: ^4.12.1 + version: 4.13.0 + json-schema-to-ts: + specifier: ^3.1.1 + version: 3.1.1 + react: + specifier: ^19.2.7 + version: 19.2.7 + react-dom: + specifier: ^19.2.7 + version: 19.2.7(react@19.2.7) + react-markdown: + specifier: ^10.1.0 + version: 10.1.0(@types/react@19.2.17)(react@19.2.7) + remark-gfm: + specifier: ^4.0.1 + version: 4.0.1 + typescript: + specifier: ^5.7.3 + version: 5.9.3 + vite: + specifier: ^6.1.0 + version: 6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12) + vitest: + specifier: ^4.1.10 + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(jsdom@28.1.0(@noble/hashes@2.3.0))(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12)) + packages/plugins/create-paperclip-plugin: dependencies: '@paperclipai/plugin-sdk': @@ -852,6 +910,9 @@ importers: specifier: ^3.24.2 version: 3.25.76 devDependencies: + '@paperclipai/paperclip-runner': + specifier: workspace:* + version: link:../packages/paperclip-runner '@types/express': specifier: ^5.0.0 version: 5.0.6 @@ -1280,68 +1341,34 @@ packages: resolution: {integrity: sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==} engines: {node: '>=18.0.0'} - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.29.7': resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} - engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.7': resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} engines: {node: '>=6.9.0'} - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - '@babel/core@7.29.7': resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} engines: {node: '>=6.9.0'} - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - '@babel/generator@7.29.8': resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.29.7': resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - '@babel/helper-globals@7.29.7': resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.29.7': resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@7.29.7': resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} engines: {node: '>=6.9.0'} @@ -1352,43 +1379,22 @@ packages: resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} - engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.29.7': resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.29.7': resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.6': - resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} - engines: {node: '>=6.9.0'} - '@babel/helpers@7.29.7': resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} - engines: {node: '>=6.0.0'} - hasBin: true - '@babel/parser@7.29.8': resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} @@ -1410,26 +1416,14 @@ packages: resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} - engines: {node: '>=6.9.0'} - '@babel/template@7.29.7': resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} - engines: {node: '>=6.9.0'} - '@babel/traverse@7.29.8': resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.8': resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} @@ -5644,10 +5638,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - baseline-browser-mapping@2.9.19: - resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} - hasBin: true - bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} @@ -5750,11 +5740,6 @@ packages: resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} engines: {node: 20 || >=22} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.28.8: resolution: {integrity: sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -5800,9 +5785,6 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - caniuse-lite@1.0.30001770: - resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==} - caniuse-lite@1.0.30001809: resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} @@ -6405,9 +6387,6 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.286: - resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} - electron-to-chromium@1.5.409: resolution: {integrity: sha512-ChI4N44d0B4A6C8prnNjMOaGgE59fUyEVYcRYm2XEXIjMbbvF5i9UL1cblDbpGqiU0uS8FE8UcKxqZqTXdmzbQ==} @@ -7565,9 +7544,6 @@ packages: engines: {node: '>= 10.12.0'} hasBin: true - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - node-releases@2.0.53: resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} engines: {node: '>=18'} @@ -7829,9 +7805,6 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - property-information@7.1.0: - resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} - property-information@7.2.0: resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} @@ -8561,12 +8534,6 @@ packages: resolution: {integrity: sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==} engines: {node: '>=18.12.0'} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-browserslist-db@1.3.1: resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} hasBin: true @@ -9271,42 +9238,14 @@ snapshots: '@aws/lambda-invoke-store@0.3.0': {} - '@babel/code-frame@7.29.0': - dependencies: - '@babel/helper-validator-identifier': 7.28.5 - js-tokens: 4.0.0 - picocolors: 1.1.1 - '@babel/code-frame@7.29.7': dependencies: '@babel/helper-validator-identifier': 7.29.7 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.0': {} - '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -9327,14 +9266,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - '@babel/generator@7.29.8': dependencies: '@babel/parser': 7.29.8 @@ -9343,14 +9274,6 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.28.6': - dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 - semver: 6.3.1 - '@babel/helper-compilation-targets@7.29.7': dependencies: '@babel/compat-data': 7.29.7 @@ -9359,17 +9282,8 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-globals@7.28.0': {} - '@babel/helper-globals@7.29.7': {} - '@babel/helper-module-imports@7.28.6': - dependencies: - '@babel/traverse': 7.29.8 - '@babel/types': 7.29.8 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-imports@7.29.7': dependencies: '@babel/traverse': 7.29.8 @@ -9377,15 +9291,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -9397,72 +9302,39 @@ snapshots: '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-option@7.27.1': {} - '@babel/helper-validator-option@7.29.7': {} - '@babel/helpers@7.28.6': - dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - '@babel/helpers@7.29.7': dependencies: '@babel/template': 7.29.7 '@babel/types': 7.29.8 - '@babel/parser@7.29.0': - dependencies: - '@babel/types': 7.29.0 - '@babel/parser@7.29.8': dependencies: '@babel/types': 7.29.8 - '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.0 + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.28.6 '@babel/runtime@7.29.7': {} - '@babel/template@7.28.6': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 '@babel/parser': 7.29.8 '@babel/types': 7.29.8 - '@babel/traverse@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - '@babel/traverse@7.29.8': dependencies: '@babel/code-frame': 7.29.7 @@ -9475,11 +9347,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/types@7.29.8': dependencies: '@babel/helper-string-parser': 7.29.7 @@ -12947,24 +12814,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.8 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.8 '@types/body-parser@1.19.6': dependencies: @@ -13228,9 +13095,9 @@ snapshots: '@vitejs/plugin-react@4.7.0(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12))': dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@babel/core': 7.29.7 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.7) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.7) '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 react-refresh: 0.17.0 @@ -13288,6 +13155,14 @@ snapshots: optionalDependencies: vite: 7.3.1(@types/node@25.2.3)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12) + '@vitest/mocker@4.1.11(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12))': + dependencies: + '@vitest/spy': 4.1.11 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12) + '@vitest/mocker@4.1.11(vite@7.3.1(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12))': dependencies: '@vitest/spy': 4.1.11 @@ -13536,8 +13411,6 @@ snapshots: baseline-browser-mapping@2.11.15: {} - baseline-browser-mapping@2.9.19: {} - bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 @@ -13629,14 +13502,6 @@ snapshots: dependencies: balanced-match: 4.0.4 - browserslist@4.28.1: - dependencies: - baseline-browser-mapping: 2.9.19 - caniuse-lite: 1.0.30001770 - electron-to-chromium: 1.5.286 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) - browserslist@4.28.8: dependencies: baseline-browser-mapping: 2.11.15 @@ -13707,8 +13572,6 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - caniuse-lite@1.0.30001770: {} - caniuse-lite@1.0.30001809: {} ccount@2.0.1: {} @@ -14217,8 +14080,6 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.286: {} - electron-to-chromium@1.5.409: {} embedded-postgres@18.1.0-beta.16(patch_hash=55uhvnotpqyiy37rn3pqpukhei): @@ -14845,7 +14706,7 @@ snapshots: mdast-util-mdx-expression: 2.0.1 mdast-util-mdx-jsx: 3.2.0 mdast-util-mdxjs-esm: 2.0.1 - property-information: 7.1.0 + property-information: 7.2.0 space-separated-tokens: 2.0.2 style-to-js: 1.1.21 unist-util-position: 5.0.0 @@ -15899,8 +15760,6 @@ snapshots: - supports-color optional: true - node-releases@2.0.27: {} - node-releases@2.0.53: {} nopt@5.0.0: @@ -16228,8 +16087,6 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - property-information@7.1.0: {} - property-information@7.2.0: {} proxy-addr@2.0.7: @@ -17191,12 +17048,6 @@ snapshots: picomatch: 4.0.5 webpack-virtual-modules: 0.6.2 - update-browserslist-db@1.2.3(browserslist@4.28.1): - dependencies: - browserslist: 4.28.1 - escalade: 3.2.0 - picocolors: 1.1.1 - update-browserslist-db@1.3.1(browserslist@4.28.8): dependencies: browserslist: 4.28.8 @@ -17402,6 +17253,35 @@ snapshots: transitivePeerDependencies: - msw + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(jsdom@28.1.0(@noble/hashes@2.3.0))(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12)): + dependencies: + '@vitest/expect': 4.1.11 + '@vitest/mocker': 4.1.11(vite@6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12)) + '@vitest/pretty-format': 4.1.11 + '@vitest/runner': 4.1.11 + '@vitest/snapshot': 4.1.11 + '@vitest/spy': 4.1.11 + '@vitest/utils': 4.1.11 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 0.30.21 + obug: 2.1.4 + pathe: 2.0.3 + picomatch: 4.0.5 + std-env: 4.2.0 + tinybench: 2.9.0 + tinyexec: 1.3.0 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.1 + vite: 6.4.3(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@types/node': 22.20.1 + jsdom: 28.1.0(@noble/hashes@2.3.0) + transitivePeerDependencies: + - msw + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(jsdom@28.1.0(@noble/hashes@2.3.0))(vite@7.3.1(@types/node@22.20.1)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.23.12)): dependencies: '@vitest/expect': 4.1.11