Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
d1f0a91
fix(server): walk parent dirs in isGitRepository so subdirectories of…
imabdulazeez May 1, 2026
9a042e5
refactor(server): simplify isGitRepository per review
imabdulazeez May 1, 2026
147aadc
fix(server): check input dir in isGitRepository before walking parents
imabdulazeez May 1, 2026
ab662ce
Rename app stage label from Alpha to AA
imabdulazeez May 5, 2026
4dac9bd
Add setting to disable auto-create PR on push
imabdulazeez May 5, 2026
e1cd96a
Merge branch 'feat/toggle-auto-pr-creation' into aa
imabdulazeez May 5, 2026
ab9842b
Replace 'ref' terminology with 'branch' in git actions
imabdulazeez May 5, 2026
eff43b0
Merge branch 'fix/git-actions-branch-copy' into aa
imabdulazeez May 5, 2026
343e785
Add ability to select fonts for code diffs
imabdulazeez May 5, 2026
c57acc3
Merge branch 'feat/ability-to-select-fonts' into aa
imabdulazeez May 5, 2026
1066e6c
Add terminal font customization
imabdulazeez May 5, 2026
51b4e8c
Reorganize settings into categorized sections
imabdulazeez May 5, 2026
69f9b42
Merge branch 'feat/ability-to-select-fonts' into aa
imabdulazeez May 5, 2026
213a279
Format resolveQuickAction call in GitActionsControl test
imabdulazeez May 6, 2026
9a7fedc
Remove CLAUDE.md symlink
imabdulazeez May 6, 2026
957a626
Add autoCreatePrOnPush to test clientSettings fixture
imabdulazeez May 6, 2026
cd3500b
Add autoCreatePrOnPush to test clientSettings fixtures
imabdulazeez May 6, 2026
8f5f03e
Merge branch 'feat/toggle-auto-pr-creation' into aa
imabdulazeez May 6, 2026
4c0a191
Merge branch 'fix/git-actions-branch-copy' into aa
imabdulazeez May 6, 2026
0b5db8c
Fix clientSettings fixture and apply formatter after merge
imabdulazeez May 6, 2026
594ed43
Link CLAUDE.md to agents.md
imabdulazeez May 6, 2026
45a1f97
Merge upstream/main into aa
imabdulazeez May 6, 2026
9d09998
Fix clipboard write in packaged desktop build
imabdulazeez May 6, 2026
82e3c03
Include build timestamp in desktop artifact filenames
imabdulazeez May 6, 2026
affd002
Merge upstream main into aa
imabdulazeez May 7, 2026
90a454b
Restore message text and attachments when reverting edits
imabdulazeez May 8, 2026
724c6c1
Restructure desktop app with Effect-based modules
imabdulazeez May 8, 2026
561a448
update electron permissions
imabdulazeez May 8, 2026
76934ad
Implement fallback plan capture for text-only plan-mode responses
imabdulazeez May 8, 2026
3f4e22e
Track interaction mode state in Claude adapter
imabdulazeez May 8, 2026
087a96b
Track interaction mode state in Claude adapter
imabdulazeez May 8, 2026
489b001
Merge fix/claude-plan-feedback into aa
imabdulazeez May 8, 2026
53de8b8
Rebrand to A3 and add build timestamp tracking
imabdulazeez May 8, 2026
02f720e
Merge feat/edit-messages into aa
imabdulazeez May 8, 2026
9a2211a
Merge branch 'main' into aa
imabdulazeez May 9, 2026
40c9578
Rename stage label from AA to A3
imabdulazeez May 9, 2026
30d31cf
Add manual plan promotion/revert commands
imabdulazeez May 9, 2026
c23432f
Reformat rawSource type to single line
imabdulazeez May 9, 2026
6af883e
Merge branch 'fix/claude-plan-feedback' into aa
imabdulazeez May 9, 2026
d713c12
Support reverting and re-promoting proposed plans
imabdulazeez May 9, 2026
59c73da
fix: show implement button for promoted Claude plans when session is …
imabdulazeez May 9, 2026
fe21b8f
Update DesktopLifecycle.ts
imabdulazeez May 10, 2026
3f847c6
Create settings.json
imabdulazeez May 10, 2026
932ea06
Merge branch 'main' into aa-2026-05-10
imabdulazeez May 10, 2026
6251b57
Add timeout to desktop shutdown to prevent app hangs
imabdulazeez May 10, 2026
56e4eeb
Prevent plan promotion when user input is pending
imabdulazeez May 10, 2026
6267bef
Switch build timestamps from UTC to local time
imabdulazeez May 10, 2026
7f50a22
Merge branch 'main' into aa-2026-05-12
imabdulazeez May 11, 2026
09cfbf9
Add plan implementation in new thread draft mode
imabdulazeez May 11, 2026
7a423b3
Merge branch 'feat/implement-plan-new-thread-draft' into aa-2026-05-12
imabdulazeez May 11, 2026
b71664f
Support plan reimplementation and sanitize PR bodies
imabdulazeez May 12, 2026
fa4bf81
Refactor checkpoints to delegate to VCS drivers
imabdulazeez May 13, 2026
d522adc
remove zed settings
imabdulazeez May 13, 2026
a145a65
Replace ref terminology with branch in UI
imabdulazeez May 13, 2026
6c2029e
Merge upstream/main into aa/2026-05-13; re-applied fork additions on …
imabdulazeez May 13, 2026
09b88c6
Add setting to expand changed files by default
imabdulazeez May 13, 2026
6d1a36c
chore: add security comments to pr-size.yml and scope release.yml per…
imabdulazeez May 13, 2026
62f73a6
Merge upstream/main into aa/2026-05-13; re-applied fork additions on …
imabdulazeez May 13, 2026
74ae907
Merge upstream/main into aa/2026-05-14; re-applied fork additions on …
imabdulazeez May 14, 2026
2022f1d
Strip workspace dependencies from desktop artifact
imabdulazeez May 14, 2026
7abe321
Add process resource history monitoring
imabdulazeez May 14, 2026
399ae69
Add option to hide unavailable providers in model picker
imabdulazeez May 15, 2026
40ebd04
Add OpenCode provider filter to model picker
imabdulazeez May 15, 2026
46db6c6
Merge OpenCode provider filter
imabdulazeez May 15, 2026
6309e73
Merge upstream/main into aa/2026-05-16; re-applied fork additions on …
imabdulazeez May 16, 2026
bd1182a
Add head repository support to change requests
imabdulazeez May 17, 2026
0501123
Allow customizing prompt instructions for version control generation
imabdulazeez May 17, 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 .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jobs:
NIGHTLY_RUN_NUMBER: ${{ github.run_number }}
run: |
if [[ "${GITHUB_EVENT_NAME}" == "schedule" || ( "${GITHUB_EVENT_NAME}" == "workflow_dispatch" && "${DISPATCH_CHANNEL:-stable}" == "nightly" ) ]]; then
nightly_date="$(date -u -d "$NIGHTLY_DATE" +%Y%m%d)"
nightly_date="$(date -d "$NIGHTLY_DATE" +%Y%m%d)"

