Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
8e0896c
feat(updater): show installed release notes once and in Settings
WilliamWang1721 Sep 30, 2026
8baa1e4
Merge latest upstream main into update release notes
WilliamWang1721 Oct 1, 2026
12eabe8
fix(updater): defer installed notes until a visible workspace exists
WilliamWang1721 Oct 1, 2026
91e41f3
fix: resolve workspace dialog modules from shell event dispatcher
WilliamWang1721 Oct 1, 2026
e872cc3
style: format shell dispatcher module imports
WilliamWang1721 Oct 1, 2026
91abb72
ci: rerun unchanged source after Windows native probe timing failure
WilliamWang1721 Oct 1, 2026
e763523
Merge upstream main into feat/update-release-notes
WilliamWang1721 Oct 1, 2026
1e5a058
fix: preserve pending release descriptions in a version-isolated cache
WilliamWang1721 Oct 1, 2026
185b5be
fix: encode release-note cache digests with the existing byte-wise he…
WilliamWang1721 Oct 1, 2026
ba00ef1
Merge upstream main into feat/update-release-notes
WilliamWang1721 Oct 1, 2026
6403d0c
Merge upstream main into feat/update-release-notes
WilliamWang1721 Oct 1, 2026
67ac8e9
Merge upstream main into PR #418
WilliamWang1721 Oct 1, 2026
690c748
Merge upstream main into PR #418
WilliamWang1721 Oct 1, 2026
2434136
Merge upstream main into PR #418
WilliamWang1721 Oct 3, 2026
c29edf5
Merge upstream main into PR #418
WilliamWang1721 Oct 3, 2026
eb1829f
Merge upstream main into feat/update-release-notes
WilliamWang1721 Oct 4, 2026
f490f5b
Merge upstream main into feat/update-release-notes
WilliamWang1721 Oct 4, 2026
db327c3
Merge branch 'main' into feat/update-release-notes
WilliamWang1721 Oct 6, 2026
b9cce68
ci: rerun native tests after unrelated flaky failure
WilliamWang1721 Oct 6, 2026
dd20446
Merge main into feat/update-release-notes
claude Oct 9, 2026
dbab948
Merge main into feat/update-release-notes
WilliamWang1721 Oct 11, 2026
6bc0b2e
Merge main into feat/update-release-notes
WilliamWang1721 Oct 11, 2026
379c70b
ci: retrigger native tests after unrelated Windows timeout
WilliamWang1721 Oct 12, 2026
8d0b1ab
Merge main into feat/update-release-notes
WilliamWang1721 Oct 13, 2026
35651ee
Merge origin/feat/update-release-notes
WilliamWang1721 Oct 13, 2026
a6c61ec
Merge main into feat/update-release-notes
WilliamWang1721 Oct 13, 2026
911a8ce
Merge main into feat/update-release-notes
WilliamWang1721 Oct 14, 2026
327681d
Merge main into feat/update-release-notes
WilliamWang1721 Oct 14, 2026
2d93bbb
Merge main into feat/update-release-notes
WilliamWang1721 Oct 14, 2026
2202cf9
Merge main into feat/update-release-notes
WilliamWang1721 Oct 15, 2026
2e5ccfa
ci: retrigger after unrelated macOS Intel test flake
WilliamWang1721 Oct 15, 2026
0280f4f
Merge main into feat/update-release-notes
WilliamWang1721 Oct 15, 2026
283b127
Merge main into feat/update-release-notes
WilliamWang1721 Oct 16, 2026
36b1389
Merge main into feat/update-release-notes
WilliamWang1721 Oct 17, 2026
28a0010
Merge main into feat/update-release-notes
WilliamWang1721 Oct 19, 2026
d81927d
Merge main into feat/update-release-notes
WilliamWang1721 Oct 21, 2026
020e1ae
Merge main into feat/update-release-notes
WilliamWang1721 Oct 21, 2026
0ebe25e
Merge main into feat/update-release-notes
WilliamWang1721 Oct 22, 2026
00ae1fa
Merge main into feat/update-release-notes
WilliamWang1721 Oct 23, 2026
abe8e22
Merge main into feat/update-release-notes
WilliamWang1721 Oct 23, 2026
d9cd748
Merge main into feat/update-release-notes
WilliamWang1721 Oct 23, 2026
8610b07
Merge main into feat/update-release-notes
WilliamWang1721 Oct 24, 2026
be75f59
Merge main into feat/update-release-notes
WilliamWang1721 Oct 24, 2026
b4e94b1
Merge main into feat/update-release-notes
WilliamWang1721 Oct 25, 2026
848496d
Merge main into feat/update-release-notes
WilliamWang1721 Oct 26, 2026
60e1552
Merge main into feat/update-release-notes
WilliamWang1721 Oct 26, 2026
ac9323f
Merge main into feat/update-release-notes
WilliamWang1721 Oct 27, 2026
1149ad2
Merge main into feat/update-release-notes
WilliamWang1721 Oct 28, 2026
d6866c2
Merge main into feat/update-release-notes
WilliamWang1721 Oct 28, 2026
e1ac030
Merge main into feat/update-release-notes
WilliamWang1721 Oct 30, 2026
0611570
Merge main into feat/update-release-notes
WilliamWang1721 Oct 31, 2026
02d7424
Merge main into feat/update-release-notes
WilliamWang1721 Nov 1, 2026
ed1d453
Merge main into feat/update-release-notes
WilliamWang1721 Nov 2, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Installed notes wait for a visible window

