Skip to content

fix: correct NPM_TOKEN secret reference + QoL updates#152

Merged
filiphric merged 18 commits into
mainfrom
updates/updates-added-qol
Jun 28, 2026
Merged

fix: correct NPM_TOKEN secret reference + QoL updates#152
filiphric merged 18 commits into
mainfrom
updates/updates-added-qol

Conversation

@filiphric

Copy link
Copy Markdown
Owner

What

Fixes the failing e2e-tests workflow and bundles the pending QoL updates on this branch.

Why the release was failing

The latest Actions run failed at the Semantic Release step with SemanticReleaseError: Invalid npm token. Root cause: a typo in .github/workflows/tests.yml referencing the secret as secrets/NPM_TOKEN (slash) instead of secrets.NPM_TOKEN (dot), so the token resolved to empty.

Changes

  • fix: correct NPM_TOKEN secret reference in release workflow
  • Plus the accumulated feat:/fix: commits already on this branch (binary/ArrayBuffer handling, request panel tabs, config updates, etc.)

Result

Merging to main will trigger semantic-release to cut a new minor version and publish to npm.

Note: the npm token in repo secrets was last updated 2022-10-07. If the release still reports an invalid token after merge, regenerate an npm Automation token and run gh secret set NPM_TOKEN.

sclem-tylr and others added 16 commits January 7, 2026 14:41
…ce response handling

- Deleted the ESLint configuration file.

- Updated dependencies in package.json and package-lock.json, including major version upgrades for Vue, ESLint, and TypeScript-related packages.

- Refactored response handling in Cypress tests to improve validation for XML, HTML, and JSON formats.

- Enhanced the UI components to support new features like cURL generation and improved tab handling in request and response panels.

- Adjusted CSS styles for better interaction and visibility of highlighted sections.
- Implemented a new endpoint for file uploads that responds with a success message.
- Added endpoints to serve binary content and decoded binary responses.
- Enhanced response handling to support ArrayBuffer and Uint8Array types, ensuring proper formatting and size calculation for various response types.
- Updated type definitions to allow for string or object response bodies.
- Introduced a new test HTML file for Cypress fixtures.
- Expanded the response handling in the server to support ArrayBuffer and Uint8Array types, ensuring proper formatting and size calculation.
- Updated type definitions to allow for string or object response bodies, improving flexibility in handling various response formats.
…e handling

- Added a setupNodeEvents function in cypress.config.ts to manage video deletion for passing tests.
- Updated package dependencies, including cypress and commitlint packages, to their latest versions.
- Refactored response handling in various Cypress tests to improve error handling and response format detection.
- Improved the UI components for better interaction, including adjustments to the CodeBlock and RequestPanel components.
- Enhanced CSS styles for better visibility and interaction of highlighted sections.
- Lat Fixes I will add this should address most concerns.
…functionality

- Changed Cypress test assertions from 'be.visible' to 'exist' for better reliability in binary response handling.
- Moved the fallback copy to clipboard function into App.vue for improved code organization and added functionality to handle clipboard operations more effectively.
- Updated the transform module to ensure 'details' elements are opened by default for better user experience in displaying JSON structures.
- Removed error parameter from catch blocks in clipboard-related functions for cleaner code.
- Enhanced readability and maintainability of the clipboard functionality in App.vue.
…onding Cypress test

- Implemented a new POST endpoint '/json-with-commas' in the server to return a structured JSON response with commas.
- Added a Cypress test to verify that commas are correctly aligned on the same line as closing brackets and braces in both request and response bodies.
- Enhanced the transform module to ensure proper formatting of closing braces and brackets with commas in the displayed JSON.
…inary data support

- Implemented new endpoints '/arraybuffer-request' and '/arraybuffer-response' in the server to handle ArrayBuffer data in both request and response bodies.
- Enhanced Cypress tests to verify correct handling and display of ArrayBuffer content in the UI.
- Updated the transform and response handling modules to support ArrayBuffer and Blob types, ensuring proper decoding and formatting.
- Improved request body formatting to accommodate FormData and ArrayBuffer types for better data handling.
…d Cypress tests

- Added tests to verify visibility of request headers, query parameters, and request body in the RequestPanel based on the presence of corresponding data.
- Implemented logic in RequestPanel.vue to dynamically select the appropriate tab (query, headers, auth, or body) based on the content of the request.
- Introduced a MutationObserver to update the selected tab when the request panel is highlighted in the Cypress command log, improving user experience.
- Updated Vue and TypeScript dependencies to their latest versions for improved performance and compatibility.
- Added back and updated the semantic-release and standard-version for automated versioning and changelog generation.
- Enhanced the RequestPanel component to improve tab selection logic and user experience.
- Improved error handling in the server to manage port conflicts gracefully.
- Updated CSS styles for better readability and interaction in code blocks.
- Upgraded semantic-release to version 25.0.2 and standard-version to 13.1.1 for improved versioning and changelog generation.
- Updated Node.js engine requirement to >=22.14.0 in package.json and package-lock.json.
- Enhanced GitHub Actions workflow to set up Node.js version 22.14.0 for consistent CI environment.
- Improved type handling in App.vue for better integration with TypeScript.
- Added `expose` configuration options in `cypress.config.ts` to enable timeline and request mode features.
- Introduced `hideCredentials` and `testToken` environment variables for better credential management during tests.
- Updated Cypress to version 15.10.0 in `package.json` and `package-lock.json` for improved functionality.
- Enhanced README documentation to clarify usage of new features and configuration options.
- Refactored tests to utilize the new configuration methods for hiding credentials and managing request modes.
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (6) 📘 Rule violations (4) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. server/index.js adds console.error 📘 Rule violation ◔ Observability
Description
New console.error(...) statements were added to the server error handler. This violates the
requirement to avoid introducing new logging statements in this codebase.
Code

server/index.js[R232-242]

+  .on('error', (err) => {
+    if (err.code === 'EADDRINUSE') {
+      console.error(`\n❌ Port ${port} is already in use.`)
+      console.error(`   Please stop the process using port ${port} or use a different port.\n`)
+      console.error(`   To find and kill the process on Windows:`)
+      console.error(`   netstat -ano | findstr :${port}`)
+      console.error(`   taskkill /PID <PID> /F\n`)
+      process.exit(1)
+    } else {
+      console.error('Server error:', err)
+      process.exit(1)
Evidence
PR Compliance ID 6548 forbids adding new logging statements. The added error handler introduces
multiple new console.error(...) calls in server/index.js.

Rule 6548: Avoid adding new logging statements in this codebase
server/index.js[232-242]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New `console.error(...)` logging statements were introduced in `server/index.js`, which violates the compliance requirement to avoid adding new logging statements.
## Issue Context
The PR adds an `.on('error', ...)` handler that prints multiple error messages to the console.
## Fix Focus Areas
- server/index.js[232-242]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. copyCurl.cy.ts adds cy.log ✓ Resolved 📘 Rule violation ◔ Observability
Description
New cy.log(...) debug logging statements were added to the Cypress test. This violates the
requirement to avoid introducing new logging statements.
Code

cypress/e2e/copyCurl.cy.ts[R705-743]

+            cy.log('Pre element textContent length:', textContent.length)
+            cy.log('Pre element textContent (first 100 chars):', textContent.substring(0, 100))
+            
+            // Find the code element inside pre (transform wraps content in <code>)
+            const codeElement = $pre[0].querySelector('code')
+            cy.log('Code element found:', !!codeElement)
+            if (codeElement) {
+              cy.log('Code element textContent length:', codeElement.textContent?.length || 0)
+            }
+            
+            // Check computed styles for user-select on pre
+            const preStyles = window.getComputedStyle($pre[0])
+            cy.log('Pre computed user-select:', preStyles.userSelect)
+            cy.log('Pre computed pointer-events:', preStyles.pointerEvents)
+            cy.log('Pre computed cursor:', preStyles.cursor)
+            
+            // Check computed styles on code element if it exists
+            if (codeElement) {
+              const codeStyles = window.getComputedStyle(codeElement)
+              cy.log('Code computed user-select:', codeStyles.userSelect)
+              cy.log('Code computed pointer-events:', codeStyles.pointerEvents)
+            }
+            
+            // Check parent element styles
+            const parent = $pre[0].parentElement
+            if (parent) {
+              const parentStyles = window.getComputedStyle(parent)
+              cy.log('Parent user-select:', parentStyles.userSelect)
+              cy.log('Parent pointer-events:', parentStyles.pointerEvents)
+              cy.log('Parent cursor:', parentStyles.cursor)
+            }
+            
+            // Check if section is highlighted
+            const section = $pre[0].closest('section')
+            if (section) {
+              cy.log('Section has __cypress-highlight:', section.classList.contains('__cypress-highlight'))
+              const sectionStyles = window.getComputedStyle(section)
+              cy.log('Section cursor:', sectionStyles.cursor)
+              cy.log('Section pointer-events:', sectionStyles.pointerEvents)
Evidence
PR Compliance ID 6548 requires no new logging statements. The added test code includes multiple new
cy.log(...) calls (e.g., logging text lengths and computed styles).

Rule 6548: Avoid adding new logging statements in this codebase
cypress/e2e/copyCurl.cy.ts[705-743]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new Cypress test introduces multiple `cy.log(...)` statements, which are new logging statements and violate the compliance rule.
## Issue Context
These logs appear to be debugging output (text lengths, computed styles, selection state) and are not required for the test assertions.
## Fix Focus Areas
- cypress/e2e/copyCurl.cy.ts[705-743]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Hard-coded colors in style.css 📘 Rule violation ⚙ Maintainability
Description
New hard-coded color values (rgba(...) / rgb(...)) were added in src/style.css instead of
using semantic design-system tokens. This violates the requirement to avoid hard-coded UI colors.
Code

src/style.css[R20-37]

+  outline: 3px solid rgba(59, 130, 246, 0.6) !important;
+  outline-offset: 2px !important;
+  opacity: 1 !important;
+  pointer-events: auto !important;
}
+.__cypress-highlight:not(section),
+.__cypress-highlight [data-cy],
+.__cypress-highlight [data-cy] *,
+.__cypress-highlight pre,
+.__cypress-highlight div[data-cy] {
+  outline: none !important;
+}
+
+section.__cypress-highlight {
+  pointer-events: auto !important;
+  cursor: pointer;
+  background-color: rgba(255, 255, 255, 0.1) !important;
Evidence
PR Compliance ID 6640 requires semantic color tokens instead of hard-coded colors. The changed CSS
adds several rgba(...) and rgb(...) literals for outlines, backgrounds, scrollbars, and syntax
highlighting colors.

Rule 6640: Use design-system semantic color tokens instead of hard-coded colors
src/style.css[20-21]
src/style.css[37-37]
src/style.css[303-314]
src/style.css[345-360]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/style.css` introduces multiple hard-coded color literals (e.g., `rgba(...)`, `rgb(...)`) which should be replaced by the project’s semantic color tokens.
## Issue Context
The stylesheet otherwise uses semantic Tailwind tokens like `bg-cy-*` / `text-cy-*`, but these new rules bypass them via raw RGB/RGBA values.
## Fix Focus Areas
- src/style.css[20-21]
- src/style.css[37-37]
- src/style.css[303-314]
- src/style.css[345-360]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (9)
4. cURL leaks masked secrets 🐞 Bug ⛨ Security
Description
handleResponse() exposes a generated cURL string in Cypress.log().consoleProps() built from the
original request options (headers/body/url), bypassing anonymize() which only masks props[index]
when hideCredentials is enabled. This can contradict the expected hideCredentials behavior and leak
secrets (e.g., cy.env()-sourced tokens) into Command Log console props, including CI artifacts or
shared debugging sessions.
Code

src/modules/handleResponse.ts[R192-216]

+      const generateCurl = () => {
+        let curl = `curl -X ${options.method || 'GET'} "${options.url}"`;
+        if (options.headers) {
+          Object.entries(options.headers).forEach(([key, value]) => {
+            curl += ` -H "${key}: ${value}"`;
+          });
+        }
+        if (options.body) {
+          if (typeof options.body === 'object') {
+            curl += ` -d '${JSON.stringify(options.body)}'`;
+          } else {
+            curl += ` -d '${options.body}'`;
+          }
+        }
+        return curl;
+      };
+
    log.set({
      consoleProps() {
        return {
-            yielded
+            yielded,
+            cURL: generateCurl()
        }
      }
    })
Evidence
The code path applies masking only to the RequestProps copy (props[index]) via anonymize() when
hideCredentials is enabled, but handleResponse() separately generates and logs a cURL string using
the original, unmasked options (including headers/body/url) in Cypress.log().consoleProps(). Because
consoleProps is derived from raw options rather than the already-anonymized props structure,
sensitive values can still be emitted despite the UI props appearing masked, creating a mismatch
between the advertised hideCredentials behavior and what is actually logged.

src/modules/api.ts[12-23]
src/utils/anonymize.ts[10-59]
src/modules/handleResponse.ts[192-216]
src/utils/generateCurl.ts[3-57]
src/modules/api.ts[14-23]
src/utils/anonymize.ts[10-61]
src/modules/handleResponse.ts[188-216]
cypress.config.ts[13-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`handleResponse()` adds a `cURL` entry to `consoleProps()` by generating it from the original, unmasked `options` (headers/body/url). Since `hideCredentials` masking is applied only to `props[index]` via `anonymize()`, secrets can still appear in the Cypress Command Log console props even when credentials are expected to be hidden.
## Issue Context
- Masking is currently applied only to `props[index]` (RequestProps) through `anonymize()` when `hideCredentials` is enabled; `options` (ApiRequestOptions) retains the original sensitive values.
- `handleResponse()` should emit cURL derived from already-masked data (`props[index]`) or a masked clone, otherwise console output can leak tokens in CI artifacts or shared debugging sessions.
- The repo already has a shared `src/utils/generateCurl.ts` helper that generates cURL from `RequestProps` (the masked structure), and it should be reused rather than duplicating options-based generation.
## Fix Focus Areas
- src/modules/handleResponse.ts[188-216]
- src/modules/api.ts[12-23]
- src/utils/generateCurl.ts[1-58]
- src/utils/anonymize.ts[10-59]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Unescaped plaintext HTML output ✓ Resolved 🐞 Bug ⛨ Security
Description
When Prism has no grammar for the requested language (notably plaintext), transform() falls back
to returning ... with raw, unescaped content, so attacker-controlled request/response text can
be interpreted as HTML when rendered (via v-html) in the Cypress runner UI. Because only
json/markup Prism components are imported while callers frequently format as plaintext, this can
break rendering and create an XSS vector in panels like the command log/cURL output.
Code

src/modules/transform.ts[R153-162]

+  if (content) {
+    let prismLanguageName: string = language
+    if (language === 'html' || language === 'xml') {
+      prismLanguageName = 'markup'
+    }
+    
+    const prismLanguage = Prism.languages[prismLanguageName]
+    if (!prismLanguage) {
+      return `<code class="language-plaintext">${content}</code>`
+    }
Evidence
The cited behavior comes from transform() having a fallback path when
Prism.languages[prismLanguageName] is missing that directly interpolates ${content} into a ``
wrapper without HTML-escaping, meaning any HTML-like text in content becomes real markup on
render. The risk is amplified by the fact that only prism-json and prism-markup are imported,
while multiple call sites pass plaintext (including cURL rendering and response fallbacks such as
application/octet-stream), making it likely the unescaped fallback is exercised; when Prism
highlighting does run it typically encodes output, but this fallback bypasses that safety, enabling
injection in the Cypress runner UI where the formatted output is rendered with v-html.

src/modules/transform.ts[1-4]
src/modules/transform.ts[153-162]
src/modules/handleResponse.ts[120-143]
src/components/RequestPanel.vue[129-153]
src/modules/transform.ts[153-163]
src/components/RequestPanel.vue[144-153]
src/modules/handleResponse.ts[137-142]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`transform()` has a fallback branch for when `Prism.languages[prismLanguageName]` is missing (commonly hit for `plaintext`), but it returns `<code>...</code>` containing raw, unescaped `content`. Because the UI renders this formatted output using `v-html`, attacker-controlled request/response text can be interpreted as HTML (or scripts), breaking rendering and creating an XSS vector inside the Cypress runner UI.
## Issue Context
- Only `prism-json` and `prism-markup` are imported, yet multiple call sites request `transform(..., 'plaintext')`.
- `plaintext` is used for cURL rendering and for some response bodies (e.g., `application/octet-stream`).
- Prism highlighting is generally HTML-safe when it runs, but the missing-grammar fallback bypasses that safety by interpolating `content` directly into HTML.
- Add regression coverage to pin the rendering contract (e.g., ensure strings like `"</code><script>alert(1)</script>"` render as text, not markup).
## Fix Focus Areas
- src/modules/transform.ts[1-4]
- src/modules/transform.ts[153-163]
- src/modules/handleResponse.ts[120-143]
- src/components/RequestPanel.vue[129-153]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Deprecated checkout action 🧑 Team insight ☼ Reliability
Description
**Inspired by shay-qodo's coding and review patterns** — The workflow still uses
actions/checkout@v2, which is deprecated and can fail due to older Node runtime deprecations on
GitHub-hosted runners. This undermines the stated goal of fixing the failing workflow and can
re-break CI unexpectedly.
Code

.github/workflows/tests.yml[R11-13]

    - name: Checkout
      uses: actions/checkout@v2
    - name: Cypress run
Evidence
The workflow uses a deprecated checkout major. Shay-qodo prioritizes production/operational
reliability and would flag CI dependencies that can fail due to upstream deprecations, especially in
a PR intended to unbreak releases.

.github/workflows/tests.yml[7-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`actions/checkout@v2` is deprecated/EOL and may stop working on modern GitHub runner environments.
### Issue Context
This PR is explicitly about fixing the workflow; leaving a deprecated core action is a reliability risk.
### Fix Focus Areas
- .github/workflows/tests.yml[7-13]
### Suggested fix
Update:
- `uses: actions/checkout@v2` → `uses: actions/checkout@v4`
(Optionally) also consider bumping other actions to current major versions if you see warnings in Actions logs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Unescaped plaintext HTML output ✓ Resolved 🐞 Bug ⛨ Security
Description
When Prism has no grammar for the requested language (notably plaintext), transform() falls back
to returning ... with raw, unescaped content, so attacker-controlled request/response text can
be interpreted as HTML when rendered (via v-html) in the Cypress runner UI. Because only
json/markup Prism components are imported while callers frequently format as plaintext, this can
break rendering and create an XSS vector in panels like the command log/cURL output.
Code

src/modules/transform.ts[R153-162]

+  if (content) {
+    let prismLanguageName: string = language
+    if (language === 'html' || language === 'xml') {
+      prismLanguageName = 'markup'
+    }
+    
+    const prismLanguage = Prism.languages[prismLanguageName]
+    if (!prismLanguage) {
+      return `<code class="language-plaintext">${content}</code>`
+    }
Evidence
The cited behavior comes from transform() having a fallback path when
Prism.languages[prismLanguageName] is missing that directly interpolates ${content} into a ``
wrapper without HTML-escaping, meaning any HTML-like text in content becomes real markup on
render. The risk is amplified by the fact that only prism-json and prism-markup are imported,
while multiple call sites pass plaintext (including cURL rendering and response fallbacks such as
application/octet-stream), making it likely the unescaped fallback is exercised; when Prism
highlighting does run it typically encodes output, but this fallback bypasses that safety, enabling
injection in the Cypress runner UI where the formatted output is rendered with v-html.

src/modules/transform.ts[1-4]
src/modules/transform.ts[153-162]
src/modules/handleResponse.ts[120-143]
src/components/RequestPanel.vue[129-153]
src/modules/transform.ts[153-163]
src/components/RequestPanel.vue[144-153]
src/modules/handleResponse.ts[137-142]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`transform()` has a fallback branch for when `Prism.languages[prismLanguageName]` is missing (commonly hit for `plaintext`), but it returns `<code>...</code>` containing raw, unescaped `content`. Because the UI renders this formatted output using `v-html`, attacker-controlled request/response text can be interpreted as HTML (or scripts), breaking rendering and creating an XSS vector inside the Cypress runner UI.
## Issue Context
- Only `prism-json` and `prism-markup` are imported, yet multiple call sites request `transform(..., 'plaintext')`.
- `plaintext` is used for cURL rendering and for some response bodies (e.g., `application/octet-stream`).
- Prism highlighting is generally HTML-safe when it runs, but the missing-grammar fallback bypasses that safety by interpolating `content` directly into HTML.
- Add regression coverage to pin the rendering contract (e.g., ensure strings like `"</code><script>alert(1)</script>"` render as text, not markup).
## Fix Focus Areas
- src/modules/transform.ts[1-4]
- src/modules/transform.ts[153-163]
- src/modules/handleResponse.ts[120-143]
- src/components/RequestPanel.vue[129-153]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Hard-coded colors in style.css 📘 Rule violation ⚙ Maintainability
Description
New hard-coded color values (rgba(...) / rgb(...)) were added in src/style.css instead of
using semantic design-system tokens. This violates the requirement to avoid hard-coded UI colors.
Code

src/style.css[R20-37]

+  outline: 3px solid rgba(59, 130, 246, 0.6) !important;
+  outline-offset: 2px !important;
+  opacity: 1 !important;
+  pointer-events: auto !important;
}

+.__cypress-highlight:not(section),
+.__cypress-highlight [data-cy],
+.__cypress-highlight [data-cy] *,
+.__cypress-highlight pre,
+.__cypress-highlight div[data-cy] {
+  outline: none !important;
+}
+
+section.__cypress-highlight {
+  pointer-events: auto !important;
+  cursor: pointer;
+  background-color: rgba(255, 255, 255, 0.1) !important;
Evidence
PR Compliance ID 6640 requires semantic color tokens instead of hard-coded colors. The changed CSS
adds several rgba(...) and rgb(...) literals for outlines, backgrounds, scrollbars, and syntax
highlighting colors.

Rule 6640: Use design-system semantic color tokens instead of hard-coded colors
src/style.css[20-21]
src/style.css[37-37]
src/style.css[303-314]
src/style.css[345-360]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/style.css` introduces multiple hard-coded color literals (e.g., `rgba(...)`, `rgb(...)`) which should be replaced by the project’s semantic color tokens.
## Issue Context
The stylesheet otherwise uses semantic Tailwind tokens like `bg-cy-*` / `text-cy-*`, but these new rules bypass them via raw RGB/RGBA values.
## Fix Focus Areas
- src/style.css[20-21]
- src/style.css[37-37]
- src/style.css[303-314]
- src/style.css[345-360]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. cURL leaks masked secrets 🐞 Bug ⛨ Security
Description
handleResponse() exposes a generated cURL string in Cypress.log().consoleProps() built from the
original request options (headers/body/url), bypassing anonymize() which only masks props[index]
when hideCredentials is enabled. This can contradict the expected hideCredentials behavior and leak
secrets (e.g., cy.env()-sourced tokens) into Command Log console props, including CI artifacts or
shared debugging sessions.
Code

src/modules/handleResponse.ts[R192-216]

+      const generateCurl = () => {
+        let curl = `curl -X ${options.method || 'GET'} "${options.url}"`;
+        if (options.headers) {
+          Object.entries(options.headers).forEach(([key, value]) => {
+            curl += ` -H "${key}: ${value}"`;
+          });
+        }
+        if (options.body) {
+          if (typeof options.body === 'object') {
+            curl += ` -d '${JSON.stringify(options.body)}'`;
+          } else {
+            curl += ` -d '${options.body}'`;
+          }
+        }
+        return curl;
+      };
+
     log.set({
       consoleProps() {
         return {
-            yielded
+            yielded,
+            cURL: generateCurl()
         }
       }
     })
Evidence
The code path applies masking only to the RequestProps copy (props[index]) via anonymize() when
hideCredentials is enabled, but handleResponse() separately generates and logs a cURL string using
the original, unmasked options (including headers/body/url) in Cypress.log().consoleProps(). Because
consoleProps is derived from raw options rather than the already-anonymized props structure,
sensitive values can still be emitted despite the UI props appearing masked, creating a mismatch
between the advertised hideCredentials behavior and what is actually logged.

src/modules/api.ts[12-23]
src/utils/anonymize.ts[10-59]
src/modules/handleResponse.ts[192-216]
src/utils/generateCurl.ts[3-57]
src/modules/api.ts[14-23]
src/utils/anonymize.ts[10-61]
src/modules/handleResponse.ts[188-216]
cypress.config.ts[13-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`handleResponse()` adds a `cURL` entry to `consoleProps()` by generating it from the original, unmasked `options` (headers/body/url). Since `hideCredentials` masking is applied only to `props[index]` via `anonymize()`, secrets can still appear in the Cypress Command Log console props even when credentials are expected to be hidden.
## Issue Context
- Masking is currently applied only to `props[index]` (RequestProps) through `anonymize()` when `hideCredentials` is enabled; `options` (ApiRequestOptions) retains the original sensitive values.
- `handleResponse()` should emit cURL derived from already-masked data (`props[index]`) or a masked clone, otherwise console output can leak tokens in CI artifacts or shared debugging sessions.
- The repo already has a shared `src/utils/generateCurl.ts` helper that generates cURL from `RequestProps` (the masked structure), and it should be reused rather than duplicating options-based generation.
## Fix Focus Areas
- src/modules/handleResponse.ts[188-216]
- src/modules/api.ts[12-23]
- src/utils/generateCurl.ts[1-58]
- src/utils/anonymize.ts[10-59]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Deprecated checkout action 🧑 Team insight ☼ Reliability
Description
**Inspired by shay-qodo's coding and review patterns** — The workflow still uses
actions/checkout@v2, which is deprecated and can fail due to older Node runtime deprecations on
GitHub-hosted runners. This undermines the stated goal of fixing the failing workflow and can
re-break CI unexpectedly.
Code

.github/workflows/tests.yml[R11-13]

     - name: Checkout
       uses: actions/checkout@v2
     - name: Cypress run
Evidence
The workflow uses a deprecated checkout major. Shay-qodo prioritizes production/operational
reliability and would flag CI dependencies that can fail due to upstream deprecations, especially in
a PR intended to unbreak releases.

.github/workflows/tests.yml[7-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`actions/checkout@v2` is deprecated/EOL and may stop working on modern GitHub runner environments.
### Issue Context
This PR is explicitly about fixing the workflow; leaving a deprecated core action is a reliability risk.
### Fix Focus Areas
- .github/workflows/tests.yml[7-13]
### Suggested fix
Update:
- `uses: actions/checkout@v2` → `uses: actions/checkout@v4`
(Optionally) also consider bumping other actions to current major versions if you see warnings in Actions logs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. server/index.js adds console.error 📘 Rule violation ◔ Observability
Description
New console.error(...) statements were added to the server error handler. This violates the
requirement to avoid introducing new logging statements in this codebase.
Code

server/index.js[R232-242]

+  .on('error', (err) => {
+    if (err.code === 'EADDRINUSE') {
+      console.error(`\n❌ Port ${port} is already in use.`)
+      console.error(`   Please stop the process using port ${port} or use a different port.\n`)
+      console.error(`   To find and kill the process on Windows:`)
+      console.error(`   netstat -ano | findstr :${port}`)
+      console.error(`   taskkill /PID <PID> /F\n`)
+      process.exit(1)
+    } else {
+      console.error('Server error:', err)
+      process.exit(1)
Evidence
PR Compliance ID 6548 forbids adding new logging statements. The added error handler introduces
multiple new console.error(...) calls in server/index.js.

Rule 6548: Avoid adding new logging statements in this codebase
server/index.js[232-242]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New `console.error(...)` logging statements were introduced in `server/index.js`, which violates the compliance requirement to avoid adding new logging statements.
## Issue Context
The PR adds an `.on('error', ...)` handler that prints multiple error messages to the console.
## Fix Focus Areas
- server/index.js[232-242]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. copyCurl.cy.ts adds cy.log ✓ Resolved 📘 Rule violation ◔ Observability
Description
New cy.log(...) debug logging statements were added to the Cypress test. This violates the
requirement to avoid introducing new logging statements.
Code

cypress/e2e/copyCurl.cy.ts[R705-743]

+            cy.log('Pre element textContent length:', textContent.length)
+            cy.log('Pre element textContent (first 100 chars):', textContent.substring(0, 100))
+            
+            // Find the code element inside pre (transform wraps content in <code>)
+            const codeElement = $pre[0].querySelector('code')
+            cy.log('Code element found:', !!codeElement)
+            if (codeElement) {
+              cy.log('Code element textContent length:', codeElement.textContent?.length || 0)
+            }
+            
+            // Check computed styles for user-select on pre
+            const preStyles = window.getComputedStyle($pre[0])
+            cy.log('Pre computed user-select:', preStyles.userSelect)
+            cy.log('Pre computed pointer-events:', preStyles.pointerEvents)
+            cy.log('Pre computed cursor:', preStyles.cursor)
+            
+            // Check computed styles on code element if it exists
+            if (codeElement) {
+              const codeStyles = window.getComputedStyle(codeElement)
+              cy.log('Code computed user-select:', codeStyles.userSelect)
+              cy.log('Code computed pointer-events:', codeStyles.pointerEvents)
+            }
+            
+            // Check parent element styles
+            const parent = $pre[0].parentElement
+            if (parent) {
+              const parentStyles = window.getComputedStyle(parent)
+              cy.log('Parent user-select:', parentStyles.userSelect)
+              cy.log('Parent pointer-events:', parentStyles.pointerEvents)
+              cy.log('Parent cursor:', parentStyles.cursor)
+            }
+            
+            // Check if section is highlighted
+            const section = $pre[0].closest('section')
+            if (section) {
+              cy.log('Section has __cypress-highlight:', section.classList.contains('__cypress-highlight'))
+              const sectionStyles = window.getComputedStyle(section)
+              cy.log('Section cursor:', sectionStyles.cursor)
+              cy.log('Section pointer-events:', sectionStyles.pointerEvents)
Evidence
PR Compliance ID 6548 requires no new logging statements. The added test code includes multiple new
cy.log(...) calls (e.g., logging text lengths and computed styles).

Rule 6548: Avoid adding new logging statements in this codebase
cypress/e2e/copyCurl.cy.ts[705-743]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new Cypress test introduces multiple `cy.log(...)` statements, which are new logging statements and violate the compliance rule.
## Issue Context
These logs appear to be debugging output (text lengths, computed styles, selection state) and are not required for the test assertions.
## Fix Focus Areas
- cypress/e2e/copyCurl.cy.ts[705-743]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

13. Expensive transform hot path ✓ Resolved 🐞 Bug ➹ Performance
Description
transform() now performs multiple full-string passes and repeated scans/replacements (including
repeated indexOf loops and substring rebuilds) for JSON folding/indent logic. Since transform() runs
for each request/response body and headers, large payloads can cause noticeable slowdowns in the
runner UI.
Code

src/modules/transform.ts[R169-205]

+    if (language === 'json' && isValidJson(content)) {
+      const openBracePattern = '<span class="token punctuation">{</span>'
+      const closeBracePattern = '<span class="token punctuation">}</span>'
+      const openBracketPattern = '<span class="token punctuation">[</span>'
+      const closeBracketPattern = '<span class="token punctuation">]</span>'
+      
+      interface TokenPosition {
+        index: number
+        type: 'openBrace' | 'closeBrace' | 'openBracket' | 'closeBracket'
+        nestingLevel: number
+      }
+      
+      const tokens: TokenPosition[] = []
+      let searchIndex = 0
+      
+      while ((searchIndex = code.indexOf(openBracePattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'openBrace', nestingLevel: 0 })
+        searchIndex += openBracePattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(closeBracePattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'closeBrace', nestingLevel: 0 })
+        searchIndex += closeBracePattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(openBracketPattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'openBracket', nestingLevel: 0 })
+        searchIndex += openBracketPattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(closeBracketPattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'closeBracket', nestingLevel: 0 })
+        searchIndex += closeBracketPattern.length
+      }
Evidence
transform() contains multiple loops and full-string transformations (including repeated indexOf
searches over the highlighted HTML) and is invoked for request/response bodies and headers in the
normal cy.api() flow, so its cost directly impacts the runner UI for large payloads.

src/modules/transform.ts[23-145]
src/modules/transform.ts[169-205]
src/modules/handleResponse.ts[120-165]
src/modules/transformData.ts[5-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The updated `transform()` implementation does substantial extra work per render (splits/maps/joins, brace alignment passes, repeated `indexOf` scans, and large string rebuilds). Because `transform()` is called for request/response bodies and headers on every `cy.api()`, large responses can degrade UI responsiveness.
### Issue Context
This is most impactful on large JSON bodies where the folding/brace matching logic runs over the full highlighted HTML string.
### Fix
- Add a size-based guard (e.g., `if (content.length > N)`) to skip folding/brace matching and only do basic syntax highlighting.
- Consider making folding optional (config flag) or lazy (only compute when user opens the JSON view).
- Avoid repeated `indexOf` scans by doing a single pass parse of the highlighted output (or avoid post-processing highlighted HTML altogether).
### Fix Focus Areas
- src/modules/transform.ts[23-145]
- src/modules/transform.ts[169-305]
- src/modules/handleResponse.ts[120-165]
- src/modules/transformData.ts[5-113]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. Octet-stream parsers conflict 🧑 Team insight ≡ Correctness
Description
**Inspired by shay-qodo's coding and review patterns** — The server registers both express.text()
and express.raw() for application/octet-stream, so the first middleware will consume the body
and the later one won’t run. This makes /arraybuffer-request behavior inconsistent (e.g.,
Buffer.isBuffer(req.body) may never be true) and can lead to flaky/incorrect binary tests.
Code

server/index.js[R9-12]

+app.use(express.json({ limit: '10mb' }));
+app.use(express.urlencoded({ extended: true, limit: '10mb' }));
+app.use(express.text({ type: 'application/octet-stream', limit: '10mb' }));
+app.use(express.raw({ type: 'application/octet-stream', limit: '10mb' }));
Evidence
The middleware order makes octet-stream request parsing non-deterministic for the intended route
logic. Shay-qodo is reliability-oriented and typically flags subtle runtime-shape hazards that cause
flaky behavior under real execution.

server/index.js[8-13]
server/index.js[159-195]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`express.text({ type: 'application/octet-stream' })` and `express.raw({ type: 'application/octet-stream' })` are both registered. Express will pick the first matching parser, so the second is effectively dead, and `req.body` shape becomes surprising.
### Issue Context
`/arraybuffer-request` branches on `Buffer.isBuffer(req.body)` and other binary shapes; having the body coerced to string by `express.text()` breaks that contract.
### Fix Focus Areas
- server/index.js[8-13]
- server/index.js[159-195]
### Suggested fix
- Prefer **only** `express.raw({ type: 'application/octet-stream' })` for octet-stream, and decode inside the route when you want text.
- If you need both, scope parsers per-route (attach middleware on the specific route) or use different `type` matchers so they don’t overlap.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. Expensive transform hot path ✓ Resolved 🐞 Bug ➹ Performance
Description
transform() now performs multiple full-string passes and repeated scans/replacements (including
repeated indexOf loops and substring rebuilds) for JSON folding/indent logic. Since transform() runs
for each request/response body and headers, large payloads can cause noticeable slowdowns in the
runner UI.
Code

src/modules/transform.ts[R169-205]

+    if (language === 'json' && isValidJson(content)) {
+      const openBracePattern = '<span class="token punctuation">{</span>'
+      const closeBracePattern = '<span class="token punctuation">}</span>'
+      const openBracketPattern = '<span class="token punctuation">[</span>'
+      const closeBracketPattern = '<span class="token punctuation">]</span>'
+      
+      interface TokenPosition {
+        index: number
+        type: 'openBrace' | 'closeBrace' | 'openBracket' | 'closeBracket'
+        nestingLevel: number
+      }
+      
+      const tokens: TokenPosition[] = []
+      let searchIndex = 0
+      
+      while ((searchIndex = code.indexOf(openBracePattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'openBrace', nestingLevel: 0 })
+        searchIndex += openBracePattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(closeBracePattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'closeBrace', nestingLevel: 0 })
+        searchIndex += closeBracePattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(openBracketPattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'openBracket', nestingLevel: 0 })
+        searchIndex += openBracketPattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(closeBracketPattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'closeBracket', nestingLevel: 0 })
+        searchIndex += closeBracketPattern.length
+      }
Evidence
transform() contains multiple loops and full-string transformations (including repeated indexOf
searches over the highlighted HTML) and is invoked for request/response bodies and headers in the
normal cy.api() flow, so its cost directly impacts the runner UI for large payloads.

src/modules/transform.ts[23-145]
src/modules/transform.ts[169-205]
src/modules/handleResponse.ts[120-165]
src/modules/transformData.ts[5-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The updated `transform()` implementation does substantial extra work per render (splits/maps/joins, brace alignment passes, repeated `indexOf` scans, and large string rebuilds). Because `transform()` is called for request/response bodies and headers on every `cy.api()`, large responses can degrade UI responsiveness.
### Issue Context
This is most impactful on large JSON bodies where the folding/brace matching logic runs over the full highlighted HTML string.
### Fix
- Add a size-based guard (e.g., `if (content.length > N)`) to skip folding/brace matching and only do basic syntax highlighting.
- Consider making folding optional (config flag) or lazy (only compute when user opens the JSON view).
- Avoid repeated `indexOf` scans by doing a single pass parse of the highlighted output (or avoid post-processing highlighted HTML altogether).
### Fix Focus Areas
- src/modules/transform.ts[23-145]
- src/modules/transform.ts[169-305]
- src/modules/handleResponse.ts[120-165]
- src/modules/transformData.ts[5-113]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
16. Octet-stream parsers conflict 🧑 Team insight ≡ Correctness
Description
**Inspired by shay-qodo's coding and review patterns** — The server registers both express.text()
and express.raw() for application/octet-stream, so the first middleware will consume the body
and the later one won’t run. This makes /arraybuffer-request behavior inconsistent (e.g.,
Buffer.isBuffer(req.body) may never be true) and can lead to flaky/incorrect binary tests.
Code

server/index.js[R9-12]

+app.use(express.json({ limit: '10mb' }));
+app.use(express.urlencoded({ extended: true, limit: '10mb' }));
+app.use(express.text({ type: 'application/octet-stream', limit: '10mb' }));
+app.use(express.raw({ type: 'application/octet-stream', limit: '10mb' }));
Evidence
The middleware order makes octet-stream request parsing non-deterministic for the intended route
logic. Shay-qodo is reliability-oriented and typically flags subtle runtime-shape hazards that cause
flaky behavior under real execution.

server/index.js[8-13]
server/index.js[159-195]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`express.text({ type: 'application/octet-stream' })` and `express.raw({ type: 'application/octet-stream' })` are both registered. Express will pick the first matching parser, so the second is effectively dead, and `req.body` shape becomes surprising.
### Issue Context
`/arraybuffer-request` branches on `Buffer.isBuffer(req.body)` and other binary shapes; having the body coerced to string by `express.text()` breaks that contract.
### Fix Focus Areas
- server/index.js[8-13]
- server/index.js[159-195]
### Suggested fix
- Prefer **only** `express.raw({ type: 'application/octet-stream' })` for octet-stream, and decode inside the route when you want text.
- If you need both, scope parsers per-route (attach middleware on the specific route) or use different `type` matchers so they don’t overlap.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@cypress

cypress Bot commented Jun 27, 2026

Copy link
Copy Markdown

cypress-plugin-api    Run #205

Run Properties:  status check passed Passed #205  •  git commit 3db842f3de: Merge remote-tracking branch 'origin/main' into updates/updates-added-qol
Project cypress-plugin-api
Branch Review updates/updates-added-qol
Run status status check passed Passed #205
Run duration 01m 20s
Commit git commit 3db842f3de: Merge remote-tracking branch 'origin/main' into updates/updates-added-qol
Committer Filip Hric
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 91
View all changes introduced in this branch ↗︎

@qodo-for-filiphric

qodo-for-filiphric Bot commented Jun 27, 2026

Copy link
Copy Markdown

PR Summary by Qodo

fix: correct NPM_TOKEN secret reference + QoL updates (v2.12.0)
🐞 Bug fix ✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

Description

• Fix NPM_TOKEN secret reference so Semantic Release receives a non-empty token.
• Add request-panel cURL tab + clipboard copy on highlighted request sections.
• Improve binary (ArrayBuffer/Uint8Array/FormData/Blob) request/response handling and formatting.
• Upgrade toolchain (Cypress/Vue/Vite/TS/ESLint) and expand E2E coverage.
Diagram

graph TD
    CI["CI workflow"] --> SR["Semantic Release"] --> NPM["npm publish"]

    API["cy.api() entry"] --> INIT["initialize.ts"] --> HR["handleResponse.ts"] --> TR["transform.ts"] --> UI["Vue UI"]
    INIT --> TD["transformData.ts"] --> TR
    HR --> ANON["anonymize.ts"]
    INIT --> PC["pluginConfig.ts"]
    HR --> PC
    ANON --> PC
    UI --> GC["generateCurl.ts"]

    subgraph Legend
      direction LR
      _cfg["CI/Config"] ~~~ _core(["Core module"]) ~~~ _ui["UI"]
    end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Add explicit 'Copy cURL' button in the cURL tab
  • ➕ More discoverable than highlight-click behavior
  • ➕ Avoids global capture-phase click handler and highlight coupling
  • ➕ Reduces risk of accidental clipboard writes
  • ➖ Adds UI chrome and needs styling/spacing decisions
  • ➖ Doesn’t leverage Cypress time-travel highlight interaction
2. Keep using Cypress.env() only (no pluginConfig abstraction)
  • ➕ Less code and fewer moving parts
  • ➖ Cypress 15.10+ introduces expose-based plugin config; env() is deprecated for this use case
  • ➖ Cypress.env() is unreliable for config set during a test run, motivating the runtime store
3. Use a dedicated binary viewer/download link for octet-stream responses
  • ➕ Clearer UX for true binary payloads
  • ➕ Avoids potentially misleading text decoding
  • ➖ More UI/feature complexity; current decoding is sufficient for test-server use cases

Recommendation: Given Cypress 15.10+ config changes, the pluginConfig abstraction is the right long-term direction. The cURL feature’s highlight-click copy is a pragmatic solution for the Cypress iframe/clipboard constraints and aligns with time-travel workflows, but reviewers should double-check that the capture-phase handler + MutationObserver cannot interfere with normal panel interaction and that masking (hideCredentials) applies consistently to cURL output.

Files changed (54) +4225 / -409

Enhancement (9) +1050 / -73
index.jsExpand test server for binary/upload and edge-case payloads +126/-4

Expand test server for binary/upload and edge-case payloads

• Moves server to ESM import style, adds parsers for JSON/urlencoded/raw/text, and adds endpoints for file upload, binary content, ArrayBuffer request/response, and empty/nested-empty cases. Adds clearer EADDRINUSE error handling.

server/index.js

App.vueAdd data-curl + clipboard copy on highlighted request click +107/-9

Add data-curl + clipboard copy on highlighted request click

• Adds 'data-curl' attribute per request section and a global click handler that copies cURL when clicking the Cypress-highlighted section while avoiding interactive elements.

src/components/App.vue

RequestPanel.vueAdd cURL tab and robust tab selection behavior +205/-6

Add cURL tab and robust tab selection behavior

• Adds a cURL tab rendering generated curl output, moves to explicit 'selectedTab' state, and adds MutationObserver logic to switch back to the most relevant content tab when Cypress highlights a request section.

src/components/RequestPanel.vue

ResponsePanel.vueMake response tab selection stateful and data-driven +38/-3

Make response tab selection stateful and data-driven

• Adds 'selectedTab' state and initialization rules to choose between response/body/headers/cookies depending on available data; fixes cookies tab visibility for empty objects.

src/components/ResponsePanel.vue

transformData.tsHandle non-JSON request body types (binary/FormData/Blob/urlencoded) +100/-1

Handle non-JSON request body types (binary/FormData/Blob/urlencoded)

• Expands request-body transformation to decode ArrayBuffer/Uint8Array, summarize FormData/File and Blob payloads, and parse urlencoded bodies into displayable structures.

src/modules/transformData.ts

style.cssRevise highlight styling to keep sections interactive/selectable +359/-23

Revise highlight styling to keep sections interactive/selectable

• Reworks '__cypress-highlight' styling from low-opacity/non-interactive to outlined and selectable, ensuring panel interactions remain usable while supporting highlight-click cURL copy.

src/style.css

types.tsAdd Cypress.expose typings and widen responseBody type +15/-27

Add Cypress.expose typings and widen responseBody type

• Adds typings for 'Cypress.expose' and 'expose' test overrides, documents env() deprecation context, and widens 'responseBody.body' type to support string bodies from decoded binaries.

src/types.ts

generateCurl.tsAdd cURL generator utility +58/-0

Add cURL generator utility

• New utility that constructs a representative curl command from captured request details (method, url, auth, headers, query params, and body).

src/utils/generateCurl.ts

pluginConfig.tsAdd unified plugin config read/write helpers (supports Cypress.expose) +42/-0

Add unified plugin config read/write helpers (supports Cypress.expose)

• Adds 'getPluginConfig' and 'setPluginConfig' with a runtime store and fallback ordering across Cypress.expose/env/config to make plugin options reliable across Cypress versions.

src/utils/pluginConfig.ts

Bug fix (7) +553 / -98
tests.ymlFix NPM token secret reference and modernize release step +6/-1

Fix NPM token secret reference and modernize release step

• Fixes 'NPM_TOKEN' env wiring by using 'secrets.NPM_TOKEN' (dot) rather than an invalid slash reference. Upgrades semantic-release action to v4, pins semantic-release version, and adds a Node 22 setup step.

.github/workflows/tests.yml

CodeBlock.vuePrevent code-block clicks from triggering global cURL copy +19/-1

Prevent code-block clicks from triggering global cURL copy

• Stops click propagation from CodeBlock except for JSON folding '<summary>' interactions; adds special styling for the cURL block.

src/components/CodeBlock.vue

CookieTable.vueFix cookie rendering condition and empty state +33/-33

Fix cookie rendering condition and empty state

• Adjusts cookie rendering logic to handle object-based cookie storage and show a proper empty-state message when no cookies are present.

src/components/CookieTable.vue

handleResponse.tsDecode binary response bodies and improve formatting/size calc +144/-25

Decode binary response bodies and improve formatting/size calc

• Adds ArrayBuffer/Uint8Array decoding + JSON detection, improves fallback formatting, and computes size accurately for string bodies. Also adjusts URL derivation and includes a generated cURL string in Cypress consoleProps.

src/modules/handleResponse.ts

initialize.tsFix retry lifecycle (unmount + remove mount root) and use pluginConfig +22/-9

Fix retry lifecycle (unmount + remove mount root) and use pluginConfig

• Ensures retries clean up the previous Vue app/mount root to avoid stale UI. Reads snapshotOnly via 'getPluginConfig' to support Cypress.expose and runtime overrides.

src/modules/initialize.ts

transform.tsRewrite transform formatter: JSON folding correctness + markup support +298/-11

Rewrite transform formatter: JSON folding correctness + markup support

• Adds Prism markup support for HTML/XML and rewrites JSON formatting/folding logic to properly match braces/brackets, collapse empty structures, and align indentation for improved readability.

src/modules/transform.ts

anonymize.tsImprove masking rules and pull config via pluginConfig +31/-18

Improve masking rules and pull config via pluginConfig

• Uses 'getPluginConfig' for hideCredentialsOptions, expands default masked keys (token/apiKey/etc.), and makes masking header-name case-insensitive with safer value handling.

src/utils/anonymize.ts

Refactor (12) +64 / -27
TitlePanel.vueImprove URL display handling +10/-3

Improve URL display handling

• Uses a computed displayUrl fallback and adjusts styling/attributes for the readonly URL field.

src/components/TitlePanel.vue

addStyles.tsMinor addStyles adjustments +2/-2

Minor addStyles adjustments

• Small refactor to align style injection with updated project/tooling.

src/modules/addStyles.ts

api.tsSmall API module cleanup +3/-4

Small API module cleanup

• Minor updates to the API module to stay consistent with new types/behavior.

src/modules/api.ts

cloneProps.tsUpdate cloning to support expanded body types +34/-2

Update cloning to support expanded body types

• Adjusts cloning logic to handle updated request/response body shapes introduced by binary handling changes.

src/modules/cloneProps.ts

mountPlugin.tsReturn mount root for lifecycle management +4/-4

Return mount root for lifecycle management

• Updates mountPlugin to return the created root so callers can clean it up on retry/unmount flows.

src/modules/mountPlugin.ts

support.tsMinor support entry updates +5/-2

Minor support entry updates

• Small changes to plugin support wiring aligned with new config/types.

src/support.ts

calculateSize.tsRemove legacy size calculation helper +0/-2

Remove legacy size calculation helper

• Removes the old calculateSize implementation; size is now computed differently (e.g., via Blob sizing for strings).

src/utils/calculateSize.ts

getFormat.tsMinor format detection tweaks +2/-2

Minor format detection tweaks

• Small adjustments to format detection to accommodate new body/transform behavior.

src/utils/getFormat.ts

isValidHtml.tsMinor validation tweak +1/-1

Minor validation tweak

• Small update to HTML validation helper used in formatting decisions.

src/utils/isValidHtml.ts

isValidJson.tsMinor validation tweak +1/-3

Minor validation tweak

• Small update to JSON validation helper used for decode/transform decisions.

src/utils/isValidJson.ts

isValidUrl.tsMinor validation tweak +1/-1

Minor validation tweak

• Small update to URL validation helper logic.

src/utils/isValidUrl.ts

isValidXml.tsMinor validation tweak +1/-1

Minor validation tweak

• Small update to XML validation helper used in formatting decisions.

src/utils/isValidXml.ts

Tests (16) +2304 / -99
authorization.cy.tsExtend credential masking coverage (including cy.env values) +37/-41

Extend credential masking coverage (including cy.env values)

• Adds tests ensuring values loaded via 'cy.env()' are masked when 'hideCredentials' is enabled and shown when disabled. Cleans up env override usage.

cypress/e2e/authorization.cy.ts

binaryResponse.cy.tsAdd binary/ArrayBuffer response E2E coverage +344/-0

Add binary/ArrayBuffer response E2E coverage

• New suite validating UI behavior and formatting for binary and ArrayBuffer responses and related endpoints.

cypress/e2e/binaryResponse.cy.ts

copyCurl.cy.tsAdd cURL generation and clipboard behavior E2E coverage +894/-0

Add cURL generation and clipboard behavior E2E coverage

• New suite validating generated cURL output for different request types and the copy-to-clipboard behavior in the Cypress runner context.

cypress/e2e/copyCurl.cy.ts

example.jsonAdd fixture for nested Cypress config +5/-0

Add fixture for nested Cypress config

• Adds a simple JSON fixture used by the nested Cypress setup.

cypress/e2e/cypress/fixtures/example.json

commands.jsAdd commands support for nested Cypress config +25/-0

Add commands support for nested Cypress config

• Adds support commands file for nested Cypress setup.

cypress/e2e/cypress/support/commands.js

e2e.jsAdd e2e support entry for nested Cypress config +17/-0

Add e2e support entry for nested Cypress config

• Adds the nested support entrypoint used by the nested Cypress config.

cypress/e2e/cypress/support/e2e.js

formats.cy.tsHarden response-format E2E assertions and update expected styling +181/-26

Harden response-format E2E assertions and update expected styling

• Refactors tests to validate returned body content (XML/HTML/JSON) before asserting on rendered output and theme colors.

cypress/e2e/formats.cy.ts

panels.cy.tsAdd request panel visibility tests +82/-6

Add request panel visibility tests

• Adds additional coverage ensuring headers/query/body panels show expected content and disables credential masking for this suite to avoid false negatives.

cypress/e2e/panels.cy.ts

requestBody.cy.tsAdd request-body type coverage (FormData/Blob/binary) +332/-0

Add request-body type coverage (FormData/Blob/binary)

• New suite covering request-body rendering for urlencoded, FormData, Blob, ArrayBuffer, and Uint8Array inputs.

cypress/e2e/requestBody.cy.ts

requestMode.cy.tsAdjust requestMode E2E tests for config changes +11/-4

Adjust requestMode E2E tests for config changes

• Updates requestMode tests to align with new configuration/behavior.

cypress/e2e/requestMode.cy.ts

responseBody.cy.tsAdd response-body E2E suite for multiple content types +356/-0

Add response-body E2E suite for multiple content types

• New suite validating response-body rendering across JSON/XML/HTML/text and binary-like content.

cypress/e2e/responseBody.cy.ts

retries.cy.tsUpdate retry behavior tests +3/-9

Update retry behavior tests

• Adjusts retry tests to reflect new initialization/unmount behavior.

cypress/e2e/retries.cy.ts

snapshotOnly.cy.tsUpdate snapshotOnly tests for pluginConfig/expose +10/-7

Update snapshotOnly tests for pluginConfig/expose

• Aligns snapshotOnly tests with the new plugin config access patterns.

cypress/e2e/snapshotOnly.cy.ts

statuses.cy.tsMinor status test updates +4/-4

Minor status test updates

• Small E2E adjustments while keeping status coverage intact.

cypress/e2e/statuses.cy.ts

syntax.cy.tsMinor syntax highlighting test updates +2/-2

Minor syntax highlighting test updates

• Small E2E adjustments for updated Prism/transform behavior.

cypress/e2e/syntax.cy.ts

test.htmlAdd HTML fixture +1/-0

Add HTML fixture

• Adds a minimal HTML fixture used by format/binary-related tests.

cypress/fixtures/test.html

Documentation (1) +119 / -41
README.mdUpdate docs for Cypress 15.10 expose config and credential masking +119/-41

Update docs for Cypress 15.10 expose config and credential masking

• Refreshes usage docs around 'snapshotOnly', 'hideCredentials', and configuration patterns for newer Cypress versions (including 'Cypress.expose'). Expands guidance on masking secrets and mentions the cURL tab behavior.

README.md

Other (9) +135 / -71
.eslintrc.jsRemove legacy ESLint config +0/-33

Remove legacy ESLint config

• Deletes the old '.eslintrc.js' configuration in favor of ESLint 9 flat config.

.eslintrc.js

cypress.config.tsUpdate Cypress config for expose-based plugin options and CI video cleanup +28/-2

Update Cypress config for expose-based plugin options and CI video cleanup

• Adds 'expose' defaults (enableTimeline/requestMode), enables 'hideCredentials' in config env, and adds a test token for masking tests. Replaces 'videoUploadOnPasses' behavior with an 'after:spec' hook that deletes videos for passing runs.

cypress.config.ts

cypress.config.jsAdd nested Cypress config for sub-suite +9/-0

Add nested Cypress config for sub-suite

• Introduces a Cypress config file under 'cypress/e2e/' for isolated runs of nested fixtures/support files.

cypress/e2e/cypress.config.js

e2e.tsMinor Cypress support wiring tweak +1/-1

Minor Cypress support wiring tweak

• Small adjustment to support setup to match new test structure/config.

cypress/support/e2e.ts

eslint.config.jsAdd ESLint 9 flat config +44/-0

Add ESLint 9 flat config

• Introduces ESLint flat config using @eslint/js, typescript-eslint, and eslint-plugin-vue, with no-only-tests enabled and dist/server ignored.

eslint.config.js

package.jsonBump to 2.12.0, migrate to ESM, and upgrade dependencies +42/-31

Bump to 2.12.0, migrate to ESM, and upgrade dependencies

• Bumps version, sets 'type: module', updates entry points, tightens Node/Cypress requirements, upgrades Cypress/Vue/Vite/TS/ESLint ecosystem packages, and adjusts semantic-release npm config.

package.json

postcss.config.jsConvert PostCSS config to ESM export +1/-1

Convert PostCSS config to ESM export

• Switches from CommonJS 'module.exports' to 'export default' to match ESM project configuration.

postcss.config.js

shims-vue.d.tsAdjust Vue TS shims for upgraded toolchain +9/-1

Adjust Vue TS shims for upgraded toolchain

• Updates Vue typing shims to match the upgraded Vue/TypeScript environment.

src/shims-vue.d.ts

vite.config.tsAdjust bundling externals +1/-2

Adjust bundling externals

• Removes Vue from Rollup externals configuration to change bundling behavior under the upgraded Vite/Rollup toolchain.

vite.config.ts

@qodo-for-filiphric

qodo-for-filiphric Bot commented Jun 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (2)   🧑 Team insights (2)   📜 Skill insights (0)
🐞 ⛨ Security (1)
📘 ⚙ Maintainability (1) ◔ Observability (1)
🧑 ≡ Correctness (1) ☼ Reliability (1)
Context used
✅ Compliance rules (platform): 3 rules
✅ Team profiles: shay-qodo, OmriGM
Review effort: 🔍 Standard

Grey Divider


Action required

1. Unescaped plaintext HTML output ✓ Resolved 🐞 ⛨ Security
Description
When Prism has no grammar for the requested language (notably plaintext), transform() falls back
to returning <code>...</code> with raw, unescaped content, so attacker-controlled
request/response text can be interpreted as HTML when rendered (via v-html) in the Cypress runner
UI. Because only json/markup Prism components are imported while callers frequently format as
plaintext, this can break rendering and create an XSS vector in panels like the command log/cURL
output.
Code

src/modules/transform.ts[R153-162]

+  if (content) {
+    let prismLanguageName: string = language
+    if (language === 'html' || language === 'xml') {
+      prismLanguageName = 'markup'
+    }
+    
+    const prismLanguage = Prism.languages[prismLanguageName]
+    if (!prismLanguage) {
+      return `<code class="language-plaintext">${content}</code>`
+    }
Evidence
The cited behavior comes from transform() having a fallback path when
Prism.languages[prismLanguageName] is missing that directly interpolates ${content} into a
<code> wrapper without HTML-escaping, meaning any HTML-like text in content becomes real markup
on render. The risk is amplified by the fact that only prism-json and prism-markup are imported,
while multiple call sites pass plaintext (including cURL rendering and response fallbacks such as
application/octet-stream), making it likely the unescaped fallback is exercised; when Prism
highlighting does run it typically encodes output, but this fallback bypasses that safety, enabling
injection in the Cypress runner UI where the formatted output is rendered with v-html.

src/modules/transform.ts[1-4]
src/modules/transform.ts[153-162]
src/modules/handleResponse.ts[120-143]
src/components/RequestPanel.vue[129-153]
src/modules/transform.ts[153-163]
src/components/RequestPanel.vue[144-153]
src/modules/handleResponse.ts[137-142]

Teammate info & reasoning
Type safety and explicit contracts
Reason for choosing OmriGM: Best fit for the broad frontend/tooling changes (Vue components, TS modules, Vite/Cypress updates) to ensure UI behavior and test suite adjustments are correct and consistent.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`transform()` has a fallback branch for when `Prism.languages[prismLanguageName]` is missing (commonly hit for `plaintext`), but it returns `<code>...</code>` containing raw, unescaped `content`. Because the UI renders this formatted output using `v-html`, attacker-controlled request/response text can be interpreted as HTML (or scripts), breaking rendering and creating an XSS vector inside the Cypress runner UI.

## Issue Context
- Only `prism-json` and `prism-markup` are imported, yet multiple call sites request `transform(..., 'plaintext')`.
- `plaintext` is used for cURL rendering and for some response bodies (e.g., `application/octet-stream`).
- Prism highlighting is generally HTML-safe when it runs, but the missing-grammar fallback bypasses that safety by interpolating `content` directly into HTML.
- Add regression coverage to pin the rendering contract (e.g., ensure strings like `"</code><script>alert(1)</script>"` render as text, not markup).

## Fix Focus Areas
- src/modules/transform.ts[1-4]
- src/modules/transform.ts[153-163]
- src/modules/handleResponse.ts[120-143]
- src/components/RequestPanel.vue[129-153]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Hard-coded colors in style.css 📘 ⚙ Maintainability
Description
New hard-coded color values (rgba(...) / rgb(...)) were added in src/style.css instead of
using semantic design-system tokens. This violates the requirement to avoid hard-coded UI colors.
Code

src/style.css[R20-37]

+  outline: 3px solid rgba(59, 130, 246, 0.6) !important;
+  outline-offset: 2px !important;
+  opacity: 1 !important;
+  pointer-events: auto !important;
}

+.__cypress-highlight:not(section),
+.__cypress-highlight [data-cy],
+.__cypress-highlight [data-cy] *,
+.__cypress-highlight pre,
+.__cypress-highlight div[data-cy] {
+  outline: none !important;
+}
+
+section.__cypress-highlight {
+  pointer-events: auto !important;
+  cursor: pointer;
+  background-color: rgba(255, 255, 255, 0.1) !important;
Evidence
PR Compliance ID 6640 requires semantic color tokens instead of hard-coded colors. The changed CSS
adds several rgba(...) and rgb(...) literals for outlines, backgrounds, scrollbars, and syntax
highlighting colors.

Rule 6640: Use design-system semantic color tokens instead of hard-coded colors
src/style.css[20-21]
src/style.css[37-37]
src/style.css[303-314]
src/style.css[345-360]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/style.css` introduces multiple hard-coded color literals (e.g., `rgba(...)`, `rgb(...)`) which should be replaced by the project’s semantic color tokens.

## Issue Context
The stylesheet otherwise uses semantic Tailwind tokens like `bg-cy-*` / `text-cy-*`, but these new rules bypass them via raw RGB/RGBA values.

## Fix Focus Areas
- src/style.css[20-21]
- src/style.css[37-37]
- src/style.css[303-314]
- src/style.css[345-360]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. cURL leaks masked secrets 🐞 ⛨ Security
Description
handleResponse() exposes a generated cURL string in Cypress.log().consoleProps() built from the
original request options (headers/body/url), bypassing anonymize() which only masks props[index]
when hideCredentials is enabled. This can contradict the expected hideCredentials behavior and leak
secrets (e.g., cy.env()-sourced tokens) into Command Log console props, including CI artifacts or
shared debugging sessions.
Code

src/modules/handleResponse.ts[R192-216]

+      const generateCurl = () => {
+        let curl = `curl -X ${options.method || 'GET'} "${options.url}"`;
+        if (options.headers) {
+          Object.entries(options.headers).forEach(([key, value]) => {
+            curl += ` -H "${key}: ${value}"`;
+          });
+        }
+        if (options.body) {
+          if (typeof options.body === 'object') {
+            curl += ` -d '${JSON.stringify(options.body)}'`;
+          } else {
+            curl += ` -d '${options.body}'`;
+          }
+        }
+        return curl;
+      };
+
      log.set({
        consoleProps() {
          return {
-            yielded
+            yielded,
+            cURL: generateCurl()
          }
        }
      })
Evidence
The code path applies masking only to the RequestProps copy (props[index]) via anonymize() when
hideCredentials is enabled, but handleResponse() separately generates and logs a cURL string using
the original, unmasked options (including headers/body/url) in Cypress.log().consoleProps(). Because
consoleProps is derived from raw options rather than the already-anonymized props structure,
sensitive values can still be emitted despite the UI props appearing masked, creating a mismatch
between the advertised hideCredentials behavior and what is actually logged.

src/modules/api.ts[12-23]
src/utils/anonymize.ts[10-59]
src/modules/handleResponse.ts[192-216]
src/utils/generateCurl.ts[3-57]
src/modules/api.ts[14-23]
src/utils/anonymize.ts[10-61]
src/modules/handleResponse.ts[188-216]
cypress.config.ts[13-18]

Teammate info & reasoning
Type safety and explicit contracts
Reason for choosing OmriGM: Best fit for the broad frontend/tooling changes (Vue components, TS modules, Vite/Cypress updates) to ensure UI behavior and test suite adjustments are correct and consistent.
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`handleResponse()` adds a `cURL` entry to `consoleProps()` by generating it from the original, unmasked `options` (headers/body/url). Since `hideCredentials` masking is applied only to `props[index]` via `anonymize()`, secrets can still appear in the Cypress Command Log console props even when credentials are expected to be hidden.

## Issue Context
- Masking is currently applied only to `props[index]` (RequestProps) through `anonymize()` when `hideCredentials` is enabled; `options` (ApiRequestOptions) retains the original sensitive values.
- `handleResponse()` should emit cURL derived from already-masked data (`props[index]`) or a masked clone, otherwise console output can leak tokens in CI artifacts or shared debugging sessions.
- The repo already has a shared `src/utils/generateCurl.ts` helper that generates cURL from `RequestProps` (the masked structure), and it should be reused rather than duplicating options-based generation.

## Fix Focus Areas
- src/modules/handleResponse.ts[188-216]
- src/modules/api.ts[12-23]
- src/utils/generateCurl.ts[1-58]
- src/utils/anonymize.ts[10-59]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (3)
4. Deprecated checkout action 🧑 ☼ Reliability
Description
**Inspired by shay-qodo's coding and review patterns** — The workflow still uses
actions/checkout@v2, which is deprecated and can fail due to older Node runtime deprecations on
GitHub-hosted runners. This undermines the stated goal of fixing the failing workflow and can
re-break CI unexpectedly.
Code

.github/workflows/tests.yml[R11-13]

      - name: Checkout
        uses: actions/checkout@v2
      - name: Cypress run
Evidence
The workflow uses a deprecated checkout major. Shay-qodo prioritizes production/operational
reliability and would flag CI dependencies that can fail due to upstream deprecations, especially in
a PR intended to unbreak releases.

.github/workflows/tests.yml[7-13]

Teammate info & reasoning
Reliability of external calls (retries + bounded latency)
Reason for choosing shay-qodo: Strong fit to review the GitHub Actions / semantic-release fix (NPM_TOKEN secret reference) and other CI/config touches (workflows, lint/build configs).
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`actions/checkout@v2` is deprecated/EOL and may stop working on modern GitHub runner environments.

### Issue Context
This PR is explicitly about fixing the workflow; leaving a deprecated core action is a reliability risk.

### Fix Focus Areas
- .github/workflows/tests.yml[7-13]

### Suggested fix
Update:
- `uses: actions/checkout@v2` → `uses: actions/checkout@v4`

(Optionally) also consider bumping other actions to current major versions if you see warnings in Actions logs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. server/index.js adds console.error 📘 ◔ Observability
Description
New console.error(...) statements were added to the server error handler. This violates the
requirement to avoid introducing new logging statements in this codebase.
Code

server/index.js[R232-242]

+  .on('error', (err) => {
+    if (err.code === 'EADDRINUSE') {
+      console.error(`\n❌ Port ${port} is already in use.`)
+      console.error(`   Please stop the process using port ${port} or use a different port.\n`)
+      console.error(`   To find and kill the process on Windows:`)
+      console.error(`   netstat -ano | findstr :${port}`)
+      console.error(`   taskkill /PID <PID> /F\n`)
+      process.exit(1)
+    } else {
+      console.error('Server error:', err)
+      process.exit(1)
Evidence
PR Compliance ID 6548 forbids adding new logging statements. The added error handler introduces
multiple new console.error(...) calls in server/index.js.

Rule 6548: Avoid adding new logging statements in this codebase
server/index.js[232-242]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New `console.error(...)` logging statements were introduced in `server/index.js`, which violates the compliance requirement to avoid adding new logging statements.

## Issue Context
The PR adds an `.on('error', ...)` handler that prints multiple error messages to the console.

## Fix Focus Areas
- server/index.js[232-242]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. copyCurl.cy.ts adds cy.log ✓ Resolved 📘 ◔ Observability
Description
New cy.log(...) debug logging statements were added to the Cypress test. This violates the
requirement to avoid introducing new logging statements.
Code

cypress/e2e/copyCurl.cy.ts[R705-743]

+            cy.log('Pre element textContent length:', textContent.length)
+            cy.log('Pre element textContent (first 100 chars):', textContent.substring(0, 100))
+            
+            // Find the code element inside pre (transform wraps content in <code>)
+            const codeElement = $pre[0].querySelector('code')
+            cy.log('Code element found:', !!codeElement)
+            if (codeElement) {
+              cy.log('Code element textContent length:', codeElement.textContent?.length || 0)
+            }
+            
+            // Check computed styles for user-select on pre
+            const preStyles = window.getComputedStyle($pre[0])
+            cy.log('Pre computed user-select:', preStyles.userSelect)
+            cy.log('Pre computed pointer-events:', preStyles.pointerEvents)
+            cy.log('Pre computed cursor:', preStyles.cursor)
+            
+            // Check computed styles on code element if it exists
+            if (codeElement) {
+              const codeStyles = window.getComputedStyle(codeElement)
+              cy.log('Code computed user-select:', codeStyles.userSelect)
+              cy.log('Code computed pointer-events:', codeStyles.pointerEvents)
+            }
+            
+            // Check parent element styles
+            const parent = $pre[0].parentElement
+            if (parent) {
+              const parentStyles = window.getComputedStyle(parent)
+              cy.log('Parent user-select:', parentStyles.userSelect)
+              cy.log('Parent pointer-events:', parentStyles.pointerEvents)
+              cy.log('Parent cursor:', parentStyles.cursor)
+            }
+            
+            // Check if section is highlighted
+            const section = $pre[0].closest('section')
+            if (section) {
+              cy.log('Section has __cypress-highlight:', section.classList.contains('__cypress-highlight'))
+              const sectionStyles = window.getComputedStyle(section)
+              cy.log('Section cursor:', sectionStyles.cursor)
+              cy.log('Section pointer-events:', sectionStyles.pointerEvents)
Evidence
PR Compliance ID 6548 requires no new logging statements. The added test code includes multiple new
cy.log(...) calls (e.g., logging text lengths and computed styles).

Rule 6548: Avoid adding new logging statements in this codebase
cypress/e2e/copyCurl.cy.ts[705-743]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new Cypress test introduces multiple `cy.log(...)` statements, which are new logging statements and violate the compliance rule.

## Issue Context
These logs appear to be debugging output (text lengths, computed styles, selection state) and are not required for the test assertions.

## Fix Focus Areas
- cypress/e2e/copyCurl.cy.ts[705-743]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

7. Expensive transform hot path ✓ Resolved 🐞 ➹ Performance
Description
transform() now performs multiple full-string passes and repeated scans/replacements (including
repeated indexOf loops and substring rebuilds) for JSON folding/indent logic. Since transform() runs
for each request/response body and headers, large payloads can cause noticeable slowdowns in the
runner UI.
Code

src/modules/transform.ts[R169-205]

+    if (language === 'json' && isValidJson(content)) {
+      const openBracePattern = '<span class="token punctuation">{</span>'
+      const closeBracePattern = '<span class="token punctuation">}</span>'
+      const openBracketPattern = '<span class="token punctuation">[</span>'
+      const closeBracketPattern = '<span class="token punctuation">]</span>'
+      
+      interface TokenPosition {
+        index: number
+        type: 'openBrace' | 'closeBrace' | 'openBracket' | 'closeBracket'
+        nestingLevel: number
+      }
+      
+      const tokens: TokenPosition[] = []
+      let searchIndex = 0
+      
+      while ((searchIndex = code.indexOf(openBracePattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'openBrace', nestingLevel: 0 })
+        searchIndex += openBracePattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(closeBracePattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'closeBrace', nestingLevel: 0 })
+        searchIndex += closeBracePattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(openBracketPattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'openBracket', nestingLevel: 0 })
+        searchIndex += openBracketPattern.length
+      }
+      
+      searchIndex = 0
+      while ((searchIndex = code.indexOf(closeBracketPattern, searchIndex)) !== -1) {
+        tokens.push({ index: searchIndex, type: 'closeBracket', nestingLevel: 0 })
+        searchIndex += closeBracketPattern.length
+      }
Evidence
transform() contains multiple loops and full-string transformations (including repeated indexOf
searches over the highlighted HTML) and is invoked for request/response bodies and headers in the
normal cy.api() flow, so its cost directly impacts the runner UI for large payloads.

src/modules/transform.ts[23-145]
src/modules/transform.ts[169-205]
src/modules/handleResponse.ts[120-165]
src/modules/transformData.ts[5-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The updated `transform()` implementation does substantial extra work per render (splits/maps/joins, brace alignment passes, repeated `indexOf` scans, and large string rebuilds). Because `transform()` is called for request/response bodies and headers on every `cy.api()`, large responses can degrade UI responsiveness.

### Issue Context
This is most impactful on large JSON bodies where the folding/brace matching logic runs over the full highlighted HTML string.

### Fix
- Add a size-based guard (e.g., `if (content.length > N)`) to skip folding/brace matching and only do basic syntax highlighting.
- Consider making folding optional (config flag) or lazy (only compute when user opens the JSON view).
- Avoid repeated `indexOf` scans by doing a single pass parse of the highlighted output (or avoid post-processing highlighted HTML altogether).

### Fix Focus Areas
- src/modules/transform.ts[23-145]
- src/modules/transform.ts[169-305]
- src/modules/handleResponse.ts[120-165]
- src/modules/transformData.ts[5-113]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Octet-stream parsers conflict 🧑 ≡ Correctness
Description
**Inspired by shay-qodo's coding and review patterns** — The server registers both express.text()
and express.raw() for application/octet-stream, so the first middleware will consume the body
and the later one won’t run. This makes /arraybuffer-request behavior inconsistent (e.g.,
Buffer.isBuffer(req.body) may never be true) and can lead to flaky/incorrect binary tests.
Code

server/index.js[R9-12]

+app.use(express.json({ limit: '10mb' }));
+app.use(express.urlencoded({ extended: true, limit: '10mb' }));
+app.use(express.text({ type: 'application/octet-stream', limit: '10mb' }));
+app.use(express.raw({ type: 'application/octet-stream', limit: '10mb' }));
Evidence
The middleware order makes octet-stream request parsing non-deterministic for the intended route
logic. Shay-qodo is reliability-oriented and typically flags subtle runtime-shape hazards that cause
flaky behavior under real execution.

server/index.js[8-13]
server/index.js[159-195]

Teammate info & reasoning
Reliability of external calls (retries + bounded latency)
Reason for choosing shay-qodo: Strong fit to review the GitHub Actions / semantic-release fix (NPM_TOKEN secret reference) and other CI/config touches (workflows, lint/build configs).
Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`express.text({ type: 'application/octet-stream' })` and `express.raw({ type: 'application/octet-stream' })` are both registered. Express will pick the first matching parser, so the second is effectively dead, and `req.body` shape becomes surprising.

### Issue Context
`/arraybuffer-request` branches on `Buffer.isBuffer(req.body)` and other binary shapes; having the body coerced to string by `express.text()` breaks that contract.

### Fix Focus Areas
- server/index.js[8-13]
- server/index.js[159-195]

### Suggested fix
- Prefer **only** `express.raw({ type: 'application/octet-stream' })` for octet-stream, and decode inside the route when you want text.
- If you need both, scope parsers per-route (attach middleware on the specific route) or use different `type` matchers so they don’t overlap.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread server/index.js
Comment on lines +232 to +242
.on('error', (err) => {
if (err.code === 'EADDRINUSE') {
console.error(`\n❌ Port ${port} is already in use.`)
console.error(` Please stop the process using port ${port} or use a different port.\n`)
console.error(` To find and kill the process on Windows:`)
console.error(` netstat -ano | findstr :${port}`)
console.error(` taskkill /PID <PID> /F\n`)
process.exit(1)
} else {
console.error('Server error:', err)
process.exit(1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. server/index.js adds console.error 📘 Rule violation ◔ Observability

New console.error(...) statements were added to the server error handler. This violates the
requirement to avoid introducing new logging statements in this codebase.
Agent Prompt
## Issue description
New `console.error(...)` logging statements were introduced in `server/index.js`, which violates the compliance requirement to avoid adding new logging statements.

## Issue Context
The PR adds an `.on('error', ...)` handler that prints multiple error messages to the console.

## Fix Focus Areas
- server/index.js[232-242]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread cypress/e2e/copyCurl.cy.ts Outdated
Comment thread src/style.css Outdated
Comment on lines +20 to +37
outline: 3px solid rgba(59, 130, 246, 0.6) !important;
outline-offset: 2px !important;
opacity: 1 !important;
pointer-events: auto !important;
}

.__cypress-highlight:not(section),
.__cypress-highlight [data-cy],
.__cypress-highlight [data-cy] *,
.__cypress-highlight pre,
.__cypress-highlight div[data-cy] {
outline: none !important;
}

section.__cypress-highlight {
pointer-events: auto !important;
cursor: pointer;
background-color: rgba(255, 255, 255, 0.1) !important;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Hard-coded colors in style.css 📘 Rule violation ⚙ Maintainability

New hard-coded color values (rgba(...) / rgb(...)) were added in src/style.css instead of
using semantic design-system tokens. This violates the requirement to avoid hard-coded UI colors.
Agent Prompt
## Issue description
`src/style.css` introduces multiple hard-coded color literals (e.g., `rgba(...)`, `rgb(...)`) which should be replaced by the project’s semantic color tokens.

## Issue Context
The stylesheet otherwise uses semantic Tailwind tokens like `bg-cy-*` / `text-cy-*`, but these new rules bypass them via raw RGB/RGBA values.

## Fix Focus Areas
- src/style.css[20-21]
- src/style.css[37-37]
- src/style.css[303-314]
- src/style.css[345-360]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +192 to 216
const generateCurl = () => {
let curl = `curl -X ${options.method || 'GET'} "${options.url}"`;
if (options.headers) {
Object.entries(options.headers).forEach(([key, value]) => {
curl += ` -H "${key}: ${value}"`;
});
}
if (options.body) {
if (typeof options.body === 'object') {
curl += ` -d '${JSON.stringify(options.body)}'`;
} else {
curl += ` -d '${options.body}'`;
}
}
return curl;
};

log.set({
consoleProps() {
return {
yielded
yielded,
cURL: generateCurl()
}
}
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

4. Curl leaks masked secrets 🐞 Bug ⛨ Security

handleResponse() exposes a generated cURL string in Cypress.log().consoleProps() built from the
original request options (headers/body/url), bypassing anonymize() which only masks props[index]
when hideCredentials is enabled. This can contradict the expected hideCredentials behavior and leak
secrets (e.g., cy.env()-sourced tokens) into Command Log console props, including CI artifacts or
shared debugging sessions.
Agent Prompt
## Issue description
`handleResponse()` adds a `cURL` entry to `consoleProps()` by generating it from the original, unmasked `options` (headers/body/url). Since `hideCredentials` masking is applied only to `props[index]` via `anonymize()`, secrets can still appear in the Cypress Command Log console props even when credentials are expected to be hidden.

## Issue Context
- Masking is currently applied only to `props[index]` (RequestProps) through `anonymize()` when `hideCredentials` is enabled; `options` (ApiRequestOptions) retains the original sensitive values.
- `handleResponse()` should emit cURL derived from already-masked data (`props[index]`) or a masked clone, otherwise console output can leak tokens in CI artifacts or shared debugging sessions.
- The repo already has a shared `src/utils/generateCurl.ts` helper that generates cURL from `RequestProps` (the masked structure), and it should be reused rather than duplicating options-based generation.

## Fix Focus Areas
- src/modules/handleResponse.ts[188-216]
- src/modules/api.ts[12-23]
- src/utils/generateCurl.ts[1-58]
- src/utils/anonymize.ts[10-59]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/modules/transform.ts Outdated
Comment on lines 11 to 13
- name: Checkout
uses: actions/checkout@v2
- name: Cypress run

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

8. Deprecated checkout action 🧑 Team insight ☼ Reliability

**Inspired by shay-qodo's coding and review patterns** — The workflow still uses
actions/checkout@v2, which is deprecated and can fail due to older Node runtime deprecations on
GitHub-hosted runners. This undermines the stated goal of fixing the failing workflow and can
re-break CI unexpectedly.
Agent Prompt
### Issue description
`actions/checkout@v2` is deprecated/EOL and may stop working on modern GitHub runner environments.

### Issue Context
This PR is explicitly about fixing the workflow; leaving a deprecated core action is a reliability risk.

### Fix Focus Areas
- .github/workflows/tests.yml[7-13]

### Suggested fix
Update:
- `uses: actions/checkout@v2` → `uses: actions/checkout@v4`

(Optionally) also consider bumping other actions to current major versions if you see warnings in Actions logs.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-for-filiphric

Copy link
Copy Markdown

Qodo Fixer

🍒 Ready to be cherry-picked — ✅ Merged (0) · ☑ Fixed (6)

Grey Divider

🔗 Fix PR: #153

This fix PR was closed automatically. Its branch is preserved so you can cherry pick the changes into the original PR.

Prompt for coding agent

This is an automated fix prepared on a separate branch (#153). It is NOT applied to this PR.
To use it: review Fix PR #153 (https://github.com/filiphric/cypress-plugin-api/pull/153), evaluate each change critically against your local context, and cherry-pick the changes that are correct into this branch. Do not accept them blindly.
Process — 6 fixed
  • ☑ Fixed: Unescaped plaintext HTML output
  • ☑ Fixed: Hard-coded colors in style.css
  • ☑ Fixed: cURL leaks masked secrets
  • ☑ Fixed: Deprecated checkout action
  • ☑ Fixed: server/index.js adds console.error
  • ☑ Fixed: copyCurl.cy.ts adds cy.log

…-qol

# Conflicts:
#	cypress.config.ts
#	cypress/e2e/authorization.cy.ts
#	cypress/e2e/copyCurl.cy.ts
#	eslint.config.js
#	package-lock.json
#	package.json
#	src/components/RequestPanel.vue
#	src/modules/handleResponse.ts
#	src/modules/transform.ts
#	src/shims-vue.d.ts
#	src/style.css
#	src/utils/generateCurl.ts
@filiphric filiphric merged commit c808dfd into main Jun 28, 2026
2 checks passed
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.

2 participants