Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions flatpak/com.t3tools.t3code.metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@
<launchable type="desktop-id">com.t3tools.t3code.desktop</launchable>
<url type="homepage">https://t3.codes</url>
<releases>
<release version="0.1.2" date="2026-10-22">
<url type="details">https://github.com/pingdotgg/t3code/releases/tag/v0.1.2</url>
<description>
<p>Update to T3 Code 0.1.2, which ships Electron 44.9.3 upstream.</p>
<p>Settings now offers to reclaim the local database's space until automatic
shrinking is on, and can delete the database kept from before 0.1.0.</p>
</description>
</release>
<release version="0.1.1-1" date="2026-10-21">
<url type="details">https://github.com/pingdotgg/t3code/releases/tag/v0.1.1</url>
<description>
Expand Down
15 changes: 10 additions & 5 deletions flatpak/modules/pnpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ buildsystem: simple
cleanup:
- "*"
build-commands:
# pnpm 12 runs as a native binary that finds its bundled node-gyp in the `dist/` next to it.
- mkdir -p /app/bin /app/lib/pnpm
- cp -a bin dist package.json LICENSE /app/lib/pnpm/
- ln -s ../lib/pnpm/bin/pnpm.mjs /app/bin/pnpm
- ln -s ../lib/pnpm/bin/pnpx.mjs /app/bin/pnpx
- cp -a dist package.json /app/lib/pnpm/
- install -m755 exe/pnpm /app/lib/pnpm/pnpm
- ln -s ../lib/pnpm/pnpm /app/bin/pnpm
sources:
- type: archive
url: https://registry.npmjs.org/pnpm/-/pnpm-11.10.0.tgz
sha256: 620b6605ea4f62fc56a6d0a98733f479071d0321e03e486b522c7e9a74617431
url: https://registry.npmjs.org/pnpm/-/pnpm-12.14.0.tgz
sha256: ea206e35474bf87be9564a85ca70ed1c8ebdc45da55aafb0a3bf09d1ba69b179
- type: archive
url: https://registry.npmjs.org/@pnpm/exe.linux-x64/-/exe.linux-x64-12.14.0.tgz
sha256: 1de98ed2e9621113b0887b06322b461efb9df73d913fc1d151039b10b7117a41
dest: exe
7 changes: 3 additions & 4 deletions flatpak/modules/t3code.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ test-commands:
env -u FLATPAK_ID
pnpm --filter @t3tools/desktop exec vp test run
--exclude src/wsl/DesktopWslEnvironment.test.ts
- pnpm --filter @t3tools/desktop typecheck
- pnpm --filter @t3tools/desktop exec vp run typecheck
- >-
pnpm --filter t3 exec vp test run
src/process/externalLauncher.test.ts
Expand All @@ -58,8 +58,8 @@ test-commands:
sources:
- type: git
url: https://github.com/pingdotgg/t3code.git
tag: v0.1.1
commit: fe27e8e3dc12dcbb108e9a28fd9b8cb65f34ae92
tag: v0.1.2
commit: 044f07257c9684ae4543bd1e1ebf9c394e9e3830
x-checker-data:
type: json
url: https://api.github.com/repos/pingdotgg/t3code/releases/latest
Expand All @@ -81,7 +81,6 @@ sources:
- ../../patches/0010-flatpak-browser-requirements.patch
- ../../patches/0011-flatpak-database-maintenance.patch
- ../../patches/0012-flatpak-update-channel.patch
- ../../patches/0013-electron-security-update.patch
use-git: true
- type: dir
path: ../package
Expand Down
9 changes: 5 additions & 4 deletions flatpak/package/host-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ unset T3CODE_DESKTOP_HTTPS_ENDPOINTS T3CODE_TAILSCALE_SERVE T3CODE_TAILSCALE_SER
cd "$HOME"