## Status

Implemented; isolated visibility regression passed on all selected native platforms.

## Context

The post-install notice is persistent and shown once. A resident first launch can have only a hidden workspace.

## Evidence

The original UpdateInstalled dispatch chose an MRU window without inspecting window_hidden, then persisted release_notes_shown before opening its dialog. Quitting before revealing that hidden window could consume a notice the user never saw.

## Decision

The update dialog capability owns one pending installed description in App memory. The process shell event dispatcher chooses a live visible workspace before claiming and opening it. Existing pump ticks retry after reveal; a destroyed handle leaves it pending. Failed persistent claims retry after five seconds. No activation or forced reveal is added.

The complete process shell event dispatcher lives under windowing/shell_events, separately from window creation, transfer, geometry and snapshot responsibilities. Its existing event behavior is preserved.

## Rejected alternatives

- A hidden dialog must not count as a visible notice.
- Forcing a background resident window to the foreground would change startup policy.
- A second persisted notice state would duplicate the existing locked updater authority.

## Consequences

Only a successful persistent claim for a visible target consumes the pending notice. Process exit before reveal preserves the existing unclaimed update state. The pending payload is App-owned and does not create another worker or persistence format.

## Validation

An isolated GPUI regression sends the real installed event while the workspace is hidden, checks that no persistent acknowledgement exists, reveals it, and checks one acknowledgement. Existing rendered-dialog tests cover content and close/Escape.

PR head e763523db8ad0bbe3a6d053cd11b1e46ee682adf passed all ten required checks. Its macOS ARM native suite passed 2583 tests (24 existing skips); the visibility regression passed in 3.046 seconds. Later cache changes require their own current-head CI result and do not replace this visibility evidence.

## Supersedes

None; refines the installed release-notes lifecycle.

## Revisit when

Resident window visibility or updater acknowledgement ownership changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Installed release descriptions

## Status

Proposed in this PR.

## Context

Users need to read the installed version's GitHub Release description in Settings,
and see it once after an in-app update succeeds. A newer release can appear before
that first launch; checking `/latest` cannot identify the installed description.

## Evidence

`update_check.rs` already parses the Release body for checksums but discards it.
`update_download/handoff.rs` records the installer transaction, executable and
result and verifies the running version when recovering the workspace.
`update_state.json` already serializes prompt preferences with process/file locks.
The GPUI component `TextView` already renders selectable Markdown in the product.

The initial single-file cache could lose a pending release when Settings fetched
the installed version before handoff preparation; an offline first launch then
had no matching snapshot. Concurrent version writes also cannot share a replacing file.

## Decision

Retain the Release body as separate updater metadata. Cache it during a successful
update check, then snapshot the matching version in the existing handoff directory
before authorizing installation. This adds no installation authority or helper
protocol field. Missing cached notes do not prevent installation.

Cache each version in its own atomic file keyed by a SHA-256 digest of the version,
using the existing digest dependency. Version strings cannot escape the updater
directory, and installed-version reads do not evict pending-update metadata.
The old single-file cache remains an exact-version read fallback for compatibility;
new writes use only version-keyed files. Handoff snapshots keep their existing format.

On startup require a successful result matching the transaction, installation and
running version. Load the snapshot, or fetch that exact version's tag when no
snapshot exists. Failed/offline reads leave the notice pending for a later launch.
Claim the notice with the existing prompt-state process/file locks before showing
it in the selected window. The optional `release_notes_shown` field defaults to
unset for existing state files and is independent of update snooze/skip settings.

Settings and the dialog share a read-only Markdown view with loading, empty,
failure/retry and external-release states. Remote descriptions are rendered as
content; only HTTP(S) links are opened by the view. Settings remain available on
externally managed distributions; their updates do not create in-app handoffs.

## Rejected alternatives

- Inferring success from a changed version: also triggers on fresh installs,
manual installs and failed updates followed by a rollback.
- Showing the latest description: can describe a version not yet installed.
- Using the workspace restore acknowledgement: restoration and reading notes have
independent lifecycles; an offline metadata fetch must not consume the notice.
- A second rich-text renderer or dependency: the existing TextView is sufficient.

## Consequences

Release text is stored under the existing updater directory, outside user
settings. No new thread is added; discovery uses the existing startup check and
view-owned background tasks. Automatic installation remains Windows/macOS only;
other distributions can read their installed version's notes in Settings.

Each cached file retains the existing 2 MiB read limit. Retained metadata grows
with distinct versions rather than requests; pruning must preserve pending update
notes and is separate from correcting version isolation.

The shown marker gives at-most-once presentation across normal restarts and
concurrent processes. As with existing update prompts, a crash after persisting
that marker but before painting can consume the notice; Settings still exposes it.

