icebear0828 Claude Opus 4.6 commited on
Commit
66b06ea
·
1 Parent(s): b51ffa1

fix: version display uses git tag + remove inline-grid layout hack

Browse files

- getProxyInfo() now tries `git describe --tags` first, falls back to
package.json (skipping placeholder "1.0.0"), so git-mode users see
the actual release version or just the commit hash
- Replace all inline-grid overlay technique with simple whitespace-nowrap
to fix two-line button text caused by invisible reference spans

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Files changed (2) hide show
  1. src/self-update.ts +23 -8
  2. web/src/components/Header.tsx +5 -20
src/self-update.ts CHANGED
@@ -39,7 +39,7 @@ const CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000; // 6 hours
39
  const INITIAL_DELAY_MS = 10_000; // 10 seconds after startup
40
 
41
  export interface ProxyInfo {
42
- version: string;
43
  commit: string | null;
44
  }
45
 
@@ -75,15 +75,30 @@ let _checkTimer: ReturnType<typeof setInterval> | null = null;
75
  let _initialTimer: ReturnType<typeof setTimeout> | null = null;
76
  let _checking = false;
77
 
78
- /** Read proxy version from package.json + current git commit hash. */
79
  export function getProxyInfo(): ProxyInfo {
80
- let version = "unknown";
 
 
 
81
  try {
82
- const pkg = JSON.parse(readFileSync(resolve(getRootDir(), "package.json"), "utf-8")) as { version?: string };
83
- version = pkg.version ?? "unknown";
84
- } catch { /* ignore */ }
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
- let commit: string | null = null;
87
  try {
88
  const out = execFileSync("git", ["rev-parse", "--short", "HEAD"], {
89
  cwd: process.cwd(),
@@ -236,7 +251,7 @@ export async function checkProxySelfUpdate(): Promise<ProxySelfUpdateResult> {
236
 
237
  // Docker or Electron — GitHub Releases API
238
  const release = await checkGitHubRelease();
239
- const currentVersion = getProxyInfo().version;
240
  const updateAvailable = release !== null
241
  && release.version !== currentVersion
242
  && release.version.localeCompare(currentVersion, undefined, { numeric: true }) > 0;
 
39
  const INITIAL_DELAY_MS = 10_000; // 10 seconds after startup
40
 
41
  export interface ProxyInfo {
42
+ version: string | null;
43
  commit: string | null;
44
  }
45
 
 
75
  let _initialTimer: ReturnType<typeof setTimeout> | null = null;
76
  let _checking = false;
77
 
78
+ /** Read proxy version from git tag / package.json + current git commit hash. */
79
  export function getProxyInfo(): ProxyInfo {
80
+ let version: string | null = null;
81
+ let commit: string | null = null;
82
+
83
+ // Try git tag first (meaningful for versioned releases)
84
  try {
85
+ const tag = execFileSync("git", ["describe", "--tags", "--abbrev=0", "HEAD"], {
86
+ cwd: process.cwd(),
87
+ encoding: "utf-8",
88
+ timeout: 5000,
89
+ }).trim();
90
+ if (tag) version = tag.startsWith("v") ? tag.slice(1) : tag;
91
+ } catch { /* no reachable tag */ }
92
+
93
+ // Fall back to package.json (skip "1.0.0" placeholder on master)
94
+ if (!version) {
95
+ try {
96
+ const pkg = JSON.parse(readFileSync(resolve(getRootDir(), "package.json"), "utf-8")) as { version?: string };
97
+ const v = pkg.version;
98
+ if (v && v !== "1.0.0") version = v;
99
+ } catch { /* ignore */ }
100
+ }
101
 
 
102
  try {
103
  const out = execFileSync("git", ["rev-parse", "--short", "HEAD"], {
104
  cwd: process.cwd(),
 
251
 
252
  // Docker or Electron — GitHub Releases API
253
  const release = await checkGitHubRelease();
254
+ const currentVersion = getProxyInfo().version ?? "0.0.0";
255
  const updateAvailable = release !== null
256
  && release.version !== currentVersion
257
  && release.version.localeCompare(currentVersion, undefined, { numeric: true }) > 0;
web/src/components/Header.tsx CHANGED
@@ -64,10 +64,7 @@ export function Header({ onAddAccount, onCheckUpdate, onOpenUpdateModal, checkin
64
  <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" />
65
  <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-primary" />
66
  </span>
67
- <span class="text-xs font-semibold text-primary inline-grid">
68
- <span class="invisible col-start-1 row-start-1">Server Online</span>
69
- <span class="col-start-1 row-start-1">{t("serverOnline")}</span>
70
- </span>
71
  {version && (
72
  <span class="text-[0.65rem] font-mono text-primary/70">v{version}</span>
73
  )}
@@ -85,10 +82,7 @@ export function Header({ onAddAccount, onCheckUpdate, onOpenUpdateModal, checkin
85
  <svg class="size-3.5" viewBox="0 0 24 24" fill="currentColor">
86
  <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
87
  </svg>
88
- <span class="text-xs font-semibold inline-grid">
89
- <span class="invisible col-start-1 row-start-1">Star on GitHub</span>
90
- <span class="col-start-1 row-start-1">{t("starOnGithub")}</span>
91
- </span>
92
  </a>
93
  {/* Check for Updates */}
94
  <button
@@ -99,10 +93,7 @@ export function Header({ onAddAccount, onCheckUpdate, onOpenUpdateModal, checkin
99
  <svg class={`size-3.5 ${checking ? "animate-spin" : ""}`} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
100
  <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.992 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182M20.985 4.356v4.992" />
101
  </svg>
102
- <span class="text-xs font-semibold inline-grid">
103
- <span class="invisible col-start-1 row-start-1">Check for Updates</span>
104
- <span class="col-start-1 row-start-1">{checking ? t("checkingUpdates") : t("checkForUpdates")}</span>
105
- </span>
106
  </button>
107
  {/* Update status message */}
108
  {updateStatusMsg && !checking && (
@@ -139,10 +130,7 @@ export function Header({ onAddAccount, onCheckUpdate, onOpenUpdateModal, checkin
139
  <svg class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
140
  <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75" />
141
  </svg>
142
- <span class="text-xs font-semibold inline-grid">
143
- <span class="invisible col-start-1 row-start-1">Proxy Assignment</span>
144
- <span class="col-start-1 row-start-1">{t("proxySettings")}</span>
145
- </span>
146
  </a>
147
  <button
148
  onClick={onAddAccount}
@@ -151,10 +139,7 @@ export function Header({ onAddAccount, onCheckUpdate, onOpenUpdateModal, checkin
151
  <svg class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
152
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
153
  </svg>
154
- <span class="inline-grid">
155
- <span class="invisible col-start-1 row-start-1">Add Account</span>
156
- <span class="col-start-1 row-start-1">{t("addAccount")}</span>
157
- </span>
158
  </button>
159
  </>
160
  )}
 
64
  <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" />
65
  <span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-primary" />
66
  </span>
67
+ <span class="text-xs font-semibold text-primary whitespace-nowrap">{t("serverOnline")}</span>
 
 
 
68
  {version && (
69
  <span class="text-[0.65rem] font-mono text-primary/70">v{version}</span>
70
  )}
 
82
  <svg class="size-3.5" viewBox="0 0 24 24" fill="currentColor">
83
  <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
84
  </svg>
85
+ <span class="text-xs font-semibold whitespace-nowrap">{t("starOnGithub")}</span>
 
 
 
86
  </a>
87
  {/* Check for Updates */}
88
  <button
 
93
  <svg class={`size-3.5 ${checking ? "animate-spin" : ""}`} viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
94
  <path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.992 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182M20.985 4.356v4.992" />
95
  </svg>
96
+ <span class="text-xs font-semibold whitespace-nowrap">{checking ? t("checkingUpdates") : t("checkForUpdates")}</span>
 
 
 
97
  </button>
98
  {/* Update status message */}
99
  {updateStatusMsg && !checking && (
 
130
  <svg class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
131
  <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75" />
132
  </svg>
133
+ <span class="text-xs font-semibold whitespace-nowrap">{t("proxySettings")}</span>
 
 
 
134
  </a>
135
  <button
136
  onClick={onAddAccount}
 
139
  <svg class="size-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
140
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
141
  </svg>
142
+ <span class="whitespace-nowrap">{t("addAccount")}</span>
 
 
 
143
  </button>
144
  </>
145
  )}