Skip to content

Merge Bruno v4 into RestWolf, and rework the vault integration - #21

Merged
AustralianRaven merged 506 commits into
mainfrom
chore/merge-upstream-v3
Aug 18, 2026
Merged

Merge Bruno v4 into RestWolf, and rework the vault integration#21
AustralianRaven merged 506 commits into
mainfrom
chore/merge-upstream-v3

Conversation

@AustralianRaven

Copy link
Copy Markdown
Owner

Summary

  • Merges 490 upstream commits from usebruno/bruno main (past the v4.0.0 tag) into RestWolf, resolving 44 conflicting files while keeping every fork feature working: Azure Vault, saved and per-environment auth modes, tab retention, custom accent colour, RestWolf branding, the auto-updater and release pipeline, and the PostHog removal.
  • Wires up Bruno's git engine, which upstream ships but never registers. Adds a Git UI tab and a toolbar branch chip covering status, stage/unstage, discard, commit, diffs, fetch/pull/push, sync and branch switching.
  • Replaces the single enable-and-configure Azure vault with a Secrets Manager section in Preferences, plus an ordered list of vault secrets per environment mirroring the vault-teller tier layout (tenant, cluster, global) with first-match-wins precedence.
  • Moves the accent colour picker out of the environment panels and the Themes pane into the Appearance dropdown, fixing a regression where the environment screens edited the app accent.
  • Restores upstream code an earlier squash-sync had silently rolled back, and bumps RestWolf to 4.0.0.

Changed files

packages/bruno-electron/src/ipc/git.js
Registers the git operations upstream leaves unreachable: status, init, stage, unstage, discard, commit, file diff, fetch, pull, push and checkout. Every mutating handler returns the recomputed panel state so the renderer never has to re-query. Also works around two quirks in the existing utils — pullGitChanges rejects without an explicit merge strategy, and getUnstagedFileDiff matches absolute paths while git status reports repo-relative ones.

packages/bruno-app/src/hooks/useGitStatus/index.js
Shared git state for a collection, used by both the Git UI tab and the toolbar chip so an action in one updates the other. Each operation reports through a toast, because git succeeds silently and a working push was otherwise indistinguishable from a broken button. sync() pulls before pushing so a diverged branch does not hit a non-fast-forward rejection.

packages/bruno-app/src/components/Git/GitUI/
The Git UI tab: a sidebar with the commit box and changed-file list, and a main pane with sync, fetch, pull, push, ahead/behind counts and a branch switcher. Selecting a file swaps the pane for a coloured diff. A checkout that would overwrite local edits is left to fail so git's own message surfaces, rather than being forced or auto-stashed.

packages/bruno-app/src/components/Git/GitBranchChip/
Branch chip in the collection toolbar showing the current branch and ahead/behind drift, rendered only for collections that sit inside a git repository. Clicking it opens the Git UI tab.

packages/bruno-electron/src/store/secret-managers.js
New encrypted store for external secret providers. Credentials previously sat in plain text in preferences.json; the client secret is now encrypted at rest through the existing safeStorage-backed helpers and never leaves the main process. Provider order is meaningful — it is the precedence used when a secret could come from more than one vault.

packages/bruno-electron/src/ipc/secret-managers.js
CRUD, connection testing and resolution for secret providers. Resolution walks an ordered list of {vaultName, secretName} refs, first match winning per key, and records what each tier shadowed so a lower tier does not look silently ignored. A pinned vault is honoured or reported rather than falling back to another provider, which would otherwise return a different environment's values under the same key names.

packages/bruno-app/src/components/Preferences/SecretsManager/
Preferences pane for adding, editing, reordering and removing providers, with a Test Connection action. The client secret field stays blank when editing and only overwrites the stored value when a replacement is typed.

packages/bruno-app/src/components/Environments/VaultSecrets/
The environment Secrets panel. Holds the ordered secret list, each row pinned to a provider or left as "any vault", and after fetching offers a source dropdown to switch between the merged view and any single tier. Keys claimed by a higher tier are struck through and labelled with the winner. Apply pushes the merged set into the environment; Clear removes the secret rows, since Reset only reverts to the saved state and is no help once they have been saved.

packages/bruno-app/src/components/WorkspaceHome/WorkspaceEnvironments/EnvironmentList/EnvironmentDetails/EnvironmentVariables/index.js
Rewritten around the ordered secret refs. The list persists as a single VAULT_SECRETS variable of <vault>:<secret> entries so it travels with the collection in git; the previous VAULT_SECRET is still read. The panel is a sibling of the table inside a scrolling column, because neither the environment content area nor the table wrapper scrolls, and an unbounded panel pushed the table's Save button out of reach.

packages/bruno-app/src/components/EnvironmentVariablesTable/index.js
Handles the bulk apply and bulk clear events from the vault panel. Values arriving from a vault are now all marked secret rather than guessed at by name, so they land on the Secrets tab and are masked. The old inline vault row and its styles are removed.

packages/bruno-app/src/components/Preferences/General/index.js
Drops the Azure vault section, its Yup schema and its save payload, superseded by the Secrets Manager pane.

packages/bruno-electron/src/ipc/azure-vault.js
Deleted. Its single-vault fetch is replaced by the provider-aware resolver; services/azure-vault.js remains as the Azure client.