## Validation

Focused regressions cover exact-version text, persisted snapshots, successful
handoff, duplicate claims, rollback exclusion and existing workspace recovery.
PR evidence records compilation, rendered UI checks and native CI separately.
The cache regression reproduces a pending update followed by an installed-version
Settings read, then verifies an offline handoff snapshot. Compatibility and
untrusted version-path cases exercise the same production cache helpers.

## Supersedes

None.

## Revisit when

The updater accepts another release source, the handoff protocol changes, or
release notes need a user acknowledgement rather than once-only presentation.
11 changes: 9 additions & 2 deletions nebula_app/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@
"advanced": "advanced session tray restore startup autostart login silent",
"backup": "backup cloud sync export restore webdav s3 sftp 123 nextcloud synology nas r2 minio snapshots",
"agents": "agents agent hook hooks claude codex opencode cursor kimi pi omp copilot grok",
"mobile": "mobile phone android ios remote pairing qr lan relay"
"mobile": "mobile phone android ios remote pairing qr lan relay",
"release_notes": "release notes changelog what is new"
}
},
"opacity": {
Expand Down Expand Up @@ -1471,7 +1472,13 @@
"later": "Later",
"prepare_failed": "Could not prepare the update: {error}. Pebrel will stay open.",
"draft_changed": "A document changed while preparing to exit. Save or discard the latest changes, then retry.",
"in_progress": "This installation is being updated. Wait for the update to finish; Pebrel will reopen automatically."
"in_progress": "This installation is being updated. Wait for the update to finish; Pebrel will reopen automatically.",
"release_notes_title": "Release notes",
"release_notes_loading": "Loading release notes…",
"release_notes_failed": "Could not load release notes: {error}",
"release_notes_retry": "Retry",
"release_notes_empty": "This release has no description.",
"open_release": "Open release"
},
"files.filter_placeholder": "Filter files...",
"files.match_case": "Match case",
Expand Down
3 changes: 2 additions & 1 deletion nebula_app/i18n/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"advanced": "詳細設定 セッション トレイ 復元 起動 自動起動 ログイン サイレント",
"backup": "バックアップ クラウド 同期 ストレージ エクスポート 復元 スナップショット 資格情報 パスワード",
"agents": "エージェント フック 連携",
"mobile": "モバイル スマートフォン スマホ リモート ペアリング QRコード ローカルネットワーク リレー ネットワークアダプター 閲覧専用 通知"
"mobile": "モバイル スマートフォン スマホ リモート ペアリング QRコード ローカルネットワーク リレー ネットワークアダプター 閲覧専用 通知",
"release_notes": "リリースノート 更新内容 変更履歴"
}
},
"opacity": {
Expand Down
11 changes: 9 additions & 2 deletions nebula_app/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@
"advanced": "高级 会话 托盘 恢复 自启动 静默启动 开机 登录",
"backup": "云备份 云同步 云存储 备份 导出 恢复 坚果云 123云盘 群晖 快照",
"agents": "智能体 钩子 接入",
"mobile": "手机 远程 配对 二维码 局域网 中转 网卡 只看 手机通知"
"mobile": "手机 远程 配对 二维码 局域网 中转 网卡 只看 手机通知",
"release_notes": "更新内容 更新日志 版本说明"
}
},
"opacity": {
Expand Down Expand Up @@ -1471,7 +1472,13 @@
"later": "稍后",
"prepare_failed": "更新准备失败:{error}。Pebrel 将保持打开。",
"draft_changed": "准备退出期间文档发生了变化。请保存或放弃最新修改后重试。",
"in_progress": "当前安装正在更新,请等待更新完成,Pebrel 随后会自动重新打开。"
"in_progress": "当前安装正在更新,请等待更新完成,Pebrel 随后会自动重新打开。",
"release_notes_title": "更新内容",
"release_notes_loading": "正在加载更新内容…",
"release_notes_failed": "无法加载更新内容:{error}",
"release_notes_retry": "重试",
"release_notes_empty": "此版本未提供更新说明。",
"open_release": "打开发布页"
},
"files.filter_placeholder": "过滤文件...",
"files.match_case": "区分大小写",
Expand Down
2 changes: 2 additions & 0 deletions nebula_app/src/gpui_shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ mod molecule_view;
mod motion;
pub mod network_settings;
pub mod prelude;
mod release_notes;
mod scientific_render;
pub mod session_restore;
#[cfg(all(test, feature = "gpui-test-support"))]
Expand Down Expand Up @@ -75,6 +76,7 @@ pub(crate) enum GpuiShellEvent {
MuxAttach,
RuntimeControl(std::sync::Arc<crate::runtime_api::RuntimeDispatch>),
UpdateAvailable(crate::update_check::UpdateCheckResult),
UpdateInstalled(crate::update_check::release_notes::ReleaseNotes),
SshPrompt(std::sync::Arc<crate::ssh_prompt::Prompt>),
OpenDirectories(Vec<String>),
ElevatedLaunch(std::sync::Arc<crate::platform::elevation::handover::Dispatch>),
Expand Down
Loading
Loading