Conversation
* fix: update webhook service taxonomy and guard against undefined service - Rename service values from signals.vss/events.behavior/events.safety to signals/events - Prefix condition field names with vss. namespace - Merge event name options into single events key - Change isEventService to use strict equality instead of startsWith (fixes crash when service is undefined) - Add service default value to NewWebhookForm to prevent undefined on initial render Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Bump yaml from 2.8.2 to 2.8.3 Bumps [yaml](https://github.com/eemeli/yaml) from 2.8.2 to 2.8.3. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](eemeli/yaml@v2.8.2...v2.8.3) --- updated-dependencies: - dependency-name: yaml dependency-version: 2.8.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Update constants and vehicle details * Update burn * Enable Stale vehicle removal * Add debug * Add delete check * Fix db anomaly * Add SACD * setPermissions fix * powertraintype fix * Remove powertrainType that's throwing off the mint * fix SACD and add animation * Show button to simulator * Update to paymaster * Revert "Update to paymaster" This reverts commit 37f58c1. * Update app creation modal * Badge for simulated vehicles * Remove Tesla replace with Chevy * Configurator mis-disabling * Avoid 0x mismatch * Explorer init * fix 404 * Explorer work * compile issue fix * Type fix * init query * token xchange * query fix * vehicle pages * Remove double wrapping * debug * Avoid circular dep issue * path fix * move sdk to serverside * Add query * JSON update * error handling + navbar * new license card * fix * Sharing card * hide right column * fix transparent icon * SDK update * Bump lodash, @graphql-codegen/cli and @graphql-codegen/client-preset Bumps [lodash](https://github.com/lodash/lodash), [@graphql-codegen/cli](https://github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/graphql-codegen-cli) and [@graphql-codegen/client-preset](https://github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/presets/client). These dependencies needed to be updated together. Updates `lodash` from 4.17.21 to 4.18.1 - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](lodash/lodash@4.17.21...4.18.1) Updates `@graphql-codegen/cli` from 5.0.7 to 6.2.1 - [Release notes](https://github.com/dotansimha/graphql-code-generator/releases) - [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/graphql-codegen-cli/CHANGELOG.md) - [Commits](https://github.com/dotansimha/graphql-code-generator/commits/@graphql-codegen/cli@6.2.1/packages/graphql-codegen-cli) Updates `@graphql-codegen/client-preset` from 4.8.3 to 5.2.4 - [Release notes](https://github.com/dotansimha/graphql-code-generator/releases) - [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/presets/client/CHANGELOG.md) - [Commits](https://github.com/dotansimha/graphql-code-generator/commits/HEAD/packages/presets/client) --- updated-dependencies: - dependency-name: lodash dependency-version: 4.18.1 dependency-type: direct:production - dependency-name: "@graphql-codegen/cli" dependency-version: 6.2.1 dependency-type: direct:development - dependency-name: "@graphql-codegen/client-preset" dependency-version: 5.2.4 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> * Improve API key gen exp * modal fix * Perf improvements on web3 transactions * More exp improvements * Add FleetOS tenant registration flow from API Keys section - New "Generate FleetOS Tenant" button: ensures fleets.dimo.co is an authorized redirect URI, generates an API key, obtains a DevJWT, and registers the tenant via POST to the FleetOS API in one guided flow - FleetOS signer address persisted to localStorage so the matching row is tagged with a "FleetOS" badge across page refreshes - Signer is rolled back on-chain if anything after enablement fails, since the private key is unknown to FleetOS at that point - Loading modal is now non-dismissable (backdrop + Escape blocked) while status is 'loading', preventing mid-flow exits across all operations Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Regenerate GraphQL types for updated SignerFragment Added clientId and redirectURIs fields to SignerFragment require codegen output to be updated so the typed gql document resolves correctly at compile time. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix TDZ crash: move useFragment before useState that depends on it In production builds, minification causes a ReferenceError when fragment.clientId is accessed inside a useState initializer that appears before the fragment const declaration. Moving useFragment to the top of the component resolves the temporal dead zone. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Register FleetOS: rename, new icon, confirmation modal - Rename button to "Register FleetOS" with TruckIcon - Button now opens a confirmation modal explaining the multi-step flow before any transactions are initiated - Confirmation lists what will happen (redirect URI, API key, tenant registration) and warns not to close the window once started Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix FleetOS button layout, modal centering, and copy - Wrap buttons in flex div so they render side by side - Remove className from Modal to preserve fixed overlay centering - Shorten confirmation modal copy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * FleetOS: all-or-none rollback on failure - Track addedRedirectUri to distinguish newly-added from pre-existing - On failure: roll back signer and redirect URI only if created in this flow, leaving pre-existing redirect URIs untouched - Show "Rolling back changes..." status so the user knows cleanup is happening before the error is surfaced Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * RentalOS: update /tenant/register request shape with user profile data Rename FLEETS_REGISTER_ENDPOINT → RENTAL_OS_REGISTER_ENDPOINT and update the POST body to match the new API contract: adds wallet (smartContractAddress), email, first_name, last_name, and business_name fetched from the DB via getUserByToken. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix: use server action getUser instead of server-only service getUserByToken imports next/headers which can't run in a client component. Switch to the existing getUser server action wrapper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Allow fleets.dimo.co in CSP connect-src Required for the RentalOS /tenant/register fetch from the browser. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * RentalOS: wait for on-chain propagation, retry JWT + registration After enabling the signer and redirect URI, wait 8 s for auth servers to index the on-chain state before requesting a JWT. Then retry JWT generation up to 3x (5 s apart) and the registration call up to 3x (5 s apart) before giving up. Rollback only happens after all retries are exhausted. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix RentalOS tag not showing after wizard completes GraphQL returns addresses in lowercase; account.address is checksummed. Normalize to lowercase on save and comparison so the tag matches regardless of which source the signer row comes from. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * RentalOS: use Developer JWT signed by API key, not Global Account key getGlobalAccountDeveloperJwt signs with the Turnkey embedded key (User JWT). Instead, call getDeveloperJwt directly with the newly generated signer private key so the Authorization header carries a proper Developer JWT tied to the developer license. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * RentalOS: add console logging to diagnose 403 failures Logs getDeveloperJwt result/errors per attempt, the registration request body (API key redacted), and the full status + response body from each /tenant/register attempt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix: strip 0x prefix from private key before getDeveloperJwt web3 returns privateKey with 0x prefix; the DIMO SDK expects raw hex. Matches how APIKeyModal displays the key and how Turnkey exports it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Fix: strip 0x prefix from apiKey in /tenant/register body Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Trim whitespace from business_name before /tenant/register Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add multi-configuration design spec One-to-many configurations per license — backend API changes, new list page at /configurator, create moves to /configurator/new. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add multi-configuration implementation plan Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: rename getConfigurationsByClientId to return array, add deleteConfiguration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor: consolidate [id] configurator form components to shared location Add configuration_id to shared SharedProps type, update [id] ConfigurationForm imports to reference shared components path, and delete the now-redundant duplicate files from the [id]-specific directory. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add ConfigurationList component with edit/delete per row Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add /configurator list page and /configurator/new create route Moves DEVELOPER_LICENSE_INFO to ListView, replaces the root configurator page with a list view, and adds a /new route for creating configurations (redirects to list on save instead of the edit page). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add /configurator list page and /configurator/new create route Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: simplify Vehicles entry point — always route to configurator list * fix: update stale import path after [id] types consolidation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: update LicenseCard to use renamed getConfigurationsByClientId Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: normalize getConfigurationsByClientId response to always return array Backend currently returns a single object; wrap it until API is updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: show configurator link with count when multiple configurations exist Single config still shows copy button; 2+ configs links to configurator list. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add Copy Link action to configurator list Copies the login.dimo.org sharing URL directly from the list without entering each configuration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: auto-open Register RentalOS modal via ?focus=rentals_os_signup Visitors arriving at console.dimo.org?focus=rentals_os_signup are now routed (post-login) to their first developer license details page, with the Register RentalOS confirmation modal opened automatically. The focus value is preserved across the unauthenticated /sign-in redirect, the OAuth round-trip, and the post-login /app redirect via sessionStorage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: wrap home pages in Suspense for useSearchParams CSR bailout Adding useSearchParams to the home View triggered a Next.js "missing-suspense-with-csr-bailout" prerender error on /app and /. Wrap the View in <Suspense> on both routes (matches the existing sign-in page pattern). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: import focus constants from server-safe module in middleware Middleware was importing FOCUS_QUERY_PARAM from src/utils/focus.ts, which is marked 'use client'. In production the Edge-Runtime middleware bundle treated the import as a client reference instead of inlining the string, so request.nextUrl.searchParams.get(undefined) returned null and ?focus=rentals_os_signup was dropped on the / -> /sign-in redirect. Split the shared constants into src/utils/focusConstants.ts (no 'use client') and have middleware import from there. The client helpers (saveFocus / getFocus / clearFocus) stay in focus.ts and re-export the constants so existing client call sites are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * link updates * Add Japan * Connection License Msg update * feat(brand): Brand panel on license details (uploads + name) (#274) * feat(brand): Brand panel on license details (uploads + name) Adds a CollapsibleSection to /license/[tokenId]/details/ where dev license owners can set their OEM brand: - name (string, <= 100 chars) - logo (any aspect, used on the auth button + redirect pages) - icon (square, cropped on upload via react-easy-crop; used in the popup chrome + tab favicon) These persist via dev-console-api's new endpoints (DIMO-Network/dimo-developer-console-api#68). The login-with-dimo SDK will fetch them at initializeDimoSDK time so the button auto-themes. How it composes src/services/brand.ts axios wrappers for the three new endpoints — matches app.ts pattern. src/actions/brand.ts 'use server' thin wrappers, matches actions/workspace.ts. components/Brand/Brand.tsx CollapsibleSection. Loads workspace via getWorkspace() then existing brand via fetchMyBrand. Gates edits with useIsLicenseOwner. components/Brand/components/ ImagePicker.tsx File picker + drag-and-drop + preview. For square icon w/ non-SVG, wraps react-easy-crop to produce a 1:1 cropped File via canvas. SVGs pass through unchanged. components/View/View.tsx Mounts <Brand> next to RedirectUris; adds BrandFragment to the GQL query. Deps + react-easy-crop ^5.5.0 Auth No new pattern — reads and writes ride the existing AuthenticationMiddleware on dev-console-api. Ownership verified server-side as workspace.owner === request.user.user.address. Non-owners see the panel in read-only mode. * feat(brand): primary color picker in Brand panel Adds a hex color input + native <input type=color> picker to the Brand panel on /license/[tokenId]/details/. Validates #RRGGBB format client-side and on the API. A small swatch shows the resolved color next to the input. Color flows through saveMyBrand → console-api → workspace_brands .primary_color. SDK + popup pick it up via their respective brand fetches. * fix(build): install react-easy-crop + regen gql + null-safe tokenId access - Adds react-easy-crop to package-lock.json (Vercel build was missing the dep) - Regenerates src/gql after adding BrandFragment - One pre-existing null-safety hop in layout.tsx surfaced by the codegen rerun: data?.developerLicense.tokenId -> data?.developerLicense?.tokenId * fix(brand): require display name in panel SDK and popup both gate brand load on body.name — an empty name causes the entire brand (logo, icon, color) to be silently dropped on the consumer side. Make the form refuse to submit without a name so users aren't surprised when their uploaded logo never appears. * fix(brand): allow IPFS gateway + blob/data URIs in img-src CSP Brand panel renders the uploaded logo/icon via <img src=https://assets.dimo.org/...> and the live preview via URL.createObjectURL (blob: URLs). Default CSP only allowed 'self' + walletconnect — both would have been silently blocked, so the user would upload a logo and see nothing on the next render. * fix(brand): strip dead WalletConnect entries from CSP Console uses Turnkey + ZeroDev for auth; wagmi is only used for HTTP transports + chain defs, no WC connector is configured. Verified runtime: Vercel preview sign-in page settles with zero requests to explorer-api.walletconnect.com or pulse.walletconnect.org. CSP was allowlisting endpoints we never call — removed both from connect-src and img-src to shrink the attack surface and stop signalling that the codebase uses WC. * chore: revert unrelated .gitignore change CLAUDE.md gitignore entry slipped into this PR but is not related to the brand work. Belongs in a separate housekeeping change. * fix(brand): address code review issues before merge - Color picker: replace reset() with setValue(..., { shouldDirty: true }) so the form isDirty flag stays correct and other fields aren't re-validated - CSP img-src: remove `data:` — image previews use blob: URLs (URL.createObjectURL), not data URIs - Add setValue to useForm destructure (required by the above fix) - services/brand: handle 404 from API (API now returns 404 when no brand exists, previously returned {}); import isAxiosError for the guard Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(brand): handle 404 in getMyBrand (API now returns 404 not {}) API endpoint GET /my/workspace/:id/brand was updated to return 404 when no brand exists instead of {}. Update the service to catch 404 and return null instead of trying to distinguish {} from a valid response. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: James Li <james.li.upenn@gmail.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(brand): surface workspace-load failures instead of silent no-op (#275) When getWorkspace() returns no id (expired session, no company workspace yet) the load effect was returning silently — setLoading(false) still ran via finally, so the form rendered, but workspaceId stayed null and every Save click hit the early-return guard with zero user feedback. Notify on both code paths: - load(): if !ws?.id, show 'Workspace not found' toast + Sentry message - onSubmit(): if !workspaceId, show 'Cannot save' toast instead of return - load() catch: surface a generic 'Brand load error' toast Diagnostic for users currently seeing 'Save Brand does nothing' on console.dimo.org — the toast will name which step failed. * fix(brand): stop toast loop on workspace-load failure (#276) dae756c added setNotification to the load effect's deps to surface the silent no-op. But NotificationContext's setNotification reference is not stable across renders — each toast caused a re-render that flipped the dep, which re-ran the effect, which fetched + failed + toasted again. Infinite loop of "Could not load your workspace" toasts on any account whose getWorkspace() returns empty. Two changes: - load effect runs once (empty deps) via a ref-pinned setNotification - error message goes into a loadError state slot, toasted by a second effect keyed only on loadError so re-renders can't refire the fetch setNotification used in onSubmit is unchanged — that path runs on user click, not in a render cycle. * fix(brand): resolve workspace by license tokenId (#277) Companion to DIMO-Network/dimo-developer-console-api#69. The Brand panel is per-license, so the URL already pins the right workspace — switch the load effect to use the new /api/my/workspace/by-token/:tokenId endpoint and keep the company-scoped lookup only as a fallback. Fixes the silent 'Save Brand does nothing' bug on accounts whose workspace.company_id has drifted from the user's current company. * content type fix * NextJs config * docs: add multi-brand per developer license design spec Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(brand): extend service + action layers for multi-brand collection Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(brand): add BrandRow component with default badge and owner-gated actions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(brand): add BrandForm component for create/edit with rename warning and set-default Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(brand): refactor Brand panel into multi-brand list manager with SDK hint Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: update InputMaybe type to include undefined Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(brand): disable delete button when only one brand or brand is default canDelete was inverted - was allowing delete of the only brand (which the API rejects anyway with 409). Now correctly disabled unless there are multiple brands AND this one is not the default. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(configurator): add brandName selector to Login with DIMO config When a workspace has multiple brands, the Login with DIMO configuration form now shows a brand dropdown populated from the configured brands. Selecting a brand emits brandName in the generated code snippet and URL. Leaving it as 'Default' omits the prop, matching existing single-brand behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(configurator): add brandName selector to Share Vehicles with DIMO section Mirrors the Login with DIMO brand dropdown — shows when workspace has multiple named brands, omitted for single-brand workspaces. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(connections): grant SACD permissions to generated connection keys (#279) * feat(connections): grant SACD permissions to generated connection keys The connection-create flow generated a Connection License key and a Device Issuance key but never granted them any on-chain permissions, so neither could actually be used to generate certificates or mint synthetic devices. After the mint, the flow now reads connectionId from the ConnectionMinted event and calls setPermissions on the SACD contract for each grantee: permission 1 (MintSD, bitmask 12) for the device-issuance key, permission 2 (GenerateCertificate, bitmask 48) for the license key. The unused Kernel AA wrapping is dropped — the grantee is the raw EOA derived from each generated private key. The loading modal now describes what each signature is for instead of a single generic label. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(connections): show device issuance address on connection details Derive and display the EOA address for the Device Issuance Key so users can reference it without unmasking the private key. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore: update codegen'd GraphQL types Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Correct more connection mint prices 100 to 1 * docs: add design spec for renounce vehicle permissions feature Captures architecture, data flow, component design, error handling, and testing plan for the per-vehicle renounce action on the vehicle list table. Also removes unused axios import from brand.ts that was blocking the pre-commit lint hook. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(vehicles): add renounce vehicle access action - useRenounceVehiclePermissions hook: calls SACD setPermissions with permissions=0 and expiration=0 to zero out developer's access - RenounceVehicleModal: confirmation modal with vehicle MMY, consequence copy, inline error on failure, loading state during tx - VehicleDetailsTable: inline kebab menu per row opens modal; optimistic removal from list on success + background refetch; success/error toasts via NotificationContext; Sentry capture on error - Tests: 14 passing across hook unit and modal unit test suites Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(vehicles): restore exact gql query string for TypedDocumentNode inference Trailing whitespace in the query must match the codegen-registered string exactly or gql() returns unknown instead of TypedDocumentNode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(vehicles): use renouncePermissions instead of setPermissions The SACD contract only allows the grantor to call setPermissions — grantees get Unauthorized(address). The contract exposes a dedicated renouncePermissions(asset, tokenId) function (0x290a7e7e) where msg.sender is treated as the grantee, allowing developers to self-revoke access. Added renouncePermissions to Sacd.json ABI and updated hook accordingly. Removed unused currentUser dependency from the hook. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(vehicles): throw on success:false receipt from processTransactions processTransactions only throws on HttpRequestError or a non-empty receipt.reason — a failed transaction with success:false and no reason string was silently returning, causing the UI to show success while the on-chain renounce never executed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * debug(vehicles): log clientId vs smartContractAddress in renounce Surfaces whether the SACD grantee (clientId) matches msg.sender (smartContractAddress) — a mismatch would explain silent no-ops. Also logs the full processTransactions result including tx hash. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(test): pass clientId arg to renounce calls Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add frontend redesign design spec DIMO Teal direction, dark/light mode via next-themes + class strategy, collapsible grouped sidebar, shadcn/ui component migration plan. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add frontend redesign implementation plan 10-task foundation-first plan: token layer, theme toggle, sidebar collapse, shadcn/ui migration, Sonner, AppCard simplification. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add DIMO Teal token layer and shadcn/ui foundation Installs next-themes, lucide-react, clsx, tailwind-merge, and shadcn/ui. Sets up DIMO Teal HSL CSS variables for light/dark modes, updates Tailwind config with darkMode class + token colors, and adds src/lib/utils.ts with cn(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add dark/light mode toggle via next-themes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: make ThemeToggle keyboard accessible, fix hydration fallback size Replace div[role=switch] with a native <button> so the toggle is focusable and activatable via Space/Enter without custom JS. Also correct the hydration placeholder dimensions from 52×26px to 54×22px to match the real rendered size (p-0.5 + two w-6 h-[18px] spans + gap-0.5). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: add sidebar collapse state to LayoutContext Extends LayoutContext with isSidebarCollapsed/setSidebarCollapsed, persisting the value to localStorage via withLayout HOC. TDD: tests written first. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: redesign sidebar with grouped sections and collapse toggle Replaces flat nav list with workspace/resources sections, adds a collapse button that toggles icon-only mode, and migrates all hardcoded dark colors to design-token Tailwind classes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: remove Wrapper-in-render, add type=button, stable keys, type bottomMenu Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: redesign header credits as teal pill, show balance in USD Switch Header.css to semantic tokens (bg-sidebar, border-border, text-foreground). Redesign CreditsWidget small variant as a compact teal pill with $-prefixed USD balance — no wallet icon, no "DCX" text. Large variant updated to "Buy Credits" and semantic token classes. Initial balance now shows "$0.00" instead of "0". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: migrate Button to shadcn/ui foundation Replace @base-ui/react/button with standard HTML button via React.forwardRef in src/components/ui/button.tsx. Wrap it in the app Button component using cn() + variant="default", and replace all hardcoded dark colors in Button.css with semantic token classes while preserving all variant selectors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: migrate form primitives to shadcn/ui (Input, Textarea, Switch, Checkbox) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: import ChangeEvent type directly in CheckboxField * feat: migrate Modal to shadcn Dialog Replace Headless UI Dialog+Transition with shadcn/Radix Dialog primitive. Keeps identical prop API (isOpen, setIsOpen, className, showClose, children) and preserves role="close-modal" on the close button. Removes shadcn's auto-generated close button from DialogContent to avoid duplication. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * wip: frontend-redesign paused at 8/10 tasks * feat: replace withNotifications HOC and Toast with Sonner Migrates all 44 setNotification callsites to toast.success/error/info from sonner. Removes withNotifications HOC from AuthorizedLayout, GuestLayout, sign-in/View, and sign-up/View. Adds <Toaster /> to RootLayout inside ThemeProvider. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat: AppCard simplification + LicenseCard token cleanup (Task 10) Removes environment display from AppCard (scope/ENVIRONMENTS_LABELS), updates AppCard CSS to use card/border/foreground tokens. Updates LicenseCard CSS to use card/border tokens instead of surface-raised. Updates test to remove environment label assertion. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: migrate useErrorHandler to sonner, clean up VehicleSimulator test mock Removes the last non-infrastructure usages of NotificationContext: - useErrorHandler now calls toast.error() directly via sonner - VehicleSimulator test no longer wraps with NotificationContext.Provider since the component already uses toast directly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: remove dead notification infrastructure (Toast, NotificationPanel, withNotifications, useNotification) These were superseded by Sonner during the frontend redesign. No remaining imports in src/. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: replace remaining bg-surface-* and hardcoded text-white with semantic tokens Completes the DIMO Teal shadcn/ui semantic token migration across all high-priority components and pages. bg-surface-default→bg-card, bg-surface-raised→bg-accent, bg-surface-sunken→bg-background, text-white (standalone)→text-foreground, text-white/50→text-muted-foreground, border-[#322D2F]→border-border. bg-black in connection cards also replaced with bg-card. Intentional colored-bg text-white pairings (cta-default, blue-600, red-900, indigo-600) left untouched. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: replace invalid text-text-primary token, clean up remaining text-white misses text-text-primary generates no CSS in this project — replaced all occurrences with text-foreground. Also removes dead onClick prop from AppCard interface and fixes standalone text-white/text-white/50 on plain backgrounds in EmptyList, modal CSS files, CSVUpload, and _not-found. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: replace inert bg-surface-overlay with bg-accent token * fix: add sr-only DialogTitle to Modal, remove stale handoff files * chore: remove .superpowers from tracking, add to .gitignore * tailwind update --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: James Reategui <JamesReate@users.noreply.github.com> Co-authored-by: zer0stars <74260741+zer0stars@users.noreply.github.com> Co-authored-by: Dylan Moreland <79415431+elffjs@users.noreply.github.com> Co-authored-by: Dylan Moreland <dylan@dimo.zone>
…mode - GuestLayout always uses dark mode to avoid background image issues - SelectField uses semantic color tokens instead of hardcoded dark values so dropdown text and menus render correctly in light mode Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The dark class on <main> overrides CSS vars for children but the body background still leaks through without an explicit bg-background on the guest-layout container. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced hardcoded bg-cta-default/text-white with semantic tokens (bg-background, border-input, text-foreground) to match ui/input.tsx so selects render correctly in both light and dark mode. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SelectWithChevron rewritten as a custom div-based dropdown using the same select-field/custom-menu CSS as SelectField — native <select> popups use OS styling and can't be themed - CEL builder components (DataAttributeSelector, OperatorSelector, EventNameSelector, ValueInput) switched from SelectWithChevron + register() to SelectField + control, matching the Service.tsx pattern Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New /licenses page shows license list and onboarding banner (content previously on the home page) - Home page redesigned with shortcut cards: Licenses, Connections, Webhooks, Vehicle Explorer — for quick navigation - Licenses added to sidebar Workspace section just below Home - /licenses added to page titles for header rendering Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaced bg-cta-default/text-white with bg-background/border-input/ text-foreground to match ui/input.tsx and render correctly in both themes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Top section: always-dark cluster with radial gradient, 3-column grid (Usage gauge | License identity | Vehicles gauge) - Gauge rings: circular border with primary glow, large count + label - Usage and Vehicles get cluster prop for compact gauge rendering - Bottom sections: 2-column grid (Signers, Redirect URIs, JWTs, Brand) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LicenseCard: whole card is now clickable → navigates directly to details, removing the redundant "License Details" button - License details: widen center cluster column (1fr 2fr 1fr) so Client ID doesn't wrap; stack expandable panels in a single column to prevent the expand-neighbors visual glitch; add border to CollapsibleSection for light mode contrast - Icons: replace DeveloperBoardIcon (white fill, chip-like) with an ID-card outline; ChipIcon (Data Explorer) with a magnifying glass; ConnectionsIcon (wide graph network, similar to Webhooks) with a link-chain icon — all now use currentColor so they adapt to light/dark themes - Navigation: clean up hardcoded fill-white/stroke-white classes on Webhooks menu item Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Nav "Licenses" now goes directly to /license/[tokenId]/details when the user has a license. With no licenses, shows a prompt and the "Create a license" button instead of the old license list page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Matches the DeveloperJwts pattern: action button sits in the CollapsibleSection title row (right side), not buried in the content. Removed the verbose description from the Brand header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Documents the tab-based layout replacing the instrument cluster UI. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ader Replace the instrument-cluster layout with a persistent header (name, token ID, client ID, rename button) and a 4-tab layout (Overview, Config, Vehicles, Brand). Overview tab shows Usage stat, vehicle count, and quick-action shortcuts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sm font-mono for key fields
…e fixes All conflicts resolved by keeping staging (HEAD) versions, which include: - Light-mode color fixes (bg-primary, border-border, fill-foreground) - Settings page redesign - License details page redesign - CSS semantic token migration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Save brandName to configuration JSON for LoginWithDimo and ShareVehiclesWithDimo (was silently dropped on submit) - Fix Cancel/Resend buttons in email recovery using hardcoded border-white + CSS invert filter — replace with primary-outline - Remove hardcoded bg-grey-400 disabled override in email recovery CSS, letting Button's disabled:opacity-50 handle it properly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign-in and email-recovery forms use bg-card inside a hardcoded .dark container, but text color was inherited from body (light mode = dark text) rather than resolved from the .dark context. Adding text-card-foreground forces the correct light text within the dark card regardless of the app-level theme. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OTP boxes were nearly invisible (bg-background ≈ black on dark theme) and cramped (outer padding left no room for the digit). Switch to bg-muted, strip padding, and center content so digits are legible. Resend Code button had same border invert border-white anti-pattern as the email recovery buttons — replace with primary-outline. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
TextField wraps shadcn Input which hardcodes bg-background, h-10, w-full, px-3/py-2 — impossible to override via className. Switch to bare <input> elements styled directly with bg-muted, w-12 h-12, text-center, and proper focus ring. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.