Compare commits

..

3 Commits

Author SHA1 Message Date
Jiang Bohan
e149075d20 fix(desktop): show git-described version in dev instead of stale 0.1.0
Packaged builds are unaffected: scripts/package.mjs already injects the
git tag into electron-builder's extraMetadata.version, so the .app users
download from GitHub Release reports the right version through
app.getVersion() and the auto-updater's latest.yml comparison works
correctly.

Dev mode (`pnpm dev:desktop`) didn't go through that path though, so
app.getVersion() returned the static "0.1.0" from package.json — the
new Settings → Updates panel surfaced this and made it look like the
dev build was ancient. Add a tiny getAppVersion() helper that falls
back to `git describe --tags --always --dirty` only when !app.isPackaged,
and use it for the app-info IPC. No change to packaged behavior; if git
is unavailable for any reason, we silently fall back to app.getVersion().
2026-04-29 19:15:03 +08:00
Bohan Jiang
f4eb83bd41 feat(desktop): show current version in Updates settings (#1861)
Surface the running app version (from app.getVersion via preload's
appInfo) at the top of Settings → Updates so users have a clear place
to check which build they're on, instead of only seeing it inline after
clicking "Check now".
2026-04-29 19:07:39 +08:00
Jiayuan Zhang
dde42ba84a fix(views): remove Sparkles icon before "Created by" in quick capture dialog (#1859)
Removes the Sparkles icon from the agent picker trigger in the
quick-create-issue dialog, keeping only the "Created by" text label.
2026-04-29 12:51:08 +02:00
3 changed files with 48 additions and 4 deletions

View File

@@ -0,0 +1,33 @@
import { app } from "electron";
import { execSync } from "node:child_process";
/**
* Resolve the running app version. In packaged builds this is the value
* `electron-builder` baked into package.json via `extraMetadata.version`
* (driven by `git describe` — see `apps/desktop/scripts/package.mjs`), so
* `app.getVersion()` matches the GitHub Release tag exactly.
*
* In dev (`pnpm dev:desktop`) `app.getVersion()` only sees the static
* `apps/desktop/package.json` value, which is "0.1.0" and never bumped —
* the Settings → Updates panel and any other UI surfacing the version
* would mislead developers into thinking they're running ancient builds.
* Fall back to `git describe --tags --always --dirty` (same source the
* packager uses) so dev shows e.g. `0.2.19-14-gabcdef-dirty`. If git is
* unavailable for whatever reason, we just return the package.json value.
*/
export function getAppVersion(): string {
if (app.isPackaged) {
return app.getVersion();
}
try {
const raw = execSync("git describe --tags --always --dirty", {
cwd: app.getAppPath(),
encoding: "utf-8",
stdio: ["ignore", "pipe", "ignore"],
}).trim();
if (!raw) return app.getVersion();
return raw.replace(/^v/, "");
} catch {
return app.getVersion();
}
}

View File

@@ -7,6 +7,7 @@ import { setupAutoUpdater } from "./updater";
import { setupDaemonManager } from "./daemon-manager";
import { openExternalSafely } from "./external-url";
import { installContextMenu } from "./context-menu";
import { getAppVersion } from "./app-version";
// Bundled icon used for dev-mode dock/taskbar branding. In production the
// app bundle icon (from electron-builder) wins; this path is only consumed
@@ -203,7 +204,7 @@ if (!gotTheLock) {
ipcMain.on("app:get-info", (event) => {
const p = process.platform;
const os = p === "darwin" ? "macos" : p === "win32" ? "windows" : p === "linux" ? "linux" : "unknown";
event.returnValue = { version: app.getVersion(), os };
event.returnValue = { version: getAppVersion(), os };
});
// IPC: toggle immersive mode — hides the macOS traffic lights so full-screen

View File

@@ -5,12 +5,13 @@ import { Button } from "@multica/ui/components/ui/button";
type CheckState =
| { status: "idle" }
| { status: "checking" }
| { status: "up-to-date"; currentVersion: string }
| { status: "up-to-date" }
| { status: "available"; latestVersion: string }
| { status: "error"; message: string };
export function UpdatesSettingsTab() {
const [state, setState] = useState<CheckState>({ status: "idle" });
const currentVersion = window.desktopAPI.appInfo.version;
const handleCheck = useCallback(async () => {
setState({ status: "checking" });
@@ -22,7 +23,7 @@ export function UpdatesSettingsTab() {
setState(
result.available
? { status: "available", latestVersion: result.latestVersion }
: { status: "up-to-date", currentVersion: result.currentVersion },
: { status: "up-to-date" },
);
}, []);
@@ -35,6 +36,15 @@ export function UpdatesSettingsTab() {
</p>
<div className="mt-6 divide-y">
<div className="flex items-center justify-between gap-6 py-4">
<div className="min-w-0">
<p className="text-sm font-medium">Current version</p>
<p className="text-sm text-muted-foreground mt-0.5 font-mono">
v{currentVersion}
</p>
</div>
</div>
<div className="flex items-start justify-between gap-6 py-4">
<div className="min-w-0">
<p className="text-sm font-medium">Check for updates</p>
@@ -45,7 +55,7 @@ export function UpdatesSettingsTab() {
{state.status === "up-to-date" && (
<p className="text-sm text-muted-foreground mt-2 inline-flex items-center gap-1.5">
<Check className="size-3.5 text-success" />
You&apos;re on the latest version (v{state.currentVersion}).
You&apos;re on the latest version.
</p>
)}
{state.status === "available" && (