Showing the changes to apps/server/src (45 of 71 files). Show all
Unified · Split
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // @effect-diagnostics nodeBuiltinImport:off |
| 2 | −import NodePath from "node:path"; | |
| 2 | +import * as NodePath from "node:path"; | |
| 3 | 3 | |
| 4 | 4 | export function normalizeAttachmentRelativePath(rawRelativePath: string): string | null { |
| 5 | 5 | const normalized = NodePath.normalize(rawRelativePath).replace(/^[/\\]+/, ""); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import { describe, expect, it } from "vite-plus/test"; |
| 7 | 7 | |
| @@ -45,11 +45,13 @@ describe("attachmentStore", () => { · 37 unmodified lines | ||
| 45 | 45 | }); |
| 46 | 46 | |
| 47 | 47 | 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 | + ); | |
| 49 | 51 | try { |
| 50 | 52 | 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")); | |
| 53 | 55 | |
| 54 | 56 | const resolved = resolveAttachmentPathById({ |
| 55 | 57 | attachmentsDir, |
| @@ -57,12 +59,14 @@ describe("attachmentStore", () => { · 1 unmodified line | ||
| 57 | 59 | }); |
| 58 | 60 | expect(resolved).toBe(pngPath); |
| 59 | 61 | } finally { |
| 60 | − fs.rmSync(attachmentsDir, { recursive: true, force: true }); | |
| 62 | + NodeFS.rmSync(attachmentsDir, { recursive: true, force: true }); | |
| 61 | 63 | } |
| 62 | 64 | }); |
| 63 | 65 | |
| 64 | 66 | 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 | + ); | |
| 66 | 70 | try { |
| 67 | 71 | const resolved = resolveAttachmentPathById({ |
| 68 | 72 | attachmentsDir, |
| @@ -70,7 +74,7 @@ describe("attachmentStore", () => { · 1 unmodified line | ||
| 70 | 74 | }); |
| 71 | 75 | expect(resolved).toBeNull(); |
| 72 | 76 | } finally { |
| 73 | − fs.rmSync(attachmentsDir, { recursive: true, force: true }); | |
| 77 | + NodeFS.rmSync(attachmentsDir, { recursive: true, force: true }); | |
| 74 | 78 | } |
| 75 | 79 | }); |
| 76 | 80 | }); |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // @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"; | |
| 4 | 4 | |
| 5 | 5 | import type { ChatAttachment } from "@t3tools/contracts"; |
| 6 | 6 | |
| @@ -39,7 +39,7 @@ export function createAttachmentId(threadId: string): string | null { · 32 unmodified lines | ||
| 39 | 39 | if (!threadSegment) { |
| 40 | 40 | return null; |
| 41 | 41 | } |
| 42 | − return `${threadSegment}-${randomUUID()}`; | |
| 42 | + return `${threadSegment}-${NodeCrypto.randomUUID()}`; | |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | 45 | export function parseThreadSegmentFromAttachmentId(attachmentId: string): string | null { |
| @@ -89,7 +89,7 @@ export function resolveAttachmentPathById(input: { · 43 unmodified lines | ||
| 89 | 89 | attachmentsDir: input.attachmentsDir, |
| 90 | 90 | relativePath: `${normalizedId}${extension}`, |
| 91 | 91 | }); |
| 92 | − if (maybePath && existsSync(maybePath)) { | |
| 92 | + if (maybePath && NodeFS.existsSync(maybePath)) { | |
| 93 | 93 | return maybePath; |
| 94 | 94 | } |
| 95 | 95 | } |
| @@ -4,7 +4,7 @@ import type { · 3 unmodified lines | ||
| 4 | 4 | AuthClientPresentationMetadata, |
| 5 | 5 | } from "@t3tools/contracts"; |
| 6 | 6 | import type * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"; |
| 7 | −import * as Crypto from "node:crypto"; | |
| 7 | +import * as NodeCrypto from "node:crypto"; | |
| 8 | 8 | import * as Encoding from "effect/Encoding"; |
| 9 | 9 | import * as Result from "effect/Result"; |
| 10 | 10 | |
| @@ -32,7 +32,7 @@ export function base64UrlDecodeUtf8(input: string): string { · 21 unmodified lines | ||
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | 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"); | |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | 38 | export function timingSafeEqualBase64Url(left: string, right: string): boolean { |
| @@ -41,7 +41,7 @@ export function timingSafeEqualBase64Url(left: string, right: string): boolean { · 2 unmodified lines | ||
| 41 | 41 | if (leftBuffer.length !== rightBuffer.length) { |
| 42 | 42 | return false; |
| 43 | 43 | } |
| 44 | − return Crypto.timingSafeEqual(leftBuffer, rightBuffer); | |
| 44 | + return NodeCrypto.timingSafeEqual(leftBuffer, rightBuffer); | |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | function normalizeNonEmptyString(value: string | null | undefined): string | undefined { |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer"; |
| 8 | 8 | 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 | ||
| 124 | 124 | ), |
| 125 | 125 | Layer.provideMerge(makeProjectPersistenceLayer(config)), |
| 126 | 126 | Layer.provideMerge( |
| 127 | − NodeHttpServer.layer(createServer, { | |
| 127 | + NodeHttpServer.layer(NodeHttp.createServer, { | |
| 128 | 128 | host: "127.0.0.1", |
| 129 | 129 | port: 0, |
| 130 | 130 | }), |
| @@ -197,7 +197,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 66 unmodified lines | ||
| 197 | 197 | |
| 198 | 198 | it.effect("reports fresh headless connect state without requiring local configuration", () => |
| 199 | 199 | 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 | + ); | |
| 201 | 203 | const { output } = yield* captureStdout( |
| 202 | 204 | runConnectCli(["connect", "status", "--base-dir", baseDir, "--json"]), |
| 203 | 205 | ); |
| @@ -220,7 +222,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 16 unmodified lines | ||
| 220 | 222 | |
| 221 | 223 | it.effect("reports actionable human-readable headless connect state", () => |
| 222 | 224 | 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 | + ); | |
| 224 | 228 | const { output } = yield* captureStdout( |
| 225 | 229 | runConnectCli(["connect", "status", "--base-dir", baseDir]), |
| 226 | 230 | ); |
| @@ -234,11 +238,13 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 7 unmodified lines | ||
| 234 | 238 | |
| 235 | 239 | it.effect("logs in to headless connect without enabling access", () => |
| 236 | 240 | 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 | + ); | |
| 238 | 244 | 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"), | |
| 242 | 248 | // @effect-diagnostics-next-line preferSchemaOverJson:off - Test fixture matches the persisted CLI token representation. |
| 243 | 249 | JSON.stringify({ |
| 244 | 250 | accessToken: "access-token", |
| @@ -267,7 +273,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 22 unmodified lines | ||
| 267 | 273 | |
| 268 | 274 | it.effect("disables headless connect without a running server", () => |
| 269 | 275 | 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 | + ); | |
| 271 | 279 | const { output } = yield* captureStdout( |
| 272 | 280 | runConnectCli(["connect", "unlink", "--base-dir", baseDir]), |
| 273 | 281 | ); |
| @@ -278,24 +286,28 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 4 unmodified lines | ||
| 278 | 286 | |
| 279 | 287 | it.effect("logs out of headless connect and removes the stored CLI authorization", () => |
| 280 | 288 | 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 | + ); | |
| 282 | 292 | 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"); | |
| 286 | 296 | |
| 287 | 297 | const { output } = yield* captureStdout( |
| 288 | 298 | runConnectCli(["connect", "logout", "--base-dir", baseDir]), |
| 289 | 299 | ); |
| 290 | 300 | |
| 291 | 301 | assert.equal(output, "Signed out of T3 Connect locally."); |
| 292 | − assert.isFalse(existsSync(tokenPath)); | |
| 302 | + assert.isFalse(NodeFS.existsSync(tokenPath)); | |
| 293 | 303 | }), |
| 294 | 304 | ); |
| 295 | 305 | |
| 296 | 306 | it.effect("executes auth pairing subcommands and redacts secrets from list output", () => |
| 297 | 307 | 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 | + ); | |
| 299 | 311 | |
| 300 | 312 | const createdOutput = yield* captureStdout( |
| 301 | 313 | runCli(["auth", "pairing", "create", "--base-dir", baseDir, "--json"]), |
| @@ -325,7 +337,9 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 23 unmodified lines | ||
| 325 | 337 | |
| 326 | 338 | it.effect("executes auth session subcommands and redacts secrets from list output", () => |
| 327 | 339 | 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 | + ); | |
| 329 | 343 | |
| 330 | 344 | const issuedOutput = yield* captureStdout( |
| 331 | 345 | runCli(["auth", "session", "issue", "--base-dir", baseDir, "--json"]), |
| @@ -400,8 +414,12 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 68 unmodified lines | ||
| 400 | 414 | |
| 401 | 415 | it.effect("adds, renames, and removes projects offline through the orchestration engine", () => |
| 402 | 416 | 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 | + ); | |
| 405 | 423 | |
| 406 | 424 | yield* runCliWithRuntime([ |
| 407 | 425 | "project", |
| @@ -444,8 +462,12 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 36 unmodified lines | ||
| 444 | 462 | |
| 445 | 463 | it.effect("routes project commands through a running server when runtime state is present", () => |
| 446 | 464 | 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 | + ); | |
| 449 | 471 | |
| 450 | 472 | yield* withLiveProjectCliServer(baseDir, () => |
| 451 | 473 | Effect.gen(function* () { |
| @@ -472,8 +494,8 @@ it.layer(NodeServices.layer)("bin cli parsing", (it) => { · 20 unmodified lines | ||
| 472 | 494 | |
| 473 | 495 | it.effect("rejects dev-url on project commands", () => |
| 474 | 496 | 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-"), | |
| 477 | 499 | ); |
| 478 | 500 | const error = yield* runCliWithRuntime([ |
| 479 | 501 | "project", |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 6 | 6 | import { it } from "@effect/vitest"; |
| 7 | 7 | import * as FileSystem from "effect/FileSystem"; |
| @@ -53,8 +53,8 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 45 unmodified lines | ||
| 53 | 53 | ); |
| 54 | 54 | |
| 55 | 55 | 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)), | |
| 58 | 58 | ); |
| 59 | 59 | |
| 60 | 60 | const payload = yield* readBootstrapEnvelope(TestEnvelopeSchema, fd, { timeoutMs: 100 }); |
| @@ -78,7 +78,7 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 17 unmodified lines | ||
| 78 | 78 | // so the stream owns the fd lifecycle and closes it asynchronously on end. |
| 79 | 79 | // Attempting to also close it synchronously in a finalizer races with the |
| 80 | 80 | // stream's async close and produces an uncaught EBADF. |
| 81 | − const fd = NFS.openSync(filePath, "r"); | |
| 81 | + const fd = NodeFS.openSync(filePath, "r"); | |
| 82 | 82 | |
| 83 | 83 | openSyncInterceptor.failPath = `/proc/self/fd/${fd}`; |
| 84 | 84 | try { |
| @@ -96,8 +96,8 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 11 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | it.effect("returns none when the fd is unavailable", () => |
| 98 | 98 | 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); | |
| 101 | 101 | |
| 102 | 102 | const payload = yield* readBootstrapEnvelope(TestEnvelopeSchema, fd, { timeoutMs: 100 }); |
| 103 | 103 | assertNone(payload); |
| @@ -108,13 +108,13 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 4 unmodified lines | ||
| 108 | 108 | Effect.gen(function* () { |
| 109 | 109 | const fs = yield* FileSystem.FileSystem; |
| 110 | 110 | const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-bootstrap-" }); |
| 111 | − const fifoPath = path.join(tempDir, "bootstrap.pipe"); | |
| 111 | + const fifoPath = NodePath.join(tempDir, "bootstrap.pipe"); | |
| 112 | 112 | |
| 113 | − yield* Effect.sync(() => execFileSync("mkfifo", [fifoPath])); | |
| 113 | + yield* Effect.sync(() => NodeChildProcess.execFileSync("mkfifo", [fifoPath])); | |
| 114 | 114 | |
| 115 | 115 | const _writer = yield* Effect.acquireRelease( |
| 116 | 116 | 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], { | |
| 118 | 118 | stdio: ["ignore", "ignore", "ignore"], |
| 119 | 119 | }), |
| 120 | 120 | ), |
| @@ -125,8 +125,8 @@ it.layer(NodeServices.layer)("readBootstrapEnvelope", (it) => { · 4 unmodified lines | ||
| 125 | 125 | ); |
| 126 | 126 | |
| 127 | 127 | 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)), | |
| 130 | 130 | ); |
| 131 | 131 | |
| 132 | 132 | const fiber = yield* readBootstrapEnvelope(TestEnvelopeSchema, fd, { |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as Data from "effect/Data"; |
| 8 | 8 | import * as Effect from "effect/Effect"; |
| @@ -33,7 +33,7 @@ export const readBootstrapEnvelope = Effect.fn("readBootstrapEnvelope")(function · 24 unmodified lines | ||
| 33 | 33 | const timeoutMs = options?.timeoutMs ?? 1000; |
| 34 | 34 | |
| 35 | 35 | return yield* Effect.callback<Option.Option<A>, BootstrapError>((resume) => { |
| 36 | − const input = readline.createInterface({ | |
| 36 | + const input = NodeReadline.createInterface({ | |
| 37 | 37 | input: stream, |
| 38 | 38 | crlfDelay: Infinity, |
| 39 | 39 | }); |
| @@ -96,7 +96,7 @@ const isUnavailableBootstrapFdError = Predicate.compose( · 56 unmodified lines | ||
| 96 | 96 | |
| 97 | 97 | const isFdReady = (fd: number) => |
| 98 | 98 | Effect.try({ |
| 99 | − try: () => NFS.fstatSync(fd), | |
| 99 | + try: () => NodeFS.fstatSync(fd), | |
| 100 | 100 | catch: (error) => |
| 101 | 101 | new BootstrapError({ |
| 102 | 102 | message: "Failed to stat bootstrap fd.", |
| @@ -113,7 +113,7 @@ const isFdReady = (fd: number) => · 10 unmodified lines | ||
| 113 | 113 | const makeBootstrapInputStream = (fd: number) => |
| 114 | 114 | Effect.gen(function* () { |
| 115 | 115 | const platform = yield* HostProcessPlatform; |
| 116 | − return yield* Effect.try<Readable, BootstrapError>({ | |
| 116 | + return yield* Effect.try<NodeStream.Readable, BootstrapError>({ | |
| 117 | 117 | try: () => { |
| 118 | 118 | const fdPath = resolveFdPath(fd, platform); |
| 119 | 119 | if (fdPath === undefined) { |
| @@ -122,8 +122,8 @@ const makeBootstrapInputStream = (fd: number) => · 2 unmodified lines | ||
| 122 | 122 | |
| 123 | 123 | let streamFd: number | undefined; |
| 124 | 124 | try { |
| 125 | − streamFd = NFS.openSync(fdPath, "r"); | |
| 126 | − return NFS.createReadStream("", { | |
| 125 | + streamFd = NodeFS.openSync(fdPath, "r"); | |
| 126 | + return NodeFS.createReadStream("", { | |
| 127 | 127 | fd: streamFd, |
| 128 | 128 | encoding: "utf8", |
| 129 | 129 | autoClose: true, |
| @@ -131,7 +131,7 @@ const makeBootstrapInputStream = (fd: number) => · 1 unmodified line | ||
| 131 | 131 | } catch (error) { |
| 132 | 132 | if (isBootstrapFdPathDuplicationError(error)) { |
| 133 | 133 | if (streamFd !== undefined) { |
| 134 | − NFS.closeSync(streamFd); | |
| 134 | + NodeFS.closeSync(streamFd); | |
| 135 | 135 | } |
| 136 | 136 | return makeDirectBootstrapStream(fd); |
| 137 | 137 | } |
| @@ -146,15 +146,15 @@ const makeBootstrapInputStream = (fd: number) => · 8 unmodified lines | ||
| 146 | 146 | }); |
| 147 | 147 | }); |
| 148 | 148 | |
| 149 | −const makeDirectBootstrapStream = (fd: number): Readable => { | |
| 149 | +const makeDirectBootstrapStream = (fd: number): NodeStream.Readable => { | |
| 150 | 150 | try { |
| 151 | − return NFS.createReadStream("", { | |
| 151 | + return NodeFS.createReadStream("", { | |
| 152 | 152 | fd, |
| 153 | 153 | encoding: "utf8", |
| 154 | 154 | autoClose: true, |
| 155 | 155 | }); |
| 156 | 156 | } catch { |
| 157 | − const stream = new Net.Socket({ | |
| 157 | + const stream = new NodeNet.Socket({ | |
| 158 | 158 | fd, |
| 159 | 159 | readable: true, |
| 160 | 160 | writable: false, |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // @effect-diagnostics nodeBuiltinImport:off |
| 2 | −import path from "node:path"; | |
| 2 | +import * as NodePath from "node:path"; | |
| 3 | 3 | |
| 4 | 4 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 5 | 5 | import { it } from "@effect/vitest"; |
| @@ -80,7 +80,7 @@ function initRepoWithCommit( · 74 unmodified lines | ||
| 80 | 80 | yield* git(cwd, ["init"]); |
| 81 | 81 | yield* git(cwd, ["config", "user.email", "test@test.com"]); |
| 82 | 82 | 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"); | |
| 84 | 84 | yield* git(cwd, ["add", "."]); |
| 85 | 85 | yield* git(cwd, ["commit", "-m", "initial commit"]); |
| 86 | 86 | }); |
| @@ -107,7 +107,7 @@ it.layer(TestLayer)("CheckpointStore.layer", (it) => { · 20 unmodified lines | ||
| 107 | 107 | cwd: tmp, |
| 108 | 108 | checkpointRef: fromCheckpointRef, |
| 109 | 109 | }); |
| 110 | − yield* writeTextFile(path.join(tmp, "README.md"), buildLargeText()); | |
| 110 | + yield* writeTextFile(NodePath.join(tmp, "README.md"), buildLargeText()); | |
| 111 | 111 | yield* checkpointStore.captureCheckpoint({ |
| 112 | 112 | cwd: tmp, |
| 113 | 113 | checkpointRef: toCheckpointRef, |
| @@ -135,7 +135,7 @@ it.layer(TestLayer)("CheckpointStore.layer", (it) => { · 21 unmodified lines | ||
| 135 | 135 | const fromCheckpointRef = checkpointRefForThreadTurn(threadId, 0); |
| 136 | 136 | const toCheckpointRef = checkpointRefForThreadTurn(threadId, 1); |
| 137 | 137 | |
| 138 | − const componentPath = path.join(tmp, "Component.tsx"); | |
| 138 | + const componentPath = NodePath.join(tmp, "Component.tsx"); | |
| 139 | 139 | yield* writeTextFile( |
| 140 | 140 | componentPath, |
| 141 | 141 | [ |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // @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"; | |
| 3 | 3 | |
| 4 | 4 | import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer"; |
| 5 | 5 | import * as Clock from "effect/Clock"; |
| @@ -206,7 +206,7 @@ export const make = Effect.gen(function* () { · 200 unmodified lines | ||
| 206 | 206 | disableLogger: true, |
| 207 | 207 | }).pipe( |
| 208 | 208 | Layer.provide( |
| 209 | − NodeHttpServer.layer(createServer, { | |
| 209 | + NodeHttpServer.layer(NodeHttp.createServer, { | |
| 210 | 210 | host: "127.0.0.1", |
| 211 | 211 | port: 34338, |
| 212 | 212 | disablePreemptiveShutdown: true, |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import { createPublicKey } from "node:crypto"; | |
| 1 | +import * as NodeCrypto from "node:crypto"; | |
| 2 | 2 | import { |
| 3 | 3 | AuthRelayReadScope, |
| 4 | 4 | AuthRelayWriteScope, |
| @@ -152,7 +152,7 @@ function validateCloudMintPublicKey( · 147 unmodified lines | ||
| 152 | 152 | publicKey: string, |
| 153 | 153 | ): Effect.Effect<void, EnvironmentHttpBadRequestError> { |
| 154 | 154 | return Effect.try({ |
| 155 | − try: () => createPublicKey(publicKey.replace(/\\n/g, "\n")), | |
| 155 | + try: () => NodeCrypto.createPublicKey(publicKey.replace(/\\n/g, "\n")), | |
| 156 | 156 | catch: () => |
| 157 | 157 | new EnvironmentHttpBadRequestError({ |
| 158 | 158 | message: "Cloud mint public key must be a valid Ed25519 public key.", |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | // @effect-diagnostics nodeBuiltinImport:off |
| 2 | −import { dirname } from "node:path"; | |
| 2 | +import * as NodePath from "node:path"; | |
| 3 | 3 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 4 | 4 | import { expect, it } from "@effect/vitest"; |
| 5 | 5 | import * as Effect from "effect/Effect"; |
| @@ -76,7 +76,7 @@ it.layer(NodeServices.layer)("ServerEnvironmentLive", (it) => { · 70 unmodified lines | ||
| 76 | 76 | }); |
| 77 | 77 | const serverConfig = yield* makeServerConfig(baseDir); |
| 78 | 78 | const environmentIdPath = serverConfig.environmentIdPath; |
| 79 | − yield* fileSystem.makeDirectory(dirname(environmentIdPath), { recursive: true }); | |
| 79 | + yield* fileSystem.makeDirectory(NodePath.dirname(environmentIdPath), { recursive: true }); | |
| 80 | 80 | yield* fileSystem.writeFileString(environmentIdPath, "persisted-environment-id\n"); |
| 81 | 81 | const writeAttempts: string[] = []; |
| 82 | 82 | const failingFileSystemLayer = FileSystem.layerNoop({ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 7 | 7 | import { it } from "@effect/vitest"; |
| @@ -164,7 +164,7 @@ function normalizeFakePullRequestSummary(raw: unknown): GitHubCli.GitHubPullRequ · 156 unmodified lines | ||
| 164 | 164 | } |
| 165 | 165 | |
| 166 | 166 | function runGitSyncForFakeGh(cwd: string, args: readonly string[]): void { |
| 167 | − const result = spawnSync("git", args, { | |
| 167 | + const result = NodeChildProcess.spawnSync("git", args, { | |
| 168 | 168 | cwd, |
| 169 | 169 | encoding: "utf8", |
| 170 | 170 | }); |
| @@ -254,7 +254,7 @@ function initRepo( · 83 unmodified lines | ||
| 254 | 254 | yield* runGit(cwd, ["init", "--initial-branch=main"]); |
| 255 | 255 | yield* runGit(cwd, ["config", "user.email", "test@example.com"]); |
| 256 | 256 | 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"); | |
| 258 | 258 | yield* runGit(cwd, ["add", "README.md"]); |
| 259 | 259 | yield* runGit(cwd, ["commit", "-m", "Initial commit"]); |
| 260 | 260 | }); |
| @@ -459,7 +459,7 @@ function createGitHubCliWithFakeGh(scenario: FakeGhScenario = {}): { · 198 unmodified lines | ||
| 459 | 459 | try: () => { |
| 460 | 460 | const headBranch = scenario.pullRequest?.headRefName; |
| 461 | 461 | if (headBranch) { |
| 462 | − const existingBranch = spawnSync( | |
| 462 | + const existingBranch = NodeChildProcess.spawnSync( | |
| 463 | 463 | "git", |
| 464 | 464 | ["show-ref", "--verify", "--quiet", `refs/heads/${headBranch}`], |
| 465 | 465 | { |
| @@ -916,7 +916,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 450 unmodified lines | ||
| 916 | 916 | it.effect("status returns an explicit non-repo result for deleted directories", () => |
| 917 | 917 | Effect.gen(function* () { |
| 918 | 918 | 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"); | |
| 920 | 920 | yield* makeDirectory(cwd); |
| 921 | 921 | yield* removePath(cwd); |
| 922 | 922 | const { manager } = yield* makeManager(); |
| @@ -1026,7 +1026,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 103 unmodified lines | ||
| 1026 | 1026 | const forkDir = yield* createBareRemote(); |
| 1027 | 1027 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 1028 | 1028 | 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"); | |
| 1030 | 1030 | yield* runGit(repoDir, ["add", "fork-pr.txt"]); |
| 1031 | 1031 | yield* runGit(repoDir, ["commit", "-m", "Fork PR branch"]); |
| 1032 | 1032 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "statemachine"]); |
| @@ -1348,7 +1348,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 315 unmodified lines | ||
| 1348 | 1348 | Effect.gen(function* () { |
| 1349 | 1349 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 1350 | 1350 | 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"); | |
| 1352 | 1352 | |
| 1353 | 1353 | const { manager } = yield* makeManager(); |
| 1354 | 1354 | const result = yield* runStackedAction(manager, { |
| @@ -1383,7 +1383,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 28 unmodified lines | ||
| 1383 | 1383 | Effect.gen(function* () { |
| 1384 | 1384 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 1385 | 1385 | 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"); | |
| 1387 | 1387 | let generatedCount = 0; |
| 1388 | 1388 | |
| 1389 | 1389 | const { manager } = yield* makeManager({ |
| @@ -1426,8 +1426,8 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 36 unmodified lines | ||
| 1426 | 1426 | Effect.gen(function* () { |
| 1427 | 1427 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 1428 | 1428 | 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"); | |
| 1431 | 1431 | |
| 1432 | 1432 | const { manager } = yield* makeManager(); |
| 1433 | 1433 | const result = yield* runStackedAction(manager, { |
| @@ -1454,7 +1454,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 20 unmodified lines | ||
| 1454 | 1454 | const remoteDir = yield* createBareRemote(); |
| 1455 | 1455 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); |
| 1456 | 1456 | 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"); | |
| 1458 | 1458 | let generatedCount = 0; |
| 1459 | 1459 | |
| 1460 | 1460 | const { manager } = yield* makeManager({ |
| @@ -1514,7 +1514,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 53 unmodified lines | ||
| 1514 | 1514 | Effect.gen(function* () { |
| 1515 | 1515 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 1516 | 1516 | 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"); | |
| 1518 | 1518 | let generatedCount = 0; |
| 1519 | 1519 | |
| 1520 | 1520 | const { manager } = yield* makeManager({ |
| @@ -1597,7 +1597,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 76 unmodified lines | ||
| 1597 | 1597 | yield* runGit(repoDir, ["checkout", "-b", "feature/stacked-flow"]); |
| 1598 | 1598 | const remoteDir = yield* createBareRemote(); |
| 1599 | 1599 | 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"); | |
| 1601 | 1601 | |
| 1602 | 1602 | const { manager } = yield* makeManager(); |
| 1603 | 1603 | const result = yield* runStackedAction(manager, { |
| @@ -1626,7 +1626,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 22 unmodified lines | ||
| 1626 | 1626 | yield* runGit(repoDir, ["checkout", "-b", "feature/no-upstream-pr"]); |
| 1627 | 1627 | const remoteDir = yield* createBareRemote(); |
| 1628 | 1628 | 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"); | |
| 1630 | 1630 | |
| 1631 | 1631 | const { manager, ghCalls } = yield* makeManager({ |
| 1632 | 1632 | ghScenario: { |
| @@ -1697,7 +1697,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 64 unmodified lines | ||
| 1697 | 1697 | yield* runGit(repoDir, ["checkout", "-b", "feature/push-only"]); |
| 1698 | 1698 | const remoteDir = yield* createBareRemote(); |
| 1699 | 1699 | 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"); | |
| 1701 | 1701 | yield* runGit(repoDir, ["add", "push-only.txt"]); |
| 1702 | 1702 | yield* runGit(repoDir, ["commit", "-m", "Push only branch"]); |
| 1703 | 1703 | |
| @@ -1725,11 +1725,11 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 21 unmodified lines | ||
| 1725 | 1725 | yield* runGit(repoDir, ["checkout", "-b", "feature/push-dirty"]); |
| 1726 | 1726 | const remoteDir = yield* createBareRemote(); |
| 1727 | 1727 | 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"); | |
| 1729 | 1729 | yield* runGit(repoDir, ["add", "push-dirty.txt"]); |
| 1730 | 1730 | 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"); | |
| 1733 | 1733 | |
| 1734 | 1734 | const { manager } = yield* makeManager(); |
| 1735 | 1735 | const result = yield* runStackedAction(manager, { |
| @@ -1760,7 +1760,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 24 unmodified lines | ||
| 1760 | 1760 | yield* runGit(repoDir, ["checkout", "-b", "feature/create-pr-only"]); |
| 1761 | 1761 | const remoteDir = yield* createBareRemote(); |
| 1762 | 1762 | 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"); | |
| 1764 | 1764 | yield* runGit(repoDir, ["add", "create-pr-only.txt"]); |
| 1765 | 1765 | yield* runGit(repoDir, ["commit", "-m", "Create PR only branch"]); |
| 1766 | 1766 | |
| @@ -1805,7 +1805,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 38 unmodified lines | ||
| 1805 | 1805 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 1806 | 1806 | yield* initRepo(repoDir); |
| 1807 | 1807 | 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"); | |
| 1809 | 1809 | yield* runGit(repoDir, ["add", "provider-fallback.txt"]); |
| 1810 | 1810 | yield* runGit(repoDir, ["commit", "-m", "Provider fallback"]); |
| 1811 | 1811 | const remoteDir = yield* createBareRemote(); |
| @@ -1982,7 +1982,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 170 unmodified lines | ||
| 1982 | 1982 | yield* runGit(repoDir, ["checkout", "main"]); |
| 1983 | 1983 | yield* runGit(repoDir, ["branch", "-D", "effect-atom"]); |
| 1984 | 1984 | 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"); | |
| 1986 | 1986 | yield* runGit(repoDir, ["add", "changes.txt"]); |
| 1987 | 1987 | yield* runGit(repoDir, ["commit", "-m", "Feature commit"]); |
| 1988 | 1988 | |
| @@ -2200,7 +2200,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 211 unmodified lines | ||
| 2200 | 2200 | yield* runGit(repoDir, ["checkout", "-b", "feature-create-pr"]); |
| 2201 | 2201 | const remoteDir = yield* createBareRemote(); |
| 2202 | 2202 | 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"); | |
| 2204 | 2204 | yield* runGit(repoDir, ["add", "changes.txt"]); |
| 2205 | 2205 | yield* runGit(repoDir, ["commit", "-m", "Feature commit"]); |
| 2206 | 2206 | yield* runGit(repoDir, ["push", "-u", "origin", "feature-create-pr"]); |
| @@ -2252,7 +2252,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 45 unmodified lines | ||
| 2252 | 2252 | yield* runGit(peerDir, ["clone", remoteDir, "."]); |
| 2253 | 2253 | yield* runGit(peerDir, ["config", "user.email", "peer@example.com"]); |
| 2254 | 2254 | 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"); | |
| 2256 | 2256 | yield* runGit(peerDir, ["add", "remote.txt"]); |
| 2257 | 2257 | yield* runGit(peerDir, ["commit", "-m", "Remote base commit"]); |
| 2258 | 2258 | yield* runGit(peerDir, ["push", "origin", "main"]); |
| @@ -2265,7 +2265,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 6 unmodified lines | ||
| 2265 | 2265 | "feature/remote-base", |
| 2266 | 2266 | "origin/main", |
| 2267 | 2267 | ]); |
| 2268 | − fs.writeFileSync(path.join(repoDir, "feature.txt"), "feature\n"); | |
| 2268 | + NodeFS.writeFileSync(NodePath.join(repoDir, "feature.txt"), "feature\n"); | |
| 2269 | 2269 | yield* runGit(repoDir, ["add", "feature.txt"]); |
| 2270 | 2270 | yield* runGit(repoDir, ["commit", "-m", "Feature commit"]); |
| 2271 | 2271 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/remote-base"]); |
| @@ -2304,7 +2304,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 32 unmodified lines | ||
| 2304 | 2304 | yield* runGit(repoDir, ["checkout", "-b", "feature/no-fork-match"]); |
| 2305 | 2305 | const remoteDir = yield* createBareRemote(); |
| 2306 | 2306 | 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"); | |
| 2308 | 2308 | yield* runGit(repoDir, ["add", "changes.txt"]); |
| 2309 | 2309 | yield* runGit(repoDir, ["commit", "-m", "Feature commit"]); |
| 2310 | 2310 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/no-fork-match"]); |
| @@ -2376,7 +2376,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 65 unmodified lines | ||
| 2376 | 2376 | const forkDir = yield* createBareRemote(); |
| 2377 | 2377 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 2378 | 2378 | 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"); | |
| 2380 | 2380 | yield* runGit(repoDir, ["add", "changes.txt"]); |
| 2381 | 2381 | yield* runGit(repoDir, ["commit", "-m", "Feature commit"]); |
| 2382 | 2382 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "statemachine"]); |
| @@ -2556,7 +2556,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 173 unmodified lines | ||
| 2556 | 2556 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 2557 | 2557 | yield* initRepo(repoDir); |
| 2558 | 2558 | 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"); | |
| 2560 | 2560 | yield* runGit(repoDir, ["add", "local.txt"]); |
| 2561 | 2561 | yield* runGit(repoDir, ["commit", "-m", "Local PR branch"]); |
| 2562 | 2562 | |
| @@ -2597,7 +2597,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 34 unmodified lines | ||
| 2597 | 2597 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); |
| 2598 | 2598 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2599 | 2599 | 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"); | |
| 2601 | 2601 | yield* runGit(repoDir, ["add", "upstream.txt"]); |
| 2602 | 2602 | yield* runGit(repoDir, ["commit", "-m", "Local upstream PR branch"]); |
| 2603 | 2603 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-local-upstream"]); |
| @@ -2655,7 +2655,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 51 unmodified lines | ||
| 2655 | 2655 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); |
| 2656 | 2656 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2657 | 2657 | 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"); | |
| 2659 | 2659 | yield* runGit(repoDir, ["add", "no-head-repo.txt"]); |
| 2660 | 2660 | yield* runGit(repoDir, ["commit", "-m", "Local PR branch without repo metadata"]); |
| 2661 | 2661 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-local-no-head-repo"]); |
| @@ -2702,7 +2702,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 40 unmodified lines | ||
| 2702 | 2702 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); |
| 2703 | 2703 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2704 | 2704 | 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"); | |
| 2706 | 2706 | yield* runGit(repoDir, ["add", "worktree.txt"]); |
| 2707 | 2707 | yield* runGit(repoDir, ["commit", "-m", "PR worktree branch"]); |
| 2708 | 2708 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-worktree"]); |
| @@ -2730,7 +2730,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 21 unmodified lines | ||
| 2730 | 2730 | |
| 2731 | 2731 | expect(result.branch).toBe("feature/pr-worktree"); |
| 2732 | 2732 | 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); | |
| 2734 | 2734 | const worktreeBranch = (yield* runGit(result.worktreePath as string, [ |
| 2735 | 2735 | "branch", |
| 2736 | 2736 | "--show-current", |
| @@ -2747,7 +2747,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 10 unmodified lines | ||
| 2747 | 2747 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); |
| 2748 | 2748 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2749 | 2749 | 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"); | |
| 2751 | 2751 | yield* runGit(repoDir, ["add", "setup.txt"]); |
| 2752 | 2752 | yield* runGit(repoDir, ["commit", "-m", "PR worktree setup branch"]); |
| 2753 | 2753 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-worktree-setup"]); |
| @@ -2802,7 +2802,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 48 unmodified lines | ||
| 2802 | 2802 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2803 | 2803 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 2804 | 2804 | 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"); | |
| 2806 | 2806 | yield* runGit(repoDir, ["add", "fork.txt"]); |
| 2807 | 2807 | yield* runGit(repoDir, ["commit", "-m", "Fork PR branch"]); |
| 2808 | 2808 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "feature/pr-fork"]); |
| @@ -2864,7 +2864,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 55 unmodified lines | ||
| 2864 | 2864 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2865 | 2865 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 2866 | 2866 | 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"); | |
| 2868 | 2868 | yield* runGit(repoDir, ["add", "local-fork.txt"]); |
| 2869 | 2869 | yield* runGit(repoDir, ["commit", "-m", "Local fork PR branch"]); |
| 2870 | 2870 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "feature/pr-local-fork"]); |
| @@ -2917,7 +2917,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 46 unmodified lines | ||
| 2917 | 2917 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 2918 | 2918 | yield* runGit(repoDir, ["remote", "add", "binbandit-seed", forkDir]); |
| 2919 | 2919 | 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"); | |
| 2921 | 2921 | yield* runGit(repoDir, ["add", "derived-fork.txt"]); |
| 2922 | 2922 | yield* runGit(repoDir, ["commit", "-m", "Derived fork PR branch"]); |
| 2923 | 2923 | yield* runGit(repoDir, [ |
| @@ -2969,11 +2969,15 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 45 unmodified lines | ||
| 2969 | 2969 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 2970 | 2970 | yield* initRepo(repoDir); |
| 2971 | 2971 | 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"); | |
| 2973 | 2973 | yield* runGit(repoDir, ["add", "existing.txt"]); |
| 2974 | 2974 | yield* runGit(repoDir, ["commit", "-m", "Existing worktree branch"]); |
| 2975 | 2975 | 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 | + ); | |
| 2977 | 2981 | yield* runGit(repoDir, ["worktree", "add", worktreePath, "feature/pr-existing-worktree"]); |
| 2978 | 2982 | |
| 2979 | 2983 | const setupCalls: ProjectSetupScriptRunner.ProjectSetupScriptRunnerInput[] = []; |
| @@ -3004,8 +3008,8 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 24 unmodified lines | ||
| 3004 | 3008 | threadId: asThreadId("thread-pr-existing-worktree"), |
| 3005 | 3009 | }); |
| 3006 | 3010 | |
| 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), | |
| 3009 | 3013 | ); |
| 3010 | 3014 | expect(result.branch).toBe("feature/pr-existing-worktree"); |
| 3011 | 3015 | expect(setupCalls).toHaveLength(0); |
| @@ -3024,7 +3028,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 12 unmodified lines | ||
| 3024 | 3028 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 3025 | 3029 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 3026 | 3030 | 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"); | |
| 3028 | 3032 | yield* runGit(repoDir, ["add", "fork-main.txt"]); |
| 3029 | 3033 | yield* runGit(repoDir, ["commit", "-m", "Fork main branch"]); |
| 3030 | 3034 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "fork-main-source:main"]); |
| @@ -3084,7 +3088,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 53 unmodified lines | ||
| 3084 | 3088 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 3085 | 3089 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 3086 | 3090 | 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"); | |
| 3088 | 3092 | yield* runGit(repoDir, ["add", "fork-main-second.txt"]); |
| 3089 | 3093 | yield* runGit(repoDir, ["commit", "-m", "Fork main second branch"]); |
| 3090 | 3094 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "fork-main-source:main"]); |
| @@ -3142,12 +3146,16 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 51 unmodified lines | ||
| 3142 | 3146 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 3143 | 3147 | yield* runGit(repoDir, ["remote", "add", "fork-seed", forkDir]); |
| 3144 | 3148 | 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"); | |
| 3146 | 3150 | yield* runGit(repoDir, ["add", "reused-fork.txt"]); |
| 3147 | 3151 | yield* runGit(repoDir, ["commit", "-m", "Reused fork PR branch"]); |
| 3148 | 3152 | yield* runGit(repoDir, ["push", "-u", "fork-seed", "feature/pr-reused-fork"]); |
| 3149 | 3153 | 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 | + ); | |
| 3151 | 3159 | yield* runGit(repoDir, ["worktree", "add", worktreePath, "feature/pr-reused-fork"]); |
| 3152 | 3160 | yield* runGit(worktreePath, ["branch", "--unset-upstream"], true); |
| 3153 | 3161 | |
| @@ -3179,8 +3187,8 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 25 unmodified lines | ||
| 3179 | 3187 | mode: "worktree", |
| 3180 | 3188 | }); |
| 3181 | 3189 | |
| 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), | |
| 3184 | 3192 | ); |
| 3185 | 3193 | expect( |
| 3186 | 3194 | (yield* runGit(worktreePath, ["rev-parse", "--abbrev-ref", "@{upstream}"])).stdout.trim(), |
| @@ -3196,7 +3204,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 9 unmodified lines | ||
| 3196 | 3204 | yield* runGit(repoDir, ["remote", "add", "origin", remoteDir]); |
| 3197 | 3205 | yield* runGit(repoDir, ["push", "-u", "origin", "main"]); |
| 3198 | 3206 | 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"); | |
| 3200 | 3208 | yield* runGit(repoDir, ["add", "setup-failure.txt"]); |
| 3201 | 3209 | yield* runGit(repoDir, ["commit", "-m", "PR setup failure branch"]); |
| 3202 | 3210 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-setup-failure"]); |
| @@ -3236,7 +3244,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 33 unmodified lines | ||
| 3236 | 3244 | |
| 3237 | 3245 | expect(result.branch).toBe("feature/pr-setup-failure"); |
| 3238 | 3246 | 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); | |
| 3240 | 3248 | }), |
| 3241 | 3249 | ); |
| 3242 | 3250 | |
| @@ -3276,9 +3284,9 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 33 unmodified lines | ||
| 3276 | 3284 | Effect.gen(function* () { |
| 3277 | 3285 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 3278 | 3286 | 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"), | |
| 3282 | 3290 | '#!/bin/sh\necho "hook: start" >&2\nsleep 0.05\necho "hook: end" >&2\n', |
| 3283 | 3291 | { mode: 0o755 }, |
| 3284 | 3292 | ); |
| @@ -3339,9 +3347,9 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 54 unmodified lines | ||
| 3339 | 3347 | Effect.gen(function* () { |
| 3340 | 3348 | const repoDir = yield* makeTempDir("t3code-git-manager-"); |
| 3341 | 3349 | 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"), | |
| 3345 | 3353 | '#!/bin/sh\necho "hook: fail" >&2\nexit 1\n', |
| 3346 | 3354 | { mode: 0o755 }, |
| 3347 | 3355 | ); |
| @@ -3392,7 +3400,7 @@ it.layer(GitManagerTestLayer)("GitManager", (it) => { · 44 unmodified lines | ||
| 3392 | 3400 | yield* runGit(repoDir, ["checkout", "-b", "feature/pr-only-follow-up"]); |
| 3393 | 3401 | const remoteDir = yield* createBareRemote(); |
| 3394 | 3402 | 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"); | |
| 3396 | 3404 | yield* runGit(repoDir, ["add", "pr-only.txt"]); |
| 3397 | 3405 | yield* runGit(repoDir, ["commit", "-m", "PR only branch"]); |
| 3398 | 3406 | yield* runGit(repoDir, ["push", "-u", "origin", "feature/pr-only-follow-up"]); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 4 | 4 | |
| 5 | 5 | export function isGitRepository(cwd: string): boolean { |
| 6 | − return existsSync(join(cwd, ".git")); | |
| 6 | + return NodeFS.existsSync(NodePath.join(cwd, ".git")); | |
| 7 | 7 | } |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import { |
| 8 | 8 | ProviderDriverKind, |
| @@ -198,7 +198,7 @@ async function waitForEvent( · 189 unmodified lines | ||
| 198 | 198 | } |
| 199 | 199 | |
| 200 | 200 | function runGit(cwd: string, args: ReadonlyArray<string>) { |
| 201 | − return execFileSync("git", args, { | |
| 201 | + return NodeChildProcess.execFileSync("git", args, { | |
| 202 | 202 | cwd, |
| 203 | 203 | stdio: ["ignore", "pipe", "pipe"], |
| 204 | 204 | encoding: "utf8", |
| @@ -206,11 +206,11 @@ function runGit(cwd: string, args: ReadonlyArray<string>) { · 1 unmodified line | ||
| 206 | 206 | } |
| 207 | 207 | |
| 208 | 208 | 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-")); | |
| 210 | 210 | runGit(cwd, ["init", "--initial-branch=main"]); |
| 211 | 211 | runGit(cwd, ["config", "user.email", "test@example.com"]); |
| 212 | 212 | 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"); | |
| 214 | 214 | runGit(cwd, ["add", "."]); |
| 215 | 215 | runGit(cwd, ["commit", "-m", "Initial"]); |
| 216 | 216 | return cwd; |
| @@ -267,7 +267,7 @@ describe("CheckpointReactor", () => { · 50 unmodified lines | ||
| 267 | 267 | while (tempDirs.length > 0) { |
| 268 | 268 | const dir = tempDirs.pop(); |
| 269 | 269 | if (dir) { |
| 270 | − fs.rmSync(dir, { recursive: true, force: true }); | |
| 270 | + NodeFS.rmSync(dir, { recursive: true, force: true }); | |
| 271 | 271 | } |
| 272 | 272 | } |
| 273 | 273 | }); |
| @@ -395,14 +395,14 @@ describe("CheckpointReactor", () => { · 121 unmodified lines | ||
| 395 | 395 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 396 | 396 | }), |
| 397 | 397 | ); |
| 398 | − fs.writeFileSync(path.join(cwd, "README.md"), "v2\n", "utf8"); | |
| 398 | + NodeFS.writeFileSync(NodePath.join(cwd, "README.md"), "v2\n", "utf8"); | |
| 399 | 399 | await runtime.runPromise( |
| 400 | 400 | checkpointStore.captureCheckpoint({ |
| 401 | 401 | cwd, |
| 402 | 402 | checkpointRef: checkpointRefForThreadTurn(ThreadId.make("thread-1"), 1), |
| 403 | 403 | }), |
| 404 | 404 | ); |
| 405 | − fs.writeFileSync(path.join(cwd, "README.md"), "v3\n", "utf8"); | |
| 405 | + NodeFS.writeFileSync(NodePath.join(cwd, "README.md"), "v3\n", "utf8"); | |
| 406 | 406 | await runtime.runPromise( |
| 407 | 407 | checkpointStore.captureCheckpoint({ |
| 408 | 408 | cwd, |
| @@ -456,7 +456,7 @@ describe("CheckpointReactor", () => { · 47 unmodified lines | ||
| 456 | 456 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 457 | 457 | ); |
| 458 | 458 | |
| 459 | − fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 459 | + NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 460 | 460 | harness.provider.emit({ |
| 461 | 461 | type: "turn.completed", |
| 462 | 462 | eventId: EventId.make("evt-turn-completed-1"), |
| @@ -554,7 +554,7 @@ describe("CheckpointReactor", () => { · 91 unmodified lines | ||
| 554 | 554 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 555 | 555 | ); |
| 556 | 556 | |
| 557 | − fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 557 | + NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 558 | 558 | |
| 559 | 559 | harness.provider.emit({ |
| 560 | 560 | type: "turn.completed", |
| @@ -628,7 +628,7 @@ describe("CheckpointReactor", () => { · 67 unmodified lines | ||
| 628 | 628 | checkpointRefForThreadTurn(ThreadId.make("thread-1"), 0), |
| 629 | 629 | ); |
| 630 | 630 | |
| 631 | − fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 631 | + NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 632 | 632 | harness.provider.emit({ |
| 633 | 633 | type: "turn.completed", |
| 634 | 634 | eventId: EventId.make("evt-turn-completed-claude-1"), |
| @@ -761,7 +761,7 @@ describe("CheckpointReactor", () => { · 126 unmodified lines | ||
| 761 | 761 | }), |
| 762 | 762 | ); |
| 763 | 763 | |
| 764 | − fs.writeFileSync(path.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 764 | + NodeFS.writeFileSync(NodePath.join(harness.cwd, "README.md"), "v2\n", "utf8"); | |
| 765 | 765 | harness.provider.emit({ |
| 766 | 766 | type: "turn.completed", |
| 767 | 767 | eventId: EventId.make("evt-turn-completed-missing-provider-cwd"), |
| @@ -829,8 +829,8 @@ describe("CheckpointReactor", () => { · 61 unmodified lines | ||
| 829 | 829 | }); |
| 830 | 830 | |
| 831 | 831 | 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-"), | |
| 834 | 834 | ); |
| 835 | 835 | tempDirs.push(nonRepositorySessionCwd); |
| 836 | 836 | |
| @@ -963,7 +963,7 @@ describe("CheckpointReactor", () => { · 126 unmodified lines | ||
| 963 | 963 | threadId: ThreadId.make("thread-1"), |
| 964 | 964 | numTurns: 1, |
| 965 | 965 | }); |
| 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"); | |
| 967 | 967 | expect( |
| 968 | 968 | gitRefExists(harness.cwd, checkpointRefForThreadTurn(ThreadId.make("thread-1"), 2)), |
| 969 | 969 | ).toBe(false); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import { |
| 7 | 7 | ModelSelection, |
| @@ -107,11 +107,11 @@ describe("ProviderCommandReactor", () => { · 99 unmodified lines | ||
| 107 | 107 | } |
| 108 | 108 | runtime = null; |
| 109 | 109 | for (const stateDir of createdStateDirs) { |
| 110 | − fs.rmSync(stateDir, { recursive: true, force: true }); | |
| 110 | + NodeFS.rmSync(stateDir, { recursive: true, force: true }); | |
| 111 | 111 | } |
| 112 | 112 | createdStateDirs.clear(); |
| 113 | 113 | for (const baseDir of createdBaseDirs) { |
| 114 | − fs.rmSync(baseDir, { recursive: true, force: true }); | |
| 114 | + NodeFS.rmSync(baseDir, { recursive: true, force: true }); | |
| 115 | 115 | } |
| 116 | 116 | createdBaseDirs.clear(); |
| 117 | 117 | }); |
| @@ -147,7 +147,8 @@ describe("ProviderCommandReactor", () => { · 29 unmodified lines | ||
| 147 | 147 | readonly requiresNewThreadForModelChange?: boolean; |
| 148 | 148 | }) { |
| 149 | 149 | 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-")); | |
| 151 | 152 | createdBaseDirs.add(baseDir); |
| 152 | 153 | const { stateDir } = deriveServerPathsSync(baseDir, undefined); |
| 153 | 154 | createdStateDirs.add(stateDir); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import { |
| 7 | 7 | OrchestrationReadModel, |
| @@ -198,7 +198,7 @@ describe("ProviderRuntimeIngestion", () => { · 190 unmodified lines | ||
| 198 | 198 | const tempDirs: string[] = []; |
| 199 | 199 | |
| 200 | 200 | 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)); | |
| 202 | 202 | tempDirs.push(dir); |
| 203 | 203 | return dir; |
| 204 | 204 | } |
| @@ -213,13 +213,13 @@ describe("ProviderRuntimeIngestion", () => { · 8 unmodified lines | ||
| 213 | 213 | } |
| 214 | 214 | runtime = null; |
| 215 | 215 | for (const dir of tempDirs.splice(0)) { |
| 216 | − fs.rmSync(dir, { recursive: true, force: true }); | |
| 216 | + NodeFS.rmSync(dir, { recursive: true, force: true }); | |
| 217 | 217 | } |
| 218 | 218 | }); |
| 219 | 219 | |
| 220 | 220 | async function createHarness(options?: { serverSettings?: Partial<ServerSettings> }) { |
| 221 | 221 | const workspaceRoot = makeTempDir("t3-provider-project-"); |
| 222 | − fs.mkdirSync(path.join(workspaceRoot, ".git")); | |
| 222 | + NodeFS.mkdirSync(NodePath.join(workspaceRoot, ".git")); | |
| 223 | 223 | const provider = createProviderServiceHarness(); |
| 224 | 224 | const orchestrationLayer = OrchestrationEngineLive.pipe( |
| 225 | 225 | Layer.provide(OrchestrationProjectionSnapshotQueryLive), |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // @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"; | |
| 4 | 4 | import { describe, expect, it } from "vite-plus/test"; |
| 5 | 5 | |
| 6 | 6 | import { expandHomePath } from "./pathExpansion.ts"; |
| @@ -17,15 +17,15 @@ describe("expandHomePath", () => { · 10 unmodified lines | ||
| 17 | 17 | }); |
| 18 | 18 | |
| 19 | 19 | it("expands a lone tilde to the home directory", () => { |
| 20 | − expect(expandHomePath("~")).toBe(homedir()); | |
| 20 | + expect(expandHomePath("~")).toBe(NodeOS.homedir()); | |
| 21 | 21 | }); |
| 22 | 22 | |
| 23 | 23 | 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")); | |
| 25 | 25 | }); |
| 26 | 26 | |
| 27 | 27 | it("expands a Windows-style ~\\ prefix", () => { |
| 28 | − expect(expandHomePath("~\\.codex")).toBe(join(homedir(), ".codex")); | |
| 28 | + expect(expandHomePath("~\\.codex")).toBe(NodePath.join(NodeOS.homedir(), ".codex")); | |
| 29 | 29 | }); |
| 30 | 30 | |
| 31 | 31 | it("does not expand ~user paths", () => { |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // @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"; | |
| 4 | 4 | |
| 5 | 5 | /** |
| 6 | 6 | * Expand a leading `~` (or `~/…`, `~\…`) in a user-supplied path to the |
| @@ -16,9 +16,9 @@ import { join } from "node:path"; · 9 unmodified lines | ||
| 16 | 16 | */ |
| 17 | 17 | export function expandHomePath(value: string): string { |
| 18 | 18 | if (!value) return value; |
| 19 | − if (value === "~") return homedir(); | |
| 19 | + if (value === "~") return NodeOS.homedir(); | |
| 20 | 20 | if (value.startsWith("~/") || value.startsWith("~\\")) { |
| 21 | − return join(homedir(), value.slice(2)); | |
| 21 | + return NodePath.join(NodeOS.homedir(), value.slice(2)); | |
| 22 | 22 | } |
| 23 | 23 | return value; |
| 24 | 24 | } |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | * |
| 5 | 5 | * @module SqliteClient |
| 6 | 6 | */ |
| 7 | −import { DatabaseSync, type StatementSync } from "node:sqlite"; | |
| 7 | +import * as NodeSqlite from "node:sqlite"; | |
| 8 | 8 | |
| 9 | 9 | import * as Cache from "effect/Cache"; |
| 10 | 10 | import * as Config from "effect/Config"; |
| @@ -69,7 +69,7 @@ const checkNodeSqliteCompat = () => { · 58 unmodified lines | ||
| 69 | 69 | |
| 70 | 70 | const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( |
| 71 | 71 | options: SqliteClientConfig, |
| 72 | − openDatabase: () => DatabaseSync, | |
| 72 | + openDatabase: () => NodeSqlite.DatabaseSync, | |
| 73 | 73 | ): Effect.fn.Return<Client.SqlClient, never, Scope.Scope | Reactivity.Reactivity> { |
| 74 | 74 | yield* checkNodeSqliteCompat(); |
| 75 | 75 | |
| @@ -86,8 +86,8 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( · 10 unmodified lines | ||
| 86 | 86 | Effect.sync(() => db.close()), |
| 87 | 87 | ); |
| 88 | 88 | |
| 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 => { | |
| 91 | 91 | const cached = statementReaderCache.get(statement); |
| 92 | 92 | if (cached !== undefined) { |
| 93 | 93 | return cached; |
| @@ -113,7 +113,11 @@ const makeWithDatabase = Effect.fn("makeWithDatabase")(function* ( · 19 unmodified lines | ||
| 113 | 113 | }), |
| 114 | 114 | }); |
| 115 | 115 | |
| 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 | + ) => | |
| 117 | 121 | Effect.withFiber<ReadonlyArray<any>, SqlError>((fiber) => { |
| 118 | 122 | statement.setReadBigInts(Boolean(Context.get(fiber.context, Client.SafeIntegers))); |
| 119 | 123 | try { |
| @@ -220,7 +224,7 @@ const make = ( · 100 unmodified lines | ||
| 220 | 224 | makeWithDatabase( |
| 221 | 225 | options, |
| 222 | 226 | () => |
| 223 | − new DatabaseSync(options.filename, { | |
| 227 | + new NodeSqlite.DatabaseSync(options.filename, { | |
| 224 | 228 | readOnly: options.readonly ?? false, |
| 225 | 229 | allowExtension: options.allowExtension ?? false, |
| 226 | 230 | }), |
| @@ -236,7 +240,7 @@ const makeMemory = ( · 9 unmodified lines | ||
| 236 | 240 | readonly: false, |
| 237 | 241 | }, |
| 238 | 242 | () => { |
| 239 | − const database = new DatabaseSync(":memory:", { | |
| 243 | + const database = new NodeSqlite.DatabaseSync(":memory:", { | |
| 240 | 244 | allowExtension: config.allowExtension ?? false, |
| 241 | 245 | }); |
| 242 | 246 | return database; |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import * as net from "node:net"; | |
| 1 | +import * as NodeNet from "node:net"; | |
| 2 | 2 | |
| 3 | 3 | import { it as effectIt } from "@effect/vitest"; |
| 4 | 4 | import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; |
| @@ -17,9 +17,9 @@ const TestPortDiscoveryLive = PortScanner.layer.pipe( · 12 unmodified lines | ||
| 17 | 17 | ), |
| 18 | 18 | ); |
| 19 | 19 | |
| 20 | −const openServer = (port: number): Effect.Effect<net.Server | null> => | |
| 20 | +const openServer = (port: number): Effect.Effect<NodeNet.Server | null> => | |
| 21 | 21 | Effect.callback((resume) => { |
| 22 | − const server = net.createServer(); | |
| 22 | + const server = NodeNet.createServer(); | |
| 23 | 23 | server.once("error", () => { |
| 24 | 24 | resume(Effect.succeed(null)); |
| 25 | 25 | }); |
| @@ -31,7 +31,7 @@ const openServer = (port: number): Effect.Effect<net.Server | null> => · 5 unmodified lines | ||
| 31 | 31 | }); |
| 32 | 32 | }); |
| 33 | 33 | |
| 34 | −const closeServer = (server: net.Server): Effect.Effect<void> => | |
| 34 | +const closeServer = (server: NodeNet.Server): Effect.Effect<void> => | |
| 35 | 35 | Effect.callback((resume) => { |
| 36 | 36 | server.close(() => resume(Effect.void)); |
| 37 | 37 | }); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 7 | 7 | import type { |
| @@ -395,7 +395,7 @@ describe("ClaudeAdapterLive", () => { · 387 unmodified lines | ||
| 395 | 395 | }); |
| 396 | 396 | |
| 397 | 397 | 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")); | |
| 399 | 399 | }).pipe( |
| 400 | 400 | Effect.provideService(Random.Random, makeDeterministicRandomService()), |
| 401 | 401 | Effect.provide(harness.layer), |
| @@ -649,7 +649,7 @@ describe("ClaudeAdapterLive", () => { · 247 unmodified lines | ||
| 649 | 649 | }); |
| 650 | 650 | |
| 651 | 651 | 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-")); | |
| 653 | 653 | const harness = makeHarness({ |
| 654 | 654 | cwd: "/tmp/project-claude-attachments", |
| 655 | 655 | baseDir, |
| @@ -657,7 +657,7 @@ describe("ClaudeAdapterLive", () => { · 1 unmodified line | ||
| 657 | 657 | return Effect.gen(function* () { |
| 658 | 658 | yield* Effect.addFinalizer(() => |
| 659 | 659 | Effect.sync(() => |
| 660 | − rmSync(baseDir, { | |
| 660 | + NodeFS.rmSync(baseDir, { | |
| 661 | 661 | recursive: true, |
| 662 | 662 | force: true, |
| 663 | 663 | }), |
| @@ -674,9 +674,9 @@ describe("ClaudeAdapterLive", () => { · 10 unmodified lines | ||
| 674 | 674 | mimeType: "image/png", |
| 675 | 675 | sizeBytes: 4, |
| 676 | 676 | }; |
| 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])); | |
| 680 | 680 | |
| 681 | 681 | const session = yield* adapter.startSession({ |
| 682 | 682 | threadId: THREAD_ID, |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | import { |
| 7 | 7 | ApprovalRequestId, |
| 8 | 8 | CodexSettings, |
| @@ -250,8 +250,8 @@ validationLayer("CodexAdapterLive validation", (it) => { · 241 unmodified lines | ||
| 250 | 250 | }) |
| 251 | 251 | .pipe(Effect.result); |
| 252 | 252 | |
| 253 | − assert.equal(result._tag, "Failure"); | |
| 254 | − assert.deepStrictEqual( | |
| 253 | + NodeAssert.equal(result._tag, "Failure"); | |
| 254 | + NodeAssert.deepStrictEqual( | |
| 255 | 255 | result.failure, |
| 256 | 256 | new ProviderAdapterValidationError({ |
| 257 | 257 | provider: ProviderDriverKind.make("codex"), |
| @@ -259,7 +259,7 @@ validationLayer("CodexAdapterLive validation", (it) => { · 1 unmodified line | ||
| 259 | 259 | issue: "Expected provider 'codex' but received 'claudeAgent'.", |
| 260 | 260 | }), |
| 261 | 261 | ); |
| 262 | − assert.equal(validationRuntimeFactory.factory.mock.calls.length, 0); | |
| 262 | + NodeAssert.equal(validationRuntimeFactory.factory.mock.calls.length, 0); | |
| 263 | 263 | }), |
| 264 | 264 | ); |
| 265 | 265 | it.effect("maps codex model options before starting a session", () => |
| @@ -276,7 +276,7 @@ validationLayer("CodexAdapterLive validation", (it) => { · 10 unmodified lines | ||
| 276 | 276 | runtimeMode: "full-access", |
| 277 | 277 | }); |
| 278 | 278 | |
| 279 | − assert.deepStrictEqual(validationRuntimeFactory.factory.mock.calls[0]?.[0], { | |
| 279 | + NodeAssert.deepStrictEqual(validationRuntimeFactory.factory.mock.calls[0]?.[0], { | |
| 280 | 280 | binaryPath: "codex", |
| 281 | 281 | cwd: process.cwd(), |
| 282 | 282 | model: "gpt-5.3-codex", |
| @@ -319,10 +319,10 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 36 unmodified lines | ||
| 319 | 319 | }) |
| 320 | 320 | .pipe(Effect.result); |
| 321 | 321 | |
| 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"); | |
| 326 | 326 | }), |
| 327 | 327 | ); |
| 328 | 328 | |
| @@ -335,7 +335,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 6 unmodified lines | ||
| 335 | 335 | runtimeMode: "full-access", |
| 336 | 336 | }); |
| 337 | 337 | const runtime = sessionRuntimeFactory.lastRuntime; |
| 338 | − assert.ok(runtime); | |
| 338 | + NodeAssert.ok(runtime); | |
| 339 | 339 | runtime.sendTurnImpl.mockClear(); |
| 340 | 340 | |
| 341 | 341 | yield* Effect.ignore( |
| @@ -350,7 +350,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 8 unmodified lines | ||
| 350 | 350 | }), |
| 351 | 351 | ); |
| 352 | 352 | |
| 353 | − assert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], { | |
| 353 | + NodeAssert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], { | |
| 354 | 354 | input: "hello", |
| 355 | 355 | model: "gpt-5.3-codex", |
| 356 | 356 | effort: "high", |
| @@ -386,7 +386,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 29 unmodified lines | ||
| 386 | 386 | runtimeMode: "full-access", |
| 387 | 387 | }); |
| 388 | 388 | const runtime = customRuntimeFactory.lastRuntime; |
| 389 | − assert.ok(runtime); | |
| 389 | + NodeAssert.ok(runtime); | |
| 390 | 390 | runtime.sendTurnImpl.mockClear(); |
| 391 | 391 | |
| 392 | 392 | yield* Effect.ignore( |
| @@ -405,7 +405,7 @@ sessionErrorLayer("CodexAdapterLive session errors", (it) => { · 12 unmodified lines | ||
| 405 | 405 | }), |
| 406 | 406 | ); |
| 407 | 407 | |
| 408 | − assert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], { | |
| 408 | + NodeAssert.deepStrictEqual(runtime.sendTurnImpl.mock.calls[0]?.[0], { | |
| 409 | 409 | input: "hello", |
| 410 | 410 | model: "gpt-5.3-codex", |
| 411 | 411 | effort: "high", |
| @@ -442,7 +442,7 @@ function startLifecycleRuntime() { · 30 unmodified lines | ||
| 442 | 442 | runtimeMode: "full-access", |
| 443 | 443 | }); |
| 444 | 444 | const runtime = lifecycleRuntimeFactory.lastRuntime; |
| 445 | − assert.ok(runtime); | |
| 445 | + NodeAssert.ok(runtime); | |
| 446 | 446 | return { adapter, runtime }; |
| 447 | 447 | }); |
| 448 | 448 | } |
| @@ -477,17 +477,17 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 28 unmodified lines | ||
| 477 | 477 | yield* runtime.emit(event); |
| 478 | 478 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 479 | 479 | |
| 480 | − assert.equal(firstEvent._tag, "Some"); | |
| 480 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 481 | 481 | if (firstEvent._tag !== "Some") { |
| 482 | 482 | return; |
| 483 | 483 | } |
| 484 | − assert.equal(firstEvent.value.type, "item.completed"); | |
| 484 | + NodeAssert.equal(firstEvent.value.type, "item.completed"); | |
| 485 | 485 | if (firstEvent.value.type !== "item.completed") { |
| 486 | 486 | return; |
| 487 | 487 | } |
| 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"); | |
| 491 | 491 | }), |
| 492 | 492 | ); |
| 493 | 493 | |
| @@ -524,13 +524,13 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 30 unmodified lines | ||
| 524 | 524 | }); |
| 525 | 525 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 526 | 526 | |
| 527 | − assert.equal(firstEvent._tag, "Some"); | |
| 527 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 528 | 528 | if (firstEvent._tag !== "Some" || firstEvent.value.type !== "item.completed") { |
| 529 | 529 | return; |
| 530 | 530 | } |
| 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, { | |
| 534 | 534 | completedAtMs: 1_778_000_000_000, |
| 535 | 535 | threadId: "thread-1", |
| 536 | 536 | turnId: "turn-1", |
| @@ -578,16 +578,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 41 unmodified lines | ||
| 578 | 578 | yield* runtime.emit(event); |
| 579 | 579 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 580 | 580 | |
| 581 | − assert.equal(firstEvent._tag, "Some"); | |
| 581 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 582 | 582 | if (firstEvent._tag !== "Some") { |
| 583 | 583 | return; |
| 584 | 584 | } |
| 585 | − assert.equal(firstEvent.value.type, "turn.proposed.completed"); | |
| 585 | + NodeAssert.equal(firstEvent.value.type, "turn.proposed.completed"); | |
| 586 | 586 | if (firstEvent.value.type !== "turn.proposed.completed") { |
| 587 | 587 | return; |
| 588 | 588 | } |
| 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"); | |
| 591 | 591 | }), |
| 592 | 592 | ); |
| 593 | 593 | |
| @@ -615,16 +615,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 21 unmodified lines | ||
| 615 | 615 | |
| 616 | 616 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 617 | 617 | |
| 618 | − assert.equal(firstEvent._tag, "Some"); | |
| 618 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 619 | 619 | if (firstEvent._tag !== "Some") { |
| 620 | 620 | return; |
| 621 | 621 | } |
| 622 | − assert.equal(firstEvent.value.type, "turn.proposed.delta"); | |
| 622 | + NodeAssert.equal(firstEvent.value.type, "turn.proposed.delta"); | |
| 623 | 623 | if (firstEvent.value.type !== "turn.proposed.delta") { |
| 624 | 624 | return; |
| 625 | 625 | } |
| 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"); | |
| 628 | 628 | }), |
| 629 | 629 | ); |
| 630 | 630 | |
| @@ -646,16 +646,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 15 unmodified lines | ||
| 646 | 646 | yield* runtime.emit(event); |
| 647 | 647 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 648 | 648 | |
| 649 | − assert.equal(firstEvent._tag, "Some"); | |
| 649 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 650 | 650 | if (firstEvent._tag !== "Some") { |
| 651 | 651 | return; |
| 652 | 652 | } |
| 653 | − assert.equal(firstEvent.value.type, "session.exited"); | |
| 653 | + NodeAssert.equal(firstEvent.value.type, "session.exited"); | |
| 654 | 654 | if (firstEvent.value.type !== "session.exited") { |
| 655 | 655 | return; |
| 656 | 656 | } |
| 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"); | |
| 659 | 659 | }), |
| 660 | 660 | ); |
| 661 | 661 | |
| @@ -684,16 +684,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 22 unmodified lines | ||
| 684 | 684 | |
| 685 | 685 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 686 | 686 | |
| 687 | − assert.equal(firstEvent._tag, "Some"); | |
| 687 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 688 | 688 | if (firstEvent._tag !== "Some") { |
| 689 | 689 | return; |
| 690 | 690 | } |
| 691 | − assert.equal(firstEvent.value.type, "runtime.warning"); | |
| 691 | + NodeAssert.equal(firstEvent.value.type, "runtime.warning"); | |
| 692 | 692 | if (firstEvent.value.type !== "runtime.warning") { |
| 693 | 693 | return; |
| 694 | 694 | } |
| 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"); | |
| 697 | 697 | }), |
| 698 | 698 | ); |
| 699 | 699 | |
| @@ -715,16 +715,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 15 unmodified lines | ||
| 715 | 715 | |
| 716 | 716 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 717 | 717 | |
| 718 | − assert.equal(firstEvent._tag, "Some"); | |
| 718 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 719 | 719 | if (firstEvent._tag !== "Some") { |
| 720 | 720 | return; |
| 721 | 721 | } |
| 722 | − assert.equal(firstEvent.value.type, "runtime.warning"); | |
| 722 | + NodeAssert.equal(firstEvent.value.type, "runtime.warning"); | |
| 723 | 723 | if (firstEvent.value.type !== "runtime.warning") { |
| 724 | 724 | return; |
| 725 | 725 | } |
| 726 | − assert.equal(firstEvent.value.turnId, "turn-1"); | |
| 727 | − assert.equal( | |
| 726 | + NodeAssert.equal(firstEvent.value.turnId, "turn-1"); | |
| 727 | + NodeAssert.equal( | |
| 728 | 728 | firstEvent.value.payload.message, |
| 729 | 729 | "The filename or extension is too long. (os error 206)", |
| 730 | 730 | ); |
| @@ -752,16 +752,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 21 unmodified lines | ||
| 752 | 752 | |
| 753 | 753 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 754 | 754 | |
| 755 | − assert.equal(firstEvent._tag, "Some"); | |
| 755 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 756 | 756 | if (firstEvent._tag !== "Some") { |
| 757 | 757 | return; |
| 758 | 758 | } |
| 759 | − assert.equal(firstEvent.value.type, "thread.realtime.started"); | |
| 759 | + NodeAssert.equal(firstEvent.value.type, "thread.realtime.started"); | |
| 760 | 760 | if (firstEvent.value.type !== "thread.realtime.started") { |
| 761 | 761 | return; |
| 762 | 762 | } |
| 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"); | |
| 765 | 765 | }), |
| 766 | 766 | ); |
| 767 | 767 | |
| @@ -784,17 +784,17 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 16 unmodified lines | ||
| 784 | 784 | |
| 785 | 785 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 786 | 786 | |
| 787 | − assert.equal(firstEvent._tag, "Some"); | |
| 787 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 788 | 788 | if (firstEvent._tag !== "Some") { |
| 789 | 789 | return; |
| 790 | 790 | } |
| 791 | − assert.equal(firstEvent.value.type, "runtime.error"); | |
| 791 | + NodeAssert.equal(firstEvent.value.type, "runtime.error"); | |
| 792 | 792 | if (firstEvent.value.type !== "runtime.error") { |
| 793 | 793 | return; |
| 794 | 794 | } |
| 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( | |
| 798 | 798 | firstEvent.value.payload.message, |
| 799 | 799 | "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", |
| 800 | 800 | ); |
| @@ -824,15 +824,15 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 23 unmodified lines | ||
| 824 | 824 | yield* runtime.emit(event); |
| 825 | 825 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 826 | 826 | |
| 827 | − assert.equal(firstEvent._tag, "Some"); | |
| 827 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 828 | 828 | if (firstEvent._tag !== "Some") { |
| 829 | 829 | return; |
| 830 | 830 | } |
| 831 | − assert.equal(firstEvent.value.type, "request.resolved"); | |
| 831 | + NodeAssert.equal(firstEvent.value.type, "request.resolved"); | |
| 832 | 832 | if (firstEvent.value.type !== "request.resolved") { |
| 833 | 833 | return; |
| 834 | 834 | } |
| 835 | − assert.equal(firstEvent.value.payload.requestType, "command_execution_approval"); | |
| 835 | + NodeAssert.equal(firstEvent.value.payload.requestType, "command_execution_approval"); | |
| 836 | 836 | }), |
| 837 | 837 | ); |
| 838 | 838 | |
| @@ -859,15 +859,15 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 20 unmodified lines | ||
| 859 | 859 | yield* runtime.emit(event); |
| 860 | 860 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 861 | 861 | |
| 862 | − assert.equal(firstEvent._tag, "Some"); | |
| 862 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 863 | 863 | if (firstEvent._tag !== "Some") { |
| 864 | 864 | return; |
| 865 | 865 | } |
| 866 | − assert.equal(firstEvent.value.type, "request.resolved"); | |
| 866 | + NodeAssert.equal(firstEvent.value.type, "request.resolved"); | |
| 867 | 867 | if (firstEvent.value.type !== "request.resolved") { |
| 868 | 868 | return; |
| 869 | 869 | } |
| 870 | − assert.equal(firstEvent.value.payload.requestType, "file_read_approval"); | |
| 870 | + NodeAssert.equal(firstEvent.value.payload.requestType, "file_read_approval"); | |
| 871 | 871 | }), |
| 872 | 872 | ); |
| 873 | 873 | |
| @@ -895,15 +895,15 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 21 unmodified lines | ||
| 895 | 895 | yield* runtime.emit(event); |
| 896 | 896 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 897 | 897 | |
| 898 | − assert.equal(firstEvent._tag, "Some"); | |
| 898 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 899 | 899 | if (firstEvent._tag !== "Some") { |
| 900 | 900 | return; |
| 901 | 901 | } |
| 902 | − assert.equal(firstEvent.value.type, "user-input.resolved"); | |
| 902 | + NodeAssert.equal(firstEvent.value.type, "user-input.resolved"); | |
| 903 | 903 | if (firstEvent.value.type !== "user-input.resolved") { |
| 904 | 904 | return; |
| 905 | 905 | } |
| 906 | − assert.deepEqual(firstEvent.value.payload.answers, { | |
| 906 | + NodeAssert.deepEqual(firstEvent.value.payload.answers, { | |
| 907 | 907 | scope: [], |
| 908 | 908 | }); |
| 909 | 909 | }), |
| @@ -934,20 +934,20 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 24 unmodified lines | ||
| 934 | 934 | yield* runtime.emit(event); |
| 935 | 935 | const events = Array.from(yield* Fiber.join(eventsFiber)); |
| 936 | 936 | |
| 937 | − assert.equal(events.length, 2); | |
| 937 | + NodeAssert.equal(events.length, 2); | |
| 938 | 938 | |
| 939 | 939 | const firstEvent = events[0]; |
| 940 | 940 | const secondEvent = events[1]; |
| 941 | 941 | |
| 942 | − assert.equal(firstEvent?.type, "session.state.changed"); | |
| 942 | + NodeAssert.equal(firstEvent?.type, "session.state.changed"); | |
| 943 | 943 | 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"); | |
| 946 | 946 | } |
| 947 | 947 | |
| 948 | − assert.equal(secondEvent?.type, "runtime.warning"); | |
| 948 | + NodeAssert.equal(secondEvent?.type, "runtime.warning"); | |
| 949 | 949 | if (secondEvent?.type === "runtime.warning") { |
| 950 | − assert.equal(secondEvent.payload.message, "Sandbox setup failed"); | |
| 950 | + NodeAssert.equal(secondEvent.payload.message, "Sandbox setup failed"); | |
| 951 | 951 | } |
| 952 | 952 | }), |
| 953 | 953 | ); |
| @@ -1006,17 +1006,17 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 52 unmodified lines | ||
| 1006 | 1006 | } satisfies ProviderEvent); |
| 1007 | 1007 | |
| 1008 | 1008 | 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"); | |
| 1010 | 1010 | 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); | |
| 1014 | 1014 | } |
| 1015 | 1015 | |
| 1016 | − assert.equal(events[1]?.type, "user-input.resolved"); | |
| 1016 | + NodeAssert.equal(events[1]?.type, "user-input.resolved"); | |
| 1017 | 1017 | 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, { | |
| 1020 | 1020 | sandbox_mode: "workspace-write", |
| 1021 | 1021 | }); |
| 1022 | 1022 | } |
| @@ -1060,16 +1060,16 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => { · 37 unmodified lines | ||
| 1060 | 1060 | } satisfies ProviderEvent); |
| 1061 | 1061 | |
| 1062 | 1062 | const firstEvent = yield* Fiber.join(firstEventFiber); |
| 1063 | − assert.equal(firstEvent._tag, "Some"); | |
| 1063 | + NodeAssert.equal(firstEvent._tag, "Some"); | |
| 1064 | 1064 | if (firstEvent._tag !== "Some") { |
| 1065 | 1065 | return; |
| 1066 | 1066 | } |
| 1067 | − assert.equal(firstEvent.value.type, "thread.token-usage.updated"); | |
| 1067 | + NodeAssert.equal(firstEvent.value.type, "thread.token-usage.updated"); | |
| 1068 | 1068 | if (firstEvent.value.type !== "thread.token-usage.updated") { |
| 1069 | 1069 | return; |
| 1070 | 1070 | } |
| 1071 | 1071 | |
| 1072 | − assert.deepEqual(firstEvent.value.payload.usage, { | |
| 1072 | + NodeAssert.deepEqual(firstEvent.value.payload.usage, { | |
| 1073 | 1073 | usedTokens: 126, |
| 1074 | 1074 | totalProcessedTokens: 11_839, |
| 1075 | 1075 | maxTokens: 258_400, |
| @@ -1119,15 +1119,15 @@ scopedLifecycleLayer("CodexAdapterLive scoped lifecycle", (it) => { · 43 unmodified lines | ||
| 1119 | 1119 | }); |
| 1120 | 1120 | |
| 1121 | 1121 | const runtime = scopedLifecycleRuntimeFactory.lastRuntime; |
| 1122 | − assert.ok(runtime); | |
| 1122 | + NodeAssert.ok(runtime); | |
| 1123 | 1123 | |
| 1124 | 1124 | yield* adapter.stopSession(asThreadId("thread-stop")); |
| 1125 | 1125 | |
| 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, [ | |
| 1128 | 1128 | asThreadId("thread-stop"), |
| 1129 | 1129 | ]); |
| 1130 | − assert.equal(yield* adapter.hasSession(asThreadId("thread-stop")), false); | |
| 1130 | + NodeAssert.equal(yield* adapter.hasSession(asThreadId("thread-stop")), false); | |
| 1131 | 1131 | }), |
| 1132 | 1132 | ); |
| 1133 | 1133 | }); |
| @@ -1164,20 +1164,22 @@ scopedFailureLayer("CodexAdapterLive scoped startup failure", (it) => { · 30 unmodified lines | ||
| 1164 | 1164 | }) |
| 1165 | 1165 | .pipe(Effect.result); |
| 1166 | 1166 | |
| 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, [ | |
| 1170 | 1170 | asThreadId("thread-fail"), |
| 1171 | 1171 | ]); |
| 1172 | − assert.equal(yield* adapter.hasSession(asThreadId("thread-fail")), false); | |
| 1172 | + NodeAssert.equal(yield* adapter.hasSession(asThreadId("thread-fail")), false); | |
| 1173 | 1173 | }), |
| 1174 | 1174 | ); |
| 1175 | 1175 | }); |
| 1176 | 1176 | |
| 1177 | 1177 | it.effect("flushes managed native logs when the adapter layer shuts down", () => |
| 1178 | 1178 | 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"); | |
| 1181 | 1183 | const runtimeFactory = makeRuntimeFactory(); |
| 1182 | 1184 | const scope = yield* Scope.make("sequential"); |
| 1183 | 1185 | let scopeClosed = false; |
| @@ -1208,7 +1210,7 @@ it.effect("flushes managed native logs when the adapter layer shuts down", () => · 24 unmodified lines | ||
| 1208 | 1210 | }); |
| 1209 | 1211 | |
| 1210 | 1212 | const runtime = runtimeFactory.lastRuntime; |
| 1211 | − assert.ok(runtime); | |
| 1213 | + NodeAssert.ok(runtime); | |
| 1212 | 1214 | |
| 1213 | 1215 | const firstEventFiber = yield* Stream.runHead(adapter.streamEvents).pipe(Effect.forkChild); |
| 1214 | 1216 | yield* runtime.emit({ |
| @@ -1225,15 +1227,15 @@ it.effect("flushes managed native logs when the adapter layer shuts down", () => · 10 unmodified lines | ||
| 1225 | 1227 | yield* Scope.close(scope, Exit.void); |
| 1226 | 1228 | scopeClosed = true; |
| 1227 | 1229 | |
| 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"/); | |
| 1232 | 1234 | } finally { |
| 1233 | 1235 | if (!scopeClosed) { |
| 1234 | 1236 | yield* Scope.close(scope, Exit.void); |
| 1235 | 1237 | } |
| 1236 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 1238 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 1237 | 1239 | } |
| 1238 | 1240 | }), |
| 1239 | 1241 | ); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import assert from "node:assert/strict"; | |
| 1 | +import * as NodeAssert from "node:assert/strict"; | |
| 2 | 2 | |
| 3 | 3 | import * as Effect from "effect/Effect"; |
| 4 | 4 | import * as Schema from "effect/Schema"; |
| @@ -55,7 +55,7 @@ describe("buildTurnStartParams", () => { · 50 unmodified lines | ||
| 55 | 55 | }), |
| 56 | 56 | ); |
| 57 | 57 | |
| 58 | − assert.deepStrictEqual(params, { | |
| 58 | + NodeAssert.deepStrictEqual(params, { | |
| 59 | 59 | threadId: "provider-thread-1", |
| 60 | 60 | approvalPolicy: "never", |
| 61 | 61 | sandboxPolicy: { |
| @@ -97,7 +97,7 @@ describe("buildTurnStartParams", () => { · 35 unmodified lines | ||
| 97 | 97 | }), |
| 98 | 98 | ); |
| 99 | 99 | |
| 100 | − assert.deepStrictEqual(params, { | |
| 100 | + NodeAssert.deepStrictEqual(params, { | |
| 101 | 101 | threadId: "provider-thread-1", |
| 102 | 102 | approvalPolicy: "on-request", |
| 103 | 103 | sandboxPolicy: { |
| @@ -134,7 +134,7 @@ describe("buildTurnStartParams", () => { · 30 unmodified lines | ||
| 134 | 134 | }), |
| 135 | 135 | ); |
| 136 | 136 | |
| 137 | − assert.deepStrictEqual(params, { | |
| 137 | + NodeAssert.deepStrictEqual(params, { | |
| 138 | 138 | threadId: "provider-thread-1", |
| 139 | 139 | approvalPolicy: "untrusted", |
| 140 | 140 | sandboxPolicy: { |
| @@ -156,19 +156,19 @@ describe("T3 browser developer instructions", () => { · 15 unmodified lines | ||
| 156 | 156 | CODEX_DEFAULT_MODE_DEVELOPER_INSTRUCTIONS, |
| 157 | 157 | CODEX_PLAN_MODE_DEVELOPER_INSTRUCTIONS, |
| 158 | 158 | ]) { |
| 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/); | |
| 163 | 163 | } |
| 164 | 164 | }); |
| 165 | 165 | }); |
| 166 | 166 | |
| 167 | 167 | describe("hasConfiguredMcpServer", () => { |
| 168 | 168 | 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( | |
| 172 | 172 | hasConfiguredMcpServer(["-c", 'mcp_servers.t3-code.url="http://127.0.0.1/mcp"']), |
| 173 | 173 | true, |
| 174 | 174 | ); |
| @@ -177,7 +177,7 @@ describe("hasConfiguredMcpServer", () => { · 2 unmodified lines | ||
| 177 | 177 | |
| 178 | 178 | describe("isRecoverableThreadResumeError", () => { |
| 179 | 179 | it("matches missing thread errors", () => { |
| 180 | − assert.equal( | |
| 180 | + NodeAssert.equal( | |
| 181 | 181 | isRecoverableThreadResumeError( |
| 182 | 182 | new CodexErrors.CodexAppServerRequestError({ |
| 183 | 183 | code: -32603, |
| @@ -189,7 +189,7 @@ describe("isRecoverableThreadResumeError", () => { · 5 unmodified lines | ||
| 189 | 189 | }); |
| 190 | 190 | |
| 191 | 191 | it("ignores non-recoverable resume errors", () => { |
| 192 | − assert.equal( | |
| 192 | + NodeAssert.equal( | |
| 193 | 193 | isRecoverableThreadResumeError( |
| 194 | 194 | new CodexErrors.CodexAppServerRequestError({ |
| 195 | 195 | code: -32603, |
| @@ -201,7 +201,7 @@ describe("isRecoverableThreadResumeError", () => { · 5 unmodified lines | ||
| 201 | 201 | }); |
| 202 | 202 | |
| 203 | 203 | it("ignores unrelated missing-resource errors that do not mention threads", () => { |
| 204 | − assert.equal( | |
| 204 | + NodeAssert.equal( | |
| 205 | 205 | isRecoverableThreadResumeError( |
| 206 | 206 | new CodexErrors.CodexAppServerRequestError({ |
| 207 | 207 | code: -32603, |
| @@ -210,7 +210,7 @@ describe("isRecoverableThreadResumeError", () => { · 2 unmodified lines | ||
| 210 | 210 | ), |
| 211 | 211 | false, |
| 212 | 212 | ); |
| 213 | − assert.equal( | |
| 213 | + NodeAssert.equal( | |
| 214 | 214 | isRecoverableThreadResumeError( |
| 215 | 215 | new CodexErrors.CodexAppServerRequestError({ |
| 216 | 216 | code: -32603, |
| @@ -256,8 +256,8 @@ describe("openCodexThread", () => { · 39 unmodified lines | ||
| 256 | 256 | }), |
| 257 | 257 | ); |
| 258 | 258 | |
| 259 | − assert.equal(opened.thread.id, "fresh-thread"); | |
| 260 | − assert.deepStrictEqual( | |
| 259 | + NodeAssert.equal(opened.thread.id, "fresh-thread"); | |
| 260 | + NodeAssert.deepStrictEqual( | |
| 261 | 261 | calls.map((call) => call.method), |
| 262 | 262 | ["thread/resume", "thread/start"], |
| 263 | 263 | ); |
| @@ -283,7 +283,7 @@ describe("openCodexThread", () => { · 19 unmodified lines | ||
| 283 | 283 | }, |
| 284 | 284 | }; |
| 285 | 285 | |
| 286 | − await assert.rejects( | |
| 286 | + await NodeAssert.rejects( | |
| 287 | 287 | Effect.runPromise( |
| 288 | 288 | openCodexThread({ |
| 289 | 289 | client, |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 8 | 8 | import { assert, it } from "@effect/vitest"; |
| @@ -36,8 +36,8 @@ class CursorAdapter extends Context.Service<CursorAdapter, CursorAdapterShape>() · 27 unmodified lines | ||
| 36 | 36 | "t3/provider/Layers/CursorAdapter.test/CursorAdapter", |
| 37 | 37 | ) {} |
| 38 | 38 | |
| 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"); | |
| 41 | 41 | const mockAgentCommand = "node"; |
| 42 | 42 | const mockAgentArgs = [mockAgentPath] as const; |
| 43 | 43 | |
| @@ -45,8 +45,8 @@ async function makeMockAgentWrapper( · 1 unmodified line | ||
| 45 | 45 | extraEnv?: Record<string, string>, |
| 46 | 46 | options?: { initialDelaySeconds?: number }, |
| 47 | 47 | ) { |
| 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"); | |
| 50 | 50 | const envExports = Object.entries(extraEnv ?? {}) |
| 51 | 51 | .map(([key, value]) => `export ${key}=${JSON.stringify(value)}`) |
| 52 | 52 | .join("\n"); |
| @@ -55,8 +55,8 @@ ${envExports} · 2 unmodified lines | ||
| 55 | 55 | ${options?.initialDelaySeconds ? `sleep ${JSON.stringify(String(options.initialDelaySeconds))}` : ""} |
| 56 | 56 | exec ${JSON.stringify(mockAgentCommand)} ${mockAgentArgs.map((arg) => JSON.stringify(arg)).join(" ")} "$@" |
| 57 | 57 | `; |
| 58 | − await writeFile(wrapperPath, script, "utf8"); | |
| 59 | − await chmod(wrapperPath, 0o755); | |
| 58 | + await NodeFSP.writeFile(wrapperPath, script, "utf8"); | |
| 59 | + await NodeFSP.chmod(wrapperPath, 0o755); | |
| 60 | 60 | return wrapperPath; |
| 61 | 61 | } |
| 62 | 62 | |
| @@ -65,8 +65,8 @@ async function makeProbeWrapper( · 2 unmodified lines | ||
| 65 | 65 | argvLogPath: string, |
| 66 | 66 | extraEnv?: Record<string, string>, |
| 67 | 67 | ) { |
| 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"); | |
| 70 | 70 | const envExports = Object.entries(extraEnv ?? {}) |
| 71 | 71 | .map(([key, value]) => `export ${key}=${JSON.stringify(value)}`) |
| 72 | 72 | .join("\n"); |
| @@ -77,13 +77,13 @@ export T3_ACP_REQUEST_LOG_PATH=${JSON.stringify(requestLogPath)} · 4 unmodified lines | ||
| 77 | 77 | ${envExports} |
| 78 | 78 | exec ${JSON.stringify(mockAgentCommand)} ${mockAgentArgs.map((arg) => JSON.stringify(arg)).join(" ")} "$@" |
| 79 | 79 | `; |
| 80 | − await writeFile(wrapperPath, script, "utf8"); | |
| 81 | − await chmod(wrapperPath, 0o755); | |
| 80 | + await NodeFSP.writeFile(wrapperPath, script, "utf8"); | |
| 81 | + await NodeFSP.chmod(wrapperPath, 0o755); | |
| 82 | 82 | return wrapperPath; |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | 85 | async function readArgvLog(filePath: string) { |
| 86 | − const raw = await readFile(filePath, "utf8"); | |
| 86 | + const raw = await NodeFSP.readFile(filePath, "utf8"); | |
| 87 | 87 | return raw |
| 88 | 88 | .split("\n") |
| 89 | 89 | .map((line) => line.trim()) |
| @@ -92,7 +92,7 @@ async function readArgvLog(filePath: string) { · 2 unmodified lines | ||
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | async function readJsonLines(filePath: string) { |
| 95 | − const raw = await readFile(filePath, "utf8"); | |
| 95 | + const raw = await NodeFSP.readFile(filePath, "utf8"); | |
| 96 | 96 | return raw |
| 97 | 97 | .split("\n") |
| 98 | 98 | .map((line) => line.trim()) |
| @@ -103,7 +103,7 @@ async function readJsonLines(filePath: string) { · 4 unmodified lines | ||
| 103 | 103 | async function waitForFileContent(filePath: string, attempts = 40) { |
| 104 | 104 | for (let attempt = 0; attempt < attempts; attempt += 1) { |
| 105 | 105 | try { |
| 106 | − const raw = await readFile(filePath, "utf8"); | |
| 106 | + const raw = await NodeFSP.readFile(filePath, "utf8"); | |
| 107 | 107 | if (raw.trim().length > 0) { |
| 108 | 108 | return raw; |
| 109 | 109 | } |
| @@ -315,9 +315,9 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 205 unmodified lines | ||
| 315 | 315 | const settings = yield* ServerSettingsService; |
| 316 | 316 | const threadId = ThreadId.make("cursor-stop-session-close"); |
| 317 | 317 | 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-")), | |
| 319 | 319 | ); |
| 320 | − const exitLogPath = path.join(tempDir, "exit.log"); | |
| 320 | + const exitLogPath = NodePath.join(tempDir, "exit.log"); | |
| 321 | 321 | |
| 322 | 322 | const wrapperPath = yield* Effect.promise(() => |
| 323 | 323 | makeMockAgentWrapper({ |
| @@ -349,9 +349,9 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 25 unmodified lines | ||
| 349 | 349 | const settings = yield* ServerSettingsService; |
| 350 | 350 | const threadId = ThreadId.make("cursor-concurrent-start-session"); |
| 351 | 351 | 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-")), | |
| 353 | 353 | ); |
| 354 | − const exitLogPath = path.join(tempDir, "exit.log"); | |
| 354 | + const exitLogPath = NodePath.join(tempDir, "exit.log"); | |
| 355 | 355 | |
| 356 | 356 | const wrapperPath = yield* Effect.promise(() => |
| 357 | 357 | makeMockAgentWrapper( |
| @@ -414,10 +414,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 56 unmodified lines | ||
| 414 | 414 | const adapter = yield* CursorAdapter; |
| 415 | 415 | const serverSettings = yield* ServerSettingsService; |
| 416 | 416 | 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")); | |
| 421 | 423 | const wrapperPath = yield* Effect.promise(() => |
| 422 | 424 | makeProbeWrapper(requestLogPath, argvLogPath), |
| 423 | 425 | ); |
| @@ -470,10 +472,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 46 unmodified lines | ||
| 470 | 472 | const adapter = yield* CursorAdapter; |
| 471 | 473 | const serverSettings = yield* ServerSettingsService; |
| 472 | 474 | 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")); | |
| 477 | 481 | const wrapperPath = yield* Effect.promise(() => |
| 478 | 482 | makeProbeWrapper(requestLogPath, argvLogPath), |
| 479 | 483 | ); |
| @@ -713,10 +717,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 233 unmodified lines | ||
| 713 | 717 | const runtimeEvents: Array<ProviderRuntimeEvent> = []; |
| 714 | 718 | const settledEventTypes = new Set<string>(); |
| 715 | 719 | 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")); | |
| 720 | 726 | const wrapperPath = yield* Effect.promise(() => |
| 721 | 727 | makeProbeWrapper(requestLogPath, argvLogPath, { T3_ACP_EMIT_TOOL_CALLS: "1" }), |
| 722 | 728 | ); |
| @@ -931,10 +937,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 208 unmodified lines | ||
| 931 | 937 | const adapter = yield* CursorAdapter; |
| 932 | 938 | const serverSettings = yield* ServerSettingsService; |
| 933 | 939 | 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")); | |
| 938 | 946 | const wrapperPath = yield* Effect.promise(() => |
| 939 | 947 | makeProbeWrapper(requestLogPath, argvLogPath, { T3_ACP_EMIT_TOOL_CALLS: "1" }), |
| 940 | 948 | ); |
| @@ -1192,10 +1200,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 251 unmodified lines | ||
| 1192 | 1200 | const adapter = yield* CursorAdapter; |
| 1193 | 1201 | const serverSettings = yield* ServerSettingsService; |
| 1194 | 1202 | 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")); | |
| 1199 | 1209 | const wrapperPath = yield* Effect.promise(() => |
| 1200 | 1210 | makeProbeWrapper(requestLogPath, argvLogPath), |
| 1201 | 1211 | ); |
| @@ -1255,10 +1265,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 53 unmodified lines | ||
| 1255 | 1265 | const adapter = yield* CursorAdapter; |
| 1256 | 1266 | const serverSettings = yield* ServerSettingsService; |
| 1257 | 1267 | 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")); | |
| 1262 | 1274 | const wrapperPath = yield* Effect.promise(() => |
| 1263 | 1275 | makeProbeWrapper(requestLogPath, argvLogPath), |
| 1264 | 1276 | ); |
| @@ -1339,10 +1351,12 @@ cursorAdapterTestLayer("CursorAdapterLive", (it) => { · 74 unmodified lines | ||
| 1339 | 1351 | const adapter = yield* CursorAdapter; |
| 1340 | 1352 | const serverSettings = yield* ServerSettingsService; |
| 1341 | 1353 | 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")); | |
| 1346 | 1360 | const wrapperPath = yield* Effect.promise(() => |
| 1347 | 1361 | makeProbeWrapper(requestLogPath, argvLogPath), |
| 1348 | 1362 | ); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import * as NodeOs from "node:os"; | |
| 1 | +import * as NodeOS from "node:os"; | |
| 2 | 2 | import type { |
| 3 | 3 | CursorSettings, |
| 4 | 4 | ModelCapabilities, |
| @@ -746,7 +746,7 @@ function isCursorAboutJsonFormatUnsupported(result: CommandResult): boolean { · 741 unmodified lines | ||
| 746 | 746 | const readCursorCliConfigChannel = Effect.fn("readCursorCliConfigChannel")(function* () { |
| 747 | 747 | const fileSystem = yield* FileSystem.FileSystem; |
| 748 | 748 | 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"); | |
| 750 | 750 | const raw = yield* fileSystem.readFileString(configPath).pipe(Effect.orElseSucceed(() => "")); |
| 751 | 751 | return parseCursorCliConfigChannel(raw); |
| 752 | 752 | }); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import { ThreadId } from "@t3tools/contracts"; |
| 7 | 7 | import { assert, describe, it } from "@effect/vitest"; |
| @@ -31,8 +31,8 @@ function parseLogLine(line: string) { · 23 unmodified lines | ||
| 31 | 31 | describe("EventNdjsonLogger", () => { |
| 32 | 32 | it.effect("writes effect-style lines to thread-scoped files", () => |
| 33 | 33 | 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"); | |
| 36 | 36 | |
| 37 | 37 | try { |
| 38 | 38 | const logger = yield* makeEventNdjsonLogger(basePath, { stream: "native" }); |
| @@ -51,13 +51,13 @@ describe("EventNdjsonLogger", () => { · 12 unmodified lines | ||
| 51 | 51 | ); |
| 52 | 52 | yield* logger.close(); |
| 53 | 53 | |
| 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); | |
| 58 | 58 | |
| 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()); | |
| 61 | 61 | |
| 62 | 62 | assert.equal(Number.isNaN(Date.parse(first.observedAt)), false); |
| 63 | 63 | assert.equal(first.stream, "NTIVE"); |
| @@ -70,7 +70,7 @@ describe("EventNdjsonLogger", () => { · 6 unmodified lines | ||
| 70 | 70 | '{"type":"turn.completed","threadId":"provider-thread-2","id":"evt-2"}', |
| 71 | 71 | ); |
| 72 | 72 | } finally { |
| 73 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 73 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 74 | 74 | } |
| 75 | 75 | }), |
| 76 | 76 | ); |
| @@ -79,8 +79,8 @@ describe("EventNdjsonLogger", () => { · 2 unmodified lines | ||
| 79 | 79 | "falls back to a global segment when orchestration thread id is missing or invalid", |
| 80 | 80 | () => |
| 81 | 81 | 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"); | |
| 84 | 84 | |
| 85 | 85 | try { |
| 86 | 86 | const logger = yield* makeEventNdjsonLogger(basePath, { stream: "orchestration" }); |
| @@ -93,10 +93,9 @@ describe("EventNdjsonLogger", () => { · 6 unmodified lines | ||
| 93 | 93 | yield* logger.write({ id: "evt-invalid-thread" }, "!!!" as unknown as ThreadId); |
| 94 | 94 | yield* logger.close(); |
| 95 | 95 | |
| 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") | |
| 100 | 99 | .trim() |
| 101 | 100 | .split("\n") |
| 102 | 101 | .map((line) => parseLogLine(line)); |
| @@ -108,15 +107,15 @@ describe("EventNdjsonLogger", () => { · 5 unmodified lines | ||
| 108 | 107 | assert.equal(lines[1]?.stream, "CANON"); |
| 109 | 108 | assert.equal(lines[1]?.payload, '{"id":"evt-invalid-thread"}'); |
| 110 | 109 | } finally { |
| 111 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 110 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 112 | 111 | } |
| 113 | 112 | }), |
| 114 | 113 | ); |
| 115 | 114 | |
| 116 | 115 | it.effect("serializes concurrent first writes for the same segment", () => |
| 117 | 116 | 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"); | |
| 120 | 119 | |
| 121 | 120 | try { |
| 122 | 121 | const logger = yield* makeEventNdjsonLogger(basePath, { |
| @@ -137,10 +136,9 @@ describe("EventNdjsonLogger", () => { · 14 unmodified lines | ||
| 137 | 136 | ); |
| 138 | 137 | yield* logger.close(); |
| 139 | 138 | |
| 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") | |
| 144 | 142 | .trim() |
| 145 | 143 | .split("\n") |
| 146 | 144 | .map((line) => parseLogLine(line)); |
| @@ -151,15 +149,15 @@ describe("EventNdjsonLogger", () => { · 4 unmodified lines | ||
| 151 | 149 | '{"id":"evt-concurrent-2"}', |
| 152 | 150 | ]); |
| 153 | 151 | } finally { |
| 154 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 152 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 155 | 153 | } |
| 156 | 154 | }), |
| 157 | 155 | ); |
| 158 | 156 | |
| 159 | 157 | it.effect("rotates per-thread files when max size is exceeded", () => |
| 160 | 158 | 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"); | |
| 163 | 161 | |
| 164 | 162 | try { |
| 165 | 163 | const logger = yield* makeEventNdjsonLogger(basePath, { |
| @@ -185,8 +183,7 @@ describe("EventNdjsonLogger", () => { · 19 unmodified lines | ||
| 185 | 183 | yield* logger.close(); |
| 186 | 184 | |
| 187 | 185 | const fileStem = "thread-rotate.log"; |
| 188 | − const matchingFiles = fs | |
| 189 | − .readdirSync(tempDir) | |
| 186 | + const matchingFiles = NodeFS.readdirSync(tempDir) | |
| 190 | 187 | .filter((entry) => entry === fileStem || entry.startsWith(`${fileStem}.`)) |
| 191 | 188 | .toSorted(); |
| 192 | 189 | |
| @@ -203,7 +200,7 @@ describe("EventNdjsonLogger", () => { · 10 unmodified lines | ||
| 203 | 200 | false, |
| 204 | 201 | ); |
| 205 | 202 | } finally { |
| 206 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 203 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 207 | 204 | } |
| 208 | 205 | }), |
| 209 | 206 | ); |
| @@ -6,8 +6,8 @@ · 5 unmodified lines | ||
| 6 | 6 | * single effect-style text line in a thread-scoped file. Failures are |
| 7 | 7 | * downgraded to warnings so provider runtime behavior is unaffected. |
| 8 | 8 | */ |
| 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"; | |
| 11 | 11 | |
| 12 | 12 | import type { ThreadId } from "@t3tools/contracts"; |
| 13 | 13 | import { RotatingFileSink } from "@t3tools/shared/logging"; |
| @@ -178,7 +178,7 @@ export const makeEventNdjsonLogger = Effect.fn("makeEventNdjsonLogger")(function · 164 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | const directoryReady = yield* Effect.sync(() => { |
| 180 | 180 | try { |
| 181 | − fs.mkdirSync(path.dirname(filePath), { recursive: true }); | |
| 181 | + NodeFS.mkdirSync(NodePath.dirname(filePath), { recursive: true }); | |
| 182 | 182 | return true; |
| 183 | 183 | } catch (error) { |
| 184 | 184 | return { ok: false as const, error }; |
| @@ -211,7 +211,7 @@ export const makeEventNdjsonLogger = Effect.fn("makeEventNdjsonLogger")(function · 26 unmodified lines | ||
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | return makeThreadWriter({ |
| 214 | − filePath: path.join(path.dirname(filePath), `${threadSegment}.log`), | |
| 214 | + filePath: NodePath.join(NodePath.dirname(filePath), `${threadSegment}.log`), | |
| 215 | 215 | maxBytes, |
| 216 | 216 | maxFiles, |
| 217 | 217 | batchWindowMs, |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 8 | 8 | import { assert, it } from "@effect/vitest"; |
| @@ -26,13 +26,13 @@ import { ServerConfig } from "../../config.ts"; · 17 unmodified lines | ||
| 26 | 26 | import { makeGrokAdapter } from "./GrokAdapter.ts"; |
| 27 | 27 | const decodeGrokSettings = Schema.decodeSync(GrokSettings); |
| 28 | 28 | |
| 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"); | |
| 31 | 31 | const mockAgentCommand = process.execPath; |
| 32 | 32 | |
| 33 | 33 | 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"); | |
| 36 | 36 | const envExports = Object.entries(extraEnv ?? {}) |
| 37 | 37 | .map(([key, value]) => `export ${key}=${JSON.stringify(value)}`) |
| 38 | 38 | .join("\n"); |
| @@ -40,8 +40,8 @@ async function makeMockGrokWrapper(extraEnv?: Record<string, string>) { · 1 unmodified line | ||
| 40 | 40 | ${envExports} |
| 41 | 41 | exec ${JSON.stringify(mockAgentCommand)} ${JSON.stringify(mockAgentPath)} "$@" |
| 42 | 42 | `; |
| 43 | − await writeFile(wrapperPath, script, "utf8"); | |
| 44 | − await chmod(wrapperPath, 0o755); | |
| 43 | + await NodeFSP.writeFile(wrapperPath, script, "utf8"); | |
| 44 | + await NodeFSP.chmod(wrapperPath, 0o755); | |
| 45 | 45 | return wrapperPath; |
| 46 | 46 | } |
| 47 | 47 | |
| @@ -51,7 +51,7 @@ function waitForFileContent(filePath: string, attempts = 40): Effect.Effect<stri · 3 unmodified lines | ||
| 51 | 51 | if (remainingAttempts <= 0) { |
| 52 | 52 | return yield* Effect.die(new Error(`Timed out waiting for file content at ${filePath}`)); |
| 53 | 53 | } |
| 54 | − const raw = yield* Effect.tryPromise(() => readFile(filePath, "utf8")).pipe( | |
| 54 | + const raw = yield* Effect.tryPromise(() => NodeFSP.readFile(filePath, "utf8")).pipe( | |
| 55 | 55 | Effect.orElseSucceed(() => ""), |
| 56 | 56 | ); |
| 57 | 57 | if (raw.trim().length > 0) { |
| @@ -64,7 +64,7 @@ function waitForFileContent(filePath: string, attempts = 40): Effect.Effect<stri · 6 unmodified lines | ||
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | async function readJsonLines(filePath: string) { |
| 67 | − const raw = await readFile(filePath, "utf8"); | |
| 67 | + const raw = await NodeFSP.readFile(filePath, "utf8"); | |
| 68 | 68 | return raw |
| 69 | 69 | .split("\n") |
| 70 | 70 | .map((line) => line.trim()) |
| @@ -149,9 +149,9 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { · 78 unmodified lines | ||
| 149 | 149 | Effect.gen(function* () { |
| 150 | 150 | const threadId = ThreadId.make("grok-stop-session-close"); |
| 151 | 151 | 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-")), | |
| 153 | 153 | ); |
| 154 | − const exitLogPath = path.join(tempDir, "exit.log"); | |
| 154 | + const exitLogPath = NodePath.join(tempDir, "exit.log"); | |
| 155 | 155 | |
| 156 | 156 | const wrapperPath = yield* Effect.promise(() => |
| 157 | 157 | makeMockGrokWrapper({ |
| @@ -227,8 +227,10 @@ it.layer(grokAdapterTestLayer)("GrokAdapterLive", (it) => { · 69 unmodified lines | ||
| 227 | 227 | it.effect("responds to ACP approvals using provider-supplied option ids", () => |
| 228 | 228 | Effect.gen(function* () { |
| 229 | 229 | 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"); | |
| 232 | 234 | const wrapperPath = yield* Effect.promise(() => |
| 233 | 235 | makeMockGrokWrapper({ |
| 234 | 236 | T3_ACP_REQUEST_LOG_PATH: requestLogPath, |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import assert from "node:assert/strict"; | |
| 1 | +import * as NodeAssert from "node:assert/strict"; | |
| 2 | 2 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 3 | 3 | import { it } from "@effect/vitest"; |
| 4 | 4 | import * as Context from "effect/Context"; |
| @@ -238,11 +238,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 233 unmodified lines | ||
| 238 | 238 | runtimeMode: "full-access", |
| 239 | 239 | }); |
| 240 | 240 | |
| 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, [ | |
| 246 | 246 | `Basic ${btoa("opencode:secret-password")}`, |
| 247 | 247 | ]); |
| 248 | 248 | }), |
| @@ -259,8 +259,8 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 10 unmodified lines | ||
| 259 | 259 | |
| 260 | 260 | yield* adapter.stopSession(asThreadId("thread-opencode")); |
| 261 | 261 | |
| 262 | − assert.deepEqual(runtimeMock.state.startCalls, []); | |
| 263 | − assert.deepEqual( | |
| 262 | + NodeAssert.deepEqual(runtimeMock.state.startCalls, []); | |
| 263 | + NodeAssert.deepEqual( | |
| 264 | 264 | runtimeMock.state.abortCalls.includes("http://127.0.0.1:9999/session"), |
| 265 | 265 | true, |
| 266 | 266 | ); |
| @@ -286,7 +286,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 19 unmodified lines | ||
| 286 | 286 | yield* adapter.stopSession(threadId); |
| 287 | 287 | |
| 288 | 288 | const events = Array.from(yield* Fiber.join(eventsFiber).pipe(Effect.timeout("1 second"))); |
| 289 | − assert.deepEqual( | |
| 289 | + NodeAssert.deepEqual( | |
| 290 | 290 | events.map((event) => event.type), |
| 291 | 291 | ["session.started", "thread.started", "session.exited"], |
| 292 | 292 | ); |
| @@ -316,11 +316,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 23 unmodified lines | ||
| 316 | 316 | yield* Effect.exit(adapter.stopAll()); |
| 317 | 317 | const sessions = yield* adapter.listSessions(); |
| 318 | 318 | |
| 319 | − assert.deepEqual(runtimeMock.state.closeCalls, [ | |
| 319 | + NodeAssert.deepEqual(runtimeMock.state.closeCalls, [ | |
| 320 | 320 | "http://127.0.0.1:9999", |
| 321 | 321 | "http://127.0.0.1:9999", |
| 322 | 322 | ]); |
| 323 | − assert.deepEqual(sessions, []); | |
| 323 | + NodeAssert.deepEqual(sessions, []); | |
| 324 | 324 | }), |
| 325 | 325 | ); |
| 326 | 326 | |
| @@ -348,7 +348,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 21 unmodified lines | ||
| 348 | 348 | scopeClosed = true; |
| 349 | 349 | |
| 350 | 350 | 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); | |
| 352 | 352 | } finally { |
| 353 | 353 | if (!scopeClosed) { |
| 354 | 354 | yield* Scope.close(scope, Exit.void).pipe(Effect.ignore); |
| @@ -379,19 +379,19 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 24 unmodified lines | ||
| 379 | 379 | .pipe(Effect.flip); |
| 380 | 380 | const sessions = yield* adapter.listSessions(); |
| 381 | 381 | |
| 382 | − assert.equal(error._tag, "ProviderAdapterRequestError"); | |
| 382 | + NodeAssert.equal(error._tag, "ProviderAdapterRequestError"); | |
| 383 | 383 | if (error._tag !== "ProviderAdapterRequestError") { |
| 384 | 384 | throw new Error("Unexpected error type"); |
| 385 | 385 | } |
| 386 | − assert.equal(error.detail, "prompt failed"); | |
| 387 | − assert.equal( | |
| 386 | + NodeAssert.equal(error.detail, "prompt failed"); | |
| 387 | + NodeAssert.equal( | |
| 388 | 388 | error.message, |
| 389 | 389 | "Provider adapter request failed (opencode) for session.promptAsync: prompt failed", |
| 390 | 390 | ); |
| 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"); | |
| 395 | 395 | }), |
| 396 | 396 | ); |
| 397 | 397 | |
| @@ -424,13 +424,13 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 26 unmodified lines | ||
| 424 | 424 | model: "openai/gpt-5", |
| 425 | 425 | }, |
| 426 | 426 | }); |
| 427 | − assert.equal(String(steeredTurn.turnId), String(turn.turnId)); | |
| 427 | + NodeAssert.equal(String(steeredTurn.turnId), String(turn.turnId)); | |
| 428 | 428 | |
| 429 | 429 | const sessions = yield* adapter.listSessions(); |
| 430 | 430 | 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); | |
| 434 | 434 | }), |
| 435 | 435 | ); |
| 436 | 436 | |
| @@ -466,11 +466,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 29 unmodified lines | ||
| 466 | 466 | .pipe(Effect.flip); |
| 467 | 467 | |
| 468 | 468 | // The original turn keeps running — only the steer prompt failed. |
| 469 | − assert.equal(error._tag, "ProviderAdapterRequestError"); | |
| 469 | + NodeAssert.equal(error._tag, "ProviderAdapterRequestError"); | |
| 470 | 470 | const sessions = yield* adapter.listSessions(); |
| 471 | 471 | 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)); | |
| 474 | 474 | }), |
| 475 | 475 | ); |
| 476 | 476 | |
| @@ -508,7 +508,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 31 unmodified lines | ||
| 508 | 508 | ), |
| 509 | 509 | }); |
| 510 | 510 | |
| 511 | − assert.deepEqual(runtimeMock.state.promptCalls.at(-1), { | |
| 511 | + NodeAssert.deepEqual(runtimeMock.state.promptCalls.at(-1), { | |
| 512 | 512 | sessionID: "http://127.0.0.1:9999/session", |
| 513 | 513 | model: { |
| 514 | 514 | providerID: "anthropic", |
| @@ -552,7 +552,7 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 37 unmodified lines | ||
| 552 | 552 | input: "Fix it", |
| 553 | 553 | }); |
| 554 | 554 | |
| 555 | − assert.deepEqual(runtimeMock.state.promptCalls.at(-1), { | |
| 555 | + NodeAssert.deepEqual(runtimeMock.state.promptCalls.at(-1), { | |
| 556 | 556 | sessionID: "http://127.0.0.1:9999/session", |
| 557 | 557 | model: { |
| 558 | 558 | providerID: "anthropic", |
| @@ -596,15 +596,15 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 37 unmodified lines | ||
| 596 | 596 | }) |
| 597 | 597 | .pipe(Effect.flip); |
| 598 | 598 | |
| 599 | − assert.equal(error._tag, "ProviderAdapterValidationError"); | |
| 599 | + NodeAssert.equal(error._tag, "ProviderAdapterValidationError"); | |
| 600 | 600 | if (error._tag !== "ProviderAdapterValidationError") { |
| 601 | 601 | throw new Error("Unexpected error type"); |
| 602 | 602 | } |
| 603 | − assert.equal( | |
| 603 | + NodeAssert.equal( | |
| 604 | 604 | error.issue, |
| 605 | 605 | "OpenCode model selection is bound to instance 'opencode', expected 'opencode_zen'.", |
| 606 | 606 | ); |
| 607 | − assert.deepEqual(runtimeMock.state.promptCalls, []); | |
| 607 | + NodeAssert.deepEqual(runtimeMock.state.promptCalls, []); | |
| 608 | 608 | }).pipe(Effect.provide(adapterLayer)); |
| 609 | 609 | }); |
| 610 | 610 | |
| @@ -631,10 +631,10 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 20 unmodified lines | ||
| 631 | 631 | |
| 632 | 632 | const snapshot = yield* adapter.rollbackThread(threadId, 2); |
| 633 | 633 | |
| 634 | − assert.deepEqual(runtimeMock.state.revertCalls, [ | |
| 634 | + NodeAssert.deepEqual(runtimeMock.state.revertCalls, [ | |
| 635 | 635 | { sessionID: "http://127.0.0.1:9999/session" }, |
| 636 | 636 | ]); |
| 637 | − assert.deepEqual(snapshot.turns, []); | |
| 637 | + NodeAssert.deepEqual(snapshot.turns, []); | |
| 638 | 638 | }), |
| 639 | 639 | ); |
| 640 | 640 | |
| @@ -644,11 +644,11 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 3 unmodified lines | ||
| 644 | 644 | const overlapDelta = appendOpenCodeAssistantTextDelta(firstUpdate.latestText, "lo world"); |
| 645 | 645 | const secondUpdate = mergeOpenCodeAssistantText(overlapDelta.nextText, "Hellolo world"); |
| 646 | 646 | |
| 647 | − assert.deepEqual( | |
| 647 | + NodeAssert.deepEqual( | |
| 648 | 648 | [firstUpdate.deltaToEmit, overlapDelta.deltaToEmit, secondUpdate.deltaToEmit], |
| 649 | 649 | ["Hello", "lo world", ""], |
| 650 | 650 | ); |
| 651 | − assert.equal(secondUpdate.latestText, "Hellolo world"); | |
| 651 | + NodeAssert.equal(secondUpdate.latestText, "Hellolo world"); | |
| 652 | 652 | }), |
| 653 | 653 | ); |
| 654 | 654 | |
| @@ -721,14 +721,14 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 66 unmodified lines | ||
| 721 | 721 | |
| 722 | 722 | const events = Array.from(yield* Fiber.join(eventsFiber).pipe(Effect.timeout("1 second"))); |
| 723 | 723 | const deltas = events.filter((event) => event.type === "content.delta"); |
| 724 | − assert.deepEqual( | |
| 724 | + NodeAssert.deepEqual( | |
| 725 | 725 | deltas.map((event) => (event.type === "content.delta" ? event.payload.delta : "")), |
| 726 | 726 | ["A B", "Bonus"], |
| 727 | 727 | ); |
| 728 | − assert.equal(events.at(-1)?.type, "item.completed"); | |
| 728 | + NodeAssert.equal(events.at(-1)?.type, "item.completed"); | |
| 729 | 729 | const completed = events.at(-1); |
| 730 | 730 | if (completed?.type === "item.completed") { |
| 731 | − assert.equal(completed.payload.detail, "A BBonus"); | |
| 731 | + NodeAssert.equal(completed.payload.detail, "A BBonus"); | |
| 732 | 732 | } |
| 733 | 733 | }), |
| 734 | 734 | ); |
| @@ -820,27 +820,27 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 85 unmodified lines | ||
| 820 | 820 | return started; |
| 821 | 821 | }).pipe(Effect.provide(adapterLayer)); |
| 822 | 822 | |
| 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( | |
| 826 | 826 | nativeEvents.some((record) => record.event?.provider === "opencode"), |
| 827 | 827 | true, |
| 828 | 828 | ); |
| 829 | − assert.equal( | |
| 829 | + NodeAssert.equal( | |
| 830 | 830 | nativeEvents.some( |
| 831 | 831 | (record) => record.event?.providerThreadId === "http://127.0.0.1:9999/session", |
| 832 | 832 | ), |
| 833 | 833 | true, |
| 834 | 834 | ); |
| 835 | − assert.equal( | |
| 835 | + NodeAssert.equal( | |
| 836 | 836 | nativeEvents.some((record) => record.event?.threadId === "thread-native-log"), |
| 837 | 837 | true, |
| 838 | 838 | ); |
| 839 | − assert.equal( | |
| 839 | + NodeAssert.equal( | |
| 840 | 840 | nativeEvents.some((record) => record.event?.type === "message.updated"), |
| 841 | 841 | true, |
| 842 | 842 | ); |
| 843 | − assert.equal( | |
| 843 | + NodeAssert.equal( | |
| 844 | 844 | nativeThreadIds.every((threadId) => threadId === "thread-native-log"), |
| 845 | 845 | true, |
| 846 | 846 | ); |
| @@ -911,9 +911,9 @@ it.layer(OpenCodeAdapterTestLayer)("OpenCodeAdapterLive", (it) => { · 64 unmodified lines | ||
| 911 | 911 | }; |
| 912 | 912 | }).pipe(Effect.provide(adapterLayer)); |
| 913 | 913 | |
| 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, []); | |
| 917 | 917 | }), |
| 918 | 918 | ); |
| 919 | 919 | }); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import assert from "node:assert/strict"; | |
| 1 | +import * as NodeAssert from "node:assert/strict"; | |
| 2 | 2 | |
| 3 | 3 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 4 | 4 | import { it } from "@effect/vitest"; |
| @@ -122,9 +122,12 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 117 unmodified lines | ||
| 122 | 122 | runtimeMock.state.runVersionError = new Error("spawn opencode ENOENT"); |
| 123 | 123 | const snapshot = yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd()); |
| 124 | 124 | |
| 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 | + ); | |
| 128 | 131 | }), |
| 129 | 132 | ); |
| 130 | 133 | |
| @@ -133,9 +136,9 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 2 unmodified lines | ||
| 133 | 136 | runtimeMock.state.runVersionError = new Error("An error occurred in Effect.tryPromise"); |
| 134 | 137 | const snapshot = yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd()); |
| 135 | 138 | |
| 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."); | |
| 139 | 142 | }), |
| 140 | 143 | ); |
| 141 | 144 | |
| @@ -174,20 +177,20 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 32 unmodified lines | ||
| 174 | 177 | const snapshot = yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd()); |
| 175 | 178 | const model = snapshot.models.find((entry) => entry.slug === "openai/gpt-5.4"); |
| 176 | 179 | |
| 177 | − assert.ok(model); | |
| 180 | + NodeAssert.ok(model); | |
| 178 | 181 | const variantDescriptor = model.capabilities?.optionDescriptors?.find( |
| 179 | 182 | (descriptor) => descriptor.id === "variant" && descriptor.type === "select", |
| 180 | 183 | ); |
| 181 | − assert.ok(variantDescriptor && variantDescriptor.type === "select"); | |
| 182 | − assert.equal( | |
| 184 | + NodeAssert.ok(variantDescriptor && variantDescriptor.type === "select"); | |
| 185 | + NodeAssert.equal( | |
| 183 | 186 | variantDescriptor.options.find((option) => option.isDefault === true)?.id, |
| 184 | 187 | "medium", |
| 185 | 188 | ); |
| 186 | 189 | const agentDescriptor = model.capabilities?.optionDescriptors?.find( |
| 187 | 190 | (descriptor) => descriptor.id === "agent" && descriptor.type === "select", |
| 188 | 191 | ); |
| 189 | − assert.ok(agentDescriptor && agentDescriptor.type === "select"); | |
| 190 | − assert.equal( | |
| 192 | + NodeAssert.ok(agentDescriptor && agentDescriptor.type === "select"); | |
| 193 | + NodeAssert.equal( | |
| 191 | 194 | agentDescriptor.options.find((option) => option.isDefault === true)?.id, |
| 192 | 195 | "build", |
| 193 | 196 | ); |
| @@ -198,7 +201,7 @@ it.layer(testLayer)("checkOpenCodeProviderStatus", (it) => { · 4 unmodified lines | ||
| 198 | 201 | Effect.gen(function* () { |
| 199 | 202 | yield* checkOpenCodeProviderStatus(makeOpenCodeSettings(), process.cwd()); |
| 200 | 203 | |
| 201 | − assert.equal(runtimeMock.state.closeCalls, 1); | |
| 204 | + NodeAssert.equal(runtimeMock.state.closeCalls, 1); | |
| 202 | 205 | }), |
| 203 | 206 | ); |
| 204 | 207 | }); |
| @@ -215,9 +218,9 @@ it.layer(testLayer)("checkOpenCodeProviderStatus with configured server URL", (i · 10 unmodified lines | ||
| 215 | 218 | process.cwd(), |
| 216 | 219 | ); |
| 217 | 220 | |
| 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( | |
| 221 | 224 | snapshot.message, |
| 222 | 225 | "OpenCode server rejected authentication. Check the server URL and password.", |
| 223 | 226 | ); |
| @@ -237,9 +240,9 @@ it.layer(testLayer)("checkOpenCodeProviderStatus with configured server URL", (i · 13 unmodified lines | ||
| 237 | 240 | process.cwd(), |
| 238 | 241 | ); |
| 239 | 242 | |
| 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( | |
| 243 | 246 | snapshot.message, |
| 244 | 247 | "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.", |
| 245 | 248 | ); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import type { |
| 7 | 7 | ProviderApprovalDecision, |
| @@ -644,8 +644,8 @@ it.effect("ProviderServiceLive writes canonical events to the emitting thread se · 636 unmodified lines | ||
| 644 | 644 | |
| 645 | 645 | it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", () => |
| 646 | 646 | 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"); | |
| 649 | 649 | |
| 650 | 650 | const codex = makeFakeCodexAdapter(); |
| 651 | 651 | const registry = makeAdapterRegistryMock({ |
| @@ -706,7 +706,7 @@ it.effect("ProviderServiceLive keeps persisted resumable sessions on startup", ( · 54 unmodified lines | ||
| 706 | 706 | }).pipe(Effect.provide(persistenceLayer)); |
| 707 | 707 | assert.equal(legacyTableRows.length, 0); |
| 708 | 708 | |
| 709 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 709 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 710 | 710 | }).pipe(Effect.provide(NodeServices.layer)), |
| 711 | 711 | ); |
| 712 | 712 | |
| @@ -714,8 +714,10 @@ it.effect( · 1 unmodified line | ||
| 714 | 714 | "ProviderServiceLive restores rollback routing after restart using persisted thread mapping", |
| 715 | 715 | () => |
| 716 | 716 | 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"); | |
| 719 | 721 | const persistenceLayer = makeSqlitePersistenceLive(dbPath); |
| 720 | 722 | const runtimeRepositoryLayer = ProviderSessionRuntime.layer.pipe( |
| 721 | 723 | Layer.provide(persistenceLayer), |
| @@ -834,7 +836,7 @@ it.effect( · 112 unmodified lines | ||
| 834 | 836 | assert.equal(typeof rollbackCall?.[0], "string"); |
| 835 | 837 | assert.equal(rollbackCall?.[1], 1); |
| 836 | 838 | |
| 837 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 839 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 838 | 840 | }).pipe(Effect.provide(NodeServices.layer)), |
| 839 | 841 | ); |
| 840 | 842 | |
| @@ -1283,8 +1285,10 @@ routing.layer("ProviderServiceLive routing", (it) => { · 442 unmodified lines | ||
| 1283 | 1285 | |
| 1284 | 1286 | it.effect("reuses persisted resume cursor when startSession is called after a restart", () => |
| 1285 | 1287 | 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"); | |
| 1288 | 1292 | const persistenceLayer = makeSqlitePersistenceLive(dbPath); |
| 1289 | 1293 | const runtimeRepositoryLayer = ProviderSessionRuntime.layer.pipe( |
| 1290 | 1294 | Layer.provide(persistenceLayer), |
| @@ -1379,7 +1383,7 @@ routing.layer("ProviderServiceLive routing", (it) => { · 88 unmodified lines | ||
| 1379 | 1383 | assert.equal(startPayload.threadId, initial.threadId); |
| 1380 | 1384 | } |
| 1381 | 1385 | |
| 1382 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 1386 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 1383 | 1387 | }).pipe(Effect.provide(NodeServices.layer)), |
| 1384 | 1388 | ); |
| 1385 | 1389 | |
| @@ -1387,8 +1391,10 @@ routing.layer("ProviderServiceLive routing", (it) => { · 1 unmodified line | ||
| 1387 | 1391 | "reuses persisted cwd when startSession resumes a claude session without cwd input", |
| 1388 | 1392 | () => |
| 1389 | 1393 | 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"); | |
| 1392 | 1398 | const persistenceLayer = makeSqlitePersistenceLive(dbPath); |
| 1393 | 1399 | const runtimeRepositoryLayer = ProviderSessionRuntime.layer.pipe( |
| 1394 | 1400 | Layer.provide(persistenceLayer), |
| @@ -1477,7 +1483,7 @@ routing.layer("ProviderServiceLive routing", (it) => { · 82 unmodified lines | ||
| 1477 | 1483 | assert.equal(startPayload.threadId, initial.threadId); |
| 1478 | 1484 | } |
| 1479 | 1485 | |
| 1480 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 1486 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 1481 | 1487 | }).pipe(Effect.provide(NodeServices.layer)), |
| 1482 | 1488 | ); |
| 1483 | 1489 | }); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | // @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"; | |
| 5 | 5 | |
| 6 | 6 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 7 | 7 | import { ProviderDriverKind, ThreadId } from "@t3tools/contracts"; |
| @@ -229,8 +229,8 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL · 221 unmodified lines | ||
| 229 | 229 | |
| 230 | 230 | it("rehydrates persisted mappings across layer restart", () => |
| 231 | 231 | 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"); | |
| 234 | 234 | const directoryLayer = makeDirectoryLayer(makeSqlitePersistenceLive(dbPath)); |
| 235 | 235 | |
| 236 | 236 | const threadId = ThreadId.make("thread-restart"); |
| @@ -266,6 +266,6 @@ it.layer(makeDirectoryLayer(SqlitePersistenceMemory))("ProviderSessionDirectoryL · 29 unmodified lines | ||
| 266 | 266 | assert.equal(legacyTableRows.length, 0); |
| 267 | 267 | }).pipe(Effect.provide(directoryLayer)); |
| 268 | 268 | |
| 269 | − fs.rmSync(tempDir, { recursive: true, force: true }); | |
| 269 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 270 | 270 | })); |
| 271 | 271 | }); |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 8 | 8 | import { it } from "@effect/vitest"; |
| @@ -13,8 +13,8 @@ import { describe, expect } from "vite-plus/test"; · 4 unmodified lines | ||
| 13 | 13 | import * as AcpSessionRuntime from "./AcpSessionRuntime.ts"; |
| 14 | 14 | import type * as EffectAcpProtocol from "effect-acp/protocol"; |
| 15 | 15 | |
| 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"); | |
| 18 | 18 | const mockAgentCommand = "node"; |
| 19 | 19 | const mockAgentArgs = [mockAgentPath]; |
| 20 | 20 | |
| @@ -347,8 +347,8 @@ describe("AcpSessionRuntime", () => { · 326 unmodified lines | ||
| 347 | 347 | }); |
| 348 | 348 | |
| 349 | 349 | 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"); | |
| 352 | 352 | return Effect.gen(function* () { |
| 353 | 353 | const runtime = yield* AcpSessionRuntime.AcpSessionRuntime; |
| 354 | 354 | yield* runtime.start(); |
| @@ -363,7 +363,7 @@ describe("AcpSessionRuntime", () => { · 8 unmodified lines | ||
| 363 | 363 | expect(error.message).toContain("composer-2[fast=true]"); |
| 364 | 364 | } |
| 365 | 365 | |
| 366 | − const recordedRequests = readFileSync(requestLogPath, "utf8") | |
| 366 | + const recordedRequests = NodeFS.readFileSync(requestLogPath, "utf8") | |
| 367 | 367 | .trim() |
| 368 | 368 | .split("\n") |
| 369 | 369 | .filter((line) => line.length > 0) |
| @@ -392,7 +392,7 @@ describe("AcpSessionRuntime", () => { · 22 unmodified lines | ||
| 392 | 392 | ), |
| 393 | 393 | Effect.scoped, |
| 394 | 394 | 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 }))), | |
| 396 | 396 | ); |
| 397 | 397 | }); |
| 398 | 398 | }); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import { pathToFileURL } from "node:url"; | |
| 1 | +import * as NodeURL from "node:url"; | |
| 2 | 2 | |
| 3 | 3 | import type { ChatAttachment, ProviderApprovalDecision, RuntimeMode } from "@t3tools/contracts"; |
| 4 | 4 | import { |
| @@ -206,7 +206,7 @@ export function toOpenCodeFileParts(input: { · 201 unmodified lines | ||
| 206 | 206 | type: "file", |
| 207 | 207 | mime: attachment.mimeType, |
| 208 | 208 | filename: attachment.name, |
| 209 | − url: pathToFileURL(attachmentPath).href, | |
| 209 | + url: NodeURL.pathToFileURL(attachmentPath).href, | |
| 210 | 210 | }); |
| 211 | 211 | } |
| 212 | 212 | |
| @@ -1,9 +1,9 @@ | ||
| 1 | 1 | // @effect-diagnostics nodeBuiltinImport:off |
| 2 | 2 | import { expect, it } from "@effect/vitest"; |
| 3 | −import { chmodSync, mkdirSync, symlinkSync, writeFileSync } from "node:fs"; | |
| 3 | +import * as NodeFS from "node:fs"; | |
| 4 | 4 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 5 | 5 | import * as NodeOS from "node:os"; |
| 6 | −import path from "node:path"; | |
| 6 | +import * as NodePath from "node:path"; | |
| 7 | 7 | import { ProviderDriverKind, ProviderInstanceId, type ServerProvider } from "@t3tools/contracts"; |
| 8 | 8 | import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; |
| 9 | 9 | import * as Crypto from "effect/Crypto"; |
| @@ -25,7 +25,7 @@ const driver = (value: string) => ProviderDriverKind.make(value); · 15 unmodified lines | ||
| 25 | 25 | const makeTempDir = (name: string) => |
| 26 | 26 | Crypto.Crypto.pipe( |
| 27 | 27 | 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}`)), | |
| 29 | 29 | ); |
| 30 | 30 | const isNativeTestCommandPath = |
| 31 | 31 | (expectedPathSegment: string) => |
| @@ -203,11 +203,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 171 unmodified lines | ||
| 203 | 203 | () => |
| 204 | 204 | Effect.gen(function* () { |
| 205 | 205 | 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); | |
| 211 | 211 | |
| 212 | 212 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect( |
| 213 | 213 | packageToolUpdate, |
| @@ -240,9 +240,9 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 26 unmodified lines | ||
| 240 | 240 | () => |
| 241 | 241 | Effect.gen(function* () { |
| 242 | 242 | 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"); | |
| 246 | 246 | |
| 247 | 247 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect( |
| 248 | 248 | nativePackageToolUpdate, |
| @@ -276,11 +276,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 27 unmodified lines | ||
| 276 | 276 | () => |
| 277 | 277 | Effect.gen(function* () { |
| 278 | 278 | 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); | |
| 284 | 284 | |
| 285 | 285 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect( |
| 286 | 286 | scopedPackageToolUpdate, |
| @@ -336,11 +336,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 49 unmodified lines | ||
| 336 | 336 | () => |
| 337 | 337 | Effect.gen(function* () { |
| 338 | 338 | 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); | |
| 344 | 344 | |
| 345 | 345 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect( |
| 346 | 346 | nativePackageToolUpdate, |
| @@ -373,11 +373,11 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 26 unmodified lines | ||
| 373 | 373 | () => |
| 374 | 374 | Effect.gen(function* () { |
| 375 | 375 | 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); | |
| 381 | 381 | |
| 382 | 382 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect( |
| 383 | 383 | scopedPackageToolUpdate, |
| @@ -454,8 +454,8 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 70 unmodified lines | ||
| 454 | 454 | it.effect("keeps npm updates for binaries symlinked into npm's global node_modules tree", () => |
| 455 | 455 | Effect.gen(function* () { |
| 456 | 456 | 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( | |
| 459 | 459 | tempDir, |
| 460 | 460 | "lib", |
| 461 | 461 | "node_modules", |
| @@ -463,13 +463,13 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 1 unmodified line | ||
| 463 | 463 | "package-tool", |
| 464 | 464 | "bin", |
| 465 | 465 | ); |
| 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); | |
| 473 | 473 | |
| 474 | 474 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(packageToolUpdate, { |
| 475 | 475 | binaryPath: symlinkPath, |
| @@ -497,8 +497,8 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 21 unmodified lines | ||
| 497 | 497 | it.effect("uses Effect FileSystem realPath when detecting pnpm global symlinks", () => |
| 498 | 498 | Effect.gen(function* () { |
| 499 | 499 | 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( | |
| 502 | 502 | tempDir, |
| 503 | 503 | ".local", |
| 504 | 504 | "share", |
| @@ -510,13 +510,13 @@ it.layer(NodeServices.layer)("providerMaintenance", (it) => { · 5 unmodified lines | ||
| 510 | 510 | "package-tool", |
| 511 | 511 | "bin", |
| 512 | 512 | ); |
| 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); | |
| 520 | 520 | |
| 521 | 521 | const capabilities = yield* resolveProviderMaintenanceCapabilitiesEffect(packageToolUpdate, { |
| 522 | 522 | binaryPath: symlinkPath, |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import { generateKeyPairSync } from "node:crypto"; | |
| 1 | +import * as NodeCrypto from "node:crypto"; | |
| 2 | 2 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 3 | 3 | |
| 4 | 4 | import type { |
| @@ -348,7 +348,7 @@ describe.sequential("signRelayAgentActivityPublishProof", () => { · 343 unmodified lines | ||
| 348 | 348 | }); |
| 349 | 349 | |
| 350 | 350 | it("signs the activity publish JWT and rejects tampering", async () => { |
| 351 | − const keyPair = generateKeyPairSync("ed25519", { | |
| 351 | + const keyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 352 | 352 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 353 | 353 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 354 | 354 | }); |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | import * as NodeHttpServer from "@effect/platform-node/NodeHttpServer"; |
| 2 | 2 | import * as NodeSocket from "@effect/platform-node/NodeSocket"; |
| 3 | 3 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 4 | −import { generateKeyPairSync, type KeyObject, sign } from "node:crypto"; | |
| 4 | +import * as NodeCrypto from "node:crypto"; | |
| 5 | 5 | |
| 6 | 6 | import { |
| 7 | 7 | AuthAccessTokenType, |
| @@ -950,14 +950,14 @@ const makeDpopProof = (input: { · 942 unmodified lines | ||
| 950 | 950 | readonly iat: number; |
| 951 | 951 | readonly accessToken?: string; |
| 952 | 952 | readonly jti?: string; |
| 953 | − readonly privateKey?: KeyObject; | |
| 953 | + readonly privateKey?: NodeCrypto.KeyObject; | |
| 954 | 954 | readonly publicJwk?: DpopPublicJwk; |
| 955 | 955 | }) => { |
| 956 | 956 | const keyPair = |
| 957 | 957 | input.privateKey && input.publicJwk |
| 958 | 958 | ? { privateKey: input.privateKey, publicJwk: input.publicJwk } |
| 959 | 959 | : (() => { |
| 960 | − const { privateKey, publicKey } = generateKeyPairSync("ec", { | |
| 960 | + const { privateKey, publicKey } = NodeCrypto.generateKeyPairSync("ec", { | |
| 961 | 961 | namedCurve: "P-256", |
| 962 | 962 | }); |
| 963 | 963 | return { privateKey, publicJwk: publicKey.export({ format: "jwk" }) as DpopPublicJwk }; |
| @@ -978,7 +978,7 @@ const makeDpopProof = (input: { · 14 unmodified lines | ||
| 978 | 978 | ...(input.accessToken ? { ath: computeDpopAccessTokenHash(input.accessToken) } : {}), |
| 979 | 979 | }), |
| 980 | 980 | ).toString("base64url"); |
| 981 | − const signature = sign("sha256", Buffer.from(`${header}.${payload}`), { | |
| 981 | + const signature = NodeCrypto.sign("sha256", Buffer.from(`${header}.${payload}`), { | |
| 982 | 982 | key: keyPair.privateKey, |
| 983 | 983 | dsaEncoding: "ieee-p1363", |
| 984 | 984 | }).toString("base64url"); |
| @@ -1024,7 +1024,7 @@ const makeCloudMintCredentialRequest = (input: { · 39 unmodified lines | ||
| 1024 | 1024 | const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url"); |
| 1025 | 1025 | const signingInput = `${header}.${encodedPayload}`; |
| 1026 | 1026 | 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")}`, | |
| 1028 | 1028 | }; |
| 1029 | 1029 | }; |
| 1030 | 1030 | |
| @@ -1057,7 +1057,7 @@ const makeCloudEnvironmentHealthRequest = (input: { · 26 unmodified lines | ||
| 1057 | 1057 | const encodedPayload = Buffer.from(JSON.stringify(payload)).toString("base64url"); |
| 1058 | 1058 | const signingInput = `${header}.${encodedPayload}`; |
| 1059 | 1059 | 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")}`, | |
| 1061 | 1061 | }; |
| 1062 | 1062 | }; |
| 1063 | 1063 | |
| @@ -2054,7 +2054,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 990 unmodified lines | ||
| 2054 | 2054 | Effect.gen(function* () { |
| 2055 | 2055 | yield* buildAppUnderTest(); |
| 2056 | 2056 | |
| 2057 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2057 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2058 | 2058 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2059 | 2059 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2060 | 2060 | }); |
| @@ -2131,7 +2131,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 70 unmodified lines | ||
| 2131 | 2131 | Effect.gen(function* () { |
| 2132 | 2132 | yield* buildAppUnderTest(); |
| 2133 | 2133 | |
| 2134 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2134 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2135 | 2135 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2136 | 2136 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2137 | 2137 | }); |
| @@ -2174,7 +2174,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 36 unmodified lines | ||
| 2174 | 2174 | Effect.gen(function* () { |
| 2175 | 2175 | yield* buildAppUnderTest(); |
| 2176 | 2176 | |
| 2177 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2177 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2178 | 2178 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2179 | 2179 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2180 | 2180 | }); |
| @@ -2268,7 +2268,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 87 unmodified lines | ||
| 2268 | 2268 | }, |
| 2269 | 2269 | }); |
| 2270 | 2270 | |
| 2271 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2271 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2272 | 2272 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2273 | 2273 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2274 | 2274 | }); |
| @@ -2345,7 +2345,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 70 unmodified lines | ||
| 2345 | 2345 | Effect.gen(function* () { |
| 2346 | 2346 | yield* buildAppUnderTest(); |
| 2347 | 2347 | |
| 2348 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2348 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2349 | 2349 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2350 | 2350 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2351 | 2351 | }); |
| @@ -2404,7 +2404,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 52 unmodified lines | ||
| 2404 | 2404 | Effect.gen(function* () { |
| 2405 | 2405 | yield* buildAppUnderTest(); |
| 2406 | 2406 | |
| 2407 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2407 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2408 | 2408 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2409 | 2409 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2410 | 2410 | }); |
| @@ -2463,7 +2463,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 52 unmodified lines | ||
| 2463 | 2463 | Effect.gen(function* () { |
| 2464 | 2464 | yield* buildAppUnderTest(); |
| 2465 | 2465 | |
| 2466 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2466 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2467 | 2467 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2468 | 2468 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2469 | 2469 | }); |
| @@ -2523,7 +2523,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 53 unmodified lines | ||
| 2523 | 2523 | Effect.gen(function* () { |
| 2524 | 2524 | yield* buildAppUnderTest(); |
| 2525 | 2525 | |
| 2526 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2526 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2527 | 2527 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2528 | 2528 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2529 | 2529 | }); |
| @@ -2584,7 +2584,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 54 unmodified lines | ||
| 2584 | 2584 | Effect.gen(function* () { |
| 2585 | 2585 | yield* buildAppUnderTest(); |
| 2586 | 2586 | |
| 2587 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2587 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2588 | 2588 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2589 | 2589 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2590 | 2590 | }); |
| @@ -2664,7 +2664,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 73 unmodified lines | ||
| 2664 | 2664 | }, |
| 2665 | 2665 | }); |
| 2666 | 2666 | |
| 2667 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2667 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2668 | 2668 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2669 | 2669 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2670 | 2670 | }); |
| @@ -2733,7 +2733,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 62 unmodified lines | ||
| 2733 | 2733 | Effect.gen(function* () { |
| 2734 | 2734 | yield* buildAppUnderTest(); |
| 2735 | 2735 | |
| 2736 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2736 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2737 | 2737 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2738 | 2738 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2739 | 2739 | }); |
| @@ -2800,7 +2800,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 60 unmodified lines | ||
| 2800 | 2800 | Effect.gen(function* () { |
| 2801 | 2801 | yield* buildAppUnderTest(); |
| 2802 | 2802 | |
| 2803 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2803 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2804 | 2804 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2805 | 2805 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2806 | 2806 | }); |
| @@ -2851,7 +2851,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 44 unmodified lines | ||
| 2851 | 2851 | Effect.gen(function* () { |
| 2852 | 2852 | yield* buildAppUnderTest(); |
| 2853 | 2853 | |
| 2854 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2854 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2855 | 2855 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2856 | 2856 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2857 | 2857 | }); |
| @@ -2902,7 +2902,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 44 unmodified lines | ||
| 2902 | 2902 | Effect.gen(function* () { |
| 2903 | 2903 | yield* buildAppUnderTest(); |
| 2904 | 2904 | |
| 2905 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2905 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2906 | 2906 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2907 | 2907 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2908 | 2908 | }); |
| @@ -2967,7 +2967,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 58 unmodified lines | ||
| 2967 | 2967 | Effect.gen(function* () { |
| 2968 | 2968 | yield* buildAppUnderTest(); |
| 2969 | 2969 | |
| 2970 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 2970 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 2971 | 2971 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 2972 | 2972 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 2973 | 2973 | }); |
| @@ -3017,7 +3017,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => { · 43 unmodified lines | ||
| 3017 | 3017 | Effect.gen(function* () { |
| 3018 | 3018 | yield* buildAppUnderTest(); |
| 3019 | 3019 | |
| 3020 | − const cloudKeyPair = generateKeyPairSync("ed25519", { | |
| 3020 | + const cloudKeyPair = NodeCrypto.generateKeyPairSync("ed25519", { | |
| 3021 | 3021 | privateKeyEncoding: { format: "pem", type: "pkcs8" }, |
| 3022 | 3022 | publicKeyEncoding: { format: "pem", type: "spki" }, |
| 3023 | 3023 | }); |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import { createRequire } from "node:module"; | |
| 1 | +import * as NodeModule from "node:module"; | |
| 2 | 2 | |
| 3 | 3 | import * as Effect from "effect/Effect"; |
| 4 | 4 | import * as FileSystem from "effect/FileSystem"; |
| @@ -11,7 +11,7 @@ import * as PtyAdapter from "./PtyAdapter.ts"; · 6 unmodified lines | ||
| 11 | 11 | let didEnsureSpawnHelperExecutable = false; |
| 12 | 12 | |
| 13 | 13 | const resolveNodePtySpawnHelperPath = Effect.gen(function* () { |
| 14 | − const requireForNodePty = createRequire(import.meta.url); | |
| 14 | + const requireForNodePty = NodeModule.createRequire(import.meta.url); | |
| 15 | 15 | const path = yield* Path.Path; |
| 16 | 16 | const fs = yield* FileSystem.FileSystem; |
| 17 | 17 | const platform = yield* HostProcessPlatform; |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 8 | 8 | import { it } from "@effect/vitest"; |
| @@ -21,8 +21,8 @@ import * as TextGeneration from "./TextGeneration.ts"; · 12 unmodified lines | ||
| 21 | 21 | import { makeCursorTextGeneration } from "./CursorTextGeneration.ts"; |
| 22 | 22 | const decodeCursorSettings = Schema.decodeSync(CursorSettings); |
| 23 | 23 | |
| 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"); | |
| 26 | 26 | |
| 27 | 27 | function shellSingleQuote(value: string): string { |
| 28 | 28 | return `'${value.replaceAll("'", `'"'"'`)}'`; |
| @@ -33,10 +33,10 @@ const CursorTextGenerationTestLayer = ServerConfig.ServerConfig.layerTest(proces · 4 unmodified lines | ||
| 33 | 33 | }).pipe(Layer.provideMerge(NodeServices.layer)); |
| 34 | 34 | |
| 35 | 35 | 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( | |
| 40 | 40 | agentPath, |
| 41 | 41 | [ |
| 42 | 42 | "#!/bin/sh", |
| @@ -50,7 +50,7 @@ function makeAcpAgentWrapper(dir: string, env: Record<string, string>): string { · 7 unmodified lines | ||
| 50 | 50 | ].join("\n"), |
| 51 | 51 | "utf8", |
| 52 | 52 | ); |
| 53 | − chmodSync(agentPath, 0o755); | |
| 53 | + NodeFS.chmodSync(agentPath, 0o755); | |
| 54 | 54 | return agentPath; |
| 55 | 55 | } |
| 56 | 56 | |
| @@ -59,10 +59,10 @@ function withFakeAcpAgent<A, E, R>( · 2 unmodified lines | ||
| 59 | 59 | effectFn: (textGeneration: TextGeneration.TextGeneration["Service"]) => Effect.Effect<A, E, R>, |
| 60 | 60 | ) { |
| 61 | 61 | 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-")); | |
| 63 | 63 | yield* Effect.addFinalizer(() => |
| 64 | 64 | Effect.sync(() => { |
| 65 | − rmSync(tempDir, { recursive: true, force: true }); | |
| 65 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 66 | 66 | }), |
| 67 | 67 | ); |
| 68 | 68 | const agentPath = makeAcpAgentWrapper(tempDir, env); |
| @@ -76,7 +76,7 @@ function waitForFileContent(path: string): Effect.Effect<string> { · 7 unmodified lines | ||
| 76 | 76 | return Effect.gen(function* () { |
| 77 | 77 | const deadline = (yield* Clock.currentTimeMillis) + 5_000; |
| 78 | 78 | for (;;) { |
| 79 | − const result = yield* Effect.exit(Effect.sync(() => readFileSync(path, "utf8"))); | |
| 79 | + const result = yield* Effect.exit(Effect.sync(() => NodeFS.readFileSync(path, "utf8"))); | |
| 80 | 80 | if (Exit.isSuccess(result)) { |
| 81 | 81 | return result.value; |
| 82 | 82 | } |
| @@ -92,8 +92,10 @@ function waitForFileContent(path: string): Effect.Effect<string> { · 9 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { |
| 94 | 94 | 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"); | |
| 97 | 99 | |
| 98 | 100 | return withFakeAcpAgent( |
| 99 | 101 | { |
| @@ -123,7 +125,7 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 23 unmodified lines | ||
| 123 | 125 | expect(generated.subject).toBe("Add generated commit message"); |
| 124 | 126 | expect(generated.body).toBe("- verify cursor acp model config path"); |
| 125 | 127 | |
| 126 | − const requests = readFileSync(requestLogPath, "utf8") | |
| 128 | + const requests = NodeFS.readFileSync(requestLogPath, "utf8") | |
| 127 | 129 | .trim() |
| 128 | 130 | .split("\n") |
| 129 | 131 | .filter((line) => line.length > 0) |
| @@ -181,7 +183,7 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 51 unmodified lines | ||
| 181 | 183 | ]), |
| 182 | 184 | ); |
| 183 | 185 | |
| 184 | − rmSync(requestLogDir, { recursive: true, force: true }); | |
| 186 | + NodeFS.rmSync(requestLogDir, { recursive: true, force: true }); | |
| 185 | 187 | }), |
| 186 | 188 | ); |
| 187 | 189 | }); |
| @@ -235,8 +237,10 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 47 unmodified lines | ||
| 235 | 237 | ); |
| 236 | 238 | |
| 237 | 239 | 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"); | |
| 240 | 244 | |
| 241 | 245 | return withFakeAcpAgent( |
| 242 | 246 | { |
| @@ -265,7 +269,7 @@ it.layer(CursorTextGenerationTestLayer)("CursorTextGeneration", (it) => { · 22 unmodified lines | ||
| 265 | 269 | const exitLog = yield* waitForFileContent(exitLogPath); |
| 266 | 270 | expect(exitLog).toContain("exit:0"); |
| 267 | 271 | |
| 268 | − rmSync(exitLogDir, { recursive: true, force: true }); | |
| 272 | + NodeFS.rmSync(exitLogDir, { recursive: true, force: true }); | |
| 269 | 273 | }), |
| 270 | 274 | ); |
| 271 | 275 | }); |
| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | // @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"; | |
| 6 | 6 | |
| 7 | 7 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 8 | 8 | import { it } from "@effect/vitest"; |
| @@ -18,8 +18,8 @@ import * as TextGeneration from "./TextGeneration.ts"; · 9 unmodified lines | ||
| 18 | 18 | import { makeGrokTextGeneration } from "./GrokTextGeneration.ts"; |
| 19 | 19 | const decodeGrokSettings = Schema.decodeSync(GrokSettings); |
| 20 | 20 | |
| 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"); | |
| 23 | 23 | |
| 24 | 24 | function shellSingleQuote(value: string): string { |
| 25 | 25 | return `'${value.replaceAll("'", `'"'"'`)}'`; |
| @@ -30,10 +30,10 @@ const GrokTextGenerationTestLayer = ServerConfig.ServerConfig.layerTest(process. · 4 unmodified lines | ||
| 30 | 30 | }).pipe(Layer.provideMerge(NodeServices.layer)); |
| 31 | 31 | |
| 32 | 32 | 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( | |
| 37 | 37 | grokPath, |
| 38 | 38 | [ |
| 39 | 39 | "#!/bin/sh", |
| @@ -47,7 +47,7 @@ function makeAcpGrokWrapper(dir: string, env: Record<string, string>): string { · 7 unmodified lines | ||
| 47 | 47 | ].join("\n"), |
| 48 | 48 | "utf8", |
| 49 | 49 | ); |
| 50 | − chmodSync(grokPath, 0o755); | |
| 50 | + NodeFS.chmodSync(grokPath, 0o755); | |
| 51 | 51 | return grokPath; |
| 52 | 52 | } |
| 53 | 53 | |
| @@ -56,10 +56,10 @@ function withFakeAcpGrok<A, E, R>( · 2 unmodified lines | ||
| 56 | 56 | effectFn: (textGeneration: TextGeneration.TextGeneration["Service"]) => Effect.Effect<A, E, R>, |
| 57 | 57 | ) { |
| 58 | 58 | 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-")); | |
| 60 | 60 | yield* Effect.addFinalizer(() => |
| 61 | 61 | Effect.sync(() => { |
| 62 | − rmSync(tempDir, { recursive: true, force: true }); | |
| 62 | + NodeFS.rmSync(tempDir, { recursive: true, force: true }); | |
| 63 | 63 | }), |
| 64 | 64 | ); |
| 65 | 65 | const binaryPath = makeAcpGrokWrapper(tempDir, env); |
| @@ -72,7 +72,7 @@ function withFakeAcpGrok<A, E, R>( · 6 unmodified lines | ||
| 72 | 72 | function readJsonRpcRequests( |
| 73 | 73 | filePath: string, |
| 74 | 74 | ): ReadonlyArray<{ readonly method?: string; readonly params?: Record<string, unknown> }> { |
| 75 | − return readFileSync(filePath, "utf8") | |
| 75 | + return NodeFS.readFileSync(filePath, "utf8") | |
| 76 | 76 | .trim() |
| 77 | 77 | .split("\n") |
| 78 | 78 | .filter((line) => line.length > 0) |
| @@ -81,8 +81,10 @@ function readJsonRpcRequests( · 2 unmodified lines | ||
| 81 | 81 | |
| 82 | 82 | it.layer(GrokTextGenerationTestLayer)("GrokTextGeneration", (it) => { |
| 83 | 83 | 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"); | |
| 86 | 88 | |
| 87 | 89 | return withFakeAcpGrok( |
| 88 | 90 | { |
| @@ -1,4 +1,4 @@ | ||
| 1 | −import { randomUUID } from "node:crypto"; | |
| 1 | +import * as NodeCrypto from "node:crypto"; | |
| 2 | 2 | |
| 3 | 3 | import * as Context from "effect/Context"; |
| 4 | 4 | import * as DateTime from "effect/DateTime"; |
| @@ -651,7 +651,10 @@ export const makeVcsDriverShape = Effect.fn("makeGitVcsDriverShape")(function* ( · 646 unmodified lines | ||
| 651 | 651 | captureCheckpoint: Effect.fn("GitVcsDriver.checkpoints.captureCheckpoint")(function* (input) { |
| 652 | 652 | const operation = "GitVcsDriver.checkpoints.captureCheckpoint"; |
| 653 | 653 | 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 | + ); | |
| 655 | 658 | const commitEnv: NodeJS.ProcessEnv = { |
| 656 | 659 | ...process.env, |
| 657 | 660 | GIT_INDEX_FILE: tempIndexPath, |
| @@ -1,13 +1,14 @@ | ||
| 1 | 1 | // @effect-diagnostics nodeBuiltinImport:off |
| 2 | −import fsPromises from "node:fs/promises"; | |
| 2 | +import * as NodeFSP from "node:fs/promises"; | |
| 3 | 3 | import * as NodeServices from "@effect/platform-node/NodeServices"; |
| 4 | 4 | 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"; | |
| 6 | 6 | import * as Effect from "effect/Effect"; |
| 7 | 7 | import * as FileSystem from "effect/FileSystem"; |
| 8 | 8 | import * as Layer from "effect/Layer"; |
| 9 | 9 | import * as Path from "effect/Path"; |
| 10 | 10 | import * as PlatformError from "effect/PlatformError"; |
| 11 | +import { vi } from "vite-plus/test"; | |
| 11 | 12 | |
| 12 | 13 | import * as ServerConfig from "../config.ts"; |
| 13 | 14 | import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; |
| @@ -15,6 +16,11 @@ import * as VcsProcess from "../vcs/VcsProcess.ts"; · 1 unmodified line | ||
| 15 | 16 | import * as WorkspaceEntries from "./WorkspaceEntries.ts"; |
| 16 | 17 | import * as WorkspacePaths from "./WorkspacePaths.ts"; |
| 17 | 18 | |
| 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 | + | |
| 18 | 24 | const TestLayer = Layer.empty.pipe( |
| 19 | 25 | Layer.provideMerge(WorkspaceEntries.layer.pipe(Layer.provide(WorkspacePaths.layer))), |
| 20 | 26 | Layer.provideMerge(WorkspacePaths.layer), |
| @@ -376,7 +382,7 @@ it.layer(TestLayer, { excludeTestServices: true })("WorkspaceEntries", (it) => { · 355 unmodified lines | ||
| 376 | 382 | const cwd = yield* makeTempDir({ prefix: "t3code-workspace-browse-eacces-" }); |
| 377 | 383 | |
| 378 | 384 | 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); | |
| 380 | 386 | |
| 381 | 387 | const result = yield* workspaceEntries.browse({ |
| 382 | 388 | partialPath: yield* appendSeparator(cwd), |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | // @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"; | |
| 4 | 4 | |
| 5 | 5 | import * as Context from "effect/Context"; |
| 6 | 6 | import * as Effect from "effect/Effect"; |
| @@ -98,10 +98,10 @@ export class WorkspaceEntries extends Context.Service< · 91 unmodified lines | ||
| 98 | 98 | |
| 99 | 99 | function expandHomePath(input: string, path: Path.Path): string { |
| 100 | 100 | if (input === "~") { |
| 101 | − return homedir(); | |
| 101 | + return NodeOS.homedir(); | |
| 102 | 102 | } |
| 103 | 103 | if (input.startsWith("~/") || input.startsWith("~\\")) { |
| 104 | − return path.join(homedir(), input.slice(2)); | |
| 104 | + return path.join(NodeOS.homedir(), input.slice(2)); | |
| 105 | 105 | } |
| 106 | 106 | return input; |
| 107 | 107 | } |
| @@ -176,7 +176,7 @@ export const make = Effect.gen(function* () { · 68 unmodified lines | ||
| 176 | 176 | const prefix = endsWithSeparator ? "" : path.basename(resolvedInputPath); |
| 177 | 177 | |
| 178 | 178 | const dirents = yield* Effect.tryPromise({ |
| 179 | − try: () => readdir(parentPath, { withFileTypes: true }), | |
| 179 | + try: () => NodeFSP.readdir(parentPath, { withFileTypes: true }), | |
| 180 | 180 | catch: (cause) => |
| 181 | 181 | new WorkspaceEntriesReadDirectoryError({ |
| 182 | 182 | cwd: input.cwd, |
| @@ -7,7 +7,7 @@ · 6 unmodified lines | ||
| 7 | 7 | * |
| 8 | 8 | * @module WorkspaceFileSystem |
| 9 | 9 | */ |
| 10 | −import { open, realpath } from "node:fs/promises"; | |
| 10 | +import * as NodeFSP from "node:fs/promises"; | |
| 11 | 11 | |
| 12 | 12 | import type { |
| 13 | 13 | ProjectReadFileInput, |
| @@ -89,8 +89,8 @@ export const make = Effect.gen(function* () { · 75 unmodified lines | ||
| 89 | 89 | return yield* Effect.tryPromise({ |
| 90 | 90 | try: async () => { |
| 91 | 91 | const [realWorkspaceRoot, realTargetPath] = await Promise.all([ |
| 92 | − realpath(input.cwd), | |
| 93 | − realpath(target.absolutePath), | |
| 92 | + NodeFSP.realpath(input.cwd), | |
| 93 | + NodeFSP.realpath(target.absolutePath), | |
| 94 | 94 | ]); |
| 95 | 95 | const relativeRealPath = path.relative(realWorkspaceRoot, realTargetPath); |
| 96 | 96 | if ( |
| @@ -101,7 +101,7 @@ export const make = Effect.gen(function* () { · 4 unmodified lines | ||
| 101 | 101 | throw new Error("Workspace file path resolves outside the project root."); |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | − const handle = await open(realTargetPath, "r"); | |
| 104 | + const handle = await NodeFSP.open(realTargetPath, "r"); | |
| 105 | 105 | try { |
| 106 | 106 | const stat = await handle.stat(); |
| 107 | 107 | if (!stat.isFile()) { |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | * |
| 7 | 7 | * @module WorkspacePaths |
| 8 | 8 | */ |
| 9 | −import { homedir } from "node:os"; | |
| 9 | +import * as NodeOS from "node:os"; | |
| 10 | 10 | |
| 11 | 11 | import * as Context from "effect/Context"; |
| 12 | 12 | import * as Effect from "effect/Effect"; |
| @@ -105,10 +105,10 @@ function toPosixRelativePath(input: string): string { · 92 unmodified lines | ||
| 105 | 105 | |
| 106 | 106 | function expandHomePath(input: string, path: Path.Path): string { |
| 107 | 107 | if (input === "~") { |
| 108 | − return homedir(); | |
| 108 | + return NodeOS.homedir(); | |
| 109 | 109 | } |
| 110 | 110 | if (input.startsWith("~/") || input.startsWith("~\\")) { |
| 111 | − return path.join(homedir(), input.slice(2)); | |
| 111 | + return path.join(NodeOS.homedir(), input.slice(2)); | |
| 112 | 112 | } |
| 113 | 113 | return input; |
| 114 | 114 | } |