Skip to content

v4.0.0#610

Open
jthrilly wants to merge 2733 commits into
mainfrom
next
Open

v4.0.0#610
jthrilly wants to merge 2733 commits into
mainfrom
next

Conversation

@jthrilly
Copy link
Copy Markdown
Member

@jthrilly jthrilly commented Feb 9, 2026

Significant release!

  • New form system
  • Schema 8
    • Geospatial interface
    • Anonymisation interface
    • Multi-select dyad census
    • Family tree census
  • New drag and drop system
  • New dashboard UI
  • Multi-user capability
  • Preview mode
  • React 19 and Next 16

Waiting on:

  • New form system #453
  • Implementation of same-sex relationships in family tree census
  • Upgrade to posthog based analytics
  • React 19 and Next 16 upgrade
  • Bugfixes for dashboard
  • Bugfixes for ALL interview features
  • e2e test coverage of SILOS
  • Cross browser playwright and storybook coverage
  • Two factor auth

Copilot AI review requested due to automatic review settings February 9, 2026 11:09
@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fresco-sandbox Ready Ready Preview, Comment Mar 2, 2026 8:19am
fresco-silos Ready Ready Preview, Comment Mar 2, 2026 8:19am
fresco-storybook Ready Ready Preview, Comment Mar 2, 2026 8:19am

Request Review

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 9, 2026

Deploy Preview for fresco-sandbox ready!

Name Link
🔨 Latest commit c6f5899
🔍 Latest deploy log https://app.netlify.com/projects/fresco-sandbox/deploys/698a35907e33ebf10843bf3f
😎 Deploy Preview https://deploy-preview-610--fresco-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Major v4.0.0 release update introducing a new form system, schema v8 support, preview mode, multi-user capability, and a revamped drag-and-drop/dashboard UI, alongside significant refactors and infrastructure/config updates.

Changes:

  • Added preview mode infrastructure (API routes, DB fields, auth toggle, preview interview flow).
  • Introduced new form field system (TanStack Form contexts/hooks + many new field components).
  • Reworked drag-and-drop (new lib/dnd store/hooks/utils, plus refactors in interviewer components).

Reviewed changes

