diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts
index 4a2c1ce6c8c..ce8aa7d8382 100644
--- a/apps/desktop/electron/main.ts
+++ b/apps/desktop/electron/main.ts
@@ -11069,7 +11069,7 @@ function resolveHermesVersionInfo() {
baseVersion: INSTALL_STAMP.baseVersion ?? undefined,
distance: INSTALL_STAMP.distance ?? undefined,
commit: INSTALL_STAMP.commit,
- branch: INSTALL_STAMP.branch ?? undefined,
+ branch: INSTALL_STAMP.branch,
source: INSTALL_STAMP.source ?? undefined,
installMethod: INSTALL_STAMP.installMethod ?? undefined,
dirty: INSTALL_STAMP.dirty
diff --git a/apps/desktop/src/components/version-details.test.tsx b/apps/desktop/src/components/version-details.test.tsx
new file mode 100644
index 00000000000..a720d80d565
--- /dev/null
+++ b/apps/desktop/src/components/version-details.test.tsx
@@ -0,0 +1,41 @@
+import { cleanup, render, screen } from '@testing-library/react'
+import { afterEach, describe, expect, it } from 'vitest'
+
+import type { DesktopVersionInfo } from '@/global'
+import { I18nProvider } from '@/i18n'
+
+import { VersionDetails } from './version-details'
+
+const baseVersion: DesktopVersionInfo = {
+ appVersion: '0.19.0',
+ electronVersion: '37.0.0',
+ hermesRoot: '/tmp/hermes',
+ nodeVersion: '22.0.0',
+ platform: 'linux'
+}
+
+afterEach(cleanup)
+
+describe('VersionDetails', () => {
+ it('labels a missing branch explicitly', () => {
+ render(
+
+
+
+ )
+
+ expect(screen.getByText('Branch')).toBeTruthy()
+ expect(screen.getByText('No branch information')).toBeTruthy()
+ })
+
+ it('preserves a literal branch named unknown', () => {
+ render(
+
+
+
+ )
+
+ expect(screen.getByText('unknown')).toBeTruthy()
+ expect(screen.queryByText('No branch information')).toBeNull()
+ })
+})
diff --git a/apps/desktop/src/components/version-details.tsx b/apps/desktop/src/components/version-details.tsx
index 2e6f24e76bc..498ace7ede2 100644
--- a/apps/desktop/src/components/version-details.tsx
+++ b/apps/desktop/src/components/version-details.tsx
@@ -25,12 +25,10 @@ export function VersionDetails({ version }: { version: DesktopVersionInfo }) {
{version.baseVersion}
)}
- {version.branch && (
-
-
{u.versionDetailsBranch}
- {version.branch}
-
- )}
+
+
{u.versionDetailsBranch}
+ {version.branch ?? u.versionDetailsNoBranchInfo}
+
{version.commit && (
{u.versionDetailsCommit}
diff --git a/apps/desktop/src/global.d.ts b/apps/desktop/src/global.d.ts
index 3b4f4f1c305..241d558e23d 100644
--- a/apps/desktop/src/global.d.ts
+++ b/apps/desktop/src/global.d.ts
@@ -320,7 +320,7 @@ export interface HermesTerminalExit {
export interface DesktopVersionInfo {
appVersion: string
baseVersion?: string
- branch?: string
+ branch?: string | null
commit?: string
distance?: number
dirty?: boolean
diff --git a/apps/desktop/src/i18n/en.ts b/apps/desktop/src/i18n/en.ts
index f33335a990e..6746449611b 100644
--- a/apps/desktop/src/i18n/en.ts
+++ b/apps/desktop/src/i18n/en.ts
@@ -2132,6 +2132,7 @@ export const en: Translations = {
versionDetailsVersion: 'Version',
versionDetailsBaseVersion: 'Release version',
versionDetailsBranch: 'Branch',
+ versionDetailsNoBranchInfo: 'No branch information',
versionDetailsCommit: 'Commit',
versionDetailsDirty: 'This package was built from a dirty source tree.',
versionDetailsDirtyUnknown: 'Built from a dirty source tree. The number of changes since the last release is unknown.',
diff --git a/apps/desktop/src/i18n/ja.ts b/apps/desktop/src/i18n/ja.ts
index 2d16d792ec5..6bbc48ba4cb 100644
--- a/apps/desktop/src/i18n/ja.ts
+++ b/apps/desktop/src/i18n/ja.ts
@@ -1992,6 +1992,7 @@ export const ja = defineLocale({
versionDetailsVersion: 'バージョン',
versionDetailsBaseVersion: 'リリースバージョン',
versionDetailsBranch: 'ブランチ',
+ versionDetailsNoBranchInfo: 'ブランチ情報なし',
versionDetailsCommit: 'コミット',
versionDetailsDirty: 'このパッケージは変更のあるソースツリーからビルドされました。',
versionDetailsDirtyUnknown: '変更のあるソースツリーからビルドされました。最後のリリースからの変更数は不明です。',
diff --git a/apps/desktop/src/i18n/types.ts b/apps/desktop/src/i18n/types.ts
index 8039339c24d..6d7211ec1eb 100644
--- a/apps/desktop/src/i18n/types.ts
+++ b/apps/desktop/src/i18n/types.ts
@@ -1771,6 +1771,7 @@ export interface Translations {
versionDetailsVersion: string
versionDetailsBaseVersion: string
versionDetailsBranch: string
+ versionDetailsNoBranchInfo: string
versionDetailsCommit: string
versionDetailsDirty: string
versionDetailsDirtyUnknown: string
diff --git a/apps/desktop/src/i18n/zh-hant.ts b/apps/desktop/src/i18n/zh-hant.ts
index d55d46c2559..5b372a113c5 100644
--- a/apps/desktop/src/i18n/zh-hant.ts
+++ b/apps/desktop/src/i18n/zh-hant.ts
@@ -1932,6 +1932,7 @@ export const zhHant = defineLocale({
versionDetailsVersion: '版本',
versionDetailsBaseVersion: '發行版本',
versionDetailsBranch: '分支',
+ versionDetailsNoBranchInfo: '沒有分支資訊',
versionDetailsCommit: '提交',
versionDetailsDirty: '此套件從有未提交變更的來源樹建置。',
versionDetailsDirtyUnknown: '從有未提交變更的來源樹建置。自上次發布以來的變更數量未知。',
diff --git a/apps/desktop/src/i18n/zh.ts b/apps/desktop/src/i18n/zh.ts
index fd116f3f247..d8b05bfe5b5 100644
--- a/apps/desktop/src/i18n/zh.ts
+++ b/apps/desktop/src/i18n/zh.ts
@@ -2323,6 +2323,7 @@ export const zh: Translations = {
versionDetailsVersion: '版本',
versionDetailsBaseVersion: '发布版本',
versionDetailsBranch: '分支',
+ versionDetailsNoBranchInfo: '无分支信息',
versionDetailsCommit: '提交',
versionDetailsDirty: '此软件包从有未提交更改的源代码树构建。',
versionDetailsDirtyUnknown: '从有未提交更改的源代码树构建。自上次发布以来的更改数量未知。',
diff --git a/nix/desktop.nix b/nix/desktop.nix
index 430e3860ba1..b71a7a5aab0 100644
--- a/nix/desktop.nix
+++ b/nix/desktop.nix
@@ -44,10 +44,6 @@ let
if distance != null && distance > 0 then "${version}+${toString distance}"
else if dirty && distance == null then "${version}+?"
else version;
- # On a dirty tree, sourceInfo.ref is null (flakes can't determine the ref).
- # Show "unknown" rather than null so the desktop doesn't fall back to its
- # self-update default branch ("main") when the real branch is unavailable.
- branchLabel = if branch != null then branch else "unknown";
electronHeaders = pkgs.fetchurl {
url = "https://artifacts.electronjs.org/headers/dist/v${electron.version}/node-v${electron.version}-headers.tar.gz";
@@ -166,7 +162,7 @@ let
cp -rn apps/desktop/dist $out/
cat > $out/install-stamp.json <<'EOF'
- {"schemaVersion":2,"commit":${builtins.toJSON rev},"branch":${builtins.toJSON branchLabel},"baseVersion":"${version}","displayVersion":"${displayVersion}","distance":${builtins.toJSON distance},"dirty":${
+ {"schemaVersion":2,"commit":${builtins.toJSON rev},"branch":${builtins.toJSON branch},"baseVersion":"${version}","displayVersion":"${displayVersion}","distance":${builtins.toJSON distance},"dirty":${
if dirty then "true" else "false"
},"source":"nix","installMethod":"nix"}
EOF
diff --git a/nix/hermes-agent.nix b/nix/hermes-agent.nix
index 228df8f24c5..c84fd4604aa 100644
--- a/nix/hermes-agent.nix
+++ b/nix/hermes-agent.nix
@@ -56,7 +56,6 @@ let
if stampDistance != null && stampDistance > 0 then "${version}+${toString stampDistance}"
else if dirty && stampDistance == null then "${version}+?"
else version;
- stampBranch = if branch != null then branch else "unknown";
nodejs = nodejs_22;
mkHermesVenv =
@@ -206,7 +205,7 @@ stdenv.mkDerivation (finalAttrs: {
# runtime instead of probing env vars or .git — one file, one source
# of truth for the Python runtime (CLI, TUI).
cat > $out/share/hermes-agent/.hermes_build_info.json < git
if dirty is None:
diff --git a/tests/hermes_cli/test_version_info.py b/tests/hermes_cli/test_version_info.py
index 2b1cada5c57..4a23f771a05 100644
--- a/tests/hermes_cli/test_version_info.py
+++ b/tests/hermes_cli/test_version_info.py
@@ -47,11 +47,11 @@ def test_stamp_version_info_reads_nix_stamp(tmp_path, monkeypatch):
assert info == VersionInfo("0.19.0", "0.19.0+3", 3, "a" * 40, "feature/version", "nix")
-def test_stamp_version_info_reads_docker_stamp_with_unknown_distance(tmp_path, monkeypatch):
+def test_stamp_version_info_preserves_missing_branch(tmp_path, monkeypatch):
stamp = {
"schemaVersion": 2,
"commit": "b" * 40,
- "branch": "unknown",
+ "branch": None,
"baseVersion": "0.19.0",
"displayVersion": "0.19.0+?",
"distance": None,
@@ -64,7 +64,7 @@ def test_stamp_version_info_reads_docker_stamp_with_unknown_distance(tmp_path, m
info = get_version_info()
- assert info == VersionInfo("0.19.0", "0.19.0+?", None, "b" * 40, "unknown", "docker", True)
+ assert info == VersionInfo("0.19.0", "0.19.0+?", None, "b" * 40, None, "docker", True)
def test_stamp_version_info_ignores_fallback_commit(tmp_path, monkeypatch):