Skip to content

fixes: OpenAPI Spec Viewer: throws resolver errors for $ref schemas - #8892

Merged
sid-bruno merged 4 commits into
usebruno:mainfrom
arpit-bruno:fix/openapi-31-ref-resolver-file-baseuri
Aug 7, 2026
Merged

fixes: OpenAPI Spec Viewer: throws resolver errors for $ref schemas #8892
sid-bruno merged 4 commits into
usebruno:mainfrom
arpit-bruno:fix/openapi-31-ref-resolver-file-baseuri

Conversation

@arpit-bruno

@arpit-bruno arpit-bruno commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description

OpenAPI 3.1 specs were failing to render in the packaged app, every internal $ref throws "Could not resolve reference: Evaluation failed on URI".
In Dev mode and 3.0 specs are working fine.

Problem

  1. Resolver: swagger-client's 3.1 resolver checks the scheme of document.baseURI before dereferencing any refs. The packaged app loads over file:// so the check fails for every ref.
  2. Error panel: the panel rendered with raw swagger-ui styles (unreadable heading colors in dark theme), and the long resolver URIs overflowed the panel. Also on window resize the panel was not responsive.

Fix

  1. Report an http base to swagger with a small override next to the SwaggerUI mount.

Root cause (resolver):
https://github.com/swagger-api/swagger-js/blob/v3.36.1/src/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js#L519
the condition is always true, the else branch meant to resolve unknown-scheme bases (like file://) vand the catch-block is isURL-gated, so non-http bases have no path to resolve and hence the error is thrown.

Screenshots

Screen.Recording.2026-07-19.at.4.38.39.PM.mov

Note
The real fix needs to be done in swagger-js , I will raise a PR there for the resolver's scheme gate. Once that lands and swagger-ui-react picks it up, this overriding fix can be deleted.

  1. Themed the panel with the app's danger tokens, long tokens now wraps and the panel is responsive

How to replicate the error panel:

openapi: 3.1.0
info:
  title: Long Error Test
  version: 1.0.0
paths:
  /pets:
    get:
      summary: List pets
      responses:
        '200':
          description: ok
          content:
            application/json:
              schema:
                $ref: 'file:///a/very/long/unresolvable/path/that/does/not/exist/index.html#/components/schemas/Pet'
  1. Open this spec (API Specs → Open API Spec),
  2. then expand GET /pets .

Before :
Screenshot 2026-08-07 at 12 52 42 PM

After:
Screenshot 2026-08-07 at 1 09 50 PM

REF: BRU-3939

Summary by CodeRabbit

  • Bug Fixes
    • Improved Swagger error panel styling for clearer visibility and better readability across themes.
    • Fixed Swagger rendering in packaged applications by enabling internal OpenAPI references to resolve correctly.
    • Improved handling of long error messages and constrained content widths for more consistent layouts.

@arpit-bruno arpit-bruno changed the title fixes: resolve 3.1 $refs resolutions in packaged app OpenAPI Spec Viewer: throws resolver errors for $ref schemas Aug 6, 2026
@arpit-bruno arpit-bruno changed the title OpenAPI Spec Viewer: throws resolver errors for $ref schemas fixes: OpenAPI Spec Viewer: throws resolver errors for $ref schemas Aug 6, 2026
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The Swagger renderer now supports packaged app execution over file: URLs and applies themed styling to its errors panel.

Changes

Swagger renderer

Layer / File(s) Summary
Packaged URL base handling
packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/index.js
The renderer replaces non-HTTP(S) document.baseURI values with http://localhost/ before Swagger UI initialization.
Themed Swagger error presentation
packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/StyledWrapper.js
The errors panel uses themed danger colors, spacing, borders, overflow handling, constrained widths, and theme text colors.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: utkarsh-bruno

Poem

Swagger paths cross packaged skies,
While themed errors neatly rise.
Borders frame each warning bright,
Text now matches the chosen light.
$ref finds home through every flight.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the OpenAPI Spec Viewer resolver errors for $ref schemas, which is the main change.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

❤️ Share

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

@pull-request-size pull-request-size Bot added size/M and removed size/S labels Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/index.js (1)

17-22: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Scope the document.baseURI override to Swagger resolution.

SpecViewer is the only renderer source that renders Swagger, but this module redefines global document.baseURI for the whole Electron renderer. If any other renderer path later needs to rely on the real base URI, that behavior will change. Move this into Swagger’s dependency/config, or use an explicit resolver/base option instead of mutating the global document.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/index.js`
around lines 17 - 22, Remove the global document.baseURI mutation from the
module-level initialization and scope the localhost fallback to Swagger
resolution in SpecViewer. Pass an explicit resolver or base-URI option through
Swagger’s dependency/configuration path, preserving the existing fallback only
for Swagger without affecting other renderers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/index.js`:
- Around line 17-22: Remove the global document.baseURI mutation from the
module-level initialization and scope the localhost fallback to Swagger
resolution in SpecViewer. Pass an explicit resolver or base-URI option through
Swagger’s dependency/configuration path, preserving the existing fallback only
for Swagger without affecting other renderers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 14a3aa68-d43b-4d1b-b5b3-9223f46779c1

📥 Commits

Reviewing files that changed from the base of the PR and between 1c2ec7c and 5be517b.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/StyledWrapper.js
  • packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/index.js

@arpit-bruno

Copy link
Copy Markdown
Contributor Author

Ref: swagger-api/swagger-client#4258

@sid-bruno
sid-bruno merged commit 7c3c4ff into usebruno:main Aug 7, 2026
14 of 17 checks passed
AustralianRaven added a commit to AustralianRaven/rest-wolf that referenced this pull request Aug 18, 2026
* fix(ws): keep body-mode dropdown above collapsed sticky headers (#8622)

* fix(ws): keep body-mode dropdown above collapsed sticky headers

* fix

* add: test

* rm: only

* improvement

* fix(app): point generated docs to api-docs CDN path (#8633)

* test(sidebar): move sidebar locators to a dedicated file (#8634)

Co-authored-by: Bijin A B <bijin@usebruno.com>

* fix(ai): align AI buttons to primary color and refine copy (#8627)

* fix(ai): align AI buttons to primary color and refine copy

* fix: test

---------

Co-authored-by: naman-bruno <naman@usebruno.com>

* improve: test file arrangement

* fix(new-app): prevented validation error on blur and dialog layout shift (#8624)

* add: unit test

* feat(proxy-settings): show "last refreshed" timestamp on System Proxy panel (#8640)

* refactor: improve Wysiwyg editor toolbar interactions, add delete table option

* refactor: update documentation code block background theme colors

* reconciled autocomplete suggestions against typed prefix to stop dupes + invalid res (#8621)

* fix(ai): scope autocomplete API hints by scriptType so pre-request never suggests res

* fix(ai): de-duplicated typed token in autocomplete + unify suggestion sanitization

* resolved the coderabit review.

* fix(ai): reconciled autocomplete suggestions against typed prefix to stop dupes + invalid res

* fix(ws): keep selection on current message when deleting another (#8643)

* Generate documentation modal text and style changes (#8644)

* fix(ui): visual improvements for tables in FileBody and EnvironmentVarsTable (#8632)

* fix(StyledWrapper): improve table header styling and add ellipsis for overflow text

* fix(FileBody): add truncation to 'Selected' column for better overflow handling

* fix: ui improvements for descriptions and tables

* fix(EnvironmentVariablesTable): improve formatting and overflow handling in EnvVarValueCell

* fix(EnvironmentVariablesTable): add testId to SecretEyeButton for better testing support

* chore(claude): add .claude config into the repo (#8648)

* fix(app): resolve collection level variables in bru.ctx and add app logs to console (#8650)

* fix(app): resolve collection level variables in bru.ctx.variables

* fix(app): log bru.ctx.log output into app console

* refactor(app): integrate Portal component and enhance form submission (#8645)

* chore(mount): route request entries through buildRequestNode in buildTree (#8658)

* Update CODEOWNERS (#8666)

* refactor: replace DocsLinkModal with contextual DocsLinkPopover and update toolbar link handling

* test(environments): env tab eye icon (#8655)

* fix(interpolation): add interpolation for akamai-auth (#8631)

* fix: show correct New Request shortcut in response placeholder (#8116)

* refactor: redesign documentation editor table styles, update mode switch UI

* fix(ai): respected the redact-secret-variables toggle for name-pattern variables (#8657)

* fix(app): chevron positioning and selector width (#8669)

* refactor: extract richtext editor test utility and modularize test suites

* fix(ai): improve script types and clarify res restrictions in pre scripts (#8678)

* Update beta features section in preferences (#8642)

* Refine bug report issue template UI

* Rename config.yaml to config.yml

* Update FeatureRequest.yaml

* chore(ui-component)/added radio group component with storybook and updated the preset component

* added storybook docs

* added tests for radio group

* fix(environments): keep secret values on the secret row when a variable shares its name (#8679)

* fix(environments): keep secret values on the secret row when a variable shares its name

* rm: comment

* fix

* fix(mount): redact large text blocks so big .bru files parse fast (#8660)

Large .bru files (>=512KB) were fed whole to the ohm parser on mount,
which is slow and memory-heavy. Add a redaction pass that splits the
flat text blocks (bodies, scripts, tests, docs) out of the file, parses
the small remaining skeleton, and re-attaches the extracted content.

- redactLargeBruTextBlocks: replaces each top-level text block's content
  with a content-hash token, returning a skeleton + the extracted values
- restoreRedactedBlocks: re-attaches values wherever the tokens land in
  the parsed object
- parse-file uses this for request, collection and folder .bru above the
  size threshold
- values are extracted to be byte-identical to a normal parse (leading
  blank lines, CRLF terminator and 2-space outdent all handled), proven
  by round-trip tests that deep-equal against a normal parse

* added stories for ui components

* feat(mount): follow symlinks when walking collections (#8649)

* feat(mount): follow symlinks when walking collections

Resolve symbolic-link entries during the mountv2 walk so symlinked
request files and directories are classified and listed like their
real counterparts. Broken links are skipped.

Adds an e2e spec covering symlinked file and directory entries across
both formats and with the file cache off and on.

* test(mount): use waitForReadyPage and closeElectronApp helpers in symlink spec

* fix(mount): guard against directory-symlink cycles when walking

A directory symlink that resolves to an ancestor (or itself) previously
re-entered the same subtree until the walk exhausted the stack. Track
canonical directory paths and skip any directory already visited, so a
cyclic link is walked at most once.

Extends the symlink e2e spec with an ancestor-pointing link, asserting
the mounted tree stays bounded (file-cache path).

* removed preset component

* fix(size/S):Minor bug fix in the version edit popup for the new version input box (#8672)

* Minor bug fix for the version edit popup

* Fix unit test case failing issue

* added segment group component with stories and tests

* revert presets to not use segment group

* added theme selector

* added readme for storybook

* feat(ai): implement immediate security settings save (#8685)

* feat(ai): implement immediate security settings save

* Update packages/bruno-app/src/components/Preferences/AI/index.js

* refactor: migrate editor components to RichTextEditor, and adjust ModeSwitch UI styles

* refactor: rename Docs-prefixed editor extensions to Editor

* refactor: rename Wysiwyg references to Rich Text

* enabled code in storybook and updated Radio and Segmented control API to accept list

* refactor: remove code-block test file

* removed box shadow

* refactor: rename docs CSS classes to editor prefix for consistency

* fix(snapshot): environment loss of some workspaces (#8686)

* fix: draft attempt 1

* fix(snapshot): enhance active workspace collection handling in SnapshotManager

* fix(snapshot): refactor collection lookup assignments for improved readability

* fix(snapshot): simplify collection lookup assignments for clarity and maintainability

* fix(snapshot): improve handling of workspace-scoped collection lookups and ensure distinct entries based on active workspace preferences

* fix: coderabbit comments

* added a box shadow on active item

* updated shadow to lighter version

* improved readme file

* added test and stories for toggle switch

* added post css loader so Storybook can compile the app's Tailwind CSS

* added dropdown stories and test

* feat(ai): enhance app handling in AiChatSidebar (#8697)

* fix: size of cancel button (#8692)

Co-authored-by: shubh-bruno <shubh-bruno@shubh-bruno.local>

* task (migration) : hiding migration options and the respective test (#8690)

* fix(ui): SensitiveFieldWarning tooltip position (#8698)

* feat(ai): add request handling to ai chatbar (#8700)

* feat(ai): add request handling to ai chatbar

* fix: test

* Added changelog for v4 (#8677)

* Added changelog for v4

* updated images to use s3 links

* Updated url for images

* Added version for docs urls

* Reverted version change

Co-authored-by: Bijin A B <bijin@usebruno.com>

* Updated the YAML migration text

---------

Co-authored-by: Bijin A B <bijin@usebruno.com>

* fix(keybindings): new request in active tab based on active collection (#8703)

* Added beta flag for AI (#8706)

* chore(coderabbit)/adds coderabbit instructions for adding new file as ts/tsx in bruno app (#8717)

* fix(devtools): prevent console panel from bleeding over modals (#8716)

* feat(web-buidler): remote artifact builder plugin  (#8718)

* basic plugin

* Apply suggestion from @sid-bruno

* fix(settings): Enable App toggle for GQL requests (#8723)

* fix(converters): add missing auth mappings on postman export, add additional parameters mapping on postman import (#8494)

* fix(import): add Oauth fallback for grant authorization code, parse additional parameters.

* feat(import): support NTLM auth import from postman. #BRU-3114

* feat(export): support collection level auth. support awsv4, digest, ntlm, oauth1 and oauth2 auth types. fix bearer type return structure.

* test(import): add NTLM, Additional parameters tests.

* fix(export): add 'in' key for 'apiKey' auth type

* test(export): add test cases for bruno to postman Auth flow.

* fix (export): add folder level auth in export and use ensureString for string attributes

* fix(import): add missing placement default and remove grant-type redundant logic

* fix: revert missed grantType variable

* test(export): add auth undefined assertion (code rabbit review)

* fix: use common string util method for fallback

* added stories and tests for Help component

* fix(mountv2): give duplicate-named env variables distinct uids (#8730)

* refactor(tests): update data type assertions to use data-selected-type attribute for consistency (#8731)

* added stories and tests for accordian

* fix(secrets): environment table (#8733)

* fix(secrets): environment table

* fix: removed useeffect

* added introduction md file

* test(converters): add round trip tests for Postman <-> Bruno converters (#8534)

* test(export): add round trip tests for Postman <-> Bruno converter

* fix(export): add unique key for paths to handle duplicates, fix postman collections to handle more code coverage

* fix(conveters): add diff enum for reusability

* fix: add enum for auth types

* fix: CJS to ESM imports

* fix: update readme info for round trip

* added outlined version for segmented control

* updated icons

* removed dropdown

* chore(eslint): adds eslint config warnings for unused-vars, debuggers, duplicate-imports (#8505)

* feat(tests): enhance Playwright configuration for sharded CI runs (#8742)

* refactor(ui): extract richtext editor utilities to utils folder

* refactor(ui): move useLinkHandlers to utils folder

* refactor(ui): extract richtext editor components to components folder

* refactor(ui): refactor RichTextEditor toolbar state into custom hooks

* test(e2e): fix richtext editor locators and handle new button components

* fix(tests-macos): update branch filters for workflow triggers to support release branches (#8752)

* fix: encode url for url without protocol (#8756)

* fix(cookies): toggle raw mode state in ModifyCookieModal (#8755)

* refactor: reorganize RichTextEditor hooks

* feat(ai): add focus for prompt input after AI response completion (#8747)

* fix(security): overflow on chip list styling (#8748)

* feat(converters): add support for script execution flow in yml configuration (#8745)

* chore: remove accidentally added non-bruno-app files

* feat(collections): open multiple collections from a monorepo (#8724)

* feat(collections): open multiple collections at once

* refactor(collections): rename open-collection IPC channels

* test(collections): e2e coverage for open collection picker and selection modal

* refactor(collections): 'no collections found' toast message

* fix(collections): import hydrateCollectionWithUiStateSnapshot in workspaces actions

* fix(collections): default to no selection and surface open failures

* feat(collections): prevent duplicate open collection toasts

* fix(collections): update auto close condition for selection modal

* test(collections): open collection selection selectors moved to page module

* test(collections): match open collection rows by exact title

* Merge branch 'main' into feat/open-multiple-collections

* fix(workspaces): switch to default workspace on close so header shows correct name (#8425)

* fix(workspaces): switch to default workspace on close so header shows correct name

* Added the test spec related review.

* added e2e test for closing workspace returns to default

* added e2e test for closing workspace returns to default

* added e2e test for closing workspace returns to default

* test(workspaces): used stable test ids for workspace switcher and actions in close-workspace e2e

* refactor(ai): update API key handling in openai comp providers (#8749)

* refactor(ai): update API key handling in openai comp providers

* fix

* refactor: simplify rich text editor link management with unified ToolHint components and improved URL validation logic

* chore(pr-decription)/updated pr description (#8786)

* removed unused stories

* removed radio group

* chore(eslint)/disable autofix for const (#8760)

* chore(eslint)/disable autofix for const

* added a config

* Apply suggestion from @sid-bruno

Co-authored-by: Sid <siddharth@usebruno.com>

* Apply suggestion from @sid-bruno

Co-authored-by: Sid <siddharth@usebruno.com>

* Apply suggestion from @sid-bruno

Co-authored-by: Sid <siddharth@usebruno.com>

* Apply suggestion from @sid-bruno

Co-authored-by: Sid <siddharth@usebruno.com>

* lint fix

* added inline check

* removed comment

---------

Co-authored-by: Sid <siddharth@usebruno.com>

* updated segment control design

* fix: decouple task lists from mixed-content lists and improve markdown serialization for block elements

* Fix: binary body lost on importing from postman (#8729)

* fix/3118 - Postman Import: Binary Body Type Silently Lost

* fix/3118 - Postman Import: Binary Body Type Silently Lost

* fix/3118 - Postman Import: Binary Body Type Silently Lost

* fix/Added indentation

* Import binary body mode

* handling else if

* Handling example with binary body

* file body mode

* Add tests for importing Postman binary body requests

* Enhance Postman binary body import by inferring content type from file extensions and adding tests for various file types

* Add mime-types as an external dependency and implement test for .bin file content type resolution in Postman to Bruno conversion

* fix: import statements

* fix: e2e tests

* refactor: improve test structure and assertions for Postman binary body import

---------

Co-authored-by: rajashreehj-bruno <rajashree@usebruno.com>

* style: update documentation edit toggle button size to sm

* updated outlined styles

* style: update inline code and block styling with transparent backgrounds, borders, and light-mode adjustments

* fix(timeout): allow inherit request timeout for yaml requests (#8746)

* fix(timeout): allow inherit request timeout for yaml requests

* fix: add test.step for timeout

* fix(timeout): normalize resolveTimeoutSetting to reject non-finite/negative timeouts

* style: update code and block border radius to use base theme radius

* fix(environment): auto save on env table removing some characters (#8732)

* fix(environment)/auto save on env table

* moved autosave tests

* added locators

* added test for multi line

* updated name

* feat(code-mirror-search): add replace and replace-all with search position, debouncing and tests (#8715)

* feat(environment): add default env to presets (#8612)

* fix: Folder Sequencing When we try to move any folder at the bottom of the folders list (#8722)

* fix: Folder Sequencing When we try to move any folder at the bottom of the folders list

* fix(bruno-app): use path-segment ancestry for folder drop checks to avoid sibling-prefix false positives

* fix(bruno-app): allow folder to be reordered to bottom via dropType edge zones (BRU-1112)

* ci: re-run benchmark check (flaky perf gate)

* docs(bruno-app): updated stale dropType comments to above/below terminology

* Added the fix for bru.runner.stopExecution() while running collection run from tests (#8720)

* Added the fix for bru.runner.stopExecution() while running collection run from tests

* resolved the code review for coderabbit

* fix

* feat(collections): add description text to open collection selection modal (#8793)

* fix(ws): remove auto-reconnect in websockets  (#8605)

* feat: add preserve scripts option for Postman import/export (#8726)

* feat(import): add preserve scripts option for Postman import/export

* test(import): add postman preserve scripts coverage

* fix(import): align preserve scripts option place and color

* fix(import): address coderabbit comments

* test(import): assert export scripts and centralize import locators

* fix(export): validate empty filename, dismiss dialogs between tests

* refactor(import): use options object for convertCollection config params

* refactor(import): remove redundant check from importPostmanV2CollectionItem

* Added the ignore for the collection nested folders (#8725)

* Added the ignore for the collection nested folders

* Removed the unignored functionality for Collection folder for now

* require path boundary in folder ignore matching to prevent prefix and empty-pattern over-matching

* fix(collection): deep-cloned bruno config before transform so ignore/update never mutated the object returned to redux

* resolved the coderebbit review comments

* fix:env configure remains visible (#8530)

Co-authored-by: Adwait Aayush <adwaitaayush@Adwaits-MacBook-Air.local>

* fix:url truncates in docs (#8468)

* fix:url truncates in docs

* refactor:added unit testcases made functions modular

* Keep the default selected as none in the environments (#8785)

* feat(request): warn when binary body file is missing on disk (#8753)

* fix/request - Binary body type - show warning on file not exists in system

* Made filename extraction OS-agnostic.

* Use theme tokens for warning colors in this styled-component block.

* Refactor FilePickerEditor to use useMissingFileCheck hook for file existence validation and improve warning display. Introduced new hook for checking missing files and updated tests to reflect changes in file picker behavior.

* Enhance FilePickerEditor: Update title handling for single/multiple filenames and improve warning tooltip layout with icon integration. Adjust StyledWrapper to utilize theme-based border radius for consistency.

---------

Co-authored-by: rajashreehj-bruno <rajashree@usebruno.com>

* updated test ids

* added dev tag so stories shows in docs only

* added disabled

* fix: failing test case fix (#8801)

* feat(db): sqlite as a re-usable SDK for secondary queries (#8533)

* chore: PR checklist update (#8806)

* fix: avoid network probe in PAC myIpAddress (#8588)

* fix

* Fix/collection runner loader issue (#8783)

* fix(runner): Collection Runner - Loader still keeps running even after Cancelling the execution

* added a test id for the action buttons

* removed onborading section

* updated bg of segment control

* added disabled color

* fix(bruno-response): normalize response header name lookup to be case-insensitive (#8461)

* fix(bruno-response): normalize header name lookup to be case-insensitive

* fix(bruno-response): handle non-string header names in getHeader method

* chore: resolve GitHub review conversations

* fix(dev-tools): console and network filter dropdown position to top if no space (#8713)

* fix(dev-tools): console and network filter dropdown scroll

* fix(ws-replace)/add height for ws msgs to fix search overlap

* fixed the accordion's isSearchOpen goes stale on collapse

* fix(workspace): notify about collections that fail to open in Workspa… (#8719)

* fix(workspace): notify about collections that fail to open in Workspace Home

* Resolved the coderabbit comments

* test(workspace): added e2e coverage for collections that fail to open

* resolved the code rabit comments

* refactor(ui): changed  data-testid prop on StatusBadge for consistency

* fix(workspace): exclude failed-to-open collections when reopening on config update

* test(workspace): added the switch-time aggregated toast for unopenable collections

* test(workspace): guard that config updates don't reopen failed-to-open collections

* feat(snapshot):persisting sidebar state in the snapshot (#8328)

* chore: new folder shortcut (#8805)

* refactor(ai): moved AI Assist from floating overlay into request pane and collection/folder settings tab bars (#8693)

* refactor(ai): moved AI Assist from floating overlay into request pane and collection/folder settings tab bars

* test(ai): added e2e coverage for AI Assist tab-bar placement across request pane, collection and folder settings

* test(ai): added e2e coverage for AI Assist tab-bar placement across request pane and settings

* test(ai): extended AI Assist tab-bar placement coverage to graphql, grpc, websocket, app tab and default script sub-tab

* scoped AI Assist placement assertions to the tab bar and added a settings tab bar test id

* feat(auth-headers):handling authorization header leaks to third party servers on redirect (#8380)

* feat: add forwardAuthorizationOnRedirect setting to allow stripping sensitive headers on cross-origin redirects

* feat: add forwardAuthorizationOnRedirect to opencollection types

* fix: restore missing forwardAuthorizationHeader config lines in runners and filestore

* feat: apply secure forwardAuthorizationHeader default to Insomnia and OpenAPI imports

* refactor: remove stale module augmentations for GraphQL and HTTP request settings

* refactor: centralize default HTTP request settings and improve test step organization

* chore: update @opencollection/types to version 0.10.0 across packages

* fix: handle cross-origin redirect auth stripping, and optimize Redux settings initialization

* refactor: fix formatting in collection schemas

* chore: remove unused data-testid from Settings toggle

* refactor: simplify forwardAuthorizationHeader serialization logic with nullish coalescing

* refactor: migrate redirect auth strip E2E tests to use common locators utility

* refactor: use toBool helper in bruToJson

* feat: update forwardAuthorizationHeader to respect Postman protocol profile behavior

* refactor: move DEFAULT_HTTP_ITEM_SETTINGS to bruno-common and update UI layout and redirection logic

* refactor: introduce type conversion helpers to simplify HTTP request setting parsing

* tests: support Postman protocolProfileBehavior for authorization header forwarding

* feat: add test ID to forward auth toggle

* feat: enable URL encoding by default in request settings

* refactor: centralize isSameOrigin utility and simplify GraphQL settings conversion logic

* refactor: replace manual type checks with toBool and toNumber helpers in collection converters

* refactor: migrate request settings test locators to page object model

* chore: set default encodeUrl to false and add line breaks for utils

* test: add regression tests for encode URL setting default behavior

* refactor: migrate encode-url-default-behaviour tests to use pageWithUserData fixture

* updated discable dtext opacity

* fix(node-vm): resolve npm modules from additionalContextRoots via native walk-up (#8538)

* fix: resolve npm modules from additionalContextRoots node_modules in NodeVM

When shared script folders configured via additionalContextRoots have
their own node_modules, the NodeVM runtime now searches those directories
for npm packages instead of only checking the collection and Bruno paths.

* fix(node-vm): enhance npm module resolution security by restricting access to ancestor node_modules

Added a new function to compare resolved npm module paths against allowed roots, ensuring that modules from ancestor directories outside the configured additionalContextRoots are not accessible. Updated the loadNpmModule function to utilize this security check during module resolution. Added tests to verify that ancestor node_modules cannot be accessed when not explicitly allowed.

* feat(tests): add integration tests for additionalContextRoots npm module resolution

Introduced a comprehensive set of integration tests to validate the resolution of npm modules from additionalContextRoots in the CLI. The tests ensure that shared libraries are correctly resolved, ancestor node_modules are inaccessible, and that collections can successfully utilize shared scripts. Additionally, created fixture files to support the testing environment, including workspace configurations and sample scripts for both collections A and B.

* chore(tests): update .gitignore to track specific node_modules for e2e tests

Modified .gitignore to include tracking for node_modules in test fixtures, ensuring that fake npm packages are available for end-to-end tests. Added new files for 'forbidden-lib' and 'signature-utils' to support testing scenarios.

* test(node-vm): add test for resolving npm modules via symlink in additionalContextRoots

Implemented a new test to verify that npm modules can be resolved correctly when additionalContextRoots points to a symlink. The test ensures that the symlinked library is accessible and that the context variable is set appropriately, enhancing the coverage for npm module resolution scenarios.

* feat(node-vm): enhance npm module resolution with additional context roots

Added support for resolving npm modules from additional context roots, including symlinked modules. Introduced new functions to validate module paths against allowed roots, ensuring security and proper resolution of transitive dependencies. Updated the loadNpmModule and createNpmModuleRequire functions to incorporate these changes, improving the flexibility and reliability of module loading in the NodeVM context.

* feat(node-vm): improve npm module resolution for linked packages

Enhanced the module resolution logic to allow internal relative requires within npm-linked packages, even when their physical location is outside declared allowed roots. Introduced a new function to find the closest package root, ensuring that internal dependencies can be resolved correctly. Updated tests to validate this behavior, confirming that the system handles linked packages as expected.

* feat(node-vm): support subpath imports for npm-linked packages

Enhanced the module resolution logic to allow subpath imports from npm-linked packages, ensuring that imports like `require('linked-pkg/utils')` are correctly resolved. Updated the `isModuleLinkedFromAllowedRoot` function to utilize bare-name lookup for improved accuracy. Added tests to validate this new behavior, confirming that subpath imports function as expected in the NodeVM context.

* refactor(tests): remove forbidden-lib tests and update integration scenarios

Eliminated tests related to the forbidden-lib package to streamline the test suite, ensuring that ancestor node_modules are not resolvable. Updated integration tests for additionalContextRoots to reflect changes in request counts and improved clarity in test descriptions. Adjusted workspace configurations to enhance overall test coverage and maintainability.

* refactor(cjs-loader): simplify module resolution documentation

Updated comments in the cjs-loader.js file to clarify the module resolution order, removing redundant explanations while maintaining essential details. This change enhances the readability and understanding of the module loading process in the NodeVM context.

* refactor(cjs-loader): improve comments and clarify module resolution logic

Updated comments in cjs-loader.js to enhance clarity regarding module resolution, specifically indicating fallback behavior when modules are not found in the collection. Adjusted the path used in createNpmModuleRequire for improved accuracy in module loading.

* feat(tests): add additional-context-root-lib and update workflows

Introduced the additional-context-root-lib package with its dependencies and updated relevant workflows to install this new library. Adjusted the CLI test and flaky test detector workflows to include installation steps for the additional-context-root-lib, ensuring proper setup for testing scenarios.

* refactor(tests): update npm module resolution test for additionalContextRoots

Revised the test case to ensure that requiring an npm package from a sibling additionalContextRoot fails as expected. Updated the test description for clarity and adjusted the script to reflect the intended behavior of module resolution, emphasizing the limitations of cross-root discovery in the NodeVM context.

* refactor(tests): clean up comments in node-vm sandbox tests

* refactor(tests): update fixture URLs in additional-context-roots tests

Modified the URLs in the .bru fixture files to point to the local testbench server instead of an external service. This change ensures consistent test behavior and eliminates reliance on external resources during testing.

* refactor(tests): enhance node-vm sandbox tests with symlink support

Introduced a symlink support check in the node-vm sandbox tests to conditionally skip tests on Windows where symlink creation is restricted. Refactored the test setup to utilize a new `makePkg` function for creating package directories and files, improving code readability and maintainability. Updated relevant tests to leverage this new structure, ensuring consistent behavior across different environments.

* refactor(setup): preserve specific node_modules during cleanup

Added a mechanism to preserve certain `node_modules` directories during the cleanup process in the setup script. This change ensures that fixture data remains intact for testing, specifically for directories related to additional context roots.

---------

Co-authored-by: lohit-bruno <lohit@usebruno.com>

* feat(cli): add --global-env-var to override global environment variables at runtime (#8620)

* feat(cli): add support for overriding global environment variables with --global-env-var option

- Introduced the --global-env-var option to allow users to overwrite global environment variables during command execution.
- Updated the command handler to validate and process global environment variable overrides.
- Enhanced the persistence logic to ensure that global environment variable overrides are handled correctly without leaking into the global environment file.
- Added tests to verify the correct behavior of global environment variable persistence.

* test(cli): enhance integration tests for global env var overrides

- Added checks to ensure that runtime overrides do not persist to the global environment file.
- Updated fixture scripts to reflect the expected behavior of global environment variable persistence.
- Improved the substitution logic for dynamic URLs in test fixtures to ensure accurate testing of overrides.

* refactor(tests): streamline CLI test arguments and error handling

- Refactored CLI test cases to use a consistent argument array for command execution.
- Improved error handling by consolidating error message construction for better readability.
- Ensured that the tests maintain clarity while verifying global environment variable overrides.

* fix: remove global env file check for global overrides

* refactor(persist-variables): enhance global environment variable handling

- Introduced a new `globalOverrides` option to manage global environment variable overrides more effectively.
- Updated logic to ensure that both local and global overrides are correctly applied and do not persist unintended values to the global environment file.
- Improved comments for clarity on the behavior of global environment variable persistence.

* fix: address review comments

* fix: address review comments

* removed chnages which were out of scope

* remove unused no-global-env fixture

* refactor(tests): update integration tests for global env var overrides

- Removed outdated fixture files related to global environment variable overrides.
- Enhanced the test setup to dynamically create necessary workspace and collection structures.
- Improved clarity in test descriptions and logic for validating that transient overrides do not persist to the global environment file.

* refactor(tests): simplify global env var test setup

* refactor(tests): remove outdated test for global env var persistence

* feat: add markdown mode to documentation editor and upgrade rich text editor extensions

* Fix: added actions for post reposne vars in yml (#8815)

* feat: introduce DocsEditor component and useDocsEditingState hook to support rich text editing in collection documentation

* fix: add dynamic font size adjustment for CodeMirror info display (#8817)

* fix: add dynamic font size adjustment for CodeMirror info display

* test: implement comprehensive E2E test suite and resolve rich text editor formatting issues

* feat(envs): adding search filter to environment selector dropdown (#8277)

* feat: adding search filter to environment selector dropdown

* fix: making the search input sticky

* test: updating tests into individual tests for environment selector search

* fix: avioding searchinput refocus if already focussed

* tests: ensuring dropdown open for tests and adding first printable key test

* refactor: replace inline search logic with reusable SearchInput component in EnvironmentSelector

* refactor: standardize environment selector locators and test actions for improved search functionality testing

* test: update environment search casing, improve tab state handling in actions

* refactor: decouple and centralize collection header locators and utility functions into dedicated module

* refactor: migrate environment selector locators to a dedicated utilities file and update collection header references

* refactor: consolidate collection header locators and update environment selector test utilities

* test: add and implement closeEnvironmentSelector utility to clean up environment selector state in tests

* refactor: simplify environment selector lifecycle management by centralizing open/close logic in test hooks

* refactor: lift search state to environment selector and clear input on close

* test: refactor EnvironmentListContent unit tests to use a wrapper component for state management and update clear button selector

* fix(locators): reverting environment selector locator reference

* refactor: clear search input when switching environment tabs and ensure persistent visibility of configure button

* test: add global environments data and verify search functionality in environment selector

---------

Co-authored-by: sachin-thakur-bruno <sachin.thakur@usebruno.com>

* feat(client certs): add global client certs and allow disabling individual client certs. (#8751)

* feat: add client certificates to global preferences

* feat(client certificates): apply global client certs on requests, allow disabling individual certs at global and collection level

* fix: create list group component. modify client certificate UI to match new mockup.

* test(client certs): setup client certs test suite and add CLI test cases for client certs

* test(client certs): add E2E cases for collection and global client certs

* fix: fix code review comments from claude

* fix: count test failures using filter to remove duplicate counting.

* fix: minor UI fixes to support storybook

* fix: remove duplicated onboarding config from test preferences.json

* fix: use testIds on test and ws responses for better test reachability. use the new test-ids on locators

* fix: coderabbit fixes

* fix: fix lint issues

* fix: review comment changes for test cases

* fix: add timeout for the fixture setup

* fix: add break for grpcCurl to match first case

* test: prevent stale response reads in client-cert e2e specs

* fix: add separate fixture for sandbox modes in WSS to prevent stale close connection message

* fix: add regex matching for ws assertions to reduce flakiness

* fix: fix list group "add button"'s icon alignment

* fix: add save button to collection client certificates

* test: add collection client certificate precedence test case

* feat(presets)/updated the requests to use segmented control (#8816)

* feat(presets)/updated the requests to use segmented control

* updated icons

* yml migration rework (#8795)

* feat: extend markdown linkify support for relative assets in rich text editor

* feat: add color-scheme support for task list items in editor styles

* refactor: updating file/folder structure for docs editor files

* refactor: encapsulate DocsAction styling in a new StyledWrapper component

* refactor: update richtext editor tests to import utilities from actions instead of utils

* fix:cmd+w now works for transient tabs (#8429)

* fix:cmd+w now works for transient tabs

* test: verify URL is preserved after saving and closing a transient tab

* test: use centralized page locators and test.step in the transient close spec

* refactor: branch on transient at the save dispatch site

* refactor:use if/else branches in onSaveAndClose

---------

Co-authored-by: Adwait Aayush <adwaitaayush@Adwaits-MacBook-Air.local>

* Fix: Description missing for the import export yml for the environments (#8822)

* Fix: Description not there in the import export yml for the environments

* Comments addressed

* Comments addressed

* security(ipc): confine renderer file writes to known collections (#8274)

* fix(openapi):strip trailing dots from operation names on import (#8812)

* fix(openapi):strip trailing dots from operation names on import

* fix(openapi): strip trailing dots from environment names on import

---------

Co-authored-by: Adwait Aayush <adwaitaayush@Adwaits-MacBook-Air.local>

* feat(rich-text-editor)/scroll persist

* fix:populate collection & folder docs on OpenAPI/swagger imports (#8803)

* fix:populate collection & folder docs on OpenAPI/swagger imports

* fix(openapi): coerce spec descriptions to strings before use

* test(openapi): extract findRequestByName/findFolderByName into shared helper

* fix:guard against object names

---------

Co-authored-by: Adwait Aayush <adwaitaayush@Adwaits-MacBook-Air.local>

* fix(generate-code): generate code for url interpolation (#7308)

* fix(presets)/ux fixes for dropdown and icon spacing (#8827)

* fix ux

* updated padding

* fix(secrets): block duplicate secret names to prevent value loss (#8750)

* refactor: migrate documentation edit toggle to use test ID instead of class selector

* refactor: migrate collection and folder documentation edit toggle to shared DocsAction component

* chore: enhance claude rules & skills

* feat: support drag-and-drop and alphabetical sorting for variables (#8603)

* test: update doc toggle locators to use test-ids

* Mock Server Implementation (#8734)

* reported how many collections failed to open on workspace load (#8831)

* reported how many collections failed to open on workspace load

* Added the failed collection in the overview list of collections in the workspace

* test: fix the draft indicator tests for collection client certs (#8824)

* fix(generate-code): encode a literal colon in the path when the toggl… (#8834)

* fix(e2e): Playwright failures from mock server and lazy mount (#8835)

* fix: green Linux Playwright failures from mock server and lazy mount

Unscoped Create clicks collided with the new mock-server button, and
sidebar-created examples open in edit mode so view-mode title asserts
were stale. Cross-format drops into unmounted workspace collections
also failed path confinement; mount on drop and treat last-opened
collections as known roots.

* Update packages/bruno-electron/src/ipc/collection.js

* refactor: simplify collection path retrieval in findCollectionPathByItemPath function

* test: update method search test to use test-id for environment selection

* fix: simplify watcher management in CollectionWatcher class

* feat(presets)/updated presets design (#8828)

* feat(presets)/updated presets design

* fixed text

* updated the text

* removed styles

* ci: move all linux to self hosted (#8791)

* feat(docs): syntax highlighting for code blocks in rich text docs (#8670)

* feat(presets)/updated dropdown with menu dropdown and label weight ux changes (#8841)

* feat(presets)/updated dropdown with menu dropdown and label weight ux changes

* removed the comment

* used button for dropdown trigger

* feat(tests): enhance CodeEditor and EditorCodeBlock tests with additional mocks and configurations (#8858)

* fix:sorting now works for secrets tab (#8871)

* fix(mount): hydrate websocket message uids in the cached mount path (#8862)

WS message expand/collapse is keyed by the message uid, so a message
without one cannot be opened at all — the toggle bails on a falsy uid and
every row renders with the same undefined React key.

The v1 mount path hydrated request.body.ws (via hydrateRequestWithUuid),
but mount v2's uid list omitted it. With File Cache enabled the tree is
built from the cache on cold start, so every WS message arrived with no
uid and its body could not be expanded. It only reproduced after a
restart because live edits during a session still flow through the
collection watcher's v1 hydration.

Since v2 seeds uids deterministically from the file path, expanded-message
state now also survives a restart instead of resetting.

* fix:keep sort column header from shifting when the arrow appears (#8833)

* fix:keep sort column header from shifting when the arrow appears

---------
Co-authored-by: Sid <siddharth@usebruno.com>

* fix:change-version modal ui (#8735)

* fix:change-version modal ui

* feat: add migrate-to-YML pill to collection header (#8882)

* fix(mock-server): bring the UI in line with the rest of Bruno (#8880)

* fix(mock-server): bring the UI in line with the rest of Bruno

* fix

---------

Co-authored-by: Utkarsh <utkarsh@usebruno.com>

* fix(ws): disable message queuing when in intermediate connection states (#8879)

* feat: add disabled state to SendButton based on connection status

* Update packages/bruno-app/src/components/RequestPane/WsQueryUrl/index.js

Co-authored-by: Chirag Chandrashekhar <chirag@usebruno.com>

* fix: update WebSocket connection handling and improve run button behavior

---------

Co-authored-by: Chirag Chandrashekhar <chirag@usebruno.com>

* fix(proxy): update timestamp label format  (#8870)

* fix(proxy): update timestamp label format and enhance timestamp utility function

* fix(tests): update timestamp regex to match AM/PM format in system proxy tests

* fix(timestamp): enhance formatProxyTimestamp function to replace non-breaking spaces and update regex for system proxy timestamp

* fix: persist additional request values in preferences general tab save (#8823)

* fix (transient-request): unable to create transient request when preset is websocket (#8889)

* fix(transient): updated the websocket type key from websocket to ws to match the key coming from presets

* test(transient): added tests, locators, and actions to validate the default request type of transient request when a preset is selected

* refactor(import): imported the REQUEST_TYPE (aliased) from common utils and removed unused imports

* fixes: OpenAPI Spec Viewer: throws resolver errors for `$ref` schemas  (#8892)

* fix(app): global environment variables for apps (#8900)

* feat(mock-server): enhance MockResponseRequestPane with method selection and other minor tweaks (#8885)

* fix(auth): stop AWS V4 auth headers from leaking on cross-origin redirects (#8893)

* fix: strip AWS Signature V4 headers on cross-origin redirects when authorization forwarding is disabled

* fix: prevent AWS SigV4 header leakage on cross-origin redirects by isolating signature removal from authorization header forwarding

* refactor: update formatting of AWS SigV4 redirect comment block for readability

* refactor: simplify response text extraction in redirect authentication tests using innerText

* fix(editor): allow app keybindings if that keybindings is not present in rich text editor (#8894)

* fix(doc-editor)/key bindings for doc editor

* fix(mock-server): improve mock response name validation (#8908)

* feat(migrate): enhance migration modal to handle collection drafts (#8899)

* fix(codemirror-search)/keybinding for focusing search and replace inside the search container (#8895)

* fix(sidebar): prevent drag divider from disappearing on zoom-out (#8266)

* fix(sidebar): prevent drag divider from disappearing on zoom-out

* fix(sidebar): keep resize divider visible across tabs and zoom levels

* refactor: remove AI documentation assistant and related context payload generation from documentation components (#8921)

* fix(editor)/add guessed language in language dropdown picket (#8925)

* fix(editor): tab indentation on code blocks (#8926)

* fix(git): use removePath for failed-clone cleanup

ipc/git.js imported removeDirectory from utils/filesystem, which only
exports removePath. On a failed clone the cleanup branch threw
"TypeError: removeDirectory is not a function", replacing the rejection
and hiding why the clone actually failed.

removePath removes recursively, which is the semantics this call wanted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: restore upstream code the fork had stripped

These files carried no RestWolf feature - the earlier squash-sync had
rolled back upstream improvements, and the merge preserved those
rollbacks because upstream's later edits did not textually conflict.

- CreateCollection / CreateWorkspace: name trimming and validation messages
- ExampleTab: exampleIndex lookup, matching the accessor restored in
  tabs.js and the snapshot serializer
- insomnia converter specs, request-pane-interactivity, create-collection
  and create-workspace e2e specs

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: restore remaining upstream code stripped by the fork

Same pattern as the previous commit, found by diffing the merged tree
against upstream/main for net deletions:

- RequestTabPanel / ExampleItem: exampleIndex plumbing
- insomnia-to-bruno: empty-mimeType text body handling, covered by the
  insomnia specs restored earlier (now passing)

Remaining divergence from upstream is fork features and branding only:
Azure Vault, saved auth modes, tab retention, theme colours, RestWolf
branding, auto-updater, PostHog removal, and trimmed docs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(git): add Git UI tab and branch chip

Upstream ships the git engine in bruno-electron/src/utils/git.js but wires
only clone to IPC, so none of it is reachable from the app. This registers
the rest and adds the UI.

IPC (ipc/git.js): status, init, stage, unstage, discard, commit, file diff,
fetch, pull, push. Each mutating handler returns the recomputed panel state
so the renderer never has to re-query.

UI: a Git UI tab (left panel with commit box and changed-file list, right
pane with fetch/pull/push and ahead-behind), opened from a branch chip in
the collection toolbar. Both read shared state via the useGitStatus hook.

Two quirks in the existing utils this works around:
- pullGitChanges rejects unless given an explicit merge strategy
- getUnstagedFileDiff matches absolute paths, while git status reports
  repo-relative ones

Verified against a real repository: status, branch, remote and diffs; plus
a full init/stage/commit/edit/diff/discard round trip on a scratch repo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(theme): move accent colour into the Appearance dropdown

The fork repurposed ColorPicker to take value/label/onReset for the accent
colour, but the merge restored upstream's per-environment call sites, which
pass a `color` prop that component no longer reads. Both environment panels
therefore rendered the accent picker and edited the app accent.

Removes the picker from both environment panels and from the Themes
preferences pane, and puts it in the Appearance dropdown behind the palette
button in the status bar, where it edits the accent for whichever theme is
on screen.

feat(git): branch switching in the Git UI

Adds a renderer:git-checkout handler and a branch switcher in the panel
footer. A checkout that would overwrite local edits is left to fail, and
git's own message is shown in the panel - matching how VS Code reports it -
rather than being forced or auto-stashed.

Verified: create-and-switch, clean switch, and a dirty switch refused with
"Your local changes to the following files would be overwritten by
checkout", with the edit left intact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(theme): keep the accent picker inside the Appearance menu

.theme-menu had a fixed 325px height, so the accent row rendered past the
bottom edge and overlapped the status bar. min-height lets the menu grow
while keeping its size steady when the theme lists are short.

The swatch's own dropdown is absolutely positioned below its trigger, which
falls off-screen for a menu anchored to the status bar, so it is flipped to
open upward within this section.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore: remove screenshot committed by mistake

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(git): pass remote and branch to push and pull

pushGitChanges looks the branch up by name (branchSummary.branches[remoteBranch])
and rejects with "Branch undefined does not exist" when it isn't supplied, so
Push failed from the panel. Both handlers now default the remote to origin and
resolve the current branch.

Verified against a local bare remote: commit leaves ahead=1, push clears it,
a remote commit shows behind=1 after fetch, and pull brings it down.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(git): sync button and visible feedback for git operations

Git operations succeed silently, so a push that worked and a push that
failed looked identical - the error banner only rendered inside the sidebar's
Changes section, which is collapsible and sits away from the buttons.

Every operation now reports through a toast, and the error banner also shows
next to the fetch/pull/push controls.

Adds a Sync button that pulls before pushing, matching VS Code's ordering so a
diverged branch does not hit a non-fast-forward rejection. Its label states
what will move: "Sync 2 down, 1 up", "Push 3 commits", "Pull 1 commit", or
"Sync Changes" when level.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(secrets): secret managers with ordered vault tiers

Replaces the single enable-and-configure Azure vault in General preferences
with a Secrets Manager section modelled on how Bruno configures providers:
add a provider, pick Azure Key Vault, enter connection details, test the
connection. Providers are listed in precedence order.

Environments gain an ordered list of vault secret names on the Secrets tab,
matching the vault-teller tier layout (tenant, cluster, global). Resolution
is first-match-wins per key, so the most specific tier sits at the top -
the same precedence as vault-teller's tenant ?? cluster ?? global.

Fetching shows what each tier actually contributed: a source dropdown
switches between the merged view and any single secret, and keys claimed by
a higher tier are struck through with the winner named, so a shadowed value
is visible rather than looking ignored.

Credentials are now encrypted at rest via the existing safeStorage-backed
helpers instead of sitting in plain text in preferences.json, and the client
secret is never sent to the renderer.

The ordered secret names persist as a VAULT_SECRETS environment variable so
they travel with the collection in git; the previous VAULT_SECRET is still
read so existing environments keep working.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(secrets): make the vault panel reachable in global environments

The panel was passed as renderExtraButtonContent, which the table renders
inline beside Save and Reset, so a block-level panel with tables was crushed
into that row. It is now a sibling of the table inside a scrolling column,
since neither the environment content area nor the table wrapper scrolls -
without that, a fetched result pushed the table's Save button out of reach.

The resolved table is capped and scrolls on its own, and the panel header
carrying Apply is sticky so it stays available while reading a long tier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(secrets): pin each vault secret to a provider

Each entry on the environment's Secrets tab now carries a vault dropdown, so
a tier can name which provider serves it rather than relying on lookup order.
"Any vault" keeps the previous behaviour of trying each configured provider
in turn.

A pinned vault is honoured or reported: an unknown vault name, or a secret
missing from the pinned vault, is surfaced as an error instead of falling
back to another provider, which would otherwise hand back a different
environment's values under the same key.

The choice persists by vault name rather than local id so it still resolves
for a teammate whose provider has a different id. Entries serialise as
"<vault>:<secret>" in VAULT_SECRETS, with bare names still accepted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* style(secrets): fix operator indentation in the resolver

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* feat(secrets): clear all vault secrets from an environment

Reset reverts the table to the saved environment, so once fetched secrets
have been saved there is nothing for it to undo and it appears to do nothing.
Removing them meant deleting each row by hand.

Adds a Clear secrets action beside Apply, giving the bulk add a matching bulk
removal. It drops the rows from the table only, so the environment still has
to be saved and a mis-click is undone by Reset.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* chore(release): bump RestWolf to 4.0.0

Major bump for the upstream v3-to-v4 merge and the features built on it:
Git UI, secret managers with ordered vault tiers, and the accent colour move.

Version lives only in packages/bruno-electron/package.json - electron-builder
reads it for artifact names, and scripts/release.js bumps it from there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Pooja <pooja@usebruno.com>
Co-authored-by: Sundram <sundram@usebruno.com>
Co-authored-by: Bijin A B <bijin@usebruno.com>
Co-authored-by: gopu-bruno <gopu@usebruno.com>
Co-authored-by: naman-bruno <naman@usebruno.com>
Co-authored-by: ravindra-bruno <ravindra@usebruno.com>
Co-authored-by: Abhishek Patil <abhishek.p@usebruno.com>
Co-authored-by: Gopi-bruno <gopi@usebruno.com>
Co-authored-by: sachin-bruno <sachin@usebruno.com>
Co-authored-by: Sid <siddharth@usebruno.com>
Co-authored-by: Chirag Chandrashekhar <chirag@usebruno.com>
Co-authored-by: shubh-bruno <shubham@usebruno.com>
Co-authored-by: Jiawen Geng <technicalcute@gmail.com>
Co-authored-by: anusree-bruno <anusree@usebruno.com>
Co-authored-by: Rohan-Bruno <rohan@usebruno.com>
Co-authored-by: sachin-thakur-bruno <sachin.thakur@usebruno.com>
Co-authored-by: Ryan <ryan@usebruno.com>
Co-authored-by: shubh-bruno <shubh-bruno@shubh-bruno.local>
Co-authored-by: Utkarsh <utkarsh@usebruno.com>
Co-authored-by: morsh-bruno <morsh@usebruno.com>
Co-authored-by: sanish chirayath <sanish@usebruno.com>
Co-authored-by: rajashreehj-bruno <rajashree@usebruno.com>
Co-authored-by: adwait-bruno <adwait@usebruno.com>
Co-authored-by: Adwait Aayush <adwaitaayush@Adwaits-MacBook-Air.local>
Co-authored-by: Rayan Salhab <r.salhab@aiyexpertsolutions.com>
Co-authored-by: sharan-bruno <sharanabasappa@usebruno.com>
Co-authored-by: lohit-bruno <lohit@usebruno.com>
Co-authored-by: arpit-bruno <arpit@usebruno.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants