From 706b79819e62f01d3fa1812bfdfa20b0a6a032b2 Mon Sep 17 00:00:00 2001 From: Aiden Bai Date: Thu, 19 Mar 2026 03:45:27 -0700 Subject: [PATCH 1/5] chore: remove tailwind-merge dependency Simplify cn utility to use clsx only, fix tailwindcss import with source("."), and gitignore meta.json. Made-with: Cursor --- .gitignore | 3 ++- packages/react-grab/package.json | 1 - packages/react-grab/src/styles.css | 2 +- packages/react-grab/src/utils/cn.ts | 3 +-- packages/react-grab/tsup.config.ts | 2 +- pnpm-lock.yaml | 3 --- 6 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 9410ad399..0a4a02732 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,5 @@ test-results playwright-report .vercel .cursor/debug.log -.cursor \ No newline at end of file +.cursor +meta.json \ No newline at end of file diff --git a/packages/react-grab/package.json b/packages/react-grab/package.json index bb2c0ab89..0cb819eb6 100644 --- a/packages/react-grab/package.json +++ b/packages/react-grab/package.json @@ -117,7 +117,6 @@ "esbuild-plugin-babel": "^0.2.3", "oxlint": "^1.42.0", "publint": "^0.2.12", - "tailwind-merge": "^2.5.5", "tailwindcss": "^4.1.0", "tsup": "^8.2.4" }, diff --git a/packages/react-grab/src/styles.css b/packages/react-grab/src/styles.css index 4c4eaca8e..d55bc0ea8 100644 --- a/packages/react-grab/src/styles.css +++ b/packages/react-grab/src/styles.css @@ -1,4 +1,4 @@ -@import "tailwindcss"; +@import "tailwindcss" source("."); @theme { --font-sans: "Geist", ui-sans-serif, system-ui, sans-serif; diff --git a/packages/react-grab/src/utils/cn.ts b/packages/react-grab/src/utils/cn.ts index 8f55b553c..e4fba47da 100644 --- a/packages/react-grab/src/utils/cn.ts +++ b/packages/react-grab/src/utils/cn.ts @@ -1,4 +1,3 @@ import { clsx, type ClassValue } from "clsx"; -import { twMerge } from "tailwind-merge"; -export const cn = (...inputs: ClassValue[]): string => twMerge(clsx(inputs)); +export const cn = (...inputs: ClassValue[]): string => clsx(inputs); diff --git a/packages/react-grab/tsup.config.ts b/packages/react-grab/tsup.config.ts index 092c985f7..6ce39c507 100644 --- a/packages/react-grab/tsup.config.ts +++ b/packages/react-grab/tsup.config.ts @@ -50,7 +50,7 @@ const DEFAULT_OPTIONS: Options = { ".css": "text", }, minify: process.env.NODE_ENV === "production", - noExternal: ["clsx", "tailwind-merge", "solid-js", "bippy"], + noExternal: ["clsx", "solid-js", "bippy"], onSuccess: process.env.COPY ? "pbcopy < ./dist/index.global.js" : undefined, outDir: "./dist", sourcemap: false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 243c87bee..82a4b1876 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -523,9 +523,6 @@ importers: publint: specifier: ^0.2.12 version: 0.2.12 - tailwind-merge: - specifier: ^2.5.5 - version: 2.6.0 tailwindcss: specifier: ^4.1.0 version: 4.1.15 From aa7bc228edf9fff0f447dbbf8743e2fbc10016e6 Mon Sep 17 00:00:00 2001 From: Aiden Bai Date: Thu, 19 Mar 2026 16:34:14 -0700 Subject: [PATCH 2/5] chore: clean up AGENTS.md headings and remove stale flaky test note Rename "Cursor Cloud specific instructions" to "Development instructions" and remove outdated "Known flaky test" section. Co-Authored-By: Claude Opus 4.6 --- AGENTS.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 5773c4a4d..d9fb39056 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -101,7 +101,7 @@ pnpm typecheck # runs type checking pnpm format ``` -## Cursor Cloud specific instructions +## Development instructions This is a pnpm + Turborepo monorepo (19 packages under `packages/`). No external services (databases, Docker, etc.) are required. @@ -117,10 +117,6 @@ The root `package.json` has `pnpm.onlyBuiltDependencies` configured for `@parcel E2E tests (`pnpm test` at root) run Playwright against the `e2e-playground` Vite dev server on port 5175 (auto-started by the Playwright config). Chromium must be installed: `npx --prefix packages/react-grab playwright install chromium --with-deps`. -### Known flaky test - -`e2e/history-items.spec.ts` > "should reposition when toolbar is dragged to top edge" intermittently times out in headless CI environments. This is a pre-existing issue. - ### Key commands reference See root `package.json` scripts and `CONTRIBUTING.md` for the full list. Quick reference: From 0c88cc615569b823bfece08c003651446b2b7798 Mon Sep 17 00:00:00 2001 From: Aiden Bai Date: Thu, 19 Mar 2026 16:34:18 -0700 Subject: [PATCH 3/5] feat: migrate to Solid 2.0 beta - Upgrade solid-js, @solidjs/web, babel-preset-solid to 2.0.0-beta.3 - Split all createEffect calls into (compute, apply) form - Replace onMount with onSettled (return cleanup) - Replace Index with For keyed={false} - Replace classList with class array/object form - Replace produce/path-style setStore with draft-first and storePath - Replace createResource with createSignal + createEffect - Remove batch (automatic in 2.0), on helper, solid-js/store, solid-js/web - Add stale-request guards for async createResource replacements - Add defer: true to 5 effects that require deferred initial execution - Fix aria-pressed/aria-expanded to use string literals - Fix readOnly to lowercase readonly --- packages/react-grab/package.json | 5 +- .../src/components/clear-history-prompt.tsx | 8 +- .../src/components/context-menu.tsx | 79 +-- .../src/components/history-dropdown.tsx | 229 ++++---- .../src/components/overlay-canvas.tsx | 308 +++++----- .../react-grab/src/components/renderer.tsx | 11 +- .../selection-label/arrow-navigation-menu.tsx | 106 ++-- .../selection-label/completion-view.tsx | 16 +- .../selection-label/discard-prompt.tsx | 13 +- .../components/selection-label/error-view.tsx | 19 +- .../src/components/selection-label/index.tsx | 153 ++--- .../src/components/toolbar/index.tsx | 254 ++++----- .../components/toolbar/toolbar-content.tsx | 4 +- .../src/components/toolbar/toolbar-menu.tsx | 27 +- .../react-grab/src/components/tooltip.tsx | 46 +- packages/react-grab/src/core/index.tsx | 528 +++++++++--------- .../react-grab/src/core/plugin-registry.ts | 14 +- packages/react-grab/src/core/store.ts | 420 +++++++------- .../src/utils/create-anchored-dropdown.ts | 90 +-- packages/react-grab/tsup.config.ts | 2 +- pnpm-lock.yaml | 120 +++- 21 files changed, 1284 insertions(+), 1168 deletions(-) diff --git a/packages/react-grab/package.json b/packages/react-grab/package.json index 0cb819eb6..f0fe555f2 100644 --- a/packages/react-grab/package.json +++ b/packages/react-grab/package.json @@ -100,9 +100,10 @@ "dependencies": { "@medv/finder": "^4.0.2", "@react-grab/cli": "workspace:*", + "@solidjs/web": "2.0.0-beta.3", "bippy": "^0.5.32", "element-source": "^0.0.3", - "solid-js": "^1.9.10" + "solid-js": "2.0.0-beta.3" }, "devDependencies": { "@babel/core": "^7.28.5", @@ -111,7 +112,7 @@ "@tailwindcss/cli": "^4.1.17", "@types/node": "^20.19.23", "@types/react": "^19.2.11", - "babel-preset-solid": "^1.9.10", + "babel-preset-solid": "2.0.0-beta.3", "clsx": "^2.1.1", "concurrently": "^9.1.2", "esbuild-plugin-babel": "^0.2.3", diff --git a/packages/react-grab/src/components/clear-history-prompt.tsx b/packages/react-grab/src/components/clear-history-prompt.tsx index 127adda43..659a3aa62 100644 --- a/packages/react-grab/src/components/clear-history-prompt.tsx +++ b/packages/react-grab/src/components/clear-history-prompt.tsx @@ -1,4 +1,4 @@ -import { Show, onMount, onCleanup } from "solid-js"; +import { Show, onSettled } from "solid-js"; import type { Component } from "solid-js"; import type { DropdownAnchor } from "../types.js"; import { DROPDOWN_EDGE_TRANSFORM_ORIGIN, Z_INDEX_LABEL } from "../constants.js"; @@ -24,7 +24,7 @@ export const ClearHistoryPrompt: Component = ( () => props.position, ); - onMount(() => { + onSettled(() => { dropdown.measure(); const unregisterOverlayDismiss = registerOverlayDismiss({ isOpen: () => Boolean(props.position), @@ -33,10 +33,10 @@ export const ClearHistoryPrompt: Component = ( shouldIgnoreInputEvents: true, }); - onCleanup(() => { + return () => { dropdown.clearAnimationHandles(); unregisterOverlayDismiss(); - }); + }; }); return ( diff --git a/packages/react-grab/src/components/context-menu.tsx b/packages/react-grab/src/components/context-menu.tsx index c10a72af6..1a257d72c 100644 --- a/packages/react-grab/src/components/context-menu.tsx +++ b/packages/react-grab/src/components/context-menu.tsx @@ -1,8 +1,7 @@ import { Show, For, - onMount, - onCleanup, + onSettled, createSignal, createEffect, createMemo, @@ -80,11 +79,14 @@ export const ContextMenu: Component = (props) => { } }; - createEffect(() => { - if (isVisible()) { - nativeRequestAnimationFrame(measureContainer); - } - }); + createEffect( + () => isVisible(), + (visible) => { + if (visible) { + nativeRequestAnimationFrame(measureContainer); + } + }, + ); const computedPosition = createMemo(() => { const bounds = props.selectionBounds; @@ -165,7 +167,7 @@ export const ContextMenu: Component = (props) => { } }; - onMount(() => { + onSettled(() => { measureContainer(); const handleKeyDown = (event: KeyboardEvent) => { @@ -219,10 +221,10 @@ export const ContextMenu: Component = (props) => { }); window.addEventListener("keydown", handleKeyDown, { capture: true }); - onCleanup(() => { + return () => { unregisterOverlayDismiss(); window.removeEventListener("keydown", handleKeyDown, { capture: true }); - }); + }; }); return ( @@ -283,33 +285,36 @@ export const ContextMenu: Component = (props) => { class="pointer-events-none absolute bg-black/5 opacity-0 transition-[top,left,width,height,opacity] duration-75 ease-out" /> - {(item) => ( - - )} + {(itemAccessor) => { + const menuItem = () => itemAccessor(); + return ( + + ); + }} diff --git a/packages/react-grab/src/components/history-dropdown.tsx b/packages/react-grab/src/components/history-dropdown.tsx index 5c7763997..6172b2327 100644 --- a/packages/react-grab/src/components/history-dropdown.tsx +++ b/packages/react-grab/src/components/history-dropdown.tsx @@ -1,12 +1,4 @@ -import { - Show, - For, - onMount, - onCleanup, - createSignal, - createEffect, - on, -} from "solid-js"; +import { Show, For, onSettled, createSignal, createEffect } from "solid-js"; import type { Component } from "solid-js"; import type { HistoryItem, DropdownAnchor } from "../types.js"; import { @@ -102,15 +94,14 @@ export const HistoryDropdown: Component = (props) => { // HACK: mouseenter doesn't fire when an element appears under the cursor, so we check :hover after the enter animation commits createEffect( - on( - () => dropdown.isAnimatedIn(), - (animatedIn) => { - if (animatedIn && containerRef?.matches(":hover")) { - props.onDropdownHover?.(true); - } - }, - { defer: true }, - ), + () => dropdown.isAnimatedIn(), + (animatedIn) => { + if (animatedIn && containerRef?.matches(":hover")) { + props.onDropdownHover?.(true); + } + }, + undefined, + { defer: true }, ); const clampedMaxWidth = () => @@ -129,7 +120,7 @@ export const HistoryDropdown: Component = (props) => { const panelMinWidth = () => Math.max(DROPDOWN_MIN_WIDTH_PX, props.position?.toolbarWidth ?? 0); - onMount(() => { + onSettled(() => { dropdown.measure(); const handleKeyDown = (event: KeyboardEvent) => { @@ -143,13 +134,13 @@ export const HistoryDropdown: Component = (props) => { window.addEventListener("keydown", handleKeyDown, { capture: true }); - onCleanup(() => { + return () => { clearTimeout(copyAllFeedbackTimeout); clearTimeout(copyItemFeedbackTimeout); dropdown.clearAnimationHandles(); window.removeEventListener("keydown", handleKeyDown, { capture: true }); safePolygonTracker.stop(); - }); + }; }); return ( @@ -284,104 +275,114 @@ export const HistoryDropdown: Component = (props) => { class="pointer-events-none absolute bg-black/5 opacity-0 transition-[top,left,width,height,opacity] duration-75 ease-out" /> - {(item) => ( -
event.stopPropagation()} - onClick={(event) => { - event.stopPropagation(); - props.onSelectItem?.(item); - setConfirmedCopyItemId(item.id); - clearTimeout(copyItemFeedbackTimeout); - copyItemFeedbackTimeout = setTimeout(() => { - setConfirmedCopyItemId(null); - }, FEEDBACK_DURATION_MS); - }} - onKeyDown={(event) => { - if ( - event.code === "Space" && - event.currentTarget === event.target - ) { - event.preventDefault(); + {(itemAccessor) => { + const historyItem = () => itemAccessor(); + return ( +
event.stopPropagation()} + onClick={(event) => { event.stopPropagation(); - props.onSelectItem?.(item); - } - }} - onMouseEnter={(event) => { - if (!props.disconnectedItemIds?.has(item.id)) { - props.onItemHover?.(item.id); - } - updateHighlight(event.currentTarget); - }} - onMouseLeave={() => { - props.onItemHover?.(null); - clearHighlight(); - }} - onFocus={(event) => updateHighlight(event.currentTarget)} - onBlur={clearHighlight} - > - - - {getHistoryItemDisplayName(item)} - - - - {item.commentText} + props.onSelectItem?.(historyItem()); + setConfirmedCopyItemId(historyItem().id); + clearTimeout(copyItemFeedbackTimeout); + copyItemFeedbackTimeout = setTimeout(() => { + setConfirmedCopyItemId(null); + }, FEEDBACK_DURATION_MS); + }} + onKeyDown={(event) => { + if ( + event.code === "Space" && + event.currentTarget === event.target + ) { + event.preventDefault(); + event.stopPropagation(); + props.onSelectItem?.(historyItem()); + } + }} + onMouseEnter={(event) => { + if (!props.disconnectedItemIds?.has(historyItem().id)) { + props.onItemHover?.(historyItem().id); + } + updateHighlight(event.currentTarget); + }} + onMouseLeave={() => { + props.onItemHover?.(null); + clearHighlight(); + }} + onFocus={(event) => updateHighlight(event.currentTarget)} + onBlur={clearHighlight} + > + + + {getHistoryItemDisplayName(historyItem())} - - - - - {formatRelativeTime(item.timestamp)} + + + {historyItem().commentText} + + - - -
- )} +
+ ); + }}
diff --git a/packages/react-grab/src/components/overlay-canvas.tsx b/packages/react-grab/src/components/overlay-canvas.tsx index 462a8f726..c63ab4bd5 100644 --- a/packages/react-grab/src/components/overlay-canvas.tsx +++ b/packages/react-grab/src/components/overlay-canvas.tsx @@ -1,4 +1,4 @@ -import { createEffect, onCleanup, onMount, on } from "solid-js"; +import { createEffect, onSettled } from "solid-js"; import type { Component } from "solid-js"; import type { OverlayBounds, @@ -492,202 +492,192 @@ export const OverlayCanvas: Component = (props) => { }; createEffect( - on( - () => - [ - props.selectionVisible, - props.selectionBounds, - props.selectionBoundsMultiple, - props.selectionIsFading, - props.selectionShouldSnap, - ] as const, - ([isVisible, singleBounds, multipleBounds, , shouldSnap]) => { - if ( - !isVisible || - (!singleBounds && (!multipleBounds || multipleBounds.length === 0)) - ) { - selectionAnimations = []; - scheduleAnimationFrame(); - return; - } - - const boundsToRender = - multipleBounds && multipleBounds.length > 0 - ? multipleBounds - : singleBounds - ? [singleBounds] - : []; + () => + [ + props.selectionVisible, + props.selectionBounds, + props.selectionBoundsMultiple, + props.selectionIsFading, + props.selectionShouldSnap, + ] as const, + ([isVisible, singleBounds, multipleBounds, , shouldSnap]) => { + if ( + !isVisible || + (!singleBounds && (!multipleBounds || multipleBounds.length === 0)) + ) { + selectionAnimations = []; + scheduleAnimationFrame(); + return; + } - selectionAnimations = boundsToRender.map((bounds, index) => { - const animationId = `selection-${index}`; - const existingAnimation = selectionAnimations.find( - (animation) => animation.id === animationId, - ); + const boundsToRender = + multipleBounds && multipleBounds.length > 0 + ? multipleBounds + : singleBounds + ? [singleBounds] + : []; + + selectionAnimations = boundsToRender.map((bounds, index) => { + const animationId = `selection-${index}`; + const existingAnimation = selectionAnimations.find( + (animation) => animation.id === animationId, + ); - if (existingAnimation) { - updateAnimationTarget(existingAnimation, bounds); - if (shouldSnap) { - existingAnimation.current = { ...existingAnimation.target }; - } - return existingAnimation; + if (existingAnimation) { + updateAnimationTarget(existingAnimation, bounds); + if (shouldSnap) { + existingAnimation.current = { ...existingAnimation.target }; } + return existingAnimation; + } - return createAnimatedBounds(animationId, bounds); - }); + return createAnimatedBounds(animationId, bounds); + }); - scheduleAnimationFrame(); - }, - ), + scheduleAnimationFrame(); + }, ); createEffect( - on( - () => [props.dragVisible, props.dragBounds] as const, - ([isVisible, bounds]) => { - if (!isVisible || !bounds) { - dragAnimation = null; - scheduleAnimationFrame(); - return; - } + () => [props.dragVisible, props.dragBounds] as const, + ([isVisible, bounds]) => { + if (!isVisible || !bounds) { + dragAnimation = null; + scheduleAnimationFrame(); + return; + } - if (dragAnimation) { - updateAnimationTarget(dragAnimation, bounds); - } else { - dragAnimation = createAnimatedBounds("drag", bounds); - } + if (dragAnimation) { + updateAnimationTarget(dragAnimation, bounds); + } else { + dragAnimation = createAnimatedBounds("drag", bounds); + } - scheduleAnimationFrame(); - }, - ), + scheduleAnimationFrame(); + }, ); createEffect( - on( - () => props.grabbedBoxes, - (grabbedBoxes) => { - const boxesToProcess = grabbedBoxes ?? []; - const activeBoxIds = new Set(boxesToProcess.map((box) => box.id)); - const existingAnimationIds = new Set( - grabbedAnimations.map((animation) => animation.id), - ); + () => props.grabbedBoxes, + (grabbedBoxes) => { + const boxesToProcess = grabbedBoxes ?? []; + const activeBoxIds = new Set(boxesToProcess.map((box) => box.id)); + const existingAnimationIds = new Set( + grabbedAnimations.map((animation) => animation.id), + ); - for (const box of boxesToProcess) { - if (!existingAnimationIds.has(box.id)) { - grabbedAnimations.push( - createAnimatedBounds(box.id, box.bounds, { - createdAt: box.createdAt, - }), - ); - } + for (const box of boxesToProcess) { + if (!existingAnimationIds.has(box.id)) { + grabbedAnimations.push( + createAnimatedBounds(box.id, box.bounds, { + createdAt: box.createdAt, + }), + ); } + } - for (const animation of grabbedAnimations) { - const matchingBox = boxesToProcess.find( - (box) => box.id === animation.id, - ); - if (matchingBox) { - updateAnimationTarget(animation, matchingBox.bounds); - } + for (const animation of grabbedAnimations) { + const matchingBox = boxesToProcess.find( + (box) => box.id === animation.id, + ); + if (matchingBox) { + updateAnimationTarget(animation, matchingBox.bounds); } + } - grabbedAnimations = grabbedAnimations.filter((animation) => { - if (animation.id.startsWith("label-")) { - return true; - } - return activeBoxIds.has(animation.id); - }); + grabbedAnimations = grabbedAnimations.filter((animation) => { + if (animation.id.startsWith("label-")) { + return true; + } + return activeBoxIds.has(animation.id); + }); - scheduleAnimationFrame(); - }, - ), + scheduleAnimationFrame(); + }, ); createEffect( - on( - () => props.agentSessions, - (agentSessions) => { - if (!agentSessions || agentSessions.size === 0) { - processingAnimations = []; - scheduleAnimationFrame(); - return; - } + () => props.agentSessions, + (agentSessions) => { + if (!agentSessions || agentSessions.size === 0) { + processingAnimations = []; + scheduleAnimationFrame(); + return; + } - const updatedAnimations: AnimatedBounds[] = []; + const updatedAnimations: AnimatedBounds[] = []; - for (const [sessionId, session] of agentSessions) { - for (let index = 0; index < session.selectionBounds.length; index++) { - const bounds = session.selectionBounds[index]; - const animationId = `processing-${sessionId}-${index}`; - const existingAnimation = processingAnimations.find( - (animation) => animation.id === animationId, - ); + for (const [sessionId, session] of agentSessions) { + for (let index = 0; index < session.selectionBounds.length; index++) { + const bounds = session.selectionBounds[index]; + const animationId = `processing-${sessionId}-${index}`; + const existingAnimation = processingAnimations.find( + (animation) => animation.id === animationId, + ); - if (existingAnimation) { - updateAnimationTarget(existingAnimation, bounds); - updatedAnimations.push(existingAnimation); - } else { - updatedAnimations.push(createAnimatedBounds(animationId, bounds)); - } + if (existingAnimation) { + updateAnimationTarget(existingAnimation, bounds); + updatedAnimations.push(existingAnimation); + } else { + updatedAnimations.push(createAnimatedBounds(animationId, bounds)); } } + } - processingAnimations = updatedAnimations; - scheduleAnimationFrame(); - }, - ), + processingAnimations = updatedAnimations; + scheduleAnimationFrame(); + }, ); createEffect( - on( - () => props.labelInstances, - (labelInstances) => { - const instancesToProcess = labelInstances ?? []; - - for (const instance of instancesToProcess) { - const boundsToRender = resolveBoundsArray(instance); - const targetOpacity = instance.status === "fading" ? 0 : 1; - - for (let index = 0; index < boundsToRender.length; index++) { - const bounds = boundsToRender[index]; - const animationId = `label-${instance.id}-${index}`; - const existingAnimation = grabbedAnimations.find( - (animation) => animation.id === animationId, - ); + () => props.labelInstances, + (labelInstances) => { + const instancesToProcess = labelInstances ?? []; + + for (const instance of instancesToProcess) { + const boundsToRender = resolveBoundsArray(instance); + const targetOpacity = instance.status === "fading" ? 0 : 1; + + for (let index = 0; index < boundsToRender.length; index++) { + const bounds = boundsToRender[index]; + const animationId = `label-${instance.id}-${index}`; + const existingAnimation = grabbedAnimations.find( + (animation) => animation.id === animationId, + ); - if (existingAnimation) { - updateAnimationTarget(existingAnimation, bounds, targetOpacity); - } else { - grabbedAnimations.push( - createAnimatedBounds(animationId, bounds, { - opacity: 1, - targetOpacity, - }), - ); - } + if (existingAnimation) { + updateAnimationTarget(existingAnimation, bounds, targetOpacity); + } else { + grabbedAnimations.push( + createAnimatedBounds(animationId, bounds, { + opacity: 1, + targetOpacity, + }), + ); } } + } - const activeLabelIds = new Set(); - for (const instance of instancesToProcess) { - const boundsToRender = resolveBoundsArray(instance); - for (let index = 0; index < boundsToRender.length; index++) { - activeLabelIds.add(`label-${instance.id}-${index}`); - } + const activeLabelIds = new Set(); + for (const instance of instancesToProcess) { + const boundsToRender = resolveBoundsArray(instance); + for (let index = 0; index < boundsToRender.length; index++) { + activeLabelIds.add(`label-${instance.id}-${index}`); } + } - grabbedAnimations = grabbedAnimations.filter((animation) => { - if (animation.id.startsWith("label-")) { - return activeLabelIds.has(animation.id); - } - return true; - }); + grabbedAnimations = grabbedAnimations.filter((animation) => { + if (animation.id.startsWith("label-")) { + return activeLabelIds.has(animation.id); + } + return true; + }); - scheduleAnimationFrame(); - }, - ), + scheduleAnimationFrame(); + }, ); - onMount(() => { + onSettled(() => { initializeCanvas(); scheduleAnimationFrame(); @@ -724,7 +714,7 @@ export const OverlayCanvas: Component = (props) => { setupDprMediaQuery(); - onCleanup(() => { + return () => { window.removeEventListener("resize", handleWindowResize); if (currentDprMediaQuery) { currentDprMediaQuery.removeEventListener( @@ -735,7 +725,7 @@ export const OverlayCanvas: Component = (props) => { if (animationFrameId !== null) { nativeCancelAnimationFrame(animationFrameId); } - }); + }; }); return ( diff --git a/packages/react-grab/src/components/renderer.tsx b/packages/react-grab/src/components/renderer.tsx index 781e3889d..017c7fa49 100644 --- a/packages/react-grab/src/components/renderer.tsx +++ b/packages/react-grab/src/components/renderer.tsx @@ -1,4 +1,4 @@ -import { Show, Index } from "solid-js"; +import { Show, For } from "solid-js"; import type { Component } from "solid-js"; import type { AgentSession, ReactGrabRendererProps } from "../types.js"; import { @@ -64,10 +64,11 @@ export const ReactGrabRenderer: Component = (props) => { }} /> - {(session) => ( 0}> @@ -116,7 +117,7 @@ export const ReactGrabRenderer: Component = (props) => { /> )} - + = (props) => { /> - + {(instance) => ( = (props) => { } /> )} - + = ( return activeMenuButton ?? undefined; }; - createEffect(() => { - void props.items; - didPointerMove = false; - }); + createEffect( + () => props.items, + () => { + didPointerMove = false; + }, + ); - createEffect(() => { - const activeMenuItem = getMenuItemByIndex(props.activeIndex); - if (activeMenuItem) { - updateHighlight(activeMenuItem); - } - }); + createEffect( + () => props.activeIndex, + (activeIndex) => { + const activeMenuItem = getMenuItemByIndex(activeIndex); + if (activeMenuItem) { + updateHighlight(activeMenuItem); + } + }, + ); return ( @@ -62,47 +67,52 @@ export const ArrowNavigationMenu: Component = ( class="pointer-events-none absolute bg-black/5 opacity-0 transition-[top,left,width,height,opacity] duration-75 ease-out" /> - {(item, itemIndex) => ( - - )} + + + {navItem().componentName} + . + + {navItem().tagName} + + + ); + }} diff --git a/packages/react-grab/src/components/selection-label/completion-view.tsx b/packages/react-grab/src/components/selection-label/completion-view.tsx index a1f30a5cb..c2b2e9f55 100644 --- a/packages/react-grab/src/components/selection-label/completion-view.tsx +++ b/packages/react-grab/src/components/selection-label/completion-view.tsx @@ -1,4 +1,4 @@ -import { Show, createSignal, onMount, onCleanup } from "solid-js"; +import { Show, createSignal, onSettled } from "solid-js"; import type { Component } from "solid-js"; import type { CompletionViewProps } from "../../types.js"; import { @@ -142,20 +142,20 @@ export const CompletionView: Component = (props) => { confirmationFocusManager.claim(instanceId); }; - onMount(() => { + onSettled(() => { confirmationFocusManager.claim(instanceId); window.addEventListener("keydown", handleKeyDown, { capture: true }); if (props.supportsFollowUp && props.onFollowUpSubmit && inputRef) { inputRef.focus(); } - }); - onCleanup(() => { - confirmationFocusManager.release(instanceId); - window.removeEventListener("keydown", handleKeyDown, { capture: true }); - if (fadeTimeoutId !== undefined) window.clearTimeout(fadeTimeoutId); - if (dismissTimeoutId !== undefined) window.clearTimeout(dismissTimeoutId); + return () => { + confirmationFocusManager.release(instanceId); + window.removeEventListener("keydown", handleKeyDown, { capture: true }); + if (fadeTimeoutId !== undefined) window.clearTimeout(fadeTimeoutId); + if (dismissTimeoutId !== undefined) window.clearTimeout(dismissTimeoutId); + }; }); return ( diff --git a/packages/react-grab/src/components/selection-label/discard-prompt.tsx b/packages/react-grab/src/components/selection-label/discard-prompt.tsx index 43db71203..e94848203 100644 --- a/packages/react-grab/src/components/selection-label/discard-prompt.tsx +++ b/packages/react-grab/src/components/selection-label/discard-prompt.tsx @@ -1,4 +1,4 @@ -import { onMount, onCleanup } from "solid-js"; +import { onSettled } from "solid-js"; import type { Component } from "solid-js"; import type { DiscardPromptProps } from "../../types.js"; import { confirmationFocusManager } from "../../utils/confirmation-focus-manager.js"; @@ -30,14 +30,13 @@ export const DiscardPrompt: Component = (props) => { confirmationFocusManager.claim(instanceId); }; - onMount(() => { + onSettled(() => { confirmationFocusManager.claim(instanceId); window.addEventListener("keydown", handleKeyDown, { capture: true }); - }); - - onCleanup(() => { - confirmationFocusManager.release(instanceId); - window.removeEventListener("keydown", handleKeyDown, { capture: true }); + return () => { + confirmationFocusManager.release(instanceId); + window.removeEventListener("keydown", handleKeyDown, { capture: true }); + }; }); return ( diff --git a/packages/react-grab/src/components/selection-label/error-view.tsx b/packages/react-grab/src/components/selection-label/error-view.tsx index 3dea9d749..1e56467fd 100644 --- a/packages/react-grab/src/components/selection-label/error-view.tsx +++ b/packages/react-grab/src/components/selection-label/error-view.tsx @@ -1,4 +1,4 @@ -import { onMount, onCleanup, Show } from "solid-js"; +import { onSettled, Show } from "solid-js"; import type { Component } from "solid-js"; import type { ErrorViewProps } from "../../types.js"; import { confirmationFocusManager } from "../../utils/confirmation-focus-manager.js"; @@ -31,14 +31,13 @@ export const ErrorView: Component = (props) => { confirmationFocusManager.claim(instanceId); }; - onMount(() => { + onSettled(() => { confirmationFocusManager.claim(instanceId); window.addEventListener("keydown", handleKeyDown, { capture: true }); - }); - - onCleanup(() => { - confirmationFocusManager.release(instanceId); - window.removeEventListener("keydown", handleKeyDown, { capture: true }); + return () => { + confirmationFocusManager.release(instanceId); + window.removeEventListener("keydown", handleKeyDown, { capture: true }); + }; }); const hasActions = () => Boolean(props.onRetry || props.onAcknowledge); @@ -51,8 +50,10 @@ export const ErrorView: Component = (props) => { onClick={handleFocus} >
= (props) => { } }; - onMount(() => { + onSettled(() => { resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { const rect = entry.target.getBoundingClientRect(); @@ -157,36 +155,42 @@ export const SelectionLabel: Component = (props) => { window.visualViewport?.addEventListener("resize", handleViewportChange); window.visualViewport?.addEventListener("scroll", handleViewportChange); window.addEventListener("keydown", handleGlobalKeyDown, { capture: true }); - }); - - onCleanup(() => { - resizeObserver?.disconnect(); - window.removeEventListener("scroll", handleViewportChange, true); - window.removeEventListener("resize", handleViewportChange); - window.visualViewport?.removeEventListener("resize", handleViewportChange); - window.visualViewport?.removeEventListener("scroll", handleViewportChange); - window.removeEventListener("keydown", handleGlobalKeyDown, { - capture: true, - }); + return () => { + resizeObserver?.disconnect(); + window.removeEventListener("scroll", handleViewportChange, true); + window.removeEventListener("resize", handleViewportChange); + window.visualViewport?.removeEventListener( + "resize", + handleViewportChange, + ); + window.visualViewport?.removeEventListener( + "scroll", + handleViewportChange, + ); + window.removeEventListener("keydown", handleGlobalKeyDown, { + capture: true, + }); + }; }); const elementIdentity = () => `${props.tagName ?? ""}:${props.componentName ?? ""}`; - createEffect(() => { - if (props.isPromptMode && inputRef && props.onSubmit) { - // HACK: Defer focus one tick so the textarea is fully mounted. - const focusTimeout = setTimeout(() => { - if (inputRef) { - inputRef.focus(); - autoResizeTextarea(inputRef, TEXTAREA_MAX_HEIGHT_PX); - } - }, 0); - onCleanup(() => { - clearTimeout(focusTimeout); - }); - } - }); + createEffect( + () => [props.isPromptMode, Boolean(props.onSubmit)] as const, + ([isPromptMode, hasSubmit]) => { + if (isPromptMode && inputRef && hasSubmit) { + // HACK: Defer focus one tick so the textarea is fully mounted. + const focusTimeout = setTimeout(() => { + if (inputRef) { + inputRef.focus(); + autoResizeTextarea(inputRef, TEXTAREA_MAX_HEIGHT_PX); + } + }, 0); + return () => clearTimeout(focusTimeout); + } + }, + ); const positionComputation = createMemo( (previousResult: PositionResult): PositionResult => { @@ -324,11 +328,12 @@ export const SelectionLabel: Component = (props) => { const hadValidBounds = () => positionComputation().hadValidBounds; createEffect( - on( - () => props.selectionLabelShakeCount, - () => setIsShaking(true), - { defer: true }, - ), + () => props.selectionLabelShakeCount, + () => { + setIsShaking(true); + }, + undefined, + { defer: true }, ); const handleKeyDown = (event: KeyboardEvent) => { @@ -460,10 +465,12 @@ export const SelectionLabel: Component = (props) => { >
@@ -518,15 +525,19 @@ export const SelectionLabel: Component = (props) => {
= (props) => {
- {(item, itemIndex) => ( -
- - {item.label} - - - - {formatShortcut(item.shortcut!)} + {(itemAccessor, itemIndex) => { + const cycleItem = () => itemAccessor(); + return ( +
+ + {cycleItem().label} - -
- )} + + + {formatShortcut(cycleItem().shortcut!)} + + +
+ ); + }}
@@ -633,7 +650,7 @@ export const SelectionLabel: Component = (props) => { onKeyDown={handleKeyDown} placeholder="Add context" rows={1} - readOnly={!props.onSubmit} + readonly={!props.onSubmit} />
@@ -3158,19 +3163,22 @@ const DesignSystemGrid = () => { Selection Label
- {(state) => ( - getBoundsForCell(state.id)} - registerCell={(element) => registerCell(state.id, element)} - onRefresh={createRefreshHandler(state.id)} - getTargetDisplayText={() => getTargetDisplayText(state)} - isStarred={isStarred(state.id)} - onToggleStar={() => handleToggleStar(state.id)} - isScrambled={isScrambled()} - /> - )} + {(stateAccessor) => { + const state = stateAccessor(); + return ( + getBoundsForCell(state.id)} + registerCell={(element) => registerCell(state.id, element)} + onRefresh={createRefreshHandler(state.id)} + getTargetDisplayText={() => getTargetDisplayText(state)} + isStarred={isStarred(state.id)} + onToggleStar={() => handleToggleStar(state.id)} + isScrambled={isScrambled()} + /> + ); + }}
@@ -3182,19 +3190,22 @@ const DesignSystemGrid = () => { Context Menu (Right-Click)
- {(state) => ( - getBoundsForCell(state.id)} - registerCell={(element) => registerCell(state.id, element)} - onRefresh={createRefreshHandler(state.id)} - getTargetDisplayText={() => getTargetDisplayText(state)} - isStarred={isStarred(state.id)} - onToggleStar={() => handleToggleStar(state.id)} - isScrambled={isScrambled()} - /> - )} + {(stateAccessor) => { + const state = stateAccessor(); + return ( + getBoundsForCell(state.id)} + registerCell={(element) => registerCell(state.id, element)} + onRefresh={createRefreshHandler(state.id)} + getTargetDisplayText={() => getTargetDisplayText(state)} + isStarred={isStarred(state.id)} + onToggleStar={() => handleToggleStar(state.id)} + isScrambled={isScrambled()} + /> + ); + }}
@@ -3206,19 +3217,22 @@ const DesignSystemGrid = () => { Toolbar
- {(state) => ( - getBoundsForCell(state.id)} - registerCell={(element) => registerCell(state.id, element)} - onRefresh={createRefreshHandler(state.id)} - getTargetDisplayText={() => getTargetDisplayText(state)} - isStarred={isStarred(state.id)} - onToggleStar={() => handleToggleStar(state.id)} - isScrambled={isScrambled()} - /> - )} + {(stateAccessor) => { + const state = stateAccessor(); + return ( + getBoundsForCell(state.id)} + registerCell={(element) => registerCell(state.id, element)} + onRefresh={createRefreshHandler(state.id)} + getTargetDisplayText={() => getTargetDisplayText(state)} + isStarred={isStarred(state.id)} + onToggleStar={() => handleToggleStar(state.id)} + isScrambled={isScrambled()} + /> + ); + }}
@@ -3230,19 +3244,22 @@ const DesignSystemGrid = () => { History Dropdown
- {(state) => ( - getBoundsForCell(state.id)} - registerCell={(element) => registerCell(state.id, element)} - onRefresh={createRefreshHandler(state.id)} - getTargetDisplayText={() => getTargetDisplayText(state)} - isStarred={isStarred(state.id)} - onToggleStar={() => handleToggleStar(state.id)} - isScrambled={isScrambled()} - /> - )} + {(stateAccessor) => { + const state = stateAccessor(); + return ( + getBoundsForCell(state.id)} + registerCell={(element) => registerCell(state.id, element)} + onRefresh={createRefreshHandler(state.id)} + getTargetDisplayText={() => getTargetDisplayText(state)} + isStarred={isStarred(state.id)} + onToggleStar={() => handleToggleStar(state.id)} + isScrambled={isScrambled()} + /> + ); + }}
@@ -3254,19 +3271,22 @@ const DesignSystemGrid = () => { Agent States
- {(state) => ( - getBoundsForCell(state.id)} - registerCell={(element) => registerCell(state.id, element)} - onRefresh={createRefreshHandler(state.id)} - getTargetDisplayText={() => getTargetDisplayText(state)} - isStarred={isStarred(state.id)} - onToggleStar={() => handleToggleStar(state.id)} - isScrambled={isScrambled()} - /> - )} + {(stateAccessor) => { + const state = stateAccessor(); + return ( + getBoundsForCell(state.id)} + registerCell={(element) => registerCell(state.id, element)} + onRefresh={createRefreshHandler(state.id)} + getTargetDisplayText={() => getTargetDisplayText(state)} + isStarred={isStarred(state.id)} + onToggleStar={() => handleToggleStar(state.id)} + isScrambled={isScrambled()} + /> + ); + }}
diff --git a/packages/design-system/tsup.config.ts b/packages/design-system/tsup.config.ts index 61f01b870..97fd2b1fd 100644 --- a/packages/design-system/tsup.config.ts +++ b/packages/design-system/tsup.config.ts @@ -13,7 +13,7 @@ const options: Options = { ".css": "text", }, minify: process.env.NODE_ENV === "production", - noExternal: ["solid-js", /^react-grab\/src/, "react-grab/dist/styles.css"], + noExternal: ["solid-js", "@solidjs/web", /^react-grab\/src/, "react-grab/dist/styles.css"], outDir: "./dist", platform: "browser", sourcemap: false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 553bb5c02..7d9dd3dfd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -60,12 +60,15 @@ importers: packages/design-system: dependencies: + '@solidjs/web': + specifier: 2.0.0-beta.3 + version: 2.0.0-beta.3(@solidjs/signals@0.13.3)(solid-js@2.0.0-beta.3) react-grab: specifier: workspace:* version: link:../react-grab solid-js: - specifier: ^1.9.10 - version: 1.9.10 + specifier: 2.0.0-beta.3 + version: 2.0.0-beta.3 devDependencies: '@babel/core': specifier: ^7.28.5 @@ -74,8 +77,8 @@ importers: specifier: ^7.28.5 version: 7.28.5(@babel/core@7.28.5) babel-preset-solid: - specifier: ^1.9.10 - version: 1.9.10(@babel/core@7.28.5)(solid-js@1.9.10) + specifier: 2.0.0-beta.3 + version: 2.0.0-beta.3(@babel/core@7.28.5)(solid-js@2.0.0-beta.3) esbuild-plugin-babel: specifier: ^0.2.3 version: 0.2.3(@babel/core@7.28.5) @@ -795,10 +798,6 @@ packages: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.27.1': - resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} - engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} @@ -878,10 +877,6 @@ packages: resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} - engines: {node: '>=6.9.0'} - '@babel/types@7.28.5': resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} @@ -2990,8 +2985,8 @@ packages: resolution: {integrity: sha512-y9/ltK2TY+0HD1H2Sz7MvU3zFh4SjER6eQVNQfBx/0gK9N7S0QwHW6cmhHLx3CP25zN190LKHXPieMGqsVvrOQ==} engines: {node: '>=18'} - '@sourcegraph/amp@0.0.1773907698-g6757dd': - resolution: {integrity: sha512-yCY1M8D42FBRdq3MwNHHmrKngH/nNKOWRHLgBehR9gt3w7cv9BaD2cPA/+eQgjcNMCpL7w7YcGGkXapOc1EiqA==} + '@sourcegraph/amp@0.0.1773950853-g6caa21': + resolution: {integrity: sha512-GJ463ale5AMrf6jPSYrtq4ewvSPqMBlLF16YQfTDivLs0mTgZspRW2uNAEq0YDy50GcGTeUakMsuUb6ZBaATfw==} engines: {node: '>=20'} hasBin: true @@ -3792,11 +3787,6 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - babel-plugin-jsx-dom-expressions@0.40.3: - resolution: {integrity: sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w==} - peerDependencies: - '@babel/core': ^7.20.12 - babel-plugin-jsx-dom-expressions@0.41.0-next.11: resolution: {integrity: sha512-m0yus4+XLNENjhpJNtZtjHXQLPepT3y0bmgAeceoSOgKGKeGfE8A6fOoObUHpz+mRd25dn4wJHa6wqO4JvQMWQ==} peerDependencies: @@ -3805,15 +3795,6 @@ packages: babel-plugin-react-compiler@1.0.0: resolution: {integrity: sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==} - babel-preset-solid@1.9.10: - resolution: {integrity: sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ==} - peerDependencies: - '@babel/core': ^7.0.0 - solid-js: ^1.9.10 - peerDependenciesMeta: - solid-js: - optional: true - babel-preset-solid@2.0.0-beta.3: resolution: {integrity: sha512-hV8Gi0Akolju1ydXNZNmt/SWcvGSWX5mqg+HHQFU2/iz22MDMflRSJrhaqrmN0gxJin9s3A/x3A20HqmcGhkBg==} peerDependencies: @@ -6325,22 +6306,12 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} - seroval-plugins@1.3.3: - resolution: {integrity: sha512-16OL3NnUBw8JG1jBLUoZJsLnQq0n5Ua6aHalhJK4fMQkz1lqR7Osz1sA30trBtd9VUDc2NgkuRCn8+/pBwqZ+w==} - engines: {node: '>=10'} - peerDependencies: - seroval: ^1.0 - seroval-plugins@1.5.1: resolution: {integrity: sha512-4FbuZ/TMl02sqv0RTFexu0SP6V+ywaIe5bAWCCEik0fk17BhALgwvUDVF7e3Uvf9pxmwCEJsRPmlkUE6HdzLAw==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 - seroval@1.3.2: - resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==} - engines: {node: '>=10'} - seroval@1.5.1: resolution: {integrity: sha512-OwrZRZAfhHww0WEnKHDY8OM0U/Qs8OTfIDWhUD4BLpNJUfXK4cGmjiagGze086m+mhI+V2nD0gfbHEnJjb9STA==} engines: {node: '>=10'} @@ -6433,9 +6404,6 @@ packages: resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} engines: {node: '>= 18'} - solid-js@1.9.10: - resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==} - solid-js@2.0.0-beta.3: resolution: {integrity: sha512-s2UT66v1UpmM1QybhNrQlJUiSG1HYl2TM7ah2d0TETy5U4fLxIYbyVECB3YOw7GwOTzaGjjJjlg4A7hkYqCQ+g==} @@ -7364,7 +7332,7 @@ snapshots: '@babel/helper-module-imports@7.18.6': dependencies: - '@babel/types': 7.28.5 + '@babel/types': 7.29.0 '@babel/helper-module-imports@7.27.1': dependencies: @@ -7406,8 +7374,6 @@ snapshots: '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-option@7.27.1': {} @@ -7495,11 +7461,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.28.4': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.28.5': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -9209,10 +9170,10 @@ snapshots: '@sourcegraph/amp-sdk@0.1.0-20251210081226-g90e3892': dependencies: - '@sourcegraph/amp': 0.0.1773907698-g6757dd + '@sourcegraph/amp': 0.0.1773950853-g6caa21 zod: 3.25.76 - '@sourcegraph/amp@0.0.1773907698-g6757dd': + '@sourcegraph/amp@0.0.1773950853-g6caa21': dependencies: '@napi-rs/keyring': 1.1.9 @@ -9970,15 +9931,6 @@ snapshots: axobject-query@4.1.0: {} - babel-plugin-jsx-dom-expressions@0.40.3(@babel/core@7.28.5): - dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.18.6 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/types': 7.28.4 - html-entities: 2.3.3 - parse5: 7.3.0 - babel-plugin-jsx-dom-expressions@0.41.0-next.11(@babel/core@7.28.5): dependencies: '@babel/core': 7.28.5 @@ -9994,13 +9946,6 @@ snapshots: '@babel/types': 7.29.0 optional: true - babel-preset-solid@1.9.10(@babel/core@7.28.5)(solid-js@1.9.10): - dependencies: - '@babel/core': 7.28.5 - babel-plugin-jsx-dom-expressions: 0.40.3(@babel/core@7.28.5) - optionalDependencies: - solid-js: 1.9.10 - babel-preset-solid@2.0.0-beta.3(@babel/core@7.28.5)(solid-js@2.0.0-beta.3): dependencies: '@babel/core': 7.28.5 @@ -10743,8 +10688,8 @@ snapshots: '@typescript-eslint/parser': 8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) eslint: 9.37.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.37.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.37.0(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.37.0(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.37.0(jiti@2.6.1)) eslint-plugin-react-hooks: 5.2.0(eslint@9.37.0(jiti@2.6.1)) @@ -10760,8 +10705,8 @@ snapshots: '@next/eslint-plugin-next': 16.0.7 eslint: 9.37.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.37.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.37.0(jiti@2.6.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.37.0(jiti@2.6.1)) eslint-plugin-react: 7.37.5(eslint@9.37.0(jiti@2.6.1)) eslint-plugin-react-hooks: 7.0.1(eslint@9.37.0(jiti@2.6.1)) @@ -10783,7 +10728,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.37.0(jiti@2.6.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -10794,22 +10739,22 @@ snapshots: tinyglobby: 0.2.15 unrs-resolver: 1.11.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.37.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.37.0(jiti@2.6.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3) eslint: 9.37.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.37.0(jiti@2.6.1)) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.37.0(jiti@2.6.1)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -10820,7 +10765,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.37.0(jiti@2.6.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)))(eslint@9.37.0(jiti@2.6.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.37.0(jiti@2.6.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -12799,16 +12744,10 @@ snapshots: transitivePeerDependencies: - supports-color - seroval-plugins@1.3.3(seroval@1.3.2): - dependencies: - seroval: 1.3.2 - seroval-plugins@1.5.1(seroval@1.5.1): dependencies: seroval: 1.5.1 - seroval@1.3.2: {} - seroval@1.5.1: {} serve-static@2.2.1: @@ -12944,12 +12883,6 @@ snapshots: smol-toml@1.6.0: {} - solid-js@1.9.10: - dependencies: - csstype: 3.2.3 - seroval: 1.3.2 - seroval-plugins: 1.3.3(seroval@1.3.2) - solid-js@2.0.0-beta.3: dependencies: '@solidjs/signals': 0.13.3