| @@ -38,7 +38,7 @@ import type { · 37 unmodified lines |
| 38 | 38 | TerminalWriteInput, |
| 39 | 39 | } from "@t3tools/contracts"; |
| 40 | 40 | import { TerminalManager, type TerminalManagerShape } from "./terminal/Services/Manager"; |
| 41 | | −import { SqlitePersistenceMemory } from "./persistence/Layers/Sqlite"; |
| 41 | +import { makeSqlitePersistenceLive, SqlitePersistenceMemory } from "./persistence/Layers/Sqlite"; |
| 42 | 42 | import { SqlClient } from "effect/unstable/sql"; |
| 43 | 43 | import { ProviderService, type ProviderServiceShape } from "./provider/Services/ProviderService"; |
| 44 | 44 | import { Open, type OpenShape } from "./open"; |
| @@ -506,6 +506,61 @@ describe("WebSocket Server", () => { · 461 unmodified lines |
| 506 | 506 | ); |
| 507 | 507 | }); |
| 508 | 508 | |
| 509 | + it("includes bootstrap ids in welcome when cwd project and thread already exist", async () => { |
| 510 | + const stateDir = makeTempDir("t3code-state-bootstrap-existing-"); |
| 511 | + const persistenceLayer = makeSqlitePersistenceLive( |
| 512 | + path.join(stateDir, "state.sqlite"), |
| 513 | + ) as unknown as Layer.Layer<SqlClient.SqlClient, never>; |
| 514 | + const cwd = "/test/bootstrap-existing"; |
| 515 | + |
| 516 | + server = await createTestServer({ |
| 517 | + cwd, |
| 518 | + stateDir, |
| 519 | + persistenceLayer, |
| 520 | + autoBootstrapProjectFromCwd: true, |
| 521 | + }); |
| 522 | + let addr = server.address(); |
| 523 | + let port = typeof addr === "object" && addr !== null ? addr.port : 0; |
| 524 | + expect(port).toBeGreaterThan(0); |
| 525 | + |
| 526 | + const firstWs = await connectWs(port); |
| 527 | + connections.push(firstWs); |
| 528 | + const firstWelcome = (await waitForMessage(firstWs)) as WsPush; |
| 529 | + const firstBootstrapProjectId = (firstWelcome.data as { bootstrapProjectId?: string }) |
| 530 | + .bootstrapProjectId; |
| 531 | + const firstBootstrapThreadId = (firstWelcome.data as { bootstrapThreadId?: string }) |
| 532 | + .bootstrapThreadId; |
| 533 | + expect(firstBootstrapProjectId).toBeDefined(); |
| 534 | + expect(firstBootstrapThreadId).toBeDefined(); |
| 535 | + |
| 536 | + firstWs.close(); |
| 537 | + await closeTestServer(); |
| 538 | + server = null; |
| 539 | + |
| 540 | + server = await createTestServer({ |
| 541 | + cwd, |
| 542 | + stateDir, |
| 543 | + persistenceLayer, |
| 544 | + autoBootstrapProjectFromCwd: true, |
| 545 | + }); |
| 546 | + addr = server.address(); |
| 547 | + port = typeof addr === "object" && addr !== null ? addr.port : 0; |
| 548 | + expect(port).toBeGreaterThan(0); |
| 549 | + |
| 550 | + const secondWs = await connectWs(port); |
| 551 | + connections.push(secondWs); |
| 552 | + const secondWelcome = (await waitForMessage(secondWs)) as WsPush; |
| 553 | + expect(secondWelcome.channel).toBe(WS_CHANNELS.serverWelcome); |
| 554 | + expect(secondWelcome.data).toEqual( |
| 555 | + expect.objectContaining({ |
| 556 | + cwd, |
| 557 | + projectName: "bootstrap-existing", |
| 558 | + bootstrapProjectId: firstBootstrapProjectId, |
| 559 | + bootstrapThreadId: firstBootstrapThreadId, |
| 560 | + }), |
| 561 | + ); |
| 562 | + }); |
| 563 | + |
| 509 | 564 | it("logs outbound websocket push events in dev mode", async () => { |
| 510 | 565 | const logSpy = vi.spyOn(console, "log").mockImplementation(() => { |
| 511 | 566 | // Keep test output clean while verifying websocket logs. |