Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .github/workflows/review-desktop-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -397,17 +397,17 @@ jobs:
run: |
DIST=apps/review-desktop/dist
RELEASE_PREFIX="s3://${R2_BUCKET}/releases/${RELEASE_VERSION}/darwin-arm64"
DMG_DISPOSITION="attachment; filename=\"df-review-preview-${RELEASE_VERSION}.dmg\""
DMG_DISPOSITION="attachment; filename=\"df-whiteboard-preview-${RELEASE_VERSION}.dmg\""

aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.zip" \
"${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.zip" \
aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \
"${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \
--content-type application/zip
aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \
"${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \
aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \
"${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \
--content-type application/x-apple-diskimage \
--content-disposition "$DMG_DISPOSITION"
aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \
"s3://${R2_BUCKET}/releases/preview-latest/darwin-arm64/Review.dmg" \
aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \
"s3://${R2_BUCKET}/releases/preview-latest/darwin-arm64/Whiteboard.dmg" \
--content-type application/x-apple-diskimage \
--content-disposition "$DMG_DISPOSITION"

Expand Down Expand Up @@ -435,7 +435,7 @@ jobs:
echo "install.dev.fast/preview (expect 302 to the preview disk image):"
LOCATION=$(curl -s -o /dev/null -w "%{redirect_url}" https://install.dev.fast/preview)
echo "$LOCATION"
test "$LOCATION" = "https://install.dev.fast/releases/preview-latest/darwin-arm64/Review.dmg"
test "$LOCATION" = "https://install.dev.fast/releases/preview-latest/darwin-arm64/Whiteboard.dmg"

echo "Following it (expect 200 and a disk image):"
curl -sfL -o /dev/null -w "%{http_code} %{content_type}\n" https://install.dev.fast/preview \
Expand All @@ -445,7 +445,7 @@ jobs:
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: review-desktop-preview-${{ env.RELEASE_VERSION }}-dmg
path: apps/review-desktop/dist/Review-darwin-arm64-${{ env.RELEASE_VERSION }}.dmg
path: apps/review-desktop/dist/Whiteboard-darwin-arm64-${{ env.RELEASE_VERSION }}.dmg
retention-days: 3
compression-level: 0

Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/review-desktop-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -572,17 +572,17 @@ jobs:
RELEASE_PREFIX="s3://${R2_BUCKET}/releases/${RELEASE_VERSION}/darwin-arm64"
# The releases/latest/ key is version-free by design, so the version
# rides along in the filename a client saves the download as.
DMG_DISPOSITION="attachment; filename=\"df-review-${RELEASE_VERSION}.dmg\""
DMG_DISPOSITION="attachment; filename=\"df-whiteboard-${RELEASE_VERSION}.dmg\""

aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.zip" \
"${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.zip" \
aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \
"${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.zip" \
--content-type application/zip
aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \
"${RELEASE_PREFIX}/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \
aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \
"${RELEASE_PREFIX}/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \
--content-type application/x-apple-diskimage \
--content-disposition "$DMG_DISPOSITION"
aws s3 cp "$DIST/Review-darwin-arm64-${RELEASE_VERSION}.dmg" \
"s3://${R2_BUCKET}/releases/latest/darwin-arm64/Review.dmg" \
aws s3 cp "$DIST/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg" \
"s3://${R2_BUCKET}/releases/latest/darwin-arm64/Whiteboard.dmg" \
--content-type application/x-apple-diskimage \
--content-disposition "$DMG_DISPOSITION"

Expand Down Expand Up @@ -610,7 +610,7 @@ jobs:
echo "install.dev.fast (expect 302 to the disk image):"
LOCATION=$(curl -s -o /dev/null -w "%{redirect_url}" https://install.dev.fast/)
echo "$LOCATION"
test "$LOCATION" = "https://install.dev.fast/releases/latest/darwin-arm64/Review.dmg"
test "$LOCATION" = "https://install.dev.fast/releases/latest/darwin-arm64/Whiteboard.dmg"

echo "Following it (expect 200 and a disk image):"
curl -sfL -o /dev/null -w "%{http_code} %{content_type}\n" https://install.dev.fast/ \
Expand All @@ -623,7 +623,7 @@ jobs:
run: |
gh release upload "$RELEASE_TAG" \
--repo "${{ github.repository }}" \
"apps/review-desktop/dist/Review-darwin-arm64-${RELEASE_VERSION}.dmg"
"apps/review-desktop/dist/Whiteboard-darwin-arm64-${RELEASE_VERSION}.dmg"

- name: Remove signing credentials
if: always()
Expand Down
29 changes: 16 additions & 13 deletions apps/review-desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ packaging script but no distribution. Signed builds auto-update from
SKIP_NOTARIZE=1 pnpm --filter @dev.fast/review-desktop app:package:macos
```

builds an unsigned `VSCode-darwin-arm64/Review.app` and skips
builds an unsigned `VSCode-darwin-arm64/Whiteboard.app` and skips
signing, notarization, and artifact creation. A full run needs the signing
environment and produces `dist/Review-darwin-arm64-<version>.zip` (the
environment and produces `dist/Whiteboard-darwin-arm64-<version>.zip` (the
Squirrel update payload) and the matching `.dmg`, both notarized and stapled:

- `CODESIGN_IDENTITY` — the Developer ID Application identity string.
Expand Down Expand Up @@ -211,14 +211,16 @@ publishing an older commit intentionally rolls preview installations back to
that build.

Install the latest preview from <https://install.dev.fast/preview>. It installs
as `Review Preview.app`, displays as `/dev/fast Review Preview`, and uses an
as `Whiteboard Preview.app`, displays as `/dev/fast Whiteboard Preview`, and uses an
orange app-icon background so it stays visually distinct from stable in Finder,
the Dock, and the app switcher.

Preview uses its own bundle identifier, URL scheme, CLI name, and data folders,
so it can run beside stable without replacing the stable app or sharing its
settings. Preview updates continue to use the preview feed. To return to stable,
open the existing `Review.app` or install it from <https://install.dev.fast>.
open the existing `Whiteboard.app` or install it from <https://install.dev.fast>.
Auto-updated Review installs keep the `Review.app` file name; reinstall from
the disk image to get `Whiteboard.app`.

Builds from before the preview identity split installed as `Review.app`.
Reinstall once from <https://install.dev.fast/preview> after the split so the
Expand Down Expand Up @@ -268,26 +270,27 @@ host discrimination; the two names exist to give humans and Squirrel separate
front doors.

`GET /` is the stable install landing: it redirects to the
`releases/latest/darwin-arm64/Review.dmg` alias, while `GET /preview` redirects
to `releases/preview-latest/darwin-arm64/Review.dmg`. For example,
`releases/latest/darwin-arm64/Whiteboard.dmg` alias, while `GET /preview` redirects
to `releases/preview-latest/darwin-arm64/Whiteboard.dmg`. For example,
`curl -fLOJ https://install.dev.fast` downloads the current disk image. It
deliberately does not read `latest.json` — the alias is uploaded with the
payloads, so the download keeps working while the manifest is mid-upload. The
keys stay version-free for that reason, so the version rides on each object's
`Content-Disposition` instead and the saved file names itself. Stable uses
`df-review-<version>.dmg`; preview uses
`df-review-preview-<preview-version>.dmg`. curl only honours that with `-J`; a
`df-whiteboard-<version>.dmg`; preview uses
`df-whiteboard-preview-<preview-version>.dmg`. curl only honours that with `-J`; a
browser download always does.

```
update/stable/darwin-arm64/latest.json current-release manifest
update/preview/darwin-arm64/latest.json current-preview manifest
releases/<version>/darwin-arm64/ Review-darwin-arm64-<version>.zip + .dmg
releases/latest/darwin-arm64/Review.dmg direct-download alias, saved as
df-review-<version>.dmg
releases/preview-latest/darwin-arm64/Review.dmg
releases/<version>/darwin-arm64/ Whiteboard-darwin-arm64-<version>.zip + .dmg
releases/latest/darwin-arm64/Whiteboard.dmg
direct-download alias, saved as
df-whiteboard-<version>.dmg
releases/preview-latest/darwin-arm64/Whiteboard.dmg
preview-download alias, saved as
df-review-preview-<preview-version>.dmg
df-whiteboard-preview-<preview-version>.dmg
```

`GET /api/update/:platform/:quality/:commit` answers 204 when the caller's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async function installedDesktopPids(home) {
// LaunchServices can pick a bundle anywhere, so this only has to find a Review bundle; the two filters below narrow it.
const stdout = await listing(
"/usr/bin/pgrep",
["-f", "Review.app/Contents"],
["-f", "(Review|Whiteboard)\\.app/Contents"],
"no process matches",
);

Expand Down
4 changes: 2 additions & 2 deletions apps/review-desktop/scripts/linux-package.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test("stable versions package as dev-fast-review", () => {
assert.deepEqual(reviewPackage(product("stable"), "1.2.3", "2"), {
name: "dev-fast-review",
app: "review",
appName: "Review",
appName: "Whiteboard",
appId: "dev.fast.review",
rpmVersion: "1.2.3",
revision: "2",
Expand All @@ -24,7 +24,7 @@ test("preview versions package separately with a tilde RPM version", () => {
{
name: "dev-fast-review-preview",
app: "review-preview",
appName: "Review Preview",
appName: "Whiteboard Preview",
appId: "dev.fast.review.preview",
rpmVersion: "1.2.4~preview.20260922.7",
revision: "1",
Expand Down
4 changes: 2 additions & 2 deletions apps/review-desktop/scripts/notarize-macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ PRODUCT_NAME="$(node -p "require('$CHECKOUT/product.json').nameShort")"
PACKAGED_APP="$APP_DIR/VSCode-darwin-arm64/$PRODUCT_NAME.app"
VERSION="$(node -p "require('$APP_DIR/package.json').version")"
ARTIFACT_DIR="${DEV_FAST_REVIEW_ARTIFACT_DIR:-$APP_DIR/dist}"
UPDATE_ZIP="$ARTIFACT_DIR/Review-darwin-arm64-$VERSION.zip"
DMG="$ARTIFACT_DIR/Review-darwin-arm64-$VERSION.dmg"
UPDATE_ZIP="$ARTIFACT_DIR/Whiteboard-darwin-arm64-$VERSION.zip"
DMG="$ARTIFACT_DIR/Whiteboard-darwin-arm64-$VERSION.dmg"

if (( $# > 0 )); then
echo "usage: $0" >&2
Expand Down
8 changes: 4 additions & 4 deletions apps/review-desktop/scripts/release-channel.mjs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const RELEASE_IDENTITIES = Object.freeze({
stable: Object.freeze({
nameShort: "Review",
nameLong: "/dev/fast Review",
nameShort: "Whiteboard",
nameLong: "/dev/fast Whiteboard",
applicationName: "review",
dataFolderName: ".dev-fast-review",
sharedDataFolderName: ".dev-fast-review-shared",
darwinBundleIdentifier: "dev.fast.review",
urlProtocol: "dev-fast-review",
}),
preview: Object.freeze({
nameShort: "Review Preview",
nameLong: "/dev/fast Review Preview",
nameShort: "Whiteboard Preview",
nameLong: "/dev/fast Whiteboard Preview",
applicationName: "review-preview",
dataFolderName: ".dev-fast-review-preview",
sharedDataFolderName: ".dev-fast-review-preview-shared",
Expand Down
6 changes: 3 additions & 3 deletions apps/review-desktop/scripts/validate-release-artifacts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function buildManifest({
return {
version,
commit,
url: `${UPDATE_URL}/releases/${version}/darwin-arm64/Review-darwin-arm64-${version}.zip`,
url: `${UPDATE_URL}/releases/${version}/darwin-arm64/Whiteboard-darwin-arm64-${version}.zip`,
name: version,
pub_date: now.toISOString(),
timestamp: now.getTime(),
Expand Down Expand Up @@ -136,8 +136,8 @@ async function main() {
`${sourceProduct.nameShort}.app`,
);

const zip = path.join(artifactDir, `Review-darwin-arm64-${version}.zip`);
const dmg = path.join(artifactDir, `Review-darwin-arm64-${version}.dmg`);
const zip = path.join(artifactDir, `Whiteboard-darwin-arm64-${version}.zip`);
const dmg = path.join(artifactDir, `Whiteboard-darwin-arm64-${version}.dmg`);

await assertPackagedArtifacts(app);
assertUpdaterCompatibleApp(app);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test("buildManifest emits the schema the update Worker serves", () => {
assert.deepEqual(manifest, {
version: "1.2.3",
commit: "abc123",
url: "https://update.dev.fast/releases/1.2.3/darwin-arm64/Review-darwin-arm64-1.2.3.zip",
url: "https://update.dev.fast/releases/1.2.3/darwin-arm64/Whiteboard-darwin-arm64-1.2.3.zip",
name: "1.2.3",
pub_date: "2026-07-29T00:00:00.000Z",
timestamp: now.getTime(),
Expand Down
2 changes: 1 addition & 1 deletion packages/review/src/cli-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ export async function runReviewCli(input: ReviewCliInput): Promise<number> {
)
.option("--review <id>", "Review ID")
.option("--version <number>", "Saved version to share")
.option("--preview", "Open the share link in Review Preview by default")
.option("--preview", "Open the share link in Whiteboard Preview by default")
.option(
"--request-id <uuid>",
"Reuse this ID when retrying the same immutable upload",
Expand Down
5 changes: 3 additions & 2 deletions scripts/review-latency/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ uv run review-latency render ~/.dev/review-latency/runs/<run-dir> # re-render
uv run review-latency dashboards # compare.html + flamegraph.html over all runs
```

Requirements: the packaged Review app installed at `/Applications/dev.fast
Review.app` (each run launches its own isolated instance), `claude` on PATH,
Requirements: the packaged Whiteboard app installed at
`/Applications/Whiteboard.app` (each run launches its own isolated instance),
`claude` on PATH,
`tsx` on PATH (for `review_cli = "source"`), and the dev-review skill installed
for Claude Code.

Expand Down
2 changes: 1 addition & 1 deletion scripts/review-latency/review_latency/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def desktop_request(method: str, route: str, home: Path) -> dict | None:
# Each run gets its own review app: DEV_REVIEW_HOME (reviews store + desktop
# discovery) under the run dir, and the desktop's Electron state under a short
# /tmp path — the user-data dir carries a unix socket capped at 103 chars.
PACKAGED_DESKTOP = Path("/Applications/dev.fast Review.app/Contents/MacOS/Review")
PACKAGED_DESKTOP = Path("/Applications/Whiteboard.app/Contents/MacOS/Whiteboard")
# Development desktop from this checkout: the Code OSS shell built by
# `pnpm --filter @dev-fast/review-desktop app:build`, serving this checkout's
# review server, so desktop-side instrumentation is measurable. run.sh honors
Expand Down
Loading