From bfc69e4b4de12cd9867972dc802936acfb219b74 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Fri, 7 Aug 2026 12:35:07 +0200 Subject: [PATCH 1/4] Bump mobile app version to 1.0.2 (#5588) --- apps/mobile/app.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/mobile/app.config.ts b/apps/mobile/app.config.ts index 9a51373cf..c684689fb 100644 --- a/apps/mobile/app.config.ts +++ b/apps/mobile/app.config.ts @@ -161,7 +161,7 @@ const config: ExpoConfig = { slug: "t3-code", platforms: ["ios", "android"], scheme: variant.scheme, - version: "1.0.1", + version: "1.0.2", runtimeVersion: { // Fingerprint (not appVersion) so an OTA only reaches binaries whose native // project — native deps, config plugins, AND patches/ — matches the update. From 61b51ae0e343afc42ba0424d4d74b4f9a216d620 Mon Sep 17 00:00:00 2001 From: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:24:11 +0530 Subject: [PATCH 2/4] feat(web): click the pin icon to unpin a thread (#5578) --- apps/web/src/components/SidebarV2.tsx | 45 ++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/apps/web/src/components/SidebarV2.tsx b/apps/web/src/components/SidebarV2.tsx index 590ca9cb5..409d6bef9 100644 --- a/apps/web/src/components/SidebarV2.tsx +++ b/apps/web/src/components/SidebarV2.tsx @@ -403,8 +403,12 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { snoozeSupported: boolean; // Renders the pin glyph. Pinned cards keep the full settle/snooze quick // actions: settling clears the pin server-side, and snoozing hides the - // card until wake with the pin intact underneath. Pin/unpin themselves - // live in the context menu only. + // card until wake with the pin intact underneath. The glyph is also the + // in-row pin state cue (the pinned block has no header), so it always + // shows while pinned; it only becomes a clickable unpin quick-action once + // the pinning capability is confirmed, and stays a passive marker while + // the descriptor is not loaded. Pinning itself lives in the context menu. + pinningSupported: boolean; isPinned: boolean; // Compact wake countdown ("2h") for rows in the snoozed shelf. snoozeWakeLabelText: string | null; @@ -432,6 +436,7 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { onUnsettle: (threadRef: ScopedThreadRef) => void; onSnooze: (threadRef: ScopedThreadRef, preset: SnoozePreset) => void; onUnsnooze: (threadRef: ScopedThreadRef) => void; + onUnpin: (threadRef: ScopedThreadRef) => void; onAcknowledgeWoke: (threadRef: ScopedThreadRef, visitedAt: string) => void; onChangeRequestState: (threadKey: string, state: "open" | "closed" | "merged" | null) => void; }) { @@ -450,6 +455,7 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { onThreadClick, onUnsettle, onUnsnooze, + onUnpin, renamingTitle, thread, variant, @@ -704,6 +710,14 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { }, [onUnsnooze, threadRef], ); + const handleUnpinClick = useCallback( + (event: ReactMouseEvent) => { + event.preventDefault(); + event.stopPropagation(); + onUnpin(threadRef); + }, + [onUnpin, threadRef], + ); const handleSnoozePreset = useCallback( (preset: SnoozePreset) => { onSnooze(threadRef, preset); @@ -1001,11 +1015,23 @@ const SidebarV2Row = memo(function SidebarV2Row(props: { )} {props.isPinned ? ( - + props.pinningSupported ? ( + + ) : ( + + ) ) : null} {/* The visible state owns this slot's width: status at rest, actions on hover/keyboard focus or while the popover is open. Keeping @@ -3080,6 +3106,10 @@ export default function SidebarV2() { serverConfigs.get(thread.environmentId)?.environment.capabilities .threadSnooze === true } + pinningSupported={ + serverConfigs.get(thread.environmentId)?.environment.capabilities + .threadPinning === true + } isPinned={section === "pinned"} snoozeWakeLabelText={ section === "snoozed" && thread.snoozedUntil != null @@ -3120,6 +3150,7 @@ export default function SidebarV2() { onUnsettle={attemptUnsettle} onSnooze={attemptSnooze} onUnsnooze={attemptUnsnooze} + onUnpin={attemptUnpin} onAcknowledgeWoke={acknowledgeWoke} onChangeRequestState={handleChangeRequestState} /> From 239ef1c54df2f657912ccb5b8e25193d49d90417 Mon Sep 17 00:00:00 2001 From: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> Date: Fri, 7 Aug 2026 16:24:36 +0530 Subject: [PATCH 3/4] fix(web): show the correctly matching shortcut in new thread button's tooltip (#5594) --- apps/web/src/components/SidebarV2.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/web/src/components/SidebarV2.tsx b/apps/web/src/components/SidebarV2.tsx index 409d6bef9..81d883508 100644 --- a/apps/web/src/components/SidebarV2.tsx +++ b/apps/web/src/components/SidebarV2.tsx @@ -2816,11 +2816,13 @@ export default function SidebarV2() { openCommandPalette({ open: "new-thread-in" }); }, [isMobile, newThreadContext, projectGroups.length, setOpenMobile]); - // Same resolution as v1: prefer the local-thread binding, fall back to - // chat.new, no platform gating — web users have working shortcuts too. + // The button mirrors chat.new: in multi-project setups both route through + // the command palette's "New thread in..." picker, and in single-project + // setups both create immediately. chat.newLocal always creates directly, so + // it is only a correct label when chat.new is unbound. const newThreadShortcutLabel = - shortcutLabelForCommand(keybindings, "chat.newLocal") ?? - shortcutLabelForCommand(keybindings, "chat.new"); + shortcutLabelForCommand(keybindings, "chat.new") ?? + shortcutLabelForCommand(keybindings, "chat.newLocal"); return ( <> From be1a836745395286cbd392512179ab5816f538ba Mon Sep 17 00:00:00 2001 From: "t3-code[bot]" <269035359+t3-code[bot]@users.noreply.github.com> Date: Fri, 7 Aug 2026 11:50:54 +0000 Subject: [PATCH 4/4] chore(release): prepare v0.0.32 --- apps/desktop/package.json | 2 +- apps/server/package.json | 2 +- apps/web/package.json | 2 +- packages/contracts/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 152696542..a69cda53b 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,6 +1,6 @@ { "name": "@t3tools/desktop", - "version": "0.0.31", + "version": "0.0.32", "private": true, "type": "module", "main": "dist-electron/main.cjs", diff --git a/apps/server/package.json b/apps/server/package.json index 8e7b5b385..360f00569 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "t3", - "version": "0.0.31", + "version": "0.0.32", "license": "MIT", "repository": { "type": "git", diff --git a/apps/web/package.json b/apps/web/package.json index 0a2f0d8e8..f396bff7a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@t3tools/web", - "version": "0.0.31", + "version": "0.0.32", "private": true, "type": "module", "scripts": { diff --git a/packages/contracts/package.json b/packages/contracts/package.json index c3bd81902..357156ec0 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -1,6 +1,6 @@ { "name": "@t3tools/contracts", - "version": "0.0.31", + "version": "0.0.32", "private": true, "files": [ "dist"