authorgravatar for WeldFire@users.noreply.github.comWeld <WeldFire@users.noreply.github.com> 2026-03-10 11:45:39-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-03-10 09:45:39-07:00
log9e891d2e97d65a6e211e3da8ee95807b9a091563
treeea1acb667a3dba6789361258326a67745593675e
parentb8d07eb852e5ea30717f4079595eb68515e930cf
signature Signed by PGP key B5690EEEBB952194

Display application version in sidebar and settings (#720)


6 files changed, 50 insertions(+), 11 deletions(-)

CLAUDE.md+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1AGENTS.md
\ No newline at end of file
1AGENTS.md
apps/web/src/branding.ts+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1export const APP_BASE_NAME = "T3 Code";1export const APP_BASE_NAME = "T3 Code";
2export const APP_STAGE_LABEL = import.meta.env.DEV ? "Dev" : "Alpha";2export const APP_STAGE_LABEL = import.meta.env.DEV ? "Dev" : "Alpha";
3export const APP_DISPLAY_NAME = `${APP_BASE_NAME} (${APP_STAGE_LABEL})`;3export const APP_DISPLAY_NAME = `${APP_BASE_NAME} (${APP_STAGE_LABEL})`;
4export const APP_VERSION = import.meta.env.APP_VERSION || "0.0.0";
apps/web/src/components/Sidebar.tsx+19-10
...@@ -39,7 +39,7 @@ import { useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/rea...@@ -39,7 +39,7 @@ import { useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/rea
39import { useLocation, useNavigate, useParams } from "@tanstack/react-router";39import { useLocation, useNavigate, useParams } from "@tanstack/react-router";
40import { useAppSettings } from "../appSettings";40import { useAppSettings } from "../appSettings";
41import { isElectron } from "../env";41import { isElectron } from "../env";
42import { APP_STAGE_LABEL } from "../branding";42import { APP_STAGE_LABEL, APP_VERSION } from "../branding";
43import { isMacPlatform, newCommandId, newProjectId, newThreadId } from "../lib/utils";43import { isMacPlatform, newCommandId, newProjectId, newThreadId } from "../lib/utils";
44import { useStore } from "../store";44import { useStore } from "../store";
45import { isChatNewLocalShortcut, isChatNewShortcut, shortcutLabelForCommand } from "../keybindings";45import { isChatNewLocalShortcut, isChatNewShortcut, shortcutLabelForCommand } from "../keybindings";
...@@ -1238,15 +1238,24 @@ export default function Sidebar() {...@@ -1238,15 +1238,24 @@ export default function Sidebar() {
1238 const wordmark = (1238 const wordmark = (
1239 <div className="flex items-center gap-2">1239 <div className="flex items-center gap-2">
1240 <SidebarTrigger className="shrink-0 md:hidden" />1240 <SidebarTrigger className="shrink-0 md:hidden" />
1241 <div className="flex min-w-0 flex-1 items-center gap-1 mt-1.5 ml-1">1241 <Tooltip>
1242 <T3Wordmark />1242 <TooltipTrigger
1243 <span className="truncate text-sm font-medium tracking-tight text-muted-foreground">1243 render={
1244 Code1244 <div className="flex min-w-0 flex-1 items-center gap-1 mt-1.5 ml-1 cursor-pointer">
1245 </span>1245 <T3Wordmark />
1246 <span className="rounded-full bg-muted/50 px-1.5 py-0.5 text-[8px] font-medium uppercase tracking-[0.18em] text-muted-foreground/60">1246 <span className="truncate text-sm font-medium tracking-tight text-muted-foreground">
1247 {APP_STAGE_LABEL}1247 Code
1248 </span>1248 </span>
1249 </div>1249 <span className="rounded-full bg-muted/50 px-1.5 py-0.5 text-[8px] font-medium uppercase tracking-[0.18em] text-muted-foreground/60">
1250 {APP_STAGE_LABEL}
1251 </span>
1252 </div>
1253 }
1254 />
1255 <TooltipPopup side="bottom" sideOffset={2}>
1256 Version {APP_VERSION}
1257 </TooltipPopup>
1258 </Tooltip>
1250 </div>1259 </div>
1251 );1260 );
12521261
apps/web/src/routes/_chat.settings.tsx+19
...@@ -13,6 +13,7 @@ import { preferredTerminalEditor } from "../terminal-links";...@@ -13,6 +13,7 @@ import { preferredTerminalEditor } from "../terminal-links";
13import { Button } from "../components/ui/button";13import { Button } from "../components/ui/button";
14import { Input } from "../components/ui/input";14import { Input } from "../components/ui/input";
15import { Switch } from "../components/ui/switch";15import { Switch } from "../components/ui/switch";
16import { APP_VERSION } from "../branding";
16import { SidebarInset } from "~/components/ui/sidebar";17import { SidebarInset } from "~/components/ui/sidebar";
1718
18const THEME_OPTIONS = [19const THEME_OPTIONS = [
...@@ -554,6 +555,24 @@ function SettingsRouteView() {...@@ -554,6 +555,24 @@ function SettingsRouteView() {
554 </div>555 </div>
555 ) : null}556 ) : null}
556 </section>557 </section>
558 <section className="rounded-2xl border border-border bg-card p-5">
559 <div className="mb-4">
560 <h2 className="text-sm font-medium text-foreground">About</h2>
561 <p className="mt-1 text-xs text-muted-foreground">
562 Application version and environment information.
563 </p>
564 </div>
565
566 <div className="flex items-center justify-between rounded-lg border border-border bg-background px-3 py-2">
567 <div>
568 <p className="text-sm font-medium text-foreground">Version</p>
569 <p className="text-xs text-muted-foreground">
570 Current version of the application.
571 </p>
572 </div>
573 <code className="text-xs font-medium text-muted-foreground">{APP_VERSION}</code>
574 </div>
575 </section>
557 </div>576 </div>
558 </div>577 </div>
559 </div>578 </div>
apps/web/src/vite-env.d.ts+8
...@@ -2,6 +2,14 @@...@@ -2,6 +2,14 @@
22
3import type { NativeApi, DesktopBridge } from "@t3tools/contracts";3import type { NativeApi, DesktopBridge } from "@t3tools/contracts";
44
5interface ImportMetaEnv {
6 readonly APP_VERSION: string;
7}
8
9interface ImportMeta {
10 readonly env: ImportMetaEnv;
11}
12
5declare global {13declare global {
6 interface Window {14 interface Window {
7 nativeApi?: NativeApi;15 nativeApi?: NativeApi;
apps/web/vite.config.ts+2
...@@ -2,6 +2,7 @@ import tailwindcss from "@tailwindcss/vite";...@@ -2,6 +2,7 @@ import tailwindcss from "@tailwindcss/vite";
2import react from "@vitejs/plugin-react";2import react from "@vitejs/plugin-react";
3import { tanstackRouter } from "@tanstack/router-plugin/vite";3import { tanstackRouter } from "@tanstack/router-plugin/vite";
4import { defineConfig } from "vite";4import { defineConfig } from "vite";
5import { version } from "./package.json" with { type: "json" };
56
6const port = Number(process.env.PORT ?? 5733);7const port = Number(process.env.PORT ?? 5733);
7const sourcemapEnv = process.env.T3CODE_WEB_SOURCEMAP?.trim().toLowerCase();8const sourcemapEnv = process.env.T3CODE_WEB_SOURCEMAP?.trim().toLowerCase();
...@@ -29,6 +30,7 @@ export default defineConfig({...@@ -29,6 +30,7 @@ export default defineConfig({
29 define: {30 define: {
30 // In dev mode, tell the web app where the WebSocket server lives31 // In dev mode, tell the web app where the WebSocket server lives
31 "import.meta.env.VITE_WS_URL": JSON.stringify(process.env.VITE_WS_URL ?? ""),32 "import.meta.env.VITE_WS_URL": JSON.stringify(process.env.VITE_WS_URL ?? ""),
33 "import.meta.env.APP_VERSION": JSON.stringify(version),
32 },34 },
33 resolve: {35 resolve: {
34 tsconfigPaths: true,36 tsconfigPaths: true,