Merge Bruno v4 into RestWolf, and rework the vault integration - #21
Merged
Conversation
…runo#8622) * fix(ws): keep body-mode dropdown above collapsed sticky headers * fix * add: test * rm: only * improvement
Co-authored-by: Bijin A B <bijin@usebruno.com>
…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
…pdate toolbar link handling
…ion and other minor tweaks (usebruno#8885)
…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
…ide the search container (usebruno#8895)
…bruno#8266) * fix(sidebar): prevent drag divider from disappearing on zoom-out * fix(sidebar): keep resize divider visible across tabs and zoom levels
…ad generation from documentation components (usebruno#8921)
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
usebruno/brunomain(past thev4.0.0tag) 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.vault-tellertier layout (tenant, cluster, global) with first-match-wins precedence.4.0.0.Changed files
packages/bruno-electron/src/ipc/git.jsRegisters 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 —
pullGitChangesrejects without an explicit merge strategy, andgetUnstagedFileDiffmatches absolute paths whilegit statusreports repo-relative ones.packages/bruno-app/src/hooks/useGitStatus/index.jsShared 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.jsNew 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.jsCRUD, 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.jsRewritten around the ordered secret refs. The list persists as a single
VAULT_SECRETSvariable of<vault>:<secret>entries so it travels with the collection in git; the previousVAULT_SECRETis 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.jsHandles 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.jsDrops the Azure vault section, its Yup schema and its save payload, superseded by the Secrets Manager pane.
packages/bruno-electron/src/ipc/azure-vault.jsDeleted. Its single-vault fetch is replaced by the provider-aware resolver;
services/azure-vault.jsremains 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.jsandpackages/bruno-app/src/components/Environments/EnvironmentSettings/EnvironmentList/EnvironmentDetails/index.jsRemove the accent picker. The fork had repurposed
ColorPickerto takevalue/label/onReset, so upstream's per-environment call sites — which pass acolorprop it no longer reads — were rendering the accent picker and editing the app accent.packages/bruno-app/src/components/Preferences/index.jsRegisters 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.jsRegister
git-uias 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.jsConflict resolution on the environment grammar: the fork's
metablock and upstream'sexternalsecretsblock 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.tsEnvironment auth (fork) and
externalSecrets(upstream) both round-trip through the yml format.packages/bruno-schema/src/collections/index.jsEnvironment schema carries both
authandexternalSecrets, and the auth mode enum unions the fork'sinherit-environmentandnamedwith upstream'sakamai-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.jsRestore upstream behaviour the earlier squash-sync had rolled back: name trimming and validation messages on create, and the
exampleIndexplumbing that keeps a response example distinct from its request.packages/bruno-converters/src/insomnia/insomnia-to-bruno.jsRestores handling for an empty mime type with a text body, covered by the Insomnia specs restored alongside it.
packages/bruno-electron/src/index.jsSwaps 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.jsonBumps RestWolf to
4.0.0. This is the only file carrying the app version —electron-builderreads it for artifact names andscripts/release.jsbumps it from there.Restored test files —
tests/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.jsUpstream 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.