Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 6 additions & 3 deletions apps/desktop/src/syncShellEnvironment.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { readEnvironmentFromLoginShell, ShellEnvironmentReader } from "@t3tools/shared/shell";
import { readEnvironmentFromLoginShell, resolveLoginShell, ShellEnvironmentReader } from "@t3tools/shared/shell";

export function syncShellEnvironment(
env: NodeJS.ProcessEnv = process.env,
Expand All @@ -7,10 +7,13 @@ export function syncShellEnvironment(
readEnvironment?: ShellEnvironmentReader;
} = {},
): void {
if ((options.platform ?? process.platform) !== "darwin") return;
const platform = options.platform ?? process.platform;
if (platform !== "darwin" && platform !== "linux") return;
Comment thread
cursor[bot] marked this conversation as resolved.

try {
const shell = env.SHELL ?? "/bin/zsh";
const shell = resolveLoginShell(platform, env.SHELL);
if (!shell) return;

const shellEnvironment = (options.readEnvironment ?? readEnvironmentFromLoginShell)(shell, [
"PATH",
"SSH_AUTH_SOCK",
Expand Down
20 changes: 19 additions & 1 deletion apps/server/src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { ServerSettingsService } from "./serverSettings";

const start = vi.fn(() => undefined);
const stop = vi.fn(() => undefined);
const fixPath = vi.fn(() => undefined);
let resolvedConfig: ServerConfigShape | null = null;
const serverStart = Effect.acquireRelease(
Effect.gen(function* () {
Expand All @@ -36,7 +37,7 @@ const findAvailablePort = vi.fn((preferred: number) => Effect.succeed(preferred)
const testLayer = Layer.mergeAll(
Layer.succeed(CliConfig, {
cwd: "/tmp/t3-test-workspace",
fixPath: Effect.void,
fixPath: Effect.sync(fixPath),
resolveStaticDir: Effect.undefined,
} satisfies CliConfigShape),
Layer.succeed(NetService, {
Expand Down Expand Up @@ -81,6 +82,7 @@ beforeEach(() => {
resolvedConfig = null;
start.mockImplementation(() => undefined);
stop.mockImplementation(() => undefined);
fixPath.mockImplementation(() => undefined);
findAvailablePort.mockImplementation((preferred: number) => Effect.succeed(preferred));
});

Expand Down Expand Up @@ -329,6 +331,22 @@ it.layer(testLayer)("server CLI command", (it) => {
}),
);

it.effect("hydrates PATH before server startup", () =>
Effect.gen(function* () {
yield* runCli([]);

assert.equal(fixPath.mock.calls.length, 1);
assert.equal(start.mock.calls.length, 1);
const fixPathOrder = fixPath.mock.invocationCallOrder[0];
const startOrder = start.mock.invocationCallOrder[0];
assert.isTrue(typeof fixPathOrder === "number" && typeof startOrder === "number");
if (typeof fixPathOrder !== "number" || typeof startOrder !== "number") {
throw new Error("Expected fixPath and start to be called");
}
assert.isTrue(fixPathOrder < startOrder);
}),
);

it.effect("records a startup heartbeat with thread/project counts", () =>
Effect.gen(function* () {
const recordTelemetry = vi.fn(
Expand Down
7 changes: 3 additions & 4 deletions apps/server/src/os-jank.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as OS from "node:os";
import { Effect, Path } from "effect";
import { readPathFromLoginShell } from "@t3tools/shared/shell";
import { readPathFromLoginShell, resolveLoginShell } from "@t3tools/shared/shell";

export function fixPath(): void {
if (process.platform !== "darwin") return;

try {
const shell = process.env.SHELL ?? "/bin/zsh";
const shell = resolveLoginShell(process.platform, process.env.SHELL);
if (!shell) return;
Comment thread
cursor[bot] marked this conversation as resolved.
const result = readPathFromLoginShell(shell);
if (result) {
process.env.PATH = result;
Expand Down
20 changes: 20 additions & 0 deletions packages/shared/src/shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ type ExecFileSyncLike = (
options: { encoding: "utf8"; timeout: number },
) => string;

export function resolveLoginShell(
platform: NodeJS.Platform,
shell: string | undefined,
): string | undefined {
const trimmedShell = shell?.trim();
if (trimmedShell) {
return trimmedShell;
}

if (platform === "darwin") {
return "/bin/zsh";
}

if (platform === "linux") {
return "/bin/bash";
}

return undefined;
}

export function extractPathFromShellOutput(output: string): string | null {
const startIndex = output.indexOf(PATH_CAPTURE_START);
if (startIndex === -1) return null;
Expand Down