Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
f83d73b
fix(server): fall back to direct fd read on EACCES bootstrap
Jgratton24 May 11, 2026
0ae9a14
feat(desktop): add WSL backend mode
Jgratton24 May 11, 2026
3b9f86c
fix(desktop): address bot review findings on WSL backend swap
Jgratton24 May 11, 2026
80eddbb
fix(desktop): clear swap flow timer in finally + drop duplicate env-s…
Jgratton24 May 11, 2026
3b18e6d
fix(desktop): resolve WSL user home for tilde paths, fix select value…
Jgratton24 May 11, 2026
b6c25ca
fix(desktop): namespace backend-runtime select sentinels and drop red…
Jgratton24 May 11, 2026
4506e73
fix(desktop): treat re-pick of resolved-default distro as a no-op
Jgratton24 May 11, 2026
6d32481
fix(desktop): widen swap flow ceiling to cover stacked rollback waits
Jgratton24 May 11, 2026
e15edd9
fix(desktop): drop dead WslConfig.enabled and extend toast suppressio…
Jgratton24 May 11, 2026
cb8fbe5
fix(desktop): baseline welcome env-id from the atom to avoid immediat…
Jgratton24 May 11, 2026
4f3a90c
fix(desktop): preserve existing WSLENV entries
Jgratton24 May 16, 2026
b20a966
feat(desktop): scaffold DesktopBackendPool for concurrent backends
Jgratton24 May 16, 2026
a8fc784
feat(desktop): reshape DesktopBackendManager into per-instance factory
Jgratton24 May 16, 2026
425c7d0
feat(desktop): move backend-ready latch from DesktopState onto the wi…
Jgratton24 May 16, 2026
563820e
feat(desktop): route backend child output through a per-instance log …
Jgratton24 May 16, 2026
a0eaf56
feat(desktop): add register/unregister to DesktopBackendPool
Jgratton24 May 16, 2026
b162219
feat(desktop): replace wslMode swap toggle with wslBackendEnabled
Jgratton24 May 17, 2026
31ce3ad
feat(desktop): split DesktopBackendConfiguration into primary + wsl r…
Jgratton24 May 17, 2026
627c80c
feat(desktop): orchestrate the WSL backend as a second pool instance
Jgratton24 May 17, 2026
3fe02a4
docs(desktop): update DesktopBackendPool header for step-5 state
Jgratton24 May 17, 2026
bad6604
feat(desktop): widen local-environment bootstrap IPC to return all in…
Jgratton24 May 17, 2026
5d80468
feat(desktop): route pickFolder by target environment id
Jgratton24 May 17, 2026
eb5a03e
feat(web): replace WSL swap dialog with a toggle + distro picker
Jgratton24 May 17, 2026
60de6af
docs(desktop): refresh DesktopBackendPool header for steps 6-8 state
Jgratton24 May 17, 2026
1c7e787
feat(web): register WSL backend as a desktop-local environment
Jgratton24 May 17, 2026
38e8477
feat(web): allow "Open from file manager" against desktop-local envs
Jgratton24 May 17, 2026
c17897b
fix(web): write WSL bearer before upserting record to avoid auth race
Jgratton24 May 17, 2026
0e1d78e
docs(desktop): record final state + browser validation in pool docblock
Jgratton24 May 17, 2026
df23691
fix(desktop): route WSL renderer fetches through the distro's eth0 IP
Jgratton24 May 18, 2026
2c1620d
fix(server): make the desktop-bootstrap grant reusable for 24h
Jgratton24 May 18, 2026
24b012d
fix(web): retry local-secondary reconcile during WSL cold boot
Jgratton24 May 18, 2026
ad7e3d7
fix(web): use a container icon for desktopLocal threads in the sidebar
Jgratton24 May 18, 2026
0dbdd9f
fix(web): keep auto-retrying when the WSL bootstrap hasn't appeared yet
Jgratton24 May 18, 2026
943e1ed
fix(web): use container icon on desktopLocal-only project headers
Jgratton24 May 18, 2026
6bf864d
fix(web): timeout each WSL register attempt + expose reconciler trace
Jgratton24 May 18, 2026
c47ec5d
feat(web): show a sidebar status alert while WSL backend is connecting
Jgratton24 May 18, 2026
3558e21
fix(web): keep WSL connecting indicator steady between retry attempts
Jgratton24 May 18, 2026
a7a2e1b
fix(web): drop per-thread container icon when the whole project is WSL
Jgratton24 May 18, 2026
449e18f
feat(web): confirm before disable / distro-switch when WSL has state
Jgratton24 May 18, 2026
e00ad61
feat: add wsl-only mode + project icon dedup
Jgratton24 May 18, 2026
3c82c95
feat: auto-restart on wsl-only toggle
Jgratton24 May 18, 2026
d71f3b1
feat(web): consolidate WSL backend toggle and distro picker into one …
Jgratton24 May 18, 2026
1ebb0e5
fix(desktop): load renderer from primary's real URL, not local exposure
Jgratton24 May 18, 2026
05c5295
feat(web): pick WSL mode at enable time, clean up Off-from-wsl-only path
Jgratton24 May 18, 2026
aebb4fa
perf(web): park the local-secondary auto-retry on hosts with no WSL
Jgratton24 May 18, 2026
c3374a8
fix: review feedback from PR #2751
Jgratton24 May 18, 2026
ba31706
fix(desktop): stop every pool instance before update install, not jus…
Jgratton24 May 18, 2026
8a55a55
fix(desktop): stop every pool instance on normal shutdown, not just p…
Jgratton24 May 18, 2026
ce93b7a
fix(desktop): use loopback for WSL backend URL when in mirrored mode
Jgratton24 May 18, 2026
b62348b
fix(desktop): hide preflight-failed bootstraps + serialize WSL reconcile
Jgratton24 May 18, 2026
7e1368d
Merge remote-tracking branch 'upstream/main' into josh/desktop-wsl-pa…
Jgratton24 May 28, 2026
d4df9bb
Merge remote-tracking branch 'upstream/main' into josh/desktop-wsl-pa…
Jgratton24 May 28, 2026
9df7012
Merge remote-tracking branch 'upstream/main' into josh/desktop-wsl-pa…
Jgratton24 May 28, 2026
604de5d
fix(desktop): don't let spec.onShutdown abort stop() teardown
Jgratton24 May 28, 2026
ee7c0f8
refactor(desktop): single source of truth for the wsl: instance-id pr…
Jgratton24 May 28, 2026
a934809
Merge remote-tracking branch 'upstream/main' into josh/desktop-wsl-pa…
Jgratton24 May 29, 2026
da200cf
fix(desktop): two bugbot follow-ups on parallel-backends scaffolding
Jgratton24 May 29, 2026
3a5c764
Merge upstream/main into josh/desktop-wsl-parallel-backends
Jgratton24 May 31, 2026
defdf57
fix(desktop): fall back to Windows primary when wsl-only but WSL unav…
Jgratton24 May 31, 2026
d2b68cd
fix(desktop): log window-open failures after backend readiness
Jgratton24 Jun 1, 2026
2462f0e
fix(web): give a recovery control when WSL becomes unavailable
Jgratton24 Jun 1, 2026
3be6625
fix(desktop): make bootstrap-token get-or-create atomic
Jgratton24 Jun 1, 2026
d729b00
fix(desktop): primary label follows the resolved backend, not just se…
Jgratton24 Jun 1, 2026
c61ea48
Fix WSL picker and backend restart edge cases
Jgratton24 Jun 1, 2026
d84971a
Fix backend shutdown edge cases
Jgratton24 Jun 1, 2026
bbc10df
Resolve primary backend label lazily
Jgratton24 Jun 2, 2026
9752f9e
fix(desktop): resolve WSL availability once so the sync IPC path is safe
Jgratton24 Jun 2, 2026
b9e12d3
Improve WSL project opening from command palette
Jgratton24 Jun 2, 2026
e3448d0
Avoid duplicate backend shutdown notifications
Jgratton24 Jun 2, 2026
43187e6
Merge remote-tracking branch 'origin/main' into pr-2751
Jgratton24 Jun 2, 2026
2afae37
fix(desktop): apply WSL distro changes in wsl-only mode + unblock rec…
Jgratton24 Jun 3, 2026
ae03db4
Merge upstream/main into josh/desktop-wsl-parallel-backends
Jgratton24 Jun 5, 2026
993261f
fix(desktop): call handleBackendReady with URL in off-origin nav test
Jgratton24 Jun 5, 2026
56c0512
fix(desktop): tolerate numeric networkInterfaces family in mirrored-m…
Jgratton24 Jun 5, 2026
7d15110
fix(desktop): preserve existing WSLENV verbatim when forwarding secrets
Jgratton24 Jun 5, 2026
adaa183
Merge remote-tracking branch 'upstream/main' into josh/desktop-wsl-pa…
Jgratton24 Jun 5, 2026
3ca0696
test: point WSL test imports at vite-plus/test after upstream sync
Jgratton24 Jun 5, 2026
bd82399
refactor(desktop): use Effect.orElseSucceed for WSL probe fallbacks
Jgratton24 Jun 5, 2026
6ebdc74
Merge remote-tracking branch 'upstream/main' into josh/desktop-wsl-pa…
Jgratton24 Jun 6, 2026
19c2146
fix(desktop): resolve nvm/fnm/asdf-managed node for the WSL backend
Jgratton24 Jun 7, 2026
383d41c
fix(desktop): cap WSL preflight failures, surface them, fall back to …
Jgratton24 Jun 7, 2026
fe77570
fix(desktop): surface WSL preflight failures cleanly
Jgratton24 Jun 7, 2026
aba2f1b
fix(desktop): reuse SSH node resolver for WSL
Jgratton24 Jun 7, 2026
ac4d02e
fix(web): retry local secondary registration after connect failure
Jgratton24 Jun 7, 2026
d72c85a
fix(desktop): retry idle WSL backend after preflight cap
Jgratton24 Jun 7, 2026
b7bbad9
fix(desktop): pass WSL node engine range to resolver
Jgratton24 Jun 7, 2026
495c2dd
fix(desktop): clear stale WSL readiness state
Jgratton24 Jun 7, 2026
382d699
fix(desktop): relaunch when enabling WSL-only backend
Jgratton24 Jun 7, 2026
e560f70
fix(desktop): keep WSL fallback state in memory
Jgratton24 Jun 7, 2026
3d04133
fix(desktop): clear WSL-only state when disabling WSL
Jgratton24 Jun 7, 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
28 changes: 23 additions & 5 deletions apps/desktop/src/app/DesktopApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { installDesktopIpcHandlers } from "../ipc/DesktopIpcHandlers.ts";
import * as DesktopAppIdentity from "./DesktopAppIdentity.ts";
import * as DesktopCloudAuth from "./DesktopCloudAuth.ts";
import * as DesktopApplicationMenu from "../window/DesktopApplicationMenu.ts";
import * as DesktopBackendManager from "../backend/DesktopBackendManager.ts";
import * as DesktopBackendPool from "../backend/DesktopBackendPool.ts";
import * as DesktopEnvironment from "./DesktopEnvironment.ts";
import * as DesktopLifecycle from "./DesktopLifecycle.ts";
import * as DesktopObservability from "./DesktopObservability.ts";
Expand All @@ -22,6 +22,7 @@ import * as DesktopAppSettings from "../settings/DesktopAppSettings.ts";
import * as DesktopShellEnvironment from "../shell/DesktopShellEnvironment.ts";
import * as DesktopState from "./DesktopState.ts";
import * as DesktopUpdates from "../updates/DesktopUpdates.ts";
import * as DesktopWslBackend from "../wsl/DesktopWslBackend.ts";

const DEFAULT_DESKTOP_BACKEND_PORT = 3773;
const MAX_TCP_PORT = 65_535;
Expand Down Expand Up @@ -132,11 +133,13 @@ const fatalStartupCause = <E>(stage: string, cause: Cause.Cause<E>) =>
handleFatalStartupError(stage, Cause.pretty(cause)).pipe(Effect.andThen(Effect.failCause(cause)));

const bootstrap = Effect.gen(function* () {
const backendManager = yield* DesktopBackendManager.DesktopBackendManager;
const pool = yield* DesktopBackendPool.DesktopBackendPool;
const primaryBackend = yield* pool.primary;
const state = yield* DesktopState.DesktopState;
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const desktopSettings = yield* DesktopAppSettings.DesktopAppSettings;
const serverExposure = yield* DesktopServerExposure.DesktopServerExposure;
const wslBackend = yield* DesktopWslBackend.DesktopWslBackend;
yield* logBootstrapInfo("bootstrap start");

if (environment.isDevelopment && Option.isNone(environment.configuredBackendPort)) {
Expand Down Expand Up @@ -180,8 +183,13 @@ const bootstrap = Effect.gen(function* () {
yield* logBootstrapInfo("bootstrap ipc handlers registered");

if (!(yield* Ref.get(state.quitting))) {
yield* backendManager.start;
yield* primaryBackend.start;
yield* logBootstrapInfo("bootstrap backend start requested");
// Bring up the WSL backend if the user previously enabled it. The
// primary is already starting; reconcile fires off the WSL register
// in parallel rather than blocking primary readiness on a possibly
// slow first wsl.exe spawn.
yield* Effect.forkScoped(wslBackend.reconcile);
}
}).pipe(Effect.withSpan("desktop.bootstrap"));

Expand Down Expand Up @@ -230,10 +238,20 @@ const scopedProgram = Effect.scoped(
yield* Effect.annotateCurrentSpan({ scope: "desktop", runId });

const shutdown = yield* DesktopLifecycle.DesktopShutdown;
const backendManager = yield* DesktopBackendManager.DesktopBackendManager;

yield* Effect.addFinalizer(() =>
backendManager.stop().pipe(Effect.ensuring(shutdown.markComplete)),
Effect.gen(function* () {
const pool = yield* DesktopBackendPool.DesktopBackendPool;
// Stop every backend in the pool, not just the primary. The
// electronApp.quit() path can race ahead of the layer-scope
// cascade, so leaving the WSL instance for its parent scope
// finalizer means it gets hard-killed by the OS instead of
// receiving SIGTERM + grace. Stops run concurrently.
const instances = yield* pool.list;
yield* Effect.forEach(instances, (instance) => instance.stop(), {
concurrency: "unbounded",
});
}).pipe(Effect.ensuring(shutdown.markComplete)),
);

yield* startup;
Expand Down
5 changes: 4 additions & 1 deletion apps/desktop/src/app/DesktopObservability.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ describe("DesktopObservability", () => {
}).pipe(Effect.provide(environmentLayer));

yield* Effect.gen(function* () {
const outputLog = yield* DesktopObservability.DesktopBackendOutputLog;
const factory = yield* DesktopObservability.DesktopBackendOutputLogFactory;
const outputLog = yield* factory.forInstance("primary");
yield* outputLog.writeSessionBoundary({
phase: "START",
details: "pid=123 port=3773 cwd=/repo",
Expand All @@ -145,13 +146,15 @@ describe("DesktopObservability", () => {
assert.equal(boundary.level, "INFO");
assert.equal(boundary.annotations.component, "desktop-backend-child");
assert.equal(boundary.annotations.runId, "test-run");
assert.equal(boundary.annotations.instanceId, "primary");
assert.equal(boundary.annotations.phase, "START");
assert.equal(boundary.annotations.details, "pid=123 port=3773 cwd=/repo");

assert.equal(output.message, "backend child process output");
assert.equal(output.level, "INFO");
assert.equal(output.annotations.component, "desktop-backend-child");
assert.equal(output.annotations.runId, "test-run");
assert.equal(output.annotations.instanceId, "primary");
assert.equal(output.annotations.stream, "stdout");
assert.equal(output.annotations.text, "hello server\n");
}).pipe(
Expand Down
174 changes: 135 additions & 39 deletions apps/desktop/src/app/DesktopObservability.ts
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PRIMARY_LOCAL_ENVIRONMENT_ID } from "@t3tools/contracts";
import { makeLocalFileTracer, makeTraceSink } from "@t3tools/shared/observability";
import { parsePersistedServerObservabilitySettings } from "@t3tools/shared/serverSettings";
import * as Context from "effect/Context";
Expand All @@ -13,7 +14,9 @@ import * as PlatformError from "effect/PlatformError";
import * as References from "effect/References";
import * as Ref from "effect/Ref";
import * as Schema from "effect/Schema";
import * as Scope from "effect/Scope";
import * as Semaphore from "effect/Semaphore";
import * as SynchronizedRef from "effect/SynchronizedRef";
import * as Tracer from "effect/Tracer";
import { OtlpSerialization, OtlpTracer } from "effect/unstable/observability";

Expand All @@ -40,10 +43,23 @@ export interface DesktopBackendOutputLogShape {
) => Effect.Effect<void>;
}

export class DesktopBackendOutputLog extends Context.Service<
DesktopBackendOutputLog,
DesktopBackendOutputLogShape
>()("@t3tools/desktop/app/DesktopObservability/DesktopBackendOutputLog") {}
// Factory for per-instance backend output logs. `forInstance(id)` returns
// a writer that targets a distinct rotating log file — the primary
// instance keeps `server-child.log` so the historical path stays stable
// for ops; other instances get `server-child-<sanitized-id>.log`.
//
// Writers are cached per id within a single factory instance so repeated
// `forInstance` calls (e.g. during a backend restart that re-resolves
// services) reuse the same rotating writer rather than racing each other
// on the same file.
export interface DesktopBackendOutputLogFactoryShape {
readonly forInstance: (id: string) => Effect.Effect<DesktopBackendOutputLogShape>;
}

export class DesktopBackendOutputLogFactory extends Context.Service<
DesktopBackendOutputLogFactory,
DesktopBackendOutputLogFactoryShape
>()("@t3tools/desktop/app/DesktopObservability/DesktopBackendOutputLogFactory") {}

const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
Expand Down Expand Up @@ -293,53 +309,133 @@ const writeBackendChildLogRecord = Effect.fn("desktop.observability.writeBackend
},
);

const backendOutputLogLayer = Layer.effect(
DesktopBackendOutputLog,
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const PRIMARY_BACKEND_LOG_INSTANCE_ID = PRIMARY_LOCAL_ENVIRONMENT_ID;

const sanitizeInstanceIdForFileName = (id: string): string => id.replace(/[^a-zA-Z0-9._-]+/g, "_");

const backendLogFilePathForInstance = (
environment: DesktopEnvironment.DesktopEnvironmentShape,
id: string,
): string => {
// Primary keeps the historical "server-child.log" path so ops scripts
// and packaged-build log inspection still find it where it always lived.
if (id === PRIMARY_BACKEND_LOG_INSTANCE_ID) {
return environment.path.join(environment.logDir, "server-child.log");
}
const sanitized = sanitizeInstanceIdForFileName(id);
return environment.path.join(environment.logDir, `server-child-${sanitized}.log`);
};

const writer = yield* makeRotatingLogFileWriter({
filePath: environment.path.join(environment.logDir, "server-child.log"),
}).pipe(Effect.option);

return Option.match(writer, {
onNone: () => DesktopBackendOutputLogNoop,
onSome: (logFile) =>
({
writeSessionBoundary: Effect.fn(
"desktop.observability.backendOutput.writeSessionBoundary",
)(function* ({ phase, details }) {
// Just the IO sink. Cacheable by resolved file path so two ids that
// sanitize to the same filename share a single RotatingLogFileWriter
// (no race on currentSize tracking). Splitting the sink off from the
// per-call shape lets the shape annotate writes with the *caller's*
// id rather than whatever id created the cached writer first.
const makeBackendOutputSinkForInstance = (
environment: DesktopEnvironment.DesktopEnvironmentShape,
id: string,
): Effect.Effect<
Option.Option<RotatingLogFileWriter>,
never,
FileSystem.FileSystem | Path.Path | Scope.Scope
> =>
makeRotatingLogFileWriter({
filePath: backendLogFilePathForInstance(environment, id),
}).pipe(Effect.option);

const makeBackendOutputLogShape = (
environment: DesktopEnvironment.DesktopEnvironmentShape,
id: string,
sink: Option.Option<RotatingLogFileWriter>,
): DesktopBackendOutputLogShape =>
Option.match(sink, {
onNone: () => DesktopBackendOutputLogNoop,
onSome: (logFile) =>
({
writeSessionBoundary: Effect.fn("desktop.observability.backendOutput.writeSessionBoundary")(
function* ({ phase, details }) {
const runId = yield* currentDesktopRunId;
yield* writeBackendChildLogRecord(logFile, {
message: `backend child process session ${phase.toLowerCase()}`,
level: "INFO",
annotations: {
component: "desktop-backend-child",
runId,
instanceId: id,
phase,
details: sanitizeLogValue(details),
},
});
},
),
writeOutputChunk: Effect.fn("desktop.observability.backendOutput.writeOutputChunk")(
function* (streamName, chunk) {
if (environment.isDevelopment) {
yield* writeDevelopmentConsoleOutput(streamName, chunk);
}
const runId = yield* currentDesktopRunId;
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process output",
level: streamName === "stderr" ? "ERROR" : "INFO",
annotations: {
component: "desktop-backend-child",
runId,
instanceId: id,
stream: streamName,
text: textDecoder.decode(chunk),
},
});
},
),
}) satisfies DesktopBackendOutputLogShape,
});

const backendOutputLogFactoryLayer = Layer.effect(
DesktopBackendOutputLogFactory,
Effect.gen(function* () {
const environment = yield* DesktopEnvironment.DesktopEnvironment;
const fileSystem = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const factoryScope = yield* Scope.Scope;
// Per-file-path cache of the IO sink only. The per-call shape
// wraps the sink with the caller's instance id so a cache hit on
// a path collision (e.g. "wsl:default" and "wsl_default" both
// resolve to server-child-wsl_default.log) doesn't attribute the
// second caller's writes to the first caller's id. Each sink pins
// itself to the factory's scope so all log resources tear down
// together at app exit. Mutex serializes concurrent first-time
// lookups for the same file path.
const cacheRef = yield* SynchronizedRef.make<
ReadonlyMap<string, Option.Option<RotatingLogFileWriter>>
>(new Map());

const makeForId = (id: string): Effect.Effect<DesktopBackendOutputLogShape> =>
SynchronizedRef.modifyEffect(cacheRef, (cache) => {
const cacheKey = backendLogFilePathForInstance(environment, id);
const cached = cache.get(cacheKey);
if (cached !== undefined) {
return Effect.succeed([
makeBackendOutputLogShape(environment, id, cached),
cache,
] as const);
}
return makeBackendOutputSinkForInstance(environment, id).pipe(
Effect.provideService(FileSystem.FileSystem, fileSystem),
Effect.provideService(Path.Path, path),
Scope.provide(factoryScope),
Effect.map((sink) => {
const next = new Map(cache);
next.set(cacheKey, sink);
return [
makeBackendOutputLogShape(environment, id, sink),
next as ReadonlyMap<string, Option.Option<RotatingLogFileWriter>>,
] as const;
}),
writeOutputChunk: Effect.fn("desktop.observability.backendOutput.writeOutputChunk")(
function* (streamName, chunk) {
if (environment.isDevelopment) {
yield* writeDevelopmentConsoleOutput(streamName, chunk);
}
const runId = yield* currentDesktopRunId;
yield* writeBackendChildLogRecord(logFile, {
message: "backend child process output",
level: streamName === "stderr" ? "ERROR" : "INFO",
annotations: {
component: "desktop-backend-child",
runId,
stream: streamName,
text: textDecoder.decode(chunk),
},
});
},
),
}) satisfies DesktopBackendOutputLogShape,
);
Comment thread
cursor[bot] marked this conversation as resolved.
});

return DesktopBackendOutputLogFactory.of({
forInstance: (id) => makeForId(id),
});
}),
);
Expand Down Expand Up @@ -387,7 +483,7 @@ const tracerLayer = Layer.unwrap(
).pipe(Layer.provideMerge(OtlpSerialization.layerJson));

export const layer = Layer.mergeAll(
backendOutputLogLayer,
backendOutputLogFactoryLayer,
desktopLoggerLayer,
tracerLayer,
Layer.succeed(Tracer.MinimumTraceLevel, "Info"),
Expand Down
2 changes: 0 additions & 2 deletions apps/desktop/src/app/DesktopState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as Layer from "effect/Layer";
import * as Ref from "effect/Ref";

export interface DesktopStateShape {
readonly backendReady: Ref.Ref<boolean>;
readonly quitting: Ref.Ref<boolean>;
}

Expand All @@ -15,7 +14,6 @@ export class DesktopState extends Context.Service<DesktopState, DesktopStateShap
export const layer = Layer.effect(
DesktopState,
Effect.all({
backendReady: Ref.make(false),
quitting: Ref.make(false),
}),
);
Loading
Loading