node scripts/resolve-nightly-release.ts \
--date "$nightly_date" \
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
"typescript": "catalog:",
"vitest": "catalog:"
},
"productName": "T3 Code (Alpha)"
"productName": "T3 Code (A3)"
}
2 changes: 1 addition & 1 deletion apps/desktop/scripts/electron-launcher.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
const APP_DISPLAY_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)";
const APP_DISPLAY_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (A3)";
const APP_BUNDLE_ID = isDevelopment ? "com.t3tools.t3code.dev" : "com.t3tools.t3code";
const LAUNCHER_VERSION = 2;

Expand Down
7 changes: 4 additions & 3 deletions apps/desktop/src/app/DesktopAppIdentity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const defaultEnvironmentInput = {
isPackaged: true,
resourcesPath: "/Applications/T3 Code.app/Contents/Resources",
runningUnderArm64Translation: false,
buildTimestamp: "20260508-1430",
} satisfies DesktopEnvironment.MakeDesktopEnvironmentInput;

type TestEnvironmentInput = Partial<DesktopEnvironment.MakeDesktopEnvironmentInput> & {
Expand Down Expand Up @@ -156,9 +157,9 @@ describe("DesktopAppIdentity", () => {
const identity = yield* DesktopAppIdentity.DesktopAppIdentity;
yield* identity.configure;

assert.deepEqual(calls.setName, ["T3 Code (Alpha)"]);
assert.equal(calls.setAboutPanelOptions[0]?.applicationName, "T3 Code (Alpha)");
assert.equal(calls.setAboutPanelOptions[0]?.applicationVersion, "1.2.3");
assert.deepEqual(calls.setName, ["T3 Code (A3)"]);
assert.equal(calls.setAboutPanelOptions[0]?.applicationName, "T3 Code (A3)");
assert.equal(calls.setAboutPanelOptions[0]?.applicationVersion, "1.2.3-a3-20260508-1430");
assert.equal(calls.setAboutPanelOptions[0]?.version, "0123456789ab");
assert.deepEqual(calls.setDockIcon, ["/icon.png"]);
}),
Expand Down
3 changes: 2 additions & 1 deletion apps/desktop/src/app/DesktopAppIdentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const COMMIT_HASH_DISPLAY_LENGTH = 12;

const AppPackageMetadata = Schema.Struct({
t3codeCommitHash: Schema.optional(Schema.String),
t3codeBuildTimestamp: Schema.optional(Schema.String),
});
const decodeAppPackageMetadata = Schema.decodeEffect(Schema.fromJsonString(AppPackageMetadata));

Expand Down Expand Up @@ -98,7 +99,7 @@ const make = Effect.gen(function* () {
yield* electronApp.setName(environment.displayName);
yield* electronApp.setAboutPanelOptions({
applicationName: environment.displayName,
applicationVersion: environment.appVersion,
applicationVersion: environment.displayVersion,
version: Option.getOrElse(commitHash, () => "unknown"),
});

Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/app/DesktopEnvironment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const defaultInput = {
isPackaged: false,
resourcesPath: "/Applications/T3 Code.app/Contents/Resources",
runningUnderArm64Translation: false,
buildTimestamp: "20260508-1430",
} satisfies DesktopEnvironment.MakeDesktopEnvironmentInput;

const makeEnvironmentLayer = (
Expand Down
11 changes: 10 additions & 1 deletion apps/desktop/src/app/DesktopEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from "../settings/DesktopAppSettings.ts";
import * as DesktopConfig from "./DesktopConfig.ts";
import { isNightlyDesktopVersion } from "../updates/updateChannels.ts";
import { FORK_STAGE_LABEL, formatForkDisplayVersion } from "./forkBranding.ts";

export interface MakeDesktopEnvironmentInput {
readonly dirname: string;
Expand All @@ -28,6 +29,7 @@ export interface MakeDesktopEnvironmentInput {
readonly isPackaged: boolean;
readonly resourcesPath: string;
readonly runningUnderArm64Translation: boolean;
readonly buildTimestamp: string;
}

export interface DesktopEnvironmentShape {
Expand Down Expand Up @@ -73,6 +75,7 @@ export interface DesktopEnvironmentShape {
readonly resolvePickFolderDefaultPath: (rawOptions: unknown) => Option.Option<string>;
readonly resolveResourcePathCandidates: (fileName: string) => readonly string[];
readonly developmentDockIconPath: string;
readonly displayVersion: string;
}

export class DesktopEnvironment extends Context.Service<
Expand All @@ -90,18 +93,21 @@ function resolveDesktopAppStageLabel(input: {
return "Dev";
}

return isNightlyDesktopVersion(input.appVersion) ? "Nightly" : "Alpha";
return isNightlyDesktopVersion(input.appVersion) ? "Nightly" : FORK_STAGE_LABEL;
}

function resolveDesktopAppBranding(input: {
readonly isDevelopment: boolean;
readonly appVersion: string;
readonly displayVersion: string;
}): DesktopAppBranding {
const stageLabel = resolveDesktopAppStageLabel(input);
return {
baseName: APP_BASE_NAME,
stageLabel,
displayName: `${APP_BASE_NAME} (${stageLabel})`,
displayVersion: input.displayVersion,
appVersion: input.appVersion,
};
}

Expand Down Expand Up @@ -154,9 +160,11 @@ const makeDesktopEnvironment = Effect.fn("desktop.environment.make")(function* (
const baseDir = Option.getOrElse(config.t3Home, () => path.join(homeDirectory, ".t3"));
const rootDir = path.resolve(input.dirname, "../../..");
const appRoot = input.isPackaged ? input.appPath : rootDir;
const displayVersion = formatForkDisplayVersion(input.appVersion, input.buildTimestamp);
const branding = resolveDesktopAppBranding({
isDevelopment,
appVersion: input.appVersion,
displayVersion,
});
const displayName = branding.displayName;
const stateDir = path.join(baseDir, isDevelopment ? "dev" : "userdata");
Expand Down Expand Up @@ -242,6 +250,7 @@ const makeDesktopEnvironment = Effect.fn("desktop.environment.make")(function* (
path.join(resourcesPath, fileName),
],
developmentDockIconPath: path.join(rootDir, "assets", "dev", "blueprint-macos-1024.png"),
displayVersion,
});
});

Expand Down
61 changes: 37 additions & 24 deletions apps/desktop/src/app/DesktopLifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import * as Layer from "effect/Layer";
import * as Ref from "effect/Ref";
import * as Scope from "effect/Scope";

// @effect-diagnostics nodeBuiltinImport:off globalTimers:off
import * as NodeTimers from "node:timers";

import { app as electronAppModule, type Event as ElectronEvent } from "electron";
import type * as Electron from "electron";

import * as DesktopEnvironment from "./DesktopEnvironment.ts";
Expand Down Expand Up @@ -97,40 +101,49 @@ const requestDesktopShutdownAndWait = Effect.fn("desktop.lifecycle.requestShutdo
},
);

const SHUTDOWN_EXIT_TIMEOUT_MS = 5000;

function handleBeforeQuit(
event: Electron.Event,
event: ElectronEvent,
runEffect: <A, E>(effect: Effect.Effect<A, E, DesktopLifecycleRuntimeServices>) => Promise<A>,
allowQuit: () => boolean,
markQuitAllowed: () => void,
getShutdownPromise: () => Promise<void> | null,
setShutdownPromise: (promise: Promise<void>) => void,
): void {
if (allowQuit()) {
void runEffect(
Effect.gen(function* () {
const state = yield* DesktopState.DesktopState;
yield* Ref.set(state.quitting, true);
yield* logLifecycleInfo("before-quit received");
}).pipe(Effect.withSpan("desktop.lifecycle.beforeQuit")),
);
if (getShutdownPromise() !== null) {
event.preventDefault();
return;
}

event.preventDefault();
void runEffect(

const shutdownEffect = runEffect(
Effect.gen(function* () {
const state = yield* DesktopState.DesktopState;
yield* Ref.set(state.quitting, true);
yield* logLifecycleInfo("before-quit received");
yield* requestDesktopShutdownAndWait();
}).pipe(Effect.withSpan("desktop.lifecycle.beforeQuit")),
).finally(() => {
markQuitAllowed();
void runEffect(
Effect.gen(function* () {
const electronApp = yield* ElectronApp.ElectronApp;
yield* electronApp.quit;
}).pipe(Effect.withSpan("desktop.lifecycle.quitAfterShutdown")),
);
);

let timeoutHandle: ReturnType<typeof NodeTimers.setTimeout> | null = null;
const timeoutPromise = new Promise<void>((resolve) => {
timeoutHandle = NodeTimers.setTimeout(resolve, SHUTDOWN_EXIT_TIMEOUT_MS);
});

const racePromise = Promise.race([
shutdownEffect.then(
() => undefined,
() => undefined,
),
timeoutPromise,
]).finally(() => {
if (timeoutHandle !== null) {
NodeTimers.clearTimeout(timeoutHandle);
}
electronAppModule.exit(0);
});

setShutdownPromise(racePromise);
}

function quitFromSignal(
Expand Down Expand Up @@ -189,7 +202,7 @@ export const layer = Layer.succeed(
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const context = yield* Effect.context<DesktopLifecycleRuntimeServices>();
const runEffect = Effect.runPromiseWith(context);
let quitAllowed = false;
let shutdownPromise: Promise<void> | null = null;
yield* electronTheme.onUpdated(() => {
void runEffect(
desktopWindow.syncAppearance.pipe(Effect.withSpan("desktop.lifecycle.themeUpdated")),
Expand All @@ -199,9 +212,9 @@ export const layer = Layer.succeed(
handleBeforeQuit(
event,
runEffect,
() => quitAllowed,
() => {
quitAllowed = true;
() => shutdownPromise,
(promise) => {
shutdownPromise = promise;
},
);
});
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const environmentInput = (baseDir: string) =>
isPackaged: false,
resourcesPath: "/repo/resources",
runningUnderArm64Translation: false,
buildTimestamp: "20260508-1430",
}) satisfies DesktopEnvironment.MakeDesktopEnvironmentInput;

const makeEnvironmentLayer = (baseDir: string) =>
Expand Down
8 changes: 8 additions & 0 deletions apps/desktop/src/app/forkBranding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { DesktopAppStageLabel } from "@t3tools/contracts";

export const FORK_TAG = "a3";
export const FORK_STAGE_LABEL: DesktopAppStageLabel = "A3";

export function formatForkDisplayVersion(pkgVersion: string, buildTimestamp: string): string {
return `${pkgVersion}-${FORK_TAG}-${buildTimestamp}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function makeEnvironmentLayer(
isPackaged: options?.isPackaged ?? true,
resourcesPath: "/missing/resources",
runningUnderArm64Translation: false,
buildTimestamp: "20260508-1430",
}).pipe(
Layer.provide(
Layer.mergeAll(
Expand Down
1 change: 1 addition & 0 deletions apps/desktop/src/backend/DesktopServerExposure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ function makeEnvironmentLayer(baseDir: string, env: Record<string, string | unde
isPackaged: true,
resourcesPath: "/missing/resources",
runningUnderArm64Translation: false,
buildTimestamp: "20260508-1430",
}).pipe(
Layer.provide(
Layer.mergeAll(NodeServices.layer, DesktopConfig.layerTest({ T3CODE_HOME: baseDir, ...env })),
Expand Down
14 changes: 14 additions & 0 deletions apps/desktop/src/electron.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
declare namespace Electron {
interface Session {
setPermissionRequestHandler(
handler:
| ((
webContents: WebContents,
permission: "local-fonts" | "clipboard-sanitized-write" | "clipboard-read",
callback: (permissionGranted: boolean) => void,
details: PermissionRequest,
) => void)
| null,
): void;
}
}
34 changes: 34 additions & 0 deletions apps/desktop/src/electron/ElectronPermissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";

import * as Electron from "electron";

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

const ALLOWED_PERMISSIONS = new Set<string>([
"clipboard-sanitized-write",
"clipboard-read",
"local-fonts",
]);

const install = Effect.acquireRelease(
Effect.sync(() => {
Electron.session.defaultSession.setPermissionRequestHandler(
(_webContents, permission, callback) => {
callback(ALLOWED_PERMISSIONS.has(permission));
},
);
}),
() =>
Effect.sync(() => {
Electron.session.defaultSession.setPermissionRequestHandler(null);
}),
);

export const layer = Layer.effectDiscard(
Effect.gen(function* () {
const app = yield* ElectronApp.ElectronApp;
yield* app.whenReady;
yield* install;
}),
);
30 changes: 27 additions & 3 deletions apps/desktop/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
import * as NodeServices from "@effect/platform-node/NodeServices";
import * as NodeOS from "node:os";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Option from "effect/Option";
import * as Path from "effect/Path";

import * as Electron from "electron";
import { formatBuildTimestamp } from "@t3tools/shared/buildTimestamp";

import * as NetService from "@t3tools/shared/Net";
import { resolveRemoteT3CliPackageSpec } from "@t3tools/ssh/command";
Expand All @@ -18,6 +21,7 @@ import * as DesktopIpc from "./ipc/DesktopIpc.ts";
import * as ElectronApp from "./electron/ElectronApp.ts";
import * as ElectronDialog from "./electron/ElectronDialog.ts";
import * as ElectronMenu from "./electron/ElectronMenu.ts";
import * as ElectronPermissions from "./electron/ElectronPermissions.ts";
import * as ElectronProtocol from "./electron/ElectronProtocol.ts";
import * as DesktopSecretStorage from "./electron/ElectronSafeStorage.ts";
import * as ElectronShell from "./electron/ElectronShell.ts";
Expand Down Expand Up @@ -47,14 +51,33 @@ import * as DesktopWindow from "./window/DesktopWindow.ts";

const desktopEnvironmentLayer = Layer.unwrap(
Effect.gen(function* () {
const metadata = yield* Effect.service(ElectronApp.ElectronApp).pipe(
Effect.flatMap((app) => app.metadata),
);
const electronApp = yield* Effect.service(ElectronApp.ElectronApp);
const metadata = yield* electronApp.metadata;
let buildTimestamp = process.env.T3CODE_BUILD_TIMESTAMP;
if (!buildTimestamp && metadata.isPackaged) {
const path = yield* Path.Path;
const fs = yield* FileSystem.FileSystem;
const packagePath = path.join(metadata.appPath, "package.json");
const fileContent = yield* fs.readFileString(packagePath).pipe(Effect.option);
if (Option.isSome(fileContent)) {
// @effect-diagnostics-next-line tryCatchInEffectGen:off
try {
// @effect-diagnostics-next-line preferSchemaOverJson:off
const packageJson = JSON.parse(fileContent.value);
if (typeof packageJson?.t3codeBuildTimestamp === "string") {
buildTimestamp = packageJson.t3codeBuildTimestamp;
}
} catch {}
}
}
// @effect-diagnostics-next-line globalDateInEffect:off
buildTimestamp = buildTimestamp || formatBuildTimestamp(new Date());
return DesktopEnvironment.layer({
dirname: __dirname,
homeDirectory: NodeOS.homedir(),
platform: process.platform,
processArch: process.arch,
buildTimestamp,
...metadata,
});
}),
Expand Down Expand Up @@ -137,6 +160,7 @@ const desktopApplicationLayer = Layer.mergeAll(
DesktopLifecycle.layer,
DesktopApplicationMenu.layer,
DesktopShellEnvironment.layer,
ElectronPermissions.layer,
desktopSshLayer,
).pipe(Layer.provideMerge(DesktopUpdates.layer), Layer.provideMerge(desktopBackendLayer));

Expand Down
Loading
Loading