packages/bruno-app/src/components/StatusBar/ThemeDropdown/
Hosts the accent colour picker, editing the accent for whichever theme is currently displayed. The menu's fixed height became a minimum so the new row does not spill out over the status bar, and the swatch's own dropdown opens upward since the menu is anchored to the bottom of the window.

packages/bruno-app/src/components/Preferences/Themes/index.js and packages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/index.js
Remove the accent picker. The fork had repurposed ColorPicker to take value/label/onReset, so upstream's per-environment call sites — which pass a color prop it no longer reads — were rendering the accent picker and editing the app accent.

packages/bruno-app/src/components/Preferences/index.js
Registers the Secrets Manager tab.

packages/bruno-app/src/providers/ReduxStore/slices/tabs.js, packages/bruno-app/src/components/RequestTabs/RequestTab/SpecialTab.js, packages/bruno-app/src/components/RequestTabs/RequestTab/index.js, packages/bruno-app/src/components/RequestTabPanel/index.js, packages/bruno-app/src/components/RequestTabs/CollectionHeader/index.js
Register git-ui as a non-replaceable tab type, give it an icon and label, render the panel for that tab, and place the branch chip in the collection toolbar.

packages/bruno-lang/v2/src/envToJson.js, packages/bruno-lang/v2/src/jsonToEnv.js
Conflict resolution on the environment grammar: the fork's meta block and upstream's externalsecrets block now both parse and serialise instead of one replacing the other.

packages/bruno-filestore/src/formats/yml/parseEnvironment.ts, packages/bruno-filestore/src/formats/yml/stringifyEnvironment.ts
Environment auth (fork) and externalSecrets (upstream) both round-trip through the yml format.

packages/bruno-schema/src/collections/index.js
Environment schema carries both auth and externalSecrets, and the auth mode enum unions the fork's inherit-environment and named with upstream's akamai-edgegrid. Without this the save path rejects the merged shape.

packages/bruno-app/src/components/Sidebar/CreateCollection/index.js, packages/bruno-app/src/components/WorkspaceSidebar/CreateWorkspace/index.js, packages/bruno-app/src/components/RequestTabs/ExampleTab/index.js, packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/ExampleItem/index.js
Restore upstream behaviour the earlier squash-sync had rolled back: name trimming and validation messages on create, and the exampleIndex plumbing that keeps a response example distinct from its request.

packages/bruno-converters/src/insomnia/insomnia-to-bruno.js
Restores handling for an empty mime type with a text body, covered by the Insomnia specs restored alongside it.

packages/bruno-electron/src/index.js
Swaps the Azure vault IPC registration for the secret manager one, and keeps the fork's auto-updater init alongside upstream's new mock-server, AI, mount and sqlite registrations.

packages/bruno-electron/package.json
Bumps RestWolf to 4.0.0. This is the only file carrying the app version — electron-builder reads it for artifact names and scripts/release.js bumps it from there.

Restored test filestests/snapshots/request-pane-interactivity.spec.ts, tests/collection/create/create-collection.spec.ts, tests/workspace/create-workspace/create-workspace.spec.ts, packages/bruno-converters/tests/insomnia/insomnia-collection.spec.js, packages/bruno-converters/tests/insomnia/insomnia-collection-v5.spec.js
Upstream specs the fork had deleted, restored so the behaviours above stay covered. Two of the regressions listed here were caught by these tests once they were back in place.

pooja-bruno and others added 30 commits July 15, 2026 20:48
…runo#8622)

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

* fix

* add: test

* rm: only

* improvement
…8627)

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

* fix: test

---------

Co-authored-by: naman-bruno <naman@usebruno.com>
…s + invalid res (usebruno#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
…rsTable (usebruno#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
…ogs to console (usebruno#8650)

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

* fix(app): log bru.ctx.log output into app console
arpit-bruno and others added 28 commits August 7, 2026 15:54
…rects (usebruno#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
… in rich text editor (usebruno#8894)

* fix(doc-editor)/key bindings for doc editor
…bruno#8266)

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

* fix(sidebar): keep resize divider visible across tabs and zoom levels
Brings in 490 upstream commits (v3.0.1 -> v4.x line), including the
in-app Git integration: clone/commit/pull/push from the UI, the visual
diff viewer, and git-remote collections.

Fork features preserved: Azure Vault, saved/per-environment auth modes,
tab retention, custom theme colour, RestWolf branding, auto-updater and
release pipeline, PostHog removal.

Notable conflict resolutions:
- Environment auth (fork) and externalSecrets (upstream) both persist in
  the .bru grammar, yml parse/stringify, and the Yup schema.
- Environment detail panels adopt upstream's Variables/Secrets tab system,
  with the fork's env-auth panel added as a third tab.
- Auth mode pickers keep the fork's grouped "Saved Auths" menu and gain
  upstream's akamai-edgegrid mode.
- WorkspaceEnvironments keeps the fork's env + auth-mode sidebar rewrite.

Also reverts three regressions the previous squash-sync introduced, which
upstream's restored tests caught: Postman API-key placement mapping, the
response-example guards in tab selectors, and the tab/snapshot exampleIndex
accessor.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
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>
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>
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>
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>
.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>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
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>
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>
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>
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>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
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>
@AustralianRaven
AustralianRaven merged commit bc6385f into main Aug 18, 2026
3 of 18 checks passed
@AustralianRaven
AustralianRaven deleted the chore/merge-upstream-v3 branch August 18, 2026 05:25
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.