History

[codex] Enforce canonical Node namespace imports (#3238)

Julius Marminge committed 4 months ago

Commit 2fa37ec1 parent db2750271 files · +1205 −952Browse files

Showing the changes to apps/server/src (45 of 71 files). Show all

Unified · Split

45 files
  1. apps/server/src/attachmentPaths.ts +1 −1
  2. apps/server/src/attachmentStore.test.ts +13 −9
  3. apps/server/src/attachmentStore.ts +4 −4
  4. apps/server/src/auth/utils.ts +3 −3
  5. apps/server/src/bin.test.ts +47 −25
  6. apps/server/src/bootstrap.test.ts +13 −13
  7. apps/server/src/bootstrap.ts +13 −13
  8. apps/server/src/checkpointing/CheckpointStore.test.ts +4 −4
  9. apps/server/src/cloud/CliTokenManager.ts +2 −2
  10. apps/server/src/cloud/http.ts +2 −2
  11. apps/server/src/environment/ServerEnvironment.test.ts +2 −2
  12. apps/server/src/git/GitManager.test.ts +64 −56
  13. apps/server/src/git/Utils.ts +3 −3
  14. apps/server/src/orchestration/Layers/CheckpointReactor.test.ts +17 −17
  15. apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts +7 −6
  16. apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts +6 −6
  17. apps/server/src/pathExpansion.test.ts +5 −5
  18. apps/server/src/pathExpansion.ts +4 −4
  19. apps/server/src/persistence/NodeSqliteClient.ts +11 −7
  20. apps/server/src/preview/PortScanner.test.ts +4 −4
  21. apps/server/src/provider/Layers/ClaudeAdapter.test.ts +9 −9
  22. apps/server/src/provider/Layers/CodexAdapter.test.ts +98 −96
  23. apps/server/src/provider/Layers/CodexSessionRuntime.test.ts +18 −18
  24. apps/server/src/provider/Layers/CursorAdapter.test.ts +63 −49
  25. apps/server/src/provider/Layers/CursorProvider.ts +2 −2
  26. apps/server/src/provider/Layers/EventNdjsonLogger.test.ts +28 −31
  27. apps/server/src/provider/Layers/EventNdjsonLogger.ts +4 −4
  28. apps/server/src/provider/Layers/GrokAdapter.test.ts +18 −16
  29. apps/server/src/provider/Layers/OpenCodeAdapter.test.ts +48 −48
  30. apps/server/src/provider/Layers/OpenCodeProvider.test.ts +22 −19
  31. apps/server/src/provider/Layers/ProviderService.test.ts +21 −15
  32. apps/server/src/provider/Layers/ProviderSessionDirectory.test.ts +6 −6
  33. apps/server/src/provider/acp/AcpJsonRpcConnection.test.ts +10 −10
  34. apps/server/src/provider/opencodeRuntime.ts +2 −2
  35. apps/server/src/provider/providerMaintenance.test.ts +44 −44
  36. apps/server/src/relay/AgentAwarenessRelay.test.ts +2 −2
  37. apps/server/src/server.test.ts +22 −22
  38. apps/server/src/terminal/NodePtyAdapter.ts +2 −2
  39. apps/server/src/textGeneration/CursorTextGeneration.test.ts +25 −21
  40. apps/server/src/textGeneration/GrokTextGeneration.test.ts +18 −16
  41. apps/server/src/vcs/GitVcsDriver.ts +5 −2
  42. apps/server/src/workspace/WorkspaceEntries.test.ts +9 −3
  43. apps/server/src/workspace/WorkspaceEntries.ts +5 −5
  44. apps/server/src/workspace/WorkspaceFileSystem.ts +4 −4
  45. apps/server/src/workspace/WorkspacePaths.ts +3 −3
apps/server/src/attachmentPaths.ts+1−1
@@ -1,5 +1,5 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import NodePath from "node:path";
2+import * as NodePath from "node:path";
33
44 export function normalizeAttachmentRelativePath(rawRelativePath: string): string | null {
55 const normalized = NodePath.normalize(rawRelativePath).replace(/^[/\\]+/, "");
apps/server/src/attachmentStore.test.ts+13−9
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import { describe, expect, it } from "vite-plus/test";
77
@@ -45,11 +45,13 @@ describe("attachmentStore", () => { · 37 unmodified lines
4545 });
4646
4747 it("resolves attachment path by id using the extension that exists on disk", () => {
48− const attachmentsDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3code-attachment-store-"));
48+ const attachmentsDir = NodeFS.mkdtempSync(
49+ NodePath.join(NodeOS.tmpdir(), "t3code-attachment-store-"),
50+ );
4951 try {
5052 const attachmentId = "thread-1-attachment";
51− const pngPath = path.join(attachmentsDir, `${attachmentId}.png`);
52− fs.writeFileSync(pngPath, Buffer.from("hello"));
53+ const pngPath = NodePath.join(attachmentsDir, `${attachmentId}.png`);
54+ NodeFS.writeFileSync(pngPath, Buffer.from("hello"));
5355
5456 const resolved = resolveAttachmentPathById({
5557 attachmentsDir,
@@ -57,12 +59,14 @@ describe("attachmentStore", () => { · 1 unmodified line
5759 });
5860 expect(resolved).toBe(pngPath);
5961 } finally {
60− fs.rmSync(attachmentsDir, { recursive: true, force: true });
62+ NodeFS.rmSync(attachmentsDir, { recursive: true, force: true });
6163 }
6264 });
6365
6466 it("returns null when no attachment file exists for the id", () => {
65− const attachmentsDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3code-attachment-store-"));
67+ const attachmentsDir = NodeFS.mkdtempSync(
68+ NodePath.join(NodeOS.tmpdir(), "t3code-attachment-store-"),
69+ );
6670 try {
6771 const resolved = resolveAttachmentPathById({
6872 attachmentsDir,
@@ -70,7 +74,7 @@ describe("attachmentStore", () => { · 1 unmodified line
7074 });
7175 expect(resolved).toBeNull();
7276 } finally {
73− fs.rmSync(attachmentsDir, { recursive: true, force: true });
77+ NodeFS.rmSync(attachmentsDir, { recursive: true, force: true });
7478 }
7579 });
7680 });
apps/server/src/attachmentStore.ts+4−4
@@ -1,6 +1,6 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { randomUUID } from "node:crypto";
3−import { existsSync } from "node:fs";
2+import * as NodeCrypto from "node:crypto";
3+import * as NodeFS from "node:fs";
44
55 import type { ChatAttachment } from "@t3tools/contracts";
66
@@ -39,7 +39,7 @@ export function createAttachmentId(threadId: string): string | null { · 32 unmodified lines
3939 if (!threadSegment) {
4040 return null;
4141 }
42− return `${threadSegment}-${randomUUID()}`;
42+ return `${threadSegment}-${NodeCrypto.randomUUID()}`;
4343 }
4444
4545 export function parseThreadSegmentFromAttachmentId(attachmentId: string): string | null {
@@ -89,7 +89,7 @@ export function resolveAttachmentPathById(input: { · 43 unmodified lines
8989 attachmentsDir: input.attachmentsDir,
9090 relativePath: `${normalizedId}${extension}`,
9191 });
92− if (maybePath && existsSync(maybePath)) {
92+ if (maybePath && NodeFS.existsSync(maybePath)) {
9393 return maybePath;
9494 }
9595 }
apps/server/src/auth/utils.ts+3−3
@@ -4,7 +4,7 @@ import type { · 3 unmodified lines
44 AuthClientPresentationMetadata,
55 } from "@t3tools/contracts";
66 import type * as HttpServerRequest from "effect/unstable/http/HttpServerRequest";
7−import * as Crypto from "node:crypto";
7+import * as NodeCrypto from "node:crypto";
88 import * as Encoding from "effect/Encoding";
99 import * as Result from "effect/Result";
1010
@@ -32,7 +32,7 @@ export function base64UrlDecodeUtf8(input: string): string { · 21 unmodified lines
3232 }
3333
3434 export function signPayload(payload: string, secret: Uint8Array): string {
35− return Crypto.createHmac("sha256", Buffer.from(secret)).update(payload).digest("base64url");
35+ return NodeCrypto.createHmac("sha256", Buffer.from(secret)).update(payload).digest("base64url");
3636 }
3737
3838 export function timingSafeEqualBase64Url(left: string, right: string): boolean {
@@ -41,7 +41,7 @@ export function timingSafeEqualBase64Url(left: string, right: string): boolean { · 2 unmodified lines
4141 if (leftBuffer.length !== rightBuffer.length) {
4242 return false;
4343 }
44− return Crypto.timingSafeEqual(leftBuffer, rightBuffer);
44+ return NodeCrypto.timingSafeEqual(leftBuffer, rightBuffer);
4545 }
4646
4747 function normalizeNonEmptyString(value: string | null | undefined): string | undefined {
apps/server/src/bin.test.ts+47−25
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off - CLI integration exercises Node HTTP and filesystem boundaries.
2−import { createServer } from "node:http";
3−import { existsSync, mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
4−import { tmpdir } from "node:os";
5−import { join } from "node:path";
2+import * as NodeHttp from "node:http";
3+import * as NodeFS from "node:fs";
4+import * as NodeOS from "node:os";
5+import * as NodePath from "node:path";
66
77 import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
88 import * as NodeServices from "@effect/platform-node/NodeServices";
@@ -124,7 +124,7 @@ const withLiveProjectCliServer = <A, E, R>(baseDir: string, run: () => Effect.Ef · 115 unmodified lines
124124 ),
125125 Layer.provideMerge(makeProjectPersistenceLayer(config)),
126126 Layer.provideMerge(
127− NodeHttpServer.layer(createServer, {
127+ NodeHttpServer.layer(NodeHttp.createServer, {
128128 host: "127.0.0.1",
129129 port: 0,
130130 }),
@@ -197,7 +197,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 66 unmodified lines
197197
198198 it.effect("reports fresh headless connect state without requiring local configuration", () =>
199199 Effect.gen(function* () {
200− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-status-test-"));
200+ const baseDir = NodeFS.mkdtempSync(
201+ NodePath.join(NodeOS.tmpdir(), "t3-cli-cloud-status-test-"),
202+ );
201203 const { output } = yield* captureStdout(
202204 runConnectCli(["connect", "status", "--base-dir", baseDir, "--json"]),
203205 );
@@ -220,7 +222,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 16 unmodified lines
220222
221223 it.effect("reports actionable human-readable headless connect state", () =>
222224 Effect.gen(function* () {
223− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-status-human-test-"));
225+ const baseDir = NodeFS.mkdtempSync(
226+ NodePath.join(NodeOS.tmpdir(), "t3-cli-cloud-status-human-test-"),
227+ );
224228 const { output } = yield* captureStdout(
225229 runConnectCli(["connect", "status", "--base-dir", baseDir]),
226230 );
@@ -234,11 +238,13 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 7 unmodified lines
234238
235239 it.effect("logs in to headless connect without enabling access", () =>
236240 Effect.gen(function* () {
237− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-login-test-"));
241+ const baseDir = NodeFS.mkdtempSync(
242+ NodePath.join(NodeOS.tmpdir(), "t3-cli-cloud-login-test-"),
243+ );
238244 const { secretsDir } = yield* ServerConfig.deriveServerPaths(baseDir, undefined);
239− mkdirSync(secretsDir, { recursive: true });
240− writeFileSync(
241− join(secretsDir, "cloud-cli-oauth-token.bin"),
245+ NodeFS.mkdirSync(secretsDir, { recursive: true });
246+ NodeFS.writeFileSync(
247+ NodePath.join(secretsDir, "cloud-cli-oauth-token.bin"),
242248 // @effect-diagnostics-next-line preferSchemaOverJson:off - Test fixture matches the persisted CLI token representation.
243249 JSON.stringify({
244250 accessToken: "access-token",
@@ -267,7 +273,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 22 unmodified lines
267273
268274 it.effect("disables headless connect without a running server", () =>
269275 Effect.gen(function* () {
270− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-unlink-test-"));
276+ const baseDir = NodeFS.mkdtempSync(
277+ NodePath.join(NodeOS.tmpdir(), "t3-cli-cloud-unlink-test-"),
278+ );
271279 const { output } = yield* captureStdout(
272280 runConnectCli(["connect", "unlink", "--base-dir", baseDir]),
273281 );
@@ -278,24 +286,28 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 4 unmodified lines
278286
279287 it.effect("logs out of headless connect and removes the stored CLI authorization", () =>
280288 Effect.gen(function* () {
281− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-cloud-logout-test-"));
289+ const baseDir = NodeFS.mkdtempSync(
290+ NodePath.join(NodeOS.tmpdir(), "t3-cli-cloud-logout-test-"),
291+ );
282292 const { secretsDir } = yield* ServerConfig.deriveServerPaths(baseDir, undefined);
283− const tokenPath = join(secretsDir, "cloud-cli-oauth-token.bin");
284− mkdirSync(secretsDir, { recursive: true });
285− writeFileSync(tokenPath, "invalid persisted token");
293+ const tokenPath = NodePath.join(secretsDir, "cloud-cli-oauth-token.bin");
294+ NodeFS.mkdirSync(secretsDir, { recursive: true });
295+ NodeFS.writeFileSync(tokenPath, "invalid persisted token");
286296
287297 const { output } = yield* captureStdout(
288298 runConnectCli(["connect", "logout", "--base-dir", baseDir]),
289299 );
290300
291301 assert.equal(output, "Signed out of T3 Connect locally.");
292− assert.isFalse(existsSync(tokenPath));
302+ assert.isFalse(NodeFS.existsSync(tokenPath));
293303 }),
294304 );
295305
296306 it.effect("executes auth pairing subcommands and redacts secrets from list output", () =>
297307 Effect.gen(function* () {
298− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-auth-pairing-test-"));
308+ const baseDir = NodeFS.mkdtempSync(
309+ NodePath.join(NodeOS.tmpdir(), "t3-cli-auth-pairing-test-"),
310+ );
299311
300312 const createdOutput = yield* captureStdout(
301313 runCli(["auth", "pairing", "create", "--base-dir", baseDir, "--json"]),
@@ -325,7 +337,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 23 unmodified lines
325337
326338 it.effect("executes auth session subcommands and redacts secrets from list output", () =>
327339 Effect.gen(function* () {
328− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-auth-session-test-"));
340+ const baseDir = NodeFS.mkdtempSync(
341+ NodePath.join(NodeOS.tmpdir(), "t3-cli-auth-session-test-"),
342+ );
329343
330344 const issuedOutput = yield* captureStdout(
331345 runCli(["auth", "session", "issue", "--base-dir", baseDir, "--json"]),
@@ -400,8 +414,12 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 68 unmodified lines
400414
401415 it.effect("adds, renames, and removes projects offline through the orchestration engine", () =>
402416 Effect.gen(function* () {
403− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-projects-offline-test-"));
404− const workspaceRoot = mkdtempSync(join(tmpdir(), "t3-cli-projects-workspace-"));
417+ const baseDir = NodeFS.mkdtempSync(
418+ NodePath.join(NodeOS.tmpdir(), "t3-cli-projects-offline-test-"),
419+ );
420+ const workspaceRoot = NodeFS.mkdtempSync(
421+ NodePath.join(NodeOS.tmpdir(), "t3-cli-projects-workspace-"),
422+ );
405423
406424 yield* runCliWithRuntime([
407425 "project",
@@ -444,8 +462,12 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 36 unmodified lines
444462
445463 it.effect("routes project commands through a running server when runtime state is present", () =>
446464 Effect.gen(function* () {
447− const baseDir = mkdtempSync(join(tmpdir(), "t3-cli-projects-live-test-"));
448− const workspaceRoot = mkdtempSync(join(tmpdir(), "t3-cli-projects-live-workspace-"));
465+ const baseDir = NodeFS.mkdtempSync(
466+ NodePath.join(NodeOS.tmpdir(), "t3-cli-projects-live-test-"),
467+ );
468+ const workspaceRoot = NodeFS.mkdtempSync(
469+ NodePath.join(NodeOS.tmpdir(), "t3-cli-projects-live-workspace-"),
470+ );
449471
450472 yield* withLiveProjectCliServer(baseDir, () =>
451473 Effect.gen(function* () {
@@ -472,8 +494,8 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 20 unmodified lines
472494
473495 it.effect("rejects dev-url on project commands", () =>
474496 Effect.gen(function* () {
475− const workspaceRoot = mkdtempSync(
476− join(tmpdir(), "t3-cli-projects-unknown-option-workspace-"),
497+ const workspaceRoot = NodeFS.mkdtempSync(
498+ NodePath.join(NodeOS.tmpdir(), "t3-cli-projects-unknown-option-workspace-"),
477499 );
478500 const error = yield* runCliWithRuntime([
479501 "project",
apps/server/src/bootstrap.test.ts+13−13
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as NFS from "node:fs";
3−import * as path from "node:path";
4−import { execFileSync, spawn } from "node:child_process";
2+import * as NodeFS from "node:fs";
3+import * as NodePath from "node:path";
4+import * as NodeChildProcess from "node:child_process";
55 import * as NodeServices from "@effect/platform-node/NodeServices";
66 import { it } from "@effect/vitest";
77 import * as FileSystem from "effect/FileSystem";
@@ -53,8 +53,8 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 45 unmodified lines
5353 );
5454
5555 const fd = yield* Effect.acquireRelease(
56− Effect.sync(() => NFS.openSync(filePath, "r")),
57− (fd) => Effect.sync(() => NFS.closeSync(fd)),
56+ Effect.sync(() => NodeFS.openSync(filePath, "r")),
57+ (fd) => Effect.sync(() => NodeFS.closeSync(fd)),
5858 );
5959
6060 const payload = yield* readBootstrapEnvelope(TestEnvelopeSchema, fd, { timeoutMs: 100 });
@@ -78,7 +78,7 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 17 unmodified lines
7878 // so the stream owns the fd lifecycle and closes it asynchronously on end.
7979 // Attempting to also close it synchronously in a finalizer races with the
8080 // stream's async close and produces an uncaught EBADF.
81− const fd = NFS.openSync(filePath, "r");
81+ const fd = NodeFS.openSync(filePath, "r");
8282
8383 openSyncInterceptor.failPath = `/proc/self/fd/${fd}`;
8484 try {
@@ -96,8 +96,8 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 11 unmodified lines
9696
9797 it.effect("returns none when the fd is unavailable", () =>
9898 Effect.gen(function* () {
99− const fd = NFS.openSync("/dev/null", "r");
100− NFS.closeSync(fd);
99+ const fd = NodeFS.openSync("/dev/null", "r");
100+ NodeFS.closeSync(fd);
101101
102102 const payload = yield* readBootstrapEnvelope(TestEnvelopeSchema, fd, { timeoutMs: 100 });
103103 assertNone(payload);
@@ -108,13 +108,13 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 4 unmodified lines
108108 Effect.gen(function* () {
109109 const fs = yield* FileSystem.FileSystem;
110110 const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-bootstrap-" });
111− const fifoPath = path.join(tempDir, "bootstrap.pipe");
111+ const fifoPath = NodePath.join(tempDir, "bootstrap.pipe");
112112
113− yield* Effect.sync(() => execFileSync("mkfifo", [fifoPath]));
113+ yield* Effect.sync(() => NodeChildProcess.execFileSync("mkfifo", [fifoPath]));
114114
115115 const _writer = yield* Effect.acquireRelease(
116116 Effect.sync(() =>
117− spawn("sh", ["-c", 'exec 3>"$1"; sleep 60', "sh", fifoPath], {
117+ NodeChildProcess.spawn("sh", ["-c", 'exec 3>"$1"; sleep 60', "sh", fifoPath], {
118118 stdio: ["ignore", "ignore", "ignore"],
119119 }),
120120 ),
@@ -125,8 +125,8 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 4 unmodified lines
125125 );
126126
127127 const fd = yield* Effect.acquireRelease(
128− Effect.sync(() => NFS.openSync(fifoPath, "r")),
129− (fd) => Effect.sync(() => NFS.closeSync(fd)),
128+ Effect.sync(() => NodeFS.openSync(fifoPath, "r")),
129+ (fd) => Effect.sync(() => NodeFS.closeSync(fd)),
130130 );
131131
132132 const fiber = yield* readBootstrapEnvelope(TestEnvelopeSchema, fd, {
apps/server/src/bootstrap.ts+13−13
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as NFS from "node:fs";
3−import * as Net from "node:net";
4−import * as readline from "node:readline";
5−import type { Readable } from "node:stream";
2+import * as NodeFS from "node:fs";
3+import * as NodeNet from "node:net";
4+import * as NodeReadline from "node:readline";
5+import type * as NodeStream from "node:stream";
66
77 import * as Data from "effect/Data";
88 import * as Effect from "effect/Effect";
@@ -33,7 +33,7 @@ export const readBootstrapEnvelope = Effect.fn("readBootstrapEnvelope")(function · 24 unmodified lines
3333 const timeoutMs = options?.timeoutMs ?? 1000;
3434
3535 return yield* Effect.callback<Option.Option<A>, BootstrapError>((resume) => {
36− const input = readline.createInterface({
36+ const input = NodeReadline.createInterface({
3737 input: stream,
3838 crlfDelay: Infinity,
3939 });
@@ -96,7 +96,7 @@ const isUnavailableBootstrapFdError = Predicate.compose( · 56 unmodified lines
9696
9797 const isFdReady = (fd: number) =>
9898 Effect.try({
99− try: () => NFS.fstatSync(fd),
99+ try: () => NodeFS.fstatSync(fd),
100100 catch: (error) =>
101101 new BootstrapError({
102102 message: "Failed to stat bootstrap fd.",
@@ -113,7 +113,7 @@ const isFdReady = (fd: number) => · 10 unmodified lines
113113 const makeBootstrapInputStream = (fd: number) =>
114114 Effect.gen(function* () {
115115 const platform = yield* HostProcessPlatform;
116− return yield* Effect.try<Readable, BootstrapError>({
116+ return yield* Effect.try<NodeStream.Readable, BootstrapError>({
117117 try: () => {
118118 const fdPath = resolveFdPath(fd, platform);
119119 if (fdPath === undefined) {
@@ -122,8 +122,8 @@ const makeBootstrapInputStream = (fd: number) => · 2 unmodified lines
122122
123123 let streamFd: number | undefined;
124124 try {
125− streamFd = NFS.openSync(fdPath, "r");
126− return NFS.createReadStream("", {
125+ streamFd = NodeFS.openSync(fdPath, "r");
126+ return NodeFS.createReadStream("", {
127127 fd: streamFd,
128128 encoding: "utf8",
129129 autoClose: true,
@@ -131,7 +131,7 @@ const makeBootstrapInputStream = (fd: number) => · 1 unmodified line
131131 } catch (error) {
132132 if (isBootstrapFdPathDuplicationError(error)) {
133133 if (streamFd !== undefined) {
134− NFS.closeSync(streamFd);
134+ NodeFS.closeSync(streamFd);
135135 }
136136 return makeDirectBootstrapStream(fd);
137137 }
@@ -146,15 +146,15 @@ const makeBootstrapInputStream = (fd: number) => · 8 unmodified lines
146146 });
147147 });
148148
149−const makeDirectBootstrapStream = (fd: number): Readable => {
149+const makeDirectBootstrapStream = (fd: number): NodeStream.Readable => {
150150 try {
151− return NFS.createReadStream("", {
151+ return NodeFS.createReadStream("", {
152152 fd,
153153 encoding: "utf8",
154154 autoClose: true,
155155 });
156156 } catch {
157− const stream = new Net.Socket({
157+ const stream = new NodeNet.Socket({
158158 fd,
159159 readable: true,
160160 writable: false,
apps/server/src/checkpointing/CheckpointStore.test.ts+4−4
@@ -1,5 +1,5 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import path from "node:path";
2+import * as NodePath from "node:path";
33
44 import * as NodeServices from "@effect/platform-node/NodeServices";
55 import { it } from "@effect/vitest";
@@ -80,7 +80,7 @@ function initRepoWithCommit( · 74 unmodified lines
8080 yield* git(cwd, ["init"]);
8181 yield* git(cwd, ["config", "user.email", "test@test.com"]);
8282 yield* git(cwd, ["config", "user.name", "Test"]);
83− yield* writeTextFile(path.join(cwd, "README.md"), "# test\n");
83+ yield* writeTextFile(NodePath.join(cwd, "README.md"), "# test\n");
8484 yield* git(cwd, ["add", "."]);
8585 yield* git(cwd, ["commit", "-m", "initial commit"]);
8686 });
@@ -107,7 +107,7 @@ it.layer(TestLayer)("CheckpointStore.layer", (it) => { · 20 unmodified lines
107107 cwd: tmp,
108108 checkpointRef: fromCheckpointRef,
109109 });
110− yield* writeTextFile(path.join(tmp, "README.md"), buildLargeText());
110+ yield* writeTextFile(NodePath.join(tmp, "README.md"), buildLargeText());
111111 yield* checkpointStore.captureCheckpoint({
112112 cwd: tmp,
113113 checkpointRef: toCheckpointRef,
@@ -135,7 +135,7 @@ it.layer(TestLayer)("CheckpointStore.layer", (it) => { · 21 unmodified lines
135135 const fromCheckpointRef = checkpointRefForThreadTurn(threadId, 0);
136136 const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1);
137137
138− const componentPath = path.join(tmp, "Component.tsx");
138+ const componentPath = NodePath.join(tmp, "Component.tsx");
139139 yield* writeTextFile(
140140 componentPath,
141141 [
apps/server/src/cloud/CliTokenManager.ts+2−2
@@ -1,5 +1,5 @@
11 // @effect-diagnostics nodeBuiltinImport:off - The CLI loopback OAuth callback is a Node HTTP boundary.
2−import { createServer } from "node:http";
2+import * as NodeHttp from "node:http";
33
44 import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
55 import * as Clock from "effect/Clock";
@@ -206,7 +206,7 @@ export const make = Effect.gen(function* () { · 200 unmodified lines
206206 disableLogger: true,
207207 }).pipe(
208208 Layer.provide(
209− NodeHttpServer.layer(createServer, {
209+ NodeHttpServer.layer(NodeHttp.createServer, {
210210 host: "127.0.0.1",
211211 port: 34338,
212212 disablePreemptiveShutdown: true,
apps/server/src/cloud/http.ts+2−2
@@ -1,4 +1,4 @@
1−import { createPublicKey } from "node:crypto";
1+import * as NodeCrypto from "node:crypto";
22 import {
33 AuthRelayReadScope,
44 AuthRelayWriteScope,
@@ -152,7 +152,7 @@ function validateCloudMintPublicKey( · 147 unmodified lines
152152 publicKey: string,
153153 ): Effect.Effect<void, EnvironmentHttpBadRequestError> {
154154 return Effect.try({
155− try: () => createPublicKey(publicKey.replace(/\\n/g, "\n")),
155+ try: () => NodeCrypto.createPublicKey(publicKey.replace(/\\n/g, "\n")),
156156 catch: () =>
157157 new EnvironmentHttpBadRequestError({
158158 message: "Cloud mint public key must be a valid Ed25519 public key.",
apps/server/src/environment/ServerEnvironment.test.ts+2−2
@@ -1,5 +1,5 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { dirname } from "node:path";
2+import * as NodePath from "node:path";
33 import * as NodeServices from "@effect/platform-node/NodeServices";
44 import { expect, it } from "@effect/vitest";
55 import * as Effect from "effect/Effect";
@@ -76,7 +76,7 @@ it.layer(NodeServices.layer)("ServerEnvironmentLive", (it) => { · 70 unmodified lines
7676 });
7777 const serverConfig = yield* makeServerConfig(baseDir);
7878 const environmentIdPath = serverConfig.environmentIdPath;
79− yield* fileSystem.makeDirectory(dirname(environmentIdPath), { recursive: true });
79+ yield* fileSystem.makeDirectory(NodePath.dirname(environmentIdPath), { recursive: true });
8080 yield* fileSystem.writeFileString(environmentIdPath, "persisted-environment-id\n");
8181 const writeAttempts: string[] = [];
8282 const failingFileSystemLayer = FileSystem.layerNoop({
apps/server/src/git/GitManager.test.ts+64−56
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import path from "node:path";
4−import { spawnSync } from "node:child_process";
2+import * as NodeFS from "node:fs";
3+import * as NodePath from "node:path";
4+import * as NodeChildProcess from "node:child_process";
55
66 import * as NodeServices from "@effect/platform-node/NodeServices";
77 import { it } from "@effect/vitest";
@@ -164,7 +164,7 @@ function normalizeFakePullRequestSummary(raw: unknown): GitHubCli.GitHubPullRequ · 156 unmodified lines
164164 }
165165
166166 function runGitSyncForFakeGh(cwd: string, args: readonly string[]): void {
167− const result = spawnSync("git", args, {
167+ const result = NodeChildProcess.spawnSync("git", args, {
168168 cwd,
169169 encoding: "utf8",
170170 });
@@ -254,7 +254,7 @@ function initRepo( · 83 unmodified lines
254254 yield* runGit(cwd, ["init", "--initial-branch=main"]);
255255 yield* runGit(cwd, ["config", "user.email", "test@example.com"]);
256256 yield* runGit(cwd, ["config", "user.name", "Test User"]);
257− yield* fs.writeFileString(path.join(cwd, "README.md"), "hello\n");
257+ yield* fs.writeFileString(NodePath.join(cwd, "README.md"), "hello\n");
258258 yield* runGit(cwd, ["add", "README.md"]);
259259 yield* runGit(cwd, ["commit", "-m", "Initial commit"]);
260260 });
@@ -459,7 +459,7 @@ function createGitHubCliWithFakeGh(scenario: FakeGhScenario = {}): { · 198 unmodified lines
459459 try: () => {
460460 const headBranch = scenario.pullRequest?.headRefName;
461461 if (headBranch) {
462− const existingBranch = spawnSync(
462+ const existingBranch = NodeChildProcess.spawnSync(
463463 "git",
464464 ["show-ref", "--verify", "--quiet", `refs/heads/${headBranch}`],
465465 {
@@ -916,7 +916,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 450 unmodified lines
916916 it.effect("status returns an explicit non-repo result for deleted directories", () =>
917917 Effect.gen(function* () {
918918 const rootDir = yield* makeTempDir("t3code-git-manager-missing-dir-");
919− const cwd = path.join(rootDir, "deleted-repo");
919+ const cwd = NodePath.join(rootDir, "deleted-repo");
920920 yield* makeDirectory(cwd);
921921 yield* removePath(cwd);
922922 const { manager } = yield* makeManager();
@@ -1026,7 +1026,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 103 unmodified lines
10261026 const forkDir = yield* createBareRemote();
10271027 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
10281028 yield* runGit(repoDir, ["checkout", "-b", "statemachine"]);
1029− fs.writeFileSync(path.join(repoDir, "fork-pr.txt"), "fork pr\n");
1029+ NodeFS.writeFileSync(NodePath.join(repoDir, "fork-pr.txt"), "fork pr\n");
10301030 yield* runGit(repoDir, ["add", "fork-pr.txt"]);
10311031 yield* runGit(repoDir, ["commit", "-m", "Fork PR branch"]);
10321032 yield* runGit(repoDir, ["push", "-u", "fork-seed", "statemachine"]);
@@ -1348,7 +1348,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 315 unmodified lines
13481348 Effect.gen(function* () {
13491349 const repoDir = yield* makeTempDir("t3code-git-manager-");
13501350 yield* initRepo(repoDir);
1351− fs.writeFileSync(path.join(repoDir, "README.md"), "hello\nworld\n");
1351+ NodeFS.writeFileSync(NodePath.join(repoDir, "README.md"), "hello\nworld\n");
13521352
13531353 const { manager } = yield* makeManager();
13541354 const result = yield* runStackedAction(manager, {
@@ -1383,7 +1383,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 28 unmodified lines
13831383 Effect.gen(function* () {
13841384 const repoDir = yield* makeTempDir("t3code-git-manager-");
13851385 yield* initRepo(repoDir);
1386− fs.writeFileSync(path.join(repoDir, "README.md"), "hello\ncustom\n");
1386+ NodeFS.writeFileSync(NodePath.join(repoDir, "README.md"), "hello\ncustom\n");
13871387 let generatedCount = 0;
13881388
13891389 const { manager } = yield* makeManager({
@@ -1426,8 +1426,8 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 36 unmodified lines
14261426 Effect.gen(function* () {
14271427 const repoDir = yield* makeTempDir("t3code-git-manager-");
14281428 yield* initRepo(repoDir);
1429− fs.writeFileSync(path.join(repoDir, "a.txt"), "file a\n");
1430− fs.writeFileSync(path.join(repoDir, "b.txt"), "file b\n");
1429+ NodeFS.writeFileSync(NodePath.join(repoDir, "a.txt"), "file a\n");
1430+ NodeFS.writeFileSync(NodePath.join(repoDir, "b.txt"), "file b\n");
14311431
14321432 const { manager } = yield* makeManager();
14331433 const result = yield* runStackedAction(manager, {
@@ -1454,7 +1454,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 20 unmodified lines
14541454 const remoteDir = yield* createBareRemote();
14551455 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
14561456 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
1457− fs.writeFileSync(path.join(repoDir, "README.md"), "hello\nfeature-branch\n");
1457+ NodeFS.writeFileSync(NodePath.join(repoDir, "README.md"), "hello\nfeature-branch\n");
14581458 let generatedCount = 0;
14591459
14601460 const { manager } = yield* makeManager({
@@ -1514,7 +1514,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 53 unmodified lines
15141514 Effect.gen(function* () {
15151515 const repoDir = yield* makeTempDir("t3code-git-manager-");
15161516 yield* initRepo(repoDir);
1517− fs.writeFileSync(path.join(repoDir, "README.md"), "hello\ncustom-feature\n");
1517+ NodeFS.writeFileSync(NodePath.join(repoDir, "README.md"), "hello\ncustom-feature\n");
15181518 let generatedCount = 0;
15191519
15201520 const { manager } = yield* makeManager({
@@ -1597,7 +1597,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 76 unmodified lines
15971597 yield* runGit(repoDir, ["checkout", "-b", "feature/stacked-flow"]);
15981598 const remoteDir = yield* createBareRemote();
15991599 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
1600− fs.writeFileSync(path.join(repoDir, "feature.txt"), "feature\n");
1600+ NodeFS.writeFileSync(NodePath.join(repoDir, "feature.txt"), "feature\n");
16011601
16021602 const { manager } = yield* makeManager();
16031603 const result = yield* runStackedAction(manager, {
@@ -1626,7 +1626,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 22 unmodified lines
16261626 yield* runGit(repoDir, ["checkout", "-b", "feature/no-upstream-pr"]);
16271627 const remoteDir = yield* createBareRemote();
16281628 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
1629− fs.writeFileSync(path.join(repoDir, "feature.txt"), "feature\n");
1629+ NodeFS.writeFileSync(NodePath.join(repoDir, "feature.txt"), "feature\n");
16301630
16311631 const { manager, ghCalls } = yield* makeManager({
16321632 ghScenario: {
@@ -1697,7 +1697,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 64 unmodified lines
16971697 yield* runGit(repoDir, ["checkout", "-b", "feature/push-only"]);
16981698 const remoteDir = yield* createBareRemote();
16991699 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
1700− fs.writeFileSync(path.join(repoDir, "push-only.txt"), "push only\n");
1700+ NodeFS.writeFileSync(NodePath.join(repoDir, "push-only.txt"), "push only\n");
17011701 yield* runGit(repoDir, ["add", "push-only.txt"]);
17021702 yield* runGit(repoDir, ["commit", "-m", "Push only branch"]);
17031703
@@ -1725,11 +1725,11 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 21 unmodified lines
17251725 yield* runGit(repoDir, ["checkout", "-b", "feature/push-dirty"]);
17261726 const remoteDir = yield* createBareRemote();
17271727 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
1728− fs.writeFileSync(path.join(repoDir, "push-dirty.txt"), "push dirty\n");
1728+ NodeFS.writeFileSync(NodePath.join(repoDir, "push-dirty.txt"), "push dirty\n");
17291729 yield* runGit(repoDir, ["add", "push-dirty.txt"]);
17301730 yield* runGit(repoDir, ["commit", "-m", "Push dirty branch"]);
1731− fs.mkdirSync(path.join(repoDir, ".vercel"));
1732− fs.writeFileSync(path.join(repoDir, ".vercel", "project.json"), "{}\n");
1731+ NodeFS.mkdirSync(NodePath.join(repoDir, ".vercel"));
1732+ NodeFS.writeFileSync(NodePath.join(repoDir, ".vercel", "project.json"), "{}\n");
17331733
17341734 const { manager } = yield* makeManager();
17351735 const result = yield* runStackedAction(manager, {
@@ -1760,7 +1760,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 24 unmodified lines
17601760 yield* runGit(repoDir, ["checkout", "-b", "feature/create-pr-only"]);
17611761 const remoteDir = yield* createBareRemote();
17621762 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
1763− fs.writeFileSync(path.join(repoDir, "create-pr-only.txt"), "create pr\n");
1763+ NodeFS.writeFileSync(NodePath.join(repoDir, "create-pr-only.txt"), "create pr\n");
17641764 yield* runGit(repoDir, ["add", "create-pr-only.txt"]);
17651765 yield* runGit(repoDir, ["commit", "-m", "Create PR only branch"]);
17661766
@@ -1805,7 +1805,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 38 unmodified lines
18051805 const repoDir = yield* makeTempDir("t3code-git-manager-");
18061806 yield* initRepo(repoDir);
18071807 yield* runGit(repoDir, ["checkout", "-b", "feature/provider-fallback"]);
1808− fs.writeFileSync(path.join(repoDir, "provider-fallback.txt"), "fallback\n");
1808+ NodeFS.writeFileSync(NodePath.join(repoDir, "provider-fallback.txt"), "fallback\n");
18091809 yield* runGit(repoDir, ["add", "provider-fallback.txt"]);
18101810 yield* runGit(repoDir, ["commit", "-m", "Provider fallback"]);
18111811 const remoteDir = yield* createBareRemote();
@@ -1982,7 +1982,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 170 unmodified lines
19821982 yield* runGit(repoDir, ["checkout", "main"]);
19831983 yield* runGit(repoDir, ["branch", "-D", "effect-atom"]);
19841984 yield* runGit(repoDir, ["checkout", "--track", "my-org/upstream/effect-atom"]);
1985− fs.writeFileSync(path.join(repoDir, "changes.txt"), "change\n");
1985+ NodeFS.writeFileSync(NodePath.join(repoDir, "changes.txt"), "change\n");
19861986 yield* runGit(repoDir, ["add", "changes.txt"]);
19871987 yield* runGit(repoDir, ["commit", "-m", "Feature commit"]);
19881988
@@ -2200,7 +2200,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 211 unmodified lines
22002200 yield* runGit(repoDir, ["checkout", "-b", "feature-create-pr"]);
22012201 const remoteDir = yield* createBareRemote();
22022202 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
2203− fs.writeFileSync(path.join(repoDir, "changes.txt"), "change\n");
2203+ NodeFS.writeFileSync(NodePath.join(repoDir, "changes.txt"), "change\n");
22042204 yield* runGit(repoDir, ["add", "changes.txt"]);
22052205 yield* runGit(repoDir, ["commit", "-m", "Feature commit"]);
22062206 yield* runGit(repoDir, ["push", "-u", "origin", "feature-create-pr"]);
@@ -2252,7 +2252,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 45 unmodified lines
22522252 yield* runGit(peerDir, ["clone", remoteDir, "."]);
22532253 yield* runGit(peerDir, ["config", "user.email", "peer@example.com"]);
22542254 yield* runGit(peerDir, ["config", "user.name", "Peer User"]);
2255− fs.writeFileSync(path.join(peerDir, "remote.txt"), "remote\n");
2255+ NodeFS.writeFileSync(NodePath.join(peerDir, "remote.txt"), "remote\n");
22562256 yield* runGit(peerDir, ["add", "remote.txt"]);
22572257 yield* runGit(peerDir, ["commit", "-m", "Remote base commit"]);
22582258 yield* runGit(peerDir, ["push", "origin", "main"]);
@@ -2265,7 +2265,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 6 unmodified lines
22652265 "feature/remote-base",
22662266 "origin/main",
22672267 ]);
2268− fs.writeFileSync(path.join(repoDir, "feature.txt"), "feature\n");
2268+ NodeFS.writeFileSync(NodePath.join(repoDir, "feature.txt"), "feature\n");
22692269 yield* runGit(repoDir, ["add", "feature.txt"]);
22702270 yield* runGit(repoDir, ["commit", "-m", "Feature commit"]);
22712271 yield* runGit(repoDir, ["push", "-u", "origin", "feature/remote-base"]);
@@ -2304,7 +2304,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 32 unmodified lines
23042304 yield* runGit(repoDir, ["checkout", "-b", "feature/no-fork-match"]);
23052305 const remoteDir = yield* createBareRemote();
23062306 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
2307− fs.writeFileSync(path.join(repoDir, "changes.txt"), "change\n");
2307+ NodeFS.writeFileSync(NodePath.join(repoDir, "changes.txt"), "change\n");
23082308 yield* runGit(repoDir, ["add", "changes.txt"]);
23092309 yield* runGit(repoDir, ["commit", "-m", "Feature commit"]);
23102310 yield* runGit(repoDir, ["push", "-u", "origin", "feature/no-fork-match"]);
@@ -2376,7 +2376,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 65 unmodified lines
23762376 const forkDir = yield* createBareRemote();
23772377 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
23782378 yield* runGit(repoDir, ["checkout", "-b", "statemachine"]);
2379− fs.writeFileSync(path.join(repoDir, "changes.txt"), "change\n");
2379+ NodeFS.writeFileSync(NodePath.join(repoDir, "changes.txt"), "change\n");
23802380 yield* runGit(repoDir, ["add", "changes.txt"]);
23812381 yield* runGit(repoDir, ["commit", "-m", "Feature commit"]);
23822382 yield* runGit(repoDir, ["push", "-u", "fork-seed", "statemachine"]);
@@ -2556,7 +2556,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 173 unmodified lines
25562556 const repoDir = yield* makeTempDir("t3code-git-manager-");
25572557 yield* initRepo(repoDir);
25582558 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-local"]);
2559− fs.writeFileSync(path.join(repoDir, "local.txt"), "local\n");
2559+ NodeFS.writeFileSync(NodePath.join(repoDir, "local.txt"), "local\n");
25602560 yield* runGit(repoDir, ["add", "local.txt"]);
25612561 yield* runGit(repoDir, ["commit", "-m", "Local PR branch"]);
25622562
@@ -2597,7 +2597,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 34 unmodified lines
25972597 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
25982598 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
25992599 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-local-upstream"]);
2600− fs.writeFileSync(path.join(repoDir, "upstream.txt"), "upstream\n");
2600+ NodeFS.writeFileSync(NodePath.join(repoDir, "upstream.txt"), "upstream\n");
26012601 yield* runGit(repoDir, ["add", "upstream.txt"]);
26022602 yield* runGit(repoDir, ["commit", "-m", "Local upstream PR branch"]);
26032603 yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-local-upstream"]);
@@ -2655,7 +2655,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 51 unmodified lines
26552655 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
26562656 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
26572657 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-local-no-head-repo"]);
2658− fs.writeFileSync(path.join(repoDir, "no-head-repo.txt"), "upstream\n");
2658+ NodeFS.writeFileSync(NodePath.join(repoDir, "no-head-repo.txt"), "upstream\n");
26592659 yield* runGit(repoDir, ["add", "no-head-repo.txt"]);
26602660 yield* runGit(repoDir, ["commit", "-m", "Local PR branch without repo metadata"]);
26612661 yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-local-no-head-repo"]);
@@ -2702,7 +2702,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 40 unmodified lines
27022702 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
27032703 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
27042704 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-worktree"]);
2705− fs.writeFileSync(path.join(repoDir, "worktree.txt"), "worktree\n");
2705+ NodeFS.writeFileSync(NodePath.join(repoDir, "worktree.txt"), "worktree\n");
27062706 yield* runGit(repoDir, ["add", "worktree.txt"]);
27072707 yield* runGit(repoDir, ["commit", "-m", "PR worktree branch"]);
27082708 yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-worktree"]);
@@ -2730,7 +2730,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 21 unmodified lines
27302730
27312731 expect(result.branch).toBe("feature/pr-worktree");
27322732 expect(result.worktreePath).not.toBeNull();
2733− expect(fs.existsSync(result.worktreePath as string)).toBe(true);
2733+ expect(NodeFS.existsSync(result.worktreePath as string)).toBe(true);
27342734 const worktreeBranch = (yield* runGit(result.worktreePath as string, [
27352735 "branch",
27362736 "--show-current",
@@ -2747,7 +2747,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 10 unmodified lines
27472747 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
27482748 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
27492749 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-worktree-setup"]);
2750− fs.writeFileSync(path.join(repoDir, "setup.txt"), "setup\n");
2750+ NodeFS.writeFileSync(NodePath.join(repoDir, "setup.txt"), "setup\n");
27512751 yield* runGit(repoDir, ["add", "setup.txt"]);
27522752 yield* runGit(repoDir, ["commit", "-m", "PR worktree setup branch"]);
27532753 yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-worktree-setup"]);
@@ -2802,7 +2802,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 48 unmodified lines
28022802 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
28032803 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
28042804 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-fork"]);
2805− fs.writeFileSync(path.join(repoDir, "fork.txt"), "fork\n");
2805+ NodeFS.writeFileSync(NodePath.join(repoDir, "fork.txt"), "fork\n");
28062806 yield* runGit(repoDir, ["add", "fork.txt"]);
28072807 yield* runGit(repoDir, ["commit", "-m", "Fork PR branch"]);
28082808 yield* runGit(repoDir, ["push", "-u", "fork-seed", "feature/pr-fork"]);
@@ -2864,7 +2864,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 55 unmodified lines
28642864 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
28652865 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
28662866 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-local-fork"]);
2867− fs.writeFileSync(path.join(repoDir, "local-fork.txt"), "local fork\n");
2867+ NodeFS.writeFileSync(NodePath.join(repoDir, "local-fork.txt"), "local fork\n");
28682868 yield* runGit(repoDir, ["add", "local-fork.txt"]);
28692869 yield* runGit(repoDir, ["commit", "-m", "Local fork PR branch"]);
28702870 yield* runGit(repoDir, ["push", "-u", "fork-seed", "feature/pr-local-fork"]);
@@ -2917,7 +2917,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 46 unmodified lines
29172917 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
29182918 yield* runGit(repoDir, ["remote", "add", "binbandit-seed", forkDir]);
29192919 yield* runGit(repoDir, ["checkout", "-b", "fix/git-action-default-without-origin"]);
2920− fs.writeFileSync(path.join(repoDir, "derived-fork.txt"), "derived fork\n");
2920+ NodeFS.writeFileSync(NodePath.join(repoDir, "derived-fork.txt"), "derived fork\n");
29212921 yield* runGit(repoDir, ["add", "derived-fork.txt"]);
29222922 yield* runGit(repoDir, ["commit", "-m", "Derived fork PR branch"]);
29232923 yield* runGit(repoDir, [
@@ -2969,11 +2969,15 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 45 unmodified lines
29692969 const repoDir = yield* makeTempDir("t3code-git-manager-");
29702970 yield* initRepo(repoDir);
29712971 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-existing-worktree"]);
2972− fs.writeFileSync(path.join(repoDir, "existing.txt"), "existing\n");
2972+ NodeFS.writeFileSync(NodePath.join(repoDir, "existing.txt"), "existing\n");
29732973 yield* runGit(repoDir, ["add", "existing.txt"]);
29742974 yield* runGit(repoDir, ["commit", "-m", "Existing worktree branch"]);
29752975 yield* runGit(repoDir, ["checkout", "main"]);
2976− const worktreePath = path.join(repoDir, "..", `pr-existing-${path.basename(repoDir)}`);
2976+ const worktreePath = NodePath.join(
2977+ repoDir,
2978+ "..",
2979+ `pr-existing-${NodePath.basename(repoDir)}`,
2980+ );
29772981 yield* runGit(repoDir, ["worktree", "add", worktreePath, "feature/pr-existing-worktree"]);
29782982
29792983 const setupCalls: ProjectSetupScriptRunner.ProjectSetupScriptRunnerInput[] = [];
@@ -3004,8 +3008,8 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 24 unmodified lines
30043008 threadId: asThreadId("thread-pr-existing-worktree"),
30053009 });
30063010
3007− expect(result.worktreePath && fs.realpathSync.native(result.worktreePath)).toBe(
3008− fs.realpathSync.native(worktreePath),
3011+ expect(result.worktreePath && NodeFS.realpathSync.native(result.worktreePath)).toBe(
3012+ NodeFS.realpathSync.native(worktreePath),
30093013 );
30103014 expect(result.branch).toBe("feature/pr-existing-worktree");
30113015 expect(setupCalls).toHaveLength(0);
@@ -3024,7 +3028,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 12 unmodified lines
30243028 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
30253029 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
30263030 yield* runGit(repoDir, ["checkout", "-b", "fork-main-source"]);
3027− fs.writeFileSync(path.join(repoDir, "fork-main.txt"), "fork main\n");
3031+ NodeFS.writeFileSync(NodePath.join(repoDir, "fork-main.txt"), "fork main\n");
30283032 yield* runGit(repoDir, ["add", "fork-main.txt"]);
30293033 yield* runGit(repoDir, ["commit", "-m", "Fork main branch"]);
30303034 yield* runGit(repoDir, ["push", "-u", "fork-seed", "fork-main-source:main"]);
@@ -3084,7 +3088,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 53 unmodified lines
30843088 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
30853089 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
30863090 yield* runGit(repoDir, ["checkout", "-b", "fork-main-source"]);
3087− fs.writeFileSync(path.join(repoDir, "fork-main-second.txt"), "fork main second\n");
3091+ NodeFS.writeFileSync(NodePath.join(repoDir, "fork-main-second.txt"), "fork main second\n");
30883092 yield* runGit(repoDir, ["add", "fork-main-second.txt"]);
30893093 yield* runGit(repoDir, ["commit", "-m", "Fork main second branch"]);
30903094 yield* runGit(repoDir, ["push", "-u", "fork-seed", "fork-main-source:main"]);
@@ -3142,12 +3146,16 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 51 unmodified lines
31423146 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
31433147 yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]);
31443148 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-reused-fork"]);
3145− fs.writeFileSync(path.join(repoDir, "reused-fork.txt"), "reused fork\n");
3149+ NodeFS.writeFileSync(NodePath.join(repoDir, "reused-fork.txt"), "reused fork\n");
31463150 yield* runGit(repoDir, ["add", "reused-fork.txt"]);
31473151 yield* runGit(repoDir, ["commit", "-m", "Reused fork PR branch"]);
31483152 yield* runGit(repoDir, ["push", "-u", "fork-seed", "feature/pr-reused-fork"]);
31493153 yield* runGit(repoDir, ["checkout", "main"]);
3150− const worktreePath = path.join(repoDir, "..", `pr-reused-fork-${path.basename(repoDir)}`);
3154+ const worktreePath = NodePath.join(
3155+ repoDir,
3156+ "..",
3157+ `pr-reused-fork-${NodePath.basename(repoDir)}`,
3158+ );
31513159 yield* runGit(repoDir, ["worktree", "add", worktreePath, "feature/pr-reused-fork"]);
31523160 yield* runGit(worktreePath, ["branch", "--unset-upstream"], true);
31533161
@@ -3179,8 +3187,8 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 25 unmodified lines
31793187 mode: "worktree",
31803188 });
31813189
3182− expect(result.worktreePath && fs.realpathSync.native(result.worktreePath)).toBe(
3183− fs.realpathSync.native(worktreePath),
3190+ expect(result.worktreePath && NodeFS.realpathSync.native(result.worktreePath)).toBe(
3191+ NodeFS.realpathSync.native(worktreePath),
31843192 );
31853193 expect(
31863194 (yield* runGit(worktreePath, ["rev-parse", "--abbrev-ref", "@{upstream}"])).stdout.trim(),
@@ -3196,7 +3204,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 9 unmodified lines
31963204 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
31973205 yield* runGit(repoDir, ["push", "-u", "origin", "main"]);
31983206 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-setup-failure"]);
3199− fs.writeFileSync(path.join(repoDir, "setup-failure.txt"), "setup failure\n");
3207+ NodeFS.writeFileSync(NodePath.join(repoDir, "setup-failure.txt"), "setup failure\n");
32003208 yield* runGit(repoDir, ["add", "setup-failure.txt"]);
32013209 yield* runGit(repoDir, ["commit", "-m", "PR setup failure branch"]);
32023210 yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-setup-failure"]);
@@ -3236,7 +3244,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 33 unmodified lines
32363244
32373245 expect(result.branch).toBe("feature/pr-setup-failure");
32383246 expect(result.worktreePath).not.toBeNull();
3239− expect(fs.existsSync(result.worktreePath as string)).toBe(true);
3247+ expect(NodeFS.existsSync(result.worktreePath as string)).toBe(true);
32403248 }),
32413249 );
32423250
@@ -3276,9 +3284,9 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 33 unmodified lines
32763284 Effect.gen(function* () {
32773285 const repoDir = yield* makeTempDir("t3code-git-manager-");
32783286 yield* initRepo(repoDir);
3279− fs.writeFileSync(path.join(repoDir, "hooked.txt"), "hooked\n");
3280− fs.writeFileSync(
3281− path.join(repoDir, ".git", "hooks", "pre-commit"),
3287+ NodeFS.writeFileSync(NodePath.join(repoDir, "hooked.txt"), "hooked\n");
3288+ NodeFS.writeFileSync(
3289+ NodePath.join(repoDir, ".git", "hooks", "pre-commit"),
32823290 '#!/bin/sh\necho "hook: start" >&2\nsleep 0.05\necho "hook: end" >&2\n',
32833291 { mode: 0o755 },
32843292 );
@@ -3339,9 +3347,9 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 54 unmodified lines
33393347 Effect.gen(function* () {
33403348 const repoDir = yield* makeTempDir("t3code-git-manager-");
33413349 yield* initRepo(repoDir);
3342− fs.writeFileSync(path.join(repoDir, "hook-failure.txt"), "broken\n");
3343− fs.writeFileSync(
3344− path.join(repoDir, ".git", "hooks", "pre-commit"),
3350+ NodeFS.writeFileSync(NodePath.join(repoDir, "hook-failure.txt"), "broken\n");
3351+ NodeFS.writeFileSync(
3352+ NodePath.join(repoDir, ".git", "hooks", "pre-commit"),
33453353 '#!/bin/sh\necho "hook: fail" >&2\nexit 1\n',
33463354 { mode: 0o755 },
33473355 );
@@ -3392,7 +3400,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 44 unmodified lines
33923400 yield* runGit(repoDir, ["checkout", "-b", "feature/pr-only-follow-up"]);
33933401 const remoteDir = yield* createBareRemote();
33943402 yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]);
3395− fs.writeFileSync(path.join(repoDir, "pr-only.txt"), "pr only\n");
3403+ NodeFS.writeFileSync(NodePath.join(repoDir, "pr-only.txt"), "pr only\n");
33963404 yield* runGit(repoDir, ["add", "pr-only.txt"]);
33973405 yield* runGit(repoDir, ["commit", "-m", "PR only branch"]);
33983406 yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-only-follow-up"]);
apps/server/src/git/Utils.ts+3−3
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { existsSync } from "node:fs";
3−import { join } from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodePath from "node:path";
44
55 export function isGitRepository(cwd: string): boolean {
6− return existsSync(join(cwd, ".git"));
6+ return NodeFS.existsSync(NodePath.join(cwd, ".git"));
77 }
apps/server/src/orchestration/Layers/CheckpointReactor.test.ts+17−17
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
5−import { execFileSync } from "node:child_process";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
5+import * as NodeChildProcess from "node:child_process";
66
77 import {
88 ProviderDriverKind,
@@ -198,7 +198,7 @@ async function waitForEvent( · 189 unmodified lines
198198 }
199199
200200 function runGit(cwd: string, args: ReadonlyArray<string>) {
201− return execFileSync("git", args, {
201+ return NodeChildProcess.execFileSync("git", args, {
202202 cwd,
203203 stdio: ["ignore", "pipe", "pipe"],
204204 encoding: "utf8",
@@ -206,11 +206,11 @@ function runGit(cwd: string, args: ReadonlyArray<string>) { · 1 unmodified line
206206 }
207207
208208 function createGitRepository() {
209− const cwd = fs.mkdtempSync(path.join(os.tmpdir(), "t3-checkpoint-handler-"));
209+ const cwd = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-checkpoint-handler-"));
210210 runGit(cwd, ["init", "--initial-branch=main"]);
211211 runGit(cwd, ["config", "user.email", "test@example.com"]);
212212 runGit(cwd, ["config", "user.name", "Test User"]);
213− fs.writeFileSync(path.join(cwd, "README.md"), "v1\n", "utf8");
213+ NodeFS.writeFileSync(NodePath.join(cwd, "README.md"), "v1\n", "utf8");
214214 runGit(cwd, ["add", "."]);
215215 runGit(cwd, ["commit", "-m", "Initial"]);
216216 return cwd;
@@ -267,7 +267,7 @@ describe("CheckpointReactor", () => { · 50 unmodified lines
267267 while (tempDirs.length > 0) {
268268 const dir = tempDirs.pop();
269269 if (dir) {
270− fs.rmSync(dir, { recursive: true, force: true });
270+ NodeFS.rmSync(dir, { recursive: true, force: true });
271271 }
272272 }
273273 });
@@ -395,14 +395,14 @@ describe("CheckpointReactor", () => { · 121 unmodified lines
395395 checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0),
396396 }),
397397 );
398− fs.writeFileSync(path.join(cwd, "README.md"), "v2\n", "utf8");
398+ NodeFS.writeFileSync(NodePath.join(cwd, "README.md"), "v2\n", "utf8");
399399 await runtime.runPromise(
400400 checkpointStore.captureCheckpoint({
401401 cwd,
402402 checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1),
403403 }),
404404 );
405− fs.writeFileSync(path.join(cwd, "README.md"), "v3\n", "utf8");
405+ NodeFS.writeFileSync(NodePath.join(cwd, "README.md"), "v3\n", "utf8");
406406 await runtime.runPromise(
407407 checkpointStore.captureCheckpoint({
408408 cwd,
@@ -456,7 +456,7 @@ describe("CheckpointReactor", () => { · 47 unmodified lines
456456 checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0),
457457 );
458458
459− fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8");
459+ NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8");
460460 harness.provider.emit({
461461 type: "turn.completed",
462462 eventId: EventId.make("evt-turn-completed-1"),
@@ -554,7 +554,7 @@ describe("CheckpointReactor", () => { · 91 unmodified lines
554554 checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0),
555555 );
556556
557− fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8");
557+ NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8");
558558
559559 harness.provider.emit({
560560 type: "turn.completed",
@@ -628,7 +628,7 @@ describe("CheckpointReactor", () => { · 67 unmodified lines
628628 checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0),
629629 );
630630
631− fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8");
631+ NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8");
632632 harness.provider.emit({
633633 type: "turn.completed",
634634 eventId: EventId.make("evt-turn-completed-claude-1"),
@@ -761,7 +761,7 @@ describe("CheckpointReactor", () => { · 126 unmodified lines
761761 }),
762762 );
763763
764− fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8");
764+ NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8");
765765 harness.provider.emit({
766766 type: "turn.completed",
767767 eventId: EventId.make("evt-turn-completed-missing-provider-cwd"),
@@ -829,8 +829,8 @@ describe("CheckpointReactor", () => { · 61 unmodified lines
829829 });
830830
831831 it("continues processing runtime events after a single checkpoint runtime failure", async () => {
832− const nonRepositorySessionCwd = fs.mkdtempSync(
833− path.join(os.tmpdir(), "t3-checkpoint-runtime-non-repo-"),
832+ const nonRepositorySessionCwd = NodeFS.mkdtempSync(
833+ NodePath.join(NodeOS.tmpdir(), "t3-checkpoint-runtime-non-repo-"),
834834 );
835835 tempDirs.push(nonRepositorySessionCwd);
836836
@@ -963,7 +963,7 @@ describe("CheckpointReactor", () => { · 126 unmodified lines
963963 threadId: ThreadId.make("thread-1"),
964964 numTurns: 1,
965965 });
966− expect(fs.readFileSync(path.join(harness.cwd, "README.md"), "utf8")).toBe("v2\n");
966+ expect(NodeFS.readFileSync(NodePath.join(harness.cwd, "README.md"), "utf8")).toBe("v2\n");
967967 expect(
968968 gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2)),
969969 ).toBe(false);
apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts+7−6
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import {
77 ModelSelection,
@@ -107,11 +107,11 @@ describe("ProviderCommandReactor", () => { · 99 unmodified lines
107107 }
108108 runtime = null;
109109 for (const stateDir of createdStateDirs) {
110− fs.rmSync(stateDir, { recursive: true, force: true });
110+ NodeFS.rmSync(stateDir, { recursive: true, force: true });
111111 }
112112 createdStateDirs.clear();
113113 for (const baseDir of createdBaseDirs) {
114− fs.rmSync(baseDir, { recursive: true, force: true });
114+ NodeFS.rmSync(baseDir, { recursive: true, force: true });
115115 }
116116 createdBaseDirs.clear();
117117 });
@@ -147,7 +147,8 @@ describe("ProviderCommandReactor", () => { · 29 unmodified lines
147147 readonly requiresNewThreadForModelChange?: boolean;
148148 }) {
149149 const now = "2026-01-01T00:00:00.000Z";
150− const baseDir = input?.baseDir ?? fs.mkdtempSync(path.join(os.tmpdir(), "t3code-reactor-"));
150+ const baseDir =
151+ input?.baseDir ?? NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3code-reactor-"));
151152 createdBaseDirs.add(baseDir);
152153 const { stateDir } = deriveServerPathsSync(baseDir, undefined);
153154 createdStateDirs.add(stateDir);
apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts+6−6
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import {
77 OrchestrationReadModel,
@@ -198,7 +198,7 @@ describe("ProviderRuntimeIngestion", () => { · 190 unmodified lines
198198 const tempDirs: string[] = [];
199199
200200 function makeTempDir(prefix: string): string {
201− const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
201+ const dir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), prefix));
202202 tempDirs.push(dir);
203203 return dir;
204204 }
@@ -213,13 +213,13 @@ describe("ProviderRuntimeIngestion", () => { · 8 unmodified lines
213213 }
214214 runtime = null;
215215 for (const dir of tempDirs.splice(0)) {
216− fs.rmSync(dir, { recursive: true, force: true });
216+ NodeFS.rmSync(dir, { recursive: true, force: true });
217217 }
218218 });
219219
220220 async function createHarness(options?: { serverSettings?: Partial<ServerSettings> }) {
221221 const workspaceRoot = makeTempDir("t3-provider-project-");
222− fs.mkdirSync(path.join(workspaceRoot, ".git"));
222+ NodeFS.mkdirSync(NodePath.join(workspaceRoot, ".git"));
223223 const provider = createProviderServiceHarness();
224224 const orchestrationLayer = OrchestrationEngineLive.pipe(
225225 Layer.provide(OrchestrationProjectionSnapshotQueryLive),
apps/server/src/pathExpansion.test.ts+5−5
@@ -1,6 +1,6 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { homedir } from "node:os";
3−import { join } from "node:path";
2+import * as NodeOS from "node:os";
3+import * as NodePath from "node:path";
44 import { describe, expect, it } from "vite-plus/test";
55
66 import { expandHomePath } from "./pathExpansion.ts";
@@ -17,15 +17,15 @@ describe("expandHomePath", () => { · 10 unmodified lines
1717 });
1818
1919 it("expands a lone tilde to the home directory", () => {
20− expect(expandHomePath("~")).toBe(homedir());
20+ expect(expandHomePath("~")).toBe(NodeOS.homedir());
2121 });
2222
2323 it("expands ~/ to a subpath of the home directory", () => {
24− expect(expandHomePath("~/.codex-work")).toBe(join(homedir(), ".codex-work"));
24+ expect(expandHomePath("~/.codex-work")).toBe(NodePath.join(NodeOS.homedir(), ".codex-work"));
2525 });
2626
2727 it("expands a Windows-style ~\\ prefix", () => {
28− expect(expandHomePath("~\\.codex")).toBe(join(homedir(), ".codex"));
28+ expect(expandHomePath("~\\.codex")).toBe(NodePath.join(NodeOS.homedir(), ".codex"));
2929 });
3030
3131 it("does not expand ~user paths", () => {
apps/server/src/pathExpansion.ts+4−4
@@ -1,6 +1,6 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { homedir } from "node:os";
3−import { join } from "node:path";
2+import * as NodeOS from "node:os";
3+import * as NodePath from "node:path";
44
55 /**
66 * Expand a leading `~` (or `~/…`, `~\…`) in a user-supplied path to the
@@ -16,9 +16,9 @@ import { join } from "node:path"; · 9 unmodified lines
1616 */
1717 export function expandHomePath(value: string): string {
1818 if (!value) return value;
19− if (value === "~") return homedir();
19+ if (value === "~") return NodeOS.homedir();
2020 if (value.startsWith("~/") || value.startsWith("~\\")) {
21− return join(homedir(), value.slice(2));
21+ return NodePath.join(NodeOS.homedir(), value.slice(2));
2222 }
2323 return value;
2424 }
apps/server/src/persistence/NodeSqliteClient.ts+11−7
@@ -4,7 +4,7 @@ · 3 unmodified lines
44 *
55 * @module SqliteClient
66 */
7−import { DatabaseSync, type StatementSync } from "node:sqlite";
7+import * as NodeSqlite from "node:sqlite";
88
99 import * as Cache from "effect/Cache";
1010 import * as Config from "effect/Config";
@@ -69,7 +69,7 @@ const checkNodeSqliteCompat = () => { · 58 unmodified lines
6969
7070 const makeWithDatabase = Effect.fn("makeWithDatabase")(function* (
7171 options: SqliteClientConfig,
72− openDatabase: () => DatabaseSync,
72+ openDatabase: () => NodeSqlite.DatabaseSync,
7373 ): Effect.fn.Return<Client.SqlClient, never, Scope.Scope | Reactivity.Reactivity> {
7474 yield* checkNodeSqliteCompat();
7575
@@ -86,8 +86,8 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( · 10 unmodified lines
8686 Effect.sync(() => db.close()),
8787 );
8888
89− const statementReaderCache = new WeakMap<StatementSync, boolean>();
90− const hasRows = (statement: StatementSync): boolean => {
89+ const statementReaderCache = new WeakMap<NodeSqlite.StatementSync, boolean>();
90+ const hasRows = (statement: NodeSqlite.StatementSync): boolean => {
9191 const cached = statementReaderCache.get(statement);
9292 if (cached !== undefined) {
9393 return cached;
@@ -113,7 +113,11 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( · 19 unmodified lines
113113 }),
114114 });
115115
116− const runStatement = (statement: StatementSync, params: ReadonlyArray<unknown>, raw: boolean) =>
116+ const runStatement = (
117+ statement: NodeSqlite.StatementSync,
118+ params: ReadonlyArray<unknown>,
119+ raw: boolean,
120+ ) =>
117121 Effect.withFiber<ReadonlyArray<any>, SqlError>((fiber) => {
118122 statement.setReadBigInts(Boolean(Context.get(fiber.context, Client.SafeIntegers)));
119123 try {
@@ -220,7 +224,7 @@ const make = ( · 100 unmodified lines
220224 makeWithDatabase(
221225 options,
222226 () =>
223− new DatabaseSync(options.filename, {
227+ new NodeSqlite.DatabaseSync(options.filename, {
224228 readOnly: options.readonly ?? false,
225229 allowExtension: options.allowExtension ?? false,
226230 }),
@@ -236,7 +240,7 @@ const makeMemory = ( · 9 unmodified lines
236240 readonly: false,
237241 },
238242 () => {
239− const database = new DatabaseSync(":memory:", {
243+ const database = new NodeSqlite.DatabaseSync(":memory:", {
240244 allowExtension: config.allowExtension ?? false,
241245 });
242246 return database;
apps/server/src/preview/PortScanner.test.ts+4−4
@@ -1,4 +1,4 @@
1−import * as net from "node:net";
1+import * as NodeNet from "node:net";
22
33 import { it as effectIt } from "@effect/vitest";
44 import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
@@ -17,9 +17,9 @@ const TestPortDiscoveryLive = PortScanner.layer.pipe( · 12 unmodified lines
1717 ),
1818 );
1919
20−const openServer = (port: number): Effect.Effect<net.Server | null> =>
20+const openServer = (port: number): Effect.Effect<NodeNet.Server | null> =>
2121 Effect.callback((resume) => {
22− const server = net.createServer();
22+ const server = NodeNet.createServer();
2323 server.once("error", () => {
2424 resume(Effect.succeed(null));
2525 });
@@ -31,7 +31,7 @@ const openServer = (port: number): Effect.Effect<net.Server | null> => · 5 unmodified lines
3131 });
3232 });
3333
34−const closeServer = (server: net.Server): Effect.Effect<void> =>
34+const closeServer = (server: NodeNet.Server): Effect.Effect<void> =>
3535 Effect.callback((resume) => {
3636 server.close(() => resume(Effect.void));
3737 });
apps/server/src/provider/Layers/ClaudeAdapter.test.ts+9−9
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import * as NodeServices from "@effect/platform-node/NodeServices";
77 import type {
@@ -395,7 +395,7 @@ describe("ClaudeAdapterLive", () => { · 387 unmodified lines
395395 });
396396
397397 const createInput = harness.getLastCreateQueryInput();
398− assert.equal(createInput?.options.env?.HOME, path.join(os.homedir(), ".claude-work"));
398+ assert.equal(createInput?.options.env?.HOME, NodePath.join(NodeOS.homedir(), ".claude-work"));
399399 }).pipe(
400400 Effect.provideService(Random.Random, makeDeterministicRandomService()),
401401 Effect.provide(harness.layer),
@@ -649,7 +649,7 @@ describe("ClaudeAdapterLive", () => { · 247 unmodified lines
649649 });
650650
651651 it.effect("embeds image attachments in Claude user messages", () => {
652− const baseDir = mkdtempSync(path.join(os.tmpdir(), "claude-attachments-"));
652+ const baseDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "claude-attachments-"));
653653 const harness = makeHarness({
654654 cwd: "/tmp/project-claude-attachments",
655655 baseDir,
@@ -657,7 +657,7 @@ describe("ClaudeAdapterLive", () => { · 1 unmodified line
657657 return Effect.gen(function* () {
658658 yield* Effect.addFinalizer(() =>
659659 Effect.sync(() =>
660− rmSync(baseDir, {
660+ NodeFS.rmSync(baseDir, {
661661 recursive: true,
662662 force: true,
663663 }),
@@ -674,9 +674,9 @@ describe("ClaudeAdapterLive", () => { · 10 unmodified lines
674674 mimeType: "image/png",
675675 sizeBytes: 4,
676676 };
677− const attachmentPath = path.join(attachmentsDir, attachmentRelativePath(attachment));
678− mkdirSync(path.dirname(attachmentPath), { recursive: true });
679− writeFileSync(attachmentPath, Uint8Array.from([1, 2, 3, 4]));
677+ const attachmentPath = NodePath.join(attachmentsDir, attachmentRelativePath(attachment));
678+ NodeFS.mkdirSync(NodePath.dirname(attachmentPath), { recursive: true });
679+ NodeFS.writeFileSync(attachmentPath, Uint8Array.from([1, 2, 3, 4]));
680680
681681 const session = yield* adapter.startSession({
682682 threadId: THREAD_ID,
apps/server/src/provider/Layers/CodexAdapter.test.ts+98−96
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import assert from "node:assert/strict";
3−import fs from "node:fs";
4−import os from "node:os";
5−import path from "node:path";
2+import * as NodeAssert from "node:assert/strict";
3+import * as NodeFS from "node:fs";
4+import * as NodeOS from "node:os";
5+import * as NodePath from "node:path";
66 import {
77 ApprovalRequestId,
88 CodexSettings,
@@ -250,8 +250,8 @@ validationLayer("CodexAdapterLive validation", (it) => { · 241 unmodified lines
250250 })
251251 .pipe(Effect.result);
252252
253− assert.equal(result._tag, "Failure");
254− assert.deepStrictEqual(
253+ NodeAssert.equal(result._tag, "Failure");
254+ NodeAssert.deepStrictEqual(
255255 result.failure,
256256 new ProviderAdapterValidationError({
257257 provider: ProviderDriverKind.make("codex"),
@@ -259,7 +259,7 @@ validationLayer("CodexAdapterLive validation", (it) => { · 1 unmodified line
259259 issue: "Expected provider 'codex' but received 'claudeAgent'.",
260260 }),
261261 );
262− assert.equal(validationRuntimeFactory.factory.mock.calls.length, 0);
262+ NodeAssert.equal(validationRuntimeFactory.factory.mock.calls.length, 0);
263263 }),
264264 );
265265 it.effect("maps codex model options before starting a session", () =>
@@ -276,7 +276,7 @@ validationLayer("CodexAdapterLive validation", (it) => { · 10 unmodified lines
276276 runtimeMode: "full-access",
277277 });
278278
279− assert.deepStrictEqual(validationRuntimeFactory.factory.mock.calls[0]?.[0], {
279+ NodeAssert.deepStrictEqual(validationRuntimeFactory.factory.mock.calls[0]?.[0], {
280280 binaryPath: "codex",
281281 cwd: process.cwd(),
282282 model: "gpt-5.3-codex",
@@ -319,10 +319,10 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 36 unmodified lines
319319 })
320320 .pipe(Effect.result);
321321
322− assert.equal(result._tag, "Failure");
323− assert.equal(result.failure._tag, "ProviderAdapterSessionNotFoundError");
324− assert.equal(result.failure.provider, "codex");
325− assert.equal(result.failure.threadId, "sess-missing");
322+ NodeAssert.equal(result._tag, "Failure");
323+ NodeAssert.equal(result.failure._tag, "ProviderAdapterSessionNotFoundError");
324+ NodeAssert.equal(result.failure.provider, "codex");
325+ NodeAssert.equal(result.failure.threadId, "sess-missing");
326326 }),
327327 );
328328
@@ -335,7 +335,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 6 unmodified lines
335335 runtimeMode: "full-access",
336336 });
337337 const runtime = sessionRuntimeFactory.lastRuntime;
338− assert.ok(runtime);
338+ NodeAssert.ok(runtime);
339339 runtime.sendTurnImpl.mockClear();
340340
341341 yield* Effect.ignore(
@@ -350,7 +350,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 8 unmodified lines
350350 }),
351351 );
352352
353− assert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], {
353+ NodeAssert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], {
354354 input: "hello",
355355 model: "gpt-5.3-codex",
356356 effort: "high",
@@ -386,7 +386,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 29 unmodified lines
386386 runtimeMode: "full-access",
387387 });
388388 const runtime = customRuntimeFactory.lastRuntime;
389− assert.ok(runtime);
389+ NodeAssert.ok(runtime);
390390 runtime.sendTurnImpl.mockClear();
391391
392392 yield* Effect.ignore(
@@ -405,7 +405,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 12 unmodified lines
405405 }),
406406 );
407407
408− assert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], {
408+ NodeAssert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], {
409409 input: "hello",
410410 model: "gpt-5.3-codex",
411411 effort: "high",
@@ -442,7 +442,7 @@ function startLifecycleRuntime() { · 30 unmodified lines
442442 runtimeMode: "full-access",
443443 });
444444 const runtime = lifecycleRuntimeFactory.lastRuntime;
445− assert.ok(runtime);
445+ NodeAssert.ok(runtime);
446446 return { adapter, runtime };
447447 });
448448 }
@@ -477,17 +477,17 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 28 unmodified lines
477477 yield* runtime.emit(event);
478478 const firstEvent = yield* Fiber.join(firstEventFiber);
479479
480− assert.equal(firstEvent._tag, "Some");
480+ NodeAssert.equal(firstEvent._tag, "Some");
481481 if (firstEvent._tag !== "Some") {
482482 return;
483483 }
484− assert.equal(firstEvent.value.type, "item.completed");
484+ NodeAssert.equal(firstEvent.value.type, "item.completed");
485485 if (firstEvent.value.type !== "item.completed") {
486486 return;
487487 }
488− assert.equal(firstEvent.value.itemId, "msg_1");
489− assert.equal(firstEvent.value.turnId, "turn-1");
490− assert.equal(firstEvent.value.payload.itemType, "assistant_message");
488+ NodeAssert.equal(firstEvent.value.itemId, "msg_1");
489+ NodeAssert.equal(firstEvent.value.turnId, "turn-1");
490+ NodeAssert.equal(firstEvent.value.payload.itemType, "assistant_message");
491491 }),
492492 );
493493
@@ -524,13 +524,13 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 30 unmodified lines
524524 });
525525 const firstEvent = yield* Fiber.join(firstEventFiber);
526526
527− assert.equal(firstEvent._tag, "Some");
527+ NodeAssert.equal(firstEvent._tag, "Some");
528528 if (firstEvent._tag !== "Some" || firstEvent.value.type !== "item.completed") {
529529 return;
530530 }
531− assert.equal(firstEvent.value.payload.itemType, "mcp_tool_call");
532− assert.equal(firstEvent.value.payload.title, "t3-code · preview_status");
533− assert.deepStrictEqual(firstEvent.value.payload.data, {
531+ NodeAssert.equal(firstEvent.value.payload.itemType, "mcp_tool_call");
532+ NodeAssert.equal(firstEvent.value.payload.title, "t3-code · preview_status");
533+ NodeAssert.deepStrictEqual(firstEvent.value.payload.data, {
534534 completedAtMs: 1_778_000_000_000,
535535 threadId: "thread-1",
536536 turnId: "turn-1",
@@ -578,16 +578,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 41 unmodified lines
578578 yield* runtime.emit(event);
579579 const firstEvent = yield* Fiber.join(firstEventFiber);
580580
581− assert.equal(firstEvent._tag, "Some");
581+ NodeAssert.equal(firstEvent._tag, "Some");
582582 if (firstEvent._tag !== "Some") {
583583 return;
584584 }
585− assert.equal(firstEvent.value.type, "turn.proposed.completed");
585+ NodeAssert.equal(firstEvent.value.type, "turn.proposed.completed");
586586 if (firstEvent.value.type !== "turn.proposed.completed") {
587587 return;
588588 }
589− assert.equal(firstEvent.value.turnId, "turn-1");
590− assert.equal(firstEvent.value.payload.planMarkdown, "## Final plan\n\n- one\n- two");
589+ NodeAssert.equal(firstEvent.value.turnId, "turn-1");
590+ NodeAssert.equal(firstEvent.value.payload.planMarkdown, "## Final plan\n\n- one\n- two");
591591 }),
592592 );
593593
@@ -615,16 +615,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 21 unmodified lines
615615
616616 const firstEvent = yield* Fiber.join(firstEventFiber);
617617
618− assert.equal(firstEvent._tag, "Some");
618+ NodeAssert.equal(firstEvent._tag, "Some");
619619 if (firstEvent._tag !== "Some") {
620620 return;
621621 }
622− assert.equal(firstEvent.value.type, "turn.proposed.delta");
622+ NodeAssert.equal(firstEvent.value.type, "turn.proposed.delta");
623623 if (firstEvent.value.type !== "turn.proposed.delta") {
624624 return;
625625 }
626− assert.equal(firstEvent.value.turnId, "turn-1");
627− assert.equal(firstEvent.value.payload.delta, "## Final plan");
626+ NodeAssert.equal(firstEvent.value.turnId, "turn-1");
627+ NodeAssert.equal(firstEvent.value.payload.delta, "## Final plan");
628628 }),
629629 );
630630
@@ -646,16 +646,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 15 unmodified lines
646646 yield* runtime.emit(event);
647647 const firstEvent = yield* Fiber.join(firstEventFiber);
648648
649− assert.equal(firstEvent._tag, "Some");
649+ NodeAssert.equal(firstEvent._tag, "Some");
650650 if (firstEvent._tag !== "Some") {
651651 return;
652652 }
653− assert.equal(firstEvent.value.type, "session.exited");
653+ NodeAssert.equal(firstEvent.value.type, "session.exited");
654654 if (firstEvent.value.type !== "session.exited") {
655655 return;
656656 }
657− assert.equal(firstEvent.value.threadId, "thread-1");
658− assert.equal(firstEvent.value.payload.reason, "Session stopped");
657+ NodeAssert.equal(firstEvent.value.threadId, "thread-1");
658+ NodeAssert.equal(firstEvent.value.payload.reason, "Session stopped");
659659 }),
660660 );
661661
@@ -684,16 +684,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 22 unmodified lines
684684
685685 const firstEvent = yield* Fiber.join(firstEventFiber);
686686
687− assert.equal(firstEvent._tag, "Some");
687+ NodeAssert.equal(firstEvent._tag, "Some");
688688 if (firstEvent._tag !== "Some") {
689689 return;
690690 }
691− assert.equal(firstEvent.value.type, "runtime.warning");
691+ NodeAssert.equal(firstEvent.value.type, "runtime.warning");
692692 if (firstEvent.value.type !== "runtime.warning") {
693693 return;
694694 }
695− assert.equal(firstEvent.value.turnId, "turn-1");
696− assert.equal(firstEvent.value.payload.message, "Reconnecting... 2/5");
695+ NodeAssert.equal(firstEvent.value.turnId, "turn-1");
696+ NodeAssert.equal(firstEvent.value.payload.message, "Reconnecting... 2/5");
697697 }),
698698 );
699699
@@ -715,16 +715,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 15 unmodified lines
715715
716716 const firstEvent = yield* Fiber.join(firstEventFiber);
717717
718− assert.equal(firstEvent._tag, "Some");
718+ NodeAssert.equal(firstEvent._tag, "Some");
719719 if (firstEvent._tag !== "Some") {
720720 return;
721721 }
722− assert.equal(firstEvent.value.type, "runtime.warning");
722+ NodeAssert.equal(firstEvent.value.type, "runtime.warning");
723723 if (firstEvent.value.type !== "runtime.warning") {
724724 return;
725725 }
726− assert.equal(firstEvent.value.turnId, "turn-1");
727− assert.equal(
726+ NodeAssert.equal(firstEvent.value.turnId, "turn-1");
727+ NodeAssert.equal(
728728 firstEvent.value.payload.message,
729729 "The filename or extension is too long. (os error 206)",
730730 );
@@ -752,16 +752,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 21 unmodified lines
752752
753753 const firstEvent = yield* Fiber.join(firstEventFiber);
754754
755− assert.equal(firstEvent._tag, "Some");
755+ NodeAssert.equal(firstEvent._tag, "Some");
756756 if (firstEvent._tag !== "Some") {
757757 return;
758758 }
759− assert.equal(firstEvent.value.type, "thread.realtime.started");
759+ NodeAssert.equal(firstEvent.value.type, "thread.realtime.started");
760760 if (firstEvent.value.type !== "thread.realtime.started") {
761761 return;
762762 }
763− assert.equal(firstEvent.value.threadId, "thread-1");
764− assert.equal(firstEvent.value.payload.realtimeSessionId, "realtime-session-1");
763+ NodeAssert.equal(firstEvent.value.threadId, "thread-1");
764+ NodeAssert.equal(firstEvent.value.payload.realtimeSessionId, "realtime-session-1");
765765 }),
766766 );
767767
@@ -784,17 +784,17 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 16 unmodified lines
784784
785785 const firstEvent = yield* Fiber.join(firstEventFiber);
786786
787− assert.equal(firstEvent._tag, "Some");
787+ NodeAssert.equal(firstEvent._tag, "Some");
788788 if (firstEvent._tag !== "Some") {
789789 return;
790790 }
791− assert.equal(firstEvent.value.type, "runtime.error");
791+ NodeAssert.equal(firstEvent.value.type, "runtime.error");
792792 if (firstEvent.value.type !== "runtime.error") {
793793 return;
794794 }
795− assert.equal(firstEvent.value.turnId, "turn-1");
796− assert.equal(firstEvent.value.payload.class, "provider_error");
797− assert.equal(
795+ NodeAssert.equal(firstEvent.value.turnId, "turn-1");
796+ NodeAssert.equal(firstEvent.value.payload.class, "provider_error");
797+ NodeAssert.equal(
798798 firstEvent.value.payload.message,
799799 "2026-03-31T18:14:06.833399Z ERROR codex_api::endpoint::responses_websocket: failed to connect to websocket: HTTP error: 503 Service Unavailable, url: wss://chatgpt.com/backend-api/codex/responses",
800800 );
@@ -824,15 +824,15 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 23 unmodified lines
824824 yield* runtime.emit(event);
825825 const firstEvent = yield* Fiber.join(firstEventFiber);
826826
827− assert.equal(firstEvent._tag, "Some");
827+ NodeAssert.equal(firstEvent._tag, "Some");
828828 if (firstEvent._tag !== "Some") {
829829 return;
830830 }
831− assert.equal(firstEvent.value.type, "request.resolved");
831+ NodeAssert.equal(firstEvent.value.type, "request.resolved");
832832 if (firstEvent.value.type !== "request.resolved") {
833833 return;
834834 }
835− assert.equal(firstEvent.value.payload.requestType, "command_execution_approval");
835+ NodeAssert.equal(firstEvent.value.payload.requestType, "command_execution_approval");
836836 }),
837837 );
838838
@@ -859,15 +859,15 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 20 unmodified lines
859859 yield* runtime.emit(event);
860860 const firstEvent = yield* Fiber.join(firstEventFiber);
861861
862− assert.equal(firstEvent._tag, "Some");
862+ NodeAssert.equal(firstEvent._tag, "Some");
863863 if (firstEvent._tag !== "Some") {
864864 return;
865865 }
866− assert.equal(firstEvent.value.type, "request.resolved");
866+ NodeAssert.equal(firstEvent.value.type, "request.resolved");
867867 if (firstEvent.value.type !== "request.resolved") {
868868 return;
869869 }
870− assert.equal(firstEvent.value.payload.requestType, "file_read_approval");
870+ NodeAssert.equal(firstEvent.value.payload.requestType, "file_read_approval");
871871 }),
872872 );
873873
@@ -895,15 +895,15 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 21 unmodified lines
895895 yield* runtime.emit(event);
896896 const firstEvent = yield* Fiber.join(firstEventFiber);
897897
898− assert.equal(firstEvent._tag, "Some");
898+ NodeAssert.equal(firstEvent._tag, "Some");
899899 if (firstEvent._tag !== "Some") {
900900 return;
901901 }
902− assert.equal(firstEvent.value.type, "user-input.resolved");
902+ NodeAssert.equal(firstEvent.value.type, "user-input.resolved");
903903 if (firstEvent.value.type !== "user-input.resolved") {
904904 return;
905905 }
906− assert.deepEqual(firstEvent.value.payload.answers, {
906+ NodeAssert.deepEqual(firstEvent.value.payload.answers, {
907907 scope: [],
908908 });
909909 }),
@@ -934,20 +934,20 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 24 unmodified lines
934934 yield* runtime.emit(event);
935935 const events = Array.from(yield* Fiber.join(eventsFiber));
936936
937− assert.equal(events.length, 2);
937+ NodeAssert.equal(events.length, 2);
938938
939939 const firstEvent = events[0];
940940 const secondEvent = events[1];
941941
942− assert.equal(firstEvent?.type, "session.state.changed");
942+ NodeAssert.equal(firstEvent?.type, "session.state.changed");
943943 if (firstEvent?.type === "session.state.changed") {
944− assert.equal(firstEvent.payload.state, "error");
945− assert.equal(firstEvent.payload.reason, "Sandbox setup failed");
944+ NodeAssert.equal(firstEvent.payload.state, "error");
945+ NodeAssert.equal(firstEvent.payload.reason, "Sandbox setup failed");
946946 }
947947
948− assert.equal(secondEvent?.type, "runtime.warning");
948+ NodeAssert.equal(secondEvent?.type, "runtime.warning");
949949 if (secondEvent?.type === "runtime.warning") {
950− assert.equal(secondEvent.payload.message, "Sandbox setup failed");
950+ NodeAssert.equal(secondEvent.payload.message, "Sandbox setup failed");
951951 }
952952 }),
953953 );
@@ -1006,17 +1006,17 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 52 unmodified lines
10061006 } satisfies ProviderEvent);
10071007
10081008 const events = Array.from(yield* Fiber.join(eventsFiber));
1009− assert.equal(events[0]?.type, "user-input.requested");
1009+ NodeAssert.equal(events[0]?.type, "user-input.requested");
10101010 if (events[0]?.type === "user-input.requested") {
1011− assert.equal(events[0].requestId, "req-user-input-1");
1012− assert.equal(events[0].payload.questions[0]?.id, "sandbox_mode");
1013− assert.equal(events[0].payload.questions[0]?.multiSelect, false);
1011+ NodeAssert.equal(events[0].requestId, "req-user-input-1");
1012+ NodeAssert.equal(events[0].payload.questions[0]?.id, "sandbox_mode");
1013+ NodeAssert.equal(events[0].payload.questions[0]?.multiSelect, false);
10141014 }
10151015
1016− assert.equal(events[1]?.type, "user-input.resolved");
1016+ NodeAssert.equal(events[1]?.type, "user-input.resolved");
10171017 if (events[1]?.type === "user-input.resolved") {
1018− assert.equal(events[1].requestId, "req-user-input-1");
1019− assert.deepEqual(events[1].payload.answers, {
1018+ NodeAssert.equal(events[1].requestId, "req-user-input-1");
1019+ NodeAssert.deepEqual(events[1].payload.answers, {
10201020 sandbox_mode: "workspace-write",
10211021 });
10221022 }
@@ -1060,16 +1060,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 37 unmodified lines
10601060 } satisfies ProviderEvent);
10611061
10621062 const firstEvent = yield* Fiber.join(firstEventFiber);
1063− assert.equal(firstEvent._tag, "Some");
1063+ NodeAssert.equal(firstEvent._tag, "Some");
10641064 if (firstEvent._tag !== "Some") {
10651065 return;
10661066 }
1067− assert.equal(firstEvent.value.type, "thread.token-usage.updated");
1067+ NodeAssert.equal(firstEvent.value.type, "thread.token-usage.updated");
10681068 if (firstEvent.value.type !== "thread.token-usage.updated") {
10691069 return;
10701070 }
10711071
1072− assert.deepEqual(firstEvent.value.payload.usage, {
1072+ NodeAssert.deepEqual(firstEvent.value.payload.usage, {
10731073 usedTokens: 126,
10741074 totalProcessedTokens: 11_839,
10751075 maxTokens: 258_400,
@@ -1119,15 +1119,15 @@ scopedLifecycleLayer("CodexAdapterLive scoped lifecycle", (it) => { · 43 unmodified lines
11191119 });
11201120
11211121 const runtime = scopedLifecycleRuntimeFactory.lastRuntime;
1122− assert.ok(runtime);
1122+ NodeAssert.ok(runtime);
11231123
11241124 yield* adapter.stopSession(asThreadId("thread-stop"));
11251125
1126− assert.equal(runtime.closeImpl.mock.calls.length, 1);
1127− assert.deepStrictEqual(scopedLifecycleRuntimeFactory.releasedThreadIds, [
1126+ NodeAssert.equal(runtime.closeImpl.mock.calls.length, 1);
1127+ NodeAssert.deepStrictEqual(scopedLifecycleRuntimeFactory.releasedThreadIds, [
11281128 asThreadId("thread-stop"),
11291129 ]);
1130− assert.equal(yield* adapter.hasSession(asThreadId("thread-stop")), false);
1130+ NodeAssert.equal(yield* adapter.hasSession(asThreadId("thread-stop")), false);
11311131 }),
11321132 );
11331133 });
@@ -1164,20 +1164,22 @@ scopedFailureLayer("CodexAdapterLive scoped startup failure", (it) => { · 30 unmodified lines
11641164 })
11651165 .pipe(Effect.result);
11661166
1167− assert.equal(result._tag, "Failure");
1168− assert.equal(result.failure._tag, "ProviderAdapterProcessError");
1169− assert.deepStrictEqual(scopedFailureRuntimeFactory.releasedThreadIds, [
1167+ NodeAssert.equal(result._tag, "Failure");
1168+ NodeAssert.equal(result.failure._tag, "ProviderAdapterProcessError");
1169+ NodeAssert.deepStrictEqual(scopedFailureRuntimeFactory.releasedThreadIds, [
11701170 asThreadId("thread-fail"),
11711171 ]);
1172− assert.equal(yield* adapter.hasSession(asThreadId("thread-fail")), false);
1172+ NodeAssert.equal(yield* adapter.hasSession(asThreadId("thread-fail")), false);
11731173 }),
11741174 );
11751175 });
11761176
11771177 it.effect("flushes managed native logs when the adapter layer shuts down", () =>
11781178 Effect.gen(function* () {
1179− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-codex-adapter-native-log-"));
1180− const basePath = path.join(tempDir, "provider-native.ndjson");
1179+ const tempDir = NodeFS.mkdtempSync(
1180+ NodePath.join(NodeOS.tmpdir(), "t3-codex-adapter-native-log-"),
1181+ );
1182+ const basePath = NodePath.join(tempDir, "provider-native.ndjson");
11811183 const runtimeFactory = makeRuntimeFactory();
11821184 const scope = yield* Scope.make("sequential");
11831185 let scopeClosed = false;
@@ -1208,7 +1210,7 @@ it.effect("flushes managed native logs when the adapter layer shuts down", () => · 24 unmodified lines
12081210 });
12091211
12101212 const runtime = runtimeFactory.lastRuntime;
1211− assert.ok(runtime);
1213+ NodeAssert.ok(runtime);
12121214
12131215 const firstEventFiber = yield* Stream.runHead(adapter.streamEvents).pipe(Effect.forkChild);
12141216 yield* runtime.emit({
@@ -1225,15 +1227,15 @@ it.effect("flushes managed native logs when the adapter layer shuts down", () => · 10 unmodified lines
12251227 yield* Scope.close(scope, Exit.void);
12261228 scopeClosed = true;
12271229
1228− const threadLogPath = path.join(tempDir, "thread-logger.log");
1229− assert.equal(fs.existsSync(threadLogPath), true);
1230− const contents = fs.readFileSync(threadLogPath, "utf8");
1231− assert.match(contents, /NTIVE: .*"message":"native flush test"/);
1230+ const threadLogPath = NodePath.join(tempDir, "thread-logger.log");
1231+ NodeAssert.equal(NodeFS.existsSync(threadLogPath), true);
1232+ const contents = NodeFS.readFileSync(threadLogPath, "utf8");
1233+ NodeAssert.match(contents, /NTIVE: .*"message":"native flush test"/);
12321234 } finally {
12331235 if (!scopeClosed) {
12341236 yield* Scope.close(scope, Exit.void);
12351237 }
1236− fs.rmSync(tempDir, { recursive: true, force: true });
1238+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
12371239 }
12381240 }),
12391241 );
apps/server/src/provider/Layers/CodexSessionRuntime.test.ts+18−18
@@ -1,4 +1,4 @@
1−import assert from "node:assert/strict";
1+import * as NodeAssert from "node:assert/strict";
22
33 import * as Effect from "effect/Effect";
44 import * as Schema from "effect/Schema";
@@ -55,7 +55,7 @@ describe("buildTurnStartParams", () => { · 50 unmodified lines
5555 }),
5656 );
5757
58− assert.deepStrictEqual(params, {
58+ NodeAssert.deepStrictEqual(params, {
5959 threadId: "provider-thread-1",
6060 approvalPolicy: "never",
6161 sandboxPolicy: {
@@ -97,7 +97,7 @@ describe("buildTurnStartParams", () => { · 35 unmodified lines
9797 }),
9898 );
9999
100− assert.deepStrictEqual(params, {
100+ NodeAssert.deepStrictEqual(params, {
101101 threadId: "provider-thread-1",
102102 approvalPolicy: "on-request",
103103 sandboxPolicy: {
@@ -134,7 +134,7 @@ describe("buildTurnStartParams", () => { · 30 unmodified lines
134134 }),
135135 );
136136
137− assert.deepStrictEqual(params, {
137+ NodeAssert.deepStrictEqual(params, {
138138 threadId: "provider-thread-1",
139139 approvalPolicy: "untrusted",
140140 sandboxPolicy: {
@@ -156,19 +156,19 @@ describe("T3 browser developer instructions", () => { · 15 unmodified lines
156156 CODEX_DEFAULT_MODE_DEVELOPER_INSTRUCTIONS,
157157 CODEX_PLAN_MODE_DEVELOPER_INSTRUCTIONS,
158158 ]) {
159− assert.match(instructions, /t3-code/);
160− assert.match(instructions, /preview_status/);
161− assert.match(instructions, /preview_open/);
162− assert.match(instructions, /Do not switch to global browser skills/);
159+ NodeAssert.match(instructions, /t3-code/);
160+ NodeAssert.match(instructions, /preview_status/);
161+ NodeAssert.match(instructions, /preview_open/);
162+ NodeAssert.match(instructions, /Do not switch to global browser skills/);
163163 }
164164 });
165165 });
166166
167167 describe("hasConfiguredMcpServer", () => {
168168 it("detects inline Codex MCP configuration arguments", () => {
169− assert.equal(hasConfiguredMcpServer(undefined), false);
170− assert.equal(hasConfiguredMcpServer(["--model", "gpt-5.4"]), false);
171− assert.equal(
169+ NodeAssert.equal(hasConfiguredMcpServer(undefined), false);
170+ NodeAssert.equal(hasConfiguredMcpServer(["--model", "gpt-5.4"]), false);
171+ NodeAssert.equal(
172172 hasConfiguredMcpServer(["-c", 'mcp_servers.t3-code.url="http://127.0.0.1/mcp"']),
173173 true,
174174 );
@@ -177,7 +177,7 @@ describe("hasConfiguredMcpServer", () => { · 2 unmodified lines
177177
178178 describe("isRecoverableThreadResumeError", () => {
179179 it("matches missing thread errors", () => {
180− assert.equal(
180+ NodeAssert.equal(
181181 isRecoverableThreadResumeError(
182182 new CodexErrors.CodexAppServerRequestError({
183183 code: -32603,
@@ -189,7 +189,7 @@ describe("isRecoverableThreadResumeError", () => { · 5 unmodified lines
189189 });
190190
191191 it("ignores non-recoverable resume errors", () => {
192− assert.equal(
192+ NodeAssert.equal(
193193 isRecoverableThreadResumeError(
194194 new CodexErrors.CodexAppServerRequestError({
195195 code: -32603,
@@ -201,7 +201,7 @@ describe("isRecoverableThreadResumeError", () => { · 5 unmodified lines
201201 });
202202
203203 it("ignores unrelated missing-resource errors that do not mention threads", () => {
204− assert.equal(
204+ NodeAssert.equal(
205205 isRecoverableThreadResumeError(
206206 new CodexErrors.CodexAppServerRequestError({
207207 code: -32603,
@@ -210,7 +210,7 @@ describe("isRecoverableThreadResumeError", () => { · 2 unmodified lines
210210 ),
211211 false,
212212 );
213− assert.equal(
213+ NodeAssert.equal(
214214 isRecoverableThreadResumeError(
215215 new CodexErrors.CodexAppServerRequestError({
216216 code: -32603,
@@ -256,8 +256,8 @@ describe("openCodexThread", () => { · 39 unmodified lines
256256 }),
257257 );
258258
259− assert.equal(opened.thread.id, "fresh-thread");
260− assert.deepStrictEqual(
259+ NodeAssert.equal(opened.thread.id, "fresh-thread");
260+ NodeAssert.deepStrictEqual(
261261 calls.map((call) => call.method),
262262 ["thread/resume", "thread/start"],
263263 );
@@ -283,7 +283,7 @@ describe("openCodexThread", () => { · 19 unmodified lines
283283 },
284284 };
285285
286− await assert.rejects(
286+ await NodeAssert.rejects(
287287 Effect.runPromise(
288288 openCodexThread({
289289 client,
apps/server/src/provider/Layers/CursorAdapter.test.ts+63−49
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as path from "node:path";
3−import * as os from "node:os";
4−import { chmod, mkdtemp, readFile, writeFile } from "node:fs/promises";
5−import { fileURLToPath } from "node:url";
2+import * as NodePath from "node:path";
3+import * as NodeOS from "node:os";
4+import * as NodeFSP from "node:fs/promises";
5+import * as NodeURL from "node:url";
66
77 import * as NodeServices from "@effect/platform-node/NodeServices";
88 import { assert, it } from "@effect/vitest";
@@ -36,8 +36,8 @@ class CursorAdapter extends Context.Service<CursorAdapter, CursorAdapterShape>() · 27 unmodified lines
3636 "t3/provider/Layers/CursorAdapter.test/CursorAdapter",
3737 ) {}
3838
39−const __dirname = path.dirname(fileURLToPath(import.meta.url));
40−const mockAgentPath = path.join(__dirname, "../../../scripts/acp-mock-agent.ts");
39+const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url));
40+const mockAgentPath = NodePath.join(__dirname, "../../../scripts/acp-mock-agent.ts");
4141 const mockAgentCommand = "node";
4242 const mockAgentArgs = [mockAgentPath] as const;
4343
@@ -45,8 +45,8 @@ async function makeMockAgentWrapper( · 1 unmodified line
4545 extraEnv?: Record<string, string>,
4646 options?: { initialDelaySeconds?: number },
4747 ) {
48− const dir = await mkdtemp(path.join(os.tmpdir(), "cursor-acp-mock-"));
49− const wrapperPath = path.join(dir, "fake-agent.sh");
48+ const dir = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-mock-"));
49+ const wrapperPath = NodePath.join(dir, "fake-agent.sh");
5050 const envExports = Object.entries(extraEnv ?? {})
5151 .map(([key, value]) => `export ${key}=${JSON.stringify(value)}`)
5252 .join("\n");
@@ -55,8 +55,8 @@ ${envExports} · 2 unmodified lines
5555 ${options?.initialDelaySeconds ? `sleep ${JSON.stringify(String(options.initialDelaySeconds))}` : ""}
5656 exec ${JSON.stringify(mockAgentCommand)} ${mockAgentArgs.map((arg) => JSON.stringify(arg)).join(" ")} "$@"
5757 `;
58− await writeFile(wrapperPath, script, "utf8");
59− await chmod(wrapperPath, 0o755);
58+ await NodeFSP.writeFile(wrapperPath, script, "utf8");
59+ await NodeFSP.chmod(wrapperPath, 0o755);
6060 return wrapperPath;
6161 }
6262
@@ -65,8 +65,8 @@ async function makeProbeWrapper( · 2 unmodified lines
6565 argvLogPath: string,
6666 extraEnv?: Record<string, string>,
6767 ) {
68− const dir = await mkdtemp(path.join(os.tmpdir(), "cursor-acp-probe-"));
69− const wrapperPath = path.join(dir, "fake-agent.sh");
68+ const dir = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-probe-"));
69+ const wrapperPath = NodePath.join(dir, "fake-agent.sh");
7070 const envExports = Object.entries(extraEnv ?? {})
7171 .map(([key, value]) => `export ${key}=${JSON.stringify(value)}`)
7272 .join("\n");
@@ -77,13 +77,13 @@ export T3_ACP_REQUEST_LOG_PATH=${JSON.stringify(requestLogPath)} · 4 unmodified lines
7777 ${envExports}
7878 exec ${JSON.stringify(mockAgentCommand)} ${mockAgentArgs.map((arg) => JSON.stringify(arg)).join(" ")} "$@"
7979 `;
80− await writeFile(wrapperPath, script, "utf8");
81− await chmod(wrapperPath, 0o755);
80+ await NodeFSP.writeFile(wrapperPath, script, "utf8");
81+ await NodeFSP.chmod(wrapperPath, 0o755);
8282 return wrapperPath;
8383 }
8484
8585 async function readArgvLog(filePath: string) {
86− const raw = await readFile(filePath, "utf8");
86+ const raw = await NodeFSP.readFile(filePath, "utf8");
8787 return raw
8888 .split("\n")
8989 .map((line) => line.trim())
@@ -92,7 +92,7 @@ async function readArgvLog(filePath: string) { · 2 unmodified lines
9292 }
9393
9494 async function readJsonLines(filePath: string) {
95− const raw = await readFile(filePath, "utf8");
95+ const raw = await NodeFSP.readFile(filePath, "utf8");
9696 return raw
9797 .split("\n")
9898 .map((line) => line.trim())
@@ -103,7 +103,7 @@ async function readJsonLines(filePath: string) { · 4 unmodified lines
103103 async function waitForFileContent(filePath: string, attempts = 40) {
104104 for (let attempt = 0; attempt < attempts; attempt += 1) {
105105 try {
106− const raw = await readFile(filePath, "utf8");
106+ const raw = await NodeFSP.readFile(filePath, "utf8");
107107 if (raw.trim().length > 0) {
108108 return raw;
109109 }
@@ -315,9 +315,9 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 205 unmodified lines
315315 const settings = yield* ServerSettingsService;
316316 const threadId = ThreadId.make("cursor-stop-session-close");
317317 const tempDir = yield* Effect.promise(() =>
318− mkdtemp(path.join(os.tmpdir(), "cursor-adapter-exit-log-")),
318+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-adapter-exit-log-")),
319319 );
320− const exitLogPath = path.join(tempDir, "exit.log");
320+ const exitLogPath = NodePath.join(tempDir, "exit.log");
321321
322322 const wrapperPath = yield* Effect.promise(() =>
323323 makeMockAgentWrapper({
@@ -349,9 +349,9 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 25 unmodified lines
349349 const settings = yield* ServerSettingsService;
350350 const threadId = ThreadId.make("cursor-concurrent-start-session");
351351 const tempDir = yield* Effect.promise(() =>
352− mkdtemp(path.join(os.tmpdir(), "cursor-adapter-concurrent-exit-log-")),
352+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-adapter-concurrent-exit-log-")),
353353 );
354− const exitLogPath = path.join(tempDir, "exit.log");
354+ const exitLogPath = NodePath.join(tempDir, "exit.log");
355355
356356 const wrapperPath = yield* Effect.promise(() =>
357357 makeMockAgentWrapper(
@@ -414,10 +414,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 56 unmodified lines
414414 const adapter = yield* CursorAdapter;
415415 const serverSettings = yield* ServerSettingsService;
416416 const threadId = ThreadId.make("cursor-plan-mode-probe");
417− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
418− const requestLogPath = path.join(tempDir, "requests.ndjson");
419− const argvLogPath = path.join(tempDir, "argv.txt");
420− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
417+ const tempDir = yield* Effect.promise(() =>
418+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
419+ );
420+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
421+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
422+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
421423 const wrapperPath = yield* Effect.promise(() =>
422424 makeProbeWrapper(requestLogPath, argvLogPath),
423425 );
@@ -470,10 +472,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 46 unmodified lines
470472 const adapter = yield* CursorAdapter;
471473 const serverSettings = yield* ServerSettingsService;
472474 const threadId = ThreadId.make("cursor-initial-config-probe");
473− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
474− const requestLogPath = path.join(tempDir, "requests.ndjson");
475− const argvLogPath = path.join(tempDir, "argv.txt");
476− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
475+ const tempDir = yield* Effect.promise(() =>
476+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
477+ );
478+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
479+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
480+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
477481 const wrapperPath = yield* Effect.promise(() =>
478482 makeProbeWrapper(requestLogPath, argvLogPath),
479483 );
@@ -713,10 +717,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 233 unmodified lines
713717 const runtimeEvents: Array<ProviderRuntimeEvent> = [];
714718 const settledEventTypes = new Set<string>();
715719 const settledEventsReady = yield* Deferred.make<void>();
716− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
717− const requestLogPath = path.join(tempDir, "requests.ndjson");
718− const argvLogPath = path.join(tempDir, "argv.txt");
719− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
720+ const tempDir = yield* Effect.promise(() =>
721+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
722+ );
723+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
724+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
725+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
720726 const wrapperPath = yield* Effect.promise(() =>
721727 makeProbeWrapper(requestLogPath, argvLogPath, { T3_ACP_EMIT_TOOL_CALLS: "1" }),
722728 );
@@ -931,10 +937,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 208 unmodified lines
931937 const adapter = yield* CursorAdapter;
932938 const serverSettings = yield* ServerSettingsService;
933939 const threadId = ThreadId.make("cursor-cancel-probe");
934− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
935− const requestLogPath = path.join(tempDir, "requests.ndjson");
936− const argvLogPath = path.join(tempDir, "argv.txt");
937− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
940+ const tempDir = yield* Effect.promise(() =>
941+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
942+ );
943+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
944+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
945+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
938946 const wrapperPath = yield* Effect.promise(() =>
939947 makeProbeWrapper(requestLogPath, argvLogPath, { T3_ACP_EMIT_TOOL_CALLS: "1" }),
940948 );
@@ -1192,10 +1200,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 251 unmodified lines
11921200 const adapter = yield* CursorAdapter;
11931201 const serverSettings = yield* ServerSettingsService;
11941202 const threadId = ThreadId.make("cursor-model-switch");
1195− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
1196− const requestLogPath = path.join(tempDir, "requests.ndjson");
1197− const argvLogPath = path.join(tempDir, "argv.txt");
1198− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
1203+ const tempDir = yield* Effect.promise(() =>
1204+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
1205+ );
1206+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
1207+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
1208+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
11991209 const wrapperPath = yield* Effect.promise(() =>
12001210 makeProbeWrapper(requestLogPath, argvLogPath),
12011211 );
@@ -1255,10 +1265,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 53 unmodified lines
12551265 const adapter = yield* CursorAdapter;
12561266 const serverSettings = yield* ServerSettingsService;
12571267 const threadId = ThreadId.make("cursor-fast-mode-reset");
1258− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
1259− const requestLogPath = path.join(tempDir, "requests.ndjson");
1260− const argvLogPath = path.join(tempDir, "argv.txt");
1261− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
1268+ const tempDir = yield* Effect.promise(() =>
1269+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
1270+ );
1271+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
1272+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
1273+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
12621274 const wrapperPath = yield* Effect.promise(() =>
12631275 makeProbeWrapper(requestLogPath, argvLogPath),
12641276 );
@@ -1339,10 +1351,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 74 unmodified lines
13391351 const adapter = yield* CursorAdapter;
13401352 const serverSettings = yield* ServerSettingsService;
13411353 const threadId = ThreadId.make("cursor-fast-mode-custom-instance");
1342− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "cursor-acp-")));
1343− const requestLogPath = path.join(tempDir, "requests.ndjson");
1344− const argvLogPath = path.join(tempDir, "argv.txt");
1345− yield* Effect.promise(() => writeFile(requestLogPath, "", "utf8"));
1354+ const tempDir = yield* Effect.promise(() =>
1355+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "cursor-acp-")),
1356+ );
1357+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
1358+ const argvLogPath = NodePath.join(tempDir, "argv.txt");
1359+ yield* Effect.promise(() => NodeFSP.writeFile(requestLogPath, "", "utf8"));
13461360 const wrapperPath = yield* Effect.promise(() =>
13471361 makeProbeWrapper(requestLogPath, argvLogPath),
13481362 );
apps/server/src/provider/Layers/CursorProvider.ts+2−2
@@ -1,4 +1,4 @@
1−import * as NodeOs from "node:os";
1+import * as NodeOS from "node:os";
22 import type {
33 CursorSettings,
44 ModelCapabilities,
@@ -746,7 +746,7 @@ function isCursorAboutJsonFormatUnsupported(result: CommandResult): boolean { · 741 unmodified lines
746746 const readCursorCliConfigChannel = Effect.fn("readCursorCliConfigChannel")(function* () {
747747 const fileSystem = yield* FileSystem.FileSystem;
748748 const path = yield* Path.Path;
749− const configPath = path.join(NodeOs.homedir(), ".cursor", "cli-config.json");
749+ const configPath = path.join(NodeOS.homedir(), ".cursor", "cli-config.json");
750750 const raw = yield* fileSystem.readFileString(configPath).pipe(Effect.orElseSucceed(() => ""));
751751 return parseCursorCliConfigChannel(raw);
752752 });
apps/server/src/provider/Layers/EventNdjsonLogger.test.ts+28−31
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import { ThreadId } from "@t3tools/contracts";
77 import { assert, describe, it } from "@effect/vitest";
@@ -31,8 +31,8 @@ function parseLogLine(line: string) { · 23 unmodified lines
3131 describe("EventNdjsonLogger", () => {
3232 it.effect("writes effect-style lines to thread-scoped files", () =>
3333 Effect.gen(function* () {
34− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-log-"));
35− const basePath = path.join(tempDir, "provider-native.ndjson");
34+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-provider-log-"));
35+ const basePath = NodePath.join(tempDir, "provider-native.ndjson");
3636
3737 try {
3838 const logger = yield* makeEventNdjsonLogger(basePath, { stream: "native" });
@@ -51,13 +51,13 @@ describe("EventNdjsonLogger", () => { · 12 unmodified lines
5151 );
5252 yield* logger.close();
5353
54− const threadOnePath = path.join(tempDir, "thread-1.log");
55− const threadTwoPath = path.join(tempDir, "thread-2.log");
56− assert.equal(fs.existsSync(threadOnePath), true);
57− assert.equal(fs.existsSync(threadTwoPath), true);
54+ const threadOnePath = NodePath.join(tempDir, "thread-1.log");
55+ const threadTwoPath = NodePath.join(tempDir, "thread-2.log");
56+ assert.equal(NodeFS.existsSync(threadOnePath), true);
57+ assert.equal(NodeFS.existsSync(threadTwoPath), true);
5858
59− const first = parseLogLine(fs.readFileSync(threadOnePath, "utf8").trim());
60− const second = parseLogLine(fs.readFileSync(threadTwoPath, "utf8").trim());
59+ const first = parseLogLine(NodeFS.readFileSync(threadOnePath, "utf8").trim());
60+ const second = parseLogLine(NodeFS.readFileSync(threadTwoPath, "utf8").trim());
6161
6262 assert.equal(Number.isNaN(Date.parse(first.observedAt)), false);
6363 assert.equal(first.stream, "NTIVE");
@@ -70,7 +70,7 @@ describe("EventNdjsonLogger", () => { · 6 unmodified lines
7070 '{"type":"turn.completed","threadId":"provider-thread-2","id":"evt-2"}',
7171 );
7272 } finally {
73− fs.rmSync(tempDir, { recursive: true, force: true });
73+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
7474 }
7575 }),
7676 );
@@ -79,8 +79,8 @@ describe("EventNdjsonLogger", () => { · 2 unmodified lines
7979 "falls back to a global segment when orchestration thread id is missing or invalid",
8080 () =>
8181 Effect.gen(function* () {
82− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-log-"));
83− const basePath = path.join(tempDir, "provider-canonical.ndjson");
82+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-provider-log-"));
83+ const basePath = NodePath.join(tempDir, "provider-canonical.ndjson");
8484
8585 try {
8686 const logger = yield* makeEventNdjsonLogger(basePath, { stream: "orchestration" });
@@ -93,10 +93,9 @@ describe("EventNdjsonLogger", () => { · 6 unmodified lines
9393 yield* logger.write({ id: "evt-invalid-thread" }, "!!!" as unknown as ThreadId);
9494 yield* logger.close();
9595
96− const globalPath = path.join(tempDir, "_global.log");
97− assert.equal(fs.existsSync(globalPath), true);
98− const lines = fs
99− .readFileSync(globalPath, "utf8")
96+ const globalPath = NodePath.join(tempDir, "_global.log");
97+ assert.equal(NodeFS.existsSync(globalPath), true);
98+ const lines = NodeFS.readFileSync(globalPath, "utf8")
10099 .trim()
101100 .split("\n")
102101 .map((line) => parseLogLine(line));
@@ -108,15 +107,15 @@ describe("EventNdjsonLogger", () => { · 5 unmodified lines
108107 assert.equal(lines[1]?.stream, "CANON");
109108 assert.equal(lines[1]?.payload, '{"id":"evt-invalid-thread"}');
110109 } finally {
111− fs.rmSync(tempDir, { recursive: true, force: true });
110+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
112111 }
113112 }),
114113 );
115114
116115 it.effect("serializes concurrent first writes for the same segment", () =>
117116 Effect.gen(function* () {
118− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-log-"));
119− const basePath = path.join(tempDir, "provider-canonical.ndjson");
117+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-provider-log-"));
118+ const basePath = NodePath.join(tempDir, "provider-canonical.ndjson");
120119
121120 try {
122121 const logger = yield* makeEventNdjsonLogger(basePath, {
@@ -137,10 +136,9 @@ describe("EventNdjsonLogger", () => { · 14 unmodified lines
137136 );
138137 yield* logger.close();
139138
140− const globalPath = path.join(tempDir, "_global.log");
141− assert.equal(fs.existsSync(globalPath), true);
142− const lines = fs
143− .readFileSync(globalPath, "utf8")
139+ const globalPath = NodePath.join(tempDir, "_global.log");
140+ assert.equal(NodeFS.existsSync(globalPath), true);
141+ const lines = NodeFS.readFileSync(globalPath, "utf8")
144142 .trim()
145143 .split("\n")
146144 .map((line) => parseLogLine(line));
@@ -151,15 +149,15 @@ describe("EventNdjsonLogger", () => { · 4 unmodified lines
151149 '{"id":"evt-concurrent-2"}',
152150 ]);
153151 } finally {
154− fs.rmSync(tempDir, { recursive: true, force: true });
152+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
155153 }
156154 }),
157155 );
158156
159157 it.effect("rotates per-thread files when max size is exceeded", () =>
160158 Effect.gen(function* () {
161− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-log-"));
162− const basePath = path.join(tempDir, "provider-native.ndjson");
159+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-provider-log-"));
160+ const basePath = NodePath.join(tempDir, "provider-native.ndjson");
163161
164162 try {
165163 const logger = yield* makeEventNdjsonLogger(basePath, {
@@ -185,8 +183,7 @@ describe("EventNdjsonLogger", () => { · 19 unmodified lines
185183 yield* logger.close();
186184
187185 const fileStem = "thread-rotate.log";
188− const matchingFiles = fs
189− .readdirSync(tempDir)
186+ const matchingFiles = NodeFS.readdirSync(tempDir)
190187 .filter((entry) => entry === fileStem || entry.startsWith(`${fileStem}.`))
191188 .toSorted();
192189
@@ -203,7 +200,7 @@ describe("EventNdjsonLogger", () => { · 10 unmodified lines
203200 false,
204201 );
205202 } finally {
206− fs.rmSync(tempDir, { recursive: true, force: true });
203+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
207204 }
208205 }),
209206 );
apps/server/src/provider/Layers/EventNdjsonLogger.ts+4−4
@@ -6,8 +6,8 @@ · 5 unmodified lines
66 * single effect-style text line in a thread-scoped file. Failures are
77 * downgraded to warnings so provider runtime behavior is unaffected.
88 */
9−import fs from "node:fs";
10−import path from "node:path";
9+import * as NodeFS from "node:fs";
10+import * as NodePath from "node:path";
1111
1212 import type { ThreadId } from "@t3tools/contracts";
1313 import { RotatingFileSink } from "@t3tools/shared/logging";
@@ -178,7 +178,7 @@ export const makeEventNdjsonLogger = Effect.fn("makeEventNdjsonLogger")(function · 164 unmodified lines
178178
179179 const directoryReady = yield* Effect.sync(() => {
180180 try {
181− fs.mkdirSync(path.dirname(filePath), { recursive: true });
181+ NodeFS.mkdirSync(NodePath.dirname(filePath), { recursive: true });
182182 return true;
183183 } catch (error) {
184184 return { ok: false as const, error };
@@ -211,7 +211,7 @@ export const makeEventNdjsonLogger = Effect.fn("makeEventNdjsonLogger")(function · 26 unmodified lines
211211 }
212212
213213 return makeThreadWriter({
214− filePath: path.join(path.dirname(filePath), `${threadSegment}.log`),
214+ filePath: NodePath.join(NodePath.dirname(filePath), `${threadSegment}.log`),
215215 maxBytes,
216216 maxFiles,
217217 batchWindowMs,
apps/server/src/provider/Layers/GrokAdapter.test.ts+18−16
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as path from "node:path";
3−import * as os from "node:os";
4−import { chmod, mkdtemp, readFile, writeFile } from "node:fs/promises";
5−import { fileURLToPath } from "node:url";
2+import * as NodePath from "node:path";
3+import * as NodeOS from "node:os";
4+import * as NodeFSP from "node:fs/promises";
5+import * as NodeURL from "node:url";
66
77 import * as NodeServices from "@effect/platform-node/NodeServices";
88 import { assert, it } from "@effect/vitest";
@@ -26,13 +26,13 @@ import { ServerConfig } from "../../config.ts"; · 17 unmodified lines
2626 import { makeGrokAdapter } from "./GrokAdapter.ts";
2727 const decodeGrokSettings = Schema.decodeSync(GrokSettings);
2828
29−const __dirname = path.dirname(fileURLToPath(import.meta.url));
30−const mockAgentPath = path.join(__dirname, "../../../scripts/acp-mock-agent.ts");
29+const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url));
30+const mockAgentPath = NodePath.join(__dirname, "../../../scripts/acp-mock-agent.ts");
3131 const mockAgentCommand = process.execPath;
3232
3333 async function makeMockGrokWrapper(extraEnv?: Record<string, string>) {
34− const dir = await mkdtemp(path.join(os.tmpdir(), "grok-acp-mock-"));
35− const wrapperPath = path.join(dir, "fake-grok.sh");
34+ const dir = await NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "grok-acp-mock-"));
35+ const wrapperPath = NodePath.join(dir, "fake-grok.sh");
3636 const envExports = Object.entries(extraEnv ?? {})
3737 .map(([key, value]) => `export ${key}=${JSON.stringify(value)}`)
3838 .join("\n");
@@ -40,8 +40,8 @@ async function makeMockGrokWrapper(extraEnv?: Record<string, string>) { · 1 unmodified line
4040 ${envExports}
4141 exec ${JSON.stringify(mockAgentCommand)} ${JSON.stringify(mockAgentPath)} "$@"
4242 `;
43− await writeFile(wrapperPath, script, "utf8");
44− await chmod(wrapperPath, 0o755);
43+ await NodeFSP.writeFile(wrapperPath, script, "utf8");
44+ await NodeFSP.chmod(wrapperPath, 0o755);
4545 return wrapperPath;
4646 }
4747
@@ -51,7 +51,7 @@ function waitForFileContent(filePath: string, attempts = 40): Effect.Effect<stri · 3 unmodified lines
5151 if (remainingAttempts <= 0) {
5252 return yield* Effect.die(new Error(`Timed out waiting for file content at ${filePath}`));
5353 }
54− const raw = yield* Effect.tryPromise(() => readFile(filePath, "utf8")).pipe(
54+ const raw = yield* Effect.tryPromise(() => NodeFSP.readFile(filePath, "utf8")).pipe(
5555 Effect.orElseSucceed(() => ""),
5656 );
5757 if (raw.trim().length > 0) {
@@ -64,7 +64,7 @@ function waitForFileContent(filePath: string, attempts = 40): Effect.Effect<stri · 6 unmodified lines
6464 }
6565
6666 async function readJsonLines(filePath: string) {
67− const raw = await readFile(filePath, "utf8");
67+ const raw = await NodeFSP.readFile(filePath, "utf8");
6868 return raw
6969 .split("\n")
7070 .map((line) => line.trim())
@@ -149,9 +149,9 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { · 78 unmodified lines
149149 Effect.gen(function* () {
150150 const threadId = ThreadId.make("grok-stop-session-close");
151151 const tempDir = yield* Effect.promise(() =>
152− mkdtemp(path.join(os.tmpdir(), "grok-adapter-exit-log-")),
152+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "grok-adapter-exit-log-")),
153153 );
154− const exitLogPath = path.join(tempDir, "exit.log");
154+ const exitLogPath = NodePath.join(tempDir, "exit.log");
155155
156156 const wrapperPath = yield* Effect.promise(() =>
157157 makeMockGrokWrapper({
@@ -227,8 +227,10 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { · 69 unmodified lines
227227 it.effect("responds to ACP approvals using provider-supplied option ids", () =>
228228 Effect.gen(function* () {
229229 const threadId = ThreadId.make("grok-custom-approval-option-id");
230− const tempDir = yield* Effect.promise(() => mkdtemp(path.join(os.tmpdir(), "grok-acp-")));
231− const requestLogPath = path.join(tempDir, "requests.ndjson");
230+ const tempDir = yield* Effect.promise(() =>
231+ NodeFSP.mkdtemp(NodePath.join(NodeOS.tmpdir(), "grok-acp-")),
232+ );
233+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
232234 const wrapperPath = yield* Effect.promise(() =>
233235 makeMockGrokWrapper({
234236 T3_ACP_REQUEST_LOG_PATH: requestLogPath,
apps/server/src/provider/Layers/OpenCodeAdapter.test.ts+48−48
@@ -1,4 +1,4 @@
1−import assert from "node:assert/strict";
1+import * as NodeAssert from "node:assert/strict";
22 import * as NodeServices from "@effect/platform-node/NodeServices";
33 import { it } from "@effect/vitest";
44 import * as Context from "effect/Context";
@@ -238,11 +238,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 233 unmodified lines
238238 runtimeMode: "full-access",
239239 });
240240
241− assert.equal(session.provider, "opencode");
242− assert.equal(session.threadId, "thread-opencode");
243− assert.deepEqual(runtimeMock.state.startCalls, []);
244− assert.deepEqual(runtimeMock.state.sessionCreateUrls, ["http://127.0.0.1:9999"]);
245− assert.deepEqual(runtimeMock.state.authHeaders, [
241+ NodeAssert.equal(session.provider, "opencode");
242+ NodeAssert.equal(session.threadId, "thread-opencode");
243+ NodeAssert.deepEqual(runtimeMock.state.startCalls, []);
244+ NodeAssert.deepEqual(runtimeMock.state.sessionCreateUrls, ["http://127.0.0.1:9999"]);
245+ NodeAssert.deepEqual(runtimeMock.state.authHeaders, [
246246 `Basic ${btoa("opencode:secret-password")}`,
247247 ]);
248248 }),
@@ -259,8 +259,8 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 10 unmodified lines
259259
260260 yield* adapter.stopSession(asThreadId("thread-opencode"));
261261
262− assert.deepEqual(runtimeMock.state.startCalls, []);
263− assert.deepEqual(
262+ NodeAssert.deepEqual(runtimeMock.state.startCalls, []);
263+ NodeAssert.deepEqual(
264264 runtimeMock.state.abortCalls.includes("http://127.0.0.1:9999/session"),
265265 true,
266266 );
@@ -286,7 +286,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 19 unmodified lines
286286 yield* adapter.stopSession(threadId);
287287
288288 const events = Array.from(yield* Fiber.join(eventsFiber).pipe(Effect.timeout("1 second")));
289− assert.deepEqual(
289+ NodeAssert.deepEqual(
290290 events.map((event) => event.type),
291291 ["session.started", "thread.started", "session.exited"],
292292 );
@@ -316,11 +316,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 23 unmodified lines
316316 yield* Effect.exit(adapter.stopAll());
317317 const sessions = yield* adapter.listSessions();
318318
319− assert.deepEqual(runtimeMock.state.closeCalls, [
319+ NodeAssert.deepEqual(runtimeMock.state.closeCalls, [
320320 "http://127.0.0.1:9999",
321321 "http://127.0.0.1:9999",
322322 ]);
323− assert.deepEqual(sessions, []);
323+ NodeAssert.deepEqual(sessions, []);
324324 }),
325325 );
326326
@@ -348,7 +348,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 21 unmodified lines
348348 scopeClosed = true;
349349
350350 const exit = yield* Fiber.await(eventsFiber).pipe(Effect.timeout("1 second"));
351− assert.equal(Exit.hasInterrupts(exit), true);
351+ NodeAssert.equal(Exit.hasInterrupts(exit), true);
352352 } finally {
353353 if (!scopeClosed) {
354354 yield* Scope.close(scope, Exit.void).pipe(Effect.ignore);
@@ -379,19 +379,19 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 24 unmodified lines
379379 .pipe(Effect.flip);
380380 const sessions = yield* adapter.listSessions();
381381
382− assert.equal(error._tag, "ProviderAdapterRequestError");
382+ NodeAssert.equal(error._tag, "ProviderAdapterRequestError");
383383 if (error._tag !== "ProviderAdapterRequestError") {
384384 throw new Error("Unexpected error type");
385385 }
386− assert.equal(error.detail, "prompt failed");
387− assert.equal(
386+ NodeAssert.equal(error.detail, "prompt failed");
387+ NodeAssert.equal(
388388 error.message,
389389 "Provider adapter request failed (opencode) for session.promptAsync: prompt failed",
390390 );
391− assert.equal(sessions.length, 1);
392− assert.equal(sessions[0]?.status, "ready");
393− assert.equal(sessions[0]?.activeTurnId, undefined);
394− assert.equal(sessions[0]?.lastError, "prompt failed");
391+ NodeAssert.equal(sessions.length, 1);
392+ NodeAssert.equal(sessions[0]?.status, "ready");
393+ NodeAssert.equal(sessions[0]?.activeTurnId, undefined);
394+ NodeAssert.equal(sessions[0]?.lastError, "prompt failed");
395395 }),
396396 );
397397
@@ -424,13 +424,13 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 26 unmodified lines
424424 model: "openai/gpt-5",
425425 },
426426 });
427− assert.equal(String(steeredTurn.turnId), String(turn.turnId));
427+ NodeAssert.equal(String(steeredTurn.turnId), String(turn.turnId));
428428
429429 const sessions = yield* adapter.listSessions();
430430 const session = sessions.find((entry) => entry.threadId === threadId);
431− assert.equal(session?.status, "running");
432− assert.equal(String(session?.activeTurnId), String(turn.turnId));
433− assert.equal(runtimeMock.state.promptCalls.length, 2);
431+ NodeAssert.equal(session?.status, "running");
432+ NodeAssert.equal(String(session?.activeTurnId), String(turn.turnId));
433+ NodeAssert.equal(runtimeMock.state.promptCalls.length, 2);
434434 }),
435435 );
436436
@@ -466,11 +466,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 29 unmodified lines
466466 .pipe(Effect.flip);
467467
468468 // The original turn keeps running — only the steer prompt failed.
469− assert.equal(error._tag, "ProviderAdapterRequestError");
469+ NodeAssert.equal(error._tag, "ProviderAdapterRequestError");
470470 const sessions = yield* adapter.listSessions();
471471 const session = sessions.find((entry) => entry.threadId === threadId);
472− assert.equal(session?.status, "running");
473− assert.equal(String(session?.activeTurnId), String(turn.turnId));
472+ NodeAssert.equal(session?.status, "running");
473+ NodeAssert.equal(String(session?.activeTurnId), String(turn.turnId));
474474 }),
475475 );
476476
@@ -508,7 +508,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 31 unmodified lines
508508 ),
509509 });
510510
511− assert.deepEqual(runtimeMock.state.promptCalls.at(-1), {
511+ NodeAssert.deepEqual(runtimeMock.state.promptCalls.at(-1), {
512512 sessionID: "http://127.0.0.1:9999/session",
513513 model: {
514514 providerID: "anthropic",
@@ -552,7 +552,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 37 unmodified lines
552552 input: "Fix it",
553553 });
554554
555− assert.deepEqual(runtimeMock.state.promptCalls.at(-1), {
555+ NodeAssert.deepEqual(runtimeMock.state.promptCalls.at(-1), {
556556 sessionID: "http://127.0.0.1:9999/session",
557557 model: {
558558 providerID: "anthropic",
@@ -596,15 +596,15 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 37 unmodified lines
596596 })
597597 .pipe(Effect.flip);
598598
599− assert.equal(error._tag, "ProviderAdapterValidationError");
599+ NodeAssert.equal(error._tag, "ProviderAdapterValidationError");
600600 if (error._tag !== "ProviderAdapterValidationError") {
601601 throw new Error("Unexpected error type");
602602 }
603− assert.equal(
603+ NodeAssert.equal(
604604 error.issue,
605605 "OpenCode model selection is bound to instance 'opencode', expected 'opencode_zen'.",
606606 );
607− assert.deepEqual(runtimeMock.state.promptCalls, []);
607+ NodeAssert.deepEqual(runtimeMock.state.promptCalls, []);
608608 }).pipe(Effect.provide(adapterLayer));
609609 });
610610
@@ -631,10 +631,10 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 20 unmodified lines
631631
632632 const snapshot = yield* adapter.rollbackThread(threadId, 2);
633633
634− assert.deepEqual(runtimeMock.state.revertCalls, [
634+ NodeAssert.deepEqual(runtimeMock.state.revertCalls, [
635635 { sessionID: "http://127.0.0.1:9999/session" },
636636 ]);
637− assert.deepEqual(snapshot.turns, []);
637+ NodeAssert.deepEqual(snapshot.turns, []);
638638 }),
639639 );
640640
@@ -644,11 +644,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 3 unmodified lines
644644 const overlapDelta = appendOpenCodeAssistantTextDelta(firstUpdate.latestText, "lo world");
645645 const secondUpdate = mergeOpenCodeAssistantText(overlapDelta.nextText, "Hellolo world");
646646
647− assert.deepEqual(
647+ NodeAssert.deepEqual(
648648 [firstUpdate.deltaToEmit, overlapDelta.deltaToEmit, secondUpdate.deltaToEmit],
649649 ["Hello", "lo world", ""],
650650 );
651− assert.equal(secondUpdate.latestText, "Hellolo world");
651+ NodeAssert.equal(secondUpdate.latestText, "Hellolo world");
652652 }),
653653 );
654654
@@ -721,14 +721,14 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 66 unmodified lines
721721
722722 const events = Array.from(yield* Fiber.join(eventsFiber).pipe(Effect.timeout("1 second")));
723723 const deltas = events.filter((event) => event.type === "content.delta");
724− assert.deepEqual(
724+ NodeAssert.deepEqual(
725725 deltas.map((event) => (event.type === "content.delta" ? event.payload.delta : "")),
726726 ["A B", "Bonus"],
727727 );
728− assert.equal(events.at(-1)?.type, "item.completed");
728+ NodeAssert.equal(events.at(-1)?.type, "item.completed");
729729 const completed = events.at(-1);
730730 if (completed?.type === "item.completed") {
731− assert.equal(completed.payload.detail, "A BBonus");
731+ NodeAssert.equal(completed.payload.detail, "A BBonus");
732732 }
733733 }),
734734 );
@@ -820,27 +820,27 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 85 unmodified lines
820820 return started;
821821 }).pipe(Effect.provide(adapterLayer));
822822
823− assert.equal(session.threadId, "thread-native-log");
824− assert.equal(nativeEvents.length, 1);
825− assert.equal(
823+ NodeAssert.equal(session.threadId, "thread-native-log");
824+ NodeAssert.equal(nativeEvents.length, 1);
825+ NodeAssert.equal(
826826 nativeEvents.some((record) => record.event?.provider === "opencode"),
827827 true,
828828 );
829− assert.equal(
829+ NodeAssert.equal(
830830 nativeEvents.some(
831831 (record) => record.event?.providerThreadId === "http://127.0.0.1:9999/session",
832832 ),
833833 true,
834834 );
835− assert.equal(
835+ NodeAssert.equal(
836836 nativeEvents.some((record) => record.event?.threadId === "thread-native-log"),
837837 true,
838838 );
839− assert.equal(
839+ NodeAssert.equal(
840840 nativeEvents.some((record) => record.event?.type === "message.updated"),
841841 true,
842842 );
843− assert.equal(
843+ NodeAssert.equal(
844844 nativeThreadIds.every((threadId) => threadId === "thread-native-log"),
845845 true,
846846 );
@@ -911,9 +911,9 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 64 unmodified lines
911911 };
912912 }).pipe(Effect.provide(adapterLayer));
913913
914− assert.equal(sessions.length, 1);
915− assert.equal(sessions[0]?.threadId, "thread-native-log-failure");
916− assert.deepEqual(closeCallsDuringRun, []);
914+ NodeAssert.equal(sessions.length, 1);
915+ NodeAssert.equal(sessions[0]?.threadId, "thread-native-log-failure");
916+ NodeAssert.deepEqual(closeCallsDuringRun, []);
917917 }),
918918 );
919919 });
apps/server/src/provider/Layers/OpenCodeProvider.test.ts+22−19
@@ -1,4 +1,4 @@
1−import assert from "node:assert/strict";
1+import * as NodeAssert from "node:assert/strict";
22
33 import * as NodeServices from "@effect/platform-node/NodeServices";
44 import { it } from "@effect/vitest";
@@ -122,9 +122,12 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 117 unmodified lines
122122 runtimeMock.state.runVersionError = new Error("spawn opencode ENOENT");
123123 const snapshot = yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd());
124124
125− assert.equal(snapshot.status, "error");
126− assert.equal(snapshot.installed, false);
127− assert.equal(snapshot.message, "OpenCode CLI (`opencode`) is not installed or not on PATH.");
125+ NodeAssert.equal(snapshot.status, "error");
126+ NodeAssert.equal(snapshot.installed, false);
127+ NodeAssert.equal(
128+ snapshot.message,
129+ "OpenCode CLI (`opencode`) is not installed or not on PATH.",
130+ );
128131 }),
129132 );
130133
@@ -133,9 +136,9 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 2 unmodified lines
133136 runtimeMock.state.runVersionError = new Error("An error occurred in Effect.tryPromise");
134137 const snapshot = yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd());
135138
136− assert.equal(snapshot.status, "error");
137− assert.equal(snapshot.installed, true);
138− assert.equal(snapshot.message, "Failed to execute OpenCode CLI health check.");
139+ NodeAssert.equal(snapshot.status, "error");
140+ NodeAssert.equal(snapshot.installed, true);
141+ NodeAssert.equal(snapshot.message, "Failed to execute OpenCode CLI health check.");
139142 }),
140143 );
141144
@@ -174,20 +177,20 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 32 unmodified lines
174177 const snapshot = yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd());
175178 const model = snapshot.models.find((entry) => entry.slug === "openai/gpt-5.4");
176179
177− assert.ok(model);
180+ NodeAssert.ok(model);
178181 const variantDescriptor = model.capabilities?.optionDescriptors?.find(
179182 (descriptor) => descriptor.id === "variant" && descriptor.type === "select",
180183 );
181− assert.ok(variantDescriptor && variantDescriptor.type === "select");
182− assert.equal(
184+ NodeAssert.ok(variantDescriptor && variantDescriptor.type === "select");
185+ NodeAssert.equal(
183186 variantDescriptor.options.find((option) => option.isDefault === true)?.id,
184187 "medium",
185188 );
186189 const agentDescriptor = model.capabilities?.optionDescriptors?.find(
187190 (descriptor) => descriptor.id === "agent" && descriptor.type === "select",
188191 );
189− assert.ok(agentDescriptor && agentDescriptor.type === "select");
190− assert.equal(
192+ NodeAssert.ok(agentDescriptor && agentDescriptor.type === "select");
193+ NodeAssert.equal(
191194 agentDescriptor.options.find((option) => option.isDefault === true)?.id,
192195 "build",
193196 );
@@ -198,7 +201,7 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 4 unmodified lines
198201 Effect.gen(function* () {
199202 yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd());
200203
201− assert.equal(runtimeMock.state.closeCalls, 1);
204+ NodeAssert.equal(runtimeMock.state.closeCalls, 1);
202205 }),
203206 );
204207 });
@@ -215,9 +218,9 @@ it.layer(testLayer)("checkOpenCodeProviderStatus with configured server URL", (i · 10 unmodified lines
215218 process.cwd(),
216219 );
217220
218− assert.equal(snapshot.status, "error");
219− assert.equal(snapshot.installed, true);
220− assert.equal(
221+ NodeAssert.equal(snapshot.status, "error");
222+ NodeAssert.equal(snapshot.installed, true);
223+ NodeAssert.equal(
221224 snapshot.message,
222225 "OpenCode server rejected authentication. Check the server URL and password.",
223226 );
@@ -237,9 +240,9 @@ it.layer(testLayer)("checkOpenCodeProviderStatus with configured server URL", (i · 13 unmodified lines
237240 process.cwd(),
238241 );
239242
240− assert.equal(snapshot.status, "error");
241− assert.equal(snapshot.installed, true);
242− assert.equal(
243+ NodeAssert.equal(snapshot.status, "error");
244+ NodeAssert.equal(snapshot.installed, true);
245+ NodeAssert.equal(
243246 snapshot.message,
244247 "Couldn't reach the configured OpenCode server at http://127.0.0.1:9999. Check that the server is running and the URL is correct.",
245248 );
apps/server/src/provider/Layers/ProviderService.test.ts+21−15
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import type {
77 ProviderApprovalDecision,
@@ -644,8 +644,8 @@ it.effect("ProviderServiceLive writes canonical events to the emitting thread se · 636 unmodified lines
644644
645645 it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", () =>
646646 Effect.gen(function* () {
647− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-service-"));
648− const dbPath = path.join(tempDir, "orchestration.sqlite");
647+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-provider-service-"));
648+ const dbPath = NodePath.join(tempDir, "orchestration.sqlite");
649649
650650 const codex = makeFakeCodexAdapter();
651651 const registry = makeAdapterRegistryMock({
@@ -706,7 +706,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", ( · 54 unmodified lines
706706 }).pipe(Effect.provide(persistenceLayer));
707707 assert.equal(legacyTableRows.length, 0);
708708
709− fs.rmSync(tempDir, { recursive: true, force: true });
709+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
710710 }).pipe(Effect.provide(NodeServices.layer)),
711711 );
712712
@@ -714,8 +714,10 @@ it.effect( · 1 unmodified line
714714 "ProviderServiceLive restores rollback routing after restart using persisted thread mapping",
715715 () =>
716716 Effect.gen(function* () {
717− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-service-restart-"));
718− const dbPath = path.join(tempDir, "orchestration.sqlite");
717+ const tempDir = NodeFS.mkdtempSync(
718+ NodePath.join(NodeOS.tmpdir(), "t3-provider-service-restart-"),
719+ );
720+ const dbPath = NodePath.join(tempDir, "orchestration.sqlite");
719721 const persistenceLayer = makeSqlitePersistenceLive(dbPath);
720722 const runtimeRepositoryLayer = ProviderSessionRuntime.layer.pipe(
721723 Layer.provide(persistenceLayer),
@@ -834,7 +836,7 @@ it.effect( · 112 unmodified lines
834836 assert.equal(typeof rollbackCall?.[0], "string");
835837 assert.equal(rollbackCall?.[1], 1);
836838
837− fs.rmSync(tempDir, { recursive: true, force: true });
839+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
838840 }).pipe(Effect.provide(NodeServices.layer)),
839841 );
840842
@@ -1283,8 +1285,10 @@ routing.layer("ProviderServiceLive routing", (it) => { · 442 unmodified lines
12831285
12841286 it.effect("reuses persisted resume cursor when startSession is called after a restart", () =>
12851287 Effect.gen(function* () {
1286− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-service-start-"));
1287− const dbPath = path.join(tempDir, "orchestration.sqlite");
1288+ const tempDir = NodeFS.mkdtempSync(
1289+ NodePath.join(NodeOS.tmpdir(), "t3-provider-service-start-"),
1290+ );
1291+ const dbPath = NodePath.join(tempDir, "orchestration.sqlite");
12881292 const persistenceLayer = makeSqlitePersistenceLive(dbPath);
12891293 const runtimeRepositoryLayer = ProviderSessionRuntime.layer.pipe(
12901294 Layer.provide(persistenceLayer),
@@ -1379,7 +1383,7 @@ routing.layer("ProviderServiceLive routing", (it) => { · 88 unmodified lines
13791383 assert.equal(startPayload.threadId, initial.threadId);
13801384 }
13811385
1382− fs.rmSync(tempDir, { recursive: true, force: true });
1386+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
13831387 }).pipe(Effect.provide(NodeServices.layer)),
13841388 );
13851389
@@ -1387,8 +1391,10 @@ routing.layer("ProviderServiceLive routing", (it) => { · 1 unmodified line
13871391 "reuses persisted cwd when startSession resumes a claude session without cwd input",
13881392 () =>
13891393 Effect.gen(function* () {
1390− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-service-cwd-"));
1391− const dbPath = path.join(tempDir, "orchestration.sqlite");
1394+ const tempDir = NodeFS.mkdtempSync(
1395+ NodePath.join(NodeOS.tmpdir(), "t3-provider-service-cwd-"),
1396+ );
1397+ const dbPath = NodePath.join(tempDir, "orchestration.sqlite");
13921398 const persistenceLayer = makeSqlitePersistenceLive(dbPath);
13931399 const runtimeRepositoryLayer = ProviderSessionRuntime.layer.pipe(
13941400 Layer.provide(persistenceLayer),
@@ -1477,7 +1483,7 @@ routing.layer("ProviderServiceLive routing", (it) => { · 82 unmodified lines
14771483 assert.equal(startPayload.threadId, initial.threadId);
14781484 }
14791485
1480− fs.rmSync(tempDir, { recursive: true, force: true });
1486+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
14811487 }).pipe(Effect.provide(NodeServices.layer)),
14821488 );
14831489 });
apps/server/src/provider/Layers/ProviderSessionDirectory.test.ts+6−6
@@ -1,7 +1,7 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fs from "node:fs";
3−import os from "node:os";
4−import path from "node:path";
2+import * as NodeFS from "node:fs";
3+import * as NodeOS from "node:os";
4+import * as NodePath from "node:path";
55
66 import * as NodeServices from "@effect/platform-node/NodeServices";
77 import { ProviderDriverKind, ThreadId } from "@t3tools/contracts";
@@ -229,8 +229,8 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL · 221 unmodified lines
229229
230230 it("rehydrates persisted mappings across layer restart", () =>
231231 Effect.gen(function* () {
232− const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "t3-provider-directory-"));
233− const dbPath = path.join(tempDir, "orchestration.sqlite");
232+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3-provider-directory-"));
233+ const dbPath = NodePath.join(tempDir, "orchestration.sqlite");
234234 const directoryLayer = makeDirectoryLayer(makeSqlitePersistenceLive(dbPath));
235235
236236 const threadId = ThreadId.make("thread-restart");
@@ -266,6 +266,6 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL · 29 unmodified lines
266266 assert.equal(legacyTableRows.length, 0);
267267 }).pipe(Effect.provide(directoryLayer));
268268
269− fs.rmSync(tempDir, { recursive: true, force: true });
269+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
270270 }));
271271 });
apps/server/src/provider/acp/AcpJsonRpcConnection.test.ts+10−10
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as path from "node:path";
3−import * as os from "node:os";
4−import { fileURLToPath } from "node:url";
5−import { mkdtempSync, readFileSync, rmSync } from "node:fs";
2+import * as NodePath from "node:path";
3+import * as NodeOS from "node:os";
4+import * as NodeURL from "node:url";
5+import * as NodeFS from "node:fs";
66
77 import * as NodeServices from "@effect/platform-node/NodeServices";
88 import { it } from "@effect/vitest";
@@ -13,8 +13,8 @@ import { describe, expect } from "vite-plus/test"; · 4 unmodified lines
1313 import * as AcpSessionRuntime from "./AcpSessionRuntime.ts";
1414 import type * as EffectAcpProtocol from "effect-acp/protocol";
1515
16−const __dirname = path.dirname(fileURLToPath(import.meta.url));
17−const mockAgentPath = path.join(__dirname, "../../../scripts/acp-mock-agent.ts");
16+const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url));
17+const mockAgentPath = NodePath.join(__dirname, "../../../scripts/acp-mock-agent.ts");
1818 const mockAgentCommand = "node";
1919 const mockAgentArgs = [mockAgentPath];
2020
@@ -347,8 +347,8 @@ describe("AcpSessionRuntime", () => { · 326 unmodified lines
347347 });
348348
349349 it.effect("rejects invalid config option values before sending session/set_config_option", () => {
350− const tempDir = mkdtempSync(path.join(os.tmpdir(), "acp-runtime-"));
351− const requestLogPath = path.join(tempDir, "requests.ndjson");
350+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "acp-runtime-"));
351+ const requestLogPath = NodePath.join(tempDir, "requests.ndjson");
352352 return Effect.gen(function* () {
353353 const runtime = yield* AcpSessionRuntime.AcpSessionRuntime;
354354 yield* runtime.start();
@@ -363,7 +363,7 @@ describe("AcpSessionRuntime", () => { · 8 unmodified lines
363363 expect(error.message).toContain("composer-2[fast=true]");
364364 }
365365
366− const recordedRequests = readFileSync(requestLogPath, "utf8")
366+ const recordedRequests = NodeFS.readFileSync(requestLogPath, "utf8")
367367 .trim()
368368 .split("\n")
369369 .filter((line) => line.length > 0)
@@ -392,7 +392,7 @@ describe("AcpSessionRuntime", () => { · 22 unmodified lines
392392 ),
393393 Effect.scoped,
394394 Effect.provide(NodeServices.layer),
395− Effect.ensuring(Effect.sync(() => rmSync(tempDir, { recursive: true, force: true }))),
395+ Effect.ensuring(Effect.sync(() => NodeFS.rmSync(tempDir, { recursive: true, force: true }))),
396396 );
397397 });
398398 });
apps/server/src/provider/opencodeRuntime.ts+2−2
@@ -1,4 +1,4 @@
1−import { pathToFileURL } from "node:url";
1+import * as NodeURL from "node:url";
22
33 import type { ChatAttachment, ProviderApprovalDecision, RuntimeMode } from "@t3tools/contracts";
44 import {
@@ -206,7 +206,7 @@ export function toOpenCodeFileParts(input: { · 201 unmodified lines
206206 type: "file",
207207 mime: attachment.mimeType,
208208 filename: attachment.name,
209− url: pathToFileURL(attachmentPath).href,
209+ url: NodeURL.pathToFileURL(attachmentPath).href,
210210 });
211211 }
212212
apps/server/src/provider/providerMaintenance.test.ts+44−44
@@ -1,9 +1,9 @@
11 // @effect-diagnostics nodeBuiltinImport:off
22 import { expect, it } from "@effect/vitest";
3−import { chmodSync, mkdirSync, symlinkSync, writeFileSync } from "node:fs";
3+import * as NodeFS from "node:fs";
44 import * as NodeServices from "@effect/platform-node/NodeServices";
55 import * as NodeOS from "node:os";
6−import path from "node:path";
6+import * as NodePath from "node:path";
77 import { ProviderDriverKind, ProviderInstanceId, type ServerProvider } from "@t3tools/contracts";
88 import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
99 import * as Crypto from "effect/Crypto";
@@ -25,7 +25,7 @@ const driver = (value: string) => ProviderDriverKind.make(value); · 15 unmodified lines
2525 const makeTempDir = (name: string) =>
2626 Crypto.Crypto.pipe(
2727 Effect.flatMap((crypto) => crypto.randomUUIDv4),
28− Effect.map((id) => path.join(NodeOS.tmpdir(), `${name}-${id}`)),
28+ Effect.map((id) => NodePath.join(NodeOS.tmpdir(), `${name}-${id}`)),
2929 );
3030 const isNativeTestCommandPath =
3131 (expectedPathSegment: string) =>
@@ -203,11 +203,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 171 unmodified lines
203203 () =>
204204 Effect.gen(function* () {
205205 const tempDir = yield* makeTempDir("t3-vite-plus-capabilities");
206− const vitePlusBinDir = path.join(tempDir, ".vite-plus", "bin");
207− mkdirSync(vitePlusBinDir, { recursive: true });
208− const packageToolPath = path.join(vitePlusBinDir, "package-tool");
209− writeFileSync(packageToolPath, "#!/bin/sh\n");
210− chmodSync(packageToolPath, 0o755);
206+ const vitePlusBinDir = NodePath.join(tempDir, ".vite-plus", "bin");
207+ NodeFS.mkdirSync(vitePlusBinDir, { recursive: true });
208+ const packageToolPath = NodePath.join(vitePlusBinDir, "package-tool");
209+ NodeFS.writeFileSync(packageToolPath, "#!/bin/sh\n");
210+ NodeFS.chmodSync(packageToolPath, 0o755);
211211
212212 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(
213213 packageToolUpdate,
@@ -240,9 +240,9 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 26 unmodified lines
240240 () =>
241241 Effect.gen(function* () {
242242 const tempDir = yield* makeTempDir("t3-bun-capabilities");
243− const bunBinDir = path.join(tempDir, ".bun", "bin");
244− mkdirSync(bunBinDir, { recursive: true });
245− writeFileSync(path.join(bunBinDir, "native-package-tool.exe"), "MZ");
243+ const bunBinDir = NodePath.join(tempDir, ".bun", "bin");
244+ NodeFS.mkdirSync(bunBinDir, { recursive: true });
245+ NodeFS.writeFileSync(NodePath.join(bunBinDir, "native-package-tool.exe"), "MZ");
246246
247247 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(
248248 nativePackageToolUpdate,
@@ -276,11 +276,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 27 unmodified lines
276276 () =>
277277 Effect.gen(function* () {
278278 const tempDir = yield* makeTempDir("t3-pnpm-capabilities");
279− const pnpmHomeDir = path.join(tempDir, ".local", "share", "pnpm");
280− mkdirSync(pnpmHomeDir, { recursive: true });
281− const scopedPackageToolPath = path.join(pnpmHomeDir, "scoped-package-tool");
282− writeFileSync(scopedPackageToolPath, "#!/bin/sh\n");
283− chmodSync(scopedPackageToolPath, 0o755);
279+ const pnpmHomeDir = NodePath.join(tempDir, ".local", "share", "pnpm");
280+ NodeFS.mkdirSync(pnpmHomeDir, { recursive: true });
281+ const scopedPackageToolPath = NodePath.join(pnpmHomeDir, "scoped-package-tool");
282+ NodeFS.writeFileSync(scopedPackageToolPath, "#!/bin/sh\n");
283+ NodeFS.chmodSync(scopedPackageToolPath, 0o755);
284284
285285 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(
286286 scopedPackageToolUpdate,
@@ -336,11 +336,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 49 unmodified lines
336336 () =>
337337 Effect.gen(function* () {
338338 const tempDir = yield* makeTempDir("t3-native-package-tool-native-capabilities");
339− const nativeBinDir = path.join(tempDir, ".local", "bin");
340− mkdirSync(nativeBinDir, { recursive: true });
341− const nativePackageToolPath = path.join(nativeBinDir, "native-package-tool");
342− writeFileSync(nativePackageToolPath, "#!/bin/sh\n");
343− chmodSync(nativePackageToolPath, 0o755);
339+ const nativeBinDir = NodePath.join(tempDir, ".local", "bin");
340+ NodeFS.mkdirSync(nativeBinDir, { recursive: true });
341+ const nativePackageToolPath = NodePath.join(nativeBinDir, "native-package-tool");
342+ NodeFS.writeFileSync(nativePackageToolPath, "#!/bin/sh\n");
343+ NodeFS.chmodSync(nativePackageToolPath, 0o755);
344344
345345 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(
346346 nativePackageToolUpdate,
@@ -373,11 +373,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 26 unmodified lines
373373 () =>
374374 Effect.gen(function* () {
375375 const tempDir = yield* makeTempDir("t3-scoped-package-tool-native-capabilities");
376− const nativeBinDir = path.join(tempDir, ".scoped-package-tool", "bin");
377− mkdirSync(nativeBinDir, { recursive: true });
378− const scopedPackageToolPath = path.join(nativeBinDir, "scoped-package-tool");
379− writeFileSync(scopedPackageToolPath, "#!/bin/sh\n");
380− chmodSync(scopedPackageToolPath, 0o755);
376+ const nativeBinDir = NodePath.join(tempDir, ".scoped-package-tool", "bin");
377+ NodeFS.mkdirSync(nativeBinDir, { recursive: true });
378+ const scopedPackageToolPath = NodePath.join(nativeBinDir, "scoped-package-tool");
379+ NodeFS.writeFileSync(scopedPackageToolPath, "#!/bin/sh\n");
380+ NodeFS.chmodSync(scopedPackageToolPath, 0o755);
381381
382382 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(
383383 scopedPackageToolUpdate,
@@ -454,8 +454,8 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 70 unmodified lines
454454 it.effect("keeps npm updates for binaries symlinked into npm's global node_modules tree", () =>
455455 Effect.gen(function* () {
456456 const tempDir = yield* makeTempDir("t3-npm-capabilities");
457− const binDir = path.join(tempDir, "bin");
458− const packageBinDir = path.join(
457+ const binDir = NodePath.join(tempDir, "bin");
458+ const packageBinDir = NodePath.join(
459459 tempDir,
460460 "lib",
461461 "node_modules",
@@ -463,13 +463,13 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 1 unmodified line
463463 "package-tool",
464464 "bin",
465465 );
466− mkdirSync(binDir, { recursive: true });
467− mkdirSync(packageBinDir, { recursive: true });
468− const packageBinPath = path.join(packageBinDir, "package-tool.js");
469− const symlinkPath = path.join(binDir, "package-tool");
470− writeFileSync(packageBinPath, "#!/usr/bin/env node\n");
471− chmodSync(packageBinPath, 0o755);
472− symlinkSync(packageBinPath, symlinkPath);
466+ NodeFS.mkdirSync(binDir, { recursive: true });
467+ NodeFS.mkdirSync(packageBinDir, { recursive: true });
468+ const packageBinPath = NodePath.join(packageBinDir, "package-tool.js");
469+ const symlinkPath = NodePath.join(binDir, "package-tool");
470+ NodeFS.writeFileSync(packageBinPath, "#!/usr/bin/env node\n");
471+ NodeFS.chmodSync(packageBinPath, 0o755);
472+ NodeFS.symlinkSync(packageBinPath, symlinkPath);
473473
474474 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(packageToolUpdate, {
475475 binaryPath: symlinkPath,
@@ -497,8 +497,8 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 21 unmodified lines
497497 it.effect("uses Effect FileSystem realPath when detecting pnpm global symlinks", () =>
498498 Effect.gen(function* () {
499499 const tempDir = yield* makeTempDir("t3-pnpm-realpath-capabilities");
500− const binDir = path.join(tempDir, "bin");
501− const packageBinDir = path.join(
500+ const binDir = NodePath.join(tempDir, "bin");
501+ const packageBinDir = NodePath.join(
502502 tempDir,
503503 ".local",
504504 "share",
@@ -510,13 +510,13 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 5 unmodified lines
510510 "package-tool",
511511 "bin",
512512 );
513− mkdirSync(binDir, { recursive: true });
514− mkdirSync(packageBinDir, { recursive: true });
515− const packageBinPath = path.join(packageBinDir, "package-tool.js");
516− const symlinkPath = path.join(binDir, "package-tool");
517− writeFileSync(packageBinPath, "#!/usr/bin/env node\n");
518− chmodSync(packageBinPath, 0o755);
519− symlinkSync(packageBinPath, symlinkPath);
513+ NodeFS.mkdirSync(binDir, { recursive: true });
514+ NodeFS.mkdirSync(packageBinDir, { recursive: true });
515+ const packageBinPath = NodePath.join(packageBinDir, "package-tool.js");
516+ const symlinkPath = NodePath.join(binDir, "package-tool");
517+ NodeFS.writeFileSync(packageBinPath, "#!/usr/bin/env node\n");
518+ NodeFS.chmodSync(packageBinPath, 0o755);
519+ NodeFS.symlinkSync(packageBinPath, symlinkPath);
520520
521521 const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(packageToolUpdate, {
522522 binaryPath: symlinkPath,
apps/server/src/relay/AgentAwarenessRelay.test.ts+2−2
@@ -1,4 +1,4 @@
1−import { generateKeyPairSync } from "node:crypto";
1+import * as NodeCrypto from "node:crypto";
22 import * as NodeServices from "@effect/platform-node/NodeServices";
33
44 import type {
@@ -348,7 +348,7 @@ describe.sequential("signRelayAgentActivityPublishProof", () => { · 343 unmodified lines
348348 });
349349
350350 it("signs the activity publish JWT and rejects tampering", async () => {
351− const keyPair = generateKeyPairSync("ed25519", {
351+ const keyPair = NodeCrypto.generateKeyPairSync("ed25519", {
352352 privateKeyEncoding: { format: "pem", type: "pkcs8" },
353353 publicKeyEncoding: { format: "pem", type: "spki" },
354354 });
apps/server/src/server.test.ts+22−22
@@ -1,7 +1,7 @@
11 import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer";
22 import * as NodeSocket from "@effect/platform-node/NodeSocket";
33 import * as NodeServices from "@effect/platform-node/NodeServices";
4−import { generateKeyPairSync, type KeyObject, sign } from "node:crypto";
4+import * as NodeCrypto from "node:crypto";
55
66 import {
77 AuthAccessTokenType,
@@ -950,14 +950,14 @@ const makeDpopProof = (input: { · 942 unmodified lines
950950 readonly iat: number;
951951 readonly accessToken?: string;
952952 readonly jti?: string;
953− readonly privateKey?: KeyObject;
953+ readonly privateKey?: NodeCrypto.KeyObject;
954954 readonly publicJwk?: DpopPublicJwk;
955955 }) => {
956956 const keyPair =
957957 input.privateKey && input.publicJwk
958958 ? { privateKey: input.privateKey, publicJwk: input.publicJwk }
959959 : (() => {
960− const { privateKey, publicKey } = generateKeyPairSync("ec", {
960+ const { privateKey, publicKey } = NodeCrypto.generateKeyPairSync("ec", {
961961 namedCurve: "P-256",
962962 });
963963 return { privateKey, publicJwk: publicKey.export({ format: "jwk" }) as DpopPublicJwk };
@@ -978,7 +978,7 @@ const makeDpopProof = (input: { · 14 unmodified lines
978978 ...(input.accessToken ? { ath: computeDpopAccessTokenHash(input.accessToken) } : {}),
979979 }),
980980 ).toString("base64url");
981− const signature = sign("sha256", Buffer.from(`${header}.${payload}`), {
981+ const signature = NodeCrypto.sign("sha256", Buffer.from(`${header}.${payload}`), {
982982 key: keyPair.privateKey,
983983 dsaEncoding: "ieee-p1363",
984984 }).toString("base64url");
@@ -1024,7 +1024,7 @@ const makeCloudMintCredentialRequest = (input: { · 39 unmodified lines
10241024 const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
10251025 const signingInput = `${header}.${encodedPayload}`;
10261026 return {
1027− proof: `${signingInput}.${sign(null, Buffer.from(signingInput), input.privateKey).toString("base64url")}`,
1027+ proof: `${signingInput}.${NodeCrypto.sign(null, Buffer.from(signingInput), input.privateKey).toString("base64url")}`,
10281028 };
10291029 };
10301030
@@ -1057,7 +1057,7 @@ const makeCloudEnvironmentHealthRequest = (input: { · 26 unmodified lines
10571057 const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url");
10581058 const signingInput = `${header}.${encodedPayload}`;
10591059 return {
1060− proof: `${signingInput}.${sign(null, Buffer.from(signingInput), input.privateKey).toString("base64url")}`,
1060+ proof: `${signingInput}.${NodeCrypto.sign(null, Buffer.from(signingInput), input.privateKey).toString("base64url")}`,
10611061 };
10621062 };
10631063
@@ -2054,7 +2054,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 990 unmodified lines
20542054 Effect.gen(function* () {
20552055 yield* buildAppUnderTest();
20562056
2057− const cloudKeyPair = generateKeyPairSync("ed25519", {
2057+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
20582058 privateKeyEncoding: { format: "pem", type: "pkcs8" },
20592059 publicKeyEncoding: { format: "pem", type: "spki" },
20602060 });
@@ -2131,7 +2131,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 70 unmodified lines
21312131 Effect.gen(function* () {
21322132 yield* buildAppUnderTest();
21332133
2134− const cloudKeyPair = generateKeyPairSync("ed25519", {
2134+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
21352135 privateKeyEncoding: { format: "pem", type: "pkcs8" },
21362136 publicKeyEncoding: { format: "pem", type: "spki" },
21372137 });
@@ -2174,7 +2174,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 36 unmodified lines
21742174 Effect.gen(function* () {
21752175 yield* buildAppUnderTest();
21762176
2177− const cloudKeyPair = generateKeyPairSync("ed25519", {
2177+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
21782178 privateKeyEncoding: { format: "pem", type: "pkcs8" },
21792179 publicKeyEncoding: { format: "pem", type: "spki" },
21802180 });
@@ -2268,7 +2268,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 87 unmodified lines
22682268 },
22692269 });
22702270
2271− const cloudKeyPair = generateKeyPairSync("ed25519", {
2271+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
22722272 privateKeyEncoding: { format: "pem", type: "pkcs8" },
22732273 publicKeyEncoding: { format: "pem", type: "spki" },
22742274 });
@@ -2345,7 +2345,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 70 unmodified lines
23452345 Effect.gen(function* () {
23462346 yield* buildAppUnderTest();
23472347
2348− const cloudKeyPair = generateKeyPairSync("ed25519", {
2348+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
23492349 privateKeyEncoding: { format: "pem", type: "pkcs8" },
23502350 publicKeyEncoding: { format: "pem", type: "spki" },
23512351 });
@@ -2404,7 +2404,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 52 unmodified lines
24042404 Effect.gen(function* () {
24052405 yield* buildAppUnderTest();
24062406
2407− const cloudKeyPair = generateKeyPairSync("ed25519", {
2407+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
24082408 privateKeyEncoding: { format: "pem", type: "pkcs8" },
24092409 publicKeyEncoding: { format: "pem", type: "spki" },
24102410 });
@@ -2463,7 +2463,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 52 unmodified lines
24632463 Effect.gen(function* () {
24642464 yield* buildAppUnderTest();
24652465
2466− const cloudKeyPair = generateKeyPairSync("ed25519", {
2466+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
24672467 privateKeyEncoding: { format: "pem", type: "pkcs8" },
24682468 publicKeyEncoding: { format: "pem", type: "spki" },
24692469 });
@@ -2523,7 +2523,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 53 unmodified lines
25232523 Effect.gen(function* () {
25242524 yield* buildAppUnderTest();
25252525
2526− const cloudKeyPair = generateKeyPairSync("ed25519", {
2526+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
25272527 privateKeyEncoding: { format: "pem", type: "pkcs8" },
25282528 publicKeyEncoding: { format: "pem", type: "spki" },
25292529 });
@@ -2584,7 +2584,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 54 unmodified lines
25842584 Effect.gen(function* () {
25852585 yield* buildAppUnderTest();
25862586
2587− const cloudKeyPair = generateKeyPairSync("ed25519", {
2587+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
25882588 privateKeyEncoding: { format: "pem", type: "pkcs8" },
25892589 publicKeyEncoding: { format: "pem", type: "spki" },
25902590 });
@@ -2664,7 +2664,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 73 unmodified lines
26642664 },
26652665 });
26662666
2667− const cloudKeyPair = generateKeyPairSync("ed25519", {
2667+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
26682668 privateKeyEncoding: { format: "pem", type: "pkcs8" },
26692669 publicKeyEncoding: { format: "pem", type: "spki" },
26702670 });
@@ -2733,7 +2733,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 62 unmodified lines
27332733 Effect.gen(function* () {
27342734 yield* buildAppUnderTest();
27352735
2736− const cloudKeyPair = generateKeyPairSync("ed25519", {
2736+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
27372737 privateKeyEncoding: { format: "pem", type: "pkcs8" },
27382738 publicKeyEncoding: { format: "pem", type: "spki" },
27392739 });
@@ -2800,7 +2800,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 60 unmodified lines
28002800 Effect.gen(function* () {
28012801 yield* buildAppUnderTest();
28022802
2803− const cloudKeyPair = generateKeyPairSync("ed25519", {
2803+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
28042804 privateKeyEncoding: { format: "pem", type: "pkcs8" },
28052805 publicKeyEncoding: { format: "pem", type: "spki" },
28062806 });
@@ -2851,7 +2851,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 44 unmodified lines
28512851 Effect.gen(function* () {
28522852 yield* buildAppUnderTest();
28532853
2854− const cloudKeyPair = generateKeyPairSync("ed25519", {
2854+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
28552855 privateKeyEncoding: { format: "pem", type: "pkcs8" },
28562856 publicKeyEncoding: { format: "pem", type: "spki" },
28572857 });
@@ -2902,7 +2902,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 44 unmodified lines
29022902 Effect.gen(function* () {
29032903 yield* buildAppUnderTest();
29042904
2905− const cloudKeyPair = generateKeyPairSync("ed25519", {
2905+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
29062906 privateKeyEncoding: { format: "pem", type: "pkcs8" },
29072907 publicKeyEncoding: { format: "pem", type: "spki" },
29082908 });
@@ -2967,7 +2967,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 58 unmodified lines
29672967 Effect.gen(function* () {
29682968 yield* buildAppUnderTest();
29692969
2970− const cloudKeyPair = generateKeyPairSync("ed25519", {
2970+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
29712971 privateKeyEncoding: { format: "pem", type: "pkcs8" },
29722972 publicKeyEncoding: { format: "pem", type: "spki" },
29732973 });
@@ -3017,7 +3017,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 43 unmodified lines
30173017 Effect.gen(function* () {
30183018 yield* buildAppUnderTest();
30193019
3020− const cloudKeyPair = generateKeyPairSync("ed25519", {
3020+ const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", {
30213021 privateKeyEncoding: { format: "pem", type: "pkcs8" },
30223022 publicKeyEncoding: { format: "pem", type: "spki" },
30233023 });
apps/server/src/terminal/NodePtyAdapter.ts+2−2
@@ -1,4 +1,4 @@
1−import { createRequire } from "node:module";
1+import * as NodeModule from "node:module";
22
33 import * as Effect from "effect/Effect";
44 import * as FileSystem from "effect/FileSystem";
@@ -11,7 +11,7 @@ import * as PtyAdapter from "./PtyAdapter.ts"; · 6 unmodified lines
1111 let didEnsureSpawnHelperExecutable = false;
1212
1313 const resolveNodePtySpawnHelperPath = Effect.gen(function* () {
14− const requireForNodePty = createRequire(import.meta.url);
14+ const requireForNodePty = NodeModule.createRequire(import.meta.url);
1515 const path = yield* Path.Path;
1616 const fs = yield* FileSystem.FileSystem;
1717 const platform = yield* HostProcessPlatform;
apps/server/src/textGeneration/CursorTextGeneration.test.ts+25−21
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as path from "node:path";
3−import * as os from "node:os";
4−import { fileURLToPath } from "node:url";
5−import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2+import * as NodePath from "node:path";
3+import * as NodeOS from "node:os";
4+import * as NodeURL from "node:url";
5+import * as NodeFS from "node:fs";
66
77 import * as NodeServices from "@effect/platform-node/NodeServices";
88 import { it } from "@effect/vitest";
@@ -21,8 +21,8 @@ import * as TextGeneration from "./TextGeneration.ts"; · 12 unmodified lines
2121 import { makeCursorTextGeneration } from "./CursorTextGeneration.ts";
2222 const decodeCursorSettings = Schema.decodeSync(CursorSettings);
2323
24−const __dirname = path.dirname(fileURLToPath(import.meta.url));
25−const mockAgentPath = path.join(__dirname, "../../scripts/acp-mock-agent.ts");
24+const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url));
25+const mockAgentPath = NodePath.join(__dirname, "../../scripts/acp-mock-agent.ts");
2626
2727 function shellSingleQuote(value: string): string {
2828 return `'${value.replaceAll("'", `'"'"'`)}'`;
@@ -33,10 +33,10 @@ const CursorTextGenerationTestLayer = ServerConfig.ServerConfig.layerTest(proces · 4 unmodified lines
3333 }).pipe(Layer.provideMerge(NodeServices.layer));
3434
3535 function makeAcpAgentWrapper(dir: string, env: Record<string, string>): string {
36− const binDir = path.join(dir, "bin");
37− const agentPath = path.join(binDir, "agent");
38− mkdirSync(binDir, { recursive: true });
39− writeFileSync(
36+ const binDir = NodePath.join(dir, "bin");
37+ const agentPath = NodePath.join(binDir, "agent");
38+ NodeFS.mkdirSync(binDir, { recursive: true });
39+ NodeFS.writeFileSync(
4040 agentPath,
4141 [
4242 "#!/bin/sh",
@@ -50,7 +50,7 @@ function makeAcpAgentWrapper(dir: string, env: Record<string, string>): string { · 7 unmodified lines
5050 ].join("\n"),
5151 "utf8",
5252 );
53− chmodSync(agentPath, 0o755);
53+ NodeFS.chmodSync(agentPath, 0o755);
5454 return agentPath;
5555 }
5656
@@ -59,10 +59,10 @@ function withFakeAcpAgent<A, E, R>( · 2 unmodified lines
5959 effectFn: (textGeneration: TextGeneration.TextGeneration["Service"]) => Effect.Effect<A, E, R>,
6060 ) {
6161 return Effect.gen(function* () {
62− const tempDir = mkdtempSync(path.join(os.tmpdir(), "t3code-cursor-text-acp-"));
62+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3code-cursor-text-acp-"));
6363 yield* Effect.addFinalizer(() =>
6464 Effect.sync(() => {
65− rmSync(tempDir, { recursive: true, force: true });
65+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
6666 }),
6767 );
6868 const agentPath = makeAcpAgentWrapper(tempDir, env);
@@ -76,7 +76,7 @@ function waitForFileContent(path: string): Effect.Effect<string> { · 7 unmodified lines
7676 return Effect.gen(function* () {
7777 const deadline = (yield* Clock.currentTimeMillis) + 5_000;
7878 for (;;) {
79− const result = yield* Effect.exit(Effect.sync(() => readFileSync(path, "utf8")));
79+ const result = yield* Effect.exit(Effect.sync(() => NodeFS.readFileSync(path, "utf8")));
8080 if (Exit.isSuccess(result)) {
8181 return result.value;
8282 }
@@ -92,8 +92,10 @@ function waitForFileContent(path: string): Effect.Effect<string> { · 9 unmodified lines
9292
9393 it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => {
9494 it.effect("uses ACP model config options instead of raw CLI model ids", () => {
95− const requestLogDir = mkdtempSync(path.join(os.tmpdir(), "t3code-cursor-text-log-"));
96− const requestLogPath = path.join(requestLogDir, "requests.ndjson");
95+ const requestLogDir = NodeFS.mkdtempSync(
96+ NodePath.join(NodeOS.tmpdir(), "t3code-cursor-text-log-"),
97+ );
98+ const requestLogPath = NodePath.join(requestLogDir, "requests.ndjson");
9799
98100 return withFakeAcpAgent(
99101 {
@@ -123,7 +125,7 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 23 unmodified lines
123125 expect(generated.subject).toBe("Add generated commit message");
124126 expect(generated.body).toBe("- verify cursor acp model config path");
125127
126− const requests = readFileSync(requestLogPath, "utf8")
128+ const requests = NodeFS.readFileSync(requestLogPath, "utf8")
127129 .trim()
128130 .split("\n")
129131 .filter((line) => line.length > 0)
@@ -181,7 +183,7 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 51 unmodified lines
181183 ]),
182184 );
183185
184− rmSync(requestLogDir, { recursive: true, force: true });
186+ NodeFS.rmSync(requestLogDir, { recursive: true, force: true });
185187 }),
186188 );
187189 });
@@ -235,8 +237,10 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 47 unmodified lines
235237 );
236238
237239 it.effect("closes the ACP child process after text generation completes", () => {
238− const exitLogDir = mkdtempSync(path.join(os.tmpdir(), "t3code-cursor-text-exit-log-"));
239− const exitLogPath = path.join(exitLogDir, "exit.log");
240+ const exitLogDir = NodeFS.mkdtempSync(
241+ NodePath.join(NodeOS.tmpdir(), "t3code-cursor-text-exit-log-"),
242+ );
243+ const exitLogPath = NodePath.join(exitLogDir, "exit.log");
240244
241245 return withFakeAcpAgent(
242246 {
@@ -265,7 +269,7 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 22 unmodified lines
265269 const exitLog = yield* waitForFileContent(exitLogPath);
266270 expect(exitLog).toContain("exit:0");
267271
268− rmSync(exitLogDir, { recursive: true, force: true });
272+ NodeFS.rmSync(exitLogDir, { recursive: true, force: true });
269273 }),
270274 );
271275 });
apps/server/src/textGeneration/GrokTextGeneration.test.ts+18−16
@@ -1,8 +1,8 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import * as path from "node:path";
3−import * as os from "node:os";
4−import { fileURLToPath } from "node:url";
5−import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2+import * as NodePath from "node:path";
3+import * as NodeOS from "node:os";
4+import * as NodeURL from "node:url";
5+import * as NodeFS from "node:fs";
66
77 import * as NodeServices from "@effect/platform-node/NodeServices";
88 import { it } from "@effect/vitest";
@@ -18,8 +18,8 @@ import * as TextGeneration from "./TextGeneration.ts"; · 9 unmodified lines
1818 import { makeGrokTextGeneration } from "./GrokTextGeneration.ts";
1919 const decodeGrokSettings = Schema.decodeSync(GrokSettings);
2020
21−const __dirname = path.dirname(fileURLToPath(import.meta.url));
22−const mockAgentPath = path.join(__dirname, "../../scripts/acp-mock-agent.ts");
21+const __dirname = NodePath.dirname(NodeURL.fileURLToPath(import.meta.url));
22+const mockAgentPath = NodePath.join(__dirname, "../../scripts/acp-mock-agent.ts");
2323
2424 function shellSingleQuote(value: string): string {
2525 return `'${value.replaceAll("'", `'"'"'`)}'`;
@@ -30,10 +30,10 @@ const GrokTextGenerationTestLayer = ServerConfig.ServerConfig.layerTest(process. · 4 unmodified lines
3030 }).pipe(Layer.provideMerge(NodeServices.layer));
3131
3232 function makeAcpGrokWrapper(dir: string, env: Record<string, string>): string {
33− const binDir = path.join(dir, "bin");
34− const grokPath = path.join(binDir, "grok");
35− mkdirSync(binDir, { recursive: true });
36− writeFileSync(
33+ const binDir = NodePath.join(dir, "bin");
34+ const grokPath = NodePath.join(binDir, "grok");
35+ NodeFS.mkdirSync(binDir, { recursive: true });
36+ NodeFS.writeFileSync(
3737 grokPath,
3838 [
3939 "#!/bin/sh",
@@ -47,7 +47,7 @@ function makeAcpGrokWrapper(dir: string, env: Record<string, string>): string { · 7 unmodified lines
4747 ].join("\n"),
4848 "utf8",
4949 );
50− chmodSync(grokPath, 0o755);
50+ NodeFS.chmodSync(grokPath, 0o755);
5151 return grokPath;
5252 }
5353
@@ -56,10 +56,10 @@ function withFakeAcpGrok<A, E, R>( · 2 unmodified lines
5656 effectFn: (textGeneration: TextGeneration.TextGeneration["Service"]) => Effect.Effect<A, E, R>,
5757 ) {
5858 return Effect.gen(function* () {
59− const tempDir = mkdtempSync(path.join(os.tmpdir(), "t3code-grok-text-acp-"));
59+ const tempDir = NodeFS.mkdtempSync(NodePath.join(NodeOS.tmpdir(), "t3code-grok-text-acp-"));
6060 yield* Effect.addFinalizer(() =>
6161 Effect.sync(() => {
62− rmSync(tempDir, { recursive: true, force: true });
62+ NodeFS.rmSync(tempDir, { recursive: true, force: true });
6363 }),
6464 );
6565 const binaryPath = makeAcpGrokWrapper(tempDir, env);
@@ -72,7 +72,7 @@ function withFakeAcpGrok<A, E, R>( · 6 unmodified lines
7272 function readJsonRpcRequests(
7373 filePath: string,
7474 ): ReadonlyArray<{ readonly method?: string; readonly params?: Record<string, unknown> }> {
75− return readFileSync(filePath, "utf8")
75+ return NodeFS.readFileSync(filePath, "utf8")
7676 .trim()
7777 .split("\n")
7878 .filter((line) => line.length > 0)
@@ -81,8 +81,10 @@ function readJsonRpcRequests( · 2 unmodified lines
8181
8282 it.layer(GrokTextGenerationTestLayer)("GrokTextGeneration", (it) => {
8383 it.effect("uses ACP with disabled tool capabilities and forwards the requested model id", () => {
84− const requestLogDir = mkdtempSync(path.join(os.tmpdir(), "t3code-grok-text-log-"));
85− const requestLogPath = path.join(requestLogDir, "requests.ndjson");
84+ const requestLogDir = NodeFS.mkdtempSync(
85+ NodePath.join(NodeOS.tmpdir(), "t3code-grok-text-log-"),
86+ );
87+ const requestLogPath = NodePath.join(requestLogDir, "requests.ndjson");
8688
8789 return withFakeAcpGrok(
8890 {
apps/server/src/vcs/GitVcsDriver.ts+5−2
@@ -1,4 +1,4 @@
1−import { randomUUID } from "node:crypto";
1+import * as NodeCrypto from "node:crypto";
22
33 import * as Context from "effect/Context";
44 import * as DateTime from "effect/DateTime";
@@ -651,7 +651,10 @@ export const makeVcsDriverShape = Effect.fn("makeGitVcsDriverShape")(function* ( · 646 unmodified lines
651651 captureCheckpoint: Effect.fn("GitVcsDriver.checkpoints.captureCheckpoint")(function* (input) {
652652 const operation = "GitVcsDriver.checkpoints.captureCheckpoint";
653653 const gitCommonDir = yield* resolveGitCommonDir(input.cwd);
654− const tempIndexPath = path.join(gitCommonDir, `t3-checkpoint-index-${randomUUID()}`);
654+ const tempIndexPath = path.join(
655+ gitCommonDir,
656+ `t3-checkpoint-index-${NodeCrypto.randomUUID()}`,
657+ );
655658 const commitEnv: NodeJS.ProcessEnv = {
656659 ...process.env,
657660 GIT_INDEX_FILE: tempIndexPath,
apps/server/src/workspace/WorkspaceEntries.test.ts+9−3
@@ -1,13 +1,14 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import fsPromises from "node:fs/promises";
2+import * as NodeFSP from "node:fs/promises";
33 import * as NodeServices from "@effect/platform-node/NodeServices";
44 import { FileFinder } from "@ff-labs/fff-node";
5−import { it, afterEach, describe, expect, vi } from "@effect/vitest";
5+import { it, afterEach, describe, expect } from "@effect/vitest";
66 import * as Effect from "effect/Effect";
77 import * as FileSystem from "effect/FileSystem";
88 import * as Layer from "effect/Layer";
99 import * as Path from "effect/Path";
1010 import * as PlatformError from "effect/PlatformError";
11+import { vi } from "vite-plus/test";
1112
1213 import * as ServerConfig from "../config.ts";
1314 import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
@@ -15,6 +16,11 @@ import * as VcsProcess from "../vcs/VcsProcess.ts"; · 1 unmodified line
1516 import * as WorkspaceEntries from "./WorkspaceEntries.ts";
1617 import * as WorkspacePaths from "./WorkspacePaths.ts";
1718
19+vi.mock("node:fs/promises", async (importOriginal) => {
20+ const actual = await importOriginal<typeof import("node:fs/promises")>();
21+ return { ...actual, readdir: vi.fn(actual.readdir) };
22+});
23+
1824 const TestLayer = Layer.empty.pipe(
1925 Layer.provideMerge(WorkspaceEntries.layer.pipe(Layer.provide(WorkspacePaths.layer))),
2026 Layer.provideMerge(WorkspacePaths.layer),
@@ -376,7 +382,7 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceEntries", (it) => { · 355 unmodified lines
376382 const cwd = yield* makeTempDir({ prefix: "t3code-workspace-browse-eacces-" });
377383
378384 const denied = Object.assign(new Error("EACCES: permission denied"), { code: "EACCES" });
379− vi.spyOn(fsPromises, "readdir").mockRejectedValueOnce(denied);
385+ vi.mocked(NodeFSP.readdir).mockRejectedValueOnce(denied);
380386
381387 const result = yield* workspaceEntries.browse({
382388 partialPath: yield* appendSeparator(cwd),
apps/server/src/workspace/WorkspaceEntries.ts+5−5
@@ -1,6 +1,6 @@
11 // @effect-diagnostics nodeBuiltinImport:off
2−import { readdir } from "node:fs/promises";
3−import { homedir } from "node:os";
2+import * as NodeFSP from "node:fs/promises";
3+import * as NodeOS from "node:os";
44
55 import * as Context from "effect/Context";
66 import * as Effect from "effect/Effect";
@@ -98,10 +98,10 @@ export class WorkspaceEntries extends Context.Service< · 91 unmodified lines
9898
9999 function expandHomePath(input: string, path: Path.Path): string {
100100 if (input === "~") {
101− return homedir();
101+ return NodeOS.homedir();
102102 }
103103 if (input.startsWith("~/") || input.startsWith("~\\")) {
104− return path.join(homedir(), input.slice(2));
104+ return path.join(NodeOS.homedir(), input.slice(2));
105105 }
106106 return input;
107107 }
@@ -176,7 +176,7 @@ export const make = Effect.gen(function* () { · 68 unmodified lines
176176 const prefix = endsWithSeparator ? "" : path.basename(resolvedInputPath);
177177
178178 const dirents = yield* Effect.tryPromise({
179− try: () => readdir(parentPath, { withFileTypes: true }),
179+ try: () => NodeFSP.readdir(parentPath, { withFileTypes: true }),
180180 catch: (cause) =>
181181 new WorkspaceEntriesReadDirectoryError({
182182 cwd: input.cwd,
apps/server/src/workspace/WorkspaceFileSystem.ts+4−4
@@ -7,7 +7,7 @@ · 6 unmodified lines
77 *
88 * @module WorkspaceFileSystem
99 */
10−import { open, realpath } from "node:fs/promises";
10+import * as NodeFSP from "node:fs/promises";
1111
1212 import type {
1313 ProjectReadFileInput,
@@ -89,8 +89,8 @@ export const make = Effect.gen(function* () { · 75 unmodified lines
8989 return yield* Effect.tryPromise({
9090 try: async () => {
9191 const [realWorkspaceRoot, realTargetPath] = await Promise.all([
92− realpath(input.cwd),
93− realpath(target.absolutePath),
92+ NodeFSP.realpath(input.cwd),
93+ NodeFSP.realpath(target.absolutePath),
9494 ]);
9595 const relativeRealPath = path.relative(realWorkspaceRoot, realTargetPath);
9696 if (
@@ -101,7 +101,7 @@ export const make = Effect.gen(function* () { · 4 unmodified lines
101101 throw new Error("Workspace file path resolves outside the project root.");
102102 }
103103
104− const handle = await open(realTargetPath, "r");
104+ const handle = await NodeFSP.open(realTargetPath, "r");
105105 try {
106106 const stat = await handle.stat();
107107 if (!stat.isFile()) {
apps/server/src/workspace/WorkspacePaths.ts+3−3
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 *
77 * @module WorkspacePaths
88 */
9−import { homedir } from "node:os";
9+import * as NodeOS from "node:os";
1010
1111 import * as Context from "effect/Context";
1212 import * as Effect from "effect/Effect";
@@ -105,10 +105,10 @@ function toPosixRelativePath(input: string): string { · 92 unmodified lines
105105
106106 function expandHomePath(input: string, path: Path.Path): string {
107107 if (input === "~") {
108− return homedir();
108+ return NodeOS.homedir();
109109 }
110110 if (input.startsWith("~/") || input.startsWith("~\\")) {
111− return path.join(homedir(), input.slice(2));
111+ return path.join(NodeOS.homedir(), input.slice(2));
112112 }
113113 return input;
114114 }