Copilot reviewed 293 out of 804 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
lib/interviewer/components/Panels.js Formatting simplification for panel wrapper
lib/interviewer/components/Panel.tsx New TSX panel component with collapse/minimize/highlight logic
lib/interviewer/components/Panel.js Removed legacy Panel implementation
lib/interviewer/components/NodeBin.tsx New NodeBin using new ~/lib/dnd drop target hook
lib/interviewer/components/NodeBin.js Removed legacy NodeBin drag/drop HOC implementation
lib/interviewer/components/Node.tsx New memoized Node wrapper + MotionNode
lib/interviewer/components/Node.js Removed legacy Node implementation
lib/interviewer/components/Navigation.tsx Navigation refactor (props-driven disable state + passphrase prompt)
lib/interviewer/components/MultiNodeBucket.js Removed legacy bucket component
lib/interviewer/components/Edge.js Updated edge color selector wiring
lib/interviewer/components/DialogManager.js Redux action import refactor
lib/interviewer/components/CollapsablePrompts.js Added support for rendering children in prompts container
lib/interviewer/components/CategoricalItem.js Removed legacy categorical item implementation
lib/interviewer/components/Canvas/NodeLayout.js Updated updateNode API usage
lib/interviewer/components/Canvas/NarrativeEdgeLayout.js Minor formatting cleanup
lib/interviewer/components/Canvas/LayoutNode.js Layout node rendering tweaks (size + import ordering)
lib/interviewer/components/Canvas/EdgeLayout.js Selector refactor for codebook lookup
lib/interviewer/components/Canvas/ConvexHulls.js Selector import consolidation
lib/interviewer/components/Canvas/Canvas.js Formatting cleanup
lib/interviewer/components/BackgroundImage.js Formatting cleanup
lib/interviewer/behaviours/scrollable.js Removed legacy scrollable HOC
lib/interviewer/behaviours/DragAndDrop/useDropMonitor.js Removed legacy drop monitor hook
lib/interviewer/behaviours/DragAndDrop/store.js Store middleware updated for unserializable drag/drop values
lib/interviewer/behaviours/DragAndDrop/reducer.js Action type constants changed from Symbols to strings
lib/interviewer/behaviours/DragAndDrop/index.js Export surface adjusted
lib/interviewer/behaviours/DragAndDrop/MonitorDropTarget.js Removed legacy monitor HOC
lib/interviewer/behaviours/DragAndDrop/MonitorDragSource.js Removed legacy monitor HOC
lib/interviewer/behaviours/DragAndDrop/Monitor.js Removed legacy monitor base
lib/interviewer/behaviours/DragAndDrop/DropTarget.js Import cleanup
lib/interviewer/behaviours/DragAndDrop/DropObstacle.js Formatting + minor simplifications
lib/interviewer/behaviours/DragAndDrop/DragSource.js Defaults added for handler props
lib/interviewer/behaviours/DragAndDrop/DragPreview.js Removed eslint disable header (left blank line)
lib/interviewer/behaviours/AssetMetaProvider.js Selector import/path refactor
lib/form/utils/scrollToFirstError.ts Added helper to scroll to first form error
lib/form/utils/formContexts.ts Added TanStack Form contexts
lib/form/types.ts Added core form typing layer
lib/form/hooks/useTanStackForm.ts Added TanStack Form hook wrapper
lib/form/components/fields/utils/options.js Added option normalization helpers
lib/form/components/fields/VisualAnalogScale.js Added VAS wrapper field
lib/form/components/fields/ToggleButton.tsx Added ToggleButton field
lib/form/components/fields/Toggle.tsx Added Toggle field
lib/form/components/fields/TextArea.tsx Added TextArea field
lib/form/components/fields/Slider/index.js Added Slider barrel export
lib/form/components/fields/Slider/Track.js Added slider Track component
lib/form/components/fields/Slider/Tick.js Added slider Tick component
lib/form/components/fields/Slider/Field.js Added Slider field wrapper
lib/form/components/fields/Search.tsx Added Search field wrapper
lib/form/components/fields/RelativeDatePicker.js Added relative date picker wrapper
lib/form/components/fields/Radio.tsx Added Radio field
lib/form/components/fields/MarkdownLabel.js Added markdown label wrapper
lib/form/components/fields/Markdown.js Added markdown renderer with sanitize/raw support
lib/form/components/fields/LikertScale.js Added Likert scale wrapper
lib/form/components/fields/FieldSkeleton.tsx Added skeleton for loading states
lib/form/components/fields/DatePicker/index.js Added DatePicker barrel export
lib/form/components/fields/DatePicker/helpers.js Added DatePicker helper utilities
lib/form/components/fields/DatePicker/Panels.js Added DatePicker animated panels container
lib/form/components/fields/DatePicker/Panel.js Added DatePicker animated panel
lib/form/components/fields/DatePicker/Field.js Added DatePicker field wrapper
lib/form/components/fields/DatePicker/DatePicker/helpers.js Added DatePicker internal helpers
lib/form/components/fields/DatePicker/DatePicker/Years.js Added years range supplier
lib/form/components/fields/DatePicker/DatePicker/Months.js Added months range supplier
lib/form/components/fields/DatePicker/DatePicker/Days.js Added days range supplier
lib/form/components/fields/DatePicker/DatePicker/DatePickerContext.js Added DatePicker context
lib/form/components/fields/DatePicker/DatePicker/Date.js Added DatePicker date selector helper
lib/form/components/fields/Checkbox.js Added checkbox field component (redux-form style props)
lib/form/components/fields/Boolean.js Added boolean field component
lib/dnd/utils.ts Added DnD hit detection + raf throttle utilities
lib/dnd/types.ts Added core DnD types
lib/dnd/index.ts Added DnD public exports
lib/dnd/tests/setup.ts Added test environment setup for DnD
lib/dnd/DndStoreProvider.tsx Added Zustand-based DnD store provider + drag preview portal
lib/dialogs/useDialog.stories.tsx Added story for useDialog
lib/dialogs/Dialog.stories.tsx Added dialog stories
lib/dialogs/ControlledDialog.tsx Added controlled dialog variant
lib/dialogs/ControlledDialog.stories.tsx Added controlled dialog stories
lib/db/schema.prisma Added preview + pending protocol fields, ApiToken model, asset value
lib/db/migrations/20251204222357_add_protocol_is_pending/migration.sql Migration: add Protocol.isPending
lib/db/migrations/20251118073416_add_preview_mode_and_api_tokens/migration.sql Migration: preview mode + ApiToken + index
lib/db/migrations/20250426201139_add_protocol_experiments/migration.sql Migration: add Protocol.experiments
lib/db/migrations/20250122184616_add_asset_value/migration.sql Migration: add Asset.value + join table pk changes
lib/cache.ts Cache tags refactor + multi-tag revalidation + deployment keying
knip.json Knip config updates + Playwright wiring
jsconfig.json Added JS compilerOptions config file
hooks/usePortal.ts Made usePortal client-safe for SSR + delayed mount
hooks/useCanvas.ts Formatting cleanup
hooks/use-data-table.tsx Updated data table types import path
fresco.config.ts Added schema v8 + preview min architect version
env.js Added PREVIEW_MODE env var
docker-compose.prod.yml Updated prod compose env + ports + volumes
docker-compose.dev.yml YAML formatting cleanup
components/ui/tooltip.tsx Tailwind class ordering tweaks
components/ui/toaster.tsx Tailwind class ordering tweaks
components/ui/toast.tsx Fixed Heading import path
components/ui/table.tsx Table container styling/layout changes
components/ui/switch.tsx Tailwind class ordering tweaks
components/ui/separator.tsx Quote/style normalization
components/ui/select.tsx Tailwind class ordering tweaks
components/ui/progress.tsx Tailwind class ordering tweaks
components/ui/popover.tsx Quote/style normalization
components/ui/dialog.tsx Fixed typography import paths
components/ui/checkbox.tsx Tailwind class ordering tweaks
components/ui/card.tsx Fixed Heading import path + class changes
components/ui/badge.tsx Fixed export formatting
components/ui/Label.tsx Fixed Heading import path
components/ui/Input.tsx Tailwind class ordering tweaks
components/ui/CloseButton.tsx Made onClick optional + class ordering
components/ui/Button.tsx Updated tableHeader variant styles
components/ui/AlertDialog.tsx Fixed typography import paths
components/ui/Alert.tsx Fixed typography import paths
components/typography/Heading.tsx Minor expression parenthesization cleanup
components/layout/SettingsSection.tsx Updated Heading import path
components/layout/ResponsiveContainer.tsx Added new content base size
components/interview/ActionButton.tsx Added interview action button component
components/interview/ActionButton.stories.tsx Added ActionButton story
components/data-table/data-table.tsx Updated types import path + layout tweaks
components/data-table/data-table-toolbar.tsx Updated types import path + layout tweaks
components/data-table/data-table-skeleton.tsx Layout tweaks
components/data-table/data-table-pagination.tsx Updated pageSizes import path
components/data-table/data-table-floating-bar.tsx Minor typing + class ordering
components/data-table/data-table-faceted-filter.tsx Updated Option import path + class ordering
components/data-table/advanced/data-table-advanced-toolbar.tsx Updated types import path + wrapper removal
components/data-table/advanced/data-table-advanced-filter.tsx Updated types import path
components/VersionSection.tsx Typography import path updates + class ordering
components/Providers/index.tsx Added global Providers wrapper (Motion/Radix/Dialog/Toaster)
components/Providers/RadixDirectionProvider.tsx Added Radix direction provider
components/ProtocolImport/JobReducer.ts Added “Migrating protocol” import status
components/ProtocolImport/JobCard.tsx Typography import updates + class ordering
components/PreviewModeAuthSwitch.tsx Added switch for preview auth requirement
components/ErrorReportNotifier.tsx Class ordering tweaks
components/ErrorDetails.tsx Import ordering + class ordering tweaks
components/DynamicLucideIcon.tsx Added CMS-safe lucide icon resolver
components/DataTable/types.ts Added new activity types (API token + preview mode)
components/DataTable/DataTable.tsx Removed redundant wrapper border
components/DataTable/ColumnHeader.tsx UI tweaks for sortable headers
components/CloseButton.tsx Added new CloseButton wrapper component
components/BackgroundBlobs/Canvas.tsx Tailwind conversion for sizing
components/BackgroundBlobs/BackgroundBlobs.tsx Inlined RNG helpers (removed import)
app/not-found.tsx Typography import path updates + class ordering
app/layout.tsx Added Providers + ResponsiveContainer path change
app/global-error.tsx Typography import path updates + ResponsiveContainer path change
app/error.tsx Typography import path updates + ResponsiveContainer path change
app/dashboard/settings/loading.tsx Typography + ResponsiveContainer import path updates
app/dashboard/settings/_components/UpdateUploadThingToken.tsx Switched to generic UpdateSettingsValue API
app/dashboard/settings/_components/UpdateInstallationId.tsx Switched to generic UpdateSettingsValue API
app/dashboard/protocols/page.tsx Typography + ResponsiveContainer import path updates
app/dashboard/protocols/loading.tsx Typography + ResponsiveContainer import path updates
app/dashboard/protocols/_components/DeleteProtocolsDialog.tsx Updated Protocol type import + improved warning copy
app/dashboard/participants/page.tsx Typography + ResponsiveContainer import path updates
app/dashboard/participants/loading.tsx Typography + ResponsiveContainer import path updates
app/dashboard/participants/_components/ParticipantModal.tsx Typography import path updates
app/dashboard/participants/_components/ImportCSVModal.tsx Typography import path updates + error message change
app/dashboard/participants/_components/ExportParticipants/ImportExportSection.tsx Typography + ResponsiveContainer import updates
app/dashboard/participants/_components/ExportParticipants/GenerateParticipantURLsButton.tsx Updated types to table client exports
app/dashboard/participants/_components/ExportParticipants/ExportParticipants.tsx Added SuperJSON parsing for participants payload
app/dashboard/participants/_components/ExportParticipants/ExportCSVParticipantURLs.tsx Updated types to table client exports
app/dashboard/participants/_components/DropzoneField.tsx Typography import path updates
app/dashboard/participants/_components/DeleteParticipantsDialog.tsx Alert variant set + improved warning copy
app/dashboard/page.tsx Typography + ResponsiveContainer import path updates
app/dashboard/loading.tsx Typography + ResponsiveContainer import path updates
app/dashboard/interviews/page.tsx Typography + ResponsiveContainer import path updates
app/dashboard/interviews/loading.tsx Typography + ResponsiveContainer import path updates
app/dashboard/interviews/_components/GenerateInterviewURLs.tsx Added SuperJSON parsing for protocols payload
app/dashboard/interviews/_components/ExportOptionsView.tsx Typography import path updates
app/dashboard/interviews/_components/ExportInterviewsDialog.tsx Added SuperJSON parsing for prepared export payloads
app/dashboard/interviews/_components/ExportCSVInterviewURLs.tsx Updated protocol/interview types
app/dashboard/_components/UploadThingModal.tsx Typography import path updates
app/dashboard/_components/UpdateSettingsValue.tsx Simplified API: now uses setAppSetting by key
app/dashboard/_components/SummaryStatistics/SummaryStatistics.tsx ResponsiveContainer import path updates
app/dashboard/_components/SummaryStatistics/StatCard.tsx Typography import path updates
app/dashboard/_components/RecruitmentTestSectionServer.tsx Typography import path updates
app/dashboard/_components/RecruitmentTestSection.tsx Added SuperJSON parsing for promises
app/dashboard/_components/ProtocolsTable/ProtocolsTableClient.tsx Added SuperJSON parsing + exported ProtocolWithInterviews type
app/dashboard/_components/ProtocolsTable/ProtocolsTable.tsx Removed unstable_noStore usage
app/dashboard/_components/ProtocolsTable/Columns.tsx Updated imports + ProtocolWithInterviews type source
app/dashboard/_components/ProtocolsTable/ActionsDropdown.tsx Updated ProtocolWithInterviews type source
app/dashboard/_components/ProtocolUploader.tsx Class ordering tweaks
app/dashboard/_components/ParticipantsTable/ParticipantsTableClient.tsx Added SuperJSON parsing + exported ParticipantWithInterviews type
app/dashboard/_components/ParticipantsTable/GenerateParticipantURLButton.tsx Updated protocol types + typography import path
app/dashboard/_components/ParticipantsTable/Columns.tsx Updated protocol/participant type sources + typography import path
app/dashboard/_components/ParticipantsTable/ActionsDropdown.tsx Updated participant type source
app/dashboard/_components/NavigationBar.tsx Typography import path update + Image priority
app/dashboard/_components/InterviewsTable/InterviewsTable.tsx Added SuperJSON parsing for interviews payload
app/dashboard/_components/ActivityFeed/utils.ts Updated ActivityType type import path
app/dashboard/_components/ActivityFeed/SearchParams.ts Updated filter/sort type import path
app/dashboard/_components/ActivityFeed/ColumnDefinition.tsx Updated data-table types import path + minor cell render tweak
app/api/uploadthing/route.ts Use derived base URL for callback, tolerate missing token
app/api/test/clear-cache/route.ts Added test-only cache invalidation endpoint
app/api/preview/types.ts Added preview message exchange types
app/api/preview/helpers.ts Added preview mode auth helper + CORS response helpers
app/(interview)/preview/layout.tsx Added preview layout with small-screen overlay
app/(interview)/preview/[protocolId]/route.ts Added preview protocol gate + redirect handler
app/(interview)/preview/[protocolId]/interview/page.tsx Added preview interview page (in-memory interview construction)
app/(interview)/layout.tsx Added shared interview root layout with metadata + styles import
app/(interview)/interview/layout.tsx Simplified interview layout (moved overlay out)
app/(interview)/interview/finished/page.tsx Typography import path updates + class ordering
app/(interview)/interview/_components/SmallScreenOverlay.tsx Typography import path updates
app/(interview)/interview/_components/ServerSync.tsx Removed legacy client-side sync component
app/(interview)/interview/_components/InterviewShell.tsx Switched to SuperJSON payload + store factory + DnD provider
app/(interview)/interview/[interviewId]/sync/route.ts Added POST route to persist interview state
app/(interview)/interview/[interviewId]/page.tsx Switched to SuperJSON payload + updated finished interview guard
app/(interview)/interview/[interviewId]/layout.tsx Added per-session layout with small-screen overlay
app/(blobs)/layout.tsx Class ordering tweaks
app/(blobs)/expired/page.tsx Removed runtime redirect check + styling tweak
app/(blobs)/(setup)/setup/page.tsx Class ordering tweaks
app/(blobs)/(setup)/layout.tsx Forced dynamic rendering for DB-backed expiry check
app/(blobs)/(setup)/_components/SignInForm.tsx Typography import path updates
app/(blobs)/(setup)/_components/Sidebar.tsx Typography import path updates
app/(blobs)/(setup)/_components/OnboardSteps/UploadProtocol.tsx Typography import path updates
app/(blobs)/(setup)/_components/OnboardSteps/ManageParticipants.tsx Typography import path updates
app/(blobs)/(setup)/_components/OnboardSteps/Documentation.tsx Typography import path updates
app/(blobs)/(setup)/_components/OnboardSteps/CreateAccount.tsx Typography import path updates
app/(blobs)/(setup)/_components/OnboardSteps/ConnectUploadThing.tsx Typography import path updates
actions/uploadThing.ts Updated UploadThing helper import path
actions/reset.ts Batch tag revalidation + UploadThing helper import path update
actions/protocols.ts Protocol insert refactor (schema/typing changes)
actions/appSettings.ts App setting schema refactor + centralized getStringValue
actions/activityFeed.ts Updated activity types import path
Dockerfile Added build arg + NODE_OPTIONS change + prisma CLI install step
CLAUDE.md Documentation whitespace + “Debugging” tips section
.vscode/settings.json Editor defaults + Tailwind regex tweaks
.vscode/launch.json JSON formatting cleanup
.vscode/extensions.json JSON formatting cleanup
.storybook/preview.tsx Switched to nextjs-vite preview + Providers decorator
.storybook/preview.ts Removed old preview config
.storybook/main.ts Switched Storybook framework to @storybook/nextjs-vite
.prettierrc Added tabWidth/useTabs options
.github/workflows/docker-build-pr.yml Input to disable image optimization + renamed image
.github/workflows/chromatic.yml Added Chromatic CI workflow
.github/dependabot.yml Quote/style normalization
.github/workflows/update-snapshots.yml Removed snapshot update workflow
.github/workflows/playwright.yml Removed Playwright CI workflow
.eslintrc.cjs Removed legacy ESLint config
.serena/memories/* Removed Serena memory docs/ignores
Comments suppressed due to low confidence (1)

actions/protocols.ts:1

  • The function signature indicates protocolInsertSchema is the source of truth, but the runtime validation (protocolInsertSchema.parse(input)) was removed. This allows malformed/untrusted input to reach Prisma writes (and can cause runtime exceptions or invalid DB state). Re-introduce protocolInsertSchema.parse(input) (or safeParse with a clear error) and destructure from the parsed result.
'use server';

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/form/components/fields/Radio.tsx Outdated
Comment thread lib/form/components/fields/Checkbox.js Outdated
Comment thread components/DataTable/ColumnHeader.tsx Outdated
Comment thread docker-compose.prod.yml Outdated
Comment thread docker-compose.prod.yml Outdated
Comment thread app/layout.tsx Outdated
Comment thread actions/appSettings.ts
Comment thread actions/appSettings.ts
Comment thread app/api/[version]/preview/_handlers/v1/helpers.ts Outdated
Comment thread app/dashboard/participants/_components/ExportParticipants/ExportParticipants.tsx Outdated
Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 9, 2026

@jthrilly I've opened a new pull request, #611, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 9, 2026

@jthrilly I've opened a new pull request, #612, to work on those changes. Once the pull request is ready, I'll request review from you.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 293 out of 802 changed files in this pull request and generated 12 comments.

Comments suppressed due to low confidence (1)

app/dashboard/participants/_components/ImportCSVModal.tsx:1

  • ZodError.message is often a generic/verbose summary and may be less actionable than showing a specific issue. Consider using e.errors[0]?.message (or formatting e.errors) to surface the most relevant validation problem to the user.
'use client';

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread actions/protocols.ts
Comment thread app/api/test/clear-cache/route.ts Outdated
Comment thread docker-compose.prod.yml Outdated
Comment thread docker-compose.prod.yml Outdated
Comment thread lib/form/utils/scrollToFirstError.ts Outdated
Comment thread app/dashboard/_components/ParticipantsTable/ParticipantsTableClient.tsx Outdated
Comment thread lib/form/components/fields/Checkbox.js Outdated
Comment thread app/api/preview/types.ts Outdated
Comment thread components/DynamicLucideIcon.tsx Outdated
Comment thread app/(interview)/interview/[interviewId]/sync/route.ts
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 9, 2026

🎭 Playwright E2E Test Report

Tests failed. View the full report here:

👉 https://complexdatacollective.github.io/Fresco/

Report details

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 9, 2026

🎭 Playwright E2E Test Report

Tests failed. View the full report here:

👉 https://complexdatacollective.github.io/Fresco/

Report details

jthrilly and others added 16 commits May 12, 2026 20:22
# Conflicts:
#	.github/workflows/cleanup-e2e-reports.yml
#	.github/workflows/e2e.yml
The --sea-green CSS variable from @codaco/tailwind-config is an oklch
tuple (lightness chroma hue), not a complete color value. Using it
directly in color-mix() produced invalid colors; wrap with oklch() so
the column highlight background renders correctly.
…10.2 / alpha.19 / alpha.18

No consumer-side migrations required:
- fresco-ui's `xs` control size was removed in 2.10.2 but no usages
  exist in this repo; DialogFooter cancel-left clustering only applies
  to dialogs that use the cancel + secondary + primary trio.
- interview's CategoricalBin / AlterForm / SlidesForm changes are
  internal to the package; intro-panel spacing pass is purely visual.
- tailwind-config's static CategoricalBin grid and interview
  type-scale tweaks propagate transparently.
Removes the in-development Preview Mode feature that let Architect Web
upload protocols to Fresco for preview. This includes routes, components,
the upload API, server actions, preview AppSettings, and the
Protocol.isPreview / Protocol.isPending columns.

Since Preview Mode was only ever on the unreleased interview-package
branch, the rollback is done by removing/rewriting the original
migrations rather than adding a new one. The shared ApiToken table is
preserved (still used by the Interview Data API); its migration is
renamed to 20251118073416_add_api_tokens.

Local dev DBs that had any of the deleted preview migrations applied
will need to run prisma migrate reset before next startup.
refactor: consume @codaco/interview package, delete lib/interviewer
Returns [{id, name, importedAt, lastModified}] so external scripts can get protocol ids for constructing onboarding urls
preserve CORS on protocols-meta error paths, add Bearer challenge
Bumps every dependency (production and dev) to its latest published
version where ecosystem compatibility allows. Notable upgrades:

- next 16.2.3 -> 16.2.6, react/react-dom 19.2.5 -> 19.2.6
- @types/node ^22 -> ^25 (major)
- prisma / @prisma/* 7.7.0 -> 7.8.0
- storybook + @storybook/* 10.3.5 -> 10.4.0
- vitest / @vitest/* 4.1.4 -> 4.1.6, vite 8.0.8 -> 8.0.13
- typescript-eslint 8.58.1 -> 8.59.3, tailwindcss 4.2.4 -> 4.3.0
- knip 6.7.0 -> 6.13.1, chromatic 16.2.0 -> 16.10.0
- @aws-sdk/* 3.1038.0 -> 3.1047.0, posthog-* / lucide-react / motion / zod

eslint stays on v9.39.4: eslint-plugin-react 7.37.5 (latest available)
does not yet declare ESLint 10 support, so bumping eslint to v10 broke
the React rules with a getFilename runtime error.

Drive-by fixes required by the new toolchain:
- Cast Buffer -> Uint8Array<ArrayBuffer> when constructing the upload
  File in UploadThingFileStorage (@types/node v25 narrowed BlobPart).
- Drop redundant type assertions flagged by typescript-eslint 8.59
  (no-unnecessary-type-assertion) in a handful of files.
- Replace [scrollbar-gutter:stable_both-edges] with the canonical
  scrollbar-gutter-both class in dashboard/layout.
Drops @types/node back to ^24.12.4. v25 narrowed BlobPart and forced
a manual Uint8Array<ArrayBuffer> view in UploadThingFileStorage; v24
accepts the Buffer directly, so revert that workaround.

Also restores the `as Route` casts in RecruitmentTestSection that the
previous typescript-eslint autofix removed - they were only redundant
under v25's type resolution, v24 still requires them for Next.js's
typed Route.
typescript-eslint 8.59 flags the two `as Route` casts as unnecessary
when run without Next.js's typed-routes artifact (.next/types/routes.d.ts),
which is the state CI is always in - lint runs before any build step,
so Route resolves to its wide `string & {}` default and the cast is
genuinely redundant. After `next build` the casts become required, so
the conflict was unresolvable as written.

Rewrite to avoid the cast altogether: guard against `selectedProtocol`
being undefined (the function previously silently produced
`/onboard/undefined` URLs), and pin the return type to the explicit
template-literal union plus null. Callers null-check before navigating.
Both states - CI (no typed-routes overlay) and post-build (narrow Route
union) - now typecheck and lint cleanly.
…asts

Replace the inlined template-literal return type with `Route | null`.
In CI, where `.next/types/routes.d.ts` is never generated, Route
resolves to its wide `string & {}` default and the template literals
returned satisfy it directly - no `as Route` cast needed (typescript-
eslint 8.59 correctly flags it as redundant in that state). Keeping
the `Route` brand documents intent without duplicating Next.js's
route-type internals at every call site.
`next typegen` writes .next/types/routes.d.ts (the typedRoutes overlay)
without requiring a full `next build`. Without it, `pnpm typecheck` and
`pnpm lint` in CI see `Route` as its wide `string & {}` default, which
made typescript-eslint 8.59 flag the `as Route` casts in
RecruitmentTestSection as unnecessary - even though they're doing real
narrowing work (selectedProtocol?.id is string | undefined).

Wiring typegen into postinstall means the overlay is always present
after `pnpm install` (CI, deploy preview, fresh clones), Route is
correctly narrowed everywhere, and the original casts compile and lint
cleanly. Restores RecruitmentTestSection to its pre-update form.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Important

Review skipped

Too many files!

This PR contains 300 files, which is 150 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f918602a-095b-4612-b503-7fff2a5e8a0b

📥 Commits

Reviewing files that changed from the base of the PR and between 2942469 and 51633fa.

📒 Files selected for processing (300)
  • .claude/skills/generate-e2e-tests/SKILL.md
  • .env.example
  • .eslintrc.cjs
  • .github/dependabot.yml
  • .github/workflows/build.yml
  • .github/workflows/chromatic.yml
  • .github/workflows/deploy-storybook.yaml
  • .github/workflows/docker-build-pr.yml
  • .github/workflows/docker-publish.yml
  • .github/workflows/e2e.yml
  • .github/workflows/netlify-cleanup-preview.yml
  • .github/workflows/netlify-deploy-preview.yml
  • .github/workflows/netlify-deploy-status.yml
  • .gitignore
  • .prettierrc
  • .serena/.gitignore
  • .serena/memories/code_style_conventions.md
  • .serena/memories/codebase_structure.md
  • .serena/memories/project_overview.md
  • .serena/memories/suggested_commands.md
  • .serena/memories/task_completion_checklist.md
  • .serena/project.yml
  • .storybook/main.ts
  • .storybook/preview.ts
  • .storybook/preview.tsx
  • .storybook/tsconfig.json
  • .storybook/vite-plugin-stub-use-server.ts
  • .vscode/extensions.json
  • .vscode/launch.json
  • .vscode/settings.json
  • CLAUDE.md
  • Dockerfile
  • actions/__tests__/auth.test.ts
  • actions/__tests__/createInterview.test.ts
  • actions/__tests__/totp.test.ts
  • actions/__tests__/twoFactor.test.ts
  • actions/activityFeed.ts
  • actions/apiTokens.ts
  • actions/appSettings.ts
  • actions/auth.ts
  • actions/interviews.ts
  • actions/participants.ts
  • actions/protocols.ts
  • actions/reset.ts
  • actions/storageProvider.ts
  • actions/synthetic-interviews.ts
  • actions/totp.ts
  • actions/twoFactor.ts
  • actions/uploadThing.ts
  • actions/users.ts
  • actions/webauthn.ts
  • app/(blobs)/(setup)/_components/OnboardContinue.tsx
  • app/(blobs)/(setup)/_components/OnboardSteps/ConfigureStorage.tsx
  • app/(blobs)/(setup)/_components/OnboardSteps/ConnectUploadThing.tsx
  • app/(blobs)/(setup)/_components/OnboardSteps/CreateAccount.tsx
  • app/(blobs)/(setup)/_components/OnboardSteps/Documentation.tsx
  • app/(blobs)/(setup)/_components/OnboardSteps/ManageParticipants.tsx
  • app/(blobs)/(setup)/_components/OnboardSteps/UploadProtocol.tsx
  • app/(blobs)/(setup)/_components/S3ConfigForm.tsx
  • app/(blobs)/(setup)/_components/SandboxCredentials.tsx
  • app/(blobs)/(setup)/_components/Sidebar.tsx
  • app/(blobs)/(setup)/_components/SignInForm.tsx
  • app/(blobs)/(setup)/_components/SignUpForm.tsx
  • app/(blobs)/(setup)/_components/StorageProviderSelector.tsx
  • app/(blobs)/(setup)/_components/UploadThingTokenForm.tsx
  • app/(blobs)/(setup)/layout.tsx
  • app/(blobs)/(setup)/setup/Setup.tsx
  • app/(blobs)/(setup)/setup/page.tsx
  • app/(blobs)/(setup)/signin/page.tsx
  • app/(blobs)/expired/page.tsx
  • app/(blobs)/layout.tsx
  • app/(interview)/interview/[interviewId]/InterviewClient.tsx
  • app/(interview)/interview/[interviewId]/layout.tsx
  • app/(interview)/interview/[interviewId]/loading.tsx
  • app/(interview)/interview/[interviewId]/mapInterviewPayload.ts
  • app/(interview)/interview/[interviewId]/page.tsx
  • app/(interview)/interview/[interviewId]/sync/route.ts
  • app/(interview)/interview/_components/ErrorMessage.tsx
  • app/(interview)/interview/_components/InterviewShell.tsx
  • app/(interview)/interview/_components/ServerSync.tsx
  • app/(interview)/interview/_components/SmallScreenOverlay.tsx
  • app/(interview)/interview/finished/page.tsx
  • app/(interview)/interview/layout.tsx
  • app/(interview)/layout.tsx
  • app/(interview)/onboard/[protocolId]/__tests__/route.test.ts
  • app/(interview)/onboard/[protocolId]/route.ts
  • app/api/[version]/interview/[interviewId]/route.ts
  • app/api/[version]/interview/route.ts
  • app/api/[version]/protocols-meta/route.ts
  • app/api/_helpers/__tests__/auth.test.ts
  • app/api/_helpers/__tests__/versioning.test.ts
  • app/api/_helpers/auth.ts
  • app/api/_helpers/versioning.ts
  • app/api/analytics/route.ts
  • app/api/export-interviews/route.ts
  • app/api/generate-test-interviews/route.ts
  • app/api/health/route.ts
  • app/api/interviews/[interviewId]/finish/route.ts
  • app/api/storage/presign/route.ts
  • app/api/uploadthing/core.ts
  • app/api/uploadthing/route.ts
  • app/dashboard/_components/ActivityFeed/ActivityFeed.tsx
  • app/dashboard/_components/ActivityFeed/ActivityFeedRows.tsx
  • app/dashboard/_components/ActivityFeed/ActivityFeedTable.tsx
  • app/dashboard/_components/ActivityFeed/ActivityFeedToolbar.tsx
  • app/dashboard/_components/ActivityFeed/ColumnDefinition.tsx
  • app/dashboard/_components/ActivityFeed/SearchParams.ts
  • app/dashboard/_components/ActivityFeed/types.ts
  • app/dashboard/_components/ActivityFeed/useTableStateFromSearchParams.ts
  • app/dashboard/_components/ActivityFeed/utils.ts
  • app/dashboard/_components/AnalyticsButton.tsx
  • app/dashboard/_components/InterviewsTable/ActionsDropdown.tsx
  • app/dashboard/_components/InterviewsTable/Columns.tsx
  • app/dashboard/_components/InterviewsTable/InterviewsTable.tsx
  • app/dashboard/_components/InterviewsTable/InterviewsTableServer.tsx
  • app/dashboard/_components/InterviewsTable/NetworkSummary.tsx
  • app/dashboard/_components/MobileNavDrawer.tsx
  • app/dashboard/_components/NavigationBar.tsx
  • app/dashboard/_components/ParticipantsTable/ActionsDropdown.tsx
  • app/dashboard/_components/ParticipantsTable/Columns.tsx
  • app/dashboard/_components/ParticipantsTable/GenerateParticipantURLButton.tsx
  • app/dashboard/_components/ParticipantsTable/ParticipantsTable.tsx
  • app/dashboard/_components/ParticipantsTable/ParticipantsTableClient.tsx
  • app/dashboard/_components/ProtocolUploader.tsx
  • app/dashboard/_components/ProtocolsTable/ActionsDropdown.tsx
  • app/dashboard/_components/ProtocolsTable/AnonymousRecruitmentURLButton.tsx
  • app/dashboard/_components/ProtocolsTable/Columns.tsx
  • app/dashboard/_components/ProtocolsTable/ProtocolsTable.tsx
  • app/dashboard/_components/ProtocolsTable/ProtocolsTableClient.tsx
  • app/dashboard/_components/RecruitmentTestSection.tsx
  • app/dashboard/_components/RecruitmentTestSectionServer.tsx
  • app/dashboard/_components/ResetButton.tsx
  • app/dashboard/_components/SummaryStatistics/Icons.tsx
  • app/dashboard/_components/SummaryStatistics/StatCard.tsx
  • app/dashboard/_components/SummaryStatistics/SummaryStatistics.tsx
  • app/dashboard/_components/UpdateSettingsValue.tsx
  • app/dashboard/_components/UpdateUploadThingTokenAlert.tsx
  • app/dashboard/_components/UploadThingModal.tsx
  • app/dashboard/_components/UserMenu.tsx
  • app/dashboard/interviews/_components/DeleteInterviewsDialog.tsx
  • app/dashboard/interviews/_components/ExportCSVInterviewURLs.tsx
  • app/dashboard/interviews/_components/ExportInterviewsDialog.tsx
  • app/dashboard/interviews/_components/ExportOptionsView.tsx
  • app/dashboard/interviews/_components/GenerateInterviewURLs.tsx
  • app/dashboard/interviews/loading.tsx
  • app/dashboard/interviews/page.tsx
  • app/dashboard/layout.tsx
  • app/dashboard/loading.tsx
  • app/dashboard/page.tsx
  • app/dashboard/participants/_components/AddParticipantButton.tsx
  • app/dashboard/participants/_components/DeleteParticipantsDialog.tsx
  • app/dashboard/participants/_components/DropzoneField.tsx
  • app/dashboard/participants/_components/ExportParticipants/ExportCSVParticipantURLs.tsx
  • app/dashboard/participants/_components/ExportParticipants/ExportParticipants.tsx
  • app/dashboard/participants/_components/ExportParticipants/GenerateParticipantURLsButton.tsx
  • app/dashboard/participants/_components/ExportParticipants/ImportExportSection.tsx
  • app/dashboard/participants/_components/ImportCSVModal.tsx
  • app/dashboard/participants/_components/ImportParticipants.tsx
  • app/dashboard/participants/_components/ParticipantModal.tsx
  • app/dashboard/participants/loading.tsx
  • app/dashboard/participants/page.tsx
  • app/dashboard/protocols/_components/AnonymousRecruitmentWarning.tsx
  • app/dashboard/protocols/_components/DeleteProtocolsDialog.tsx
  • app/dashboard/protocols/loading.tsx
  • app/dashboard/protocols/page.tsx
  • app/dashboard/settings/ReadOnlyEnvAlert.tsx
  • app/dashboard/settings/_components/ApiTokensSection.tsx
  • app/dashboard/settings/_components/ConfigurationSection.tsx
  • app/dashboard/settings/_components/DeveloperToolsSection.tsx
  • app/dashboard/settings/_components/InterviewSettingsSection.tsx
  • app/dashboard/settings/_components/PasskeySettings.tsx
  • app/dashboard/settings/_components/PrivacySection.tsx
  • app/dashboard/settings/_components/StorageProviderSection.tsx
  • app/dashboard/settings/_components/SyntheticInterviewDataSection.tsx
  • app/dashboard/settings/_components/SyntheticInterviewDataServer.tsx
  • app/dashboard/settings/_components/TwoFactorSettings.tsx
  • app/dashboard/settings/_components/UpdateInstallationId.tsx
  • app/dashboard/settings/_components/UpdateS3Settings.tsx
  • app/dashboard/settings/_components/UpdateUploadThingToken.tsx
  • app/dashboard/settings/_components/UserManagement.tsx
  • app/dashboard/settings/_components/UserManagementSection.tsx
  • app/dashboard/settings/loading.tsx
  • app/dashboard/settings/page.tsx
  • app/error.tsx
  • app/global-error.tsx
  • app/layout.tsx
  • app/not-found.tsx
  • auth.d.ts
  • chromatic.config.json
  • components.json
  • components/ActionError.tsx
  • components/AnonymousRecruitmentSwitchClient.tsx
  • components/ApiTokenManagement.tsx
  • components/BackgroundBlobs/BackgroundBlobs.tsx
  • components/BackgroundBlobs/Canvas.tsx
  • components/ContainerClasses.ts
  • components/CopyDebugInfoButton.tsx
  • components/DataTable/ColumnHeader.tsx
  • components/DataTable/DataTable.tsx
  • components/DataTable/DefaultColumns.tsx
  • components/DataTable/nuqs/NuqsClearFilters.tsx
  • components/DataTable/nuqs/NuqsFacetedFilter.tsx
  • components/DataTable/nuqs/NuqsSearchFilter.tsx
  • components/DataTable/nuqs/NuqsTableProvider.tsx
  • components/ErrorDetails.tsx
  • components/ErrorReportNotifier.tsx
  • components/ExportProgressProvider.tsx
  • components/FreezeInterviewsSwitch.tsx
  • components/InfoTooltip.stories.tsx
  • components/InfoTooltip.tsx
  • components/InterviewDataApiSwitch.tsx
  • components/LimitInterviewsSwitchClient.tsx
  • components/Link.tsx
  • components/NetlifyBadge.tsx
  • components/ProtocolImport/ImportToastContent.stories.tsx
  • components/ProtocolImport/ImportToastContent.tsx
  • components/ProtocolImport/JobCard.tsx
  • components/ProtocolImport/JobReducer.ts
  • components/ProtocolImport/ProtocolImportDropzone.tsx
  • components/ProtocolImport/ProtocolImportPopover.stories.tsx
  • components/ProtocolImport/ProtocolImportPopover.tsx
  • components/ProtocolImport/__tests__/calculateImportProgress.test.ts
  • components/ProtocolImport/calculateImportProgress.ts
  • components/Providers/PosthogIdentify.ts
  • components/Providers/__tests__/PosthogIdentify.test.tsx
  • components/Providers/index.tsx
  • components/RecoveryCodes.tsx
  • components/ResponsiveContainer.tsx
  • components/SubmitButton.tsx
  • components/SwitchWithOptimisticUpdate.tsx
  • components/TwoFactorSetup.tsx
  • components/TwoFactorVerify.tsx
  • components/VersionSection.tsx
  • components/data-table/advanced/data-table-advanced-filter.tsx
  • components/data-table/advanced/data-table-advanced-toolbar.tsx
  • components/data-table/data-table-faceted-filter.tsx
  • components/data-table/data-table-floating-bar.tsx
  • components/data-table/data-table-pagination.tsx
  • components/data-table/data-table-skeleton.tsx
  • components/data-table/data-table-toolbar.tsx
  • components/data-table/data-table.tsx
  • components/layout/Section.tsx
  • components/layout/SettingsSection.tsx
  • components/settings/SettingsCard.tsx
  • components/settings/SettingsField.tsx
  • components/settings/SettingsNavigation.tsx
  • components/ui/Alert.tsx
  • components/ui/AlertDialog.tsx
  • components/ui/Button.tsx
  • components/ui/CloseButton.tsx
  • components/ui/Divider.tsx
  • components/ui/ErrorDialog.tsx
  • components/ui/FancyBox.tsx
  • components/ui/Input.tsx
  • components/ui/Label.tsx
  • components/ui/TimeAgo.tsx
  • components/ui/badge.tsx
  • components/ui/card.tsx
  • components/ui/checkbox.tsx
  • components/ui/collapsible.tsx
  • components/ui/command.tsx
  • components/ui/dialog.tsx
  • components/ui/dropdown-menu.tsx
  • components/ui/popover.tsx
  • components/ui/progress.tsx
  • components/ui/select.tsx
  • components/ui/separator.tsx
  • components/ui/skeleton.tsx
  • components/ui/switch.tsx
  • components/ui/table.tsx
  • components/ui/toast.tsx
  • components/ui/toaster.tsx
  • components/ui/tooltip.tsx
  • components/ui/typography/Heading.tsx
  • components/ui/typography/PageHeader.tsx
  • components/ui/typography/Paragraph.tsx
  • components/ui/typography/UnorderedList.tsx
  • components/ui/use-toast.ts
  • declarations.d.ts
  • docker-compose.dev.yml
  • docker-compose.prod.yml
  • docs/example-api-query.R
  • docs/example-api-query.py
  • env.js
  • eslint.config.mjs
  • fresco.config.ts
  • hooks/__tests__/useClientDataTable.test.tsx
  • hooks/__tests__/useNodeMeasurement.test.tsx
  • hooks/__tests__/useScrolledToBottom.test.tsx
  • hooks/use-data-table.tsx
  • hooks/useCanvas.ts
  • hooks/useClientDataTable.ts
  • hooks/useNodeMeasurement.tsx
  • hooks/usePortal.ts
  • hooks/usePrevious.ts
  • hooks/useProtocolImport.tsx
  • hooks/useResizeObserver.ts
  • hooks/useSafeLocalStorage.tsx
  • hooks/useScrolledToBottom.ts
  • hooks/useUploadAssets.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch next

Comment @coderabbitai help to get the list of available commands and usage tips.

claude and others added 13 commits May 15, 2026 09:52
Migrates project configuration to pnpm v11. Settings moved out of
package.json#pnpm and .npmrc into pnpm-workspace.yaml as required by
v11. onlyBuiltDependencies is replaced by allowBuilds; newly-detected
build scripts are blocked to preserve v10 behavior.
Restores the corepack integrity hash on the packageManager field for
supply-chain verification and reproducibility, and notes the exact
pinned pnpm version in CLAUDE.md.
…m-11-tboh0

Migrate pnpm configuration to workspace format and upgrade to v11
Wrap captureEvent and captureException in try/catch so DB lookup failures
(installationId/disableAnalytics) cannot replace the calling error or
break the main flow. Removes the defensive .catch() at the protocols-meta
call site and adds tests covering the swallow behavior.
pnpm 10+ resolves the global bin directory as `$PNPM_HOME/bin`, but
pnpm/action-setup sets PNPM_HOME to `.../node_modules/.bin` (already a
bin dir), so `pnpm add -g` ends up writing to `.bin/bin` which isn't on
PATH. Using `npm install -g` sidesteps the issue since setup-node puts
npm's global bin on PATH.
v2 of the shared action fixes the pnpm 10+ global-bin-dir issue by
configuring `pnpm config set global-bin-dir "$PNPM_HOME"`, which lets
`pnpm add -g` work again. Revert the netlify workflow's npm workaround
back to `pnpm add -g netlify-cli` accordingly. Pinned to commit SHA per
shared-action best practice.
…ols-meta

feat(api): add protocols-meta endpoint
`mode: delete-on-completion` posts a comment that auto-deletes when the
job ends, so it requires `message` or `file-path`. The intent here is
to remove any prior failure comment when this run succeeds — that's
`mode: delete`, which works by `comment-tag` alone.
…push

Two related changes for the next-branch (sandbox-dev) Netlify project,
which has auto-builds disabled and is fed exclusively via API trigger:

1. Add scripts/netlify-deploy.sh — triggers a build via the Netlify API,
   then polls /deploys/<id> until a terminal state. Exits non-zero on
   error/failed/rejected/skipped/canceled or on timeout, so the CI step
   actually fails when the underlying deploy fails (previously the curl
   fire-and-forget reported success even for broken deploys).

2. Add netlify-deploy-production.yml — fires on push to next and calls
   the same script to trigger a production-context build. Netlify's own
   `pnpm build:platform` command runs migrations + initialization, so
   the workflow itself does no DB setup.

Also restrict the preview workflow to PRs whose base is next, so it
doesn't fire for PRs targeting main (which use a different deploy
path).
With auto-builds re-enabled, Netlify deploys pushes to next directly
via its git integration. The explicit API-triggered production workflow
is redundant. Preview workflow + scripts/netlify-deploy.sh stay (still
used to trigger and gate-on-outcome for PR previews).
Netlify auto-deploys pushes to next, but Netlify notifications on this
project don't support production-deploy events. Add a workflow that
fires on push to next, finds the deploy by commit SHA, polls it to a
terminal state, and reports the outcome as a real GitHub Actions check
(so it shows up alongside other PR/commit checks and can be marked
required).

The new scripts/netlify-await-deploy.sh handles the two-phase polling:
discovery (deploy may not exist immediately after push) then state
polling. Shares no code with scripts/netlify-deploy.sh by design — the
trigger flow and the observe flow are short enough that a shared
polling helper is more friction than the ~25 line duplication.
- Bump @codaco/fresco-ui to 2.11.0, @codaco/interview to 1.0.0-alpha.21,
  @codaco/protocol-validation to 11.6.0, @codaco/shared-consts to 5.1.0
- Add @codaco/protocol-utilities (synthetic interview generation split out
  of @codaco/interview); import generateNetwork from there
- Source StageMetadataSchema from @codaco/shared-consts (now regular zod,
  not zod/mini) — it's no longer exported from @codaco/interview
- Replace local components/DataTable with @codaco/fresco-ui/DataTable;
  keep the nuqs URL-state wrappers under components/DataTable/nuqs
- Inline the small ColumnFiltersStateSchema in useClientDataTable, its
  only consumer
- Drop @faker-js/faker, luxon, @types/luxon — only used by the removed
  DataTable stories and date filter
…wing

fresco-ui's TableCell hard-codes whitespace-nowrap on every td. The
activity feed's free-form message text couldn't wrap, forcing the column
wider than the available space and showing a horizontal scrollbar. Wrap
the cell content in a div with whitespace-normal so the text wraps;
nowrap on the td still does its job for badge/timestamp columns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants