diff --git a/apps/server/src/wsServer.test.ts b/apps/server/src/wsServer.test.ts index 2a76010b5..0b56e1e29 100644 --- a/apps/server/src/wsServer.test.ts +++ b/apps/server/src/wsServer.test.ts @@ -464,6 +464,13 @@ function deriveServerPathsSync(baseDir: string, devUrl: URL | undefined) { ); } +function makeWorkspaceFixture(name: string): { baseDir: string; cwd: string } { + const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), "okcode-ws-fixture-")); + const cwd = path.join(baseDir, name); + fs.mkdirSync(cwd, { recursive: true }); + return { baseDir, cwd }; +} + describe("WebSocket Server", () => { let server: Http.Server | null = null; let serverScope: Scope.Closeable | null = null; @@ -504,6 +511,8 @@ describe("WebSocket Server", () => { const baseDir = options.baseDir ?? makeTempDir("okcode-ws-base-"); const devUrl = options.devUrl ? new URL(options.devUrl) : undefined; const derivedPaths = deriveServerPathsSync(baseDir, devUrl); + const cwd = options.cwd ?? path.join(baseDir, "project"); + fs.mkdirSync(cwd, { recursive: true }); const scope = await Effect.runPromise(Scope.make("sequential")); const persistenceLayer = options.persistenceLayer ?? SqlitePersistenceMemory; const providerLayer = options.providerLayer ?? makeServerProviderLayer(); @@ -516,7 +525,7 @@ describe("WebSocket Server", () => { mode: "web", port: 0, host: undefined, - cwd: options.cwd ?? "/test/project", + cwd, baseDir, ...derivedPaths, staticDir: options.staticDir, @@ -595,7 +604,8 @@ describe("WebSocket Server", () => { }); it("sends welcome message on connect", async () => { - server = await createTestServer({ cwd: "/test/project" }); + const { cwd } = makeWorkspaceFixture("project"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; expect(port).toBeGreaterThan(0); @@ -605,7 +615,7 @@ describe("WebSocket Server", () => { expect(welcome.type).toBe("push"); expect(welcome.data).toEqual({ - cwd: "/test/project", + cwd, projectName: "project", }); }); @@ -617,7 +627,8 @@ describe("WebSocket Server", () => { fs.mkdirSync(path.dirname(attachmentPath), { recursive: true }); fs.writeFileSync(attachmentPath, Buffer.from("hello-attachment")); - server = await createTestServer({ cwd: "/test/project", baseDir }); + const { cwd } = makeWorkspaceFixture("project"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; expect(port).toBeGreaterThan(0); @@ -641,7 +652,8 @@ describe("WebSocket Server", () => { fs.mkdirSync(path.dirname(attachmentPath), { recursive: true }); fs.writeFileSync(attachmentPath, Buffer.from("hello-encoded-attachment")); - server = await createTestServer({ cwd: "/test/project", baseDir }); + const { cwd } = makeWorkspaceFixture("project"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; expect(port).toBeGreaterThan(0); @@ -660,7 +672,8 @@ describe("WebSocket Server", () => { const staticDir = makeTempDir("okcode-static-root-"); fs.writeFileSync(path.join(staticDir, "index.html"), "

static-root

", "utf8"); - server = await createTestServer({ cwd: "/test/project", baseDir, staticDir }); + const { cwd } = makeWorkspaceFixture("project"); + server = await createTestServer({ cwd, baseDir, staticDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; expect(port).toBeGreaterThan(0); @@ -675,7 +688,8 @@ describe("WebSocket Server", () => { const staticDir = makeTempDir("okcode-static-traversal-"); fs.writeFileSync(path.join(staticDir, "index.html"), "

safe

", "utf8"); - server = await createTestServer({ cwd: "/test/project", baseDir, staticDir }); + const { cwd } = makeWorkspaceFixture("project"); + server = await createTestServer({ cwd, baseDir, staticDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; expect(port).toBeGreaterThan(0); @@ -686,8 +700,9 @@ describe("WebSocket Server", () => { }); it("bootstraps the cwd project on startup when enabled", async () => { + const { cwd } = makeWorkspaceFixture("bootstrap-workspace"); server = await createTestServer({ - cwd: "/test/bootstrap-workspace", + cwd, autoBootstrapProjectFromCwd: true, }); const addr = server.address(); @@ -698,7 +713,7 @@ describe("WebSocket Server", () => { connections.push(ws); expect(welcome.data).toEqual( expect.objectContaining({ - cwd: "/test/bootstrap-workspace", + cwd, projectName: "bootstrap-workspace", bootstrapProjectId: expect.any(String), bootstrapThreadId: expect.any(String), @@ -732,7 +747,7 @@ describe("WebSocket Server", () => { expect.arrayContaining([ expect.objectContaining({ id: bootstrapProjectId, - workspaceRoot: "/test/bootstrap-workspace", + workspaceRoot: cwd, title: "bootstrap-workspace", defaultModel: "gpt-5-codex", }), @@ -758,7 +773,7 @@ describe("WebSocket Server", () => { const persistenceLayer = makeSqlitePersistenceLive(dbPath).pipe( Layer.provide(NodeServices.layer), ); - const cwd = "/test/bootstrap-existing"; + const { cwd } = makeWorkspaceFixture("bootstrap-existing"); server = await createTestServer({ cwd, @@ -810,8 +825,9 @@ describe("WebSocket Server", () => { // Keep test output clean while verifying websocket logs. }); + const { cwd } = makeWorkspaceFixture("project"); server = await createTestServer({ - cwd: "/test/project", + cwd, devUrl: "http://localhost:5173", }); const addr = server.address(); @@ -840,7 +856,8 @@ describe("WebSocket Server", () => { ensureParentDir(keybindingsPath); fs.writeFileSync(keybindingsPath, "[]", "utf8"); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -850,7 +867,7 @@ describe("WebSocket Server", () => { const response = await sendRequest(ws, WS_METHODS.serverGetConfig); expect(response.error).toBeUndefined(); expect(response.result).toEqual({ - cwd: "/my/workspace", + cwd, keybindingsConfigPath: keybindingsPath, keybindings: DEFAULT_RESOLVED_KEYBINDINGS, issues: [], @@ -865,7 +882,8 @@ describe("WebSocket Server", () => { const { keybindingsConfigPath: keybindingsPath } = deriveServerPathsSync(baseDir, undefined); expect(fs.existsSync(keybindingsPath)).toBe(false); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -875,7 +893,7 @@ describe("WebSocket Server", () => { const response = await sendRequest(ws, WS_METHODS.serverGetConfig); expect(response.error).toBeUndefined(); expect(response.result).toEqual({ - cwd: "/my/workspace", + cwd, keybindingsConfigPath: keybindingsPath, keybindings: DEFAULT_RESOLVED_KEYBINDINGS, issues: [], @@ -896,7 +914,8 @@ describe("WebSocket Server", () => { ensureParentDir(keybindingsPath); fs.writeFileSync(keybindingsPath, "{ not-json", "utf8"); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -906,7 +925,7 @@ describe("WebSocket Server", () => { const response = await sendRequest(ws, WS_METHODS.serverGetConfig); expect(response.error).toBeUndefined(); expect(response.result).toEqual({ - cwd: "/my/workspace", + cwd, keybindingsConfigPath: keybindingsPath, keybindings: DEFAULT_RESOLVED_KEYBINDINGS, issues: [ @@ -936,7 +955,8 @@ describe("WebSocket Server", () => { "utf8", ); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -953,7 +973,7 @@ describe("WebSocket Server", () => { providers: ReadonlyArray; availableEditors: unknown; }; - expect(result.cwd).toBe("/my/workspace"); + expect(result.cwd).toBe(cwd); expect(result.keybindingsConfigPath).toBe(keybindingsPath); expect(result.issues).toEqual([ { @@ -986,7 +1006,8 @@ describe("WebSocket Server", () => { ensureParentDir(keybindingsPath); fs.writeFileSync(keybindingsPath, "[]", "utf8"); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1017,6 +1038,7 @@ describe("WebSocket Server", () => { }); it("routes shell.openInEditor through the injected open service", async () => { + const { cwd } = makeWorkspaceFixture("workspace"); const openCalls: Array<{ cwd: string; editor: string }> = []; const openService: OpenShape = { openBrowser: () => Effect.void, @@ -1028,7 +1050,7 @@ describe("WebSocket Server", () => { revealInFileManager: () => Effect.void, }; - server = await createTestServer({ cwd: "/my/workspace", open: openService }); + server = await createTestServer({ cwd, open: openService }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1036,14 +1058,15 @@ describe("WebSocket Server", () => { connections.push(ws); const response = await sendRequest(ws, WS_METHODS.shellOpenInEditor, { - cwd: "/my/workspace", + cwd, editor: "cursor", }); expect(response.error).toBeUndefined(); - expect(openCalls).toEqual([{ cwd: "/my/workspace", editor: "cursor" }]); + expect(openCalls).toEqual([{ cwd, editor: "cursor" }]); }); it("routes shell.openInFileManager through the injected open service", async () => { + const { cwd } = makeWorkspaceFixture("workspace"); const openCalls: string[] = []; const openService: OpenShape = { openBrowser: () => Effect.void, @@ -1055,7 +1078,7 @@ describe("WebSocket Server", () => { revealInFileManager: () => Effect.void, }; - server = await createTestServer({ cwd: "/my/workspace", open: openService }); + server = await createTestServer({ cwd, open: openService }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1063,13 +1086,14 @@ describe("WebSocket Server", () => { connections.push(ws); const response = await sendRequest(ws, WS_METHODS.shellOpenInFileManager, { - path: "/my/workspace/src", + path: path.join(cwd, "src"), }); expect(response.error).toBeUndefined(); - expect(openCalls).toEqual(["/my/workspace/src"]); + expect(openCalls).toEqual([path.join(cwd, "src")]); }); it("routes shell.revealInFileManager through the injected open service", async () => { + const { cwd } = makeWorkspaceFixture("workspace"); const revealCalls: string[] = []; const openService: OpenShape = { openBrowser: () => Effect.void, @@ -1081,7 +1105,7 @@ describe("WebSocket Server", () => { }, }; - server = await createTestServer({ cwd: "/my/workspace", open: openService }); + server = await createTestServer({ cwd, open: openService }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1089,10 +1113,10 @@ describe("WebSocket Server", () => { connections.push(ws); const response = await sendRequest(ws, WS_METHODS.shellRevealInFileManager, { - path: "/my/workspace/src/index.ts", + path: path.join(cwd, "src", "index.ts"), }); expect(response.error).toBeUndefined(); - expect(revealCalls).toEqual(["/my/workspace/src/index.ts"]); + expect(revealCalls).toEqual([path.join(cwd, "src", "index.ts")]); }); it("reads keybindings from the configured state directory", async () => { @@ -1108,7 +1132,8 @@ describe("WebSocket Server", () => { ]), "utf8", ); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1121,7 +1146,7 @@ describe("WebSocket Server", () => { fs.readFileSync(keybindingsPath, "utf8"), ) as KeybindingsConfig; expect(response.result).toEqual({ - cwd: "/my/workspace", + cwd, keybindingsConfigPath: keybindingsPath, keybindings: compileKeybindings(persistedConfig), issues: [], @@ -1141,7 +1166,8 @@ describe("WebSocket Server", () => { "utf8", ); - server = await createTestServer({ cwd: "/my/workspace", baseDir }); + const { cwd } = makeWorkspaceFixture("workspace"); + server = await createTestServer({ cwd, baseDir }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1169,7 +1195,7 @@ describe("WebSocket Server", () => { const configResponse = await sendRequest(ws, WS_METHODS.serverGetConfig); expect(configResponse.error).toBeUndefined(); expect(configResponse.result).toEqual({ - cwd: "/my/workspace", + cwd, keybindingsConfigPath: keybindingsPath, keybindings: compileKeybindings(persistedConfig), issues: [], @@ -1182,7 +1208,8 @@ describe("WebSocket Server", () => { }); it("returns error for unknown methods", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1195,7 +1222,8 @@ describe("WebSocket Server", () => { }); it("returns error when requesting turn diff for unknown thread", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1212,7 +1240,8 @@ describe("WebSocket Server", () => { }); it("returns error when requesting turn diff with an inverted range", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1231,7 +1260,8 @@ describe("WebSocket Server", () => { }); it("returns error when requesting full thread diff for unknown thread", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1247,7 +1277,8 @@ describe("WebSocket Server", () => { }); it("returns retryable error when requested turn exceeds current checkpoint turn count", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1292,6 +1323,7 @@ describe("WebSocket Server", () => { it("keeps orchestration domain push behavior for provider runtime events", async () => { const runtimeEventPubSub = Effect.runSync(PubSub.unbounded()); + const { cwd } = makeWorkspaceFixture("test"); const emitRuntimeEvent = (event: ProviderRuntimeEvent) => { Effect.runSync(PubSub.publish(runtimeEventPubSub, event)); }; @@ -1323,7 +1355,7 @@ describe("WebSocket Server", () => { const providerLayer = Layer.succeed(ProviderService, providerService); server = await createTestServer({ - cwd: "/test", + cwd, providerLayer, }); const addr = server.address(); @@ -1414,8 +1446,9 @@ describe("WebSocket Server", () => { it("routes terminal RPC methods and broadcasts terminal events", async () => { const cwd = makeTempDir("okcode-ws-terminal-cwd-"); const terminalManager = new MockTerminalManager(); + const { cwd: workspaceCwd } = makeWorkspaceFixture("test"); server = await createTestServer({ - cwd: "/test", + cwd: workspaceCwd, terminalManager, }); const addr = server.address(); @@ -1486,8 +1519,9 @@ describe("WebSocket Server", () => { it("detaches terminal event listener on stop for injected manager", async () => { const terminalManager = new MockTerminalManager(); + const { cwd } = makeWorkspaceFixture("test"); server = await createTestServer({ - cwd: "/test", + cwd, terminalManager, }); @@ -1500,7 +1534,8 @@ describe("WebSocket Server", () => { }); it("returns validation errors for invalid terminal open params", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1517,7 +1552,8 @@ describe("WebSocket Server", () => { }); it("handles invalid JSON gracefully", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1560,9 +1596,10 @@ describe("WebSocket Server", () => { openInFileManager: () => Effect.void, revealInFileManager: () => Effect.void, }; + const { cwd } = makeWorkspaceFixture("test"); try { - server = await createTestServer({ cwd: "/test", open: brokenOpenService }); + server = await createTestServer({ cwd, open: brokenOpenService }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1607,7 +1644,8 @@ describe("WebSocket Server", () => { }); it("returns errors for removed projects CRUD methods", async () => { - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1643,7 +1681,8 @@ describe("WebSocket Server", () => { fs.mkdirSync(path.join(workspace, ".git"), { recursive: true }); fs.writeFileSync(path.join(workspace, ".git", "HEAD"), "ref: refs/heads/main\n", "utf8"); - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1675,7 +1714,8 @@ describe("WebSocket Server", () => { "utf8", ); - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1709,7 +1749,8 @@ describe("WebSocket Server", () => { it("supports projects.writeFile within the workspace root", async () => { const workspace = makeTempDir("okcode-ws-write-file-"); - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1734,7 +1775,8 @@ describe("WebSocket Server", () => { it("rejects projects.writeFile paths outside the workspace root", async () => { const workspace = makeTempDir("okcode-ws-write-file-reject-"); - server = await createTestServer({ cwd: "/test" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1774,8 +1816,9 @@ describe("WebSocket Server", () => { ), ); + const { cwd } = makeWorkspaceFixture("test"); server = await createTestServer({ - cwd: "/test", + cwd, gitCore: { listBranches, initRepo, @@ -1832,7 +1875,8 @@ describe("WebSocket Server", () => { listPullRequests: vi.fn(() => Effect.succeed({ pullRequests: [] })), }; - server = await createTestServer({ cwd: "/test", gitManager }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd, gitManager }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1840,11 +1884,11 @@ describe("WebSocket Server", () => { connections.push(ws); const response = await sendRequest(ws, WS_METHODS.gitStatus, { - cwd: "/test", + cwd, }); expect(response.error).toBeUndefined(); expect(response.result).toEqual(statusResult); - expect(status).toHaveBeenCalledWith({ cwd: "/test" }); + expect(status).toHaveBeenCalledWith({ cwd }); }); it("supports git pull request routing over websocket", async () => { @@ -1872,7 +1916,8 @@ describe("WebSocket Server", () => { listPullRequests: vi.fn(() => Effect.succeed({ pullRequests: [] })), }; - server = await createTestServer({ cwd: "/test", gitManager }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd, gitManager }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1880,25 +1925,25 @@ describe("WebSocket Server", () => { connections.push(ws); const resolveResponse = await sendRequest(ws, WS_METHODS.gitResolvePullRequest, { - cwd: "/test", + cwd, reference: "#42", }); expect(resolveResponse.error).toBeUndefined(); expect(resolveResponse.result).toEqual(resolvePullRequestResult); const prepareResponse = await sendRequest(ws, WS_METHODS.gitPreparePullRequestThread, { - cwd: "/test", + cwd, reference: "42", mode: "worktree", }); expect(prepareResponse.error).toBeUndefined(); expect(prepareResponse.result).toEqual(preparePullRequestThreadResult); expect(gitManager.resolvePullRequest).toHaveBeenCalledWith({ - cwd: "/test", + cwd, reference: "#42", }); expect(gitManager.preparePullRequestThread).toHaveBeenCalledWith({ - cwd: "/test", + cwd, reference: "42", mode: "worktree", }); @@ -1932,7 +1977,8 @@ describe("WebSocket Server", () => { listPullRequests: vi.fn(() => Effect.succeed({ pullRequests: [] })), }; - server = await createTestServer({ cwd: "/test", gitManager }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd, gitManager }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -1941,7 +1987,7 @@ describe("WebSocket Server", () => { const response = await sendRequest(ws, WS_METHODS.gitRunStackedAction, { actionId: "client-action-1", - cwd: "/test", + cwd, action: "commit_push", }); expect(response.result).toBeUndefined(); @@ -1956,7 +2002,7 @@ describe("WebSocket Server", () => { expect(runStackedAction).toHaveBeenCalledWith( { actionId: "client-action-1", - cwd: "/test", + cwd, action: "commit_push", }, expect.objectContaining({ @@ -1998,7 +2044,8 @@ describe("WebSocket Server", () => { listPullRequests: vi.fn(() => Effect.succeed({ pullRequests: [] })), }; - server = await createTestServer({ cwd: "/test", gitManager }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd, gitManager }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; @@ -2008,14 +2055,14 @@ describe("WebSocket Server", () => { const responsePromise = sendRequest(initiatingWs, WS_METHODS.gitRunStackedAction, { actionId: "client-action-2", - cwd: "/test", + cwd, action: "commit", }); const progressPush = await waitForPush(initiatingWs, WS_CHANNELS.gitActionProgress); expect(progressPush.data).toEqual({ actionId: "client-action-2", - cwd: "/test", + cwd, action: "commit", kind: "phase_started", phase: "commit", @@ -2035,7 +2082,8 @@ describe("WebSocket Server", () => { }); it("rejects websocket connections without a valid auth token", async () => { - server = await createTestServer({ cwd: "/test", authToken: "secret-token" }); + const { cwd } = makeWorkspaceFixture("test"); + server = await createTestServer({ cwd, authToken: "secret-token" }); const addr = server.address(); const port = typeof addr === "object" && addr !== null ? addr.port : 0; diff --git a/apps/web/src/components/BranchToolbar.tsx b/apps/web/src/components/BranchToolbar.tsx index c3a2d7050..d81676aa3 100644 --- a/apps/web/src/components/BranchToolbar.tsx +++ b/apps/web/src/components/BranchToolbar.tsx @@ -3,7 +3,12 @@ import { ArrowDownIcon, FolderIcon, GitForkIcon, LoaderIcon } from "lucide-react import { useCallback, useEffect } from "react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; -import { gitPullMutationOptions, gitQueryKeys, gitStatusQueryOptions, invalidateGitQueries } from "../lib/gitReactQuery"; +import { + gitPullMutationOptions, + gitQueryKeys, + gitStatusQueryOptions, + invalidateGitQueries, +} from "../lib/gitReactQuery"; import { newCommandId } from "../lib/utils"; import { readNativeApi } from "../nativeApi"; import { useComposerDraftStore } from "../composerDraftStore"; @@ -222,14 +227,19 @@ export default function BranchToolbar({ )} Pull - + {behindCount} } /> - Local branch is {behindCount} commit{behindCount !== 1 ? "s" : ""} behind upstream. Pull to update before starting a new thread. + Local branch is {behindCount} commit{behindCount !== 1 ? "s" : ""} behind upstream. + Pull to update before starting a new thread. ) : null} diff --git a/bun.lock b/bun.lock index 845efff8b..f8376d645 100644 --- a/bun.lock +++ b/bun.lock @@ -19,7 +19,7 @@ }, "apps/desktop": { "name": "@okcode/desktop", - "version": "0.13.0", + "version": "0.14.0", "dependencies": { "effect": "catalog:", "electron": "40.6.0", @@ -103,7 +103,7 @@ }, "apps/mobile": { "name": "@okcode/mobile", - "version": "0.13.0", + "version": "0.14.0", "dependencies": { "@capacitor/android": "^8.3.0", "@capacitor/app": "^8.1.0", @@ -123,7 +123,7 @@ }, "apps/server": { "name": "okcodes", - "version": "0.13.0", + "version": "0.14.0", "bin": { "okcode": "./dist/index.mjs", }, @@ -154,7 +154,7 @@ }, "apps/web": { "name": "@okcode/web", - "version": "0.13.0", + "version": "0.14.0", "dependencies": { "@base-ui/react": "^1.2.0", "@codemirror/language": "^6.12.3", @@ -214,7 +214,7 @@ }, "packages/contracts": { "name": "@okcode/contracts", - "version": "0.13.0", + "version": "0.14.0", "dependencies": { "effect": "catalog:", }, diff --git a/docs/releases/v0.14.0/assets.md b/docs/releases/v0.14.0/assets.md index 0b5250700..3b973e36b 100644 --- a/docs/releases/v0.14.0/assets.md +++ b/docs/releases/v0.14.0/assets.md @@ -14,13 +14,13 @@ After the workflow completes, expect **installer and updater** artifacts similar ## Desktop installers and payloads -| Platform | Kind | Typical pattern | -| ------------------- | -------------- | ----------------- | -| macOS Apple Silicon | DMG (signed) | `*.dmg` (arm64) | -| macOS Intel | DMG (signed) | `*.dmg` (x64) | -| macOS | ZIP (updater) | `*.zip` | -| Linux x64 | AppImage | `*.AppImage` | -| Windows x64 | NSIS installer | `*.exe` | +| Platform | Kind | Typical pattern | +| ------------------- | -------------- | --------------- | +| macOS Apple Silicon | DMG (signed) | `*.dmg` (arm64) | +| macOS Intel | DMG (signed) | `*.dmg` (x64) | +| macOS | ZIP (updater) | `*.zip` | +| Linux x64 | AppImage | `*.AppImage` | +| Windows x64 | NSIS installer | `*.exe` | ### macOS code signing and notarization