Skip to content

fix: formatting in studio (pt2)#2601

Merged
Aenimus merged 3 commits intomainfrom
ondrej/eng-9087-cosmostudioci-fix-formatting-drift-enforce-formatting-in-ci-pt2
Mar 9, 2026
Merged

fix: formatting in studio (pt2)#2601
Aenimus merged 3 commits intomainfrom
ondrej/eng-9087-cosmostudioci-fix-formatting-drift-enforce-formatting-in-ci-pt2

Conversation

@comatory
Copy link
Copy Markdown
Contributor

@comatory comatory commented Mar 6, 2026

Summary by CodeRabbit

  • Style

    • Standardized code formatting across the codebase for consistency.
  • Chores

    • Updated configuration file merging in Prettier settings.

Checklist

Fixes formatting drift in studio just for *.ts, *.css, *.md files. There will be follow up PR(s) to fix rest

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 6, 2026

Walkthrough

Large-scale code style normalization across the studio codebase, primarily switching string delimiters from double to single quotes, reformatting function signatures from multi-line to single-line layouts, and making minor type adjustments. Several behavioral changes are interspersed, including logic updates to hooks, type refinements for public interfaces, and Sentry integration restructuring.

Changes

Cohort / File(s) Summary
Configuration & Build Files
studio/next.config.mjs, studio/sentry.client.config.ts, studio/sentry.edge.config.ts, studio/sentry.server.config.ts, studio/src/env.mjs, studio/prettier.config.js, studio/vitest.config.mts, studio/tailwind.config.js
Quote normalization (double to single), minor whitespace adjustments, and reformatting of config objects. Sentry client config refactors replay integration initialization to use an array pattern. Prettier config merges parent .prettierrc.json.
Type Definitions & Constants
studio/src/lib/constants.ts, studio/src/lib/trace-utils.ts, studio/src/lib/schema-helpers.ts, studio/src/components/playground/types.ts, studio/src/lib/signup-content.ts
Quote normalization in type aliases and literal string values. playground/types.ts updates type indexing syntax and reformats Zod schema structure. constants.ts reworks SHARE_OPTIONS construction. trace-utils.ts updates public enum and constant values to single quotes.
Hook Files
studio/src/hooks/use-*.ts (18 files: use-check-user-access.ts, use-event-callback.ts, use-event-listener.ts, use-form.ts, use-hash.ts, use-local-storage.ts, use-session-storage.ts, use-share-playground-modal.ts, use-new-features-popup-disabled.ts, use-pagination-params.ts, use-star-banner-disabled.ts, use-user.ts, use-workspace.ts, use-cookie-organization.ts, use-cookie.ts, use-current-plan.ts, use-current-organization.ts, use-feature.ts)
Quote normalization, signature reformatting to single lines, and trailing comma additions. use-hash.ts adds isClient state and changes return type to `string
Analytics & Playground Components
studio/src/components/analytics/useSyncTableWithQuery.ts, studio/src/components/analytics/constructAnalyticsTableQueryState.ts, studio/src/components/analytics/getDataTableFilters.ts, studio/src/components/analytics/useAnalyticsQueryState.ts, studio/src/components/analytics/defaultFilterFunction.ts, studio/src/components/playground/prettyPrint.ts, studio/src/components/checks/use-open-usage.ts
Quote normalization and minor formatting. useSyncTableWithQuery.ts adds else branch for sorting and try/catch for date range parsing. defaultFilterFunction.ts collapses multi-line conditionals to single-line. getDataTableFilters.ts reformats signature to single line.
Member Groups & Type Updates
studio/src/components/member-groups/use-group-resources.ts
Restructured function signature with explicit destructuring, added early return for undefined resources. Expands GroupResourceItem public interface with selected, disabled, and optional children properties. Updates type values to single quotes and adds satisfies GroupResourceItem usage in mappings.
Utility & Format Functions
studio/src/lib/utils.ts, studio/src/lib/download-string-as-file.ts, studio/src/lib/format-date.ts, studio/src/lib/format-number.ts, studio/src/lib/format-status.ts, studio/src/lib/format-metric.ts, studio/src/lib/playground-storage.ts, studio/src/lib/playground-url-state-*.ts, studio/src/lib/page.d.ts, studio/src/lib/posthog.ts, studio/src/lib/stripe.ts, studio/src/lib/track.ts, studio/src/lib/insights-helpers.ts
Quote normalization and signature reformatting to single lines. Minor behavioral adjustments: utils.ts adds parameter destructuring, format-date.ts and format-number.ts collapse multi-line signatures.
Test Files
studio/src/__tests__/playground-url-state-encoding-decoding.test.ts, studio/src/__tests__/schema-helpers.test.ts, studio/src/__tests__/lint-page.test.ts
Quote normalization in test descriptions and assertions. No logic or assertion changes; purely formatting updates.
Style & Markup Files
studio/src/styles/login.css, studio/src/styles/globals.css, studio/src/styles/utils.css, studio/src/components/schema/monaco-dark-theme.ts, studio/README.md, studio/src/pages/cosmo-managed-solution-terms.md, studio/src/pages/_error.jsx
Quote normalization in CSS selectors and font declarations. login.css expands multi-line shadow definitions. terms.md has formatting and capitalization adjustments. monaco-dark-theme.ts converts theme colors to single quotes.
Hydration & Hooks
studio/src/hooks/use-hydrate-playground-state-from-url.ts, studio/src/components/ui/use-toast.ts
Quote normalization, spacing adjustments, and internal type refinements. use-hydrate-playground-state-from-url.ts clarifies ScriptData field typings and updates local storage annotations.
Configuration & Feature Detection
studio/src/instrumentation.ts, studio/src/hooks/use-fireworks.ts, studio/src/hooks/use-isomorphic-layout-effect.ts, studio/src/hooks/use-is-admin.ts, studio/src/hooks/use-is-creator.ts, studio/src/hooks/use-feature-limit.ts, studio/src/hooks/use-roles.ts, studio/src/hooks/use-resolved-theme.ts, studio/src/hooks/use-subgraph.ts, studio/src/hooks/use-subscription.ts, studio/src/hooks/use-window-size.ts
Quote normalization and minor signature/formatting updates. instrumentation.ts updates runtime comparisons to single quotes. Most other files are purely stylistic updates with no behavioral changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: formatting in studio (pt2)' directly and clearly summarizes the main change: formatting fixes in the studio directory, specifically part 2 of a multi-part effort.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (1)
studio/src/hooks/use-share-playground-modal.ts (1)

119-125: Note: Missing dependency in useEffect.

The useEffect on line 120 calls generateShareableUrl but doesn't include it in the dependency array. While this is likely intentional (only run when modal opens), consider adding an eslint-disable comment to document this intent, similar to the pattern in use-hydrate-playground-state-from-url.ts.

📝 Suggested documentation
   useEffect(() => {
     if (!isOpen) return;

     setSelectedOptions(DEFAULT_SELECTED_OPTIONS);
     generateShareableUrl(DEFAULT_SELECTED_OPTIONS);
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [isOpen]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@studio/src/hooks/use-share-playground-modal.ts` around lines 119 - 125, The
effect resets state and calls generateShareableUrl when the modal opens but
omits generateShareableUrl from the dependency array without documenting that
intent; update the useEffect in use-share-playground-modal.ts to either include
generateShareableUrl in the deps or (preferred to match the existing pattern)
add an eslint-disable-next-line react-hooks/exhaustive-deps comment with a short
explanation (e.g., "Only run on open; generateShareableUrl is stable/intentional
to omit") similar to the pattern used in
use-hydrate-playground-state-from-url.ts, referencing useEffect,
generateShareableUrl and DEFAULT_SELECTED_OPTIONS.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@studio/next.config.mjs`:
- Around line 72-75: The CSP currently includes "'unsafe-eval'" because
allowUnsafeEval is hardcoded true; change the logic so allowUnsafeEval (or the
inline conditional that appends "'unsafe-eval'") only evaluates true for
development builds (e.g., when NODE_ENV === 'development' or when !isProduction
&& !isPreview) so production/preview never emit 'unsafe-eval' in the script-src
string; update the allowUnsafeEval declaration or the template expression that
builds the script-src (the conditional adding "'unsafe-eval'") to be gated by
development-only checks.

In `@studio/src/components/analytics/useSyncTableWithQuery.ts`:
- Around line 91-95: The code sets selected group using router.query.group cast
unsafely which can produce undefined; validate router.query.group exists and is
a valid key of AnalyticsViewGroupName before calling setSelectedGroup. Check
that typeof router.query.group === "string", then test if (router.query.group as
string) is a key in AnalyticsViewGroupName (e.g., using
Object.prototype.hasOwnProperty.call or in operator) and only then call
setSelectedGroup(AnalyticsViewGroupName[router.query.group as keyof typeof
AnalyticsViewGroupName]); otherwise set a safe default or skip updating state.
Ensure this validation is applied where setSelectedGroup is invoked and
reference AnalyticsViewGroupName and router.query.group in the same scope.
- Around line 79-81: Wrap the decodeURI/JSON.parse call that produces
filterStateFromUrl in a try/catch to guard against malformed URLs: when reading
router.query.filterState in useSyncTableWithQuery.ts, perform decodeURI and
JSON.parse inside a try block, on error set filterStateFromUrl to an empty array
(or the existing safe default) and optionally log or silently ignore the parse
error; ensure you update the same variable name filterStateFromUrl so downstream
code uses the fallback instead of throwing.

In `@studio/src/components/member-groups/use-group-resources.ts`:
- Around line 180-185: The current call to mapGraph uses a non-null assertion on
the result of accessibleResources.federatedGraphs.find(...), which can throw if
no matching federated graph exists; modify the logic around mapGraph to safely
handle a missing federated graph (e.g., find result may be undefined) by
checking the find result before calling mapGraph (or providing a sensible
fallback/skipping this subgraph), updating the code paths that reference
fedGraph/federatedGraphs to avoid the `!` operator and handle the undefined case
(adjust where mapGraph is invoked and any callers expecting its result).

In `@studio/src/pages/cosmo-managed-solution-terms.md`:
- Line 71: The heading "## 10. Limitations of Liability.##" is malformed; update
the ATX heading to valid Markdown by removing the trailing hashes or adding a
space before them so it is either "## 10. Limitations of Liability." or "## 10.
Limitations of Liability ##" (replace the exact string in the file), ensuring
consistent rendering.
- Line 59: Fix the typos in the "BETA DISCLAIMER" paragraph: replace "IDENTIFED"
with "IDENTIFIED" and remove the stray word "FORM" so the clause starts
"FEATURES OF THE SOFTWARE OR SERVICE THAT ARE IDENTIFIED BY WUNDERGRAPH AS
“BETA” MAY CONTAIN DEFECTS."; update the single sentence under the BETA
DISCLAIMER heading accordingly to preserve punctuation and capitalization.

---

Nitpick comments:
In `@studio/src/hooks/use-share-playground-modal.ts`:
- Around line 119-125: The effect resets state and calls generateShareableUrl
when the modal opens but omits generateShareableUrl from the dependency array
without documenting that intent; update the useEffect in
use-share-playground-modal.ts to either include generateShareableUrl in the deps
or (preferred to match the existing pattern) add an eslint-disable-next-line
react-hooks/exhaustive-deps comment with a short explanation (e.g., "Only run on
open; generateShareableUrl is stable/intentional to omit") similar to the
pattern used in use-hydrate-playground-state-from-url.ts, referencing useEffect,
generateShareableUrl and DEFAULT_SELECTED_OPTIONS.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 302e98ef-5326-48e9-8c77-b74255f165db

📥 Commits

Reviewing files that changed from the base of the PR and between bcb96db and d715924.

📒 Files selected for processing (39)
  • studio/README.md
  • studio/next.config.mjs
  • studio/sentry.client.config.ts
  • studio/sentry.edge.config.ts
  • studio/src/__tests__/playground-url-state-encoding-decoding.test.ts
  • studio/src/__tests__/schema-helpers.test.ts
  • studio/src/components/analytics/useSyncTableWithQuery.ts
  • studio/src/components/member-groups/use-group-resources.ts
  • studio/src/components/playground/types.ts
  • studio/src/components/ui/use-toast.ts
  • studio/src/env.mjs
  • studio/src/hooks/use-check-user-access.ts
  • studio/src/hooks/use-event-callback.ts
  • studio/src/hooks/use-event-listener.ts
  • studio/src/hooks/use-fireworks.ts
  • studio/src/hooks/use-form.ts
  • studio/src/hooks/use-hydrate-playground-state-from-url.ts
  • studio/src/hooks/use-new-features-popup-disabled.ts
  • studio/src/hooks/use-pagination-params.ts
  • studio/src/hooks/use-session-storage.ts
  • studio/src/hooks/use-share-playground-modal.ts
  • studio/src/hooks/use-star-banner-disabled.ts
  • studio/src/hooks/use-user.ts
  • studio/src/hooks/use-workspace.ts
  • studio/src/lib/constants.ts
  • studio/src/lib/download-string-as-file.ts
  • studio/src/lib/format-date.ts
  • studio/src/lib/format-number.ts
  • studio/src/lib/format-status.ts
  • studio/src/lib/insights-helpers.ts
  • studio/src/lib/playground-storage.ts
  • studio/src/lib/playground-url-state-decoding.ts
  • studio/src/lib/playground-url-state-encoding.ts
  • studio/src/lib/schema-helpers.ts
  • studio/src/lib/signup-content.ts
  • studio/src/lib/utils.ts
  • studio/src/middleware.ts
  • studio/src/pages/cosmo-managed-solution-terms.md
  • studio/src/styles/login.css

Comment thread studio/next.config.mjs Outdated
Comment thread studio/src/components/analytics/useSyncTableWithQuery.ts Outdated
Comment thread studio/src/components/analytics/useSyncTableWithQuery.ts Outdated
Comment thread studio/src/components/member-groups/use-group-resources.ts Outdated
Comment thread studio/src/pages/cosmo-managed-solution-terms.md
Comment thread studio/src/pages/cosmo-managed-solution-terms.md
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 16.72131% with 1016 lines in your changes missing coverage. Please review.
✅ Project coverage is 1.40%. Comparing base (854661e) to head (b6310fa).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
studio/src/components/schema/monaco-dark-theme.ts 0.00% 349 Missing ⚠️
studio/src/lib/schema-helpers.ts 40.49% 72 Missing ⚠️
studio/src/hooks/use-share-playground-modal.ts 0.00% 62 Missing ⚠️
studio/tailwind.config.js 0.00% 58 Missing and 1 partial ⚠️
...rc/components/member-groups/use-group-resources.ts 0.00% 47 Missing ⚠️
studio/src/lib/insights-helpers.ts 0.00% 44 Missing and 1 partial ⚠️
studio/next.config.mjs 0.00% 41 Missing and 1 partial ⚠️
studio/src/lib/signup-content.ts 0.00% 35 Missing ⚠️
studio/src/components/playground/prettyPrint.ts 0.00% 27 Missing and 1 partial ⚠️
studio/src/lib/constants.ts 82.17% 23 Missing ⚠️
... and 52 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #2601       +/-   ##
==========================================
- Coverage   62.40%   1.40%   -61.01%     
==========================================
  Files         244     296       +52     
  Lines       25775   47245    +21470     
  Branches        0     432      +432     
==========================================
- Hits        16085     662    -15423     
- Misses       8314   46297    +37983     
+ Partials     1376     286     -1090     
Files with missing lines Coverage Δ
studio/src/components/playground/types.ts 100.00% <100.00%> (ø)
studio/src/lib/playground-url-state-decoding.ts 91.66% <100.00%> (ø)
studio/src/lib/playground-url-state-encoding.ts 71.11% <100.00%> (ø)
studio/src/hooks/use-current-organization.ts 0.00% <0.00%> (ø)
studio/src/hooks/use-feature-limit.ts 0.00% <0.00%> (ø)
studio/src/hooks/use-subgraph.ts 0.00% <0.00%> (ø)
studio/src/hooks/use-subscription.ts 0.00% <0.00%> (ø)
studio/src/lib/format-number.ts 0.00% <0.00%> (ø)
studio/src/hooks/use-current-plan.ts 0.00% <0.00%> (ø)
studio/src/hooks/use-feature.ts 0.00% <0.00%> (ø)
... and 55 more

... and 475 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread studio/src/components/playground/types.ts Outdated
Copy link
Copy Markdown
Member

@Aenimus Aenimus left a comment

Choose a reason for hiding this comment

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

Please can we check why these files are changing to double quotations rather than single?

@comatory comatory requested a review from Aenimus March 9, 2026 11:28
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
studio/src/components/analytics/defaultFilterFunction.ts (1)

35-52: ⚠️ Potential issue | 🟠 Major

Use includes() instead of indexOf() to properly check operator membership.

The indexOf() call returns -1 when the operator is not found in the array, and -1 is truthy in JavaScript, so if (-1) executes. This causes the simple comparison operators (EQUALS, NOT_EQUALS, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN_OR_EQUAL) to have their comparison results overwritten by isFiltered = true on line 51. The exception is CONTAINS (index 0), which is falsy and accidentally skipped. Use Array.prototype.includes(), which returns a boolean, to properly gate the server-handled operators.

🐛 Proposed fix
    if (
      [
        AnalyticsViewFilterOperator.CONTAINS,
        AnalyticsViewFilterOperator.NOT_CONTAINS,
        AnalyticsViewFilterOperator.IN,
        AnalyticsViewFilterOperator.NOT_IN,
        AnalyticsViewFilterOperator.BETWEEN,
        AnalyticsViewFilterOperator.NOT_BETWEEN,
        AnalyticsViewFilterOperator.IS_NULL,
        AnalyticsViewFilterOperator.IS_NOT_NULL,
-     ].indexOf(filterOption.operator)
+     ].includes(filterOption.operator)
    ) {
      // complex filter operations - let server handle it
      isFiltered = true;
    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@studio/src/components/analytics/defaultFilterFunction.ts` around lines 35 -
52, Replace the truthy indexOf check with a boolean membership check: in the
condition that currently uses [...].indexOf(filterOption.operator) (inside
defaultFilterFunction / the block that sets isFiltered based on
AnalyticsViewFilterOperator values), use Array.prototype.includes to test
membership (e.g., [...].includes(filterOption.operator)) so the condition
correctly evaluates to true only when the operator is one of the server-handled
operators and does not accidentally override earlier isFiltered assignments.
studio/src/hooks/use-hydrate-playground-state-from-url.ts (1)

107-114: ⚠️ Potential issue | 🟠 Major

Persist the script type when hydrating the selected operation scripts.

setPreOpSelected and setPostOpSelected now store the raw URL payload, but studio/src/components/playground/custom-scripts.tsx treats the selected entries as PlaygroundScript and later routes updates via script.type. Hydrating without 'pre-operation' / 'post-operation' leaves that state incomplete and can send later edits down an undefined key.

🧩 Proposed fix
       if (preOperation) {
         updated[newTabId]['pre-operation'] = preOperation;
-        setPreOpSelected(preOperation);
+        setPreOpSelected({ ...preOperation, type: 'pre-operation' });
       }

       if (postOperation) {
         updated[newTabId]['post-operation'] = postOperation;
-        setPostOpSelected(postOperation);
+        setPostOpSelected({ ...postOperation, type: 'post-operation' });
       }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@studio/src/hooks/use-hydrate-playground-state-from-url.ts` around lines 107 -
114, When hydrating selected operation scripts, the code calls setPreOpSelected
and setPostOpSelected with the raw URL payload but does not include the script
"type", causing components like custom-scripts.tsx to later access script.type
and fail; update the hydration to store a full PlaygroundScript-shaped object
for pre-operation and post-operation (i.e., include the "type" field matching
'pre-operation' / 'post-operation' and any other required PlaygroundScript
properties) when assigning updated[newTabId]['pre-operation'] and
updated[newTabId]['post-operation'] and before calling setPreOpSelected /
setPostOpSelected so the selected state contains the expected type key.
🧹 Nitpick comments (3)
studio/src/lib/track.ts (1)

7-12: Consider removing dead code: window.ko declaration.

The ko: any declaration on line 9 is unused. Based on learnings, all references to window.ko (Koala tracking) should be removed as it is no longer used. This will clean up the file and reduce potential confusion.

♻️ Proposed fix to remove dead code
 declare global {
   interface Window {
-    ko: any;
     Reo: any;
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@studio/src/lib/track.ts` around lines 7 - 12, Remove the dead Koala tracking
declaration by deleting the `ko: any` entry from the global Window interface and
any corresponding references to `window.ko` in this module; specifically edit
the `declare global { interface Window { ... } }` block to drop `ko: any` and
search for/remove usages of `window.ko` (or plain `ko`) in functions or exports
in this file such as anything in track.ts that references Koala tracking so the
code no longer declares or references the unused symbol.
studio/src/lib/schema-helpers.ts (1)

796-803: Regex escaping appears adequate, but consider alternative.

The static analysis tool flags potential ReDoS risk at line 799. The current escaping approach (replaceAll(/[^_0-9A-Za-z]/g, ...)) should mitigate this by escaping special regex characters. However, for clearer intent and safety, consider using a dedicated regex escape utility.

♻️ Optional: Use explicit regex escape pattern
 function isMatch(sourceText: string, searchValue: string): boolean {
   try {
-    const escaped = searchValue.replaceAll(/[^_0-9A-Za-z]/g, (ch) => '\\' + ch);
+    // Escape all regex metacharacters: \ ^ $ . | ? * + ( ) [ ] { }
+    const escaped = searchValue.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
     return sourceText.search(new RegExp(escaped, 'i')) !== -1;
   } catch {
     return sourceText.toLowerCase().includes(searchValue.toLowerCase());
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@studio/src/lib/schema-helpers.ts` around lines 796 - 803, The isMatch
function uses a custom replaceAll to escape regex metacharacters which triggered
a ReDoS warning; replace this with a dedicated, well-known regex-escaping
utility or a small deterministic escape function (e.g. escapeRegExp that
replaces all characters in the class [.*+?^${}()|[\]\\] with a backslash) and
use its output to build new RegExp(escaped, 'i'); update isMatch to call that
escape function (and you can remove the broad try/catch or keep it as a
fallback) so escaping intent is explicit and safer.
studio/src/hooks/use-share-playground-modal.ts (1)

164-176: Keep the setSelectedOptions updater pure.

React can invoke state updaters more than once in Strict Mode. Calling generateShareableUrl from inside the updater makes this callback impure and can duplicate the state updates/toasts in development. Regenerate from an effect or after computing the next options object outside setSelectedOptions, then verify the toggle flow under React 18 Strict Mode.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@studio/src/hooks/use-share-playground-modal.ts` around lines 164 - 176,
handleOptionChange currently calls generateShareableUrl from inside the
setSelectedOptions updater, making the updater impure; change it so you compute
the next options object (e.g., const updated = { ...selectedOptions, [id]:
!!checked } or derive it outside the updater), then call
setSelectedOptions(updated) and invoke generateShareableUrl(updated) only after
(or move the share URL generation into a useEffect that watches
selectedOptions), ensuring the setSelectedOptions updater remains a pure
function; update references to handleOptionChange, setSelectedOptions, and
generateShareableUrl accordingly and verify behavior under React 18 Strict Mode.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@studio/src/hooks/use-share-playground-modal.ts`:
- Around line 127-135: The catch block in use-share-playground-modal leaves
stale values in shareableUrl and warning after a failed generate, so reset the
cached share state there: inside the catch for the URL generation in the
useSharePlaygroundModal hook, clear/reset shareableUrl and warning (and
optionally isGenerating) back to their initial/empty values so the modal won’t
show an outdated link after an error; locate the variables shareableUrl and
warning in the hook and set them to undefined/empty in the catch before/after
showing the toast.

---

Outside diff comments:
In `@studio/src/components/analytics/defaultFilterFunction.ts`:
- Around line 35-52: Replace the truthy indexOf check with a boolean membership
check: in the condition that currently uses [...].indexOf(filterOption.operator)
(inside defaultFilterFunction / the block that sets isFiltered based on
AnalyticsViewFilterOperator values), use Array.prototype.includes to test
membership (e.g., [...].includes(filterOption.operator)) so the condition
correctly evaluates to true only when the operator is one of the server-handled
operators and does not accidentally override earlier isFiltered assignments.

In `@studio/src/hooks/use-hydrate-playground-state-from-url.ts`:
- Around line 107-114: When hydrating selected operation scripts, the code calls
setPreOpSelected and setPostOpSelected with the raw URL payload but does not
include the script "type", causing components like custom-scripts.tsx to later
access script.type and fail; update the hydration to store a full
PlaygroundScript-shaped object for pre-operation and post-operation (i.e.,
include the "type" field matching 'pre-operation' / 'post-operation' and any
other required PlaygroundScript properties) when assigning
updated[newTabId]['pre-operation'] and updated[newTabId]['post-operation'] and
before calling setPreOpSelected / setPostOpSelected so the selected state
contains the expected type key.

---

Nitpick comments:
In `@studio/src/hooks/use-share-playground-modal.ts`:
- Around line 164-176: handleOptionChange currently calls generateShareableUrl
from inside the setSelectedOptions updater, making the updater impure; change it
so you compute the next options object (e.g., const updated = {
...selectedOptions, [id]: !!checked } or derive it outside the updater), then
call setSelectedOptions(updated) and invoke generateShareableUrl(updated) only
after (or move the share URL generation into a useEffect that watches
selectedOptions), ensuring the setSelectedOptions updater remains a pure
function; update references to handleOptionChange, setSelectedOptions, and
generateShareableUrl accordingly and verify behavior under React 18 Strict Mode.

In `@studio/src/lib/schema-helpers.ts`:
- Around line 796-803: The isMatch function uses a custom replaceAll to escape
regex metacharacters which triggered a ReDoS warning; replace this with a
dedicated, well-known regex-escaping utility or a small deterministic escape
function (e.g. escapeRegExp that replaces all characters in the class
[.*+?^${}()|[\]\\] with a backslash) and use its output to build new
RegExp(escaped, 'i'); update isMatch to call that escape function (and you can
remove the broad try/catch or keep it as a fallback) so escaping intent is
explicit and safer.

In `@studio/src/lib/track.ts`:
- Around line 7-12: Remove the dead Koala tracking declaration by deleting the
`ko: any` entry from the global Window interface and any corresponding
references to `window.ko` in this module; specifically edit the `declare global
{ interface Window { ... } }` block to drop `ko: any` and search for/remove
usages of `window.ko` (or plain `ko`) in functions or exports in this file such
as anything in track.ts that references Koala tracking so the code no longer
declares or references the unused symbol.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 880b3e23-972e-43d5-b630-dd49072ee677

📥 Commits

Reviewing files that changed from the base of the PR and between d715924 and 87df8b3.

📒 Files selected for processing (73)
  • studio/next.config.mjs
  • studio/prettier.config.js
  • studio/sentry.client.config.ts
  • studio/sentry.edge.config.ts
  • studio/sentry.server.config.ts
  • studio/src/__tests__/lint-page.test.ts
  • studio/src/__tests__/playground-url-state-encoding-decoding.test.ts
  • studio/src/__tests__/schema-helpers.test.ts
  • studio/src/components/analytics/constructAnalyticsTableQueryState.ts
  • studio/src/components/analytics/defaultFilterFunction.ts
  • studio/src/components/analytics/getDataTableFilters.ts
  • studio/src/components/analytics/useAnalyticsQueryState.ts
  • studio/src/components/analytics/useSyncTableWithQuery.ts
  • studio/src/components/checks/use-open-usage.ts
  • studio/src/components/member-groups/use-group-resources.ts
  • studio/src/components/playground/prettyPrint.ts
  • studio/src/components/playground/types.ts
  • studio/src/components/schema/monaco-dark-theme.ts
  • studio/src/components/ui/use-toast.ts
  • studio/src/env.mjs
  • studio/src/hooks/use-check-user-access.ts
  • studio/src/hooks/use-cookie-organization.ts
  • studio/src/hooks/use-cookie.ts
  • studio/src/hooks/use-current-organization.ts
  • studio/src/hooks/use-current-plan.ts
  • studio/src/hooks/use-event-callback.ts
  • studio/src/hooks/use-event-listener.ts
  • studio/src/hooks/use-feature-limit.ts
  • studio/src/hooks/use-feature.ts
  • studio/src/hooks/use-fireworks.ts
  • studio/src/hooks/use-form.ts
  • studio/src/hooks/use-hash.ts
  • studio/src/hooks/use-hydrate-playground-state-from-url.ts
  • studio/src/hooks/use-is-admin.ts
  • studio/src/hooks/use-is-creator.ts
  • studio/src/hooks/use-isomorphic-layout-effect.ts
  • studio/src/hooks/use-local-storage.ts
  • studio/src/hooks/use-new-features-popup-disabled.ts
  • studio/src/hooks/use-pagination-params.ts
  • studio/src/hooks/use-resolved-theme.ts
  • studio/src/hooks/use-roles.ts
  • studio/src/hooks/use-session-storage.ts
  • studio/src/hooks/use-share-playground-modal.ts
  • studio/src/hooks/use-star-banner-disabled.ts
  • studio/src/hooks/use-subgraph.ts
  • studio/src/hooks/use-subscription.ts
  • studio/src/hooks/use-user.ts
  • studio/src/hooks/use-window-size.ts
  • studio/src/hooks/use-workspace.ts
  • studio/src/instrumentation.ts
  • studio/src/lib/constants.ts
  • studio/src/lib/download-string-as-file.ts
  • studio/src/lib/format-date.ts
  • studio/src/lib/format-metric.ts
  • studio/src/lib/format-number.ts
  • studio/src/lib/format-status.ts
  • studio/src/lib/insights-helpers.ts
  • studio/src/lib/page.d.ts
  • studio/src/lib/playground-storage.ts
  • studio/src/lib/playground-url-state-decoding.ts
  • studio/src/lib/playground-url-state-encoding.ts
  • studio/src/lib/posthog.ts
  • studio/src/lib/schema-helpers.ts
  • studio/src/lib/signup-content.ts
  • studio/src/lib/stripe.ts
  • studio/src/lib/trace-utils.ts
  • studio/src/lib/track.ts
  • studio/src/lib/utils.ts
  • studio/src/pages/_error.jsx
  • studio/src/styles/globals.css
  • studio/src/styles/utils.css
  • studio/tailwind.config.js
  • studio/vitest.config.mts
✅ Files skipped from review due to trivial changes (24)
  • studio/src/hooks/use-subscription.ts
  • studio/tailwind.config.js
  • studio/src/lib/posthog.ts
  • studio/src/components/schema/monaco-dark-theme.ts
  • studio/src/hooks/use-local-storage.ts
  • studio/src/hooks/use-feature.ts
  • studio/src/hooks/use-isomorphic-layout-effect.ts
  • studio/src/hooks/use-feature-limit.ts
  • studio/src/pages/_error.jsx
  • studio/src/hooks/use-is-admin.ts
  • studio/src/hooks/use-user.ts
  • studio/src/hooks/use-subgraph.ts
  • studio/src/hooks/use-is-creator.ts
  • studio/sentry.server.config.ts
  • studio/src/tests/lint-page.test.ts
  • studio/src/components/analytics/useAnalyticsQueryState.ts
  • studio/vitest.config.mts
  • studio/src/hooks/use-current-plan.ts
  • studio/src/hooks/use-window-size.ts
  • studio/src/components/ui/use-toast.ts
  • studio/src/components/checks/use-open-usage.ts
  • studio/src/lib/format-status.ts
  • studio/src/hooks/use-cookie.ts
  • studio/src/lib/playground-storage.ts
🚧 Files skipped from review as they are similar to previous changes (14)
  • studio/src/lib/format-number.ts
  • studio/src/lib/insights-helpers.ts
  • studio/src/lib/playground-url-state-encoding.ts
  • studio/src/hooks/use-new-features-popup-disabled.ts
  • studio/src/hooks/use-workspace.ts
  • studio/src/lib/signup-content.ts
  • studio/src/lib/download-string-as-file.ts
  • studio/src/lib/constants.ts
  • studio/src/lib/playground-url-state-decoding.ts
  • studio/src/hooks/use-pagination-params.ts
  • studio/next.config.mjs
  • studio/src/hooks/use-form.ts
  • studio/src/components/analytics/useSyncTableWithQuery.ts
  • studio/src/hooks/use-fireworks.ts

Comment thread studio/src/hooks/use-share-playground-modal.ts
Copy link
Copy Markdown
Member

@Aenimus Aenimus left a comment

Choose a reason for hiding this comment

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

LGTM!

@Aenimus Aenimus enabled auto-merge (squash) March 9, 2026 12:16
@Aenimus Aenimus merged commit ea70e91 into main Mar 9, 2026
11 checks passed
@Aenimus Aenimus deleted the ondrej/eng-9087-cosmostudioci-fix-formatting-drift-enforce-formatting-in-ci-pt2 branch March 9, 2026 12:34
comatory added a commit that referenced this pull request Mar 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants