diff --git a/packages/desktop/electron.vite.config.ts b/packages/desktop/electron.vite.config.ts
index 619bac64d73..d80d820d144 100644
--- a/packages/desktop/electron.vite.config.ts
+++ b/packages/desktop/electron.vite.config.ts
@@ -55,9 +55,14 @@ export default defineConfig(async ({ command }) => {
const channel = resolveChannel()
const nodePtyPkg = nodePtyPackage()
- // Beta builds carry their commit and recent history for the updater's "What's new in beta"; other channels none.
+ // Beta builds carry their commit and recent history for the updater's "What's new in beta"; the dev server carries
+ // them without asking GitHub, so the page and command can be tried; other channels none.
const betaNotes =
- channel === "beta" ? await BetaNotes.enrich(BetaNotes.embed(), { token: process.env.GITHUB_TOKEN }) : undefined
+ channel === "beta"
+ ? await BetaNotes.enrich(BetaNotes.embed(), { token: process.env.GITHUB_TOKEN })
+ : command === "serve"
+ ? BetaNotes.embed()
+ : undefined
return {
main: {
diff --git a/packages/gui-extensions/src/updater/beta-dialog.stories.tsx b/packages/gui-extensions/src/updater/beta-dialog.stories.tsx
index 2260a8bb5dc..24ef2577731 100644
--- a/packages/gui-extensions/src/updater/beta-dialog.stories.tsx
+++ b/packages/gui-extensions/src/updater/beta-dialog.stories.tsx
@@ -1,8 +1,10 @@
import { Button } from "@opencode/ui/button"
import { useDialog } from "@opencode/ui/context/dialog"
import { Option } from "effect"
-import { onMount } from "solid-js"
+import { createSignal, onMount, Show } from "solid-js"
+import { SettingsPanel } from "../../../stories/mocks/gui-extensions/settings-page"
import { DialogBetaNotes } from "./beta-dialog"
+import { BetaNotesView } from "./beta-page"
import { sliceBetaNotes, type EmbeddedNotes } from "./beta-notes"
type Author = { name: string; login?: string; avatar?: string }
@@ -128,8 +130,10 @@ const embedded = (picked: typeof commits): EmbeddedNotes => ({
const offline = (picked: typeof commits): typeof commits =>
picked.map(([type, summary, pr, author]) => [type, summary, pr, { name: author.name }])
+// View all opens the What's new page in place of the story, as the app opens it in Settings.
function Fixture(props: { picked: typeof commits; previous?: string; previousCommit?: string }) {
const dialog = useDialog()
+ const [page, setPage] = createSignal(false)
const notes = Option.getOrThrow(sliceBetaNotes(embedded(props.picked), props.previousCommit ?? sha(999)))
const open = () =>
@@ -139,12 +143,22 @@ function Fixture(props: { picked: typeof commits; previous?: string; previousCom
previous={props.previous ?? "0.0.0-beta-21180"}
dialog={{ close: () => dialog.close() }}
open={(href) => window.open(href, "_blank")}
+ viewAll={() => {
+ dialog.close()
+ setPage(true)
+ }}
/>
))
onMount(open)
- return
+ return (
+ Open What's new in beta}>
+
+ window.open(href, "_blank")} />
+
+
+ )
}
export default {
@@ -163,7 +177,7 @@ export default {
/** A typical update: a few features and fixes. */
export const Typical = { render: () => }
-/** More than ten changes: the rest are linked on GitHub. */
+/** More than ten changes: View all opens the What's new page. */
export const Many = {
render: () => ,
}
@@ -176,7 +190,16 @@ export const FixesOnly = {
render: () => type === "fix").slice(0, 4)} />,
}
-/** The previous build is older than the embedded history: the newest changes stand in, and the rest are linked. */
+/** The previous build is older than the embedded history: the newest changes stand in, and View all shows the rest. */
export const PreviousBuildUnknown = {
render: () => ,
}
+
+/** Settings > What's new in beta: every change the build carries, from ⌘K, Settings or the dialog's View all. */
+export const Page = {
+ render: () => (
+
+ window.open(href, "_blank")} />
+
+ ),
+}
diff --git a/packages/gui-extensions/src/updater/beta-dialog.tsx b/packages/gui-extensions/src/updater/beta-dialog.tsx
index 7155f4714e3..87a51fe29f6 100644
--- a/packages/gui-extensions/src/updater/beta-dialog.tsx
+++ b/packages/gui-extensions/src/updater/beta-dialog.tsx
@@ -1,4 +1,4 @@
-import { createSignal, For, onMount, Show } from "solid-js"
+import { createSignal, For, onCleanup, onMount, Show } from "solid-js"
import { createResizeObserver } from "@solid-primitives/resize-observer"
import { Option } from "effect"
import { Button } from "@opencode/ui/button"
@@ -38,18 +38,23 @@ export function showBetaNotes(
previous={input.previous}
dialog={dialog}
open={(href) => ctx.system.openExternal(href)}
+ viewAll={() => {
+ dialog.close()
+ ctx.layout.settings("whats-new")
+ }}
/>
),
{ replace: true },
)
}
-/** What's new in beta: the listed features and fixes, and a link to the whole range when some are not listed. */
+/** What's new in beta: the listed features and fixes, and the What's new page when some are not listed. */
export function DialogBetaNotes(props: {
notes: BetaNotes
previous: string
dialog: DialogHandle
open: (href: string) => void
+ viewAll: () => void
}) {
const ctx = useExtension()
const [fade, setFade] = createSignal({ top: 0, bottom: 0 })
@@ -93,11 +98,9 @@ export function DialogBetaNotes(props: {
- {(href) => (
-
- )}
+