export ELECTRON_RUN_AS_NODE=1
# Desktop maintenance runs with the same runtime and sanitized host environment,
# after the desktop has stopped its server. No user-facing CLI is installed.
if [ "${1:-}" = "--compact-database" ]; then
exec "$T3CODE_FLATPAK_SERVER" --require "$T3CODE_FLATPAK_COMPILE_CACHE" "$T3CODE_FLATPAK_ENTRY" flatpak-compact-database --base-dir "$T3CODE_HOME"
# Desktop maintenance runs with the same runtime and sanitized host environment.
# The desktop stops its server first when compacting. No user-facing CLI is installed.
if [ "${1:-}" = "--database-maintenance" ]; then
shift
exec "$T3CODE_FLATPAK_SERVER" --require "$T3CODE_FLATPAK_COMPILE_CACHE" "$T3CODE_FLATPAK_ENTRY" flatpak-database-maintenance --base-dir "$T3CODE_HOME" "$@"
fi

exec "$T3CODE_FLATPAK_SERVER" --require "$T3CODE_FLATPAK_COMPILE_CACHE" "$T3CODE_FLATPAK_ENTRY" --bootstrap-fd 3
28 changes: 14 additions & 14 deletions patches/0001-flatpak-desktop-integration.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/apps/desktop/src/app/DesktopConfig.ts b/apps/desktop/src/app/DesktopConfig.ts
index 773ea2450..8eb05c265 100644
index 773ea24509..8eb05c265a 100644
--- a/apps/desktop/src/app/DesktopConfig.ts
+++ b/apps/desktop/src/app/DesktopConfig.ts
@@ -37,6 +37,7 @@ export const DesktopConfig = Config.all({
Expand All @@ -11,7 +11,7 @@ index 773ea2450..8eb05c265 100644
devServerUrl: Config.URL("VITE_DEV_SERVER_URL").pipe(Config.option),
appUserModelIdOverride: trimmedString("T3CODE_DESKTOP_APP_USER_MODEL_ID"),
diff --git a/apps/desktop/src/app/DesktopEarlyElectronStartup.ts b/apps/desktop/src/app/DesktopEarlyElectronStartup.ts
index 0015e6426..9c792f7ed 100644
index 0015e64267..9c792f7ed3 100644
--- a/apps/desktop/src/app/DesktopEarlyElectronStartup.ts
+++ b/apps/desktop/src/app/DesktopEarlyElectronStartup.ts
@@ -1,3 +1,5 @@
Expand All @@ -35,10 +35,10 @@ index 0015e6426..9c792f7ed 100644
preference,
env: input.env,
diff --git a/apps/desktop/src/app/DesktopEnvironment.test.ts b/apps/desktop/src/app/DesktopEnvironment.test.ts
index fb6c5a8b1..b8be6acf4 100644
index 200745f111..2b9aa94ef0 100644
--- a/apps/desktop/src/app/DesktopEnvironment.test.ts
+++ b/apps/desktop/src/app/DesktopEnvironment.test.ts
@@ -39,6 +39,18 @@ const makeEnvironment = (
@@ -38,6 +38,18 @@ const makeEnvironment = (
) => DesktopEnvironment.DesktopEnvironment.pipe(Effect.provide(layerEnvironment(overrides, env)));

describe("DesktopEnvironment", () => {
Expand All @@ -54,11 +54,11 @@ index fb6c5a8b1..b8be6acf4 100644
+ }),
+ );
+
it.effect("derives state paths and development identity inside Effect", () =>
it.effect("uses the packaged Windows server sidecar as the backend root", () =>
Effect.gen(function* () {
const environment = yield* makeEnvironment(
const environment = yield* makeEnvironment({
diff --git a/apps/desktop/src/app/DesktopEnvironment.ts b/apps/desktop/src/app/DesktopEnvironment.ts
index ecf08255f..04934beb7 100644
index ecf08255fe..04934beb7c 100644
--- a/apps/desktop/src/app/DesktopEnvironment.ts
+++ b/apps/desktop/src/app/DesktopEnvironment.ts
@@ -167,10 +167,14 @@ const make = Effect.fn("desktop.environment.make")(function* (
Expand Down Expand Up @@ -91,7 +91,7 @@ index ecf08255f..04934beb7 100644
appImagePath: config.appImagePath,
defaultDesktopSettings: DesktopAppSettings.resolveDefaultDesktopSettings(input.appVersion),
diff --git a/apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts b/apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts
index 295f63eaf..2e2f315cb 100644
index 854f43c562..9fcc128aac 100644
--- a/apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts
+++ b/apps/desktop/src/app/DesktopLinuxUrlHandler.test.ts
@@ -1,5 +1,5 @@
Expand All @@ -100,8 +100,8 @@ index 295f63eaf..2e2f315cb 100644
+import { assert, describe, it, vi } from "@effect/vitest";
import * as Deferred from "effect/Deferred";
import * as Effect from "effect/Effect";
import * as Fiber from "effect/Fiber";
@@ -159,6 +159,15 @@ const emptyRecording = (): RecordedRegistration => ({
import * as FileSystem from "effect/FileSystem";
@@ -157,6 +157,15 @@ const emptyRecording = (): RecordedRegistration => ({
});

describe("DesktopLinuxUrlHandler", () => {
Expand All @@ -118,7 +118,7 @@ index 295f63eaf..2e2f315cb 100644
const entry = DesktopLinuxUrlHandler.renderUrlHandlerDesktopEntry({
displayName: "T3 Code (Nightly)",
diff --git a/apps/desktop/src/app/DesktopLinuxUrlHandler.ts b/apps/desktop/src/app/DesktopLinuxUrlHandler.ts
index e03418964..bf2c12f4e 100644
index e03418964e..bf2c12f4ef 100644
--- a/apps/desktop/src/app/DesktopLinuxUrlHandler.ts
+++ b/apps/desktop/src/app/DesktopLinuxUrlHandler.ts
@@ -9,6 +9,7 @@ import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner";
Expand All @@ -142,7 +142,7 @@ index e03418964..bf2c12f4e 100644
}
yield* writeDesktopEntry;
diff --git a/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts b/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts
index d27251d7b..cb5dfad04 100644
index 143a6e5fd8..bf37ac682c 100644
--- a/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts
+++ b/apps/desktop/src/app/DesktopPreReadyPlatform.test.ts
@@ -60,6 +60,28 @@ vi.mock("node:child_process", () => ({
Expand Down Expand Up @@ -175,7 +175,7 @@ index d27251d7b..cb5dfad04 100644
appendSwitchMock.mockReset();
getSwitchValueMock.mockReset();
diff --git a/apps/desktop/src/app/DesktopPreReadyPlatform.ts b/apps/desktop/src/app/DesktopPreReadyPlatform.ts
index 58670439a..902fec467 100644
index 58670439a5..902fec4675 100644
--- a/apps/desktop/src/app/DesktopPreReadyPlatform.ts
+++ b/apps/desktop/src/app/DesktopPreReadyPlatform.ts
@@ -9,6 +9,7 @@ import * as Layer from "effect/Layer";
Expand Down Expand Up @@ -279,7 +279,7 @@ index 58670439a..902fec467 100644
Electron.app.setDesktopName(linux.linuxDesktopEntryName);
diff --git a/apps/desktop/src/app/Flatpak.ts b/apps/desktop/src/app/Flatpak.ts
new file mode 100644
index 000000000..006f94e00
index 0000000000..006f94e000
--- /dev/null
+++ b/apps/desktop/src/app/Flatpak.ts
@@ -0,0 +1,5 @@
Expand Down
6 changes: 3 additions & 3 deletions patches/0002-flatpak-host-backend.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/apps/desktop/src/backend/DesktopBackendConfiguration.ts b/apps/desktop/src/backend/DesktopBackendConfiguration.ts
index dadbe8acc..79e41c7b6 100644
index dadbe8acc7..79e41c7b66 100644
--- a/apps/desktop/src/backend/DesktopBackendConfiguration.ts
+++ b/apps/desktop/src/backend/DesktopBackendConfiguration.ts
@@ -1,5 +1,8 @@
Expand Down Expand Up @@ -38,7 +38,7 @@ index dadbe8acc..79e41c7b6 100644

diff --git a/apps/desktop/src/backend/flatpakBackend.test.ts b/apps/desktop/src/backend/flatpakBackend.test.ts
new file mode 100644
index 000000000..cfc536d2e
index 0000000000..cfc536d2e7
--- /dev/null
+++ b/apps/desktop/src/backend/flatpakBackend.test.ts
@@ -0,0 +1,86 @@
Expand Down Expand Up @@ -130,7 +130,7 @@ index 000000000..cfc536d2e
+});
diff --git a/apps/desktop/src/backend/flatpakBackend.ts b/apps/desktop/src/backend/flatpakBackend.ts
new file mode 100644
index 000000000..e912b2119
index 0000000000..e912b2119e
--- /dev/null
+++ b/apps/desktop/src/backend/flatpakBackend.ts
@@ -0,0 +1,56 @@
Expand Down
24 changes: 12 additions & 12 deletions patches/0003-flatpak-host-environment.patch
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
diff --git a/apps/desktop/src/shell/DesktopShellEnvironment.test.ts b/apps/desktop/src/shell/DesktopShellEnvironment.test.ts
index 3adf74bf7..141319707 100644
index 9d12ed5a07..fd0201b2ab 100644
--- a/apps/desktop/src/shell/DesktopShellEnvironment.test.ts
+++ b/apps/desktop/src/shell/DesktopShellEnvironment.test.ts
@@ -126,6 +126,21 @@ function runShellEnvironment(input: {
@@ -118,6 +118,21 @@ function runShellEnvironment(input: {
}

describe("DesktopShellEnvironment", () => {
Expand All @@ -21,11 +21,11 @@ index 3adf74bf7..141319707 100644
+ }).pipe(Effect.tap(() => Effect.sync(() => assert.equal(env.PATH, "/app/bin:/usr/bin"))));
+ });
+
// Explicit opt-in keeps real shell coverage independent of globally installed tools.
it.effect.runIf(process.env.T3_TEST_NU_PATH !== undefined)(
"hydrates the desktop through a renamed Nushell symlink with native export conversions",
it.effect("rejects PATH output from a failed shell and tries the next candidate", () =>
Effect.gen(function* () {
const env: NodeJS.ProcessEnv = { SHELL: "/bin/failing", PATH: "/usr/bin" };
diff --git a/apps/desktop/src/shell/DesktopShellEnvironment.ts b/apps/desktop/src/shell/DesktopShellEnvironment.ts
index 3fdec7932..1182af006 100644
index 3fdec79323..1182af0062 100644
--- a/apps/desktop/src/shell/DesktopShellEnvironment.ts
+++ b/apps/desktop/src/shell/DesktopShellEnvironment.ts
@@ -14,6 +14,7 @@ import * as Stream from "effect/Stream";
Expand All @@ -45,7 +45,7 @@ index 3fdec7932..1182af006 100644
return installWindowsEnvironment(config);
}
diff --git a/apps/desktop/src/updates/DesktopUpdates.test.ts b/apps/desktop/src/updates/DesktopUpdates.test.ts
index 94bfbe44c..9a069527d 100644
index d2f24143fc..3bbff03927 100644
--- a/apps/desktop/src/updates/DesktopUpdates.test.ts
+++ b/apps/desktop/src/updates/DesktopUpdates.test.ts
@@ -1,4 +1,4 @@
Expand All @@ -54,7 +54,7 @@ index 94bfbe44c..9a069527d 100644
import { DESKTOP_UPDATE_RESTART_MARKER_FILE } from "@t3tools/contracts";
import * as Cause from "effect/Cause";
import * as Deferred from "effect/Deferred";
@@ -22,6 +22,28 @@ import * as DesktopUpdates from "./DesktopUpdates.ts";
@@ -21,6 +21,28 @@ import * as DesktopUpdates from "./DesktopUpdates.ts";
import { flushCallbacks, makeHarness } from "./updatesTestHarness.ts";

describe("DesktopUpdates", () => {
Expand All @@ -80,11 +80,11 @@ index 94bfbe44c..9a069527d 100644
+ );
+ });
+
it("preserves complete causes for update poller and event failures", () => {
const cause = Cause.combine(
Cause.fail(new Error("updater failed")),
it.effect("updates Linux .deb installs and leaves other non-AppImage installs off", () =>
Effect.gen(function* () {
const linuxState = (packageType: string | undefined) =>
diff --git a/apps/desktop/src/updates/DesktopUpdates.ts b/apps/desktop/src/updates/DesktopUpdates.ts
index ae3c2588f..0c6557464 100644
index ae3c2588fa..0c65574646 100644
--- a/apps/desktop/src/updates/DesktopUpdates.ts
+++ b/apps/desktop/src/updates/DesktopUpdates.ts
@@ -1,3 +1,4 @@
Expand Down
2 changes: 1 addition & 1 deletion patches/0005-flatpak-build-artifact.patch
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
diff --git a/scripts/build-desktop-artifact.ts b/scripts/build-desktop-artifact.ts
index d2cff4726..1de29fedc 100644
index d2cff47263..1de29fedc6 100644
--- a/scripts/build-desktop-artifact.ts
+++ b/scripts/build-desktop-artifact.ts
@@ -4114,10 +4114,17 @@ const buildDesktopArtifactUnlocked = Effect.fn("buildDesktopArtifactUnlocked")(f
Expand Down
57 changes: 28 additions & 29 deletions patches/0006-flatpak-document-portal-paths.patch
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
diff --git a/apps/desktop/src/electron/ElectronDialog.test.ts b/apps/desktop/src/electron/ElectronDialog.test.ts
index 2ed5a1f2f..aa1b59fde 100644
--- a/apps/desktop/src/electron/ElectronDialog.test.ts
new file mode 100644
index 0000000000..a9675e5e6f
--- /dev/null
+++ b/apps/desktop/src/electron/ElectronDialog.test.ts
@@ -3,7 +3,7 @@ import * as Cause from "effect/Cause";
import * as Effect from "effect/Effect";
import * as Option from "effect/Option";
import type { BrowserWindow } from "electron";
-import { beforeEach, vi } from "vite-plus/test";
@@ -0,0 +1,86 @@
+import { assert, describe, it } from "@effect/vitest";
+import * as Effect from "effect/Effect";
+import * as Option from "effect/Option";
+import { afterEach, beforeEach, vi } from "vite-plus/test";

import * as ElectronDialog from "./ElectronDialog.ts";

@@ -12,6 +12,9 @@ const { showMessageBoxMock, showOpenDialogMock, showErrorBoxMock } = vi.hoisted(
showOpenDialogMock: vi.fn(),
showErrorBoxMock: vi.fn(),
}));
+const { execFileMock } = vi.hoisted(() => ({ execFileMock: vi.fn() }));
+
+import * as ElectronDialog from "./ElectronDialog.ts";
+
+const { showOpenDialogMock, execFileMock } = vi.hoisted(() => ({
+ showOpenDialogMock: vi.fn(),
+ execFileMock: vi.fn(),
+}));
+
+vi.mock("node:child_process", () => ({ execFile: execFileMock }));

vi.mock("electron", () => ({
dialog: {
@@ -26,8 +29,69 @@ describe("ElectronDialog", () => {
showMessageBoxMock.mockReset();
showOpenDialogMock.mockReset();
showErrorBoxMock.mockReset();
+
+vi.mock("electron", () => ({
+ dialog: {
+ showOpenDialog: showOpenDialogMock,
+ },
+}));
+
+describe("ElectronDialog", () => {
+ beforeEach(() => {
+ showOpenDialogMock.mockReset();
+ execFileMock.mockReset();
});
+ });
+
+ afterEach(() => vi.unstubAllEnvs());
+
+ it.effect("returns the host path for a Flatpak folder picker selection", () =>
Expand Down Expand Up @@ -87,12 +89,9 @@ index 2ed5a1f2f..aa1b59fde 100644
+ assert.include((error.cause as Error).message, "could not resolve");
+ }).pipe(Effect.provide(ElectronDialog.layer)),
+ );
+
it.effect("preserves folder picker request context and cause", () =>
Effect.gen(function* () {
const cause = new Error("folder picker failed");
+});
diff --git a/apps/desktop/src/electron/ElectronDialog.ts b/apps/desktop/src/electron/ElectronDialog.ts
index b48953f11..2e868e089 100644
index b48953f117..2e868e0893 100644
--- a/apps/desktop/src/electron/ElectronDialog.ts
+++ b/apps/desktop/src/electron/ElectronDialog.ts
@@ -1,3 +1,7 @@
Expand Down
Loading