Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0ff87f2
fix(web): keep citation comment when popover is dismissed (#10831)
flamboh Sep 20, 2026
c14f601
fix(web): keep narrow chat headers readable and aligned (#12453)
shivamhwp Sep 20, 2026
fa1e171
refactor(observability): hold OTLP export settings per signal (#12657)
yordis Sep 20, 2026
ead1dee
fix(web): explain what enabling network access means in its confirmat…
Mnigos Sep 20, 2026
9f0c9f7
fix(web): reuse current PR status in the sidebar (#12545)
flamboh Sep 20, 2026
6a699f0
fix(web): stabilize pull request loading layout (#12721)
flamboh Sep 20, 2026
55c2427
fix(desktop): align preview recording cursors and show input feedback…
juliusmarminge Sep 20, 2026
7ade2d2
fix(web): the Run on / Workspace menu closes after a pick (#12685)
Mnigos Sep 20, 2026
3cfebf4
fix(web): keep portaled menus clickable over Electron drag regions (#…
maria-rcks Sep 20, 2026
5d9e27a
fix(web): render citations in queued messages (#12403)
maria-rcks Sep 20, 2026
2d8f9a8
fix(web): keep the timeline still when the resting composer expands (…
flamboh Sep 20, 2026
45e06f4
fix: composer hero reads project name to screen readers (#12397)
Leos-Khai Sep 20, 2026
f6cc6bc
fix(mobile): respect word wrap in diffs (#12590)
jakeleventhal Sep 20, 2026
adcd908
fix(web): allow full contrast in assistant replies (#12405)
maria-rcks Sep 20, 2026
e9f0d84
chore(sync): merge upstream main into Fold
BreakTheBeta Sep 20, 2026
ce5922b
docs(operations): record how Fold syncs with upstream
BreakTheBeta Sep 20, 2026
18696bd
Merge remote-tracking branch 'origin/main' into sync-upstream-main
BreakTheBeta Sep 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ T3 Code Fold extends [T3 Code](https://github.com/pingdotgg/t3code) with a folda

## Extra features

Compared with upstream `main` at [08463e2c40](https://github.com/pingdotgg/t3code/commit/08463e2c40), reviewed **9 September 2026**. These tables describe the code on Fold's `main`; an older published installer may not include every change.
Compared with upstream `main` at [adcd90858c](https://github.com/pingdotgg/t3code/commit/adcd90858c), synced **21 September 2026**. These tables describe the code on Fold's `main`; an older published installer may not include every change.

### Agents, voice, and compatibility

Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/ipc/channels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,5 @@ export const PREVIEW_POINTER_EVENT_CHANNEL = "desktop:preview-pointer-event";
export const MAC_PERMISSION_HELPER_CHANNEL = "desktop:mac-permission-helper";

export const CHECK_SYSTEM_PERMISSION_CHANNEL = "desktop:check-system-permission";

export const PREVIEW_RECORDING_INPUT_CHANNEL = "desktop:preview-recording-input";
25 changes: 20 additions & 5 deletions apps/desktop/src/ipc/methods/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ import {
} from "@t3tools/contracts";
import * as Effect from "effect/Effect";
import * as Schema from "effect/Schema";
import * as Option from "effect/Option";
import * as NodeURL from "node:url";

import * as ElectronWindow from "../../electron/ElectronWindow.ts";
import * as BrowserImport from "../../preview/BrowserImport/BrowserImport.ts";
import * as PreviewManager from "../../preview/Manager.ts";
import * as DesktopClientSettings from "../../settings/DesktopClientSettings.ts";
import { PREVIEW_WEBVIEW_PREFERENCES } from "../../preview/WebviewPreferences.ts";
import * as IpcChannels from "../channels.ts";
import * as DesktopIpc from "../DesktopIpc.ts";
Expand All @@ -50,6 +52,9 @@ export const installPreviewEventForwarding = Effect.fn(
yield* manager.subscribeRecordingFrames((frame) =>
electronWindow.sendAll(IpcChannels.PREVIEW_RECORDING_FRAME_CHANNEL, frame),
);
yield* manager.subscribeRecordingInputs((event) =>
electronWindow.sendAll(IpcChannels.PREVIEW_RECORDING_INPUT_CHANNEL, event),
);
yield* manager.subscribePointerEvents((event) =>
electronWindow.sendAll(IpcChannels.PREVIEW_POINTER_EVENT_CHANNEL, event),
);
Expand Down Expand Up @@ -180,11 +185,21 @@ export const cancelPickElement = tabMethod(
"desktop.ipc.preview.cancelPickElement",
(manager, tabId) => manager.cancelPickElement(tabId),
);
export const startRecording = tabMethod(
IpcChannels.PREVIEW_RECORDING_START_CHANNEL,
"desktop.ipc.preview.startRecording",
(manager, tabId) => manager.startRecording(tabId),
);
export const startRecording = DesktopIpc.makeIpcMethod({
channel: IpcChannels.PREVIEW_RECORDING_START_CHANNEL,
payload: DesktopPreviewTabInputSchema,
result: Schema.Void,
handler: Effect.fn("desktop.ipc.preview.startRecording")(function* ({ tabId }) {
const manager = yield* PreviewManager.PreviewManager;
const store = yield* DesktopClientSettings.DesktopClientSettings;
const settings = yield* store.get;
const options = Option.map(settings, (value) => ({
showKeyPresses: value.browserRecordingShowKeyPresses,
showMousePresses: value.browserRecordingShowMousePresses,
}));
yield* manager.startRecording(tabId, Option.getOrUndefined(options));
}),
});
export const stopRecording = tabMethod(
IpcChannels.PREVIEW_RECORDING_STOP_CHANNEL,
"desktop.ipc.preview.stopRecording",
Expand Down
10 changes: 10 additions & 0 deletions apps/desktop/src/preload.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
DesktopBridge,
DesktopPreviewPointerEvent,
DesktopPreviewRecordingInputEvent,
DesktopPreviewRecordingFrame,
DesktopPreviewTabState,
DesktopSnapShotEvent,
Expand Down Expand Up @@ -327,6 +328,15 @@ contextBridge.exposeInMainWorld("desktopBridge", {
ipcRenderer.invoke(IpcChannels.PREVIEW_PICTURE_IN_PICTURE_CLOSE_CHANNEL, { tabId }),
},
recording: {
onInput: (listener) => {
const wrappedListener = (_event: Electron.IpcRendererEvent, event: unknown) => {
if (typeof event !== "object" || event === null) return;
listener(event as DesktopPreviewRecordingInputEvent);
};
ipcRenderer.on(IpcChannels.PREVIEW_RECORDING_INPUT_CHANNEL, wrappedListener);
return () =>
ipcRenderer.removeListener(IpcChannels.PREVIEW_RECORDING_INPUT_CHANNEL, wrappedListener);
},
startScreencast: (tabId) =>
ipcRenderer.invoke(IpcChannels.PREVIEW_RECORDING_START_CHANNEL, { tabId }),
stopScreencast: (tabId) =>
Expand Down
5 changes: 5 additions & 0 deletions apps/desktop/src/preview/GuestProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ export const ANNOTATION_CAPTURED_CHANNEL = "preview:annotation-captured";
export const ANNOTATION_THEME_CHANNEL = "preview:annotation-theme";
export const HUMAN_INPUT_CHANNEL = "preview:human-input";
export const MOUSE_NAVIGATE_CHANNEL = "preview:mouse-navigate";
export const RECORDING_CURSOR_CHANNEL = "preview:recording-cursor";
export const RECORDING_POINTER_CHANNEL = "preview:recording-pointer";
export const RECORDING_KEY_CHANNEL = "preview:recording-key";
export const RECORDING_INPUT_CHANNEL = "preview:recording-input";
export const RECORDING_CONTROLLER_CHANNEL = "preview:recording-controller";
Loading
Loading