diff --git a/.claude/settings.json b/.claude/settings.json index 0ca43abce..283326b83 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -19,7 +19,10 @@ "Bash(npx nx:*)", "Bash(yarn build:ci)", "Bash(gh api:*)", - "Bash(yarn tsc:*)" + "Bash(yarn tsc:*)", + "Bash(gh release *)", + "Bash(gh pr *)", + "Bash(yarn release-notes:generate)" ], "deny": [], "ask": [] diff --git a/apps/docs/docusaurus.config.ts b/apps/docs/docusaurus.config.ts index 89dffd248..25a55683e 100644 --- a/apps/docs/docusaurus.config.ts +++ b/apps/docs/docusaurus.config.ts @@ -66,6 +66,27 @@ const config: Config = { } satisfies Preset.Options, ], ], + plugins: [ + [ + '@docusaurus/plugin-content-blog', + { + id: 'release-notes', + routeBasePath: 'release-notes', + path: './release-notes', + blogTitle: 'Release notes', + blogDescription: "What's new in Jetstream.", + blogSidebarTitle: 'All releases', + blogSidebarCount: 'ALL', + showReadingTime: false, + editUrl: 'https://github.com/jetstreamapp/jetstream/tree/main/apps/docs/', + feedOptions: { + type: 'all', + title: 'Jetstream release notes', + copyright: `Copyright © ${new Date().getFullYear()} Jetstream.`, + }, + }, + ], + ], themeConfig: { colorMode: { defaultMode: 'dark', @@ -89,6 +110,11 @@ const config: Config = { srcDark: 'img/jetstream-logo-inverse.svg', }, items: [ + { + to: '/release-notes', + label: 'Release notes', + position: 'right', + }, { href: 'https://getjetstream.app', label: 'Jetstream', diff --git a/apps/docs/release-notes/2025-07-27-v7.0.0.mdx b/apps/docs/release-notes/2025-07-27-v7.0.0.mdx new file mode 100644 index 000000000..6badc6abf --- /dev/null +++ b/apps/docs/release-notes/2025-07-27-v7.0.0.mdx @@ -0,0 +1,60 @@ +--- +slug: v7.0.0 +title: 7.0.0 - React 19, Jotai state, and better datatable keyboard navigation +date: '2025-07-27' +authors: [jetstream] +tags: [web, extension] +versions: + web: 7.0.0 + extension: 2.0.0 +summary: Major foundation update. Jetstream now runs on React 19 with Jotai for state and Floating UI for popovers, plus meaningful wins for keyboard users in the datatable. +highlights: + - title: Improved datatable keyboard navigation + description: Tab now cycles through action and record Id cells, Enter opens the record popover, and inline editing matches SLDS styles. + docLink: /query/query-results + platforms: [web, extension] + - title: Tooltips respond to keyboard focus + description: Focusing a button or icon with the keyboard now shows its tooltip, matching the behavior you get with a mouse hover. + platforms: [web, extension] + - title: Bulk update from query results fixed + description: The bulk update job from query results no longer fails because of a stale polling callback, so jobs complete and surface their status correctly. + docLink: /query/query-results + platforms: [web, extension] + - title: Dropdowns close reliably on outside click + description: Clicking outside a dropdown now closes it in the cases where it was previously staying open. + platforms: [web, extension] + - title: Modernized popovers and tooltips + description: Popovers and tooltips moved to Floating UI, which fixes several nested portal and positioning glitches across modals and popovers. + platforms: [web, extension] +--- + +{/* truncate */} + +## What's new + +### Datatable keyboard navigation + +Tabbing through the query and load datatables now behaves more predictably. The action column and the Id column are reachable with Tab, and pressing Enter on an Id cell opens the record popover. Copying a cell with the keyboard gets a visible focus style, and inline cell editing has been cleaned up to match SLDS. These changes apply anywhere the datatable is used, including query results and the web extension. + +### Tooltips with keyboard focus + +Tooltips now open when a control receives keyboard focus, not just when the mouse hovers. This makes icon-only buttons discoverable without a pointer. + +### Bulk update from query results + +Fixed a bug where the bulk update job launched from query results would silently fail because the polling callback captured stale state and never attached the job id to the tracked data. Polling now reads fresh state on each tick. + +### Foundation upgrades + +Under the hood this release rebuilds several foundations: + +- Upgraded to React 19. +- Migrated state management from Recoil (unmaintained) to Jotai. +- Migrated tooltips and popovers from Tippy and Popper.js to Floating UI, which resolved a handful of nested-portal and positioning bugs in modals and popovers. +- Upgraded the react-data-grid library. + +No action is required. If you notice any regression in tooltips, popovers, dropdowns, or inline editing after updating, please let us know. + +### Web extension 2.0.0 + +The browser extension was bumped alongside the web release and picks up all of the above: React 19, Jotai, Floating UI, and the datatable keyboard improvements. diff --git a/apps/docs/release-notes/2025-08-09-v7.1.0.mdx b/apps/docs/release-notes/2025-08-09-v7.1.0.mdx new file mode 100644 index 000000000..74533e251 --- /dev/null +++ b/apps/docs/release-notes/2025-08-09-v7.1.0.mdx @@ -0,0 +1,52 @@ +--- +slug: v7.1.0 +title: 7.1.0 - Diff editor toggle, folder metadata fixes +date: '2025-08-09' +authors: [jetstream] +tags: [web, extension] +versions: + web: 7.1.0 + extension: 2.0.1 +summary: Compare metadata got an option to hide unchanged lines, folder metadata types are now retrieved correctly, and several datatable and popover bugs are fixed. +highlights: + - title: Toggle unchanged lines in the metadata diff editor + description: When comparing metadata between orgs you can now collapse unchanged lines, which makes larger files much easier to scan. + docLink: /deploy/deploy-metadata + platforms: [web, extension] + - title: Folder metadata types work correctly + description: Document, Email, Report, and Dashboard folders now appear in the metadata picker and retrieve the correct metadata from Salesforce. + docLink: /deploy/deploy-metadata + platforms: [web, extension] + - title: Datatable tab navigation fix + description: Fixed an edge case where tab navigation inside the datatable could misidentify custom cell renderers after minification. + platforms: [web, extension] + - title: Monaco editor upgrade + description: Upgraded the embedded code editor, which powers the Apex, SOQL, and metadata editors across Jetstream. + platforms: [web, extension] +--- + +{/* truncate */} + +## What's new + +### Toggle unchanged lines when comparing metadata + +The view-and-compare metadata modal now has a control to hide unchanged lines, so you can focus on the parts of a file that actually differ. Filename sorting in that view was also fixed so files list in a stable order. + +### Folder metadata types + +Document, Email, Report, and Dashboard folders are now included when you list metadata, and folder paths are sent to Salesforce in the format the API expects (with the trailing slash). This resolves cases where folder-based metadata was missing from the deploy or compare workflows. + +### Datatable tab navigation + +The datatable identifies certain columns (action and Id columns) by the name of their renderer function. After minification that name could change, causing tab navigation to treat them as normal cells. We now tag the renderers explicitly so tab navigation works the same in development and production builds. + +### Under the hood + +- Upgraded the Monaco editor and now serve its worker assets from node_modules rather than a checked-in copy on the server. +- Removed the react-aria and headless-ui dependencies in favor of the Floating UI stack introduced in 7.0.0. The Chrome Web Store flagged obfuscated code inside react-aria, so this unblocks future extension updates and cuts a dependency from the bundle. +- Fixed a scroll-lock glitch on the landing page and tightened portal root handling so popovers and modals render in the right container. + +### Web extension 2.0.1 + +The browser extension picked up the react-aria and headless-ui removal and the scroll-lock and portal fixes. diff --git a/apps/docs/release-notes/2025-08-09-v7.2.0.mdx b/apps/docs/release-notes/2025-08-09-v7.2.0.mdx new file mode 100644 index 000000000..1eff31259 --- /dev/null +++ b/apps/docs/release-notes/2025-08-09-v7.2.0.mdx @@ -0,0 +1,28 @@ +--- +slug: v7.2.0 +title: 7.2.0 - Copy load results to clipboard +date: '2025-08-09' +authors: [jetstream] +tags: [web, extension] +versions: + web: 7.2.0 + extension: 2.1.0 +summary: You can now copy load results directly to the clipboard as Excel, CSV, or JSON without downloading a file first. +highlights: + - title: Copy load results to clipboard + description: From the load results modal, copy all or selected rows to the clipboard in spreadsheet, CSV, or JSON format. + docLink: /load/load + platforms: [web, extension] +--- + +{/* truncate */} + +## What's new + +### Copy load results to clipboard + +The load results modal now has a Copy to Clipboard button. The main button copies in a spreadsheet-friendly format (compatible with Excel and Google Sheets), and the dropdown next to it lets you choose CSV or JSON instead. This is handy when you want to paste a few rows into a ticket, spreadsheet, or script without going through a file download. + +### Web extension 2.1.0 + +The browser extension picks up the same copy-to-clipboard option in the load results view. diff --git a/apps/docs/release-notes/2025-08-11-v7.3.0.mdx b/apps/docs/release-notes/2025-08-11-v7.3.0.mdx new file mode 100644 index 000000000..fc82a1c50 --- /dev/null +++ b/apps/docs/release-notes/2025-08-11-v7.3.0.mdx @@ -0,0 +1,43 @@ +--- +slug: v7.3.0 +title: 7.3.0 - Windows desktop app and in-app desktop/extension promotion +date: '2025-08-11' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 7.3.0 + desktop: 1.1.0 +summary: The desktop app now installs and auto-updates on Windows (code-signed), and the web app surfaces links to the desktop and browser extension builds from the home screen. +highlights: + - title: Windows desktop app + description: Desktop 1.1.0 ships a signed Windows installer with proper install, update, and Start Menu shortcut handling. + docLink: /getting-started/desktop-app + platforms: [desktop] + - title: Alternative app formats on the home screen + description: The home screen now shows a card pointing entitled users to the desktop app and browser extension. + platforms: [web] + - title: Desktop entitlement fix + description: Desktop was missing from entitlement checks, so paid users could be blocked from the desktop build. This is corrected. + platforms: [web, desktop] +--- + +{/* truncate */} + +## What's new + +### Windows desktop app + +Desktop 1.1.0 adds Windows support alongside macOS. The Windows build is signed via a cloud HSM and handles Squirrel install, update, and uninstall events correctly, including Start Menu shortcuts. If you tried the desktop app previously on Windows, grab the new installer. + +### Home screen links to desktop and extension + +When you have access to the desktop app or browser extension, the app home screen now shows a card linking to those builds so you can discover and install them without leaving Jetstream. + +### Entitlement fix + +The desktop entitlement was missing from the user profile entitlement list, which could block access for paid users. Desktop is now a first-class entitlement. + +### Other improvements + +- Added a documentation page for the desktop app. +- Desktop app can now receive notifications from the server. diff --git a/apps/docs/release-notes/2025-08-11-v7.3.1.mdx b/apps/docs/release-notes/2025-08-11-v7.3.1.mdx new file mode 100644 index 000000000..039066ee1 --- /dev/null +++ b/apps/docs/release-notes/2025-08-11-v7.3.1.mdx @@ -0,0 +1,27 @@ +--- +slug: v7.3.1 +title: 7.3.1 - Login session hardening +date: '2025-08-11' +authors: [jetstream] +tags: [web] +versions: + web: 7.3.1 +summary: Patch release that regenerates the session on login and cleans up server logs that could include sensitive values. +highlights: + - title: Session regenerated on login + description: The login flow now always returns a fresh session so cached state from the pre-login request cannot carry over. + - title: Cleaner server logs + description: Removed log statements that could include sensitive header or identity values. +--- + +{/* truncate */} + +## What's new + +### Login session regeneration + +Login now runs session regeneration as a promise-backed step, guaranteeing the session is fully rebuilt before the response is sent. A duplicate header-access bug introduced during the refactor was also fixed. + +### Log hygiene + +Removed several log lines that could echo sensitive identity or header data. diff --git a/apps/docs/release-notes/2025-08-14-v7.3.2.mdx b/apps/docs/release-notes/2025-08-14-v7.3.2.mdx new file mode 100644 index 000000000..8821b9933 --- /dev/null +++ b/apps/docs/release-notes/2025-08-14-v7.3.2.mdx @@ -0,0 +1,22 @@ +--- +slug: v7.3.2 +title: 7.3.2 - Fix view-results modal for bulk edits from query +date: '2025-08-14' +authors: [jetstream] +tags: [web] +versions: + web: 7.3.2 +summary: Fixes a bug where viewing bulk results after bulk editing records from query results did nothing. +highlights: + - title: View bulk results works again + description: Bulk editing from query results and then clicking "view results" now opens the results modal instead of silently doing nothing. + docLink: /query/query-results +--- + +{/* truncate */} + +## What's new + +### Fixed: view bulk results from query + +When bulk editing records from query results, opening the view/download results modal did nothing because the parent modal was hidden before the child modal could render. The modal component now keeps its DOM mounted while a child modal is active, and the Google Drive file picker no longer hides its parent. Reported in [#1328](https://github.com/jetstreamapp/jetstream/issues/1328). diff --git a/apps/docs/release-notes/2025-08-21-v7.3.3.mdx b/apps/docs/release-notes/2025-08-21-v7.3.3.mdx new file mode 100644 index 000000000..b9b461807 --- /dev/null +++ b/apps/docs/release-notes/2025-08-21-v7.3.3.mdx @@ -0,0 +1,34 @@ +--- +slug: v7.3.3 +title: 7.3.3 - Connected app guidance and annual pricing fix +date: '2025-08-21' +authors: [jetstream] +tags: [web] +versions: + web: 7.3.3 +summary: Adds an in-app banner about upcoming Salesforce Connected App changes, updates the related docs, and fixes annual pricing display for existing subscribers. +highlights: + - title: Upcoming Salesforce Connected App notice + description: The home screen now shows a banner linking to guidance for preparing for Salesforce's upcoming Connected App changes. + docLink: /getting-started/troubleshooting + - title: Annual subscription pricing fix + description: Existing annual subscribers now see the correct price on the billing page. + - title: Docs refresh + description: Overview, security, and troubleshooting docs have been updated with current Connected App install steps. +--- + +{/* truncate */} + +## What's new + +### Connected App banner + +A new banner on the app home screen points to updated guidance for Salesforce's upcoming Connected App changes. If you start hitting "not installed" errors when connecting a new org, the linked docs walk through installing the Jetstream Connected App into that org. + +### Billing page fix + +Annual subscribers were seeing an incorrect price on the "Existing Subscriptions" screen. The displayed price now matches the actual plan. + +### Docs + +The getting-started overview, security, and troubleshooting pages have been refreshed, and a screenshot was added to the connecting-an-org walkthrough. diff --git a/apps/docs/release-notes/2025-08-23-v7.3.4.mdx b/apps/docs/release-notes/2025-08-23-v7.3.4.mdx new file mode 100644 index 000000000..3df28e061 --- /dev/null +++ b/apps/docs/release-notes/2025-08-23-v7.3.4.mdx @@ -0,0 +1,22 @@ +--- +slug: v7.3.4 +title: 7.3.4 - One-click field change in query filters +date: '2025-08-23' +authors: [jetstream] +tags: [web] +versions: + web: 7.3.4 +summary: Removes the extra clear step when changing the field in a query filter condition. +highlights: + - title: Faster field swap in query filters + description: The "x" button on a selected filter field is gone, so you can pick a different field in one click instead of two. + docLink: /query/query-results +--- + +{/* truncate */} + +## What's new + +### Query filter field swap + +In the query builder filter rows, changing the selected field required clicking a clear button first and then picking the new field. The clear button has been removed so you can swap fields in a single click. diff --git a/apps/docs/release-notes/2025-08-23-v7.3.5.mdx b/apps/docs/release-notes/2025-08-23-v7.3.5.mdx new file mode 100644 index 000000000..cb48f1f47 --- /dev/null +++ b/apps/docs/release-notes/2025-08-23-v7.3.5.mdx @@ -0,0 +1,22 @@ +--- +slug: v7.3.5 +title: 7.3.5 - Diff editor collapses unchanged regions after swap +date: '2025-08-23' +authors: [jetstream] +tags: [web] +versions: + web: 7.3.5 +summary: Fixes the view/compare metadata diff editor so collapsed unchanged regions stay collapsed after swapping the two sides. +highlights: + - title: Diff editor swap fix + description: Swapping sides in the view/compare metadata diff now re-renders the editor so unchanged regions collapse as expected. + docLink: /deploy/deploy-metadata +--- + +{/* truncate */} + +## What's new + +### Diff editor + +When comparing two pieces of metadata, swapping the left and right sides previously left the collapsed-unchanged-regions behavior out of sync. The editor now re-renders on swap so collapsing works consistently. Reported in [#1315](https://github.com/jetstreamapp/jetstream/issues/1315). diff --git a/apps/docs/release-notes/2025-08-26-v7.4.0.mdx b/apps/docs/release-notes/2025-08-26-v7.4.0.mdx new file mode 100644 index 000000000..6a86c4bda --- /dev/null +++ b/apps/docs/release-notes/2025-08-26-v7.4.0.mdx @@ -0,0 +1,31 @@ +--- +slug: v7.4.0 +title: 7.4.0 - Per-org encryption and Windows desktop login +date: '2025-08-26' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 7.4.0 +summary: Org credentials are now encrypted with a unique key per record, and deep-link login is fixed in Windows desktop development builds. +highlights: + - title: Per-org encryption keys + description: Each stored Salesforce org now uses a unique encryption key instead of a single global key, reducing blast radius if a key is ever exposed. + platforms: [web, desktop] + - title: Windows desktop login fix + description: Deep links now open correctly in Windows desktop development builds, so OAuth login completes as expected. + platforms: [desktop] +--- + +{/* truncate */} + +## What's new + +### Per-org encryption for stored credentials + +We moved to a stronger encryption strategy for Salesforce org credentials. Each stored org now has its own encryption key instead of sharing a single global key across the database. This narrows the impact if a key is ever compromised and brings the access token decryption path into tighter typing on the backend. + +No action is required. Existing orgs continue to work. + +### Windows desktop login fix + +In Windows development builds, the deep link that completes OAuth login back to Jetstream desktop was not being handled correctly. Login now completes as expected when running the desktop app on Windows. diff --git a/apps/docs/release-notes/2025-08-30-v7.5.0.mdx b/apps/docs/release-notes/2025-08-30-v7.5.0.mdx new file mode 100644 index 000000000..165202717 --- /dev/null +++ b/apps/docs/release-notes/2025-08-30-v7.5.0.mdx @@ -0,0 +1,23 @@ +--- +slug: v7.5.0 +title: 7.5.0 - Accurate record count preview for queries +date: '2025-08-30' +authors: [jetstream] +tags: [web] +versions: + web: 7.5.0 +summary: The record count preview shown before running a query no longer fails when the query includes an ORDER BY clause. +highlights: + - title: Query record count preview works with ORDER BY + description: The count preview now strips the incompatible ORDER BY before running, so you get an accurate record total every time. + docLink: /query/query-results + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Query record count preview works with ORDER BY + +When you preview how many records a query will return, Jetstream runs a `COUNT()` query under the hood. Salesforce does not allow `ORDER BY` with `COUNT()`, so any query that included an order clause was failing 100% of the time at the preview step. The order clause is now removed before the count query runs, and the preview works regardless of your sort. diff --git a/apps/docs/release-notes/2025-08-30-v7.6.0.mdx b/apps/docs/release-notes/2025-08-30-v7.6.0.mdx new file mode 100644 index 000000000..bf0e3eada --- /dev/null +++ b/apps/docs/release-notes/2025-08-30-v7.6.0.mdx @@ -0,0 +1,58 @@ +--- +slug: v7.6.0 +title: 7.6.0 - Record modal anywhere, changeset options, Google Sheet refresh +date: '2025-08-30' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 7.6.0 + desktop: 1.2.0 + extension: 2.2.0 +summary: View, edit, and clone any record from anywhere in the app, refresh Google Sheet data on the load page, and control rollback behavior when adding metadata to a changeset. +highlights: + - title: View/Edit/Clone record modal, app-wide + description: The record modal is now managed at the app level, so viewing or editing a record works consistently from any screen and updates your recent records list automatically. + platforms: [web, desktop, extension] + - title: Refresh Google Sheet data on Load Records + description: Re-pull data from your selected Google Sheet even after navigating forward and backward through the load steps. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Changeset upload options + description: When adding metadata to an outbound changeset, you can now adjust deploy options and Jetstream defaults to "rollback on failure" for production orgs. + docLink: /deploy/deploy-metadata + platforms: [web, desktop, extension] + - title: Date picker closes on outside click + description: The date picker now dismisses correctly when you click outside of it in most contexts. + platforms: [web, desktop, extension] + - title: Recent records stays in sync + description: Opening a record from anywhere in the app now updates the recent records list, so it is easier to jump back to what you were just working on. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### View, edit, and clone records from anywhere + +The View / Edit / Clone record modal is now managed at the application level instead of being wired into each individual component. Any feature can open the modal by emitting an event, so the experience is consistent whether you launch it from query results, the formula evaluator, a lookup popover, or elsewhere. As a bonus, opening a record always updates your recent records list. + +### Refresh Google Sheet data on the Load Records page + +If you pick a Google Sheet as your source on the Load Records page, you can now refresh the data from the sheet even after navigating forward through the steps and coming back. Previously the refresh button was only reliable on the initial selection. + +### Changeset upload options and safer production defaults + +When adding metadata to an outbound changeset, you can now adjust the deploy options used for the upload. For production orgs, Jetstream defaults to rolling back the deployment on failure. This matters for the small number of users who build outbound changesets from a production org and want the safer default. + +### Date picker behavior + +The date picker now closes on outside click in the common cases. A couple of edge cases remain inside modals and on inline editable data tables where clicking away closes the picker popup but not the surrounding editor - we will keep chipping at those. + +### Recent records cache fix + +A follow-up patch corrected the storage key used for the recent records cache. Existing recent-record history is reset once when upgrading, after which the list tracks correctly going forward. + +## Desktop 1.2.0 and Web Extension 2.2.0 + +Desktop and the web extension were cut at the same time as 7.6.0 and pick up all of the above. diff --git a/apps/docs/release-notes/2025-09-03-v7.6.1.mdx b/apps/docs/release-notes/2025-09-03-v7.6.1.mdx new file mode 100644 index 000000000..bf61fc7cc --- /dev/null +++ b/apps/docs/release-notes/2025-09-03-v7.6.1.mdx @@ -0,0 +1,29 @@ +--- +slug: v7.6.1 +title: 7.6.1 - Geo IP routing fix +date: '2025-09-03' +authors: [jetstream] +tags: [web] +versions: + web: 7.6.1 +summary: Fixes a routing regression in the geo IP service after the Express 5 upgrade, plus docs and build script cleanup. +highlights: + - title: Geo IP service routing fix + description: Corrected the router configuration for Express 5 so geo IP lookups resolve correctly again. + platforms: [web, desktop, extension] + - title: Desktop download link fix in docs + description: The Windows desktop download link in the connected app docs now points at the correct location. +--- + +{/* truncate */} + +## What's new + +### Geo IP service routing fix + +The geo IP API service had a router definition that was incompatible with Express 5 after a recent upgrade. Requests now route correctly again. + +### Docs and build cleanups + +- The Windows desktop download link in the connected app docs has been corrected. +- A desktop build script no longer tries to uninstall dependencies that are not present, which was breaking the build. diff --git a/apps/docs/release-notes/2025-09-05-v7.6.2.mdx b/apps/docs/release-notes/2025-09-05-v7.6.2.mdx new file mode 100644 index 000000000..629b6c8d3 --- /dev/null +++ b/apps/docs/release-notes/2025-09-05-v7.6.2.mdx @@ -0,0 +1,43 @@ +--- +slug: v7.6.2 +title: 7.6.2 - Bigger attachment uploads and desktop download fix +date: '2025-09-05' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 7.6.2 + desktop: 1.3.0 + extension: 2.3.0 +summary: Raises the binary attachment upload limit, fixes attachment downloads in the desktop app, and ships a matching web extension release. +highlights: + - title: Larger binary attachment uploads + description: Paid users can upload up to 1 GB of attachments, and the desktop app and browser extension have no upload limit. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Attachment downloads fixed on desktop + description: Zip downloads of query result attachments now work in the desktop app via a custom protocol handler. + platforms: [desktop] + - title: Safer zip attachment fetches + description: The download service worker now validates fetch URLs before requesting zip attachments. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Larger binary attachment uploads + +Uploading records with binary attachments now supports much larger payloads. Paid web users can upload up to 1 GB in a single load, and the desktop app and browser extension have no upload limit at all. The load docs were updated to reflect the new thresholds. + +### Attachment downloads fixed on desktop + +Downloading query result attachments as a zip file was failing in the desktop app. The download pipeline was reworked to use a custom protocol handler so attachment zips download correctly in the desktop app. + +### Safer zip attachment fetches + +The download zip service worker now validates fetch URLs before issuing requests, and the server controllers tightened null checking on the attachment endpoint. + +### Web extension 2.3.0 + +The web extension was also published at 2.3.0 in this window, picking up the same download pipeline changes. diff --git a/apps/docs/release-notes/2025-09-07-v7.6.3.mdx b/apps/docs/release-notes/2025-09-07-v7.6.3.mdx new file mode 100644 index 000000000..50275a1ef --- /dev/null +++ b/apps/docs/release-notes/2025-09-07-v7.6.3.mdx @@ -0,0 +1,31 @@ +--- +slug: v7.6.3 +title: 7.6.3 - Binary file load fixes +date: '2025-09-07' +authors: [jetstream] +tags: [web] +versions: + web: 7.6.3 + desktop: 1.3.1 +summary: Fixes a file picker conflict on the binary attachment loader and adds better logging when attachment processing fails. +highlights: + - title: Binary attachment file picker fix + description: Clicking the "Zip with attachments" input no longer accidentally triggers the main CSV file input. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Better logging for attachment failures + description: The loader now logs more context when processing a binary attachment fails, making issues easier to diagnose. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Binary attachment file picker fix + +On the load page, clicking the zip attachment input was also triggering the main file input on top of it. The inputs are now properly isolated so only the intended picker opens. + +### Attachment processing logs + +When processing a binary attachment fails, the loader now writes more diagnostic information so failures are easier to investigate. diff --git a/apps/docs/release-notes/2025-09-11-v7.7.0.mdx b/apps/docs/release-notes/2025-09-11-v7.7.0.mdx new file mode 100644 index 000000000..18aa5003e --- /dev/null +++ b/apps/docs/release-notes/2025-09-11-v7.7.0.mdx @@ -0,0 +1,45 @@ +--- +slug: v7.7.0 +title: 7.7.0 - CSRF protection and UI polish +date: '2025-09-11' +authors: [jetstream] +tags: [web] +versions: + web: 7.7.0 +summary: Adds CSRF double-submit token protection to API requests, cleans up the field mapping dropdown, and fixes several small UI issues. +highlights: + - title: CSRF double-submit token protection + description: API requests now carry a CSRF token validated against a signed cookie, protecting against cross-site request forgery. + platforms: [web] + - title: Cleaner field mapping dropdown + description: The load records field mapping dropdown now shows the field type as tertiary text, matching the rest of the app. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Combobox sizing fix + description: The virtualized combobox no longer miscalculates its size in certain layouts. + platforms: [web, desktop, extension] + - title: XML sanitizer and extension domain detection + description: The XML sanitizer was fixed and the Chrome extension now detects Salesforce domains more reliably. + platforms: [web, extension] + - title: Error popover styling + description: The error popover nubbin color now matches the popover background. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### CSRF double-submit token protection + +All authenticated API requests now use a CSRF double-submit cookie pattern. The client reads the token from a cookie and sends it in a header that the server validates, blocking cross-site request forgery attempts. Existing sessions automatically get a new CSRF cookie issued if they don't have one. + +### Cleaner field mapping dropdown + +In the load records field mapping, the field type used to render as a badge that crowded polymorphic lookups. It now shows as tertiary text next to the field name, matching how field types are displayed everywhere else in the app. + +### Smaller UI fixes + +- The virtualized combobox control now sizes correctly in layouts where it was previously miscalculating. +- The error popover's nubbin is now the right color so it blends with the popover body. +- The XML sanitizer has been fixed and the Chrome extension does a better job of detecting when you're on a Salesforce domain. diff --git a/apps/docs/release-notes/2025-09-13-v7.7.1.mdx b/apps/docs/release-notes/2025-09-13-v7.7.1.mdx new file mode 100644 index 000000000..0bd8da8a0 --- /dev/null +++ b/apps/docs/release-notes/2025-09-13-v7.7.1.mdx @@ -0,0 +1,29 @@ +--- +slug: v7.7.1 +title: 7.7.1 - Salesforce login URL fix +date: '2025-09-13' +authors: [jetstream] +tags: [web] +versions: + web: 7.7.1 +summary: Fixes invalid URLs generated when logging in to Salesforce from Jetstream links, and tightens attachment download host handling. +highlights: + - title: Login with Salesforce URL fix + description: Links that log you into Salesforce now build URLs properly instead of concatenating strings, avoiding double-slash and other malformed links. + platforms: [web, desktop, extension] + - title: Attachment download host handling + description: The attachment download flow now uses proper URL parsing and validates the expected host. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Login with Salesforce URL fix + +Some users reported invalid URLs when clicking "Login with Salesforce" links in Jetstream. The links now build URLs using proper URL parsing instead of string concatenation, and double slashes in the path are no longer possible. + +### Attachment download host handling + +Related URL handling in the attachment download flow was also hardened so the generated URLs are always well-formed and target the expected host. diff --git a/apps/docs/release-notes/2025-09-16-v7.7.2.mdx b/apps/docs/release-notes/2025-09-16-v7.7.2.mdx new file mode 100644 index 000000000..6e929f3ef --- /dev/null +++ b/apps/docs/release-notes/2025-09-16-v7.7.2.mdx @@ -0,0 +1,22 @@ +--- +slug: v7.7.2 +title: 7.7.2 - Billing portal CSRF fix +date: '2025-09-16' +authors: [jetstream] +tags: [web] +versions: + web: 7.7.2 +summary: Fixes the billing portal, which was failing CSRF validation after the 7.7.0 security change. +highlights: + - title: Billing portal CSRF token fix + description: Billing pages submit via POST forms, so the CSRF token is now sent in the form body as well as the header. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Billing portal CSRF token fix + +After CSRF protection was introduced in 7.7.0, opening the billing portal failed because it uses form-based POST requests that don't carry the token header. The token is now also included in the request body so billing pages load again. diff --git a/apps/docs/release-notes/2025-09-20-v7.8.0.mdx b/apps/docs/release-notes/2025-09-20-v7.8.0.mdx new file mode 100644 index 000000000..06582280f --- /dev/null +++ b/apps/docs/release-notes/2025-09-20-v7.8.0.mdx @@ -0,0 +1,38 @@ +--- +slug: v7.8.0 +title: 7.8.0 - Streaming binary uploads and higher free-plan limit +date: '2025-09-20' +authors: [jetstream] +tags: [web] +versions: + web: 7.8.0 +summary: Rewrites the binary file upload pipeline to stream multipart data end-to-end and raises the free-plan attachment filesize limit. +highlights: + - title: Streaming multipart binary uploads + description: Binary attachment loads now stream from the browser through the server to Salesforce instead of using base64, so large files upload reliably. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Higher free-plan attachment limit + description: The attachment filesize cap on the free plan was raised, and the load docs were updated accordingly. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Platform events content-type fix + description: Removed an incorrect content-type override that was causing issues when publishing platform events. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Streaming multipart binary uploads + +The binary attachment upload pipeline moved off base64 and onto streaming multipart uploads. Files are streamed from the browser, through the API, and on to Salesforce without being fully buffered, which lets much larger files upload without timeouts or memory pressure. The server transforms the incoming binary stream so the embedded JSON part matches what the Salesforce API expects, and the desktop app uses a custom axios adapter that generates the multipart boundaries directly. + +### Higher free-plan attachment limit + +The attachment filesize limit for free-plan users was increased. The load attachments documentation was updated to reflect the new cap. + +### Platform events content-type fix + +An incorrect content-type header was being set on the client data helper when publishing platform events. That override was removed so platform event requests use the right content type. diff --git a/apps/docs/release-notes/2025-09-24-v7.9.0.mdx b/apps/docs/release-notes/2025-09-24-v7.9.0.mdx new file mode 100644 index 000000000..80dcf9d1e --- /dev/null +++ b/apps/docs/release-notes/2025-09-24-v7.9.0.mdx @@ -0,0 +1,31 @@ +--- +slug: v7.9.0 +title: 7.9.0 - View All Fields in Manage Permissions +date: '2025-09-24' +authors: [jetstream] +tags: [web] +versions: + web: 7.9.0 +summary: Adds support for the new View All Fields object permission in Manage Permissions and fixes a save bug affecting View All Records. +highlights: + - title: View All Fields object permission + description: Grant or revoke the new Salesforce View All Fields permission alongside the other object permissions in Manage Permissions. + docLink: /permissions/permissions + platforms: [web, desktop, extension] + - title: Fix View All Records save value + description: Saving permissions no longer writes the dirty-state value to Salesforce for View All Records and View All, so the intended value is persisted. + docLink: /permissions/permissions + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### View All Fields object permission + +Salesforce recently introduced a `viewAllFields` object permission that grants read access to every field on an object. Manage Permissions now lists it alongside Read, Create, Edit, Delete, View All, and Modify All. You can toggle it independently in the grid, the create-new-object flow, and the export, since it has no dependencies on the other permissions. + +### Fix View All Records save value + +Saving object permission changes was writing the in-memory dirty-state value to Salesforce for View All Records and View All instead of the actual selected value. The fix restores the correct save behavior so changes made in the grid persist as expected. diff --git a/apps/docs/release-notes/2025-09-24-v7.9.1.mdx b/apps/docs/release-notes/2025-09-24-v7.9.1.mdx new file mode 100644 index 000000000..18f3b7bc4 --- /dev/null +++ b/apps/docs/release-notes/2025-09-24-v7.9.1.mdx @@ -0,0 +1,30 @@ +--- +slug: v7.9.1 +title: 7.9.1 - Permission manager column fix and desktop download link +date: '2025-09-24' +authors: [jetstream] +tags: [web] +versions: + web: 7.9.1 +summary: Fixes the View All Records column width in Manage Permissions and corrects the x64 desktop download link. +highlights: + - title: View All Records column width + description: The View All Records column in the permission manager grid now renders with the correct width. + docLink: /permissions/permissions + platforms: [web, desktop, extension] + - title: Correct x64 desktop download link + description: The desktop download page now points at the right x64 installer asset. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### View All Records column width + +The new View All Fields column introduced in 7.9.0 was causing the View All Records column in the Manage Permissions grid to render at the wrong width. The column sizing was corrected. + +### Correct x64 desktop download link + +The download link for the x64 desktop installer was pointing at the wrong asset. The download resolver was updated so the correct Windows x64 build is served. diff --git a/apps/docs/release-notes/2025-09-27-v7.10.0.mdx b/apps/docs/release-notes/2025-09-27-v7.10.0.mdx new file mode 100644 index 000000000..942097124 --- /dev/null +++ b/apps/docs/release-notes/2025-09-27-v7.10.0.mdx @@ -0,0 +1,42 @@ +--- +slug: v7.10.0 +title: 7.10.0 - Centralized app state and desktop binary upload fix +date: '2025-09-27' +authors: [jetstream] +tags: [web] +versions: + web: 7.10.0 +summary: Centralizes the application state pipeline across web, desktop, and extension, fixes binary uploads on the desktop app, and documents the upcoming outbound IP address ranges. +highlights: + - title: Centralized application state + description: App state and server URL resolution now run through a single pipeline, so the desktop app no longer falls back to localhost when history sync is enabled. + platforms: [web, desktop, extension] + - title: Binary file uploads on desktop + description: Binary attachment uploads from the desktop app now stream as ArrayBuffers directly to Salesforce without body corruption. + docLink: /load/load + platforms: [desktop] + - title: Outbound IP address ranges + description: The getting started docs now include a dedicated page describing the upcoming API outbound IP address ranges. + docLink: /getting-started/overview + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Centralized application state + +The application state and server URL pipeline was refactored so the web app, desktop app, and browser extension all share one implementation instead of maintaining bespoke copies. This also fixes a bug where the desktop app would default to a localhost websocket server when history sync was enabled because it was falling back to the default cookie value. The application cookie has been largely replaced by the heartbeat API for desktop and extension. + +### Binary file uploads on desktop + +Binary attachment uploads on the desktop app were failing due to body corruption on the outbound request. The desktop load path now uses ArrayBuffers and streams the multipart body directly to Salesforce from the main process without additional processing. + +### Outbound IP address ranges + +A new `_ip-address-ranges.mdx` partial was added to the getting started docs and surfaced from the overview, install-connected-app, and troubleshooting pages, along with a notice on the app home page about the upcoming API outbound IP address range changes. + +### Desktop menu cleanup + +The desktop application menu was trimmed to remove unused items. diff --git a/apps/docs/release-notes/2025-10-08-v8.0.0.mdx b/apps/docs/release-notes/2025-10-08-v8.0.0.mdx new file mode 100644 index 000000000..a78540f72 --- /dev/null +++ b/apps/docs/release-notes/2025-10-08-v8.0.0.mdx @@ -0,0 +1,50 @@ +--- +slug: v8.0.0 +title: 8.0.0 - Team plan +date: '2025-10-08' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 8.0.0 + desktop: 3.0.3 +summary: Introduces the new Jetstream Team plan with a team dashboard, member management, login configuration, and auth activity, plus route-validation hardening. +highlights: + - title: Team plan and team dashboard + description: Invite teammates, manage members and roles, configure login rules, and review session and authentication activity from a single dashboard. + - title: Unified billing experience + description: Reworked billing page with clearer plan cards, monthly/annual toggle, and team naming during upgrade. + - title: Salesforce route hardening + description: Added domain validation on org add/login, an HSTS policy, and an extra ownership check so only the signed-in user can access their own orgs. + platforms: [web, desktop, extension] + - title: Desktop update fixes + description: Windows auto-update now uses a more standard electron-builder configuration, and an unused Squirrel startup path was removed. + platforms: [desktop] +--- + +{/* truncate */} + +## What's new + +### Team plan and team dashboard + +Jetstream now supports multi-seat teams. Team owners get a new dashboard to invite members, set roles, deactivate users, review each member's login and session history, and configure login rules such as allowed identity providers and required MFA. Subscriptions on the Team plan auto-create a team when the subscription is upgraded. + +See the [team management docs](/team-management/team-management) for the full walkthrough. + +### Unified billing experience + +The billing page was rebuilt around plan cards with a monthly/annual period toggle, a team-name prompt when upgrading to Team, and clearer handling of existing subscriptions. Access control on billing and profile endpoints is also more consistent, and errors now report through the bug tracker for faster triage. + +### Salesforce route hardening + +Adding or reconnecting an org now validates that the target host is a legitimate Salesforce-controlled domain before issuing a redirect, and all API responses enforce HSTS so browsers stick to HTTPS. An additional server-side check confirms that the org being accessed belongs to the signed-in user, on top of the existing database-level scoping. + +### Desktop update and menu cleanup + +The Windows auto-update flow was switched to a more default electron-builder configuration to address update failures seen on the prior release. The unused Squirrel startup integration and the orphan Profile component were also removed from the desktop build. + +### Quality-of-life + +- Fixed a user-linking access bug in the profile linked-accounts panel. +- Form accessibility improvements across billing and profile screens. +- Deprecated an unused image upload endpoint. diff --git a/apps/docs/release-notes/2025-10-08-v8.0.1.mdx b/apps/docs/release-notes/2025-10-08-v8.0.1.mdx new file mode 100644 index 000000000..30415508d --- /dev/null +++ b/apps/docs/release-notes/2025-10-08-v8.0.1.mdx @@ -0,0 +1,21 @@ +--- +slug: v8.0.1 +title: 8.0.1 - Fix crash for users without entitlements +date: '2025-10-08' +authors: [jetstream] +tags: [web] +versions: + web: 8.0.1 +summary: Hotfix for a user profile parsing crash that affected users whose accounts did not yet have an entitlements record after the 8.0.0 upgrade. +highlights: + - title: Fix profile parsing crash + description: User profiles without an entitlements or preferences object no longer crash the app on load. +--- + +{/* truncate */} + +## What's new + +### Fix profile parsing crash + +After 8.0.0 shipped, some users hit an error on load because their profile payload did not include an `entitlements` or `preferences` object. The user-profile schema now accepts a null value for both fields and falls back to safe defaults, so the app initializes cleanly for every account. diff --git a/apps/docs/release-notes/2025-10-13-v8.1.0.mdx b/apps/docs/release-notes/2025-10-13-v8.1.0.mdx new file mode 100644 index 000000000..3402b88da --- /dev/null +++ b/apps/docs/release-notes/2025-10-13-v8.1.0.mdx @@ -0,0 +1,33 @@ +--- +slug: v8.1.0 +title: 8.1.0 - Login configuration and email verification fixes +date: '2025-10-13' +authors: [jetstream] +tags: [web] +versions: + web: 8.1.0 +summary: Fixes login configuration lookup for individual users and repairs the email-link verification flow used during 2FA. +highlights: + - title: Correct login configuration lookup + description: Individual accounts no longer inherit team login rules because of an argument-shape bug in the configuration lookup. + - title: Verify email via link works again + description: Restores the 2FA email-verification link flow, which was rejecting valid codes due to a mis-wired validator. +--- + +{/* truncate */} + +## What's new + +### Correct login configuration lookup + +The server was always falling back to the team login configuration, even for users without a team, because of a bug in how a polymorphic lookup argument was built. Individual accounts now resolve their own configuration, and team members continue to inherit their team's rules. + +### Verify email via link + +The email-verification link used during 2FA was wired up to the wrong Zod validator, which caused valid codes to be rejected. The correct validator is now used end-to-end. + +### Under the hood + +- Upgraded to Zod 4 across the API, with an OpenAPI spec generated from the route validators. +- Upgraded `react-hook-form` and related validators. +- Fixed geo-IP lookup and improved error logging for client-discovery requests. diff --git a/apps/docs/release-notes/2025-10-14-v8.2.0.mdx b/apps/docs/release-notes/2025-10-14-v8.2.0.mdx new file mode 100644 index 000000000..0c8a83f91 --- /dev/null +++ b/apps/docs/release-notes/2025-10-14-v8.2.0.mdx @@ -0,0 +1,52 @@ +--- +slug: v8.2.0 +title: 8.2.0 - Bug bash fixes across load, deploy, and automation control +date: '2025-10-14' +authors: [jetstream] +tags: [web, extension] +versions: + web: 8.2.0 + extension: 2.4.0 +summary: Collection of fixes from a bug bash, including deploy-metadata token refresh, a safer default for rollbackOnError in production, and a fix for Automation Control select-all on filtered rows. +highlights: + - title: Safer default for production deploys + description: The rollbackOnError option in custom-metadata loads now defaults to true in production orgs, with clearer help text when left off. + docLink: /load/load + - title: Deploy Metadata token refresh + description: Deploying metadata between orgs now checks each org's session before starting, avoiding a cryptic token-refresh failure mid-deploy. + docLink: /deploy/deploy-metadata + - title: Automation Control select-all respects filters + description: Enabling or disabling automations from the header checkbox now only affects the rows currently visible in the table. + - title: Create new record from query results + description: Creating a new record from the query results page no longer fails because of an unnecessary recordId requirement. + docLink: /query/query-results + - title: Change debug log levels + description: Fixed a case where Salesforce's 204 response caused the debug-log update API to fail while trying to parse an empty body. +--- + +{/* truncate */} + +## What's new + +### Safer default for production deploys + +When loading custom metadata into a production org, the `rollbackOnError` checkbox now defaults to on. If you turn it off, the help text is styled as a warning so it's clear Salesforce requires rollback-on-error for production loads. + +### Deploy Metadata token refresh + +When deploying metadata from one org to another, Jetstream now checks each org's connection health before kicking off the deployment. Previously a stale session in either org surfaced as an opaque token-refresh failure partway through. + +### Automation Control select-all respects filters + +The select-all checkbox in Automation Control now only toggles rows visible after filtering, instead of silently enabling or disabling every row in the underlying list. Select-all also skips parent rows when none of their children are visible. + +### Other fixes + +- Creating a new record from the query results page works again; the listener no longer requires a recordId for new-record mode. +- Changing the debug log level works again after Salesforce returned a 204 with no body. +- Removed an unnecessary bug-tracker notification on failed global picklist creation. +- Improved error logging for client-discovery requests and fixed the geo-IP service for Zod 4. + +### Web extension 2.4.0 + +Web extension 2.4.0 ships alongside this release with the same underlying fixes. diff --git a/apps/docs/release-notes/2025-10-21-v8.3.0.mdx b/apps/docs/release-notes/2025-10-21-v8.3.0.mdx new file mode 100644 index 000000000..627e1a4ff --- /dev/null +++ b/apps/docs/release-notes/2025-10-21-v8.3.0.mdx @@ -0,0 +1,45 @@ +--- +slug: v8.3.0 +title: 8.3.0 - Better related-object loading and assorted bug fixes +date: '2025-10-21' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 8.3.0 + desktop: 3.1.0 +summary: Load Records now shows every related object on polymorphic lookups and fetches related-field metadata on demand. Also fixes Firefox drag in the query builder and a create-organization regression. +highlights: + - title: All related objects on polymorphic lookups + description: Field mapping on Load Records now shows every related object for polymorphic relationships instead of capping the list at five. + docLink: /load/load + - title: On-demand related-field metadata + description: Related-object fields are now fetched only when the object is selected in mapping, with a manual retry when a fetch fails. + docLink: /load/load + - title: Firefox query builder drag + description: Condition rows in the query builder can be dragged on Firefox again after swapping the drag handle from a button to a span. + docLink: /query/query-results + - title: Create organization from selected org + description: Creating a new organization no longer silently reuses the currently selected organization state, which could block the create flow. +--- + +{/* truncate */} + +## What's new + +### Improved related-object loading + +When a Salesforce lookup is polymorphic, the Load Records field-mapping UI now lists every related object it could point to, not just the first five. Metadata for those related objects is fetched on demand when you pick the target object, which makes the initial load faster and avoids pre-fetching a lot of data you never use. If a fetch fails, you can retry without restarting the load. + +When auto-mapping fields, related-object metadata is still pre-fetched up front based on the CSV headers. + +### Firefox query builder drag + +Firefox does not allow dragging native buttons, so the query builder's condition drag handle now uses a span. Reordering conditions works again across all supported browsers. + +### Create organization fix + +Creating a new organization while another organization was selected in the switcher could fail because the create modal reused the selected-organization state for its form. The modal now keeps its own state, so create and edit flows stay independent. + +### Desktop 3.1.0 + +The desktop app is bumped to 3.1.0 with the same underlying fixes. diff --git a/apps/docs/release-notes/2025-10-28-v8.4.0.mdx b/apps/docs/release-notes/2025-10-28-v8.4.0.mdx new file mode 100644 index 000000000..b624904d7 --- /dev/null +++ b/apps/docs/release-notes/2025-10-28-v8.4.0.mdx @@ -0,0 +1,49 @@ +--- +slug: v8.4.0 +title: 8.4.0 - View Record checkbox fix, smoother desktop auto-update +date: '2025-10-28' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 8.4.0 + desktop: 3.3.0 +summary: Fixes checkboxes rendering blank in View Record, improves the desktop auto-update UX, and lets you pick filename formats for zip attachment exports. +highlights: + - title: Checkbox fields render correctly in View Record + description: Read-only checkbox fields no longer appear blank when viewing a record. + - title: Quieter desktop auto-updates + description: Update status lives in a navbar popover instead of an intrusive dialog that could pop up multiple times. + platforms: [desktop] + - title: Duplicate filenames in zip exports + description: When downloading binary attachments, you can now choose the filename format to use instead of hitting duplicate-name collisions. + docLink: /query/query-results + - title: No stray navbar icons without an org + description: Record and user search popovers are hidden until a valid org is selected, avoiding confusing empty states. + - title: Desktop login works for team accounts + description: Entitlement checks now respect team entitlements and reject logins for users no longer active in a team. + platforms: [desktop] +--- + +{/* truncate */} + +## What's new + +### View Record checkbox fix + +Checkbox fields in the read-only View Record view were rendering as blank. They now show the correct true/false value. Resolves #1414. + +### Desktop auto-update overhaul + +The desktop app's old update flow forced you through a dialog, sometimes multiple times. Update state now lives in a popover in the navbar so you can see progress, trigger installs, and dismiss at your own pace. Shipped in desktop 3.3.0. + +### Zip export filename options + +When exporting binary attachments, you can pick the filename format, which avoids collisions when records share an attachment name. Resolves #1379. + +### Navbar cleanup without an org + +Record search and user search icons are hidden until an org is selected, so you no longer see features that cannot work. Resolves #1395. + +### Desktop team login + +The desktop entitlement check now prefers team entitlements when they exist and refuses login if the user is not active in the team. diff --git a/apps/docs/release-notes/2025-11-01-v8.5.0.mdx b/apps/docs/release-notes/2025-11-01-v8.5.0.mdx new file mode 100644 index 000000000..903c6e5ea --- /dev/null +++ b/apps/docs/release-notes/2025-11-01-v8.5.0.mdx @@ -0,0 +1,45 @@ +--- +slug: v8.5.0 +title: 8.5.0 - Rebuilt binary attachment downloads +date: '2025-11-01' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.5.0 +summary: Binary attachment downloads are rebuilt with server-side streaming, desktop-native progress, and automatic field re-querying so you do not have to think about which fields to include. +highlights: + - title: Server-side streaming for attachment downloads + description: Zip creation moved off the browser service worker onto the server with back-pressure and timeout handling, eliminating the refresh-to-fix-it problem. + docLink: /query/query-results + - title: Desktop background job with live progress + description: On desktop, attachment downloads run as a background job on the main process and save directly to disk with progress notifications. + platforms: [desktop] + - title: StaticResource download support + description: StaticResource is now a supported export type alongside Attachment, ContentVersion, and Document. + - title: No more required-field guesswork + description: Jetstream re-queries records for the fields it needs, so you can pick any query and still export binary files cleanly. +--- + +{/* truncate */} + +## What's new + +### Binary attachment downloads, rebuilt + +The old attachment download flow relied on a browser service worker that often required a page refresh to register correctly. The whole pipeline is rewritten: + +- **Web**: zips are streamed from the server with back-pressure and timeout handling. +- **Desktop**: downloads run as a background job on the main process and write straight to disk, with a progress notification. +- **Extension**: zips are built and saved in one step, which is the only option available in that environment. + +### StaticResource export + +StaticResource joins Attachment, ContentVersion, and Document as a supported object for binary export. + +### Fewer footguns + +Previously you had to make sure your query included specific fields. Jetstream now re-queries the records to fetch whatever fields the download needs, so any query works. Resolves #1416. + +### Under the hood + +Job IDs are now required for download jobs so multiple downloads can be in flight at the same time. diff --git a/apps/docs/release-notes/2025-11-07-v8.6.0.mdx b/apps/docs/release-notes/2025-11-07-v8.6.0.mdx new file mode 100644 index 000000000..f7aaac10a --- /dev/null +++ b/apps/docs/release-notes/2025-11-07-v8.6.0.mdx @@ -0,0 +1,32 @@ +--- +slug: v8.6.0 +title: 8.6.0 - Opt-in analytics with cookie consent +date: '2025-11-07' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.6.0 + desktop: 3.4.0 + extension: 2.5.0 +summary: Analytics are now opt-in via a cookie consent banner for GDPR compliance, plus dependency upgrades and a desktop and extension version bump. +highlights: + - title: Cookie consent banner + description: Analytics cookies are now opt-in with an in-app consent banner, aligned with GDPR expectations. + - title: Dependency upgrades + description: Broad dependency refresh across the monorepo and project cleanup. + - title: Desktop and extension rebuilds + description: Desktop 3.4.0 and Web Extension 2.5.0 were published alongside this web release to pick up the dependency upgrades. + platforms: [desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Opt-in analytics + +Analytics cookies now require explicit consent via a banner. Declining the banner keeps analytics off, and accepting enables them. Log storage moved to an updated BetterStack location as part of the subprocessor list refresh. + +### Dependency upgrades + +A monorepo-wide dependency bump landed with this release. No functional changes are expected, but the desktop and extension builds were re-published (desktop 3.4.0, web extension 2.5.0) so they ride the same versions. diff --git a/apps/docs/release-notes/2025-11-13-v8.7.0.mdx b/apps/docs/release-notes/2025-11-13-v8.7.0.mdx new file mode 100644 index 000000000..2999bd52c --- /dev/null +++ b/apps/docs/release-notes/2025-11-13-v8.7.0.mdx @@ -0,0 +1,42 @@ +--- +slug: v8.7.0 +title: 8.7.0 - Table filter fixes and connected-app onboarding help +date: '2025-11-13' +authors: [jetstream] +tags: [web] +versions: + web: 8.7.0 +summary: Table filters now stay in sync when data reloads, password reset accepts plus-sign emails, and orgs missing the Jetstream connected app get clearer install guidance. +highlights: + - title: Table filters follow data updates + description: When table data reloads, existing filters are retained and their available values update so the filter still matches the new records. + docLink: /query/query-results + - title: Numeric column filters fixed + description: Filters on numeric fields now behave correctly and no longer drop values on refresh. + - title: Password reset with plus-sign emails + description: Emails containing a "+" no longer get mangled into a space during password reset. + - title: Connected app install guidance + description: Help links point users to the page where they would install the Jetstream connected app if it is missing, plus a sandbox sync callout. + - title: Cookie banner padding fix + description: The consent banner no longer throws off in-app alignment while still looking right on the landing page. +--- + +{/* truncate */} + +## What's new + +### Table filters retain state after refresh + +When a table refreshes (for example after a bulk action or a re-query), the filters you set are retained and their available values are recalculated so they still apply to the new data. Numeric-field filters also got a specific fix. Resolves #1421 and related. + +### Password reset accepts "+" emails + +Emails like `you+tag@example.com` were getting decoded with a space instead of a plus, which failed validation. The reset link now preserves the address correctly. + +### Help finding the connected app + +Some Salesforce orgs (mainly sandboxes) do not surface the Jetstream connected app in OAuth Usage. The app now links to docs that walk through installing it, and the "add org" popover has a matching docs entry point. There is also a callout for syncing permissions to sandboxes. + +### Cookie banner alignment + +The consent banner previously used a fixed height that worked on the landing page but misaligned in-app content. That is fixed on both sides. Resolves #1425. diff --git a/apps/docs/release-notes/2025-11-15-v8.8.0.mdx b/apps/docs/release-notes/2025-11-15-v8.8.0.mdx new file mode 100644 index 000000000..cebd7c48e --- /dev/null +++ b/apps/docs/release-notes/2025-11-15-v8.8.0.mdx @@ -0,0 +1,49 @@ +--- +slug: v8.8.0 +title: 8.8.0 - Org expiration, Organization Groups, bulk org delete +date: '2025-11-15' +authors: [jetstream] +tags: [web] +versions: + web: 8.8.0 +summary: Unused Salesforce orgs now expire with advance email notice, the Organization page handles refresh/reconnect cleanly, and you can delete orgs in bulk. +highlights: + - title: Org expiration with email notice + description: Salesforce orgs unused for 90 days are flagged for expiration, with email notifications summarizing expiring and expired orgs. + - title: Easier reconnect for expired orgs + description: The Organization page surfaces expiring and expired orgs, and reconnect uses login_hint and pre-filled connection details. + - title: Bulk delete Salesforce orgs + description: Select and delete multiple connected orgs at once from the Organizations page. + - title: Rename to "Organization Group" + description: What used to be called "Jetstream Organization" is now "Organization Group" everywhere in the app, to avoid confusion with a Salesforce organization. + - title: Download format is remembered + description: Your last-used download format (CSV, Excel, JSON, etc.) is remembered per-user as the new default. +--- + +{/* truncate */} + +## What's new + +### Org expiration process + +Salesforce orgs that have not been used in 90 days now enter an expiration workflow. A daily cron job sends users a consolidated email covering their expiring and expired orgs so nothing disappears without warning. + +### Better Organization page + +The Organization page now highlights expiring and expired orgs. Reconnecting uses the `login_hint` OAuth parameter and pre-fills the connection details you already had, so you rarely have to re-enter anything. + +### Bulk delete orgs + +A new delete-orgs modal on the Organizations page lets you remove multiple Salesforce org connections at once. Helpful for cleaning up sandbox clutter. + +### "Jetstream Organization" is now "Organization Group" + +The old term collided with "Salesforce organization." Everything (UI, docs, API variables) has been renamed to "Organization Group." Existing data is unaffected; it is purely a naming change. + +### Remembered download format + +Your last-used export format is now saved as your default, instead of falling back to the same built-in choice every time. Resolves #1429-ish workflow request. + +### Under the hood + +- Added retry and extra logging to the `.well-known` OAuth discovery call, which occasionally failed at startup on staging. diff --git a/apps/docs/release-notes/2025-11-23-v8.9.0.mdx b/apps/docs/release-notes/2025-11-23-v8.9.0.mdx new file mode 100644 index 000000000..b7bc7313b --- /dev/null +++ b/apps/docs/release-notes/2025-11-23-v8.9.0.mdx @@ -0,0 +1,62 @@ +--- +slug: v8.9.0 +title: 8.9.0 - Auth hardening and edit modal improvements +date: '2025-11-23' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.9.0 + desktop: 3.5.0 + extension: 2.6.0 +summary: Major authentication hardening including password history and account lockout, plus View All records access in the edit/create/clone record modal. +highlights: + - title: Auth hardening + description: Password history prevents reuse of the last 10 passwords, account lockout protects against repeated reset attempts, and login flows no longer leak whether an email is registered. + platforms: [web, desktop, extension] + - title: Improved password reset flow + description: Changed passwords are tracked in history, the strength indicator shows on reset, reuse errors stay visible, and the login form auto-fills the reset email. + platforms: [web, desktop, extension] + - title: View All Records on edit modal + description: The edit, create, and clone record modal now loads every field instead of only layout-assigned fields. + docLink: /query/query-results + platforms: [web, desktop, extension] + - title: Team role safety + description: Billing-only users can no longer promote others to admin or modify administrator accounts. + docLink: /team-management/team-management + platforms: [web] + - title: Smarter org expiration emails + description: The 90-day inactive-org reminder now skips users who do not actively use Jetstream, and test-mode summaries are accurate. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Auth hardening + +A sizable security pass landed across the login and signup flows: + +- Password history tracks the 10 most recent passwords and blocks reuse. +- Account lockout protects against repeated password-reset attempts. +- The signup flow verifies the email address before confirming whether it is already in use, preventing user enumeration. +- The login page shows a hint for the most recently used login method for your email. +- If you log in with a password, Jetstream offers to remember the email so the form auto-fills next time. + +### Password reset improvements + +The reset flow now writes the new password into password history, shows the strength meter during reset, keeps reuse errors visible instead of bouncing back to login, and pre-fills the email field after a successful reset. + +### Edit/Create/Clone record modal: View All + +The record modal now exposes every field on the object, not just the ones on the user's page layout. This matches the View All behavior in the query results grid. + +### Team role restrictions + +Billing-only members cannot change another user's role to admin, and cannot modify users who are already administrators. + +### Quality-of-life + +- Org popover width was corrected so long org names no longer overflow. +- Expired-org reminder emails skip inactive users and render correctly in test mode. +- Email-related default environment variables were removed so deployments fail loudly instead of silently sending with the wrong settings. diff --git a/apps/docs/release-notes/2025-11-25-v8.9.1.mdx b/apps/docs/release-notes/2025-11-25-v8.9.1.mdx new file mode 100644 index 000000000..e92a563c1 --- /dev/null +++ b/apps/docs/release-notes/2025-11-25-v8.9.1.mdx @@ -0,0 +1,25 @@ +--- +slug: v8.9.1 +title: 8.9.1 - Fix metadata download regression +date: '2025-11-25' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.9.1 + desktop: 3.6.0 + extension: 2.7.0 +summary: Patch release that restores metadata downloads after a regression in base64 handling. +highlights: + - title: Metadata downloads work again + description: A recent refactor broke base64-to-ArrayBuffer conversion, which caused metadata downloads to fail. The conversion path is fixed. + docLink: /deploy/deploy-metadata + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Metadata download fix + +A code change introduced in 8.9.0 destructured a string primitive inside `base64ToArrayBuffer`, which caused metadata downloads to throw. The function was corrected and downloads work again across retrieve, package, and deploy flows. diff --git a/apps/docs/release-notes/2025-12-01-v8.10.0.mdx b/apps/docs/release-notes/2025-12-01-v8.10.0.mdx new file mode 100644 index 000000000..19872ebba --- /dev/null +++ b/apps/docs/release-notes/2025-12-01-v8.10.0.mdx @@ -0,0 +1,39 @@ +--- +slug: v8.10.0 +title: 8.10.0 - Session error detection and SOQL parser bump +date: '2025-12-01' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.10.0 + desktop: 3.6.1 + extension: 2.7.1 +summary: Better detection of invalid org sessions so connection errors are surfaced promptly, plus a SOQL parser upgrade and regression coverage for base64 conversion. +highlights: + - title: Invalid session detection + description: Additional Salesforce error responses now mark the org as having a connection error, so you are prompted to reconnect instead of hitting opaque failures. + platforms: [web, desktop, extension] + - title: SOQL parser upgrade + description: Bumped soql-parser-js to 6.3.0 for improved parsing coverage. + docLink: /query/query + platforms: [web, desktop, extension] + - title: Base64 conversion hardening + description: Removed duplicated base64-to-ArrayBuffer code and added regression tests after the 8.9.x download issue. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Invalid session detection + +Jetstream now recognizes additional Salesforce error messages that indicate an invalid or expired session, and marks the affected org with a connection error. This means you get the standard "reconnect org" prompt instead of mysterious request failures. + +### SOQL parser 6.3.0 + +`soql-parser-js` was upgraded to 6.3.0, which brings broader support for recent SOQL grammar additions. + +### Base64 regression coverage + +The shared base64-to-ArrayBuffer helper was consolidated and now has dedicated tests so the 8.9.x download regression cannot recur silently. diff --git a/apps/docs/release-notes/2025-12-05-v8.11.0.mdx b/apps/docs/release-notes/2025-12-05-v8.11.0.mdx new file mode 100644 index 000000000..d8bd87489 --- /dev/null +++ b/apps/docs/release-notes/2025-12-05-v8.11.0.mdx @@ -0,0 +1,53 @@ +--- +slug: v8.11.0 +title: 8.11.0 - Bug bash fixes and API version bump +date: '2025-12-05' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.11.0 +summary: A batch of bug fixes from an internal bug bash, XML comment support in package manifests, clearer deployment terminology, and an API version bump. +highlights: + - title: Package.xml comment support + description: Comments inside an XML package manifest no longer break parsing during deploy and retrieve operations. + docLink: /deploy/deploy-metadata + platforms: [web, desktop, extension] + - title: Editing orgs on the deployment page + description: Fixed a bug where editing an org from the deployment page would break navigation to the next step. + docLink: /deploy/deploy-metadata + platforms: [web, desktop, extension] + - title: Unmanaged terminology + description: References to "non-managed" tests and fields were updated to "unmanaged" across the UI and docs for consistency with Salesforce. + platforms: [web, desktop, extension] + - title: Production test level warning + description: The deployment options screen now shows an inline error when an invalid test level is picked for a production org. + docLink: /deploy/deploy-metadata + platforms: [web, desktop, extension] + - title: Salesforce API 65.0 + description: Bumped the default Salesforce API version from 64.0 to 65.0. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Package.xml comments + +XML comments inside a `package.xml` manifest are now tolerated by the parser, so manually-authored manifests with inline notes work in both deploy and retrieve flows. + +### Deployment page fixes + +- Editing an org from inside the deployment wizard no longer breaks the next step. +- The deployment options screen surfaces an inline error when a production org is given an invalid test level. +- Terminology was unified: "non-managed" tests and fields are now "unmanaged" everywhere. + +### Stability + +- Fixed an application crash that could occur when a resolved item was missing. +- Fixed a missing dependency import. +- Refactored uncaught-exception logging on the server so exceptions thrown from inside the error handler itself are reported cleanly. + +### Salesforce API version + +The Salesforce API version used for new org connections was bumped to 65.0. diff --git a/apps/docs/release-notes/2025-12-12-v8.12.0.mdx b/apps/docs/release-notes/2025-12-12-v8.12.0.mdx new file mode 100644 index 000000000..1da7e952b --- /dev/null +++ b/apps/docs/release-notes/2025-12-12-v8.12.0.mdx @@ -0,0 +1,40 @@ +--- +slug: v8.12.0 +title: 8.12.0 - In-app feedback +date: '2025-12-12' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.12.0 + desktop: 3.7.0 + extension: 2.8.0 +summary: Send feedback and bug reports directly from inside Jetstream, with support for file attachments on web, desktop, and the browser extension. +highlights: + - title: In-app feedback + description: A new feedback widget lets you send questions, bug reports, and suggestions directly from the app instead of filing a GitHub issue. + docLink: /getting-started/feedback + platforms: [web, desktop, extension] + - title: Feedback from every form factor + description: The feedback flow works on web, desktop, and the browser extension, with attachment support on every platform. + platforms: [web, desktop, extension] + - title: Web extension binary upload + description: The browser extension now uses the same binary upload path as desktop, so file attachments upload reliably. + platforms: [extension] +--- + +{/* truncate */} + +## What's new + +### In-app feedback + +You can now send feedback from inside Jetstream. Open the feedback widget, add a message, optionally attach files, and it reaches the Jetstream team without needing a GitHub account. The widget is available on web, desktop, and the browser extension. + +### Extension binary uploads + +As part of the feedback work, the browser extension was updated to use the same binary file-upload mechanism as the desktop app, which makes attachments reliable in extension contexts. + +### Quality-of-life + +- The IP-address banner was removed. +- Documentation grammar fixes across various pages. diff --git a/apps/docs/release-notes/2025-12-12-v8.12.1.mdx b/apps/docs/release-notes/2025-12-12-v8.12.1.mdx new file mode 100644 index 000000000..9019afc09 --- /dev/null +++ b/apps/docs/release-notes/2025-12-12-v8.12.1.mdx @@ -0,0 +1,26 @@ +--- +slug: v8.12.1 +title: 8.12.1 - Feedback attachment fix +date: '2025-12-12' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.12.1 +summary: Patch release that fixes multiple file attachments in the new in-app feedback widget. +highlights: + - title: Multiple feedback attachments + description: The feedback form now supports up to 5 attachments, warns when you exceed the limit, and correctly delivers every attachment in the resulting email. + docLink: /getting-started/feedback + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Feedback attachments + +The in-app feedback widget shipped in 8.12.0 had issues when sending more than one attachment. This release: + +- Caps attachments at 5 per message, with a warning toast if you try to add more. +- Buffers attachments server-side so the email provider receives every file, instead of only the first stream. diff --git a/apps/docs/release-notes/2025-12-13-v8.13.0.mdx b/apps/docs/release-notes/2025-12-13-v8.13.0.mdx new file mode 100644 index 000000000..60197baed --- /dev/null +++ b/apps/docs/release-notes/2025-12-13-v8.13.0.mdx @@ -0,0 +1,32 @@ +--- +slug: v8.13.0 +title: 8.13.0 - Lookup picker for reference fields +date: '2025-12-13' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.13.0 + desktop: 3.8.0 + extension: 2.9.0 +summary: Editing reference fields now offers a lookup search instead of pasting raw IDs, with polymorphic object selection built in. +highlights: + - title: Record lookup for reference fields + description: Search for related records when editing lookup fields, including choosing the target object for polymorphic references. + docLink: /query/query-results + platforms: [web, desktop, extension] + - title: Accessibility fixes + description: Resolved several accessibility issues across the app. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Record lookup for reference fields + +When editing a reference field, you can now search for the related record instead of typing or pasting a Salesforce ID. Polymorphic relationships let you pick which object the lookup should target before searching. A toggle is available if you still want to enter the ID manually. + +### Accessibility fixes + +Assorted accessibility issues were addressed across the app to improve keyboard and screen reader support. diff --git a/apps/docs/release-notes/2025-12-13-v8.13.1.mdx b/apps/docs/release-notes/2025-12-13-v8.13.1.mdx new file mode 100644 index 000000000..d4897374b --- /dev/null +++ b/apps/docs/release-notes/2025-12-13-v8.13.1.mdx @@ -0,0 +1,24 @@ +--- +slug: v8.13.1 +title: 8.13.1 - Lookup filter styling fix +date: '2025-12-13' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.13.1 + desktop: 3.8.1 + extension: 2.9.1 +summary: Follow-up fix to styling on the new record lookup filter. +highlights: + - title: Lookup filter styles + description: Corrected visual styling on the record lookup filter introduced in 8.13.0. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Lookup filter styles + +Cleaned up the styling on the record lookup filter introduced in the previous release so it renders correctly alongside other filter inputs. diff --git a/apps/docs/release-notes/2025-12-14-v8.14.0.mdx b/apps/docs/release-notes/2025-12-14-v8.14.0.mdx new file mode 100644 index 000000000..42d30c474 --- /dev/null +++ b/apps/docs/release-notes/2025-12-14-v8.14.0.mdx @@ -0,0 +1,30 @@ +--- +slug: v8.14.0 +title: 8.14.0 - Record lookup in query filters +date: '2025-12-14' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 8.14.0 +summary: Query filter values now support a record lookup so you can search for the record you want to filter on instead of hunting for an ID. +highlights: + - title: Record lookup in query filters + description: When building a query filter on a reference field, search for the related record and have the ID inserted into your SOQL. + docLink: /query/query-results + platforms: [web, desktop, extension] + - title: Lookup clear button fix + description: The clear button now works correctly when the lookup editor is in manual text entry mode. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Record lookup in query filters + +The query builder's filter value now accepts a record lookup for reference fields. Search for the record you want, and Jetstream writes the correct ID into the generated SOQL. This makes ad-hoc filters faster when you know the record by name but not by ID. + +### Lookup clear button fix + +Fixed an issue where the clear button did not reset the value while the lookup editor was in manual text entry mode. diff --git a/apps/docs/release-notes/2025-12-16-v8.15.0.mdx b/apps/docs/release-notes/2025-12-16-v8.15.0.mdx new file mode 100644 index 000000000..86a35f0d0 --- /dev/null +++ b/apps/docs/release-notes/2025-12-16-v8.15.0.mdx @@ -0,0 +1,31 @@ +--- +slug: v8.15.0 +title: 8.15.0 - Configurable SOQL format options +date: '2025-12-16' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.15.0 + desktop: 3.8.2 + extension: 2.10.0 +summary: Choose how Jetstream formats generated SOQL to match your preferences, plus a desktop asset fix for the code editor. +highlights: + - title: SOQL format options + description: Configure how generated SOQL is formatted, including casing and layout preferences. + platforms: [web, desktop, extension] + - title: Desktop editor assets fixed + description: Resolved missing Monaco editor assets in the desktop build. + platforms: [desktop] +--- + +{/* truncate */} + +## What's new + +### SOQL format options + +You can now configure how Jetstream formats the SOQL it generates. Pick the casing and layout options you prefer, and the query builder will apply them consistently whenever it writes SOQL on your behalf. + +### Desktop editor fix + +Fixed a build issue in the desktop app where Monaco editor assets were not packaged correctly, which affected the code editor experience. diff --git a/apps/docs/release-notes/2025-12-23-v8.15.1.mdx b/apps/docs/release-notes/2025-12-23-v8.15.1.mdx new file mode 100644 index 000000000..711ca8c3b --- /dev/null +++ b/apps/docs/release-notes/2025-12-23-v8.15.1.mdx @@ -0,0 +1,40 @@ +--- +slug: v8.15.1 +title: 8.15.1 - Hard delete in load records +date: '2025-12-23' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.15.1 + desktop: 3.9.0 + extension: 2.11.0 +summary: Load records now supports hard delete, plus fixes for the picklist space key and the data table lookup editor. +highlights: + - title: Hard delete for load records + description: Added a hard delete option to the data loader and query results page alongside the existing delete operation. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Picklist space key fix + description: Pressing space in a picklist menu no longer scrolls the page. + platforms: [web, desktop, extension] + - title: Data table lookup editor fix + description: The inline lookup editor in query results no longer closes on the first keypress in manual mode, and remembers your last input mode. + docLink: /query/query-results + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Hard delete for load records + +The load records tool and the query results page now include a hard delete option in addition to the standard delete. Hard deletes skip the Recycle Bin, so use it when you know you want records removed permanently. + +### Picklist space key fix + +Pressing the space key while a picklist menu was open caused the page behind it to scroll. The menu now captures the space key correctly. + +### Data table lookup editor fix + +Editing a lookup field inline on the query results grid used to close the editor on the first keypress when in manual mode. The editor now stays open as you type, and remembers whether you last used the lookup search or manual text input so it opens in that mode next time. diff --git a/apps/docs/release-notes/2026-01-02-v8.16.0.mdx b/apps/docs/release-notes/2026-01-02-v8.16.0.mdx new file mode 100644 index 000000000..9fefac8c5 --- /dev/null +++ b/apps/docs/release-notes/2026-01-02-v8.16.0.mdx @@ -0,0 +1,53 @@ +--- +slug: v8.16.0 +title: 8.16.0 - Team dashboard in desktop, org delete shortcut +date: '2026-01-02' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.16.0 + desktop: 3.11.0 + extension: 2.12.0 +summary: Team admins can now open the team dashboard from the desktop app, and orgs with connection errors get a quick delete shortcut. +highlights: + - title: Team dashboard in the desktop app + description: If your account has team access, a new menu link opens the team dashboard from the desktop app. + platforms: [desktop] + - title: Delete button on errored org cards + description: Orgs with connection errors now show a delete button directly on the card for faster cleanup. + platforms: [web, desktop, extension] + - title: Salesforce connection errors surfaced on desktop + description: The desktop app now shows an error toast when a Salesforce connection fails. + platforms: [desktop] + - title: Encrypted client tokens + description: Stored auth tokens for the desktop app and web extension are now encrypted at rest, with legacy tokens upgraded automatically. + platforms: [desktop, extension] + - title: Consistent static field dropdown on loads + description: The static-value dropdown in field mapping now matches the styling used everywhere else. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Team dashboard in the desktop app + +Team members can now jump to the team dashboard directly from the desktop menu. If your account does not have team access, the link stays hidden. + +### Quicker org cleanup + +When an org has a connection error (expired refresh token, revoked access, etc.), the org card now shows a delete button so you can remove it without digging into settings. On desktop, a connection error also surfaces as a toast instead of failing silently. + +### Stronger auth handling for clients + +- Desktop and web extension tokens are now stored encrypted, with older plaintext tokens upgraded on next access. +- The Salesforce OAuth flow was consolidated into a shared library so desktop and web behave the same. +- Valid tokens are reused within a refresh buffer instead of issuing a new token on every call. + +### Smaller fixes + +- Load Records: the static-value dropdown in field mapping now matches the styling of other field dropdowns. +- Fixed an incorrect OpenAPI route method. +- Fixed redirect URL validation. +- Fixed a typo in the license-assignment error message. diff --git a/apps/docs/release-notes/2026-01-12-v8.17.0.mdx b/apps/docs/release-notes/2026-01-12-v8.17.0.mdx new file mode 100644 index 000000000..9d54713ab --- /dev/null +++ b/apps/docs/release-notes/2026-01-12-v8.17.0.mdx @@ -0,0 +1,50 @@ +--- +slug: v8.17.0 +title: 8.17.0 - Desktop menu upgrades, large XLSX handling +date: '2026-01-12' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.17.0 + desktop: 3.12.0 + extension: 2.13.0 +summary: The desktop app picks up recent-files and settings menu entries, and large XLSX uploads no longer hit "Invalid Array Length" errors. +highlights: + - title: Recent files in the desktop menu + description: The desktop app now lists recently opened files and log files in the menu bar. + platforms: [desktop] + - title: Open settings from the desktop menu + description: Settings are now reachable from a dedicated menu entry instead of only from the in-app nav. + platforms: [desktop] + - title: Large XLSX files load reliably + description: Large spreadsheets that previously failed with "Invalid Array Length" now process by compressing data during conversion. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Desktop bulk query downloads fixed + description: Bulk API query downloads now save to disk correctly on the desktop app. + platforms: [desktop] + - title: Desktop org links open in-app + description: '"Open in Salesforce" links now stay inside the desktop app instead of bouncing to the browser.' + platforms: [desktop] +--- + +{/* truncate */} + +## What's new + +### Desktop menu gets useful entries + +- Recent files and recent log files now appear in the menu bar. +- A new menu entry opens the settings page. +- Electron now runs with a larger heap to reduce out-of-memory errors on big jobs. +- Dev-mode logging no longer writes to the main log file. +- Electron callbacks now unsubscribe correctly to avoid leaks. + +### Large XLSX handling + +XLSX uploads above a certain size occasionally failed with an "Invalid Array Length" error because the underlying library tried to build one huge ArrayBuffer. Jetstream now compresses the data during conversion, which is slightly slower but avoids the cap. + +### Desktop fixes + +- Bulk API query downloads now save the result file correctly on desktop. +- "Open in Salesforce" and similar org links open inside the desktop app rather than forcing a browser. diff --git a/apps/docs/release-notes/2026-01-15-v8.17.1.mdx b/apps/docs/release-notes/2026-01-15-v8.17.1.mdx new file mode 100644 index 000000000..4691504c1 --- /dev/null +++ b/apps/docs/release-notes/2026-01-15-v8.17.1.mdx @@ -0,0 +1,24 @@ +--- +slug: v8.17.1 +title: 8.17.1 - Manage Permissions handles invalid FieldPermission records +date: '2026-01-15' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.17.1 + extension: 2.13.1 +summary: Fixes a Manage Permissions failure caused by invalid FieldPermission records that Salesforce had started returning. +highlights: + - title: Manage Permissions no longer fails on invalid records + description: Salesforce had started returning FieldPermission rows with invalid IDs; Manage Permissions now skips them instead of erroring out. + docLink: /permissions/permissions + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Manage Permissions fix + +Some orgs had FieldPermission records with invalid IDs saved by Salesforce, which caused Manage Permissions to fail when loading them. Jetstream now filters those records out so the page loads and saves reliably. diff --git a/apps/docs/release-notes/2026-01-20-v8.18.0.mdx b/apps/docs/release-notes/2026-01-20-v8.18.0.mdx new file mode 100644 index 000000000..6a93df6a6 --- /dev/null +++ b/apps/docs/release-notes/2026-01-20-v8.18.0.mdx @@ -0,0 +1,54 @@ +--- +slug: v8.18.0 +title: 8.18.0 - Zip preview for data loads, attachment error handling +date: '2026-01-20' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.18.0 + desktop: 3.13.0 + extension: 2.14.0 +summary: Data loads with attachments now preview the zip file and warn about mismatched filenames before the job runs. +highlights: + - title: Zip preview on data loads with attachments + description: When you attach a zip file to a load, Jetstream now previews its contents, warns about invalid filenames, and flags files that do not match any row in the data file. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Missing attachments marked as row errors + description: If a referenced binary file is not found in the zip, that record is now flagged as an error instead of silently succeeding with no attachment. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Aborted downloads handled cleanly + description: Cancelling a server download job no longer triggers closure errors, and completion events include more log context. + platforms: [web] + - title: Team management docs + description: The team management page is now linked from the docs sidebar. +--- + +{/* truncate */} + +## What's new + +### Data load zip preview + +When you pair a CSV with a zip of attachments, the Load Records preview now shows a dedicated zip-file tab. You'll see: + +- The list of files in the zip. +- Warnings for filenames that contain characters Salesforce will reject. +- Warnings for files in the zip that do not match any row in the data file. + +Catching these up front saves the usual round of "why did half my attachments fail" debugging after the job runs. + +### Attachment error handling + +If a record points at a binary file that is missing from the zip, that row is now marked as an error instead of being sent without the attachment. + +### Server reliability + +- Aborted download jobs no longer try to close already-closed streams, and completion logs include more context for debugging. +- Login activity logs are retained for 365 days and email activity logs for 180 days for better audit visibility. +- Upgraded the `tar` dependency to resolve a known vulnerability. + +### Docs + +The team management page is now in the sidebar so it is actually discoverable. diff --git a/apps/docs/release-notes/2026-01-23-v8.18.1.mdx b/apps/docs/release-notes/2026-01-23-v8.18.1.mdx new file mode 100644 index 000000000..2deba57ad --- /dev/null +++ b/apps/docs/release-notes/2026-01-23-v8.18.1.mdx @@ -0,0 +1,22 @@ +--- +slug: v8.18.1 +title: 8.18.1 - Improve email deliverability +date: '2026-01-23' +authors: [jetstream] +tags: [web] +versions: + web: 8.18.1 +summary: Removes the hidden email preview header that was tripping up some corporate email filters. +highlights: + - title: Better email deliverability + description: Removed the invisible preview text in transactional emails so corporate spam filters stop flagging them. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Email deliverability fix + +Transactional emails were being flagged by some corporate mail filters because the preview-text header inserted a block of invisible characters. The preview header has been removed to keep messages landing in inboxes. diff --git a/apps/docs/release-notes/2026-01-23-v8.19.0.mdx b/apps/docs/release-notes/2026-01-23-v8.19.0.mdx new file mode 100644 index 000000000..810f01720 --- /dev/null +++ b/apps/docs/release-notes/2026-01-23-v8.19.0.mdx @@ -0,0 +1,22 @@ +--- +slug: v8.19.0 +title: 8.19.0 - Email log storage +date: '2026-01-23' +authors: [jetstream] +tags: [web] +versions: + web: 8.19.0 +summary: Internal maintenance release that stores sent emails for better visibility into delivery failures. +highlights: + - title: Email log storage + description: Sent emails are now persisted so delivery issues can be investigated beyond the short log retention window. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Email log storage + +Jetstream now stores a record of outgoing emails so that deliverability issues can be investigated after the short log retention window expires. No user-facing changes. diff --git a/apps/docs/release-notes/2026-01-23-v8.19.1.mdx b/apps/docs/release-notes/2026-01-23-v8.19.1.mdx new file mode 100644 index 000000000..59efd196c --- /dev/null +++ b/apps/docs/release-notes/2026-01-23-v8.19.1.mdx @@ -0,0 +1,25 @@ +--- +slug: v8.19.1 +title: 8.19.1 - Field permission correctness fix +date: '2026-01-23' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.19.1 + desktop: 3.13.1 + extension: 2.14.1 +summary: Fix for field permission records that could save with incorrect values when permissions came from alternative sources. +highlights: + - title: Field permission values fix + description: Field permissions are now applied correctly when the source of the permission is not a direct record reference. + docLink: /permissions/permissions + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Field permission values fix + +Fixed a bug where field permission records could be saved with incorrect values when the permission source came from an alternative reference. Records with invalid ids are now ignored while their values are still used so the save completes correctly. diff --git a/apps/docs/release-notes/2026-02-02-v8.19.2.mdx b/apps/docs/release-notes/2026-02-02-v8.19.2.mdx new file mode 100644 index 000000000..80da32cfe --- /dev/null +++ b/apps/docs/release-notes/2026-02-02-v8.19.2.mdx @@ -0,0 +1,24 @@ +--- +slug: v8.19.2 +title: 8.19.2 - Dependency upgrades +date: '2026-02-02' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.19.2 + desktop: 3.13.2 + extension: 2.14.2 +summary: Internal maintenance release with Electron and tar dependency upgrades, including a CVE fix for tar. +highlights: + - title: Maintenance release + description: Upgraded Electron and related dependencies, plus a tar upgrade to address a published CVE. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Maintenance release + +Upgraded Electron and a set of related dependencies. Also upgraded tar to pick up a security fix for a published CVE. No user-facing behavior changes. diff --git a/apps/docs/release-notes/2026-02-03-v8.20.0.mdx b/apps/docs/release-notes/2026-02-03-v8.20.0.mdx new file mode 100644 index 000000000..c3b850190 --- /dev/null +++ b/apps/docs/release-notes/2026-02-03-v8.20.0.mdx @@ -0,0 +1,38 @@ +--- +slug: v8.20.0 +title: 8.20.0 - Permission export improvements +date: '2026-02-03' +authors: [jetstream] +tags: [web] +versions: + web: 8.20.0 +summary: Permission manager exports are more reliable, show real errors on failure, and now offer CSV as a fallback format. +highlights: + - title: More reliable permission exports + description: Export data is now prepared after you choose a download format, and XLSX settings were tuned to reduce generation failures. + docLink: /permissions/permissions + platforms: [web] + - title: CSV fallback for permission exports + description: Added CSV as an export option so you can fall back when XLSX generation fails on very large exports. + docLink: /permissions/permissions + platforms: [web] + - title: Real error messages on export failure + description: Export failures now surface an error to the user instead of silently doing nothing. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### More reliable permission exports + +Permission manager downloads had a few rough edges when exporting large permission sets. Export data is now prepared after you choose a download format rather than up front, and the XLSX generation settings were tuned to reduce failures. + +### CSV fallback for permission exports + +Added CSV as a new export option in the permission manager. If XLSX generation struggles with a large export, CSV gives you a reliable fallback. + +### Real error messages on export failure + +If an export fails, you now see an error message explaining that it failed instead of the download silently doing nothing. diff --git a/apps/docs/release-notes/2026-02-07-v8.21.0.mdx b/apps/docs/release-notes/2026-02-07-v8.21.0.mdx new file mode 100644 index 000000000..6b96c3065 --- /dev/null +++ b/apps/docs/release-notes/2026-02-07-v8.21.0.mdx @@ -0,0 +1,54 @@ +--- +slug: v8.21.0 +title: 8.21.0 - Higher load and download limits +date: '2026-02-07' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.21.0 + desktop: 3.14.0 + extension: 2.15.0 +summary: Higher limits for data loads and attachment downloads, a movable feedback widget, and a fix that keeps permission manager filter text across tab changes. +highlights: + - title: Higher data load batch limits + description: Paid users can now run more batches in a single data load, with a higher ceiling than free users. + docLink: /load/load + platforms: [web, desktop, extension] + - title: Larger attachment downloads + description: Paid web users can download up to 2000 attachments at a time, free users up to 250, and the total size limit was raised from 500MB to 1GB. + platforms: [web] + - title: No download limits on desktop and extension + description: Desktop and browser extension users have no imposed attachment download limits since the work happens locally. + platforms: [desktop, extension] + - title: Movable feedback widget + description: The feedback widget can now be moved or hidden so it does not cover content, and the query builder SOQL editor has extra scroll space underneath. + platforms: [web, desktop, extension] + - title: Permission manager filter persistence + description: The filter text you type in the permission manager is now retained when you switch tabs. + docLink: /permissions/permissions + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Higher data load batch limits + +The maximum number of batches you can submit in a single data load has been raised. Paid users get a higher limit than free users so large loads do not need to be broken into as many separate jobs. + +### Larger attachment downloads + +For the web application, paid users can now download up to 2000 attachments at a time, and free users can download up to 250. The total size limit across a single download was also raised from 500MB to 1GB. + +Desktop and browser extension users do not have an imposed attachment download limit because the downloads run locally and do not use server resources. + +### Movable feedback widget + +The feedback widget can now be moved to a different position or hidden entirely if it gets in the way. The query builder SOQL editor also has extra scroll space underneath it so the widget no longer covers the end of a query. + +The feedback email itself was also improved so the message preview and opening line display better in common email clients. + +### Permission manager filter persistence + +When you have filter text entered in the permission manager and switch between tabs, the filter is now retained instead of clearing. The rows stay filtered, so keeping the filter text matches what you see. diff --git a/apps/docs/release-notes/2026-02-09-v8.22.0.mdx b/apps/docs/release-notes/2026-02-09-v8.22.0.mdx new file mode 100644 index 000000000..b9765863b --- /dev/null +++ b/apps/docs/release-notes/2026-02-09-v8.22.0.mdx @@ -0,0 +1,22 @@ +--- +slug: v8.22.0 +title: 8.22.0 - Auto-select org on group change +date: '2026-02-09' +authors: [jetstream] +tags: [web] +versions: + web: 8.22.0 +summary: Switching org groups now auto-selects the most recently used org in that group, or the first org if none have been used. +highlights: + - title: Auto-select org when changing groups + description: Changing the active org group now picks the most recently used org from that group, or the first org in the list. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Auto-select org when changing groups + +When you switch between org groups, Jetstream now auto-selects the most recently used org from the group you switched to. If no org in the group has been used, the first org in the list is selected instead. This saves a click on every group switch. diff --git a/apps/docs/release-notes/2026-02-12-v8.23.0.mdx b/apps/docs/release-notes/2026-02-12-v8.23.0.mdx new file mode 100644 index 000000000..b3bdbcbe7 --- /dev/null +++ b/apps/docs/release-notes/2026-02-12-v8.23.0.mdx @@ -0,0 +1,34 @@ +--- +slug: v8.23.0 +title: 8.23.0 - Friendlier record creation and keyboard fixes +date: '2026-02-12' +authors: [jetstream] +tags: [web] +versions: + web: 8.23.0 +summary: Owner and audit fields are now optional when creating records, with an option to save even when the form reports errors. Keyboard navigation in lookup pickers is fixed. +highlights: + - title: Audit fields treated as optional on create + description: Owner and audit fields are no longer blocking on record creation, so Salesforce automation can populate them without your form complaining. + - title: Save anyway option + description: If the form shows validation errors that may be cleared by Salesforce automation, you can now save the record anyway. + - title: Keyboard navigation in lookup combobox + description: Tab events are no longer swallowed, so you can move through record lookup and form group dropdowns with the keyboard again. +--- + +{/* truncate */} + +## What's new + +### Record creation handles audit and owner fields better + +When creating a record, owner and audit fields are now shown as optional instead of required. Salesforce often populates these via automation, and forcing them in the UI was causing false validation errors. If your form still shows errors for fields you expect automation to fill in, a new "save anyway" option lets you submit and let Salesforce resolve the rest. + +### Keyboard navigation fixes + +Pressing Tab inside the record lookup combobox and the form group dropdown now moves focus as expected. Previously the keypress was intercepted, trapping keyboard users inside the control. + +### Other fixes + +- Fixed the error boundary fallback so it renders correctly after recent dependency upgrades. +- Assorted dependency updates. diff --git a/apps/docs/release-notes/2026-02-13-v8.23.1.mdx b/apps/docs/release-notes/2026-02-13-v8.23.1.mdx new file mode 100644 index 000000000..89198cf85 --- /dev/null +++ b/apps/docs/release-notes/2026-02-13-v8.23.1.mdx @@ -0,0 +1,22 @@ +--- +slug: v8.23.1 +title: 8.23.1 - Google export fix for Permissions Manager +date: '2026-02-13' +authors: [jetstream] +tags: [web] +versions: + web: 8.23.1 +summary: Exporting from Permissions Manager to Google Drive now correctly produces an Xlsx file instead of falling back to a local CSV download. +highlights: + - title: Permissions Manager Google export fix + description: File-type precedence was reordered so Google exports no longer default to a local CSV download. + docLink: /permissions/permissions +--- + +{/* truncate */} + +## What's new + +### Google export from Permissions Manager + +When exporting permissions to Google Drive, Jetstream was occasionally picking CSV over Xlsx and triggering a local download instead of uploading to Google. The file-type order has been adjusted so Xlsx takes priority and the export lands in Google Drive as intended. diff --git a/apps/docs/release-notes/2026-02-17-v8.24.0.mdx b/apps/docs/release-notes/2026-02-17-v8.24.0.mdx new file mode 100644 index 000000000..c1690fd28 --- /dev/null +++ b/apps/docs/release-notes/2026-02-17-v8.24.0.mdx @@ -0,0 +1,40 @@ +--- +slug: v8.24.0 +title: 8.24.0 - Metadata audit signals and Google folder memory +date: '2026-02-17' +authors: [jetstream] +tags: [web] +versions: + web: 8.24.0 +summary: Custom metadata records now show a last-modified date, invalid metadata timestamps are flagged with a warning, and Jetstream remembers your recent Google Drive folder. +highlights: + - title: Last modified on custom metadata records + description: Custom metadata records now surface SystemModstamp since Salesforce does not return standard audit fields for them. + docLink: /deploy/deploy-metadata + - title: Warning for invalid metadata timestamps + description: When Salesforce returns an invalid audit timestamp, a warning icon now tells you the correct data is not available instead of showing a misleading date. + - title: Remembered Google folder selection + description: When exporting or uploading to Google Drive, your recent folder choice is remembered so repeat uploads take fewer clicks. + - title: Automation Control works in namespaced orgs + description: Orgs that have their own namespace can now manage components inside their managed package from Automation Control. +--- + +{/* truncate */} + +## What's new + +### Better metadata audit info + +Salesforce does not return the normal CreatedBy / LastModifiedBy fields for custom metadata records via listMetadata. Jetstream now injects the available SystemModstamp so you at least see when the record was last touched. Separately, when Salesforce returns an invalid or zero timestamp on any metadata record, Jetstream shows a warning icon instead of formatting a bogus date. + +### Google Drive folder memory + +Loading or exporting to the same Google Drive folder repeatedly used to mean re-picking the folder every time. Jetstream now remembers the most recent folder selection per workflow so you can keep exports flowing into the same place. + +### Automation Control in namespaced orgs + +If your org has its own namespace, Automation Control previously could not act on components owned by the org's managed package. Those components are now reachable. + +### Under the hood + +- Swapped the XML library used during metadata parsing so browser-side flows keep working with the latest releases. diff --git a/apps/docs/release-notes/2026-02-19-v8.25.0.mdx b/apps/docs/release-notes/2026-02-19-v8.25.0.mdx new file mode 100644 index 000000000..13b9edf16 --- /dev/null +++ b/apps/docs/release-notes/2026-02-19-v8.25.0.mdx @@ -0,0 +1,42 @@ +--- +slug: v8.25.0 +title: 8.25.0 - Quick record view in the browser extension +date: '2026-02-19' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 8.25.0 + desktop: 3.15.0 + extension: 2.16.0 +summary: The browser extension gains a quick record view that opens in the same Salesforce tab, plus faster URL detection and login state fixes. +highlights: + - title: Quick record view in-place + description: View a Salesforce record inside the current tab from the browser extension without opening a new one. + platforms: [extension] + - title: Faster URL detection for current-record actions + description: The extension now checks the page URL every 0.5 seconds instead of every 5, so the view/edit current record button stays accurate as you navigate. + platforms: [extension] + - title: Extension login state fixes + description: The extension correctly reacts to login and logout events, and data-sync storage now matches application state. + platforms: [extension] +--- + +{/* truncate */} + +## What's new + +### Quick record view + +The browser extension can now display a record inside the current Salesforce tab, so you do not have to open a new tab just to peek at related data. The new action shows up alongside the existing view/edit record button on Salesforce pages. + +### Snappier current-record detection + +The poll interval the extension uses to pick up URL changes dropped from 5 seconds to half a second. The view/edit current record action reflects the record you are actually on almost immediately. + +### Login and state fixes + +The store provider now wraps the extension UI correctly, so login and logout events are picked up consistently. Data sync storage is also now kept in sync with application state, fixing cases where the UI showed stale information after signing in. + +### Desktop and extension releases + +This release also ships as desktop 3.15.0 and browser extension 2.16.0 alongside the web 8.25.0 release. diff --git a/apps/docs/release-notes/2026-02-27-v9.0.0.mdx b/apps/docs/release-notes/2026-02-27-v9.0.0.mdx new file mode 100644 index 000000000..41f31a0f7 --- /dev/null +++ b/apps/docs/release-notes/2026-02-27-v9.0.0.mdx @@ -0,0 +1,64 @@ +--- +slug: v9.0.0 +title: 9.0.0 - SAML and OIDC single sign-on for teams +date: '2026-02-27' +authors: [jetstream] +tags: [web] +versions: + web: 9.0.0 +summary: Teams can now configure SAML and OIDC single sign-on with domain-based login discovery, plus audit logging on all team record changes and rate-limit hardening. +highlights: + - title: SAML and OIDC SSO for teams + description: Team owners can configure SAML or OIDC providers (Okta, Azure, Google, generic), verify domains, and route members to SSO at login. + docLink: /team-management/sso/sso-overview + - title: Domain discovery at login + description: Enter your email and Jetstream routes you to the right SSO provider based on verified domains without extra clicks. + - title: Team audit log + description: All team-related record changes now write audit entries you can review from the team dashboard. + - title: Rate-limit and security hardening + description: Auth endpoints got tighter rate limiting and additional guards around SSO redirect safety and start-flow validation. + - title: TOTP grace period + description: TOTP verification now allows a 30 second grace window so codes on the edge of a rotation no longer fail. + - title: Improved SSO login form + description: You can submit the form before Turnstile finishes; the login waits for completion on submit. Better for password managers and autofill. +--- + +{/* truncate */} + +## What's new + +### Single sign-on for teams + +Jetstream now supports single sign-on through SAML and OIDC. Team owners configure a provider (Okta, Microsoft Entra / Azure, Google Workspace, or a generic SAML/OIDC provider), verify one or more domains, and optionally enforce SSO for members. When members log in, Jetstream matches their email domain to a verified SSO configuration and sends them to the right identity provider. + +See the [SSO overview](/team-management/sso/sso-overview) for setup walkthroughs per provider. + +### Audit logging on team changes + +Every team related record update now creates an audit log entry. Team owners can review who changed what and when, including member role changes, SSO configuration edits, and domain verification updates. + +### Security and rate limits + +Auth and team endpoints received additional hardening: + +- Tighter rate limits on sensitive auth endpoints. +- SSO start and callback flows validate redirect targets and block unsafe redirects. +- Added a database-backed cache provider so SAML state and similar short-lived data works correctly across instances and processes. +- Moved the SAML ACS identifier from URI to URN for standards compliance. + +### TOTP grace period + +If your TOTP code rotates right as you submit it, Jetstream now allows a 30 second grace window instead of rejecting immediately. You should see far fewer "invalid code" errors at rotation boundaries. + +### Login form quality of life + +The SSO login form no longer blocks submission on Turnstile completion. You can submit right away; Jetstream waits for the challenge before kicking off the login. This makes password manager and autofill flows more reliable. + +### Other fixes + +- Outbound package names in Add to Changeset are now URL-encoded so "No package.xml found" errors no longer trip on special characters. +- Dependency upgrades across the stack. + +### Why 9.0? + +This is a major version bump because SSO changes how login, session, and team auth flow through the product, and it introduces persistent state shared across server instances. Existing users are unaffected. Sign-in still works exactly as before unless your team enrolls in SSO. diff --git a/apps/docs/release-notes/2026-02-28-v9.0.1.mdx b/apps/docs/release-notes/2026-02-28-v9.0.1.mdx new file mode 100644 index 000000000..e8b8c69e3 --- /dev/null +++ b/apps/docs/release-notes/2026-02-28-v9.0.1.mdx @@ -0,0 +1,19 @@ +--- +slug: v9.0.1 +title: 9.0.1 - Maintenance +date: '2026-02-28' +authors: [jetstream] +tags: [web] +versions: + web: 9.0.1 +summary: Internal maintenance release. No user-visible changes. +highlights: + - title: Maintenance release + description: Dependency upgrades and a landing page announcement for the new SSO feature. +--- + +{/* truncate */} + +## What's new + +A follow-up to 9.0.0 with dependency upgrades and a landing-page announcement about SSO availability. No user-facing product changes. diff --git a/apps/docs/release-notes/2026-03-08-v9.1.0.mdx b/apps/docs/release-notes/2026-03-08-v9.1.0.mdx new file mode 100644 index 000000000..6da157097 --- /dev/null +++ b/apps/docs/release-notes/2026-03-08-v9.1.0.mdx @@ -0,0 +1,45 @@ +--- +slug: v9.1.0 +title: 9.1.0 - Paste sanitization and bulk-update errors +date: '2026-03-08' +authors: [jetstream] +tags: [web, extension] +versions: + web: 9.1.0 + extension: 2.17.0 +summary: Editors now strip invisible characters from pasted text, and bulk update failures surface the real server error instead of a generic message. +highlights: + - title: Sanitize pasted text in editors + description: Invisible characters from copied content are removed on paste so Salesforce won't reject the value. + platforms: [web, extension] + - title: Real error messages on bulk update failures + description: When updating records without a file, the actual server error is shown instead of a generic one. + docLink: /load/load + platforms: [web, extension] + - title: Editor line-number reset + description: Anonymous Apex and the metadata compare modal no longer jump to an odd scroll position when the editor re-renders. + docLink: /developer/anonymous-apex + platforms: [web, extension] + - title: Stream error handling in bulk API + description: Errors during bulk API stream processing are surfaced instead of silently aborting. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Paste sanitization in editors + +Invisible and non-printable characters that sneak in when copying text from web pages, PDFs, or chat apps are now stripped when you paste into any Jetstream editor. Salesforce treats those characters as invalid, so removing them up front saves a round trip of confusing save errors. + +### Better errors on bulk update + +If a bulk update without a file fails, you now see the actual error message returned by Salesforce instead of a generic fallback. Much easier to figure out what to fix. + +### Fixes + +- Editor line numbers no longer reset to an incorrect scroll position after state changes in Anonymous Apex and the metadata compare modal. +- Bulk API stream processing surfaces errors instead of silently finishing. +- Corrected invalid icon types, malformed record IDs in lookup popovers, and a duplicated storage check. +- Fixed an invalid export path in the shared UI utilities library. diff --git a/apps/docs/release-notes/2026-03-13-v9.2.0.mdx b/apps/docs/release-notes/2026-03-13-v9.2.0.mdx new file mode 100644 index 000000000..e21a6a1cc --- /dev/null +++ b/apps/docs/release-notes/2026-03-13-v9.2.0.mdx @@ -0,0 +1,32 @@ +--- +slug: v9.2.0 +title: 9.2.0 - Landing page refresh +date: '2026-03-13' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 9.2.0 + desktop: 3.16.0 + extension: 2.18.0 +summary: Refreshed marketing landing page plus internal changelog and CI fixes. No user-facing changes inside the app. +highlights: + - title: Landing page refresh + description: The getjetstream.app marketing site has been updated with new content and visuals. + platforms: [web] + - title: Changelog link fixes + description: Malformed URLs and unlinked commit references in the public changelog have been corrected. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Landing page refresh + +The public landing page at getjetstream.app has been reworked. Nothing changes inside the app itself, just a fresh coat of paint on the marketing side. + +### Maintenance + +- Fixed malformed URLs and unlinked commit references in the changelog. +- Hardened CI commands against shell interpolation and updated GitHub Actions to the latest checkout, setup-node, and upload-artifact versions. diff --git a/apps/docs/release-notes/2026-03-20-v9.3.0.mdx b/apps/docs/release-notes/2026-03-20-v9.3.0.mdx new file mode 100644 index 000000000..ff7b9ef8c --- /dev/null +++ b/apps/docs/release-notes/2026-03-20-v9.3.0.mdx @@ -0,0 +1,40 @@ +--- +slug: v9.3.0 +title: 9.3.0 - Terms of Service acceptance and per-user desktop encryption +date: '2026-03-20' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 9.3.0 + desktop: 3.17.0 + extension: 2.19.0 +summary: New Terms of Service acceptance flow during sign-up and sign-in, plus a fix for desktop users on virtual machines whose saved org credentials were becoming unreadable. +highlights: + - title: Terms of Service acceptance + description: Users are prompted to accept the current Terms of Service during registration and login, with acceptance tracked per account. + platforms: [web, desktop, extension] + - title: Per-user encryption for desktop org data + description: Saved org credentials in the desktop app now use per-user encryption instead of machine-bound keys, fixing data loss on virtual desktops that reprovision daily. + platforms: [desktop] + - title: Google SSO setup docs + description: Added images and clearer help text for configuring the OIDC issuer URL when setting up Google SSO. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Terms of Service acceptance flow + +New and returning users will now see a Terms of Service acceptance prompt. Acceptance is recorded against the account so we can prove consent cleanly for audit and compliance purposes. Once accepted, you won't see the prompt again unless the terms change. + +### Per-user encryption on the desktop app + +If you run the desktop app on a virtual desktop (VDI or similar) where the underlying machine identity changes between sessions, saved orgs would previously become unreadable. Encryption keys are now derived from the logged-in user instead of the machine, so credentials survive VM reprovisioning. + +### Docs and policy updates + +- Google SSO setup now has screenshots and clearer help text for the OIDC issuer URL field. +- DPA text was clarified. +- Terms of Service content and sub-processor list updated. diff --git a/apps/docs/release-notes/2026-03-27-v9.4.0.mdx b/apps/docs/release-notes/2026-03-27-v9.4.0.mdx new file mode 100644 index 000000000..90b20610a --- /dev/null +++ b/apps/docs/release-notes/2026-03-27-v9.4.0.mdx @@ -0,0 +1,49 @@ +--- +slug: v9.4.0 +title: 9.4.0 - Google Drive picker on desktop and extension +date: '2026-03-27' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 9.4.0 + desktop: 3.18.0 + extension: 2.20.0 +summary: Pick files and folders from Google Drive inside the desktop app and browser extension, plus a fix for SFDX change tracking after creating fields with permissions. +highlights: + - title: Google Drive picker on desktop and extension + description: Select files and folders from Google Drive when downloading or loading data, now available from the desktop app and browser extension via an external auth flow. + docLink: /load/load + platforms: [desktop, extension] + - title: SFDX change tracking for new fields with permissions + description: Creating fields with profiles or permission sets selected now touches those records so SFDX CLI picks up the change. + docLink: /deploy/deploy-fields + platforms: [web, desktop, extension] + - title: Keyboard navigation on the feedback widget + description: The feedback widget context menu supports arrow keys, Home/End, Escape, and Shift+F10 without needing a mouse. + platforms: [web, desktop, extension] + - title: Permissions Manager filter input shortcuts + description: Cmd/Ctrl+A, Home, End, and arrow keys in the header filter input now edit the text instead of navigating the grid. + docLink: /permissions/permissions + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Google Drive picker on desktop and extension + +The Google Drive file picker is now wired up for the desktop app and browser extension through an external authentication flow. You can select files for download or upload directly from your Drive without leaving Jetstream. Web users already had this, so now all three platforms behave consistently. + +### Field creation plays nice with SFDX change tracking + +When you created fields and assigned them to profiles or permission sets, SFDX CLI wouldn't detect the permission changes because the underlying Profile and PermissionSet records weren't modified. We now perform a no-op update on those records after deployment to bump `LastModifiedDate`, matching how the Permissions Manager already handles this. If the tracking touch fails, the deployment still succeeds. + +### Accessibility fixes + +- The feedback widget context menu (right-click or Shift+F10) now supports arrow-key navigation, Home/End, and Escape to close. The first item is focused automatically when the menu opens. +- The header filter input in Permissions Manager no longer loses native text-editing shortcuts (Cmd/Ctrl+A, Home, End, arrow keys) to the underlying data grid. + +### Under the hood + +- Admin security-alert emails now include geo-IP distance calculations and multi-IP session checks for better anomaly detection. diff --git a/apps/docs/release-notes/2026-03-31-v9.4.1.mdx b/apps/docs/release-notes/2026-03-31-v9.4.1.mdx new file mode 100644 index 000000000..a249e61ed --- /dev/null +++ b/apps/docs/release-notes/2026-03-31-v9.4.1.mdx @@ -0,0 +1,39 @@ +--- +slug: v9.4.1 +title: 9.4.1 - Desktop org list and Salesforce API fixes +date: '2026-03-31' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 9.4.1 + desktop: 3.18.1 +summary: Fix for orgs and org groups not appearing on first launch of the desktop app, plus safer XML parsing and empty-body handling in the Salesforce API tool. +highlights: + - title: Orgs visible on desktop first launch + description: Orgs and org groups now appear immediately on first load of the desktop app instead of requiring a manual refresh. + platforms: [desktop] + - title: Salesforce API request with empty body + description: Sending a Salesforce API request with an empty body no longer crashes the Monaco editor. + platforms: [web, desktop] + - title: Safer XML parsing + description: XML entity processing is disabled during parsing, removing a class of potential injection issues. + platforms: [web, desktop] +--- + +{/* truncate */} + +## What's new + +### Orgs show up on desktop first launch + +A regression caused orgs and org groups to be invisible until the desktop app was refreshed after first launch. They now render correctly on initial load. + +### Salesforce API tool fixes + +- Requests with an empty body are handled cleanly instead of crashing the editor. +- XML parsing no longer processes entities, closing a potential XXE-style vector. + +### Maintenance + +- Upgraded several vulnerable dependencies. +- Switched the E2E test org to JWT-based auth. diff --git a/apps/docs/release-notes/2026-04-01-v9.5.0.mdx b/apps/docs/release-notes/2026-04-01-v9.5.0.mdx new file mode 100644 index 000000000..f580970f9 --- /dev/null +++ b/apps/docs/release-notes/2026-04-01-v9.5.0.mdx @@ -0,0 +1,35 @@ +--- +slug: v9.5.0 +title: 9.5.0 - Better Salesforce formula evaluation, desktop persistence fixes +date: '2026-04-01' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 9.5.0 + desktop: 3.18.2 +summary: Formula evaluation now uses the new sf-formula-parser library for much better Salesforce formula coverage, plus desktop persistence fixes for VDI environments. +highlights: + - title: New formula evaluation engine + description: Replaced formulon with our open-source sf-formula-parser library for much broader Salesforce formula support and fewer bugs. + platforms: [web, desktop, extension] + - title: Desktop persistence reliability + description: Desktop app no longer encrypts the JWT token and avoids overwriting org data before a valid access token is obtained, reducing logout loops on Windows VDI. + platforms: [desktop] +--- + +{/* truncate */} + +## What's new + +### Salesforce formula evaluation, rebuilt + +We swapped out the old `formulon` engine for `sf-formula-parser`, a new open-source library we built specifically for Salesforce formula coverage. It handles far more of the real-world Salesforce formula language and fixes a number of long-standing bugs where valid formulas returned wrong values or failed outright. + +### Desktop persistence fixes + +On some Windows VDI and virtual-machine setups, users were getting logged out or seeing their org list wiped. Two changes in the desktop client: + +- The JWT auth token is no longer encrypted at rest, which avoids decryption failures across VM snapshots and profile roaming. +- Org data writes are guarded so a missing access token during startup won't clobber previously saved orgs. + +Additional logging was added to the persistence service to make future issues easier to diagnose. diff --git a/apps/docs/release-notes/2026-04-02-v9.6.0.mdx b/apps/docs/release-notes/2026-04-02-v9.6.0.mdx new file mode 100644 index 000000000..625543025 --- /dev/null +++ b/apps/docs/release-notes/2026-04-02-v9.6.0.mdx @@ -0,0 +1,31 @@ +--- +slug: v9.6.0 +title: 9.6.0 - New XML parser, safer user profile handling +date: '2026-04-02' +authors: [jetstream] +tags: [web, desktop] +versions: + web: 9.6.0 +summary: Swapped the XML parsing and building libraries for our own @jetstreamapp/simple-xml to reduce supply-chain risk, plus safer user profile fetch. +highlights: + - title: In-house XML parser + description: Replaced fast-xml-parser and fast-xml-builder with @jetstreamapp/simple-xml to eliminate a class of vulnerability and breaking-change risks. + platforms: [web, desktop, extension] + - title: Safer profile fetch + description: If the user profile call fails, Jetstream now falls back to a default profile instead of surfacing a confusing error. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### New XML parser and builder + +We replaced `fast-xml-parser` and `fast-xml-builder` with `@jetstreamapp/simple-xml`, a library we built ourselves to cover exactly the cases Jetstream needs. The upstream libraries had repeated vulnerability reports and a history of breaking changes shipped as patch releases. Swapping to our own library reduces both bloat and supply-chain exposure. + +Metadata deploys, profile/permission-set exports, and every other place Jetstream reads or writes Salesforce XML now route through the new parser. There should be no visible difference in behavior. + +### Profile fetch fallback + +If `fetchUserProfile` fails (network blip, auth hiccup), the app now returns a sane default profile object instead of throwing. Small change, but it smooths out a few edge-case error screens at login. diff --git a/apps/docs/release-notes/2026-04-02-v9.7.0.mdx b/apps/docs/release-notes/2026-04-02-v9.7.0.mdx new file mode 100644 index 000000000..e65f75788 --- /dev/null +++ b/apps/docs/release-notes/2026-04-02-v9.7.0.mdx @@ -0,0 +1,22 @@ +--- +slug: v9.7.0 +title: 9.7.0 - Updated Terms of Service +date: '2026-04-02' +authors: [jetstream] +tags: [web] +versions: + web: 9.7.0 +summary: Refreshed Terms of Service with a new LastUpdated date and added guidance for reporting security, ethics, or compliance concerns. +highlights: + - title: Updated Terms of Service + description: New LastUpdated date and a compliance reporting section describing how to report security, ethics, or compliance concerns. + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### Terms of Service refresh + +The Terms of Service page has a new `LastUpdated` date and now includes a compliance reporting section covering how to raise security, ethics, or compliance concerns to the Jetstream team. No functional app changes in this release. diff --git a/apps/docs/release-notes/2026-04-03-v9.8.0.mdx b/apps/docs/release-notes/2026-04-03-v9.8.0.mdx new file mode 100644 index 000000000..17235d631 --- /dev/null +++ b/apps/docs/release-notes/2026-04-03-v9.8.0.mdx @@ -0,0 +1,37 @@ +--- +slug: v9.8.0 +title: 9.8.0 - IdP-initiated OIDC login, resilient SOQL formatting +date: '2026-04-03' +authors: [jetstream] +tags: [web] +versions: + web: 9.8.0 +summary: Log in to Jetstream directly from your identity provider's dashboard, plus the query editor no longer crashes on partially typed SOQL. +highlights: + - title: IdP-initiated OIDC login + description: Users can now start login from their identity provider dashboard. Documentation covers the redirect URIs to configure per IdP. + platforms: [web] + - title: SOQL formatter crash fix + description: Invalid or in-progress SOQL no longer crashes editors that call the formatter. Formatting errors are caught and ignored. + docLink: /query/query-results + platforms: [web, desktop, extension] +--- + +{/* truncate */} + +## What's new + +### IdP-initiated OIDC login + +If your organization uses an OIDC identity provider (Okta, Entra, Google Workspace, etc.), users can now click the Jetstream tile in their IdP dashboard and land straight in the app. No more bouncing to Jetstream first to start the auth flow. + +The Jetstream SSO docs have been updated with the redirect URIs you'll need to register for each of the common identity providers. + +### SOQL formatting no longer crashes editors + +A few components pass partially typed SOQL through the formatter as you edit. If the query was syntactically invalid, the formatter could throw and take the surrounding component down with it. Formatting errors are now swallowed and the raw query is kept, so the editor keeps working while you finish typing. + +### Under the hood + +- Rollbar server root configuration removed for cleaner error payloads. +- UI Section component accessibility: corrected `aria-expanded` state and added keyboard focus assertions. diff --git a/apps/docs/release-notes/2026-04-04-v9.8.1.mdx b/apps/docs/release-notes/2026-04-04-v9.8.1.mdx new file mode 100644 index 000000000..96699be07 --- /dev/null +++ b/apps/docs/release-notes/2026-04-04-v9.8.1.mdx @@ -0,0 +1,29 @@ +--- +slug: v9.8.1 +title: 9.8.1 - Resend invitation fix +date: '2026-04-04' +authors: [jetstream] +tags: [web] +versions: + web: 9.8.1 +summary: Fixed an invalid-input error when resending team invitations, and tuned the bot-block response on the API edge. +highlights: + - title: Resend invitation works again + description: Resending a team invitation no longer fails with an invalid input error. + platforms: [web] + - title: Bot route returns 444 + description: Blocked bot traffic now receives status 444 instead of 403 to reduce retry traffic. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Resend invitation fix + +An empty body was being sent to the `resendInvitation` API, which was rejected as invalid input. The request now includes an empty data object so invitations resend correctly. + +### Bot route status code + +The bot-block route now responds with HTTP 444 (connection closed without response) instead of 403. This cuts down on retry storms from abusive clients. diff --git a/apps/docs/release-notes/2026-04-04-v9.9.0.mdx b/apps/docs/release-notes/2026-04-04-v9.9.0.mdx new file mode 100644 index 000000000..7c5ddb26d --- /dev/null +++ b/apps/docs/release-notes/2026-04-04-v9.9.0.mdx @@ -0,0 +1,24 @@ +--- +slug: v9.9.0 +title: 9.9.0 - Long-running requests no longer hit the 524 timeout +date: '2026-04-04' +authors: [jetstream] +tags: [web] +versions: + web: 9.9.0 +summary: New deferred-response middleware keeps long-running Salesforce API requests alive past the Cloudflare 524 timeout by streaming keepalive bytes until the real response is ready. +highlights: + - title: Deferred response middleware + description: Long-running Salesforce requests no longer die with Cloudflare 524 errors. The API streams keepalive bytes and delivers the final JSON when ready. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### No more 524 timeouts on long requests + +Some Salesforce operations (large bulk queries, heavy metadata reads) take longer than Cloudflare's 100-second proxy timeout and would fail with a 524 error. A new `deferredResponseMiddleware` on the API server streams keepalive bytes to the client while the underlying request continues in the background, then writes the final JSON body with `writeDeferredResponse` once it's ready. Errors from the long-running operation are also surfaced through the same deferred channel. + +This is enabled per-route and controlled by environment variables for the keepalive threshold, so it only kicks in for routes that actually need it. diff --git a/apps/docs/release-notes/2026-04-05-v9.9.1.mdx b/apps/docs/release-notes/2026-04-05-v9.9.1.mdx new file mode 100644 index 000000000..bae69b768 --- /dev/null +++ b/apps/docs/release-notes/2026-04-05-v9.9.1.mdx @@ -0,0 +1,29 @@ +--- +slug: v9.9.1 +title: 9.9.1 - Cloudflare Insights CSP, SSO blog link fix +date: '2026-04-05' +authors: [jetstream] +tags: [web] +versions: + web: 9.9.1 +summary: Added Cloudflare Insights to the Content Security Policy and corrected the SSO blog post link on the landing page. +highlights: + - title: Cloudflare Insights in CSP + description: Content Security Policy now allows Cloudflare Insights so performance and security monitoring load without console warnings. + platforms: [web] + - title: SSO blog link corrected + description: The landing-page link to the Jetstream SSO blog post now points at the correct route. + platforms: [web] +--- + +{/* truncate */} + +## What's new + +### Cloudflare Insights allowed in CSP + +Cloudflare Insights was being blocked by our Content Security Policy. The `script-src` directive now includes the Insights host so analytics load cleanly. + +### SSO blog link + +The landing page link to the SSO blog post was pointing at a stale route. It now resolves to the current Jetstream SSO post. diff --git a/apps/docs/release-notes/2026-04-08-v9.10.0.mdx b/apps/docs/release-notes/2026-04-08-v9.10.0.mdx new file mode 100644 index 000000000..d8f62bdbd --- /dev/null +++ b/apps/docs/release-notes/2026-04-08-v9.10.0.mdx @@ -0,0 +1,56 @@ +--- +slug: v9.10.0 +title: 9.10.0 - Import existing fields, more copy-to-clipboard tables +date: '2026-04-08' +authors: [jetstream] +tags: [web] +versions: + web: 9.10.0 +summary: Preload definitions of existing Salesforce fields into Create Fields, and copy data from more tables with a right-click context menu. +highlights: + - title: Import existing fields into Create Fields + description: Pull definitions from fields already on the object into the Create Fields editor as a starting point. + docLink: /deploy/deploy-fields + - title: Copy-to-clipboard context menu on more tables + description: Right-click to copy cells, rows, and columns on the data-load preview, load-failures modal, duplicate-records table, Automation Control editor, and Debug Log viewer. + docLink: /load/load + - title: Field Description in sObject export + description: sObject metadata exports can now include the field-level Description. + docLink: /developer/export-object-metadata + - title: Scroll fix in query history + description: The SOQL preview in a query-history card only captures the mouse wheel when the query is tall enough to actually scroll. + docLink: /query/query + - title: Clearer Create Fields import errors + description: Failed field imports now show the first few validation errors with a count of the remainder instead of a generic failure. + docLink: /deploy/deploy-fields +--- + +{/* truncate */} + +## What's new + +### Import existing fields into Create Fields + +A new Load Existing Fields modal lets you pick fields already on the selected object and drop their definitions into the Create Fields editor. Useful when you want to clone a handful of fields to another object or use an existing field as a template. + +### More tables support right-click copy + +The clipboard context menu (copy cell, copy row as Excel or JSON, copy column, copy table) is now wired up on: + +- The load-records data preview +- The load-records failures and results modal +- The duplicate-records warning table +- The Automation Control editor table +- The Debug Log viewer + +### sObject export + +The field-level `Description` is now selectable in sObject export and is included in the default selection. + +### Other fixes + +- Query-history card no longer hijacks the page scroll when the SOQL preview is short enough to display without scrolling. +- Create Fields import errors now list the first three validation failures and summarize any others. +- Deploy metadata comparison filters out null items that could cause runtime errors. +- Admin email template fixes for severity badges and number formatting. +- `fast-jwt` bumped to 6.2.0. diff --git a/apps/docs/release-notes/2026-04-11-v9.11.0.mdx b/apps/docs/release-notes/2026-04-11-v9.11.0.mdx new file mode 100644 index 000000000..135143b13 --- /dev/null +++ b/apps/docs/release-notes/2026-04-11-v9.11.0.mdx @@ -0,0 +1,41 @@ +--- +slug: v9.11.0 +title: 9.11.0 - JWT rotation for desktop and extension, subquery fixes +date: '2026-04-11' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 9.11.0 + desktop: 3.19.0 + extension: 2.21.0 +summary: Desktop app and browser extension now rotate their authentication tokens. Plus subquery column handling fixes in query results. +highlights: + - title: JWT rotation on desktop and extension + description: Authentication tokens issued to the desktop app and browser extension are now rotated when refreshed. + platforms: [desktop, extension] + - title: Subquery column fixes + description: Fixes several cases where subquery fields and their metadata were mismatched in query results. + docLink: /query/query-results +--- + +{/* truncate */} + +## What's new + +### Rotating authentication tokens on desktop and extension + +The desktop app and browser extension now rotate their JWT credentials when tokens are refreshed, shrinking the window that a leaked token remains valid. No user action required. + +### Subquery handling in query results + +A set of related fixes for subquery columns: + +- Correct `isFieldSubquery` and `fieldMetadataSubquery` lookups so subquery columns render with the right metadata. +- Missing relationship metadata is now tracked rather than silently dropped, which fixes certain column mismatches. +- Internal refactor of subquery column mapping for consistency. + +### Also included + +- Desktop and extension pick up the improved Create Fields error messages and other 9.10.0 fixes. +- TypeScript toolchain bumped to v6 and Vite to v8 (build only, no runtime changes). +- Security dependency upgrades. diff --git a/apps/docs/release-notes/2026-04-14-v9.12.0.mdx b/apps/docs/release-notes/2026-04-14-v9.12.0.mdx new file mode 100644 index 000000000..9d682dd19 --- /dev/null +++ b/apps/docs/release-notes/2026-04-14-v9.12.0.mdx @@ -0,0 +1,36 @@ +--- +slug: v9.12.0 +title: 9.12.0 - Bulk API error handling improvements +date: '2026-04-14' +authors: [jetstream] +tags: [web] +versions: + web: 9.12.0 +summary: Bulk API loads now detect fatal errors and retry transient failures instead of plowing ahead, with clearer progress reporting. +highlights: + - title: Smarter Bulk API error handling + description: Loads stop early on fatal job errors, back off and retry on transient failures, and update submitted-batch counts as batches are accepted. + docLink: /load/load + - title: Web extension asset path fix + description: Internal build fix so extension assets resolve from the correct path. + platforms: [extension] +--- + +{/* truncate */} + +## What's new + +### Bulk API loads handle errors more deliberately + +When loading records via the Bulk API, Jetstream now: + +- Detects fatal job-level errors (invalid job, exceeded quota, job already closed or aborted) and stops submitting further batches instead of repeating the same failure. +- Tracks consecutive batch-submission failures and stops early after too many in a row. +- Reports the submitted-batch count as batches are accepted, so progress reflects real state rather than a static total. +- Returns cleaner errors when a load is aborted versus when it fails. + +### Under the hood + +- Nonce-based Content Security Policy on the web app. +- Web extension asset path fix. +- Server-side logging moved to more granular debug levels. diff --git a/apps/docs/release-notes/2026-04-14-v9.12.1.mdx b/apps/docs/release-notes/2026-04-14-v9.12.1.mdx new file mode 100644 index 000000000..dc34f604b --- /dev/null +++ b/apps/docs/release-notes/2026-04-14-v9.12.1.mdx @@ -0,0 +1,28 @@ +--- +slug: v9.12.1 +title: 9.12.1 - Retry failed rows on a data load +date: '2026-04-14' +authors: [jetstream] +tags: [web] +versions: + web: 9.12.1 +summary: Retry just the failed rows from a data load without re-running the whole job, plus a CSP fix for third-party redirects. +highlights: + - title: Retry failed rows from the load-failures modal + description: Select failed rows in the results modal and retry them with the same configuration instead of re-running the full file. + docLink: /load/load + - title: CSP form-action fix + description: Adds form-action directives so third-party redirects (for example OAuth flows) work under the tightened CSP. +--- + +{/* truncate */} + +## What's new + +### Retry failed rows + +The load-failures modal now supports row selection with a Retry Selected action. Pick the rows you want to re-run and Jetstream kicks off a new load using the existing mapping and options, without forcing you to export the failures and start over. + +### CSP form-action directive + +Adds `form-action` directives to the Content Security Policy so form-POST redirects to third-party origins (for example during OAuth) are not blocked. diff --git a/apps/docs/release-notes/2026-04-19-v9.13.0.mdx b/apps/docs/release-notes/2026-04-19-v9.13.0.mdx new file mode 100644 index 000000000..5d0eb0495 --- /dev/null +++ b/apps/docs/release-notes/2026-04-19-v9.13.0.mdx @@ -0,0 +1,51 @@ +--- +slug: v9.13.0 +title: 9.13.0 - Clickable Name links in query results, auth hardening +date: '2026-04-19' +authors: [jetstream] +tags: [web] +versions: + web: 9.13.0 +summary: Name fields in query results now open the same record-lookup popover as Id links, plus several authentication and session hardening changes. +highlights: + - title: Clickable Name columns in query results + description: Name fields (including relationship Names like Account.Name) render as record-lookup popovers, matching the Id link behavior. + docLink: /query/query-results + - title: Salesforce refresh token rotation + description: Jetstream now stores rotated refresh tokens when Salesforce issues them during a refresh. + - title: Verification attempt limits + description: OTP, email verification, and password reset tokens now expire after a set number of invalid attempts, with rate limits on internal password reset endpoints. + - title: Revoke other sessions on password change + description: Setting a new password or removing a password from the profile page now logs out all other active sessions. + - title: Require auth before serving the app + description: Unauthenticated requests to app routes are redirected up front rather than loading the SPA and redirecting from the client. +--- + +{/* truncate */} + +## What's new + +### Name columns act like Id columns + +In query results, `Name` and relationship Name columns (for example `Account.Name`, `Owner.Name`) now render as clickable links that open the record-lookup popover, matching how Id columns already behaved. Aggregate columns and subquery child columns are skipped. + +### Salesforce refresh token rotation + +When Salesforce returns a new refresh token during a token refresh, Jetstream now stores it instead of continuing to use the old one. + +### Verification attempt limits + +OTP, email verification, and password reset tokens now expire after a set number of invalid attempts as a defense-in-depth measure. Internal password reset endpoints have additional rate limits. + +### Password change revokes other sessions + +Changing or removing your password from the profile page now deletes all other active sessions for your account. + +### Auth gate before the app loads + +A new middleware redirects unauthenticated requests to the login page before the app shell is served, avoiding a brief flash of the app for logged-out users. + +### Other + +- `NotificationClose` failures are swallowed locally instead of being reported to Rollbar. +- Dependency upgrades including `dompurify` 3.4.0 and a `@babel/traverse` security patch. diff --git a/apps/docs/release-notes/2026-04-19-v9.14.0.mdx b/apps/docs/release-notes/2026-04-19-v9.14.0.mdx new file mode 100644 index 000000000..83b166a51 --- /dev/null +++ b/apps/docs/release-notes/2026-04-19-v9.14.0.mdx @@ -0,0 +1,40 @@ +--- +slug: v9.14.0 +title: 9.14.0 - Profile and Permission Set info popover +date: '2026-04-19' +authors: [jetstream] +tags: [web, desktop, extension] +versions: + web: 9.14.0 + desktop: 3.20.0 + extension: 2.22.0 +summary: A new info popover on Profile and Permission Set rows shows assigned users and a direct link to Setup, plus security header and CSP improvements. +highlights: + - title: Profile and Permission Set info popover + description: An info trigger on Profile and Permission Set list rows opens a popover with the record label, assigned active users (searchable), and a Setup link. + docLink: /permissions/permissions + - title: Tighter security headers and cookie handling + description: Server sends hardened security headers and no longer relies on the legacy jetstream cookie for data access. + - title: CSP updates + description: Allow additional image and script sources needed for login and embedded content while keeping the tightened policy in place. +--- + +{/* truncate */} + +## What's new + +### Profile and Permission Set info popover + +Profile and Permission Set rows in Manage Permissions, Create Fields selection, Create New Object Permissions, Formula Evaluator permissions, and the User search popover now have a small info trigger. Clicking it opens a popover that shows the record label, a searchable list of assigned active users (for profiles) or active assignees (for permission sets), and a direct link to the record in Salesforce Setup. + +### Security headers and cookie cleanup + +- The legacy `JETSTREAM` cookie has been removed; the app now reads `serverUrl` from environment configuration instead. +- Added a dedicated security-headers module on the API with tests covering auth storage and proxy-cookie behavior. +- Suppresses verification emails that would otherwise be sent for placeholder login sessions. + +### CSP adjustments + +- Added image sources (for example Cloudinary, Gravatar) so avatars and embedded images render under the tightened policy. +- Desktop CSP expanded to cover additional image sources. +- Additional script and connect sources added to support login flows. diff --git a/apps/docs/release-notes/_DOC_AUDIT.md b/apps/docs/release-notes/_DOC_AUDIT.md new file mode 100644 index 000000000..728f9b251 --- /dev/null +++ b/apps/docs/release-notes/_DOC_AUDIT.md @@ -0,0 +1,106 @@ +# Doc staleness audit + +Generated 2026-04-20 while backfilling release notes for v7.0.0 through v9.14.0. Each entry flags a feature that shipped in the noted release but may not be covered (or accurately covered) in the corresponding docs page. Filename is `_`-prefixed so Docusaurus ignores it. + +**How to use this:** walk through each entry, open the suggested docs page, and either confirm the current doc is accurate or update it. Items are sorted by docs area so a docs writer can batch work. + +--- + +## Query + +- **v7.0.0 — Datatable keyboard navigation** (Tab across action/Id columns, Enter opens record popover, focus styles on keyboard-copy). Check [query-results.mdx](../docs/query/query-results.mdx) for a "Keyboard shortcuts" section; consider adding one if missing. +- **v7.3.2 — Bulk update results modal.** Verify `query-results.mdx` covers the full bulk-update-from-query flow (selecting records, running updates, viewing results). +- **v7.6.0 — Record modal at app level.** View/Edit/Clone record modal is now managed at the application level and emits recent-records updates. `query-results.mdx` may describe this only as a query-results feature. +- **v8.4.0 — Query area updates** (broad). Spot-check `query-results.mdx` against the release highlights. +- **v8.5.0 — Binary attachment downloads overhaul** (server streaming, Static Resource support, automatic field re-query). Check [download-attachments.mdx](../docs/query/download-attachments.mdx) screenshots and flow. +- **v8.9.0 — Edit/create/clone modal respects View All records.** Worth a paragraph in `query-results.mdx`. +- **v8.13.0 / v8.14.0 / v8.15.1 — Record lookup editor, polymorphic object selection, query-filter-value lookup.** Likely needs new sections in `query-results.mdx`. +- **v8.21.0 — Attachment download caps raised (500 MB to 1 GB; 2000/250 result caps).** Diff touched `download-attachments.mdx`; verify the documented numbers match the new caps. +- **v9.10.0 — Context menu on tables.** Copy-to-clipboard now works on duplicate records, data-load preview, load-failures modal, Automation Control editor, and Debug Log viewer. `query-results.mdx` should mention the right-click actions (the existing v9.10.0 post incorrectly scoped this to duplicates only). +- **v9.13.0 — Name columns render as links.** Only Name / relationship-Name columns got the new clickable behavior; Id columns already had it. Update `query-results.mdx` accordingly. + +## Load + +- **v7.2.0 — Copy load results to clipboard** (Excel/CSV/JSON from the results modal). No doc yet; consider adding to [load.mdx](../docs/load/load.mdx) or [update-records.mdx](../docs/load/update-records.mdx). +- **v7.6.0 — Google Sheet refresh.** Refresh works reliably after navigating forward/back. Note in `load.mdx`. +- **v7.6.2 — Binary attachment upload limits.** `load-attachments.mdx` was updated in the PR; verify wording covers "desktop/extension unlimited, web paid 1 GB." +- **v7.7.0 — Field mapping dropdown update** (badge removed). Screenshots in `update-records.mdx` may be stale. +- **v7.8.0 — Streaming multipart binary uploads, raised free-plan attachment limit.** `load-attachments.mdx` should reflect streaming behavior and current limits. +- **v8.2.0 — `rollbackOnError` default for production orgs.** Consider mentioning in [load-custom-metadata.mdx](../docs/load/load-custom-metadata.mdx). +- **v8.3.0 — Polymorphic related-object loading and retry UX.** Verify [load-with-related.mdx](../docs/load/load-with-related.mdx) covers on-demand metadata fetch and retry. +- **v8.15.1 — Hard delete in load records.** New option in `update-records.mdx`; confirm it is documented. +- **v8.17.0 — Large XLSX handling.** Large spreadsheets no longer error with "Invalid Array Length." Optional note in `load.mdx`. +- **v8.18.0 — Zip preview + missing-attachment error handling.** Extend `load-attachments.mdx`. +- **v8.21.0 — Data load batch limits (tiered).** Diff touched `load.mdx`; verify tiers are accurately reflected. +- **v8.23.0 — "Save anyway" / optional audit-field setting on record create.** No doc yet; consider extending [create-record-without-file.mdx](../docs/load/create-record-without-file.mdx). +- **v8.24.0 — Google folder memory.** `load.mdx` could mention Jetstream remembers the most recently used Drive folder. +- **v9.4.0 — Google Drive picker on desktop + extension.** `load.mdx` and/or export docs may still imply Drive is web-only. +- **v9.12.0 — Bulk API fatal-error handling.** Behavior change for how loads stop on unrecoverable errors. Update `load.mdx`. +- **v9.12.1 — Retry failed rows.** Prominent feature in the failures modal. Verify `update-records.mdx` / `load.mdx`. + +## Deploy + +- **v7.1.0 — "Toggle unchanged lines" in metadata-compare modal.** [deploy-metadata.mdx](../docs/deploy/deploy-metadata.mdx) likely doesn't describe this control. +- **v7.1.0 — Folder metadata types** (Document, Email, Report, Dashboard folders now selectable). Update `deploy-metadata.mdx` if it implies folders aren't supported. +- **v7.3.5 — Diff editor swap + collapse-unchanged-regions controls.** Verify `deploy-metadata.mdx`. +- **v7.6.0 — Add-to-Changeset deploy options, prod default rollback-on-failure.** Add to `deploy-metadata.mdx`. +- **v8.11.0 — `package.xml` comment support + production test-level validation.** Both warrant notes in `deploy-metadata.mdx`. +- **v8.24.0 — Custom metadata last-modified display + invalid-timestamp warning.** Consider in `deploy-metadata.mdx`. +- **v9.4.0 — SFDX change tracking for newly created fields.** Note in [deploy-fields.mdx](../docs/deploy/deploy-fields.mdx) that SFDX CLI will now pick up permission changes on new fields. +- **v9.5.0 — Formula evaluator engine swap to `sf-formula-parser`.** Spot-check [formula-evaluator.mdx](../docs/deploy/formula-evaluator.mdx) for any behavior differences to call out. +- **v9.10.0 — "Load Existing Fields" modal in Create Fields.** New feature; `deploy-fields.mdx` should describe it. +- **v9.10.0 — sObject export Description field.** The v9.10.0 prior-draft called this "object-level Description"; actually the **field-level** `Description` from `FieldDefinition`. Update [export-object-metadata.mdx](../docs/developer/export-object-metadata.mdx). + +## Permissions + +- **v7.9.0 — View All Fields object permission.** Add the `viewAllFields` column to [permissions.mdx](../docs/permissions/permissions.mdx). +- **v8.20.0 — Permission manager CSV fallback and error UX.** Update `permissions.mdx`. +- **v9.14.0 — `ProfileOrPermSetPopover` info popover.** The existing v9.14.0 draft mischaracterized this as a "quick-filter picker"; it's actually an **info/details popover** (per-row icon, searchable active-user list, Setup link). Update `permissions.mdx` to reflect the real behavior. + +## Developer + +- **v9.10.0 — sObject export Description field** (see Deploy section — same item, cross-listed). +- **v9.1.0 — Paste sanitization** across editors (invisible characters stripped). Worth a note in [anonymous-apex.mdx](../docs/developer/anonymous-apex.mdx) and any other editor pages. + +## Team management + +- **v8.0.0 — Team plan + team dashboard.** `team-management.mdx` was added; verify login-configuration coverage matches current UI. +- **v8.8.0 — "Jetstream Organization" rename to "Organization Group."** Scan `team-management/` for leftover "Jetstream Organization" terminology. +- **v8.8.0 — Org expiration 90-day workflow + notification emails.** No doc yet; consider adding. +- **v8.8.0 — Bulk org delete modal.** Screenshot refresh on org pages. +- **v8.9.0 — Team role restrictions** (billing-only users can't modify admins). Note in `team-management.mdx`. +- **v8.16.0 — Desktop team-dashboard link.** Note that desktop is supported on `team-management.mdx`. +- **v8.22.0 — Org-group auto-select on change.** Consider noting in `org-groups.mdx` or a getting-started section. +- **v9.0.0 — SSO (SAML / OIDC).** Docs exist under [team-management/sso/](../docs/team-management/sso/); confirm top-level overview links to SSO configuration. +- **v9.8.0 — IdP-initiated OIDC login.** SSO setup page should list redirect URIs for Okta, Entra, Google Workspace. + +## Getting started / security + +- **v7.3.0 — Desktop app Windows support.** Verify [desktop-app.mdx](../docs/getting-started/desktop-app.mdx) covers Windows install, auto-update, and Start Menu behavior. +- **v7.3.3 — Upcoming Salesforce Connected App changes banner.** Consider a dedicated section in [troubleshooting.mdx](../docs/getting-started/troubleshooting.mdx) keyed to the banner link. +- **v7.4.0 — Per-org encryption keys** (backend/security). Optional mention in `security.mdx`. +- **v7.7.0 — CSRF protection.** Transparent; an optional note in a security/FAQ page. +- **v7.10.0 — Outbound IP address ranges page.** New partial [_ip-address-ranges.mdx](../docs/getting-started/_ip-address-ranges.mdx); review for accuracy once ranges are finalized. +- **v8.6.0 — Cookie consent banner.** If analytics behavior is documented anywhere, update. +- **v8.7.0 — Connected app install doc links.** Verify install/sandbox docs cover the "sync permissions to sandbox" callout. +- **v8.9.0 — Auth hardening** (password history, account lockout, email-enumeration protection). `security.mdx` could mention. +- **v8.9.0 — In-app feedback widget placement.** Not in `feedback.mdx`; consider adding. +- **v8.21.0 — Movable / hide-able feedback widget.** Consider a section under a general UI or settings doc. +- **v8.25.0 — Quick record view in extension.** Verify [browser-extension.mdx](../docs/getting-started/browser-extension/browser-extension.mdx) covers the new in-tab quick-view action. +- **v9.0.0 — TOTP grace period.** Check `security.mdx`. +- **v9.3.0 — Terms of Service acceptance flow.** No doc page; consider one under account/auth. +- **v9.3.0 — Per-user desktop encryption.** Note on `desktop-app.mdx` for VDI/multi-user setups. +- **v9.4.0 — Feedback widget keyboard navigation** (Arrow keys, Home/End, Escape, Shift+F10). If an accessibility page exists, add. + +## Miscellaneous + +- **v9.9.0 — Deferred response middleware.** No more 524 errors on long requests. If any troubleshooting doc lists a 524 workaround, remove or update it. +- **v9.2.0 — Marketing landing page refresh** (not docs; no action). +- **v8.15.0 — User-configurable SOQL format options.** No existing doc covers this; consider a new settings section under `query/`. + +--- + +## Notes + +- This audit was compiled from the PR/diff research done while writing each release note. It is a starting point, not an exhaustive docs TODO. Some flagged items may already be covered (subagents flag when uncertain). +- Several release notes previously made inaccurate claims; the v9.10.0-v9.14.0 set was rewritten from scratch with verified facts. If you discover other release notes with similar issues, please correct them in place. diff --git a/apps/docs/release-notes/authors.yml b/apps/docs/release-notes/authors.yml new file mode 100644 index 000000000..de3c92934 --- /dev/null +++ b/apps/docs/release-notes/authors.yml @@ -0,0 +1,6 @@ +jetstream: + name: Jetstream team + title: Jetstream + url: https://getjetstream.app + # image_url: /img/jetstream-logo.svg + page: false diff --git a/apps/jetstream-desktop-client/project.json b/apps/jetstream-desktop-client/project.json index 1770f8c30..775035cca 100644 --- a/apps/jetstream-desktop-client/project.json +++ b/apps/jetstream-desktop-client/project.json @@ -9,6 +9,7 @@ "executor": "@nx/vite:build", "outputs": ["{options.outputPath}"], "defaultConfiguration": "production", + "dependsOn": ["^build", "release-notes:build-data"], "options": { "outputPath": "dist/apps/jetstream-desktop-client" }, diff --git a/apps/jetstream-web-extension/project.json b/apps/jetstream-web-extension/project.json index e4be9e655..c2c9ea4a5 100644 --- a/apps/jetstream-web-extension/project.json +++ b/apps/jetstream-web-extension/project.json @@ -9,6 +9,7 @@ "executor": "@nx/vite:build", "outputs": ["{options.outputPath}"], "defaultConfiguration": "production", + "dependsOn": ["^build", "release-notes:build-data"], "options": { "outputPath": "dist/apps/jetstream-web-extension" }, diff --git a/apps/jetstream/project.json b/apps/jetstream/project.json index 39c622698..d46c6bbb9 100644 --- a/apps/jetstream/project.json +++ b/apps/jetstream/project.json @@ -8,6 +8,7 @@ "targets": { "build": { "executor": "@nx/vite:build", + "dependsOn": ["^build", "release-notes:build-data"], "options": { "outputPath": "dist/apps/jetstream" }, diff --git a/libs/release-notes/eslint.config.js b/libs/release-notes/eslint.config.js new file mode 100644 index 000000000..b94a75657 --- /dev/null +++ b/libs/release-notes/eslint.config.js @@ -0,0 +1,9 @@ +const baseConfig = require('../../eslint.config.js'); + +module.exports = [ + ...baseConfig, + { + files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], + rules: {}, + }, +]; diff --git a/libs/release-notes/project.json b/libs/release-notes/project.json new file mode 100644 index 000000000..312e093b4 --- /dev/null +++ b/libs/release-notes/project.json @@ -0,0 +1,33 @@ +{ + "name": "release-notes", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/release-notes/src", + "projectType": "library", + "tags": ["scope:shared"], + "implicitDependencies": [], + "generators": {}, + "targets": { + "build-data": { + "executor": "nx:run-commands", + "inputs": [ + "{workspaceRoot}/apps/docs/release-notes/**/*.mdx", + "{workspaceRoot}/scripts/generate-release-notes.ts", + "{projectRoot}/src/lib/release-notes.types.ts" + ], + "outputs": ["{projectRoot}/src/lib/release-notes.generated.json"], + "options": { + "command": "zx ./scripts/generate-release-notes.ts" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + }, + "test": { + "executor": "@nx/vitest:test", + "outputs": ["{options.reportsDirectory}"], + "options": { + "reportsDirectory": "{projectRoot}/../../coverage/libs/release-notes" + } + } + } +} diff --git a/libs/release-notes/src/index.ts b/libs/release-notes/src/index.ts new file mode 100644 index 000000000..2a34bdd8e --- /dev/null +++ b/libs/release-notes/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/release-notes.types'; +export * from './lib/release-notes-utils'; +export { RELEASE_NOTES } from './lib/release-notes.data'; diff --git a/libs/release-notes/src/lib/__tests__/release-notes-utils.test.ts b/libs/release-notes/src/lib/__tests__/release-notes-utils.test.ts new file mode 100644 index 000000000..f793058bd --- /dev/null +++ b/libs/release-notes/src/lib/__tests__/release-notes-utils.test.ts @@ -0,0 +1,102 @@ +import { describe, expect, it } from 'vitest'; +import { ReleaseNote } from '../release-notes.types'; +import { getLatestDate, getUnseenCount, getVisibleReleases } from '../release-notes-utils'; + +const releases: ReleaseNote[] = [ + { + slug: 'v9.14.0', + title: '9.14.0', + date: '2026-04-19', + tags: ['web', 'desktop'], + summary: 'Web + desktop release', + highlights: [ + { title: 'Profile popover', platforms: ['web', 'desktop'] }, + { title: 'Security headers', platforms: ['web'] }, + ], + }, + { + slug: 'v2.22.0-ext', + title: 'Extension 2.22.0', + date: '2026-04-10', + tags: ['extension'], + summary: 'Extension-only release', + highlights: [{ title: 'Extension asset path fix' }], + }, + { + slug: 'v9.13.0', + title: '9.13.0', + date: '2026-04-05', + tags: ['all'], + summary: 'Applies to everywhere', + highlights: [{ title: 'Platform-agnostic feature' }], + }, +]; + +describe('release-notes-utils', () => { + describe('getVisibleReleases', () => { + it('filters releases by platform tag', () => { + const result = getVisibleReleases(releases, 'web'); + expect(result.map(({ slug }) => slug)).toEqual(['v9.14.0', 'v9.13.0']); + }); + + it('includes releases tagged "all" for any platform', () => { + const result = getVisibleReleases(releases, 'extension'); + expect(result.map(({ slug }) => slug)).toEqual(['v2.22.0-ext', 'v9.13.0']); + }); + + it('drops highlights filtered by per-highlight platforms override', () => { + const result = getVisibleReleases(releases, 'desktop'); + const desktopRelease = result.find(({ slug }) => slug === 'v9.14.0'); + expect(desktopRelease?.highlights.map(({ title }) => title)).toEqual(['Profile popover']); + }); + + it('drops releases whose highlights all filter out', () => { + const noHighlightsForDesktop: ReleaseNote[] = [ + { + slug: 'v1.0.0', + title: 'v1', + date: '2026-01-01', + tags: ['web', 'desktop'], + summary: 'mixed', + highlights: [{ title: 'Web only', platforms: ['web'] }], + }, + ]; + expect(getVisibleReleases(noHighlightsForDesktop, 'desktop')).toEqual([]); + }); + + it('sorts newest first', () => { + const result = getVisibleReleases(releases, 'web'); + expect(result[0].date > result[1].date).toBe(true); + }); + + it('filters to releases strictly newer than sinceDate', () => { + const result = getVisibleReleases(releases, 'web', '2026-04-05'); + expect(result.map(({ slug }) => slug)).toEqual(['v9.14.0']); + }); + }); + + describe('getLatestDate', () => { + it('returns the newest date for a platform', () => { + expect(getLatestDate(releases, 'web')).toBe('2026-04-19'); + expect(getLatestDate(releases, 'extension')).toBe('2026-04-10'); + }); + + it('returns null when no releases match', () => { + expect(getLatestDate([], 'web')).toBeNull(); + }); + }); + + describe('getUnseenCount', () => { + it('counts all releases when watermark is null', () => { + expect(getUnseenCount(releases, 'web', null)).toBe(2); + }); + + it('counts only releases newer than watermark', () => { + expect(getUnseenCount(releases, 'web', '2026-04-05')).toBe(1); + }); + + it('returns zero when watermark matches newest date', () => { + expect(getUnseenCount(releases, 'web', '2026-04-19')).toBe(0); + }); + }); +}); diff --git a/libs/release-notes/src/lib/release-notes-utils.ts b/libs/release-notes/src/lib/release-notes-utils.ts new file mode 100644 index 000000000..d1541929d --- /dev/null +++ b/libs/release-notes/src/lib/release-notes-utils.ts @@ -0,0 +1,59 @@ +import { ReleaseHighlight, ReleaseNote, ReleasePlatform, ReleaseTag } from './release-notes.types'; + +function platformMatches(tags: ReleaseTag[] | undefined, platform: ReleasePlatform): boolean { + if (!tags || tags.length === 0) { + return true; + } + return tags.includes('all') || tags.includes(platform); +} + +function filterHighlightsByPlatform(highlights: ReleaseHighlight[], platform: ReleasePlatform): ReleaseHighlight[] { + return highlights.filter((highlight) => platformMatches(highlight.platforms, platform)); +} + +/** + * Returns the releases visible to a given platform, sorted newest first. + * A release is retained if its `tags` include the platform (or `all`). + * Highlight-level `platforms` overrides further filter individual bullets; + * a release with zero surviving highlights is dropped. + * + * @param sinceDate Optional ISO date string (YYYY-MM-DD). If provided, only releases strictly newer are returned. + */ +export function getVisibleReleases( + notes: ReleaseNote[], + platform: ReleasePlatform, + sinceDate?: string | null, +): ReleaseNote[] { + const result: ReleaseNote[] = []; + for (const note of notes) { + if (!platformMatches(note.tags, platform)) { + continue; + } + if (sinceDate && note.date <= sinceDate) { + continue; + } + const highlights = filterHighlightsByPlatform(note.highlights, platform); + if (highlights.length === 0) { + continue; + } + result.push({ ...note, highlights }); + } + return result.sort((releaseA, releaseB) => (releaseA.date < releaseB.date ? 1 : releaseA.date > releaseB.date ? -1 : 0)); +} + +/** + * Returns the ISO date of the most-recent release visible to the given platform, + * or null when there are no eligible releases. + */ +export function getLatestDate(notes: ReleaseNote[], platform: ReleasePlatform): string | null { + const visible = getVisibleReleases(notes, platform); + return visible[0]?.date ?? null; +} + +/** + * Count of unseen releases for a given platform, relative to the watermark date. + * When watermark is null/undefined, every eligible release counts as unseen. + */ +export function getUnseenCount(notes: ReleaseNote[], platform: ReleasePlatform, watermarkDate: string | null | undefined): number { + return getVisibleReleases(notes, platform, watermarkDate ?? null).length; +} diff --git a/libs/release-notes/src/lib/release-notes.data.ts b/libs/release-notes/src/lib/release-notes.data.ts new file mode 100644 index 000000000..f035af6e8 --- /dev/null +++ b/libs/release-notes/src/lib/release-notes.data.ts @@ -0,0 +1,4 @@ +import generated from './release-notes.generated.json'; +import { ReleaseNote } from './release-notes.types'; + +export const RELEASE_NOTES: ReleaseNote[] = generated as ReleaseNote[]; diff --git a/libs/release-notes/src/lib/release-notes.generated.json b/libs/release-notes/src/lib/release-notes.generated.json new file mode 100644 index 000000000..202ebe310 --- /dev/null +++ b/libs/release-notes/src/lib/release-notes.generated.json @@ -0,0 +1,2960 @@ +[ + { + "slug": "v9.14.0", + "title": "9.14.0 - Profile and Permission Set info popover", + "date": "2026-04-19", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "9.14.0", + "desktop": "3.20.0", + "extension": "2.22.0" + }, + "summary": "A new info popover on Profile and Permission Set rows shows assigned users and a direct link to Setup, plus security header and CSP improvements.", + "highlights": [ + { + "title": "Profile and Permission Set info popover", + "description": "An info trigger on Profile and Permission Set list rows opens a popover with the record label, assigned active users (searchable), and a Setup link.", + "docLink": "/permissions/permissions" + }, + { + "title": "Tighter security headers and cookie handling", + "description": "Server sends hardened security headers and no longer relies on the legacy jetstream cookie for data access." + }, + { + "title": "CSP updates", + "description": "Allow additional image and script sources needed for login and embedded content while keeping the tightened policy in place." + } + ] + }, + { + "slug": "v9.13.0", + "title": "9.13.0 - Clickable Name links in query results, auth hardening", + "date": "2026-04-19", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.13.0" + }, + "summary": "Name fields in query results now open the same record-lookup popover as Id links, plus several authentication and session hardening changes.", + "highlights": [ + { + "title": "Clickable Name columns in query results", + "description": "Name fields (including relationship Names like Account.Name) render as record-lookup popovers, matching the Id link behavior.", + "docLink": "/query/query-results" + }, + { + "title": "Salesforce refresh token rotation", + "description": "Jetstream now stores rotated refresh tokens when Salesforce issues them during a refresh." + }, + { + "title": "Verification attempt limits", + "description": "OTP, email verification, and password reset tokens now expire after a set number of invalid attempts, with rate limits on internal password reset endpoints." + }, + { + "title": "Revoke other sessions on password change", + "description": "Setting a new password or removing a password from the profile page now logs out all other active sessions." + }, + { + "title": "Require auth before serving the app", + "description": "Unauthenticated requests to app routes are redirected up front rather than loading the SPA and redirecting from the client." + } + ] + }, + { + "slug": "v9.12.1", + "title": "9.12.1 - Retry failed rows on a data load", + "date": "2026-04-14", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.12.1" + }, + "summary": "Retry just the failed rows from a data load without re-running the whole job, plus a CSP fix for third-party redirects.", + "highlights": [ + { + "title": "Retry failed rows from the load-failures modal", + "description": "Select failed rows in the results modal and retry them with the same configuration instead of re-running the full file.", + "docLink": "/load/load" + }, + { + "title": "CSP form-action fix", + "description": "Adds form-action directives so third-party redirects (for example OAuth flows) work under the tightened CSP." + } + ] + }, + { + "slug": "v9.12.0", + "title": "9.12.0 - Bulk API error handling improvements", + "date": "2026-04-14", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.12.0" + }, + "summary": "Bulk API loads now detect fatal errors and retry transient failures instead of plowing ahead, with clearer progress reporting.", + "highlights": [ + { + "title": "Smarter Bulk API error handling", + "description": "Loads stop early on fatal job errors, back off and retry on transient failures, and update submitted-batch counts as batches are accepted.", + "docLink": "/load/load" + }, + { + "title": "Web extension asset path fix", + "description": "Internal build fix so extension assets resolve from the correct path.", + "platforms": [ + "extension" + ] + } + ] + }, + { + "slug": "v9.11.0", + "title": "9.11.0 - JWT rotation for desktop and extension, subquery fixes", + "date": "2026-04-11", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "9.11.0", + "desktop": "3.19.0", + "extension": "2.21.0" + }, + "summary": "Desktop app and browser extension now rotate their authentication tokens. Plus subquery column handling fixes in query results.", + "highlights": [ + { + "title": "JWT rotation on desktop and extension", + "description": "Authentication tokens issued to the desktop app and browser extension are now rotated when refreshed.", + "platforms": [ + "desktop", + "extension" + ] + }, + { + "title": "Subquery column fixes", + "description": "Fixes several cases where subquery fields and their metadata were mismatched in query results.", + "docLink": "/query/query-results" + } + ] + }, + { + "slug": "v9.10.0", + "title": "9.10.0 - Import existing fields, more copy-to-clipboard tables", + "date": "2026-04-08", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.10.0" + }, + "summary": "Preload definitions of existing Salesforce fields into Create Fields, and copy data from more tables with a right-click context menu.", + "highlights": [ + { + "title": "Import existing fields into Create Fields", + "description": "Pull definitions from fields already on the object into the Create Fields editor as a starting point.", + "docLink": "/deploy/deploy-fields" + }, + { + "title": "Copy-to-clipboard context menu on more tables", + "description": "Right-click to copy cells, rows, and columns on the data-load preview, load-failures modal, duplicate-records table, Automation Control editor, and Debug Log viewer.", + "docLink": "/load/load" + }, + { + "title": "Field Description in sObject export", + "description": "sObject metadata exports can now include the field-level Description.", + "docLink": "/developer/export-object-metadata" + }, + { + "title": "Scroll fix in query history", + "description": "The SOQL preview in a query-history card only captures the mouse wheel when the query is tall enough to actually scroll.", + "docLink": "/query/query" + }, + { + "title": "Clearer Create Fields import errors", + "description": "Failed field imports now show the first few validation errors with a count of the remainder instead of a generic failure.", + "docLink": "/deploy/deploy-fields" + } + ] + }, + { + "slug": "v9.9.1", + "title": "9.9.1 - Cloudflare Insights CSP, SSO blog link fix", + "date": "2026-04-05", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.9.1" + }, + "summary": "Added Cloudflare Insights to the Content Security Policy and corrected the SSO blog post link on the landing page.", + "highlights": [ + { + "title": "Cloudflare Insights in CSP", + "description": "Content Security Policy now allows Cloudflare Insights so performance and security monitoring load without console warnings.", + "platforms": [ + "web" + ] + }, + { + "title": "SSO blog link corrected", + "description": "The landing-page link to the Jetstream SSO blog post now points at the correct route.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v9.9.0", + "title": "9.9.0 - Long-running requests no longer hit the 524 timeout", + "date": "2026-04-04", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.9.0" + }, + "summary": "New deferred-response middleware keeps long-running Salesforce API requests alive past the Cloudflare 524 timeout by streaming keepalive bytes until the real response is ready.", + "highlights": [ + { + "title": "Deferred response middleware", + "description": "Long-running Salesforce requests no longer die with Cloudflare 524 errors. The API streams keepalive bytes and delivers the final JSON when ready.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v9.8.1", + "title": "9.8.1 - Resend invitation fix", + "date": "2026-04-04", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.8.1" + }, + "summary": "Fixed an invalid-input error when resending team invitations, and tuned the bot-block response on the API edge.", + "highlights": [ + { + "title": "Resend invitation works again", + "description": "Resending a team invitation no longer fails with an invalid input error.", + "platforms": [ + "web" + ] + }, + { + "title": "Bot route returns 444", + "description": "Blocked bot traffic now receives status 444 instead of 403 to reduce retry traffic.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v9.8.0", + "title": "9.8.0 - IdP-initiated OIDC login, resilient SOQL formatting", + "date": "2026-04-03", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.8.0" + }, + "summary": "Log in to Jetstream directly from your identity provider's dashboard, plus the query editor no longer crashes on partially typed SOQL.", + "highlights": [ + { + "title": "IdP-initiated OIDC login", + "description": "Users can now start login from their identity provider dashboard. Documentation covers the redirect URIs to configure per IdP.", + "platforms": [ + "web" + ] + }, + { + "title": "SOQL formatter crash fix", + "description": "Invalid or in-progress SOQL no longer crashes editors that call the formatter. Formatting errors are caught and ignored.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query-results" + } + ] + }, + { + "slug": "v9.7.0", + "title": "9.7.0 - Updated Terms of Service", + "date": "2026-04-02", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.7.0" + }, + "summary": "Refreshed Terms of Service with a new LastUpdated date and added guidance for reporting security, ethics, or compliance concerns.", + "highlights": [ + { + "title": "Updated Terms of Service", + "description": "New LastUpdated date and a compliance reporting section describing how to report security, ethics, or compliance concerns.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v9.6.0", + "title": "9.6.0 - New XML parser, safer user profile handling", + "date": "2026-04-02", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "9.6.0" + }, + "summary": "Swapped the XML parsing and building libraries for our own @jetstreamapp/simple-xml to reduce supply-chain risk, plus safer user profile fetch.", + "highlights": [ + { + "title": "In-house XML parser", + "description": "Replaced fast-xml-parser and fast-xml-builder with @jetstreamapp/simple-xml to eliminate a class of vulnerability and breaking-change risks.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Safer profile fetch", + "description": "If the user profile call fails, Jetstream now falls back to a default profile instead of surfacing a confusing error.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v9.5.0", + "title": "9.5.0 - Better Salesforce formula evaluation, desktop persistence fixes", + "date": "2026-04-01", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "9.5.0", + "desktop": "3.18.2" + }, + "summary": "Formula evaluation now uses the new sf-formula-parser library for much better Salesforce formula coverage, plus desktop persistence fixes for VDI environments.", + "highlights": [ + { + "title": "New formula evaluation engine", + "description": "Replaced formulon with our open-source sf-formula-parser library for much broader Salesforce formula support and fewer bugs.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Desktop persistence reliability", + "description": "Desktop app no longer encrypts the JWT token and avoids overwriting org data before a valid access token is obtained, reducing logout loops on Windows VDI.", + "platforms": [ + "desktop" + ] + } + ] + }, + { + "slug": "v9.4.1", + "title": "9.4.1 - Desktop org list and Salesforce API fixes", + "date": "2026-03-31", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "9.4.1", + "desktop": "3.18.1" + }, + "summary": "Fix for orgs and org groups not appearing on first launch of the desktop app, plus safer XML parsing and empty-body handling in the Salesforce API tool.", + "highlights": [ + { + "title": "Orgs visible on desktop first launch", + "description": "Orgs and org groups now appear immediately on first load of the desktop app instead of requiring a manual refresh.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Salesforce API request with empty body", + "description": "Sending a Salesforce API request with an empty body no longer crashes the Monaco editor.", + "platforms": [ + "web", + "desktop" + ] + }, + { + "title": "Safer XML parsing", + "description": "XML entity processing is disabled during parsing, removing a class of potential injection issues.", + "platforms": [ + "web", + "desktop" + ] + } + ] + }, + { + "slug": "v9.4.0", + "title": "9.4.0 - Google Drive picker on desktop and extension", + "date": "2026-03-27", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "9.4.0", + "desktop": "3.18.0", + "extension": "2.20.0" + }, + "summary": "Pick files and folders from Google Drive inside the desktop app and browser extension, plus a fix for SFDX change tracking after creating fields with permissions.", + "highlights": [ + { + "title": "Google Drive picker on desktop and extension", + "description": "Select files and folders from Google Drive when downloading or loading data, now available from the desktop app and browser extension via an external auth flow.", + "platforms": [ + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "SFDX change tracking for new fields with permissions", + "description": "Creating fields with profiles or permission sets selected now touches those records so SFDX CLI picks up the change.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/deploy/deploy-fields" + }, + { + "title": "Keyboard navigation on the feedback widget", + "description": "The feedback widget context menu supports arrow keys, Home/End, Escape, and Shift+F10 without needing a mouse.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Permissions Manager filter input shortcuts", + "description": "Cmd/Ctrl+A, Home, End, and arrow keys in the header filter input now edit the text instead of navigating the grid.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + } + ] + }, + { + "slug": "v9.3.0", + "title": "9.3.0 - Terms of Service acceptance and per-user desktop encryption", + "date": "2026-03-20", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "9.3.0", + "desktop": "3.17.0", + "extension": "2.19.0" + }, + "summary": "New Terms of Service acceptance flow during sign-up and sign-in, plus a fix for desktop users on virtual machines whose saved org credentials were becoming unreadable.", + "highlights": [ + { + "title": "Terms of Service acceptance", + "description": "Users are prompted to accept the current Terms of Service during registration and login, with acceptance tracked per account.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Per-user encryption for desktop org data", + "description": "Saved org credentials in the desktop app now use per-user encryption instead of machine-bound keys, fixing data loss on virtual desktops that reprovision daily.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Google SSO setup docs", + "description": "Added images and clearer help text for configuring the OIDC issuer URL when setting up Google SSO.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v9.2.0", + "title": "9.2.0 - Landing page refresh", + "date": "2026-03-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "9.2.0", + "desktop": "3.16.0", + "extension": "2.18.0" + }, + "summary": "Refreshed marketing landing page plus internal changelog and CI fixes. No user-facing changes inside the app.", + "highlights": [ + { + "title": "Landing page refresh", + "description": "The getjetstream.app marketing site has been updated with new content and visuals.", + "platforms": [ + "web" + ] + }, + { + "title": "Changelog link fixes", + "description": "Malformed URLs and unlinked commit references in the public changelog have been corrected.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v9.1.0", + "title": "9.1.0 - Paste sanitization and bulk-update errors", + "date": "2026-03-08", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "extension" + ], + "versions": { + "web": "9.1.0", + "extension": "2.17.0" + }, + "summary": "Editors now strip invisible characters from pasted text, and bulk update failures surface the real server error instead of a generic message.", + "highlights": [ + { + "title": "Sanitize pasted text in editors", + "description": "Invisible characters from copied content are removed on paste so Salesforce won't reject the value.", + "platforms": [ + "web", + "extension" + ] + }, + { + "title": "Real error messages on bulk update failures", + "description": "When updating records without a file, the actual server error is shown instead of a generic one.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Editor line-number reset", + "description": "Anonymous Apex and the metadata compare modal no longer jump to an odd scroll position when the editor re-renders.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/developer/anonymous-apex" + }, + { + "title": "Stream error handling in bulk API", + "description": "Errors during bulk API stream processing are surfaced instead of silently aborting.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v9.0.1", + "title": "9.0.1 - Maintenance", + "date": "2026-02-28", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.0.1" + }, + "summary": "Internal maintenance release. No user-visible changes.", + "highlights": [ + { + "title": "Maintenance release", + "description": "Dependency upgrades and a landing page announcement for the new SSO feature." + } + ] + }, + { + "slug": "v9.0.0", + "title": "9.0.0 - SAML and OIDC single sign-on for teams", + "date": "2026-02-27", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "9.0.0" + }, + "summary": "Teams can now configure SAML and OIDC single sign-on with domain-based login discovery, plus audit logging on all team record changes and rate-limit hardening.", + "highlights": [ + { + "title": "SAML and OIDC SSO for teams", + "description": "Team owners can configure SAML or OIDC providers (Okta, Azure, Google, generic), verify domains, and route members to SSO at login.", + "docLink": "/team-management/sso/sso-overview" + }, + { + "title": "Domain discovery at login", + "description": "Enter your email and Jetstream routes you to the right SSO provider based on verified domains without extra clicks." + }, + { + "title": "Team audit log", + "description": "All team-related record changes now write audit entries you can review from the team dashboard." + }, + { + "title": "Rate-limit and security hardening", + "description": "Auth endpoints got tighter rate limiting and additional guards around SSO redirect safety and start-flow validation." + }, + { + "title": "TOTP grace period", + "description": "TOTP verification now allows a 30 second grace window so codes on the edge of a rotation no longer fail." + }, + { + "title": "Improved SSO login form", + "description": "You can submit the form before Turnstile finishes; the login waits for completion on submit. Better for password managers and autofill." + } + ] + }, + { + "slug": "v8.25.0", + "title": "8.25.0 - Quick record view in the browser extension", + "date": "2026-02-19", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.25.0", + "desktop": "3.15.0", + "extension": "2.16.0" + }, + "summary": "The browser extension gains a quick record view that opens in the same Salesforce tab, plus faster URL detection and login state fixes.", + "highlights": [ + { + "title": "Quick record view in-place", + "description": "View a Salesforce record inside the current tab from the browser extension without opening a new one.", + "platforms": [ + "extension" + ] + }, + { + "title": "Faster URL detection for current-record actions", + "description": "The extension now checks the page URL every 0.5 seconds instead of every 5, so the view/edit current record button stays accurate as you navigate.", + "platforms": [ + "extension" + ] + }, + { + "title": "Extension login state fixes", + "description": "The extension correctly reacts to login and logout events, and data-sync storage now matches application state.", + "platforms": [ + "extension" + ] + } + ] + }, + { + "slug": "v8.24.0", + "title": "8.24.0 - Metadata audit signals and Google folder memory", + "date": "2026-02-17", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.24.0" + }, + "summary": "Custom metadata records now show a last-modified date, invalid metadata timestamps are flagged with a warning, and Jetstream remembers your recent Google Drive folder.", + "highlights": [ + { + "title": "Last modified on custom metadata records", + "description": "Custom metadata records now surface SystemModstamp since Salesforce does not return standard audit fields for them.", + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Warning for invalid metadata timestamps", + "description": "When Salesforce returns an invalid audit timestamp, a warning icon now tells you the correct data is not available instead of showing a misleading date." + }, + { + "title": "Remembered Google folder selection", + "description": "When exporting or uploading to Google Drive, your recent folder choice is remembered so repeat uploads take fewer clicks." + }, + { + "title": "Automation Control works in namespaced orgs", + "description": "Orgs that have their own namespace can now manage components inside their managed package from Automation Control." + } + ] + }, + { + "slug": "v8.23.1", + "title": "8.23.1 - Google export fix for Permissions Manager", + "date": "2026-02-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.23.1" + }, + "summary": "Exporting from Permissions Manager to Google Drive now correctly produces an Xlsx file instead of falling back to a local CSV download.", + "highlights": [ + { + "title": "Permissions Manager Google export fix", + "description": "File-type precedence was reordered so Google exports no longer default to a local CSV download.", + "docLink": "/permissions/permissions" + } + ] + }, + { + "slug": "v8.23.0", + "title": "8.23.0 - Friendlier record creation and keyboard fixes", + "date": "2026-02-12", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.23.0" + }, + "summary": "Owner and audit fields are now optional when creating records, with an option to save even when the form reports errors. Keyboard navigation in lookup pickers is fixed.", + "highlights": [ + { + "title": "Audit fields treated as optional on create", + "description": "Owner and audit fields are no longer blocking on record creation, so Salesforce automation can populate them without your form complaining." + }, + { + "title": "Save anyway option", + "description": "If the form shows validation errors that may be cleared by Salesforce automation, you can now save the record anyway." + }, + { + "title": "Keyboard navigation in lookup combobox", + "description": "Tab events are no longer swallowed, so you can move through record lookup and form group dropdowns with the keyboard again." + } + ] + }, + { + "slug": "v8.22.0", + "title": "8.22.0 - Auto-select org on group change", + "date": "2026-02-09", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.22.0" + }, + "summary": "Switching org groups now auto-selects the most recently used org in that group, or the first org if none have been used.", + "highlights": [ + { + "title": "Auto-select org when changing groups", + "description": "Changing the active org group now picks the most recently used org from that group, or the first org in the list.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v8.21.0", + "title": "8.21.0 - Higher load and download limits", + "date": "2026-02-07", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.21.0", + "desktop": "3.14.0", + "extension": "2.15.0" + }, + "summary": "Higher limits for data loads and attachment downloads, a movable feedback widget, and a fix that keeps permission manager filter text across tab changes.", + "highlights": [ + { + "title": "Higher data load batch limits", + "description": "Paid users can now run more batches in a single data load, with a higher ceiling than free users.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Larger attachment downloads", + "description": "Paid web users can download up to 2000 attachments at a time, free users up to 250, and the total size limit was raised from 500MB to 1GB.", + "platforms": [ + "web" + ] + }, + { + "title": "No download limits on desktop and extension", + "description": "Desktop and browser extension users have no imposed attachment download limits since the work happens locally.", + "platforms": [ + "desktop", + "extension" + ] + }, + { + "title": "Movable feedback widget", + "description": "The feedback widget can now be moved or hidden so it does not cover content, and the query builder SOQL editor has extra scroll space underneath.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Permission manager filter persistence", + "description": "The filter text you type in the permission manager is now retained when you switch tabs.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + } + ] + }, + { + "slug": "v8.20.0", + "title": "8.20.0 - Permission export improvements", + "date": "2026-02-03", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.20.0" + }, + "summary": "Permission manager exports are more reliable, show real errors on failure, and now offer CSV as a fallback format.", + "highlights": [ + { + "title": "More reliable permission exports", + "description": "Export data is now prepared after you choose a download format, and XLSX settings were tuned to reduce generation failures.", + "platforms": [ + "web" + ], + "docLink": "/permissions/permissions" + }, + { + "title": "CSV fallback for permission exports", + "description": "Added CSV as an export option so you can fall back when XLSX generation fails on very large exports.", + "platforms": [ + "web" + ], + "docLink": "/permissions/permissions" + }, + { + "title": "Real error messages on export failure", + "description": "Export failures now surface an error to the user instead of silently doing nothing.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v8.19.2", + "title": "8.19.2 - Dependency upgrades", + "date": "2026-02-02", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.19.2", + "desktop": "3.13.2", + "extension": "2.14.2" + }, + "summary": "Internal maintenance release with Electron and tar dependency upgrades, including a CVE fix for tar.", + "highlights": [ + { + "title": "Maintenance release", + "description": "Upgraded Electron and related dependencies, plus a tar upgrade to address a published CVE.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.19.1", + "title": "8.19.1 - Field permission correctness fix", + "date": "2026-01-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.19.1", + "desktop": "3.13.1", + "extension": "2.14.1" + }, + "summary": "Fix for field permission records that could save with incorrect values when permissions came from alternative sources.", + "highlights": [ + { + "title": "Field permission values fix", + "description": "Field permissions are now applied correctly when the source of the permission is not a direct record reference.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + } + ] + }, + { + "slug": "v8.19.0", + "title": "8.19.0 - Email log storage", + "date": "2026-01-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.19.0" + }, + "summary": "Internal maintenance release that stores sent emails for better visibility into delivery failures.", + "highlights": [ + { + "title": "Email log storage", + "description": "Sent emails are now persisted so delivery issues can be investigated beyond the short log retention window.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v8.18.1", + "title": "8.18.1 - Improve email deliverability", + "date": "2026-01-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.18.1" + }, + "summary": "Removes the hidden email preview header that was tripping up some corporate email filters.", + "highlights": [ + { + "title": "Better email deliverability", + "description": "Removed the invisible preview text in transactional emails so corporate spam filters stop flagging them.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v8.18.0", + "title": "8.18.0 - Zip preview for data loads, attachment error handling", + "date": "2026-01-20", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.18.0", + "desktop": "3.13.0", + "extension": "2.14.0" + }, + "summary": "Data loads with attachments now preview the zip file and warn about mismatched filenames before the job runs.", + "highlights": [ + { + "title": "Zip preview on data loads with attachments", + "description": "When you attach a zip file to a load, Jetstream now previews its contents, warns about invalid filenames, and flags files that do not match any row in the data file.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Missing attachments marked as row errors", + "description": "If a referenced binary file is not found in the zip, that record is now flagged as an error instead of silently succeeding with no attachment.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Aborted downloads handled cleanly", + "description": "Cancelling a server download job no longer triggers closure errors, and completion events include more log context.", + "platforms": [ + "web" + ] + }, + { + "title": "Team management docs", + "description": "The team management page is now linked from the docs sidebar." + } + ] + }, + { + "slug": "v8.17.1", + "title": "8.17.1 - Manage Permissions handles invalid FieldPermission records", + "date": "2026-01-15", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.17.1", + "extension": "2.13.1" + }, + "summary": "Fixes a Manage Permissions failure caused by invalid FieldPermission records that Salesforce had started returning.", + "highlights": [ + { + "title": "Manage Permissions no longer fails on invalid records", + "description": "Salesforce had started returning FieldPermission rows with invalid IDs; Manage Permissions now skips them instead of erroring out.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + } + ] + }, + { + "slug": "v8.17.0", + "title": "8.17.0 - Desktop menu upgrades, large XLSX handling", + "date": "2026-01-12", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.17.0", + "desktop": "3.12.0", + "extension": "2.13.0" + }, + "summary": "The desktop app picks up recent-files and settings menu entries, and large XLSX uploads no longer hit \"Invalid Array Length\" errors.", + "highlights": [ + { + "title": "Recent files in the desktop menu", + "description": "The desktop app now lists recently opened files and log files in the menu bar.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Open settings from the desktop menu", + "description": "Settings are now reachable from a dedicated menu entry instead of only from the in-app nav.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Large XLSX files load reliably", + "description": "Large spreadsheets that previously failed with \"Invalid Array Length\" now process by compressing data during conversion.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Desktop bulk query downloads fixed", + "description": "Bulk API query downloads now save to disk correctly on the desktop app.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Desktop org links open in-app", + "description": "\"Open in Salesforce\" links now stay inside the desktop app instead of bouncing to the browser.", + "platforms": [ + "desktop" + ] + } + ] + }, + { + "slug": "v8.16.0", + "title": "8.16.0 - Team dashboard in desktop, org delete shortcut", + "date": "2026-01-02", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.16.0", + "desktop": "3.11.0", + "extension": "2.12.0" + }, + "summary": "Team admins can now open the team dashboard from the desktop app, and orgs with connection errors get a quick delete shortcut.", + "highlights": [ + { + "title": "Team dashboard in the desktop app", + "description": "If your account has team access, a new menu link opens the team dashboard from the desktop app.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Delete button on errored org cards", + "description": "Orgs with connection errors now show a delete button directly on the card for faster cleanup.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Salesforce connection errors surfaced on desktop", + "description": "The desktop app now shows an error toast when a Salesforce connection fails.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Encrypted client tokens", + "description": "Stored auth tokens for the desktop app and web extension are now encrypted at rest, with legacy tokens upgraded automatically.", + "platforms": [ + "desktop", + "extension" + ] + }, + { + "title": "Consistent static field dropdown on loads", + "description": "The static-value dropdown in field mapping now matches the styling used everywhere else.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.15.1", + "title": "8.15.1 - Hard delete in load records", + "date": "2025-12-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.15.1", + "desktop": "3.9.0", + "extension": "2.11.0" + }, + "summary": "Load records now supports hard delete, plus fixes for the picklist space key and the data table lookup editor.", + "highlights": [ + { + "title": "Hard delete for load records", + "description": "Added a hard delete option to the data loader and query results page alongside the existing delete operation.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Picklist space key fix", + "description": "Pressing space in a picklist menu no longer scrolls the page.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Data table lookup editor fix", + "description": "The inline lookup editor in query results no longer closes on the first keypress in manual mode, and remembers your last input mode.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query-results" + } + ] + }, + { + "slug": "v8.15.0", + "title": "8.15.0 - Configurable SOQL format options", + "date": "2025-12-16", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.15.0", + "desktop": "3.8.2", + "extension": "2.10.0" + }, + "summary": "Choose how Jetstream formats generated SOQL to match your preferences, plus a desktop asset fix for the code editor.", + "highlights": [ + { + "title": "SOQL format options", + "description": "Configure how generated SOQL is formatted, including casing and layout preferences.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Desktop editor assets fixed", + "description": "Resolved missing Monaco editor assets in the desktop build.", + "platforms": [ + "desktop" + ] + } + ] + }, + { + "slug": "v8.14.0", + "title": "8.14.0 - Record lookup in query filters", + "date": "2025-12-14", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "8.14.0" + }, + "summary": "Query filter values now support a record lookup so you can search for the record you want to filter on instead of hunting for an ID.", + "highlights": [ + { + "title": "Record lookup in query filters", + "description": "When building a query filter on a reference field, search for the related record and have the ID inserted into your SOQL.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query-results" + }, + { + "title": "Lookup clear button fix", + "description": "The clear button now works correctly when the lookup editor is in manual text entry mode.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.13.1", + "title": "8.13.1 - Lookup filter styling fix", + "date": "2025-12-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.13.1", + "desktop": "3.8.1", + "extension": "2.9.1" + }, + "summary": "Follow-up fix to styling on the new record lookup filter.", + "highlights": [ + { + "title": "Lookup filter styles", + "description": "Corrected visual styling on the record lookup filter introduced in 8.13.0.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.13.0", + "title": "8.13.0 - Lookup picker for reference fields", + "date": "2025-12-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.13.0", + "desktop": "3.8.0", + "extension": "2.9.0" + }, + "summary": "Editing reference fields now offers a lookup search instead of pasting raw IDs, with polymorphic object selection built in.", + "highlights": [ + { + "title": "Record lookup for reference fields", + "description": "Search for related records when editing lookup fields, including choosing the target object for polymorphic references.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query-results" + }, + { + "title": "Accessibility fixes", + "description": "Resolved several accessibility issues across the app.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.12.1", + "title": "8.12.1 - Feedback attachment fix", + "date": "2025-12-12", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.12.1" + }, + "summary": "Patch release that fixes multiple file attachments in the new in-app feedback widget.", + "highlights": [ + { + "title": "Multiple feedback attachments", + "description": "The feedback form now supports up to 5 attachments, warns when you exceed the limit, and correctly delivers every attachment in the resulting email.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/getting-started/feedback" + } + ] + }, + { + "slug": "v8.12.0", + "title": "8.12.0 - In-app feedback", + "date": "2025-12-12", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.12.0", + "desktop": "3.7.0", + "extension": "2.8.0" + }, + "summary": "Send feedback and bug reports directly from inside Jetstream, with support for file attachments on web, desktop, and the browser extension.", + "highlights": [ + { + "title": "In-app feedback", + "description": "A new feedback widget lets you send questions, bug reports, and suggestions directly from the app instead of filing a GitHub issue.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/getting-started/feedback" + }, + { + "title": "Feedback from every form factor", + "description": "The feedback flow works on web, desktop, and the browser extension, with attachment support on every platform.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Web extension binary upload", + "description": "The browser extension now uses the same binary upload path as desktop, so file attachments upload reliably.", + "platforms": [ + "extension" + ] + } + ] + }, + { + "slug": "v8.11.0", + "title": "8.11.0 - Bug bash fixes and API version bump", + "date": "2025-12-05", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.11.0" + }, + "summary": "A batch of bug fixes from an internal bug bash, XML comment support in package manifests, clearer deployment terminology, and an API version bump.", + "highlights": [ + { + "title": "Package.xml comment support", + "description": "Comments inside an XML package manifest no longer break parsing during deploy and retrieve operations.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Editing orgs on the deployment page", + "description": "Fixed a bug where editing an org from the deployment page would break navigation to the next step.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Unmanaged terminology", + "description": "References to \"non-managed\" tests and fields were updated to \"unmanaged\" across the UI and docs for consistency with Salesforce.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Production test level warning", + "description": "The deployment options screen now shows an inline error when an invalid test level is picked for a production org.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Salesforce API 65.0", + "description": "Bumped the default Salesforce API version from 64.0 to 65.0.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.10.0", + "title": "8.10.0 - Session error detection and SOQL parser bump", + "date": "2025-12-01", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.10.0", + "desktop": "3.6.1", + "extension": "2.7.1" + }, + "summary": "Better detection of invalid org sessions so connection errors are surfaced promptly, plus a SOQL parser upgrade and regression coverage for base64 conversion.", + "highlights": [ + { + "title": "Invalid session detection", + "description": "Additional Salesforce error responses now mark the org as having a connection error, so you are prompted to reconnect instead of hitting opaque failures.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "SOQL parser upgrade", + "description": "Bumped soql-parser-js to 6.3.0 for improved parsing coverage.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query" + }, + { + "title": "Base64 conversion hardening", + "description": "Removed duplicated base64-to-ArrayBuffer code and added regression tests after the 8.9.x download issue.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.9.1", + "title": "8.9.1 - Fix metadata download regression", + "date": "2025-11-25", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.9.1", + "desktop": "3.6.0", + "extension": "2.7.0" + }, + "summary": "Patch release that restores metadata downloads after a regression in base64 handling.", + "highlights": [ + { + "title": "Metadata downloads work again", + "description": "A recent refactor broke base64-to-ArrayBuffer conversion, which caused metadata downloads to fail. The conversion path is fixed.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + } + ] + }, + { + "slug": "v8.9.0", + "title": "8.9.0 - Auth hardening and edit modal improvements", + "date": "2025-11-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.9.0", + "desktop": "3.5.0", + "extension": "2.6.0" + }, + "summary": "Major authentication hardening including password history and account lockout, plus View All records access in the edit/create/clone record modal.", + "highlights": [ + { + "title": "Auth hardening", + "description": "Password history prevents reuse of the last 10 passwords, account lockout protects against repeated reset attempts, and login flows no longer leak whether an email is registered.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Improved password reset flow", + "description": "Changed passwords are tracked in history, the strength indicator shows on reset, reuse errors stay visible, and the login form auto-fills the reset email.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "View All Records on edit modal", + "description": "The edit, create, and clone record modal now loads every field instead of only layout-assigned fields.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query-results" + }, + { + "title": "Team role safety", + "description": "Billing-only users can no longer promote others to admin or modify administrator accounts.", + "platforms": [ + "web" + ], + "docLink": "/team-management/team-management" + }, + { + "title": "Smarter org expiration emails", + "description": "The 90-day inactive-org reminder now skips users who do not actively use Jetstream, and test-mode summaries are accurate.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v8.8.0", + "title": "8.8.0 - Org expiration, Organization Groups, bulk org delete", + "date": "2025-11-15", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.8.0" + }, + "summary": "Unused Salesforce orgs now expire with advance email notice, the Organization page handles refresh/reconnect cleanly, and you can delete orgs in bulk.", + "highlights": [ + { + "title": "Org expiration with email notice", + "description": "Salesforce orgs unused for 90 days are flagged for expiration, with email notifications summarizing expiring and expired orgs." + }, + { + "title": "Easier reconnect for expired orgs", + "description": "The Organization page surfaces expiring and expired orgs, and reconnect uses login_hint and pre-filled connection details." + }, + { + "title": "Bulk delete Salesforce orgs", + "description": "Select and delete multiple connected orgs at once from the Organizations page." + }, + { + "title": "Rename to \"Organization Group\"", + "description": "What used to be called \"Jetstream Organization\" is now \"Organization Group\" everywhere in the app, to avoid confusion with a Salesforce organization." + }, + { + "title": "Download format is remembered", + "description": "Your last-used download format (CSV, Excel, JSON, etc.) is remembered per-user as the new default." + } + ] + }, + { + "slug": "v8.7.0", + "title": "8.7.0 - Table filter fixes and connected-app onboarding help", + "date": "2025-11-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.7.0" + }, + "summary": "Table filters now stay in sync when data reloads, password reset accepts plus-sign emails, and orgs missing the Jetstream connected app get clearer install guidance.", + "highlights": [ + { + "title": "Table filters follow data updates", + "description": "When table data reloads, existing filters are retained and their available values update so the filter still matches the new records.", + "docLink": "/query/query-results" + }, + { + "title": "Numeric column filters fixed", + "description": "Filters on numeric fields now behave correctly and no longer drop values on refresh." + }, + { + "title": "Password reset with plus-sign emails", + "description": "Emails containing a \"+\" no longer get mangled into a space during password reset." + }, + { + "title": "Connected app install guidance", + "description": "Help links point users to the page where they would install the Jetstream connected app if it is missing, plus a sandbox sync callout." + }, + { + "title": "Cookie banner padding fix", + "description": "The consent banner no longer throws off in-app alignment while still looking right on the landing page." + } + ] + }, + { + "slug": "v8.6.0", + "title": "8.6.0 - Opt-in analytics with cookie consent", + "date": "2025-11-07", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.6.0", + "desktop": "3.4.0", + "extension": "2.5.0" + }, + "summary": "Analytics are now opt-in via a cookie consent banner for GDPR compliance, plus dependency upgrades and a desktop and extension version bump.", + "highlights": [ + { + "title": "Cookie consent banner", + "description": "Analytics cookies are now opt-in with an in-app consent banner, aligned with GDPR expectations." + }, + { + "title": "Dependency upgrades", + "description": "Broad dependency refresh across the monorepo and project cleanup." + }, + { + "title": "Desktop and extension rebuilds", + "description": "Desktop 3.4.0 and Web Extension 2.5.0 were published alongside this web release to pick up the dependency upgrades.", + "platforms": [ + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v8.5.0", + "title": "8.5.0 - Rebuilt binary attachment downloads", + "date": "2025-11-01", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "8.5.0" + }, + "summary": "Binary attachment downloads are rebuilt with server-side streaming, desktop-native progress, and automatic field re-querying so you do not have to think about which fields to include.", + "highlights": [ + { + "title": "Server-side streaming for attachment downloads", + "description": "Zip creation moved off the browser service worker onto the server with back-pressure and timeout handling, eliminating the refresh-to-fix-it problem.", + "docLink": "/query/query-results" + }, + { + "title": "Desktop background job with live progress", + "description": "On desktop, attachment downloads run as a background job on the main process and save directly to disk with progress notifications.", + "platforms": [ + "desktop" + ] + }, + { + "title": "StaticResource download support", + "description": "StaticResource is now a supported export type alongside Attachment, ContentVersion, and Document." + }, + { + "title": "No more required-field guesswork", + "description": "Jetstream re-queries records for the fields it needs, so you can pick any query and still export binary files cleanly." + } + ] + }, + { + "slug": "v8.4.0", + "title": "8.4.0 - View Record checkbox fix, smoother desktop auto-update", + "date": "2025-10-28", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "8.4.0", + "desktop": "3.3.0" + }, + "summary": "Fixes checkboxes rendering blank in View Record, improves the desktop auto-update UX, and lets you pick filename formats for zip attachment exports.", + "highlights": [ + { + "title": "Checkbox fields render correctly in View Record", + "description": "Read-only checkbox fields no longer appear blank when viewing a record." + }, + { + "title": "Quieter desktop auto-updates", + "description": "Update status lives in a navbar popover instead of an intrusive dialog that could pop up multiple times.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Duplicate filenames in zip exports", + "description": "When downloading binary attachments, you can now choose the filename format to use instead of hitting duplicate-name collisions.", + "docLink": "/query/query-results" + }, + { + "title": "No stray navbar icons without an org", + "description": "Record and user search popovers are hidden until a valid org is selected, avoiding confusing empty states." + }, + { + "title": "Desktop login works for team accounts", + "description": "Entitlement checks now respect team entitlements and reject logins for users no longer active in a team.", + "platforms": [ + "desktop" + ] + } + ] + }, + { + "slug": "v8.3.0", + "title": "8.3.0 - Better related-object loading and assorted bug fixes", + "date": "2025-10-21", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "8.3.0", + "desktop": "3.1.0" + }, + "summary": "Load Records now shows every related object on polymorphic lookups and fetches related-field metadata on demand. Also fixes Firefox drag in the query builder and a create-organization regression.", + "highlights": [ + { + "title": "All related objects on polymorphic lookups", + "description": "Field mapping on Load Records now shows every related object for polymorphic relationships instead of capping the list at five.", + "docLink": "/load/load" + }, + { + "title": "On-demand related-field metadata", + "description": "Related-object fields are now fetched only when the object is selected in mapping, with a manual retry when a fetch fails.", + "docLink": "/load/load" + }, + { + "title": "Firefox query builder drag", + "description": "Condition rows in the query builder can be dragged on Firefox again after swapping the drag handle from a button to a span.", + "docLink": "/query/query-results" + }, + { + "title": "Create organization from selected org", + "description": "Creating a new organization no longer silently reuses the currently selected organization state, which could block the create flow." + } + ] + }, + { + "slug": "v8.2.0", + "title": "8.2.0 - Bug bash fixes across load, deploy, and automation control", + "date": "2025-10-14", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "extension" + ], + "versions": { + "web": "8.2.0", + "extension": "2.4.0" + }, + "summary": "Collection of fixes from a bug bash, including deploy-metadata token refresh, a safer default for rollbackOnError in production, and a fix for Automation Control select-all on filtered rows.", + "highlights": [ + { + "title": "Safer default for production deploys", + "description": "The rollbackOnError option in custom-metadata loads now defaults to true in production orgs, with clearer help text when left off.", + "docLink": "/load/load" + }, + { + "title": "Deploy Metadata token refresh", + "description": "Deploying metadata between orgs now checks each org's session before starting, avoiding a cryptic token-refresh failure mid-deploy.", + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Automation Control select-all respects filters", + "description": "Enabling or disabling automations from the header checkbox now only affects the rows currently visible in the table." + }, + { + "title": "Create new record from query results", + "description": "Creating a new record from the query results page no longer fails because of an unnecessary recordId requirement.", + "docLink": "/query/query-results" + }, + { + "title": "Change debug log levels", + "description": "Fixed a case where Salesforce's 204 response caused the debug-log update API to fail while trying to parse an empty body." + } + ] + }, + { + "slug": "v8.1.0", + "title": "8.1.0 - Login configuration and email verification fixes", + "date": "2025-10-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.1.0" + }, + "summary": "Fixes login configuration lookup for individual users and repairs the email-link verification flow used during 2FA.", + "highlights": [ + { + "title": "Correct login configuration lookup", + "description": "Individual accounts no longer inherit team login rules because of an argument-shape bug in the configuration lookup." + }, + { + "title": "Verify email via link works again", + "description": "Restores the 2FA email-verification link flow, which was rejecting valid codes due to a mis-wired validator." + } + ] + }, + { + "slug": "v8.0.1", + "title": "8.0.1 - Fix crash for users without entitlements", + "date": "2025-10-08", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "8.0.1" + }, + "summary": "Hotfix for a user profile parsing crash that affected users whose accounts did not yet have an entitlements record after the 8.0.0 upgrade.", + "highlights": [ + { + "title": "Fix profile parsing crash", + "description": "User profiles without an entitlements or preferences object no longer crash the app on load." + } + ] + }, + { + "slug": "v8.0.0", + "title": "8.0.0 - Team plan", + "date": "2025-10-08", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "8.0.0", + "desktop": "3.0.3" + }, + "summary": "Introduces the new Jetstream Team plan with a team dashboard, member management, login configuration, and auth activity, plus route-validation hardening.", + "highlights": [ + { + "title": "Team plan and team dashboard", + "description": "Invite teammates, manage members and roles, configure login rules, and review session and authentication activity from a single dashboard." + }, + { + "title": "Unified billing experience", + "description": "Reworked billing page with clearer plan cards, monthly/annual toggle, and team naming during upgrade." + }, + { + "title": "Salesforce route hardening", + "description": "Added domain validation on org add/login, an HSTS policy, and an extra ownership check so only the signed-in user can access their own orgs.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Desktop update fixes", + "description": "Windows auto-update now uses a more standard electron-builder configuration, and an unused Squirrel startup path was removed.", + "platforms": [ + "desktop" + ] + } + ] + }, + { + "slug": "v7.10.0", + "title": "7.10.0 - Centralized app state and desktop binary upload fix", + "date": "2025-09-27", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.10.0" + }, + "summary": "Centralizes the application state pipeline across web, desktop, and extension, fixes binary uploads on the desktop app, and documents the upcoming outbound IP address ranges.", + "highlights": [ + { + "title": "Centralized application state", + "description": "App state and server URL resolution now run through a single pipeline, so the desktop app no longer falls back to localhost when history sync is enabled.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Binary file uploads on desktop", + "description": "Binary attachment uploads from the desktop app now stream as ArrayBuffers directly to Salesforce without body corruption.", + "platforms": [ + "desktop" + ], + "docLink": "/load/load" + }, + { + "title": "Outbound IP address ranges", + "description": "The getting started docs now include a dedicated page describing the upcoming API outbound IP address ranges.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/getting-started/overview" + } + ] + }, + { + "slug": "v7.9.1", + "title": "7.9.1 - Permission manager column fix and desktop download link", + "date": "2025-09-24", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.9.1" + }, + "summary": "Fixes the View All Records column width in Manage Permissions and corrects the x64 desktop download link.", + "highlights": [ + { + "title": "View All Records column width", + "description": "The View All Records column in the permission manager grid now renders with the correct width.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + }, + { + "title": "Correct x64 desktop download link", + "description": "The desktop download page now points at the right x64 installer asset.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v7.9.0", + "title": "7.9.0 - View All Fields in Manage Permissions", + "date": "2025-09-24", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.9.0" + }, + "summary": "Adds support for the new View All Fields object permission in Manage Permissions and fixes a save bug affecting View All Records.", + "highlights": [ + { + "title": "View All Fields object permission", + "description": "Grant or revoke the new Salesforce View All Fields permission alongside the other object permissions in Manage Permissions.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + }, + { + "title": "Fix View All Records save value", + "description": "Saving permissions no longer writes the dirty-state value to Salesforce for View All Records and View All, so the intended value is persisted.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/permissions/permissions" + } + ] + }, + { + "slug": "v7.8.0", + "title": "7.8.0 - Streaming binary uploads and higher free-plan limit", + "date": "2025-09-20", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.8.0" + }, + "summary": "Rewrites the binary file upload pipeline to stream multipart data end-to-end and raises the free-plan attachment filesize limit.", + "highlights": [ + { + "title": "Streaming multipart binary uploads", + "description": "Binary attachment loads now stream from the browser through the server to Salesforce instead of using base64, so large files upload reliably.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Higher free-plan attachment limit", + "description": "The attachment filesize cap on the free plan was raised, and the load docs were updated accordingly.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Platform events content-type fix", + "description": "Removed an incorrect content-type override that was causing issues when publishing platform events.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v7.7.2", + "title": "7.7.2 - Billing portal CSRF fix", + "date": "2025-09-16", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.7.2" + }, + "summary": "Fixes the billing portal, which was failing CSRF validation after the 7.7.0 security change.", + "highlights": [ + { + "title": "Billing portal CSRF token fix", + "description": "Billing pages submit via POST forms, so the CSRF token is now sent in the form body as well as the header.", + "platforms": [ + "web" + ] + } + ] + }, + { + "slug": "v7.7.1", + "title": "7.7.1 - Salesforce login URL fix", + "date": "2025-09-13", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.7.1" + }, + "summary": "Fixes invalid URLs generated when logging in to Salesforce from Jetstream links, and tightens attachment download host handling.", + "highlights": [ + { + "title": "Login with Salesforce URL fix", + "description": "Links that log you into Salesforce now build URLs properly instead of concatenating strings, avoiding double-slash and other malformed links.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Attachment download host handling", + "description": "The attachment download flow now uses proper URL parsing and validates the expected host.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v7.7.0", + "title": "7.7.0 - CSRF protection and UI polish", + "date": "2025-09-11", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.7.0" + }, + "summary": "Adds CSRF double-submit token protection to API requests, cleans up the field mapping dropdown, and fixes several small UI issues.", + "highlights": [ + { + "title": "CSRF double-submit token protection", + "description": "API requests now carry a CSRF token validated against a signed cookie, protecting against cross-site request forgery.", + "platforms": [ + "web" + ] + }, + { + "title": "Cleaner field mapping dropdown", + "description": "The load records field mapping dropdown now shows the field type as tertiary text, matching the rest of the app.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Combobox sizing fix", + "description": "The virtualized combobox no longer miscalculates its size in certain layouts.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "XML sanitizer and extension domain detection", + "description": "The XML sanitizer was fixed and the Chrome extension now detects Salesforce domains more reliably.", + "platforms": [ + "web", + "extension" + ] + }, + { + "title": "Error popover styling", + "description": "The error popover nubbin color now matches the popover background.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v7.6.3", + "title": "7.6.3 - Binary file load fixes", + "date": "2025-09-07", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.6.3", + "desktop": "1.3.1" + }, + "summary": "Fixes a file picker conflict on the binary attachment loader and adds better logging when attachment processing fails.", + "highlights": [ + { + "title": "Binary attachment file picker fix", + "description": "Clicking the \"Zip with attachments\" input no longer accidentally triggers the main CSV file input.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Better logging for attachment failures", + "description": "The loader now logs more context when processing a binary attachment fails, making issues easier to diagnose.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v7.6.2", + "title": "7.6.2 - Bigger attachment uploads and desktop download fix", + "date": "2025-09-05", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "7.6.2", + "desktop": "1.3.0", + "extension": "2.3.0" + }, + "summary": "Raises the binary attachment upload limit, fixes attachment downloads in the desktop app, and ships a matching web extension release.", + "highlights": [ + { + "title": "Larger binary attachment uploads", + "description": "Paid users can upload up to 1 GB of attachments, and the desktop app and browser extension have no upload limit.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Attachment downloads fixed on desktop", + "description": "Zip downloads of query result attachments now work in the desktop app via a custom protocol handler.", + "platforms": [ + "desktop" + ] + }, + { + "title": "Safer zip attachment fetches", + "description": "The download service worker now validates fetch URLs before requesting zip attachments.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v7.6.1", + "title": "7.6.1 - Geo IP routing fix", + "date": "2025-09-03", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.6.1" + }, + "summary": "Fixes a routing regression in the geo IP service after the Express 5 upgrade, plus docs and build script cleanup.", + "highlights": [ + { + "title": "Geo IP service routing fix", + "description": "Corrected the router configuration for Express 5 so geo IP lookups resolve correctly again.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Desktop download link fix in docs", + "description": "The Windows desktop download link in the connected app docs now points at the correct location." + } + ] + }, + { + "slug": "v7.6.0", + "title": "7.6.0 - Record modal anywhere, changeset options, Google Sheet refresh", + "date": "2025-08-30", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop", + "extension" + ], + "versions": { + "web": "7.6.0", + "desktop": "1.2.0", + "extension": "2.2.0" + }, + "summary": "View, edit, and clone any record from anywhere in the app, refresh Google Sheet data on the load page, and control rollback behavior when adding metadata to a changeset.", + "highlights": [ + { + "title": "View/Edit/Clone record modal, app-wide", + "description": "The record modal is now managed at the app level, so viewing or editing a record works consistently from any screen and updates your recent records list automatically.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Refresh Google Sheet data on Load Records", + "description": "Re-pull data from your selected Google Sheet even after navigating forward and backward through the load steps.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/load/load" + }, + { + "title": "Changeset upload options", + "description": "When adding metadata to an outbound changeset, you can now adjust deploy options and Jetstream defaults to \"rollback on failure\" for production orgs.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Date picker closes on outside click", + "description": "The date picker now dismisses correctly when you click outside of it in most contexts.", + "platforms": [ + "web", + "desktop", + "extension" + ] + }, + { + "title": "Recent records stays in sync", + "description": "Opening a record from anywhere in the app now updates the recent records list, so it is easier to jump back to what you were just working on.", + "platforms": [ + "web", + "desktop", + "extension" + ] + } + ] + }, + { + "slug": "v7.5.0", + "title": "7.5.0 - Accurate record count preview for queries", + "date": "2025-08-30", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.5.0" + }, + "summary": "The record count preview shown before running a query no longer fails when the query includes an ORDER BY clause.", + "highlights": [ + { + "title": "Query record count preview works with ORDER BY", + "description": "The count preview now strips the incompatible ORDER BY before running, so you get an accurate record total every time.", + "platforms": [ + "web", + "desktop", + "extension" + ], + "docLink": "/query/query-results" + } + ] + }, + { + "slug": "v7.4.0", + "title": "7.4.0 - Per-org encryption and Windows desktop login", + "date": "2025-08-26", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "7.4.0" + }, + "summary": "Org credentials are now encrypted with a unique key per record, and deep-link login is fixed in Windows desktop development builds.", + "highlights": [ + { + "title": "Per-org encryption keys", + "description": "Each stored Salesforce org now uses a unique encryption key instead of a single global key, reducing blast radius if a key is ever exposed.", + "platforms": [ + "web", + "desktop" + ] + }, + { + "title": "Windows desktop login fix", + "description": "Deep links now open correctly in Windows desktop development builds, so OAuth login completes as expected.", + "platforms": [ + "desktop" + ] + } + ] + }, + { + "slug": "v7.3.5", + "title": "7.3.5 - Diff editor collapses unchanged regions after swap", + "date": "2025-08-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.3.5" + }, + "summary": "Fixes the view/compare metadata diff editor so collapsed unchanged regions stay collapsed after swapping the two sides.", + "highlights": [ + { + "title": "Diff editor swap fix", + "description": "Swapping sides in the view/compare metadata diff now re-renders the editor so unchanged regions collapse as expected.", + "docLink": "/deploy/deploy-metadata" + } + ] + }, + { + "slug": "v7.3.4", + "title": "7.3.4 - One-click field change in query filters", + "date": "2025-08-23", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.3.4" + }, + "summary": "Removes the extra clear step when changing the field in a query filter condition.", + "highlights": [ + { + "title": "Faster field swap in query filters", + "description": "The \"x\" button on a selected filter field is gone, so you can pick a different field in one click instead of two.", + "docLink": "/query/query-results" + } + ] + }, + { + "slug": "v7.3.3", + "title": "7.3.3 - Connected app guidance and annual pricing fix", + "date": "2025-08-21", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.3.3" + }, + "summary": "Adds an in-app banner about upcoming Salesforce Connected App changes, updates the related docs, and fixes annual pricing display for existing subscribers.", + "highlights": [ + { + "title": "Upcoming Salesforce Connected App notice", + "description": "The home screen now shows a banner linking to guidance for preparing for Salesforce's upcoming Connected App changes.", + "docLink": "/getting-started/troubleshooting" + }, + { + "title": "Annual subscription pricing fix", + "description": "Existing annual subscribers now see the correct price on the billing page." + }, + { + "title": "Docs refresh", + "description": "Overview, security, and troubleshooting docs have been updated with current Connected App install steps." + } + ] + }, + { + "slug": "v7.3.2", + "title": "7.3.2 - Fix view-results modal for bulk edits from query", + "date": "2025-08-14", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.3.2" + }, + "summary": "Fixes a bug where viewing bulk results after bulk editing records from query results did nothing.", + "highlights": [ + { + "title": "View bulk results works again", + "description": "Bulk editing from query results and then clicking \"view results\" now opens the results modal instead of silently doing nothing.", + "docLink": "/query/query-results" + } + ] + }, + { + "slug": "v7.3.1", + "title": "7.3.1 - Login session hardening", + "date": "2025-08-11", + "authors": [ + "jetstream" + ], + "tags": [ + "web" + ], + "versions": { + "web": "7.3.1" + }, + "summary": "Patch release that regenerates the session on login and cleans up server logs that could include sensitive values.", + "highlights": [ + { + "title": "Session regenerated on login", + "description": "The login flow now always returns a fresh session so cached state from the pre-login request cannot carry over." + }, + { + "title": "Cleaner server logs", + "description": "Removed log statements that could include sensitive header or identity values." + } + ] + }, + { + "slug": "v7.3.0", + "title": "7.3.0 - Windows desktop app and in-app desktop/extension promotion", + "date": "2025-08-11", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "desktop" + ], + "versions": { + "web": "7.3.0", + "desktop": "1.1.0" + }, + "summary": "The desktop app now installs and auto-updates on Windows (code-signed), and the web app surfaces links to the desktop and browser extension builds from the home screen.", + "highlights": [ + { + "title": "Windows desktop app", + "description": "Desktop 1.1.0 ships a signed Windows installer with proper install, update, and Start Menu shortcut handling.", + "platforms": [ + "desktop" + ], + "docLink": "/getting-started/desktop-app" + }, + { + "title": "Alternative app formats on the home screen", + "description": "The home screen now shows a card pointing entitled users to the desktop app and browser extension.", + "platforms": [ + "web" + ] + }, + { + "title": "Desktop entitlement fix", + "description": "Desktop was missing from entitlement checks, so paid users could be blocked from the desktop build. This is corrected.", + "platforms": [ + "web", + "desktop" + ] + } + ] + }, + { + "slug": "v7.2.0", + "title": "7.2.0 - Copy load results to clipboard", + "date": "2025-08-09", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "extension" + ], + "versions": { + "web": "7.2.0", + "extension": "2.1.0" + }, + "summary": "You can now copy load results directly to the clipboard as Excel, CSV, or JSON without downloading a file first.", + "highlights": [ + { + "title": "Copy load results to clipboard", + "description": "From the load results modal, copy all or selected rows to the clipboard in spreadsheet, CSV, or JSON format.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/load/load" + } + ] + }, + { + "slug": "v7.1.0", + "title": "7.1.0 - Diff editor toggle, folder metadata fixes", + "date": "2025-08-09", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "extension" + ], + "versions": { + "web": "7.1.0", + "extension": "2.0.1" + }, + "summary": "Compare metadata got an option to hide unchanged lines, folder metadata types are now retrieved correctly, and several datatable and popover bugs are fixed.", + "highlights": [ + { + "title": "Toggle unchanged lines in the metadata diff editor", + "description": "When comparing metadata between orgs you can now collapse unchanged lines, which makes larger files much easier to scan.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Folder metadata types work correctly", + "description": "Document, Email, Report, and Dashboard folders now appear in the metadata picker and retrieve the correct metadata from Salesforce.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/deploy/deploy-metadata" + }, + { + "title": "Datatable tab navigation fix", + "description": "Fixed an edge case where tab navigation inside the datatable could misidentify custom cell renderers after minification.", + "platforms": [ + "web", + "extension" + ] + }, + { + "title": "Monaco editor upgrade", + "description": "Upgraded the embedded code editor, which powers the Apex, SOQL, and metadata editors across Jetstream.", + "platforms": [ + "web", + "extension" + ] + } + ] + }, + { + "slug": "v7.0.0", + "title": "7.0.0 - React 19, Jotai state, and better datatable keyboard navigation", + "date": "2025-07-27", + "authors": [ + "jetstream" + ], + "tags": [ + "web", + "extension" + ], + "versions": { + "web": "7.0.0", + "extension": "2.0.0" + }, + "summary": "Major foundation update. Jetstream now runs on React 19 with Jotai for state and Floating UI for popovers, plus meaningful wins for keyboard users in the datatable.", + "highlights": [ + { + "title": "Improved datatable keyboard navigation", + "description": "Tab now cycles through action and record Id cells, Enter opens the record popover, and inline editing matches SLDS styles.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/query/query-results" + }, + { + "title": "Tooltips respond to keyboard focus", + "description": "Focusing a button or icon with the keyboard now shows its tooltip, matching the behavior you get with a mouse hover.", + "platforms": [ + "web", + "extension" + ] + }, + { + "title": "Bulk update from query results fixed", + "description": "The bulk update job from query results no longer fails because of a stale polling callback, so jobs complete and surface their status correctly.", + "platforms": [ + "web", + "extension" + ], + "docLink": "/query/query-results" + }, + { + "title": "Dropdowns close reliably on outside click", + "description": "Clicking outside a dropdown now closes it in the cases where it was previously staying open.", + "platforms": [ + "web", + "extension" + ] + }, + { + "title": "Modernized popovers and tooltips", + "description": "Popovers and tooltips moved to Floating UI, which fixes several nested portal and positioning glitches across modals and popovers.", + "platforms": [ + "web", + "extension" + ] + } + ] + } +] diff --git a/libs/release-notes/src/lib/release-notes.types.ts b/libs/release-notes/src/lib/release-notes.types.ts new file mode 100644 index 000000000..61540a963 --- /dev/null +++ b/libs/release-notes/src/lib/release-notes.types.ts @@ -0,0 +1,58 @@ +import { z } from 'zod'; + +export const releaseTagSchema = z.enum(['web', 'desktop', 'extension', 'all']); +export type ReleaseTag = z.infer; + +export const releasePlatformSchema = z.enum(['web', 'desktop', 'extension']); +export type ReleasePlatform = z.infer; + +export const releaseHighlightSchema = z.object({ + title: z.string().min(1), + description: z.string().optional(), + platforms: z.array(releaseTagSchema).optional(), + docLink: z.string().optional(), +}); +export type ReleaseHighlight = z.infer; + +export const releaseCtaSchema = z.object({ + label: z.string().min(1), + href: z.string().min(1), +}); +export type ReleaseCta = z.infer; + +export const releaseVersionsSchema = z + .object({ + web: z.string().optional(), + desktop: z.string().optional(), + extension: z.string().optional(), + }) + .optional(); +export type ReleaseVersions = z.infer; + +/** + * Shape of the MDX frontmatter authored in apps/docs/release-notes/*.mdx. + * The generator script reads this, validates it, and writes a JSON array of ReleaseNote. + */ +export const releaseNoteFrontmatterSchema = z.object({ + slug: z.string().min(1), + title: z.string().min(1), + date: z.string().min(1), + authors: z.array(z.string()).optional(), + tags: z.array(releaseTagSchema).min(1), + versions: releaseVersionsSchema, + summary: z.string().min(1), + highlights: z.array(releaseHighlightSchema).min(1), + cta: releaseCtaSchema.optional(), +}); +export type ReleaseNoteFrontmatter = z.infer; + +/** + * A single release note, as consumed at runtime by the in-app popover. + * Derived from the MDX frontmatter; `date` is normalized to ISO (YYYY-MM-DD). + */ +export const releaseNoteSchema = releaseNoteFrontmatterSchema.extend({ + date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/), +}); +export type ReleaseNote = z.infer; + +export const releaseNotesArraySchema = z.array(releaseNoteSchema); diff --git a/libs/release-notes/tsconfig.json b/libs/release-notes/tsconfig.json new file mode 100644 index 000000000..0f53ad61f --- /dev/null +++ b/libs/release-notes/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "strictNullChecks": true, + "resolveJsonModule": true, + "types": ["node"] + }, + "include": [], + "files": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/release-notes/tsconfig.lib.json b/libs/release-notes/tsconfig.lib.json new file mode 100644 index 000000000..0237cb0c6 --- /dev/null +++ b/libs/release-notes/tsconfig.lib.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../../dist/out-tsc", + "declaration": true, + "resolveJsonModule": true, + "types": ["node"] + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts" + ], + "include": ["**/*.ts", "**/*.json"] +} diff --git a/libs/release-notes/tsconfig.spec.json b/libs/release-notes/tsconfig.spec.json new file mode 100644 index 000000000..91cffee64 --- /dev/null +++ b/libs/release-notes/tsconfig.spec.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "resolveJsonModule": true, + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] + }, + "include": [ + "vite.config.ts", + "vite.config.mts", + "vitest.config.ts", + "vitest.config.mts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/libs/release-notes/vite.config.ts b/libs/release-notes/vite.config.ts new file mode 100644 index 000000000..81e8fbe01 --- /dev/null +++ b/libs/release-notes/vite.config.ts @@ -0,0 +1,22 @@ +/// +import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; +import { defineConfig } from 'vite'; + +export default defineConfig(() => ({ + root: __dirname, + cacheDir: '../../node_modules/.vite/libs/release-notes', + plugins: [nxViteTsPaths()], + test: { + name: 'release-notes', + watch: false, + globals: true, + environment: 'node', + include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + reporters: ['default'], + passWithNoTests: true, + coverage: { + reportsDirectory: '../../coverage/libs/release-notes', + provider: 'v8' as const, + }, + }, +})); diff --git a/libs/shared/ui-core/src/app/HeaderNavbar.tsx b/libs/shared/ui-core/src/app/HeaderNavbar.tsx index de08bd22a..1296a60c6 100644 --- a/libs/shared/ui-core/src/app/HeaderNavbar.tsx +++ b/libs/shared/ui-core/src/app/HeaderNavbar.tsx @@ -1,7 +1,8 @@ import { SerializedStyles } from '@emotion/react'; import { AppAbility } from '@jetstream/acl'; import { APP_ROUTES } from '@jetstream/shared/ui-router'; -import { isCanvasApp } from '@jetstream/shared/ui-utils'; +import { ReleasePlatform } from '@jetstream/release-notes'; +import { isBrowserExtension, isCanvasApp } from '@jetstream/shared/ui-utils'; import { AddOrgHandlerFn, DropDownItem, UserProfileUi } from '@jetstream/types'; import { Header, Icon, Navbar, UpgradeToProButton } from '@jetstream/ui'; import { @@ -28,6 +29,7 @@ import HeaderHelpPopover from './HeaderHelpPopover'; import { HeaderNavbarItems } from './HeaderNavbarItems'; import { HeaderNavbarBillingUserItems } from './HeaderNavbarReadOnlyUserItems'; import HeaderUpdateNotification from './HeaderUpdateNotification'; +import HeaderWhatsNewPopover from './HeaderWhatsNewPopover'; import LogoPro from './jetstream-logo-pro-200w.png'; import Logo from './jetstream-logo-v1-200w.png'; import NotificationsRequestModal from './NotificationsRequestModal'; @@ -167,9 +169,11 @@ export const HeaderNavbar = ({ const showFullscreenLink = isCanvasApp() && !isFullscreen; const instanceUrl = selectedOrg?.instanceUrl; + const releaseNotePlatform: ReleasePlatform = isDesktop ? 'desktop' : isBrowserExtension() ? 'extension' : 'web'; + const rightHandMenuItems = useMemo(() => { if (isReadOnlyUser) { - return []; + return [, ]; } if (isEmbeddedApp || isDesktop) { @@ -196,7 +200,7 @@ export const HeaderNavbar = ({ items.push(); } - items.push(); + items.push(, ); return items; } @@ -206,6 +210,7 @@ export const HeaderNavbar = ({ , , , + , , , ]; @@ -218,12 +223,30 @@ export const HeaderNavbar = ({ , , , + , , ]; } - return [, , , , ]; - }, [isReadOnlyUser, isEmbeddedApp, isDesktop, isBillingEnabled, hasPaidPlan, trackEvent, showFullscreenLink, instanceUrl]); + return [ + , + , + , + , + , + , + ]; + }, [ + isReadOnlyUser, + isEmbeddedApp, + isDesktop, + isBillingEnabled, + hasPaidPlan, + trackEvent, + showFullscreenLink, + instanceUrl, + releaseNotePlatform, + ]); return ( diff --git a/libs/shared/ui-core/src/app/HeaderWhatsNewPopover.tsx b/libs/shared/ui-core/src/app/HeaderWhatsNewPopover.tsx new file mode 100644 index 000000000..b208dd368 --- /dev/null +++ b/libs/shared/ui-core/src/app/HeaderWhatsNewPopover.tsx @@ -0,0 +1,231 @@ +import { css } from '@emotion/react'; +import { getVisibleReleases, ReleaseNote, ReleasePlatform, RELEASE_NOTES } from '@jetstream/release-notes'; +import { setItemInLocalStorage } from '@jetstream/shared/ui-utils'; +import { Icon, Popover, PopoverRef } from '@jetstream/ui'; +import { FunctionComponent, useEffect, useMemo, useRef, useState } from 'react'; + +const LS_WATERMARK_KEY = 'whats_new_last_seen_date'; +const DOCS_RELEASE_NOTES_URL = 'https://docs.getjetstream.app/release-notes'; +const DOCS_BASE_URL = 'https://docs.getjetstream.app'; +const MAX_VISIBLE_RELEASES = 5; + +export interface HeaderWhatsNewPopoverProps { + platform: ReleasePlatform; + /** + * Optional override for testing and for consumers that want to inject a specific release list. + */ + releases?: ReleaseNote[]; +} + +function readWatermark(): string | null { + try { + return localStorage.getItem(LS_WATERMARK_KEY); + } catch { + return null; + } +} + +function writeWatermark(date: string) { + setItemInLocalStorage(LS_WATERMARK_KEY, date); +} + +function formatReleaseDate(isoDate: string): string { + const [year, month, day] = isoDate.split('-').map((segment) => parseInt(segment, 10)); + const date = new Date(Date.UTC(year, (month || 1) - 1, day || 1)); + return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric', timeZone: 'UTC' }); +} + +function resolveDocHref(docLink: string): string { + if (/^https?:\/\//i.test(docLink)) { + return docLink; + } + return `${DOCS_BASE_URL}${docLink.startsWith('/') ? '' : '/'}${docLink}`; +} + +export const HeaderWhatsNewPopover: FunctionComponent = ({ platform, releases }) => { + const popoverRef = useRef(null); + const [watermark, setWatermark] = useState(() => readWatermark()); + + const allVisible = useMemo(() => getVisibleReleases(releases ?? RELEASE_NOTES, platform), [releases, platform]); + const visible = useMemo(() => allVisible.slice(0, MAX_VISIBLE_RELEASES), [allVisible]); + const unseenCount = useMemo( + () => allVisible.filter(({ date }) => !watermark || date > watermark).length, + [allVisible, watermark], + ); + const newestDate = allVisible[0]?.date ?? null; + + useEffect(() => { + const handler = (event: StorageEvent) => { + if (event.key === LS_WATERMARK_KEY) { + setWatermark(event.newValue); + } + }; + window.addEventListener('storage', handler); + return () => window.removeEventListener('storage', handler); + }, []); + + function handleMarkAllRead() { + if (!newestDate) { + return; + } + writeWatermark(newestDate); + setWatermark(newestDate); + popoverRef.current?.close(); + } + + function handleOpenChange(isOpen: boolean) { + if (!isOpen && newestDate && newestDate !== watermark) { + writeWatermark(newestDate); + setWatermark(newestDate); + } + } + + if (visible.length === 0) { + return null; + } + + return ( + +

+ What's new +

+ + } + content={ +
    + {visible.map((release) => { + const isUnseen = !watermark || release.date > watermark; + return ( +
  • +
    +

    + {release.title} +

    + {isUnseen && New} +
    +

    + {formatReleaseDate(release.date)} +

    +

    {release.summary}

    + {release.cta && ( +

    + + {release.cta.label} + + +

    + )} +
      + {release.highlights.map((highlight, index) => ( +
    • + {highlight.title} + {highlight.description && : {highlight.description}} + {highlight.docLink && ( + + Learn more + + + )} +
    • + ))} +
    + + Read full release notes + + +
  • + ); + })} +
+ } + footer={ + + } + buttonProps={{ + className: + 'slds-button slds-button_icon slds-button_icon slds-button_icon-container slds-button_icon-small slds-global-actions__item-action cursor-pointer', + 'aria-label': unseenCount > 0 ? `What's new — ${unseenCount} unread` : "What's new", + }} + > + + + {unseenCount > 0 && ( + +
+ ); +}; + +export default HeaderWhatsNewPopover; diff --git a/libs/shared/ui-core/src/app/__tests__/HeaderWhatsNewPopover.spec.tsx b/libs/shared/ui-core/src/app/__tests__/HeaderWhatsNewPopover.spec.tsx new file mode 100644 index 000000000..7e89756ea --- /dev/null +++ b/libs/shared/ui-core/src/app/__tests__/HeaderWhatsNewPopover.spec.tsx @@ -0,0 +1,59 @@ +import { ReleaseNote } from '@jetstream/release-notes'; +import { render, screen } from '@testing-library/react'; +import { afterEach, describe, expect, it } from 'vitest'; +import { HeaderWhatsNewPopover } from '../HeaderWhatsNewPopover'; + +const LS_KEY = 'whats_new_last_seen_date'; + +const releases: ReleaseNote[] = [ + { + slug: 'v9.14.0', + title: '9.14.0', + date: '2026-04-19', + tags: ['web', 'desktop'], + summary: 'Web + desktop release', + highlights: [{ title: 'Popover' }], + }, + { + slug: 'v2.22.0', + title: 'Extension 2.22.0', + date: '2026-04-10', + tags: ['extension'], + summary: 'Extension-only', + highlights: [{ title: 'Extension fix' }], + }, +]; + +describe('HeaderWhatsNewPopover', () => { + afterEach(() => { + localStorage.clear(); + }); + + it('renders the badge when the watermark is unset', () => { + render(); + expect(screen.getByTestId('whats-new-badge')).toBeTruthy(); + expect(screen.getByRole('button', { name: /unread/i })).toBeTruthy(); + }); + + it('hides the badge when the watermark is at-or-past the newest release', () => { + localStorage.setItem(LS_KEY, '2026-04-19'); + render(); + expect(screen.queryByTestId('whats-new-badge')).toBeNull(); + }); + + it('shows the badge when the watermark is older than the newest release', () => { + localStorage.setItem(LS_KEY, '2026-01-01'); + render(); + expect(screen.getByTestId('whats-new-badge')).toBeTruthy(); + }); + + it('returns null when no releases match the platform', () => { + const { container } = render(); + expect(container.firstChild).toBeNull(); + }); + + it('aria-label reflects unread count', () => { + render(); + expect(screen.getByRole('button', { name: /What's new.*1 unread/i })).toBeTruthy(); + }); +}); diff --git a/libs/shared/ui-core/src/index.ts b/libs/shared/ui-core/src/index.ts index 7ca6f5794..3a1c20485 100644 --- a/libs/shared/ui-core/src/index.ts +++ b/libs/shared/ui-core/src/index.ts @@ -12,6 +12,7 @@ export * from './app/HeaderDonatePopover'; export * from './app/HeaderHelpPopover'; export * from './app/HeaderNavbar'; export * from './app/HeaderUpdateNotification'; +export * from './app/HeaderWhatsNewPopover'; export * from './app/NotificationsRequestModal'; export * from './app/PromptNavigation'; export * from './app/RequireMetadataApiBanner'; diff --git a/package.json b/package.json index b80587035..044676c1b 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,8 @@ "scripts": { "postinstall": "prisma generate", "init:project": "zx ./scripts/init-project.mjs", + "release-notes:generate": "zx ./scripts/generate-release-notes.ts", + "new-release-note": "zx ./scripts/new-release-note.mjs", "nx": "nx", "start": "nx serve", "start:api": "nx serve api", @@ -228,6 +230,7 @@ "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.0.1", "fishery": "^2.4.0", + "gray-matter": "^4.0.3", "husky": "^9.1.7", "jsdom": "^29.0.1", "jsonc-eslint-parser": "^2.1.0", diff --git a/scripts/generate-release-notes.ts b/scripts/generate-release-notes.ts new file mode 100644 index 000000000..ea33edff4 --- /dev/null +++ b/scripts/generate-release-notes.ts @@ -0,0 +1,105 @@ +#!/usr/bin/env zx +/** + * Reads MDX release notes from apps/docs/release-notes/, validates frontmatter + * against the Zod schema in libs/release-notes, and writes a sorted JSON array + * to libs/release-notes/src/lib/release-notes.generated.json. + * + * Run via: yarn release-notes:generate + * or: nx run release-notes:build-data + */ +import matter from 'gray-matter'; +import { chalk, fs, globby, path } from 'zx'; +import { releaseNoteFrontmatterSchema, releaseNotesArraySchema } from '../libs/release-notes/src/lib/release-notes.types.ts'; +import type { ReleaseNote } from '../libs/release-notes/src/lib/release-notes.types.ts'; + +const ROOT = path.resolve(__dirname, '..'); +const SOURCE_DIR = path.join(ROOT, 'apps/docs/release-notes'); +const OUTPUT_FILE = path.join(ROOT, 'libs/release-notes/src/lib/release-notes.generated.json'); + +const files = await globby('*.mdx', { cwd: SOURCE_DIR, absolute: true }); + +if (files.length === 0) { + console.log(chalk.yellow(`No MDX files found in ${path.relative(ROOT, SOURCE_DIR)}; writing empty array.`)); +} + +const errors: Array<{ file: string; issues: Array<{ path?: readonly (string | number)[]; message: string }> }> = []; +const notes: ReleaseNote[] = []; + +for (const file of [...files].sort()) { + const raw = await fs.readFile(file, 'utf8'); + const { data } = matter(raw); + const parsed = releaseNoteFrontmatterSchema.safeParse(data); + if (!parsed.success) { + errors.push({ file: path.relative(ROOT, file), issues: parsed.error.issues }); + continue; + } + const normalizedDate = normalizeDate(parsed.data.date); + if (!normalizedDate) { + errors.push({ + file: path.relative(ROOT, file), + issues: [{ path: ['date'], message: `Invalid date "${String(parsed.data.date)}" — expected YYYY-MM-DD.` }], + }); + continue; + } + notes.push({ ...parsed.data, date: normalizedDate }); +} + +if (errors.length) { + console.error(chalk.red(`\nFailed to parse ${errors.length} release-note file${errors.length > 1 ? 's' : ''}:\n`)); + for (const { file, issues } of errors) { + console.error(chalk.red(` ${file}`)); + for (const issue of issues) { + const loc = (issue.path ?? []).join('.') || '(root)'; + console.error(chalk.red(` • ${loc}: ${issue.message}`)); + } + } + process.exit(1); +} + +notes.sort((noteA, noteB) => { + if (noteA.date !== noteB.date) { + return noteA.date < noteB.date ? 1 : -1; + } + return compareSemver(noteB.slug, noteA.slug); +}); + +const validated = releaseNotesArraySchema.safeParse(notes); +if (!validated.success) { + console.error(chalk.red('Post-normalization validation failed:')); + console.error(validated.error.issues); + process.exit(1); +} + +await fs.ensureDir(path.dirname(OUTPUT_FILE)); +await fs.writeFile(OUTPUT_FILE, JSON.stringify(validated.data, null, 2) + '\n'); + +console.log( + chalk.greenBright(`Wrote ${notes.length} release note${notes.length === 1 ? '' : 's'} → ${path.relative(ROOT, OUTPUT_FILE)}`), +); + +function compareSemver(a: string, b: string): number { + const parse = (slug: string) => + slug + .replace(/^v/, '') + .split('.') + .map((segment) => parseInt(segment, 10) || 0); + const [aMajor, aMinor, aPatch] = parse(a); + const [bMajor, bMinor, bPatch] = parse(b); + if (aMajor !== bMajor) { + return aMajor - bMajor; + } + if (aMinor !== bMinor) { + return aMinor - bMinor; + } + return aPatch - bPatch; +} + +function normalizeDate(value: unknown): string | null { + if (value instanceof Date && !Number.isNaN(value.valueOf())) { + return value.toISOString().slice(0, 10); + } + if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(value)) { + return value; + } + return null; +} diff --git a/scripts/new-release-note.mjs b/scripts/new-release-note.mjs new file mode 100644 index 000000000..015b2daa8 --- /dev/null +++ b/scripts/new-release-note.mjs @@ -0,0 +1,69 @@ +#!/usr/bin/env node +/** + * Scaffold a new release-note MDX file under apps/docs/release-notes/ using + * the current package.json version, today's date, and `git log` subjects since + * the last tag to pre-populate highlights. Hand-edit the result before committing. + * + * Run: yarn new-release-note + */ +import { $, chalk, fs, path } from 'zx'; + +$.verbose = false; + +const ROOT = path.resolve(__dirname, '..'); +const OUTPUT_DIR = path.join(ROOT, 'apps/docs/release-notes'); + +const pkg = JSON.parse(await fs.readFile(path.join(ROOT, 'package.json'), 'utf8')); +const version = pkg.version; +const today = new Date().toISOString().slice(0, 10); +const fileName = `${today}-v${version}.mdx`; +const outputPath = path.join(OUTPUT_DIR, fileName); + +if (await fs.pathExists(outputPath)) { + console.error(chalk.red(`File already exists: ${path.relative(ROOT, outputPath)}`)); + process.exit(1); +} + +let commitLines = []; +try { + const lastTag = (await $`git describe --tags --abbrev=0 --match "v*"`).stdout.trim(); + const log = (await $`git log --pretty=format:%s ${lastTag}..HEAD`).stdout.trim(); + commitLines = log + .split('\n') + .map((line) => line.trim()) + .filter((line) => /^(feat|fix)(\(|:)/i.test(line)); +} catch (error) { + console.log(chalk.yellow('Could not read git log since last tag; leaving highlights blank.')); +} + +const highlightsYaml = commitLines.length + ? commitLines.map((line) => ` - title: ${JSON.stringify(stripConventionalPrefix(line))}`).join('\n') + : ' - title: "TODO — write a user-visible highlight"'; + +const scaffold = `--- +slug: v${version} +title: "${version} — TODO short description" +date: '${today}' +authors: [jetstream] +tags: [web] +versions: + web: ${version} +summary: TODO — one-to-two sentence summary for the in-app popover. +highlights: +${highlightsYaml} +--- + +## What's new + +TODO — full release notes body rendered on the docs site. +`; + +await fs.ensureDir(OUTPUT_DIR); +await fs.writeFile(outputPath, scaffold); + +console.log(chalk.greenBright(`Created ${path.relative(ROOT, outputPath)}`)); +console.log(chalk.cyan('Edit the frontmatter + body, then run: yarn release-notes:generate')); + +function stripConventionalPrefix(line) { + return line.replace(/^(feat|fix|chore|docs|refactor|perf|test|build|ci)(\([^)]+\))?!?:\s*/i, '').trim(); +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 2998600e6..a84de8c78 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -48,6 +48,7 @@ "@jetstream/monaco": ["./libs/monaco-configuration/src/index.ts"], "@jetstream/prisma": ["./libs/prisma/src/index.ts"], "@jetstream/record-form": ["./libs/shared/ui-record-form/src/index.ts"], + "@jetstream/release-notes": ["./libs/release-notes/src/index.ts"], "@jetstream/salesforce-api": ["./libs/salesforce-api/src/index.ts"], "@jetstream/shared/client-logger": ["./libs/shared/client-logger/src/index.ts"], "@jetstream/shared/constants": ["./libs/shared/constants/src/index.ts"], diff --git a/yarn.lock b/yarn.lock index a6f06f9ff..9d73dc0be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16731,6 +16731,13 @@ ext-name@^5.0.0: ext-list "^2.0.0" sort-keys-length "^1.0.0" +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + extract-zip@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" @@ -17915,6 +17922,16 @@ graphmatch@^1.1.0: resolved "https://registry.yarnpkg.com/graphmatch/-/graphmatch-1.1.1.tgz#dcec68e8cb74de0a372d5252fc06e241daf71c38" integrity sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg== +gray-matter@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" + integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== + dependencies: + js-yaml "^3.13.1" + kind-of "^6.0.2" + section-matter "^1.0.0" + strip-bom-string "^1.0.0" + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -18710,6 +18727,11 @@ is-docker@^3.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== +is-extendable@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" @@ -19953,7 +19975,7 @@ kill-port@^1.6.1: get-them-args "1.3.2" shell-exec "1.0.2" -kind-of@^6.0.2: +kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== @@ -24855,6 +24877,14 @@ schema-utils@^4.3.3: ajv-formats "^2.1.1" ajv-keywords "^5.1.0" +section-matter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" + integrity sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA== + dependencies: + extend-shallow "^2.0.1" + kind-of "^6.0.0" + secure-compare@3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz" @@ -26002,6 +26032,11 @@ strip-bom-stream@4.0.0: first-chunk-stream "^3.0.0" strip-bom-buf "^2.0.0" +strip-bom-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" + integrity sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g== + strip-bom@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-5.0.0.tgz#88d2e135d154dca7a5e06b4a4ba9653b6bdc0dd2"